r3278 - in branches/kernel-image-2.6.11/debian: . bin patches-arch templates
Jurij Smakov
jurij-guest at costa.debian.org
Fri Oct 19 10:58:27 UTC 2007
Author: jurij-guest
Date: 2005-05-31 00:52:12 +0000 (Tue, 31 May 2005)
New Revision: 3278
Added:
branches/kernel-image-2.6.11/debian/bin/unpatch
branches/kernel-image-2.6.11/debian/control
branches/kernel-image-2.6.11/debian/patches-arch/
branches/kernel-image-2.6.11/debian/patches-arch/apus.diff
branches/kernel-image-2.6.11/debian/patches-arch/hppa.diff
Modified:
branches/kernel-image-2.6.11/debian/Makefile
branches/kernel-image-2.6.11/debian/rules
branches/kernel-image-2.6.11/debian/templates/control.main.in
Log:
Added preliminary support for arch-specific
patches.
Modified: branches/kernel-image-2.6.11/debian/Makefile
===================================================================
--- branches/kernel-image-2.6.11/debian/Makefile 2005-05-30 21:02:58 UTC (rev 3277)
+++ branches/kernel-image-2.6.11/debian/Makefile 2005-05-31 00:52:12 UTC (rev 3278)
@@ -11,7 +11,6 @@
#
SHELL := sh -e
debver := $(version)-$(abiname)
-uver := $(subst .,_,$(version))
debnum := -$(abiname)
#
# These variables control the behaviour of make-kpkg
Added: branches/kernel-image-2.6.11/debian/bin/unpatch
===================================================================
--- branches/kernel-image-2.6.11/debian/bin/unpatch 2005-05-30 21:02:58 UTC (rev 3277)
+++ branches/kernel-image-2.6.11/debian/bin/unpatch 2005-05-31 00:52:12 UTC (rev 3278)
@@ -0,0 +1,8 @@
+#!/bin/sh
+# $Id: unpatch,v 1.3 2003/06/30 12:49:09 herbert Exp $
+
+set -e
+
+upstream=${override_upstream:- at upstream@}
+
+/usr/src/kernel-patches/all/$upstream/apply/debian $upstream
Property changes on: branches/kernel-image-2.6.11/debian/bin/unpatch
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/kernel-image-2.6.11/debian/control
===================================================================
--- branches/kernel-image-2.6.11/debian/control 2005-05-30 21:02:58 UTC (rev 3277)
+++ branches/kernel-image-2.6.11/debian/control 2005-05-31 00:52:12 UTC (rev 3278)
@@ -0,0 +1,86 @@
+Source: linux-source-2.6.11
+Section: devel
+Priority: optional
+Maintainer: Debian Kernel Team <debian-kernel at lists.debian.org>
+Standards-Version: 3.6.1.0
+Build-Depends: Build-Depends: gcc (>= 4:3.3), debhelper (>= 4), kernel-package, module-init-tools, sparc-utils [sparc]
+
+Package: linux-source-2.6.11
+Architecture: all
+Section: devel
+Priority: optional
+Provides: linux-source, linux-source-2.6
+Depends: binutils, bzip2, coreutils | fileutils (>= 4.0)
+Recommends: libc6-dev | libc-dev, gcc, make
+Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-mt-dev
+Description: Linux kernel source for version 2.6.11 with Debian patches
+ This package provides the source code for the Linux kernel version 2.6.11.
+ .
+ If you wish to use this package to create a custom Linux kernel, then
+ it is suggested that you investigate the package kernel-package,
+ which has been designed to ease the task of creating kernel image
+ packages.
+
+Package: linux-doc-2.6.11
+Architecture: all
+Section: doc
+Priority: optional
+Provides: linux-doc-2.6
+Depends: coreutils | fileutils (>= 4.0)
+Description: Linux kernel specific documentation for version 2.6.11
+ This package provides the various README files in the 2.6.11 kernel
+ Documentation/ subdirectory: these typically contain kernel-specific
+ installation notes for some drivers for example. See
+ /usr/share/doc/linux-doc-2.6.11/Documentation/00-INDEX for a list of what
+ is contained in each file.
+
+Package: linux-patch-debian-2.6.11
+Architecture: all
+Section: devel
+Priority: optional
+Depends: bzip2, ${kpatch:Depends}
+Suggests: linux-source-2.6.11
+Description: Debian patches to version 2.6.11 of the Linux kernel
+ This package includes the patches used to produce the prepackaged
+ linux-source-2.6.11 package. Note that these patches do NOT apply
+ against a pristine Linux 2.6.11 kernel but only against
+ linux-source-2.6.11_2.6.11.orig.tar.gz from the Debian archive.
+
+Package: linux-tree-2.6.11
+Architecture: all
+Section: devel
+Priority: optional
+Depends: linux-patch-debian-2.6.11 (= 2.6.11-5), linux-source-2.6.11 (= 2.6.11-1) | linux-source-2.6.11 (= 2.6.11-2) | linux-source-2.6.11 (= 2.6.11-3) | linux-source-2.6.11 (= 2.6.11-4) | linux-source-2.6.11 (= 2.6.11-5)
+Provides: linux-tree-2.6.11-1, linux-tree-2.6.11-2, linux-tree-2.6.11-3, linux-tree-2.6.11-4, linux-tree-2.6.11-5
+Description: Linux kernel source tree for building Debian kernel images
+ This meta package is used as a build dependency of Debian
+ linux-image packages to prevent a version discrepancy between
+ the linux-image and corresponding linux-sources packages in the
+ fast-moving unstable archive. The package's dependency relations
+ are structured so that a linux-image package's build
+ dependencies can always be satisfied, even if the linux-source
+ package that had been used to compile the image has been
+ superseeded by a newer Debian revision since the last build.
+ .
+ The package provides a list of virtual packages, corresponding to
+ Debian revisions of a linux-source package. The Debian
+ linux-patch contains the information needed to roll back the
+ current linux-source to any of the revisions identified by the
+ provided virtual packages. Therefore, the linux-tree package
+ ensures the availability of the Linux kernel source tree corresponding
+ to each of the virtual packages listed.
+ .
+ The package serves no purpose outside of the Debian build and
+ archive infrastructure.
+
+Package: linux-scripts-2.6.11-1
+Architecture: any
+Section: devel
+Priority: optional
+Depends: coreutils | fileutils (>= 4.0)
+Description: Architecture-specific header files for Linux kernel 2.6.11
+ This package provides the architecture-specific support files for Linux
+ kernel version 2.6.11, generally used for building out-of-tree
+ kernel modules. It mainly contains the binaries from the script/ kernel
+ directory, as well as other architecture-dependent files such as
+ asm-offsets.s.
Added: branches/kernel-image-2.6.11/debian/patches-arch/apus.diff
===================================================================
Added: branches/kernel-image-2.6.11/debian/patches-arch/hppa.diff
===================================================================
--- branches/kernel-image-2.6.11/debian/patches-arch/hppa.diff 2005-05-30 21:02:58 UTC (rev 3277)
+++ branches/kernel-image-2.6.11/debian/patches-arch/hppa.diff 2005-05-31 00:52:12 UTC (rev 3278)
@@ -0,0 +1,28834 @@
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/Documentation/kernel-parameters.txt CVS2_6_11_PA2/Documentation/kernel-parameters.txt
+--- LINUS_2_6_11/Documentation/kernel-parameters.txt 2005-03-02 04:18:53.000000000 -0700
++++ CVS2_6_11_PA2/Documentation/kernel-parameters.txt 2005-02-13 19:54:56.000000000 -0700
+@@ -1345,9 +1345,6 @@
+ sym53c416= [HW,SCSI]
+ See header of drivers/scsi/sym53c416.c.
+
+- sym53c8xx= [HW,SCSI]
+- See Documentation/scsi/ncr53c8xx.txt.
+-
+ t128= [HW,SCSI]
+ See header of drivers/scsi/t128.c.
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/Documentation/parisc/00-INDEX CVS2_6_11_PA2/Documentation/parisc/00-INDEX
+--- LINUS_2_6_11/Documentation/parisc/00-INDEX 2005-03-02 04:18:54.000000000 -0700
++++ CVS2_6_11_PA2/Documentation/parisc/00-INDEX 2004-11-11 08:52:52.000000000 -0700
+@@ -1,10 +1,6 @@
+ 00-INDEX
+ - this file.
+-IODC.txt
+- - Documentation IODC
+ debugging
+ - some debugging hints for real-mode code
+-mm
+- - Documentation on parisc mm status
+ registers
+ - current/planned usage of registers
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/Documentation/parisc/todo CVS2_6_11_PA2/Documentation/parisc/todo
+--- LINUS_2_6_11/Documentation/parisc/todo 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/Documentation/parisc/todo 2005-02-07 11:34:52.000000000 -0700
+@@ -0,0 +1,83 @@
++Status 2005-02-07 :
++-------------------
++ - Merged to 2.6.11-rc3
++
++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
++ - ad1889 driver: only works with .wav; Convert to ALSA (ggg, tausq, tbone)
++ - 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_11/Documentation/scsi/sym53c8xx_2.txt CVS2_6_11_PA2/Documentation/scsi/sym53c8xx_2.txt
+--- LINUS_2_6_11/Documentation/scsi/sym53c8xx_2.txt 2005-03-02 04:18:55.000000000 -0700
++++ CVS2_6_11_PA2/Documentation/scsi/sym53c8xx_2.txt 2004-12-26 10:32:18.000000000 -0700
+@@ -440,7 +440,7 @@
+ The following command will install the driver module with the same
+ options as above.
+
+- modprobe sym53c8xx cmd_per_lun=4 sync=10 debug=0x200"
++ modprobe sym53c8xx cmd_per_lun=4 sync=10 debug=0x200
+
+ 10.2 Available arguments
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/MAINTAINERS CVS2_6_11_PA2/MAINTAINERS
+--- LINUS_2_6_11/MAINTAINERS 2005-03-02 04:18:52.000000000 -0700
++++ CVS2_6_11_PA2/MAINTAINERS 2005-02-19 17:56:46.000000000 -0700
+@@ -199,6 +199,13 @@
+ W: http://linux.thorsten-knabe.de
+ S: Maintained
+
++AD1889 SOUND DRIVER
++P: Kyle McMartin
++M: kyle at parisc-linux.org
++W: http://www.parisc-linux.org/~kyle/ad1889/
++L: parisc-linux at lists.parisc-linux.org
++S: Maintained
++
+ ADM1025 HARDWARE MONITOR DRIVER
+ P: Jean Delvare
+ M: khali at linux-fr.org
+@@ -916,6 +923,13 @@
+ W: http://hq.pm.waw.pl/hdlc/
+ S: Maintained
+
++HARMONY SOUND DRIVER
++P: Kyle McMartin
++M: kyle at parisc-linux.org
++W: http://www.parisc-linux.org/~kyle/harmony/
++L: parisc-linux at lists.parisc-linux.org
++S: Maintained
++
+ HAYES ESP SERIAL DRIVER
+ P: Andrew J. Robinson
+ M: arobinso at nyx.net
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/Kconfig CVS2_6_11_PA2/arch/parisc/Kconfig
+--- LINUS_2_6_11/arch/parisc/Kconfig 2005-03-02 04:18:59.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/Kconfig 2005-02-04 12:34:34.000000000 -0700
+@@ -6,8 +6,7 @@
+ mainmenu "Linux/PA-RISC Kernel Configuration"
+
+ config PARISC
+- bool
+- default y
++ def_bool y
+ help
+ The PA-RISC microprocessor is designed by Hewlett-Packard and used
+ in many of their workstations & servers (HP9000 700 and 800 series,
+@@ -15,19 +14,16 @@
+ at <http://www.parisc-linux.org/>.
+
+ config MMU
+- bool
+- default y
++ def_bool y
+
+ config STACK_GROWSUP
+- bool
+- default y
++ def_bool y
+
+ config UID16
+ bool
+
+ config RWSEM_GENERIC_SPINLOCK
+- bool
+- default y
++ def_bool y
+
+ config RWSEM_XCHGADD_ALGORITHM
+ bool
+@@ -111,7 +107,7 @@
+ def_bool y
+ depends on PA8X00
+
+-config PARISC64
++config 64BIT
+ bool "64-bit kernel"
+ depends on PA8X00
+ help
+@@ -124,9 +120,6 @@
+ enable this option otherwise. The 64bit kernel is significantly bigger
+ and slower than the 32bit one.
+
+-config 64BIT
+- def_bool PARISC64
+-
+ config SMP
+ bool "Symmetric multi-processing support"
+ ---help---
+@@ -166,13 +159,12 @@
+ default n
+
+ config COMPAT
+- bool
+- depends on PARISC64
+- default y
++ def_bool y
++ depends on 64BIT
+
+ config HPUX
+ bool "Support for HP-UX binaries"
+- depends on !PARISC64
++ depends on !64BIT
+
+ config NR_CPUS
+ int "Maximum number of CPUs (2-32)"
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/Makefile CVS2_6_11_PA2/arch/parisc/Makefile
+--- LINUS_2_6_11/arch/parisc/Makefile 2005-03-02 04:18:59.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/Makefile 2005-02-04 12:34:34.000000000 -0700
+@@ -17,9 +17,12 @@
+ # Mike Shaver, Helge Deller and Martin K. Petersen
+ #
+ NM = sh $(srctree)/arch/parisc/nm
+-ifdef CONFIG_PARISC64
++CHECKFLAGS += -D__hppa__=1
++
++ifdef CONFIG_64BIT
+ CROSS_COMPILE := hppa64-linux-
+ UTS_MACHINE := parisc64
++CHECKFLAGS += -D__LP64__=1 -m64
+ else
+ MACHINE := $(subst 64,,$(shell uname -m))
+ ifneq ($(MACHINE),parisc)
+@@ -65,8 +68,12 @@
+
+ drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/
+
++PALO := $(shell if which palo; then : ; \
++ elif [ -x /sbin/palo ]; then echo /sbin/palo; \
++ fi)
++
+ palo: vmlinux
+- @if [ $$(palo -f /dev/null >/dev/null 2>&1 ; echo $$?) != 2 ]; then \
++ @if [ -x $PALO ]; then \
+ echo 'ERROR: Please install palo first (apt-get install palo)';\
+ echo 'or build it from source and install it somewhere in your $$PATH';\
+ false; \
+@@ -78,7 +85,7 @@
+ echo 'WARNING: the "lifimage" file is now placed in this directory by default!'; \
+ false; \
+ fi
+- palo -f ./palo.conf
++ $(PALO) -f ./palo.conf
+
+ oldpalo: vmlinux
+ export TOPDIR=`pwd`; \
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/configs/a500_defconfig CVS2_6_11_PA2/arch/parisc/configs/a500_defconfig
+--- LINUS_2_6_11/arch/parisc/configs/a500_defconfig 2005-03-02 04:18:59.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/configs/a500_defconfig 2005-02-16 14:19:58.000000000 -0700
+@@ -1,12 +1,15 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-pa5
+-# Wed Jan 5 13:22:34 2005
++# Linux kernel version: 2.6.11-rc4-pa1
++# Wed Feb 16 11:32:49 2005
+ #
+ CONFIG_PARISC=y
+ CONFIG_MMU=y
+ CONFIG_STACK_GROWSUP=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_GENERIC_IRQ_PROBE=y
+
+ #
+ # Code maturity level options
+@@ -68,7 +71,6 @@
+ CONFIG_PA8X00=y
+ CONFIG_PA20=y
+ CONFIG_PREFETCH=y
+-CONFIG_PARISC64=y
+ CONFIG_64BIT=y
+ CONFIG_SMP=y
+ CONFIG_HOTPLUG_CPU=y
+@@ -87,16 +89,12 @@
+ CONFIG_PCI_LBA=y
+ CONFIG_IOSAPIC=y
+ CONFIG_IOMMU_SBA=y
+-# CONFIG_SUPERIO is not set
+-# CONFIG_CHASSIS_LCD_LED is not set
+-CONFIG_PDC_CHASSIS=y
+
+ #
+ # PCCARD (PCMCIA/CardBus) support
+ #
+ CONFIG_PCCARD=m
+ # CONFIG_PCMCIA_DEBUG is not set
+-# CONFIG_PCMCIA_OBSOLETE is not set
+ CONFIG_PCMCIA=m
+ CONFIG_CARDBUS=y
+
+@@ -107,6 +105,7 @@
+ CONFIG_PD6729=m
+ CONFIG_I82092=m
+ CONFIG_TCIC=m
++CONFIG_PCCARD_NONSTATIC=m
+
+ #
+ # PCI Hotplug Support
+@@ -114,6 +113,14 @@
+ # CONFIG_HOTPLUG_PCI is not set
+
+ #
++# PA-RISC specific drivers
++#
++# CONFIG_SUPERIO is not set
++# CONFIG_CHASSIS_LCD_LED is not set
++CONFIG_PDC_CHASSIS=y
++CONFIG_PDC_STABLE=y
++
++#
+ # Executable file formats
+ #
+ CONFIG_BINFMT_ELF=y
+@@ -153,6 +160,7 @@
+ # CONFIG_BLK_CPQ_CISS_DA is not set
+ # CONFIG_BLK_DEV_DAC960 is not set
+ CONFIG_BLK_DEV_UMEM=m
++# CONFIG_BLK_DEV_COW_COMMON is not set
+ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+@@ -171,6 +179,7 @@
+ CONFIG_IOSCHED_AS=y
+ CONFIG_IOSCHED_DEADLINE=y
+ CONFIG_IOSCHED_CFQ=y
++# CONFIG_ATA_OVER_ETH is not set
+
+ #
+ # ATA/ATAPI/MFM/RLL support
+@@ -205,6 +214,7 @@
+ #
+ CONFIG_SCSI_SPI_ATTRS=y
+ CONFIG_SCSI_FC_ATTRS=m
++CONFIG_SCSI_ISCSI_ATTRS=m
+
+ #
+ # SCSI low-level drivers
+@@ -231,10 +241,10 @@
+ # CONFIG_SCSI_INITIO is not set
+ # CONFIG_SCSI_INIA100 is not set
+ CONFIG_SCSI_SYM53C8XX_2=y
+-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
++CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+-CONFIG_SCSI_SYM53C8XX_IOMAPPED=y
++# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
+ # CONFIG_SCSI_IPR is not set
+ # CONFIG_SCSI_PCI2000 is not set
+ # CONFIG_SCSI_PCI2220I is not set
+@@ -249,7 +259,6 @@
+ CONFIG_SCSI_QLA2300=m
+ CONFIG_SCSI_QLA2322=m
+ CONFIG_SCSI_QLA6312=m
+-CONFIG_SCSI_QLA6322=m
+ # CONFIG_SCSI_DC395x is not set
+ # CONFIG_SCSI_DC390T is not set
+ CONFIG_SCSI_DEBUG=m
+@@ -399,8 +408,6 @@
+ CONFIG_IP_NF_ARPTABLES=m
+ CONFIG_IP_NF_ARPFILTER=m
+ CONFIG_IP_NF_ARP_MANGLE=m
+-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+ CONFIG_XFRM=y
+ CONFIG_XFRM_USER=m
+
+@@ -465,7 +472,7 @@
+ #
+ CONFIG_NET_TULIP=y
+ CONFIG_DE2104X=m
+-CONFIG_TULIP=m
++CONFIG_TULIP=y
+ # CONFIG_TULIP_MWI is not set
+ CONFIG_TULIP_MMIO=y
+ # CONFIG_TULIP_NAPI is not set
+@@ -483,7 +490,6 @@
+ # CONFIG_FORCEDETH is not set
+ # CONFIG_DGRS is not set
+ CONFIG_EEPRO100=m
+-# CONFIG_EEPRO100_PIO is not set
+ CONFIG_E100=m
+ CONFIG_E100_NAPI=y
+ # CONFIG_FEALNX is not set
+@@ -524,6 +530,7 @@
+ CONFIG_IXGB_NAPI=y
+ CONFIG_S2IO=m
+ CONFIG_S2IO_NAPI=y
++# CONFIG_2BUFF_MODE is not set
+
+ #
+ # Token Ring devices
+@@ -691,7 +698,6 @@
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+
+ #
+@@ -733,9 +739,9 @@
+ #
+ # Console display driver support
+ #
++CONFIG_DUMMY_CONSOLE=y
+ CONFIG_DUMMY_CONSOLE_COLUMNS=160
+ CONFIG_DUMMY_CONSOLE_ROWS=64
+-CONFIG_DUMMY_CONSOLE=y
+
+ #
+ # Sound
+@@ -764,6 +770,15 @@
+ # CONFIG_MMC is not set
+
+ #
++# InfiniBand support
++#
++CONFIG_INFINIBAND=m
++CONFIG_INFINIBAND_MTHCA=m
++# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
++CONFIG_INFINIBAND_IPOIB=m
++# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
++
++#
+ # File systems
+ #
+ CONFIG_EXT2_FS=y
+@@ -775,10 +790,16 @@
+ # CONFIG_REISERFS_FS is not set
+ CONFIG_JFS_FS=m
+ # CONFIG_JFS_POSIX_ACL is not set
++# CONFIG_JFS_SECURITY is not set
+ # CONFIG_JFS_DEBUG is not set
+ # CONFIG_JFS_STATISTICS is not set
+ CONFIG_FS_POSIX_ACL=y
++
++#
++# XFS support
++#
+ CONFIG_XFS_FS=m
++CONFIG_XFS_EXPORT=y
+ # CONFIG_XFS_RT is not set
+ # CONFIG_XFS_QUOTA is not set
+ # CONFIG_XFS_SECURITY is not set
+@@ -786,7 +807,7 @@
+ # CONFIG_MINIX_FS is not set
+ # CONFIG_ROMFS_FS is not set
+ # CONFIG_QUOTA is not set
+-# CONFIG_DNOTIFY is not set
++CONFIG_DNOTIFY=y
+ # CONFIG_AUTOFS_FS is not set
+ CONFIG_AUTOFS4_FS=y
+
+@@ -817,7 +838,8 @@
+ CONFIG_SYSFS=y
+ # CONFIG_DEVFS_FS is not set
+ # CONFIG_DEVPTS_FS_XATTR is not set
+-# CONFIG_TMPFS is not set
++CONFIG_TMPFS=y
++# CONFIG_TMPFS_XATTR is not set
+ # CONFIG_HUGETLBFS is not set
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
+@@ -935,6 +957,8 @@
+ # CONFIG_DEBUG_SPINLOCK is not set
+ # CONFIG_DEBUG_KOBJECT is not set
+ # CONFIG_DEBUG_INFO is not set
++# CONFIG_DEBUG_IOREMAP is not set
++# CONFIG_DEBUG_FS is not set
+ # CONFIG_DEBUG_RWLOCK is not set
+
+ #
+@@ -973,6 +997,10 @@
+ CONFIG_CRYPTO_TEST=m
+
+ #
++# Hardware crypto devices
++#
++
++#
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/configs/n4000_defconfig CVS2_6_11_PA2/arch/parisc/configs/n4000_defconfig
+--- LINUS_2_6_11/arch/parisc/configs/n4000_defconfig 2005-03-02 04:18:59.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/configs/n4000_defconfig 1969-12-31 17:00:00.000000000 -0700
+@@ -1,927 +0,0 @@
+-#
+-# Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-pa5
+-# Wed Jan 5 13:40:36 2005
+-#
+-CONFIG_PARISC=y
+-CONFIG_MMU=y
+-CONFIG_STACK_GROWSUP=y
+-CONFIG_RWSEM_GENERIC_SPINLOCK=y
+-
+-#
+-# Code maturity level options
+-#
+-CONFIG_EXPERIMENTAL=y
+-# CONFIG_CLEAN_COMPILE is not set
+-CONFIG_BROKEN=y
+-CONFIG_BROKEN_ON_SMP=y
+-
+-#
+-# General setup
+-#
+-CONFIG_LOCALVERSION=""
+-CONFIG_SWAP=y
+-CONFIG_SYSVIPC=y
+-CONFIG_POSIX_MQUEUE=y
+-# CONFIG_BSD_PROCESS_ACCT is not set
+-CONFIG_SYSCTL=y
+-# CONFIG_AUDIT is not set
+-CONFIG_LOG_BUF_SHIFT=16
+-CONFIG_HOTPLUG=y
+-CONFIG_KOBJECT_UEVENT=y
+-CONFIG_IKCONFIG=y
+-CONFIG_IKCONFIG_PROC=y
+-CONFIG_EMBEDDED=y
+-CONFIG_KALLSYMS=y
+-CONFIG_KALLSYMS_ALL=y
+-# CONFIG_KALLSYMS_EXTRA_PASS is not set
+-CONFIG_FUTEX=y
+-CONFIG_EPOLL=y
+-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+-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
+-
+-#
+-# Loadable module support
+-#
+-CONFIG_MODULES=y
+-CONFIG_MODULE_UNLOAD=y
+-CONFIG_MODULE_FORCE_UNLOAD=y
+-CONFIG_OBSOLETE_MODPARM=y
+-# CONFIG_MODVERSIONS is not set
+-# CONFIG_MODULE_SRCVERSION_ALL is not set
+-CONFIG_KMOD=y
+-
+-#
+-# Processor type and features
+-#
+-# CONFIG_PA7000 is not set
+-# CONFIG_PA7100LC is not set
+-# CONFIG_PA7200 is not set
+-# CONFIG_PA7300LC is not set
+-CONFIG_PA8X00=y
+-CONFIG_PA20=y
+-CONFIG_PREFETCH=y
+-CONFIG_PARISC64=y
+-CONFIG_64BIT=y
+-# CONFIG_SMP is not set
+-CONFIG_DISCONTIGMEM=y
+-# CONFIG_PREEMPT is not set
+-CONFIG_COMPAT=y
+-
+-#
+-# Bus options (PCI, PCMCIA, EISA, GSC, ISA)
+-#
+-# CONFIG_GSC is not set
+-CONFIG_PCI=y
+-CONFIG_PCI_LEGACY_PROC=y
+-CONFIG_PCI_NAMES=y
+-CONFIG_PCI_LBA=y
+-CONFIG_IOSAPIC=y
+-CONFIG_IOMMU_SBA=y
+-# CONFIG_SUPERIO is not set
+-CONFIG_CHASSIS_LCD_LED=y
+-# CONFIG_PDC_CHASSIS is not set
+-
+-#
+-# PCCARD (PCMCIA/CardBus) support
+-#
+-# CONFIG_PCCARD is not set
+-
+-#
+-# PC-card bridges
+-#
+-
+-#
+-# PCI Hotplug Support
+-#
+-# CONFIG_HOTPLUG_PCI is not set
+-
+-#
+-# Executable file formats
+-#
+-CONFIG_BINFMT_ELF=y
+-# CONFIG_BINFMT_MISC is not set
+-
+-#
+-# Device Drivers
+-#
+-
+-#
+-# Generic Driver Options
+-#
+-# CONFIG_STANDALONE is not set
+-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+-CONFIG_FW_LOADER=y
+-# CONFIG_DEBUG_DRIVER is not set
+-
+-#
+-# Memory Technology Devices (MTD)
+-#
+-# CONFIG_MTD is not set
+-
+-#
+-# Parallel port support
+-#
+-# CONFIG_PARPORT is not set
+-
+-#
+-# Plug and Play support
+-#
+-
+-#
+-# Block devices
+-#
+-# CONFIG_BLK_DEV_FD is not set
+-# CONFIG_BLK_CPQ_DA is not set
+-# CONFIG_BLK_CPQ_CISS_DA is not set
+-# CONFIG_BLK_DEV_DAC960 is not set
+-CONFIG_BLK_DEV_UMEM=m
+-CONFIG_BLK_DEV_LOOP=y
+-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+-# CONFIG_BLK_DEV_NBD is not set
+-# CONFIG_BLK_DEV_SX8 is not set
+-CONFIG_BLK_DEV_RAM=y
+-CONFIG_BLK_DEV_RAM_COUNT=16
+-CONFIG_BLK_DEV_RAM_SIZE=6144
+-CONFIG_BLK_DEV_INITRD=y
+-CONFIG_INITRAMFS_SOURCE=""
+-CONFIG_CDROM_PKTCDVD=m
+-CONFIG_CDROM_PKTCDVD_BUFFERS=8
+-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+-
+-#
+-# IO Schedulers
+-#
+-CONFIG_IOSCHED_NOOP=y
+-CONFIG_IOSCHED_AS=y
+-CONFIG_IOSCHED_DEADLINE=y
+-CONFIG_IOSCHED_CFQ=y
+-
+-#
+-# ATA/ATAPI/MFM/RLL support
+-#
+-# CONFIG_IDE is not set
+-
+-#
+-# SCSI device support
+-#
+-CONFIG_SCSI=y
+-CONFIG_SCSI_PROC_FS=y
+-
+-#
+-# SCSI support type (disk, tape, CD-ROM)
+-#
+-CONFIG_BLK_DEV_SD=y
+-CONFIG_CHR_DEV_ST=y
+-# CONFIG_CHR_DEV_OSST is not set
+-CONFIG_BLK_DEV_SR=y
+-# CONFIG_BLK_DEV_SR_VENDOR is not set
+-CONFIG_CHR_DEV_SG=y
+-
+-#
+-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+-#
+-CONFIG_SCSI_MULTI_LUN=y
+-# CONFIG_SCSI_CONSTANTS is not set
+-# CONFIG_SCSI_LOGGING is not set
+-
+-#
+-# SCSI Transport Attributes
+-#
+-CONFIG_SCSI_SPI_ATTRS=y
+-CONFIG_SCSI_FC_ATTRS=m
+-
+-#
+-# 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_ADVANSYS is not set
+-# CONFIG_MEGARAID_NEWGEN is not set
+-# CONFIG_MEGARAID_LEGACY 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_IPS is not set
+-# CONFIG_SCSI_INITIO is not set
+-# CONFIG_SCSI_INIA100 is not set
+-CONFIG_SCSI_SYM53C8XX_2=y
+-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+-CONFIG_SCSI_SYM53C8XX_IOMAPPED=y
+-# CONFIG_SCSI_IPR is not set
+-# CONFIG_SCSI_PCI2000 is not set
+-# CONFIG_SCSI_PCI2220I is not set
+-# CONFIG_SCSI_QLOGIC_ISP is not set
+-CONFIG_SCSI_QLOGIC_FC=m
+-# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+-CONFIG_SCSI_QLOGIC_1280=m
+-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
+-CONFIG_SCSI_QLA2XXX=y
+-# CONFIG_SCSI_QLA21XX is not set
+-# CONFIG_SCSI_QLA22XX is not set
+-CONFIG_SCSI_QLA2300=m
+-CONFIG_SCSI_QLA2322=m
+-CONFIG_SCSI_QLA6312=m
+-CONFIG_SCSI_QLA6322=m
+-# CONFIG_SCSI_DC395x is not set
+-# CONFIG_SCSI_DC390T is not set
+-CONFIG_SCSI_DEBUG=m
+-
+-#
+-# Multi-device support (RAID and LVM)
+-#
+-CONFIG_MD=y
+-CONFIG_BLK_DEV_MD=y
+-CONFIG_MD_LINEAR=y
+-CONFIG_MD_RAID0=y
+-CONFIG_MD_RAID1=y
+-# CONFIG_MD_RAID10 is not set
+-# CONFIG_MD_RAID5 is not set
+-# CONFIG_MD_RAID6 is not set
+-# CONFIG_MD_MULTIPATH is not set
+-# CONFIG_MD_FAULTY is not set
+-# CONFIG_BLK_DEV_DM is not set
+-
+-#
+-# Fusion MPT device support
+-#
+-CONFIG_FUSION=m
+-CONFIG_FUSION_MAX_SGE=40
+-CONFIG_FUSION_CTL=m
+-
+-#
+-# IEEE 1394 (FireWire) support
+-#
+-# CONFIG_IEEE1394 is not set
+-
+-#
+-# I2O device support
+-#
+-# CONFIG_I2O is not set
+-
+-#
+-# Networking support
+-#
+-CONFIG_NET=y
+-
+-#
+-# Networking options
+-#
+-CONFIG_PACKET=y
+-CONFIG_PACKET_MMAP=y
+-CONFIG_NETLINK_DEV=y
+-CONFIG_UNIX=y
+-CONFIG_NET_KEY=m
+-CONFIG_INET=y
+-CONFIG_IP_MULTICAST=y
+-# CONFIG_IP_ADVANCED_ROUTER is not set
+-CONFIG_IP_PNP=y
+-CONFIG_IP_PNP_DHCP=y
+-CONFIG_IP_PNP_BOOTP=y
+-# CONFIG_IP_PNP_RARP is not set
+-# CONFIG_NET_IPIP is not set
+-# CONFIG_NET_IPGRE is not set
+-# CONFIG_IP_MROUTE is not set
+-# CONFIG_ARPD is not set
+-# CONFIG_SYN_COOKIES is not set
+-CONFIG_INET_AH=m
+-CONFIG_INET_ESP=m
+-# CONFIG_INET_IPCOMP is not set
+-# CONFIG_INET_TUNNEL is not set
+-CONFIG_IP_TCPDIAG=y
+-# CONFIG_IP_TCPDIAG_IPV6 is not set
+-
+-#
+-# IP: Virtual Server Configuration
+-#
+-# CONFIG_IP_VS is not set
+-# CONFIG_IPV6 is not set
+-CONFIG_NETFILTER=y
+-# CONFIG_NETFILTER_DEBUG 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_CT_PROTO_SCTP is not set
+-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_IPRANGE=m
+-CONFIG_IP_NF_MATCH_MAC=m
+-CONFIG_IP_NF_MATCH_PKTTYPE=m
+-CONFIG_IP_NF_MATCH_MARK=m
+-CONFIG_IP_NF_MATCH_MULTIPORT=m
+-CONFIG_IP_NF_MATCH_TOS=m
+-CONFIG_IP_NF_MATCH_RECENT=m
+-CONFIG_IP_NF_MATCH_ECN=m
+-CONFIG_IP_NF_MATCH_DSCP=m
+-CONFIG_IP_NF_MATCH_AH_ESP=m
+-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=m
+-CONFIG_IP_NF_MATCH_REALM=m
+-CONFIG_IP_NF_MATCH_SCTP=m
+-CONFIG_IP_NF_MATCH_COMMENT=m
+-CONFIG_IP_NF_MATCH_HASHLIMIT=m
+-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_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=m
+-CONFIG_IP_NF_TARGET_SAME=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_CLASSIFY=m
+-CONFIG_IP_NF_RAW=m
+-CONFIG_IP_NF_TARGET_NOTRACK=m
+-CONFIG_IP_NF_ARPTABLES=m
+-CONFIG_IP_NF_ARPFILTER=m
+-CONFIG_IP_NF_ARP_MANGLE=m
+-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+-CONFIG_XFRM=y
+-CONFIG_XFRM_USER=m
+-
+-#
+-# 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_LLC=m
+-CONFIG_LLC2=m
+-# 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
+-
+-#
+-# QoS and/or fair queueing
+-#
+-# CONFIG_NET_SCHED is not set
+-CONFIG_NET_CLS_ROUTE=y
+-
+-#
+-# Network testing
+-#
+-CONFIG_NET_PKTGEN=m
+-# CONFIG_NETPOLL is not set
+-# CONFIG_NET_POLL_CONTROLLER is not set
+-# CONFIG_HAMRADIO is not set
+-# CONFIG_IRDA is not set
+-# CONFIG_BT is not set
+-CONFIG_NETDEVICES=y
+-CONFIG_DUMMY=m
+-CONFIG_BONDING=m
+-# CONFIG_EQUALIZER is not set
+-CONFIG_TUN=m
+-# CONFIG_ETHERTAP is not set
+-
+-#
+-# ARCnet devices
+-#
+-# CONFIG_ARCNET is not set
+-
+-#
+-# Ethernet (10 or 100Mbit)
+-#
+-CONFIG_NET_ETHERNET=y
+-CONFIG_MII=m
+-# CONFIG_HAPPYMEAL is not set
+-# CONFIG_SUNGEM is not set
+-CONFIG_NET_VENDOR_3COM=y
+-CONFIG_VORTEX=m
+-CONFIG_TYPHOON=m
+-
+-#
+-# Tulip family network device support
+-#
+-CONFIG_NET_TULIP=y
+-CONFIG_DE2104X=y
+-CONFIG_TULIP=y
+-# CONFIG_TULIP_MWI is not set
+-CONFIG_TULIP_MMIO=y
+-# CONFIG_TULIP_NAPI is not set
+-# CONFIG_DE4X5 is not set
+-# CONFIG_WINBOND_840 is not set
+-# CONFIG_DM9102 is not set
+-CONFIG_HP100=m
+-CONFIG_NET_PCI=y
+-CONFIG_PCNET32=m
+-# CONFIG_AMD8111_ETH is not set
+-# 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_EEPRO100_PIO is not set
+-CONFIG_E100=m
+-CONFIG_E100_NAPI=y
+-# CONFIG_FEALNX is not set
+-CONFIG_NATSEMI=m
+-# CONFIG_NE2K_PCI is not set
+-# CONFIG_8139CP is not set
+-CONFIG_8139TOO=m
+-# CONFIG_8139TOO_PIO is not set
+-# CONFIG_8139TOO_TUNE_TWISTER is not set
+-# CONFIG_8139TOO_8129 is not set
+-# CONFIG_8139_OLD_RX_RESET is not set
+-# CONFIG_SIS900 is not set
+-CONFIG_EPIC100=m
+-# CONFIG_SUNDANCE is not set
+-CONFIG_VIA_RHINE=m
+-CONFIG_VIA_RHINE_MMIO=y
+-
+-#
+-# Ethernet (1000 Mbit)
+-#
+-CONFIG_ACENIC=m
+-CONFIG_ACENIC_OMIT_TIGON_I=y
+-CONFIG_DL2K=m
+-CONFIG_E1000=m
+-CONFIG_E1000_NAPI=y
+-# CONFIG_NS83820 is not set
+-# CONFIG_HAMACHI is not set
+-# CONFIG_YELLOWFIN is not set
+-# CONFIG_R8169 is not set
+-# CONFIG_SK98LIN is not set
+-# CONFIG_VIA_VELOCITY is not set
+-CONFIG_TIGON3=m
+-
+-#
+-# Ethernet (10000 Mbit)
+-#
+-CONFIG_IXGB=m
+-CONFIG_IXGB_NAPI=y
+-CONFIG_S2IO=m
+-CONFIG_S2IO_NAPI=y
+-
+-#
+-# Token Ring devices
+-#
+-# CONFIG_TR is not set
+-
+-#
+-# Wireless LAN (non-hamradio)
+-#
+-CONFIG_NET_RADIO=y
+-
+-#
+-# Obsolete Wireless cards support (pre-802.11)
+-#
+-# CONFIG_STRIP is not set
+-
+-#
+-# Wireless 802.11b ISA/PCI cards support
+-#
+-CONFIG_HERMES=m
+-CONFIG_PLX_HERMES=m
+-CONFIG_TMD_HERMES=m
+-CONFIG_PCI_HERMES=m
+-# CONFIG_ATMEL is not set
+-
+-#
+-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
+-#
+-# CONFIG_PRISM54 is not set
+-CONFIG_NET_WIRELESS=y
+-
+-#
+-# Wan interfaces
+-#
+-# CONFIG_WAN is not set
+-# CONFIG_FDDI is not set
+-# CONFIG_HIPPI is not set
+-CONFIG_PPP=m
+-# CONFIG_PPP_MULTILINK is not set
+-# CONFIG_PPP_FILTER is not set
+-CONFIG_PPP_ASYNC=m
+-CONFIG_PPP_SYNC_TTY=m
+-CONFIG_PPP_DEFLATE=m
+-CONFIG_PPP_BSDCOMP=m
+-# CONFIG_PPPOE is not set
+-# CONFIG_SLIP is not set
+-# CONFIG_NET_FC is not set
+-# CONFIG_SHAPER is not set
+-# CONFIG_NETCONSOLE is not set
+-
+-#
+-# ISDN subsystem
+-#
+-# CONFIG_ISDN is not set
+-
+-#
+-# Telephony Support
+-#
+-# CONFIG_PHONE is not set
+-
+-#
+-# Input device support
+-#
+-CONFIG_INPUT=y
+-
+-#
+-# Userland interfaces
+-#
+-# CONFIG_INPUT_MOUSEDEV is not set
+-# CONFIG_INPUT_JOYDEV is not set
+-# CONFIG_INPUT_TSDEV is not set
+-# CONFIG_INPUT_EVDEV is not set
+-# CONFIG_INPUT_EVBUG is not set
+-
+-#
+-# Input I/O drivers
+-#
+-# CONFIG_GAMEPORT is not set
+-CONFIG_SOUND_GAMEPORT=y
+-# CONFIG_SERIO is not set
+-
+-#
+-# Input Device Drivers
+-#
+-# CONFIG_INPUT_KEYBOARD is not set
+-# CONFIG_INPUT_MOUSE is not set
+-# CONFIG_INPUT_JOYSTICK is not set
+-# CONFIG_INPUT_TOUCHSCREEN is not set
+-# CONFIG_INPUT_MISC is not set
+-
+-#
+-# Character devices
+-#
+-CONFIG_VT=y
+-CONFIG_VT_CONSOLE=y
+-CONFIG_HW_CONSOLE=y
+-# CONFIG_SERIAL_NONSTANDARD is not set
+-
+-#
+-# Serial drivers
+-#
+-CONFIG_SERIAL_8250=y
+-CONFIG_SERIAL_8250_CONSOLE=y
+-CONFIG_SERIAL_8250_NR_UARTS=8
+-CONFIG_SERIAL_8250_EXTENDED=y
+-CONFIG_SERIAL_8250_MANY_PORTS=y
+-CONFIG_SERIAL_8250_SHARE_IRQ=y
+-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+-# CONFIG_SERIAL_8250_MULTIPORT is not set
+-# CONFIG_SERIAL_8250_RSA is not set
+-
+-#
+-# Non-8250 serial port support
+-#
+-# CONFIG_SERIAL_MUX is not set
+-CONFIG_PDC_CONSOLE=y
+-CONFIG_SERIAL_CORE=y
+-CONFIG_SERIAL_CORE_CONSOLE=y
+-CONFIG_UNIX98_PTYS=y
+-# CONFIG_LEGACY_PTYS is not set
+-
+-#
+-# IPMI
+-#
+-# CONFIG_IPMI_HANDLER is not set
+-
+-#
+-# Watchdog Cards
+-#
+-# CONFIG_WATCHDOG is not set
+-CONFIG_GEN_RTC=y
+-CONFIG_GEN_RTC_X=y
+-# CONFIG_DTLK is not set
+-# CONFIG_R3964 is not set
+-# CONFIG_APPLICOM is not set
+-
+-#
+-# Ftape, the floppy tape device driver
+-#
+-# CONFIG_AGP is not set
+-# CONFIG_DRM is not set
+-CONFIG_RAW_DRIVER=y
+-CONFIG_MAX_RAW_DEVS=256
+-
+-#
+-# I2C support
+-#
+-# CONFIG_I2C is not set
+-
+-#
+-# Dallas's 1-wire bus
+-#
+-# CONFIG_W1 is not set
+-
+-#
+-# Misc devices
+-#
+-
+-#
+-# Multimedia devices
+-#
+-# CONFIG_VIDEO_DEV is not set
+-
+-#
+-# Digital Video Broadcasting Devices
+-#
+-# CONFIG_DVB is not set
+-
+-#
+-# Graphics support
+-#
+-# CONFIG_FB is not set
+-
+-#
+-# Console display driver support
+-#
+-CONFIG_DUMMY_CONSOLE_COLUMNS=160
+-CONFIG_DUMMY_CONSOLE_ROWS=64
+-CONFIG_DUMMY_CONSOLE=y
+-
+-#
+-# Sound
+-#
+-# CONFIG_SOUND is not set
+-
+-#
+-# USB support
+-#
+-# CONFIG_USB is not set
+-CONFIG_USB_ARCH_HAS_HCD=y
+-CONFIG_USB_ARCH_HAS_OHCI=y
+-
+-#
+-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+-#
+-
+-#
+-# USB Gadget Support
+-#
+-# CONFIG_USB_GADGET is not set
+-
+-#
+-# MMC/SD Card support
+-#
+-# CONFIG_MMC is not set
+-
+-#
+-# File systems
+-#
+-CONFIG_EXT2_FS=y
+-# CONFIG_EXT2_FS_XATTR is not set
+-CONFIG_EXT3_FS=y
+-# CONFIG_EXT3_FS_XATTR is not set
+-CONFIG_JBD=y
+-# CONFIG_JBD_DEBUG is not set
+-# CONFIG_REISERFS_FS is not set
+-CONFIG_JFS_FS=m
+-# CONFIG_JFS_POSIX_ACL is not set
+-# CONFIG_JFS_DEBUG is not set
+-# CONFIG_JFS_STATISTICS is not set
+-CONFIG_FS_POSIX_ACL=y
+-CONFIG_XFS_FS=m
+-# CONFIG_XFS_RT is not set
+-# CONFIG_XFS_QUOTA is not set
+-# CONFIG_XFS_SECURITY is not set
+-# CONFIG_XFS_POSIX_ACL is not set
+-# CONFIG_MINIX_FS is not set
+-# CONFIG_ROMFS_FS is not set
+-# CONFIG_QUOTA is not set
+-# CONFIG_DNOTIFY is not set
+-# CONFIG_AUTOFS_FS is not set
+-CONFIG_AUTOFS4_FS=y
+-
+-#
+-# CD-ROM/DVD Filesystems
+-#
+-CONFIG_ISO9660_FS=y
+-CONFIG_JOLIET=y
+-# CONFIG_ZISOFS is not set
+-CONFIG_UDF_FS=m
+-CONFIG_UDF_NLS=y
+-
+-#
+-# DOS/FAT/NT Filesystems
+-#
+-CONFIG_FAT_FS=m
+-CONFIG_MSDOS_FS=m
+-CONFIG_VFAT_FS=m
+-CONFIG_FAT_DEFAULT_CODEPAGE=437
+-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+-# CONFIG_NTFS_FS is not set
+-
+-#
+-# Pseudo filesystems
+-#
+-CONFIG_PROC_FS=y
+-CONFIG_PROC_KCORE=y
+-CONFIG_SYSFS=y
+-# CONFIG_DEVFS_FS is not set
+-# CONFIG_DEVPTS_FS_XATTR is not set
+-CONFIG_TMPFS=y
+-# CONFIG_TMPFS_XATTR is not set
+-# CONFIG_HUGETLBFS is not set
+-# CONFIG_HUGETLB_PAGE is not set
+-CONFIG_RAMFS=y
+-
+-#
+-# Miscellaneous filesystems
+-#
+-# CONFIG_ADFS_FS is not set
+-# CONFIG_AFFS_FS is not set
+-# CONFIG_HFS_FS is not set
+-# 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 is not set
+-# CONFIG_VXFS_FS is not set
+-# CONFIG_HPFS_FS is not set
+-# CONFIG_QNX4FS_FS is not set
+-# CONFIG_SYSV_FS is not set
+-CONFIG_UFS_FS=m
+-# CONFIG_UFS_FS_WRITE is not set
+-
+-#
+-# Network File Systems
+-#
+-CONFIG_NFS_FS=y
+-CONFIG_NFS_V3=y
+-CONFIG_NFS_V4=y
+-CONFIG_NFS_DIRECTIO=y
+-CONFIG_NFSD=m
+-CONFIG_NFSD_V3=y
+-CONFIG_NFSD_V4=y
+-CONFIG_NFSD_TCP=y
+-CONFIG_ROOT_NFS=y
+-CONFIG_LOCKD=y
+-CONFIG_LOCKD_V4=y
+-CONFIG_EXPORTFS=m
+-CONFIG_SUNRPC=y
+-CONFIG_SUNRPC_GSS=y
+-CONFIG_RPCSEC_GSS_KRB5=y
+-# CONFIG_RPCSEC_GSS_SPKM3 is not set
+-CONFIG_SMB_FS=m
+-CONFIG_SMB_NLS_DEFAULT=y
+-CONFIG_SMB_NLS_REMOTE="cp437"
+-CONFIG_CIFS=m
+-# CONFIG_CIFS_STATS is not set
+-# CONFIG_CIFS_XATTR is not set
+-# CONFIG_CIFS_EXPERIMENTAL is not set
+-# CONFIG_NCP_FS is not set
+-# CONFIG_CODA_FS is not set
+-# CONFIG_AFS_FS is not set
+-
+-#
+-# Partition Types
+-#
+-# CONFIG_PARTITION_ADVANCED is not set
+-CONFIG_MSDOS_PARTITION=y
+-
+-#
+-# Native Language Support
+-#
+-CONFIG_NLS=y
+-CONFIG_NLS_DEFAULT="iso8859-1"
+-CONFIG_NLS_CODEPAGE_437=m
+-# CONFIG_NLS_CODEPAGE_737 is not set
+-# CONFIG_NLS_CODEPAGE_775 is not set
+-CONFIG_NLS_CODEPAGE_850=m
+-CONFIG_NLS_CODEPAGE_852=m
+-# CONFIG_NLS_CODEPAGE_855 is not set
+-# CONFIG_NLS_CODEPAGE_857 is not set
+-# CONFIG_NLS_CODEPAGE_860 is not set
+-# CONFIG_NLS_CODEPAGE_861 is not set
+-# CONFIG_NLS_CODEPAGE_862 is not set
+-CONFIG_NLS_CODEPAGE_863=m
+-# CONFIG_NLS_CODEPAGE_864 is not set
+-CONFIG_NLS_CODEPAGE_865=m
+-# CONFIG_NLS_CODEPAGE_866 is not set
+-# CONFIG_NLS_CODEPAGE_869 is not set
+-# CONFIG_NLS_CODEPAGE_936 is not set
+-# CONFIG_NLS_CODEPAGE_950 is not set
+-# CONFIG_NLS_CODEPAGE_932 is not set
+-# CONFIG_NLS_CODEPAGE_949 is not set
+-# CONFIG_NLS_CODEPAGE_874 is not set
+-# CONFIG_NLS_ISO8859_8 is not set
+-# CONFIG_NLS_CODEPAGE_1250 is not set
+-# CONFIG_NLS_CODEPAGE_1251 is not set
+-# CONFIG_NLS_ASCII is not set
+-CONFIG_NLS_ISO8859_1=m
+-CONFIG_NLS_ISO8859_2=m
+-CONFIG_NLS_ISO8859_3=m
+-CONFIG_NLS_ISO8859_4=m
+-# CONFIG_NLS_ISO8859_5 is not set
+-# CONFIG_NLS_ISO8859_6 is not set
+-# CONFIG_NLS_ISO8859_7 is not set
+-# CONFIG_NLS_ISO8859_9 is not set
+-# CONFIG_NLS_ISO8859_13 is not set
+-# CONFIG_NLS_ISO8859_14 is not set
+-CONFIG_NLS_ISO8859_15=m
+-# CONFIG_NLS_KOI8_R is not set
+-# CONFIG_NLS_KOI8_U is not set
+-CONFIG_NLS_UTF8=m
+-
+-#
+-# Profiling support
+-#
+-CONFIG_PROFILING=y
+-CONFIG_OPROFILE=m
+-
+-#
+-# Kernel hacking
+-#
+-CONFIG_DEBUG_KERNEL=y
+-CONFIG_MAGIC_SYSRQ=y
+-# CONFIG_SCHEDSTATS is not set
+-# CONFIG_DEBUG_SLAB is not set
+-# CONFIG_DEBUG_SPINLOCK is not set
+-# CONFIG_DEBUG_KOBJECT is not set
+-# CONFIG_DEBUG_INFO is not set
+-
+-#
+-# Security options
+-#
+-# CONFIG_KEYS is not set
+-# CONFIG_SECURITY is not set
+-
+-#
+-# Cryptographic options
+-#
+-CONFIG_CRYPTO=y
+-CONFIG_CRYPTO_HMAC=y
+-CONFIG_CRYPTO_NULL=m
+-CONFIG_CRYPTO_MD4=m
+-CONFIG_CRYPTO_MD5=y
+-CONFIG_CRYPTO_SHA1=m
+-CONFIG_CRYPTO_SHA256=m
+-CONFIG_CRYPTO_SHA512=m
+-CONFIG_CRYPTO_WP512=m
+-CONFIG_CRYPTO_DES=y
+-CONFIG_CRYPTO_BLOWFISH=m
+-CONFIG_CRYPTO_TWOFISH=m
+-CONFIG_CRYPTO_SERPENT=m
+-CONFIG_CRYPTO_AES=m
+-CONFIG_CRYPTO_CAST5=m
+-CONFIG_CRYPTO_CAST6=m
+-CONFIG_CRYPTO_TEA=m
+-# CONFIG_CRYPTO_ARC4 is not set
+-CONFIG_CRYPTO_KHAZAD=m
+-CONFIG_CRYPTO_ANUBIS=m
+-CONFIG_CRYPTO_DEFLATE=m
+-# CONFIG_CRYPTO_MICHAEL_MIC is not set
+-CONFIG_CRYPTO_CRC32C=m
+-CONFIG_CRYPTO_TEST=m
+-
+-#
+-# Library routines
+-#
+-CONFIG_CRC_CCITT=m
+-CONFIG_CRC32=y
+-CONFIG_LIBCRC32C=m
+-CONFIG_ZLIB_INFLATE=m
+-CONFIG_ZLIB_DEFLATE=m
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/Makefile CVS2_6_11_PA2/arch/parisc/kernel/Makefile
+--- LINUS_2_6_11/arch/parisc/kernel/Makefile 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/Makefile 2005-02-04 12:34:34.000000000 -0700
+@@ -19,6 +19,6 @@
+ obj-$(CONFIG_PA11) += pci-dma.o
+ obj-$(CONFIG_PCI) += pci.o
+ obj-$(CONFIG_MODULES) += module.o
+-obj-$(CONFIG_PARISC64) += binfmt_elf32.o sys_parisc32.o ioctl32.o signal32.o
++obj-$(CONFIG_64BIT) += binfmt_elf32.o sys_parisc32.o ioctl32.o signal32.o
+ # only supported for PCX-W/U in 64-bit mode at the moment
+-obj-$(CONFIG_PARISC64) += perf.o perf_asm.o
++obj-$(CONFIG_64BIT) += perf.o perf_asm.o
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/binfmt_elf32.c CVS2_6_11_PA2/arch/parisc/kernel/binfmt_elf32.c
+--- LINUS_2_6_11/arch/parisc/kernel/binfmt_elf32.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/binfmt_elf32.c 2005-03-01 23:47:36.000000000 -0700
+@@ -37,7 +37,6 @@
+ #include <linux/spinlock.h>
+ #include <asm/processor.h>
+ #include <linux/module.h>
+-#include <linux/config.h>
+ #include <linux/elfcore.h>
+ #include <linux/compat.h> /* struct compat_timeval */
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/drivers.c CVS2_6_11_PA2/arch/parisc/kernel/drivers.c
+--- LINUS_2_6_11/arch/parisc/kernel/drivers.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/drivers.c 2005-01-26 09:23:26.000000000 -0700
+@@ -10,7 +10,7 @@
+ * Copyright (c) 2001 Matthew Wilcox for Hewlett Packard
+ * Copyright (c) 2001 Helge Deller <deller at gmx.de>
+ * Copyright (c) 2001,2002 Ryan Bradetich
+- * Copyright (c) 2004 Thibaut VARENE <varenet at parisc-linux.org>
++ * Copyright (c) 2004-2005 Thibaut VARENE <varenet at parisc-linux.org>
+ *
+ * The file handles registering devices and drivers, then matching them.
+ * It's the closest we get to a dating agency.
+@@ -611,6 +611,24 @@
+ }
+ EXPORT_SYMBOL(hwpath_to_device);
+
++/**
++ * device_to_hwpath - Populates the hwpath corresponding to the given device.
++ * @param dev the target device
++ * @param path pointer to a previously allocated hwpath struct to be filled in
++ */
++void device_to_hwpath(struct device *dev, struct hardware_path *path)
++{
++ struct parisc_device *padev;
++ if (dev->bus == &parisc_bus_type) {
++ padev = to_parisc_device(dev);
++ get_node_path(dev->parent, path);
++ path->mod = padev->hw_path;
++ } else if (is_pci_dev(dev)) {
++ get_node_path(dev, path);
++ }
++}
++EXPORT_SYMBOL(device_to_hwpath);
++
+ #define BC_PORT_MASK 0x8
+ #define BC_LOWER_PORT 0x8
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/entry.S CVS2_6_11_PA2/arch/parisc/kernel/entry.S
+--- LINUS_2_6_11/arch/parisc/kernel/entry.S 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/entry.S 2005-01-07 14:14:33.000000000 -0700
+@@ -76,13 +76,11 @@
+ mtsp %r0, %sr5
+ mtsp %r0, %sr6
+ mtsp %r0, %sr7
+- ldil L%KERNEL_PSW, %r1
+- ldo R%KERNEL_PSW(%r1), %r1
++ load32 KERNEL_PSW, %r1
+ mtctl %r1, %cr22
+ mtctl %r0, %cr17 /* Clear IIASQ tail */
+ mtctl %r0, %cr17 /* Clear IIASQ head */
+- ldil L%4f, %r1
+- ldo R%4f(%r1), %r1
++ load32 4f, %r1
+ mtctl %r1, %cr18 /* Set IIAOQ tail */
+ ldo 4(%r1), %r1
+ mtctl %r1, %cr18 /* Set IIAOQ head */
+@@ -197,8 +195,7 @@
+ /* HPMC handler */
+ .macro hpmc code
+ nop /* must be a NOP, will be patched later */
+- ldil L%PA(os_hpmc), %r3
+- ldo R%PA(os_hpmc)(%r3), %r3
++ load32 PA(os_hpmc), %r3
+ bv,n 0(%r3)
+ nop
+ .word 0 /* checksum (will be patched) */
+@@ -860,8 +857,7 @@
+
+ callee_save
+
+- ldil L%_switch_to_ret, %r2
+- ldo R%_switch_to_ret(%r2), %r2
++ load32 _switch_to_ret, %r2
+
+ STREG %r2, TASK_PT_KPC(%r26)
+ LDREG TASK_PT_KPC(%r25), %r2
+@@ -914,16 +910,13 @@
+ depi 3,31,2,%r19
+ STREG %r19,PT_IAOQ1(%r16)
+ LDREG PT_PSW(%r16),%r19
+- ldil L%USER_PSW_MASK,%r1
+- ldo R%USER_PSW_MASK(%r1),%r1
++ load32 USER_PSW_MASK,%r1
+ #ifdef __LP64__
+- ldil L%USER_PSW_HI_MASK,%r20
+- ldo R%USER_PSW_HI_MASK(%r20),%r20
++ load32 USER_PSW_HI_MASK,%r20
+ depd %r20,31,32,%r1
+ #endif
+ and %r19,%r1,%r19 /* Mask out bits that user shouldn't play with */
+- ldil L%USER_PSW,%r1
+- ldo R%USER_PSW(%r1),%r1
++ load32 USER_PSW,%r1
+ or %r19,%r1,%r19 /* Make sure default USER_PSW bits are set */
+ STREG %r19,PT_PSW(%r16)
+
+@@ -955,8 +948,7 @@
+
+ .import irq_stat,data
+
+- ldil L%irq_stat,%r19
+- ldo R%irq_stat(%r19),%r19
++ load32 irq_stat,%r19
+ #ifdef CONFIG_SMP
+ mfctl %cr30,%r1
+ ldw TI_CPU(%r1),%r1 /* get cpu # - int */
+@@ -1079,7 +1071,7 @@
+ BL do_signal,%r2
+ copy %r0, %r26 /* sigset_t *oldset = NULL */
+
+- b intr_restore
++ b intr_check_sig
+ nop
+
+ /*
+@@ -1607,8 +1599,7 @@
+
+ #ifdef CONFIG_SMP
+ CMPIB=,n 0,spc,dbit_nolock_20w
+- ldil L%PA(pa_dbit_lock),t0
+- ldo R%PA(pa_dbit_lock)(t0),t0
++ load32 PA(pa_dbit_lock),t0
+
+ dbit_spin_20w:
+ ldcw 0(t0),t1
+@@ -1644,8 +1635,7 @@
+
+ #ifdef CONFIG_SMP
+ CMPIB=,n 0,spc,dbit_nolock_11
+- ldil L%PA(pa_dbit_lock),t0
+- ldo R%PA(pa_dbit_lock)(t0),t0
++ load32 PA(pa_dbit_lock),t0
+
+ dbit_spin_11:
+ ldcw 0(t0),t1
+@@ -1685,8 +1675,7 @@
+
+ #ifdef CONFIG_SMP
+ CMPIB=,n 0,spc,dbit_nolock_20
+- ldil L%PA(pa_dbit_lock),t0
+- ldo R%PA(pa_dbit_lock)(t0),t0
++ load32 PA(pa_dbit_lock),t0
+
+ dbit_spin_20:
+ ldcw 0(t0),t1
+@@ -2082,8 +2071,7 @@
+
+ .import irq_stat,data
+
+- ldil L%irq_stat,%r19
+- ldo R%irq_stat(%r19),%r19
++ load32 irq_stat,%r19
+
+ #ifdef CONFIG_SMP
+ /* sched.h: int processor */
+@@ -2282,7 +2270,7 @@
+ ldo TASK_REGS(%r1), %r20 /* reload pt_regs */
+ reg_restore %r20
+
+- b,n syscall_restore
++ b,n syscall_check_sig
+
+ /*
+ * get_register is used by the non access tlb miss handlers to
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/firmware.c CVS2_6_11_PA2/arch/parisc/kernel/firmware.c
+--- LINUS_2_6_11/arch/parisc/kernel/firmware.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/firmware.c 2005-02-11 14:28:18.000000000 -0700
+@@ -120,10 +120,10 @@
+ #ifdef __LP64__
+ if(unlikely(parisc_narrow_firmware)) {
+ if((address & 0xff000000) == 0xf0000000)
+- return 0xf0f0f0f000000000 | (u32)address;
++ return 0xf0f0f0f000000000UL | (u32)address;
+
+ if((address & 0xf0000000) == 0xf0000000)
+- return 0xffffffff00000000 | (u32)address;
++ return 0xffffffff00000000UL | (u32)address;
+ }
+ #endif
+ return address;
+@@ -782,6 +782,8 @@
+ {
+ int retval;
+
++ BUG_ON((unsigned long)tbl & 0x7);
++
+ spin_lock_irq(&pdc_lock);
+ pdc_result[0] = num_entries;
+ retval = mem_pdc_call(PDC_PCI_INDEX, PDC_PCI_GET_INT_TBL,
+@@ -912,7 +914,7 @@
+ *
+ * Reset the system.
+ */
+-int pdc_do_reset()
++int pdc_do_reset(void)
+ {
+ int retval;
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/hardware.c CVS2_6_11_PA2/arch/parisc/kernel/hardware.c
+--- LINUS_2_6_11/arch/parisc/kernel/hardware.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/hardware.c 2004-10-04 13:12:49.000000000 -0600
+@@ -1296,18 +1296,18 @@
+ };
+
+ char *cpu_name_version[][2] = {
+- [pcx] { "PA7000 (PCX)", "1.0" },
+- [pcxs] { "PA7000 (PCX-S)", "1.1a" },
+- [pcxt] { "PA7100 (PCX-T)", "1.1b" },
+- [pcxt_] { "PA7200 (PCX-T')", "1.1c" },
+- [pcxl] { "PA7100LC (PCX-L)", "1.1d" },
+- [pcxl2] { "PA7300LC (PCX-L2)", "1.1e" },
+- [pcxu] { "PA8000 (PCX-U)", "2.0" },
+- [pcxu_] { "PA8200 (PCX-U+)", "2.0" },
+- [pcxw] { "PA8500 (PCX-W)", "2.0" },
+- [pcxw_] { "PA8600 (PCX-W+)", "2.0" },
+- [pcxw2] { "PA8700 (PCX-W2)", "2.0" },
+- [mako] { "PA8800 (Mako)", "2.0" }
++ [pcx] = { "PA7000 (PCX)", "1.0" },
++ [pcxs] = { "PA7000 (PCX-S)", "1.1a" },
++ [pcxt] = { "PA7100 (PCX-T)", "1.1b" },
++ [pcxt_] = { "PA7200 (PCX-T')", "1.1c" },
++ [pcxl] = { "PA7100LC (PCX-L)", "1.1d" },
++ [pcxl2] = { "PA7300LC (PCX-L2)", "1.1e" },
++ [pcxu] = { "PA8000 (PCX-U)", "2.0" },
++ [pcxu_] = { "PA8200 (PCX-U+)", "2.0" },
++ [pcxw] = { "PA8500 (PCX-W)", "2.0" },
++ [pcxw_] = { "PA8600 (PCX-W+)", "2.0" },
++ [pcxw2] = { "PA8700 (PCX-W2)", "2.0" },
++ [mako] = { "PA8800 (Mako)", "2.0" }
+ };
+
+ const char * __init
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/head.S CVS2_6_11_PA2/arch/parisc/kernel/head.S
+--- LINUS_2_6_11/arch/parisc/kernel/head.S 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/head.S 2004-11-01 09:15:50.000000000 -0700
+@@ -71,47 +71,42 @@
+ stw,ma %arg2,4(%r1)
+ stw,ma %arg3,4(%r1)
+
+- /* Initialize startup VM. Just map first 8 MB of memory */
+- load32 PA(pg0),%r1
+-
+-#ifdef __LP64__
+- load32 PA(pmd0),%r5
+- shrd %r5,PxD_VALUE_SHIFT,%r3
+-#else
+- shr %r1,PxD_VALUE_SHIFT,%r3
+-#endif
+- ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
+-
++ /* Initialize startup VM. Just map first 8/16 MB of memory */
+ load32 PA(swapper_pg_dir),%r4
+ mtctl %r4,%cr24 /* Initialize kernel root pointer */
+ mtctl %r4,%cr25 /* Initialize user root pointer */
+
+ #ifdef __LP64__
++ /* Set pmd in pgd */
++ load32 PA(pmd0),%r5
++ shrd %r5,PxD_VALUE_SHIFT,%r3
++ ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
+ stw %r3,ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4)
+- shrd %r1,PxD_VALUE_SHIFT,%r3
+- ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
+- ldo ASM_PMD_ENTRY*ASM_PMD_ENTRY_SIZE(%r5),%r5
++ ldo ASM_PMD_ENTRY*ASM_PMD_ENTRY_SIZE(%r5),%r4
+ #else
++ /* 2-level page table, so pmd == pgd */
+ ldo ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4),%r4
+ #endif
++
++ /* Fill in pmd with enough pte directories */
++ load32 PA(pg0),%r1
++ SHRREG %r1,PxD_VALUE_SHIFT,%r3
++ ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3
++
+ ldi ASM_PT_INITIAL,%r1
+
+ 1:
+-#ifdef __LP64__
+- stw %r3,0(%r5)
+-#else
+- stw %r3,0(%r4)
+-#endif
+-
++ stw %r3,0(%r4)
+ ldo (ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
+ addib,> -1,%r1,1b
+-
+ #ifdef __LP64__
+- ldo ASM_PMD_ENTRY_SIZE(%r5),%r5
++ ldo ASM_PMD_ENTRY_SIZE(%r4),%r4
+ #else
+- ldo ASM_PGD_ENTRY_SIZE(%r4),%r4
++ ldo ASM_PGD_ENTRY_SIZE(%r4),%r4
+ #endif
+
++
++ /* Now initialize the PTEs themselves */
+ ldo _PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */
+ load32 PA(pg0),%r1
+
+@@ -306,7 +301,7 @@
+ mtctl %r11,%cr18 /* IIAOQ head */
+ ldo 4(%r11),%r11
+ mtctl %r11,%cr18 /* IIAOQ tail */
+-
++
+ /* Jump to hyperspace */
+ rfi
+ nop
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/hpmc.S CVS2_6_11_PA2/arch/parisc/kernel/hpmc.S
+--- LINUS_2_6_11/arch/parisc/kernel/hpmc.S 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/hpmc.S 2005-01-07 14:14:33.000000000 -0700
+@@ -121,8 +121,7 @@
+
+ /* Setup stack pointer. */
+
+- ldil L%PA(hpmc_stack),sp
+- ldo R%PA(hpmc_stack)(sp),sp
++ load32 PA(hpmc_stack),sp
+
+ ldo 128(sp),sp /* leave room for arguments */
+
+@@ -135,8 +134,7 @@
+ mtctl %r4,ipsw
+ mtctl %r0,pcsq
+ mtctl %r0,pcsq
+- ldil L%PA(os_hpmc_1),%r4
+- ldo R%PA(os_hpmc_1)(%r4),%r4
++ load32 PA(os_hpmc_1),%r4
+ mtctl %r4,pcoq
+ ldo 4(%r4),%r4
+ mtctl %r4,pcoq
+@@ -155,12 +153,9 @@
+
+ ldo PDC_PIM(%r0), arg0
+ ldo PDC_PIM_HPMC(%r0),arg1 /* Transfer HPMC data */
+- ldil L%PA(hpmc_raddr),arg2
+- ldo R%PA(hpmc_raddr)(arg2),arg2
+- ldil L%PA(hpmc_pim_data),arg3
+- ldo R%PA(hpmc_pim_data)(arg3),arg3
+- ldil L%HPMC_PIM_DATA_SIZE,%r4
+- ldo R%HPMC_PIM_DATA_SIZE(%r4),%r4
++ load32 PA(hpmc_raddr),arg2
++ load32 PA(hpmc_pim_data),arg3
++ load32 HPMC_PIM_DATA_SIZE,%r4
+ stw %r4,-52(sp)
+
+ ldil L%PA(os_hpmc_2), rp
+@@ -199,16 +194,13 @@
+
+ ldo PDC_IODC(%r0),arg0
+ ldo PDC_IODC_READ(%r0),arg1
+- ldil L%PA(hpmc_raddr),arg2
+- ldo R%PA(hpmc_raddr)(arg2),arg2
++ load32 PA(hpmc_raddr),arg2
+ ldw BOOT_CONSOLE_HPA_OFFSET(%r0),arg3 /* console hpa */
+ ldo PDC_IODC_RI_INIT(%r0),%r4
+ stw %r4,-52(sp)
+- ldil L%PA(hpmc_iodc_buf),%r4
+- ldo R%PA(hpmc_iodc_buf)(%r4),%r4
++ load32 PA(hpmc_iodc_buf),%r4
+ stw %r4,-56(sp)
+- ldil L%HPMC_IODC_BUF_SIZE,%r4
+- ldo R%HPMC_IODC_BUF_SIZE(%r4),%r4
++ load32 HPMC_IODC_BUF_SIZE,%r4
+ stw %r4,-60(sp)
+
+ ldil L%PA(os_hpmc_4),rp
+@@ -225,16 +217,14 @@
+ ldw BOOT_CONSOLE_SPA_OFFSET(%r0),arg2 /* console spa */
+ depi 0,31,11,arg2 /* clear bits 21-31 */
+ ldo BOOT_CONSOLE_PATH_OFFSET(%r0),arg3 /* console path */
+- ldil L%PA(hpmc_raddr),%r4
+- ldo R%PA(hpmc_raddr)(%r4),%r4
++ load32 PA(hpmc_raddr),%r4
+ stw %r4, -52(sp)
+ stw %r0, -56(sp) /* HV */
+ stw %r0, -60(sp) /* HV */
+ stw %r0, -64(sp) /* HV */
+ stw %r0, -68(sp) /* lang, must be zero */
+
+- ldil L%PA(hpmc_iodc_buf),%r5
+- ldo R%PA(hpmc_iodc_buf)(%r5),%r5
++ load32 PA(hpmc_iodc_buf),%r5
+ ldil L%PA(os_hpmc_5),rp
+ bv (%r5)
+ ldo R%PA(os_hpmc_5)(rp),rp
+@@ -249,8 +239,7 @@
+ * we don't intend to ever return to user land anyway)
+ */
+
+- ldil L%PA(swapper_pg_dir),%r4
+- ldo R%PA(swapper_pg_dir)(%r4),%r4
++ load32 PA(swapper_pg_dir),%r4
+ mtctl %r4,%cr24 /* Initialize kernel root pointer */
+ mtctl %r4,%cr25 /* Initialize user root pointer */
+
+@@ -265,8 +254,7 @@
+
+ rsm 8,%r0 /* Clear Q bit */
+ ldi 1,%r8 /* Set trap code to "1" for HPMC */
+- ldil L%PA(intr_save), %r1
+- ldo R%PA(intr_save)(%r1), %r1
++ load32 PA(intr_save),%r1
+ be 0(%sr7,%r1)
+ nop
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/init_task.c CVS2_6_11_PA2/arch/parisc/kernel/init_task.c
+--- LINUS_2_6_11/arch/parisc/kernel/init_task.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/init_task.c 2004-10-31 16:11:09.000000000 -0700
+@@ -55,11 +55,15 @@
+
+ #ifdef __LP64__
+ /* NOTE: This layout exactly conforms to the hybrid L2/L3 page table layout
+- * with the first pmd adjacent to the pgd and below it */
+-pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((aligned(PAGE_SIZE))) = { {0}, };
++ * with the first pmd adjacent to the pgd and below it. gcc doesn't actually
++ * guarantee that global objects will be laid out in memory in the same order
++ * as the order of declaration, so put these in different sections and use
++ * the linker script to order them. */
++pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((aligned(PAGE_SIZE))) __attribute__ ((__section__ (".data.vm0.pmd"))) = { {0}, };
++
+ #endif
+-pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((aligned(PAGE_SIZE))) = { {0}, };
+-pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((aligned(PAGE_SIZE))) = { {0}, };
++pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((aligned(PAGE_SIZE))) __attribute__ ((__section__ (".data.vm0.pgd"))) = { {0}, };
++pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((aligned(PAGE_SIZE))) __attribute__ ((__section__ (".data.vm0.pte"))) = { {0}, };
+
+ /*
+ * Initial task structure.
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/ioctl32.c CVS2_6_11_PA2/arch/parisc/kernel/ioctl32.c
+--- LINUS_2_6_11/arch/parisc/kernel/ioctl32.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/ioctl32.c 2004-10-04 13:12:49.000000000 -0600
+@@ -563,7 +563,7 @@
+
+ #endif
+
+-#define HANDLE_IOCTL(cmd, handler) { cmd, (ioctl_trans_handler_t)handler, 0 },
++#define HANDLE_IOCTL(cmd, handler) { cmd, (ioctl_trans_handler_t)handler, NULL },
+ #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl)
+
+ #define IOCTL_TABLE_START struct ioctl_trans ioctl_start[] = {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/irq.c CVS2_6_11_PA2/arch/parisc/kernel/irq.c
+--- LINUS_2_6_11/arch/parisc/kernel/irq.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/irq.c 2005-02-13 20:22:34.000000000 -0700
+@@ -5,6 +5,7 @@
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle
+ * Copyright (C) 1999 SuSE GmbH (Philipp Rumpf, prumpf at tux.org)
+ * Copyright (C) 1999-2000 Grant Grundler
++ * Copyright (c) 2005 Matthew Wilcox
+ *
+ * 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
+@@ -22,38 +23,19 @@
+ */
+ #include <linux/bitops.h>
+ #include <linux/config.h>
+-#include <linux/eisa.h>
+ #include <linux/errno.h>
+ #include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/signal.h>
+-#include <linux/types.h>
+-#include <linux/ioport.h>
+-#include <linux/timex.h>
+-#include <linux/slab.h>
+-#include <linux/random.h>
+-#include <linux/sched.h>
+ #include <linux/interrupt.h>
+ #include <linux/kernel_stat.h>
+-#include <linux/irq.h>
+ #include <linux/seq_file.h>
+ #include <linux/spinlock.h>
++#include <linux/types.h>
+
+-#include <asm/cache.h>
+-#include <asm/pdc.h>
+-
+-#undef DEBUG_IRQ
+ #undef PARISC_IRQ_CR16_COUNTS
+
+ extern irqreturn_t timer_interrupt(int, void *, struct pt_regs *);
+ extern irqreturn_t ipi_interrupt(int, void *, struct pt_regs *);
+
+-#ifdef DEBUG_IRQ
+-#define DBG_IRQ(irq, x) if ((irq) != TIMER_IRQ) printk x
+-#else /* DEBUG_IRQ */
+-#define DBG_IRQ(irq, x) do { } while (0)
+-#endif /* DEBUG_IRQ */
+-
+ #define EIEM_MASK(irq) (1UL<<(CPU_IRQ_MAX - irq))
+
+ /* Bits in EIEM correlate with cpu_irq_action[].
+@@ -120,8 +102,10 @@
+ }
+
+ if (i < NR_IRQS) {
++ struct irqaction *action;
++
+ spin_lock_irqsave(&irq_desc[i].lock, flags);
+- struct irqaction *action = irq_desc[i].action;
++ action = irq_desc[i].action;
+ if (!action)
+ goto skip;
+ seq_printf(p, "%3d: ", i);
+@@ -200,7 +184,25 @@
+ return cpu_claim_irq(irq, NULL, NULL) ? -1 : irq;
+ }
+
+-int txn_alloc_irq(void)
++/*
++ * The bits_wide parameter accommodates the limitations of the HW/SW which
++ * use these bits:
++ * Legacy PA I/O (GSC/NIO): 5 bits (architected EIM register)
++ * V-class (EPIC): 6 bits
++ * N/L/A-class (iosapic): 8 bits
++ * PCI 2.2 MSI: 16 bits
++ * Some PCI devices: 32 bits (Symbios SCSI/ATM/HyperFabric)
++ *
++ * On the service provider side:
++ * o PA 1.1 (and PA2.0 narrow mode) 5-bits (width of EIR register)
++ * o PA 2.0 wide mode 6-bits (per processor)
++ * o IA64 8-bits (0-256 total)
++ *
++ * So a Legacy PA I/O device on a PA 2.0 box can't use all the bits supported
++ * by the processor...and the N/L-class I/O subsystem supports more bits than
++ * PA2.0 has. The first case is the problem.
++ */
++int txn_alloc_irq(unsigned int bits_wide)
+ {
+ int irq;
+
+@@ -208,6 +210,8 @@
+ for (irq = CPU_IRQ_BASE + 1; irq <= CPU_IRQ_MAX; irq++) {
+ if (cpu_claim_irq(irq, NULL, NULL) < 0)
+ continue;
++ if ((irq - CPU_IRQ_BASE) >= (1 << bits_wide))
++ continue;
+ return irq;
+ }
+
+@@ -215,7 +219,7 @@
+ return -1;
+ }
+
+-unsigned long txn_alloc_addr(int virt_irq)
++unsigned long txn_alloc_addr(unsigned int virt_irq)
+ {
+ static int next_cpu = -1;
+
+@@ -233,36 +237,8 @@
+ }
+
+
+-/*
+-** The alloc process needs to accept a parameter to accommodate limitations
+-** of the HW/SW which use these bits:
+-** Legacy PA I/O (GSC/NIO): 5 bits (architected EIM register)
+-** V-class (EPIC): 6 bits
+-** N/L-class/A500: 8 bits (iosapic)
+-** PCI 2.2 MSI: 16 bits (I think)
+-** Existing PCI devices: 32-bits (all Symbios SCSI/ATM/HyperFabric)
+-**
+-** On the service provider side:
+-** o PA 1.1 (and PA2.0 narrow mode) 5-bits (width of EIR register)
+-** o PA 2.0 wide mode 6-bits (per processor)
+-** o IA64 8-bits (0-256 total)
+-**
+-** So a Legacy PA I/O device on a PA 2.0 box can't use all
+-** the bits supported by the processor...and the N/L-class
+-** I/O subsystem supports more bits than PA2.0 has. The first
+-** case is the problem.
+-*/
+-unsigned int txn_alloc_data(int virt_irq, unsigned int bits_wide)
++unsigned int txn_alloc_data(unsigned int virt_irq)
+ {
+- /* XXX FIXME : bits_wide indicates how wide the transaction
+- ** data is allowed to be...we may need a different virt_irq
+- ** if this one won't work. Another reason to index virtual
+- ** irq's into a table which can manage CPU/IRQ bit separately.
+- */
+- if ((virt_irq - CPU_IRQ_BASE) > (1 << (bits_wide - 1))) {
+- panic("Sorry -- didn't allocate valid IRQ for this device\n");
+- }
+-
+ return virt_irq - CPU_IRQ_BASE;
+ }
+
+@@ -270,42 +246,35 @@
+ void do_cpu_irq_mask(struct pt_regs *regs)
+ {
+ unsigned long eirr_val;
+- unsigned int i=3; /* limit time in interrupt context */
++
++ irq_enter();
+
+ /*
+- * PSW_I or EIEM bits cannot be enabled until after the
+- * interrupts are processed.
+- * timer_interrupt() assumes it won't get interrupted when it
+- * holds the xtime_lock...an unmasked interrupt source could
+- * interrupt and deadlock by trying to grab xtime_lock too.
+- * Keeping PSW_I and EIEM disabled avoids this.
++ * Only allow interrupt processing to be interrupted by the
++ * timer tick
+ */
+- set_eiem(0UL); /* disable all extr interrupt for now */
++ set_eiem(EIEM_MASK(TIMER_IRQ));
+
+ /* 1) only process IRQs that are enabled/unmasked (cpu_eiem)
+ * 2) We loop here on EIRR contents in order to avoid
+ * nested interrupts or having to take another interrupt
+ * when we could have just handled it right away.
+- * 3) Limit the number of times we loop to make sure other
+- * processing can occur.
+ */
+ for (;;) {
+ unsigned long bit = (1UL << (BITS_PER_LONG - 1));
+ unsigned int irq;
+ eirr_val = mfctl(23) & cpu_eiem;
+- if (!eirr_val || !i--)
++ if (!eirr_val)
+ break;
+
+- mtctl(eirr_val, 23); /* reset bits we are going to process */
++ if (eirr_val & EIEM_MASK(TIMER_IRQ))
++ set_eiem(0);
+
+-#ifdef DEBUG_IRQ
+- if (eirr_val != (1UL << MAX_CPU_IRQ))
+- printk(KERN_DEBUG "do_cpu_irq_mask 0x%x & 0x%x\n", eirr_val, cpu_eiem);
+-#endif
++ mtctl(eirr_val, 23); /* reset bits we are going to process */
+
+ /* Work our way from MSb to LSb...same order we alloc EIRs */
+ for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) {
+- if (!(bit & eirr_val & cpu_eiem))
++ if (!(bit & eirr_val))
+ continue;
+
+ /* clear bit in mask - can exit loop sooner */
+@@ -315,6 +284,7 @@
+ }
+ }
+ set_eiem(cpu_eiem);
++ irq_exit();
+ }
+
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/module.c CVS2_6_11_PA2/arch/parisc/kernel/module.c
+--- LINUS_2_6_11/arch/parisc/kernel/module.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/module.c 2005-02-25 07:54:20.000000000 -0700
+@@ -2,7 +2,7 @@
+ *
+ * The best reference for this stuff is probably the Processor-
+ * Specific ELF Supplement for PA-RISC:
+- * http://ftp.parisc-linux.org/docs/elf-pa-hp.pdf
++ * http://ftp.parisc-linux.org/docs/arch/elf-pa-hp.pdf
+ *
+ * Linux/PA-RISC Project (http://www.parisc-linux.org/)
+ * Copyright (C) 2003 Randolph Chung <tausq at debian . org>
+@@ -21,6 +21,23 @@
+ * 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
++ *
++ *
++ * Notes:
++ * - SEGREL32 handling
++ * We are not doing SEGREL32 handling correctly. According to the ABI, we
++ * should do a value offset, like this:
++ * if (is_init(me, (void *)val))
++ * val -= (uint32_t)me->module_init;
++ * else
++ * val -= (uint32_t)me->module_core;
++ * However, SEGREL32 is used only for PARISC unwind entries, and we want
++ * those entries to have an absolute address, and not just an offset.
++ *
++ * The unwind table mechanism has the ability to specify an offset for
++ * the unwind table; however, because we split off the init functions into
++ * a different piece of memory, it is not possible to do this using a
++ * single offset. Instead, we use the above hack for now.
+ */
+
+ #include <linux/moduleloader.h>
+@@ -30,6 +47,8 @@
+ #include <linux/string.h>
+ #include <linux/kernel.h>
+
++#include <asm/unwind.h>
++
+ #if 0
+ #define DEBUGP printk
+ #else
+@@ -248,6 +267,10 @@
+ const Elf_Rela *rels = (void *)hdr + sechdrs[i].sh_offset;
+ unsigned long nrels = sechdrs[i].sh_size / sizeof(*rels);
+
++ if (strncmp(secstrings + sechdrs[i].sh_name,
++ ".PARISC.unwind", 14) == 0)
++ me->arch.unwind_section = i;
++
+ if (sechdrs[i].sh_type != SHT_RELA)
+ continue;
+
+@@ -499,7 +522,9 @@
+ break;
+ case R_PARISC_SEGREL32:
+ /* 32-bit segment relative address */
+- val -= (uint32_t)me->module_core;
++ /* See note about special handling of SEGREL32 at
++ * the beginning of this file.
++ */
+ *loc = fsel(val, addend);
+ break;
+ case R_PARISC_DPREL21L:
+@@ -651,7 +676,9 @@
+ break;
+ case R_PARISC_SEGREL32:
+ /* 32-bit segment relative address */
+- val -= (uint64_t)me->module_core;
++ /* See note about special handling of SEGREL32 at
++ * the beginning of this file.
++ */
+ *loc = fsel(val, addend);
+ break;
+ case R_PARISC_FPTR64:
+@@ -682,6 +709,32 @@
+ }
+ #endif
+
++static void
++register_unwind_table(struct module *me,
++ const Elf_Shdr *sechdrs)
++{
++ unsigned char *table, *end;
++ unsigned long gp;
++
++ if (!me->arch.unwind_section)
++ return;
++
++ table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
++ end = table + sechdrs[me->arch.unwind_section].sh_size;
++ gp = (Elf_Addr)me->module_core + me->arch.got_offset;
++
++ DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
++ me->arch.unwind_section, table, end, gp);
++ me->arch.unwind = unwind_table_add(me->name, 0, gp, table, end);
++}
++
++static void
++deregister_unwind_table(struct module *me)
++{
++ if (me->arch.unwind)
++ unwind_table_remove(me->arch.unwind);
++}
++
+ int module_finalize(const Elf_Ehdr *hdr,
+ const Elf_Shdr *sechdrs,
+ struct module *me)
+@@ -711,6 +764,8 @@
+ me->arch.fdesc_count, me->arch.fdesc_max);
+ #endif
+
++ register_unwind_table(me, sechdrs);
++
+ /* haven't filled in me->symtab yet, so have to find it
+ * ourselves */
+ for (i = 1; i < hdr->e_shnum; i++) {
+@@ -763,4 +818,5 @@
+
+ void module_arch_cleanup(struct module *mod)
+ {
++ deregister_unwind_table(mod);
+ }
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/pacache.S CVS2_6_11_PA2/arch/parisc/kernel/pacache.S
+--- LINUS_2_6_11/arch/parisc/kernel/pacache.S 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/pacache.S 2005-02-27 16:41:13.000000000 -0700
+@@ -27,17 +27,17 @@
+ */
+
+ #ifdef __LP64__
+-#define ADDIB addib,*
+-#define CMPB cmpb,*
+-#define ANDCM andcm,*
++#define ADDIB addib,*
++#define CMPB cmpb,*
++#define ANDCM andcm,*
+
+- .level 2.0w
++ .level 2.0w
+ #else
+-#define ADDIB addib,
+-#define CMPB cmpb,
+-#define ANDCM andcm
++#define ADDIB addib,
++#define CMPB cmpb,
++#define ANDCM andcm
+
+- .level 2.0
++ .level 2.0
+ #endif
+
+ #include <asm/assembly.h>
+@@ -46,7 +46,7 @@
+ #include <asm/cache.h>
+
+ .text
+- .align 128
++ .align 128
+
+ .export flush_tlb_all_local,code
+
+@@ -68,7 +68,7 @@
+ * consolidated.
+ */
+
+- rsm PSW_SM_I,%r19 /* relied upon translation! PA 2.0 Arch. F-5 */
++ rsm PSW_SM_I, %r19 /* relied upon translation! PA 2.0 Arch. F-5 */
+ nop
+ nop
+ nop
+@@ -77,127 +77,127 @@
+ nop
+ nop
+
+- rsm PSW_SM_Q,%r0 /* Turn off Q bit to load iia queue */
+- ldil L%REAL_MODE_PSW, %r1
+- ldo R%REAL_MODE_PSW(%r1), %r1
+- mtctl %r1, %cr22
+- mtctl %r0, %cr17 /* Clear IIASQ tail */
+- mtctl %r0, %cr17 /* Clear IIASQ head */
+- ldil L%PA(1f),%r1
+- ldo R%PA(1f)(%r1),%r1
+- mtctl %r1, %cr18 /* IIAOQ head */
+- ldo 4(%r1), %r1
+- mtctl %r1, %cr18 /* IIAOQ tail */
++ rsm PSW_SM_Q, %r0 /* Turn off Q bit to load iia queue */
++ ldil L%REAL_MODE_PSW, %r1
++ ldo R%REAL_MODE_PSW(%r1), %r1
++ mtctl %r1, %cr22
++ mtctl %r0, %cr17 /* Clear IIASQ tail */
++ mtctl %r0, %cr17 /* Clear IIASQ head */
++ ldil L%PA(1f), %r1
++ ldo R%PA(1f)(%r1), %r1
++ mtctl %r1, %cr18 /* IIAOQ head */
++ ldo 4(%r1), %r1
++ mtctl %r1, %cr18 /* IIAOQ tail */
+ rfi
+ nop
+
+-1: ldil L%PA(cache_info),%r1
+- ldo R%PA(cache_info)(%r1),%r1
++1: ldil L%PA(cache_info), %r1
++ ldo R%PA(cache_info)(%r1), %r1
+
+ /* Flush Instruction Tlb */
+
+- LDREG ITLB_SID_BASE(%r1),%r20
+- LDREG ITLB_SID_STRIDE(%r1),%r21
+- LDREG ITLB_SID_COUNT(%r1),%r22
+- LDREG ITLB_OFF_BASE(%r1),%arg0
+- LDREG ITLB_OFF_STRIDE(%r1),%arg1
+- LDREG ITLB_OFF_COUNT(%r1),%arg2
+- LDREG ITLB_LOOP(%r1),%arg3
+-
+- ADDIB= -1,%arg3,fitoneloop /* Preadjust and test */
+- movb,<,n %arg3,%r31,fitdone /* If loop < 0, skip */
+- copy %arg0,%r28 /* Init base addr */
+-
+-fitmanyloop: /* Loop if LOOP >= 2 */
+- mtsp %r20,%sr1
+- add %r21,%r20,%r20 /* increment space */
+- copy %arg2,%r29 /* Init middle loop count */
+-
+-fitmanymiddle: /* Loop if LOOP >= 2 */
+- ADDIB> -1,%r31,fitmanymiddle /* Adjusted inner loop decr */
+- pitlbe 0(%sr1,%r28)
+- pitlbe,m %arg1(%sr1,%r28) /* Last pitlbe and addr adjust */
+- ADDIB> -1,%r29,fitmanymiddle /* Middle loop decr */
+- copy %arg3,%r31 /* Re-init inner loop count */
+-
+- movb,tr %arg0,%r28,fitmanyloop /* Re-init base addr */
+- ADDIB<=,n -1,%r22,fitdone /* Outer loop count decr */
+-
+-fitoneloop: /* Loop if LOOP = 1 */
+- mtsp %r20,%sr1
+- copy %arg0,%r28 /* init base addr */
+- copy %arg2,%r29 /* init middle loop count */
+-
+-fitonemiddle: /* Loop if LOOP = 1 */
+- ADDIB> -1,%r29,fitonemiddle /* Middle loop count decr */
+- pitlbe,m %arg1(%sr1,%r28) /* pitlbe for one loop */
++ LDREG ITLB_SID_BASE(%r1), %r20
++ LDREG ITLB_SID_STRIDE(%r1), %r21
++ LDREG ITLB_SID_COUNT(%r1), %r22
++ LDREG ITLB_OFF_BASE(%r1), %arg0
++ LDREG ITLB_OFF_STRIDE(%r1), %arg1
++ LDREG ITLB_OFF_COUNT(%r1), %arg2
++ LDREG ITLB_LOOP(%r1), %arg3
++
++ ADDIB= -1, %arg3, fitoneloop /* Preadjust and test */
++ movb,<,n %arg3, %r31, fitdone /* If loop < 0, skip */
++ copy %arg0, %r28 /* Init base addr */
++
++fitmanyloop: /* Loop if LOOP >= 2 */
++ mtsp %r20, %sr1
++ add %r21, %r20, %r20 /* increment space */
++ copy %arg2, %r29 /* Init middle loop count */
++
++fitmanymiddle: /* Loop if LOOP >= 2 */
++ ADDIB> -1, %r31, fitmanymiddle /* Adjusted inner loop decr */
++ pitlbe 0(%sr1, %r28)
++ pitlbe,m %arg1(%sr1, %r28) /* Last pitlbe and addr adjust */
++ ADDIB> -1, %r29, fitmanymiddle /* Middle loop decr */
++ copy %arg3, %r31 /* Re-init inner loop count */
++
++ movb,tr %arg0, %r28, fitmanyloop /* Re-init base addr */
++ ADDIB<=,n -1, %r22, fitdone /* Outer loop count decr */
++
++fitoneloop: /* Loop if LOOP = 1 */
++ mtsp %r20, %sr1
++ copy %arg0, %r28 /* init base addr */
++ copy %arg2, %r29 /* init middle loop count */
++
++fitonemiddle: /* Loop if LOOP = 1 */
++ ADDIB> -1, %r29, fitonemiddle /* Middle loop count decr */
++ pitlbe,m %arg1(%sr1, %r28) /* pitlbe for one loop */
+
+- ADDIB> -1,%r22,fitoneloop /* Outer loop count decr */
+- add %r21,%r20,%r20 /* increment space */
++ ADDIB> -1, %r22, fitoneloop /* Outer loop count decr */
++ add %r21, %r20, %r20 /* increment space */
+
+ fitdone:
+
+ /* Flush Data Tlb */
+
+- LDREG DTLB_SID_BASE(%r1),%r20
+- LDREG DTLB_SID_STRIDE(%r1),%r21
+- LDREG DTLB_SID_COUNT(%r1),%r22
+- LDREG DTLB_OFF_BASE(%r1),%arg0
+- LDREG DTLB_OFF_STRIDE(%r1),%arg1
+- LDREG DTLB_OFF_COUNT(%r1),%arg2
+- LDREG DTLB_LOOP(%r1),%arg3
+-
+- ADDIB= -1,%arg3,fdtoneloop /* Preadjust and test */
+- movb,<,n %arg3,%r31,fdtdone /* If loop < 0, skip */
+- copy %arg0,%r28 /* Init base addr */
+-
+-fdtmanyloop: /* Loop if LOOP >= 2 */
+- mtsp %r20,%sr1
+- add %r21,%r20,%r20 /* increment space */
+- copy %arg2,%r29 /* Init middle loop count */
+-
+-fdtmanymiddle: /* Loop if LOOP >= 2 */
+- ADDIB> -1,%r31,fdtmanymiddle /* Adjusted inner loop decr */
+- pdtlbe 0(%sr1,%r28)
+- pdtlbe,m %arg1(%sr1,%r28) /* Last pdtlbe and addr adjust */
+- ADDIB> -1,%r29,fdtmanymiddle /* Middle loop decr */
+- copy %arg3,%r31 /* Re-init inner loop count */
+-
+- movb,tr %arg0,%r28,fdtmanyloop /* Re-init base addr */
+- ADDIB<=,n -1,%r22,fdtdone /* Outer loop count decr */
+-
+-fdtoneloop: /* Loop if LOOP = 1 */
+- mtsp %r20,%sr1
+- copy %arg0,%r28 /* init base addr */
+- copy %arg2,%r29 /* init middle loop count */
+-
+-fdtonemiddle: /* Loop if LOOP = 1 */
+- ADDIB> -1,%r29,fdtonemiddle /* Middle loop count decr */
+- pdtlbe,m %arg1(%sr1,%r28) /* pdtlbe for one loop */
++ LDREG DTLB_SID_BASE(%r1), %r20
++ LDREG DTLB_SID_STRIDE(%r1), %r21
++ LDREG DTLB_SID_COUNT(%r1), %r22
++ LDREG DTLB_OFF_BASE(%r1), %arg0
++ LDREG DTLB_OFF_STRIDE(%r1), %arg1
++ LDREG DTLB_OFF_COUNT(%r1), %arg2
++ LDREG DTLB_LOOP(%r1), %arg3
++
++ ADDIB= -1, %arg3, fdtoneloop /* Preadjust and test */
++ movb,<,n %arg3, %r31, fdtdone /* If loop < 0, skip */
++ copy %arg0, %r28 /* Init base addr */
++
++fdtmanyloop: /* Loop if LOOP >= 2 */
++ mtsp %r20, %sr1
++ add %r21, %r20, %r20 /* increment space */
++ copy %arg2, %r29 /* Init middle loop count */
++
++fdtmanymiddle: /* Loop if LOOP >= 2 */
++ ADDIB> -1, %r31, fdtmanymiddle /* Adjusted inner loop decr */
++ pdtlbe 0(%sr1, %r28)
++ pdtlbe,m %arg1(%sr1, %r28) /* Last pdtlbe and addr adjust */
++ ADDIB> -1, %r29, fdtmanymiddle /* Middle loop decr */
++ copy %arg3, %r31 /* Re-init inner loop count */
++
++ movb,tr %arg0, %r28, fdtmanyloop /* Re-init base addr */
++ ADDIB<=,n -1, %r22,fdtdone /* Outer loop count decr */
++
++fdtoneloop: /* Loop if LOOP = 1 */
++ mtsp %r20, %sr1
++ copy %arg0, %r28 /* init base addr */
++ copy %arg2, %r29 /* init middle loop count */
++
++fdtonemiddle: /* Loop if LOOP = 1 */
++ ADDIB> -1, %r29, fdtonemiddle /* Middle loop count decr */
++ pdtlbe,m %arg1(%sr1, %r28) /* pdtlbe for one loop */
+
+- ADDIB> -1,%r22,fdtoneloop /* Outer loop count decr */
+- add %r21,%r20,%r20 /* increment space */
++ ADDIB> -1, %r22, fdtoneloop /* Outer loop count decr */
++ add %r21, %r20, %r20 /* increment space */
+
+ fdtdone:
+
+ /* Switch back to virtual mode */
+
+- rsm PSW_SM_Q,%r0 /* clear Q bit to load iia queue */
+- ldil L%KERNEL_PSW, %r1
+- ldo R%KERNEL_PSW(%r1), %r1
+- or %r1,%r19,%r1 /* Set I bit if set on entry */
+- mtctl %r1, %cr22
+- mtctl %r0, %cr17 /* Clear IIASQ tail */
+- mtctl %r0, %cr17 /* Clear IIASQ head */
+- ldil L%(2f), %r1
+- ldo R%(2f)(%r1), %r1
+- mtctl %r1, %cr18 /* IIAOQ head */
+- ldo 4(%r1), %r1
+- mtctl %r1, %cr18 /* IIAOQ tail */
++ rsm PSW_SM_Q, %r0 /* clear Q bit to load iia queue */
++ ldil L%KERNEL_PSW, %r1
++ ldo R%KERNEL_PSW(%r1), %r1
++ or %r1, %r19, %r1 /* Set I bit if set on entry */
++ mtctl %r1, %cr22
++ mtctl %r0, %cr17 /* Clear IIASQ tail */
++ mtctl %r0, %cr17 /* Clear IIASQ head */
++ ldil L%(2f), %r1
++ ldo R%(2f)(%r1), %r1
++ mtctl %r1, %cr18 /* IIAOQ head */
++ ldo 4(%r1), %r1
++ mtctl %r1, %cr18 /* IIAOQ tail */
+ rfi
+ nop
+
+-2: bv %r0(%r2)
++2: bv %r0(%r2)
+ nop
+ .exit
+
+@@ -211,140 +211,198 @@
+ .callinfo NO_CALLS
+ .entry
+
+- mtsp %r0,%sr1
+- ldil L%cache_info,%r1
+- ldo R%cache_info(%r1),%r1
++ mtsp %r0, %sr1
++ ldil L%cache_info, %r1
++ ldo R%cache_info(%r1), %r1
+
+ /* Flush Instruction Cache */
+
+- LDREG ICACHE_BASE(%r1),%arg0
+- LDREG ICACHE_STRIDE(%r1),%arg1
+- LDREG ICACHE_COUNT(%r1),%arg2
+- LDREG ICACHE_LOOP(%r1),%arg3
+- rsm PSW_SM_I,%r22 /* No mmgt ops during loop*/
+- ADDIB= -1,%arg3,fioneloop /* Preadjust and test */
+- movb,<,n %arg3,%r31,fisync /* If loop < 0, do sync */
+-
+-fimanyloop: /* Loop if LOOP >= 2 */
+- ADDIB> -1,%r31,fimanyloop /* Adjusted inner loop decr */
+- fice 0(%sr1,%arg0)
+- fice,m %arg1(%sr1,%arg0) /* Last fice and addr adjust */
+- movb,tr %arg3,%r31,fimanyloop /* Re-init inner loop count */
+- ADDIB<=,n -1,%arg2,fisync /* Outer loop decr */
+-
+-fioneloop: /* Loop if LOOP = 1 */
+- ADDIB> -1,%arg2,fioneloop /* Outer loop count decr */
+- fice,m %arg1(%sr1,%arg0) /* Fice for one loop */
++ LDREG ICACHE_BASE(%r1), %arg0
++ LDREG ICACHE_STRIDE(%r1), %arg1
++ LDREG ICACHE_COUNT(%r1), %arg2
++ LDREG ICACHE_LOOP(%r1), %arg3
++ rsm PSW_SM_I, %r22 /* No mmgt ops during loop*/
++ ADDIB= -1, %arg3, fioneloop /* Preadjust and test */
++ movb,<,n %arg3, %r31, fisync /* If loop < 0, do sync */
++
++fimanyloop: /* Loop if LOOP >= 2 */
++ ADDIB> -1, %r31, fimanyloop /* Adjusted inner loop decr */
++ fice 0(%sr1, %arg0)
++ fice,m %arg1(%sr1, %arg0) /* Last fice and addr adjust */
++ movb,tr %arg3, %r31, fimanyloop /* Re-init inner loop count */
++ ADDIB<=,n -1, %arg2, fisync /* Outer loop decr */
++
++fioneloop: /* Loop if LOOP = 1 */
++ ADDIB> -1, %arg2, fioneloop /* Outer loop count decr */
++ fice,m %arg1(%sr1, %arg0) /* Fice for one loop */
+
+ fisync:
+ sync
+- mtsm %r22
+- bv %r0(%r2)
++ mtsm %r22
++ bv %r0(%r2)
+ nop
+ .exit
+
+ .procend
+
+- .export flush_data_cache_local,code
+- .import cache_info,data
++ .export flush_data_cache_local, code
++ .import cache_info, data
+
+ flush_data_cache_local:
+ .proc
+ .callinfo NO_CALLS
+ .entry
+
+- mtsp %r0,%sr1
+- ldil L%cache_info,%r1
+- ldo R%cache_info(%r1),%r1
++ mtsp %r0, %sr1
++ ldil L%cache_info, %r1
++ ldo R%cache_info(%r1), %r1
+
+ /* Flush Data Cache */
+
+- LDREG DCACHE_BASE(%r1),%arg0
+- LDREG DCACHE_STRIDE(%r1),%arg1
+- LDREG DCACHE_COUNT(%r1),%arg2
+- LDREG DCACHE_LOOP(%r1),%arg3
+- rsm PSW_SM_I,%r22
+- ADDIB= -1,%arg3,fdoneloop /* Preadjust and test */
+- movb,<,n %arg3,%r31,fdsync /* If loop < 0, do sync */
+-
+-fdmanyloop: /* Loop if LOOP >= 2 */
+- ADDIB> -1,%r31,fdmanyloop /* Adjusted inner loop decr */
+- fdce 0(%sr1,%arg0)
+- fdce,m %arg1(%sr1,%arg0) /* Last fdce and addr adjust */
+- movb,tr %arg3,%r31,fdmanyloop /* Re-init inner loop count */
+- ADDIB<=,n -1,%arg2,fdsync /* Outer loop decr */
+-
+-fdoneloop: /* Loop if LOOP = 1 */
+- ADDIB> -1,%arg2,fdoneloop /* Outer loop count decr */
+- fdce,m %arg1(%sr1,%arg0) /* Fdce for one loop */
++ LDREG DCACHE_BASE(%r1), %arg0
++ LDREG DCACHE_STRIDE(%r1), %arg1
++ LDREG DCACHE_COUNT(%r1), %arg2
++ LDREG DCACHE_LOOP(%r1), %arg3
++ rsm PSW_SM_I, %r22
++ ADDIB= -1, %arg3, fdoneloop /* Preadjust and test */
++ movb,<,n %arg3, %r31, fdsync /* If loop < 0, do sync */
++
++fdmanyloop: /* Loop if LOOP >= 2 */
++ ADDIB> -1, %r31, fdmanyloop /* Adjusted inner loop decr */
++ fdce 0(%sr1, %arg0)
++ fdce,m %arg1(%sr1, %arg0) /* Last fdce and addr adjust */
++ movb,tr %arg3, %r31, fdmanyloop /* Re-init inner loop count */
++ ADDIB<=,n -1, %arg2, fdsync /* Outer loop decr */
++
++fdoneloop: /* Loop if LOOP = 1 */
++ ADDIB> -1, %arg2, fdoneloop /* Outer loop count decr */
++ fdce,m %arg1(%sr1, %arg0) /* Fdce for one loop */
+
+ fdsync:
+ syncdma
+ sync
+- mtsm %r22
+- bv %r0(%r2)
++ mtsm %r22
++ bv %r0(%r2)
+ nop
+ .exit
+
+ .procend
+
+ .export copy_user_page_asm,code
++ .align 16
+
+ copy_user_page_asm:
+ .proc
+ .callinfo NO_CALLS
+ .entry
+
+- ldi 64,%r1
++#ifdef __LP64__
++ /* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
++ * Unroll the loop by hand and arrange insn appropriately.
++ * GCC probably can do this just as well.
++ */
++
++ ldd 0(%r25), %r19
++ ldi 32, %r1 /* PAGE_SIZE/128 == 32 */
++ ldw 64(%r25), %r0 /* prefetch 1 cacheline ahead */
++ ldw 128(%r25), %r0 /* prefetch 2 */
++
++1: ldd 8(%r25), %r20
++ ldw 192(%r25), %r0 /* prefetch 3 */
++ ldw 256(%r25), %r0 /* prefetch 4 */
++
++ ldd 16(%r25), %r21
++ ldd 24(%r25), %r22
++ std %r19, 0(%r26)
++ std %r20, 8(%r26)
++
++ ldd 32(%r25), %r19
++ ldd 40(%r25), %r20
++ std %r21, 16(%r26)
++ std %r22, 24(%r26)
++
++ ldd 48(%r25), %r21
++ ldd 56(%r25), %r22
++ std %r19, 32(%r26)
++ std %r20, 40(%r26)
++
++ ldd 64(%r25), %r19
++ ldd 72(%r25), %r20
++ std %r21, 48(%r26)
++ std %r22, 56(%r26)
++
++ ldd 80(%r25), %r21
++ ldd 88(%r25), %r22
++ std %r19, 64(%r26)
++ std %r20, 72(%r26)
++
++ ldd 96(%r25), %r19
++ ldd 104(%r25), %r20
++ std %r21, 80(%r26)
++ std %r22, 88(%r26)
++
++ ldd 112(%r25), %r21
++ ldd 120(%r25), %r22
++ std %r19, 96(%r26)
++ std %r20, 104(%r26)
++
++ ldo 128(%r25), %r25
++ std %r21, 112(%r26)
++ std %r22, 120(%r26)
++ ldo 128(%r26), %r26
++
++ ADDIB> -1, %r1, 1b /* bundle 10 */
++ ldd 0(%r25), %r19 /* start next loads */
++
++#else
+
+ /*
+ * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
+- * bundles (very restricted rules for bundling). It probably
+- * does OK on PCXU and better, but we could do better with
+- * ldd/std instructions. Note that until (if) we start saving
++ * bundles (very restricted rules for bundling).
++ * Note that until (if) we start saving
+ * the full 64 bit register values on interrupt, we can't
+ * use ldd/std on a 32 bit kernel.
+ */
+-
++ ldi 64, %r1 /* PAGE_SIZE/64 == 64 */
+
+ 1:
+- ldw 0(%r25),%r19
+- ldw 4(%r25),%r20
+- ldw 8(%r25),%r21
+- ldw 12(%r25),%r22
+- stw %r19,0(%r26)
+- stw %r20,4(%r26)
+- stw %r21,8(%r26)
+- stw %r22,12(%r26)
+- ldw 16(%r25),%r19
+- ldw 20(%r25),%r20
+- ldw 24(%r25),%r21
+- ldw 28(%r25),%r22
+- stw %r19,16(%r26)
+- stw %r20,20(%r26)
+- stw %r21,24(%r26)
+- stw %r22,28(%r26)
+- ldw 32(%r25),%r19
+- ldw 36(%r25),%r20
+- ldw 40(%r25),%r21
+- ldw 44(%r25),%r22
+- stw %r19,32(%r26)
+- stw %r20,36(%r26)
+- stw %r21,40(%r26)
+- stw %r22,44(%r26)
+- ldw 48(%r25),%r19
+- ldw 52(%r25),%r20
+- ldw 56(%r25),%r21
+- ldw 60(%r25),%r22
+- stw %r19,48(%r26)
+- stw %r20,52(%r26)
+- stw %r21,56(%r26)
+- stw %r22,60(%r26)
+- ldo 64(%r26),%r26
+- ADDIB> -1,%r1,1b
+- ldo 64(%r25),%r25
+-
+- bv %r0(%r2)
++ ldw 0(%r25), %r19
++ ldw 4(%r25), %r20
++ ldw 8(%r25), %r21
++ ldw 12(%r25), %r22
++ stw %r19, 0(%r26)
++ stw %r20, 4(%r26)
++ stw %r21, 8(%r26)
++ stw %r22, 12(%r26)
++ ldw 16(%r25), %r19
++ ldw 20(%r25), %r20
++ ldw 24(%r25), %r21
++ ldw 28(%r25), %r22
++ stw %r19, 16(%r26)
++ stw %r20, 20(%r26)
++ stw %r21, 24(%r26)
++ stw %r22, 28(%r26)
++ ldw 32(%r25), %r19
++ ldw 36(%r25), %r20
++ ldw 40(%r25), %r21
++ ldw 44(%r25), %r22
++ stw %r19, 32(%r26)
++ stw %r20, 36(%r26)
++ stw %r21, 40(%r26)
++ stw %r22, 44(%r26)
++ ldw 48(%r25), %r19
++ ldw 52(%r25), %r20
++ ldw 56(%r25), %r21
++ ldw 60(%r25), %r22
++ stw %r19, 48(%r26)
++ stw %r20, 52(%r26)
++ stw %r21, 56(%r26)
++ stw %r22, 60(%r26)
++ ldo 64(%r26), %r26
++ ADDIB> -1, %r1, 1b
++ ldo 64(%r25), %r25
++#endif
++ bv %r0(%r2)
+ nop
+ .exit
+
+@@ -393,33 +451,33 @@
+ .callinfo NO_CALLS
+ .entry
+
+- ldil L%(__PAGE_OFFSET),%r1
+- sub %r26,%r1,%r26
+- sub %r25,%r1,%r23 /* move physical addr into non shadowed reg */
+-
+- ldil L%(TMPALIAS_MAP_START),%r28
+-#ifdef __LP64__
+- extrd,u %r26,56,32,%r26 /* convert phys addr to tlb insert format */
+- extrd,u %r23,56,32,%r23 /* convert phys addr to tlb insert format */
+- depd %r24,63,22,%r28 /* Form aliased virtual address 'to' */
+- depdi 0,63,12,%r28 /* Clear any offset bits */
+- copy %r28,%r29
+- depdi 1,41,1,%r29 /* Form aliased virtual address 'from' */
+-#else
+- extrw,u %r26,24,25,%r26 /* convert phys addr to tlb insert format */
+- extrw,u %r23,24,25,%r23 /* convert phys addr to tlb insert format */
+- depw %r24,31,22,%r28 /* Form aliased virtual address 'to' */
+- depwi 0,31,12,%r28 /* Clear any offset bits */
+- copy %r28,%r29
+- depwi 1,9,1,%r29 /* Form aliased virtual address 'from' */
++ ldil L%(__PAGE_OFFSET), %r1
++ sub %r26, %r1, %r26
++ sub %r25, %r1, %r23 /* move physical addr into non shadowed reg */
++
++ ldil L%(TMPALIAS_MAP_START), %r28
++#ifdef __LP64__
++ extrd,u %r26,56,32, %r26 /* convert phys addr to tlb insert format */
++ extrd,u %r23,56,32, %r23 /* convert phys addr to tlb insert format */
++ depd %r24,63,22, %r28 /* Form aliased virtual address 'to' */
++ depdi 0, 63,12, %r28 /* Clear any offset bits */
++ copy %r28, %r29
++ depdi 1, 41,1, %r29 /* Form aliased virtual address 'from' */
++#else
++ extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
++ extrw,u %r23, 24,25, %r23 /* convert phys addr to tlb insert format */
++ depw %r24, 31,22, %r28 /* Form aliased virtual address 'to' */
++ depwi 0, 31,12, %r28 /* Clear any offset bits */
++ copy %r28, %r29
++ depwi 1, 9,1, %r29 /* Form aliased virtual address 'from' */
+ #endif
+
+ /* Purge any old translations */
+
+- pdtlb 0(%r28)
+- pdtlb 0(%r29)
++ pdtlb 0(%r28)
++ pdtlb 0(%r29)
+
+- ldi 64,%r1
++ ldi 64, %r1
+
+ /*
+ * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
+@@ -432,43 +490,43 @@
+
+
+ 1:
+- ldw 0(%r29),%r19
+- ldw 4(%r29),%r20
+- ldw 8(%r29),%r21
+- ldw 12(%r29),%r22
+- stw %r19,0(%r28)
+- stw %r20,4(%r28)
+- stw %r21,8(%r28)
+- stw %r22,12(%r28)
+- ldw 16(%r29),%r19
+- ldw 20(%r29),%r20
+- ldw 24(%r29),%r21
+- ldw 28(%r29),%r22
+- stw %r19,16(%r28)
+- stw %r20,20(%r28)
+- stw %r21,24(%r28)
+- stw %r22,28(%r28)
+- ldw 32(%r29),%r19
+- ldw 36(%r29),%r20
+- ldw 40(%r29),%r21
+- ldw 44(%r29),%r22
+- stw %r19,32(%r28)
+- stw %r20,36(%r28)
+- stw %r21,40(%r28)
+- stw %r22,44(%r28)
+- ldw 48(%r29),%r19
+- ldw 52(%r29),%r20
+- ldw 56(%r29),%r21
+- ldw 60(%r29),%r22
+- stw %r19,48(%r28)
+- stw %r20,52(%r28)
+- stw %r21,56(%r28)
+- stw %r22,60(%r28)
+- ldo 64(%r28),%r28
+- ADDIB> -1,%r1,1b
+- ldo 64(%r29),%r29
++ ldw 0(%r29), %r19
++ ldw 4(%r29), %r20
++ ldw 8(%r29), %r21
++ ldw 12(%r29), %r22
++ stw %r19, 0(%r28)
++ stw %r20, 4(%r28)
++ stw %r21, 8(%r28)
++ stw %r22, 12(%r28)
++ ldw 16(%r29), %r19
++ ldw 20(%r29), %r20
++ ldw 24(%r29), %r21
++ ldw 28(%r29), %r22
++ stw %r19, 16(%r28)
++ stw %r20, 20(%r28)
++ stw %r21, 24(%r28)
++ stw %r22, 28(%r28)
++ ldw 32(%r29), %r19
++ ldw 36(%r29), %r20
++ ldw 40(%r29), %r21
++ ldw 44(%r29), %r22
++ stw %r19, 32(%r28)
++ stw %r20, 36(%r28)
++ stw %r21, 40(%r28)
++ stw %r22, 44(%r28)
++ ldw 48(%r29), %r19
++ ldw 52(%r29), %r20
++ ldw 56(%r29), %r21
++ ldw 60(%r29), %r22
++ stw %r19, 48(%r28)
++ stw %r20, 52(%r28)
++ stw %r21, 56(%r28)
++ stw %r22, 60(%r28)
++ ldo 64(%r28), %r28
++ ADDIB> -1, %r1,1b
++ ldo 64(%r29), %r29
+
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+ .exit
+
+@@ -482,49 +540,77 @@
+ .callinfo NO_CALLS
+ .entry
+
+- tophys_r1 %r26
++ tophys_r1 %r26
+
+- ldil L%(TMPALIAS_MAP_START),%r28
++ ldil L%(TMPALIAS_MAP_START), %r28
+ #ifdef __LP64__
+ #if (TMPALIAS_MAP_START >= 0x80000000)
+- depdi 0,31,32,%r28 /* clear any sign extension */
++ depdi 0, 31,32, %r28 /* clear any sign extension */
+ #endif
+- extrd,u %r26,56,32,%r26 /* convert phys addr to tlb insert format */
+- depd %r25,63,22,%r28 /* Form aliased virtual address 'to' */
+- depdi 0,63,12,%r28 /* Clear any offset bits */
+-#else
+- extrw,u %r26,24,25,%r26 /* convert phys addr to tlb insert format */
+- depw %r25,31,22,%r28 /* Form aliased virtual address 'to' */
+- depwi 0,31,12,%r28 /* Clear any offset bits */
++ extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */
++ depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
++ depdi 0, 63,12, %r28 /* Clear any offset bits */
++#else
++ extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
++ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
++ depwi 0, 31,12, %r28 /* Clear any offset bits */
+ #endif
+
+ /* Purge any old translation */
+
+- pdtlb 0(%r28)
++ pdtlb 0(%r28)
+
+- ldi 64,%r1
++#ifdef __LP64__
++ ldi 32, %r1 /* PAGE_SIZE/128 == 32 */
++
++ /* PREFETCH (Write) has not (yet) been proven to help here */
++/* #define PREFETCHW_OP ldd 256(%0), %r0 */
++
++1: std %r0, 0(%r28)
++ std %r0, 8(%r28)
++ std %r0, 16(%r28)
++ std %r0, 24(%r28)
++ std %r0, 32(%r28)
++ std %r0, 40(%r28)
++ std %r0, 48(%r28)
++ std %r0, 56(%r28)
++ std %r0, 64(%r28)
++ std %r0, 72(%r28)
++ std %r0, 80(%r28)
++ std %r0, 88(%r28)
++ std %r0, 96(%r28)
++ std %r0, 104(%r28)
++ std %r0, 112(%r28)
++ std %r0, 120(%r28)
++ ADDIB> -1, %r1, 1b
++ ldo 128(%r28), %r28
++
++#else /* ! __LP64 */
++
++ ldi 64, %r1 /* PAGE_SIZE/64 == 64 */
+
+ 1:
+- stw %r0,0(%r28)
+- stw %r0,4(%r28)
+- stw %r0,8(%r28)
+- stw %r0,12(%r28)
+- stw %r0,16(%r28)
+- stw %r0,20(%r28)
+- stw %r0,24(%r28)
+- stw %r0,28(%r28)
+- stw %r0,32(%r28)
+- stw %r0,36(%r28)
+- stw %r0,40(%r28)
+- stw %r0,44(%r28)
+- stw %r0,48(%r28)
+- stw %r0,52(%r28)
+- stw %r0,56(%r28)
+- stw %r0,60(%r28)
+- ADDIB> -1,%r1,1b
+- ldo 64(%r28),%r28
++ stw %r0, 0(%r28)
++ stw %r0, 4(%r28)
++ stw %r0, 8(%r28)
++ stw %r0, 12(%r28)
++ stw %r0, 16(%r28)
++ stw %r0, 20(%r28)
++ stw %r0, 24(%r28)
++ stw %r0, 28(%r28)
++ stw %r0, 32(%r28)
++ stw %r0, 36(%r28)
++ stw %r0, 40(%r28)
++ stw %r0, 44(%r28)
++ stw %r0, 48(%r28)
++ stw %r0, 52(%r28)
++ stw %r0, 56(%r28)
++ stw %r0, 60(%r28)
++ ADDIB> -1, %r1, 1b
++ ldo 64(%r28), %r28
++#endif /* __LP64 */
+
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+ .exit
+
+@@ -537,38 +623,38 @@
+ .callinfo NO_CALLS
+ .entry
+
+- ldil L%dcache_stride,%r1
+- ldw R%dcache_stride(%r1),%r23
++ ldil L%dcache_stride, %r1
++ ldw R%dcache_stride(%r1), %r23
+
+ #ifdef __LP64__
+- depdi,z 1,63-PAGE_SHIFT,1,%r25
++ depdi,z 1, 63-PAGE_SHIFT,1, %r25
+ #else
+- depwi,z 1,31-PAGE_SHIFT,1,%r25
++ depwi,z 1, 31-PAGE_SHIFT,1, %r25
+ #endif
+- add %r26,%r25,%r25
+- sub %r25,%r23,%r25
+-
+-
+-1: fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- fdc,m %r23(%r26)
+- CMPB<< %r26,%r25,1b
+- fdc,m %r23(%r26)
++ add %r26, %r25, %r25
++ sub %r25, %r23, %r25
++
++
++1: fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ fdc,m %r23(%r26)
++ CMPB<< %r26, %r25,1b
++ fdc,m %r23(%r26)
+
+ sync
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+ .exit
+
+@@ -581,38 +667,38 @@
+ .callinfo NO_CALLS
+ .entry
+
+- ldil L%dcache_stride,%r1
+- ldw R%dcache_stride(%r1),%r23
++ ldil L%dcache_stride, %r1
++ ldw R%dcache_stride(%r1), %r23
+
+ #ifdef __LP64__
+- depdi,z 1,63-PAGE_SHIFT,1,%r25
++ depdi,z 1,63-PAGE_SHIFT,1, %r25
+ #else
+- depwi,z 1,31-PAGE_SHIFT,1,%r25
++ depwi,z 1,31-PAGE_SHIFT,1, %r25
+ #endif
+- add %r26,%r25,%r25
+- sub %r25,%r23,%r25
+-
+-
+-1: fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- fdc,m %r23(%sr3,%r26)
+- CMPB<< %r26,%r25,1b
+- fdc,m %r23(%sr3,%r26)
++ add %r26, %r25, %r25
++ sub %r25, %r23, %r25
++
++
++1: fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ fdc,m %r23(%sr3, %r26)
++ CMPB<< %r26, %r25,1b
++ fdc,m %r23(%sr3, %r26)
+
+ sync
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+ .exit
+
+@@ -625,38 +711,38 @@
+ .callinfo NO_CALLS
+ .entry
+
+- ldil L%dcache_stride,%r1
+- ldw R%dcache_stride(%r1),%r23
++ ldil L%dcache_stride, %r1
++ ldw R%dcache_stride(%r1), %r23
+
+ #ifdef __LP64__
+- depdi,z 1,63-PAGE_SHIFT,1,%r25
++ depdi,z 1, 63-PAGE_SHIFT,1, %r25
+ #else
+- depwi,z 1,31-PAGE_SHIFT,1,%r25
++ depwi,z 1, 31-PAGE_SHIFT,1, %r25
+ #endif
+- add %r26,%r25,%r25
+- sub %r25,%r23,%r25
+-
+-
+-1: fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- fic,m %r23(%sr3,%r26)
+- CMPB<< %r26,%r25,1b
+- fic,m %r23(%sr3,%r26)
++ add %r26, %r25, %r25
++ sub %r25, %r23, %r25
++
++
++1: fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ fic,m %r23(%sr3, %r26)
++ CMPB<< %r26, %r25,1b
++ fic,m %r23(%sr3, %r26)
+
+ sync
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+ .exit
+
+@@ -670,37 +756,37 @@
+ .callinfo NO_CALLS
+ .entry
+
+- ldil L%dcache_stride,%r1
+- ldw R%dcache_stride(%r1),%r23
++ ldil L%dcache_stride, %r1
++ ldw R%dcache_stride(%r1), %r23
+
+ #ifdef __LP64__
+- depdi,z 1,63-PAGE_SHIFT,1,%r25
++ depdi,z 1, 63-PAGE_SHIFT,1, %r25
+ #else
+- depwi,z 1,31-PAGE_SHIFT,1,%r25
++ depwi,z 1, 31-PAGE_SHIFT,1, %r25
+ #endif
+- add %r26,%r25,%r25
+- sub %r25,%r23,%r25
+-
+-1: pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- pdc,m %r23(%r26)
+- CMPB<< %r26,%r25,1b
+- pdc,m %r23(%r26)
++ add %r26, %r25, %r25
++ sub %r25, %r23, %r25
++
++1: pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ pdc,m %r23(%r26)
++ CMPB<< %r26, %r25, 1b
++ pdc,m %r23(%r26)
+
+ sync
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+ .exit
+
+@@ -718,54 +804,54 @@
+ .callinfo NO_CALLS
+ .entry
+
+- tophys_r1 %r26
++ tophys_r1 %r26
+
+- ldil L%(TMPALIAS_MAP_START),%r28
++ ldil L%(TMPALIAS_MAP_START), %r28
+ #ifdef __LP64__
+- extrd,u %r26,56,32,%r26 /* convert phys addr to tlb insert format */
+- depd %r25,63,22,%r28 /* Form aliased virtual address 'to' */
+- depdi 0,63,12,%r28 /* Clear any offset bits */
++ extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */
++ depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
++ depdi 0, 63,12, %r28 /* Clear any offset bits */
+ #else
+- extrw,u %r26,24,25,%r26 /* convert phys addr to tlb insert format */
+- depw %r25,31,22,%r28 /* Form aliased virtual address 'to' */
+- depwi 0,31,12,%r28 /* Clear any offset bits */
++ extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
++ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
++ depwi 0, 31,12, %r28 /* Clear any offset bits */
+ #endif
+
+ /* Purge any old translation */
+
+- pdtlb 0(%r28)
++ pdtlb 0(%r28)
+
+- ldil L%dcache_stride,%r1
+- ldw R%dcache_stride(%r1),%r23
++ ldil L%dcache_stride, %r1
++ ldw R%dcache_stride(%r1), %r23
+
+ #ifdef __LP64__
+- depdi,z 1,63-PAGE_SHIFT,1,%r29
++ depdi,z 1, 63-PAGE_SHIFT,1, %r29
+ #else
+- depwi,z 1,31-PAGE_SHIFT,1,%r29
+-#endif
+- add %r28,%r29,%r29
+- sub %r29,%r23,%r29
+-
+-1: fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- fdc,m %r23(%r28)
+- CMPB<< %r28,%r29,1b
+- fdc,m %r23(%r28)
++ depwi,z 1, 31-PAGE_SHIFT,1, %r29
++#endif
++ add %r28, %r29, %r29
++ sub %r29, %r23, %r29
++
++1: fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ fdc,m %r23(%r28)
++ CMPB<< %r28, %r29, 1b
++ fdc,m %r23(%r28)
+
+ sync
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+ .exit
+
+@@ -779,16 +865,16 @@
+ .callinfo NO_CALLS
+ .entry
+
+- ldil L%dcache_stride,%r1
+- ldw R%dcache_stride(%r1),%r23
+- ldo -1(%r23),%r21
+- ANDCM %r26,%r21,%r26
++ ldil L%dcache_stride, %r1
++ ldw R%dcache_stride(%r1), %r23
++ ldo -1(%r23), %r21
++ ANDCM %r26, %r21, %r26
+
+-1: CMPB<<,n %r26,%r25,1b
+- fdc,m %r23(%sr3,%r26)
++1: CMPB<<,n %r26, %r25, 1b
++ fdc,m %r23(%sr3, %r26)
+
+ sync
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+ .exit
+
+@@ -801,17 +887,17 @@
+ .callinfo NO_CALLS
+ .entry
+
+- ldil L%dcache_stride,%r1
+- ldw R%dcache_stride(%r1),%r23
+- ldo -1(%r23),%r21
+- ANDCM %r26,%r21,%r26
++ ldil L%dcache_stride, %r1
++ ldw R%dcache_stride(%r1), %r23
++ ldo -1(%r23), %r21
++ ANDCM %r26, %r21, %r26
+
+-1: CMPB<<,n %r26,%r25,1b
+- fdc,m %r23(%r26)
++1: CMPB<<,n %r26, %r25,1b
++ fdc,m %r23(%r26)
+
+ sync
+ syncdma
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+ .exit
+
+@@ -824,16 +910,16 @@
+ .callinfo NO_CALLS
+ .entry
+
+- ldil L%icache_stride,%r1
+- ldw R%icache_stride(%r1),%r23
+- ldo -1(%r23),%r21
+- ANDCM %r26,%r21,%r26
++ ldil L%icache_stride, %r1
++ ldw R%icache_stride(%r1), %r23
++ ldo -1(%r23), %r21
++ ANDCM %r26, %r21, %r26
+
+-1: CMPB<<,n %r26,%r25,1b
+- fic,m %r23(%sr3,%r26)
++1: CMPB<<,n %r26, %r25,1b
++ fic,m %r23(%sr3, %r26)
+
+ sync
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+ .exit
+
+@@ -846,38 +932,38 @@
+ .callinfo NO_CALLS
+ .entry
+
+- ldil L%icache_stride,%r1
+- ldw R%icache_stride(%r1),%r23
++ ldil L%icache_stride, %r1
++ ldw R%icache_stride(%r1), %r23
+
+ #ifdef __LP64__
+- depdi,z 1,63-PAGE_SHIFT,1,%r25
++ depdi,z 1, 63-PAGE_SHIFT,1, %r25
+ #else
+- depwi,z 1,31-PAGE_SHIFT,1,%r25
++ depwi,z 1, 31-PAGE_SHIFT,1, %r25
+ #endif
+- add %r26,%r25,%r25
+- sub %r25,%r23,%r25
+-
+-
+-1: fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- fic,m %r23(%r26)
+- CMPB<< %r26,%r25,1b
+- fic,m %r23(%r26)
++ add %r26, %r25, %r25
++ sub %r25, %r23, %r25
++
++
++1: fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ fic,m %r23(%r26)
++ CMPB<< %r26, %r25, 1b
++ fic,m %r23(%r26)
+
+ sync
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+ .exit
+
+@@ -890,22 +976,22 @@
+ .callinfo NO_CALLS
+ .entry
+
+- ldil L%icache_stride,%r1
+- ldw R%icache_stride(%r1),%r23
+- ldo -1(%r23),%r21
+- ANDCM %r26,%r21,%r26
++ ldil L%icache_stride, %r1
++ ldw R%icache_stride(%r1), %r23
++ ldo -1(%r23), %r21
++ ANDCM %r26, %r21, %r26
+
+-1: CMPB<<,n %r26,%r25,1b
+- fic,m %r23(%r26)
++1: CMPB<<,n %r26, %r25, 1b
++ fic,m %r23(%r26)
+
+ sync
+- bv %r0(%r2)
++ bv %r0(%r2)
+ nop
+ .exit
+
+ .procend
+
+- .align 128
++ .align 128
+
+ .export disable_sr_hashing_asm,code
+
+@@ -916,7 +1002,7 @@
+
+ /* Switch to real mode */
+
+- ssm 0,%r0 /* relied upon translation! */
++ ssm 0, %r0 /* relied upon translation! */
+ nop
+ nop
+ nop
+@@ -925,73 +1011,73 @@
+ nop
+ nop
+
+- rsm (PSW_SM_Q|PSW_SM_I),%r0 /* disable Q&I to load the iia queue */
+- ldil L%REAL_MODE_PSW, %r1
+- ldo R%REAL_MODE_PSW(%r1), %r1
+- mtctl %r1, %cr22
+- mtctl %r0, %cr17 /* Clear IIASQ tail */
+- mtctl %r0, %cr17 /* Clear IIASQ head */
+- ldil L%PA(1f),%r1
+- ldo R%PA(1f)(%r1),%r1
+- mtctl %r1, %cr18 /* IIAOQ head */
+- ldo 4(%r1), %r1
+- mtctl %r1, %cr18 /* IIAOQ tail */
++ rsm (PSW_SM_Q|PSW_SM_I), %r0 /* disable Q&I to load the iia queue */
++ ldil L%REAL_MODE_PSW, %r1
++ ldo R%REAL_MODE_PSW(%r1), %r1
++ mtctl %r1, %cr22
++ mtctl %r0, %cr17 /* Clear IIASQ tail */
++ mtctl %r0, %cr17 /* Clear IIASQ head */
++ ldil L%PA(1f), %r1
++ ldo R%PA(1f)(%r1), %r1
++ mtctl %r1, %cr18 /* IIAOQ head */
++ ldo 4(%r1), %r1
++ mtctl %r1, %cr18 /* IIAOQ tail */
+ rfi
+ nop
+
+-1: cmpib,=,n SRHASH_PCXST,%r26,srdis_pcxs
+- cmpib,=,n SRHASH_PCXL,%r26,srdis_pcxl
+- cmpib,=,n SRHASH_PA20,%r26,srdis_pa20
+- b,n srdis_done
++1: cmpib,=,n SRHASH_PCXST, %r26,srdis_pcxs
++ cmpib,=,n SRHASH_PCXL, %r26,srdis_pcxl
++ cmpib,=,n SRHASH_PA20, %r26,srdis_pa20
++ b,n srdis_done
+
+ srdis_pcxs:
+
+ /* Disable Space Register Hashing for PCXS,PCXT,PCXT' */
+
+- .word 0x141c1a00 /* mfdiag %dr0,%r28 */
+- .word 0x141c1a00 /* must issue twice */
+- depwi 0,18,1,%r28 /* Clear DHE (dcache hash enable) */
+- depwi 0,20,1,%r28 /* Clear IHE (icache hash enable) */
+- .word 0x141c1600 /* mtdiag %r28,%dr0 */
+- .word 0x141c1600 /* must issue twice */
+- b,n srdis_done
++ .word 0x141c1a00 /* mfdiag %dr0, %r28 */
++ .word 0x141c1a00 /* must issue twice */
++ depwi 0,18,1, %r28 /* Clear DHE (dcache hash enable) */
++ depwi 0,20,1, %r28 /* Clear IHE (icache hash enable) */
++ .word 0x141c1600 /* mtdiag %r28, %dr0 */
++ .word 0x141c1600 /* must issue twice */
++ b,n srdis_done
+
+ srdis_pcxl:
+
+ /* Disable Space Register Hashing for PCXL */
+
+- .word 0x141c0600 /* mfdiag %dr0,%r28 */
+- depwi 0,28,2,%r28 /* Clear DHASH_EN & IHASH_EN */
+- .word 0x141c0240 /* mtdiag %r28,%dr0 */
+- b,n srdis_done
++ .word 0x141c0600 /* mfdiag %dr0, %r28 */
++ depwi 0,28,2, %r28 /* Clear DHASH_EN & IHASH_EN */
++ .word 0x141c0240 /* mtdiag %r28, %dr0 */
++ b,n srdis_done
+
+ srdis_pa20:
+
+ /* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+ */
+
+- .word 0x144008bc /* mfdiag %dr2,%r28 */
+- depdi 0,54,1,%r28 /* clear DIAG_SPHASH_ENAB (bit 54) */
+- .word 0x145c1840 /* mtdiag %r28,%dr2 */
++ .word 0x144008bc /* mfdiag %dr2, %r28 */
++ depdi 0, 54,1, %r28 /* clear DIAG_SPHASH_ENAB (bit 54) */
++ .word 0x145c1840 /* mtdiag %r28, %dr2 */
+
+ srdis_done:
+
+ /* Switch back to virtual mode */
+
+- rsm PSW_SM_Q,%r0 /* clear Q bit to load iia queue */
+- ldil L%KERNEL_PSW, %r1
+- ldo R%KERNEL_PSW(%r1), %r1
+- mtctl %r1, %cr22
+- mtctl %r0, %cr17 /* Clear IIASQ tail */
+- mtctl %r0, %cr17 /* Clear IIASQ head */
+- ldil L%(2f), %r1
+- ldo R%(2f)(%r1), %r1
+- mtctl %r1, %cr18 /* IIAOQ head */
+- ldo 4(%r1), %r1
+- mtctl %r1, %cr18 /* IIAOQ tail */
++ rsm PSW_SM_Q, %r0 /* clear Q bit to load iia queue */
++ ldil L%KERNEL_PSW, %r1
++ ldo R%KERNEL_PSW(%r1), %r1
++ mtctl %r1, %cr22
++ mtctl %r0, %cr17 /* Clear IIASQ tail */
++ mtctl %r0, %cr17 /* Clear IIASQ head */
++ ldil L%(2f), %r1
++ ldo R%(2f)(%r1), %r1
++ mtctl %r1, %cr18 /* IIAOQ head */
++ ldo 4(%r1), %r1
++ mtctl %r1, %cr18 /* IIAOQ tail */
+ rfi
+ nop
+
+-2: bv %r0(%r2)
++2: bv %r0(%r2)
+ nop
+ .exit
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/pci-dma.c CVS2_6_11_PA2/arch/parisc/kernel/pci-dma.c
+--- LINUS_2_6_11/arch/parisc/kernel/pci-dma.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/pci-dma.c 2004-11-17 15:17:42.000000000 -0700
+@@ -32,18 +32,6 @@
+ #include <asm/pgalloc.h>
+ #include <asm/uaccess.h>
+
+-#ifdef DEBUG_PCI
+-#undef ASSERT
+-#define ASSERT(expr) \
+- if(!(expr)) { \
+- printk("\n%s:%d: Assertion " #expr " failed!\n", \
+- __FILE__, __LINE__); \
+- panic(#expr); \
+- }
+-#else
+-#define ASSERT(expr)
+-#endif
+-
+
+ static struct proc_dir_entry * proc_gsc_root = NULL;
+ static int pcxl_proc_info(char *buffer, char **start, off_t offset, int length);
+@@ -259,10 +247,6 @@
+ u_long mask, flags;
+ unsigned int pages_needed = size >> PAGE_SHIFT;
+
+- ASSERT(pages_needed);
+- ASSERT((pages_needed * PAGE_SIZE) < DMA_CHUNK_SIZE);
+- ASSERT(pages_needed < (BITS_PER_LONG - PAGE_SHIFT));
+-
+ mask = (u_long) -1L;
+ mask >>= BITS_PER_LONG - pages_needed;
+
+@@ -306,7 +290,7 @@
+
+ #define PCXL_FREE_MAPPINGS(idx, m, size) \
+ u##size *res_ptr = (u##size *)&(pcxl_res_map[(idx) + (((size >> 3) - 1) & (~((size >> 3) - 1)))]); \
+- ASSERT((*res_ptr & m) == m); \
++ /* BUG_ON((*res_ptr & m) != m); */ \
+ *res_ptr &= ~m;
+
+ /*
+@@ -319,10 +303,6 @@
+ unsigned int res_idx = (vaddr - pcxl_dma_start) >> (PAGE_SHIFT + 3);
+ unsigned int pages_mapped = size >> PAGE_SHIFT;
+
+- ASSERT(pages_mapped);
+- ASSERT((pages_mapped * PAGE_SIZE) < DMA_CHUNK_SIZE);
+- ASSERT(pages_mapped < (BITS_PER_LONG - PAGE_SHIFT));
+-
+ mask = (u_long) -1L;
+ mask >>= BITS_PER_LONG - pages_mapped;
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/pci.c CVS2_6_11_PA2/arch/parisc/kernel/pci.c
+--- LINUS_2_6_11/arch/parisc/kernel/pci.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/pci.c 2004-11-02 17:57:49.000000000 -0700
+@@ -202,7 +202,8 @@
+ pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
+ {
+ if (!r->parent) {
+- printk(KERN_EMERG "PCI: Tell willy he's wrong\n");
++ printk(KERN_EMERG "PCI: resource not parented! [%lx-%lx]\n",
++ r->start, r->end);
+ r->parent = hba_res;
+
+ /* reverse link is harder *sigh* */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/pdc_chassis.c CVS2_6_11_PA2/arch/parisc/kernel/pdc_chassis.c
+--- LINUS_2_6_11/arch/parisc/kernel/pdc_chassis.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/pdc_chassis.c 2005-02-04 12:34:34.000000000 -0700
+@@ -2,7 +2,7 @@
+ * interfaces to log Chassis Codes via PDC (firmware)
+ *
+ * Copyright (C) 2002 Laurent Canet <canetl at esiee.fr>
+- * Copyright (C) 2002-2004 Thibaut VARENE <varenet at esiee.fr>
++ * Copyright (C) 2002-2004 Thibaut VARENE <varenet at parisc-linux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -182,7 +182,7 @@
+
+ DPRINTK(KERN_DEBUG "%s: pdc_chassis_send_status(%d)\n", __FILE__, message);
+
+-#ifdef CONFIG_PARISC64
++#ifdef CONFIG_64BIT
+ if (is_pdc_pat()) {
+ switch(message) {
+ case PDC_CHASSIS_DIRECT_BSTART:
+@@ -238,7 +238,7 @@
+ retval = -1;
+ }
+ } else retval = -1;
+-#endif /* CONFIG_PARISC64 */
++#endif /* CONFIG_64BIT */
+ } /* if (pdc_chassis_enabled) */
+ #endif /* CONFIG_PDC_CHASSIS */
+ return retval;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/perf.c CVS2_6_11_PA2/arch/parisc/kernel/perf.c
+--- LINUS_2_6_11/arch/parisc/kernel/perf.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/perf.c 2005-03-01 23:47:36.000000000 -0700
+@@ -42,7 +42,6 @@
+ * on every box.
+ */
+
+-#include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/proc_fs.h>
+ #include <linux/miscdevice.h>
+@@ -157,16 +156,16 @@
+ * this array.
+ */
+ static uint64_t perf_bitmasks[] = {
+- 0x0000000000000000, /* first dbl word must be zero */
+- 0xfdffe00000000000, /* RDR0 bitmask */
+- 0x003f000000000000, /* RDR1 bitmask */
+- 0x00ffffffffffffff, /* RDR20-RDR21 bitmask (152 bits) */
+- 0xffffffffffffffff,
+- 0xfffffffc00000000,
+- 0xffffffffffffffff, /* RDR22-RDR23 bitmask (233 bits) */
+- 0xffffffffffffffff,
+- 0xfffffffffffffffc,
+- 0xff00000000000000
++ 0x0000000000000000ul, /* first dbl word must be zero */
++ 0xfdffe00000000000ul, /* RDR0 bitmask */
++ 0x003f000000000000ul, /* RDR1 bitmask */
++ 0x00fffffffffffffful, /* RDR20-RDR21 bitmask (152 bits) */
++ 0xfffffffffffffffful,
++ 0xfffffffc00000000ul,
++ 0xfffffffffffffffful, /* RDR22-RDR23 bitmask (233 bits) */
++ 0xfffffffffffffffful,
++ 0xfffffffffffffffcul,
++ 0xff00000000000000ul
+ };
+
+ /*
+@@ -174,16 +173,16 @@
+ * somethings have changed slightly.
+ */
+ static uint64_t perf_bitmasks_piranha[] = {
+- 0x0000000000000000, /* first dbl word must be zero */
+- 0xfdffe00000000000, /* RDR0 bitmask */
+- 0x003f000000000000, /* RDR1 bitmask */
+- 0x00ffffffffffffff, /* RDR20-RDR21 bitmask (158 bits) */
+- 0xffffffffffffffff,
+- 0xfffffffc00000000,
+- 0xffffffffffffffff, /* RDR22-RDR23 bitmask (210 bits) */
+- 0xffffffffffffffff,
+- 0xffffffffffffffff,
+- 0xfffc000000000000
++ 0x0000000000000000ul, /* first dbl word must be zero */
++ 0xfdffe00000000000ul, /* RDR0 bitmask */
++ 0x003f000000000000ul, /* RDR1 bitmask */
++ 0x00fffffffffffffful, /* RDR20-RDR21 bitmask (158 bits) */
++ 0xfffffffffffffffful,
++ 0xfffffffc00000000ul,
++ 0xfffffffffffffffful, /* RDR22-RDR23 bitmask (210 bits) */
++ 0xfffffffffffffffful,
++ 0xfffffffffffffffful,
++ 0xfffc000000000000ul
+ };
+
+ static uint64_t *bitmask_array; /* array of bitmasks to use */
+@@ -194,8 +193,8 @@
+ static int perf_config(uint32_t *image_ptr);
+ static int perf_release(struct inode *inode, struct file *file);
+ static int perf_open(struct inode *inode, struct file *file);
+-static ssize_t perf_read(struct file *file, char *buf, size_t cnt, loff_t *ppos);
+-static ssize_t perf_write(struct file *file, const char *buf, size_t count,
++static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos);
++static ssize_t perf_write(struct file *file, const char __user *buf, size_t count,
+ loff_t *ppos);
+ static int perf_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg);
+@@ -287,7 +286,7 @@
+ /*
+ * Read does nothing for this driver
+ */
+-static ssize_t perf_read(struct file *file, char *buf, size_t cnt, loff_t *ppos)
++static ssize_t perf_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos)
+ {
+ return 0;
+ }
+@@ -299,7 +298,7 @@
+ * called on the processor that the download should happen
+ * on.
+ */
+-static ssize_t perf_write(struct file *file, const char *buf, size_t count,
++static ssize_t perf_write(struct file *file, const char __user *buf, size_t count,
+ loff_t *ppos)
+ {
+ int err;
+@@ -460,7 +459,7 @@
+ }
+
+ /* copy out the Counters */
+- if (copy_to_user((void *)arg, raddr,
++ if (copy_to_user((void __user *)arg, raddr,
+ sizeof (raddr)) != 0) {
+ return -EFAULT;
+ }
+@@ -607,7 +606,7 @@
+ * all of dword 22 and 58 bits (plus 6 don't care bits) of
+ * dword 23.
+ */
+- userbuf[21] &= 0xfffffffffffffc00; /* 0 to last 10 bits */
++ userbuf[21] &= 0xfffffffffffffc00ul; /* 0 to last 10 bits */
+ userbuf[22] = 0;
+ userbuf[23] = 0;
+
+@@ -802,8 +801,8 @@
+ proc_hpa = cpu_device->hpa;
+
+ /* Merge intrigue bits into Runway STATUS 0 */
+- tmp64 = __raw_readq(proc_hpa + RUNWAY_STATUS) & 0xffecffffffffffff;
+- __raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000), proc_hpa + RUNWAY_STATUS);
++ tmp64 = __raw_readq(proc_hpa + RUNWAY_STATUS) & 0xffecfffffffffffful;
++ __raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul), proc_hpa + RUNWAY_STATUS);
+
+ /* Write RUNWAY DEBUG registers */
+ for (i = 0; i < 8; i++) {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/perf_asm.S CVS2_6_11_PA2/arch/parisc/kernel/perf_asm.S
+--- LINUS_2_6_11/arch/parisc/kernel/perf_asm.S 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/perf_asm.S 2005-03-01 23:47:36.000000000 -0700
+@@ -22,9 +22,9 @@
+ #include <linux/config.h>
+ #include <asm/assembly.h>
+
+-#ifdef __LP64__
++#ifdef CONFIG_64BIT
+ .level 2.0w
+-#endif /* __LP64__ */
++#endif /* CONFIG_64BIT */
+
+ #define MTDIAG_1(gr) .word 0x14201840 + gr*0x10000
+ #define MTDIAG_2(gr) .word 0x14401840 + gr*0x10000
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/process.c CVS2_6_11_PA2/arch/parisc/kernel/process.c
+--- LINUS_2_6_11/arch/parisc/kernel/process.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/process.c 2004-12-27 19:13:47.000000000 -0700
+@@ -54,7 +54,7 @@
+ #include <asm/uaccess.h>
+ #include <asm/unwind.h>
+
+-int hlt_counter;
++static int hlt_counter;
+
+ /*
+ * Power off function, if any
+@@ -251,7 +251,7 @@
+ sys_clone(unsigned long clone_flags, unsigned long usp,
+ struct pt_regs *regs)
+ {
+- int *user_tid = (int *)regs->gr[26];
++ int __user *user_tid = (int __user *)regs->gr[26];
+
+ /* usp must be word aligned. This also prevents users from
+ * passing in the value 1 (which is the signal for a special
+@@ -357,12 +357,12 @@
+ int error;
+ char *filename;
+
+- filename = getname((char *) regs->gr[26]);
++ filename = getname((const char __user *) regs->gr[26]);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ goto out;
+- error = do_execve(filename, (char **) regs->gr[25],
+- (char **) regs->gr[24], regs);
++ error = do_execve(filename, (char __user **) regs->gr[25],
++ (char __user **) regs->gr[24], regs);
+ if (error == 0) {
+ task_lock(current);
+ current->ptrace &= ~PT_DTRACE;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/real2.S CVS2_6_11_PA2/arch/parisc/kernel/real2.S
+--- LINUS_2_6_11/arch/parisc/kernel/real2.S 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/real2.S 2005-01-07 14:14:33.000000000 -0700
+@@ -81,8 +81,7 @@
+ rsm PSW_SM_W, %r0 /* go narrow */
+ #endif
+
+- ldil L%PA(ric_ret), %r2
+- ldo R%PA(ric_ret)(%r2), %r2
++ load32 PA(ric_ret), %r2
+ bv 0(%r31)
+ nop
+ ric_ret:
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/setup.c CVS2_6_11_PA2/arch/parisc/kernel/setup.c
+--- LINUS_2_6_11/arch/parisc/kernel/setup.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/setup.c 2004-12-31 10:26:35.000000000 -0700
+@@ -53,6 +53,15 @@
+ struct proc_dir_entry * proc_gsc_root = NULL;
+ struct proc_dir_entry * proc_mckinley_root = NULL;
+
++#if !defined(CONFIG_PA20) && (defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA))
++int parisc_bus_is_phys = 1; /* Assume no IOMMU is present */
++EXPORT_SYMBOL(parisc_bus_is_phys);
++#endif
++
++/* This sets the vmerge boundary and size, it's here because it has to
++ * be available on all platforms (zero means no-virtual merging) */
++unsigned long parisc_vmerge_boundary = 0;
++unsigned long parisc_vmerge_max_size = 0;
+
+ void __init setup_cmdline(char **cmdline_p)
+ {
+@@ -112,6 +121,10 @@
+
+ void __init setup_arch(char **cmdline_p)
+ {
++#ifdef __LP64__
++ extern int parisc_narrow_firmware;
++#endif
++
+ init_per_cpu(smp_processor_id()); /* Set Modes & Enable FP */
+
+ #ifdef __LP64__
+@@ -123,7 +136,6 @@
+ pdc_console_init();
+
+ #ifdef __LP64__
+- extern int parisc_narrow_firmware;
+ if(parisc_narrow_firmware) {
+ printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n");
+ }
+@@ -199,7 +211,7 @@
+ case pcxl2:
+ if (NULL == proc_gsc_root)
+ {
+- proc_gsc_root = proc_mkdir("bus/gsc", 0);
++ proc_gsc_root = proc_mkdir("bus/gsc", NULL);
+ }
+ break;
+ case pcxt_:
+@@ -210,13 +222,13 @@
+ case pcxw2:
+ if (NULL == proc_runway_root)
+ {
+- proc_runway_root = proc_mkdir("bus/runway", 0);
++ proc_runway_root = proc_mkdir("bus/runway", NULL);
+ }
+ break;
+ case mako:
+ if (NULL == proc_mckinley_root)
+ {
+- proc_mckinley_root = proc_mkdir("bus/mckinley", 0);
++ proc_mckinley_root = proc_mkdir("bus/mckinley", NULL);
+ }
+ break;
+ default:
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/signal.c CVS2_6_11_PA2/arch/parisc/kernel/signal.c
+--- LINUS_2_6_11/arch/parisc/kernel/signal.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/signal.c 2004-12-02 00:56:50.000000000 -0700
+@@ -32,6 +32,7 @@
+ #include <asm/uaccess.h>
+ #include <asm/pgalloc.h>
+ #include <asm/cacheflush.h>
++#include <asm/offsets.h>
+
+ #ifdef CONFIG_COMPAT
+ #include <linux/compat.h>
+@@ -69,7 +70,7 @@
+ #endif
+
+ asmlinkage int
+-sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs *regs)
++sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
+ {
+ sigset_t saveset, newset;
+ #ifdef __LP64__
+@@ -79,7 +80,7 @@
+ /* XXX: Don't preclude handling different sized sigset_t's. */
+ if (sigsetsize != sizeof(compat_sigset_t))
+ return -EINVAL;
+- if (copy_from_user(&newset32, (compat_sigset_t *)unewset, sizeof(newset32)))
++ if (copy_from_user(&newset32, (compat_sigset_t __user *)unewset, sizeof(newset32)))
+ return -EFAULT;
+ sigset_32to64(&newset,&newset32);
+
+@@ -125,7 +126,7 @@
+ #define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */
+
+ static long
+-restore_sigcontext(struct sigcontext *sc, struct pt_regs *regs)
++restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
+ {
+ long err = 0;
+
+@@ -143,14 +144,14 @@
+ void
+ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
+ {
+- struct rt_sigframe *frame;
++ struct rt_sigframe __user *frame;
+ struct siginfo si;
+ sigset_t set;
+ unsigned long usp = (regs->gr[30] & ~(0x01UL));
+ unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
+ #ifdef __LP64__
+ compat_sigset_t compat_set;
+- struct compat_rt_sigframe * compat_frame;
++ struct compat_rt_sigframe __user * compat_frame;
+
+ if(personality(current->personality) == PER_LINUX32)
+ sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
+@@ -158,12 +159,12 @@
+
+
+ /* Unwind the user stack to get the rt_sigframe structure. */
+- frame = (struct rt_sigframe *)
++ frame = (struct rt_sigframe __user *)
+ (usp - sigframe_size);
+ DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
+
+ #ifdef __LP64__
+- compat_frame = (struct compat_rt_sigframe *)frame;
++ compat_frame = (struct compat_rt_sigframe __user *)frame;
+
+ if(personality(current->personality) == PER_LINUX32){
+ DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
+@@ -238,7 +239,7 @@
+ * Set up a signal frame.
+ */
+
+-static inline void *
++static inline void __user *
+ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
+ {
+ /*FIXME: ELF32 vs. ELF64 has different frame_size, but since we
+@@ -251,11 +252,11 @@
+ sp = current->sas_ss_sp; /* Stacks grow up! */
+
+ DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp);
+- return (void *) sp; /* Stacks grow up. Fun. */
++ return (void __user *) sp; /* Stacks grow up. Fun. */
+ }
+
+ static long
+-setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, int in_syscall)
++setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_syscall)
+
+ {
+ unsigned long flags = 0;
+@@ -292,14 +293,14 @@
+ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs *regs, int in_syscall)
+ {
+- struct rt_sigframe *frame;
++ struct rt_sigframe __user *frame;
+ unsigned long rp, usp;
+ unsigned long haddr, sigframe_size;
+ struct siginfo si;
+ int err = 0;
+ #ifdef __LP64__
+ compat_int_t compat_val;
+- struct compat_rt_sigframe * compat_frame;
++ struct compat_rt_sigframe __user * compat_frame;
+ compat_sigset_t compat_set;
+ #endif
+
+@@ -313,7 +314,7 @@
+
+ #ifdef __LP64__
+
+- compat_frame = (struct compat_rt_sigframe *)frame;
++ compat_frame = (struct compat_rt_sigframe __user *)frame;
+
+ if(personality(current->personality) == PER_LINUX32) {
+ DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
+@@ -396,7 +397,7 @@
+ #endif
+ if (haddr & PA_PLABEL_FDESC) {
+ Elf32_Fdesc fdesc;
+- Elf32_Fdesc *ufdesc = (Elf32_Fdesc *)A(haddr & ~3);
++ Elf32_Fdesc __user *ufdesc = (Elf32_Fdesc __user *)A(haddr & ~3);
+
+ err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
+
+@@ -409,7 +410,7 @@
+ #ifdef __LP64__
+ } else {
+ Elf64_Fdesc fdesc;
+- Elf64_Fdesc *ufdesc = (Elf64_Fdesc *)A(haddr & ~3);
++ Elf64_Fdesc __user *ufdesc = (Elf64_Fdesc __user *)A(haddr & ~3);
+
+ err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
+
+@@ -443,6 +444,18 @@
+ psw |= PSW_W;
+ #endif
+
++ /* If we are singlestepping, arrange a trap to be delivered
++ when we return to userspace. Note the semantics -- we
++ should trap before the first insn in the handler is
++ executed. Ref:
++ http://sources.redhat.com/ml/gdb/2004-11/msg00245.html
++ */
++ if (pa_psw(current)->r) {
++ pa_psw(current)->r = 0;
++ psw |= PSW_R;
++ mtctl(-1, 0);
++ }
++
+ regs->gr[0] = psw;
+ regs->iaoq[0] = haddr | 3;
+ regs->iaoq[1] = regs->iaoq[0] + 4;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/signal32.c CVS2_6_11_PA2/arch/parisc/kernel/signal32.c
+--- LINUS_2_6_11/arch/parisc/kernel/signal32.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/signal32.c 2005-03-01 23:47:36.000000000 -0700
+@@ -20,7 +20,6 @@
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+-#include <linux/config.h>
+ #include <linux/compat.h>
+ #include <linux/slab.h>
+ #include <linux/module.h>
+@@ -65,7 +64,7 @@
+ }
+
+ static int
+-put_sigset32(compat_sigset_t *up, sigset_t *set, size_t sz)
++put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
+ {
+ compat_sigset_t s;
+
+@@ -76,7 +75,7 @@
+ }
+
+ static int
+-get_sigset32(compat_sigset_t *up, sigset_t *set, size_t sz)
++get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
+ {
+ compat_sigset_t s;
+ int r;
+@@ -90,7 +89,7 @@
+ return r;
+ }
+
+-int sys32_rt_sigprocmask(int how, compat_sigset_t *set, compat_sigset_t *oset,
++int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
+ unsigned int sigsetsize)
+ {
+ sigset_t old_set, new_set;
+@@ -99,8 +98,8 @@
+ if (set && get_sigset32(set, &new_set, sigsetsize))
+ return -EFAULT;
+
+- KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? &new_set : NULL,
+- oset ? &old_set : NULL, sigsetsize);
++ KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? (sigset_t __user *)&new_set : NULL,
++ oset ? (sigset_t __user *)&old_set : NULL, sigsetsize);
+
+ if (!ret && oset && put_sigset32(oset, &old_set, sigsetsize))
+ return -EFAULT;
+@@ -109,12 +108,12 @@
+ }
+
+
+-int sys32_rt_sigpending(compat_sigset_t *uset, unsigned int sigsetsize)
++int sys32_rt_sigpending(compat_sigset_t __user *uset, unsigned int sigsetsize)
+ {
+ int ret;
+ sigset_t set;
+
+- KERNEL_SYSCALL(ret, sys_rt_sigpending, &set, sigsetsize);
++ KERNEL_SYSCALL(ret, sys_rt_sigpending, (sigset_t __user *)&set, sigsetsize);
+
+ if (!ret && put_sigset32(uset, &set, sigsetsize))
+ return -EFAULT;
+@@ -123,7 +122,7 @@
+ }
+
+ long
+-sys32_rt_sigaction(int sig, const struct sigaction32 *act, struct sigaction32 *oact,
++sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact,
+ size_t sigsetsize)
+ {
+ struct k_sigaction32 new_sa32, old_sa32;
+@@ -151,7 +150,7 @@
+ }
+
+ int
+-do_sigaltstack32 (const compat_stack_t *uss32, compat_stack_t *uoss32, unsigned long sp)
++do_sigaltstack32 (const compat_stack_t __user *uss32, compat_stack_t __user *uoss32, unsigned long sp)
+ {
+ compat_stack_t ss32, oss32;
+ stack_t ss, oss;
+@@ -162,7 +161,7 @@
+ if (copy_from_user(&ss32, uss32, sizeof ss32))
+ return -EFAULT;
+
+- ss.ss_sp = (void *)(unsigned long)ss32.ss_sp;
++ ss.ss_sp = (void __user *)(unsigned long)ss32.ss_sp;
+ ss.ss_flags = ss32.ss_flags;
+ ss.ss_size = ss32.ss_size;
+
+@@ -172,7 +171,7 @@
+ if (uoss32)
+ ossp = &oss;
+
+- KERNEL_SYSCALL(ret, do_sigaltstack, ssp, ossp, sp);
++ KERNEL_SYSCALL(ret, do_sigaltstack, (const stack_t __user *)ssp, (stack_t __user *)ossp, sp);
+
+ if (!ret && uoss32) {
+ oss32.ss_sp = (unsigned int)(unsigned long)oss.ss_sp;
+@@ -186,7 +185,7 @@
+ }
+
+ long
+-restore_sigcontext32(struct compat_sigcontext *sc, struct compat_regfile * rf,
++restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
+ struct pt_regs *regs)
+ {
+ long err = 0;
+@@ -265,7 +264,7 @@
+ * truncate for a 32-bit userspace.
+ */
+ long
+-setup_sigcontext32(struct compat_sigcontext *sc, struct compat_regfile * rf,
++setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
+ struct pt_regs *regs, int in_syscall)
+ {
+ compat_int_t flags = 0;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/signal32.h CVS2_6_11_PA2/arch/parisc/kernel/signal32.h
+--- LINUS_2_6_11/arch/parisc/kernel/signal32.h 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/signal32.h 2004-10-04 13:12:49.000000000 -0600
+@@ -31,13 +31,13 @@
+
+ void sigset_32to64(sigset_t *s64, compat_sigset_t *s32);
+ void sigset_64to32(compat_sigset_t *s32, sigset_t *s64);
+-int do_sigaltstack32 (const compat_stack_t *uss32,
+- compat_stack_t *uoss32, unsigned long sp);
+-long restore_sigcontext32(struct compat_sigcontext *sc,
+- struct compat_regfile *rf,
++int do_sigaltstack32 (const compat_stack_t __user *uss32,
++ compat_stack_t __user *uoss32, unsigned long sp);
++long restore_sigcontext32(struct compat_sigcontext __user *sc,
++ struct compat_regfile __user *rf,
+ struct pt_regs *regs);
+-long setup_sigcontext32(struct compat_sigcontext *sc,
+- struct compat_regfile *rf,
++long setup_sigcontext32(struct compat_sigcontext __user *sc,
++ struct compat_regfile __user *rf,
+ struct pt_regs *regs, int in_syscall);
+
+ #endif
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/sys_parisc.c CVS2_6_11_PA2/arch/parisc/kernel/sys_parisc.c
+--- LINUS_2_6_11/arch/parisc/kernel/sys_parisc.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/sys_parisc.c 2005-02-04 12:34:34.000000000 -0700
+@@ -32,7 +32,7 @@
+ #include <linux/smp_lock.h>
+ #include <linux/syscalls.h>
+
+-int sys_pipe(int *fildes)
++int sys_pipe(int __user *fildes)
+ {
+ int fd[2];
+ int error;
+@@ -161,7 +161,7 @@
+ }
+ }
+
+-long sys_shmat_wrapper(int shmid, char *shmaddr, int shmflag)
++long sys_shmat_wrapper(int shmid, char __user *shmaddr, int shmflag)
+ {
+ unsigned long raddr;
+ int r;
+@@ -174,8 +174,8 @@
+
+ /* Fucking broken ABI */
+
+-#ifdef CONFIG_PARISC64
+-asmlinkage long parisc_truncate64(const char * path,
++#ifdef CONFIG_64BIT
++asmlinkage long parisc_truncate64(const char __user * path,
+ unsigned int high, unsigned int low)
+ {
+ return sys_truncate(path, (long)high << 32 | low);
+@@ -189,7 +189,7 @@
+
+ /* stubs for the benefit of the syscall_table since truncate64 and truncate
+ * are identical on LP64 */
+-asmlinkage long sys_truncate64(const char * path, unsigned long length)
++asmlinkage long sys_truncate64(const char __user * path, unsigned long length)
+ {
+ return sys_truncate(path, length);
+ }
+@@ -203,7 +203,7 @@
+ }
+ #else
+
+-asmlinkage long parisc_truncate64(const char * path,
++asmlinkage long parisc_truncate64(const char __user * path,
+ unsigned int high, unsigned int low)
+ {
+ return sys_truncate64(path, (loff_t)high << 32 | low);
+@@ -216,13 +216,13 @@
+ }
+ #endif
+
+-asmlinkage ssize_t parisc_pread64(unsigned int fd, char *buf, size_t count,
++asmlinkage ssize_t parisc_pread64(unsigned int fd, char __user *buf, size_t count,
+ unsigned int high, unsigned int low)
+ {
+ return sys_pread64(fd, buf, count, (loff_t)high << 32 | low);
+ }
+
+-asmlinkage ssize_t parisc_pwrite64(unsigned int fd, const char *buf,
++asmlinkage ssize_t parisc_pwrite64(unsigned int fd, const char __user *buf,
+ size_t count, unsigned int high, unsigned int low)
+ {
+ return sys_pwrite64(fd, buf, count, (loff_t)high << 32 | low);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/sys_parisc32.c CVS2_6_11_PA2/arch/parisc/kernel/sys_parisc32.c
+--- LINUS_2_6_11/arch/parisc/kernel/sys_parisc32.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/sys_parisc32.c 2005-02-03 04:44:18.000000000 -0700
+@@ -74,7 +74,7 @@
+ char *filename;
+
+ DBG(("sys32_execve(%p) r26 = 0x%lx\n", regs, regs->gr[26]));
+- filename = getname((char *) regs->gr[26]);
++ filename = getname((const char __user *) regs->gr[26]);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ goto out;
+@@ -111,13 +111,13 @@
+ u32 __unused[4];
+ };
+
+-asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
++asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
+ {
+ struct __sysctl_args32 tmp;
+ int error;
+ unsigned int oldlen32;
+ size_t oldlen, *oldlenp = NULL;
+- unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
++ unsigned long addr = (((long __force)&args->__unused[0]) + 7) & ~7;
+ extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
+ void *newval, size_t newlen);
+
+@@ -159,7 +159,7 @@
+ error = -EFAULT;
+ }
+ }
+- if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)))
++ if (copy_to_user(&args->__unused[0], tmp.__unused, sizeof(tmp.__unused)))
+ error = -EFAULT;
+ }
+ return error;
+@@ -168,19 +168,19 @@
+ #endif /* CONFIG_SYSCTL */
+
+ asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
+- struct compat_timespec *interval)
++ struct compat_timespec __user *interval)
+ {
+ struct timespec t;
+ int ret;
+-
+- KERNEL_SYSCALL(ret, sys_sched_rr_get_interval, pid, &t);
++
++ KERNEL_SYSCALL(ret, sys_sched_rr_get_interval, pid, (struct timespec __user *)&t);
+ if (put_compat_timespec(&t, interval))
+ return -EFAULT;
+ return ret;
+ }
+
+ static int
+-put_compat_timeval(struct compat_timeval *u, struct timeval *t)
++put_compat_timeval(struct compat_timeval __user *u, struct timeval *t)
+ {
+ struct compat_timeval t32;
+ t32.tv_sec = t->tv_sec;
+@@ -188,7 +188,7 @@
+ return copy_to_user(u, &t32, sizeof t32);
+ }
+
+-static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
++static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
+ {
+ long usec;
+
+@@ -201,7 +201,7 @@
+ }
+
+ asmlinkage int
+-sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
++sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
+ {
+ extern void do_gettimeofday(struct timeval *tv);
+
+@@ -220,7 +220,7 @@
+ }
+
+ asmlinkage
+-int sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
++int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
+ {
+ struct timespec kts;
+ struct timezone ktz;
+@@ -237,7 +237,7 @@
+ return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
+ }
+
+-int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
++int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
+ {
+ int err;
+
+@@ -294,24 +294,24 @@
+ };
+
+ struct getdents32_callback {
+- struct linux32_dirent * current_dir;
+- struct linux32_dirent * previous;
++ struct linux32_dirent __user * current_dir;
++ struct linux32_dirent __user * previous;
+ int count;
+ int error;
+ };
+
+ struct readdir32_callback {
+- struct old_linux32_dirent * dirent;
++ struct old_linux32_dirent __user * dirent;
+ int count;
+ };
+
+ #define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
+-#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
++#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
+ static int
+ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
+ unsigned int d_type)
+ {
+- struct linux32_dirent * dirent;
++ struct linux32_dirent __user * dirent;
+ struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
+ int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
+
+@@ -327,17 +327,17 @@
+ put_user(reclen, &dirent->d_reclen);
+ copy_to_user(dirent->d_name, name, namlen);
+ put_user(0, dirent->d_name + namlen);
+- dirent = (struct linux32_dirent *)((char *)dirent + reclen);
++ dirent = ((void __user *)dirent) + reclen;
+ buf->current_dir = dirent;
+ buf->count -= reclen;
+ return 0;
+ }
+
+ asmlinkage long
+-sys32_getdents (unsigned int fd, void * dirent, unsigned int count)
++sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count)
+ {
+ struct file * file;
+- struct linux32_dirent * lastdirent;
++ struct linux32_dirent __user * lastdirent;
+ struct getdents32_callback buf;
+ int error;
+
+@@ -346,7 +346,7 @@
+ if (!file)
+ goto out;
+
+- buf.current_dir = (struct linux32_dirent *) dirent;
++ buf.current_dir = (struct linux32_dirent __user *) dirent;
+ buf.previous = NULL;
+ buf.count = count;
+ buf.error = 0;
+@@ -372,7 +372,7 @@
+ unsigned int d_type)
+ {
+ struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
+- struct old_linux32_dirent * dirent;
++ struct old_linux32_dirent __user * dirent;
+
+ if (buf->count)
+ return -EINVAL;
+@@ -387,7 +387,7 @@
+ }
+
+ asmlinkage long
+-sys32_readdir (unsigned int fd, void * dirent, unsigned int count)
++sys32_readdir (unsigned int fd, void __user * dirent, unsigned int count)
+ {
+ int error;
+ struct file * file;
+@@ -477,7 +477,7 @@
+ };
+
+ asmlinkage long sys32_msgsnd(int msqid,
+- struct msgbuf32 *umsgp32,
++ struct msgbuf32 __user *umsgp32,
+ size_t msgsz, int msgflg)
+ {
+ struct msgbuf *mb;
+@@ -494,14 +494,14 @@
+ if (err)
+ err = -EFAULT;
+ else
+- KERNEL_SYSCALL(err, sys_msgsnd, msqid, mb, msgsz, msgflg);
++ KERNEL_SYSCALL(err, sys_msgsnd, msqid, (struct msgbuf __user *)mb, msgsz, msgflg);
+
+ kfree(mb);
+ return err;
+ }
+
+ asmlinkage long sys32_msgrcv(int msqid,
+- struct msgbuf32 *umsgp32,
++ struct msgbuf32 __user *umsgp32,
+ size_t msgsz, long msgtyp, int msgflg)
+ {
+ struct msgbuf *mb;
+@@ -511,7 +511,7 @@
+ if ((mb = kmalloc(msgsz + sizeof *mb + 4, GFP_KERNEL)) == NULL)
+ return -ENOMEM;
+
+- KERNEL_SYSCALL(err, sys_msgrcv, msqid, mb, msgsz, msgtyp, msgflg);
++ KERNEL_SYSCALL(err, sys_msgrcv, msqid, (struct msgbuf __user *)mb, msgsz, msgtyp, msgflg);
+
+ if (err >= 0) {
+ len = err;
+@@ -528,7 +528,7 @@
+ return err;
+ }
+
+-asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, s32 count)
++asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count)
+ {
+ mm_segment_t old_fs = get_fs();
+ int ret;
+@@ -538,7 +538,7 @@
+ return -EFAULT;
+
+ set_fs(KERNEL_DS);
+- ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
++ ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, count);
+ set_fs(old_fs);
+
+ if (offset && put_user(of, offset))
+@@ -547,9 +547,7 @@
+ return ret;
+ }
+
+-typedef long __kernel_loff_t32; /* move this to asm/posix_types.h? */
+-
+-asmlinkage int sys32_sendfile64(int out_fd, int in_fd, __kernel_loff_t32 *offset, s32 count)
++asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count)
+ {
+ mm_segment_t old_fs = get_fs();
+ int ret;
+@@ -559,7 +557,7 @@
+ return -EFAULT;
+
+ set_fs(KERNEL_DS);
+- ret = sys_sendfile64(out_fd, in_fd, offset ? &lof : NULL, count);
++ ret = sys_sendfile64(out_fd, in_fd, offset ? (loff_t __user *)&lof : NULL, count);
+ set_fs(old_fs);
+
+ if (offset && put_user(lof, offset))
+@@ -598,7 +596,7 @@
+ int :32; int :32; int :32; int :32;
+ };
+
+-asmlinkage long sys32_adjtimex(struct timex32 *txc_p32)
++asmlinkage long sys32_adjtimex(struct timex32 __user *txc_p32)
+ {
+ struct timex txc;
+ struct timex32 t32;
+@@ -647,7 +645,7 @@
+ * damage, I decided to just duplicate the code from sys_sysinfo here.
+ */
+
+-asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
++asmlinkage int sys32_sysinfo(struct sysinfo32 __user *info)
+ {
+ struct sysinfo val;
+ int err;
+@@ -714,7 +712,7 @@
+ return sys_semctl (semid, semnum, cmd, arg);
+ }
+
+-long sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char *buf,
++long sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char __user *buf,
+ size_t len)
+ {
+ return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/traps.c CVS2_6_11_PA2/arch/parisc/kernel/traps.c
+--- LINUS_2_6_11/arch/parisc/kernel/traps.c 2005-03-02 04:19:00.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/traps.c 2005-03-01 18:20:47.000000000 -0700
+@@ -163,13 +163,20 @@
+ struct unwind_frame_info info;
+
+ if (!task) {
+- unsigned long sp, ip, rp;
++ unsigned long sp;
++ struct pt_regs *r;
+
+ HERE:
+ asm volatile ("copy %%r30, %0" : "=r"(sp));
+- ip = (unsigned long)&&HERE;
+- rp = (unsigned long)__builtin_return_address(0);
+- unwind_frame_init(&info, current, sp, ip, rp);
++ r = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
++ if (!r)
++ return;
++ memset(r, 0, sizeof(struct pt_regs));
++ r->iaoq[0] = (unsigned long)&&HERE;
++ r->gr[2] = (unsigned long)__builtin_return_address(0);
++ r->gr[30] = sp;
++ unwind_frame_init(&info, current, r);
++ kfree(r);
+ } else {
+ unwind_frame_init_from_blocked_task(&info, task);
+ }
+@@ -242,7 +249,7 @@
+ struct siginfo si;
+
+ si.si_code = wot;
+- si.si_addr = (void *) (regs->iaoq[0] & ~3);
++ si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
+ si.si_signo = SIGTRAP;
+ si.si_errno = 0;
+ force_sig_info(SIGTRAP, &si, current);
+@@ -263,7 +270,7 @@
+ show_regs(regs);
+ #endif
+ si.si_code = TRAP_BRKPT;
+- si.si_addr = (void *) (regs->iaoq[0] & ~3);
++ si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
+ si.si_signo = SIGTRAP;
+ force_sig_info(SIGTRAP, &si, current);
+ break;
+@@ -281,7 +288,7 @@
+ #endif
+ si.si_signo = SIGTRAP;
+ si.si_code = TRAP_BRKPT;
+- si.si_addr = (void *) (regs->iaoq[0] & ~3);
++ si.si_addr = (void __user *) (regs->iaoq[0] & ~3);
+ force_sig_info(SIGTRAP, &si, current);
+ return;
+ }
+@@ -416,7 +423,7 @@
+ {
+ /* show_stack(NULL, (unsigned long *)regs->gr[30]); */
+ struct unwind_frame_info info;
+- unwind_frame_init(&info, current, regs->gr[30], regs->iaoq[0], regs->gr[2]);
++ unwind_frame_init(&info, current, regs);
+ do_show_stack(&info);
+ }
+
+@@ -569,7 +576,7 @@
+ give_sigill:
+ si.si_signo = SIGILL;
+ si.si_errno = 0;
+- si.si_addr = (void *) regs->iaoq[0];
++ si.si_addr = (void __user *) regs->iaoq[0];
+ force_sig_info(SIGILL, &si, current);
+ return;
+
+@@ -577,7 +584,7 @@
+ /* Overflow Trap, let the userland signal handler do the cleanup */
+ si.si_signo = SIGFPE;
+ si.si_code = FPE_INTOVF;
+- si.si_addr = (void *) regs->iaoq[0];
++ si.si_addr = (void __user *) regs->iaoq[0];
+ force_sig_info(SIGFPE, &si, current);
+ return;
+
+@@ -699,9 +706,9 @@
+ si.si_signo = SIGSEGV;
+ si.si_errno = 0;
+ if (code == 7)
+- si.si_addr = (void *) regs->iaoq[0];
++ si.si_addr = (void __user *) regs->iaoq[0];
+ else
+- si.si_addr = (void *) regs->ior;
++ si.si_addr = (void __user *) regs->ior;
+ force_sig_info(SIGSEGV, &si, current);
+ return;
+
+@@ -721,7 +728,7 @@
+ si.si_signo = SIGBUS;
+ si.si_code = BUS_OBJERR;
+ si.si_errno = 0;
+- si.si_addr = (void *) regs->ior;
++ si.si_addr = (void __user *) regs->ior;
+ force_sig_info(SIGBUS, &si, current);
+ return;
+ }
+@@ -732,7 +739,7 @@
+ }
+
+ if (user_mode(regs)) {
+- if ((fault_space>>SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) {
++ if ((fault_space >> SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) {
+ #ifdef PRINT_USER_FAULTS
+ if (fault_space == 0)
+ printk(KERN_DEBUG "User Fault on Kernel Space ");
+@@ -745,7 +752,7 @@
+ si.si_signo = SIGSEGV;
+ si.si_errno = 0;
+ si.si_code = SEGV_MAPERR;
+- si.si_addr = (void *) regs->ior;
++ si.si_addr = (void __user *) regs->ior;
+ force_sig_info(SIGSEGV, &si, current);
+ return;
+ }
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/unaligned.c CVS2_6_11_PA2/arch/parisc/kernel/unaligned.c
+--- LINUS_2_6_11/arch/parisc/kernel/unaligned.c 2005-03-02 04:19:01.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/unaligned.c 2004-10-04 13:12:49.000000000 -0600
+@@ -744,7 +744,7 @@
+ si.si_signo = SIGSEGV;
+ si.si_errno = 0;
+ si.si_code = SEGV_MAPERR;
+- si.si_addr = (void *)regs->ior;
++ si.si_addr = (void __user *)regs->ior;
+ force_sig_info(SIGSEGV, &si, current);
+ }
+ else
+@@ -754,7 +754,7 @@
+ si.si_signo = SIGBUS;
+ si.si_errno = 0;
+ si.si_code = BUS_ADRALN;
+- si.si_addr = (void *)regs->ior;
++ si.si_addr = (void __user *)regs->ior;
+ force_sig_info(SIGBUS, &si, current);
+ }
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/unwind.c CVS2_6_11_PA2/arch/parisc/kernel/unwind.c
+--- LINUS_2_6_11/arch/parisc/kernel/unwind.c 2005-03-02 04:19:01.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/unwind.c 2005-03-01 18:20:47.000000000 -0700
+@@ -36,8 +36,7 @@
+ * possible (before the slab allocator is initialized)
+ */
+ static struct unwind_table kernel_unwind_table;
+-static struct unwind_table *unwind_tables, *unwind_tables_end;
+-
++static LIST_HEAD(unwind_tables);
+
+ static inline const struct unwind_table_entry *
+ find_unwind_entry_in_table(const struct unwind_table *table, unsigned long addr)
+@@ -65,14 +64,14 @@
+ static const struct unwind_table_entry *
+ find_unwind_entry(unsigned long addr)
+ {
+- struct unwind_table *table = unwind_tables;
++ struct unwind_table *table;
+ const struct unwind_table_entry *e = NULL;
+
+ if (addr >= kernel_unwind_table.start &&
+ addr <= kernel_unwind_table.end)
+ e = find_unwind_entry_in_table(&kernel_unwind_table, addr);
+- else
+- for (; table; table = table->next) {
++ else
++ list_for_each_entry(table, &unwind_tables, list) {
+ if (addr >= table->start &&
+ addr <= table->end)
+ e = find_unwind_entry_in_table(table, addr);
+@@ -99,7 +98,7 @@
+ table->end = base_addr + end->region_end;
+ table->table = (struct unwind_table_entry *)table_start;
+ table->length = end - start + 1;
+- table->next = NULL;
++ INIT_LIST_HEAD(&table->list);
+
+ for (; start <= end; start++) {
+ if (start < end &&
+@@ -112,33 +111,60 @@
+ }
+ }
+
+-void *
++static void
++unwind_table_sort(struct unwind_table_entry *start,
++ struct unwind_table_entry *finish)
++{
++ struct unwind_table_entry el, *p, *q;
++
++ for (p = start + 1; p < finish; ++p) {
++ if (p[0].region_start < p[-1].region_start) {
++ el = *p;
++ q = p;
++ do {
++ q[0] = q[-1];
++ --q;
++ } while (q > start &&
++ el.region_start < q[-1].region_start);
++ *q = el;
++ }
++ }
++}
++
++struct unwind_table *
+ unwind_table_add(const char *name, unsigned long base_addr,
+ unsigned long gp,
+ void *start, void *end)
+ {
+ struct unwind_table *table;
+ unsigned long flags;
++ struct unwind_table_entry *s = (struct unwind_table_entry *)start;
++ struct unwind_table_entry *e = (struct unwind_table_entry *)end;
++
++ unwind_table_sort(s, e);
+
+ table = kmalloc(sizeof(struct unwind_table), GFP_USER);
+ if (table == NULL)
+ return NULL;
+ unwind_table_init(table, name, base_addr, gp, start, end);
+ spin_lock_irqsave(&unwind_lock, flags);
+- if (unwind_tables)
+- {
+- unwind_tables_end->next = table;
+- unwind_tables_end = table;
+- }
+- else
+- {
+- unwind_tables = unwind_tables_end = table;
+- }
++ list_add_tail(&table->list, &unwind_tables);
+ spin_unlock_irqrestore(&unwind_lock, flags);
+
+ return table;
+ }
+
++void unwind_table_remove(struct unwind_table *table)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&unwind_lock, flags);
++ list_del(&table->list);
++ spin_unlock_irqrestore(&unwind_lock, flags);
++
++ kfree(table);
++}
++
+ /* Called from setup_arch to import the kernel unwind info */
+ static int unwind_init(void)
+ {
+@@ -148,6 +174,8 @@
+ start = (long)&__start___unwind[0];
+ stop = (long)&__stop___unwind[0];
+
++ spin_lock_init(&unwind_lock);
++
+ printk("unwind_init: start = 0x%lx, end = 0x%lx, entries = %lu\n",
+ start, stop,
+ (stop - start) / sizeof(struct unwind_table_entry));
+@@ -239,9 +267,9 @@
+ info->prev_sp, info->prev_ip);
+ } else {
+ dbg("e->start = 0x%x, e->end = 0x%x, Save_SP = %d, "
+- "Save_RP = %d size = %u\n", e->region_start,
+- e->region_end, e->Save_SP, e->Save_RP,
+- e->Total_frame_size);
++ "Save_RP = %d, Millicode = %d size = %u\n",
++ e->region_start, e->region_end, e->Save_SP, e->Save_RP,
++ e->Millicode, e->Total_frame_size);
+
+ looking_for_rp = e->Save_RP;
+
+@@ -284,7 +312,9 @@
+ }
+
+ info->prev_sp = info->sp - frame_size;
+- if (rpoffset)
++ if (e->Millicode)
++ info->rp = info->r31;
++ else if (rpoffset)
+ info->rp = *(unsigned long *)(info->prev_sp - rpoffset);
+ info->prev_ip = info->rp;
+ info->rp = 0;
+@@ -296,13 +326,14 @@
+ }
+
+ void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
+- unsigned long sp, unsigned long ip, unsigned long rp)
++ struct pt_regs *regs)
+ {
+ memset(info, 0, sizeof(struct unwind_frame_info));
+ info->t = t;
+- info->sp = sp;
+- info->ip = ip;
+- info->rp = rp;
++ info->sp = regs->gr[30];
++ info->ip = regs->iaoq[0];
++ info->rp = regs->gr[2];
++ info->r31 = regs->gr[31];
+
+ dbg("(%d) Start unwind from sp=%08lx ip=%08lx\n",
+ t ? (int)t->pid : -1, info->sp, info->ip);
+@@ -310,14 +341,22 @@
+
+ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t)
+ {
+- struct pt_regs *regs = &t->thread.regs;
+- unwind_frame_init(info, t, regs->ksp, regs->kpc, 0);
++ struct pt_regs *r = &t->thread.regs;
++ struct pt_regs *r2;
++
++ r2 = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
++ if (!r2)
++ return;
++ *r2 = *r;
++ r2->gr[30] = r->ksp;
++ r2->iaoq[0] = r->kpc;
++ unwind_frame_init(info, t, r2);
++ kfree(r2);
+ }
+
+ void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs)
+ {
+- unwind_frame_init(info, current, regs->gr[30], regs->iaoq[0],
+- regs->gr[2]);
++ unwind_frame_init(info, current, regs);
+ }
+
+ int unwind_once(struct unwind_frame_info *next_frame)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/kernel/vmlinux.lds.S CVS2_6_11_PA2/arch/parisc/kernel/vmlinux.lds.S
+--- LINUS_2_6_11/arch/parisc/kernel/vmlinux.lds.S 2005-03-02 04:19:01.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/kernel/vmlinux.lds.S 2005-02-04 12:34:34.000000000 -0700
+@@ -29,7 +29,7 @@
+ #include <asm/page.h>
+
+ /* ld script to make hppa Linux kernel */
+-#ifndef CONFIG_PARISC64
++#ifndef CONFIG_64BIT
+ OUTPUT_FORMAT("elf32-hppa-linux")
+ OUTPUT_ARCH(hppa)
+ #else
+@@ -38,7 +38,7 @@
+ #endif
+
+ ENTRY(_stext)
+-#ifndef CONFIG_PARISC64
++#ifndef CONFIG_64BIT
+ jiffies = jiffies_64 + 4;
+ #else
+ jiffies = jiffies_64;
+@@ -84,6 +84,9 @@
+
+ .data : { /* Data */
+ *(.data)
++ *(.data.vm0.pmd)
++ *(.data.vm0.pgd)
++ *(.data.vm0.pte)
+ CONSTRUCTORS
+ }
+
+@@ -112,7 +115,7 @@
+ . = ALIGN(16384);
+ init_istack : { *(init_istack) }
+
+-#ifdef CONFIG_PARISC64
++#ifdef CONFIG_64BIT
+ . = ALIGN(16); /* Linkage tables */
+ .opd : { *(.opd) } PROVIDE (__gp = .);
+ .plt : { *(.plt) }
+@@ -180,7 +183,7 @@
+ /* Sections to be discarded */
+ /DISCARD/ : {
+ *(.exitcall.exit)
+-#ifdef CONFIG_PARISC64
++#ifdef CONFIG_64BIT
+ /* temporary hack until binutils is fixed to not emit these
+ for static binaries */
+ *(.interp)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/lib/checksum.c CVS2_6_11_PA2/arch/parisc/lib/checksum.c
+--- LINUS_2_6_11/arch/parisc/lib/checksum.c 2005-03-02 04:19:01.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/lib/checksum.c 2005-01-22 07:58:57.000000000 -0700
+@@ -131,9 +131,9 @@
+ * Copy from userspace and compute checksum. If we catch an exception
+ * then zero the rest of the buffer.
+ */
+-unsigned int csum_partial_copy_from_user (const unsigned char *src, unsigned char *dst,
+- int len, unsigned int sum,
+- int *err_ptr)
++unsigned int csum_partial_copy_from_user(const unsigned char __user *src,
++ unsigned char *dst, int len,
++ unsigned int sum, int *err_ptr)
+ {
+ int missing;
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/lib/debuglocks.c CVS2_6_11_PA2/arch/parisc/lib/debuglocks.c
+--- LINUS_2_6_11/arch/parisc/lib/debuglocks.c 2005-03-02 04:19:01.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/lib/debuglocks.c 2005-01-13 08:38:42.000000000 -0700
+@@ -1,7 +1,7 @@
+ /*
+ * Debugging versions of SMP locking primitives.
+ *
+- * Copyright (C) 2004 Thibaut VARENE <varenet at esiee.fr>
++ * Copyright (C) 2004 Thibaut VARENE <varenet at parisc-linux.org>
+ *
+ * Some code stollen from alpha & sparc64 ;)
+ *
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/lib/memcpy.c CVS2_6_11_PA2/arch/parisc/lib/memcpy.c
+--- LINUS_2_6_11/arch/parisc/lib/memcpy.c 2005-03-02 04:19:01.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/lib/memcpy.c 2005-02-03 04:44:19.000000000 -0700
+@@ -111,7 +111,7 @@
+ "\t" EXC_WORD "\t" #_e "\n" \
+ "\t.previous\n" \
+ : _tt(_t), "+r"(_a) \
+- : "1"(_a) \
++ : \
+ : "r8")
+
+ #define def_store_ai_insn(_insn,_sz,_tt,_s,_a,_t,_e) \
+@@ -122,7 +122,7 @@
+ "\t" EXC_WORD "\t" #_e "\n" \
+ "\t.previous\n" \
+ : "+r"(_a) \
+- : _tt(_t), "0"(_a) \
++ : _tt(_t) \
+ : "r8")
+
+ #define ldbma(_s, _a, _t, _e) def_load_ai_insn(ldbs,1,"=r",_s,_a,_t,_e)
+@@ -297,7 +297,7 @@
+ unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
+ {
+ register unsigned long src, dst, t1, t2, t3;
+- register char *pcs, *pcd;
++ register unsigned char *pcs, *pcd;
+ register unsigned int *pws, *pwd;
+ register double *pds, *pdd;
+ unsigned long ret = 0;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/math-emu/driver.c CVS2_6_11_PA2/arch/parisc/math-emu/driver.c
+--- LINUS_2_6_11/arch/parisc/math-emu/driver.c 2005-03-02 04:19:02.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/math-emu/driver.c 2005-03-01 23:47:36.000000000 -0700
+@@ -27,7 +27,6 @@
+ * Copyright (C) 2001 Hewlett-Packard <bame at debian.org>
+ */
+
+-#include <linux/config.h>
+ #include <linux/sched.h>
+ #include "float.h"
+ #include "math-emu.h"
+@@ -120,7 +119,7 @@
+ si.si_signo = signalcode >> 24;
+ si.si_errno = 0;
+ si.si_code = signalcode & 0xffffff;
+- si.si_addr = (void *) regs->iaoq[0];
++ si.si_addr = (void __user *) regs->iaoq[0];
+ force_sig_info(si.si_signo, &si, current);
+ return -1;
+ }
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/mm/fault.c CVS2_6_11_PA2/arch/parisc/mm/fault.c
+--- LINUS_2_6_11/arch/parisc/mm/fault.c 2005-03-02 04:19:02.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/mm/fault.c 2004-10-04 13:12:50.000000000 -0600
+@@ -225,7 +225,7 @@
+ si.si_signo = SIGSEGV;
+ si.si_errno = 0;
+ si.si_code = SEGV_MAPERR;
+- si.si_addr = (void *) address;
++ si.si_addr = (void __user *) address;
+ force_sig_info(SIGSEGV, &si, current);
+ return;
+ }
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/arch/parisc/mm/init.c CVS2_6_11_PA2/arch/parisc/mm/init.c
+--- LINUS_2_6_11/arch/parisc/mm/init.c 2005-03-02 04:19:02.000000000 -0700
++++ CVS2_6_11_PA2/arch/parisc/mm/init.c 2005-01-26 06:28:50.000000000 -0700
+@@ -21,6 +21,7 @@
+ #include <linux/swap.h>
+ #include <linux/unistd.h>
+ #include <linux/nodemask.h> /* for node_online_map */
++#include <linux/pagemap.h> /* for release_pages and page_cache_release */
+
+ #include <asm/pgalloc.h>
+ #include <asm/tlb.h>
+@@ -59,8 +60,6 @@
+
+ static struct resource sysram_resources[MAX_PHYSMEM_RANGES];
+
+-static unsigned long max_pfn;
+-
+ /* The following array is initialized from the firmware specific
+ * information retrieved in kernel/inventory.c.
+ */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/ide/Kconfig CVS2_6_11_PA2/drivers/ide/Kconfig
+--- LINUS_2_6_11/drivers/ide/Kconfig 2005-03-02 04:19:06.000000000 -0700
++++ CVS2_6_11_PA2/drivers/ide/Kconfig 2005-02-24 06:57:03.000000000 -0700
+@@ -611,7 +611,7 @@
+ tristate "NS87415 chipset support"
+ help
+ This driver adds detection and support for the NS87415 chip
+- (used in SPARC64, among others).
++ (used mainly on SPARC64 and PA-RISC machines).
+
+ Please read the comments at the top of <file:drivers/ide/pci/ns87415.c>.
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/keyboard/Kconfig CVS2_6_11_PA2/drivers/input/keyboard/Kconfig
+--- LINUS_2_6_11/drivers/input/keyboard/Kconfig 2005-03-02 04:19:07.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/keyboard/Kconfig 2005-01-12 13:16:31.000000000 -0700
+@@ -30,6 +30,44 @@
+ To compile this driver as a module, choose M here: the
+ module will be called atkbd.
+
++config KEYBOARD_ATKBD_HP_KEYCODES
++ bool "Use HP keyboard scancodes"
++ depends on PARISC && KEYBOARD_ATKBD
++ default y
++ help
++ Say Y here if you have a PA-RISC machine and want to use an AT or
++ PS/2 keyboard, and your keyboard uses keycodes that are specific to
++ PA-RISC keyboards.
++
++ Say N if you use a standard keyboard.
++
++config KEYBOARD_ATKBD_RDI_KEYCODES
++ bool "Use PrecisionBook keyboard scancodes"
++ depends on KEYBOARD_ATKBD_HP_KEYCODES
++ default n
++ help
++ If you have an RDI PrecisionBook, say Y here if you want to use its
++ built-in keyboard (as opposed to an external keyboard).
++
++ The PrecisionBook has five keys that conflict with those used by most
++ AT and PS/2 keyboards. These are as follows:
++
++ PrecisionBook Standard AT or PS/2
++
++ F1 F12
++ Left Ctrl Left Alt
++ Caps Lock Left Ctrl
++ Right Ctrl Caps Lock
++ Left 102nd key (the key to the right of Left Shift)
++
++ If you say N here, and use the PrecisionBook keyboard, then each key
++ in the left-hand column will be interpreted as the corresponding key
++ in the right-hand column.
++
++ If you say Y here, and use an external keyboard, then each key in the
++ right-hand column will be interpreted as the key shown in the
++ left-hand column.
++
+ config KEYBOARD_SUNKBD
+ tristate "Sun Type 4 and Type 5 keyboard support"
+ depends on INPUT && INPUT_KEYBOARD
+@@ -97,3 +135,34 @@
+
+ To compile this driver as a module, choose M here: the
+ module will be called amikbd.
++
++config KEYBOARD_HIL_OLD
++ tristate "HP HIL keyboard support (simple driver)"
++ depends on GSC && INPUT && INPUT_KEYBOARD && !HIL_MLC
++ default y
++ help
++ The "Human Interface Loop" is a older, 8-channel USB-like
++ controller used in several Hewlett Packard models. This driver
++ was adapted from the one written for m68k/hp300, and implements
++ support for a keyboard attached to the HIL port, but not for
++ any other types of HIL input devices like mice or tablets.
++ However, it has been thoroughly tested and is stable.
++
++ If you want full HIL support including support for multiple
++ keyboards, mices and tablets, you have to enable the
++ "HP System Device Controller i8042 Support" in the input/serio
++ submenu.
++
++config KEYBOARD_HIL
++ tristate "HP HIL keyboard support"
++ depends on GSC && INPUT && INPUT_KEYBOARD
++ default y
++ select HP_SDC
++ select HIL_MLC
++ select SERIO
++ help
++ The "Human Interface Loop" is a older, 8-channel USB-like
++ controller used in several Hewlett Packard models.
++ This driver implements support for HIL-keyboards attached
++ to your machine, so normally you should say Y here.
++
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/keyboard/Makefile CVS2_6_11_PA2/drivers/input/keyboard/Makefile
+--- LINUS_2_6_11/drivers/input/keyboard/Makefile 2005-03-02 04:19:07.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/keyboard/Makefile 2004-03-20 13:29:36.000000000 -0700
+@@ -2,8 +2,6 @@
+ # Makefile for the input core drivers.
+ #
+
+-# Each configuration option enables a list of files.
+-
+ obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o
+ obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o
+ obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
+@@ -12,3 +10,5 @@
+ obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o
+ obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
+ obj-$(CONFIG_KEYBOARD_98KBD) += 98kbd.o
++obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
++obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/keyboard/atkbd.c CVS2_6_11_PA2/drivers/input/keyboard/atkbd.c
+--- LINUS_2_6_11/drivers/input/keyboard/atkbd.c 2005-03-02 04:19:07.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/keyboard/atkbd.c 2005-02-03 04:44:37.000000000 -0700
+@@ -71,12 +71,15 @@
+ * are loadable via an userland utility.
+ */
+
+-#if defined(__hppa__)
+-#include "hpps2atkbd.h"
+-#else
+-
+ static unsigned char atkbd_set2_keycode[512] = {
+
++#ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES
++
++/* XXX: need a more general approach */
++
++#include "hpps2atkbd.h" /* include the keyboard scancodes */
++
++#else
+ 0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41,117,
+ 0, 56, 42, 93, 29, 16, 2, 0, 0, 0, 44, 31, 30, 17, 3, 0,
+ 0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183,
+@@ -96,9 +99,8 @@
+ 110,111,108,112,106,103, 0,119, 0,118,109, 0, 99,104,119, 0,
+
+ 0, 0, 0, 65, 99,
+-};
+-
+ #endif
++};
+
+ static unsigned char atkbd_set3_keycode[512] = {
+
+@@ -254,8 +256,8 @@
+ int scroll = 0, click = -1;
+ int value;
+
+-#ifdef ATKBD_DEBUG
+- printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
++#if 0 || defined(ATKBD_DEBUG) /* CHANGEME */
++ printk(KERN_ERR "atkbd.c: Received %02x flags %02x\n", data, flags);
+ #endif
+
+ #if !defined(__i386__) && !defined (__x86_64__)
+@@ -388,6 +390,9 @@
+ break;
+ }
+
++#if 0 /* CHANGEME */
++ printk(KERN_ERR "Reporting: %#x, emul=%d\n", code, atkbd->emul);
++#endif
+ atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value);
+ }
+
+@@ -501,7 +506,12 @@
+ * controller may confuse the keyboard need a full reset of the keyboard. On
+ * these systems the BIOS also usually doesn't do it for us.
+ */
+-
++/* XXX: I think this is wrong. We can't assume, that this definitively is a
++ keyboard. Since we are still in probing phase, it could be a mouse or
++ anything else and just sending a ATKBD_CMD_RESET_BAT might confuse the
++ device. IMHO those lines should be moved to the end of atkbd_probe().
++ Helge Deller
++ */
+ if (atkbd_reset)
+ if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT))
+ printk(KERN_WARNING "atkbd.c: keyboard reset failed on %s\n", ps2dev->serio->phys);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/keyboard/hil_kbd.c CVS2_6_11_PA2/drivers/input/keyboard/hil_kbd.c
+--- LINUS_2_6_11/drivers/input/keyboard/hil_kbd.c 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/keyboard/hil_kbd.c 2004-11-01 10:57:39.000000000 -0700
+@@ -0,0 +1,375 @@
++/*
++ * Generic linux-input device driver for keyboard devices
++ *
++ * Copyright (c) 2001 Brian S. Julin
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL").
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
++ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ *
++ * References:
++ * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
++ *
++ */
++
++#include <linux/hil.h>
++#include <linux/input.h>
++#include <linux/serio.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/pci_ids.h>
++
++#define PREFIX "HIL KEYB: "
++#define HIL_GENERIC_NAME "HIL keyboard"
++
++MODULE_AUTHOR("Brian S. Julin <bri at calyx.com>");
++MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver");
++MODULE_LICENSE("Dual BSD/GPL");
++
++#define HIL_KBD_MAX_LENGTH 16
++
++#define HIL_KBD_SET1_UPBIT 0x01
++#define HIL_KBD_SET1_SHIFT 1
++static unsigned int hil_kbd_set1[HIL_KEYCODES_SET1_TBLSIZE] =
++ { HIL_KEYCODES_SET1 };
++
++#define HIL_KBD_SET2_UPBIT 0x01
++#define HIL_KBD_SET2_SHIFT 1
++/* Set2 is user defined */
++
++#define HIL_KBD_SET3_UPBIT 0x80
++#define HIL_KBD_SET3_SHIFT 0
++static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] =
++ { HIL_KEYCODES_SET3 };
++
++static char hil_language[][16] = { HIL_LOCALE_MAP };
++
++struct hil_kbd {
++ struct input_dev dev;
++ struct serio *serio;
++
++ /* Input buffer and index for packets from HIL bus. */
++ hil_packet data[HIL_KBD_MAX_LENGTH];
++ int idx4; /* four counts per packet */
++
++ /* Raw device info records from HIL bus, see hil.h for fields. */
++ char idd[HIL_KBD_MAX_LENGTH]; /* DID byte and IDD record */
++ char rsc[HIL_KBD_MAX_LENGTH]; /* RSC record */
++ char exd[HIL_KBD_MAX_LENGTH]; /* EXD record */
++ char rnm[HIL_KBD_MAX_LENGTH + 1]; /* RNM record + NULL term. */
++
++ /* Something to sleep around with. */
++ struct semaphore sem;
++};
++
++/* Process a complete packet after transfer from the HIL */
++static void hil_kbd_process_record(struct hil_kbd *kbd)
++{
++ struct input_dev *dev = &kbd->dev;
++ hil_packet *data = kbd->data;
++ hil_packet p;
++ int idx, i, cnt;
++
++ idx = kbd->idx4/4;
++ p = data[idx - 1];
++
++ if ((p & ~HIL_CMDCT_POL) ==
++ (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report;
++ if ((p & ~HIL_CMDCT_RPL) ==
++ (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report;
++
++ /* Not a poll response. See if we are loading config records. */
++ switch (p & HIL_PKT_DATA_MASK) {
++ case HIL_CMD_IDD:
++ for (i = 0; i < idx; i++)
++ kbd->idd[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
++ for (; i < HIL_KBD_MAX_LENGTH; i++)
++ kbd->idd[i] = 0;
++ break;
++ case HIL_CMD_RSC:
++ for (i = 0; i < idx; i++)
++ kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
++ for (; i < HIL_KBD_MAX_LENGTH; i++)
++ kbd->rsc[i] = 0;
++ break;
++ case HIL_CMD_EXD:
++ for (i = 0; i < idx; i++)
++ kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
++ for (; i < HIL_KBD_MAX_LENGTH; i++)
++ kbd->exd[i] = 0;
++ break;
++ case HIL_CMD_RNM:
++ for (i = 0; i < idx; i++)
++ kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK;
++ for (; i < HIL_KBD_MAX_LENGTH + 1; i++)
++ kbd->rnm[i] = '\0';
++ break;
++ default:
++ /* These occur when device isn't present */
++ if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break;
++ /* Anything else we'd like to know about. */
++ printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
++ break;
++ }
++ goto out;
++
++ report:
++ cnt = 1;
++ switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) {
++ case HIL_POL_CHARTYPE_NONE:
++ break;
++ case HIL_POL_CHARTYPE_ASCII:
++ while (cnt < idx - 1)
++ input_report_key(dev, kbd->data[cnt++] & 0x7f, 1);
++ break;
++ case HIL_POL_CHARTYPE_RSVD1:
++ case HIL_POL_CHARTYPE_RSVD2:
++ case HIL_POL_CHARTYPE_BINARY:
++ while (cnt < idx - 1)
++ input_report_key(dev, kbd->data[cnt++], 1);
++ break;
++ case HIL_POL_CHARTYPE_SET1:
++ while (cnt < idx - 1) {
++ unsigned int key;
++ int up;
++ key = kbd->data[cnt++];
++ up = key & HIL_KBD_SET1_UPBIT;
++ key &= (~HIL_KBD_SET1_UPBIT & 0xff);
++ key = hil_kbd_set1[key >> HIL_KBD_SET1_SHIFT];
++ if (key != KEY_RESERVED)
++ input_report_key(dev, key, !up);
++ }
++ break;
++ case HIL_POL_CHARTYPE_SET2:
++ while (cnt < idx - 1) {
++ unsigned int key;
++ int up;
++ key = kbd->data[cnt++];
++ up = key & HIL_KBD_SET2_UPBIT;
++ key &= (~HIL_KBD_SET1_UPBIT & 0xff);
++ key = key >> HIL_KBD_SET2_SHIFT;
++ if (key != KEY_RESERVED)
++ input_report_key(dev, key, !up);
++ }
++ break;
++ case HIL_POL_CHARTYPE_SET3:
++ while (cnt < idx - 1) {
++ unsigned int key;
++ int up;
++ key = kbd->data[cnt++];
++ up = key & HIL_KBD_SET3_UPBIT;
++ key &= (~HIL_KBD_SET1_UPBIT & 0xff);
++ key = hil_kbd_set3[key >> HIL_KBD_SET3_SHIFT];
++ if (key != KEY_RESERVED)
++ input_report_key(dev, key, !up);
++ }
++ break;
++ }
++ out:
++ kbd->idx4 = 0;
++ up(&kbd->sem);
++}
++
++static void hil_kbd_process_err(struct hil_kbd *kbd) {
++ printk(KERN_WARNING PREFIX "errored HIL packet\n");
++ kbd->idx4 = 0;
++ up(&kbd->sem);
++}
++
++static irqreturn_t hil_kbd_interrupt(struct serio *serio,
++ unsigned char data, unsigned int flags, struct pt_regs *regs)
++{
++ struct hil_kbd *kbd;
++ hil_packet packet;
++ int idx;
++
++ kbd = (struct hil_kbd *)serio->private;
++ if (kbd == NULL) {
++ BUG();
++ return IRQ_HANDLED;
++ }
++
++ if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) {
++ hil_kbd_process_err(kbd);
++ return IRQ_HANDLED;
++ }
++ idx = kbd->idx4/4;
++ if (!(kbd->idx4 % 4)) kbd->data[idx] = 0;
++ packet = kbd->data[idx];
++ packet |= ((hil_packet)data) << ((3 - (kbd->idx4 % 4)) * 8);
++ kbd->data[idx] = packet;
++
++ /* Records of N 4-byte hil_packets must terminate with a command. */
++ if ((++(kbd->idx4)) % 4) return IRQ_HANDLED;
++ if ((packet & 0xffff0000) != HIL_ERR_INT) {
++ hil_kbd_process_err(kbd);
++ return IRQ_HANDLED;
++ }
++ if (packet & HIL_PKT_CMD) hil_kbd_process_record(kbd);
++ return IRQ_HANDLED;
++}
++
++static void hil_kbd_disconnect(struct serio *serio)
++{
++ struct hil_kbd *kbd;
++
++ kbd = (struct hil_kbd *)serio->private;
++ if (kbd == NULL) {
++ BUG();
++ return;
++ }
++
++ input_unregister_device(&kbd->dev);
++ serio_close(serio);
++ kfree(kbd);
++}
++
++static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
++{
++ struct hil_kbd *kbd;
++ uint8_t did, *idd;
++ int i;
++
++ if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return;
++
++ if (!(kbd = kmalloc(sizeof(struct hil_kbd), GFP_KERNEL))) return;
++ memset(kbd, 0, sizeof(struct hil_kbd));
++
++ if (serio_open(serio, drv)) goto bail0;
++
++ serio->private = kbd;
++ kbd->serio = serio;
++ kbd->dev.private = kbd;
++
++ init_MUTEX_LOCKED(&(kbd->sem));
++
++ /* Get device info. MLC driver supplies devid/status/etc. */
++ serio->write(serio, 0);
++ serio->write(serio, 0);
++ serio->write(serio, HIL_PKT_CMD >> 8);
++ serio->write(serio, HIL_CMD_IDD);
++ down(&(kbd->sem));
++
++ serio->write(serio, 0);
++ serio->write(serio, 0);
++ serio->write(serio, HIL_PKT_CMD >> 8);
++ serio->write(serio, HIL_CMD_RSC);
++ down(&(kbd->sem));
++
++ serio->write(serio, 0);
++ serio->write(serio, 0);
++ serio->write(serio, HIL_PKT_CMD >> 8);
++ serio->write(serio, HIL_CMD_RNM);
++ down(&(kbd->sem));
++
++ serio->write(serio, 0);
++ serio->write(serio, 0);
++ serio->write(serio, HIL_PKT_CMD >> 8);
++ serio->write(serio, HIL_CMD_EXD);
++ down(&(kbd->sem));
++
++ up(&(kbd->sem));
++
++ did = kbd->idd[0];
++ idd = kbd->idd + 1;
++ switch (did & HIL_IDD_DID_TYPE_MASK) {
++ case HIL_IDD_DID_TYPE_KB_INTEGRAL:
++ case HIL_IDD_DID_TYPE_KB_ITF:
++ case HIL_IDD_DID_TYPE_KB_RSVD:
++ case HIL_IDD_DID_TYPE_CHAR:
++ printk(KERN_INFO PREFIX "HIL keyboard found (did = 0x%02x, lang = %s)\n",
++ did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]);
++ break;
++ default:
++ goto bail1;
++ }
++
++ if(HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) {
++ printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n");
++ goto bail1;
++ }
++
++
++ kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++ kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
++ kbd->dev.keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
++ kbd->dev.keycodesize = sizeof(hil_kbd_set1[0]);
++ kbd->dev.keycode = hil_kbd_set1;
++ kbd->dev.name = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME;
++ kbd->dev.phys = "hpkbd/input0"; /* XXX */
++
++ kbd->dev.id.bustype = BUS_HIL;
++ kbd->dev.id.vendor = PCI_VENDOR_ID_HP;
++ kbd->dev.id.product = 0x0001; /* TODO: get from kbd->rsc */
++ kbd->dev.id.version = 0x0100; /* TODO: get from kbd->rsc */
++ kbd->dev.dev = &serio->dev;
++
++ for (i = 0; i < 128; i++) {
++ set_bit(hil_kbd_set1[i], kbd->dev.keybit);
++ set_bit(hil_kbd_set3[i], kbd->dev.keybit);
++ }
++ clear_bit(0, kbd->dev.keybit);
++
++ input_register_device(&kbd->dev);
++ printk(KERN_INFO "input: %s, ID: %d\n",
++ kbd->dev.name, did);
++
++ serio->write(serio, 0);
++ serio->write(serio, 0);
++ serio->write(serio, HIL_PKT_CMD >> 8);
++ serio->write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */
++ down(&(kbd->sem));
++ up(&(kbd->sem));
++
++ return;
++ bail1:
++ serio_close(serio);
++ bail0:
++ kfree(kbd);
++}
++
++
++struct serio_driver hil_kbd_serio_drv = {
++ .driver = {
++ .name = "hil_kbd",
++ },
++ .description = "HP HIL keyboard driver",
++ .connect = hil_kbd_connect,
++ .disconnect = hil_kbd_disconnect,
++ .interrupt = hil_kbd_interrupt
++};
++
++static int __init hil_kbd_init(void)
++{
++ serio_register_driver(&hil_kbd_serio_drv);
++ return 0;
++}
++
++static void __exit hil_kbd_exit(void)
++{
++ serio_unregister_driver(&hil_kbd_serio_drv);
++}
++
++module_init(hil_kbd_init);
++module_exit(hil_kbd_exit);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/keyboard/hilkbd.c CVS2_6_11_PA2/drivers/input/keyboard/hilkbd.c
+--- LINUS_2_6_11/drivers/input/keyboard/hilkbd.c 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/keyboard/hilkbd.c 2005-01-11 07:11:34.000000000 -0700
+@@ -0,0 +1,343 @@
++/*
++ * linux/drivers/hil/hilkbd.c
++ *
++ * Copyright (C) 1998 Philip Blundell <philb at gnu.org>
++ * Copyright (C) 1999 Matthew Wilcox <willy at bofh.ai>
++ * Copyright (C) 1999-2003 Helge Deller <deller at gmx.de>
++ *
++ * Very basic HP Human Interface Loop (HIL) driver.
++ * This driver handles the keyboard on HP300 (m68k) and on some
++ * HP700 (parisc) series machines.
++ *
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License version 2. See the file COPYING in the main directory of this
++ * archive for more details.
++ */
++
++#include <linux/pci_ids.h>
++#include <linux/ioport.h>
++#include <linux/module.h>
++#include <linux/config.h>
++#include <linux/errno.h>
++#include <linux/input.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/hil.h>
++#include <linux/spinlock.h>
++
++
++MODULE_AUTHOR("Philip Blundell, Matthew Wilcox, Helge Deller");
++MODULE_DESCRIPTION("HIL keyboard driver (basic functionality)");
++MODULE_LICENSE("GPL v2");
++
++
++#if defined(CONFIG_PARISC)
++
++ #include <asm/io.h>
++ #include <asm/hardware.h>
++ #include <asm/parisc-device.h>
++ static unsigned long hil_base; /* HPA for the HIL device */
++ static unsigned int hil_irq;
++ #define HILBASE hil_base /* HPPA (parisc) port address */
++ #define HIL_DATA 0x800
++ #define HIL_CMD 0x801
++ #define HIL_IRQ hil_irq
++ #define hil_readb(p) gsc_readb(p)
++ #define hil_writeb(v,p) gsc_writeb((v),(p))
++
++#elif defined(CONFIG_HP300)
++
++ #define HILBASE 0xf0428000 /* HP300 (m86k) port address */
++ #define HIL_DATA 0x1
++ #define HIL_CMD 0x3
++ #define HIL_IRQ 2
++ #define hil_readb(p) readb(p)
++ #define hil_writeb(v,p) writeb((v),(p))
++
++#else
++#error "HIL is not supported on this platform"
++#endif
++
++
++
++/* HIL helper functions */
++
++#define hil_busy() (hil_readb(HILBASE + HIL_CMD) & HIL_BUSY)
++#define hil_data_available() (hil_readb(HILBASE + HIL_CMD) & HIL_DATA_RDY)
++#define hil_status() (hil_readb(HILBASE + HIL_CMD))
++#define hil_command(x) do { hil_writeb((x), HILBASE + HIL_CMD); } while (0)
++#define hil_read_data() (hil_readb(HILBASE + HIL_DATA))
++#define hil_write_data(x) do { hil_writeb((x), HILBASE + HIL_DATA); } while (0)
++
++/* HIL constants */
++
++#define HIL_BUSY 0x02
++#define HIL_DATA_RDY 0x01
++
++#define HIL_SETARD 0xA0 /* set auto-repeat delay */
++#define HIL_SETARR 0xA2 /* set auto-repeat rate */
++#define HIL_SETTONE 0xA3 /* set tone generator */
++#define HIL_CNMT 0xB2 /* clear nmi */
++#define HIL_INTON 0x5C /* Turn on interrupts. */
++#define HIL_INTOFF 0x5D /* Turn off interrupts. */
++
++#define HIL_READKBDSADR 0xF9
++#define HIL_WRITEKBDSADR 0xE9
++
++static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] =
++ { HIL_KEYCODES_SET1 };
++
++/* HIL structure */
++static struct {
++ struct input_dev dev;
++
++ unsigned int curdev;
++
++ unsigned char s;
++ unsigned char c;
++ int valid;
++
++ unsigned char data[16];
++ unsigned int ptr;
++ spinlock_t lock;
++
++ void *dev_id; /* native bus device */
++} hil_dev;
++
++
++static void poll_finished(void)
++{
++ int down;
++ int key;
++ unsigned char scode;
++
++ switch (hil_dev.data[0]) {
++ case 0x40:
++ down = (hil_dev.data[1] & 1) == 0;
++ scode = hil_dev.data[1] >> 1;
++ key = hphilkeyb_keycode[scode];
++ input_report_key(&hil_dev.dev, key, down);
++ break;
++ }
++ hil_dev.curdev = 0;
++}
++
++static inline void handle_status(unsigned char s, unsigned char c)
++{
++ if (c & 0x8) {
++ /* End of block */
++ if (c & 0x10)
++ poll_finished();
++ } else {
++ if (c & 0x10) {
++ if (hil_dev.curdev)
++ poll_finished(); /* just in case */
++ hil_dev.curdev = c & 7;
++ hil_dev.ptr = 0;
++ }
++ }
++}
++
++static inline void handle_data(unsigned char s, unsigned char c)
++{
++ if (hil_dev.curdev) {
++ hil_dev.data[hil_dev.ptr++] = c;
++ hil_dev.ptr &= 15;
++ }
++}
++
++
++/*
++ * Handle HIL interrupts.
++ */
++static irqreturn_t hil_interrupt(int irq, void *handle, struct pt_regs *regs)
++{
++ unsigned char s, c;
++
++ s = hil_status();
++ c = hil_read_data();
++
++ switch (s >> 4) {
++ case 0x5:
++ handle_status(s, c);
++ break;
++ case 0x6:
++ handle_data(s, c);
++ break;
++ case 0x4:
++ hil_dev.s = s;
++ hil_dev.c = c;
++ mb();
++ hil_dev.valid = 1;
++ break;
++ }
++ return IRQ_HANDLED;
++}
++
++/*
++ * Send a command to the HIL
++ */
++
++static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&hil_dev.lock, flags);
++ while (hil_busy())
++ /* wait */;
++ hil_command(cmd);
++ while (len--) {
++ while (hil_busy())
++ /* wait */;
++ hil_write_data(*(data++));
++ }
++ spin_unlock_irqrestore(&hil_dev.lock, flags);
++}
++
++
++/*
++ * Initialise HIL.
++ */
++
++static int __init
++hil_keyb_init(void)
++{
++ unsigned char c;
++ unsigned int i, kbid;
++ wait_queue_head_t hil_wait;
++
++ if (hil_dev.dev.id.bustype) {
++ return -ENODEV; /* already initialized */
++ }
++
++#if defined(CONFIG_HP300)
++ if (!hwreg_present((void *)(HILBASE + HIL_DATA)))
++ return -ENODEV;
++
++ request_region(HILBASE+HIL_DATA, 2, "hil");
++#endif
++
++ request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id);
++
++ /* Turn on interrupts */
++ hil_do(HIL_INTON, NULL, 0);
++
++ /* Look for keyboards */
++ hil_dev.valid = 0; /* clear any pending data */
++ hil_do(HIL_READKBDSADR, NULL, 0);
++
++ init_waitqueue_head(&hil_wait);
++ wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ);
++ if (!hil_dev.valid) {
++ printk(KERN_WARNING "HIL: timed out, assuming no keyboard present.\n");
++ }
++
++ c = hil_dev.c;
++ hil_dev.valid = 0;
++ if (c == 0) {
++ kbid = -1;
++ printk(KERN_WARNING "HIL: no keyboard present.\n");
++ } else {
++ kbid = ffz(~c);
++ /* printk(KERN_INFO "HIL: keyboard found at id %d\n", kbid); */
++ }
++
++ /* set it to raw mode */
++ c = 0;
++ hil_do(HIL_WRITEKBDSADR, &c, 1);
++
++ init_input_dev(&hil_dev.dev);
++
++ for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)
++ if (hphilkeyb_keycode[i] != KEY_RESERVED)
++ set_bit(hphilkeyb_keycode[i], hil_dev.dev.keybit);
++
++ hil_dev.dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
++ hil_dev.dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
++ hil_dev.dev.keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
++ hil_dev.dev.keycodesize = sizeof(hphilkeyb_keycode[0]);
++ hil_dev.dev.keycode = hphilkeyb_keycode;
++ hil_dev.dev.name = "HIL keyboard";
++ hil_dev.dev.phys = "hpkbd/input0";
++
++ hil_dev.dev.id.bustype = BUS_HIL;
++ hil_dev.dev.id.vendor = PCI_VENDOR_ID_HP;
++ hil_dev.dev.id.product = 0x0001;
++ hil_dev.dev.id.version = 0x0010;
++
++ input_register_device(&hil_dev.dev);
++ printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",
++ hil_dev.dev.name, kbid, HILBASE, HIL_IRQ);
++
++ return 0;
++}
++
++#if defined(CONFIG_PARISC)
++static int __init
++hil_init_chip(struct parisc_device *dev)
++{
++ if (!dev->irq) {
++ printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa);
++ return -ENODEV;
++ }
++
++ hil_base = dev->hpa;
++ hil_irq = dev->irq;
++ hil_dev.dev_id = dev;
++
++ printk(KERN_INFO "Found HIL bus at 0x%08lx, IRQ %d\n", hil_base, hil_irq);
++
++ return hil_keyb_init();
++}
++
++static struct parisc_device_id hil_tbl[] = {
++ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 },
++ { 0, }
++};
++
++MODULE_DEVICE_TABLE(parisc, hil_tbl);
++
++static struct parisc_driver hil_driver = {
++ .name = "HIL",
++ .id_table = hil_tbl,
++ .probe = hil_init_chip,
++};
++#endif /* CONFIG_PARISC */
++
++
++
++
++
++static int __init hil_init(void)
++{
++#if defined(CONFIG_PARISC)
++ return register_parisc_driver(&hil_driver);
++#else
++ return hil_keyb_init();
++#endif
++}
++
++
++static void __exit hil_exit(void)
++{
++ if (HIL_IRQ) {
++ disable_irq(HIL_IRQ);
++ free_irq(HIL_IRQ, hil_dev.dev_id);
++ }
++
++ /* Turn off interrupts */
++ hil_do(HIL_INTOFF, NULL, 0);
++
++ input_unregister_device(&hil_dev.dev);
++
++#if defined(CONFIG_PARISC)
++ unregister_parisc_driver(&hil_driver);
++#else
++ release_region(HILBASE+HIL_DATA, 2);
++#endif
++}
++
++module_init(hil_init);
++module_exit(hil_exit);
++
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/keyboard/hpps2atkbd.h CVS2_6_11_PA2/drivers/input/keyboard/hpps2atkbd.h
+--- LINUS_2_6_11/drivers/input/keyboard/hpps2atkbd.h 2005-03-02 04:19:07.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/keyboard/hpps2atkbd.h 2005-01-13 08:38:42.000000000 -0700
+@@ -3,7 +3,7 @@
+ *
+ * Copyright (c) 2004 Helge Deller <deller at gmx.de>
+ * Copyright (c) 2002 Laurent Canet <canetl at esiee.fr>
+- * Copyright (c) 2002 Thibaut Varene <varenet at esiee.fr>
++ * Copyright (c) 2002 Thibaut Varene <varenet at parisc-linux.org>
+ * Copyright (c) 2000 Xavier Debacker <debackex at esiee.fr>
+ *
+ * HP PS/2 AT-compatible Keyboard, found in PA/RISC Workstations & Laptops
+@@ -14,10 +14,8 @@
+ */
+
+
+-/* undefine if you have a RDI PRECISIONBOOK */
+-#define STANDARD_KEYBOARD
+-
+-#if defined(STANDARD_KEYBOARD)
++/* Is the keyboard an RDI PrecisionBook? */
++#ifndef CONFIG_KEYBOARD_ATKBD_RDI_KEYCODES
+ # define CONFLICT(x,y) x
+ #else
+ # define CONFLICT(x,y) y
+@@ -50,10 +48,10 @@
+ /* 60 */ KEY_DOWN, C_61, KEY_PAUSE, KEY_UP, KEY_DELETE, KEY_END, KEY_BACKSPACE, KEY_INSERT,
+ /* 68 */ KEY_RESERVED, KEY_KP1, KEY_RIGHT, KEY_KP4, KEY_KP7, KEY_PAGEDOWN, KEY_HOME, KEY_PAGEUP,
+ /* 70 */ KEY_KP0, KEY_KPDOT, KEY_KP2, KEY_KP5, KEY_KP6, KEY_KP8, KEY_ESC, KEY_NUMLOCK,
+-/* 78 */ KEY_F11, KEY_KPPLUS, KEY_KP3, KEY_KPMINUS, KEY_KPASTERISK,KEY_KP9, KEY_SCROLLLOCK,KEY_103RD,
++/* 78 */ KEY_F11, KEY_KPPLUS, KEY_KP3, KEY_KPMINUS, KEY_KPASTERISK,KEY_KP9, KEY_SCROLLLOCK,KEY_102ND,
+ /* 80 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ /* 88 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+-/* 90 */ KEY_RESERVED, KEY_RIGHTALT, KEY_SYSRQ, KEY_RESERVED, KEY_RIGHTCTRL, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
++/* 90 */ KEY_RESERVED, KEY_RIGHTALT, 255, KEY_RESERVED, KEY_RIGHTCTRL, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ /* 98 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_CAPSLOCK, KEY_RESERVED, KEY_LEFTMETA,
+ /* a0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RIGHTMETA,
+ /* a8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_COMPOSE,
+@@ -103,7 +101,6 @@
+ /* f0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
+ /* f8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED
+
+-#undef STANDARD_KEYBOARD
+ #undef CONFLICT
+ #undef C_07
+ #undef C_11
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/misc/Kconfig CVS2_6_11_PA2/drivers/input/misc/Kconfig
+--- LINUS_2_6_11/drivers/input/misc/Kconfig 2005-03-02 04:19:08.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/misc/Kconfig 2005-01-22 07:59:19.000000000 -0700
+@@ -49,3 +49,11 @@
+ To compile this driver as a module, choose M here: the
+ module will be called uinput.
+
++config HP_SDC_RTC
++ tristate "HP SDC Real Time Clock"
++ depends on INPUT && INPUT_MISC && GSC
++ select HP_SDC
++ help
++ Say Y here if you want to support the built-in real time clock
++ of the HP SDC controller.
++
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/misc/Makefile CVS2_6_11_PA2/drivers/input/misc/Makefile
+--- LINUS_2_6_11/drivers/input/misc/Makefile 2005-03-02 04:19:08.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/misc/Makefile 2004-01-14 11:19:43.000000000 -0700
+@@ -9,3 +9,4 @@
+ obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
+ obj-$(CONFIG_INPUT_98SPKR) += 98spkr.o
+ obj-$(CONFIG_INPUT_UINPUT) += uinput.o
++obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/misc/hp_sdc_rtc.c CVS2_6_11_PA2/drivers/input/misc/hp_sdc_rtc.c
+--- LINUS_2_6_11/drivers/input/misc/hp_sdc_rtc.c 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/misc/hp_sdc_rtc.c 2004-10-27 14:17:18.000000000 -0600
+@@ -0,0 +1,724 @@
++/*
++ * HP i8042 SDC + MSM-58321 BBRTC driver.
++ *
++ * Copyright (c) 2001 Brian S. Julin
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL").
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
++ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ *
++ * References:
++ * System Device Controller Microprocessor Firmware Theory of Operation
++ * for Part Number 1820-4784 Revision B. Dwg No. A-1820-4784-2
++ * efirtc.c by Stephane Eranian/Hewlett Packard
++ *
++ */
++
++#include <linux/hp_sdc.h>
++#include <linux/errno.h>
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/time.h>
++#include <linux/miscdevice.h>
++#include <linux/proc_fs.h>
++#include <linux/poll.h>
++#include <linux/rtc.h>
++
++MODULE_AUTHOR("Brian S. Julin <bri at calyx.com>");
++MODULE_DESCRIPTION("HP i8042 SDC + MSM-58321 RTC Driver");
++MODULE_LICENSE("Dual BSD/GPL");
++
++#define RTC_VERSION "1.10d"
++
++static unsigned long epoch = 2000;
++
++static struct semaphore i8042tregs;
++
++static hp_sdc_irqhook hp_sdc_rtc_isr;
++
++static struct fasync_struct *hp_sdc_rtc_async_queue;
++
++static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait);
++
++static loff_t hp_sdc_rtc_llseek(struct file *file, loff_t offset, int origin);
++
++static ssize_t hp_sdc_rtc_read(struct file *file, char *buf,
++ size_t count, loff_t *ppos);
++
++static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file,
++ unsigned int cmd, unsigned long arg);
++
++static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait);
++
++static int hp_sdc_rtc_open(struct inode *inode, struct file *file);
++static int hp_sdc_rtc_release(struct inode *inode, struct file *file);
++static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on);
++
++static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off,
++ int count, int *eof, void *data);
++
++static void hp_sdc_rtc_isr (int irq, void *dev_id,
++ uint8_t status, uint8_t data)
++{
++ return;
++}
++
++static int hp_sdc_rtc_do_read_bbrtc (struct rtc_time *rtctm)
++{
++ struct semaphore tsem;
++ hp_sdc_transaction t;
++ uint8_t tseq[91];
++ int i;
++
++ i = 0;
++ while (i < 91) {
++ tseq[i++] = HP_SDC_ACT_DATAREG |
++ HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN;
++ tseq[i++] = 0x01; /* write i8042[0x70] */
++ tseq[i] = i / 7; /* BBRTC reg address */
++ i++;
++ tseq[i++] = HP_SDC_CMD_DO_RTCR; /* Trigger command */
++ tseq[i++] = 2; /* expect 1 stat/dat pair back. */
++ i++; i++; /* buffer for stat/dat pair */
++ }
++ tseq[84] |= HP_SDC_ACT_SEMAPHORE;
++ t.endidx = 91;
++ t.seq = tseq;
++ t.act.semaphore = &tsem;
++ init_MUTEX_LOCKED(&tsem);
++
++ if (hp_sdc_enqueue_transaction(&t)) return -1;
++
++ down_interruptible(&tsem); /* Put ourselves to sleep for results. */
++
++ /* Check for nonpresence of BBRTC */
++ if (!((tseq[83] | tseq[90] | tseq[69] | tseq[76] |
++ tseq[55] | tseq[62] | tseq[34] | tseq[41] |
++ tseq[20] | tseq[27] | tseq[6] | tseq[13]) & 0x0f))
++ return -1;
++
++ memset(rtctm, 0, sizeof(struct rtc_time));
++ rtctm->tm_year = (tseq[83] & 0x0f) + (tseq[90] & 0x0f) * 10;
++ rtctm->tm_mon = (tseq[69] & 0x0f) + (tseq[76] & 0x0f) * 10;
++ rtctm->tm_mday = (tseq[55] & 0x0f) + (tseq[62] & 0x0f) * 10;
++ rtctm->tm_wday = (tseq[48] & 0x0f);
++ rtctm->tm_hour = (tseq[34] & 0x0f) + (tseq[41] & 0x0f) * 10;
++ rtctm->tm_min = (tseq[20] & 0x0f) + (tseq[27] & 0x0f) * 10;
++ rtctm->tm_sec = (tseq[6] & 0x0f) + (tseq[13] & 0x0f) * 10;
++
++ return 0;
++}
++
++static int hp_sdc_rtc_read_bbrtc (struct rtc_time *rtctm)
++{
++ struct rtc_time tm, tm_last;
++ int i = 0;
++
++ /* MSM-58321 has no read latch, so must read twice and compare. */
++
++ if (hp_sdc_rtc_do_read_bbrtc(&tm_last)) return -1;
++ if (hp_sdc_rtc_do_read_bbrtc(&tm)) return -1;
++
++ while (memcmp(&tm, &tm_last, sizeof(struct rtc_time))) {
++ if (i++ > 4) return -1;
++ memcpy(&tm_last, &tm, sizeof(struct rtc_time));
++ if (hp_sdc_rtc_do_read_bbrtc(&tm)) return -1;
++ }
++
++ memcpy(rtctm, &tm, sizeof(struct rtc_time));
++
++ return 0;
++}
++
++
++static int64_t hp_sdc_rtc_read_i8042timer (uint8_t loadcmd, int numreg)
++{
++ hp_sdc_transaction t;
++ uint8_t tseq[26] = {
++ HP_SDC_ACT_PRECMD | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN,
++ 0,
++ HP_SDC_CMD_READ_T1, 2, 0, 0,
++ HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN,
++ HP_SDC_CMD_READ_T2, 2, 0, 0,
++ HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN,
++ HP_SDC_CMD_READ_T3, 2, 0, 0,
++ HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN,
++ HP_SDC_CMD_READ_T4, 2, 0, 0,
++ HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN,
++ HP_SDC_CMD_READ_T5, 2, 0, 0
++ };
++
++ t.endidx = numreg * 5;
++
++ tseq[1] = loadcmd;
++ tseq[t.endidx - 4] |= HP_SDC_ACT_SEMAPHORE; /* numreg assumed > 1 */
++
++ t.seq = tseq;
++ t.act.semaphore = &i8042tregs;
++
++ down_interruptible(&i8042tregs); /* Sleep if output regs in use. */
++
++ if (hp_sdc_enqueue_transaction(&t)) return -1;
++
++ down_interruptible(&i8042tregs); /* Sleep until results come back. */
++ up(&i8042tregs);
++
++ return (tseq[5] |
++ ((uint64_t)(tseq[10]) << 8) | ((uint64_t)(tseq[15]) << 16) |
++ ((uint64_t)(tseq[20]) << 24) | ((uint64_t)(tseq[25]) << 32));
++}
++
++
++/* Read the i8042 real-time clock */
++static inline int hp_sdc_rtc_read_rt(struct timeval *res) {
++ int64_t raw;
++ uint32_t tenms;
++ unsigned int days;
++
++ raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_RT, 5);
++ if (raw < 0) return -1;
++
++ tenms = (uint32_t)raw & 0xffffff;
++ days = (unsigned int)(raw >> 24) & 0xffff;
++
++ res->tv_usec = (suseconds_t)(tenms % 100) * 10000;
++ res->tv_sec = (time_t)(tenms / 100) + days * 86400;
++
++ return 0;
++}
++
++
++/* Read the i8042 fast handshake timer */
++static inline int hp_sdc_rtc_read_fhs(struct timeval *res) {
++ uint64_t raw;
++ unsigned int tenms;
++
++ raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_FHS, 2);
++ if (raw < 0) return -1;
++
++ tenms = (unsigned int)raw & 0xffff;
++
++ res->tv_usec = (suseconds_t)(tenms % 100) * 10000;
++ res->tv_sec = (time_t)(tenms / 100);
++
++ return 0;
++}
++
++
++/* Read the i8042 match timer (a.k.a. alarm) */
++static inline int hp_sdc_rtc_read_mt(struct timeval *res) {
++ int64_t raw;
++ uint32_t tenms;
++
++ raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_MT, 3);
++ if (raw < 0) return -1;
++
++ tenms = (uint32_t)raw & 0xffffff;
++
++ res->tv_usec = (suseconds_t)(tenms % 100) * 10000;
++ res->tv_sec = (time_t)(tenms / 100);
++
++ return 0;
++}
++
++
++/* Read the i8042 delay timer */
++static inline int hp_sdc_rtc_read_dt(struct timeval *res) {
++ int64_t raw;
++ uint32_t tenms;
++
++ raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_DT, 3);
++ if (raw < 0) return -1;
++
++ tenms = (uint32_t)raw & 0xffffff;
++
++ res->tv_usec = (suseconds_t)(tenms % 100) * 10000;
++ res->tv_sec = (time_t)(tenms / 100);
++
++ return 0;
++}
++
++
++/* Read the i8042 cycle timer (a.k.a. periodic) */
++static inline int hp_sdc_rtc_read_ct(struct timeval *res) {
++ int64_t raw;
++ uint32_t tenms;
++
++ raw = hp_sdc_rtc_read_i8042timer(HP_SDC_CMD_LOAD_CT, 3);
++ if (raw < 0) return -1;
++
++ tenms = (uint32_t)raw & 0xffffff;
++
++ res->tv_usec = (suseconds_t)(tenms % 100) * 10000;
++ res->tv_sec = (time_t)(tenms / 100);
++
++ return 0;
++}
++
++
++/* Set the i8042 real-time clock */
++static int hp_sdc_rtc_set_rt (struct timeval *setto)
++{
++ uint32_t tenms;
++ unsigned int days;
++ hp_sdc_transaction t;
++ uint8_t tseq[11] = {
++ HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT,
++ HP_SDC_CMD_SET_RTMS, 3, 0, 0, 0,
++ HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT,
++ HP_SDC_CMD_SET_RTD, 2, 0, 0
++ };
++
++ t.endidx = 10;
++
++ if (0xffff < setto->tv_sec / 86400) return -1;
++ days = setto->tv_sec / 86400;
++ if (0xffff < setto->tv_usec / 1000000 / 86400) return -1;
++ days += ((setto->tv_sec % 86400) + setto->tv_usec / 1000000) / 86400;
++ if (days > 0xffff) return -1;
++
++ if (0xffffff < setto->tv_sec) return -1;
++ tenms = setto->tv_sec * 100;
++ if (0xffffff < setto->tv_usec / 10000) return -1;
++ tenms += setto->tv_usec / 10000;
++ if (tenms > 0xffffff) return -1;
++
++ tseq[3] = (uint8_t)(tenms & 0xff);
++ tseq[4] = (uint8_t)((tenms >> 8) & 0xff);
++ tseq[5] = (uint8_t)((tenms >> 16) & 0xff);
++
++ tseq[9] = (uint8_t)(days & 0xff);
++ tseq[10] = (uint8_t)((days >> 8) & 0xff);
++
++ t.seq = tseq;
++
++ if (hp_sdc_enqueue_transaction(&t)) return -1;
++ return 0;
++}
++
++/* Set the i8042 fast handshake timer */
++static int hp_sdc_rtc_set_fhs (struct timeval *setto)
++{
++ uint32_t tenms;
++ hp_sdc_transaction t;
++ uint8_t tseq[5] = {
++ HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT,
++ HP_SDC_CMD_SET_FHS, 2, 0, 0
++ };
++
++ t.endidx = 4;
++
++ if (0xffff < setto->tv_sec) return -1;
++ tenms = setto->tv_sec * 100;
++ if (0xffff < setto->tv_usec / 10000) return -1;
++ tenms += setto->tv_usec / 10000;
++ if (tenms > 0xffff) return -1;
++
++ tseq[3] = (uint8_t)(tenms & 0xff);
++ tseq[4] = (uint8_t)((tenms >> 8) & 0xff);
++
++ t.seq = tseq;
++
++ if (hp_sdc_enqueue_transaction(&t)) return -1;
++ return 0;
++}
++
++
++/* Set the i8042 match timer (a.k.a. alarm) */
++#define hp_sdc_rtc_set_mt (setto) \
++ hp_sdc_rtc_set_i8042timer(setto, HP_SDC_CMD_SET_MT)
++
++/* Set the i8042 delay timer */
++#define hp_sdc_rtc_set_dt (setto) \
++ hp_sdc_rtc_set_i8042timer(setto, HP_SDC_CMD_SET_DT)
++
++/* Set the i8042 cycle timer (a.k.a. periodic) */
++#define hp_sdc_rtc_set_ct (setto) \
++ hp_sdc_rtc_set_i8042timer(setto, HP_SDC_CMD_SET_CT)
++
++/* Set one of the i8042 3-byte wide timers */
++static int hp_sdc_rtc_set_i8042timer (struct timeval *setto, uint8_t setcmd)
++{
++ uint32_t tenms;
++ hp_sdc_transaction t;
++ uint8_t tseq[6] = {
++ HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT,
++ 0, 3, 0, 0, 0
++ };
++
++ t.endidx = 6;
++
++ if (0xffffff < setto->tv_sec) return -1;
++ tenms = setto->tv_sec * 100;
++ if (0xffffff < setto->tv_usec / 10000) return -1;
++ tenms += setto->tv_usec / 10000;
++ if (tenms > 0xffffff) return -1;
++
++ tseq[1] = setcmd;
++ tseq[3] = (uint8_t)(tenms & 0xff);
++ tseq[4] = (uint8_t)((tenms >> 8) & 0xff);
++ tseq[5] = (uint8_t)((tenms >> 16) & 0xff);
++
++ t.seq = tseq;
++
++ if (hp_sdc_enqueue_transaction(&t)) {
++ return -1;
++ }
++ return 0;
++}
++
++static loff_t hp_sdc_rtc_llseek(struct file *file, loff_t offset, int origin)
++{
++ return -ESPIPE;
++}
++
++static ssize_t hp_sdc_rtc_read(struct file *file, char *buf,
++ size_t count, loff_t *ppos) {
++ ssize_t retval;
++
++ if (count < sizeof(unsigned long))
++ return -EINVAL;
++
++ retval = put_user(68, (unsigned long *)buf);
++ return retval;
++}
++
++static unsigned int hp_sdc_rtc_poll(struct file *file, poll_table *wait)
++{
++ unsigned long l;
++
++ l = 0;
++ if (l != 0)
++ return POLLIN | POLLRDNORM;
++ return 0;
++}
++
++static int hp_sdc_rtc_open(struct inode *inode, struct file *file)
++{
++ return 0;
++}
++
++static int hp_sdc_rtc_release(struct inode *inode, struct file *file)
++{
++ /* Turn off interrupts? */
++
++ if (file->f_flags & FASYNC) {
++ hp_sdc_rtc_fasync (-1, file, 0);
++ }
++
++ return 0;
++}
++
++static int hp_sdc_rtc_fasync (int fd, struct file *filp, int on)
++{
++ return fasync_helper (fd, filp, on, &hp_sdc_rtc_async_queue);
++}
++
++static int hp_sdc_rtc_proc_output (char *buf)
++{
++#define YN(bit) ("no")
++#define NY(bit) ("yes")
++ char *p;
++ struct rtc_time tm;
++ struct timeval tv;
++
++ memset(&tm, 0, sizeof(struct rtc_time));
++
++ p = buf;
++
++ if (hp_sdc_rtc_read_bbrtc(&tm)) {
++ p += sprintf(p, "BBRTC\t\t: READ FAILED!\n");
++ } else {
++ p += sprintf(p,
++ "rtc_time\t: %02d:%02d:%02d\n"
++ "rtc_date\t: %04d-%02d-%02d\n"
++ "rtc_epoch\t: %04lu\n",
++ tm.tm_hour, tm.tm_min, tm.tm_sec,
++ tm.tm_year + 1900, tm.tm_mon + 1,
++ tm.tm_mday, epoch);
++ }
++
++ if (hp_sdc_rtc_read_rt(&tv)) {
++ p += sprintf(p, "i8042 rtc\t: READ FAILED!\n");
++ } else {
++ p += sprintf(p, "i8042 rtc\t: %ld.%02d seconds\n",
++ tv.tv_sec, tv.tv_usec/1000);
++ }
++
++ if (hp_sdc_rtc_read_fhs(&tv)) {
++ p += sprintf(p, "handshake\t: READ FAILED!\n");
++ } else {
++ p += sprintf(p, "handshake\t: %ld.%02d seconds\n",
++ tv.tv_sec, tv.tv_usec/1000);
++ }
++
++ if (hp_sdc_rtc_read_mt(&tv)) {
++ p += sprintf(p, "alarm\t\t: READ FAILED!\n");
++ } else {
++ p += sprintf(p, "alarm\t\t: %ld.%02d seconds\n",
++ tv.tv_sec, tv.tv_usec/1000);
++ }
++
++ if (hp_sdc_rtc_read_dt(&tv)) {
++ p += sprintf(p, "delay\t\t: READ FAILED!\n");
++ } else {
++ p += sprintf(p, "delay\t\t: %ld.%02d seconds\n",
++ tv.tv_sec, tv.tv_usec/1000);
++ }
++
++ if (hp_sdc_rtc_read_ct(&tv)) {
++ p += sprintf(p, "periodic\t: READ FAILED!\n");
++ } else {
++ p += sprintf(p, "periodic\t: %ld.%02d seconds\n",
++ tv.tv_sec, tv.tv_usec/1000);
++ }
++
++ p += sprintf(p,
++ "DST_enable\t: %s\n"
++ "BCD\t\t: %s\n"
++ "24hr\t\t: %s\n"
++ "square_wave\t: %s\n"
++ "alarm_IRQ\t: %s\n"
++ "update_IRQ\t: %s\n"
++ "periodic_IRQ\t: %s\n"
++ "periodic_freq\t: %ld\n"
++ "batt_status\t: %s\n",
++ YN(RTC_DST_EN),
++ NY(RTC_DM_BINARY),
++ YN(RTC_24H),
++ YN(RTC_SQWE),
++ YN(RTC_AIE),
++ YN(RTC_UIE),
++ YN(RTC_PIE),
++ 1UL,
++ 1 ? "okay" : "dead");
++
++ return p - buf;
++#undef YN
++#undef NY
++}
++
++static int hp_sdc_rtc_read_proc(char *page, char **start, off_t off,
++ int count, int *eof, void *data)
++{
++ int len = hp_sdc_rtc_proc_output (page);
++ if (len <= off+count) *eof = 1;
++ *start = page + off;
++ len -= off;
++ if (len>count) len = count;
++ if (len<0) len = 0;
++ return len;
++}
++
++static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file,
++ unsigned int cmd, unsigned long arg)
++{
++#if 1
++ return -EINVAL;
++#else
++
++ struct rtc_time wtime;
++ struct timeval ttime;
++ int use_wtime = 0;
++
++ /* This needs major work. */
++
++ switch (cmd) {
++
++ case RTC_AIE_OFF: /* Mask alarm int. enab. bit */
++ case RTC_AIE_ON: /* Allow alarm interrupts. */
++ case RTC_PIE_OFF: /* Mask periodic int. enab. bit */
++ case RTC_PIE_ON: /* Allow periodic ints */
++ case RTC_UIE_ON: /* Allow ints for RTC updates. */
++ case RTC_UIE_OFF: /* Allow ints for RTC updates. */
++ {
++ /* We cannot mask individual user timers and we
++ cannot tell them apart when they occur, so it
++ would be disingenuous to succeed these IOCTLs */
++ return -EINVAL;
++ }
++ case RTC_ALM_READ: /* Read the present alarm time */
++ {
++ if (hp_sdc_rtc_read_mt(&ttime)) return -EFAULT;
++ if (hp_sdc_rtc_read_bbrtc(&wtime)) return -EFAULT;
++
++ wtime.tm_hour = ttime.tv_sec / 3600; ttime.tv_sec %= 3600;
++ wtime.tm_min = ttime.tv_sec / 60; ttime.tv_sec %= 60;
++ wtime.tm_sec = ttime.tv_sec;
++
++ break;
++ }
++ case RTC_IRQP_READ: /* Read the periodic IRQ rate. */
++ {
++ return put_user(hp_sdc_rtc_freq, (unsigned long *)arg);
++ }
++ case RTC_IRQP_SET: /* Set periodic IRQ rate. */
++ {
++ /*
++ * The max we can do is 100Hz.
++ */
++
++ if ((arg < 1) || (arg > 100)) return -EINVAL;
++ ttime.tv_sec = 0;
++ ttime.tv_usec = 1000000 / arg;
++ if (hp_sdc_rtc_set_ct(&ttime)) return -EFAULT;
++ hp_sdc_rtc_freq = arg;
++ return 0;
++ }
++ case RTC_ALM_SET: /* Store a time into the alarm */
++ {
++ /*
++ * This expects a struct hp_sdc_rtc_time. Writing 0xff means
++ * "don't care" or "match all" for PC timers. The HP SDC
++ * does not support that perk, but it could be emulated fairly
++ * easily. Only the tm_hour, tm_min and tm_sec are used.
++ * We could do it with 10ms accuracy with the HP SDC, if the
++ * rtc interface left us a way to do that.
++ */
++ struct hp_sdc_rtc_time alm_tm;
++
++ if (copy_from_user(&alm_tm, (struct hp_sdc_rtc_time*)arg,
++ sizeof(struct hp_sdc_rtc_time)))
++ return -EFAULT;
++
++ if (alm_tm.tm_hour > 23) return -EINVAL;
++ if (alm_tm.tm_min > 59) return -EINVAL;
++ if (alm_tm.tm_sec > 59) return -EINVAL;
++
++ ttime.sec = alm_tm.tm_hour * 3600 +
++ alm_tm.tm_min * 60 + alm_tm.tm_sec;
++ ttime.usec = 0;
++ if (hp_sdc_rtc_set_mt(&ttime)) return -EFAULT;
++ return 0;
++ }
++ case RTC_RD_TIME: /* Read the time/date from RTC */
++ {
++ if (hp_sdc_rtc_read_bbrtc(&wtime)) return -EFAULT;
++ break;
++ }
++ case RTC_SET_TIME: /* Set the RTC */
++ {
++ struct rtc_time hp_sdc_rtc_tm;
++ unsigned char mon, day, hrs, min, sec, leap_yr;
++ unsigned int yrs;
++
++ if (!capable(CAP_SYS_TIME))
++ return -EACCES;
++ if (copy_from_user(&hp_sdc_rtc_tm, (struct rtc_time *)arg,
++ sizeof(struct rtc_time)))
++ return -EFAULT;
++
++ yrs = hp_sdc_rtc_tm.tm_year + 1900;
++ mon = hp_sdc_rtc_tm.tm_mon + 1; /* tm_mon starts at zero */
++ day = hp_sdc_rtc_tm.tm_mday;
++ hrs = hp_sdc_rtc_tm.tm_hour;
++ min = hp_sdc_rtc_tm.tm_min;
++ sec = hp_sdc_rtc_tm.tm_sec;
++
++ if (yrs < 1970)
++ return -EINVAL;
++
++ leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
++
++ if ((mon > 12) || (day == 0))
++ return -EINVAL;
++ if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
++ return -EINVAL;
++ if ((hrs >= 24) || (min >= 60) || (sec >= 60))
++ return -EINVAL;
++
++ if ((yrs -= eH) > 255) /* They are unsigned */
++ return -EINVAL;
++
++
++ return 0;
++ }
++ case RTC_EPOCH_READ: /* Read the epoch. */
++ {
++ return put_user (epoch, (unsigned long *)arg);
++ }
++ case RTC_EPOCH_SET: /* Set the epoch. */
++ {
++ /*
++ * There were no RTC clocks before 1900.
++ */
++ if (arg < 1900)
++ return -EINVAL;
++ if (!capable(CAP_SYS_TIME))
++ return -EACCES;
++
++ epoch = arg;
++ return 0;
++ }
++ default:
++ return -EINVAL;
++ }
++ return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
++#endif
++}
++
++static struct file_operations hp_sdc_rtc_fops = {
++ .owner = THIS_MODULE,
++ .llseek = hp_sdc_rtc_llseek,
++ .read = hp_sdc_rtc_read,
++ .poll = hp_sdc_rtc_poll,
++ .ioctl = hp_sdc_rtc_ioctl,
++ .open = hp_sdc_rtc_open,
++ .release = hp_sdc_rtc_release,
++ .fasync = hp_sdc_rtc_fasync,
++};
++
++static struct miscdevice hp_sdc_rtc_dev = {
++ .minor = RTC_MINOR,
++ .name = "rtc_HIL",
++ .fops = &hp_sdc_rtc_fops
++};
++
++static int __init hp_sdc_rtc_init(void)
++{
++ int ret;
++
++ init_MUTEX(&i8042tregs);
++
++ if ((ret = hp_sdc_request_timer_irq(&hp_sdc_rtc_isr)))
++ return ret;
++ misc_register(&hp_sdc_rtc_dev);
++ create_proc_read_entry ("driver/rtc", 0, 0,
++ hp_sdc_rtc_read_proc, NULL);
++
++ printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support loaded "
++ "(RTC v " RTC_VERSION ")\n");
++
++ return 0;
++}
++
++static void __exit hp_sdc_rtc_exit(void)
++{
++ remove_proc_entry ("driver/rtc", NULL);
++ misc_deregister(&hp_sdc_rtc_dev);
++ hp_sdc_release_timer_irq(hp_sdc_rtc_isr);
++ printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support unloaded\n");
++}
++
++module_init(hp_sdc_rtc_init);
++module_exit(hp_sdc_rtc_exit);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/mouse/Kconfig CVS2_6_11_PA2/drivers/input/mouse/Kconfig
+--- LINUS_2_6_11/drivers/input/mouse/Kconfig 2005-03-02 04:19:08.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/mouse/Kconfig 2005-01-22 07:59:19.000000000 -0700
+@@ -129,3 +129,10 @@
+ described in the source file). This driver also works with the
+ digitizer (VSXXX-AB) DEC produced.
+
++config MOUSE_HIL
++ tristate "HIL pointers (mice etc)."
++ depends on GSC && INPUT_MOUSE
++ select HP_SDC
++ select HIL_MLC
++ help
++ Say Y here to support HIL pointers.
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/mouse/Makefile CVS2_6_11_PA2/drivers/input/mouse/Makefile
+--- LINUS_2_6_11/drivers/input/mouse/Makefile 2005-03-02 04:19:08.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/mouse/Makefile 2005-01-12 13:16:32.000000000 -0700
+@@ -12,6 +12,7 @@
+ obj-$(CONFIG_MOUSE_PC110PAD) += pc110pad.o
+ obj-$(CONFIG_MOUSE_PS2) += psmouse.o
+ obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o
++obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o
+ obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o
+
+ psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/mouse/hil_ptr.c CVS2_6_11_PA2/drivers/input/mouse/hil_ptr.c
+--- LINUS_2_6_11/drivers/input/mouse/hil_ptr.c 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/mouse/hil_ptr.c 2004-10-27 14:17:19.000000000 -0600
+@@ -0,0 +1,414 @@
++/*
++ * Generic linux-input device driver for axis-bearing devices
++ *
++ * Copyright (c) 2001 Brian S. Julin
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL").
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
++ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ *
++ * References:
++ * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
++ *
++ */
++
++#include <linux/hil.h>
++#include <linux/input.h>
++#include <linux/serio.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/pci_ids.h>
++
++#define PREFIX "HIL PTR: "
++#define HIL_GENERIC_NAME "HIL pointer device"
++
++MODULE_AUTHOR("Brian S. Julin <bri at calyx.com>");
++MODULE_DESCRIPTION(HIL_GENERIC_NAME " driver");
++MODULE_LICENSE("Dual BSD/GPL");
++
++
++#define TABLET_SIMULATES_MOUSE /* allow tablet to be used as mouse */
++#undef TABLET_AUTOADJUST /* auto-adjust valid tablet ranges */
++
++
++#define HIL_PTR_MAX_LENGTH 16
++
++struct hil_ptr {
++ struct input_dev dev;
++ struct serio *serio;
++
++ /* Input buffer and index for packets from HIL bus. */
++ hil_packet data[HIL_PTR_MAX_LENGTH];
++ int idx4; /* four counts per packet */
++
++ /* Raw device info records from HIL bus, see hil.h for fields. */
++ char idd[HIL_PTR_MAX_LENGTH]; /* DID byte and IDD record */
++ char rsc[HIL_PTR_MAX_LENGTH]; /* RSC record */
++ char exd[HIL_PTR_MAX_LENGTH]; /* EXD record */
++ char rnm[HIL_PTR_MAX_LENGTH + 1]; /* RNM record + NULL term. */
++
++ /* Extra device details not contained in struct input_dev. */
++ unsigned int nbtn, naxes;
++ unsigned int btnmap[7];
++
++ /* Something to sleep around with. */
++ struct semaphore sem;
++};
++
++/* Process a complete packet after transfer from the HIL */
++static void hil_ptr_process_record(struct hil_ptr *ptr)
++{
++ struct input_dev *dev = &ptr->dev;
++ hil_packet *data = ptr->data;
++ hil_packet p;
++ int idx, i, cnt, laxis;
++ int ax16, absdev;
++
++ idx = ptr->idx4/4;
++ p = data[idx - 1];
++
++ if ((p & ~HIL_CMDCT_POL) ==
++ (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report;
++ if ((p & ~HIL_CMDCT_RPL) ==
++ (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report;
++
++ /* Not a poll response. See if we are loading config records. */
++ switch (p & HIL_PKT_DATA_MASK) {
++ case HIL_CMD_IDD:
++ for (i = 0; i < idx; i++)
++ ptr->idd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
++ for (; i < HIL_PTR_MAX_LENGTH; i++)
++ ptr->idd[i] = 0;
++ break;
++ case HIL_CMD_RSC:
++ for (i = 0; i < idx; i++)
++ ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
++ for (; i < HIL_PTR_MAX_LENGTH; i++)
++ ptr->rsc[i] = 0;
++ break;
++ case HIL_CMD_EXD:
++ for (i = 0; i < idx; i++)
++ ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
++ for (; i < HIL_PTR_MAX_LENGTH; i++)
++ ptr->exd[i] = 0;
++ break;
++ case HIL_CMD_RNM:
++ for (i = 0; i < idx; i++)
++ ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK;
++ for (; i < HIL_PTR_MAX_LENGTH + 1; i++)
++ ptr->rnm[i] = '\0';
++ break;
++ default:
++ /* These occur when device isn't present */
++ if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break;
++ /* Anything else we'd like to know about. */
++ printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
++ break;
++ }
++ goto out;
++
++ report:
++ if ((p & HIL_CMDCT_POL) != idx - 1) {
++ printk(KERN_WARNING PREFIX "Malformed poll packet %x (idx = %i)\n", p, idx);
++ goto out;
++ }
++
++ i = (ptr->data[0] & HIL_POL_AXIS_ALT) ? 3 : 0;
++ laxis = ptr->data[0] & HIL_POL_NUM_AXES_MASK;
++ laxis += i;
++
++ ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */
++ absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS;
++
++ for (cnt = 1; i < laxis; i++) {
++ unsigned int lo,hi,val;
++ lo = ptr->data[cnt++] & HIL_PKT_DATA_MASK;
++ hi = ax16 ? (ptr->data[cnt++] & HIL_PKT_DATA_MASK) : 0;
++ if (absdev) {
++ val = lo + (hi<<8);
++#ifdef TABLET_AUTOADJUST
++ if (val < ptr->dev.absmin[ABS_X + i])
++ ptr->dev.absmin[ABS_X + i] = val;
++ if (val > ptr->dev.absmax[ABS_X + i])
++ ptr->dev.absmax[ABS_X + i] = val;
++#endif
++ if (i%3) val = ptr->dev.absmax[ABS_X + i] - val;
++ input_report_abs(dev, ABS_X + i, val);
++ } else {
++ val = (int) (((int8_t)lo) | ((int8_t)hi<<8));
++ if (i%3) val *= -1;
++ input_report_rel(dev, REL_X + i, val);
++ }
++ }
++
++ while (cnt < idx - 1) {
++ unsigned int btn;
++ int up;
++ btn = ptr->data[cnt++];
++ up = btn & 1;
++ btn &= 0xfe;
++ if (btn == 0x8e) {
++ continue; /* TODO: proximity == touch? */
++ }
++ else if ((btn > 0x8c) || (btn < 0x80)) continue;
++ btn = (btn - 0x80) >> 1;
++ btn = ptr->btnmap[btn];
++ input_report_key(dev, btn, !up);
++ }
++ input_sync(dev);
++ out:
++ ptr->idx4 = 0;
++ up(&ptr->sem);
++}
++
++static void hil_ptr_process_err(struct hil_ptr *ptr) {
++ printk(KERN_WARNING PREFIX "errored HIL packet\n");
++ ptr->idx4 = 0;
++ up(&ptr->sem);
++ return;
++}
++
++static irqreturn_t hil_ptr_interrupt(struct serio *serio,
++ unsigned char data, unsigned int flags, struct pt_regs *regs)
++{
++ struct hil_ptr *ptr;
++ hil_packet packet;
++ int idx;
++
++ ptr = (struct hil_ptr *)serio->private;
++ if (ptr == NULL) {
++ BUG();
++ return IRQ_HANDLED;
++ }
++
++ if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) {
++ hil_ptr_process_err(ptr);
++ return IRQ_HANDLED;
++ }
++ idx = ptr->idx4/4;
++ if (!(ptr->idx4 % 4)) ptr->data[idx] = 0;
++ packet = ptr->data[idx];
++ packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8);
++ ptr->data[idx] = packet;
++
++ /* Records of N 4-byte hil_packets must terminate with a command. */
++ if ((++(ptr->idx4)) % 4) return IRQ_HANDLED;
++ if ((packet & 0xffff0000) != HIL_ERR_INT) {
++ hil_ptr_process_err(ptr);
++ return IRQ_HANDLED;
++ }
++ if (packet & HIL_PKT_CMD)
++ hil_ptr_process_record(ptr);
++ return IRQ_HANDLED;
++}
++
++static void hil_ptr_disconnect(struct serio *serio)
++{
++ struct hil_ptr *ptr;
++
++ ptr = (struct hil_ptr *)serio->private;
++ if (ptr == NULL) {
++ BUG();
++ return;
++ }
++
++ input_unregister_device(&ptr->dev);
++ serio_close(serio);
++ kfree(ptr);
++}
++
++static void hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
++{
++ struct hil_ptr *ptr;
++ char *txt;
++ unsigned int i, naxsets, btntype;
++ uint8_t did, *idd;
++
++ if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return;
++
++ if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return;
++ memset(ptr, 0, sizeof(struct hil_ptr));
++
++ if (serio_open(serio, driver)) goto bail0;
++
++ serio->private = ptr;
++ ptr->serio = serio;
++ ptr->dev.private = ptr;
++
++ init_MUTEX_LOCKED(&(ptr->sem));
++
++ /* Get device info. MLC driver supplies devid/status/etc. */
++ serio->write(serio, 0);
++ serio->write(serio, 0);
++ serio->write(serio, HIL_PKT_CMD >> 8);
++ serio->write(serio, HIL_CMD_IDD);
++ down(&(ptr->sem));
++
++ serio->write(serio, 0);
++ serio->write(serio, 0);
++ serio->write(serio, HIL_PKT_CMD >> 8);
++ serio->write(serio, HIL_CMD_RSC);
++ down(&(ptr->sem));
++
++ serio->write(serio, 0);
++ serio->write(serio, 0);
++ serio->write(serio, HIL_PKT_CMD >> 8);
++ serio->write(serio, HIL_CMD_RNM);
++ down(&(ptr->sem));
++
++ serio->write(serio, 0);
++ serio->write(serio, 0);
++ serio->write(serio, HIL_PKT_CMD >> 8);
++ serio->write(serio, HIL_CMD_EXD);
++ down(&(ptr->sem));
++
++ up(&(ptr->sem));
++
++ init_input_dev(&ptr->dev);
++ did = ptr->idd[0];
++ idd = ptr->idd + 1;
++ txt = "unknown";
++ if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
++ ptr->dev.evbit[0] = BIT(EV_REL);
++ txt = "relative";
++ }
++
++ if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) {
++ ptr->dev.evbit[0] = BIT(EV_ABS);
++ txt = "absolute";
++ }
++ if (!ptr->dev.evbit[0]) {
++ goto bail1;
++ }
++
++ ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
++ if (ptr->nbtn) ptr->dev.evbit[0] |= BIT(EV_KEY);
++
++ naxsets = HIL_IDD_NUM_AXSETS(*idd);
++ ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
++
++ printk(KERN_INFO PREFIX "HIL pointer device found (did: 0x%02x, axis: %s)\n",
++ did, txt);
++ printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n",
++ ptr->nbtn, naxsets, ptr->naxes);
++
++ btntype = BTN_MISC;
++ if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET)
++#ifdef TABLET_SIMULATES_MOUSE
++ btntype = BTN_TOUCH;
++#else
++ btntype = BTN_DIGI;
++#endif
++ if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN)
++ btntype = BTN_TOUCH;
++
++ if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE)
++ btntype = BTN_MOUSE;
++
++ for (i = 0; i < ptr->nbtn; i++) {
++ set_bit(btntype | i, ptr->dev.keybit);
++ ptr->btnmap[i] = btntype | i;
++ }
++
++ if (btntype == BTN_MOUSE) {
++ /* Swap buttons 2 and 3 */
++ ptr->btnmap[1] = BTN_MIDDLE;
++ ptr->btnmap[2] = BTN_RIGHT;
++ }
++
++ if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
++ for (i = 0; i < ptr->naxes; i++) {
++ set_bit(REL_X + i, ptr->dev.relbit);
++ }
++ for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
++ set_bit(REL_X + i, ptr->dev.relbit);
++ }
++ } else {
++ for (i = 0; i < ptr->naxes; i++) {
++ set_bit(ABS_X + i, ptr->dev.absbit);
++ ptr->dev.absmin[ABS_X + i] = 0;
++ ptr->dev.absmax[ABS_X + i] =
++ HIL_IDD_AXIS_MAX((ptr->idd + 1), i);
++ }
++ for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
++ set_bit(ABS_X + i, ptr->dev.absbit);
++ ptr->dev.absmin[ABS_X + i] = 0;
++ ptr->dev.absmax[ABS_X + i] =
++ HIL_IDD_AXIS_MAX((ptr->idd + 1), (i - 3));
++ }
++#ifdef TABLET_AUTOADJUST
++ for (i = 0; i < ABS_MAX; i++) {
++ int diff = ptr->dev.absmax[ABS_X + i] / 10;
++ ptr->dev.absmin[ABS_X + i] += diff;
++ ptr->dev.absmax[ABS_X + i] -= diff;
++ }
++#endif
++ }
++
++ ptr->dev.name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME;
++
++ ptr->dev.id.bustype = BUS_HIL;
++ ptr->dev.id.vendor = PCI_VENDOR_ID_HP;
++ ptr->dev.id.product = 0x0001; /* TODO: get from ptr->rsc */
++ ptr->dev.id.version = 0x0100; /* TODO: get from ptr->rsc */
++ ptr->dev.dev = &serio->dev;
++
++ input_register_device(&ptr->dev);
++ printk(KERN_INFO "input: %s (%s), ID: %d\n",
++ ptr->dev.name,
++ (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
++ did);
++
++ return;
++ bail1:
++ serio_close(serio);
++ bail0:
++ kfree(ptr);
++ return;
++}
++
++
++static struct serio_driver hil_ptr_serio_driver = {
++ .driver = {
++ .name = "hil_ptr",
++ },
++ .description = "HP HIL mouse/tablet driver",
++ .connect = hil_ptr_connect,
++ .disconnect = hil_ptr_disconnect,
++ .interrupt = hil_ptr_interrupt
++};
++
++static int __init hil_ptr_init(void)
++{
++ serio_register_driver(&hil_ptr_serio_driver);
++ return 0;
++}
++
++static void __exit hil_ptr_exit(void)
++{
++ serio_unregister_driver(&hil_ptr_serio_driver);
++}
++
++module_init(hil_ptr_init);
++module_exit(hil_ptr_exit);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/serio/Kconfig CVS2_6_11_PA2/drivers/input/serio/Kconfig
+--- LINUS_2_6_11/drivers/input/serio/Kconfig 2005-03-02 04:19:09.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/serio/Kconfig 2005-01-12 13:16:32.000000000 -0700
+@@ -48,8 +48,7 @@
+
+ config SERIO_CT82C710
+ tristate "ct82c710 Aux port controller"
+- depends on SERIO
+- depends on !PARISC
++ depends on X86 && SERIO
+ ---help---
+ Say Y here if you have a Texas Instruments TravelMate notebook
+ equipped with the ct82c710 chip and want to use a mouse connected
+@@ -111,6 +110,32 @@
+ To compile this driver as a module, choose M here: the
+ module will be called gscps2.
+
++config HP_SDC
++ tristate "HP System Device Controller i8042 Support"
++ depends on GSC && SERIO
++ default y
++ ---help---
++ This option enables supports for the the "System Device
++ Controller", an i8042 carrying microcode to manage a
++ few miscellanous devices on some Hewlett Packard systems.
++ The SDC itself contains a 10ms resolution timer/clock capable
++ of delivering interrupts on a periodic and one-shot basis.
++ The SDC may also be connected to a battery-backed real-time
++ clock, a basic audio waveform generator, and an HP-HIL Master
++ Link Controller serving up to seven input devices.
++
++ By itself this option is rather useless, but enabling it will
++ enable selection of drivers for the abovementioned devices.
++ It is, however, incompatible with the old, reliable HIL keyboard
++ driver, and the new HIL driver is experimental, so if you plan
++ to use a HIL keyboard as your primary keyboard, you may wish
++ to keep using that driver until the new HIL drivers have had
++ more testing.
++
++config HIL_MLC
++ tristate "HIL MLC Support (needed for HIL input devices)"
++ depends on HP_SDC
++
+ config SERIO_PCIPS2
+ tristate "PCI PS/2 keyboard and PS/2 mouse controller"
+ depends on PCI && SERIO
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/serio/Makefile CVS2_6_11_PA2/drivers/input/serio/Makefile
+--- LINUS_2_6_11/drivers/input/serio/Makefile 2005-03-02 04:19:09.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/serio/Makefile 2005-01-12 13:16:32.000000000 -0700
+@@ -2,8 +2,6 @@
+ # Makefile for the input core drivers.
+ #
+
+-# Each configuration option enables a list of files.
+-
+ obj-$(CONFIG_SERIO) += serio.o
+ obj-$(CONFIG_SERIO_I8042) += i8042.o
+ obj-$(CONFIG_SERIO_PARKBD) += parkbd.o
+@@ -15,6 +13,8 @@
+ obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o
+ obj-$(CONFIG_SERIO_98KBD) += 98kbd-io.o
+ obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o
++obj-$(CONFIG_HP_SDC) += hp_sdc.o
++obj-$(CONFIG_HIL_MLC) += hp_sdc_mlc.o hil_mlc.o
+ obj-$(CONFIG_SERIO_PCIPS2) += pcips2.o
+ obj-$(CONFIG_SERIO_MACEPS2) += maceps2.o
+ obj-$(CONFIG_SERIO_LIBPS2) += libps2.o
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/serio/gscps2.c CVS2_6_11_PA2/drivers/input/serio/gscps2.c
+--- LINUS_2_6_11/drivers/input/serio/gscps2.c 2005-03-02 04:19:09.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/serio/gscps2.c 2005-01-13 08:38:43.000000000 -0700
+@@ -3,7 +3,7 @@
+ *
+ * Copyright (c) 2004 Helge Deller <deller at gmx.de>
+ * Copyright (c) 2002 Laurent Canet <canetl at esiee.fr>
+- * Copyright (c) 2002 Thibaut Varene <varenet at esiee.fr>
++ * Copyright (c) 2002 Thibaut Varene <varenet at parisc-linux.org>
+ *
+ * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c
+ * Copyright (c) 1999 Alex deVries <alex at onefishtwo.ca>
+@@ -37,8 +37,8 @@
+ #include <asm/io.h>
+ #include <asm/parisc-device.h>
+
+-MODULE_AUTHOR("Laurent Canet <canetl at esiee.fr>, Thibaut Varene <varenet at esiee.fr>, Helge Deller <deller at gmx.de>");
+-MODULE_DESCRIPTION("HP GSC PS/2 port driver");
++MODULE_AUTHOR("Laurent Canet <canetl at esiee.fr>, Thibaut Varene <varenet at parisc-linux.org>, Helge Deller <deller at gmx.de>");
++MODULE_DESCRIPTION("HP GSC PS2 port driver");
+ MODULE_LICENSE("GPL");
+ MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
+
+@@ -448,7 +448,7 @@
+ };
+
+ static struct parisc_driver parisc_ps2_driver = {
+- .name = "GSC PS/2",
++ .name = "GSC PS2",
+ .id_table = gscps2_device_tbl,
+ .probe = gscps2_probe,
+ .remove = gscps2_remove,
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/serio/hil_mlc.c CVS2_6_11_PA2/drivers/input/serio/hil_mlc.c
+--- LINUS_2_6_11/drivers/input/serio/hil_mlc.c 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/serio/hil_mlc.c 2004-10-30 13:51:50.000000000 -0600
+@@ -0,0 +1,949 @@
++/*
++ * HIL MLC state machine and serio interface driver
++ *
++ * Copyright (c) 2001 Brian S. Julin
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL").
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
++ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ *
++ * References:
++ * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
++ *
++ *
++ * Driver theory of operation:
++ *
++ * Some access methods and an ISR is defined by the sub-driver
++ * (e.g. hp_sdc_mlc.c). These methods are expected to provide a
++ * few bits of logic in addition to raw access to the HIL MLC,
++ * specifically, the ISR, which is entirely registered by the
++ * sub-driver and invoked directly, must check for record
++ * termination or packet match, at which point a semaphore must
++ * be cleared and then the hil_mlcs_tasklet must be scheduled.
++ *
++ * The hil_mlcs_tasklet processes the state machine for all MLCs
++ * each time it runs, checking each MLC's progress at the current
++ * node in the state machine, and moving the MLC to subsequent nodes
++ * in the state machine when appropriate. It will reschedule
++ * itself if output is pending. (This rescheduling should be replaced
++ * at some point with a sub-driver-specific mechanism.)
++ *
++ * A timer task prods the tasklet once per second to prevent
++ * hangups when attached devices do not return expected data
++ * and to initiate probes of the loop for new devices.
++ */
++
++#include <linux/hil_mlc.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/timer.h>
++#include <linux/sched.h>
++#include <linux/list.h>
++
++MODULE_AUTHOR("Brian S. Julin <bri at calyx.com>");
++MODULE_DESCRIPTION("HIL MLC serio");
++MODULE_LICENSE("Dual BSD/GPL");
++
++EXPORT_SYMBOL(hil_mlc_register);
++EXPORT_SYMBOL(hil_mlc_unregister);
++
++#define PREFIX "HIL MLC: "
++
++static LIST_HEAD(hil_mlcs);
++static rwlock_t hil_mlcs_lock = RW_LOCK_UNLOCKED;
++static struct timer_list hil_mlcs_kicker;
++static int hil_mlcs_probe;
++
++static void hil_mlcs_process(unsigned long unused);
++DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0);
++
++
++/* #define HIL_MLC_DEBUG */
++
++/********************** Device info/instance management **********************/
++
++static void hil_mlc_clear_di_map (hil_mlc *mlc, int val) {
++ int j;
++ for (j = val; j < 7 ; j++) {
++ mlc->di_map[j] = -1;
++ }
++}
++
++static void hil_mlc_clear_di_scratch (hil_mlc *mlc) {
++ memset(&(mlc->di_scratch), 0, sizeof(mlc->di_scratch));
++}
++
++static void hil_mlc_copy_di_scratch (hil_mlc *mlc, int idx) {
++ memcpy(&(mlc->di[idx]), &(mlc->di_scratch), sizeof(mlc->di_scratch));
++}
++
++static int hil_mlc_match_di_scratch (hil_mlc *mlc) {
++ int idx;
++
++ for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) {
++ int j, found;
++
++ /* In-use slots are not eligible. */
++ found = 0;
++ for (j = 0; j < 7 ; j++) {
++ if (mlc->di_map[j] == idx) found++;
++ }
++ if (found) continue;
++ if (!memcmp(mlc->di + idx,
++ &(mlc->di_scratch),
++ sizeof(mlc->di_scratch))) break;
++ }
++ return((idx >= HIL_MLC_DEVMEM) ? -1 : idx);
++}
++
++static int hil_mlc_find_free_di(hil_mlc *mlc) {
++ int idx;
++ /* TODO: Pick all-zero slots first, failing that,
++ * randomize the slot picked among those eligible.
++ */
++ for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) {
++ int j, found;
++ found = 0;
++ for (j = 0; j < 7 ; j++) {
++ if (mlc->di_map[j] == idx) found++;
++ }
++ if (!found) break;
++ }
++ return(idx); /* Note: It is guaranteed at least one above will match */
++}
++
++static inline void hil_mlc_clean_serio_map(hil_mlc *mlc) {
++ int idx;
++ for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) {
++ int j, found;
++ found = 0;
++ for (j = 0; j < 7 ; j++) {
++ if (mlc->di_map[j] == idx) found++;
++ }
++ if (!found) mlc->serio_map[idx].di_revmap = -1;
++ }
++}
++
++static void hil_mlc_send_polls(hil_mlc *mlc) {
++ int did, i, cnt;
++ struct serio *serio;
++ struct serio_driver *drv;
++
++ i = cnt = 0;
++ did = (mlc->ipacket[0] & HIL_PKT_ADDR_MASK) >> 8;
++ serio = did ? mlc->serio[mlc->di_map[did - 1]] : NULL;
++ drv = (serio != NULL) ? serio->drv : NULL;
++
++ while (mlc->icount < 15 - i) {
++ hil_packet p;
++ p = mlc->ipacket[i];
++ if (did != (p & HIL_PKT_ADDR_MASK) >> 8) {
++ if (drv == NULL || drv->interrupt == NULL) goto skip;
++
++ drv->interrupt(serio, 0, 0, NULL);
++ drv->interrupt(serio, HIL_ERR_INT >> 16, 0, NULL);
++ drv->interrupt(serio, HIL_PKT_CMD >> 8, 0, NULL);
++ drv->interrupt(serio, HIL_CMD_POL + cnt, 0, NULL);
++ skip:
++ did = (p & HIL_PKT_ADDR_MASK) >> 8;
++ serio = did ? mlc->serio[mlc->di_map[did-1]] : NULL;
++ drv = (serio != NULL) ? serio->drv : NULL;
++ cnt = 0;
++ }
++ cnt++; i++;
++ if (drv == NULL || drv->interrupt == NULL) continue;
++ drv->interrupt(serio, (p >> 24), 0, NULL);
++ drv->interrupt(serio, (p >> 16) & 0xff, 0, NULL);
++ drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0, NULL);
++ drv->interrupt(serio, p & 0xff, 0, NULL);
++ }
++}
++
++/*************************** State engine *********************************/
++
++#define HILSEN_SCHED 0x000100 /* Schedule the tasklet */
++#define HILSEN_BREAK 0x000200 /* Wait until next pass */
++#define HILSEN_UP 0x000400 /* relative node#, decrement */
++#define HILSEN_DOWN 0x000800 /* relative node#, increment */
++#define HILSEN_FOLLOW 0x001000 /* use retval as next node# */
++
++#define HILSEN_MASK 0x0000ff
++#define HILSEN_START 0
++#define HILSEN_RESTART 1
++#define HILSEN_DHR 9
++#define HILSEN_DHR2 10
++#define HILSEN_IFC 14
++#define HILSEN_HEAL0 16
++#define HILSEN_HEAL 18
++#define HILSEN_ACF 21
++#define HILSEN_ACF2 22
++#define HILSEN_DISC0 25
++#define HILSEN_DISC 27
++#define HILSEN_MATCH 40
++#define HILSEN_OPERATE 41
++#define HILSEN_PROBE 44
++#define HILSEN_DSR 52
++#define HILSEN_REPOLL 55
++#define HILSEN_IFCACF 58
++#define HILSEN_END 60
++
++#define HILSEN_NEXT (HILSEN_DOWN | 1)
++#define HILSEN_SAME (HILSEN_DOWN | 0)
++#define HILSEN_LAST (HILSEN_UP | 1)
++
++#define HILSEN_DOZE (HILSEN_SAME | HILSEN_SCHED | HILSEN_BREAK)
++#define HILSEN_SLEEP (HILSEN_SAME | HILSEN_BREAK)
++
++static int hilse_match(hil_mlc *mlc, int unused) {
++ int rc;
++ rc = hil_mlc_match_di_scratch(mlc);
++ if (rc == -1) {
++ rc = hil_mlc_find_free_di(mlc);
++ if (rc == -1) goto err;
++#ifdef HIL_MLC_DEBUG
++ printk(KERN_DEBUG PREFIX "new in slot %i\n", rc);
++#endif
++ hil_mlc_copy_di_scratch(mlc, rc);
++ mlc->di_map[mlc->ddi] = rc;
++ mlc->serio_map[rc].di_revmap = mlc->ddi;
++ hil_mlc_clean_serio_map(mlc);
++ serio_rescan(mlc->serio[rc]);
++ return -1;
++ }
++ mlc->di_map[mlc->ddi] = rc;
++#ifdef HIL_MLC_DEBUG
++ printk(KERN_DEBUG PREFIX "same in slot %i\n", rc);
++#endif
++ mlc->serio_map[rc].di_revmap = mlc->ddi;
++ hil_mlc_clean_serio_map(mlc);
++ return 0;
++ err:
++ printk(KERN_ERR PREFIX "Residual device slots exhausted, close some serios!\n");
++ return 1;
++}
++
++/* An LCV used to prevent runaway loops, forces 5 second sleep when reset. */
++static int hilse_init_lcv(hil_mlc *mlc, int unused) {
++ struct timeval tv;
++
++ do_gettimeofday(&tv);
++
++ if(mlc->lcv == 0) goto restart; /* First init, no need to dally */
++ if(tv.tv_sec - mlc->lcv_tv.tv_sec < 5) return -1;
++ restart:
++ mlc->lcv_tv = tv;
++ mlc->lcv = 0;
++ return 0;
++}
++
++static int hilse_inc_lcv(hil_mlc *mlc, int lim) {
++ if (mlc->lcv++ >= lim) return -1;
++ return 0;
++}
++
++#if 0
++static int hilse_set_lcv(hil_mlc *mlc, int val) {
++ mlc->lcv = val;
++ return 0;
++}
++#endif
++
++/* Management of the discovered device index (zero based, -1 means no devs) */
++static int hilse_set_ddi(hil_mlc *mlc, int val) {
++ mlc->ddi = val;
++ hil_mlc_clear_di_map(mlc, val + 1);
++ return 0;
++}
++
++static int hilse_dec_ddi(hil_mlc *mlc, int unused) {
++ mlc->ddi--;
++ if (mlc->ddi <= -1) {
++ mlc->ddi = -1;
++ hil_mlc_clear_di_map(mlc, 0);
++ return -1;
++ }
++ hil_mlc_clear_di_map(mlc, mlc->ddi + 1);
++ return 0;
++}
++
++static int hilse_inc_ddi(hil_mlc *mlc, int unused) {
++ if (mlc->ddi >= 6) {
++ BUG();
++ return -1;
++ }
++ mlc->ddi++;
++ return 0;
++}
++
++static int hilse_take_idd(hil_mlc *mlc, int unused) {
++ int i;
++
++ /* Help the state engine:
++ * Is this a real IDD response or just an echo?
++ *
++ * Real IDD response does not start with a command.
++ */
++ if (mlc->ipacket[0] & HIL_PKT_CMD) goto bail;
++ /* Should have the command echoed further down. */
++ for (i = 1; i < 16; i++) {
++ if (((mlc->ipacket[i] & HIL_PKT_ADDR_MASK) ==
++ (mlc->ipacket[0] & HIL_PKT_ADDR_MASK)) &&
++ (mlc->ipacket[i] & HIL_PKT_CMD) &&
++ ((mlc->ipacket[i] & HIL_PKT_DATA_MASK) == HIL_CMD_IDD))
++ break;
++ }
++ if (i > 15) goto bail;
++ /* And the rest of the packets should still be clear. */
++ while (++i < 16) {
++ if (mlc->ipacket[i]) break;
++ }
++ if (i < 16) goto bail;
++ for (i = 0; i < 16; i++) {
++ mlc->di_scratch.idd[i] =
++ mlc->ipacket[i] & HIL_PKT_DATA_MASK;
++ }
++ /* Next step is to see if RSC supported */
++ if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_RSC)
++ return HILSEN_NEXT;
++ if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD)
++ return HILSEN_DOWN | 4;
++ return 0;
++ bail:
++ mlc->ddi--;
++ return -1; /* This should send us off to ACF */
++}
++
++static int hilse_take_rsc(hil_mlc *mlc, int unused) {
++ int i;
++
++ for (i = 0; i < 16; i++) {
++ mlc->di_scratch.rsc[i] =
++ mlc->ipacket[i] & HIL_PKT_DATA_MASK;
++ }
++ /* Next step is to see if EXD supported (IDD has already been read) */
++ if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD)
++ return HILSEN_NEXT;
++ return 0;
++}
++
++static int hilse_take_exd(hil_mlc *mlc, int unused) {
++ int i;
++
++ for (i = 0; i < 16; i++) {
++ mlc->di_scratch.exd[i] =
++ mlc->ipacket[i] & HIL_PKT_DATA_MASK;
++ }
++ /* Next step is to see if RNM supported. */
++ if (mlc->di_scratch.exd[0] & HIL_EXD_HEADER_RNM)
++ return HILSEN_NEXT;
++ return 0;
++}
++
++static int hilse_take_rnm(hil_mlc *mlc, int unused) {
++ int i;
++
++ for (i = 0; i < 16; i++) {
++ mlc->di_scratch.rnm[i] =
++ mlc->ipacket[i] & HIL_PKT_DATA_MASK;
++ }
++ do {
++ char nam[17];
++ snprintf(nam, 16, "%s", mlc->di_scratch.rnm);
++ nam[16] = '\0';
++ printk(KERN_INFO PREFIX "Device name gotten: %s\n", nam);
++ } while (0);
++ return 0;
++}
++
++static int hilse_operate(hil_mlc *mlc, int repoll) {
++
++ if (mlc->opercnt == 0) hil_mlcs_probe = 0;
++ mlc->opercnt = 1;
++
++ hil_mlc_send_polls(mlc);
++
++ if (!hil_mlcs_probe) return 0;
++ hil_mlcs_probe = 0;
++ mlc->opercnt = 0;
++ return 1;
++}
++
++#define FUNC(funct, funct_arg, zero_rc, neg_rc, pos_rc) \
++{ HILSE_FUNC, { func: &funct }, funct_arg, zero_rc, neg_rc, pos_rc },
++#define OUT(pack) \
++{ HILSE_OUT, { packet: pack }, 0, HILSEN_NEXT, HILSEN_DOZE, 0 },
++#define CTS \
++{ HILSE_CTS, { packet: 0 }, 0, HILSEN_NEXT | HILSEN_SCHED | HILSEN_BREAK, HILSEN_DOZE, 0 },
++#define EXPECT(comp, to, got, got_wrong, timed_out) \
++{ HILSE_EXPECT, { packet: comp }, to, got, got_wrong, timed_out },
++#define EXPECT_LAST(comp, to, got, got_wrong, timed_out) \
++{ HILSE_EXPECT_LAST, { packet: comp }, to, got, got_wrong, timed_out },
++#define EXPECT_DISC(comp, to, got, got_wrong, timed_out) \
++{ HILSE_EXPECT_DISC, { packet: comp }, to, got, got_wrong, timed_out },
++#define IN(to, got, got_error, timed_out) \
++{ HILSE_IN, { packet: 0 }, to, got, got_error, timed_out },
++#define OUT_DISC(pack) \
++{ HILSE_OUT_DISC, { packet: pack }, 0, 0, 0, 0 },
++#define OUT_LAST(pack) \
++{ HILSE_OUT_LAST, { packet: pack }, 0, 0, 0, 0 },
++
++struct hilse_node hil_mlc_se[HILSEN_END] = {
++
++ /* 0 HILSEN_START */
++ FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0)
++
++ /* 1 HILSEN_RESTART */
++ FUNC(hilse_inc_lcv, 10, HILSEN_NEXT, HILSEN_START, 0)
++ OUT(HIL_CTRL_ONLY) /* Disable APE */
++ CTS
++
++#define TEST_PACKET(x) \
++(HIL_PKT_CMD | (x << HIL_PKT_ADDR_SHIFT) | x << 4 | x)
++
++ OUT(HIL_DO_ALTER_CTRL | HIL_CTRL_TEST | TEST_PACKET(0x5))
++ EXPECT(HIL_ERR_INT | TEST_PACKET(0x5),
++ 2000, HILSEN_NEXT, HILSEN_RESTART, HILSEN_RESTART)
++ OUT(HIL_DO_ALTER_CTRL | HIL_CTRL_TEST | TEST_PACKET(0xa))
++ EXPECT(HIL_ERR_INT | TEST_PACKET(0xa),
++ 2000, HILSEN_NEXT, HILSEN_RESTART, HILSEN_RESTART)
++ OUT(HIL_CTRL_ONLY | 0) /* Disable test mode */
++
++ /* 9 HILSEN_DHR */
++ FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0)
++
++ /* 10 HILSEN_DHR2 */
++ FUNC(hilse_inc_lcv, 10, HILSEN_NEXT, HILSEN_START, 0)
++ FUNC(hilse_set_ddi, -1, HILSEN_NEXT, 0, 0)
++ OUT(HIL_PKT_CMD | HIL_CMD_DHR)
++ IN(300000, HILSEN_DHR2, HILSEN_DHR2, HILSEN_NEXT)
++
++ /* 14 HILSEN_IFC */
++ OUT(HIL_PKT_CMD | HIL_CMD_IFC)
++ EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT,
++ 20000, HILSEN_DISC, HILSEN_DHR2, HILSEN_NEXT )
++
++ /* If devices are there, they weren't in PUP or other loopback mode.
++ * We're more concerned at this point with restoring operation
++ * to devices than discovering new ones, so we try to salvage
++ * the loop configuration by closing off the loop.
++ */
++
++ /* 16 HILSEN_HEAL0 */
++ FUNC(hilse_dec_ddi, 0, HILSEN_NEXT, HILSEN_ACF, 0)
++ FUNC(hilse_inc_ddi, 0, HILSEN_NEXT, 0, 0)
++
++ /* 18 HILSEN_HEAL */
++ OUT_LAST(HIL_CMD_ELB)
++ EXPECT_LAST(HIL_CMD_ELB | HIL_ERR_INT,
++ 20000, HILSEN_REPOLL, HILSEN_DSR, HILSEN_NEXT)
++ FUNC(hilse_dec_ddi, 0, HILSEN_HEAL, HILSEN_NEXT, 0)
++
++ /* 21 HILSEN_ACF */
++ FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_DOZE, 0)
++
++ /* 22 HILSEN_ACF2 */
++ FUNC(hilse_inc_lcv, 10, HILSEN_NEXT, HILSEN_START, 0)
++ OUT(HIL_PKT_CMD | HIL_CMD_ACF | 1)
++ IN(20000, HILSEN_NEXT, HILSEN_DSR, HILSEN_NEXT)
++
++ /* 25 HILSEN_DISC0 */
++ OUT_DISC(HIL_PKT_CMD | HIL_CMD_ELB)
++ EXPECT_DISC(HIL_PKT_CMD | HIL_CMD_ELB | HIL_ERR_INT,
++ 20000, HILSEN_NEXT, HILSEN_DSR, HILSEN_DSR)
++
++ /* Only enter here if response just received */
++ /* 27 HILSEN_DISC */
++ OUT_DISC(HIL_PKT_CMD | HIL_CMD_IDD)
++ EXPECT_DISC(HIL_PKT_CMD | HIL_CMD_IDD | HIL_ERR_INT,
++ 20000, HILSEN_NEXT, HILSEN_DSR, HILSEN_START)
++ FUNC(hilse_inc_ddi, 0, HILSEN_NEXT, HILSEN_START, 0)
++ FUNC(hilse_take_idd, 0, HILSEN_MATCH, HILSEN_IFCACF, HILSEN_FOLLOW)
++ OUT_LAST(HIL_PKT_CMD | HIL_CMD_RSC)
++ EXPECT_LAST(HIL_PKT_CMD | HIL_CMD_RSC | HIL_ERR_INT,
++ 30000, HILSEN_NEXT, HILSEN_DSR, HILSEN_DSR)
++ FUNC(hilse_take_rsc, 0, HILSEN_MATCH, 0, HILSEN_FOLLOW)
++ OUT_LAST(HIL_PKT_CMD | HIL_CMD_EXD)
++ EXPECT_LAST(HIL_PKT_CMD | HIL_CMD_EXD | HIL_ERR_INT,
++ 30000, HILSEN_NEXT, HILSEN_DSR, HILSEN_DSR)
++ FUNC(hilse_take_exd, 0, HILSEN_MATCH, 0, HILSEN_FOLLOW)
++ OUT_LAST(HIL_PKT_CMD | HIL_CMD_RNM)
++ EXPECT_LAST(HIL_PKT_CMD | HIL_CMD_RNM | HIL_ERR_INT,
++ 30000, HILSEN_NEXT, HILSEN_DSR, HILSEN_DSR)
++ FUNC(hilse_take_rnm, 0, HILSEN_MATCH, 0, 0)
++
++ /* 40 HILSEN_MATCH */
++ FUNC(hilse_match, 0, HILSEN_NEXT, HILSEN_NEXT, /* TODO */ 0)
++
++ /* 41 HILSEN_OPERATE */
++ OUT(HIL_PKT_CMD | HIL_CMD_POL)
++ EXPECT(HIL_PKT_CMD | HIL_CMD_POL | HIL_ERR_INT,
++ 20000, HILSEN_NEXT, HILSEN_DSR, HILSEN_NEXT)
++ FUNC(hilse_operate, 0, HILSEN_OPERATE, HILSEN_IFC, HILSEN_NEXT)
++
++ /* 44 HILSEN_PROBE */
++ OUT_LAST(HIL_PKT_CMD | HIL_CMD_EPT)
++ IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT)
++ OUT_DISC(HIL_PKT_CMD | HIL_CMD_ELB)
++ IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT)
++ OUT(HIL_PKT_CMD | HIL_CMD_ACF | 1)
++ IN(10000, HILSEN_DISC0, HILSEN_DSR, HILSEN_NEXT)
++ OUT_LAST(HIL_PKT_CMD | HIL_CMD_ELB)
++ IN(10000, HILSEN_OPERATE, HILSEN_DSR, HILSEN_DSR)
++
++ /* 52 HILSEN_DSR */
++ FUNC(hilse_set_ddi, -1, HILSEN_NEXT, 0, 0)
++ OUT(HIL_PKT_CMD | HIL_CMD_DSR)
++ IN(20000, HILSEN_DHR, HILSEN_DHR, HILSEN_IFC)
++
++ /* 55 HILSEN_REPOLL */
++ OUT(HIL_PKT_CMD | HIL_CMD_RPL)
++ EXPECT(HIL_PKT_CMD | HIL_CMD_RPL | HIL_ERR_INT,
++ 20000, HILSEN_NEXT, HILSEN_DSR, HILSEN_NEXT)
++ FUNC(hilse_operate, 1, HILSEN_OPERATE, HILSEN_IFC, HILSEN_PROBE)
++
++ /* 58 HILSEN_IFCACF */
++ OUT(HIL_PKT_CMD | HIL_CMD_IFC)
++ EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT,
++ 20000, HILSEN_ACF2, HILSEN_DHR2, HILSEN_HEAL)
++
++ /* 60 HILSEN_END */
++};
++
++static inline void hilse_setup_input(hil_mlc *mlc, struct hilse_node *node) {
++
++ switch (node->act) {
++ case HILSE_EXPECT_DISC:
++ mlc->imatch = node->object.packet;
++ mlc->imatch |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT);
++ break;
++ case HILSE_EXPECT_LAST:
++ mlc->imatch = node->object.packet;
++ mlc->imatch |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT);
++ break;
++ case HILSE_EXPECT:
++ mlc->imatch = node->object.packet;
++ break;
++ case HILSE_IN:
++ mlc->imatch = 0;
++ break;
++ default:
++ BUG();
++ }
++ mlc->istarted = 1;
++ mlc->intimeout = node->arg;
++ do_gettimeofday(&(mlc->instart));
++ mlc->icount = 15;
++ memset(mlc->ipacket, 0, 16 * sizeof(hil_packet));
++ if (down_trylock(&(mlc->isem))) BUG();
++
++ return;
++}
++
++#ifdef HIL_MLC_DEBUG
++static int doze = 0;
++static int seidx; /* For debug */
++static int kick = 1;
++#endif
++
++static int hilse_donode (hil_mlc *mlc) {
++ struct hilse_node *node;
++ int nextidx = 0;
++ int sched_long = 0;
++ unsigned long flags;
++
++#ifdef HIL_MLC_DEBUG
++ if (mlc->seidx && (mlc->seidx != seidx) && mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) {
++ printk(KERN_DEBUG PREFIX "z%i \n%s {%i}", doze, kick ? "K" : "", mlc->seidx);
++ doze = 0;
++ }
++ kick = 0;
++
++ seidx = mlc->seidx;
++#endif
++ node = hil_mlc_se + mlc->seidx;
++
++ switch (node->act) {
++ int rc;
++ hil_packet pack;
++
++ case HILSE_FUNC:
++ if (node->object.func == NULL) break;
++ rc = node->object.func(mlc, node->arg);
++ nextidx = (rc > 0) ? node->ugly :
++ ((rc < 0) ? node->bad : node->good);
++ if (nextidx == HILSEN_FOLLOW) nextidx = rc;
++ break;
++ case HILSE_EXPECT_LAST:
++ case HILSE_EXPECT_DISC:
++ case HILSE_EXPECT:
++ case HILSE_IN:
++ /* Already set up from previous HILSE_OUT_* */
++ write_lock_irqsave(&(mlc->lock), flags);
++ rc = mlc->in(mlc, node->arg);
++ if (rc == 2) {
++ nextidx = HILSEN_DOZE;
++ sched_long = 1;
++ write_unlock_irqrestore(&(mlc->lock), flags);
++ break;
++ }
++ if (rc == 1) nextidx = node->ugly;
++ else if (rc == 0) nextidx = node->good;
++ else nextidx = node->bad;
++ mlc->istarted = 0;
++ write_unlock_irqrestore(&(mlc->lock), flags);
++ break;
++ case HILSE_OUT_LAST:
++ write_lock_irqsave(&(mlc->lock), flags);
++ pack = node->object.packet;
++ pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT);
++ goto out;
++ case HILSE_OUT_DISC:
++ write_lock_irqsave(&(mlc->lock), flags);
++ pack = node->object.packet;
++ pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT);
++ goto out;
++ case HILSE_OUT:
++ write_lock_irqsave(&(mlc->lock), flags);
++ pack = node->object.packet;
++ out:
++ if (mlc->istarted) goto out2;
++ /* Prepare to receive input */
++ if ((node + 1)->act & HILSE_IN)
++ hilse_setup_input(mlc, node + 1);
++
++ out2:
++ write_unlock_irqrestore(&(mlc->lock), flags);
++
++ if (down_trylock(&mlc->osem)) {
++ nextidx = HILSEN_DOZE;
++ break;
++ }
++ up(&mlc->osem);
++
++ write_lock_irqsave(&(mlc->lock), flags);
++ if (!(mlc->ostarted)) {
++ mlc->ostarted = 1;
++ mlc->opacket = pack;
++ mlc->out(mlc);
++ nextidx = HILSEN_DOZE;
++ write_unlock_irqrestore(&(mlc->lock), flags);
++ break;
++ }
++ mlc->ostarted = 0;
++ do_gettimeofday(&(mlc->instart));
++ write_unlock_irqrestore(&(mlc->lock), flags);
++ nextidx = HILSEN_NEXT;
++ break;
++ case HILSE_CTS:
++ nextidx = mlc->cts(mlc) ? node->bad : node->good;
++ break;
++ default:
++ BUG();
++ nextidx = 0;
++ break;
++ }
++
++#ifdef HIL_MLC_DEBUG
++ if (nextidx == HILSEN_DOZE) doze++;
++#endif
++
++ while (nextidx & HILSEN_SCHED) {
++ struct timeval tv;
++
++ if (!sched_long) goto sched;
++
++ do_gettimeofday(&tv);
++ tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec);
++ tv.tv_usec -= mlc->instart.tv_usec;
++ if (tv.tv_usec >= mlc->intimeout) goto sched;
++ tv.tv_usec = (mlc->intimeout - tv.tv_usec) * HZ / 1000000;
++ if (!tv.tv_usec) goto sched;
++ mod_timer(&hil_mlcs_kicker, jiffies + tv.tv_usec);
++ break;
++ sched:
++ tasklet_schedule(&hil_mlcs_tasklet);
++ break;
++ }
++ if (nextidx & HILSEN_DOWN) mlc->seidx += nextidx & HILSEN_MASK;
++ else if (nextidx & HILSEN_UP) mlc->seidx -= nextidx & HILSEN_MASK;
++ else mlc->seidx = nextidx & HILSEN_MASK;
++
++ if (nextidx & HILSEN_BREAK) return 1;
++ return 0;
++}
++
++/******************** tasklet context functions **************************/
++static void hil_mlcs_process(unsigned long unused) {
++ struct list_head *tmp;
++
++ read_lock(&hil_mlcs_lock);
++ list_for_each(tmp, &hil_mlcs) {
++ struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list);
++ while (hilse_donode(mlc) == 0) {
++#ifdef HIL_MLC_DEBUG
++ if (mlc->seidx != 41 &&
++ mlc->seidx != 42 &&
++ mlc->seidx != 43)
++ printk(KERN_DEBUG PREFIX " + ");
++#endif
++ };
++ }
++ read_unlock(&hil_mlcs_lock);
++}
++
++/************************* Keepalive timer task *********************/
++
++void hil_mlcs_timer (unsigned long data) {
++ hil_mlcs_probe = 1;
++ tasklet_schedule(&hil_mlcs_tasklet);
++ /* Re-insert the periodic task. */
++ if (!timer_pending(&hil_mlcs_kicker))
++ mod_timer(&hil_mlcs_kicker, jiffies + HZ);
++}
++
++/******************** user/kernel context functions **********************/
++
++static int hil_mlc_serio_write(struct serio *serio, unsigned char c) {
++ struct hil_mlc_serio_map *map;
++ struct hil_mlc *mlc;
++ struct serio_driver *drv;
++ uint8_t *idx, *last;
++
++ map = serio->port_data;
++ if (map == NULL) {
++ BUG();
++ return -EIO;
++ }
++ mlc = map->mlc;
++ if (mlc == NULL) {
++ BUG();
++ return -EIO;
++ }
++ mlc->serio_opacket[map->didx] |=
++ ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx]));
++
++ if (mlc->serio_oidx[map->didx] >= 3) {
++ /* for now only commands */
++ if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD))
++ return -EIO;
++ switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) {
++ case HIL_CMD_IDD:
++ idx = mlc->di[map->didx].idd;
++ goto emu;
++ case HIL_CMD_RSC:
++ idx = mlc->di[map->didx].rsc;
++ goto emu;
++ case HIL_CMD_EXD:
++ idx = mlc->di[map->didx].exd;
++ goto emu;
++ case HIL_CMD_RNM:
++ idx = mlc->di[map->didx].rnm;
++ goto emu;
++ default:
++ break;
++ }
++ mlc->serio_oidx[map->didx] = 0;
++ mlc->serio_opacket[map->didx] = 0;
++ }
++
++ mlc->serio_oidx[map->didx]++;
++ return -EIO;
++ emu:
++ drv = serio->drv;
++ if (drv == NULL) {
++ BUG();
++ return -EIO;
++ }
++ last = idx + 15;
++ while ((last != idx) && (*last == 0)) last--;
++
++ while (idx != last) {
++ drv->interrupt(serio, 0, 0, NULL);
++ drv->interrupt(serio, HIL_ERR_INT >> 16, 0, NULL);
++ drv->interrupt(serio, 0, 0, NULL);
++ drv->interrupt(serio, *idx, 0, NULL);
++ idx++;
++ }
++ drv->interrupt(serio, 0, 0, NULL);
++ drv->interrupt(serio, HIL_ERR_INT >> 16, 0, NULL);
++ drv->interrupt(serio, HIL_PKT_CMD >> 8, 0, NULL);
++ drv->interrupt(serio, *idx, 0, NULL);
++
++ mlc->serio_oidx[map->didx] = 0;
++ mlc->serio_opacket[map->didx] = 0;
++
++ return 0;
++}
++
++static int hil_mlc_serio_open(struct serio *serio) {
++ struct hil_mlc_serio_map *map;
++ struct hil_mlc *mlc;
++
++ if (serio->private != NULL) return -EBUSY;
++
++ map = serio->port_data;
++ if (map == NULL) {
++ BUG();
++ return -ENODEV;
++ }
++ mlc = map->mlc;
++ if (mlc == NULL) {
++ BUG();
++ return -ENODEV;
++ }
++
++ return 0;
++}
++
++static void hil_mlc_serio_close(struct serio *serio) {
++ struct hil_mlc_serio_map *map;
++ struct hil_mlc *mlc;
++
++ map = serio->port_data;
++ if (map == NULL) {
++ BUG();
++ return;
++ }
++ mlc = map->mlc;
++ if (mlc == NULL) {
++ BUG();
++ return;
++ }
++
++ serio->private = NULL;
++ serio->drv = NULL;
++ /* TODO wake up interruptable */
++}
++
++int hil_mlc_register(hil_mlc *mlc) {
++ int i;
++ unsigned long flags;
++
++ if (mlc == NULL) {
++ return -EINVAL;
++ }
++
++ mlc->istarted = 0;
++ mlc->ostarted = 0;
++
++ mlc->lock = RW_LOCK_UNLOCKED;
++ init_MUTEX(&(mlc->osem));
++
++ init_MUTEX(&(mlc->isem));
++ mlc->icount = -1;
++ mlc->imatch = 0;
++
++ mlc->opercnt = 0;
++
++ init_MUTEX_LOCKED(&(mlc->csem));
++
++ hil_mlc_clear_di_scratch(mlc);
++ hil_mlc_clear_di_map(mlc, 0);
++ for (i = 0; i < HIL_MLC_DEVMEM; i++) {
++ struct serio *mlc_serio;
++ hil_mlc_copy_di_scratch(mlc, i);
++ mlc_serio = kmalloc(sizeof(*mlc_serio), GFP_KERNEL);
++ mlc->serio[i] = mlc_serio;
++ memset(mlc_serio, 0, sizeof(*mlc_serio));
++ mlc_serio->type = SERIO_HIL | SERIO_HIL_MLC;
++ mlc_serio->write = hil_mlc_serio_write;
++ mlc_serio->open = hil_mlc_serio_open;
++ mlc_serio->close = hil_mlc_serio_close;
++ mlc_serio->port_data = &(mlc->serio_map[i]);
++ mlc->serio_map[i].mlc = mlc;
++ mlc->serio_map[i].didx = i;
++ mlc->serio_map[i].di_revmap = -1;
++ mlc->serio_opacket[i] = 0;
++ mlc->serio_oidx[i] = 0;
++ serio_register_port(mlc_serio);
++ }
++
++ mlc->tasklet = &hil_mlcs_tasklet;
++
++ write_lock_irqsave(&hil_mlcs_lock, flags);
++ list_add_tail(&mlc->list, &hil_mlcs);
++ mlc->seidx = HILSEN_START;
++ write_unlock_irqrestore(&hil_mlcs_lock, flags);
++
++ tasklet_schedule(&hil_mlcs_tasklet);
++ return 0;
++}
++
++int hil_mlc_unregister(hil_mlc *mlc) {
++ struct list_head *tmp;
++ unsigned long flags;
++ int i;
++
++ if (mlc == NULL)
++ return -EINVAL;
++
++ write_lock_irqsave(&hil_mlcs_lock, flags);
++ list_for_each(tmp, &hil_mlcs) {
++ if (list_entry(tmp, hil_mlc, list) == mlc)
++ goto found;
++ }
++
++ /* not found in list */
++ write_unlock_irqrestore(&hil_mlcs_lock, flags);
++ tasklet_schedule(&hil_mlcs_tasklet);
++ return -ENODEV;
++
++ found:
++ list_del(tmp);
++ write_unlock_irqrestore(&hil_mlcs_lock, flags);
++
++ for (i = 0; i < HIL_MLC_DEVMEM; i++) {
++ serio_unregister_port(mlc->serio[i]);
++ mlc->serio[i] = NULL;
++ }
++
++ tasklet_schedule(&hil_mlcs_tasklet);
++ return 0;
++}
++
++/**************************** Module interface *************************/
++
++static int __init hil_mlc_init(void)
++{
++ init_timer(&hil_mlcs_kicker);
++ hil_mlcs_kicker.expires = jiffies + HZ;
++ hil_mlcs_kicker.function = &hil_mlcs_timer;
++ add_timer(&hil_mlcs_kicker);
++
++ tasklet_enable(&hil_mlcs_tasklet);
++
++ return 0;
++}
++
++static void __exit hil_mlc_exit(void)
++{
++ del_timer(&hil_mlcs_kicker);
++
++ tasklet_disable(&hil_mlcs_tasklet);
++ tasklet_kill(&hil_mlcs_tasklet);
++}
++
++module_init(hil_mlc_init);
++module_exit(hil_mlc_exit);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/serio/hp_sdc.c CVS2_6_11_PA2/drivers/input/serio/hp_sdc.c
+--- LINUS_2_6_11/drivers/input/serio/hp_sdc.c 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/serio/hp_sdc.c 2005-02-03 05:48:16.000000000 -0700
+@@ -0,0 +1,1054 @@
++/*
++ * HP i8042-based System Device Controller driver.
++ *
++ * Copyright (c) 2001 Brian S. Julin
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL").
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
++ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ *
++ * References:
++ * System Device Controller Microprocessor Firmware Theory of Operation
++ * for Part Number 1820-4784 Revision B. Dwg No. A-1820-4784-2
++ * Helge Deller's original hilkbd.c port for PA-RISC.
++ *
++ *
++ * Driver theory of operation:
++ *
++ * hp_sdc_put does all writing to the SDC. ISR can run on a different
++ * CPU than hp_sdc_put, but only one CPU runs hp_sdc_put at a time
++ * (it cannot really benefit from SMP anyway.) A tasket fit this perfectly.
++ *
++ * All data coming back from the SDC is sent via interrupt and can be read
++ * fully in the ISR, so there are no latency/throughput problems there.
++ * The problem is with output, due to the slow clock speed of the SDC
++ * compared to the CPU. This should not be too horrible most of the time,
++ * but if used with HIL devices that support the multibyte transfer command,
++ * keeping outbound throughput flowing at the 6500KBps that the HIL is
++ * capable of is more than can be done at HZ=100.
++ *
++ * Busy polling for IBF clear wastes CPU cycles and bus cycles. hp_sdc.ibf
++ * is set to 0 when the IBF flag in the status register has cleared. ISR
++ * may do this, and may also access the parts of queued transactions related
++ * to reading data back from the SDC, but otherwise will not touch the
++ * hp_sdc state. Whenever a register is written hp_sdc.ibf is set to 1.
++ *
++ * The i8042 write index and the values in the 4-byte input buffer
++ * starting at 0x70 are kept track of in hp_sdc.wi, and .r7[], respectively,
++ * to minimize the amount of IO needed to the SDC. However these values
++ * do not need to be locked since they are only ever accessed by hp_sdc_put.
++ *
++ * A timer task schedules the tasklet once per second just to make
++ * sure it doesn't freeze up and to allow for bad reads to time out.
++ */
++
++#include <linux/hp_sdc.h>
++#include <linux/sched.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/ioport.h>
++#include <linux/time.h>
++#include <linux/slab.h>
++#include <linux/hil.h>
++#include <asm/io.h>
++#include <asm/system.h>
++
++/* Machine-specific abstraction */
++
++#if defined(__hppa__)
++# include <asm/parisc-device.h>
++# define sdc_readb(p) gsc_readb(p)
++# define sdc_writeb(v,p) gsc_writeb((v),(p))
++#elif defined(__mc68000__)
++# include <asm/uaccess.h>
++# define sdc_readb(p) in_8(p)
++# define sdc_writeb(v,p) out_8((p),(v))
++#else
++# error "HIL is not supported on this platform"
++#endif
++
++#define PREFIX "HP SDC: "
++
++MODULE_AUTHOR("Brian S. Julin <bri at calyx.com>");
++MODULE_DESCRIPTION("HP i8042-based SDC Driver");
++MODULE_LICENSE("Dual BSD/GPL");
++
++EXPORT_SYMBOL(hp_sdc_request_timer_irq);
++EXPORT_SYMBOL(hp_sdc_request_hil_irq);
++EXPORT_SYMBOL(hp_sdc_request_cooked_irq);
++
++EXPORT_SYMBOL(hp_sdc_release_timer_irq);
++EXPORT_SYMBOL(hp_sdc_release_hil_irq);
++EXPORT_SYMBOL(hp_sdc_release_cooked_irq);
++
++EXPORT_SYMBOL(hp_sdc_enqueue_transaction);
++EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
++
++static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */
++
++/*************** primitives for use in any context *********************/
++static inline uint8_t hp_sdc_status_in8 (void) {
++ uint8_t status;
++ unsigned long flags;
++
++ write_lock_irqsave(&hp_sdc.ibf_lock, flags);
++ status = sdc_readb(hp_sdc.status_io);
++ if (!(status & HP_SDC_STATUS_IBF)) hp_sdc.ibf = 0;
++ write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
++
++ return status;
++}
++
++static inline uint8_t hp_sdc_data_in8 (void) {
++ return sdc_readb(hp_sdc.data_io);
++}
++
++static inline void hp_sdc_status_out8 (uint8_t val) {
++ unsigned long flags;
++
++ write_lock_irqsave(&hp_sdc.ibf_lock, flags);
++ hp_sdc.ibf = 1;
++ if ((val & 0xf0) == 0xe0) hp_sdc.wi = 0xff;
++ sdc_writeb(val, hp_sdc.status_io);
++ write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
++}
++
++static inline void hp_sdc_data_out8 (uint8_t val) {
++ unsigned long flags;
++
++ write_lock_irqsave(&hp_sdc.ibf_lock, flags);
++ hp_sdc.ibf = 1;
++ sdc_writeb(val, hp_sdc.data_io);
++ write_unlock_irqrestore(&hp_sdc.ibf_lock, flags);
++}
++
++/* Care must be taken to only invoke hp_sdc_spin_ibf when
++ * absolutely needed, or in rarely invoked subroutines.
++ * Not only does it waste CPU cycles, it also wastes bus cycles.
++ */
++static inline void hp_sdc_spin_ibf(void) {
++ unsigned long flags;
++ rwlock_t *lock;
++
++ lock = &hp_sdc.ibf_lock;
++
++ read_lock_irqsave(lock, flags);
++ if (!hp_sdc.ibf) {
++ read_unlock_irqrestore(lock, flags);
++ return;
++ }
++ read_unlock(lock);
++ write_lock(lock);
++ while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF) {};
++ hp_sdc.ibf = 0;
++ write_unlock_irqrestore(lock, flags);
++}
++
++
++/************************ Interrupt context functions ************************/
++static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) {
++ hp_sdc_transaction *curr;
++
++ read_lock(&hp_sdc.rtq_lock);
++ if (hp_sdc.rcurr < 0) {
++ read_unlock(&hp_sdc.rtq_lock);
++ return;
++ }
++ curr = hp_sdc.tq[hp_sdc.rcurr];
++ read_unlock(&hp_sdc.rtq_lock);
++
++ curr->seq[curr->idx++] = status;
++ curr->seq[curr->idx++] = data;
++ hp_sdc.rqty -= 2;
++ do_gettimeofday(&hp_sdc.rtv);
++
++ if (hp_sdc.rqty <= 0) {
++ /* All data has been gathered. */
++ if(curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE) {
++ if (curr->act.semaphore) up(curr->act.semaphore);
++ }
++ if(curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK) {
++ if (curr->act.irqhook)
++ curr->act.irqhook(irq, dev_id, status, data);
++ }
++ curr->actidx = curr->idx;
++ curr->idx++;
++ /* Return control of this transaction */
++ write_lock(&hp_sdc.rtq_lock);
++ hp_sdc.rcurr = -1;
++ hp_sdc.rqty = 0;
++ write_unlock(&hp_sdc.rtq_lock);
++ tasklet_schedule(&hp_sdc.task);
++ }
++}
++
++static irqreturn_t hp_sdc_isr(int irq, void *dev_id, struct pt_regs * regs) {
++ uint8_t status, data;
++
++ status = hp_sdc_status_in8();
++ /* Read data unconditionally to advance i8042. */
++ data = hp_sdc_data_in8();
++
++ /* For now we are ignoring these until we get the SDC to behave. */
++ if (((status & 0xf1) == 0x51) && data == 0x82) {
++ return IRQ_HANDLED;
++ }
++
++ switch(status & HP_SDC_STATUS_IRQMASK) {
++ case 0: /* This case is not documented. */
++ break;
++ case HP_SDC_STATUS_USERTIMER:
++ case HP_SDC_STATUS_PERIODIC:
++ case HP_SDC_STATUS_TIMER:
++ read_lock(&hp_sdc.hook_lock);
++ if (hp_sdc.timer != NULL)
++ hp_sdc.timer(irq, dev_id, status, data);
++ read_unlock(&hp_sdc.hook_lock);
++ break;
++ case HP_SDC_STATUS_REG:
++ hp_sdc_take(irq, dev_id, status, data);
++ break;
++ case HP_SDC_STATUS_HILCMD:
++ case HP_SDC_STATUS_HILDATA:
++ read_lock(&hp_sdc.hook_lock);
++ if (hp_sdc.hil != NULL)
++ hp_sdc.hil(irq, dev_id, status, data);
++ read_unlock(&hp_sdc.hook_lock);
++ break;
++ case HP_SDC_STATUS_PUP:
++ read_lock(&hp_sdc.hook_lock);
++ if (hp_sdc.pup != NULL)
++ hp_sdc.pup(irq, dev_id, status, data);
++ else printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n");
++ read_unlock(&hp_sdc.hook_lock);
++ break;
++ default:
++ read_lock(&hp_sdc.hook_lock);
++ if (hp_sdc.cooked != NULL)
++ hp_sdc.cooked(irq, dev_id, status, data);
++ read_unlock(&hp_sdc.hook_lock);
++ break;
++ }
++ return IRQ_HANDLED;
++}
++
++
++static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id, struct pt_regs * regs) {
++ int status;
++
++ status = hp_sdc_status_in8();
++ printk(KERN_WARNING PREFIX "NMI !\n");
++
++#if 0
++ if (status & HP_SDC_NMISTATUS_FHS) {
++ read_lock(&hp_sdc.hook_lock);
++ if (hp_sdc.timer != NULL)
++ hp_sdc.timer(irq, dev_id, status, 0);
++ read_unlock(&hp_sdc.hook_lock);
++ }
++ else {
++ /* TODO: pass this on to the HIL handler, or do SAK here? */
++ printk(KERN_WARNING PREFIX "HIL NMI\n");
++ }
++#endif
++ return IRQ_HANDLED;
++}
++
++
++/***************** Kernel (tasklet) context functions ****************/
++
++unsigned long hp_sdc_put(void);
++
++static void hp_sdc_tasklet(unsigned long foo) {
++
++ write_lock_irq(&hp_sdc.rtq_lock);
++ if (hp_sdc.rcurr >= 0) {
++ struct timeval tv;
++ do_gettimeofday(&tv);
++ if (tv.tv_sec > hp_sdc.rtv.tv_sec) tv.tv_usec += 1000000;
++ if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) {
++ hp_sdc_transaction *curr;
++ uint8_t tmp;
++
++ curr = hp_sdc.tq[hp_sdc.rcurr];
++ /* If this turns out to be a normal failure mode
++ * we'll need to figure out a way to communicate
++ * it back to the application. and be less verbose.
++ */
++ printk(KERN_WARNING PREFIX "read timeout (%ius)!\n",
++ tv.tv_usec - hp_sdc.rtv.tv_usec);
++ curr->idx += hp_sdc.rqty;
++ hp_sdc.rqty = 0;
++ tmp = curr->seq[curr->actidx];
++ curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD;
++ if(tmp & HP_SDC_ACT_SEMAPHORE) {
++ if (curr->act.semaphore)
++ up(curr->act.semaphore);
++ }
++ if(tmp & HP_SDC_ACT_CALLBACK) {
++ /* Note this means that irqhooks may be called
++ * in tasklet/bh context.
++ */
++ if (curr->act.irqhook)
++ curr->act.irqhook(0, 0, 0, 0);
++ }
++ curr->actidx = curr->idx;
++ curr->idx++;
++ hp_sdc.rcurr = -1;
++ }
++ }
++ write_unlock_irq(&hp_sdc.rtq_lock);
++ hp_sdc_put();
++}
++
++unsigned long hp_sdc_put(void) {
++ hp_sdc_transaction *curr;
++ uint8_t act;
++ int idx, curridx;
++
++ int limit = 0;
++
++ write_lock(&hp_sdc.lock);
++
++ /* If i8042 buffers are full, we cannot do anything that
++ requires output, so we skip to the administrativa. */
++ if (hp_sdc.ibf) {
++ hp_sdc_status_in8();
++ if (hp_sdc.ibf) goto finish;
++ }
++
++ anew:
++ /* See if we are in the middle of a sequence. */
++ if (hp_sdc.wcurr < 0) hp_sdc.wcurr = 0;
++ read_lock_irq(&hp_sdc.rtq_lock);
++ if (hp_sdc.rcurr == hp_sdc.wcurr) hp_sdc.wcurr++;
++ read_unlock_irq(&hp_sdc.rtq_lock);
++ if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0;
++ curridx = hp_sdc.wcurr;
++
++ if (hp_sdc.tq[curridx] != NULL) goto start;
++
++ while (++curridx != hp_sdc.wcurr) {
++ if (curridx >= HP_SDC_QUEUE_LEN) {
++ curridx = -1; /* Wrap to top */
++ continue;
++ }
++ read_lock_irq(&hp_sdc.rtq_lock);
++ if (hp_sdc.rcurr == curridx) {
++ read_unlock_irq(&hp_sdc.rtq_lock);
++ continue;
++ }
++ read_unlock_irq(&hp_sdc.rtq_lock);
++ if (hp_sdc.tq[curridx] != NULL) break; /* Found one. */
++ }
++ if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */
++ curridx = -1;
++ }
++ hp_sdc.wcurr = curridx;
++
++ start:
++
++ /* Check to see if the interrupt mask needs to be set. */
++ if (hp_sdc.set_im) {
++ hp_sdc_status_out8(hp_sdc.im | HP_SDC_CMD_SET_IM);
++ hp_sdc.set_im = 0;
++ goto finish;
++ }
++
++ if (hp_sdc.wcurr == -1) goto done;
++
++ curr = hp_sdc.tq[curridx];
++ idx = curr->actidx;
++
++ if (curr->actidx >= curr->endidx) {
++ hp_sdc.tq[curridx] = NULL;
++ /* Interleave outbound data between the transactions. */
++ hp_sdc.wcurr++;
++ if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0;
++ goto finish;
++ }
++
++ act = curr->seq[idx];
++ idx++;
++
++ if (curr->idx >= curr->endidx) {
++ if (act & HP_SDC_ACT_DEALLOC) kfree(curr);
++ hp_sdc.tq[curridx] = NULL;
++ /* Interleave outbound data between the transactions. */
++ hp_sdc.wcurr++;
++ if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0;
++ goto finish;
++ }
++
++ while (act & HP_SDC_ACT_PRECMD) {
++ if (curr->idx != idx) {
++ idx++;
++ act &= ~HP_SDC_ACT_PRECMD;
++ break;
++ }
++ hp_sdc_status_out8(curr->seq[idx]);
++ curr->idx++;
++ /* act finished? */
++ if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD)
++ goto actdone;
++ /* skip quantity field if data-out sequence follows. */
++ if (act & HP_SDC_ACT_DATAOUT) curr->idx++;
++ goto finish;
++ }
++ if (act & HP_SDC_ACT_DATAOUT) {
++ int qty;
++
++ qty = curr->seq[idx];
++ idx++;
++ if (curr->idx - idx < qty) {
++ hp_sdc_data_out8(curr->seq[curr->idx]);
++ curr->idx++;
++ /* act finished? */
++ if ((curr->idx - idx >= qty) &&
++ ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT))
++ goto actdone;
++ goto finish;
++ }
++ idx += qty;
++ act &= ~HP_SDC_ACT_DATAOUT;
++ }
++ else while (act & HP_SDC_ACT_DATAREG) {
++ int mask;
++ uint8_t w7[4];
++
++ mask = curr->seq[idx];
++ if (idx != curr->idx) {
++ idx++;
++ idx += !!(mask & 1);
++ idx += !!(mask & 2);
++ idx += !!(mask & 4);
++ idx += !!(mask & 8);
++ act &= ~HP_SDC_ACT_DATAREG;
++ break;
++ }
++
++ w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0];
++ w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1];
++ w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2];
++ w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3];
++
++ if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 ||
++ w7[hp_sdc.wi-0x70] == hp_sdc.r7[hp_sdc.wi-0x70]) {
++ int i = 0;
++
++ /* Need to point the write index register */
++ while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++;
++ if (i < 4) {
++ hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i);
++ hp_sdc.wi = 0x70 + i;
++ goto finish;
++ }
++ idx++;
++ if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG)
++ goto actdone;
++ curr->idx = idx;
++ act &= ~HP_SDC_ACT_DATAREG;
++ break;
++ }
++
++ hp_sdc_data_out8(w7[hp_sdc.wi - 0x70]);
++ hp_sdc.r7[hp_sdc.wi - 0x70] = w7[hp_sdc.wi - 0x70];
++ hp_sdc.wi++; /* write index register autoincrements */
++ {
++ int i = 0;
++
++ while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++;
++ if (i >= 4) {
++ curr->idx = idx + 1;
++ if ((act & HP_SDC_ACT_DURING) ==
++ HP_SDC_ACT_DATAREG)
++ goto actdone;
++ }
++ }
++ goto finish;
++ }
++ /* We don't go any further in the command if there is a pending read,
++ because we don't want interleaved results. */
++ read_lock_irq(&hp_sdc.rtq_lock);
++ if (hp_sdc.rcurr >= 0) {
++ read_unlock_irq(&hp_sdc.rtq_lock);
++ goto finish;
++ }
++ read_unlock_irq(&hp_sdc.rtq_lock);
++
++
++ if (act & HP_SDC_ACT_POSTCMD) {
++ uint8_t postcmd;
++
++ /* curr->idx should == idx at this point. */
++ postcmd = curr->seq[idx];
++ curr->idx++;
++ if (act & HP_SDC_ACT_DATAIN) {
++
++ /* Start a new read */
++ hp_sdc.rqty = curr->seq[curr->idx];
++ do_gettimeofday(&hp_sdc.rtv);
++ curr->idx++;
++ /* Still need to lock here in case of spurious irq. */
++ write_lock_irq(&hp_sdc.rtq_lock);
++ hp_sdc.rcurr = curridx;
++ write_unlock_irq(&hp_sdc.rtq_lock);
++ hp_sdc_status_out8(postcmd);
++ goto finish;
++ }
++ hp_sdc_status_out8(postcmd);
++ goto actdone;
++ }
++
++actdone:
++ if (act & HP_SDC_ACT_SEMAPHORE) {
++ up(curr->act.semaphore);
++ }
++ else if (act & HP_SDC_ACT_CALLBACK) {
++ curr->act.irqhook(0,0,0,0);
++ }
++ if (curr->idx >= curr->endidx) { /* This transaction is over. */
++ if (act & HP_SDC_ACT_DEALLOC) kfree(curr);
++ hp_sdc.tq[curridx] = NULL;
++ }
++ else {
++ curr->actidx = idx + 1;
++ curr->idx = idx + 2;
++ }
++ /* Interleave outbound data between the transactions. */
++ hp_sdc.wcurr++;
++ if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0;
++
++ finish:
++ /* If by some quirk IBF has cleared and our ISR has run to
++ see that that has happened, do it all again. */
++ if (!hp_sdc.ibf && limit++ < 20) goto anew;
++
++ done:
++ if (hp_sdc.wcurr >= 0) tasklet_schedule(&hp_sdc.task);
++ write_unlock(&hp_sdc.lock);
++ return 0;
++}
++
++/******* Functions called in either user or kernel context ****/
++int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) {
++ unsigned long flags;
++ int i;
++
++ if (this == NULL) {
++ tasklet_schedule(&hp_sdc.task);
++ return -EINVAL;
++ };
++
++ write_lock_irqsave(&hp_sdc.lock, flags);
++
++ /* Can't have same transaction on queue twice */
++ for (i=0; i < HP_SDC_QUEUE_LEN; i++)
++ if (hp_sdc.tq[i] == this) goto fail;
++
++ this->actidx = 0;
++ this->idx = 1;
++
++ /* Search for empty slot */
++ for (i=0; i < HP_SDC_QUEUE_LEN; i++) {
++ if (hp_sdc.tq[i] == NULL) {
++ hp_sdc.tq[i] = this;
++ write_unlock_irqrestore(&hp_sdc.lock, flags);
++ tasklet_schedule(&hp_sdc.task);
++ return 0;
++ }
++ }
++ write_unlock_irqrestore(&hp_sdc.lock, flags);
++ printk(KERN_WARNING PREFIX "No free slot to add transaction.\n");
++ return -EBUSY;
++
++ fail:
++ write_unlock_irqrestore(&hp_sdc.lock,flags);
++ printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n");
++ return -EINVAL;
++}
++
++int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) {
++ unsigned long flags;
++ int i;
++
++ write_lock_irqsave(&hp_sdc.lock, flags);
++
++ /* TODO: don't remove it if it's not done. */
++
++ for (i=0; i < HP_SDC_QUEUE_LEN; i++)
++ if (hp_sdc.tq[i] == this) hp_sdc.tq[i] = NULL;
++
++ write_unlock_irqrestore(&hp_sdc.lock, flags);
++ return 0;
++}
++
++
++
++/********************** User context functions **************************/
++int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) {
++
++ if (callback == NULL || hp_sdc.dev == NULL) {
++ return -EINVAL;
++ }
++ write_lock_irq(&hp_sdc.hook_lock);
++ if (hp_sdc.timer != NULL) {
++ write_unlock_irq(&hp_sdc.hook_lock);
++ return -EBUSY;
++ }
++
++ hp_sdc.timer = callback;
++ /* Enable interrupts from the timers */
++ hp_sdc.im &= ~HP_SDC_IM_FH;
++ hp_sdc.im &= ~HP_SDC_IM_PT;
++ hp_sdc.im &= ~HP_SDC_IM_TIMERS;
++ hp_sdc.set_im = 1;
++ write_unlock_irq(&hp_sdc.hook_lock);
++
++ tasklet_schedule(&hp_sdc.task);
++
++ return 0;
++}
++
++int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) {
++
++ if (callback == NULL || hp_sdc.dev == NULL) {
++ return -EINVAL;
++ }
++ write_lock_irq(&hp_sdc.hook_lock);
++ if (hp_sdc.hil != NULL) {
++ write_unlock_irq(&hp_sdc.hook_lock);
++ return -EBUSY;
++ }
++
++ hp_sdc.hil = callback;
++ hp_sdc.im &= ~(HP_SDC_IM_HIL | HP_SDC_IM_RESET);
++ hp_sdc.set_im = 1;
++ write_unlock_irq(&hp_sdc.hook_lock);
++
++ tasklet_schedule(&hp_sdc.task);
++
++ return 0;
++}
++
++int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) {
++
++ if (callback == NULL || hp_sdc.dev == NULL) {
++ return -EINVAL;
++ }
++ write_lock_irq(&hp_sdc.hook_lock);
++ if (hp_sdc.cooked != NULL) {
++ write_unlock_irq(&hp_sdc.hook_lock);
++ return -EBUSY;
++ }
++
++ /* Enable interrupts from the HIL MLC */
++ hp_sdc.cooked = callback;
++ hp_sdc.im &= ~(HP_SDC_IM_HIL | HP_SDC_IM_RESET);
++ hp_sdc.set_im = 1;
++ write_unlock_irq(&hp_sdc.hook_lock);
++
++ tasklet_schedule(&hp_sdc.task);
++
++ return 0;
++}
++
++int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) {
++
++
++ write_lock_irq(&hp_sdc.hook_lock);
++ if ((callback != hp_sdc.timer) ||
++ (hp_sdc.timer == NULL)) {
++ write_unlock_irq(&hp_sdc.hook_lock);
++ return -EINVAL;
++ }
++
++ /* Disable interrupts from the timers */
++ hp_sdc.timer = NULL;
++ hp_sdc.im |= HP_SDC_IM_TIMERS;
++ hp_sdc.im |= HP_SDC_IM_FH;
++ hp_sdc.im |= HP_SDC_IM_PT;
++ hp_sdc.set_im = 1;
++ write_unlock_irq(&hp_sdc.hook_lock);
++ tasklet_schedule(&hp_sdc.task);
++
++ return 0;
++}
++
++int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) {
++
++ write_lock_irq(&hp_sdc.hook_lock);
++ if ((callback != hp_sdc.hil) ||
++ (hp_sdc.hil == NULL)) {
++ write_unlock_irq(&hp_sdc.hook_lock);
++ return -EINVAL;
++ }
++
++ hp_sdc.hil = NULL;
++ /* Disable interrupts from HIL only if there is no cooked driver. */
++ if(hp_sdc.cooked == NULL) {
++ hp_sdc.im |= (HP_SDC_IM_HIL | HP_SDC_IM_RESET);
++ hp_sdc.set_im = 1;
++ }
++ write_unlock_irq(&hp_sdc.hook_lock);
++ tasklet_schedule(&hp_sdc.task);
++
++ return 0;
++}
++
++int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) {
++
++ write_lock_irq(&hp_sdc.hook_lock);
++ if ((callback != hp_sdc.cooked) ||
++ (hp_sdc.cooked == NULL)) {
++ write_unlock_irq(&hp_sdc.hook_lock);
++ return -EINVAL;
++ }
++
++ hp_sdc.cooked = NULL;
++ /* Disable interrupts from HIL only if there is no raw HIL driver. */
++ if(hp_sdc.hil == NULL) {
++ hp_sdc.im |= (HP_SDC_IM_HIL | HP_SDC_IM_RESET);
++ hp_sdc.set_im = 1;
++ }
++ write_unlock_irq(&hp_sdc.hook_lock);
++ tasklet_schedule(&hp_sdc.task);
++
++ return 0;
++}
++
++/************************* Keepalive timer task *********************/
++
++void hp_sdc_kicker (unsigned long data) {
++ tasklet_schedule(&hp_sdc.task);
++ /* Re-insert the periodic task. */
++ mod_timer(&hp_sdc.kicker, jiffies + HZ);
++}
++
++/************************** Module Initialization ***************************/
++
++#if defined(__hppa__)
++
++static struct parisc_device_id hp_sdc_tbl[] = {
++ {
++ .hw_type = HPHW_FIO,
++ .hversion_rev = HVERSION_REV_ANY_ID,
++ .hversion = HVERSION_ANY_ID,
++ .sversion = 0x73,
++ },
++ { 0, }
++};
++
++MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl);
++
++static int __init hp_sdc_init_hppa(struct parisc_device *d);
++
++static struct parisc_driver hp_sdc_driver = {
++ .name = "HP SDC",
++ .id_table = hp_sdc_tbl,
++ .probe = hp_sdc_init_hppa,
++};
++
++#endif /* __hppa__ */
++
++static int __init hp_sdc_init(void)
++{
++ int i;
++ char *errstr;
++ hp_sdc_transaction t_sync;
++ uint8_t ts_sync[6];
++ struct semaphore s_sync;
++
++ hp_sdc.lock = RW_LOCK_UNLOCKED;
++ hp_sdc.ibf_lock = RW_LOCK_UNLOCKED;
++ hp_sdc.rtq_lock = RW_LOCK_UNLOCKED;
++ hp_sdc.hook_lock = RW_LOCK_UNLOCKED;
++
++ hp_sdc.timer = NULL;
++ hp_sdc.hil = NULL;
++ hp_sdc.pup = NULL;
++ hp_sdc.cooked = NULL;
++ hp_sdc.im = HP_SDC_IM_MASK; /* Mask maskable irqs */
++ hp_sdc.set_im = 1;
++ hp_sdc.wi = 0xff;
++ hp_sdc.r7[0] = 0xff;
++ hp_sdc.r7[1] = 0xff;
++ hp_sdc.r7[2] = 0xff;
++ hp_sdc.r7[3] = 0xff;
++ hp_sdc.ibf = 1;
++
++ for (i = 0; i < HP_SDC_QUEUE_LEN; i++) hp_sdc.tq[i] = NULL;
++ hp_sdc.wcurr = -1;
++ hp_sdc.rcurr = -1;
++ hp_sdc.rqty = 0;
++
++ hp_sdc.dev_err = -ENODEV;
++
++ errstr = "IO not found for";
++ if (!hp_sdc.base_io) goto err0;
++
++ errstr = "IRQ not found for";
++ if (!hp_sdc.irq) goto err0;
++
++ hp_sdc.dev_err = -EBUSY;
++
++#if defined(__hppa__)
++ errstr = "IO not available for";
++ if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) goto err0;
++#endif
++
++ errstr = "IRQ not available for";
++ if(request_irq(hp_sdc.irq, &hp_sdc_isr, 0, "HP SDC",
++ (void *) hp_sdc.base_io)) goto err1;
++
++ errstr = "NMI not available for";
++ if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, 0, "HP SDC NMI",
++ (void *) hp_sdc.base_io)) goto err2;
++
++ printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n",
++ (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
++
++ hp_sdc_status_in8();
++ hp_sdc_data_in8();
++
++ tasklet_init(&hp_sdc.task, hp_sdc_tasklet, 0);
++
++ /* Sync the output buffer registers, thus scheduling hp_sdc_tasklet. */
++ t_sync.actidx = 0;
++ t_sync.idx = 1;
++ t_sync.endidx = 6;
++ t_sync.seq = ts_sync;
++ ts_sync[0] = HP_SDC_ACT_DATAREG | HP_SDC_ACT_SEMAPHORE;
++ ts_sync[1] = 0x0f;
++ ts_sync[2] = ts_sync[3] = ts_sync[4] = ts_sync[5] = 0;
++ t_sync.act.semaphore = &s_sync;
++ init_MUTEX_LOCKED(&s_sync);
++ hp_sdc_enqueue_transaction(&t_sync);
++ down(&s_sync); /* Wait for t_sync to complete */
++
++ /* Create the keepalive task */
++ init_timer(&hp_sdc.kicker);
++ hp_sdc.kicker.expires = jiffies + HZ;
++ hp_sdc.kicker.function = &hp_sdc_kicker;
++ add_timer(&hp_sdc.kicker);
++
++ hp_sdc.dev_err = 0;
++ return 0;
++ err2:
++ free_irq(hp_sdc.irq, NULL);
++ err1:
++ release_region(hp_sdc.data_io, 2);
++ err0:
++ printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n",
++ errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi);
++ hp_sdc.dev = NULL;
++ return hp_sdc.dev_err;
++}
++
++#if defined(__hppa__)
++
++static int __init hp_sdc_init_hppa(struct parisc_device *d)
++{
++ if (!d) return 1;
++ if (hp_sdc.dev != NULL) return 1; /* We only expect one SDC */
++
++ hp_sdc.dev = d;
++ hp_sdc.irq = d->irq;
++ hp_sdc.nmi = d->aux_irq;
++ hp_sdc.base_io = d->hpa;
++ hp_sdc.data_io = d->hpa + 0x800;
++ hp_sdc.status_io = d->hpa + 0x801;
++
++ return hp_sdc_init();
++}
++
++#endif /* __hppa__ */
++
++#if !defined(__mc68000__) /* Link error on m68k! */
++static void __exit hp_sdc_exit(void)
++#else
++static void hp_sdc_exit(void)
++#endif
++{
++ write_lock_irq(&hp_sdc.lock);
++
++ /* Turn off all maskable "sub-function" irq's. */
++ hp_sdc_spin_ibf();
++ sdc_writeb(HP_SDC_CMD_SET_IM | HP_SDC_IM_MASK, hp_sdc.status_io);
++
++ /* Wait until we know this has been processed by the i8042 */
++ hp_sdc_spin_ibf();
++
++ free_irq(hp_sdc.nmi, NULL);
++ free_irq(hp_sdc.irq, NULL);
++ write_unlock_irq(&hp_sdc.lock);
++
++ del_timer(&hp_sdc.kicker);
++
++ tasklet_kill(&hp_sdc.task);
++
++/* release_region(hp_sdc.data_io, 2); */
++
++#if defined(__hppa__)
++ if (unregister_parisc_driver(&hp_sdc_driver))
++ printk(KERN_WARNING PREFIX "Error unregistering HP SDC");
++#endif
++}
++
++static int __init hp_sdc_register(void)
++{
++ hp_sdc_transaction tq_init;
++ uint8_t tq_init_seq[5];
++ struct semaphore tq_init_sem;
++#if defined(__mc68000__)
++ mm_segment_t fs;
++ unsigned char i;
++#endif
++
++ hp_sdc.dev = NULL;
++ hp_sdc.dev_err = 0;
++#if defined(__hppa__)
++ if (register_parisc_driver(&hp_sdc_driver)) {
++ printk(KERN_WARNING PREFIX "Error registering SDC with system bus tree.\n");
++ return -ENODEV;
++ }
++#elif defined(__mc68000__)
++ if (!MACH_IS_HP300)
++ return -ENODEV;
++
++ hp_sdc.irq = 1;
++ hp_sdc.nmi = 7;
++ hp_sdc.base_io = (unsigned long) 0xf0428000;
++ hp_sdc.data_io = (unsigned long) hp_sdc.base_io + 1;
++ hp_sdc.status_io = (unsigned long) hp_sdc.base_io + 3;
++ fs = get_fs();
++ set_fs(KERNEL_DS);
++ if (!get_user(i, (unsigned char *)hp_sdc.data_io))
++ hp_sdc.dev = (void *)1;
++ set_fs(fs);
++ hp_sdc.dev_err = hp_sdc_init();
++#endif
++ if (hp_sdc.dev == NULL) {
++ printk(KERN_WARNING PREFIX "No SDC found.\n");
++ return hp_sdc.dev_err;
++ }
++
++ init_MUTEX_LOCKED(&tq_init_sem);
++
++ tq_init.actidx = 0;
++ tq_init.idx = 1;
++ tq_init.endidx = 5;
++ tq_init.seq = tq_init_seq;
++ tq_init.act.semaphore = &tq_init_sem;
++
++ tq_init_seq[0] =
++ HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE;
++ tq_init_seq[1] = HP_SDC_CMD_READ_KCC;
++ tq_init_seq[2] = 1;
++ tq_init_seq[3] = 0;
++ tq_init_seq[4] = 0;
++
++ hp_sdc_enqueue_transaction(&tq_init);
++
++ down(&tq_init_sem);
++ up(&tq_init_sem);
++
++ if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) {
++ printk(KERN_WARNING PREFIX "Error reading config byte.\n");
++ hp_sdc_exit();
++ return -ENODEV;
++ }
++ hp_sdc.r11 = tq_init_seq[4];
++ if (hp_sdc.r11 & HP_SDC_CFG_NEW) {
++ char *str;
++ printk(KERN_INFO PREFIX "New style SDC\n");
++ tq_init_seq[1] = HP_SDC_CMD_READ_XTD;
++ tq_init.actidx = 0;
++ tq_init.idx = 1;
++ down(&tq_init_sem);
++ hp_sdc_enqueue_transaction(&tq_init);
++ down(&tq_init_sem);
++ up(&tq_init_sem);
++ if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) {
++ printk(KERN_WARNING PREFIX "Error reading extended config byte.\n");
++ return -ENODEV;
++ }
++ hp_sdc.r7e = tq_init_seq[4];
++ HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str)
++ printk(KERN_INFO PREFIX "Revision: %s\n", str);
++ if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) {
++ printk(KERN_INFO PREFIX "TI SN76494 beeper present\n");
++ }
++ if (hp_sdc.r7e & HP_SDC_XTD_BBRTC) {
++ printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n");
++ }
++ printk(KERN_INFO PREFIX "Spunking the self test register to force PUP "
++ "on next firmware reset.\n");
++ tq_init_seq[0] = HP_SDC_ACT_PRECMD |
++ HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE;
++ tq_init_seq[1] = HP_SDC_CMD_SET_STR;
++ tq_init_seq[2] = 1;
++ tq_init_seq[3] = 0;
++ tq_init.actidx = 0;
++ tq_init.idx = 1;
++ tq_init.endidx = 4;
++ down(&tq_init_sem);
++ hp_sdc_enqueue_transaction(&tq_init);
++ down(&tq_init_sem);
++ up(&tq_init_sem);
++ }
++ else {
++ printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n",
++ (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087");
++ }
++
++ return 0;
++}
++
++module_init(hp_sdc_register);
++module_exit(hp_sdc_exit);
++
++/* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64)
++ * cycles cycles-adj time
++ * between two consecutive mfctl(16)'s: 4 n/a 63ns
++ * hp_sdc_spin_ibf when idle: 119 115 1.7us
++ * gsc_writeb status register: 83 79 1.2us
++ * IBF to clear after sending SET_IM: 6204 6006 93us
++ * IBF to clear after sending LOAD_RT: 4467 4352 68us
++ * IBF to clear after sending two LOAD_RTs: 18974 18859 295us
++ * READ_T1, read status/data, IRQ, call handler: 35564 n/a 556us
++ * cmd to ~IBF READ_T1 2nd time right after: 5158403 n/a 81ms
++ * between IRQ received and ~IBF for above: 2578877 n/a 40ms
++ *
++ * Performance stats after a run of this module configuring HIL and
++ * receiving a few mouse events:
++ *
++ * status in8 282508 cycles 7128 calls
++ * status out8 8404 cycles 341 calls
++ * data out8 1734 cycles 78 calls
++ * isr 174324 cycles 617 calls (includes take)
++ * take 1241 cycles 2 calls
++ * put 1411504 cycles 6937 calls
++ * task 1655209 cycles 6937 calls (includes put)
++ *
++ */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/input/serio/hp_sdc_mlc.c CVS2_6_11_PA2/drivers/input/serio/hp_sdc_mlc.c
+--- LINUS_2_6_11/drivers/input/serio/hp_sdc_mlc.c 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/drivers/input/serio/hp_sdc_mlc.c 2004-10-30 13:51:50.000000000 -0600
+@@ -0,0 +1,358 @@
++/*
++ * Access to HP-HIL MLC through HP System Device Controller.
++ *
++ * Copyright (c) 2001 Brian S. Julin
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL").
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
++ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ *
++ * References:
++ * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
++ * System Device Controller Microprocessor Firmware Theory of Operation
++ * for Part Number 1820-4784 Revision B. Dwg No. A-1820-4784-2
++ *
++ */
++
++#include <linux/hil_mlc.h>
++#include <linux/hp_sdc.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/string.h>
++
++#define PREFIX "HP SDC MLC: "
++
++static hil_mlc hp_sdc_mlc;
++
++MODULE_AUTHOR("Brian S. Julin <bri at calyx.com>");
++MODULE_DESCRIPTION("Glue for onboard HIL MLC in HP-PARISC machines");
++MODULE_LICENSE("Dual BSD/GPL");
++
++struct hp_sdc_mlc_priv_s {
++ int emtestmode;
++ hp_sdc_transaction trans;
++ u8 tseq[16];
++ int got5x;
++} hp_sdc_mlc_priv;
++
++/************************* Interrupt context ******************************/
++static void hp_sdc_mlc_isr (int irq, void *dev_id,
++ uint8_t status, uint8_t data) {
++ int idx;
++ hil_mlc *mlc = &hp_sdc_mlc;
++
++ write_lock(&(mlc->lock));
++ if (mlc->icount < 0) {
++ printk(KERN_WARNING PREFIX "HIL Overflow!\n");
++ up(&mlc->isem);
++ goto out;
++ }
++ idx = 15 - mlc->icount;
++ if ((status & HP_SDC_STATUS_IRQMASK) == HP_SDC_STATUS_HILDATA) {
++ mlc->ipacket[idx] |= data | HIL_ERR_INT;
++ mlc->icount--;
++ if (hp_sdc_mlc_priv.got5x) goto check;
++ if (!idx) goto check;
++ if ((mlc->ipacket[idx-1] & HIL_PKT_ADDR_MASK) !=
++ (mlc->ipacket[idx] & HIL_PKT_ADDR_MASK)) {
++ mlc->ipacket[idx] &= ~HIL_PKT_ADDR_MASK;
++ mlc->ipacket[idx] |= (mlc->ipacket[idx-1]
++ & HIL_PKT_ADDR_MASK);
++ }
++ goto check;
++ }
++ /* We know status is 5X */
++ if (data & HP_SDC_HIL_ISERR) goto err;
++ mlc->ipacket[idx] =
++ (data & HP_SDC_HIL_R1MASK) << HIL_PKT_ADDR_SHIFT;
++ hp_sdc_mlc_priv.got5x = 1;
++ goto out;
++
++ check:
++ hp_sdc_mlc_priv.got5x = 0;
++ if (mlc->imatch == 0) goto done;
++ if ((mlc->imatch == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
++ && (mlc->ipacket[idx] == (mlc->imatch | idx))) goto done;
++ if (mlc->ipacket[idx] == mlc->imatch) goto done;
++ goto out;
++
++ err:
++ printk(KERN_DEBUG PREFIX "err code %x\n", data);
++ switch (data) {
++ case HP_SDC_HIL_RC_DONE:
++ printk(KERN_WARNING PREFIX "Bastard SDC reconfigured loop!\n");
++ break;
++ case HP_SDC_HIL_ERR:
++ mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_PERR |
++ HIL_ERR_FERR | HIL_ERR_FOF;
++ break;
++ case HP_SDC_HIL_TO:
++ mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_LERR;
++ break;
++ case HP_SDC_HIL_RC:
++ printk(KERN_WARNING PREFIX "Bastard SDC decided to reconfigure loop!\n");
++ break;
++ default:
++ printk(KERN_WARNING PREFIX "Unkown HIL Error status (%x)!\n", data);
++ break;
++ }
++ /* No more data will be coming due to an error. */
++ done:
++ tasklet_schedule(mlc->tasklet);
++ up(&(mlc->isem));
++ out:
++ write_unlock(&(mlc->lock));
++}
++
++
++/******************** Tasklet or userspace context functions ****************/
++
++static int hp_sdc_mlc_in (hil_mlc *mlc, suseconds_t timeout) {
++ unsigned long flags;
++ struct hp_sdc_mlc_priv_s *priv;
++ int rc = 2;
++
++ priv = mlc->priv;
++
++ write_lock_irqsave(&(mlc->lock), flags);
++
++ /* Try to down the semaphore */
++ if (down_trylock(&(mlc->isem))) {
++ struct timeval tv;
++ if (priv->emtestmode) {
++ mlc->ipacket[0] =
++ HIL_ERR_INT | (mlc->opacket &
++ (HIL_PKT_CMD |
++ HIL_PKT_ADDR_MASK |
++ HIL_PKT_DATA_MASK));
++ mlc->icount = 14;
++ /* printk(KERN_DEBUG PREFIX ">[%x]\n", mlc->ipacket[0]); */
++ goto wasup;
++ }
++ do_gettimeofday(&tv);
++ tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec);
++ if (tv.tv_usec - mlc->instart.tv_usec > mlc->intimeout) {
++ /* printk("!%i %i",
++ tv.tv_usec - mlc->instart.tv_usec,
++ mlc->intimeout);
++ */
++ rc = 1;
++ up(&(mlc->isem));
++ }
++ goto done;
++ }
++ wasup:
++ up(&(mlc->isem));
++ rc = 0;
++ goto done;
++ done:
++ write_unlock_irqrestore(&(mlc->lock), flags);
++ return rc;
++}
++
++static int hp_sdc_mlc_cts (hil_mlc *mlc) {
++ struct hp_sdc_mlc_priv_s *priv;
++ unsigned long flags;
++
++ priv = mlc->priv;
++
++ write_lock_irqsave(&(mlc->lock), flags);
++
++ /* Try to down the semaphores -- they should be up. */
++ if (down_trylock(&(mlc->isem))) {
++ BUG();
++ goto busy;
++ }
++ if (down_trylock(&(mlc->osem))) {
++ BUG();
++ up(&(mlc->isem));
++ goto busy;
++ }
++ up(&(mlc->isem));
++ up(&(mlc->osem));
++
++ if (down_trylock(&(mlc->csem))) {
++ if (priv->trans.act.semaphore != &(mlc->csem)) goto poll;
++ goto busy;
++ }
++ if (!(priv->tseq[4] & HP_SDC_USE_LOOP)) goto done;
++
++ poll:
++ priv->trans.act.semaphore = &(mlc->csem);
++ priv->trans.actidx = 0;
++ priv->trans.idx = 1;
++ priv->trans.endidx = 5;
++ priv->tseq[0] =
++ HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE;
++ priv->tseq[1] = HP_SDC_CMD_READ_USE;
++ priv->tseq[2] = 1;
++ priv->tseq[3] = 0;
++ priv->tseq[4] = 0;
++ hp_sdc_enqueue_transaction(&(priv->trans));
++ busy:
++ write_unlock_irqrestore(&(mlc->lock), flags);
++ return 1;
++ done:
++ priv->trans.act.semaphore = &(mlc->osem);
++ up(&(mlc->csem));
++ write_unlock_irqrestore(&(mlc->lock), flags);
++ return 0;
++}
++
++static void hp_sdc_mlc_out (hil_mlc *mlc) {
++ struct hp_sdc_mlc_priv_s *priv;
++ unsigned long flags;
++
++ priv = mlc->priv;
++
++ write_lock_irqsave(&(mlc->lock), flags);
++
++ /* Try to down the semaphore -- it should be up. */
++ if (down_trylock(&(mlc->osem))) {
++ BUG();
++ goto done;
++ }
++
++ if (mlc->opacket & HIL_DO_ALTER_CTRL) goto do_control;
++
++ do_data:
++ if (priv->emtestmode) {
++ up(&(mlc->osem));
++ goto done;
++ }
++ /* Shouldn't be sending commands when loop may be busy */
++ if (down_trylock(&(mlc->csem))) {
++ BUG();
++ goto done;
++ }
++ up(&(mlc->csem));
++
++ priv->trans.actidx = 0;
++ priv->trans.idx = 1;
++ priv->trans.act.semaphore = &(mlc->osem);
++ priv->trans.endidx = 6;
++ priv->tseq[0] =
++ HP_SDC_ACT_DATAREG | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_SEMAPHORE;
++ priv->tseq[1] = 0x7;
++ priv->tseq[2] =
++ (mlc->opacket &
++ (HIL_PKT_ADDR_MASK | HIL_PKT_CMD))
++ >> HIL_PKT_ADDR_SHIFT;
++ priv->tseq[3] =
++ (mlc->opacket & HIL_PKT_DATA_MASK)
++ >> HIL_PKT_DATA_SHIFT;
++ priv->tseq[4] = 0; /* No timeout */
++ if (priv->tseq[3] == HIL_CMD_DHR) priv->tseq[4] = 1;
++ priv->tseq[5] = HP_SDC_CMD_DO_HIL;
++ goto enqueue;
++
++ do_control:
++ priv->emtestmode = mlc->opacket & HIL_CTRL_TEST;
++ if ((mlc->opacket & (HIL_CTRL_APE | HIL_CTRL_IPF)) == HIL_CTRL_APE) {
++ BUG(); /* we cannot emulate this, it should not be used. */
++ }
++ if ((mlc->opacket & HIL_CTRL_ONLY) == HIL_CTRL_ONLY) goto control_only;
++ if (mlc->opacket & HIL_CTRL_APE) {
++ BUG(); /* Should not send command/data after engaging APE */
++ goto done;
++ }
++ /* Disengaging APE this way would not be valid either since
++ * the loop must be allowed to idle.
++ *
++ * So, it works out that we really never actually send control
++ * and data when using SDC, we just send the data.
++ */
++ goto do_data;
++
++ control_only:
++ priv->trans.actidx = 0;
++ priv->trans.idx = 1;
++ priv->trans.act.semaphore = &(mlc->osem);
++ priv->trans.endidx = 4;
++ priv->tseq[0] =
++ HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE;
++ priv->tseq[1] = HP_SDC_CMD_SET_LPC;
++ priv->tseq[2] = 1;
++ // priv->tseq[3] = (mlc->ddc + 1) | HP_SDC_LPS_ACSUCC;
++ priv->tseq[3] = 0;
++ if (mlc->opacket & HIL_CTRL_APE) {
++ priv->tseq[3] |= HP_SDC_LPC_APE_IPF;
++ down_trylock(&(mlc->csem));
++ }
++ enqueue:
++ hp_sdc_enqueue_transaction(&(priv->trans));
++ done:
++ write_unlock_irqrestore(&(mlc->lock), flags);
++}
++
++static int __init hp_sdc_mlc_init(void)
++{
++ hil_mlc *mlc = &hp_sdc_mlc;
++
++ printk(KERN_INFO PREFIX "Registering the System Domain Controller's HIL MLC.\n");
++
++ hp_sdc_mlc_priv.emtestmode = 0;
++ hp_sdc_mlc_priv.trans.seq = hp_sdc_mlc_priv.tseq;
++ hp_sdc_mlc_priv.trans.act.semaphore = &(mlc->osem);
++ hp_sdc_mlc_priv.got5x = 0;
++
++ mlc->cts = &hp_sdc_mlc_cts;
++ mlc->in = &hp_sdc_mlc_in;
++ mlc->out = &hp_sdc_mlc_out;
++
++ if (hil_mlc_register(mlc)) {
++ printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n");
++ goto err0;
++ }
++ mlc->priv = &hp_sdc_mlc_priv;
++
++ if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) {
++ printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n");
++ goto err1;
++ }
++ return 0;
++ err1:
++ if (hil_mlc_unregister(mlc)) {
++ printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n"
++ "This is bad. Could cause an oops.\n");
++ }
++ err0:
++ return -EBUSY;
++}
++
++static void __exit hp_sdc_mlc_exit(void)
++{
++ hil_mlc *mlc = &hp_sdc_mlc;
++ if (hp_sdc_release_hil_irq(&hp_sdc_mlc_isr)) {
++ printk(KERN_ERR PREFIX "Failed to release the raw HIL ISR hook.\n"
++ "This is bad. Could cause an oops.\n");
++ }
++ if (hil_mlc_unregister(mlc)) {
++ printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n"
++ "This is bad. Could cause an oops.\n");
++ }
++}
++
++module_init(hp_sdc_mlc_init);
++module_exit(hp_sdc_mlc_exit);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/net/tulip/media.c CVS2_6_11_PA2/drivers/net/tulip/media.c
+--- LINUS_2_6_11/drivers/net/tulip/media.c 2005-03-02 04:19:10.000000000 -0700
++++ CVS2_6_11_PA2/drivers/net/tulip/media.c 2005-01-12 13:16:53.000000000 -0700
+@@ -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)
+ {
+@@ -307,13 +309,29 @@
+ 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_11/drivers/net/tulip/tulip.h CVS2_6_11_PA2/drivers/net/tulip/tulip.h
+--- LINUS_2_6_11/drivers/net/tulip/tulip.h 2005-03-02 04:19:10.000000000 -0700
++++ CVS2_6_11_PA2/drivers/net/tulip/tulip.h 2005-01-12 13:16:53.000000000 -0700
+@@ -475,8 +475,11 @@
+ udelay(10);
+
+ if (!i)
+- printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed\n",
+- tp->pdev->slot_name);
++ printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed"
++ " (CSR5 0x%x CSR6 0x%x)\n",
++ tp->pdev->slot_name,
++ ioread32(ioaddr + CSR5),
++ ioread32(ioaddr + CSR6));
+ }
+ }
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/net/tulip/tulip_core.c CVS2_6_11_PA2/drivers/net/tulip/tulip_core.c
+--- LINUS_2_6_11/drivers/net/tulip/tulip_core.c 2005-03-02 04:19:10.000000000 -0700
++++ CVS2_6_11_PA2/drivers/net/tulip/tulip_core.c 2005-01-22 07:59:27.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>
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/Kconfig CVS2_6_11_PA2/drivers/parisc/Kconfig
+--- LINUS_2_6_11/drivers/parisc/Kconfig 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/Kconfig 2005-01-13 08:35:18.000000000 -0700
+@@ -110,6 +110,14 @@
+ # help
+ # Say Y here for V-class PCI, DMA/IOMMU, IRQ subsystem support.
+
++source "drivers/pcmcia/Kconfig"
++
++source "drivers/pci/hotplug/Kconfig"
++
++endmenu
++
++menu "PA-RISC specific drivers"
++
+ config SUPERIO
+ bool "SuperIO (SuckyIO) support"
+ depends on PCI_LBA
+@@ -144,9 +152,18 @@
+
+ If unsure, say Y.
+
+-source "drivers/pcmcia/Kconfig"
+-
+-source "drivers/pci/hotplug/Kconfig"
+-
++config PDC_STABLE
++ tristate "PDC Stable Storage support"
++ depends on SYSFS
++ default y
++ help
++ Say Y here if you want to enable support for accessing Stable Storage
++ variables (PDC non volatile variables such as Primary Boot Path,
++ Console Path, Autoboot, Autosearch, etc) through SysFS.
++
++ If unsure, say Y.
++
++ To compile this driver as a module, choose M here.
++ The module will be called pdc_stable.
+
+ endmenu
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/Makefile CVS2_6_11_PA2/drivers/parisc/Makefile
+--- LINUS_2_6_11/drivers/parisc/Makefile 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/Makefile 2005-01-12 17:17:12.000000000 -0700
+@@ -22,5 +22,6 @@
+
+ obj-$(CONFIG_SUPERIO) += superio.o
+ obj-$(CONFIG_CHASSIS_LCD_LED) += led.o
++obj-$(CONFIG_PDC_STABLE) += pdc_stable.o
+ obj-y += power.o
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/asp.c CVS2_6_11_PA2/drivers/parisc/asp.c
+--- LINUS_2_6_11/drivers/parisc/asp.c 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/asp.c 2005-02-03 05:48:16.000000000 -0700
+@@ -30,6 +30,8 @@
+
+ #define VIPER_INT_WORD 0xFFFBF088 /* addr of viper interrupt word */
+
++static struct gsc_asic asp;
++
+ static void asp_choose_irq(struct parisc_device *dev, void *ctrl)
+ {
+ int irq;
+@@ -51,6 +53,14 @@
+ }
+
+ gsc_asic_assign_irq(ctrl, irq, &dev->irq);
++
++ switch (dev->id.sversion) {
++ case 0x73: irq = 2; break; /* i8042 High-priority */
++ case 0x76: irq = 0; break; /* EISA BA */
++ default: return; /* Other */
++ }
++
++ gsc_asic_assign_irq(ctrl, irq, &dev->aux_irq);
+ }
+
+ /* There are two register ranges we're interested in. Interrupt /
+@@ -64,20 +74,15 @@
+ int __init
+ asp_init_chip(struct parisc_device *dev)
+ {
+- struct gsc_asic *asp;
+ struct gsc_irq gsc_irq;
+ int ret;
+
+- asp = kmalloc(sizeof(*asp), GFP_KERNEL);
+- if(!asp)
+- return -ENOMEM;
+-
+- asp->version = gsc_readb(dev->hpa + ASP_VER_OFFSET) & 0xf;
+- asp->name = (asp->version == 1) ? "Asp" : "Cutoff";
+- asp->hpa = ASP_INTERRUPT_ADDR;
++ asp.version = gsc_readb(dev->hpa + ASP_VER_OFFSET) & 0xf;
++ asp.name = (asp.version == 1) ? "Asp" : "Cutoff";
++ asp.hpa = ASP_INTERRUPT_ADDR;
+
+ printk(KERN_INFO "%s version %d at 0x%lx found.\n",
+- asp->name, asp->version, dev->hpa);
++ asp.name, asp.version, dev->hpa);
+
+ /* the IRQ ASP should use */
+ ret = -EBUSY;
+@@ -87,9 +92,9 @@
+ goto out;
+ }
+
+- asp->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
++ asp.eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data;
+
+- ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "asp", asp);
++ ret = request_irq(gsc_irq.irq, gsc_asic_intr, 0, "asp", &asp);
+ if (ret < 0)
+ goto out;
+
+@@ -97,13 +102,13 @@
+ gsc_writel((1 << (31 - ASP_GSC_IRQ)),VIPER_INT_WORD);
+
+ /* Done init'ing, register this driver */
+- ret = gsc_common_setup(dev, asp);
++ ret = gsc_common_setup(dev, &asp);
+ if (ret)
+ goto out;
+
+- gsc_fixup_irqs(dev, asp, asp_choose_irq);
++ gsc_fixup_irqs(dev, &asp, asp_choose_irq);
+ /* Mongoose is a sibling of Asp, not a child... */
+- gsc_fixup_irqs(parisc_parent(dev), asp, asp_choose_irq);
++ gsc_fixup_irqs(parisc_parent(dev), &asp, asp_choose_irq);
+
+ /* initialize the chassis LEDs */
+ #ifdef CONFIG_CHASSIS_LCD_LED
+@@ -111,10 +116,7 @@
+ ASP_LED_ADDR);
+ #endif
+
+- return 0;
+-
+-out:
+- kfree(asp);
++ out:
+ return ret;
+ }
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/ccio-dma.c CVS2_6_11_PA2/drivers/parisc/ccio-dma.c
+--- LINUS_2_6_11/drivers/parisc/ccio-dma.c 2004-11-17 11:07:08.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/ccio-dma.c 2005-03-06 16:48:39.000000000 -0700
+@@ -262,8 +262,6 @@
+ struct resource mmio_region[2]; /* The "routed" MMIO regions */
+ };
+
+-/* Ratio of Host MEM to IOV Space size */
+-static unsigned long ccio_mem_ratio = 4;
+ static struct ioc *ioc_list;
+ static int ioc_count;
+
+@@ -559,7 +557,7 @@
+ ccio_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
+ unsigned long hints)
+ {
+- register unsigned long pa = (volatile unsigned long) vba;
++ register unsigned long pa;
+ register unsigned long ci; /* coherent index */
+
+ /* We currently only support kernel addresses */
+@@ -1243,6 +1241,21 @@
+ #define CCIO_CHAINID_MASK 0xff
+ #endif /* 0 */
+
++/* We *can't* support JAVA (T600). Venture there at your own risk. */
++static struct parisc_device_id ccio_tbl[] = {
++ { HPHW_IOA, HVERSION_REV_ANY_ID, U2_IOA_RUNWAY, 0xb }, /* U2 */
++ { HPHW_IOA, HVERSION_REV_ANY_ID, UTURN_IOA_RUNWAY, 0xb }, /* UTurn */
++ { 0, }
++};
++
++static int ccio_probe(struct parisc_device *dev);
++
++static struct parisc_driver ccio_driver = {
++ .name = "U2:Uturn",
++ .id_table = ccio_tbl,
++ .probe = ccio_probe,
++};
++
+ /**
+ * ccio_ioc_init - Initalize the I/O Controller
+ * @ioc: The I/O Controller.
+@@ -1254,9 +1267,9 @@
+ static void
+ ccio_ioc_init(struct ioc *ioc)
+ {
+- int i, iov_order;
++ int i;
++ unsigned int iov_order;
+ u32 iova_space_size;
+- unsigned long physmem;
+
+ /*
+ ** Determine IOVA Space size from memory size.
+@@ -1269,17 +1282,16 @@
+ ** Hot-Plug/Removal of PCI cards. (aka PCI OLARD).
+ */
+
++ iova_space_size = (u32) (num_physpages / count_parisc_driver(&ccio_driver));
++
+ /* limit IOVA space size to 1MB-1GB */
+
+- physmem = num_physpages << PAGE_SHIFT;
+- if(physmem < (ccio_mem_ratio * 1024 * 1024)) {
+- iova_space_size = 1024 * 1024;
++ if (iova_space_size < (1 << (20 - PAGE_SHIFT))) {
++ iova_space_size = 1 << (20 - PAGE_SHIFT);
+ #ifdef __LP64__
+- } else if(physmem > (ccio_mem_ratio * 512 * 1024 * 1024)) {
+- iova_space_size = 512 * 1024 * 1024;
++ } else if (iova_space_size > (1 << (30 - PAGE_SHIFT))) {
++ iova_space_size = 1 << (30 - PAGE_SHIFT);
+ #endif
+- } else {
+- iova_space_size = (u32)(physmem / ccio_mem_ratio);
+ }
+
+ /*
+@@ -1295,10 +1307,10 @@
+ ** this is the case under linux."
+ */
+
+- iov_order = get_order(iova_space_size) >> (IOVP_SHIFT - PAGE_SHIFT);
+- BUG_ON(iov_order > (30 - IOVP_SHIFT)); /* iova_space_size <= 1GB */
+- BUG_ON(iov_order < (20 - IOVP_SHIFT)); /* iova_space_size >= 1MB */
+- iova_space_size = 1 << (iov_order + IOVP_SHIFT);
++ iov_order = get_order(iova_space_size << PAGE_SHIFT);
++
++ /* iova_space_size is now bytes, not pages */
++ iova_space_size = 1 << (iov_order + PAGE_SHIFT);
+
+ ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64);
+
+@@ -1307,9 +1319,12 @@
+ /* Verify it's a power of two */
+ BUG_ON((1 << get_order(ioc->pdir_size)) != (ioc->pdir_size >> PAGE_SHIFT));
+
+- DBG_INIT("%s() hpa 0x%p mem %luMB IOV %dMB (%d bits) PDIR size 0x%0x",
+- __FUNCTION__, ioc->ioc_hpa, physmem>>20, iova_space_size>>20,
+- iov_order + PAGE_SHIFT, ioc->pdir_size);
++ DBG_INIT("%s() hpa 0x%lx mem %luMB IOV %dMB (%d bits)\n",
++ __FUNCTION__,
++ ioc->ioc_hpa,
++ (unsigned long) num_physpages >> (20 - PAGE_SHIFT),
++ iova_space_size>>20,
++ iov_order + PAGE_SHIFT);
+
+ ioc->pdir_base = (u64 *)__get_free_pages(GFP_KERNEL,
+ get_order(ioc->pdir_size));
+@@ -1566,19 +1581,6 @@
+ return 0;
+ }
+
+-/* We *can't* support JAVA (T600). Venture there at your own risk. */
+-static struct parisc_device_id ccio_tbl[] = {
+- { HPHW_IOA, HVERSION_REV_ANY_ID, U2_IOA_RUNWAY, 0xb }, /* U2 */
+- { HPHW_IOA, HVERSION_REV_ANY_ID, UTURN_IOA_RUNWAY, 0xb }, /* UTurn */
+- { 0, }
+-};
+-
+-static struct parisc_driver ccio_driver = {
+- .name = "U2:Uturn",
+- .id_table = ccio_tbl,
+- .probe = ccio_probe,
+-};
+-
+ /**
+ * ccio_init - ccio initalization procedure.
+ *
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/eisa.c CVS2_6_11_PA2/drivers/parisc/eisa.c
+--- LINUS_2_6_11/drivers/parisc/eisa.c 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/eisa.c 2005-02-15 08:23:58.000000000 -0700
+@@ -44,6 +44,7 @@
+ #include <asm/parisc-device.h>
+ #include <asm/delay.h>
+ #include <asm/eisa_bus.h>
++#include <asm/eisa_eeprom.h>
+
+ #if 0
+ #define EISA_DBG(msg, arg... ) printk(KERN_DEBUG "eisa: " msg , ## arg )
+@@ -56,6 +57,8 @@
+
+ static DEFINE_SPINLOCK(eisa_irq_lock);
+
++void __iomem *eisa_eeprom_addr;
++
+ /* We can only have one EISA adapter in the system because neither
+ * implementation can be flexed.
+ */
+@@ -351,6 +354,7 @@
+ }
+
+ EISA_bus = 1;
++
+ if (dev->num_addrs) {
+ /* newer firmware hand out the eeprom address */
+ eisa_dev.eeprom_addr = dev->addr[0];
+@@ -362,8 +366,9 @@
+ eisa_dev.eeprom_addr = MIRAGE_EEPROM_BASE_ADDR;
+ }
+ }
+- eisa_eeprom_init(eisa_dev.eeprom_addr);
+- result = eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space, &eisa_dev.hba.lmmio_space);
++ eisa_eeprom_addr = ioremap(eisa_dev.eeprom_addr, HPEE_MAX_LENGTH);
++ result = eisa_enumerator(eisa_dev.eeprom_addr, &eisa_dev.hba.io_space,
++ &eisa_dev.hba.lmmio_space);
+ init_eisa_pic();
+
+ if (result >= 0) {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/eisa_eeprom.c CVS2_6_11_PA2/drivers/parisc/eisa_eeprom.c
+--- LINUS_2_6_11/drivers/parisc/eisa_eeprom.c 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/eisa_eeprom.c 2005-03-01 23:47:37.000000000 -0700
+@@ -19,7 +19,6 @@
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+@@ -32,8 +31,6 @@
+
+ #define EISA_EEPROM_MINOR 241
+
+-static unsigned long eeprom_addr;
+-
+ static loff_t eisa_eeprom_llseek(struct file *file, loff_t offset, int origin )
+ {
+ switch (origin) {
+@@ -64,7 +61,7 @@
+ tmp = kmalloc(count, GFP_KERNEL);
+ if (tmp) {
+ for (i = 0; i < count; i++)
+- tmp[i] = gsc_readb(eeprom_addr+(*ppos)++);
++ tmp[i] = readb(eisa_eeprom_addr+(*ppos)++);
+
+ if (copy_to_user (buf, tmp, count))
+ ret = -EFAULT;
+@@ -86,7 +83,7 @@
+
+ static int eisa_eeprom_open(struct inode *inode, struct file *file)
+ {
+- if (file->f_mode & 2 || eeprom_addr == 0)
++ if (file->f_mode & 2)
+ return -EINVAL;
+
+ return 0;
+@@ -109,22 +106,18 @@
+ .release = eisa_eeprom_release,
+ };
+
+-static struct miscdevice eisa_eeprom_dev=
+-{
++static struct miscdevice eisa_eeprom_dev = {
+ EISA_EEPROM_MINOR,
+- "eisa eeprom",
++ "eisa_eeprom",
+ &eisa_eeprom_fops
+ };
+
+-int __init eisa_eeprom_init(unsigned long addr)
++static int __init eisa_eeprom_init(void)
+ {
+ int retval;
+
+- /* XXX why return success when we haven't done anything? */
+- if (!addr)
+- return 0;
+-
+- eeprom_addr = addr;
++ if (!eisa_eeprom_addr)
++ return -ENODEV;
+
+ retval = misc_register(&eisa_eeprom_dev);
+ if (retval < 0) {
+@@ -132,8 +125,10 @@
+ return retval;
+ }
+
+- printk(KERN_INFO "EISA EEPROM at 0x%lx\n", eeprom_addr);
++ printk(KERN_INFO "EISA EEPROM at 0x%p\n", eisa_eeprom_addr);
+ return 0;
+ }
+
+ MODULE_LICENSE("GPL");
++
++module_init(eisa_eeprom_init);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/gsc.c CVS2_6_11_PA2/drivers/parisc/gsc.c
+--- LINUS_2_6_11/drivers/parisc/gsc.c 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/gsc.c 2005-01-22 17:09:47.000000000 -0700
+@@ -38,14 +38,14 @@
+
+ int gsc_alloc_irq(struct gsc_irq *i)
+ {
+- int irq = txn_alloc_irq();
++ int irq = txn_alloc_irq(GSC_EIM_WIDTH);
+ if (irq < 0) {
+ printk("cannot get irq\n");
+ return irq;
+ }
+
+ i->txn_addr = txn_alloc_addr(irq);
+- i->txn_data = txn_alloc_data(irq, GSC_EIM_WIDTH);
++ i->txn_data = txn_alloc_data(irq);
+ i->irq = irq;
+
+ return irq;
+@@ -64,7 +64,7 @@
+ }
+
+ i->txn_addr = txn_alloc_addr(irq);
+- i->txn_data = txn_alloc_data(irq, GSC_EIM_WIDTH);
++ i->txn_data = txn_alloc_data(irq);
+ i->irq = irq;
+
+ return irq;
+@@ -171,12 +171,16 @@
+
+ void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp)
+ {
+- int irq = gsc_assign_irq(&gsc_asic_interrupt_type, asic);
+- if (irq == NO_IRQ)
+- return;
++ int irq = asic->global_irq[local_irq];
++
++ if (irq <= 0) {
++ irq = gsc_assign_irq(&gsc_asic_interrupt_type, asic);
++ if (irq == NO_IRQ)
++ return;
+
++ asic->global_irq[local_irq] = irq;
++ }
+ *irqp = irq;
+- asic->global_irq[local_irq] = irq;
+ }
+
+ void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
+@@ -198,9 +202,15 @@
+ int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic)
+ {
+ struct resource *res;
++ int i;
+
+ gsc_asic->gsc = parent;
+
++ /* Initialise local irq -> global irq mapping */
++ for (i = 0; i < 32; i++) {
++ gsc_asic->global_irq[i] = NO_IRQ;
++ }
++
+ /* allocate resource region */
+ res = request_mem_region(gsc_asic->hpa, 0x100000, gsc_asic->name);
+ if (res) {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/hppb.c CVS2_6_11_PA2/drivers/parisc/hppb.c
+--- LINUS_2_6_11/drivers/parisc/hppb.c 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/hppb.c 2005-03-01 23:47:37.000000000 -0700
+@@ -16,7 +16,6 @@
+ **
+ */
+
+-#include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/init.h>
+ #include <linux/mm.h>
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/iosapic.c CVS2_6_11_PA2/drivers/parisc/iosapic.c
+--- LINUS_2_6_11/drivers/parisc/iosapic.c 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/iosapic.c 2005-02-11 14:28:18.000000000 -0700
+@@ -158,31 +158,9 @@
+
+
+ #ifdef DEBUG_IOSAPIC
+-static char assert_buf[128];
+-
+-static int
+-assert_failed (char *a, char *f, int l)
+-{
+- sprintf(assert_buf,
+- "ASSERT(%s) failed!\nline %d in %s\n",
+- a, /* assertion text */
+- l, /* line number */
+- f); /* file name */
+- panic(assert_buf);
+- return 0;
+-}
+-
+-#undef ASSERT
+-#define ASSERT(EX) { if (!(EX)) assert_failed(# EX, __FILE__, __LINE__); }
+-
+ #define DBG(x...) printk(x)
+-
+ #else /* DEBUG_IOSAPIC */
+-
+ #define DBG(x...)
+-#undef ASSERT
+-#define ASSERT(EX)
+-
+ #endif /* DEBUG_IOSAPIC */
+
+ #ifdef DEBUG_IOSAPIC_IRT
+@@ -191,6 +169,12 @@
+ #define DBG_IRT(x...)
+ #endif
+
++#ifdef CONFIG_64BIT
++#define COMPARE_IRTE_ADDR(irte, hpa) ((irte)->dest_iosapic_addr == (hpa))
++#else
++#define COMPARE_IRTE_ADDR(irte, hpa) \
++ ((irte)->dest_iosapic_addr == ((hpa) | 0xffffffff00000000ULL))
++#endif
+
+ #define IOSAPIC_REG_SELECT 0x00
+ #define IOSAPIC_REG_WINDOW 0x10
+@@ -201,33 +185,18 @@
+ #define IOSAPIC_IRDT_ENTRY(idx) (0x10+(idx)*2)
+ #define IOSAPIC_IRDT_ENTRY_HI(idx) (0x11+(idx)*2)
+
+-static inline unsigned int iosapic_read(unsigned long iosapic, unsigned int reg)
++static inline unsigned int iosapic_read(void __iomem *iosapic, unsigned int reg)
+ {
+ writel(reg, iosapic + IOSAPIC_REG_SELECT);
+ return readl(iosapic + IOSAPIC_REG_WINDOW);
+ }
+
+-static inline void iosapic_write(unsigned long iosapic, unsigned int reg, u32 val)
++static inline void iosapic_write(void __iomem *iosapic, unsigned int reg, u32 val)
+ {
+ writel(reg, iosapic + IOSAPIC_REG_SELECT);
+ writel(val, iosapic + IOSAPIC_REG_WINDOW);
+ }
+
+-/*
+-** GFP_KERNEL includes __GFP_WAIT flag and that may not
+-** be acceptable. Since this is boot time, we shouldn't have
+-** to wait ever and this code should (will?) never get called
+-** from the interrrupt context.
+-*/
+-#define IOSAPIC_KALLOC(a_type, cnt) \
+- (a_type *) kmalloc(sizeof(a_type)*(cnt), GFP_KERNEL)
+-#define IOSAPIC_FREE(addr, f_type, cnt) kfree((void *)addr)
+-
+-
+-#define IOSAPIC_LOCK(lck) spin_lock_irqsave(lck, irqflags)
+-#define IOSAPIC_UNLOCK(lck) spin_unlock_irqrestore(lck, irqflags)
+-
+-
+ #define IOSAPIC_VERSION_MASK 0x000000ff
+ #define IOSAPIC_VERSION(ver) ((int) (ver & IOSAPIC_VERSION_MASK))
+
+@@ -265,52 +234,64 @@
+ static struct irt_entry *irt_cell;
+ static size_t irt_num_entry;
+
++static struct irt_entry *iosapic_alloc_irt(int num_entries)
++{
++ unsigned long a;
+
++ /* The IRT needs to be 8-byte aligned for the PDC call.
++ * Normally kmalloc would guarantee larger alignment, but
++ * if CONFIG_DEBUG_SLAB is enabled, then we can get only
++ * 4-byte alignment on 32-bit kernels
++ */
++ a = (unsigned long)kmalloc(sizeof(struct irt_entry) * num_entries + 8, GFP_KERNEL);
++ a = (a + 7) & ~7;
++ return (struct irt_entry *)a;
++}
+
+-/*
+-** iosapic_load_irt
+-**
+-** The "Get PCI INT Routing Table Size" option returns the number of
+-** entries in the PCI interrupt routing table for the cell specified
+-** in the cell_number argument. The cell number must be for a cell
+-** within the caller's protection domain.
+-**
+-** The "Get PCI INT Routing Table" option returns, for the cell
+-** specified in the cell_number argument, the PCI interrupt routing
+-** table in the caller allocated memory pointed to by mem_addr.
+-** We assume the IRT only contains entries for I/O SAPIC and
+-** calculate the size based on the size of I/O sapic entries.
+-**
+-** The PCI interrupt routing table entry format is derived from the
+-** IA64 SAL Specification 2.4. The PCI interrupt routing table defines
+-** the routing of PCI interrupt signals between the PCI device output
+-** "pins" and the IO SAPICs' input "lines" (including core I/O PCI
+-** devices). This table does NOT include information for devices/slots
+-** behind PCI to PCI bridges. See PCI to PCI Bridge Architecture Spec.
+-** for the architected method of routing of IRQ's behind PPB's.
+-*/
++/**
++ * iosapic_load_irt - Fill in the interrupt routing table
++ * @cell_num: The cell number of the CPU we're currently executing on
++ * @irt: The address to place the new IRT at
++ * @return The number of entries found
++ *
++ * The "Get PCI INT Routing Table Size" option returns the number of
++ * entries in the PCI interrupt routing table for the cell specified
++ * in the cell_number argument. The cell number must be for a cell
++ * within the caller's protection domain.
++ *
++ * The "Get PCI INT Routing Table" option returns, for the cell
++ * specified in the cell_number argument, the PCI interrupt routing
++ * table in the caller allocated memory pointed to by mem_addr.
++ * We assume the IRT only contains entries for I/O SAPIC and
++ * calculate the size based on the size of I/O sapic entries.
++ *
++ * The PCI interrupt routing table entry format is derived from the
++ * IA64 SAL Specification 2.4. The PCI interrupt routing table defines
++ * the routing of PCI interrupt signals between the PCI device output
++ * "pins" and the IO SAPICs' input "lines" (including core I/O PCI
++ * devices). This table does NOT include information for devices/slots
++ * behind PCI to PCI bridges. See PCI to PCI Bridge Architecture Spec.
++ * for the architected method of routing of IRQ's behind PPB's.
++ */
+
+
+-static int __init /* return number of entries as success/fail flag */
++static int __init
+ iosapic_load_irt(unsigned long cell_num, struct irt_entry **irt)
+ {
+ long status; /* PDC return value status */
+ struct irt_entry *table; /* start of interrupt routing tbl */
+ unsigned long num_entries = 0UL;
+
+- ASSERT(NULL != irt);
++ BUG_ON(!irt);
+
+ if (is_pdc_pat()) {
+-
+ /* Use pat pdc routine to get interrupt routing table size */
+ DBG("calling get_irt_size (cell %ld)\n", cell_num);
+ status = pdc_pat_get_irt_size(&num_entries, cell_num);
+ DBG("get_irt_size: %ld\n", status);
+
+- ASSERT(status == PDC_OK);
+-
+- /* save the number of entries in the table */
+- ASSERT(0UL != num_entries);
++ BUG_ON(status != PDC_OK);
++ BUG_ON(num_entries == 0);
+
+ /*
+ ** allocate memory for interrupt routing table
+@@ -318,45 +299,47 @@
+ ** the contents of the table are exclusively
+ ** for I/O sapic devices.
+ */
+- table = IOSAPIC_KALLOC(struct irt_entry, num_entries);
++ table = iosapic_alloc_irt(num_entries);
+ if (table == NULL) {
+- printk(KERN_WARNING MODULE_NAME ": read_irt : can not alloc mem for IRT\n");
++ printk(KERN_WARNING MODULE_NAME ": read_irt : can "
++ "not alloc mem for IRT\n");
+ return 0;
+ }
+
+ /* get PCI INT routing table */
+ status = pdc_pat_get_irt(table, cell_num);
+ DBG("pdc_pat_get_irt: %ld\n", status);
+- ASSERT(status == PDC_OK);
++ WARN_ON(status != PDC_OK);
+ } else {
+ /*
+ ** C3000/J5000 (and similar) platforms with Sprockets PDC
+ ** will return exactly one IRT for all iosapics.
+ ** So if we have one, don't need to get it again.
+ */
+- if (NULL != irt_cell)
++ if (irt_cell)
+ return 0;
+
+ /* Should be using the Elroy's HPA, but it's ignored anyway */
+ status = pdc_pci_irt_size(&num_entries, 0);
+ DBG("pdc_pci_irt_size: %ld\n", status);
+
+- if (PDC_OK != status) {
++ if (status != PDC_OK) {
+ /* Not a "legacy" system with I/O SAPIC either */
+ return 0;
+ }
+
+- ASSERT(0UL != num_entries);
++ BUG_ON(num_entries == 0);
+
+- table = IOSAPIC_KALLOC(struct irt_entry, num_entries);
+- if (table == NULL) {
+- printk(KERN_WARNING MODULE_NAME ": read_irt : can not alloc mem for IRT\n");
++ table = iosapic_alloc_irt(num_entries);
++ if (!table) {
++ printk(KERN_WARNING MODULE_NAME ": read_irt : can "
++ "not alloc mem for IRT\n");
+ return 0;
+ }
+
+ /* HPA ignored by this call too. */
+ status = pdc_pci_irt(num_entries, 0, table);
+- ASSERT(PDC_OK == status);
++ BUG_ON(status != PDC_OK);
+ }
+
+ /* return interrupt table address */
+@@ -390,16 +373,10 @@
+
+
+
+-void __init
+-iosapic_init(void)
++void __init iosapic_init(void)
+ {
+ unsigned long cell = 0;
+
+- /* init global data */
+- spin_lock_init(&iosapic_lock);
+- iosapic_list = (struct iosapic_info *) NULL;
+- iosapic_count = 0;
+-
+ DBG("iosapic_init()\n");
+
+ #ifdef __LP64__
+@@ -414,11 +391,9 @@
+ }
+ #endif
+
+- /*
+- ** get IRT for this cell.
+- */
+- irt_num_entry = iosapic_load_irt(cell, &irt_cell);
+- if (0 == irt_num_entry)
++ /* get interrupt routing table for this cell */
++ irt_num_entry = iosapic_load_irt(cell, &irt_cell);
++ if (irt_num_entry == 0)
+ irt_cell = NULL; /* old PDC w/o iosapic */
+ }
+
+@@ -459,10 +434,7 @@
+ continue;
+ }
+
+- /*
+- ** Compare: dest_iosapic_addr, src_bus_irq_devno
+- */
+- if (i->dest_iosapic_addr != (u64) ((long) isi->isi_hpa))
++ if (!COMPARE_IRTE_ADDR(i, isi->isi_hpa))
+ continue;
+
+ if ((i->src_bus_irq_devno & IRT_IRQ_DEVNO_MASK) != irq_devno)
+@@ -506,10 +478,10 @@
+
+ pci_read_config_byte(pcidev, PCI_INTERRUPT_PIN, &intr_pin);
+
+- DBG_IRT("iosapic_xlate_pin() SLOT %d pin %d\n",
+- PCI_SLOT(pcidev->devfn), intr_pin);
++ DBG_IRT("iosapic_xlate_pin(%s) SLOT %d pin %d\n",
++ pcidev->slot_name, PCI_SLOT(pcidev->devfn), intr_pin);
+
+- if (0 == intr_pin) {
++ if (intr_pin == 0) {
+ /* The device does NOT support/use IRQ lines. */
+ return NULL;
+ }
+@@ -606,7 +578,6 @@
+ {
+ u32 mode = 0;
+ struct irt_entry *p = vi->irte;
+- ASSERT(NULL != vi->irte);
+
+ if ((p->polarity_trigger & IRT_PO_MASK) == IRT_ACTIVE_LO)
+ mode |= IOSAPIC_IRDT_PO_LOW;
+@@ -619,7 +590,6 @@
+ ** PA doesn't support EXTINT or LPRIO bits.
+ */
+
+- ASSERT(vi->txn_data);
+ *dp0 = mode | (u32) vi->txn_data;
+
+ /*
+@@ -802,22 +772,23 @@
+
+ vi->irte = irte;
+
+- /* Allocate processor IRQ */
+- vi->txn_irq = txn_alloc_irq();
+-
+ /*
++ * Allocate processor IRQ
++ *
+ * XXX/FIXME The txn_alloc_irq() code and related code should be
+ * moved to enable_irq(). That way we only allocate processor IRQ
+ * bits for devices that actually have drivers claiming them.
+ * Right now we assign an IRQ to every PCI device present,
+ * regardless of whether it's used or not.
+ */
++ vi->txn_irq = txn_alloc_irq(8);
++
+ if (vi->txn_irq < 0)
+ panic("I/O sapic: couldn't get TXN IRQ\n");
+
+ /* enable_irq() will use txn_* to program IRdT */
+ vi->txn_addr = txn_alloc_addr(vi->txn_irq);
+- vi->txn_data = txn_alloc_data(vi->txn_irq, 8);
++ vi->txn_data = txn_alloc_data(vi->txn_irq);
+
+ vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
+ vi->eoi_data = cpu_to_le32(vi->txn_data);
+@@ -841,10 +812,7 @@
+ static unsigned int
+ iosapic_rd_version(struct iosapic_info *isi)
+ {
+- ASSERT(isi);
+- ASSERT(isi->isi_hpa);
+-
+- return iosapic_read(isi->isi_hpa, IOSAPIC_REG_VERSION);
++ return iosapic_read(isi->addr, IOSAPIC_REG_VERSION);
+ }
+
+
+@@ -866,44 +834,38 @@
+ int cnt; /* track how many entries we've looked at */
+
+ /*
+- ** Astro based platforms can't support PCI OLARD if they
+- ** implement the legacy PDC (not PAT). Though Legacy PDC
+- ** supports an IRT, LBA's with no device under them
+- ** are *not* listed in the IRT.
+- ** Search the IRT and ignore iosapic's which aren't
+- ** in the IRT.
+- */
+- ASSERT(NULL != irte); /* always have built-in devices */
++ * Astro based platforms can only support PCI OLARD if they implement
++ * PAT PDC. Legacy PDC omits LBAs with no PCI devices from the IRT.
++ * Search the IRT and ignore iosapic's which aren't in the IRT.
++ */
+ for (cnt=0; cnt < irt_num_entry; cnt++, irte++) {
+- ASSERT(IRT_IOSAPIC_TYPE == irte->entry_type);
+- /*
+- ** We need sign extension of the hpa on 32-bit kernels.
+- ** The address in the IRT is *always* 64 bit and really
+- ** is an unsigned quantity (like all physical addresses).
+- */
+- if (irte->dest_iosapic_addr == (s64) ((long) hpa))
++ WARN_ON(IRT_IOSAPIC_TYPE != irte->entry_type);
++ if (COMPARE_IRTE_ADDR(irte, hpa))
+ break;
+ }
+
+- if (cnt >= irt_num_entry)
+- return (NULL);
++ if (cnt >= irt_num_entry) {
++ DBG("iosapic_register() ignoring 0x%lx (NOT FOUND)\n", hpa);
++ return NULL;
++ }
+
+- if ((isi = IOSAPIC_KALLOC(struct iosapic_info, 1)) == NULL) {
++ isi = (struct iosapic_info *)kmalloc(sizeof(struct iosapic_info), GFP_KERNEL);
++ if (!isi) {
+ BUG();
+- return (NULL);
++ return NULL;
+ }
+
+ memset(isi, 0, sizeof(struct iosapic_info));
+
+- isi->isi_hpa = hpa;
+- isi->isi_version = iosapic_rd_version(isi);
++ isi->addr = ioremap(hpa, 4096);
++ isi->isi_hpa = hpa;
++ isi->isi_version = iosapic_rd_version(isi);
+ isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
+
+- vip = isi->isi_vector =
+- IOSAPIC_KALLOC(struct vector_info, isi->isi_num_vectors);
+-
++ vip = isi->isi_vector = (struct vector_info *)
++ kmalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL);
+ if (vip == NULL) {
+- IOSAPIC_FREE(isi, struct iosapic_info, 1);
++ kfree(isi);
+ return NULL;
+ }
+
+@@ -924,7 +886,6 @@
+ {
+ unsigned int i, *irp = (unsigned int *) irt;
+
+- ASSERT(NULL != irt);
+
+ printk(KERN_DEBUG MODULE_NAME ": Interrupt Routing Table (%lx entries)\n", num_entry);
+
+@@ -938,8 +899,6 @@
+ static void
+ iosapic_prt_vi(struct vector_info *vi)
+ {
+- ASSERT(NULL != vi);
+-
+ printk(KERN_DEBUG MODULE_NAME ": vector_info[%d] is at %p\n", vi->irqline, vi);
+ printk(KERN_DEBUG "\t\tstatus: %.4x\n", vi->status);
+ printk(KERN_DEBUG "\t\ttxn_irq: %d\n", vi->txn_irq);
+@@ -953,10 +912,9 @@
+ static void
+ iosapic_prt_isi(struct iosapic_info *isi)
+ {
+- ASSERT(NULL != isi);
+ printk(KERN_DEBUG MODULE_NAME ": io_sapic_info at %p\n", isi);
+ printk(KERN_DEBUG "\t\tisi_hpa: %lx\n", isi->isi_hpa);
+- printk(KERN_DEBUG "\t\tisi_status: %x\n", isi->isi_status);
++ printk(KERN_DEBUG "\t\tisi_status: %x\n", isi->isi_status);
+ printk(KERN_DEBUG "\t\tisi_version: %x\n", isi->isi_version);
+ printk(KERN_DEBUG "\t\tisi_vector: %p\n", isi->isi_vector);
+ }
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/lasi.c CVS2_6_11_PA2/drivers/parisc/lasi.c
+--- LINUS_2_6_11/drivers/parisc/lasi.c 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/lasi.c 2005-01-11 21:10:48.000000000 -0700
+@@ -139,7 +139,7 @@
+ break;
+ }
+
+- register_led_driver(DISPLAY_MODEL_LASI, LED_CMD_REG_NONE, (char *)datareg);
++ register_led_driver(DISPLAY_MODEL_LASI, LED_CMD_REG_NONE, datareg);
+ }
+ #endif
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/lba_pci.c CVS2_6_11_PA2/drivers/parisc/lba_pci.c
+--- LINUS_2_6_11/drivers/parisc/lba_pci.c 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/lba_pci.c 2005-02-12 00:58:59.000000000 -0700
+@@ -51,11 +51,6 @@
+ #include <asm/iosapic.h> /* for iosapic_register() */
+ #include <asm/io.h> /* read/write stuff */
+
+-#ifndef TRUE
+-#define TRUE (1 == 1)
+-#define FALSE (1 == 0)
+-#endif
+-
+ #undef DEBUG_LBA /* general stuff */
+ #undef DEBUG_LBA_PORT /* debug I/O Port access */
+ #undef DEBUG_LBA_CFG /* debug Config Space Access (ie PCI Bus walk) */
+@@ -88,18 +83,6 @@
+ #define DBG_PAT(x...)
+ #endif
+
+-#ifdef DEBUG_LBA
+-#undef ASSERT
+-#define ASSERT(expr) \
+- if(!(expr)) { \
+- printk("\n%s:%d: Assertion " #expr " failed!\n", \
+- __FILE__, __LINE__); \
+- panic(#expr); \
+- }
+-#else
+-#define ASSERT(expr)
+-#endif
+-
+
+ /*
+ ** Config accessor functions only pass in the 8-bit bus number and not
+@@ -184,6 +167,7 @@
+
+ /* non-postable I/O port space, densely packed */
+ #define LBA_PORT_BASE (PCI_F_EXTEND | 0xfee00000UL)
++static void __iomem *astro_iop_base;
+
+ #define ELROY_HVERS 0x782
+ #define MERCURY_HVERS 0x783
+@@ -214,8 +198,8 @@
+ spinlock_t lba_lock;
+ void *iosapic_obj;
+
+-#ifdef CONFIG_PARISC64
+- unsigned long iop_base; /* PA_VIEW - for IO port accessor funcs */
++#ifdef CONFIG_64BIT
++ void __iomem * iop_base; /* PA_VIEW - for IO port accessor funcs */
+ #endif
+
+ int flags; /* state/functionality enabled */
+@@ -225,15 +209,9 @@
+
+ static u32 lba_t32;
+
+-/*
+-** lba "flags"
+-*/
+-#define LBA_FLAG_NO_DMA_DURING_CFG 0x01
++/* lba flags */
+ #define LBA_FLAG_SKIP_PROBE 0x10
+
+-/* Tape Release 4 == hw_rev 5 */
+-#define LBA_TR4PLUS(d) ((d)->hw_rev > 0x4)
+-#define LBA_DMA_DURING_CFG_DISABLED(d) ((d)->flags & LBA_FLAG_NO_DMA_DURING_CFG)
+ #define LBA_SKIP_PROBE(d) ((d)->flags & LBA_FLAG_SKIP_PROBE)
+
+
+@@ -293,7 +271,7 @@
+
+ printk(KERN_DEBUG "(%p)", r->parent);
+ for (i = d; i ; --i) printk(" ");
+- printk(KERN_DEBUG "%p [%lx,%lx]/%x\n", r, r->start, r->end, (int) r->flags);
++ printk(KERN_DEBUG "%p [%lx,%lx]/%lx\n", r, r->start, r->end, r->flags);
+ lba_dump_res(r->child, d+2);
+ lba_dump_res(r->sibling, d);
+ }
+@@ -303,7 +281,7 @@
+ ** LBA rev 2.0, 2.1, 2.2, and 3.0 bus walks require a complex
+ ** workaround for cfg cycles:
+ ** -- preserve LBA state
+-** -- LBA_FLAG_NO_DMA_DURING_CFG workaround
++** -- prevent any DMA from occurring
+ ** -- turn on smart mode
+ ** -- probe with config writes before doing config reads
+ ** -- check ERROR_STATUS
+@@ -313,25 +291,18 @@
+ ** The workaround is only used for device discovery.
+ */
+
+-static int
+-lba_device_present( u8 bus, u8 dfn, struct lba_device *d)
++static int lba_device_present(u8 bus, u8 dfn, struct lba_device *d)
+ {
+ u8 first_bus = d->hba.hba_bus->secondary;
+ u8 last_sub_bus = d->hba.hba_bus->subordinate;
+
+- ASSERT(bus >= first_bus);
+- ASSERT(bus <= last_sub_bus);
+- ASSERT((bus - first_bus) < LBA_MAX_NUM_BUSES);
+-
+ if ((bus < first_bus) ||
+ (bus > last_sub_bus) ||
+- ((bus - first_bus) >= LBA_MAX_NUM_BUSES))
+- {
+- /* devices that fall into any of these cases won't get claimed */
+- return(FALSE);
++ ((bus - first_bus) >= LBA_MAX_NUM_BUSES)) {
++ return 0;
+ }
+
+- return TRUE;
++ return 1;
+ }
+
+
+@@ -346,7 +317,6 @@
+ /* For LBA rev 2.0, 2.1, 2.2, and 3.0, we must disable DMA \
+ ** arbitration for full bus walks. \
+ */ \
+- if (LBA_DMA_DURING_CFG_DISABLED(d)) { \
+ /* Save contents of arb mask register. */ \
+ arb_mask = READ_REG32(d->hba.base_addr + LBA_ARB_MASK); \
+ \
+@@ -354,8 +324,7 @@
+ * Turn off all device arbitration bits (i.e. everything \
+ * except arbitration enable bit). \
+ */ \
+- WRITE_REG32(0x1, d->hba.base_addr + LBA_ARB_MASK); \
+- } \
++ WRITE_REG32(0x1, d->hba.base_addr + LBA_ARB_MASK); \
+ \
+ /* \
+ * Set the smart mode bit so that master aborts don't cause \
+@@ -375,7 +344,7 @@
+ * Read address register to ensure that LBA is the bus master, \
+ * which implies that DMA traffic has stopped when DMA arb is off. \
+ */ \
+- lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR); \
++ lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR); \
+ /* \
+ * Generate a cfg write cycle (will have no affect on \
+ * Vendor ID register since read-only). \
+@@ -385,7 +354,7 @@
+ * Make sure write has completed before proceeding further, \
+ * i.e. before setting clear enable. \
+ */ \
+- lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR); \
++ lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR); \
+ }
+
+
+@@ -439,20 +408,16 @@
+ } \
+ }
+
+-#define LBA_CFG_TR4_ADDR_SETUP(d, addr) \
+- WRITE_REG32(((addr) & ~3), (d)->hba.base_addr + LBA_PCI_CFG_ADDR); \
+- lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR)
++#define LBA_CFG_TR4_ADDR_SETUP(d, addr) \
++ WRITE_REG32(((addr) & ~3), (d)->hba.base_addr + LBA_PCI_CFG_ADDR);
+
+-#define LBA_CFG_ADDR_SETUP(d, addr) { \
++#define LBA_CFG_ADDR_SETUP(d, addr) { \
+ WRITE_REG32(((addr) & ~3), (d)->hba.base_addr + LBA_PCI_CFG_ADDR); \
+ /* \
+- * HPREVISIT: \
+- * -- Potentially could skip this once DMA bug fixed. \
+- * \
+ * Read address register to ensure that LBA is the bus master, \
+ * which implies that DMA traffic has stopped when DMA arb is off. \
+ */ \
+- lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR); \
++ lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR); \
+ }
+
+
+@@ -465,12 +430,10 @@
+ * Restore error config register (turn off smart mode). \
+ */ \
+ WRITE_REG32(error_config, base + LBA_ERROR_CONFIG); \
+- if (LBA_DMA_DURING_CFG_DISABLED(d)) { \
+ /* \
+ * Restore arb mask register (reenables DMA arbitration). \
+ */ \
+ WRITE_REG32(arb_mask, base + LBA_ARB_MASK); \
+- } \
+ }
+
+
+@@ -478,39 +441,23 @@
+ static unsigned int
+ lba_rd_cfg(struct lba_device *d, u32 tok, u8 reg, u32 size)
+ {
+- u32 data = ~0;
++ u32 data = ~0U;
+ int error = 0;
+ u32 arb_mask = 0; /* used by LBA_CFG_SETUP/RESTORE */
+ u32 error_config = 0; /* used by LBA_CFG_SETUP/RESTORE */
+ u32 status_control = 0; /* used by LBA_CFG_SETUP/RESTORE */
+
+- ASSERT((size == sizeof(u8)) ||
+- (size == sizeof(u16)) ||
+- (size == sizeof(u32)));
+-
+- if ((size != sizeof(u8)) &&
+- (size != sizeof(u16)) &&
+- (size != sizeof(u32))) {
+- return(data);
+- }
+-
+ LBA_CFG_SETUP(d, tok);
+ LBA_CFG_PROBE(d, tok);
+ LBA_CFG_MASTER_ABORT_CHECK(d, d->hba.base_addr, tok, error);
+ if (!error) {
++ void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
++
+ LBA_CFG_ADDR_SETUP(d, tok | reg);
+ switch (size) {
+- case sizeof(u8):
+- data = (u32) READ_REG8(d->hba.base_addr + LBA_PCI_CFG_DATA + (reg & 3));
+- break;
+- case sizeof(u16):
+- data = (u32) READ_REG16(d->hba.base_addr + LBA_PCI_CFG_DATA + (reg & 2));
+- break;
+- case sizeof(u32):
+- data = READ_REG32(d->hba.base_addr + LBA_PCI_CFG_DATA);
+- break;
+- default:
+- break; /* leave data as -1 */
++ case 1: data = (u32) READ_REG8(data_reg + (reg & 3)); break;
++ case 2: data = (u32) READ_REG16(data_reg+ (reg & 2)); break;
++ case 4: data = READ_REG32(data_reg); break;
+ }
+ }
+ LBA_CFG_RESTORE(d, d->hba.base_addr);
+@@ -518,142 +465,26 @@
+ }
+
+
+-#if USE_PAT_PDC_CFG
+-
+-/* PAT PDC needs to be relocated in order to perform properly.
+- * tg3 driver does about 1600 PCI Cfg writes to initialize the card.
+- * On 440Mhz A500, PDC takes ~20ms/write, or ~30 seconds per card.
+- * On PA8800, that takes about 5ms/write (8 seconds).
+- * But relocating PDC will burn at least 4MB of RAM.
+- * Easier/Cheaper to just maintain our own mercury cfg ops.
+- */
+-#define pat_cfg_addr(bus, devfn, addr) (((bus) << 16) | ((devfn) << 8) | (addr))
+-
+-static int pat_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
+-{
+- int tok = pat_cfg_addr(bus->number, devfn, pos);
+- u32 tmp;
+- int ret = pdc_pat_io_pci_cfg_read(tok, size, &tmp);
+-
+- DBG_CFG("%s(%d:%d.%d+0x%02x) -> 0x%x %d\n", __FUNCTION__, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), pos, tmp, ret);
+-
+- switch (size) {
+- case 1: *data = (u8) tmp; return (tmp == (u8) ~0);
+- case 2: *data = (u16) tmp; return (tmp == (u16) ~0);
+- case 4: *data = (u32) tmp; return (tmp == (u32) ~0);
+- }
+- *data = ~0;
+- return (ret);
+-}
+-
+-static int pat_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data)
+-{
+- int tok = pat_cfg_addr(bus->number, devfn, pos);
+- int ret = pdc_pat_io_pci_cfg_write(tok, size, data);
+-
+- DBG_CFG("%s(%d:%d.%d+0x%02x, 0x%lx/%d)\n", __FUNCTION__, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), pos, data, size);
+- return (ret);
+-}
+-
+-static struct pci_ops pat_cfg_ops = {
+- .read = pat_cfg_read,
+- .write = pat_cfg_write,
+-};
+-#endif
+-
+-
+-#ifdef CONFIG_PARISC64
+-static int mercury_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
++static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
+ {
+ struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
+ u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+ u32 tok = LBA_CFG_TOK(local_bus, devfn);
++ void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
+
+- /* Basic Algorithm
+- ** Should only get here on fully working LBA rev.
+- ** This is how simple the original LBA code should have been.
+- */
+- LBA_CFG_TR4_ADDR_SETUP(d, tok | pos);
+- switch(size) {
+- case 1: *(u8 *) data = READ_REG8(d->hba.base_addr + LBA_PCI_CFG_DATA
+- + (pos & 3));
+- DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __FUNCTION__, tok, pos,
+- *(u8 *)data);
+- return(*(u8 *)data == (u8) ~0U);
+- case 2: *(u16 *) data = READ_REG16(d->hba.base_addr + LBA_PCI_CFG_DATA
+- + (pos & 2));
+- DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __FUNCTION__, tok, pos,
+- *(u16 *)data);
+- return(*(u16 *)data == (u16) ~0U);
+- case 4: *(u32 *) data = READ_REG32(d->hba.base_addr + LBA_PCI_CFG_DATA);
+- DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __FUNCTION__, tok, pos, *data);
+- return(*data == ~0U);
+- }
+- DBG_CFG("%s(%x+%2x) -> bad size (%d)\n", __FUNCTION__, tok, pos, size);
+- *data = ~0U;
+- return(!PCIBIOS_SUCCESSFUL); /* failed */
+-}
+-
+-/*
+- * LBA 4.0 config write code implements non-postable semantics
+- * by doing a read of CONFIG ADDR after the write.
+- */
+-
+-static int mercury_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data)
+-{
+- struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
+- unsigned long data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
+- u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+- u32 tok = LBA_CFG_TOK(local_bus,devfn);
+-
+- ASSERT((tok & 0xff) == 0);
+- ASSERT(pos < 0x100);
+-
+- DBG_CFG("%s(%x+%2x) <- 0x%x (c)\n", __FUNCTION__, tok, pos, data);
+-
+- /* Basic Algorithm */
+- LBA_CFG_TR4_ADDR_SETUP(d, tok | pos);
+- switch(size) {
+- case 1: WRITE_REG8 (data, data_reg + (pos & 3)); break;
+- case 2: WRITE_REG16(data, data_reg + (pos & 2)); break;
+- case 4: WRITE_REG32(data, data_reg); break;
+- default:
+- DBG_CFG("%s(%x+%2x) WTF! size %d\n", __FUNCTION__, tok, pos,
+- size);
+- }
+-
+- /* flush posted write */
+- lba_t32 = READ_U32(d->hba.base_addr + LBA_PCI_CFG_ADDR);
+- return PCIBIOS_SUCCESSFUL;
+-}
+-
+-
+-static struct pci_ops mercury_cfg_ops = {
+- .read = mercury_cfg_read,
+- .write = mercury_cfg_write,
+-};
+-#else
+-#define mercury_cfg_ops lba_cfg_ops
+-#endif /* CONFIG_PARISC64 */
+-
+-
+-static int lba_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
+-{
+- struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
+- u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+- u32 tok = LBA_CFG_TOK(local_bus, devfn);
++ if ((pos > 255) || (devfn > 255))
++ return -EINVAL;
+
+ /* FIXME: B2K/C3600 workaround is always use old method... */
+- /* if (!LBA_TR4PLUS(d) && !LBA_SKIP_PROBE(d)) */ {
++ /* if (!LBA_SKIP_PROBE(d)) */ {
+ /* original - Generate config cycle on broken elroy
+ with risk we will miss PCI bus errors. */
+ *data = lba_rd_cfg(d, tok, pos, size);
+ DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __FUNCTION__, tok, pos, *data);
+- return(*data == ~0U);
++ return 0;
+ }
+
+- if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->secondary, devfn, d)))
+- {
++ if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->secondary, devfn, d)) {
+ DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __FUNCTION__, tok, pos);
+ /* either don't want to look or know device isn't present. */
+ *data = ~0U;
+@@ -664,52 +495,32 @@
+ ** Should only get here on fully working LBA rev.
+ ** This is how simple the code should have been.
+ */
+- LBA_CFG_TR4_ADDR_SETUP(d, tok | pos);
++ LBA_CFG_ADDR_SETUP(d, tok | pos);
+ switch(size) {
+- case 1: *(u8 *) data = READ_REG8(d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & 3));
+- break;
+- case 2: *(u16 *) data = READ_REG16(d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & 2));
+- break;
+- case 4: *(u32 *) data = READ_REG32(d->hba.base_addr + LBA_PCI_CFG_DATA);
+- break;
++ case 1: *data = READ_REG8 (data_reg + (pos & 3)); break;
++ case 2: *data = READ_REG16(data_reg + (pos & 2)); break;
++ case 4: *data = READ_REG32(data_reg); break;
+ }
+ DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __FUNCTION__, tok, pos, *data);
+- return(*data == ~0U);
++ return 0;
+ }
+
+
+ static void
+-lba_wr_cfg( struct lba_device *d, u32 tok, u8 reg, u32 data, u32 size)
++lba_wr_cfg(struct lba_device *d, u32 tok, u8 reg, u32 data, u32 size)
+ {
+ int error = 0;
+ u32 arb_mask = 0;
+ u32 error_config = 0;
+ u32 status_control = 0;
+-
+- ASSERT((size == sizeof(u8)) ||
+- (size == sizeof(u16)) ||
+- (size == sizeof(u32)));
+-
+- if ((size != sizeof(u8)) &&
+- (size != sizeof(u16)) &&
+- (size != sizeof(u32))) {
+- return;
+- }
++ void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
+
+ LBA_CFG_SETUP(d, tok);
+ LBA_CFG_ADDR_SETUP(d, tok | reg);
+ switch (size) {
+- case sizeof(u8):
+- WRITE_REG8((u8) data, d->hba.base_addr + LBA_PCI_CFG_DATA + (reg&3));
+- break;
+- case sizeof(u16):
+- WRITE_REG16((u8) data, d->hba.base_addr + LBA_PCI_CFG_DATA +(reg&2));
+- break;
+- case sizeof(u32):
+- WRITE_REG32(data, d->hba.base_addr + LBA_PCI_CFG_DATA);
+- break;
+- default:
+- break;
++ case 1: WRITE_REG8 (data, data_reg + (reg & 3)); break;
++ case 2: WRITE_REG16(data, data_reg + (reg & 2)); break;
++ case 4: WRITE_REG32(data, data_reg); break;
+ }
+ LBA_CFG_MASTER_ABORT_CHECK(d, d->hba.base_addr, tok, error);
+ LBA_CFG_RESTORE(d, d->hba.base_addr);
+@@ -721,16 +532,16 @@
+ * by doing a read of CONFIG ADDR after the write.
+ */
+
+-static int lba_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data)
++static int elroy_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data)
+ {
+ struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
+ u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
+ u32 tok = LBA_CFG_TOK(local_bus,devfn);
+
+- ASSERT((tok & 0xff) == 0);
+- ASSERT(pos < 0x100);
++ if ((pos > 255) || (devfn > 255))
++ return -EINVAL;
+
+- if (!LBA_TR4PLUS(d) && !LBA_SKIP_PROBE(d)) {
++ if (!LBA_SKIP_PROBE(d)) {
+ /* Original Workaround */
+ lba_wr_cfg(d, tok, pos, (u32) data, size);
+ DBG_CFG("%s(%x+%2x) = 0x%x (a)\n", __FUNCTION__, tok, pos,data);
+@@ -745,7 +556,7 @@
+ DBG_CFG("%s(%x+%2x) = 0x%x (c)\n", __FUNCTION__, tok, pos, data);
+
+ /* Basic Algorithm */
+- LBA_CFG_TR4_ADDR_SETUP(d, tok | pos);
++ LBA_CFG_ADDR_SETUP(d, tok | pos);
+ switch(size) {
+ case 1: WRITE_REG8 (data, d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & 3));
+ break;
+@@ -760,9 +571,82 @@
+ }
+
+
+-static struct pci_ops lba_cfg_ops = {
+- .read = lba_cfg_read,
+- .write = lba_cfg_write,
++static struct pci_ops elroy_cfg_ops = {
++ .read = elroy_cfg_read,
++ .write = elroy_cfg_write,
++};
++
++/*
++ * The mercury_cfg_ops are slightly misnamed; they're also used for Elroy
++ * TR4.0 as no additional bugs were found in this areea between Elroy and
++ * Mercury
++ */
++
++static int mercury_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data)
++{
++ struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
++ u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
++ u32 tok = LBA_CFG_TOK(local_bus, devfn);
++ void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
++
++ if ((pos > 255) || (devfn > 255))
++ return -EINVAL;
++
++ LBA_CFG_TR4_ADDR_SETUP(d, tok | pos);
++ switch(size) {
++ case 1:
++ *data = READ_REG8(data_reg + (pos & 3));
++ break;
++ case 2:
++ *data = READ_REG16(data_reg + (pos & 2));
++ break;
++ case 4:
++ *data = READ_REG32(data_reg); break;
++ break;
++ }
++
++ DBG_CFG("mercury_cfg_read(%x+%2x) -> 0x%x\n", tok, pos, *data);
++ return 0;
++}
++
++/*
++ * LBA 4.0 config write code implements non-postable semantics
++ * by doing a read of CONFIG ADDR after the write.
++ */
++
++static int mercury_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data)
++{
++ struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge));
++ void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA;
++ u32 local_bus = (bus->parent == NULL) ? 0 : bus->secondary;
++ u32 tok = LBA_CFG_TOK(local_bus,devfn);
++
++ if ((pos > 255) || (devfn > 255))
++ return -EINVAL;
++
++ DBG_CFG("%s(%x+%2x) <- 0x%x (c)\n", __FUNCTION__, tok, pos, data);
++
++ LBA_CFG_TR4_ADDR_SETUP(d, tok | pos);
++ switch(size) {
++ case 1:
++ WRITE_REG8 (data, data_reg + (pos & 3));
++ break;
++ case 2:
++ WRITE_REG16(data, data_reg + (pos & 2));
++ break;
++ case 4:
++ WRITE_REG32(data, data_reg);
++ break;
++ }
++
++ /* flush posted write */
++ lba_t32 = READ_U32(d->hba.base_addr + LBA_PCI_CFG_ADDR);
++ return 0;
++}
++
++static struct pci_ops mercury_cfg_ops = {
++ .read = mercury_cfg_read,
++ .write = mercury_cfg_write,
+ };
+
+
+@@ -773,7 +657,7 @@
+ }
+
+
+-#ifdef CONFIG_PARISC64
++#ifdef CONFIG_64BIT
+
+ /*
+ ** Determine if a device is already configured.
+@@ -802,11 +686,11 @@
+ for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+ if (dev->resource[i].flags & srch_flags) {
+ pci_claim_resource(dev, i);
+- DBG(" claimed %s %d [%lx,%lx]/%x\n",
++ DBG(" claimed %s %d [%lx,%lx]/%lx\n",
+ pci_name(dev), i,
+ dev->resource[i].start,
+ dev->resource[i].end,
+- (int) dev->resource[i].flags
++ dev->resource[i].flags
+ );
+ }
+ }
+@@ -835,7 +719,7 @@
+ struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge));
+ int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num);
+
+- DBG("lba_fixup_bus(0x%p) bus %d sysdata 0x%p\n",
++ DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n",
+ bus, bus->secondary, bus->bridge->platform_data);
+
+ /*
+@@ -849,14 +733,14 @@
+ /* Host-PCI Bridge */
+ int err, i;
+
+- DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
++ DBG("lba_fixup_bus() %s [%lx/%lx]/%lx\n",
+ ldev->hba.io_space.name,
+ ldev->hba.io_space.start, ldev->hba.io_space.end,
+- (int) ldev->hba.io_space.flags);
+- DBG("lba_fixup_bus() %s [%lx/%lx]/%x\n",
++ ldev->hba.io_space.flags);
++ DBG("lba_fixup_bus() %s [%lx/%lx]/%lx\n",
+ ldev->hba.lmmio_space.name,
+ ldev->hba.lmmio_space.start, ldev->hba.lmmio_space.end,
+- (int) ldev->hba.lmmio_space.flags);
++ ldev->hba.lmmio_space.flags);
+
+ err = request_resource(&ioport_resource, &(ldev->hba.io_space));
+ if (err < 0) {
+@@ -895,7 +779,7 @@
+ /* lba_dump_res(&iomem_resource, 2); */
+ }
+
+-#ifdef CONFIG_PARISC64
++#ifdef CONFIG_64BIT
+ /* GMMIO is distributed range. Every LBA/Rope gets part it. */
+ if (ldev->hba.gmmio_space.flags) {
+ err = request_resource(&iomem_resource, &(ldev->hba.gmmio_space));
+@@ -1035,7 +919,7 @@
+ static u##size lba_astro_in##size (struct pci_hba_data *d, u16 addr) \
+ { \
+ u##size t; \
+- t = READ_REG##size(LBA_PORT_BASE + addr); \
++ t = READ_REG##size(astro_iop_base + addr); \
+ DBG_PORT(" 0x%x\n", t); \
+ return (t); \
+ }
+@@ -1075,9 +959,8 @@
+ #define LBA_PORT_OUT(size, mask) \
+ static void lba_astro_out##size (struct pci_hba_data *d, u16 addr, u##size val) \
+ { \
+- ASSERT(d != NULL); \
+ DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __FUNCTION__, d, addr, val); \
+- WRITE_REG##size(val, LBA_PORT_BASE + addr); \
++ WRITE_REG##size(val, astro_iop_base + addr); \
+ if (LBA_DEV(d)->hw_rev < 3) \
+ lba_t32 = READ_U32(d->base_addr + LBA_FUNC_ID); \
+ }
+@@ -1097,7 +980,7 @@
+ };
+
+
+-#ifdef CONFIG_PARISC64
++#ifdef CONFIG_64BIT
+ #define PIOP_TO_GMMIO(lba, addr) \
+ ((lba)->iop_base + (((addr)&0xFFFC)<<10) + ((addr)&3))
+
+@@ -1215,16 +1098,19 @@
+ case PAT_LMMIO:
+ /* used to fix up pre-initialized MEM BARs */
+ if (!lba_dev->hba.lmmio_space.start) {
+- sprintf(lba_dev->hba.lmmio_name, "PCI%02x LMMIO",
+- (int) lba_dev->hba.bus_num.start);
+- lba_dev->hba.lmmio_space_offset = p->start - io->start;
+- r = &(lba_dev->hba.lmmio_space);
+- r->name = lba_dev->hba.lmmio_name;
++ sprintf(lba_dev->hba.lmmio_name,
++ "PCI%02lx LMMIO",
++ lba_dev->hba.bus_num.start);
++ lba_dev->hba.lmmio_space_offset = p->start -
++ io->start;
++ r = &lba_dev->hba.lmmio_space;
++ r->name = lba_dev->hba.lmmio_name;
+ } else if (!lba_dev->hba.elmmio_space.start) {
+- sprintf(lba_dev->hba.elmmio_name, "PCI%02x ELMMIO",
+- (int) lba_dev->hba.bus_num.start);
+- r = &(lba_dev->hba.elmmio_space);
+- r->name = lba_dev->hba.elmmio_name;
++ sprintf(lba_dev->hba.elmmio_name,
++ "PCI%02lx ELMMIO",
++ lba_dev->hba.bus_num.start);
++ r = &lba_dev->hba.elmmio_space;
++ r->name = lba_dev->hba.elmmio_name;
+ } else {
+ printk(KERN_WARNING MODULE_NAME
+ " only supports 2 LMMIO resources!\n");
+@@ -1239,9 +1125,9 @@
+
+ case PAT_GMMIO:
+ /* MMIO space > 4GB phys addr; for 64-bit BAR */
+- sprintf(lba_dev->hba.gmmio_name, "PCI%02x GMMIO",
+- (int) lba_dev->hba.bus_num.start);
+- r = &(lba_dev->hba.gmmio_space);
++ sprintf(lba_dev->hba.gmmio_name, "PCI%02lx GMMIO",
++ lba_dev->hba.bus_num.start);
++ r = &lba_dev->hba.gmmio_space;
+ r->name = lba_dev->hba.gmmio_name;
+ r->start = p->start;
+ r->end = p->end;
+@@ -1260,11 +1146,11 @@
+ ** Postable I/O port space is per PCI host adapter.
+ ** base of 64MB PIOP region
+ */
+- lba_dev->iop_base = p->start;
++ lba_dev->iop_base = ioremap(p->start, 64 * 1024 * 1024);
+
+- sprintf(lba_dev->hba.io_name, "PCI%02x Ports",
+- (int) lba_dev->hba.bus_num.start);
+- r = &(lba_dev->hba.io_space);
++ sprintf(lba_dev->hba.io_name, "PCI%02lx Ports",
++ lba_dev->hba.bus_num.start);
++ r = &lba_dev->hba.io_space;
+ r->name = lba_dev->hba.io_name;
+ r->start = HBA_PORT_BASE(lba_dev->hba.hba_num);
+ r->end = r->start + HBA_PORT_SPACE_SIZE - 1;
+@@ -1284,7 +1170,7 @@
+ /* keep compiler from complaining about missing declarations */
+ #define lba_pat_port_ops lba_astro_port_ops
+ #define lba_pat_resources(pa_dev, lba_dev)
+-#endif /* CONFIG_PARISC64 */
++#endif /* CONFIG_64BIT */
+
+
+ extern void sba_distributed_lmmio(struct parisc_device *, struct resource *);
+@@ -1306,7 +1192,7 @@
+ ** PCI bus walk *should* end up with the same result.
+ ** FIXME: But we don't have sanity checks in PCI or LBA.
+ */
+- lba_num = READ_REG32(pa_dev->hpa + LBA_FW_SCRATCH);
++ lba_num = READ_REG32(lba_dev->hba.base_addr + LBA_FW_SCRATCH);
+ r = &(lba_dev->hba.bus_num);
+ r->name = "LBA PCI Busses";
+ r->start = lba_num & 0xff;
+@@ -1316,8 +1202,8 @@
+ ** Legacy boxes but it's nice to see in /proc/iomem.
+ */
+ r = &(lba_dev->hba.lmmio_space);
+- sprintf(lba_dev->hba.lmmio_name, "PCI%02x LMMIO",
+- (int) lba_dev->hba.bus_num.start);
++ sprintf(lba_dev->hba.lmmio_name, "PCI%02lx LMMIO",
++ lba_dev->hba.bus_num.start);
+ r->name = lba_dev->hba.lmmio_name;
+
+ #if 1
+@@ -1387,7 +1273,7 @@
+ *
+ * All is well now.
+ */
+- r->start = (long) READ_REG32(pa_dev->hpa + LBA_LMMIO_BASE);
++ r->start = READ_REG32(lba_dev->hba.base_addr + LBA_LMMIO_BASE);
+ if (r->start & 1) {
+ unsigned long rsize;
+
+@@ -1395,7 +1281,7 @@
+ /* mmio_mask also clears Enable bit */
+ r->start &= mmio_mask;
+ r->start = PCI_HOST_ADDR(HBA_DATA(lba_dev), r->start);
+- rsize = ~ READ_REG32(pa_dev->hpa + LBA_LMMIO_MASK);
++ rsize = ~ READ_REG32(lba_dev->hba.base_addr + LBA_LMMIO_MASK);
+
+ /*
+ ** Each rope only gets part of the distributed range.
+@@ -1425,15 +1311,15 @@
+ ** an existing (but unused portion of) distributed range.
+ */
+ r = &(lba_dev->hba.elmmio_space);
+- sprintf(lba_dev->hba.elmmio_name, "PCI%02x ELMMIO",
+- (int) lba_dev->hba.bus_num.start);
++ sprintf(lba_dev->hba.elmmio_name, "PCI%02lx ELMMIO",
++ lba_dev->hba.bus_num.start);
+ r->name = lba_dev->hba.elmmio_name;
+
+ #if 1
+ /* See comment which precedes call to sba_directed_lmmio() */
+ sba_directed_lmmio(pa_dev, r);
+ #else
+- r->start = READ_REG32(pa_dev->hpa + LBA_ELMMIO_BASE);
++ r->start = READ_REG32(lba_dev->hba.base_addr + LBA_ELMMIO_BASE);
+
+ if (r->start & 1) {
+ unsigned long rsize;
+@@ -1441,18 +1327,18 @@
+ /* mmio_mask also clears Enable bit */
+ r->start &= mmio_mask;
+ r->start = PCI_HOST_ADDR(HBA_DATA(lba_dev), r->start);
+- rsize = READ_REG32(pa_dev->hpa + LBA_ELMMIO_MASK);
++ rsize = READ_REG32(lba_dev->hba.base_addr + LBA_ELMMIO_MASK);
+ r->end = r->start + ~rsize;
+ }
+ #endif
+
+ r = &(lba_dev->hba.io_space);
+- sprintf(lba_dev->hba.io_name, "PCI%02x Ports",
+- (int) lba_dev->hba.bus_num.start);
++ sprintf(lba_dev->hba.io_name, "PCI%02lx Ports",
++ lba_dev->hba.bus_num.start);
+ r->name = lba_dev->hba.io_name;
+ r->flags = IORESOURCE_IO;
+- r->start = READ_REG32(pa_dev->hpa + LBA_IOS_BASE) & ~1L;
+- r->end = r->start + (READ_REG32(pa_dev->hpa + LBA_IOS_MASK) ^ (HBA_PORT_SPACE_SIZE - 1));
++ r->start = READ_REG32(lba_dev->hba.base_addr + LBA_IOS_BASE) & ~1L;
++ r->end = r->start + (READ_REG32(lba_dev->hba.base_addr + LBA_IOS_MASK) ^ (HBA_PORT_SPACE_SIZE - 1));
+
+ /* Virtualize the I/O Port space ranges */
+ lba_num = HBA_PORT_BASE(lba_dev->hba.hba_num);
+@@ -1501,7 +1387,7 @@
+ printk("\n");
+ #endif /* DEBUG_LBA_PAT */
+
+-#ifdef CONFIG_PARISC64
++#ifdef CONFIG_64BIT
+ /*
+ * FIXME add support for PDC_PAT_IO "Get slot status" - OLAR support
+ * Only N-Class and up can really make use of Get slot status.
+@@ -1558,23 +1444,6 @@
+
+
+
+-static void __init
+-lba_common_init(struct lba_device *lba_dev)
+-{
+- pci_bios = &lba_bios_ops;
+- pcibios_register_hba(HBA_DATA(lba_dev));
+- spin_lock_init(&lba_dev->lba_lock);
+-
+- /*
+- ** Set flags which depend on hw_rev
+- */
+- if (!LBA_TR4PLUS(lba_dev)) {
+- lba_dev->flags |= LBA_FLAG_NO_DMA_DURING_CFG;
+- }
+-}
+-
+-
+-
+ /*
+ ** Determine if lba should claim this chip (return 0) or not (return 1).
+ ** If so, initialize the chip and tell other partners in crime they
+@@ -1585,12 +1454,14 @@
+ {
+ struct lba_device *lba_dev;
+ struct pci_bus *lba_bus;
++ struct pci_ops *cfg_ops;
+ u32 func_class;
+ void *tmp_obj;
+ char *version;
++ void __iomem *addr = ioremap(dev->hpa, 4096);
+
+ /* Read HW Rev First */
+- func_class = READ_REG32(dev->hpa + LBA_FCLASS);
++ func_class = READ_REG32(addr + LBA_FCLASS);
+
+ if (IS_ELROY(dev)) {
+ func_class &= 0xf;
+@@ -1603,24 +1474,40 @@
+ case 5: version = "TR4.0"; break;
+ default: version = "TR4+";
+ }
++
+ printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
+ MODULE_NAME, version, func_class & 0xf, dev->hpa);
+
+- /* Just in case we find some prototypes... */
++ if (func_class < 2) {
++ printk(KERN_WARNING "Can't support LBA older than "
++ "TR2.1 - continuing under adversity.\n");
++ }
++
++#if 0
++/* Elroy TR4.0 should work with simple algorithm.
++ But it doesn't. Still missing something. *sigh*
++*/
++ if (func_class > 4) {
++ cfg_ops = &mercury_cfg_ops;
++ } else
++#endif
++ {
++ cfg_ops = &elroy_cfg_ops;
++ }
++
+ } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) {
+ func_class &= 0xff;
+ version = kmalloc(6, GFP_KERNEL);
+ sprintf(version,"TR%d.%d",(func_class >> 4),(func_class & 0xf));
+- /* We could use one printk for both and have it outside,
++ /* We could use one printk for both Elroy and Mercury,
+ * but for the mask for func_class.
+ */
+ printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
+ MODULE_NAME, version, func_class & 0xff, dev->hpa);
+- }
+-
+- if (func_class < 2) {
+- printk(KERN_WARNING "Can't support LBA older than TR2.1"
+- " - continuing under adversity.\n");
++ cfg_ops = &mercury_cfg_ops;
++ } else {
++ printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa);
++ return -ENODEV;
+ }
+
+ /*
+@@ -1633,8 +1520,7 @@
+ */
+
+ lba_dev = kmalloc(sizeof(struct lba_device), GFP_KERNEL);
+- if (NULL == lba_dev)
+- {
++ if (!lba_dev) {
+ printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n");
+ return(1);
+ }
+@@ -1644,19 +1530,16 @@
+
+ /* ---------- First : initialize data we already have --------- */
+
+- /*
+- ** Need hw_rev to adjust configuration space behavior.
+- ** LBA_TR4PLUS macro uses hw_rev field.
+- */
+ lba_dev->hw_rev = func_class;
+-
+- lba_dev->hba.base_addr = dev->hpa; /* faster access */
++ lba_dev->hba.base_addr = addr;
+ lba_dev->hba.dev = dev;
+ lba_dev->iosapic_obj = tmp_obj; /* save interrupt handle */
+ lba_dev->hba.iommu = sba_get_iommu(dev); /* get iommu data */
+
+ /* ------------ Second : initialize common stuff ---------- */
+- lba_common_init(lba_dev);
++ pci_bios = &lba_bios_ops;
++ pcibios_register_hba(HBA_DATA(lba_dev));
++ spin_lock_init(&lba_dev->lba_lock);
+
+ if (lba_hw_init(lba_dev))
+ return(1);
+@@ -1669,8 +1552,11 @@
+ /* Go ask PDC PAT what resources this LBA has */
+ lba_pat_resources(dev, lba_dev);
+ } else {
+- /* Sprockets PDC uses NPIOP region */
+- pci_port = &lba_astro_port_ops;
++ if (!astro_iop_base) {
++ /* Sprockets PDC uses NPIOP region */
++ astro_iop_base = ioremap(LBA_PORT_BASE, 64 * 1024);
++ pci_port = &lba_astro_port_ops;
++ }
+
+ /* Poke the chip a bit for /proc output */
+ lba_legacy_resources(dev, lba_dev);
+@@ -1683,8 +1569,7 @@
+ dev->dev.platform_data = lba_dev;
+ lba_bus = lba_dev->hba.hba_bus =
+ pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start,
+- IS_ELROY(dev) ? &lba_cfg_ops : &mercury_cfg_ops,
+- NULL);
++ cfg_ops, NULL);
+
+ /* This is in lieu of calling pci_assign_unassigned_resources() */
+ if (is_pdc_pat()) {
+@@ -1711,7 +1596,7 @@
+ ** space is restricted. Avoids master aborts on config cycles.
+ ** Early LBA revs go fatal on *any* master abort.
+ */
+- if (!LBA_TR4PLUS(lba_dev)) {
++ if (cfg_ops == &elroy_cfg_ops) {
+ lba_dev->flags |= LBA_FLAG_SKIP_PROBE;
+ }
+
+@@ -1746,18 +1631,19 @@
+ ** Only called from sba_iommu.c in order to route ranges (MMIO vs DMA).
+ ** sba_iommu is responsible for locking (none needed at init time).
+ */
+-void
+-lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
++void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
+ {
+- unsigned long base_addr = lba->hpa;
++ void __iomem * base_addr = ioremap(lba->hpa, 4096);
+
+ imask <<= 2; /* adjust for hints - 2 more bits */
+
+- ASSERT((ibase & 0x003fffff) == 0);
+- ASSERT((imask & 0x003fffff) == 0);
++ /* Make sure we aren't trying to set bits that aren't writeable. */
++ WARN_ON((ibase & 0x001fffff) != 0);
++ WARN_ON((imask & 0x001fffff) != 0);
+
+ DBG("%s() ibase 0x%x imask 0x%x\n", __FUNCTION__, ibase, imask);
+ WRITE_REG32( imask, base_addr + LBA_IMASK);
+ WRITE_REG32( ibase, base_addr + LBA_IBASE);
++ iounmap(base_addr);
+ }
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/led.c CVS2_6_11_PA2/drivers/parisc/led.c
+--- LINUS_2_6_11/drivers/parisc/led.c 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/led.c 2005-02-03 04:44:44.000000000 -0700
+@@ -77,8 +77,8 @@
+ struct pdc_chassis_lcd_info_ret_block {
+ unsigned long model:16; /* DISPLAY_MODEL_XXXX */
+ unsigned long lcd_width:16; /* width of the LCD in chars (DISPLAY_MODEL_LCD only) */
+- char *lcd_cmd_reg_addr; /* ptr to LCD cmd-register & data ptr for LED */
+- char *lcd_data_reg_addr; /* ptr to LCD data-register (LCD only) */
++ unsigned long lcd_cmd_reg_addr; /* ptr to LCD cmd-register & data ptr for LED */
++ unsigned long lcd_data_reg_addr; /* ptr to LCD data-register (LCD only) */
+ unsigned int min_cmd_delay; /* delay in uS after cmd-write (LCD only) */
+ unsigned char reset_cmd1; /* command #1 for writing LCD string (LCD only) */
+ unsigned char reset_cmd2; /* command #2 for writing LCD string (LCD only) */
+@@ -102,8 +102,8 @@
+ {
+ .model = DISPLAY_MODEL_LCD,
+ .lcd_width = 16,
+- .lcd_cmd_reg_addr = (char *) KITTYHAWK_LCD_CMD,
+- .lcd_data_reg_addr = (char *) KITTYHAWK_LCD_DATA,
++ .lcd_cmd_reg_addr = KITTYHAWK_LCD_CMD,
++ .lcd_data_reg_addr = KITTYHAWK_LCD_DATA,
+ .min_cmd_delay = 40,
+ .reset_cmd1 = 0x80,
+ .reset_cmd2 = 0xc0,
+@@ -540,20 +540,20 @@
+ **
+ */
+
+-int __init register_led_driver(int model, char *cmd_reg, char *data_reg)
++int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long data_reg)
+ {
+ static int initialized;
+
+ if (initialized || !data_reg)
+- return 1;
++ return 1;
+
+ lcd_info.model = model; /* store the values */
+- LCD_CMD_REG = (cmd_reg == LED_CMD_REG_NONE) ? NULL : cmd_reg;
++ LCD_CMD_REG = (cmd_reg == LED_CMD_REG_NONE) ? 0 : cmd_reg;
+
+ switch (lcd_info.model) {
+ case DISPLAY_MODEL_LCD:
+ LCD_DATA_REG = data_reg;
+- printk(KERN_INFO "LCD display at %p,%p registered\n",
++ printk(KERN_INFO "LCD display at %lu,%lu registered\n",
+ LCD_CMD_REG , LCD_DATA_REG);
+ led_func_ptr = led_LCD_driver;
+ lcd_print( lcd_text_default );
+@@ -563,14 +563,14 @@
+ case DISPLAY_MODEL_LASI:
+ LED_DATA_REG = data_reg;
+ led_func_ptr = led_LASI_driver;
+- printk(KERN_INFO "LED display at %p registered\n", LED_DATA_REG);
++ printk(KERN_INFO "LED display at %lu registered\n", LED_DATA_REG);
+ led_type = LED_NOLCD;
+ break;
+
+ case DISPLAY_MODEL_OLD_ASP:
+ LED_DATA_REG = data_reg;
+ led_func_ptr = led_ASP_driver;
+- printk(KERN_INFO "LED (ASP-style) display at %p registered\n",
++ printk(KERN_INFO "LED (ASP-style) display at %lu registered\n",
+ LED_DATA_REG);
+ led_type = LED_NOLCD;
+ break;
+@@ -695,7 +695,8 @@
+ lcd_info.model = DISPLAY_MODEL_NONE;
+ chassis_info.actcnt = chassis_info.maxcnt = 0;
+
+- if ((ret = pdc_chassis_info(&chassis_info, &lcd_info, sizeof(lcd_info))) == PDC_OK) {
++ ret = pdc_chassis_info(&chassis_info, &lcd_info, sizeof(lcd_info));
++ if (ret == PDC_OK) {
+ DPRINTK((KERN_INFO "%s: chassis info: model=%d (%s), "
+ "lcd_width=%d, cmd_delay=%u,\n"
+ "%s: sizecnt=%d, actcnt=%ld, maxcnt=%ld\n",
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/pdc_stable.c CVS2_6_11_PA2/drivers/parisc/pdc_stable.c
+--- LINUS_2_6_11/drivers/parisc/pdc_stable.c 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/pdc_stable.c 2005-03-01 23:47:37.000000000 -0700
+@@ -0,0 +1,735 @@
++/*
++ * Interfaces to retrieve and set PDC Stable options (firmware)
++ *
++ * Copyright (C) 2005 Thibaut VARENE <varenet at parisc-linux.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ *
++ * DEV NOTE: the PDC Procedures reference states that:
++ * "A minimum of 96 bytes of Stable Storage is required. Providing more than
++ * 96 bytes of Stable Storage is optional [...]. Failure to provide the
++ * optional locations from 96 to 192 results in the loss of certain
++ * functionality during boot."
++ *
++ * Since locations between 96 and 192 are the various paths, most (if not
++ * all) PA-RISC machines should have them. Anyway, for safety reasons, the
++ * following code can deal with only 96 bytes of Stable Storage, and all
++ * sizes between 96 and 192 bytes (provided they are multiple of struct
++ * device_path size, eg: 128, 160 and 192) to provide full information.
++ * The code makes no use of data above 192 bytes. One last word: there's one
++ * path we can always count on: the primary path.
++ */
++
++#undef PDCS_DEBUG
++#ifdef PDCS_DEBUG
++#define DPRINTK(fmt, args...) printk(KERN_DEBUG fmt, ## args)
++#else
++#define DPRINTK(fmt, args...)
++#endif
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/sched.h> /* for capable() */
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/ctype.h>
++#include <linux/sysfs.h>
++#include <linux/kobject.h>
++#include <linux/device.h>
++#include <linux/errno.h>
++
++#include <asm/pdc.h>
++#include <asm/page.h>
++#include <asm/uaccess.h>
++#include <asm/hardware.h>
++
++#define PDCS_VERSION "0.09"
++
++#define PDCS_ADDR_PPRI 0x00
++#define PDCS_ADDR_OSID 0x40
++#define PDCS_ADDR_FSIZ 0x5C
++#define PDCS_ADDR_PCON 0x60
++#define PDCS_ADDR_PALT 0x80
++#define PDCS_ADDR_PKBD 0xA0
++
++MODULE_AUTHOR("Thibaut VARENE <varenet at parisc-linux.org>");
++MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data");
++MODULE_LICENSE("GPL");
++MODULE_VERSION(PDCS_VERSION);
++
++static unsigned long pdcs_size = 0;
++
++/* This struct defines what we need to deal with a parisc pdc path entry */
++struct pdcspath_entry {
++ short ready; /* entry record is valid if != 0 */
++ unsigned long addr; /* entry address in stable storage */
++ char *name; /* entry name */
++ struct device_path devpath; /* device path in parisc representation */
++ struct device *dev; /* corresponding device */
++ struct kobject kobj;
++};
++
++struct pdcspath_attribute {
++ struct attribute attr;
++ ssize_t (*show)(struct pdcspath_entry *entry, char *buf);
++ ssize_t (*store)(struct pdcspath_entry *entry, const char *buf, size_t count);
++};
++
++#define PDCSPATH_ENTRY(_addr, _name) \
++struct pdcspath_entry pdcspath_entry_##_name = { \
++ .ready = 0, \
++ .addr = _addr, \
++ .name = __stringify(_name), \
++};
++
++#define PDCS_ATTR(_name, _mode, _show, _store) \
++struct subsys_attribute pdcs_attr_##_name = { \
++ .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
++ .show = _show, \
++ .store = _store, \
++};
++
++#define PATHS_ATTR(_name, _mode, _show, _store) \
++struct pdcspath_attribute paths_attr_##_name = { \
++ .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE}, \
++ .show = _show, \
++ .store = _store, \
++};
++
++#define to_pdcspath_attribute(_attr) container_of(_attr, struct pdcspath_attribute, attr)
++#define to_pdcspath_entry(obj) container_of(obj, struct pdcspath_entry, kobj)
++
++/**
++ * pdcspath_fetch - This function populates the path entry structs.
++ * @entry: A pointer to an allocated pdcspath_entry.
++ *
++ * The general idea is that you don't read from the Stable Storage every time
++ * you access the files provided by the facilites. We store a copy of the
++ * content of the stable storage WRT various paths in these structs. We read
++ * these structs when reading the files, and we will write to these structs when
++ * writing to the files, and only then write them back to the Stable Storage.
++ */
++static int
++pdcspath_fetch(struct pdcspath_entry *entry)
++{
++ struct device_path *devpath;
++
++ if (!entry)
++ return -EINVAL;
++
++ devpath = &entry->devpath;
++
++ DPRINTK("%s: fetch: 0x%p, 0x%p, addr: 0x%lx\n", __func__,
++ entry, devpath, entry->addr);
++
++ /* addr, devpath and count must be word aligned */
++ if (pdc_stable_read(entry->addr, devpath, sizeof(*devpath)) != PDC_OK)
++ return -EIO;
++
++ /* Find the matching device.
++ NOTE: hardware_path overlays with device_path, so the nice cast can
++ be used */
++ entry->dev = hwpath_to_device((struct hardware_path *)devpath);
++
++ entry->ready = 1;
++
++ DPRINTK("%s: device: 0x%p\n", __func__, entry->dev);
++
++ return 0;
++}
++
++/**
++ * pdcspath_store - This function writes a path to stable storage.
++ * @entry: A pointer to an allocated pdcspath_entry.
++ *
++ * It can be used in two ways: either by passing it a preset devpath struct
++ * containing an already computed hardware path, or by passing it a device
++ * pointer, from which it'll find out the corresponding hardware path.
++ * For now we do not handle the case where there's an error in writing to the
++ * Stable Storage area, so you'd better not mess up the data :P
++ */
++static int
++pdcspath_store(struct pdcspath_entry *entry)
++{
++ struct device_path *devpath;
++
++ if (!entry)
++ return -EINVAL;
++
++ devpath = &entry->devpath;
++
++ /* We expect the caller to set the ready flag to 0 if the hardware
++ path struct provided is invalid, so that we know we have to fill it.
++ First case, we don't have a preset hwpath... */
++ if (!entry->ready) {
++ /* ...but we have a device, map it */
++ if (entry->dev)
++ device_to_hwpath(entry->dev, (struct hardware_path *)devpath);
++ else
++ return -EINVAL;
++ }
++ /* else, we expect the provided hwpath to be valid. */
++
++ DPRINTK("%s: store: 0x%p, 0x%p, addr: 0x%lx\n", __func__,
++ entry, devpath, entry->addr);
++
++ /* addr, devpath and count must be word aligned */
++ if (pdc_stable_write(entry->addr, devpath, sizeof(*devpath)) != PDC_OK) {
++ printk(KERN_ERR "%s: an error occured when writing to PDC.\n"
++ "It is likely that the Stable Storage data has been corrupted.\n"
++ "Please check it carefully upon next reboot.\n", __func__);
++ return -EIO;
++ }
++
++ entry->ready = 1;
++
++ DPRINTK("%s: device: 0x%p\n", __func__, entry->dev);
++
++ return 0;
++}
++
++/**
++ * pdcspath_hwpath_read - This function handles hardware path pretty printing.
++ * @entry: An allocated and populated pdscpath_entry struct.
++ * @buf: The output buffer to write to.
++ *
++ * We will call this function to format the output of the hwpath attribute file.
++ */
++static ssize_t
++pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf)
++{
++ char *out = buf;
++ struct device_path *devpath;
++ unsigned short i;
++
++ if (!entry || !buf)
++ return -EINVAL;
++
++ devpath = &entry->devpath;
++
++ if (!entry->ready)
++ return -ENODATA;
++
++ for (i = 0; i < 6; i++) {
++ if (devpath->bc[i] >= 128)
++ continue;
++ out += sprintf(out, "%u/", (unsigned char)devpath->bc[i]);
++ }
++ out += sprintf(out, "%u\n", (unsigned char)devpath->mod);
++
++ return out - buf;
++}
++
++/**
++ * pdcspath_hwpath_write - This function handles hardware path modifying.
++ * @entry: An allocated and populated pdscpath_entry struct.
++ * @buf: The input buffer to read from.
++ * @count: The number of bytes to be read.
++ *
++ * We will call this function to change the current hardware path.
++ * Hardware paths are to be given '/'-delimited, without brackets.
++ * We take care to make sure that the provided path actually maps to an existing
++ * device, BUT nothing would prevent some foolish user to set the path to some
++ * PCI bridge or even a CPU...
++ * A better work around would be to make sure we are at the end of a device tree
++ * for instance, but it would be IMHO beyond the simple scope of that driver.
++ * The aim is to provide a facility. Data correctness is left to userland.
++ */
++static ssize_t
++pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t count)
++{
++ struct hardware_path hwpath;
++ unsigned short i;
++ char in[count+1], *temp;
++ struct device *dev;
++
++ if (!entry || !buf || !count)
++ return -EINVAL;
++
++ /* We'll use a local copy of buf */
++ memset(in, 0, count+1);
++ strncpy(in, buf, count);
++
++ /* Let's clean up the target. 0xff is a blank pattern */
++ memset(&hwpath, 0xff, sizeof(hwpath));
++
++ /* First, pick the mod field (the last one of the input string) */
++ if (!(temp = strrchr(in, '/')))
++ return -EINVAL;
++
++ hwpath.mod = simple_strtoul(temp+1, NULL, 10);
++ in[temp-in] = '\0'; /* truncate the remaining string. just precaution */
++ DPRINTK("%s: mod: %d\n", __func__, hwpath.mod);
++
++ /* Then, loop for each delimiter, making sure we don't have too many.
++ we write the bc fields in a down-top way. No matter what, we stop
++ before writing the last field. If there are too many fields anyway,
++ then the user is a moron and it'll be caught up later when we'll
++ check the consistency of the given hwpath. */
++ for (i=5; ((temp = strrchr(in, '/'))) && (temp-in > 0) && (likely(i)); i--) {
++ hwpath.bc[i] = simple_strtoul(temp+1, NULL, 10);
++ in[temp-in] = '\0';
++ DPRINTK("%s: bc[%d]: %d\n", __func__, i, hwpath.bc[i]);
++ }
++
++ /* Store the final field */
++ hwpath.bc[i] = simple_strtoul(in, NULL, 10);
++ DPRINTK("%s: bc[%d]: %d\n", __func__, i, hwpath.bc[i]);
++
++ /* Now we check that the user isn't trying to lure us */
++ if (!(dev = hwpath_to_device((struct hardware_path *)&hwpath))) {
++ printk(KERN_WARNING "%s: attempt to set invalid \"%s\" "
++ "hardware path: %s\n", __func__, entry->name, buf);
++ return -EINVAL;
++ }
++
++ /* So far so good, let's get in deep */
++ entry->ready = 0;
++ entry->dev = dev;
++
++ /* Now, dive in. Write back to the hardware */
++ WARN_ON(pdcspath_store(entry)); /* this warn should *NEVER* happen */
++
++ /* Update the symlink to the real device */
++ sysfs_remove_link(&entry->kobj, "device");
++ sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
++
++ printk(KERN_INFO "PDC Stable Storage: changed \"%s\" path to \"%s\"\n",
++ entry->name, buf);
++
++ return count;
++}
++
++/**
++ * pdcspath_layer_read - Extended layer (eg. SCSI ids) pretty printing.
++ * @entry: An allocated and populated pdscpath_entry struct.
++ * @buf: The output buffer to write to.
++ *
++ * We will call this function to format the output of the layer attribute file.
++ */
++static ssize_t
++pdcspath_layer_read(struct pdcspath_entry *entry, char *buf)
++{
++ char *out = buf;
++ struct device_path *devpath;
++ unsigned short i;
++
++ if (!entry || !buf)
++ return -EINVAL;
++
++ devpath = &entry->devpath;
++
++ if (!entry->ready)
++ return -ENODATA;
++
++ for (i = 0; devpath->layers[i] && (likely(i < 6)); i++)
++ out += sprintf(out, "%u ", devpath->layers[i]);
++
++ out += sprintf(out, "\n");
++
++ return out - buf;
++}
++
++/**
++ * pdcspath_layer_write - This function handles extended layer modifying.
++ * @entry: An allocated and populated pdscpath_entry struct.
++ * @buf: The input buffer to read from.
++ * @count: The number of bytes to be read.
++ *
++ * We will call this function to change the current layer value.
++ * Layers are to be given '.'-delimited, without brackets.
++ * XXX beware we are far less checky WRT input data provided than for hwpath.
++ * Potential harm can be done, since there's no way to check the validity of
++ * the layer fields.
++ */
++static ssize_t
++pdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count)
++{
++ unsigned int layers[6]; /* device-specific info (ctlr#, unit#, ...) */
++ unsigned short i;
++ char in[count+1], *temp;
++
++ if (!entry || !buf || !count)
++ return -EINVAL;
++
++ /* We'll use a local copy of buf */
++ memset(in, 0, count+1);
++ strncpy(in, buf, count);
++
++ /* Let's clean up the target. 0 is a blank pattern */
++ memset(&layers, 0, sizeof(layers));
++
++ /* First, pick the first layer */
++ if (unlikely(!isdigit(*in)))
++ return -EINVAL;
++ layers[0] = simple_strtoul(in, NULL, 10);
++ DPRINTK("%s: layer[0]: %d\n", __func__, layers[0]);
++
++ temp = in;
++ for (i=1; ((temp = strchr(temp, '.'))) && (likely(i<6)); i++) {
++ if (unlikely(!isdigit(*(++temp))))
++ return -EINVAL;
++ layers[i] = simple_strtoul(temp, NULL, 10);
++ DPRINTK("%s: layer[%d]: %d\n", __func__, i, layers[i]);
++ }
++
++ /* So far so good, let's get in deep */
++
++ /* First, overwrite the current layers with the new ones, not touching
++ the hardware path. */
++ memcpy(&entry->devpath.layers, &layers, sizeof(layers));
++
++ /* Now, dive in. Write back to the hardware */
++ WARN_ON(pdcspath_store(entry)); /* this warn should *NEVER* happen */
++
++ printk(KERN_INFO "PDC Stable Storage: changed \"%s\" layers to \"%s\"\n",
++ entry->name, buf);
++
++ return count;
++}
++
++/**
++ * pdcspath_attr_show - Generic read function call wrapper.
++ * @kobj: The kobject to get info from.
++ * @attr: The attribute looked upon.
++ * @buf: The output buffer.
++ */
++static ssize_t
++pdcspath_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
++{
++ struct pdcspath_entry *entry = to_pdcspath_entry(kobj);
++ struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr);
++ ssize_t ret = 0;
++
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
++
++ if (pdcs_attr->show)
++ ret = pdcs_attr->show(entry, buf);
++
++ return ret;
++}
++
++/**
++ * pdcspath_attr_store - Generic write function call wrapper.
++ * @kobj: The kobject to write info to.
++ * @attr: The attribute to be modified.
++ * @buf: The input buffer.
++ * @count: The size of the buffer.
++ */
++static ssize_t
++pdcspath_attr_store(struct kobject *kobj, struct attribute *attr,
++ const char *buf, size_t count)
++{
++ struct pdcspath_entry *entry = to_pdcspath_entry(kobj);
++ struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr);
++ ssize_t ret = 0;
++
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
++
++ if (pdcs_attr->store)
++ ret = pdcs_attr->store(entry, buf, count);
++
++ return ret;
++}
++
++static struct sysfs_ops pdcspath_attr_ops = {
++ .show = pdcspath_attr_show,
++ .store = pdcspath_attr_store,
++};
++
++/* These are the two attributes of any PDC path. */
++static PATHS_ATTR(hwpath, 0600, pdcspath_hwpath_read, pdcspath_hwpath_write);
++static PATHS_ATTR(layer, 0600, pdcspath_layer_read, pdcspath_layer_write);
++
++static struct attribute *paths_subsys_attrs[] = {
++ &paths_attr_hwpath.attr,
++ &paths_attr_layer.attr,
++ NULL,
++};
++
++/* Specific kobject type for our PDC paths */
++static struct kobj_type ktype_pdcspath = {
++ .sysfs_ops = &pdcspath_attr_ops,
++ .default_attrs = paths_subsys_attrs,
++};
++
++/* We hard define the 4 types of path we expect to find */
++static PDCSPATH_ENTRY(PDCS_ADDR_PPRI, primary);
++static PDCSPATH_ENTRY(PDCS_ADDR_PCON, console);
++static PDCSPATH_ENTRY(PDCS_ADDR_PALT, alternative);
++static PDCSPATH_ENTRY(PDCS_ADDR_PKBD, keyboard);
++
++/* An array containing all PDC paths we will deal with */
++static struct pdcspath_entry *pdcspath_entries[] = {
++ &pdcspath_entry_primary,
++ &pdcspath_entry_alternative,
++ &pdcspath_entry_console,
++ &pdcspath_entry_keyboard,
++ NULL,
++};
++
++/**
++ * pdcs_info_read - Pretty printing of the remaining useful data.
++ * @entry: An allocated and populated subsytem struct. We don't use it tho.
++ * @buf: The output buffer to write to.
++ *
++ * We will call this function to format the output of the 'info' attribute file.
++ * Please refer to PDC Procedures documentation, section PDC_STABLE to get a
++ * better insight of what we're doing here.
++ */
++static ssize_t
++pdcs_info_read(struct subsystem *entry, char *buf)
++{
++ char *out = buf;
++ __u32 result;
++ struct device_path devpath;
++ char *tmpstr = NULL;
++
++ if (!entry || !buf)
++ return -EINVAL;
++
++ /* show the size of the stable storage */
++ out += sprintf(out, "Stable Storage size: %ld bytes\n", pdcs_size);
++
++ /* deal with flags */
++ if (pdc_stable_read(PDCS_ADDR_PPRI, &devpath, sizeof(devpath)) != PDC_OK)
++ return -EIO;
++
++ out += sprintf(out, "Autoboot: %s\n", (devpath.flags & PF_AUTOBOOT) ? "On" : "Off");
++ out += sprintf(out, "Autosearch: %s\n", (devpath.flags & PF_AUTOSEARCH) ? "On" : "Off");
++ out += sprintf(out, "Timer: %u s\n", (devpath.flags & PF_TIMER) ? (1 << (devpath.flags & PF_TIMER)) : 0);
++
++ /* get OSID */
++ if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK)
++ return -EIO;
++
++ /* the actual result is 16 bits away */
++ switch (result >> 16) {
++ case 0x0000: tmpstr = "No OS-dependent data"; break;
++ case 0x0001: tmpstr = "HP-UX dependent data"; break;
++ case 0x0002: tmpstr = "MPE-iX dependent data"; break;
++ case 0x0003: tmpstr = "OSF dependent data"; break;
++ case 0x0004: tmpstr = "HP-RT dependent data"; break;
++ case 0x0005: tmpstr = "Novell Netware dependent data"; break;
++ default: tmpstr = "Unknown"; break;
++ }
++ out += sprintf(out, "OS ID: %s (0x%.4x)\n", tmpstr, (result >> 16));
++
++ /* get fast-size */
++ if (pdc_stable_read(PDCS_ADDR_FSIZ, &result, sizeof(result)) != PDC_OK)
++ return -EIO;
++
++ out += sprintf(out, "Memory tested: ");
++ if ((result & 0x0F) < 0x0E)
++ out += sprintf(out, "%.3f MB", 0.256*(1<<(result & 0x0F)));
++ else
++ out += sprintf(out, "All");
++ out += sprintf(out, "\n");
++
++ return out - buf;
++}
++
++/**
++ * pdcs_info_write - This function handles boot flag modifying.
++ * @entry: An allocated and populated subsytem struct. We don't use it tho.
++ * @buf: The input buffer to read from.
++ * @count: The number of bytes to be read.
++ *
++ * We will call this function to change the current boot flags.
++ * We expect a precise syntax:
++ * \"n n\" (n == 0 or 1) to toggle respectively AutoBoot and AutoSearch
++ *
++ * As of now there is no incentive on my side to provide more "knobs" to that
++ * interface, since modifying the rest of the data is pretty meaningless when
++ * the machine is running and for the expected use of that facility, such as
++ * PALO setting up the boot disk when installing a Linux distribution...
++ */
++static ssize_t
++pdcs_info_write(struct subsystem *entry, const char *buf, size_t count)
++{
++ struct pdcspath_entry *pathentry;
++ unsigned char flags;
++ char in[count+1], *temp;
++ char c;
++
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
++
++ if (!entry || !buf || !count)
++ return -EINVAL;
++
++ /* We'll use a local copy of buf */
++ memset(in, 0, count+1);
++ strncpy(in, buf, count);
++
++ /* Current flags are stored in primary boot path entry */
++ pathentry = &pdcspath_entry_primary;
++
++ /* Be nice to the existing flag record */
++ flags = pathentry->devpath.flags;
++
++ DPRINTK("%s: flags before: 0x%X\n", __func__, flags);
++
++ temp = in;
++
++ while (*temp && isspace(*temp))
++ temp++;
++
++ c = *temp++ - '0';
++ if ((c != 0) && (c != 1))
++ goto parse_error;
++ if (c == 0)
++ flags &= ~PF_AUTOBOOT;
++ else
++ flags |= PF_AUTOBOOT;
++
++ if (*temp++ != ' ')
++ goto parse_error;
++
++ c = *temp++ - '0';
++ if ((c != 0) && (c != 1))
++ goto parse_error;
++ if (c == 0)
++ flags &= ~PF_AUTOSEARCH;
++ else
++ flags |= PF_AUTOSEARCH;
++
++ DPRINTK("%s: flags after: 0x%X\n", __func__, flags);
++
++ /* So far so good, let's get in deep */
++
++ /* Change the path entry flags first */
++ pathentry->devpath.flags = flags;
++
++ /* Now, dive in. Write back to the hardware */
++ WARN_ON(pdcspath_store(pathentry)); /* this warn should *NEVER* happen */
++
++ printk(KERN_INFO "PDC Stable Storage: changed flags to \"%s\"\n", buf);
++
++ return count;
++
++parse_error:
++ printk(KERN_WARNING "%s: Parse error: expect \"n n\" (n == 0 or 1) for AB and AS\n", __func__);
++ return -EINVAL;
++}
++
++/* The last attribute (the 'root' one actually) with all remaining data. */
++static PDCS_ATTR(info, 0600, pdcs_info_read, pdcs_info_write);
++
++static struct subsys_attribute *pdcs_subsys_attrs[] = {
++ &pdcs_attr_info,
++ NULL, /* maybe more in the future? */
++};
++
++static decl_subsys(paths, &ktype_pdcspath, NULL);
++static decl_subsys(pdc, NULL, NULL);
++
++/**
++ * pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage.
++ *
++ * It creates kobjects corresponding to each path entry with nice sysfs
++ * links to the real device. This is where the magic takes place: when
++ * registering the subsystem attributes during module init, each kobject hereby
++ * created will show in the sysfs tree as a folder containing files as defined
++ * by path_subsys_attr[].
++ */
++static inline int __init
++pdcs_register_pathentries(void)
++{
++ unsigned short i;
++ struct pdcspath_entry *entry;
++
++ for (i = 0; (entry = pdcspath_entries[i]); i++) {
++ if (pdcspath_fetch(entry) < 0)
++ continue;
++
++ kobject_set_name(&entry->kobj, "%s", entry->name);
++ kobj_set_kset_s(entry, paths_subsys);
++ kobject_register(&entry->kobj);
++
++ if (!entry->dev)
++ continue;
++
++ /* Add a nice symlink to the real device */
++ sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
++ }
++
++ return 0;
++}
++
++/**
++ * pdcs_unregister_pathentries - Routine called when unregistering the module.
++ */
++static inline void __exit
++pdcs_unregister_pathentries(void)
++{
++ unsigned short i;
++ struct pdcspath_entry *entry;
++
++ for (i = 0; (entry = pdcspath_entries[i]); i++)
++ if (entry->ready)
++ kobject_unregister(&entry->kobj);
++}
++
++/*
++ * For now we register the pdc subsystem with the firmware subsystem
++ * and the paths subsystem with the pdc subsystem
++ */
++static int __init
++pdc_stable_init(void)
++{
++ struct subsys_attribute *attr;
++ int i, rc = 0, error = 0;
++
++ /* find the size of the stable storage */
++ if (pdc_stable_get_size(&pdcs_size) != PDC_OK)
++ return -ENODEV;
++
++ printk(KERN_INFO "PDC Stable Storage facility v%s\n", PDCS_VERSION);
++
++ /* For now we'll register the pdc subsys within this driver */
++ if ((rc = firmware_register(&pdc_subsys)))
++ return rc;
++
++ /* Don't forget the info entry */
++ for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++)
++ if (attr->show)
++ error = subsys_create_file(&pdc_subsys, attr);
++
++ /* register the paths subsys as a subsystem of pdc subsys */
++ kset_set_kset_s(&paths_subsys, pdc_subsys);
++ subsystem_register(&paths_subsys);
++
++ /* now we create all "files" for the paths subsys */
++ pdcs_register_pathentries();
++
++ return 0;
++}
++
++static void __exit
++pdc_stable_exit(void)
++{
++ pdcs_unregister_pathentries();
++ subsystem_unregister(&paths_subsys);
++
++ firmware_unregister(&pdc_subsys);
++}
++
++
++module_init(pdc_stable_init);
++module_exit(pdc_stable_exit);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/power.c CVS2_6_11_PA2/drivers/parisc/power.c
+--- LINUS_2_6_11/drivers/parisc/power.c 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/power.c 2005-01-11 21:10:48.000000000 -0700
+@@ -47,7 +47,6 @@
+ #include <linux/workqueue.h>
+
+ #include <asm/pdc.h>
+-#include <asm/irq.h>
+ #include <asm/io.h>
+ #include <asm/led.h>
+ #include <asm/uaccess.h>
+@@ -126,11 +125,11 @@
+
+ /* wait until the button was pressed for 1 second */
+ if (shutdown_timer == HZ) {
++#if defined (DEBUG) || defined(CONFIG_CHASSIS_LCD_LED)
+ static char msg[] = "Shutting down...";
++#endif
+ DPRINTK(KERN_INFO "%s\n", msg);
+-#ifdef CONFIG_CHASSIS_LCD_LED
+ lcd_print(msg);
+-#endif
+ poweroff();
+ }
+ }
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/sba_iommu.c CVS2_6_11_PA2/drivers/parisc/sba_iommu.c
+--- LINUS_2_6_11/drivers/parisc/sba_iommu.c 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/sba_iommu.c 2005-02-27 16:41:13.000000000 -0700
+@@ -58,7 +58,6 @@
+ ** Don't even think about messing with it unless you have
+ ** plenty of 710's to sacrifice to the computer gods. :^)
+ */
+-#undef DEBUG_SBA_ASSERT
+ #undef DEBUG_SBA_INIT
+ #undef DEBUG_SBA_RUN
+ #undef DEBUG_SBA_RUN_SG
+@@ -92,19 +91,6 @@
+ #define DBG_RES(x...)
+ #endif
+
+-#ifdef DEBUG_SBA_ASSERT
+-#undef ASSERT
+-#define ASSERT(expr) \
+- if(!(expr)) { \
+- printk("\n%s:%d: Assertion " #expr " failed!\n", \
+- __FILE__, __LINE__); \
+- panic(#expr); \
+- }
+-#else
+-#define ASSERT(expr)
+-#endif
+-
+-
+ #if defined(__LP64__) && !defined(CONFIG_PDC_NARROW)
+ /* "low end" PA8800 machines use ZX1 chipset */
+ #define ZX1_SUPPORT
+@@ -125,39 +111,24 @@
+ #define DEFAULT_DMA_HINT_REG 0
+
+ #define ASTRO_RUNWAY_PORT 0x582
+-#define ASTRO_ROPES_PORT 0x780
+-
+ #define IKE_MERCED_PORT 0x803
+-#define IKE_ROPES_PORT 0x781
+-
+ #define REO_MERCED_PORT 0x804
+-#define REO_ROPES_PORT 0x782
+-
+ #define REOG_MERCED_PORT 0x805
+-#define REOG_ROPES_PORT 0x783
+-
+ #define PLUTO_MCKINLEY_PORT 0x880
+-#define PLUTO_ROPES_PORT 0x784
+
+ #define SBA_FUNC_ID 0x0000 /* function id */
+ #define SBA_FCLASS 0x0008 /* function class, bist, header, rev... */
+
+-#define IS_ASTRO(id) \
+-(((id)->hversion == ASTRO_RUNWAY_PORT) || ((id)->hversion == ASTRO_ROPES_PORT))
+-
+-#define IS_IKE(id) \
+-(((id)->hversion == IKE_MERCED_PORT) || ((id)->hversion == IKE_ROPES_PORT))
+-
+-#define IS_PLUTO(id) \
+-(((id)->hversion == PLUTO_MCKINLEY_PORT) || ((id)->hversion == PLUTO_ROPES_PORT))
++#define IS_ASTRO(id) ((id)->hversion == ASTRO_RUNWAY_PORT)
++#define IS_IKE(id) ((id)->hversion == IKE_MERCED_PORT)
++#define IS_PLUTO(id) ((id)->hversion == PLUTO_MCKINLEY_PORT)
+
+ #define SBA_FUNC_SIZE 4096 /* SBA configuration function reg set */
+
+-#define ASTRO_IOC_OFFSET 0x20000
+-/* Ike's IOC's occupy functions 2 and 3 (not 0 and 1) */
+-#define IKE_IOC_OFFSET(p) ((p+2)*SBA_FUNC_SIZE)
+-
+-#define PLUTO_IOC_OFFSET 0x1000
++#define ASTRO_IOC_OFFSET (32 * SBA_FUNC_SIZE)
++#define PLUTO_IOC_OFFSET (1 * SBA_FUNC_SIZE)
++/* Ike's IOC's occupy functions 2 and 3 */
++#define IKE_IOC_OFFSET(p) ((p+2) * SBA_FUNC_SIZE)
+
+ #define IOC_CTRL 0x8 /* IOC_CTRL offset */
+ #define IOC_CTRL_TC (1 << 0) /* TOC Enable */
+@@ -165,6 +136,8 @@
+ #define IOC_CTRL_DE (1 << 2) /* Dillon Enable */
+ #define IOC_CTRL_RM (1 << 8) /* Real Mode */
+ #define IOC_CTRL_NC (1 << 9) /* Non Coherent Mode */
++#define IOC_CTRL_D4 (1 << 11) /* Disable 4-byte coalescing */
++#define IOC_CTRL_DD (1 << 13) /* Disable distr. LMMIO range coalescing */
+
+ #define MAX_IOC 2 /* per Ike. Pluto/Astro only have 1. */
+
+@@ -246,9 +219,9 @@
+
+
+ struct ioc {
+- unsigned long ioc_hpa; /* I/O MMU base address */
+- char *res_map; /* resource map, bit == pdir entry */
+- u64 *pdir_base; /* physical base address */
++ void __iomem *ioc_hpa; /* I/O MMU base address */
++ char *res_map; /* resource map, bit == pdir entry */
++ u64 *pdir_base; /* physical base address */
+ unsigned long ibase; /* pdir IOV Space base - shared w/lba_pci */
+ unsigned long imask; /* pdir IOV Space mask - shared w/lba_pci */
+ #ifdef ZX1_SUPPORT
+@@ -295,7 +268,7 @@
+ struct parisc_device *dev; /* dev found in bus walk */
+ struct parisc_device_id *iodc; /* data about dev from firmware */
+ const char *name;
+- unsigned long sba_hpa; /* base address */
++ void __iomem *sba_hpa; /* base address */
+ spinlock_t sba_lock;
+ unsigned int flags; /* state/functionality enabled */
+ unsigned int hw_rev; /* HW revision of chip */
+@@ -312,9 +285,6 @@
+
+ static unsigned long ioc_needs_fdc = 0;
+
+-/* Ratio of Host MEM to IOV Space size */
+-static unsigned long sba_mem_ratio = 8;
+-
+ /* global count of IOMMUs in the system */
+ static unsigned int global_ioc_cnt = 0;
+
+@@ -364,9 +334,9 @@
+ * IO Adapter (aka Bus Converter).
+ */
+ static void
+-sba_dump_ranges(unsigned long hpa)
++sba_dump_ranges(void __iomem *hpa)
+ {
+- DBG_INIT("SBA at 0x%lx\n", hpa);
++ DBG_INIT("SBA at 0x%p\n", hpa);
+ DBG_INIT("IOS_DIST_BASE : %Lx\n", READ_REG64(hpa+IOS_DIST_BASE));
+ DBG_INIT("IOS_DIST_MASK : %Lx\n", READ_REG64(hpa+IOS_DIST_MASK));
+ DBG_INIT("IOS_DIST_ROUTE : %Lx\n", READ_REG64(hpa+IOS_DIST_ROUTE));
+@@ -382,10 +352,9 @@
+ *
+ * Print the size/location of the IO MMU PDIR.
+ */
+-static void
+-sba_dump_tlb(unsigned long hpa)
++static void sba_dump_tlb(void __iomem *hpa)
+ {
+- DBG_INIT("IO TLB at 0x%lx\n", hpa);
++ DBG_INIT("IO TLB at 0x%p\n", hpa);
+ DBG_INIT("IOC_IBASE : 0x%Lx\n", READ_REG64(hpa+IOC_IBASE));
+ DBG_INIT("IOC_IMASK : 0x%Lx\n", READ_REG64(hpa+IOC_IMASK));
+ DBG_INIT("IOC_TCNFG : 0x%Lx\n", READ_REG64(hpa+IOC_TCNFG));
+@@ -547,8 +516,6 @@
+ unsigned long *res_end = (unsigned long *) &(ioc->res_map[ioc->res_size]);
+ unsigned long pide = ~0UL;
+
+- ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0);
+- ASSERT(res_ptr < res_end);
+ if (bits_wanted > (BITS_PER_LONG/2)) {
+ /* Search word at a time - no mask needed */
+ for(; res_ptr < res_end; ++res_ptr) {
+@@ -583,8 +550,8 @@
+ while(res_ptr < res_end)
+ {
+ DBG_RES(" %p %lx %lx\n", res_ptr, mask, *res_ptr);
+- BUG_ON(0 == mask);
+- if(0 == ((*res_ptr) & mask)) {
++ WARN_ON(mask == 0);
++ if(((*res_ptr) & mask) == 0) {
+ *res_ptr |= mask; /* mark resources busy! */
+ pide = ((unsigned long)res_ptr - (unsigned long)ioc->res_map);
+ pide <<= 3; /* convert to bit address */
+@@ -593,7 +560,7 @@
+ }
+ mask >>= o;
+ bitshiftcnt += o;
+- if (0 == mask) {
++ if (mask == 0) {
+ mask = RESMAP_MASK(bits_wanted);
+ bitshiftcnt=0;
+ res_ptr++;
+@@ -631,21 +598,11 @@
+ #endif
+ unsigned long pide;
+
+- ASSERT(pages_needed);
+- ASSERT((pages_needed * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+- ASSERT(pages_needed <= BITS_PER_LONG);
+- ASSERT(0 == (size & ~IOVP_MASK));
+-
+- /*
+- ** "seek and ye shall find"...praying never hurts either...
+- ** ggg sacrifices another 710 to the computer gods.
+- */
+-
+ pide = sba_search_bitmap(ioc, pages_needed);
+ if (pide >= (ioc->res_size << 3)) {
+ pide = sba_search_bitmap(ioc, pages_needed);
+ if (pide >= (ioc->res_size << 3))
+- panic("%s: I/O MMU @ %lx is out of mapping resources\n",
++ panic("%s: I/O MMU @ %p is out of mapping resources\n",
+ __FILE__, ioc->ioc_hpa);
+ }
+
+@@ -707,11 +664,6 @@
+ ioc->used_pages -= bits_not_wanted;
+ #endif
+
+- ASSERT(m != 0);
+- ASSERT(bits_not_wanted);
+- ASSERT((bits_not_wanted * IOVP_SIZE) <= DMA_CHUNK_SIZE);
+- ASSERT(bits_not_wanted <= BITS_PER_LONG);
+- ASSERT((*res_ptr & m) == m); /* verify same bits are set */
+ *res_ptr &= ~m;
+ }
+
+@@ -732,8 +684,9 @@
+ /**
+ * sba_io_pdir_entry - fill in one IO PDIR entry
+ * @pdir_ptr: pointer to IO PDIR entry
+- * @sid: process Space ID
++ * @sid: process Space ID - currently only support KERNEL_SPACE
+ * @vba: Virtual CPU address of buffer to map
++ * @hint: DMA hint set to use for this mapping
+ *
+ * SBA Mapping Routine
+ *
+@@ -768,7 +721,6 @@
+ * IOMMU uses little endian for the pdir.
+ */
+
+-
+ void SBA_INLINE
+ sba_io_pdir_entry(u64 *pdir_ptr, space_t sid, unsigned long vba,
+ unsigned long hint)
+@@ -776,12 +728,6 @@
+ u64 pa; /* physical address */
+ register unsigned ci; /* coherent index */
+
+- /* We currently only support kernel addresses.
+- * fdc instr below will need to reload sr1 with KERNEL_SPACE
+- * once we try to support direct DMA to user space.
+- */
+- ASSERT(sid == KERNEL_SPACE);
+-
+ pa = virt_to_phys(vba);
+ pa &= IOVP_MASK;
+
+@@ -830,10 +776,6 @@
+ */
+ int off = PDIR_INDEX(iovp)*sizeof(u64)+7;
+
+- /* Must be non-zero and rounded up */
+- ASSERT(byte_cnt > 0);
+- ASSERT(0 == (byte_cnt & ~IOVP_MASK));
+-
+ #ifdef ASSERT_PDIR_SANITY
+ /* Assert first pdir entry is set */
+ if (0x80 != (((u8 *) ioc->pdir_base)[off])) {
+@@ -843,8 +785,6 @@
+
+ if (byte_cnt <= IOVP_SIZE)
+ {
+- ASSERT( off < ioc->pdir_size);
+-
+ iovp |= IOVP_SHIFT; /* set "size" field for PCOM */
+
+ /*
+@@ -858,11 +798,7 @@
+ u32 t = get_order(byte_cnt) + PAGE_SHIFT;
+
+ iovp |= t;
+- ASSERT(t <= 31); /* 2GB! Max value of "size" field */
+-
+ do {
+- /* verify this pdir entry is enabled */
+- ASSERT(0x80 == (((u8 *) ioc->pdir_base)[off] & 0x80));
+ /* clear I/O Pdir entry "valid" bit first */
+ ((u8 *)(ioc->pdir_base))[off] = 0;
+ off += sizeof(u64);
+@@ -880,17 +816,21 @@
+ *
+ * See Documentation/DMA-mapping.txt
+ */
+-static int
+-sba_dma_supported( struct device *dev, u64 mask)
++static int sba_dma_supported( struct device *dev, u64 mask)
+ {
++ struct ioc *ioc;
+ if (dev == NULL) {
+ printk(KERN_ERR MODULE_NAME ": EISA/ISA/et al not supported\n");
+ BUG();
+ return(0);
+ }
+
+- /* only support 32-bit PCI devices - no DAC support (yet) */
+- return((int) (mask == 0xffffffffUL));
++ ioc = GET_IOC(dev);
++
++ /* check if mask is > than the largest IO Virt Address */
++
++ return((int) (mask >= (ioc->ibase +
++ (ioc->pdir_size / sizeof(u64) * IOVP_SIZE) )));
+ }
+
+
+@@ -914,11 +854,7 @@
+ u64 *pdir_start;
+ int pide;
+
+- ASSERT(size > 0);
+- ASSERT(size <= DMA_CHUNK_SIZE);
+-
+ ioc = GET_IOC(dev);
+- ASSERT(ioc);
+
+ /* save offset bits */
+ offset = ((dma_addr_t) (long) addr) & ~IOVP_MASK;
+@@ -944,7 +880,6 @@
+ pdir_start = &(ioc->pdir_base[pide]);
+
+ while (size > 0) {
+- ASSERT(((u8 *)pdir_start)[7] == 0); /* verify availability */
+ sba_io_pdir_entry(pdir_start, KERNEL_SPACE, (unsigned long) addr, 0);
+
+ DBG_RUN(" pdir 0x%p %02x%02x%02x%02x%02x%02x%02x%02x\n",
+@@ -992,14 +927,10 @@
+ unsigned long flags;
+ dma_addr_t offset;
+
+- ioc = GET_IOC(dev);
+- ASSERT(ioc);
++ DBG_RUN("%s() iovp 0x%lx/%x\n", __FUNCTION__, (long) iova, size);
+
++ ioc = GET_IOC(dev);
+ offset = iova & ~IOVP_MASK;
+-
+- DBG_RUN("%s() iovp 0x%lx/%x\n",
+- __FUNCTION__, (long) iova, size);
+-
+ iova ^= offset; /* clear offset bits */
+ size += offset;
+ size = ROUNDUP(size, IOVP_SIZE);
+@@ -1131,7 +1062,6 @@
+ DBG_RUN_SG("%s() START %d entries\n", __FUNCTION__, nents);
+
+ ioc = GET_IOC(dev);
+- ASSERT(ioc);
+
+ /* Fast path single entry scatterlists. */
+ if (nents == 1) {
+@@ -1186,7 +1116,6 @@
+
+ spin_unlock_irqrestore(&ioc->res_lock, flags);
+
+- ASSERT(coalesced == filled);
+ DBG_RUN_SG("%s() DONE %d mappings\n", __FUNCTION__, filled);
+
+ return filled;
+@@ -1215,7 +1144,6 @@
+ __FUNCTION__, nents, sg_virt_addr(sglist), sglist->length);
+
+ ioc = GET_IOC(dev);
+- ASSERT(ioc);
+
+ #ifdef SBA_COLLECT_STATS
+ ioc->usg_calls++;
+@@ -1394,16 +1322,27 @@
+ return (void *) pdir_base;
+ }
+
+-static void
+-sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
++/* setup Mercury or Elroy IBASE/IMASK registers. */
++static void setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
+ {
+- /* lba_set_iregs() is in arch/parisc/kernel/lba_pci.c */
++ /* lba_set_iregs() is in drivers/parisc/lba_pci.c */
+ extern void lba_set_iregs(struct parisc_device *, u32, u32);
++ struct device *dev;
++
++ list_for_each_entry(dev, &sba->dev.children, node) {
++ struct parisc_device *lba = to_parisc_device(dev);
++ int rope_num = (lba->hpa >> 13) & 0xf;
++ if (rope_num >> 3 == ioc_num)
++ lba_set_iregs(lba, ioc->ibase, ioc->imask);
++ }
++}
+
++static void
++sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
++{
+ u32 iova_space_mask;
+ u32 iova_space_size;
+ int iov_order, tcnfg;
+- struct parisc_device *lba;
+ #if SBA_AGP_SUPPORT
+ int agp_found = 0;
+ #endif
+@@ -1449,7 +1388,7 @@
+ ioc->hint_shift_pdir, ioc->hint_mask_pdir);
+ #endif
+
+- ASSERT((((unsigned long) ioc->pdir_base) & PAGE_MASK) == (unsigned long) ioc->pdir_base);
++ WARN_ON((((unsigned long) ioc->pdir_base) & PAGE_MASK) != (unsigned long) ioc->pdir_base);
+ WRITE_REG(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE);
+
+ /* build IMASK for IOC and Elroy */
+@@ -1461,14 +1400,7 @@
+ #endif
+ sba_dump_tlb(ioc->ioc_hpa);
+
+- /*
+- ** setup Mercury IBASE/IMASK registers as well.
+- */
+- for (lba = sba->child; lba; lba = lba->sibling) {
+- int rope_num = (lba->hpa >> 13) & 0xf;
+- if (rope_num >> 3 == ioc_num)
+- lba_set_iregs(lba, ioc->ibase, ioc->imask);
+- }
++ setup_ibase_imask(sba, ioc, ioc_num);
+
+ WRITE_REG(ioc->imask, ioc->ioc_hpa + IOC_IMASK);
+
+@@ -1534,13 +1466,8 @@
+ static void
+ sba_ioc_init(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
+ {
+- /* lba_set_iregs() is in arch/parisc/kernel/lba_pci.c */
+- extern void lba_set_iregs(struct parisc_device *, u32, u32);
+-
+ u32 iova_space_size, iova_space_mask;
+- int pdir_size, iov_order;
+- unsigned long physmem;
+- struct parisc_device *lba;
++ unsigned int pdir_size, iov_order;
+
+ /*
+ ** Determine IOVA Space size from memory size.
+@@ -1556,16 +1483,15 @@
+ ** for DMA hints - ergo only 30 bits max.
+ */
+
+- physmem = num_physpages << PAGE_SHIFT;
+- iova_space_size = (u32) (physmem/(sba_mem_ratio*global_ioc_cnt));
++ iova_space_size = (u32) (num_physpages/global_ioc_cnt);
+
+ /* limit IOVA space size to 1MB-1GB */
+- if (iova_space_size < 1024*1024) {
+- iova_space_size = 1024*1024;
++ if (iova_space_size < (1 << (20 - PAGE_SHIFT))) {
++ iova_space_size = 1 << (20 - PAGE_SHIFT);
+ }
+ #ifdef __LP64__
+- else if (iova_space_size > 512*1024*1024) {
+- iova_space_size = 512*1024*1024;
++ else if (iova_space_size > (1 << (30 - PAGE_SHIFT))) {
++ iova_space_size = 1 << (30 - PAGE_SHIFT);
+ }
+ #endif
+
+@@ -1574,21 +1500,19 @@
+ ** thus, pdir/res_map will also be log2().
+ ** PIRANHA BUG: Exception is when IO Pdir is 2MB (gets reduced)
+ */
+- iov_order = get_order(iova_space_size >> (IOVP_SHIFT-PAGE_SHIFT));
+- ASSERT(iov_order <= (30 - IOVP_SHIFT)); /* iova_space_size <= 1GB */
+- ASSERT(iov_order >= (20 - IOVP_SHIFT)); /* iova_space_size >= 1MB */
+- iova_space_size = 1 << (iov_order + IOVP_SHIFT);
++ iov_order = get_order(iova_space_size << PAGE_SHIFT);
+
+- ioc->pdir_size = pdir_size = (iova_space_size/IOVP_SIZE) * sizeof(u64);
++ /* iova_space_size is now bytes, not pages */
++ iova_space_size = 1 << (iov_order + PAGE_SHIFT);
+
+- ASSERT(pdir_size < 4*1024*1024); /* max pdir size == 2MB */
+-
+- /* Verify it's a power of two */
+- ASSERT((1 << get_order(pdir_size)) == (pdir_size >> PAGE_SHIFT));
++ ioc->pdir_size = pdir_size = (iova_space_size/IOVP_SIZE) * sizeof(u64);
+
+- DBG_INIT("%s() hpa 0x%lx mem %dMB IOV %dMB (%d bits) PDIR size 0x%0x\n",
+- __FUNCTION__, ioc->ioc_hpa, (int) (physmem>>20),
+- iova_space_size>>20, iov_order + PAGE_SHIFT, pdir_size);
++ DBG_INIT("%s() hpa 0x%lx mem %ldMB IOV %dMB (%d bits)\n",
++ __FUNCTION__,
++ ioc->ioc_hpa,
++ (unsigned long) num_physpages >> (20 - PAGE_SHIFT),
++ iova_space_size>>20,
++ iov_order + PAGE_SHIFT);
+
+ ioc->pdir_base = sba_alloc_pdir(pdir_size);
+
+@@ -1604,7 +1528,6 @@
+ ioc->hint_shift_pdir, ioc->hint_mask_pdir);
+ #endif
+
+- ASSERT((((unsigned long) ioc->pdir_base) & PAGE_MASK) == (unsigned long) ioc->pdir_base);
+ WRITE_REG64(virt_to_phys(ioc->pdir_base), ioc->ioc_hpa + IOC_PDIR_BASE);
+
+ /* build IMASK for IOC and Elroy */
+@@ -1630,14 +1553,7 @@
+ ** can't reprogram them the way drivers want.
+ */
+
+- /*
+- ** setup Elroy IBASE/IMASK registers as well.
+- */
+- for (lba = sba->child; lba; lba = lba->sibling) {
+- int rope_num = (lba->hpa >> 13) & 0xf;
+- if (rope_num >> 3 == ioc_num)
+- lba_set_iregs(lba, ioc->ibase, ioc->imask);
+- }
++ setup_ibase_imask(sba, ioc, ioc_num);
+
+ /*
+ ** Program the IOC's ibase and enable IOVA translation
+@@ -1672,8 +1588,12 @@
+ **
+ **************************************************************************/
+
+-static void
+-sba_hw_init(struct sba_device *sba_dev)
++static void __iomem *ioc_remap(struct sba_device *sba_dev, int offset)
++{
++ return ioremap(sba_dev->dev->hpa + offset, SBA_FUNC_SIZE);
++}
++
++static void sba_hw_init(struct sba_device *sba_dev)
+ {
+ int i;
+ int num_ioc;
+@@ -1682,24 +1602,55 @@
+ if (!is_pdc_pat()) {
+ /* Shutdown the USB controller on Astro-based workstations.
+ ** Once we reprogram the IOMMU, the next DMA performed by
+- ** USB will HPMC the box.
++ ** USB will HPMC the box. USB is only enabled if a
++ ** keyboard is present and found.
++ **
++ ** With serial console, j6k v5.0 firmware says:
++ ** mem_kbd hpa 0xfee003f8 sba 0x0 pad 0x0 cl_class 0x7
++ **
++ ** FIXME: Using GFX+USB console at power up but direct
++ ** linux to serial console is still broken.
++ ** USB could generate DMA so we must reset USB.
++ ** The proper sequence would be:
++ ** o block console output
++ ** o reset USB device
++ ** o reprogram serial port
++ ** o unblock console output
+ */
+- pdc_io_reset_devices();
++ if (PAGE0->mem_kbd.cl_class == CL_KEYBD) {
++ pdc_io_reset_devices();
++ }
+
+- /*
+- ** XXX May need something more sophisticated to deal
+- ** with DMA from LAN. Maybe use page zero boot device
+- ** as a handle to talk to PDC about which device to
+- ** shutdown. This also needs to work for is_pdc_pat().
+- */
+ }
+
++
++#if 0
++printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa,
++ PAGE0->mem_boot.spa, PAGE0->mem_boot.pad, PAGE0->mem_boot.cl_class);
++
++ /*
++ ** Need to deal with DMA from LAN.
++ ** Maybe use page zero boot device as a handle to talk
++ ** to PDC about which device to shutdown.
++ **
++ ** Netbooting, j6k v5.0 firmware says:
++ ** mem_boot hpa 0xf4008000 sba 0x0 pad 0x0 cl_class 0x1002
++ ** ARGH! invalid class.
++ */
++ if ((PAGE0->mem_boot.cl_class != CL_RANDOM)
++ && (PAGE0->mem_boot.cl_class != CL_SEQU)) {
++ pdc_io_reset();
++ }
++#endif
++
+ if (!IS_PLUTO(sba_dev->iodc)) {
+ ioc_ctl = READ_REG(sba_dev->sba_hpa+IOC_CTRL);
+ DBG_INIT("%s() hpa 0x%lx ioc_ctl 0x%Lx ->",
+ __FUNCTION__, sba_dev->sba_hpa, ioc_ctl);
+ ioc_ctl &= ~(IOC_CTRL_RM | IOC_CTRL_NC | IOC_CTRL_CE);
+- ioc_ctl |= IOC_CTRL_TC; /* Astro: firmware enables this */
++ ioc_ctl |= IOC_CTRL_DD | IOC_CTRL_D4 | IOC_CTRL_TC;
++ /* j6700 v1.6 firmware sets 0x294f */
++ /* A500 firmware sets 0x4d */
+
+ WRITE_REG(ioc_ctl, sba_dev->sba_hpa+IOC_CTRL);
+
+@@ -1712,7 +1663,7 @@
+ if (IS_ASTRO(sba_dev->iodc)) {
+ int err;
+ /* PAT_PDC (L-class) also reports the same goofy base */
+- sba_dev->ioc[0].ioc_hpa = ASTRO_IOC_OFFSET;
++ sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, ASTRO_IOC_OFFSET);
+ num_ioc = 1;
+
+ sba_dev->chip_resv.name = "Astro Intr Ack";
+@@ -1730,32 +1681,32 @@
+ * corrected when we add it with IKE's IOC offset.
+ * Doesnt look clean, but fewer code.
+ */
+- sba_dev->ioc[0].ioc_hpa = -PLUTO_IOC_OFFSET;
++ sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, PLUTO_IOC_OFFSET);
+ num_ioc = 1;
+
+ sba_dev->chip_resv.name = "Pluto Intr/PIOP/VGA";
+ sba_dev->chip_resv.start = PCI_F_EXTEND | 0xfee00000UL;
+ sba_dev->chip_resv.end = PCI_F_EXTEND | (0xff200000UL - 1);
+ err = request_resource(&iomem_resource, &(sba_dev->chip_resv));
+- BUG_ON(err < 0);
++ WARN_ON(err < 0);
+
+ sba_dev->iommu_resv.name = "IOVA Space";
+ sba_dev->iommu_resv.start = 0x40000000UL;
+ sba_dev->iommu_resv.end = 0x50000000UL - 1;
+ err = request_resource(&iomem_resource, &(sba_dev->iommu_resv));
+- BUG_ON(err < 0);
++ WARN_ON(err < 0);
+ } else {
+ /* IS_IKE (ie N-class, L3000, L1500) */
+- sba_dev->ioc[0].ioc_hpa = sba_dev->ioc[1].ioc_hpa = 0;
++ sba_dev->ioc[0].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(0));
++ sba_dev->ioc[1].ioc_hpa = ioc_remap(sba_dev, IKE_IOC_OFFSET(1));
+ num_ioc = 2;
+
+ /* TODO - LOOKUP Ike/Stretch chipset mem map */
+ }
++ /* XXX: What about Reo? */
+
+ sba_dev->num_ioc = num_ioc;
+ for (i = 0; i < num_ioc; i++) {
+- sba_dev->ioc[i].ioc_hpa += sba_dev->sba_hpa + IKE_IOC_OFFSET(i);
+-
+ /*
+ ** Make sure the box crashes if we get any errors on a rope.
+ */
+@@ -1771,6 +1722,16 @@
+ /* flush out the writes */
+ READ_REG(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL);
+
++ DBG_INIT(" ioc[%d] ROPE_CFG 0x%Lx ROPE_DBG 0x%Lx\n",
++ i,
++ READ_REG(sba_dev->ioc[i].ioc_hpa + 0x40),
++ READ_REG(sba_dev->ioc[i].ioc_hpa + 0x50)
++ );
++ DBG_INIT(" STATUS_CONTROL 0x%Lx FLUSH_CTRL 0x%Lx\n",
++ READ_REG(sba_dev->ioc[i].ioc_hpa + 0x108),
++ READ_REG(sba_dev->ioc[i].ioc_hpa + 0x400)
++ );
++
+ if (IS_PLUTO(sba_dev->iodc)) {
+ sba_ioc_init_pluto(sba_dev->dev, &(sba_dev->ioc[i]), i);
+ } else {
+@@ -1984,16 +1945,6 @@
+ { HPHW_BCPORT, HVERSION_REV_ANY_ID, REO_MERCED_PORT, 0xc },
+ { HPHW_BCPORT, HVERSION_REV_ANY_ID, REOG_MERCED_PORT, 0xc },
+ { HPHW_IOA, HVERSION_REV_ANY_ID, PLUTO_MCKINLEY_PORT, 0xc },
+-/* These two entries commented out because we don't find them in a
+- * buswalk yet. If/when we do, they would cause us to think we had
+- * many more SBAs then we really do.
+- * { HPHW_BCPORT, HVERSION_REV_ANY_ID, ASTRO_ROPES_PORT, 0xc },
+- * { HPHW_BCPORT, HVERSION_REV_ANY_ID, IKE_ROPES_PORT, 0xc },
+- */
+-/* We shall also comment out Pluto Ropes Port since bus walk doesnt
+- * report it yet.
+- * { HPHW_BCPORT, HVERSION_REV_ANY_ID, PLUTO_ROPES_PORT, 0xc },
+- */
+ { 0, }
+ };
+
+@@ -2017,18 +1968,19 @@
+ u32 func_class;
+ int i;
+ char *version;
++ void __iomem *sba_addr = ioremap(dev->hpa, SBA_FUNC_SIZE);
+
+- sba_dump_ranges(dev->hpa);
++ sba_dump_ranges(sba_addr);
+
+ /* Read HW Rev First */
+- func_class = READ_REG(dev->hpa + SBA_FCLASS);
++ func_class = READ_REG(sba_addr + SBA_FCLASS);
+
+ if (IS_ASTRO(&dev->id)) {
+ unsigned long fclass;
+ static char astro_rev[]="Astro ?.?";
+
+ /* Astro is broken...Read HW Rev First */
+- fclass = READ_REG(dev->hpa);
++ fclass = READ_REG(sba_addr);
+
+ astro_rev[6] = '1' + (char) (fclass & 0x7);
+ astro_rev[8] = '0' + (char) ((fclass & 0x18) >> 3);
+@@ -2061,12 +2013,12 @@
+ MODULE_NAME, version, dev->hpa);
+
+ sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL);
+- if (NULL == sba_dev) {
++ if (!sba_dev) {
+ printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n");
+- return(1);
++ return -ENOMEM;
+ }
+
+- dev->sysdata = (void *) sba_dev;
++ parisc_set_drvdata(dev, sba_dev);
+ memset(sba_dev, 0, sizeof(struct sba_device));
+
+ for(i=0; i<MAX_IOC; i++)
+@@ -2076,7 +2028,7 @@
+ sba_dev->hw_rev = func_class;
+ sba_dev->iodc = &dev->id;
+ sba_dev->name = dev->name;
+- sba_dev->sba_hpa = dev->hpa; /* faster access */
++ sba_dev->sba_hpa = sba_addr;
+
+ sba_get_pat_resources(sba_dev);
+ sba_hw_init(sba_dev);
+@@ -2100,7 +2052,7 @@
+ #endif
+ parisc_vmerge_boundary = IOVP_SIZE;
+ parisc_vmerge_max_size = IOVP_SIZE * BITS_PER_LONG;
+-
++ parisc_has_iommu();
+ return 0;
+ }
+
+@@ -2129,7 +2081,7 @@
+ char t = sba_dev->id.hw_type;
+ int iocnum = (pci_hba->hw_path >> 3); /* rope # */
+
+- BUG_ON((t != HPHW_IOA) && (t != HPHW_BCPORT));
++ WARN_ON((t != HPHW_IOA) && (t != HPHW_BCPORT));
+
+ return &(sba->ioc[iocnum]);
+ }
+@@ -2159,7 +2111,7 @@
+ /* Astro has 4 directed ranges. Not sure about Ike/Pluto/et al */
+ for (i=0; i<4; i++) {
+ int base, size;
+- unsigned long reg = sba->sba_hpa + i*0x18;
++ void __iomem *reg = sba->sba_hpa + i*0x18;
+
+ base = READ_REG32(reg + LMMIO_DIRECT0_BASE);
+ if ((base & 1) == 0)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/superio.c CVS2_6_11_PA2/drivers/parisc/superio.c
+--- LINUS_2_6_11/drivers/parisc/superio.c 2005-01-11 21:10:48.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/superio.c 2005-03-06 15:29:27.000000000 -0700
+@@ -495,7 +495,7 @@
+
+ static int __init superio_modinit(void)
+ {
+- return pci_module_init(&superio_driver);
++ return pci_register_driver(&superio_driver);
+ }
+
+ static void __exit superio_exit(void)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parisc/wax.c CVS2_6_11_PA2/drivers/parisc/wax.c
+--- LINUS_2_6_11/drivers/parisc/wax.c 2005-03-02 04:19:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parisc/wax.c 2005-02-03 05:48:16.000000000 -0700
+@@ -25,20 +25,27 @@
+ #include "gsc.h"
+
+ #define WAX_GSC_IRQ 7 /* Hardcoded Interrupt for GSC */
+-#define WAX_GSC_NMI_IRQ 29
+
+ static void wax_choose_irq(struct parisc_device *dev, void *ctrl)
+ {
+ int irq;
+
+ switch (dev->id.sversion) {
+- case 0x73: irq = 1; break; /* HIL */
+- case 0x8c: irq = 6; break; /* RS232 */
+- case 0x90: irq = 10; break; /* WAX EISA BA */
++ case 0x73: irq = 1; break; /* i8042 General */
++ case 0x8c: irq = 6; break; /* Serial */
++ case 0x90: irq = 10; break; /* EISA */
+ default: return; /* Unknown */
+ }
+
+ gsc_asic_assign_irq(ctrl, irq, &dev->irq);
++
++ switch (dev->id.sversion) {
++ case 0x73: irq = 2; break; /* i8042 High-priority */
++ case 0x90: irq = 0; break; /* EISA NMI */
++ default: return; /* No secondary IRQ */
++ }
++
++ gsc_asic_assign_irq(ctrl, irq, &dev->aux_irq);
+ }
+
+ static void __init
+@@ -46,7 +53,7 @@
+ {
+ unsigned long base = wax->hpa;
+
+- /* Stop WAX barking for a bit */
++ /* Wax-off */
+ gsc_writel(0x00000000, base+OFFSET_IMR);
+
+ /* clear pending interrupts */
+@@ -59,11 +66,6 @@
+ /* Resets */
+ // gsc_writel(0xFFFFFFFF, base+0x1000); /* HIL */
+ // gsc_writel(0xFFFFFFFF, base+0x2000); /* RS232-B on Wax */
+-
+- /* Ok we hit it on the head with a hammer, our Dog is now
+- ** comatose and muzzled. Devices will now unmask WAX
+- ** interrupts as they are registered as irq's in the WAX range.
+- */
+ }
+
+ int __init
+@@ -78,7 +80,7 @@
+ if (!wax)
+ return -ENOMEM;
+
+- wax->name = "Wax";
++ wax->name = "wax";
+ wax->hpa = dev->hpa;
+
+ wax->version = 0; /* gsc_readb(wax->hpa+WAX_VER); */
+@@ -132,7 +134,7 @@
+ MODULE_DEVICE_TABLE(parisc, wax_tbl);
+
+ struct parisc_driver wax_driver = {
+- .name = "Wax",
++ .name = "wax",
+ .id_table = wax_tbl,
+ .probe = wax_init_chip,
+ };
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parport/parport_gsc.c CVS2_6_11_PA2/drivers/parport/parport_gsc.c
+--- LINUS_2_6_11/drivers/parport/parport_gsc.c 2005-03-02 04:19:12.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parport/parport_gsc.c 2005-01-03 16:44:27.000000000 -0700
+@@ -42,7 +42,7 @@
+ #include <asm/pdc.h>
+ #include <asm/parisc-device.h>
+ #include <asm/hardware.h>
+-#include <asm/parport_gsc.h>
++#include "parport_gsc.h"
+
+
+ MODULE_AUTHOR("Helge Deller <deller at gmx.de>");
+@@ -87,95 +87,6 @@
+ return IRQ_HANDLED;
+ }
+
+-void parport_gsc_write_data(struct parport *p, unsigned char d)
+-{
+- parport_writeb (d, DATA (p));
+-}
+-
+-unsigned char parport_gsc_read_data(struct parport *p)
+-{
+- unsigned char c = parport_readb (DATA (p));
+- return c;
+-}
+-
+-void parport_gsc_write_control(struct parport *p, unsigned char d)
+-{
+- const unsigned char wm = (PARPORT_CONTROL_STROBE |
+- PARPORT_CONTROL_AUTOFD |
+- PARPORT_CONTROL_INIT |
+- PARPORT_CONTROL_SELECT);
+-
+- /* Take this out when drivers have adapted to the newer interface. */
+- if (d & 0x20) {
+- pr_debug("%s (%s): use data_reverse for this!\n",
+- p->name, p->cad->name);
+- parport_gsc_data_reverse (p);
+- }
+-
+- __parport_gsc_frob_control (p, wm, d & wm);
+-}
+-
+-unsigned char parport_gsc_read_control(struct parport *p)
+-{
+- const unsigned char wm = (PARPORT_CONTROL_STROBE |
+- PARPORT_CONTROL_AUTOFD |
+- PARPORT_CONTROL_INIT |
+- PARPORT_CONTROL_SELECT);
+- const struct parport_gsc_private *priv = p->physport->private_data;
+- return priv->ctr & wm; /* Use soft copy */
+-}
+-
+-unsigned char parport_gsc_frob_control (struct parport *p, unsigned char mask,
+- unsigned char val)
+-{
+- const unsigned char wm = (PARPORT_CONTROL_STROBE |
+- PARPORT_CONTROL_AUTOFD |
+- PARPORT_CONTROL_INIT |
+- PARPORT_CONTROL_SELECT);
+-
+- /* Take this out when drivers have adapted to the newer interface. */
+- if (mask & 0x20) {
+- pr_debug("%s (%s): use data_%s for this!\n",
+- p->name, p->cad->name,
+- (val & 0x20) ? "reverse" : "forward");
+- if (val & 0x20)
+- parport_gsc_data_reverse (p);
+- else
+- parport_gsc_data_forward (p);
+- }
+-
+- /* Restrict mask and val to control lines. */
+- mask &= wm;
+- val &= wm;
+-
+- return __parport_gsc_frob_control (p, mask, val);
+-}
+-
+-unsigned char parport_gsc_read_status(struct parport *p)
+-{
+- return parport_readb (STATUS (p));
+-}
+-
+-void parport_gsc_disable_irq(struct parport *p)
+-{
+- __parport_gsc_frob_control (p, 0x10, 0);
+-}
+-
+-void parport_gsc_enable_irq(struct parport *p)
+-{
+- __parport_gsc_frob_control (p, 0x10, 0x10);
+-}
+-
+-void parport_gsc_data_forward (struct parport *p)
+-{
+- __parport_gsc_frob_control (p, 0x20, 0);
+-}
+-
+-void parport_gsc_data_reverse (struct parport *p)
+-{
+- __parport_gsc_frob_control (p, 0x20, 0x20);
+-}
+-
+ void parport_gsc_init_state(struct pardevice *dev, struct parport_state *s)
+ {
+ s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/parport/parport_gsc.h CVS2_6_11_PA2/drivers/parport/parport_gsc.h
+--- LINUS_2_6_11/drivers/parport/parport_gsc.h 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/drivers/parport/parport_gsc.h 2005-01-03 16:44:27.000000000 -0700
+@@ -0,0 +1,222 @@
++/*
++ * Low-level parallel-support for PC-style hardware integrated in the
++ * LASI-Controller (on GSC-Bus) for HP-PARISC Workstations
++ *
++ * (C) 1999-2001 by Helge Deller <deller at gmx.de>
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ * based on parport_pc.c by
++ * Grant Guenther <grant at torque.net>
++ * Phil Blundell <Philip.Blundell at pobox.com>
++ * Tim Waugh <tim at cyberelk.demon.co.uk>
++ * Jose Renau <renau at acm.org>
++ * David Campbell <campbell at torque.net>
++ * Andrea Arcangeli
++ */
++
++#ifndef __DRIVERS_PARPORT_PARPORT_GSC_H
++#define __DRIVERS_PARPORT_PARPORT_GSC_H
++
++#include <asm/io.h>
++#include <linux/delay.h>
++
++#undef DEBUG_PARPORT /* undefine for production */
++#define DELAY_TIME 0
++
++#if DELAY_TIME == 0
++#define parport_readb gsc_readb
++#define parport_writeb gsc_writeb
++#else
++static __inline__ unsigned char parport_readb( unsigned long port )
++{
++ udelay(DELAY_TIME);
++ return gsc_readb(port);
++}
++
++static __inline__ void parport_writeb( unsigned char value, unsigned long port )
++{
++ gsc_writeb(value,port);
++ udelay(DELAY_TIME);
++}
++#endif
++
++/* --- register definitions ------------------------------- */
++
++#define EPPDATA(p) ((p)->base + 0x4)
++#define EPPADDR(p) ((p)->base + 0x3)
++#define CONTROL(p) ((p)->base + 0x2)
++#define STATUS(p) ((p)->base + 0x1)
++#define DATA(p) ((p)->base + 0x0)
++
++struct parport_gsc_private {
++ /* Contents of CTR. */
++ unsigned char ctr;
++
++ /* Bitmask of writable CTR bits. */
++ unsigned char ctr_writable;
++
++ /* Number of bytes per portword. */
++ int pword;
++
++ /* Not used yet. */
++ int readIntrThreshold;
++ int writeIntrThreshold;
++
++ /* buffer suitable for DMA, if DMA enabled */
++ char *dma_buf;
++ dma_addr_t dma_handle;
++ struct pci_dev *dev;
++};
++
++static inline void parport_gsc_write_data(struct parport *p, unsigned char d)
++{
++#ifdef DEBUG_PARPORT
++ printk (KERN_DEBUG "parport_gsc_write_data(%p,0x%02x)\n", p, d);
++#endif
++ parport_writeb(d, DATA(p));
++}
++
++static inline unsigned char parport_gsc_read_data(struct parport *p)
++{
++ unsigned char val = parport_readb (DATA (p));
++#ifdef DEBUG_PARPORT
++ printk (KERN_DEBUG "parport_gsc_read_data(%p) = 0x%02x\n",
++ p, val);
++#endif
++ return val;
++}
++
++/* __parport_gsc_frob_control differs from parport_gsc_frob_control in that
++ * it doesn't do any extra masking. */
++static inline unsigned char __parport_gsc_frob_control(struct parport *p,
++ unsigned char mask,
++ unsigned char val)
++{
++ struct parport_gsc_private *priv = p->physport->private_data;
++ unsigned char ctr = priv->ctr;
++#ifdef DEBUG_PARPORT
++ printk (KERN_DEBUG
++ "__parport_gsc_frob_control(%02x,%02x): %02x -> %02x\n",
++ mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable);
++#endif
++ ctr = (ctr & ~mask) ^ val;
++ ctr &= priv->ctr_writable; /* only write writable bits. */
++ parport_writeb (ctr, CONTROL (p));
++ priv->ctr = ctr; /* Update soft copy */
++ return ctr;
++}
++
++static inline void parport_gsc_data_reverse(struct parport *p)
++{
++ __parport_gsc_frob_control (p, 0x20, 0x20);
++}
++
++static inline void parport_gsc_data_forward(struct parport *p)
++{
++ __parport_gsc_frob_control (p, 0x20, 0x00);
++}
++
++static inline void parport_gsc_write_control(struct parport *p,
++ unsigned char d)
++{
++ const unsigned char wm = (PARPORT_CONTROL_STROBE |
++ PARPORT_CONTROL_AUTOFD |
++ PARPORT_CONTROL_INIT |
++ PARPORT_CONTROL_SELECT);
++
++ /* Take this out when drivers have adapted to newer interface. */
++ if (d & 0x20) {
++ printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n",
++ p->name, p->cad->name);
++ parport_gsc_data_reverse (p);
++ }
++
++ __parport_gsc_frob_control (p, wm, d & wm);
++}
++
++static inline unsigned char parport_gsc_read_control(struct parport *p)
++{
++ const unsigned char rm = (PARPORT_CONTROL_STROBE |
++ PARPORT_CONTROL_AUTOFD |
++ PARPORT_CONTROL_INIT |
++ PARPORT_CONTROL_SELECT);
++ const struct parport_gsc_private *priv = p->physport->private_data;
++ return priv->ctr & rm; /* Use soft copy */
++}
++
++static inline unsigned char parport_gsc_frob_control(struct parport *p,
++ unsigned char mask,
++ unsigned char val)
++{
++ const unsigned char wm = (PARPORT_CONTROL_STROBE |
++ PARPORT_CONTROL_AUTOFD |
++ PARPORT_CONTROL_INIT |
++ PARPORT_CONTROL_SELECT);
++
++ /* Take this out when drivers have adapted to newer interface. */
++ if (mask & 0x20) {
++ printk (KERN_DEBUG "%s (%s): use data_%s for this!\n",
++ p->name, p->cad->name,
++ (val & 0x20) ? "reverse" : "forward");
++ if (val & 0x20)
++ parport_gsc_data_reverse (p);
++ else
++ parport_gsc_data_forward (p);
++ }
++
++ /* Restrict mask and val to control lines. */
++ mask &= wm;
++ val &= wm;
++
++ return __parport_gsc_frob_control (p, mask, val);
++}
++
++static inline unsigned char parport_gsc_read_status(struct parport *p)
++{
++ return parport_readb (STATUS(p));
++}
++
++static inline void parport_gsc_disable_irq(struct parport *p)
++{
++ __parport_gsc_frob_control (p, 0x10, 0x00);
++}
++
++static inline void parport_gsc_enable_irq(struct parport *p)
++{
++ __parport_gsc_frob_control (p, 0x10, 0x10);
++}
++
++extern void parport_gsc_release_resources(struct parport *p);
++
++extern int parport_gsc_claim_resources(struct parport *p);
++
++extern void parport_gsc_init_state(struct pardevice *, struct parport_state *s);
++
++extern void parport_gsc_save_state(struct parport *p, struct parport_state *s);
++
++extern void parport_gsc_restore_state(struct parport *p, struct parport_state *s);
++
++extern void parport_gsc_inc_use_count(void);
++
++extern void parport_gsc_dec_use_count(void);
++
++extern struct parport *parport_gsc_probe_port(unsigned long base,
++ unsigned long base_hi,
++ int irq, int dma,
++ struct pci_dev *dev);
++
++#endif /* __DRIVERS_PARPORT_PARPORT_GSC_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/pci/quirks.c CVS2_6_11_PA2/drivers/pci/quirks.c
+--- LINUS_2_6_11/drivers/pci/quirks.c 2005-03-02 04:19:12.000000000 -0700
++++ CVS2_6_11_PA2/drivers/pci/quirks.c 2005-02-13 19:55:21.000000000 -0700
+@@ -536,7 +536,7 @@
+ return;
+ pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0);
+ }
+-DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy );
++DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
+
+ /*
+ * Following the PCI ordering rules is optional on the AMD762. I'm not
+@@ -654,7 +654,7 @@
+ printk(KERN_INFO "PCI: Ignoring BAR%d-%d of IDE controller %s\n",
+ first_bar, last_bar, pci_name(dev));
+ }
+-DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_ide_bases );
++DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_ide_bases);
+
+ /*
+ * Ensure C0 rev restreaming is off. This is normally done by
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/pcmcia/Kconfig CVS2_6_11_PA2/drivers/pcmcia/Kconfig
+--- LINUS_2_6_11/drivers/pcmcia/Kconfig 2005-03-02 04:19:13.000000000 -0700
++++ CVS2_6_11_PA2/drivers/pcmcia/Kconfig 2005-02-03 04:44:45.000000000 -0700
+@@ -166,7 +166,11 @@
+
+ config PCMCIA_PROBE
+ bool
+- default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X
++ default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC
++
++config PCMCIA_PROBE_MEM
++ bool
++ default y if !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_11/drivers/pcmcia/rsrc_nonstatic.c CVS2_6_11_PA2/drivers/pcmcia/rsrc_nonstatic.c
+--- LINUS_2_6_11/drivers/pcmcia/rsrc_nonstatic.c 2005-03-02 04:19:13.000000000 -0700
++++ CVS2_6_11_PA2/drivers/pcmcia/rsrc_nonstatic.c 2005-02-03 04:44:45.000000000 -0700
+@@ -41,7 +41,11 @@
+
+ #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
+
++#ifdef CONFIG_PCMCIA_PROBE_MEM
+ INT_MODULE_PARM(probe_mem, 1); /* memory probe? */
++#else
++INT_MODULE_PARM(probe_mem, 0); /* memory probe? */
++#endif
+ #ifdef CONFIG_PCMCIA_PROBE
+ INT_MODULE_PARM(probe_io, 1); /* IO port probe? */
+ INT_MODULE_PARM(mem_limit, 0x10000);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/53c700.c CVS2_6_11_PA2/drivers/scsi/53c700.c
+--- LINUS_2_6_11/drivers/scsi/53c700.c 2005-03-02 04:19:13.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/53c700.c 2005-02-24 07:48:28.000000000 -0700
+@@ -303,6 +303,7 @@
+ __u8 *memory;
+ __u32 *script;
+ struct Scsi_Host *host;
++ const char *chipname;
+ static int banner = 0;
+ int j;
+
+@@ -407,15 +408,15 @@
+ 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);
+
+- if (request_irq(irq, NCR_700_intr, SA_SHIRQ, dev->bus_id, host)) {
++ if (request_irq(irq, NCR_700_intr, SA_SHIRQ, chipname, host)) {
+ dev_printk(KERN_ERR, dev, "53c700: irq %lu request failed\n ",
+ irq);
+ goto out_put_host;
+@@ -824,6 +825,7 @@
+ switch(hostdata->msgin[2]) {
+ case A_SDTR_MSG:
+ if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
++ struct scsi_target *starget = SCp->device->sdev_target;
+ __u8 period = hostdata->msgin[3];
+ __u8 offset = hostdata->msgin[4];
+
+@@ -831,22 +833,15 @@
+ offset = 0;
+ period = 0;
+ }
++
++ spi_offset(starget) = offset;
++ spi_period(starget) = period;
+
+ if(NCR_700_is_flag_set(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION)) {
+- if(spi_offset(SCp->device->sdev_target) != 0)
+- printk(KERN_INFO "scsi%d: (%d:%d) Synchronous at offset %d, period %dns\n",
+- host->host_no, pun, lun,
+- offset, period*4);
+- else
+- printk(KERN_INFO "scsi%d: (%d:%d) Asynchronous\n",
+- host->host_no, pun, lun);
++ spi_display_xfer_agreement(starget);
+ NCR_700_clear_flag(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION);
+ }
+-
+- spi_offset(SCp->device->sdev_target) = offset;
+- spi_period(SCp->device->sdev_target) = period;
+
+-
+ NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
+ NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/53c700.h CVS2_6_11_PA2/drivers/scsi/53c700.h
+--- LINUS_2_6_11/drivers/scsi/53c700.h 2005-03-02 04:19:13.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/53c700.h 2005-02-14 11:04:39.000000000 -0700
+@@ -461,13 +461,13 @@
+ const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+ = (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+- return readb(host->base + (reg^bE));
++ return readb((void __iomem *)host->base + (reg^bE));
+ }
+
+ static inline __u32
+ NCR_700_mem_readl(struct Scsi_Host *host, __u32 reg)
+ {
+- __u32 value = __raw_readl(host->base + reg);
++ __u32 value = __raw_readl((void __iomem *)host->base + reg);
+ const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+ = (struct NCR_700_Host_Parameters *)host->hostdata[0];
+ #if 1
+@@ -485,7 +485,7 @@
+ const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+ = (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+- writeb(value, host->base + (reg^bE));
++ writeb(value, (void __iomem *)host->base + (reg^bE));
+ }
+
+ static inline void
+@@ -500,7 +500,7 @@
+ BUG();
+ #endif
+
+- __raw_writel(bS_to_host(value), host->base + reg);
++ __raw_writel(bS_to_host(value), (void __iomem *)host->base + reg);
+ }
+
+ static inline __u8
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/lasi700.c CVS2_6_11_PA2/drivers/scsi/lasi700.c
+--- LINUS_2_6_11/drivers/scsi/lasi700.c 2005-03-02 04:19:13.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/lasi700.c 2005-02-20 05:32:02.000000000 -0700
+@@ -112,7 +112,7 @@
+
+ hostdata->dev = &dev->dev;
+ dma_set_mask(&dev->dev, 0xffffffffUL);
+- hostdata->base = base;
++ hostdata->base = ioremap(base, 0x100);
+ hostdata->differential = 0;
+
+ if (dev->id.sversion == LASI_700_SVERSION) {
+@@ -138,6 +138,7 @@
+ return 0;
+
+ out_kfree:
++ iounmap(hostdata->base);
+ kfree(hostdata);
+ return -ENODEV;
+ }
+@@ -152,6 +153,7 @@
+ scsi_remove_host(host);
+ NCR_700_release(host);
+ free_irq(host->irq, host);
++ iounmap(hostdata->base);
+ kfree(hostdata);
+
+ return 0;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/ncr53c8xx.c CVS2_6_11_PA2/drivers/scsi/ncr53c8xx.c
+--- LINUS_2_6_11/drivers/scsi/ncr53c8xx.c 2005-03-02 04:19:13.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/ncr53c8xx.c 2005-02-24 07:48:28.000000000 -0700
+@@ -536,7 +536,7 @@
+ u_char usrwide;
+ u_char usrtags;
+ u_char usrflag;
+- struct scsi_target *starget;
++ struct scsi_device *sdev;
+ };
+
+ /*========================================================================
+@@ -1219,7 +1219,7 @@
+ static struct lcb * ncr_setup_lcb (struct ncb *np, struct scsi_device *sdev);
+ static void ncr_getclock (struct ncb *np, int mult);
+ static void ncr_selectclock (struct ncb *np, u_char scntl3);
+-static struct ccb *ncr_get_ccb (struct ncb *np, u_char tn, u_char ln);
++static struct ccb *ncr_get_ccb (struct ncb *np, struct scsi_cmnd *cmd);
+ static void ncr_chip_reset (struct ncb *np, int delay);
+ static void ncr_init (struct ncb *np, int reset, char * msg, u_long code);
+ static int ncr_int_sbmc (struct ncb *np);
+@@ -1238,8 +1238,6 @@
+ static void ncr_setsync (struct ncb *np, struct ccb *cp, u_char scntl3, u_char sxfer);
+ static void ncr_setup_tags (struct ncb *np, struct scsi_device *sdev);
+ static void ncr_setwide (struct ncb *np, struct ccb *cp, u_char wide, u_char ack);
+-static int ncr_show_msg (u_char * msg);
+-static void ncr_print_msg (struct ccb *cp, char *label, u_char *msg);
+ static int ncr_snooptest (struct ncb *np);
+ static void ncr_timeout (struct ncb *np);
+ static void ncr_wakeup (struct ncb *np, u_long code);
+@@ -2746,7 +2744,7 @@
+ for (i=0; i<MAX_START; i++) {
+ *p++ =SCR_CALL;
+ *p++ =PADDR (idle);
+- };
++ }
+
+ BUG_ON((u_long)p != (u_long)&scrh->tryloop + sizeof (scrh->tryloop));
+
+@@ -2771,7 +2769,7 @@
+ *p++ =PADDR (dispatch);
+ *p++ =SCR_MOVE_TBL ^ SCR_DATA_IN;
+ *p++ =offsetof (struct dsb, data[i]);
+- };
++ }
+
+ BUG_ON((u_long)p != (u_long)&scrh->hdata_in + sizeof (scrh->hdata_in));
+
+@@ -2781,7 +2779,7 @@
+ *p++ =PADDR (dispatch);
+ *p++ =SCR_MOVE_TBL ^ SCR_DATA_IN;
+ *p++ =offsetof (struct dsb, data[i]);
+- };
++ }
+
+ BUG_ON((u_long)p != (u_long)&scr->data_in + sizeof (scr->data_in));
+
+@@ -2791,7 +2789,7 @@
+ *p++ =PADDR (dispatch);
+ *p++ =SCR_MOVE_TBL ^ SCR_DATA_OUT;
+ *p++ =offsetof (struct dsb, data[i]);
+- };
++ }
+
+ BUG_ON((u_long)p != (u_long)&scrh->hdata_out + sizeof (scrh->hdata_out));
+
+@@ -2801,7 +2799,7 @@
+ *p++ =PADDR (dispatch);
+ *p++ =SCR_MOVE_TBL ^ SCR_DATA_OUT;
+ *p++ =offsetof (struct dsb, data[i]);
+- };
++ }
+
+ BUG_ON((u_long) p != (u_long)&scr->data_out + sizeof (scr->data_out));
+ }
+@@ -2842,7 +2840,7 @@
+ printk (KERN_ERR "%s: ERROR0 IN SCRIPT at %d.\n",
+ ncr_name(np), (int) (src-start-1));
+ mdelay(1000);
+- };
++ }
+
+ if (DEBUG_FLAGS & DEBUG_SCRIPT)
+ printk (KERN_DEBUG "%p: <%x>\n",
+@@ -2911,7 +2909,7 @@
+ default:
+ relocs = 0;
+ break;
+- };
++ }
+
+ if (relocs) {
+ while (relocs--) {
+@@ -2958,7 +2956,7 @@
+ } else
+ *dst++ = cpu_to_scr(*src++);
+
+- };
++ }
+ }
+
+ /*
+@@ -2969,25 +2967,25 @@
+ struct ncb *ncb;
+ };
+
+-/*
+-** Print something which allows to retrieve the controller type, unit,
+-** target, lun concerned by a kernel message.
+-*/
++#define PRINT_ADDR(cmd, arg...) dev_info(&cmd->device->sdev_gendev , ## arg)
+
+-static void PRINT_TARGET(struct ncb *np, int target)
++static void ncr_print_msg(struct ccb *cp, char *label, u_char *msg)
+ {
+- printk(KERN_INFO "%s-<%d,*>: ", ncr_name(np), target);
+-}
++ int i;
++ PRINT_ADDR(cp->cmd, "%s: ", label);
+
+-static void PRINT_LUN(struct ncb *np, int target, int lun)
+-{
+- printk(KERN_INFO "%s-<%d,%d>: ", ncr_name(np), target, lun);
+-}
++ 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]);
++ }
+
+-static void PRINT_ADDR(struct scsi_cmnd *cmd)
+-{
+- struct host_data *host_data = (struct host_data *) cmd->device->host->hostdata;
+- PRINT_LUN(host_data->ncb, cmd->device->id, cmd->device->lun);
++ printk(".\n");
+ }
+
+ /*==========================================================
+@@ -3367,36 +3365,25 @@
+ struct tcb *tp = &np->target[cp->target];
+ int msglen = 0;
+ int nego = 0;
+- struct scsi_target *starget = tp->starget;
+-
+- if (likely(starget)) {
+-
+- /*
+- ** negotiate wide transfers ?
+- */
+-
+- if (!tp->widedone) {
+- if (spi_support_wide(starget)) {
+- nego = NS_WIDE;
+- } else
+- tp->widedone=1;
++ struct scsi_target *starget = tp->sdev->sdev_target;
+
+- };
+-
+- /*
+- ** negotiate synchronous transfers?
+- */
++ /* negotiate wide transfers ? */
++ if (!tp->widedone) {
++ if (spi_support_wide(starget)) {
++ nego = NS_WIDE;
++ } else
++ tp->widedone=1;
++ }
+
+- if (!nego && !tp->period) {
+- if (spi_support_sync(starget)) {
+- nego = NS_SYNC;
+- } else {
+- tp->period =0xffff;
+- PRINT_TARGET(np, cp->target);
+- printk ("target did not report SYNC.\n");
+- };
+- };
+- };
++ /* negotiate synchronous transfers? */
++ if (!nego && !tp->period) {
++ if (spi_support_sync(starget)) {
++ nego = NS_SYNC;
++ } else {
++ tp->period =0xffff;
++ dev_info(&starget->dev, "target did not report SYNC.\n");
++ }
++ }
+
+ switch (nego) {
+ case NS_SYNC:
+@@ -3412,7 +3399,7 @@
+ msgptr[msglen++] = M_X_WIDE_REQ;
+ msgptr[msglen++] = tp->usrwide;
+ break;
+- };
++ }
+
+ cp->nego_status = nego;
+
+@@ -3421,8 +3408,8 @@
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+ ncr_print_msg(cp, nego == NS_WIDE ?
+ "wide msgout":"sync_msgout", msgptr);
+- };
+- };
++ }
++ }
+
+ return msglen;
+ }
+@@ -3440,9 +3427,9 @@
+ */
+ static int ncr_queue_command (struct ncb *np, struct scsi_cmnd *cmd)
+ {
+-/* struct scsi_device *device = cmd->device; */
+- struct tcb *tp = &np->target[cmd->device->id];
+- struct lcb *lp = tp->lp[cmd->device->lun];
++ struct scsi_device *sdev = cmd->device;
++ struct tcb *tp = &np->target[sdev->id];
++ struct lcb *lp = tp->lp[sdev->lun];
+ struct ccb *cp;
+
+ int segments;
+@@ -3457,9 +3444,9 @@
+ **
+ **---------------------------------------------
+ */
+- if ((cmd->device->id == np->myaddr ) ||
+- (cmd->device->id >= MAX_TARGET) ||
+- (cmd->device->lun >= MAX_LUN )) {
++ if ((sdev->id == np->myaddr ) ||
++ (sdev->id >= MAX_TARGET) ||
++ (sdev->lun >= MAX_LUN )) {
+ return(DID_BAD_TARGET);
+ }
+
+@@ -3479,8 +3466,7 @@
+ }
+
+ if (DEBUG_FLAGS & DEBUG_TINY) {
+- PRINT_ADDR(cmd);
+- printk ("CMD=%x ", cmd->cmnd[0]);
++ PRINT_ADDR(cmd, "CMD=%x ", cmd->cmnd[0]);
+ }
+
+ /*---------------------------------------------------
+@@ -3499,7 +3485,7 @@
+ np->settle_time = tlimit;
+ }
+
+- if (np->settle_time || !(cp=ncr_get_ccb (np, cmd->device->id, cmd->device->lun))) {
++ if (np->settle_time || !(cp=ncr_get_ccb (np, cmd))) {
+ insert_into_waiting_list(np, cmd);
+ return(DID_OK);
+ }
+@@ -3512,7 +3498,7 @@
+ **----------------------------------------------------
+ */
+
+- idmsg = M_IDENTIFY | cmd->device->lun;
++ idmsg = M_IDENTIFY | sdev->lun;
+
+ if (cp ->tag != NO_TAG ||
+ (cp != np->ccb && np->disc && !(tp->usrflag & UF_NODISC)))
+@@ -3533,8 +3519,8 @@
+ if (lp->tags_smap) {
+ order = M_ORDERED_TAG;
+ if ((DEBUG_FLAGS & DEBUG_TAGS)||bootverbose>2){
+- PRINT_ADDR(cmd);
+- printk("ordered tag forced.\n");
++ PRINT_ADDR(cmd,
++ "ordered tag forced.\n");
+ }
+ }
+ lp->tags_stime = ktime_get(3*HZ);
+@@ -3682,7 +3668,7 @@
+ /*
+ ** select
+ */
+- cp->phys.select.sel_id = cmd->device->id;
++ cp->phys.select.sel_id = sdev->id;
+ cp->phys.select.sel_scntl3 = tp->wval;
+ cp->phys.select.sel_sxfer = tp->sval;
+ /*
+@@ -3719,9 +3705,7 @@
+ **----------------------------------------------------
+ */
+
+- /*
+- ** activate this job.
+- */
++ /* activate this job. */
+ cp->magic = CCB_MAGIC;
+
+ /*
+@@ -3734,11 +3718,9 @@
+ else
+ ncr_put_start_queue(np, cp);
+
+- /*
+- ** Command is successfully queued.
+- */
++ /* Command is successfully queued. */
+
+- return(DID_OK);
++ return DID_OK;
+ }
+
+
+@@ -4203,8 +4185,7 @@
+ */
+
+ if (cp->parity_status > 1) {
+- PRINT_ADDR(cmd);
+- printk ("%d parity error(s).\n",cp->parity_status);
++ PRINT_ADDR(cmd, "%d parity error(s).\n",cp->parity_status);
+ }
+
+ /*
+@@ -4212,16 +4193,16 @@
+ */
+
+ if (cp->xerr_status != XE_OK) {
+- PRINT_ADDR(cmd);
+ switch (cp->xerr_status) {
+ case XE_EXTRA_DATA:
+- printk ("extraneous data discarded.\n");
++ PRINT_ADDR(cmd, "extraneous data discarded.\n");
+ break;
+ case XE_BAD_PHASE:
+- printk ("invalid scsi phase (4/5).\n");
++ PRINT_ADDR(cmd, "invalid scsi phase (4/5).\n");
+ break;
+ default:
+- printk ("extended error %d.\n", cp->xerr_status);
++ PRINT_ADDR(cmd, "extended error %d.\n",
++ cp->xerr_status);
+ break;
+ }
+ if (cp->host_status==HS_COMPLETE)
+@@ -4233,9 +4214,9 @@
+ */
+ if (DEBUG_FLAGS & (DEBUG_RESULT|DEBUG_TINY)) {
+ if (cp->host_status!=HS_COMPLETE || cp->scsi_status!=S_GOOD) {
+- PRINT_ADDR(cmd);
+- printk ("ERROR: cmd=%x host_status=%x scsi_status=%x\n",
+- cmd->cmnd[0], cp->host_status, cp->scsi_status);
++ PRINT_ADDR(cmd, "ERROR: cmd=%x host_status=%x "
++ "scsi_status=%x\n", cmd->cmnd[0],
++ cp->host_status, cp->scsi_status);
+ }
+ }
+
+@@ -4296,8 +4277,7 @@
+ if (DEBUG_FLAGS & (DEBUG_RESULT|DEBUG_TINY)) {
+ u_char * p = (u_char*) & cmd->sense_buffer;
+ int i;
+- PRINT_ADDR(cmd);
+- printk ("sense data:");
++ PRINT_ADDR(cmd, "sense data:");
+ for (i=0; i<14; i++) printk (" %x", *p++);
+ printk (".\n");
+ }
+@@ -4344,8 +4324,7 @@
+ /*
+ ** Other protocol messes
+ */
+- PRINT_ADDR(cmd);
+- printk ("COMMAND FAILED (%x %x) @%p.\n",
++ PRINT_ADDR(cmd, "COMMAND FAILED (%x %x) @%p.\n",
+ cp->host_status, cp->scsi_status, cp);
+
+ cmd->result = ScsiResult(DID_ERROR, cp->scsi_status);
+@@ -4358,8 +4337,7 @@
+ if (tp->usrflag & UF_TRACE) {
+ u_char * p;
+ int i;
+- PRINT_ADDR(cmd);
+- printk (" CMD:");
++ PRINT_ADDR(cmd, " CMD:");
+ p = (u_char*) &cmd->cmnd[0];
+ for (i=0; i<cmd->cmd_len; i++) printk (" %x", *p++);
+
+@@ -4667,7 +4645,7 @@
+ }
+ else
+ tp->usrsync = 255;
+- };
++ }
+
+ if (tp->usrwide > np->maxwide)
+ tp->usrwide = np->maxwide;
+@@ -4849,7 +4827,7 @@
+ #endif
+ cp->phys.select.sel_scntl3 = tp->wval;
+ cp->phys.select.sel_sxfer = tp->sval;
+- };
++ }
+ }
+
+ /*==========================================================
+@@ -4885,40 +4863,19 @@
+ else
+ tp->period = 0xffff;
+
+- /*
+- ** Stop there if sync parameters are unchanged
+- */
+- if (tp->sval == sxfer && tp->wval == scntl3) return;
++ /* Stop there if sync parameters are unchanged */
++ if (tp->sval == sxfer && tp->wval == scntl3)
++ return;
+ tp->sval = sxfer;
+ tp->wval = scntl3;
+
+- /*
+- ** Bells and whistles ;-)
+- */
+- PRINT_TARGET(np, target);
+ if (sxfer & 0x01f) {
+- unsigned f10 = 100000 << (tp->widedone ? tp->widedone -1 : 0);
+- unsigned mb10 = (f10 + tp->period/2) / tp->period;
+- char *scsi;
+-
+- /*
+- ** Disable extended Sreq/Sack filtering
+- */
+- if (tp->period <= 2000) OUTOFFB (nc_stest2, EXT);
+-
+- /*
+- ** Bells and whistles ;-)
+- */
+- if (tp->period < 500) scsi = "FAST-40";
+- else if (tp->period < 1000) scsi = "FAST-20";
+- else if (tp->period < 2000) scsi = "FAST-10";
+- else scsi = "FAST-5";
+-
+- printk ("%s %sSCSI %d.%d MB/s (%d ns, offset %d)\n", scsi,
+- tp->widedone > 1 ? "WIDE " : "",
+- mb10 / 10, mb10 % 10, tp->period / 10, sxfer & 0x1f);
+- } else
+- printk ("%sasynchronous.\n", tp->widedone > 1 ? "wide " : "");
++ /* Disable extended Sreq/Sack filtering */
++ if (tp->period <= 2000)
++ OUTOFFB(nc_stest2, EXT);
++ }
++
++ spi_display_xfer_agreement(tp->sdev->sdev_target);
+
+ /*
+ ** set actual value and sync_status
+@@ -4964,11 +4921,8 @@
+ ** Bells and whistles ;-)
+ */
+ if (bootverbose >= 2) {
+- PRINT_TARGET(np, target);
+- if (scntl3 & EWS)
+- printk ("WIDE SCSI (16 bit) enabled.\n");
+- else
+- printk ("WIDE SCSI disabled.\n");
++ dev_info(&cmd->device->sdev_target->dev, "WIDE SCSI %sabled.\n",
++ (scntl3 & EWS) ? "en" : "dis");
+ }
+
+ /*
+@@ -5023,7 +4977,7 @@
+ reqtags = lp->numtags;
+ } else {
+ reqtags = 1;
+- };
++ }
+
+ /*
+ ** Update max number of tags
+@@ -5063,12 +5017,13 @@
+ ** Announce change to user.
+ */
+ if (bootverbose) {
+- PRINT_LUN(np, tn, ln);
+ if (lp->usetags) {
+- printk("tagged command queue depth set to %d\n", reqtags);
+- }
+- else {
+- printk("tagged command queueing disabled\n");
++ dev_info(&sdev->sdev_gendev,
++ "tagged command queue depth set to %d\n",
++ reqtags);
++ } else {
++ dev_info(&sdev->sdev_gendev,
++ "tagged command queueing disabled\n");
+ }
+ }
+ }
+@@ -5274,7 +5229,7 @@
+ istat = INB (nc_istat);
+ if (DEBUG_FLAGS & DEBUG_TINY) printk ("F ");
+ ncr_wakeup_done (np);
+- };
++ }
+
+ if (!(istat & (SIP|DIP)))
+ return;
+@@ -5335,7 +5290,7 @@
+ }
+ OUTONB_STD ();
+ return;
+- };
++ }
+
+ /*========================================================
+ ** Now, interrupts that need some fixing up.
+@@ -5355,7 +5310,7 @@
+ if (sist & RST) {
+ ncr_init (np, 1, bootverbose ? "scsi reset" : NULL, HS_RESET);
+ return;
+- };
++ }
+
+ if ((sist & STO) &&
+ !(dstat & (MDPE|BF|ABRT))) {
+@@ -5366,7 +5321,7 @@
+
+ ncr_int_sto (np);
+ return;
+- };
++ }
+
+ /*=========================================================
+ ** Now, interrupts we are not able to recover cleanly.
+@@ -5387,7 +5342,7 @@
+ ((char*)&np->regdump)[i] = INB_OFF(i);
+ np->regdump.nc_dstat = dstat;
+ np->regdump.nc_sist = sist;
+- };
++ }
+
+ ncr_log_hard_error(np, sist, dstat);
+
+@@ -5399,20 +5354,20 @@
+ (dstat & (MDPE|BF|ABRT|IID))) {
+ ncr_start_reset(np);
+ return;
+- };
++ }
+
+ if (sist & HTH) {
+ printk ("%s: handshake timeout\n", ncr_name(np));
+ ncr_start_reset(np);
+ return;
+- };
++ }
+
+ if (sist & UDC) {
+ printk ("%s: unexpected disconnect\n", ncr_name(np));
+ OUTB (HS_PRT, HS_UNEXPECTED);
+ OUTL_DSP (NCB_SCRIPT_PHYS (np, cleanup));
+ return;
+- };
++ }
+
+ /*=========================================================
+ ** We just miss the cause of the interrupt. :(
+@@ -5456,7 +5411,7 @@
+ if (cp) {
+ cp-> host_status = HS_SEL_TIMEOUT;
+ ncr_complete (np, cp);
+- };
++ }
+
+ /*
+ ** repair start queue and jump to start point.
+@@ -5647,7 +5602,7 @@
+ ss2 = INB (nc_sstat2);
+ if (ss2 & OLF1) rest++;
+ if (ss2 & ORF1) rest++;
+- };
++ }
+
+ if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_PHASE))
+ printk ("P%x%x RL=%d D=%d SS0=%x ", cmd&7, sbcl&7,
+@@ -5716,7 +5671,7 @@
+ cp, np->header.cp,
+ (unsigned)dsp,
+ (unsigned)nxtdsp, vdsp, cmd);
+- };
++ }
+
+ /*
+ ** cp=0 means that the DSA does not point to a valid control
+@@ -5744,7 +5699,7 @@
+ } else {
+ tblp = (u32 *) 0;
+ olen = scr_to_cpu(vdsp[0]) & 0xffffff;
+- };
++ }
+
+ if (DEBUG_FLAGS & DEBUG_PHASE) {
+ printk ("OCMD=%x\nTBLP=%p OLEN=%x OADR=%x\n",
+@@ -5752,16 +5707,15 @@
+ tblp,
+ (unsigned) olen,
+ (unsigned) oadr);
+- };
++ }
+
+ /*
+ ** check cmd against assumed interrupted script command.
+ */
+
+ if (cmd != (scr_to_cpu(vdsp[0]) >> 24)) {
+- PRINT_ADDR(cp->cmd);
+- printk ("internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n",
+- (unsigned)cmd, (unsigned)scr_to_cpu(vdsp[0]) >> 24);
++ PRINT_ADDR(cp->cmd, "internal error: cmd=%02x != %02x=(vdsp[0] "
++ ">> 24)\n", cmd, scr_to_cpu(vdsp[0]) >> 24);
+
+ goto reset_all;
+ }
+@@ -5783,12 +5737,11 @@
+ */
+
+ if (cmd & 0x06) {
+- PRINT_ADDR(cp->cmd);
+- printk ("phase change %x-%x %d@%08x resid=%d.\n",
++ PRINT_ADDR(cp->cmd, "phase change %x-%x %d@%08x resid=%d.\n",
+ cmd&7, sbcl&7, (unsigned)olen,
+ (unsigned)oadr, (unsigned)rest);
+ goto unexpected_phase;
+- };
++ }
+
+ /*
+ ** choose the correct patch area.
+@@ -5812,8 +5765,7 @@
+ newcmd[3] = cpu_to_scr(nxtdsp);
+
+ if (DEBUG_FLAGS & DEBUG_PHASE) {
+- PRINT_ADDR(cp->cmd);
+- printk ("newcmd[%d] %x %x %x %x.\n",
++ PRINT_ADDR(cp->cmd, "newcmd[%d] %x %x %x %x.\n",
+ (int) (newcmd - cp->patch),
+ (unsigned)scr_to_cpu(newcmd[0]),
+ (unsigned)scr_to_cpu(newcmd[1]),
+@@ -5939,9 +5891,8 @@
+ if (!lp)
+ goto out;
+ if (bootverbose >= 1) {
+- PRINT_ADDR(cmd);
+- printk ("QUEUE FULL! %d busy, %d disconnected CCBs\n",
+- busy_cnt, disc_cnt);
++ PRINT_ADDR(cmd, "QUEUE FULL! %d busy, %d disconnected "
++ "CCBs\n", busy_cnt, disc_cnt);
+ }
+ if (disc_cnt < lp->numtags) {
+ lp->numtags = disc_cnt > 2 ? disc_cnt : 2;
+@@ -5978,7 +5929,7 @@
+ **
+ ** identify message
+ */
+- cp->scsi_smsg2[0] = M_IDENTIFY | cmd->device->lun;
++ cp->scsi_smsg2[0] = IDENTIFY(0, cmd->device->lun);
+ cp->phys.smsg.addr = cpu_to_scr(CCB_PHYS (cp, scsi_smsg2));
+ cp->phys.smsg.size = cpu_to_scr(1);
+
+@@ -6048,34 +5999,6 @@
+ **==========================================================
+ */
+
+-static int ncr_show_msg (u_char * msg)
+-{
+- u_char i;
+- printk ("%x",*msg);
+- if (*msg==M_EXTENDED) {
+- for (i=1;i<8;i++) {
+- if (i-1>msg[1]) break;
+- printk ("-%x",msg[i]);
+- };
+- return (i+1);
+- } else if ((*msg & 0xf0) == 0x20) {
+- printk ("-%x",msg[1]);
+- return (2);
+- };
+- return (1);
+-}
+-
+-static void ncr_print_msg ( struct ccb *cp, char *label, u_char *msg)
+-{
+- if (cp)
+- PRINT_ADDR(cp->cmd);
+- if (label)
+- printk("%s: ", label);
+-
+- (void) ncr_show_msg (msg);
+- printk(".\n");
+-}
+-
+ void ncr_int_sir (struct ncb *np)
+ {
+ u_char scntl3;
+@@ -6085,7 +6008,7 @@
+ u_long dsa = INL (nc_dsa);
+ u_char target = INB (nc_sdid) & 0x0f;
+ struct tcb *tp = &np->target[target];
+- struct scsi_target *starget = tp->starget;
++ struct scsi_target *starget = tp->sdev->sdev_target;
+
+ if (DEBUG_FLAGS & DEBUG_TINY) printk ("I#%d", num);
+
+@@ -6230,10 +6153,9 @@
+ */
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+- PRINT_ADDR(cp->cmd);
+- printk ("negotiation failed sir=%x status=%x.\n",
+- num, cp->nego_status);
+- };
++ PRINT_ADDR(cp->cmd, "negotiation failed sir=%x "
++ "status=%x.\n", num, cp->nego_status);
++ }
+
+ /*
+ ** any error in negotiation:
+@@ -6242,37 +6164,26 @@
+ switch (cp->nego_status) {
+
+ case NS_SYNC:
+- ncr_setsync (np, cp, 0, 0xe0);
+ spi_period(starget) = 0;
+ spi_offset(starget) = 0;
++ ncr_setsync (np, cp, 0, 0xe0);
+ break;
+
+ case NS_WIDE:
+- ncr_setwide (np, cp, 0, 0);
+ spi_width(starget) = 0;
++ ncr_setwide (np, cp, 0, 0);
+ break;
+
+- };
++ }
+ np->msgin [0] = M_NOOP;
+ np->msgout[0] = M_NOOP;
+ cp->nego_status = 0;
+ break;
+
+ case SIR_NEGO_SYNC:
+- /*
+- ** Synchronous request message received.
+- */
+-
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+- PRINT_ADDR(cp->cmd);
+- printk ("sync msgin: ");
+- (void) ncr_show_msg (np->msgin);
+- printk (".\n");
+- };
+-
+- /*
+- ** get requested values.
+- */
++ ncr_print_msg(cp, "sync msgin", np->msgin);
++ }
+
+ chg = 0;
+ per = np->msgin[3];
+@@ -6284,8 +6195,8 @@
+ ** it CAN transfer synch.
+ */
+
+- if (ofs && tp->starget)
+- spi_support_sync(tp->starget) = 1;
++ if (ofs && starget)
++ spi_support_sync(starget) = 1;
+
+ /*
+ ** check values against driver limits.
+@@ -6318,9 +6229,8 @@
+ }
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+- PRINT_ADDR(cp->cmd);
+- printk ("sync: per=%d scntl3=0x%x ofs=%d fak=%d chg=%d.\n",
+- per, scntl3, ofs, fak, chg);
++ PRINT_ADDR(cp->cmd, "sync: per=%d scntl3=0x%x ofs=%d "
++ "fak=%d chg=%d.\n", per, scntl3, ofs, fak, chg);
+ }
+
+ if (INB (HS_PRT) == HS_NEGOTIATE) {
+@@ -6328,43 +6238,37 @@
+ switch (cp->nego_status) {
+
+ case NS_SYNC:
+- /*
+- ** This was an answer message
+- */
++ /* This was an answer message */
+ if (chg) {
+- /*
+- ** Answer wasn't acceptable.
+- */
+- ncr_setsync (np, cp, 0, 0xe0);
++ /* Answer wasn't acceptable. */
+ spi_period(starget) = 0;
+ spi_offset(starget) = 0;
+- OUTL_DSP (NCB_SCRIPT_PHYS (np, msg_bad));
++ ncr_setsync(np, cp, 0, 0xe0);
++ OUTL_DSP(NCB_SCRIPT_PHYS (np, msg_bad));
+ } else {
+- /*
+- ** Answer is ok.
+- */
+- ncr_setsync (np, cp, scntl3, (fak<<5)|ofs);
++ /* Answer is ok. */
+ spi_period(starget) = per;
+ spi_offset(starget) = ofs;
+- OUTL_DSP (NCB_SCRIPT_PHYS (np, clrack));
+- };
++ ncr_setsync(np, cp, scntl3, (fak<<5)|ofs);
++ OUTL_DSP(NCB_SCRIPT_PHYS (np, clrack));
++ }
+ return;
+
+ case NS_WIDE:
+- ncr_setwide (np, cp, 0, 0);
+ spi_width(starget) = 0;
++ ncr_setwide(np, cp, 0, 0);
+ break;
+- };
+- };
++ }
++ }
+
+ /*
+ ** It was a request. Set value and
+ ** prepare an answer message
+ */
+
+- ncr_setsync (np, cp, scntl3, (fak<<5)|ofs);
+ spi_period(starget) = per;
+ spi_offset(starget) = ofs;
++ ncr_setsync(np, cp, scntl3, (fak<<5)|ofs);
+
+ np->msgout[0] = M_EXTENDED;
+ np->msgout[1] = 3;
+@@ -6375,10 +6279,7 @@
+ cp->nego_status = NS_SYNC;
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+- PRINT_ADDR(cp->cmd);
+- printk ("sync msgout: ");
+- (void) ncr_show_msg (np->msgout);
+- printk (".\n");
++ ncr_print_msg(cp, "sync msgout", np->msgout);
+ }
+
+ if (!ofs) {
+@@ -6394,11 +6295,8 @@
+ ** Wide request message received.
+ */
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+- PRINT_ADDR(cp->cmd);
+- printk ("wide msgin: ");
+- (void) ncr_show_msg (np->msgin);
+- printk (".\n");
+- };
++ ncr_print_msg(cp, "wide msgin", np->msgin);
++ }
+
+ /*
+ ** get requested values.
+@@ -6412,8 +6310,8 @@
+ ** it CAN transfer wide.
+ */
+
+- if (wide && tp->starget)
+- spi_support_wide(tp->starget) = 1;
++ if (wide && starget)
++ spi_support_wide(starget) = 1;
+
+ /*
+ ** check values against driver limits.
+@@ -6423,8 +6321,8 @@
+ {chg = 1; wide = tp->usrwide;}
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+- PRINT_ADDR(cp->cmd);
+- printk ("wide: wide=%d chg=%d.\n", wide, chg);
++ PRINT_ADDR(cp->cmd, "wide: wide=%d chg=%d.\n", wide,
++ chg);
+ }
+
+ if (INB (HS_PRT) == HS_NEGOTIATE) {
+@@ -6436,37 +6334,33 @@
+ ** This was an answer message
+ */
+ if (chg) {
+- /*
+- ** Answer wasn't acceptable.
+- */
+- ncr_setwide (np, cp, 0, 1);
++ /* Answer wasn't acceptable. */
+ spi_width(starget) = 0;
++ ncr_setwide(np, cp, 0, 1);
+ OUTL_DSP (NCB_SCRIPT_PHYS (np, msg_bad));
+ } else {
+- /*
+- ** Answer is ok.
+- */
+- ncr_setwide (np, cp, wide, 1);
++ /* Answer is ok. */
+ spi_width(starget) = wide;
++ ncr_setwide(np, cp, wide, 1);
+ OUTL_DSP (NCB_SCRIPT_PHYS (np, clrack));
+- };
++ }
+ return;
+
+ case NS_SYNC:
+- ncr_setsync (np, cp, 0, 0xe0);
+ spi_period(starget) = 0;
+ spi_offset(starget) = 0;
++ ncr_setsync(np, cp, 0, 0xe0);
+ break;
+- };
+- };
++ }
++ }
+
+ /*
+ ** It was a request, set value and
+ ** prepare an answer message
+ */
+
+- ncr_setwide (np, cp, wide, 1);
+ spi_width(starget) = wide;
++ ncr_setwide(np, cp, wide, 1);
+
+ np->msgout[0] = M_EXTENDED;
+ np->msgout[1] = 2;
+@@ -6478,10 +6372,7 @@
+ cp->nego_status = NS_WIDE;
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+- PRINT_ADDR(cp->cmd);
+- printk ("wide msgout: ");
+- (void) ncr_show_msg (np->msgin);
+- printk (".\n");
++ ncr_print_msg(cp, "wide msgout", np->msgin);
+ }
+ break;
+
+@@ -6500,8 +6391,7 @@
+ **-----------------------------------------------
+ */
+
+- PRINT_ADDR(cp->cmd);
+- printk ("M_REJECT received (%x:%x).\n",
++ PRINT_ADDR(cp->cmd, "M_REJECT received (%x:%x).\n",
+ (unsigned)scr_to_cpu(np->lastmsg), np->msgout[0]);
+ break;
+
+@@ -6513,10 +6403,7 @@
+ **-----------------------------------------------
+ */
+
+- PRINT_ADDR(cp->cmd);
+- printk ("M_REJECT sent for ");
+- (void) ncr_show_msg (np->msgin);
+- printk (".\n");
++ ncr_print_msg(cp, "M_REJECT sent for", np->msgin);
+ break;
+
+ /*--------------------------------------------------------------------
+@@ -6535,8 +6422,8 @@
+ **-----------------------------------------------
+ */
+
+- PRINT_ADDR(cp->cmd);
+- printk ("M_IGN_RESIDUE received, but not yet implemented.\n");
++ PRINT_ADDR(cp->cmd, "M_IGN_RESIDUE received, but not yet "
++ "implemented.\n");
+ break;
+ #if 0
+ case SIR_MISSING_SAVE:
+@@ -6548,15 +6435,14 @@
+ **-----------------------------------------------
+ */
+
+- PRINT_ADDR(cp->cmd);
+- printk ("M_DISCONNECT received, but datapointer not saved: "
+- "data=%x save=%x goal=%x.\n",
++ PRINT_ADDR(cp->cmd, "M_DISCONNECT received, but datapointer "
++ "not saved: data=%x save=%x goal=%x.\n",
+ (unsigned) INL (nc_temp),
+ (unsigned) scr_to_cpu(np->header.savep),
+ (unsigned) scr_to_cpu(np->header.goalp));
+ break;
+ #endif
+- };
++ }
+
+ out:
+ OUTONB_STD ();
+@@ -6571,8 +6457,10 @@
+ **==========================================================
+ */
+
+-static struct ccb *ncr_get_ccb (struct ncb *np, u_char tn, u_char ln)
++static struct ccb *ncr_get_ccb(struct ncb *np, struct scsi_cmnd *cmd)
+ {
++ u_char tn = cmd->device->id;
++ u_char ln = cmd->device->lun;
+ struct tcb *tp = &np->target[tn];
+ struct lcb *lp = tp->lp[ln];
+ u_char tag = NO_TAG;
+@@ -6602,8 +6490,8 @@
+ if (qp) {
+ cp = list_entry(qp, struct ccb, link_ccbq);
+ if (cp->magic) {
+- PRINT_LUN(np, tn, ln);
+- printk ("ccb free list corrupted (@%p)\n", cp);
++ PRINT_ADDR(cmd, "ccb free list corrupted "
++ "(@%p)\n", cp);
+ cp = NULL;
+ } else {
+ list_add_tail(qp, &lp->wait_ccbq);
+@@ -6637,7 +6525,7 @@
+ if (flags & SCSI_NOSLEEP) break;
+ if (tsleep ((caddr_t)cp, PRIBIO|PCATCH, "ncr", 0))
+ break;
+- };
++ }
+ #endif
+
+ if (cp->magic)
+@@ -6665,8 +6553,7 @@
+ cp->lun = ln;
+
+ if (DEBUG_FLAGS & DEBUG_TAGS) {
+- PRINT_LUN(np, tn, ln);
+- printk ("ccb @%p using tag %d.\n", cp, tag);
++ PRINT_ADDR(cmd, "ccb @%p using tag %d.\n", cp, tag);
+ }
+
+ return cp;
+@@ -6687,8 +6574,7 @@
+ struct lcb *lp = tp->lp[cp->lun];
+
+ if (DEBUG_FLAGS & DEBUG_TAGS) {
+- PRINT_LUN(np, cp->target, cp->lun);
+- printk ("ccb @%p freeing tag %d.\n", cp, cp->tag);
++ PRINT_ADDR(cp->cmd, "ccb @%p freeing tag %d.\n", cp, cp->tag);
+ }
+
+ /*
+@@ -7014,17 +6900,13 @@
+ unsigned char tn = sdev->id, ln = sdev->lun;
+ struct tcb *tp = &np->target[tn];
+ struct lcb *lp = tp->lp[ln];
+- struct scsi_target *starget = tp->starget;
++ struct scsi_target *starget = sdev->sdev_target;
+
+- /*
+- ** If no lcb, try to allocate it.
+- */
++ /* If no lcb, try to allocate it. */
+ if (!lp && !(lp = ncr_alloc_lcb(np, tn, ln)))
+ goto fail;
+
+- /*
+- ** Prepare negotiation
+- */
++ /* Prepare negotiation */
+ if (spi_support_wide(starget) || spi_support_sync(starget))
+ ncr_negotiate(np, tp);
+
+@@ -7170,7 +7052,7 @@
+ printk ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n",
+ (unsigned) data);
+ return (0x10);
+- };
++ }
+ return (0);
+ }
+
+@@ -7223,7 +7105,7 @@
+ if (i>=NCR_SNOOP_TIMEOUT) {
+ printk ("CACHE TEST FAILED: timeout.\n");
+ return (0x20);
+- };
++ }
+ /*
+ ** Check termination position.
+ */
+@@ -7233,7 +7115,7 @@
+ (u_long) NCB_SCRIPTH_PHYS (np, snooptest), (u_long) pc,
+ (u_long) NCB_SCRIPTH_PHYS (np, snoopend) +8);
+ return (0x40);
+- };
++ }
+ /*
+ ** Show results.
+ */
+@@ -7241,17 +7123,17 @@
+ printk ("CACHE TEST FAILED: host wrote %d, ncr read %d.\n",
+ (int) host_wr, (int) ncr_rd);
+ err |= 1;
+- };
++ }
+ if (host_rd != ncr_wr) {
+ printk ("CACHE TEST FAILED: ncr wrote %d, host read %d.\n",
+ (int) ncr_wr, (int) host_rd);
+ err |= 2;
+- };
++ }
+ if (ncr_bk != ncr_wr) {
+ printk ("CACHE TEST FAILED: ncr wrote %d, read back %d.\n",
+ (int) ncr_wr, (int) ncr_bk);
+ err |= 4;
+- };
++ }
+ return (err);
+ }
+
+@@ -7424,6 +7306,16 @@
+
+ /*===================== LINUX ENTRY POINTS SECTION ==========================*/
+
++static int ncr53c8xx_slave_alloc(struct scsi_device *device)
++{
++ struct Scsi_Host *host = device->host;
++ struct ncb *np = ((struct host_data *) host->hostdata)->ncb;
++ struct tcb *tp = &np->target[device->id];
++ tp->sdev = device;
++
++ return 0;
++}
++
+ static int ncr53c8xx_slave_configure(struct scsi_device *device)
+ {
+ struct Scsi_Host *host = device->host;
+@@ -7432,8 +7324,6 @@
+ struct lcb *lp = tp->lp[device->lun];
+ int numtags, depth_to_use;
+
+- tp->starget = device->sdev_target;
+-
+ ncr_setup_lcb(np, device);
+
+ /*
+@@ -7778,6 +7668,7 @@
+
+ tpnt->queuecommand = ncr53c8xx_queue_command;
+ tpnt->slave_configure = ncr53c8xx_slave_configure;
++ tpnt->slave_alloc = ncr53c8xx_slave_alloc;
+ tpnt->eh_bus_reset_handler = ncr53c8xx_bus_reset;
+ tpnt->can_queue = SCSI_NCR_CAN_QUEUE;
+ tpnt->this_id = 7;
+@@ -7925,7 +7816,7 @@
+ if (ncr_snooptest(np)) {
+ printk(KERN_ERR "CACHE INCORRECTLY CONFIGURED.\n");
+ goto attach_error;
+- };
++ }
+
+ /* Install the interrupt handler. */
+ np->irq = device->slot.irq;
+@@ -8057,6 +7948,25 @@
+ ncr_negotiate(np, tp);
+ }
+
++static void ncr53c8xx_get_signalling(struct Scsi_Host *shost)
++{
++ struct ncb *np = ((struct host_data *)shost->hostdata)->ncb;
++ enum spi_signal_type type;
++
++ switch (np->scsi_mode) {
++ case SMODE_SE:
++ type = SPI_SIGNAL_SE;
++ break;
++ case SMODE_HVD:
++ type = SPI_SIGNAL_HVD;
++ break;
++ default:
++ type = SPI_SIGNAL_UNKNOWN;
++ break;
++ }
++ spi_signalling(shost) = type;
++}
++
+ static struct spi_function_template ncr53c8xx_transport_functions = {
+ .set_period = ncr53c8xx_set_period,
+ .show_period = 1,
+@@ -8064,6 +7974,7 @@
+ .show_offset = 1,
+ .set_width = ncr53c8xx_set_width,
+ .show_width = 1,
++ .get_signalling = ncr53c8xx_get_signalling,
+ };
+
+ int __init ncr53c8xx_init(void)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/scsi_transport_spi.c CVS2_6_11_PA2/drivers/scsi/scsi_transport_spi.c
+--- LINUS_2_6_11/drivers/scsi/scsi_transport_spi.c 2005-03-02 04:19:13.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/scsi_transport_spi.c 2005-03-06 10:11:18.000000000 -0700
+@@ -18,15 +18,11 @@
+ * 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/module.h>
++#include <linux/ctype.h>
+ #include <linux/init.h>
+-#include <linux/smp_lock.h>
+-#include <linux/list.h>
+-#include <linux/spinlock.h>
+-#include <linux/mm.h>
++#include <linux/module.h>
+ #include <linux/workqueue.h>
+-#include <asm/scatterlist.h>
+-#include <asm/io.h>
++#include <asm/semaphore.h>
+ #include <scsi/scsi.h>
+ #include "scsi_priv.h"
+ #include <scsi/scsi_device.h>
+@@ -63,27 +59,47 @@
+
+ #define to_spi_internal(tmpl) container_of(tmpl, struct spi_internal, t)
+
+-static const char *const ppr_to_ns[] = {
++static const int ppr_to_ps[] = {
+ /* The PPR values 0-6 are reserved, fill them in when
+ * the committee defines them */
+- NULL, /* 0x00 */
+- NULL, /* 0x01 */
+- NULL, /* 0x02 */
+- NULL, /* 0x03 */
+- NULL, /* 0x04 */
+- NULL, /* 0x05 */
+- NULL, /* 0x06 */
+- "3.125", /* 0x07 */
+- "6.25", /* 0x08 */
+- "12.5", /* 0x09 */
+- "25", /* 0x0a */
+- "30.3", /* 0x0b */
+- "50", /* 0x0c */
++ -1, /* 0x00 */
++ -1, /* 0x01 */
++ -1, /* 0x02 */
++ -1, /* 0x03 */
++ -1, /* 0x04 */
++ -1, /* 0x05 */
++ -1, /* 0x06 */
++ 3125, /* 0x07 */
++ 6250, /* 0x08 */
++ 12500, /* 0x09 */
++ 25000, /* 0x0a */
++ 30300, /* 0x0b */
++ 50000, /* 0x0c */
+ };
+ /* The PPR values at which you calculate the period in ns by multiplying
+ * by 4 */
+ #define SPI_STATIC_PPR 0x0c
+
++static int sprint_frac(char *dest, int value, int denom)
++{
++ int frac = value % denom;
++ int result = sprintf(dest, "%d", value / denom);
++
++ if (frac == 0)
++ return result;
++ dest[result++] = '.';
++
++ do {
++ denom /= 10;
++ sprintf(dest + result, "%d", frac / denom);
++ result++;
++ frac %= denom;
++ } while (frac);
++
++ dest[result++] = '\0';
++ return result;
++}
++
+ static struct {
+ enum spi_signal_type value;
+ char *name;
+@@ -261,7 +277,7 @@
+ struct scsi_target *starget = transport_class_to_starget(cdev);
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct spi_transport_attrs *tp;
+- const char *str;
++ int len, picosec;
+ struct spi_internal *i = to_spi_internal(shost->transportt);
+
+ tp = (struct spi_transport_attrs *)&starget->starget_data;
+@@ -269,22 +285,20 @@
+ if (i->f->get_period)
+ i->f->get_period(starget);
+
+- switch(tp->period) {
+-
+- case 0x07 ... SPI_STATIC_PPR:
+- str = ppr_to_ns[tp->period];
+- if(!str)
+- str = "reserved";
+- break;
+-
+-
+- case (SPI_STATIC_PPR+1) ... 0xff:
+- return sprintf(buf, "%d\n", tp->period * 4);
+-
+- default:
+- str = "unknown";
++ if (tp->period < 0 || tp->period > 0xff) {
++ picosec = -1;
++ } else if (tp->period <= SPI_STATIC_PPR) {
++ picosec = ppr_to_ps[tp->period];
++ } else {
++ picosec = tp->period * 4000;
+ }
+- return sprintf(buf, "%s\n", str);
++
++ if (picosec == -1)
++ return sprintf(buf, "reserved");
++ len = sprint_frac(buf, picosec, 1000);
++ buf[len++] = '\n';
++ buf[len] = '\0';
++ return len;
+ }
+
+ static ssize_t
+@@ -294,34 +308,30 @@
+ struct scsi_target *starget = transport_class_to_starget(cdev);
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct spi_internal *i = to_spi_internal(shost->transportt);
+- int j, period = -1;
++ int j, picosec, period = -1;
++ char *endp;
+
+- for (j = 0; j < SPI_STATIC_PPR; j++) {
+- int len;
+-
+- if(ppr_to_ns[j] == NULL)
+- continue;
+-
+- len = strlen(ppr_to_ns[j]);
+-
+- if(strncmp(ppr_to_ns[j], buf, len) != 0)
+- continue;
++ picosec = simple_strtoul(buf, &endp, 10) * 1000;
++ if (*endp == '.') {
++ int mult = 100;
++ do {
++ endp++;
++ if (!isdigit(*endp))
++ break;
++ picosec += (*endp - '0') * mult;
++ mult /= 10;
++ } while (mult > 0);
++ }
+
+- if(buf[len] != '\n')
++ for (j = 0; j <= SPI_STATIC_PPR; j++) {
++ if (ppr_to_ps[j] < picosec)
+ continue;
+-
+ period = j;
+ break;
+ }
+
+- if (period == -1) {
+- int val = simple_strtoul(buf, NULL, 0);
+-
+-
+- /* Should probably check limits here, but this
+- * gets reasonably close to OK for most things */
+- period = val/4;
+- }
++ if (period == -1)
++ period = picosec / 4000;
+
+ if (period > 0xff)
+ period = 0xff;
+@@ -330,7 +340,7 @@
+
+ return count;
+ }
+-
++
+ static CLASS_DEVICE_ATTR(period, S_IRUGO | S_IWUSR,
+ show_spi_transport_period,
+ store_spi_transport_period);
+@@ -795,6 +805,61 @@
+ }
+ EXPORT_SYMBOL(spi_schedule_dv_device);
+
++/**
++ * spi_display_xfer_agreement - Print the current target transfer agreement
++ * @starget: The target for which to display the agreement
++ *
++ * Each SPI port is required to maintain a transfer agreement for each
++ * other port on the bus. This function prints a one-line summary of
++ * the current agreement; more detailed information is available in sysfs.
++ */
++void spi_display_xfer_agreement(struct scsi_target *starget)
++{
++ struct spi_transport_attrs *tp;
++ tp = (struct spi_transport_attrs *)&starget->starget_data;
++
++ if (tp->offset > 0 && tp->period > 0) {
++ unsigned int picosec, kb100;
++ char *scsi = "FAST-?";
++ char tmp[8];
++
++ if (tp->period <= SPI_STATIC_PPR) {
++ picosec = ppr_to_ps[tp->period];
++ switch (tp->period) {
++ case 7: scsi = "FAST-320"; break;
++ case 8: scsi = "FAST-160"; break;
++ case 9: scsi = "FAST-80"; break;
++ case 10:
++ case 11: scsi = "FAST-40"; break;
++ case 12: scsi = "FAST-20"; break;
++ }
++ } else {
++ picosec = tp->period * 4000;
++ if (tp->period < 25)
++ scsi = "FAST-20";
++ else if (tp->period < 50)
++ scsi = "FAST-10";
++ else
++ scsi = "FAST-5";
++ }
++
++ kb100 = (10000000 + picosec / 2) / picosec;
++ if (tp->width)
++ kb100 *= 2;
++ sprint_frac(tmp, picosec, 1000);
++
++ dev_info(&starget->dev,
++ "%s %sSCSI %d.%d MB/s %s%s%s (%s ns, offset %d)\n",
++ scsi, tp->width ? "WIDE " : "", kb100/10, kb100 % 10,
++ tp->dt ? "DT" : "ST", tp->iu ? " IU" : "",
++ tp->qas ? " QAS" : "", tmp, tp->offset);
++ } else {
++ dev_info(&starget->dev, "%sasynchronous.\n",
++ tp->width ? "wide " : "");
++ }
++}
++EXPORT_SYMBOL(spi_display_xfer_agreement);
++
+ #define SETUP_ATTRIBUTE(field) \
+ i->private_attrs[count] = class_device_attr_##field; \
+ if (!i->f->set_##field) { \
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/Makefile CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/Makefile
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/Makefile 2005-03-02 04:19:14.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/Makefile 2005-02-26 22:14:50.000000000 -0700
+@@ -1,4 +1,4 @@
+ # Makefile for the NCR/SYMBIOS/LSI 53C8XX PCI SCSI controllers driver.
+
+-sym53c8xx-objs := sym_fw.o sym_glue.o sym_hipd.o sym_malloc.o sym_misc.o sym_nvram.o
++sym53c8xx-objs := sym_fw.o sym_glue.o sym_hipd.o sym_malloc.o sym_nvram.o
+ obj-$(CONFIG_SCSI_SYM53C8XX_2) := sym53c8xx.o
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym53c8xx.h CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym53c8xx.h
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym53c8xx.h 2005-03-02 04:19:14.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym53c8xx.h 2005-03-04 08:54:42.000000000 -0700
+@@ -42,10 +42,6 @@
+
+ #include <linux/config.h>
+
+-#ifdef CONFIG_SCSI_SYM53C8XX_IOMAPPED
+-#define SYM_CONF_IOMAPPED
+-#endif
+-
+ /*
+ * DMA addressing mode.
+ *
+@@ -144,10 +140,6 @@
+ #define SYM_SETUP_HOST_ID sym_driver_setup.host_id
+ #define boot_verbose sym_driver_setup.verbose
+
+-/* Always enable parity. */
+-#define SYM_SETUP_PCI_PARITY 1
+-#define SYM_SETUP_SCSI_PARITY 1
+-
+ /*
+ * Initial setup.
+ *
+@@ -170,4 +162,56 @@
+ extern unsigned int sym_debug_flags;
+ #define DEBUG_FLAGS sym_debug_flags
+
++/*
++ * Max number of targets.
++ * Maximum is 16 and you are advised not to change this value.
++ */
++#ifndef SYM_CONF_MAX_TARGET
++#define SYM_CONF_MAX_TARGET (16)
++#endif
++
++/*
++ * Max number of logical units.
++ * SPI-2 allows up to 64 logical units, but in real life, target
++ * that implements more that 7 logical units are pretty rare.
++ * Anyway, the cost of accepting up to 64 logical unit is low in
++ * this driver, thus going with the maximum is acceptable.
++ */
++#ifndef SYM_CONF_MAX_LUN
++#define SYM_CONF_MAX_LUN (64)
++#endif
++
++/*
++ * Max number of IO control blocks queued to the controller.
++ * Each entry needs 8 bytes and the queues are allocated contiguously.
++ * Since we donnot want to allocate more than a page, the theorical
++ * maximum is PAGE_SIZE/8. For safety, we announce a bit less to the
++ * access method. :)
++ * When not supplied, as it is suggested, the driver compute some
++ * good value for this parameter.
++ */
++/* #define SYM_CONF_MAX_START (PAGE_SIZE/8 - 16) */
++
++/*
++ * Support for Immediate Arbitration.
++ * Not advised.
++ */
++/* #define SYM_CONF_IARB_SUPPORT */
++
++/*
++ * Only relevant if IARB support configured.
++ * - Max number of successive settings of IARB hints.
++ * - Set IARB on arbitration lost.
++ */
++#define SYM_CONF_IARB_MAX 3
++#define SYM_CONF_SET_IARB_ON_ARB_LOST 1
++
++/*
++ * Returning wrong residuals may make problems.
++ * When zero, this define tells the driver to
++ * always return 0 as transfer residual.
++ * Btw, all my testings of residuals have succeeded.
++ */
++#define SYM_SETUP_RESIDUAL_SUPPORT 1
++
+ #endif /* SYM53C8XX_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_conf.h CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_conf.h
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_conf.h 2005-03-02 04:19:14.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_conf.h 1969-12-31 17:00:00.000000000 -0700
+@@ -1,110 +0,0 @@
+-/*
+- * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family
+- * of PCI-SCSI IO processors.
+- *
+- * Copyright (C) 1999-2001 Gerard Roudier <groudier at free.fr>
+- *
+- * This driver is derived from the Linux sym53c8xx driver.
+- * Copyright (C) 1998-2000 Gerard Roudier
+- *
+- * The sym53c8xx driver is derived from the ncr53c8xx driver that had been
+- * a port of the FreeBSD ncr driver to Linux-1.2.13.
+- *
+- * The original ncr driver has been written for 386bsd and FreeBSD by
+- * Wolfgang Stanglmeier <wolf at cologne.de>
+- * Stefan Esser <se at mi.Uni-Koeln.de>
+- * Copyright (C) 1994 Wolfgang Stanglmeier
+- *
+- * Other major contributions:
+- *
+- * NVRAM detection and reading.
+- * Copyright (C) 1997 Richard Waltham <dormouse at farsrobt.demon.co.uk>
+- *
+- *-----------------------------------------------------------------------------
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-#ifndef SYM_CONF_H
+-#define SYM_CONF_H
+-
+-#include "sym53c8xx.h"
+-
+-/*
+- * Max number of targets.
+- * Maximum is 16 and you are advised not to change this value.
+- */
+-#ifndef SYM_CONF_MAX_TARGET
+-#define SYM_CONF_MAX_TARGET (16)
+-#endif
+-
+-/*
+- * Max number of logical units.
+- * SPI-2 allows up to 64 logical units, but in real life, target
+- * that implements more that 7 logical units are pretty rare.
+- * Anyway, the cost of accepting up to 64 logical unit is low in
+- * this driver, thus going with the maximum is acceptable.
+- */
+-#ifndef SYM_CONF_MAX_LUN
+-#define SYM_CONF_MAX_LUN (64)
+-#endif
+-
+-/*
+- * Max number of IO control blocks queued to the controller.
+- * Each entry needs 8 bytes and the queues are allocated contiguously.
+- * Since we donnot want to allocate more than a page, the theorical
+- * maximum is PAGE_SIZE/8. For safety, we announce a bit less to the
+- * access method. :)
+- * When not supplied, as it is suggested, the driver compute some
+- * good value for this parameter.
+- */
+-/* #define SYM_CONF_MAX_START (PAGE_SIZE/8 - 16) */
+-
+-/*
+- * Support for Immediate Arbitration.
+- * Not advised.
+- */
+-/* #define SYM_CONF_IARB_SUPPORT */
+-
+-/*
+- * Only relevant if IARB support configured.
+- * - Max number of successive settings of IARB hints.
+- * - Set IARB on arbitration lost.
+- */
+-#define SYM_CONF_IARB_MAX 3
+-#define SYM_CONF_SET_IARB_ON_ARB_LOST 1
+-
+-/*
+- * Returning wrong residuals may make problems.
+- * When zero, this define tells the driver to
+- * always return 0 as transfer residual.
+- * Btw, all my testings of residuals have succeeded.
+- */
+-#define SYM_SETUP_RESIDUAL_SUPPORT 1
+-
+-/*
+- * Supported maximum number of LUNs to announce to
+- * the access method.
+- * The driver supports up to 64 LUNs per target as
+- * required by SPI-2/SPI-3. However some SCSI devices
+- * designed prior to these specifications or not being
+- * conformant may be highly confused when they are
+- * asked about a LUN > 7.
+- */
+-#ifndef SYM_SETUP_MAX_LUN
+-#define SYM_SETUP_MAX_LUN (8)
+-#endif
+-
+-#endif /* SYM_CONF_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_defs.h CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_defs.h
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_defs.h 2004-12-29 12:42:24.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_defs.h 2005-03-04 08:35:58.000000000 -0700
+@@ -40,13 +40,13 @@
+ #ifndef SYM_DEFS_H
+ #define SYM_DEFS_H
+
+-#define SYM_VERSION "2.1.18n"
++#define SYM_VERSION "2.2.0"
+ #define SYM_DRIVER_NAME "sym-" SYM_VERSION
+
+ /*
+ * SYM53C8XX device features descriptor.
+ */
+-struct sym_pci_chip {
++struct sym_chip {
+ u_short device_id;
+ u_short revision_id;
+ char *name;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_fw.c CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_fw.c
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_fw.c 2004-12-02 12:51:11.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_fw.c 2005-03-04 08:35:58.000000000 -0700
+@@ -361,7 +361,7 @@
+ * Find the most appropriate firmware for a chip.
+ */
+ struct sym_fw *
+-sym_find_firmware(struct sym_pci_chip *chip)
++sym_find_firmware(struct sym_chip *chip)
+ {
+ if (chip->features & FE_LDSTR)
+ return &sym_fw2;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_glue.c CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_glue.c
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_glue.c 2005-03-02 04:19:14.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_glue.c 2005-03-04 08:35:58.000000000 -0700
+@@ -3,7 +3,7 @@
+ * of PCI-SCSI IO processors.
+ *
+ * Copyright (C) 1999-2001 Gerard Roudier <groudier at free.fr>
+- * Copyright (c) 2003-2004 Matthew Wilcox <matthew at wil.cx>
++ * Copyright (c) 2003-2005 Matthew Wilcox <matthew at wil.cx>
+ *
+ * This driver is derived from the Linux sym53c8xx driver.
+ * Copyright (C) 1998-2000 Gerard Roudier
+@@ -47,7 +47,6 @@
+ #include <scsi/scsi_tcq.h>
+ #include <scsi/scsi_device.h>
+ #include <scsi/scsi_transport.h>
+-#include <scsi/scsi_transport_spi.h>
+
+ #include "sym_glue.h"
+ #include "sym_nvram.h"
+@@ -135,81 +134,47 @@
+ }
+ }
+
++/*
++ * 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, u_long *base)
++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;
+- ++index;
++ pci_read_config_dword(pdev, PCI_BAR_OFFSET(index++), &tmp);
++ base = tmp;
+ if ((tmp & 0x7) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
+-#if BITS_PER_LONG > 32
+- pci_read_config_dword(pdev, PCI_BAR_OFFSET(index), &tmp);
+- *base |= (((u_long)tmp) << 32);
+-#endif
+- ++index;
++ 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
+ }
+
+-/* This lock protects only the memory allocation/free. */
+-static DEFINE_SPINLOCK(sym53c8xx_lock);
+-
+ static struct scsi_transport_template *sym2_transport_template = NULL;
+
+ /*
+- * Wrappers to the generic memory allocator.
+- */
+-void *sym_calloc(int size, char *name)
+-{
+- unsigned long flags;
+- void *m;
+- spin_lock_irqsave(&sym53c8xx_lock, flags);
+- m = sym_calloc_unlocked(size, name);
+- spin_unlock_irqrestore(&sym53c8xx_lock, flags);
+- return m;
+-}
+-
+-void sym_mfree(void *m, int size, char *name)
+-{
+- unsigned long flags;
+- spin_lock_irqsave(&sym53c8xx_lock, flags);
+- sym_mfree_unlocked(m, size, name);
+- spin_unlock_irqrestore(&sym53c8xx_lock, flags);
+-}
+-
+-void *__sym_calloc_dma(m_pool_ident_t dev_dmat, int size, char *name)
+-{
+- unsigned long flags;
+- void *m;
+- spin_lock_irqsave(&sym53c8xx_lock, flags);
+- m = __sym_calloc_dma_unlocked(dev_dmat, size, name);
+- spin_unlock_irqrestore(&sym53c8xx_lock, flags);
+- return m;
+-}
+-
+-void __sym_mfree_dma(m_pool_ident_t dev_dmat, void *m, int size, char *name)
+-{
+- unsigned long flags;
+- spin_lock_irqsave(&sym53c8xx_lock, flags);
+- __sym_mfree_dma_unlocked(dev_dmat, m, size, name);
+- spin_unlock_irqrestore(&sym53c8xx_lock, flags);
+-}
+-
+-m_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m)
+-{
+- unsigned long flags;
+- m_addr_t b;
+- spin_lock_irqsave(&sym53c8xx_lock, flags);
+- b = __vtobus_unlocked(dev_dmat, m);
+- spin_unlock_irqrestore(&sym53c8xx_lock, flags);
+- return b;
+-}
+-
+-/*
+ * Used by the eh thread to wait for command completion.
+ * It is allocated on the eh thread stack.
+ */
+@@ -231,8 +196,7 @@
+ };
+
+ #define SYM_UCMD_PTR(cmd) ((struct sym_ucmd *)(&(cmd)->SCp))
+-#define SYM_SCMD_PTR(ucmd) sym_que_entry(ucmd, struct scsi_cmnd, SCp)
+-#define SYM_SOFTC_PTR(cmd) (((struct host_data *)cmd->device->host->hostdata)->ncb)
++#define SYM_SOFTC_PTR(cmd) sym_get_hcb(cmd->device->host)
+
+ static void __unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
+ {
+@@ -288,31 +252,20 @@
+ /*
+ * Complete a pending CAM CCB.
+ */
+-void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb)
++void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *cmd)
+ {
+- unmap_scsi_data(np, ccb);
+- ccb->scsi_done(ccb);
++ unmap_scsi_data(np, cmd);
++ cmd->scsi_done(cmd);
+ }
+
+-static void sym_xpt_done2(struct sym_hcb *np, struct scsi_cmnd *ccb, int cam_status)
++static void sym_xpt_done2(struct sym_hcb *np, struct scsi_cmnd *cmd, int cam_status)
+ {
+- sym_set_cam_status(ccb, cam_status);
+- sym_xpt_done(np, ccb);
++ sym_set_cam_status(cmd, cam_status);
++ sym_xpt_done(np, cmd);
+ }
+
+
+ /*
+- * Print something that identifies the IO.
+- */
+-void sym_print_addr(struct sym_ccb *cp)
+-{
+- struct scsi_cmnd *cmd = cp->cam_ccb;
+- if (cmd)
+- printf("%s:%d:%d:", sym_name(SYM_SOFTC_PTR(cmd)),
+- cmd->device->id, cmd->device->lun);
+-}
+-
+-/*
+ * Tell the SCSI layer about a BUS RESET.
+ */
+ void sym_xpt_async_bus_reset(struct sym_hcb *np)
+@@ -334,16 +287,6 @@
+ }
+
+ /*
+- * Tell the SCSI layer about the new transfer parameters.
+- */
+-void sym_xpt_async_nego_wide(struct sym_hcb *np, int target)
+-{
+- if (sym_verbose < 3)
+- return;
+- sym_announce_transfer_rate(np, target);
+-}
+-
+-/*
+ * Choose the more appropriate CAM status if
+ * the IO encountered an extended error.
+ */
+@@ -367,7 +310,7 @@
+ */
+ void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid)
+ {
+- struct scsi_cmnd *csio = cp->cam_ccb;
++ struct scsi_cmnd *cmd = cp->cmd;
+ u_int cam_status, scsi_status, drv_status;
+
+ drv_status = 0;
+@@ -378,7 +321,7 @@
+ scsi_status = cp->sv_scsi_status;
+ resid = cp->sv_resid;
+ if (sym_verbose && cp->sv_xerr_status)
+- sym_print_xerr(cp, cp->sv_xerr_status);
++ sym_print_xerr(cmd, cp->sv_xerr_status);
+ if (cp->host_status == HS_COMPLETE &&
+ cp->ssss_status == S_GOOD &&
+ cp->xerr_status == 0) {
+@@ -388,9 +331,9 @@
+ /*
+ * Bounce back the sense data to user.
+ */
+- memset(&csio->sense_buffer, 0, sizeof(csio->sense_buffer));
+- memcpy(csio->sense_buffer, cp->sns_bbuf,
+- min(sizeof(csio->sense_buffer),
++ memset(&cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
++ memcpy(cmd->sense_buffer, cp->sns_bbuf,
++ min(sizeof(cmd->sense_buffer),
+ (size_t)SYM_SNS_BBUF_LEN));
+ #if 0
+ /*
+@@ -400,7 +343,7 @@
+ */
+ if (1) {
+ u_char *p;
+- p = (u_char *) csio->sense_data;
++ p = (u_char *) cmd->sense_data;
+ if (p[0]==0x70 && p[2]==0x6 && p[12]==0x29)
+ sym_clear_tasks(np, DID_ABORT,
+ cp->target,cp->lun, -1);
+@@ -413,7 +356,7 @@
+ * condition otherwise the device will always return
+ * BUSY. Use a big stick.
+ */
+- sym_reset_scsi_target(np, csio->device->id);
++ sym_reset_scsi_target(np, cmd->device->id);
+ cam_status = DID_ERROR;
+ }
+ } else if (cp->host_status == HS_COMPLETE) /* Bad SCSI status */
+@@ -424,8 +367,7 @@
+ cam_status = DID_ERROR;
+ else { /* Extended error */
+ if (sym_verbose) {
+- PRINT_ADDR(cp);
+- printf ("COMMAND FAILED (%x %x %x).\n",
++ sym_print_addr(cmd, "COMMAND FAILED (%x %x %x).\n",
+ cp->host_status, cp->ssss_status,
+ cp->xerr_status);
+ }
+@@ -434,8 +376,8 @@
+ */
+ cam_status = sym_xerr_cam_status(DID_ERROR, cp->xerr_status);
+ }
+- csio->resid = resid;
+- csio->result = (drv_status << 24) + (cam_status << 16) + scsi_status;
++ cmd->resid = resid;
++ cmd->result = (drv_status << 24) + (cam_status << 16) + scsi_status;
+ }
+
+
+@@ -502,9 +444,9 @@
+ /*
+ * Queue a SCSI command.
+ */
+-static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *ccb)
++static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd)
+ {
+-/* struct scsi_device *device = ccb->device; */
++ struct scsi_device *sdev = cmd->device;
+ struct sym_tcb *tp;
+ struct sym_lcb *lp;
+ struct sym_ccb *cp;
+@@ -514,17 +456,17 @@
+ * Minimal checkings, so that we will not
+ * go outside our tables.
+ */
+- if (ccb->device->id == np->myaddr ||
+- ccb->device->id >= SYM_CONF_MAX_TARGET ||
+- ccb->device->lun >= SYM_CONF_MAX_LUN) {
+- sym_xpt_done2(np, ccb, CAM_DEV_NOT_THERE);
++ if (sdev->id == np->myaddr ||
++ sdev->id >= SYM_CONF_MAX_TARGET ||
++ sdev->lun >= SYM_CONF_MAX_LUN) {
++ sym_xpt_done2(np, cmd, CAM_DEV_NOT_THERE);
+ return 0;
+ }
+
+ /*
+ * Retrieve the target descriptor.
+ */
+- tp = &np->target[ccb->device->id];
++ tp = &np->target[sdev->id];
+
+ /*
+ * Complete the 1st INQUIRY command with error
+@@ -538,12 +480,12 @@
+ * devices behave badly when asked for some non
+ * zero LUN. Btw, this is an absolute hack.:-)
+ */
+- if (ccb->cmnd[0] == 0x12 || ccb->cmnd[0] == 0x0) {
++ if (cmd->cmnd[0] == 0x12 || cmd->cmnd[0] == 0x0) {
+ if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
+ ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) &&
+- ccb->device->lun != 0)) {
++ sdev->lun != 0)) {
+ tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
+- sym_xpt_done2(np, ccb, CAM_DEV_NOT_THERE);
++ sym_xpt_done2(np, cmd, CAM_DEV_NOT_THERE);
+ return 0;
+ }
+ }
+@@ -551,23 +493,23 @@
+ /*
+ * Select tagged/untagged.
+ */
+- lp = sym_lp(np, tp, ccb->device->lun);
++ lp = sym_lp(tp, sdev->lun);
+ order = (lp && lp->s.reqtags) ? M_SIMPLE_TAG : 0;
+
+ /*
+ * Queue the SCSI IO.
+ */
+- cp = sym_get_ccb(np, ccb->device->id, ccb->device->lun, order);
++ cp = sym_get_ccb(np, cmd, order);
+ if (!cp)
+ return 1; /* Means resource shortage */
+- sym_queue_scsiio(np, ccb, cp);
++ sym_queue_scsiio(np, cmd, cp);
+ return 0;
+ }
+
+ /*
+ * Setup buffers and pointers that address the CDB.
+ */
+-static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *ccb, struct sym_ccb *cp)
++static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
+ {
+ u32 cmd_ba;
+ int cmd_len;
+@@ -575,14 +517,14 @@
+ /*
+ * CDB is 16 bytes max.
+ */
+- if (ccb->cmd_len > sizeof(cp->cdb_buf)) {
+- sym_set_cam_status(cp->cam_ccb, CAM_REQ_INVALID);
++ if (cmd->cmd_len > sizeof(cp->cdb_buf)) {
++ sym_set_cam_status(cp->cmd, CAM_REQ_INVALID);
+ return -1;
+ }
+
+- memcpy(cp->cdb_buf, ccb->cmnd, ccb->cmd_len);
++ memcpy(cp->cdb_buf, cmd->cmnd, cmd->cmd_len);
+ cmd_ba = CCB_BA (cp, cdb_buf[0]);
+- cmd_len = ccb->cmd_len;
++ cmd_len = cmd->cmd_len;
+
+ cp->phys.cmd.addr = cpu_to_scr(cmd_ba);
+ cp->phys.cmd.size = cpu_to_scr(cmd_len);
+@@ -593,29 +535,29 @@
+ /*
+ * Setup pointers that address the data and start the I/O.
+ */
+-int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp)
++int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
+ {
+ int dir;
+ struct sym_tcb *tp = &np->target[cp->target];
+- struct sym_lcb *lp = sym_lp(np, tp, cp->lun);
++ struct sym_lcb *lp = sym_lp(tp, cp->lun);
+
+ /*
+ * Build the CDB.
+ */
+- if (sym_setup_cdb(np, csio, cp))
++ if (sym_setup_cdb(np, cmd, cp))
+ goto out_abort;
+
+ /*
+ * No direction means no data.
+ */
+- dir = csio->sc_data_direction;
++ dir = cmd->sc_data_direction;
+ if (dir != DMA_NONE) {
+- cp->segments = sym_scatter(np, cp, csio);
++ cp->segments = sym_scatter(np, cp, cmd);
+ if (cp->segments < 0) {
+ if (cp->segments == -2)
+- sym_set_cam_status(csio, CAM_RESRC_UNAVAIL);
++ sym_set_cam_status(cmd, CAM_RESRC_UNAVAIL);
+ else
+- sym_set_cam_status(csio, CAM_REQ_TOO_BIG);
++ sym_set_cam_status(cmd, CAM_REQ_TOO_BIG);
+ goto out_abort;
+ }
+ } else {
+@@ -655,7 +597,7 @@
+
+ out_abort:
+ sym_free_ccb(np, cp);
+- sym_xpt_done(np, csio);
++ sym_xpt_done(np, cmd);
+ return 0;
+ }
+
+@@ -855,11 +797,8 @@
+ int to_do = SYM_EH_DO_IGNORE;
+ int sts = -1;
+ struct sym_eh_wait eh, *ep = &eh;
+- char devname[20];
+-
+- sprintf(devname, "%s:%d:%d", sym_name(np), cmd->device->id, cmd->device->lun);
+
+- printf_warning("%s: %s operation started.\n", devname, opname);
++ dev_warn(&cmd->device->sdev_gendev, "%s operation started.\n", opname);
+
+ #if 0
+ /* This one should be the result of some race, thus to ignore */
+@@ -870,7 +809,7 @@
+ /* 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->cam_ccb == cmd) {
++ if (cp->cmd == cmd) {
+ to_do = SYM_EH_DO_WAIT;
+ goto prepare;
+ }
+@@ -939,9 +878,9 @@
+ if (ep->timed_out)
+ sts = -2;
+ }
+- printf_warning("%s: %s operation %s.\n", devname, opname,
+- sts==0?"complete":sts==-2?"timed-out":"failed");
+- return sts? SCSI_FAILED : SCSI_SUCCESS;
++ 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;
+ }
+
+
+@@ -971,10 +910,9 @@
+ /*
+ * Tune device queuing depth, according to various limits.
+ */
+-static void sym_tune_dev_queuing(struct sym_hcb *np, int target, int lun, u_short reqtags)
++static void sym_tune_dev_queuing(struct sym_tcb *tp, int lun, u_short reqtags)
+ {
+- struct sym_tcb *tp = &np->target[target];
+- struct sym_lcb *lp = sym_lp(np, tp, lun);
++ struct sym_lcb *lp = sym_lp(tp, lun);
+ u_short oldtags;
+
+ if (!lp)
+@@ -990,9 +928,8 @@
+ lp->s.reqtags = reqtags;
+
+ if (reqtags != oldtags) {
+- printf_info("%s:%d:%d: "
++ dev_info(&tp->sdev->sdev_target->dev,
+ "tagged command queuing %s, command queue depth %d.\n",
+- sym_name(np), target, lun,
+ lp->s.reqtags ? "enabled" : "disabled",
+ lp->started_limit);
+ }
+@@ -1051,21 +988,34 @@
+ return DEF_DEPTH;
+ }
+
++static int sym53c8xx_slave_alloc(struct scsi_device *device)
++{
++ struct sym_hcb *np = sym_get_hcb(device->host);
++ struct sym_tcb *tp = &np->target[device->id];
++ if (!tp->sdev)
++ tp->sdev = device;
++
++ return 0;
++}
++
++static void sym53c8xx_slave_destroy(struct scsi_device *device)
++{
++ struct sym_hcb *np = sym_get_hcb(device->host);
++ struct sym_tcb *tp = &np->target[device->id];
++ if (tp->sdev == device)
++ tp->sdev = NULL;
++}
++
+ /*
+ * Linux entry point for device queue sizing.
+ */
+ static int sym53c8xx_slave_configure(struct scsi_device *device)
+ {
+- struct Scsi_Host *host = device->host;
+- struct sym_hcb *np;
+- struct sym_tcb *tp;
++ struct sym_hcb *np = sym_get_hcb(device->host);
++ struct sym_tcb *tp = &np->target[device->id];
+ struct sym_lcb *lp;
+ int reqtags, depth_to_use;
+
+- np = ((struct host_data *) host->hostdata)->ncb;
+- tp = &np->target[device->id];
+- tp->sdev = device;
+-
+ /*
+ * Allocate the LCB if not yet.
+ * If it fail, we may well be in the sh*t. :)
+@@ -1102,7 +1052,7 @@
+ MSG_SIMPLE_TAG : 0),
+ depth_to_use);
+ lp->s.scdev_depth = depth_to_use;
+- sym_tune_dev_queuing(np, device->id, device->lun, reqtags);
++ sym_tune_dev_queuing(tp, device->lun, reqtags);
+
+ if (!spi_initial_dv(device->sdev_target))
+ spi_dv_device(device);
+@@ -1115,7 +1065,7 @@
+ */
+ static const char *sym53c8xx_info (struct Scsi_Host *host)
+ {
+- return sym_driver_name();
++ return SYM_DRIVER_NAME;
+ }
+
+
+@@ -1178,44 +1128,47 @@
+
+ case UC_SETSYNC:
+ if (!uc->data || uc->data >= 255) {
+- tp->tinfo.goal.options = 0;
+- tp->tinfo.goal.offset = 0;
+- break;
+- }
+- if (uc->data <= 9 && np->minsync_dt) {
++ tp->tgoal.iu = tp->tgoal.dt =
++ tp->tgoal.qas = 0;
++ tp->tgoal.offset = 0;
++ } else if (uc->data <= 9 && np->minsync_dt) {
+ if (uc->data < np->minsync_dt)
+ uc->data = np->minsync_dt;
+- tp->tinfo.goal.options = PPR_OPT_MASK;
+- tp->tinfo.goal.width = 1;
+- tp->tinfo.goal.period = uc->data;
+- tp->tinfo.goal.offset = np->maxoffs_dt;
++ tp->tgoal.iu = tp->tgoal.dt =
++ tp->tgoal.qas = 1;
++ tp->tgoal.width = 1;
++ tp->tgoal.period = uc->data;
++ tp->tgoal.offset = np->maxoffs_dt;
+ } else {
+ if (uc->data < np->minsync)
+ uc->data = np->minsync;
+- tp->tinfo.goal.options = 0;
+- tp->tinfo.goal.period = uc->data;
+- tp->tinfo.goal.offset = np->maxoffs;
++ tp->tgoal.iu = tp->tgoal.dt =
++ tp->tgoal.qas = 0;
++ tp->tgoal.period = uc->data;
++ tp->tgoal.offset = np->maxoffs;
+ }
++ tp->tgoal.check_nego = 1;
+ break;
+ case UC_SETWIDE:
+- tp->tinfo.goal.width = uc->data ? 1 : 0;
++ tp->tgoal.width = uc->data ? 1 : 0;
++ tp->tgoal.check_nego = 1;
+ break;
+ case UC_SETTAGS:
+ for (l = 0; l < SYM_CONF_MAX_LUN; l++)
+- sym_tune_dev_queuing(np, t,l, uc->data);
++ sym_tune_dev_queuing(tp, l, uc->data);
+ break;
+ case UC_RESETDEV:
+ tp->to_reset = 1;
+ np->istat_sem = SEM;
+- OUTB (nc_istat, SIGP|SEM);
++ OUTB(np, nc_istat, SIGP|SEM);
+ break;
+ case UC_CLEARDEV:
+ for (l = 0; l < SYM_CONF_MAX_LUN; l++) {
+- struct sym_lcb *lp = sym_lp(np, tp, l);
++ struct sym_lcb *lp = sym_lp(tp, l);
+ if (lp) lp->to_clear = 1;
+ }
+ np->istat_sem = SEM;
+- OUTB (nc_istat, SIGP|SEM);
++ OUTB(np, nc_istat, SIGP|SEM);
+ break;
+ case UC_SETFLAG:
+ tp->usrflags = uc->data;
+@@ -1226,8 +1179,6 @@
+ }
+ }
+
+-#define digit_to_bin(c) ((c) - '0')
+-
+ static int skip_spaces(char *ptr, int len)
+ {
+ int cnt, c;
+@@ -1239,17 +1190,10 @@
+
+ static int get_int_arg(char *ptr, int len, u_long *pv)
+ {
+- int cnt, c;
+- u_long v;
++ char *end;
+
+- for (v = 0, cnt = len; cnt > 0 && (c = *ptr++) && isdigit(c); cnt--) {
+- v = (v * 10) + digit_to_bin(c);
+- }
+-
+- if (pv)
+- *pv = v;
+-
+- return (len - cnt);
++ *pv = simple_strtoul(ptr, &end, 10);
++ return (end - ptr);
+ }
+
+ static int is_keyword(char *ptr, int len, char *verb)
+@@ -1260,15 +1204,14 @@
+ return verb_len;
+ else
+ return 0;
+-
+ }
+
+-#define SKIP_SPACES(min_spaces) \
+- if ((arg_len = skip_spaces(ptr, len)) < (min_spaces)) \
++#define SKIP_SPACES(ptr, len) \
++ if ((arg_len = skip_spaces(ptr, len)) < 1) \
+ return -EINVAL; \
+ ptr += arg_len; len -= arg_len;
+
+-#define GET_INT_ARG(v) \
++#define GET_INT_ARG(ptr, len, v) \
+ if (!(arg_len = get_int_arg(ptr, len, &(v)))) \
+ return -EINVAL; \
+ ptr += arg_len; len -= arg_len;
+@@ -1327,12 +1270,12 @@
+ case UC_SETFLAG:
+ case UC_RESETDEV:
+ case UC_CLEARDEV:
+- SKIP_SPACES(1);
++ SKIP_SPACES(ptr, len);
+ if ((arg_len = is_keyword(ptr, len, "all")) != 0) {
+ ptr += arg_len; len -= arg_len;
+ uc->target = ~0;
+ } else {
+- GET_INT_ARG(target);
++ GET_INT_ARG(ptr, len, target);
+ uc->target = (1<<target);
+ #ifdef DEBUG_PROC_INFO
+ printk("sym_user_command: target=%ld\n", target);
+@@ -1346,8 +1289,8 @@
+ case UC_SETSYNC:
+ case UC_SETTAGS:
+ case UC_SETWIDE:
+- SKIP_SPACES(1);
+- GET_INT_ARG(uc->data);
++ SKIP_SPACES(ptr, len);
++ GET_INT_ARG(ptr, len, uc->data);
+ #ifdef DEBUG_PROC_INFO
+ printk("sym_user_command: data=%ld\n", uc->data);
+ #endif
+@@ -1355,7 +1298,7 @@
+ #ifdef SYM_LINUX_DEBUG_CONTROL_SUPPORT
+ case UC_SETDEBUG:
+ while (len > 0) {
+- SKIP_SPACES(1);
++ SKIP_SPACES(ptr, len);
+ if ((arg_len = is_keyword(ptr, len, "alloc")))
+ uc->data |= DEBUG_ALLOC;
+ else if ((arg_len = is_keyword(ptr, len, "phase")))
+@@ -1389,7 +1332,7 @@
+ #endif /* SYM_LINUX_DEBUG_CONTROL_SUPPORT */
+ case UC_SETFLAG:
+ while (len > 0) {
+- SKIP_SPACES(1);
++ SKIP_SPACES(ptr, len);
+ if ((arg_len = is_keyword(ptr, len, "no_disc")))
+ uc->data &= ~SYM_DISC_ENABLED;
+ else
+@@ -1499,15 +1442,9 @@
+ static int sym53c8xx_proc_info(struct Scsi_Host *host, char *buffer,
+ char **start, off_t offset, int length, int func)
+ {
+- struct host_data *host_data;
+- struct sym_hcb *np = NULL;
++ struct sym_hcb *np = sym_get_hcb(host);
+ int retv;
+
+- host_data = (struct host_data *) host->hostdata;
+- np = host_data->ncb;
+- if (!np)
+- return -EINVAL;
+-
+ if (func) {
+ #ifdef SYM_LINUX_USER_COMMAND_SUPPORT
+ retv = sym_user_command(np, buffer, length);
+@@ -1531,19 +1468,17 @@
+ /*
+ * Free controller resources.
+ */
+-static void sym_free_resources(struct sym_hcb *np)
++static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev)
+ {
+ /*
+ * Free O/S specific resources.
+ */
+ if (np->s.irq)
+ free_irq(np->s.irq, np);
+-#ifndef SYM_CONF_IOMAPPED
+- if (np->s.mmio_va)
+- iounmap(np->s.mmio_va);
+-#endif
+- if (np->s.ram_va)
+- iounmap(np->s.ram_va);
++ if (np->s.ioaddr)
++ pci_iounmap(pdev, np->s.ioaddr);
++ if (np->s.ramaddr)
++ pci_iounmap(pdev, np->s.ramaddr);
+ /*
+ * Free O/S independent resources.
+ */
+@@ -1592,13 +1527,14 @@
+ struct host_data *host_data;
+ struct sym_hcb *np = NULL;
+ struct Scsi_Host *instance = NULL;
++ struct pci_dev *pdev = dev->pdev;
+ unsigned long flags;
+ struct sym_fw *fw;
+
+ printk(KERN_INFO
+ "sym%d: <%s> rev 0x%x at pci %s irq " IRQ_FMT "\n",
+ unit, dev->chip.name, dev->chip.revision_id,
+- pci_name(dev->pdev), IRQ_PRM(dev->s.irq));
++ pci_name(pdev), IRQ_PRM(pdev->irq));
+
+ /*
+ * Get the firmware for this chip.
+@@ -1621,22 +1557,22 @@
+ * We keep track in the HCB of all the resources that
+ * are to be released on error.
+ */
+- np = __sym_calloc_dma(dev->pdev, sizeof(*np), "HCB");
++ np = __sym_calloc_dma(&pdev->dev, sizeof(*np), "HCB");
+ if (!np)
+ goto attach_failed;
+- np->s.device = dev->pdev;
+- np->bus_dmat = dev->pdev; /* Result in 1 DMA pool per HBA */
++ np->s.device = pdev;
++ np->bus_dmat = &pdev->dev; /* Result in 1 DMA pool per HBA */
+ host_data->ncb = np;
+ np->s.host = instance;
+
+- pci_set_drvdata(dev->pdev, np);
++ pci_set_drvdata(pdev, np);
+
+ /*
+ * Copy some useful infos to the HCB.
+ */
+ np->hcb_ba = vtobus(np);
+ np->verbose = sym_driver_setup.verbose;
+- np->s.device = dev->pdev;
++ np->s.device = pdev;
+ np->s.unit = unit;
+ np->device_id = dev->chip.device_id;
+ np->revision_id = dev->chip.revision_id;
+@@ -1659,58 +1595,35 @@
+ * Try to map the controller chip to
+ * virtual and physical memory.
+ */
+- np->mmio_ba = (u32)dev->s.base;
+- np->s.io_ws = (np->features & FE_IO256)? 256 : 128;
+-
+-#ifndef SYM_CONF_IOMAPPED
+- np->s.mmio_va = ioremap(dev->s.base_c, np->s.io_ws);
+- if (!np->s.mmio_va) {
+- printf_err("%s: can't map PCI MMIO region\n", sym_name(np));
+- goto attach_failed;
+- } else if (sym_verbose > 1)
+- printf_info("%s: using memory mapped IO\n", sym_name(np));
+-#endif /* !defined SYM_CONF_IOMAPPED */
+-
+- np->s.io_port = dev->s.io_port;
++ np->mmio_ba = (u32)dev->mmio_base;
++ np->s.ioaddr = dev->s.ioaddr;
++ np->s.ramaddr = dev->s.ramaddr;
++ np->s.io_ws = (np->features & FE_IO256) ? 256 : 128;
+
+ /*
+ * Map on-chip RAM if present and supported.
+ */
+ if (!(np->features & FE_RAM))
+- dev->s.base_2 = 0;
+- if (dev->s.base_2) {
+- np->ram_ba = (u32)dev->s.base_2;
+- if (np->features & FE_RAM8K)
+- np->ram_ws = 8192;
+- else
+- np->ram_ws = 4096;
+- np->s.ram_va = ioremap(dev->s.base_2_c, np->ram_ws);
+- if (!np->s.ram_va) {
+- printf_err("%s: can't map PCI MEMORY region\n",
+- sym_name(np));
+- goto attach_failed;
+- }
++ dev->ram_base = 0;
++ if (dev->ram_base) {
++ np->ram_ba = (u32)dev->ram_base;
++ np->ram_ws = (np->features & FE_RAM8K) ? 8192 : 4096;
+ }
+
+- /*
+- * Perform O/S independent stuff.
+- */
+- if (sym_hcb_attach(np, fw, dev->nvram))
++ if (sym_hcb_attach(instance, fw, dev->nvram))
+ goto attach_failed;
+
+-
+ /*
+ * Install the interrupt handler.
+ * If we synchonize the C code with SCRIPTS on interrupt,
+- * we donnot want to share the INTR line at all.
++ * we do not want to share the INTR line at all.
+ */
+- if (request_irq(dev->s.irq, sym53c8xx_intr, SA_SHIRQ,
+- NAME53C8XX, np)) {
++ if (request_irq(pdev->irq, sym53c8xx_intr, SA_SHIRQ, NAME53C8XX, np)) {
+ printf_err("%s: request irq %d failure\n",
+- sym_name(np), dev->s.irq);
++ sym_name(np), pdev->irq);
+ goto attach_failed;
+ }
+- np->s.irq = dev->s.irq;
++ np->s.irq = pdev->irq;
+
+ /*
+ * After SCSI devices have been opened, we cannot
+@@ -1742,14 +1655,7 @@
+ instance->this_id = np->myaddr;
+ instance->max_id = np->maxwide ? 16 : 8;
+ instance->max_lun = SYM_CONF_MAX_LUN;
+-#ifndef SYM_CONF_IOMAPPED
+- instance->base = (unsigned long) np->s.mmio_va;
+-#endif
+- instance->irq = np->s.irq;
+- instance->unique_id = np->s.io_port;
+- instance->io_port = np->s.io_port;
+- instance->n_io_port = np->s.io_ws;
+- instance->dma_channel = 0;
++ instance->unique_id = pci_resource_start(pdev, 0);
+ instance->cmd_per_lun = SYM_CONF_MAX_TAG;
+ instance->can_queue = (SYM_CONF_MAX_START-2);
+ instance->sg_tablesize = SYM_CONF_MAX_SG;
+@@ -1770,7 +1676,7 @@
+ return NULL;
+ printf_info("%s: giving up ...\n", sym_name(np));
+ if (np)
+- sym_free_resources(np);
++ sym_free_resources(np, pdev);
+ scsi_host_put(instance);
+
+ return NULL;
+@@ -1787,23 +1693,7 @@
+ devp->device_id = devp->chip.device_id;
+ nvp->type = 0;
+
+- /*
+- * Get access to chip IO registers
+- */
+-#ifndef SYM_CONF_IOMAPPED
+- devp->s.mmio_va = ioremap(devp->s.base_c, 128);
+- if (!devp->s.mmio_va)
+- return;
+-#endif
+-
+ sym_read_nvram(devp, nvp);
+-
+- /*
+- * Release access to chip IO registers
+- */
+-#ifndef SYM_CONF_IOMAPPED
+- iounmap(devp->s.mmio_va);
+-#endif
+ }
+ #else
+ static inline void sym_get_nvram(struct sym_device *devp, struct sym_nvram *nvp)
+@@ -1813,15 +1703,15 @@
+
+ static int __devinit sym_check_supported(struct sym_device *device)
+ {
+- struct sym_pci_chip *chip;
++ struct sym_chip *chip;
+ struct pci_dev *pdev = device->pdev;
+ u_char revision;
+- unsigned long io_port = device->s.io_port;
+- unsigned long base = device->s.base;
++ unsigned long io_port = pci_resource_start(pdev, 0);
+ int i;
+
+ /*
+ * If user excluded this chip, do not initialize it.
++ * I hate this code so much. Must kill it.
+ */
+ if (io_port) {
+ for (i = 0 ; i < 8 ; i++) {
+@@ -1831,32 +1721,14 @@
+ }
+
+ /*
+- * Check if the chip has been assigned resources we need.
+- * XXX: can this still happen with Linux 2.6's PCI layer?
+- */
+-#ifdef SYM_CONF_IOMAPPED
+- if (!io_port) {
+- printf_info("%s: IO base address disabled.\n",
+- sym_name(device));
+- return -ENODEV;
+- }
+-#else
+- if (!base) {
+- printf_info("%s: MMIO base address disabled.\n",
+- sym_name(device));
+- return -ENODEV;
+- }
+-#endif
+-
+- /*
+ * Check if the chip is supported. Then copy the chip description
+ * to our device structure so we can make it match the actual device
+ * and options.
+ */
+ pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
+- chip = sym_lookup_pci_chip_table(pdev->device, revision);
++ chip = sym_lookup_chip_table(pdev->device, revision);
+ if (!chip) {
+- printf_info("%s: device not supported\n", sym_name(device));
++ dev_info(&pdev->dev, "device not supported\n");
+ return -ENODEV;
+ }
+ memcpy(&device->chip, chip, sizeof(device->chip));
+@@ -1871,11 +1743,9 @@
+ */
+ static int __devinit sym_check_raid(struct sym_device *device)
+ {
+- unsigned long base_2_c = device->s.base_2_c;
+ unsigned int ram_size, ram_val;
+- void __iomem *ram_ptr;
+
+- if (!base_2_c)
++ if (!device->s.ramaddr)
+ return 0;
+
+ if (device->chip.features & FE_RAM8K)
+@@ -1883,23 +1753,18 @@
+ else
+ ram_size = 4096;
+
+- ram_ptr = ioremap(base_2_c, ram_size);
+- if (!ram_ptr)
+- return 0;
+-
+- ram_val = readl(ram_ptr + ram_size - 16);
+- iounmap(ram_ptr);
++ ram_val = readl(device->s.ramaddr + ram_size - 16);
+ if (ram_val != 0x52414944)
+ return 0;
+
+- printf_info("%s: not initializing, driven by RAID controller.\n",
+- sym_name(device));
++ dev_info(&device->pdev->dev,
++ "not initializing, driven by RAID controller.\n");
+ return -ENODEV;
+ }
+
+ static int __devinit sym_set_workarounds(struct sym_device *device)
+ {
+- struct sym_pci_chip *chip = &device->chip;
++ struct sym_chip *chip = &device->chip;
+ struct pci_dev *pdev = device->pdev;
+ u_short status_reg;
+
+@@ -1952,26 +1817,25 @@
+ static void __devinit
+ sym_init_device(struct pci_dev *pdev, struct sym_device *device)
+ {
+- unsigned long base, base_2;
+ int i;
+
+ device->host_id = SYM_SETUP_HOST_ID;
+ device->pdev = pdev;
+- device->s.irq = pdev->irq;
+-
+- /* Choose some short name for this device */
+- sprintf(device->s.inst_name, "sym.%d.%d.%d", pdev->bus->number,
+- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+-
+- device->s.io_port = pdev->resource[0].start;
+
+- device->s.base_c = pdev->resource[1].start;
+- i = pci_get_base_address(pdev, 1, &base);
+- device->s.base = base & PCI_BASE_ADDRESS_MEM_MASK;
++ i = pci_get_base_address(pdev, 1, &device->mmio_base);
++ pci_get_base_address(pdev, i, &device->ram_base);
+
+- device->s.base_2_c = pdev->resource[i].start;
+- pci_get_base_address(pdev, i, &base_2);
+- device->s.base_2 = base_2 & PCI_BASE_ADDRESS_MEM_MASK;
++#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED
++ if (device->mmio_base)
++ device->s.ioaddr = pci_iomap(pdev, 1,
++ pci_resource_len(pdev, 1));
++#endif
++ if (!device->s.ioaddr)
++ device->s.ioaddr = pci_iomap(pdev, 0,
++ pci_resource_len(pdev, 0));
++ if (device->ram_base)
++ device->s.ramaddr = pci_iomap(pdev, i,
++ pci_resource_len(pdev, i));
+ }
+
+ /*
+@@ -2027,7 +1891,7 @@
+ * Detach the host.
+ * We have to free resources and halt the NCR chip.
+ */
+-static int sym_detach(struct sym_hcb *np)
++static int sym_detach(struct sym_hcb *np, struct pci_dev *pdev)
+ {
+ printk("%s: detaching ...\n", sym_name(np));
+
+@@ -2039,11 +1903,11 @@
+ * so, since we may not be safe if interrupts occur.
+ */
+ printk("%s: resetting chip\n", sym_name(np));
+- OUTB (nc_istat, SRST);
+- UDELAY (10);
+- OUTB (nc_istat, 0);
++ OUTB(np, nc_istat, SRST);
++ udelay(10);
++ OUTB(np, nc_istat, 0);
+
+- sym_free_resources(np);
++ sym_free_resources(np, pdev);
+
+ return 1;
+ }
+@@ -2056,7 +1920,9 @@
+ .name = "sym53c8xx",
+ .info = sym53c8xx_info,
+ .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,
+@@ -2116,7 +1982,7 @@
+ return 0;
+
+ detach:
+- sym_detach(pci_get_drvdata(pdev));
++ sym_detach(pci_get_drvdata(pdev), pdev);
+ free:
+ pci_release_regions(pdev);
+ disable:
+@@ -2133,7 +1999,7 @@
+ scsi_remove_host(host);
+ scsi_host_put(host);
+
+- sym_detach(np);
++ sym_detach(np, pdev);
+
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+@@ -2143,12 +2009,12 @@
+
+ static void sym2_get_signalling(struct Scsi_Host *shost)
+ {
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
++ struct sym_hcb *np = sym_get_hcb(shost);
+ enum spi_signal_type type;
+
+ switch (np->scsi_mode) {
+ case SMODE_SE:
+- type = SPI_SIGNAL_SE;
++ type = SPI_SIGNAL_SE;
+ break;
+ case SMODE_LVD:
+ type = SPI_SIGNAL_LVD;
+@@ -2163,152 +2029,97 @@
+ spi_signalling(shost) = type;
+ }
+
+-static void sym2_get_offset(struct scsi_target *starget)
+-{
+- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
+- struct sym_tcb *tp = &np->target[starget->id];
+-
+- spi_offset(starget) = tp->tinfo.curr.offset;
+-}
+-
+ static void sym2_set_offset(struct scsi_target *starget, int offset)
+ {
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
+- struct sym_tcb *tp = &np->target[starget->id];
+-
+- tp->tinfo.goal.offset = offset;
+-}
+-
+-
+-static void sym2_get_period(struct scsi_target *starget)
+-{
+- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
++ struct sym_hcb *np = sym_get_hcb(shost);
+ struct sym_tcb *tp = &np->target[starget->id];
+
+- spi_period(starget) = tp->tinfo.curr.period;
++ tp->tgoal.offset = offset;
++ tp->tgoal.check_nego = 1;
+ }
+
+ static void sym2_set_period(struct scsi_target *starget, int period)
+ {
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
++ struct sym_hcb *np = sym_get_hcb(shost);
+ struct sym_tcb *tp = &np->target[starget->id];
+
+ /* have to have DT for these transfers */
+ if (period <= np->minsync)
+- tp->tinfo.goal.options |= PPR_OPT_DT;
++ tp->tgoal.dt = 1;
+
+- tp->tinfo.goal.period = period;
+-}
+-
+-static void sym2_get_width(struct scsi_target *starget)
+-{
+- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
+- struct sym_tcb *tp = &np->target[starget->id];
+-
+- spi_width(starget) = tp->tinfo.curr.width ? 1 : 0;
++ tp->tgoal.period = period;
++ tp->tgoal.check_nego = 1;
+ }
+
+ static void sym2_set_width(struct scsi_target *starget, int width)
+ {
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
++ struct sym_hcb *np = sym_get_hcb(shost);
+ struct sym_tcb *tp = &np->target[starget->id];
+
+ /* It is illegal to have DT set on narrow transfers. If DT is
+ * clear, we must also clear IU and QAS. */
+ if (width == 0)
+- tp->tinfo.goal.options &= ~PPR_OPT_MASK;
++ tp->tgoal.iu = tp->tgoal.dt = tp->tgoal.qas = 0;
+
+- tp->tinfo.goal.width = width;
+-}
+-
+-static void sym2_get_dt(struct scsi_target *starget)
+-{
+- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
+- struct sym_tcb *tp = &np->target[starget->id];
+-
+- spi_dt(starget) = (tp->tinfo.curr.options & PPR_OPT_DT) ? 1 : 0;
++ tp->tgoal.width = width;
++ tp->tgoal.check_nego = 1;
+ }
+
+ static void sym2_set_dt(struct scsi_target *starget, int dt)
+ {
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
++ struct sym_hcb *np = sym_get_hcb(shost);
+ struct sym_tcb *tp = &np->target[starget->id];
+
+ /* We must clear QAS and IU if DT is clear */
+ if (dt)
+- tp->tinfo.goal.options |= PPR_OPT_DT;
++ tp->tgoal.dt = 1;
+ else
+- tp->tinfo.goal.options &= ~PPR_OPT_MASK;
+-}
+-
+-static void sym2_get_iu(struct scsi_target *starget)
+-{
+- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
+- struct sym_tcb *tp = &np->target[starget->id];
+-
+- spi_iu(starget) = (tp->tinfo.curr.options & PPR_OPT_IU) ? 1 : 0;
++ tp->tgoal.iu = tp->tgoal.dt = tp->tgoal.qas = 0;
++ tp->tgoal.check_nego = 1;
+ }
+
+ static void sym2_set_iu(struct scsi_target *starget, int iu)
+ {
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
++ struct sym_hcb *np = sym_get_hcb(shost);
+ struct sym_tcb *tp = &np->target[starget->id];
+
+ if (iu)
+- tp->tinfo.goal.options |= PPR_OPT_IU | PPR_OPT_DT;
++ tp->tgoal.iu = tp->tgoal.dt = 1;
+ else
+- tp->tinfo.goal.options &= ~PPR_OPT_IU;
+-}
+-
+-static void sym2_get_qas(struct scsi_target *starget)
+-{
+- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
+- struct sym_tcb *tp = &np->target[starget->id];
+-
+- spi_qas(starget) = (tp->tinfo.curr.options & PPR_OPT_QAS) ? 1 : 0;
++ tp->tgoal.iu = 0;
++ tp->tgoal.check_nego = 1;
+ }
+
+ static void sym2_set_qas(struct scsi_target *starget, int qas)
+ {
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+- struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb;
++ struct sym_hcb *np = sym_get_hcb(shost);
+ struct sym_tcb *tp = &np->target[starget->id];
+
+ if (qas)
+- tp->tinfo.goal.options |= PPR_OPT_QAS | PPR_OPT_DT;
++ tp->tgoal.dt = tp->tgoal.qas = 1;
+ else
+- tp->tinfo.goal.options &= ~PPR_OPT_QAS;
++ tp->tgoal.qas = 0;
++ tp->tgoal.check_nego = 1;
+ }
+
+
+ static struct spi_function_template sym2_transport_functions = {
+ .set_offset = sym2_set_offset,
+- .get_offset = sym2_get_offset,
+ .show_offset = 1,
+ .set_period = sym2_set_period,
+- .get_period = sym2_get_period,
+ .show_period = 1,
+ .set_width = sym2_set_width,
+- .get_width = sym2_get_width,
+ .show_width = 1,
+- .get_dt = sym2_get_dt,
+ .set_dt = sym2_set_dt,
+ .show_dt = 1,
+- .get_iu = sym2_get_iu,
+ .set_iu = sym2_set_iu,
+ .show_iu = 1,
+- .get_qas = sym2_get_qas,
+ .set_qas = sym2_set_qas,
+ .show_qas = 1,
+ .get_signalling = sym2_get_signalling,
+@@ -2370,7 +2181,7 @@
+ if (!sym2_transport_template)
+ return -ENODEV;
+
+- error = pci_module_init(&sym2_driver);
++ error = pci_register_driver(&sym2_driver);
+ if (error)
+ spi_release_transport(sym2_transport_template);
+ return error;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_glue.h CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_glue.h
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_glue.h 2005-03-02 04:19:14.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_glue.h 2005-03-04 08:35:58.000000000 -0700
+@@ -56,9 +56,10 @@
+ #include <scsi/scsi.h>
+ #include <scsi/scsi_cmnd.h>
+ #include <scsi/scsi_device.h>
++#include <scsi/scsi_transport_spi.h>
+ #include <scsi/scsi_host.h>
+
+-#include "sym_conf.h"
++#include "sym53c8xx.h"
+ #include "sym_defs.h"
+ #include "sym_misc.h"
+
+@@ -70,7 +71,6 @@
+ #define SYM_OPT_HANDLE_DIR_UNKNOWN
+ #define SYM_OPT_HANDLE_DEVICE_QUEUEING
+ #define SYM_OPT_LIMIT_COMMAND_REORDERING
+-#define SYM_OPT_ANNOUNCE_TRANSFER_RATE
+
+ /*
+ * Print a message with severity.
+@@ -86,11 +86,6 @@
+ #define printf(args...) printk(args)
+
+ /*
+- * Insert a delay in micro-seconds
+- */
+-#define sym_udelay(us) udelay(us)
+-
+-/*
+ * A 'read barrier' flushes any data that have been prefetched
+ * by the processor due to out of order execution. Such a barrier
+ * must notably be inserted prior to looking at data that have
+@@ -111,23 +106,12 @@
+ #define MEMORY_WRITE_BARRIER() wmb()
+
+ /*
+- * Let the compiler know about driver data structure names.
+- */
+-typedef struct sym_tcb *tcb_p;
+-typedef struct sym_lcb *lcb_p;
+-typedef struct sym_ccb *ccb_p;
+-
+-/*
+ * IO functions definition for big/little endian CPU support.
+ * For now, PCI chips are 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 readw_l2b readw
+ #define readl_l2b readl
+ #define writew_b2l writew
+@@ -135,11 +119,6 @@
+
+ #else /* little endian */
+
+-#define inw_raw inw
+-#define inl_raw inl
+-#define outw_raw outw
+-#define outl_raw outl
+-
+ #define readw_raw readw
+ #define readl_raw readl
+ #define writew_raw writew
+@@ -151,27 +130,6 @@
+ #error "Chips in BIG ENDIAN addressing mode are not (yet) supported"
+ #endif
+
+-
+-/*
+- * If the chip 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, sym_offb() and sym_offw() macros only apply to
+- * constants and so donnot generate bloated code.
+- */
+-
+-#if defined(SYM_CONF_CHIP_BIG_ENDIAN)
+-
+-#define sym_offb(o) (((o)&~3)+((~((o)&3))&3))
+-#define sym_offw(o) (((o)&~3)+((~((o)&3))&2))
+-
+-#else
+-
+-#define sym_offb(o) (o)
+-#define sym_offw(o) (o)
+-
+-#endif
+-
+ /*
+ * If the CPU and the chip use same endian-ness addressing,
+ * no byte reordering is needed for script patching.
+@@ -180,117 +138,9 @@
+ * from the script.
+ */
+
+-#if defined(__BIG_ENDIAN) && !defined(SYM_CONF_CHIP_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(SYM_CONF_CHIP_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 SYM_CONF_IOMAPPED is defined, the driver will use
+- * normal IOs instead of the MEMORY MAPPED IO method
+- * recommended by PCI specifications.
+- * If all PCI bridges, host brigdes and architectures
+- * would have been correctly designed for PCI, this
+- * option would be useless.
+- *
+- * If the CPU and the chip 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, ...
+- */
+-
+-#if defined(SYM_CONF_IOMAPPED)
+-
+-/*
+- * IO mapped only input / ouput
+- */
+-
+-#define INB_OFF(o) inb (np->s.io_port + sym_offb(o))
+-#define OUTB_OFF(o, val) outb ((val), np->s.io_port + sym_offb(o))
+-
+-#if defined(__BIG_ENDIAN) && !defined(SYM_CONF_CHIP_BIG_ENDIAN)
+-
+-#define INW_OFF(o) inw_l2b (np->s.io_port + sym_offw(o))
+-#define INL_OFF(o) inl_l2b (np->s.io_port + (o))
+-
+-#define OUTW_OFF(o, val) outw_b2l ((val), np->s.io_port + sym_offw(o))
+-#define OUTL_OFF(o, val) outl_b2l ((val), np->s.io_port + (o))
+-
+-#elif defined(__LITTLE_ENDIAN) && defined(SYM_CONF_CHIP_BIG_ENDIAN)
+-
+-#define INW_OFF(o) inw_b2l (np->s.io_port + sym_offw(o))
+-#define INL_OFF(o) inl_b2l (np->s.io_port + (o))
+-
+-#define OUTW_OFF(o, val) outw_l2b ((val), np->s.io_port + sym_offw(o))
+-#define OUTL_OFF(o, val) outl_l2b ((val), np->s.io_port + (o))
+-
+-#else
+-
+-#define INW_OFF(o) inw_raw (np->s.io_port + sym_offw(o))
+-#define INL_OFF(o) inl_raw (np->s.io_port + (o))
+-
+-#define OUTW_OFF(o, val) outw_raw ((val), np->s.io_port + sym_offw(o))
+-#define OUTL_OFF(o, val) outl_raw ((val), np->s.io_port + (o))
+-
+-#endif /* ENDIANs */
+-
+-#else /* defined SYM_CONF_IOMAPPED */
+-
+-/*
+- * MEMORY mapped IO input / output
+- */
+-
+-#define INB_OFF(o) readb(np->s.mmio_va + sym_offb(o))
+-#define OUTB_OFF(o, val) writeb((val), np->s.mmio_va + sym_offb(o))
+-
+-#if defined(__BIG_ENDIAN) && !defined(SYM_CONF_CHIP_BIG_ENDIAN)
+-
+-#define INW_OFF(o) readw_l2b(np->s.mmio_va + sym_offw(o))
+-#define INL_OFF(o) readl_l2b(np->s.mmio_va + (o))
+-
+-#define OUTW_OFF(o, val) writew_b2l((val), np->s.mmio_va + sym_offw(o))
+-#define OUTL_OFF(o, val) writel_b2l((val), np->s.mmio_va + (o))
+-
+-#elif defined(__LITTLE_ENDIAN) && defined(SYM_CONF_CHIP_BIG_ENDIAN)
+-
+-#define INW_OFF(o) readw_b2l(np->s.mmio_va + sym_offw(o))
+-#define INL_OFF(o) readl_b2l(np->s.mmio_va + (o))
+-
+-#define OUTW_OFF(o, val) writew_l2b((val), np->s.mmio_va + sym_offw(o))
+-#define OUTL_OFF(o, val) writel_l2b((val), np->s.mmio_va + (o))
+-
+-#else
+-
+-#define INW_OFF(o) readw_raw(np->s.mmio_va + sym_offw(o))
+-#define INL_OFF(o) readl_raw(np->s.mmio_va + (o))
+-
+-#define OUTW_OFF(o, val) writew_raw((val), np->s.mmio_va + sym_offw(o))
+-#define OUTL_OFF(o, val) writel_raw((val), np->s.mmio_va + (o))
+-
+-#endif
+-
+-#endif /* defined SYM_CONF_IOMAPPED */
+-
+-#define OUTRAM_OFF(o, a, l) memcpy_toio(np->s.ram_va + (o), (a), (l))
+-
+ /*
+ * Remap some status field values.
+ */
+@@ -360,9 +210,8 @@
+
+ struct Scsi_Host *host;
+
+- void __iomem * mmio_va; /* MMIO kernel virtual address */
+- void __iomem * ram_va; /* RAM kernel virtual address */
+- u_long io_port; /* IO port address cookie */
++ void __iomem * ioaddr; /* MMIO kernel io address */
++ void __iomem * ramaddr; /* RAM kernel io address */
+ u_short io_ws; /* IO window size */
+ int irq; /* IRQ number */
+
+@@ -377,29 +226,20 @@
+ */
+ #define sym_name(np) (np)->s.inst_name
+
+-/*
+- * Data structure used as input for the NVRAM reading.
+- * Must resolve the IO macros and sym_name(), when
+- * used as sub-field 's' of another structure.
+- */
+-struct sym_slot {
+- u_long base;
+- u_long base_2;
+- u_long base_c;
+- u_long base_2_c;
+- int irq;
+-/* port and address fields to fit INB, OUTB macros */
+- u_long io_port;
+- void __iomem * mmio_va;
+- char inst_name[16];
+-};
+-
+ struct sym_nvram;
+
++/*
++ * The IO macros require a struct called 's' and are abused in sym_nvram.c
++ */
+ struct sym_device {
+ struct pci_dev *pdev;
+- struct sym_slot s;
+- struct sym_pci_chip chip;
++ unsigned long mmio_base;
++ unsigned long ram_base;
++ struct {
++ void __iomem *ioaddr;
++ void __iomem *ramaddr;
++ } s;
++ struct sym_chip chip;
+ struct sym_nvram *nvram;
+ u_short device_id;
+ u_char host_id;
+@@ -412,133 +252,48 @@
+ struct sym_hcb *ncb;
+ };
+
+-/*
+- * The driver definitions (sym_hipd.h) must know about a
+- * couple of things related to the memory allocator.
+- */
+-typedef u_long m_addr_t; /* Enough bits to represent any address */
+-#define SYM_MEM_PAGE_ORDER 0 /* 1 PAGE maximum */
+-#define SYM_MEM_CLUSTER_SHIFT (PAGE_SHIFT+SYM_MEM_PAGE_ORDER)
+-#ifdef MODULE
+-#define SYM_MEM_FREE_UNUSED /* Free unused pages immediately */
+-#endif
+-typedef struct pci_dev *m_pool_ident_t;
+-
+-/*
+- * Include driver soft definitions.
+- */
+-#include "sym_fw.h"
+-#include "sym_hipd.h"
+-
+-/*
+- * Memory allocator related stuff.
+- */
+-
+-#define SYM_MEM_GFP_FLAGS GFP_ATOMIC
+-#define SYM_MEM_WARN 1 /* Warn on failed operations */
+-
+-#define sym_get_mem_cluster() \
+- __get_free_pages(SYM_MEM_GFP_FLAGS, SYM_MEM_PAGE_ORDER)
+-#define sym_free_mem_cluster(p) \
+- free_pages(p, SYM_MEM_PAGE_ORDER)
+-
+-void *sym_calloc(int size, char *name);
+-void sym_mfree(void *m, int size, char *name);
+-
+-/*
+- * We have to provide the driver memory allocator with methods for
+- * it to maintain virtual to bus physical address translations.
+- */
+-
+-#define sym_m_pool_match(mp_id1, mp_id2) (mp_id1 == mp_id2)
+-
+-static __inline m_addr_t sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
++static inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host)
+ {
+- void *vaddr = NULL;
+- dma_addr_t baddr = 0;
+-
+- vaddr = pci_alloc_consistent(mp->dev_dmat,SYM_MEM_CLUSTER_SIZE, &baddr);
+- if (vaddr) {
+- vbp->vaddr = (m_addr_t) vaddr;
+- vbp->baddr = (m_addr_t) baddr;
+- }
+- return (m_addr_t) vaddr;
++ return ((struct host_data *)host->hostdata)->ncb;
+ }
+
+-static __inline void sym_m_free_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
+-{
+- pci_free_consistent(mp->dev_dmat, SYM_MEM_CLUSTER_SIZE,
+- (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
+-}
+-
+-#define sym_m_create_dma_mem_tag(mp) (0)
+-#define sym_m_delete_dma_mem_tag(mp) do { ; } while (0)
+-
+-void *__sym_calloc_dma(m_pool_ident_t dev_dmat, int size, char *name);
+-void __sym_mfree_dma(m_pool_ident_t dev_dmat, void *m, int size, char *name);
+-m_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m);
++#include "sym_fw.h"
++#include "sym_hipd.h"
+
+ /*
+ * Set the status field of a CAM CCB.
+ */
+ static __inline void
+-sym_set_cam_status(struct scsi_cmnd *ccb, int status)
++sym_set_cam_status(struct scsi_cmnd *cmd, int status)
+ {
+- ccb->result &= ~(0xff << 16);
+- ccb->result |= (status << 16);
++ cmd->result &= ~(0xff << 16);
++ cmd->result |= (status << 16);
+ }
+
+ /*
+ * Get the status field of a CAM CCB.
+ */
+ static __inline int
+-sym_get_cam_status(struct scsi_cmnd *ccb)
++sym_get_cam_status(struct scsi_cmnd *cmd)
+ {
+- return ((ccb->result >> 16) & 0xff);
++ return host_byte(cmd->result);
+ }
+
+ /*
+- * The dma mapping is mostly handled by the
+- * SCSI layer and the driver glue under Linux.
+- */
+-#define sym_data_dmamap_create(np, cp) (0)
+-#define sym_data_dmamap_destroy(np, cp) do { ; } while (0)
+-#define sym_data_dmamap_unload(np, cp) do { ; } while (0)
+-#define sym_data_dmamap_presync(np, cp) do { ; } while (0)
+-#define sym_data_dmamap_postsync(np, cp) do { ; } while (0)
+-
+-/*
+- * Async handler for negotiations.
+- */
+-void sym_xpt_async_nego_wide(struct sym_hcb *np, int target);
+-#define sym_xpt_async_nego_sync(np, target) \
+- sym_announce_transfer_rate(np, target)
+-#define sym_xpt_async_nego_ppr(np, target) \
+- sym_announce_transfer_rate(np, target)
+-
+-/*
+ * Build CAM result for a successful IO and for a failed IO.
+ */
+-static __inline void sym_set_cam_result_ok(struct sym_hcb *np, ccb_p cp, int resid)
++static __inline void sym_set_cam_result_ok(struct sym_ccb *cp, struct scsi_cmnd *cmd, int resid)
+ {
+- struct scsi_cmnd *cmd = cp->cam_ccb;
+-
+ cmd->resid = resid;
+ cmd->result = (((DID_OK) << 16) + ((cp->ssss_status) & 0x7f));
+ }
+-void sym_set_cam_result_error(struct sym_hcb *np, ccb_p cp, int resid);
++void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid);
+
+-/*
+- * Other O/S specific methods.
+- */
+-#define sym_cam_target_id(ccb) (ccb)->target
+-#define sym_cam_target_lun(ccb) (ccb)->lun
+-#define sym_freeze_cam_ccb(ccb) do { ; } while (0)
+ void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb);
+-void sym_print_addr (ccb_p cp);
++#define sym_print_addr(cmd, arg...) dev_info(&cmd->device->sdev_gendev , ## arg)
+ void sym_xpt_async_bus_reset(struct sym_hcb *np);
+ 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, ccb_p cp);
++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);
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_hipd.c CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_hipd.c
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_hipd.c 2005-03-02 04:19:14.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_hipd.c 2005-03-04 10:02:40.000000000 -0700
+@@ -3,7 +3,7 @@
+ * of PCI-SCSI IO processors.
+ *
+ * Copyright (C) 1999-2001 Gerard Roudier <groudier at free.fr>
+- * Copyright (c) 2003-2004 Matthew Wilcox <matthew at wil.cx>
++ * Copyright (c) 2003-2005 Matthew Wilcox <matthew at wil.cx>
+ *
+ * This driver is derived from the Linux sym53c8xx driver.
+ * Copyright (C) 1998-2000 Gerard Roudier
+@@ -49,54 +49,24 @@
+ */
+ static void sym_int_ma (struct sym_hcb *np);
+ static void sym_int_sir (struct sym_hcb *np);
+-static ccb_p sym_alloc_ccb(struct sym_hcb *np);
+-static ccb_p sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa);
++static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np);
++static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa);
+ static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln);
+-static void sym_complete_error (struct sym_hcb *np, ccb_p cp);
+-static void sym_complete_ok (struct sym_hcb *np, ccb_p cp);
+-static int sym_compute_residual(struct sym_hcb *np, ccb_p cp);
++static void sym_complete_error (struct sym_hcb *np, struct sym_ccb *cp);
++static void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp);
++static int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp);
+
+ /*
+- * Returns the name of this driver.
++ * Print a buffer in hexadecimal format with a ".\n" at end.
+ */
+-char *sym_driver_name(void)
+-{
+- return SYM_DRIVER_NAME;
+-}
+-/*
+- * Print a buffer in hexadecimal format.
+- */
+-static void sym_printb_hex (u_char *p, int n)
++static void sym_printl_hex(u_char *p, int n)
+ {
+ while (n-- > 0)
+ printf (" %x", *p++);
+-}
+-
+-/*
+- * Same with a label at beginning and .\n at end.
+- */
+-static void sym_printl_hex (char *label, u_char *p, int n)
+-{
+- printf ("%s", label);
+- sym_printb_hex (p, n);
+ printf (".\n");
+ }
+
+ /*
+- * Print something which allows to retrieve the controler type,
+- * unit, target, lun concerned by a kernel message.
+- */
+-static void sym_print_target (struct sym_hcb *np, int target)
+-{
+- printf ("%s:%d:", sym_name(np), target);
+-}
+-
+-static void sym_print_lun(struct sym_hcb *np, int target, int lun)
+-{
+- printf ("%s:%d:%d:", sym_name(np), target, lun);
+-}
+-
+-/*
+ * Print out the content of a SCSI message.
+ */
+ static int sym_show_msg (u_char * msg)
+@@ -107,59 +77,51 @@
+ 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 (ccb_p cp, char *label, u_char *msg)
++static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg)
+ {
+- PRINT_ADDR(cp);
+- if (label)
+- printf ("%s: ", label);
++ sym_print_addr(cp->cmd, "%s: ", label);
+
+- (void) sym_show_msg (msg);
+- printf (".\n");
++ sym_show_msg(msg);
++ printf(".\n");
+ }
+
+-static void sym_print_nego_msg (struct sym_hcb *np, int target, char *label, u_char *msg)
++static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg)
+ {
+- PRINT_TARGET(np, target);
+- if (label)
+- printf ("%s: ", label);
++ struct sym_tcb *tp = &np->target[target];
++ dev_info(&tp->sdev->sdev_target->dev, "%s: ", label);
+
+- (void) sym_show_msg (msg);
+- printf (".\n");
++ sym_show_msg(msg);
++ printf(".\n");
+ }
+
+ /*
+ * Print something that tells about extended errors.
+ */
+-void sym_print_xerr(ccb_p cp, int x_status)
++void sym_print_xerr(struct scsi_cmnd *cmd, int x_status)
+ {
+ if (x_status & XE_PARITY_ERR) {
+- PRINT_ADDR(cp);
+- printf ("unrecovered SCSI parity error.\n");
++ sym_print_addr(cmd, "unrecovered SCSI parity error.\n");
+ }
+ if (x_status & XE_EXTRA_DATA) {
+- PRINT_ADDR(cp);
+- printf ("extraneous data discarded.\n");
++ sym_print_addr(cmd, "extraneous data discarded.\n");
+ }
+ if (x_status & XE_BAD_PHASE) {
+- PRINT_ADDR(cp);
+- printf ("illegal scsi phase (4/5).\n");
++ sym_print_addr(cmd, "illegal scsi phase (4/5).\n");
+ }
+ if (x_status & XE_SODL_UNRUN) {
+- PRINT_ADDR(cp);
+- printf ("ODD transfer in DATA OUT phase.\n");
++ sym_print_addr(cmd, "ODD transfer in DATA OUT phase.\n");
+ }
+ if (x_status & XE_SWIDE_OVRUN) {
+- PRINT_ADDR(cp);
+- printf ("ODD transfer in DATA IN phase.\n");
++ sym_print_addr(cmd, "ODD transfer in DATA IN phase.\n");
+ }
+ }
+
+@@ -186,10 +148,10 @@
+ */
+ static void sym_chip_reset (struct sym_hcb *np)
+ {
+- OUTB (nc_istat, SRST);
+- UDELAY (10);
+- OUTB (nc_istat, 0);
+- UDELAY(2000); /* For BUS MODE to settle */
++ OUTB(np, nc_istat, SRST);
++ udelay(10);
++ OUTB(np, nc_istat, 0);
++ udelay(2000); /* For BUS MODE to settle */
+ }
+
+ /*
+@@ -206,27 +168,27 @@
+ u_char istat = 0;
+ int i;
+
+- if (!(np->features & FE_ISTAT1) || !(INB (nc_istat1) & SCRUN))
++ if (!(np->features & FE_ISTAT1) || !(INB(np, nc_istat1) & SCRUN))
+ goto do_chip_reset;
+
+- OUTB (nc_istat, CABRT);
++ OUTB(np, nc_istat, CABRT);
+ for (i = 100000 ; i ; --i) {
+- istat = INB (nc_istat);
++ istat = INB(np, nc_istat);
+ if (istat & SIP) {
+- INW (nc_sist);
++ INW(np, nc_sist);
+ }
+ else if (istat & DIP) {
+- if (INB (nc_dstat) & ABRT)
++ if (INB(np, nc_dstat) & ABRT)
+ break;
+ }
+- UDELAY(5);
++ udelay(5);
+ }
+- OUTB (nc_istat, 0);
++ OUTB(np, nc_istat, 0);
+ if (!i)
+ printf("%s: unable to abort current chip operation, "
+ "ISTAT=0x%02x.\n", sym_name(np), istat);
+ do_chip_reset:
+- sym_chip_reset (np);
++ sym_chip_reset(np);
+ }
+
+ /*
+@@ -236,7 +198,7 @@
+ */
+ static void sym_start_reset(struct sym_hcb *np)
+ {
+- (void) sym_reset_scsi_bus(np, 1);
++ sym_reset_scsi_bus(np, 1);
+ }
+
+ int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int)
+@@ -246,15 +208,15 @@
+
+ sym_soft_reset(np); /* Soft reset the chip */
+ if (enab_int)
+- OUTW (nc_sien, RST);
++ OUTW(np, nc_sien, RST);
+ /*
+ * Enable Tolerant, reset IRQD if present and
+ * properly set IRQ mode, prior to resetting the bus.
+ */
+- OUTB (nc_stest3, TE);
+- OUTB (nc_dcntl, (np->rv_dcntl & IRQM));
+- OUTB (nc_scntl1, CRST);
+- UDELAY (200);
++ OUTB(np, nc_stest3, TE);
++ OUTB(np, nc_dcntl, (np->rv_dcntl & IRQM));
++ OUTB(np, nc_scntl1, CRST);
++ udelay(200);
+
+ if (!SYM_SETUP_SCSI_BUS_CHECK)
+ goto out;
+@@ -264,12 +226,12 @@
+ * We are expecting RESET to be TRUE and other signals to be
+ * FALSE.
+ */
+- term = INB(nc_sstat0);
++ term = INB(np, nc_sstat0);
+ term = ((term & 2) << 7) + ((term & 1) << 17); /* rst sdp0 */
+- term |= ((INB(nc_sstat2) & 0x01) << 26) | /* sdp1 */
+- ((INW(nc_sbdl) & 0xff) << 9) | /* d7-0 */
+- ((INW(nc_sbdl) & 0xff00) << 10) | /* d15-8 */
+- INB(nc_sbcl); /* req ack bsy sel atn msg cd io */
++ term |= ((INB(np, nc_sstat2) & 0x01) << 26) | /* sdp1 */
++ ((INW(np, nc_sbdl) & 0xff) << 9) | /* d7-0 */
++ ((INW(np, nc_sbdl) & 0xff00) << 10) | /* d15-8 */
++ INB(np, nc_sbcl); /* req ack bsy sel atn msg cd io */
+
+ if (!np->maxwide)
+ term &= 0x3ffff;
+@@ -286,7 +248,7 @@
+ retv = 1;
+ }
+ out:
+- OUTB (nc_scntl1, 0);
++ OUTB(np, nc_scntl1, 0);
+ return retv;
+ }
+
+@@ -299,31 +261,31 @@
+ * If multiplier not present or not selected, leave here.
+ */
+ if (np->multiplier <= 1) {
+- OUTB(nc_scntl3, scntl3);
++ OUTB(np, nc_scntl3, scntl3);
+ return;
+ }
+
+ if (sym_verbose >= 2)
+ printf ("%s: enabling clock multiplier\n", sym_name(np));
+
+- OUTB(nc_stest1, DBLEN); /* Enable clock multiplier */
++ OUTB(np, nc_stest1, DBLEN); /* Enable clock multiplier */
+ /*
+ * Wait for the LCKFRQ bit to be set if supported by the chip.
+ * Otherwise wait 50 micro-seconds (at least).
+ */
+ if (np->features & FE_LCKFRQ) {
+ int i = 20;
+- while (!(INB(nc_stest4) & LCKFRQ) && --i > 0)
+- UDELAY (20);
++ while (!(INB(np, nc_stest4) & LCKFRQ) && --i > 0)
++ udelay(20);
+ if (!i)
+ printf("%s: the chip cannot lock the frequency\n",
+ sym_name(np));
+ } else
+- UDELAY ((50+10));
+- OUTB(nc_stest3, HSC); /* Halt the scsi clock */
+- OUTB(nc_scntl3, scntl3);
+- OUTB(nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier */
+- OUTB(nc_stest3, 0x00); /* Restart scsi clock */
++ udelay((50+10));
++ OUTB(np, nc_stest3, HSC); /* Halt the scsi clock */
++ OUTB(np, nc_scntl3, scntl3);
++ OUTB(np, nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier */
++ OUTB(np, nc_stest3, 0x00); /* Restart scsi clock */
+ }
+
+
+@@ -368,38 +330,38 @@
+ * performed trust the higher delay
+ * (lower frequency returned).
+ */
+- OUTW (nc_sien , 0); /* mask all scsi interrupts */
+- (void) INW (nc_sist); /* clear pending scsi interrupt */
+- OUTB (nc_dien , 0); /* mask all dma interrupts */
+- (void) INW (nc_sist); /* another one, just to be sure :) */
++ OUTW(np, nc_sien, 0); /* mask all scsi interrupts */
++ INW(np, nc_sist); /* clear pending scsi interrupt */
++ OUTB(np, nc_dien, 0); /* mask all dma interrupts */
++ INW(np, nc_sist); /* another one, just to be sure :) */
+ /*
+ * The C1010-33 core does not report GEN in SIST,
+ * if this interrupt is masked in SIEN.
+ * I don't know yet if the C1010-66 behaves the same way.
+ */
+ if (np->features & FE_C10) {
+- OUTW (nc_sien, GEN);
+- OUTB (nc_istat1, SIRQD);
++ OUTW(np, nc_sien, GEN);
++ OUTB(np, nc_istat1, SIRQD);
+ }
+- OUTB (nc_scntl3, 4); /* set pre-scaler to divide by 3 */
+- OUTB (nc_stime1, 0); /* disable general purpose timer */
+- OUTB (nc_stime1, gen); /* set to nominal delay of 1<<gen * 125us */
+- while (!(INW(nc_sist) & GEN) && ms++ < 100000)
+- UDELAY (1000/4);/* count in 1/4 of ms */
+- OUTB (nc_stime1, 0); /* disable general purpose timer */
++ OUTB(np, nc_scntl3, 4); /* set pre-scaler to divide by 3 */
++ OUTB(np, nc_stime1, 0); /* disable general purpose timer */
++ OUTB(np, nc_stime1, gen); /* set to nominal delay of 1<<gen * 125us */
++ while (!(INW(np, nc_sist) & GEN) && ms++ < 100000)
++ udelay(1000/4); /* count in 1/4 of ms */
++ OUTB(np, nc_stime1, 0); /* disable general purpose timer */
+ /*
+ * Undo C1010-33 specific settings.
+ */
+ if (np->features & FE_C10) {
+- OUTW (nc_sien, 0);
+- OUTB (nc_istat1, 0);
++ OUTW(np, nc_sien, 0);
++ OUTB(np, nc_istat1, 0);
+ }
+ /*
+ * set prescaler to divide by whatever 0 means
+ * 0 ought to choose divide by 2, but appears
+ * to set divide by 3.5 mode in my 53c810 ...
+ */
+- OUTB (nc_scntl3, 0);
++ OUTB(np, nc_scntl3, 0);
+
+ /*
+ * adjust for prescaler, and convert into KHz
+@@ -425,7 +387,7 @@
+ u_int f1, f2;
+ int gen = 8;
+
+- (void) getfreq (np, gen); /* throw away first result */
++ getfreq (np, gen); /* throw away first result */
+ f1 = getfreq (np, gen);
+ f2 = getfreq (np, gen);
+ if (f1 > f2) f1 = f2; /* trust lower result */
+@@ -458,7 +420,7 @@
+ * Otherwise trust scntl3 BIOS setting.
+ */
+ if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) {
+- OUTB (nc_stest1, 0); /* make sure doubler is OFF */
++ OUTB(np, nc_stest1, 0); /* make sure doubler is OFF */
+ f1 = sym_getfreq (np);
+
+ if (sym_verbose)
+@@ -505,9 +467,9 @@
+ #else
+ if (1) {
+ #endif
+- OUTB (nc_stest1, SCLK); /* Use the PCI clock as SCSI clock */
+- f = (int) sym_getfreq (np);
+- OUTB (nc_stest1, 0);
++ OUTB(np, nc_stest1, SCLK); /* Use the PCI clock as SCSI clock */
++ f = sym_getfreq(np);
++ OUTB(np, nc_stest1, 0);
+ }
+ np->pciclk_khz = f;
+
+@@ -698,29 +660,29 @@
+ */
+ static void sym_save_initial_setting (struct sym_hcb *np)
+ {
+- np->sv_scntl0 = INB(nc_scntl0) & 0x0a;
+- np->sv_scntl3 = INB(nc_scntl3) & 0x07;
+- np->sv_dmode = INB(nc_dmode) & 0xce;
+- np->sv_dcntl = INB(nc_dcntl) & 0xa8;
+- np->sv_ctest3 = INB(nc_ctest3) & 0x01;
+- np->sv_ctest4 = INB(nc_ctest4) & 0x80;
+- np->sv_gpcntl = INB(nc_gpcntl);
+- np->sv_stest1 = INB(nc_stest1);
+- np->sv_stest2 = INB(nc_stest2) & 0x20;
+- np->sv_stest4 = INB(nc_stest4);
++ np->sv_scntl0 = INB(np, nc_scntl0) & 0x0a;
++ np->sv_scntl3 = INB(np, nc_scntl3) & 0x07;
++ np->sv_dmode = INB(np, nc_dmode) & 0xce;
++ np->sv_dcntl = INB(np, nc_dcntl) & 0xa8;
++ np->sv_ctest3 = INB(np, nc_ctest3) & 0x01;
++ np->sv_ctest4 = INB(np, nc_ctest4) & 0x80;
++ np->sv_gpcntl = INB(np, nc_gpcntl);
++ np->sv_stest1 = INB(np, nc_stest1);
++ np->sv_stest2 = INB(np, nc_stest2) & 0x20;
++ np->sv_stest4 = INB(np, nc_stest4);
+ if (np->features & FE_C10) { /* Always large DMA fifo + ultra3 */
+- np->sv_scntl4 = INB(nc_scntl4);
+- np->sv_ctest5 = INB(nc_ctest5) & 0x04;
++ np->sv_scntl4 = INB(np, nc_scntl4);
++ np->sv_ctest5 = INB(np, nc_ctest5) & 0x04;
+ }
+ else
+- np->sv_ctest5 = INB(nc_ctest5) & 0x24;
++ np->sv_ctest5 = INB(np, nc_ctest5) & 0x24;
+ }
+
+ /*
+ * Prepare io register values used by sym_start_up()
+ * according to selected and supported features.
+ */
+-static int sym_prepare_setting(struct sym_hcb *np, struct sym_nvram *nvram)
++static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram)
+ {
+ u_char burst_max;
+ u32 period;
+@@ -903,22 +865,20 @@
+ /*
+ * Select some other
+ */
+- if (SYM_SETUP_PCI_PARITY)
+- np->rv_ctest4 |= MPEE; /* Master parity checking */
+- if (SYM_SETUP_SCSI_PARITY)
+- np->rv_scntl0 |= 0x0a; /* full arb., ena parity, par->ATN */
++ np->rv_ctest4 |= MPEE; /* Master parity checking */
++ np->rv_scntl0 |= 0x0a; /* full arb., ena parity, par->ATN */
+
+ /*
+ * Get parity checking, host ID and verbose mode from NVRAM
+ */
+ np->myaddr = 255;
+- sym_nvram_setup_host (np, nvram);
++ sym_nvram_setup_host(shost, np, nvram);
+
+ /*
+ * Get SCSI addr of host adapter (set by bios?).
+ */
+ if (np->myaddr == 255) {
+- np->myaddr = INB(nc_scid) & 0x07;
++ np->myaddr = INB(np, nc_scid) & 0x07;
+ if (!np->myaddr)
+ np->myaddr = SYM_SETUP_HOST_ID;
+ }
+@@ -946,7 +906,7 @@
+ np->scsi_mode = SMODE_HVD;
+ }
+ else if (nvram->type == SYM_SYMBIOS_NVRAM) {
+- if (!(INB(nc_gpreg) & 0x08))
++ if (!(INB(np, nc_gpreg) & 0x08))
+ np->scsi_mode = SMODE_HVD;
+ }
+ }
+@@ -988,12 +948,12 @@
+ * If NVRAM present get targets setup from NVRAM.
+ */
+ for (i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {
+- tcb_p tp = &np->target[i];
++ struct sym_tcb *tp = &np->target[i];
+
+ 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(np, i, nvram);
+
+ if (!tp->usrtags)
+ tp->usrflags &= ~SYM_TAGS_ENABLED;
+@@ -1002,11 +962,8 @@
+ /*
+ * Let user know about the settings.
+ */
+- i = nvram->type;
+- printf("%s: %s NVRAM, ID %d, Fast-%d, %s, %s\n", sym_name(np),
+- i == SYM_SYMBIOS_NVRAM ? "Symbios" :
+- (i == SYM_TEKRAM_NVRAM ? "Tekram" : "No"),
+- np->myaddr,
++ printf("%s: %s, ID %d, Fast-%d, %s, %s\n", sym_name(np),
++ sym_nvram_type(nvram), np->myaddr,
+ (np->features & FE_ULTRA3) ? 80 :
+ (np->features & FE_ULTRA2) ? 40 :
+ (np->features & FE_ULTRA) ? 20 : 10,
+@@ -1055,7 +1012,7 @@
+ *
+ * Has to be called with interrupts disabled.
+ */
+-#ifndef SYM_CONF_IOMAPPED
++#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED
+ static int sym_regtest (struct sym_hcb *np)
+ {
+ register volatile u32 data;
+@@ -1065,8 +1022,8 @@
+ * and try to read it back.
+ */
+ data = 0xffffffff;
+- OUTL_OFF(offsetof(struct sym_reg, nc_dstat), data);
+- data = INL_OFF(offsetof(struct sym_reg, nc_dstat));
++ OUTL(np, nc_dstat, data);
++ data = INL(np, nc_dstat);
+ #if 1
+ if (data == 0xffffffff) {
+ #else
+@@ -1075,7 +1032,7 @@
+ printf ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n",
+ (unsigned) data);
+ return (0x10);
+- };
++ }
+ return (0);
+ }
+ #endif
+@@ -1084,7 +1041,7 @@
+ {
+ u32 sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat;
+ int i, err=0;
+-#ifndef SYM_CONF_IOMAPPED
++#ifndef CONFIG_SCSI_SYM53C8XX_IOMAPPED
+ err |= sym_regtest (np);
+ if (err) return (err);
+ #endif
+@@ -1093,37 +1050,37 @@
+ * Enable Master Parity Checking as we intend
+ * to enable it for normal operations.
+ */
+- OUTB (nc_ctest4, (np->rv_ctest4 & MPEE));
++ OUTB(np, nc_ctest4, (np->rv_ctest4 & MPEE));
+ /*
+ * init
+ */
+- pc = SCRIPTZ_BA (np, snooptest);
++ pc = SCRIPTZ_BA(np, snooptest);
+ host_wr = 1;
+ sym_wr = 2;
+ /*
+ * Set memory and register.
+ */
+ np->scratch = cpu_to_scr(host_wr);
+- OUTL (nc_temp, sym_wr);
++ OUTL(np, nc_temp, sym_wr);
+ /*
+ * Start script (exchange values)
+ */
+- OUTL (nc_dsa, np->hcb_ba);
+- OUTL_DSP (pc);
++ OUTL(np, nc_dsa, np->hcb_ba);
++ OUTL_DSP(np, pc);
+ /*
+ * Wait 'til done (with timeout)
+ */
+ for (i=0; i<SYM_SNOOP_TIMEOUT; i++)
+- if (INB(nc_istat) & (INTF|SIP|DIP))
++ if (INB(np, nc_istat) & (INTF|SIP|DIP))
+ break;
+ if (i>=SYM_SNOOP_TIMEOUT) {
+ printf ("CACHE TEST FAILED: timeout.\n");
+ return (0x20);
+- };
++ }
+ /*
+ * Check for fatal DMA errors.
+ */
+- dstat = INB (nc_dstat);
++ dstat = INB(np, nc_dstat);
+ #if 1 /* Band aiding for broken hardwares that fail PCI parity */
+ if ((dstat & MDPE) && (np->rv_ctest4 & MPEE)) {
+ printf ("%s: PCI DATA PARITY ERROR DETECTED - "
+@@ -1140,23 +1097,23 @@
+ /*
+ * Save termination position.
+ */
+- pc = INL (nc_dsp);
++ pc = INL(np, nc_dsp);
+ /*
+ * Read memory and register.
+ */
+ host_rd = scr_to_cpu(np->scratch);
+- sym_rd = INL (nc_scratcha);
+- sym_bk = INL (nc_temp);
++ sym_rd = INL(np, nc_scratcha);
++ sym_bk = INL(np, nc_temp);
+ /*
+ * Check termination position.
+ */
+- if (pc != SCRIPTZ_BA (np, snoopend)+8) {
++ if (pc != SCRIPTZ_BA(np, snoopend)+8) {
+ printf ("CACHE TEST FAILED: script execution failed.\n");
+ printf ("start=%08lx, pc=%08lx, end=%08lx\n",
+- (u_long) SCRIPTZ_BA (np, snooptest), (u_long) pc,
+- (u_long) SCRIPTZ_BA (np, snoopend) +8);
++ (u_long) SCRIPTZ_BA(np, snooptest), (u_long) pc,
++ (u_long) SCRIPTZ_BA(np, snoopend) +8);
+ return (0x40);
+- };
++ }
+ /*
+ * Show results.
+ */
+@@ -1164,17 +1121,17 @@
+ printf ("CACHE TEST FAILED: host wrote %d, chip read %d.\n",
+ (int) host_wr, (int) sym_rd);
+ err |= 1;
+- };
++ }
+ if (host_rd != sym_wr) {
+ printf ("CACHE TEST FAILED: chip wrote %d, host read %d.\n",
+ (int) sym_wr, (int) host_rd);
+ err |= 2;
+- };
++ }
+ if (sym_bk != sym_wr) {
+ printf ("CACHE TEST FAILED: chip wrote %d, read back %d.\n",
+ (int) sym_wr, (int) sym_bk);
+ err |= 4;
+- };
++ }
+
+ return (err);
+ }
+@@ -1215,7 +1172,7 @@
+ u_char *script_base;
+ int i;
+
+- dsp = INL (nc_dsp);
++ dsp = INL(np, nc_dsp);
+
+ if (dsp > np->scripta_ba &&
+ dsp <= np->scripta_ba + np->scripta_sz) {
+@@ -1238,12 +1195,12 @@
+ }
+
+ printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x/%x) @ (%s %x:%08x).\n",
+- sym_name (np), (unsigned)INB (nc_sdid)&0x0f, dstat, sist,
+- (unsigned)INB (nc_socl), (unsigned)INB (nc_sbcl),
+- (unsigned)INB (nc_sbdl), (unsigned)INB (nc_sxfer),
+- (unsigned)INB (nc_scntl3),
+- (np->features & FE_C10) ? (unsigned)INB (nc_scntl4) : 0,
+- script_name, script_ofs, (unsigned)INL (nc_dbc));
++ sym_name(np), (unsigned)INB(np, nc_sdid)&0x0f, dstat, sist,
++ (unsigned)INB(np, nc_socl), (unsigned)INB(np, nc_sbcl),
++ (unsigned)INB(np, nc_sbdl), (unsigned)INB(np, nc_sxfer),
++ (unsigned)INB(np, nc_scntl3),
++ (np->features & FE_C10) ? (unsigned)INB(np, nc_scntl4) : 0,
++ script_name, script_ofs, (unsigned)INL(np, nc_dbc));
+
+ if (((script_ofs & 3) == 0) &&
+ (unsigned)script_ofs < script_size) {
+@@ -1253,7 +1210,7 @@
+
+ printf ("%s: regdump:", sym_name(np));
+ for (i=0; i<24;i++)
+- printf (" %02x", (unsigned)INB_OFF(i));
++ printf (" %02x", (unsigned)INB_OFF(np, i));
+ printf (".\n");
+
+ /*
+@@ -1263,7 +1220,7 @@
+ sym_log_bus_error(np);
+ }
+
+-static struct sym_pci_chip sym_pci_dev_table[] = {
++static struct sym_chip sym_dev_table[] = {
+ {PCI_DEVICE_ID_NCR_53C810, 0x0f, "810", 4, 8, 4, 64,
+ FE_ERL}
+ ,
+@@ -1347,8 +1304,8 @@
+ FE_RAM|FE_IO256|FE_LEDC}
+ };
+
+-#define sym_pci_num_devs \
+- (sizeof(sym_pci_dev_table) / sizeof(sym_pci_dev_table[0]))
++#define sym_num_devs \
++ (sizeof(sym_dev_table) / sizeof(sym_dev_table[0]))
+
+ /*
+ * Look up the chip table.
+@@ -1356,14 +1313,14 @@
+ * Return a pointer to the chip entry if found,
+ * zero otherwise.
+ */
+-struct sym_pci_chip *
+-sym_lookup_pci_chip_table (u_short device_id, u_char revision)
++struct sym_chip *
++sym_lookup_chip_table (u_short device_id, u_char revision)
+ {
+- struct sym_pci_chip *chip;
++ struct sym_chip *chip;
+ int i;
+
+- for (i = 0; i < sym_pci_num_devs; i++) {
+- chip = &sym_pci_dev_table[i];
++ for (i = 0; i < sym_num_devs; i++) {
++ chip = &sym_dev_table[i];
+ if (device_id != chip->device_id)
+ continue;
+ if (revision > chip->revision_id)
+@@ -1421,7 +1378,7 @@
+ return;
+ o = offsetof(struct sym_reg, nc_scrx[0]);
+ for (i = 0; i < SYM_DMAP_SIZE; i++) {
+- OUTL_OFF(o, np->dmap_bah[i]);
++ OUTL_OFF(np, o, np->dmap_bah[i]);
+ o += 4;
+ }
+ np->dmap_dirty = 0;
+@@ -1429,52 +1386,52 @@
+ #endif
+
+ /* Enforce all the fiddly SPI rules and the chip limitations */
+-static void sym_check_goals(struct scsi_device *sdev)
++static void sym_check_goals(struct sym_hcb *np, struct scsi_target *starget,
++ struct sym_trans *goal)
+ {
+- struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb;
+- struct sym_trans *st = &np->target[sdev->id].tinfo.goal;
+-
+- if (!scsi_device_wide(sdev))
+- st->width = 0;
++ if (!spi_support_wide(starget))
++ goal->width = 0;
+
+- if (!scsi_device_sync(sdev)) {
+- st->options = 0;
+- st->period = 0;
+- st->offset = 0;
++ if (!spi_support_sync(starget)) {
++ goal->iu = 0;
++ goal->dt = 0;
++ goal->qas = 0;
++ goal->period = 0;
++ goal->offset = 0;
+ return;
+ }
+
+- if (scsi_device_dt(sdev)) {
+- if (scsi_device_dt_only(sdev))
+- st->options |= PPR_OPT_DT;
++ if (spi_support_dt(starget)) {
++ if (spi_support_dt_only(starget))
++ goal->dt = 1;
+
+- if (st->offset == 0)
+- st->options &= ~PPR_OPT_DT;
++ if (goal->offset == 0)
++ goal->dt = 0;
+ } else {
+- st->options &= ~PPR_OPT_DT;
++ goal->dt = 0;
+ }
+
+ /* Some targets fail to properly negotiate DT in SE mode */
+ if ((np->scsi_mode != SMODE_LVD) || !(np->features & FE_U3EN))
+- st->options &= ~PPR_OPT_DT;
++ goal->dt = 0;
+
+- if (st->options & PPR_OPT_DT) {
++ if (goal->dt) {
+ /* all DT transfers must be wide */
+- st->width = 1;
+- if (st->offset > np->maxoffs_dt)
+- st->offset = np->maxoffs_dt;
+- if (st->period < np->minsync_dt)
+- st->period = np->minsync_dt;
+- if (st->period > np->maxsync_dt)
+- st->period = np->maxsync_dt;
++ goal->width = 1;
++ if (goal->offset > np->maxoffs_dt)
++ goal->offset = np->maxoffs_dt;
++ if (goal->period < np->minsync_dt)
++ goal->period = np->minsync_dt;
++ if (goal->period > np->maxsync_dt)
++ goal->period = np->maxsync_dt;
+ } else {
+- st->options &= ~PPR_OPT_MASK;
+- if (st->offset > np->maxoffs)
+- st->offset = np->maxoffs;
+- if (st->period < np->minsync)
+- st->period = np->minsync;
+- if (st->period > np->maxsync)
+- st->period = np->maxsync;
++ goal->iu = goal->qas = 0;
++ if (goal->offset > np->maxoffs)
++ goal->offset = np->maxoffs;
++ if (goal->period < np->minsync)
++ goal->period = np->minsync;
++ if (goal->period > np->maxsync)
++ goal->period = np->maxsync;
+ }
+ }
+
+@@ -1485,30 +1442,29 @@
+ * negotiation and the nego_status field of the CCB.
+ * Returns the size of the message in bytes.
+ */
+-static int sym_prepare_nego(struct sym_hcb *np, ccb_p cp, u_char *msgptr)
++static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgptr)
+ {
+- tcb_p tp = &np->target[cp->target];
+- struct scsi_device *sdev = tp->sdev;
+- struct sym_trans *goal = &tp->tinfo.goal;
+- struct sym_trans *curr = &tp->tinfo.curr;
++ struct sym_tcb *tp = &np->target[cp->target];
++ struct scsi_target *starget = tp->sdev->sdev_target;
++ struct sym_trans *goal = &tp->tgoal;
+ int msglen = 0;
+ int nego;
+
+- if (likely(sdev))
+- sym_check_goals(sdev);
++ sym_check_goals(np, starget, goal);
+
+ /*
+ * Many devices implement PPR in a buggy way, so only use it if we
+ * really want to.
+ */
+- if ((goal->options & PPR_OPT_MASK) || (goal->period < 0xa)) {
++ if (goal->iu || goal->dt || goal->qas || (goal->period < 0xa)) {
+ nego = NS_PPR;
+- } else if (curr->width != goal->width) {
++ } else if (spi_width(starget) != goal->width) {
+ nego = NS_WIDE;
+- } else if (curr->period != goal->period ||
+- curr->offset != goal->offset) {
++ } else if (spi_period(starget) != goal->period ||
++ spi_offset(starget) != goal->offset) {
+ nego = NS_SYNC;
+ } else {
++ goal->check_nego = 0;
+ nego = 0;
+ }
+
+@@ -1534,9 +1490,11 @@
+ msgptr[msglen++] = 0;
+ msgptr[msglen++] = goal->offset;
+ msgptr[msglen++] = goal->width;
+- msgptr[msglen++] = goal->options & PPR_OPT_MASK;
++ msgptr[msglen++] = (goal->iu ? PPR_OPT_IU : 0) |
++ (goal->dt ? PPR_OPT_DT : 0) |
++ (goal->qas ? PPR_OPT_QAS : 0);
+ break;
+- };
++ }
+
+ cp->nego_status = nego;
+
+@@ -1547,8 +1505,8 @@
+ nego == NS_SYNC ? "sync msgout" :
+ nego == NS_WIDE ? "wide msgout" :
+ "ppr msgout", msgptr);
+- };
+- };
++ }
++ }
+
+ return msglen;
+ }
+@@ -1556,7 +1514,7 @@
+ /*
+ * Insert a job into the start queue.
+ */
+-void sym_put_start_queue(struct sym_hcb *np, ccb_p cp)
++void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
+ {
+ u_short qidx;
+
+@@ -1608,17 +1566,17 @@
+ * Wake it up.
+ */
+ MEMORY_WRITE_BARRIER();
+- OUTB (nc_istat, SIGP|np->istat_sem);
++ OUTB(np, nc_istat, SIGP|np->istat_sem);
+ }
+
+ #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
+ /*
+ * Start next ready-to-start CCBs.
+ */
+-void sym_start_next_ccbs(struct sym_hcb *np, lcb_p lp, int maxn)
++void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn)
+ {
+ SYM_QUEHEAD *qp;
+- ccb_p cp;
++ struct sym_ccb *cp;
+
+ /*
+ * Paranoia, as usual. :-)
+@@ -1643,7 +1601,7 @@
+ }
+ lp->itlq_tbl[cp->tag] = cpu_to_scr(cp->ccb_ba);
+ lp->head.resel_sa =
+- cpu_to_scr(SCRIPTA_BA (np, resel_tag));
++ cpu_to_scr(SCRIPTA_BA(np, resel_tag));
+ ++lp->started_tags;
+ } else {
+ if (lp->started_no_tag || lp->started_tags) {
+@@ -1652,7 +1610,7 @@
+ }
+ lp->head.itl_task_sa = cpu_to_scr(cp->ccb_ba);
+ lp->head.resel_sa =
+- cpu_to_scr(SCRIPTA_BA (np, resel_no_tag));
++ cpu_to_scr(SCRIPTA_BA(np, resel_no_tag));
+ ++lp->started_no_tag;
+ }
+ cp->started = 1;
+@@ -1671,7 +1629,7 @@
+ */
+ static int sym_wakeup_done (struct sym_hcb *np)
+ {
+- ccb_p cp;
++ struct sym_ccb *cp;
+ int i, n;
+ u32 dsa;
+
+@@ -1719,22 +1677,22 @@
+ static void sym_flush_comp_queue(struct sym_hcb *np, int cam_status)
+ {
+ SYM_QUEHEAD *qp;
+- ccb_p cp;
++ struct sym_ccb *cp;
+
+ while ((qp = sym_remque_head(&np->comp_ccbq)) != 0) {
+- struct scsi_cmnd *ccb;
++ struct scsi_cmnd *cmd;
+ cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
+ sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq);
+ /* Leave quiet CCBs waiting for resources */
+ if (cp->host_status == HS_WAIT)
+ continue;
+- ccb = cp->cam_ccb;
++ cmd = cp->cmd;
+ if (cam_status)
+- sym_set_cam_status(ccb, cam_status);
++ sym_set_cam_status(cmd, cam_status);
+ #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
+- if (sym_get_cam_status(ccb) == CAM_REQUEUE_REQ) {
+- tcb_p tp = &np->target[cp->target];
+- lcb_p lp = sym_lp(np, tp, cp->lun);
++ if (sym_get_cam_status(cmd) == CAM_REQUEUE_REQ) {
++ struct sym_tcb *tp = &np->target[cp->target];
++ struct sym_lcb *lp = sym_lp(tp, cp->lun);
+ if (lp) {
+ sym_remque(&cp->link2_ccbq);
+ sym_insque_tail(&cp->link2_ccbq,
+@@ -1751,8 +1709,7 @@
+ }
+ #endif
+ sym_free_ccb(np, cp);
+- sym_freeze_cam_ccb(ccb);
+- sym_xpt_done(np, ccb);
++ sym_xpt_done(np, cmd);
+ }
+ }
+
+@@ -1790,8 +1747,8 @@
+ if (reason == 1)
+ sym_soft_reset(np);
+ else {
+- OUTB (nc_stest3, TE|CSF);
+- OUTONB (nc_ctest3, CLF);
++ OUTB(np, nc_stest3, TE|CSF);
++ OUTONB(np, nc_ctest3, CLF);
+ }
+
+ /*
+@@ -1839,39 +1796,39 @@
+ /*
+ * Init chip.
+ */
+- OUTB (nc_istat, 0x00 ); /* Remove Reset, abort */
+- UDELAY (2000); /* The 895 needs time for the bus mode to settle */
++ OUTB(np, nc_istat, 0x00); /* Remove Reset, abort */
++ udelay(2000); /* The 895 needs time for the bus mode to settle */
+
+- OUTB (nc_scntl0, np->rv_scntl0 | 0xc0);
++ OUTB(np, nc_scntl0, np->rv_scntl0 | 0xc0);
+ /* full arb., ena parity, par->ATN */
+- OUTB (nc_scntl1, 0x00); /* odd parity, and remove CRST!! */
++ OUTB(np, nc_scntl1, 0x00); /* odd parity, and remove CRST!! */
+
+ sym_selectclock(np, np->rv_scntl3); /* Select SCSI clock */
+
+- OUTB (nc_scid , RRE|np->myaddr); /* Adapter SCSI address */
+- OUTW (nc_respid, 1ul<<np->myaddr); /* Id to respond to */
+- OUTB (nc_istat , SIGP ); /* Signal Process */
+- OUTB (nc_dmode , np->rv_dmode); /* Burst length, dma mode */
+- OUTB (nc_ctest5, np->rv_ctest5); /* Large fifo + large burst */
+-
+- OUTB (nc_dcntl , NOCOM|np->rv_dcntl); /* Protect SFBR */
+- OUTB (nc_ctest3, np->rv_ctest3); /* Write and invalidate */
+- OUTB (nc_ctest4, np->rv_ctest4); /* Master parity checking */
++ OUTB(np, nc_scid , RRE|np->myaddr); /* Adapter SCSI address */
++ OUTW(np, nc_respid, 1ul<<np->myaddr); /* Id to respond to */
++ OUTB(np, nc_istat , SIGP ); /* Signal Process */
++ OUTB(np, nc_dmode , np->rv_dmode); /* Burst length, dma mode */
++ OUTB(np, nc_ctest5, np->rv_ctest5); /* Large fifo + large burst */
++
++ OUTB(np, nc_dcntl , NOCOM|np->rv_dcntl); /* Protect SFBR */
++ OUTB(np, nc_ctest3, np->rv_ctest3); /* Write and invalidate */
++ OUTB(np, nc_ctest4, np->rv_ctest4); /* Master parity checking */
+
+ /* Extended Sreq/Sack filtering not supported on the C10 */
+ if (np->features & FE_C10)
+- OUTB (nc_stest2, np->rv_stest2);
++ OUTB(np, nc_stest2, np->rv_stest2);
+ else
+- OUTB (nc_stest2, EXT|np->rv_stest2);
++ OUTB(np, nc_stest2, EXT|np->rv_stest2);
+
+- OUTB (nc_stest3, TE); /* TolerANT enable */
+- OUTB (nc_stime0, 0x0c); /* HTH disabled STO 0.25 sec */
++ OUTB(np, nc_stest3, TE); /* TolerANT enable */
++ OUTB(np, nc_stime0, 0x0c); /* HTH disabled STO 0.25 sec */
+
+ /*
+ * For now, disable AIP generation on C1010-66.
+ */
+ if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66)
+- OUTB (nc_aipcntl1, DISAIP);
++ OUTB(np, nc_aipcntl1, DISAIP);
+
+ /*
+ * C10101 rev. 0 errata.
+@@ -1882,7 +1839,7 @@
+ */
+ if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 &&
+ np->revision_id < 1)
+- OUTB (nc_stest1, INB(nc_stest1) | 0x30);
++ OUTB(np, nc_stest1, INB(np, nc_stest1) | 0x30);
+
+ /*
+ * DEL 441 - 53C876 Rev 5 - Part Number 609-0392787/2788 - ITEM 2.
+@@ -1890,7 +1847,7 @@
+ * regardless revision id (kind of post-chip-design feature. ;-))
+ */
+ if (np->device_id == PCI_DEVICE_ID_NCR_53C875)
+- OUTB (nc_ctest0, (1<<5));
++ OUTB(np, nc_ctest0, (1<<5));
+ else if (np->device_id == PCI_DEVICE_ID_NCR_53C896)
+ np->rv_ccntl0 |= DPR;
+
+@@ -1900,8 +1857,8 @@
+ * seem to support those IO registers.
+ */
+ if (np->features & (FE_DAC|FE_NOPM)) {
+- OUTB (nc_ccntl0, np->rv_ccntl0);
+- OUTB (nc_ccntl1, np->rv_ccntl1);
++ OUTB(np, nc_ccntl0, np->rv_ccntl0);
++ OUTB(np, nc_ccntl1, np->rv_ccntl1);
+ }
+
+ #if SYM_CONF_DMA_ADDRESSING_MODE == 2
+@@ -1911,8 +1868,8 @@
+ */
+ if (np->use_dac) {
+ np->dmap_bah[0] = 0; /* ??? */
+- OUTL (nc_scrx[0], np->dmap_bah[0]);
+- OUTL (nc_drs, np->dmap_bah[0]);
++ OUTL(np, nc_scrx[0], np->dmap_bah[0]);
++ OUTL(np, nc_drs, np->dmap_bah[0]);
+ }
+ #endif
+
+@@ -1921,8 +1878,8 @@
+ * set PM jump addresses.
+ */
+ if (np->features & FE_NOPM) {
+- OUTL (nc_pmjad1, SCRIPTB_BA (np, pm_handle));
+- OUTL (nc_pmjad2, SCRIPTB_BA (np, pm_handle));
++ OUTL(np, nc_pmjad1, SCRIPTB_BA(np, pm_handle));
++ OUTL(np, nc_pmjad2, SCRIPTB_BA(np, pm_handle));
+ }
+
+ /*
+@@ -1930,15 +1887,15 @@
+ * Also set GPIO5 and clear GPIO6 if hardware LED control.
+ */
+ if (np->features & FE_LED0)
+- OUTB(nc_gpcntl, INB(nc_gpcntl) & ~0x01);
++ OUTB(np, nc_gpcntl, INB(np, nc_gpcntl) & ~0x01);
+ else if (np->features & FE_LEDC)
+- OUTB(nc_gpcntl, (INB(nc_gpcntl) & ~0x41) | 0x20);
++ OUTB(np, nc_gpcntl, (INB(np, nc_gpcntl) & ~0x41) | 0x20);
+
+ /*
+ * enable ints
+ */
+- OUTW (nc_sien , STO|HTH|MA|SGE|UDC|RST|PAR);
+- OUTB (nc_dien , MDPE|BF|SSI|SIR|IID);
++ OUTW(np, nc_sien , STO|HTH|MA|SGE|UDC|RST|PAR);
++ OUTB(np, nc_dien , MDPE|BF|SSI|SIR|IID);
+
+ /*
+ * For 895/6 enable SBMC interrupt and save current SCSI bus mode.
+@@ -1946,12 +1903,12 @@
+ * we reset the chip but not the SCSI BUS (at initialization).
+ */
+ if (np->features & (FE_ULTRA2|FE_ULTRA3)) {
+- OUTONW (nc_sien, SBMC);
++ OUTONW(np, nc_sien, SBMC);
+ if (reason == 0) {
+ mdelay(100);
+- INW (nc_sist);
++ INW(np, nc_sist);
+ }
+- np->scsi_mode = INB (nc_stest4) & SMODE;
++ np->scsi_mode = INB(np, nc_stest4) & SMODE;
+ }
+
+ /*
+@@ -1961,17 +1918,12 @@
+ * Prepare sync negotiation according to actual SCSI bus mode.
+ */
+ for (i=0;i<SYM_CONF_MAX_TARGET;i++) {
+- tcb_p tp = &np->target[i];
++ struct sym_tcb *tp = &np->target[i];
+
+ tp->to_reset = 0;
+ tp->head.sval = 0;
+ tp->head.wval = np->rv_scntl3;
+ tp->head.uval = 0;
+-
+- tp->tinfo.curr.period = 0;
+- tp->tinfo.curr.offset = 0;
+- tp->tinfo.curr.width = BUS_8_BIT;
+- tp->tinfo.curr.options = 0;
+ }
+
+ /*
+@@ -1981,29 +1933,25 @@
+ * For platforms that may not support PCI memory mapping,
+ * we use simple SCRIPTS that performs MEMORY MOVEs.
+ */
++ phys = SCRIPTA_BA(np, init);
+ if (np->ram_ba) {
+ if (sym_verbose >= 2)
+- printf ("%s: Downloading SCSI SCRIPTS.\n",
+- sym_name(np));
++ printf("%s: Downloading SCSI SCRIPTS.\n", sym_name(np));
++ memcpy_toio(np->s.ramaddr, np->scripta0, np->scripta_sz);
+ if (np->ram_ws == 8192) {
+- OUTRAM_OFF(4096, np->scriptb0, np->scriptb_sz);
+- phys = scr_to_cpu(np->scr_ram_seg);
+- OUTL (nc_mmws, phys);
+- OUTL (nc_mmrs, phys);
+- OUTL (nc_sfs, phys);
+- phys = SCRIPTB_BA (np, start64);
++ memcpy_toio(np->s.ramaddr + 4096, np->scriptb0, np->scriptb_sz);
++ phys = scr_to_cpu(np->scr_ram_seg);
++ OUTL(np, nc_mmws, phys);
++ OUTL(np, nc_mmrs, phys);
++ OUTL(np, nc_sfs, phys);
++ phys = SCRIPTB_BA(np, start64);
+ }
+- else
+- phys = SCRIPTA_BA (np, init);
+- OUTRAM_OFF(0, np->scripta0, np->scripta_sz);
+ }
+- else
+- phys = SCRIPTA_BA (np, init);
+
+ np->istat_sem = 0;
+
+- OUTL (nc_dsa, np->hcb_ba);
+- OUTL_DSP (phys);
++ OUTL(np, nc_dsa, np->hcb_ba);
++ OUTL_DSP(np, phys);
+
+ /*
+ * Notify the XPT about the RESET condition.
+@@ -2013,16 +1961,16 @@
+ }
+
+ /*
+- * Switch trans mode for current job and it's target.
++ * Switch trans mode for current job and its target.
+ */
+ static void sym_settrans(struct sym_hcb *np, int target, u_char opts, u_char ofs,
+ u_char per, u_char wide, u_char div, u_char fak)
+ {
+ SYM_QUEHEAD *qp;
+ u_char sval, wval, uval;
+- tcb_p tp = &np->target[target];
++ struct sym_tcb *tp = &np->target[target];
+
+- assert(target == (INB (nc_sdid) & 0x0f));
++ assert(target == (INB(np, nc_sdid) & 0x0f));
+
+ sval = tp->head.sval;
+ wval = tp->head.wval;
+@@ -2070,8 +2018,7 @@
+ assert(np->features & FE_U3EN);
+ uval |= U3EN;
+ }
+- }
+- else {
++ } else {
+ wval = wval & ~ULTRA;
+ if (per <= 12) wval |= ULTRA;
+ }
+@@ -2092,23 +2039,23 @@
+ * Not supported on the C1010.
+ */
+ if (per < 50 && !(np->features & FE_C10))
+- OUTOFFB (nc_stest2, EXT);
++ OUTOFFB(np, nc_stest2, EXT);
+
+ /*
+ * set actual value and sync_status
+ */
+- OUTB (nc_sxfer, tp->head.sval);
+- OUTB (nc_scntl3, tp->head.wval);
++ OUTB(np, nc_sxfer, tp->head.sval);
++ OUTB(np, nc_scntl3, tp->head.wval);
+
+ if (np->features & FE_C10) {
+- OUTB (nc_scntl4, tp->head.uval);
++ OUTB(np, nc_scntl4, tp->head.uval);
+ }
+
+ /*
+ * patch ALL busy ccbs of this target.
+ */
+ FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
+- ccb_p cp;
++ struct sym_ccb *cp;
+ cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
+ if (cp->target != target)
+ continue;
+@@ -2126,16 +2073,24 @@
+ */
+ static void sym_setwide(struct sym_hcb *np, int target, u_char wide)
+ {
+- tcb_p tp = &np->target[target];
++ struct sym_tcb *tp = &np->target[target];
++ struct scsi_target *starget = tp->sdev->sdev_target;
++
++ if (spi_width(starget) == wide)
++ return;
+
+ sym_settrans(np, target, 0, 0, 0, wide, 0, 0);
+
+- tp->tinfo.goal.width = tp->tinfo.curr.width = wide;
+- tp->tinfo.curr.offset = 0;
+- tp->tinfo.curr.period = 0;
+- tp->tinfo.curr.options = 0;
++ tp->tgoal.width = wide;
++ spi_offset(starget) = 0;
++ spi_period(starget) = 0;
++ spi_width(starget) = wide;
++ spi_iu(starget) = 0;
++ spi_dt(starget) = 0;
++ spi_qas(starget) = 0;
+
+- sym_xpt_async_nego_wide(np, target);
++ if (sym_verbose >= 3)
++ spi_display_xfer_agreement(starget);
+ }
+
+ /*
+@@ -2146,22 +2101,23 @@
+ sym_setsync(struct sym_hcb *np, int target,
+ u_char ofs, u_char per, u_char div, u_char fak)
+ {
+- tcb_p tp = &np->target[target];
++ struct sym_tcb *tp = &np->target[target];
++ struct scsi_target *starget = tp->sdev->sdev_target;
+ u_char wide = (tp->head.wval & EWS) ? BUS_16_BIT : BUS_8_BIT;
+
+ sym_settrans(np, target, 0, ofs, per, wide, div, fak);
+
+- tp->tinfo.curr.period = per;
+- tp->tinfo.curr.offset = ofs;
+- tp->tinfo.curr.options = 0;
++ spi_period(starget) = per;
++ spi_offset(starget) = ofs;
++ spi_iu(starget) = spi_dt(starget) = spi_qas(starget) = 0;
+
+- if (!(tp->tinfo.goal.options & PPR_OPT_MASK)) {
+- tp->tinfo.goal.period = per;
+- tp->tinfo.goal.offset = ofs;
+- tp->tinfo.goal.options = 0;
++ if (!tp->tgoal.dt && !tp->tgoal.iu && !tp->tgoal.qas) {
++ tp->tgoal.period = per;
++ tp->tgoal.offset = ofs;
++ tp->tgoal.check_nego = 0;
+ }
+
+- sym_xpt_async_nego_sync(np, target);
++ spi_display_xfer_agreement(starget);
+ }
+
+ /*
+@@ -2172,16 +2128,20 @@
+ sym_setpprot(struct sym_hcb *np, int target, u_char opts, u_char ofs,
+ u_char per, u_char wide, u_char div, u_char fak)
+ {
+- tcb_p tp = &np->target[target];
++ struct sym_tcb *tp = &np->target[target];
++ struct scsi_target *starget = tp->sdev->sdev_target;
+
+ sym_settrans(np, target, opts, ofs, per, wide, div, fak);
+
+- tp->tinfo.goal.width = tp->tinfo.curr.width = wide;
+- tp->tinfo.goal.period = tp->tinfo.curr.period = per;
+- tp->tinfo.goal.offset = tp->tinfo.curr.offset = ofs;
+- tp->tinfo.goal.options = tp->tinfo.curr.options = opts;
++ spi_width(starget) = tp->tgoal.width = wide;
++ spi_period(starget) = tp->tgoal.period = per;
++ spi_offset(starget) = tp->tgoal.offset = ofs;
++ spi_iu(starget) = tp->tgoal.iu = !!(opts & PPR_OPT_IU);
++ spi_dt(starget) = tp->tgoal.dt = !!(opts & PPR_OPT_DT);
++ spi_qas(starget) = tp->tgoal.qas = !!(opts & PPR_OPT_QAS);
++ tp->tgoal.check_nego = 0;
+
+- sym_xpt_async_nego_ppr(np, target);
++ spi_display_xfer_agreement(starget);
+ }
+
+ /*
+@@ -2212,25 +2172,25 @@
+ */
+ static void sym_recover_scsi_int (struct sym_hcb *np, u_char hsts)
+ {
+- u32 dsp = INL (nc_dsp);
+- u32 dsa = INL (nc_dsa);
+- ccb_p cp = sym_ccb_from_dsa(np, dsa);
++ u32 dsp = INL(np, nc_dsp);
++ u32 dsa = INL(np, nc_dsa);
++ struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa);
+
+ /*
+ * If we haven't been interrupted inside the SCRIPTS
+ * critical pathes, we can safely restart the SCRIPTS
+ * and trust the DSA value if it matches a CCB.
+ */
+- if ((!(dsp > SCRIPTA_BA (np, getjob_begin) &&
+- dsp < SCRIPTA_BA (np, getjob_end) + 1)) &&
+- (!(dsp > SCRIPTA_BA (np, ungetjob) &&
+- dsp < SCRIPTA_BA (np, reselect) + 1)) &&
+- (!(dsp > SCRIPTB_BA (np, sel_for_abort) &&
+- dsp < SCRIPTB_BA (np, sel_for_abort_1) + 1)) &&
+- (!(dsp > SCRIPTA_BA (np, done) &&
+- dsp < SCRIPTA_BA (np, done_end) + 1))) {
+- OUTB (nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */
+- OUTB (nc_stest3, TE|CSF); /* clear scsi fifo */
++ if ((!(dsp > SCRIPTA_BA(np, getjob_begin) &&
++ dsp < SCRIPTA_BA(np, getjob_end) + 1)) &&
++ (!(dsp > SCRIPTA_BA(np, ungetjob) &&
++ dsp < SCRIPTA_BA(np, reselect) + 1)) &&
++ (!(dsp > SCRIPTB_BA(np, sel_for_abort) &&
++ dsp < SCRIPTB_BA(np, sel_for_abort_1) + 1)) &&
++ (!(dsp > SCRIPTA_BA(np, done) &&
++ dsp < SCRIPTA_BA(np, done_end) + 1))) {
++ OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */
++ OUTB(np, nc_stest3, TE|CSF); /* clear scsi fifo */
+ /*
+ * If we have a CCB, let the SCRIPTS call us back for
+ * the handling of the error with SCRATCHA filled with
+@@ -2239,14 +2199,14 @@
+ */
+ if (cp) {
+ cp->host_status = hsts;
+- OUTL_DSP (SCRIPTA_BA (np, complete_error));
++ OUTL_DSP(np, SCRIPTA_BA(np, complete_error));
+ }
+ /*
+ * Otherwise just restart the SCRIPTS.
+ */
+ else {
+- OUTL (nc_dsa, 0xffffff);
+- OUTL_DSP (SCRIPTA_BA (np, start));
++ OUTL(np, nc_dsa, 0xffffff);
++ OUTL_DSP(np, SCRIPTA_BA(np, start));
+ }
+ }
+ else
+@@ -2263,11 +2223,11 @@
+ */
+ static void sym_int_sto (struct sym_hcb *np)
+ {
+- u32 dsp = INL (nc_dsp);
++ u32 dsp = INL(np, nc_dsp);
+
+ if (DEBUG_FLAGS & DEBUG_TINY) printf ("T");
+
+- if (dsp == SCRIPTA_BA (np, wf_sel_done) + 8)
++ if (dsp == SCRIPTA_BA(np, wf_sel_done) + 8)
+ sym_recover_scsi_int(np, HS_SEL_TIMEOUT);
+ else
+ sym_start_reset(np);
+@@ -2294,7 +2254,7 @@
+ */
+ static void sym_int_sbmc (struct sym_hcb *np)
+ {
+- u_char scsi_mode = INB (nc_stest4) & SMODE;
++ u_char scsi_mode = INB(np, nc_stest4) & SMODE;
+
+ /*
+ * Notify user.
+@@ -2335,14 +2295,14 @@
+ */
+ static void sym_int_par (struct sym_hcb *np, u_short sist)
+ {
+- u_char hsts = INB (HS_PRT);
+- u32 dsp = INL (nc_dsp);
+- u32 dbc = INL (nc_dbc);
+- u32 dsa = INL (nc_dsa);
+- u_char sbcl = INB (nc_sbcl);
++ u_char hsts = INB(np, HS_PRT);
++ u32 dsp = INL(np, nc_dsp);
++ u32 dbc = INL(np, nc_dbc);
++ u32 dsa = INL(np, nc_dsa);
++ u_char sbcl = INB(np, nc_sbcl);
+ u_char cmd = dbc >> 24;
+ int phase = cmd & 7;
+- ccb_p cp = sym_ccb_from_dsa(np, dsa);
++ struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa);
+
+ printf("%s: SCSI parity error detected: SCR1=%d DBC=%x SBCL=%x\n",
+ sym_name(np), hsts, dbc, sbcl);
+@@ -2350,7 +2310,7 @@
+ /*
+ * Check that the chip is connected to the SCSI BUS.
+ */
+- if (!(INB (nc_scntl1) & ISCON)) {
++ if (!(INB(np, nc_scntl1) & ISCON)) {
+ sym_recover_scsi_int(np, HS_UNEXPECTED);
+ return;
+ }
+@@ -2372,7 +2332,7 @@
+ /*
+ * Keep track of the parity error.
+ */
+- OUTONB (HF_PRT, HF_EXT_ERR);
++ OUTONB(np, HF_PRT, HF_EXT_ERR);
+ cp->xerr_status |= XE_PARITY_ERR;
+
+ /*
+@@ -2389,25 +2349,25 @@
+ */
+ if (phase == 1 || phase == 5) {
+ /* Phase mismatch handled by SCRIPTS */
+- if (dsp == SCRIPTB_BA (np, pm_handle))
+- OUTL_DSP (dsp);
++ if (dsp == SCRIPTB_BA(np, pm_handle))
++ OUTL_DSP(np, dsp);
+ /* Phase mismatch handled by the C code */
+ else if (sist & MA)
+ sym_int_ma (np);
+ /* No phase mismatch occurred */
+ else {
+ sym_set_script_dp (np, cp, dsp);
+- OUTL_DSP (SCRIPTA_BA (np, dispatch));
++ OUTL_DSP(np, SCRIPTA_BA(np, dispatch));
+ }
+ }
+ else if (phase == 7) /* We definitely cannot handle parity errors */
+ #if 1 /* in message-in phase due to the relection */
+ goto reset_all; /* path and various message anticipations. */
+ #else
+- OUTL_DSP (SCRIPTA_BA (np, clrack));
++ OUTL_DSP(np, SCRIPTA_BA(np, clrack));
+ #endif
+ else
+- OUTL_DSP (SCRIPTA_BA (np, dispatch));
++ OUTL_DSP(np, SCRIPTA_BA(np, dispatch));
+ return;
+
+ reset_all:
+@@ -2436,11 +2396,11 @@
+ u_char cmd;
+ u_char hflags, hflags0;
+ struct sym_pmc *pm;
+- ccb_p cp;
++ struct sym_ccb *cp;
+
+- dsp = INL (nc_dsp);
+- dbc = INL (nc_dbc);
+- dsa = INL (nc_dsa);
++ dsp = INL(np, nc_dsp);
++ dbc = INL(np, nc_dbc);
++ dsa = INL(np, nc_dsa);
+
+ cmd = dbc >> 24;
+ rest = dbc & 0xffffff;
+@@ -2461,14 +2421,14 @@
+ u_char ss0, ss2;
+
+ if (np->features & FE_DFBC)
+- delta = INW (nc_dfbc);
++ delta = INW(np, nc_dfbc);
+ else {
+ u32 dfifo;
+
+ /*
+ * Read DFIFO, CTEST[4-6] using 1 PCI bus ownership.
+ */
+- dfifo = INL(nc_dfifo);
++ dfifo = INL(np, nc_dfifo);
+
+ /*
+ * Calculate remaining bytes in DMA fifo.
+@@ -2488,29 +2448,29 @@
+ * Check the sstat2 register in case of wide transfer.
+ */
+ rest += delta;
+- ss0 = INB (nc_sstat0);
++ ss0 = INB(np, nc_sstat0);
+ if (ss0 & OLF) rest++;
+ if (!(np->features & FE_C10))
+ if (ss0 & ORF) rest++;
+ if (cp && (cp->phys.select.sel_scntl3 & EWS)) {
+- ss2 = INB (nc_sstat2);
++ ss2 = INB(np, nc_sstat2);
+ if (ss2 & OLF1) rest++;
+ if (!(np->features & FE_C10))
+ if (ss2 & ORF1) rest++;
+- };
++ }
+
+ /*
+ * Clear fifos.
+ */
+- OUTB (nc_ctest3, np->rv_ctest3 | CLF); /* dma fifo */
+- OUTB (nc_stest3, TE|CSF); /* scsi fifo */
++ OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* dma fifo */
++ OUTB(np, nc_stest3, TE|CSF); /* scsi fifo */
+ }
+
+ /*
+ * log the information
+ */
+ if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_PHASE))
+- printf ("P%x%x RL=%d D=%d ", cmd&7, INB(nc_sbcl)&7,
++ printf ("P%x%x RL=%d D=%d ", cmd&7, INB(np, nc_sbcl)&7,
+ (unsigned) rest, (unsigned) delta);
+
+ /*
+@@ -2536,7 +2496,7 @@
+ if (DEBUG_FLAGS & DEBUG_PHASE) {
+ printf ("\nCP=%p DSP=%x NXT=%x VDSP=%p CMD=%x ",
+ cp, (unsigned)dsp, (unsigned)nxtdsp, vdsp, cmd);
+- };
++ }
+
+ if (!vdsp) {
+ printf ("%s: interrupted SCRIPT address not found.\n",
+@@ -2562,7 +2522,7 @@
+ } else {
+ tblp = (u32 *) 0;
+ olen = scr_to_cpu(vdsp[0]) & 0xffffff;
+- };
++ }
+
+ if (DEBUG_FLAGS & DEBUG_PHASE) {
+ printf ("OCMD=%x\nTBLP=%p OLEN=%x OADR=%x\n",
+@@ -2570,7 +2530,7 @@
+ tblp,
+ (unsigned) olen,
+ (unsigned) oadr);
+- };
++ }
+
+ /*
+ * check cmd against assumed interrupted script command.
+@@ -2578,23 +2538,23 @@
+ * the phase.
+ */
+ if (((cmd & 2) ? cmd : (cmd & ~4)) != (scr_to_cpu(vdsp[0]) >> 24)) {
+- PRINT_ADDR(cp);
+- printf ("internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n",
+- (unsigned)cmd, (unsigned)scr_to_cpu(vdsp[0]) >> 24);
++ sym_print_addr(cp->cmd,
++ "internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n",
++ cmd, scr_to_cpu(vdsp[0]) >> 24);
+
+ goto reset_all;
+- };
++ }
+
+ /*
+ * if old phase not dataphase, leave here.
+ */
+ if (cmd & 2) {
+- PRINT_ADDR(cp);
+- printf ("phase change %x-%x %d@%08x resid=%d.\n",
+- cmd&7, INB(nc_sbcl)&7, (unsigned)olen,
++ sym_print_addr(cp->cmd,
++ "phase change %x-%x %d@%08x resid=%d.\n",
++ cmd&7, INB(np, nc_sbcl)&7, (unsigned)olen,
+ (unsigned)oadr, (unsigned)rest);
+ goto unexpected_phase;
+- };
++ }
+
+ /*
+ * Choose the correct PM save area.
+@@ -2604,7 +2564,7 @@
+ * SCRIPTS for the 895A, 896 and 1010 that are able to
+ * handle PM from the SCRIPTS processor.
+ */
+- hflags0 = INB (HF_PRT);
++ hflags0 = INB(np, HF_PRT);
+ hflags = hflags0;
+
+ if (hflags & (HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED)) {
+@@ -2619,16 +2579,16 @@
+
+ if (!(hflags & HF_ACT_PM)) {
+ pm = &cp->phys.pm0;
+- newcmd = SCRIPTA_BA (np, pm0_data);
++ newcmd = SCRIPTA_BA(np, pm0_data);
+ }
+ else {
+ pm = &cp->phys.pm1;
+- newcmd = SCRIPTA_BA (np, pm1_data);
++ newcmd = SCRIPTA_BA(np, pm1_data);
+ }
+
+ hflags &= ~(HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED);
+ if (hflags != hflags0)
+- OUTB (HF_PRT, hflags);
++ OUTB(np, HF_PRT, hflags);
+
+ /*
+ * fillin the phase mismatch context
+@@ -2643,9 +2603,9 @@
+ * - compute the SCRIPTS address to restart from,
+ * - move current data pointer context by one byte.
+ */
+- nxtdsp = SCRIPTA_BA (np, dispatch);
++ nxtdsp = SCRIPTA_BA(np, dispatch);
+ if ((cmd & 7) == 1 && cp && (cp->phys.select.sel_scntl3 & EWS) &&
+- (INB (nc_scntl2) & WSR)) {
++ (INB(np, nc_scntl2) & WSR)) {
+ u32 tmp;
+
+ /*
+@@ -2671,12 +2631,11 @@
+ * Prepare the address of SCRIPTS that will
+ * move the residual byte to memory.
+ */
+- nxtdsp = SCRIPTB_BA (np, wsr_ma_helper);
++ nxtdsp = SCRIPTB_BA(np, wsr_ma_helper);
+ }
+
+ if (DEBUG_FLAGS & DEBUG_PHASE) {
+- PRINT_ADDR(cp);
+- printf ("PM %x %x %x / %x %x %x.\n",
++ sym_print_addr(cp->cmd, "PM %x %x %x / %x %x %x.\n",
+ hflags0, hflags, newcmd,
+ (unsigned)scr_to_cpu(pm->sg.addr),
+ (unsigned)scr_to_cpu(pm->sg.size),
+@@ -2687,7 +2646,7 @@
+ * Restart the SCRIPTS processor.
+ */
+ sym_set_script_dp (np, cp, newcmd);
+- OUTL_DSP (nxtdsp);
++ OUTL_DSP(np, nxtdsp);
+ return;
+
+ /*
+@@ -2723,11 +2682,11 @@
+
+ switch (cmd & 7) {
+ case 2: /* COMMAND phase */
+- nxtdsp = SCRIPTA_BA (np, dispatch);
++ nxtdsp = SCRIPTA_BA(np, dispatch);
+ break;
+ #if 0
+ case 3: /* STATUS phase */
+- nxtdsp = SCRIPTA_BA (np, dispatch);
++ nxtdsp = SCRIPTA_BA(np, dispatch);
+ break;
+ #endif
+ case 6: /* MSG OUT phase */
+@@ -2737,30 +2696,34 @@
+ * since we will not be able to handle reselect.
+ * Otherwise, we just don't care.
+ */
+- if (dsp == SCRIPTA_BA (np, send_ident)) {
++ if (dsp == SCRIPTA_BA(np, send_ident)) {
+ if (cp->tag != NO_TAG && olen - rest <= 3) {
+ cp->host_status = HS_BUSY;
+ np->msgout[0] = IDENTIFY(0, cp->lun);
+- nxtdsp = SCRIPTB_BA (np, ident_break_atn);
++ nxtdsp = SCRIPTB_BA(np, ident_break_atn);
+ }
+ else
+- nxtdsp = SCRIPTB_BA (np, ident_break);
++ nxtdsp = SCRIPTB_BA(np, ident_break);
+ }
+- else if (dsp == SCRIPTB_BA (np, send_wdtr) ||
+- dsp == SCRIPTB_BA (np, send_sdtr) ||
+- dsp == SCRIPTB_BA (np, send_ppr)) {
+- nxtdsp = SCRIPTB_BA (np, nego_bad_phase);
++ else if (dsp == SCRIPTB_BA(np, send_wdtr) ||
++ dsp == SCRIPTB_BA(np, send_sdtr) ||
++ dsp == SCRIPTB_BA(np, send_ppr)) {
++ nxtdsp = SCRIPTB_BA(np, nego_bad_phase);
++ if (dsp == SCRIPTB_BA(np, send_ppr)) {
++ struct scsi_device *dev = cp->cmd->device;
++ dev->ppr = 0;
++ }
+ }
+ break;
+ #if 0
+ case 7: /* MSG IN phase */
+- nxtdsp = SCRIPTA_BA (np, clrack);
++ nxtdsp = SCRIPTA_BA(np, clrack);
+ break;
+ #endif
+ }
+
+ if (nxtdsp) {
+- OUTL_DSP (nxtdsp);
++ OUTL_DSP(np, nxtdsp);
+ return;
+ }
+
+@@ -2848,20 +2811,20 @@
+ * Note that SCRIPTS also (dummy) read to memory
+ * prior to deliver the INTF interrupt condition.
+ */
+- istat = INB (nc_istat);
++ istat = INB(np, nc_istat);
+ if (istat & INTF) {
+- OUTB (nc_istat, (istat & SIGP) | INTF | np->istat_sem);
+- istat = INB (nc_istat); /* DUMMY READ */
++ OUTB(np, nc_istat, (istat & SIGP) | INTF | np->istat_sem);
++ istat = INB(np, nc_istat); /* DUMMY READ */
+ if (DEBUG_FLAGS & DEBUG_TINY) printf ("F ");
+- (void)sym_wakeup_done (np);
+- };
++ sym_wakeup_done(np);
++ }
+
+ if (!(istat & (SIP|DIP)))
+ return;
+
+ #if 0 /* We should never get this one */
+ if (istat & CABRT)
+- OUTB (nc_istat, CABRT);
++ OUTB(np, nc_istat, CABRT);
+ #endif
+
+ /*
+@@ -2879,19 +2842,19 @@
+ istatc = istat;
+ do {
+ if (istatc & SIP)
+- sist |= INW (nc_sist);
++ sist |= INW(np, nc_sist);
+ if (istatc & DIP)
+- dstat |= INB (nc_dstat);
+- istatc = INB (nc_istat);
++ dstat |= INB(np, nc_dstat);
++ istatc = INB(np, nc_istat);
+ istat |= istatc;
+ } while (istatc & (SIP|DIP));
+
+ if (DEBUG_FLAGS & DEBUG_TINY)
+ printf ("<%d|%x:%x|%x:%x>",
+- (int)INB(nc_scr0),
++ (int)INB(np, nc_scr0),
+ dstat,sist,
+- (unsigned)INL(nc_dsp),
+- (unsigned)INL(nc_dbc));
++ (unsigned)INL(np, nc_dsp),
++ (unsigned)INL(np, nc_dbc));
+ /*
+ * On paper, a memory read barrier may be needed here to
+ * prevent out of order LOADs by the CPU from having
+@@ -2918,10 +2881,10 @@
+ if (sist & PAR) sym_int_par (np, sist);
+ else if (sist & MA) sym_int_ma (np);
+ else if (dstat & SIR) sym_int_sir (np);
+- else if (dstat & SSI) OUTONB_STD ();
++ else if (dstat & SSI) OUTONB_STD();
+ else goto unknown_int;
+ return;
+- };
++ }
+
+ /*
+ * Now, interrupts that donnot happen in normal
+@@ -2938,10 +2901,10 @@
+ printf("%s: SCSI BUS reset detected.\n", sym_name(np));
+ sym_start_up (np, 1);
+ return;
+- };
++ }
+
+- OUTB (nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */
+- OUTB (nc_stest3, TE|CSF); /* clear scsi fifo */
++ OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */
++ OUTB(np, nc_stest3, TE|CSF); /* clear scsi fifo */
+
+ if (!(sist & (GEN|HTH|SGE)) &&
+ !(dstat & (MDPE|BF|ABRT|IID))) {
+@@ -2950,7 +2913,7 @@
+ else if (sist & UDC) sym_int_udc (np);
+ else goto unknown_int;
+ return;
+- };
++ }
+
+ /*
+ * Now, interrupts we are not able to recover cleanly.
+@@ -2965,7 +2928,7 @@
+ (dstat & (MDPE|BF|ABRT|IID))) {
+ sym_start_reset(np);
+ return;
+- };
++ }
+
+ unknown_int:
+ /*
+@@ -2989,7 +2952,7 @@
+ sym_dequeue_from_squeue(struct sym_hcb *np, int i, int target, int lun, int task)
+ {
+ int j;
+- ccb_p cp;
++ struct sym_ccb *cp;
+
+ /*
+ * Make sure the starting index is within range.
+@@ -3011,7 +2974,7 @@
+ if ((target == -1 || cp->target == target) &&
+ (lun == -1 || cp->lun == lun) &&
+ (task == -1 || cp->tag == task)) {
+- sym_set_cam_status(cp->cam_ccb, CAM_REQUEUE_REQ);
++ sym_set_cam_status(cp->cmd, CAM_REQUEUE_REQ);
+ sym_remque(&cp->link_ccbq);
+ sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
+ }
+@@ -3047,9 +3010,8 @@
+ * SCRATCHA is assumed to have been loaded with STARTPOS
+ * before the SCRIPTS called the C code.
+ */
+-static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, ccb_p cp)
++static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, struct sym_ccb *cp)
+ {
+- tcb_p tp = &np->target[cp->target];
+ u32 startp;
+ u_char s_status = cp->ssss_status;
+ u_char h_flags = cp->host_flags;
+@@ -3059,7 +3021,7 @@
+ /*
+ * Compute the index of the next job to start from SCRIPTS.
+ */
+- i = (INL (nc_scratcha) - np->squeue_ba) / 4;
++ i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
+
+ /*
+ * The last CCB queued used for IARB hint may be
+@@ -3077,8 +3039,7 @@
+ case S_BUSY:
+ case S_QUEUE_FULL:
+ if (sym_verbose >= 2) {
+- PRINT_ADDR(cp);
+- printf ("%s\n",
++ sym_print_addr(cp->cmd, "%s\n",
+ s_status == S_BUSY ? "BUSY" : "QUEUE FULL\n");
+ }
+ default: /* S_INT, S_INT_COND_MET, S_CONFLICT */
+@@ -3098,8 +3059,8 @@
+ * Dequeue all queued CCBs for that device not yet started,
+ * and restart the SCRIPTS processor immediately.
+ */
+- (void) sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1);
+- OUTL_DSP (SCRIPTA_BA (np, start));
++ sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1);
++ OUTL_DSP(np, SCRIPTA_BA(np, start));
+
+ /*
+ * Save some info of the actual IO.
+@@ -3132,13 +3093,13 @@
+ /*
+ * Message table indirect structure.
+ */
+- cp->phys.smsg.addr = cpu_to_scr(CCB_BA (cp, scsi_smsg2));
++ cp->phys.smsg.addr = cpu_to_scr(CCB_BA(cp, scsi_smsg2));
+ cp->phys.smsg.size = cpu_to_scr(msglen);
+
+ /*
+ * sense command
+ */
+- cp->phys.cmd.addr = cpu_to_scr(CCB_BA (cp, sensecmd));
++ cp->phys.cmd.addr = cpu_to_scr(CCB_BA(cp, sensecmd));
+ cp->phys.cmd.size = cpu_to_scr(6);
+
+ /*
+@@ -3146,7 +3107,7 @@
+ */
+ cp->sensecmd[0] = REQUEST_SENSE;
+ cp->sensecmd[1] = 0;
+- if (tp->tinfo.curr.scsi_version <= 2 && cp->lun <= 7)
++ if (cp->cmd->device->scsi_level <= SCSI_2 && cp->lun <= 7)
+ cp->sensecmd[1] = cp->lun << 5;
+ cp->sensecmd[4] = SYM_SNS_BBUF_LEN;
+ cp->data_len = SYM_SNS_BBUF_LEN;
+@@ -3155,13 +3116,13 @@
+ * sense data
+ */
+ memset(cp->sns_bbuf, 0, SYM_SNS_BBUF_LEN);
+- cp->phys.sense.addr = cpu_to_scr(vtobus(cp->sns_bbuf));
++ cp->phys.sense.addr = cpu_to_scr(CCB_BA(cp, sns_bbuf));
+ cp->phys.sense.size = cpu_to_scr(SYM_SNS_BBUF_LEN);
+
+ /*
+ * requeue the command.
+ */
+- startp = SCRIPTB_BA (np, sdata_in);
++ startp = SCRIPTB_BA(np, sdata_in);
+
+ cp->phys.head.savep = cpu_to_scr(startp);
+ cp->phys.head.lastp = cpu_to_scr(startp);
+@@ -3175,7 +3136,7 @@
+ cp->xerr_status = 0;
+ cp->extra_bytes = 0;
+
+- cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA (np, select));
++ cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, select));
+
+ /*
+ * Requeue the command.
+@@ -3208,7 +3169,7 @@
+ {
+ SYM_QUEHEAD qtmp, *qp;
+ int i = 0;
+- ccb_p cp;
++ struct sym_ccb *cp;
+
+ /*
+ * Move the entire BUSY queue to our temporary queue.
+@@ -3223,9 +3184,9 @@
+ * the BUSY queue.
+ */
+ while ((qp = sym_remque_head(&qtmp)) != 0) {
+- struct scsi_cmnd *ccb;
++ struct scsi_cmnd *cmd;
+ cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
+- ccb = cp->cam_ccb;
++ cmd = cp->cmd;
+ if (cp->host_status != HS_DISCONNECT ||
+ cp->target != target ||
+ (lun != -1 && cp->lun != lun) ||
+@@ -3237,8 +3198,8 @@
+ sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
+
+ /* Preserve the software timeout condition */
+- if (sym_get_cam_status(ccb) != CAM_CMD_TIMEOUT)
+- sym_set_cam_status(ccb, cam_status);
++ if (sym_get_cam_status(cmd) != CAM_CMD_TIMEOUT)
++ sym_set_cam_status(cmd, cam_status);
+ ++i;
+ #if 0
+ printf("XXXX TASK @%p CLEARED\n", cp);
+@@ -3290,8 +3251,9 @@
+ static void sym_sir_task_recovery(struct sym_hcb *np, int num)
+ {
+ SYM_QUEHEAD *qp;
+- ccb_p cp;
+- tcb_p tp;
++ struct sym_ccb *cp;
++ struct sym_tcb *tp = NULL; /* gcc isn't quite smart enough yet */
++ struct scsi_target *starget;
+ int target=-1, lun=-1, task;
+ int i, k;
+
+@@ -3349,8 +3311,8 @@
+ np->abrt_sel.sel_id = target;
+ np->abrt_sel.sel_scntl3 = tp->head.wval;
+ np->abrt_sel.sel_sxfer = tp->head.sval;
+- OUTL(nc_dsa, np->hcb_ba);
+- OUTL_DSP (SCRIPTB_BA (np, sel_for_abort));
++ OUTL(np, nc_dsa, np->hcb_ba);
++ OUTL_DSP(np, SCRIPTB_BA(np, sel_for_abort));
+ return;
+ }
+
+@@ -3389,7 +3351,7 @@
+ * Remove the SEM flag from the ISTAT.
+ */
+ np->istat_sem = 0;
+- OUTB (nc_istat, SIGP);
++ OUTB(np, nc_istat, SIGP);
+ break;
+ }
+ /*
+@@ -3397,14 +3359,14 @@
+ * queue the SCRIPTS intends to start and dequeue
+ * all CCBs for that device that haven't been started.
+ */
+- i = (INL (nc_scratcha) - np->squeue_ba) / 4;
++ i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
+ i = sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1);
+
+ /*
+ * Make sure at least our IO to abort has been dequeued.
+ */
+ #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
+- assert(i && sym_get_cam_status(cp->cam_ccb) == CAM_REQUEUE_REQ);
++ assert(i && sym_get_cam_status(cp->cmd) == CAM_REQUEUE_REQ);
+ #else
+ sym_remque(&cp->link_ccbq);
+ sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq);
+@@ -3413,9 +3375,9 @@
+ * Keep track in cam status of the reason of the abort.
+ */
+ if (cp->to_abort == 2)
+- sym_set_cam_status(cp->cam_ccb, CAM_CMD_TIMEOUT);
++ sym_set_cam_status(cp->cmd, CAM_CMD_TIMEOUT);
+ else
+- sym_set_cam_status(cp->cam_ccb, CAM_REQ_ABORTED);
++ sym_set_cam_status(cp->cmd, CAM_REQ_ABORTED);
+
+ /*
+ * Complete with error everything that we have dequeued.
+@@ -3427,7 +3389,7 @@
+ * we may have some manual recovery to perform for.
+ */
+ case SIR_TARGET_SELECTED:
+- target = (INB (nc_sdid) & 0xf);
++ target = INB(np, nc_sdid) & 0xf;
+ tp = &np->target[target];
+
+ np->abrt_tbl.addr = cpu_to_scr(vtobus(np->abrt_msg));
+@@ -3463,7 +3425,7 @@
+ * an IDENTIFY(lun) + ABORT MESSAGE.
+ */
+ if (lun != -1) {
+- lcb_p lp = sym_lp(np, tp, lun);
++ struct sym_lcb *lp = sym_lp(tp, lun);
+ lp->to_clear = 0; /* We don't expect to fail here */
+ np->abrt_msg[0] = IDENTIFY(0, lun);
+ np->abrt_msg[1] = M_ABORT;
+@@ -3529,7 +3491,7 @@
+ * conditions not due to timeout.
+ */
+ if (cp->to_abort == 2)
+- sym_set_cam_status(cp->cam_ccb, CAM_CMD_TIMEOUT);
++ sym_set_cam_status(cp->cmd, CAM_CMD_TIMEOUT);
+ cp->to_abort = 0; /* We donnot expect to fail here */
+ break;
+
+@@ -3538,8 +3500,9 @@
+ * to BUS FREE phase as we expected.
+ */
+ case SIR_ABORT_SENT:
+- target = (INB (nc_sdid) & 0xf);
++ target = INB(np, nc_sdid) & 0xf;
+ tp = &np->target[target];
++ starget = tp->sdev->sdev_target;
+
+ /*
+ ** If we didn't abort anything, leave here.
+@@ -3561,10 +3524,13 @@
+ tp->head.sval = 0;
+ tp->head.wval = np->rv_scntl3;
+ tp->head.uval = 0;
+- tp->tinfo.curr.period = 0;
+- tp->tinfo.curr.offset = 0;
+- tp->tinfo.curr.width = BUS_8_BIT;
+- tp->tinfo.curr.options = 0;
++ spi_period(starget) = 0;
++ spi_offset(starget) = 0;
++ spi_width(starget) = 0;
++ spi_iu(starget) = 0;
++ spi_dt(starget) = 0;
++ spi_qas(starget) = 0;
++ tp->tgoal.check_nego = 1;
+ }
+
+ /*
+@@ -3583,9 +3549,9 @@
+ * Complete all the CCBs the device should have
+ * aborted due to our 'kiss of death' message.
+ */
+- i = (INL (nc_scratcha) - np->squeue_ba) / 4;
+- (void) sym_dequeue_from_squeue(np, i, target, lun, -1);
+- (void) sym_clear_tasks(np, CAM_REQ_ABORTED, target, lun, task);
++ i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
++ sym_dequeue_from_squeue(np, i, target, lun, -1);
++ sym_clear_tasks(np, CAM_REQ_ABORTED, target, lun, task);
+ sym_flush_comp_queue(np, 0);
+
+ /*
+@@ -3600,16 +3566,15 @@
+ * Print to the log the message we intend to send.
+ */
+ if (num == SIR_TARGET_SELECTED) {
+- PRINT_TARGET(np, target);
+- sym_printl_hex("control msgout:", np->abrt_msg,
+- np->abrt_tbl.size);
++ dev_info(&tp->sdev->sdev_target->dev, "control msgout:");
++ sym_printl_hex(np->abrt_msg, np->abrt_tbl.size);
+ np->abrt_tbl.size = cpu_to_scr(np->abrt_tbl.size);
+ }
+
+ /*
+ * Let the SCRIPTS processor continue.
+ */
+- OUTONB_STD ();
++ OUTONB_STD();
+ }
+
+ /*
+@@ -3617,7 +3582,7 @@
+ * pointer for both MDP and the residual calculation.
+ *
+ * I didn't want to bloat the code by more than 200
+- * lignes for the handling of both MDP and the residual.
++ * lines for the handling of both MDP and the residual.
+ * This has been achieved by using a data pointer
+ * representation consisting in an index in the data
+ * array (dp_sg) and a negative offset (dp_ofs) that
+@@ -3639,7 +3604,7 @@
+ * the corresponding values of dp_sg and dp_ofs.
+ */
+
+-static int sym_evaluate_dp(struct sym_hcb *np, ccb_p cp, u32 scr, int *ofs)
++static int sym_evaluate_dp(struct sym_hcb *np, struct sym_ccb *cp, u32 scr, int *ofs)
+ {
+ u32 dp_scr;
+ int dp_ofs, dp_sg, dp_sgmin;
+@@ -3652,9 +3617,9 @@
+ */
+ dp_scr = scr;
+ dp_ofs = *ofs;
+- if (dp_scr == SCRIPTA_BA (np, pm0_data))
++ if (dp_scr == SCRIPTA_BA(np, pm0_data))
+ pm = &cp->phys.pm0;
+- else if (dp_scr == SCRIPTA_BA (np, pm1_data))
++ else if (dp_scr == SCRIPTA_BA(np, pm1_data))
+ pm = &cp->phys.pm1;
+ else
+ pm = NULL;
+@@ -3757,7 +3722,7 @@
+ * is equivalent to a MODIFY DATA POINTER (offset=-1).
+ */
+
+-static void sym_modify_dp(struct sym_hcb *np, tcb_p tp, ccb_p cp, int ofs)
++static void sym_modify_dp(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp, int ofs)
+ {
+ int dp_ofs = ofs;
+ u32 dp_scr = sym_get_script_dp (np, cp);
+@@ -3800,23 +3765,23 @@
+ /*
+ * Get a context for the new current data pointer.
+ */
+- hflags = INB (HF_PRT);
++ hflags = INB(np, HF_PRT);
+
+ if (hflags & HF_DP_SAVED)
+ hflags ^= HF_ACT_PM;
+
+ if (!(hflags & HF_ACT_PM)) {
+ pm = &cp->phys.pm0;
+- dp_scr = SCRIPTA_BA (np, pm0_data);
++ dp_scr = SCRIPTA_BA(np, pm0_data);
+ }
+ else {
+ pm = &cp->phys.pm1;
+- dp_scr = SCRIPTA_BA (np, pm1_data);
++ dp_scr = SCRIPTA_BA(np, pm1_data);
+ }
+
+ hflags &= ~(HF_DP_SAVED);
+
+- OUTB (HF_PRT, hflags);
++ OUTB(np, HF_PRT, hflags);
+
+ /*
+ * Set up the new current data pointer.
+@@ -3833,11 +3798,11 @@
+
+ out_ok:
+ sym_set_script_dp (np, cp, dp_scr);
+- OUTL_DSP (SCRIPTA_BA (np, clrack));
++ OUTL_DSP(np, SCRIPTA_BA(np, clrack));
+ return;
+
+ out_reject:
+- OUTL_DSP (SCRIPTB_BA (np, msg_bad));
++ OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
+ }
+
+
+@@ -3856,7 +3821,7 @@
+ * a relevant information. :)
+ */
+
+-int sym_compute_residual(struct sym_hcb *np, ccb_p cp)
++int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp)
+ {
+ int dp_sg, dp_sgmin, resid = 0;
+ int dp_ofs = 0;
+@@ -3956,13 +3921,14 @@
+ * chip handler for SYNCHRONOUS DATA TRANSFER REQUEST (SDTR) message.
+ */
+ static int
+-sym_sync_nego_check(struct sym_hcb *np, int req, int target)
++sym_sync_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp)
+ {
++ int target = cp->target;
+ u_char chg, ofs, per, fak, div;
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+ sym_print_nego_msg(np, target, "sync msgin", np->msgin);
+- };
++ }
+
+ /*
+ * Get requested values.
+@@ -3992,9 +3958,9 @@
+ goto reject_it;
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+- PRINT_TARGET(np, target);
+- printf ("sdtr: ofs=%d per=%d div=%d fak=%d chg=%d.\n",
+- ofs, per, div, fak, chg);
++ sym_print_addr(cp->cmd,
++ "sdtr: ofs=%d per=%d div=%d fak=%d chg=%d.\n",
++ ofs, per, div, fak, chg);
+ }
+
+ /*
+@@ -4037,7 +4003,7 @@
+ return -1;
+ }
+
+-static void sym_sync_nego(struct sym_hcb *np, tcb_p tp, ccb_p cp)
++static void sym_sync_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
+ {
+ int req = 1;
+ int result;
+@@ -4045,8 +4011,8 @@
+ /*
+ * Request or answer ?
+ */
+- if (INB (HS_PRT) == HS_NEGOTIATE) {
+- OUTB (HS_PRT, HS_BUSY);
++ if (INB(np, HS_PRT) == HS_NEGOTIATE) {
++ OUTB(np, HS_PRT, HS_BUSY);
+ if (cp->nego_status && cp->nego_status != NS_SYNC)
+ goto reject_it;
+ req = 0;
+@@ -4055,19 +4021,19 @@
+ /*
+ * Check and apply new values.
+ */
+- result = sym_sync_nego_check(np, req, cp->target);
++ result = sym_sync_nego_check(np, req, cp);
+ if (result) /* Not acceptable, reject it */
+ goto reject_it;
+ if (req) { /* Was a request, send response. */
+ cp->nego_status = NS_SYNC;
+- OUTL_DSP (SCRIPTB_BA (np, sdtr_resp));
++ OUTL_DSP(np, SCRIPTB_BA(np, sdtr_resp));
+ }
+ else /* Was a response, we are done. */
+- OUTL_DSP (SCRIPTA_BA (np, clrack));
++ OUTL_DSP(np, SCRIPTA_BA(np, clrack));
+ return;
+
+ reject_it:
+- OUTL_DSP (SCRIPTB_BA (np, msg_bad));
++ OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
+ }
+
+ /*
+@@ -4076,7 +4042,7 @@
+ static int
+ sym_ppr_nego_check(struct sym_hcb *np, int req, int target)
+ {
+- tcb_p tp = &np->target[target];
++ struct sym_tcb *tp = &np->target[target];
+ unsigned char fak, div;
+ int dt, chg = 0;
+
+@@ -4096,10 +4062,7 @@
+ chg = 1;
+ wide = np->maxwide;
+ }
+- if (!wide || !(np->features & FE_ULTRA3))
+- opts = 0;
+-
+- if (!(np->features & FE_U3EN)) /* Broken U3EN bit not supported */
++ if (!wide || !(np->features & FE_U3EN))
+ opts = 0;
+
+ if (opts != (np->msgin[7] & PPR_OPT_MASK))
+@@ -4175,15 +4138,16 @@
+ * ST, we may want to try a legacy negotiation later.
+ */
+ if (!req && !opts) {
+- tp->tinfo.goal.options = 0;
+- tp->tinfo.goal.width = wide;
+- tp->tinfo.goal.period = per;
+- tp->tinfo.goal.offset = ofs;
++ tp->tgoal.period = per;
++ tp->tgoal.offset = ofs;
++ tp->tgoal.width = wide;
++ tp->tgoal.iu = tp->tgoal.dt = tp->tgoal.qas = 0;
++ tp->tgoal.check_nego = 1;
+ }
+ return -1;
+ }
+
+-static void sym_ppr_nego(struct sym_hcb *np, tcb_p tp, ccb_p cp)
++static void sym_ppr_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
+ {
+ int req = 1;
+ int result;
+@@ -4191,8 +4155,8 @@
+ /*
+ * Request or answer ?
+ */
+- if (INB (HS_PRT) == HS_NEGOTIATE) {
+- OUTB (HS_PRT, HS_BUSY);
++ if (INB(np, HS_PRT) == HS_NEGOTIATE) {
++ OUTB(np, HS_PRT, HS_BUSY);
+ if (cp->nego_status && cp->nego_status != NS_PPR)
+ goto reject_it;
+ req = 0;
+@@ -4206,27 +4170,28 @@
+ goto reject_it;
+ if (req) { /* Was a request, send response. */
+ cp->nego_status = NS_PPR;
+- OUTL_DSP (SCRIPTB_BA (np, ppr_resp));
++ OUTL_DSP(np, SCRIPTB_BA(np, ppr_resp));
+ }
+ else /* Was a response, we are done. */
+- OUTL_DSP (SCRIPTA_BA (np, clrack));
++ OUTL_DSP(np, SCRIPTA_BA(np, clrack));
+ return;
+
+ reject_it:
+- OUTL_DSP (SCRIPTB_BA (np, msg_bad));
++ OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
+ }
+
+ /*
+ * chip handler for WIDE DATA TRANSFER REQUEST (WDTR) message.
+ */
+ static int
+-sym_wide_nego_check(struct sym_hcb *np, int req, int target)
++sym_wide_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp)
+ {
++ int target = cp->target;
+ u_char chg, wide;
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+ sym_print_nego_msg(np, target, "wide msgin", np->msgin);
+- };
++ }
+
+ /*
+ * Get requested values.
+@@ -4243,8 +4208,8 @@
+ }
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+- PRINT_TARGET(np, target);
+- printf ("wdtr: wide=%d chg=%d.\n", wide, chg);
++ sym_print_addr(cp->cmd, "wdtr: wide=%d chg=%d.\n",
++ wide, chg);
+ }
+
+ /*
+@@ -4285,7 +4250,7 @@
+ return -1;
+ }
+
+-static void sym_wide_nego(struct sym_hcb *np, tcb_p tp, ccb_p cp)
++static void sym_wide_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
+ {
+ int req = 1;
+ int result;
+@@ -4293,8 +4258,8 @@
+ /*
+ * Request or answer ?
+ */
+- if (INB (HS_PRT) == HS_NEGOTIATE) {
+- OUTB (HS_PRT, HS_BUSY);
++ if (INB(np, HS_PRT) == HS_NEGOTIATE) {
++ OUTB(np, HS_PRT, HS_BUSY);
+ if (cp->nego_status && cp->nego_status != NS_WIDE)
+ goto reject_it;
+ req = 0;
+@@ -4303,25 +4268,24 @@
+ /*
+ * Check and apply new values.
+ */
+- result = sym_wide_nego_check(np, req, cp->target);
++ result = sym_wide_nego_check(np, req, cp);
+ if (result) /* Not acceptable, reject it */
+ goto reject_it;
+ if (req) { /* Was a request, send response. */
+ cp->nego_status = NS_WIDE;
+- OUTL_DSP (SCRIPTB_BA (np, wdtr_resp));
+- }
+- else { /* Was a response. */
++ OUTL_DSP(np, SCRIPTB_BA(np, wdtr_resp));
++ } else { /* Was a response. */
+ /*
+ * Negotiate for SYNC immediately after WIDE response.
+ * This allows to negotiate for both WIDE and SYNC on
+ * a single SCSI command (Suggested by Justin Gibbs).
+ */
+- if (tp->tinfo.goal.offset) {
++ if (tp->tgoal.offset) {
+ np->msgout[0] = M_EXTENDED;
+ np->msgout[1] = 3;
+ np->msgout[2] = M_X_SYNC_REQ;
+- np->msgout[3] = tp->tinfo.goal.period;
+- np->msgout[4] = tp->tinfo.goal.offset;
++ np->msgout[3] = tp->tgoal.period;
++ np->msgout[4] = tp->tgoal.offset;
+
+ if (DEBUG_FLAGS & DEBUG_NEGO) {
+ sym_print_nego_msg(np, cp->target,
+@@ -4329,18 +4293,17 @@
+ }
+
+ cp->nego_status = NS_SYNC;
+- OUTB (HS_PRT, HS_NEGOTIATE);
+- OUTL_DSP (SCRIPTB_BA (np, sdtr_resp));
++ OUTB(np, HS_PRT, HS_NEGOTIATE);
++ OUTL_DSP(np, SCRIPTB_BA(np, sdtr_resp));
+ return;
+- }
+- else
+- OUTL_DSP (SCRIPTA_BA (np, clrack));
+- };
++ } else
++ OUTL_DSP(np, SCRIPTA_BA(np, clrack));
++ }
+
+ return;
+
+ reject_it:
+- OUTL_DSP (SCRIPTB_BA (np, msg_bad));
++ OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
+ }
+
+ /*
+@@ -4354,18 +4317,19 @@
+ * So, if a PPR makes problems, we may just want to
+ * try a legacy negotiation later.
+ */
+-static void sym_nego_default(struct sym_hcb *np, tcb_p tp, ccb_p cp)
++static void sym_nego_default(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
+ {
+ switch (cp->nego_status) {
+ case NS_PPR:
+ #if 0
+ sym_setpprot (np, cp->target, 0, 0, 0, 0, 0, 0);
+ #else
+- tp->tinfo.goal.options = 0;
+- if (tp->tinfo.goal.period < np->minsync)
+- tp->tinfo.goal.period = np->minsync;
+- if (tp->tinfo.goal.offset > np->maxoffs)
+- tp->tinfo.goal.offset = np->maxoffs;
++ if (tp->tgoal.period < np->minsync)
++ tp->tgoal.period = np->minsync;
++ if (tp->tgoal.offset > np->maxoffs)
++ tp->tgoal.offset = np->maxoffs;
++ tp->tgoal.iu = tp->tgoal.dt = tp->tgoal.qas = 0;
++ tp->tgoal.check_nego = 1;
+ #endif
+ break;
+ case NS_SYNC:
+@@ -4374,7 +4338,7 @@
+ case NS_WIDE:
+ sym_setwide (np, cp->target, 0);
+ break;
+- };
++ }
+ np->msgin [0] = M_NOOP;
+ np->msgout[0] = M_NOOP;
+ cp->nego_status = 0;
+@@ -4384,10 +4348,10 @@
+ * chip handler for MESSAGE REJECT received in response to
+ * PPR, WIDE or SYNCHRONOUS negotiation.
+ */
+-static void sym_nego_rejected(struct sym_hcb *np, tcb_p tp, ccb_p cp)
++static void sym_nego_rejected(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp)
+ {
+ sym_nego_default(np, tp, cp);
+- OUTB (HS_PRT, HS_BUSY);
++ OUTB(np, HS_PRT, HS_BUSY);
+ }
+
+ /*
+@@ -4395,11 +4359,11 @@
+ */
+ static void sym_int_sir (struct sym_hcb *np)
+ {
+- u_char num = INB (nc_dsps);
+- u32 dsa = INL (nc_dsa);
+- ccb_p cp = sym_ccb_from_dsa(np, dsa);
+- u_char target = INB (nc_sdid) & 0x0f;
+- tcb_p tp = &np->target[target];
++ u_char num = INB(np, nc_dsps);
++ u32 dsa = INL(np, nc_dsa);
++ struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa);
++ u_char target = INB(np, nc_sdid) & 0x0f;
++ struct sym_tcb *tp = &np->target[target];
+ int tmp;
+
+ if (DEBUG_FLAGS & DEBUG_TINY) printf ("I#%d", num);
+@@ -4497,7 +4461,7 @@
+ if (cp) {
+ cp->xerr_status &= ~XE_PARITY_ERR;
+ if (!cp->xerr_status)
+- OUTOFFB (HF_PRT, HF_EXT_ERR);
++ OUTOFFB(np, HF_PRT, HF_EXT_ERR);
+ }
+ }
+ goto out;
+@@ -4527,7 +4491,7 @@
+ */
+ case SIR_SWIDE_OVERRUN:
+ if (cp) {
+- OUTONB (HF_PRT, HF_EXT_ERR);
++ OUTONB(np, HF_PRT, HF_EXT_ERR);
+ cp->xerr_status |= XE_SWIDE_OVRUN;
+ }
+ goto out;
+@@ -4538,7 +4502,7 @@
+ */
+ case SIR_SODL_UNDERRUN:
+ if (cp) {
+- OUTONB (HF_PRT, HF_EXT_ERR);
++ OUTONB(np, HF_PRT, HF_EXT_ERR);
+ cp->xerr_status |= XE_SODL_UNRUN;
+ }
+ goto out;
+@@ -4550,9 +4514,9 @@
+ */
+ case SIR_DATA_OVERRUN:
+ if (cp) {
+- OUTONB (HF_PRT, HF_EXT_ERR);
++ OUTONB(np, HF_PRT, HF_EXT_ERR);
+ cp->xerr_status |= XE_EXTRA_DATA;
+- cp->extra_bytes += INL (nc_scratcha);
++ cp->extra_bytes += INL(np, nc_scratcha);
+ }
+ goto out;
+ /*
+@@ -4560,7 +4524,7 @@
+ */
+ case SIR_BAD_PHASE:
+ if (cp) {
+- OUTONB (HF_PRT, HF_EXT_ERR);
++ OUTONB(np, HF_PRT, HF_EXT_ERR);
+ cp->xerr_status |= XE_BAD_PHASE;
+ }
+ goto out;
+@@ -4609,16 +4573,16 @@
+ if (DEBUG_FLAGS & DEBUG_POINTER)
+ sym_print_msg(cp,"ign wide residue", np->msgin);
+ if (cp->host_flags & HF_SENSE)
+- OUTL_DSP (SCRIPTA_BA (np, clrack));
++ OUTL_DSP(np, SCRIPTA_BA(np, clrack));
+ else
+ sym_modify_dp(np, tp, cp, -1);
+ return;
+ case M_REJECT:
+- if (INB (HS_PRT) == HS_NEGOTIATE)
++ if (INB(np, HS_PRT) == HS_NEGOTIATE)
+ sym_nego_rejected(np, tp, cp);
+ else {
+- PRINT_ADDR(cp);
+- printf ("M_REJECT received (%x:%x).\n",
++ sym_print_addr(cp->cmd,
++ "M_REJECT received (%x:%x).\n",
+ scr_to_cpu(np->lastmsg), np->msgout[0]);
+ }
+ goto out_clrack;
+@@ -4633,7 +4597,7 @@
+ */
+ case SIR_MSG_WEIRD:
+ sym_print_msg(cp, "WEIRD message received", np->msgin);
+- OUTL_DSP (SCRIPTB_BA (np, msg_weird));
++ OUTL_DSP(np, SCRIPTB_BA(np, msg_weird));
+ return;
+ /*
+ * Negotiation failed.
+@@ -4641,7 +4605,7 @@
+ * Remove the HS_NEGOTIATE status.
+ */
+ case SIR_NEGO_FAILED:
+- OUTB (HS_PRT, HS_BUSY);
++ OUTB(np, HS_PRT, HS_BUSY);
+ /*
+ * Negotiation failed.
+ * Target does not want answer message.
+@@ -4649,16 +4613,16 @@
+ case SIR_NEGO_PROTO:
+ sym_nego_default(np, tp, cp);
+ goto out;
+- };
++ }
+
+ out:
+- OUTONB_STD ();
++ OUTONB_STD();
+ return;
+ out_reject:
+- OUTL_DSP (SCRIPTB_BA (np, msg_bad));
++ OUTL_DSP(np, SCRIPTB_BA(np, msg_bad));
+ return;
+ out_clrack:
+- OUTL_DSP (SCRIPTA_BA (np, clrack));
++ OUTL_DSP(np, SCRIPTA_BA(np, clrack));
+ return;
+ out_stuck:
+ return;
+@@ -4667,19 +4631,21 @@
+ /*
+ * Acquire a control block
+ */
+-ccb_p sym_get_ccb (struct sym_hcb *np, u_char tn, u_char ln, u_char tag_order)
++struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order)
+ {
+- tcb_p tp = &np->target[tn];
+- lcb_p lp = sym_lp(np, tp, ln);
++ u_char tn = cmd->device->id;
++ u_char ln = cmd->device->lun;
++ struct sym_tcb *tp = &np->target[tn];
++ struct sym_lcb *lp = sym_lp(tp, ln);
+ u_short tag = NO_TAG;
+ SYM_QUEHEAD *qp;
+- ccb_p cp = (ccb_p) 0;
++ struct sym_ccb *cp = NULL;
+
+ /*
+ * Look for a free CCB
+ */
+ if (sym_que_empty(&np->free_ccbq))
+- (void) sym_alloc_ccb(np);
++ sym_alloc_ccb(np);
+ qp = sym_remque_head(&np->free_ccbq);
+ if (!qp)
+ goto out;
+@@ -4741,7 +4707,7 @@
+ #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
+ lp->itlq_tbl[tag] = cpu_to_scr(cp->ccb_ba);
+ lp->head.resel_sa =
+- cpu_to_scr(SCRIPTA_BA (np, resel_tag));
++ cpu_to_scr(SCRIPTA_BA(np, resel_tag));
+ #endif
+ #ifdef SYM_OPT_LIMIT_COMMAND_REORDERING
+ cp->tags_si = lp->tags_si;
+@@ -4774,7 +4740,7 @@
+ if (lp->busy_itl == 1) {
+ lp->head.itl_task_sa = cpu_to_scr(cp->ccb_ba);
+ lp->head.resel_sa =
+- cpu_to_scr(SCRIPTA_BA (np, resel_no_tag));
++ cpu_to_scr(SCRIPTA_BA(np, resel_no_tag));
+ }
+ else
+ goto out_free;
+@@ -4802,28 +4768,27 @@
+ cp->lun = ln;
+
+ if (DEBUG_FLAGS & DEBUG_TAGS) {
+- PRINT_LUN(np, tn, ln);
+- printf ("ccb @%p using tag %d.\n", cp, tag);
++ sym_print_addr(cmd, "ccb @%p using tag %d.\n", cp, tag);
+ }
+
+ out:
+ return cp;
+ out_free:
+ sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
+- return (ccb_p) 0;
++ return NULL;
+ }
+
+ /*
+ * Release one control block
+ */
+-void sym_free_ccb (struct sym_hcb *np, ccb_p cp)
++void sym_free_ccb (struct sym_hcb *np, struct sym_ccb *cp)
+ {
+- tcb_p tp = &np->target[cp->target];
+- lcb_p lp = sym_lp(np, tp, cp->lun);
++ struct sym_tcb *tp = &np->target[cp->target];
++ struct sym_lcb *lp = sym_lp(tp, cp->lun);
+
+ if (DEBUG_FLAGS & DEBUG_TAGS) {
+- PRINT_LUN(np, cp->target, cp->lun);
+- printf ("ccb @%p freeing tag %d.\n", cp, cp->tag);
++ sym_print_addr(cp->cmd, "ccb @%p freeing tag %d.\n",
++ cp, cp->tag);
+ }
+
+ /*
+@@ -4862,7 +4827,7 @@
+ */
+ if (lp->busy_itlq == 0 && lp->busy_itl == 0)
+ lp->head.resel_sa =
+- cpu_to_scr(SCRIPTB_BA (np, resel_bad_lun));
++ cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
+ }
+ /*
+ * Otherwise, we only accept 1 IO per LUN.
+@@ -4889,14 +4854,9 @@
+ #endif
+
+ /*
+- * Unmap user data from DMA map if needed.
+- */
+- sym_data_dmamap_unload(np, cp);
+-
+- /*
+ * Make this CCB available.
+ */
+- cp->cam_ccb = NULL;
++ cp->cmd = NULL;
+ cp->host_status = HS_IDLE;
+ sym_remque(&cp->link_ccbq);
+ sym_insque_head(&cp->link_ccbq, &np->free_ccbq);
+@@ -4919,9 +4879,9 @@
+ /*
+ * Allocate a CCB from memory and initialize its fixed part.
+ */
+-static ccb_p sym_alloc_ccb(struct sym_hcb *np)
++static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np)
+ {
+- ccb_p cp = NULL;
++ struct sym_ccb *cp = NULL;
+ int hcode;
+
+ /*
+@@ -4939,19 +4899,6 @@
+ goto out_free;
+
+ /*
+- * Allocate a bounce buffer for sense data.
+- */
+- cp->sns_bbuf = sym_calloc_dma(SYM_SNS_BBUF_LEN, "SNS_BBUF");
+- if (!cp->sns_bbuf)
+- goto out_free;
+-
+- /*
+- * Allocate a map for the DMA of user data.
+- */
+- if (sym_data_dmamap_create(np, cp))
+- goto out_free;
+-
+- /*
+ * Count it.
+ */
+ np->actccbs++;
+@@ -4971,8 +4918,8 @@
+ /*
+ * Initialyze the start and restart actions.
+ */
+- cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA (np, idle));
+- cp->phys.head.go.restart = cpu_to_scr(SCRIPTB_BA (np, bad_i_t_l));
++ cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, idle));
++ cp->phys.head.go.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
+
+ /*
+ * Initilialyze some other fields.
+@@ -4992,21 +4939,18 @@
+ #endif
+ return cp;
+ out_free:
+- if (cp) {
+- if (cp->sns_bbuf)
+- sym_mfree_dma(cp->sns_bbuf,SYM_SNS_BBUF_LEN,"SNS_BBUF");
++ if (cp)
+ sym_mfree_dma(cp, sizeof(*cp), "CCB");
+- }
+ return NULL;
+ }
+
+ /*
+ * Look up a CCB from a DSA value.
+ */
+-static ccb_p sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa)
++static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa)
+ {
+ int hcode;
+- ccb_p cp;
++ struct sym_ccb *cp;
+
+ hcode = CCB_HASH_CODE(dsa);
+ cp = np->ccbh[hcode];
+@@ -5039,10 +4983,10 @@
+ /*
+ * Lun control block allocation and initialization.
+ */
+-lcb_p sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
++struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
+ {
+- tcb_p tp = &np->target[tn];
+- lcb_p lp = sym_lp(np, tp, ln);
++ struct sym_tcb *tp = &np->target[tn];
++ struct sym_lcb *lp = sym_lp(tp, ln);
+
+ /*
+ * Already done, just return.
+@@ -5081,8 +5025,8 @@
+ * Allocate the table of pointers for LUN(s) > 0, if needed.
+ */
+ if (ln && !tp->lunmp) {
+- tp->lunmp = sym_calloc(SYM_CONF_MAX_LUN * sizeof(lcb_p),
+- "LUNMP");
++ tp->lunmp = kcalloc(SYM_CONF_MAX_LUN, sizeof(struct sym_lcb *),
++ GFP_KERNEL);
+ if (!tp->lunmp)
+ goto fail;
+ }
+@@ -5111,7 +5055,7 @@
+ /*
+ * Set the reselect pattern to our default. :)
+ */
+- lp->head.resel_sa = cpu_to_scr(SCRIPTB_BA (np, resel_bad_lun));
++ lp->head.resel_sa = cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
+
+ /*
+ * Set user capabilities.
+@@ -5143,8 +5087,8 @@
+ */
+ static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln)
+ {
+- tcb_p tp = &np->target[tn];
+- lcb_p lp = sym_lp(np, tp, ln);
++ struct sym_tcb *tp = &np->target[tn];
++ struct sym_lcb *lp = sym_lp(tp, ln);
+ int i;
+
+ /*
+@@ -5160,7 +5104,7 @@
+ lp->itlq_tbl = sym_calloc_dma(SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
+ if (!lp->itlq_tbl)
+ goto fail;
+- lp->cb_tags = sym_calloc(SYM_CONF_MAX_TASK, "CB_TAGS");
++ lp->cb_tags = kcalloc(SYM_CONF_MAX_TASK, 1, GFP_KERNEL);
+ if (!lp->cb_tags) {
+ sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, "ITLQ_TBL");
+ lp->itlq_tbl = NULL;
+@@ -5193,10 +5137,11 @@
+ /*
+ * Queue a SCSI IO to the controller.
+ */
+-int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *csio, ccb_p cp)
++int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
+ {
+- tcb_p tp;
+- lcb_p lp;
++ struct scsi_device *sdev = cmd->device;
++ struct sym_tcb *tp;
++ struct sym_lcb *lp;
+ u_char *msgptr;
+ u_int msglen;
+ int can_disconnect;
+@@ -5204,7 +5149,7 @@
+ /*
+ * Keep track of the IO in our CCB.
+ */
+- cp->cam_ccb = csio;
++ cp->cmd = cmd;
+
+ /*
+ * Retrieve the target descriptor.
+@@ -5214,14 +5159,14 @@
+ /*
+ * Retrieve the lun descriptor.
+ */
+- lp = sym_lp(np, tp, cp->lun);
++ lp = sym_lp(tp, sdev->lun);
+
+ can_disconnect = (cp->tag != NO_TAG) ||
+ (lp && (lp->curr_flags & SYM_DISC_ENABLED));
+
+ msgptr = cp->scsi_smsg;
+ msglen = 0;
+- msgptr[msglen++] = IDENTIFY(can_disconnect, cp->lun);
++ msgptr[msglen++] = IDENTIFY(can_disconnect, sdev->lun);
+
+ /*
+ * Build the tag message if present.
+@@ -5249,8 +5194,8 @@
+ if (lp->tags_sum[lp->tags_si]) {
+ order = M_ORDERED_TAG;
+ if ((DEBUG_FLAGS & DEBUG_TAGS)||sym_verbose>1) {
+- PRINT_ADDR(cp);
+- printf("ordered tag forced.\n");
++ sym_print_addr(cmd,
++ "ordered tag forced.\n");
+ }
+ }
+ lp->tags_since = 0;
+@@ -5277,19 +5222,15 @@
+ * (nego_status is filled by sym_prepare_nego())
+ */
+ cp->nego_status = 0;
+- if (tp->tinfo.curr.width != tp->tinfo.goal.width ||
+- tp->tinfo.curr.period != tp->tinfo.goal.period ||
+- tp->tinfo.curr.offset != tp->tinfo.goal.offset ||
+- tp->tinfo.curr.options != tp->tinfo.goal.options) {
+- if (!tp->nego_cp && lp)
+- msglen += sym_prepare_nego(np, cp, msgptr + msglen);
++ if (tp->tgoal.check_nego && !tp->nego_cp && lp) {
++ msglen += sym_prepare_nego(np, cp, msgptr + msglen);
+ }
+
+ /*
+ * Startqueue
+ */
+- cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA (np, select));
+- cp->phys.head.go.restart = cpu_to_scr(SCRIPTA_BA (np, resel_dsa));
++ cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, select));
++ cp->phys.head.go.restart = cpu_to_scr(SCRIPTA_BA(np, resel_dsa));
+
+ /*
+ * select
+@@ -5302,7 +5243,7 @@
+ /*
+ * message
+ */
+- cp->phys.smsg.addr = cpu_to_scr(CCB_BA (cp, scsi_smsg));
++ cp->phys.smsg.addr = cpu_to_scr(CCB_BA(cp, scsi_smsg));
+ cp->phys.smsg.size = cpu_to_scr(msglen);
+
+ /*
+@@ -5326,7 +5267,7 @@
+ * Build the CDB and DATA descriptor block
+ * and start the IO.
+ */
+- return sym_setup_data_and_start(np, csio, cp);
++ return sym_setup_data_and_start(np, cmd, cp);
+ }
+
+ /*
+@@ -5334,7 +5275,7 @@
+ */
+ int sym_reset_scsi_target(struct sym_hcb *np, int target)
+ {
+- tcb_p tp;
++ struct sym_tcb *tp;
+
+ if (target == np->myaddr || (u_int)target >= SYM_CONF_MAX_TARGET)
+ return -1;
+@@ -5343,7 +5284,7 @@
+ tp->to_reset = 1;
+
+ np->istat_sem = SEM;
+- OUTB (nc_istat, SIGP|SEM);
++ OUTB(np, nc_istat, SIGP|SEM);
+
+ return 0;
+ }
+@@ -5351,7 +5292,7 @@
+ /*
+ * Abort a SCSI IO.
+ */
+-int sym_abort_ccb(struct sym_hcb *np, ccb_p cp, int timed_out)
++static int sym_abort_ccb(struct sym_hcb *np, struct sym_ccb *cp, int timed_out)
+ {
+ /*
+ * Check that the IO is active.
+@@ -5377,13 +5318,13 @@
+ * Tell the SCRIPTS processor to stop and synchronize with us.
+ */
+ np->istat_sem = SEM;
+- OUTB (nc_istat, SIGP|SEM);
++ OUTB(np, nc_istat, SIGP|SEM);
+ return 0;
+ }
+
+-int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *ccb, int timed_out)
++int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, int timed_out)
+ {
+- ccb_p cp;
++ struct sym_ccb *cp;
+ SYM_QUEHEAD *qp;
+
+ /*
+@@ -5391,8 +5332,8 @@
+ */
+ cp = NULL;
+ FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
+- ccb_p cp2 = sym_que_entry(qp, struct sym_ccb, link_ccbq);
+- if (cp2->cam_ccb == ccb) {
++ struct sym_ccb *cp2 = sym_que_entry(qp, struct sym_ccb, link_ccbq);
++ if (cp2->cmd == cmd) {
+ cp = cp2;
+ break;
+ }
+@@ -5411,37 +5352,40 @@
+ * SCRATCHA is assumed to have been loaded with STARTPOS
+ * before the SCRIPTS called the C code.
+ */
+-void sym_complete_error (struct sym_hcb *np, ccb_p cp)
++void sym_complete_error(struct sym_hcb *np, struct sym_ccb *cp)
+ {
+- tcb_p tp;
+- lcb_p lp;
++ struct scsi_device *sdev;
++ struct scsi_cmnd *cmd;
++ struct sym_tcb *tp;
++ struct sym_lcb *lp;
+ int resid;
+ int i;
+
+ /*
+ * Paranoid check. :)
+ */
+- if (!cp || !cp->cam_ccb)
++ if (!cp || !cp->cmd)
+ return;
+
++ cmd = cp->cmd;
++ sdev = cmd->device;
+ if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_RESULT)) {
+- printf ("CCB=%lx STAT=%x/%x/%x DEV=%d/%d\n", (unsigned long)cp,
+- cp->host_status, cp->ssss_status, cp->host_flags,
+- cp->target, cp->lun);
++ dev_info(&sdev->sdev_gendev, "CCB=%p STAT=%x/%x/%x\n", cp,
++ cp->host_status, cp->ssss_status, cp->host_flags);
+ }
+
+ /*
+ * Get target and lun pointers.
+ */
+ tp = &np->target[cp->target];
+- lp = sym_lp(np, tp, cp->lun);
++ lp = sym_lp(tp, sdev->lun);
+
+ /*
+ * Check for extended errors.
+ */
+ if (cp->xerr_status) {
+ if (sym_verbose)
+- sym_print_xerr(cp, cp->xerr_status);
++ sym_print_xerr(cmd, cp->xerr_status);
+ if (cp->host_status == HS_COMPLETE)
+ cp->host_status = HS_COMP_ERR;
+ }
+@@ -5464,13 +5408,13 @@
+ * Dequeue all queued CCBs for that device
+ * not yet started by SCRIPTS.
+ */
+- i = (INL (nc_scratcha) - np->squeue_ba) / 4;
+- i = sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1);
++ i = (INL(np, nc_scratcha) - np->squeue_ba) / 4;
++ i = sym_dequeue_from_squeue(np, i, cp->target, sdev->lun, -1);
+
+ /*
+ * Restart the SCRIPTS processor.
+ */
+- OUTL_DSP (SCRIPTA_BA (np, start));
++ OUTL_DSP(np, SCRIPTA_BA(np, start));
+
+ #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
+ if (cp->host_status == HS_COMPLETE &&
+@@ -5484,8 +5428,8 @@
+ lp->num_sgood = 0;
+
+ if (sym_verbose >= 2) {
+- PRINT_LUN(np, cp->target, cp->lun);
+- printf(" queue depth is now %d\n", lp->started_max);
++ sym_print_addr(cmd, " queue depth is now %d\n",
++ lp->started_max);
+ }
+
+ /*
+@@ -5497,17 +5441,12 @@
+ /*
+ * Let's requeue it to device.
+ */
+- sym_set_cam_status(cp->cam_ccb, CAM_REQUEUE_REQ);
++ sym_set_cam_status(cmd, CAM_REQUEUE_REQ);
+ goto finish;
+ }
+ weirdness:
+ #endif
+ /*
+- * Synchronize DMA map if needed.
+- */
+- sym_data_dmamap_postsync(np, cp);
+-
+- /*
+ * Build result in CAM ccb.
+ */
+ sym_set_cam_result_error(np, cp, resid);
+@@ -5545,30 +5484,30 @@
+ * The SCRIPTS processor is running while we are
+ * completing successful commands.
+ */
+-void sym_complete_ok (struct sym_hcb *np, ccb_p cp)
++void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp)
+ {
+- tcb_p tp;
+- lcb_p lp;
+- struct scsi_cmnd *ccb;
++ struct sym_tcb *tp;
++ struct sym_lcb *lp;
++ struct scsi_cmnd *cmd;
+ int resid;
+
+ /*
+ * Paranoid check. :)
+ */
+- if (!cp || !cp->cam_ccb)
++ if (!cp || !cp->cmd)
+ return;
+ assert (cp->host_status == HS_COMPLETE);
+
+ /*
+ * Get user command.
+ */
+- ccb = cp->cam_ccb;
++ cmd = cp->cmd;
+
+ /*
+ * Get target and lun pointers.
+ */
+ tp = &np->target[cp->target];
+- lp = sym_lp(np, tp, cp->lun);
++ lp = sym_lp(tp, cp->lun);
+
+ /*
+ * Assume device discovered on first success.
+@@ -5586,8 +5525,8 @@
+
+ /*
+ * Wrong transfer residuals may be worse than just always
+- * returning zero. User can disable this feature from
+- * sym_conf.h. Residual support is enabled by default.
++ * returning zero. User can disable this feature in
++ * sym53c8xx.h. Residual support is enabled by default.
+ */
+ if (!SYM_SETUP_RESIDUAL_SUPPORT)
+ resid = 0;
+@@ -5597,14 +5536,9 @@
+ #endif
+
+ /*
+- * Synchronize DMA map if needed.
+- */
+- sym_data_dmamap_postsync(np, cp);
+-
+- /*
+ * Build result in CAM ccb.
+ */
+- sym_set_cam_result_ok(np, cp, resid);
++ sym_set_cam_result_ok(cp, cmd, resid);
+
+ #ifdef SYM_OPT_SNIFF_INQUIRY
+ /*
+@@ -5612,7 +5546,7 @@
+ * not set), sniff out device capabilities.
+ */
+ if (cp->cdb_buf[0] == INQUIRY && !(cp->cdb_buf[1] & 0x3))
+- sym_sniff_inquiry(np, cp->cam_ccb, resid);
++ sym_sniff_inquiry(np, cmd, resid);
+ #endif
+
+ #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
+@@ -5626,8 +5560,7 @@
+ lp->num_sgood = 0;
+ ++lp->started_max;
+ if (sym_verbose >= 2) {
+- PRINT_LUN(np, cp->target, cp->lun);
+- printf(" queue depth is now %d\n",
++ sym_print_addr(cmd, " queue depth is now %d\n",
+ lp->started_max);
+ }
+ }
+@@ -5649,14 +5582,15 @@
+ /*
+ * Complete the command.
+ */
+- sym_xpt_done(np, ccb);
++ sym_xpt_done(np, cmd);
+ }
+
+ /*
+ * Soft-attach the controller.
+ */
+-int sym_hcb_attach(struct sym_hcb *np, struct sym_fw *fw, struct sym_nvram *nvram)
++int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram *nvram)
+ {
++ struct sym_hcb *np = sym_get_hcb(shost);
+ int i;
+
+ /*
+@@ -5680,13 +5614,13 @@
+ * that SCSI clock calibration may not work properly
+ * if the chip is currently active.
+ */
+- sym_chip_reset (np);
++ sym_chip_reset(np);
+
+ /*
+ * Prepare controller and devices settings, according
+ * to chip features, user set-up and driver set-up.
+ */
+- (void) sym_prepare_setting(np, nvram);
++ sym_prepare_setting(shost, np, nvram);
+
+ /*
+ * Check the PCI clock frequency.
+@@ -5701,7 +5635,7 @@
+ /*
+ * Allocate the start queue.
+ */
+- np->squeue = (u32 *) sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"SQUEUE");
++ np->squeue = sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"SQUEUE");
+ if (!np->squeue)
+ goto attach_failed;
+ np->squeue_ba = vtobus(np->squeue);
+@@ -5709,7 +5643,7 @@
+ /*
+ * Allocate the done queue.
+ */
+- np->dqueue = (u32 *) sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"DQUEUE");
++ np->dqueue = sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"DQUEUE");
+ if (!np->dqueue)
+ goto attach_failed;
+ np->dqueue_ba = vtobus(np->dqueue);
+@@ -5717,7 +5651,7 @@
+ /*
+ * Allocate the target bus address array.
+ */
+- np->targtbl = (u32 *) sym_calloc_dma(256, "TARGTBL");
++ np->targtbl = sym_calloc_dma(256, "TARGTBL");
+ if (!np->targtbl)
+ goto attach_failed;
+ np->targtbl_ba = vtobus(np->targtbl);
+@@ -5734,7 +5668,7 @@
+ /*
+ * Allocate the array of lists of CCBs hashed by DSA.
+ */
+- np->ccbh = sym_calloc(sizeof(ccb_p *)*CCB_HASH_SIZE, "CCBH");
++ np->ccbh = kcalloc(sizeof(struct sym_ccb **), CCB_HASH_SIZE, GFP_KERNEL);
+ if (!np->ccbh)
+ goto attach_failed;
+
+@@ -5817,20 +5751,20 @@
+ /*
+ * Prepare the idle and invalid task actions.
+ */
+- np->idletask.start = cpu_to_scr(SCRIPTA_BA (np, idle));
+- np->idletask.restart = cpu_to_scr(SCRIPTB_BA (np, bad_i_t_l));
++ np->idletask.start = cpu_to_scr(SCRIPTA_BA(np, idle));
++ np->idletask.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
+ np->idletask_ba = vtobus(&np->idletask);
+
+- np->notask.start = cpu_to_scr(SCRIPTA_BA (np, idle));
+- np->notask.restart = cpu_to_scr(SCRIPTB_BA (np, bad_i_t_l));
++ np->notask.start = cpu_to_scr(SCRIPTA_BA(np, idle));
++ np->notask.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
+ np->notask_ba = vtobus(&np->notask);
+
+- np->bad_itl.start = cpu_to_scr(SCRIPTA_BA (np, idle));
+- np->bad_itl.restart = cpu_to_scr(SCRIPTB_BA (np, bad_i_t_l));
++ np->bad_itl.start = cpu_to_scr(SCRIPTA_BA(np, idle));
++ np->bad_itl.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l));
+ np->bad_itl_ba = vtobus(&np->bad_itl);
+
+- np->bad_itlq.start = cpu_to_scr(SCRIPTA_BA (np, idle));
+- np->bad_itlq.restart = cpu_to_scr(SCRIPTB_BA (np,bad_i_t_l_q));
++ np->bad_itlq.start = cpu_to_scr(SCRIPTA_BA(np, idle));
++ np->bad_itlq.restart = cpu_to_scr(SCRIPTB_BA(np,bad_i_t_l_q));
+ np->bad_itlq_ba = vtobus(&np->bad_itlq);
+
+ /*
+@@ -5843,7 +5777,7 @@
+ if (!np->badluntbl)
+ goto attach_failed;
+
+- np->badlun_sa = cpu_to_scr(SCRIPTB_BA (np, resel_bad_lun));
++ np->badlun_sa = cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
+ for (i = 0 ; i < 64 ; i++) /* 64 luns/target, no less */
+ np->badluntbl[i] = cpu_to_scr(vtobus(&np->badlun_sa));
+
+@@ -5866,7 +5800,7 @@
+ if (sym_snooptest (np)) {
+ printf("%s: CACHE INCORRECTLY CONFIGURED.\n", sym_name(np));
+ goto attach_failed;
+- };
++ }
+
+ /*
+ * Sigh! we are done.
+@@ -5883,9 +5817,9 @@
+ void sym_hcb_free(struct sym_hcb *np)
+ {
+ SYM_QUEHEAD *qp;
+- ccb_p cp;
+- tcb_p tp;
+- lcb_p lp;
++ struct sym_ccb *cp;
++ struct sym_tcb *tp;
++ struct sym_lcb *lp;
+ int target, lun;
+
+ if (np->scriptz0)
+@@ -5902,14 +5836,10 @@
+ if (np->actccbs) {
+ while ((qp = sym_remque_head(&np->free_ccbq)) != 0) {
+ cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
+- sym_data_dmamap_destroy(np, cp);
+- sym_mfree_dma(cp->sns_bbuf, SYM_SNS_BBUF_LEN,
+- "SNS_BBUF");
+ sym_mfree_dma(cp, sizeof(*cp), "CCB");
+ }
+ }
+- if (np->ccbh)
+- sym_mfree(np->ccbh, sizeof(ccb_p *)*CCB_HASH_SIZE, "CCBH");
++ kfree(np->ccbh);
+
+ if (np->badluntbl)
+ sym_mfree_dma(np->badluntbl, 256,"BADLUNTBL");
+@@ -5917,21 +5847,17 @@
+ 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(np, tp, 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");
+- if (lp->cb_tags)
+- sym_mfree(lp->cb_tags, SYM_CONF_MAX_TASK,
+- "CB_TAGS");
++ kfree(lp->cb_tags);
+ sym_mfree_dma(lp, sizeof(*lp), "LCB");
+ }
+ #if SYM_CONF_MAX_LUN > 1
+- if (tp->lunmp)
+- sym_mfree(tp->lunmp, SYM_CONF_MAX_LUN*sizeof(lcb_p),
+- "LUNMP");
++ kfree(tp->lunmp);
+ #endif
+ }
+ if (np->targtbl)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_hipd.h CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_hipd.h
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_hipd.h 2005-03-02 04:19:14.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_hipd.h 2005-03-04 10:02:40.000000000 -0700
+@@ -188,36 +188,45 @@
+ /*
+ * Common definitions for both bus space based and legacy IO methods.
+ */
+-#define INB(r) INB_OFF(offsetof(struct sym_reg,r))
+-#define INW(r) INW_OFF(offsetof(struct sym_reg,r))
+-#define INL(r) INL_OFF(offsetof(struct sym_reg,r))
+-
+-#define OUTB(r, v) OUTB_OFF(offsetof(struct sym_reg,r), (v))
+-#define OUTW(r, v) OUTW_OFF(offsetof(struct sym_reg,r), (v))
+-#define OUTL(r, v) OUTL_OFF(offsetof(struct sym_reg,r), (v))
+-
+-#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))
++
++#define INB_OFF(np, o) ioread8(np->s.ioaddr + (o))
++#define INW_OFF(np, o) ioread16(np->s.ioaddr + (o))
++#define INL_OFF(np, o) ioread32(np->s.ioaddr + (o))
++
++#define OUTB_OFF(np, o, val) iowrite8((val), np->s.ioaddr + (o))
++#define OUTW_OFF(np, o, val) iowrite16((val), np->s.ioaddr + (o))
++#define OUTL_OFF(np, o, val) iowrite32((val), np->s.ioaddr + (o))
++
++#define INB(np, r) INB_OFF(np, offsetof(struct sym_reg, r))
++#define INW(np, r) INW_OFF(np, offsetof(struct sym_reg, r))
++#define INL(np, r) INL_OFF(np, offsetof(struct sym_reg, r))
++
++#define OUTB(np, r, v) OUTB_OFF(np, offsetof(struct sym_reg, r), (v))
++#define OUTW(np, r, v) OUTW_OFF(np, offsetof(struct sym_reg, r), (v))
++#define OUTL(np, r, v) OUTL_OFF(np, offsetof(struct sym_reg, r), (v))
++
++#define OUTONB(np, r, m) OUTB(np, r, INB(np, r) | (m))
++#define OUTOFFB(np, r, m) OUTB(np, r, INB(np, r) & ~(m))
++#define OUTONW(np, r, m) OUTW(np, r, INW(np, r) | (m))
++#define OUTOFFW(np, r, m) OUTW(np, r, INW(np, r) & ~(m))
++#define OUTONL(np, r, m) OUTL(np, r, INL(np, r) | (m))
++#define OUTOFFL(np, r, m) OUTL(np, r, INL(np, 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) \
++#define OUTL_DSP(np, v) \
+ do { \
+ MEMORY_WRITE_BARRIER(); \
+- OUTL (nc_dsp, (v)); \
++ OUTL(np, nc_dsp, (v)); \
+ } while (0)
+
+ #define OUTONB_STD() \
+ do { \
+ MEMORY_WRITE_BARRIER(); \
+- OUTONB (nc_dcntl, (STD|NOCOM)); \
++ OUTONB(np, nc_dcntl, (STD|NOCOM)); \
+ } while (0)
+
+ /*
+@@ -321,7 +330,6 @@
+ * Host adapter miscellaneous flags.
+ */
+ #define SYM_AVOID_BUS_RESET (1)
+-#define SYM_SCAN_TARGETS_HILO (1<<1)
+
+ /*
+ * Misc.
+@@ -334,20 +342,13 @@
+ * Gather negotiable parameters value
+ */
+ struct sym_trans {
+- u8 scsi_version;
+- u8 spi_version;
+ u8 period;
+ u8 offset;
+- u8 width;
+- u8 options; /* PPR options */
+-};
+-
+-struct sym_tinfo {
+- struct sym_trans curr;
+- struct sym_trans goal;
+-#ifdef SYM_OPT_ANNOUNCE_TRANSFER_RATE
+- struct sym_trans prev;
+-#endif
++ unsigned int width:1;
++ unsigned int iu:1;
++ unsigned int dt:1;
++ unsigned int qas:1;
++ unsigned int check_nego:1;
+ };
+
+ /*
+@@ -398,9 +399,9 @@
+ /*
+ * LUN table used by the C code.
+ */
+- lcb_p lun0p; /* LCB of LUN #0 (usual case) */
++ struct sym_lcb *lun0p; /* LCB of LUN #0 (usual case) */
+ #if SYM_CONF_MAX_LUN > 1
+- lcb_p *lunmp; /* Other LCBs [1..MAX_LUN] */
++ struct sym_lcb **lunmp; /* Other LCBs [1..MAX_LUN] */
+ #endif
+
+ /*
+@@ -423,16 +424,14 @@
+ struct sym_stcb s;
+ #endif
+
+- /*
+- * Transfer capabilities (SIP)
+- */
+- struct sym_tinfo tinfo;
++ /* Transfer goal */
++ struct sym_trans tgoal;
+
+ /*
+ * Keep track of the CCB used for the negotiation in order
+ * to ensure that only 1 negotiation is queued at a time.
+ */
+- ccb_p nego_cp; /* CCB used for the nego */
++ struct sym_ccb * nego_cp; /* CCB used for the nego */
+
+ /*
+ * Set when we want to reset the device.
+@@ -520,10 +519,8 @@
+ * Optionnaly the driver can handle device queueing,
+ * and requeues internally command to redo.
+ */
+- SYM_QUEHEAD
+- waiting_ccbq;
+- SYM_QUEHEAD
+- started_ccbq;
++ SYM_QUEHEAD waiting_ccbq;
++ SYM_QUEHEAD started_ccbq;
+ int num_sgood;
+ u_short started_tags;
+ u_short started_no_tag;
+@@ -533,8 +530,8 @@
+
+ #ifdef SYM_OPT_LIMIT_COMMAND_REORDERING
+ /*
+- * Optionnaly the driver can try to prevent SCSI
+- * IOs from being too much reordering.
++ * Optionally the driver can try to prevent SCSI
++ * IOs from being reordered too much.
+ */
+ u_char tags_si; /* Current index to tags sum */
+ u_short tags_sum[2]; /* Tags sum counters */
+@@ -582,9 +579,9 @@
+ * LUN(s) > 0.
+ */
+ #if SYM_CONF_MAX_LUN <= 1
+-#define sym_lp(np, tp, lun) (!lun) ? (tp)->lun0p : NULL
++#define sym_lp(tp, lun) (!lun) ? (tp)->lun0p : NULL
+ #else
+-#define sym_lp(np, tp, lun) \
++#define sym_lp(tp, lun) \
+ (!lun) ? (tp)->lun0p : (tp)->lunmp ? (tp)->lunmp[(lun)] : NULL
+ #endif
+
+@@ -749,12 +746,10 @@
+ /*
+ * Pointer to CAM ccb and related stuff.
+ */
+- struct scsi_cmnd *cam_ccb; /* CAM scsiio ccb */
++ struct scsi_cmnd *cmd; /* CAM scsiio ccb */
+ u8 cdb_buf[16]; /* Copy of CDB */
+- u8 *sns_bbuf; /* Bounce buffer for sense data */
+-#ifndef SYM_SNS_BBUF_LEN
+-#define SYM_SNS_BBUF_LEN (32)
+-#endif
++#define SYM_SNS_BBUF_LEN 32
++ u8 sns_bbuf[SYM_SNS_BBUF_LEN]; /* Bounce buffer for sense data */
+ int data_len; /* Total data length */
+ int segments; /* Number of SG segments */
+
+@@ -801,9 +796,8 @@
+ /* NO_TAG means no tag */
+ u_char target;
+ u_char lun;
+- ccb_p link_ccbh; /* Host adapter CCB hash chain */
+- SYM_QUEHEAD
+- link_ccbq; /* Link to free/busy CCB queue */
++ struct sym_ccb *link_ccbh; /* Host adapter CCB hash chain */
++ 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
+@@ -812,8 +806,7 @@
+ int ext_sg; /* Extreme data pointer, used */
+ int ext_ofs; /* to calculate the residual. */
+ #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
+- SYM_QUEHEAD
+- link2_ccbq; /* Link for device queueing */
++ SYM_QUEHEAD link2_ccbq; /* Link for device queueing */
+ u_char started; /* CCB queued to the squeue */
+ #endif
+ u_char to_abort; /* Want this IO to be aborted */
+@@ -830,6 +823,8 @@
+ #define sym_goalp(cp) (cp->goalp)
+ #endif
+
++typedef struct device *m_pool_ident_t;
++
+ /*
+ * Host Control Block
+ */
+@@ -1005,7 +1000,7 @@
+ /*
+ * CCB lists and queue.
+ */
+- ccb_p *ccbh; /* CCBs hashed by DSA value */
++ struct sym_ccb **ccbh; /* CCBs hashed by DSA value */
+ /* CCB_HASH_SIZE lists of CCBs */
+ SYM_QUEHEAD free_ccbq; /* Queue of available CCBs */
+ SYM_QUEHEAD busy_ccbq; /* Queue of busy CCBs */
+@@ -1037,7 +1032,7 @@
+ #ifdef SYM_CONF_IARB_SUPPORT
+ u_short iarb_max; /* Max. # consecutive IARB hints*/
+ u_short iarb_count; /* Actual # of these hints */
+- ccb_p last_cp;
++ struct sym_ccb * last_cp;
+ #endif
+
+ /*
+@@ -1068,41 +1063,31 @@
+ /*
+ * FIRMWARES (sym_fw.c)
+ */
+-struct sym_fw * sym_find_firmware(struct sym_pci_chip *chip);
+-void sym_fw_bind_script (struct sym_hcb *np, u32 *start, int len);
++struct sym_fw * sym_find_firmware(struct sym_chip *chip);
++void sym_fw_bind_script(struct sym_hcb *np, u32 *start, int len);
+
+ /*
+ * Driver methods called from O/S specific code.
+ */
+ char *sym_driver_name(void);
+-void sym_print_xerr(ccb_p cp, int x_status);
++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_pci_chip *
+-sym_lookup_pci_chip_table (u_short device_id, u_char revision);
+-void sym_put_start_queue(struct sym_hcb *np, ccb_p cp);
++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, lcb_p lp, int maxn);
++void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn);
+ #endif
+-void sym_start_up (struct sym_hcb *np, int reason);
+-void sym_interrupt (struct sym_hcb *np);
++void sym_start_up(struct sym_hcb *np, int reason);
++void sym_interrupt(struct sym_hcb *np);
+ int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task);
+-ccb_p sym_get_ccb (struct sym_hcb *np, u_char tn, u_char ln, u_char tag_order);
+-void sym_free_ccb (struct sym_hcb *np, ccb_p cp);
+-lcb_p sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln);
+-int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *csio, ccb_p cp);
++struct sym_ccb *sym_get_ccb(struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order);
++void sym_free_ccb(struct sym_hcb *np, struct sym_ccb *cp);
++struct sym_lcb *sym_alloc_lcb(struct sym_hcb *np, u_char tn, u_char ln);
++int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp);
+ int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *ccb, int timed_out);
+-int sym_abort_ccb(struct sym_hcb *np, ccb_p cp, int timed_out);
+ int sym_reset_scsi_target(struct sym_hcb *np, int target);
+ void sym_hcb_free(struct sym_hcb *np);
+-int sym_hcb_attach(struct sym_hcb *np, struct sym_fw *fw, struct sym_nvram *nvram);
+-
+-/*
+- * Optionnaly, the driver may provide a function
+- * to announce transfer rate changes.
+- */
+-#ifdef SYM_OPT_ANNOUNCE_TRANSFER_RATE
+-void sym_announce_transfer_rate(struct sym_hcb *np, int target);
+-#endif
++int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram *nvram);
+
+ /*
+ * Build a scatter/gather entry.
+@@ -1169,7 +1154,7 @@
+ case CAM_DIR_UNKNOWN:
+ #endif
+ case CAM_DIR_OUT:
+- goalp = SCRIPTA_BA (np, data_out2) + 8;
++ 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);
+@@ -1182,7 +1167,7 @@
+ #endif
+ case CAM_DIR_IN:
+ cp->host_flags |= HF_DATA_IN;
+- goalp = SCRIPTA_BA (np, data_in2) + 8;
++ goalp = SCRIPTA_BA(np, data_in2) + 8;
+ lastp = goalp - 8 - (cp->segments * (2*4));
+ break;
+ case CAM_DIR_NONE:
+@@ -1190,7 +1175,7 @@
+ #ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
+ cp->host_flags |= HF_DATA_IN;
+ #endif
+- lastp = goalp = SCRIPTB_BA (np, no_data);
++ lastp = goalp = SCRIPTB_BA(np, no_data);
+ break;
+ }
+
+@@ -1207,7 +1192,7 @@
+ * If direction is unknown, start at data_io.
+ */
+ if (dir == CAM_DIR_UNKNOWN)
+- cp->phys.head.savep = cpu_to_scr(SCRIPTB_BA (np, data_io));
++ cp->phys.head.savep = cpu_to_scr(SCRIPTB_BA(np, data_io));
+ #endif
+ }
+
+@@ -1215,6 +1200,17 @@
+ * MEMORY ALLOCATOR.
+ */
+
++#define SYM_MEM_PAGE_ORDER 0 /* 1 PAGE maximum */
++#define SYM_MEM_CLUSTER_SHIFT (PAGE_SHIFT+SYM_MEM_PAGE_ORDER)
++#define SYM_MEM_FREE_UNUSED /* Free unused pages immediately */
++
++#define SYM_MEM_WARN 1 /* Warn on failed operations */
++
++#define sym_get_mem_cluster() \
++ (void *) __get_free_pages(GFP_ATOMIC, SYM_MEM_PAGE_ORDER)
++#define sym_free_mem_cluster(p) \
++ free_pages((unsigned long)p, SYM_MEM_PAGE_ORDER)
++
+ /*
+ * Link between free memory chunks of a given size.
+ */
+@@ -1228,11 +1224,8 @@
+ */
+ typedef struct sym_m_vtob { /* Virtual to Bus address translation */
+ struct sym_m_vtob *next;
+-#ifdef SYM_HAVE_M_SVTOB
+- struct sym_m_svtob s; /* OS specific data structure */
+-#endif
+- m_addr_t vaddr; /* Virtual address */
+- m_addr_t baddr; /* Bus physical address */
++ void *vaddr; /* Virtual address */
++ dma_addr_t baddr; /* Bus physical address */
+ } *m_vtob_p;
+
+ /* Hash this stuff a bit to speed up translations */
+@@ -1240,7 +1233,7 @@
+ #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)) >> SYM_MEM_CLUSTER_SHIFT) & VTOB_HASH_MASK)
++ ((((unsigned long)(m)) >> SYM_MEM_CLUSTER_SHIFT) & VTOB_HASH_MASK)
+
+ /*
+ * Memory pool of a given kind.
+@@ -1253,15 +1246,12 @@
+ */
+ typedef struct sym_m_pool {
+ m_pool_ident_t dev_dmat; /* Identifies the pool (see above) */
+- m_addr_t (*get_mem_cluster)(struct sym_m_pool *);
++ void * (*get_mem_cluster)(struct sym_m_pool *);
+ #ifdef SYM_MEM_FREE_UNUSED
+- void (*free_mem_cluster)(struct sym_m_pool *, m_addr_t);
++ void (*free_mem_cluster)(struct sym_m_pool *, void *);
+ #endif
+ #define M_GET_MEM_CLUSTER() mp->get_mem_cluster(mp)
+ #define M_FREE_MEM_CLUSTER(p) mp->free_mem_cluster(mp, p)
+-#ifdef SYM_HAVE_M_SPOOL
+- struct sym_m_spool s; /* OS specific data structure */
+-#endif
+ int nump;
+ m_vtob_p vtob[VTOB_HASH_SIZE];
+ struct sym_m_pool *next;
+@@ -1269,19 +1259,12 @@
+ } *m_pool_p;
+
+ /*
+- * Alloc and free non DMAable memory.
+- */
+-void sym_mfree_unlocked(void *ptr, int size, char *name);
+-void *sym_calloc_unlocked(int size, char *name);
+-
+-/*
+ * Alloc, free and translate addresses to bus physical
+ * for DMAable memory.
+ */
+-void *__sym_calloc_dma_unlocked(m_pool_ident_t dev_dmat, int size, char *name);
+-void
+-__sym_mfree_dma_unlocked(m_pool_ident_t dev_dmat, void *m,int size, char *name);
+-u32 __vtobus_unlocked(m_pool_ident_t dev_dmat, void *m);
++void *__sym_calloc_dma(m_pool_ident_t dev_dmat, int size, char *name);
++void __sym_mfree_dma(m_pool_ident_t dev_dmat, void *m, int size, char *name);
++dma_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m);
+
+ /*
+ * Verbs used by the driver code for DMAable memory handling.
+@@ -1295,15 +1278,33 @@
+ __sym_mfree_dma(np->bus_dmat, _uvptv_(p), l, n)
+ #define sym_calloc_dma(l, n) _sym_calloc_dma(np, l, n)
+ #define sym_mfree_dma(p, l, n) _sym_mfree_dma(np, p, l, n)
+-#define _vtobus(np, p) __vtobus(np->bus_dmat, _uvptv_(p))
+-#define vtobus(p) _vtobus(np, p)
++#define vtobus(p) __vtobus(np->bus_dmat, _uvptv_(p))
+
+ /*
+- * Override some function names.
++ * We have to provide the driver memory allocator with methods for
++ * it to maintain virtual to bus physical address translations.
+ */
+-#define PRINT_ADDR sym_print_addr
+-#define PRINT_TARGET sym_print_target
+-#define PRINT_LUN sym_print_lun
+-#define UDELAY sym_udelay
++
++#define sym_m_pool_match(mp_id1, mp_id2) (mp_id1 == mp_id2)
++
++static __inline void *sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
++{
++ void *vaddr = NULL;
++ dma_addr_t baddr = 0;
++
++ vaddr = dma_alloc_coherent(mp->dev_dmat, SYM_MEM_CLUSTER_SIZE, &baddr,
++ GFP_ATOMIC);
++ if (vaddr) {
++ vbp->vaddr = vaddr;
++ vbp->baddr = baddr;
++ }
++ return vaddr;
++}
++
++static __inline void sym_m_free_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
++{
++ dma_free_coherent(mp->dev_dmat, SYM_MEM_CLUSTER_SIZE, vbp->vaddr,
++ vbp->baddr);
++}
+
+ #endif /* SYM_HIPD_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_malloc.c CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_malloc.c
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_malloc.c 2005-03-02 04:19:14.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_malloc.c 2005-03-04 08:35:58.000000000 -0700
+@@ -66,7 +66,7 @@
+ int i = 0;
+ int s = (1 << SYM_MEM_SHIFT);
+ int j;
+- m_addr_t a;
++ void *a;
+ m_link_p h = mp->h;
+
+ if (size > SYM_MEM_CLUSTER_SIZE)
+@@ -88,7 +88,7 @@
+ ++j;
+ s <<= 1;
+ }
+- a = (m_addr_t) h[j].next;
++ a = h[j].next;
+ if (a) {
+ h[j].next = h[j].next->next;
+ while (j > i) {
+@@ -101,7 +101,7 @@
+ #ifdef DEBUG
+ printf("___sym_malloc(%d) = %p\n", size, (void *) a);
+ #endif
+- return (void *) a;
++ return a;
+ }
+
+ /*
+@@ -112,7 +112,7 @@
+ int i = 0;
+ int s = (1 << SYM_MEM_SHIFT);
+ m_link_p q;
+- m_addr_t a, b;
++ unsigned long a, b;
+ m_link_p h = mp->h;
+
+ #ifdef DEBUG
+@@ -127,12 +127,12 @@
+ ++i;
+ }
+
+- a = (m_addr_t) ptr;
++ a = (unsigned long)ptr;
+
+ while (1) {
+ if (s == SYM_MEM_CLUSTER_SIZE) {
+ #ifdef SYM_MEM_FREE_UNUSED
+- M_FREE_MEM_CLUSTER(a);
++ M_FREE_MEM_CLUSTER((void *)a);
+ #else
+ ((m_link_p) a)->next = h[i].next;
+ h[i].next = (m_link_p) a;
+@@ -194,58 +194,40 @@
+ * With DMA abstraction, we use functions (methods), to
+ * distinguish between non DMAable memory and DMAable memory.
+ */
+-static m_addr_t ___mp0_get_mem_cluster(m_pool_p mp)
++static void *___mp0_get_mem_cluster(m_pool_p mp)
+ {
+- m_addr_t m = (m_addr_t) sym_get_mem_cluster();
++ void *m = sym_get_mem_cluster();
+ if (m)
+ ++mp->nump;
+ return m;
+ }
+
+ #ifdef SYM_MEM_FREE_UNUSED
+-static void ___mp0_free_mem_cluster(m_pool_p mp, m_addr_t m)
++static void ___mp0_free_mem_cluster(m_pool_p mp, void *m)
+ {
+ sym_free_mem_cluster(m);
+ --mp->nump;
+ }
+-#endif
+-
+-#ifdef SYM_MEM_FREE_UNUSED
+-static struct sym_m_pool mp0 =
+- {NULL, ___mp0_get_mem_cluster, ___mp0_free_mem_cluster};
+ #else
+-static struct sym_m_pool mp0 =
+- {NULL, ___mp0_get_mem_cluster};
++#define ___mp0_free_mem_cluster NULL
+ #endif
+
+-/*
+- * Actual memory allocation routine for non-DMAed memory.
+- */
+-void *sym_calloc_unlocked(int size, char *name)
+-{
+- void *m;
+- m = __sym_calloc(&mp0, size, name);
+- return m;
+-}
+-
+-/*
+- * Its counter-part.
+- */
+-void sym_mfree_unlocked(void *ptr, int size, char *name)
+-{
+- __sym_mfree(&mp0, ptr, size, name);
+-}
++static struct sym_m_pool mp0 = {
++ NULL,
++ ___mp0_get_mem_cluster,
++ ___mp0_free_mem_cluster
++};
+
+ /*
+ * Methods that maintains DMAable pools according to user allocations.
+ * New pools are created on the fly when a new pool id is provided.
+ * They are deleted on the fly when they get emptied.
+ */
+-/* Get a memory cluster that matches the DMA contraints of a given pool */
+-static m_addr_t ___get_dma_mem_cluster(m_pool_p mp)
++/* Get a memory cluster that matches the DMA constraints of a given pool */
++static void * ___get_dma_mem_cluster(m_pool_p mp)
+ {
+ m_vtob_p vbp;
+- m_addr_t vaddr;
++ void *vaddr;
+
+ vbp = __sym_calloc(&mp0, sizeof(*vbp), "VTOB");
+ if (!vbp)
+@@ -257,16 +239,15 @@
+ vbp->next = mp->vtob[hc];
+ mp->vtob[hc] = vbp;
+ ++mp->nump;
+- return (m_addr_t) vaddr;
+ }
+ return vaddr;
+ out_err:
+- return 0;
++ return NULL;
+ }
+
+ #ifdef SYM_MEM_FREE_UNUSED
+ /* Free a memory cluster and associated resources for DMA */
+-static void ___free_dma_mem_cluster(m_pool_p mp, m_addr_t m)
++static void ___free_dma_mem_cluster(m_pool_p mp, void *m)
+ {
+ m_vtob_p *vbpp, vbp;
+ int hc = VTOB_HASH_CODE(m);
+@@ -297,23 +278,17 @@
+ /* Create a new memory DMAable pool (when fetch failed) */
+ static m_pool_p ___cre_dma_pool(m_pool_ident_t dev_dmat)
+ {
+- m_pool_p mp = NULL;
+-
+- mp = __sym_calloc(&mp0, sizeof(*mp), "MPOOL");
++ m_pool_p mp = __sym_calloc(&mp0, sizeof(*mp), "MPOOL");
+ if (mp) {
+ mp->dev_dmat = dev_dmat;
+- if (!sym_m_create_dma_mem_tag(mp)) {
+- mp->get_mem_cluster = ___get_dma_mem_cluster;
++ mp->get_mem_cluster = ___get_dma_mem_cluster;
+ #ifdef SYM_MEM_FREE_UNUSED
+- mp->free_mem_cluster = ___free_dma_mem_cluster;
++ mp->free_mem_cluster = ___free_dma_mem_cluster;
+ #endif
+- mp->next = mp0.next;
+- mp0.next = mp;
+- return mp;
+- }
++ mp->next = mp0.next;
++ mp0.next = mp;
++ return mp;
+ }
+- if (mp)
+- __sym_mfree(&mp0, mp, sizeof(*mp), "MPOOL");
+ return NULL;
+ }
+
+@@ -327,68 +302,81 @@
+ pp = &(*pp)->next;
+ if (*pp) {
+ *pp = (*pp)->next;
+- sym_m_delete_dma_mem_tag(p);
+ __sym_mfree(&mp0, p, sizeof(*p), "MPOOL");
+ }
+ }
+ #endif
+
++/* This lock protects only the memory allocation/free. */
++static DEFINE_SPINLOCK(sym53c8xx_lock);
++
+ /*
+ * Actual allocator for DMAable memory.
+ */
+-void *__sym_calloc_dma_unlocked(m_pool_ident_t dev_dmat, int size, char *name)
++void *__sym_calloc_dma(m_pool_ident_t dev_dmat, int size, char *name)
+ {
++ unsigned long flags;
+ m_pool_p mp;
+ void *m = NULL;
+
++ spin_lock_irqsave(&sym53c8xx_lock, flags);
+ mp = ___get_dma_pool(dev_dmat);
+ if (!mp)
+ mp = ___cre_dma_pool(dev_dmat);
+- if (mp)
+- m = __sym_calloc(mp, size, name);
++ if (!mp)
++ goto out;
++ m = __sym_calloc(mp, size, name);
+ #ifdef SYM_MEM_FREE_UNUSED
+- if (mp && !mp->nump)
++ if (!mp->nump)
+ ___del_dma_pool(mp);
+ #endif
+
++ out:
++ spin_unlock_irqrestore(&sym53c8xx_lock, flags);
+ return m;
+ }
+
+-/*
+- * Its counter-part.
+- */
+-void
+-__sym_mfree_dma_unlocked(m_pool_ident_t dev_dmat, void *m, int size, char *name)
++void __sym_mfree_dma(m_pool_ident_t dev_dmat, void *m, int size, char *name)
+ {
++ unsigned long flags;
+ m_pool_p mp;
+
++ spin_lock_irqsave(&sym53c8xx_lock, flags);
+ mp = ___get_dma_pool(dev_dmat);
+- if (mp)
+- __sym_mfree(mp, m, size, name);
++ if (!mp)
++ goto out;
++ __sym_mfree(mp, m, size, name);
+ #ifdef SYM_MEM_FREE_UNUSED
+- if (mp && !mp->nump)
++ if (!mp->nump)
+ ___del_dma_pool(mp);
+ #endif
++ out:
++ spin_unlock_irqrestore(&sym53c8xx_lock, flags);
+ }
+
+ /*
+ * Actual virtual to bus physical address translator
+ * for 32 bit addressable DMAable memory.
+ */
+-u32 __vtobus_unlocked(m_pool_ident_t dev_dmat, void *m)
++dma_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m)
+ {
++ unsigned long flags;
+ m_pool_p mp;
+ int hc = VTOB_HASH_CODE(m);
+ m_vtob_p vp = NULL;
+- m_addr_t a = ((m_addr_t) m) & ~SYM_MEM_CLUSTER_MASK;
++ void *a = (void *)((unsigned long)m & ~SYM_MEM_CLUSTER_MASK);
++ dma_addr_t b;
+
++ spin_lock_irqsave(&sym53c8xx_lock, flags);
+ mp = ___get_dma_pool(dev_dmat);
+ if (mp) {
+ vp = mp->vtob[hc];
+- while (vp && (m_addr_t) vp->vaddr != a)
++ while (vp && vp->vaddr != a)
+ vp = vp->next;
+ }
+ if (!vp)
+ panic("sym: VTOBUS FAILED!\n");
+- return (u32)(vp ? vp->baddr + (((m_addr_t) m) - a) : 0);
++ b = vp->baddr + (m - a);
++ spin_unlock_irqrestore(&sym53c8xx_lock, flags);
++ return b;
+ }
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_misc.c CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_misc.c
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_misc.c 2005-03-02 04:19:14.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_misc.c 1969-12-31 17:00:00.000000000 -0700
+@@ -1,111 +0,0 @@
+-/*
+- * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family
+- * of PCI-SCSI IO processors.
+- *
+- * Copyright (C) 1999-2001 Gerard Roudier <groudier at free.fr>
+- *
+- * This driver is derived from the Linux sym53c8xx driver.
+- * Copyright (C) 1998-2000 Gerard Roudier
+- *
+- * The sym53c8xx driver is derived from the ncr53c8xx driver that had been
+- * a port of the FreeBSD ncr driver to Linux-1.2.13.
+- *
+- * The original ncr driver has been written for 386bsd and FreeBSD by
+- * Wolfgang Stanglmeier <wolf at cologne.de>
+- * Stefan Esser <se at mi.Uni-Koeln.de>
+- * Copyright (C) 1994 Wolfgang Stanglmeier
+- *
+- * Other major contributions:
+- *
+- * NVRAM detection and reading.
+- * Copyright (C) 1997 Richard Waltham <dormouse at farsrobt.demon.co.uk>
+- *
+- *-----------------------------------------------------------------------------
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-
+-#include "sym_glue.h"
+-
+-#ifdef SYM_OPT_ANNOUNCE_TRANSFER_RATE
+-/*
+- * Announce transfer rate if anything changed since last announcement.
+- */
+-void sym_announce_transfer_rate(struct sym_hcb *np, int target)
+-{
+- tcb_p tp = &np->target[target];
+-
+-#define __tprev tp->tinfo.prev
+-#define __tcurr tp->tinfo.curr
+-
+- if (__tprev.options == __tcurr.options &&
+- __tprev.width == __tcurr.width &&
+- __tprev.offset == __tcurr.offset &&
+- !(__tprev.offset && __tprev.period != __tcurr.period))
+- return;
+-
+- __tprev.options = __tcurr.options;
+- __tprev.width = __tcurr.width;
+- __tprev.offset = __tcurr.offset;
+- __tprev.period = __tcurr.period;
+-
+- if (__tcurr.offset && __tcurr.period) {
+- u_int period, f10, mb10;
+- char *scsi;
+-
+- period = f10 = mb10 = 0;
+- scsi = "FAST-5";
+-
+- if (__tcurr.period <= 9) {
+- scsi = "FAST-80";
+- period = 125;
+- mb10 = 1600;
+- }
+- else {
+- if (__tcurr.period <= 11) {
+- scsi = "FAST-40";
+- period = 250;
+- if (__tcurr.period == 11)
+- period = 303;
+- }
+- else if (__tcurr.period < 25) {
+- scsi = "FAST-20";
+- if (__tcurr.period == 12)
+- period = 500;
+- }
+- else if (__tcurr.period <= 50) {
+- scsi = "FAST-10";
+- }
+- if (!period)
+- period = 40 * __tcurr.period;
+- f10 = 100000 << (__tcurr.width ? 1 : 0);
+- mb10 = (f10 + period/2) / period;
+- }
+- printf_info (
+- "%s:%d: %s %sSCSI %d.%d MB/s %s%s%s (%d.%d ns, offset %d)\n",
+- sym_name(np), target, scsi, __tcurr.width? "WIDE " : "",
+- mb10/10, mb10%10,
+- (__tcurr.options & PPR_OPT_DT) ? "DT" : "ST",
+- (__tcurr.options & PPR_OPT_IU) ? " IU" : "",
+- (__tcurr.options & PPR_OPT_QAS) ? " QAS" : "",
+- period/10, period%10, __tcurr.offset);
+- }
+- else
+- printf_info ("%s:%d: %sasynchronous.\n",
+- sym_name(np), target, __tcurr.width? "wide " : "");
+-}
+-#undef __tprev
+-#undef __tcurr
+-#endif /* SYM_OPT_ANNOUNCE_TRANSFER_RATE */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_nvram.c CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_nvram.c
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_nvram.c 2005-03-02 04:19:14.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_nvram.c 2005-03-02 09:29:49.000000000 -0700
+@@ -47,7 +47,7 @@
+ /*
+ * Get host setup from NVRAM.
+ */
+-void sym_nvram_setup_host(struct sym_hcb *np, struct sym_nvram *nvram)
++void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram)
+ {
+ /*
+ * Get parity checking, host ID, verbose mode
+@@ -61,7 +61,7 @@
+ if (nvram->data.Symbios.flags & SYMBIOS_VERBOSE_MSGS)
+ np->verbose += 1;
+ if (nvram->data.Symbios.flags1 & SYMBIOS_SCAN_HI_LO)
+- np->usrflags |= SYM_SCAN_TARGETS_HILO;
++ shost->reverse_ordering = 1;
+ if (nvram->data.Symbios.flags2 & SYMBIOS_AVOID_BUS_RESET)
+ np->usrflags |= SYM_AVOID_BUS_RESET;
+ break;
+@@ -253,7 +253,7 @@
+ static void S24C16_set_bit(struct sym_device *np, u_char write_bit, u_char *gpreg,
+ int bit_mode)
+ {
+- UDELAY (5);
++ udelay(5);
+ switch (bit_mode) {
+ case SET_BIT:
+ *gpreg |= write_bit;
+@@ -269,8 +269,8 @@
+ break;
+
+ }
+- OUTB (nc_gpreg, *gpreg);
+- UDELAY (5);
++ OUTB(np, nc_gpreg, *gpreg);
++ udelay(5);
+ }
+
+ /*
+@@ -303,7 +303,7 @@
+ S24C16_set_bit(np, write_bit, gpreg, SET_BIT);
+ S24C16_set_bit(np, 0, gpreg, SET_CLK);
+ if (read_bit)
+- *read_bit = INB (nc_gpreg);
++ *read_bit = INB(np, nc_gpreg);
+ S24C16_set_bit(np, 0, gpreg, CLR_CLK);
+ S24C16_set_bit(np, 0, gpreg, CLR_BIT);
+ }
+@@ -315,9 +315,9 @@
+ static void S24C16_write_ack(struct sym_device *np, u_char write_bit, u_char *gpreg,
+ u_char *gpcntl)
+ {
+- OUTB (nc_gpcntl, *gpcntl & 0xfe);
++ OUTB(np, nc_gpcntl, *gpcntl & 0xfe);
+ S24C16_do_bit(np, NULL, write_bit, gpreg);
+- OUTB (nc_gpcntl, *gpcntl);
++ OUTB(np, nc_gpcntl, *gpcntl);
+ }
+
+ /*
+@@ -327,9 +327,9 @@
+ static void S24C16_read_ack(struct sym_device *np, u_char *read_bit, u_char *gpreg,
+ u_char *gpcntl)
+ {
+- OUTB (nc_gpcntl, *gpcntl | 0x01);
++ OUTB(np, nc_gpcntl, *gpcntl | 0x01);
+ S24C16_do_bit(np, read_bit, 1, gpreg);
+- OUTB (nc_gpcntl, *gpcntl);
++ OUTB(np, nc_gpcntl, *gpcntl);
+ }
+
+ /*
+@@ -379,13 +379,13 @@
+ int x;
+
+ /* save current state of GPCNTL and GPREG */
+- old_gpreg = INB (nc_gpreg);
+- old_gpcntl = INB (nc_gpcntl);
++ old_gpreg = INB(np, nc_gpreg);
++ old_gpcntl = INB(np, nc_gpcntl);
+ gpcntl = old_gpcntl & 0x1c;
+
+ /* set up GPREG & GPCNTL to set GPIO0 and GPIO1 in to known state */
+- OUTB (nc_gpreg, old_gpreg);
+- OUTB (nc_gpcntl, gpcntl);
++ OUTB(np, nc_gpreg, old_gpreg);
++ OUTB(np, nc_gpcntl, gpcntl);
+
+ /* this is to set NVRAM into a known state with GPIO0/1 both low */
+ gpreg = old_gpreg;
+@@ -414,8 +414,8 @@
+ }
+
+ /* return GPIO0/1 to original states after having accessed NVRAM */
+- OUTB (nc_gpcntl, old_gpcntl);
+- OUTB (nc_gpreg, old_gpreg);
++ OUTB(np, nc_gpcntl, old_gpcntl);
++ OUTB(np, nc_gpreg, old_gpreg);
+
+ return 0;
+ }
+@@ -433,13 +433,13 @@
+ int x;
+
+ /* save current state of GPCNTL and GPREG */
+- old_gpreg = INB (nc_gpreg);
+- old_gpcntl = INB (nc_gpcntl);
++ old_gpreg = INB(np, nc_gpreg);
++ old_gpcntl = INB(np, nc_gpcntl);
+ gpcntl = old_gpcntl & 0x1c;
+
+ /* set up GPREG & GPCNTL to set GPIO0 and GPIO1 in to known state */
+- OUTB (nc_gpreg, old_gpreg);
+- OUTB (nc_gpcntl, gpcntl);
++ OUTB(np, nc_gpreg, old_gpreg);
++ OUTB(np, nc_gpcntl, gpcntl);
+
+ /* this is to set NVRAM into a known state with GPIO0/1 both low */
+ gpreg = old_gpreg;
+@@ -475,7 +475,7 @@
+
+ /* now set up GPIO0 for inputting data */
+ gpcntl |= 0x01;
+- OUTB (nc_gpcntl, gpcntl);
++ OUTB(np, nc_gpcntl, gpcntl);
+
+ /* input all requested data - only part of total NVRAM */
+ for (x = 0; x < len; x++)
+@@ -483,13 +483,13 @@
+
+ /* finally put NVRAM back in inactive mode */
+ gpcntl &= 0xfe;
+- OUTB (nc_gpcntl, gpcntl);
++ OUTB(np, nc_gpcntl, gpcntl);
+ S24C16_stop(np, &gpreg);
+ retv = 0;
+ out:
+ /* return GPIO0/1 to original states after having accessed NVRAM */
+- OUTB (nc_gpcntl, old_gpcntl);
+- OUTB (nc_gpreg, old_gpreg);
++ OUTB(np, nc_gpcntl, old_gpcntl);
++ OUTB(np, nc_gpreg, old_gpreg);
+
+ return retv;
+ }
+@@ -546,9 +546,9 @@
+ */
+ static void T93C46_Clk(struct sym_device *np, u_char *gpreg)
+ {
+- OUTB (nc_gpreg, *gpreg | 0x04);
+- UDELAY (2);
+- OUTB (nc_gpreg, *gpreg);
++ OUTB(np, nc_gpreg, *gpreg | 0x04);
++ udelay(2);
++ OUTB(np, nc_gpreg, *gpreg);
+ }
+
+ /*
+@@ -556,9 +556,9 @@
+ */
+ static void T93C46_Read_Bit(struct sym_device *np, u_char *read_bit, u_char *gpreg)
+ {
+- UDELAY (2);
++ udelay(2);
+ T93C46_Clk(np, gpreg);
+- *read_bit = INB (nc_gpreg);
++ *read_bit = INB(np, nc_gpreg);
+ }
+
+ /*
+@@ -573,8 +573,8 @@
+
+ *gpreg |= 0x10;
+
+- OUTB (nc_gpreg, *gpreg);
+- UDELAY (2);
++ OUTB(np, nc_gpreg, *gpreg);
++ udelay(2);
+
+ T93C46_Clk(np, gpreg);
+ }
+@@ -585,8 +585,8 @@
+ static void T93C46_Stop(struct sym_device *np, u_char *gpreg)
+ {
+ *gpreg &= 0xef;
+- OUTB (nc_gpreg, *gpreg);
+- UDELAY (2);
++ OUTB(np, nc_gpreg, *gpreg);
++ udelay(2);
+
+ T93C46_Clk(np, gpreg);
+ }
+@@ -603,7 +603,7 @@
+ for (x = 0; x < 9; x++)
+ T93C46_Write_Bit(np, (u_char) (write_data >> (8 - x)), gpreg);
+
+- *read_bit = INB (nc_gpreg);
++ *read_bit = INB(np, nc_gpreg);
+ }
+
+ /*
+@@ -657,23 +657,23 @@
+ int retv = 1;
+
+ /* save current state of GPCNTL and GPREG */
+- old_gpreg = INB (nc_gpreg);
+- old_gpcntl = INB (nc_gpcntl);
++ old_gpreg = INB(np, nc_gpreg);
++ old_gpcntl = INB(np, nc_gpcntl);
+
+ /* set up GPREG & GPCNTL to set GPIO0/1/2/4 in to known state, 0 in,
+ 1/2/4 out */
+ gpreg = old_gpreg & 0xe9;
+- OUTB (nc_gpreg, gpreg);
++ OUTB(np, nc_gpreg, gpreg);
+ gpcntl = (old_gpcntl & 0xe9) | 0x09;
+- OUTB (nc_gpcntl, gpcntl);
++ OUTB(np, nc_gpcntl, gpcntl);
+
+ /* input all of NVRAM, 64 words */
+ retv = T93C46_Read_Data(np, (u_short *) nvram,
+ sizeof(*nvram) / sizeof(short), &gpreg);
+
+ /* return GPIO0/1/2/4 to original states after having accessed NVRAM */
+- OUTB (nc_gpcntl, old_gpcntl);
+- OUTB (nc_gpreg, old_gpreg);
++ OUTB(np, nc_gpcntl, old_gpcntl);
++ OUTB(np, nc_gpreg, old_gpreg);
+
+ return retv;
+ }
+@@ -755,3 +755,17 @@
+ }
+ return nvp->type;
+ }
++
++char *sym_nvram_type(struct sym_nvram *nvp)
++{
++ switch (nvp->type) {
++ case SYM_SYMBIOS_NVRAM:
++ return "Symbios NVRAM";
++ case SYM_TEKRAM_NVRAM:
++ return "Tekram NVRAM";
++ case SYM_PARISC_PDC:
++ return "PA-RISC Firmware";
++ default:
++ return "No NVRAM";
++ }
++}
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_nvram.h CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_nvram.h
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_2/sym_nvram.h 2005-03-02 04:19:14.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_2/sym_nvram.h 2005-03-01 10:05:10.000000000 -0700
+@@ -40,7 +40,7 @@
+ #ifndef SYM_NVRAM_H
+ #define SYM_NVRAM_H
+
+-#include "sym_conf.h"
++#include "sym53c8xx.h"
+
+ /*
+ * Symbios NVRAM data format
+@@ -193,17 +193,22 @@
+ };
+
+ #if SYM_CONF_NVRAM_SUPPORT
+-void sym_nvram_setup_host (struct sym_hcb *np, struct sym_nvram *nvram);
++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);
+ 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 sym_hcb *np, struct sym_nvram *nvram) { }
++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 int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp)
+ {
+ nvp->type = 0;
+ return 0;
+ }
++static inline char *sym_nvram_type(struct sym_nvram *nvp)
++{
++ return "No NVRAM";
++}
+ #endif
+
+ #endif /* SYM_NVRAM_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/sym53c8xx_defs.h CVS2_6_11_PA2/drivers/scsi/sym53c8xx_defs.h
+--- LINUS_2_6_11/drivers/scsi/sym53c8xx_defs.h 2005-03-02 04:19:13.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/sym53c8xx_defs.h 2005-02-21 08:26:11.000000000 -0700
+@@ -314,9 +314,9 @@
+ #define writew_b2l __raw_writew
+ #define writel_b2l __raw_writel
+ #define readw_raw __raw_readw
+-#define readl_raw(a) __raw_readl((unsigned long)(a))
++#define readl_raw __raw_readl
+ #define writew_raw __raw_writew
+-#define writel_raw(v,a) __raw_writel(v,(unsigned long)(a))
++#define writel_raw __raw_writel
+ #else /* Other big-endian */
+ #define readw_l2b readw
+ #define readl_l2b readl
+@@ -1281,34 +1281,34 @@
+ ** Messages
+ */
+
+-#define M_COMPLETE (0x00)
+-#define M_EXTENDED (0x01)
+-#define M_SAVE_DP (0x02)
+-#define M_RESTORE_DP (0x03)
+-#define M_DISCONNECT (0x04)
+-#define M_ID_ERROR (0x05)
+-#define M_ABORT (0x06)
+-#define M_REJECT (0x07)
+-#define M_NOOP (0x08)
+-#define M_PARITY (0x09)
+-#define M_LCOMPLETE (0x0a)
+-#define M_FCOMPLETE (0x0b)
+-#define M_RESET (0x0c)
+-#define M_ABORT_TAG (0x0d)
+-#define M_CLEAR_QUEUE (0x0e)
+-#define M_INIT_REC (0x0f)
+-#define M_REL_REC (0x10)
++#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 (0x20)
+-#define M_HEAD_TAG (0x21)
+-#define M_ORDERED_TAG (0x22)
+-#define M_IGN_RESIDUE (0x23)
++#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 (0x00)
+-#define M_X_SYNC_REQ (0x01)
+-#define M_X_WIDE_REQ (0x03)
+-#define M_X_PPR_REQ (0x04)
++#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
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/scsi/zalon.c CVS2_6_11_PA2/drivers/scsi/zalon.c
+--- LINUS_2_6_11/drivers/scsi/zalon.c 2005-03-02 04:19:13.000000000 -0700
++++ CVS2_6_11_PA2/drivers/scsi/zalon.c 2005-01-11 21:02:54.000000000 -0700
+@@ -88,31 +88,30 @@
+ struct gsc_irq gsc_irq;
+ u32 zalon_vers;
+ int error = -ENODEV;
+- unsigned long zalon = dev->hpa;
+- unsigned long io_port = zalon + GSC_SCSI_ZALON_OFFSET;
++ void __iomem *zalon = ioremap(dev->hpa, 4096);
++ void __iomem *io_port = zalon + GSC_SCSI_ZALON_OFFSET;
+ static int unit = 0;
+ struct Scsi_Host *host;
+ struct ncr_device device;
+
+ __raw_writel(CMD_RESET, zalon + IO_MODULE_IO_COMMAND);
+ while (!(__raw_readl(zalon + IO_MODULE_IO_STATUS) & IOSTATUS_RY))
+- ;
++ cpu_relax();
+ __raw_writel(IOIIDATA_MINT5EN | IOIIDATA_PACKEN | IOIIDATA_PREFETCHEN,
+ zalon + IO_MODULE_II_CDATA);
+
+ /* XXX: Save the Zalon version for bug workarounds? */
+- zalon_vers = __raw_readl(dev->hpa + IO_MODULE_II_CDATA) & 0x07000000;
+- zalon_vers >>= 24;
++ zalon_vers = (__raw_readl(zalon + IO_MODULE_II_CDATA) >> 24) & 0x07;
+
+ /* Setup the interrupts first.
+ ** Later on request_irq() will register the handler.
+ */
+ dev->irq = gsc_alloc_irq(&gsc_irq);
+
+- printk("%s: Zalon vers field is 0x%x, IRQ %d\n", __FUNCTION__,
++ printk(KERN_INFO "%s: Zalon version %d, IRQ %d\n", __FUNCTION__,
+ zalon_vers, dev->irq);
+
+- __raw_writel(gsc_irq.txn_addr | gsc_irq.txn_data, dev->hpa + IO_MODULE_EIM);
++ __raw_writel(gsc_irq.txn_addr | gsc_irq.txn_data, zalon + IO_MODULE_EIM);
+
+ if (zalon_vers == 0)
+ printk(KERN_WARNING "%s: Zalon 1.1 or earlier\n", __FUNCTION__);
+@@ -120,16 +119,16 @@
+ memset(&device, 0, sizeof(struct ncr_device));
+
+ /* The following three are needed before any other access. */
+- writeb(0x20, io_port + 0x38); /* DCNTL_REG, EA */
+- writeb(0x04, io_port + 0x1b); /* CTEST0_REG, EHP */
+- writeb(0x80, io_port + 0x22); /* CTEST4_REG, MUX */
++ __raw_writeb(0x20, io_port + 0x38); /* DCNTL_REG, EA */
++ __raw_writeb(0x04, io_port + 0x1b); /* CTEST0_REG, EHP */
++ __raw_writeb(0x80, io_port + 0x22); /* CTEST4_REG, MUX */
+
+ /* Initialise ncr_device structure with items required by ncr_attach. */
+ device.chip = zalon720_chip;
+ device.host_id = 7;
+ device.dev = &dev->dev;
+- device.slot.base = (u_long)io_port;
+- device.slot.base_c = (u_long)io_port;
++ device.slot.base = dev->hpa + GSC_SCSI_ZALON_OFFSET;
++ device.slot.base_v = io_port;
+ device.slot.irq = dev->irq;
+ device.differential = 2;
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/serial/mux.c CVS2_6_11_PA2/drivers/serial/mux.c
+--- LINUS_2_6_11/drivers/serial/mux.c 2005-03-02 04:19:15.000000000 -0700
++++ CVS2_6_11_PA2/drivers/serial/mux.c 2005-02-14 07:56:20.000000000 -0700
+@@ -27,6 +27,7 @@
+ #include <linux/delay.h> /* for udelay */
+ #include <linux/device.h>
+ #include <asm/io.h>
++#include <asm/irq.h>
+ #include <asm/parisc-device.h>
+
+ #ifdef CONFIG_MAGIC_SYSRQ
+@@ -404,7 +405,7 @@
+ .write = mux_console_write,
+ .device = mux_console_device,
+ .setup = mux_console_setup,
+- .flags = CON_BOOT|CON_PRINTBUFFER|CON_ENABLED,
++ .flags = CON_ENABLED | CON_PRINTBUFFER,
+ .index = 0,
+ };
+
+@@ -475,7 +476,7 @@
+ port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET);
+ port->iotype = SERIAL_IO_MEM;
+ port->type = PORT_MUX;
+- port->irq = SERIAL_IRQ_NONE;
++ port->irq = NO_IRQ;
+ port->uartclk = 0;
+ port->fifosize = MUX_FIFO_SIZE;
+ port->ops = &mux_pops;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/serial/serial_core.c CVS2_6_11_PA2/drivers/serial/serial_core.c
+--- LINUS_2_6_11/drivers/serial/serial_core.c 2005-03-02 04:19:15.000000000 -0700
++++ CVS2_6_11_PA2/drivers/serial/serial_core.c 2005-01-22 07:59:34.000000000 -0700
+@@ -1929,7 +1929,14 @@
+ printk("MMIO 0x%lx", port->mapbase);
+ break;
+ }
+- printk(" (irq = %d) is a %s\n", port->irq, uart_type(port));
++#ifndef NO_IRQ
++#define NO_IRQ (-1)
++#endif
++ if (port->irq == NO_IRQ) {
++ printk(" (polled) is a %s\n", uart_type(port));
++ } else {
++ printk(" (irq = %d) is a %s\n", port->irq, uart_type(port));
++ }
+ }
+
+ static void
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/video/console/Kconfig CVS2_6_11_PA2/drivers/video/console/Kconfig
+--- LINUS_2_6_11/drivers/video/console/Kconfig 2005-03-02 04:19:17.000000000 -0700
++++ CVS2_6_11_PA2/drivers/video/console/Kconfig 2005-02-14 07:45:08.000000000 -0700
+@@ -65,30 +65,6 @@
+ card of your Indy. Most people say Y here.
+
+ # bool 'IODC console' CONFIG_IODC_CONSOLE
+-config STI_CONSOLE
+- tristate "STI text console"
+- depends on PARISC && FRAMEBUFFER_CONSOLE
+- default y
+- help
+- The STI console is the builtin display/keyboard on HP-PARISC
+- machines. Say Y here to build support for it into your kernel.
+- The alternative is to use your primary serial port as a console.
+-
+-config DUMMY_CONSOLE_COLUMNS
+- int "Initial number of console screen columns" if STI_CONSOLE
+- depends on PARISC
+- default "160"
+- help
+- The default value is 160, which should fit a 1280x1024 monitor.
+- Select 80 if you use a 640x480 resolution by default.
+-
+-config DUMMY_CONSOLE_ROWS
+- int "Initial number of console screen rows" if STI_CONSOLE
+- depends on PARISC
+- default "64"
+- help
+- The default value is 64, which should fit a 1280x1024 monitor.
+- Select 25 if you use a 640x480 resolution by default.
+
+ config PROM_CONSOLE
+ bool "PROM console"
+@@ -102,11 +78,36 @@
+ depends on PROM_CONSOLE!=y || VGA_CONSOLE!=y || SGI_NEWPORT_CONSOLE!=y
+ default y
+
++config DUMMY_CONSOLE_COLUMNS
++ int "Initial number of console screen columns"
++ depends on PARISC && DUMMY_CONSOLE
++ default "160"
++ help
++ The default value is 160, which should fit a 1280x1024 monitor.
++ Select 80 if you use a 640x480 resolution by default.
++
++config DUMMY_CONSOLE_ROWS
++ int "Initial number of console screen rows"
++ depends on PARISC && DUMMY_CONSOLE
++ default "64"
++ help
++ The default value is 64, which should fit a 1280x1024 monitor.
++ Select 25 if you use a 640x480 resolution by default.
++
+ config FRAMEBUFFER_CONSOLE
+ tristate "Framebuffer Console support"
+ depends on FB
+ select CRC32
+
++config STI_CONSOLE
++ tristate "STI text console"
++ depends on PARISC && FRAMEBUFFER_CONSOLE
++ default y
++ help
++ The STI console is the builtin display/keyboard on HP-PARISC
++ machines. Say Y here to build support for it into your kernel.
++ The alternative is to use your primary serial port as a console.
++
+ config FONTS
+ bool "Select compiled-in fonts"
+ depends on FRAMEBUFFER_CONSOLE
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/video/console/sticore.c CVS2_6_11_PA2/drivers/video/console/sticore.c
+--- LINUS_2_6_11/drivers/video/console/sticore.c 2005-03-02 04:19:17.000000000 -0700
++++ CVS2_6_11_PA2/drivers/video/console/sticore.c 2005-03-05 15:11:21.000000000 -0700
+@@ -249,13 +249,13 @@
+ /* this still needs to be revisited (see arch/parisc/mm/init.c:246) ! */
+ while (count >= 4) {
+ count -= 4;
+- *(u32 *)dest = __raw_readl(base);
++ *(u32 *)dest = gsc_readl(base);
+ base += 4;
+ dest += 4;
+ }
+ while (count) {
+ count--;
+- *(u8 *)dest = __raw_readb(base);
++ *(u8 *)dest = gsc_readb(base);
+ base++;
+ dest++;
+ }
+@@ -460,12 +460,20 @@
+ /* remap virtually */
+ /* FIXME: add BTLB support if btlb==1 */
+ len = sti->regions[i].region_desc.length * 4096;
+-
++
++/* XXX: Enabling IOREMAP debugging causes a crash, so we must be passing
++ * a virtual address to something expecting a physical address that doesn't
++ * go through a readX macro */
++#if 0
+ if (len)
+ glob_cfg->region_ptrs[i] = (unsigned long) (
+ sti->regions[i].region_desc.cache ?
+ ioremap(sti->regions_phys[i], len) :
+ ioremap_nocache(sti->regions_phys[i], len) );
++#else
++ if (len)
++ glob_cfg->region_ptrs[i] = sti->regions_phys[i];
++#endif
+
+ DPRINTK(("region #%d: phys %08lx, virt %08x, len=%lukB, "
+ "btlb=%d, sysonly=%d, cache=%d, last=%d\n",
+@@ -680,7 +688,7 @@
+
+ while (count) {
+ count--;
+- *(u8 *)dest = __raw_readl(base);
++ *(u8 *)dest = gsc_readl(base);
+ base += 4;
+ dest++;
+ }
+@@ -730,7 +738,7 @@
+ unsigned long size;
+
+ /* read the ROM size directly from the struct in ROM */
+- size = __raw_readl(address + offsetof(struct sti_rom,last_addr));
++ size = gsc_readl(address + offsetof(struct sti_rom,last_addr));
+
+ raw = kmalloc(size, GFP_KERNEL);
+ if(raw)
+@@ -825,13 +833,13 @@
+ if (pdc_add_valid(address))
+ goto out_err;
+
+- sig = __raw_readl(address);
++ sig = gsc_readl(address);
+
+ /* check for a PCI ROM structure */
+ if ((le32_to_cpu(sig)==0xaa55)) {
+ unsigned int i, rm_offset;
+ u32 *rm;
+- i = __raw_readl(address+0x04);
++ i = gsc_readl(address+0x04);
+ if (i != 1) {
+ /* The ROM could have multiple architecture
+ * dependent images (e.g. i386, parisc,...) */
+@@ -842,17 +850,17 @@
+
+ sti->pd = pd;
+
+- i = __raw_readl(address+0x0c);
++ i = gsc_readl(address+0x0c);
+ DPRINTK(("PCI ROM size (from header) = %d kB\n",
+ le16_to_cpu(i>>16)*512/1024));
+ rm_offset = le16_to_cpu(i & 0xffff);
+ if (rm_offset) {
+ /* read 16 bytes from the pci region mapper array */
+ rm = (u32*) &sti->rm_entry;
+- *rm++ = __raw_readl(address+rm_offset+0x00);
+- *rm++ = __raw_readl(address+rm_offset+0x04);
+- *rm++ = __raw_readl(address+rm_offset+0x08);
+- *rm++ = __raw_readl(address+rm_offset+0x0c);
++ *rm++ = gsc_readl(address+rm_offset+0x00);
++ *rm++ = gsc_readl(address+rm_offset+0x04);
++ *rm++ = gsc_readl(address+rm_offset+0x08);
++ *rm++ = gsc_readl(address+rm_offset+0x0c);
+ DPRINTK(("PCI region Mapper offset = %08x: ",
+ rm_offset));
+ for (i=0; i<16; i++)
+@@ -860,7 +868,7 @@
+ DPRINTK(("\n"));
+ }
+
+- address += le32_to_cpu(__raw_readl(address+8));
++ address += le32_to_cpu(gsc_readl(address+8));
+ DPRINTK(("sig %04x, PCI STI ROM at %08lx\n", sig, address));
+ goto test_rom;
+ }
+@@ -1003,17 +1011,17 @@
+
+
+ static struct pci_device_id sti_pci_tbl[] = {
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_EG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FX6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FX4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FX2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FXE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
++ { PCI_DEVICE(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_EG) },
++ { PCI_DEVICE(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FX6) },
++ { PCI_DEVICE(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FX4) },
++ { PCI_DEVICE(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FX2) },
++ { PCI_DEVICE(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_VISUALIZE_FXE) },
+ { 0, } /* terminate list */
+ };
+ MODULE_DEVICE_TABLE(pci, sti_pci_tbl);
+
+ static struct pci_driver pci_sti_driver = {
+- .name = "sti (pci)",
++ .name = "sti",
+ .id_table = sti_pci_tbl,
+ .probe = sticore_pci_init,
+ .remove = sticore_pci_remove,
+@@ -1026,7 +1034,7 @@
+ };
+
+ static struct parisc_driver pa_sti_driver = {
+- .name = "sti (native)",
++ .name = "sti",
+ .id_table = sti_pa_tbl,
+ .probe = sticore_pa_init,
+ };
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/drivers/video/stifb.c CVS2_6_11_PA2/drivers/video/stifb.c
+--- LINUS_2_6_11/drivers/video/stifb.c 2005-03-02 04:19:16.000000000 -0700
++++ CVS2_6_11_PA2/drivers/video/stifb.c 2004-11-29 13:42:47.000000000 -0700
+@@ -112,11 +112,10 @@
+ ngle_rom_t ngle_rom;
+ struct sti_struct *sti;
+ int deviceSpecificConfig;
+- u32 pseudo_palette[16];
++ u32 pseudo_palette[256];
+ };
+
+-static int __initdata bpp = 8; /* parameter from modprobe */
+-static int __initdata stifb_force_bpp[MAX_STI_ROMS];
++static int __initdata stifb_bpp_pref[MAX_STI_ROMS];
+
+ /* ------------------- chipset specific functions -------------------------- */
+
+@@ -155,15 +154,15 @@
+ #define REG_44 0x210030
+ #define REG_45 0x210034
+
+-#define READ_BYTE(fb,reg) __raw_readb((fb)->info.fix.mmio_start + (reg))
+-#define READ_WORD(fb,reg) __raw_readl((fb)->info.fix.mmio_start + (reg))
++#define READ_BYTE(fb,reg) gsc_readb((fb)->info.fix.mmio_start + (reg))
++#define READ_WORD(fb,reg) gsc_readl((fb)->info.fix.mmio_start + (reg))
+
+
+ #ifndef DEBUG_STIFB_REGS
+ # define DEBUG_OFF()
+ # define DEBUG_ON()
+-# define WRITE_BYTE(value,fb,reg) __raw_writeb((value),(fb)->info.fix.mmio_start + (reg))
+-# define WRITE_WORD(value,fb,reg) __raw_writel((value),(fb)->info.fix.mmio_start + (reg))
++# define WRITE_BYTE(value,fb,reg) gsc_writeb((value),(fb)->info.fix.mmio_start + (reg))
++# define WRITE_WORD(value,fb,reg) gsc_writel((value),(fb)->info.fix.mmio_start + (reg))
+ #else
+ static int debug_on = 1;
+ # define DEBUG_OFF() debug_on=0
+@@ -171,11 +170,11 @@
+ # define WRITE_BYTE(value,fb,reg) do { if (debug_on) \
+ printk(KERN_DEBUG "%30s: WRITE_BYTE(0x%06x) = 0x%02x (old=0x%02x)\n", \
+ __FUNCTION__, reg, value, READ_BYTE(fb,reg)); \
+- __raw_writeb((value),(fb)->info.fix.mmio_start + (reg)); } while (0)
++ gsc_writeb((value),(fb)->info.fix.mmio_start + (reg)); } while (0)
+ # define WRITE_WORD(value,fb,reg) do { if (debug_on) \
+ printk(KERN_DEBUG "%30s: WRITE_WORD(0x%06x) = 0x%08x (old=0x%08x)\n", \
+ __FUNCTION__, reg, value, READ_WORD(fb,reg)); \
+- __raw_writel((value),(fb)->info.fix.mmio_start + (reg)); } while (0)
++ gsc_writel((value),(fb)->info.fix.mmio_start + (reg)); } while (0)
+ #endif /* DEBUG_STIFB_REGS */
+
+
+@@ -1018,6 +1017,15 @@
+ (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;
++ }
++
+ WRITE_IMAGE_COLOR(fb, regno, color);
+
+ if (fb->id == S9000_ID_HCRX) {
+@@ -1031,14 +1039,6 @@
+ /* 0x100 is same as used in WRITE_IMAGE_COLOR() */
+ START_COLORMAPLOAD(fb, lutBltCtl.all);
+ SETUP_FB(fb);
+-
+- /* info->var.bits_per_pixel == 32 */
+- if (regno < 16)
+- ((u32 *)(info->pseudo_palette))[regno] =
+- (red << info->var.red.offset) |
+- (green << info->var.green.offset) |
+- (blue << info->var.blue.offset);
+-
+ } else {
+ /* cleanup colormap hardware */
+ FINISH_IMAGE_COLORMAP_ACCESS(fb);
+@@ -1156,7 +1156,7 @@
+ */
+
+ int __init
+-stifb_init_fb(struct sti_struct *sti, int force_bpp)
++stifb_init_fb(struct sti_struct *sti, int bpp_pref)
+ {
+ struct fb_fix_screeninfo *fix;
+ struct fb_var_screeninfo *var;
+@@ -1257,10 +1257,10 @@
+ #ifdef __LP64__
+ sti_rom_address |= 0xffffffff00000000;
+ #endif
+- fb->deviceSpecificConfig = __raw_readl(sti_rom_address);
++ fb->deviceSpecificConfig = gsc_readl(sti_rom_address);
+ if (IS_24_DEVICE(fb)) {
+- if (force_bpp == 8 || force_bpp == 32)
+- bpp = force_bpp;
++ if (bpp_pref == 8 || bpp_pref == 32)
++ bpp = bpp_pref;
+ else
+ bpp = 32;
+ } else
+@@ -1409,21 +1409,24 @@
+
+ def_sti = sti_get_rom(0);
+ if (def_sti) {
+- for (i = 1; i < MAX_STI_ROMS; i++) {
++ for (i = 1; i <= MAX_STI_ROMS; i++) {
+ sti = sti_get_rom(i);
+- if (sti == def_sti && bpp > 0)
+- stifb_force_bpp[i] = bpp;
++ if (!sti)
++ break;
++ if (sti == def_sti) {
++ stifb_init_fb(sti, stifb_bpp_pref[i - 1]);
++ break;
++ }
+ }
+- stifb_init_fb(def_sti, stifb_force_bpp[i]);
+ }
+
+- for (i = 1; i < MAX_STI_ROMS; i++) {
++ for (i = 1; i <= MAX_STI_ROMS; i++) {
+ sti = sti_get_rom(i);
+- if (!sti || sti==def_sti)
++ if (!sti)
+ break;
+- if (bpp > 0)
+- stifb_force_bpp[i] = bpp;
+- stifb_init_fb(sti, stifb_force_bpp[i]);
++ if (sti == def_sti)
++ continue;
++ stifb_init_fb(sti, stifb_bpp_pref[i - 1]);
+ }
+ return 0;
+ }
+@@ -1438,7 +1441,7 @@
+ struct sti_struct *sti;
+ int i;
+
+- for (i = 1; i < MAX_STI_ROMS; i++) {
++ for (i = 1; i <= MAX_STI_ROMS; i++) {
+ sti = sti_get_rom(i);
+ if (!sti)
+ break;
+@@ -1470,11 +1473,9 @@
+ if (strncmp(options, "bpp", 3) == 0) {
+ options += 3;
+ for (i = 0; i < MAX_STI_ROMS; i++) {
+- if (*options++ == ':') {
+- stifb_force_bpp[i] = simple_strtoul(options, &options, 10);
+- bpp = -1;
+- } else
++ if (*options++ != ':')
+ break;
++ stifb_bpp_pref[i] = simple_strtoul(options, &options, 10);
+ }
+ }
+ return 0;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/fs/Kconfig CVS2_6_11_PA2/fs/Kconfig
+--- LINUS_2_6_11/fs/Kconfig 2005-03-02 04:19:17.000000000 -0700
++++ CVS2_6_11_PA2/fs/Kconfig 2005-02-13 19:55:28.000000000 -0700
+@@ -1400,6 +1400,7 @@
+ tristate "NFS server support"
+ depends on INET
+ select LOCKD
++ select EXPORTFS
+ select SUNRPC
+ select EXPORTFS
+ help
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/fs/smbfs/inode.c CVS2_6_11_PA2/fs/smbfs/inode.c
+--- LINUS_2_6_11/fs/smbfs/inode.c 2005-03-02 04:19:18.000000000 -0700
++++ CVS2_6_11_PA2/fs/smbfs/inode.c 2005-01-12 13:17:32.000000000 -0700
+@@ -564,6 +564,7 @@
+
+ mnt->ttl = SMB_TTL_DEFAULT;
+ if (ver == SMB_MOUNT_OLDVERSION) {
++#ifdef CONFIG_UID16
+ mnt->version = oldmnt->version;
+
+ SET_UID(mnt->uid, oldmnt->uid);
+@@ -574,6 +575,9 @@
+
+ mnt->flags = (oldmnt->file_mode >> 9) | SMB_MOUNT_UID |
+ SMB_MOUNT_GID | SMB_MOUNT_FMODE | SMB_MOUNT_DMODE;
++#else
++ goto out_bad_option;
++#endif
+ } else {
+ mnt->file_mode = S_IRWXU | S_IRGRP | S_IXGRP |
+ S_IROTH | S_IXOTH | S_IFREG;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-generic/compat_signal.h CVS2_6_11_PA2/include/asm-generic/compat_signal.h
+--- LINUS_2_6_11/include/asm-generic/compat_signal.h 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/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_11/include/asm-generic/siginfo.h CVS2_6_11_PA2/include/asm-generic/siginfo.h
+--- LINUS_2_6_11/include/asm-generic/siginfo.h 2005-03-02 04:19:19.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-generic/siginfo.h 2005-01-12 13:17:46.000000000 -0700
+@@ -237,9 +237,13 @@
+ #define SIGEV_THREAD 2 /* deliver via thread creation */
+ #define SIGEV_THREAD_ID 4 /* deliver to thread */
+
++#ifndef __ARCH_SIGEV_PREAMBLE_SIZE
++#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(int) * 2 + sizeof(sigval_t))
++#endif
++
+ #define SIGEV_MAX_SIZE 64
+ #ifndef SIGEV_PAD_SIZE
+-#define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3)
++#define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE - __ARCH_SIGEV_PREAMBLE_SIZE)/sizeof(int))
+ #endif
+
+ typedef struct sigevent {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-ia64/compat.h CVS2_6_11_PA2/include/asm-ia64/compat.h
+--- LINUS_2_6_11/include/asm-ia64/compat.h 2005-03-02 04:19:19.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-ia64/compat.h 2004-10-11 15:41: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;
+@@ -27,6 +30,7 @@
+ typedef s32 compat_daddr_t;
+ typedef u32 compat_caddr_t;
+ typedef __kernel_fsid_t compat_fsid_t;
++typedef s32 compat_timer_t;
+
+ typedef s32 compat_int_t;
+ typedef s32 compat_long_t;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/assembly.h CVS2_6_11_PA2/include/asm-parisc/assembly.h
+--- LINUS_2_6_11/include/asm-parisc/assembly.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/assembly.h 2005-02-04 12:34:33.000000000 -0700
+@@ -37,6 +37,7 @@
+ #define LDREGX ldwx,s
+ #define LDREGM ldwm
+ #define STREGM stwm
++#define SHRREG shr
+ #define RP_OFFSET 20
+ #define FRAME_SIZE 64
+ #define CALLEE_SAVE_FRAME_SIZE 128
+@@ -44,7 +45,7 @@
+
+ #ifdef CONFIG_PA20
+ #define BL b,l
+-# ifdef CONFIG_PARISC64
++# ifdef CONFIG_64BIT
+ # define LEVEL 2.0w
+ # else
+ # define LEVEL 2.0
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/bitops.h CVS2_6_11_PA2/include/asm-parisc/bitops.h
+--- LINUS_2_6_11/include/asm-parisc/bitops.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/bitops.h 2005-02-18 07:22:09.000000000 -0700
+@@ -446,14 +446,14 @@
+ * disabling interrupts.
+ */
+ #ifdef __LP64__
+-#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr)
++#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr)
+ #define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr)
+-#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr)
++#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr)
+ #define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr)
+ #else
+-#define ext2_set_bit(nr, addr) test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr)
++#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr)
+ #define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr)
+-#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr)
++#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr)
+ #define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr)
+ #endif
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/checksum.h CVS2_6_11_PA2/include/asm-parisc/checksum.h
+--- LINUS_2_6_11/include/asm-parisc/checksum.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/checksum.h 2005-01-22 07:59:50.000000000 -0700
+@@ -30,8 +30,8 @@
+ * this is a new version of the above that records errors it finds in *errp,
+ * but continues and zeros the rest of the buffer.
+ */
+-extern unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst,
+- int len, unsigned int sum, int *errp);
++extern unsigned int csum_partial_copy_from_user(const unsigned char __user *src,
++ unsigned char *dst, int len, unsigned int sum, int *errp);
+
+ /*
+ * Optimized for IP headers, which always checksum on 4 octet boundaries.
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/compat.h CVS2_6_11_PA2/include/asm-parisc/compat.h
+--- LINUS_2_6_11/include/asm-parisc/compat.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/compat.h 2004-10-04 13:12:50.000000000 -0600
+@@ -131,15 +131,15 @@
+ */
+ typedef u32 compat_uptr_t;
+
+-static inline void *compat_ptr(compat_uptr_t uptr)
++static inline void __user *compat_ptr(compat_uptr_t uptr)
+ {
+- return (void *)(unsigned long)uptr;
++ return (void __user *)(unsigned long)uptr;
+ }
+
+-static __inline__ void *compat_alloc_user_space(long len)
++static __inline__ void __user *compat_alloc_user_space(long len)
+ {
+ struct pt_regs *regs = ¤t->thread.regs;
+- return (void *)regs->gr[30];
++ return (void __user *)regs->gr[30];
+ }
+
+ #endif /* _ASM_PARISC_COMPAT_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/dma-mapping.h CVS2_6_11_PA2/include/asm-parisc/dma-mapping.h
+--- LINUS_2_6_11/include/asm-parisc/dma-mapping.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/dma-mapping.h 2004-09-14 09:07:26.000000000 -0600
+@@ -1,8 +1,8 @@
+ #ifndef _PARISC_DMA_MAPPING_H
+ #define _PARISC_DMA_MAPPING_H
+
+-#include <linux/mm.h>
+ #include <linux/config.h>
++#include <linux/mm.h>
+ #include <asm/cacheflush.h>
+ #include <asm/scatterlist.h>
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/eisa_eeprom.h CVS2_6_11_PA2/include/asm-parisc/eisa_eeprom.h
+--- LINUS_2_6_11/include/asm-parisc/eisa_eeprom.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/eisa_eeprom.h 2005-02-15 08:23:58.000000000 -0700
+@@ -13,6 +13,8 @@
+ #ifndef ASM_EISA_EEPROM_H
+ #define ASM_EISA_EEPROM_H
+
++extern void __iomem *eisa_eeprom_addr;
++
+ #define HPEE_MAX_LENGTH 0x2000 /* maximum eeprom length */
+
+ #define HPEE_SLOT_INFO(slot) (20+(48*slot))
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/hardirq.h CVS2_6_11_PA2/include/asm-parisc/hardirq.h
+--- LINUS_2_6_11/include/asm-parisc/hardirq.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/hardirq.h 2005-03-01 23:47:37.000000000 -0700
+@@ -15,9 +15,7 @@
+ #ifndef _PARISC_HARDIRQ_H
+ #define _PARISC_HARDIRQ_H
+
+-#include <linux/config.h>
+ #include <linux/threads.h>
+-#include <linux/cache.h>
+ #include <linux/irq.h>
+
+ typedef struct {
+@@ -26,16 +24,6 @@
+
+ #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+-#define HARDIRQ_BITS 16
+-
+-/*
+- * The hardirq mask has to be large enough to have space for potentially all
+- * IRQ sources in the system nesting on a single CPU:
+- */
+-#if (1 << HARDIRQ_BITS) < NR_IRQS
+-# error HARDIRQ_BITS is too low!
+-#endif
+-
+ void ack_bad_irq(unsigned int irq);
+
+ #endif /* _PARISC_HARDIRQ_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/hardware.h CVS2_6_11_PA2/include/asm-parisc/hardware.h
+--- LINUS_2_6_11/include/asm-parisc/hardware.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/hardware.h 2005-01-26 09:23:27.000000000 -0700
+@@ -122,6 +122,7 @@
+ extern void get_pci_node_path(struct pci_dev *dev, struct hardware_path *path);
+ extern void init_parisc_bus(void);
+ extern struct device *hwpath_to_device(struct hardware_path *modpath);
++extern void device_to_hwpath(struct device *dev, struct hardware_path *path);
+
+
+ /* inventory.c: */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/ide.h CVS2_6_11_PA2/include/asm-parisc/ide.h
+--- LINUS_2_6_11/include/asm-parisc/ide.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/ide.h 2005-03-01 23:47:37.000000000 -0700
+@@ -13,8 +13,6 @@
+
+ #ifdef __KERNEL__
+
+-#include <linux/config.h>
+-
+ #ifndef MAX_HWIFS
+ #define MAX_HWIFS 2
+ #endif
+@@ -34,7 +32,7 @@
+ #define __ide_outsw outsw
+ #define __ide_outsl outsl
+
+-static __inline__ void __ide_mm_insw(unsigned long port, void *addr, u32 count)
++static __inline__ void __ide_mm_insw(void __iomem *port, void *addr, u32 count)
+ {
+ while (count--) {
+ *(u16 *)addr = __raw_readw(port);
+@@ -42,7 +40,7 @@
+ }
+ }
+
+-static __inline__ void __ide_mm_insl(unsigned long port, void *addr, u32 count)
++static __inline__ void __ide_mm_insl(void __iomem *port, void *addr, u32 count)
+ {
+ while (count--) {
+ *(u32 *)addr = __raw_readl(port);
+@@ -50,7 +48,7 @@
+ }
+ }
+
+-static __inline__ void __ide_mm_outsw(unsigned long port, void *addr, u32 count)
++static __inline__ void __ide_mm_outsw(void __iomem *port, void *addr, u32 count)
+ {
+ while (count--) {
+ __raw_writew(*(u16 *)addr, port);
+@@ -58,7 +56,7 @@
+ }
+ }
+
+-static __inline__ void __ide_mm_outsl(unsigned long port, void *addr, u32 count)
++static __inline__ void __ide_mm_outsl(void __iomem *port, void *addr, u32 count)
+ {
+ while (count--) {
+ __raw_writel(*(u32 *)addr, port);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/io.h CVS2_6_11_PA2/include/asm-parisc/io.h
+--- LINUS_2_6_11/include/asm-parisc/io.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/io.h 2005-02-15 16:26:13.000000000 -0700
+@@ -273,10 +273,11 @@
+ }
+ #endif /* !USE_HPPA_IOREMAP */
+
++/* readb can never be const, so use __fswab instead of le*_to_cpu */
+ #define readb(addr) __raw_readb(addr)
+-#define readw(addr) le16_to_cpu(__raw_readw(addr))
+-#define readl(addr) le32_to_cpu(__raw_readl(addr))
+-#define readq(addr) le64_to_cpu(__raw_readq(addr))
++#define readw(addr) __fswab16(__raw_readw(addr))
++#define readl(addr) __fswab32(__raw_readl(addr))
++#define readq(addr) __fswab64(__raw_readq(addr))
+ #define writeb(b, addr) __raw_writeb(b, addr)
+ #define writew(b, addr) __raw_writew(cpu_to_le16(b), addr)
+ #define writel(b, addr) __raw_writel(cpu_to_le32(b), addr)
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/irq.h CVS2_6_11_PA2/include/asm-parisc/irq.h
+--- LINUS_2_6_11/include/asm-parisc/irq.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/irq.h 2005-01-22 07:59:50.000000000 -0700
+@@ -40,10 +40,12 @@
+ void no_ack_irq(unsigned int irq);
+ void no_end_irq(unsigned int irq);
+
+-extern int txn_alloc_irq(void);
++extern int txn_alloc_irq(unsigned int nbits);
+ extern int txn_claim_irq(int);
+-extern unsigned int txn_alloc_data(int, unsigned int);
+-extern unsigned long txn_alloc_addr(int);
++extern unsigned int txn_alloc_data(unsigned int);
++extern unsigned long txn_alloc_addr(unsigned int);
++
++extern int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *, void *);
+
+ extern int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *, void *);
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/led.h CVS2_6_11_PA2/include/asm-parisc/led.h
+--- LINUS_2_6_11/include/asm-parisc/led.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/led.h 2004-12-30 01:07:48.000000000 -0700
+@@ -21,19 +21,23 @@
+ #define DISPLAY_MODEL_LASI 2 /* LASI style 8 bit LED */
+ #define DISPLAY_MODEL_OLD_ASP 0x7F /* faked: ASP style 8 x 1 bit LED (only very old ASP versions) */
+
+-#define LED_CMD_REG_NONE NULL /* NULL == no addr for the cmd register */
++#define LED_CMD_REG_NONE 0 /* NULL == no addr for the cmd register */
+
+ /* led tasklet struct */
+ extern struct tasklet_struct led_tasklet;
+
+ /* register_led_driver() */
+-int __init register_led_driver( int model, char *cmd_reg, char *data_reg );
++int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long data_reg);
+
+ /* registers the LED regions for procfs */
+ void __init register_led_regions(void);
+
++#ifdef CONFIG_CHASSIS_LCD_LED
+ /* writes a string to the LCD display (if possible on this h/w) */
+ int lcd_print(char *str);
++#else
++#define lcd_print(str)
++#endif
+
+ /* main LED initialization function (uses PDC) */
+ int __init led_init(void);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/module.h CVS2_6_11_PA2/include/asm-parisc/module.h
+--- LINUS_2_6_11/include/asm-parisc/module.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/module.h 2005-02-25 07:54:20.000000000 -0700
+@@ -17,12 +17,16 @@
+ #define Elf_Rela Elf32_Rela
+ #endif
+
++struct unwind_table;
++
+ struct mod_arch_specific
+ {
+ unsigned long got_offset, got_count, got_max;
+ unsigned long fdesc_offset, fdesc_count, fdesc_max;
+ unsigned long stub_offset, stub_count, stub_max;
+ unsigned long init_stub_offset, init_stub_count, init_stub_max;
++ int unwind_section;
++ struct unwind_table *unwind;
+ };
+
+ #endif /* _ASM_PARISC_MODULE_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/numnodes.h CVS2_6_11_PA2/include/asm-parisc/numnodes.h
+--- LINUS_2_6_11/include/asm-parisc/numnodes.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/numnodes.h 2005-03-01 23:47:37.000000000 -0700
+@@ -1,8 +1,6 @@
+ #ifndef _ASM_MAX_NUMNODES_H
+ #define _ASM_MAX_NUMNODES_H
+
+-#include <linux/config.h>
+-
+ /* Max 8 Nodes */
+ #define NODES_SHIFT 3
+
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/parisc-device.h CVS2_6_11_PA2/include/asm-parisc/parisc-device.h
+--- LINUS_2_6_11/include/asm-parisc/parisc-device.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/parisc-device.h 2005-02-03 05:48:16.000000000 -0700
+@@ -6,6 +6,7 @@
+ struct parisc_driver *driver; /* Driver for this device */
+ char name[80]; /* The hardware description */
+ int irq;
++ int aux_irq; /* Some devices have a second IRQ */
+
+ char hw_path; /* The module number on this bus */
+ unsigned int num_addrs; /* some devices have additional address ranges. */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/parport_gsc.h CVS2_6_11_PA2/include/asm-parisc/parport_gsc.h
+--- LINUS_2_6_11/include/asm-parisc/parport_gsc.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/parport_gsc.h 1969-12-31 17:00:00.000000000 -0700
+@@ -1,193 +0,0 @@
+-#ifndef __LINUX_PARPORT_GSC_H
+-#define __LINUX_PARPORT_GSC_H
+-
+-#include <asm/io.h>
+-#include <linux/delay.h>
+-
+-#undef DEBUG_PARPORT /* undefine for production */
+-#define DELAY_TIME 0
+-
+-#if DELAY_TIME == 0
+-#define parport_readb gsc_readb
+-#define parport_writeb gsc_writeb
+-#else
+-static __inline__ unsigned char parport_readb( unsigned long port )
+-{
+- udelay(DELAY_TIME);
+- return gsc_readb(port);
+-}
+-
+-static __inline__ void parport_writeb( unsigned char value, unsigned long port )
+-{
+- gsc_writeb(value,port);
+- udelay(DELAY_TIME);
+-}
+-#endif
+-
+-/* --- register definitions ------------------------------- */
+-
+-#define EPPDATA(p) ((p)->base + 0x4)
+-#define EPPADDR(p) ((p)->base + 0x3)
+-#define CONTROL(p) ((p)->base + 0x2)
+-#define STATUS(p) ((p)->base + 0x1)
+-#define DATA(p) ((p)->base + 0x0)
+-
+-struct parport_gsc_private {
+- /* Contents of CTR. */
+- unsigned char ctr;
+-
+- /* Bitmask of writable CTR bits. */
+- unsigned char ctr_writable;
+-
+- /* Number of bytes per portword. */
+- int pword;
+-
+- /* Not used yet. */
+- int readIntrThreshold;
+- int writeIntrThreshold;
+-
+- /* buffer suitable for DMA, if DMA enabled */
+- char *dma_buf;
+- dma_addr_t dma_handle;
+- struct pci_dev *dev;
+-};
+-
+-extern __inline__ void parport_gsc_write_data(struct parport *p, unsigned char d)
+-{
+-#ifdef DEBUG_PARPORT
+- printk (KERN_DEBUG "parport_gsc_write_data(%p,0x%02x)\n", p, d);
+-#endif
+- parport_writeb(d, DATA(p));
+-}
+-
+-extern __inline__ unsigned char parport_gsc_read_data(struct parport *p)
+-{
+- unsigned char val = parport_readb (DATA (p));
+-#ifdef DEBUG_PARPORT
+- printk (KERN_DEBUG "parport_gsc_read_data(%p) = 0x%02x\n",
+- p, val);
+-#endif
+- return val;
+-}
+-
+-/* __parport_gsc_frob_control differs from parport_gsc_frob_control in that
+- * it doesn't do any extra masking. */
+-static __inline__ unsigned char __parport_gsc_frob_control (struct parport *p,
+- unsigned char mask,
+- unsigned char val)
+-{
+- struct parport_gsc_private *priv = p->physport->private_data;
+- unsigned char ctr = priv->ctr;
+-#ifdef DEBUG_PARPORT
+- printk (KERN_DEBUG
+- "__parport_gsc_frob_control(%02x,%02x): %02x -> %02x\n",
+- mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable);
+-#endif
+- ctr = (ctr & ~mask) ^ val;
+- ctr &= priv->ctr_writable; /* only write writable bits. */
+- parport_writeb (ctr, CONTROL (p));
+- priv->ctr = ctr; /* Update soft copy */
+- return ctr;
+-}
+-
+-extern __inline__ void parport_gsc_data_reverse (struct parport *p)
+-{
+- __parport_gsc_frob_control (p, 0x20, 0x20);
+-}
+-
+-extern __inline__ void parport_gsc_data_forward (struct parport *p)
+-{
+- __parport_gsc_frob_control (p, 0x20, 0x00);
+-}
+-
+-extern __inline__ void parport_gsc_write_control (struct parport *p,
+- unsigned char d)
+-{
+- const unsigned char wm = (PARPORT_CONTROL_STROBE |
+- PARPORT_CONTROL_AUTOFD |
+- PARPORT_CONTROL_INIT |
+- PARPORT_CONTROL_SELECT);
+-
+- /* Take this out when drivers have adapted to newer interface. */
+- if (d & 0x20) {
+- printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n",
+- p->name, p->cad->name);
+- parport_gsc_data_reverse (p);
+- }
+-
+- __parport_gsc_frob_control (p, wm, d & wm);
+-}
+-
+-extern __inline__ unsigned char parport_gsc_read_control(struct parport *p)
+-{
+- const unsigned char rm = (PARPORT_CONTROL_STROBE |
+- PARPORT_CONTROL_AUTOFD |
+- PARPORT_CONTROL_INIT |
+- PARPORT_CONTROL_SELECT);
+- const struct parport_gsc_private *priv = p->physport->private_data;
+- return priv->ctr & rm; /* Use soft copy */
+-}
+-
+-extern __inline__ unsigned char parport_gsc_frob_control (struct parport *p,
+- unsigned char mask,
+- unsigned char val)
+-{
+- const unsigned char wm = (PARPORT_CONTROL_STROBE |
+- PARPORT_CONTROL_AUTOFD |
+- PARPORT_CONTROL_INIT |
+- PARPORT_CONTROL_SELECT);
+-
+- /* Take this out when drivers have adapted to newer interface. */
+- if (mask & 0x20) {
+- printk (KERN_DEBUG "%s (%s): use data_%s for this!\n",
+- p->name, p->cad->name,
+- (val & 0x20) ? "reverse" : "forward");
+- if (val & 0x20)
+- parport_gsc_data_reverse (p);
+- else
+- parport_gsc_data_forward (p);
+- }
+-
+- /* Restrict mask and val to control lines. */
+- mask &= wm;
+- val &= wm;
+-
+- return __parport_gsc_frob_control (p, mask, val);
+-}
+-
+-extern __inline__ unsigned char parport_gsc_read_status(struct parport *p)
+-{
+- return parport_readb (STATUS(p));
+-}
+-
+-
+-extern __inline__ void parport_gsc_disable_irq(struct parport *p)
+-{
+- __parport_gsc_frob_control (p, 0x10, 0x00);
+-}
+-
+-extern __inline__ void parport_gsc_enable_irq(struct parport *p)
+-{
+- __parport_gsc_frob_control (p, 0x10, 0x10);
+-}
+-
+-extern void parport_gsc_release_resources(struct parport *p);
+-
+-extern int parport_gsc_claim_resources(struct parport *p);
+-
+-extern void parport_gsc_init_state(struct pardevice *, struct parport_state *s);
+-
+-extern void parport_gsc_save_state(struct parport *p, struct parport_state *s);
+-
+-extern void parport_gsc_restore_state(struct parport *p, struct parport_state *s);
+-
+-extern void parport_gsc_inc_use_count(void);
+-
+-extern void parport_gsc_dec_use_count(void);
+-
+-extern struct parport *parport_gsc_probe_port (unsigned long base,
+- unsigned long base_hi,
+- int irq, int dma,
+- struct pci_dev *dev);
+-
+-#endif
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/pci.h CVS2_6_11_PA2/include/asm-parisc/pci.h
+--- LINUS_2_6_11/include/asm-parisc/pci.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/pci.h 2005-02-04 12:34:33.000000000 -0700
+@@ -28,7 +28,7 @@
+ ** Data needed by pcibios layer belongs here.
+ */
+ struct pci_hba_data {
+- unsigned long base_addr; /* aka Host Physical Address */
++ void __iomem *base_addr; /* aka Host Physical Address */
+ const struct parisc_device *dev; /* device from PA bus walk */
+ struct pci_bus *hba_bus; /* primary PCI bus below HBA */
+ int hba_num; /* I/O port space access "key" */
+@@ -69,7 +69,7 @@
+ #define PCI_PORT_HBA(a) ((a) >> HBA_PORT_SPACE_BITS)
+ #define PCI_PORT_ADDR(a) ((a) & (HBA_PORT_SPACE_SIZE - 1))
+
+-#if CONFIG_PARISC64
++#if CONFIG_64BIT
+ #define PCI_F_EXTEND 0xffffffff00000000UL
+ #define PCI_IS_LMMIO(hba,a) pci_is_lmmio(hba,a)
+
+@@ -90,14 +90,14 @@
+ : (a)) /* GMMIO */
+ #define PCI_HOST_ADDR(hba,a) ((a) + hba->lmmio_space_offset)
+
+-#else /* !CONFIG_PARISC64 */
++#else /* !CONFIG_64BIT */
+
+ #define PCI_BUS_ADDR(hba,a) (a)
+ #define PCI_HOST_ADDR(hba,a) (a)
+ #define PCI_F_EXTEND 0UL
+ #define PCI_IS_LMMIO(hba,a) (1) /* 32-bit doesn't support GMMIO */
+
+-#endif /* !CONFIG_PARISC64 */
++#endif /* !CONFIG_64BIT */
+
+ /*
+ ** KLUGE: linux/pci.h include asm/pci.h BEFORE declaring struct pci_bus
+@@ -106,11 +106,28 @@
+ struct pci_bus;
+ struct pci_dev;
+
+-/* The PCI address space does equal the physical memory
+- * address space. The networking and block device layers use
++/*
++ * If the PCI device's view of memory is the same as the CPU's view of memory,
++ * PCI_DMA_BUS_IS_PHYS is true. The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+-#define PCI_DMA_BUS_IS_PHYS (1)
++#ifdef CONFIG_PA20
++/* All PA-2.0 machines have an IOMMU. */
++#define PCI_DMA_BUS_IS_PHYS 0
++#define parisc_has_iommu() do { } while (0)
++#else
++
++#if defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA)
++extern int parisc_bus_is_phys; /* in arch/parisc/kernel/setup.c */
++#define PCI_DMA_BUS_IS_PHYS parisc_bus_is_phys
++#define parisc_has_iommu() do { parisc_bus_is_phys = 0; } while (0)
++#else
++#define PCI_DMA_BUS_IS_PHYS 1
++#define parisc_has_iommu() do { } while (0)
++#endif
++
++#endif /* !CONFIG_PA20 */
++
+
+ /*
+ ** Most PCI devices (eg Tulip, NCR720) also export the same registers
+@@ -182,16 +199,25 @@
+ #endif
+
+ /*
+-** used by drivers/pci/pci.c:pci_do_scan_bus()
+-** 0 == check if bridge is numbered before re-numbering.
+-** 1 == pci_do_scan_bus() should automatically number all PCI-PCI bridges.
+-**
+-** REVISIT:
+-** To date, only alpha sets this to one. We'll need to set this
+-** to zero for legacy platforms and one for PAT platforms.
+-*/
+-#define pcibios_assign_all_busses() (pdc_type == PDC_TYPE_PAT)
+-#define pcibios_scan_all_fns(a, b) 0
++ * pcibios_assign_all_busses() is used in drivers/pci/pci.c:pci_do_scan_bus()
++ * 0 == check if bridge is numbered before re-numbering.
++ * 1 == pci_do_scan_bus() should automatically number all PCI-PCI bridges.
++ *
++ * We *should* set this to zero for "legacy" platforms and one
++ * for PAT platforms.
++ *
++ * But legacy platforms also need to *re*-enumerate the busses below
++ * a Host Bus controller. Adding a 4-port Tulip card under dino (bus 0)
++ * in a C200 resulted in the secondary bus being enumerated to 1.
++ * The second PCI host bus controller (cujo) had been enumerated by
++ * firmware as bus 1 and sysfs complained.
++ *
++ * The firmware is correct since the second controller is a seperate
++ * PCI domain. This problem could have been fixed by making dino
++ * support use seperate PCI domains but this is alot simpler/easier.
++ */
++#define pcibios_assign_all_busses() (1)
++#define pcibios_scan_all_fns(a, b) (0)
+
+ #define PCIBIOS_MIN_IO 0x10
+ #define PCIBIOS_MIN_MEM 0x1000 /* NBPG - but pci/setup-res.c dies */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/pdc_chassis.h CVS2_6_11_PA2/include/asm-parisc/pdc_chassis.h
+--- LINUS_2_6_11/include/asm-parisc/pdc_chassis.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/pdc_chassis.h 2005-01-13 08:38:43.000000000 -0700
+@@ -1,8 +1,8 @@
+ /*
+- * include/asm-parisc/pdc_chassis.h
++ * include/asm-parisc/pdc_chassis.h
+ *
+- * Copyright (C) 2002 Laurent Canet <canetl at esiee.fr>
+- * Copyright (C) 2002 Thibaut Varene <varenet at esiee.fr>
++ * Copyright (C) 2002 Laurent Canet <canetl at esiee.fr>
++ * Copyright (C) 2002 Thibaut Varene <varenet at parisc-linux.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/pdcpat.h CVS2_6_11_PA2/include/asm-parisc/pdcpat.h
+--- LINUS_2_6_11/include/asm-parisc/pdcpat.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/pdcpat.h 2005-02-04 12:34:33.000000000 -0700
+@@ -190,16 +190,16 @@
+ #ifndef __ASSEMBLY__
+ #include <linux/types.h>
+
+-#ifdef CONFIG_PARISC64
++#ifdef CONFIG_64BIT
+ #define is_pdc_pat() (PDC_TYPE_PAT == pdc_type)
+ extern int pdc_pat_get_irt_size(unsigned long *num_entries, unsigned long cell_num);
+ extern int pdc_pat_get_irt(void *r_addr, unsigned long cell_num);
+-#else /* ! CONFIG_PARISC64 */
++#else /* ! CONFIG_64BIT */
+ /* No PAT support for 32-bit kernels...sorry */
+ #define is_pdc_pat() (0)
+ #define pdc_pat_get_irt_size(num_entries, cell_numn) PDC_BAD_PROC
+ #define pdc_pat_get_irt(r_addr, cell_num) PDC_BAD_PROC
+-#endif /* ! CONFIG_PARISC64 */
++#endif /* ! CONFIG_64BIT */
+
+
+ struct pdc_pat_cell_num {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/serial.h CVS2_6_11_PA2/include/asm-parisc/serial.h
+--- LINUS_2_6_11/include/asm-parisc/serial.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/serial.h 2005-03-01 23:47:37.000000000 -0700
+@@ -2,8 +2,6 @@
+ * include/asm-parisc/serial.h
+ */
+
+-#include <linux/config.h>
+-
+ /*
+ * This assumes you have a 7.272727 MHz clock for your UART.
+ * The documentation implies a 40Mhz clock, and elsewhere a 7Mhz clock
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/signal.h CVS2_6_11_PA2/include/asm-parisc/signal.h
+--- LINUS_2_6_11/include/asm-parisc/signal.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/signal.h 2004-10-04 13:12:50.000000000 -0600
+@@ -123,13 +123,14 @@
+ * compiler doesn't support code which changes or tests the address of
+ * the function in the little struct. This is really ugly -PB
+ */
+-typedef __kernel_caddr_t __sighandler_t;
++typedef char __user *__sighandler_t;
+ #else
+-typedef void (*__sighandler_t)(int);
++typedef void __signalfn_t(int);
++typedef __signalfn_t __user *__sighandler_t;
+ #endif
+
+ typedef struct sigaltstack {
+- void *ss_sp;
++ void __user *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+ } stack_t;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/system.h CVS2_6_11_PA2/include/asm-parisc/system.h
+--- LINUS_2_6_11/include/asm-parisc/system.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/system.h 2005-02-13 20:21:52.000000000 -0700
+@@ -125,7 +125,7 @@
+ ** The __asm__ op below simple prevents gcc/ld from reordering
+ ** instructions across the mb() "call".
+ */
+-#define mb() __asm__ __volatile__("":::"memory"); /* barrier() */
++#define mb() __asm__ __volatile__("":::"memory") /* barrier() */
+ #define rmb() mb()
+ #define wmb() mb()
+ #define smp_mb() mb()
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/thread_info.h CVS2_6_11_PA2/include/asm-parisc/thread_info.h
+--- LINUS_2_6_11/include/asm-parisc/thread_info.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/thread_info.h 2005-02-03 10:28:08.000000000 -0700
+@@ -23,7 +23,7 @@
+ .flags = 0, \
+ .cpu = 0, \
+ .addr_limit = KERNEL_DS, \
+- .preempt_count = 0, \
++ .preempt_count = 1, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall \
+ } \
+@@ -52,7 +52,7 @@
+
+ #endif /* !__ASSEMBLY */
+
+-#define PREEMPT_ACTIVE 0x4000000
++#define PREEMPT_ACTIVE 0x10000000
+
+ /*
+ * thread information flags
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/uaccess.h CVS2_6_11_PA2/include/asm-parisc/uaccess.h
+--- LINUS_2_6_11/include/asm-parisc/uaccess.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/uaccess.h 2005-02-21 09:40:53.000000000 -0700
+@@ -34,7 +34,12 @@
+ extern int __put_kernel_bad(void);
+ extern int __put_user_bad(void);
+
+-#define access_ok(type,addr,size) (1)
++static inline long access_ok(int type, const void __user * addr,
++ unsigned long size)
++{
++ return 1;
++}
++
+ #define verify_area(type,addr,size) (0)
+
+ #define put_user __put_user
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-parisc/unwind.h CVS2_6_11_PA2/include/asm-parisc/unwind.h
+--- LINUS_2_6_11/include/asm-parisc/unwind.h 2005-03-02 04:19:20.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-parisc/unwind.h 2005-03-01 18:20:47.000000000 -0700
+@@ -1,6 +1,8 @@
+ #ifndef _UNWIND_H_
+ #define _UNWIND_H_
+
++#include <linux/list.h>
++
+ /* From ABI specifications */
+ struct unwind_table_entry {
+ unsigned int region_start;
+@@ -39,7 +41,7 @@
+ };
+
+ struct unwind_table {
+- struct unwind_table *next;
++ struct list_head list;
+ const char *name;
+ unsigned long gp;
+ unsigned long base_addr;
+@@ -55,15 +57,18 @@
+ available; but for now we only try to get the sp and ip for each
+ frame */
+ /* struct pt_regs regs; */
+- unsigned long sp, ip, rp;
++ unsigned long sp, ip, rp, r31;
+ unsigned long prev_sp, prev_ip;
+ };
+
+-void * unwind_table_add(const char *name, unsigned long base_addr,
+- unsigned long gp,
+- void *start, void *end);
++struct unwind_table *
++unwind_table_add(const char *name, unsigned long base_addr,
++ unsigned long gp, void *start, void *end);
++void
++unwind_table_remove(struct unwind_table *table);
++
+ void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
+- unsigned long sp, unsigned long ip, unsigned long rp);
++ struct pt_regs *regs);
+ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t);
+ void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs);
+ int unwind_once(struct unwind_frame_info *info);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/asm-s390/compat.h CVS2_6_11_PA2/include/asm-s390/compat.h
+--- LINUS_2_6_11/include/asm-s390/compat.h 2005-03-02 04:19:21.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-s390/compat.h 2004-10-10 15:23:29.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_11/include/asm-sparc64/compat.h CVS2_6_11_PA2/include/asm-sparc64/compat.h
+--- LINUS_2_6_11/include/asm-sparc64/compat.h 2005-03-02 04:19:21.000000000 -0700
++++ CVS2_6_11_PA2/include/asm-sparc64/compat.h 2005-02-24 06:57:13.000000000 -0700
+@@ -12,6 +12,9 @@
+ typedef s32 compat_time_t;
+ typedef s32 compat_clock_t;
+ typedef s32 compat_pid_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 u16 compat_uid_t;
+ typedef u16 compat_gid_t;
+ typedef u16 compat_mode_t;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/linux/compat.h CVS2_6_11_PA2/include/linux/compat.h
+--- LINUS_2_6_11/include/linux/compat.h 2005-03-02 04:19:22.000000000 -0700
++++ CVS2_6_11_PA2/include/linux/compat.h 2005-02-24 06:57:13.000000000 -0700
+@@ -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
++
+ struct rusage;
+
+ struct compat_itimerspec {
+@@ -90,27 +101,6 @@
+ char d_name[256];
+ };
+
+-typedef union compat_sigval {
+- compat_int_t sival_int;
+- compat_uptr_t sival_ptr;
+-} compat_sigval_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[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);
+ long compat_sys_msgrcv(int first, int second, int msgtyp, int third,
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/linux/compat_siginfo.h CVS2_6_11_PA2/include/linux/compat_siginfo.h
+--- LINUS_2_6_11/include/linux/compat_siginfo.h 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/include/linux/compat_siginfo.h 2004-09-27 04:05:39.000000000 -0600
+@@ -0,0 +1,184 @@
++#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 SIGEV_COMPAT_MAX_SIZE 64
++#ifndef SIGEV_COMPAT_PAD_SIZE
++#define SIGEV_COMPAT_PAD_SIZE ((SIGEV_COMPAT_MAX_SIZE - __ARCH_SIGEV_COMPAT_PREAMBLE_SIZE)/sizeof(compat_int_t))
++#endif
++
++#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[SIGEV_COMPAT_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);
++
++#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_11/include/linux/console.h CVS2_6_11_PA2/include/linux/console.h
+--- LINUS_2_6_11/include/linux/console.h 2005-03-02 04:19:22.000000000 -0700
++++ CVS2_6_11_PA2/include/linux/console.h 2005-02-13 19:55:34.000000000 -0700
+@@ -84,6 +84,7 @@
+ #define CON_PRINTBUFFER (1)
+ #define CON_CONSDEV (2) /* Last on the command line */
+ #define CON_ENABLED (4)
++#define CON_BOOT (8)
+
+ struct console
+ {
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/linux/hil.h CVS2_6_11_PA2/include/linux/hil.h
+--- LINUS_2_6_11/include/linux/hil.h 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/include/linux/hil.h 2004-10-31 14:05:59.000000000 -0700
+@@ -0,0 +1,483 @@
++#ifndef _HIL_H_
++#define _HIL_H_
++
++/*
++ * Hewlett Packard Human Interface Loop (HP-HIL) Protocol -- header.
++ *
++ * Copyright (c) 2001 Brian S. Julin
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL").
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
++ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ *
++ * References:
++ * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
++ *
++ * A note of thanks to HP for providing and shipping reference materials
++ * free of charge to help in the development of HIL support for Linux.
++ *
++ */
++
++#include <asm/types.h>
++
++/* Physical constants relevant to raw loop/device timing.
++ */
++
++#define HIL_CLOCK 8MHZ
++#define HIL_EK1_CLOCK 30HZ
++#define HIL_EK2_CLOCK 60HZ
++
++#define HIL_TIMEOUT_DEV 5 /* ms */
++#define HIL_TIMEOUT_DEVS 10 /* ms */
++#define HIL_TIMEOUT_NORESP 10 /* ms */
++#define HIL_TIMEOUT_DEVS_DATA 16 /* ms */
++#define HIL_TIMEOUT_SELFTEST 200 /* ms */
++
++
++/* Actual wire line coding. These will only be useful if someone is
++ * implementing a software MLC to run HIL devices on a non-parisc machine.
++ */
++
++#define HIL_WIRE_PACKET_LEN 15
++enum hil_wire_bitpos {
++ HIL_WIRE_START = 0,
++ HIL_WIRE_ADDR2,
++ HIL_WIRE_ADDR1,
++ HIL_WIRE_ADDR0,
++ HIL_WIRE_COMMAND,
++ HIL_WIRE_DATA7,
++ HIL_WIRE_DATA6,
++ HIL_WIRE_DATA5,
++ HIL_WIRE_DATA4,
++ HIL_WIRE_DATA3,
++ HIL_WIRE_DATA2,
++ HIL_WIRE_DATA1,
++ HIL_WIRE_DATA0,
++ HIL_WIRE_PARITY,
++ HIL_WIRE_STOP
++};
++
++/* HP documentation uses these bit positions to refer to commands;
++ * we will call these "packets".
++ */
++enum hil_pkt_bitpos {
++ HIL_PKT_CMD = 0x00000800,
++ HIL_PKT_ADDR2 = 0x00000400,
++ HIL_PKT_ADDR1 = 0x00000200,
++ HIL_PKT_ADDR0 = 0x00000100,
++ HIL_PKT_ADDR_MASK = 0x00000700,
++ HIL_PKT_ADDR_SHIFT = 8,
++ HIL_PKT_DATA7 = 0x00000080,
++ HIL_PKT_DATA6 = 0x00000040,
++ HIL_PKT_DATA5 = 0x00000020,
++ HIL_PKT_DATA4 = 0x00000010,
++ HIL_PKT_DATA3 = 0x00000008,
++ HIL_PKT_DATA2 = 0x00000004,
++ HIL_PKT_DATA1 = 0x00000002,
++ HIL_PKT_DATA0 = 0x00000001,
++ HIL_PKT_DATA_MASK = 0x000000FF,
++ HIL_PKT_DATA_SHIFT = 0
++};
++
++/* The HIL MLC also has several error/status/control bits. We extend the
++ * "packet" to include these when direct access to the MLC is available,
++ * or emulate them in cases where they are not available.
++ *
++ * This way the device driver knows that the underlying MLC driver
++ * has had to deal with loop errors.
++ */
++enum hil_error_bitpos {
++ HIL_ERR_OB = 0x00000800, /* MLC is busy sending an auto-poll,
++ or we have filled up the output
++ buffer and must wait. */
++ HIL_ERR_INT = 0x00010000, /* A normal interrupt has occurred. */
++ HIL_ERR_NMI = 0x00020000, /* An NMI has occurred. */
++ HIL_ERR_LERR = 0x00040000, /* A poll didn't come back. */
++ HIL_ERR_PERR = 0x01000000, /* There was a Parity Error. */
++ HIL_ERR_FERR = 0x02000000, /* There was a Framing Error. */
++ HIL_ERR_FOF = 0x04000000 /* Input FIFO Overflowed. */
++};
++
++enum hil_control_bitpos {
++ HIL_CTRL_TEST = 0x00010000,
++ HIL_CTRL_IPF = 0x00040000,
++ HIL_CTRL_APE = 0x02000000
++};
++
++/* Bits 30,31 are unused, we use them to control write behavior. */
++#define HIL_DO_ALTER_CTRL 0x40000000 /* Write MSW of packet to control
++ before writing LSW to loop */
++#define HIL_CTRL_ONLY 0xc0000000 /* *Only* alter the control registers */
++
++/* This gives us a 32-bit "packet"
++ */
++typedef u32 hil_packet;
++
++
++/* HIL Loop commands
++ */
++enum hil_command {
++ HIL_CMD_IFC = 0x00, /* Interface Clear */
++ HIL_CMD_EPT = 0x01, /* Enter Pass-Thru Mode */
++ HIL_CMD_ELB = 0x02, /* Enter Loop-Back Mode */
++ HIL_CMD_IDD = 0x03, /* Identify and Describe */
++ HIL_CMD_DSR = 0x04, /* Device Soft Reset */
++ HIL_CMD_PST = 0x05, /* Perform Self Test */
++ HIL_CMD_RRG = 0x06, /* Read Register */
++ HIL_CMD_WRG = 0x07, /* Write Register */
++ HIL_CMD_ACF = 0x08, /* Auto Configure */
++ HIL_CMDID_ACF = 0x07, /* Auto Configure bits with incremented ID */
++ HIL_CMD_POL = 0x10, /* Poll */
++ HIL_CMDCT_POL = 0x0f, /* Poll command bits with item count */
++ HIL_CMD_RPL = 0x20, /* RePoll */
++ HIL_CMDCT_RPL = 0x0f, /* RePoll command bits with item count */
++ HIL_CMD_RNM = 0x30, /* Report Name */
++ HIL_CMD_RST = 0x31, /* Report Status */
++ HIL_CMD_EXD = 0x32, /* Extended Describe */
++ HIL_CMD_RSC = 0x33, /* Report Security Code */
++
++ /* 0x34 to 0x3c reserved for future use */
++
++ HIL_CMD_DKA = 0x3d, /* Disable Keyswitch Autorepeat */
++ HIL_CMD_EK1 = 0x3e, /* Enable Keyswitch Autorepeat 1 */
++ HIL_CMD_EK2 = 0x3f, /* Enable Keyswitch Autorepeat 2 */
++ HIL_CMD_PR1 = 0x40, /* Prompt1 */
++ HIL_CMD_PR2 = 0x41, /* Prompt2 */
++ HIL_CMD_PR3 = 0x42, /* Prompt3 */
++ HIL_CMD_PR4 = 0x43, /* Prompt4 */
++ HIL_CMD_PR5 = 0x44, /* Prompt5 */
++ HIL_CMD_PR6 = 0x45, /* Prompt6 */
++ HIL_CMD_PR7 = 0x46, /* Prompt7 */
++ HIL_CMD_PRM = 0x47, /* Prompt (General Purpose) */
++ HIL_CMD_AK1 = 0x48, /* Acknowlege1 */
++ HIL_CMD_AK2 = 0x49, /* Acknowlege2 */
++ HIL_CMD_AK3 = 0x4a, /* Acknowlege3 */
++ HIL_CMD_AK4 = 0x4b, /* Acknowlege4 */
++ HIL_CMD_AK5 = 0x4c, /* Acknowlege5 */
++ HIL_CMD_AK6 = 0x4d, /* Acknowlege6 */
++ HIL_CMD_AK7 = 0x4e, /* Acknowlege7 */
++ HIL_CMD_ACK = 0x4f, /* Acknowlege (General Purpose) */
++
++ /* 0x50 to 0x78 reserved for future use */
++ /* 0x80 to 0xEF device-specific commands */
++ /* 0xf0 to 0xf9 reserved for future use */
++
++ HIL_CMD_RIO = 0xfa, /* Register I/O Error */
++ HIL_CMD_SHR = 0xfb, /* System Hard Reset */
++ HIL_CMD_TER = 0xfc, /* Transmission Error */
++ HIL_CMD_CAE = 0xfd, /* Configuration Address Error */
++ HIL_CMD_DHR = 0xfe, /* Device Hard Reset */
++
++ /* 0xff is prohibited from use. */
++};
++
++
++/*
++ * Response "records" to HIL commands
++ */
++
++/* Device ID byte
++ */
++#define HIL_IDD_DID_TYPE_MASK 0xe0 /* Primary type bits */
++#define HIL_IDD_DID_TYPE_KB_INTEGRAL 0xa0 /* Integral keyboard */
++#define HIL_IDD_DID_TYPE_KB_ITF 0xc0 /* ITD keyboard */
++#define HIL_IDD_DID_TYPE_KB_RSVD 0xe0 /* Reserved keyboard type */
++#define HIL_IDD_DID_TYPE_KB_LANG_MASK 0x1f /* Keyboard locale bits */
++#define HIL_IDD_DID_KBLANG_USE_ESD 0x00 /* Use ESD Locale instead */
++#define HIL_IDD_DID_TYPE_ABS 0x80 /* Absolute Positioners */
++#define HIL_IDD_DID_ABS_RSVD1_MASK 0xf8 /* Reserved */
++#define HIL_IDD_DID_ABS_RSVD1 0x98
++#define HIL_IDD_DID_ABS_TABLET_MASK 0xf8 /* Tablets and digitizers */
++#define HIL_IDD_DID_ABS_TABLET 0x90
++#define HIL_IDD_DID_ABS_TSCREEN_MASK 0xfc /* Touch screens */
++#define HIL_IDD_DID_ABS_TSCREEN 0x8c
++#define HIL_IDD_DID_ABS_RSVD2_MASK 0xfc /* Reserved */
++#define HIL_IDD_DID_ABS_RSVD2 0x88
++#define HIL_IDD_DID_ABS_RSVD3_MASK 0xfc /* Reserved */
++#define HIL_IDD_DID_ABS_RSVD3 0x80
++#define HIL_IDD_DID_TYPE_REL 0x60 /* Relative Positioners */
++#define HIL_IDD_DID_REL_RSVD1_MASK 0xf0 /* Reserved */
++#define HIL_IDD_DID_REL_RSVD1 0x70
++#define HIL_IDD_DID_REL_RSVD2_MASK 0xfc /* Reserved */
++#define HIL_IDD_DID_REL_RSVD2 0x6c
++#define HIL_IDD_DID_REL_MOUSE_MASK 0xfc /* Mouse */
++#define HIL_IDD_DID_REL_MOUSE 0x68
++#define HIL_IDD_DID_REL_QUAD_MASK 0xf8 /* Other Quadrature Devices */
++#define HIL_IDD_DID_REL_QUAD 0x60
++#define HIL_IDD_DID_TYPE_CHAR 0x40 /* Character Entry */
++#define HIL_IDD_DID_CHAR_BARCODE_MASK 0xfc /* Barcode Reader */
++#define HIL_IDD_DID_CHAR_BARCODE 0x5c
++#define HIL_IDD_DID_CHAR_RSVD1_MASK 0xfc /* Reserved */
++#define HIL_IDD_DID_CHAR_RSVD1 0x58
++#define HIL_IDD_DID_CHAR_RSVD2_MASK 0xf8 /* Reserved */
++#define HIL_IDD_DID_CHAR_RSVD2 0x50
++#define HIL_IDD_DID_CHAR_RSVD3_MASK 0xf0 /* Reserved */
++#define HIL_IDD_DID_CHAR_RSVD3 0x40
++#define HIL_IDD_DID_TYPE_OTHER 0x20 /* Miscellaneous */
++#define HIL_IDD_DID_OTHER_RSVD1_MASK 0xf0 /* Reserved */
++#define HIL_IDD_DID_OTHER_RSVD1 0x30
++#define HIL_IDD_DID_OTHER_BARCODE_MASK 0xfc /* Tone Generator */
++#define HIL_IDD_DID_OTHER_BARCODE 0x2c
++#define HIL_IDD_DID_OTHER_RSVD2_MASK 0xfc /* Reserved */
++#define HIL_IDD_DID_OTHER_RSVD2 0x28
++#define HIL_IDD_DID_OTHER_RSVD3_MASK 0xf8 /* Reserved */
++#define HIL_IDD_DID_OTHER_RSVD3 0x20
++#define HIL_IDD_DID_TYPE_KEYPAD 0x00 /* Vectra Keyboard */
++
++/* IDD record header
++ */
++#define HIL_IDD_HEADER_AXSET_MASK 0x03 /* Number of axis in a set */
++#define HIL_IDD_HEADER_RSC 0x04 /* Supports RSC command */
++#define HIL_IDD_HEADER_EXD 0x08 /* Supports EXD command */
++#define HIL_IDD_HEADER_IOD 0x10 /* IOD byte to follow */
++#define HIL_IDD_HEADER_16BIT 0x20 /* 16 (vs. 8) bit resolution */
++#define HIL_IDD_HEADER_ABS 0x40 /* Reports Absolute Position */
++#define HIL_IDD_HEADER_2X_AXIS 0x80 /* Two sets of 1-3 axis */
++
++/* I/O Descriptor
++ */
++#define HIL_IDD_IOD_NBUTTON_MASK 0x07 /* Number of buttons */
++#define HIL_IDD_IOD_PROXIMITY 0x08 /* Proximity in/out events */
++#define HIL_IDD_IOD_PROMPT_MASK 0x70 /* Number of prompts/acks */
++#define HIL_IDD_IOD_PROMPT_SHIFT 4
++#define HIL_IDD_IOD_PROMPT 0x80 /* Generic prompt/ack */
++
++#define HIL_IDD_NUM_AXES_PER_SET(header_packet) \
++((header_packet) & HIL_IDD_HEADER_AXSET_MASK)
++
++#define HIL_IDD_NUM_AXSETS(header_packet) \
++(2 - !((header_packet) & HIL_IDD_HEADER_2X_AXIS))
++
++#define HIL_IDD_LEN(header_packet) \
++((4 - !(header_packet & HIL_IDD_HEADER_IOD) - \
++ 2 * !(HIL_IDD_NUM_AXES_PER_SET(header_packet))) + \
++ 2 * HIL_IDD_NUM_AXES_PER_SET(header_packet) * \
++ !!((header_packet) & HIL_IDD_HEADER_ABS))
++
++/* The following HIL_IDD_* macros assume you have an array of
++ * packets and/or unpacked 8-bit data in the order that they
++ * were received.
++ */
++
++#define HIL_IDD_AXIS_COUNTS_PER_M(header_ptr) \
++(!(HIL_IDD_NUM_AXSETS(*(header_ptr))) ? -1 : \
++(((*(header_ptr + 1) & HIL_PKT_DATA_MASK) + \
++ ((*(header_ptr + 2) & HIL_PKT_DATA_MASK)) << 8) \
++* ((*(header_ptr) & HIL_IDD_HEADER_16BIT) ? 100 : 1)))
++
++#define HIL_IDD_AXIS_MAX(header_ptr, __axnum) \
++((!(*(header_ptr) & HIL_IDD_HEADER_ABS) || \
++ (HIL_IDD_NUM_AXES_PER_SET(*(header_ptr)) <= __axnum)) ? 0 : \
++ ((HIL_PKT_DATA_MASK & *((header_ptr) + 3 + 2 * __axnum)) + \
++ ((HIL_PKT_DATA_MASK & *((header_ptr) + 4 + 2 * __axnum)) << 8)))
++
++#define HIL_IDD_IOD(header_ptr) \
++(*(header_ptr + HIL_IDD_LEN((*header_ptr)) - 1))
++
++#define HIL_IDD_HAS_GEN_PROMPT(header_ptr) \
++((*header_ptr & HIL_IDD_HEADER_IOD) && \
++ (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_PROMPT))
++
++#define HIL_IDD_HAS_GEN_PROXIMITY(header_ptr) \
++((*header_ptr & HIL_IDD_HEADER_IOD) && \
++ (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_PROXIMITY))
++
++#define HIL_IDD_NUM_BUTTONS(header_ptr) \
++((*header_ptr & HIL_IDD_HEADER_IOD) ? \
++ (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_NBUTTON_MASK) : 0)
++
++#define HIL_IDD_NUM_PROMPTS(header_ptr) \
++((*header_ptr & HIL_IDD_HEADER_IOD) ? \
++ ((HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_NPROMPT_MASK) \
++ >> HIL_IDD_IOD_PROMPT_SHIFT) : 0)
++
++/* The response to HIL EXD commands -- the "extended describe record" */
++#define HIL_EXD_HEADER_WRG 0x03 /* Supports type2 WRG */
++#define HIL_EXD_HEADER_WRG_TYPE1 0x01 /* Supports type1 WRG */
++#define HIL_EXD_HEADER_WRG_TYPE2 0x02 /* Supports type2 WRG */
++#define HIL_EXD_HEADER_RRG 0x04 /* Supports RRG command */
++#define HIL_EXD_HEADER_RNM 0x10 /* Supports RNM command */
++#define HIL_EXD_HEADER_RST 0x20 /* Supports RST command */
++#define HIL_EXD_HEADER_LOCALE 0x40 /* Contains locale code */
++
++#define HIL_EXD_NUM_RRG(header_ptr) \
++((*header_ptr & HIL_EXD_HEADER_RRG) ? \
++ (*(header_ptr + 1) & HIL_PKT_DATA_MASK) : 0)
++
++#define HIL_EXD_NUM_WWG(header_ptr) \
++((*header_ptr & HIL_EXD_HEADER_WRG) ? \
++ (*(header_ptr + 2 - !(*header_ptr & HIL_EXD_HEADER_RRG)) & \
++ HIL_PKT_DATA_MASK) : 0)
++
++#define HIL_EXD_LEN(header_ptr) \
++(!!(*header_ptr & HIL_EXD_HEADER_RRG) + \
++ !!(*header_ptr & HIL_EXD_HEADER_WRG) + \
++ !!(*header_ptr & HIL_EXD_HEADER_LOCALE) + \
++ 2 * !!(*header_ptr & HIL_EXD_HEADER_WRG_TYPE2) + 1)
++
++#define HIL_EXD_LOCALE(header_ptr) \
++(!(*header_ptr & HIL_EXD_HEADER_LOCALE) ? -1 : \
++ (*(header_ptr + HIL_EXD_LEN(header_ptr) - 1) & HIL_PKT_DATA_MASK))
++
++#define HIL_EXD_WRG_TYPE2_LEN(header_ptr) \
++(!(*header_ptr & HIL_EXD_HEADER_WRG_TYPE2) ? -1 : \
++ (*(header_ptr + HIL_EXD_LEN(header_ptr) - 2 - \
++ !!(*header_ptr & HIL_EXD_HEADER_LOCALE)) & HIL_PKT_DATA_MASK) + \
++ ((*(header_ptr + HIL_EXD_LEN(header_ptr) - 1 - \
++ !!(*header_ptr & HIL_EXD_HEADER_LOCALE)) & HIL_PKT_DATA_MASK) << 8))
++
++/* Device locale codes. */
++
++/* Last defined locale code. Everything above this is "Reserved",
++ and note that this same table applies to the Device ID Byte where
++ keyboards may have a nationality code which is only 5 bits. */
++#define HIL_LOCALE_MAX 0x1f
++
++/* Map to hopefully useful strings. I was trying to make these look
++ like locale.aliases strings do; maybe that isn't the right table to
++ emulate. In either case, I didn't have much to work on. */
++#define HIL_LOCALE_MAP \
++"", /* 0x00 Reserved */ \
++"", /* 0x01 Reserved */ \
++"", /* 0x02 Reserved */ \
++"swiss.french", /* 0x03 Swiss/French */ \
++"portuguese", /* 0x04 Portuguese */ \
++"arabic", /* 0x05 Arabic */ \
++"hebrew", /* 0x06 Hebrew */ \
++"english.canadian", /* 0x07 Canadian English */ \
++"turkish", /* 0x08 Turkish */ \
++"greek", /* 0x09 Greek */ \
++"thai", /* 0x0a Thai (Thailand) */ \
++"italian", /* 0x0b Italian */ \
++"korean", /* 0x0c Hangul (Korea) */ \
++"dutch", /* 0x0d Dutch */ \
++"swedish", /* 0x0e Swedish */ \
++"german", /* 0x0f German */ \
++"chinese", /* 0x10 Chinese-PRC */ \
++"chinese", /* 0x11 Chinese-ROC */ \
++"swiss.french", /* 0x12 Swiss/French II */ \
++"spanish", /* 0x13 Spanish */ \
++"swiss.german", /* 0x14 Swiss/German II */ \
++"flemish", /* 0x15 Belgian (Flemish) */ \
++"finnish", /* 0x16 Finnish */ \
++"english.uk", /* 0x17 United Kingdom */ \
++"french.canadian", /* 0x18 French/Canadian */ \
++"swiss.german", /* 0x19 Swiss/German */ \
++"norwegian", /* 0x1a Norwegian */ \
++"french", /* 0x1b French */ \
++"danish", /* 0x1c Danish */ \
++"japanese", /* 0x1d Katakana */ \
++"spanish", /* 0x1e Latin American/Spanish*/\
++"english.us" /* 0x1f United States */ \
++
++
++/* HIL keycodes */
++#define HIL_KEYCODES_SET1_TBLSIZE 128
++#define HIL_KEYCODES_SET1 \
++ KEY_5, KEY_RESERVED, KEY_RIGHTALT, KEY_LEFTALT, \
++ KEY_RIGHTSHIFT, KEY_LEFTSHIFT, KEY_LEFTCTRL, KEY_SYSRQ, \
++ KEY_KP4, KEY_KP8, KEY_KP5, KEY_KP9, \
++ KEY_KP6, KEY_KP7, KEY_KPCOMMA, KEY_KPENTER, \
++ KEY_KP1, KEY_KPSLASH, KEY_KP2, KEY_KPPLUS, \
++ KEY_KP3, KEY_KPASTERISK, KEY_KP0, KEY_KPMINUS, \
++ KEY_B, KEY_V, KEY_C, KEY_X, \
++ KEY_Z, KEY_RESERVED, KEY_RESERVED, KEY_ESC, \
++ KEY_6, KEY_F10, KEY_3, KEY_F11, \
++ KEY_KPDOT, KEY_F9, KEY_TAB /*KP*/, KEY_F12, \
++ KEY_H, KEY_G, KEY_F, KEY_D, \
++ KEY_S, KEY_A, KEY_RESERVED, KEY_CAPSLOCK, \
++ KEY_U, KEY_Y, KEY_T, KEY_R, \
++ KEY_E, KEY_W, KEY_Q, KEY_TAB, \
++ KEY_7, KEY_6, KEY_5, KEY_4, \
++ KEY_3, KEY_2, KEY_1, KEY_GRAVE, \
++ KEY_F13, KEY_F14, KEY_F15, KEY_F16, \
++ KEY_F17, KEY_F18, KEY_F19, KEY_F20, \
++ KEY_MENU, KEY_F4, KEY_F3, KEY_F2, \
++ KEY_F1, KEY_VOLUMEUP, KEY_STOP, KEY_SENDFILE, \
++ KEY_SYSRQ, KEY_F5, KEY_F6, KEY_F7, \
++ KEY_F8, KEY_VOLUMEDOWN, KEY_DEL_EOL, KEY_DEL_EOS, \
++ KEY_8, KEY_9, KEY_0, KEY_MINUS, \
++ KEY_EQUAL, KEY_BACKSPACE, KEY_INS_LINE, KEY_DEL_LINE, \
++ KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE, \
++ KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_INSERT, KEY_DELETE, \
++ KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, \
++ KEY_APOSTROPHE, KEY_ENTER, KEY_HOME, KEY_PAGEUP, \
++ KEY_M, KEY_COMMA, KEY_DOT, KEY_SLASH, \
++ KEY_BACKSLASH, KEY_SELECT, KEY_102ND, KEY_PAGEDOWN, \
++ KEY_N, KEY_SPACE, KEY_NEXT, KEY_RESERVED, \
++ KEY_LEFT, KEY_DOWN, KEY_UP, KEY_RIGHT
++
++
++#define HIL_KEYCODES_SET3_TBLSIZE 128
++#define HIL_KEYCODES_SET3 \
++ KEY_RESERVED, KEY_ESC, KEY_1, KEY_2, \
++ KEY_3, KEY_4, KEY_5, KEY_6, \
++ KEY_7, KEY_8, KEY_9, KEY_0, \
++ KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_TAB, \
++ KEY_Q, KEY_W, KEY_E, KEY_R, \
++ KEY_T, KEY_Y, KEY_U, KEY_I, \
++ KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, \
++ KEY_ENTER, KEY_LEFTCTRL, KEY_A, KEY_S, \
++ KEY_D, KEY_F, KEY_G, KEY_H, \
++ KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, \
++ KEY_APOSTROPHE,KEY_GRAVE, KEY_LEFTSHIFT, KEY_BACKSLASH, \
++ KEY_Z, KEY_X, KEY_C, KEY_V, \
++ KEY_B, KEY_N, KEY_M, KEY_COMMA, \
++ KEY_DOT, KEY_SLASH, KEY_RIGHTSHIFT, KEY_KPASTERISK, \
++ KEY_LEFTALT, KEY_SPACE, KEY_CAPSLOCK, KEY_F1, \
++ KEY_F2, KEY_F3, KEY_F4, KEY_F5, \
++ KEY_F6, KEY_F7, KEY_F8, KEY_F9, \
++ KEY_F10, KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_KP7, \
++ KEY_KP8, KEY_KP9, KEY_KPMINUS, KEY_KP4, \
++ KEY_KP5, KEY_KP6, KEY_KPPLUS, KEY_KP1, \
++ KEY_KP2, KEY_KP3, KEY_KP0, KEY_KPDOT, \
++ KEY_SYSRQ, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
++ KEY_UP, KEY_LEFT, KEY_DOWN, KEY_RIGHT, \
++ KEY_HOME, KEY_PAGEUP, KEY_END, KEY_PAGEDOWN, \
++ KEY_INSERT, KEY_DELETE, KEY_102ND, KEY_RESERVED, \
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
++ KEY_F1, KEY_F2, KEY_F3, KEY_F4, \
++ KEY_F5, KEY_F6, KEY_F7, KEY_F8, \
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, \
++ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED
++
++
++/* Response to POL command, the "poll record header" */
++
++#define HIL_POL_NUM_AXES_MASK 0x03 /* Number of axis reported */
++#define HIL_POL_CTS 0x04 /* Device ready to receive data */
++#define HIL_POL_STATUS_PENDING 0x08 /* Device has status to report */
++#define HIL_POL_CHARTYPE_MASK 0x70 /* Type of character data to follow */
++#define HIL_POL_CHARTYPE_NONE 0x00 /* No character data to follow */
++#define HIL_POL_CHARTYPE_RSVD1 0x10 /* Reserved Set 1 */
++#define HIL_POL_CHARTYPE_ASCII 0x20 /* U.S. ASCII */
++#define HIL_POL_CHARTYPE_BINARY 0x30 /* Binary data */
++#define HIL_POL_CHARTYPE_SET1 0x40 /* Keycode Set 1 */
++#define HIL_POL_CHARTYPE_RSVD2 0x50 /* Reserved Set 2 */
++#define HIL_POL_CHARTYPE_SET2 0x60 /* Keycode Set 2 */
++#define HIL_POL_CHARTYPE_SET3 0x70 /* Keycode Set 3 */
++#define HIL_POL_AXIS_ALT 0x80 /* Data is from axis set 2 */
++
++
++#endif /* _HIL_H_ */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/linux/hil_mlc.h CVS2_6_11_PA2/include/linux/hil_mlc.h
+--- LINUS_2_6_11/include/linux/hil_mlc.h 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/include/linux/hil_mlc.h 2004-10-30 13:51:51.000000000 -0600
+@@ -0,0 +1,168 @@
++/*
++ * HP Human Interface Loop Master Link Controller driver.
++ *
++ * Copyright (c) 2001 Brian S. Julin
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL").
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
++ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ *
++ * References:
++ * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
++ *
++ */
++
++#include <linux/hil.h>
++#include <linux/time.h>
++#include <linux/interrupt.h>
++#include <asm/semaphore.h>
++#include <linux/serio.h>
++#include <linux/list.h>
++
++typedef struct hil_mlc hil_mlc;
++
++/* The HIL has a complicated state engine.
++ * We define the structure of nodes in the state engine here.
++ */
++enum hilse_act {
++ /* HILSE_OUT prepares to receive input if the next node
++ * is an IN or EXPECT, and then sends the given packet.
++ */
++ HILSE_OUT = 0,
++
++ /* HILSE_CTS checks if the loop is busy. */
++ HILSE_CTS,
++
++ /* HILSE_OUT_LAST sends the given command packet to
++ * the last configured/running device on the loop.
++ */
++ HILSE_OUT_LAST,
++
++ /* HILSE_OUT_DISC sends the given command packet to
++ * the next device past the last configured/running one.
++ */
++ HILSE_OUT_DISC,
++
++ /* HILSE_FUNC runs a callback function with given arguments.
++ * a positive return value causes the "ugly" branch to be taken.
++ */
++ HILSE_FUNC,
++
++ /* HILSE_IN simply expects any non-errored packet to arrive
++ * within arg usecs.
++ */
++ HILSE_IN = 0x100,
++
++ /* HILSE_EXPECT expects a particular packet to arrive
++ * within arg usecs, any other packet is considered an error.
++ */
++ HILSE_EXPECT,
++
++ /* HILSE_EXPECT_LAST as above but dev field should be last
++ * discovered/operational device.
++ */
++ HILSE_EXPECT_LAST,
++
++ /* HILSE_EXPECT_LAST as above but dev field should be first
++ * undiscovered/inoperational device.
++ */
++ HILSE_EXPECT_DISC
++};
++
++typedef int (hilse_func) (hil_mlc *mlc, int arg);
++struct hilse_node {
++ enum hilse_act act; /* How to process this node */
++ union {
++ hilse_func *func; /* Function to call if HILSE_FUNC */
++ hil_packet packet; /* Packet to send or to compare */
++ } object;
++ int arg; /* Timeout in usec or parm for func */
++ int good; /* Node to jump to on success */
++ int bad; /* Node to jump to on error */
++ int ugly; /* Node to jump to on timeout */
++};
++
++/* Methods for back-end drivers, e.g. hp_sdc_mlc */
++typedef int (hil_mlc_cts) (hil_mlc *mlc);
++typedef void (hil_mlc_out) (hil_mlc *mlc);
++typedef int (hil_mlc_in) (hil_mlc *mlc, suseconds_t timeout);
++
++struct hil_mlc_devinfo {
++ uint8_t idd[16]; /* Device ID Byte and Describe Record */
++ uint8_t rsc[16]; /* Security Code Header and Record */
++ uint8_t exd[16]; /* Extended Describe Record */
++ uint8_t rnm[16]; /* Device name as returned by RNM command */
++};
++
++struct hil_mlc_serio_map {
++ hil_mlc *mlc;
++ int di_revmap;
++ int didx;
++};
++
++/* How many (possibly old/detached) devices the we try to keep track of */
++#define HIL_MLC_DEVMEM 16
++
++struct hil_mlc {
++ struct list_head list; /* hil_mlc is organized as linked list */
++
++ rwlock_t lock;
++
++ void *priv; /* Data specific to a particular type of MLC */
++
++ int seidx; /* Current node in state engine */
++ int istarted, ostarted;
++
++ hil_mlc_cts *cts;
++ struct semaphore csem; /* Raised when loop idle */
++
++ hil_mlc_out *out;
++ struct semaphore osem; /* Raised when outpacket dispatched */
++ hil_packet opacket;
++
++ hil_mlc_in *in;
++ struct semaphore isem; /* Raised when a packet arrives */
++ hil_packet ipacket[16];
++ hil_packet imatch;
++ int icount;
++ struct timeval instart;
++ suseconds_t intimeout;
++
++ int ddi; /* Last operational device id */
++ int lcv; /* LCV to throttle loops */
++ struct timeval lcv_tv; /* Time loop was started */
++
++ int di_map[7]; /* Maps below items to live devs */
++ struct hil_mlc_devinfo di[HIL_MLC_DEVMEM];
++ struct serio *serio[HIL_MLC_DEVMEM];
++ struct hil_mlc_serio_map serio_map[HIL_MLC_DEVMEM];
++ hil_packet serio_opacket[HIL_MLC_DEVMEM];
++ int serio_oidx[HIL_MLC_DEVMEM];
++ struct hil_mlc_devinfo di_scratch; /* Temporary area */
++
++ int opercnt;
++
++ struct tasklet_struct *tasklet;
++};
++
++int hil_mlc_register(hil_mlc *mlc);
++int hil_mlc_unregister(hil_mlc *mlc);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/linux/hp_sdc.h CVS2_6_11_PA2/include/linux/hp_sdc.h
+--- LINUS_2_6_11/include/linux/hp_sdc.h 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/include/linux/hp_sdc.h 2004-07-11 16:03:48.000000000 -0600
+@@ -0,0 +1,300 @@
++/*
++ * HP i8042 System Device Controller -- header
++ *
++ * Copyright (c) 2001 Brian S. Julin
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions, and the following disclaimer,
++ * without modification.
++ * 2. The name of the author may not be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * Alternatively, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL").
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
++ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ *
++ * References:
++ *
++ * HP-HIL Technical Reference Manual. Hewlett Packard Product No. 45918A
++ *
++ * System Device Controller Microprocessor Firmware Theory of Operation
++ * for Part Number 1820-4784 Revision B. Dwg No. A-1820-4784-2
++ *
++ */
++
++#ifndef _LINUX_HP_SDC_H
++#define _LINUX_HP_SDC_H
++
++#include <linux/interrupt.h>
++#include <linux/types.h>
++#include <linux/time.h>
++#include <linux/timer.h>
++#if defined(__hppa__)
++#include <asm/hardware.h>
++#endif
++
++
++/* No 4X status reads take longer than this (in usec).
++ */
++#define HP_SDC_MAX_REG_DELAY 20000
++
++typedef void (hp_sdc_irqhook) (int irq, void *dev_id,
++ uint8_t status, uint8_t data);
++
++int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback);
++int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback);
++int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback);
++int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback);
++int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback);
++int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback);
++
++typedef struct {
++ int actidx; /* Start of act. Acts are atomic WRT I/O to SDC */
++ int idx; /* Index within the act */
++ int endidx; /* transaction is over and done if idx == endidx */
++ uint8_t *seq; /* commands/data for the transaction */
++ union {
++ hp_sdc_irqhook *irqhook; /* Callback, isr or tasklet context */
++ struct semaphore *semaphore; /* Semaphore to sleep on. */
++ } act;
++} hp_sdc_transaction;
++int hp_sdc_enqueue_transaction(hp_sdc_transaction *this);
++int hp_sdc_dequeue_transaction(hp_sdc_transaction *this);
++
++/* The HP_SDC_ACT* values are peculiar to this driver.
++ * Nuance: never HP_SDC_ACT_DATAIN | HP_SDC_ACT_DEALLOC, use another
++ * act to perform the dealloc.
++ */
++#define HP_SDC_ACT_PRECMD 0x01 /* Send a command first */
++#define HP_SDC_ACT_DATAREG 0x02 /* Set data registers */
++#define HP_SDC_ACT_DATAOUT 0x04 /* Send data bytes */
++#define HP_SDC_ACT_POSTCMD 0x08 /* Send command after */
++#define HP_SDC_ACT_DATAIN 0x10 /* Collect data after */
++#define HP_SDC_ACT_DURING 0x1f
++#define HP_SDC_ACT_SEMAPHORE 0x20 /* Raise semaphore after */
++#define HP_SDC_ACT_CALLBACK 0x40 /* Pass data to IRQ handler */
++#define HP_SDC_ACT_DEALLOC 0x80 /* Destroy transaction after */
++#define HP_SDC_ACT_AFTER 0xe0
++#define HP_SDC_ACT_DEAD 0x60 /* Act timed out. */
++
++/* Rest of the flags are straightforward representation of the SDC interface */
++#define HP_SDC_STATUS_IBF 0x02 /* Input buffer full */
++
++#define HP_SDC_STATUS_IRQMASK 0xf0 /* Bits containing "level 1" irq */
++#define HP_SDC_STATUS_PERIODIC 0x10 /* Periodic 10ms timer */
++#define HP_SDC_STATUS_USERTIMER 0x20 /* "Special purpose" timer */
++#define HP_SDC_STATUS_TIMER 0x30 /* Both PERIODIC and USERTIMER */
++#define HP_SDC_STATUS_REG 0x40 /* Data from an i8042 register */
++#define HP_SDC_STATUS_HILCMD 0x50 /* Command from HIL MLC */
++#define HP_SDC_STATUS_HILDATA 0x60 /* Data from HIL MLC */
++#define HP_SDC_STATUS_PUP 0x70 /* Sucessful power-up self test */
++#define HP_SDC_STATUS_KCOOKED 0x80 /* Key from cooked kbd */
++#define HP_SDC_STATUS_KRPG 0xc0 /* Key from Repeat Gen */
++#define HP_SDC_STATUS_KMOD_SUP 0x10 /* Shift key is up */
++#define HP_SDC_STATUS_KMOD_CUP 0x20 /* Control key is up */
++
++#define HP_SDC_NMISTATUS_FHS 0x40 /* NMI is a fast handshake irq */
++
++/* Internal i8042 registers (there are more, but they are not too useful). */
++
++#define HP_SDC_USE 0x02 /* Resource usage (including OB bit) */
++#define HP_SDC_IM 0x04 /* Interrupt mask */
++#define HP_SDC_CFG 0x11 /* Configuration register */
++#define HP_SDC_KBLANGUAGE 0x12 /* Keyboard language */
++
++#define HP_SDC_D0 0x70 /* General purpose data buffer 0 */
++#define HP_SDC_D1 0x71 /* General purpose data buffer 1 */
++#define HP_SDC_D2 0x72 /* General purpose data buffer 2 */
++#define HP_SDC_D3 0x73 /* General purpose data buffer 3 */
++#define HP_SDC_VT1 0x74 /* Timer for voice 1 */
++#define HP_SDC_VT2 0x75 /* Timer for voice 2 */
++#define HP_SDC_VT3 0x76 /* Timer for voice 3 */
++#define HP_SDC_VT4 0x77 /* Timer for voice 4 */
++#define HP_SDC_KBN 0x78 /* Which HIL devs are Nimitz */
++#define HP_SDC_KBC 0x79 /* Which HIL devs are cooked kbds */
++#define HP_SDC_LPS 0x7a /* i8042's view of HIL status */
++#define HP_SDC_LPC 0x7b /* i8042's view of HIL "control" */
++#define HP_SDC_RSV 0x7c /* Reserved "for testing" */
++#define HP_SDC_LPR 0x7d /* i8042 count of HIL reconfigs */
++#define HP_SDC_XTD 0x7e /* "Extended Configuration" register */
++#define HP_SDC_STR 0x7f /* i8042 self-test result */
++
++/* Bitfields for above registers */
++#define HP_SDC_USE_LOOP 0x04 /* Command is currently on the loop. */
++
++#define HP_SDC_IM_MASK 0x1f /* these bits not part of cmd/status */
++#define HP_SDC_IM_FH 0x10 /* Mask the fast handshake irq */
++#define HP_SDC_IM_PT 0x08 /* Mask the periodic timer irq */
++#define HP_SDC_IM_TIMERS 0x04 /* Mask the MT/DT/CT irq */
++#define HP_SDC_IM_RESET 0x02 /* Mask the reset key irq */
++#define HP_SDC_IM_HIL 0x01 /* Mask the HIL MLC irq */
++
++#define HP_SDC_CFG_ROLLOVER 0x08 /* WTF is "N-key rollover"? */
++#define HP_SDC_CFG_KBD 0x10 /* There is a keyboard */
++#define HP_SDC_CFG_NEW 0x20 /* Supports/uses HIL MLC */
++#define HP_SDC_CFG_KBD_OLD 0x03 /* keyboard code for non-HIL */
++#define HP_SDC_CFG_KBD_NEW 0x07 /* keyboard code from HIL autoconfig */
++#define HP_SDC_CFG_REV 0x40 /* Code revision bit */
++#define HP_SDC_CFG_IDPROM 0x80 /* IDPROM present in kbd (not HIL) */
++
++#define HP_SDC_LPS_NDEV 0x07 /* # devices autoconfigured on HIL */
++#define HP_SDC_LPS_ACSUCC 0x08 /* loop autoconfigured successfully */
++#define HP_SDC_LPS_ACFAIL 0x80 /* last loop autoconfigure failed */
++
++#define HP_SDC_LPC_APE_IPF 0x01 /* HIL MLC APE/IPF (autopoll) set */
++#define HP_SDC_LPC_ARCONERR 0x02 /* i8042 autoreconfigs loop on err */
++#define HP_SDC_LPC_ARCQUIET 0x03 /* i8042 doesn't report autoreconfigs*/
++#define HP_SDC_LPC_COOK 0x10 /* i8042 cooks devices in _KBN */
++#define HP_SDC_LPC_RC 0x80 /* causes autoreconfig */
++
++#define HP_SDC_XTD_REV 0x07 /* contains revision code */
++#define HP_SDC_XTD_REV_STRINGS(val, str) \
++switch (val) { \
++ case 0x1: str = "1820-3712"; break; \
++ case 0x2: str = "1820-4379"; break; \
++ case 0x3: str = "1820-4784"; break; \
++ default: str = "unknown"; \
++};
++#define HP_SDC_XTD_BEEPER 0x08 /* TI SN76494 beeper available */
++#define HP_SDC_XTD_BBRTC 0x20 /* OKI MSM-58321 BBRTC present */
++
++#define HP_SDC_CMD_LOAD_RT 0x31 /* Load real time (from 8042) */
++#define HP_SDC_CMD_LOAD_FHS 0x36 /* Load the fast handshake timer */
++#define HP_SDC_CMD_LOAD_MT 0x38 /* Load the match timer */
++#define HP_SDC_CMD_LOAD_DT 0x3B /* Load the delay timer */
++#define HP_SDC_CMD_LOAD_CT 0x3E /* Load the cycle timer */
++
++#define HP_SDC_CMD_SET_IM 0x40 /* 010xxxxx == set irq mask */
++
++/* The documents provided do not explicitly state that all registers betweem
++ * 0x01 and 0x1f inclusive can be read by sending their register index as a
++ * command, but this is implied and appears to be the case.
++ */
++#define HP_SDC_CMD_READ_RAM 0x00 /* Load from i8042 RAM (autoinc) */
++#define HP_SDC_CMD_READ_USE 0x02 /* Undocumented! Load from usage reg */
++#define HP_SDC_CMD_READ_IM 0x04 /* Load current interrupt mask */
++#define HP_SDC_CMD_READ_KCC 0x11 /* Load primary kbd config code */
++#define HP_SDC_CMD_READ_KLC 0x12 /* Load primary kbd language code */
++#define HP_SDC_CMD_READ_T1 0x13 /* Load timer output buffer byte 1 */
++#define HP_SDC_CMD_READ_T2 0x14 /* Load timer output buffer byte 1 */
++#define HP_SDC_CMD_READ_T3 0x15 /* Load timer output buffer byte 1 */
++#define HP_SDC_CMD_READ_T4 0x16 /* Load timer output buffer byte 1 */
++#define HP_SDC_CMD_READ_T5 0x17 /* Load timer output buffer byte 1 */
++#define HP_SDC_CMD_READ_D0 0xf0 /* Load from i8042 RAM location 0x70 */
++#define HP_SDC_CMD_READ_D1 0xf1 /* Load from i8042 RAM location 0x71 */
++#define HP_SDC_CMD_READ_D2 0xf2 /* Load from i8042 RAM location 0x72 */
++#define HP_SDC_CMD_READ_D3 0xf3 /* Load from i8042 RAM location 0x73 */
++#define HP_SDC_CMD_READ_VT1 0xf4 /* Load from i8042 RAM location 0x74 */
++#define HP_SDC_CMD_READ_VT2 0xf5 /* Load from i8042 RAM location 0x75 */
++#define HP_SDC_CMD_READ_VT3 0xf6 /* Load from i8042 RAM location 0x76 */
++#define HP_SDC_CMD_READ_VT4 0xf7 /* Load from i8042 RAM location 0x77 */
++#define HP_SDC_CMD_READ_KBN 0xf8 /* Load from i8042 RAM location 0x78 */
++#define HP_SDC_CMD_READ_KBC 0xf9 /* Load from i8042 RAM location 0x79 */
++#define HP_SDC_CMD_READ_LPS 0xfa /* Load from i8042 RAM location 0x7a */
++#define HP_SDC_CMD_READ_LPC 0xfb /* Load from i8042 RAM location 0x7b */
++#define HP_SDC_CMD_READ_RSV 0xfc /* Load from i8042 RAM location 0x7c */
++#define HP_SDC_CMD_READ_LPR 0xfd /* Load from i8042 RAM location 0x7d */
++#define HP_SDC_CMD_READ_XTD 0xfe /* Load from i8042 RAM location 0x7e */
++#define HP_SDC_CMD_READ_STR 0xff /* Load from i8042 RAM location 0x7f */
++
++#define HP_SDC_CMD_SET_ARD 0xA0 /* Set emulated autorepeat delay */
++#define HP_SDC_CMD_SET_ARR 0xA2 /* Set emulated autorepeat rate */
++#define HP_SDC_CMD_SET_BELL 0xA3 /* Set voice 3 params for "beep" cmd */
++#define HP_SDC_CMD_SET_RPGR 0xA6 /* Set "RPG" irq rate (doesn't work) */
++#define HP_SDC_CMD_SET_RTMS 0xAD /* Set the RTC time (milliseconds) */
++#define HP_SDC_CMD_SET_RTD 0xAF /* Set the RTC time (days) */
++#define HP_SDC_CMD_SET_FHS 0xB2 /* Set fast handshake timer */
++#define HP_SDC_CMD_SET_MT 0xB4 /* Set match timer */
++#define HP_SDC_CMD_SET_DT 0xB7 /* Set delay timer */
++#define HP_SDC_CMD_SET_CT 0xBA /* Set cycle timer */
++#define HP_SDC_CMD_SET_RAMP 0xC1 /* Reset READ_RAM autoinc counter */
++#define HP_SDC_CMD_SET_D0 0xe0 /* Load to i8042 RAM location 0x70 */
++#define HP_SDC_CMD_SET_D1 0xe1 /* Load to i8042 RAM location 0x71 */
++#define HP_SDC_CMD_SET_D2 0xe2 /* Load to i8042 RAM location 0x72 */
++#define HP_SDC_CMD_SET_D3 0xe3 /* Load to i8042 RAM location 0x73 */
++#define HP_SDC_CMD_SET_VT1 0xe4 /* Load to i8042 RAM location 0x74 */
++#define HP_SDC_CMD_SET_VT2 0xe5 /* Load to i8042 RAM location 0x75 */
++#define HP_SDC_CMD_SET_VT3 0xe6 /* Load to i8042 RAM location 0x76 */
++#define HP_SDC_CMD_SET_VT4 0xe7 /* Load to i8042 RAM location 0x77 */
++#define HP_SDC_CMD_SET_KBN 0xe8 /* Load to i8042 RAM location 0x78 */
++#define HP_SDC_CMD_SET_KBC 0xe9 /* Load to i8042 RAM location 0x79 */
++#define HP_SDC_CMD_SET_LPS 0xea /* Load to i8042 RAM location 0x7a */
++#define HP_SDC_CMD_SET_LPC 0xeb /* Load to i8042 RAM location 0x7b */
++#define HP_SDC_CMD_SET_RSV 0xec /* Load to i8042 RAM location 0x7c */
++#define HP_SDC_CMD_SET_LPR 0xed /* Load to i8042 RAM location 0x7d */
++#define HP_SDC_CMD_SET_XTD 0xee /* Load to i8042 RAM location 0x7e */
++#define HP_SDC_CMD_SET_STR 0xef /* Load to i8042 RAM location 0x7f */
++
++#define HP_SDC_CMD_DO_RTCW 0xc2 /* i8042 RAM 0x70 --> RTC */
++#define HP_SDC_CMD_DO_RTCR 0xc3 /* RTC[0x70 0:3] --> irq/status/data */
++#define HP_SDC_CMD_DO_BEEP 0xc4 /* i8042 RAM 0x70-74 --> beeper,VT3 */
++#define HP_SDC_CMD_DO_HIL 0xc5 /* i8042 RAM 0x70-73 -->
++ HIL MLC R0,R1 i8042 HIL watchdog */
++
++/* Values used to (de)mangle input/output to/from the HIL MLC */
++#define HP_SDC_DATA 0x40 /* Data from an 8042 register */
++#define HP_SDC_HIL_CMD 0x50 /* Data from HIL MLC R1/8042 */
++#define HP_SDC_HIL_R1MASK 0x0f /* Contents of HIL MLC R1 0:3 */
++#define HP_SDC_HIL_AUTO 0x10 /* Set if POL results from i8042 */
++#define HP_SDC_HIL_ISERR 0x80 /* Has meaning as in next 4 values */
++#define HP_SDC_HIL_RC_DONE 0x80 /* i8042 auto-configured loop */
++#define HP_SDC_HIL_ERR 0x81 /* HIL MLC R2 had a bit set */
++#define HP_SDC_HIL_TO 0x82 /* i8042 HIL watchdog expired */
++#define HP_SDC_HIL_RC 0x84 /* i8042 is auto-configuring loop */
++#define HP_SDC_HIL_DAT 0x60 /* Data from HIL MLC R0 */
++
++
++typedef struct {
++ rwlock_t ibf_lock;
++ rwlock_t lock; /* user/tasklet lock */
++ rwlock_t rtq_lock; /* isr/tasklet lock */
++ rwlock_t hook_lock; /* isr/user lock for handler add/del */
++
++ unsigned int irq, nmi; /* Our IRQ lines */
++ unsigned long base_io, status_io, data_io; /* Our IO ports */
++
++ uint8_t im; /* Interrupt mask */
++ int set_im; /* Interrupt mask needs to be set. */
++
++ int ibf; /* Last known status of IBF flag */
++ uint8_t wi; /* current i8042 write index */
++ uint8_t r7[4]; /* current i8042[0x70 - 0x74] values */
++ uint8_t r11, r7e; /* Values from version/revision regs */
++
++ hp_sdc_irqhook *timer, *reg, *hil, *pup, *cooked;
++
++#define HP_SDC_QUEUE_LEN 16
++ hp_sdc_transaction *tq[HP_SDC_QUEUE_LEN]; /* All pending read/writes */
++
++ int rcurr, rqty; /* Current read transact in process */
++ struct timeval rtv; /* Time when current read started */
++ int wcurr; /* Current write transact in process */
++
++ int dev_err; /* carries status from registration */
++#if defined(__hppa__)
++ struct parisc_device *dev;
++#elif defined(__mc68000__)
++ void *dev;
++#else
++#error No support for device registration on this arch yet.
++#endif
++
++ struct timer_list kicker; /* Keeps below task alive */
++ struct tasklet_struct task;
++
++} hp_i8042_sdc;
++
++#endif /* _LINUX_HP_SDC_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/linux/input.h CVS2_6_11_PA2/include/linux/input.h
+--- LINUS_2_6_11/include/linux/input.h 2005-03-02 04:19:22.000000000 -0700
++++ CVS2_6_11_PA2/include/linux/input.h 2005-01-12 13:17:57.000000000 -0700
+@@ -615,6 +615,7 @@
+ #define BUS_ADB 0x17
+ #define BUS_I2C 0x18
+ #define BUS_HOST 0x19
++#define BUS_GSC 0x1A
+
+ /*
+ * Values describing the status of an effect
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/linux/signal.h CVS2_6_11_PA2/include/linux/signal.h
+--- LINUS_2_6_11/include/linux/signal.h 2005-03-02 04:19:22.000000000 -0700
++++ CVS2_6_11_PA2/include/linux/signal.h 2004-09-13 09:24:14.000000000 -0600
+@@ -220,6 +220,9 @@
+ extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
+ #endif
+
++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_11/include/scsi/scsi_transport_spi.h CVS2_6_11_PA2/include/scsi/scsi_transport_spi.h
+--- LINUS_2_6_11/include/scsi/scsi_transport_spi.h 2005-03-02 04:19:23.000000000 -0700
++++ CVS2_6_11_PA2/include/scsi/scsi_transport_spi.h 2005-02-23 11:31:37.000000000 -0700
+@@ -130,5 +130,6 @@
+ void spi_release_transport(struct scsi_transport_template *);
+ void spi_schedule_dv_device(struct scsi_device *);
+ void spi_dv_device(struct scsi_device *);
++void spi_display_xfer_agreement(struct scsi_target *);
+
+ #endif /* SCSI_TRANSPORT_SPI_H */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/include/sound/opl3.h CVS2_6_11_PA2/include/sound/opl3.h
+--- LINUS_2_6_11/include/sound/opl3.h 2005-03-02 04:19:23.000000000 -0700
++++ CVS2_6_11_PA2/include/sound/opl3.h 2005-03-01 09:56:38.000000000 -0700
+@@ -261,8 +261,8 @@
+ } 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;
+ unsigned short hardware;
+@@ -319,6 +319,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_11/ipc/compat_mq.c CVS2_6_11_PA2/ipc/compat_mq.c
+--- LINUS_2_6_11/ipc/compat_mq.c 2005-03-02 04:19:24.000000000 -0700
++++ CVS2_6_11_PA2/ipc/compat_mq.c 2004-07-20 16:07:41.000000000 -0600
+@@ -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_11/kernel/Makefile CVS2_6_11_PA2/kernel/Makefile
+--- LINUS_2_6_11/kernel/Makefile 2005-03-02 04:19:24.000000000 -0700
++++ CVS2_6_11_PA2/kernel/Makefile 2004-11-29 12:56:52.000000000 -0700
+@@ -17,7 +17,7 @@
+ obj-$(CONFIG_KALLSYMS) += kallsyms.o
+ obj-$(CONFIG_PM) += power/
+ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
+-obj-$(CONFIG_COMPAT) += compat.o
++obj-$(CONFIG_COMPAT) += compat.o compat_signal.o
+ obj-$(CONFIG_IKCONFIG) += configs.o
+ obj-$(CONFIG_IKCONFIG_PROC) += 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_11/kernel/compat.c CVS2_6_11_PA2/kernel/compat.c
+--- LINUS_2_6_11/kernel/compat.c 2005-03-02 04:19:24.000000000 -0700
++++ CVS2_6_11_PA2/kernel/compat.c 2005-01-22 07:59:56.000000000 -0700
+@@ -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>
+@@ -601,6 +602,26 @@
+
+ /* 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;
++ mm_segment_t old_fs = get_fs();
++ long ret;
++
++ if (timer_event_spec != NULL)
++ if (compat_copy_sigevent_from_user(&kevent, timer_event_spec) != 0)
++ return -EFAULT;
++
++ set_fs(KERNEL_DS);
++ ret = sys_timer_create(which_clock, timer_event_spec ? (sigevent_t __user *)&kevent : NULL, created_timer_id);
++ set_fs(old_fs);
++
++ return ret;
++}
++
++
+ long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask,
+ unsigned long bitmap_size)
+ {
+@@ -682,6 +703,40 @@
+ return 0;
+ }
+
++asmlinkage int compat_sys_waitid(int which, pid_t pid,
++ compat_siginfo_t __user *infop, int options,
++ struct compat_rusage __user *ru)
++{
++ long ret;
++ siginfo_t ksiginfo;
++ struct rusage kru;
++ mm_segment_t old_fs = get_fs();
++
++ memset(&ksiginfo, 0, sizeof(ksiginfo));
++
++ set_fs(KERNEL_DS);
++ ret = sys_waitid(which, pid, (siginfo_t __user *)&ksiginfo, options, (struct rusage __user *)&kru);
++ set_fs(old_fs);
++
++ /* If there was an error don't bother copying siginfo */
++ if (ret < 0 || ksiginfo.si_signo == 0)
++ return ret;
++
++ if (ru) {
++ ret = put_compat_rusage(&kru, ru);
++ if (ret)
++ return ret;
++ }
++
++ /* Tell copy_siginfo_to_user that it was __SI_CHLD */
++ ksiginfo.si_code |= __SI_CHLD;
++
++ if (compat_copy_siginfo_to_user(infop, &ksiginfo) != 0)
++ return -EFAULT;
++
++ return 0;
++}
++
+ void
+ sigset_from_compat (sigset_t *set, compat_sigset_t *compat)
+ {
+@@ -758,7 +813,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_11/kernel/compat_signal.c CVS2_6_11_PA2/kernel/compat_signal.c
+--- LINUS_2_6_11/kernel/compat_signal.c 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/kernel/compat_signal.c 2004-11-03 15:07:38.000000000 -0700
+@@ -0,0 +1,244 @@
++/*
++ * 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
++
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/kernel/printk.c CVS2_6_11_PA2/kernel/printk.c
+--- LINUS_2_6_11/kernel/printk.c 2005-03-02 04:19:24.000000000 -0700
++++ CVS2_6_11_PA2/kernel/printk.c 2005-02-13 19:55:36.000000000 -0700
+@@ -92,8 +92,8 @@
+ * must be masked before subscripting
+ */
+ static unsigned long log_start; /* Index into log_buf: next char to be read by syslog() */
+-static unsigned long con_start; /* Index into log_buf: next char to be sent to consoles */
+-static unsigned long log_end; /* Index into log_buf: most-recently-written-char + 1 */
++unsigned long con_start; /* Index into log_buf: next char to be sent to consoles */
++unsigned long log_end; /* Index into log_buf: most-recently-written-char + 1 */
+ static unsigned long logged_chars; /* Number of chars produced since last read+clear operation */
+
+ /*
+@@ -804,6 +804,11 @@
+ if (!(console->flags & CON_ENABLED))
+ return;
+
++ if (console_drivers && (console_drivers->flags & CON_BOOT)) {
++ unregister_console(console_drivers);
++ console->flags &= ~CON_PRINTBUFFER;
++ }
++
+ /*
+ * Put this console in the list - keep the
+ * preferred driver at the head of the list.
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/kernel/ptrace.c CVS2_6_11_PA2/kernel/ptrace.c
+--- LINUS_2_6_11/kernel/ptrace.c 2005-03-02 04:19:24.000000000 -0700
++++ CVS2_6_11_PA2/kernel/ptrace.c 2005-02-03 04:45:14.000000000 -0700
+@@ -343,7 +343,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_11/kernel/resource.c CVS2_6_11_PA2/kernel/resource.c
+--- LINUS_2_6_11/kernel/resource.c 2005-03-02 04:19:24.000000000 -0700
++++ CVS2_6_11_PA2/kernel/resource.c 2005-01-12 13:18:05.000000000 -0700
+@@ -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_11/kernel/signal.c CVS2_6_11_PA2/kernel/signal.c
+--- LINUS_2_6_11/kernel/signal.c 2005-03-02 04:19:24.000000000 -0700
++++ CVS2_6_11_PA2/kernel/signal.c 2005-02-03 04:45:14.000000000 -0700
+@@ -22,6 +22,7 @@
+ #include <linux/security.h>
+ #include <linux/syscalls.h>
+ #include <linux/ptrace.h>
++#include <linux/compat_siginfo.h>
+ #include <asm/param.h>
+ #include <asm/uaccess.h>
+ #include <asm/unistd.h>
+@@ -2083,17 +2084,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.
+@@ -2330,7 +2349,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_11/mm/shmem.c CVS2_6_11_PA2/mm/shmem.c
+--- LINUS_2_6_11/mm/shmem.c 2005-03-02 04:19:24.000000000 -0700
++++ CVS2_6_11_PA2/mm/shmem.c 2005-02-13 19:55:36.000000000 -0700
+@@ -461,7 +461,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_11/sound/drivers/opl3/opl3_lib.c CVS2_6_11_PA2/sound/drivers/opl3/opl3_lib.c
+--- LINUS_2_6_11/sound/drivers/opl3/opl3_lib.c 2005-03-02 04:19:28.000000000 -0700
++++ CVS2_6_11_PA2/sound/drivers/opl3/opl3_lib.c 2005-03-01 09:56:38.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
+@@ -333,6 +333,8 @@
+ release_resource(opl3->res_r_port);
+ kfree_nocheck(opl3->res_r_port);
+ }
++ iounmap(opl3->l_port);
++ iounmap(opl3->r_port);
+ kfree(opl3);
+ return 0;
+ }
+@@ -397,12 +399,13 @@
+ 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,
++ struct resource *res_l_port,
++ struct resource *res_r_port,
++ unsigned short hardware,
++ opl3_t ** ropl3)
+ {
+ opl3_t *opl3;
+ int err;
+@@ -410,21 +413,10 @@
+ *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->res_l_port = res_l_port;
++ opl3->res_r_port = res_r_port;
+
+ switch (opl3->hardware) {
+ /* some hardware doesn't support timers */
+@@ -455,6 +447,67 @@
+ 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, 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, res_l_port, res_r_port, hardware, ropl3);
++
++fail:
++ if (res_l_port) {
++ release_resource(res_l_port);
++ kfree_nocheck(res_l_port);
++ }
++ if (res_r_port) {
++ release_resource(res_r_port);
++ kfree_nocheck(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;
+@@ -534,6 +587,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_11/sound/oss/ad1889.c CVS2_6_11_PA2/sound/oss/ad1889.c
+--- LINUS_2_6_11/sound/oss/ad1889.c 2005-03-02 04:19:28.000000000 -0700
++++ CVS2_6_11_PA2/sound/oss/ad1889.c 2005-03-01 16:00:56.000000000 -0700
+@@ -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);
+ }
+@@ -301,53 +301,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 }
+ };
+
+@@ -400,9 +400,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;
+ }
+@@ -639,9 +639,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;
+
+@@ -649,22 +649,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;
+@@ -739,7 +739,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:
+@@ -769,7 +769,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);
+ }
+
+@@ -826,15 +826,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)
+@@ -883,24 +883,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--;
+@@ -908,16 +908,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;
+ }
+
+@@ -935,10 +935,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");
+@@ -964,15 +964,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)
+@@ -1005,7 +1005,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_11/sound/oss/ad1889.h CVS2_6_11_PA2/sound/oss/ad1889.h
+--- LINUS_2_6_11/sound/oss/ad1889.h 2005-03-02 04:19:28.000000000 -0700
++++ CVS2_6_11_PA2/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_11/sound/oss/harmony.c CVS2_6_11_PA2/sound/oss/harmony.c
+--- LINUS_2_6_11/sound/oss/harmony.c 2005-03-02 04:19:28.000000000 -0700
++++ CVS2_6_11_PA2/sound/oss/harmony.c 2005-02-28 19:08:15.000000000 -0700
+@@ -310,7 +310,7 @@
+ case 32000: newrate = HARMONY_SR_32KHZ; break;
+ case 48000: newrate = HARMONY_SR_48KHZ; break;
+ case 9600: newrate = HARMONY_SR_9KHZ; break;
+- case 5125: newrate = HARMONY_SR_5KHZ; break;
++ case 5512: newrate = HARMONY_SR_5KHZ; break;
+ case 11025: newrate = HARMONY_SR_11KHZ; break;
+ case 18900: newrate = HARMONY_SR_18KHZ; break;
+ case 22050: newrate = HARMONY_SR_22KHZ; break;
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/sound/parisc/Kconfig CVS2_6_11_PA2/sound/parisc/Kconfig
+--- LINUS_2_6_11/sound/parisc/Kconfig 2005-03-02 04:19:29.000000000 -0700
++++ CVS2_6_11_PA2/sound/parisc/Kconfig 2004-12-13 00:19:10.000000000 -0700
+@@ -1,6 +1,6 @@
+ # ALSA PA-RISC drivers
+
+-menu "ALSA GSC devices"
++menu "GSC devices"
+ depends on SND!=n && GSC
+
+ config SND_HARMONY
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/sound/parisc/harmony.c CVS2_6_11_PA2/sound/parisc/harmony.c
+--- LINUS_2_6_11/sound/parisc/harmony.c 2005-03-02 04:19:29.000000000 -0700
++++ CVS2_6_11_PA2/sound/parisc/harmony.c 2005-03-01 08:28:41.000000000 -0700
+@@ -1,264 +1,88 @@
+-/*
+- * Harmony chipset driver
++/* Hewlett-Packard Harmony audio driver
+ *
+- * This is a sound driver for ASP's and Lasi's Harmony sound chip
+- * and is unlikely to be used for anything other than on a HP PA-RISC.
++ * This is a driver for the Harmony audio chipset found
++ * on the LASI ASIC of various early HP PA-RISC workstations.
+ *
+- * Harmony is found in HP 712s, 715/new and many other GSC based machines.
+- * On older 715 machines you'll find the technically identical chip
+- * called 'Vivace'. Both Harmony and Vivace are supported by this driver.
++ * Copyright (C) 2004, Kyle McMartin <kyle@{debian.org,parisc-linux.org}>
+ *
+- * this ALSA driver is based on OSS driver by:
+- * Copyright 2000 (c) Linuxcare Canada, Alex deVries <alex at linuxcare.com>
+- * Copyright 2000-2002 (c) Helge Deller <deller at gmx.de>
+- * Copyright 2001 (c) Matthieu Delahaye <delahaym at esiee.fr>
++ * Based on the previous Harmony incarnations by,
++ * Copyright 2000 (c) Linuxcare Canada, Alex deVries
++ * Copyright 2000-2003 (c) Helge Deller
++ * Copyright 2001 (c) Matthieu Delahaye
++ * Copyright 2001 (c) Jean-Christophe Vaugeois
++ * Copyright 2003 (c) Laurent Canet
++ * Copyright 2004 (c) Stuart Brady
+ *
+- * TODO:
+- * - use generic DMA interface and ioremap()/iounmap()
+- * - capture is still untested (and probaby non-working)
+- * - spin locks
+- * - implement non-consistent DMA pages
+- * - implement gain meter
+- * - module parameters
+- * - correct cleaning sequence
+- * - better error checking
+- * - try to have a better quality.
+- *
+- */
+-
+-/*
+- * Harmony chipset 'modus operandi'.
+- * - This chipset is found in some HP 32bit workstations, like 712, or B132 class.
+- * most of controls are done through registers. Register are found at a fixed offset
+- * from the hard physical adress, given in struct dev by register_parisc_driver.
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License, version 2, as
++ * published by the Free Software Foundation.
+ *
+- * Playback and recording use 4kb pages (dma or not, depending on the machine).
++ * 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.
+ *
+- * Most of PCM playback & capture is done through interrupt. When harmony needs
+- * a new buffer to put recorded data or read played PCM, it sends an interrupt.
+- * Bits 2 and 10 of DSTATUS register are '1' when harmony needs respectively
+- * a new page for recording and playing.
+- * Interrupt are disabled/enabled by writing to bit 32 of DSTATUS.
+- * Adresses of next page to be played is put in PNXTADD register, next page
+- * to be recorded is put in RNXTADD. There is 2 read-only registers, PCURADD and
+- * RCURADD that provides adress of current page.
+- *
+- * Harmony has no way to control full duplex or half duplex mode. It means
+- * that we always need to provide adresses of playback and capture data, even
+- * when this is not needed. That's why we statically alloc one graveyard
+- * buffer (to put recorded data in play-only mode) and a silence buffer.
+- *
+- * Bitrate, number of channels and data format are controlled with
+- * the CNTL register.
++ * 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.
+ *
+- * Mixer work is done through one register (GAINCTL). Only input gain,
+- * output attenuation and general attenuation control is provided. There is
+- * also controls for enabling/disabling internal speaker and line
+- * input.
++ * Notes:
++ * - graveyard and silence buffers last for lifetime of
++ * the driver. playback and capture buffers are allocated
++ * per _open()/_close().
++ *
++ * TODO:
+ *
+- * Buffers used by this driver are all DMA consistent.
+ */
+
+-#include <linux/delay.h>
+-#include <sound/driver.h>
+ #include <linux/init.h>
+-#include <linux/interrupt.h>
+ #include <linux/slab.h>
+ #include <linux/time.h>
+ #include <linux/wait.h>
+-#include <linux/moduleparam.h>
++#include <linux/delay.h>
++#include <linux/module.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/dma-mapping.h>
++
++#include <sound/driver.h>
+ #include <sound/core.h>
+-#include <sound/control.h>
+ #include <sound/pcm.h>
++#include <sound/control.h>
+ #include <sound/rawmidi.h>
+ #include <sound/initval.h>
+ #include <sound/info.h>
+-#include <asm/hardware.h>
++
+ #include <asm/io.h>
++#include <asm/hardware.h>
+ #include <asm/parisc-device.h>
+
+-MODULE_AUTHOR("Laurent Canet <canetl at esiee.fr>");
+-MODULE_DESCRIPTION("ALSA Harmony sound driver");
+-MODULE_LICENSE("GPL");
+-MODULE_SUPPORTED_DEVICE("{{ALSA,Harmony soundcard}}");
+-
+-#undef DEBUG
+-#ifdef DEBUG
+-# define DPRINTK printk
+-#else
+-# define DPRINTK(x,...)
+-#endif
+-
+-#define PFX "harmony: "
+-
+-#define MAX_PCM_DEVICES 1
+-#define MAX_PCM_SUBSTREAMS 4
+-#define MAX_MIDI_DEVICES 0
+-
+-#define HARMONY_BUF_SIZE 4096
+-#define MAX_BUFS 10
+-#define MAX_BUFFER_SIZE (MAX_BUFS * HARMONY_BUF_SIZE)
+-
+-/* number of silence & graveyard buffers */
+-#define GRAVEYARD_BUFS 3
+-#define SILENCE_BUFS 3
+-
+-#define HARMONY_CNTL_C 0x80000000
+-
+-#define HARMONY_DSTATUS_PN 0x00000200
+-#define HARMONY_DSTATUS_RN 0x00000002
+-#define HARMONY_DSTATUS_IE 0x80000000
+-
+-#define HARMONY_DF_16BIT_LINEAR 0x00000000
+-#define HARMONY_DF_8BIT_ULAW 0x00000001
+-#define HARMONY_DF_8BIT_ALAW 0x00000002
+-
+-#define HARMONY_SS_MONO 0x00000000
+-#define HARMONY_SS_STEREO 0x00000001
+-
+-/*
+- * Channels Mask in mixer register
+- * try some "reasonable" default gain values
+- */
+-
+-#define HARMONY_GAIN_TOTAL_SILENCE 0x00F00FFF
+-
+-/* the following should be enough (mixer is
+- * very sensible on harmony)
+- */
+-#define HARMONY_GAIN_DEFAULT 0x0F2FF082
+-
+-
+-/* useless since only one card is supported ATM */
+-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
+-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
+-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
+-
+-module_param_array(index, int, NULL, 0444);
+-MODULE_PARM_DESC(index, "Index value for Harmony device.");
+-module_param_array(id, charp, NULL, 0444);
+-MODULE_PARM_DESC(id, "ID string for Harmony device.");
+-module_param_array(enable, bool, NULL, 0444);
+-MODULE_PARM_DESC(enable, "Enable Harmony device.");
+-
+-/* Register offset (from base hpa) */
+-#define REG_ID 0x00
+-#define REG_RESET 0x04
+-#define REG_CNTL 0x08
+-#define REG_GAINCTL 0x0C
+-#define REG_PNXTADD 0x10
+-#define REG_PCURADD 0x14
+-#define REG_RNXTADD 0x18
+-#define REG_RCURADD 0x1C
+-#define REG_DSTATUS 0x20
+-#define REG_OV 0x24
+-#define REG_PIO 0x28
+-#define REG_DIAG 0x3C
+-
+-/*
+- * main harmony structure
+- */
+-
+-typedef struct snd_card_harmony {
+-
+- /* spinlocks (To be done) */
+- spinlock_t mixer_lock;
+- spinlock_t control_lock;
+-
+- /* parameters */
+- int irq;
+- unsigned long hpa;
+- int id;
+- int rev;
+-
+- u32 current_gain;
+- int data_format; /* HARMONY_DF_xx_BIT_xxx */
+- int sample_rate; /* HARMONY_SR_xx_KHZ */
+- int stereo_select; /* HARMONY_SS_MONO or HARMONY_SS_STEREO */
+- int format_initialized;
+-
+- unsigned long ply_buffer;
+- int ply_buf;
+- int ply_count;
+- int ply_size;
+- int ply_stopped;
+- int ply_total;
+-
+- unsigned long cap_buffer;
+- int cap_buf;
+- int cap_count;
+- int cap_size;
+- int cap_stopped;
+- int cap_total;
+-
+- struct parisc_device *pa_dev;
+-
+- struct snd_dma_device dma_dev;
+-
+- /* the graveyard buffer is used as recording buffer when playback,
+- * because harmony always want a buffer to put recorded data */
+- struct snd_dma_buffer graveyard_dma;
+- int graveyard_count;
+-
+- /* same thing for silence buffer */
+- struct snd_dma_buffer silence_dma;
+- int silence_count;
+-
+- /* alsa stuff */
+- snd_card_t *card;
+- snd_pcm_t *pcm;
+- snd_pcm_substream_t *playback_substream;
+- snd_pcm_substream_t *capture_substream;
+- snd_info_entry_t *proc_entry;
+-} snd_card_harmony_t;
++#include "harmony.h"
+
+-static snd_card_t *snd_harmony_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
++static struct parisc_device_id snd_harmony_devtable[] = {
++ /* bushmaster / flounder */
++ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A },
++ /* 712 / 715 */
++ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007B },
++ /* pace */
++ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007E },
++ /* outfield / coral II */
++ { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007F },
++ { 0, }
++};
+
+-/* wait to be out of control mode */
+-static inline void snd_harmony_wait_cntl(snd_card_harmony_t *harmony)
+-{
+- int timeout = 5000;
++MODULE_DEVICE_TABLE(parisc, snd_harmony_devtable);
+
+- while ( (gsc_readl(harmony->hpa+REG_CNTL) & HARMONY_CNTL_C) && --timeout)
+- {
+- /* Wait */ ;
+- }
+- if (timeout == 0) DPRINTK(KERN_DEBUG PFX "Error: wait cntl timeouted\n");
+-}
++#define NAME "harmony"
++#define PFX NAME ": "
+
+-
+-/*
+- * sample rate routines
+- */
+-static unsigned int snd_card_harmony_rates[] = {
+- 5125, 6615, 8000, 9600,
++static unsigned int snd_harmony_rates[] = {
++ 5512, 6615, 8000, 9600,
+ 11025, 16000, 18900, 22050,
+ 27428, 32000, 33075, 37800,
+ 44100, 48000
+ };
+
+-static snd_pcm_hw_constraint_list_t hw_constraint_rates = {
+- .count = ARRAY_SIZE(snd_card_harmony_rates),
+- .list = snd_card_harmony_rates,
+- .mask = 0,
+-};
+-
+-#define HARMONY_SR_8KHZ 0x08
+-#define HARMONY_SR_16KHZ 0x09
+-#define HARMONY_SR_27KHZ 0x0A
+-#define HARMONY_SR_32KHZ 0x0B
+-#define HARMONY_SR_48KHZ 0x0E
+-#define HARMONY_SR_9KHZ 0x0F
+-#define HARMONY_SR_5KHZ 0x10
+-#define HARMONY_SR_11KHZ 0x11
+-#define HARMONY_SR_18KHZ 0x12
+-#define HARMONY_SR_22KHZ 0x13
+-#define HARMONY_SR_37KHZ 0x14
+-#define HARMONY_SR_44KHZ 0x15
+-#define HARMONY_SR_33KHZ 0x16
+-#define HARMONY_SR_6KHZ 0x17
+-
+-/* bits corresponding to the entries of snd_card_harmony_rates */
+ static unsigned int rate_bits[14] = {
+ HARMONY_SR_5KHZ, HARMONY_SR_6KHZ, HARMONY_SR_8KHZ,
+ HARMONY_SR_9KHZ, HARMONY_SR_11KHZ, HARMONY_SR_16KHZ,
+@@ -267,642 +91,624 @@
+ HARMONY_SR_44KHZ, HARMONY_SR_48KHZ
+ };
+
+-/* snd_card_harmony_rate_bits
+- * @rate: index of current data rate in list
+- * returns: harmony hex code for registers
+- */
+-static unsigned int snd_card_harmony_rate_bits(int rate)
++static snd_pcm_hw_constraint_list_t hw_constraint_rates = {
++ .count = ARRAY_SIZE(snd_harmony_rates),
++ .list = snd_harmony_rates,
++ .mask = 0,
++};
++
++inline unsigned long
++harmony_read(harmony_t *h, unsigned r)
+ {
+- unsigned int idx;
+-
+- for (idx = 0; idx < ARRAY_SIZE(snd_card_harmony_rates); idx++)
+- if (snd_card_harmony_rates[idx] == rate)
+- return rate_bits[idx];
+- return HARMONY_SR_44KHZ; /* fallback */
++ return __raw_readl(h->iobase + r);
+ }
+
+-/*
+- * update controls (data format, sample rate, number of channels)
+- * according to value supplied in data structure
+- */
+-void snd_harmony_update_control(snd_card_harmony_t *harmony)
++inline void
++harmony_write(harmony_t *h, unsigned r, unsigned long v)
+ {
+- u32 default_cntl;
+-
+- /* Set CNTL */
+- default_cntl = (HARMONY_CNTL_C | /* The C bit */
+- (harmony->data_format << 6) | /* Set the data format */
+- (harmony->stereo_select << 5) | /* Stereo select */
+- (harmony->sample_rate)); /* Set sample rate */
+-
+- /* initialize CNTL */
+- snd_harmony_wait_cntl(harmony);
+-
+- gsc_writel(default_cntl, harmony->hpa+REG_CNTL);
+-
++ __raw_writel(v, h->iobase + r);
+ }
+
+-/*
+- * interruption controls routines
+- */
++static void
++harmony_wait_for_control(harmony_t *h)
++{
++ while (harmony_read(h, HARMONY_CNTL) & HARMONY_CNTL_C) ;
++}
+
+-static void snd_harmony_disable_interrupts(snd_card_harmony_t *chip)
++inline void
++harmony_reset(harmony_t *h)
+ {
+- snd_harmony_wait_cntl(chip);
+- gsc_writel(0, chip->hpa+REG_DSTATUS);
++ harmony_write(h, HARMONY_RESET, 1);
++ mdelay(50);
++ harmony_write(h, HARMONY_RESET, 0);
+ }
+
+-static void snd_harmony_enable_interrupts(snd_card_harmony_t *chip)
++static void
++harmony_disable_interrupts(harmony_t *h)
+ {
+- snd_harmony_wait_cntl(chip);
+- gsc_writel(HARMONY_DSTATUS_IE, chip->hpa+REG_DSTATUS);
++ u32 dstatus;
++ harmony_wait_for_control(h);
++ dstatus = harmony_read(h, HARMONY_DSTATUS);
++ dstatus &= ~HARMONY_DSTATUS_IE;
++ harmony_write(h, HARMONY_DSTATUS, dstatus);
+ }
+
+-/*
+- * interruption routine:
+- * The interrupt routine must provide adresse of next physical pages
+- * used by harmony
+- */
+-static int snd_card_harmony_interrupt(int irq, void *dev, struct pt_regs *regs)
++static void
++harmony_enable_interrupts(harmony_t *h)
+ {
+- snd_card_harmony_t *harmony = (snd_card_harmony_t *)dev;
+- u32 dstatus = 0;
+- unsigned long hpa = harmony->hpa;
+-
+- /* Turn off interrupts */
+- snd_harmony_disable_interrupts(harmony);
+-
+- /* wait for control to free */
+- snd_harmony_wait_cntl(harmony);
+-
+- /* Read dstatus and pcuradd (the current address) */
+- dstatus = gsc_readl(hpa+REG_DSTATUS);
+-
+- /* Check if this is a request to get the next play buffer */
++ u32 dstatus;
++ harmony_wait_for_control(h);
++ dstatus = harmony_read(h, HARMONY_DSTATUS);
++ dstatus |= HARMONY_DSTATUS_IE;
++ harmony_write(h, HARMONY_DSTATUS, dstatus);
++}
++
++static void
++harmony_mute(harmony_t *h)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&h->mixer_lock, flags);
++ harmony_wait_for_control(h);
++ harmony_write(h, HARMONY_GAINCTL, HARMONY_GAIN_SILENCE);
++ spin_unlock_irqrestore(&h->mixer_lock, flags);
++}
++
++static void
++harmony_unmute(harmony_t *h)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&h->mixer_lock, flags);
++ harmony_wait_for_control(h);
++ harmony_write(h, HARMONY_GAINCTL, h->st.gain);
++ spin_unlock_irqrestore(&h->mixer_lock, flags);
++}
++
++static void
++harmony_set_control(harmony_t *h)
++{
++ u32 ctrl;
++ unsigned long flags;
++
++ spin_lock_irqsave(&h->lock, flags);
++
++ ctrl = (HARMONY_CNTL_C |
++ (h->st.format << 6) |
++ (h->st.stereo << 5) |
++ (h->st.rate));
++
++ harmony_wait_for_control(h);
++ harmony_write(h, HARMONY_CNTL, ctrl);
++
++ spin_unlock_irqrestore(&h->lock, flags);
++}
++
++static irqreturn_t
++snd_harmony_interrupt(int irq, void *dev, struct pt_regs *regs)
++{
++ u32 dstatus;
++ harmony_t *h = dev;
++
++ spin_lock(&h->lock);
++ harmony_disable_interrupts(h);
++ harmony_wait_for_control(h);
++ dstatus = harmony_read(h, HARMONY_DSTATUS);
++ spin_unlock(&h->lock);
++
+ if (dstatus & HARMONY_DSTATUS_PN) {
+- if (harmony->playback_substream) {
+- harmony->ply_buf += harmony->ply_count;
+- harmony->ply_buf %= harmony->ply_size;
+-
+- gsc_writel(harmony->ply_buffer + harmony->ply_buf,
+- hpa+REG_PNXTADD);
+-
+- snd_pcm_period_elapsed(harmony->playback_substream);
+- harmony->ply_total++;
++ if (h->psubs) {
++ spin_lock(&h->lock);
++ h->pbuf.buf += h->pbuf.count; /* PAGE_SIZE */
++ h->pbuf.buf %= h->pbuf.size; /* MAX_BUFS*PAGE_SIZE */
++
++ harmony_write(h, HARMONY_PNXTADD,
++ h->pbuf.addr + h->pbuf.buf);
++ h->stats.play_intr++;
++ spin_unlock(&h->lock);
++ snd_pcm_period_elapsed(h->psubs);
+ } else {
+- gsc_writel(harmony->silence_dma.addr +
+- (HARMONY_BUF_SIZE*harmony->silence_count),
+- hpa+REG_PNXTADD);
+- harmony->silence_count++;
+- harmony->silence_count %= SILENCE_BUFS;
++ spin_lock(&h->lock);
++ harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
++ h->stats.silence_intr++;
++ spin_unlock(&h->lock);
+ }
+ }
+-
+- /* Check if we're being asked to fill in a recording buffer */
++
+ if (dstatus & HARMONY_DSTATUS_RN) {
+- if (harmony->capture_substream) {
+- harmony->cap_buf += harmony->cap_count;
+- harmony->cap_buf %= harmony->cap_size;
+-
+- gsc_writel(harmony->cap_buffer + harmony->cap_buf,
+- hpa+REG_RNXTADD);
+-
+- snd_pcm_period_elapsed(harmony->capture_substream);
+- harmony->cap_total++;
++ if (h->csubs) {
++ spin_lock(&h->lock);
++ h->cbuf.buf += h->cbuf.count;
++ h->cbuf.buf %= h->cbuf.size;
++
++ harmony_write(h, HARMONY_RNXTADD,
++ h->cbuf.addr + h->cbuf.buf);
++ h->stats.rec_intr++;
++ spin_unlock(&h->lock);
++ snd_pcm_period_elapsed(h->csubs);
+ } else {
+- /* graveyard buffer */
+- gsc_writel(harmony->graveyard_dma.addr +
+- (HARMONY_BUF_SIZE*harmony->graveyard_count),
+- hpa+REG_RNXTADD);
+- harmony->graveyard_count++;
+- harmony->graveyard_count %= GRAVEYARD_BUFS;
++ spin_lock(&h->lock);
++ harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
++ h->stats.graveyard_intr++;
++ spin_unlock(&h->lock);
+ }
+ }
+- snd_harmony_enable_interrupts(harmony);
++
++ spin_lock(&h->lock);
++ harmony_enable_interrupts(h);
++ spin_unlock(&h->lock);
+
+ return IRQ_HANDLED;
+ }
+
+-/*
+- * proc entry
+- * this proc file will give some debugging info
+- */
+-
+-static void snd_harmony_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
++static unsigned int
++snd_harmony_rate_bits(int rate)
+ {
+- snd_card_harmony_t *harmony = (snd_card_harmony_t *)entry->private_data;
+-
+- snd_iprintf(buffer, "LASI Harmony driver\nLaurent Canet <canetl at esiee.fr>\n\n");
+- snd_iprintf(buffer, "IRQ %d, hpa %lx, id %d rev %d\n",
+- harmony->irq, harmony->hpa,
+- harmony->id, harmony->rev);
+- snd_iprintf(buffer, "Current gain %lx\n", (unsigned long) harmony->current_gain);
+- snd_iprintf(buffer, "\tsample rate=%d\n", harmony->sample_rate);
+- snd_iprintf(buffer, "\tstereo select=%d\n", harmony->stereo_select);
+- snd_iprintf(buffer, "\tbitperchan=%d\n\n", harmony->data_format);
+-
+- snd_iprintf(buffer, "Play status:\n");
+- snd_iprintf(buffer, "\tstopped %d\n", harmony->ply_stopped);
+- snd_iprintf(buffer, "\tbuffer %lx, count %d\n", harmony->ply_buffer, harmony->ply_count);
+- snd_iprintf(buffer, "\tbuf %d size %d\n\n", harmony->ply_buf, harmony->ply_size);
+-
+- snd_iprintf(buffer, "Capture status:\n");
+- snd_iprintf(buffer, "\tstopped %d\n", harmony->cap_stopped);
+- snd_iprintf(buffer, "\tbuffer %lx, count %d\n", harmony->cap_buffer, harmony->cap_count);
+- snd_iprintf(buffer, "\tbuf %d, size %d\n\n", harmony->cap_buf, harmony->cap_size);
+-
+- snd_iprintf(buffer, "Funny stats: total played=%d, recorded=%d\n\n", harmony->ply_total, harmony->cap_total);
+-
+- snd_iprintf(buffer, "Register:\n");
+- snd_iprintf(buffer, "\tgainctl: %lx\n", (unsigned long) gsc_readl(harmony->hpa+REG_GAINCTL));
+- snd_iprintf(buffer, "\tcntl: %lx\n", (unsigned long) gsc_readl(harmony->hpa+REG_CNTL));
+- snd_iprintf(buffer, "\tid: %lx\n", (unsigned long) gsc_readl(harmony->hpa+REG_ID));
+- snd_iprintf(buffer, "\tpcuradd: %lx\n", (unsigned long) gsc_readl(harmony->hpa+REG_PCURADD));
+- snd_iprintf(buffer, "\trcuradd: %lx\n", (unsigned long) gsc_readl(harmony->hpa+REG_RCURADD));
+- snd_iprintf(buffer, "\tpnxtadd: %lx\n", (unsigned long) gsc_readl(harmony->hpa+REG_PNXTADD));
+- snd_iprintf(buffer, "\trnxtadd: %lx\n", (unsigned long) gsc_readl(harmony->hpa+REG_RNXTADD));
+- snd_iprintf(buffer, "\tdstatus: %lx\n", (unsigned long) gsc_readl(harmony->hpa+REG_DSTATUS));
+- snd_iprintf(buffer, "\tov: %lx\n\n", (unsigned long) gsc_readl(harmony->hpa+REG_OV));
++ unsigned int i;
+
+-}
++ for (i = 0; i < ARRAY_SIZE(snd_harmony_rates); i++)
++ if (snd_harmony_rates[i] == rate)
++ return rate_bits[i];
++
++ return HARMONY_SR_44KHZ;
++}
++
++static snd_pcm_hardware_t snd_harmony_playback =
++{
++ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
++ SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
++ SNDRV_PCM_INFO_BLOCK_TRANSFER),
++ .formats = (SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_MU_LAW |
++ SNDRV_PCM_FMTBIT_A_LAW),
++ .rates = (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 |
++ SNDRV_PCM_RATE_KNOT),
++ .rate_min = 5512,
++ .rate_max = 48000,
++ .channels_min = 1,
++ .channels_max = 2,
++ .buffer_bytes_max = MAX_BUF_SIZE,
++ .period_bytes_min = BUF_SIZE,
++ .period_bytes_max = BUF_SIZE,
++ .periods_min = 1,
++ .periods_max = MAX_BUFS,
++ .fifo_size = 0,
++};
+
+-static void __devinit snd_harmony_proc_init(snd_card_harmony_t *harmony)
++static snd_pcm_hardware_t snd_harmony_capture =
+ {
+- snd_info_entry_t *entry;
+-
+- if (! snd_card_proc_new(harmony->card, "harmony", &entry))
+- snd_info_set_text_ops(entry, harmony, 2048, snd_harmony_proc_read);
+-}
+-
+-/*
+- * PCM Stuff
+- */
++ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
++ SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
++ SNDRV_PCM_INFO_BLOCK_TRANSFER),
++ .formats = (SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_MU_LAW |
++ SNDRV_PCM_FMTBIT_A_LAW),
++ .rates = (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000 |
++ SNDRV_PCM_RATE_KNOT),
++ .rate_min = 5512,
++ .rate_max = 48000,
++ .channels_min = 1,
++ .channels_max = 2,
++ .buffer_bytes_max = MAX_BUF_SIZE,
++ .period_bytes_min = BUF_SIZE,
++ .period_bytes_max = BUF_SIZE,
++ .periods_min = 1,
++ .periods_max = MAX_BUFS,
++ .fifo_size = 0,
++};
+
+-static int snd_card_harmony_playback_ioctl(snd_pcm_substream_t * substream,
+- unsigned int cmd,
+- void *arg)
++static int
++snd_harmony_playback_trigger(snd_pcm_substream_t *ss, int cmd)
+ {
+- return snd_pcm_lib_ioctl(substream, cmd, arg);
+-}
++ harmony_t *h = snd_pcm_substream_chip(ss);
++ unsigned long flags;
+
+-static int snd_card_harmony_capture_ioctl(snd_pcm_substream_t * substream,
+- unsigned int cmd,
+- void *arg)
+-{
+- return snd_pcm_lib_ioctl(substream, cmd, arg);
+-}
++ if (h->st.capturing)
++ return -EBUSY;
+
+-static int snd_card_harmony_playback_trigger(snd_pcm_substream_t * substream,
+- int cmd)
+-{
+- snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
+-
++ spin_lock_irqsave(&h->lock, flags);
+ switch (cmd) {
+- case SNDRV_PCM_TRIGGER_STOP:
+- if (harmony->ply_stopped)
+- return -EBUSY;
+- harmony->ply_stopped = 1;
+- snd_harmony_disable_interrupts(harmony);
+- break;
+- case SNDRV_PCM_TRIGGER_START:
+- if (!harmony->ply_stopped)
+- return -EBUSY;
+- harmony->ply_stopped = 0;
+- /* write the location of the first buffer to play */
+- gsc_writel(harmony->ply_buffer, harmony->hpa+REG_PNXTADD);
+- snd_harmony_enable_interrupts(harmony);
+- break;
+- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+- case SNDRV_PCM_TRIGGER_SUSPEND:
+- DPRINTK(KERN_INFO PFX "received unimplemented trigger: %d\n", cmd);
+- default:
+- return -EINVAL;
++ case SNDRV_PCM_TRIGGER_START:
++ h->st.playing = 1;
++ harmony_write(h, HARMONY_PNXTADD, h->pbuf.addr);
++ harmony_write(h, HARMONY_RNXTADD, h->gdma.addr);
++ harmony_unmute(h);
++ harmony_enable_interrupts(h);
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ h->st.playing = 0;
++ harmony_mute(h);
++ harmony_disable_interrupts(h);
++ break;
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ default:
++ spin_unlock_irqrestore(&h->lock, flags);
++ snd_BUG();
++ return -EINVAL;
+ }
++ spin_unlock_irqrestore(&h->lock, flags);
++
+ return 0;
+ }
+
+-static int snd_card_harmony_capture_trigger(snd_pcm_substream_t * substream,
+- int cmd)
++static int
++snd_harmony_capture_trigger(snd_pcm_substream_t *ss, int cmd)
+ {
+- snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
+-
+- switch (cmd) {
+- case SNDRV_PCM_TRIGGER_STOP:
+- if (harmony->cap_stopped)
+- return -EBUSY;
+- harmony->cap_stopped = 1;
+- snd_harmony_disable_interrupts(harmony);
+- break;
+- case SNDRV_PCM_TRIGGER_START:
+- if (!harmony->cap_stopped)
+- return -EBUSY;
+- harmony->cap_stopped = 0;
+- snd_harmony_enable_interrupts(harmony);
+- break;
+- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+- case SNDRV_PCM_TRIGGER_SUSPEND:
+- DPRINTK(KERN_INFO PFX "Received unimplemented trigger: %d\n", cmd);
+- default:
+- return -EINVAL;
+- }
+- return 0;
++ harmony_t *h = snd_pcm_substream_chip(ss);
++ unsigned long flags;
++
++ if (h->st.playing)
++ return -EBUSY;
++
++ spin_lock_irqsave(&h->lock, flags);
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ h->st.capturing = 1;
++ harmony_write(h, HARMONY_PNXTADD, h->sdma.addr);
++ harmony_write(h, HARMONY_RNXTADD, h->cbuf.addr);
++ harmony_unmute(h);
++ harmony_enable_interrupts(h);
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ h->st.capturing = 0;
++ harmony_mute(h);
++ harmony_disable_interrupts(h);
++ break;
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ default:
++ spin_unlock_irqrestore(&h->lock, flags);
++ snd_BUG();
++ return -EINVAL;
++ }
++ spin_unlock_irqrestore(&h->lock, flags);
++
++ return 0;
+ }
+
+-/* set data format */
+-static int snd_harmony_set_data_format(snd_card_harmony_t *harmony, int pcm_format)
++static int
++snd_harmony_set_data_format(harmony_t *h, int fmt)
+ {
+- int old_format = harmony->data_format;
+- int new_format = old_format;
+- switch (pcm_format) {
++ int o = h->st.format;
++ int n;
++
++ switch(fmt) {
+ case SNDRV_PCM_FORMAT_S16_BE:
+- new_format = HARMONY_DF_16BIT_LINEAR;
++ n = HARMONY_DF_16BIT_LINEAR;
+ break;
+ case SNDRV_PCM_FORMAT_A_LAW:
+- new_format = HARMONY_DF_8BIT_ALAW;
++ n = HARMONY_DF_8BIT_ALAW;
+ break;
+ case SNDRV_PCM_FORMAT_MU_LAW:
+- new_format = HARMONY_DF_8BIT_ULAW;
++ n = HARMONY_DF_8BIT_ULAW;
+ break;
++ default:
++ n = HARMONY_DF_16BIT_LINEAR;
++ break;
++ }
++
++ if (o != n) {
++ snd_pcm_format_set_silence(fmt, h->sdma.area,
++ SILENCE_BUFSZ /
++ snd_pcm_format_width(fmt));
+ }
+- /* re-initialize silence buffer if needed */
+- if (old_format != new_format)
+- snd_pcm_format_set_silence(pcm_format, harmony->silence_dma.area,
+- (HARMONY_BUF_SIZE * SILENCE_BUFS * 8) / snd_pcm_format_width(pcm_format));
+
+- return new_format;
++ return n;
+ }
+
+-static int snd_card_harmony_playback_prepare(snd_pcm_substream_t * substream)
++static int
++snd_harmony_playback_prepare(snd_pcm_substream_t *ss)
+ {
+- snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
+- snd_pcm_runtime_t *runtime = substream->runtime;
++ harmony_t *h = snd_pcm_substream_chip(ss);
++ snd_pcm_runtime_t *rt = ss->runtime;
+
+- harmony->ply_size = snd_pcm_lib_buffer_bytes(substream);
+- harmony->ply_count = snd_pcm_lib_period_bytes(substream);
+- harmony->ply_buf = 0;
+- harmony->ply_stopped = 1;
++ if (h->st.capturing)
++ return -EBUSY;
+
+- /* initialize given sample rate */
+- harmony->sample_rate = snd_card_harmony_rate_bits(runtime->rate);
+-
+- /* data format */
+- harmony->data_format = snd_harmony_set_data_format(harmony, runtime->format);
++ h->pbuf.size = snd_pcm_lib_buffer_bytes(ss);
++ h->pbuf.count = snd_pcm_lib_period_bytes(ss);
++ h->pbuf.buf = 0;
++ h->st.playing = 0;
+
+- /* number of channels */
+- if (runtime->channels == 2)
+- harmony->stereo_select = HARMONY_SS_STEREO;
+- else
+- harmony->stereo_select = HARMONY_SS_MONO;
+-
+- DPRINTK(KERN_INFO PFX "Playback_prepare, sr=%d(%x), df=%x, ss=%x hpa=%lx\n", runtime->rate,
+- harmony->sample_rate, harmony->data_format, harmony->stereo_select, harmony->hpa);
+- snd_harmony_update_control(harmony);
+- harmony->format_initialized = 1;
+- harmony->ply_buffer = runtime->dma_addr;
++ h->st.rate = snd_harmony_rate_bits(rt->rate);
++ h->st.format = snd_harmony_set_data_format(h, rt->format);
+
++ if (rt->channels == 2)
++ h->st.stereo = HARMONY_SS_STEREO;
++ else
++ h->st.stereo = HARMONY_SS_MONO;
++
++ harmony_set_control(h);
++
++ h->pbuf.addr = rt->dma_addr;
++
+ return 0;
+ }
+
+-static int snd_card_harmony_capture_prepare(snd_pcm_substream_t * substream)
++static int
++snd_harmony_capture_prepare(snd_pcm_substream_t *ss)
+ {
+- snd_pcm_runtime_t *runtime = substream->runtime;
+- snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
+-
+- harmony->cap_size = snd_pcm_lib_buffer_bytes(substream);
+- harmony->cap_count = snd_pcm_lib_period_bytes(substream);
+- harmony->cap_count = 0;
+- harmony->cap_stopped = 1;
+-
+- /* initialize given sample rate */
+- harmony->sample_rate = snd_card_harmony_rate_bits(runtime->rate);
+-
+- /* data format */
+- harmony->data_format = snd_harmony_set_data_format(harmony, runtime->format);
+-
+- /* number of channels */
+- if (runtime->channels == 1)
+- harmony->stereo_select = HARMONY_SS_MONO;
+- else if (runtime->channels == 2)
+- harmony->stereo_select = HARMONY_SS_STEREO;
+-
+- snd_harmony_update_control(harmony);
+- harmony->format_initialized = 1;
+-
+- harmony->cap_buffer = runtime->dma_addr;
++ harmony_t *h = snd_pcm_substream_chip(ss);
++ snd_pcm_runtime_t *rt = ss->runtime;
+
+- return 0;
++ if (h->st.playing)
++ return -EBUSY;
++
++ h->cbuf.size = snd_pcm_lib_buffer_bytes(ss);
++ h->cbuf.count = snd_pcm_lib_period_bytes(ss);
++ h->cbuf.buf = 0;
++ h->st.capturing = 0;
++
++ h->st.rate = snd_harmony_rate_bits(rt->rate);
++ h->st.format = snd_harmony_set_data_format(h, rt->format);
++
++ if (rt->channels == 2)
++ h->st.stereo = HARMONY_SS_STEREO;
++ else
++ h->st.stereo = HARMONY_SS_MONO;
++
++ harmony_set_control(h);
++
++ h->cbuf.addr = rt->dma_addr;
++
++ return 0;
+ }
+
+-static snd_pcm_uframes_t snd_card_harmony_capture_pointer(snd_pcm_substream_t * substream)
++static snd_pcm_uframes_t
++snd_harmony_playback_pointer(snd_pcm_substream_t *ss)
+ {
+- snd_pcm_runtime_t *runtime = substream->runtime;
+- snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
+- unsigned long rcuradd;
+- int recorded;
+-
+- if (harmony->cap_stopped) return 0;
+- if (harmony->capture_substream == NULL) return 0;
+-
+- rcuradd = gsc_readl(harmony->hpa+REG_RCURADD);
+- recorded = (rcuradd - harmony->cap_buffer);
+- recorded %= harmony->cap_size;
+-
+- return bytes_to_frames(runtime, recorded);
+-}
++ snd_pcm_runtime_t *rt = ss->runtime;
++ harmony_t *h = snd_pcm_substream_chip(ss);
++ unsigned long pcuradd;
++ unsigned long played;
+
+-/*
+- */
++ if (!(h->st.playing) || (h->psubs == NULL))
++ return 0;
+
+-static snd_pcm_uframes_t snd_card_harmony_playback_pointer(snd_pcm_substream_t * substream)
+-{
+- snd_pcm_runtime_t *runtime = substream->runtime;
+- snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
+- int played;
+- long int pcuradd = gsc_readl(harmony->hpa+REG_PCURADD);
+-
+- if ((harmony->ply_stopped) || (harmony->playback_substream == NULL)) return 0;
+- if ((harmony->ply_buffer == 0) || (harmony->ply_size == 0)) return 0;
+-
+- played = (pcuradd - harmony->ply_buffer);
+-
+- printk(KERN_DEBUG PFX "Pointer is %lx-%lx = %d\n", pcuradd, harmony->ply_buffer, played);
+-
+- if (pcuradd > harmony->ply_buffer + harmony->ply_size) return 0;
+-
+- return bytes_to_frames(runtime, played);
+-}
+-
+-static snd_pcm_hardware_t snd_card_harmony_playback =
+-{
+- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+- SNDRV_PCM_INFO_JOINT_DUPLEX |
+- SNDRV_PCM_INFO_MMAP_VALID |
+- SNDRV_PCM_INFO_BLOCK_TRANSFER),
+- .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_BE |
+- SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_MU_LAW),
+- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
+- .rate_min = 5500,
+- .rate_max = 48000,
+- .channels_min = 1,
+- .channels_max = 2,
+- .buffer_bytes_max = MAX_BUFFER_SIZE,
+- .period_bytes_min = HARMONY_BUF_SIZE,
+- .period_bytes_max = HARMONY_BUF_SIZE,
+- .periods_min = 1,
+- .periods_max = MAX_BUFS,
+- .fifo_size = 0,
+-};
++ if ((h->pbuf.addr == 0) || (h->pbuf.size == 0))
++ return 0;
++
++ pcuradd = harmony_read(h, HARMONY_PCURADD);
++ played = pcuradd - h->pbuf.addr;
++
++#ifdef HARMONY_DEBUG
++ printk(KERN_DEBUG PFX "playback_pointer is 0x%lx-0x%lx = %d bytes\n",
++ pcuradd, h->pbuf.addr, played);
++#endif
++
++ if (pcuradd > h->pbuf.addr + h->pbuf.size) {
++ return 0;
++ }
++
++ return bytes_to_frames(rt, played);
++}
+
+-static snd_pcm_hardware_t snd_card_harmony_capture =
++static snd_pcm_uframes_t
++snd_harmony_capture_pointer(snd_pcm_substream_t *ss)
+ {
+- .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+- SNDRV_PCM_INFO_JOINT_DUPLEX |
+- SNDRV_PCM_INFO_MMAP_VALID |
+- SNDRV_PCM_INFO_BLOCK_TRANSFER),
+- .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_BE |
+- SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_MU_LAW),
+- .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
+- .rate_min = 5500,
+- .rate_max = 48000,
+- .channels_min = 1,
+- .channels_max = 2,
+- .buffer_bytes_max = MAX_BUFFER_SIZE,
+- .period_bytes_min = HARMONY_BUF_SIZE,
+- .period_bytes_max = HARMONY_BUF_SIZE,
+- .periods_min = 1,
+- .periods_max = MAX_BUFS,
+- .fifo_size = 0,
+-};
++ snd_pcm_runtime_t *rt = ss->runtime;
++ harmony_t *h = snd_pcm_substream_chip(ss);
++ unsigned long rcuradd;
++ unsigned long caught;
++
++ if (!(h->st.capturing) || (h->csubs == NULL))
++ return 0;
++
++ if ((h->cbuf.addr == 0) || (h->cbuf.size == 0))
++ return 0;
++
++ rcuradd = harmony_read(h, HARMONY_RCURADD);
++ caught = rcuradd - h->cbuf.addr;
+
+-static int snd_card_harmony_playback_open(snd_pcm_substream_t * substream)
++#ifdef HARMONY_DEBUG
++ printk(KERN_DEBUG PFX "capture_pointer is 0x%lx-0x%lx = %d bytes\n",
++ rcuradd, h->cbuf.addr, caught);
++#endif
++
++ if (rcuradd > h->cbuf.addr + h->cbuf.size) {
++ return 0;
++ }
++
++ return bytes_to_frames(rt, caught);
++}
++
++static int
++snd_harmony_playback_open(snd_pcm_substream_t *ss)
+ {
+- snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
+- snd_pcm_runtime_t *runtime = substream->runtime;
++ harmony_t *h = snd_pcm_substream_chip(ss);
++ snd_pcm_runtime_t *rt = ss->runtime;
+ int err;
+
+- harmony->playback_substream = substream;
+- runtime->hw = snd_card_harmony_playback;
+- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraint_rates);
++ h->psubs = ss;
++ rt->hw = snd_harmony_playback;
++ snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE,
++ &hw_constraint_rates);
+
+- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
++ err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
++ if (err < 0)
+ return err;
+
+ return 0;
+ }
+
+-static int snd_card_harmony_capture_open(snd_pcm_substream_t * substream)
++static int
++snd_harmony_capture_open(snd_pcm_substream_t *ss)
+ {
+- snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
+- snd_pcm_runtime_t *runtime = substream->runtime;
+- int err;
+-
+- harmony->capture_substream = substream;
+- runtime->hw = snd_card_harmony_capture;
+- snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraint_rates);
+- if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+- return err;
+- return 0;
++ harmony_t *h = snd_pcm_substream_chip(ss);
++ snd_pcm_runtime_t *rt = ss->runtime;
++ int err;
+
++ h->csubs = ss;
++ rt->hw = snd_harmony_capture;
++ snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE,
++ &hw_constraint_rates);
++
++ err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
++ if (err < 0)
++ return err;
++
++ return 0;
+ }
+
+-static int snd_card_harmony_playback_close(snd_pcm_substream_t * substream)
++static int
++snd_harmony_playback_close(snd_pcm_substream_t *ss)
+ {
+- snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
+-
+- harmony->playback_substream = NULL;
+- harmony->ply_size = 0;
+- harmony->ply_buf = 0;
+- harmony->ply_buffer = 0;
+- harmony->ply_count = 0;
+- harmony->ply_stopped = 1;
+- harmony->format_initialized = 0;
+-
++ harmony_t *h = snd_pcm_substream_chip(ss);
++ h->psubs = NULL;
+ return 0;
+ }
+
+-static int snd_card_harmony_capture_close(snd_pcm_substream_t * substream)
++static int
++snd_harmony_capture_close(snd_pcm_substream_t *ss)
+ {
+- snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
+-
+- harmony->capture_substream = NULL;
+- harmony->cap_size = 0;
+- harmony->cap_buf = 0;
+- harmony->cap_buffer = 0;
+- harmony->cap_count = 0;
+- harmony->cap_stopped = 1;
+- harmony->format_initialized = 0;
+-
+- return 0;
++ harmony_t *h = snd_pcm_substream_chip(ss);
++ h->csubs = NULL;
++ return 0;
+ }
+
+-static int snd_card_harmony_hw_params(snd_pcm_substream_t *substream,
+- snd_pcm_hw_params_t * hw_params)
++static int
++snd_harmony_hw_params(snd_pcm_substream_t *ss,
++ snd_pcm_hw_params_t *hw)
+ {
+ int err;
+- snd_card_harmony_t *harmony = snd_pcm_substream_chip(substream);
++ harmony_t *h = snd_pcm_substream_chip(ss);
++
++ err = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw));
++ if (err > 0 && h->dma.type == SNDRV_DMA_TYPE_CONTINUOUS)
++ ss->runtime->dma_addr = __pa(ss->runtime->dma_area);
+
+- err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+- if (err > 0 && harmony->dma_dev.type == SNDRV_DMA_TYPE_CONTINUOUS)
+- substream->runtime->dma_addr = __pa(substream->runtime->dma_area);
+- DPRINTK(KERN_INFO PFX "HW Params returned %d, dma_addr %lx\n", err,
+- (unsigned long)substream->runtime->dma_addr);
+ return err;
+ }
+
+-static int snd_card_harmony_hw_free(snd_pcm_substream_t *substream)
++static int
++snd_harmony_hw_free(snd_pcm_substream_t *ss)
+ {
+- snd_pcm_lib_free_pages(substream);
+- return 0;
++ return snd_pcm_lib_free_pages(ss);
+ }
+
+-static snd_pcm_ops_t snd_card_harmony_playback_ops = {
+- .open = snd_card_harmony_playback_open,
+- .close = snd_card_harmony_playback_close,
+- .ioctl = snd_card_harmony_playback_ioctl,
+- .hw_params = snd_card_harmony_hw_params,
+- .hw_free = snd_card_harmony_hw_free,
+- .prepare = snd_card_harmony_playback_prepare,
+- .trigger = snd_card_harmony_playback_trigger,
+- .pointer = snd_card_harmony_playback_pointer,
++static snd_pcm_ops_t snd_harmony_playback_ops = {
++ .open = snd_harmony_playback_open,
++ .close = snd_harmony_playback_close,
++ .ioctl = snd_pcm_lib_ioctl,
++ .hw_params = snd_harmony_hw_params,
++ .hw_free = snd_harmony_hw_free,
++ .prepare = snd_harmony_playback_prepare,
++ .trigger = snd_harmony_playback_trigger,
++ .pointer = snd_harmony_playback_pointer,
+ };
+
+-static snd_pcm_ops_t snd_card_harmony_capture_ops = {
+- .open = snd_card_harmony_capture_open,
+- .close = snd_card_harmony_capture_close,
+- .ioctl = snd_card_harmony_capture_ioctl,
+- .hw_params = snd_card_harmony_hw_params,
+- .hw_free = snd_card_harmony_hw_free,
+- .prepare = snd_card_harmony_capture_prepare,
+- .trigger = snd_card_harmony_capture_trigger,
+- .pointer = snd_card_harmony_capture_pointer,
++static snd_pcm_ops_t snd_harmony_capture_ops = {
++ .open = snd_harmony_capture_open,
++ .close = snd_harmony_capture_close,
++ .ioctl = snd_pcm_lib_ioctl,
++ .hw_params = snd_harmony_hw_params,
++ .hw_free = snd_harmony_hw_free,
++ .prepare = snd_harmony_capture_prepare,
++ .trigger = snd_harmony_capture_trigger,
++ .pointer = snd_harmony_capture_pointer,
+ };
+
+-static int snd_card_harmony_pcm_init(snd_card_harmony_t *harmony)
++static int
++snd_harmony_pcm_init(harmony_t *h)
+ {
+ snd_pcm_t *pcm;
+ int err;
+
+- /* Request that IRQ */
+- if (request_irq(harmony->irq, snd_card_harmony_interrupt, 0 ,"harmony", harmony)) {
+- printk(KERN_ERR PFX "Error requesting irq %d.\n", harmony->irq);
+- return -EFAULT;
+- }
+-
+- snd_harmony_disable_interrupts(harmony);
++ harmony_disable_interrupts(h);
+
+- if ((err = snd_pcm_new(harmony->card, "Harmony", 0, 1, 1, &pcm)) < 0)
++ err = snd_pcm_new(h->card, "harmony", 0, 1, 1, &pcm);
++ if (err < 0)
+ return err;
+
+- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_harmony_playback_ops);
+- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_harmony_capture_ops);
+-
+- pcm->private_data = harmony;
++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
++ &snd_harmony_playback_ops);
++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
++ &snd_harmony_capture_ops);
++
++ pcm->private_data = h;
+ pcm->info_flags = 0;
+- strcpy(pcm->name, "Harmony");
+- harmony->pcm = pcm;
++ strcpy(pcm->name, "harmony");
++ h->pcm = pcm;
++
++ h->psubs = NULL;
++ h->csubs = NULL;
+
+ /* initialize graveyard buffer */
+- harmony->dma_dev.type = SNDRV_DMA_TYPE_DEV;
+- harmony->dma_dev.dev = &harmony->pa_dev->dev;
+- err = snd_dma_alloc_pages(harmony->dma_dev.type,
+- harmony->dma_dev.dev,
+- HARMONY_BUF_SIZE*GRAVEYARD_BUFS,
+- &harmony->graveyard_dma);
+- if (err == -ENOMEM) {
+- /* use continuous buffers */
+- harmony->dma_dev.type = SNDRV_DMA_TYPE_CONTINUOUS;
+- harmony->dma_dev.dev = snd_dma_continuous_data(GFP_KERNEL);
+- err = snd_dma_alloc_pages(harmony->dma_dev.type,
+- harmony->dma_dev.dev,
+- HARMONY_BUF_SIZE*GRAVEYARD_BUFS,
+- &harmony->graveyard_dma);
+- }
++ h->dma.type = SNDRV_DMA_TYPE_DEV;
++ h->dma.dev = &h->dev->dev;
++ err = snd_dma_alloc_pages(h->dma.type,
++ h->dma.dev,
++ BUF_SIZE*GRAVEYARD_BUFS,
++ &h->gdma);
+ if (err < 0) {
+- printk(KERN_ERR PFX "can't allocate graveyard buffer\n");
++ printk(KERN_ERR PFX "cannot allocate graveyard buffer!\n");
+ return err;
+ }
+- harmony->graveyard_count = 0;
+
+ /* initialize silence buffers */
+- err = snd_dma_alloc_pages(harmony->dma_dev.type,
+- harmony->dma_dev.dev,
+- HARMONY_BUF_SIZE*SILENCE_BUFS,
+- &harmony->silence_dma);
++ err = snd_dma_alloc_pages(h->dma.type,
++ h->dma.dev,
++ BUF_SIZE*SILENCE_BUFS,
++ &h->sdma);
+ if (err < 0) {
+- printk(KERN_ERR PFX "can't allocate silence buffer\n");
++ printk(KERN_ERR PFX "cannot allocate silence buffer!\n");
+ return err;
+ }
+- harmony->silence_count = 0;
+-
+- if (harmony->dma_dev.type == SNDRV_DMA_TYPE_CONTINUOUS) {
+- harmony->graveyard_dma.addr = __pa(harmony->graveyard_dma.area);
+- harmony->silence_dma.addr = __pa(harmony->silence_dma.area);
+- }
+-
+- harmony->ply_stopped = harmony->cap_stopped = 1;
+-
+- harmony->playback_substream = NULL;
+- harmony->capture_substream = NULL;
+- harmony->graveyard_count = 0;
+
+- err = snd_pcm_lib_preallocate_pages_for_all(pcm, harmony->dma_dev.type,
+- harmony->dma_dev.dev,
+- MAX_BUFFER_SIZE, MAX_BUFFER_SIZE);
++ /* pre-allocate space for DMA */
++ err = snd_pcm_lib_preallocate_pages_for_all(pcm, h->dma.type,
++ h->dma.dev,
++ MAX_BUF_SIZE,
++ MAX_BUF_SIZE);
+ if (err < 0) {
+- printk(KERN_ERR PFX "buffer allocation error %d\n", err);
+- // return err;
++ printk(KERN_ERR PFX "buffer allocation error: %d\n", err);
++ return err;
+ }
+
+ return 0;
+ }
+
+-/*
+- * mixer routines
+- */
+-
+-static void snd_harmony_set_new_gain(snd_card_harmony_t *harmony)
++static void
++snd_harmony_set_new_gain(harmony_t *h)
+ {
+- DPRINTK(KERN_INFO PFX "Setting new gain %x at %lx\n", harmony->current_gain, harmony->hpa+REG_GAINCTL);
+- /* Wait until we're out of control mode */
+- snd_harmony_wait_cntl(harmony);
+-
+- gsc_writel(harmony->current_gain, harmony->hpa+REG_GAINCTL);
++ harmony_wait_for_control(h);
++ harmony_write(h, HARMONY_GAINCTL, h->st.gain);
+ }
+
+-#define HARMONY_VOLUME(xname, left_shift, right_shift, mask, invert) \
+-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+- .info = snd_harmony_mixercontrol_info, \
+- .get = snd_harmony_volume_get, .put = snd_harmony_volume_put, \
+- .private_value = ((left_shift) | ((right_shift) << 8) | ((mask) << 16) | ((invert) << 24)) }
+-
+-static int snd_harmony_mixercontrol_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+-{
+- int mask = (kcontrol->private_value >> 16) & 0xff;
+- int left_shift = (kcontrol->private_value) & 0xff;
+- int right_shift = (kcontrol->private_value >> 8) & 0xff;
++static int
++snd_harmony_mixercontrol_info(snd_kcontrol_t *kc,
++ snd_ctl_elem_info_t *uinfo)
++{
++ int mask = (kc->private_value >> 16) & 0xff;
++ int left_shift = (kc->private_value) & 0xff;
++ int right_shift = (kc->private_value >> 8) & 0xff;
+
+- uinfo->type = (mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER);
+- uinfo->count = (left_shift == right_shift) ? 1 : 2;
++ uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN :
++ SNDRV_CTL_ELEM_TYPE_INTEGER;
++ uinfo->count = left_shift == right_shift ? 1 : 2;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = mask;
++
+ return 0;
+ }
+-
+-static int snd_harmony_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+-{
+- snd_card_harmony_t *harmony = snd_kcontrol_chip(kcontrol);
+- int shift_left = (kcontrol->private_value) & 0xff;
+- int shift_right = (kcontrol->private_value >> 8) & 0xff;
+- int mask = (kcontrol->private_value >> 16) & 0xff;
+- int invert = (kcontrol->private_value >> 24) & 0xff;
+- unsigned long flags;
++
++static int
++snd_harmony_volume_get(snd_kcontrol_t *kc,
++ snd_ctl_elem_value_t *ucontrol)
++{
++ harmony_t *h = snd_kcontrol_chip(kc);
++ int shift_left = (kc->private_value) & 0xff;
++ int shift_right = (kc->private_value >> 8) & 0xff;
++ int mask = (kc->private_value >> 16) & 0xff;
++ int invert = (kc->private_value >> 24) & 0xff;
+ int left, right;
++ unsigned long flags;
+
+- spin_lock_irqsave(&harmony->mixer_lock, flags);
+- left = (harmony->current_gain >> shift_left) & mask;
+- right = (harmony->current_gain >> shift_right) & mask;
++ spin_lock_irqsave(&h->mixer_lock, flags);
++
++ left = (h->st.gain >> shift_left) & mask;
++ right = (h->st.gain >> shift_right) & mask;
+
+ if (invert) {
+ left = mask - left;
+@@ -910,21 +716,24 @@
+ }
+ ucontrol->value.integer.value[0] = left;
+ ucontrol->value.integer.value[1] = right;
+- spin_unlock_irqrestore(&harmony->mixer_lock, flags);
++
++ spin_unlock_irqrestore(&h->mixer_lock, flags);
+
+ return 0;
+ }
+
+-static int snd_harmony_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+-{
+- snd_card_harmony_t *harmony = snd_kcontrol_chip(kcontrol);
+- int shift_left = (kcontrol->private_value) & 0xff;
+- int shift_right = (kcontrol->private_value >> 8) & 0xff;
+- int mask = (kcontrol->private_value >> 16) & 0xff;
+- int invert = (kcontrol->private_value >> 24) & 0xff;
+- unsigned long flags;
++static int
++snd_harmony_volume_put(snd_kcontrol_t *kc,
++ snd_ctl_elem_value_t *ucontrol)
++{
++ harmony_t *h = snd_kcontrol_chip(kc);
++ int shift_left = (kc->private_value) & 0xff;
++ int shift_right = (kc->private_value >> 8) & 0xff;
++ int mask = (kc->private_value >> 16) & 0xff;
++ int invert = (kc->private_value >> 24) & 0xff;
+ int left, right;
+- int old_gain = harmony->current_gain;
++ int old_gain = h->st.gain;
++ unsigned long flags;
+
+ left = ucontrol->value.integer.value[0] & mask;
+ right = ucontrol->value.integer.value[1] & mask;
+@@ -933,213 +742,249 @@
+ right = mask - right;
+ }
+
+- spin_lock_irqsave(&harmony->mixer_lock, flags);
+- harmony->current_gain = harmony->current_gain & ~( (mask << shift_right) | (mask << shift_left));
+- harmony->current_gain = harmony->current_gain | ((left << shift_left) | (right << shift_right) );
+- snd_harmony_set_new_gain(harmony);
+- spin_unlock_irqrestore(&harmony->mixer_lock, flags);
++ spin_lock_irqsave(&h->mixer_lock, flags);
++
++ h->st.gain &= ~( (mask << shift_right) | (mask << shift_left) );
++ h->st.gain |= ( (left << shift_left) | (right << shift_right) );
++ snd_harmony_set_new_gain(h);
++
++ spin_unlock_irqrestore(&h->mixer_lock, flags);
+
+- return (old_gain - harmony->current_gain);
++ return (old_gain - h->st.gain);
+ }
+
+-#define HARMONY_CONTROLS (sizeof(snd_harmony_controls)/sizeof(snd_kcontrol_new_t))
++#define HARMONY_CONTROLS (sizeof(snd_harmony_controls)/ \
++ sizeof(snd_kcontrol_new_t))
++
++#define HARMONY_VOLUME(xname, left_shift, right_shift, mask, invert) \
++{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
++ .info = snd_harmony_mixercontrol_info, \
++ .get = snd_harmony_volume_get, .put = snd_harmony_volume_put, \
++ .private_value = ((left_shift) | ((right_shift) << 8) | \
++ ((mask) << 16) | ((invert) << 24)) }
+
+ static snd_kcontrol_new_t snd_harmony_controls[] = {
+-HARMONY_VOLUME("PCM Capture Volume", 12, 16, 0x0f, 0),
+-HARMONY_VOLUME("Master Volume", 20, 20, 0x0f, 1),
+-HARMONY_VOLUME("PCM Playback Volume", 6, 0, 0x3f, 1),
++ HARMONY_VOLUME("Playback Volume", HARMONY_GAIN_LO_SHIFT,
++ HARMONY_GAIN_RO_SHIFT, HARMONY_GAIN_OUT, 1),
++ HARMONY_VOLUME("Capture Volume", HARMONY_GAIN_LI_SHIFT,
++ HARMONY_GAIN_RI_SHIFT, HARMONY_GAIN_IN, 0),
+ };
+
+-static void __init snd_harmony_reset_codec(snd_card_harmony_t *harmony)
+-{
+- snd_harmony_wait_cntl(harmony);
+- gsc_writel(1, harmony->hpa+REG_RESET);
+- mdelay(50); /* wait 50 ms */
+- gsc_writel(0, harmony->hpa+REG_RESET);
+-}
+-
+-/*
+- * Mute all the output and reset Harmony.
+- */
+-
+-static void __init snd_harmony_mixer_reset(snd_card_harmony_t *harmony)
++static void __init
++snd_harmony_mixer_reset(harmony_t *h)
+ {
+- harmony->current_gain = HARMONY_GAIN_TOTAL_SILENCE;
+- snd_harmony_set_new_gain(harmony);
+- snd_harmony_reset_codec(harmony);
+- harmony->current_gain = HARMONY_GAIN_DEFAULT;
+- snd_harmony_set_new_gain(harmony);
++ harmony_mute(h);
++ harmony_reset(h);
++ h->st.gain = HARMONY_GAIN_DEFAULT;
++ harmony_unmute(h);
+ }
+
+-
+-static int __init snd_card_harmony_mixer_init(snd_card_harmony_t *harmony)
++static int __init
++snd_harmony_mixer_init(harmony_t *h)
+ {
+- snd_card_t *card = harmony->card;
++ snd_card_t *card = h->card;
+ int idx, err;
+
+- snd_assert(harmony != NULL, return -EINVAL);
++ snd_assert(h != NULL, return -EINVAL);
+ strcpy(card->mixername, "Harmony Gain control interface");
+
+ for (idx = 0; idx < HARMONY_CONTROLS; idx++) {
+- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_harmony_controls[idx], harmony))) < 0)
++ err = snd_ctl_add(card,
++ snd_ctl_new1(&snd_harmony_controls[idx], h));
++ if (err < 0)
+ return err;
+ }
+
+- snd_harmony_mixer_reset(harmony);
++ snd_harmony_mixer_reset(h);
+
+ return 0;
+ }
+
+-static int snd_card_harmony_create(snd_card_t *card, struct parisc_device *pa_dev, snd_card_harmony_t *harmony)
++static int
++snd_harmony_free(harmony_t *h)
+ {
+- u32 cntl;
+-
+- harmony->card = card;
+-
+- harmony->pa_dev = pa_dev;
++ if (h->gdma.addr)
++ snd_dma_free_pages(&h->gdma);
++ if (h->sdma.addr)
++ snd_dma_free_pages(&h->sdma);
+
+- /* Set the HPA of harmony */
+- harmony->hpa = pa_dev->hpa;
+-
+- harmony->irq = pa_dev->irq;
+- if (!harmony->irq) {
+- printk(KERN_ERR PFX "no irq found\n");
+- return -ENODEV;
+- }
++ if (h->irq >= 0)
++ free_irq(h->irq, h);
+
+- /* Grab the ID and revision from the device */
+- harmony->id = (gsc_readl(harmony->hpa+REG_ID)&0x00ff0000) >> 16;
+- if ((harmony->id | 1) != 0x15) {
+- printk(KERN_WARNING PFX "wrong harmony id 0x%02x\n", harmony->id);
+- return -EBUSY;
+- }
+- cntl = gsc_readl(harmony->hpa+REG_CNTL);
+- harmony->rev = (cntl>>20) & 0xff;
++ if (h->iobase)
++ iounmap(h->iobase);
+
+- printk(KERN_INFO "Lasi Harmony Audio driver h/w id %i, rev. %i at 0x%lx, IRQ %i\n", harmony->id, harmony->rev, pa_dev->hpa, harmony->irq);
+-
+- /* Make sure the control bit isn't set, although I don't think it
+- ever is. */
+- if (cntl & HARMONY_CNTL_C) {
+- printk(KERN_WARNING PFX "CNTL busy\n");
+- harmony->hpa = 0;
+- return -EBUSY;
++ parisc_set_drvdata(h->dev, NULL);
++
++ kfree(h);
++ return 0;
++}
++
++static int
++snd_harmony_dev_free(snd_device_t *dev)
++{
++ harmony_t *h = dev->device_data;
++ return snd_harmony_free(h);
++}
++
++static int __devinit
++snd_harmony_create(snd_card_t *card,
++ struct parisc_device *padev,
++ harmony_t **rchip)
++{
++ int err;
++ harmony_t *h;
++ static snd_device_ops_t ops = {
++ .dev_free = snd_harmony_dev_free,
++ };
++
++ *rchip = NULL;
++
++ h = kmalloc(sizeof(*h), GFP_KERNEL);
++ if (h == NULL)
++ return -ENOMEM;
++
++ memset(&h->st, 0, sizeof(h->st));
++ memset(&h->stats, 0, sizeof(h->stats));
++ memset(&h->pbuf, 0, sizeof(h->pbuf));
++ memset(&h->cbuf, 0, sizeof(h->cbuf));
++
++ h->hpa = padev->hpa;
++ h->card = card;
++ h->dev = padev;
++ h->irq = padev->irq;
++ h->iobase = ioremap_nocache(padev->hpa, HARMONY_SIZE);
++ if (h->iobase == NULL) {
++ printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n",
++ padev->hpa);
++ err = -EBUSY;
++ goto free_and_ret;
+ }
+-
++
++ err = request_irq(h->irq, snd_harmony_interrupt, 0,
++ "harmony", h);
++ if (err) {
++ printk(KERN_ERR PFX "could not obtain interrupt %d",
++ h->irq);
++ goto free_and_ret;
++ }
++
++ spin_lock_init(&h->mixer_lock);
++ spin_lock_init(&h->lock);
++
++ if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
++ h, &ops)) < 0) {
++ goto free_and_ret;
++ }
++
++ *rchip = h;
++
+ return 0;
++
++free_and_ret:
++ snd_harmony_free(h);
++ return err;
+ }
+-
+-static int __init snd_card_harmony_probe(struct parisc_device *pa_dev)
++
++static int __devinit
++snd_harmony_probe(struct parisc_device *padev)
+ {
++ int err;
+ static int dev;
+- snd_card_harmony_t *chip;
+ snd_card_t *card;
+- int err;
+-
+- if (dev >= SNDRV_CARDS)
++ harmony_t *h;
++ static int index = SNDRV_DEFAULT_IDX1;
++ static char *id = SNDRV_DEFAULT_STR1;
++
++ h = parisc_get_drvdata(padev);
++ if (h != NULL) {
+ return -ENODEV;
+- if (!enable[dev]) {
+- dev++;
+- return -ENOENT;
+ }
+-
+- snd_harmony_cards[dev] = snd_card_new(index[dev], id[dev], THIS_MODULE,
+- sizeof(snd_card_harmony_t));
+- card = snd_harmony_cards[dev];
+-
++
++ card = snd_card_new(index, id, THIS_MODULE, 0);
+ if (card == NULL)
+ return -ENOMEM;
+- chip = (struct snd_card_harmony *)card->private_data;
+- spin_lock_init(&chip->control_lock);
+- spin_lock_init(&chip->mixer_lock);
+-
+- if ((err = snd_card_harmony_create(card, pa_dev, chip)) < 0) {
+- printk(KERN_ERR PFX "Creation failed\n");
+- snd_card_free(card);
+- return err;
++
++ err = snd_harmony_create(card, padev, &h);
++ if (err < 0) {
++ goto free_and_ret;
+ }
+- if ((err = snd_card_harmony_pcm_init(chip)) < 0) {
+- printk(KERN_ERR PFX "PCM Init failed\n");
+- snd_card_free(card);
+- return err;
++
++ err = snd_harmony_pcm_init(h);
++ if (err < 0) {
++ goto free_and_ret;
+ }
+- if ((err = snd_card_harmony_mixer_init(chip)) < 0) {
+- printk(KERN_ERR PFX "Mixer init failed\n");
+- snd_card_free(card);
+- return err;
++
++ err = snd_harmony_mixer_init(h);
++ if (err < 0) {
++ goto free_and_ret;
+ }
+-
+- snd_harmony_proc_init(chip);
+-
+- strcpy(card->driver, "Harmony");
+- strcpy(card->shortname, "ALSA driver for LASI Harmony");
+- sprintf(card->longname, "%s at h/w, id %i, rev. %i hpa 0x%lx, IRQ %i\n",card->shortname, chip->id, chip->rev, pa_dev->hpa, chip->irq);
+
+- if ((err = snd_card_register(card)) < 0) {
+- snd_card_free(card);
+- return err;
++ strcpy(card->driver, "harmony");
++ strcpy(card->shortname, "Harmony");
++ sprintf(card->longname, "%s at 0x%lx, irq %i",
++ card->shortname, h->hpa, h->irq);
++
++ err = snd_card_register(card);
++ if (err < 0) {
++ goto free_and_ret;
+ }
+
+- printk(KERN_DEBUG PFX "Successfully registered harmony pcm backend & mixer %d\n", dev);
+ dev++;
+- return 0;
+-}
++ parisc_set_drvdata(padev, h);
+
+-static struct parisc_device_id snd_card_harmony_devicetbl[] = {
+- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, /* Bushmaster/Flounder */
+- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007B }, /* 712/715 Audio */
+- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007E }, /* Pace Audio */
+- { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007F }, /* Outfield / Coral II */
+- { 0, }
+-};
++ return 0;
+
+-MODULE_DEVICE_TABLE(parisc, snd_card_harmony_devicetbl);
++free_and_ret:
++ snd_card_free(card);
++ return err;
++}
+
+-/*
+- * bloc device parisc. c'est une structure qui definit un device
+- * que l'on trouve sur parisc.
+- * On y trouve les differents numeros HVERSION correspondant au device
+- * en question (ce qui permet a l'inventory de l'identifier) et la fonction
+- * d'initialisation du chose
+- */
++static int __devexit
++snd_harmony_remove(struct parisc_device *padev)
++{
++ harmony_t *h = parisc_get_drvdata(padev);
++ snd_card_free(h->card);
++ return 0;
++}
+
+-static struct parisc_driver snd_card_harmony_driver = {
+- .name = "Lasi ALSA Harmony",
+- .id_table = snd_card_harmony_devicetbl,
+- .probe = snd_card_harmony_probe,
++static struct parisc_driver snd_harmony_driver = {
++ .name = "harmony",
++ .id_table = snd_harmony_devtable,
++ .probe = snd_harmony_probe,
++ .remove = snd_harmony_remove,
+ };
+
+-static int __init alsa_card_harmony_init(void)
++static int __init
++alsa_harmony_init(void)
+ {
+ int err;
+-
+- if ((err = register_parisc_driver(&snd_card_harmony_driver)) < 0) {
+- printk(KERN_ERR "Harmony soundcard not found or device busy\n");
++
++ err = register_parisc_driver(&snd_harmony_driver);
++ if (err < 0) {
++ printk(KERN_ERR PFX "device not found\n");
+ return err;
+ }
+
+ return 0;
+ }
+
+-static void __exit alsa_card_harmony_exit(void)
++static void __exit
++alsa_harmony_fini(void)
+ {
+- int idx;
+- snd_card_harmony_t *harmony;
++ int err;
++
++ err = unregister_parisc_driver(&snd_harmony_driver);
++ if (err < 0) {
++ printk(KERN_ERR PFX "failed to unregister\n");
++ }
+
+- for (idx = 0; idx < SNDRV_CARDS; idx++)
+- {
+- if (snd_harmony_cards[idx] != NULL)
+- {
+- DPRINTK(KERN_INFO PFX "Freeing card %d\n", idx);
+- harmony = snd_harmony_cards[idx]->private_data;
+- free_irq(harmony->irq, harmony);
+- printk(KERN_INFO PFX "Card unloaded %d, irq=%d\n", idx, harmony->irq);
+- snd_card_free(snd_harmony_cards[idx]);
+- }
+- }
+- if (unregister_parisc_driver(&snd_card_harmony_driver) < 0)
+- printk(KERN_ERR PFX "Failed to unregister Harmony driver\n");
++ return;
+ }
+
+-module_init(alsa_card_harmony_init)
+-module_exit(alsa_card_harmony_exit)
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Kyle McMartin <kyle at parisc-linux.org>");
++MODULE_DESCRIPTION("Harmony sound driver");
++
++module_init(alsa_harmony_init);
++module_exit(alsa_harmony_fini);
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/sound/parisc/harmony.h CVS2_6_11_PA2/sound/parisc/harmony.h
+--- LINUS_2_6_11/sound/parisc/harmony.h 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/sound/parisc/harmony.h 2005-02-28 20:03:11.000000000 -0700
+@@ -0,0 +1,151 @@
++/* Hewlett-Packard Harmony audio driver
++ * Copyright (C) 2004, Kyle McMartin <kyle at parisc-linux.org>
++ */
++
++#ifndef __HARMONY_H__
++#define __HARMONY_H__
++
++struct harmony_buffer {
++ unsigned long addr;
++ int buf;
++ int count;
++ int size;
++ int coherent;
++};
++
++typedef struct snd_card_harmony {
++ int irq;
++
++ unsigned long hpa; /* hard physical address */
++ void __iomem *iobase; /* remapped io address */
++
++ struct parisc_device *dev;
++
++ struct {
++ u32 gain;
++ u32 rate;
++ u32 format;
++ u32 stereo;
++ int playing;
++ int capturing;
++ } st;
++
++ struct snd_dma_device dma; /* playback/capture */
++ struct harmony_buffer pbuf;
++ struct harmony_buffer cbuf;
++
++ struct snd_dma_buffer gdma; /* graveyard */
++ struct snd_dma_buffer sdma; /* silence */
++
++ struct {
++ unsigned long play_intr;
++ unsigned long rec_intr;
++ unsigned long graveyard_intr;
++ unsigned long silence_intr;
++ } stats;
++
++ snd_pcm_t *pcm;
++ snd_card_t *card;
++ snd_pcm_substream_t *psubs;
++ snd_pcm_substream_t *csubs;
++ snd_info_entry_t *proc;
++
++ spinlock_t lock;
++ spinlock_t mixer_lock;
++} harmony_t;
++
++#define MAX_PCM_DEVICES 1
++#define MAX_PCM_SUBSTREAMS 4
++#define MAX_MIDI_DEVICES 0
++
++#define HARMONY_SIZE 64
++
++#define BUF_SIZE PAGE_SIZE
++#define MAX_BUFS 10
++#define MAX_BUF_SIZE (MAX_BUFS * BUF_SIZE)
++
++#define PLAYBACK_BUFS MAX_BUFS
++#define RECORD_BUFS MAX_BUFS
++#define GRAVEYARD_BUFS 1
++#define GRAVEYARD_BUFSZ (GRAVEYARD_BUFS*BUF_SIZE)
++#define SILENCE_BUFS 1
++#define SILENCE_BUFSZ (SILENCE_BUFS*BUF_SIZE)
++
++#define HARMONY_ID 0x000
++#define HARMONY_RESET 0x004
++#define HARMONY_CNTL 0x008
++#define HARMONY_GAINCTL 0x00c
++#define HARMONY_PNXTADD 0x010
++#define HARMONY_PCURADD 0x014
++#define HARMONY_RNXTADD 0x018
++#define HARMONY_RCURADD 0x01c
++#define HARMONY_DSTATUS 0x020
++#define HARMONY_OV 0x024
++#define HARMONY_PIO 0x028
++#define HARMONY_DIAG 0x03c
++
++#define HARMONY_CNTL_C 0x80000000
++#define HARMONY_CNTL_ST 0x00000020
++#define HARMONY_CNTL_44100 0x00000015 /* HARMONY_SR_44KHZ */
++#define HARMONY_CNTL_8000 0x00000008 /* HARMONY_SR_8KHZ */
++
++#define HARMONY_DSTATUS_ID 0x00000000 /* interrupts off */
++#define HARMONY_DSTATUS_PN 0x00000200 /* playback fill */
++#define HARMONY_DSTATUS_RN 0x00000002 /* record fill */
++#define HARMONY_DSTATUS_IE 0x80000000 /* interrupts on */
++
++#define HARMONY_DF_16BIT_LINEAR 0x00000000
++#define HARMONY_DF_8BIT_ULAW 0x00000001
++#define HARMONY_DF_8BIT_ALAW 0x00000002
++
++#define HARMONY_SS_MONO 0x00000000
++#define HARMONY_SS_STEREO 0x00000001
++
++#define HARMONY_GAIN_SILENCE 0x00F00FFF
++#define HARMONY_GAIN_DEFAULT 0x0FF00000
++
++#define HARMONY_GAIN_HE_SHIFT 27
++#define HARMONY_GAIN_HE_MASK (1 << HARMONY_GAIN_HE_SHIFT)
++#define HARMONY_GAIN_LE_SHIFT 26
++#define HARMONY_GAIN_LE_MASK (1 << HARMONY_GAIN_LE_SHIFT)
++#define HARMONY_GAIN_SE_SHIFT 25
++#define HARMONY_GAIN_SE_MASK (1 << HARMONY_GAIN_SE_SHIFT)
++#define HARMONY_GAIN_IS_SHIFT 24
++#define HARMONY_GAIN_IS_MASK (1 << HARMONY_GAIN_IS_SHIFT)
++
++#define HARMONY_GAIN_MA 0x0f
++#define HARMONY_GAIN_MA_SHIFT 20
++#define HARMONY_GAIN_MA_MASK (HARMONY_GAIN_MA << HARMONY_GAIN_MA_SHIFT)
++
++#define HARMONY_GAIN_IN 0x0f
++#define HARMONY_GAIN_LI_SHIFT 16
++#define HARMONY_GAIN_LI_MASK (HARMONY_GAIN_IN << HARMONY_GAIN_LI_SHIFT)
++#define HARMONY_GAIN_RI_SHIFT 12
++#define HARMONY_GAIN_RI_MASK (HARMONY_GAIN_IN << HARMONY_GAIN_RI_SHIFT)
++
++#define HARMONY_GAIN_OUT 0x3f
++#define HARMONY_GAIN_LO_SHIFT 6
++#define HARMONY_GAIN_LO_MASK (HARMONY_GAIN_OUT << HARMONY_GAIN_LO_SHIFT)
++#define HARMONY_GAIN_RO_SHIFT 0
++#define HARMONY_GAIN_RO_MASK (HARMONY_GAIN_OUT << HARMONY_GAIN_RO_SHIFT)
++
++#define HARMONY_MAX_OUT (HARMONY_GAIN_RO_MASK >> HARMONY_GAIN_RO_SHIFT)
++#define HARMONY_MAX_IN (HARMONY_GAIN_RI_MASK >> HARMONY_GAIN_RI_SHIFT)
++#define HARMONY_MAX_MON (HARMONY_GAIN_MA_MASK >> HARMONY_GAIN_MA_SHIFT)
++
++#define HARMONY_SR_8KHZ 0x08
++#define HARMONY_SR_16KHZ 0x09
++#define HARMONY_SR_27KHZ 0x0A
++#define HARMONY_SR_32KHZ 0x0B
++#define HARMONY_SR_48KHZ 0x0E
++#define HARMONY_SR_9KHZ 0x0F
++#define HARMONY_SR_5KHZ 0x10
++#define HARMONY_SR_11KHZ 0x11
++#define HARMONY_SR_18KHZ 0x12
++#define HARMONY_SR_22KHZ 0x13
++#define HARMONY_SR_37KHZ 0x14
++#define HARMONY_SR_44KHZ 0x15
++#define HARMONY_SR_33KHZ 0x16
++#define HARMONY_SR_6KHZ 0x17
++
++#endif /* __HARMONY_H__ */
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/sound/pci/Kconfig CVS2_6_11_PA2/sound/pci/Kconfig
+--- LINUS_2_6_11/sound/pci/Kconfig 2005-03-02 04:19:29.000000000 -0700
++++ CVS2_6_11_PA2/sound/pci/Kconfig 2005-03-01 09:56:38.000000000 -0700
+@@ -21,6 +21,26 @@
+ To compile this driver as a module, choose M here: the module
+ will be called snd-ali5451.
+
++config SND_AD1889
++ tristate "Analog Devices AD1889"
++ depends on SND && PARISC && EXPERIMENTAL
++ select SND_AC97_CODEC
++ help
++ Say Y here to include support for the integrated AC97 sound
++ device on the Hewlett-Packard BCJ-xxx0 class workstations.
++ FTSO Analog Devices.
++
++ 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"
++ depends on SND_AD1889
++ select SND_OPL3_LIB
++ help
++ Say Y here to include support for the OPL3-compatible interface
++ provided on an Analog Devices AD1889.
++
+ config SND_ATIIXP
+ tristate "ATI IXP AC97 Controller"
+ depends on SND
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/sound/pci/Makefile CVS2_6_11_PA2/sound/pci/Makefile
+--- LINUS_2_6_11/sound/pci/Makefile 2005-03-02 04:19:29.000000000 -0700
++++ CVS2_6_11_PA2/sound/pci/Makefile 2005-02-19 17:56:46.000000000 -0700
+@@ -4,6 +4,7 @@
+ #
+
+ snd-als4000-objs := als4000.o
++snd-ad1889-objs := ad1889.o
+ snd-atiixp-objs := atiixp.o
+ snd-atiixp-modem-objs := atiixp_modem.o
+ snd-azt3328-objs := azt3328.o
+@@ -26,6 +27,7 @@
+
+ # Toplevel Module Dependency
+ obj-$(CONFIG_SND_ALS4000) += snd-als4000.o
++obj-$(CONFIG_SND_AD1889) += snd-ad1889.o
+ obj-$(CONFIG_SND_ATIIXP) += snd-atiixp.o
+ obj-$(CONFIG_SND_ATIIXP_MODEM) += snd-atiixp-modem.o
+ obj-$(CONFIG_SND_AZT3328) += snd-azt3328.o
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/sound/pci/ad1889.c CVS2_6_11_PA2/sound/pci/ad1889.c
+--- LINUS_2_6_11/sound/pci/ad1889.c 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/sound/pci/ad1889.c 2005-03-01 13:51:08.000000000 -0700
+@@ -0,0 +1,780 @@
++/* Analog Devices 1889 audio driver
++ *
++ * This is a driver for the AD1889 PCI audio chipset found
++ * on the HP PA-RISC [BCJ]-xxx0 workstations.
++ *
++ * Copyright (C) 2004-2005, Kyle McMartin <kyle at parisc-linux.org>
++ * Based on the OSS AD1889 driver by Randolph Chung <tausq at debian.org>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License, version 2, as
++ * published by the Free Software Foundation.
++ *
++ * 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.
++ *
++ * TODO:
++ * - SYN/RES support.
++ * - Scatter-Gather DMA.
++ *
++ */
++
++#include <linux/init.h>
++#include <linux/pci.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <linux/compiler.h>
++#include <linux/delay.h>
++
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#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"
++
++MODULE_AUTHOR("Kyle McMartin <kyle at parisc-linux.org>");
++MODULE_DESCRIPTION("Analog Devices AD1889 sound driver");
++MODULE_LICENSE("GPL");
++
++static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
++module_param_array(index, int, NULL, 0444);
++MODULE_PARM_DESC(index, "Index value for the AD1889 soundcard.");
++
++static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
++module_param_array(id, charp, NULL, 0444);
++MODULE_PARM_DESC(id, "ID string for the AD1889 soundcard.");
++
++static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
++module_param_array(enable, bool, NULL, 0444);
++MODULE_PARM_DESC(enable, "Enable AD1889 soundcard.");
++
++#define DEVNAME "ad1889"
++#define PFX DEVNAME ": "
++
++/* keep track of each hw register */
++struct ad1889_register_state {
++ u16 reg;
++ u32 addr;
++ u16 rate;
++ unsigned long pos;
++ unsigned long buf;
++ unsigned long size;
++ unsigned long count;
++};
++
++struct snd_ad1889 {
++ snd_card_t *card;
++ struct pci_dev *pci;
++
++ int irq;
++ unsigned long bar;
++ void __iomem *iobase;
++
++#ifdef CONFIG_SND_AD1889_OPL3
++ unsigned long opl3_bar;
++ void __iomem *opl3_iobase;
++#endif
++
++ ac97_t *ac97;
++ ac97_bus_t *ac97_bus;
++ snd_pcm_t *pcm;
++ snd_info_entry_t *proc;
++
++#ifdef CONFIG_SND_AD1889_OPL3
++ opl3_t *opl3;
++ snd_hwdep_t *opl3hwdep;
++#endif
++
++ struct snd_dma_device dma;
++ snd_pcm_substream_t *psubs; /* playback substream */
++
++ /* playback register state */
++ struct ad1889_register_state play;
++
++ struct {
++ unsigned long wav_intr;
++ unsigned long adc_intr;
++ unsigned long syn_intr;
++ unsigned long res_intr;
++ } stats;
++
++ spinlock_t lock;
++};
++
++static u16
++ad1889_readw(struct snd_ad1889 *dev, unsigned reg)
++{
++ return readw(dev->iobase + reg);
++}
++
++static void
++ad1889_writew(struct snd_ad1889 *dev, unsigned reg, u16 val)
++{
++ writew(val, dev->iobase + reg);
++}
++
++static u32
++ad1889_readl(struct snd_ad1889 *dev, unsigned reg)
++{
++ return readl(dev->iobase + reg);
++}
++
++static void
++ad1889_writel(struct snd_ad1889 *dev, unsigned reg, u32 val)
++{
++ writel(val, dev->iobase + reg);
++}
++
++static void
++ad1889_power_on(struct snd_ad1889 *dev)
++{
++ u16 st;
++ st = ad1889_readw(dev, AD_DS_CCS) | AD_DS_CCS_PDALL;
++ ad1889_writew(dev, AD_DS_CCS, st);
++ ad1889_readw(dev, AD_DS_CCS);
++}
++
++static void
++ad1889_power_off(struct snd_ad1889 *dev)
++{
++ u16 st;
++ st = ad1889_readw(dev, AD_DS_CCS) & ~AD_DS_CCS_PDALL;
++ ad1889_writew(dev, AD_DS_CCS, st);
++ ad1889_readw(dev, AD_DS_CCS);
++}
++
++static void
++ad1889_clock_on(struct snd_ad1889 *dev)
++{
++ u16 st;
++ st = ad1889_readw(dev, AD_DS_CCS) | AD_DS_CCS_CLKEN;
++ ad1889_writew(dev, AD_DS_CCS, st);
++ ad1889_readw(dev, AD_DS_CCS);
++}
++
++static void
++ad1889_clock_off(struct snd_ad1889 *dev)
++{
++ unsigned short st;
++ st = ad1889_readw(dev, AD_DS_CCS) & ~AD_DS_CCS_CLKEN;
++ ad1889_writew(dev, AD_DS_CCS, st);
++ ad1889_readw(dev, AD_DS_CCS);
++}
++
++static void
++ad1889_mute(struct snd_ad1889 *dev)
++{
++ u16 st;
++ st = ad1889_readw(dev, AD_DS_WADA) &
++ ~(AD_DS_WADA_RWAM | AD_DS_WADA_LWAM);
++ ad1889_writew(dev, AD_DS_WADA, st);
++ ad1889_readw(dev, AD_DS_WADA);
++}
++
++static void
++ad1889_unmute(struct snd_ad1889 *dev)
++{
++ u16 st;
++ st = ad1889_readw(dev, AD_DS_WADA) | AD_DS_WADA_RWAM | AD_DS_WADA_LWAM;
++ ad1889_writew(dev, AD_DS_WADA, st);
++ ad1889_readw(dev, AD_DS_WADA);
++}
++
++static u16
++snd_ad1889_ac97_read(ac97_t *ac97,
++ unsigned short reg)
++{
++ u16 val;
++ struct snd_ad1889 *dev = ac97->private_data;
++ return ad1889_readw(dev, AD_AC97_BASE + reg);
++}
++
++static void
++snd_ad1889_ac97_write(ac97_t *ac97,
++ unsigned short reg,
++ unsigned short val)
++{
++ struct snd_ad1889 *dev = ac97->private_data;
++ ad1889_writew(dev, AD_AC97_BASE + reg, val);
++}
++
++static int
++snd_ad1889_hw_params(snd_pcm_substream_t *substream,
++ snd_pcm_hw_params_t *hw_params)
++{
++ return snd_pcm_lib_malloc_pages(substream,
++ params_buffer_bytes(hw_params));
++}
++
++static int
++snd_ad1889_hw_free(snd_pcm_substream_t *substream)
++{
++ return snd_pcm_lib_free_pages(substream);
++}
++
++static snd_pcm_hardware_t snd_ad1889_playback =
++{
++ .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
++ SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
++ SNDRV_PCM_INFO_BLOCK_TRANSFER),
++ .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_BE),
++ .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
++ .rate_min = 5500,
++ .rate_max = 48000,
++ .channels_min = 1,
++ .channels_max = 2,
++ .buffer_bytes_max = DMA_SIZE,
++ .period_bytes_min = BUF_SIZE,
++ .period_bytes_max = BUF_SIZE,
++ .periods_min = 1,
++ .periods_max = MAX_BUFS,
++ .fifo_size = 0,
++};
++
++static unsigned int rates[] = {
++ 5500, 8000, 9600, 11025,
++ 16000, 19200, 22050, 32000,
++ 38400, 44100, 48000
++};
++
++static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
++ .count = ARRAY_SIZE(rates),
++ .list = rates,
++ .mask = 0,
++};
++
++static unsigned int channels[] = {
++ 2
++};
++
++static snd_pcm_hw_constraint_list_t hw_constraints_channels = {
++ .count = ARRAY_SIZE(channels),
++ .list = channels,
++ .mask = 0,
++};
++
++static int
++snd_ad1889_playback_open(snd_pcm_substream_t *ss)
++{
++ struct snd_ad1889 *dev = snd_pcm_substream_chip(ss);
++ snd_pcm_runtime_t *rt = ss->runtime;
++ int err;
++
++ dev->psubs = ss;
++ rt->hw = snd_ad1889_playback;
++ snd_pcm_hw_constraint_list(rt, 0, SNDRV_PCM_HW_PARAM_RATE,
++ &hw_constraints_rates);
++
++ err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
++ if (err < 0)
++ return err;
++
++ return 0;
++}
++
++static int
++snd_ad1889_playback_close(snd_pcm_substream_t *substream)
++{
++ struct snd_ad1889 *dev = snd_pcm_substream_chip(substream);
++ dev->psubs = NULL;
++ return 0;
++}
++
++static int
++snd_ad1889_playback_prepare(snd_pcm_substream_t *ss)
++{
++ struct snd_ad1889 *dev = snd_pcm_substream_chip(ss);
++ snd_pcm_runtime_t *rt = ss->runtime;
++
++ spin_lock_irq(&dev->lock);
++
++ dev->play.size = snd_pcm_lib_buffer_bytes(ss);
++ dev->play.count = snd_pcm_lib_period_bytes(ss);
++
++ if (snd_pcm_format_width(rt->format) == 16)
++ dev->play.reg |= AD_DS_WSMC_WA16;
++ if (rt->channels > 1)
++ dev->play.reg |= AD_DS_WSMC_WAST;
++
++ dev->play.buf = 0;
++ dev->play.rate = rt->rate;
++ dev->play.addr = rt->dma_addr;
++
++ ad1889_writew(dev, AD_DS_WSMC, dev->play.reg);
++ ad1889_writew(dev, AD_DS_WAS, dev->play.rate);
++
++ ad1889_writel(dev, AD_DMA_WAVBA, dev->play.addr);
++ ad1889_writel(dev, AD_DMA_WAVCA, dev->play.addr);
++
++ ad1889_writel(dev, AD_DMA_WAVBC, dev->play.count);
++ ad1889_writel(dev, AD_DMA_WAVCC, dev->play.count);
++
++ spin_unlock_irq(&dev->lock);
++
++ return 0;
++}
++
++static int
++snd_ad1889_playback_trigger(snd_pcm_substream_t *ss,
++ int cmd)
++{
++ u16 wsmc;
++ unsigned long flags;
++ struct snd_ad1889 *dev = snd_pcm_substream_chip(ss);
++
++ spin_lock_irqsave(&dev->lock, flags);
++ wsmc = ad1889_readw(dev, AD_DS_WSMC);
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ wsmc |= AD_DS_WSMC_WAEN;
++ ad1889_unmute(dev);
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ wsmc &= ~AD_DS_WSMC_WAEN;
++ ad1889_mute(dev);
++ break;
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ break;
++ default:
++ spin_unlock_irqrestore(&dev->lock, flags);
++ snd_BUG();
++ return -EINVAL;
++ }
++ ad1889_writew(dev, AD_DS_WSMC, wsmc);
++ spin_unlock_irqrestore(&dev->lock, flags);
++
++ return 0;
++}
++
++static snd_pcm_uframes_t
++snd_ad1889_playback_pointer(snd_pcm_substream_t *ss)
++{
++ size_t ptr = 0;
++ struct snd_ad1889 *dev = snd_pcm_substream_chip(ss);
++
++ if (!(dev->play.reg & AD_DS_WSMC_WAEN))
++ return 0;
++
++ spin_lock(&dev->lock);
++
++ /* XXX: */
++
++ spin_unlock(&dev->lock);
++
++ return bytes_to_frames(ss->runtime, ptr);
++}
++
++static snd_pcm_ops_t snd_ad1889_playback_ops = {
++ .open = snd_ad1889_playback_open,
++ .close = snd_ad1889_playback_close,
++ .ioctl = snd_pcm_lib_ioctl,
++ .hw_params = snd_ad1889_hw_params,
++ .hw_free = snd_ad1889_hw_free,
++ .prepare = snd_ad1889_playback_prepare,
++ .trigger = snd_ad1889_playback_trigger,
++ .pointer = snd_ad1889_playback_pointer,
++};
++
++static void
++snd_ad1889_pcm_free(snd_pcm_t *pcm)
++{
++ struct snd_ad1889 *dev = pcm->private_data;
++ dev->pcm = NULL;
++ snd_pcm_lib_preallocate_free_for_all(pcm);
++}
++
++static int __devinit
++snd_ad1889_pcm_init(struct snd_ad1889 *dev, int device, snd_pcm_t **rpcm)
++{
++ int err;
++ snd_pcm_t *pcm;
++
++ if (rpcm)
++ *rpcm = NULL;
++
++ err = snd_pcm_new(dev->card, "ad1889", device, 1, 1, &pcm);
++ if (err < 0)
++ return err;
++
++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
++ &snd_ad1889_playback_ops);
++
++ pcm->private_data = dev;
++ pcm->private_free = snd_ad1889_pcm_free;
++ pcm->info_flags = 0;
++ strcpy(pcm->name, "ad1889");
++ dev->pcm = pcm;
++ dev->psubs = NULL;
++
++ dev->dma.dev = dev;
++ dev->dma.type = SNDRV_DMA_TYPE_DEV;
++
++ err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
++ snd_dma_pci_data(dev->pci),
++ DMA_SIZE, DMA_SIZE);
++ if (err < 0) {
++ printk(KERN_ERR PFX "buffer allocation error: %d\n", err);
++ return err;
++ }
++
++ if (rpcm)
++ *rpcm = pcm;
++
++ return 0;
++}
++
++static int
++snd_ad1889_ac97_init(struct snd_ad1889 *dev)
++{
++ int err;
++ ac97_bus_t *bus;
++ ac97_template_t ac97;
++ static ac97_bus_ops_t ops = {
++ .write = snd_ad1889_ac97_write,
++ .read = snd_ad1889_ac97_read,
++ };
++
++ err = snd_ac97_bus(dev->card, 0, &ops, NULL, &bus);
++ if (err < 0) {
++ return err;
++ }
++
++ memset(&ac97, 0, sizeof(ac97));
++ ac97.private_data = dev;
++ dev->ac97_bus = bus;
++
++ return snd_ac97_mixer(bus, &ac97, &dev->ac97);
++}
++
++static irqreturn_t
++snd_ad1889_interrupt(int irq,
++ void *dev_id,
++ struct pt_regs *regs)
++{
++ unsigned long st;
++ unsigned long next;
++ struct snd_ad1889 *dev = dev_id;
++
++ spin_lock(&dev->lock);
++
++ st = ad1889_readl(dev, AD_DMA_DISR);
++ st &= AD_INTR_MASK;
++
++ if (!st)
++ return IRQ_NONE;
++
++ ad1889_writel(dev, AD_DMA_DISR, st);
++
++ if (dev->pcm && (st & AD_DMA_DISR_WAVI) && dev->psubs) {
++ dev->stats.wav_intr++;
++
++ dev->play.buf++;
++ dev->play.pos += dev->play.count;
++ dev->play.pos %= dev->play.size;
++ next = dev->play.pos + dev->play.count;
++ next %= dev->play.size;
++
++ ad1889_writel(dev, AD_DMA_WAVCA, dev->play.addr + next);
++
++ spin_unlock(&dev->lock);
++ snd_pcm_period_elapsed(dev->psubs);
++ spin_lock(&dev->lock);
++ }
++
++ spin_unlock(&dev->lock);
++
++ return IRQ_HANDLED;
++}
++
++static int
++snd_ad1889_free(struct snd_ad1889 *dev)
++{
++ if (dev->irq >= 0)
++ free_irq(dev->irq, (void*)dev);
++ if (dev->iobase)
++ iounmap(dev->iobase);
++ pci_release_regions(dev->pci);
++ kfree(dev);
++ return 0;
++}
++
++static int
++snd_ad1889_dev_free(snd_device_t *device)
++{
++ struct snd_ad1889 *dev = device->device_data;
++ return snd_ad1889_free(dev);
++}
++
++static int
++snd_ad1889_init(struct snd_ad1889 *dev)
++{
++ u32 dma_wav;
++
++ spin_lock(&dev->lock);
++
++ dma_wav = ad1889_readl(dev, AD_DMA_WAV);
++ dma_wav &= ~0xff; /* mask off lower byte */
++ /* interrupt on count, loop enabled */
++ dma_wav |= (AD_DMA_WAV_IM_CNT | AD_DMA_WAV_LOOP);
++ ad1889_writel(dev, AD_DMA_WAV, dma_wav);
++ ad1889_readl(dev, AD_DMA_WAV);
++ ad1889_unmute(dev);
++
++ spin_unlock(&dev->lock);
++
++ return 0;
++}
++
++static int __devinit
++snd_ad1889_create(snd_card_t *card,
++ struct pci_dev *pci,
++ struct snd_ad1889 **rchip)
++{
++ int err;
++
++ struct snd_ad1889 *dev;
++ static snd_device_ops_t ops = {
++ .dev_free = snd_ad1889_dev_free,
++ };
++
++ *rchip = NULL;
++
++ if ((err = pci_enable_device(pci)) < 0)
++ return err;
++ if (pci_set_dma_mask(pci, 0xffffffff) < 0 ||
++ pci_set_consistent_dma_mask(pci, 0xffffffff) < 0) {
++ printk(KERN_ERR PFX "error setting 32-bit DMA mask.\n");
++ return -ENXIO;
++ }
++
++ dev = kmalloc(sizeof(*dev), GFP_KERNEL);
++ if (dev == NULL)
++ return -ENOMEM;
++
++ dev->card = card;
++ card->private_data = dev;
++ dev->pci = pci;
++ dev->irq = -1;
++
++ /* zero out stats */
++ memset(&dev->stats, 0, sizeof(dev->stats));
++
++ if ((err = pci_request_regions(pci, "ad1889")) < 0) {
++ kfree(dev);
++ return err;
++ }
++
++ dev->bar = pci_resource_start(pci, 0);
++ dev->iobase = ioremap_nocache(dev->bar, pci_resource_len(pci, 0));
++ if (dev->iobase == NULL) {
++ printk(KERN_ERR PFX "unable to reserve region.\n");
++ err = -EBUSY;
++ goto free_and_ret;
++ }
++
++#ifdef CONFIG_SND_AD1889_OPL3
++ dev->opl3_bar = pci_resource_start(pci, 1);
++ dev->opl3_iobase = ioremap_nocache(dev->opl3_bar, pci_resource_len(pci, 1));
++ if (dev->opl3_iobase == NULL) {
++ printk(KERN_ERR PFX "unable to reserve region.\n");
++ err = -EBUSY;
++ goto free_and_ret;
++ }
++#endif
++
++ if (request_irq(pci->irq, snd_ad1889_interrupt,
++ SA_INTERRUPT|SA_SHIRQ, "ad1889", (void*)dev)) {
++ printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
++ err = -EBUSY;
++ goto free_and_ret;
++ }
++
++ dev->irq = pci->irq;
++
++ snd_ad1889_init(dev);
++
++ if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
++ dev, &ops)) < 0) {
++ goto free_and_ret;
++ }
++
++ *rchip = dev;
++
++ return 0;
++
++free_and_ret:
++ snd_ad1889_free(dev);
++
++ return err;
++}
++
++/* FIXME */
++#define WAIT_100MS() do { int __i; for (__i = 0; __i < 100; __i++) udelay(1000); } while(0)
++
++static int
++snd_ad1889_aclink_reset(struct snd_ad1889 *dev)
++{
++ u16 stat;
++ int retry = 200;
++
++ ad1889_writew(dev, AD_DS_CCS, AD_DS_CCS_CLKEN); /* turn on clock */
++ ad1889_readw(dev, AD_DS_CCS);
++
++ WAIT_100MS();
++
++ stat = ad1889_readw(dev, AD_AC97_ACIC);
++ stat |= AD_AC97_ACIC_ACRD; /* Reset Disable */
++ ad1889_writew(dev, AD_AC97_ACIC, stat);
++ (void) ad1889_readw(dev, AD_AC97_ACIC); /* flush posted write */
++
++ udelay(10);
++
++ stat = ad1889_readw(dev, AD_AC97_ACIC);
++ stat |= AD_AC97_ACIC_ACIE; /* Interface Enable */
++ ad1889_writew(dev, AD_AC97_ACIC, stat);
++
++ do {
++ if (ad1889_readw(dev, AD_AC97_ACIC) & AD_AC97_ACIC_ACRDY) /* Ready */
++ break;
++ WAIT_100MS();
++ retry--;
++ } while (retry > 0);
++
++ if (!retry) {
++ printk(KERN_ERR "snd_ad1889_aclink_reset: codec is not ready [0x%x]\n",
++ ad1889_readw(dev, AD_AC97_ACIC));
++ return -EBUSY;
++ }
++
++ /* TODO reset AC97 codec */
++ /* TODO set wave/adc pci ctrl status */
++
++ stat = ad1889_readw(dev, AD_AC97_ACIC);
++ stat |= AD_AC97_ACIC_ASOE; /* Audio Stream Output Enable */
++ ad1889_writew(dev, AD_AC97_ACIC, stat);
++ (void) ad1889_readw(dev, AD_AC97_ACIC); /* flush posted write */
++ return 0;
++}
++
++static int __devinit
++snd_ad1889_probe(struct pci_dev *pci,
++ const struct pci_device_id *pci_id)
++{
++ int err;
++ static int devno;
++
++ snd_card_t *card;
++ struct snd_ad1889 *dev;
++
++ if (devno >= SNDRV_CARDS)
++ return -ENODEV;
++ if (!enable[devno]) {
++ devno++;
++ return -ENOENT;
++ }
++
++ card = snd_card_new(index[devno], id[devno], THIS_MODULE, 0);
++ if (card == NULL)
++ return -ENOMEM;
++
++ if ((err = snd_ad1889_create(card, pci, &dev)) < 0) {
++ snd_card_free(card);
++ return err;
++ }
++
++ strcpy(card->driver, "ad1889");
++ strcpy(card->shortname, "Analog Devices AD1889");
++ sprintf(card->longname, "%s at 0x%lx irq %i",
++ card->shortname, dev->bar, dev->irq);
++
++ if ((err = snd_ad1889_aclink_reset(dev)) < 0) {
++ snd_card_free(card);
++ return err;
++ }
++
++ if ((err = snd_ad1889_ac97_init(dev)) < 0) {
++ snd_card_free(card);
++ return err;
++ }
++
++#ifdef CONFIG_SND_AD1889_OPL3
++ if ((err = snd_opl3_create_mapped(card, dev->opl3_iobase, dev->opl3_iobase + 2,
++ OPL3_HW_OPL3, &dev->opl3))) {
++ printk(KERN_ERR PFX "failed to create opl3\n");
++ snd_card_free(card);
++ return err;
++ }
++
++ if ((err = snd_opl3_hwdep_new(dev->opl3, 0, 0, &dev->opl3hwdep))) {
++ printk(KERN_ERR PFX "failed to create opl3hwdep\n");
++ snd_card_free(card);
++ return err;
++ }
++#endif
++
++ if ((err = snd_ad1889_pcm_init(dev, 0, NULL)) < 0) {
++ snd_card_free(card);
++ return err;
++ }
++
++ if ((err = snd_card_register(card)) < 0) {
++ snd_card_free(card);
++ return err;
++ }
++
++ pci_set_drvdata(pci, card);
++
++ devno++;
++ return 0;
++}
++
++static void __devexit
++snd_ad1889_remove(struct pci_dev *pci)
++{
++ snd_card_free(pci_get_drvdata(pci));
++ pci_set_drvdata(pci, NULL);
++}
++
++static struct pci_device_id snd_ad1889_ids[] = {
++ { PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) },
++ { },
++};
++MODULE_DEVICE_TABLE(pci, snd_ad1889_ids);
++
++static struct pci_driver ad1889_pci = {
++ .name = "ad1889",
++ .id_table = snd_ad1889_ids,
++ .probe = snd_ad1889_probe,
++ .remove = __devexit_p(snd_ad1889_remove),
++};
++
++static int __init
++alsa_ad1889_init(void)
++{
++ return pci_module_init(&ad1889_pci);
++}
++
++static void __exit
++alsa_ad1889_fini(void)
++{
++ pci_unregister_driver(&ad1889_pci);
++}
++
++module_init(alsa_ad1889_init);
++module_exit(alsa_ad1889_fini);
++
+diff -urN --exclude-from=/var/www/download/linux-2.6/autobuild/build-tools/dontdiff LINUS_2_6_11/sound/pci/ad1889.h CVS2_6_11_PA2/sound/pci/ad1889.h
+--- LINUS_2_6_11/sound/pci/ad1889.h 1969-12-31 17:00:00.000000000 -0700
++++ CVS2_6_11_PA2/sound/pci/ad1889.h 2005-03-01 09:16:54.000000000 -0700
+@@ -0,0 +1,156 @@
++/* Analog Devices 1889 audio driver
++ * Copyright (C) 2004, Kyle McMartin <kyle at parisc-linux.org>
++ */
++
++#ifndef __AD1889_H__
++#define __AD1889_H__
++
++#define AD_DS_WSMC 0x00 /* wave/synthesis channel mixer control */
++#define AD_DS_WSMC_SYEN 0x0004 /* synthesis channel enable */
++#define AD_DS_WSMC_SYRQ 0x0030 /* synth. fifo request point */
++#define AD_DS_WSMC_WA16 0x0100 /* wave channel 16bit select */
++#define AD_DS_WSMC_WAST 0x0200 /* wave channel stereo select */
++#define AD_DS_WSMC_WAEN 0x0400 /* wave channel enable */
++#define AD_DS_WSMC_WARQ 0x3000 /* wave fifo request point */
++
++#define AD_DS_RAMC 0x02 /* resampler/ADC channel mixer control */
++#define AD_DS_RAMC_AD16 0x0001 /* ADC channel 16bit select */
++#define AD_DS_RAMC_ADST 0x0002 /* ADC channel stereo select */
++#define AD_DS_RAMC_ADEN 0x0004 /* ADC channel enable */
++#define AD_DS_RAMC_ACRQ 0x0030 /* ADC fifo request point */
++#define AD_DS_RAMC_REEN 0x0400 /* resampler channel enable */
++#define AD_DS_RAMC_RERQ 0x3000 /* res. fifo request point */
++
++#define AD_DS_WADA 0x04 /* wave channel mix attenuation */
++#define AD_DS_WADA_RWAM 0x0080 /* right wave mute */
++#define AD_DS_WADA_RWAA 0x001f /* right wave attenuation */
++#define AD_DS_WADA_LWAM 0x8000 /* left wave mute */
++#define AD_DS_WADA_LWAA 0x3e00 /* left wave attenuation */
++
++#define AD_DS_SYDA 0x06 /* synthesis channel mix attenuation */
++#define AD_DS_SYDA_RSYM 0x0080 /* right synthesis mute */
++#define AD_DS_SYDA_RSYA 0x001f /* right synthesis attenuation */
++#define AD_DS_SYDA_LSYM 0x8000 /* left synthesis mute */
++#define AD_DS_SYDA_LSYA 0x3e00 /* left synthesis attenuation */
++
++#define AD_DS_WAS 0x08 /* wave channel sample rate */
++#define AD_DS_WAS_WAS 0xffff /* sample rate mask */
++
++#define AD_DS_RES 0x0a /* resampler channel sample rate */
++#define AD_DS_RES_RES 0xffff /* sample rate mask */
++
++#define AD_DS_CCS 0x0c /* chip control/status */
++#define AD_DS_CCS_ADO 0x0001 /* ADC channel overflow */
++#define AD_DS_CCS_REO 0x0002 /* resampler channel overflow */
++#define AD_DS_CCS_SYU 0x0004 /* synthesis channel underflow */
++#define AD_DS_CCS_WAU 0x0008 /* wave channel underflow */
++/* bits 4 -> 7, 9, 11 -> 14 reserved */
++#define AD_DS_CCS_XTD 0x0100 /* xtd delay control (4096 clock cycles) */
++#define AD_DS_CCS_PDALL 0x0400 /* power */
++#define AD_DS_CCS_CLKEN 0x8000 /* clock */
++
++#define AD_DMA_WAV 0xb8 /* wave dma control */
++#define AD_DMA_WAV_SGDE 0x0001 /* SGD mode enable */
++#define AD_DMA_WAV_LOOP 0x0002 /* loop enable */
++#define AD_DMA_WAV_IM 0x000c /* interrupt mode mask */
++#define AD_DMA_WAV_IM_DIS (~0x0c) /* interrupt disabled */
++#define AD_DMA_WAV_IM_CNT 0x04 /* interrupt on count */
++#define AD_DMA_WAV_IM_SGD 0x08 /* interrupt on SGD flag */
++#define AD_DMA_WAV_IM_EOL 0x0c /* interrupt on End of Linked List */
++#define AD_DMA_WAV_SGDS 0x0030 /* SGD status */
++#define AD_DMA_WAV_SFLG 0x0040 /* SGD flag */
++#define AD_DMA_WAV_EOL 0x0080 /* SGD end of list */
++/* bits 8 -> 15 reserved */
++
++#define AD_DMA_WAVIC 0x98 /* wave dma interrupt current byte count */
++#define AD_DMA_WAVIC_ICC 0xffffff /* current byte count mask */
++/* bits 24 -> 31 reserved */
++
++#define AD_DMA_WAVIB 0x9c /* wave dma interrupt base byte count */
++#define AD_DMA_WAVIB_IBC 0xffffff /* base byte count mask */
++/* bits 24 -> 31 reserved */
++
++#define AD_DMA_WAVBA 0x70 /* wave base address */
++#define AD_DMA_WAVCA 0x74 /* wave current address */
++#define AD_DMA_WAVBC 0x78 /* wave base count */
++#define AD_DMA_WAVCC 0x7c /* wave current count */
++
++#define AD_DMA_DISR 0xc0 /* dma interrupt status */
++#define AD_DMA_DISR_RESI 0x000001 /* resampler channel interrupt */
++#define AD_DMA_DISR_ADCI 0x000002 /* ADC channel interrupt */
++#define AD_DMA_DISR_SYNI 0x000004 /* synthesis channel interrupt */
++#define AD_DMA_DISR_WAVI 0x000008 /* wave channel interrupt */
++/* bits 4, 5 reserved */
++#define AD_DMA_DISR_SEPS 0x000040 /* serial eeprom status */
++/* bits 7 -> 13 reserved */
++#define AD_DMA_DISR_PMAI 0x004000 /* pci master abort interrupt */
++#define AD_DMA_DISR_PTAI 0x008000 /* pci target abort interrupt */
++#define AD_DMA_DISR_PTAE 0x010000 /* pci target abort interrupt enable */
++#define AD_DMA_DISR_PMAE 0x020000 /* pci master abort interrupt enable */
++/* bits 19 -> 31 reserved */
++
++/* interrupt mask */
++#define AD_INTR_MASK (AD_DMA_DISR_RESI|AD_DMA_DISR_ADCI| \
++ AD_DMA_DISR_WAVI|AD_DMA_DISR_SYNI)
++
++#define AD_DMA_CHSS 0xc4 /* dma channel stop status */
++#define AD_DMA_CHSS_RESS 0x000001 /* resampler channel stopped */
++#define AD_DMA_CHSS_ADCS 0x000002 /* ADC channel stopped */
++#define AD_DMA_CHSS_SYNS 0x000004 /* synthesis channel stopped */
++#define AD_DMA_CHSS_WAVS 0x000008 /* wave channel stopped */
++
++#define AD_AC97_BASE 0x100 /* ac97 base register */
++#define AD_AC97_ACIC 0x180 /* ac97 codec interface control */
++#define AD_AC97_ACIC_ACIE 0x0001 /* analog codec interface enable */
++#define AD_AC97_ACIC_ACRD 0x0002 /* analog codec reset disable */
++#define AD_AC97_ACIC_ASOE 0x0004 /* audio stream output enable */
++#define AD_AC97_ACIC_VSRM 0x0008 /* variable sample rate mode */
++#define AD_AC97_ACIC_FSDH 0x0100 /* force SDATA_OUT high */
++#define AD_AC97_ACIC_FSYH 0x0200 /* force sync high */
++#define AD_AC97_ACIC_ACRDY 0x8000 /* analog codec ready status */
++/* bits 10 -> 14 reserved */
++
++#define AD_GPIO_IPC 0xc8 /* gpio port control */
++#define AD_GPIO_IPC_IPC1 0x0001 /* 1 */
++#define AD_GPIO_IPC_IPC2 0x0002 /* 2 */
++#define AD_GPIO_IPC_IPC3 0x0004 /* 3 */
++#define AD_GPIO_IPC_IPC4 0x0008 /* 4 */
++#define AD_GPIO_IPC_IPC5 0x0010 /* 5 */
++#define AD_GPIO_IPC_IPC6 0x0020 /* 6 */
++#define AD_GPIO_IPC_IPC7 0x0040 /* 7 */
++#define AD_GPIO_IPC_IPC8 0x0080 /* 8 */
++
++#define AD_GPIO_OP 0xca /* gpio output port status */
++#define AD_GPIO_OP_OP1 0x0001 /* 1 */
++#define AD_GPIO_OP_OP2 0x0002 /* 2 */
++#define AD_GPIO_OP_OP3 0x0004 /* 3 */
++#define AD_GPIO_OP_OP4 0x0008 /* 4 */
++#define AD_GPIO_OP_OP5 0x0010 /* 5 */
++#define AD_GPIO_OP_OP6 0x0020 /* 6 */
++#define AD_GPIO_OP_OP7 0x0040 /* 7 */
++#define AD_GPIO_OP_OP8 0x0080 /* 8 */
++
++#define AD_GPIO_IP 0xcc /* gpio input port status */
++#define AD_GPIO_IP_IP1 0x0001 /* 1 */
++#define AD_GPIO_IP_IP2 0x0002 /* 2 */
++#define AD_GPIO_IP_IP3 0x0004 /* 3 */
++#define AD_GPIO_IP_IP4 0x0008 /* 4 */
++#define AD_GPIO_IP_IP5 0x0010 /* 5 */
++#define AD_GPIO_IP_IP6 0x0020 /* 6 */
++#define AD_GPIO_IP_IP7 0x0040 /* 7 */
++#define AD_GPIO_IP_IP8 0x0080 /* 8 */
++
++#define AD_DS_MEMSIZE 512
++#define AD_OPL_MEMSIZE 16
++#define AD_MIDI_MEMSIZE 16
++
++#define AD_WAV_STATE 0
++#define AD_ADC_STATE 1
++#define AD_MAX_STATES 2
++
++#define BUF_SIZE 1024
++#define MAX_BUFS 128
++#define DMA_SIZE (MAX_BUFS*BUF_SIZE)
++#define NR_HW_CHAN 4
++
++#endif /* __AD1889_H__ */
Modified: branches/kernel-image-2.6.11/debian/rules
===================================================================
--- branches/kernel-image-2.6.11/debian/rules 2005-05-30 21:02:58 UTC (rev 3277)
+++ branches/kernel-image-2.6.11/debian/rules 2005-05-31 00:52:12 UTC (rev 3278)
@@ -13,6 +13,7 @@
major := $(basename $(version))
srcver := $(shell dpkg-parsechangelog | awk '/^Version:/ {print $$2}')
release := $(version)-$(ltver)
+uver := $(subst .,_,$(version))
#
# Construct depends and provides for the linux-tree
#
@@ -41,7 +42,7 @@
#
source_files = $(filter-out debian linux-source-$(version), $(shell echo *))
-export version abiname ltver kbuildver flavours major
+export version abiname ltver kbuildver flavours major uver
patch: debian/patch-stamp
debian/patch-stamp: debian/bin/apply
@@ -85,6 +86,7 @@
dh_fixperms -p$(spkg)
dh_installdeb -p$(spkg)
dh_gencontrol -p$(spkg)
+ dh_md5sums -p$(spkg)
dh_builddeb -p$(spkg)
touch debian/source-stamp
#
@@ -102,6 +104,7 @@
dh_fixperms -p$(tpkg)
dh_installdeb -p$(tpkg)
dh_gencontrol -p$(tpkg)
+ dh_md5sum -p$(tpkg)
dh_builddeb -p$(tpkg)
touch debian/tree-stamp
#
@@ -111,23 +114,41 @@
pbase := /usr/src/linux-patches/all/$(version)
pfull := debian/$(ppkg)$(pbase)
pdirs := $(pbase) $(pbase)/apply $(pbase)/debian $(pbase)/unpatch
+ptchs := $(notdir $(wildcard debian/patches-arch/*))
+kptch := debian/$(ppkg).kpatches.arch
+pcdir := debian/patches-arch
patch-debian: debian/patch-debian-stamp
debian/patch-debian-stamp: debian/bin/apply debian/bin/unpatch
dh_testdir
dh_testroot
dh_installdirs -p$(ppkg) $(pdirs)
- dh_install -p$(ppkg) debian/patches/* $(pbase)/debian
+ dh_install -p$(ppkg) debian/patches-debian/* $(pbase)/debian
+# Install the debian patches
sed 's/@version@/$(release)/g' debian/bin/apply > $(pfull)/apply/debian
sed 's/@upstream@/$(version)/g' debian/bin/unpatch > $(pfull)/unpatch/debian
chmod a+x $(pfull)/apply/debian $(pfull)/unpatch/debian
chmod -x $(pfull)/debian/*.patch
bzip2 -9 $(pfull)/debian/*.patch
+# Now the arch/subarch-specific patches
+ for i in $(ptchs); do \
+ rm -f $(kptch); \
+ arch=$${i%%.*}; \
+ echo "Patch-name: $${arch}" >> $(kptch); \
+ echo "Patch-id: $${arch}_$(uver)" >> $(kptch); \
+ echo "Path-strip-level: 1" >> $(kptch); \
+ echo >> $(kptch); \
+ echo "Patch-file: $(pcdir)/$${i}" >> $(kptch); \
+ echo "Architecture: $${arch}" >> $(kptch); \
+ echo "Kernel-version: $(version)" >> $(kptch); \
+ dh_installkpatches -p$(ppkg); \
+ done
dh_fixperms -p$(ppkg)
dh_installdocs -p$(ppkg)
dh_installchangelogs -p$(ppkg)
dh_compress -p$(ppkg)
dh_installdeb -p$(ppkg)
dh_gencontrol -p$(ppkg)
+ dh_md5sums -p$(ppkg)
dh_builddeb -p$(ppkg)
touch debian/patch-debian-stamp
@@ -155,7 +176,7 @@
rm -f version.Debian
rm -rf linux-source-$(version)
cd debian; \
- rm -f *-stamp-* *-stamp config.*; \
+ rm -f *-stamp-* *-stamp config.* *.kpatches.arch; \
rm -f header-install-* post-install-* bin/touch.orig; \
rm -rf kernel-source-* build-* install-*
dh_clean
Modified: branches/kernel-image-2.6.11/debian/templates/control.main.in
===================================================================
--- branches/kernel-image-2.6.11/debian/templates/control.main.in 2005-05-30 21:02:58 UTC (rev 3277)
+++ branches/kernel-image-2.6.11/debian/templates/control.main.in 2005-05-31 00:52:12 UTC (rev 3278)
@@ -14,24 +14,24 @@
which has been designed to ease the task of creating kernel image
packages.
-Package: linux-docs- at version@
+Package: linux-doc- at version@
Architecture: all
Section: doc
Priority: optional
-Provides: linux-docs- at major@
+Provides: linux-doc- at major@
Depends: coreutils | fileutils (>= 4.0)
Description: Linux kernel specific documentation for version @version@
This package provides the various README files in the @version@ kernel
Documentation/ subdirectory: these typically contain kernel-specific
installation notes for some drivers for example. See
- /usr/share/doc/linux-docs- at version@/Documentation/00-INDEX for a list of what
+ /usr/share/doc/linux-doc- at version@/Documentation/00-INDEX for a list of what
is contained in each file.
Package: linux-patch-debian- at version@
Architecture: all
Section: devel
Priority: optional
-Depends: bzip2
+Depends: bzip2, ${kpatch:Depends}
Suggests: linux-source- at version@
Description: Debian patches to version @version@ of the Linux kernel
This package includes the patches used to produce the prepackaged
More information about the Kernel-svn-changes
mailing list