[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,¤t_thread_info()->flags);
+-}
+-
+-static inline void clear_thread_flag(int flag)
+-{
+- clear_bit(flag,¤t_thread_info()->flags);
+-}
+-
+-static inline int test_and_set_thread_flag(int flag)
+-{
+- return test_and_set_bit(flag,¤t_thread_info()->flags);
+-}
+-
+-static inline int test_and_clear_thread_flag(int flag)
+-{
+- return test_and_clear_bit(flag,¤t_thread_info()->flags);
+-}
+-
+-static inline int test_thread_flag(int flag)
+-{
+- return test_bit(flag,¤t_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