[kernel] r5312 - in people/waldi/linux-2.6: . debian debian/patches debian/patches-debian debian/patches/series

Bastian Blank waldi at costa.debian.org
Fri Jan 6 14:05:49 UTC 2006


Author: waldi
Date: Fri Jan  6 14:05:03 2006
New Revision: 5312

Added:
   people/waldi/linux-2.6/debian/patches/
   people/waldi/linux-2.6/debian/patches/TODO
   people/waldi/linux-2.6/debian/patches/drivers-scsi-megaraid_splitup.patch
   people/waldi/linux-2.6/debian/patches/fbdev-radeon-noaccel.patch
   people/waldi/linux-2.6/debian/patches/fs-asfs-2.patch
   people/waldi/linux-2.6/debian/patches/hppa-incompatible.patch
   people/waldi/linux-2.6/debian/patches/ia64-irq-affinity-upfix.patch
   people/waldi/linux-2.6/debian/patches/m68k-bvme.patch
   people/waldi/linux-2.6/debian/patches/m68k-incompatible.patch
   people/waldi/linux-2.6/debian/patches/m68k-mvme147.patch
   people/waldi/linux-2.6/debian/patches/m68k-mvme16x.patch
   people/waldi/linux-2.6/debian/patches/m68k-spinlock.patch
   people/waldi/linux-2.6/debian/patches/modular-ide-pnp.patch
   people/waldi/linux-2.6/debian/patches/powerpc-apus.patch
   people/waldi/linux-2.6/debian/patches/powerpc-arch-default-powerpc.patch
   people/waldi/linux-2.6/debian/patches/powerpc-build-links.patch
   people/waldi/linux-2.6/debian/patches/powerpc-calibrate-tau.patch
   people/waldi/linux-2.6/debian/patches/powerpc-g3-750cxe.patch
   people/waldi/linux-2.6/debian/patches/powerpc-mkvmlinuz-support.patch
   people/waldi/linux-2.6/debian/patches/powerpc-mv643xx-hotplug-support.patch
   people/waldi/linux-2.6/debian/patches/powerpc-mv643xx-spinlock-fix-support.patch
   people/waldi/linux-2.6/debian/patches/powerpc-prep-utah-ide-interrupt.patch
   people/waldi/linux-2.6/debian/patches/powerpc-serial.patch
   people/waldi/linux-2.6/debian/patches/remove-references-to-removed-drivers.patch
   people/waldi/linux-2.6/debian/patches/s390-uaccess-const.patch
   people/waldi/linux-2.6/debian/patches/series/
   people/waldi/linux-2.6/debian/patches/series/1
   people/waldi/linux-2.6/debian/patches/series/2-extra
   people/waldi/linux-2.6/debian/patches/sparc64-atyfb-xl-gr-final.patch
   people/waldi/linux-2.6/debian/patches/sparc64-hme-lockup.patch
   people/waldi/linux-2.6/debian/patches/tty-locking-fixes9.patch
   people/waldi/linux-2.6/debian/patches/version.patch
Removed:
   people/waldi/linux-2.6/debian/TODO.patches
   people/waldi/linux-2.6/debian/patches-debian/
Modified:
   people/waldi/linux-2.6/   (props changed)
   people/waldi/linux-2.6/debian/changelog
   people/waldi/linux-2.6/debian/rules.real
Log:
Merge /dists/trunk/linux-2.6.


Modified: people/waldi/linux-2.6/debian/changelog
==============================================================================
--- people/waldi/linux-2.6/debian/changelog	(original)
+++ people/waldi/linux-2.6/debian/changelog	Fri Jan  6 14:05:03 2006
@@ -2,15 +2,19 @@
 
   [ maximilian attems ]
   * Default to initramfs-tools as initramfs generator.
+    (Closes: #346141, #343147, #341524)
 
   [ dann frazier ]
   * [ia64] Update config for 2.6.15.
 
   [ Frederik Schüler ]
-  * Make CONFIG_IPW2100 a per-architecture option and deactivate it on all 
+  * Make CONFIG_IPW2100 a per-architecture option and deactivate it on all
     architectures but i386. (Closes: #344515)
 
- -- Frederik Schüler <fs at debian.org>  Thu,  5 Jan 2006 14:19:56 +0100
+  [ Sven Luther ]
+  * Removed spurious file from powerpc-apus patch. (Closes: #346159)
+
+ -- Sven Luther <luther at debian.org>  Fri,  6 Jan 2006 07:56:52 +0000
 
 linux-2.6 (2.6.15-1) unstable; urgency=low
 

Added: people/waldi/linux-2.6/debian/patches/TODO
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/TODO	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,115 @@
+Disabled because not applying cleanly, need investigating :
+
+drivers-scsi-megaraid_splitup.patch
+  FAILS:   1 hunk (drivers/scsi/megaraid/Kconfig.megaraid)
+
+remove-references-to-removed-drivers.patch
+  FAILS    1 hunk (drivers/usb/misc/Makefile)
+
+powerpc-g4-l2-flush-errata.patch
+  FAILS    1 hunk (arch/ppc/kernel/l2cr.S)
+
+
+
+Complete list of Mark Hymers (not all of those where still in use).
+
+Applied upstream
+================
+
+amd64-tlb-flush-sigsegv-fix.patch
+   Git commit: bc5e8fdfc622b03acf5ac974a1b8b26da6511c99
+
+kernel-api-documentation-generation-fix.diff
+   Git commit: 9d01a82e46a8dd18233121a6bc140e5576649583
+
+m68k-sonic.patch
+   Git commit: efcce839360fb3a7b6dedeacaec80f68b0f2d052
+
+mempolicy-check-mode.patch
+   Git commit: ba17101b41977f124948e0a7797fdcbb59e19f3e
+
+powerpc-pmac-sound-check.patch
+   Git commit: 4e6a06eec46067df3c30fe1fbc2e1a7cc37b9678
+
+powerpc-ppc64-biarch-override.patch
+   Git commit: 723e2b35e43dcbcfd737c40453caa7d198092d23
+
+
+Not applied upstream
+====================
+
+amd64-int3-fix.patch
+  APPLIES  Offset
+
+drivers-scsi-megaraid_splitup.patch
+  FAILS:   1 hunk (drivers/scsi/megaraid/Kconfig.megaraid)
+
+fbdev-radeon-noaccel.patch
+  APPLIES  Offset
+
+fs-asfs-2.patch
+  APPLIES  Offset
+
+ia64-irq-affinity-upfix.patch
+  APPLIES  Offset
+
+m68k-42_dma.patch
+  APPLIES  Offset
+
+modular-ide.patch
+  APPLIES  Offset
+
+modular-ide-pnp.patch
+  APPLIES  Offset
+
+powerpc-apus.patch
+  APPLIES  Offset
+
+powerpc-apus-todo.patch
+  FAILS    1 hunk (include/video/vga.h)
+
+powerpc-calibrate-tau.patch
+  APPLIES  Offset + fuzz
+
+powerpc-fix-power3-ftbfs.patch
+  APPLIES
+
+powerpc-g3-750cxe.patch
+  Claims to already be applied
+  Looks like patch is confused as a different but similar model was added
+
+powerpc-g4-l2-flush-errata.patch
+  FAILS    1 hunk (arch/ppc/kernel/l2cr.S)
+
+powerpc-mkvmlinuz-support.patch
+  APPLIES
+
+powerpc-mv643xx-hotplug-support.patch
+  APPLIES
+
+powerpc-pmac-cache-power34-fix.patch
+  APPLIES
+
+powerpc-serial-of.patch
+  FAILS    1 hunk ignored (arch/ppc64/kernel/setup.c)
+           This hunk claims to already be applied
+
+powerpc-serial.patch
+  APPLIES  Offset
+
+qla2xxx-removed.patch
+  APPLIES  Offset
+
+remove-references-to-removed-drivers.patch
+  FAILS    1 hunk (drivers/usb/misc/Makefile)
+
+sparc64-hme-lockup.patch
+  APPLIES
+
+tty-locking-fixes9.patch
+  APPLIES
+
+version.patch
+  APPLIES OFFSET
+
+==============

Added: people/waldi/linux-2.6/debian/patches/drivers-scsi-megaraid_splitup.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/drivers-scsi-megaraid_splitup.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,155 @@
+# drivers-scsi-megaraid_splitup.patch by Frederik Schüler <fs at debian.org>
+# Patch author: Ben Collins <bcollins at ubuntu.com>
+# Upstream status: not submitted
+# Description: Support megaraid legacy and megraid newgen, side-by-side
+# Source: ubuntu-2.6 git
+# diff from ca0e9390e01be69893d78bf9576d63ec85a6965e to 03bba4e0c091909e36520f2e617e51e87e50f8cd 
+# diff from e82633eb19c4b390846a6eecd72204b696448954 to 8378e9887b6cf0b99e28a3b71c585bd1279932f7
+
+diff --git a/drivers/scsi/megaraid/Kconfig.megaraid b/drivers/scsi/megaraid/Kconfig.megaraid
+index 7363e12..d71a230 100644
+--- a/drivers/scsi/megaraid/Kconfig.megaraid
++++ b/drivers/scsi/megaraid/Kconfig.megaraid
+@@ -1,12 +1,6 @@
+-config MEGARAID_NEWGEN
+-	bool "LSI Logic New Generation RAID Device Drivers"
+-	depends on PCI && SCSI
+-	help
+-	LSI Logic RAID Device Drivers
+-
+ config MEGARAID_MM
+ 	tristate "LSI Logic Management Module (New Driver)"
+-	depends on PCI && SCSI && MEGARAID_NEWGEN
++	depends on PCI && SCSI
+ 	help
+ 	Management Module provides ioctl, sysfs support for LSI Logic
+ 	RAID controllers.
+@@ -64,18 +58,15 @@ config MEGARAID_MAILBOX
+ 	To compile this driver as a module, choose M here: the
+ 	module will be called megaraid_mbox
+ 
+-if MEGARAID_NEWGEN=n
+ config MEGARAID_LEGACY
+ 	tristate "LSI Logic Legacy MegaRAID Driver"
+ 	depends on PCI && SCSI
+ 	help
+-	This driver supports the LSI MegaRAID 418, 428, 438, 466, 762, 490
+-	and 467 SCSI host adapters. This driver also support the all U320
+-	RAID controllers
++	This driver supports the AMI MEGARAID 1 and 2, and the HP NETRAID
++	1 and 2
+ 
+ 	To compile this driver as a module, choose M here: the
+ 	module will be called megaraid
+-endif
+ 
+ config MEGARAID_SAS
+ 	tristate "LSI Logic MegaRAID SAS RAID Module"
+diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
+index 4facf55..59cdd2a 100644
+--- a/drivers/scsi/megaraid.h
++++ b/drivers/scsi/megaraid.h
+@@ -84,6 +84,10 @@
+ #define LSI_SUBSYS_VID			0x1000
+ #define INTEL_SUBSYS_VID		0x8086
+ 
++/* Sub-System Device IDs */
++#define HP_NETRAID1M_SUBSYS_DID		0x60E7
++#define HP_NETRAID2M_SUBSYS_DID		0x60E8
++
+ #define HBA_SIGNATURE	      		0x3344
+ #define HBA_SIGNATURE_471	  	0xCCCC
+ #define HBA_SIGNATURE_64BIT		0x0299
+--- a/drivers/scsi/megaraid.c
++++ b/drivers/scsi/megaraid.c
+@@ -4570,7 +4570,7 @@
+ };
+ 
+ static int __devinit
+-megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
++megaraid_legacy_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ {
+ 	struct Scsi_Host *host;
+ 	adapter_t *adapter;
+@@ -5036,36 +5036,28 @@
+ 	__megaraid_shutdown(adapter);
+ }
+ 
+-static struct pci_device_id megaraid_pci_tbl[] = {
+-	{PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DISCOVERY,
+-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+-	{PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4_DI,
+-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, BOARD_64BIT},
+-	{PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4_QC_VERDE,
+-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, BOARD_64BIT},
++static struct pci_device_id megaraid_legacy_pci_tbl[] = {
+ 	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID,
+ 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ 	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID2,
+ 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ 	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3,
+-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+-	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_AMI_MEGARAID3,
+-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+-	{PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_AMI_MEGARAID3,
+-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
++		HP_SUBSYS_VID, HP_NETRAID1M_SUBSYS_DID, 0, 0, 0},
++	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3,
++		HP_SUBSYS_VID, HP_NETRAID2M_SUBSYS_DID, 0, 0, 0},
+ 	{0,}
+ };
+-MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl);
++MODULE_DEVICE_TABLE(pci, megaraid_legacy_pci_tbl);
+ 
+-static struct pci_driver megaraid_pci_driver = {
+-	.name		= "megaraid",
+-	.id_table	= megaraid_pci_tbl,
+-	.probe		= megaraid_probe_one,
++static struct pci_driver megaraid_legacy_pci_driver = {
++	.name		= "megaraidlegacy",
++	.id_table	= megaraid_legacy_pci_tbl,
++	.probe		= megaraid_legacy_probe_one,
+ 	.remove		= __devexit_p(megaraid_remove_one),
+ 	.shutdown	= megaraid_shutdown,
+ };
+ 
+-static int __init megaraid_init(void)
++static int __init megaraid_legacy_init(void)
+ {
+ 	int error;
+ 
+@@ -5081,7 +5073,7 @@
+ 				"megaraid: failed to create megaraid root\n");
+ 	}
+ #endif
+-	error = pci_module_init(&megaraid_pci_driver);
++	error = pci_module_init(&megaraid_legacy_pci_driver);
+ 	if (error) {
+ #ifdef CONFIG_PROC_FS
+ 		remove_proc_entry("megaraid", &proc_root);
+@@ -5104,21 +5096,21 @@
+ 	return 0;
+ }
+ 
+-static void __exit megaraid_exit(void)
++static void __exit megaraid_legacy_exit(void)
+ {
+ 	/*
+ 	 * Unregister the character device interface to the driver.
+ 	 */
+ 	unregister_chrdev(major, "megadev");
+ 
+-	pci_unregister_driver(&megaraid_pci_driver);
++	pci_unregister_driver(&megaraid_legacy_pci_driver);
+ 
+ #ifdef CONFIG_PROC_FS
+ 	remove_proc_entry("megaraid", &proc_root);
+ #endif
+ }
+ 
+-module_init(megaraid_init);
+-module_exit(megaraid_exit);
++module_init(megaraid_legacy_init);
++module_exit(megaraid_legacy_exit);
+ 
+ /* vi: set ts=8 sw=8 tw=78: */

Added: people/waldi/linux-2.6/debian/patches/fbdev-radeon-noaccel.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/fbdev-radeon-noaccel.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,17 @@
+diff -aurN a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
+--- a/drivers/video/aty/radeon_base.c	2005-06-06 11:22:29.000000000 -0400
++++ b/drivers/video/aty/radeon_base.c	2005-06-15 21:55:56.000000000 -0400
+@@ -1907,8 +1907,12 @@
+ 
+ 	fb_alloc_cmap(&info->cmap, 256, 0);
+ 
+-	if (noaccel)
++	if (noaccel) {
+ 		info->flags |= FBINFO_HWACCEL_DISABLED;
++		info->fix.accel = FB_ACCEL_NONE;
++	} else {
++		info->fix.accel = FB_ACCEL_ATI_RADEON;
++	}
+ 
+         return 0;
+ }

Added: people/waldi/linux-2.6/debian/patches/fs-asfs-2.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/fs-asfs-2.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,5262 @@
+## fs-asfs.dpatch by Sven Luther <luther at debian.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Description: add support for the Amiga SmartFilesystem (asfs), 1.0beta9
+## DP: Patch author: Marek Szyprowski <marek at amiga.pl>
+## DP: Upstream status: submitted but no reply. Submitted again on 2005.03.22.
+## DP: Reference: http://home.elka.pw.edu.pl/~mszyprow/programy/asfs/
+
+diff -aurN a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
+--- a/Documentation/filesystems/00-INDEX	2005-06-06 11:22:29.000000000 -0400
++++ b/Documentation/filesystems/00-INDEX	2005-06-15 22:05:09.000000000 -0400
+@@ -6,6 +6,8 @@
+ 	- info and mount options for the Acorn Advanced Disc Filing System.
+ affs.txt
+ 	- info and mount options for the Amiga Fast File System.
++asfs.txt
++	- info and mount options for the Amiga Smart File System.
+ bfs.txt
+ 	- info for the SCO UnixWare Boot Filesystem (BFS).
+ cifs.txt
+diff -aurN a/Documentation/filesystems/asfs.txt b/Documentation/filesystems/asfs.txt
+--- a/Documentation/filesystems/asfs.txt	1969-12-31 19:00:00.000000000 -0500
++++ b/Documentation/filesystems/asfs.txt	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,161 @@
++
++Amiga SmartFileSystem, Linux implementation
++===========================================
++
++ASFS is a Amiga Smart FileSystem driver for Linux. It supports reading
++files and directories. From version 1.0 there is also an experimental 
++(almost full) write support. Experimental means that it hasn't been 
++tested enough yet, so use it with care. Symbolic links (in AmigaOS
++called soft links) are also supported read/write. Read notes below 
++about symlinks support.
++
++
++Unsupported features of Amiga SFS
++================================
++
++ASFS currently does not support safe-delete feature of Amiga SFS 
++filesystem. It simply deletes files instead of moving them to 
++".recycled" directory. It also doesn't remove files from ".recycled" 
++directory, when there is no space left on drive. 
++
++If there is no space left, you need to manually remove files from 
++".recycled" directory. Also if you want to delete a file in a safe 
++way, you need to move it to ".recycled" directory by hand.
++
++Because of all of above, the amount of free space on disk does not 
++include space used by all files from ".recycled" directory.
++
++
++Limitations
++===========
++
++There is no Amiga protection bits into Linux permission bits tranlation
++and vice versa. If you need this feature, mail me.
++
++ASFS will always keep some amount of blocks free. This means that you 
++cannot fill the drive completely. It is because Amiga SFS uses some 
++special methods of writing data (called safe write), which needs some
++additional free space.
++
++File systems with unfinished transactions (this happens when system crashed
++during writing data to disk on AmigaOS/MorphOS) will be mounted read-only
++to protect data. The only way to fix such filesystem is to mount it under
++AmigaOS or MorphOS.
++
++Do not try to mount and write to filesystem with errors. Bad things will
++happen.
++
++
++Mount options for the ASFS
++==========================
++
++setuid=uid	
++		This sets the owner of all files and directories in the file
++		system to uid.
++
++setgid=gid	
++		Same as above, but for gid.
++
++mode=mode	
++		Sets the mode flags to the given (octal) value. Directories 
++		will get an x permission if the corresponding r bit is set.
++		The default mode is 0644, which means that everybody are allowed 
++		to read files, but only root can write to them.
++		(for directories this means also that search bits are set).
++
++prefix=path	
++		Path will be prefixed to every absolute path name of symbolic 
++		links on an ASFS/AFFS partition. Default = "/". (See below.)
++
++volume=name
++		When symbolic links with an absolute path are created
++		on an ASFS/AFFS partition, name will be prepended as the
++		volume name. Default = "" (empty string). (See below.)
++
++lowercasevol
++		Translate all volume names in symlinks to lower case.
++		Disabled by default. (See below.)
++
++iocharset=name
++		Character set to use for converting file names. Specifies 
++		character set used by your Linux system. 
++codepage=name
++		Set the codepage number for converting file names. Specifies
++		character set used by your Amiga. Use full name (for example
++		'cp1251' instead of '1251') here, this allows to specify any
++		character set, not only numbered one (like 'iso8859-2').
++		Use special name 'none' to disable the NLS file name 
++		translation.
++
++Symbolic links
++==============
++
++Although the Amiga and Linux file systems resemble each other, there
++are some, not always subtle, differences. One of them becomes apparent
++with symbolic links. While Linux has a file system with exactly one
++root directory, the Amiga has a separate root directory for each
++file system (for example, partition, floppy disk, ...). With the Amiga,
++these entities are called "volumes". They have symbolic names which
++can be used to access them. Thus, symbolic links can point to a
++different volume. ASFS turns the volume name into a directory name
++and prepends the prefix path (see prefix option) to it. When option
++"lowercasevol" is set, it also translates volume names to lower case.
++If the volume name is the same as a name given in "volume" option,
++it will be ignored and an absolute path will be created.
++
++Example:
++You mount all your Amiga partitions under /amiga/<volume> (where
++<volume> is the name of the volume), and you give options
++`prefix="/amiga/",volume="Linux",lowercasevol' when mounting all your 
++ASFS partitions. (They might be "User", "WB" and "Graphics", the mount 
++points /amiga/user, /amiga/wb and /amiga/graphics). 
++
++A symbolic link referring to "USER:sc/include/dos/dos.h" will be 
++translated to "/amiga/user/sc/include/dos/dos.h".
++A symbolic link referring to "Linux:etc/fstab" will be translated to
++"/etc/fstab".
++If you create a symlink referring to "/amiga/graphics/data/pict.jpg",
++it will be saved as "graphics:data/pict.jpg".
++If you create a symlink referring to "/boot/System.map", it will be 
++saved as "Linux:boot/System.map".
++
++
++Other information
++=================
++
++Supported block sizes are: 512, 1024, 2048 and 4096 bytes. Larger blocks
++speed up almost everything at the expense of wasted disk space. The speed
++gain above 4K seems not really worth the price, so you don't lose too
++much here, either.
++
++This file system has been tested on Motorola PPC and 68k, as well as 
++Intel x86 systems. I don't know, if it works on other Linux systems.
++
++This filesystem is in BETA STAGE. This means that driver MIGHT corrupt
++or damage data on your disk. Remember! YOU USE IT ON YOUR OWN RISK! 
++
++I made almost all I could to minimalize this risk. On my systems several 
++gigabytes has been succesfully copied from and to SFS disks. I would also 
++appreciate any infomation if this filesystem works on your system or not. 
++See next paragraph for my email.
++
++Some parts of this documentation has been adapted from AFFS driver docs.
++
++
++Author, contact and copyright infos
++===================================
++
++ASFS has been written by Marek 'March' Szyprowski <marek at amiga.pl>.
++Mail me if you have any suggestions or found a bug.
++
++Copyright (C) 2003,2004,2005  Marek 'March' Szyprowski <marek at amiga.pl>
++
++Thanks to Marcin Kurek (Morgoth/Dreamolers-CAPS) for help and parts 
++of original amiga version of SmartFilesystem source code. 
++
++SmartFilesystem is copyrighted (C) 2003,2004 by: John Hendrikx, 
++Ralph Schmidt, Emmanuel Lesueur, David Gerber and Marcin Kurek
++
++The ASFS driver is realased under the terms of of the GNU General 
++Public License. See source code for more details.
++
+diff -aurN a/fs/Kconfig b/fs/Kconfig
+--- a/fs/Kconfig	2005-06-06 11:22:29.000000000 -0400
++++ b/fs/Kconfig	2005-06-15 22:05:09.000000000 -0400
+@@ -921,6 +921,53 @@
+ 	  To compile this file system support as a module, choose M here: the
+ 	  module will be called affs.  If unsure, say N.
+ 
++config ASFS_FS
++	tristate "Amiga SFS file system support (EXPERIMENTAL)"
++	select NLS
++	depends on EXPERIMENTAL
++	help
++
++	  The Amiga Smart FileSystem (SFS) is the file system used on hard 
++	  disks by Amiga(tm) and MorphOS(tm) systems.  Say Y if you want 
++	  to be able to read files from an Amiga SFS partition on your hard 
++	  drive.
++
++	  For more information read <file:Documentation/filesystems/asfs.txt>
++
++	  To compile this file system support as a module, choose M here: the
++	  module will be called asfs.
++
++	  If unsure, say N.
++
++config ASFS_DEFAULT_CODEPAGE
++	string "Default codepage for SFS"
++	depends on ASFS_FS
++	default ""
++	help
++	  This option should be set to the codepage of your SFS filesystems.
++	  It can be overridden with the 'codepage' mount option. Leave it blank 
++	  or enter 'none' to disable filename converting.
++
++	  Use full codepage name (for example 'cp1251' instead of '1251') here, 
++	  this allows to specify any character set, not only numbered one (like 
++	  'iso8859-2').
++
++	  If unsure, leave it blank.
++
++config ASFS_RW
++	bool "Amiga SFS write support (DANGEROUS)"
++	depends on ASFS_FS
++	help
++
++	  If you say Y here, you will be able to write to ASFS file
++	  systems as well as read from them. The read-write support in ASFS
++	  is in beta stage. This means that useing it to write files to SFS 
++	  partitions is DANGEROUS and COULD corrupt the filesystem.
++
++	  For more information read <file:Documentation/filesystems/asfs.txt>
++
++	  If unsure, say N.
++
+ config HFS_FS
+ 	tristate "Apple Macintosh file system support (EXPERIMENTAL)"
+ 	depends on EXPERIMENTAL
+diff -aurN a/fs/Makefile b/fs/Makefile
+--- a/fs/Makefile	2005-06-06 11:22:29.000000000 -0400
++++ b/fs/Makefile	2005-06-15 22:05:09.000000000 -0400
+@@ -81,6 +81,7 @@
+ obj-$(CONFIG_JFFS_FS)		+= jffs/
+ obj-$(CONFIG_JFFS2_FS)		+= jffs2/
+ obj-$(CONFIG_AFFS_FS)		+= affs/
++obj-$(CONFIG_ASFS_FS)		+= asfs/
+ obj-$(CONFIG_ROMFS_FS)		+= romfs/
+ obj-$(CONFIG_QNX4FS_FS)		+= qnx4/
+ obj-$(CONFIG_AUTOFS_FS)		+= autofs/
+diff -aurN a/fs/asfs/Changes b/fs/asfs/Changes
+--- a/fs/asfs/Changes	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/Changes	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,108 @@
++
++Amiga Smart File System, Linux implementation
++
++Please direct bug reports to: marek at amiga.pl
++
++History:
++
++v1.0beta9 (17.03.2005)
++- added NLS support (thanks to Pavel Fedin!)
++
++v1.0beta8 (07.01.2005)
++- adapted to 2.6.10 kenrel VFS changes
++- added workaround for buggy Mandrake kernel headers
++
++v1.0beta7 (25.06.2004)
++- small changes in documentation
++- code clean up: bitfuncs.c, super.c, inode.c, *.h, Makefile, added 
++  asfs_ prefix to function names, made some functions static
++  (big thanks to Christoph Hellwig for advice!)
++- fixed minor bugs (inode leak in super.c, not-realesed buffer during 
++  object renaming in inode.c)
++- now files/dirs are created with global ownership/permission bits
++
++v1.0beta6 (04.06.2004)
++- fixed: ASFS_SB(sb)->flags was always zero in 2.6.x code
++
++v1.0beta5 (07.05.2004)
++- finally fixed a problem with file size attrib. not being written
++  to disk
++- fixed some problems with GCC 3.x and debug enabled
++
++v1.0beta4 (12.04.2004)
++- removed dummy asfs_notify_change (this fixes major bug introduced
++  in 1.0beta3 - file size wasn't written to disk) until it will 
++  be implemented completely
++
++v1.0beta3 (22.03.2004) - still beta
++- updated for 2.6.x kernels VFS changes
++- code clean-up 
++- added dummy asfs_notify_change (chmod now returns no errors)
++- added symlinks write support
++- fixed: ASFS_SB(sb)->flags was always zero
++
++v1.0beta2 (11.01.2004) - special version for Pegasos][ kernel
++- separated read and write functions, can be compiled also
++  as read-only fs
++
++v1.0beta1 (02.12.2003) - first public beta with write support
++- added dentry hashing/comparing routines
++- code clean-up
++
++v1.0aplha4 (30.11.2003) - preparing for first public beta
++- fixed some problems with renaming/moving files
++- fixed two major bugs, which didn't occur when fs was mounted
++  on loopback device (newly allocated blocks were not written to
++  disk and state bits were not set correctly on newly mapped file
++  blocks)
++- fixed many small bugs in io code (some buffers were not freed)
++- added/modified sb locks in asfs_lookup and asfs_getblock
++- fixed serious bug in file block allocation routines
++
++v1.0aplha3 (23.11.2003)
++- added (hopefully) all byteswap code, should now work again on 
++  little-endian systems (also with write support!)
++- updated documentation
++
++v1.0alpha2 (13.11.2003) 
++- now alocates file blocks in chunks during one request
++- fixed some dead-locks, other fixes
++
++v1.0alpha (02.11.2003) - first working version with full write support
++- too much to list it here ;)
++
++... (working on write support)
++
++v0.7 (12.10.2003) - internal realase
++- added asfs_breadcheck, modified asfs_get_node, asfs_search_BTree, 
++  no more from_be32/16 macros, other...
++- code splitted into several files
++
++v0.6 (04.09.2003) - final read-only version
++- added support for HashTables, directory scaning should be
++  MUCH faster now
++- added checking of block IDs before reading any data from block
++
++v0.5 (19.07.2003)
++- added simple but effective extent cache - real speed-up 
++  in reading large files
++- added read support for symlinks - based on AFFS symlinks
++
++v0.4 (10.07.2003)
++- third code clean-up (thanks to Roman Zippel for advice)
++- now uses generic readpage and readinode routines
++
++v0.3beta (17.06.2003)
++- second code clean-up
++
++v0.2beta2 (15.06.2003)
++- fixed yet another stupid bug - driver can't read root block on little-endian systems
++v0.2beta (15.06.2003)
++- fixed stupid bug - now files have 'file' flag (S_IFREG) set...
++- added mount options to set uid, gid and mode of files and dirs
++- made hidden files & dirs really hidden (= not listed in directories)
++- code clean-up
++
++v0.1beta (11.06.2003) 
++- after many kernel crashes, finally got it! 
++- first working read-only filesystem driver
+diff -aurN a/fs/asfs/Makefile b/fs/asfs/Makefile
+--- a/fs/asfs/Makefile	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/Makefile	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,8 @@
++#
++# Makefile for the linux asfs filesystem routines.
++#
++
++obj-$(CONFIG_ASFS_FS) += asfs.o
++
++asfs-y += dir.o extents.o file.o inode.o namei.o nodes.o objects.o super.o symlink.o
++asfs-$(CONFIG_ASFS_RW) += adminspace.o bitfuncs.o 
+diff -aurN a/fs/asfs/adminspace.c b/fs/asfs/adminspace.c
+--- a/fs/asfs/adminspace.c	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/adminspace.c	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,446 @@
++/*
++ *
++ * Amiga Smart File System, Linux implementation
++ * version: 1.0beta7
++ *
++ * This file contains some parts of the original amiga version of 
++ * SmartFilesystem source code.
++ *
++ * SmartFilesystem is copyrighted (C) 2003 by: John Hendrikx, 
++ * Ralph Schmidt, Emmanuel Lesueur, David Gerber, and Marcin Kurek
++ * 
++ * Adapted and modified by Marek 'March' Szyprowski <marek at amiga.pl>
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include "asfs_fs.h"
++#include "bitfuncs.h"
++
++#include <asm/byteorder.h>
++
++#ifdef CONFIG_ASFS_RW
++
++static int setfreeblocks(struct super_block *sb, u32 freeblocks)
++{
++	struct buffer_head *bh;
++	if ((bh = asfs_breadcheck(sb, ASFS_SB(sb)->rootobjectcontainer, ASFS_OBJECTCONTAINER_ID))) {
++		struct fsRootInfo *ri = (struct fsRootInfo *) ((u8 *) bh->b_data + sb->s_blocksize - sizeof(struct fsRootInfo));
++		ASFS_SB(sb)->freeblocks = freeblocks;
++		ri->freeblocks = cpu_to_be32(freeblocks);
++		asfs_bstore(sb, bh);
++		asfs_brelse(bh);
++		return 0;
++	}
++	return -EIO;
++}
++
++static inline int enoughspace(struct super_block *sb, u32 blocks)
++{
++	if (ASFS_SB(sb)->freeblocks - ASFS_ALWAYSFREE < blocks)
++		return FALSE;
++
++	return TRUE;
++}
++
++	/* Determines the amount of free blocks starting from block /block/.
++	   If there are no blocks found or if there was an error -1 is returned,
++	   otherwise this function will count the number of free blocks until
++	   an allocated block is encountered or until maxneeded has been
++	   exceeded. */
++
++static int availablespace(struct super_block *sb, u32 block, u32 maxneeded)
++{
++	struct buffer_head *bh = NULL;
++	struct fsBitmap *b;
++	u32 longs = ASFS_SB(sb)->blocks_inbitmap >> 5;
++	u32 maxbitmapblock = ASFS_SB(sb)->bitmapbase + ASFS_SB(sb)->blocks_bitmap;
++	int blocksfound = 0;
++	u32 bitstart;
++	int bitend;
++	u32 nextblock = ASFS_SB(sb)->bitmapbase + block / ASFS_SB(sb)->blocks_inbitmap;
++
++	bitstart = block % ASFS_SB(sb)->blocks_inbitmap;
++
++	while (nextblock < maxbitmapblock && (bh = asfs_breadcheck(sb, nextblock++, ASFS_BITMAP_ID))) {
++		b = (void *) bh->b_data;
++
++		if ((bitend = bmffz(b->bitmap, longs, bitstart)) >= 0) {
++			blocksfound += bitend - bitstart;
++			asfs_brelse(bh);
++			return blocksfound;
++		}
++		blocksfound += ASFS_SB(sb)->blocks_inbitmap - bitstart;
++		if (blocksfound >= maxneeded) {
++			asfs_brelse(bh);
++			return blocksfound;
++		}
++		bitstart = 0;
++		asfs_brelse(bh);
++	}
++
++	if (bh == NULL)
++		return (-1);
++
++	return (blocksfound);
++}
++
++int asfs_findspace(struct super_block *sb, u32 maxneeded, u32 start, u32 end, u32 * returned_block, u32 * returned_blocks)
++{
++	struct buffer_head *bh;
++	u32 longs = ASFS_SB(sb)->blocks_inbitmap >> 5;
++	u32 space = 0;
++	u32 block;
++	u32 bitmapblock = ASFS_SB(sb)->bitmapbase + start / ASFS_SB(sb)->blocks_inbitmap;
++	u32 breakpoint;
++	int bitstart, bitend;
++	int reads;
++
++	if (enoughspace(sb, maxneeded) == FALSE) {
++		*returned_block = 0;
++		*returned_blocks = 0;
++		return -ENOSPC;
++	}
++
++	if (start >= ASFS_SB(sb)->totalblocks)
++		start -= ASFS_SB(sb)->totalblocks;
++
++	if (end == 0)
++		end = ASFS_SB(sb)->totalblocks;
++
++	reads = ((end - 1) / ASFS_SB(sb)->blocks_inbitmap) + 1 - start / ASFS_SB(sb)->blocks_inbitmap;
++
++	if (start >= end)
++		reads += (ASFS_SB(sb)->totalblocks - 1) / ASFS_SB(sb)->blocks_inbitmap + 1;
++
++	breakpoint = (start < end ? end : ASFS_SB(sb)->totalblocks);
++
++	*returned_block = 0;
++	*returned_blocks = 0;
++
++	bitend = start % ASFS_SB(sb)->blocks_inbitmap;
++	block = start - bitend;
++
++	while ((bh = asfs_breadcheck(sb, bitmapblock++, ASFS_BITMAP_ID))) {
++		struct fsBitmap *b = (void *) bh->b_data;
++		u32 localbreakpoint = breakpoint - block;
++
++		if (localbreakpoint > ASFS_SB(sb)->blocks_inbitmap)
++			localbreakpoint = ASFS_SB(sb)->blocks_inbitmap;
++
++		/* At this point space contains the amount of free blocks at
++		   the end of the previous bitmap block.  If there are no
++		   free blocks at the start of this bitmap block, space will
++		   be set to zero, since in that case the space isn't adjacent. */
++
++		while ((bitstart = bmffo(b->bitmap, longs, bitend)) < ASFS_SB(sb)->blocks_inbitmap) {
++			/* found the start of an empty space, now find out how large it is */
++
++			if (bitstart >= localbreakpoint)
++				break;
++
++			if (bitstart != 0)
++				space = 0;
++
++			bitend = bmffz(b->bitmap, longs, bitstart);
++
++			if (bitend > localbreakpoint)
++				bitend = localbreakpoint;
++
++			space += bitend - bitstart;
++
++			if (*returned_blocks < space) {
++				*returned_block = block + bitend - space;
++				if (space >= maxneeded) {
++					*returned_blocks = maxneeded;
++					asfs_brelse(bh);
++					return 0;
++				}
++				*returned_blocks = space;
++			}
++
++			if (bitend >= localbreakpoint)
++				break;
++		}
++
++		if (--reads == 0)
++			break;
++
++		/* no (more) empty spaces found in this block */
++
++		if (bitend != ASFS_SB(sb)->blocks_inbitmap)
++			space = 0;
++
++		bitend = 0;
++		block += ASFS_SB(sb)->blocks_inbitmap;
++
++		if (block >= ASFS_SB(sb)->totalblocks) {
++			block = 0;
++			space = 0;
++			breakpoint = end;
++			bitmapblock = ASFS_SB(sb)->bitmapbase;
++		}
++		asfs_brelse(bh);
++	}
++
++	if (bh == NULL)
++		return -EIO;
++
++	asfs_brelse(bh);
++
++	if (*returned_blocks == 0)
++		return -ENOSPC;
++	else
++		return 0;
++}
++
++int asfs_markspace(struct super_block *sb, u32 block, u32 blocks)
++{
++	int errorcode;
++
++	asfs_debug("markspace: Marking %d blocks from block %d\n", blocks, block);
++
++	if ((availablespace(sb, block, blocks)) < blocks) {
++		printk("ASFS: Attempted to mark %d blocks from block %d, but some of them were already full!\n", blocks, block);
++		return -EIO;
++	}
++
++	if ((errorcode = setfreeblocks(sb, ASFS_SB(sb)->freeblocks - blocks)) == 0) {
++		struct buffer_head *bh;
++		u32 skipblocks = block / ASFS_SB(sb)->blocks_inbitmap;
++		u32 longs = (sb->s_blocksize - sizeof(struct fsBitmap)) >> 2;
++		u32 bitmapblock;
++
++		block -= skipblocks * ASFS_SB(sb)->blocks_inbitmap;
++		bitmapblock = ASFS_SB(sb)->bitmapbase + skipblocks;
++
++		while (blocks > 0) {
++			if ((bh = asfs_breadcheck(sb, bitmapblock++, ASFS_BITMAP_ID))) {
++				struct fsBitmap *b = (void *) bh->b_data;
++
++				blocks -= bmclr(b->bitmap, longs, block, blocks);
++				block = 0;
++
++				asfs_bstore(sb, bh);
++				asfs_brelse(bh);
++			} else
++				return -EIO;
++		}
++	}
++
++	return (errorcode);
++}
++
++	/* This function checks the bitmap and tries to locate at least /blocksneeded/
++	   adjacent unused blocks.  If found it sets returned_block to the start block
++	   and returns no error.  If not found, ERROR_DISK_IS_FULL is returned and
++	   returned_block is set to zero.  Any other errors are returned as well. */
++
++static inline int internalfindspace(struct super_block *sb, u32 blocksneeded, u32 startblock, u32 endblock, u32 * returned_block)
++{
++	u32 blocks;
++	int errorcode;
++
++	if ((errorcode = asfs_findspace(sb, blocksneeded, startblock, endblock, returned_block, &blocks)) == 0)
++		if (blocks != blocksneeded)
++			return -ENOSPC;
++
++	return errorcode;
++}
++
++static int findandmarkspace(struct super_block *sb, u32 blocksneeded, u32 * returned_block)
++{
++	int errorcode;
++
++	if (enoughspace(sb, blocksneeded) != FALSE) {
++		if ((errorcode = internalfindspace(sb, blocksneeded, 0, ASFS_SB(sb)->totalblocks, returned_block)) == 0)
++			errorcode = asfs_markspace(sb, *returned_block, blocksneeded);
++	} else
++		errorcode = -ENOSPC;
++
++	return (errorcode);
++}
++
++/* ************************** */
++
++int asfs_freespace(struct super_block *sb, u32 block, u32 blocks)
++{
++	int errorcode;
++
++	asfs_debug("freespace: Freeing %d blocks from block %d\n", blocks, block);
++
++	if ((errorcode = setfreeblocks(sb, ASFS_SB(sb)->freeblocks + blocks)) == 0) {
++		struct buffer_head *bh;
++		u32 skipblocks = block / ASFS_SB(sb)->blocks_inbitmap;
++		u32 longs = (sb->s_blocksize - sizeof(struct fsBitmap)) >> 2;
++		u32 bitmapblock;
++
++		block -= skipblocks * ASFS_SB(sb)->blocks_inbitmap;
++		bitmapblock = ASFS_SB(sb)->bitmapbase + skipblocks;
++
++		while (blocks > 0) {
++			if ((bh = asfs_breadcheck(sb, bitmapblock++, ASFS_BITMAP_ID))) {
++				struct fsBitmap *b = (void *) bh->b_data;
++
++				blocks -= bmset(b->bitmap, longs, block, blocks);
++				block = 0;
++
++				asfs_bstore(sb, bh);
++				asfs_brelse(bh);
++			} else
++				return -EIO;
++		}
++	}
++
++	return (errorcode);
++}
++
++/*************** admin space containers ****************/
++
++int asfs_allocadminspace(struct super_block *sb, u32 *returned_block)
++{
++	struct buffer_head *bh;
++	u32 adminspaceblock = ASFS_SB(sb)->adminspacecontainer;
++	int errorcode = -EIO;
++
++	asfs_debug("allocadminspace: allocating new block\n");
++
++	while ((bh = asfs_breadcheck(sb, adminspaceblock, ASFS_ADMINSPACECONTAINER_ID))) {
++		struct fsAdminSpaceContainer *asc1 = (void *) bh->b_data;
++		struct fsAdminSpace *as1 = asc1->adminspace;
++		int adminspaces1 = (sb->s_blocksize - sizeof(struct fsAdminSpaceContainer)) / sizeof(struct fsAdminSpace);
++
++		while (adminspaces1-- > 0) {
++			s16 bitoffset;
++
++			if (as1->space != 0 && (bitoffset = bfffz(be32_to_cpu(as1->bits), 0)) >= 0) {
++				u32 emptyadminblock = be32_to_cpu(as1->space) + bitoffset;
++				as1->bits |= cpu_to_be32(1 << (31 - bitoffset));
++				asfs_bstore(sb, bh);
++				*returned_block = emptyadminblock;
++				asfs_brelse(bh);
++				asfs_debug("allocadminspace: found block %d\n", *returned_block);
++				return 0;
++			}
++			as1++;
++		}
++
++		adminspaceblock = be32_to_cpu(asc1->next);
++		asfs_brelse(bh);
++
++		if (adminspaceblock == 0) {
++			u32 startblock;
++
++			asfs_debug("allocadminspace: allocating new adminspace area\n");
++
++			/* If we get here it means current adminspace areas are all filled.
++			   We would now need to find a new area and create a fsAdminSpace
++			   structure in one of the AdminSpaceContainer blocks.  If these
++			   don't have any room left for new adminspace areas a new
++			   AdminSpaceContainer would have to be created first which is
++			   placed as the first block in the newly found admin area. */
++
++			adminspaceblock = ASFS_SB(sb)->adminspacecontainer;
++
++			if ((errorcode = findandmarkspace(sb, 32, &startblock)))
++				return errorcode;
++
++			while ((bh = asfs_breadcheck(sb, adminspaceblock, ASFS_ADMINSPACECONTAINER_ID))) {
++				struct fsAdminSpaceContainer *asc2 = (void *) bh->b_data;
++				struct fsAdminSpace *as2 = asc2->adminspace;
++				int adminspaces2 = (sb->s_blocksize - sizeof(struct fsAdminSpaceContainer)) / sizeof(struct fsAdminSpace);
++
++				while (adminspaces2-- > 0 && as2->space != 0)
++					as2++;
++
++				if (adminspaces2 >= 0) {	/* Found a unused AdminSpace in this AdminSpaceContainer! */
++					as2->space = cpu_to_be32(startblock);
++					as2->bits = 0;
++					asfs_bstore(sb, bh);
++					asfs_brelse(bh);
++					break;
++				}
++
++				if (asc2->next == 0) {
++					/* Oh-oh... we marked our new adminspace area in use, but we couldn't
++					   find space to store a fsAdminSpace structure in the existing
++					   fsAdminSpaceContainer blocks.  This means we need to create and
++					   link a new fsAdminSpaceContainer as the first block in our newly
++					   marked adminspace. */
++
++					asc2->next = cpu_to_be32(startblock);
++					asfs_bstore(sb, bh);
++					asfs_brelse(bh);
++
++					/* Now preparing new AdminSpaceContainer */
++
++					if ((bh = asfs_getzeroblk(sb, startblock)) == NULL)
++						return -EIO;
++
++					asc2 = (void *) bh->b_data;
++					asc2->bheader.id = cpu_to_be32(ASFS_ADMINSPACECONTAINER_ID);
++					asc2->bheader.ownblock = cpu_to_be32(startblock);
++					asc2->previous = cpu_to_be32(adminspaceblock);
++					asc2->adminspace[0].space = cpu_to_be32(startblock);
++					asc2->adminspace[0].bits = cpu_to_be32(0x80000000);
++					asc2->bits = 32;
++
++					asfs_bstore(sb, bh);
++					asfs_brelse(bh);
++
++					adminspaceblock = startblock;
++					break;	/* Breaks through to outer loop! */
++				}
++				adminspaceblock = be32_to_cpu(asc2->next);
++				asfs_brelse(bh);
++			}
++		}
++	}
++	return errorcode;
++}
++
++int asfs_freeadminspace(struct super_block *sb, u32 block)
++{
++	struct buffer_head *bh;
++	u32 adminspaceblock = ASFS_SB(sb)->adminspacecontainer;
++
++	asfs_debug("freeadminspace: Entry -- freeing block %d\n", block);
++
++	while ((bh = asfs_breadcheck(sb, adminspaceblock, ASFS_ADMINSPACECONTAINER_ID))) {
++		struct fsAdminSpaceContainer *asc = (void *) bh->b_data;
++		struct fsAdminSpace *as = asc->adminspace;
++		int adminspaces = (sb->s_blocksize - sizeof(struct fsAdminSpaceContainer)) / sizeof(struct fsAdminSpace);
++
++		while (adminspaces-- > 0) {
++			if (block >= be32_to_cpu(as->space) && block < be32_to_cpu(as->space) + 32) {
++				s16 bitoffset = block - be32_to_cpu(as->space);
++				asfs_debug("freeadminspace: Block to be freed is located in AdminSpaceContainer block at %d\n", adminspaceblock);
++				as->bits &= cpu_to_be32(~(1 << (31 - bitoffset)));
++				asfs_bstore(sb, bh);
++				asfs_brelse(bh);
++				return 0;
++			}
++			as++;
++		}
++
++		if ((adminspaceblock = be32_to_cpu(asc->next)) == 0)
++			break;
++
++		asfs_brelse(bh);
++	}
++
++	if (bh != NULL) {
++		asfs_brelse(bh);
++		printk("ASFS: Unable to free an administration block. The block cannot be found.");
++		return -ENOENT;
++	}
++
++	return -EIO;
++}
++
++#endif
+diff -aurN a/fs/asfs/asfs_fs.h b/fs/asfs/asfs_fs.h
+--- a/fs/asfs/asfs_fs.h	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/asfs_fs.h	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,234 @@
++#ifndef __LINUX_ASFS_FS_H
++#define __LINUX_ASFS_FS_H
++
++#include <linux/types.h>
++#include <linux/fs.h>
++#include <linux/buffer_head.h>
++#include <asm/byteorder.h>
++#include <linux/amigasfs.h>
++
++#define asfs_debug(fmt,arg...) /* no debug at all */
++//#define asfs_debug(fmt,arg...) printk(fmt,##arg)  /* general debug infos */
++
++#if !defined (__BIG_ENDIAN) && !defined (__LITTLE_ENDIAN)
++#error Endianes must be known for ASFS to work. Sorry.
++#endif
++
++#define ASFS_MAXFN_BUF (ASFS_MAXFN + 4)
++#define ASFS_DEFAULT_UID 0
++#define ASFS_DEFAULT_GID 0
++#define ASFS_DEFAULT_MODE 0644	/* default permission bits for files, dirs have same permission, but with "x" set */
++
++/* Extent structure located in RAM (e.g. inside inode structure), 
++   currently used to store last used extent */
++
++struct inramExtent {
++	u32 startblock;	/* Block from begginig of the file */
++	u32 key;
++	u32 next;
++	u16 blocks;
++};
++
++/* inode in-kernel data */
++
++struct asfs_inode_info {
++	u32 firstblock;
++	u32 hashtable;
++	int modified;
++	loff_t mmu_private;
++	struct inramExtent ext_cache;
++	struct inode vfs_inode;
++};
++
++/* short cut to get to the asfs specific inode data */
++static inline struct asfs_inode_info *ASFS_I(struct inode *inode)
++{
++   return list_entry(inode, struct asfs_inode_info, vfs_inode);
++}
++
++/* Amiga SFS superblock in-core data */
++
++struct asfs_sb_info {
++	u32 totalblocks;
++	u32 rootobjectcontainer;
++	u32 extentbnoderoot;
++	u32 objectnoderoot;
++
++	u32 adminspacecontainer;
++	u32 bitmapbase;
++	u32 freeblocks;
++	u32 blocks_inbitmap;
++	u32 blocks_bitmap;
++	u32 block_rovingblockptr;
++
++	uid_t uid;
++	gid_t gid;
++	umode_t mode;
++	u16 flags;
++	char *prefix;
++	char *root_volume;		/* Volume prefix for absolute symlinks. */
++	char *iocharset;
++	char *codepage;
++	struct nls_table *nls_io;
++	struct nls_table *nls_disk;
++};
++
++/* short cut to get to the asfs specific sb data */
++static inline struct asfs_sb_info *ASFS_SB(struct super_block *sb)
++{
++	return sb->s_fs_info;
++}
++ 
++/* io inline code */
++
++u32 asfs_calcchecksum(void *block, u32 blocksize);
++
++static inline int
++asfs_check_block(struct fsBlockHeader *block, u32 blocksize, u32 n, u32 id)
++{
++	if (asfs_calcchecksum(block, blocksize) ==
++	    be32_to_cpu(((struct fsBlockHeader *) block)->checksum) &&
++	    n == be32_to_cpu(((struct fsBlockHeader *) block)->ownblock) &&
++	    id == be32_to_cpu(((struct fsBlockHeader *) block)->id))
++		return TRUE;
++	return FALSE;
++}
++
++/* get fs structure from block and do some checks... */
++static inline struct buffer_head *
++asfs_breadcheck(struct super_block *sb, u32 n, u32 type)
++{
++	struct buffer_head *bh;
++	if ((bh = sb_bread(sb, n))) {
++		if (asfs_check_block ((void *)bh->b_data, sb->s_blocksize, n, type)) {
++			return bh;	/* all okay */
++		}
++		brelse(bh);
++	}
++	return NULL;		/* error */
++}
++
++static inline struct buffer_head *
++asfs_getzeroblk(struct super_block *sb, int block)
++{
++	struct buffer_head *bh;
++	bh = sb_getblk(sb, block);
++	lock_buffer(bh);
++	memset(bh->b_data, 0, sb->s_blocksize);
++	set_buffer_uptodate(bh);
++	unlock_buffer(bh);
++	return bh;
++}
++
++static inline void 
++asfs_bstore(struct super_block *sb, struct buffer_head *bh)
++{
++	((struct fsBlockHeader *) (bh->b_data))->checksum =
++	    cpu_to_be32(asfs_calcchecksum(bh->b_data, sb->s_blocksize));
++	mark_buffer_dirty(bh);
++}
++
++static inline void asfs_brelse(struct buffer_head *bh)
++{
++	brelse(bh);
++}
++
++static inline void dec_count(struct inode *inode)
++{
++	inode->i_nlink--;
++	mark_inode_dirty(inode);
++}
++
++/* all prototypes */
++
++/* adminspace.c */
++int asfs_allocadminspace(struct super_block *sb, u32 * block);
++int asfs_freeadminspace(struct super_block *sb, u32 block);
++int asfs_markspace(struct super_block *sb, u32 block, u32 blocks);
++int asfs_freespace(struct super_block *sb, u32 block, u32 blocks);
++int asfs_findspace(struct super_block *sb, u32 maxneeded, u32 start, u32 end,
++	      u32 * returned_block, u32 * returned_blocks);
++
++/* dir.c */
++int asfs_readdir(struct file *filp, void *dirent, filldir_t filldir);
++struct dentry *asfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd);
++
++/* extents.c */
++int asfs_getextent(struct super_block *sb, u32 key, struct buffer_head **ret_bh,
++	      struct fsExtentBNode **ret_ebn);
++int asfs_deletebnode(struct super_block *sb, struct buffer_head *cb, u32 key);
++int asfs_deleteextents(struct super_block *sb, u32 key);
++int asfs_addblocks(struct super_block *sb, u16 blocks, u32 newspace,
++	      u32 objectnode, u32 * io_lastextentbnode);
++
++/* file.c */
++int asfs_readpage(struct file *file, struct page *page);
++sector_t asfs_bmap(struct address_space *mapping, sector_t block);
++int asfs_writepage(struct page *page, struct writeback_control *wbc);
++int asfs_prepare_write(struct file *file, struct page *page, unsigned from,
++		       unsigned to);
++void asfs_truncate(struct inode *inode);
++int asfs_file_open(struct inode *inode, struct file *filp);
++int asfs_file_release(struct inode *inode, struct file *filp);
++
++/* inode.c */
++struct inode *asfs_get_root_inode(struct super_block *sb);
++void asfs_read_locked_inode(struct inode *inode, void *arg);
++int asfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd);
++int asfs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
++int asfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname);
++int asfs_rmdir(struct inode *dir, struct dentry *dentry);
++int asfs_unlink(struct inode *dir, struct dentry *dentry);
++int asfs_rename(struct inode *old_dir, struct dentry *old_dentry,
++		struct inode *new_dir, struct dentry *new_dentry);
++int asfs_notify_change(struct dentry *dentry, struct iattr *attr);
++
++/* namei */
++u8 asfs_lowerchar(u8 c);
++int asfs_check_name(const u8 *name, int len);
++int asfs_namecmp(u8 *s, u8 *ct, int casesensitive, struct nls_table *t);
++u16 asfs_hash(u8 *name, int casesensitive);
++void asfs_translate(u8 *to, u8 *from, struct nls_table *nls_to, struct nls_table *nls_from, int limit);
++
++/* nodes */
++int asfs_getnode(struct super_block *sb, u32 nodeno,
++	    struct buffer_head **ret_bh, struct fsObjectNode **ret_node);
++int asfs_createnode(struct super_block *sb, struct buffer_head **returned_cb,
++	       struct fsNode **returned_node, u32 * returned_nodeno);
++int asfs_deletenode(struct super_block *sb, u32 objectnode);
++
++/* objects */
++struct fsObject *asfs_nextobject(struct fsObject *obj);
++struct fsObject *asfs_find_obj_by_name(struct super_block *sb,
++		struct fsObjectContainer *objcont, u8 * name);
++int asfs_readobject(struct super_block *sb, u32 objectnode,
++	       struct buffer_head **cb, struct fsObject **returned_object);
++int asfs_createobject(struct super_block *sb, struct buffer_head **io_cb,
++		 struct fsObject **io_o, struct fsObject *src_o,
++		 u8 * objname, int force);
++int asfs_deleteobject(struct super_block *sb, struct buffer_head *cb,
++		 struct fsObject *o);
++int asfs_renameobject(struct super_block *sb, struct buffer_head *cb1,
++		 struct fsObject *o1, struct buffer_head *cbparent,
++		 struct fsObject *oparent, u8 * newname);
++
++int asfs_addblockstofile(struct super_block *sb, struct buffer_head *objcb,
++		    struct fsObject *o, u32 blocks, u32 * newspace,
++		    u32 * addedblocks);
++int asfs_truncateblocksinfile(struct super_block *sb, struct buffer_head *bh,
++			 struct fsObject *o, u32 newsize);
++
++/* super.c */
++struct super_block *asfs_read_super(struct super_block *sb, void *data,
++				    int silent);
++void asfs_put_super(struct super_block *sb);
++int asfs_statfs(struct super_block *sb, struct kstatfs *buf);
++int asfs_remount(struct super_block *sb, int *flags, char *data);
++struct inode *asfs_alloc_inode(struct super_block *sb);
++void asfs_destroy_inode(struct inode *inode);
++
++/* symlink.c */
++int asfs_symlink_readpage(struct file *file, struct page *page);
++int asfs_write_symlink(struct inode *symfile, const char *symname);
++
++#endif
+diff -aurN a/fs/asfs/bitfuncs.c b/fs/asfs/bitfuncs.c
+--- a/fs/asfs/bitfuncs.c	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/bitfuncs.c	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,171 @@
++/*
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/types.h>
++#include <asm/byteorder.h>
++#include "bitfuncs.h"
++
++/* Bitmap (bm) functions:
++   These functions perform bit-operations on regions of memory which
++   are a multiple of 4 bytes in length. Bitmap is in bigendian byte order.
++*/
++
++/* This function finds the first set bit in a region of memory starting
++   with /bitoffset/.  The region of memory is /longs/ longs long.  It
++   returns the bitoffset of the first set bit it finds. */
++
++int bmffo(u32 *bitmap, int longs, int bitoffset)
++{
++	u32 *scan = bitmap;
++	int longoffset, bit;
++
++	longoffset = bitoffset >> 5;
++	longs -= longoffset;
++	scan += longoffset;
++
++	bitoffset = bitoffset & 0x1F;
++
++	if (bitoffset != 0) {
++		if ((bit = bfffo(be32_to_cpu(*scan), bitoffset)) >= 0) {
++			return (bit + ((scan - bitmap) << 5));
++		}
++		scan++;
++		longs--;
++	}
++
++	while (longs-- > 0) {
++		if (*scan++ != 0) {
++			return (bfffo(be32_to_cpu(*--scan), 0) + ((scan - bitmap) << 5));
++		}
++	}
++
++	return (-1);
++}
++
++/* This function finds the first unset bit in a region of memory starting
++   with /bitoffset/.  The region of memory is /longs/ longs long.  It
++   returns the bitoffset of the first unset bit it finds. */
++
++int bmffz(u32 *bitmap, int longs, int bitoffset)
++{
++	u32 *scan = bitmap;
++	int longoffset, bit;
++
++	longoffset = bitoffset >> 5;
++	longs -= longoffset;
++	scan += longoffset;
++
++	bitoffset = bitoffset & 0x1F;
++
++	if (bitoffset != 0) {
++		if ((bit = bfffz(be32_to_cpu(*scan), bitoffset)) >= 0) {
++			return (bit + ((scan - bitmap) << 5));
++		}
++		scan++;
++		longs--;
++	}
++
++	while (longs-- > 0) {
++		if (*scan++ != 0xFFFFFFFF) {
++			return (bfffz(be32_to_cpu(*--scan), 0) + ((scan - bitmap) << 5));
++		}
++	}
++
++	return (-1);
++}
++
++/* This function clears /bits/ bits in a region of memory starting
++   with /bitoffset/.  The region of memory is /longs/ longs long.  If
++   the region of memory is too small to clear /bits/ bits then this
++   function exits after having cleared all bits till the end of the
++   memory region.  In any case it returns the number of bits which
++   were actually cleared. */
++
++int bmclr(u32 *bitmap, int longs, int bitoffset, int bits)
++{
++	u32 *scan = bitmap;
++	int longoffset;
++	int orgbits = bits;
++
++	longoffset = bitoffset >> 5;
++	longs -= longoffset;
++	scan += longoffset;
++
++	bitoffset = bitoffset & 0x1F;
++
++	if (bitoffset != 0) {
++		if (bits < 32) {
++			*scan = cpu_to_be32(bfclr(be32_to_cpu(*scan), bitoffset, bits));
++		} else {
++			*scan = cpu_to_be32(bfclr(be32_to_cpu(*scan), bitoffset, 32));
++		}
++		scan++;
++		longs--;
++		bits -= 32 - bitoffset;
++	}
++
++	while (bits > 0 && longs-- > 0) {
++		if (bits > 31) {
++			*scan++ = 0;
++		} else {
++			*scan = cpu_to_be32(bfclr(be32_to_cpu(*scan), 0, bits));
++		}
++		bits -= 32;
++	}
++
++	if (bits <= 0) {
++		return (orgbits);
++	}
++	return (orgbits - bits);
++}
++
++/* This function sets /bits/ bits in a region of memory starting
++   with /bitoffset/.  The region of memory is /longs/ longs long.  If
++   the region of memory is too small to set /bits/ bits then this
++   function exits after having set all bits till the end of the
++   memory region.  In any case it returns the number of bits which
++   were actually set. */
++
++int bmset(u32 *bitmap, int longs, int bitoffset, int bits)
++{
++	u32 *scan = bitmap;
++	int longoffset;
++	int orgbits = bits;
++
++	longoffset = bitoffset >> 5;
++	longs -= longoffset;
++	scan += longoffset;
++
++	bitoffset = bitoffset & 0x1F;
++
++	if (bitoffset != 0) {
++		if (bits < 32) {
++			*scan = cpu_to_be32(bfset(be32_to_cpu(*scan), bitoffset, bits));
++		} else {
++			*scan = cpu_to_be32(bfset(be32_to_cpu(*scan), bitoffset, 32));
++		}
++		scan++;
++		longs--;
++		bits -= 32 - bitoffset;
++	}
++
++	while (bits > 0 && longs-- > 0) {
++		if (bits > 31) {
++			*scan++ = 0xFFFFFFFF;
++		} else {
++			*scan = cpu_to_be32(bfset(be32_to_cpu(*scan), 0, bits));
++		}
++		bits -= 32;
++	}
++
++	if (bits <= 0) {
++		return (orgbits);
++	}
++	return (orgbits - bits);
++}
+diff -aurN a/fs/asfs/bitfuncs.h b/fs/asfs/bitfuncs.h
+--- a/fs/asfs/bitfuncs.h	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/bitfuncs.h	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,59 @@
++/*
++ *
++ * 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.
++ *
++ */
++
++#ifndef __BITFUNCS_H
++#define __BITFUNCS_H
++
++#include <linux/types.h>
++#include <asm/byteorder.h>
++
++#include <asm/bitops.h>
++#include <linux/bitops.h>
++
++/* Finds first set bit in /data/ starting at /bitoffset/.  This function
++   considers the MSB to be the first bit. */
++static inline int bfffo(u32 data, int bitoffset)
++{
++	u32 mask = 0xffffffff >> bitoffset;
++	data &= mask;
++	return data == 0 ? -1 : 32-fls(data);
++}
++
++/* Finds first zero bit in /data/ starting at /bitoffset/.  This function
++   considers the MSB to be the first bit. */
++static inline int bfffz(u32 data, int bitoffset)
++{
++	return bfffo(~data, bitoffset);
++}
++
++/* Sets /bits/ bits starting from /bitoffset/ in /data/.
++   /bits/ must be between 1 and 32. */
++static inline u32 bfset(u32 data, int bitoffset, int bits)
++{
++	u32 mask = ~((1 << (32 - bits)) - 1);
++	mask >>= bitoffset;
++	return data | mask;
++}
++
++/* Clears /bits/ bits starting from /bitoffset/ in /data/.
++   /bits/ must be between 1 and 32. */
++static inline u32 bfclr(u32 data, int bitoffset, int bits)
++{
++	u32 mask = ~((1 << (32 - bits)) - 1);
++	mask >>= bitoffset;
++	return data & ~mask;
++}
++
++/* bm??? functions assumes that in-memory bitmap is in bigendian byte order */
++int bmffo(u32 *, int, int);
++int bmffz(u32 *, int, int);
++int bmclr(u32 *, int, int, int);
++int bmset(u32 *, int, int, int);
++
++#endif
+diff -aurN a/fs/asfs/dir.c b/fs/asfs/dir.c
+--- a/fs/asfs/dir.c	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/dir.c	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,240 @@
++/*
++ *
++ * Amiga Smart File System, Linux implementation
++ * version: 1.0beta7
++ *
++ * Copyright (C) 2003,2004  Marek 'March' Szyprowski <marek at amiga.pl>
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include "asfs_fs.h"
++
++#include <asm/byteorder.h>
++
++extern struct dentry_operations asfs_dentry_operations;
++
++int asfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
++{
++	struct inode *dir = filp->f_dentry->d_inode;
++	struct super_block *sb = dir->i_sb;
++	struct nls_table *nls_io = ASFS_SB(sb)->nls_io;
++	struct nls_table *nls_disk = ASFS_SB(sb)->nls_disk;
++	u8 buf[512];
++	unsigned long f_pos;
++	int stored = 0;
++
++	struct buffer_head *bh;
++	struct fsObjectContainer *objcont;
++	struct fsObject *obj;
++	u32 block;
++	int startnode;
++	int add;
++
++	asfs_debug("asfs_readdir:\n");
++
++	if (filp->f_pos == ASFS_SB(sb)->totalblocks)
++		return stored;
++
++	f_pos = filp->f_pos;
++
++	if (f_pos == 0) {
++		filp->private_data = (void *)0;
++		if (filldir(dirent, ".", 1, f_pos, dir->i_ino, DT_DIR) < 0)
++			return 0;
++		filp->f_pos = f_pos = 1;
++		stored++;
++	}
++	if (f_pos == 1) {
++		if (filldir(dirent, "..", 2, f_pos, parent_ino(filp->f_dentry), DT_DIR) < 0)
++			return stored;
++		filp->f_pos = f_pos = 2;
++		stored++;
++	}
++
++	if (ASFS_I(dir)->firstblock == 0) {	/* empty directory */
++		filp->f_pos = ASFS_SB(sb)->totalblocks;
++		ASFS_I(dir)->modified = 0;
++		return stored;
++	}
++
++	if (f_pos == 2) {	/* reading directory from its beginning */
++		block = ASFS_I(dir)->firstblock;
++		add = 1;
++		startnode = 0;
++	} else {
++		startnode = (int)filp->private_data;
++		add = 0;
++		if (ASFS_I(dir)->modified == 0)
++			block = f_pos;
++		else
++			block = ASFS_I(dir)->firstblock;
++	}
++
++	do {
++		if (!(bh = asfs_breadcheck(sb, block, ASFS_OBJECTCONTAINER_ID)))
++			return stored;
++		objcont = (struct fsObjectContainer *) bh->b_data;
++		obj = &(objcont->object[0]);
++
++		while (be32_to_cpu(obj->objectnode) > 0 && 
++		      ((char *)obj - (char *)objcont) + sizeof(struct fsObject) + 2 < sb->s_blocksize) {
++
++			if (!add && be32_to_cpu(obj->objectnode) == startnode)
++				add++;
++
++			if (add && !(obj->bits & OTYPE_HIDDEN)) {
++				unsigned int type;
++				asfs_translate(buf, obj->name, nls_io, nls_disk, 512);
++				asfs_debug("ASFS: DirFilling: entry #%d \"%s\" (node %u offset %u), type %x\n", \
++				           stored, buf, be32_to_cpu(obj->objectnode), block, obj->bits);
++				filp->f_pos = block;
++
++				if (obj->bits & OTYPE_DIR)
++					type = DT_DIR;
++				else if (obj->bits & OTYPE_LINK && !(obj->bits & OTYPE_HARDLINK))
++					type = DT_LNK;
++				else
++					type = DT_REG;
++
++				if (filldir(dirent, buf, strlen(buf), block, be32_to_cpu(obj->objectnode), type) < 0) {
++					filp->private_data = (void *)be32_to_cpu(obj->objectnode);
++					ASFS_I(dir)->modified = 0;
++					asfs_debug("ASFS: DirFilling: to be continued...\n");
++					asfs_brelse(bh);
++					return stored;
++				}
++				stored++;
++			}
++			obj = asfs_nextobject(obj);
++		}
++		block = be32_to_cpu(objcont->next);
++		asfs_brelse(bh);
++
++	} while (block != 0);
++
++	filp->f_pos = ASFS_SB(sb)->totalblocks;
++	ASFS_I(dir)->modified = 0;
++
++	return stored;
++}
++
++static struct fsObject *asfs_find_obj_by_name_nls(struct super_block *sb, struct fsObjectContainer *objcont, u8 * name)
++{
++	struct fsObject *obj;
++	u8 buf[512];
++
++	obj = &(objcont->object[0]);
++	while (be32_to_cpu(obj->objectnode) > 0 && ((char *) obj - (char *) objcont) + sizeof(struct fsObject) + 2 < sb->s_blocksize) {
++		asfs_translate(buf, obj->name, ASFS_SB(sb)->nls_io, ASFS_SB(sb)->nls_disk, 512);
++		if (asfs_namecmp(buf, name, ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE, ASFS_SB(sb)->nls_io) == 0) {
++			asfs_debug("Object found! Node %u, Name %s, Type %x, inCont %u\n", be32_to_cpu(obj->objectnode), obj->name, obj->bits, be32_to_cpu(objcont->bheader.ownblock));
++			return obj;
++		}
++		obj = asfs_nextobject(obj);
++	}
++	return NULL;
++}
++
++struct dentry *asfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
++{
++	int res = -EACCES;       /* placeholder for "no data here" */
++	struct inode *inode;
++	struct super_block *sb = dir->i_sb;
++	u8 *name = (u8 *) dentry->d_name.name;
++	struct buffer_head *bh;
++	struct fsObject *obj;
++	u8 bufname[ASFS_MAXFN_BUF];
++
++	asfs_translate(bufname, name, ASFS_SB(sb)->nls_disk, ASFS_SB(sb)->nls_io, ASFS_MAXFN_BUF);
++
++	asfs_debug("asfs_lookup: (searching \"%s\"...) ", name);
++
++	lock_super(sb);
++
++	if ((!strchr(name, '?')) && (ASFS_I(dir)->hashtable != 0)) {	/* hashtable block is available and name can be reverse translated, quick search */
++		struct fsObjectNode *node_p;
++		struct buffer_head *node_bh;
++		u32 node;
++		u16 hash16;
++
++		asfs_debug("(quick search) ");
++
++		if (!(bh = asfs_breadcheck(sb, ASFS_I(dir)->hashtable, ASFS_HASHTABLE_ID))) {
++			unlock_super(sb);
++			return ERR_PTR(res);
++		}
++		hash16 = asfs_hash(bufname, ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE); 
++		node = be32_to_cpu(((struct fsHashTable *) bh->b_data)->hashentry[HASHCHAIN(hash16)]);
++		asfs_brelse(bh);
++
++		while (node != 0) {
++			if (asfs_getnode(sb, node, &node_bh, &node_p) != 0)
++				goto not_found;
++			if (be16_to_cpu(node_p->hash16) == hash16) {
++				if (!(bh = asfs_breadcheck(sb, be32_to_cpu(node_p->node.data), ASFS_OBJECTCONTAINER_ID))) {
++					asfs_brelse(node_bh);
++					unlock_super(sb);
++					return ERR_PTR(res);
++				}
++				if ((obj = asfs_find_obj_by_name(sb, (struct fsObjectContainer *) bh->b_data, bufname)) != NULL) {
++					asfs_brelse(node_bh);
++					goto found_inode;
++				}
++				asfs_brelse(bh);
++			}
++			node = be32_to_cpu(node_p->next);
++			asfs_brelse(node_bh);
++		}
++	} else { /* hashtable not available or name can't be reverse-translated, long search */
++		struct fsObjectContainer *objcont;
++		u32 block;
++
++		asfs_debug("(long search) ");
++		block = ASFS_I(dir)->firstblock;
++		while (block != 0) {
++			if (!(bh = asfs_breadcheck(sb, block, ASFS_OBJECTCONTAINER_ID))) {
++				unlock_super(sb);
++				return ERR_PTR(res);
++			}
++			objcont = (struct fsObjectContainer *) bh->b_data;
++			if ((obj = asfs_find_obj_by_name_nls(sb, objcont, name)) != NULL)
++				goto found_inode;
++			block = be32_to_cpu(objcont->next);
++			asfs_brelse(bh);
++		}
++	}
++
++not_found:
++	unlock_super(sb);
++	inode = NULL;
++	asfs_debug("object not found.\n");
++	if (0) {
++found_inode:
++		unlock_super(sb);
++		if (!(inode = iget_locked(sb, be32_to_cpu(obj->objectnode)))) {
++			asfs_debug("ASFS: Strange - no inode allocated.\n");
++			return ERR_PTR(res);
++		}
++		if (inode->i_state & I_NEW) {
++			asfs_read_locked_inode(inode, obj);
++			unlock_new_inode(inode);
++		}
++		asfs_brelse(bh);
++	}
++	res = 0;
++	dentry->d_op = &asfs_dentry_operations;
++	d_add(dentry, inode);
++	return ERR_PTR(res);
++}
+diff -aurN a/fs/asfs/extents.c b/fs/asfs/extents.c
+--- a/fs/asfs/extents.c	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/extents.c	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,586 @@
++/*
++ *
++ * Amiga Smart File System, Linux implementation
++ * version: 1.0beta7
++ *
++ * This file contains some parts of the original amiga version of 
++ * SmartFilesystem source code.
++ *
++ * SmartFilesystem is copyrighted (C) 2003 by: John Hendrikx, 
++ * Ralph Schmidt, Emmanuel Lesueur, David Gerber and Marcin Kurek
++ * 
++ * Adapted and modified by Marek 'March' Szyprowski <marek at amiga.pl>
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include "asfs_fs.h"
++
++#include <asm/byteorder.h>
++
++	/* This function looks for the BNode equal to the key.  If no
++	   exact match is available then the BNode which is slightly
++	   lower than key will be returned.  If no such BNode exists
++	   either, then the first BNode in this block is returned.
++
++	   This function will return the first BNode even if there
++	   are no BNode's at all in this block (this can only happen
++	   for the Root of the tree).  Be sure to check if the Root
++	   is not empty before calling this function. */
++
++static struct BNode *searchforbnode(u32 key, struct BTreeContainer *tc)
++{
++	struct BNode *tn;
++	s16 n = be16_to_cpu(tc->nodecount) - 1;
++
++	tn = (struct BNode *) ((u8 *) tc->bnode + n * tc->nodesize);
++	for (;;) {
++		if (n <= 0 || key >= be32_to_cpu(tn->key))
++			return tn;
++
++		tn = (struct BNode *) ((u8 *) tn - tc->nodesize);
++		n--;
++	}
++}
++
++/* This function finds the BNode with the given key.  If no exact match can be
++   found then this function will return either the next or previous closest
++   match (don't rely on this).
++
++   If there were no BNode's at all, then *returned_bh will be NULL. */
++
++static int findbnode(struct super_block *sb, u32 key, struct buffer_head **returned_bh, struct BNode **returned_bnode)
++{
++	u32 rootblock = ASFS_SB(sb)->extentbnoderoot;
++
++	asfs_debug("findbnode: Looking for BNode with key %d\n", key);
++
++	while ((*returned_bh = asfs_breadcheck(sb, rootblock, ASFS_BNODECONTAINER_ID))) {
++		struct fsBNodeContainer *bnc = (void *) (*returned_bh)->b_data;
++		struct BTreeContainer *btc = &bnc->btc;
++
++		if (btc->nodecount == 0) {
++			*returned_bnode = NULL;
++			break;
++		}
++
++		*returned_bnode = searchforbnode(key, btc);
++		if (btc->isleaf == TRUE)
++			break;
++
++		rootblock = be32_to_cpu((*returned_bnode)->data);
++		asfs_brelse(*returned_bh);
++	}
++
++	if (*returned_bh == NULL)
++		return -EIO;
++
++	return 0;
++}
++
++int asfs_getextent(struct super_block *sb, u32 key, struct buffer_head **ret_bh, struct fsExtentBNode **ret_ebn)
++{
++	int result;
++	if ((result = findbnode(sb, key, ret_bh, (struct BNode **)ret_ebn)) == 0) 
++		if (be32_to_cpu((*ret_ebn)->key) != key) {
++			brelse(*ret_bh);
++			*ret_bh = NULL;
++			return -ENOENT;
++		}
++
++	return result;
++}
++
++#ifdef CONFIG_ASFS_RW
++
++	/* This routine inserts a node sorted into a BTreeContainer.  It does
++	   this by starting at the end, and moving the nodes one by one to
++	   a higher slot until the empty slot has the correct position for
++	   this key.  Donot use this function on completely filled
++	   BTreeContainers! */
++
++static struct BNode *insertbnode(u32 key, struct BTreeContainer *btc)
++{
++	struct BNode *bn;
++	bn = (struct BNode *) ((u8 *) btc->bnode + btc->nodesize * (be16_to_cpu(btc->nodecount) - 1));
++
++	for (;;) {
++		if (bn < btc->bnode || key > be32_to_cpu(bn->key)) {
++			bn = (struct BNode *) ((u8 *) bn + btc->nodesize);
++			bn->key = cpu_to_be32(key);
++			btc->nodecount = cpu_to_be16(be16_to_cpu(btc->nodecount) + 1);
++			break;
++		} else 
++			memmove((u8 *)bn + btc->nodesize, bn, btc->nodesize);
++
++		bn = (struct BNode *) ((u8 *) bn - btc->nodesize);
++	}
++
++	return bn;
++}
++
++static int getparentbtreecontainer(struct super_block *sb, struct buffer_head *bh, struct buffer_head **parent_bh)
++{
++	u32 rootblock = ASFS_SB(sb)->extentbnoderoot;
++	u32 childkey = be32_to_cpu(((struct fsBNodeContainer *) bh->b_data)->btc.bnode[0].key);
++	u32 childblock = be32_to_cpu(((struct fsBNodeContainer *) bh->b_data)->bheader.ownblock);
++
++	asfs_debug("getparentbtreecontainer: Getting parent of block %d\n", childblock);
++
++	/* This function gets the BTreeContainer parent of the passed in buffer_head. If
++	   there is no parent this function sets dest_cont io_bh to NULL */
++
++	if (rootblock != childblock) {
++		while ((*parent_bh = asfs_breadcheck(sb, rootblock, ASFS_BNODECONTAINER_ID))) {
++			struct fsBNodeContainer *bnc = (void *) (*parent_bh)->b_data;
++			struct BTreeContainer *btc = &bnc->btc;
++			struct BNode *bn;
++			s16 n = be16_to_cpu(btc->nodecount);
++
++			if (btc->isleaf == TRUE) {
++				asfs_brelse(*parent_bh);
++				break;
++			}
++
++			while (n-- > 0)
++				if (be32_to_cpu(btc->bnode[n].data) == childblock)
++					return 0;	/* Found parent!! */
++
++			bn = searchforbnode(childkey, btc);	/* This searchforbnode() doesn't have to get EXACT key matches. */
++			rootblock = be32_to_cpu(bn->data);
++			asfs_brelse(*parent_bh);
++		}
++		if (*parent_bh == NULL)
++			return -EIO;
++	}
++
++	*parent_bh = NULL;
++	return 0;
++}
++
++/* Spits a btreecontainer. It realses passed in bh! */
++
++static int splitbtreecontainer(struct super_block *sb, struct buffer_head *bh)
++{
++	struct buffer_head *bhparent;
++	struct BNode *bn;
++	int errorcode;
++
++	asfs_debug("splitbtreecontainer: splitting block %u\n", be32_to_cpu(((struct fsBlockHeader *) bh->b_data)->ownblock));
++
++	if ((errorcode = getparentbtreecontainer(sb, bh, &bhparent)) == 0) {
++		if (bhparent == NULL) {
++			u32 newbcontblock;
++			u32 bcontblock;
++			/* We need to create Root tree-container - adding new level to extent tree */
++
++			asfs_debug("splitbtreecontainer: creating root tree-container.\n");
++
++			bhparent = bh;
++			if ((errorcode = asfs_allocadminspace(sb, &newbcontblock)) == 0 && (bh = asfs_getzeroblk(sb, newbcontblock))) {
++				struct fsBNodeContainer *bnc = (void *) bh->b_data;
++				struct fsBNodeContainer *bncparent = (void *) bhparent->b_data;
++				struct BTreeContainer *btcparent = &bncparent->btc;
++
++				bcontblock = be32_to_cpu(bncparent->bheader.ownblock);
++				memcpy(bh->b_data, bhparent->b_data, sb->s_blocksize);
++				bnc->bheader.ownblock = cpu_to_be32(newbcontblock);
++				asfs_bstore(sb, bh);
++
++				memset(bhparent->b_data, '\0', sb->s_blocksize);	/* Not strictly needed, but makes things more clear. */
++				bncparent->bheader.id = cpu_to_be32(ASFS_BNODECONTAINER_ID);
++				bncparent->bheader.ownblock = cpu_to_be32(bcontblock);
++				btcparent->isleaf = FALSE;
++				btcparent->nodesize = sizeof(struct BNode);
++				btcparent->nodecount = 0;
++
++				bn = insertbnode(0, btcparent);
++				bn->data = cpu_to_be32(newbcontblock);
++
++				asfs_bstore(sb, bhparent);
++			}
++			if (bh == NULL)
++				errorcode = -EIO;
++		}
++
++		if (errorcode == 0) {
++			struct fsBNodeContainer *bncparent = (void *) bhparent->b_data;
++			struct BTreeContainer *btcparent = &bncparent->btc;
++			int branches1 = (sb->s_blocksize - sizeof(struct fsBNodeContainer)) / btcparent->nodesize;
++
++			if (be16_to_cpu(btcparent->nodecount) == branches1) {
++				/* We need to split the parent tree-container first! */
++				if ((errorcode = splitbtreecontainer(sb, bhparent)) == 0) {
++					/* bhparent might have changed after the split and has been released */
++					if ((errorcode = getparentbtreecontainer(sb, bh, &bhparent)) == 0) {	
++						bncparent = (void *) bhparent->b_data;
++						btcparent = &bncparent->btc;
++					}
++				}
++			}
++
++			if (errorcode == 0) {
++				u32 newbcontblock;
++				struct buffer_head *bhnew;
++
++				/* We can split this container and add it to the parent
++				   because the parent has enough room. */
++
++				if ((errorcode = asfs_allocadminspace(sb, &newbcontblock)) == 0 && (bhnew = asfs_getzeroblk(sb, newbcontblock))) {
++					struct fsBNodeContainer *bncnew = (void *) bhnew->b_data;
++					struct BTreeContainer *btcnew = &bncnew->btc;
++					struct fsBNodeContainer *bnc = (void *) bh->b_data;
++					struct BTreeContainer *btc = &bnc->btc;
++					int branches2 = (sb->s_blocksize - sizeof(struct fsBNodeContainer)) / btc->nodesize;
++					u32 newkey;
++
++					bncnew->bheader.id = cpu_to_be32(ASFS_BNODECONTAINER_ID);
++					bncnew->bheader.ownblock = cpu_to_be32(newbcontblock);
++
++					btcnew->isleaf = btc->isleaf;
++					btcnew->nodesize = btc->nodesize;
++
++					btcnew->nodecount = cpu_to_be16(branches2 - branches2 / 2);
++
++					memcpy(btcnew->bnode, (u8 *) btc->bnode + branches2 / 2 * btc->nodesize, (branches2 - branches2 / 2) * btc->nodesize);
++					newkey = be32_to_cpu(btcnew->bnode[0].key);
++
++					asfs_bstore(sb, bhnew);
++					asfs_brelse(bhnew);
++
++					btc->nodecount = cpu_to_be16(branches2 / 2);
++					asfs_bstore(sb, bh);
++
++					bn = insertbnode(newkey, btcparent);
++					bn->data = cpu_to_be32(newbcontblock);
++					asfs_bstore(sb, bhparent);
++				}
++			}
++		}
++		asfs_brelse(bhparent);
++	}
++	asfs_brelse(bh);
++
++	return errorcode;
++}
++
++/* Returns created extentbnode - returned_bh need to saved and realesed in caller funkction! */
++
++int createextentbnode(struct super_block *sb, u32 key, struct buffer_head **returned_bh, struct BNode **returned_bnode)
++{
++	int errorcode;
++
++	asfs_debug("createbnode: Creating BNode with key %d\n", key);
++
++	while ((errorcode = findbnode(sb, key, returned_bh, returned_bnode)) == 0) {
++		struct fsBNodeContainer *bnc = (void *) (*returned_bh)->b_data;
++		struct BTreeContainer *btc = &bnc->btc;
++		int extbranches = (sb->s_blocksize - sizeof(struct fsBNodeContainer)) / btc->nodesize;
++
++		asfs_debug("createbnode: findbnode found block %d\n", be32_to_cpu(((struct fsBlockHeader *) (*returned_bh)->b_data)->ownblock));
++
++		if (be16_to_cpu(btc->nodecount) < extbranches) {
++			/* Simply insert new node in this BTreeContainer */
++			asfs_debug("createbnode: Simple insert\n");
++			*returned_bnode = insertbnode(key, btc);
++			break;
++		} else if ((errorcode = splitbtreecontainer(sb, *returned_bh)) != 0)
++			break;
++
++		/* Loop and try insert it the normal way again :-) */
++	}
++
++	return (errorcode);
++}
++
++
++/* This routine removes a node from a BTreeContainer indentified
++   by its key.  If no such key exists this routine does nothing.
++   It correctly handles empty BTreeContainers. */
++
++static void removebnode(u32 key, struct BTreeContainer *btc)
++{
++	struct BNode *bn = btc->bnode;
++	int n = 0;
++
++	asfs_debug("removebnode: key %d\n", key);
++
++	while (n < be16_to_cpu(btc->nodecount)) {
++		if (be32_to_cpu(bn->key) == key) {
++			btc->nodecount = cpu_to_be16(be16_to_cpu(btc->nodecount) - 1);
++			memmove(bn, (u8 *) bn + btc->nodesize, (be16_to_cpu(btc->nodecount) - n) * btc->nodesize);
++			break;
++		}
++		bn = (struct BNode *) ((u8 *) bn + btc->nodesize);
++		n++;
++	}
++}
++
++int asfs_deletebnode(struct super_block *sb, struct buffer_head *bh, u32 key)
++{
++	struct fsBNodeContainer *bnc1 = (void *) bh->b_data;
++	struct BTreeContainer *btc = &bnc1->btc;
++	u16 branches = (sb->s_blocksize - sizeof(struct fsBNodeContainer)) / btc->nodesize;
++	int errorcode = 0;
++
++	/* Deletes specified internal node. */
++
++	removebnode(key, btc);
++	asfs_bstore(sb, bh);
++
++	/* Now checks if the container still contains enough nodes,
++	   and takes action accordingly. */
++
++	asfs_debug("deletebnode: branches = %d, btc->nodecount = %d\n", branches, be16_to_cpu(btc->nodecount));
++
++	if (be16_to_cpu(btc->nodecount) < (branches + 1) / 2) {
++		struct buffer_head *bhparent;
++		struct buffer_head *bhsec;
++
++		/* nodecount has become to low.  We need to merge this Container
++		   with a neighbouring Container, or we need to steal a few nodes
++		   from a neighbouring Container. */
++
++		/* We get the parent of the container here, so we can find out what
++		   containers neighbour the container which currently hasn't got enough nodes. */
++
++		if ((errorcode = getparentbtreecontainer(sb, bh, &bhparent)) == 0) {
++			if (bhparent != NULL) {
++				struct fsBNodeContainer *bncparent = (void *) bhparent->b_data;
++				struct BTreeContainer *btcparent = &bncparent->btc;
++				s16 n;
++
++				asfs_debug("deletebnode: get parent returned block %d.\n", be32_to_cpu(((struct fsBlockHeader *) bhparent->b_data)->ownblock));
++
++				for (n = 0; n < be16_to_cpu(btcparent->nodecount); n++)
++					if (btcparent->bnode[n].data == bnc1->bheader.ownblock)
++						break;
++				/* n is now the offset of our own bnode. */
++
++				if (n < be16_to_cpu(btcparent->nodecount) - 1) {	/* Check if we have a next neighbour. */
++					asfs_debug("deletebnode: using next container - merging blocks %d and %d\n", be32_to_cpu(bnc1->bheader.ownblock), be32_to_cpu(btcparent->bnode[n+1].data));
++
++					if ((bhsec = asfs_breadcheck(sb, be32_to_cpu(btcparent->bnode[n + 1].data), ASFS_BNODECONTAINER_ID))) {
++						struct fsBNodeContainer *bnc_next = (void *) bhsec->b_data;
++						struct BTreeContainer *btc_next = &bnc_next->btc;
++
++						if (be16_to_cpu(btc_next->nodecount) + be16_to_cpu(btc->nodecount) > branches) {	/* Check if we need to steal nodes. */
++							s16 nodestosteal = (be16_to_cpu(btc_next->nodecount) + be16_to_cpu(btc->nodecount)) / 2 - be16_to_cpu(btc->nodecount);
++
++							/* Merging them is not possible.  Steal a few nodes then. */
++							memcpy((u8 *) btc->bnode + be16_to_cpu(btc->nodecount) * btc->nodesize, btc_next->bnode, nodestosteal * btc->nodesize);
++							btc->nodecount = cpu_to_be16(be16_to_cpu(btc->nodecount) + nodestosteal);
++							asfs_bstore(sb, bh);
++
++							memcpy(btc_next->bnode, (u8 *) btc_next->bnode + btc_next->nodesize * nodestosteal,
++							       btc->nodesize * (be16_to_cpu(btc_next->nodecount) - nodestosteal));
++							btc_next->nodecount = cpu_to_be16(be16_to_cpu(btc_next->nodecount) - nodestosteal);
++							asfs_bstore(sb, bhsec);
++
++							btcparent->bnode[n + 1].key = btc_next->bnode[0].key;
++							asfs_bstore(sb, bhparent);
++						} else {	/* Merging is possible. */
++							memcpy((u8 *) btc->bnode + btc->nodesize * be16_to_cpu(btc->nodecount), btc_next->bnode, btc->nodesize * be16_to_cpu(btc_next->nodecount));
++							btc->nodecount = cpu_to_be16(be16_to_cpu(btc->nodecount) + be16_to_cpu(btc_next->nodecount));
++							asfs_bstore(sb, bh);
++
++							if ((errorcode = asfs_freeadminspace(sb, be32_to_cpu(((struct fsBlockHeader *) bhsec->b_data)->ownblock))) == 0)
++								errorcode = asfs_deletebnode(sb, bhparent, be32_to_cpu(btcparent->bnode[n + 1].key));
++						}
++						asfs_brelse(bhsec);
++					}
++				} else if (n > 0) {	/* Check if we have a previous neighbour. */
++					asfs_debug("deletebnode: using prev container.\n");
++
++					if ((bhsec = asfs_breadcheck(sb, be32_to_cpu(btcparent->bnode[n - 1].data), ASFS_BNODECONTAINER_ID)) == 0) {
++						struct fsBNodeContainer *bnc2 = (void *) bhsec->b_data;
++						struct BTreeContainer *btc2 = &bnc2->btc;
++
++						if (be16_to_cpu(btc2->nodecount) + be16_to_cpu(btc->nodecount) > branches) {
++							/* Merging them is not possible.  Steal a few nodes then. */
++							s16 nodestosteal = (be16_to_cpu(btc2->nodecount) + be16_to_cpu(btc->nodecount)) / 2 - be16_to_cpu(btc->nodecount);
++
++							memmove((u8 *) btc->bnode + nodestosteal * btc->nodesize, btc->bnode, be16_to_cpu(btc->nodecount) * btc->nodesize);
++							btc->nodecount = cpu_to_be16(be16_to_cpu(btc->nodecount) + nodestosteal);
++							memcpy(btc->bnode, (u8 *) btc2->bnode + (be16_to_cpu(btc2->nodecount) - nodestosteal) * btc2->nodesize, nodestosteal * btc->nodesize);
++
++							asfs_bstore(sb, bh);
++
++							btc2->nodecount = cpu_to_be16(be16_to_cpu(btc2->nodecount) - nodestosteal);
++							asfs_bstore(sb, bhsec);
++
++							btcparent->bnode[n].key = btc->bnode[0].key;
++							asfs_bstore(sb, bhparent);
++						} else {	/* Merging is possible. */
++							memcpy((u8 *) btc2->bnode + be16_to_cpu(btc2->nodecount) * btc2->nodesize, btc->bnode, be16_to_cpu(btc->nodecount) * btc->nodesize);
++							btc2->nodecount = cpu_to_be16(be16_to_cpu(btc2->nodecount) + be16_to_cpu(btc->nodecount));
++							asfs_bstore(sb, bhsec);
++
++							if ((errorcode = asfs_freeadminspace(sb, be32_to_cpu(((struct fsBlockHeader *) bhsec->b_data)->ownblock))) == 0)
++								errorcode = asfs_deletebnode(sb, bhparent, be32_to_cpu(btcparent->bnode[n].key));
++						}
++						asfs_brelse(bhsec);
++					}
++				}
++				/*      else    
++				   {
++				   // Never happens, except for root and then we don't care.
++				   } */
++			} else if (btc->nodecount == 1) {
++				/* No parent, so must be root. */
++
++				asfs_debug("deletebnode: no parent so must be root\n");
++
++				if (btc->isleaf == FALSE) {
++					struct fsBNodeContainer *bnc3 = (void *) bh->b_data;
++
++					/* The current root has only 1 node.  We now copy the data of this node into the
++					   root and promote that data to be the new root.  The rootblock number stays the
++					   same that way. */
++
++					if ((bhsec = asfs_breadcheck(sb, be32_to_cpu(btc->bnode[0].data), ASFS_BNODECONTAINER_ID))) {
++						u32 blockno = be32_to_cpu(((struct fsBlockHeader *) bh->b_data)->ownblock);
++						memcpy(bh->b_data, bhsec->b_data, sb->s_blocksize);
++						bnc3->bheader.ownblock = cpu_to_be32(blockno);
++
++						asfs_bstore(sb, bh);
++						errorcode = asfs_freeadminspace(sb, be32_to_cpu(((struct fsBlockHeader *) bhsec->b_data)->ownblock));
++						asfs_brelse(bhsec);
++					} else
++						errorcode = -EIO;
++				}
++				/* If not, then root contains leafs. */
++			}
++
++			asfs_debug("deletebnode: almost done\n");
++			/* otherwise, it must be the root, and the root is allowed
++			   to contain less than the minimum amount of nodes. */
++
++		}
++		if (bhparent != NULL)
++			asfs_brelse(bhparent);
++	}
++
++	return errorcode;
++}
++
++   /* Deletes an fsExtentBNode structure by key and any fsExtentBNodes linked to it.
++      This function DOES NOT fix the next pointer in a possible fsExtentBNode which
++      might have been pointing to the first BNode we are deleting.  Make sure you check
++      this yourself, if needed.
++
++      If key is zero, than this function does nothing. */
++
++int asfs_deleteextents(struct super_block *sb, u32 key)
++{
++	struct buffer_head *bh;
++	struct fsExtentBNode *ebn;
++	int errorcode = 0;
++
++	asfs_debug("deleteextents: Entry -- deleting extents from key %d\n", key);
++
++	while (key != 0 && (errorcode = findbnode(sb, key, &bh, (struct BNode **) &ebn)) == 0) {
++		/* node to be deleted located. */
++		key = be32_to_cpu(ebn->next);
++		if ((errorcode = asfs_freespace(sb, be32_to_cpu(ebn->key), be16_to_cpu(ebn->blocks))) != 0)
++			break;
++
++		if ((errorcode = asfs_deletebnode(sb, bh, be32_to_cpu(ebn->key))) != 0)
++			break;
++
++		asfs_brelse(bh);
++	}
++
++	return (errorcode);
++}
++
++   /* This function adds /blocks/ blocks starting at block /newspace/ to a file
++      identified by /objectnode/ and /lastextentbnode/.  /io_lastextentbnode/ can
++      be zero if there is no ExtentBNode chain attached to this file yet.
++      /blocks/ ranges from 1 to 8192.  To be able to extend Extents which are
++      almost full, it is wise to make this value no higher than 8192 blocks.
++      /io_lastextentbnode/ will contain the new lastextentbnode value when this
++      function completes.
++      If there was no chain yet, then this function will create a new one.  */
++
++int asfs_addblocks(struct super_block *sb, u16 blocks, u32 newspace, u32 objectnode, u32 *io_lastextentbnode)
++{
++	struct buffer_head *bh;
++	struct fsExtentBNode *ebn;
++	int errorcode = 0;
++
++	if (*io_lastextentbnode != 0) {
++		/* There was already a ExtentBNode chain for this file.  Extending it. */
++
++		asfs_debug("  addblocks: Extending existing ExtentBNode chain.\n");
++
++		if ((errorcode = asfs_getextent(sb, *io_lastextentbnode, &bh, &ebn)) == 0) {
++			if (be32_to_cpu(ebn->key) + be16_to_cpu(ebn->blocks) == newspace && be16_to_cpu(ebn->blocks) + blocks < 65536) {
++				/* It is possible to extent the last ExtentBNode! */
++				asfs_debug("  addblocks: Extending last ExtentBNode.\n");
++
++				ebn->blocks = cpu_to_be16(be16_to_cpu(ebn->blocks) + blocks);
++
++				asfs_bstore(sb, bh);
++				asfs_brelse(bh);
++			} else {
++				/* It isn't possible to extent the last ExtentBNode so we create
++				   a new one and link it to the last ExtentBNode. */
++
++				ebn->next = cpu_to_be32(newspace);
++				asfs_bstore(sb, bh);
++				asfs_brelse(bh);
++
++				if ((errorcode = createextentbnode(sb, newspace, &bh, (struct BNode **) &ebn)) == 0) {
++					asfs_debug("  addblocks: Created new ExtentBNode.\n");
++
++					ebn->key = cpu_to_be32(newspace);
++					ebn->prev = cpu_to_be32(*io_lastextentbnode);
++					ebn->next = 0;
++					ebn->blocks = cpu_to_be16(blocks);
++
++					*io_lastextentbnode = newspace;
++
++					asfs_bstore(sb, bh);
++					asfs_brelse(bh);
++
++					ASFS_SB(sb)->block_rovingblockptr = newspace + blocks;
++
++	/* to be changed in the future */
++/*					if (ASFS_SB(sb)->block_rovingblockptr >= ASFS_SB(sb)->totalblocks)
++						ASFS_SB(sb)->block_rovingblockptr = 0;*/
++				}
++			}
++		}
++	} else {
++		/* There is no ExtentBNode chain yet for this file.  Attaching one! */
++		if ((errorcode = createextentbnode(sb, newspace, &bh, (struct BNode **) &ebn)) == 0) {
++			asfs_debug("  addblocks: Created new ExtentBNode chain.\n");
++
++			ebn->key = cpu_to_be32(newspace);
++			ebn->prev = cpu_to_be32(objectnode + 0x80000000);
++			ebn->next = 0;
++			ebn->blocks = cpu_to_be16(blocks);
++
++			*io_lastextentbnode = newspace;
++
++			asfs_bstore(sb, bh);
++			asfs_brelse(bh);
++
++			ASFS_SB(sb)->block_rovingblockptr = newspace + blocks;
++
++/*			if (ASFS_SB(sb)->block_rovingblockptr >= ASFS_SB(sb)->totalblocks)
++				ASFS_SB(sb)->block_rovingblockptr = 0;*/
++		}
++	}
++
++	asfs_debug("  addblocks: done.\n");
++
++	return errorcode;
++}
++#endif
+diff -aurN a/fs/asfs/file.c b/fs/asfs/file.c
+--- a/fs/asfs/file.c	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/file.c	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,251 @@
++/*
++ *
++ * Amiga Smart File System, Linux implementation
++ * version: 1.0beta7
++ *  
++ * Copyright (C) 2003,2004  Marek 'March' Szyprowski <marek at amiga.pl>
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/pagemap.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include "asfs_fs.h"
++
++#include <asm/byteorder.h>
++
++static int
++asfs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_result, int create)
++{
++	struct buffer_head *ebn_bh;
++	struct fsExtentBNode extent, *ebn_p;
++	u32 filedata;
++	unsigned long pos;
++	struct super_block *sb = inode->i_sb;
++#ifdef CONFIG_ASFS_RW
++	int error;
++	struct buffer_head *bh;
++	struct fsObject *obj;
++#endif
++
++	asfs_debug("ASFS: get_block(%lu, %ld, %d)\n", inode->i_ino, block, create);
++
++	if (block < 0) {
++		printk(KERN_ERR "ASFS: asfsget_block: requested block (%ld) < 0!\n", block);
++		return -EIO;
++	} else if (block >= inode->i_blocks && !create) {
++		printk(KERN_ERR "ASFS: asfsget_block: strange block request %ld!\n", block);
++		return -EIO;
++	} 
++
++	if (create)
++#ifdef CONFIG_ASFS_RW
++		ASFS_I(inode)->modified = TRUE;
++#else
++		return -EROFS;
++#endif
++
++	if (block < inode->i_blocks)
++		create = 0;
++
++	lock_super(sb);
++
++#ifdef CONFIG_ASFS_RW
++	if (create) {
++		int blockstoadd;
++		u32 newspace, addedblocks;
++
++		blockstoadd = block - inode->i_blocks + 1;
++
++		if (blockstoadd < ASFS_BLOCKCHUNKS)
++			blockstoadd = ASFS_BLOCKCHUNKS;
++ 
++		asfs_debug("ASFS get_block: Trying to add %d blocks to file\n", blockstoadd);
++		
++		if ((error = asfs_readobject(sb, inode->i_ino, &bh, &obj)) != 0) {
++			unlock_super(sb);
++			return error;
++		}
++
++		if ((error = asfs_addblockstofile(sb, bh, obj, blockstoadd, &newspace, &addedblocks)) != 0) {
++			asfs_brelse(bh);
++			unlock_super(sb);
++			return error;
++		}
++		ASFS_I(inode)->mmu_private += addedblocks * sb->s_blocksize;
++		inode->i_blocks += addedblocks;
++		ASFS_I(inode)->ext_cache.key = 0;
++		ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.file.data);
++		asfs_brelse(bh);
++	}
++#endif
++
++	if (ASFS_I(inode)->ext_cache.key > 0 && ASFS_I(inode)->ext_cache.startblock <= block) {
++		extent.key = ASFS_I(inode)->ext_cache.key;
++		extent.next = ASFS_I(inode)->ext_cache.next;
++		extent.blocks = ASFS_I(inode)->ext_cache.blocks;
++		pos = ASFS_I(inode)->ext_cache.startblock;
++	} else {
++		if (asfs_getextent(inode->i_sb, ASFS_I(inode)->firstblock, &ebn_bh, &ebn_p) != 0) {
++			unlock_super(sb);
++			return -EIO;
++		}
++		extent.key = be32_to_cpu(ebn_p->key);
++		extent.next = be32_to_cpu(ebn_p->next);
++		extent.blocks = be16_to_cpu(ebn_p->blocks);
++		pos = 0;
++		asfs_brelse(ebn_bh);
++	}
++	ebn_p = &extent;
++	filedata = ebn_p->next;
++
++	while (pos + ebn_p->blocks <= block && ebn_p->next != 0 && pos < inode->i_blocks) {
++		pos += ebn_p->blocks;
++		if (asfs_getextent(inode->i_sb, filedata, &ebn_bh, &ebn_p) != 0) {
++			unlock_super(sb);
++			return -EIO;
++		}
++		extent.key = be32_to_cpu(ebn_p->key);
++		extent.next = be32_to_cpu(ebn_p->next);
++		extent.blocks = be16_to_cpu(ebn_p->blocks);
++		ebn_p = &extent;	
++		filedata = ebn_p->next;
++		asfs_brelse(ebn_bh);
++	}
++
++	unlock_super(sb);
++
++	map_bh(bh_result, inode->i_sb, (sector_t) (ebn_p->key + block - pos));
++
++	if (create)
++		set_buffer_new(bh_result);
++
++	asfs_debug("ASFS: get_block - mapped block %lu\n", ebn_p->key + block - pos);
++
++	ASFS_I(inode)->ext_cache.startblock = pos;
++	ASFS_I(inode)->ext_cache.key = ebn_p->key;
++	ASFS_I(inode)->ext_cache.next = ebn_p->next;
++	ASFS_I(inode)->ext_cache.blocks = ebn_p->blocks;
++
++	return 0;
++}
++
++int asfs_readpage(struct file *file, struct page *page)
++{
++	asfs_debug("ASFS: %s\n", __FUNCTION__);
++	return block_read_full_page(page, asfs_get_block);
++}
++
++sector_t asfs_bmap(struct address_space *mapping, sector_t block)
++{
++	asfs_debug("ASFS: %s\n", __FUNCTION__);
++	return generic_block_bmap(mapping,block,asfs_get_block);
++}
++
++#ifdef CONFIG_ASFS_RW
++
++int asfs_writepage(struct page *page, struct writeback_control *wbc)
++{
++	asfs_debug("ASFS: %s\n", __FUNCTION__);
++	return block_write_full_page(page, asfs_get_block, wbc);
++}
++
++int asfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
++{
++	asfs_debug("ASFS: %s\n", __FUNCTION__);
++	return cont_prepare_write(page, from, to, asfs_get_block, &ASFS_I(page->mapping->host)->mmu_private);
++}
++
++void asfs_truncate(struct inode *inode)
++{
++	struct super_block *sb = inode->i_sb;
++	struct buffer_head *bh;
++	struct fsObject *obj;
++
++	asfs_debug("AFFS: truncate(inode=%d, oldsize=%u, newsize=%u)\n",
++		 (u32)inode->i_ino, (u32)ASFS_I(inode)->mmu_private, (u32)inode->i_size);
++
++	if (inode->i_size > ASFS_I(inode)->mmu_private) {
++		printk("ASFS: enlarging file is not supported yet\n");
++		return;
++	}
++
++	lock_super(sb);
++
++	if ((asfs_readobject(sb, inode->i_ino, &bh, &obj)) != 0) {
++		unlock_super(sb);
++		return;
++	}
++
++	if (asfs_truncateblocksinfile(sb, bh, obj, inode->i_size) != 0) {
++		asfs_brelse(bh);
++		unlock_super(sb);
++		return;
++	}
++		
++	obj->object.file.size = cpu_to_be32(inode->i_size);
++	ASFS_I(inode)->mmu_private = inode->i_size;
++	ASFS_I(inode)->modified = TRUE;
++	inode->i_blocks = (be32_to_cpu(obj->object.file.size) + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
++	asfs_bstore(sb, bh);
++	asfs_brelse(bh);
++
++	unlock_super(sb);
++}
++
++int asfs_file_open(struct inode *inode, struct file *filp)
++{
++	if (atomic_read(&filp->f_count) != 1)
++		return 0;
++	asfs_debug("ASFS: file open (node %d)\n", (int)inode->i_ino);
++	return 0;
++}
++
++int asfs_file_release(struct inode *inode, struct file *filp)
++{
++	int error = 0;
++
++	asfs_debug("ASFS: file release (node %d oc %d)\n", (int)inode->i_ino, atomic_read(&filp->f_count));
++
++	if (atomic_read(&filp->f_count) != 0)
++		return 0;
++
++	if (ASFS_I(inode)->modified == TRUE) {
++		struct buffer_head *bh;
++		struct fsObject *obj;
++		lock_super(inode->i_sb);
++
++		if ((error = asfs_readobject(inode->i_sb, inode->i_ino, &bh, &obj)) != 0) {
++			unlock_super(inode->i_sb);
++			return error;
++		}
++
++		obj->datemodified = cpu_to_be32(inode->i_mtime.tv_sec - (365*8+2)*24*60*60);
++		if (inode->i_mode & S_IFREG) {
++			error = asfs_truncateblocksinfile(inode->i_sb, bh, obj, (u32)inode->i_size);
++			obj->object.file.size = cpu_to_be32(inode->i_size);
++			ASFS_I(inode)->mmu_private = inode->i_size;
++			inode->i_blocks = (be32_to_cpu(obj->object.file.size) + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
++		}
++		asfs_bstore(inode->i_sb, bh);
++
++		unlock_super(inode->i_sb);
++
++		asfs_brelse(bh);
++	}
++	ASFS_I(inode)->modified = FALSE;
++
++	return error;
++}
++
++#endif
+diff -aurN a/fs/asfs/inode.c b/fs/asfs/inode.c
+--- a/fs/asfs/inode.c	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/inode.c	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,426 @@
++/*
++ *
++ * Amiga Smart File System, Linux implementation
++ * version: 1.0beta8
++ *  
++ * Copyright (C) 2003,2004,2005  Marek 'March' Szyprowski <marek at amiga.pl>
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/smp_lock.h>
++#include <linux/time.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include <linux/dirent.h>
++#include "asfs_fs.h"
++
++#include <asm/byteorder.h>
++
++/* Mapping from our types to the kernel */
++
++static struct address_space_operations asfs_aops = {
++	.readpage	= asfs_readpage,
++	.sync_page	= block_sync_page,
++	.bmap		= asfs_bmap,
++#ifdef CONFIG_ASFS_RW
++	.writepage	= asfs_writepage,
++	.prepare_write = asfs_prepare_write,
++	.commit_write = generic_commit_write,
++#endif
++};
++
++static struct file_operations asfs_file_operations = {
++	.llseek		= generic_file_llseek,
++	.read		= generic_file_read,
++	.mmap		= generic_file_mmap,
++#ifdef CONFIG_ASFS_RW
++	.write		= generic_file_write,
++	.open		= asfs_file_open,
++	.release	= asfs_file_release,
++	.fsync		= file_fsync,
++#endif
++};
++
++static struct file_operations asfs_dir_operations = {
++	.read		= generic_read_dir,
++	.readdir	= asfs_readdir,
++};
++
++static struct inode_operations asfs_dir_inode_operations = {
++	.lookup		= asfs_lookup,
++#ifdef CONFIG_ASFS_RW
++	.create		= asfs_create,
++	.unlink		= asfs_unlink,
++	.symlink	= asfs_symlink,
++	.mkdir		= asfs_mkdir,
++	.rmdir		= asfs_rmdir,
++	.rename		= asfs_rename,
++/*	.setattr	= asfs_notify_change,*/
++#endif
++};
++
++static struct inode_operations asfs_file_inode_operations = {
++#ifdef CONFIG_ASFS_RW
++	.truncate	= asfs_truncate,
++/*	.setattr		= asfs_notify_change,*/
++#endif
++};
++
++static struct address_space_operations asfs_symlink_aops = {
++	.readpage	= asfs_symlink_readpage,
++};
++
++static struct inode_operations asfs_symlink_inode_operations = {
++	.readlink	= page_readlink,
++	.follow_link	= page_follow_link_light,
++	.put_link	= page_put_link,
++#ifdef CONFIG_ASFS_RW
++/*	.setattr	= asfs_notify_change,*/
++#endif
++};
++
++void asfs_read_locked_inode(struct inode *inode, void *arg)
++{
++	struct super_block *sb = inode->i_sb;
++	struct fsObject *obj = arg;
++
++	inode->i_mode = ASFS_SB(sb)->mode;
++	inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = be32_to_cpu(obj->datemodified) + (365*8+2)*24*60*60;  
++	/* Linux: seconds since 01-01-1970, AmigaSFS: seconds since 01-01-1978 */
++	inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_atime.tv_nsec = 0;
++	inode->i_uid = ASFS_SB(sb)->uid;
++	inode->i_gid = ASFS_SB(sb)->gid;
++
++	asfs_debug("asfs_read_inode2: Setting-up node %lu... ", inode->i_ino);
++
++	if (obj->bits & OTYPE_DIR) {
++		asfs_debug("dir (FirstdirBlock: %u, HashTable %u)\n", \
++		           be32_to_cpu(obj->object.dir.firstdirblock), be32_to_cpu(obj->object.dir.hashtable));
++
++		inode->i_size = 0;
++		inode->i_op = &asfs_dir_inode_operations;
++		inode->i_fop = &asfs_dir_operations;
++		inode->i_mode |= S_IFDIR | ((inode->i_mode & 0400) ? 0100 : 0) | 
++		              ((inode->i_mode & 0040) ? 0010 : 0) | ((inode->i_mode & 0004) ? 0001 : 0);
++		ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.dir.firstdirblock);
++		ASFS_I(inode)->hashtable = be32_to_cpu(obj->object.dir.hashtable);
++		ASFS_I(inode)->modified = 0;
++	} else if (obj->bits & OTYPE_LINK && !(obj->bits & OTYPE_HARDLINK)) {
++		asfs_debug("symlink\n");
++		inode->i_size = 0;
++		inode->i_op = &asfs_symlink_inode_operations;
++		inode->i_mapping->a_ops = &asfs_symlink_aops;
++		inode->i_mode |= S_IFLNK | S_IRWXUGO;
++		ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.file.data);
++	} else {
++		asfs_debug("file (Size: %u, FirstBlock: %u)\n", be32_to_cpu(obj->object.file.size), be32_to_cpu(obj->object.file.data));
++		inode->i_size = be32_to_cpu(obj->object.file.size);
++		inode->i_blocks = (be32_to_cpu(obj->object.file.size) + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
++		inode->i_op = &asfs_file_inode_operations;
++		inode->i_fop = &asfs_file_operations;
++		inode->i_mapping->a_ops = &asfs_aops;
++		inode->i_mode |= S_IFREG;
++		ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.file.data);
++		ASFS_I(inode)->ext_cache.startblock = 0;
++		ASFS_I(inode)->ext_cache.key = 0;
++		ASFS_I(inode)->mmu_private = inode->i_size;
++	}
++	return;	
++}
++
++struct inode *asfs_get_root_inode(struct super_block *sb)
++{
++	struct inode *result = NULL;
++	struct fsObject *obj;
++	struct buffer_head *bh;
++
++	asfs_debug("asfs_get_root_inode\n");
++
++	if ((bh = asfs_breadcheck(sb, ASFS_SB(sb)->rootobjectcontainer, ASFS_OBJECTCONTAINER_ID))) {
++		obj = &(((struct fsObjectContainer *)bh->b_data)->object[0]);
++		if (be32_to_cpu(obj->objectnode) > 0)
++			result = iget_locked(sb, be32_to_cpu(obj->objectnode));
++
++		if (result != NULL && result->i_state & I_NEW) {
++			asfs_read_locked_inode(result, obj);
++			unlock_new_inode(result);
++		}
++		asfs_brelse(bh);
++	}
++	return result;
++}
++
++#ifdef CONFIG_ASFS_RW
++
++static void asfs_sync_dir_inode(struct inode *dir, struct fsObject *obj)
++{
++	ASFS_I(dir)->firstblock = be32_to_cpu(obj->object.dir.firstdirblock);
++	ASFS_I(dir)->modified = 1;
++	dir->i_mtime = dir->i_atime = dir->i_ctime = CURRENT_TIME;
++	obj->datemodified = cpu_to_be32(dir->i_mtime.tv_sec - (365*8+2)*24*60*60);
++}
++
++enum { it_file, it_dir, it_link };
++
++static int asfs_create_object(struct inode *dir, struct dentry *dentry, int mode, int type, const char *symname)
++{
++	int error;
++	struct super_block *sb = dir->i_sb;
++	struct inode *inode;
++	struct buffer_head *bh, *dir_bh;
++	struct fsObject obj_data, *dir_obj, *obj;
++	u8 *name = (u8 *) dentry->d_name.name;
++	u8 bufname[ASFS_MAXFN_BUF];
++
++	asfs_debug("asfs_create_obj %s in dir node %d\n", name, (int)dir->i_ino);
++
++	asfs_translate(bufname, name, ASFS_SB(sb)->nls_disk, ASFS_SB(sb)->nls_io, ASFS_MAXFN_BUF);
++	if ((error = asfs_check_name(bufname, strlen(bufname))) != 0)
++		return error;
++
++	sb = dir->i_sb;
++	inode = new_inode(sb);
++	if (!inode)
++		return -ENOMEM;
++
++	memset(&obj_data, 0, sizeof(struct fsObject));
++
++	obj_data.protection = cpu_to_be32(FIBF_READ|FIBF_WRITE|FIBF_EXECUTE|FIBF_DELETE);
++	obj_data.datemodified = cpu_to_be32(inode->i_mtime.tv_sec - (365*8+2)*24*60*60);
++	switch (type) {
++	case it_dir:
++		obj_data.bits = OTYPE_DIR;
++		break;
++	case it_link:
++		obj_data.bits = OTYPE_LINK;
++		break;
++	default:
++		break;
++	}
++
++	lock_super(sb);
++
++	if ((error = asfs_readobject(sb, dir->i_ino, &dir_bh, &dir_obj)) != 0) {
++		dec_count(inode);
++		unlock_super(sb);
++		return error;
++	}
++
++	bh = dir_bh;
++	obj = dir_obj;
++
++	if ((error = asfs_createobject(sb, &bh, &obj, &obj_data, bufname, FALSE)) != 0) {
++		asfs_brelse(dir_bh);
++		dec_count(inode);
++		unlock_super(sb);
++		return error;
++	}
++
++	inode->i_ino = be32_to_cpu(obj->objectnode);
++	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
++	inode->i_size = inode->i_blocks = inode->i_blksize = 0;
++	inode->i_uid = dir->i_uid;
++	inode->i_gid = dir->i_gid;
++	inode->i_mode = mode | ASFS_SB(sb)->mode;
++
++	switch (type) {
++	case it_dir:
++		inode->i_mode |= S_IFDIR;
++		inode->i_op = &asfs_dir_inode_operations;
++		inode->i_fop = &asfs_dir_operations;
++		ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.dir.firstdirblock);
++		ASFS_I(inode)->hashtable = be32_to_cpu(obj->object.dir.hashtable);
++		ASFS_I(inode)->modified = 0;
++		break;
++	case it_file:
++		inode->i_mode |= S_IFREG;
++		inode->i_op = &asfs_file_inode_operations;
++		inode->i_fop = &asfs_file_operations;
++		inode->i_mapping->a_ops = &asfs_aops;
++		ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.file.data);
++		ASFS_I(inode)->ext_cache.startblock = 0;
++		ASFS_I(inode)->ext_cache.key = 0;
++		ASFS_I(inode)->mmu_private = inode->i_size;
++		break;
++	case it_link:
++		inode->i_mode = S_IFLNK | S_IRWXUGO;
++		inode->i_op = &page_symlink_inode_operations;
++		inode->i_mapping->a_ops = &asfs_symlink_aops;
++		ASFS_I(inode)->firstblock = be32_to_cpu(obj->object.file.data);
++		error = asfs_write_symlink(inode, symname);
++		break;
++	default:
++		break;
++	}
++
++	asfs_bstore(sb, bh);
++	insert_inode_hash(inode);
++	mark_inode_dirty(inode);
++	d_instantiate(dentry, inode);
++	asfs_sync_dir_inode(dir, dir_obj);
++	asfs_bstore(sb, dir_bh); 
++
++	unlock_super(sb);
++	asfs_brelse(bh);
++	asfs_brelse(dir_bh);
++	
++	return error;
++}
++
++int asfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
++{
++	return asfs_create_object(dir, dentry, mode, it_file, NULL);
++}
++
++int asfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
++{
++	return asfs_create_object(dir, dentry, mode, it_dir, NULL);
++}
++
++int asfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
++{
++	return asfs_create_object(dir, dentry, 0, it_link, symname);
++}
++
++int asfs_rmdir(struct inode *dir, struct dentry *dentry)
++{
++	asfs_debug("ASFS: %s\n", __FUNCTION__);
++
++	if (ASFS_I(dentry->d_inode)->firstblock != 0)
++		return -ENOTEMPTY;
++	
++	return asfs_unlink(dir, dentry);
++}
++
++int asfs_unlink(struct inode *dir, struct dentry *dentry)
++{
++	struct inode *inode = dentry->d_inode;
++	int error;
++	struct super_block *sb = dir->i_sb;
++	struct buffer_head *bh, *dir_bh;
++	struct fsObject *dir_obj, *obj;
++
++	asfs_debug("ASFS: %s\n", __FUNCTION__);
++
++	lock_super(sb);
++
++	if ((error = asfs_readobject(sb, inode->i_ino, &bh, &obj)) != 0) {
++		unlock_super(sb);
++		return error;
++	}
++	if ((error = asfs_deleteobject(sb, bh, obj)) != 0) {
++		asfs_brelse(bh);
++		unlock_super(sb);
++		return error;
++	}
++	asfs_brelse(bh);
++
++	/* directory data could change after removing the object */
++	if ((error = asfs_readobject(sb, dir->i_ino, &dir_bh, &dir_obj)) != 0) {
++		unlock_super(sb);
++		return error;
++	}
++
++	asfs_sync_dir_inode(dir, dir_obj);
++	asfs_bstore(sb, dir_bh); 
++
++	dec_count(inode);
++	unlock_super(sb);
++	asfs_brelse(dir_bh);
++
++	return 0;
++}
++
++int asfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
++{
++	struct super_block *sb = old_dir->i_sb;
++	struct buffer_head *src_bh, *old_bh, *new_bh;
++	int error;
++	struct fsObject *src_obj, *old_obj, *new_obj;
++	u8 bufname[ASFS_MAXFN_BUF];
++
++	asfs_debug("ASFS: rename (old=%u,\"%*s\" to new=%u,\"%*s\")\n",
++		 (u32)old_dir->i_ino, (int)old_dentry->d_name.len, old_dentry->d_name.name,
++		 (u32)new_dir->i_ino, (int)new_dentry->d_name.len, new_dentry->d_name.name);
++
++	asfs_translate(bufname, (u8 *) new_dentry->d_name.name, ASFS_SB(sb)->nls_disk, ASFS_SB(sb)->nls_io, ASFS_MAXFN_BUF);
++	if ((error = asfs_check_name(bufname, strlen(bufname))) != 0)
++		return error;
++
++
++	/* Unlink destination if it already exists */
++	if (new_dentry->d_inode) 
++		if ((error = asfs_unlink(new_dir, new_dentry)) != 0)
++			return error;
++
++	lock_super(sb);
++
++	if ((error = asfs_readobject(sb, old_dentry->d_inode->i_ino, &src_bh, &src_obj)) != 0) {
++		unlock_super(sb);
++		return error;
++	}
++	if ((error = asfs_readobject(sb, new_dir->i_ino, &new_bh, &new_obj)) != 0) {
++		asfs_brelse(src_bh);
++		unlock_super(sb);
++		return error;
++	}
++
++	if ((error = asfs_renameobject(sb, src_bh, src_obj, new_bh, new_obj, bufname)) != 0) {
++		asfs_brelse(src_bh);
++		asfs_brelse(new_bh);
++		unlock_super(sb);
++		return error;
++	}
++	asfs_brelse(src_bh);
++	asfs_brelse(new_bh);
++
++	if ((error = asfs_readobject(sb, old_dir->i_ino, &old_bh, &old_obj)) != 0) {
++		unlock_super(sb);
++		return error;
++	}
++	if ((error = asfs_readobject(sb, new_dir->i_ino, &new_bh, &new_obj)) != 0) {
++		asfs_brelse(old_bh);
++		unlock_super(sb);
++		return error;
++	}
++
++	asfs_sync_dir_inode(old_dir, old_obj);
++	asfs_sync_dir_inode(new_dir, new_obj);
++
++	asfs_bstore(sb, new_bh);	
++	asfs_bstore(sb, old_bh);
++
++	unlock_super(sb);
++	asfs_brelse(old_bh);
++	asfs_brelse(new_bh);
++
++	mark_inode_dirty(old_dir);
++	mark_inode_dirty(new_dir);
++
++	return 0;
++}
++
++/*
++int asfs_notify_change(struct dentry *dentry, struct iattr *attr)
++{
++	struct inode *inode = dentry->d_inode;
++	int error = 0;
++
++	asfs_debug("ASFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid);
++
++	error = inode_change_ok(inode,attr);
++
++	return error;
++}
++*/
++#endif
+diff -aurN a/fs/asfs/namei.c b/fs/asfs/namei.c
+--- a/fs/asfs/namei.c	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/namei.c	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,197 @@
++/*
++ *
++ * Amiga Smart File System, Linux implementation
++ * version: 1.0beta7
++ *
++ * Copyright (C) 2003,2004  Marek 'March' Szyprowski <marek at amiga.pl>
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/fs.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include <linux/string.h>
++#include <linux/nls.h>
++#include "asfs_fs.h"
++
++static inline u8 asfs_upperchar(u8 c)
++{
++	if ((c >= 224 && c <= 254 && c != 247) || (c >= 'a' && c <= 'z'))
++		c -= 32;
++	return (c);
++}
++
++u8 asfs_lowerchar(u8 c)
++{
++	if ((c >= 192 && c <= 222 && c != 215) || (c >= 'A' && c <= 'Z'))
++		c += 32;
++	return (c);
++}
++
++static inline u8 asfs_nls_upperchar(u8 c, struct nls_table *t)
++{
++	if (t) {
++		u8 nc = t->charset2upper[c];
++		return nc ? nc : c;
++	} else
++		return asfs_upperchar(c);
++}
++
++/* Check if the name is valid for a asfs object. */
++
++inline int asfs_check_name(const u8 *name, int len)
++{
++	int i;
++
++	if (len > ASFS_MAXFN)
++		return -ENAMETOOLONG;
++
++	for (i = 0; i < len; i++)
++		if (name[i] < ' ' || name[i] == ':' || (name[i] > 0x7e && name[i] < 0xa0))
++			return -EINVAL;
++
++	return 0;
++}
++
++/* Note: the dentry argument is the parent dentry. */
++
++static int asfs_hash_dentry(struct dentry *dentry, struct qstr *qstr)
++{
++	struct super_block *sb = dentry->d_inode->i_sb;
++	const u8 *name = qstr->name;
++	unsigned long hash;
++	int i;
++	struct nls_table *nls_io = ASFS_SB(sb)->nls_io;
++
++	i = asfs_check_name(qstr->name,qstr->len);
++	if (i)
++		return i;
++
++	hash = init_name_hash();
++
++	if (ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE)
++		for (i=qstr->len; i > 0; name++, i--)
++			hash = partial_name_hash(*name, hash);
++	else
++		for (i=qstr->len; i > 0; name++, i--)
++			hash = partial_name_hash(asfs_nls_upperchar(*name, nls_io), hash);
++
++	qstr->hash = end_name_hash(hash);
++
++	return 0;
++}
++
++static int asfs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
++{
++	struct super_block *sb = dentry->d_inode->i_sb;
++	const u8 *aname = a->name;
++	const u8 *bname = b->name;
++	int len;
++	struct nls_table *nls_io = ASFS_SB(sb)->nls_io;
++
++	/* 'a' is the qstr of an already existing dentry, so the name
++	 * must be valid. 'b' must be validated first.
++	 */
++
++	if (asfs_check_name(b->name,b->len))
++		return 1;
++
++	if (a->len != b->len)
++		return 1;
++
++	if (ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE) {
++		for (len=a->len; len > 0; len--)
++			if (*aname++ != *bname++)
++				return 1;
++	} else {
++		for (len=a->len; len > 0; len--)
++			if (asfs_nls_upperchar(*aname++, nls_io) != asfs_nls_upperchar(*bname++, nls_io))
++				return 1;
++	}
++
++	return 0;
++}
++
++struct dentry_operations asfs_dentry_operations = {
++	d_hash:		asfs_hash_dentry,
++	d_compare:	asfs_compare_dentry,
++};
++
++int asfs_namecmp(u8 *s, u8 *ct, int casesensitive, struct nls_table *t)
++{
++	if (casesensitive) {
++		while (*s == *ct && *ct != '\0' && *ct != '/') {
++			s++;
++			ct++;
++		}
++	} else {
++		while (asfs_nls_upperchar(*s, t) == asfs_nls_upperchar(*ct, t) && *ct != '\0'
++		       && *ct != '/') {
++			s++;
++			ct++;
++		}
++	}
++	return (*s == '\0' && (*ct == '\0' || *ct == '/')) ? 0 : *ct - *s;
++}
++
++u16 asfs_hash(u8 *name, int casesensitive)
++{
++	u16 hashval = 0;
++	while (name[hashval] != 0 && name[hashval] != '/')
++		hashval++;
++	if (casesensitive) {
++		u8 c = *name;
++		while (c != 0 && c != '/') {
++			hashval = hashval * 13 + c;
++			c = *++name;
++		}
++	} else {
++		u8 c = *name;
++		while (c != 0 && c != '/') {
++			hashval = hashval * 13 + asfs_upperchar(c);
++			c = *++name;
++		}
++	}
++	return hashval;
++}
++
++void asfs_translate(u8 *to, u8 *from, struct nls_table *nls_to, struct nls_table *nls_from, int limit)
++{
++	wchar_t uni;
++	int i, len;
++	int from_len, to_len = limit;
++
++	if (nls_to) {
++		from_len = strlen(from);
++		for (i=0; i < from_len && to_len > 1; ) {
++			len = nls_from->char2uni(&from[i], from_len-i, &uni);
++			if (len > 0) {
++				i += len;
++				len = nls_to->uni2char(uni, to, to_len);
++				if (len > 0) {
++					to += len;
++					to_len -= len;
++				}
++			} else
++				i++;
++			if (len < 0) {
++				*to++ = '?';
++				to_len--;
++			}
++		}
++		*to = '\0';
++	} else {
++		strncpy (to, from, limit);
++		to[limit] = '\0';
++	}
++}
+diff -aurN a/fs/asfs/nodes.c b/fs/asfs/nodes.c
+--- a/fs/asfs/nodes.c	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/nodes.c	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,455 @@
++/*
++ *
++ * Amiga Smart File System, Linux implementation
++ * version: 1.0beta7
++ *
++ * This file contains some parts of the original amiga version of 
++ * SmartFilesystem source code.
++ *
++ * SmartFilesystem is copyrighted (C) 2003 by: John Hendrikx, 
++ * Ralph Schmidt, Emmanuel Lesueur, David Gerber and Marcin Kurek
++ * 
++ * Adapted and modified by Marek 'March' Szyprowski <marek at amiga.pl>
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include "asfs_fs.h"
++
++#include <asm/byteorder.h>
++
++/* Finds a specific node by number. */
++int asfs_getnode(struct super_block *sb, u32 nodeno, struct buffer_head **ret_bh, struct fsObjectNode **ret_node)
++{
++	struct buffer_head *bh;
++	struct fsNodeContainer *nodecont;
++	u32 nodeindex = ASFS_SB(sb)->objectnoderoot;
++
++	while ((bh = asfs_breadcheck(sb, nodeindex, ASFS_NODECONTAINER_ID))) {
++		nodecont = (struct fsNodeContainer *) bh->b_data;
++
++		if (be32_to_cpu(nodecont->nodes) == 1) {
++			*ret_node = (struct fsObjectNode *) ((u8 *) nodecont->node + NODE_STRUCT_SIZE * (nodeno - be32_to_cpu(nodecont->nodenumber)));
++			*ret_bh = bh;
++			return 0;
++		} else {
++			u16 containerentry = (nodeno - be32_to_cpu(nodecont->nodenumber)) / be32_to_cpu(nodecont->nodes);
++			nodeindex = be32_to_cpu(nodecont->node[containerentry]) >> (sb->s_blocksize_bits - ASFS_BLCKFACCURACY);
++		}
++		asfs_brelse(bh);
++	}
++	if (bh == NULL)
++		return -EIO;
++	return -ENOENT;
++}
++
++#ifdef CONFIG_ASFS_RW
++
++	/* Looks for the parent of the passed-in buffer_head (fsNodeContainer)
++	   starting from the root.  It returns an error if any error occured.
++	   If error is 0 and io_bh is NULL as well, then there was no parent (ie,
++	   you asked parent of the root).  Otherwise io_bh should contain the
++	   parent of the passed-in NodeContainer. */
++
++static int parentnodecontainer(struct super_block *sb, struct buffer_head **io_bh)
++{
++	u32 noderoot = ASFS_SB(sb)->objectnoderoot;
++	u32 childblock = be32_to_cpu(((struct fsBlockHeader *) (*io_bh)->b_data)->ownblock);
++	u32 nodenumber = be32_to_cpu(((struct fsNodeContainer *) (*io_bh)->b_data)->nodenumber);
++	int errorcode = 0;
++
++	if (noderoot == childblock) {
++		*io_bh = NULL;
++		return 0;
++	}
++
++	while ((*io_bh = asfs_breadcheck(sb, noderoot, ASFS_NODECONTAINER_ID))) {
++		struct fsNodeContainer *nc = (void *) (*io_bh)->b_data;
++
++		if (be32_to_cpu(nc->nodes) == 1) {
++			/* We've descended the tree to a leaf NodeContainer, something
++			   which should never happen if the passed-in io_bh had
++			   contained a valid fsNodeContainer. */
++			printk("ASFS: Failed to locate the parent NodeContainer - node tree is corrupted!\n");
++			*io_bh = NULL;
++			return -EIO;
++		} else {
++			u16 containerentry = (nodenumber - be32_to_cpu(nc->nodenumber)) / be32_to_cpu(nc->nodes);
++			noderoot = be32_to_cpu(nc->node[containerentry]) >> (sb->s_blocksize_bits - ASFS_BLCKFACCURACY);
++		}
++
++		if (noderoot == childblock)
++			break;
++
++		asfs_brelse(*io_bh);
++	}
++
++	if (*io_bh == NULL)
++		return -EIO;
++
++	return errorcode;
++}
++
++
++static int isfull(struct super_block *sb, struct fsNodeContainer *nc)
++{
++	u32 *p = nc->node;
++	s16 n = NODECONT_BLOCK_COUNT;
++
++	while (--n >= 0) {
++		if (*p == 0 || (be32_to_cpu(*p) & 0x00000001) == 0) {
++			break;
++		}
++		p++;
++	}
++
++	return n < 0;
++}
++
++static int markparentfull(struct super_block *sb, struct buffer_head *bh)
++{
++	u32 nodenumber = be32_to_cpu(((struct fsNodeContainer *) (bh->b_data))->nodenumber);
++	int errorcode;
++
++	if ((errorcode = parentnodecontainer(sb, &bh)) == 0 && bh != 0) {
++		struct fsNodeContainer *nc = (void *) bh->b_data;
++		u16 containerentry = (nodenumber - be32_to_cpu(nc->nodenumber)) / be32_to_cpu(nc->nodes);
++
++		nc->node[containerentry] = cpu_to_be32(be32_to_cpu(nc->node[containerentry]) | 0x00000001);
++
++		asfs_bstore(sb, bh);
++
++		if (isfull(sb, nc)) {	/* This container now is full as well!  Mark the next higher up container too then! */
++			return markparentfull(sb, bh);
++		}
++		asfs_brelse(bh);
++	}
++
++	return errorcode;
++}
++
++static int addnewnodelevel(struct super_block *sb, u16 nodesize)
++{
++	struct buffer_head *bh;
++	u32 noderoot = ASFS_SB(sb)->objectnoderoot;
++	int errorcode;
++
++	/* Adds a new level to the Node tree. */
++
++	asfs_debug("addnewnodelevel: Entry\n");
++
++	if ((bh = asfs_breadcheck(sb, noderoot, ASFS_NODECONTAINER_ID))) {
++		struct buffer_head *newbh;
++		u32 newblock;
++
++		if ((errorcode = asfs_allocadminspace(sb, &newblock)) == 0 && (newbh = asfs_getzeroblk(sb, newblock))) {
++			struct fsNodeContainer *nc = (void *) bh->b_data;
++			struct fsNodeContainer *newnc = (void *) newbh->b_data;
++
++			/* The newly allocated block will become a copy of the current root. */
++
++			newnc->bheader.id = cpu_to_be32(ASFS_NODECONTAINER_ID);
++			newnc->bheader.ownblock = cpu_to_be32(newblock);
++			newnc->nodenumber = nc->nodenumber;
++			newnc->nodes = nc->nodes;
++			memcpy(newnc->node, nc->node, sb->s_blocksize - sizeof(struct fsNodeContainer));
++
++			asfs_bstore(sb, newbh);
++			asfs_brelse(newbh);
++
++			/* The current root will now be transformed into a new root. */
++
++			if (be32_to_cpu(nc->nodes) == 1)
++				nc->nodes = cpu_to_be32((sb->s_blocksize - sizeof(struct fsNodeContainer)) / nodesize);
++			else
++				nc->nodes = cpu_to_be32(be32_to_cpu(nc->nodes) * NODECONT_BLOCK_COUNT);
++
++			nc->node[0] = cpu_to_be32((newblock << (sb->s_blocksize_bits - ASFS_BLCKFACCURACY)) + 1);	/* Tree is full from that point! */
++			memset(&nc->node[1], 0, sb->s_blocksize - sizeof(struct fsNodeContainer) - 4);
++
++			asfs_bstore(sb, bh);
++		}
++		asfs_brelse(bh);
++	} else
++		errorcode = -EIO;
++
++	return errorcode;
++}
++
++static int createnodecontainer(struct super_block *sb, u32 nodenumber, u32 nodes, u32 * returned_block)
++{
++	struct buffer_head *bh;
++	int errorcode;
++	u32 newblock;
++
++	asfs_debug("createnodecontainer: nodenumber = %u, nodes = %u\n", nodenumber, nodes);
++
++	if ((errorcode = asfs_allocadminspace(sb, &newblock)) == 0 && (bh = asfs_getzeroblk(sb, newblock))) {
++		struct fsNodeContainer *nc = (void *) bh->b_data;
++
++		nc->bheader.id = cpu_to_be32(ASFS_NODECONTAINER_ID);
++		nc->bheader.ownblock = cpu_to_be32(newblock);
++
++		nc->nodenumber = cpu_to_be32(nodenumber);
++		nc->nodes = cpu_to_be32(nodes);
++
++		asfs_bstore(sb, bh);
++		asfs_brelse(bh);
++		*returned_block = newblock;
++	}
++
++	return errorcode;
++}
++
++	/* This function creates a new fsNode structure in a fsNodeContainer.  If needed
++	   it will create a new fsNodeContainers and a new fsNodeIndexContainer. */
++
++int asfs_createnode(struct super_block *sb, struct buffer_head **returned_bh, struct fsNode **returned_node, u32 * returned_nodeno)
++{
++	u16 nodecount = (sb->s_blocksize - sizeof(struct fsNodeContainer)) / NODE_STRUCT_SIZE;
++	u32 noderoot = ASFS_SB(sb)->objectnoderoot;
++	u32 nodeindex = noderoot;
++	int errorcode = 0;
++
++	while ((*returned_bh = asfs_breadcheck(sb, nodeindex, ASFS_NODECONTAINER_ID))) {
++		struct fsNodeContainer *nc = (void *) (*returned_bh)->b_data;
++
++		if (be32_to_cpu(nc->nodes) == 1) {	/* Is it a leaf-container? */
++			struct fsNode *n;
++			s16 i = nodecount;
++
++			n = (struct fsNode *) nc->node;
++
++			while (i-- > 0) {
++				if (n->data == 0)
++					break;
++
++				n = (struct fsNode *) ((u8 *) n + NODE_STRUCT_SIZE);
++			}
++
++			if (i >= 0) {
++				/* Found an empty fsNode structure! */
++				*returned_node = n;
++				*returned_nodeno = be32_to_cpu(nc->nodenumber) + ((u8 *) n - (u8 *) nc->node) / NODE_STRUCT_SIZE;
++
++				asfs_debug("createnode: Created Node %d\n", *returned_nodeno);
++
++				/* Below we continue to look through the NodeContainer block.  We skip the entry
++				   we found to be unused, and see if there are any more unused entries.  If we
++				   do not find any more unused entries then this container is now full. */
++
++				n = (struct fsNode *) ((u8 *) n + NODE_STRUCT_SIZE);
++
++				while (i-- > 0) {
++					if (n->data == 0)
++						break;
++
++					n = (struct fsNode *) ((u8 *) n + NODE_STRUCT_SIZE);
++				}
++
++				if (i < 0) {
++					/* No more empty fsNode structures in this block.  Mark parent full. */
++					errorcode = markparentfull(sb, *returned_bh);
++				}
++
++				return errorcode;
++			} else {
++				/* What happened now is that we found a leaf-container which was
++				   completely filled.  In practice this should only happen when there
++				   is only a single NodeContainer (only this container), or when there
++				   was an error in one of the full-bits in a higher level container. */
++
++				if (noderoot != nodeindex) {
++					/*** Hmmm... it looks like there was a damaged full-bit or something.
++					     In this case we'd probably better call markcontainerfull. */
++
++					printk("ASFS: Couldn't find empty Node in NodeContainer while NodeIndexContainer indicated there should be one!\n");
++
++					errorcode = -ENOSPC;
++					break;
++				} else {
++					/* Container is completely filled. */
++
++					if ((errorcode = addnewnodelevel(sb, NODE_STRUCT_SIZE)) != 0)
++						return errorcode;
++
++					nodeindex = noderoot;
++				}
++			}
++		} else {	/* This isn't a leaf container */
++			u32 *p = nc->node;
++			s16 i = NODECONT_BLOCK_COUNT;
++
++			/* We've read a normal container */
++
++			while (i-- > 0) {
++				if (*p != 0 && (be32_to_cpu(*p) & 0x00000001) == 0)
++					break;
++
++				p++;
++			}
++
++			if (i >= 0) {
++				/* Found a not completely filled Container */
++
++				nodeindex = be32_to_cpu(*p) >> (sb->s_blocksize_bits - ASFS_BLCKFACCURACY);
++			} else {
++				/* Everything in the NodeIndexContainer was completely filled.  There possibly
++				   are some unused pointers in this block however.  */
++
++				asfs_debug("createnode: NodeContainer at block has no empty Nodes.\n");
++
++				p = nc->node;
++				i = NODECONT_BLOCK_COUNT;
++
++				while (i-- > 0) {
++					if (*p == 0)
++						break;
++
++					p++;
++				}
++
++				if (i >= 0) {
++					u32 newblock;
++					u32 nodes;
++
++					/* Found an unused Container pointer */
++
++					if (be32_to_cpu(nc->nodes) == (sb->s_blocksize - sizeof(struct fsNodeContainer)) / NODE_STRUCT_SIZE) {
++						nodes = 1;
++					} else {
++						nodes = be32_to_cpu(nc->nodes) / NODECONT_BLOCK_COUNT;
++					}
++
++					if ((errorcode = createnodecontainer(sb, be32_to_cpu(nc->nodenumber) + (p - nc->node) * be32_to_cpu(nc->nodes), nodes, &newblock)) != 0) {
++						break;
++					}
++
++					*p = cpu_to_be32(newblock << (sb->s_blocksize_bits - ASFS_BLCKFACCURACY));
++
++					asfs_bstore(sb, *returned_bh);
++				} else {
++					/* Container is completely filled.  This must be the top-level NodeIndex container
++					   as otherwise the full-bit would have been wrong! */
++
++					if ((errorcode = addnewnodelevel(sb, NODE_STRUCT_SIZE)) != 0)
++						break;
++
++					nodeindex = noderoot;
++				}
++			}
++		}
++		asfs_brelse(*returned_bh);
++	}
++
++	if (*returned_bh == NULL)
++		return -EIO;
++
++	return (errorcode);
++}
++
++static int markparentempty(struct super_block *sb, struct buffer_head *bh)
++{
++	u32 nodenumber = be32_to_cpu(((struct fsNodeContainer *) bh->b_data)->nodenumber);
++	int errorcode;
++
++	if ((errorcode = parentnodecontainer(sb, &bh)) == 0 && bh != 0) {
++		struct fsNodeContainer *nc = (void *) bh->b_data;
++		int wasfull;
++		u16 containerentry = (nodenumber - be32_to_cpu(nc->nodenumber)) / be32_to_cpu(nc->nodes);
++
++		wasfull = isfull(sb, nc);
++
++		nc->node[containerentry] = cpu_to_be32(be32_to_cpu(nc->node[containerentry]) & ~0x00000001);
++
++		asfs_bstore(sb, bh);
++
++		if (wasfull) {
++			/* This container was completely full before!  Mark the next higher up container too then! */
++			return markparentempty(sb, bh);
++		}
++		asfs_brelse(bh);
++	}
++
++	return errorcode;
++}
++
++static int freecontainer(struct super_block *sb, struct buffer_head *bh)
++{
++	u32 nodenumber = be32_to_cpu(((struct fsNodeContainer *) bh->b_data)->nodenumber);
++	int errorcode;
++
++	if ((errorcode = parentnodecontainer(sb, &bh)) == 0 && bh != NULL) {	/* This line also prevents the freeing of the noderoot. */
++		struct fsNodeContainer *nc = (void *) bh->b_data;
++		u16 containerindex = (nodenumber - be32_to_cpu(nc->nodenumber)) / be32_to_cpu(nc->nodes);
++
++		if ((errorcode = asfs_freeadminspace(sb, be32_to_cpu(nc->node[containerindex]) >> (sb->s_blocksize_bits - ASFS_BLCKFACCURACY))) == 0) {
++			u32 *p = nc->node;
++			s16 n = NODECONT_BLOCK_COUNT;
++
++			nc->node[containerindex] = 0;
++			asfs_bstore(sb, bh);
++
++			while (n-- > 0)
++				if (*p++ != 0)
++					break;
++
++			if (n < 0) {	/* This container is now completely empty!  Free this NodeIndexContainer too then! */
++				return freecontainer(sb, bh);
++			}
++		}
++		asfs_brelse(bh);
++	}
++
++	return errorcode;
++}
++
++static int internaldeletenode(struct super_block *sb, struct buffer_head *bh, struct fsNode *n)
++{
++	struct fsNodeContainer *nc = (void *) bh->b_data;
++	u16 nodecount = (sb->s_blocksize - sizeof(struct fsNodeContainer)) / NODE_STRUCT_SIZE;
++	s16 i = nodecount;
++	s16 empty = 0;
++	int errorcode = 0;
++
++	n->data = 0;
++	n = (struct fsNode *) nc->node;
++
++	while (i-- > 0) {
++		if (n->data == 0)
++			empty++;
++
++		n = (struct fsNode *) ((u8 *) n + NODE_STRUCT_SIZE);
++	}
++
++	asfs_bstore(sb, bh);
++
++	if (empty == 1)		/* NodeContainer was completely full before, so we need to mark it empty now. */
++		errorcode = markparentempty(sb, bh);
++	else if (empty == nodecount)	/* NodeContainer is now completely empty!  Free it! */
++		errorcode = freecontainer(sb, bh);
++
++	return (errorcode);
++}
++
++int asfs_deletenode(struct super_block *sb, u32 objectnode)
++{
++	struct buffer_head *bh;
++	struct fsObjectNode *on;
++	int errorcode;
++
++	asfs_debug("deletenode: Deleting Node %d\n", objectnode);
++
++	if ((errorcode = asfs_getnode(sb, objectnode, &bh, &on)) == 0)
++		errorcode = internaldeletenode(sb, bh, (struct fsNode *) on);
++
++	asfs_brelse(bh);
++	return (errorcode);
++}
++
++#endif
+diff -aurN a/fs/asfs/objects.c b/fs/asfs/objects.c
+--- a/fs/asfs/objects.c	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/objects.c	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,765 @@
++/*
++ *
++ * Amiga Smart File System, Linux implementation
++ * version: 1.0beta7
++ *
++ * This file contains some parts of the original amiga version of 
++ * SmartFilesystem source code.
++ *
++ * SmartFilesystem is copyrighted (C) 2003 by: John Hendrikx, 
++ * Ralph Schmidt, Emmanuel Lesueur, David Gerber, and Marcin Kurek
++ * 
++ * Adapted and modified by Marek 'March' Szyprowski <marek at amiga.pl>
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include "asfs_fs.h"
++
++#include <asm/byteorder.h>
++
++struct fsObject *asfs_nextobject(struct fsObject *obj)
++{
++	int i;
++	u8 *p = obj->name;
++
++	for (i = 2; i > 0; p++)
++		if (*p == '\0')
++			i--;
++	if ((p - (u8 *) obj) & 0x01)
++		p++;
++
++	return ((struct fsObject *) p);
++}
++
++struct fsObject *asfs_find_obj_by_name(struct super_block *sb, struct fsObjectContainer *objcont, u8 * name)
++{
++	struct fsObject *obj;
++
++	obj = &(objcont->object[0]);
++	while (be32_to_cpu(obj->objectnode) > 0 && ((char *) obj - (char *) objcont) + sizeof(struct fsObject) + 2 < sb->s_blocksize) {
++		if (asfs_namecmp(obj->name, name, ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE, NULL) == 0) {
++			asfs_debug("Object found! Node %u, Name %s, Type %x, inCont %u\n", be32_to_cpu(obj->objectnode), obj->name, obj->bits, be32_to_cpu(objcont->bheader.ownblock));
++			return obj;
++		}
++		obj = asfs_nextobject(obj);
++	}
++	return NULL;
++}
++
++#ifdef CONFIG_ASFS_RW
++
++struct fsObject *find_obj_by_node(struct super_block *sb, struct fsObjectContainer *objcont, u32 objnode)
++{
++	struct fsObject *obj;
++
++	obj = &(objcont->object[0]);
++	while (be32_to_cpu(obj->objectnode) > 0 && ((char *) obj - (char *) objcont) + sizeof(struct fsObject) + 2 < sb->s_blocksize) {
++		if (be32_to_cpu(obj->objectnode) == objnode) {
++			return obj;
++		}
++		obj = asfs_nextobject(obj);
++	}
++	return NULL;
++}
++
++int asfs_readobject(struct super_block *sb, u32 objectnode, struct buffer_head **bh, struct fsObject **returned_object)
++{
++	struct fsObjectNode *on;
++	int errorcode;
++	u32 contblock;
++
++	asfs_debug("Seaching object - node %d\n", objectnode);
++
++	if ((errorcode = asfs_getnode(sb, objectnode, bh, &on)) != 0)
++		return errorcode;
++	contblock = be32_to_cpu(on->node.data);
++	asfs_brelse(*bh);
++
++	if (contblock > 0 && (*bh = asfs_breadcheck(sb, contblock, ASFS_OBJECTCONTAINER_ID))) {
++		*returned_object = find_obj_by_node(sb, (void *) (*bh)->b_data, objectnode);
++		if (*returned_object == NULL) {
++			brelse(*bh);
++			*bh = NULL;
++			return -ENOENT;
++		}
++		return 0;
++	} else
++		return -EIO;
++}
++
++static int removeobjectcontainer(struct super_block *sb, struct buffer_head *bh)
++{
++	struct fsObjectContainer *oc = (void *) bh->b_data;
++	int errorcode;
++	struct buffer_head *block;
++
++	asfs_debug("removeobjectcontainer: block %u\n", be32_to_cpu(oc->bheader.ownblock));
++
++	if (oc->next != 0 && oc->next != oc->bheader.ownblock) {
++		struct fsObjectContainer *next_oc;
++
++		if ((block = asfs_breadcheck(sb, be32_to_cpu(oc->next), ASFS_OBJECTCONTAINER_ID)) == NULL)
++			return -EIO;
++
++		next_oc = (void *) block->b_data;
++		next_oc->previous = oc->previous;
++
++		asfs_bstore(sb, block);
++		asfs_brelse(block);
++	}
++
++	if (oc->previous != 0 && oc->previous != oc->bheader.ownblock) {
++		struct fsObjectContainer *previous_oc;
++
++		if ((block = asfs_breadcheck(sb, be32_to_cpu(oc->previous), ASFS_OBJECTCONTAINER_ID)) == NULL)
++			return -EIO;
++
++		previous_oc = (void *) block->b_data;
++		previous_oc->next = oc->next;
++
++		asfs_bstore(sb, block);
++		asfs_brelse(block);
++	} else {
++		struct fsObject *parent_o;
++
++		if ((errorcode = asfs_readobject(sb, be32_to_cpu(oc->parent), &block, &parent_o)) != 0)
++			return (errorcode);
++
++		parent_o->object.dir.firstdirblock = oc->next;
++
++		asfs_bstore(sb, block);
++		asfs_brelse(block);
++	}
++
++	if ((errorcode = asfs_freeadminspace(sb, be32_to_cpu(oc->bheader.ownblock))) != 0)
++		return (errorcode);
++
++	return (0);
++}
++
++static int setrecycledinfodiff(struct super_block *sb, s32 deletedfiles, s32 deletedblocks)
++{
++	struct buffer_head *bh;
++
++	if ((bh = asfs_breadcheck(sb, ASFS_SB(sb)->rootobjectcontainer, ASFS_OBJECTCONTAINER_ID))) {
++		struct fsRootInfo *ri = (struct fsRootInfo *) ((u8 *) bh->b_data + sb->s_blocksize - sizeof(struct fsRootInfo));
++
++		ri->deletedfiles = cpu_to_be32(be32_to_cpu(ri->deletedfiles) + deletedfiles);
++		ri->deletedblocks = cpu_to_be32(be32_to_cpu(ri->deletedblocks) + deletedblocks);
++
++		asfs_bstore(sb, bh);
++		asfs_brelse(bh);
++	} else
++		return -EIO;
++	return 0;
++}
++
++	/* This function removes the fsObject structure passed in from the passed
++	   buffer_head.  If the ObjectContainer becomes completely empty it will be 
++	   delinked from the ObjectContainer chain and marked free for reuse.
++	   This function doesn't delink the object from the hashchain! */
++
++static int simpleremoveobject(struct super_block *sb, struct buffer_head *bh, struct fsObject *o)
++{
++	struct fsObjectContainer *oc = (void *) bh->b_data;
++	int errorcode = 0;
++
++	asfs_debug("simpleremoveobject:\n");
++
++	if (be32_to_cpu(oc->parent) == ASFS_RECYCLEDNODE) {
++		/* This object is removed from the Recycled directory. */
++		if ((errorcode = setrecycledinfodiff(sb, -1, -((be32_to_cpu(o->object.file.size) + sb->s_blocksize - 1) >> sb->s_blocksize_bits))) != 0)
++			return errorcode;
++	}
++
++	if ((asfs_nextobject(oc->object))->name[0] == '\0')
++		errorcode = removeobjectcontainer(sb, bh);
++	else {
++		struct fsObject *nexto;
++		int objlen;
++
++		nexto = asfs_nextobject(o);
++		objlen = (u8 *) nexto - (u8 *) o;
++
++		memmove(o, nexto, sb->s_blocksize - ((u8 *) nexto - (u8 *) oc));
++		memset((u8 *) oc + sb->s_blocksize - objlen, 0, objlen);
++
++		asfs_bstore(sb, bh);
++	}
++	return errorcode;
++}
++
++/* This function delinks the passed in ObjectNode from its hash-chain.  Handy when deleting
++   the object, or when renaming/moving it. */
++
++static int dehashobjectquick(struct super_block *sb, u32 objectnode, u8 *name, u32 parentobjectnode)
++{
++	struct fsObject *o;
++	int errorcode = 0;
++	struct buffer_head *block;
++
++	asfs_debug("dehashobject: Delinking object %d (=ObjectNode) from hashchain. Parentnode = %d\n", objectnode, parentobjectnode);
++
++	if ((errorcode = asfs_readobject(sb, parentobjectnode, &block, &o)) == 0 && o->object.dir.hashtable != 0) {
++		u32 hashtable = be32_to_cpu(o->object.dir.hashtable);
++		asfs_brelse(block);
++
++		if ((block = asfs_breadcheck(sb, hashtable, ASFS_HASHTABLE_ID))) {
++			struct buffer_head *node_bh;
++			struct fsObjectNode *onptr, on;
++			struct fsHashTable *ht = (void *) block->b_data;
++			u32 nexthash;
++
++			if ((errorcode = asfs_getnode(sb, objectnode, &node_bh, &onptr)) == 0) {
++				u16 hashchain;
++
++				asfs_debug("dehashobject: Read HashTable block of parent object of object to be delinked\n");
++
++				hashchain = HASHCHAIN(asfs_hash(name, ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE));
++				nexthash = be32_to_cpu(ht->hashentry[hashchain]);
++
++				if (nexthash == objectnode) {
++					/* The hashtable directly points to the fsObject to be delinked.  We simply
++					   modify the Hashtable to point to the new nexthash entry. */
++
++					asfs_debug("dehashobject: The hashtable points directly to the to be delinked object\n");
++
++					ht->hashentry[hashchain] = onptr->next;
++					asfs_bstore(sb, block);
++				} else {
++					struct fsObjectNode *onsearch = 0;
++
++					on = *onptr;
++
++					asfs_debug("dehashobject: Walking through hashchain\n");
++
++					while (nexthash != 0 && nexthash != objectnode) {
++						asfs_brelse(node_bh);
++						if ((errorcode = asfs_getnode(sb, nexthash, &node_bh, &onsearch)) != 0)
++							break;
++						nexthash = be32_to_cpu(onsearch->next);
++					}
++
++					if (errorcode == 0) {
++						if (nexthash != 0) {
++							/* Previous fsObjectNode found in hash chain.  Modify the fsObjectNode to 'skip' the
++							   ObjectNode which is being delinked from the hash chain. */
++
++							onsearch->next = on.next;
++							asfs_bstore(sb, node_bh);
++						} else {
++							printk("ASFS: Hashchain of object %d is corrupt or incorrectly linked.", objectnode);
++
++							/*** This is strange.  We have been looking for the fsObjectNode which is located before the
++							     passed in fsObjectNode in the hash-chain.  However, we never found the
++							     fsObjectNode reffered to in the hash-chain!  Has to be somekind
++							     of internal error... */
++
++							errorcode = -ENOENT;
++						}
++					}
++				}
++				asfs_brelse(node_bh);
++			}
++			asfs_brelse(block);
++		}
++	}
++	return errorcode;
++}
++
++
++	/* This function removes an object from any directory.  It takes care
++	   of delinking the object from the hashchain and also frees the
++	   objectnode number. */
++
++static int removeobject(struct super_block *sb, struct buffer_head *bh, struct fsObject *o)
++{
++	struct fsObjectContainer *oc = (void *) bh->b_data;
++	int errorcode;
++
++	asfs_debug("removeobject\n");
++
++	if ((errorcode = dehashobjectquick(sb, be32_to_cpu(o->objectnode), o->name, be32_to_cpu(oc->parent))) == 0) {
++		u32 objectnode = be32_to_cpu(o->objectnode);
++
++		if ((errorcode = simpleremoveobject(sb, bh, o)) == 0)
++			errorcode = asfs_deletenode(sb, objectnode);
++	}
++
++	return (errorcode);
++}
++
++	/* This function deletes the specified object. */
++int asfs_deleteobject(struct super_block *sb, struct buffer_head *bh, struct fsObject *o)
++{
++	int errorcode = 0;
++
++	asfs_debug("deleteobject: Entry -- deleting object %d (%s)\n", be32_to_cpu(o->objectnode), o->name);
++
++	if ((o->bits & OTYPE_DIR) == 0 || o->object.dir.firstdirblock == 0) {
++		u8 bits = o->bits;
++		u32 hashblckno = be32_to_cpu(o->object.dir.hashtable);
++		u32 extentbnode = be32_to_cpu(o->object.file.data);
++
++		if ((errorcode = removeobject(sb, bh, o)) == 0) {
++			if ((bits & OTYPE_LINK) != 0) {
++				asfs_debug("deleteobject: Object is soft link!\n");
++				errorcode = asfs_freeadminspace(sb, extentbnode);
++			} else if ((bits & OTYPE_DIR) != 0) {
++				asfs_debug("deleteobject: Object is a directory!\n");
++				errorcode = asfs_freeadminspace(sb, hashblckno);
++			} else {
++				asfs_debug("deleteobject: Object is a file\n");
++				if (extentbnode != 0)
++					errorcode = asfs_deleteextents(sb, extentbnode);
++			}
++		}
++	}
++
++	return (errorcode);
++}
++
++	/* This function takes a HashBlock pointer, an ObjectNode and an ObjectName.
++	   If there is a hashblock, then this function will correctly link the object
++	   into the hashchain.  If there isn't a hashblock (=0) then this function
++	   does nothing.  */
++
++static int hashobject(struct super_block *sb, u32 hashblock, struct fsObjectNode *on, u32 nodeno, u8 *objectname)
++{
++	struct buffer_head *hash_bh;
++
++	asfs_debug("hashobject, using hashblock %d\n", hashblock);
++	if (hashblock == 0)
++		return 0;
++
++	if ((hash_bh = asfs_breadcheck(sb, hashblock, ASFS_HASHTABLE_ID))) {
++		struct fsHashTable *ht = (void *) hash_bh->b_data;
++		u32 nexthash;
++		u16 hashvalue, hashchain;
++
++		hashvalue = asfs_hash(objectname, ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE);
++		hashchain = HASHCHAIN(hashvalue);
++		nexthash = be32_to_cpu(ht->hashentry[hashchain]);
++
++		ht->hashentry[hashchain] = cpu_to_be32(nodeno);
++
++		asfs_bstore(sb, hash_bh);
++		asfs_brelse(hash_bh);
++
++		on->next = cpu_to_be32(nexthash);
++		on->hash16 = cpu_to_be16(hashvalue);
++	} else
++		return -EIO;
++
++	return 0;
++}
++
++	/* This function returns a pointer to the first unused byte in
++	   an ObjectContainer. */
++
++static u8 *emptyspaceinobjectcontainer(struct super_block *sb, struct fsObjectContainer *oc)
++{
++	struct fsObject *o = oc->object;
++	u8 *endadr;
++
++	endadr = (u8 *) oc + sb->s_blocksize - sizeof(struct fsObject) - 2;
++
++	while ((u8 *) o < endadr && o->name[0] != 0)
++		o = asfs_nextobject(o);
++
++	return (u8 *) o;
++}
++
++	/* This function will look in the directory indicated by io_o
++	   for an ObjectContainer block which contains bytesneeded free
++	   bytes.  If none is found then this function simply creates a
++	   new ObjectContainer and adds that to the indicated directory. */
++
++static int findobjectspace(struct super_block *sb, struct buffer_head **io_bh, struct fsObject **io_o, u32 bytesneeded)
++{
++	struct buffer_head *bhparent = *io_bh;
++	struct fsObject *oparent = *io_o;
++	struct buffer_head *bh;
++	u32 nextblock = be32_to_cpu(oparent->object.dir.firstdirblock);
++	int errorcode = 0;
++
++	asfs_debug("findobjectspace: Looking for %u bytes in directory with ObjectNode number %d (in block %d)\n", bytesneeded, be32_to_cpu((*io_o)->objectnode),
++		   be32_to_cpu(((struct fsBlockHeader *) (*io_bh)->b_data)->ownblock));
++
++	while (nextblock != 0 && (bh = asfs_breadcheck(sb, nextblock, ASFS_OBJECTCONTAINER_ID))) {
++		struct fsObjectContainer *oc = (void *) bh->b_data;
++		u8 *emptyspace;
++
++		/* We need to find out how much free space this ObjectContainer has */
++
++		emptyspace = emptyspaceinobjectcontainer(sb, oc);
++
++		if ((u8 *) oc + sb->s_blocksize - emptyspace >= bytesneeded) {
++			/* We found enough space in one of the ObjectContainer blocks!!
++			   We return a struct fsObject *. */
++			*io_bh = bh;
++			*io_o = (struct fsObject *) emptyspace;
++			break;
++		}
++		nextblock = be32_to_cpu(oc->next);
++		asfs_brelse(bh);
++	}
++
++	if (nextblock == 0) {
++		u32 newcontblock;
++		/* If we get here, we traversed the *entire* directory (ough!) and found no empty
++		   space large enough for our entry.  We allocate new space and add it to this
++		   directory. */
++
++		if ((errorcode = asfs_allocadminspace(sb, &newcontblock)) == 0 && (bh = asfs_getzeroblk(sb, newcontblock))) {
++			struct fsObjectContainer *oc = (void *) bh->b_data;
++			struct buffer_head *bhnext;
++
++			asfs_debug("findobjectspace: No room was found, allocated new block at %u\n", newcontblock);
++
++			/* Allocated new block.  We will now link it to the START of the directory chain
++			   so the new free space can be found quickly when more entries need to be added. */
++
++			oc->bheader.id = cpu_to_be32(ASFS_OBJECTCONTAINER_ID);
++			oc->bheader.ownblock = cpu_to_be32(newcontblock);
++			oc->parent = oparent->objectnode;
++			oc->next = oparent->object.dir.firstdirblock;
++			oc->previous = 0;
++
++			oparent->object.dir.firstdirblock = cpu_to_be32(newcontblock);
++
++			asfs_bstore(sb, bhparent);
++
++			if (oc->next != 0 && (bhnext = asfs_breadcheck(sb, be32_to_cpu(oc->next), ASFS_OBJECTCONTAINER_ID))) {
++				struct fsObjectContainer *ocnext = (void *) bhnext->b_data;
++				ocnext->previous = cpu_to_be32(newcontblock);
++				asfs_bstore(sb, bhnext);
++				asfs_brelse(bhnext);
++			}
++
++			*io_bh = bh;
++			*io_o = oc->object;
++		}
++	}
++
++	asfs_debug("findobjectspace: new object will be in container block %u\n", be32_to_cpu(((struct fsBlockHeader *) (*io_bh)->b_data)->ownblock));
++
++	return (errorcode);
++}
++
++/* io_bh & io_o refer to the direct parent of the new object.  Objectname is the
++	name of the new object (name only). Does not realese io_bh !!! */
++
++int asfs_createobject(struct super_block *sb, struct buffer_head **io_bh, struct fsObject **io_o, struct fsObject *src_o, u8 *objectname, int force)
++{
++	int errorcode;
++	u32 object_size;
++	u32 hashblock = be32_to_cpu((*io_o)->object.dir.hashtable);
++
++	asfs_debug("createobject: Creating object '%s' in dir '%s'.\n", objectname, (*io_o)->name);
++
++	if (!force && ASFS_SB(sb)->freeblocks < ASFS_ALWAYSFREE)
++		return -ENOSPC;
++
++	if (!force && be32_to_cpu((*io_o)->objectnode) == ASFS_RECYCLEDNODE)
++		return -EINVAL;
++
++	object_size = sizeof(struct fsObject) + strlen(objectname) + 2;
++
++	if ((errorcode = findobjectspace(sb, io_bh, io_o, object_size)) == 0) {
++		struct fsObject *o2 = *io_o;
++		u8 *name = o2->name;
++		u8 *objname = objectname;
++		struct buffer_head *node_bh;
++		struct fsObjectNode *on;
++		u32 nodeno;
++
++		**io_o = *src_o;	/* Copying whole object data... */
++
++		while (*objname != 0)	/* Copying name */
++			*name++ = *objname++;
++
++		*name++ = 0;
++		*name = 0;	/* zero byte for comment */
++
++		if (o2->objectnode != 0)	/* ObjectNode reuse or creation */
++			errorcode = asfs_getnode(sb, o2->objectnode, &node_bh, &on);
++		else {
++			if ((errorcode = asfs_createnode(sb, &node_bh, (struct fsNode **) &on, &nodeno)) == 0) {
++				on->hash16 = cpu_to_be16(asfs_hash(o2->name, ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE));
++				o2->objectnode = cpu_to_be32(nodeno);
++			}
++			asfs_debug("createnode returned with errorcode: %d\n", errorcode);
++		}
++
++		if (errorcode == 0) {	/* in io_bh there is a container with created object */
++			on->node.data = ((struct fsBlockHeader *) (*io_bh)->b_data)->ownblock;
++			if ((errorcode = hashobject(sb, hashblock, on, be32_to_cpu(o2->objectnode), objectname)) == 0) {
++				asfs_bstore(sb, node_bh);
++				asfs_brelse(node_bh);
++			} else
++				errorcode = -EIO;
++		}
++
++		if (errorcode == 0) {	/* HashBlock reuse or creation:*/
++
++			if ((o2->bits & OTYPE_DIR) != 0 && o2->object.dir.hashtable == 0) {
++				struct buffer_head *hashbh;
++				u32 hashblock;
++
++				asfs_debug("creating Hashblock\n");
++
++				if ((errorcode = asfs_allocadminspace(sb, &hashblock)) == 0 && (hashbh = asfs_getzeroblk(sb, hashblock))) {	    
++					struct fsHashTable *ht = (void *) hashbh->b_data;
++
++					o2->object.dir.hashtable = cpu_to_be32(hashblock);
++
++					ht->bheader.id = cpu_to_be32(ASFS_HASHTABLE_ID);
++					ht->bheader.ownblock = cpu_to_be32(hashblock);
++					ht->parent = o2->objectnode;
++
++					asfs_bstore(sb, hashbh);
++					asfs_brelse(hashbh);
++				}
++			}
++		}
++
++		if (errorcode == 0) {	/* SoftLink creation: */
++			if ((o2->bits & (OTYPE_LINK | OTYPE_HARDLINK)) == OTYPE_LINK && o2->object.file.data == 0) {
++				struct buffer_head *bh2;
++				u32 slinkblock;
++
++				if ((errorcode = asfs_allocadminspace(sb, &slinkblock)) == 0 && (bh2 = asfs_getzeroblk(sb, slinkblock))) {
++					struct fsSoftLink *sl = (void *) bh2->b_data;
++					o2->object.file.data = cpu_to_be32(slinkblock);
++					sl->bheader.id = cpu_to_be32(ASFS_SOFTLINK_ID);
++					sl->bheader.ownblock = cpu_to_be32(slinkblock);
++					sl->parent = o2->objectnode;
++					sl->next = 0;
++					sl->previous = 0;
++					asfs_bstore(sb, bh2);
++					asfs_brelse(bh2);
++				}
++			}
++		}
++	}
++	asfs_debug("createobject: done.\n");
++
++	return (errorcode);
++}
++
++	/* This function extends the file object 'o' with a number  of blocks 
++		(hopefully, if any blocks has been found!). Only new Extents will 
++      be created -- the size of the file will not be altered, and changing 
++		it is left up to the caller.  If the file did not have any blocks 
++		yet, then the o->object.file.data will be set to the first (new) 
++		ExtentBNode. It returns the number of added blocks through 
++		addedblocks pointer */
++
++int asfs_addblockstofile(struct super_block *sb, struct buffer_head *objbh, struct fsObject *o, u32 blocks, u32 * newspace, u32 * addedblocks)
++{
++	u32 lastextentbnode;
++	int errorcode = 0;
++	struct fsExtentBNode *ebnp;
++	struct buffer_head *block = NULL;
++
++
++	asfs_debug("extendblocksinfile: Trying to increasing number of blocks by %d.\n", blocks);
++
++	lastextentbnode = be32_to_cpu(o->object.file.data);
++
++	if (lastextentbnode != 0) {
++		while (lastextentbnode != 0 && errorcode == 0) {
++			if (block != NULL)
++				asfs_brelse(block);
++			errorcode = asfs_getextent(sb, lastextentbnode, &block, &ebnp);
++			lastextentbnode = be32_to_cpu(ebnp->next);
++		}
++		lastextentbnode = be32_to_cpu(ebnp->key);
++	}
++
++	if (errorcode == 0) {
++		u32 searchstart;
++
++		u32 found_block;
++		u32 found_blocks;
++
++		*addedblocks = 0;
++		*newspace = 0;
++
++		if (lastextentbnode != 0)
++			searchstart = be32_to_cpu(ebnp->key) + be16_to_cpu(ebnp->blocks);
++		else
++			searchstart = 0; //ASFS_SB(sb)->block_rovingblockptr;
++
++		if ((errorcode = asfs_findspace(sb, blocks, searchstart, searchstart, &found_block, &found_blocks)) != 0) {
++			asfs_brelse(block);
++			asfs_debug("extendblocksinfile: findspace returned %s\n", errorcode == -ENOSPC ? "ENOSPC" : "error");
++			return errorcode;
++		}
++
++		blocks = found_blocks;
++		errorcode = asfs_markspace(sb, found_block, found_blocks);
++		*addedblocks = found_blocks;
++		*newspace = found_block;
++
++		asfs_debug("extendblocksinfile: block = %u, lastextentbnode = %u, extentblocks = %d\n", found_block, lastextentbnode, blocks);
++
++		if ((errorcode = asfs_addblocks(sb, blocks, found_block, be32_to_cpu(o->objectnode), &lastextentbnode)) != 0) {
++			asfs_debug("extendblocksinfile: addblocks returned errorcode %d\n", errorcode);
++			return errorcode;
++		}
++
++		if (o->object.file.data == 0)
++			o->object.file.data = cpu_to_be32(lastextentbnode);
++	}
++
++	if (block)
++		asfs_brelse(block);
++	asfs_bstore(sb, objbh);
++
++	asfs_debug("addblockstofile: done. added %d blocks\n", *addedblocks);
++
++	return errorcode;
++}
++
++	/* The Object indicated by bh1 & o1, gets renamed to newname and placed
++	   in the directory indicated by bhparent & oparent. */
++
++int asfs_renameobject(struct super_block *sb, struct buffer_head *bh1, struct fsObject *o1, struct buffer_head *bhparent, struct fsObject *oparent, u8 * newname)
++{
++	struct fsObject object;
++	u32 oldparentnode = be32_to_cpu(((struct fsObjectContainer *) bh1->b_data)->parent);
++	u8 oldname[107];
++	int errorcode;
++
++	asfs_debug("renameobject: Renaming '%s' to '%s' in dir '%s'\n", o1->name, newname, oparent->name);
++
++	object = *o1;
++	strcpy(oldname, o1->name);
++
++	if ((errorcode = dehashobjectquick(sb, be32_to_cpu(o1->objectnode), o1->name, oldparentnode)) == 0) {
++		u32 parentobjectnode = be32_to_cpu(oparent->objectnode);
++
++		if ((errorcode = simpleremoveobject(sb, bh1, o1)) == 0) {
++			struct buffer_head *bh2 = bhparent;
++			struct fsObject *o2;
++
++			/* oparent might changed after simpleremoveobject */
++			oparent = o2 = find_obj_by_node(sb, (struct fsObjectContainer *) bhparent->b_data, parentobjectnode);
++
++			/* In goes the Parent bh & o, out comes the New object's bh & o :-) */
++			if ((errorcode = asfs_createobject(sb, &bh2, &o2, &object, newname, TRUE)) == 0) {
++				asfs_bstore(sb, bh2);
++				if (be32_to_cpu(oparent->objectnode) == ASFS_RECYCLEDNODE) {
++					asfs_debug("renameobject: Updating recycled dir info\n");
++					if ((errorcode = setrecycledinfodiff(sb, 1, (be32_to_cpu(o2->object.file.size) + sb->s_blocksize - 1) >> sb->s_blocksize_bits)) != 0) {
++						brelse(bh2);
++						return errorcode;
++					}
++				}
++				brelse(bh2);
++				asfs_debug("renameobject: Succesfully created & stored new object.\n");
++			} else { /* recreate object in old place, maybe this will not fail, but who knows... */
++				asfs_debug("renameobject: Creating new object failed. Trying to recreate it in source directory.\n");
++				if (asfs_readobject(sb, oldparentnode, &bh1, &o1) == 0) {
++					struct buffer_head *bh2 = bh1;
++					if (asfs_createobject(sb, &bh2, &o1, &object, oldname, TRUE) == 0) {
++						asfs_bstore(sb, bh2);
++						if (oldparentnode == ASFS_RECYCLEDNODE) {
++							asfs_debug("renameobject: Updating recycled dir info\n");
++							setrecycledinfodiff(sb, 1, (be32_to_cpu(o1->object.file.size) + sb->s_blocksize - 1) >> sb->s_blocksize_bits);
++						}
++						brelse(bh2);
++					}
++					brelse(bh1);
++				}
++			}
++		}
++	}
++	return errorcode;
++}
++
++		/* Truncates the specified file to /newsize/ bytes */
++
++int asfs_truncateblocksinfile(struct super_block *sb, struct buffer_head *bh, struct fsObject *o, u32 newsize)
++{
++	struct buffer_head *ebh;
++	struct fsExtentBNode *ebn;
++	int errorcode;
++	u32 pos = 0;
++	u32 newblocks = (newsize + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
++	u32 filedata = be32_to_cpu(o->object.file.data);
++	u32 eprev, ekey;
++	u16 eblocks;
++
++	asfs_debug("trucateblocksinfile: newsize %u\n", newsize);
++
++	if (filedata == 0)
++		return 0;
++
++	for (;;) {
++		if ((errorcode = asfs_getextent(sb, filedata, &ebh, &ebn)) != 0)
++			return errorcode;
++		if (pos + be16_to_cpu(ebn->blocks) >= newblocks)
++			break;
++		pos += be16_to_cpu(ebn->blocks);
++		if ((filedata = be32_to_cpu(ebn->next)) == 0)
++			break;
++		asfs_brelse(ebh);
++	};
++
++	eblocks = newblocks - pos;
++	ekey = be32_to_cpu(ebn->key);
++	eprev = be32_to_cpu(ebn->prev);
++
++	if (be16_to_cpu(ebn->blocks) < eblocks) {
++		printk("ASFS: Extent chain is too short or damaged!\n");
++		asfs_brelse(ebh);
++		return -ENOENT;
++	}
++	if (be16_to_cpu(ebn->blocks) - eblocks > 0 && (errorcode = asfs_freespace(sb, be32_to_cpu(ebn->key) + eblocks, be16_to_cpu(ebn->blocks) - eblocks)) != 0) {
++		asfs_brelse(ebh);
++		return errorcode;
++	}
++	if (be32_to_cpu(ebn->next) > 0 && (errorcode = asfs_deleteextents(sb, be32_to_cpu(ebn->next))) != 0) {
++		asfs_brelse(ebh);
++		return errorcode;
++	}
++	ebn->blocks = cpu_to_be16(eblocks);
++	ebn->next = 0;
++	asfs_bstore(sb, ebh);
++
++	if (eblocks == 0) {
++		if (eprev & MSB_MASK) {
++			o->object.file.data = 0;
++			asfs_bstore(sb, bh);
++		} else {
++			struct buffer_head *ebhp;
++			struct fsExtentBNode *ebnp;
++
++			if ((errorcode = asfs_getextent(sb, eprev & !MSB_MASK, &ebhp, &ebnp)) != 0) {
++				asfs_brelse(ebh);
++				return errorcode;
++			}
++
++			ebnp->next = 0;
++			asfs_bstore(sb, ebhp);
++			asfs_brelse(ebhp);
++		}
++		if ((errorcode = asfs_deletebnode(sb, ebh, ekey)) != 0) {
++			asfs_brelse(ebh);
++			return errorcode;
++		}
++	}
++	asfs_brelse(ebh);
++
++	return 0;
++}
++#endif
+diff -aurN a/fs/asfs/super.c b/fs/asfs/super.c
+--- a/fs/asfs/super.c	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/super.c	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,488 @@
++/*
++ *
++ * Amiga Smart File System, Linux implementation
++ *
++ * version: 1.0beta9 for 2.6.xx kernel
++ *  
++ * Copyright (C) 2003,2004,2005  Marek 'March' Szyprowski <marek at amiga.pl>
++ *
++ * NLS support by Pavel Fedin (C) 2005
++ *
++ *
++ * Thanks to Marcin Kurek (Morgoth/Dreamolers-CAPS) for help and parts 
++ * of original amiga version of SmartFilesystem source code. 
++ *
++ * SmartFilesystem is copyrighted (C) 2003 by: John Hendrikx, 
++ * Ralph Schmidt, Emmanuel Lesueur, David Gerber and Marcin Kurek
++ * 
++ *
++ * ASFS is based on the Amiga FFS filesystem for Linux
++ * Copyright (C) 1993  Ray Burr
++ * Copyright (C) 1996  Hans-Joachim Widmaier
++ *
++ * Earlier versions were based on the Linux implementation of 
++ * the ROMFS file system
++ * Copyright (C) 1997-1999  Janos Farkas <chexum at shadow.banki.hu>
++ *
++ * ASFS used some parts of the smbfs filesystem:
++ * Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
++ * Copyright (C) 1997 by Volker Lendecke
++ *
++ * and parts of the Minix filesystem additionally
++ * Copyright (C) 1991, 1992  Linus Torvalds
++ * Copyright (C) 1996  Gertjan van Wingerde 
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ *
++ */
++
++/* todo:
++ * - remove bugs
++ * - add missing features (maybe safe-delete, other...)
++ * - create other fs tools like mkfs.asfs and fsck.asfs, some data-recovery tools
++ */
++
++#define ASFS_VERSION "1.0beta9 (17.03.2005)"
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/init.h>
++#include <linux/smp_lock.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include <linux/parser.h>
++#include <linux/nls.h>
++#include "asfs_fs.h"
++
++#include <asm/byteorder.h>
++#include <asm/uaccess.h>
++
++static char asfs_default_codepage[] = CONFIG_ASFS_DEFAULT_CODEPAGE;
++static char asfs_default_iocharset[] = CONFIG_NLS_DEFAULT;
++
++u32 asfs_calcchecksum(void *block, u32 blocksize)
++{
++	u32 *data = block, checksum = 1;
++	while (blocksize > 0) {
++		checksum += be32_to_cpu(*data++);
++		blocksize -= 4;
++	}
++	checksum -= be32_to_cpu(((struct fsBlockHeader *)block)->checksum);
++	return -checksum;
++}
++
++static struct super_operations asfs_ops = {
++	.alloc_inode	= asfs_alloc_inode,
++	.destroy_inode	= asfs_destroy_inode,
++	.put_super		= asfs_put_super,
++	.statfs			= asfs_statfs,
++#ifdef CONFIG_ASFS_RW
++	.remount_fs		= asfs_remount,
++#endif
++};
++
++extern struct dentry_operations asfs_dentry_operations;
++
++enum {
++	Opt_mode, Opt_setgid, Opt_setuid, Opt_prefix, Opt_volume, 
++	Opt_lcvol, Opt_iocharset, Opt_codepage, Opt_ignore, Opt_err
++};
++
++static match_table_t tokens = {
++	{Opt_mode, "mode=%o"},
++	{Opt_setgid, "setgid=%u"},
++	{Opt_setuid, "setuid=%u"},
++	{Opt_prefix, "prefix=%s"},
++	{Opt_volume, "volume=%s"},
++	{Opt_lcvol, "lowercasevol"},
++	{Opt_iocharset, "iocharset=%s"},
++	{Opt_codepage, "codepage=%s"},
++	{Opt_ignore, "grpquota"},
++	{Opt_ignore, "noquota"},
++	{Opt_ignore, "quota"},
++	{Opt_ignore, "usrquota"},
++	{Opt_err, NULL},
++};
++
++static int asfs_parse_options(char *options, struct super_block *sb)
++{
++	char *p;
++	substring_t args[MAX_OPT_ARGS];
++
++	if (!options)
++		return 1;
++	while ((p = strsep(&options, ",")) != NULL) {
++		int token, option;
++		if (!*p)
++			continue;
++		token = match_token(p, tokens, args);
++
++		switch (token) {
++		case Opt_mode:
++			if (match_octal(&args[0], &option))
++				goto no_arg;
++			ASFS_SB(sb)->mode = option & 0777;
++			break;
++		case Opt_setgid:
++			if (match_int(&args[0], &option))
++				goto no_arg;
++			ASFS_SB(sb)->gid = option;
++			break;
++		case Opt_setuid:
++			if (match_int(&args[0], &option))
++				goto no_arg;
++			ASFS_SB(sb)->uid = option;
++			break;
++		case Opt_prefix:
++			if (ASFS_SB(sb)->prefix) {
++				kfree(ASFS_SB(sb)->prefix);
++				ASFS_SB(sb)->prefix = NULL;
++			}
++			ASFS_SB(sb)->prefix = match_strdup(&args[0]);
++			if (! ASFS_SB(sb)->prefix)
++				return 0;
++			break;
++		case Opt_volume:
++			if (ASFS_SB(sb)->root_volume) {
++				kfree(ASFS_SB(sb)->root_volume);
++				ASFS_SB(sb)->root_volume = NULL;
++			}
++			ASFS_SB(sb)->root_volume = match_strdup(&args[0]);
++			if (! ASFS_SB(sb)->root_volume)
++				return 0;
++			break;
++		case Opt_lcvol:
++			ASFS_SB(sb)->flags |= ASFS_VOL_LOWERCASE;
++			break;
++		case Opt_iocharset:
++			if (ASFS_SB(sb)->iocharset != asfs_default_iocharset)
++				kfree(ASFS_SB(sb)->iocharset);
++			ASFS_SB(sb)->iocharset = match_strdup(&args[0]);
++			if (!ASFS_SB(sb)->iocharset)
++				return 0;
++			break;
++		case Opt_codepage:
++			if (ASFS_SB(sb)->codepage != asfs_default_codepage)
++				kfree(ASFS_SB(sb)->codepage);
++			ASFS_SB(sb)->codepage = match_strdup(&args[0]);
++			if (!ASFS_SB(sb)->codepage)
++				return 0;
++		case Opt_ignore:
++		 	/* Silently ignore the quota options */
++			break;
++		default:
++no_arg:
++			printk("ASFS: Unrecognized mount option \"%s\" "
++					"or missing value\n", p);
++			return 0;
++		}
++	}
++	return 1;
++}
++
++static int asfs_fill_super(struct super_block *sb, void *data, int silent)
++{
++	struct asfs_sb_info *sbi;
++	struct buffer_head *bh;
++	struct fsRootBlock *rootblock;
++	struct inode *rootinode;
++
++	sbi = kmalloc(sizeof(struct asfs_sb_info), GFP_KERNEL);
++	if (!sbi)
++		return -ENOMEM;
++	sb->s_fs_info = sbi;
++
++	/* Fill in defaults */
++	ASFS_SB(sb)->uid = ASFS_DEFAULT_UID;
++	ASFS_SB(sb)->gid = ASFS_DEFAULT_GID;
++	ASFS_SB(sb)->mode = ASFS_DEFAULT_MODE;
++	ASFS_SB(sb)->prefix = NULL;
++	ASFS_SB(sb)->root_volume = NULL;
++	ASFS_SB(sb)->flags = 0;
++	ASFS_SB(sb)->iocharset = asfs_default_iocharset;
++	ASFS_SB(sb)->codepage = asfs_default_codepage;
++
++	if (!asfs_parse_options(data, sb)) {
++		printk(KERN_ERR "ASFS: Error parsing options\n");
++		return -EINVAL;
++	}
++
++	if (!sb_set_blocksize(sb, 512))
++		return -EINVAL;
++	sb->s_maxbytes = ASFS_MAXFILESIZE;
++
++	bh = sb_bread(sb, 0);
++	if (!bh) {
++		printk(KERN_ERR "ASFS: unable to read superblock\n");
++		return -EINVAL;
++	}
++
++	rootblock = (struct fsRootBlock *)bh->b_data;
++
++	if (be32_to_cpu(rootblock->bheader.id) == ASFS_ROOTID && 
++		be16_to_cpu(rootblock->version) == ASFS_STRUCTURE_VERISON) {
++
++		sb->s_blocksize = be32_to_cpu(rootblock->blocksize);
++		ASFS_SB(sb)->totalblocks = be32_to_cpu(rootblock->totalblocks);
++		ASFS_SB(sb)->rootobjectcontainer = be32_to_cpu(rootblock->rootobjectcontainer);
++		ASFS_SB(sb)->extentbnoderoot = be32_to_cpu(rootblock->extentbnoderoot);
++		ASFS_SB(sb)->objectnoderoot = be32_to_cpu(rootblock->objectnoderoot);
++		ASFS_SB(sb)->flags |= 0xff & rootblock->bits;
++		ASFS_SB(sb)->adminspacecontainer = be32_to_cpu(rootblock->adminspacecontainer);
++		ASFS_SB(sb)->bitmapbase = be32_to_cpu(rootblock->bitmapbase);
++		ASFS_SB(sb)->blocks_inbitmap = (sb->s_blocksize - sizeof(struct fsBitmap))<<3;  /* must be a multiple of 32 !! */
++		ASFS_SB(sb)->blocks_bitmap = (ASFS_SB(sb)->totalblocks + ASFS_SB(sb)->blocks_inbitmap - 1) / ASFS_SB(sb)->blocks_inbitmap;
++		ASFS_SB(sb)->block_rovingblockptr = 0;
++		asfs_brelse(bh);
++
++		if (!sb_set_blocksize(sb, sb->s_blocksize)) {
++			printk(KERN_ERR "ASFS: Found Amiga SFS RootBlock on dev %s, but blocksize %ld is not supported!\n", \
++			       sb->s_id, sb->s_blocksize);
++			return -EINVAL;
++		}
++
++		bh = sb_bread(sb, 0);
++		if (!bh) {
++			printk(KERN_ERR "ASFS: unable to read superblock\n");
++			goto out;
++		}
++		rootblock = (struct fsRootBlock *)bh->b_data;
++
++		if (asfs_check_block((void *)rootblock, sb->s_blocksize, 0, ASFS_ROOTID)) {
++#ifdef CONFIG_ASFS_RW
++			struct buffer_head *tmpbh;
++			if ((tmpbh = asfs_breadcheck(sb, ASFS_SB(sb)->rootobjectcontainer, ASFS_OBJECTCONTAINER_ID))) {
++				struct fsRootInfo *ri = (struct fsRootInfo *)((u8 *)tmpbh->b_data + sb->s_blocksize - sizeof(struct fsRootInfo));
++				ASFS_SB(sb)->freeblocks = be32_to_cpu(ri->freeblocks);
++				asfs_brelse(tmpbh);
++			} else
++				ASFS_SB(sb)->freeblocks = 0;
++
++			if ((tmpbh = asfs_breadcheck(sb, ASFS_SB(sb)->rootobjectcontainer+2, ASFS_TRANSACTIONFAILURE_ID))) {
++				printk(KERN_NOTICE "VFS: Found Amiga SFS RootBlock on dev %s, but it has unfinished transaction. Mounting read-only.\n", sb->s_id);
++				ASFS_SB(sb)->flags |= ASFS_READONLY;
++				asfs_brelse(tmpbh);
++			}
++
++			if ((tmpbh = asfs_breadcheck(sb, ASFS_SB(sb)->totalblocks-1, ASFS_ROOTID)) == NULL) {
++				printk(KERN_NOTICE "VFS: Found Amiga SFS RootBlock on dev %s, but there is no second RootBlock! Mounting read-only.\n", sb->s_id);
++				ASFS_SB(sb)->flags |= ASFS_READONLY;
++				asfs_brelse(tmpbh);
++			}
++			if (!(ASFS_SB(sb)->flags & ASFS_READONLY))
++				printk(KERN_NOTICE "VFS: Found Amiga SFS RootBlock on dev %s.\n", sb->s_id);
++#else
++			ASFS_SB(sb)->freeblocks = 0;
++			ASFS_SB(sb)->flags |= ASFS_READONLY;
++			printk(KERN_NOTICE "VFS: Found Amiga SFS RootBlock on dev %s.\n", sb->s_id);
++#endif
++		} else {
++			if (!silent)
++				printk(KERN_ERR "VFS: Found Amiga SFS RootBlock on dev %s, but it has checksum error!\n", \
++				       sb->s_id);
++			goto out;
++		}
++	} else {
++		if (!silent)
++			printk(KERN_ERR "VFS: Can't find a valid Amiga SFS filesystem on dev %s.\n", \
++			       sb->s_id);
++		goto out;
++	}
++
++	asfs_brelse(bh);
++
++	sb->s_magic = ASFS_MAGIC;
++	sb->s_flags |= MS_NODEV | MS_NOSUID;
++	if (ASFS_SB(sb)->flags & ASFS_READONLY) 
++		sb->s_flags |= MS_RDONLY;
++	sb->s_op = &asfs_ops;
++	asfs_debug("Case sensitive: %s\n", (ASFS_SB(sb)->flags & ASFS_ROOTBITS_CASESENSITIVE) ? "yes" : "no");
++
++	if (ASFS_SB(sb)->codepage[0] != '\0' && strcmp(ASFS_SB(sb)->codepage, "none") != 0) {
++		ASFS_SB(sb)->nls_disk = load_nls(ASFS_SB(sb)->codepage);
++		if (!ASFS_SB(sb)->nls_disk) {
++			printk(KERN_ERR "ASFS: codepage %s not found\n", ASFS_SB(sb)->codepage);
++			return -EINVAL;
++		}
++		ASFS_SB(sb)->nls_io = load_nls(ASFS_SB(sb)->iocharset);
++		if (!ASFS_SB(sb)->nls_io) {
++			printk(KERN_ERR "ASFS: IO charset %s not found\n", ASFS_SB(sb)->iocharset);
++			goto out2;
++		}
++	} else {
++		ASFS_SB(sb)->nls_io = NULL;
++		ASFS_SB(sb)->nls_disk = NULL;
++	}
++
++	if ((rootinode = asfs_get_root_inode(sb))) {
++		if ((sb->s_root = d_alloc_root(rootinode))) {
++			sb->s_root->d_op = &asfs_dentry_operations;
++			return 0;
++		}
++		iput(rootinode);
++	}
++	unload_nls(ASFS_SB(sb)->nls_io);
++out2:
++	unload_nls(ASFS_SB(sb)->nls_disk);
++	return -EINVAL;
++
++out:
++	asfs_brelse(bh);
++	return -EINVAL;
++
++}
++
++#ifdef CONFIG_ASFS_RW
++int asfs_remount(struct super_block *sb, int *flags, char *data)
++{
++	asfs_debug("ASFS: remount (flags=0x%x, opts=\"%s\")\n",*flags,data);
++
++	if (!asfs_parse_options(data,sb))
++		return -EINVAL;
++
++	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
++		return 0;
++
++	if (*flags & MS_RDONLY) {
++		sb->s_flags |= MS_RDONLY;
++	} else if (!(ASFS_SB(sb)->flags & ASFS_READONLY)) {
++		sb->s_flags &= ~MS_RDONLY;
++	} else {
++		printk("VFS: Can't remount Amiga SFS on dev %s read/write because of errors.", sb->s_id);
++		return -EINVAL;
++	}
++	return 0;
++}
++#endif
++
++void asfs_put_super(struct super_block *sb)
++{
++	struct asfs_sb_info *sbi = ASFS_SB(sb);
++
++	if (ASFS_SB(sb)->prefix)
++		kfree(ASFS_SB(sb)->prefix);
++	if (ASFS_SB(sb)->root_volume)
++		kfree(ASFS_SB(sb)->root_volume);
++	if (ASFS_SB(sb)->nls_disk)
++		unload_nls(ASFS_SB(sb)->nls_disk);
++	if (ASFS_SB(sb)->nls_io)
++		unload_nls(ASFS_SB(sb)->nls_io);
++	if (ASFS_SB(sb)->iocharset != asfs_default_iocharset)
++		kfree(ASFS_SB(sb)->iocharset);
++	if (ASFS_SB(sb)->codepage != asfs_default_codepage)
++		kfree(ASFS_SB(sb)->codepage);
++
++	kfree(sbi);
++	sb->s_fs_info = NULL;
++	return;
++}
++
++/* That's simple too. */
++int asfs_statfs(struct super_block *sb, struct kstatfs *buf)
++{
++	buf->f_type = ASFS_MAGIC;
++	buf->f_bsize = sb->s_blocksize;
++	buf->f_bfree = buf->f_bavail = ASFS_SB(sb)->freeblocks;
++	buf->f_blocks = ASFS_SB(sb)->totalblocks;
++	buf->f_namelen = ASFS_MAXFN;
++	return 0;
++}
++
++/* --- new in 2.6.x --- */
++static kmem_cache_t * asfs_inode_cachep;
++
++struct inode *asfs_alloc_inode(struct super_block *sb)
++{
++	struct asfs_inode_info *ei;
++	ei = (struct asfs_inode_info *)kmem_cache_alloc(asfs_inode_cachep, SLAB_KERNEL);
++	if (!ei)
++		return NULL;
++	return &ei->vfs_inode;
++}
++
++void asfs_destroy_inode(struct inode *inode)
++{
++	kmem_cache_free(asfs_inode_cachep, ASFS_I(inode));
++}
++
++static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
++{
++	struct asfs_inode_info *ei = (struct asfs_inode_info *) foo;
++
++	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
++	    SLAB_CTOR_CONSTRUCTOR) {
++		inode_init_once(&ei->vfs_inode);
++	}
++}
++
++static int init_inodecache(void)
++{
++	asfs_inode_cachep = kmem_cache_create("asfs_inode_cache",
++					     sizeof(struct asfs_inode_info),
++					     0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
++					     init_once, NULL);
++	if (asfs_inode_cachep == NULL)
++		return -ENOMEM;
++	return 0;
++}
++
++static void destroy_inodecache(void)
++{
++	if (kmem_cache_destroy(asfs_inode_cachep))
++		printk(KERN_INFO "asfs_inode_cache: not all structures were freed\n");
++}
++
++static struct super_block *asfs_get_sb(struct file_system_type *fs_type,
++	int flags, const char *dev_name, void *data)
++{
++	return get_sb_bdev(fs_type, flags, dev_name, data, asfs_fill_super);
++}
++
++static struct file_system_type asfs_fs_type = {
++	.owner		= THIS_MODULE,
++	.name		= "asfs",
++	.get_sb		= asfs_get_sb,
++	.kill_sb	= kill_block_super,
++	.fs_flags	= FS_REQUIRES_DEV,
++};
++
++static int __init init_asfs_fs(void)
++{
++	int err = init_inodecache();
++	if (err)
++		goto out1;
++	err = register_filesystem(&asfs_fs_type);
++	if (err)
++		goto out;
++	return 0;
++out:
++	destroy_inodecache();
++out1:
++	return err;
++}
++
++static void __exit exit_asfs_fs(void)
++{
++	unregister_filesystem(&asfs_fs_type);
++	destroy_inodecache();
++}
++
++/* Yes, works even as a module... :) */
++
++#ifdef CONFIG_ASFS_RW
++MODULE_DESCRIPTION("Amiga Smart File System (read/write) support for Linux kernel 2.6.x v" ASFS_VERSION);
++#else
++MODULE_DESCRIPTION("Amiga Smart File System (read-only) support for Linux kernel 2.6.x v" ASFS_VERSION);
++#endif
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Marek Szyprowski <marek at amiga.pl>");
++
++module_init(init_asfs_fs)
++module_exit(exit_asfs_fs)
+diff -aurN a/fs/asfs/symlink.c b/fs/asfs/symlink.c
+--- a/fs/asfs/symlink.c	1969-12-31 19:00:00.000000000 -0500
++++ b/fs/asfs/symlink.c	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,235 @@
++/*
++ *
++ * Amiga Smart File System, Linux implementation
++ * version: 1.0beta9
++ *  
++ * Copyright (C) 2003,2004,2005  Marek 'March' Szyprowski <marek at amiga.pl>
++ *
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ *
++ */
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/slab.h>
++#include <linux/fs.h>
++#include <linux/buffer_head.h>
++#include <linux/vfs.h>
++#include <linux/pagemap.h>
++#include <linux/nls.h>
++#include "asfs_fs.h"
++
++#include <asm/byteorder.h>
++#include <asm/uaccess.h>
++
++int asfs_symlink_readpage(struct file *file, struct page *page)
++{
++	struct buffer_head *bh;
++	struct fsSoftLink *slinkcont;
++	struct inode *inode = page->mapping->host;
++	struct super_block *sb = inode->i_sb;
++	struct nls_table *nls_io = ASFS_SB(sb)->nls_io;
++	struct nls_table *nls_disk = ASFS_SB(sb)->nls_disk;
++	char *link = kmap(page);
++	int i = 0, j = 0;
++	char c, lc = 0, *prefix, *lf, *p;
++	wchar_t uni;
++	int clen;
++
++	if (!(bh = asfs_breadcheck(sb, ASFS_I(inode)->firstblock, ASFS_SOFTLINK_ID))) {
++		SetPageError(page);
++		kunmap(page);
++		unlock_page(page);
++		return -EIO;
++	}
++	slinkcont = (struct fsSoftLink *) bh->b_data;
++
++	lf = slinkcont->string;
++	prefix = ASFS_SB(sb)->prefix ? ASFS_SB(sb)->prefix : "/";
++
++	if ((p = strchr(lf,':'))) {	/* Handle assign or volume name */
++		if (ASFS_SB(sb)->root_volume &&
++		    strncmp(lf, ASFS_SB(sb)->root_volume, strlen(ASFS_SB(sb)->root_volume)) == 0) {
++			/* global root volume name found */
++			link[i++] = '/';
++			lf = p+1;
++		} else {
++			/* adding volume prefix */ 
++			while (i < 1023 && (c = prefix[i]))
++				link[i++] = c;
++			while (i < 1023 && lf[j] != ':')
++			{
++				c = lf[j++];
++				if (ASFS_SB(sb)->flags & ASFS_VOL_LOWERCASE)
++					c = asfs_lowerchar(c);
++				if (nls_io)
++				{
++					clen = nls_disk->char2uni(&c, 1, &uni);
++					if (clen>0) {
++						clen = nls_io->uni2char(uni, &link[i], NLS_MAX_CHARSET_SIZE);
++						if (clen>0)
++							i += clen;
++					}
++					if (clen<0)
++						link[i++] = '?';
++				} else
++					link[i++] = c;
++			}
++			if (i < 1023)
++				link[i++] = '/';
++			j++;
++		}
++		lc = '/';
++	}
++
++	while (i < 1023 && (c = lf[j])) {
++		if (c == '/' && lc == '/' && i < 1020) {	/* parent dir */
++			link[i++] = '.';
++			link[i++] = '.';
++		}
++		lc = c;
++		if (nls_io)
++		{
++			clen = nls_disk->char2uni(&c, 1, &uni);
++			if (clen>0) {
++				clen = nls_io->uni2char(uni, &link[i], NLS_MAX_CHARSET_SIZE);
++				if (clen>0)
++					i += clen;
++			}
++			if (clen<0)
++				link[i++] = '?';
++		} else
++			link[i++] = c;
++		j++;
++	}
++	link[i] = '\0';
++	SetPageUptodate(page);
++	kunmap(page);
++	unlock_page(page);
++	asfs_brelse(bh);
++	return 0;
++}
++
++#ifdef CONFIG_ASFS_RW
++
++int asfs_write_symlink(struct inode *symfile, const char *symname)
++{
++	struct super_block *sb = symfile->i_sb;
++	struct buffer_head *bh;
++	struct fsSoftLink *slinkcont;
++	struct nls_table *nls_io = ASFS_SB(sb)->nls_io;
++	struct nls_table *nls_disk = ASFS_SB(sb)->nls_disk;
++	char *p, c, lc;
++	int i, maxlen, pflen;
++	wchar_t uni;
++	int clen, blen;
++
++	asfs_debug("asfs_write_symlink %s to node %d\n", symname, (int)symfile->i_ino);
++
++	if (!(bh = asfs_breadcheck(sb, ASFS_I(symfile)->firstblock, ASFS_SOFTLINK_ID))) {
++		unlock_super(sb);
++		return -EIO;
++	}
++	slinkcont = (struct fsSoftLink *) bh->b_data;
++
++	/* translating symlink target path */
++
++	maxlen = sb->s_blocksize - sizeof(struct fsSoftLink) - 2;
++	i  = 0;
++	p  = slinkcont->string;
++	lc = '/';
++
++	if (*symname == '/') {
++		while (*symname == '/')
++			symname++;
++		if (ASFS_SB(sb)->prefix &&
++		    strncmp(symname-1, ASFS_SB(sb)->prefix, (pflen = strlen(ASFS_SB(sb)->prefix))) == 0) {
++			/* found volume prefix, ommiting it */
++			symname += pflen;
++			blen = strlen(symname);
++			while (*symname != '/' && *symname != '\0') {
++				clen = nls_io->char2uni(symname, blen, &uni);
++				if (clen>0) {
++					symname += clen;
++					blen -= clen;
++					clen = nls_disk->uni2char(uni, p, NLS_MAX_CHARSET_SIZE);
++					if (clen>0)
++						p += clen;
++				}
++				else
++				{
++					symname++;
++					blen--;
++				}
++				if (clen<0)
++					*p++ = '?';
++				i++;
++			}
++			symname++;
++			*p++ = ':';
++		} else if (ASFS_SB(sb)->root_volume) {	/* adding root volume name */
++			while (ASFS_SB(sb)->root_volume[i])
++				*p++ = ASFS_SB(sb)->root_volume[i++];
++			*p++ = ':';
++		} else {	/* do nothing */
++			*p++ = '/';
++		}
++		i++;
++	}
++
++	blen = strlen(symname);
++	while (i < maxlen && (c = *symname)) {
++		if (c == '.' && lc == '/' && symname[1] == '.' && symname[2] == '/') {
++			*p++ = '/';
++			i++;
++			symname += 3;
++			blen -= 3;
++			lc = '/';
++		} else if (c == '.' && lc == '/' && symname[1] == '/') {
++			symname += 2;
++			blen -= 2;
++			lc = '/';
++		} else {
++			clen = nls_io->char2uni(symname, blen, &uni);
++			if (clen>0) {
++				symname += clen;
++				blen -= clen;
++				clen = nls_disk->uni2char(uni, p, NLS_MAX_CHARSET_SIZE);
++				if (clen>0)
++					lc = *p;
++					p += clen;
++			}
++			else
++			{
++				symname++;
++				blen--;
++			}
++			if (clen<0)
++			{
++				*p++ = '?';
++				lc = '?';
++			}
++			i++;
++		}
++		if (lc == '/')
++			while (*symname == '/')
++			{
++				symname++;
++				blen--;
++			}
++	}
++	*p = 0;
++
++	asfs_bstore(sb, bh);
++	asfs_brelse(bh);
++
++	unlock_super(sb);
++	
++	return 0;
++}
++
++#endif
+diff -aurN a/include/linux/amigasfs.h b/include/linux/amigasfs.h
+--- a/include/linux/amigasfs.h	1969-12-31 19:00:00.000000000 -0500
++++ b/include/linux/amigasfs.h	2005-06-15 22:05:09.000000000 -0400
+@@ -0,0 +1,276 @@
++#ifndef __LINUX_AMIGASFS_H
++#define __LINUX_AMIGASFS_H
++
++#include <linux/types.h>
++
++/* some helper macros... */
++#define ASFS_MAKE_ID(a,b,c,d) (((a)&0xff)<<24|((b)&0xff)<<16|((c)&0xff)<<8|((d)&0xff))
++
++/* Amiga SFS block IDs */
++#define ASFS_ROOTID                 ASFS_MAKE_ID('S','F','S','\0')
++#define ASFS_OBJECTCONTAINER_ID     ASFS_MAKE_ID('O','B','J','C')
++#define ASFS_BNODECONTAINER_ID      ASFS_MAKE_ID('B','N','D','C')
++#define ASFS_NODECONTAINER_ID       ASFS_MAKE_ID('N','D','C',' ')
++#define ASFS_HASHTABLE_ID           ASFS_MAKE_ID('H','T','A','B')
++#define ASFS_SOFTLINK_ID            ASFS_MAKE_ID('S','L','N','K')
++#define ASFS_ADMINSPACECONTAINER_ID ASFS_MAKE_ID('A','D','M','C')
++#define ASFS_BITMAP_ID              ASFS_MAKE_ID('B','T','M','P')
++#define ASFS_TRANSACTIONFAILURE_ID  ASFS_MAKE_ID('T','R','F','A')
++
++/* Amiga SFS defines and magic values */
++
++#define ASFS_MAGIC 0xa0ff
++#define ASFS_MAXFN (105u)
++#define ASFS_MAXFILESIZE 0x8FFFFFFE
++
++#define ASFS_STRUCTURE_VERISON (3)
++#define ASFS_BLCKFACCURACY	(5)
++
++#define ASFS_ROOTBITS_CASESENSITIVE (128)
++#define ASFS_READONLY (512)
++#define ASFS_VOL_LOWERCASE (1024)
++
++#define ASFS_ROOTNODE   (1)
++#define ASFS_RECYCLEDNODE (2)
++
++#define OTYPE_HIDDEN      (1)
++#define OTYPE_HARDLINK    (32)
++#define OTYPE_LINK        (64)
++#define OTYPE_DIR         (128)
++
++#define MSB_MASK (1ul << 31)
++
++#define NODE_STRUCT_SIZE (10)	/* (sizeof(struct fsObjectNode)) */
++#define NODECONT_BLOCK_COUNT ((sb->s_blocksize - sizeof(struct fsNodeContainer)) / sizeof(u32))
++
++#define ASFS_ALWAYSFREE (16)		/* keep this amount of blocks free */
++
++#define ASFS_BLOCKCHUNKS (16)		/* try to allocate this number of blocks in one request */
++
++#ifndef TRUE
++#define TRUE		1
++#endif
++#ifndef FALSE
++#define FALSE		0
++#endif
++
++/* amigados protection bits */
++
++#define FIBB_SCRIPT    6	/* program is a script (execute) file */
++#define FIBB_PURE      5	/* program is reentrant and rexecutable */
++#define FIBB_ARCHIVE   4	/* cleared whenever file is changed */
++#define FIBB_READ      3	/* ignored by old filesystem */
++#define FIBB_WRITE     2	/* ignored by old filesystem */
++#define FIBB_EXECUTE   1	/* ignored by system, used by Shell */
++#define FIBB_DELETE    0	/* prevent file from being deleted */
++
++#define FIBF_SCRIPT    (1<<FIBB_SCRIPT)
++#define FIBF_PURE      (1<<FIBB_PURE)
++#define FIBF_ARCHIVE   (1<<FIBB_ARCHIVE)
++#define FIBF_READ      (1<<FIBB_READ)
++#define FIBF_WRITE     (1<<FIBB_WRITE)
++#define FIBF_EXECUTE   (1<<FIBB_EXECUTE)
++#define FIBF_DELETE    (1<<FIBB_DELETE)
++
++/* name hashing macro */
++
++#define HASHCHAIN(x) (u16)(x % (u16)(((sb->s_blocksize) - sizeof(struct fsHashTable))>>2))
++
++/* Each block has its own header with checksum and id, its called fsBlockHeader */
++
++struct fsBlockHeader {
++	u32 id;			/* 4 character id string of this block */
++	u32 checksum;		/* The checksum */
++	u32 ownblock;		/* The blocknumber of the block this block is stored at */
++};
++
++/* On-disk "super block", called fsRootBlock */
++
++struct fsRootBlock {
++	struct fsBlockHeader bheader;
++
++	u16 version;		/* Version number of the filesystem block structure */
++	u16 sequencenumber;	/* The Root with the highest sequencenumber is valid */
++
++	u32 datecreated;	/* Creation date (when first formatted).  Cannot be changed. */
++	u8 bits;		/* various settings, see defines below. */
++	u8 pad1;
++	u16 pad2;
++
++	u32 reserved1[2];
++
++	u32 firstbyteh;		/* The first byte of our partition from the start of the */
++	u32 firstbyte;		/* disk.  firstbyteh = upper 32 bits, firstbyte = lower 32 bits. */
++
++	u32 lastbyteh;		/* The last byte of our partition, excluding this one. */
++	u32 lastbyte;
++
++	u32 totalblocks;	/* size of this partition in blocks */
++	u32 blocksize;		/* blocksize used */
++
++	u32 reserved2[2];
++	u32 reserved3[8];
++
++	u32 bitmapbase;		/* location of the bitmap */
++	u32 adminspacecontainer;	/* location of first adminspace container */
++	u32 rootobjectcontainer;	/* location of the root objectcontainer */
++	u32 extentbnoderoot;	/* location of the root of the extentbnode B-tree */
++	u32 objectnoderoot;	/* location of the root of the objectnode tree */
++
++	u32 reserved4[3];
++};
++
++/* On disk inode, called fsObject */
++
++struct fsObject {
++	u16 owneruid;
++	u16 ownergid;
++	u32 objectnode;
++	u32 protection;
++
++	union {
++		struct {
++			u32 data;
++			u32 size;
++		} file;
++
++		struct {
++			u32 hashtable;	/* for directories & root, 0 means no hashblock */
++			u32 firstdirblock;
++		} dir;
++	} object;
++
++	u32 datemodified;
++	u8 bits;
++
++	u8 name[0];
++	u8 comment[0];
++};
++
++/* On disk block containging a number of fsObjects */
++
++struct fsObjectContainer {
++	struct fsBlockHeader bheader;
++
++	u32 parent;
++	u32 next;
++	u32 previous;		/* 0 for the first block in the directory chain */
++
++	struct fsObject object[0];
++};
++
++/* BTree structures, used to collect file data position on disk */
++
++struct fsExtentBNode {
++	u32 key;		/* data! */
++	u32 next;
++	u32 prev;
++	u16 blocks;		/* The size in blocks of the region this Extent controls */
++};
++
++struct BNode {
++	u32 key;
++	u32 data;
++};
++
++struct BTreeContainer {
++	u16 nodecount;
++	u8 isleaf;
++	u8 nodesize;		/* Must be a multiple of 2 */
++
++	struct BNode bnode[0];
++};
++
++/* On disk block with BTreeContainer */
++
++struct fsBNodeContainer {
++	struct fsBlockHeader bheader;
++	struct BTreeContainer btc;
++};
++
++/* On disk block  with soft link data */
++
++struct fsSoftLink {
++	struct fsBlockHeader bheader;
++	u32 parent;
++	u32 next;
++	u32 previous;
++	u8 string[0];
++};
++
++/* On disk block with hashtable data */
++
++struct fsHashTable {
++	struct fsBlockHeader bheader;
++	u32 parent;
++	u32 hashentry[0];
++};
++
++/* On disk block with node index and some helper structures */
++
++struct fsNodeContainer {
++	struct fsBlockHeader bheader;
++	u32 nodenumber;
++	u32 nodes;
++	u32 node[0];
++};
++
++struct fsNode {
++	u32 data;
++};
++
++struct fsObjectNode {
++	struct fsNode node;
++	u32 next;
++	u16 hash16;
++} __attribute__ ((packed));
++
++/* Some adminspace and bitmap block structures */
++
++struct fsAdminSpace {
++	u32 space;
++	u32 bits;		
++/* Set bits are used blocks, bit 31 is	the first block in the AdminSpace. */
++};
++
++struct fsAdminSpaceContainer {
++	struct fsBlockHeader bheader;
++
++	u32 next;
++	u32 previous;
++
++	u8 bits;
++	u8 pad1;
++	u16 pad2;
++
++	struct fsAdminSpace adminspace[0];
++};
++
++struct fsBitmap {
++	struct fsBlockHeader bheader;
++
++	u32 bitmap[0];
++
++/* Bits are 1 if the block is free, and 0 if full.
++   Bitmap must consist of an integral number of longwords. */
++};
++
++/* The fsRootInfo structure has all kinds of information about the format
++   of the disk. */
++
++struct fsRootInfo {
++	u32 deletedblocks;	/* Amount in blocks which deleted files consume. */
++	u32 deletedfiles;	/* Number of deleted files in recycled. */
++	u32 freeblocks;		/* Cached number of free blocks on disk. */
++
++	u32 datecreated;
++
++	u32 lastallocatedblock;	/* Block which was most recently allocated */
++	u32 lastallocatedadminspace;	/* AdminSpaceContainer which most recently was used to allocate a block */
++	u32 lastallocatedextentnode;	/* ExtentNode which was most recently created */
++	u32 lastallocatedobjectnode;	/* ObjectNode which was most recently created */
++
++	u32 rovingpointer;
++};
++
++#endif

Added: people/waldi/linux-2.6/debian/patches/hppa-incompatible.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/hppa-incompatible.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,9775 @@
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/Documentation/parisc/todo CVS2_6_15_RC7_PA0/Documentation/parisc/todo
+--- LINUS_2_6_15_RC7/Documentation/parisc/todo	1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_15_RC7_PA0/Documentation/parisc/todo	2005-10-28 19:28:34.000000000 -0600
+@@ -0,0 +1,82 @@
++Status 2005-10-28 :
++-------------------
++ - Merged to 2.6.15
++
++Todo:
++-----
++
++ - Review and eliminate all warnings for io accesses with an eye to
++   turning on ioremap
++ - 2005-02-04 (Carlos) Review the gettimeofday
++   implementation, possibly use a light-weight-syscall and
++   rely on cr16 and cpu speed for more accurate timing?
++   This requires adding some backwards compatibility code in
++   userspace since the LWS might not be available on the
++   booted kernel. Detecting LWS is a problem.
++ - PREEMPT support
++ - CPU hotplug: we cannot bring up cpus after init, and we don't know if we can
++   shutdown cpus
++ - task_struct/thread_info split -- task_struct should not be visible in
++   entry.S, we need to move some items into thread_info -- this includes
++   pt_regs and maybe some of the flags (ptrace, etc)
++ - flush_tlb_kernel_range is horribly inefficient. this has been merged
++   with the userspace tlb flush, but it has a magic constant that needs
++   tuning
++ - Superdome support
++ - our PDC early debug console hacks need to be cleaned up somehow
++ - CPU IRQ affinity (willy)
++ - Allow more than BITS_PER_LONG cpu interrupts to be allocated (willy)
++ - 64-bit userspace (Leandro)
++ - syscall signal return path needs work, we don't loop on signal
++   delivery like other archs.
++	= 2005-02-04 (Carlos) This entry should be more specific,
++	we recently fixed do_signal such that it always
++	loops forcing the signal. If this was the bug then it was
++	fixed.
++
++
++Drivers
++-------
++
++ - write Lasi floppy driver
++ - write Suckyio floppy driver
++ - write spifi driver (rbrad)
++ - modify ncr53c8xx driver for Outfield (735 & 755)
++ - write GSC FDDI driver
++ - write Timi ASIC (74x) support
++ - EISA DMA support
++
++
++Started and in progress:
++------------------------
++ - 2004-08-16 (Carlos)
++   64-bit binutils needs to be fixed to get multiple stub
++   section support.
++ - port hil_kbd.c to new input layer
++ - port hil_ptr.c to new input layer
++
++
++CONFIG options without help:
++-----------------------------
++ - REVIEW THESE ENTRIES!
++
++ _USB_OHCI_HCD (add parisc info?)
++ _HP_SDC_RTC
++ _HIL_MLC
++ _HIL_KBD (to improve)
++ _HIL_PTR (to improve)
++
++ 
++Review all the todo entries below!
++----------------------------------
++
++ - the fix for do_fork needs checking
++ - ns87415 dma doesn't work reliably on suckyio-systems
++ - (ab)use kmap/kunmap on 64-bit to eliminate flush_dcache calls.
++ - cp_new_stat32 for sys_parisc32.c is inefficient; maybe it's better
++   to fill in a tmp stat32 and just do copy_to_user in one go at the end?
++ - investigate not putting in extable entries for put_kernel_asm; will
++   probably reduce kernel size
++ - fix HIL problem: ksoftirqd/0 eats 56% cpu (kernel 2.4 & kernel 2.6)
++ - NPTL kernel support (CLONE_*TID flags need to be correctly handled by 
++   sys_clone() and friends)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/ia64/ia32/ia32_signal.c CVS2_6_15_RC7_PA0/arch/ia64/ia32/ia32_signal.c
+--- LINUS_2_6_15_RC7/arch/ia64/ia32/ia32_signal.c	2005-12-27 13:25:34.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/ia64/ia32/ia32_signal.c	2005-09-14 06:54:22.000000000 -0600
+@@ -24,6 +24,7 @@
+ #include <linux/unistd.h>
+ #include <linux/wait.h>
+ #include <linux/compat.h>
++#include <linux/compat_siginfo.h>
+ 
+ #include <asm/intrinsics.h>
+ #include <asm/uaccess.h>
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/ia64/ia32/ia32priv.h CVS2_6_15_RC7_PA0/arch/ia64/ia32/ia32priv.h
+--- LINUS_2_6_15_RC7/arch/ia64/ia32/ia32priv.h	2005-12-27 13:25:34.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/ia64/ia32/ia32priv.h	2005-12-19 05:42:13.000000000 -0700
+@@ -225,58 +225,6 @@
+ 	unsigned int	st_ino_hi;
+ };
+ 
+-typedef struct compat_siginfo {
+-	int si_signo;
+-	int si_errno;
+-	int si_code;
+-
+-	union {
+-		int _pad[((128/sizeof(int)) - 3)];
+-
+-		/* kill() */
+-		struct {
+-			unsigned int _pid;	/* sender's pid */
+-			unsigned int _uid;	/* sender's uid */
+-		} _kill;
+-
+-		/* POSIX.1b timers */
+-		struct {
+-			compat_timer_t _tid;		/* timer id */
+-			int _overrun;		/* overrun count */
+-			char _pad[sizeof(unsigned int) - sizeof(int)];
+-			compat_sigval_t _sigval;	/* same as below */
+-			int _sys_private;       /* not to be passed to user */
+-		} _timer;
+-
+-		/* POSIX.1b signals */
+-		struct {
+-			unsigned int _pid;	/* sender's pid */
+-			unsigned int _uid;	/* sender's uid */
+-			compat_sigval_t _sigval;
+-		} _rt;
+-
+-		/* SIGCHLD */
+-		struct {
+-			unsigned int _pid;	/* which child */
+-			unsigned int _uid;	/* sender's uid */
+-			int _status;		/* exit code */
+-			compat_clock_t _utime;
+-			compat_clock_t _stime;
+-		} _sigchld;
+-
+-		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+-		struct {
+-			unsigned int _addr;	/* faulting insn/memory ref. */
+-		} _sigfault;
+-
+-		/* SIGPOLL */
+-		struct {
+-			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+-			int _fd;
+-		} _sigpoll;
+-	} _sifields;
+-} compat_siginfo_t;
+-
+ struct old_linux32_dirent {
+ 	u32	d_ino;
+ 	u32	d_offset;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/cache.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/cache.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/cache.c	2005-12-27 13:25:34.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/cache.c	2005-12-17 10:21:16.000000000 -0700
+@@ -29,9 +29,9 @@
+ #include <asm/processor.h>
+ #include <asm/sections.h>
+ 
+-int split_tlb;
+-int dcache_stride;
+-int icache_stride;
++int split_tlb __read_mostly;
++int dcache_stride __read_mostly;
++int icache_stride __read_mostly;
+ EXPORT_SYMBOL(dcache_stride);
+ 
+ 
+@@ -45,29 +45,29 @@
+ EXPORT_SYMBOL(pa_tlb_lock);
+ #endif
+ 
+-struct pdc_cache_info cache_info;
++struct pdc_cache_info cache_info __read_mostly;
+ #ifndef CONFIG_PA20
+-static struct pdc_btlb_info btlb_info;
++static struct pdc_btlb_info btlb_info __read_mostly;
+ #endif
+ 
+ #ifdef CONFIG_SMP
+ void
+ flush_data_cache(void)
+ {
+-	on_each_cpu((void (*)(void *))flush_data_cache_local, NULL, 1, 1);
++	on_each_cpu(flush_data_cache_local, NULL, 1, 1);
+ }
+ void 
+ flush_instruction_cache(void)
+ {
+-	on_each_cpu((void (*)(void *))flush_instruction_cache_local, NULL, 1, 1);
++	on_each_cpu(flush_instruction_cache_local, NULL, 1, 1);
+ }
+ #endif
+ 
+ void
+ flush_cache_all_local(void)
+ {
+-	flush_instruction_cache_local();
+-	flush_data_cache_local();
++	flush_instruction_cache_local(NULL);
++	flush_data_cache_local(NULL);
+ }
+ EXPORT_SYMBOL(flush_cache_all_local);
+ 
+@@ -332,7 +332,7 @@
+ }
+ 
+ #define FLUSH_THRESHOLD 0x80000 /* 0.5MB */
+-int parisc_cache_flush_threshold = FLUSH_THRESHOLD;
++int parisc_cache_flush_threshold __read_mostly = FLUSH_THRESHOLD;
+ 
+ void parisc_setup_cache_timing(void)
+ {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/drivers.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/drivers.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/drivers.c	2005-12-27 13:25:34.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/drivers.c	2005-12-17 11:18:59.000000000 -0700
+@@ -39,7 +39,7 @@
+ #include <asm/parisc-device.h>
+ 
+ /* See comments in include/asm-parisc/pci.h */
+-struct hppa_dma_ops *hppa_dma_ops;
++struct hppa_dma_ops *hppa_dma_ops __read_mostly;
+ EXPORT_SYMBOL(hppa_dma_ops);
+ 
+ static struct device root = {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/firmware.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/firmware.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/firmware.c	2005-12-27 13:25:34.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/firmware.c	2005-12-17 10:21:16.000000000 -0700
+@@ -80,7 +80,7 @@
+ 
+ /* Firmware needs to be initially set to narrow to determine the 
+  * actual firmware width. */
+-int parisc_narrow_firmware = 1;
++int parisc_narrow_firmware __read_mostly = 1;
+ #endif
+ 
+ /* On most currently-supported platforms, IODC I/O calls are 32-bit calls
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/inventory.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/inventory.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/inventory.c	2005-12-27 13:25:34.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/inventory.c	2005-12-17 10:54:41.000000000 -0700
+@@ -38,7 +38,7 @@
+ */
+ #undef DEBUG_PAT
+ 
+-int pdc_type = PDC_TYPE_ILLEGAL;
++int pdc_type __read_mostly = PDC_TYPE_ILLEGAL;
+ 
+ void __init setup_pdc(void)
+ {
+@@ -120,8 +120,8 @@
+ 	 * pdc info is bad in this case).
+ 	 */
+ 
+-	if (   ((start & (PAGE_SIZE - 1)) != 0)
+-	    || ((pages4k & ((1UL << PDC_PAGE_ADJ_SHIFT) - 1)) != 0) ) {
++	if (unlikely( ((start & (PAGE_SIZE - 1)) != 0)
++	    || ((pages4k & ((1UL << PDC_PAGE_ADJ_SHIFT) - 1)) != 0) )) {
+ 
+ 		panic("Memory range doesn't align with page size!\n");
+ 	}
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/pci-dma.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/pci-dma.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/pci-dma.c	2005-12-27 13:25:34.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/pci-dma.c	2005-12-17 10:54:41.000000000 -0700
+@@ -33,10 +33,10 @@
+ #include <asm/uaccess.h>
+ #include <asm/tlbflush.h>	/* for purge_tlb_*() macros */
+ 
+-static struct proc_dir_entry * proc_gsc_root = NULL;
++static struct proc_dir_entry * proc_gsc_root __read_mostly = NULL;
+ static int pcxl_proc_info(char *buffer, char **start, off_t offset, int length);
+-static unsigned long pcxl_used_bytes = 0;
+-static unsigned long pcxl_used_pages = 0;
++static unsigned long pcxl_used_bytes __read_mostly = 0;
++static unsigned long pcxl_used_pages __read_mostly = 0;
+ 
+ extern unsigned long pcxl_dma_start; /* Start of pcxl dma mapping area */
+ static spinlock_t   pcxl_res_lock;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/pdc_chassis.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/pdc_chassis.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/pdc_chassis.c	2005-12-27 13:25:34.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/pdc_chassis.c	2005-12-17 11:18:59.000000000 -0700
+@@ -30,6 +30,7 @@
+ #include <linux/kernel.h>
+ #include <linux/reboot.h>
+ #include <linux/notifier.h>
++#include <linux/cache.h>
+ 
+ #include <asm/pdc_chassis.h>
+ #include <asm/processor.h>
+@@ -38,8 +39,8 @@
+ 
+ 
+ #ifdef CONFIG_PDC_CHASSIS
+-static int pdc_chassis_old = 0;	
+-static unsigned int pdc_chassis_enabled = 1;
++static int pdc_chassis_old __read_mostly = 0;	
++static unsigned int pdc_chassis_enabled __read_mostly = 1;
+ 
+ 
+ /**
+@@ -132,7 +133,7 @@
+ {
+ #ifdef CONFIG_PDC_CHASSIS
+ 	int handle = 0;
+-	if (pdc_chassis_enabled) {
++	if (likely(pdc_chassis_enabled)) {
+ 		DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__);
+ 
+ 		/* Let see if we have something to handle... */
+@@ -142,7 +143,7 @@
+ 			printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n");
+ 			handle = 1;
+ 		}
+-		else if (pdc_chassis_old) {
++		else if (unlikely(pdc_chassis_old)) {
+ 			printk(KERN_INFO "Enabling old style chassis LED panel support.\n");
+ 			handle = 1;
+ 		}
+@@ -178,7 +179,7 @@
+ 	/* Maybe we should do that in an other way ? */
+ 	int retval = 0;
+ #ifdef CONFIG_PDC_CHASSIS
+-	if (pdc_chassis_enabled) {
++	if (likely(pdc_chassis_enabled)) {
+ 
+ 		DPRINTK(KERN_DEBUG "%s: pdc_chassis_send_status(%d)\n", __FILE__, message);
+ 
+@@ -214,7 +215,7 @@
+ 			}
+ 		} else retval = -1;
+ #else
+-		if (pdc_chassis_old) {
++		if (unlikely(pdc_chassis_old)) {
+ 			switch (message) {
+ 				case PDC_CHASSIS_DIRECT_BSTART:
+ 				case PDC_CHASSIS_DIRECT_BCOMPLETE:
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/perf.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/perf.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/perf.c	2005-12-27 13:25:34.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/perf.c	2005-12-17 10:54:41.000000000 -0700
+@@ -66,10 +66,10 @@
+ 	uint8_t		write_control;
+ };
+ 
+-static int perf_processor_interface = UNKNOWN_INTF;
+-static int perf_enabled = 0;
++static int perf_processor_interface __read_mostly = UNKNOWN_INTF;
++static int perf_enabled __read_mostly = 0;
+ static spinlock_t perf_lock;
+-struct parisc_device *cpu_device = NULL;
++struct parisc_device *cpu_device __read_mostly = NULL;
+ 
+ /* RDRs to write for PCX-W */
+ static int perf_rdrs_W[] = 
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/process.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/process.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/process.c	2005-12-27 13:25:34.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/process.c	2005-12-17 10:54:41.000000000 -0700
+@@ -54,7 +54,7 @@
+ #include <asm/uaccess.h>
+ #include <asm/unwind.h>
+ 
+-static int hlt_counter;
++static int hlt_counter __read_mostly;
+ 
+ /*
+  * Power off function, if any
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/processor.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/processor.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/processor.c	2005-12-27 13:25:34.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/processor.c	2005-12-17 10:21:16.000000000 -0700
+@@ -44,10 +44,10 @@
+ #include <asm/irq.h>		/* for struct irq_region */
+ #include <asm/parisc-device.h>
+ 
+-struct system_cpuinfo_parisc boot_cpu_data;
++struct system_cpuinfo_parisc boot_cpu_data __read_mostly;
+ EXPORT_SYMBOL(boot_cpu_data);
+ 
+-struct cpuinfo_parisc cpu_data[NR_CPUS];
++struct cpuinfo_parisc cpu_data[NR_CPUS] __read_mostly;
+ 
+ /*
+ **  	PARISC CPU driver - claim "device" and initialize CPU data structures.
+@@ -378,12 +378,12 @@
+ 	return 0;
+ }
+ 
+-static struct parisc_device_id processor_tbl[] = {
++static struct parisc_device_id processor_tbl[] __read_mostly = {
+ 	{ HPHW_NPROC, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, SVERSION_ANY_ID },
+ 	{ 0, }
+ };
+ 
+-static struct parisc_driver cpu_driver = {
++static struct parisc_driver cpu_driver __read_mostly = {
+ 	.name		= "CPU",
+ 	.id_table	= processor_tbl,
+ 	.probe		= processor_probe
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/setup.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/setup.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/setup.c	2005-12-27 13:25:34.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/setup.c	2005-12-17 10:54:41.000000000 -0700
+@@ -46,15 +46,15 @@
+ #include <asm/io.h>
+ #include <asm/setup.h>
+ 
+-char	command_line[COMMAND_LINE_SIZE];
++char	command_line[COMMAND_LINE_SIZE] __read_mostly;
+ 
+ /* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */
+-struct proc_dir_entry * proc_runway_root = NULL;
+-struct proc_dir_entry * proc_gsc_root = NULL;
+-struct proc_dir_entry * proc_mckinley_root = NULL;
++struct proc_dir_entry * proc_runway_root __read_mostly = NULL;
++struct proc_dir_entry * proc_gsc_root __read_mostly = NULL;
++struct proc_dir_entry * proc_mckinley_root __read_mostly = NULL;
+ 
+ #if !defined(CONFIG_PA20) && (defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA))
+-int parisc_bus_is_phys = 1;	/* Assume no IOMMU is present */
++int parisc_bus_is_phys __read_mostly = 1;	/* Assume no IOMMU is present */
+ EXPORT_SYMBOL(parisc_bus_is_phys);
+ #endif
+ 
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/smp.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/smp.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/smp.c	2005-12-27 13:25:35.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/smp.c	2005-12-17 10:54:41.000000000 -0700
+@@ -39,7 +39,7 @@
+ #include <asm/atomic.h>
+ #include <asm/current.h>
+ #include <asm/delay.h>
+-#include <asm/pgalloc.h>	/* for flush_tlb_all() proto/macro */
++#include <asm/tlbflush.h>
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>		/* for CPU_IRQ_REGION and friends */
+@@ -58,9 +58,9 @@
+ 
+ volatile struct task_struct *smp_init_current_idle_task;
+ 
+-static volatile int cpu_now_booting = 0;	/* track which CPU is booting */
++static volatile int cpu_now_booting __read_mostly = 0;	/* track which CPU is booting */
+ 
+-static int parisc_max_cpus = 1;
++static int parisc_max_cpus __read_mostly = 1;
+ 
+ /* online cpus are ones that we've managed to bring up completely
+  * possible cpus are all valid cpu 
+@@ -71,8 +71,8 @@
+  * empty in the beginning.
+  */
+ 
+-cpumask_t cpu_online_map = CPU_MASK_NONE;	/* Bitmap of online CPUs */
+-cpumask_t cpu_possible_map = CPU_MASK_ALL;	/* Bitmap of Present CPUs */
++cpumask_t cpu_online_map   __read_mostly = CPU_MASK_NONE;	/* Bitmap of online CPUs */
++cpumask_t cpu_possible_map __read_mostly = CPU_MASK_ALL;	/* Bitmap of Present CPUs */
+ 
+ EXPORT_SYMBOL(cpu_online_map);
+ EXPORT_SYMBOL(cpu_possible_map);
+@@ -406,12 +406,10 @@
+  * as we want to ensure all TLB's flushed before proceeding.
+  */
+ 
+-extern void flush_tlb_all_local(void);
+-
+ void
+ smp_flush_tlb_all(void)
+ {
+-	on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
++	on_each_cpu(flush_tlb_all_local, NULL, 1, 1);
+ }
+ 
+ 
+@@ -487,7 +485,7 @@
+ #endif
+ 
+ 	flush_cache_all_local(); /* start with known state */
+-	flush_tlb_all_local();
++	flush_tlb_all_local(NULL);
+ 
+ 	local_irq_enable();  /* Interrupts have been off until now */
+ 
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/time.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/time.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/time.c	2005-12-27 13:25:35.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/time.c	2005-12-17 10:21:16.000000000 -0700
+@@ -36,8 +36,8 @@
+ /* xtime and wall_jiffies keep wall-clock time */
+ extern unsigned long wall_jiffies;
+ 
+-static long clocktick;	/* timer cycles per tick */
+-static long halftick;
++static long clocktick __read_mostly;	/* timer cycles per tick */
++static long halftick __read_mostly;
+ 
+ #ifdef CONFIG_SMP
+ extern void smp_do_timer(struct pt_regs *regs);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/topology.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/topology.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/topology.c	2005-12-27 13:25:35.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/topology.c	2005-12-17 11:18:59.000000000 -0700
+@@ -20,8 +20,9 @@
+ #include <linux/init.h>
+ #include <linux/smp.h>
+ #include <linux/cpu.h>
++#include <linux/cache.h>
+ 
+-static struct cpu cpu_devices[NR_CPUS];
++static struct cpu cpu_devices[NR_CPUS] __read_mostly;
+ 
+ static int __init topology_init(void)
+ {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/unaligned.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/unaligned.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/unaligned.c	2005-12-27 13:25:35.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/unaligned.c	2005-12-17 10:21:16.000000000 -0700
+@@ -122,7 +122,7 @@
+ #define ERR_NOTHANDLED	-1
+ #define ERR_PAGEFAULT	-2
+ 
+-int unaligned_enabled = 1;
++int unaligned_enabled __read_mostly = 1;
+ 
+ void die_if_kernel (char *str, struct pt_regs *regs, long err);
+ 
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/unwind.c CVS2_6_15_RC7_PA0/arch/parisc/kernel/unwind.c
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/unwind.c	2005-12-27 13:25:35.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/unwind.c	2005-12-17 10:54:41.000000000 -0700
+@@ -35,7 +35,7 @@
+  * we can call unwind_init as early in the bootup process as 
+  * possible (before the slab allocator is initialized)
+  */
+-static struct unwind_table kernel_unwind_table;
++static struct unwind_table kernel_unwind_table __read_mostly;
+ static LIST_HEAD(unwind_tables);
+ 
+ static inline const struct unwind_table_entry *
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/kernel/vmlinux.lds.S CVS2_6_15_RC7_PA0/arch/parisc/kernel/vmlinux.lds.S
+--- LINUS_2_6_15_RC7/arch/parisc/kernel/vmlinux.lds.S	2005-12-27 13:25:35.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/kernel/vmlinux.lds.S	2005-12-19 08:10:07.000000000 -0700
+@@ -68,7 +68,7 @@
+   RODATA
+ 
+   /* writeable */
+-  . = ALIGN(4096);		/* Make sure this is paged aligned so
++  . = ALIGN(4096);		/* Make sure this is page aligned so
+   				   that we can properly leave these
+ 				   as writable */
+   data_start = .;
+@@ -105,6 +105,10 @@
+   . = ALIGN(16);
+   .data.lock_aligned : { *(.data.lock_aligned) }
+ 
++  /* rarely changed data like cpu maps */
++  . = ALIGN(16);
++  .data.read_mostly : { *(.data.read_mostly) }
++
+   _edata = .;			/* End of data section */
+ 
+   . = ALIGN(16384); 		/* init_task */
+@@ -194,14 +198,7 @@
+ #endif
+ 	}
+ 
+-  /* Stabs debugging sections.  */
+-  .stab 0 : { *(.stab) }
+-  .stabstr 0 : { *(.stabstr) }
+-  .stab.excl 0 : { *(.stab.excl) }
+-  .stab.exclstr 0 : { *(.stab.exclstr) }
+-  .stab.index 0 : { *(.stab.index) }
+-  .stab.indexstr 0 : { *(.stab.indexstr) }
+-  .comment 0 : { *(.comment) }
++  STABS_DEBUG
+   .note 0 : { *(.note) }	
+ 
+ }
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/mm/init.c CVS2_6_15_RC7_PA0/arch/parisc/mm/init.c
+--- LINUS_2_6_15_RC7/arch/parisc/mm/init.c	2005-12-27 13:25:35.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/mm/init.c	2005-12-17 11:04:12.000000000 -0700
+@@ -36,9 +36,9 @@
+ extern char __init_begin, __init_end;
+ 
+ #ifdef CONFIG_DISCONTIGMEM
+-struct node_map_data node_data[MAX_NUMNODES];
+-bootmem_data_t bmem_data[MAX_NUMNODES];
+-unsigned char pfnnid_map[PFNNID_MAP_MAX];
++struct node_map_data node_data[MAX_NUMNODES] __read_mostly;
++bootmem_data_t bmem_data[MAX_NUMNODES] __read_mostly;
++unsigned char pfnnid_map[PFNNID_MAP_MAX] __read_mostly;
+ #endif
+ 
+ static struct resource data_resource = {
+@@ -58,14 +58,14 @@
+ 	.flags	= IORESOURCE_BUSY | IORESOURCE_MEM,
+ };
+ 
+-static struct resource sysram_resources[MAX_PHYSMEM_RANGES];
++static struct resource sysram_resources[MAX_PHYSMEM_RANGES] __read_mostly;
+ 
+ /* The following array is initialized from the firmware specific
+  * information retrieved in kernel/inventory.c.
+  */
+ 
+-physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES];
+-int npmem_ranges;
++physmem_range_t pmem_ranges[MAX_PHYSMEM_RANGES] __read_mostly;
++int npmem_ranges __read_mostly;
+ 
+ #ifdef __LP64__
+ #define MAX_MEM         (~0UL)
+@@ -73,7 +73,7 @@
+ #define MAX_MEM         (3584U*1024U*1024U)
+ #endif /* !__LP64__ */
+ 
+-static unsigned long mem_limit = MAX_MEM;
++static unsigned long mem_limit __read_mostly = MAX_MEM;
+ 
+ static void __init mem_limit_func(void)
+ {
+@@ -300,6 +300,13 @@
+ 			max_pfn = start_pfn + npages;
+ 	}
+ 
++	/* IOMMU is always used to access "high mem" on those boxes
++	 * that can support enough mem that a PCI device couldn't
++	 * directly DMA to any physical addresses.
++	 * ISA DMA support will need to revisit this.
++	 */
++	max_low_pfn = max_pfn;
++
+ 	if ((bootmap_pfn - bootmap_start_pfn) != bootmap_pages) {
+ 		printk(KERN_WARNING "WARNING! bootmap sizing is messed up!\n");
+ 		BUG();
+@@ -431,11 +438,11 @@
+ #define SET_MAP_OFFSET(x) ((void *)(((unsigned long)(x) + VM_MAP_OFFSET) \
+ 				     & ~(VM_MAP_OFFSET-1)))
+ 
+-void *vmalloc_start;
++void *vmalloc_start __read_mostly;
+ EXPORT_SYMBOL(vmalloc_start);
+ 
+ #ifdef CONFIG_PA11
+-unsigned long pcxl_dma_start;
++unsigned long pcxl_dma_start __read_mostly;
+ #endif
+ 
+ void __init mem_init(void)
+@@ -475,7 +482,7 @@
+ 	return 0;
+ }
+ 
+-unsigned long *empty_zero_page;
++unsigned long *empty_zero_page __read_mostly;
+ 
+ void show_mem(void)
+ {
+@@ -785,8 +792,6 @@
+ EXPORT_SYMBOL(map_hpux_gateway_page);
+ #endif
+ 
+-extern void flush_tlb_all_local(void);
+-
+ void __init paging_init(void)
+ {
+ 	int i;
+@@ -795,7 +800,7 @@
+ 	pagetable_init();
+ 	gateway_init();
+ 	flush_cache_all_local(); /* start with known state */
+-	flush_tlb_all_local();
++	flush_tlb_all_local(NULL);
+ 
+ 	for (i = 0; i < npmem_ranges; i++) {
+ 		unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0 };
+@@ -986,7 +991,7 @@
+ 	    do_recycle++;
+ 	}
+ 	spin_unlock(&sid_lock);
+-	on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1);
++	on_each_cpu(flush_tlb_all_local, NULL, 1, 1);
+ 	if (do_recycle) {
+ 	    spin_lock(&sid_lock);
+ 	    recycle_sids(recycle_ndirty,recycle_dirty_array);
+@@ -998,7 +1003,7 @@
+ void flush_tlb_all(void)
+ {
+ 	spin_lock(&sid_lock);
+-	flush_tlb_all_local();
++	flush_tlb_all_local(NULL);
+ 	recycle_sids();
+ 	spin_unlock(&sid_lock);
+ }
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/parisc/mm/ioremap.c CVS2_6_15_RC7_PA0/arch/parisc/mm/ioremap.c
+--- LINUS_2_6_15_RC7/arch/parisc/mm/ioremap.c	2005-12-27 13:25:35.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/parisc/mm/ioremap.c	2005-12-23 18:30:19.000000000 -0700
+@@ -1,12 +1,9 @@
+ /*
+  * arch/parisc/mm/ioremap.c
+  *
+- * Re-map IO memory to kernel address space so that we can access it.
+- * This is needed for high PCI addresses that aren't mapped in the
+- * 640k-1MB IO memory area on PC's
+- *
+  * (C) Copyright 1995 1996 Linus Torvalds
+  * (C) Copyright 2001 Helge Deller <deller at gmx.de>
++ * (C) Copyright 2005 Kyle McMartin <kyle at parisc-linux.org>
+  */
+ 
+ #include <linux/vmalloc.h>
+@@ -14,81 +11,107 @@
+ #include <linux/module.h>
+ #include <asm/io.h>
+ #include <asm/pgalloc.h>
++#include <asm/tlbflush.h>
++#include <asm/cacheflush.h>
+ 
+-static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+-	unsigned long phys_addr, unsigned long flags)
+-{
+-	unsigned long end;
++static inline void 
++remap_area_pte(pte_t *pte, unsigned long address, unsigned long size,
++	       unsigned long phys_addr, unsigned long flags)
++{
++	unsigned long end, pfn;
++	pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY |
++				   _PAGE_ACCESSED | flags);
+ 
+ 	address &= ~PMD_MASK;
++
+ 	end = address + size;
+ 	if (end > PMD_SIZE)
+ 		end = PMD_SIZE;
+-	if (address >= end)
+-		BUG();
++
++	BUG_ON(address >= end);
++
++	pfn = phys_addr >> PAGE_SHIFT;
+ 	do {
+-		if (!pte_none(*pte)) {
+-			printk(KERN_ERR "remap_area_pte: page already exists\n");
+-			BUG();
+-		}
+-		set_pte(pte, mk_pte_phys(phys_addr, __pgprot(_PAGE_PRESENT | _PAGE_RW | 
+-					_PAGE_DIRTY | _PAGE_ACCESSED | flags)));
++		BUG_ON(!pte_none(*pte));
++
++		set_pte(pte, pfn_pte(pfn, pgprot));
++
+ 		address += PAGE_SIZE;
+-		phys_addr += PAGE_SIZE;
++		pfn++;
+ 		pte++;
+ 	} while (address && (address < end));
+ }
+ 
+-static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
+-	unsigned long phys_addr, unsigned long flags)
++static inline int 
++remap_area_pmd(pmd_t *pmd, unsigned long address, unsigned long size,
++	       unsigned long phys_addr, unsigned long flags)
+ {
+ 	unsigned long end;
+ 
+ 	address &= ~PGDIR_MASK;
++
+ 	end = address + size;
+ 	if (end > PGDIR_SIZE)
+ 		end = PGDIR_SIZE;
++
++	BUG_ON(address >= end);
++
+ 	phys_addr -= address;
+-	if (address >= end)
+-		BUG();
+ 	do {
+-		pte_t * pte = pte_alloc_kernel(pmd, address);
++		pte_t *pte = pte_alloc_kernel(pmd, address);
+ 		if (!pte)
+ 			return -ENOMEM;
+-		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
++
++		remap_area_pte(pte, address, end - address, 
++			       address + phys_addr, flags);
++
+ 		address = (address + PMD_SIZE) & PMD_MASK;
+ 		pmd++;
+ 	} while (address && (address < end));
++
+ 	return 0;
+ }
+ 
+-#if (USE_HPPA_IOREMAP)
+-static int remap_area_pages(unsigned long address, unsigned long phys_addr,
+-				 unsigned long size, unsigned long flags)
++#if USE_HPPA_IOREMAP
++static int 
++remap_area_pages(unsigned long address, unsigned long phys_addr,
++		 unsigned long size, unsigned long flags)
+ {
+-	int error;
+-	pgd_t * dir;
++	pgd_t *dir;
++	int error = 0;
+ 	unsigned long end = address + size;
+ 
++	BUG_ON(address >= end);
++
+ 	phys_addr -= address;
+-	dir = pgd_offset(&init_mm, address);
++	dir = pgd_offset_k(address);
++
+ 	flush_cache_all();
+-	if (address >= end)
+-		BUG();
++
+ 	do {
++		pud_t *pud;
+ 		pmd_t *pmd;
+-		pmd = pmd_alloc(&init_mm, dir, address);
++
+ 		error = -ENOMEM;
++		pud = pud_alloc(&init_mm, dir, address);
++		if (!pud)
++			break;
++
++		pmd = pmd_alloc(&init_mm, pud, address);
+ 		if (!pmd)
+ 			break;
++
+ 		if (remap_area_pmd(pmd, address, end - address,
+-					 phys_addr + address, flags))
++				   phys_addr + address, flags))
+ 			break;
++
+ 		error = 0;
+ 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ 		dir++;
+ 	} while (address && (address < end));
++
+ 	flush_tlb_all();
++
+ 	return error;
+ }
+ #endif /* USE_HPPA_IOREMAP */
+@@ -123,8 +146,7 @@
+ 
+ /*
+  * Remap an arbitrary physical address space into the kernel virtual
+- * address space. Needed when the kernel wants to access high addresses
+- * directly.
++ * address space.
+  *
+  * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+  * have to convert them into an offset in a page-aligned mapping, but the
+@@ -148,8 +170,8 @@
+ #endif
+ 
+ #else
+-	void * addr;
+-	struct vm_struct * area;
++	void *addr;
++	struct vm_struct *area;
+ 	unsigned long offset, last_addr;
+ 
+ 	/* Don't allow wraparound or zero size */
+@@ -167,9 +189,11 @@
+ 		t_addr = __va(phys_addr);
+ 		t_end = t_addr + (size - 1);
+ 	   
+-		for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
++		for (page = virt_to_page(t_addr); 
++		     page <= virt_to_page(t_end); page++) {
+ 			if(!PageReserved(page))
+ 				return NULL;
++		}
+ 	}
+ 
+ 	/*
+@@ -185,11 +209,13 @@
+ 	area = get_vm_area(size, VM_IOREMAP);
+ 	if (!area)
+ 		return NULL;
++
+ 	addr = area->addr;
+ 	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ 		vfree(addr);
+ 		return NULL;
+ 	}
++
+ 	return (void __iomem *) (offset + (char *)addr);
+ #endif
+ }
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/arch/x86_64/ia32/ia32_signal.c CVS2_6_15_RC7_PA0/arch/x86_64/ia32/ia32_signal.c
+--- LINUS_2_6_15_RC7/arch/x86_64/ia32/ia32_signal.c	2005-12-27 13:25:38.000000000 -0700
++++ CVS2_6_15_RC7_PA0/arch/x86_64/ia32/ia32_signal.c	2005-11-12 20:29:21.000000000 -0700
+@@ -23,6 +23,7 @@
+ #include <linux/stddef.h>
+ #include <linux/personality.h>
+ #include <linux/compat.h>
++#include <linux/compat_siginfo.h>
+ #include <asm/ucontext.h>
+ #include <asm/uaccess.h>
+ #include <asm/i387.h>
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/net/tulip/media.c CVS2_6_15_RC7_PA0/drivers/net/tulip/media.c
+--- LINUS_2_6_15_RC7/drivers/net/tulip/media.c	2005-12-27 13:25:46.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/net/tulip/media.c	2005-09-14 06:56:25.000000000 -0600
+@@ -44,8 +44,10 @@
+ 
+ /* MII transceiver control section.
+    Read and write the MII registers using software-generated serial
+-   MDIO protocol.  See the MII specifications or DP83840A data sheet
+-   for details. */
++   MDIO protocol.
++   See IEEE 802.3-2002.pdf (Section 2, Chapter "22.2.4 Management functions")
++   or DP83840A data sheet for more details.
++   */
+ 
+ int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
+ {
+@@ -261,24 +263,56 @@
+ 				u16 *reset_sequence = &((u16*)(p+3))[init_length];
+ 				int reset_length = p[2 + init_length*2];
+ 				misc_info = reset_sequence + reset_length;
+-				if (startup)
++				if (startup) {
++					int timeout = 10;	/* max 1 ms */
+ 					for (i = 0; i < reset_length; i++)
+ 						iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
++				
++					/* flush posted writes */
++					ioread32(ioaddr + CSR15);
++
++					/* Sect 3.10.3 in DP83840A.pdf (p39) */
++					udelay(500);
++
++					/* Section 4.2 in DP83840A.pdf (p43) */
++					/* and IEEE 802.3 "22.2.4.1.1 Reset" */
++					while (timeout-- &&
++						(tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
++						udelay(100);
++				}
+ 				for (i = 0; i < init_length; i++)
+ 					iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
++
++				ioread32(ioaddr + CSR15);	/* flush posted writes */
+ 			} else {
+ 				u8 *init_sequence = p + 2;
+ 				u8 *reset_sequence = p + 3 + init_length;
+ 				int reset_length = p[2 + init_length];
+ 				misc_info = (u16*)(reset_sequence + reset_length);
+ 				if (startup) {
++					int timeout = 10;	/* max 1 ms */
+ 					iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
+ 					for (i = 0; i < reset_length; i++)
+ 						iowrite32(reset_sequence[i], ioaddr + CSR12);
++
++					/* flush posted writes */
++					ioread32(ioaddr + CSR12);
++
++					/* Sect 3.10.3 in DP83840A.pdf (p39) */
++					udelay(500);
++
++					/* Section 4.2 in DP83840A.pdf (p43) */
++					/* and IEEE 802.3 "22.2.4.1.1 Reset" */
++					while (timeout-- &&
++						(tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET))
++						udelay(100);
+ 				}
+ 				for (i = 0; i < init_length; i++)
+ 					iowrite32(init_sequence[i], ioaddr + CSR12);
++
++				ioread32(ioaddr + CSR12);	/* flush posted writes */
+ 			}
++
+ 			tmp_info = get_u16(&misc_info[1]);
+ 			if (tmp_info)
+ 				tp->advertising[phy_num] = tmp_info | 1;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/net/tulip/tulip.h CVS2_6_15_RC7_PA0/drivers/net/tulip/tulip.h
+--- LINUS_2_6_15_RC7/drivers/net/tulip/tulip.h	2005-12-27 13:25:46.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/net/tulip/tulip.h	2005-09-14 06:56:25.000000000 -0600
+@@ -474,8 +474,11 @@
+ 			udelay(10);
+ 
+ 		if (!i)
+-			printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed\n",
+-					pci_name(tp->pdev));
++			printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed"
++					" (CSR5 0x%x CSR6 0x%x)\n",
++					pci_name(tp->pdev),
++					ioread32(ioaddr + CSR5),
++					ioread32(ioaddr + CSR6));
+ 	}
+ }
+ 
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/net/tulip/tulip_core.c CVS2_6_15_RC7_PA0/drivers/net/tulip/tulip_core.c
+--- LINUS_2_6_15_RC7/drivers/net/tulip/tulip_core.c	2005-12-27 13:25:46.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/net/tulip/tulip_core.c	2005-11-11 21:07:59.000000000 -0700
+@@ -22,7 +22,7 @@
+ #else
+ #define DRV_VERSION	"1.1.13"
+ #endif
+-#define DRV_RELDATE	"May 11, 2002"
++#define DRV_RELDATE	"December 15, 2004"
+ 
+ 
+ #include <linux/module.h>
+@@ -148,7 +148,7 @@
+ 	HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer },
+ 
+   /* DC21142, DC21143 */
+-  { "Digital DS21143 Tulip", 128, 0x0801fbff,
++  { "Digital DS21142/DS21143 Tulip", 128, 0x0801fbff,
+ 	HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY
+ 	| HAS_INTR_MITIGATION | HAS_PCI_MWI, t21142_timer },
+ 
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/dino.c CVS2_6_15_RC7_PA0/drivers/parisc/dino.c
+--- LINUS_2_6_15_RC7/drivers/parisc/dino.c	2005-12-27 13:25:46.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/parisc/dino.c	2005-12-14 00:49:15.000000000 -0700
+@@ -124,6 +124,7 @@
+ 
+ #define DINO_IRQS 11		/* bits 0-10 are architected */
+ #define DINO_IRR_MASK	0x5ff	/* only 10 bits are implemented */
++#define DINO_LOCAL_IRQS (DINO_IRQS+1)
+ 
+ #define DINO_MASK_IRQ(x)	(1<<(x))
+ 
+@@ -146,7 +147,7 @@
+ 	unsigned long		txn_addr; /* EIR addr to generate interrupt */ 
+ 	u32			txn_data; /* EIR data assign to each dino */ 
+ 	u32 			imr;	  /* IRQ's which are enabled */ 
+-	int			global_irq[12]; /* map IMR bit to global irq */
++	int			global_irq[DINO_LOCAL_IRQS]; /* map IMR bit to global irq */
+ #ifdef DINO_DEBUG
+ 	unsigned int		dino_irr0; /* save most recent IRQ line stat */
+ #endif
+@@ -297,7 +298,7 @@
+ static void dino_disable_irq(unsigned int irq)
+ {
+ 	struct dino_device *dino_dev = irq_desc[irq].handler_data;
+-	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq);
++	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
+ 
+ 	DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq);
+ 
+@@ -309,7 +310,7 @@
+ static void dino_enable_irq(unsigned int irq)
+ {
+ 	struct dino_device *dino_dev = irq_desc[irq].handler_data;
+-	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, irq);
++	int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
+ 	u32 tmp;
+ 
+ 	DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq);
+@@ -435,6 +436,21 @@
+ 	dino_assign_irq(dino, irq, &dev->irq);
+ }
+ 
++
++/*
++ * Cirrus 6832 Cardbus reports wrong irq on RDI Tadpole PARISC Laptop (deller at gmx.de)
++ * (the irqs are off-by-one, not sure yet if this is a cirrus, dino-hardware or dino-driver problem...)
++ */
++static void __devinit quirk_cirrus_cardbus(struct pci_dev *dev)
++{
++	u8 new_irq = dev->irq - 1;
++	printk(KERN_INFO "PCI: Cirrus Cardbus IRQ fixup for %s, from %d to %d\n",
++			pci_name(dev), dev->irq, new_irq);
++	dev->irq = new_irq;
++}
++DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832, quirk_cirrus_cardbus );
++
++
+ static void __init
+ dino_bios_init(void)
+ {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/eisa.c CVS2_6_15_RC7_PA0/drivers/parisc/eisa.c
+--- LINUS_2_6_15_RC7/drivers/parisc/eisa.c	2005-12-27 13:25:46.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/parisc/eisa.c	2005-12-19 06:48:41.000000000 -0700
+@@ -57,7 +57,7 @@
+ 
+ static DEFINE_SPINLOCK(eisa_irq_lock);
+ 
+-void __iomem *eisa_eeprom_addr;
++void __iomem *eisa_eeprom_addr __read_mostly;
+ 
+ /* We can only have one EISA adapter in the system because neither
+  * implementation can be flexed.
+@@ -141,7 +141,7 @@
+  * in the furure. 
+  */
+ /* irq 13,8,2,1,0 must be edge */
+-static unsigned int eisa_irq_level; /* default to edge triggered */
++static unsigned int eisa_irq_level __read_mostly; /* default to edge triggered */
+ 
+ 
+ /* called by free irq */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/eisa_eeprom.c CVS2_6_15_RC7_PA0/drivers/parisc/eisa_eeprom.c
+--- LINUS_2_6_15_RC7/drivers/parisc/eisa_eeprom.c	2005-12-27 13:25:46.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/parisc/eisa_eeprom.c	2005-12-23 19:04:41.000000000 -0700
+@@ -48,7 +48,7 @@
+ }
+ 
+ static ssize_t eisa_eeprom_read(struct file * file,
+-			      char *buf, size_t count, loff_t *ppos )
++			      char __user *buf, size_t count, loff_t *ppos )
+ {
+ 	unsigned char *tmp;
+ 	ssize_t ret;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/lasi.c CVS2_6_15_RC7_PA0/drivers/parisc/lasi.c
+--- LINUS_2_6_15_RC7/drivers/parisc/lasi.c	2005-12-27 13:25:46.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/parisc/lasi.c	2005-12-19 06:48:41.000000000 -0700
+@@ -150,7 +150,7 @@
+  * 
+  */
+ 
+-static unsigned long lasi_power_off_hpa;
++static unsigned long lasi_power_off_hpa __read_mostly;
+ 
+ static void lasi_power_off(void)
+ {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/lba_pci.c CVS2_6_15_RC7_PA0/drivers/parisc/lba_pci.c
+--- LINUS_2_6_15_RC7/drivers/parisc/lba_pci.c	2005-12-27 13:25:46.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/parisc/lba_pci.c	2005-12-19 06:48:41.000000000 -0700
+@@ -167,7 +167,7 @@
+ 
+ /* non-postable I/O port space, densely packed */
+ #define LBA_PORT_BASE	(PCI_F_EXTEND | 0xfee00000UL)
+-static void __iomem *astro_iop_base;
++static void __iomem *astro_iop_base __read_mostly;
+ 
+ #define ELROY_HVERS	0x782
+ #define MERCURY_HVERS	0x783
+@@ -695,11 +695,71 @@
+ 		}
+ 	}
+ }
++
++
++/*
++ * truncate_pat_collision:  Deal with overlaps or outright collisions
++ *			between PAT PDC reported ranges.
++ *
++ *   Broken PA8800 firmware will report lmmio range that
++ *   overlaps with CPU HPA. Just truncate the lmmio range.
++ *
++ *   BEWARE: conflicts with this lmmio range may be an
++ *   elmmio range which is pointing down another rope.
++ *
++ *  FIXME: only deals with one collision per range...theoretically we
++ *  could have several. Supporting more than one collision will get messy.
++ */
++static unsigned long
++truncate_pat_collision(struct resource *root, struct resource *new)
++{
++	unsigned long start = new->start;
++	unsigned long end = new->end;
++	struct resource *tmp = root->child;
++
++	if (end <= start || start < root->start || !tmp)
++		return 0;
++
++	/* find first overlap */
++	while (tmp && tmp->end < start)
++		tmp = tmp->sibling;
++
++	/* no entries overlap */
++	if (!tmp)  return 0;
++
++	/* found one that starts behind the new one
++	** Don't need to do anything.
++	*/
++	if (tmp->start >= end) return 0;
++
++	if (tmp->start <= start) {
++		/* "front" of new one overlaps */
++		new->start = tmp->end + 1;
++
++		if (tmp->end >= end) {
++			/* AACCKK! totally overlaps! drop this range. */
++			return 1;
++		}
++	} 
++
++	if (tmp->end < end ) {
++		/* "end" of new one overlaps */
++		new->end = tmp->start - 1;
++	}
++
++	printk(KERN_WARNING "LBA: Truncating lmmio_space [%lx/%lx] "
++					"to [%lx,%lx]\n",
++			start, end,
++			new->start, new->end );
++
++	return 0;	/* truncation successful */
++}
++
+ #else
+-#define lba_claim_dev_resources(dev)
++#define lba_claim_dev_resources(dev) do { } while (0)
++#define truncate_pat_collision(r,n)  (0)
+ #endif
+ 
+-
+ /*
+ ** The algorithm is generic code.
+ ** But it needs to access local data structures to get the IRQ base.
+@@ -747,6 +807,9 @@
+ 			lba_dump_res(&ioport_resource, 2);
+ 			BUG();
+ 		}
++		/* advertize Host bridge resources to PCI bus */
++		bus->resource[0] = &(ldev->hba.io_space);
++		i = 1;
+ 
+ 		if (ldev->hba.elmmio_space.start) {
+ 			err = request_resource(&iomem_resource,
+@@ -760,23 +823,35 @@
+ 
+ 				/* lba_dump_res(&iomem_resource, 2); */
+ 				/* BUG(); */
+-			}
++			} else
++				bus->resource[i++] = &(ldev->hba.elmmio_space);
+ 		}
+ 
+-		err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space));
+-		if (err < 0) {
+-			/*   FIXME  overlaps with elmmio will fail here.
+-			 *   Need to prune (or disable) the distributed range.
+-			 *
+-			 *   BEWARE: conflicts with this lmmio range may be
+-			 *   elmmio range which is pointing down another rope.
+-			 */
+ 
+-			printk("FAILED: lba_fixup_bus() request for "
++		/*   Overlaps with elmmio can (and should) fail here.
++		 *   We will prune (or ignore) the distributed range.
++		 *
++		 *   FIXME: SBA code should register all elmmio ranges first.
++		 *      that would take care of elmmio ranges routed
++		 *	to a different rope (already discovered) from
++		 *	getting registered *after* LBA code has already
++		 *	registered it's distributed lmmio range.
++		 */
++		if (truncate_pat_collision(&iomem_resource,
++				       	&(ldev->hba.lmmio_space))) {
++
++			printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n",
++					ldev->hba.lmmio_space.start,
++					ldev->hba.lmmio_space.end);
++		} else {
++			err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space));
++			if (err < 0) {
++				printk(KERN_ERR "FAILED: lba_fixup_bus() request for "
+ 					"lmmio_space [%lx/%lx]\n",
+ 					ldev->hba.lmmio_space.start,
+ 					ldev->hba.lmmio_space.end);
+-			/* lba_dump_res(&iomem_resource, 2); */
++			} else
++				bus->resource[i++] = &(ldev->hba.lmmio_space);
+ 		}
+ 
+ #ifdef CONFIG_64BIT
+@@ -791,18 +866,10 @@
+ 				lba_dump_res(&iomem_resource, 2);
+ 				BUG();
+ 			}
++			bus->resource[i++] = &(ldev->hba.gmmio_space);
+ 		}
+ #endif
+ 
+-		/* advertize Host bridge resources to PCI bus */
+-		bus->resource[0] = &(ldev->hba.io_space);
+-		bus->resource[1] = &(ldev->hba.lmmio_space);
+-		i=2;
+-		if (ldev->hba.elmmio_space.start)
+-			bus->resource[i++] = &(ldev->hba.elmmio_space);
+-		if (ldev->hba.gmmio_space.start)
+-			bus->resource[i++] = &(ldev->hba.gmmio_space);
+-			
+ 	}
+ 
+ 	list_for_each(ln, &bus->devices) {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/led.c CVS2_6_15_RC7_PA0/drivers/parisc/led.c
+--- LINUS_2_6_15_RC7/drivers/parisc/led.c	2005-12-27 13:25:46.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/parisc/led.c	2005-12-19 06:48:41.000000000 -0700
+@@ -3,7 +3,7 @@
+  *
+  *      (c) Copyright 2000 Red Hat Software
+  *      (c) Copyright 2000 Helge Deller <hdeller at redhat.com>
+- *      (c) Copyright 2001-2004 Helge Deller <deller at gmx.de>
++ *      (c) Copyright 2001-2005 Helge Deller <deller at gmx.de>
+  *      (c) Copyright 2001 Randolph Chung <tausq at debian.org>
+  *
+  *      This program is free software; you can redistribute it and/or modify
+@@ -56,13 +56,13 @@
+    relatively large amount of CPU time, some of the calculations can be 
+    turned off with the following variables (controlled via procfs) */
+ 
+-static int led_type = -1;
++static int led_type __read_mostly = -1;
+ static unsigned char lastleds;	/* LED state from most recent update */
+-static unsigned int led_heartbeat = 1;
+-static unsigned int led_diskio = 1;
+-static unsigned int led_lanrxtx = 1;
+-static char lcd_text[32];
+-static char lcd_text_default[32];
++static unsigned int led_heartbeat __read_mostly = 1;
++static unsigned int led_diskio    __read_mostly = 1;
++static unsigned int led_lanrxtx   __read_mostly = 1;
++static char lcd_text[32]          __read_mostly;
++static char lcd_text_default[32]  __read_mostly;
+ 
+ 
+ static struct workqueue_struct *led_wq;
+@@ -108,7 +108,7 @@
+ /* lcd_info is pre-initialized to the values needed to program KittyHawk LCD's 
+  * HP seems to have used Sharp/Hitachi HD44780 LCDs most of the time. */
+ static struct pdc_chassis_lcd_info_ret_block
+-lcd_info __attribute__((aligned(8))) =
++lcd_info __attribute__((aligned(8))) __read_mostly =
+ {
+ 	.model =		DISPLAY_MODEL_LCD,
+ 	.lcd_width =		16,
+@@ -144,7 +144,7 @@
+ device_initcall(start_task);
+ 
+ /* ptr to LCD/LED-specific function */
+-static void (*led_func_ptr) (unsigned char);
++static void (*led_func_ptr) (unsigned char) __read_mostly;
+ 
+ #ifdef CONFIG_PROC_FS
+ static int led_proc_read(char *page, char **start, off_t off, int count, 
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/pdc_stable.c CVS2_6_15_RC7_PA0/drivers/parisc/pdc_stable.c
+--- LINUS_2_6_15_RC7/drivers/parisc/pdc_stable.c	2005-12-27 13:25:46.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/parisc/pdc_stable.c	2005-12-19 06:48:41.000000000 -0700
+@@ -56,7 +56,7 @@
+ #include <asm/uaccess.h>
+ #include <asm/hardware.h>
+ 
+-#define PDCS_VERSION	"0.09"
++#define PDCS_VERSION	"0.10"
+ 
+ #define PDCS_ADDR_PPRI	0x00
+ #define PDCS_ADDR_OSID	0x40
+@@ -70,7 +70,7 @@
+ MODULE_LICENSE("GPL");
+ MODULE_VERSION(PDCS_VERSION);
+ 
+-static unsigned long pdcs_size = 0;
++static unsigned long pdcs_size __read_mostly;
+ 
+ /* This struct defines what we need to deal with a parisc pdc path entry */
+ struct pdcspath_entry {
+@@ -194,7 +194,8 @@
+ 		return -EIO;
+ 	}
+ 		
+-	entry->ready = 1;
++	/* kobject is already registered */
++	entry->ready = 2;
+ 	
+ 	DPRINTK("%s: device: 0x%p\n", __func__, entry->dev);
+ 	
+@@ -653,15 +654,21 @@
+ {
+ 	unsigned short i;
+ 	struct pdcspath_entry *entry;
++	int err;
+ 	
+ 	for (i = 0; (entry = pdcspath_entries[i]); i++) {
+ 		if (pdcspath_fetch(entry) < 0)
+ 			continue;
+ 
+-		kobject_set_name(&entry->kobj, "%s", entry->name);
++		if ((err = kobject_set_name(&entry->kobj, "%s", entry->name)))
++			return err;
+ 		kobj_set_kset_s(entry, paths_subsys);
+-		kobject_register(&entry->kobj);
+-
++		if ((err = kobject_register(&entry->kobj)))
++			return err;
++		
++		/* kobject is now registered */
++		entry->ready = 2;
++		
+ 		if (!entry->dev)
+ 			continue;
+ 
+@@ -675,14 +682,14 @@
+ /**
+  * pdcs_unregister_pathentries - Routine called when unregistering the module.
+  */
+-static inline void __exit
++static inline void
+ pdcs_unregister_pathentries(void)
+ {
+ 	unsigned short i;
+ 	struct pdcspath_entry *entry;
+ 	
+ 	for (i = 0; (entry = pdcspath_entries[i]); i++)
+-		if (entry->ready)
++		if (entry->ready >= 2)
+ 			kobject_unregister(&entry->kobj);	
+ }
+ 
+@@ -704,7 +711,7 @@
+ 
+ 	/* For now we'll register the pdc subsys within this driver */
+ 	if ((rc = firmware_register(&pdc_subsys)))
+-		return rc;
++		goto fail_firmreg;
+ 
+ 	/* Don't forget the info entry */
+ 	for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++)
+@@ -713,12 +720,25 @@
+ 	
+ 	/* register the paths subsys as a subsystem of pdc subsys */
+ 	kset_set_kset_s(&paths_subsys, pdc_subsys);
+-	subsystem_register(&paths_subsys);
++	if ((rc= subsystem_register(&paths_subsys)))
++		goto fail_subsysreg;
+ 
+ 	/* now we create all "files" for the paths subsys */
+-	pdcs_register_pathentries();
++	if ((rc = pdcs_register_pathentries()))
++		goto fail_pdcsreg;
++
++	return rc;
+ 	
+-	return 0;
++fail_pdcsreg:
++	pdcs_unregister_pathentries();
++	subsystem_unregister(&paths_subsys);
++	
++fail_subsysreg:
++	firmware_unregister(&pdc_subsys);
++	
++fail_firmreg:
++	printk(KERN_INFO "PDC Stable Storage bailing out\n");
++	return rc;
+ }
+ 
+ static void __exit
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parisc/power.c CVS2_6_15_RC7_PA0/drivers/parisc/power.c
+--- LINUS_2_6_15_RC7/drivers/parisc/power.c	2005-12-27 13:25:46.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/parisc/power.c	2005-12-19 06:48:41.000000000 -0700
+@@ -2,7 +2,7 @@
+  * linux/arch/parisc/kernel/power.c
+  * HP PARISC soft power switch support driver
+  *
+- * Copyright (c) 2001-2002 Helge Deller <deller at gmx.de>
++ * Copyright (c) 2001-2005 Helge Deller <deller at gmx.de>
+  * All rights reserved.
+  *
+  *
+@@ -102,7 +102,7 @@
+ 
+ static void poweroff(void)
+ {
+-	static int powering_off;
++	static int powering_off __read_mostly;
+ 
+ 	if (powering_off)
+ 		return;
+@@ -113,7 +113,7 @@
+ 
+ 
+ /* local time-counter for shutdown */
+-static int shutdown_timer;
++static int shutdown_timer __read_mostly;
+ 
+ /* check, give feedback and start shutdown after one second */
+ static void process_shutdown(void)
+@@ -139,7 +139,7 @@
+ DECLARE_TASKLET_DISABLED(power_tasklet, NULL, 0);
+ 
+ /* soft power switch enabled/disabled */
+-int pwrsw_enabled = 1;
++int pwrsw_enabled __read_mostly = 1;
+ 
+ /*
+  * On gecko style machines (e.g. 712/xx and 715/xx) 
+@@ -149,7 +149,7 @@
+  */
+ static void gecko_tasklet_func(unsigned long unused)
+ {
+-	if (!pwrsw_enabled)
++	if (unlikely(!pwrsw_enabled))
+ 		return;
+ 
+ 	if (__getDIAG(25) & 0x80000000) {
+@@ -173,7 +173,7 @@
+ {
+         unsigned long current_status;
+ 	
+-	if (!pwrsw_enabled)
++	if (unlikely(!pwrsw_enabled))
+ 		return;
+ 
+ 	current_status = gsc_readl(soft_power_reg);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/parport/Kconfig CVS2_6_15_RC7_PA0/drivers/parport/Kconfig
+--- LINUS_2_6_15_RC7/drivers/parport/Kconfig	2005-12-27 13:25:47.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/parport/Kconfig	2005-12-07 14:28:17.000000000 -0700
+@@ -121,6 +121,7 @@
+ 	tristate
+ 	default GSC
+ 	depends on PARPORT
++	select PARPORT_NOT_PC
+ 
+ config PARPORT_SUNBPP
+ 	tristate "Sparc hardware (EXPERIMENTAL)"
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/pcmcia/Kconfig CVS2_6_15_RC7_PA0/drivers/pcmcia/Kconfig
+--- LINUS_2_6_15_RC7/drivers/pcmcia/Kconfig	2005-12-27 13:25:47.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/pcmcia/Kconfig	2005-12-11 10:56:12.000000000 -0700
+@@ -200,7 +200,7 @@
+ 
+ config PCMCIA_PROBE
+ 	bool
+-	default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X
++	default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711XS && !PARISC
+ 
+ config M32R_PCC
+ 	bool "M32R PCMCIA I/F"
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/53c700.c CVS2_6_15_RC7_PA0/drivers/scsi/53c700.c
+--- LINUS_2_6_15_RC7/drivers/scsi/53c700.c	2005-12-27 13:25:48.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/53c700.c	2005-11-11 21:08:09.000000000 -0700
+@@ -302,6 +302,7 @@
+ 	__u8 *memory;
+ 	__u32 *script;
+ 	struct Scsi_Host *host;
++	const char *chipname;
+ 	static int banner = 0;
+ 	int j;
+ 
+@@ -402,11 +403,11 @@
+ 		printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley at HansenPartnership.com\n");
+ 		banner = 1;
+ 	}
++	chipname = hostdata->chip710 ? "53c710" : \
++		   (hostdata->fast ? "53c700-66" : "53c700");
+ 	printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no,
+-	       hostdata->chip710 ? "53c710" : 
+-	       (hostdata->fast ? "53c700-66" : "53c700"),
+-	       hostdata->rev, hostdata->differential ?
+-	       "(Differential)" : "");
++			chipname, hostdata->rev,
++			hostdata->differential ?  "(Differential)" : "");
+ 	/* reset the chip */
+ 	NCR_700_chip_reset(host);
+ 
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/Kconfig CVS2_6_15_RC7_PA0/drivers/scsi/Kconfig
+--- LINUS_2_6_15_RC7/drivers/scsi/Kconfig	2005-12-27 13:25:48.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/Kconfig	2005-12-12 09:35:31.000000000 -0700
+@@ -1066,7 +1066,7 @@
+ 	  memory using PCI DAC cycles.
+ 
+ config SCSI_SYM53C8XX_DEFAULT_TAGS
+-	int "default tagged command queue depth"
++	int "Default tagged command queue depth"
+ 	depends on SCSI_SYM53C8XX_2
+ 	default "16"
+ 	help
+@@ -1077,7 +1077,7 @@
+ 	  exceed CONFIG_SCSI_SYM53C8XX_MAX_TAGS.
+ 
+ config SCSI_SYM53C8XX_MAX_TAGS
+-	int "maximum number of queued commands"
++	int "Maximum number of queued commands"
+ 	depends on SCSI_SYM53C8XX_2
+ 	default "64"
+ 	help
+@@ -1086,13 +1086,14 @@
+ 	  possible. The driver supports up to 256 queued commands per device.
+ 	  This value is used as a compiled-in hard limit.
+ 
+-config SCSI_SYM53C8XX_IOMAPPED
+-	bool "use port IO"
++config SCSI_SYM53C8XX_MMIO
++	bool "Use memory mapped IO"
+ 	depends on SCSI_SYM53C8XX_2
++	default y
+ 	help
+-	  If you say Y here, the driver will use port IO to access
+-	  the card.  This is significantly slower then using memory
+-	  mapped IO.  Most people should answer N.
++	  Memory mapped IO is faster than Port IO.  Most people should
++	  answer Y here, but some machines may have problems.  If you have
++	  to answer N here, please report the problem to the maintainer.
+ 
+ config SCSI_IPR
+ 	tristate "IBM Power Linux RAID adapter support"
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/constants.c CVS2_6_15_RC7_PA0/drivers/scsi/constants.c
+--- LINUS_2_6_15_RC7/drivers/scsi/constants.c	2005-12-27 13:25:48.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/constants.c	2005-12-12 17:01:16.000000000 -0700
+@@ -114,8 +114,7 @@
+ 	{0xd, "Report supported task management functions"},
+ 	{0xe, "Report priority"},
+ };
+-#define MAINT_IN_SZ \
+-        (int)(sizeof(maint_in_arr) / sizeof(maint_in_arr[0]))
++#define MAINT_IN_SZ (int)ARRAY_SIZE(maint_in_arr)
+ 
+ static const struct value_name_pair maint_out_arr[] = {
+ 	{0x6, "Set device identifier"},
+@@ -123,34 +122,29 @@
+ 	{0xb, "Change aliases"},
+ 	{0xe, "Set priority"},
+ };
+-#define MAINT_OUT_SZ \
+-        (int)(sizeof(maint_out_arr) / sizeof(maint_out_arr[0]))
++#define MAINT_OUT_SZ (int)ARRAY_SIZE(maint_out_arr)
+ 
+ static const struct value_name_pair serv_in12_arr[] = {
+ 	{0x1, "Read media serial number"},
+ };
+-#define SERV_IN12_SZ  \
+-        (int)(sizeof(serv_in12_arr) / sizeof(serv_in12_arr[0]))
++#define SERV_IN12_SZ (int)ARRAY_SIZE(serv_in12_arr)
+ 
+ static const struct value_name_pair serv_out12_arr[] = {
+ 	{-1, "dummy entry"},
+ };
+-#define SERV_OUT12_SZ \
+-        (int)(sizeof(serv_out12_arr) / sizeof(serv_in12_arr[0]))
++#define SERV_OUT12_SZ (int)ARRAY_SIZE(serv_out12_arr)
+ 
+ static const struct value_name_pair serv_in16_arr[] = {
+ 	{0x10, "Read capacity(16)"},
+ 	{0x11, "Read long(16)"},
+ };
+-#define SERV_IN16_SZ  \
+-        (int)(sizeof(serv_in16_arr) / sizeof(serv_in16_arr[0]))
++#define SERV_IN16_SZ (int)ARRAY_SIZE(serv_in16_arr)
+ 
+ static const struct value_name_pair serv_out16_arr[] = {
+ 	{0x11, "Write long(16)"},
+ 	{0x1f, "Notify data transfer device(16)"},
+ };
+-#define SERV_OUT16_SZ \
+-        (int)(sizeof(serv_out16_arr) / sizeof(serv_in16_arr[0]))
++#define SERV_OUT16_SZ (int)ARRAY_SIZE(serv_out16_arr)
+ 
+ static const struct value_name_pair variable_length_arr[] = {
+ 	{0x1, "Rebuild(32)"},
+@@ -190,8 +184,7 @@
+ 	{0x8f7e, "Perform SCSI command (osd)"},
+ 	{0x8f7f, "Perform task management function (osd)"},
+ };
+-#define VARIABLE_LENGTH_SZ \
+-        (int)(sizeof(variable_length_arr) / sizeof(variable_length_arr[0]))
++#define VARIABLE_LENGTH_SZ (int)ARRAY_SIZE(variable_length_arr)
+ 
+ static const char * get_sa_name(const struct value_name_pair * arr,
+ 			        int arr_sz, int service_action)
+@@ -1287,19 +1280,20 @@
+ /* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue", 
+ /* 0x0f */ "Initiate Recovery", "Release Recovery"
+ };
+-#define NO_ONE_BYTE_MSGS (sizeof(one_byte_msgs)  / sizeof (const char *))
++#define NO_ONE_BYTE_MSGS ARRAY_SIZE(one_byte_msgs)
+ 
+ static const char *two_byte_msgs[] = {
+-/* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag"
++/* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag",
+ /* 0x23 */ "Ignore Wide Residue"
+ };
+-#define NO_TWO_BYTE_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
++#define NO_TWO_BYTE_MSGS ARRAY_SIZE(two_byte_msgs)
+ 
+ static const char *extended_msgs[] = {
+ /* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request",
+-/* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request"
++/* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request",
++/* 0x04 */ "Parallel Protocol Request"
+ };
+-#define NO_EXTENDED_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
++#define NO_EXTENDED_MSGS ARRAY_SIZE(extended_msgs)
+ 
+ 
+ int scsi_print_msg (const unsigned char *msg)
+@@ -1324,6 +1318,10 @@
+ 		case EXTENDED_WDTR:
+ 			printk("width = 2^%d bytes", msg[3]);
+ 			break;
++		case EXTENDED_PPR:
++			printk("period = %d ns, offset = %d, width = %d",
++				(int) msg[3] * 4, (int) msg[5], 1 << msg[6]);
++			break;
+ 		default:
+ 		for (i = 2; i < len; ++i) 
+ 			printk("%02x ", msg[i]);
+@@ -1401,7 +1399,7 @@
+ "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", 
+ "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
+ "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"};
+-#define NUM_HOSTBYTE_STRS (sizeof(hostbyte_table) / sizeof(const char *))
++#define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table)
+ 
+ void scsi_print_hostbyte(int scsiresult)
+ {
+@@ -1425,12 +1423,12 @@
+ static const char * driverbyte_table[]={
+ "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT",  "DRIVER_MEDIA", "DRIVER_ERROR", 
+ "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"};
+-#define NUM_DRIVERBYTE_STRS (sizeof(driverbyte_table) / sizeof(const char *))
++#define NUM_DRIVERBYTE_STRS ARRAY_SIZE(driverbyte_table)
+ 
+ static const char * driversuggest_table[]={"SUGGEST_OK",
+ "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
+ "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"};
+-#define NUM_SUGGEST_STRS (sizeof(driversuggest_table) / sizeof(const char *))
++#define NUM_SUGGEST_STRS ARRAY_SIZE(driversuggest_table)
+ 
+ void scsi_print_driverbyte(int scsiresult)
+ {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/ncr53c8xx.c CVS2_6_15_RC7_PA0/drivers/scsi/ncr53c8xx.c
+--- LINUS_2_6_15_RC7/drivers/scsi/ncr53c8xx.c	2005-12-27 13:25:48.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/ncr53c8xx.c	2005-12-12 12:01:54.000000000 -0700
+@@ -69,6 +69,10 @@
+ **     Low PCI traffic for command handling when on-chip RAM is present.
+ **     Aggressive SCSI SCRIPTS optimizations.
+ **
++**  2005 by Matthew Wilcox and James Bottomley
++**     PCI-ectomy.  This driver now supports only the 720 chip (see the
++**     NCR_Q720 and zalon drivers for the bus probe logic).
++**
+ *******************************************************************************
+ */
+ 
+@@ -90,13 +94,6 @@
+ 
+ #define SCSI_NCR_DEBUG_FLAGS	(0)
+ 
+-/*==========================================================
+-**
+-**      Include files
+-**
+-**==========================================================
+-*/
+-
+ #include <linux/blkdev.h>
+ #include <linux/delay.h>
+ #include <linux/dma-mapping.h>
+@@ -121,6 +118,7 @@
+ 
+ #include <scsi/scsi.h>
+ #include <scsi/scsi_cmnd.h>
++#include <scsi/scsi_dbg.h>
+ #include <scsi/scsi_device.h>
+ #include <scsi/scsi_tcq.h>
+ #include <scsi/scsi_transport.h>
+@@ -128,10 +126,740 @@
+ 
+ #include "ncr53c8xx.h"
+ 
+-#define NAME53C			"ncr53c"
+ #define NAME53C8XX		"ncr53c8xx"
+ 
+-#include "sym53c8xx_comm.h"
++/*==========================================================
++**
++**	Debugging tags
++**
++**==========================================================
++*/
++
++#define DEBUG_ALLOC    (0x0001)
++#define DEBUG_PHASE    (0x0002)
++#define DEBUG_QUEUE    (0x0008)
++#define DEBUG_RESULT   (0x0010)
++#define DEBUG_POINTER  (0x0020)
++#define DEBUG_SCRIPT   (0x0040)
++#define DEBUG_TINY     (0x0080)
++#define DEBUG_TIMING   (0x0100)
++#define DEBUG_NEGO     (0x0200)
++#define DEBUG_TAGS     (0x0400)
++#define DEBUG_SCATTER  (0x0800)
++#define DEBUG_IC        (0x1000)
++
++/*
++**    Enable/Disable debug messages.
++**    Can be changed at runtime too.
++*/
++
++#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
++static int ncr_debug = SCSI_NCR_DEBUG_FLAGS;
++	#define DEBUG_FLAGS ncr_debug
++#else
++	#define DEBUG_FLAGS	SCSI_NCR_DEBUG_FLAGS
++#endif
++
++static inline struct list_head *ncr_list_pop(struct list_head *head)
++{
++	if (!list_empty(head)) {
++		struct list_head *elem = head->next;
++
++		list_del(elem);
++		return elem;
++	}
++
++	return NULL;
++}
++
++/*==========================================================
++**
++**	Simple power of two buddy-like allocator.
++**
++**	This simple code is not intended to be fast, but to 
++**	provide power of 2 aligned memory allocations.
++**	Since the SCRIPTS processor only supplies 8 bit 
++**	arithmetic, this allocator allows simple and fast 
++**	address calculations  from the SCRIPTS code.
++**	In addition, cache line alignment is guaranteed for 
++**	power of 2 cache line size.
++**	Enhanced in linux-2.3.44 to provide a memory pool 
++**	per pcidev to support dynamic dma mapping. (I would 
++**	have preferred a real bus astraction, btw).
++**
++**==========================================================
++*/
++
++#define MEMO_SHIFT	4	/* 16 bytes minimum memory chunk */
++#if PAGE_SIZE >= 8192
++#define MEMO_PAGE_ORDER	0	/* 1 PAGE  maximum */
++#else
++#define MEMO_PAGE_ORDER	1	/* 2 PAGES maximum */
++#endif
++#define MEMO_FREE_UNUSED	/* Free unused pages immediately */
++#define MEMO_WARN	1
++#define MEMO_GFP_FLAGS	GFP_ATOMIC
++#define MEMO_CLUSTER_SHIFT	(PAGE_SHIFT+MEMO_PAGE_ORDER)
++#define MEMO_CLUSTER_SIZE	(1UL << MEMO_CLUSTER_SHIFT)
++#define MEMO_CLUSTER_MASK	(MEMO_CLUSTER_SIZE-1)
++
++typedef u_long m_addr_t;	/* Enough bits to bit-hack addresses */
++typedef struct device *m_bush_t;	/* Something that addresses DMAable */
++
++typedef struct m_link {		/* Link between free memory chunks */
++	struct m_link *next;
++} m_link_s;
++
++typedef struct m_vtob {		/* Virtual to Bus address translation */
++	struct m_vtob *next;
++	m_addr_t vaddr;
++	m_addr_t baddr;
++} m_vtob_s;
++#define VTOB_HASH_SHIFT		5
++#define VTOB_HASH_SIZE		(1UL << VTOB_HASH_SHIFT)
++#define VTOB_HASH_MASK		(VTOB_HASH_SIZE-1)
++#define VTOB_HASH_CODE(m)	\
++	((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK)
++
++typedef struct m_pool {		/* Memory pool of a given kind */
++	m_bush_t bush;
++	m_addr_t (*getp)(struct m_pool *);
++	void (*freep)(struct m_pool *, m_addr_t);
++	int nump;
++	m_vtob_s *(vtob[VTOB_HASH_SIZE]);
++	struct m_pool *next;
++	struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1];
++} m_pool_s;
++
++static void *___m_alloc(m_pool_s *mp, int size)
++{
++	int i = 0;
++	int s = (1 << MEMO_SHIFT);
++	int j;
++	m_addr_t a;
++	m_link_s *h = mp->h;
++
++	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
++		return NULL;
++
++	while (size > s) {
++		s <<= 1;
++		++i;
++	}
++
++	j = i;
++	while (!h[j].next) {
++		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
++			h[j].next = (m_link_s *)mp->getp(mp);
++			if (h[j].next)
++				h[j].next->next = NULL;
++			break;
++		}
++		++j;
++		s <<= 1;
++	}
++	a = (m_addr_t) h[j].next;
++	if (a) {
++		h[j].next = h[j].next->next;
++		while (j > i) {
++			j -= 1;
++			s >>= 1;
++			h[j].next = (m_link_s *) (a+s);
++			h[j].next->next = NULL;
++		}
++	}
++#ifdef DEBUG
++	printk("___m_alloc(%d) = %p\n", size, (void *) a);
++#endif
++	return (void *) a;
++}
++
++static void ___m_free(m_pool_s *mp, void *ptr, int size)
++{
++	int i = 0;
++	int s = (1 << MEMO_SHIFT);
++	m_link_s *q;
++	m_addr_t a, b;
++	m_link_s *h = mp->h;
++
++#ifdef DEBUG
++	printk("___m_free(%p, %d)\n", ptr, size);
++#endif
++
++	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
++		return;
++
++	while (size > s) {
++		s <<= 1;
++		++i;
++	}
++
++	a = (m_addr_t) ptr;
++
++	while (1) {
++#ifdef MEMO_FREE_UNUSED
++		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
++			mp->freep(mp, a);
++			break;
++		}
++#endif
++		b = a ^ s;
++		q = &h[i];
++		while (q->next && q->next != (m_link_s *) b) {
++			q = q->next;
++		}
++		if (!q->next) {
++			((m_link_s *) a)->next = h[i].next;
++			h[i].next = (m_link_s *) a;
++			break;
++		}
++		q->next = q->next->next;
++		a = a & b;
++		s <<= 1;
++		++i;
++	}
++}
++
++static DEFINE_SPINLOCK(ncr53c8xx_lock);
++
++static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags)
++{
++	void *p;
++
++	p = ___m_alloc(mp, size);
++
++	if (DEBUG_FLAGS & DEBUG_ALLOC)
++		printk ("new %-10s[%4d] @%p.\n", name, size, p);
++
++	if (p)
++		memset(p, 0, size);
++	else if (uflags & MEMO_WARN)
++		printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size);
++
++	return p;
++}
++
++#define __m_calloc(mp, s, n)	__m_calloc2(mp, s, n, MEMO_WARN)
++
++static void __m_free(m_pool_s *mp, void *ptr, int size, char *name)
++{
++	if (DEBUG_FLAGS & DEBUG_ALLOC)
++		printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr);
++
++	___m_free(mp, ptr, size);
++
++}
++
++/*
++ * With pci bus iommu support, we use a default pool of unmapped memory 
++ * for memory we donnot need to DMA from/to and one pool per pcidev for 
++ * memory accessed by the PCI chip. `mp0' is the default not DMAable pool.
++ */
++
++static m_addr_t ___mp0_getp(m_pool_s *mp)
++{
++	m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER);
++	if (m)
++		++mp->nump;
++	return m;
++}
++
++static void ___mp0_freep(m_pool_s *mp, m_addr_t m)
++{
++	free_pages(m, MEMO_PAGE_ORDER);
++	--mp->nump;
++}
++
++static m_pool_s mp0 = {NULL, ___mp0_getp, ___mp0_freep};
++
++/*
++ * DMAable pools.
++ */
++
++/*
++ * With pci bus iommu support, we maintain one pool per pcidev and a 
++ * hashed reverse table for virtual to bus physical address translations.
++ */
++static m_addr_t ___dma_getp(m_pool_s *mp)
++{
++	m_addr_t vp;
++	m_vtob_s *vbp;
++
++	vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");
++	if (vbp) {
++		dma_addr_t daddr;
++		vp = (m_addr_t) dma_alloc_coherent(mp->bush,
++						PAGE_SIZE<<MEMO_PAGE_ORDER,
++						&daddr, GFP_ATOMIC);
++		if (vp) {
++			int hc = VTOB_HASH_CODE(vp);
++			vbp->vaddr = vp;
++			vbp->baddr = daddr;
++			vbp->next = mp->vtob[hc];
++			mp->vtob[hc] = vbp;
++			++mp->nump;
++			return vp;
++		}
++	}
++	if (vbp)
++		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
++	return 0;
++}
++
++static void ___dma_freep(m_pool_s *mp, m_addr_t m)
++{
++	m_vtob_s **vbpp, *vbp;
++	int hc = VTOB_HASH_CODE(m);
++
++	vbpp = &mp->vtob[hc];
++	while (*vbpp && (*vbpp)->vaddr != m)
++		vbpp = &(*vbpp)->next;
++	if (*vbpp) {
++		vbp = *vbpp;
++		*vbpp = (*vbpp)->next;
++		dma_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
++				  (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
++		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
++		--mp->nump;
++	}
++}
++
++static inline m_pool_s *___get_dma_pool(m_bush_t bush)
++{
++	m_pool_s *mp;
++	for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next);
++	return mp;
++}
++
++static m_pool_s *___cre_dma_pool(m_bush_t bush)
++{
++	m_pool_s *mp;
++	mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL");
++	if (mp) {
++		memset(mp, 0, sizeof(*mp));
++		mp->bush = bush;
++		mp->getp = ___dma_getp;
++		mp->freep = ___dma_freep;
++		mp->next = mp0.next;
++		mp0.next = mp;
++	}
++	return mp;
++}
++
++static void ___del_dma_pool(m_pool_s *p)
++{
++	struct m_pool **pp = &mp0.next;
++
++	while (*pp && *pp != p)
++		pp = &(*pp)->next;
++	if (*pp) {
++		*pp = (*pp)->next;
++		__m_free(&mp0, p, sizeof(*p), "MPOOL");
++	}
++}
++
++static void *__m_calloc_dma(m_bush_t bush, int size, char *name)
++{
++	u_long flags;
++	struct m_pool *mp;
++	void *m = NULL;
++
++	spin_lock_irqsave(&ncr53c8xx_lock, flags);
++	mp = ___get_dma_pool(bush);
++	if (!mp)
++		mp = ___cre_dma_pool(bush);
++	if (mp)
++		m = __m_calloc(mp, size, name);
++	if (mp && !mp->nump)
++		___del_dma_pool(mp);
++	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
++
++	return m;
++}
++
++static void __m_free_dma(m_bush_t bush, void *m, int size, char *name)
++{
++	u_long flags;
++	struct m_pool *mp;
++
++	spin_lock_irqsave(&ncr53c8xx_lock, flags);
++	mp = ___get_dma_pool(bush);
++	if (mp)
++		__m_free(mp, m, size, name);
++	if (mp && !mp->nump)
++		___del_dma_pool(mp);
++	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
++}
++
++static m_addr_t __vtobus(m_bush_t bush, void *m)
++{
++	u_long flags;
++	m_pool_s *mp;
++	int hc = VTOB_HASH_CODE(m);
++	m_vtob_s *vp = NULL;
++	m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK;
++
++	spin_lock_irqsave(&ncr53c8xx_lock, flags);
++	mp = ___get_dma_pool(bush);
++	if (mp) {
++		vp = mp->vtob[hc];
++		while (vp && (m_addr_t) vp->vaddr != a)
++			vp = vp->next;
++	}
++	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
++	return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;
++}
++
++#define _m_calloc_dma(np, s, n)		__m_calloc_dma(np->dev, s, n)
++#define _m_free_dma(np, p, s, n)	__m_free_dma(np->dev, p, s, n)
++#define m_calloc_dma(s, n)		_m_calloc_dma(np, s, n)
++#define m_free_dma(p, s, n)		_m_free_dma(np, p, s, n)
++#define _vtobus(np, p)			__vtobus(np->dev, p)
++#define vtobus(p)			_vtobus(np, p)
++
++/*
++ *  Deal with DMA mapping/unmapping.
++ */
++
++/* To keep track of the dma mapping (sg/single) that has been set */
++#define __data_mapped	SCp.phase
++#define __data_mapping	SCp.have_data_in
++
++static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd)
++{
++	switch(cmd->__data_mapped) {
++	case 2:
++		dma_unmap_sg(dev, cmd->buffer, cmd->use_sg,
++				cmd->sc_data_direction);
++		break;
++	case 1:
++		dma_unmap_single(dev, cmd->__data_mapping,
++				 cmd->request_bufflen,
++				 cmd->sc_data_direction);
++		break;
++	}
++	cmd->__data_mapped = 0;
++}
++
++static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd)
++{
++	dma_addr_t mapping;
++
++	if (cmd->request_bufflen == 0)
++		return 0;
++
++	mapping = dma_map_single(dev, cmd->request_buffer,
++				 cmd->request_bufflen,
++				 cmd->sc_data_direction);
++	cmd->__data_mapped = 1;
++	cmd->__data_mapping = mapping;
++
++	return mapping;
++}
++
++static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
++{
++	int use_sg;
++
++	if (cmd->use_sg == 0)
++		return 0;
++
++	use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg,
++			cmd->sc_data_direction);
++	cmd->__data_mapped = 2;
++	cmd->__data_mapping = use_sg;
++
++	return use_sg;
++}
++
++#define unmap_scsi_data(np, cmd)	__unmap_scsi_data(np->dev, cmd)
++#define map_scsi_single_data(np, cmd)	__map_scsi_single_data(np->dev, cmd)
++#define map_scsi_sg_data(np, cmd)	__map_scsi_sg_data(np->dev, cmd)
++
++/*==========================================================
++**
++**	Driver setup.
++**
++**	This structure is initialized from linux config 
++**	options. It can be overridden at boot-up by the boot 
++**	command line.
++**
++**==========================================================
++*/
++static struct ncr_driver_setup
++	driver_setup			= SCSI_NCR_DRIVER_SETUP;
++
++#ifdef	SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
++static struct ncr_driver_setup
++	driver_safe_setup __initdata	= SCSI_NCR_DRIVER_SAFE_SETUP;
++#endif
++
++#define initverbose (driver_setup.verbose)
++#define bootverbose (np->verbose)
++
++
++/*===================================================================
++**
++**	Driver setup from the boot command line
++**
++**===================================================================
++*/
++
++#ifdef MODULE
++#define	ARG_SEP	' '
++#else
++#define	ARG_SEP	','
++#endif
++
++#define OPT_TAGS		1
++#define OPT_MASTER_PARITY	2
++#define OPT_SCSI_PARITY		3
++#define OPT_DISCONNECTION	4
++#define OPT_SPECIAL_FEATURES	5
++#define OPT_UNUSED_1		6
++#define OPT_FORCE_SYNC_NEGO	7
++#define OPT_REVERSE_PROBE	8
++#define OPT_DEFAULT_SYNC	9
++#define OPT_VERBOSE		10
++#define OPT_DEBUG		11
++#define OPT_BURST_MAX		12
++#define OPT_LED_PIN		13
++#define OPT_MAX_WIDE		14
++#define OPT_SETTLE_DELAY	15
++#define OPT_DIFF_SUPPORT	16
++#define OPT_IRQM		17
++#define OPT_PCI_FIX_UP		18
++#define OPT_BUS_CHECK		19
++#define OPT_OPTIMIZE		20
++#define OPT_RECOVERY		21
++#define OPT_SAFE_SETUP		22
++#define OPT_USE_NVRAM		23
++#define OPT_EXCLUDE		24
++#define OPT_HOST_ID		25
++
++#ifdef SCSI_NCR_IARB_SUPPORT
++#define OPT_IARB		26
++#endif
++
++static char setup_token[] __initdata = 
++	"tags:"   "mpar:"
++	"spar:"   "disc:"
++	"specf:"  "ultra:"
++	"fsn:"    "revprob:"
++	"sync:"   "verb:"
++	"debug:"  "burst:"
++	"led:"    "wide:"
++	"settle:" "diff:"
++	"irqm:"   "pcifix:"
++	"buschk:" "optim:"
++	"recovery:"
++	"safe:"   "nvram:"
++	"excl:"   "hostid:"
++#ifdef SCSI_NCR_IARB_SUPPORT
++	"iarb:"
++#endif
++	;	/* DONNOT REMOVE THIS ';' */
++
++#ifdef MODULE
++#define	ARG_SEP	' '
++#else
++#define	ARG_SEP	','
++#endif
++
++static int __init get_setup_token(char *p)
++{
++	char *cur = setup_token;
++	char *pc;
++	int i = 0;
++
++	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
++		++pc;
++		++i;
++		if (!strncmp(p, cur, pc - cur))
++			return i;
++		cur = pc;
++	}
++	return 0;
++}
++
++
++static int __init sym53c8xx__setup(char *str)
++{
++#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
++	char *cur = str;
++	char *pc, *pv;
++	int i, val, c;
++	int xi = 0;
++
++	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
++		char *pe;
++
++		val = 0;
++		pv = pc;
++		c = *++pv;
++
++		if	(c == 'n')
++			val = 0;
++		else if	(c == 'y')
++			val = 1;
++		else
++			val = (int) simple_strtoul(pv, &pe, 0);
++
++		switch (get_setup_token(cur)) {
++		case OPT_TAGS:
++			driver_setup.default_tags = val;
++			if (pe && *pe == '/') {
++				i = 0;
++				while (*pe && *pe != ARG_SEP && 
++					i < sizeof(driver_setup.tag_ctrl)-1) {
++					driver_setup.tag_ctrl[i++] = *pe++;
++				}
++				driver_setup.tag_ctrl[i] = '\0';
++			}
++			break;
++		case OPT_MASTER_PARITY:
++			driver_setup.master_parity = val;
++			break;
++		case OPT_SCSI_PARITY:
++			driver_setup.scsi_parity = val;
++			break;
++		case OPT_DISCONNECTION:
++			driver_setup.disconnection = val;
++			break;
++		case OPT_SPECIAL_FEATURES:
++			driver_setup.special_features = val;
++			break;
++		case OPT_FORCE_SYNC_NEGO:
++			driver_setup.force_sync_nego = val;
++			break;
++		case OPT_REVERSE_PROBE:
++			driver_setup.reverse_probe = val;
++			break;
++		case OPT_DEFAULT_SYNC:
++			driver_setup.default_sync = val;
++			break;
++		case OPT_VERBOSE:
++			driver_setup.verbose = val;
++			break;
++		case OPT_DEBUG:
++			driver_setup.debug = val;
++			break;
++		case OPT_BURST_MAX:
++			driver_setup.burst_max = val;
++			break;
++		case OPT_LED_PIN:
++			driver_setup.led_pin = val;
++			break;
++		case OPT_MAX_WIDE:
++			driver_setup.max_wide = val? 1:0;
++			break;
++		case OPT_SETTLE_DELAY:
++			driver_setup.settle_delay = val;
++			break;
++		case OPT_DIFF_SUPPORT:
++			driver_setup.diff_support = val;
++			break;
++		case OPT_IRQM:
++			driver_setup.irqm = val;
++			break;
++		case OPT_PCI_FIX_UP:
++			driver_setup.pci_fix_up	= val;
++			break;
++		case OPT_BUS_CHECK:
++			driver_setup.bus_check = val;
++			break;
++		case OPT_OPTIMIZE:
++			driver_setup.optimize = val;
++			break;
++		case OPT_RECOVERY:
++			driver_setup.recovery = val;
++			break;
++		case OPT_USE_NVRAM:
++			driver_setup.use_nvram = val;
++			break;
++		case OPT_SAFE_SETUP:
++			memcpy(&driver_setup, &driver_safe_setup,
++				sizeof(driver_setup));
++			break;
++		case OPT_EXCLUDE:
++			if (xi < SCSI_NCR_MAX_EXCLUDES)
++				driver_setup.excludes[xi++] = val;
++			break;
++		case OPT_HOST_ID:
++			driver_setup.host_id = val;
++			break;
++#ifdef SCSI_NCR_IARB_SUPPORT
++		case OPT_IARB:
++			driver_setup.iarb = val;
++			break;
++#endif
++		default:
++			printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
++			break;
++		}
++
++		if ((cur = strchr(cur, ARG_SEP)) != NULL)
++			++cur;
++	}
++#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */
++	return 1;
++}
++
++/*===================================================================
++**
++**	Get device queue depth from boot command line.
++**
++**===================================================================
++*/
++#define DEF_DEPTH	(driver_setup.default_tags)
++#define ALL_TARGETS	-2
++#define NO_TARGET	-1
++#define ALL_LUNS	-2
++#define NO_LUN		-1
++
++static int device_queue_depth(int unit, int target, int lun)
++{
++	int c, h, t, u, v;
++	char *p = driver_setup.tag_ctrl;
++	char *ep;
++
++	h = -1;
++	t = NO_TARGET;
++	u = NO_LUN;
++	while ((c = *p++) != 0) {
++		v = simple_strtoul(p, &ep, 0);
++		switch(c) {
++		case '/':
++			++h;
++			t = ALL_TARGETS;
++			u = ALL_LUNS;
++			break;
++		case 't':
++			if (t != target)
++				t = (target == v) ? v : NO_TARGET;
++			u = ALL_LUNS;
++			break;
++		case 'u':
++			if (u != lun)
++				u = (lun == v) ? v : NO_LUN;
++			break;
++		case 'q':
++			if (h == unit &&
++				(t == ALL_TARGETS || t == target) &&
++				(u == ALL_LUNS    || u == lun))
++				return v;
++			break;
++		case '-':
++			t = ALL_TARGETS;
++			u = ALL_LUNS;
++			break;
++		default:
++			break;
++		}
++		p = ep;
++	}
++	return DEF_DEPTH;
++}
+ 
+ 
+ /*==========================================================
+@@ -1379,7 +2107,7 @@
+ 	*/
+ 
+ 	/*
+-	**	The M_REJECT problem seems to be due to a selection 
++	**	The MESSAGE_REJECT problem seems to be due to a selection 
+ 	**	timing problem.
+ 	**	Wait immediately for the selection to complete. 
+ 	**	(2.5x behaves so)
+@@ -1430,7 +2158,7 @@
+ 	/*
+ 	**	Selection complete.
+ 	**	Send the IDENTIFY and SIMPLE_TAG messages
+-	**	(and the M_X_SYNC_REQ message)
++	**	(and the EXTENDED_SDTR message)
+ 	*/
+ 	SCR_MOVE_TBL ^ SCR_MSG_OUT,
+ 		offsetof (struct dsb, smsg),
+@@ -1459,7 +2187,7 @@
+ 	/*
+ 	**	Initialize the msgout buffer with a NOOP message.
+ 	*/
+-	SCR_LOAD_REG (scratcha, M_NOOP),
++	SCR_LOAD_REG (scratcha, NOP),
+ 		0,
+ 	SCR_COPY (1),
+ 		RADDR (scratcha),
+@@ -1611,21 +2339,21 @@
+ 	/*
+ 	**	Handle this message.
+ 	*/
+-	SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)),
++	SCR_JUMP ^ IFTRUE (DATA (COMMAND_COMPLETE)),
+ 		PADDR (complete),
+-	SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)),
++	SCR_JUMP ^ IFTRUE (DATA (DISCONNECT)),
+ 		PADDR (disconnect),
+-	SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)),
++	SCR_JUMP ^ IFTRUE (DATA (SAVE_POINTERS)),
+ 		PADDR (save_dp),
+-	SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)),
++	SCR_JUMP ^ IFTRUE (DATA (RESTORE_POINTERS)),
+ 		PADDR (restore_dp),
+-	SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)),
++	SCR_JUMP ^ IFTRUE (DATA (EXTENDED_MESSAGE)),
+ 		PADDRH (msg_extended),
+-	SCR_JUMP ^ IFTRUE (DATA (M_NOOP)),
++	SCR_JUMP ^ IFTRUE (DATA (NOP)),
+ 		PADDR (clrack),
+-	SCR_JUMP ^ IFTRUE (DATA (M_REJECT)),
++	SCR_JUMP ^ IFTRUE (DATA (MESSAGE_REJECT)),
+ 		PADDRH (msg_reject),
+-	SCR_JUMP ^ IFTRUE (DATA (M_IGN_RESIDUE)),
++	SCR_JUMP ^ IFTRUE (DATA (IGNORE_WIDE_RESIDUE)),
+ 		PADDRH (msg_ign_residue),
+ 	/*
+ 	**	Rest of the messages left as
+@@ -1640,7 +2368,7 @@
+ 	*/
+ 	SCR_INT,
+ 		SIR_REJECT_SENT,
+-	SCR_LOAD_REG (scratcha, M_REJECT),
++	SCR_LOAD_REG (scratcha, MESSAGE_REJECT),
+ 		0,
+ }/*-------------------------< SETMSG >----------------------*/,{
+ 	SCR_COPY (1),
+@@ -1832,7 +2560,7 @@
+ 	/*
+ 	**	If it was no ABORT message ...
+ 	*/
+-	SCR_JUMP ^ IFTRUE (DATA (M_ABORT)),
++	SCR_JUMP ^ IFTRUE (DATA (ABORT_TASK_SET)),
+ 		PADDRH (msg_out_abort),
+ 	/*
+ 	**	... wait for the next phase
+@@ -1844,7 +2572,7 @@
+ 	/*
+ 	**	... else clear the message ...
+ 	*/
+-	SCR_LOAD_REG (scratcha, M_NOOP),
++	SCR_LOAD_REG (scratcha, NOP),
+ 		0,
+ 	SCR_COPY (4),
+ 		RADDR (scratcha),
+@@ -2303,7 +3031,7 @@
+ 	*/
+ 	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
+ 		NADDR (msgin[2]),
+-	SCR_JUMP ^ IFTRUE (DATA (M_X_WIDE_REQ)),
++	SCR_JUMP ^ IFTRUE (DATA (EXTENDED_WDTR)),
+ 		PADDRH (msg_wdtr),
+ 	/*
+ 	**	unknown extended message
+@@ -2337,7 +3065,7 @@
+ 
+ }/*-------------------------< SEND_WDTR >----------------*/,{
+ 	/*
+-	**	Send the M_X_WIDE_REQ
++	**	Send the EXTENDED_WDTR
+ 	*/
+ 	SCR_MOVE_ABS (4) ^ SCR_MSG_OUT,
+ 		NADDR (msgout),
+@@ -2357,7 +3085,7 @@
+ 	*/
+ 	SCR_MOVE_ABS (1) ^ SCR_MSG_IN,
+ 		NADDR (msgin[2]),
+-	SCR_JUMP ^ IFTRUE (DATA (M_X_SYNC_REQ)),
++	SCR_JUMP ^ IFTRUE (DATA (EXTENDED_SDTR)),
+ 		PADDRH (msg_sdtr),
+ 	/*
+ 	**	unknown extended message
+@@ -2392,7 +3120,7 @@
+ 
+ }/*-------------------------< SEND_SDTR >-------------*/,{
+ 	/*
+-	**	Send the M_X_SYNC_REQ
++	**	Send the EXTENDED_SDTR
+ 	*/
+ 	SCR_MOVE_ABS (5) ^ SCR_MSG_OUT,
+ 		NADDR (msgout),
+@@ -2470,10 +3198,10 @@
+ 
+ }/*-------------------------< RESET >----------------------*/,{
+ 	/*
+-	**      Send a M_RESET message if bad IDENTIFY 
++	**      Send a TARGET_RESET message if bad IDENTIFY 
+ 	**	received on reselection.
+ 	*/
+-	SCR_LOAD_REG (scratcha, M_ABORT_TAG),
++	SCR_LOAD_REG (scratcha, ABORT_TASK),
+ 		0,
+ 	SCR_JUMP,
+ 		PADDRH (abort_resel),
+@@ -2481,7 +3209,7 @@
+ 	/*
+ 	**      Abort a wrong tag received on reselection.
+ 	*/
+-	SCR_LOAD_REG (scratcha, M_ABORT_TAG),
++	SCR_LOAD_REG (scratcha, ABORT_TASK),
+ 		0,
+ 	SCR_JUMP,
+ 		PADDRH (abort_resel),
+@@ -2489,7 +3217,7 @@
+ 	/*
+ 	**      Abort a reselection when no active CCB.
+ 	*/
+-	SCR_LOAD_REG (scratcha, M_ABORT),
++	SCR_LOAD_REG (scratcha, ABORT_TASK_SET),
+ 		0,
+ }/*-------------------------< ABORT_RESEL >----------------*/,{
+ 	SCR_COPY (1),
+@@ -2601,7 +3329,7 @@
+ 	**	Read the message, since we got it directly 
+ 	**	from the SCSI BUS data lines.
+ 	**	Signal problem to C code for logging the event.
+-	**	Send a M_ABORT to clear all pending tasks.
++	**	Send an ABORT_TASK_SET to clear all pending tasks.
+ 	*/
+ 	SCR_INT,
+ 		SIR_RESEL_BAD_LUN,
+@@ -2613,7 +3341,7 @@
+ 	/*
+ 	**	We donnot have a task for that I_T_L.
+ 	**	Signal problem to C code for logging the event.
+-	**	Send a M_ABORT message.
++	**	Send an ABORT_TASK_SET message.
+ 	*/
+ 	SCR_INT,
+ 		SIR_RESEL_BAD_I_T_L,
+@@ -2623,7 +3351,7 @@
+ 	/*
+ 	**	We donnot have a task that matches the tag.
+ 	**	Signal problem to C code for logging the event.
+-	**	Send a M_ABORTTAG message.
++	**	Send an ABORT_TASK message.
+ 	*/
+ 	SCR_INT,
+ 		SIR_RESEL_BAD_I_T_L_Q,
+@@ -2634,7 +3362,7 @@
+ 	**	We donnot know the target that reselected us.
+ 	**	Grab the first message if any (IDENTIFY).
+ 	**	Signal problem to C code for logging the event.
+-	**	M_RESET message.
++	**	TARGET_RESET message.
+ 	*/
+ 	SCR_INT,
+ 		SIR_RESEL_BAD_TARGET,
+@@ -2971,21 +3699,10 @@
+ 
+ static void ncr_print_msg(struct ccb *cp, char *label, u_char *msg)
+ {
+-	int i;
+ 	PRINT_ADDR(cp->cmd, "%s: ", label);
+ 
+-	printk ("%x",*msg);
+-	if (*msg == M_EXTENDED) {
+-		for (i = 1; i < 8; i++) {
+-			if (i - 1 > msg[1])
+-				break;
+-			printk ("-%x",msg[i]);
+-		}
+-	} else if ((*msg & 0xf0) == 0x20) {
+-		printk ("-%x",msg[1]);
+-	}
+-
+-	printk(".\n");
++	scsi_print_msg(msg);
++	printk("\n");
+ }
+ 
+ /*==========================================================
+@@ -3388,16 +4105,16 @@
+ 
+ 	switch (nego) {
+ 	case NS_SYNC:
+-		msgptr[msglen++] = M_EXTENDED;
++		msgptr[msglen++] = EXTENDED_MESSAGE;
+ 		msgptr[msglen++] = 3;
+-		msgptr[msglen++] = M_X_SYNC_REQ;
++		msgptr[msglen++] = EXTENDED_SDTR;
+ 		msgptr[msglen++] = tp->maxoffs ? tp->minsync : 0;
+ 		msgptr[msglen++] = tp->maxoffs;
+ 		break;
+ 	case NS_WIDE:
+-		msgptr[msglen++] = M_EXTENDED;
++		msgptr[msglen++] = EXTENDED_MESSAGE;
+ 		msgptr[msglen++] = 2;
+-		msgptr[msglen++] = M_X_WIDE_REQ;
++		msgptr[msglen++] = EXTENDED_WDTR;
+ 		msgptr[msglen++] = tp->usrwide;
+ 		break;
+ 	}
+@@ -3499,7 +4216,7 @@
+ 	**----------------------------------------------------
+ 	*/
+ 
+-	idmsg = M_IDENTIFY | sdev->lun;
++	idmsg = IDENTIFY(0, sdev->lun);
+ 
+ 	if (cp ->tag != NO_TAG ||
+ 		(cp != np->ccb && np->disc && !(tp->usrflag & UF_NODISC)))
+@@ -3518,7 +4235,7 @@
+ 		*/
+ 		if (lp && time_after(jiffies, lp->tags_stime)) {
+ 			if (lp->tags_smap) {
+-				order = M_ORDERED_TAG;
++				order = ORDERED_QUEUE_TAG;
+ 				if ((DEBUG_FLAGS & DEBUG_TAGS)||bootverbose>2){ 
+ 					PRINT_ADDR(cmd,
+ 						"ordered tag forced.\n");
+@@ -3536,10 +4253,10 @@
+ 			case 0x08:  /* READ_SMALL (6) */
+ 			case 0x28:  /* READ_BIG  (10) */
+ 			case 0xa8:  /* READ_HUGE (12) */
+-				order = M_SIMPLE_TAG;
++				order = SIMPLE_QUEUE_TAG;
+ 				break;
+ 			default:
+-				order = M_ORDERED_TAG;
++				order = ORDERED_QUEUE_TAG;
+ 			}
+ 		}
+ 		msgptr[msglen++] = order;
+@@ -5508,9 +6225,9 @@
+ 	if (!(dbc & 0xc0000000))
+ 		phase = (dbc >> 24) & 7;
+ 	if (phase == 7)
+-		msg = M_PARITY;
++		msg = MSG_PARITY_ERROR;
+ 	else
+-		msg = M_ID_ERROR;
++		msg = INITIATOR_ERROR;
+ 
+ 
+ 	/*
+@@ -6074,6 +6791,8 @@
+ /*-----------------------------------------------------------------------------
+ **
+ **	Was Sie schon immer ueber transfermode negotiation wissen wollten ...
++**	("Everything you've always wanted to know about transfer mode
++**	  negotiation")
+ **
+ **	We try to negotiate sync and wide transfer only after
+ **	a successful inquire command. We look at byte 7 of the
+@@ -6175,8 +6894,8 @@
+ 			break;
+ 
+ 		}
+-		np->msgin [0] = M_NOOP;
+-		np->msgout[0] = M_NOOP;
++		np->msgin [0] = NOP;
++		np->msgout[0] = NOP;
+ 		cp->nego_status = 0;
+ 		break;
+ 
+@@ -6270,9 +6989,9 @@
+ 		spi_offset(starget) = ofs;
+ 		ncr_setsync(np, cp, scntl3, (fak<<5)|ofs);
+ 
+-		np->msgout[0] = M_EXTENDED;
++		np->msgout[0] = EXTENDED_MESSAGE;
+ 		np->msgout[1] = 3;
+-		np->msgout[2] = M_X_SYNC_REQ;
++		np->msgout[2] = EXTENDED_SDTR;
+ 		np->msgout[3] = per;
+ 		np->msgout[4] = ofs;
+ 
+@@ -6286,7 +7005,7 @@
+ 			OUTL_DSP (NCB_SCRIPT_PHYS (np, msg_bad));
+ 			return;
+ 		}
+-		np->msgin [0] = M_NOOP;
++		np->msgin [0] = NOP;
+ 
+ 		break;
+ 
+@@ -6362,12 +7081,12 @@
+ 		spi_width(starget) = wide;
+ 		ncr_setwide(np, cp, wide, 1);
+ 
+-		np->msgout[0] = M_EXTENDED;
++		np->msgout[0] = EXTENDED_MESSAGE;
+ 		np->msgout[1] = 2;
+-		np->msgout[2] = M_X_WIDE_REQ;
++		np->msgout[2] = EXTENDED_WDTR;
+ 		np->msgout[3] = wide;
+ 
+-		np->msgin [0] = M_NOOP;
++		np->msgin [0] = NOP;
+ 
+ 		cp->nego_status = NS_WIDE;
+ 
+@@ -6386,12 +7105,12 @@
+ 	case SIR_REJECT_RECEIVED:
+ 		/*-----------------------------------------------
+ 		**
+-		**	We received a M_REJECT message.
++		**	We received a MESSAGE_REJECT.
+ 		**
+ 		**-----------------------------------------------
+ 		*/
+ 
+-		PRINT_ADDR(cp->cmd, "M_REJECT received (%x:%x).\n",
++		PRINT_ADDR(cp->cmd, "MESSAGE_REJECT received (%x:%x).\n",
+ 			(unsigned)scr_to_cpu(np->lastmsg), np->msgout[0]);
+ 		break;
+ 
+@@ -6403,7 +7122,7 @@
+ 		**-----------------------------------------------
+ 		*/
+ 
+-		ncr_print_msg(cp, "M_REJECT sent for", np->msgin);
++		ncr_print_msg(cp, "MESSAGE_REJECT sent for", np->msgin);
+ 		break;
+ 
+ /*--------------------------------------------------------------------
+@@ -6422,7 +7141,7 @@
+ 		**-----------------------------------------------
+ 		*/
+ 
+-		PRINT_ADDR(cp->cmd, "M_IGN_RESIDUE received, but not yet "
++		PRINT_ADDR(cp->cmd, "IGNORE_WIDE_RESIDUE received, but not yet "
+ 				"implemented.\n");
+ 		break;
+ #if 0
+@@ -6435,7 +7154,7 @@
+ 		**-----------------------------------------------
+ 		*/
+ 
+-		PRINT_ADDR(cp->cmd, "M_DISCONNECT received, but datapointer "
++		PRINT_ADDR(cp->cmd, "DISCONNECT received, but datapointer "
+ 				"not saved: data=%x save=%x goal=%x.\n",
+ 			(unsigned) INL (nc_temp),
+ 			(unsigned) scr_to_cpu(np->header.savep),
+@@ -7141,7 +7860,7 @@
+ **==========================================================
+ **
+ **	Note: we have to return the correct value.
+-**	THERE IS NO SAVE DEFAULT VALUE.
++**	THERE IS NO SAFE DEFAULT VALUE.
+ **
+ **	Most NCR/SYMBIOS boards are delivered with a 40 Mhz clock.
+ **	53C860 and 53C875 rev. 1 support fast20 transfers but 
+@@ -7841,7 +8560,7 @@
+ 
+ 	/* use SIMPLE TAG messages by default */
+ #ifdef SCSI_NCR_ALWAYS_SIMPLE_TAG
+-	np->order = M_SIMPLE_TAG;
++	np->order = SIMPLE_QUEUE_TAG;
+ #endif
+ 
+ 	spin_unlock_irqrestore(&np->smp_lock, flags);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/ncr53c8xx.h CVS2_6_15_RC7_PA0/drivers/scsi/ncr53c8xx.h
+--- LINUS_2_6_15_RC7/drivers/scsi/ncr53c8xx.h	2005-12-27 13:25:48.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/ncr53c8xx.h	2005-12-12 12:01:54.000000000 -0700
+@@ -36,6 +36,13 @@
+ **  And has been ported to NetBSD by
+ **          Charles M. Hannum           <mycroft at gnu.ai.mit.edu>
+ **
++**  Added support for MIPS big endian systems.
++**    Carsten Langgaard, carstenl at mips.com
++**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
++**
++**  Added support for HP PARISC big endian systems.
++**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
++**
+ *******************************************************************************
+ */
+ 
+@@ -44,7 +51,1225 @@
+ 
+ #include <scsi/scsi_host.h>
+ 
+-#include "sym53c8xx_defs.h"
++#include <linux/config.h>
++
++/*
++**	If you want a driver as small as possible, donnot define the 
++**	following options.
++*/
++#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
++#define SCSI_NCR_DEBUG_INFO_SUPPORT
++
++/*
++**	To disable integrity checking, do not define the 
++**	following option.
++*/
++#ifdef	CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK
++#	define SCSI_NCR_ENABLE_INTEGRITY_CHECK
++#endif
++
++/* ---------------------------------------------------------------------
++** Take into account kernel configured parameters.
++** Most of these options can be overridden at startup by a command line.
++** ---------------------------------------------------------------------
++*/
++
++/*
++ * For Ultra2 and Ultra3 SCSI support option, use special features. 
++ *
++ * Value (default) means:
++ *	bit 0 : all features enabled, except:
++ *		bit 1 : PCI Write And Invalidate.
++ *		bit 2 : Data Phase Mismatch handling from SCRIPTS.
++ *
++ * Use boot options ncr53c8xx=specf:1 if you want all chip features to be 
++ * enabled by the driver.
++ */
++#define	SCSI_NCR_SETUP_SPECIAL_FEATURES		(3)
++
++#define SCSI_NCR_MAX_SYNC			(80)
++
++/*
++ * Allow tags from 2 to 256, default 8
++ */
++#ifdef	CONFIG_SCSI_NCR53C8XX_MAX_TAGS
++#if	CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2
++#define SCSI_NCR_MAX_TAGS	(2)
++#elif	CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256
++#define SCSI_NCR_MAX_TAGS	(256)
++#else
++#define	SCSI_NCR_MAX_TAGS	CONFIG_SCSI_NCR53C8XX_MAX_TAGS
++#endif
++#else
++#define SCSI_NCR_MAX_TAGS	(8)
++#endif
++
++/*
++ * Allow tagged command queuing support if configured with default number 
++ * of tags set to max (see above).
++ */
++#ifdef	CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
++#define	SCSI_NCR_SETUP_DEFAULT_TAGS	CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
++#elif	defined CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE
++#define	SCSI_NCR_SETUP_DEFAULT_TAGS	SCSI_NCR_MAX_TAGS
++#else
++#define	SCSI_NCR_SETUP_DEFAULT_TAGS	(0)
++#endif
++
++/*
++ * Immediate arbitration
++ */
++#if defined(CONFIG_SCSI_NCR53C8XX_IARB)
++#define SCSI_NCR_IARB_SUPPORT
++#endif
++
++/*
++ * Sync transfer frequency at startup.
++ * Allow from 5Mhz to 80Mhz default 20 Mhz.
++ */
++#ifndef	CONFIG_SCSI_NCR53C8XX_SYNC
++#define	CONFIG_SCSI_NCR53C8XX_SYNC	(20)
++#elif	CONFIG_SCSI_NCR53C8XX_SYNC > SCSI_NCR_MAX_SYNC
++#undef	CONFIG_SCSI_NCR53C8XX_SYNC
++#define	CONFIG_SCSI_NCR53C8XX_SYNC	SCSI_NCR_MAX_SYNC
++#endif
++
++#if	CONFIG_SCSI_NCR53C8XX_SYNC == 0
++#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(255)
++#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 5
++#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(50)
++#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 20
++#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(250/(CONFIG_SCSI_NCR53C8XX_SYNC))
++#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 33
++#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(11)
++#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 40
++#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(10)
++#else
++#define	SCSI_NCR_SETUP_DEFAULT_SYNC 	(9)
++#endif
++
++/*
++ * Disallow disconnections at boot-up
++ */
++#ifdef CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
++#define SCSI_NCR_SETUP_DISCONNECTION	(0)
++#else
++#define SCSI_NCR_SETUP_DISCONNECTION	(1)
++#endif
++
++/*
++ * Force synchronous negotiation for all targets
++ */
++#ifdef CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO
++#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO	(1)
++#else
++#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO	(0)
++#endif
++
++/*
++ * Disable master parity checking (flawed hardwares need that)
++ */
++#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK
++#define SCSI_NCR_SETUP_MASTER_PARITY	(0)
++#else
++#define SCSI_NCR_SETUP_MASTER_PARITY	(1)
++#endif
++
++/*
++ * Disable scsi parity checking (flawed devices may need that)
++ */
++#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK
++#define SCSI_NCR_SETUP_SCSI_PARITY	(0)
++#else
++#define SCSI_NCR_SETUP_SCSI_PARITY	(1)
++#endif
++
++/*
++ * Settle time after reset at boot-up
++ */
++#define SCSI_NCR_SETUP_SETTLE_TIME	(2)
++
++/*
++**	Bridge quirks work-around option defaulted to 1.
++*/
++#ifndef	SCSI_NCR_PCIQ_WORK_AROUND_OPT
++#define	SCSI_NCR_PCIQ_WORK_AROUND_OPT	1
++#endif
++
++/*
++**	Work-around common bridge misbehaviour.
++**
++**	- Do not flush posted writes in the opposite 
++**	  direction on read.
++**	- May reorder DMA writes to memory.
++**
++**	This option should not affect performances 
++**	significantly, so it is the default.
++*/
++#if	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1
++#define	SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
++#define	SCSI_NCR_PCIQ_MAY_REORDER_WRITES
++#define	SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
++
++/*
++**	Same as option 1, but also deal with 
++**	misconfigured interrupts.
++**
++**	- Edge triggerred instead of level sensitive.
++**	- No interrupt line connected.
++**	- IRQ number misconfigured.
++**	
++**	If no interrupt is delivered, the driver will 
++**	catch the interrupt conditions 10 times per 
++**	second. No need to say that this option is 
++**	not recommended.
++*/
++#elif	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2
++#define	SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
++#define	SCSI_NCR_PCIQ_MAY_REORDER_WRITES
++#define	SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
++#define	SCSI_NCR_PCIQ_BROKEN_INTR
++
++/*
++**	Some bridge designers decided to flush 
++**	everything prior to deliver the interrupt.
++**	This option tries to deal with such a 
++**	behaviour.
++*/
++#elif	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3
++#define	SCSI_NCR_PCIQ_SYNC_ON_INTR
++#endif
++
++/*
++**	Other parameters not configurable with "make config"
++**	Avoid to change these constants, unless you know what you are doing.
++*/
++
++#define SCSI_NCR_ALWAYS_SIMPLE_TAG
++#define SCSI_NCR_MAX_SCATTER	(127)
++#define SCSI_NCR_MAX_TARGET	(16)
++
++/*
++**   Compute some desirable value for CAN_QUEUE 
++**   and CMD_PER_LUN.
++**   The driver will use lower values if these 
++**   ones appear to be too large.
++*/
++#define SCSI_NCR_CAN_QUEUE	(8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET)
++#define SCSI_NCR_CMD_PER_LUN	(SCSI_NCR_MAX_TAGS)
++
++#define SCSI_NCR_SG_TABLESIZE	(SCSI_NCR_MAX_SCATTER)
++#define SCSI_NCR_TIMER_INTERVAL	(HZ)
++
++#if 1 /* defined CONFIG_SCSI_MULTI_LUN */
++#define SCSI_NCR_MAX_LUN	(16)
++#else
++#define SCSI_NCR_MAX_LUN	(1)
++#endif
++
++/*
++ *  IO functions definition for big/little endian CPU support.
++ *  For now, the NCR is only supported in little endian addressing mode, 
++ */
++
++#ifdef	__BIG_ENDIAN
++
++#define	inw_l2b		inw
++#define	inl_l2b		inl
++#define	outw_b2l	outw
++#define	outl_b2l	outl
++
++#define	readb_raw	readb
++#define	writeb_raw	writeb
++
++#if defined(SCSI_NCR_BIG_ENDIAN)
++#define	readw_l2b	__raw_readw
++#define	readl_l2b	__raw_readl
++#define	writew_b2l	__raw_writew
++#define	writel_b2l	__raw_writel
++#define	readw_raw	__raw_readw
++#define	readl_raw	__raw_readl
++#define	writew_raw	__raw_writew
++#define	writel_raw	__raw_writel
++#else	/* Other big-endian */
++#define	readw_l2b	readw
++#define	readl_l2b	readl
++#define	writew_b2l	writew
++#define	writel_b2l	writel
++#define	readw_raw	readw
++#define	readl_raw	readl
++#define	writew_raw	writew
++#define	writel_raw	writel
++#endif
++
++#else	/* little endian */
++
++#define	inw_raw		inw
++#define	inl_raw		inl
++#define	outw_raw	outw
++#define	outl_raw	outl
++
++#define	readb_raw	readb
++#define	readw_raw	readw
++#define	readl_raw	readl
++#define	writeb_raw	writeb
++#define	writew_raw	writew
++#define	writel_raw	writel
++
++#endif
++
++#if !defined(__hppa__) && !defined(__mips__)
++#ifdef	SCSI_NCR_BIG_ENDIAN
++#error	"The NCR in BIG ENDIAN addressing mode is not (yet) supported"
++#endif
++#endif
++
++#define MEMORY_BARRIER()	mb()
++
++
++/*
++ *  If the NCR uses big endian addressing mode over the 
++ *  PCI, actual io register addresses for byte and word 
++ *  accesses must be changed according to lane routing.
++ *  Btw, ncr_offb() and ncr_offw() macros only apply to 
++ *  constants and so donnot generate bloated code.
++ */
++
++#if	defined(SCSI_NCR_BIG_ENDIAN)
++
++#define ncr_offb(o)	(((o)&~3)+((~((o)&3))&3))
++#define ncr_offw(o)	(((o)&~3)+((~((o)&3))&2))
++
++#else
++
++#define ncr_offb(o)	(o)
++#define ncr_offw(o)	(o)
++
++#endif
++
++/*
++ *  If the CPU and the NCR use same endian-ness addressing,
++ *  no byte reordering is needed for script patching.
++ *  Macro cpu_to_scr() is to be used for script patching.
++ *  Macro scr_to_cpu() is to be used for getting a DWORD 
++ *  from the script.
++ */
++
++#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
++
++#define cpu_to_scr(dw)	cpu_to_le32(dw)
++#define scr_to_cpu(dw)	le32_to_cpu(dw)
++
++#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
++
++#define cpu_to_scr(dw)	cpu_to_be32(dw)
++#define scr_to_cpu(dw)	be32_to_cpu(dw)
++
++#else
++
++#define cpu_to_scr(dw)	(dw)
++#define scr_to_cpu(dw)	(dw)
++
++#endif
++
++/*
++ *  Access to the controller chip.
++ *
++ *  If the CPU and the NCR use same endian-ness addressing,
++ *  no byte reordering is needed for accessing chip io 
++ *  registers. Functions suffixed by '_raw' are assumed 
++ *  to access the chip over the PCI without doing byte 
++ *  reordering. Functions suffixed by '_l2b' are 
++ *  assumed to perform little-endian to big-endian byte 
++ *  reordering, those suffixed by '_b2l' blah, blah,
++ *  blah, ...
++ */
++
++/*
++ *  MEMORY mapped IO input / output
++ */
++
++#define INB_OFF(o)		readb_raw((char __iomem *)np->reg + ncr_offb(o))
++#define OUTB_OFF(o, val)	writeb_raw((val), (char __iomem *)np->reg + ncr_offb(o))
++
++#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
++
++#define INW_OFF(o)		readw_l2b((char __iomem *)np->reg + ncr_offw(o))
++#define INL_OFF(o)		readl_l2b((char __iomem *)np->reg + (o))
++
++#define OUTW_OFF(o, val)	writew_b2l((val), (char __iomem *)np->reg + ncr_offw(o))
++#define OUTL_OFF(o, val)	writel_b2l((val), (char __iomem *)np->reg + (o))
++
++#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
++
++#define INW_OFF(o)		readw_b2l((char __iomem *)np->reg + ncr_offw(o))
++#define INL_OFF(o)		readl_b2l((char __iomem *)np->reg + (o))
++
++#define OUTW_OFF(o, val)	writew_l2b((val), (char __iomem *)np->reg + ncr_offw(o))
++#define OUTL_OFF(o, val)	writel_l2b((val), (char __iomem *)np->reg + (o))
++
++#else
++
++#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
++/* Only 8 or 32 bit transfers allowed */
++#define INW_OFF(o)		(readb((char __iomem *)np->reg + ncr_offw(o)) << 8 | readb((char __iomem *)np->reg + ncr_offw(o) + 1))
++#else
++#define INW_OFF(o)		readw_raw((char __iomem *)np->reg + ncr_offw(o))
++#endif
++#define INL_OFF(o)		readl_raw((char __iomem *)np->reg + (o))
++
++#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
++/* Only 8 or 32 bit transfers allowed */
++#define OUTW_OFF(o, val)	do { writeb((char)((val) >> 8), (char __iomem *)np->reg + ncr_offw(o)); writeb((char)(val), (char __iomem *)np->reg + ncr_offw(o) + 1); } while (0)
++#else
++#define OUTW_OFF(o, val)	writew_raw((val), (char __iomem *)np->reg + ncr_offw(o))
++#endif
++#define OUTL_OFF(o, val)	writel_raw((val), (char __iomem *)np->reg + (o))
++
++#endif
++
++#define INB(r)		INB_OFF (offsetof(struct ncr_reg,r))
++#define INW(r)		INW_OFF (offsetof(struct ncr_reg,r))
++#define INL(r)		INL_OFF (offsetof(struct ncr_reg,r))
++
++#define OUTB(r, val)	OUTB_OFF (offsetof(struct ncr_reg,r), (val))
++#define OUTW(r, val)	OUTW_OFF (offsetof(struct ncr_reg,r), (val))
++#define OUTL(r, val)	OUTL_OFF (offsetof(struct ncr_reg,r), (val))
++
++/*
++ *  Set bit field ON, OFF 
++ */
++
++#define OUTONB(r, m)	OUTB(r, INB(r) | (m))
++#define OUTOFFB(r, m)	OUTB(r, INB(r) & ~(m))
++#define OUTONW(r, m)	OUTW(r, INW(r) | (m))
++#define OUTOFFW(r, m)	OUTW(r, INW(r) & ~(m))
++#define OUTONL(r, m)	OUTL(r, INL(r) | (m))
++#define OUTOFFL(r, m)	OUTL(r, INL(r) & ~(m))
++
++/*
++ *  We normally want the chip to have a consistent view
++ *  of driver internal data structures when we restart it.
++ *  Thus these macros.
++ */
++#define OUTL_DSP(v)				\
++	do {					\
++		MEMORY_BARRIER();		\
++		OUTL (nc_dsp, (v));		\
++	} while (0)
++
++#define OUTONB_STD()				\
++	do {					\
++		MEMORY_BARRIER();		\
++		OUTONB (nc_dcntl, (STD|NOCOM));	\
++	} while (0)
++
++
++/*
++**   NCR53C8XX devices features table.
++*/
++struct ncr_chip {
++	unsigned short	revision_id;
++	unsigned char	burst_max;	/* log-base-2 of max burst */
++	unsigned char	offset_max;
++	unsigned char	nr_divisor;
++	unsigned int	features;
++#define FE_LED0		(1<<0)
++#define FE_WIDE		(1<<1)    /* Wide data transfers */
++#define FE_ULTRA	(1<<2)	  /* Ultra speed 20Mtrans/sec */
++#define FE_DBLR		(1<<4)	  /* Clock doubler present */
++#define FE_QUAD		(1<<5)	  /* Clock quadrupler present */
++#define FE_ERL		(1<<6)    /* Enable read line */
++#define FE_CLSE		(1<<7)    /* Cache line size enable */
++#define FE_WRIE		(1<<8)    /* Write & Invalidate enable */
++#define FE_ERMP		(1<<9)    /* Enable read multiple */
++#define FE_BOF		(1<<10)   /* Burst opcode fetch */
++#define FE_DFS		(1<<11)   /* DMA fifo size */
++#define FE_PFEN		(1<<12)   /* Prefetch enable */
++#define FE_LDSTR	(1<<13)   /* Load/Store supported */
++#define FE_RAM		(1<<14)   /* On chip RAM present */
++#define FE_VARCLK	(1<<15)   /* SCSI clock may vary */
++#define FE_RAM8K	(1<<16)   /* On chip RAM sized 8Kb */
++#define FE_64BIT	(1<<17)   /* Have a 64-bit PCI interface */
++#define FE_IO256	(1<<18)   /* Requires full 256 bytes in PCI space */
++#define FE_NOPM		(1<<19)   /* Scripts handles phase mismatch */
++#define FE_LEDC		(1<<20)   /* Hardware control of LED */
++#define FE_DIFF		(1<<21)   /* Support Differential SCSI */
++#define FE_66MHZ 	(1<<23)   /* 66MHz PCI Support */
++#define FE_DAC	 	(1<<24)   /* Support DAC cycles (64 bit addressing) */
++#define FE_ISTAT1 	(1<<25)   /* Have ISTAT1, MBOX0, MBOX1 registers */
++#define FE_DAC_IN_USE	(1<<26)	  /* Platform does DAC cycles */
++#define FE_EHP		(1<<27)   /* 720: Even host parity */
++#define FE_MUX		(1<<28)   /* 720: Multiplexed bus */
++#define FE_EA		(1<<29)   /* 720: Enable Ack */
++
++#define FE_CACHE_SET	(FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP)
++#define FE_SCSI_SET	(FE_WIDE|FE_ULTRA|FE_DBLR|FE_QUAD|F_CLK80)
++#define FE_SPECIAL_SET	(FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM)
++};
++
++
++/*
++**	Driver setup structure.
++**
++**	This structure is initialized from linux config options.
++**	It can be overridden at boot-up by the boot command line.
++*/
++#define SCSI_NCR_MAX_EXCLUDES 8
++struct ncr_driver_setup {
++	u8	master_parity;
++	u8	scsi_parity;
++	u8	disconnection;
++	u8	special_features;
++	u8	force_sync_nego;
++	u8	reverse_probe;
++	u8	pci_fix_up;
++	u8	use_nvram;
++	u8	verbose;
++	u8	default_tags;
++	u16	default_sync;
++	u16	debug;
++	u8	burst_max;
++	u8	led_pin;
++	u8	max_wide;
++	u8	settle_delay;
++	u8	diff_support;
++	u8	irqm;
++	u8	bus_check;
++	u8	optimize;
++	u8	recovery;
++	u8	host_id;
++	u16	iarb;
++	u32	excludes[SCSI_NCR_MAX_EXCLUDES];
++	char	tag_ctrl[100];
++};
++
++/*
++**	Initial setup.
++**	Can be overriden at startup by a command line.
++*/
++#define SCSI_NCR_DRIVER_SETUP			\
++{						\
++	SCSI_NCR_SETUP_MASTER_PARITY,		\
++	SCSI_NCR_SETUP_SCSI_PARITY,		\
++	SCSI_NCR_SETUP_DISCONNECTION,		\
++	SCSI_NCR_SETUP_SPECIAL_FEATURES,	\
++	SCSI_NCR_SETUP_FORCE_SYNC_NEGO,		\
++	0,					\
++	0,					\
++	1,					\
++	0,					\
++	SCSI_NCR_SETUP_DEFAULT_TAGS,		\
++	SCSI_NCR_SETUP_DEFAULT_SYNC,		\
++	0x00,					\
++	7,					\
++	0,					\
++	1,					\
++	SCSI_NCR_SETUP_SETTLE_TIME,		\
++	0,					\
++	0,					\
++	1,					\
++	0,					\
++	0,					\
++	255,					\
++	0x00					\
++}
++
++/*
++**	Boot fail safe setup.
++**	Override initial setup from boot command line:
++**	ncr53c8xx=safe:y
++*/
++#define SCSI_NCR_DRIVER_SAFE_SETUP		\
++{						\
++	0,					\
++	1,					\
++	0,					\
++	0,					\
++	0,					\
++	0,					\
++	0,					\
++	1,					\
++	2,					\
++	0,					\
++	255,					\
++	0x00,					\
++	255,					\
++	0,					\
++	0,					\
++	10,					\
++	1,					\
++	1,					\
++	1,					\
++	0,					\
++	0,					\
++	255					\
++}
++
++/**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/
++
++/*-----------------------------------------------------------------
++**
++**	The ncr 53c810 register structure.
++**
++**-----------------------------------------------------------------
++*/
++
++struct ncr_reg {
++/*00*/  u8	nc_scntl0;    /* full arb., ena parity, par->ATN  */
++
++/*01*/  u8	nc_scntl1;    /* no reset                         */
++        #define   ISCON   0x10  /* connected to scsi		    */
++        #define   CRST    0x08  /* force reset                      */
++        #define   IARB    0x02  /* immediate arbitration            */
++
++/*02*/  u8	nc_scntl2;    /* no disconnect expected           */
++	#define   SDU     0x80  /* cmd: disconnect will raise error */
++	#define   CHM     0x40  /* sta: chained mode                */
++	#define   WSS     0x08  /* sta: wide scsi send           [W]*/
++	#define   WSR     0x01  /* sta: wide scsi received       [W]*/
++
++/*03*/  u8	nc_scntl3;    /* cnf system clock dependent       */
++	#define   EWS     0x08  /* cmd: enable wide scsi         [W]*/
++	#define   ULTRA   0x80  /* cmd: ULTRA enable                */
++				/* bits 0-2, 7 rsvd for C1010       */
++
++/*04*/  u8	nc_scid;	/* cnf host adapter scsi address    */
++	#define   RRE     0x40  /* r/w:e enable response to resel.  */
++	#define   SRE     0x20  /* r/w:e enable response to select  */
++
++/*05*/  u8	nc_sxfer;	/* ### Sync speed and count         */
++				/* bits 6-7 rsvd for C1010          */
++
++/*06*/  u8	nc_sdid;	/* ### Destination-ID               */
++
++/*07*/  u8	nc_gpreg;	/* ??? IO-Pins                      */
++
++/*08*/  u8	nc_sfbr;	/* ### First byte in phase          */
++
++/*09*/  u8	nc_socl;
++	#define   CREQ	  0x80	/* r/w: SCSI-REQ                    */
++	#define   CACK	  0x40	/* r/w: SCSI-ACK                    */
++	#define   CBSY	  0x20	/* r/w: SCSI-BSY                    */
++	#define   CSEL	  0x10	/* r/w: SCSI-SEL                    */
++	#define   CATN	  0x08	/* r/w: SCSI-ATN                    */
++	#define   CMSG	  0x04	/* r/w: SCSI-MSG                    */
++	#define   CC_D	  0x02	/* r/w: SCSI-C_D                    */
++	#define   CI_O	  0x01	/* r/w: SCSI-I_O                    */
++
++/*0a*/  u8	nc_ssid;
++
++/*0b*/  u8	nc_sbcl;
++
++/*0c*/  u8	nc_dstat;
++        #define   DFE     0x80  /* sta: dma fifo empty              */
++        #define   MDPE    0x40  /* int: master data parity error    */
++        #define   BF      0x20  /* int: script: bus fault           */
++        #define   ABRT    0x10  /* int: script: command aborted     */
++        #define   SSI     0x08  /* int: script: single step         */
++        #define   SIR     0x04  /* int: script: interrupt instruct. */
++        #define   IID     0x01  /* int: script: illegal instruct.   */
++
++/*0d*/  u8	nc_sstat0;
++        #define   ILF     0x80  /* sta: data in SIDL register lsb   */
++        #define   ORF     0x40  /* sta: data in SODR register lsb   */
++        #define   OLF     0x20  /* sta: data in SODL register lsb   */
++        #define   AIP     0x10  /* sta: arbitration in progress     */
++        #define   LOA     0x08  /* sta: arbitration lost            */
++        #define   WOA     0x04  /* sta: arbitration won             */
++        #define   IRST    0x02  /* sta: scsi reset signal           */
++        #define   SDP     0x01  /* sta: scsi parity signal          */
++
++/*0e*/  u8	nc_sstat1;
++	#define   FF3210  0xf0	/* sta: bytes in the scsi fifo      */
++
++/*0f*/  u8	nc_sstat2;
++        #define   ILF1    0x80  /* sta: data in SIDL register msb[W]*/
++        #define   ORF1    0x40  /* sta: data in SODR register msb[W]*/
++        #define   OLF1    0x20  /* sta: data in SODL register msb[W]*/
++        #define   DM      0x04  /* sta: DIFFSENS mismatch (895/6 only) */
++        #define   LDSC    0x02  /* sta: disconnect & reconnect      */
++
++/*10*/  u8	nc_dsa;	/* --> Base page                    */
++/*11*/  u8	nc_dsa1;
++/*12*/  u8	nc_dsa2;
++/*13*/  u8	nc_dsa3;
++
++/*14*/  u8	nc_istat;	/* --> Main Command and status      */
++        #define   CABRT   0x80  /* cmd: abort current operation     */
++        #define   SRST    0x40  /* mod: reset chip                  */
++        #define   SIGP    0x20  /* r/w: message from host to ncr    */
++        #define   SEM     0x10  /* r/w: message between host + ncr  */
++        #define   CON     0x08  /* sta: connected to scsi           */
++        #define   INTF    0x04  /* sta: int on the fly (reset by wr)*/
++        #define   SIP     0x02  /* sta: scsi-interrupt              */
++        #define   DIP     0x01  /* sta: host/script interrupt       */
++
++/*15*/  u8	nc_istat1;	/* 896 and later cores only */
++        #define   FLSH    0x04  /* sta: chip is flushing            */
++        #define   SRUN    0x02  /* sta: scripts are running         */
++        #define   SIRQD   0x01  /* r/w: disable INT pin             */
++
++/*16*/  u8	nc_mbox0;	/* 896 and later cores only */
++/*17*/  u8	nc_mbox1;	/* 896 and later cores only */
++
++/*18*/	u8	nc_ctest0;
++	#define   EHP     0x04	/* 720 even host parity             */
++/*19*/  u8	nc_ctest1;
++
++/*1a*/  u8	nc_ctest2;
++	#define   CSIGP   0x40
++				/* bits 0-2,7 rsvd for C1010        */
++
++/*1b*/  u8	nc_ctest3;
++	#define   FLF     0x08  /* cmd: flush dma fifo              */
++	#define   CLF	  0x04	/* cmd: clear dma fifo		    */
++	#define   FM      0x02  /* mod: fetch pin mode              */
++	#define   WRIE    0x01  /* mod: write and invalidate enable */
++				/* bits 4-7 rsvd for C1010          */
++
++/*1c*/  u32    nc_temp;	/* ### Temporary stack              */
++
++/*20*/	u8	nc_dfifo;
++/*21*/  u8	nc_ctest4;
++	#define   MUX     0x80  /* 720 host bus multiplex mode      */
++	#define   BDIS    0x80  /* mod: burst disable               */
++	#define   MPEE    0x08  /* mod: master parity error enable  */
++
++/*22*/  u8	nc_ctest5;
++	#define   DFS     0x20  /* mod: dma fifo size               */
++				/* bits 0-1, 3-7 rsvd for C1010          */
++/*23*/  u8	nc_ctest6;
++
++/*24*/  u32    nc_dbc;	/* ### Byte count and command       */
++/*28*/  u32    nc_dnad;	/* ### Next command register        */
++/*2c*/  u32    nc_dsp;	/* --> Script Pointer               */
++/*30*/  u32    nc_dsps;	/* --> Script pointer save/opcode#2 */
++
++/*34*/  u8	nc_scratcha;  /* Temporary register a            */
++/*35*/  u8	nc_scratcha1;
++/*36*/  u8	nc_scratcha2;
++/*37*/  u8	nc_scratcha3;
++
++/*38*/  u8	nc_dmode;
++	#define   BL_2    0x80  /* mod: burst length shift value +2 */
++	#define   BL_1    0x40  /* mod: burst length shift value +1 */
++	#define   ERL     0x08  /* mod: enable read line            */
++	#define   ERMP    0x04  /* mod: enable read multiple        */
++	#define   BOF     0x02  /* mod: burst op code fetch         */
++
++/*39*/  u8	nc_dien;
++/*3a*/  u8	nc_sbr;
++
++/*3b*/  u8	nc_dcntl;	/* --> Script execution control     */
++	#define   CLSE    0x80  /* mod: cache line size enable      */
++	#define   PFF     0x40  /* cmd: pre-fetch flush             */
++	#define   PFEN    0x20  /* mod: pre-fetch enable            */
++	#define   EA      0x20  /* mod: 720 enable-ack              */
++	#define   SSM     0x10  /* mod: single step mode            */
++	#define   IRQM    0x08  /* mod: irq mode (1 = totem pole !) */
++	#define   STD     0x04  /* cmd: start dma mode              */
++	#define   IRQD    0x02  /* mod: irq disable                 */
++ 	#define	  NOCOM   0x01	/* cmd: protect sfbr while reselect */
++				/* bits 0-1 rsvd for C1010          */
++
++/*3c*/  u32	nc_adder;
++
++/*40*/  u16	nc_sien;	/* -->: interrupt enable            */
++/*42*/  u16	nc_sist;	/* <--: interrupt status            */
++        #define   SBMC    0x1000/* sta: SCSI Bus Mode Change (895/6 only) */
++        #define   STO     0x0400/* sta: timeout (select)            */
++        #define   GEN     0x0200/* sta: timeout (general)           */
++        #define   HTH     0x0100/* sta: timeout (handshake)         */
++        #define   MA      0x80  /* sta: phase mismatch              */
++        #define   CMP     0x40  /* sta: arbitration complete        */
++        #define   SEL     0x20  /* sta: selected by another device  */
++        #define   RSL     0x10  /* sta: reselected by another device*/
++        #define   SGE     0x08  /* sta: gross error (over/underflow)*/
++        #define   UDC     0x04  /* sta: unexpected disconnect       */
++        #define   RST     0x02  /* sta: scsi bus reset detected     */
++        #define   PAR     0x01  /* sta: scsi parity error           */
++
++/*44*/  u8	nc_slpar;
++/*45*/  u8	nc_swide;
++/*46*/  u8	nc_macntl;
++/*47*/  u8	nc_gpcntl;
++/*48*/  u8	nc_stime0;    /* cmd: timeout for select&handshake*/
++/*49*/  u8	nc_stime1;    /* cmd: timeout user defined        */
++/*4a*/  u16   nc_respid;    /* sta: Reselect-IDs                */
++
++/*4c*/  u8	nc_stest0;
++
++/*4d*/  u8	nc_stest1;
++	#define   SCLK    0x80	/* Use the PCI clock as SCSI clock	*/
++	#define   DBLEN   0x08	/* clock doubler running		*/
++	#define   DBLSEL  0x04	/* clock doubler selected		*/
++  
++
++/*4e*/  u8	nc_stest2;
++	#define   ROF     0x40	/* reset scsi offset (after gross error!) */
++	#define   DIF     0x20  /* 720 SCSI differential mode             */
++	#define   EXT     0x02  /* extended filtering                     */
++
++/*4f*/  u8	nc_stest3;
++	#define   TE     0x80	/* c: tolerAnt enable */
++	#define   HSC    0x20	/* c: Halt SCSI Clock */
++	#define   CSF    0x02	/* c: clear scsi fifo */
++
++/*50*/  u16   nc_sidl;	/* Lowlevel: latched from scsi data */
++/*52*/  u8	nc_stest4;
++	#define   SMODE  0xc0	/* SCSI bus mode      (895/6 only) */
++	#define    SMODE_HVD 0x40	/* High Voltage Differential       */
++	#define    SMODE_SE  0x80	/* Single Ended                    */
++	#define    SMODE_LVD 0xc0	/* Low Voltage Differential        */
++	#define   LCKFRQ 0x20	/* Frequency Lock (895/6 only)     */
++				/* bits 0-5 rsvd for C1010          */
++
++/*53*/  u8	nc_53_;
++/*54*/  u16	nc_sodl;	/* Lowlevel: data out to scsi data  */
++/*56*/	u8	nc_ccntl0;	/* Chip Control 0 (896)             */
++	#define   ENPMJ  0x80	/* Enable Phase Mismatch Jump       */
++	#define   PMJCTL 0x40	/* Phase Mismatch Jump Control      */
++	#define   ENNDJ  0x20	/* Enable Non Data PM Jump          */
++	#define   DISFC  0x10	/* Disable Auto FIFO Clear          */
++	#define   DILS   0x02	/* Disable Internal Load/Store      */
++	#define   DPR    0x01	/* Disable Pipe Req                 */
++
++/*57*/	u8	nc_ccntl1;	/* Chip Control 1 (896)             */
++	#define   ZMOD   0x80	/* High Impedance Mode              */
++	#define	  DIC	 0x10	/* Disable Internal Cycles	    */
++	#define   DDAC   0x08	/* Disable Dual Address Cycle       */
++	#define   XTIMOD 0x04	/* 64-bit Table Ind. Indexing Mode  */
++	#define   EXTIBMV 0x02	/* Enable 64-bit Table Ind. BMOV    */
++	#define   EXDBMV 0x01	/* Enable 64-bit Direct BMOV        */
++
++/*58*/  u16	nc_sbdl;	/* Lowlevel: data from scsi data    */
++/*5a*/  u16	nc_5a_;
++
++/*5c*/  u8	nc_scr0;	/* Working register B               */
++/*5d*/  u8	nc_scr1;	/*                                  */
++/*5e*/  u8	nc_scr2;	/*                                  */
++/*5f*/  u8	nc_scr3;	/*                                  */
++
++/*60*/  u8	nc_scrx[64];	/* Working register C-R             */
++/*a0*/	u32	nc_mmrs;	/* Memory Move Read Selector        */
++/*a4*/	u32	nc_mmws;	/* Memory Move Write Selector       */
++/*a8*/	u32	nc_sfs;		/* Script Fetch Selector            */
++/*ac*/	u32	nc_drs;		/* DSA Relative Selector            */
++/*b0*/	u32	nc_sbms;	/* Static Block Move Selector       */
++/*b4*/	u32	nc_dbms;	/* Dynamic Block Move Selector      */
++/*b8*/	u32	nc_dnad64;	/* DMA Next Address 64              */
++/*bc*/	u16	nc_scntl4;	/* C1010 only                       */
++	#define   U3EN   0x80	/* Enable Ultra 3                   */
++	#define   AIPEN	 0x40   /* Allow check upper byte lanes     */
++	#define   XCLKH_DT 0x08 /* Extra clock of data hold on DT
++					transfer edge	            */
++	#define   XCLKH_ST 0x04 /* Extra clock of data hold on ST
++					transfer edge	            */
++
++/*be*/  u8	nc_aipcntl0;	/* Epat Control 1 C1010 only        */
++/*bf*/  u8	nc_aipcntl1;	/* AIP Control C1010_66 Only        */
++
++/*c0*/	u32	nc_pmjad1;	/* Phase Mismatch Jump Address 1    */
++/*c4*/	u32	nc_pmjad2;	/* Phase Mismatch Jump Address 2    */
++/*c8*/	u8	nc_rbc;		/* Remaining Byte Count             */
++/*c9*/	u8	nc_rbc1;	/*                                  */
++/*ca*/	u8	nc_rbc2;	/*                                  */
++/*cb*/	u8	nc_rbc3;	/*                                  */
++
++/*cc*/	u8	nc_ua;		/* Updated Address                  */
++/*cd*/	u8	nc_ua1;		/*                                  */
++/*ce*/	u8	nc_ua2;		/*                                  */
++/*cf*/	u8	nc_ua3;		/*                                  */
++/*d0*/	u32	nc_esa;		/* Entry Storage Address            */
++/*d4*/	u8	nc_ia;		/* Instruction Address              */
++/*d5*/	u8	nc_ia1;
++/*d6*/	u8	nc_ia2;
++/*d7*/	u8	nc_ia3;
++/*d8*/	u32	nc_sbc;		/* SCSI Byte Count (3 bytes only)   */
++/*dc*/	u32	nc_csbc;	/* Cumulative SCSI Byte Count       */
++
++				/* Following for C1010 only         */
++/*e0*/  u16	nc_crcpad;	/* CRC Value                        */
++/*e2*/  u8	nc_crccntl0;	/* CRC control register             */
++	#define   SNDCRC  0x10	/* Send CRC Request                 */
++/*e3*/  u8	nc_crccntl1;	/* CRC control register             */
++/*e4*/  u32	nc_crcdata;	/* CRC data register                */ 
++/*e8*/  u32	nc_e8_;		/* rsvd 			    */
++/*ec*/  u32	nc_ec_;		/* rsvd 			    */
++/*f0*/  u16	nc_dfbc;	/* DMA FIFO byte count              */ 
++
++};
++
++/*-----------------------------------------------------------
++**
++**	Utility macros for the script.
++**
++**-----------------------------------------------------------
++*/
++
++#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r))
++#define REG(r) REGJ (nc_, r)
++
++typedef u32 ncrcmd;
++
++/*-----------------------------------------------------------
++**
++**	SCSI phases
++**
++**	DT phases illegal for ncr driver.
++**
++**-----------------------------------------------------------
++*/
++
++#define	SCR_DATA_OUT	0x00000000
++#define	SCR_DATA_IN	0x01000000
++#define	SCR_COMMAND	0x02000000
++#define	SCR_STATUS	0x03000000
++#define SCR_DT_DATA_OUT	0x04000000
++#define SCR_DT_DATA_IN	0x05000000
++#define SCR_MSG_OUT	0x06000000
++#define SCR_MSG_IN      0x07000000
++
++#define SCR_ILG_OUT	0x04000000
++#define SCR_ILG_IN	0x05000000
++
++/*-----------------------------------------------------------
++**
++**	Data transfer via SCSI.
++**
++**-----------------------------------------------------------
++**
++**	MOVE_ABS (LEN)
++**	<<start address>>
++**
++**	MOVE_IND (LEN)
++**	<<dnad_offset>>
++**
++**	MOVE_TBL
++**	<<dnad_offset>>
++**
++**-----------------------------------------------------------
++*/
++
++#define OPC_MOVE          0x08000000
++
++#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l))
++#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l))
++#define SCR_MOVE_TBL     (0x10000000 | OPC_MOVE)
++
++#define SCR_CHMOV_ABS(l) ((0x00000000) | (l))
++#define SCR_CHMOV_IND(l) ((0x20000000) | (l))
++#define SCR_CHMOV_TBL     (0x10000000)
++
++struct scr_tblmove {
++        u32  size;
++        u32  addr;
++};
++
++/*-----------------------------------------------------------
++**
++**	Selection
++**
++**-----------------------------------------------------------
++**
++**	SEL_ABS | SCR_ID (0..15)    [ | REL_JMP]
++**	<<alternate_address>>
++**
++**	SEL_TBL | << dnad_offset>>  [ | REL_JMP]
++**	<<alternate_address>>
++**
++**-----------------------------------------------------------
++*/
++
++#define	SCR_SEL_ABS	0x40000000
++#define	SCR_SEL_ABS_ATN	0x41000000
++#define	SCR_SEL_TBL	0x42000000
++#define	SCR_SEL_TBL_ATN	0x43000000
++
++
++#ifdef SCSI_NCR_BIG_ENDIAN
++struct scr_tblsel {
++        u8	sel_scntl3;
++        u8	sel_id;
++        u8	sel_sxfer;
++        u8	sel_scntl4;	
++};
++#else
++struct scr_tblsel {
++        u8	sel_scntl4;	
++        u8	sel_sxfer;
++        u8	sel_id;
++        u8	sel_scntl3;
++};
++#endif
++
++#define SCR_JMP_REL     0x04000000
++#define SCR_ID(id)	(((u32)(id)) << 16)
++
++/*-----------------------------------------------------------
++**
++**	Waiting for Disconnect or Reselect
++**
++**-----------------------------------------------------------
++**
++**	WAIT_DISC
++**	dummy: <<alternate_address>>
++**
++**	WAIT_RESEL
++**	<<alternate_address>>
++**
++**-----------------------------------------------------------
++*/
++
++#define	SCR_WAIT_DISC	0x48000000
++#define SCR_WAIT_RESEL  0x50000000
++
++/*-----------------------------------------------------------
++**
++**	Bit Set / Reset
++**
++**-----------------------------------------------------------
++**
++**	SET (flags {|.. })
++**
++**	CLR (flags {|.. })
++**
++**-----------------------------------------------------------
++*/
++
++#define SCR_SET(f)     (0x58000000 | (f))
++#define SCR_CLR(f)     (0x60000000 | (f))
++
++#define	SCR_CARRY	0x00000400
++#define	SCR_TRG		0x00000200
++#define	SCR_ACK		0x00000040
++#define	SCR_ATN		0x00000008
++
++
++
++
++/*-----------------------------------------------------------
++**
++**	Memory to memory move
++**
++**-----------------------------------------------------------
++**
++**	COPY (bytecount)
++**	<< source_address >>
++**	<< destination_address >>
++**
++**	SCR_COPY   sets the NO FLUSH option by default.
++**	SCR_COPY_F does not set this option.
++**
++**	For chips which do not support this option,
++**	ncr_copy_and_bind() will remove this bit.
++**-----------------------------------------------------------
++*/
++
++#define SCR_NO_FLUSH 0x01000000
++
++#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n))
++#define SCR_COPY_F(n) (0xc0000000 | (n))
++
++/*-----------------------------------------------------------
++**
++**	Register move and binary operations
++**
++**-----------------------------------------------------------
++**
++**	SFBR_REG (reg, op, data)        reg  = SFBR op data
++**	<< 0 >>
++**
++**	REG_SFBR (reg, op, data)        SFBR = reg op data
++**	<< 0 >>
++**
++**	REG_REG  (reg, op, data)        reg  = reg op data
++**	<< 0 >>
++**
++**-----------------------------------------------------------
++**	On 810A, 860, 825A, 875, 895 and 896 chips the content 
++**	of SFBR register can be used as data (SCR_SFBR_DATA).
++**	The 896 has additionnal IO registers starting at 
++**	offset 0x80. Bit 7 of register offset is stored in 
++**	bit 7 of the SCRIPTS instruction first DWORD.
++**-----------------------------------------------------------
++*/
++
++#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul) + ((ofs) & 0x80)) 
++
++#define SCR_SFBR_REG(reg,op,data) \
++        (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
++
++#define SCR_REG_SFBR(reg,op,data) \
++        (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
++
++#define SCR_REG_REG(reg,op,data) \
++        (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
++
++
++#define      SCR_LOAD   0x00000000
++#define      SCR_SHL    0x01000000
++#define      SCR_OR     0x02000000
++#define      SCR_XOR    0x03000000
++#define      SCR_AND    0x04000000
++#define      SCR_SHR    0x05000000
++#define      SCR_ADD    0x06000000
++#define      SCR_ADDC   0x07000000
++
++#define      SCR_SFBR_DATA   (0x00800000>>8ul)	/* Use SFBR as data */
++
++/*-----------------------------------------------------------
++**
++**	FROM_REG (reg)		  SFBR = reg
++**	<< 0 >>
++**
++**	TO_REG	 (reg)		  reg  = SFBR
++**	<< 0 >>
++**
++**	LOAD_REG (reg, data)	  reg  = <data>
++**	<< 0 >>
++**
++**	LOAD_SFBR(data) 	  SFBR = <data>
++**	<< 0 >>
++**
++**-----------------------------------------------------------
++*/
++
++#define	SCR_FROM_REG(reg) \
++	SCR_REG_SFBR(reg,SCR_OR,0)
++
++#define	SCR_TO_REG(reg) \
++	SCR_SFBR_REG(reg,SCR_OR,0)
++
++#define	SCR_LOAD_REG(reg,data) \
++	SCR_REG_REG(reg,SCR_LOAD,data)
++
++#define SCR_LOAD_SFBR(data) \
++        (SCR_REG_SFBR (gpreg, SCR_LOAD, data))
++
++/*-----------------------------------------------------------
++**
++**	LOAD  from memory   to register.
++**	STORE from register to memory.
++**
++**	Only supported by 810A, 860, 825A, 875, 895 and 896.
++**
++**-----------------------------------------------------------
++**
++**	LOAD_ABS (LEN)
++**	<<start address>>
++**
++**	LOAD_REL (LEN)        (DSA relative)
++**	<<dsa_offset>>
++**
++**-----------------------------------------------------------
++*/
++
++#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul)
++#define SCR_NO_FLUSH2	0x02000000
++#define SCR_DSA_REL2	0x10000000
++
++#define SCR_LOAD_R(reg, how, n) \
++        (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
++
++#define SCR_STORE_R(reg, how, n) \
++        (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
++
++#define SCR_LOAD_ABS(reg, n)	SCR_LOAD_R(reg, SCR_NO_FLUSH2, n)
++#define SCR_LOAD_REL(reg, n)	SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n)
++#define SCR_LOAD_ABS_F(reg, n)	SCR_LOAD_R(reg, 0, n)
++#define SCR_LOAD_REL_F(reg, n)	SCR_LOAD_R(reg, SCR_DSA_REL2, n)
++
++#define SCR_STORE_ABS(reg, n)	SCR_STORE_R(reg, SCR_NO_FLUSH2, n)
++#define SCR_STORE_REL(reg, n)	SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n)
++#define SCR_STORE_ABS_F(reg, n)	SCR_STORE_R(reg, 0, n)
++#define SCR_STORE_REL_F(reg, n)	SCR_STORE_R(reg, SCR_DSA_REL2, n)
++
++
++/*-----------------------------------------------------------
++**
++**	Waiting for Disconnect or Reselect
++**
++**-----------------------------------------------------------
++**
++**	JUMP            [ | IFTRUE/IFFALSE ( ... ) ]
++**	<<address>>
++**
++**	JUMPR           [ | IFTRUE/IFFALSE ( ... ) ]
++**	<<distance>>
++**
++**	CALL            [ | IFTRUE/IFFALSE ( ... ) ]
++**	<<address>>
++**
++**	CALLR           [ | IFTRUE/IFFALSE ( ... ) ]
++**	<<distance>>
++**
++**	RETURN          [ | IFTRUE/IFFALSE ( ... ) ]
++**	<<dummy>>
++**
++**	INT             [ | IFTRUE/IFFALSE ( ... ) ]
++**	<<ident>>
++**
++**	INT_FLY         [ | IFTRUE/IFFALSE ( ... ) ]
++**	<<ident>>
++**
++**	Conditions:
++**	     WHEN (phase)
++**	     IF   (phase)
++**	     CARRYSET
++**	     DATA (data, mask)
++**
++**-----------------------------------------------------------
++*/
++
++#define SCR_NO_OP       0x80000000
++#define SCR_JUMP        0x80080000
++#define SCR_JUMP64      0x80480000
++#define SCR_JUMPR       0x80880000
++#define SCR_CALL        0x88080000
++#define SCR_CALLR       0x88880000
++#define SCR_RETURN      0x90080000
++#define SCR_INT         0x98080000
++#define SCR_INT_FLY     0x98180000
++
++#define IFFALSE(arg)   (0x00080000 | (arg))
++#define IFTRUE(arg)    (0x00000000 | (arg))
++
++#define WHEN(phase)    (0x00030000 | (phase))
++#define IF(phase)      (0x00020000 | (phase))
++
++#define DATA(D)        (0x00040000 | ((D) & 0xff))
++#define MASK(D,M)      (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff))
++
++#define CARRYSET       (0x00200000)
++
++/*-----------------------------------------------------------
++**
++**	SCSI  constants.
++**
++**-----------------------------------------------------------
++*/
++
++/*
++**	Status
++*/
++
++#define	S_GOOD		(0x00)
++#define	S_CHECK_COND	(0x02)
++#define	S_COND_MET	(0x04)
++#define	S_BUSY		(0x08)
++#define	S_INT		(0x10)
++#define	S_INT_COND_MET	(0x14)
++#define	S_CONFLICT	(0x18)
++#define	S_TERMINATED	(0x20)
++#define	S_QUEUE_FULL	(0x28)
++#define	S_ILLEGAL	(0xff)
++#define	S_SENSE		(0x80)
++
++/*
++ * End of ncrreg from FreeBSD
++ */
+ 
+ /*
+ 	Build a scatter/gather entry.
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_defs.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_defs.h
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_defs.h	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_defs.h	2005-12-12 09:00:09.000000000 -0700
+@@ -40,7 +40,7 @@
+ #ifndef SYM_DEFS_H
+ #define SYM_DEFS_H
+ 
+-#define SYM_VERSION "2.2.1"
++#define SYM_VERSION "2.2.2"
+ #define SYM_DRIVER_NAME	"sym-" SYM_VERSION
+ 
+ /*
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw.c CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw.c
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw.c	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw.c	2005-09-27 08:18:02.000000000 -0600
+@@ -37,11 +37,7 @@
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
+ 
+-#ifdef __FreeBSD__
+-#include <dev/sym/sym_glue.h>
+-#else
+ #include "sym_glue.h"
+-#endif
+ 
+ /*
+  *  Macros used for all firmwares.
+@@ -60,19 +56,12 @@
+ #define	SYM_FWA_SCR		sym_fw1a_scr
+ #define	SYM_FWB_SCR		sym_fw1b_scr
+ #define	SYM_FWZ_SCR		sym_fw1z_scr
+-#ifdef __FreeBSD__
+-#include <dev/sym/sym_fw1.h>
+-#else
+ #include "sym_fw1.h"
+-#endif
+ static struct sym_fwa_ofs sym_fw1a_ofs = {
+ 	SYM_GEN_FW_A(struct SYM_FWA_SCR)
+ };
+ static struct sym_fwb_ofs sym_fw1b_ofs = {
+ 	SYM_GEN_FW_B(struct SYM_FWB_SCR)
+-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
+-	SYM_GEN_B(struct SYM_FWB_SCR, data_io)
+-#endif
+ };
+ static struct sym_fwz_ofs sym_fw1z_ofs = {
+ 	SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
+@@ -88,19 +77,12 @@
+ #define	SYM_FWA_SCR		sym_fw2a_scr
+ #define	SYM_FWB_SCR		sym_fw2b_scr
+ #define	SYM_FWZ_SCR		sym_fw2z_scr
+-#ifdef __FreeBSD__
+-#include <dev/sym/sym_fw2.h>
+-#else
+ #include "sym_fw2.h"
+-#endif
+ static struct sym_fwa_ofs sym_fw2a_ofs = {
+ 	SYM_GEN_FW_A(struct SYM_FWA_SCR)
+ };
+ static struct sym_fwb_ofs sym_fw2b_ofs = {
+ 	SYM_GEN_FW_B(struct SYM_FWB_SCR)
+-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
+-	SYM_GEN_B(struct SYM_FWB_SCR, data_io)
+-#endif
+ 	SYM_GEN_B(struct SYM_FWB_SCR, start64)
+ 	SYM_GEN_B(struct SYM_FWB_SCR, pm_handle)
+ };
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw.h
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw.h	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw.h	2005-09-27 08:18:02.000000000 -0600
+@@ -92,9 +92,6 @@
+ };
+ struct sym_fwb_ofs {
+ 	SYM_GEN_FW_B(u_short)
+-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
+-	SYM_GEN_B(u_short, data_io)
+-#endif
+ 	SYM_GEN_B(u_short, start64)
+ 	SYM_GEN_B(u_short, pm_handle)
+ };
+@@ -111,9 +108,6 @@
+ };
+ struct sym_fwb_ba {
+ 	SYM_GEN_FW_B(u32)
+-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
+-	SYM_GEN_B(u32, data_io)
+-#endif
+ 	SYM_GEN_B(u32, start64);
+ 	SYM_GEN_B(u32, pm_handle);
+ };
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw1.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw1.h
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw1.h	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw1.h	2005-09-27 08:18:02.000000000 -0600
+@@ -197,12 +197,6 @@
+ 	u32 bad_status		[  7];
+ 	u32 wsr_ma_helper	[  4];
+ 
+-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
+-	/* Unknown direction handling */
+-	u32 data_io		[  2];
+-	u32 data_io_com		[  8];
+-	u32 data_io_out		[  7];
+-#endif
+ 	/* Data area */
+ 	u32 zero		[  1];
+ 	u32 scratch		[  1];
+@@ -1747,48 +1741,6 @@
+ 	SCR_JUMP,
+ 		PADDR_A (dispatch),
+ 
+-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
+-}/*-------------------------< DATA_IO >--------------------------*/,{
+-	/*
+-	 *  We jump here if the data direction was unknown at the 
+-	 *  time we had to queue the command to the scripts processor.
+-	 *  Pointers had been set as follow in this situation:
+-	 *    savep   -->   DATA_IO
+-	 *    lastp   -->   start pointer when DATA_IN
+-	 *    wlastp  -->   start pointer when DATA_OUT
+-	 *  This script sets savep and lastp according to the 
+-	 *  direction chosen by the target.
+-	 */
+-	SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)),
+-		PADDR_B (data_io_out),
+-}/*-------------------------< DATA_IO_COM >----------------------*/,{
+-	/*
+-	 *  Direction is DATA IN.
+-	 */
+-	SCR_COPY  (4),
+-		HADDR_1 (ccb_head.lastp),
+-		HADDR_1 (ccb_head.savep),
+-	/*
+-	 *  Jump to the SCRIPTS according to actual direction.
+-	 */
+-	SCR_COPY  (4),
+-		HADDR_1 (ccb_head.savep),
+-		RADDR_1 (temp),
+-	SCR_RETURN,
+-		0,
+-}/*-------------------------< DATA_IO_OUT >----------------------*/,{
+-	/*
+-	 *  Direction is DATA OUT.
+-	 */
+-	SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)),
+-		0,
+-	SCR_COPY  (4),
+-		HADDR_1 (ccb_head.wlastp),
+-		HADDR_1 (ccb_head.lastp),
+-	SCR_JUMP,
+-		PADDR_B(data_io_com),
+-#endif /* SYM_OPT_HANDLE_DIR_UNKNOWN */
+-
+ }/*-------------------------< ZERO >-----------------------------*/,{
+ 	SCR_DATA_ZERO,
+ }/*-------------------------< SCRATCH >--------------------------*/,{
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw2.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw2.h
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_fw2.h	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_fw2.h	2005-09-27 08:18:02.000000000 -0600
+@@ -191,13 +191,6 @@
+ 	u32 pm_wsr_handle	[ 38];
+ 	u32 wsr_ma_helper	[  4];
+ 
+-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
+-	/* Unknown direction handling */
+-	u32 data_io		[  2];
+-	u32 data_io_in		[  2];
+-	u32 data_io_com		[  6];
+-	u32 data_io_out		[  8];
+-#endif
+ 	/* Data area */
+ 	u32 zero		[  1];
+ 	u32 scratch		[  1];
+@@ -1838,51 +1831,6 @@
+ 	SCR_JUMP,
+ 		PADDR_A (dispatch),
+ 
+-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
+-}/*-------------------------< DATA_IO >--------------------------*/,{
+-	/*
+-	 *  We jump here if the data direction was unknown at the 
+-	 *  time we had to queue the command to the scripts processor.
+-	 *  Pointers had been set as follow in this situation:
+-	 *    savep   -->   DATA_IO
+-	 *    lastp   -->   start pointer when DATA_IN
+-	 *    wlastp  -->   start pointer when DATA_OUT
+-	 *  This script sets savep and lastp according to the 
+-	 *  direction chosen by the target.
+-	 */
+-	SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)),
+-		PADDR_B (data_io_out),
+-}/*-------------------------< DATA_IO_IN >-----------------------*/,{
+-	/*
+-	 *  Direction is DATA IN.
+-	 */
+-	SCR_LOAD_REL  (scratcha, 4),
+-		offsetof (struct sym_ccb, phys.head.lastp),
+-}/*-------------------------< DATA_IO_COM >----------------------*/,{
+-	SCR_STORE_REL (scratcha, 4),
+-		offsetof (struct sym_ccb, phys.head.savep),
+-
+-	/*
+-	 *  Jump to the SCRIPTS according to actual direction.
+-	 */
+-	SCR_LOAD_REL  (temp, 4),
+-		offsetof (struct sym_ccb, phys.head.savep),
+-	SCR_RETURN,
+-		0,
+-}/*-------------------------< DATA_IO_OUT >----------------------*/,{
+-	/*
+-	 *  Direction is DATA OUT.
+-	 */
+-	SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)),
+-		0,
+-	SCR_LOAD_REL  (scratcha, 4),
+-		offsetof (struct sym_ccb, phys.head.wlastp),
+-	SCR_STORE_REL (scratcha, 4),
+-		offsetof (struct sym_ccb, phys.head.lastp),
+-	SCR_JUMP,
+-		PADDR_B(data_io_com),
+-#endif /* SYM_OPT_HANDLE_DIR_UNKNOWN */
+-
+ }/*-------------------------< ZERO >-----------------------------*/,{
+ 	SCR_DATA_ZERO,
+ }/*-------------------------< SCRATCH >--------------------------*/,{
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_glue.c CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_glue.c
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_glue.c	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_glue.c	2005-12-18 08:29:09.000000000 -0700
+@@ -134,45 +134,6 @@
+ 	}
+ }
+ 
+-/*
+- * We used to try to deal with 64-bit BARs here, but don't any more.
+- * There are many parts of this driver which would need to be modified
+- * to handle a 64-bit base address, including scripts.  I'm uncomfortable
+- * with making those changes when I have no way of testing it, so I'm
+- * just going to disable it.
+- *
+- * Note that some machines (eg HP rx8620 and Superdome) have bus addresses
+- * below 4GB and physical addresses above 4GB.  These will continue to work.
+- */
+-static int __devinit
+-pci_get_base_address(struct pci_dev *pdev, int index, unsigned long *basep)
+-{
+-	u32 tmp;
+-	unsigned long base;
+-#define PCI_BAR_OFFSET(index) (PCI_BASE_ADDRESS_0 + (index<<2))
+-
+-	pci_read_config_dword(pdev, PCI_BAR_OFFSET(index++), &tmp);
+-	base = tmp;
+-	if ((tmp & 0x7) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
+-		pci_read_config_dword(pdev, PCI_BAR_OFFSET(index++), &tmp);
+-		if (tmp > 0) {
+-			dev_err(&pdev->dev,
+-				"BAR %d is 64-bit, disabling\n", index - 1);
+-			base = 0;
+-		}
+-	}
+-
+-	if ((base & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+-		base &= PCI_BASE_ADDRESS_IO_MASK;
+-	} else {
+-		base &= PCI_BASE_ADDRESS_MEM_MASK;
+-	}
+-
+-	*basep = base;
+-	return index;
+-#undef PCI_BAR_OFFSET
+-}
+-
+ static struct scsi_transport_template *sym2_transport_template = NULL;
+ 
+ /*
+@@ -514,9 +475,8 @@
+  */
+ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
+ {
++	u32 lastp, goalp;
+ 	int dir;
+-	struct sym_tcb *tp = &np->target[cp->target];
+-	struct sym_lcb *lp = sym_lp(tp, cp->lun);
+ 
+ 	/*
+ 	 *  Build the CDB.
+@@ -534,15 +494,47 @@
+ 			sym_set_cam_status(cmd, DID_ERROR);
+ 			goto out_abort;
+ 		}
++
++		/*
++		 *  No segments means no data.
++		 */
++		if (!cp->segments)
++			dir = DMA_NONE;
+ 	} else {
+ 		cp->data_len = 0;
+ 		cp->segments = 0;
+ 	}
+ 
+ 	/*
+-	 *  Set data pointers.
++	 *  Set the data pointer.
++	 */
++	switch (dir) {
++	case DMA_BIDIRECTIONAL:
++		printk("%s: got DMA_BIDIRECTIONAL command", sym_name(np));
++		sym_set_cam_status(cmd, DID_ERROR);
++		goto out_abort;
++	case DMA_TO_DEVICE:
++		goalp = SCRIPTA_BA(np, data_out2) + 8;
++		lastp = goalp - 8 - (cp->segments * (2*4));
++		break;
++	case DMA_FROM_DEVICE:
++		cp->host_flags |= HF_DATA_IN;
++		goalp = SCRIPTA_BA(np, data_in2) + 8;
++		lastp = goalp - 8 - (cp->segments * (2*4));
++		break;
++	case DMA_NONE:
++	default:
++		lastp = goalp = SCRIPTB_BA(np, no_data);
++		break;
++	}
++
++	/*
++	 *  Set all pointers values needed by SCRIPTS.
+ 	 */
+-	sym_setup_data_pointers(np, cp, dir);
++	cp->phys.head.lastp = cpu_to_scr(lastp);
++	cp->phys.head.savep = cpu_to_scr(lastp);
++	cp->startp	    = cp->phys.head.savep;
++	cp->goalp	    = cpu_to_scr(goalp);
+ 
+ 	/*
+ 	 *  When `#ifed 1', the code below makes the driver 
+@@ -563,10 +555,7 @@
+ 	/*
+ 	 *	activate this job.
+ 	 */
+-	if (lp)
+-		sym_start_next_ccbs(np, lp, 2);
+-	else
+-		sym_put_start_queue(np, cp);
++	sym_put_start_queue(np, cp);
+ 	return 0;
+ 
+ out_abort:
+@@ -721,7 +710,6 @@
+  *  What we will do regarding the involved SCSI command.
+  */
+ #define SYM_EH_DO_IGNORE	0
+-#define SYM_EH_DO_COMPLETE	1
+ #define SYM_EH_DO_WAIT		2
+ 
+ /*
+@@ -773,25 +761,18 @@
+ 
+ 	dev_warn(&cmd->device->sdev_gendev, "%s operation started.\n", opname);
+ 
++	spin_lock_irq(cmd->device->host->host_lock);
+ 	/* This one is queued in some place -> to wait for completion */
+ 	FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
+ 		struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
+ 		if (cp->cmd == cmd) {
+ 			to_do = SYM_EH_DO_WAIT;
+-			goto prepare;
++			break;
+ 		}
+ 	}
+ 
+-prepare:
+-	/* Prepare stuff to either ignore, complete or wait for completion */
+-	switch(to_do) {
+-	default:
+-	case SYM_EH_DO_IGNORE:
+-		break;
+-	case SYM_EH_DO_WAIT:
++	if (to_do == SYM_EH_DO_WAIT) {
+ 		init_completion(&ep->done);
+-		/* fall through */
+-	case SYM_EH_DO_COMPLETE:
+ 		ep->old_done = cmd->scsi_done;
+ 		cmd->scsi_done = sym_eh_done;
+ 		SYM_UCMD_PTR(cmd)->eh_wait = ep;
+@@ -827,9 +808,6 @@
+ 	}
+ 
+ 	ep->to_do = to_do;
+-	/* Complete the command with locks held as required by the driver */
+-	if (to_do == SYM_EH_DO_COMPLETE)
+-		sym_xpt_done2(np, cmd, DID_ABORT);
+ 
+ 	/* Wait for completion with locks released, as required by kernel */
+ 	if (to_do == SYM_EH_DO_WAIT) {
+@@ -845,6 +823,7 @@
+ 		if (ep->timed_out)
+ 			sts = -2;
+ 	}
++	spin_unlock_irq(cmd->device->host->host_lock);
+ 	dev_warn(&cmd->device->sdev_gendev, "%s operation %s.\n", opname,
+ 			sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed");
+ 	return sts ? SCSI_FAILED : SCSI_SUCCESS;
+@@ -856,46 +835,22 @@
+  */
+ static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd)
+ {
+-	int rc;
+-
+-	spin_lock_irq(cmd->device->host->host_lock);
+-	rc = sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd);
+-	spin_unlock_irq(cmd->device->host->host_lock);
+-
+-	return rc;
++	return sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd);
+ }
+ 
+ static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd)
+ {
+-	int rc;
+-
+-	spin_lock_irq(cmd->device->host->host_lock);
+-	rc = sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd);
+-	spin_unlock_irq(cmd->device->host->host_lock);
+-
+-	return rc;
++	return sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd);
+ }
+ 
+ static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)
+ {
+-	int rc;
+-
+-	spin_lock_irq(cmd->device->host->host_lock);
+-	rc = sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd);
+-	spin_unlock_irq(cmd->device->host->host_lock);
+-
+-	return rc;
++	return sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd);
+ }
+ 
+ static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd)
+ {
+-	int rc;
+-
+-	spin_lock_irq(cmd->device->host->host_lock);
+-	rc = sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd);
+-	spin_unlock_irq(cmd->device->host->host_lock);
+-
+-	return rc;
++	return sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd);
+ }
+ 
+ /*
+@@ -914,15 +869,12 @@
+ 	if (reqtags > lp->s.scdev_depth)
+ 		reqtags = lp->s.scdev_depth;
+ 
+-	lp->started_limit = reqtags ? reqtags : 2;
+-	lp->started_max   = 1;
+ 	lp->s.reqtags     = reqtags;
+ 
+ 	if (reqtags != oldtags) {
+ 		dev_info(&tp->starget->dev,
+ 		         "tagged command queuing %s, command queue depth %d.\n",
+-		          lp->s.reqtags ? "enabled" : "disabled",
+- 		          lp->started_limit);
++		          lp->s.reqtags ? "enabled" : "disabled", reqtags);
+ 	}
+ }
+ 
+@@ -981,15 +933,14 @@
+ 
+ static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
+ {
+-	struct sym_hcb *np;
+-	struct sym_tcb *tp;
++	struct sym_hcb *np = sym_get_hcb(sdev->host);
++	struct sym_tcb *tp = &np->target[sdev->id];
++	struct sym_lcb *lp;
+ 
+ 	if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN)
+ 		return -ENXIO;
+ 
+-	np = sym_get_hcb(sdev->host);
+-	tp = &np->target[sdev->id];
+-
++	tp->starget = sdev->sdev_target;
+ 	/*
+ 	 * Fail the device init if the device is flagged NOSCAN at BOOT in
+ 	 * the NVRAM.  This may speed up boot and maintain coherency with
+@@ -999,35 +950,41 @@
+ 	 * lun devices behave badly when asked for a non zero LUN.
+ 	 */
+ 
+-	if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
+-	    ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && sdev->lun != 0)) {
++	if (tp->usrflags & SYM_SCAN_BOOT_DISABLED) {
+ 		tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
++		starget_printk(KERN_INFO, tp->starget,
++				"Scan at boot disabled in NVRAM\n");
+ 		return -ENXIO;
+ 	}
+ 
+-	tp->starget = sdev->sdev_target;
++	if (tp->usrflags & SYM_SCAN_LUNS_DISABLED) {
++		if (sdev->lun != 0)
++			return -ENXIO;
++		starget_printk(KERN_INFO, tp->starget,
++				"Multiple LUNs disabled in NVRAM\n");
++	}
++
++	lp = sym_alloc_lcb(np, sdev->id, sdev->lun);
++	if (!lp)
++		return -ENOMEM;
++
++	spi_min_period(tp->starget) = tp->usr_period;
++	spi_max_width(tp->starget) = tp->usr_width;
++
+ 	return 0;
+ }
+ 
+ /*
+  * Linux entry point for device queue sizing.
+  */
+-static int sym53c8xx_slave_configure(struct scsi_device *device)
++static int sym53c8xx_slave_configure(struct scsi_device *sdev)
+ {
+-	struct sym_hcb *np = sym_get_hcb(device->host);
+-	struct sym_tcb *tp = &np->target[device->id];
+-	struct sym_lcb *lp;
++	struct sym_hcb *np = sym_get_hcb(sdev->host);
++	struct sym_tcb *tp = &np->target[sdev->id];
++	struct sym_lcb *lp = sym_lp(tp, sdev->lun);
+ 	int reqtags, depth_to_use;
+ 
+ 	/*
+-	 *  Allocate the LCB if not yet.
+-	 *  If it fail, we may well be in the sh*t. :)
+-	 */
+-	lp = sym_alloc_lcb(np, device->id, device->lun);
+-	if (!lp)
+-		return -ENOMEM;
+-
+-	/*
+ 	 *  Get user flags.
+ 	 */
+ 	lp->curr_flags = lp->user_flags;
+@@ -1038,10 +995,10 @@
+ 	 *  Use at least 2.
+ 	 *  Donnot use more than our maximum.
+ 	 */
+-	reqtags = device_queue_depth(np, device->id, device->lun);
++	reqtags = device_queue_depth(np, sdev->id, sdev->lun);
+ 	if (reqtags > tp->usrtags)
+ 		reqtags = tp->usrtags;
+-	if (!device->tagged_supported)
++	if (!sdev->tagged_supported)
+ 		reqtags = 0;
+ #if 1 /* Avoid to locally queue commands for no good reasons */
+ 	if (reqtags > SYM_CONF_MAX_TAG)
+@@ -1050,19 +1007,30 @@
+ #else
+ 	depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2);
+ #endif
+-	scsi_adjust_queue_depth(device,
+-				(device->tagged_supported ?
++	scsi_adjust_queue_depth(sdev,
++				(sdev->tagged_supported ?
+ 				 MSG_SIMPLE_TAG : 0),
+ 				depth_to_use);
+ 	lp->s.scdev_depth = depth_to_use;
+-	sym_tune_dev_queuing(tp, device->lun, reqtags);
++	sym_tune_dev_queuing(tp, sdev->lun, reqtags);
+ 
+-	if (!spi_initial_dv(device->sdev_target))
+-		spi_dv_device(device);
++	if (!spi_initial_dv(sdev->sdev_target))
++		spi_dv_device(sdev);
+ 
+ 	return 0;
+ }
+ 
++static void sym53c8xx_slave_destroy(struct scsi_device *sdev)
++{
++	struct sym_hcb *np = sym_get_hcb(sdev->host);
++	struct sym_lcb *lp = sym_lp(&np->target[sdev->id], sdev->lun);
++
++	if (lp->itlq_tbl)
++		sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK * 4, "ITLQ_TBL");
++	kfree(lp->cb_tags);
++	sym_mfree_dma(lp, sizeof(*lp), "LCB");
++}
++
+ /*
+  *  Linux entry point for info() function
+  */
+@@ -1497,7 +1465,7 @@
+ {
+ #if SYM_CONF_DMA_ADDRESSING_MODE > 0
+ #if   SYM_CONF_DMA_ADDRESSING_MODE == 1
+-#define	DMA_DAC_MASK	0x000000ffffffffffULL /* 40-bit */
++#define	DMA_DAC_MASK	DMA_40BIT_MASK
+ #elif SYM_CONF_DMA_ADDRESSING_MODE == 2
+ #define	DMA_DAC_MASK	DMA_64BIT_MASK
+ #endif
+@@ -1820,15 +1788,25 @@
+ static void __devinit
+ sym_init_device(struct pci_dev *pdev, struct sym_device *device)
+ {
+-	int i;
++	int i = 2;
++	struct pci_bus_region bus_addr;
+ 
+ 	device->host_id = SYM_SETUP_HOST_ID;
+ 	device->pdev = pdev;
+ 
+-	i = pci_get_base_address(pdev, 1, &device->mmio_base);
+-	pci_get_base_address(pdev, i, &device->ram_base);
++	pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[1]);
++	device->mmio_base = bus_addr.start;
++
++	/*
++	 * If the BAR is 64-bit, resource 2 will be occupied by the
++	 * upper 32 bits
++	 */
++	if (!pdev->resource[i].flags)
++		i++;
++	pcibios_resource_to_bus(pdev, &bus_addr, &pdev->resource[i]);
++	device->ram_base = bus_addr.start;
+ 
+-#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED
++#ifdef CONFIG_SCSI_SYM53C8XX_MMIO
+ 	if (device->mmio_base)
+ 		device->s.ioaddr = pci_iomap(pdev, 1,
+ 						pci_resource_len(pdev, 1));
+@@ -1926,6 +1904,7 @@
+ 	.queuecommand		= sym53c8xx_queue_command,
+ 	.slave_alloc		= sym53c8xx_slave_alloc,
+ 	.slave_configure	= sym53c8xx_slave_configure,
++	.slave_destroy		= sym53c8xx_slave_destroy,
+ 	.eh_abort_handler	= sym53c8xx_eh_abort_handler,
+ 	.eh_device_reset_handler = sym53c8xx_eh_device_reset_handler,
+ 	.eh_bus_reset_handler	= sym53c8xx_eh_bus_reset_handler,
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_glue.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_glue.h
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_glue.h	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_glue.h	2005-12-18 08:29:09.000000000 -0700
+@@ -68,8 +68,7 @@
+  */
+ #define	SYM_CONF_TIMER_INTERVAL		((HZ+1)/2)
+ 
+-#define SYM_OPT_HANDLE_DIR_UNKNOWN
+-#define SYM_OPT_HANDLE_DEVICE_QUEUEING
++#undef SYM_OPT_HANDLE_DEVICE_QUEUEING
+ #define SYM_OPT_LIMIT_COMMAND_REORDERING
+ 
+ /*
+@@ -268,6 +267,5 @@
+ void sym_xpt_async_sent_bdr(struct sym_hcb *np, int target);
+ int  sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp);
+ void sym_log_bus_error(struct sym_hcb *np);
+-void sym_sniff_inquiry(struct sym_hcb *np, struct scsi_cmnd *cmd, int resid);
+ 
+ #endif /* SYM_GLUE_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_hipd.c CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_hipd.c
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_hipd.c	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_hipd.c	2005-12-18 08:29:09.000000000 -0700
+@@ -40,6 +40,7 @@
+ 
+ #include <linux/slab.h>
+ #include <asm/param.h>		/* for timeouts in units of HZ */
++#include <scsi/scsi_dbg.h>
+ 
+ #include "sym_glue.h"
+ #include "sym_nvram.h"
+@@ -70,32 +71,12 @@
+ 	printf (".\n");
+ }
+ 
+-/*
+- *  Print out the content of a SCSI message.
+- */
+-static int sym_show_msg (u_char * msg)
+-{
+-	u_char i;
+-	printf ("%x",*msg);
+-	if (*msg==M_EXTENDED) {
+-		for (i=1;i<8;i++) {
+-			if (i-1>msg[1]) break;
+-			printf ("-%x",msg[i]);
+-		}
+-		return (i+1);
+-	} else if ((*msg & 0xf0) == 0x20) {
+-		printf ("-%x",msg[1]);
+-		return (2);
+-	}
+-	return (1);
+-}
+-
+ static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg)
+ {
+ 	sym_print_addr(cp->cmd, "%s: ", label);
+ 
+-	sym_show_msg(msg);
+-	printf(".\n");
++	scsi_print_msg(msg);
++	printf("\n");
+ }
+ 
+ static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg)
+@@ -103,8 +84,8 @@
+ 	struct sym_tcb *tp = &np->target[target];
+ 	dev_info(&tp->starget->dev, "%s: ", label);
+ 
+-	sym_show_msg(msg);
+-	printf(".\n");
++	scsi_print_msg(msg);
++	printf("\n");
+ }
+ 
+ /*
+@@ -635,29 +616,6 @@
+ 	}
+ }
+ 
+-
+-/*
+- * Print out the list of targets that have some flag disabled by user.
+- */
+-static void sym_print_targets_flag(struct sym_hcb *np, int mask, char *msg)
+-{
+-	int cnt;
+-	int i;
+-
+-	for (cnt = 0, i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {
+-		if (i == np->myaddr)
+-			continue;
+-		if (np->target[i].usrflags & mask) {
+-			if (!cnt++)
+-				printf("%s: %s disabled for targets",
+-					sym_name(np), msg);
+-			printf(" %d", i);
+-		}
+-	}
+-	if (cnt)
+-		printf(".\n");
+-}
+-
+ /*
+  *  Save initial settings of some IO registers.
+  *  Assumed to have been set by BIOS.
+@@ -962,7 +920,7 @@
+ 		tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED);
+ 		tp->usrtags = SYM_SETUP_MAX_TAG;
+ 
+-		sym_nvram_setup_target(np, i, nvram);
++		sym_nvram_setup_target(tp, i, nvram);
+ 
+ 		if (!tp->usrtags)
+ 			tp->usrflags &= ~SYM_TAGS_ENABLED;
+@@ -1005,13 +963,6 @@
+ 			sym_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl,
+ 			np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
+ 	}
+-	/*
+-	 *  Let user be aware of targets that have some disable flags set.
+-	 */
+-	sym_print_targets_flag(np, SYM_SCAN_BOOT_DISABLED, "SCAN AT BOOT");
+-	if (sym_verbose)
+-		sym_print_targets_flag(np, SYM_SCAN_LUNS_DISABLED,
+-				       "SCAN FOR LUNS");
+ 
+ 	return 0;
+ }
+@@ -1021,8 +972,8 @@
+  *
+  *  Has to be called with interrupts disabled.
+  */
+-#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED
+-static int sym_regtest (struct sym_hcb *np)
++#ifdef CONFIG_SCSI_SYM53C8XX_MMIO
++static int sym_regtest(struct sym_hcb *np)
+ {
+ 	register volatile u32 data;
+ 	/*
+@@ -1040,20 +991,25 @@
+ #endif
+ 		printf ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n",
+ 			(unsigned) data);
+-		return (0x10);
++		return 0x10;
+ 	}
+-	return (0);
++	return 0;
++}
++#else
++static inline int sym_regtest(struct sym_hcb *np)
++{
++	return 0;
+ }
+ #endif
+ 
+-static int sym_snooptest (struct sym_hcb *np)
++static int sym_snooptest(struct sym_hcb *np)
+ {
+-	u32	sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat;
+-	int	i, err=0;
+-#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED
+-	err |= sym_regtest (np);
+-	if (err) return (err);
+-#endif
++	u32 sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat;
++	int i, err;
++
++	err = sym_regtest(np);
++	if (err)
++		return err;
+ restart_test:
+ 	/*
+ 	 *  Enable Master Parity Checking as we intend 
+@@ -1142,7 +1098,7 @@
+ 		err |= 4;
+ 	}
+ 
+-	return (err);
++	return err;
+ }
+ 
+ /*
+@@ -3654,7 +3610,7 @@
+ 	 *  If result is dp_sg = SYM_CONF_MAX_SG, then we are at the 
+ 	 *  end of the data.
+ 	 */
+-	tmp = scr_to_cpu(sym_goalp(cp));
++	tmp = scr_to_cpu(cp->goalp);
+ 	dp_sg = SYM_CONF_MAX_SG;
+ 	if (dp_scr != tmp)
+ 		dp_sg -= (tmp - 8 - (int)dp_scr) / (2*4);
+@@ -3761,7 +3717,7 @@
+ 	 *  And our alchemy:) allows to easily calculate the data 
+ 	 *  script address we want to return for the next data phase.
+ 	 */
+-	dp_ret = cpu_to_scr(sym_goalp(cp));
++	dp_ret = cpu_to_scr(cp->goalp);
+ 	dp_ret = dp_ret - 8 - (SYM_CONF_MAX_SG - dp_sg) * (2*4);
+ 
+ 	/*
+@@ -3857,7 +3813,7 @@
+ 	 *  If all data has been transferred,
+ 	 *  there is no residual.
+ 	 */
+-	if (cp->phys.head.lastp == sym_goalp(cp))
++	if (cp->phys.head.lastp == cp->goalp)
+ 		return resid;
+ 
+ 	/*
+@@ -4664,30 +4620,7 @@
+ 		goto out;
+ 	cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
+ 
+-#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
+-	/*
+-	 *  If the LCB is not yet available and the LUN
+-	 *  has been probed ok, try to allocate the LCB.
+-	 */
+-	if (!lp && sym_is_bit(tp->lun_map, ln)) {
+-		lp = sym_alloc_lcb(np, tn, ln);
+-		if (!lp)
+-			goto out_free;
+-	}
+-#endif
+-
+-	/*
+-	 *  If the LCB is not available here, then the 
+-	 *  logical unit is not yet discovered. For those 
+-	 *  ones only accept 1 SCSI IO per logical unit, 
+-	 *  since we cannot allow disconnections.
+-	 */
+-	if (!lp) {
+-		if (!sym_is_bit(tp->busy0_map, ln))
+-			sym_set_bit(tp->busy0_map, ln);
+-		else
+-			goto out_free;
+-	} else {
++	{
+ 		/*
+ 		 *  If we have been asked for a tagged command.
+ 		 */
+@@ -4696,7 +4629,8 @@
+ 			 *  Debugging purpose.
+ 			 */
+ #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
+-			assert(lp->busy_itl == 0);
++			if (lp->busy_itl != 0)
++				goto out_free;
+ #endif
+ 			/*
+ 			 *  Allocate resources for tags if not yet.
+@@ -4741,7 +4675,8 @@
+ 			 *  Debugging purpose.
+ 			 */
+ #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
+-			assert(lp->busy_itl == 0 && lp->busy_itlq == 0);
++			if (lp->busy_itl != 0 || lp->busy_itlq != 0)
++				goto out_free;
+ #endif
+ 			/*
+ 			 *  Count this nexus for this LUN.
+@@ -4840,12 +4775,6 @@
+ 			lp->head.resel_sa =
+ 				cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
+ 	}
+-	/*
+-	 *  Otherwise, we only accept 1 IO per LUN.
+-	 *  Clear the bit that keeps track of this IO.
+-	 */
+-	else
+-		sym_clr_bit(tp->busy0_map, cp->lun);
+ 
+ 	/*
+ 	 *  We donnot queue more than 1 ccb per target 
+@@ -4997,20 +4926,7 @@
+ struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
+ {
+ 	struct sym_tcb *tp = &np->target[tn];
+-	struct sym_lcb *lp = sym_lp(tp, ln);
+-
+-	/*
+-	 *  Already done, just return.
+-	 */
+-	if (lp)
+-		return lp;
+-
+-	/*
+-	 *  Donnot allow LUN control block 
+-	 *  allocation for not probed LUNs.
+-	 */
+-	if (!sym_is_bit(tp->lun_map, ln))
+-		return NULL;
++	struct sym_lcb *lp = NULL;
+ 
+ 	/*
+ 	 *  Initialize the target control block if not yet.
+@@ -5082,13 +4998,7 @@
+ 	lp->started_max   = SYM_CONF_MAX_TASK;
+ 	lp->started_limit = SYM_CONF_MAX_TASK;
+ #endif
+-	/*
+-	 *  If we are busy, count the IO.
+-	 */
+-	if (sym_is_bit(tp->busy0_map, ln)) {
+-		lp->busy_itl = 1;
+-		sym_clr_bit(tp->busy0_map, ln);
+-	}
++
+ fail:
+ 	return lp;
+ }
+@@ -5103,12 +5013,6 @@
+ 	int i;
+ 
+ 	/*
+-	 *  If LCB not available, try to allocate it.
+-	 */
+-	if (!lp && !(lp = sym_alloc_lcb(np, tn, ln)))
+-		goto fail;
+-
+-	/*
+ 	 *  Allocate the task table and and the tag allocation 
+ 	 *  circular buffer. We want both or none.
+ 	 */
+@@ -5481,8 +5385,7 @@
+ 	/*
+ 	 *  Donnot start more than 1 command after an error.
+ 	 */
+-	if (lp)
+-		sym_start_next_ccbs(np, lp, 1);
++	sym_start_next_ccbs(np, lp, 1);
+ #endif
+ }
+ 
+@@ -5521,17 +5424,11 @@
+ 	lp = sym_lp(tp, cp->lun);
+ 
+ 	/*
+-	 *  Assume device discovered on first success.
+-	 */
+-	if (!lp)
+-		sym_set_bit(tp->lun_map, cp->lun);
+-
+-	/*
+ 	 *  If all data have been transferred, given than no
+ 	 *  extended error did occur, there is no residual.
+ 	 */
+ 	resid = 0;
+-	if (cp->phys.head.lastp != sym_goalp(cp))
++	if (cp->phys.head.lastp != cp->goalp)
+ 		resid = sym_compute_residual(np, cp);
+ 
+ 	/*
+@@ -5551,15 +5448,6 @@
+ 	 */
+ 	sym_set_cam_result_ok(cp, cmd, resid);
+ 
+-#ifdef	SYM_OPT_SNIFF_INQUIRY
+-	/*
+-	 *  On standard INQUIRY response (EVPD and CmDt 
+-	 *  not set), sniff out device capabilities.
+-	 */
+-	if (cp->cdb_buf[0] == INQUIRY && !(cp->cdb_buf[1] & 0x3))
+-		sym_sniff_inquiry(np, cmd, resid);
+-#endif
+-
+ #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
+ 	/*
+ 	 *  If max number of started ccbs had been reduced,
+@@ -5587,7 +5475,7 @@
+ 	/*
+ 	 *  Requeue a couple of awaiting scsi commands.
+ 	 */
+-	if (lp && !sym_que_empty(&lp->waiting_ccbq))
++	if (!sym_que_empty(&lp->waiting_ccbq))
+ 		sym_start_next_ccbs(np, lp, 2);
+ #endif
+ 	/*
+@@ -5830,8 +5718,7 @@
+ 	SYM_QUEHEAD *qp;
+ 	struct sym_ccb *cp;
+ 	struct sym_tcb *tp;
+-	struct sym_lcb *lp;
+-	int target, lun;
++	int target;
+ 
+ 	if (np->scriptz0)
+ 		sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0");
+@@ -5857,16 +5744,6 @@
+ 
+ 	for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) {
+ 		tp = &np->target[target];
+-		for (lun = 0 ; lun < SYM_CONF_MAX_LUN ; lun++) {
+-			lp = sym_lp(tp, lun);
+-			if (!lp)
+-				continue;
+-			if (lp->itlq_tbl)
+-				sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4,
+-				       "ITLQ_TBL");
+-			kfree(lp->cb_tags);
+-			sym_mfree_dma(lp, sizeof(*lp), "LCB");
+-		}
+ #if SYM_CONF_MAX_LUN > 1
+ 		kfree(tp->lunmp);
+ #endif 
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_hipd.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_hipd.h
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_hipd.h	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_hipd.h	2005-12-18 08:29:09.000000000 -0700
+@@ -48,12 +48,6 @@
+  *  They may be defined in platform specific headers, if they 
+  *  are useful.
+  *
+- *    SYM_OPT_HANDLE_DIR_UNKNOWN
+- *        When this option is set, the SCRIPTS used by the driver 
+- *        are able to handle SCSI transfers with direction not 
+- *        supplied by user.
+- *        (set for Linux-2.0.X)
+- *
+  *    SYM_OPT_HANDLE_DEVICE_QUEUEING
+  *        When this option is set, the driver will use a queue per 
+  *        device and handle QUEUE FULL status requeuing internally.
+@@ -64,7 +58,6 @@
+  *        (set for Linux)
+  */
+ #if 0
+-#define SYM_OPT_HANDLE_DIR_UNKNOWN
+ #define SYM_OPT_HANDLE_DEVICE_QUEUEING
+ #define SYM_OPT_LIMIT_COMMAND_REORDERING
+ #endif
+@@ -416,19 +409,6 @@
+ 	struct sym_lcb **lunmp;		/* Other LCBs [1..MAX_LUN]	*/
+ #endif
+ 
+-	/*
+-	 *  Bitmap that tells about LUNs that succeeded at least 
+-	 *  1 IO and therefore assumed to be a real device.
+-	 *  Avoid useless allocation of the LCB structure.
+-	 */
+-	u32	lun_map[(SYM_CONF_MAX_LUN+31)/32];
+-
+-	/*
+-	 *  Bitmap that tells about LUNs that haven't yet an LCB 
+-	 *  allocated (not discovered or LCB allocation failed).
+-	 */
+-	u32	busy0_map[(SYM_CONF_MAX_LUN+31)/32];
+-
+ #ifdef	SYM_HAVE_STCB
+ 	/*
+ 	 *  O/S specific data structure.
+@@ -454,8 +434,10 @@
+ 	 *  Other user settable limits and options.
+ 	 *  These limits are read from the NVRAM if present.
+ 	 */
+-	u_char	usrflags;
+-	u_short	usrtags;
++	unsigned char	usrflags;
++	unsigned char	usr_period;
++	unsigned char	usr_width;
++	unsigned short	usrtags;
+ 	struct scsi_target *starget;
+ };
+ 
+@@ -672,9 +654,6 @@
+ 	 */
+ 	u32	savep;		/* Jump address to saved data pointer	*/
+ 	u32	lastp;		/* SCRIPTS address at end of data	*/
+-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
+-	u32	wlastp;
+-#endif
+ 
+ 	/*
+ 	 *  Status fields.
+@@ -804,9 +783,6 @@
+ 	SYM_QUEHEAD link_ccbq;	/* Link to free/busy CCB queue	*/
+ 	u32	startp;		/* Initial data pointer		*/
+ 	u32	goalp;		/* Expected last data pointer	*/
+-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
+-	u32	wgoalp;
+-#endif
+ 	int	ext_sg;		/* Extreme data pointer, used	*/
+ 	int	ext_ofs;	/*  to calculate the residual.	*/
+ #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
+@@ -821,12 +797,6 @@
+ 
+ #define CCB_BA(cp,lbl)	cpu_to_scr(cp->ccb_ba + offsetof(struct sym_ccb, lbl))
+ 
+-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
+-#define	sym_goalp(cp) ((cp->host_flags & HF_DATA_IN) ? cp->goalp : cp->wgoalp)
+-#else
+-#define	sym_goalp(cp) (cp->goalp)
+-#endif
+-
+ typedef struct device *m_pool_ident_t;
+ 
+ /*
+@@ -1077,9 +1047,10 @@
+ void sym_print_xerr(struct scsi_cmnd *cmd, int x_status);
+ int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int);
+ struct sym_chip *sym_lookup_chip_table(u_short device_id, u_char revision);
+-void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp);
+ #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
+ void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn);
++#else
++void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp);
+ #endif
+ void sym_start_up(struct sym_hcb *np, int reason);
+ void sym_interrupt(struct sym_hcb *np);
+@@ -1136,71 +1107,6 @@
+ #endif
+ 
+ /*
+- *  Set up data pointers used by SCRIPTS.
+- *  Called from O/S specific code.
+- */
+-static inline void sym_setup_data_pointers(struct sym_hcb *np,
+-		struct sym_ccb *cp, int dir)
+-{
+-	u32 lastp, goalp;
+-
+-	/*
+-	 *  No segments means no data.
+-	 */
+-	if (!cp->segments)
+-		dir = DMA_NONE;
+-
+-	/*
+-	 *  Set the data pointer.
+-	 */
+-	switch(dir) {
+-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
+-	case DMA_BIDIRECTIONAL:
+-#endif
+-	case DMA_TO_DEVICE:
+-		goalp = SCRIPTA_BA(np, data_out2) + 8;
+-		lastp = goalp - 8 - (cp->segments * (2*4));
+-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
+-		cp->wgoalp = cpu_to_scr(goalp);
+-		if (dir != DMA_BIDIRECTIONAL)
+-			break;
+-		cp->phys.head.wlastp = cpu_to_scr(lastp);
+-		/* fall through */
+-#else
+-		break;
+-#endif
+-	case DMA_FROM_DEVICE:
+-		cp->host_flags |= HF_DATA_IN;
+-		goalp = SCRIPTA_BA(np, data_in2) + 8;
+-		lastp = goalp - 8 - (cp->segments * (2*4));
+-		break;
+-	case DMA_NONE:
+-	default:
+-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
+-		cp->host_flags |= HF_DATA_IN;
+-#endif
+-		lastp = goalp = SCRIPTB_BA(np, no_data);
+-		break;
+-	}
+-
+-	/*
+-	 *  Set all pointers values needed by SCRIPTS.
+-	 */
+-	cp->phys.head.lastp = cpu_to_scr(lastp);
+-	cp->phys.head.savep = cpu_to_scr(lastp);
+-	cp->startp	    = cp->phys.head.savep;
+-	cp->goalp	    = cpu_to_scr(goalp);
+-
+-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
+-	/*
+-	 *  If direction is unknown, start at data_io.
+-	 */
+-	if (dir == DMA_BIDIRECTIONAL)
+-		cp->phys.head.savep = cpu_to_scr(SCRIPTB_BA(np, data_io));
+-#endif
+-}
+-
+-/*
+  *  MEMORY ALLOCATOR.
+  */
+ 
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_malloc.c CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_malloc.c
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_malloc.c	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_malloc.c	2005-09-27 06:03:22.000000000 -0600
+@@ -37,11 +37,7 @@
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
+ 
+-#ifdef __FreeBSD__
+-#include <dev/sym/sym_glue.h>
+-#else
+ #include "sym_glue.h"
+-#endif
+ 
+ /*
+  *  Simple power of two buddy-like generic allocator.
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_nvram.c CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_nvram.c
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_nvram.c	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_nvram.c	2005-12-12 09:00:09.000000000 -0700
+@@ -92,29 +92,32 @@
+  *  Get target set-up from Symbios format NVRAM.
+  */
+ static void
+-sym_Symbios_setup_target(struct sym_hcb *np, int target, Symbios_nvram *nvram)
++sym_Symbios_setup_target(struct sym_tcb *tp, int target, Symbios_nvram *nvram)
+ {
+-	struct sym_tcb *tp = &np->target[target];
+ 	Symbios_target *tn = &nvram->target[target];
+ 
+-	tp->usrtags =
+-		(tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? SYM_SETUP_MAX_TAG : 0;
+-
++	if (!(tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED))
++		tp->usrtags = 0;
+ 	if (!(tn->flags & SYMBIOS_DISCONNECT_ENABLE))
+ 		tp->usrflags &= ~SYM_DISC_ENABLED;
+ 	if (!(tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME))
+ 		tp->usrflags |= SYM_SCAN_BOOT_DISABLED;
+ 	if (!(tn->flags & SYMBIOS_SCAN_LUNS))
+ 		tp->usrflags |= SYM_SCAN_LUNS_DISABLED;
++	tp->usr_period = (tn->sync_period + 3) / 4;
++	tp->usr_width = (tn->bus_width == 0x8) ? 0 : 1;
+ }
+ 
++static const unsigned char Tekram_sync[16] = {
++	25, 31, 37, 43, 50, 62, 75, 125, 12, 15, 18, 21, 6, 7, 9, 10
++};
++
+ /*
+  *  Get target set-up from Tekram format NVRAM.
+  */
+ static void
+-sym_Tekram_setup_target(struct sym_hcb *np, int target, Tekram_nvram *nvram)
++sym_Tekram_setup_target(struct sym_tcb *tp, int target, Tekram_nvram *nvram)
+ {
+-	struct sym_tcb *tp = &np->target[target];
+ 	struct Tekram_target *tn = &nvram->target[target];
+ 
+ 	if (tn->flags & TEKRAM_TAGGED_COMMANDS) {
+@@ -124,22 +127,22 @@
+ 	if (tn->flags & TEKRAM_DISCONNECT_ENABLE)
+ 		tp->usrflags |= SYM_DISC_ENABLED;
+  
+-	/* If any device does not support parity, we will not use this option */
+-	if (!(tn->flags & TEKRAM_PARITY_CHECK))
+-		np->rv_scntl0  &= ~0x0a; /* SCSI parity checking disabled */
++	if (tn->flags & TEKRAM_SYNC_NEGO)
++		tp->usr_period = Tekram_sync[tn->sync_index & 0xf];
++	tp->usr_width = (tn->flags & TEKRAM_WIDE_NEGO) ? 1 : 0;
+ }
+ 
+ /*
+  *  Get target setup from NVRAM.
+  */
+-void sym_nvram_setup_target(struct sym_hcb *np, int target, struct sym_nvram *nvp)
++void sym_nvram_setup_target(struct sym_tcb *tp, int target, struct sym_nvram *nvp)
+ {
+ 	switch (nvp->type) {
+ 	case SYM_SYMBIOS_NVRAM:
+-		sym_Symbios_setup_target(np, target, &nvp->data.Symbios);
++		sym_Symbios_setup_target(tp, target, &nvp->data.Symbios);
+ 		break;
+ 	case SYM_TEKRAM_NVRAM:
+-		sym_Tekram_setup_target(np, target, &nvp->data.Tekram);
++		sym_Tekram_setup_target(tp, target, &nvp->data.Tekram);
+ 		break;
+ 	default:
+ 		break;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_nvram.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_nvram.h
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_2/sym_nvram.h	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_2/sym_nvram.h	2005-12-12 09:00:09.000000000 -0700
+@@ -194,12 +194,12 @@
+ 
+ #if SYM_CONF_NVRAM_SUPPORT
+ void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram);
+-void sym_nvram_setup_target (struct sym_hcb *np, int target, struct sym_nvram *nvp);
++void sym_nvram_setup_target (struct sym_tcb *tp, int target, struct sym_nvram *nvp);
+ int sym_read_nvram (struct sym_device *np, struct sym_nvram *nvp);
+ char *sym_nvram_type(struct sym_nvram *nvp);
+ #else
+ static inline void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) { }
+-static inline void sym_nvram_setup_target(struct sym_hcb *np, struct sym_nvram *nvram) { }
++static inline void sym_nvram_setup_target(struct sym_tcb *tp, struct sym_nvram *nvram) { }
+ static inline int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp)
+ {
+ 	nvp->type = 0;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_comm.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_comm.h
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_comm.h	2005-12-27 13:25:48.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_comm.h	1969-12-31 17:00:00.000000000 -0700
+@@ -1,792 +0,0 @@
+-/******************************************************************************
+-**  High Performance device driver for the Symbios 53C896 controller.
+-**
+-**  Copyright (C) 1998-2001  Gerard Roudier <groudier at free.fr>
+-**
+-**  This driver also supports all the Symbios 53C8XX controller family, 
+-**  except 53C810 revisions < 16, 53C825 revisions < 16 and all 
+-**  revisions of 53C815 controllers.
+-**
+-**  This driver is based on the Linux port of the FreeBSD ncr driver.
+-** 
+-**  Copyright (C) 1994  Wolfgang Stanglmeier
+-**  
+-**-----------------------------------------------------------------------------
+-**  
+-**  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.
+-**
+-**-----------------------------------------------------------------------------
+-**
+-**  The Linux port of the FreeBSD ncr driver has been achieved in 
+-**  november 1995 by:
+-**
+-**          Gerard Roudier              <groudier at free.fr>
+-**
+-**  Being given that this driver originates from the FreeBSD version, and
+-**  in order to keep synergy on both, any suggested enhancements and corrections
+-**  received on Linux are automatically a potential candidate for the FreeBSD 
+-**  version.
+-**
+-**  The original driver has been written for 386bsd and FreeBSD by
+-**          Wolfgang Stanglmeier        <wolf at cologne.de>
+-**          Stefan Esser                <se at mi.Uni-Koeln.de>
+-**
+-**-----------------------------------------------------------------------------
+-**
+-**  Major contributions:
+-**  --------------------
+-**
+-**  NVRAM detection and reading.
+-**    Copyright (C) 1997 Richard Waltham <dormouse at farsrobt.demon.co.uk>
+-**
+-*******************************************************************************
+-*/
+-
+-/*==========================================================
+-**
+-**	Debugging tags
+-**
+-**==========================================================
+-*/
+-
+-#define DEBUG_ALLOC    (0x0001)
+-#define DEBUG_PHASE    (0x0002)
+-#define DEBUG_QUEUE    (0x0008)
+-#define DEBUG_RESULT   (0x0010)
+-#define DEBUG_POINTER  (0x0020)
+-#define DEBUG_SCRIPT   (0x0040)
+-#define DEBUG_TINY     (0x0080)
+-#define DEBUG_TIMING   (0x0100)
+-#define DEBUG_NEGO     (0x0200)
+-#define DEBUG_TAGS     (0x0400)
+-#define DEBUG_SCATTER  (0x0800)
+-#define DEBUG_IC        (0x1000)
+-
+-/*
+-**    Enable/Disable debug messages.
+-**    Can be changed at runtime too.
+-*/
+-
+-#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
+-static int ncr_debug = SCSI_NCR_DEBUG_FLAGS;
+-	#define DEBUG_FLAGS ncr_debug
+-#else
+-	#define DEBUG_FLAGS	SCSI_NCR_DEBUG_FLAGS
+-#endif
+-
+-static inline struct list_head *ncr_list_pop(struct list_head *head)
+-{
+-	if (!list_empty(head)) {
+-		struct list_head *elem = head->next;
+-
+-		list_del(elem);
+-		return elem;
+-	}
+-
+-	return NULL;
+-}
+-
+-#ifdef __sparc__
+-#include <asm/irq.h>
+-#endif
+-
+-/*==========================================================
+-**
+-**	Simple power of two buddy-like allocator.
+-**
+-**	This simple code is not intended to be fast, but to 
+-**	provide power of 2 aligned memory allocations.
+-**	Since the SCRIPTS processor only supplies 8 bit 
+-**	arithmetic, this allocator allows simple and fast 
+-**	address calculations  from the SCRIPTS code.
+-**	In addition, cache line alignment is guaranteed for 
+-**	power of 2 cache line size.
+-**	Enhanced in linux-2.3.44 to provide a memory pool 
+-**	per pcidev to support dynamic dma mapping. (I would 
+-**	have preferred a real bus astraction, btw).
+-**
+-**==========================================================
+-*/
+-
+-#define MEMO_SHIFT	4	/* 16 bytes minimum memory chunk */
+-#if PAGE_SIZE >= 8192
+-#define MEMO_PAGE_ORDER	0	/* 1 PAGE  maximum */
+-#else
+-#define MEMO_PAGE_ORDER	1	/* 2 PAGES maximum */
+-#endif
+-#define MEMO_FREE_UNUSED	/* Free unused pages immediately */
+-#define MEMO_WARN	1
+-#define MEMO_GFP_FLAGS	GFP_ATOMIC
+-#define MEMO_CLUSTER_SHIFT	(PAGE_SHIFT+MEMO_PAGE_ORDER)
+-#define MEMO_CLUSTER_SIZE	(1UL << MEMO_CLUSTER_SHIFT)
+-#define MEMO_CLUSTER_MASK	(MEMO_CLUSTER_SIZE-1)
+-
+-typedef u_long m_addr_t;	/* Enough bits to bit-hack addresses */
+-typedef struct device *m_bush_t;	/* Something that addresses DMAable */
+-
+-typedef struct m_link {		/* Link between free memory chunks */
+-	struct m_link *next;
+-} m_link_s;
+-
+-typedef struct m_vtob {		/* Virtual to Bus address translation */
+-	struct m_vtob *next;
+-	m_addr_t vaddr;
+-	m_addr_t baddr;
+-} m_vtob_s;
+-#define VTOB_HASH_SHIFT		5
+-#define VTOB_HASH_SIZE		(1UL << VTOB_HASH_SHIFT)
+-#define VTOB_HASH_MASK		(VTOB_HASH_SIZE-1)
+-#define VTOB_HASH_CODE(m)	\
+-	((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK)
+-
+-typedef struct m_pool {		/* Memory pool of a given kind */
+-	m_bush_t bush;
+-	m_addr_t (*getp)(struct m_pool *);
+-	void (*freep)(struct m_pool *, m_addr_t);
+-	int nump;
+-	m_vtob_s *(vtob[VTOB_HASH_SIZE]);
+-	struct m_pool *next;
+-	struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1];
+-} m_pool_s;
+-
+-static void *___m_alloc(m_pool_s *mp, int size)
+-{
+-	int i = 0;
+-	int s = (1 << MEMO_SHIFT);
+-	int j;
+-	m_addr_t a;
+-	m_link_s *h = mp->h;
+-
+-	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
+-		return NULL;
+-
+-	while (size > s) {
+-		s <<= 1;
+-		++i;
+-	}
+-
+-	j = i;
+-	while (!h[j].next) {
+-		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
+-			h[j].next = (m_link_s *)mp->getp(mp);
+-			if (h[j].next)
+-				h[j].next->next = NULL;
+-			break;
+-		}
+-		++j;
+-		s <<= 1;
+-	}
+-	a = (m_addr_t) h[j].next;
+-	if (a) {
+-		h[j].next = h[j].next->next;
+-		while (j > i) {
+-			j -= 1;
+-			s >>= 1;
+-			h[j].next = (m_link_s *) (a+s);
+-			h[j].next->next = NULL;
+-		}
+-	}
+-#ifdef DEBUG
+-	printk("___m_alloc(%d) = %p\n", size, (void *) a);
+-#endif
+-	return (void *) a;
+-}
+-
+-static void ___m_free(m_pool_s *mp, void *ptr, int size)
+-{
+-	int i = 0;
+-	int s = (1 << MEMO_SHIFT);
+-	m_link_s *q;
+-	m_addr_t a, b;
+-	m_link_s *h = mp->h;
+-
+-#ifdef DEBUG
+-	printk("___m_free(%p, %d)\n", ptr, size);
+-#endif
+-
+-	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
+-		return;
+-
+-	while (size > s) {
+-		s <<= 1;
+-		++i;
+-	}
+-
+-	a = (m_addr_t) ptr;
+-
+-	while (1) {
+-#ifdef MEMO_FREE_UNUSED
+-		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
+-			mp->freep(mp, a);
+-			break;
+-		}
+-#endif
+-		b = a ^ s;
+-		q = &h[i];
+-		while (q->next && q->next != (m_link_s *) b) {
+-			q = q->next;
+-		}
+-		if (!q->next) {
+-			((m_link_s *) a)->next = h[i].next;
+-			h[i].next = (m_link_s *) a;
+-			break;
+-		}
+-		q->next = q->next->next;
+-		a = a & b;
+-		s <<= 1;
+-		++i;
+-	}
+-}
+-
+-static DEFINE_SPINLOCK(ncr53c8xx_lock);
+-
+-static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags)
+-{
+-	void *p;
+-
+-	p = ___m_alloc(mp, size);
+-
+-	if (DEBUG_FLAGS & DEBUG_ALLOC)
+-		printk ("new %-10s[%4d] @%p.\n", name, size, p);
+-
+-	if (p)
+-		memset(p, 0, size);
+-	else if (uflags & MEMO_WARN)
+-		printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size);
+-
+-	return p;
+-}
+-
+-#define __m_calloc(mp, s, n)	__m_calloc2(mp, s, n, MEMO_WARN)
+-
+-static void __m_free(m_pool_s *mp, void *ptr, int size, char *name)
+-{
+-	if (DEBUG_FLAGS & DEBUG_ALLOC)
+-		printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr);
+-
+-	___m_free(mp, ptr, size);
+-
+-}
+-
+-/*
+- * With pci bus iommu support, we use a default pool of unmapped memory 
+- * for memory we donnot need to DMA from/to and one pool per pcidev for 
+- * memory accessed by the PCI chip. `mp0' is the default not DMAable pool.
+- */
+-
+-static m_addr_t ___mp0_getp(m_pool_s *mp)
+-{
+-	m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER);
+-	if (m)
+-		++mp->nump;
+-	return m;
+-}
+-
+-static void ___mp0_freep(m_pool_s *mp, m_addr_t m)
+-{
+-	free_pages(m, MEMO_PAGE_ORDER);
+-	--mp->nump;
+-}
+-
+-static m_pool_s mp0 = {NULL, ___mp0_getp, ___mp0_freep};
+-
+-/*
+- * DMAable pools.
+- */
+-
+-/*
+- * With pci bus iommu support, we maintain one pool per pcidev and a 
+- * hashed reverse table for virtual to bus physical address translations.
+- */
+-static m_addr_t ___dma_getp(m_pool_s *mp)
+-{
+-	m_addr_t vp;
+-	m_vtob_s *vbp;
+-
+-	vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");
+-	if (vbp) {
+-		dma_addr_t daddr;
+-		vp = (m_addr_t) dma_alloc_coherent(mp->bush,
+-						PAGE_SIZE<<MEMO_PAGE_ORDER,
+-						&daddr, GFP_ATOMIC);
+-		if (vp) {
+-			int hc = VTOB_HASH_CODE(vp);
+-			vbp->vaddr = vp;
+-			vbp->baddr = daddr;
+-			vbp->next = mp->vtob[hc];
+-			mp->vtob[hc] = vbp;
+-			++mp->nump;
+-			return vp;
+-		}
+-	}
+-	if (vbp)
+-		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
+-	return 0;
+-}
+-
+-static void ___dma_freep(m_pool_s *mp, m_addr_t m)
+-{
+-	m_vtob_s **vbpp, *vbp;
+-	int hc = VTOB_HASH_CODE(m);
+-
+-	vbpp = &mp->vtob[hc];
+-	while (*vbpp && (*vbpp)->vaddr != m)
+-		vbpp = &(*vbpp)->next;
+-	if (*vbpp) {
+-		vbp = *vbpp;
+-		*vbpp = (*vbpp)->next;
+-		dma_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
+-				  (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
+-		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
+-		--mp->nump;
+-	}
+-}
+-
+-static inline m_pool_s *___get_dma_pool(m_bush_t bush)
+-{
+-	m_pool_s *mp;
+-	for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next);
+-	return mp;
+-}
+-
+-static m_pool_s *___cre_dma_pool(m_bush_t bush)
+-{
+-	m_pool_s *mp;
+-	mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL");
+-	if (mp) {
+-		memset(mp, 0, sizeof(*mp));
+-		mp->bush = bush;
+-		mp->getp = ___dma_getp;
+-		mp->freep = ___dma_freep;
+-		mp->next = mp0.next;
+-		mp0.next = mp;
+-	}
+-	return mp;
+-}
+-
+-static void ___del_dma_pool(m_pool_s *p)
+-{
+-	struct m_pool **pp = &mp0.next;
+-
+-	while (*pp && *pp != p)
+-		pp = &(*pp)->next;
+-	if (*pp) {
+-		*pp = (*pp)->next;
+-		__m_free(&mp0, p, sizeof(*p), "MPOOL");
+-	}
+-}
+-
+-static void *__m_calloc_dma(m_bush_t bush, int size, char *name)
+-{
+-	u_long flags;
+-	struct m_pool *mp;
+-	void *m = NULL;
+-
+-	spin_lock_irqsave(&ncr53c8xx_lock, flags);
+-	mp = ___get_dma_pool(bush);
+-	if (!mp)
+-		mp = ___cre_dma_pool(bush);
+-	if (mp)
+-		m = __m_calloc(mp, size, name);
+-	if (mp && !mp->nump)
+-		___del_dma_pool(mp);
+-	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
+-
+-	return m;
+-}
+-
+-static void __m_free_dma(m_bush_t bush, void *m, int size, char *name)
+-{
+-	u_long flags;
+-	struct m_pool *mp;
+-
+-	spin_lock_irqsave(&ncr53c8xx_lock, flags);
+-	mp = ___get_dma_pool(bush);
+-	if (mp)
+-		__m_free(mp, m, size, name);
+-	if (mp && !mp->nump)
+-		___del_dma_pool(mp);
+-	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
+-}
+-
+-static m_addr_t __vtobus(m_bush_t bush, void *m)
+-{
+-	u_long flags;
+-	m_pool_s *mp;
+-	int hc = VTOB_HASH_CODE(m);
+-	m_vtob_s *vp = NULL;
+-	m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK;
+-
+-	spin_lock_irqsave(&ncr53c8xx_lock, flags);
+-	mp = ___get_dma_pool(bush);
+-	if (mp) {
+-		vp = mp->vtob[hc];
+-		while (vp && (m_addr_t) vp->vaddr != a)
+-			vp = vp->next;
+-	}
+-	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
+-	return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;
+-}
+-
+-#define _m_calloc_dma(np, s, n)		__m_calloc_dma(np->dev, s, n)
+-#define _m_free_dma(np, p, s, n)	__m_free_dma(np->dev, p, s, n)
+-#define m_calloc_dma(s, n)		_m_calloc_dma(np, s, n)
+-#define m_free_dma(p, s, n)		_m_free_dma(np, p, s, n)
+-#define _vtobus(np, p)			__vtobus(np->dev, p)
+-#define vtobus(p)			_vtobus(np, p)
+-
+-/*
+- *  Deal with DMA mapping/unmapping.
+- */
+-
+-/* To keep track of the dma mapping (sg/single) that has been set */
+-#define __data_mapped	SCp.phase
+-#define __data_mapping	SCp.have_data_in
+-
+-static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd)
+-{
+-	switch(cmd->__data_mapped) {
+-	case 2:
+-		dma_unmap_sg(dev, cmd->buffer, cmd->use_sg,
+-				cmd->sc_data_direction);
+-		break;
+-	case 1:
+-		dma_unmap_single(dev, cmd->__data_mapping,
+-				 cmd->request_bufflen,
+-				 cmd->sc_data_direction);
+-		break;
+-	}
+-	cmd->__data_mapped = 0;
+-}
+-
+-static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd)
+-{
+-	dma_addr_t mapping;
+-
+-	if (cmd->request_bufflen == 0)
+-		return 0;
+-
+-	mapping = dma_map_single(dev, cmd->request_buffer,
+-				 cmd->request_bufflen,
+-				 cmd->sc_data_direction);
+-	cmd->__data_mapped = 1;
+-	cmd->__data_mapping = mapping;
+-
+-	return mapping;
+-}
+-
+-static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
+-{
+-	int use_sg;
+-
+-	if (cmd->use_sg == 0)
+-		return 0;
+-
+-	use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg,
+-			cmd->sc_data_direction);
+-	cmd->__data_mapped = 2;
+-	cmd->__data_mapping = use_sg;
+-
+-	return use_sg;
+-}
+-
+-#define unmap_scsi_data(np, cmd)	__unmap_scsi_data(np->dev, cmd)
+-#define map_scsi_single_data(np, cmd)	__map_scsi_single_data(np->dev, cmd)
+-#define map_scsi_sg_data(np, cmd)	__map_scsi_sg_data(np->dev, cmd)
+-
+-/*==========================================================
+-**
+-**	Driver setup.
+-**
+-**	This structure is initialized from linux config 
+-**	options. It can be overridden at boot-up by the boot 
+-**	command line.
+-**
+-**==========================================================
+-*/
+-static struct ncr_driver_setup
+-	driver_setup			= SCSI_NCR_DRIVER_SETUP;
+-
+-#ifdef	SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
+-static struct ncr_driver_setup
+-	driver_safe_setup __initdata	= SCSI_NCR_DRIVER_SAFE_SETUP;
+-#endif
+-
+-#define initverbose (driver_setup.verbose)
+-#define bootverbose (np->verbose)
+-
+-
+-/*===================================================================
+-**
+-**	Driver setup from the boot command line
+-**
+-**===================================================================
+-*/
+-
+-#ifdef MODULE
+-#define	ARG_SEP	' '
+-#else
+-#define	ARG_SEP	','
+-#endif
+-
+-#define OPT_TAGS		1
+-#define OPT_MASTER_PARITY	2
+-#define OPT_SCSI_PARITY		3
+-#define OPT_DISCONNECTION	4
+-#define OPT_SPECIAL_FEATURES	5
+-#define OPT_UNUSED_1		6
+-#define OPT_FORCE_SYNC_NEGO	7
+-#define OPT_REVERSE_PROBE	8
+-#define OPT_DEFAULT_SYNC	9
+-#define OPT_VERBOSE		10
+-#define OPT_DEBUG		11
+-#define OPT_BURST_MAX		12
+-#define OPT_LED_PIN		13
+-#define OPT_MAX_WIDE		14
+-#define OPT_SETTLE_DELAY	15
+-#define OPT_DIFF_SUPPORT	16
+-#define OPT_IRQM		17
+-#define OPT_PCI_FIX_UP		18
+-#define OPT_BUS_CHECK		19
+-#define OPT_OPTIMIZE		20
+-#define OPT_RECOVERY		21
+-#define OPT_SAFE_SETUP		22
+-#define OPT_USE_NVRAM		23
+-#define OPT_EXCLUDE		24
+-#define OPT_HOST_ID		25
+-
+-#ifdef SCSI_NCR_IARB_SUPPORT
+-#define OPT_IARB		26
+-#endif
+-
+-static char setup_token[] __initdata = 
+-	"tags:"   "mpar:"
+-	"spar:"   "disc:"
+-	"specf:"  "ultra:"
+-	"fsn:"    "revprob:"
+-	"sync:"   "verb:"
+-	"debug:"  "burst:"
+-	"led:"    "wide:"
+-	"settle:" "diff:"
+-	"irqm:"   "pcifix:"
+-	"buschk:" "optim:"
+-	"recovery:"
+-	"safe:"   "nvram:"
+-	"excl:"   "hostid:"
+-#ifdef SCSI_NCR_IARB_SUPPORT
+-	"iarb:"
+-#endif
+-	;	/* DONNOT REMOVE THIS ';' */
+-
+-#ifdef MODULE
+-#define	ARG_SEP	' '
+-#else
+-#define	ARG_SEP	','
+-#endif
+-
+-static int __init get_setup_token(char *p)
+-{
+-	char *cur = setup_token;
+-	char *pc;
+-	int i = 0;
+-
+-	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
+-		++pc;
+-		++i;
+-		if (!strncmp(p, cur, pc - cur))
+-			return i;
+-		cur = pc;
+-	}
+-	return 0;
+-}
+-
+-
+-static int __init sym53c8xx__setup(char *str)
+-{
+-#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
+-	char *cur = str;
+-	char *pc, *pv;
+-	int i, val, c;
+-	int xi = 0;
+-
+-	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
+-		char *pe;
+-
+-		val = 0;
+-		pv = pc;
+-		c = *++pv;
+-
+-		if	(c == 'n')
+-			val = 0;
+-		else if	(c == 'y')
+-			val = 1;
+-		else
+-			val = (int) simple_strtoul(pv, &pe, 0);
+-
+-		switch (get_setup_token(cur)) {
+-		case OPT_TAGS:
+-			driver_setup.default_tags = val;
+-			if (pe && *pe == '/') {
+-				i = 0;
+-				while (*pe && *pe != ARG_SEP && 
+-					i < sizeof(driver_setup.tag_ctrl)-1) {
+-					driver_setup.tag_ctrl[i++] = *pe++;
+-				}
+-				driver_setup.tag_ctrl[i] = '\0';
+-			}
+-			break;
+-		case OPT_MASTER_PARITY:
+-			driver_setup.master_parity = val;
+-			break;
+-		case OPT_SCSI_PARITY:
+-			driver_setup.scsi_parity = val;
+-			break;
+-		case OPT_DISCONNECTION:
+-			driver_setup.disconnection = val;
+-			break;
+-		case OPT_SPECIAL_FEATURES:
+-			driver_setup.special_features = val;
+-			break;
+-		case OPT_FORCE_SYNC_NEGO:
+-			driver_setup.force_sync_nego = val;
+-			break;
+-		case OPT_REVERSE_PROBE:
+-			driver_setup.reverse_probe = val;
+-			break;
+-		case OPT_DEFAULT_SYNC:
+-			driver_setup.default_sync = val;
+-			break;
+-		case OPT_VERBOSE:
+-			driver_setup.verbose = val;
+-			break;
+-		case OPT_DEBUG:
+-			driver_setup.debug = val;
+-			break;
+-		case OPT_BURST_MAX:
+-			driver_setup.burst_max = val;
+-			break;
+-		case OPT_LED_PIN:
+-			driver_setup.led_pin = val;
+-			break;
+-		case OPT_MAX_WIDE:
+-			driver_setup.max_wide = val? 1:0;
+-			break;
+-		case OPT_SETTLE_DELAY:
+-			driver_setup.settle_delay = val;
+-			break;
+-		case OPT_DIFF_SUPPORT:
+-			driver_setup.diff_support = val;
+-			break;
+-		case OPT_IRQM:
+-			driver_setup.irqm = val;
+-			break;
+-		case OPT_PCI_FIX_UP:
+-			driver_setup.pci_fix_up	= val;
+-			break;
+-		case OPT_BUS_CHECK:
+-			driver_setup.bus_check = val;
+-			break;
+-		case OPT_OPTIMIZE:
+-			driver_setup.optimize = val;
+-			break;
+-		case OPT_RECOVERY:
+-			driver_setup.recovery = val;
+-			break;
+-		case OPT_USE_NVRAM:
+-			driver_setup.use_nvram = val;
+-			break;
+-		case OPT_SAFE_SETUP:
+-			memcpy(&driver_setup, &driver_safe_setup,
+-				sizeof(driver_setup));
+-			break;
+-		case OPT_EXCLUDE:
+-			if (xi < SCSI_NCR_MAX_EXCLUDES)
+-				driver_setup.excludes[xi++] = val;
+-			break;
+-		case OPT_HOST_ID:
+-			driver_setup.host_id = val;
+-			break;
+-#ifdef SCSI_NCR_IARB_SUPPORT
+-		case OPT_IARB:
+-			driver_setup.iarb = val;
+-			break;
+-#endif
+-		default:
+-			printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
+-			break;
+-		}
+-
+-		if ((cur = strchr(cur, ARG_SEP)) != NULL)
+-			++cur;
+-	}
+-#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */
+-	return 1;
+-}
+-
+-/*===================================================================
+-**
+-**	Get device queue depth from boot command line.
+-**
+-**===================================================================
+-*/
+-#define DEF_DEPTH	(driver_setup.default_tags)
+-#define ALL_TARGETS	-2
+-#define NO_TARGET	-1
+-#define ALL_LUNS	-2
+-#define NO_LUN		-1
+-
+-static int device_queue_depth(int unit, int target, int lun)
+-{
+-	int c, h, t, u, v;
+-	char *p = driver_setup.tag_ctrl;
+-	char *ep;
+-
+-	h = -1;
+-	t = NO_TARGET;
+-	u = NO_LUN;
+-	while ((c = *p++) != 0) {
+-		v = simple_strtoul(p, &ep, 0);
+-		switch(c) {
+-		case '/':
+-			++h;
+-			t = ALL_TARGETS;
+-			u = ALL_LUNS;
+-			break;
+-		case 't':
+-			if (t != target)
+-				t = (target == v) ? v : NO_TARGET;
+-			u = ALL_LUNS;
+-			break;
+-		case 'u':
+-			if (u != lun)
+-				u = (lun == v) ? v : NO_LUN;
+-			break;
+-		case 'q':
+-			if (h == unit &&
+-				(t == ALL_TARGETS || t == target) &&
+-				(u == ALL_LUNS    || u == lun))
+-				return v;
+-			break;
+-		case '-':
+-			t = ALL_TARGETS;
+-			u = ALL_LUNS;
+-			break;
+-		default:
+-			break;
+-		}
+-		p = ep;
+-	}
+-	return DEF_DEPTH;
+-}
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_defs.h CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_defs.h
+--- LINUS_2_6_15_RC7/drivers/scsi/sym53c8xx_defs.h	2005-12-27 13:25:48.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/scsi/sym53c8xx_defs.h	1969-12-31 17:00:00.000000000 -0700
+@@ -1,1320 +0,0 @@
+-/******************************************************************************
+-**  High Performance device driver for the Symbios 53C896 controller.
+-**
+-**  Copyright (C) 1998-2001  Gerard Roudier <groudier at free.fr>
+-**
+-**  This driver also supports all the Symbios 53C8XX controller family, 
+-**  except 53C810 revisions < 16, 53C825 revisions < 16 and all 
+-**  revisions of 53C815 controllers.
+-**
+-**  This driver is based on the Linux port of the FreeBSD ncr driver.
+-** 
+-**  Copyright (C) 1994  Wolfgang Stanglmeier
+-**  
+-**-----------------------------------------------------------------------------
+-**  
+-**  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.
+-**
+-**-----------------------------------------------------------------------------
+-**
+-**  The Linux port of the FreeBSD ncr driver has been achieved in 
+-**  november 1995 by:
+-**
+-**          Gerard Roudier              <groudier at free.fr>
+-**
+-**  Being given that this driver originates from the FreeBSD version, and
+-**  in order to keep synergy on both, any suggested enhancements and corrections
+-**  received on Linux are automatically a potential candidate for the FreeBSD 
+-**  version.
+-**
+-**  The original driver has been written for 386bsd and FreeBSD by
+-**          Wolfgang Stanglmeier        <wolf at cologne.de>
+-**          Stefan Esser                <se at mi.Uni-Koeln.de>
+-**
+-**-----------------------------------------------------------------------------
+-**
+-**  Major contributions:
+-**  --------------------
+-**
+-**  NVRAM detection and reading.
+-**    Copyright (C) 1997 Richard Waltham <dormouse at farsrobt.demon.co.uk>
+-**
+-**  Added support for MIPS big endian systems.
+-**    Carsten Langgaard, carstenl at mips.com
+-**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+-**
+-**  Added support for HP PARISC big endian systems.
+-**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+-**
+-*******************************************************************************
+-*/
+-
+-#ifndef SYM53C8XX_DEFS_H
+-#define SYM53C8XX_DEFS_H
+-
+-#include <linux/config.h>
+-
+-/*
+-**	If you want a driver as small as possible, donnot define the 
+-**	following options.
+-*/
+-#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
+-#define SCSI_NCR_DEBUG_INFO_SUPPORT
+-
+-/*
+-**	To disable integrity checking, do not define the 
+-**	following option.
+-*/
+-#ifdef	CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK
+-#	define SCSI_NCR_ENABLE_INTEGRITY_CHECK
+-#endif
+-
+-/* ---------------------------------------------------------------------
+-** Take into account kernel configured parameters.
+-** Most of these options can be overridden at startup by a command line.
+-** ---------------------------------------------------------------------
+-*/
+-
+-/*
+- * For Ultra2 and Ultra3 SCSI support option, use special features. 
+- *
+- * Value (default) means:
+- *	bit 0 : all features enabled, except:
+- *		bit 1 : PCI Write And Invalidate.
+- *		bit 2 : Data Phase Mismatch handling from SCRIPTS.
+- *
+- * Use boot options ncr53c8xx=specf:1 if you want all chip features to be 
+- * enabled by the driver.
+- */
+-#define	SCSI_NCR_SETUP_SPECIAL_FEATURES		(3)
+-
+-#define SCSI_NCR_MAX_SYNC			(80)
+-
+-/*
+- * Allow tags from 2 to 256, default 8
+- */
+-#ifdef	CONFIG_SCSI_NCR53C8XX_MAX_TAGS
+-#if	CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2
+-#define SCSI_NCR_MAX_TAGS	(2)
+-#elif	CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256
+-#define SCSI_NCR_MAX_TAGS	(256)
+-#else
+-#define	SCSI_NCR_MAX_TAGS	CONFIG_SCSI_NCR53C8XX_MAX_TAGS
+-#endif
+-#else
+-#define SCSI_NCR_MAX_TAGS	(8)
+-#endif
+-
+-/*
+- * Allow tagged command queuing support if configured with default number 
+- * of tags set to max (see above).
+- */
+-#ifdef	CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
+-#define	SCSI_NCR_SETUP_DEFAULT_TAGS	CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
+-#elif	defined CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE
+-#define	SCSI_NCR_SETUP_DEFAULT_TAGS	SCSI_NCR_MAX_TAGS
+-#else
+-#define	SCSI_NCR_SETUP_DEFAULT_TAGS	(0)
+-#endif
+-
+-/*
+- * Immediate arbitration
+- */
+-#if defined(CONFIG_SCSI_NCR53C8XX_IARB)
+-#define SCSI_NCR_IARB_SUPPORT
+-#endif
+-
+-/*
+- * Sync transfer frequency at startup.
+- * Allow from 5Mhz to 80Mhz default 20 Mhz.
+- */
+-#ifndef	CONFIG_SCSI_NCR53C8XX_SYNC
+-#define	CONFIG_SCSI_NCR53C8XX_SYNC	(20)
+-#elif	CONFIG_SCSI_NCR53C8XX_SYNC > SCSI_NCR_MAX_SYNC
+-#undef	CONFIG_SCSI_NCR53C8XX_SYNC
+-#define	CONFIG_SCSI_NCR53C8XX_SYNC	SCSI_NCR_MAX_SYNC
+-#endif
+-
+-#if	CONFIG_SCSI_NCR53C8XX_SYNC == 0
+-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(255)
+-#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 5
+-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(50)
+-#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 20
+-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(250/(CONFIG_SCSI_NCR53C8XX_SYNC))
+-#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 33
+-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(11)
+-#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 40
+-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(10)
+-#else
+-#define	SCSI_NCR_SETUP_DEFAULT_SYNC 	(9)
+-#endif
+-
+-/*
+- * Disallow disconnections at boot-up
+- */
+-#ifdef CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
+-#define SCSI_NCR_SETUP_DISCONNECTION	(0)
+-#else
+-#define SCSI_NCR_SETUP_DISCONNECTION	(1)
+-#endif
+-
+-/*
+- * Force synchronous negotiation for all targets
+- */
+-#ifdef CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO
+-#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO	(1)
+-#else
+-#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO	(0)
+-#endif
+-
+-/*
+- * Disable master parity checking (flawed hardwares need that)
+- */
+-#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK
+-#define SCSI_NCR_SETUP_MASTER_PARITY	(0)
+-#else
+-#define SCSI_NCR_SETUP_MASTER_PARITY	(1)
+-#endif
+-
+-/*
+- * Disable scsi parity checking (flawed devices may need that)
+- */
+-#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK
+-#define SCSI_NCR_SETUP_SCSI_PARITY	(0)
+-#else
+-#define SCSI_NCR_SETUP_SCSI_PARITY	(1)
+-#endif
+-
+-/*
+- * Settle time after reset at boot-up
+- */
+-#define SCSI_NCR_SETUP_SETTLE_TIME	(2)
+-
+-/*
+-**	Bridge quirks work-around option defaulted to 1.
+-*/
+-#ifndef	SCSI_NCR_PCIQ_WORK_AROUND_OPT
+-#define	SCSI_NCR_PCIQ_WORK_AROUND_OPT	1
+-#endif
+-
+-/*
+-**	Work-around common bridge misbehaviour.
+-**
+-**	- Do not flush posted writes in the opposite 
+-**	  direction on read.
+-**	- May reorder DMA writes to memory.
+-**
+-**	This option should not affect performances 
+-**	significantly, so it is the default.
+-*/
+-#if	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1
+-#define	SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
+-#define	SCSI_NCR_PCIQ_MAY_REORDER_WRITES
+-#define	SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
+-
+-/*
+-**	Same as option 1, but also deal with 
+-**	misconfigured interrupts.
+-**
+-**	- Edge triggerred instead of level sensitive.
+-**	- No interrupt line connected.
+-**	- IRQ number misconfigured.
+-**	
+-**	If no interrupt is delivered, the driver will 
+-**	catch the interrupt conditions 10 times per 
+-**	second. No need to say that this option is 
+-**	not recommended.
+-*/
+-#elif	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2
+-#define	SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
+-#define	SCSI_NCR_PCIQ_MAY_REORDER_WRITES
+-#define	SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
+-#define	SCSI_NCR_PCIQ_BROKEN_INTR
+-
+-/*
+-**	Some bridge designers decided to flush 
+-**	everything prior to deliver the interrupt.
+-**	This option tries to deal with such a 
+-**	behaviour.
+-*/
+-#elif	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3
+-#define	SCSI_NCR_PCIQ_SYNC_ON_INTR
+-#endif
+-
+-/*
+-**	Other parameters not configurable with "make config"
+-**	Avoid to change these constants, unless you know what you are doing.
+-*/
+-
+-#define SCSI_NCR_ALWAYS_SIMPLE_TAG
+-#define SCSI_NCR_MAX_SCATTER	(127)
+-#define SCSI_NCR_MAX_TARGET	(16)
+-
+-/*
+-**   Compute some desirable value for CAN_QUEUE 
+-**   and CMD_PER_LUN.
+-**   The driver will use lower values if these 
+-**   ones appear to be too large.
+-*/
+-#define SCSI_NCR_CAN_QUEUE	(8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET)
+-#define SCSI_NCR_CMD_PER_LUN	(SCSI_NCR_MAX_TAGS)
+-
+-#define SCSI_NCR_SG_TABLESIZE	(SCSI_NCR_MAX_SCATTER)
+-#define SCSI_NCR_TIMER_INTERVAL	(HZ)
+-
+-#if 1 /* defined CONFIG_SCSI_MULTI_LUN */
+-#define SCSI_NCR_MAX_LUN	(16)
+-#else
+-#define SCSI_NCR_MAX_LUN	(1)
+-#endif
+-
+-/*
+- *  IO functions definition for big/little endian CPU support.
+- *  For now, the NCR is only supported in little endian addressing mode, 
+- */
+-
+-#ifdef	__BIG_ENDIAN
+-
+-#define	inw_l2b		inw
+-#define	inl_l2b		inl
+-#define	outw_b2l	outw
+-#define	outl_b2l	outl
+-
+-#define	readb_raw	readb
+-#define	writeb_raw	writeb
+-
+-#if defined(SCSI_NCR_BIG_ENDIAN)
+-#define	readw_l2b	__raw_readw
+-#define	readl_l2b	__raw_readl
+-#define	writew_b2l	__raw_writew
+-#define	writel_b2l	__raw_writel
+-#define	readw_raw	__raw_readw
+-#define	readl_raw	__raw_readl
+-#define	writew_raw	__raw_writew
+-#define	writel_raw	__raw_writel
+-#else	/* Other big-endian */
+-#define	readw_l2b	readw
+-#define	readl_l2b	readl
+-#define	writew_b2l	writew
+-#define	writel_b2l	writel
+-#define	readw_raw	readw
+-#define	readl_raw	readl
+-#define	writew_raw	writew
+-#define	writel_raw	writel
+-#endif
+-
+-#else	/* little endian */
+-
+-#define	inw_raw		inw
+-#define	inl_raw		inl
+-#define	outw_raw	outw
+-#define	outl_raw	outl
+-
+-#define	readb_raw	readb
+-#define	readw_raw	readw
+-#define	readl_raw	readl
+-#define	writeb_raw	writeb
+-#define	writew_raw	writew
+-#define	writel_raw	writel
+-
+-#endif
+-
+-#if !defined(__hppa__) && !defined(__mips__)
+-#ifdef	SCSI_NCR_BIG_ENDIAN
+-#error	"The NCR in BIG ENDIAN addressing mode is not (yet) supported"
+-#endif
+-#endif
+-
+-#define MEMORY_BARRIER()	mb()
+-
+-
+-/*
+- *  If the NCR uses big endian addressing mode over the 
+- *  PCI, actual io register addresses for byte and word 
+- *  accesses must be changed according to lane routing.
+- *  Btw, ncr_offb() and ncr_offw() macros only apply to 
+- *  constants and so donnot generate bloated code.
+- */
+-
+-#if	defined(SCSI_NCR_BIG_ENDIAN)
+-
+-#define ncr_offb(o)	(((o)&~3)+((~((o)&3))&3))
+-#define ncr_offw(o)	(((o)&~3)+((~((o)&3))&2))
+-
+-#else
+-
+-#define ncr_offb(o)	(o)
+-#define ncr_offw(o)	(o)
+-
+-#endif
+-
+-/*
+- *  If the CPU and the NCR use same endian-ness addressing,
+- *  no byte reordering is needed for script patching.
+- *  Macro cpu_to_scr() is to be used for script patching.
+- *  Macro scr_to_cpu() is to be used for getting a DWORD 
+- *  from the script.
+- */
+-
+-#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
+-
+-#define cpu_to_scr(dw)	cpu_to_le32(dw)
+-#define scr_to_cpu(dw)	le32_to_cpu(dw)
+-
+-#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
+-
+-#define cpu_to_scr(dw)	cpu_to_be32(dw)
+-#define scr_to_cpu(dw)	be32_to_cpu(dw)
+-
+-#else
+-
+-#define cpu_to_scr(dw)	(dw)
+-#define scr_to_cpu(dw)	(dw)
+-
+-#endif
+-
+-/*
+- *  Access to the controller chip.
+- *
+- *  If the CPU and the NCR use same endian-ness addressing,
+- *  no byte reordering is needed for accessing chip io 
+- *  registers. Functions suffixed by '_raw' are assumed 
+- *  to access the chip over the PCI without doing byte 
+- *  reordering. Functions suffixed by '_l2b' are 
+- *  assumed to perform little-endian to big-endian byte 
+- *  reordering, those suffixed by '_b2l' blah, blah,
+- *  blah, ...
+- */
+-
+-/*
+- *  MEMORY mapped IO input / output
+- */
+-
+-#define INB_OFF(o)		readb_raw((char __iomem *)np->reg + ncr_offb(o))
+-#define OUTB_OFF(o, val)	writeb_raw((val), (char __iomem *)np->reg + ncr_offb(o))
+-
+-#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
+-
+-#define INW_OFF(o)		readw_l2b((char __iomem *)np->reg + ncr_offw(o))
+-#define INL_OFF(o)		readl_l2b((char __iomem *)np->reg + (o))
+-
+-#define OUTW_OFF(o, val)	writew_b2l((val), (char __iomem *)np->reg + ncr_offw(o))
+-#define OUTL_OFF(o, val)	writel_b2l((val), (char __iomem *)np->reg + (o))
+-
+-#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
+-
+-#define INW_OFF(o)		readw_b2l((char __iomem *)np->reg + ncr_offw(o))
+-#define INL_OFF(o)		readl_b2l((char __iomem *)np->reg + (o))
+-
+-#define OUTW_OFF(o, val)	writew_l2b((val), (char __iomem *)np->reg + ncr_offw(o))
+-#define OUTL_OFF(o, val)	writel_l2b((val), (char __iomem *)np->reg + (o))
+-
+-#else
+-
+-#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
+-/* Only 8 or 32 bit transfers allowed */
+-#define INW_OFF(o)		(readb((char __iomem *)np->reg + ncr_offw(o)) << 8 | readb((char __iomem *)np->reg + ncr_offw(o) + 1))
+-#else
+-#define INW_OFF(o)		readw_raw((char __iomem *)np->reg + ncr_offw(o))
+-#endif
+-#define INL_OFF(o)		readl_raw((char __iomem *)np->reg + (o))
+-
+-#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
+-/* Only 8 or 32 bit transfers allowed */
+-#define OUTW_OFF(o, val)	do { writeb((char)((val) >> 8), (char __iomem *)np->reg + ncr_offw(o)); writeb((char)(val), (char __iomem *)np->reg + ncr_offw(o) + 1); } while (0)
+-#else
+-#define OUTW_OFF(o, val)	writew_raw((val), (char __iomem *)np->reg + ncr_offw(o))
+-#endif
+-#define OUTL_OFF(o, val)	writel_raw((val), (char __iomem *)np->reg + (o))
+-
+-#endif
+-
+-#define INB(r)		INB_OFF (offsetof(struct ncr_reg,r))
+-#define INW(r)		INW_OFF (offsetof(struct ncr_reg,r))
+-#define INL(r)		INL_OFF (offsetof(struct ncr_reg,r))
+-
+-#define OUTB(r, val)	OUTB_OFF (offsetof(struct ncr_reg,r), (val))
+-#define OUTW(r, val)	OUTW_OFF (offsetof(struct ncr_reg,r), (val))
+-#define OUTL(r, val)	OUTL_OFF (offsetof(struct ncr_reg,r), (val))
+-
+-/*
+- *  Set bit field ON, OFF 
+- */
+-
+-#define OUTONB(r, m)	OUTB(r, INB(r) | (m))
+-#define OUTOFFB(r, m)	OUTB(r, INB(r) & ~(m))
+-#define OUTONW(r, m)	OUTW(r, INW(r) | (m))
+-#define OUTOFFW(r, m)	OUTW(r, INW(r) & ~(m))
+-#define OUTONL(r, m)	OUTL(r, INL(r) | (m))
+-#define OUTOFFL(r, m)	OUTL(r, INL(r) & ~(m))
+-
+-/*
+- *  We normally want the chip to have a consistent view
+- *  of driver internal data structures when we restart it.
+- *  Thus these macros.
+- */
+-#define OUTL_DSP(v)				\
+-	do {					\
+-		MEMORY_BARRIER();		\
+-		OUTL (nc_dsp, (v));		\
+-	} while (0)
+-
+-#define OUTONB_STD()				\
+-	do {					\
+-		MEMORY_BARRIER();		\
+-		OUTONB (nc_dcntl, (STD|NOCOM));	\
+-	} while (0)
+-
+-
+-/*
+-**   NCR53C8XX devices features table.
+-*/
+-struct ncr_chip {
+-	unsigned short	revision_id;
+-	unsigned char	burst_max;	/* log-base-2 of max burst */
+-	unsigned char	offset_max;
+-	unsigned char	nr_divisor;
+-	unsigned int	features;
+-#define FE_LED0		(1<<0)
+-#define FE_WIDE		(1<<1)    /* Wide data transfers */
+-#define FE_ULTRA	(1<<2)	  /* Ultra speed 20Mtrans/sec */
+-#define FE_DBLR		(1<<4)	  /* Clock doubler present */
+-#define FE_QUAD		(1<<5)	  /* Clock quadrupler present */
+-#define FE_ERL		(1<<6)    /* Enable read line */
+-#define FE_CLSE		(1<<7)    /* Cache line size enable */
+-#define FE_WRIE		(1<<8)    /* Write & Invalidate enable */
+-#define FE_ERMP		(1<<9)    /* Enable read multiple */
+-#define FE_BOF		(1<<10)   /* Burst opcode fetch */
+-#define FE_DFS		(1<<11)   /* DMA fifo size */
+-#define FE_PFEN		(1<<12)   /* Prefetch enable */
+-#define FE_LDSTR	(1<<13)   /* Load/Store supported */
+-#define FE_RAM		(1<<14)   /* On chip RAM present */
+-#define FE_VARCLK	(1<<15)   /* SCSI clock may vary */
+-#define FE_RAM8K	(1<<16)   /* On chip RAM sized 8Kb */
+-#define FE_64BIT	(1<<17)   /* Have a 64-bit PCI interface */
+-#define FE_IO256	(1<<18)   /* Requires full 256 bytes in PCI space */
+-#define FE_NOPM		(1<<19)   /* Scripts handles phase mismatch */
+-#define FE_LEDC		(1<<20)   /* Hardware control of LED */
+-#define FE_DIFF		(1<<21)   /* Support Differential SCSI */
+-#define FE_66MHZ 	(1<<23)   /* 66MHz PCI Support */
+-#define FE_DAC	 	(1<<24)   /* Support DAC cycles (64 bit addressing) */
+-#define FE_ISTAT1 	(1<<25)   /* Have ISTAT1, MBOX0, MBOX1 registers */
+-#define FE_DAC_IN_USE	(1<<26)	  /* Platform does DAC cycles */
+-#define FE_EHP		(1<<27)   /* 720: Even host parity */
+-#define FE_MUX		(1<<28)   /* 720: Multiplexed bus */
+-#define FE_EA		(1<<29)   /* 720: Enable Ack */
+-
+-#define FE_CACHE_SET	(FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP)
+-#define FE_SCSI_SET	(FE_WIDE|FE_ULTRA|FE_DBLR|FE_QUAD|F_CLK80)
+-#define FE_SPECIAL_SET	(FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM)
+-};
+-
+-
+-/*
+-**	Driver setup structure.
+-**
+-**	This structure is initialized from linux config options.
+-**	It can be overridden at boot-up by the boot command line.
+-*/
+-#define SCSI_NCR_MAX_EXCLUDES 8
+-struct ncr_driver_setup {
+-	u8	master_parity;
+-	u8	scsi_parity;
+-	u8	disconnection;
+-	u8	special_features;
+-	u8	force_sync_nego;
+-	u8	reverse_probe;
+-	u8	pci_fix_up;
+-	u8	use_nvram;
+-	u8	verbose;
+-	u8	default_tags;
+-	u16	default_sync;
+-	u16	debug;
+-	u8	burst_max;
+-	u8	led_pin;
+-	u8	max_wide;
+-	u8	settle_delay;
+-	u8	diff_support;
+-	u8	irqm;
+-	u8	bus_check;
+-	u8	optimize;
+-	u8	recovery;
+-	u8	host_id;
+-	u16	iarb;
+-	u32	excludes[SCSI_NCR_MAX_EXCLUDES];
+-	char	tag_ctrl[100];
+-};
+-
+-/*
+-**	Initial setup.
+-**	Can be overriden at startup by a command line.
+-*/
+-#define SCSI_NCR_DRIVER_SETUP			\
+-{						\
+-	SCSI_NCR_SETUP_MASTER_PARITY,		\
+-	SCSI_NCR_SETUP_SCSI_PARITY,		\
+-	SCSI_NCR_SETUP_DISCONNECTION,		\
+-	SCSI_NCR_SETUP_SPECIAL_FEATURES,	\
+-	SCSI_NCR_SETUP_FORCE_SYNC_NEGO,		\
+-	0,					\
+-	0,					\
+-	1,					\
+-	0,					\
+-	SCSI_NCR_SETUP_DEFAULT_TAGS,		\
+-	SCSI_NCR_SETUP_DEFAULT_SYNC,		\
+-	0x00,					\
+-	7,					\
+-	0,					\
+-	1,					\
+-	SCSI_NCR_SETUP_SETTLE_TIME,		\
+-	0,					\
+-	0,					\
+-	1,					\
+-	0,					\
+-	0,					\
+-	255,					\
+-	0x00					\
+-}
+-
+-/*
+-**	Boot fail safe setup.
+-**	Override initial setup from boot command line:
+-**	ncr53c8xx=safe:y
+-*/
+-#define SCSI_NCR_DRIVER_SAFE_SETUP		\
+-{						\
+-	0,					\
+-	1,					\
+-	0,					\
+-	0,					\
+-	0,					\
+-	0,					\
+-	0,					\
+-	1,					\
+-	2,					\
+-	0,					\
+-	255,					\
+-	0x00,					\
+-	255,					\
+-	0,					\
+-	0,					\
+-	10,					\
+-	1,					\
+-	1,					\
+-	1,					\
+-	0,					\
+-	0,					\
+-	255					\
+-}
+-
+-/**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/
+-
+-/*-----------------------------------------------------------------
+-**
+-**	The ncr 53c810 register structure.
+-**
+-**-----------------------------------------------------------------
+-*/
+-
+-struct ncr_reg {
+-/*00*/  u8	nc_scntl0;    /* full arb., ena parity, par->ATN  */
+-
+-/*01*/  u8	nc_scntl1;    /* no reset                         */
+-        #define   ISCON   0x10  /* connected to scsi		    */
+-        #define   CRST    0x08  /* force reset                      */
+-        #define   IARB    0x02  /* immediate arbitration            */
+-
+-/*02*/  u8	nc_scntl2;    /* no disconnect expected           */
+-	#define   SDU     0x80  /* cmd: disconnect will raise error */
+-	#define   CHM     0x40  /* sta: chained mode                */
+-	#define   WSS     0x08  /* sta: wide scsi send           [W]*/
+-	#define   WSR     0x01  /* sta: wide scsi received       [W]*/
+-
+-/*03*/  u8	nc_scntl3;    /* cnf system clock dependent       */
+-	#define   EWS     0x08  /* cmd: enable wide scsi         [W]*/
+-	#define   ULTRA   0x80  /* cmd: ULTRA enable                */
+-				/* bits 0-2, 7 rsvd for C1010       */
+-
+-/*04*/  u8	nc_scid;	/* cnf host adapter scsi address    */
+-	#define   RRE     0x40  /* r/w:e enable response to resel.  */
+-	#define   SRE     0x20  /* r/w:e enable response to select  */
+-
+-/*05*/  u8	nc_sxfer;	/* ### Sync speed and count         */
+-				/* bits 6-7 rsvd for C1010          */
+-
+-/*06*/  u8	nc_sdid;	/* ### Destination-ID               */
+-
+-/*07*/  u8	nc_gpreg;	/* ??? IO-Pins                      */
+-
+-/*08*/  u8	nc_sfbr;	/* ### First byte in phase          */
+-
+-/*09*/  u8	nc_socl;
+-	#define   CREQ	  0x80	/* r/w: SCSI-REQ                    */
+-	#define   CACK	  0x40	/* r/w: SCSI-ACK                    */
+-	#define   CBSY	  0x20	/* r/w: SCSI-BSY                    */
+-	#define   CSEL	  0x10	/* r/w: SCSI-SEL                    */
+-	#define   CATN	  0x08	/* r/w: SCSI-ATN                    */
+-	#define   CMSG	  0x04	/* r/w: SCSI-MSG                    */
+-	#define   CC_D	  0x02	/* r/w: SCSI-C_D                    */
+-	#define   CI_O	  0x01	/* r/w: SCSI-I_O                    */
+-
+-/*0a*/  u8	nc_ssid;
+-
+-/*0b*/  u8	nc_sbcl;
+-
+-/*0c*/  u8	nc_dstat;
+-        #define   DFE     0x80  /* sta: dma fifo empty              */
+-        #define   MDPE    0x40  /* int: master data parity error    */
+-        #define   BF      0x20  /* int: script: bus fault           */
+-        #define   ABRT    0x10  /* int: script: command aborted     */
+-        #define   SSI     0x08  /* int: script: single step         */
+-        #define   SIR     0x04  /* int: script: interrupt instruct. */
+-        #define   IID     0x01  /* int: script: illegal instruct.   */
+-
+-/*0d*/  u8	nc_sstat0;
+-        #define   ILF     0x80  /* sta: data in SIDL register lsb   */
+-        #define   ORF     0x40  /* sta: data in SODR register lsb   */
+-        #define   OLF     0x20  /* sta: data in SODL register lsb   */
+-        #define   AIP     0x10  /* sta: arbitration in progress     */
+-        #define   LOA     0x08  /* sta: arbitration lost            */
+-        #define   WOA     0x04  /* sta: arbitration won             */
+-        #define   IRST    0x02  /* sta: scsi reset signal           */
+-        #define   SDP     0x01  /* sta: scsi parity signal          */
+-
+-/*0e*/  u8	nc_sstat1;
+-	#define   FF3210  0xf0	/* sta: bytes in the scsi fifo      */
+-
+-/*0f*/  u8	nc_sstat2;
+-        #define   ILF1    0x80  /* sta: data in SIDL register msb[W]*/
+-        #define   ORF1    0x40  /* sta: data in SODR register msb[W]*/
+-        #define   OLF1    0x20  /* sta: data in SODL register msb[W]*/
+-        #define   DM      0x04  /* sta: DIFFSENS mismatch (895/6 only) */
+-        #define   LDSC    0x02  /* sta: disconnect & reconnect      */
+-
+-/*10*/  u8	nc_dsa;	/* --> Base page                    */
+-/*11*/  u8	nc_dsa1;
+-/*12*/  u8	nc_dsa2;
+-/*13*/  u8	nc_dsa3;
+-
+-/*14*/  u8	nc_istat;	/* --> Main Command and status      */
+-        #define   CABRT   0x80  /* cmd: abort current operation     */
+-        #define   SRST    0x40  /* mod: reset chip                  */
+-        #define   SIGP    0x20  /* r/w: message from host to ncr    */
+-        #define   SEM     0x10  /* r/w: message between host + ncr  */
+-        #define   CON     0x08  /* sta: connected to scsi           */
+-        #define   INTF    0x04  /* sta: int on the fly (reset by wr)*/
+-        #define   SIP     0x02  /* sta: scsi-interrupt              */
+-        #define   DIP     0x01  /* sta: host/script interrupt       */
+-
+-/*15*/  u8	nc_istat1;	/* 896 and later cores only */
+-        #define   FLSH    0x04  /* sta: chip is flushing            */
+-        #define   SRUN    0x02  /* sta: scripts are running         */
+-        #define   SIRQD   0x01  /* r/w: disable INT pin             */
+-
+-/*16*/  u8	nc_mbox0;	/* 896 and later cores only */
+-/*17*/  u8	nc_mbox1;	/* 896 and later cores only */
+-
+-/*18*/	u8	nc_ctest0;
+-	#define   EHP     0x04	/* 720 even host parity             */
+-/*19*/  u8	nc_ctest1;
+-
+-/*1a*/  u8	nc_ctest2;
+-	#define   CSIGP   0x40
+-				/* bits 0-2,7 rsvd for C1010        */
+-
+-/*1b*/  u8	nc_ctest3;
+-	#define   FLF     0x08  /* cmd: flush dma fifo              */
+-	#define   CLF	  0x04	/* cmd: clear dma fifo		    */
+-	#define   FM      0x02  /* mod: fetch pin mode              */
+-	#define   WRIE    0x01  /* mod: write and invalidate enable */
+-				/* bits 4-7 rsvd for C1010          */
+-
+-/*1c*/  u32    nc_temp;	/* ### Temporary stack              */
+-
+-/*20*/	u8	nc_dfifo;
+-/*21*/  u8	nc_ctest4;
+-	#define   MUX     0x80  /* 720 host bus multiplex mode      */
+-	#define   BDIS    0x80  /* mod: burst disable               */
+-	#define   MPEE    0x08  /* mod: master parity error enable  */
+-
+-/*22*/  u8	nc_ctest5;
+-	#define   DFS     0x20  /* mod: dma fifo size               */
+-				/* bits 0-1, 3-7 rsvd for C1010          */
+-/*23*/  u8	nc_ctest6;
+-
+-/*24*/  u32    nc_dbc;	/* ### Byte count and command       */
+-/*28*/  u32    nc_dnad;	/* ### Next command register        */
+-/*2c*/  u32    nc_dsp;	/* --> Script Pointer               */
+-/*30*/  u32    nc_dsps;	/* --> Script pointer save/opcode#2 */
+-
+-/*34*/  u8	nc_scratcha;  /* Temporary register a            */
+-/*35*/  u8	nc_scratcha1;
+-/*36*/  u8	nc_scratcha2;
+-/*37*/  u8	nc_scratcha3;
+-
+-/*38*/  u8	nc_dmode;
+-	#define   BL_2    0x80  /* mod: burst length shift value +2 */
+-	#define   BL_1    0x40  /* mod: burst length shift value +1 */
+-	#define   ERL     0x08  /* mod: enable read line            */
+-	#define   ERMP    0x04  /* mod: enable read multiple        */
+-	#define   BOF     0x02  /* mod: burst op code fetch         */
+-
+-/*39*/  u8	nc_dien;
+-/*3a*/  u8	nc_sbr;
+-
+-/*3b*/  u8	nc_dcntl;	/* --> Script execution control     */
+-	#define   CLSE    0x80  /* mod: cache line size enable      */
+-	#define   PFF     0x40  /* cmd: pre-fetch flush             */
+-	#define   PFEN    0x20  /* mod: pre-fetch enable            */
+-	#define   EA      0x20  /* mod: 720 enable-ack              */
+-	#define   SSM     0x10  /* mod: single step mode            */
+-	#define   IRQM    0x08  /* mod: irq mode (1 = totem pole !) */
+-	#define   STD     0x04  /* cmd: start dma mode              */
+-	#define   IRQD    0x02  /* mod: irq disable                 */
+- 	#define	  NOCOM   0x01	/* cmd: protect sfbr while reselect */
+-				/* bits 0-1 rsvd for C1010          */
+-
+-/*3c*/  u32	nc_adder;
+-
+-/*40*/  u16	nc_sien;	/* -->: interrupt enable            */
+-/*42*/  u16	nc_sist;	/* <--: interrupt status            */
+-        #define   SBMC    0x1000/* sta: SCSI Bus Mode Change (895/6 only) */
+-        #define   STO     0x0400/* sta: timeout (select)            */
+-        #define   GEN     0x0200/* sta: timeout (general)           */
+-        #define   HTH     0x0100/* sta: timeout (handshake)         */
+-        #define   MA      0x80  /* sta: phase mismatch              */
+-        #define   CMP     0x40  /* sta: arbitration complete        */
+-        #define   SEL     0x20  /* sta: selected by another device  */
+-        #define   RSL     0x10  /* sta: reselected by another device*/
+-        #define   SGE     0x08  /* sta: gross error (over/underflow)*/
+-        #define   UDC     0x04  /* sta: unexpected disconnect       */
+-        #define   RST     0x02  /* sta: scsi bus reset detected     */
+-        #define   PAR     0x01  /* sta: scsi parity error           */
+-
+-/*44*/  u8	nc_slpar;
+-/*45*/  u8	nc_swide;
+-/*46*/  u8	nc_macntl;
+-/*47*/  u8	nc_gpcntl;
+-/*48*/  u8	nc_stime0;    /* cmd: timeout for select&handshake*/
+-/*49*/  u8	nc_stime1;    /* cmd: timeout user defined        */
+-/*4a*/  u16   nc_respid;    /* sta: Reselect-IDs                */
+-
+-/*4c*/  u8	nc_stest0;
+-
+-/*4d*/  u8	nc_stest1;
+-	#define   SCLK    0x80	/* Use the PCI clock as SCSI clock	*/
+-	#define   DBLEN   0x08	/* clock doubler running		*/
+-	#define   DBLSEL  0x04	/* clock doubler selected		*/
+-  
+-
+-/*4e*/  u8	nc_stest2;
+-	#define   ROF     0x40	/* reset scsi offset (after gross error!) */
+-	#define   DIF     0x20  /* 720 SCSI differential mode             */
+-	#define   EXT     0x02  /* extended filtering                     */
+-
+-/*4f*/  u8	nc_stest3;
+-	#define   TE     0x80	/* c: tolerAnt enable */
+-	#define   HSC    0x20	/* c: Halt SCSI Clock */
+-	#define   CSF    0x02	/* c: clear scsi fifo */
+-
+-/*50*/  u16   nc_sidl;	/* Lowlevel: latched from scsi data */
+-/*52*/  u8	nc_stest4;
+-	#define   SMODE  0xc0	/* SCSI bus mode      (895/6 only) */
+-	#define    SMODE_HVD 0x40	/* High Voltage Differential       */
+-	#define    SMODE_SE  0x80	/* Single Ended                    */
+-	#define    SMODE_LVD 0xc0	/* Low Voltage Differential        */
+-	#define   LCKFRQ 0x20	/* Frequency Lock (895/6 only)     */
+-				/* bits 0-5 rsvd for C1010          */
+-
+-/*53*/  u8	nc_53_;
+-/*54*/  u16	nc_sodl;	/* Lowlevel: data out to scsi data  */
+-/*56*/	u8	nc_ccntl0;	/* Chip Control 0 (896)             */
+-	#define   ENPMJ  0x80	/* Enable Phase Mismatch Jump       */
+-	#define   PMJCTL 0x40	/* Phase Mismatch Jump Control      */
+-	#define   ENNDJ  0x20	/* Enable Non Data PM Jump          */
+-	#define   DISFC  0x10	/* Disable Auto FIFO Clear          */
+-	#define   DILS   0x02	/* Disable Internal Load/Store      */
+-	#define   DPR    0x01	/* Disable Pipe Req                 */
+-
+-/*57*/	u8	nc_ccntl1;	/* Chip Control 1 (896)             */
+-	#define   ZMOD   0x80	/* High Impedance Mode              */
+-	#define	  DIC	 0x10	/* Disable Internal Cycles	    */
+-	#define   DDAC   0x08	/* Disable Dual Address Cycle       */
+-	#define   XTIMOD 0x04	/* 64-bit Table Ind. Indexing Mode  */
+-	#define   EXTIBMV 0x02	/* Enable 64-bit Table Ind. BMOV    */
+-	#define   EXDBMV 0x01	/* Enable 64-bit Direct BMOV        */
+-
+-/*58*/  u16	nc_sbdl;	/* Lowlevel: data from scsi data    */
+-/*5a*/  u16	nc_5a_;
+-
+-/*5c*/  u8	nc_scr0;	/* Working register B               */
+-/*5d*/  u8	nc_scr1;	/*                                  */
+-/*5e*/  u8	nc_scr2;	/*                                  */
+-/*5f*/  u8	nc_scr3;	/*                                  */
+-
+-/*60*/  u8	nc_scrx[64];	/* Working register C-R             */
+-/*a0*/	u32	nc_mmrs;	/* Memory Move Read Selector        */
+-/*a4*/	u32	nc_mmws;	/* Memory Move Write Selector       */
+-/*a8*/	u32	nc_sfs;		/* Script Fetch Selector            */
+-/*ac*/	u32	nc_drs;		/* DSA Relative Selector            */
+-/*b0*/	u32	nc_sbms;	/* Static Block Move Selector       */
+-/*b4*/	u32	nc_dbms;	/* Dynamic Block Move Selector      */
+-/*b8*/	u32	nc_dnad64;	/* DMA Next Address 64              */
+-/*bc*/	u16	nc_scntl4;	/* C1010 only                       */
+-	#define   U3EN   0x80	/* Enable Ultra 3                   */
+-	#define   AIPEN	 0x40   /* Allow check upper byte lanes     */
+-	#define   XCLKH_DT 0x08 /* Extra clock of data hold on DT
+-					transfer edge	            */
+-	#define   XCLKH_ST 0x04 /* Extra clock of data hold on ST
+-					transfer edge	            */
+-
+-/*be*/  u8	nc_aipcntl0;	/* Epat Control 1 C1010 only        */
+-/*bf*/  u8	nc_aipcntl1;	/* AIP Control C1010_66 Only        */
+-
+-/*c0*/	u32	nc_pmjad1;	/* Phase Mismatch Jump Address 1    */
+-/*c4*/	u32	nc_pmjad2;	/* Phase Mismatch Jump Address 2    */
+-/*c8*/	u8	nc_rbc;		/* Remaining Byte Count             */
+-/*c9*/	u8	nc_rbc1;	/*                                  */
+-/*ca*/	u8	nc_rbc2;	/*                                  */
+-/*cb*/	u8	nc_rbc3;	/*                                  */
+-
+-/*cc*/	u8	nc_ua;		/* Updated Address                  */
+-/*cd*/	u8	nc_ua1;		/*                                  */
+-/*ce*/	u8	nc_ua2;		/*                                  */
+-/*cf*/	u8	nc_ua3;		/*                                  */
+-/*d0*/	u32	nc_esa;		/* Entry Storage Address            */
+-/*d4*/	u8	nc_ia;		/* Instruction Address              */
+-/*d5*/	u8	nc_ia1;
+-/*d6*/	u8	nc_ia2;
+-/*d7*/	u8	nc_ia3;
+-/*d8*/	u32	nc_sbc;		/* SCSI Byte Count (3 bytes only)   */
+-/*dc*/	u32	nc_csbc;	/* Cumulative SCSI Byte Count       */
+-
+-				/* Following for C1010 only         */
+-/*e0*/  u16	nc_crcpad;	/* CRC Value                        */
+-/*e2*/  u8	nc_crccntl0;	/* CRC control register             */
+-	#define   SNDCRC  0x10	/* Send CRC Request                 */
+-/*e3*/  u8	nc_crccntl1;	/* CRC control register             */
+-/*e4*/  u32	nc_crcdata;	/* CRC data register                */ 
+-/*e8*/  u32	nc_e8_;		/* rsvd 			    */
+-/*ec*/  u32	nc_ec_;		/* rsvd 			    */
+-/*f0*/  u16	nc_dfbc;	/* DMA FIFO byte count              */ 
+-
+-};
+-
+-/*-----------------------------------------------------------
+-**
+-**	Utility macros for the script.
+-**
+-**-----------------------------------------------------------
+-*/
+-
+-#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r))
+-#define REG(r) REGJ (nc_, r)
+-
+-typedef u32 ncrcmd;
+-
+-/*-----------------------------------------------------------
+-**
+-**	SCSI phases
+-**
+-**	DT phases illegal for ncr driver.
+-**
+-**-----------------------------------------------------------
+-*/
+-
+-#define	SCR_DATA_OUT	0x00000000
+-#define	SCR_DATA_IN	0x01000000
+-#define	SCR_COMMAND	0x02000000
+-#define	SCR_STATUS	0x03000000
+-#define SCR_DT_DATA_OUT	0x04000000
+-#define SCR_DT_DATA_IN	0x05000000
+-#define SCR_MSG_OUT	0x06000000
+-#define SCR_MSG_IN      0x07000000
+-
+-#define SCR_ILG_OUT	0x04000000
+-#define SCR_ILG_IN	0x05000000
+-
+-/*-----------------------------------------------------------
+-**
+-**	Data transfer via SCSI.
+-**
+-**-----------------------------------------------------------
+-**
+-**	MOVE_ABS (LEN)
+-**	<<start address>>
+-**
+-**	MOVE_IND (LEN)
+-**	<<dnad_offset>>
+-**
+-**	MOVE_TBL
+-**	<<dnad_offset>>
+-**
+-**-----------------------------------------------------------
+-*/
+-
+-#define OPC_MOVE          0x08000000
+-
+-#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l))
+-#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l))
+-#define SCR_MOVE_TBL     (0x10000000 | OPC_MOVE)
+-
+-#define SCR_CHMOV_ABS(l) ((0x00000000) | (l))
+-#define SCR_CHMOV_IND(l) ((0x20000000) | (l))
+-#define SCR_CHMOV_TBL     (0x10000000)
+-
+-struct scr_tblmove {
+-        u32  size;
+-        u32  addr;
+-};
+-
+-/*-----------------------------------------------------------
+-**
+-**	Selection
+-**
+-**-----------------------------------------------------------
+-**
+-**	SEL_ABS | SCR_ID (0..15)    [ | REL_JMP]
+-**	<<alternate_address>>
+-**
+-**	SEL_TBL | << dnad_offset>>  [ | REL_JMP]
+-**	<<alternate_address>>
+-**
+-**-----------------------------------------------------------
+-*/
+-
+-#define	SCR_SEL_ABS	0x40000000
+-#define	SCR_SEL_ABS_ATN	0x41000000
+-#define	SCR_SEL_TBL	0x42000000
+-#define	SCR_SEL_TBL_ATN	0x43000000
+-
+-
+-#ifdef SCSI_NCR_BIG_ENDIAN
+-struct scr_tblsel {
+-        u8	sel_scntl3;
+-        u8	sel_id;
+-        u8	sel_sxfer;
+-        u8	sel_scntl4;	
+-};
+-#else
+-struct scr_tblsel {
+-        u8	sel_scntl4;	
+-        u8	sel_sxfer;
+-        u8	sel_id;
+-        u8	sel_scntl3;
+-};
+-#endif
+-
+-#define SCR_JMP_REL     0x04000000
+-#define SCR_ID(id)	(((u32)(id)) << 16)
+-
+-/*-----------------------------------------------------------
+-**
+-**	Waiting for Disconnect or Reselect
+-**
+-**-----------------------------------------------------------
+-**
+-**	WAIT_DISC
+-**	dummy: <<alternate_address>>
+-**
+-**	WAIT_RESEL
+-**	<<alternate_address>>
+-**
+-**-----------------------------------------------------------
+-*/
+-
+-#define	SCR_WAIT_DISC	0x48000000
+-#define SCR_WAIT_RESEL  0x50000000
+-
+-/*-----------------------------------------------------------
+-**
+-**	Bit Set / Reset
+-**
+-**-----------------------------------------------------------
+-**
+-**	SET (flags {|.. })
+-**
+-**	CLR (flags {|.. })
+-**
+-**-----------------------------------------------------------
+-*/
+-
+-#define SCR_SET(f)     (0x58000000 | (f))
+-#define SCR_CLR(f)     (0x60000000 | (f))
+-
+-#define	SCR_CARRY	0x00000400
+-#define	SCR_TRG		0x00000200
+-#define	SCR_ACK		0x00000040
+-#define	SCR_ATN		0x00000008
+-
+-
+-
+-
+-/*-----------------------------------------------------------
+-**
+-**	Memory to memory move
+-**
+-**-----------------------------------------------------------
+-**
+-**	COPY (bytecount)
+-**	<< source_address >>
+-**	<< destination_address >>
+-**
+-**	SCR_COPY   sets the NO FLUSH option by default.
+-**	SCR_COPY_F does not set this option.
+-**
+-**	For chips which do not support this option,
+-**	ncr_copy_and_bind() will remove this bit.
+-**-----------------------------------------------------------
+-*/
+-
+-#define SCR_NO_FLUSH 0x01000000
+-
+-#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n))
+-#define SCR_COPY_F(n) (0xc0000000 | (n))
+-
+-/*-----------------------------------------------------------
+-**
+-**	Register move and binary operations
+-**
+-**-----------------------------------------------------------
+-**
+-**	SFBR_REG (reg, op, data)        reg  = SFBR op data
+-**	<< 0 >>
+-**
+-**	REG_SFBR (reg, op, data)        SFBR = reg op data
+-**	<< 0 >>
+-**
+-**	REG_REG  (reg, op, data)        reg  = reg op data
+-**	<< 0 >>
+-**
+-**-----------------------------------------------------------
+-**	On 810A, 860, 825A, 875, 895 and 896 chips the content 
+-**	of SFBR register can be used as data (SCR_SFBR_DATA).
+-**	The 896 has additionnal IO registers starting at 
+-**	offset 0x80. Bit 7 of register offset is stored in 
+-**	bit 7 of the SCRIPTS instruction first DWORD.
+-**-----------------------------------------------------------
+-*/
+-
+-#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul) + ((ofs) & 0x80)) 
+-
+-#define SCR_SFBR_REG(reg,op,data) \
+-        (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+-
+-#define SCR_REG_SFBR(reg,op,data) \
+-        (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+-
+-#define SCR_REG_REG(reg,op,data) \
+-        (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+-
+-
+-#define      SCR_LOAD   0x00000000
+-#define      SCR_SHL    0x01000000
+-#define      SCR_OR     0x02000000
+-#define      SCR_XOR    0x03000000
+-#define      SCR_AND    0x04000000
+-#define      SCR_SHR    0x05000000
+-#define      SCR_ADD    0x06000000
+-#define      SCR_ADDC   0x07000000
+-
+-#define      SCR_SFBR_DATA   (0x00800000>>8ul)	/* Use SFBR as data */
+-
+-/*-----------------------------------------------------------
+-**
+-**	FROM_REG (reg)		  SFBR = reg
+-**	<< 0 >>
+-**
+-**	TO_REG	 (reg)		  reg  = SFBR
+-**	<< 0 >>
+-**
+-**	LOAD_REG (reg, data)	  reg  = <data>
+-**	<< 0 >>
+-**
+-**	LOAD_SFBR(data) 	  SFBR = <data>
+-**	<< 0 >>
+-**
+-**-----------------------------------------------------------
+-*/
+-
+-#define	SCR_FROM_REG(reg) \
+-	SCR_REG_SFBR(reg,SCR_OR,0)
+-
+-#define	SCR_TO_REG(reg) \
+-	SCR_SFBR_REG(reg,SCR_OR,0)
+-
+-#define	SCR_LOAD_REG(reg,data) \
+-	SCR_REG_REG(reg,SCR_LOAD,data)
+-
+-#define SCR_LOAD_SFBR(data) \
+-        (SCR_REG_SFBR (gpreg, SCR_LOAD, data))
+-
+-/*-----------------------------------------------------------
+-**
+-**	LOAD  from memory   to register.
+-**	STORE from register to memory.
+-**
+-**	Only supported by 810A, 860, 825A, 875, 895 and 896.
+-**
+-**-----------------------------------------------------------
+-**
+-**	LOAD_ABS (LEN)
+-**	<<start address>>
+-**
+-**	LOAD_REL (LEN)        (DSA relative)
+-**	<<dsa_offset>>
+-**
+-**-----------------------------------------------------------
+-*/
+-
+-#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul)
+-#define SCR_NO_FLUSH2	0x02000000
+-#define SCR_DSA_REL2	0x10000000
+-
+-#define SCR_LOAD_R(reg, how, n) \
+-        (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
+-
+-#define SCR_STORE_R(reg, how, n) \
+-        (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
+-
+-#define SCR_LOAD_ABS(reg, n)	SCR_LOAD_R(reg, SCR_NO_FLUSH2, n)
+-#define SCR_LOAD_REL(reg, n)	SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n)
+-#define SCR_LOAD_ABS_F(reg, n)	SCR_LOAD_R(reg, 0, n)
+-#define SCR_LOAD_REL_F(reg, n)	SCR_LOAD_R(reg, SCR_DSA_REL2, n)
+-
+-#define SCR_STORE_ABS(reg, n)	SCR_STORE_R(reg, SCR_NO_FLUSH2, n)
+-#define SCR_STORE_REL(reg, n)	SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n)
+-#define SCR_STORE_ABS_F(reg, n)	SCR_STORE_R(reg, 0, n)
+-#define SCR_STORE_REL_F(reg, n)	SCR_STORE_R(reg, SCR_DSA_REL2, n)
+-
+-
+-/*-----------------------------------------------------------
+-**
+-**	Waiting for Disconnect or Reselect
+-**
+-**-----------------------------------------------------------
+-**
+-**	JUMP            [ | IFTRUE/IFFALSE ( ... ) ]
+-**	<<address>>
+-**
+-**	JUMPR           [ | IFTRUE/IFFALSE ( ... ) ]
+-**	<<distance>>
+-**
+-**	CALL            [ | IFTRUE/IFFALSE ( ... ) ]
+-**	<<address>>
+-**
+-**	CALLR           [ | IFTRUE/IFFALSE ( ... ) ]
+-**	<<distance>>
+-**
+-**	RETURN          [ | IFTRUE/IFFALSE ( ... ) ]
+-**	<<dummy>>
+-**
+-**	INT             [ | IFTRUE/IFFALSE ( ... ) ]
+-**	<<ident>>
+-**
+-**	INT_FLY         [ | IFTRUE/IFFALSE ( ... ) ]
+-**	<<ident>>
+-**
+-**	Conditions:
+-**	     WHEN (phase)
+-**	     IF   (phase)
+-**	     CARRYSET
+-**	     DATA (data, mask)
+-**
+-**-----------------------------------------------------------
+-*/
+-
+-#define SCR_NO_OP       0x80000000
+-#define SCR_JUMP        0x80080000
+-#define SCR_JUMP64      0x80480000
+-#define SCR_JUMPR       0x80880000
+-#define SCR_CALL        0x88080000
+-#define SCR_CALLR       0x88880000
+-#define SCR_RETURN      0x90080000
+-#define SCR_INT         0x98080000
+-#define SCR_INT_FLY     0x98180000
+-
+-#define IFFALSE(arg)   (0x00080000 | (arg))
+-#define IFTRUE(arg)    (0x00000000 | (arg))
+-
+-#define WHEN(phase)    (0x00030000 | (phase))
+-#define IF(phase)      (0x00020000 | (phase))
+-
+-#define DATA(D)        (0x00040000 | ((D) & 0xff))
+-#define MASK(D,M)      (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff))
+-
+-#define CARRYSET       (0x00200000)
+-
+-/*-----------------------------------------------------------
+-**
+-**	SCSI  constants.
+-**
+-**-----------------------------------------------------------
+-*/
+-
+-/*
+-**	Messages
+-*/
+-
+-#define	M_COMPLETE	COMMAND_COMPLETE
+-#define	M_EXTENDED	EXTENDED_MESSAGE
+-#define	M_SAVE_DP	SAVE_POINTERS
+-#define	M_RESTORE_DP	RESTORE_POINTERS
+-#define	M_DISCONNECT	DISCONNECT
+-#define	M_ID_ERROR	INITIATOR_ERROR
+-#define	M_ABORT		ABORT_TASK_SET
+-#define	M_REJECT	MESSAGE_REJECT
+-#define	M_NOOP		NOP
+-#define	M_PARITY	MSG_PARITY_ERROR
+-#define	M_LCOMPLETE	LINKED_CMD_COMPLETE
+-#define	M_FCOMPLETE	LINKED_FLG_CMD_COMPLETE
+-#define	M_RESET		TARGET_RESET
+-#define	M_ABORT_TAG	ABORT_TASK
+-#define	M_CLEAR_QUEUE	CLEAR_TASK_SET
+-#define	M_INIT_REC	INITIATE_RECOVERY
+-#define	M_REL_REC	RELEASE_RECOVERY
+-#define	M_TERMINATE	(0x11)
+-#define	M_SIMPLE_TAG	SIMPLE_QUEUE_TAG
+-#define	M_HEAD_TAG	HEAD_OF_QUEUE_TAG
+-#define	M_ORDERED_TAG	ORDERED_QUEUE_TAG
+-#define	M_IGN_RESIDUE	IGNORE_WIDE_RESIDUE
+-#define	M_IDENTIFY   	(0x80)
+-
+-#define	M_X_MODIFY_DP	EXTENDED_MODIFY_DATA_POINTER
+-#define	M_X_SYNC_REQ	EXTENDED_SDTR
+-#define	M_X_WIDE_REQ	EXTENDED_WDTR
+-#define	M_X_PPR_REQ	EXTENDED_PPR
+-
+-/*
+-**	Status
+-*/
+-
+-#define	S_GOOD		(0x00)
+-#define	S_CHECK_COND	(0x02)
+-#define	S_COND_MET	(0x04)
+-#define	S_BUSY		(0x08)
+-#define	S_INT		(0x10)
+-#define	S_INT_COND_MET	(0x14)
+-#define	S_CONFLICT	(0x18)
+-#define	S_TERMINATED	(0x20)
+-#define	S_QUEUE_FULL	(0x28)
+-#define	S_ILLEGAL	(0xff)
+-#define	S_SENSE		(0x80)
+-
+-/*
+- * End of ncrreg from FreeBSD
+- */
+-
+-#endif /* defined SYM53C8XX_DEFS_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/serial/serial_core.c CVS2_6_15_RC7_PA0/drivers/serial/serial_core.c
+--- LINUS_2_6_15_RC7/drivers/serial/serial_core.c	2005-12-27 13:25:49.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/serial/serial_core.c	2005-11-29 11:03:08.000000000 -0700
+@@ -1961,6 +1961,7 @@
+ uart_report_port(struct uart_driver *drv, struct uart_port *port)
+ {
+ 	char address[64];
++	char irq[16];
+ 
+ 	switch (port->iotype) {
+ 	case UPIO_PORT:
+@@ -1982,10 +1983,19 @@
+ 		break;
+ 	}
+ 
+-	printk(KERN_INFO "%s%s%s%d at %s (irq = %d) is a %s\n",
++#ifndef NO_IRQ
++#define NO_IRQ (-1)
++#endif
++	if (port->irq == NO_IRQ) {
++		strlcpy(irq, "polled", sizeof(irq));
++	} else {
++		snprintf(irq, sizeof(irq), "irq = %d", port->irq);
++	}
++
++	printk(KERN_INFO "%s%s%s%d at %s (%s) is a %s\n",
+ 	       port->dev ? port->dev->bus_id : "",
+ 	       port->dev ? ": " : "",
+-	       drv->dev_name, port->line, address, port->irq, uart_type(port));
++	       drv->dev_name, port->line, address, irq, uart_type(port));
+ }
+ 
+ static void
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/usb/input/hid-core.c CVS2_6_15_RC7_PA0/drivers/usb/input/hid-core.c
+--- LINUS_2_6_15_RC7/drivers/usb/input/hid-core.c	2005-12-27 13:25:50.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/usb/input/hid-core.c	2005-12-19 05:42:37.000000000 -0700
+@@ -760,21 +760,31 @@
+ }
+ 
+ /*
+- * Extract/implement a data field from/to a report.
++ * Extract/implement a data field from/to a little endian report (bit array).
+  */
+ 
+ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n)
+ {
+-	report += (offset >> 5) << 2; offset &= 31;
+-	return (le64_to_cpu(get_unaligned((__le64*)report)) >> offset) & ((1ULL << n) - 1);
++	u32 x;
++
++	report += offset >> 3;  /* adjust byte index */
++	offset &= 8 - 1;
++	x = get_unaligned((u32 *) report);
++	x = le32_to_cpu(x);
++	x = (x >> offset) & ((1 << n) - 1);
++	return x;
+ }
+ 
+ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value)
+ {
+-	report += (offset >> 5) << 2; offset &= 31;
+-	put_unaligned((get_unaligned((__le64*)report)
+-		& cpu_to_le64(~((((__u64) 1 << n) - 1) << offset)))
+-		| cpu_to_le64((__u64)value << offset), (__le64*)report);
++	u32 x;
++
++	report += offset >> 3;
++	offset &= 8 - 1;
++	x = get_unaligned((u32 *)report);
++	x &= cpu_to_le32(~((((__u32) 1 << n) - 1) << offset));
++	x |= cpu_to_le32(value << offset);
++	put_unaligned(x,(u32 *)report);
+ }
+ 
+ /*
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/drivers/video/stifb.c CVS2_6_15_RC7_PA0/drivers/video/stifb.c
+--- LINUS_2_6_15_RC7/drivers/video/stifb.c	2005-12-27 13:25:50.000000000 -0700
++++ CVS2_6_15_RC7_PA0/drivers/video/stifb.c	2005-12-19 08:32:13.000000000 -0700
+@@ -3,7 +3,7 @@
+  * Low level Frame buffer driver for HP workstations with 
+  * STI (standard text interface) video firmware.
+  *
+- * Copyright (C) 2001-2004 Helge Deller <deller at gmx.de>
++ * Copyright (C) 2001-2005 Helge Deller <deller at gmx.de>
+  * Portions Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at alpha.franken.de>
+  * 
+  * Based on:
+@@ -73,16 +73,13 @@
+ #include "sticore.h"
+ 
+ /* REGION_BASE(fb_info, index) returns the virtual address for region <index> */
+-#ifdef __LP64__
+-  #define REGION_BASE(fb_info, index) \
+-	(fb_info->sti->glob_cfg->region_ptrs[index] | 0xffffffff00000000)
+-#else
+-  #define REGION_BASE(fb_info, index) \
+-	fb_info->sti->glob_cfg->region_ptrs[index]
+-#endif
++#define REGION_BASE(fb_info, index) \
++	F_EXTEND(fb_info->sti->glob_cfg->region_ptrs[index])
+ 
+ #define NGLEDEVDEPROM_CRT_REGION 1
+ 
++#define NR_PALETTE 256
++
+ typedef struct {
+ 	__s32	video_config_reg;
+ 	__s32	misc_video_start;
+@@ -112,7 +109,7 @@
+ 	ngle_rom_t ngle_rom;
+ 	struct sti_struct *sti;
+ 	int deviceSpecificConfig;
+-	u32 pseudo_palette[256];
++	u32 pseudo_palette[16];
+ };
+ 
+ static int __initdata stifb_bpp_pref[MAX_STI_ROMS];
+@@ -352,10 +349,10 @@
+ #define IS_888_DEVICE(fb) \
+ 	(!(IS_24_DEVICE(fb)))
+ 
+-#define GET_FIFO_SLOTS(fb, cnt, numslots)			\
+-{	while (cnt < numslots) 					\
++#define GET_FIFO_SLOTS(fb, cnt, numslots)	\
++{	while (cnt < numslots) 			\
+ 		cnt = READ_WORD(fb, REG_34);	\
+-	cnt -= numslots;					\
++	cnt -= numslots;			\
+ }
+ 
+ #define	    IndexedDcd	0	/* Pixel data is indexed (pseudo) color */
+@@ -995,7 +992,7 @@
+ 	struct stifb_info *fb = (struct stifb_info *) info;
+ 	u32 color;
+ 
+-	if (regno >= 256)  /* no. of hw registers */
++	if (regno >= NR_PALETTE)
+ 		return 1;
+ 
+ 	red   >>= 8;
+@@ -1005,8 +1002,8 @@
+ 	DEBUG_OFF();
+ 
+ 	START_IMAGE_COLORMAP_ACCESS(fb);
+-	
+-	if (fb->info.var.grayscale) {
++
++	if (unlikely(fb->info.var.grayscale)) {
+ 		/* gray = 0.30*R + 0.59*G + 0.11*B */
+ 		color = ((red * 77) +
+ 			 (green * 151) +
+@@ -1017,17 +1014,17 @@
+ 			 (blue));
+ 	}
+ 
+-	if (info->var.bits_per_pixel == 32) {
+-		((u32 *)(info->pseudo_palette))[regno] =
+-			(red   << info->var.red.offset)   |
+-			(green << info->var.green.offset) |
+-			(blue  << info->var.blue.offset);
+-	} else {
+-		((u32 *)(info->pseudo_palette))[regno] = regno;
++	if (fb->info.fix.visual == FB_VISUAL_DIRECTCOLOR) {
++		struct fb_var_screeninfo *var = &fb->info.var;
++		if (regno < 16)
++			((u32 *)fb->info.pseudo_palette)[regno] =
++				regno << var->red.offset |
++				regno << var->green.offset |
++				regno << var->blue.offset;
+ 	}
+ 
+ 	WRITE_IMAGE_COLOR(fb, regno, color);
+-	
++
+ 	if (fb->id == S9000_ID_HCRX) {
+ 		NgleLutBltCtl lutBltCtl;
+ 
+@@ -1066,9 +1063,9 @@
+ 	case S9000_ID_HCRX:
+ 		HYPER_ENABLE_DISABLE_DISPLAY(fb, enable);
+ 		break;
+-	case S9000_ID_A1659A:;	/* fall through */
+-	case S9000_ID_TIMBER:;
+-	case CRX24_OVERLAY_PLANES:;
++	case S9000_ID_A1659A:	/* fall through */
++	case S9000_ID_TIMBER:
++	case CRX24_OVERLAY_PLANES:
+ 	default:
+ 		ENABLE_DISABLE_DISPLAY(fb, enable);
+ 		break;
+@@ -1250,12 +1247,10 @@
+ 		memset(&fb->ngle_rom, 0, sizeof(fb->ngle_rom));
+ 		if ((fb->sti->regions_phys[0] & 0xfc000000) ==
+ 		    (fb->sti->regions_phys[2] & 0xfc000000))
+-			sti_rom_address = fb->sti->regions_phys[0];
++			sti_rom_address = F_EXTEND(fb->sti->regions_phys[0]);
+ 		else
+-			sti_rom_address = fb->sti->regions_phys[1];
+-#ifdef __LP64__
+-	        sti_rom_address |= 0xffffffff00000000;
+-#endif
++			sti_rom_address = F_EXTEND(fb->sti->regions_phys[1]);
++
+ 		fb->deviceSpecificConfig = gsc_readl(sti_rom_address);
+ 		if (IS_24_DEVICE(fb)) {
+ 			if (bpp_pref == 8 || bpp_pref == 32)
+@@ -1315,7 +1310,7 @@
+ 		break;
+ 	    case 32:
+ 		fix->type = FB_TYPE_PACKED_PIXELS;
+-		fix->visual = FB_VISUAL_TRUECOLOR;
++		fix->visual = FB_VISUAL_DIRECTCOLOR;
+ 		var->red.length = var->green.length = var->blue.length = var->transp.length = 8;
+ 		var->blue.offset = 0;
+ 		var->green.offset = 8;
+@@ -1337,7 +1332,7 @@
+ 	info->pseudo_palette = &fb->pseudo_palette;
+ 
+ 	/* This has to been done !!! */
+-	fb_alloc_cmap(&info->cmap, 256, 0);
++	fb_alloc_cmap(&info->cmap, NR_PALETTE, 0);
+ 	stifb_init_display(fb);
+ 
+ 	if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb fb")) {
+@@ -1488,7 +1483,3 @@
+ MODULE_AUTHOR("Helge Deller <deller at gmx.de>, Thomas Bogendoerfer <tsbogend at alpha.franken.de>");
+ MODULE_DESCRIPTION("Framebuffer driver for HP's NGLE series graphics cards in HP PARISC machines");
+ MODULE_LICENSE("GPL v2");
+-
+-MODULE_PARM(bpp, "i");
+-MODULE_PARM_DESC(mem, "Bits per pixel (default: 8)");
+-
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-generic/compat_signal.h CVS2_6_15_RC7_PA0/include/asm-generic/compat_signal.h
+--- LINUS_2_6_15_RC7/include/asm-generic/compat_signal.h	1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/asm-generic/compat_signal.h	2004-01-27 22:12:47.000000000 -0700
+@@ -0,0 +1,25 @@
++#ifndef _ASM_GENERIC_COMPAT_SIGNAL_H
++#define _ASM_GENERIC_COMPAT_SIGNAL_H
++
++#ifndef __ASSEMBLY__
++#include <linux/compat.h>
++
++typedef compat_uptr_t compat_sighandler_t;
++
++typedef struct compat_sigaltstack {
++	compat_uptr_t ss_sp;
++	compat_int_t ss_flags;
++	compat_size_t ss_size;
++} compat_stack_t;
++
++/* Most things should be clean enough to redefine this at will, if care
++   is taken to make libc match.  */
++
++struct compat_sigaction {
++	compat_sighandler_t sa_handler;
++	compat_uint_t sa_flags;
++	compat_sigset_t sa_mask;		/* mask last for extensibility */
++};
++
++#endif /* !__ASSEMBLY__ */
++#endif /* !_ASM_GENERIC_COMPAT_SIGNAL_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-ia64/compat.h CVS2_6_15_RC7_PA0/include/asm-ia64/compat.h
+--- LINUS_2_6_15_RC7/include/asm-ia64/compat.h	2005-12-27 13:25:53.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/asm-ia64/compat.h	2005-09-14 06:57:31.000000000 -0600
+@@ -15,6 +15,9 @@
+ typedef s32		compat_pid_t;
+ typedef u16		__compat_uid_t;
+ typedef u16		__compat_gid_t;
++/* Define for use in compat_siginfo_t */
++#undef __ARCH_SI_COMPAT_UID_T
++#define __ARCH_SI_COMPAT_UID_T	__compat_uid32_t
+ typedef u32		__compat_uid32_t;
+ typedef u32		__compat_gid32_t;
+ typedef u16		compat_mode_t;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-parisc/cache.h CVS2_6_15_RC7_PA0/include/asm-parisc/cache.h
+--- LINUS_2_6_15_RC7/include/asm-parisc/cache.h	2005-12-27 13:25:54.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/asm-parisc/cache.h	2005-12-16 06:02:55.000000000 -0700
+@@ -30,14 +30,14 @@
+ #define SMP_CACHE_BYTES L1_CACHE_BYTES
+ #define L1_CACHE_SHIFT_MAX 5	/* largest L1 which this arch supports */
+ 
+-extern void flush_data_cache_local(void);  /* flushes local data-cache only */
+-extern void flush_instruction_cache_local(void); /* flushes local code-cache only */
++extern void flush_data_cache_local(void *);  /* flushes local data-cache only */
++extern void flush_instruction_cache_local(void *); /* flushes local code-cache only */
+ #ifdef CONFIG_SMP
+ extern void flush_data_cache(void); /* flushes data-cache only (all processors) */
+ extern void flush_instruction_cache(void); /* flushes i-cache only (all processors) */
+ #else
+-#define flush_data_cache flush_data_cache_local
+-#define flush_instruction_cache flush_instruction_cache_local
++#define flush_data_cache() flush_data_cache_local(NULL)
++#define flush_instruction_cache() flush_instruction_cache_local(NULL)
+ #endif
+ 
+ extern void parisc_cache_init(void);	/* initializes cache-flushing */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-parisc/io.h CVS2_6_15_RC7_PA0/include/asm-parisc/io.h
+--- LINUS_2_6_15_RC7/include/asm-parisc/io.h	2005-12-27 13:25:54.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/asm-parisc/io.h	2005-12-23 19:01:55.000000000 -0700
+@@ -41,7 +41,7 @@
+ #define __raw_check_addr(addr)					\
+ 	if (((unsigned long)addr >> NYBBLE_SHIFT) != 0xe)	\
+ 		__raw_bad_addr(addr);			\
+-	addr = (void *)((unsigned long)addr | (0xfUL << NYBBLE_SHIFT));
++	addr = (void __iomem *)((unsigned long)addr | (0xfUL << NYBBLE_SHIFT));
+ #else
+ #define gsc_check_addr(addr)
+ #define __raw_check_addr(addr)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-parisc/page.h CVS2_6_15_RC7_PA0/include/asm-parisc/page.h
+--- LINUS_2_6_15_RC7/include/asm-parisc/page.h	2005-12-27 13:25:54.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/asm-parisc/page.h	2005-12-12 14:28:25.000000000 -0700
+@@ -135,6 +135,13 @@
+ #define pfn_valid(pfn)		((pfn) < max_mapnr)
+ #endif /* CONFIG_DISCONTIGMEM */
+ 
++#ifdef CONFIG_HUGETLB_PAGE
++#define HPAGE_SHIFT		22	/* 4MB (is this fixed?) */
++#define HPAGE_SIZE      	((1UL) << HPAGE_SHIFT)
++#define HPAGE_MASK		(~(HPAGE_SIZE - 1))
++#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
++#endif
++
+ #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+ 
+ #define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-parisc/pci.h CVS2_6_15_RC7_PA0/include/asm-parisc/pci.h
+--- LINUS_2_6_15_RC7/include/asm-parisc/pci.h	2005-12-27 13:25:54.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/asm-parisc/pci.h	2005-12-15 12:34:46.000000000 -0700
+@@ -84,11 +84,17 @@
+ /*
+ ** Convert between PCI (IO_VIEW) addresses and processor (PA_VIEW) addresses.
+ ** See pcibios.c for more conversions used by Generic PCI code.
++**
++** Platform characteristics/firmware guarantee that
++**	(1) PA_VIEW - IO_VIEW = lmmio_offset for both LMMIO and ELMMIO
++**	(2) PA_VIEW == IO_VIEW for GMMIO
+ */
+ #define PCI_BUS_ADDR(hba,a)	(PCI_IS_LMMIO(hba,a)	\
+ 		?  ((a) - hba->lmmio_space_offset)	/* mangle LMMIO */ \
+ 		: (a))					/* GMMIO */
+-#define PCI_HOST_ADDR(hba,a)	((a) + hba->lmmio_space_offset)
++#define PCI_HOST_ADDR(hba,a)	(((a) & PCI_F_EXTEND) == 0 \
++		? (a) + hba->lmmio_space_offset \
++		: (a))
+ 
+ #else	/* !CONFIG_64BIT */
+ 
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-parisc/processor.h CVS2_6_15_RC7_PA0/include/asm-parisc/processor.h
+--- LINUS_2_6_15_RC7/include/asm-parisc/processor.h	2005-12-27 13:25:54.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/asm-parisc/processor.h	2005-12-23 19:03:24.000000000 -0700
+@@ -144,16 +144,16 @@
+         })
+ 
+ #define INIT_THREAD { \
+-	regs:	{	gr: { 0, }, \
+-			fr: { 0, }, \
+-			sr: { 0, }, \
+-			iasq: { 0, }, \
+-			iaoq: { 0, }, \
+-			cr27: 0, \
++	.regs = {	.gr	= { 0, }, \
++			.fr	= { 0, }, \
++			.sr	= { 0, }, \
++			.iasq	= { 0, }, \
++			.iaoq	= { 0, }, \
++			.cr27	= 0, \
+ 		}, \
+-	task_size:      DEFAULT_TASK_SIZE, \
+-	map_base:       DEFAULT_MAP_BASE, \
+-	flags:          0 \
++	.task_size	= DEFAULT_TASK_SIZE, \
++	.map_base	= DEFAULT_MAP_BASE, \
++	.flags		= 0 \
+ 	}
+ 
+ /*
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-parisc/tlbflush.h CVS2_6_15_RC7_PA0/include/asm-parisc/tlbflush.h
+--- LINUS_2_6_15_RC7/include/asm-parisc/tlbflush.h	2005-12-27 13:25:54.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/asm-parisc/tlbflush.h	2005-12-15 11:12:46.000000000 -0700
+@@ -22,6 +22,7 @@
+ #define purge_tlb_end(x) spin_unlock(&pa_tlb_lock)
+ 
+ extern void flush_tlb_all(void);
++extern void flush_tlb_all_local(void *);
+ 
+ /*
+  * flush_tlb_mm()
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-s390/compat.h CVS2_6_15_RC7_PA0/include/asm-s390/compat.h
+--- LINUS_2_6_15_RC7/include/asm-s390/compat.h	2005-12-27 13:25:54.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/asm-s390/compat.h	2005-09-14 06:57:44.000000000 -0600
+@@ -15,6 +15,9 @@
+ typedef s32		compat_pid_t;
+ typedef u16		__compat_uid_t;
+ typedef u16		__compat_gid_t;
++/* Define for use in compat_siginfo_t */
++#undef __ARCH_SI_COMPAT_UID_T
++#define __ARCH_SI_COMPAT_UID_T __compat_uid32_t
+ typedef u32		__compat_uid32_t;
+ typedef u32		__compat_gid32_t;
+ typedef u16		compat_mode_t;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-sparc64/compat.h CVS2_6_15_RC7_PA0/include/asm-sparc64/compat.h
+--- LINUS_2_6_15_RC7/include/asm-sparc64/compat.h	2005-12-27 13:25:54.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/asm-sparc64/compat.h	2005-09-14 06:57:45.000000000 -0600
+@@ -14,6 +14,9 @@
+ typedef s32		compat_pid_t;
+ typedef u16		__compat_uid_t;
+ typedef u16		__compat_gid_t;
++/* Define for use in the compat_siginfo_t */
++#undef __ARCH_SI_COMPAT_UID_T
++#define __ARCH_SI_COMPAT_UID_T compat_uint_t
+ typedef u32		__compat_uid32_t;
+ typedef u32		__compat_gid32_t;
+ typedef u16		compat_mode_t;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-x86_64/compat.h CVS2_6_15_RC7_PA0/include/asm-x86_64/compat.h
+--- LINUS_2_6_15_RC7/include/asm-x86_64/compat.h	2005-12-27 13:25:55.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/asm-x86_64/compat.h	2005-11-12 20:29:21.000000000 -0700
+@@ -16,6 +16,9 @@
+ typedef s32		compat_pid_t;
+ typedef u16		__compat_uid_t;
+ typedef u16		__compat_gid_t;
++/* Define for use in compat_siginfo_t */
++#undef __ARCH_SI_COMPAT_UID_T
++#define __ARCH_SI_COMPAT_UID_T __compat_uid32_t
+ typedef u32		__compat_uid32_t;
+ typedef u32		__compat_gid32_t;
+ typedef u16		compat_mode_t;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/asm-x86_64/ia32.h CVS2_6_15_RC7_PA0/include/asm-x86_64/ia32.h
+--- LINUS_2_6_15_RC7/include/asm-x86_64/ia32.h	2005-12-27 13:25:55.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/asm-x86_64/ia32.h	2005-11-19 22:09:34.000000000 -0700
+@@ -6,6 +6,7 @@
+ #ifdef CONFIG_IA32_EMULATION
+ 
+ #include <linux/compat.h>
++#include <linux/compat_siginfo.h>
+ 
+ /*
+  * 32 bit structures for IA32 support.
+@@ -78,58 +79,6 @@
+ 	unsigned long long	st_ino;
+ } __attribute__((packed));
+ 
+-typedef struct compat_siginfo{
+-	int si_signo;
+-	int si_errno;
+-	int si_code;
+-
+-	union {
+-		int _pad[((128/sizeof(int)) - 3)];
+-
+-		/* kill() */
+-		struct {
+-			unsigned int _pid;	/* sender's pid */
+-			unsigned int _uid;	/* sender's uid */
+-		} _kill;
+-
+-		/* POSIX.1b timers */
+-		struct {
+-			compat_timer_t _tid;	/* timer id */
+-			int _overrun;		/* overrun count */
+-			compat_sigval_t _sigval;	/* same as below */
+-			int _sys_private;	/* not to be passed to user */
+-			int _overrun_incr;	/* amount to add to overrun */
+-		} _timer;
+-
+-		/* POSIX.1b signals */
+-		struct {
+-			unsigned int _pid;	/* sender's pid */
+-			unsigned int _uid;	/* sender's uid */
+-			compat_sigval_t _sigval;
+-		} _rt;
+-
+-		/* SIGCHLD */
+-		struct {
+-			unsigned int _pid;	/* which child */
+-			unsigned int _uid;	/* sender's uid */
+-			int _status;		/* exit code */
+-			compat_clock_t _utime;
+-			compat_clock_t _stime;
+-		} _sigchld;
+-
+-		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+-		struct {
+-			unsigned int _addr;	/* faulting insn/memory ref. */
+-		} _sigfault;
+-
+-		/* SIGPOLL */
+-		struct {
+-			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+-			int _fd;
+-		} _sigpoll;
+-	} _sifields;
+-} compat_siginfo_t;
+-
+ struct sigframe32
+ {
+         u32 pretcode;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/linux/cache.h CVS2_6_15_RC7_PA0/include/linux/cache.h
+--- LINUS_2_6_15_RC7/include/linux/cache.h	2005-12-27 13:25:55.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/linux/cache.h	2005-12-19 05:42:41.000000000 -0700
+@@ -13,7 +13,7 @@
+ #define SMP_CACHE_BYTES L1_CACHE_BYTES
+ #endif
+ 
+-#if defined(CONFIG_X86) || defined(CONFIG_SPARC64) || defined(CONFIG_IA64)
++#if defined(CONFIG_X86) || defined(CONFIG_SPARC64) || defined(CONFIG_IA64) || defined(CONFIG_PARISC)
+ #define __read_mostly __attribute__((__section__(".data.read_mostly")))
+ #else
+ #define __read_mostly
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/linux/compat.h CVS2_6_15_RC7_PA0/include/linux/compat.h
+--- LINUS_2_6_15_RC7/include/linux/compat.h	2005-12-27 13:25:55.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/linux/compat.h	2005-09-14 06:57:49.000000000 -0600
+@@ -6,10 +6,16 @@
+  */
+ #include <linux/config.h>
+ 
+-#ifdef CONFIG_COMPAT
++#ifndef CONFIG_COMPAT
++
++/* Non-native task requiring compat... doesn't exist */
++#define is_compat_task(x) 0
++
++#else
+ 
+ #include <linux/stat.h>
+ #include <linux/param.h>	/* for HZ */
++#include <linux/personality.h>  /* Conditional process compat */
+ #include <linux/sem.h>
+ 
+ #include <asm/compat.h>
+@@ -18,6 +24,11 @@
+ #define compat_jiffies_to_clock_t(x)	\
+ 		(((unsigned long)(x) * COMPAT_USER_HZ) / HZ)
+ 
++/* Non-native task requiring compat */
++#ifndef HAVE_ARCH_IS_COMPAT_TASK
++#define is_compat_task(x) (personality(x->personality) == PER_LINUX32)
++#endif
++
+ typedef __compat_uid32_t	compat_uid_t;
+ typedef __compat_gid32_t	compat_gid_t;
+ 
+@@ -99,28 +110,6 @@
+ 	char		d_name[256];
+ };
+ 
+-typedef union compat_sigval {
+-	compat_int_t	sival_int;
+-	compat_uptr_t	sival_ptr;
+-} compat_sigval_t;
+-
+-#define COMPAT_SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
+-
+-typedef struct compat_sigevent {
+-	compat_sigval_t sigev_value;
+-	compat_int_t sigev_signo;
+-	compat_int_t sigev_notify;
+-	union {
+-		compat_int_t _pad[COMPAT_SIGEV_PAD_SIZE];
+-		compat_int_t _tid;
+-
+-		struct {
+-			compat_uptr_t _function;
+-			compat_uptr_t _attribute;
+-		} _sigev_thread;
+-	} _sigev_un;
+-} compat_sigevent_t;
+-
+ 
+ long compat_sys_semctl(int first, int second, int third, void __user *uptr);
+ long compat_sys_msgsnd(int first, int second, int third, void __user *uptr);
+@@ -156,10 +145,6 @@
+ 		       unsigned long bitmap_size);
+ long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
+ 		       unsigned long bitmap_size);
+-int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from);
+-int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from);
+-int get_compat_sigevent(struct sigevent *event,
+-		const struct compat_sigevent __user *u_event);
+ 
+ #endif /* CONFIG_COMPAT */
+ #endif /* _LINUX_COMPAT_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/linux/compat_siginfo.h CVS2_6_15_RC7_PA0/include/linux/compat_siginfo.h
+--- LINUS_2_6_15_RC7/include/linux/compat_siginfo.h	1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/linux/compat_siginfo.h	2005-08-02 08:33:30.000000000 -0600
+@@ -0,0 +1,182 @@
++#ifndef _ASM_GENERIC_COMPAT_SIGINFO_H
++#define _ASM_GENERIC_COMPAT_SIGINFO_H
++
++#include <linux/config.h>
++#include <linux/compat.h>
++
++#ifndef CONFIG_COMPAT
++
++/* No compatibility layer required, add empty definitions for the compiler */
++
++typedef struct compat_siginfo{
++} compat_siginfo_t;
++
++static inline int compat_copy_siginfo_to_user(compat_siginfo_t __user *to, 
++						struct siginfo *from)
++{
++	return -1;
++}
++
++static inline int compat_copy_siginfo_from_user(struct siginfo *to,
++                                                compat_siginfo_t __user *from)
++{
++        return -1;
++}
++
++#else
++
++#include <linux/compiler.h>
++#include <asm/siginfo.h>
++
++/* compat view of sigval_t */
++typedef union compat_sigval {
++	compat_int_t sival_int;
++	compat_uptr_t sival_ptr;
++} compat_sigval_t;
++
++/*
++ * This is the size (including padding) of the part of the
++ * struct siginfo that is before the union.
++ */
++#ifndef __ARCH_SI_COMPAT_PREAMBLE_SIZE
++#define __ARCH_SI_COMPAT_PREAMBLE_SIZE	(3 * sizeof(compat_int_t))
++#endif
++
++#define SI_COMPAT_MAX_SIZE	128
++#ifndef SI_COMPAT_PAD_SIZE
++#define SI_COMPAT_PAD_SIZE \
++  ((SI_COMPAT_MAX_SIZE - __ARCH_SI_COMPAT_PREAMBLE_SIZE) / sizeof(compat_int_t))
++#endif
++
++/* 32-bit view of si.uid_t */
++#ifndef __ARCH_SI_COMPAT_UID_T
++#define __ARCH_SI_COMPAT_UID_T compat_uid_t
++#endif
++
++/* 32-bit view of si.band_t */
++#ifndef __ARCH_SI_COMPAT_BAND_T
++#define __ARCH_SI_COMPAT_BAND_T compat_int_t
++#endif
++
++#ifndef HAVE_ARCH_COMPAT_SIGINFO_T
++
++/* Compat view of siginfo_t */
++typedef struct compat_siginfo {
++	compat_int_t si_signo;
++	compat_int_t si_errno;
++	compat_int_t si_code;
++
++	union {
++		compat_int_t _pad[SI_COMPAT_PAD_SIZE];
++
++		/* kill() */
++		struct {
++			compat_pid_t _pid;	/* sender's pid */
++			__ARCH_SI_COMPAT_UID_T _uid;	/* sender's uid */
++		} _kill;
++
++		/* POSIX.1b timers */
++		struct {
++			compat_timer_t _tid;	/* timer id */
++			compat_int_t _overrun;		/* overrun count */
++			char _pad[sizeof(__ARCH_SI_COMPAT_UID_T) - sizeof(compat_int_t)];
++			compat_sigval_t _sigval;	/* same as below */
++			compat_int_t _sys_private;       /* not to be passed to user */
++		} _timer;
++
++		/* POSIX.1b signals */
++		struct {
++			compat_pid_t _pid;		/* sender's pid */
++			__ARCH_SI_COMPAT_UID_T _uid;	/* sender's uid */
++			compat_sigval_t _sigval;
++		} _rt;
++
++		/* SIGCHLD */
++		struct {
++			compat_pid_t _pid;		/* which child */
++			__ARCH_SI_COMPAT_UID_T _uid;	/* sender's uid */
++			compat_int_t _status;		/* exit code */
++			compat_clock_t _utime;
++			compat_clock_t _stime;
++		} _sigchld;
++
++		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
++		struct {
++			compat_uptr_t _addr; /* faulting insn/memory ref. */
++#ifdef __ARCH_SI_COMPAT_TRAPNO
++			compat_int_t _trapno;	/* TRAP # which caused the signal */
++#endif
++		} _sigfault;
++
++		/* SIGPOLL */
++		struct {
++			__ARCH_SI_COMPAT_BAND_T _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
++			compat_int_t _fd;
++		} _sigpoll;
++	} _sifields;
++} compat_siginfo_t;
++#endif /* !HAVE_ARCH_COMPAT_SIGINFO_T */
++
++#ifdef __ARCH_SI_COMPAT_TRAPNO
++#define si_trapno	_sifields._sigfault._trapno
++#endif
++
++/*
++ * sigevent definitions
++ * 
++ * It seems likely that SIGEV_THREAD will have to be handled from 
++ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
++ * thread manager then catches and does the appropriate nonsense.
++ * However, everything is written out here so as to not get lost.
++ */
++
++#ifndef __ARCH_SIGEV_COMPAT_PREAMBLE_SIZE
++#define __ARCH_SIGEV_COMPAT_PREAMBLE_SIZE (sizeof(compat_int_t) * 2 + sizeof(compat_sigval_t))
++#endif
++
++#define COMPAT_SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE/sizeof(int)) - 3)
++
++#ifndef HAVE_ARCH_COMPAT_SIGEVENT_T
++
++/* 32-bit view of sigevent_t */
++typedef struct compat_sigevent {
++	compat_sigval_t sigev_value;
++	compat_int_t sigev_signo;
++	compat_int_t sigev_notify;
++	union {
++		compat_int_t _pad[COMPAT_SIGEV_PAD_SIZE];
++		compat_int_t _tid;
++
++		struct {
++			compat_uptr_t _function;
++			compat_uptr_t _attribute;  /* really pthread_attr_t */
++		} _sigev_thread;
++	} _sigev_un;
++} compat_sigevent_t;
++
++#endif /* HAVE_ARCH_COMPAT_SIGEVENT_T */
++
++#ifndef HAVE_ARCH_COMPAT_COPY_SIGINFO
++
++#include <linux/string.h>
++
++static inline void compat_copy_siginfo(struct compat_siginfo *to, struct compat_siginfo *from)
++{
++	if (from->si_code < 0)
++		memcpy(to, from, sizeof(*to));
++	else
++		/* _sigchld is currently the largest know union member */
++		memcpy(to, from, __ARCH_SI_COMPAT_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld));
++}
++
++#endif /* !HAVE_ARCH_COMPAT_COPY_SIGINFO */
++
++extern int compat_copy_siginfo_to_user(compat_siginfo_t __user *to, struct siginfo *from);
++extern int compat_copy_siginfo_from_user(struct siginfo *to, compat_siginfo_t __user *from);
++
++extern int compat_copy_sigevent_from_user(struct sigevent *to, compat_sigevent_t __user *from);
++extern int compat_copy_sigevent_to_user(compat_sigevent_t __user *to, struct sigevent *from);
++
++#endif /* CONFIG_COMPAT */
++#endif /* _ASM_GENERIC_COMPAT_SIGINFO_H */
++
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/linux/signal.h CVS2_6_15_RC7_PA0/include/linux/signal.h
+--- LINUS_2_6_15_RC7/include/linux/signal.h	2005-12-27 13:25:55.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/linux/signal.h	2005-11-11 21:09:17.000000000 -0700
+@@ -233,6 +233,9 @@
+ struct pt_regs;
+ extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
+ 
++int copy_siginfo_from_user(siginfo_t *to, siginfo_t __user *from);
++int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from);
++
+ #endif /* __KERNEL__ */
+ 
+ #endif /* _LINUX_SIGNAL_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/include/sound/opl3.h CVS2_6_15_RC7_PA0/include/sound/opl3.h
+--- LINUS_2_6_15_RC7/include/sound/opl3.h	2005-12-27 13:25:56.000000000 -0700
++++ CVS2_6_15_RC7_PA0/include/sound/opl3.h	2005-09-13 18:31:04.000000000 -0600
+@@ -261,10 +261,11 @@
+ } snd_opl3_voice_t;
+ 
+ struct snd_opl3 {
+-	unsigned long l_port;
+-	unsigned long r_port;
++	void __iomem *l_port;
++	void __iomem *r_port;
+ 	struct resource *res_l_port;
+ 	struct resource *res_r_port;
++	int unmap_on_free;
+ 	unsigned short hardware;
+ 	/* hardware access */
+ 	void (*command) (opl3_t * opl3, unsigned short cmd, unsigned char val);
+@@ -319,6 +320,9 @@
+ void snd_opl3_interrupt(snd_hwdep_t * hw);
+ int snd_opl3_new(snd_card_t *card, unsigned short hardware, opl3_t **ropl3);
+ int snd_opl3_init(opl3_t *opl3);
++int snd_opl3_create_mapped(snd_card_t * card,
++			   void __iomem * l_port, void __iomem * r_port,
++			   unsigned short hardware, opl3_t ** opl3);
+ int snd_opl3_create(snd_card_t * card,
+ 		    unsigned long l_port, unsigned long r_port,
+ 		    unsigned short hardware,
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/ipc/compat_mq.c CVS2_6_15_RC7_PA0/ipc/compat_mq.c
+--- LINUS_2_6_15_RC7/ipc/compat_mq.c	2005-12-27 13:25:57.000000000 -0700
++++ CVS2_6_15_RC7_PA0/ipc/compat_mq.c	2005-03-18 06:17:54.000000000 -0700
+@@ -7,6 +7,7 @@
+  */
+ 
+ #include <linux/compat.h>
++#include <linux/compat_siginfo.h>
+ #include <linux/fs.h>
+ #include <linux/kernel.h>
+ #include <linux/mqueue.h>
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/kernel/Makefile CVS2_6_15_RC7_PA0/kernel/Makefile
+--- LINUS_2_6_15_RC7/kernel/Makefile	2005-12-27 13:25:57.000000000 -0700
++++ CVS2_6_15_RC7_PA0/kernel/Makefile	2005-11-11 21:09:26.000000000 -0700
+@@ -19,7 +19,7 @@
+ obj-$(CONFIG_PM) += power/
+ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
+ obj-$(CONFIG_KEXEC) += kexec.o
+-obj-$(CONFIG_COMPAT) += compat.o
++obj-$(CONFIG_COMPAT) += compat.o compat_signal.o
+ obj-$(CONFIG_CPUSETS) += cpuset.o
+ obj-$(CONFIG_IKCONFIG) += configs.o
+ obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/kernel/compat.c CVS2_6_15_RC7_PA0/kernel/compat.c
+--- LINUS_2_6_15_RC7/kernel/compat.c	2005-12-27 13:25:57.000000000 -0700
++++ CVS2_6_15_RC7_PA0/kernel/compat.c	2005-09-14 06:57:58.000000000 -0600
+@@ -13,6 +13,7 @@
+ 
+ #include <linux/linkage.h>
+ #include <linux/compat.h>
++#include <linux/compat_siginfo.h>
+ #include <linux/errno.h>
+ #include <linux/time.h>
+ #include <linux/signal.h>
+@@ -439,7 +440,11 @@
+ 
+ 	BUG_ON(info.si_code & __SI_MASK);
+ 	info.si_code |= __SI_CHLD;
+-	return copy_siginfo_to_user32(uinfo, &info);
++	
++	if (compat_copy_siginfo_to_user(uinfo, &info) != 0)
++		return -EFAULT;
++
++	return 0;
+ }
+ 
+ static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr,
+@@ -651,6 +656,44 @@
+ 
+ /* timer_create is architecture specific because it needs sigevent conversion */
+ 
++long compat_sys_timer_create(clockid_t which_clock,
++			     compat_sigevent_t __user *timer_event_spec,
++			     compat_timer_t __user * created_timer_id)
++{
++	sigevent_t kevent;
++	timer_t ktimer;
++	mm_segment_t old_fs = get_fs();
++	long ret;
++
++	/* sigevent_t needs handling for 32-bit to 64-bit compat */
++	if (timer_event_spec != NULL)
++		if (compat_copy_sigevent_from_user(&kevent, timer_event_spec) != 0)
++			return -EFAULT;
++	
++	/* Timer ID is assumed to be a non-struct simple value */
++	if (created_timer_id != NULL)
++		if (__get_user(ktimer, created_timer_id) != 0)
++		  	return -EFAULT;
++
++	set_fs(KERNEL_DS);
++	ret = sys_timer_create(which_clock, 
++	    			timer_event_spec ? (sigevent_t __user *)&kevent : NULL, 
++	    			created_timer_id ? (timer_t __user *)&ktimer : NULL);
++	set_fs(old_fs);
++	
++	/* Copy back the results to userspace */
++	if (timer_event_spec != NULL)
++	  	if (compat_copy_sigevent_to_user(timer_event_spec, &kevent) != 0)
++			return -EFAULT;
++
++	if (created_timer_id != NULL)
++	  	if (__put_user(ktimer, created_timer_id) != 0)
++		  	return -EFAULT;
++	
++	return ret;
++}
++
++
+ long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask,
+ 		       unsigned long bitmap_size)
+ {
+@@ -807,7 +850,7 @@
+ 	if (sig) {
+ 		ret = sig;
+ 		if (uinfo) {
+-			if (copy_siginfo_to_user32(uinfo, &info))
++			if (compat_copy_siginfo_to_user(uinfo, &info))
+ 				ret = -EFAULT;
+ 		}
+ 	}else {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/kernel/compat_signal.c CVS2_6_15_RC7_PA0/kernel/compat_signal.c
+--- LINUS_2_6_15_RC7/kernel/compat_signal.c	1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_15_RC7_PA0/kernel/compat_signal.c	2005-08-02 10:22:04.000000000 -0600
+@@ -0,0 +1,280 @@
++/*
++ *  Copyright (C) 2003 Carlos O'Donell
++ * 
++ *  2003-12-20  Carlos O'Donell
++ *              Copied linux/kernel/compat_signal.c (copy_siginfo_to_user)
++ *              and modified to use compat_siginfo_t for thunking down to
++ *              32-bit userspace from a 64-bit kernel.
++ *              
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or (at
++ * your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
++ * NON INFRINGEMENT.  See the GNU General Public License for more
++ * details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
++ *
++ */
++
++#include <linux/compat_siginfo.h>
++#include <asm/errno.h>
++#include <asm/uaccess.h>
++#include <asm/siginfo.h>
++
++#ifndef HAVE_ARCH_COMPAT_COPY_SIGINFO_TO_USER
++int compat_copy_siginfo_to_user(compat_siginfo_t __user *to, siginfo_t *from)
++{
++	int err;
++	compat_siginfo_t compat_from;	
++
++	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
++		return -EFAULT;
++	
++	/*
++	 * If you change compat_siginfo_t structure *or* siginfo_t, 
++	 * please be sure this code is fixed accordingly.
++	 * It should never copy any pad contained in the structure
++	 * to avoid security leaks, but must copy the generic
++	 * 3 ints plus the relevant union member.
++	 */
++
++	/* Convert structure, don't leak anything in the copy */
++	memset(&compat_from,'\0',sizeof(compat_siginfo_t));
++
++        /* Always copy si_signo, si_errno, and si_code */
++	compat_from.si_signo = (compat_int_t)(from->si_signo);
++	compat_from.si_errno = (compat_int_t)(from->si_errno);
++	/* si_code is only a (short) value, remove kernel bits. */
++	compat_from.si_code = (short)(from->si_code);
++        
++	err = __put_user(compat_from.si_signo, &to->si_signo);
++	err |= __put_user(compat_from.si_errno, &to->si_errno);
++	err |= __put_user(compat_from.si_code, &to->si_code);
++
++        /* siginfo_t came from userspace, so it is the right
++         * size, no need for conversion
++         */        
++	if (from->si_code < 0) {
++		return __copy_to_user(&to->_sifields._pad, 
++                                      &from->_sifields._pad, 
++                                      SI_COMPAT_PAD_SIZE)
++			? -EFAULT : 0;
++        }
++	
++	switch (from->si_code & __SI_MASK) {
++	case __SI_KILL:
++		compat_from.si_pid = (compat_pid_t)(from->si_pid);
++		compat_from.si_uid = (__ARCH_SI_COMPAT_UID_T)(from->si_uid);
++		err |= __put_user(compat_from.si_pid, &to->si_pid);
++		err |= __put_user(compat_from.si_uid, &to->si_uid);
++		break;
++	case __SI_TIMER:
++		compat_from.si_pid = (compat_timer_t)(from->si_tid);
++		compat_from.si_overrun = (compat_int_t)(from->si_overrun);
++		compat_from.si_ptr = (compat_uptr_t)((u64 __force)(from->si_ptr) & 0xffffffffUL);
++		err |= __put_user(compat_from.si_tid, &to->si_tid);
++		err |= __put_user(compat_from.si_overrun, &to->si_overrun);
++		err |= __put_user(compat_from.si_ptr, &to->si_ptr);
++		break;
++	case __SI_POLL:
++		compat_from.si_band = (__ARCH_SI_COMPAT_BAND_T)(from->si_band);
++		compat_from.si_fd = (compat_int_t)(from->si_fd);
++		err |= __put_user(compat_from.si_band, &to->si_band);
++		err |= __put_user(compat_from.si_fd, &to->si_fd);
++		break;
++	case __SI_FAULT:
++		compat_from.si_addr = (compat_uptr_t)((u64 __force)(from->si_addr) & 0xffffffffUL);
++		err |= __put_user(compat_from.si_addr, &to->si_addr);
++#ifdef __ARCH_SI_COMPAT_TRAPNO
++		compat_from.si_trapno = (compat_int_t)(from->si_addr);
++		err |= __put_user(compat_from.si_trapno, &to->si_trapno);
++#endif
++		break;
++	case __SI_CHLD:
++		compat_from.si_pid = (compat_pid_t)(from->si_pid);
++		compat_from.si_uid = (__ARCH_SI_COMPAT_UID_T)(from->si_uid);
++		compat_from.si_status = (compat_int_t)(from->si_status);
++		compat_from.si_utime = (compat_clock_t)(from->si_utime);
++		compat_from.si_stime = (compat_clock_t)(from->si_stime);
++		err |= __put_user(compat_from.si_pid, &to->si_pid);
++		err |= __put_user(compat_from.si_uid, &to->si_uid);
++		err |= __put_user(compat_from.si_status, &to->si_status);
++		err |= __put_user(compat_from.si_utime, &to->si_utime);
++		err |= __put_user(compat_from.si_stime, &to->si_stime);
++		break;
++	case __SI_RT: /* This is not generated by the kernel as of now. */
++	case __SI_MESGQ: /* But this is */
++		compat_from.si_pid = (compat_pid_t)(from->si_pid);
++		compat_from.si_uid = (__ARCH_SI_COMPAT_UID_T)(from->si_uid);
++		compat_from.si_int = (compat_int_t)(from->si_int);
++		compat_from.si_ptr = (compat_uptr_t)((u64 __force)(from->si_ptr) & 0xffffffffUL);
++		err |= __put_user(compat_from.si_pid, &to->si_pid);
++		err |= __put_user(compat_from.si_uid, &to->si_uid);
++		err |= __put_user(compat_from.si_int, &to->si_int);
++		err |= __put_user(compat_from.si_ptr, &to->si_ptr);
++		break;
++	default: /* this is just in case for now ... */
++		compat_from.si_pid = (compat_pid_t)(from->si_pid);
++		compat_from.si_uid = (__ARCH_SI_COMPAT_UID_T)(from->si_uid);
++		err |= __put_user(compat_from.si_pid, &to->si_pid);
++		err |= __put_user(compat_from.si_uid, &to->si_uid);
++		break;
++	}
++	return err;
++}
++#endif
++
++#ifndef HAVE_ARCH_COPY_SIGINFO_FROM_USER
++int compat_copy_siginfo_from_user(siginfo_t *to, compat_siginfo_t __user *from)
++{
++	int err;
++        u64 scratch;
++
++	if (!access_ok (VERIFY_READ, from, sizeof(compat_siginfo_t)))
++		return -EFAULT;
++	
++	/*
++	 * If you change compat_siginfo_t structure *or* siginfo_t, 
++	 * please be sure this code is fixed accordingly.
++	 */
++
++        /* Always copy si_signo, si_errno, and si_code */
++	err = __get_user(to->si_signo, &from->si_signo);
++	err |= __get_user(to->si_errno, &from->si_errno);
++	err |= __get_user(to->si_code, &from->si_code);
++        
++        /* siginfo_t came from userspace, so it is the right
++         * size, no need for conversion
++         */        
++	if (to->si_code < 0) {
++		return __copy_from_user(&to->_sifields._pad, 
++                                        &from->_sifields._pad, 
++                                        SI_COMPAT_PAD_SIZE)
++			? -EFAULT : 0;
++        }
++	
++	switch (to->si_code & __SI_MASK) {
++	case __SI_KILL:
++		err |= __get_user(to->si_pid, &from->si_pid);
++		err |= __get_user(to->si_uid, &from->si_uid);
++		break;
++	case __SI_TIMER:
++		err |= __get_user(to->si_tid, &from->si_tid);
++		err |= __get_user(to->si_overrun, &from->si_overrun);
++		err |= __get_user(scratch, &from->si_ptr);
++                to->si_ptr = (u64 __user*)scratch;                
++		break;
++	case __SI_POLL:
++		err |= __get_user(to->si_band, &from->si_band);
++		err |= __get_user(to->si_fd, &from->si_fd);
++		break;
++	case __SI_FAULT:
++		err |= __get_user(scratch, &from->si_addr);
++                to->si_addr = (u64 __user*)scratch;
++#ifdef __ARCH_SI_COMPAT_TRAPNO
++		err |= __get_user(to->si_trapno, &from->si_trapno);
++#endif
++		break;
++	case __SI_CHLD:
++		err |= __get_user(to->si_pid, &from->si_pid);
++		err |= __get_user(to->si_uid, &from->si_uid);
++		err |= __get_user(to->si_status, &from->si_status);
++		err |= __get_user(to->si_utime, &from->si_utime);
++		err |= __get_user(to->si_stime, &from->si_stime);
++		break;
++	case __SI_RT: /* This is not generated by the kernel as of now. */
++	case __SI_MESGQ: /* But this is */
++		err |= __get_user(to->si_pid, &from->si_pid);
++		err |= __get_user(to->si_uid, &from->si_uid);
++		err |= __get_user(to->si_int, &from->si_int);
++		err |= __get_user(scratch, &from->si_ptr);
++                to->si_ptr = (u64 __user*)scratch;
++		break;
++	default: /* this is just in case for now ... */
++		err |= __get_user(to->si_pid, &from->si_pid);
++		err |= __get_user(to->si_uid, &from->si_uid);
++		break;
++	}
++	return err;
++}
++#endif
++
++#ifndef HAVE_ARCH_COPY_SIGEVENT_FROM_USER
++int compat_copy_sigevent_from_user(sigevent_t *to, compat_sigevent_t __user *from)
++{
++	int err;
++	u64 scratch;
++	
++	/* copy sigval_t sigev_value 
++	 	int_t sival_int		(same)
++	 	uptr_t sival_ptr	(32 vs 64)*/
++	err = __get_user(to->sigev_value.sival_int, 
++	    		 &from->sigev_value.sival_int);
++	err |= __get_user(scratch, &from->sigev_value.sival_ptr);
++	to->sigev_value.sival_ptr = (u64 __user *)scratch;
++	
++	/* copy int_t sigev_signo 	(same)*/
++	err |= __get_user(to->sigev_signo, &from->sigev_signo);
++	
++	/* copy int_t sigev_notify	(same)*/
++	err |= __get_user(to->sigev_notify, &from->sigev_notify);
++
++	/* never copy _sigev_un padding */
++
++	/* copy int_t _tid 		(same),
++	   good_sigevent() uses this value of */
++	err |= __get_user(to->sigev_notify_thread_id, &from->sigev_notify_thread_id);
++	
++	/* XXX: Do not copy these, they aren't used by
++	   anyone. We would need to distinguish the uses of the union.
++	   copy _sigev_thread
++	  	uptr_t _function	(32 vs 64)
++	  	uptr_t _attribute	(32 vs 64)*/
++	
++	return err;
++}
++#endif
++
++#ifndef HAVE_ARCH_COPY_SIGEVENT_TO_USER
++int compat_copy_sigevent_to_user(compat_sigevent_t __user *to, sigevent_t *from)
++{
++	int err;
++	u32 scratch;
++	
++	/* copy sigval_t sigev_value 
++	 	int_t sival_int		(same)
++	 	uptr_t sival_ptr	(32 vs 64)*/
++	err = __put_user(from->sigev_value.sival_int, 
++	    		 &to->sigev_value.sival_int);
++	scratch = (u32)((u64 __force)from->sigev_value.sival_ptr & 0xffffffffUL);
++	err |= __put_user((compat_uptr_t)scratch, &to->sigev_value.sival_ptr);
++	
++	/* copy int_t sigev_signo 	(same)*/
++	err |= __put_user(from->sigev_signo, &to->sigev_signo);
++	
++	/* copy int_t sigev_notify	(same)*/
++	err |= __put_user(from->sigev_notify, &to->sigev_notify);
++
++	/* never copy _sigev_un padding */
++
++	/* copy int_t _tid 		(same),
++	   good_sigevent() uses this value of */
++	err |= __put_user(from->sigev_notify_thread_id, &to->sigev_notify_thread_id);
++	
++	/* XXX: Do not copy these, they aren't used by
++	   anyone. We would need to distinguish the uses of the union.
++	   copy _sigev_thread
++	  	uptr_t _function	(32 vs 64)
++	  	uptr_t _attribute	(32 vs 64)*/
++	
++	return err;
++}
++#endif
++
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/kernel/ptrace.c CVS2_6_15_RC7_PA0/kernel/ptrace.c
+--- LINUS_2_6_15_RC7/kernel/ptrace.c	2005-12-27 13:25:57.000000000 -0700
++++ CVS2_6_15_RC7_PA0/kernel/ptrace.c	2005-12-04 00:25:16.000000000 -0700
+@@ -363,7 +363,7 @@
+ 	siginfo_t newinfo;
+ 	int error = -ESRCH;
+ 
+-	if (copy_from_user(&newinfo, data, sizeof (siginfo_t)))
++	if (copy_siginfo_from_user(&newinfo, data) != 0)
+ 		return -EFAULT;
+ 
+ 	read_lock(&tasklist_lock);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/kernel/resource.c CVS2_6_15_RC7_PA0/kernel/resource.c
+--- LINUS_2_6_15_RC7/kernel/resource.c	2005-12-27 13:25:57.000000000 -0700
++++ CVS2_6_15_RC7_PA0/kernel/resource.c	2005-09-14 06:57:58.000000000 -0600
+@@ -181,6 +181,8 @@
+ {
+ 	struct resource *tmp, **p;
+ 
++	BUG_ON(old->child);
++
+ 	p = &old->parent->child;
+ 	for (;;) {
+ 		tmp = *p;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/kernel/signal.c CVS2_6_15_RC7_PA0/kernel/signal.c
+--- LINUS_2_6_15_RC7/kernel/signal.c	2005-12-27 13:25:57.000000000 -0700
++++ CVS2_6_15_RC7_PA0/kernel/signal.c	2005-11-19 22:09:36.000000000 -0700
+@@ -22,6 +22,7 @@
+ #include <linux/security.h>
+ #include <linux/syscalls.h>
+ #include <linux/ptrace.h>
++#include <linux/compat_siginfo.h>
+ #include <linux/posix-timers.h>
+ #include <linux/signal.h>
+ #include <linux/audit.h>
+@@ -2095,17 +2096,35 @@
+ 	return do_sigpending(set, sigsetsize);
+ }
+ 
++#ifndef HAVE_ARCH_COPY_SIGINFO_FROM_USER
++
++int copy_siginfo_from_user(siginfo_t *to, siginfo_t __user *from)
++{
++        if(is_compat_task(current))
++                return compat_copy_siginfo_from_user(to,(compat_siginfo_t __user *)from);
++  
++        return copy_from_user(&to, from, sizeof(siginfo_t));
++}
++
++#endif
++
+ #ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER
+ 
+ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from)
+ {
+ 	int err;
++	
++	/* Use compat_siginfo_t with 32-bit signals */
++	if(is_compat_task(current)){
++		return compat_copy_siginfo_to_user((compat_siginfo_t __user *)to,from);
++	}
+ 
+ 	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
+ 		return -EFAULT;
+ 	if (from->si_code < 0)
+ 		return __copy_to_user(to, from, sizeof(siginfo_t))
+ 			? -EFAULT : 0;
++	
+ 	/*
+ 	 * If you change siginfo_t structure, please be sure
+ 	 * this code is fixed accordingly.
+@@ -2321,7 +2340,7 @@
+ {
+ 	siginfo_t info;
+ 
+-	if (copy_from_user(&info, uinfo, sizeof(siginfo_t)))
++	if (copy_siginfo_from_user(&info, uinfo))
+ 		return -EFAULT;
+ 
+ 	/* Not even root can pretend to send signals from the kernel.
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/mm/shmem.c CVS2_6_15_RC7_PA0/mm/shmem.c
+--- LINUS_2_6_15_RC7/mm/shmem.c	2005-12-27 13:25:58.000000000 -0700
++++ CVS2_6_15_RC7_PA0/mm/shmem.c	2005-11-11 21:09:28.000000000 -0700
+@@ -457,7 +457,7 @@
+ 	} while (next);
+ }
+ 
+-static void shmem_truncate(struct inode *inode)
++/* static gcc-3.3 OPD bug - GGG */ void shmem_truncate(struct inode *inode)
+ {
+ 	struct shmem_inode_info *info = SHMEM_I(inode);
+ 	unsigned long idx;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/sound/drivers/opl3/opl3_lib.c CVS2_6_15_RC7_PA0/sound/drivers/opl3/opl3_lib.c
+--- LINUS_2_6_15_RC7/sound/drivers/opl3/opl3_lib.c	2005-12-27 13:26:01.000000000 -0700
++++ CVS2_6_15_RC7_PA0/sound/drivers/opl3/opl3_lib.c	2005-11-11 23:00:07.000000000 -0700
+@@ -40,7 +40,7 @@
+ static void snd_opl2_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
+ {
+ 	unsigned long flags;
+-	unsigned long port;
++	void __iomem *port;
+ 
+ 	/*
+ 	 * The original 2-OP synth requires a quite long delay
+@@ -51,10 +51,10 @@
+ 
+ 	spin_lock_irqsave(&opl3->reg_lock, flags);
+ 
+-	outb((unsigned char) cmd, port);
++	iowrite8((unsigned char) cmd, port);
+ 	udelay(10);
+ 
+-	outb((unsigned char) val, port + 1);
++	iowrite8((unsigned char) val, port + 1);
+ 	udelay(30);
+ 
+ 	spin_unlock_irqrestore(&opl3->reg_lock, flags);
+@@ -63,7 +63,7 @@
+ static void snd_opl3_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
+ {
+ 	unsigned long flags;
+-	unsigned long port;
++	void __iomem *port;
+ 
+ 	/*
+ 	 * The OPL-3 survives with just two INBs
+@@ -74,13 +74,13 @@
+ 
+ 	spin_lock_irqsave(&opl3->reg_lock, flags);
+ 
+-	outb((unsigned char) cmd, port);
+-	inb(opl3->l_port);
+-	inb(opl3->l_port);
+-
+-	outb((unsigned char) val, port + 1);
+-	inb(opl3->l_port);
+-	inb(opl3->l_port);
++	iowrite8((unsigned char) cmd, port);
++	ioread8(opl3->l_port);
++	ioread8(opl3->l_port);
++
++	iowrite8((unsigned char) val, port + 1);
++	ioread8(opl3->l_port);
++	ioread8(opl3->l_port);
+ 
+ 	spin_unlock_irqrestore(&opl3->reg_lock, flags);
+ }
+@@ -104,7 +104,7 @@
+ 	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
+ 	/* Reset the IRQ of the FM chip */
+ 	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
+-	signature = stat1 = inb(opl3->l_port);	/* Status register */
++	signature = stat1 = ioread8(opl3->l_port);	/* Status register */
+ 	if ((stat1 & 0xe0) != 0x00) {	/* Should be 0x00 */
+ 		snd_printd("OPL3: stat1 = 0x%x\n", stat1);
+ 		return -ENODEV;
+@@ -116,7 +116,7 @@
+ 	/* Now we have to delay at least 80us */
+ 	udelay(200);
+ 	/* Read status after timers have expired */
+-	stat2 = inb(opl3->l_port);
++	stat2 = ioread8(opl3->l_port);
+ 	/* Stop the timers */
+ 	opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
+ 	/* Reset the IRQ of the FM chip */
+@@ -299,7 +299,7 @@
+ 		return;
+ 
+ 	opl3 = hw->private_data;
+-	status = inb(opl3->l_port);
++	status = ioread8(opl3->l_port);
+ #if 0
+ 	snd_printk("AdLib IRQ status = 0x%x\n", status);
+ #endif
+@@ -327,6 +327,10 @@
+ 		opl3->private_free(opl3);
+ 	release_and_free_resource(opl3->res_l_port);
+ 	release_and_free_resource(opl3->res_r_port);
++	if (opl3->unmap_on_free) {
++		iounmap(opl3->l_port);
++		iounmap(opl3->r_port);
++	}
+ 	kfree(opl3);
+ 	return 0;
+ }
+@@ -391,12 +395,14 @@
+ 	return 0;
+ }
+ 
+-int snd_opl3_create(snd_card_t * card,
+-		    unsigned long l_port,
+-		    unsigned long r_port,
+-		    unsigned short hardware,
+-		    int integrated,
+-		    opl3_t ** ropl3)
++static int snd_opl3_create_main(snd_card_t * card,
++				void __iomem *l_port,
++				void __iomem *r_port,
++				int unmap_on_free,
++				struct resource *res_l_port,
++				struct resource *res_r_port,
++				unsigned short hardware,
++				opl3_t ** ropl3)
+ {
+ 	opl3_t *opl3;
+ 	int err;
+@@ -404,21 +410,11 @@
+ 	*ropl3 = NULL;
+ 	if ((err = snd_opl3_new(card, hardware, &opl3)) < 0)
+ 		return err;
+-	if (! integrated) {
+-		if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
+-			snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
+-			snd_opl3_free(opl3);
+-			return -EBUSY;
+-		}
+-		if (r_port != 0 &&
+-		    (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
+-			snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
+-			snd_opl3_free(opl3);
+-			return -EBUSY;
+-		}
+-	}
+ 	opl3->l_port = l_port;
+ 	opl3->r_port = r_port;
++	opl3->unmap_on_free = unmap_on_free;
++	opl3->res_l_port = res_l_port;
++	opl3->res_r_port = res_r_port;
+ 
+ 	switch (opl3->hardware) {
+ 	/* some hardware doesn't support timers */
+@@ -449,6 +445,61 @@
+ 	return 0;
+ }
+ 
++int snd_opl3_create_mapped(snd_card_t * card,
++			   void __iomem * l_port,
++			   void __iomem * r_port,
++			   unsigned short hardware,
++			   opl3_t ** ropl3)
++{
++	return snd_opl3_create_main(card, l_port, r_port, 0, NULL, NULL, hardware, ropl3);
++}
++
++int snd_opl3_create(snd_card_t * card,
++		    unsigned long l_port,
++		    unsigned long r_port,
++		    unsigned short hardware,
++		    int integrated,
++		    opl3_t ** ropl3) {
++	struct resource *res_l_port = NULL;
++	struct resource *res_r_port = NULL;
++	void __iomem *l_mapped = NULL;
++	void __iomem *r_mapped = NULL;
++	
++	if (! integrated) {
++		if ((res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
++			snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
++			goto fail;
++		}
++		if (r_port != 0 &&
++		    (res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
++			snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
++			goto fail;
++		}
++	}
++	
++	l_mapped = ioport_map(l_port, 2);
++	if (l_mapped == NULL) {
++		snd_printk(KERN_ERR "opl3: failed to map port 0x%lx\n", l_port);
++		goto fail;
++	}
++	r_mapped = ioport_map(r_port, 2);
++	if (r_mapped == NULL) {
++		snd_printk(KERN_ERR "opl3: failed to map port 0x%lx\n", r_port);
++		goto fail;
++	}
++	
++	return snd_opl3_create_main(card, l_mapped, r_mapped, 1, res_l_port, res_r_port, hardware, ropl3);
++
++fail:
++	release_and_free_resource(res_l_port);
++	release_and_free_resource(res_r_port);
++	if (l_mapped)
++		iounmap(l_mapped);
++	if (r_mapped)
++		iounmap(r_mapped);
++	return -EBUSY;
++}
++
+ int snd_opl3_timer_new(opl3_t * opl3, int timer1_dev, int timer2_dev)
+ {
+ 	int err;
+@@ -528,6 +579,7 @@
+ EXPORT_SYMBOL(snd_opl3_new);
+ EXPORT_SYMBOL(snd_opl3_init);
+ EXPORT_SYMBOL(snd_opl3_create);
++EXPORT_SYMBOL(snd_opl3_create_mapped);
+ EXPORT_SYMBOL(snd_opl3_timer_new);
+ EXPORT_SYMBOL(snd_opl3_hwdep_new);
+ 
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/sound/oss/ad1889.c CVS2_6_15_RC7_PA0/sound/oss/ad1889.c
+--- LINUS_2_6_15_RC7/sound/oss/ad1889.c	2005-12-27 13:26:02.000000000 -0700
++++ CVS2_6_15_RC7_PA0/sound/oss/ad1889.c	2005-06-30 08:26:47.000000000 -0600
+@@ -74,7 +74,7 @@
+ 
+ 	DBG("Setting WAV rate to %d\n", rate);
+ 	dev->state[AD_WAV_STATE].dmabuf.rate = rate;
+-	AD1889_WRITEW(dev, AD_DSWAS, rate);
++	AD1889_WRITEW(dev, AD_DS_WAS, rate);
+ 
+ 	/* Cycle the DAC to enable the new rate */
+ 	ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0x0200);
+@@ -88,14 +88,14 @@
+ 
+ 	DBG("Setting WAV format to 0x%x\n", fmt);
+ 
+-	tmp = AD1889_READW(ad1889_dev, AD_DSWSMC);
++	tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC);
+ 	if (fmt & AFMT_S16_LE) {
+ 		//tmp |= 0x0100; /* set WA16 */
+ 		tmp |= 0x0300; /* set WA16 stereo */
+ 	} else if (fmt & AFMT_U8) {
+ 		tmp &= ~0x0100; /* clear WA16 */
+ 	} 
+-	AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp);
++	AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp);
+ }
+ 
+ static inline void ad1889_set_adc_fmt(ad1889_dev_t *dev, int fmt)
+@@ -104,13 +104,13 @@
+ 
+ 	DBG("Setting ADC format to 0x%x\n", fmt);
+ 
+-	tmp = AD1889_READW(ad1889_dev, AD_DSRAMC);
++	tmp = AD1889_READW(ad1889_dev, AD_DS_RAMC);
+ 	if (fmt & AFMT_S16_LE) {
+ 		tmp |= 0x0100; /* set WA16 */
+ 	} else if (fmt & AFMT_U8) {
+ 		tmp &= ~0x0100; /* clear WA16 */
+ 	} 
+-	AD1889_WRITEW(ad1889_dev, AD_DSRAMC, tmp);
++	AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, tmp);
+ }
+ 
+ static void ad1889_start_wav(ad1889_state_t *state)
+@@ -144,21 +144,21 @@
+ 	    dmabuf->rd_ptr, dmabuf->dma_len);
+ 
+         /* load up the current register set */
+-	AD1889_WRITEL(ad1889_dev, AD_DMAWAVCC, cnt);
+-	AD1889_WRITEL(ad1889_dev, AD_DMAWAVICC, cnt);
+-	AD1889_WRITEL(ad1889_dev, AD_DMAWAVCA, dmabuf->dma_handle);
++	AD1889_WRITEL(ad1889_dev, AD_DMA_WAVCC, cnt);
++	AD1889_WRITEL(ad1889_dev, AD_DMA_WAVICC, cnt);
++	AD1889_WRITEL(ad1889_dev, AD_DMA_WAVCA, dmabuf->dma_handle);
+ 
+ 	/* TODO: for now we load the base registers with the same thing */
+-	AD1889_WRITEL(ad1889_dev, AD_DMAWAVBC, cnt);
+-	AD1889_WRITEL(ad1889_dev, AD_DMAWAVIBC, cnt);
+-	AD1889_WRITEL(ad1889_dev, AD_DMAWAVBA, dmabuf->dma_handle);
++	AD1889_WRITEL(ad1889_dev, AD_DMA_WAVBC, cnt);
++	AD1889_WRITEL(ad1889_dev, AD_DMA_WAVIBC, cnt);
++	AD1889_WRITEL(ad1889_dev, AD_DMA_WAVBA, dmabuf->dma_handle);
+ 
+ 	/* and we're off to the races... */
+-	AD1889_WRITEL(ad1889_dev, AD_DMACHSS, 0x8);
+-	tmp = AD1889_READW(ad1889_dev, AD_DSWSMC);
++	AD1889_WRITEL(ad1889_dev, AD_DMA_CHSS, 0x8);
++	tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC);
+ 	tmp |= 0x0400; /* set WAEN */
+-	AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp);
+-	(void) AD1889_READW(ad1889_dev, AD_DSWSMC); /* flush posted PCI write */
++	AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp);
++	(void) AD1889_READW(ad1889_dev, AD_DS_WSMC); /* flush posted PCI write */
+ 
+ 	dmabuf->enable |= DAC_RUNNING;
+ 
+@@ -178,10 +178,10 @@
+ 		u16 tmp;
+ 		unsigned long cnt = dmabuf->dma_len;
+ 
+-		tmp = AD1889_READW(ad1889_dev, AD_DSWSMC);
++		tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC);
+ 		tmp &= ~0x0400; /* clear WAEN */
+-		AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp);
+-		(void) AD1889_READW(ad1889_dev, AD_DSWSMC); /* flush posted PCI write */
++		AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp);
++		(void) AD1889_READW(ad1889_dev, AD_DS_WSMC); /* flush posted PCI write */
+ 		pci_unmap_single(ad1889_dev->pci, dmabuf->dma_handle, 
+ 				cnt, PCI_DMA_TODEVICE);
+ 
+@@ -210,7 +210,7 @@
+ 
+ 	spin_lock_irqsave(&state->card->lock, flags);
+ 	
+-	tmp = AD1889_READW(ad1889_dev, AD_DSRAMC);
++	tmp = AD1889_READW(ad1889_dev, AD_DS_RAMC);
+ 	if (start) {
+ 		state->dmabuf.enable |= ADC_RUNNING;
+ 		tmp |= 0x0004; /* set ADEN */
+@@ -218,7 +218,7 @@
+ 		state->dmabuf.enable &= ~ADC_RUNNING;
+ 		tmp &= ~0x0004; /* clear ADEN */
+ 	}
+-	AD1889_WRITEW(ad1889_dev, AD_DSRAMC, tmp);
++	AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, tmp);
+ 
+ 	spin_unlock_irqrestore(&state->card->lock, flags);
+ }
+@@ -300,53 +300,53 @@
+ 	int len, i;
+ 	ad1889_dev_t *dev = data;
+ 	ad1889_reg_t regs[] = {
+-		{ "WSMC", AD_DSWSMC, 16 },
+-		{ "RAMC", AD_DSRAMC, 16 },
+-		{ "WADA", AD_DSWADA, 16 },
+-		{ "SYDA", AD_DSSYDA, 16 },
+-		{ "WAS", AD_DSWAS, 16 },
+-		{ "RES", AD_DSRES, 16 },
+-		{ "CCS", AD_DSCCS, 16 },
+-		{ "ADCBA", AD_DMAADCBA, 32 },
+-		{ "ADCCA", AD_DMAADCCA, 32 },
+-		{ "ADCBC", AD_DMAADCBC, 32 },
+-		{ "ADCCC", AD_DMAADCCC, 32 },
+-		{ "ADCIBC", AD_DMAADCIBC, 32 },
+-		{ "ADCICC", AD_DMAADCICC, 32 },
+-		{ "ADCCTRL", AD_DMAADCCTRL, 16 },
+-		{ "WAVBA", AD_DMAWAVBA, 32 },
+-		{ "WAVCA", AD_DMAWAVCA, 32 },
+-		{ "WAVBC", AD_DMAWAVBC, 32 },
+-		{ "WAVCC", AD_DMAWAVCC, 32 },
+-		{ "WAVIBC", AD_DMAWAVIBC, 32 },
+-		{ "WAVICC", AD_DMAWAVICC, 32 },
+-		{ "WAVCTRL", AD_DMAWAVCTRL, 16 },
+-		{ "DISR", AD_DMADISR, 32 },
+-		{ "CHSS", AD_DMACHSS, 32 },
+-		{ "IPC", AD_GPIOIPC, 16 },
+-		{ "OP", AD_GPIOOP, 16 },
+-		{ "IP", AD_GPIOIP, 16 },
+-		{ "ACIC", AD_ACIC, 16 },
+-		{ "AC97_RESET", 0x100 + AC97_RESET, 16 },
+-		{ "AC97_MASTER_VOL_STEREO", 0x100 + AC97_MASTER_VOL_STEREO, 16 },
+-		{ "AC97_HEADPHONE_VOL", 0x100 + AC97_HEADPHONE_VOL, 16 },
+-		{ "AC97_MASTER_VOL_MONO", 0x100 + AC97_MASTER_VOL_MONO, 16 },
+-		{ "AC97_MASTER_TONE", 0x100 + AC97_MASTER_TONE, 16 },
+-		{ "AC97_PCBEEP_VOL", 0x100 + AC97_PCBEEP_VOL, 16 },
+-		{ "AC97_PHONE_VOL", 0x100 + AC97_PHONE_VOL, 16 },
+-		{ "AC97_MIC_VOL", 0x100 + AC97_MIC_VOL, 16 },
+-		{ "AC97_LINEIN_VOL", 0x100 + AC97_LINEIN_VOL, 16 },
+-		{ "AC97_CD_VOL", 0x100 + AC97_CD_VOL, 16 },
+-		{ "AC97_VIDEO_VOL", 0x100 + AC97_VIDEO_VOL, 16 },
+-		{ "AC97_AUX_VOL", 0x100 + AC97_AUX_VOL, 16 },
+-		{ "AC97_PCMOUT_VOL", 0x100 + AC97_PCMOUT_VOL, 16 },
+-		{ "AC97_RECORD_SELECT", 0x100 + AC97_RECORD_SELECT, 16 },
+-		{ "AC97_RECORD_GAIN", 0x100 + AC97_RECORD_GAIN, 16 },
+-		{ "AC97_RECORD_GAIN_MIC", 0x100 + AC97_RECORD_GAIN_MIC, 16 },
+-		{ "AC97_GENERAL_PURPOSE", 0x100 + AC97_GENERAL_PURPOSE, 16 },
+-		{ "AC97_3D_CONTROL", 0x100 + AC97_3D_CONTROL, 16 },
+-		{ "AC97_MODEM_RATE", 0x100 + AC97_MODEM_RATE, 16 },
+-		{ "AC97_POWER_CONTROL", 0x100 + AC97_POWER_CONTROL, 16 },
++		{ "WSMC", AD_DS_WSMC, 16 },
++		{ "RAMC", AD_DS_RAMC, 16 },
++		{ "WADA", AD_DS_WADA, 16 },
++		{ "SYDA", AD_DS_SYDA, 16 },
++		{ "WAS", AD_DS_WAS, 16 },
++		{ "RES", AD_DS_RES, 16 },
++		{ "CCS", AD_DS_CCS, 16 },
++		{ "ADCBA", AD_DMA_ADCBA, 32 },
++		{ "ADCCA", AD_DMA_ADCCA, 32 },
++		{ "ADCBC", AD_DMA_ADCBC, 32 },
++		{ "ADCCC", AD_DMA_ADCCC, 32 },
++		{ "ADCIBC", AD_DMA_ADCIBC, 32 },
++		{ "ADCICC", AD_DMA_ADCICC, 32 },
++		{ "ADCCTRL", AD_DMA_ADCCTRL, 16 },
++		{ "WAVBA", AD_DMA_WAVBA, 32 },
++		{ "WAVCA", AD_DMA_WAVCA, 32 },
++		{ "WAVBC", AD_DMA_WAVBC, 32 },
++		{ "WAVCC", AD_DMA_WAVCC, 32 },
++		{ "WAVIBC", AD_DMA_WAVIBC, 32 },
++		{ "WAVICC", AD_DMA_WAVICC, 32 },
++		{ "WAVCTRL", AD_DMA_WAVCTRL, 16 },
++		{ "DISR", AD_DMA_DISR, 32 },
++		{ "CHSS", AD_DMA_CHSS, 32 },
++		{ "IPC", AD_GPIO_IPC, 16 },
++		{ "OP", AD_GPIO_OP, 16 },
++		{ "IP", AD_GPIO_IP, 16 },
++		{ "ACIC", AD_AC97_ACIC, 16 },
++		{ "AC97_RESET", AD_AC97_BASE + AC97_RESET, 16 },
++		{ "AC97_MASTER_VOL_STEREO", AD_AC97_BASE + AC97_MASTER_VOL_STEREO, 16 },
++		{ "AC97_HEADPHONE_VOL", AD_AC97_BASE + AC97_HEADPHONE_VOL, 16 },
++		{ "AC97_MASTER_VOL_MONO", AD_AC97_BASE + AC97_MASTER_VOL_MONO, 16 },
++		{ "AC97_MASTER_TONE", AD_AC97_BASE + AC97_MASTER_TONE, 16 },
++		{ "AC97_PCBEEP_VOL", AD_AC97_BASE + AC97_PCBEEP_VOL, 16 },
++		{ "AC97_PHONE_VOL", AD_AC97_BASE + AC97_PHONE_VOL, 16 },
++		{ "AC97_MIC_VOL", AD_AC97_BASE + AC97_MIC_VOL, 16 },
++		{ "AC97_LINEIN_VOL", AD_AC97_BASE + AC97_LINEIN_VOL, 16 },
++		{ "AC97_CD_VOL", AD_AC97_BASE + AC97_CD_VOL, 16 },
++		{ "AC97_VIDEO_VOL", AD_AC97_BASE + AC97_VIDEO_VOL, 16 },
++		{ "AC97_AUX_VOL", AD_AC97_BASE + AC97_AUX_VOL, 16 },
++		{ "AC97_PCMOUT_VOL", AD_AC97_BASE + AC97_PCMOUT_VOL, 16 },
++		{ "AC97_RECORD_SELECT", AD_AC97_BASE + AC97_RECORD_SELECT, 16 },
++		{ "AC97_RECORD_GAIN", AD_AC97_BASE + AC97_RECORD_GAIN, 16 },
++		{ "AC97_RECORD_GAIN_MIC", AD_AC97_BASE + AC97_RECORD_GAIN_MIC, 16 },
++		{ "AC97_GENERAL_PURPOSE", AD_AC97_BASE + AC97_GENERAL_PURPOSE, 16 },
++		{ "AC97_3D_CONTROL", AD_AC97_BASE + AC97_3D_CONTROL, 16 },
++		{ "AC97_MODEM_RATE", AD_AC97_BASE + AC97_MODEM_RATE, 16 },
++		{ "AC97_POWER_CONTROL", AD_AC97_BASE + AC97_POWER_CONTROL, 16 },
+ 		{ NULL }
+ 	};
+ 
+@@ -399,9 +399,9 @@
+ 	}
+ 	
+ 	if (dmabuf->enable & DAC_RUNNING)
+-		offset = le32_to_cpu(AD1889_READL(state->card, AD_DMAWAVBA));
++		offset = le32_to_cpu(AD1889_READL(state->card, AD_DMA_WAVBA));
+ 	else
+-		offset = le32_to_cpu(AD1889_READL(state->card, AD_DMAADCBA));
++		offset = le32_to_cpu(AD1889_READL(state->card, AD_DMA_ADCBA));
+ 
+ 	return (unsigned long)bus_to_virt((unsigned long)offset) - (unsigned long)dmabuf->rawbuf;
+ }
+@@ -638,9 +638,9 @@
+ 		if (val > 5400 && val < 48000)
+ 		{
+ 			if (file->f_mode & FMODE_WRITE)
+-				AD1889_WRITEW(ad1889_dev, AD_DSWAS, val);
++				AD1889_WRITEW(ad1889_dev, AD_DS_WAS, val);
+ 			if (file->f_mode & FMODE_READ)
+-				AD1889_WRITEW(ad1889_dev, AD_DSRES, val);
++				AD1889_WRITEW(ad1889_dev, AD_DS_RES, val);
+ 		}
+ 		return 0;
+ 
+@@ -648,22 +648,22 @@
+ 		if (get_user(val, p))
+ 			return -EFAULT;
+ 		if (file->f_mode & FMODE_READ) {
+-			val = AD1889_READW(ad1889_dev, AD_DSWSMC);
++			val = AD1889_READW(ad1889_dev, AD_DS_WSMC);
+ 			if (val) {
+ 				val |= 0x0200;  /* set WAST */
+ 			} else {
+ 				val &= ~0x0200; /* clear WAST */
+ 			}
+-			AD1889_WRITEW(ad1889_dev, AD_DSWSMC, val);
++			AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, val);
+ 		}
+ 		if (file->f_mode & FMODE_WRITE) {
+-			val = AD1889_READW(ad1889_dev, AD_DSRAMC);
++			val = AD1889_READW(ad1889_dev, AD_DS_RAMC);
+ 			if (val) {
+ 				val |= 0x0002;  /* set ADST */
+ 			} else {
+ 				val &= ~0x0002; /* clear ADST */
+ 			}
+-			AD1889_WRITEW(ad1889_dev, AD_DSRAMC, val);
++			AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, val);
+ 		}
+ 
+ 		return 0;
+@@ -738,7 +738,7 @@
+ 		break;
+ 
+ 	case SOUND_PCM_READ_RATE:
+-		return put_user(AD1889_READW(ad1889_dev, AD_DSWAS), p);
++		return put_user(AD1889_READW(ad1889_dev, AD_DS_WAS), p);
+ 
+ 	case SOUND_PCM_READ_CHANNELS:
+ 	case SOUND_PCM_READ_BITS:
+@@ -768,7 +768,7 @@
+ 
+ 	ad1889_set_wav_rate(ad1889_dev, 48000);
+ 	ad1889_set_wav_fmt(ad1889_dev, AFMT_S16_LE);
+-	AD1889_WRITEW(ad1889_dev, AD_DSWADA, 0x0404); /* attenuation */
++	AD1889_WRITEW(ad1889_dev, AD_DS_WADA, 0x0404); /* attenuation */
+ 	return nonseekable_open(inode, file);
+ }
+ 
+@@ -825,15 +825,15 @@
+ {
+ 	ad1889_dev_t *dev = ac97->private_data;
+ 
+-	//DBG("Writing 0x%x to 0x%lx\n", val, dev->regbase + 0x100 + reg);
+-	AD1889_WRITEW(dev, 0x100 + reg, val);
++	//DBG("Writing 0x%x to 0x%lx\n", val, dev->regbase + AD_AC97_BASE + reg);
++	AD1889_WRITEW(dev, AD_AC97_BASE + reg, val);
+ }
+ 
+ static u16 ad1889_codec_read(struct ac97_codec *ac97, u8 reg)
+ {
+ 	ad1889_dev_t *dev = ac97->private_data;
+-	//DBG("Reading from 0x%lx\n", dev->regbase + 0x100 + reg);
+-	return AD1889_READW(dev, 0x100 + reg);
++	//DBG("Reading from 0x%lx\n", dev->regbase + AD_AC97_BASE + reg);
++	return AD1889_READW(dev, AD_AC97_BASE + reg);
+ }	
+ 
+ static int ad1889_ac97_init(ad1889_dev_t *dev, int id)
+@@ -882,24 +882,24 @@
+ 	int retry = 200;
+ 	ad1889_dev_t *dev = pci_get_drvdata(pcidev);
+ 
+-	AD1889_WRITEW(dev, AD_DSCCS, 0x8000); /* turn on clock */
+-	AD1889_READW(dev, AD_DSCCS); 
++	AD1889_WRITEW(dev, AD_DS_CCS, 0x8000); /* turn on clock */
++	AD1889_READW(dev, AD_DS_CCS); 
+ 
+ 	WAIT_10MS();
+ 
+-	stat = AD1889_READW(dev, AD_ACIC);
++	stat = AD1889_READW(dev, AD_AC97_ACIC);
+ 	stat |= 0x0002;				/* Reset Disable */
+-	AD1889_WRITEW(dev, AD_ACIC, stat);
+-	(void) AD1889_READW(dev, AD_ACIC);	/* flush posted write */
++	AD1889_WRITEW(dev, AD_AC97_ACIC, stat);
++	(void) AD1889_READW(dev, AD_AC97_ACIC);	/* flush posted write */
+ 
+ 	udelay(10);
+ 
+-	stat = AD1889_READW(dev, AD_ACIC);
++	stat = AD1889_READW(dev, AD_AC97_ACIC);
+ 	stat |= 0x0001;				/* Interface Enable */
+-	AD1889_WRITEW(dev, AD_ACIC, stat);
++	AD1889_WRITEW(dev, AD_AC97_ACIC, stat);
+ 
+ 	do {
+-		if (AD1889_READW(dev, AD_ACIC) & 0x8000)	/* Ready */
++		if (AD1889_READW(dev, AD_AC97_ACIC) & 0x8000)	/* Ready */
+ 			break;
+ 		WAIT_10MS();
+ 		retry--;
+@@ -907,16 +907,16 @@
+ 
+ 	if (!retry) {
+ 		printk(KERN_ERR "ad1889_aclink_reset: codec is not ready [0x%x]\n",
+-			    AD1889_READW(dev, AD_ACIC));
++			    AD1889_READW(dev, AD_AC97_ACIC));
+ 		return -EBUSY;
+ 	}
+ 
+ 	/* TODO reset AC97 codec */
+ 	/* TODO set wave/adc pci ctrl status */
+ 
+-	stat = AD1889_READW(dev, AD_ACIC);
++	stat = AD1889_READW(dev, AD_AC97_ACIC);
+ 	stat |= 0x0004;				/* Audio Stream Output Enable */
+-	AD1889_WRITEW(dev, AD_ACIC, stat);
++	AD1889_WRITEW(dev, AD_AC97_ACIC, stat);
+ 	return 0;
+ }
+ 
+@@ -934,10 +934,10 @@
+ 	u32 stat;
+ 	ad1889_dev_t *dev = (ad1889_dev_t *)dev_id;
+ 
+-	stat = AD1889_READL(dev, AD_DMADISR);
++	stat = AD1889_READL(dev, AD_DMA_DISR);
+ 
+ 	/* clear ISR */
+-	AD1889_WRITEL(dev, AD_DMADISR, stat);
++	AD1889_WRITEL(dev, AD_DMA_DISR, stat);
+ 
+ 	if (stat & 0x8) {		/* WAVI */
+ 		DBG("WAV interrupt\n");
+@@ -963,15 +963,15 @@
+ 	u32 tmp32;
+ 
+ 	/* make sure the interrupt bits are setup the way we want */
+-	tmp32 = AD1889_READL(dev, AD_DMAWAVCTRL);
++	tmp32 = AD1889_READL(dev, AD_DMA_WAVCTRL);
+ 	tmp32 &= ~0xff; /* flat dma, no sg, mask out the intr bits */
+ 	tmp32 |= 0x6;  /* intr on count, loop */
+-	AD1889_WRITEL(dev, AD_DMAWAVCTRL, tmp32);
++	AD1889_WRITEL(dev, AD_DMA_WAVCTRL, tmp32);
+ 
+ 	/* unmute... */
+-	tmp16 = AD1889_READW(dev, AD_DSWADA);
++	tmp16 = AD1889_READW(dev, AD_DS_WADA);
+ 	tmp16 &= ~0x8080;
+-	AD1889_WRITEW(dev, AD_DSWADA, tmp16);
++	AD1889_WRITEW(dev, AD_DS_WADA, tmp16);
+ }
+ 
+ static int __devinit ad1889_probe(struct pci_dev *pcidev, const struct pci_device_id *ent)
+@@ -1004,7 +1004,7 @@
+ 		goto out1;
+ 	}
+ 
+-	dev->regbase = ioremap_nocache(bar, AD_DSIOMEMSIZE);
++	dev->regbase = ioremap_nocache(bar, AD_DS_IOMEMSIZE);
+ 	if (!dev->regbase) {
+ 		printk(KERN_ERR DEVNAME ": unable to remap iomem\n");
+ 		goto out2;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/sound/oss/ad1889.h CVS2_6_15_RC7_PA0/sound/oss/ad1889.h
+--- LINUS_2_6_15_RC7/sound/oss/ad1889.h	2005-12-27 13:26:02.000000000 -0700
++++ CVS2_6_15_RC7_PA0/sound/oss/ad1889.h	2005-03-01 16:00:56.000000000 -0700
+@@ -1,57 +1,58 @@
+ #ifndef _AD1889_H_
+ #define _AD1889_H_
+ 
+-#define AD_DSWSMC	0x00	/* DMA input wave/syn mixer control */
+-#define AD_DSRAMC	0x02	/* DMA output resamp/ADC mixer control */
+-#define AD_DSWADA	0x04	/* DMA input wave attenuation */
+-#define AD_DSSYDA	0x06	/* DMA input syn attentuation */
+-#define AD_DSWAS	0x08	/* wave input sample rate */
+-#define AD_DSRES	0x0a	/* resampler output sample rate */
+-#define AD_DSCCS	0x0c	/* chip control/status */
+-
+-#define AD_DMARESBA	0x40	/* RES base addr */
+-#define AD_DMARESCA	0x44	/* RES current addr */
+-#define AD_DMARESBC	0x48	/* RES base cnt */
+-#define AD_DMARESCC	0x4c	/* RES current count */
+-#define AD_DMAADCBA	0x50	/* ADC */
+-#define AD_DMAADCCA	0x54
+-#define AD_DMAADCBC	0x58
+-#define AD_DMAADCCC	0x5c
+-#define AD_DMASYNBA	0x60	/* SYN */
+-#define AD_DMASYNCA	0x64
+-#define AD_DMASYNBC	0x68
+-#define AD_DMASYNCC	0x6c
+-#define AD_DMAWAVBA	0x70	/* WAV */
+-#define AD_DMAWAVCA	0x74
+-#define AD_DMAWAVBC	0x78
+-#define AD_DMAWAVCC	0x7c
+-#define AD_DMARESICC	0x80	/* RES interrupt current count */
+-#define AD_DMARESIBC	0x84	/* RES interrupt base count */
+-#define AD_DMAADCICC	0x88	/* ADC interrupt current count */
+-#define AD_DMAADCIBC	0x8c	/* ADC interrupt base count */
+-#define AD_DMASYNICC	0x90	/* SYN interrupt current count */
+-#define AD_DMASYNIBC	0x94	/* SYN interrupt base count */
+-#define AD_DMAWAVICC	0x98	/* WAV interrupt current count */
+-#define AD_DMAWAVIBC	0x9c	/* WAV interrupt base count */
+-#define AD_DMARESCTRL	0xa0	/* RES PCI control/status */
+-#define AD_DMAADCCTRL	0xa8	/* ADC PCI control/status */
+-#define AD_DMASYNCTRL	0xb0	/* SYN PCI control/status */
+-#define AD_DMAWAVCTRL	0xb8	/* WAV PCI control/status */
+-#define AD_DMADISR	0xc0	/* PCI DMA intr status */
+-#define AD_DMACHSS	0xc4	/* PCI DMA channel stop status */
+-
+-#define AD_GPIOIPC	0xc8	/* IO port ctrl */
+-#define AD_GPIOOP	0xca	/* IO output status */
+-#define AD_GPIOIP	0xcc	/* IO input status */
++#define AD_DS_WSMC	0x00	/* DMA input wave/syn mixer control */
++#define AD_DS_RAMC	0x02	/* DMA output resamp/ADC mixer control */
++#define AD_DS_WADA	0x04	/* DMA input wave attenuation */
++#define AD_DS_SYDA	0x06	/* DMA input syn attentuation */
++#define AD_DS_WAS	0x08	/* wave input sample rate */
++#define AD_DS_RES	0x0a	/* resampler output sample rate */
++#define AD_DS_CCS	0x0c	/* chip control/status */
++
++#define AD_DMA_RESBA	0x40	/* RES base addr */
++#define AD_DMA_RESCA	0x44	/* RES current addr */
++#define AD_DMA_RESBC	0x48	/* RES base cnt */
++#define AD_DMA_RESCC	0x4c	/* RES current count */
++#define AD_DMA_ADCBA	0x50	/* ADC */
++#define AD_DMA_ADCCA	0x54
++#define AD_DMA_ADCBC	0x58
++#define AD_DMA_ADCCC	0x5c
++#define AD_DMA_SYNBA	0x60	/* SYN */
++#define AD_DMA_SYNCA	0x64
++#define AD_DMA_SYNBC	0x68
++#define AD_DMA_SYNCC	0x6c
++#define AD_DMA_WAVBA	0x70	/* WAV */
++#define AD_DMA_WAVCA	0x74
++#define AD_DMA_WAVBC	0x78
++#define AD_DMA_WAVCC	0x7c
++#define AD_DMA_RESICC	0x80	/* RES interrupt current count */
++#define AD_DMA_RESIBC	0x84	/* RES interrupt base count */
++#define AD_DMA_ADCICC	0x88	/* ADC interrupt current count */
++#define AD_DMA_ADCIBC	0x8c	/* ADC interrupt base count */
++#define AD_DMA_SYNICC	0x90	/* SYN interrupt current count */
++#define AD_DMA_SYNIBC	0x94	/* SYN interrupt base count */
++#define AD_DMA_WAVICC	0x98	/* WAV interrupt current count */
++#define AD_DMA_WAVIBC	0x9c	/* WAV interrupt base count */
++#define AD_DMA_RESCTRL	0xa0	/* RES PCI control/status */
++#define AD_DMA_ADCCTRL	0xa8	/* ADC PCI control/status */
++#define AD_DMA_SYNCTRL	0xb0	/* SYN PCI control/status */
++#define AD_DMA_WAVCTRL	0xb8	/* WAV PCI control/status */
++#define AD_DMA_DISR	0xc0	/* PCI DMA intr status */
++#define AD_DMA_CHSS	0xc4	/* PCI DMA channel stop status */
++
++#define AD_GPIO_IPC	0xc8	/* IO port ctrl */
++#define AD_GPIO_OP	0xca	/* IO output status */
++#define AD_GPIO_IP	0xcc	/* IO input status */
+ 
+ /* AC97 registers, 0x100 - 0x17f; see ac97.h */
+-#define AD_ACIC		0x180	/* AC Link interface ctrl */
++#define AD_AC97_BASE    0x100   /* ac97 base register */
++#define AD_AC97_ACIC	0x180	/* AC Link interface ctrl */
+ 
+ /* OPL3; BAR1 */
+-#define AD_OPLM0AS	0x00	/* Music0 address/status */
+-#define AD_OPLM0DATA	0x01	/* Music0 data */
+-#define AD_OPLM1A	0x02	/* Music1 address */
+-#define AD_OPLM1DATA	0x03	/* Music1 data */
++#define AD_OPL_M0AS	0x00	/* Music0 address/status */
++#define AD_OPL_M0DATA	0x01	/* Music0 data */
++#define AD_OPL_M1A	0x02	/* Music1 address */
++#define AD_OPL_M1DATA	0x03	/* Music1 data */
+ /* 0x04-0x0f reserved */
+ 
+ /* MIDI; BAR2 */
+@@ -59,9 +60,9 @@
+ #define AD_MISC		0x01	/* MIDI status/cmd */
+ /* 0x02-0xff reserved */
+ 
+-#define AD_DSIOMEMSIZE	512
+-#define AD_OPLMEMSIZE	16
+-#define AD_MIDIMEMSIZE	16
++#define AD_DS_IOMEMSIZE	512
++#define AD_OPL_MEMSIZE	16
++#define AD_MIDI_MEMSIZE	16
+ 
+ #define AD_WAV_STATE	0
+ #define AD_ADC_STATE	1
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/sound/oss/harmony.c CVS2_6_15_RC7_PA0/sound/oss/harmony.c
+--- LINUS_2_6_15_RC7/sound/oss/harmony.c	2005-12-27 13:26:02.000000000 -0700
++++ CVS2_6_15_RC7_PA0/sound/oss/harmony.c	2005-12-19 13:43:22.000000000 -0700
+@@ -1236,7 +1236,7 @@
+ 	}
+ 
+ 	/* Set the HPA of harmony */
+-	harmony.hpa = (struct harmony_hpa *)dev->hpa;
++	harmony.hpa = (struct harmony_hpa *)dev->hpa.start;
+ 	harmony.dev = dev;
+ 
+ 	/* Grab the ID and revision from the device */
+@@ -1250,7 +1250,7 @@
+ 
+ 	printk(KERN_INFO "Lasi Harmony Audio driver " HARMONY_VERSION ", "
+ 			"h/w id %i, rev. %i at 0x%lx, IRQ %i\n",
+-			id, rev, dev->hpa, harmony.dev->irq);
++			id, rev, dev->hpa.start, harmony.dev->irq);
+ 	
+ 	/* Make sure the control bit isn't set, although I don't think it 
+ 	   ever is. */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/sound/pci/Kconfig CVS2_6_15_RC7_PA0/sound/pci/Kconfig
+--- LINUS_2_6_15_RC7/sound/pci/Kconfig	2005-12-27 13:26:03.000000000 -0700
++++ CVS2_6_15_RC7_PA0/sound/pci/Kconfig	2005-11-11 21:09:48.000000000 -0700
+@@ -321,6 +321,14 @@
+ 	  To compile this as a module, choose M here: the module
+ 	  will be called snd-ad1889.
+ 
++config SND_AD1889_OPL3
++	bool "Analog Devices AD1889 OPL3 Support (Experimental)"
++	depends on SND_AD1889 && EXPERIMENTAL
++	select SND_OPL3_LIB
++	help
++	  Say Y here to include support for the OPL3-compatible interface
++	  provided on an Analog Devices AD1889.
++
+ config SND_ALS4000
+ 	tristate "Avance Logic ALS4000"
+ 	depends on SND && ISA_DMA_API
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_15_RC7/sound/pci/ad1889.c CVS2_6_15_RC7_PA0/sound/pci/ad1889.c
+--- LINUS_2_6_15_RC7/sound/pci/ad1889.c	2005-12-27 13:26:03.000000000 -0700
++++ CVS2_6_15_RC7_PA0/sound/pci/ad1889.c	2005-11-11 21:09:48.000000000 -0700
+@@ -45,6 +45,10 @@
+ #include <sound/initval.h>
+ #include <sound/ac97_codec.h>
+ 
++#ifdef CONFIG_SND_AD1889_OPL3
++#include <sound/opl3.h>
++#endif
++
+ #include <asm/io.h>
+ 
+ #include "ad1889.h"
+@@ -55,6 +59,7 @@
+ MODULE_AUTHOR("Kyle McMartin <kyle at parisc-linux.org>, Thibaut Varene <t-bone at parisc-linux.org>");
+ MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver");
+ MODULE_LICENSE("GPL");
++MODULE_VERSION(AD1889_DRVVER);
+ MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1889}}");
+ 
+ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+@@ -94,11 +99,20 @@
+ 	unsigned long bar;
+ 	void __iomem *iobase;
+ 
++#ifdef CONFIG_SND_AD1889_OPL3
++	unsigned long opl3_bar;
++	void __iomem *opl3_iobase;
++
++	opl3_t *opl3;
++	snd_hwdep_t *opl3hwdep;
++#endif
++
+ 	ac97_t *ac97;
+ 	ac97_bus_t *ac97_bus;
+ 	snd_pcm_t *pcm;
+ 	snd_info_entry_t *proc;
+ 
++	struct snd_dma_device dma;
+ 	snd_pcm_substream_t *psubs;
+ 	snd_pcm_substream_t *csubs;
+ 
+@@ -112,25 +126,25 @@
+ static inline u16
+ ad1889_readw(struct snd_ad1889 *chip, unsigned reg)
+ {
+-	return readw(chip->iobase + reg);
++	return ioread16(chip->iobase + reg);
+ }
+ 
+ static inline void
+ ad1889_writew(struct snd_ad1889 *chip, unsigned reg, u16 val)
+ {
+-	writew(val, chip->iobase + reg);
++	iowrite16(val, chip->iobase + reg);
+ }
+ 
+ static inline u32
+ ad1889_readl(struct snd_ad1889 *chip, unsigned reg)
+ {
+-	return readl(chip->iobase + reg);
++	return ioread32(chip->iobase + reg);
+ }
+ 
+ static inline void
+ ad1889_writel(struct snd_ad1889 *chip, unsigned reg, u32 val)
+ {
+-	writel(val, chip->iobase + reg);
++	iowrite32(val, chip->iobase + reg);
+ }
+ 
+ static inline void
+@@ -620,6 +634,9 @@
+ 	if ((st & AD_DMA_DISR_ADCI) && chip->csubs)
+ 		snd_pcm_period_elapsed(chip->csubs);
+ 
++	ad1889_readl(chip, AD_DMA_DISR); /* flush */
++	/* XXX under some circumstances the DISR write flush may not happen */
++
+ 	return IRQ_HANDLED;
+ }
+ 
+@@ -658,6 +675,9 @@
+ 	chip->psubs = NULL;
+ 	chip->csubs = NULL;
+ 
++	chip->dma.dev = &chip->pci->dev;
++	chip->dma.type = SNDRV_DMA_TYPE_DEV;
++
+ 	err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+ 						snd_dma_pci_data(chip->pci),
+ 						BUFFER_BYTES_MAX / 2,
+@@ -874,6 +894,11 @@
+ 	if (chip->iobase)
+ 		iounmap(chip->iobase);
+ 
++#ifdef CONFIG_SND_AD1889_OPL3
++	if (chip->opl3_iobase)
++		iounmap(chip->opl3_iobase);
++#endif
++	
+ 	pci_release_regions(chip->pci);
+ 	pci_disable_device(chip->pci);
+ 
+@@ -954,6 +979,17 @@
+ 
+ 	spin_lock_init(&chip->lock);	/* only now can we call ad1889_free */
+ 
++#ifdef CONFIG_SND_AD1889_OPL3
++	chip->opl3_bar = pci_resource_start(pci, 1);
++	chip->opl3_iobase = ioremap_nocache(chip->opl3_bar, 
++					   pci_resource_len(pci, 1));
++	if (chip->opl3_iobase == NULL) {
++		printk(KERN_ERR PFX "unable to reserve region.\n");
++		snd_ad1889_free(chip);
++		return -EBUSY;
++	}
++#endif
++
+ 	if (request_irq(pci->irq, snd_ad1889_interrupt,
+ 			SA_INTERRUPT|SA_SHIRQ, card->driver, (void*)chip)) {
+ 		printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
+@@ -1029,6 +1065,22 @@
+ 	if (err < 0)
+ 		goto free_and_ret;
+ 	
++#ifdef CONFIG_SND_AD1889_OPL3
++	err = snd_opl3_create_mapped(card, chip->opl3_iobase,
++				     chip->opl3_iobase + 2, OPL3_HW_OPL3,
++				     &chip->opl3);
++	if (err) {
++		printk(KERN_ERR PFX "failed to create opl3\n");
++		goto free_and_ret;
++	}
++
++	err = snd_opl3_hwdep_new(chip->opl3, 0, 0, &chip->opl3hwdep);
++	if (err) {
++		printk(KERN_ERR PFX "failed to create opl3hwdep\n");
++		goto free_and_ret;
++	}
++#endif
++
+ 	err = snd_ad1889_pcm_init(chip, 0, NULL);
+ 	if (err < 0)
+ 		goto free_and_ret;

Added: people/waldi/linux-2.6/debian/patches/ia64-irq-affinity-upfix.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/ia64-irq-affinity-upfix.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,18 @@
+## DP: Description: Add a no-op set_irq_affinity_info() for non-SMP
+## DP: Patch author: dann frazier <dannf at hp.com>
+## DP: Upstream status: Submitted
+#
+--- linux-2.6-2.6.13/arch/ia64/kernel/irq.c~	2005-10-20 17:28:56.000000000 -0600
++++ linux-2.6-2.6.13/arch/ia64/kernel/irq.c	2005-10-20 17:29:41.000000000 -0600
+@@ -105,6 +105,11 @@
+ 		irq_redir[irq] = (char) (redir & 0xff);
+ 	}
+ }
++
++#else /* !CONFIG_SMP */
++void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
++{
++}
+ #endif /* CONFIG_SMP */
+ 
+ #ifdef CONFIG_HOTPLUG_CPU

Added: people/waldi/linux-2.6/debian/patches/m68k-bvme.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/m68k-bvme.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,10 @@
+--- linux-2.6-2.6.14/arch/m68k/bvme6000/bvmeints.c.orig	2005-10-28 02:02:08.000000000 +0200
++++ linux-2.6-2.6.14/arch/m68k/bvme6000/bvmeints.c	2005-11-07 21:35:32.000000000 +0100
+@@ -15,6 +15,7 @@
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/seq_file.h>
++#include <linux/interrupt.h>
+ 
+ #include <asm/ptrace.h>
+ #include <asm/system.h>

Added: people/waldi/linux-2.6/debian/patches/m68k-incompatible.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/m68k-incompatible.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,4737 @@
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/Makefile linux-m68k/Makefile
+--- linux-i386/Makefile	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/Makefile	2005-10-29 10:40:15.000000000 +0200
+@@ -189,7 +189,7 @@
+ # Default value for CROSS_COMPILE is not to prefix executables
+ # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
+ 
+-ARCH		?= $(SUBARCH)
++ARCH		?= m68k
+ CROSS_COMPILE	?=
+ 
+ # Architecture as present in compile.h
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/Kconfig linux-m68k/arch/m68k/Kconfig
+--- linux-i386/arch/m68k/Kconfig	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/Kconfig	2005-10-29 10:40:42.000000000 +0200
+@@ -618,7 +618,7 @@
+ 
+ config SERIAL167
+ 	bool "CD2401 support for MVME166/7 serial ports"
+-	depends on MVME16x && BROKEN
++	depends on MVME16x
+ 	help
+ 	  This is the driver for the serial ports on the Motorola MVME166,
+ 	  167, and 172 boards.  Everyone using one of these boards should say
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/amiga/amiints.c linux-m68k/arch/m68k/amiga/amiints.c
+--- linux-i386/arch/m68k/amiga/amiints.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/amiga/amiints.c	2005-11-01 16:31:28.000000000 +0100
+@@ -40,6 +40,7 @@
+ #include <linux/sched.h>
+ #include <linux/kernel_stat.h>
+ #include <linux/init.h>
++#include <linux/interrupt.h>
+ #include <linux/errno.h>
+ #include <linux/seq_file.h>
+ 
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/amiga/config.c linux-m68k/arch/m68k/amiga/config.c
+--- linux-i386/arch/m68k/amiga/config.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/amiga/config.c	2005-10-12 16:31:23.000000000 +0200
+@@ -431,9 +431,6 @@
+   mach_floppy_setup    = amiga_floppy_setup;
+ #endif
+   mach_reset           = amiga_reset;
+-#ifdef CONFIG_DUMMY_CONSOLE
+-  conswitchp           = &dummy_con;
+-#endif
+ #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
+   mach_beep            = amiga_mksound;
+ #endif
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/apollo/config.c linux-m68k/arch/m68k/apollo/config.c
+--- linux-i386/arch/m68k/apollo/config.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/apollo/config.c	2005-10-12 16:31:23.000000000 +0200
+@@ -176,9 +176,6 @@
+ 	mach_set_clock_mmss  = dn_dummy_set_clock_mmss; /* */
+ 	mach_process_int     = dn_process_int;
+ 	mach_reset	     = dn_dummy_reset;  /* */
+-#ifdef CONFIG_DUMMY_CONSOLE
+-        conswitchp           = &dummy_con;
+-#endif
+ #ifdef CONFIG_HEARTBEAT
+ 	mach_heartbeat = dn_heartbeat;
+ #endif
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/atari/config.c linux-m68k/arch/m68k/atari/config.c
+--- linux-i386/arch/m68k/atari/config.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/atari/config.c	2005-10-12 16:31:23.000000000 +0200
+@@ -247,9 +247,6 @@
+ #ifdef CONFIG_ATARI_FLOPPY
+     mach_floppy_setup	 = atari_floppy_setup;
+ #endif
+-#ifdef CONFIG_DUMMY_CONSOLE
+-    conswitchp	         = &dummy_con;
+-#endif
+     mach_max_dma_address = 0xffffff;
+ #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
+     mach_beep          = atari_mksound;
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/fpsp040/skeleton.S linux-m68k/arch/m68k/fpsp040/skeleton.S
+--- linux-i386/arch/m68k/fpsp040/skeleton.S	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/fpsp040/skeleton.S	2005-10-29 10:40:44.000000000 +0200
+@@ -381,10 +381,8 @@
+ .Lnotkern:
+ 	SAVE_ALL_INT
+ 	GET_CURRENT(%d0)
+-	tstb	%curptr@(TASK_NEEDRESCHED)
+-	jne	ret_from_exception	| deliver signals,
+-					| reschedule etc..
+-	RESTORE_ALL
++	| deliver signals, reschedule etc..
++	jra	ret_from_exception
+ 
+ |
+ |	mem_write --- write to user or supervisor address space
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/hp300/config.c linux-m68k/arch/m68k/hp300/config.c
+--- linux-i386/arch/m68k/hp300/config.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/hp300/config.c	2005-10-12 16:31:23.000000000 +0200
+@@ -261,9 +261,6 @@
+ #ifdef CONFIG_HEARTBEAT
+ 	mach_heartbeat       = hp300_pulse;
+ #endif
+-#ifdef CONFIG_DUMMY_CONSOLE
+-	conswitchp	     = &dummy_con;
+-#endif
+ 	mach_max_dma_address = 0xffffffff;
+ 
+ 	if (hp300_model >= HP_330 && hp300_model <= HP_433S && hp300_model != HP_350) {
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/ifpsp060/iskeleton.S linux-m68k/arch/m68k/ifpsp060/iskeleton.S
+--- linux-i386/arch/m68k/ifpsp060/iskeleton.S	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/ifpsp060/iskeleton.S	2005-10-29 10:40:44.000000000 +0200
+@@ -75,10 +75,8 @@
+ .Lnotkern:
+ 	SAVE_ALL_INT
+ 	GET_CURRENT(%d0)
+-	tstb	%curptr@(TASK_NEEDRESCHED)
+-	jne	ret_from_exception	| deliver signals,
+-					| reschedule etc..
+-	RESTORE_ALL
++	| deliver signals, reschedule etc..
++	jra	ret_from_exception
+ 
+ |
+ | _060_real_chk():
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/asm-offsets.c linux-m68k/arch/m68k/kernel/asm-offsets.c
+--- linux-i386/arch/m68k/kernel/asm-offsets.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/kernel/asm-offsets.c	2005-05-30 16:31:22.000000000 +0200
+@@ -25,12 +25,8 @@
+ 	DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+ 	DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+ 	DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+-	DEFINE(TASK_WORK, offsetof(struct task_struct, thread.work));
+-	DEFINE(TASK_NEEDRESCHED, offsetof(struct task_struct, thread.work.need_resched));
+-	DEFINE(TASK_SYSCALL_TRACE, offsetof(struct task_struct, thread.work.syscall_trace));
+-	DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, thread.work.sigpending));
+-	DEFINE(TASK_NOTIFY_RESUME, offsetof(struct task_struct, thread.work.notify_resume));
+ 	DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
++	DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
+ 	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+ 	DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+ 
+@@ -45,6 +41,10 @@
+ 	DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
+ 	DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
+ 
++	/* offsets into the thread_info struct */
++	DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
++	DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
++
+ 	/* offsets into the pt_regs */
+ 	DEFINE(PT_D0, offsetof(struct pt_regs, d0));
+ 	DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0));
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/bios32.c linux-m68k/arch/m68k/kernel/bios32.c
+--- linux-i386/arch/m68k/kernel/bios32.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/kernel/bios32.c	2004-10-20 16:38:00.000000000 +0200
+@@ -285,7 +285,7 @@
+ 
+ 	DBG_DEVS(("layout_bus: starting bus %d\n", bus->number));
+ 
+-	if (!bus->devices && !bus->children)
++	if (list_empty(&bus->devices) && list_empty(&bus->children))
+ 		return;
+ 
+ 	/*
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/entry.S linux-m68k/arch/m68k/kernel/entry.S
+--- linux-i386/arch/m68k/kernel/entry.S	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/kernel/entry.S	2005-10-29 10:40:44.000000000 +0200
+@@ -44,9 +44,7 @@
+ 
+ #include <asm/asm-offsets.h>
+ 
+-.globl system_call, buserr, trap
+-.globl resume, ret_from_exception
+-.globl ret_from_signal
++.globl system_call, buserr, trap, resume
+ .globl inthandler, sys_call_table
+ .globl sys_fork, sys_clone, sys_vfork
+ .globl ret_from_interrupt, bad_interrupt
+@@ -58,7 +56,7 @@
+ 	movel	%sp,%sp at -		| stack frame pointer argument
+ 	bsrl	buserr_c
+ 	addql	#4,%sp
+-	jra	ret_from_exception
++	jra	.Lret_from_exception
+ 
+ ENTRY(trap)
+ 	SAVE_ALL_INT
+@@ -66,7 +64,7 @@
+ 	movel	%sp,%sp at -		| stack frame pointer argument
+ 	bsrl	trap_c
+ 	addql	#4,%sp
+-	jra	ret_from_exception
++	jra	.Lret_from_exception
+ 
+ 	| After a fork we jump here directly from resume,
+ 	| so that %d1 contains the previous task
+@@ -75,30 +73,31 @@
+ 	movel	%d1,%sp at -
+ 	jsr	schedule_tail
+ 	addql	#4,%sp
+-	jra	ret_from_exception
++	jra	.Lret_from_exception
+ 
+-badsys:
+-	movel	#-ENOSYS,%sp@(PT_D0)
+-	jra	ret_from_exception
+-
+-do_trace:
++do_trace_entry:
+ 	movel	#-ENOSYS,%sp@(PT_D0)	| needed for strace
+ 	subql	#4,%sp
+ 	SAVE_SWITCH_STACK
+ 	jbsr	syscall_trace
+ 	RESTORE_SWITCH_STACK
+ 	addql	#4,%sp
+-	movel	%sp@(PT_ORIG_D0),%d1
+-	movel	#-ENOSYS,%d0
+-	cmpl	#NR_syscalls,%d1
+-	jcc	1f
+-	jbsr	@(sys_call_table,%d1:l:4)@(0)
+-1:	movel	%d0,%sp@(PT_D0)		| save the return value
+-	subql	#4,%sp			| dummy return address
++	movel	%sp@(PT_ORIG_D0),%d0
++	cmpl	#NR_syscalls,%d0
++	jcs	syscall
++badsys:
++	movel	#-ENOSYS,%sp@(PT_D0)
++	jra	ret_from_syscall
++
++do_trace_exit:
++	subql	#4,%sp
+ 	SAVE_SWITCH_STACK
+ 	jbsr	syscall_trace
++	RESTORE_SWITCH_STACK
++	addql	#4,%sp
++	jra	.Lret_from_exception
+ 
+-ret_from_signal:
++ENTRY(ret_from_signal)
+ 	RESTORE_SWITCH_STACK
+ 	addql	#4,%sp
+ /* on 68040 complete pending writebacks if any */
+@@ -111,7 +110,7 @@
+ 	addql	#4,%sp
+ 1:
+ #endif
+-	jra	ret_from_exception
++	jra	.Lret_from_exception
+ 
+ ENTRY(system_call)
+ 	SAVE_ALL_SYS
+@@ -120,30 +119,34 @@
+ 	| save top of frame
+ 	movel	%sp,%curptr@(TASK_THREAD+THREAD_ESP0)
+ 
+-	tstb	%curptr@(TASK_SYSCALL_TRACE)
+-	jne	do_trace
++	| syscall trace?
++	tstb	%curptr@(TASK_INFO+TINFO_FLAGS+2)
++	jmi	do_trace_entry
+ 	cmpl	#NR_syscalls,%d0
+ 	jcc	badsys
++syscall:
+ 	jbsr	@(sys_call_table,%d0:l:4)@(0)
+ 	movel	%d0,%sp@(PT_D0)		| save the return value
+-
++ret_from_syscall:
+ 	|oriw	#0x0700,%sr
+-	movel	%curptr@(TASK_WORK),%d0
++	movew	%curptr@(TASK_INFO+TINFO_FLAGS+2),%d0
+ 	jne	syscall_exit_work
+ 1:	RESTORE_ALL
+ 
+ syscall_exit_work:
+ 	btst	#5,%sp@(PT_SR)		| check if returning to kernel
+ 	bnes	1b			| if so, skip resched, signals
+-	tstw	%d0
+-	jeq	do_signal_return
+-	tstb	%d0
+-	jne	do_delayed_trace
+-
++	lslw	#1,%d0
++	jcs	do_trace_exit
++	jmi	do_delayed_trace
++	lslw	#8,%d0
++	jmi	do_signal_return
+ 	pea	resume_userspace
+-	jmp	schedule
++	jra	schedule
++
+ 
+-ret_from_exception:
++ENTRY(ret_from_exception)
++.Lret_from_exception:
+ 	btst	#5,%sp@(PT_SR)		| check if returning to kernel
+ 	bnes	1f			| if so, skip resched, signals
+ 	| only allow interrupts when we are really the last one on the
+@@ -152,19 +155,18 @@
+ 	andw	#ALLOWINT,%sr
+ 
+ resume_userspace:
+-	movel	%curptr@(TASK_WORK),%d0
+-	lsrl	#8,%d0
++	moveb	%curptr@(TASK_INFO+TINFO_FLAGS+3),%d0
+ 	jne	exit_work
+ 1:	RESTORE_ALL
+ 
+ exit_work:
+ 	| save top of frame
+ 	movel	%sp,%curptr@(TASK_THREAD+THREAD_ESP0)
+-	tstb	%d0
+-	jeq	do_signal_return
+-
++	lslb	#1,%d0
++	jmi	do_signal_return
+ 	pea	resume_userspace
+-	jmp	schedule
++	jra	schedule
++
+ 
+ do_signal_return:
+ 	|andw	#ALLOWINT,%sr
+@@ -254,7 +256,7 @@
+ 
+ 	/* check if we need to do software interrupts */
+ 	tstl	irq_stat+CPUSTAT_SOFTIRQ_PENDING
+-	jeq	ret_from_exception
++	jeq	.Lret_from_exception
+ 	pea	ret_from_exception
+ 	jra	do_softirq
+ 
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/process.c linux-m68k/arch/m68k/kernel/process.c
+--- linux-i386/arch/m68k/kernel/process.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/kernel/process.c	2005-08-30 16:31:36.000000000 +0200
+@@ -239,7 +239,7 @@
+ 	unsigned long stack_offset, *retp;
+ 
+ 	stack_offset = THREAD_SIZE - sizeof(struct pt_regs);
+-	childregs = (struct pt_regs *) ((unsigned long) (p->thread_info) + stack_offset);
++	childregs = (struct pt_regs *) ((unsigned long)p->stack + stack_offset);
+ 
+ 	*childregs = *regs;
+ 	childregs->d0 = 0;
+@@ -384,7 +384,7 @@
+ 	if (!p || p == current || p->state == TASK_RUNNING)
+ 		return 0;
+ 
+-	stack_page = (unsigned long)(p->thread_info);
++	stack_page = (unsigned long)p->stack;
+ 	fp = ((struct switch_stack *)p->thread.ksp)->a6;
+ 	do {
+ 		if (fp < stack_page+sizeof(struct thread_info) ||
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/ptrace.c linux-m68k/arch/m68k/kernel/ptrace.c
+--- linux-i386/arch/m68k/kernel/ptrace.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/kernel/ptrace.c	2005-06-19 16:32:04.000000000 +0200
+@@ -109,7 +109,7 @@
+ {
+ 	unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+ 	put_reg(child, PT_SR, tmp);
+-	child->thread.work.delayed_trace = 0;
++	clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
+ }
+ 
+ /*
+@@ -118,7 +118,7 @@
+ void ptrace_disable(struct task_struct *child)
+ {
+ 	singlestep_disable(child);
+-	child->thread.work.syscall_trace = 0;
++	clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ }
+ 
+ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+@@ -235,9 +235,9 @@
+ 			goto out_eio;
+ 
+ 		if (request == PTRACE_SYSCALL)
+-			child->thread.work.syscall_trace = ~0;
++			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ 		else
+-			child->thread.work.syscall_trace = 0;
++			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ 		child->exit_code = data;
+ 		singlestep_disable(child);
+ 		wake_up_process(child);
+@@ -260,10 +260,10 @@
+ 		if (!valid_signal(data))
+ 			goto out_eio;
+ 
+-		child->thread.work.syscall_trace = 0;
++		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+ 		tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
+ 		put_reg(child, PT_SR, tmp);
+-		child->thread.work.delayed_trace = 1;
++		set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
+ 
+ 		child->exit_code = data;
+ 		/* give it a chance to run. */
+@@ -329,9 +329,6 @@
+ 
+ asmlinkage void syscall_trace(void)
+ {
+-	if (!current->thread.work.delayed_trace &&
+-	    !current->thread.work.syscall_trace)
+-		return;
+ 	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+ 				 ? 0x80 : 0));
+ 	/*
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/kernel/setup.c linux-m68k/arch/m68k/kernel/setup.c
+--- linux-i386/arch/m68k/kernel/setup.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/kernel/setup.c	2005-10-12 16:31:24.000000000 +0200
+@@ -280,6 +280,10 @@
+ 	    }
+ 	}
+ 
++#ifdef CONFIG_DUMMY_CONSOLE
++	conswitchp = &dummy_con;
++#endif
++
+ 	switch (m68k_machtype) {
+ #ifdef CONFIG_AMIGA
+ 	    case MACH_AMIGA:
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/mac/config.c linux-m68k/arch/m68k/mac/config.c
+--- linux-i386/arch/m68k/mac/config.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/mac/config.c	2005-10-12 16:31:24.000000000 +0200
+@@ -212,9 +212,6 @@
+ 	mach_reset           = mac_reset;
+ 	mach_halt            = mac_poweroff;
+ 	mach_power_off       = mac_poweroff;
+-#ifdef CONFIG_DUMMY_CONSOLE
+-	conswitchp	         = &dummy_con;
+-#endif
+ 	mach_max_dma_address = 0xffffffff;
+ #if 0
+ 	mach_debug_init	 = mac_debug_init;
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/q40/config.c linux-m68k/arch/m68k/q40/config.c
+--- linux-i386/arch/m68k/q40/config.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/q40/config.c	2005-10-12 16:31:25.000000000 +0200
+@@ -194,9 +194,6 @@
+     mach_heartbeat = q40_heartbeat;
+ #endif
+     mach_halt = q40_halt;
+-#ifdef CONFIG_DUMMY_CONSOLE
+-    conswitchp = &dummy_con;
+-#endif
+ 
+     /* disable a few things that SMSQ might have left enabled */
+     q40_disable_irqs();
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/sun3/config.c linux-m68k/arch/m68k/sun3/config.c
+--- linux-i386/arch/m68k/sun3/config.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/sun3/config.c	2005-10-12 16:31:25.000000000 +0200
+@@ -160,9 +160,6 @@
+ 	mach_hwclk           =  sun3_hwclk;
+ 	mach_halt	     =  sun3_halt;
+ 	mach_get_hardware_list = sun3_get_hardware_list;
+-#if defined(CONFIG_DUMMY_CONSOLE)
+-	conswitchp	     = &dummy_con;
+-#endif
+ 
+ 	memory_start = ((((int)&_end) + 0x2000) & ~0x1fff);
+ // PROM seems to want the last couple of physical pages. --m
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/arch/m68k/sun3x/config.c linux-m68k/arch/m68k/sun3x/config.c
+--- linux-i386/arch/m68k/sun3x/config.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/arch/m68k/sun3x/config.c	2005-10-12 16:31:25.000000000 +0200
+@@ -71,10 +71,6 @@
+ 	mach_get_model       = sun3_get_model;
+ 	mach_get_hardware_list = sun3x_get_hardware_list;
+ 
+-#ifdef CONFIG_DUMMY_CONSOLE
+-	conswitchp	     = &dummy_con;
+-#endif
+-
+ 	sun3_intreg = (unsigned char *)SUN3X_INTREG;
+ 
+ 	/* only the serial console is known to work anyway... */
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/block/swim3.c linux-m68k/drivers/block/swim3.c
+--- linux-i386/drivers/block/swim3.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/block/swim3.c	2005-10-29 10:42:06.000000000 +0200
+@@ -304,7 +304,7 @@
+ #endif /* CONFIG_PMAC_MEDIABAY */
+ 		start_request(&floppy_states[i]);
+ 	}
+-	sti();
++	local_irq_enable();
+ }
+ 
+ static void start_request(struct floppy_state *fs)
+@@ -370,7 +370,7 @@
+ {
+ 	unsigned long flags;
+ 
+-	save_flags(flags); cli();
++	local_irq_save(flags);
+ 	if (fs->timeout_pending)
+ 		del_timer(&fs->timeout);
+ 	fs->timeout.expires = jiffies + nticks;
+@@ -378,7 +378,7 @@
+ 	fs->timeout.data = (unsigned long) fs;
+ 	add_timer(&fs->timeout);
+ 	fs->timeout_pending = 1;
+-	restore_flags(flags);
++	local_irq_restore(flags);
+ }
+ 
+ static inline void scan_track(struct floppy_state *fs)
+@@ -790,14 +790,13 @@
+ {
+ 	unsigned long flags;
+ 
+-	save_flags(flags);
+-	cli();
++	local_irq_save(flags);
+ 	if (fs->state != idle) {
+ 		++fs->wanted;
+ 		while (fs->state != available) {
+ 			if (interruptible && signal_pending(current)) {
+ 				--fs->wanted;
+-				restore_flags(flags);
++				local_irq_restore(flags);
+ 				return -EINTR;
+ 			}
+ 			interruptible_sleep_on(&fs->wait);
+@@ -805,7 +804,7 @@
+ 		--fs->wanted;
+ 	}
+ 	fs->state = state;
+-	restore_flags(flags);
++	local_irq_restore(flags);
+ 	return 0;
+ }
+ 
+@@ -813,11 +812,10 @@
+ {
+ 	unsigned long flags;
+ 
+-	save_flags(flags);
+-	cli();
++	local_irq_save(flags);
+ 	fs->state = idle;
+ 	start_request(fs);
+-	restore_flags(flags);
++	local_irq_restore(flags);
+ }
+ 
+ static int fd_eject(struct floppy_state *fs)
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/16c552.h linux-m68k/drivers/char/16c552.h
+--- linux-i386/drivers/char/16c552.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-m68k/drivers/char/16c552.h	2001-10-22 11:34:32.000000000 +0200
+@@ -0,0 +1,165 @@
++/*
++ * Definitions for the 16c552 DACE
++ * (dual-asynchronous-communications-element) used on the GVP
++ * IO-Extender. 
++ *
++ * Basically this is two 16c550 uarts's and a parallel port, which is
++ * why the serial definitions should be valid for the 16c550 uart
++ * aswell.
++ *
++ * Data was taken from National Semiconductors duart 16c552
++ * data-sheets and the Texas Instruments DACE 16c552 data-sheets (the
++ * NS version of the chip is _non_ standard and their data-sheets did
++ * cost me several wasted hours of work).
++ *
++ * This file is (C) 1995 Jes Sorensen (jds at kom.auc.dk)
++ *
++ * Moved from drivers/char/ to include/linux/, because it's useful
++ * on more than just the one card. I'm using it on the hp300 DCA
++ * serial driver, for example.  
++ *      -- Peter Maydell <pmaydell at chiark.greenend.org.uk> 05/1998
++ */
++
++#ifndef _16C552_H_
++#define _16C552_H_
++
++/* Serial stuff */
++
++struct uart_16c550 {
++	volatile u_char skip0;
++	volatile u_char RBR;
++	volatile u_char skip1;
++	volatile u_char IER;
++	volatile u_char skip2;
++	volatile u_char IIR;
++	volatile u_char skip3;
++	volatile u_char LCR;
++	volatile u_char skip4;
++	volatile u_char MCR;
++	volatile u_char skip5;
++	volatile u_char LSR;
++	volatile u_char skip6;
++	volatile u_char MSR;
++	volatile u_char skip7;
++	volatile u_char SCR;
++};
++
++#define THR RBR
++#define FCR IIR
++#define DLL RBR
++#define DLM IER
++#define AFR IIR
++
++/*
++ * Bit-defines for the various registers.
++ */
++
++
++/* IER */
++
++#define ERDAI         (1<<0)
++#define ETHREI        (1<<1)
++#define ELSI          (1<<2)
++#define EMSI          (1<<3)
++
++/* IIR - Interrupt Ident. Register */
++
++#define IRQ_PEND      (1<<0) /* NOTE: IRQ_PEND=0 implies irq pending */
++#define IRQ_ID1       (1<<1)
++#define IRQ_ID2       (1<<2)
++#define IRQ_ID3       (1<<3)
++#define FIFO_ENA0     (1<<6) /* Both these are set when FCR(1<<0)=1 */
++#define FIFO_ENA1     (1<<7)
++
++#define IRQ_RLS  (IRQ_ID1 | IRQ_ID2)
++#define IRQ_RDA  (IRQ_ID2)
++#define IRQ_CTI  (IRQ_ID2 | IRQ_ID3)
++#define IRQ_THRE (IRQ_ID1)
++#define IRQ_MS   0
++
++/* FCR - FIFO Control Register */
++
++#define FIFO_ENA      (1<<0)
++#define RCVR_FIFO_RES (1<<1)
++#define XMIT_FIFO_RES (1<<2)
++#define DMA_MODE_SEL  (1<<3)
++#define RCVR_TRIG_LSB (1<<6)
++#define RCVR_TRIG_MSB (1<<7)
++
++#define FIFO_TRIG_1   0x00
++#define FIFO_TRIG_4   RCVR_TRIG_LSB
++#define FIFO_TRIG_8   RCVR_TRIG_MSB
++#define FIFO_TRIG_14  RCVR_TRIG_LSB|RCVR_TRIG_MSB
++
++/* LCR - Line Control Register */
++
++#define WLS0          (1<<0)
++#define WLS1          (1<<1)
++#define STB           (1<<2)
++#define PEN           (1<<3)
++#define EPS           (1<<4)
++#define STICK_PARITY  (1<<5)
++#define SET_BREAK     (1<<6)
++#define DLAB          (1<<7)
++
++#define data_5bit      0x00
++#define data_6bit      0x01
++#define data_7bit      0x02
++#define data_8bit      0x03
++
++
++/* MCR - Modem Control Register */
++
++#define DTR           (1<<0)
++#define RTS           (1<<1)
++#define OUT1          (1<<2)
++#define OUT2          (1<<3)
++#define LOOP          (1<<4)
++
++/* LSR - Line Status Register */
++
++#define DR            (1<<0)
++#define OE            (1<<1)
++#define PE            (1<<2)
++#define FE            (1<<3)
++#define BI            (1<<4)
++#define THRE          (1<<5)
++#define TEMT          (1<<6)
++#define RCVR_FIFO_ERR (1<<7)
++
++/* MSR - Modem Status Register */
++
++#define DCTS          (1<<0)
++#define DDSR          (1<<1)
++#define TERI          (1<<2)
++#define DDCD          (1<<3)
++#define CTS           (1<<4)
++#define DSR           (1<<5)
++#define RING_I        (1<<6)
++#define DCD           (1<<7)
++
++/* AFR - Alternate Function Register */
++
++#define CONCUR_WRITE  (1<<0)
++#define BAUDOUT       (1<<1)
++#define RXRDY         (1<<2)
++
++/* Parallel stuff */
++
++/*
++ * Unfortunately National Semiconductors did not supply the
++ * specifications for the parallel port in the chip :-(
++ * TI succed though, so here they are :-)
++ *
++ * Defines for the bits can be found by including <linux/lp.h>
++ */
++struct IOEXT_par {
++	volatile u_char skip0;
++	volatile u_char DATA;
++	volatile u_char skip1;
++	volatile u_char STATUS;
++	volatile u_char skip2;
++	volatile u_char CTRL;
++};
++
++#endif
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/ioext.h linux-m68k/drivers/char/ioext.h
+--- linux-i386/drivers/char/ioext.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-m68k/drivers/char/ioext.h	2001-10-22 11:34:32.000000000 +0200
+@@ -0,0 +1,108 @@
++/*
++ * Shared data structure for GVP IO-Extender support.
++ *
++ * Merge of ioext.h and ser_ioext.h
++ */
++#ifndef _IOEXT_H_
++#define _IOEXT_H_
++
++#include <linux/config.h>
++#include <linux/netdevice.h>
++
++#include "16c552.h"
++
++#define MAX_IOEXT 5 /*
++		     * The maximum number of io-extenders is 5, as you
++		     * can't have more than 5 ZII boards in any Amiga.
++		     */
++
++#define UART_CLK 7372800
++
++#define IOEXT_BAUD_BASE (UART_CLK / 16)
++
++#define IOEXT_MAX_LINES 2
++
++#define IOEXT_PAR_PLIP  0x0001
++#define IOEXT_PAR_LP    0x0002
++
++
++/*
++ * Macros for the serial driver.
++ */
++#define curruart(info) ((struct uart_16c550 *)(info->port))
++
++#define ser_DTRon(info)  curruart(info)->MCR |=  DTR
++#define ser_RTSon(info)  curruart(info)->MCR |=  RTS
++#define ser_DTRoff(info) curruart(info)->MCR &= ~DTR
++#define ser_RTSoff(info) curruart(info)->MCR &= ~RTS
++
++
++/*
++ * CNTR defines (copied from the GVP SCSI-driver file gvp11.h
++ */
++#define GVP_BUSY	(1<<0)
++#define GVP_IRQ_PEND	(1<<1)
++#define GVP_IRQ_ENA 	(1<<3)
++#define GVP_DIR_WRITE   (1<<4)
++
++
++/*
++ * CTRL defines 
++ */
++#define PORT0_MIDI   (1<<0)  /* CLR = DRIVERS         SET = MIDI      */
++#define PORT1_MIDI   (1<<1)  /* CLR = DRIVERS         SET = MIDI      */
++#define PORT0_DRIVER (1<<2)  /* CLR = RS232,          SET = MIDI      */
++#define PORT1_DRIVER (1<<3)  /* CLR = RS232,          SET = MIDI      */
++#define IRQ_SEL      (1<<4)  /* CLR = INT2,           SET = INT6      */
++#define ROM_BANK_SEL (1<<5)  /* CLR = LOW 32K,        SET = HIGH 32K  */
++#define PORT0_CTRL   (1<<6)  /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */
++#define PORT1_CTRL   (1<<7)  /* CLR = RTSx or RXRDYx, SET = RTSx ONLY */
++
++
++/*
++ * This is the struct describing the registers on the IO-Extender.
++ * NOTE: The board uses a dual uart (16c552), which should be equal to
++ * two 16c550 uarts.
++ */
++typedef struct {
++	char gap0[0x41];
++	volatile unsigned char CNTR;	/* GVP DMAC CNTR (status register)   */
++	char gap1[0x11e];
++	struct uart_16c550 uart0;	/* The first uart                    */
++	char gap2[0xf0];
++	struct uart_16c550 uart1;	/* The second uart                   */
++	char gap3[0xf0];
++	struct IOEXT_par par;		/* The parallel port                 */
++	char gap4[0xfb];
++	volatile unsigned char CTRL;	/* The control-register on the board */
++} IOEXT_struct;
++
++
++typedef struct {
++	int num_uarts;
++	int line[IOEXT_MAX_LINES];
++	volatile struct uart_16c550 *uart[IOEXT_MAX_LINES];
++	IOEXT_struct *board;
++	int spurious_count;
++	unsigned char par_use;		/* IOEXT_PAR_xxx */
++#if defined(CONFIG_GVPIOEXT_PLIP) || defined(CONFIG_GVPIOEXT_PLIP_MODULE)
++	struct nt_device *dev;
++#endif
++#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE)
++	struct lp_struct *lp_table;
++	int lp_dev;
++	int lp_interrupt;
++#endif
++} IOExtInfoType;
++
++/* Number of detected boards.  */
++extern int ioext_num;
++extern IOExtInfoType ioext_info[MAX_IOEXT];
++
++void ioext_plip_interrupt(struct net_device *dev, int *spurious_count);
++void ioext_lp_interrupt(int dev, int *spurious_count);
++
++extern struct net_device ioext_dev_plip[3];
++extern struct lp_struct ioext_lp_table[1];
++
++#endif
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/mc68681.h linux-m68k/drivers/char/mc68681.h
+--- linux-i386/drivers/char/mc68681.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-m68k/drivers/char/mc68681.h	2001-10-22 11:34:32.000000000 +0200
+@@ -0,0 +1,131 @@
++#ifndef _MC68681_H_
++#define _MC68681_H_
++
++/* 
++ * This describes an MC68681 DUART. It has almost only overlayed registers, which
++ * the structure very ugly.
++ * Note that the ri-register isn't really a register of the duart but a kludge of bsc
++ * to make the ring indicator available.
++ * 
++ * The data came from the MFC-31-Developer Kit (from Ralph Seidel,
++ * zodiac at darkness.gun.de) and the data sheet of Phillip's clone device (SCN68681)
++ * (from Richard Hirst, srh at gpt.co.uk)
++ *
++ * 11.11.95 copyright Joerg Dorchain (dorchain at mpi-sb.mpg.de)
++ *
++ */
++
++struct duarthalf {
++union {
++volatile u_char mr1; /* rw */
++volatile u_char mr2; /* rw */
++}  mr;
++volatile u_char ri;   /* special, read */
++union {
++volatile u_char sr;  /* read */
++volatile u_char csr; /* write */
++} sr_csr;
++u_char pad1;
++volatile u_char cr; /* write */
++u_char pad2;
++union {
++volatile u_char rhr; /* read */
++volatile u_char thr; /* write */
++} hr;
++u_char pad3;
++};
++
++struct duart {
++struct duarthalf pa;
++union {
++volatile u_char ipcr; /* read */
++volatile u_char acr;  /* write */
++} ipcr_acr;
++u_char pad1;
++union {
++volatile u_char isr; /* read */
++volatile u_char imr; /* write */
++} ir;
++u_char pad2;
++volatile u_char ctu;
++u_char pad3;
++volatile u_char ctl;
++u_char pad4;
++struct duarthalf pb;
++volatile u_char ivr;
++u_char pad5;
++union {
++volatile u_char ipr; /* read */
++volatile u_char opcr; /* write */
++} ipr_opcr;
++u_char pad6;
++union {
++volatile u_char start; /* read */
++volatile u_char sopc; /* write */
++} start_sopc;
++u_char pad7;
++union {
++volatile u_char stop; /* read */
++volatile u_char ropc; /* write */
++} stop_ropc;
++u_char pad8;
++};
++
++#define MR1_BITS 3
++#define MR1_5BITS 0
++#define MR1_6BITS 1
++#define MR1_7BITS 2
++#define MR1_8BITS 3
++
++#define MR1_PARITY_ODD 4
++
++#define MR1_PARITY 24
++#define MR1_PARITY_WITH 0
++#define MR1_PARITY_FORCE 8
++#define MR1_PARITY_NO 16
++#define MR1_PARITY_MULTIDROP 24
++
++#define MR1_ERROR_BLOCK 32
++#define MR1_FFULL_IRQ 64
++#define MR1_RxRTS_ON 128
++
++#define MR2_STOPS 15
++#define MR2_1STOP 7
++#define MR2_2STOP 15
++
++#define MR2_CTS_ON 16
++#define MR2_TxRTS_ON 32
++
++#define MR2_MODE 192
++#define MR2_NORMAL 0
++#define MR2_ECHO 64
++#define MR2_LOCALLOOP 128
++#define MR2_REMOTELOOP 192
++
++#define CR_RXCOMMAND 3
++#define CR_NONE 0
++#define CR_RX_ON 1
++#define CR_RX_OFF 2
++#define CR_TXCOMMAND 12
++#define CR_TX_ON 4
++#define CR_TX_OFF 8
++#define CR_MISC 112
++#define CR_RESET_MR 16
++#define CR_RESET_RX 32
++#define CR_RESET_TX 48
++#define CR_RESET_ERR 64
++#define CR_RESET_BREAK 80
++#define CR_START_BREAK 96
++#define CR_STOP_BREAK 112
++
++#define SR_RXRDY 1
++#define SR_FFULL 2
++#define SR_TXRDY 4
++#define SR_TXEMPT 8
++#define SR_OVERRUN 16
++#define SR_PARITY 32
++#define SR_FRAMING 64
++#define SR_BREAK 128
++
++
++#endif
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/plip_ioext.c linux-m68k/drivers/char/plip_ioext.c
+--- linux-i386/drivers/char/plip_ioext.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-m68k/drivers/char/plip_ioext.c	2004-10-25 16:38:25.000000000 +0200
+@@ -0,0 +1,1058 @@
++/*
++ * plip_ioext: A parallel port "network" driver for GVP IO-Extender.
++ *
++ * Authors:	See drivers/net/plip.c
++ *              IO-Extender version by Steve Bennett, <msteveb at ozemail.com.au>
++ *
++ * This driver is for use with a 5-bit cable (LapLink (R) cable).
++ */
++
++static const char *version = "NET3 PLIP version 2.2/m68k";
++
++#define __NO_VERSION__
++
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/sched.h>
++#include <linux/errno.h>
++#include <linux/interrupt.h>
++#include <linux/slab.h>
++#include <linux/termios.h>
++#include <linux/tty.h>
++#include <linux/serial.h>
++
++#include <asm/setup.h>
++#include <asm/irq.h>
++#include <asm/amigahw.h>
++#include <asm/amigaints.h>
++#include <linux/zorro.h>
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/fcntl.h>
++#include <linux/string.h>
++#include <linux/ptrace.h>
++#include <linux/if_ether.h>
++
++#include <asm/system.h>
++
++#include <linux/in.h>
++#include <linux/delay.h>
++/*#include <linux/lp_m68k.h>*/
++
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/inetdevice.h>
++#include <linux/skbuff.h>
++#include <linux/if_plip.h>
++
++#include <linux/tqueue.h>
++#include <linux/ioport.h>
++#include <linux/bitops.h>
++#include <asm/byteorder.h>
++
++#include "ioext.h"
++
++#define DEBUG 0
++
++/* Map 'struct device *' to our control structure */
++#define PLIP_DEV(DEV) (&ioext_info[(DEV)->irq])
++
++/************************************************************************
++**
++** PLIP definitions
++**
++*************************************************************************
++*/
++
++/* Use 0 for production, 1 for verification, >2 for debug */
++#ifndef NET_DEBUG
++#define NET_DEBUG 2
++#endif
++static unsigned int net_debug = NET_DEBUG;
++
++/* In micro second */
++#define PLIP_DELAY_UNIT       1
++
++/* Connection time out = PLIP_TRIGGER_WAIT * PLIP_DELAY_UNIT usec */
++#define PLIP_TRIGGER_WAIT	 500
++
++/* Nibble time out = PLIP_NIBBLE_WAIT * PLIP_DELAY_UNIT usec */
++#define PLIP_NIBBLE_WAIT        3000
++
++#define PAR_DATA(dev)     ((dev)->base_addr+0)
++#define PAR_STATUS(dev)   ((dev)->base_addr+2)
++#define PAR_CONTROL(dev)  ((dev)->base_addr+4)
++
++static void enable_par_irq(struct device *dev, int on);
++static int plip_init(struct device *dev);
++
++/* Bottom halfs */
++static void plip_kick_bh(struct device *dev);
++static void plip_bh(struct device *dev);
++
++/* Functions for DEV methods */
++static int plip_rebuild_header(struct sk_buff *skb);
++static int plip_tx_packet(struct sk_buff *skb, struct device *dev);
++static int plip_open(struct device *dev);
++static int plip_close(struct device *dev);
++static struct enet_statistics *plip_get_stats(struct device *dev);
++static int plip_config(struct device *dev, struct ifmap *map);
++static int plip_ioctl(struct device *dev, struct ifreq *ifr, int cmd);
++
++enum plip_connection_state {
++	PLIP_CN_NONE=0,
++	PLIP_CN_RECEIVE,
++	PLIP_CN_SEND,
++	PLIP_CN_CLOSING,
++	PLIP_CN_ERROR
++};
++
++enum plip_packet_state {
++	PLIP_PK_DONE=0,
++	PLIP_PK_TRIGGER,
++	PLIP_PK_LENGTH_LSB,
++	PLIP_PK_LENGTH_MSB,
++	PLIP_PK_DATA,
++	PLIP_PK_CHECKSUM
++};
++
++enum plip_nibble_state {
++	PLIP_NB_BEGIN,
++	PLIP_NB_1,
++	PLIP_NB_2,
++};
++
++struct plip_local {
++	enum plip_packet_state state;
++	enum plip_nibble_state nibble;
++	union {
++		struct {
++#if defined(__LITTLE_ENDIAN)
++			unsigned char lsb;
++			unsigned char msb;
++#elif defined(__BIG_ENDIAN)
++			unsigned char msb;
++			unsigned char lsb;
++#else
++#error  "Please fix the endianness defines in <asm/byteorder.h>"
++#endif            
++		} b;
++		unsigned short h;
++	} length;
++	unsigned short byte;
++	unsigned char  checksum;
++	unsigned char  data;
++	struct sk_buff *skb;
++};
++
++struct net_local {
++	struct enet_statistics enet_stats;
++	struct tq_struct immediate;
++	struct tq_struct deferred;
++	struct plip_local snd_data;
++	struct plip_local rcv_data;
++	unsigned long  trigger;
++	unsigned long  nibble;
++	enum plip_connection_state connection;
++	unsigned short timeout_count;
++	char is_deferred;
++	int (*orig_rebuild_header)(struct sk_buff *skb);
++};
++
++struct device ioext_dev_plip[] = {
++	{
++		"plip0",
++		0, 0, 0, 0,    /* memory */
++		0, 0,    /* base, irq */
++		0, 0, 0, NULL, plip_init 
++	},
++	{
++		"plip1",
++		0, 0, 0, 0,    /* memory */
++		0, 0,    /* base, irq */
++		0, 0, 0, NULL, plip_init 
++	},
++	{
++		"plip2",
++		0, 0, 0, 0,    /* memory */
++		0, 0,    /* base, irq */
++		0, 0, 0, NULL, plip_init 
++	}
++};
++
++/*
++ * Check for and handle an interrupt for this PLIP device.
++ *
++ */
++void ioext_plip_interrupt(struct device *dev, int *spurious_count)
++{
++	struct net_local *nl;
++	struct plip_local *rcv;
++	unsigned char c0;
++	unsigned long flags;
++
++	nl = (struct net_local *)dev->priv;
++	rcv = &nl->rcv_data;
++
++	c0 = z_readb(PAR_STATUS(dev));
++
++	if (dev->interrupt) {
++		return;
++	}
++
++	if ((c0 & 0xf8) != 0xc0) {
++		/* Not for us */
++		++*spurious_count;
++		return;
++	}
++
++	*spurious_count = 0;
++	dev->interrupt = 1;
++
++	local_irq_save(flags);
++
++	switch (nl->connection) {
++	case PLIP_CN_CLOSING:
++		dev->tbusy = 0;
++	case PLIP_CN_NONE:
++	case PLIP_CN_SEND:
++		dev->last_rx = jiffies;
++		rcv->state = PLIP_PK_TRIGGER;
++		nl->connection = PLIP_CN_RECEIVE;
++		nl->timeout_count = 0;
++		queue_task(&nl->immediate, &tq_immediate);
++		mark_bh(IMMEDIATE_BH);
++		local_irq_restore(flags);
++#if 0
++		printk("%s: receive irq in SEND/NONE/CLOSING (%d) ok\n",
++		       dev->name, nl->connection);
++#endif
++		break;
++
++	case PLIP_CN_RECEIVE:
++		local_irq_restore(flags);
++		printk("%s: receive interrupt when receiving packet\n",
++		       dev->name);
++		break;
++
++	case PLIP_CN_ERROR:
++		local_irq_restore(flags);
++		printk("%s: receive interrupt in error state\n", dev->name);
++		break;
++	}
++}
++
++
++/* Bottom half handler for the delayed request.
++   This routine is kicked by do_timer().
++   Request `plip_bh' to be invoked. */
++static void
++plip_kick_bh(struct device *dev)
++{
++	struct net_local *nl = (struct net_local *)dev->priv;
++
++	if (nl->is_deferred) {
++		queue_task(&nl->immediate, &tq_immediate);
++		mark_bh(IMMEDIATE_BH);
++	}
++}
++
++/* Forward declarations of internal routines */
++static int plip_none(struct device *, struct net_local *,
++		     struct plip_local *, struct plip_local *);
++static int plip_receive_packet(struct device *, struct net_local *,
++			       struct plip_local *, struct plip_local *);
++static int plip_send_packet(struct device *, struct net_local *,
++			    struct plip_local *, struct plip_local *);
++static int plip_connection_close(struct device *, struct net_local *,
++				 struct plip_local *, struct plip_local *);
++static int plip_error(struct device *, struct net_local *,
++		      struct plip_local *, struct plip_local *);
++static int plip_bh_timeout_error(struct device *dev, struct net_local *nl,
++				 struct plip_local *snd,
++				 struct plip_local *rcv,
++				 int error);
++
++#define OK        0
++#define TIMEOUT   1
++#define ERROR     2
++
++typedef int (*plip_func)(struct device *dev, struct net_local *nl,
++			 struct plip_local *snd, struct plip_local *rcv);
++
++static plip_func connection_state_table[] =
++{
++	plip_none,
++	plip_receive_packet,
++	plip_send_packet,
++	plip_connection_close,
++	plip_error
++};
++
++/*
++** enable_par_irq()
++** 
++** Enable or disable parallel irq for 'dev' according to 'on'.
++**
++** It is NOT possible to disable only the parallel irq.
++** So we disable the board interrupt instead. This means that
++** during reception of a PLIP packet, no serial interrupts can
++** happen. Sorry.
++*/
++static void enable_par_irq(struct device *dev, int on)
++{
++	if (on) {
++		PLIP_DEV(dev)->board->CNTR |= GVP_IRQ_ENA;
++	}
++	else {
++		PLIP_DEV(dev)->board->CNTR &= ~GVP_IRQ_ENA;
++	}
++}
++
++/* Bottom half handler of PLIP. */
++static void
++plip_bh(struct device *dev)
++{
++	struct net_local *nl = (struct net_local *)dev->priv;
++	struct plip_local *snd = &nl->snd_data;
++	struct plip_local *rcv = &nl->rcv_data;
++	plip_func f;
++	int r;
++
++	nl->is_deferred = 0;
++	f = connection_state_table[nl->connection];
++	if ((r = (*f)(dev, nl, snd, rcv)) != OK
++	    && (r = plip_bh_timeout_error(dev, nl, snd, rcv, r)) != OK) {
++		nl->is_deferred = 1;
++		queue_task(&nl->deferred, &tq_timer);
++	}
++}
++
++static int
++plip_bh_timeout_error(struct device *dev, struct net_local *nl,
++		      struct plip_local *snd, struct plip_local *rcv,
++		      int error)
++{
++	unsigned char c0;
++	unsigned long flags;
++
++	local_irq_save(flags);
++	if (nl->connection == PLIP_CN_SEND) {
++
++		if (error != ERROR) { /* Timeout */
++			nl->timeout_count++;
++			if ((snd->state == PLIP_PK_TRIGGER
++			     && nl->timeout_count <= 10)
++			    || nl->timeout_count <= 3) {
++				local_irq_restore(flags);
++				/* Try again later */
++				return TIMEOUT;
++			}
++			c0 = z_readb(PAR_STATUS(dev));
++			printk(KERN_INFO "%s: transmit timeout(%d,%02x)\n",
++			       dev->name, snd->state, c0);
++		}
++		nl->enet_stats.tx_errors++;
++		nl->enet_stats.tx_aborted_errors++;
++	} else if (nl->connection == PLIP_CN_RECEIVE) {
++		if (rcv->state == PLIP_PK_TRIGGER) {
++			/* Transmission was interrupted. */
++			local_irq_restore(flags);
++			return OK;
++		}
++		if (error != ERROR) { /* Timeout */
++			if (++nl->timeout_count <= 3) {
++				local_irq_restore(flags);
++				/* Try again later */
++				return TIMEOUT;
++			}
++			c0 = z_readb(PAR_STATUS(dev));
++			printk(KERN_INFO "%s: receive timeout(%d,%02x)\n",
++			       dev->name, rcv->state, c0);
++		}
++		nl->enet_stats.rx_dropped++;
++	}
++	rcv->state = PLIP_PK_DONE;
++	if (rcv->skb) {
++		kfree_skb(rcv->skb);
++		rcv->skb = NULL;
++	}
++	snd->state = PLIP_PK_DONE;
++	if (snd->skb) {
++		dev_kfree_skb(snd->skb);
++		snd->skb = NULL;
++	}
++	enable_par_irq(dev, 0);
++	dev->tbusy = 1;
++	nl->connection = PLIP_CN_ERROR;
++	z_writeb(0x00, PAR_DATA(dev));
++	local_irq_restore(flags);
++
++	return TIMEOUT;
++}
++
++static int
++plip_none(struct device *dev, struct net_local *nl,
++	  struct plip_local *snd, struct plip_local *rcv)
++{
++	return OK;
++}
++
++/* PLIP_RECEIVE --- receive a byte(two nibbles)
++   Returns OK on success, TIMEOUT on timeout */
++inline static int
++plip_receive(struct device *dev, unsigned short nibble_timeout, 
++	     enum plip_nibble_state *ns_p, unsigned char *data_p)
++{
++	unsigned char c0, c1;
++	unsigned int cx;
++
++	switch (*ns_p) {
++	case PLIP_NB_BEGIN:
++		cx = nibble_timeout;
++		while (1) {
++			c0 = z_readb(PAR_STATUS(dev));
++			udelay(PLIP_DELAY_UNIT);
++			if ((c0 & 0x80) == 0) {
++				c1 = z_readb(PAR_STATUS(dev));
++				if (c0 == c1)
++					break;
++			}
++			if (--cx == 0)
++				return TIMEOUT;
++		}
++#if 0
++		printk("received first nybble: %02X -> %02X\n",
++		       c0, (c0 >> 3) & 0x0F);
++#endif
++		*data_p = (c0 >> 3) & 0x0f;
++		z_writeb(0x10, PAR_DATA(dev)); /* send ACK */
++		*ns_p = PLIP_NB_1;
++
++	case PLIP_NB_1:
++		cx = nibble_timeout;
++		while (1) {
++			c0 = z_readb(PAR_STATUS(dev));
++			udelay(PLIP_DELAY_UNIT);
++			if (c0 & 0x80) {
++				c1 = z_readb(PAR_STATUS(dev));
++				if (c0 == c1)
++					break;
++			}
++			if (--cx == 0)
++				return TIMEOUT;
++		}
++#if 0
++		printk("received second nybble: %02X -> %02X\n",
++		       c0, (c0 << 1) & 0xF0);
++#endif
++		*data_p |= (c0 << 1) & 0xf0;
++		z_writeb(0x00, PAR_DATA(dev)); /* send ACK */
++		*ns_p = PLIP_NB_BEGIN;
++	case PLIP_NB_2:
++		break;
++	}
++	return OK;
++}
++
++/* PLIP_RECEIVE_PACKET --- receive a packet */
++static int
++plip_receive_packet(struct device *dev, struct net_local *nl,
++		    struct plip_local *snd, struct plip_local *rcv)
++{
++	unsigned short nibble_timeout = nl->nibble;
++	unsigned char *lbuf;
++	unsigned long flags;
++
++	switch (rcv->state) {
++	case PLIP_PK_TRIGGER:
++		enable_par_irq(dev, 0);
++		dev->interrupt = 0;
++		z_writeb(0x01, PAR_DATA(dev)); /* send ACK */
++		if (net_debug > 2)
++			printk(KERN_DEBUG "%s: receive start\n", dev->name);
++		rcv->state = PLIP_PK_LENGTH_LSB;
++		rcv->nibble = PLIP_NB_BEGIN;
++
++	case PLIP_PK_LENGTH_LSB:
++		if (snd->state != PLIP_PK_DONE) {
++			if (plip_receive(dev, nl->trigger,
++					 &rcv->nibble, &rcv->length.b.lsb)) {
++				/* collision, here dev->tbusy == 1 */
++				rcv->state = PLIP_PK_DONE;
++				nl->is_deferred = 1;
++				nl->connection = PLIP_CN_SEND;
++				queue_task(&nl->deferred, &tq_timer);
++				enable_par_irq(dev, 1);
++				return OK;
++			}
++		} else {
++			if (plip_receive(dev, nibble_timeout, 
++					 &rcv->nibble, &rcv->length.b.lsb))
++				return TIMEOUT;
++		}
++		rcv->state = PLIP_PK_LENGTH_MSB;
++
++	case PLIP_PK_LENGTH_MSB:
++		if (plip_receive(dev, nibble_timeout, 
++				 &rcv->nibble, &rcv->length.b.msb))
++			return TIMEOUT;
++		if (rcv->length.h > dev->mtu + dev->hard_header_len
++		    || rcv->length.h < 8) {
++			printk(KERN_INFO "%s: bogus packet size %d.\n",
++			       dev->name, rcv->length.h);
++			return ERROR;
++		}
++		/* Malloc up new buffer. */
++		rcv->skb = dev_alloc_skb(rcv->length.h);
++		if (rcv->skb == NULL) {
++			printk(KERN_INFO "%s: Memory squeeze.\n", dev->name);
++			return ERROR;
++		}
++		skb_put(rcv->skb,rcv->length.h);
++		rcv->skb->dev = dev;
++		rcv->state = PLIP_PK_DATA;
++		rcv->byte = 0;
++		rcv->checksum = 0;
++
++	case PLIP_PK_DATA:
++		lbuf = rcv->skb->data;
++		do
++			if (plip_receive(dev, nibble_timeout, 
++					 &rcv->nibble, &lbuf[rcv->byte]))
++				return TIMEOUT;
++		while (++rcv->byte < rcv->length.h);
++		do
++			rcv->checksum += lbuf[--rcv->byte];
++		while (rcv->byte);
++		rcv->state = PLIP_PK_CHECKSUM;
++
++	case PLIP_PK_CHECKSUM:
++		if (plip_receive(dev, nibble_timeout, 
++				 &rcv->nibble, &rcv->data))
++			return TIMEOUT;
++		if (rcv->data != rcv->checksum) {
++			nl->enet_stats.rx_crc_errors++;
++			if (net_debug)
++				printk(KERN_INFO "%s: checksum error\n",
++				       dev->name);
++			return ERROR;
++		}
++		rcv->state = PLIP_PK_DONE;
++
++	case PLIP_PK_DONE:
++		/* Inform the upper layer for the arrival of a packet. */
++		rcv->skb->protocol=eth_type_trans(rcv->skb, dev);
++		netif_rx(rcv->skb);
++		nl->enet_stats.rx_packets++;
++		rcv->skb = NULL;
++		if (net_debug > 2)
++			printk(KERN_DEBUG "%s: receive end\n", dev->name);
++
++		/* Close the connection. */
++		z_writeb (0x00, PAR_DATA(dev));
++
++		local_irq_save(flags);
++		if (snd->state != PLIP_PK_DONE) {
++			nl->connection = PLIP_CN_SEND;
++			local_irq_restore(flags);
++			queue_task(&nl->immediate, &tq_immediate);
++			mark_bh(IMMEDIATE_BH);
++			enable_par_irq(dev, 1);
++			return OK;
++		} else {
++			nl->connection = PLIP_CN_NONE;
++			local_irq_restore(flags);
++			enable_par_irq(dev, 1);
++			return OK;
++		}
++	}
++	return OK;
++}
++
++/* PLIP_SEND --- send a byte (two nibbles) 
++   Returns OK on success, TIMEOUT when timeout    */
++inline static int
++plip_send(struct device *dev, unsigned short nibble_timeout, 
++	  enum plip_nibble_state *ns_p, unsigned char data)
++{
++	unsigned char c0;
++	unsigned int cx;
++
++	switch (*ns_p) {
++	case PLIP_NB_BEGIN:
++		z_writeb((data & 0x0f), PAR_DATA(dev));
++		*ns_p = PLIP_NB_1;
++
++	case PLIP_NB_1:
++		z_writeb(0x10 | (data & 0x0f), PAR_DATA(dev));
++		cx = nibble_timeout;
++		while (1) {
++			c0 = z_readb(PAR_STATUS(dev));
++			if ((c0 & 0x80) == 0) 
++				break;
++			if (--cx == 0)
++				return TIMEOUT;
++			udelay(PLIP_DELAY_UNIT);
++		}
++		z_writeb(0x10 | (data >> 4), PAR_DATA(dev));
++		*ns_p = PLIP_NB_2;
++
++	case PLIP_NB_2:
++		z_writeb((data >> 4), PAR_DATA(dev));
++		cx = nibble_timeout;
++		while (1) {
++			c0 = z_readb(PAR_STATUS(dev));
++			if (c0 & 0x80)
++				break;
++			if (--cx == 0)
++				return TIMEOUT;
++			udelay(PLIP_DELAY_UNIT);
++		}
++		*ns_p = PLIP_NB_BEGIN;
++		return OK;
++	}
++	return OK;
++}
++
++/* PLIP_SEND_PACKET --- send a packet */
++static int
++plip_send_packet(struct device *dev, struct net_local *nl,
++		 struct plip_local *snd, struct plip_local *rcv)
++{
++	unsigned short nibble_timeout = nl->nibble;
++	unsigned char *lbuf;
++	unsigned char c0;
++	unsigned int cx;
++	unsigned long flags;
++
++	if (snd->skb == NULL || (lbuf = snd->skb->data) == NULL) {
++		printk(KERN_INFO "%s: send skb lost\n", dev->name);
++		snd->state = PLIP_PK_DONE;
++		snd->skb = NULL;
++		return ERROR;
++	}
++
++	if (snd->length.h == 0) {
++		return OK;
++	}
++
++	switch (snd->state) {
++	case PLIP_PK_TRIGGER:
++		if ((z_readb(PAR_STATUS(dev)) & 0xf8) != 0x80)
++			return TIMEOUT;
++
++		/* Trigger remote rx interrupt. */
++		z_writeb(0x08, PAR_DATA(dev));
++		cx = nl->trigger;
++		while (1) {
++			udelay(PLIP_DELAY_UNIT);
++                        local_irq_save(flags);
++			if (nl->connection == PLIP_CN_RECEIVE) {
++				local_irq_restore(flags);
++				/* interrupted */
++				nl->enet_stats.collisions++;
++				if (net_debug > 1)
++					printk(KERN_INFO "%s: collision.\n",
++					       dev->name);
++				return OK;
++			}
++			c0 = z_readb(PAR_STATUS(dev));
++			if (c0 & 0x08) {
++				enable_par_irq(dev, 0);
++				if (net_debug > 2)
++					printk(KERN_DEBUG "%s: send start\n",
++					       dev->name);
++				snd->state = PLIP_PK_LENGTH_LSB;
++				snd->nibble = PLIP_NB_BEGIN;
++				nl->timeout_count = 0;
++				local_irq_restore(flags);
++				break;
++			}
++			local_irq_restore(flags);
++			if (--cx == 0) {
++				z_writeb(0x00, PAR_DATA(dev));
++				return TIMEOUT;
++			}
++		}
++
++	case PLIP_PK_LENGTH_LSB:
++		if (plip_send(dev, nibble_timeout, 
++			      &snd->nibble, snd->length.b.lsb))
++			return TIMEOUT;
++		snd->state = PLIP_PK_LENGTH_MSB;
++
++	case PLIP_PK_LENGTH_MSB:
++		if (plip_send(dev, nibble_timeout, 
++			      &snd->nibble, snd->length.b.msb))
++			return TIMEOUT;
++		snd->state = PLIP_PK_DATA;
++		snd->byte = 0;
++		snd->checksum = 0;
++
++	case PLIP_PK_DATA:
++		do
++			if (plip_send(dev, nibble_timeout, 
++				      &snd->nibble, lbuf[snd->byte]))
++				return TIMEOUT;
++		while (++snd->byte < snd->length.h);
++		do
++			snd->checksum += lbuf[--snd->byte];
++		while (snd->byte);
++		snd->state = PLIP_PK_CHECKSUM;
++
++	case PLIP_PK_CHECKSUM:
++		if (plip_send(dev, nibble_timeout, 
++			      &snd->nibble, snd->checksum))
++			return TIMEOUT;
++
++		dev_kfree_skb(snd->skb);
++		nl->enet_stats.tx_packets++;
++		snd->state = PLIP_PK_DONE;
++
++	case PLIP_PK_DONE:
++		/* Close the connection */
++		z_writeb (0x00, PAR_DATA(dev));
++		snd->skb = NULL;
++		if (net_debug > 2)
++			printk(KERN_DEBUG "%s: send end\n", dev->name);
++		nl->connection = PLIP_CN_CLOSING;
++		nl->is_deferred = 1;
++		queue_task(&nl->deferred, &tq_timer);
++		enable_par_irq(dev, 1);
++		return OK;
++	}
++	return OK;
++}
++
++static int
++plip_connection_close(struct device *dev, struct net_local *nl,
++		      struct plip_local *snd, struct plip_local *rcv)
++{
++	unsigned long flags;
++
++        local_irq_save(flags);
++	if (nl->connection == PLIP_CN_CLOSING) {
++		nl->connection = PLIP_CN_NONE;
++		dev->tbusy = 0;
++		mark_bh(NET_BH);
++	}
++	local_irq_restore(flags);
++	return OK;
++}
++
++/* PLIP_ERROR --- wait till other end settled */
++static int
++plip_error(struct device *dev, struct net_local *nl,
++	   struct plip_local *snd, struct plip_local *rcv)
++{
++	unsigned char status;
++
++	status = z_readb(PAR_STATUS(dev));
++	if ((status & 0xf8) == 0x80) {
++		if (net_debug > 2)
++			printk(KERN_DEBUG "%s: reset interface.\n", dev->name);
++		nl->connection = PLIP_CN_NONE;
++		dev->tbusy = 0;
++		dev->interrupt = 0;
++		enable_par_irq(dev, 1);
++		mark_bh(NET_BH);
++	} else {
++		nl->is_deferred = 1;
++		queue_task(&nl->deferred, &tq_timer);
++	}
++
++	return OK;
++}
++
++/* We don't need to send arp, for plip is point-to-point. */
++static int
++plip_rebuild_header(struct sk_buff *skb)
++{
++	struct device *dev = skb->dev;
++	struct net_local *nl = (struct net_local *)dev->priv;
++	struct ethhdr *eth = (struct ethhdr *)skb->data;
++	int i;
++
++	if ((dev->flags & IFF_NOARP)==0)
++		return nl->orig_rebuild_header(skb);
++
++	if (eth->h_proto != __constant_htons(ETH_P_IP)
++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
++	    && eth->h_proto != __constant_htons(ETH_P_IPV6)
++#endif
++		) {
++		printk(KERN_ERR "plip_rebuild_header: Don't know how to resolve type %d addresses?\n", (int)eth->h_proto);
++		memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
++		return 0;
++	}
++
++	for (i=0; i < ETH_ALEN - sizeof(u32); i++)
++		eth->h_dest[i] = 0xfc;
++#if 0
++	*(u32 *)(eth->h_dest+i) = dst;
++#else
++	/* Do not want to include net/route.h here.
++	 * In any case, it is TOP of silliness to emulate
++	 * hardware addresses on PtP link. --ANK
++	 */
++	*(u32 *)(eth->h_dest+i) = 0;
++#endif
++	return 0;
++}
++
++static int
++plip_tx_packet(struct sk_buff *skb, struct device *dev)
++{
++	struct net_local *nl = (struct net_local *)dev->priv;
++	struct plip_local *snd = &nl->snd_data;
++	unsigned long flags;
++
++	if (dev->tbusy)
++		return 1;
++
++	if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
++		printk(KERN_ERR "%s: Transmitter access conflict.\n",
++		       dev->name);
++		return 1;
++	}
++
++	if (skb->len > dev->mtu + dev->hard_header_len) {
++		printk(KERN_ERR "%s: packet too big, %d.\n",
++		       dev->name, (int)skb->len);
++		dev->tbusy = 0;
++		return 0;
++	}
++
++	if (net_debug > 2)
++		printk(KERN_DEBUG "%s: send request\n", dev->name);
++
++	local_irq_save(flags);
++	dev->trans_start = jiffies;
++	snd->skb = skb;
++	snd->length.h = skb->len;
++	snd->state = PLIP_PK_TRIGGER;
++	if (nl->connection == PLIP_CN_NONE) {
++		nl->connection = PLIP_CN_SEND;
++		nl->timeout_count = 0;
++	}
++	queue_task(&nl->immediate, &tq_immediate);
++	mark_bh(IMMEDIATE_BH);
++	local_irq_restore(flags);
++
++	return 0;
++}
++
++/* Open/initialize the board.  This is called (in the current kernel)
++   sometime after booting when the 'ifconfig' program is run.
++
++ */
++static int
++plip_open(struct device *dev)
++{
++	struct net_local *nl = (struct net_local *)dev->priv;
++	struct in_device *in_dev;
++
++#if defined(CONFIG_GVPIOEXT_LP) || defined(CONFIG_GVPIOEXT_LP_MODULE)
++	/* Yes, there is a race condition here. Fix it later */
++	if (PLIP_DEV(dev)->par_use & IOEXT_PAR_LP) {
++		/* Can't open if lp is in use */
++#if DEBUG
++		printk("par is in use by lp\n");
++#endif
++		return(-EBUSY);
++	}
++#endif
++	PLIP_DEV(dev)->par_use |= IOEXT_PAR_PLIP;
++
++#if DEBUG
++	printk("plip_open(): sending 00 to data port\n");
++#endif
++
++	/* Clear the data port. */
++	z_writeb (0x00, PAR_DATA(dev));
++
++#if DEBUG
++	printk("plip_open(): sent\n");
++#endif
++
++	/* Initialize the state machine. */
++	nl->rcv_data.state = nl->snd_data.state = PLIP_PK_DONE;
++	nl->rcv_data.skb = nl->snd_data.skb = NULL;
++	nl->connection = PLIP_CN_NONE;
++	nl->is_deferred = 0;
++
++	/* Fill in the MAC-level header.
++	   (ab)Use "dev->broadcast" to store point-to-point MAC address.
++
++	   PLIP doesn't have a real mac address, but we need to create one
++	   to be DOS compatible.  */
++	memset(dev->dev_addr,  0xfc, ETH_ALEN);
++	memset(dev->broadcast, 0xfc, ETH_ALEN);
++
++	if ((in_dev=dev->ip_ptr) != NULL) {
++		/*
++		 *	Any address will do - we take the first
++		 */
++		struct in_ifaddr *ifa=in_dev->ifa_list;
++		if (ifa != NULL) {
++			memcpy(dev->dev_addr+2, &ifa->ifa_local, 4);
++			memcpy(dev->broadcast+2, &ifa->ifa_address, 4);
++		}
++	}
++
++	dev->interrupt = 0;
++	dev->start = 1;
++	dev->tbusy = 0;
++
++	MOD_INC_USE_COUNT;
++
++	/* Enable rx interrupt. */
++	enable_par_irq(dev, 1);
++
++	return 0;
++}
++
++/* The inverse routine to plip_open (). */
++static int
++plip_close(struct device *dev)
++{
++	struct net_local *nl = (struct net_local *)dev->priv;
++	struct plip_local *snd = &nl->snd_data;
++	struct plip_local *rcv = &nl->rcv_data;
++	unsigned long flags;
++
++	dev->tbusy = 1;
++	dev->start = 0;
++        local_irq_save(flags);
++	nl->is_deferred = 0;
++	nl->connection = PLIP_CN_NONE;
++	local_irq_restore(flags);
++	z_writeb(0x00, PAR_DATA(dev));
++
++	snd->state = PLIP_PK_DONE;
++	if (snd->skb) {
++		dev_kfree_skb(snd->skb);
++		snd->skb = NULL;
++	}
++	rcv->state = PLIP_PK_DONE;
++	if (rcv->skb) {
++		kfree_skb(rcv->skb);
++		rcv->skb = NULL;
++	}
++
++	PLIP_DEV(dev)->par_use &= ~IOEXT_PAR_PLIP;
++
++	MOD_DEC_USE_COUNT;
++	return 0;
++}
++
++static struct enet_statistics *
++plip_get_stats(struct device *dev)
++{
++	struct net_local *nl = (struct net_local *)dev->priv;
++	struct enet_statistics *r = &nl->enet_stats;
++
++	return r;
++}
++
++static int
++plip_config(struct device *dev, struct ifmap *map)
++{
++	if (dev->flags & IFF_UP)
++		return -EBUSY;
++
++	printk(KERN_INFO "%s: This interface is autodetected (ignored).\n",
++	       dev->name);
++
++	return 0;
++}
++
++static int
++plip_ioctl(struct device *dev, struct ifreq *rq, int cmd)
++{
++	struct net_local *nl = (struct net_local *) dev->priv;
++	struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
++  
++	switch(pc->pcmd) {
++	case PLIP_GET_TIMEOUT:
++		pc->trigger = nl->trigger;
++		pc->nibble  = nl->nibble;
++		break;
++	case PLIP_SET_TIMEOUT:
++		nl->trigger = pc->trigger;
++		nl->nibble  = pc->nibble;
++		break;
++	default:
++		return -EOPNOTSUPP;
++	}
++	return 0;
++}
++
++/*
++ * Detect and initialize all IO-Extenders in this system.
++ *
++ * Both PLIP and serial devices are configured.
++ */
++int plip_init(struct device *dev)
++{
++	IOEXT_struct *board;
++	struct net_local *nl;
++
++	if (ioext_num == 0) {
++		printk(KERN_INFO "%s\n", version);
++	}
++
++	board = PLIP_DEV(dev)->board;
++	dev->base_addr = (unsigned long)&board->par.DATA;
++
++	/* Cheat and use irq to index into our table */
++	dev->irq = ioext_num;
++
++	printk(KERN_INFO "%s: IO-Extender parallel port at 0x%08lX\n", dev->name, dev->base_addr);
++
++	/* Fill in the generic fields of the device structure. */
++	ether_setup(dev);
++
++	/* Then, override parts of it */
++	dev->hard_start_xmit  = plip_tx_packet;
++	dev->open    = plip_open;
++	dev->stop    = plip_close;
++	dev->get_stats     = plip_get_stats;
++	dev->set_config    = plip_config;
++	dev->do_ioctl    = plip_ioctl;
++	dev->tx_queue_len  = 10;
++	dev->flags          = IFF_POINTOPOINT|IFF_NOARP;
++
++	/* Set the private structure */
++	dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL);
++	if (dev->priv == NULL) {
++		printk(KERN_ERR "%s: out of memory\n", dev->name);
++		return -ENOMEM;
++	}
++	memset(dev->priv, 0, sizeof(struct net_local));
++	nl = (struct net_local *) dev->priv;
++
++	nl->orig_rebuild_header = dev->rebuild_header;
++	dev->rebuild_header   = plip_rebuild_header;
++
++	/* Initialize constants */
++	nl->trigger  = PLIP_TRIGGER_WAIT;
++	nl->nibble  = PLIP_NIBBLE_WAIT;
++
++	/* Initialize task queue structures */
++	nl->immediate.next = NULL;
++	nl->immediate.sync = 0;
++	nl->immediate.routine = (void *)(void *)plip_bh;
++	nl->immediate.data = dev;
++
++	nl->deferred.next = NULL;
++	nl->deferred.sync = 0;
++	nl->deferred.routine = (void *)(void *)plip_kick_bh;
++	nl->deferred.data = dev;
++
++	/* Don't enable interrupts yet */
++
++	return 0;
++}
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/char/serial167.c linux-m68k/drivers/char/serial167.c
+--- linux-i386/drivers/char/serial167.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/char/serial167.c	2005-10-12 16:32:10.000000000 +0200
+@@ -1450,7 +1450,6 @@
+   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
+   unsigned long flags;
+   unsigned char status;
+-  unsigned int result;
+ 
+     channel = info->line;
+ 
+@@ -1474,7 +1473,6 @@
+   int channel;
+   volatile unsigned char *base_addr = (u_char *)BASE_ADDR;
+   unsigned long flags;
+-  unsigned int arg;
+ 	  
+     channel = info->line;
+ 
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/ide/ide-iops.c linux-m68k/drivers/ide/ide-iops.c
+--- linux-i386/drivers/ide/ide-iops.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/ide/ide-iops.c	2005-10-29 10:42:13.000000000 +0200
+@@ -341,6 +341,23 @@
+ 	int i;
+ 	u16 *stringcast;
+ 
++#ifdef __mc68000__
++	if (!MACH_IS_AMIGA && !MACH_IS_MAC && !MACH_IS_Q40 && !MACH_IS_ATARI)
++		return;
++
++#ifdef M68K_IDE_SWAPW
++	if (M68K_IDE_SWAPW) {	/* fix bus byteorder first */
++		u_char *p = (u_char *)id;
++		u_char t;
++		for (i = 0; i < 512; i += 2) {
++			t = p[i];
++			p[i] = p[i+1];
++			p[i+1] = t;
++		}
++	}
++#endif
++#endif /* __mc68000__ */
++
+ 	id->config         = __le16_to_cpu(id->config);
+ 	id->cyls           = __le16_to_cpu(id->cyls);
+ 	id->reserved2      = __le16_to_cpu(id->reserved2);
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/ide/legacy/gayle.c linux-m68k/drivers/ide/legacy/gayle.c
+--- linux-i386/drivers/ide/legacy/gayle.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/ide/legacy/gayle.c	2005-09-02 16:32:11.000000000 +0200
+@@ -161,6 +161,7 @@
+ 	base = (unsigned long)ZTWO_VADDR(phys_base);
+ 	ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0;
+ 
++	memset(&hw, 0, sizeof(hw));
+ 	ide_setup_ports(&hw, base, gayle_offsets,
+ 			ctrlport, irqport, ack_intr,
+ //			&gayle_iops,
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/keyboard/Kconfig linux-m68k/drivers/input/keyboard/Kconfig
+--- linux-i386/drivers/input/keyboard/Kconfig	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/input/keyboard/Kconfig	2005-10-29 10:42:17.000000000 +0200
+@@ -165,7 +165,7 @@
+ 
+ config KEYBOARD_HIL_OLD
+ 	tristate "HP HIL keyboard support (simple driver)"
+-	depends on GSC
++	depends on GSC || HP300
+ 	default y
+ 	help
+ 	  The "Human Interface Loop" is a older, 8-channel USB-like
+@@ -182,7 +182,7 @@
+ 
+ config KEYBOARD_HIL
+ 	tristate "HP HIL keyboard support"
+-	depends on GSC
++	depends on GSC || HP300
+ 	default y
+ 	select HP_SDC
+ 	select HIL_MLC
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/misc/Kconfig linux-m68k/drivers/input/misc/Kconfig
+--- linux-i386/drivers/input/misc/Kconfig	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/input/misc/Kconfig	2005-08-30 16:33:05.000000000 +0200
+@@ -51,7 +51,7 @@
+ 
+ config HP_SDC_RTC
+ 	tristate "HP SDC Real Time Clock"       
+-	depends on GSC
++	depends on GSC || HP300
+ 	select HP_SDC
+ 	help
+ 	  Say Y here if you want to support the built-in real time clock
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/mouse/Kconfig linux-m68k/drivers/input/mouse/Kconfig
+--- linux-i386/drivers/input/mouse/Kconfig	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/input/mouse/Kconfig	2005-08-30 16:33:05.000000000 +0200
+@@ -129,7 +129,7 @@
+ 
+ config MOUSE_HIL
+ 	tristate "HIL pointers (mice etc)."     
+-	depends on GSC
++	depends on GSC || HP300
+ 	select HP_SDC
+ 	select HIL_MLC
+ 	help
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/input/serio/Kconfig linux-m68k/drivers/input/serio/Kconfig
+--- linux-i386/drivers/input/serio/Kconfig	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/input/serio/Kconfig	2005-08-30 16:33:05.000000000 +0200
+@@ -112,7 +112,7 @@
+ 
+ config HP_SDC
+ 	tristate "HP System Device Controller i8042 Support"
+-	depends on GSC && SERIO
++	depends on (GSC || HP300) && SERIO
+ 	default y
+ 	---help---
+ 	  This option enables supports for the the "System Device
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/macintosh/adb.c linux-m68k/drivers/macintosh/adb.c
+--- linux-i386/drivers/macintosh/adb.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/macintosh/adb.c	2005-08-30 16:33:07.000000000 +0200
+@@ -476,13 +476,15 @@
+ 		use_sreq = 1;
+ 	} else
+ 		use_sreq = 0;
+-	req->nbytes = nbytes+1;
++	i = (flags & ADBREQ_RAW) ? 0 : 1;
++	req->nbytes = nbytes+i;
+ 	req->done = done;
+ 	req->reply_expected = flags & ADBREQ_REPLY;
+ 	req->data[0] = ADB_PACKET;
+ 	va_start(list, nbytes);
+-	for (i = 0; i < nbytes; ++i)
+-		req->data[i+1] = va_arg(list, int);
++	while (i < req->nbytes) {
++		req->data[i++] = va_arg(list, int);
++	}
+ 	va_end(list);
+ 
+ 	if (flags & ADBREQ_NOSEND)
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/7990.c linux-m68k/drivers/net/7990.c
+--- linux-i386/drivers/net/7990.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/net/7990.c	2005-10-12 16:32:42.000000000 +0200
+@@ -500,7 +500,7 @@
+ 	int res;
+         
+         /* Install the Interrupt handler. Or we could shunt this out to specific drivers? */
+-        if (request_irq(lp->irq, lance_interrupt, 0, lp->name, dev))
++        if (request_irq(lp->irq, lance_interrupt, SA_SHIRQ, lp->name, dev))
+                 return -EAGAIN;
+ 
+         res = lance_reset(dev);
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/Kconfig linux-m68k/drivers/net/Kconfig
+--- linux-i386/drivers/net/Kconfig	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/net/Kconfig	2005-10-29 10:42:30.000000000 +0200
+@@ -296,7 +296,7 @@
+ 
+ config MAC89x0
+ 	tristate "Macintosh CS89x0 based ethernet cards"
+-	depends on NET_ETHERNET && MAC && BROKEN
++	depends on NET_ETHERNET && MAC
+ 	---help---
+ 	  Support for CS89x0 chipset based Ethernet cards.  If you have a
+ 	  Nubus or LC-PDS network (Ethernet) card of this type, say Y and
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/hplance.c linux-m68k/drivers/net/hplance.c
+--- linux-i386/drivers/net/hplance.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/net/hplance.c	2005-10-12 16:32:43.000000000 +0200
+@@ -77,6 +77,7 @@
+ {
+ 	struct net_device *dev;
+ 	int err = -ENOMEM;
++	int i;
+ 
+ 	dev = alloc_etherdev(sizeof(struct hplance_private));
+ 	if (!dev)
+@@ -93,6 +94,15 @@
+ 		goto out_release_mem_region;
+ 
+ 	dio_set_drvdata(d, dev);
++
++	printk(KERN_INFO "%s: %s; select code %d, addr %2.2x", dev->name, d->name, d->scode, dev->dev_addr[0]);
++
++	for (i=1; i<6; i++) {
++		printk(":%2.2x", dev->dev_addr[i]);
++	}
++
++	printk(", irq %d\n", d->ipl);
++
+ 	return 0;
+ 
+  out_release_mem_region:
+@@ -118,9 +128,7 @@
+         unsigned long va = (d->resource.start + DIO_VIRADDRBASE);
+         struct hplance_private *lp;
+         int i;
+-        
+-        printk(KERN_INFO "%s: %s; select code %d, addr", dev->name, d->name, d->scode);
+-
++ 
+         /* reset the board */
+         out_8(va+DIO_IDOFF, 0xff);
+         udelay(100);                              /* ariba! ariba! udelay! udelay! */
+@@ -143,7 +151,6 @@
+                  */
+                 dev->dev_addr[i] = ((in_8(va + HPLANCE_NVRAMOFF + i*4 + 1) & 0xF) << 4)
+                         | (in_8(va + HPLANCE_NVRAMOFF + i*4 + 3) & 0xF);
+-                printk("%c%2.2x", i == 0 ? ' ' : ':', dev->dev_addr[i]);
+         }
+         
+         lp = netdev_priv(dev);
+@@ -160,7 +167,6 @@
+         lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
+         lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK;
+         lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
+-	printk(", irq %d\n", lp->lance.irq);
+ }
+ 
+ /* This is disgusting. We have to check the DIO status register for ack every
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/net/mac89x0.c linux-m68k/drivers/net/mac89x0.c
+--- linux-i386/drivers/net/mac89x0.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/net/mac89x0.c	2004-12-30 16:38:24.000000000 +0100
+@@ -128,7 +128,7 @@
+ extern void reset_chip(struct net_device *dev);
+ #endif
+ static int net_open(struct net_device *dev);
+-static int	net_send_packet(struct sk_buff *skb, struct net_device *dev);
++static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
+ static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+ static void set_multicast_list(struct net_device *dev);
+ static void net_rx(struct net_device *dev);
+@@ -374,56 +374,37 @@
+ static int
+ net_send_packet(struct sk_buff *skb, struct net_device *dev)
+ {
+-	if (dev->tbusy) {
+-		/* If we get here, some higher level has decided we are broken.
+-		   There should really be a "kick me" function call instead. */
+-		int tickssofar = jiffies - dev->trans_start;
+-		if (tickssofar < 5)
+-			return 1;
+-		if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name,
+-			   tx_done(dev) ? "IRQ conflict" : "network cable problem");
+-		/* Try to restart the adaptor. */
+-		dev->tbusy=0;
+-		dev->trans_start = jiffies;
+-	}
+-
+-	/* Block a timer-based transmit from overlapping.  This could better be
+-	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
+-	if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
+-		printk("%s: Transmitter access conflict.\n", dev->name);
+-	else {
+-		struct net_local *lp = netdev_priv(dev);
+-		unsigned long flags;
+-
+-		if (net_debug > 3)
+-			printk("%s: sent %d byte packet of type %x\n",
+-			       dev->name, skb->len,
+-			       (skb->data[ETH_ALEN+ETH_ALEN] << 8)
+-			       | skb->data[ETH_ALEN+ETH_ALEN+1]);
+-
+-		/* keep the upload from being interrupted, since we
+-                   ask the chip to start transmitting before the
+-                   whole packet has been completely uploaded. */
+-		local_irq_save(flags);
+-
+-		/* initiate a transmit sequence */
+-		writereg(dev, PP_TxCMD, lp->send_cmd);
+-		writereg(dev, PP_TxLength, skb->len);
+-
+-		/* Test to see if the chip has allocated memory for the packet */
+-		if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
+-			/* Gasp!  It hasn't.  But that shouldn't happen since
+-			   we're waiting for TxOk, so return 1 and requeue this packet. */
+-			local_irq_restore(flags);
+-			return 1;
+-		}
++	struct net_local *lp = netdev_priv(dev);
++	unsigned long flags;
+ 
+-		/* Write the contents of the packet */
+-		memcpy_toio(dev->mem_start + PP_TxFrame, skb->data, skb->len+1);
++	if (net_debug > 3)
++		printk("%s: sent %d byte packet of type %x\n",
++		       dev->name, skb->len,
++		       (skb->data[ETH_ALEN+ETH_ALEN] << 8)
++		       | skb->data[ETH_ALEN+ETH_ALEN+1]);
++
++	/* keep the upload from being interrupted, since we
++	   ask the chip to start transmitting before the
++	   whole packet has been completely uploaded. */
++	local_irq_save(flags);
+ 
++	/* initiate a transmit sequence */
++	writereg(dev, PP_TxCMD, lp->send_cmd);
++	writereg(dev, PP_TxLength, skb->len);
++
++	/* Test to see if the chip has allocated memory for the packet */
++	if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
++		/* Gasp!  It hasn't.  But that shouldn't happen since
++		   we're waiting for TxOk, so return 1 and requeue this packet. */
+ 		local_irq_restore(flags);
+-		dev->trans_start = jiffies;
++		return 1;
+ 	}
++
++	/* Write the contents of the packet */
++	memcpy((void *)(dev->mem_start + PP_TxFrame), skb->data, skb->len+1);
++
++	local_irq_restore(flags);
++	dev->trans_start = jiffies;
+ 	dev_kfree_skb (skb);
+ 
+ 	return 0;
+@@ -441,9 +422,6 @@
+ 		printk ("net_interrupt(): irq %d for unknown device.\n", irq);
+ 		return IRQ_NONE;
+ 	}
+-	if (dev->interrupt)
+-		printk("%s: Re-entering the interrupt handler.\n", dev->name);
+-	dev->interrupt = 1;
+ 
+ 	ioaddr = dev->base_addr;
+ 	lp = netdev_priv(dev);
+@@ -464,8 +442,7 @@
+ 			break;
+ 		case ISQ_TRANSMITTER_EVENT:
+ 			lp->stats.tx_packets++;
+-			dev->tbusy = 0;
+-			mark_bh(NET_BH);	/* Inform upper layers. */
++			netif_wake_queue(dev);
+ 			if ((status & TX_OK) == 0) lp->stats.tx_errors++;
+ 			if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++;
+ 			if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++;
+@@ -479,8 +456,7 @@
+                                    That shouldn't happen since we only ever
+                                    load one packet.  Shrug.  Do the right
+                                    thing anyway. */
+-				dev->tbusy = 0;
+-				mark_bh(NET_BH);	/* Inform upper layers. */
++				netif_wake_queue(dev);
+ 			}
+ 			if (status & TX_UNDERRUN) {
+ 				if (net_debug > 0) printk("%s: transmit underrun\n", dev->name);
+@@ -497,7 +473,6 @@
+ 			break;
+ 		}
+ 	}
+-	dev->interrupt = 0;
+ 	return IRQ_HANDLED;
+ }
+ 
+@@ -532,7 +507,7 @@
+ 	skb_put(skb, length);
+ 	skb->dev = dev;
+ 
+-	memcpy_fromio(skb->data, dev->mem_start + PP_RxFrame, length);
++	memcpy(skb->data, (void *)(dev->mem_start + PP_RxFrame), length);
+ 
+ 	if (net_debug > 3)printk("%s: received %d byte packet of type %x\n",
+                                  dev->name, length,
+@@ -611,8 +586,6 @@
+ static int set_mac_address(struct net_device *dev, void *addr)
+ {
+ 	int i;
+-	if (dev->start)
+-		return -EBUSY;
+ 	printk("%s: Setting MAC address to ", dev->name);
+ 	for (i = 0; i < 6; i++)
+ 		printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]);
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/53c7xx.c linux-m68k/drivers/scsi/53c7xx.c
+--- linux-i386/drivers/scsi/53c7xx.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/scsi/53c7xx.c	2005-10-29 10:42:44.000000000 +0200
+@@ -307,7 +307,7 @@
+ 
+ static int check_address (unsigned long addr, int size);
+ static void dump_events (struct Scsi_Host *host, int count);
+-static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host, 
++static struct scsi_cmnd * return_outstanding_commands (struct Scsi_Host *host, 
+     int free, int issue);
+ static void hard_reset (struct Scsi_Host *host);
+ static void ncr_scsi_reset (struct Scsi_Host *host);
+@@ -316,7 +316,7 @@
+     int scntl3, int now_connected);
+ static int datapath_residual (struct Scsi_Host *host);
+ static const char * sbcl_to_phase (int sbcl);
+-static void print_progress (Scsi_Cmnd *cmd);
++static void print_progress (struct scsi_cmnd *cmd);
+ static void print_queues (struct Scsi_Host *host);
+ static void process_issue_queue (unsigned long flags);
+ static int shutdown (struct Scsi_Host *host);
+@@ -341,9 +341,8 @@
+ static void NCR53c7x0_soft_reset (struct Scsi_Host *host);
+ 
+ /* Size of event list (per host adapter) */
+-static int track_events = 0;
+-static struct Scsi_Host *first_host = NULL;	/* Head of list of NCR boards */
+-static Scsi_Host_Template *the_template = NULL;	
++static int track_events;
++static Scsi_Host_Template *the_template;
+ 
+ /* NCR53c710 script handling code */
+ 
+@@ -666,8 +665,11 @@
+ 
+ static struct Scsi_Host *
+ find_host (int host) {
+-    struct Scsi_Host *h;
+-    for (h = first_host; h && h->host_no != host; h = h->next);
++    struct Scsi_Host *h, *s;
++    list_for_each_entry_safe(h, s, &the_template->legacy_hosts, sht_legacy_list) {
++	if (h->host_no == host)
++	    break;
++    }
+     if (!h) {
+ 	printk (KERN_ALERT "scsi%d not found\n", host);
+ 	return NULL;
+@@ -715,14 +717,14 @@
+     }
+     hostdata = (struct NCR53c7x0_hostdata *)h->hostdata[0];
+ 
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+     if (hostdata->initiate_sdtr & (1 << target)) {
+-	local_irq_restore(flags);
++	spin_unlock_irqrestore(host->host_lock, flags);
+ 	printk (KERN_ALERT "target %d already doing SDTR\n", target);
+ 	return -1;
+     } 
+     hostdata->initiate_sdtr |= (1 << target);
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+     return 0;
+ }
+ #endif
+@@ -1033,9 +1035,6 @@
+    
+     ccf = clock_to_ccf_710 (expected_clock);
+ 
+-    for (i = 0; i < 16; ++i) 
+-	hostdata->cmd_allocated[i] = 0;
+-
+     if (hostdata->init_save_regs)
+     	hostdata->init_save_regs (host);
+     if (hostdata->init_fixup)
+@@ -1043,7 +1042,6 @@
+ 
+     if (!the_template) {
+ 	the_template = host->hostt;
+-	first_host = host;
+     }
+ 
+     /* 
+@@ -1306,7 +1304,6 @@
+     hostdata->free->size = max_cmd_size;
+     hostdata->free->free = NULL;
+     hostdata->free->next = NULL;
+-    hostdata->extra_allocate = 0;
+ 
+     /* Allocate command start code space */
+     hostdata->schedule = (chip == 700 || chip == 70066) ?
+@@ -1589,10 +1586,10 @@
+ 
+     /* The NCR chip _must_ be idle to run the test scripts */
+ 
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+     if (!hostdata->idle) {
+ 	printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
+-	local_irq_restore(flags);
++	spin_unlock_irqrestore(host->host_lock, flags);
+ 	return -1;
+     }
+ 
+@@ -1616,7 +1613,7 @@
+ 	    NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl | DCNTL_SSM |
+ 						DCNTL_STD);
+ 	printk (" started\n");
+-	local_irq_restore(flags);
++	spin_unlock_irqrestore(host->host_lock, flags);
+ 
+ 	/* 
+ 	 * This is currently a .5 second timeout, since (in theory) no slow 
+@@ -1655,7 +1652,7 @@
+ 		hostdata->script, start);
+ 	    printk ("scsi%d : DSPS = 0x%x\n", host->host_no,
+ 		NCR53c7x0_read32(DSPS_REG));
+-	    local_irq_restore(flags);
++	    spin_unlock_irqrestore(host->host_lock, flags);
+ 	    return -1;
+ 	}
+     	hostdata->test_running = 0;
+@@ -1693,7 +1690,7 @@
+ 	    local_irq_disable();
+ 	    if (!hostdata->idle) {
+ 		printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
+-		local_irq_restore(flags);
++		spin_unlock_irqrestore(host->host_lock, flags);
+ 		return -1;
+ 	    }
+ 
+@@ -1709,7 +1706,7 @@
+ 	    if (hostdata->options & OPTION_DEBUG_TRACE)
+ 	        NCR53c7x0_write8 (DCNTL_REG, hostdata->saved_dcntl |
+ 				DCNTL_SSM | DCNTL_STD);
+-	    local_irq_restore(flags);
++	    spin_unlock_irqrestore(host->host_lock, flags);
+ 
+ 	    timeout = jiffies + 5 * HZ;	/* arbitrary */
+ 	    while ((hostdata->test_completed == -1) && time_before(jiffies, timeout))
+@@ -1731,19 +1728,19 @@
+ 		    host->host_no, i);
+ 		if (!hostdata->idle) {
+ 		    printk("scsi%d : not idle\n", host->host_no);
+-		    local_irq_restore(flags);
++		    spin_unlock_irqrestore(host->host_lock, flags);
+ 		    return -1;
+ 		}
+ 	    } else if (hostdata->test_completed == -1) {
+ 		printk ("scsi%d : test 2 timed out\n", host->host_no);
+-		local_irq_restore(flags);
++		spin_unlock_irqrestore(host->host_lock, flags);
+ 		return -1;
+ 	    } 
+ 	    hostdata->test_running = 0;
+ 	}
+     }
+ 
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+     return 0;
+ }
+ 
+@@ -1759,7 +1756,7 @@
+ 
+ static void 
+ NCR53c7xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
+-    Scsi_Cmnd *c = cmd->cmd;
++    struct scsi_cmnd *c = cmd->cmd;
+     struct Scsi_Host *host = c->device->host;
+     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+     	host->hostdata[0];
+@@ -1845,7 +1842,7 @@
+  *
+  * Purpose : mark SCSI command as finished, OR'ing the host portion 
+  *	of the result word into the result field of the corresponding
+- *	Scsi_Cmnd structure, and removing it from the internal queues.
++ *	scsi_cmnd structure, and removing it from the internal queues.
+  *
+  * Inputs : cmd - command, result - entire result field
+  *
+@@ -1856,7 +1853,7 @@
+ 
+ static void 
+ abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
+-    Scsi_Cmnd *c = cmd->cmd;
++    struct scsi_cmnd *c = cmd->cmd;
+     struct Scsi_Host *host = c->device->host;
+     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+     	host->hostdata[0];
+@@ -1870,7 +1867,7 @@
+     printk ("scsi%d: abnormal finished\n", host->host_no);
+ #endif
+ 
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+     found = 0;
+     /* 
+      * Traverse the NCR issue array until we find a match or run out 
+@@ -1953,7 +1950,7 @@
+     c->result = result;
+     c->scsi_done(c);
+ 
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+     run_process_issue_queue();
+ }
+ 
+@@ -1975,7 +1972,7 @@
+     NCR53c7x0_local_declare();
+     struct NCR53c7x0_break *bp;
+ #if 0
+-    Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
++    struct scsi_cmnd *c = cmd ? cmd->cmd : NULL;
+ #endif
+     u32 *dsp;
+     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+@@ -1988,7 +1985,7 @@
+      * dump the appropriate debugging information to standard 
+      * output.  
+      */
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+     dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
+     for (bp = hostdata->breakpoints; bp && bp->address != dsp; 
+     	bp = bp->next);
+@@ -2010,7 +2007,7 @@
+      * instruction in bytes.
+      */
+ 
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+ }
+ /*
+  * Function : static void print_synchronous (const char *prefix, 
+@@ -2252,7 +2249,7 @@
+     NCR53c7x0_cmd *cmd) {
+     NCR53c7x0_local_declare();
+     int print;
+-    Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
++    struct scsi_cmnd *c = cmd ? cmd->cmd : NULL;
+     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+ 	host->hostdata[0];		
+     u32 dsps,*dsp;	/* Argument of the INT instruction */
+@@ -2916,7 +2913,7 @@
+ 	host->hostdata[0];
+     NCR53c7x0_local_setup(host);
+ 
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+ 
+     /* Disable scsi chip and s/w level 7 ints */
+ 
+@@ -3017,12 +3014,12 @@
+     }
+ #endif
+     /* Anything needed for your hardware? */
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+ }
+ 
+ 
+ /*
+- * Function static struct NCR53c7x0_cmd *allocate_cmd (Scsi_Cmnd *cmd)
++ * Function static struct NCR53c7x0_cmd *allocate_cmd (struct scsi_cmnd *cmd)
+  * 
+  * Purpose : Return the first free NCR53c7x0_cmd structure (which are 
+  * 	reused in a LIFO manner to minimize cache thrashing).
+@@ -3049,86 +3046,25 @@
+ }
+ 
+ static struct NCR53c7x0_cmd *
+-allocate_cmd (Scsi_Cmnd *cmd) {
++allocate_cmd (struct scsi_cmnd *cmd) {
+     struct Scsi_Host *host = cmd->device->host;
+     struct NCR53c7x0_hostdata *hostdata = 
+ 	(struct NCR53c7x0_hostdata *) host->hostdata[0];
+-    u32 real;			/* Real address */
+-    int size;			/* Size of *tmp */
+     struct NCR53c7x0_cmd *tmp;
+     unsigned long flags;
+ 
+     if (hostdata->options & OPTION_DEBUG_ALLOCATION)
+ 	printk ("scsi%d : num_cmds = %d, can_queue = %d\n"
+-		"         target = %d, lun = %d, %s\n",
++		"         target = %d, lun = %d\n",
+ 	    host->host_no, hostdata->num_cmds, host->can_queue,
+-	    cmd->device->id, cmd->device->lun, (hostdata->cmd_allocated[cmd->device->id] &
+-		(1 << cmd->device->lun)) ? "already allocated" : "not allocated");
+-
+-/*
+- * If we have not yet reserved commands for this I_T_L nexus, and
+- * the device exists (as indicated by permanent Scsi_Cmnd structures
+- * being allocated under 1.3.x, or being outside of scan_scsis in
+- * 1.2.x), do so now.
+- */
+-    if (!(hostdata->cmd_allocated[cmd->device->id] & (1 << cmd->device->lun)) &&
+-				cmd->device && cmd->device->has_cmdblocks) {
+-      if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue)
+-          hostdata->extra_allocate += host->cmd_per_lun;
+-      hostdata->cmd_allocated[cmd->device->id] |= (1 << cmd->device->lun);
+-    }
+-
+-    for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate, 
+-    	++hostdata->num_cmds) {
+-    /* historically, kmalloc has returned unaligned addresses; pad so we
+-       have enough room to ROUNDUP */
+-	size = hostdata->max_cmd_size + sizeof (void *);
+-#ifdef FORCE_DSA_ALIGNMENT
+-	/*
+-	 * 53c710 rev.0 doesn't have an add-with-carry instruction.
+-	 * Ensure we allocate enough memory to force alignment.
+-	 */
+-	size += 256;
+-#endif
+-/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
++	    cmd->device->id, cmd->device->lun);
+ 
+-        if (size > 4096) {
+-            printk (KERN_ERR "53c7xx: allocate_cmd size > 4K\n");
+-	    return NULL;
+-	}
+-        real = get_zeroed_page(GFP_ATOMIC);
+-        if (real == 0)
+-        	return NULL;
+-        memset((void *)real, 0, 4096);
+-        cache_push(virt_to_phys((void *)real), 4096);
+-        cache_clear(virt_to_phys((void *)real), 4096);
+-        kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER);
+-	tmp = ROUNDUP(real, void *);
+-#ifdef FORCE_DSA_ALIGNMENT
+-	{
+-	    if (((u32)tmp & 0xff) > CmdPageStart)
+-		tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255);
+-	    tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart);
+-#if 0
+-	    printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n",
+-			size, real, (u32)tmp);
+-#endif
+-	}
+-#endif
+-	tmp->real = (void *)real;
+-	tmp->size = size;			
+-	tmp->free = ((void (*)(void *, int)) my_free_page);
+-	local_irq_save(flags);
+-	tmp->next = hostdata->free;
+-	hostdata->free = tmp;
+-	local_irq_restore(flags);
+-    }
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+     tmp = (struct NCR53c7x0_cmd *) hostdata->free;
+     if (tmp) {
+ 	hostdata->free = tmp->next;
+     }
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+     if (!tmp)
+ 	printk ("scsi%d : can't allocate command for target %d lun %d\n",
+ 	    host->host_no, cmd->device->id, cmd->device->lun);
+@@ -3136,11 +3072,11 @@
+ }
+ 
+ /*
+- * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd) 
++ * Function static struct NCR53c7x0_cmd *create_cmd (struct scsi_cmnd *cmd) 
+  *
+  *
+  * Purpose : allocate a NCR53c7x0_cmd structure, initialize it based on the 
+- * 	Scsi_Cmnd structure passed in cmd, including dsa and Linux field 
++ * 	scsi_cmnd structure passed in cmd, including dsa and Linux field 
+  * 	initialization, and dsa code relocation.
+  *
+  * Inputs : cmd - SCSI command
+@@ -3149,7 +3085,7 @@
+  *	NULL on failure.
+  */
+ static struct NCR53c7x0_cmd *
+-create_cmd (Scsi_Cmnd *cmd) {
++create_cmd (struct scsi_cmnd *cmd) {
+     NCR53c7x0_local_declare();
+     struct Scsi_Host *host = cmd->device->host;
+     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+@@ -3173,7 +3109,7 @@
+ 	return NULL;
+ 
+     /*
+-     * Copy CDB and initialised result fields from Scsi_Cmnd to NCR53c7x0_cmd.
++     * Copy CDB and initialised result fields from scsi_cmnd to NCR53c7x0_cmd.
+      * We do this because NCR53c7x0_cmd may have a special cache mode
+      * selected to cope with lack of bus snooping, etc.
+      */
+@@ -3316,7 +3252,7 @@
+ 
+     patch_dsa_32(tmp->dsa, dsa_next, 0, 0);
+     /*
+-     * XXX is this giving 53c710 access to the Scsi_Cmnd in some way?
++     * XXX is this giving 53c710 access to the scsi_cmnd in some way?
+      * Do we need to change it for caching reasons?
+      */
+     patch_dsa_32(tmp->dsa, dsa_cmnd, 0, virt_to_bus(cmd));
+@@ -3347,17 +3283,17 @@
+ 	memcpy ((void *) (tmp->select + 1), (void *) wdtr_message,
+ 	    sizeof(wdtr_message));
+     	patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(wdtr_message));
+-	local_irq_save(flags);
++	spin_lock_irqsave(host->host_lock, flags);
+ 	hostdata->initiate_wdtr &= ~(1 << cmd->device->id);
+-	local_irq_restore(flags);
++	spin_unlock_irqrestore(host->host_lock, flags);
+     } else if (hostdata->initiate_sdtr & (1 << cmd->device->id)) {
+ 	memcpy ((void *) (tmp->select + 1), (void *) sdtr_message, 
+ 	    sizeof(sdtr_message));
+     	patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(sdtr_message));
+ 	tmp->flags |= CMD_FLAG_SDTR;
+-	local_irq_save(flags);
++	spin_lock_irqsave(host->host_lock, flags);
+ 	hostdata->initiate_sdtr &= ~(1 << cmd->device->id);
+-	local_irq_restore(flags);
++	spin_unlock_irqrestore(host->host_lock, flags);
+     
+     }
+ #if 1
+@@ -3570,8 +3506,8 @@
+ }
+ 
+ /*
+- * Function : int NCR53c7xx_queue_command (Scsi_Cmnd *cmd,
+- *      void (*done)(Scsi_Cmnd *))
++ * Function : int NCR53c7xx_queue_command (struct scsi_cmnd *cmd,
++ *      void (*done)(struct scsi_cmnd *))
+  *
+  * Purpose :  enqueues a SCSI command
+  *
+@@ -3585,18 +3521,18 @@
+  *      twiddling done to the host specific fields of cmd.  If the
+  *      process_issue_queue coroutine isn't running, it is restarted.
+  * 
+- * NOTE : we use the host_scribble field of the Scsi_Cmnd structure to 
++ * NOTE : we use the host_scribble field of the scsi_cmnd structure to 
+  *	hold our own data, and pervert the ptr field of the SCp field
+  *	to create a linked list.
+  */
+ 
+ int
+-NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
++NCR53c7xx_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) {
+     struct Scsi_Host *host = cmd->device->host;
+     struct NCR53c7x0_hostdata *hostdata = 
+ 	(struct NCR53c7x0_hostdata *) host->hostdata[0];
+     unsigned long flags;
+-    Scsi_Cmnd *tmp;
++    struct scsi_cmnd *tmp;
+ 
+     cmd->scsi_done = done;
+     cmd->host_scribble = NULL;
+@@ -3614,7 +3550,7 @@
+     }
+ #endif
+ 
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+     if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY)) 
+ 	|| ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
+ 	    !(hostdata->debug_lun_limit[cmd->device->id] & (1 << cmd->device->lun)))
+@@ -3629,7 +3565,7 @@
+ 	    cmd->device->id, cmd->device->lun);
+ 	cmd->result = (DID_BAD_TARGET << 16);
+ 	done(cmd);
+-	local_irq_restore(flags);
++	spin_unlock_irqrestore(host->host_lock, flags);
+ 	return 0;
+     }
+ 
+@@ -3638,7 +3574,7 @@
+ 	printk("scsi%d : maximum commands exceeded\n", host->host_no);
+ 	cmd->result = (DID_BAD_TARGET << 16);
+ 	done(cmd);
+-	local_irq_restore(flags);
++	spin_unlock_irqrestore(host->host_lock, flags);
+ 	return 0;
+     }
+ 
+@@ -3650,7 +3586,7 @@
+ 		host->host_no);
+ 	    cmd->result = (DID_BAD_TARGET << 16);
+ 	    done(cmd);
+-	    local_irq_restore(flags);
++	    spin_unlock_irqrestore(host->host_lock, flags);
+ 	    return 0;
+ 	}
+     }
+@@ -3673,18 +3609,18 @@
+ 	cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
+ 	hostdata->issue_queue = cmd;
+     } else {
+-	for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->SCp.ptr; 
+-		tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
++	for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp->SCp.ptr; 
++		tmp = (struct scsi_cmnd *) tmp->SCp.ptr);
+ 	tmp->SCp.ptr = (unsigned char *) cmd;
+     }
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+     run_process_issue_queue();
+     return 0;
+ }
+ 
+ /*
+  * Function : void to_schedule_list (struct Scsi_Host *host,
+- * 	struct NCR53c7x0_hostdata * hostdata, Scsi_Cmnd *cmd)
++ * 	struct NCR53c7x0_hostdata * hostdata, struct scsi_cmnd *cmd)
+  *
+  * Purpose : takes a SCSI command which was just removed from the 
+  *	issue queue, and deals with it by inserting it in the first
+@@ -3705,7 +3641,7 @@
+ to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
+     struct NCR53c7x0_cmd *cmd) {
+     NCR53c7x0_local_declare();
+-    Scsi_Cmnd *tmp = cmd->cmd;
++    struct scsi_cmnd *tmp = cmd->cmd;
+     unsigned long flags;
+     /* dsa start is negative, so subtraction is used */
+     volatile u32 *ncrcurrent;
+@@ -3717,7 +3653,7 @@
+ 	virt_to_bus(hostdata->dsa), hostdata->dsa);
+ #endif
+ 
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+     
+     /* 
+      * Work around race condition : if an interrupt fired and we 
+@@ -3730,7 +3666,7 @@
+ 	cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
+ 	hostdata->free = cmd;
+ 	tmp->scsi_done(tmp);
+-	local_irq_restore(flags);
++	spin_unlock_irqrestore(host->host_lock, flags);
+ 	return;
+     }
+ 
+@@ -3760,7 +3696,7 @@
+ 	cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
+ 	hostdata->free = cmd;
+ 	tmp->scsi_done(tmp);
+-	local_irq_restore(flags);
++	spin_unlock_irqrestore(host->host_lock, flags);
+ 	return;
+     }
+ 
+@@ -3781,12 +3717,12 @@
+ 	NCR53c7x0_write8(hostdata->istat, ISTAT_10_SIGP);
+     }
+ 
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+ }
+ 
+ /*
+  * Function : busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata 
+- *	*hostdata, Scsi_Cmnd *cmd)
++ *	*hostdata, struct scsi_cmnd *cmd)
+  *
+  * Purpose : decide if we can pass the given SCSI command on to the 
+  *	device in question or not.
+@@ -3796,7 +3732,7 @@
+ 
+ static __inline__ int
+ busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata, 
+-    Scsi_Cmnd *cmd) {
++    struct scsi_cmnd *cmd) {
+     /* FIXME : in the future, this needs to accommodate SCSI-II tagged
+        queuing, and we may be able to play with fairness here a bit.
+      */
+@@ -3822,8 +3758,8 @@
+ 
+ static void 
+ process_issue_queue (unsigned long flags) {
+-    Scsi_Cmnd *tmp, *prev;
+-    struct Scsi_Host *host;
++    struct scsi_cmnd *tmp, *prev;
++    struct Scsi_Host *host, *s;
+     struct NCR53c7x0_hostdata *hostdata;
+     int done;
+ 
+@@ -3841,14 +3777,13 @@
+     do {
+ 	local_irq_disable(); /* Freeze request queues */
+ 	done = 1;
+-	for (host = first_host; host && host->hostt == the_template;
+-	    host = host->next) {
++	list_for_each_entry_safe(host, s, &the_template->legacy_hosts, sht_legacy_list) {
+ 	    hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
+-	    local_irq_disable();
++	    spin_lock_irq(host->host_lock);
+ 	    if (hostdata->issue_queue) {
+ 	    	if (hostdata->state == STATE_DISABLED) {
+-		    tmp = (Scsi_Cmnd *) hostdata->issue_queue;
+-		    hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
++		    tmp = (struct scsi_cmnd *) hostdata->issue_queue;
++		    hostdata->issue_queue = (struct scsi_cmnd *) tmp->SCp.ptr;
+ 		    tmp->result = (DID_BAD_TARGET << 16);
+ 		    if (tmp->host_scribble) {
+ 			((struct NCR53c7x0_cmd *)tmp->host_scribble)->next = 
+@@ -3860,15 +3795,15 @@
+ 		    tmp->scsi_done (tmp);
+ 		    done = 0;
+ 		} else 
+-		    for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, 
+-			prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *) 
++		    for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, 
++			prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) 
+ 			tmp->SCp.ptr) 
+ 			if (!tmp->host_scribble || 
+ 			    !busyp (host, hostdata, tmp)) {
+ 				if (prev)
+ 				    prev->SCp.ptr = tmp->SCp.ptr;
+ 				else
+-				    hostdata->issue_queue = (Scsi_Cmnd *) 
++				    hostdata->issue_queue = (struct scsi_cmnd *) 
+ 					tmp->SCp.ptr;
+ 			    tmp->SCp.ptr = NULL;
+ 			    if (tmp->host_scribble) {
+@@ -3893,6 +3828,7 @@
+ 			    done = 0;
+ 			} /* if target/lun is not busy */
+ 	    } /* if hostdata->issue_queue */
++	    spin_unlock(host->host_lock);
+ 	    if (!done)
+ 		local_irq_restore(flags);
+     	} /* for host */
+@@ -4103,7 +4039,7 @@
+ 	int cnt = 0;
+ 	int i = insn_log_index;
+ 	int size;
+-	struct Scsi_Host *host = first_host;
++	struct Scsi_Host *host = (struct Scsi_Host *)the_template->legacy_hosts->next;
+ 
+ 	while (cnt < 4096) {
+ 		printk ("%08x (+%6x): ", insn_log[i], (insn_log[i] - (u32)&(((struct NCR53c7x0_hostdata *)host->hostdata[0])->script))/4);
+@@ -4161,14 +4097,14 @@
+     * completion.
+     */
+ 
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+ restart:
+     for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)&(hostdata->running_list),
+ 	cmd = (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
+ 	cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next), 
+     	cmd = (struct NCR53c7x0_cmd *) cmd->next)
+     {
+-	Scsi_Cmnd *tmp;
++	struct scsi_cmnd *tmp;
+ 
+ 	if (!cmd) {
+ 	    printk("scsi%d : very weird.\n", host->host_no);
+@@ -4176,7 +4112,7 @@
+ 	}
+ 
+ 	if (!(tmp = cmd->cmd)) {
+-	    printk("scsi%d : weird.  NCR53c7x0_cmd has no Scsi_Cmnd\n",
++	    printk("scsi%d : weird.  NCR53c7x0_cmd has no scsi_cmnd\n",
+ 		    host->host_no);
+ 	    continue;
+ 	}
+@@ -4215,7 +4151,7 @@
+ 	tmp->scsi_done(tmp);
+ 	goto restart;
+     }
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+ 
+     if (!search_found)  {
+ 	printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
+@@ -4250,7 +4186,7 @@
+     struct NCR53c7x0_cmd *cmd;			/* command which halted */
+     u32 *dsa;					/* DSA */
+     int handled = 0;
+-
++    unsigned long flags;
+ #ifdef NCR_DEBUG
+     char buf[80];				/* Debugging sprintf buffer */
+     size_t buflen;				/* Length of same */
+@@ -4259,6 +4195,7 @@
+     host     = (struct Scsi_Host *)dev_id;
+     hostdata = (struct NCR53c7x0_hostdata *) host->hostdata[0];
+     NCR53c7x0_local_setup(host);
++    spin_lock_irqsave(host->host_lock, flags);
+ 
+     /*
+      * Only read istat once per loop, since reading it again will unstack
+@@ -4351,7 +4288,8 @@
+ 	    }
+ 	}
+     }
+-    return IRQ_HANDLED;
++    spin_unlock_irqrestore(host->host_lock, flags);
++    return IRQ_RETVAL(handled);
+ }
+ 
+ 
+@@ -4360,7 +4298,7 @@
+  *
+  * Purpose : Assuming that the NCR SCSI processor is currently 
+  * 	halted, break the currently established nexus.  Clean
+- *	up of the NCR53c7x0_cmd and Scsi_Cmnd structures should
++ *	up of the NCR53c7x0_cmd and scsi_cmnd structures should
+  *	be done on receipt of the abort interrupt.
+  *
+  * Inputs : host - SCSI host
+@@ -4899,12 +4837,12 @@
+ 	    /* Don't print instr. until we write DSP at end of intr function */
+ 	} else if (hostdata->options & OPTION_DEBUG_SINGLE) {
+ 	    print_insn (host, dsp, "s ", 0);
+-	    local_irq_save(flags);
++	    spin_lock_irqsave(host->host_lock, flags);
+ /* XXX - should we do this, or can we get away with writing dsp? */
+ 
+ 	    NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) & 
+     	    	~DCNTL_SSM) | DCNTL_STD);
+-	    local_irq_restore(flags);
++	    spin_unlock_irqrestore(host->host_lock, flags);
+ 	} else {
+ 	    printk(KERN_ALERT "scsi%d : unexpected single step interrupt at\n"
+ 		   "         ", host->host_no);
+@@ -5127,7 +5065,7 @@
+ }
+ 
+ /*
+- * Function : int NCR53c7xx_abort (Scsi_Cmnd *cmd)
++ * Function : int NCR53c7xx_abort (struct scsi_cmnd *cmd)
+  * 
+  * Purpose : Abort an errant SCSI command, doing all necessary
+  *	cleanup of the issue_queue, running_list, shared Linux/NCR
+@@ -5139,14 +5077,14 @@
+  */
+ 
+ int 
+-NCR53c7xx_abort (Scsi_Cmnd *cmd) {
++NCR53c7xx_abort (struct scsi_cmnd *cmd) {
+     NCR53c7x0_local_declare();
+     struct Scsi_Host *host = cmd->device->host;
+     struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *) 
+ 	host->hostdata[0] : NULL;
+     unsigned long flags;
+     struct NCR53c7x0_cmd *curr, **prev;
+-    Scsi_Cmnd *me, **last;
++    struct scsi_cmnd *me, **last;
+ #if 0
+     static long cache_pid = -1;
+ #endif
+@@ -5155,10 +5093,10 @@
+     if (!host) {
+ 	printk ("Bogus SCSI command pid %ld; no host structure\n",
+ 	    cmd->pid);
+-	return SCSI_ABORT_ERROR;
++	return FAILED;
+     } else if (!hostdata) {
+ 	printk ("Bogus SCSI host %d; no hostdata\n", host->host_no);
+-	return SCSI_ABORT_ERROR;
++	return FAILED;
+     }
+     NCR53c7x0_local_setup(host);
+ 
+@@ -5179,10 +5117,10 @@
+ 	printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no,
+ 	    cmd->pid);
+ 	NCR53c7x0_intr (host->irq, NULL, NULL);
+-	return SCSI_ABORT_BUSY;
++	return FAILED;
+     }
+ 	
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+ #if 0
+     if (cache_pid == cmd->pid) 
+ 	panic ("scsi%d : bloody fetus %d\n", host->host_no, cmd->pid);
+@@ -5201,13 +5139,13 @@
+  * pull the command out of the old queue, and call it aborted.
+  */
+ 
+-    for (me = (Scsi_Cmnd *) hostdata->issue_queue, 
+-         last = (Scsi_Cmnd **) &(hostdata->issue_queue);
+-	 me && me != cmd;  last = (Scsi_Cmnd **)&(me->SCp.ptr), 
+-	 me = (Scsi_Cmnd *)me->SCp.ptr);
++    for (me = (struct scsi_cmnd *) hostdata->issue_queue, 
++         last = (struct scsi_cmnd **) &(hostdata->issue_queue);
++	 me && me != cmd;  last = (struct scsi_cmnd **)&(me->SCp.ptr), 
++	 me = (struct scsi_cmnd *)me->SCp.ptr);
+ 
+     if (me) {
+-	*last = (Scsi_Cmnd *) me->SCp.ptr;
++	*last = (struct scsi_cmnd *) me->SCp.ptr;
+ 	if (me->host_scribble) {
+ 	    ((struct NCR53c7x0_cmd *)me->host_scribble)->next = hostdata->free;
+ 	    hostdata->free = (struct NCR53c7x0_cmd *) me->host_scribble;
+@@ -5217,9 +5155,9 @@
+ 	cmd->scsi_done(cmd);
+ 	printk ("scsi%d : found command %ld in Linux issue queue\n", 
+ 	    host->host_no, me->pid);
+-	local_irq_restore(flags);
++	spin_unlock_irqrestore(host->host_lock, flags);
+     	run_process_issue_queue();
+-	return SCSI_ABORT_SUCCESS;
++	return SUCCESS;
+     }
+ 
+ /* 
+@@ -5243,13 +5181,13 @@
+ 	    cmd->scsi_done(cmd);
+ 	printk ("scsi%d : found finished command %ld in running list\n", 
+ 	    host->host_no, cmd->pid);
+-	    local_irq_restore(flags);
+-	    return SCSI_ABORT_NOT_RUNNING;
++	    spin_unlock_irqrestore(host->host_lock, flags);
++	    return SUCCESS;
+ 	} else {
+ 	    printk ("scsi%d : DANGER : command running, can not abort.\n",
+ 		cmd->device->host->host_no);
+-	    local_irq_restore(flags);
+-	    return SCSI_ABORT_BUSY;
++	    spin_unlock_irqrestore(host->host_lock, flags);
++	    return FAILED;
+ 	}
+     }
+ 
+@@ -5280,21 +5218,20 @@
+  */
+         --hostdata->busy[cmd->device->id][cmd->device->lun];
+     }
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+     cmd->scsi_done(cmd);
+ 
+ /* 
+  * We need to run process_issue_queue since termination of this command 
+  * may allow another queued command to execute first? 
+  */
+-    return SCSI_ABORT_NOT_RUNNING;
++    return SUCCESS;
+ }
+ 
+ /*
+- * Function : int NCR53c7xx_reset (Scsi_Cmnd *cmd) 
++ * Function : int NCR53c7xx_reset (struct scsi_cmnd *cmd) 
+  * 
+- * Purpose : perform a hard reset of the SCSI bus and NCR
+- * 	chip.
++ * Purpose : perform a hard reset of the SCSI bus.
+  *
+  * Inputs : cmd - command which caused the SCSI RESET
+  *
+@@ -5302,12 +5239,12 @@
+  */
+  
+ int 
+-NCR53c7xx_reset (Scsi_Cmnd *cmd, unsigned int reset_flags) {
++NCR53c7xx_reset (struct scsi_cmnd *cmd) {
+     NCR53c7x0_local_declare();
+     unsigned long flags;
+     int found = 0;
+     struct NCR53c7x0_cmd * c;
+-    Scsi_Cmnd *tmp;
++    struct scsi_cmnd *tmp;
+     /*
+      * When we call scsi_done(), it's going to wake up anything sleeping on the
+      * resources which were in use by the aborted commands, and we'll start to 
+@@ -5322,19 +5259,19 @@
+      * pointer), do our reinitialization, and then call the done function for
+      * each command.  
+      */
+-    Scsi_Cmnd *nuke_list = NULL;
++    struct scsi_cmnd *nuke_list = NULL;
+     struct Scsi_Host *host = cmd->device->host;
+     struct NCR53c7x0_hostdata *hostdata = 
+     	(struct NCR53c7x0_hostdata *) host->hostdata[0];
+ 
+     NCR53c7x0_local_setup(host);
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+     ncr_halt (host);
+     print_lots (host);
+     dump_events (host, 30);
+     ncr_scsi_reset (host);
+     for (tmp = nuke_list = return_outstanding_commands (host, 1 /* free */,
+-	0 /* issue */ ); tmp; tmp = (Scsi_Cmnd *) tmp->SCp.buffer)
++	0 /* issue */ ); tmp; tmp = (struct scsi_cmnd *) tmp->SCp.buffer)
+ 	if (tmp == cmd) {
+ 	    found = 1;
+ 	    break;
+@@ -5357,19 +5294,21 @@
+     }
+ 
+     NCR53c7x0_driver_init (host);
++#if 0
+     hostdata->soft_reset (host);
++#endif
+     if (hostdata->resets == 0) 
+ 	disable(host);
+     else if (hostdata->resets != -1)
+ 	--hostdata->resets;
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+     for (; nuke_list; nuke_list = tmp) {
+-	tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
++	tmp = (struct scsi_cmnd *) nuke_list->SCp.buffer;
+     	nuke_list->result = DID_RESET << 16;
+ 	nuke_list->scsi_done (nuke_list);
+     }
+-    local_irq_restore(flags);
+-    return SCSI_RESET_SUCCESS;
++    spin_unlock_irqrestore(host->host_lock, flags);
++    return SUCCESS;
+ }
+ 
+ /*
+@@ -5378,7 +5317,7 @@
+  */
+ 
+ /*
+- * Function : int insn_to_offset (Scsi_Cmnd *cmd, u32 *insn)
++ * Function : int insn_to_offset (struct scsi_cmnd *cmd, u32 *insn)
+  *
+  * Purpose : convert instructions stored at NCR pointer into data 
+  *	pointer offset.
+@@ -5391,7 +5330,7 @@
+ 
+ 
+ static int 
+-insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
++insn_to_offset (struct scsi_cmnd *cmd, u32 *insn) {
+     struct NCR53c7x0_hostdata *hostdata = 
+ 	(struct NCR53c7x0_hostdata *) cmd->device->host->hostdata[0];
+     struct NCR53c7x0_cmd *ncmd = 
+@@ -5445,7 +5384,7 @@
+ 
+ 
+ /*
+- * Function : void print_progress (Scsi_Cmnd *cmd) 
++ * Function : void print_progress (struct scsi_cmnd *cmd) 
+  * 
+  * Purpose : print the current location of the saved data pointer
+  *
+@@ -5454,7 +5393,7 @@
+  */
+ 
+ static void 
+-print_progress (Scsi_Cmnd *cmd) {
++print_progress (struct scsi_cmnd *cmd) {
+     NCR53c7x0_local_declare();
+     struct NCR53c7x0_cmd *ncmd = 
+ 	(struct NCR53c7x0_cmd *) cmd->host_scribble;
+@@ -5512,7 +5451,7 @@
+ 	host->hostdata[0];
+     int i, len;
+     char *ptr;
+-    Scsi_Cmnd *cmd;
++    struct scsi_cmnd *cmd;
+ 
+     if (check_address ((unsigned long) dsa, hostdata->dsa_end - 
+ 	hostdata->dsa_start) == -1) {
+@@ -5548,7 +5487,7 @@
+ 
+     printk("        + %d : select_indirect = 0x%x\n",
+ 	hostdata->dsa_select, dsa[hostdata->dsa_select / sizeof(u32)]);
+-    cmd = (Scsi_Cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
++    cmd = (struct scsi_cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
+     printk("        + %d : dsa_cmnd = 0x%x ", hostdata->dsa_cmnd,
+ 	   (u32) virt_to_bus(cmd));
+     /* XXX Maybe we should access cmd->host_scribble->result here. RGH */
+@@ -5588,16 +5527,16 @@
+     u32 *dsa, *next_dsa;
+     volatile u32 *ncrcurrent;
+     int left;
+-    Scsi_Cmnd *cmd, *next_cmd;
++    struct scsi_cmnd *cmd, *next_cmd;
+     unsigned long flags;
+ 
+     printk ("scsi%d : issue queue\n", host->host_no);
+ 
+-    for (left = host->can_queue, cmd = (Scsi_Cmnd *) hostdata->issue_queue; 
++    for (left = host->can_queue, cmd = (struct scsi_cmnd *) hostdata->issue_queue; 
+ 	    left >= 0 && cmd; 
+ 	    cmd = next_cmd) {
+-	next_cmd = (Scsi_Cmnd *) cmd->SCp.ptr;
+-	local_irq_save(flags);
++	next_cmd = (struct scsi_cmnd *) cmd->SCp.ptr;
++	spin_lock_irqsave(host->host_lock, flags);
+ 	if (cmd->host_scribble) {
+ 	    if (check_address ((unsigned long) (cmd->host_scribble), 
+ 		sizeof (cmd->host_scribble)) == -1)
+@@ -5610,7 +5549,7 @@
+ 	} else 
+ 	    printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n",
+ 		host->host_no, cmd->pid, cmd->device->id, cmd->device->lun);
+-	local_irq_restore(flags);
++	spin_unlock_irqrestore(host->host_lock, flags);
+     }
+ 
+     if (left <= 0) {
+@@ -5642,7 +5581,7 @@
+ 	dsa = bus_to_virt (hostdata->reconnect_dsa_head);
+ 	left >= 0 && dsa; 
+ 	dsa = next_dsa) {
+-	local_irq_save(flags);
++	spin_lock_irqsave(host->host_lock, flags);
+ 	if (check_address ((unsigned long) dsa, sizeof(dsa)) == -1) {
+ 	    printk ("scsi%d: bad DSA pointer 0x%p", host->host_no,
+ 		dsa);
+@@ -5653,7 +5592,7 @@
+ 	    next_dsa = bus_to_virt(dsa[hostdata->dsa_next / sizeof(u32)]);
+ 	    print_dsa (host, dsa, "");
+ 	}
+-	local_irq_restore(flags);
++	spin_unlock_irqrestore(host->host_lock, flags);
+     }
+     printk ("scsi%d : end reconnect_dsa_head\n", host->host_no);
+     if (left < 0)
+@@ -5743,14 +5682,14 @@
+     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+ 	host->hostdata[0];
+     NCR53c7x0_local_setup(host);
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+ /* Get in a state where we can reset the SCSI bus */
+     ncr_halt (host);
+     ncr_scsi_reset (host);
+     hostdata->soft_reset(host);
+ 
+     disable (host);
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+     return 0;
+ }
+ 
+@@ -5765,11 +5704,11 @@
+     NCR53c7x0_local_declare();
+     unsigned long flags;
+     NCR53c7x0_local_setup(host);
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+     NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
+     udelay(25);	/* Minimum amount of time to assert RST */
+     NCR53c7x0_write8(SCNTL1_REG, 0);
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+ }
+ 
+ /* 
+@@ -5782,26 +5721,26 @@
+     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+ 	host->hostdata[0];
+     unsigned long flags;
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+     ncr_scsi_reset(host);
+     NCR53c7x0_driver_init (host);
+     if (hostdata->soft_reset)
+ 	hostdata->soft_reset (host);
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+ }
+ 
+ 
+ /*
+- * Function : Scsi_Cmnd *return_outstanding_commands (struct Scsi_Host *host,
++ * Function : struct scsi_cmnd *return_outstanding_commands (struct Scsi_Host *host,
+  *	int free, int issue)
+  *
+  * Purpose : return a linked list (using the SCp.buffer field as next,
+  *	so we don't perturb hostdata.  We don't use a field of the 
+  *	NCR53c7x0_cmd structure since we may not have allocated one 
+- *	for the command causing the reset.) of Scsi_Cmnd structures that 
++ *	for the command causing the reset.) of scsi_cmnd structures that 
+  *  	had propagated below the Linux issue queue level.  If free is set, 
+  *	free the NCR53c7x0_cmd structures which are associated with 
+- *	the Scsi_Cmnd structures, and clean up any internal 
++ *	the scsi_cmnd structures, and clean up any internal 
+  *	NCR lists that the commands were on.  If issue is set,
+  *	also return commands in the issue queue.
+  *
+@@ -5811,14 +5750,14 @@
+  *	if the free flag is set. 
+  */
+ 
+-static Scsi_Cmnd *
++static struct scsi_cmnd *
+ return_outstanding_commands (struct Scsi_Host *host, int free, int issue) {
+     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+ 	host->hostdata[0];
+     struct NCR53c7x0_cmd *c;
+     int i;
+     u32 *ncrcurrent;
+-    Scsi_Cmnd *list = NULL, *tmp;
++    struct scsi_cmnd *list = NULL, *tmp, *next_cmd;
+     for (c = (struct NCR53c7x0_cmd *) hostdata->running_list; c; 
+     	c = (struct NCR53c7x0_cmd *) c->next)  {
+ 	if (c->cmd->SCp.buffer) {
+@@ -5847,7 +5786,9 @@
+     }
+ 
+     if (issue) {
+-	for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; tmp = tmp->next) {
++	for (tmp = (struct scsi_cmnd *) hostdata->issue_queue; tmp; tmp = next_cmd) {
++	    next_cmd = (struct scsi_cmnd *) tmp->SCp.ptr;
++
+ 	    if (tmp->SCp.buffer) {
+ 		printk ("scsi%d : loop detected in issue queue!\n", 
+ 			host->host_no);
+@@ -5882,17 +5823,17 @@
+     struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
+ 	host->hostdata[0];
+     unsigned long flags;
+-    Scsi_Cmnd *nuke_list, *tmp;
+-    local_irq_save(flags);
++    struct scsi_cmnd *nuke_list, *tmp;
++    spin_lock_irqsave(host->host_lock, flags);
+     if (hostdata->state != STATE_HALTED)
+ 	ncr_halt (host);
+     nuke_list = return_outstanding_commands (host, 1 /* free */, 1 /* issue */);
+     hard_reset (host);
+     hostdata->state = STATE_DISABLED;
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+     printk ("scsi%d : nuking commands\n", host->host_no);
+     for (; nuke_list; nuke_list = tmp) {
+-	    tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
++	    tmp = (struct scsi_cmnd *) nuke_list->SCp.buffer;
+ 	    nuke_list->result = DID_ERROR << 16;
+ 	    nuke_list->scsi_done(nuke_list);
+     }
+@@ -5922,7 +5863,7 @@
+     int stage;
+     NCR53c7x0_local_setup(host);
+ 
+-    local_irq_save(flags);
++    spin_lock_irqsave(host->host_lock, flags);
+     /* Stage 0 : eat all interrupts
+        Stage 1 : set ABORT
+        Stage 2 : eat all but abort interrupts
+@@ -5957,7 +5898,7 @@
+ 	}
+     }
+     hostdata->state = STATE_HALTED;
+-    local_irq_restore(flags);
++    spin_unlock_irqrestore(host->host_lock, flags);
+ #if 0
+     print_lots (host);
+ #endif
+@@ -6011,7 +5952,7 @@
+  * still be guaranteed that they're happening on the same 
+  * event structure.
+  */
+-	    local_irq_save(flags);
++	    spin_lock_irqsave(host->host_lock, flags);
+ #if 0
+ 	    event = hostdata->events[i];
+ #else
+@@ -6019,7 +5960,7 @@
+ 		sizeof(event));
+ #endif
+ 
+-	    local_irq_restore(flags);
++	    spin_unlock_irqrestore(host->host_lock, flags);
+ 	    printk ("scsi%d : %s event %d at %ld secs %ld usecs target %d lun %d\n",
+ 		host->host_no, event_name (event.event), count,
+ 		(long) event.time.tv_sec, (long) event.time.tv_usec,
+@@ -6054,6 +5995,72 @@
+     return (virt_to_phys((void *)addr) < PAGE_SIZE || virt_to_phys((void *)(addr + size)) > virt_to_phys(high_memory) ?  -1 : 0);
+ }
+ 
++int
++NCR53c7xx_slave_configure(struct scsi_device *sdev) {
++    struct Scsi_Host *host = sdev->host;
++    struct NCR53c7x0_hostdata *hostdata = 
++	(struct NCR53c7x0_hostdata *) host->hostdata[0];
++    struct NCR53c7x0_cmd *tmp;
++    u32 real;			/* Real address */
++    int size;			/* Size of *tmp */
++    unsigned long flags;
++    int extra_allocate = 0;
++
++/*
++ * Reserve commands for this I_T_L nexus.
++ */
++    if (hostdata->num_cmds < host->can_queue)
++        extra_allocate = host->cmd_per_lun;
++
++    for (; extra_allocate > 0 ; --extra_allocate, 
++    	++hostdata->num_cmds) {
++    /* historically, kmalloc has returned unaligned addresses; pad so we
++       have enough room to ROUNDUP */
++	size = hostdata->max_cmd_size + sizeof (void *);
++#ifdef FORCE_DSA_ALIGNMENT
++	/*
++	 * 53c710 rev.0 doesn't have an add-with-carry instruction.
++	 * Ensure we allocate enough memory to force alignment.
++	 */
++	size += 256;
++#endif
++/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
++
++        if (size > 4096) {
++            printk (KERN_ERR "53c7xx: slave_configure size > 4K\n");
++	    return -ENOMEM;
++	}
++        real = get_zeroed_page(GFP_ATOMIC);
++        if (real == 0)
++        	return -ENOMEM;
++        memset((void *)real, 0, 4096);
++        cache_push(virt_to_phys((void *)real), 4096);
++        cache_clear(virt_to_phys((void *)real), 4096);
++        kernel_set_cachemode((void *)real, 4096, IOMAP_NOCACHE_SER);
++	tmp = ROUNDUP(real, void *);
++#ifdef FORCE_DSA_ALIGNMENT
++	{
++	    if (((u32)tmp & 0xff) > CmdPageStart)
++		tmp = (struct NCR53c7x0_cmd *)((u32)tmp + 255);
++	    tmp = (struct NCR53c7x0_cmd *)(((u32)tmp & ~0xff) + CmdPageStart);
++#if 0
++	    printk ("scsi: size = %d, real = 0x%08x, tmp set to 0x%08x\n",
++			size, real, (u32)tmp);
++#endif
++	}
++#endif
++	tmp->real = (void *)real;
++	tmp->size = size;			
++	tmp->free = ((void (*)(void *, int)) my_free_page);
++	spin_lock_irqsave(host->host_lock, flags);
++	tmp->next = hostdata->free;
++	hostdata->free = tmp;
++	spin_unlock_irqrestore(host->host_lock, flags);
++    }
++
++    return 0;
++}
++
+ #ifdef MODULE
+ int 
+ NCR53c7x0_release(struct Scsi_Host *host) {
+@@ -6063,19 +6070,22 @@
+     shutdown (host);
+     if (host->irq != SCSI_IRQ_NONE)
+ 	{
+-	    int irq_count;
+-	    struct Scsi_Host *tmp;
+-	    for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
+-		if (tmp->hostt == the_template && tmp->irq == host->irq)
++	    int irq_count = 0;
++	    struct Scsi_Host *tmp, *s;
++	    list_for_each_entry_safe(tmp, s, &the_template->legacy_hosts, sht_legacy_list) {
++		if (tmp->irq == host->irq)
+ 		    ++irq_count;
++	    }
+ 	    if (irq_count == 1)
+ 		free_irq(host->irq, NULL);
+ 	}
++#ifdef CONFIG_ISA
+     if (host->dma_channel != DMA_NONE)
+ 	free_dma(host->dma_channel);
++#endif
+     if (host->io_port)
+ 	release_region(host->io_port, host->n_io_port);
+-    
++
+     for (cmd = (struct NCR53c7x0_cmd *) hostdata->free; cmd; cmd = tmp, 
+ 	--hostdata->num_cmds) {
+ 	tmp = (struct NCR53c7x0_cmd *) cmd->next;
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/53c7xx.h linux-m68k/drivers/scsi/53c7xx.h
+--- linux-i386/drivers/scsi/53c7xx.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/scsi/53c7xx.h	2004-10-30 16:35:43.000000000 +0200
+@@ -997,7 +997,7 @@
+     u32 *dsa;			/* What's in the DSA register now (virt) */
+ /* 
+  * A few things from that SCSI pid so we know what happened after 
+- * the Scsi_Cmnd structure in question may have disappeared.
++ * the scsi_cmnd structure in question may have disappeared.
+  */
+     unsigned long pid;		/* The SCSI PID which caused this 
+ 				   event */
+@@ -1029,8 +1029,8 @@
+     void (* free)(void *, int);		/* Command to deallocate; NULL
+ 					   for structures allocated with
+ 					   scsi_register, etc. */
+-    Scsi_Cmnd *cmd;			/* Associated Scsi_Cmnd 
+-					   structure, Scsi_Cmnd points
++    struct scsi_cmnd *cmd;		/* Associated scsi_cmnd 
++					   structure, scsi_cmnd points
+ 					   at NCR53c7x0_cmd using 
+ 					   host_scribble structure */
+ 
+@@ -1039,8 +1039,8 @@
+ 
+     int flags;				/* CMD_* flags */
+ 
+-    unsigned char      cmnd[12];	/* CDB, copied from Scsi_Cmnd */
+-    int                result;		/* Copy to Scsi_Cmnd when done */
++    unsigned char      cmnd[12];	/* CDB, copied from scsi_cmnd */
++    int                result;		/* Copy to scsi_cmnd when done */
+ 
+     struct {				/* Private non-cached bounce buffer */
+         unsigned char buf[256];
+@@ -1339,7 +1339,7 @@
+     volatile struct NCR53c7x0_synchronous sync[16]
+ 	__attribute__ ((aligned (4)));
+ 
+-    volatile Scsi_Cmnd *issue_queue
++    volatile struct scsi_cmnd *issue_queue
+ 	__attribute__ ((aligned (4)));
+ 						/* waiting to be issued by
+ 						   Linux driver */
+@@ -1363,10 +1363,6 @@
+ 						   */
+     volatile int num_cmds;			/* Number of commands 
+ 						   allocated */
+-    volatile int extra_allocate;
+-    volatile unsigned char cmd_allocated[16];	/* Have we allocated commands
+-						   for this target yet?  If not,
+-						   do so ASAP */
+     volatile unsigned char busy[16][8];     	/* number of commands 
+ 						   executing on each target
+     	    	    	    	    	    	 */
+@@ -1589,20 +1585,26 @@
+ /* Patch field in dsa structure (assignment should be +=?) */
+ #define patch_dsa_32(dsa, symbol, word, value)				\
+ 	{								\
+-	(dsa)[(hostdata->##symbol - hostdata->dsa_start) / sizeof(u32)	\
++	(dsa)[(hostdata->symbol - hostdata->dsa_start) / sizeof(u32)	\
+ 	    + (word)] = (value);					\
+ 	if (hostdata->options & OPTION_DEBUG_DSA)			\
+ 	    printk("scsi : dsa %s symbol %s(%d) word %d now 0x%x\n",	\
+-		#dsa, #symbol, hostdata->##symbol, 			\
++		#dsa, #symbol, hostdata->symbol, 			\
+ 		(word), (u32) (value));					\
+ 	}
+ 
+ /* Paranoid people could use panic() here. */
+ #define FATAL(host) shutdown((host));
+ 
+-extern int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip,
++extern int ncr53c7xx_init(struct scsi_host_template *tpnt, int board, int chip,
+ 			  unsigned long base, int io_port, int irq, int dma,
+ 			  long long options, int clock);
++extern const char *NCR53c7x0_info(void);
++extern int NCR53c7xx_queue_command(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
++extern int NCR53c7xx_abort(struct scsi_cmnd *);
++extern int NCR53c7x0_release (struct Scsi_Host *);
++extern int NCR53c7xx_reset(struct scsi_cmnd *);
++extern int NCR53c7xx_slave_configure(struct scsi_device *);
+ 
+ #endif /* NCR53c710_C */
+ #endif /* NCR53c710_H */
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/Kconfig linux-m68k/drivers/scsi/Kconfig
+--- linux-i386/drivers/scsi/Kconfig	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/scsi/Kconfig	2005-10-29 10:42:45.000000000 +0200
+@@ -1654,7 +1654,7 @@
+ 
+ config SCSI_AMIGA7XX
+ 	bool "Amiga NCR53c710 SCSI support (EXPERIMENTAL)"
+-	depends on AMIGA && SCSI && EXPERIMENTAL && BROKEN
++	depends on AMIGA && SCSI && EXPERIMENTAL
+ 	help
+ 	  Support for various NCR53c710-based SCSI controllers on the Amiga.
+ 	  This includes:
+@@ -1751,7 +1751,7 @@
+ 
+ config MVME16x_SCSI
+ 	bool "NCR53C710 SCSI driver for MVME16x"
+-	depends on MVME16x && SCSI && BROKEN
++	depends on MVME16x && SCSI
+ 	help
+ 	  The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
+ 	  SCSI controller chip.  Almost everyone using one of these boards
+@@ -1759,7 +1759,7 @@
+ 
+ config BVME6000_SCSI
+ 	bool "NCR53C710 SCSI driver for BVME6000"
+-	depends on BVME6000 && SCSI && BROKEN
++	depends on BVME6000 && SCSI
+ 	help
+ 	  The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
+ 	  SCSI controller chip.  Almost everyone using one of these boards
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/NCR5380.c linux-m68k/drivers/scsi/NCR5380.c
+--- linux-i386/drivers/scsi/NCR5380.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/scsi/NCR5380.c	2005-10-29 10:42:45.000000000 +0200
+@@ -353,6 +353,7 @@
+ 	return -ETIMEDOUT;
+ }
+ 
++#if NDEBUG
+ static struct {
+ 	unsigned char value;
+ 	const char *name;
+@@ -366,7 +367,6 @@
+ 	{PHASE_UNKNOWN, "UNKNOWN"}
+ };
+ 
+-#if NDEBUG
+ static struct {
+ 	unsigned char mask;
+ 	const char *name;
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/amiga7xx.c linux-m68k/drivers/scsi/amiga7xx.c
+--- linux-i386/drivers/scsi/amiga7xx.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/scsi/amiga7xx.c	2004-10-30 16:35:43.000000000 +0200
+@@ -27,8 +27,14 @@
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include "53c7xx.h"
+-#include "amiga7xx.h"
+ 
++#ifndef CMD_PER_LUN
++#define CMD_PER_LUN 3
++#endif
++
++#ifndef CAN_QUEUE
++#define CAN_QUEUE 24
++#endif
+ 
+ static int amiga7xx_register_one(Scsi_Host_Template *tpnt,
+ 				 unsigned long address)
+@@ -115,8 +121,10 @@
+ {
+ 	if (shost->irq)
+ 		free_irq(shost->irq, NULL);
++#ifdef CONFIG_ISA
+ 	if (shost->dma_channel != 0xff)
+ 		free_dma(shost->dma_channel);
++#endif
+ 	if (shost->io_port && shost->n_io_port)
+ 		release_region(shost->io_port, shost->n_io_port);
+ 	scsi_unregister(shost);
+@@ -128,8 +136,9 @@
+ 	.detect			= amiga7xx_detect,
+ 	.release		= amiga7xx_release,
+ 	.queuecommand		= NCR53c7xx_queue_command,
+-	.abort			= NCR53c7xx_abort,
+-	.reset			= NCR53c7xx_reset,
++	.eh_abort_handler	= NCR53c7xx_abort,
++	.eh_bus_reset_handler	= NCR53c7xx_reset,
++	.slave_configure	= NCR53c7xx_slave_configure,
+ 	.can_queue		= 24,
+ 	.this_id		= 7,
+ 	.sg_tablesize		= 63,
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/amiga7xx.h linux-m68k/drivers/scsi/amiga7xx.h
+--- linux-i386/drivers/scsi/amiga7xx.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/scsi/amiga7xx.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,23 +0,0 @@
+-#ifndef AMIGA7XX_H
+-
+-#include <linux/types.h>
+-
+-int amiga7xx_detect(Scsi_Host_Template *);
+-const char *NCR53c7x0_info(void);
+-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+-int NCR53c7xx_abort(Scsi_Cmnd *);
+-int NCR53c7x0_release (struct Scsi_Host *);
+-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
+-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
+-
+-#ifndef CMD_PER_LUN
+-#define CMD_PER_LUN 3
+-#endif
+-
+-#ifndef CAN_QUEUE
+-#define CAN_QUEUE 24
+-#endif
+-
+-#include <scsi/scsicam.h>
+-
+-#endif /* AMIGA7XX_H */
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/bvme6000.c linux-m68k/drivers/scsi/bvme6000.c
+--- linux-i386/drivers/scsi/bvme6000.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/scsi/bvme6000.c	2004-10-30 16:35:43.000000000 +0200
+@@ -19,10 +19,16 @@
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include "53c7xx.h"
+-#include "bvme6000.h"
+ 
+ #include<linux/stat.h>
+ 
++#ifndef CMD_PER_LUN
++#define CMD_PER_LUN 3
++#endif
++
++#ifndef CAN_QUEUE
++#define CAN_QUEUE 24
++#endif
+ 
+ int bvme6000_scsi_detect(Scsi_Host_Template *tpnt)
+ {
+@@ -52,8 +58,10 @@
+ {
+ 	if (shost->irq)
+ 		free_irq(shost->irq, NULL);
++#ifdef CONFIG_ISA
+ 	if (shost->dma_channel != 0xff)
+ 		free_dma(shost->dma_channel);
++#endif
+ 	if (shost->io_port && shost->n_io_port)
+ 		release_region(shost->io_port, shost->n_io_port);
+ 	scsi_unregister(shost);
+@@ -65,8 +73,9 @@
+ 	.detect			= bvme6000_scsi_detect,
+ 	.release		= bvme6000_scsi_release,
+ 	.queuecommand		= NCR53c7xx_queue_command,
+-	.abort			= NCR53c7xx_abort,
+-	.reset			= NCR53c7xx_reset,
++	.eh_abort_handler	= NCR53c7xx_abort,
++	.eh_bus_reset_handler	= NCR53c7xx_reset,
++	.slave_configure	= NCR53c7xx_slave_configure,
+ 	.can_queue		= 24,
+ 	.this_id		= 7,
+ 	.sg_tablesize		= 63,
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/bvme6000.h linux-m68k/drivers/scsi/bvme6000.h
+--- linux-i386/drivers/scsi/bvme6000.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/scsi/bvme6000.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,24 +0,0 @@
+-#ifndef BVME6000_SCSI_H
+-#define BVME6000_SCSI_H
+-
+-#include <linux/types.h>
+-
+-int bvme6000_scsi_detect(Scsi_Host_Template *);
+-const char *NCR53c7x0_info(void);
+-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+-int NCR53c7xx_abort(Scsi_Cmnd *);
+-int NCR53c7x0_release (struct Scsi_Host *);
+-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
+-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
+-
+-#ifndef CMD_PER_LUN
+-#define CMD_PER_LUN 3
+-#endif
+-
+-#ifndef CAN_QUEUE
+-#define CAN_QUEUE 24
+-#endif
+-
+-#include <scsi/scsicam.h>
+-
+-#endif /* BVME6000_SCSI_H */
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/mvme16x.c linux-m68k/drivers/scsi/mvme16x.c
+--- linux-i386/drivers/scsi/mvme16x.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/scsi/mvme16x.c	2004-10-30 16:35:43.000000000 +0200
+@@ -17,10 +17,16 @@
+ #include "scsi.h"
+ #include <scsi/scsi_host.h>
+ #include "53c7xx.h"
+-#include "mvme16x.h"
+ 
+ #include<linux/stat.h>
+ 
++#ifndef CMD_PER_LUN
++#define CMD_PER_LUN 3
++#endif
++
++#ifndef CAN_QUEUE
++#define CAN_QUEUE 24
++#endif
+ 
+ int mvme16x_scsi_detect(Scsi_Host_Template *tpnt)
+ {
+@@ -54,8 +60,10 @@
+ {
+ 	if (shost->irq)
+ 		free_irq(shost->irq, NULL);
++#ifdef CONFIG_ISA
+ 	if (shost->dma_channel != 0xff)
+ 		free_dma(shost->dma_channel);
++#endif
+ 	if (shost->io_port && shost->n_io_port)
+ 		release_region(shost->io_port, shost->n_io_port);
+ 	scsi_unregister(shost);
+@@ -67,8 +75,9 @@
+ 	.detect			= mvme16x_scsi_detect,
+ 	.release		= mvme16x_scsi_release,
+ 	.queuecommand		= NCR53c7xx_queue_command,
+-	.abort			= NCR53c7xx_abort,
+-	.reset			= NCR53c7xx_reset,
++	.eh_abort_handler	= NCR53c7xx_abort,
++	.eh_bus_reset_handler	= NCR53c7xx_reset,
++	.slave_configure	= NCR53c7xx_slave_configure,
+ 	.can_queue		= 24,
+ 	.this_id		= 7,
+ 	.sg_tablesize		= 63,
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/drivers/scsi/mvme16x.h linux-m68k/drivers/scsi/mvme16x.h
+--- linux-i386/drivers/scsi/mvme16x.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/drivers/scsi/mvme16x.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,24 +0,0 @@
+-#ifndef MVME16x_SCSI_H
+-#define MVME16x_SCSI_H
+-
+-#include <linux/types.h>
+-
+-int mvme16x_scsi_detect(Scsi_Host_Template *);
+-const char *NCR53c7x0_info(void);
+-int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+-int NCR53c7xx_abort(Scsi_Cmnd *);
+-int NCR53c7x0_release (struct Scsi_Host *);
+-int NCR53c7xx_reset(Scsi_Cmnd *, unsigned int);
+-void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
+-
+-#ifndef CMD_PER_LUN
+-#define CMD_PER_LUN 3
+-#endif
+-
+-#ifndef CAN_QUEUE
+-#define CAN_QUEUE 24
+-#endif
+-
+-#include <scsi/scsicam.h>
+-
+-#endif /* MVME16x_SCSI_H */
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/fs/fat/inode.c linux-m68k/fs/fat/inode.c
+--- linux-i386/fs/fat/inode.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/fs/fat/inode.c	2005-10-29 10:43:07.000000000 +0200
+@@ -11,12 +11,14 @@
+  */
+ 
+ #include <linux/module.h>
++#include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/time.h>
+ #include <linux/slab.h>
+ #include <linux/smp_lock.h>
+ #include <linux/seq_file.h>
+ #include <linux/msdos_fs.h>
++#include <linux/major.h>
+ #include <linux/pagemap.h>
+ #include <linux/buffer_head.h>
+ #include <linux/mount.h>
+@@ -771,7 +773,7 @@
+ 	Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid,
+ 	Opt_umask, Opt_dmask, Opt_fmask, Opt_codepage, Opt_nocase,
+ 	Opt_quiet, Opt_showexec, Opt_debug, Opt_immutable,
+-	Opt_dots, Opt_nodots,
++	Opt_dots, Opt_nodots, Opt_atari_no, Opt_atari_yes,
+ 	Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
+ 	Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
+ 	Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
+@@ -796,6 +798,9 @@
+ 	{Opt_showexec, "showexec"},
+ 	{Opt_debug, "debug"},
+ 	{Opt_immutable, "sys_immutable"},
++	{Opt_atari_yes, "atari=yes"},
++	{Opt_atari_yes, "atari"},
++	{Opt_atari_no, "atari=no"},
+ 	{Opt_obsolate, "conv=binary"},
+ 	{Opt_obsolate, "conv=text"},
+ 	{Opt_obsolate, "conv=auto"},
+@@ -870,6 +875,13 @@
+ 	opts->utf8 = opts->unicode_xlate = 0;
+ 	opts->numtail = 1;
+ 	opts->nocase = 0;
++	opts->atari = 0;
++
++#ifdef CONFIG_ATARI
++	if(MACH_IS_ATARI)
++	/* make Atari GEMDOS format the default if machine is an Atari */
++		opts->atari = 1;
++#endif
+ 	*debug = 0;
+ 
+ 	if (!options)
+@@ -918,6 +930,12 @@
+ 		case Opt_immutable:
+ 			opts->sys_immutable = 1;
+ 			break;
++		case Opt_atari_yes:
++			opts->atari = 1;
++			break;
++		case Opt_atari_no:
++			opts->atari = 0;
++			break;
+ 		case Opt_uid:
+ 			if (match_int(&args[0], &option))
+ 				return 0;
+@@ -1250,8 +1268,31 @@
+ 
+ 	total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
+ 
+-	if (sbi->fat_bits != 32)
+-		sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
++	if (!sbi->options.atari) {
++		if (sbi->fat_bits != 32)
++			sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
++	} else {
++		int sectors;
++		/* Atari GEMDOS partitions always have 16-bit fat */
++		if (sbi->fat_bits != 32)
++			sbi->fat_bits = 16;
++		/* If more clusters than fat entries in 16-bit fat, we assume
++		 * it's a real MSDOS partition with 12-bit fat.
++		 */
++		if (sbi->fat_bits != 32 && total_clusters+2 > sbi->
++			fat_length*SECTOR_SIZE*8/sbi->fat_bits)
++			sbi->fat_bits = 12;
++		/* if it's a floppy disk --> 12bit fat */
++		if (sbi->fat_bits != 32 && MAJOR(sb->s_dev) == FLOPPY_MAJOR)
++			sbi->fat_bits = 12;
++		/* if it's a ramdisk or loopback device and has one of the usual
++		 * floppy sizes -> 12bit FAT  */
++		sectors = total_sectors + sbi->data_start;
++		if (sbi->fat_bits != 32 && (MAJOR(sb->s_dev) == RAMDISK_MAJOR ||
++			 MAJOR(sb->s_dev) == LOOP_MAJOR) &&
++			(sectors == 720 || sectors == 1440 || sectors == 2880))
++			sbi->fat_bits = 12;
++	}
+ 
+ 	/* check that FAT table does not overflow */
+ 	fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/hardirq.h linux-m68k/include/asm-m68k/hardirq.h
+--- linux-i386/include/asm-m68k/hardirq.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/asm-m68k/hardirq.h	2005-11-01 16:33:46.000000000 +0100
+@@ -4,6 +4,7 @@
+ #include <linux/config.h>
+ #include <linux/threads.h>
+ #include <linux/cache.h>
++#include <asm/irq.h>
+ 
+ /* entry.S is sensitive to the offsets of these fields */
+ typedef struct {
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/io.h linux-m68k/include/asm-m68k/io.h
+--- linux-i386/include/asm-m68k/io.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/asm-m68k/io.h	2005-06-19 16:35:42.000000000 +0200
+@@ -324,8 +324,6 @@
+ #define writel(val,addr) out_le32((addr),(val))
+ #endif
+ 
+-#define mmiowb()
+-
+ static inline void *ioremap(unsigned long physaddr, unsigned long size)
+ {
+ 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/irq.h linux-m68k/include/asm-m68k/irq.h
+--- linux-i386/include/asm-m68k/irq.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/asm-m68k/irq.h	2005-11-01 16:33:46.000000000 +0100
+@@ -2,7 +2,6 @@
+ #define _M68K_IRQ_H_
+ 
+ #include <linux/config.h>
+-#include <linux/interrupt.h>
+ 
+ /*
+  * # of m68k interrupts
+@@ -77,7 +76,7 @@
+ struct pt_regs;
+ 
+ extern int cpu_request_irq(unsigned int,
+-			   irqreturn_t (*)(int, void *, struct pt_regs *),
++			   int (*)(int, void *, struct pt_regs *),
+ 			   unsigned long, const char *, void *);
+ extern void cpu_free_irq(unsigned int, void *);
+ 
+@@ -99,7 +98,7 @@
+  * interrupt source (if it supports chaining).
+  */
+ typedef struct irq_node {
+-	irqreturn_t	(*handler)(int, void *, struct pt_regs *);
++	int		(*handler)(int, void *, struct pt_regs *);
+ 	unsigned long	flags;
+ 	void		*dev_id;
+ 	const char	*devname;
+@@ -110,7 +109,7 @@
+  * This structure has only 4 elements for speed reasons
+  */
+ typedef struct irq_handler {
+-	irqreturn_t	(*handler)(int, void *, struct pt_regs *);
++	int		(*handler)(int, void *, struct pt_regs *);
+ 	unsigned long	flags;
+ 	void		*dev_id;
+ 	const char	*devname;
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/processor.h linux-m68k/include/asm-m68k/processor.h
+--- linux-i386/include/asm-m68k/processor.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/asm-m68k/processor.h	2005-05-30 16:33:26.000000000 +0200
+@@ -14,6 +14,7 @@
+ #define current_text_addr() ({ __label__ _l; _l: &&_l;})
+ 
+ #include <linux/config.h>
++#include <linux/thread_info.h>
+ #include <asm/segment.h>
+ #include <asm/fpu.h>
+ #include <asm/ptrace.h>
+@@ -55,17 +56,6 @@
+ #endif
+ #define TASK_UNMAPPED_ALIGN(addr, off)	PAGE_ALIGN(addr)
+ 
+-struct task_work {
+-	unsigned char sigpending;
+-	unsigned char notify_resume;	/* request for notification on
+-					   userspace execution resumption */
+-	char          need_resched;
+-	unsigned char delayed_trace;	/* single step a syscall */
+-	unsigned char syscall_trace;	/* count of syscall interceptors */
+-	unsigned char memdie;		/* task was selected to be killed */
+-	unsigned char pad[2];
+-};
+-
+ struct thread_struct {
+ 	unsigned long  ksp;		/* kernel stack pointer */
+ 	unsigned long  usp;		/* user stack pointer */
+@@ -78,7 +68,7 @@
+ 	unsigned long  fp[8*3];
+ 	unsigned long  fpcntl[3];	/* fp control regs */
+ 	unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
+-	struct task_work work;
++	struct thread_info info;
+ };
+ 
+ #define INIT_THREAD  {							\
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/serial.h linux-m68k/include/asm-m68k/serial.h
+--- linux-i386/include/asm-m68k/serial.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/asm-m68k/serial.h	2005-08-30 16:36:03.000000000 +0200
+@@ -26,9 +26,11 @@
+ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
+ #endif
+ 
++#ifdef CONFIG_ISA
+ #define SERIAL_PORT_DFNS			\
+ 	/* UART CLK   PORT IRQ     FLAGS        */			\
+ 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
+ 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
+ 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
+ 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
++#endif
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/asm-m68k/thread_info.h linux-m68k/include/asm-m68k/thread_info.h
+--- linux-i386/include/asm-m68k/thread_info.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/asm-m68k/thread_info.h	2005-08-30 16:36:04.000000000 +0200
+@@ -2,17 +2,15 @@
+ #define _ASM_M68K_THREAD_INFO_H
+ 
+ #include <asm/types.h>
+-#include <asm/processor.h>
+ #include <asm/page.h>
+ 
+ struct thread_info {
+ 	struct task_struct	*task;		/* main task structure */
++	unsigned long		flags;
+ 	struct exec_domain	*exec_domain;	/* execution domain */
+ 	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
+ 	__u32 cpu; /* should always be 0 on m68k */
+ 	struct restart_block    restart_block;
+-
+-	__u8			supervisor_stack[0];
+ };
+ 
+ #define PREEMPT_ACTIVE		0x4000000
+@@ -28,91 +26,34 @@
+ 
+ /* THREAD_SIZE should be 8k, so handle differently for 4k and 8k machines */
+ #if PAGE_SHIFT == 13 /* 8k machines */
+-#define alloc_thread_info(tsk)   ((struct thread_info *)__get_free_pages(GFP_KERNEL,0))
+-#define free_thread_info(ti)  free_pages((unsigned long)(ti),0)
++#define alloc_thread_stack(tsk) ((void *)__get_free_pages(GFP_KERNEL,0))
++#define free_thread_stack(ti)  free_pages((unsigned long)(ti),0)
+ #else /* otherwise assume 4k pages */
+-#define alloc_thread_info(tsk)   ((struct thread_info *)__get_free_pages(GFP_KERNEL,1))
+-#define free_thread_info(ti)  free_pages((unsigned long)(ti),1)
++#define alloc_thread_stack(tsk) ((void *)__get_free_pages(GFP_KERNEL,1))
++#define free_thread_stack(ti)  free_pages((unsigned long)(ti),1)
+ #endif /* PAGE_SHIFT == 13 */
+ 
+ //#define init_thread_info	(init_task.thread.info)
+ #define init_stack		(init_thread_union.stack)
+ 
+-#define current_thread_info()	(current->thread_info)
++#define task_thread_info(tsk)	(&(tsk)->thread.info)
++#define current_thread_info()	task_thread_info(current)
+ 
++#define setup_thread_stack(p, org) ({			\
++	*(struct task_struct **)(p)->stack = (p);	\
++	task_thread_info(p)->task = (p);		\
++})
+ 
+ #define __HAVE_THREAD_FUNCTIONS
+ 
+-#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+-#define TIF_DELAYED_TRACE	1	/* single step a syscall */
+-#define TIF_NOTIFY_RESUME	2	/* resumption notification requested */
+-#define TIF_SIGPENDING		3	/* signal pending */
+-#define TIF_NEED_RESCHED	4	/* rescheduling necessary */
+-#define TIF_MEMDIE		5
+-
+-extern int thread_flag_fixme(void);
+-
+-/*
+- * flag set/clear/test wrappers
+- * - pass TIF_xxxx constants to these functions
++/* entry.S relies on these definitions!
++ * bits 0-7 are tested at every exception exit
++ * bits 8-15 are also tested at syscall exit
+  */
+-
+-#define __set_tsk_thread_flag(tsk, flag, val) ({	\
+-	switch (flag) {					\
+-	case TIF_SIGPENDING:				\
+-		tsk->thread.work.sigpending = val;	\
+-		break;					\
+-	case TIF_NEED_RESCHED:				\
+-		tsk->thread.work.need_resched = val;	\
+-		break;					\
+-	case TIF_SYSCALL_TRACE:				\
+-		tsk->thread.work.syscall_trace = val;	\
+-		break;					\
+-	case TIF_MEMDIE:				\
+-		tsk->thread.work.memdie = val;		\
+-		break;					\
+-	default:					\
+-		thread_flag_fixme();			\
+-	}						\
+-})
+-
+-#define __get_tsk_thread_flag(tsk, flag) ({		\
+-	int ___res;					\
+-	switch (flag) {					\
+-	case TIF_SIGPENDING:				\
+-		___res = tsk->thread.work.sigpending;	\
+-		break;					\
+-	case TIF_NEED_RESCHED:				\
+-		___res = tsk->thread.work.need_resched;	\
+-		break;					\
+-	case TIF_SYSCALL_TRACE:				\
+-		___res = tsk->thread.work.syscall_trace;\
+-		break;					\
+-	case TIF_MEMDIE:				\
+-		___res = tsk->thread.work.memdie;\
+-		break;					\
+-	default:					\
+-		___res = thread_flag_fixme();		\
+-	}						\
+-	___res;						\
+-})
+-
+-#define __get_set_tsk_thread_flag(tsk, flag, val) ({	\
+-	int __res = __get_tsk_thread_flag(tsk, flag);	\
+-	__set_tsk_thread_flag(tsk, flag, val);		\
+-	__res;						\
+-})
+-
+-#define set_tsk_thread_flag(tsk, flag) __set_tsk_thread_flag(tsk, flag, ~0)
+-#define clear_tsk_thread_flag(tsk, flag) __set_tsk_thread_flag(tsk, flag, 0)
+-#define test_and_set_tsk_thread_flag(tsk, flag) __get_set_tsk_thread_flag(tsk, flag, ~0)
+-#define test_tsk_thread_flag(tsk, flag) __get_tsk_thread_flag(tsk, flag)
+-
+-#define set_thread_flag(flag) set_tsk_thread_flag(current, flag)
+-#define clear_thread_flag(flag) clear_tsk_thread_flag(current, flag)
+-#define test_thread_flag(flag) test_tsk_thread_flag(current, flag)
+-
+-#define set_need_resched() set_thread_flag(TIF_NEED_RESCHED)
+-#define clear_need_resched() clear_thread_flag(TIF_NEED_RESCHED)
++#define TIF_SIGPENDING		6	/* signal pending */
++#define TIF_NEED_RESCHED	7	/* rescheduling necessary */
++#define TIF_DELAYED_TRACE	14	/* single step a syscall */
++#define TIF_SYSCALL_TRACE	15	/* syscall trace active */
++#define TIF_MEMDIE		16
+ 
+ #endif	/* _ASM_M68K_THREAD_INFO_H */
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/adb.h linux-m68k/include/linux/adb.h
+--- linux-i386/include/linux/adb.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/linux/adb.h	2003-03-25 20:25:16.000000000 +0100
+@@ -76,6 +76,7 @@
+ #define ADBREQ_REPLY	1	/* expect reply */
+ #define ADBREQ_SYNC	2	/* poll until done */
+ #define ADBREQ_NOSEND	4	/* build the request, but don't send it */
++#define ADBREQ_RAW	8	/* send raw packet (don't prepend ADB_PACKET) */
+ 
+ /* Messages sent thru the client_list notifier. You should NOT stop
+    the operation, at least not with this version */
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/bootmem.h linux-m68k/include/linux/bootmem.h
+--- linux-i386/include/linux/bootmem.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/linux/bootmem.h	2005-10-29 10:43:54.000000000 +0200
+@@ -49,11 +49,11 @@
+ #define alloc_bootmem(x) \
+ 	__alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
+ #define alloc_bootmem_low(x) \
+-	__alloc_bootmem((x), SMP_CACHE_BYTES, 0)
++	__alloc_bootmem((x), SMP_CACHE_BYTES, __pa(PAGE_OFFSET))
+ #define alloc_bootmem_pages(x) \
+ 	__alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
+ #define alloc_bootmem_low_pages(x) \
+-	__alloc_bootmem((x), PAGE_SIZE, 0)
++	__alloc_bootmem((x), PAGE_SIZE, __pa(PAGE_OFFSET))
+ 
+ #define alloc_bootmem_limit(x, limit)						\
+ 	__alloc_bootmem_limit((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS), (limit))
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/file.h linux-m68k/include/linux/file.h
+--- linux-i386/include/linux/file.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/linux/file.h	2005-11-01 16:34:09.000000000 +0100
+@@ -5,7 +5,6 @@
+ #ifndef __LINUX_FILE_H
+ #define __LINUX_FILE_H
+ 
+-#include <asm/atomic.h>
+ #include <linux/posix_types.h>
+ #include <linux/compiler.h>
+ #include <linux/spinlock.h>
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/ide.h linux-m68k/include/linux/ide.h
+--- linux-i386/include/linux/ide.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/linux/ide.h	2005-08-30 16:36:33.000000000 +0200
+@@ -592,7 +592,7 @@
+  * sense_key	: Sense key of the last failed packet command
+  */
+ typedef union {
+-	unsigned all			:8;
++	u8 all;
+ 	struct {
+ #if defined(__LITTLE_ENDIAN_BITFIELD)
+ 		unsigned ili		:1;
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/init_task.h linux-m68k/include/linux/init_task.h
+--- linux-i386/include/linux/init_task.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/linux/init_task.h	2005-10-29 10:43:55.000000000 +0200
+@@ -80,7 +80,7 @@
+ #define INIT_TASK(tsk)	\
+ {									\
+ 	.state		= 0,						\
+-	.thread_info	= &init_thread_info,				\
++	.stack		= &init_stack,					\
+ 	.usage		= ATOMIC_INIT(2),				\
+ 	.flags		= 0,						\
+ 	.lock_depth	= -1,						\
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/interrupt.h linux-m68k/include/linux/interrupt.h
+--- linux-i386/include/linux/interrupt.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/linux/interrupt.h	2005-10-29 10:43:55.000000000 +0200
+@@ -9,6 +9,7 @@
+ #include <linux/preempt.h>
+ #include <linux/cpumask.h>
+ #include <linux/hardirq.h>
++#include <linux/sched.h>
+ #include <asm/atomic.h>
+ #include <asm/ptrace.h>
+ #include <asm/system.h>
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/sched.h linux-m68k/include/linux/sched.h
+--- linux-i386/include/linux/sched.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/linux/sched.h	2005-10-29 10:43:57.000000000 +0200
+@@ -641,7 +641,8 @@
+ 
+ struct task_struct {
+ 	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
+-	struct thread_info *thread_info;
++	//struct thread_info *thread_info;
++	void *stack;
+ 	atomic_t usage;
+ 	unsigned long flags;	/* per process flags, defined below */
+ 	unsigned long ptrace;
+@@ -1182,32 +1183,50 @@
+ 	spin_unlock(&p->alloc_lock);
+ }
+ 
++#ifndef __HAVE_THREAD_FUNCTIONS
++
++#define task_thread_info(task) ((struct thread_info *)(task)->stack)
++
++static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
++{
++	*task_thread_info(p) = *task_thread_info(org);
++	task_thread_info(p)->task = p;
++}
++
++static inline unsigned long *end_of_stack(struct task_struct *p)
++{
++	return (unsigned long *)(task_thread_info(p)(p) + 1);
++}
++
++#endif
++
+ /* set thread flags in other task's structures
+  * - see asm/thread_info.h for TIF_xxxx flags available
+  */
++
+ static inline void set_tsk_thread_flag(struct task_struct *tsk, int flag)
+ {
+-	set_ti_thread_flag(tsk->thread_info,flag);
++	set_ti_thread_flag(task_thread_info(tsk), flag);
+ }
+ 
+ static inline void clear_tsk_thread_flag(struct task_struct *tsk, int flag)
+ {
+-	clear_ti_thread_flag(tsk->thread_info,flag);
++	clear_ti_thread_flag(task_thread_info(tsk), flag);
+ }
+ 
+ static inline int test_and_set_tsk_thread_flag(struct task_struct *tsk, int flag)
+ {
+-	return test_and_set_ti_thread_flag(tsk->thread_info,flag);
++	return test_and_set_ti_thread_flag(task_thread_info(tsk), flag);
+ }
+ 
+ static inline int test_and_clear_tsk_thread_flag(struct task_struct *tsk, int flag)
+ {
+-	return test_and_clear_ti_thread_flag(tsk->thread_info,flag);
++	return test_and_clear_ti_thread_flag(task_thread_info(tsk), flag);
+ }
+ 
+ static inline int test_tsk_thread_flag(struct task_struct *tsk, int flag)
+ {
+-	return test_ti_thread_flag(tsk->thread_info,flag);
++	return test_ti_thread_flag(task_thread_info(tsk), flag);
+ }
+ 
+ static inline void set_tsk_need_resched(struct task_struct *tsk)
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/smp_lock.h linux-m68k/include/linux/smp_lock.h
+--- linux-i386/include/linux/smp_lock.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/linux/smp_lock.h	2005-04-25 23:13:18.000000000 +0200
+@@ -2,7 +2,6 @@
+ #define __LINUX_SMPLOCK_H
+ 
+ #include <linux/config.h>
+-#include <linux/sched.h>
+ #include <linux/spinlock.h>
+ 
+ #ifdef CONFIG_LOCK_KERNEL
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/include/linux/thread_info.h linux-m68k/include/linux/thread_info.h
+--- linux-i386/include/linux/thread_info.h	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/include/linux/thread_info.h	2005-05-30 16:33:47.000000000 +0200
+@@ -27,31 +27,6 @@
+  * - pass TIF_xxxx constants to these functions
+  */
+ 
+-static inline void set_thread_flag(int flag)
+-{
+-	set_bit(flag,&current_thread_info()->flags);
+-}
+-
+-static inline void clear_thread_flag(int flag)
+-{
+-	clear_bit(flag,&current_thread_info()->flags);
+-}
+-
+-static inline int test_and_set_thread_flag(int flag)
+-{
+-	return test_and_set_bit(flag,&current_thread_info()->flags);
+-}
+-
+-static inline int test_and_clear_thread_flag(int flag)
+-{
+-	return test_and_clear_bit(flag,&current_thread_info()->flags);
+-}
+-
+-static inline int test_thread_flag(int flag)
+-{
+-	return test_bit(flag,&current_thread_info()->flags);
+-}
+-
+ static inline void set_ti_thread_flag(struct thread_info *ti, int flag)
+ {
+ 	set_bit(flag,&ti->flags);
+@@ -77,16 +52,20 @@
+ 	return test_bit(flag,&ti->flags);
+ }
+ 
+-static inline void set_need_resched(void)
+-{
+-	set_thread_flag(TIF_NEED_RESCHED);
+-}
++#define set_thread_flag(flag) \
++	set_ti_thread_flag(current_thread_info(), flag)
++#define clear_thread_flag(flag) \
++	clear_ti_thread_flag(current_thread_info(), flag)
++#define test_and_set_thread_flag(flag) \
++	test_and_set_ti_thread_flag(current_thread_info(), flag)
++#define test_and_clear_thread_flag(flag) \
++	test_and_clear_ti_thread_flag(current_thread_info(), flag)
++#define test_thread_flag(flag) \
++	test_ti_thread_flag(current_thread_info(), flag)
+ 
+-static inline void clear_need_resched(void)
+-{
+-	clear_thread_flag(TIF_NEED_RESCHED);
+-}
++#define set_need_resched()	set_thread_flag(TIF_NEED_RESCHED)
++#define clear_need_resched()	clear_thread_flag(TIF_NEED_RESCHED)
+ 
+-#endif
++#endif	/* __KERNEL__ */
+ 
+ #endif /* _LINUX_THREAD_INFO_H */
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/kernel/exit.c linux-m68k/kernel/exit.c
+--- linux-i386/kernel/exit.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/kernel/exit.c	2005-10-29 10:44:04.000000000 +0200
+@@ -859,7 +859,7 @@
+ 	if (group_dead && tsk->signal->leader)
+ 		disassociate_ctty(1);
+ 
+-	module_put(tsk->thread_info->exec_domain->module);
++	module_put(task_thread_info(tsk)->exec_domain->module);
+ 	if (tsk->binfmt)
+ 		module_put(tsk->binfmt->module);
+ 
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/kernel/fork.c linux-m68k/kernel/fork.c
+--- linux-i386/kernel/fork.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/kernel/fork.c	2005-10-29 10:44:04.000000000 +0200
+@@ -101,7 +101,7 @@
+ 
+ void free_task(struct task_struct *tsk)
+ {
+-	free_thread_info(tsk->thread_info);
++	free_thread_stack(tsk->stack);
+ 	free_task_struct(tsk);
+ }
+ EXPORT_SYMBOL(free_task);
+@@ -156,7 +156,7 @@
+ static struct task_struct *dup_task_struct(struct task_struct *orig)
+ {
+ 	struct task_struct *tsk;
+-	struct thread_info *ti;
++	void *stack;
+ 
+ 	prepare_to_copy(orig);
+ 
+@@ -164,16 +164,16 @@
+ 	if (!tsk)
+ 		return NULL;
+ 
+-	ti = alloc_thread_info(tsk);
+-	if (!ti) {
++	stack = alloc_thread_stack(tsk);
++	if (!stack) {
+ 		free_task_struct(tsk);
+ 		return NULL;
+ 	}
+ 
+-	*ti = *orig->thread_info;
+ 	*tsk = *orig;
+-	tsk->thread_info = ti;
+-	ti->task = tsk;
++	tsk->stack = stack;
++	*(struct task_struct **)tsk->stack = tsk;
++	setup_thread_stack(tsk, orig);
+ 
+ 	/* One for us, one for whoever does the "release_task()" (usually parent) */
+ 	atomic_set(&tsk->usage,2);
+@@ -928,7 +928,7 @@
+ 	if (nr_threads >= max_threads)
+ 		goto bad_fork_cleanup_count;
+ 
+-	if (!try_module_get(p->thread_info->exec_domain->module))
++	if (!try_module_get(task_thread_info(p)->exec_domain->module))
+ 		goto bad_fork_cleanup_count;
+ 
+ 	if (p->binfmt && !try_module_get(p->binfmt->module))
+@@ -1188,7 +1188,7 @@
+ 	if (p->binfmt)
+ 		module_put(p->binfmt->module);
+ bad_fork_cleanup_put_domain:
+-	module_put(p->thread_info->exec_domain->module);
++	module_put(task_thread_info(p)->exec_domain->module);
+ bad_fork_cleanup_count:
+ 	put_group_info(p->group_info);
+ 	atomic_dec(&p->user->processes);
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/kernel/sched.c linux-m68k/kernel/sched.c
+--- linux-i386/kernel/sched.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/kernel/sched.c	2005-10-29 10:44:05.000000000 +0200
+@@ -4230,10 +4230,10 @@
+ #endif
+ #ifdef CONFIG_DEBUG_STACK_USAGE
+ 	{
+-		unsigned long *n = (unsigned long *) (p->thread_info+1);
++		unsigned long *n = end_of_stack(p);
+ 		while (!*n)
+ 			n++;
+-		free = (unsigned long) n - (unsigned long)(p->thread_info+1);
++		free = (unsigned long) n - (unsigned long) end_of_stack(p);
+ 	}
+ #endif
+ 	printk("%5lu %5d %6d ", free, p->pid, p->parent->pid);
+@@ -4313,9 +4313,9 @@
+ 
+ 	/* Set the preempt count _outside_ the spinlocks! */
+ #if defined(CONFIG_PREEMPT) && !defined(CONFIG_PREEMPT_BKL)
+-	idle->thread_info->preempt_count = (idle->lock_depth >= 0);
++	task_thread_info(idle)->preempt_count = (idle->lock_depth >= 0);
+ #else
+-	idle->thread_info->preempt_count = 0;
++	task_thread_info(idle)->preempt_count = 0;
+ #endif
+ }
+ 
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/lib/kref.c linux-m68k/lib/kref.c
+--- linux-i386/lib/kref.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/lib/kref.c	2005-11-01 16:34:19.000000000 +0100
+@@ -11,8 +11,8 @@
+  *
+  */
+ 
+-#include <linux/kref.h>
+ #include <linux/module.h>
++#include <linux/kref.h>
+ 
+ /**
+  * kref_init - initialize object.
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/mm/bootmem.c linux-m68k/mm/bootmem.c
+--- linux-i386/mm/bootmem.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/mm/bootmem.c	2005-10-29 10:44:06.000000000 +0200
+@@ -283,7 +283,6 @@
+ 
+ 	count = 0;
+ 	/* first extant page of the node */
+-	pfn = bdata->node_boot_start >> PAGE_SHIFT;
+ 	idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
+ 	map = bdata->node_bootmem_map;
+ 	/* Check physaddr is O(LOG2(BITS_PER_LONG)) page aligned */
+@@ -296,7 +295,8 @@
+ 		if (gofast && v == ~0UL) {
+ 			int j, order;
+ 
+-			page = pfn_to_page(pfn);
++			page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) +
++							 bdata->node_boot_start));
+ 			count += BITS_PER_LONG;
+ 			__ClearPageReserved(page);
+ 			order = ffs(BITS_PER_LONG) - 1;
+@@ -308,23 +308,20 @@
+ 			}
+ 			__free_pages(page, order);
+ 			i += BITS_PER_LONG;
+-			page += BITS_PER_LONG;
+ 		} else if (v) {
+ 			unsigned long m;
+-
+-			page = pfn_to_page(pfn);
+-			for (m = 1; m && i < idx; m<<=1, page++, i++) {
++			for (m = 1; m && i < idx; m<<=1, i++) {
+ 				if (v & m) {
++					page = virt_to_page(phys_to_virt((i << PAGE_SHIFT) +
++									 bdata->node_boot_start));
+ 					count++;
+ 					__ClearPageReserved(page);
+ 					set_page_refs(page, 0);
+ 					__free_page(page);
+ 				}
+ 			}
+-		} else {
++		} else
+ 			i+=BITS_PER_LONG;
+-		}
+-		pfn += BITS_PER_LONG;
+ 	}
+ 	total += count;
+ 
+diff -urN --exclude-from=/usr/src/exclude-file linux-i386/net/ipv4/raw.c linux-m68k/net/ipv4/raw.c
+--- linux-i386/net/ipv4/raw.c	2005-10-28 02:02:08.000000000 +0200
++++ linux-m68k/net/ipv4/raw.c	2005-11-01 16:34:26.000000000 +0100
+@@ -40,7 +40,6 @@
+  */
+  
+ #include <linux/config.h> 
+-#include <asm/atomic.h>
+ #include <asm/byteorder.h>
+ #include <asm/current.h>
+ #include <asm/uaccess.h>

Added: people/waldi/linux-2.6/debian/patches/m68k-mvme147.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/m68k-mvme147.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,10 @@
+--- linux-2.6-2.6.14/arch/m68k/mvme147/147ints.c.orig	2005-10-28 02:02:08.000000000 +0200
++++ linux-2.6-2.6.14/arch/m68k/mvme147/147ints.c	2005-11-08 08:31:05.000000000 +0100
+@@ -15,6 +15,7 @@
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/seq_file.h>
++#include <linux/interrupt.h>
+ 
+ #include <asm/ptrace.h>
+ #include <asm/system.h>

Added: people/waldi/linux-2.6/debian/patches/m68k-mvme16x.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/m68k-mvme16x.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,10 @@
+--- linux-2.6-2.6.14/arch/m68k/mvme16x/16xints.c.orig	2005-10-28 02:02:08.000000000 +0200
++++ linux-2.6-2.6.14/arch/m68k/mvme16x/16xints.c	2005-11-08 08:32:28.000000000 +0100
+@@ -15,6 +15,7 @@
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+ #include <linux/seq_file.h>
++#include <linux/interrupt.h>
+ 
+ #include <asm/system.h>
+ #include <asm/ptrace.h>

Added: people/waldi/linux-2.6/debian/patches/m68k-spinlock.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/m68k-spinlock.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,33 @@
+--- linux-2.6-2.6.14/kernel/audit.c.orig	2005-10-28 02:02:08.000000000 +0200
++++ linux-2.6-2.6.14/kernel/audit.c	2005-11-08 22:29:43.000000000 +0100
+@@ -41,6 +41,7 @@
+  * Example user-space utilities: http://people.redhat.com/sgrubb/audit/
+  */
+ 
++#include <linux/spinlock.h>
+ #include <linux/init.h>
+ #include <asm/atomic.h>
+ #include <asm/types.h>
+--- linux-2.6-2.6.14/include/linux/dcache.h.orig	2005-10-28 02:02:08.000000000 +0200
++++ linux-2.6-2.6.14/include/linux/dcache.h	2005-11-08 22:19:45.000000000 +0100
+@@ -3,9 +3,9 @@
+ 
+ #ifdef __KERNEL__
+ 
++#include <linux/spinlock.h>
+ #include <asm/atomic.h>
+ #include <linux/list.h>
+-#include <linux/spinlock.h>
+ #include <linux/cache.h>
+ #include <linux/rcupdate.h>
+ #include <asm/bug.h>
+--- linux-2.6-2.6.14/drivers/md/kcopyd.c.orig	2005-10-28 02:02:08.000000000 +0200
++++ linux-2.6-2.6.14/drivers/md/kcopyd.c	2005-11-08 22:46:17.000000000 +0100
+@@ -8,6 +8,7 @@
+  * completion notification.
+  */
+ 
++#include <linux/spinlock.h>
+ #include <asm/atomic.h>
+ 
+ #include <linux/blkdev.h>

Added: people/waldi/linux-2.6/debian/patches/modular-ide-pnp.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/modular-ide-pnp.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,74 @@
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Description: Allow modular built of ide-pnp
+## DP: Patch author: Herbert Xu, Christoph Hellwig
+## DP: Upstream status: submitted
+#
+diff -aurN a/drivers/ide/Kconfig b/drivers/ide/Kconfig
+--- a/drivers/ide/Kconfig	2005-06-06 11:22:29.000000000 -0400
++++ b/drivers/ide/Kconfig	2005-06-15 22:15:06.000000000 -0400
+@@ -315,7 +315,7 @@
+ 	  Otherwise say N.
+ 
+ config BLK_DEV_IDEPNP
+-	bool "PNP EIDE support"
++	tristate "PNP EIDE support"
+ 	depends on PNP
+ 	help
+ 	  If you have a PnP (Plug and Play) compatible EIDE card and
+diff -aurN a/drivers/ide/Makefile b/drivers/ide/Makefile
+--- a/drivers/ide/Makefile	2005-06-06 11:22:29.000000000 -0400
++++ b/drivers/ide/Makefile	2005-06-15 22:15:06.000000000 -0400
+@@ -23,6 +23,5 @@
+ ide-core-$(CONFIG_BLK_DEV_IDEDMA)	+= ide-dma.o
+ ide-core-$(CONFIG_PROC_FS)		+= ide-proc.o
+-ide-core-$(CONFIG_BLK_DEV_IDEPNP)	+= ide-pnp.o
+ 
+ # built-in only drivers from arm/
+ ide-core-$(CONFIG_IDE_ARM)		+= arm/ide_arm.o
+@@ -43,6 +42,7 @@
+ 
+ obj-$(CONFIG_BLK_DEV_IDE)		+= ide-core.o
+ obj-$(CONFIG_IDE_GENERIC)		+= ide-generic.o
++obj-$(CONFIG_BLK_DEV_IDEPNP)		+= ide-pnp.o
+ 
+ obj-$(CONFIG_BLK_DEV_IDEDISK)		+= ide-disk.o
+ obj-$(CONFIG_BLK_DEV_IDECD)		+= ide-cd.o
+diff -aurN a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
+--- a/drivers/ide/ide-pnp.c	2005-06-06 11:22:29.000000000 -0400
++++ b/drivers/ide/ide-pnp.c	2005-06-15 22:15:06.000000000 -0400
+@@ -69,7 +69,21 @@
+ 	.remove		= idepnp_remove,
+ };
+ 
+-void __init pnpide_init(void)
++int __init pnpide_init(void)
+ {
+-	pnp_register_driver(&idepnp_driver);
++	return pnp_register_driver(&idepnp_driver);
+ }
++
++#ifdef MODULE
++static void __exit pnpide_exit(void)
++{
++       pnp_unregister_driver(&idepnp_driver);
++}
++
++module_init(pnpide_init);
++module_exit(pnpide_exit);
++#endif
++
++MODULE_AUTHOR("Andrey Panin");
++MODULE_DESCRIPTION("Enabler for ISAPNP IDE devices");
++MODULE_LICENSE("GPL");
+diff -aurN a/drivers/ide/ide.c b/drivers/ide/ide.c
+--- a/drivers/ide/ide.c	2005-06-06 11:22:29.000000000 -0400
++++ b/drivers/ide/ide.c	2005-06-15 22:15:06.000000000 -0400
+@@ -1789,7 +1789,7 @@
+ 	return 1;
+ }
+ 
+-extern void pnpide_init(void);
++extern int pnpide_init(void);
+ extern void h8300_ide_init(void);
+ 
+ /*

Added: people/waldi/linux-2.6/debian/patches/powerpc-apus.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/powerpc-apus.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,3355 @@
+# 
+# PowerPC/Apus support patch
+# Needed support for Amiga PowerUP boards.
+# Author: mostly Roman Zippel <zippel at linux-m68k.org>
+# Upstream status: got synced with 2.6.12 recently, so in better status than
+# previous apus patches. Only 81k left.
+# This is the part which do not interact with non-apus powerpc subarche, either
+# in amiga subdirectories, #ifdefed CONFIG_APUS or mostly a no-op in the absence 
+# of CONFIG_APUS. Another patch is left which is of more dubious quality, and which
+# i will not apply by default.
+#
+
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/Kconfig linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/Kconfig
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/Kconfig	2005-12-25 12:11:25.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/Kconfig	2005-12-29 09:27:43.000000000 +0000
+@@ -537,7 +537,6 @@
+ 
+ config APUS
+ 	bool "Amiga-APUS"
+-	depends on BROKEN
+ 	help
+ 	  Select APUS if configuring for a PowerUP Amiga.
+ 	  More information is available at:
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/Makefile linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/Makefile
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/Makefile	2005-12-25 12:11:25.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/Makefile	2005-12-29 09:29:44.000000000 +0000
+@@ -59,9 +59,12 @@
+ head-$(CONFIG_44x)		:= arch/ppc/kernel/head_44x.o
+ head-$(CONFIG_FSL_BOOKE)	:= arch/ppc/kernel/head_fsl_booke.o
+ 
++head-y				+= arch/ppc/mm/hashtable.o
++head-y				+= arch/ppc/kernel/entry.o
+ head-$(CONFIG_6xx)		+= arch/ppc/kernel/idle_6xx.o
+ head-$(CONFIG_POWER4)		+= arch/ppc/kernel/idle_power4.o
+ head-$(CONFIG_PPC_FPU)		+= arch/powerpc/kernel/fpu.o
++head-y				+= arch/ppc/kernel/head_end.o
+ 
+ core-y				+= arch/ppc/kernel/ arch/powerpc/kernel/ \
+ 				   arch/ppc/platforms/ \
+@@ -84,7 +87,9 @@
+ 
+ .PHONY: $(BOOT_TARGETS)
+ 
++ifndef CONFIG_APUS
+ all: uImage zImage
++endif
+ 
+ CPPFLAGS_vmlinux.lds	:= -Upowerpc
+ 
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/amiga/Makefile linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/amiga/Makefile
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/amiga/Makefile	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/amiga/Makefile	2005-12-29 09:27:43.000000000 +0000
+@@ -1,8 +1,8 @@
+ #
+-# Makefile for Linux arch/m68k/amiga source directory
++# Makefile for Linux arch/ppc/amiga source directory
+ #
+ 
+-obj-y		:= config.o amiints.o cia.o time.o bootinfo.o amisound.o \
+-			chipram.o amiga_ksyms.o
++obj-y	:= config.o amiints.o cia.o bootinfo.o \
++	   amisound.o chipram.o amiga_ksyms.o
+ 
+ obj-$(CONFIG_AMIGA_PCMCIA) += pcmcia.o
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/amiga/amiints.c linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/amiga/amiints.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/amiga/amiints.c	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/amiga/amiints.c	2005-12-29 09:27:43.000000000 +0000
+@@ -67,9 +67,10 @@
+ 
+ static short ami_ablecount[AMI_IRQS];
+ 
+-static void ami_badint(int irq, void *dev_id, struct pt_regs *fp)
++static irqreturn_t ami_badint(int irq, void *dev_id, struct pt_regs *fp)
+ {
+ /*	num_spurious += 1;*/
++	return IRQ_NONE;
+ }
+ 
+ /*
+@@ -206,7 +207,7 @@
+  * The builtin Amiga hardware interrupt handlers.
+  */
+ 
+-static void ami_int1(int irq, void *dev_id, struct pt_regs *fp)
++static irqreturn_t ami_int1(int irq, void *dev_id, struct pt_regs *fp)
+ {
+ 	unsigned short ints = custom.intreqr & custom.intenar;
+ 
+@@ -227,9 +228,10 @@
+ 		custom.intreq = IF_SOFT;
+ 		amiga_do_irq(IRQ_AMIGA_SOFT, fp);
+ 	}
++	return IRQ_HANDLED;
+ }
+ 
+-static void ami_int3(int irq, void *dev_id, struct pt_regs *fp)
++static irqreturn_t ami_int3(int irq, void *dev_id, struct pt_regs *fp)
+ {
+ 	unsigned short ints = custom.intreqr & custom.intenar;
+ 
+@@ -248,9 +250,11 @@
+ 	/* if a vertical blank interrupt */
+ 	if (ints & IF_VERTB)
+ 		amiga_do_irq_list(IRQ_AMIGA_VERTB, fp);
++
++	return IRQ_HANDLED;
+ }
+ 
+-static void ami_int4(int irq, void *dev_id, struct pt_regs *fp)
++static irqreturn_t ami_int4(int irq, void *dev_id, struct pt_regs *fp)
+ {
+ 	unsigned short ints = custom.intreqr & custom.intenar;
+ 
+@@ -277,9 +281,10 @@
+ 		custom.intreq = IF_AUD3;
+ 		amiga_do_irq(IRQ_AMIGA_AUD3, fp);
+ 	}
++	return IRQ_HANDLED;
+ }
+ 
+-static void ami_int5(int irq, void *dev_id, struct pt_regs *fp)
++static irqreturn_t ami_int5(int irq, void *dev_id, struct pt_regs *fp)
+ {
+ 	unsigned short ints = custom.intreqr & custom.intenar;
+ 
+@@ -294,11 +299,13 @@
+ 		custom.intreq = IF_DSKSYN;
+ 		amiga_do_irq(IRQ_AMIGA_DSKSYN, fp);
+ 	}
++	return IRQ_HANDLED;
+ }
+ 
+-static void ami_int7(int irq, void *dev_id, struct pt_regs *fp)
++static irqreturn_t ami_int7(int irq, void *dev_id, struct pt_regs *fp)
+ {
+ 	panic ("level 7 interrupt received\n");
++	return IRQ_NONE;
+ }
+ 
+ #ifdef CONFIG_APUS
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/amiga/bootinfo.c linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/amiga/bootinfo.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/amiga/bootinfo.c	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/amiga/bootinfo.c	2005-12-29 09:27:44.000000000 +0000
+@@ -13,8 +13,9 @@
+ 
+ #include <asm/setup.h>
+ #include <asm/bootinfo.h>
++#include <asm/amigahw.h>
+ 
+-extern char cmd_line[CL_SIZE];
++extern char cmd_line[COMMAND_LINE_SIZE];
+ 
+ extern int num_memory;
+ extern int m68k_realnum_memory;
+@@ -23,8 +24,6 @@
+ extern struct mem_info ramdisk;
+ 
+ extern int amiga_parse_bootinfo(const struct bi_record *);
+-extern int atari_parse_bootinfo(const struct bi_record *);
+-extern int mac_parse_bootinfo(const struct bi_record *);
+ 
+ void __init parse_bootinfo(const struct bi_record *record)
+ {
+@@ -63,14 +62,7 @@
+ 		break;
+ 
+ 	    default:
+-		if (MACH_IS_AMIGA)
+-		    unknown = amiga_parse_bootinfo(record);
+-		else if (MACH_IS_ATARI)
+-		    unknown = atari_parse_bootinfo(record);
+-		else if (MACH_IS_MAC)
+-		    unknown = mac_parse_bootinfo(record);
+-		else
+-		    unknown = 1;
++	        unknown = amiga_parse_bootinfo(record);
+ 	}
+ 	if (unknown)
+ 	    printk("parse_bootinfo: unknown tag 0x%04x ignored\n",
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/amiga/cia.c linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/amiga/cia.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/amiga/cia.c	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/amiga/cia.c	2005-12-29 09:27:44.000000000 +0000
+@@ -134,7 +134,7 @@
+ 	return cia_able_irq_private(base, mask);
+ }
+ 
+-static void cia_handler(int irq, void *dev_id, struct pt_regs *fp)
++static irqreturn_t cia_handler(int irq, void *dev_id, struct pt_regs *fp)
+ {
+ 	struct ciabase *base = (struct ciabase *)dev_id;
+ 	irq_desc_t *desc;
+@@ -156,6 +156,7 @@
+ 		desc++;
+ 	}
+ 	amiga_do_irq_list(base->server_irq, fp);
++	return IRQ_HANDLED;
+ }
+ 
+ void __init cia_init_IRQ(struct ciabase *base)
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/amiga/config.c linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/amiga/config.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/amiga/config.c	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/amiga/config.c	2005-12-29 09:27:44.000000000 +0000
+@@ -20,11 +20,12 @@
+ #include <linux/mm.h>
+ #include <linux/kd.h>
+ #include <linux/tty.h>
++#include <linux/rtc.h>
+ #include <linux/console.h>
+ #include <linux/init.h>
+-#ifdef CONFIG_ZORRO
++#include <linux/interrupt.h>
+ #include <linux/zorro.h>
+-#endif
++#include <linux/delay.h>
+ 
+ #include <asm/bootinfo.h>
+ #include <asm/setup.h>
+@@ -71,29 +72,9 @@
+ 
+ extern char m68k_debug_device[];
+ 
+-static void amiga_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+-/* amiga specific irq functions */
+-extern void amiga_init_IRQ (void);
+-extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *);
+-extern int amiga_request_irq (unsigned int irq,
+-			      void (*handler)(int, void *, struct pt_regs *),
+-                              unsigned long flags, const char *devname,
+-			      void *dev_id);
+-extern void amiga_free_irq (unsigned int irq, void *dev_id);
+-extern void amiga_enable_irq (unsigned int);
+-extern void amiga_disable_irq (unsigned int);
+ static void amiga_get_model(char *model);
+ static int amiga_get_hardware_list(char *buffer);
+ /* amiga specific timer functions */
+-static unsigned long amiga_gettimeoffset (void);
+-static void a3000_gettod (int *, int *, int *, int *, int *, int *);
+-static void a2000_gettod (int *, int *, int *, int *, int *, int *);
+-static int amiga_hwclk (int, struct hwclk_time *);
+-static int amiga_set_clock_mmss (unsigned long);
+-#ifdef CONFIG_AMIGA_FLOPPY
+-extern void amiga_floppy_setup(char *, int *);
+-#endif
+-static void amiga_reset (void);
+ extern void amiga_init_sound(void);
+ static void amiga_savekmsg_init(void);
+ static void amiga_mem_console_write(struct console *co, const char *b,
+@@ -101,9 +82,6 @@
+ void amiga_serial_console_write(struct console *co, const char *s,
+ 				unsigned int count);
+ static void amiga_debug_init(void);
+-#ifdef CONFIG_HEARTBEAT
+-static void amiga_heartbeat(int on);
+-#endif
+ 
+ static struct console amiga_console_driver = {
+ 	.name =		"debug",
+@@ -384,48 +362,15 @@
+   for (i = 0; i < 4; i++)
+     request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]);
+ 
+-  mach_sched_init      = amiga_sched_init;
+-  mach_init_IRQ        = amiga_init_IRQ;
+-#ifndef CONFIG_APUS
+-  mach_default_handler = &amiga_default_handler;
+-  mach_request_irq     = amiga_request_irq;
+-  mach_free_irq        = amiga_free_irq;
+-  enable_irq           = amiga_enable_irq;
+-  disable_irq          = amiga_disable_irq;
+-#endif
+-  mach_get_model       = amiga_get_model;
+-  mach_get_hardware_list = amiga_get_hardware_list;
+-  mach_gettimeoffset   = amiga_gettimeoffset;
+   if (AMIGAHW_PRESENT(A3000_CLK)){
+-    mach_gettod  = a3000_gettod;
+     rtc_resource.name = "A3000 RTC";
+     request_resource(&iomem_resource, &rtc_resource);
+   }
+   else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */
+-    mach_gettod  = a2000_gettod;
+     rtc_resource.name = "A2000 RTC";
+     request_resource(&iomem_resource, &rtc_resource);
+   }
+ 
+-  mach_max_dma_address = 0xffffffff; /*
+-				      * default MAX_DMA=0xffffffff
+-				      * on all machines. If we don't
+-				      * do so, the SCSI code will not
+-				      * be able to allocate any mem
+-				      * for transfers, unless we are
+-				      * dealing with a Z2 mem only
+-				      * system.                  /Jes
+-				      */
+-
+-  mach_hwclk           = amiga_hwclk;
+-  mach_set_clock_mmss  = amiga_set_clock_mmss;
+-#ifdef CONFIG_AMIGA_FLOPPY
+-  mach_floppy_setup    = amiga_floppy_setup;
+-#endif
+-  mach_reset           = amiga_reset;
+-#ifdef CONFIG_HEARTBEAT
+-  mach_heartbeat = amiga_heartbeat;
+-#endif
+ 
+   /* Fill in the clock values (based on the 700 kHz E-Clock) */
+   amiga_masterclock = 40*amiga_eclock;	/* 28 MHz */
+@@ -473,242 +418,141 @@
+ 	  *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80;
+ }
+ 
+-static unsigned short jiffy_ticks;
+-
+-static void __init amiga_sched_init(irqreturn_t (*timer_routine)(int, void *,
+-						struct pt_regs *))
+-{
+-	static struct resource sched_res = {
+-	    "timer", 0x00bfd400, 0x00bfd5ff,
+-	};
+-	jiffy_ticks = (amiga_eclock+HZ/2)/HZ;
+-
+-	if (request_resource(&mb_resources._ciab, &sched_res))
+-	    printk("Cannot allocate ciab.ta{lo,hi}\n");
+-	ciab.cra &= 0xC0;   /* turn off timer A, continuous mode, from Eclk */
+-	ciab.talo = jiffy_ticks % 256;
+-	ciab.tahi = jiffy_ticks / 256;
+-
+-	/* install interrupt service routine for CIAB Timer A
+-	 *
+-	 * Please don't change this to use ciaa, as it interferes with the
+-	 * SCSI code. We'll have to take a look at this later
+-	 */
+-	request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, 0, "timer", NULL);
+-	/* start timer */
+-	ciab.cra |= 0x11;
+-}
+-
+ #define TICK_SIZE 10000
+ 
+-extern unsigned char cia_get_irq_mask(unsigned int irq);
+-
+-/* This is always executed with interrupts disabled.  */
+-static unsigned long amiga_gettimeoffset (void)
+-{
+-	unsigned short hi, lo, hi2;
+-	unsigned long ticks, offset = 0;
+-
+-	/* read CIA B timer A current value */
+-	hi  = ciab.tahi;
+-	lo  = ciab.talo;
+-	hi2 = ciab.tahi;
+-
+-	if (hi != hi2) {
+-		lo = ciab.talo;
+-		hi = hi2;
+-	}
+-
+-	ticks = hi << 8 | lo;
+-
+-	if (ticks > jiffy_ticks / 2)
+-		/* check for pending interrupt */
+-		if (cia_get_irq_mask(IRQ_AMIGA_CIAB) & CIA_ICR_TA)
+-			offset = 10000;
+-
+-	ticks = jiffy_ticks - ticks;
+-	ticks = (10000 * ticks) / jiffy_ticks;
+-
+-	return ticks + offset;
+-}
+-
+-static void a3000_gettod (int *yearp, int *monp, int *dayp,
+-			  int *hourp, int *minp, int *secp)
+-{
+-	volatile struct tod3000 *tod = TOD_3000;
+-
+-	tod->cntrl1 = TOD3000_CNTRL1_HOLD;
+-
+-	*secp  = tod->second1 * 10 + tod->second2;
+-	*minp  = tod->minute1 * 10 + tod->minute2;
+-	*hourp = tod->hour1   * 10 + tod->hour2;
+-	*dayp  = tod->day1    * 10 + tod->day2;
+-	*monp  = tod->month1  * 10 + tod->month2;
+-	*yearp = tod->year1   * 10 + tod->year2;
+-
+-	tod->cntrl1 = TOD3000_CNTRL1_FREE;
+-}
+-
+-static void a2000_gettod (int *yearp, int *monp, int *dayp,
+-			  int *hourp, int *minp, int *secp)
+-{
+-	volatile struct tod2000 *tod = TOD_2000;
+-
+-	tod->cntrl1 = TOD2000_CNTRL1_HOLD;
+-
+-	while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
+-		;
+-
+-	*secp  = tod->second1     * 10 + tod->second2;
+-	*minp  = tod->minute1     * 10 + tod->minute2;
+-	*hourp = (tod->hour1 & 3) * 10 + tod->hour2;
+-	*dayp  = tod->day1        * 10 + tod->day2;
+-	*monp  = tod->month1      * 10 + tod->month2;
+-	*yearp = tod->year1       * 10 + tod->year2;
+-
+-	if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){
+-		if (!(tod->hour1 & TOD2000_HOUR1_PM) && *hourp == 12)
+-			*hourp = 0;
+-		else if ((tod->hour1 & TOD2000_HOUR1_PM) && *hourp != 12)
+-			*hourp += 12;
+-	}
+-
+-	tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
+-}
+-
+-static int amiga_hwclk(int op, struct hwclk_time *t)
++int amiga_hwclk(int op, struct rtc_time *t)
+ {
+ 	if (AMIGAHW_PRESENT(A3000_CLK)) {
+-		volatile struct tod3000 *tod = TOD_3000;
+-
+-		tod->cntrl1 = TOD3000_CNTRL1_HOLD;
++		tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD;
+ 
+ 		if (!op) { /* read */
+-			t->sec  = tod->second1 * 10 + tod->second2;
+-			t->min  = tod->minute1 * 10 + tod->minute2;
+-			t->hour = tod->hour1   * 10 + tod->hour2;
+-			t->day  = tod->day1    * 10 + tod->day2;
+-			t->wday = tod->weekday;
+-			t->mon  = tod->month1  * 10 + tod->month2 - 1;
+-			t->year = tod->year1   * 10 + tod->year2;
+-			if (t->year <= 69)
+-				t->year += 100;
++			t->tm_sec  = tod_3000.second1 * 10 + tod_3000.second2;
++			t->tm_min  = tod_3000.minute1 * 10 + tod_3000.minute2;
++			t->tm_hour = tod_3000.hour1   * 10 + tod_3000.hour2;
++			t->tm_mday = tod_3000.day1    * 10 + tod_3000.day2;
++			t->tm_wday = tod_3000.weekday;
++			t->tm_mon  = tod_3000.month1  * 10 + tod_3000.month2 - 1;
++			t->tm_year = tod_3000.year1   * 10 + tod_3000.year2;
++			if (t->tm_year <= 69)
++				t->tm_year += 100;
+ 		} else {
+-			tod->second1 = t->sec / 10;
+-			tod->second2 = t->sec % 10;
+-			tod->minute1 = t->min / 10;
+-			tod->minute2 = t->min % 10;
+-			tod->hour1   = t->hour / 10;
+-			tod->hour2   = t->hour % 10;
+-			tod->day1    = t->day / 10;
+-			tod->day2    = t->day % 10;
+-			if (t->wday != -1)
+-				tod->weekday = t->wday;
+-			tod->month1  = (t->mon + 1) / 10;
+-			tod->month2  = (t->mon + 1) % 10;
+-			if (t->year >= 100)
+-				t->year -= 100;
+-			tod->year1   = t->year / 10;
+-			tod->year2   = t->year % 10;
++			tod_3000.second1 = t->tm_sec / 10;
++			tod_3000.second2 = t->tm_sec % 10;
++			tod_3000.minute1 = t->tm_min / 10;
++			tod_3000.minute2 = t->tm_min % 10;
++			tod_3000.hour1   = t->tm_hour / 10;
++			tod_3000.hour2   = t->tm_hour % 10;
++			tod_3000.day1    = t->tm_mday / 10;
++			tod_3000.day2    = t->tm_mday % 10;
++			if (t->tm_wday != -1)
++				tod_3000.weekday = t->tm_wday;
++			tod_3000.month1  = (t->tm_mon + 1) / 10;
++			tod_3000.month2  = (t->tm_mon + 1) % 10;
++			if (t->tm_year >= 100)
++				t->tm_year -= 100;
++			tod_3000.year1   = t->tm_year / 10;
++			tod_3000.year2   = t->tm_year % 10;
+ 		}
+ 
+-		tod->cntrl1 = TOD3000_CNTRL1_FREE;
++		tod_3000.cntrl1 = TOD3000_CNTRL1_FREE;
+ 	} else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {
+-		volatile struct tod2000 *tod = TOD_2000;
++		int cnt = 5;
+ 
+-		tod->cntrl1 = TOD2000_CNTRL1_HOLD;
+-	
+-		while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
+-			;
++		tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD;
++
++		while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) {
++			tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
++			udelay(70);
++			tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
++		}
++
++		if (!cnt)
++			printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n", tod_2000.cntrl1);
+ 
+ 		if (!op) { /* read */
+-			t->sec  = tod->second1     * 10 + tod->second2;
+-			t->min  = tod->minute1     * 10 + tod->minute2;
+-			t->hour = (tod->hour1 & 3) * 10 + tod->hour2;
+-			t->day  = tod->day1        * 10 + tod->day2;
+-			t->wday = tod->weekday;
+-			t->mon  = tod->month1      * 10 + tod->month2 - 1;
+-			t->year = tod->year1       * 10 + tod->year2;
+-			if (t->year <= 69)
+-				t->year += 100;
+-
+-			if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){
+-				if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
+-					t->hour = 0;
+-				else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->hour != 12)
+-					t->hour += 12;
++			t->tm_sec  = tod_2000.second1     * 10 + tod_2000.second2;
++			t->tm_min  = tod_2000.minute1     * 10 + tod_2000.minute2;
++			t->tm_hour = (tod_2000.hour1 & 3) * 10 + tod_2000.hour2;
++			t->tm_mday = tod_2000.day1        * 10 + tod_2000.day2;
++			t->tm_wday = tod_2000.weekday;
++			t->tm_mon  = tod_2000.month1      * 10 + tod_2000.month2 - 1;
++			t->tm_year = tod_2000.year1       * 10 + tod_2000.year2;
++			if (t->tm_year <= 69)
++				t->tm_year += 100;
++
++			if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)){
++				if (!(tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12)
++					t->tm_hour = 0;
++				else if ((tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12)
++					t->tm_hour += 12;
+ 			}
+ 		} else {
+-			tod->second1 = t->sec / 10;
+-			tod->second2 = t->sec % 10;
+-			tod->minute1 = t->min / 10;
+-			tod->minute2 = t->min % 10;
+-			if (tod->cntrl3 & TOD2000_CNTRL3_24HMODE)
+-				tod->hour1 = t->hour / 10;
+-			else if (t->hour >= 12)
+-				tod->hour1 = TOD2000_HOUR1_PM +
+-					(t->hour - 12) / 10;
++			tod_2000.second1 = t->tm_sec / 10;
++			tod_2000.second2 = t->tm_sec % 10;
++			tod_2000.minute1 = t->tm_min / 10;
++			tod_2000.minute2 = t->tm_min % 10;
++			if (tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)
++				tod_2000.hour1 = t->tm_hour / 10;
++			else if (t->tm_hour >= 12)
++				tod_2000.hour1 = TOD2000_HOUR1_PM +
++					(t->tm_hour - 12) / 10;
+ 			else
+-				tod->hour1 = t->hour / 10;
+-			tod->hour2   = t->hour % 10;
+-			tod->day1    = t->day / 10;
+-			tod->day2    = t->day % 10;
+-			if (t->wday != -1)
+-				tod->weekday = t->wday;
+-			tod->month1  = (t->mon + 1) / 10;
+-			tod->month2  = (t->mon + 1) % 10;
+-			if (t->year >= 100)
+-				t->year -= 100;
+-			tod->year1   = t->year / 10;
+-			tod->year2   = t->year % 10;
++				tod_2000.hour1 = t->tm_hour / 10;
++			tod_2000.hour2   = t->tm_hour % 10;
++			tod_2000.day1    = t->tm_mday / 10;
++			tod_2000.day2    = t->tm_mday % 10;
++			if (t->tm_wday != -1)
++				tod_2000.weekday = t->tm_wday;
++			tod_2000.month1  = (t->tm_mon + 1) / 10;
++			tod_2000.month2  = (t->tm_mon + 1) % 10;
++			if (t->tm_year >= 100)
++				t->tm_year -= 100;
++			tod_2000.year1   = t->tm_year / 10;
++			tod_2000.year2   = t->tm_year % 10;
+ 		}
+ 
+-		tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
++		tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+-static int amiga_set_clock_mmss (unsigned long nowtime)
++int amiga_set_clock_mmss(unsigned long nowtime)
+ {
+ 	short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
+ 
+ 	if (AMIGAHW_PRESENT(A3000_CLK)) {
+-		volatile struct tod3000 *tod = TOD_3000;
+-
+-		tod->cntrl1 = TOD3000_CNTRL1_HOLD;
++		tod_3000.cntrl1 = TOD3000_CNTRL1_HOLD;
+ 
+-		tod->second1 = real_seconds / 10;
+-		tod->second2 = real_seconds % 10;
+-		tod->minute1 = real_minutes / 10;
+-		tod->minute2 = real_minutes % 10;
++		tod_3000.second1 = real_seconds / 10;
++		tod_3000.second2 = real_seconds % 10;
++		tod_3000.minute1 = real_minutes / 10;
++		tod_3000.minute2 = real_minutes % 10;
+ 
+-		tod->cntrl1 = TOD3000_CNTRL1_FREE;
++		tod_3000.cntrl1 = TOD3000_CNTRL1_FREE;
+ 	} else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {
+-		volatile struct tod2000 *tod = TOD_2000;
++		int cnt = 5;
+ 
+-		tod->cntrl1 = TOD2000_CNTRL1_HOLD;
+-	
+-		while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
+-			;
+-
+-		tod->second1 = real_seconds / 10;
+-		tod->second2 = real_seconds % 10;
+-		tod->minute1 = real_minutes / 10;
+-		tod->minute2 = real_minutes % 10;
++		tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
+ 
+-		tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
+-	}
++		while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) {
++			tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
++			udelay(70);
++			tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD;
++		}
+ 
+-	return 0;
+-}
++		if (!cnt)
++			printk(KERN_INFO "set_clock_mmss: timed out waiting for RTC (0x%x)\n", tod_2000.cntrl1);
+ 
+-static NORET_TYPE void amiga_reset( void )
+-    ATTRIB_NORET;
++		tod_2000.second1 = real_seconds / 10;
++		tod_2000.second2 = real_seconds % 10;
++		tod_2000.minute1 = real_minutes / 10;
++		tod_2000.minute2 = real_minutes % 10;
+ 
+-static void amiga_reset (void)
+-{
+-  for (;;);
++		tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD;
++	}
++
++	return 0;
+ }
+ 
+ 
+@@ -841,16 +685,6 @@
+ 	}
+ }
+ 
+-#ifdef CONFIG_HEARTBEAT
+-static void amiga_heartbeat(int on)
+-{
+-    if (on)
+-	ciaa.pra &= ~2;
+-    else
+-	ciaa.pra |= 2;
+-}
+-#endif
+-
+     /*
+      *  Amiga specific parts of /proc
+      */
+@@ -943,19 +777,14 @@
+ 	u_long mem;
+ 	int i;
+ 
+-	if (mach_get_model)
+-		mach_get_model(model);
+-	else
+-		strcpy(model, "Unknown PowerPC");
++	amiga_get_model(model);
+ 
+ 	len += sprintf(buffer+len, "Model:\t\t%s\n", model);
+-	len += get_cpuinfo(buffer+len);
++	//len += get_cpuinfo(buffer+len);
+ 	for (mem = 0, i = 0; i < m68k_realnum_memory; i++)
+ 		mem += m68k_memory[i].size;
+ 	len += sprintf(buffer+len, "System Memory:\t%ldK\n", mem>>10);
+-
+-	if (mach_get_hardware_list)
+-		len += mach_get_hardware_list(buffer+len);
++	len += amiga_get_hardware_list(buffer+len);
+ 
+ 	return(len);
+ }
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/amiga/time.c linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/amiga/time.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/amiga/time.c	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/amiga/time.c	1970-01-01 00:00:00.000000000 +0000
+@@ -1,58 +0,0 @@
+-#include <linux/config.h> /* CONFIG_HEARTBEAT */
+-#include <linux/errno.h>
+-#include <linux/sched.h>
+-#include <linux/kernel.h>
+-#include <linux/param.h>
+-#include <linux/string.h>
+-#include <linux/mm.h>
+-
+-#include <asm/machdep.h>
+-#include <asm/io.h>
+-
+-#include <linux/timex.h>
+-
+-unsigned long m68k_get_rtc_time(void)
+-{
+-	unsigned int year, mon, day, hour, min, sec;
+-
+-	extern void arch_gettod(int *year, int *mon, int *day, int *hour,
+-				int *min, int *sec);
+-
+-	arch_gettod (&year, &mon, &day, &hour, &min, &sec);
+-
+-	if ((year += 1900) < 1970)
+-		year += 100;
+-
+-	return mktime(year, mon, day, hour, min, sec);
+-}
+-
+-int m68k_set_rtc_time(unsigned long nowtime)
+-{
+-  if (mach_set_clock_mmss)
+-    return mach_set_clock_mmss (nowtime);
+-  return -1;
+-}
+-
+-void apus_heartbeat (void)
+-{
+-#ifdef CONFIG_HEARTBEAT
+-	static unsigned cnt = 0, period = 0, dist = 0;
+-
+-	if (cnt == 0 || cnt == dist)
+-                mach_heartbeat( 1 );
+-	else if (cnt == 7 || cnt == dist+7)
+-                mach_heartbeat( 0 );
+-
+-	if (++cnt > period) {
+-                cnt = 0;
+-                /* The hyperbolic function below modifies the heartbeat period
+-                 * length in dependency of the current (5min) load. It goes
+-                 * through the points f(0)=126, f(1)=86, f(5)=51,
+-                 * f(inf)->30. */
+-                period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+-                dist = period / 4;
+-	}
+-#endif
+-	/* should be made smarter */
+-	ppc_md.heartbeat_count = 1;
+-}
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/configs/apus_defconfig linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/configs/apus_defconfig
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/configs/apus_defconfig	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/configs/apus_defconfig	2005-12-29 09:27:44.000000000 +0000
+@@ -1,103 +1,139 @@
+ #
+ # Automatically generated make config: don't edit
++# Linux kernel version: 2.6.14
++# Sat Nov 12 20:49:48 2005
+ #
+ CONFIG_MMU=y
++CONFIG_GENERIC_HARDIRQS=y
+ CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+-CONFIG_HAVE_DEC_LOCK=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_PPC=y
++CONFIG_PPC32=y
++CONFIG_GENERIC_NVRAM=y
++CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
++CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+ 
+ #
+ # Code maturity level options
+ #
+ CONFIG_EXPERIMENTAL=y
++CONFIG_CLEAN_COMPILE=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
+ 
+ #
+ # General setup
+ #
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
+ CONFIG_SWAP=y
+ CONFIG_SYSVIPC=y
+-# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_POSIX_MQUEUE=y
++CONFIG_BSD_PROCESS_ACCT=y
++# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+ CONFIG_SYSCTL=y
+-CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_AUDIT is not set
++# CONFIG_HOTPLUG is not set
++CONFIG_KOBJECT_UEVENT=y
++# CONFIG_IKCONFIG is not set
++CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_EMBEDDED is not set
++CONFIG_KALLSYMS=y
++# CONFIG_KALLSYMS_ALL is not set
++# CONFIG_KALLSYMS_EXTRA_PASS is not set
++CONFIG_PRINTK=y
++CONFIG_BUG=y
++CONFIG_BASE_FULL=y
+ CONFIG_FUTEX=y
+ CONFIG_EPOLL=y
++CONFIG_SHMEM=y
++CONFIG_CC_ALIGN_FUNCTIONS=0
++CONFIG_CC_ALIGN_LABELS=0
++CONFIG_CC_ALIGN_LOOPS=0
++CONFIG_CC_ALIGN_JUMPS=0
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=0
+ 
+ #
+ # Loadable module support
+ #
+ CONFIG_MODULES=y
+ CONFIG_MODULE_UNLOAD=y
+-CONFIG_MODULE_FORCE_UNLOAD=y
++# CONFIG_MODULE_FORCE_UNLOAD is not set
+ CONFIG_OBSOLETE_MODPARM=y
+ # CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
+ CONFIG_KMOD=y
+ 
+ #
+-# Platform support
++# Processor
+ #
+-CONFIG_PPC=y
+-CONFIG_PPC32=y
+ CONFIG_6xx=y
+ # CONFIG_40x is not set
++# CONFIG_44x is not set
+ # CONFIG_POWER3 is not set
++# CONFIG_POWER4 is not set
+ # CONFIG_8xx is not set
++# CONFIG_E200 is not set
++# CONFIG_E500 is not set
++CONFIG_PPC_FPU=y
++# CONFIG_ALTIVEC is not set
++# CONFIG_TAU is not set
++# CONFIG_KEXEC is not set
++# CONFIG_CPU_FREQ is not set
++# CONFIG_WANT_EARLY_SERIAL is not set
++CONFIG_PPC_STD_MMU=y
+ 
+ #
+-# IBM 4xx options
++# Platform options
+ #
+-# CONFIG_8260 is not set
+-CONFIG_GENERIC_ISA_DMA=y
+-CONFIG_PPC_STD_MMU=y
+-CONFIG_SERIAL_CONSOLE=y
+ # CONFIG_PPC_MULTIPLATFORM is not set
+ CONFIG_APUS=y
+-# CONFIG_WILLOW_2 is not set
+-# CONFIG_PCORE is not set
++# CONFIG_KATANA is not set
++# CONFIG_WILLOW is not set
++# CONFIG_CPCI690 is not set
+ # CONFIG_POWERPMC250 is not set
+-# CONFIG_EV64260 is not set
++# CONFIG_CHESTNUT is not set
+ # CONFIG_SPRUCE is not set
++# CONFIG_HDPU is not set
++# CONFIG_EV64260 is not set
+ # CONFIG_LOPEC is not set
+-# CONFIG_MCPN765 is not set
+ # CONFIG_MVME5100 is not set
+ # CONFIG_PPLUS is not set
+ # CONFIG_PRPMC750 is not set
+ # CONFIG_PRPMC800 is not set
+ # CONFIG_SANDPOINT is not set
+-# CONFIG_ADIR is not set
+-# CONFIG_K2 is not set
++# CONFIG_RADSTONE_PPC7D is not set
+ # CONFIG_PAL4 is not set
+ # CONFIG_GEMINI is not set
++# CONFIG_EST8260 is not set
++# CONFIG_SBC82xx is not set
++# CONFIG_SBS8260 is not set
++# CONFIG_RPX8260 is not set
++# CONFIG_TQM8260 is not set
++# CONFIG_ADS8272 is not set
++# CONFIG_PQ2FADS is not set
++# CONFIG_LITE5200 is not set
++# CONFIG_MPC834x_SYS is not set
++# CONFIG_EV64360 is not set
+ # CONFIG_SMP is not set
+-# CONFIG_PREEMPT is not set
+-# CONFIG_ALTIVEC is not set
+-# CONFIG_TAU is not set
+-# CONFIG_CPU_FREQ is not set
+-
+-#
+-# General setup
+-#
+ # CONFIG_HIGHMEM is not set
+-CONFIG_PCI=y
+-CONFIG_PCI_DOMAINS=y
+-CONFIG_PCI_PERMEDIA=y
+-CONFIG_KCORE_ELF=y
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_PREEMPT_NONE=y
++# CONFIG_PREEMPT_VOLUNTARY is not set
++# CONFIG_PREEMPT is not set
++CONFIG_SELECT_MEMORY_MODEL=y
++CONFIG_FLATMEM_MANUAL=y
++# CONFIG_DISCONTIGMEM_MANUAL is not set
++# CONFIG_SPARSEMEM_MANUAL is not set
++CONFIG_FLATMEM=y
++CONFIG_FLAT_NODE_MEM_MAP=y
++# CONFIG_SPARSEMEM_STATIC is not set
+ CONFIG_BINFMT_ELF=y
+-CONFIG_KERNEL_ELF=y
+ CONFIG_BINFMT_MISC=m
+-CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+-# CONFIG_HOTPLUG is not set
+-
+-#
+-# Parallel port support
+-#
+-CONFIG_PARPORT=m
+-# CONFIG_PARPORT_PC is not set
+-CONFIG_PARPORT_AMIGA=m
+-# CONFIG_PARPORT_MFC3 is not set
+-# CONFIG_PARPORT_OTHER is not set
+-# CONFIG_PARPORT_1284 is not set
+-CONFIG_PPC601_SYNC_FIX=y
+ # CONFIG_CMDLINE_BOOL is not set
+ CONFIG_AMIGA=y
+ CONFIG_ZORRO=y
+@@ -105,16 +141,36 @@
+ CONFIG_APUS_FAST_EXCEPT=y
+ CONFIG_AMIGA_PCMCIA=y
+ CONFIG_AMIGA_BUILTIN_SERIAL=y
+-CONFIG_GVPIOEXT=y
++CONFIG_GVPIOEXT=m
+ CONFIG_GVPIOEXT_LP=m
+ CONFIG_GVPIOEXT_PLIP=m
+-CONFIG_MULTIFACE_III_TTY=y
+-CONFIG_A2232=y
+-CONFIG_WHIPPET_SERIAL=y
++CONFIG_MULTIFACE_III_TTY=m
++CONFIG_A2232=m
++CONFIG_WHIPPET_SERIAL=m
+ CONFIG_APNE=y
++CONFIG_SERIAL_CONSOLE=y
+ CONFIG_HEARTBEAT=y
+ CONFIG_PROC_HARDWARE=y
+ CONFIG_ZORRO_NAMES=y
++# CONFIG_PM is not set
++# CONFIG_SOFTWARE_SUSPEND is not set
++# CONFIG_SECCOMP is not set
++CONFIG_ISA_DMA_API=y
++
++#
++# Bus options
++#
++CONFIG_GENERIC_ISA_DMA=y
++CONFIG_PCI=y
++CONFIG_PCI_DOMAINS=y
++CONFIG_PCI_PERMEDIA=y
++CONFIG_PCI_LEGACY_PROC=y
++# CONFIG_PCI_DEBUG is not set
++
++#
++# PCCARD (PCMCIA/CardBus) support
++#
++# CONFIG_PCCARD is not set
+ 
+ #
+ # Advanced setup
+@@ -131,14 +187,183 @@
+ CONFIG_BOOT_LOAD=0x00800000
+ 
+ #
++# Networking
++#
++CONFIG_NET=y
++
++#
++# Networking options
++#
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++# CONFIG_IP_ADVANCED_ROUTER is not set
++CONFIG_IP_FIB_HASH=y
++# CONFIG_IP_PNP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++CONFIG_SYN_COOKIES=y
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_TUNNEL is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_BIC=y
++
++#
++# IP: Virtual Server Configuration
++#
++# CONFIG_IP_VS is not set
++# CONFIG_IPV6 is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++# CONFIG_NETFILTER_NETLINK is not set
++
++#
++# IP: Netfilter Configuration
++#
++CONFIG_IP_NF_CONNTRACK=m
++# CONFIG_IP_NF_CT_ACCT is not set
++# CONFIG_IP_NF_CONNTRACK_MARK is not set
++# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
++# CONFIG_IP_NF_CT_PROTO_SCTP is not set
++CONFIG_IP_NF_FTP=m
++CONFIG_IP_NF_IRC=m
++# CONFIG_IP_NF_NETBIOS_NS is not set
++CONFIG_IP_NF_TFTP=m
++CONFIG_IP_NF_AMANDA=m
++# CONFIG_IP_NF_PPTP is not set
++CONFIG_IP_NF_QUEUE=m
++CONFIG_IP_NF_IPTABLES=m
++CONFIG_IP_NF_MATCH_LIMIT=m
++# CONFIG_IP_NF_MATCH_IPRANGE is not set
++CONFIG_IP_NF_MATCH_MAC=m
++# CONFIG_IP_NF_MATCH_PKTTYPE is not set
++CONFIG_IP_NF_MATCH_MARK=m
++CONFIG_IP_NF_MATCH_MULTIPORT=m
++CONFIG_IP_NF_MATCH_TOS=m
++# CONFIG_IP_NF_MATCH_RECENT is not set
++# CONFIG_IP_NF_MATCH_ECN is not set
++# CONFIG_IP_NF_MATCH_DSCP is not set
++# CONFIG_IP_NF_MATCH_AH_ESP is not set
++CONFIG_IP_NF_MATCH_LENGTH=m
++CONFIG_IP_NF_MATCH_TTL=m
++CONFIG_IP_NF_MATCH_TCPMSS=m
++CONFIG_IP_NF_MATCH_HELPER=m
++CONFIG_IP_NF_MATCH_STATE=m
++CONFIG_IP_NF_MATCH_CONNTRACK=m
++CONFIG_IP_NF_MATCH_OWNER=m
++# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
++# CONFIG_IP_NF_MATCH_REALM is not set
++# CONFIG_IP_NF_MATCH_SCTP is not set
++# CONFIG_IP_NF_MATCH_DCCP is not set
++# CONFIG_IP_NF_MATCH_COMMENT is not set
++# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
++# CONFIG_IP_NF_MATCH_STRING is not set
++CONFIG_IP_NF_FILTER=m
++CONFIG_IP_NF_TARGET_REJECT=m
++CONFIG_IP_NF_TARGET_LOG=m
++CONFIG_IP_NF_TARGET_ULOG=m
++CONFIG_IP_NF_TARGET_TCPMSS=m
++# CONFIG_IP_NF_TARGET_NFQUEUE is not set
++CONFIG_IP_NF_NAT=m
++CONFIG_IP_NF_NAT_NEEDED=y
++CONFIG_IP_NF_TARGET_MASQUERADE=m
++CONFIG_IP_NF_TARGET_REDIRECT=m
++# CONFIG_IP_NF_TARGET_NETMAP is not set
++# CONFIG_IP_NF_TARGET_SAME is not set
++CONFIG_IP_NF_NAT_SNMP_BASIC=m
++CONFIG_IP_NF_NAT_IRC=m
++CONFIG_IP_NF_NAT_FTP=m
++CONFIG_IP_NF_NAT_TFTP=m
++CONFIG_IP_NF_NAT_AMANDA=m
++CONFIG_IP_NF_MANGLE=m
++CONFIG_IP_NF_TARGET_TOS=m
++CONFIG_IP_NF_TARGET_ECN=m
++CONFIG_IP_NF_TARGET_DSCP=m
++CONFIG_IP_NF_TARGET_MARK=m
++# CONFIG_IP_NF_TARGET_CLASSIFY is not set
++# CONFIG_IP_NF_TARGET_TTL is not set
++# CONFIG_IP_NF_RAW is not set
++CONFIG_IP_NF_ARPTABLES=m
++CONFIG_IP_NF_ARPFILTER=m
++# CONFIG_IP_NF_ARP_MANGLE is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_SCTP is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# CONFIG_LLC2 is not set
++# CONFIG_IPX is not set
++# CONFIG_ATALK is not set
++# CONFIG_X25 is not set
++# CONFIG_LAPB is not set
++# CONFIG_NET_DIVERT is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++# CONFIG_NET_SCHED is not set
++# CONFIG_NET_CLS_ROUTE is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_IEEE80211 is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_STANDALONE=y
++CONFIG_PREVENT_FIRMWARE_BUILD=y
++# CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER is not set
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++# CONFIG_CONNECTOR is not set
++
++#
+ # Memory Technology Devices (MTD)
+ #
+ # CONFIG_MTD is not set
+ 
+ #
++# Parallel port support
++#
++CONFIG_PARPORT=m
++# CONFIG_PARPORT_PC is not set
++CONFIG_PARPORT_NOT_PC=y
++CONFIG_PARPORT_AMIGA=m
++# CONFIG_PARPORT_MFC3 is not set
++# CONFIG_PARPORT_GSC is not set
++# CONFIG_PARPORT_1284 is not set
++
++#
+ # Plug and Play support
+ #
+-# CONFIG_PNP is not set
+ 
+ #
+ # Block devices
+@@ -151,42 +376,40 @@
+ # CONFIG_BLK_CPQ_CISS_DA is not set
+ # CONFIG_BLK_DEV_DAC960 is not set
+ # CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_COW_COMMON is not set
+ CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ CONFIG_BLK_DEV_NBD=m
+-CONFIG_BLK_DEV_RAM=y
++# CONFIG_BLK_DEV_SX8 is not set
++CONFIG_BLK_DEV_RAM=m
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=4096
+-CONFIG_BLK_DEV_INITRD=y
++# CONFIG_LBD is not set
++# CONFIG_CDROM_PKTCDVD is not set
+ 
+ #
+-# Multi-device support (RAID and LVM)
++# IO Schedulers
+ #
+-CONFIG_MD=y
+-CONFIG_BLK_DEV_MD=m
+-CONFIG_MD_LINEAR=m
+-CONFIG_MD_RAID0=m
+-CONFIG_MD_RAID1=m
+-CONFIG_MD_RAID5=m
+-# CONFIG_MD_MULTIPATH is not set
+-CONFIG_BLK_DEV_DM=m
++CONFIG_IOSCHED_NOOP=y
++CONFIG_IOSCHED_AS=y
++CONFIG_IOSCHED_DEADLINE=y
++CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
+ 
+ #
+-# ATA/IDE/MFM/RLL support
++# ATA/ATAPI/MFM/RLL support
+ #
+ CONFIG_IDE=y
+-
+-#
+-# IDE, ATA and ATAPI Block devices
+-#
+ CONFIG_BLK_DEV_IDE=y
+ 
+ #
+ # Please see Documentation/ide.txt for help/info on IDE drives
+ #
+-# CONFIG_BLK_DEV_HD is not set
++# CONFIG_BLK_DEV_IDE_SATA is not set
+ CONFIG_BLK_DEV_IDEDISK=y
+ # CONFIG_IDEDISK_MULTI_MODE is not set
+-# CONFIG_IDEDISK_STROKE is not set
+ CONFIG_BLK_DEV_IDECD=y
++# CONFIG_BLK_DEV_IDETAPE is not set
+ CONFIG_BLK_DEV_IDEFLOPPY=y
+ CONFIG_BLK_DEV_IDESCSI=m
+ # CONFIG_IDE_TASK_IOCTL is not set
+@@ -194,15 +417,22 @@
+ #
+ # IDE chipset support/bugfixes
+ #
++CONFIG_IDE_GENERIC=y
+ # CONFIG_BLK_DEV_IDEPCI is not set
++# CONFIG_IDE_ARM is not set
+ CONFIG_BLK_DEV_GAYLE=y
+ CONFIG_BLK_DEV_IDEDOUBLER=y
+ CONFIG_BLK_DEV_BUDDHA=y
++# CONFIG_BLK_DEV_IDEDMA is not set
++# CONFIG_IDEDMA_AUTO is not set
++# CONFIG_BLK_DEV_HD is not set
+ 
+ #
+-# SCSI support
++# SCSI device support
+ #
++# CONFIG_RAID_ATTRS is not set
+ CONFIG_SCSI=y
++CONFIG_SCSI_PROC_FS=y
+ 
+ #
+ # SCSI support type (disk, tape, CD-ROM)
+@@ -213,58 +443,65 @@
+ CONFIG_BLK_DEV_SR=y
+ CONFIG_BLK_DEV_SR_VENDOR=y
+ CONFIG_CHR_DEV_SG=m
++# CONFIG_CHR_DEV_SCH is not set
+ 
+ #
+ # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+ #
+ # CONFIG_SCSI_MULTI_LUN is not set
+-# CONFIG_SCSI_REPORT_LUNS is not set
+ CONFIG_SCSI_CONSTANTS=y
+ CONFIG_SCSI_LOGGING=y
+ 
+ #
++# SCSI Transport Attributes
++#
++# CONFIG_SCSI_SPI_ATTRS is not set
++# CONFIG_SCSI_FC_ATTRS is not set
++# CONFIG_SCSI_ISCSI_ATTRS is not set
++# CONFIG_SCSI_SAS_ATTRS is not set
++
++#
+ # SCSI low-level drivers
+ #
+ # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
++# CONFIG_SCSI_3W_9XXX is not set
+ # CONFIG_SCSI_ACARD is not set
+ # CONFIG_SCSI_AACRAID is not set
+ # CONFIG_SCSI_AIC7XXX is not set
+ # CONFIG_SCSI_AIC7XXX_OLD is not set
+ # CONFIG_SCSI_AIC79XX is not set
+ # CONFIG_SCSI_DPT_I2O is not set
+-# CONFIG_SCSI_ADVANSYS is not set
+-# CONFIG_SCSI_IN2000 is not set
+-# CONFIG_SCSI_AM53C974 is not set
+-# CONFIG_SCSI_MEGARAID is not set
++# CONFIG_MEGARAID_NEWGEN is not set
++# CONFIG_MEGARAID_LEGACY is not set
++# CONFIG_MEGARAID_SAS is not set
++# CONFIG_SCSI_SATA is not set
+ # CONFIG_SCSI_BUSLOGIC is not set
+-# CONFIG_SCSI_CPQFCTS is not set
+ # CONFIG_SCSI_DMX3191D is not set
+ # CONFIG_SCSI_EATA is not set
+-# CONFIG_SCSI_EATA_PIO is not set
+ # CONFIG_SCSI_FUTURE_DOMAIN is not set
+ # CONFIG_SCSI_GDTH is not set
+-# CONFIG_SCSI_GENERIC_NCR5380 is not set
+-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
++# CONFIG_SCSI_IPS is not set
+ # CONFIG_SCSI_INITIO is not set
+ # CONFIG_SCSI_INIA100 is not set
+ # CONFIG_SCSI_PPA is not set
+ # CONFIG_SCSI_IMM is not set
+-# CONFIG_SCSI_NCR53C7xx is not set
+ # CONFIG_SCSI_SYM53C8XX_2 is not set
+-# CONFIG_SCSI_NCR53C8XX is not set
+-# CONFIG_SCSI_SYM53C8XX is not set
+-# CONFIG_SCSI_PCI2000 is not set
+-# CONFIG_SCSI_PCI2220I is not set
+-# CONFIG_SCSI_QLOGIC_ISP is not set
++# CONFIG_SCSI_IPR is not set
+ # CONFIG_SCSI_QLOGIC_FC is not set
+ # CONFIG_SCSI_QLOGIC_1280 is not set
++CONFIG_SCSI_QLA2XXX=y
++# CONFIG_SCSI_QLA21XX is not set
++# CONFIG_SCSI_QLA22XX is not set
++# CONFIG_SCSI_QLA2300 is not set
++# CONFIG_SCSI_QLA2322 is not set
++# CONFIG_SCSI_QLA6312 is not set
++# CONFIG_SCSI_QLA24XX is not set
++# CONFIG_SCSI_LPFC is not set
+ # CONFIG_SCSI_DC395x is not set
+ # CONFIG_SCSI_DC390T is not set
+-# CONFIG_SCSI_U14_34F is not set
+ # CONFIG_SCSI_NSP32 is not set
+ # CONFIG_SCSI_DEBUG is not set
+ CONFIG_A3000_SCSI=y
+-CONFIG_A4000T_SCSI=y
+ CONFIG_A2091_SCSI=y
+ CONFIG_GVP11_SCSI=y
+ CONFIG_CYBERSTORM_SCSI=y
+@@ -272,18 +509,38 @@
+ CONFIG_BLZ2060_SCSI=y
+ CONFIG_BLZ1230_SCSI=y
+ CONFIG_FASTLANE_SCSI=y
+-CONFIG_A4091_SCSI=y
+-CONFIG_WARPENGINE_SCSI=y
+-CONFIG_BLZ603EPLUS_SCSI=y
+ CONFIG_OKTAGON_SCSI=y
+ 
+ #
++# Multi-device support (RAID and LVM)
++#
++CONFIG_MD=y
++CONFIG_BLK_DEV_MD=m
++CONFIG_MD_LINEAR=m
++CONFIG_MD_RAID0=m
++CONFIG_MD_RAID1=m
++CONFIG_MD_RAID10=m
++CONFIG_MD_RAID5=m
++# CONFIG_MD_RAID6 is not set
++# CONFIG_MD_MULTIPATH is not set
++# CONFIG_MD_FAULTY is not set
++CONFIG_BLK_DEV_DM=m
++# CONFIG_DM_CRYPT is not set
++# CONFIG_DM_SNAPSHOT is not set
++# CONFIG_DM_MIRROR is not set
++# CONFIG_DM_ZERO is not set
++# CONFIG_DM_MULTIPATH is not set
++
++#
+ # Fusion MPT device support
+ #
+ # CONFIG_FUSION is not set
++# CONFIG_FUSION_SPI is not set
++# CONFIG_FUSION_FC is not set
++# CONFIG_FUSION_SAS is not set
+ 
+ #
+-# IEEE 1394 (FireWire) support (EXPERIMENTAL)
++# IEEE 1394 (FireWire) support
+ #
+ # CONFIG_IEEE1394 is not set
+ 
+@@ -293,137 +550,40 @@
+ # CONFIG_I2O is not set
+ 
+ #
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=m
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=m
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG is not set
+-CONFIG_UNIX=y
+-# CONFIG_NET_KEY is not set
+-CONFIG_INET=y
+-# CONFIG_IP_MULTICAST is not set
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-# CONFIG_IP_PNP is not set
+-# CONFIG_NET_IPIP is not set
+-# CONFIG_NET_IPGRE is not set
+-# CONFIG_ARPD is not set
+-# CONFIG_INET_ECN is not set
+-CONFIG_SYN_COOKIES=y
+-# CONFIG_INET_AH is not set
+-# CONFIG_INET_ESP is not set
+-# CONFIG_INET_IPCOMP is not set
+-
+-#
+-# IP: Netfilter Configuration
+-#
+-CONFIG_IP_NF_CONNTRACK=m
+-CONFIG_IP_NF_FTP=m
+-CONFIG_IP_NF_IRC=m
+-CONFIG_IP_NF_TFTP=m
+-CONFIG_IP_NF_AMANDA=m
+-CONFIG_IP_NF_QUEUE=m
+-CONFIG_IP_NF_IPTABLES=m
+-CONFIG_IP_NF_MATCH_LIMIT=m
+-CONFIG_IP_NF_MATCH_MAC=m
+-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
+-CONFIG_IP_NF_MATCH_MARK=m
+-CONFIG_IP_NF_MATCH_MULTIPORT=m
+-CONFIG_IP_NF_MATCH_TOS=m
+-# CONFIG_IP_NF_MATCH_ECN is not set
+-# CONFIG_IP_NF_MATCH_DSCP is not set
+-# CONFIG_IP_NF_MATCH_AH_ESP is not set
+-CONFIG_IP_NF_MATCH_LENGTH=m
+-CONFIG_IP_NF_MATCH_TTL=m
+-CONFIG_IP_NF_MATCH_TCPMSS=m
+-CONFIG_IP_NF_MATCH_HELPER=m
+-CONFIG_IP_NF_MATCH_STATE=m
+-CONFIG_IP_NF_MATCH_CONNTRACK=m
+-CONFIG_IP_NF_MATCH_UNCLEAN=m
+-CONFIG_IP_NF_MATCH_OWNER=m
+-CONFIG_IP_NF_FILTER=m
+-CONFIG_IP_NF_TARGET_REJECT=m
+-CONFIG_IP_NF_TARGET_MIRROR=m
+-CONFIG_IP_NF_NAT=m
+-CONFIG_IP_NF_NAT_NEEDED=y
+-CONFIG_IP_NF_TARGET_MASQUERADE=m
+-CONFIG_IP_NF_TARGET_REDIRECT=m
+-CONFIG_IP_NF_NAT_SNMP_BASIC=m
+-CONFIG_IP_NF_NAT_IRC=m
+-CONFIG_IP_NF_NAT_FTP=m
+-CONFIG_IP_NF_NAT_TFTP=m
+-CONFIG_IP_NF_NAT_AMANDA=m
+-CONFIG_IP_NF_MANGLE=m
+-CONFIG_IP_NF_TARGET_TOS=m
+-CONFIG_IP_NF_TARGET_ECN=m
+-CONFIG_IP_NF_TARGET_DSCP=m
+-CONFIG_IP_NF_TARGET_MARK=m
+-CONFIG_IP_NF_TARGET_LOG=m
+-CONFIG_IP_NF_TARGET_ULOG=m
+-CONFIG_IP_NF_TARGET_TCPMSS=m
+-CONFIG_IP_NF_ARPTABLES=m
+-CONFIG_IP_NF_ARPFILTER=m
+-CONFIG_IP_NF_COMPAT_IPCHAINS=m
+-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+-# CONFIG_IPV6 is not set
+-# CONFIG_XFRM_USER is not set
+-
+-#
+-# SCTP Configuration (EXPERIMENTAL)
+-#
+-CONFIG_IPV6_SCTP__=y
+-# CONFIG_IP_SCTP is not set
+-# CONFIG_ATM is not set
+-# CONFIG_VLAN_8021Q is not set
+-# CONFIG_LLC is not set
+-# CONFIG_DECNET is not set
+-# CONFIG_BRIDGE is not set
+-# CONFIG_X25 is not set
+-# CONFIG_LAPB is not set
+-# CONFIG_NET_DIVERT is not set
+-# CONFIG_ECONET is not set
+-# CONFIG_WAN_ROUTER is not set
+-# CONFIG_NET_HW_FLOWCONTROL is not set
+-
+-#
+-# QoS and/or fair queueing
++# Macintosh device drivers
+ #
+-# CONFIG_NET_SCHED is not set
+ 
+ #
+-# Network testing
++# Network device support
+ #
+-# CONFIG_NET_PKTGEN is not set
+ CONFIG_NETDEVICES=y
++CONFIG_DUMMY=m
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_TUN=m
+ 
+ #
+ # ARCnet devices
+ #
+ # CONFIG_ARCNET is not set
+-CONFIG_DUMMY=m
+-# CONFIG_BONDING is not set
+-# CONFIG_EQUALIZER is not set
+-CONFIG_TUN=m
+-# CONFIG_ETHERTAP is not set
++
++#
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
+ 
+ #
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+ # CONFIG_MII is not set
+-# CONFIG_OAKNET is not set
+ CONFIG_ARIADNE=y
+-# CONFIG_ZORRO8390 is not set
+ CONFIG_A2065=y
+ CONFIG_HYDRA=y
++CONFIG_ZORRO8390=y
+ # CONFIG_HAPPYMEAL is not set
+ # CONFIG_SUNGEM is not set
++# CONFIG_CASSINI is not set
+ # CONFIG_NET_VENDOR_3COM is not set
+ 
+ #
+@@ -432,6 +592,7 @@
+ # CONFIG_NET_TULIP is not set
+ # CONFIG_HP100 is not set
+ # CONFIG_NET_PCI is not set
++# CONFIG_NET_POCKET is not set
+ 
+ #
+ # Ethernet (1000 Mbit)
+@@ -443,118 +604,73 @@
+ # CONFIG_HAMACHI is not set
+ # CONFIG_YELLOWFIN is not set
+ # CONFIG_R8169 is not set
++# CONFIG_SIS190 is not set
++# CONFIG_SKGE is not set
+ # CONFIG_SK98LIN is not set
+ # CONFIG_TIGON3 is not set
++# CONFIG_BNX2 is not set
+ 
+ #
+ # Ethernet (10000 Mbit)
+ #
++# CONFIG_CHELSIO_T1 is not set
+ # CONFIG_IXGB is not set
+-# CONFIG_FDDI is not set
+-# CONFIG_HIPPI is not set
+-CONFIG_PLIP=m
+-CONFIG_PPP=y
+-CONFIG_PPP_MULTILINK=y
+-CONFIG_PPP_FILTER=y
+-CONFIG_PPP_ASYNC=y
+-CONFIG_PPP_SYNC_TTY=y
+-CONFIG_PPP_DEFLATE=y
+-CONFIG_PPP_BSDCOMP=y
+-CONFIG_PPPOE=y
+-CONFIG_SLIP=y
+-CONFIG_SLIP_COMPRESSED=y
+-CONFIG_SLIP_SMART=y
+-CONFIG_SLIP_MODE_SLIP6=y
++# CONFIG_S2IO is not set
+ 
+ #
+-# Wireless LAN (non-hamradio)
++# Token Ring devices
+ #
+-# CONFIG_NET_RADIO is not set
++# CONFIG_TR is not set
+ 
+ #
+-# Token Ring devices (depends on LLC=y)
++# Wireless LAN (non-hamradio)
+ #
+-# CONFIG_NET_FC is not set
+-# CONFIG_RCPCI is not set
+-# CONFIG_SHAPER is not set
++# CONFIG_NET_RADIO is not set
+ 
+ #
+ # Wan interfaces
+ #
+ # CONFIG_WAN is not set
++# CONFIG_FDDI is not set
++# CONFIG_HIPPI is not set
++CONFIG_PLIP=m
++CONFIG_PPP=y
++CONFIG_PPP_MULTILINK=y
++CONFIG_PPP_FILTER=y
++CONFIG_PPP_ASYNC=y
++CONFIG_PPP_SYNC_TTY=y
++CONFIG_PPP_DEFLATE=y
++CONFIG_PPP_BSDCOMP=y
++CONFIG_PPPOE=y
++CONFIG_SLIP=y
++CONFIG_SLIP_COMPRESSED=y
++CONFIG_SLIP_SMART=y
++CONFIG_SLIP_MODE_SLIP6=y
++# CONFIG_NET_FC is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
+ 
+ #
+-# Amateur Radio support
+-#
+-# CONFIG_HAMRADIO is not set
+-
+-#
+-# IrDA (infrared) support
+-#
+-# CONFIG_IRDA is not set
+-
+-#
+-# ISDN subsystem
+-#
+-# CONFIG_ISDN_BOOL is not set
+-
+-#
+-# Graphics support
+-#
+-CONFIG_FB=y
+-# CONFIG_FB_CIRRUS is not set
+-CONFIG_FB_PM2=y
+-# CONFIG_FB_PM2_FIFO_DISCONNECT is not set
+-# CONFIG_FB_PM2_PCI is not set
+-CONFIG_FB_PM2_CVPPC=y
+-CONFIG_FB_CYBER2000=y
+-CONFIG_FB_AMIGA=y
+-CONFIG_FB_AMIGA_OCS=y
+-CONFIG_FB_AMIGA_ECS=y
+-CONFIG_FB_AMIGA_AGA=y
+-CONFIG_FB_CYBER=y
+-CONFIG_FB_VIRGE=y
+-CONFIG_FB_RETINAZ3=y
+-CONFIG_FB_FM2=y
+-# CONFIG_FB_CT65550 is not set
+-# CONFIG_FB_IMSTT is not set
+-# CONFIG_FB_S3TRIO is not set
+-# CONFIG_FB_VGA16 is not set
+-# CONFIG_FB_RIVA is not set
+-# CONFIG_FB_MATROX is not set
+-# CONFIG_FB_RADEON is not set
+-# CONFIG_FB_ATY128 is not set
+-# CONFIG_FB_ATY is not set
+-# CONFIG_FB_SIS is not set
+-# CONFIG_FB_NEOMAGIC is not set
+-# CONFIG_FB_3DFX is not set
+-# CONFIG_FB_VOODOO1 is not set
+-# CONFIG_FB_TRIDENT is not set
+-# CONFIG_FB_PM3 is not set
+-# CONFIG_FB_VIRTUAL is not set
+-
+-#
+-# Logo configuration
++# ISDN subsystem
+ #
+-CONFIG_LOGO=y
+-CONFIG_LOGO_LINUX_MONO=y
+-CONFIG_LOGO_LINUX_VGA16=y
+-CONFIG_LOGO_LINUX_CLUT224=y
++# CONFIG_ISDN is not set
+ 
+ #
+-# Old CD-ROM drivers (not SCSI, not IDE)
++# Telephony Support
+ #
+-# CONFIG_CD_NO_IDESCSI is not set
++# CONFIG_PHONE is not set
+ 
+ #
+ # Input device support
+ #
+-CONFIG_INPUT=m
++CONFIG_INPUT=y
+ 
+ #
+ # Userland interfaces
+ #
+-CONFIG_INPUT_MOUSEDEV=m
++CONFIG_INPUT_MOUSEDEV=y
+ CONFIG_INPUT_MOUSEDEV_PSAUX=y
+ CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+@@ -564,42 +680,37 @@
+ CONFIG_INPUT_EVBUG=m
+ 
+ #
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-CONFIG_SERIO=y
+-# CONFIG_SERIO_I8042 is not set
+-CONFIG_SERIO_SERPORT=y
+-# CONFIG_SERIO_CT82C710 is not set
+-# CONFIG_SERIO_PARKBD is not set
+-
+-#
+ # Input Device Drivers
+ #
+ CONFIG_INPUT_KEYBOARD=y
+-CONFIG_KEYBOARD_ATKBD=m
++# CONFIG_KEYBOARD_ATKBD is not set
+ # CONFIG_KEYBOARD_SUNKBD is not set
++# CONFIG_KEYBOARD_LKKBD is not set
+ # CONFIG_KEYBOARD_XTKBD is not set
+ # CONFIG_KEYBOARD_NEWTON is not set
+-CONFIG_KEYBOARD_AMIGA=m
++CONFIG_KEYBOARD_AMIGA=y
+ CONFIG_INPUT_MOUSE=y
+-CONFIG_MOUSE_PS2=m
+-CONFIG_MOUSE_SERIAL=m
++# CONFIG_MOUSE_PS2 is not set
++# CONFIG_MOUSE_SERIAL is not set
+ CONFIG_MOUSE_AMIGA=m
++# CONFIG_MOUSE_VSXXXAA is not set
+ # CONFIG_INPUT_JOYSTICK is not set
+ # CONFIG_INPUT_TOUCHSCREEN is not set
+ CONFIG_INPUT_MISC=y
+-# CONFIG_INPUT_PCSPKR is not set
+ CONFIG_INPUT_UINPUT=m
+ 
+ #
+-# Macintosh device drivers
++# Hardware I/O ports
+ #
++# CONFIG_SERIO is not set
++# CONFIG_GAMEPORT is not set
+ 
+ #
+ # Character devices
+ #
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
+ # CONFIG_SERIAL_NONSTANDARD is not set
+ 
+ #
+@@ -610,34 +721,16 @@
+ #
+ # Non-8250 serial port support
+ #
++# CONFIG_SERIAL_JSM is not set
+ CONFIG_UNIX98_PTYS=y
+-CONFIG_UNIX98_PTY_COUNT=256
++CONFIG_LEGACY_PTYS=y
++CONFIG_LEGACY_PTY_COUNT=256
+ CONFIG_PRINTER=m
+ # CONFIG_LP_CONSOLE is not set
+ # CONFIG_PPDEV is not set
+ # CONFIG_TIPAR is not set
+ 
+ #
+-# I2C support
+-#
+-# CONFIG_I2C is not set
+-
+-#
+-# I2C Hardware Sensors Mainboard support
+-#
+-
+-#
+-# I2C Hardware Sensors Chip support
+-#
+-# CONFIG_I2C_SENSOR is not set
+-
+-#
+-# Mice
+-#
+-CONFIG_BUSMOUSE=y
+-# CONFIG_QIC02_TAPE is not set
+-
+-#
+ # IPMI
+ #
+ # CONFIG_IPMI_HANDLER is not set
+@@ -656,11 +749,38 @@
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_FTAPE is not set
+ # CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+-# CONFIG_HANGCHECK_TIMER is not set
++
++#
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C is not set
++
++#
++# Dallas's 1-wire bus
++#
++# CONFIG_W1 is not set
++
++#
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia Capabilities Port drivers
++#
+ 
+ #
+ # Multimedia devices
+@@ -673,10 +793,164 @@
+ # CONFIG_DVB is not set
+ 
+ #
++# Graphics support
++#
++CONFIG_FB=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
++CONFIG_FB_SOFT_CURSOR=y
++# CONFIG_FB_MACMODES is not set
++# CONFIG_FB_MODE_HELPERS is not set
++# CONFIG_FB_TILEBLITTING is not set
++# CONFIG_FB_CIRRUS is not set
++# CONFIG_FB_PM2 is not set
++CONFIG_FB_CYBER2000=y
++CONFIG_FB_AMIGA=y
++CONFIG_FB_AMIGA_OCS=y
++CONFIG_FB_AMIGA_ECS=y
++CONFIG_FB_AMIGA_AGA=y
++CONFIG_FB_FM2=y
++# CONFIG_FB_CT65550 is not set
++# CONFIG_FB_ASILIANT is not set
++# CONFIG_FB_IMSTT is not set
++# CONFIG_FB_VGA16 is not set
++# CONFIG_FB_NVIDIA is not set
++# CONFIG_FB_RIVA is not set
++# CONFIG_FB_MATROX is not set
++# CONFIG_FB_RADEON_OLD is not set
++# CONFIG_FB_RADEON is not set
++# CONFIG_FB_ATY128 is not set
++# CONFIG_FB_ATY is not set
++# CONFIG_FB_SAVAGE is not set
++# CONFIG_FB_SIS is not set
++# CONFIG_FB_NEOMAGIC is not set
++# CONFIG_FB_KYRO is not set
++# CONFIG_FB_3DFX is not set
++# CONFIG_FB_VOODOO1 is not set
++# CONFIG_FB_CYBLA is not set
++# CONFIG_FB_TRIDENT is not set
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
++
++#
++# Console display driver support
++#
++CONFIG_VGA_CONSOLE=y
++CONFIG_DUMMY_CONSOLE=y
++CONFIG_FRAMEBUFFER_CONSOLE=y
++# CONFIG_FONTS is not set
++CONFIG_FONT_8x8=y
++CONFIG_FONT_8x16=y
++CONFIG_FONT_PEARL_8x8=y
++
++#
++# Logo configuration
++#
++CONFIG_LOGO=y
++CONFIG_LOGO_LINUX_MONO=y
++CONFIG_LOGO_LINUX_VGA16=y
++CONFIG_LOGO_LINUX_CLUT224=y
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Sound
++#
++CONFIG_SOUND=y
++CONFIG_DMASOUND_PAULA=m
++CONFIG_DMASOUND=m
++
++#
++# Advanced Linux Sound Architecture
++#
++# CONFIG_SND is not set
++
++#
++# Open Sound System
++#
++CONFIG_SOUND_PRIME=m
++# CONFIG_SOUND_BT878 is not set
++# CONFIG_SOUND_CMPCI is not set
++# CONFIG_SOUND_EMU10K1 is not set
++# CONFIG_SOUND_FUSION is not set
++# CONFIG_SOUND_CS4281 is not set
++# CONFIG_SOUND_ES1370 is not set
++# CONFIG_SOUND_ES1371 is not set
++# CONFIG_SOUND_ESSSOLO1 is not set
++# CONFIG_SOUND_MAESTRO is not set
++# CONFIG_SOUND_MAESTRO3 is not set
++# CONFIG_SOUND_ICH is not set
++# CONFIG_SOUND_SONICVIBES is not set
++# CONFIG_SOUND_TRIDENT is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++# CONFIG_SOUND_VIA82CXXX is not set
++CONFIG_SOUND_OSS=m
++CONFIG_SOUND_TRACEINIT=y
++# CONFIG_SOUND_DMAP is not set
++# CONFIG_SOUND_AD1816 is not set
++# CONFIG_SOUND_AD1889 is not set
++# CONFIG_SOUND_SGALAXY is not set
++# CONFIG_SOUND_ADLIB is not set
++# CONFIG_SOUND_ACI_MIXER is not set
++# CONFIG_SOUND_CS4232 is not set
++# CONFIG_SOUND_SSCAPE is not set
++# CONFIG_SOUND_GUS is not set
++CONFIG_SOUND_VMIDI=m
++# CONFIG_SOUND_TRIX is not set
++# CONFIG_SOUND_MSS is not set
++# CONFIG_SOUND_MPU401 is not set
++# CONFIG_SOUND_NM256 is not set
++# CONFIG_SOUND_MAD16 is not set
++# CONFIG_SOUND_PAS is not set
++# CONFIG_SOUND_PSS is not set
++# CONFIG_SOUND_SB is not set
++# CONFIG_SOUND_AWE32_SYNTH is not set
++# CONFIG_SOUND_WAVEFRONT is not set
++# CONFIG_SOUND_MAUI is not set
++# CONFIG_SOUND_YM3812 is not set
++# CONFIG_SOUND_OPL3SA1 is not set
++# CONFIG_SOUND_OPL3SA2 is not set
++# CONFIG_SOUND_YMFPCI is not set
++# CONFIG_SOUND_UART6850 is not set
++# CONFIG_SOUND_AEDSP16 is not set
++# CONFIG_SOUND_ALI5455 is not set
++# CONFIG_SOUND_FORTE is not set
++# CONFIG_SOUND_RME96XX is not set
++# CONFIG_SOUND_AD1980 is not set
++
++#
++# USB support
++#
++CONFIG_USB_ARCH_HAS_HCD=y
++CONFIG_USB_ARCH_HAS_OHCI=y
++# CONFIG_USB is not set
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# InfiniBand support
++#
++# CONFIG_INFINIBAND is not set
++
++#
++# SN Devices
++#
++
++#
+ # File systems
+ #
+ CONFIG_EXT2_FS=y
+ # CONFIG_EXT2_FS_XATTR is not set
++# CONFIG_EXT2_FS_XIP is not set
+ CONFIG_EXT3_FS=y
+ CONFIG_EXT3_FS_XATTR=y
+ # CONFIG_EXT3_FS_POSIX_ACL is not set
+@@ -686,12 +960,16 @@
+ CONFIG_FS_MBCACHE=y
+ # CONFIG_REISERFS_FS is not set
+ # CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
+ # CONFIG_XFS_FS is not set
+ CONFIG_MINIX_FS=y
+-CONFIG_ROMFS_FS=y
++CONFIG_ROMFS_FS=m
++CONFIG_INOTIFY=y
+ # CONFIG_QUOTA is not set
++CONFIG_DNOTIFY=y
+ CONFIG_AUTOFS_FS=m
+ CONFIG_AUTOFS4_FS=m
++# CONFIG_FUSE_FS is not set
+ 
+ #
+ # CD-ROM/DVD Filesystems
+@@ -707,17 +985,20 @@
+ CONFIG_FAT_FS=y
+ CONFIG_MSDOS_FS=y
+ CONFIG_VFAT_FS=y
++CONFIG_FAT_DEFAULT_CODEPAGE=437
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+ # CONFIG_NTFS_FS is not set
+ 
+ #
+ # Pseudo filesystems
+ #
+ CONFIG_PROC_FS=y
+-# CONFIG_DEVFS_FS is not set
+-CONFIG_DEVPTS_FS=y
+-# CONFIG_DEVPTS_FS_XATTR is not set
++CONFIG_PROC_KCORE=y
++CONFIG_SYSFS=y
+ CONFIG_TMPFS=y
++# CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
++# CONFIG_RELAYFS_FS is not set
+ 
+ #
+ # Miscellaneous filesystems
+@@ -725,10 +1006,11 @@
+ # CONFIG_ADFS_FS is not set
+ CONFIG_AFFS_FS=y
+ CONFIG_HFS_FS=y
++# CONFIG_HFSPLUS_FS is not set
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
+-CONFIG_CRAMFS=y
++CONFIG_CRAMFS=m
+ # CONFIG_VXFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+ # CONFIG_QNX4FS_FS is not set
+@@ -740,23 +1022,29 @@
+ #
+ CONFIG_NFS_FS=y
+ CONFIG_NFS_V3=y
++# CONFIG_NFS_V3_ACL is not set
+ # CONFIG_NFS_V4 is not set
++# CONFIG_NFS_DIRECTIO is not set
+ CONFIG_NFSD=m
+ CONFIG_NFSD_V3=y
++# CONFIG_NFSD_V3_ACL is not set
+ # CONFIG_NFSD_V4 is not set
+ # CONFIG_NFSD_TCP is not set
+ CONFIG_LOCKD=y
+ CONFIG_LOCKD_V4=y
+ CONFIG_EXPORTFS=m
++CONFIG_NFS_COMMON=y
+ CONFIG_SUNRPC=y
+-# CONFIG_SUNRPC_GSS is not set
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
+ CONFIG_SMB_FS=m
+ # CONFIG_SMB_NLS_DEFAULT is not set
+ # CONFIG_CIFS is not set
+ # CONFIG_NCP_FS is not set
+ CONFIG_CODA_FS=m
+-# CONFIG_INTERMEZZO_FS is not set
++# CONFIG_CODA_FS_OLD_API is not set
+ # CONFIG_AFS_FS is not set
++# CONFIG_9P_FS is not set
+ 
+ #
+ # Partition Types
+@@ -773,17 +1061,15 @@
+ CONFIG_SOLARIS_X86_PARTITION=y
+ CONFIG_UNIXWARE_DISKLABEL=y
+ # CONFIG_LDM_PARTITION is not set
+-# CONFIG_NEC98_PARTITION is not set
+ # CONFIG_SGI_PARTITION is not set
+ # CONFIG_ULTRIX_PARTITION is not set
+ # CONFIG_SUN_PARTITION is not set
+ # CONFIG_EFI_PARTITION is not set
+-CONFIG_SMB_NLS=y
+-CONFIG_NLS=y
+ 
+ #
+ # Native Language Support
+ #
++CONFIG_NLS=y
+ CONFIG_NLS_DEFAULT="iso8859-1"
+ CONFIG_NLS_CODEPAGE_437=m
+ CONFIG_NLS_CODEPAGE_737=m
+@@ -806,8 +1092,9 @@
+ CONFIG_NLS_CODEPAGE_949=m
+ CONFIG_NLS_CODEPAGE_874=m
+ CONFIG_NLS_ISO8859_8=m
+-# CONFIG_NLS_CODEPAGE_1250 is not set
++CONFIG_NLS_CODEPAGE_1250=m
+ CONFIG_NLS_CODEPAGE_1251=m
++CONFIG_NLS_ASCII=m
+ CONFIG_NLS_ISO8859_1=m
+ CONFIG_NLS_ISO8859_2=m
+ CONFIG_NLS_ISO8859_3=m
+@@ -824,97 +1111,49 @@
+ CONFIG_NLS_UTF8=m
+ 
+ #
+-# Sound
+-#
+-CONFIG_SOUND=y
+-CONFIG_DMASOUND_PAULA=m
+-CONFIG_DMASOUND=m
+-
+-#
+-# Advanced Linux Sound Architecture
+-#
+-# CONFIG_SND is not set
+-
+-#
+-# Open Sound System
+-#
+-CONFIG_SOUND_PRIME=m
+-# CONFIG_SOUND_BT878 is not set
+-# CONFIG_SOUND_CMPCI is not set
+-# CONFIG_SOUND_EMU10K1 is not set
+-# CONFIG_SOUND_FUSION is not set
+-# CONFIG_SOUND_CS4281 is not set
+-# CONFIG_SOUND_ES1370 is not set
+-# CONFIG_SOUND_ES1371 is not set
+-# CONFIG_SOUND_ESSSOLO1 is not set
+-# CONFIG_SOUND_MAESTRO is not set
+-# CONFIG_SOUND_MAESTRO3 is not set
+-# CONFIG_SOUND_ICH is not set
+-# CONFIG_SOUND_RME96XX is not set
+-# CONFIG_SOUND_SONICVIBES is not set
+-# CONFIG_SOUND_TRIDENT is not set
+-# CONFIG_SOUND_MSNDCLAS is not set
+-# CONFIG_SOUND_MSNDPIN is not set
+-# CONFIG_SOUND_VIA82CXXX is not set
+-CONFIG_SOUND_OSS=m
+-CONFIG_SOUND_TRACEINIT=y
+-CONFIG_SOUND_DMAP=y
+-# CONFIG_SOUND_AD1816 is not set
+-# CONFIG_SOUND_SGALAXY is not set
+-# CONFIG_SOUND_ADLIB is not set
+-# CONFIG_SOUND_ACI_MIXER is not set
+-# CONFIG_SOUND_CS4232 is not set
+-# CONFIG_SOUND_SSCAPE is not set
+-# CONFIG_SOUND_GUS is not set
+-CONFIG_SOUND_VMIDI=m
+-# CONFIG_SOUND_TRIX is not set
+-# CONFIG_SOUND_MSS is not set
+-# CONFIG_SOUND_MPU401 is not set
+-# CONFIG_SOUND_NM256 is not set
+-# CONFIG_SOUND_MAD16 is not set
+-# CONFIG_SOUND_PAS is not set
+-# CONFIG_SOUND_PSS is not set
+-# CONFIG_SOUND_SB is not set
+-# CONFIG_SOUND_AWE32_SYNTH is not set
+-# CONFIG_SOUND_WAVEFRONT is not set
+-# CONFIG_SOUND_MAUI is not set
+-# CONFIG_SOUND_YM3812 is not set
+-# CONFIG_SOUND_OPL3SA1 is not set
+-# CONFIG_SOUND_OPL3SA2 is not set
+-# CONFIG_SOUND_YMFPCI is not set
+-# CONFIG_SOUND_UART6850 is not set
+-# CONFIG_SOUND_AEDSP16 is not set
+-
+-#
+-# USB support
+-#
+-# CONFIG_USB is not set
+-# CONFIG_USB_GADGET is not set
+-
+-#
+-# Bluetooth support
+-#
+-# CONFIG_BT is not set
+-
+-#
+ # Library routines
+ #
+-# CONFIG_CRC32 is not set
++CONFIG_CRC_CCITT=y
++# CONFIG_CRC16 is not set
++CONFIG_CRC32=y
++CONFIG_LIBCRC32C=m
+ CONFIG_ZLIB_INFLATE=y
+ CONFIG_ZLIB_DEFLATE=y
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+-# CONFIG_DEBUG_KERNEL is not set
+-# CONFIG_KALLSYMS is not set
++# CONFIG_PRINTK_TIME is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_MAGIC_SYSRQ=y
++CONFIG_LOG_BUF_SHIFT=14
++# CONFIG_DETECT_SOFTLOCKUP is not set
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_DEBUG_SLAB is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
++# CONFIG_DEBUG_KOBJECT is not set
++# CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_FS is not set
++# CONFIG_XMON is not set
++# CONFIG_BDI_SWITCH is not set
+ 
+ #
+ # Security options
+ #
++# CONFIG_KEYS is not set
+ # CONFIG_SECURITY is not set
+ 
+ #
+ # Cryptographic options
+ #
+ # CONFIG_CRYPTO is not set
++
++#
++# Hardware crypto devices
++#
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/Makefile linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/Makefile
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/Makefile	2005-12-25 12:11:25.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/Makefile	2005-12-29 09:30:41.000000000 +0000
+@@ -10,9 +10,10 @@
+ extra-$(CONFIG_8xx)		:= head_8xx.o
+ extra-$(CONFIG_6xx)		+= idle_6xx.o
+ extra-$(CONFIG_POWER4)		+= idle_power4.o
++extra-y				+= entry.o head_end.o
+ extra-y				+= vmlinux.lds
+ 
+-obj-y				:= entry.o traps.o idle.o time.o misc.o \
++obj-y				:= traps.o idle.o time.o misc.o \
+ 					process.o \
+ 					setup.o \
+ 					ppc_htab.o
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/head.S linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/head.S
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/head.S	2005-12-25 12:11:25.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/head.S	2005-12-29 09:27:44.000000000 +0000
+@@ -353,6 +353,28 @@
+ #if defined(CONFIG_GEMINI) && defined(CONFIG_SMP)
+ 	. = 0x100
+ 	b	__secondary_start_gemini
++#elif defined(CONFIG_APUS)
++	. = 0x100
++	mfspr	r4,SPRN_HID0
++	li	r3,0
++	ori	r3,r3,0xc000
++	andc	r4,r4,r3
++	mtspr	SPRN_HID0,r4
++	isync
++	sync
++	lis	r8,0x6170
++	ori	r8,r8,0x7573
++	lis	r9,0xfff0
++	lwz	r9,0x1f8(r9)
++	lis	r1,init_thread_union at ha
++	addi	r1,r1,init_thread_union at l
++	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
++	subis	r1,r1,KERNELBASE at h
++	add	r1,r1,r9
++	mr	r3,r8
++	mr	r4,r9
++	mtlr	r4
++	blrl
+ #else
+ 	EXCEPTION(0x100, Reset, unknown_exception, EXC_XFER_STD)
+ #endif
+@@ -408,7 +430,15 @@
+ 	bne	1f			/* if not, try to put a PTE */
+ 	mfspr	r4,SPRN_DAR		/* into the hash table */
+ 	rlwinm	r3,r10,32-15,21,21	/* DSISR_STORE -> _PAGE_RW */
++#ifndef CONFIG_APUS
+ 	bl	hash_page
++#else
++	lis     r5,hash_page at h
++	ori	r5,r5,hash_page at l
++	tophys(r5,r5)
++	mtlr	r5
++	blrl
++#endif
+ 1:	stw	r10,_DSISR(r11)
+ 	mr	r5,r10
+ 	mfspr	r4,SPRN_DAR
+@@ -433,7 +463,15 @@
+ 	beq	1f			/* if so, try to put a PTE */
+ 	li	r3,0			/* into the hash table */
+ 	mr	r4,r12			/* SRR0 is fault address */
++#ifndef CONFIG_APUS
+ 	bl	hash_page
++#else
++	lis     r5,hash_page at h
++	ori	r5,r5,hash_page at l
++	tophys(r5,r5)
++	mtlr	r5
++	blrl
++#endif
+ 1:	mr	r4,r12
+ 	mr	r5,r9
+ 	EXC_XFER_EE_LITE(0x400, handle_page_fault)
+@@ -1193,19 +1231,6 @@
+ 	bl	machine_init
+ 	bl	MMU_init
+ 
+-#ifdef CONFIG_APUS
+-	/* Copy exception code to exception vector base on APUS. */
+-	lis	r4,KERNELBASE at h
+-#ifdef CONFIG_APUS_FAST_EXCEPT
+-	lis	r3,0xfff0		/* Copy to 0xfff00000 */
+-#else
+-	lis	r3,0			/* Copy to 0x00000000 */
+-#endif
+-	li	r5,0x4000		/* # bytes of memory to copy */
+-	li	r6,0
+-	bl	copy_and_flush		/* copy the first 0x4000 bytes */
+-#endif  /* CONFIG_APUS */
+-
+ /*
+  * Go back to running unmapped so we can load up new values
+  * for SDR1 (hash table pointer) and the segment registers
+@@ -1223,6 +1248,22 @@
+ /* Load up the kernel context */
+ 2:	bl	load_up_mmu
+ 
++#ifdef CONFIG_APUS
++	/* Copy exception code to exception vector base on APUS. */
++	lis	r4,KERNELBASE at h
++	tophys(r4,r4)
++#ifdef CONFIG_APUS_FAST_EXCEPT
++	lis	r3,0xfff0		/* Copy to 0xfff00000 */
++#else
++	lis	r3,0			/* Copy to 0x00000000 */
++#endif
++	lis	r5,__head_end at h		/* # bytes of memory to copy */
++	ori	r5,r5,__head_end at l
++	subis	r5,r5,KERNELBASE at h
++	li	r6,0
++	bl	copy_and_flush		/* copy the first 0x4000 bytes */
++#endif  /* CONFIG_APUS */
++
+ #ifdef CONFIG_BDI_SWITCH
+ 	/* Add helper information for the Abatron bdiGDB debugger.
+ 	 * We do this here because we know the mmu is disabled, and
+@@ -1403,6 +1444,17 @@
+ 	mtspr	SPRN_DBAT0U,r11		/* bit in upper BAT register */
+ 	mtspr	SPRN_IBAT0L,r8
+ 	mtspr	SPRN_IBAT0U,r11
++#ifdef CONFIG_APUS
++	/* map ZII space for early debug prints */
++	lis	r8,0x8000
++	ori	r8,r8,0x01ff
++	mtspr	SPRN_DBAT2U,r8
++	mtspr	SPRN_IBAT2U,r8
++	lis	r8,0x0000
++	ori	r8,r8,0x002a
++	mtspr	SPRN_DBAT2L,r8
++	mtspr	SPRN_IBAT2L,r8
++#endif
+ 	isync
+ 	blr
+ 
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/head_end.S linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/head_end.S
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/head_end.S	1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/head_end.S	2005-12-29 09:27:44.000000000 +0000
+@@ -0,0 +1,2 @@
++	.global __head_end
++__head_end:
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/misc.S linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/misc.S
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/misc.S	2005-12-25 12:11:25.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/misc.S	2005-12-29 09:27:44.000000000 +0000
+@@ -1325,7 +1325,11 @@
+ 	.long sys_fstat64
+ 	.long sys_pciconfig_read
+ 	.long sys_pciconfig_write
++#ifdef CONFIG_PCI
+ 	.long sys_pciconfig_iobase 	/* 200 */
++#else
++	.long sys_ni_syscall
++#endif
+ 	.long sys_ni_syscall		/* 201 - reserved - MacOnLinux - new */
+ 	.long sys_getdents64
+ 	.long sys_pivot_root
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/ppc_ksyms.c linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/ppc_ksyms.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/ppc_ksyms.c	2005-12-25 12:11:25.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/ppc_ksyms.c	2005-12-29 09:27:44.000000000 +0000
+@@ -65,8 +65,6 @@
+ long long __ashldi3(long long, int);
+ long long __lshrdi3(long long, int);
+ 
+-extern unsigned long mm_ptov (unsigned long paddr);
+-
+ EXPORT_SYMBOL(clear_pages);
+ EXPORT_SYMBOL(clear_user_page);
+ EXPORT_SYMBOL(do_signal);
+@@ -146,7 +144,6 @@
+ EXPORT_SYMBOL(_insl_ns);
+ EXPORT_SYMBOL(_outsl_ns);
+ EXPORT_SYMBOL(iopa);
+-EXPORT_SYMBOL(mm_ptov);
+ EXPORT_SYMBOL(ioremap);
+ #ifdef CONFIG_44x
+ EXPORT_SYMBOL(ioremap64);
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/setup.c linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/setup.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/setup.c	2005-12-25 12:11:25.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/setup.c	2005-12-29 09:27:44.000000000 +0000
+@@ -566,6 +566,7 @@
+ #endif /* CONFIG_SERIAL_CORE_CONSOLE */
+ #endif /* CONFIG_PPC_MULTIPLATFORM */
+ 
++#ifndef CONFIG_APUS
+ struct bi_record *find_bootinfo(void)
+ {
+ 	struct bi_record *rec;
+@@ -624,6 +625,7 @@
+ 		rec = (struct bi_record *)((ulong)rec + rec->size);
+ 	}
+ }
++#endif
+ 
+ /*
+  * Find out what kind of machine we're on and save any data we need
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/time.c linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/time.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/kernel/time.c	2005-12-25 12:11:25.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/kernel/time.c	2005-12-29 09:27:44.000000000 +0000
+@@ -156,6 +156,7 @@
+ 		tb_last_stamp = jiffy_stamp;
+ 		do_timer(regs);
+ 
++#ifndef CONFIG_APUS
+ 		/*
+ 		 * update the rtc when needed, this should be performed on the
+ 		 * right fraction of a second. Half or full second ?
+@@ -182,6 +183,7 @@
+ 				/* Try again one minute later */
+ 				last_rtc_update += 60;
+ 		}
++#endif
+ 		write_sequnlock(&xtime_lock);
+ 	}
+ 	if ( !disarm_decr[smp_processor_id()] )
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/mm/Makefile linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/mm/Makefile
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/mm/Makefile	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/mm/Makefile	2005-12-29 09:27:44.000000000 +0000
+@@ -5,7 +5,8 @@
+ obj-y				:= fault.o init.o mem_pieces.o \
+ 					mmu_context.o pgtable.o
+ 
+-obj-$(CONFIG_PPC_STD_MMU)	+= hashtable.o ppc_mmu.o tlb.o
++extra-$(CONFIG_PPC_STD_MMU)	:= hashtable.o
++obj-$(CONFIG_PPC_STD_MMU)	+= ppc_mmu.o tlb.o
+ obj-$(CONFIG_40x)		+= 4xx_mmu.o
+ obj-$(CONFIG_44x)		+= 44x_mmu.o
+ obj-$(CONFIG_FSL_BOOKE)		+= fsl_booke_mmu.o
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/mm/init.c linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/mm/init.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/mm/init.c	2005-12-25 12:11:25.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/mm/init.c	2005-12-29 09:27:44.000000000 +0000
+@@ -61,9 +61,6 @@
+ unsigned long total_memory;
+ unsigned long total_lowmem;
+ 
+-unsigned long ppc_memstart;
+-unsigned long ppc_memoffset = PAGE_OFFSET;
+-
+ int mem_init_done;
+ int init_bootmem_done;
+ int boot_mapsize;
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/mm/pgtable.c linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/mm/pgtable.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/mm/pgtable.c	2005-12-25 12:11:25.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/mm/pgtable.c	2005-12-29 09:27:45.000000000 +0000
+@@ -190,8 +190,8 @@
+ 	 * Don't allow anybody to remap normal RAM that we're using.
+ 	 * mem_init() sets high_memory so only do the check after that.
+ 	 */
+-	if ( mem_init_done && (p < virt_to_phys(high_memory)) )
+-	{
++	if (mem_init_done && (p + size >= virt_to_phys(KERNELBASE)) &&
++	    (p < virt_to_phys(high_memory))) {
+ 		printk("__ioremap(): phys addr "PHYS_FMT" is RAM lr %p\n", p,
+ 		       __builtin_return_address(0));
+ 		return NULL;
+@@ -427,42 +427,3 @@
+ 
+ 	return(pa);
+ }
+-
+-/* This is will find the virtual address for a physical one....
+- * Swiped from APUS, could be dangerous :-).
+- * This is only a placeholder until I really find a way to make this
+- * work.  -- Dan
+- */
+-unsigned long
+-mm_ptov (unsigned long paddr)
+-{
+-	unsigned long ret;
+-#if 0
+-	if (paddr < 16*1024*1024)
+-		ret = ZTWO_VADDR(paddr);
+-	else {
+-		int i;
+-
+-		for (i = 0; i < kmap_chunk_count;){
+-			unsigned long phys = kmap_chunks[i++];
+-			unsigned long size = kmap_chunks[i++];
+-			unsigned long virt = kmap_chunks[i++];
+-			if (paddr >= phys
+-			    && paddr < (phys + size)){
+-				ret = virt + paddr - phys;
+-				goto exit;
+-			}
+-		}
+-	
+-		ret = (unsigned long) __va(paddr);
+-	}
+-exit:
+-#ifdef DEBUGPV
+-	printk ("PTOV(%lx)=%lx\n", paddr, ret);
+-#endif
+-#else
+-	ret = (unsigned long)paddr + KERNELBASE;
+-#endif
+-	return ret;
+-}
+-
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/platforms/apus_setup.c linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/platforms/apus_setup.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/arch/ppc/platforms/apus_setup.c	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/platforms/apus_setup.c	2005-12-29 09:27:45.000000000 +0000
+@@ -17,11 +17,14 @@
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
+ #include <linux/initrd.h>
++#include <linux/module.h>
+ #include <linux/seq_file.h>
+ 
+ /* Needs INITSERIAL call in head.S! */
+-#undef APUS_DEBUG
++#define APUS_DEBUG
+ 
+ #include <asm/bootinfo.h>
+ #include <asm/setup.h>
+@@ -32,52 +35,27 @@
+ #include <asm/dma.h>
+ #include <asm/machdep.h>
+ #include <asm/time.h>
++#include <asm/tlbflush.h>
+ 
+ unsigned long m68k_machtype;
+ char debug_device[6] = "";
+ 
+-extern void amiga_init_IRQ(void);
+-
+-extern void apus_setup_pci_ptrs(void);
+-
+-void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata = NULL;
+-/* machine dependent irq functions */
+-void (*mach_init_IRQ) (void) __initdata = NULL;
+-void (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
+-void (*mach_get_model) (char *model) = NULL;
+-int (*mach_get_hardware_list) (char *buffer) = NULL;
+-int (*mach_get_irq_list) (struct seq_file *, void *) = NULL;
+-void (*mach_process_int) (int, struct pt_regs *) = NULL;
+-/* machine dependent timer functions */
+-unsigned long (*mach_gettimeoffset) (void);
+-void (*mach_gettod) (int*, int*, int*, int*, int*, int*);
+-int (*mach_hwclk) (int, struct hwclk_time*) = NULL;
+-int (*mach_set_clock_mmss) (unsigned long) = NULL;
+-void (*mach_reset)( void );
+-long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */
+-#if defined(CONFIG_AMIGA_FLOPPY)
+-void (*mach_floppy_setup) (char *, int *) __initdata = NULL;
+-#endif
+-#ifdef CONFIG_HEARTBEAT
+-void (*mach_heartbeat) (int) = NULL;
+-extern void apus_heartbeat (void);
+-#endif
+-
+-extern unsigned long amiga_model;
+-extern unsigned decrementer_count;/* count value for 1e6/HZ microseconds */
+-extern unsigned count_period_num; /* 1 decrementer count equals */
+-extern unsigned count_period_den; /* count_period_num / count_period_den us */
+-
+ int num_memory = 0;
+ struct mem_info memory[NUM_MEMINFO];/* memory description */
+ /* FIXME: Duplicate memory data to avoid conflicts with m68k shared code. */
+ int m68k_realnum_memory = 0;
+-struct mem_info m68k_memory[NUM_MEMINFO];/* memory description */
++EXPORT_SYMBOL(memory);
++EXPORT_SYMBOL(m68k_realnum_memory);
++
++unsigned long ppc_memstart;
++unsigned long ppc_pgstart;
++unsigned long ppc_memoffset;
++
++EXPORT_SYMBOL(ppc_memoffset);
++EXPORT_SYMBOL(ppc_pgstart);
+ 
+ struct mem_info ramdisk;
+ 
+-extern void amiga_floppy_setup(char *, int *);
+-extern void config_amiga(void);
+ 
+ static int __60nsram = 0;
+ 
+@@ -92,25 +70,43 @@
+  */
+ unsigned long apus_get_rtc_time(void)
+ {
+-#ifdef CONFIG_APUS
+-	extern unsigned long m68k_get_rtc_time(void);
++	struct rtc_time t;
+ 
+-	return m68k_get_rtc_time ();
+-#else
+-	return 0;
+-#endif
++	amiga_hwclk(0, &t);
++	t.tm_year += 1900;
++
++	return mktime(t.tm_year, t.tm_mon, t.tm_mday,
++		      t.tm_hour, t.tm_min, t.tm_sec);
+ }
+ 
+ int apus_set_rtc_time(unsigned long nowtime)
+ {
+-#ifdef CONFIG_APUS
+-	extern int m68k_set_rtc_time(unsigned long nowtime);
++	return amiga_set_clock_mmss(nowtime);
++}
+ 
+-	return m68k_set_rtc_time (nowtime);
+-#else
+-	return 0;
+-#endif
++#ifdef CONFIG_HEARTBEAT
++static void apus_heartbeat(void)
++{
++	static unsigned cnt = 0, period = 0, dist = 0;
++
++	if (cnt == 0 || cnt == dist)
++		ciaa.pra &= ~2;
++	else if (cnt == 7 || cnt == dist + 7)
++		ciaa.pra |= 2;
++
++	if (++cnt > period) {
++		cnt = 0;
++		/* The hyperbolic function below modifies the heartbeat period
++		 * length in dependency of the current (5min) load. It goes
++		 * through the points f(0)=126, f(1)=86, f(5)=51,
++		 * f(inf)->30. */
++		period = ((672<<FSHIFT) / (5*avenrun[0] + (7<<FSHIFT))) + 30;
++		dist = period / 4;
++	}
++	/* should be made smarter */
++	ppc_md.heartbeat_count = 1;
+ }
++#endif
+ 
+ /*********************************************************** SETUP */
+ /* From arch/m68k/kernel/setup.c. */
+@@ -206,8 +202,8 @@
+ 
+ void apus_calibrate_decr(void)
+ {
+-#ifdef CONFIG_APUS
+ 	unsigned long freq;
++	unsigned int tmp;
+ 
+ 	/* This algorithm for determining the bus speed was
+            contributed by Ralph Schmidt. */
+@@ -239,15 +235,34 @@
+ 		freq = 15000000;
+ 	} else if ((bus_speed >= 63) && (bus_speed < 69)) {
+ 		bus_speed = 67;
+-		freq = 16666667;
++		freq = 16500000;
+ 	} else {
+ 		printk ("APUS: Unable to determine bus speed (%d). "
+-			"Defaulting to 50MHz", bus_speed);
++			"Defaulting to 50MHz\n", bus_speed);
+ 		bus_speed = 50;
+ 		freq = 12500000;
+ 		speed_test_failed = 1;
+ 	}
+ 
++	ciab.cra = (ciab.cra & 0xc0) | 0x08;
++	ciab.icr;
++	wmb();
++	ciab.talo = 0;
++	wmb();
++	ciab.tahi = 0x80;
++	wmb();
++
++	get_current_tb(&start);
++	while (!(ciab.icr & 1))
++		barrier();
++	get_current_tb(&stop);
++
++	tmp = stop - start;
++	start = tmp * amiga_eclock;
++	stop = mulhwu(tmp, amiga_eclock);
++	start += stop << 32;
++	freq = start / 0x8000;
++
+ 	/* Ease diagnostics... */
+ 	{
+ 		extern int __map_without_bats;
+@@ -285,36 +300,8 @@
+ 
+ 	__bus_speed = bus_speed;
+ 	__speed_test_failed = speed_test_failed;
+-#endif
+-}
+-
+-void arch_gettod(int *year, int *mon, int *day, int *hour,
+-		 int *min, int *sec)
+-{
+-#ifdef CONFIG_APUS
+-	if (mach_gettod)
+-		mach_gettod(year, mon, day, hour, min, sec);
+-	else
+-		*year = *mon = *day = *hour = *min = *sec = 0;
+-#endif
+ }
+ 
+-/* for "kbd-reset" cmdline param */
+-__init
+-void kbd_reset_setup(char *str, int *ints)
+-{
+-}
+-
+-/*********************************************************** FLOPPY */
+-#if defined(CONFIG_AMIGA_FLOPPY)
+-__init
+-void floppy_setup(char *str, int *ints)
+-{
+-	if (mach_floppy_setup)
+-		mach_floppy_setup (str, ints);
+-}
+-#endif
+-
+ /*********************************************************** MEMORY */
+ #define KMAP_MAX 32
+ unsigned long kmap_chunks[KMAP_MAX*3];
+@@ -330,26 +317,22 @@
+ 	va &= PAGE_MASK;
+ 
+ 	dir = pgd_offset( mm, va );
+-	if (dir)
+-	{
++	if (dir) {
+ 		pmd = pmd_offset(dir, va & PAGE_MASK);
+ 		if (pmd && pmd_present(*pmd))
+-		{
+-			pte = pte_offset(pmd, va);
+-		}
++			pte = pte_offset_kernel(pmd, va);
+ 	}
+ 	return pte;
+ }
+ 
+ 
+ /* Again simulating an m68k/mm/kmap.c function. */
+-void kernel_set_cachemode( unsigned long address, unsigned long size,
+-			   unsigned int cmode )
++void kernel_set_cachemode(unsigned long address, unsigned long size,
++			  unsigned int cmode)
+ {
+-	unsigned long mask, flags;
++	unsigned long mask, flags, end;
+ 
+-	switch (cmode)
+-	{
++	switch (cmode) {
+ 	case IOMAP_FULL_CACHING:
+ 		mask = ~(_PAGE_NO_CACHE | _PAGE_GUARDED);
+ 		flags = 0;
+@@ -359,60 +342,29 @@
+ 		flags = (_PAGE_NO_CACHE | _PAGE_GUARDED);
+ 		break;
+ 	default:
+-		panic ("kernel_set_cachemode() doesn't support mode %d\n",
+-		       cmode);
++		panic("kernel_set_cachemode() doesn't support mode %d\n", cmode);
+ 		break;
+ 	}
+ 
+-	size /= PAGE_SIZE;
++	end = address + size;
+ 	address &= PAGE_MASK;
+-	while (size--)
+-	{
++	while (address < end) {
+ 		pte_t *pte;
+ 
+ 		pte = my_find_pte(&init_mm, address);
+-		if ( !pte )
+-		{
++		if (!pte) {
+ 			printk("pte NULL in kernel_set_cachemode()\n");
+ 			return;
+ 		}
+ 
+-                pte_val (*pte) &= mask;
+-                pte_val (*pte) |= flags;
++                pte_val(*pte) &= mask;
++                pte_val(*pte) |= flags;
+                 flush_tlb_page(find_vma(&init_mm,address),address);
+ 
+ 		address += PAGE_SIZE;
+ 	}
+ }
+ 
+-unsigned long mm_ptov (unsigned long paddr)
+-{
+-	unsigned long ret;
+-	if (paddr < 16*1024*1024)
+-		ret = ZTWO_VADDR(paddr);
+-	else {
+-		int i;
+-
+-		for (i = 0; i < kmap_chunk_count;){
+-			unsigned long phys = kmap_chunks[i++];
+-			unsigned long size = kmap_chunks[i++];
+-			unsigned long virt = kmap_chunks[i++];
+-			if (paddr >= phys
+-			    && paddr < (phys + size)){
+-				ret = virt + paddr - phys;
+-				goto exit;
+-			}
+-		}
+-
+-		ret = (unsigned long) __va(paddr);
+-	}
+-exit:
+-#ifdef DEBUGPV
+-	printk ("PTOV(%lx)=%lx\n", paddr, ret);
+-#endif
+-	return ret;
+-}
+-
+ int mm_end_of_chunk (unsigned long addr, int len)
+ {
+ 	if (memory[0].addr + memory[0].size == addr + len)
+@@ -422,11 +374,10 @@
+ 
+ /*********************************************************** CACHE */
+ 
+-#define L1_CACHE_BYTES 32
+ #define MAX_CACHE_SIZE 8192
+-void cache_push(__u32 addr, int length)
++void cache_push(u32 paddr, int length)
+ {
+-	addr = mm_ptov(addr);
++	char *addr = __va(paddr);
+ 
+ 	if (MAX_CACHE_SIZE < length)
+ 		length = MAX_CACHE_SIZE;
+@@ -443,12 +394,14 @@
+ 	       : : "r" (addr));
+ }
+ 
+-void cache_clear(__u32 addr, int length)
++void cache_clear(u32 paddr, int length)
+ {
++	char *addr;
++
+ 	if (MAX_CACHE_SIZE < length)
+ 		length = MAX_CACHE_SIZE;
+ 
+-	addr = mm_ptov(addr);
++	addr = __va(paddr);
+ 
+ 	__asm ("dcbf 0,%0\n\t"
+ 	       "sync \n\t"
+@@ -518,6 +471,8 @@
+ 	level = (ipl_emu >> 3) & IPLEMU_IPLMASK;
+ 	mask = IPLEMU_SETRESET|IPLEMU_DISABLEINT|level;
+ 	level ^= 7;
++	if (!level)
++		return -1;
+ 
+ 	/* Save previous IPL value */
+ 	if (last_ipl[level])
+@@ -535,6 +490,15 @@
+ 	return level + IRQ_AMIGA_AUTO;
+ }
+ 
++unsigned int apus_startup_irq(unsigned int irq)
++{
++	return 0;
++}
++
++void apus_ack_irq(unsigned int irq)
++{
++}
++
+ void apus_end_irq(unsigned int irq)
+ {
+ 	unsigned char ipl_emu;
+@@ -646,10 +610,12 @@
+ 	__debug_ser_out('\r');
+ }
+ 
++#ifdef APUS_DEBUG
+ static void apus_progress(char *s, unsigned short value)
+ {
+ 	__debug_print_string(s);
+ }
++#endif
+ 
+ /****************************************************** init */
+ 
+@@ -664,6 +630,8 @@
+ 
+ struct hw_interrupt_type amiga_sys_irqctrl = {
+ 	.typename = "Amiga IPL",
++	.startup = apus_startup_irq,
++	.ack = apus_ack_irq,
+ 	.end = apus_end_irq,
+ };
+ 
+@@ -677,33 +645,32 @@
+ unsigned long __init apus_find_end_of_memory(void)
+ {
+ 	int shadow = 0;
+-	unsigned long total;
++	unsigned long total, size;
+ 
+ 	/* The memory size reported by ADOS excludes the 512KB
+ 	   reserved for PPC exception registers and possibly 512KB
+ 	   containing a shadow of the ADOS ROM. */
+-	{
+-		unsigned long size = memory[0].size;
+-
+-		/* If 2MB aligned, size was probably user
+-                   specified. We can't tell anything about shadowing
+-                   in this case so skip shadow assignment. */
+-		if (0 != (size & 0x1fffff)){
+-			/* Align to 512KB to ensure correct handling
+-			   of both memfile and system specified
+-			   sizes. */
+-			size = ((size+0x0007ffff) & 0xfff80000);
+-			/* If memory is 1MB aligned, assume
+-                           shadowing. */
+-			shadow = !(size & 0x80000);
+-		}
++	size = memory[0].size;
+ 
+-		/* Add the chunk that ADOS does not see. by aligning
+-                   the size to the nearest 2MB limit upwards.  */
+-		memory[0].size = ((size+0x001fffff) & 0xffe00000);
+-	}
++	/* If 2MB aligned, size was probably user
++	   specified. We can't tell anything about shadowing
++	   in this case so skip shadow assignment. */
++	if (size & 0x1fffff){
++		/* Align to 512KB to ensure correct handling
++		   of both memfile and system specified
++		   sizes. */
++		size = ((size+0x0007ffff) & 0xfff80000);
++		/* If memory is 1MB aligned, assume
++		   shadowing. */
++		shadow = !(size & 0x80000);
++	}
++
++	/* Add the chunk that ADOS does not see. by aligning
++	   the size to the nearest 2MB limit upwards.  */
++	memory[0].size = (size + 0x001fffff) & 0xffe00000;
+ 
+ 	ppc_memstart = memory[0].addr;
++	ppc_pgstart = memory[0].addr >> PAGE_SHIFT;
+ 	ppc_memoffset = PAGE_OFFSET - PPC_MEMSTART;
+ 	total = memory[0].size;
+ 
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/drivers/block/amiflop.c linux-2.6-2.6.14+2.6.15-rc7/drivers/block/amiflop.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/drivers/block/amiflop.c	2005-12-25 12:11:26.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/drivers/block/amiflop.c	2005-12-29 09:27:45.000000000 +0000
+@@ -59,6 +59,7 @@
+ #include <linux/hdreg.h>
+ #include <linux/delay.h>
+ #include <linux/init.h>
++#include <linux/interrupt.h>
+ #include <linux/amifdreg.h>
+ #include <linux/amifd.h>
+ #include <linux/buffer_head.h>
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/drivers/video/console/fonts.c linux-2.6-2.6.14+2.6.15-rc7/drivers/video/console/fonts.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/drivers/video/console/fonts.c	2005-11-20 13:51:30.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/drivers/video/console/fonts.c	2005-12-29 09:27:45.000000000 +0000
+@@ -118,7 +118,13 @@
+     for(i=0; i<num_fonts; i++) {
+ 	f = fonts[i];
+ 	c = f->pref;
+-#if defined(__mc68000__) || defined(CONFIG_APUS)
++#if defined(CONFIG_APUS)
++#ifdef CONFIG_FONT_PEARL_8x8
++	if (f->idx == PEARL8x8_IDX)
++	    c = 100;
++#endif
++#endif
++#if defined(__mc68000__)
+ #ifdef CONFIG_FONT_PEARL_8x8
+ 	if (MACH_IS_AMIGA && f->idx == PEARL8x8_IDX)
+ 	    c = 100;
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-m68k/bootinfo.h linux-2.6-2.6.14+2.6.15-rc7/include/asm-m68k/bootinfo.h
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-m68k/bootinfo.h	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/include/asm-m68k/bootinfo.h	2005-12-29 09:27:45.000000000 +0000
+@@ -81,6 +81,8 @@
+ #define BI_AMIGA_ECLOCK		0x8005	/* EClock frequency (u_long) */
+ #define BI_AMIGA_CHIPSET	0x8006	/* native chipset present (u_long) */
+ #define BI_AMIGA_SERPER		0x8007	/* serial port period (u_short) */
++#define BI_AMIGA_PUP_BRIDGE	0x8008	/* powerup bridge (u_short) */
++#define BI_AMIGA_BPPC_SCSI	0x8009	/* blizzard ppc scsi*/
+ 
+     /*
+      *  Atari-specific tags
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-ppc/amigahw.h linux-2.6-2.6.14+2.6.15-rc7/include/asm-ppc/amigahw.h
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-ppc/amigahw.h	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/include/asm-ppc/amigahw.h	2005-12-29 09:27:45.000000000 +0000
+@@ -1,6 +1,6 @@
+-#ifdef __KERNEL__
+ #ifndef __ASMPPC_AMIGAHW_H
+ #define __ASMPPC_AMIGAHW_H
++#ifdef __KERNEL__
+ 
+ #include <linux/config.h>
+ #include <asm-m68k/amigahw.h>
+@@ -12,6 +12,29 @@
+ #define CHIP_PHYSADDR      (0x004000)
+ #endif
+ 
++struct rtc_time;
++
++extern void amiga_init_IRQ(void);
++extern int amiga_hwclk(int, struct rtc_time *);
++extern int amiga_set_clock_mmss (unsigned long nowtime);
++extern void config_amiga(void);
++extern void apus_setup_pci_ptrs(void);
++
++#define MACH_IS_AMIGA	1
++#define MACH_AMIGA	1
++#define NUM_MEMINFO	4
++
++struct mem_info {
++	unsigned long addr;		/* physical address of memory chunk */
++	unsigned long size;		/* length of memory chunk (in bytes) */
++};
++
++extern int num_memory;		/* # of memory blocks found (and used) */
++extern int m68k_realnum_memory;		/* real # of memory blocks found */
++extern struct mem_info memory[NUM_MEMINFO];/* memory description */
++
++#define m68k_num_memory num_memory
++#define m68k_memory memory
+ 
+-#endif /* __ASMPPC_AMIGAHW_H */
+ #endif /* __KERNEL__ */
++#endif /* __ASMPPC_AMIGAHW_H */
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-ppc/bootinfo.h linux-2.6-2.6.14+2.6.15-rc7/include/asm-ppc/bootinfo.h
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-ppc/bootinfo.h	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/include/asm-ppc/bootinfo.h	2005-12-29 09:27:45.000000000 +0000
+@@ -36,7 +36,6 @@
+ extern void bootinfo_init(struct bi_record *rec);
+ extern void bootinfo_append(unsigned long tag, unsigned long size, void * data);
+ extern void parse_bootinfo(struct bi_record *rec);
+-extern unsigned long boot_mem_size;
+ 
+ static inline struct bi_record *
+ bootinfo_addr(unsigned long offset)
+@@ -47,6 +46,7 @@
+ }
+ #endif /* CONFIG_APUS */
+ 
++extern unsigned long boot_mem_size;
+ 
+ #endif /* _PPC_BOOTINFO_H */
+ #endif /* __KERNEL__ */
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-ppc/io.h linux-2.6-2.6.14+2.6.15-rc7/include/asm-ppc/io.h
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-ppc/io.h	2005-12-25 12:11:28.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/include/asm-ppc/io.h	2005-12-29 09:27:45.000000000 +0000
+@@ -1,6 +1,6 @@
+-#ifdef __KERNEL__
+ #ifndef _PPC_IO_H
+ #define _PPC_IO_H
++#ifdef __KERNEL__
+ 
+ #include <linux/config.h>
+ #include <linux/string.h>
+@@ -297,10 +297,10 @@
+ __do_out_asm(outb, "stbx")
+ #ifdef CONFIG_APUS
+ __do_in_asm(inb, "lbzx")
+-__do_in_asm(inw, "lhz%U1%X1")
+-__do_in_asm(inl, "lwz%U1%X1")
+-__do_out_asm(outl,"stw%U0%X0")
+-__do_out_asm(outw, "sth%U0%X0")
++__do_in_asm(inw, "lhzx")
++__do_in_asm(inl, "lwzx")
++__do_out_asm(outl,"stwx")
++__do_out_asm(outw, "sthx")
+ #elif defined (CONFIG_8260_PCI9)
+ /* in asm cannot be defined if PCI9 workaround is used */
+ #define inb(port)		in_8((port)+___IO_BASE)
+@@ -380,12 +380,19 @@
+ extern void __iomem *ioremap64(unsigned long long address, unsigned long size);
+ #endif
+ #define ioremap_nocache(addr, size)	ioremap((addr), (size))
++#define ioremap_writethrough(addr, size) __ioremap((addr), (size), _PAGE_WRITETHRU)
+ extern void iounmap(volatile void __iomem *addr);
+ extern unsigned long iopa(unsigned long addr);
+ extern unsigned long mm_ptov(unsigned long addr) __attribute_const__;
+ extern void io_block_mapping(unsigned long virt, phys_addr_t phys,
+ 			     unsigned int size, int flags);
+ 
++/* Values for nocacheflag and cmode */
++#define IOMAP_FULL_CACHING		0
++#define IOMAP_NOCACHE_SER		1
++#define IOMAP_NOCACHE_NONSER		2
++#define IOMAP_WRITETHROUGH		3
++
+ /*
+  * The PCI bus is inherently Little-Endian.  The PowerPC is being
+  * run Big-Endian.  Thus all values which cross the [PCI] barrier
+@@ -395,24 +402,16 @@
+  */
+ extern inline unsigned long virt_to_bus(volatile void * address)
+ {
+-#ifndef CONFIG_APUS
+         if (address == (void *)0)
+ 		return 0;
+-        return (unsigned long)address - KERNELBASE + PCI_DRAM_OFFSET;
+-#else
+-	return iopa ((unsigned long) address);
+-#endif
++	return __pa(address) + PCI_DRAM_OFFSET;
+ }
+ 
+ extern inline void * bus_to_virt(unsigned long address)
+ {
+-#ifndef CONFIG_APUS
+         if (address == 0)
+ 		return NULL;
+-        return (void *)(address - PCI_DRAM_OFFSET + KERNELBASE);
+-#else
+-	return (void*) mm_ptov (address);
+-#endif
++	return __va(address) - PCI_DRAM_OFFSET;
+ }
+ 
+ /*
+@@ -421,20 +420,12 @@
+  */
+ extern inline unsigned long virt_to_phys(volatile void * address)
+ {
+-#ifndef CONFIG_APUS
+-	return (unsigned long) address - KERNELBASE;
+-#else
+-	return iopa ((unsigned long) address);
+-#endif
++	return __pa(address);
+ }
+ 
+ extern inline void * phys_to_virt(unsigned long address)
+ {
+-#ifndef CONFIG_APUS
+-	return (void *) (address + KERNELBASE);
+-#else
+-	return (void*) mm_ptov (address);
+-#endif
++	return __va(address);
+ }
+ 
+ /*
+@@ -539,8 +530,6 @@
+ extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+ extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
+ 
+-#endif /* _PPC_IO_H */
+-
+ #ifdef CONFIG_8260_PCI9
+ #include <asm/mpc8260_pci9.h>
+ #endif
+@@ -574,3 +563,4 @@
+ #define xlate_dev_kmem_ptr(p)	p
+ 
+ #endif /* __KERNEL__ */
++#endif /* _PPC_IO_H */
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-ppc/machdep.h linux-2.6-2.6.14+2.6.15-rc7/include/asm-ppc/machdep.h
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-ppc/machdep.h	2005-12-25 12:11:28.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/include/asm-ppc/machdep.h	2005-12-29 09:27:45.000000000 +0000
+@@ -9,10 +9,6 @@
+ #include <asm/setup.h>
+ #include <asm/page.h>
+ 
+-#ifdef CONFIG_APUS
+-#include <asm-m68k/machdep.h>
+-#endif
+-
+ struct pt_regs;
+ struct pci_bus;	
+ struct pci_dev;
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-ppc/pgtable.h linux-2.6-2.6.14+2.6.15-rc7/include/asm-ppc/pgtable.h
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-ppc/pgtable.h	2005-12-25 12:11:28.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/include/asm-ppc/pgtable.h	2005-12-29 09:27:45.000000000 +0000
+@@ -724,7 +724,7 @@
+ #define pmd_page_kernel(pmd)	\
+ 	((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+ #define pmd_page(pmd)		\
+-	(mem_map + (pmd_val(pmd) >> PAGE_SHIFT))
++	pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
+ #else
+ #define pmd_page_kernel(pmd)	\
+ 	((unsigned long) (pmd_val(pmd) & PAGE_MASK))
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-ppc/zorro.h linux-2.6-2.6.14+2.6.15-rc7/include/asm-ppc/zorro.h
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/include/asm-ppc/zorro.h	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/include/asm-ppc/zorro.h	2005-12-29 09:27:45.000000000 +0000
+@@ -3,13 +3,50 @@
+ 
+ #include <asm/io.h>
+ 
+-#define z_readb in_8
+-#define z_readw in_be16
+-#define z_readl in_be32
+-
+-#define z_writeb(val, port) out_8((port), (val))
+-#define z_writew(val, port) out_be16((port), (val))
+-#define z_writel(val, port) out_be32((port), (val))
++static inline unsigned int z_readb(unsigned long addr)
++{
++	unsigned int ret;
++
++	ret = *(volatile u8 *)addr;
++	eieio();
++	return ret;
++}
++
++static inline unsigned int z_readw(unsigned long addr)
++{
++	unsigned int ret;
++
++	ret = *(volatile u16 *)addr;
++	eieio();
++	return ret;
++}
++
++static inline unsigned int z_readl(unsigned long addr)
++{
++	unsigned int ret;
++
++	ret = *(volatile u32 *)addr;
++	eieio();
++	return ret;
++}
++
++static inline void z_writeb(unsigned int val, unsigned long addr)
++{
++	*(volatile u8 *)addr = val;
++	eieio();
++}
++
++static inline void z_writew(unsigned int val, unsigned long addr)
++{
++	*(volatile u16 *)addr = val;
++	eieio();
++}
++
++static inline void z_writel(unsigned int val,unsigned long addr)
++{
++	*(volatile u32 *)addr = val;
++	eieio();
++}
+ 
+ #define z_memset_io(a,b,c)	memset((void *)(a),(b),(c))
+ #define z_memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+@@ -19,7 +56,6 @@
+ 		       unsigned long flags);
+ 
+ extern void *ioremap(unsigned long address, unsigned long size);
+-extern void iounmap(void *addr);
+ 
+ extern void *__ioremap(unsigned long address, unsigned long size,
+                        unsigned long flags);
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/include/video/vga.h linux-2.6-2.6.14+2.6.15-rc7/include/video/vga.h
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/include/video/vga.h	2005-10-28 00:02:08.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/include/video/vga.h	2005-12-29 09:27:45.000000000 +0000
+@@ -28,6 +28,7 @@
+  * Ugh, we don't have PCI space, so map readb() and friends to use Zorro space
+  * for MMIO accesses. This should make cirrusfb work again on Amiga
+  */
++#include <asm/zorro.h>
+ #undef inb_p
+ #undef inw_p
+ #undef outb_p
+@@ -36,11 +37,17 @@
+ #undef writeb
+ #undef writew
+ #define inb_p(port)	0
++#undef inw_p
+ #define inw_p(port)	0
++#undef outb_p
+ #define outb_p(port, val)	do { } while (0)
++#undef outw
+ #define outw(port, val)		do { } while (0)
++#undef readb
+ #define readb		z_readb
++#undef writeb
+ #define writeb		z_writeb
++#undef writew
+ #define writew		z_writew
+ #endif
+ #include <asm/byteorder.h>
+diff -Nur linux-2.6-2.6.14+2.6.15-rc7.orig/sound/oss/dmasound/dmasound_paula.c linux-2.6-2.6.14+2.6.15-rc7/sound/oss/dmasound/dmasound_paula.c
+--- linux-2.6-2.6.14+2.6.15-rc7.orig/sound/oss/dmasound/dmasound_paula.c	2005-12-25 12:11:33.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/sound/oss/dmasound/dmasound_paula.c	2005-12-29 09:27:45.000000000 +0000
+@@ -244,6 +244,7 @@
+ 			u_char frame[], ssize_t *frameUsed,		\
+ 			ssize_t frameLeft)				\
+ {									\
++	const u_short *ptr = (const u_short *)userPtr;			\
+ 	ssize_t count, used;						\
+ 	u_short data;							\
+ 									\
+@@ -253,7 +254,7 @@
+ 		count = min_t(size_t, userCount, frameLeft)>>1 & ~1;	\
+ 		used = count*2;						\
+ 		while (count > 0) {					\
+-			if (get_user(data, ((u_short *)userPtr)++))	\
++			if (get_user(data, ptr++))			\
+ 				return -EFAULT;				\
+ 			data = convsample(data);			\
+ 			*high++ = data>>8;				\
+@@ -268,12 +269,12 @@
+ 		count = min_t(size_t, userCount, frameLeft)>>2 & ~1;	\
+ 		used = count*4;						\
+ 		while (count > 0) {					\
+-			if (get_user(data, ((u_short *)userPtr)++))	\
++			if (get_user(data, ptr++))			\
+ 				return -EFAULT;				\
+ 			data = convsample(data);			\
+ 			*lefth++ = data>>8;				\
+ 			*leftl++ = (data>>2) & 0x3f;			\
+-			if (get_user(data, ((u_short *)userPtr)++))	\
++			if (get_user(data, ptr++))			\
+ 				return -EFAULT;				\
+ 			data = convsample(data);			\
+ 			*righth++ = data>>8;				\

Added: people/waldi/linux-2.6/debian/patches/powerpc-arch-default-powerpc.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/powerpc-arch-default-powerpc.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,18 @@
+# 
+# Let's default to ARCH=powerpc, even in 32bit.
+# Author: David Woodhouse <david at woodhou.se>
+# Upstream status: upstream still uses ARCH=ppc on 32bit, but they have to
+# deal also with the embedded arches debian doesn't support.
+#
+
+--- linux-2.6.14/Makefile.orig	2005-11-19 17:13:52.000000000 +0000
++++ linux-2.6.14/Makefile	2005-11-19 17:14:04.000000000 +0000
+@@ -169,7 +169,7 @@ KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$
+ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+ 				  -e s/arm.*/arm/ -e s/sa110/arm/ \
+ 				  -e s/s390x/s390/ -e s/parisc64/parisc/ \
+-				  -e s/ppc64/powerpc/ )
++				  -e s/ppc.*/powerpc/ )
+ 
+ # Cross compiling and selecting different set of gcc/bin-utils
+ # ---------------------------------------------------------------------------

Added: people/waldi/linux-2.6/debian/patches/powerpc-build-links.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/powerpc-build-links.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,12 @@
+diff -urN ../orig/linux-2.6-2.6.13+2.6.14-rc5/arch/ppc/Makefile linux-2.6-2.6.13+2.6.14-rc5/arch/ppc/Makefile
+--- ../orig/linux-2.6-2.6.13+2.6.14-rc5/arch/ppc/Makefile	2005-10-22 18:17:48.000000000 +0000
++++ linux-2.6-2.6.13+2.6.14-rc5/arch/ppc/Makefile	2005-10-23 13:27:47.000000000 +0000
+@@ -113,7 +113,7 @@
+ include/asm: arch/$(ARCH)/include/asm
+ arch/$(ARCH)/include/asm:
+ 	$(Q)if [ ! -d arch/$(ARCH)/include ]; then mkdir -p arch/$(ARCH)/include; fi
+-	$(Q)ln -fsn $(srctree)/include/asm-powerpc arch/$(ARCH)/include/asm
++	$(Q)ln -fsn $(if $(KBUILD_SRC),$(KBUILD_SRC),../../..)/include/asm-powerpc arch/$(ARCH)/include/asm
+ 
+ # Use the file '.tmp_gas_check' for binutils tests, as gas won't output
+ # to stdout and these checks are run even on install targets.

Added: people/waldi/linux-2.6/debian/patches/powerpc-calibrate-tau.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/powerpc-calibrate-tau.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,69 @@
+#! /bin/sh -e 
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Description: Adds support TAU calibration on G3 processors
+## DP: Patch author: Nicolas DET <nd at bplan-gmbh.de>
+## DP: Upstream status: submitted
+
+diff -aurN a/arch/ppc/Kconfig b/arch/ppc/Kconfig
+--- a/arch/ppc/Kconfig	2005-06-06 11:22:29.000000000 -0400
++++ b/arch/ppc/Kconfig	2005-06-17 20:48:38.000000000 -0400
+@@ -198,6 +198,24 @@
+ 
+ 	  If in doubt, say N here.
+ 
++config TAU_CALIBRATED
++        bool "The CPU sensor has been calibrated."
++	depends on TAU
++	help
++	   Enable it you got the real temperature with an external sensor
++	   and you know the offset between the one advertised by the CPU
++	   and the real one
++
++config TAU_CALIBRATED_VALUE
++	int "Offset of the themal sensor"
++	depends on TAU_CALIBRATED
++	default "0"
++	help
++	  This is the offset of the thermal sensor compare to the real value
++	  For example, if you get 27°C in /proc/cpuinfo (uncalibrated) and
++	  you know real one is 53°C, then you should set 26 as offset.
++	  value = Real val - CPU val;
++
+ config MATH_EMULATION
+ 	bool "Math emulation"
+ 	depends on 4xx || 8xx || E500
+diff -aurN a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
+--- a/arch/ppc/kernel/setup.c	2005-06-06 11:22:29.000000000 -0400
++++ b/arch/ppc/kernel/setup.c	2005-06-17 20:50:14.000000000 -0400
+@@ -201,17 +201,25 @@
+ 
+ #ifdef CONFIG_TAU
+ 	if (cur_cpu_spec[i]->cpu_features & CPU_FTR_TAU) {
++#ifdef CONFIG_TAU_CALIBRATED
++		int is_calibrated	= 1;
++		int temp_offset		= CONFIG_TAU_CALIBRATED_VALUE;
++#else
++		int is_calibrated 	= 0;
++		int temp_offset		= 0;
++#endif
+ #ifdef CONFIG_TAU_AVERAGE
+ 		/* more straightforward, but potentially misleading */
+-		seq_printf(m,  "temperature \t: %u C (uncalibrated)\n",
+-			   cpu_temp(i));
++		seq_printf(m,  "temperature \t: %u C %s- average\n",
++			   cpu_temp(i) + temp_offset,  is_calibrated ? "" : "(uncalibrated) " );
+ #else
+ 		/* show the actual temp sensor range */
+ 		u32 temp;
+ 		temp = cpu_temp_both(i);
+-		seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n",
+-			   temp & 0xff, temp >> 16);
+-#endif
++		seq_printf(m, "temperature \t: %u-%u C %s\n",
++			   (temp & 0xff) + temp_offset, (temp >> 16) + temp_offset, is_calibrated ? "" : "(uncalibrated)" );
++
++#endif /* CONFIG_TAU_AVERAGE */
+ 	}
+ #endif /* CONFIG_TAU */
+ 

Added: people/waldi/linux-2.6/debian/patches/powerpc-g3-750cxe.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/powerpc-g3-750cxe.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,87 @@
+#! /bin/sh -e 
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Description: Adds support for 750CXe rev 3.1, prv 0008 3311 (previously recognized as 745/755).
+## DP: Patch author: Nicolas DET <nd at bplan-gmbh.de>
+## DP: Upstream status: submitted
+
+. $(dirname $0)/DPATCH
+
+ at DPATCH@
+--- linux-2.6.14-rc1/arch/ppc/kernel/cputable.c	2005-09-14 08:14:43.672219560 +0200
++++ linux-2.6.14-rc1_nico/arch/ppc/kernel/cputable.c	2005-09-23 17:01:40.355003000 +0200
+@@ -198,6 +198,7 @@
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750
+ 	},
++	// For the 750CX familly see:  http://www-306.ibm.com/chips/techlib/techlib.nsf/techdocs/291C8D0EF3EAEC1687256B72005C745C#C1
+ 	{	/* 750CX (80100 and 8010x?) */
+ 		.pvr_mask		= 0xfffffff0,
+ 		.pvr_value		= 0x00080100,
+@@ -212,10 +213,10 @@
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750cx
+ 	},
+-	{	/* 750CX (82201 and 82202) */
+-		.pvr_mask		= 0xfffffff0,
+-		.pvr_value		= 0x00082200,
+-		.cpu_name		= "750CX",
++	{	/* 750CXe (82202) */
++		.pvr_mask		= 0xffffffff,
++		.pvr_value		= 0x00082202,
++		.cpu_name		= "750CXe rev 2.2",
+ 		.cpu_features		= CPU_FTR_COMMON |
+ 			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+ 			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+@@ -226,10 +227,24 @@
+ 		.num_pmcs		= 4,
+ 		.cpu_setup		= __setup_cpu_750cx
+ 	},
+-	{	/* 750CXe (82214) */
+-		.pvr_mask		= 0xfffffff0,
+-		.pvr_value		= 0x00082210,
+-		.cpu_name		= "750CXe",
++	{	/* 750CXe (82214 & 82314) */
++		.pvr_mask		= 0xfffff0ff,
++		.pvr_value		= 0x00082214,
++		.cpu_name		= "750CXe rev 2.4",
++		.cpu_features		= CPU_FTR_COMMON |
++			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
++			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
++			CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
++		.cpu_user_features	= COMMON_PPC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750cx
++	},
++	{	/* 750CXe (00082311 or 00083311) revision 3.1 / 3.1 pre_GA */
++		.pvr_mask		= 0xffff0fff,
++		.pvr_value		= 0x00080311,
++		.cpu_name		= "750CXe rev 3.1",
+ 		.cpu_features		= CPU_FTR_COMMON |
+ 			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+ 			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
+@@ -243,7 +258,21 @@
+ 	{	/* 750CXe "Gekko" (83214) */
+ 		.pvr_mask		= 0xffffffff,
+ 		.pvr_value		= 0x00083214,
+-		.cpu_name		= "750CXe",
++		.cpu_name		= "750CXe 'Gekko'",
++		.cpu_features		= CPU_FTR_COMMON |
++			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
++			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |
++			CPU_FTR_HPTE_TABLE | CPU_FTR_MAYBE_CAN_NAP,
++		.cpu_user_features	= COMMON_PPC,
++		.icache_bsize		= 32,
++		.dcache_bsize		= 32,
++		.num_pmcs		= 4,
++		.cpu_setup		= __setup_cpu_750cx
++	},
++	{	/* 750CX (82201 and 82202) */
++		.pvr_mask		= 0xfffffff0,
++		.pvr_value		= 0x00082200,
++		.cpu_name		= "750CX",
+ 		.cpu_features		= CPU_FTR_COMMON |
+ 			CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_MAYBE_CAN_DOZE |
+ 			CPU_FTR_USE_TB | CPU_FTR_L2CR | CPU_FTR_TAU |

Added: people/waldi/linux-2.6/debian/patches/powerpc-mkvmlinuz-support.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/powerpc-mkvmlinuz-support.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,60 @@
+# 
+# Mkvmlinuz support patch, called by debian's kernel-package to generate
+# the files needed by mkvmlinuz to generate the bootable images from vmlinux.
+# Author: Sven Luther <luther at debian.org>
+# Based on work from: Jens Schmalzing <jensen at debian.org>
+# Original comment from Jens :
+#   This shell script is intended to be put into the debian subdirectory
+#   of a Linux kernel tree, where make-kpkg will find and execute it
+#   while building a kernel-image package.  The purpose of this script
+#   is to add glue (object code, libraries, utilities and so on) from
+#   the kernel tree to the kernel-image package.  Later, the mkvmlinuz
+#   utility, which is available as a separate Debian package, can use
+#   this glue to create a bootable compressed kernel from the
+#   uncompressed kernel in the kernel-image package and optionally a
+#   ramdisk.  This is especially important on PowerPC subarchitectures
+#   that don't have a boot loader, but also comes handy for rescue
+#   systems and the like.
+# Upstream status: well, this is a debian specific hack, it would be nice
+# if it was going upstream, but probably not in this form.
+#
+--- linux-kernel-2.6.12-2.6.12/arch/ppc/boot/Makefile.orig	2005-07-15 12:46:28.000000000 +0000
++++ linux-kernel-2.6.12-2.6.12/arch/ppc/boot/Makefile	2005-07-15 12:55:56.000000000 +0000
+@@ -32,3 +32,37 @@
+ $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \
+ 		$(addprefix $(obj)/,$(hostprogs-y))
+ 	$(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS)
++
++mkvmlinuz_support_install:
++	# mkvmlinuz support, based on work done originally by Jens Schmalzing <jensen at debian.org>
++	mkdir -p $(INSTALL_MKVMLINUZ)/boot
++	install -m 644 -o root -g root ld.script $(INSTALL_MKVMLINUZ)/boot
++	if [ -e openfirmware/note ]; then \
++		install -m 644 -o root -g root openfirmware/note $(INSTALL_MKVMLINUZ)/boot; \
++	fi
++
++	mkdir -p $(INSTALL_MKVMLINUZ)/lib
++	install -m 644 -o root -g root ../../../lib/lib.a $(INSTALL_MKVMLINUZ)/lib
++	install -m 644 -o root -g root lib/lib.a $(INSTALL_MKVMLINUZ)/lib/ppc.a
++	install -m 644 -o root -g root common/lib.a $(INSTALL_MKVMLINUZ)/lib/common.a
++	if [ -e of1275/lib.a ]; then \
++		install -m 644 -o root -g root of1275/lib.a $(INSTALL_MKVMLINUZ)/lib/of.a; \
++	fi
++
++	if [ -e openfirmware/common.o ]; then \
++		mkdir -p $(INSTALL_MKVMLINUZ)/obj/openfirmware; \
++		install -m 644 -o root -g root openfirmware/*.o $(INSTALL_MKVMLINUZ)/obj/openfirmware; \
++		rm -f $(INSTALL_MKVMLINUZ)/obj/openfirmware/image*; \
++	fi
++
++	mkdir -p $(INSTALL_MKVMLINUZ)/obj/simple
++	install -m 644 -o root -g root simple/*.o $(INSTALL_MKVMLINUZ)/obj/simple
++	rm -f $(INSTALL_MKVMLINUZ)/obj/simple/image*.o
++
++	mkdir -p $(INSTALL_MKVMLINUZ)/utils
++	install -m 755 -o root -g root utils/addnote $(INSTALL_MKVMLINUZ)/utils
++	install -m 755 -o root -g root utils/hack-coff $(INSTALL_MKVMLINUZ)/utils
++	install -m 755 -o root -g root utils/mkbugboot $(INSTALL_MKVMLINUZ)/utils
++	install -m 755 -o root -g root utils/mknote $(INSTALL_MKVMLINUZ)/utils
++	install -m 755 -o root -g root utils/mkprep $(INSTALL_MKVMLINUZ)/utils
++	install -m 755 -o root -g root utils/mktree $(INSTALL_MKVMLINUZ)/utils

Added: people/waldi/linux-2.6/debian/patches/powerpc-mv643xx-hotplug-support.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/powerpc-mv643xx-hotplug-support.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,35 @@
+# 
+# Hotplug support patch for mv643xx_eth driver used on pegasos machines.
+# Author: Nicolas Det <nicolas.det at bplan-gmbh.de>
+# Upstream status: In the process of being submitted, may need a bit of
+# cleanup in order to not break embedded arches using this controller, but
+# should not be a worry for debian.
+#
+--- linux/drivers/net/mv643xx_eth.c.orig	2006-01-01 17:22:07.000000000 +0000
++++ linux/drivers/net/mv643xx_eth.c	2006-01-01 17:23:56.000000000 +0000
+@@ -41,6 +41,8 @@
+ #include <linux/ethtool.h>
+ #include <linux/platform_device.h>
+ 
++#include <linux/pci.h>
++
+ #include <asm/io.h>
+ #include <asm/types.h>
+ #include <asm/pgtable.h>
+@@ -1635,6 +1637,15 @@
+ 		" and Dale Farnsworth");
+ MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX");
+ 
++static struct pci_device_id pci_marvell_mv64360[] = {
++	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64360) },
++	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_MV64460) },
++	{ }
++};
++
++MODULE_DEVICE_TABLE(pci, pci_marvell_mv64360);
++
++
+ /*
+  * The second part is the low level driver of the gigE ethernet ports.
+  */
+

Added: people/waldi/linux-2.6/debian/patches/powerpc-mv643xx-spinlock-fix-support.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/powerpc-mv643xx-spinlock-fix-support.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,66 @@
+Date: Wed, 28 Dec 2005 15:40:01 -0700
+To: netdev at vger.kernel.org
+Subject: [PATCH 4/4] mv643xx: Don't call request_irq with a held lock
+Message-ID: <20051228224001.GD5742 at xyzzy.farnsworth.org>
+References: <20051228223449.GA5742 at xyzzy.farnsworth.org>
+
+From: Dale Farnsworth <dale at farnsworth.org>
+
+We can't call request_irq() while holding a spin lock.
+
+Signed-off-by: Dale Farnsworth <dale at farnsworth.org>
+
+Index: linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
+===================================================================
+--- linux-2.6-mv643xx_enet.orig/drivers/net/mv643xx_eth.c
++++ linux-2.6-mv643xx_enet/drivers/net/mv643xx_eth.c
+@@ -655,34 +655,24 @@ static int mv643xx_eth_open(struct net_d
+ 	unsigned int port_num = mp->port_num;
+ 	int err;
+ 
+-	spin_lock_irq(&mp->lock);
+-
+ 	err = request_irq(dev->irq, mv643xx_eth_int_handler,
+ 			SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev);
+-
+ 	if (err) {
+ 		printk(KERN_ERR "Can not assign IRQ number to MV643XX_eth%d\n",
+ 								port_num);
+-		err = -EAGAIN;
+-		goto out;
++		return -EAGAIN;
+ 	}
+ 
++	spin_lock_irq(&mp->lock);
++
+ 	if (mv643xx_eth_real_open(dev)) {
+ 		printk("%s: Error opening interface\n", dev->name);
++		free_irq(dev->irq, dev);
+ 		err = -EBUSY;
+-		goto out_free;
+ 	}
+ 
+ 	spin_unlock_irq(&mp->lock);
+ 
+-	return 0;
+-
+-out_free:
+-	free_irq(dev->irq, dev);
+-
+-out:
+-	spin_unlock_irq(&mp->lock);
+-
+ 	return err;
+ }
+ 
+
+_______________________________________________
+Linuxppc-dev mailing list
+Linuxppc-dev at ozlabs.org
+https://ozlabs.org/mailman/listinfo/linuxppc-dev
+---------------------------------------------------------------------------------------
+Wanadoo vous informe que cet  e-mail a ete controle par l'anti-virus mail. 
+Aucun virus connu a ce jour par nos services n'a ete detecte.
+
+
+

Added: people/waldi/linux-2.6/debian/patches/powerpc-prep-utah-ide-interrupt.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/powerpc-prep-utah-ide-interrupt.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,16 @@
+# 
+# Description: Reenables IDE interrupt on Motorola Powerstack II (Utah)
+# Patch author: Sven Luther <luther at debian.org>
+# Closes: #345424: linux-source-2.6.14: Missing IDE IRQ for PReP Utah (PowerstackII Pro4000)
+#
+--- linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/platforms/prep_pci.c.orig	2005-12-31 14:51:16.000000000 +0000
++++ linux-2.6-2.6.14+2.6.15-rc7/arch/ppc/platforms/prep_pci.c	2005-12-31 14:58:23.000000000 +0000
+@@ -46,7 +46,7 @@
+ static char Utah_pci_IRQ_map[23] =
+ {
+         0,   /* Slot 0  - unused */
+-        0,   /* Slot 1  - unused */
++        4,   /* Slot 1  - IDE - SL82C105 */
+         5,   /* Slot 2  - SCSI - NCR825A  */
+         0,   /* Slot 3  - unused */
+         3,   /* Slot 4  - Ethernet - DEC2114x */

Added: people/waldi/linux-2.6/debian/patches/powerpc-serial.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/powerpc-serial.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,48 @@
+#! /bin/sh -e 
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Description: Disables legacy serial driver on powermacs.
+## DP: Patch author: Sven Luther <luther at debian.org> 
+## DP: Patch author: adapted from the SuSE kernel tree.
+## DP: Upstream status: workaround hack waiting for a clean legacy device solution.
+
+diff -aurN a/drivers/serial/8250.c b/drivers/serial/8250.c
+--- a/drivers/serial/8250.c	2005-06-17 15:48:29.000000000 -0400
++++ b/drivers/serial/8250.c	2005-06-18 12:05:39.000000000 -0400
+@@ -46,6 +46,10 @@
+ 
+ #include "8250.h"
+ 
++#ifdef CONFIG_PPC_MULTIPLATFORM
++#include <asm/processor.h>
++#endif
++
+ /*
+  * Configuration:
+  *   share_irqs - whether we pass SA_SHIRQ to request_irq().  This option
+@@ -2188,6 +2192,12 @@
+ 
+ static int __init serial8250_console_init(void)
+ {
++#ifdef CONFIG_PPC_MULTIPLATFORM
++	if(_machine == _MACH_Pmac) {
++		printk("%s: nothing to do on PowerMac\n",__FUNCTION__);
++		return -ENODEV;
++	}
++#endif
+ 	serial8250_isa_init_ports();
+ 	register_console(&serial8250_console);
+ 	return 0;
+@@ -2491,6 +2501,12 @@
+ {
+ 	int ret, i;
+ 
++#ifdef CONFIG_PPC_MULTIPLATFORM
++	if(_machine == _MACH_Pmac) {
++		printk("%s: nothing to do on PowerMac\n",__FUNCTION__);
++		return -ENODEV;
++	}
++#endif
+ 	printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ "
+ 		"%d ports, IRQ sharing %sabled\n", (int) UART_NR,
+ 		share_irqs ? "en" : "dis");

Added: people/waldi/linux-2.6/debian/patches/remove-references-to-removed-drivers.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/remove-references-to-removed-drivers.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,342 @@
+diff -aurN a/arch/alpha/defconfig b/arch/alpha/defconfig
+--- a/arch/alpha/defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/alpha/defconfig	2005-06-18 16:11:08.000000000 -0400
+@@ -512,7 +512,6 @@
+ # CONFIG_B44 is not set
+ # CONFIG_FORCEDETH is not set
+ # CONFIG_CS89x0 is not set
+-# CONFIG_DGRS is not set
+ # CONFIG_EEPRO100 is not set
+ # CONFIG_E100 is not set
+ # CONFIG_LNE390 is not set
+@@ -533,7 +532,6 @@
+ #
+ # Ethernet (1000 Mbit)
+ #
+-# CONFIG_ACENIC is not set
+ # CONFIG_DL2K is not set
+ # CONFIG_E1000 is not set
+ # CONFIG_NS83820 is not set
+diff -aurN a/arch/arm/configs/lpd7a404_defconfig b/arch/arm/configs/lpd7a404_defconfig
+--- a/arch/arm/configs/lpd7a404_defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/arm/configs/lpd7a404_defconfig	2005-06-18 16:30:01.000000000 -0400
+@@ -676,8 +676,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+diff -aurN a/arch/i386/defconfig b/arch/i386/defconfig
+--- a/arch/i386/defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/i386/defconfig	2005-06-18 16:22:33.000000000 -0400
+@@ -624,7 +624,6 @@
+ # CONFIG_B44 is not set
+ # CONFIG_FORCEDETH is not set
+ # CONFIG_CS89x0 is not set
+-# CONFIG_DGRS is not set
+ # CONFIG_EEPRO100 is not set
+ # CONFIG_E100 is not set
+ # CONFIG_FEALNX is not set
+@@ -646,7 +645,6 @@
+ #
+ # Ethernet (1000 Mbit)
+ #
+-# CONFIG_ACENIC is not set
+ # CONFIG_DL2K is not set
+ # CONFIG_E1000 is not set
+ # CONFIG_NS83820 is not set
+@@ -1026,7 +1024,6 @@
+ #
+ # USB Multimedia devices
+ #
+-# CONFIG_USB_DABUSB is not set
+ 
+ #
+ # Video4Linux support is needed for USB Multimedia device support
+@@ -1054,8 +1051,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_TIGL is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+diff -aurN a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
+--- a/arch/ia64/configs/zx1_defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/ia64/configs/zx1_defconfig	2005-06-18 16:27:49.000000000 -0400
+@@ -1014,8 +1014,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+diff -aurN a/arch/ia64/defconfig b/arch/ia64/defconfig
+--- a/arch/ia64/defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/ia64/defconfig	2005-06-18 16:28:03.000000000 -0400
+@@ -482,7 +482,6 @@
+ # CONFIG_ADAPTEC_STARFIRE is not set
+ # CONFIG_B44 is not set
+ # CONFIG_FORCEDETH is not set
+-# CONFIG_DGRS is not set
+ CONFIG_EEPRO100=m
+ CONFIG_E100=m
+ # CONFIG_FEALNX is not set
+@@ -500,7 +499,6 @@
+ #
+ # Ethernet (1000 Mbit)
+ #
+-# CONFIG_ACENIC is not set
+ # CONFIG_DL2K is not set
+ CONFIG_E1000=y
+ # CONFIG_E1000_NAPI is not set
+@@ -879,7 +877,6 @@
+ #
+ # USB Multimedia devices
+ #
+-# CONFIG_USB_DABUSB is not set
+ 
+ #
+ # Video4Linux support is needed for USB Multimedia device support
+@@ -906,8 +903,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+diff -aurN a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
+--- a/arch/mips/configs/rm200_defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/mips/configs/rm200_defconfig	2005-06-18 16:27:28.000000000 -0400
+@@ -1098,8 +1098,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ CONFIG_USB_AUERSWALD=m
+ CONFIG_USB_RIO500=m
+ CONFIG_USB_LEGOTOWER=m
+diff -aurN a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig
+--- a/arch/ppc/configs/common_defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/ppc/configs/common_defconfig	2005-06-18 16:24:38.000000000 -0400
+@@ -1213,8 +1213,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+diff -aurN a/arch/ppc/configs/lopec_defconfig b/arch/ppc/configs/lopec_defconfig
+--- a/arch/ppc/configs/lopec_defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/ppc/configs/lopec_defconfig	2005-06-18 16:25:01.000000000 -0400
+@@ -681,8 +681,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_TIGL is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+diff -aurN a/arch/ppc/configs/pmac_defconfig b/arch/ppc/configs/pmac_defconfig
+--- a/arch/ppc/configs/pmac_defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/ppc/configs/pmac_defconfig	2005-06-18 16:25:19.000000000 -0400
+@@ -1278,8 +1278,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+diff -aurN a/arch/ppc/configs/sandpoint_defconfig b/arch/ppc/configs/sandpoint_defconfig
+--- a/arch/ppc/configs/sandpoint_defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/ppc/configs/sandpoint_defconfig	2005-06-18 16:24:50.000000000 -0400
+@@ -600,8 +600,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_TIGL is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+diff -aurN a/arch/ppc64/configs/g5_defconfig b/arch/ppc64/configs/g5_defconfig
+--- a/arch/ppc64/configs/g5_defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/ppc64/configs/g5_defconfig	2005-06-18 16:28:43.000000000 -0400
+@@ -1059,8 +1059,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+diff -aurN a/arch/ppc64/configs/pSeries_defconfig b/arch/ppc64/configs/pSeries_defconfig
+--- a/arch/ppc64/configs/pSeries_defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/ppc64/configs/pSeries_defconfig	2005-06-18 16:29:21.000000000 -0400
+@@ -1014,8 +1014,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+diff -aurN a/arch/ppc64/defconfig b/arch/ppc64/defconfig
+--- a/arch/ppc64/defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/ppc64/defconfig	2005-06-18 16:29:36.000000000 -0400
+@@ -591,7 +591,6 @@
+ # CONFIG_ADAPTEC_STARFIRE is not set
+ # CONFIG_B44 is not set
+ # CONFIG_FORCEDETH is not set
+-# CONFIG_DGRS is not set
+ # CONFIG_EEPRO100 is not set
+ CONFIG_E100=y
+ # CONFIG_FEALNX is not set
+@@ -607,8 +606,6 @@
+ #
+ # Ethernet (1000 Mbit)
+ #
+-CONFIG_ACENIC=y
+-CONFIG_ACENIC_OMIT_TIGON_I=y
+ # CONFIG_DL2K is not set
+ CONFIG_E1000=y
+ # CONFIG_E1000_NAPI is not set
+@@ -1040,7 +1037,6 @@
+ #
+ # USB Multimedia devices
+ #
+-# CONFIG_USB_DABUSB is not set
+ 
+ #
+ # Video4Linux support is needed for USB Multimedia device support
+@@ -1069,8 +1065,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+diff -aurN a/arch/sparc64/defconfig b/arch/sparc64/defconfig
+--- a/arch/sparc64/defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/sparc64/defconfig	2005-06-18 16:23:32.000000000 -0400
+@@ -904,7 +904,6 @@
+ CONFIG_ADAPTEC_STARFIRE_NAPI=y
+ CONFIG_B44=m
+ CONFIG_FORCEDETH=m
+-CONFIG_DGRS=m
+ CONFIG_EEPRO100=m
+ CONFIG_E100=m
+ CONFIG_FEALNX=m
+@@ -926,8 +925,6 @@
+ #
+ # Ethernet (1000 Mbit)
+ #
+-CONFIG_ACENIC=m
+-# CONFIG_ACENIC_OMIT_TIGON_I is not set
+ CONFIG_DL2K=m
+ CONFIG_E1000=m
+ CONFIG_E1000_NAPI=y
+@@ -1723,7 +1720,6 @@
+ #
+ # USB Multimedia devices
+ #
+-# CONFIG_USB_DABUSB is not set
+ # CONFIG_USB_VICAM is not set
+ # CONFIG_USB_DSBR is not set
+ # CONFIG_USB_IBMCAM is not set
+@@ -1817,8 +1813,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-CONFIG_USB_EMI62=m
+-CONFIG_USB_EMI26=m
+ CONFIG_USB_AUERSWALD=m
+ CONFIG_USB_RIO500=m
+ CONFIG_USB_LEGOTOWER=m
+diff -aurN a/arch/x86_64/defconfig b/arch/x86_64/defconfig
+--- a/arch/x86_64/defconfig	2005-06-17 15:48:29.000000000 -0400
++++ b/arch/x86_64/defconfig	2005-06-18 16:31:01.000000000 -0400
+@@ -530,7 +530,6 @@
+ # CONFIG_ADAPTEC_STARFIRE is not set
+ # CONFIG_B44 is not set
+ CONFIG_FORCEDETH=y
+-# CONFIG_DGRS is not set
+ # CONFIG_EEPRO100 is not set
+ CONFIG_E100=y
+ # CONFIG_FEALNX is not set
+@@ -550,7 +549,6 @@
+ #
+ # Ethernet (1000 Mbit)
+ #
+-# CONFIG_ACENIC is not set
+ # CONFIG_DL2K is not set
+ CONFIG_E1000=y
+ # CONFIG_E1000_NAPI is not set
+@@ -862,7 +860,6 @@
+ #
+ # USB Multimedia devices
+ #
+-# CONFIG_USB_DABUSB is not set
+ 
+ #
+ # Video4Linux support is needed for USB Multimedia device support
+@@ -890,8 +887,6 @@
+ #
+ # USB Miscellaneous drivers
+ #
+-# CONFIG_USB_EMI62 is not set
+-# CONFIG_USB_EMI26 is not set
+ # CONFIG_USB_AUERSWALD is not set
+ # CONFIG_USB_RIO500 is not set
+ # CONFIG_USB_LEGOTOWER is not set
+diff -aurN a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
+--- a/drivers/usb/misc/Kconfig	2005-06-18 11:23:01.000000000 -0400
++++ b/drivers/usb/misc/Kconfig	2005-06-18 16:31:32.000000000 -0400
+@@ -4,19 +4,6 @@
+ comment "USB Miscellaneous drivers"
+ 	depends on USB
+ 
+-config USB_EMI26
+-	tristate "EMI 2|6 USB Audio interface support"
+-	depends on USB
+-	---help---
+-	  This driver loads firmware to Emagic EMI 2|6 low latency USB
+-	  Audio interface.
+-
+-	  After firmware load the device is handled with standard linux
+-	  USB Audio driver.
+-
+-	  To compile this driver as a module, choose M here: the
+-	  module will be called emi26.
+-
+ config USB_AUERSWALD
+ 	tristate "USB Auerswald ISDN support (EXPERIMENTAL)"
+ 	depends on USB && EXPERIMENTAL
+--- linux-2.6.13/drivers/usb/misc/Makefile.orig	2005-08-06 11:56:51.000000000 +0200
++++ linux-2.6.13/drivers/usb/misc/Makefile	2005-08-06 11:58:37.000000000 +0200
+@@ -5,7 +5,6 @@
+ 
+ obj-$(CONFIG_USB_AUERSWALD)	+= auerswald.o
+ obj-$(CONFIG_USB_CYTHERM)	+= cytherm.o
+-obj-$(CONFIG_USB_EMI26)		+= emi26.o
+ obj-$(CONFIG_USB_IDMOUSE)	+= idmouse.o
+ obj-$(CONFIG_USB_LCD)		+= usblcd.o
+ obj-$(CONFIG_USB_LD)		+= ldusb.o

Added: people/waldi/linux-2.6/debian/patches/s390-uaccess-const.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/s390-uaccess-const.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,63 @@
+[patch] s390: const pointer uaccess.
+
+From: Martin Schwidefsky <schwidefsky at de.ibm.com>
+
+Using __typeof__(*ptr) on a pointer to const makes the __x
+variable in __get_user const as well. The latest gcc will
+refuse to write to it.
+
+Signed-off-by: Martin Schwidefsky <schwidefsky at de.ibm.com>
+
+diffstat:
+ include/asm-s390/uaccess.h |   28 ++++++++++++++++++++++------
+ 1 files changed, 22 insertions(+), 6 deletions(-)
+
+diff -urpN linux-2.6/include/asm-s390/uaccess.h linux-2.6-patched/include/asm-s390/uaccess.h
+--- linux-2.6/include/asm-s390/uaccess.h	2005-10-19 15:54:19.000000000 +0200
++++ linux-2.6-patched/include/asm-s390/uaccess.h	2005-10-19 15:54:44.000000000 +0200
+@@ -200,21 +200,37 @@ extern int __put_user_bad(void) __attrib
+ 
+ #define __get_user(x, ptr)					\
+ ({								\
+-	__typeof__(*(ptr)) __x;					\
+ 	int __gu_err;						\
+         __chk_user_ptr(ptr);                                    \
+ 	switch (sizeof(*(ptr))) {				\
+-	case 1:							\
+-	case 2:							\
+-	case 4:							\
+-	case 8:							\
++	case 1: {						\
++		unsigned char __x;				\
+ 		__get_user_asm(__x, ptr, __gu_err);		\
++		(x) = (__typeof__(*(ptr))) __x;			\
+ 		break;						\
++	};							\
++	case 2: {						\
++		unsigned short __x;				\
++		__get_user_asm(__x, ptr, __gu_err);		\
++		(x) = (__typeof__(*(ptr))) __x;			\
++		break;						\
++	};							\
++	case 4: {						\
++		unsigned int __x;				\
++		__get_user_asm(__x, ptr, __gu_err);		\
++		(x) = (__typeof__(*(ptr))) __x;			\
++		break;						\
++	};							\
++	case 8: {						\
++		unsigned long long __x;				\
++		__get_user_asm(__x, ptr, __gu_err);		\
++		(x) = (__typeof__(*(ptr))) __x;			\
++		break;						\
++	};							\
+ 	default:						\
+ 		__get_user_bad();				\
+ 		break;						\
+ 	}							\
+-	(x) = __x;						\
+ 	__gu_err;						\
+ })
+ 
+
+

Added: people/waldi/linux-2.6/debian/patches/series/1
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/series/1	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,24 @@
++ fbdev-radeon-noaccel.patch
++ fs-asfs-2.patch
++ ia64-irq-affinity-upfix.patch
++ modular-ide-pnp.patch
++ powerpc-mkvmlinuz-support.patch
++ powerpc-serial.patch
+#+ remove-references-to-removed-drivers.patch
++ sparc64-hme-lockup.patch
+#+ tty-locking-fixes9.patch
++ version.patch
++ powerpc-apus.patch
+#+ s390-uaccess-const.patch
++ powerpc-build-links.patch
++ m68k-bvme.patch
++ m68k-mvme147.patch
++ m68k-mvme16x.patch
++ m68k-spinlock.patch
++ sparc64-atyfb-xl-gr-final.patch
++ powerpc-arch-default-powerpc.patch
++ drivers-scsi-megaraid_splitup.patch
++ powerpc-mv643xx-spinlock-fix-support.patch
++ powerpc-prep-utah-ide-interrupt.patch
++ powerpc-mv643xx-hotplug-support.patch
+

Added: people/waldi/linux-2.6/debian/patches/series/2-extra
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/series/2-extra	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,2 @@
++ hppa-incompatible.patch hppa
++ m68k-incompatible.patch m68k

Added: people/waldi/linux-2.6/debian/patches/sparc64-atyfb-xl-gr-final.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/sparc64-atyfb-xl-gr-final.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,12 @@
+diff -aur a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
+--- a/drivers/video/aty/atyfb_base.c	2005-10-27 17:02:08.000000000 -0700
++++ b/drivers/video/aty/atyfb_base.c	2005-11-09 19:56:18.000000000 -0800
+@@ -404,7 +404,7 @@
+ 	{ PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP)", 230, 83, 63, ATI_CHIP_264XL },
+ 	{ PCI_CHIP_MACH64GN, "3D RAGE XL (Mach64 GN, AGP)", 230, 83, 63, ATI_CHIP_264XL },
+ 	{ PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66/BGA)", 230, 83, 63, ATI_CHIP_264XL },
+-	{ PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 230, 83, 63, ATI_CHIP_264XL },
++	{ PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 235, 83, 63, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },
+ 	{ PCI_CHIP_MACH64GL, "3D RAGE XL (Mach64 GL, PCI)", 230, 83, 63, ATI_CHIP_264XL },
+ 	{ PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL },
+ 

Added: people/waldi/linux-2.6/debian/patches/sparc64-hme-lockup.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/sparc64-hme-lockup.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,16 @@
+# origin: Debian (bcollins)
+# cset: n/a
+# inclusion: not suitable for upstream
+# revision date: 2004-10-08
+
+diff -aurN a/drivers/net/sunhme.c b/drivers/net/sunhme.c
+--- a/drivers/net/sunhme.c	2005-06-17 15:48:29.000000000 -0400
++++ b/drivers/net/sunhme.c	2005-06-18 12:12:18.000000000 -0400
+@@ -1996,6 +1996,7 @@
+ 	}
+ 	hp->tx_old = elem;
+ 	TXD((">"));
++	udelay(1);
+ 
+ 	if (netif_queue_stopped(dev) &&
+ 	    TX_BUFFS_AVAIL(hp) > (MAX_SKB_FRAGS + 1))

Added: people/waldi/linux-2.6/debian/patches/tty-locking-fixes9.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/tty-locking-fixes9.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,12 @@
+--- kernel-source-2.6.11-2.6.11-orig/drivers/serial/serial_core.c	2005-03-02 08:37:50.000000000 +0100
++++ kernel-source-2.6.11-2.6.11/drivers/serial/serial_core.c	2005-03-05 10:46:43.417109240 +0100
+@@ -108,7 +108,8 @@
+ static void uart_tasklet_action(unsigned long data)
+ {
+ 	struct uart_state *state = (struct uart_state *)data;
+-	tty_wakeup(state->info->tty);
++	if (state->info->tty)
++		tty_wakeup(state->info->tty);
+ }
+ 
+ static inline void

Added: people/waldi/linux-2.6/debian/patches/version.patch
==============================================================================
--- (empty file)
+++ people/waldi/linux-2.6/debian/patches/version.patch	Fri Jan  6 14:05:03 2006
@@ -0,0 +1,80 @@
+Attach informations from debian/changelog to compile.h.
+
+---
+commit 932fa20ce2db25e496f6aedf6f624e939f3dafa8
+tree 87ebceaf3f1a47f9fafef53ad36510fab9cf3d5f
+parent 05dbb1e557b392c8cef3675b4ba6497794ad4124
+author Bastian Blank <waldi at debian.org> Tue, 13 Sep 2005 22:03:33 +0000
+committer Bastian Blank <waldi at debian.org> Tue, 13 Sep 2005 22:03:33 +0000
+
+ scripts/mkcompile_h |   13 +++++++++++++
+ 1 files changed, 13 insertions(+), 0 deletions(-)
+
+diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h
+--- a/scripts/mkcompile_h
++++ b/scripts/mkcompile_h
+@@ -55,6 +55,19 @@ UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}
+   fi
+ 
+   echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -n 1`\"
++
++  if [ -e debian/changelog ]; then
++    DISTRIBUTION=$(lsb_release -is 2>/dev/null)
++    [ "$DISTRIBUTION" ] || DISTRIBUTION=Debian
++    MAINTAINER=$(dpkg-parsechangelog | sed -ne 's,^Maintainer: .[^<]*<\([^>]*\)>,\1,p')
++    VERSION=$(dpkg-parsechangelog | awk '/^Version:/ {print $$2}')
++    echo \#define LINUX_COMPILE_SYSTEM_DISTRIBUTION \"$DISTRIBUTION\"
++    echo \#define LINUX_COMPILE_SYSTEM_MAINTAINER \"$MAINTAINER\"
++    echo \#define LINUX_COMPILE_SYSTEM_VERSION \"$VERSION\"
++    if [ -e debian/official ]; then
++      echo \#define LINUX_COMPILE_SYSTEM_OFFICIAL
++    fi
++  fi
+ ) > .tmpcompile
+ 
+ # Only replace the real compile.h if the new one is different,
+
+
+
+!-------------------------------------------------------------flip-
+
+
+Use debian packaging informations in version string.
+
+---
+commit f9117a71c91d355243befb1a24bc557ea5d98e5b
+tree 30e508720f0783c2a93b9103edd5e710f81f7f34
+parent 932fa20ce2db25e496f6aedf6f624e939f3dafa8
+author Bastian Blank <waldi at debian.org> Tue, 13 Sep 2005 22:04:14 +0000
+committer Bastian Blank <waldi at debian.org> Tue, 13 Sep 2005 22:04:14 +0000
+
+ init/version.c |   14 ++++++++++++--
+ 1 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/init/version.c b/init/version.c
+--- a/init/version.c
++++ b/init/version.c
+@@ -29,5 +29,15 @@ struct new_utsname system_utsname = {
+ EXPORT_SYMBOL(system_utsname);
+ 
+ const char linux_banner[] =
+-	"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
+-	LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
++	"Linux version " UTS_RELEASE " "
++#ifdef LINUX_COMPILE_SYSTEM_OFFICIAL
++	"(" LINUX_COMPILE_SYSTEM_DISTRIBUTION " "
++	    LINUX_COMPILE_SYSTEM_VERSION ") "
++	"(" LINUX_COMPILE_SYSTEM_MAINTAINER ") "
++#else
++# ifdef LINUX_COMPILE_SYSTEM_VERSION
++	"(" LINUX_COMPILE_SYSTEM_VERSION ") "
++# endif
++	"(" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ") "
++#endif
++	"(" LINUX_COMPILER ") " UTS_VERSION "\n";
+
+
+
+!-------------------------------------------------------------flip-
+
+

Modified: people/waldi/linux-2.6/debian/rules.real
==============================================================================
--- people/waldi/linux-2.6/debian/rules.real	(original)
+++ people/waldi/linux-2.6/debian/rules.real	Fri Jan  6 14:05:03 2006
@@ -100,7 +100,7 @@
 	rm -rf '$(DIR)'
 
 define patch_cmd
-cd '$(DIR)'; python2.4 '$(CURDIR)/debian/bin/apply.py' --overwrite-home='$(CURDIR)/debian/patches-debian' --overwrite-source='$(SOURCE_VERSION)' --overwrite-revisions='$(REVISIONS)'
+cd '$(DIR)'; python2.4 '$(CURDIR)/debian/bin/apply.py' --overwrite-home='$(CURDIR)/debian/patches' --overwrite-source='$(SOURCE_VERSION)' --overwrite-revisions='$(REVISIONS)'
 endef
 
 srcfiles := $(filter-out debian, $(wildcard *))
@@ -246,7 +246,7 @@
 	dh_testroot
 	dh_clean -d -k $(DH_OPTIONS)
 	dh_installdirs $(DH_OPTIONS) '$(pbase)/apply' '$(pbase)/debian' '$(pbase)/unpatch'
-	dh_install $(DH_OPTIONS) debian/patches-debian/* '$(pbase)/debian'
+	dh_install $(DH_OPTIONS) debian/patches/* '$(pbase)/debian'
 #	Install the debian patches
 	sed \
 	  -e 's, at home@,$(pbase)/debian,' \



More information about the Kernel-svn-changes mailing list