diff --git a/debian/Makefile b/debian/Makefile index 86bc7914b..71d7aae3a 100644 --- a/debian/Makefile +++ b/debian/Makefile @@ -11,7 +11,6 @@ # SHELL := sh -e debver := $(version)-$(abiname) -uver := $(subst .,_,$(version)) debnum := -$(abiname) # # These variables control the behaviour of make-kpkg diff --git a/debian/bin/unpatch b/debian/bin/unpatch new file mode 100755 index 000000000..9f567f241 --- /dev/null +++ b/debian/bin/unpatch @@ -0,0 +1,8 @@ +#!/bin/sh +# $Id: unpatch,v 1.3 2003/06/30 12:49:09 herbert Exp $ + +set -e + +upstream=${override_upstream:-@upstream@} + +/usr/src/kernel-patches/all/$upstream/apply/debian $upstream diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..a787f474f --- /dev/null +++ b/debian/control @@ -0,0 +1,86 @@ +Source: linux-source-2.6.11 +Section: devel +Priority: optional +Maintainer: Debian Kernel Team +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. diff --git a/debian/patches-arch/apus.diff b/debian/patches-arch/apus.diff new file mode 100644 index 000000000..e69de29bb diff --git a/debian/patches-arch/hppa.diff b/debian/patches-arch/hppa.diff new file mode 100644 index 000000000..04adec178 --- /dev/null +++ b/debian/patches-arch/hppa.diff @@ -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@parisc-linux.org ++W: http://www.parisc-linux.org/~kyle/ad1889/ ++L: parisc-linux@lists.parisc-linux.org ++S: Maintained ++ + ADM1025 HARDWARE MONITOR DRIVER + P: Jean Delvare + M: khali@linux-fr.org +@@ -916,6 +923,13 @@ + W: http://hq.pm.waw.pl/hdlc/ + S: Maintained + ++HARMONY SOUND DRIVER ++P: Kyle McMartin ++M: kyle@parisc-linux.org ++W: http://www.parisc-linux.org/~kyle/harmony/ ++L: parisc-linux@lists.parisc-linux.org ++S: Maintained ++ + HAYES ESP SERIAL DRIVER + P: Andrew J. Robinson + M: arobinso@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 . + + 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 + #include + #include +-#include + #include + #include /* 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 + * Copyright (c) 2001,2002 Ryan Bradetich +- * Copyright (c) 2004 Thibaut VARENE ++ * Copyright (c) 2004-2005 Thibaut VARENE + * + * 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@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 + #include +-#include + #include + #include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include + #include + #include +-#include + #include + #include ++#include + +-#include +-#include +- +-#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 +@@ -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 +@@ -30,6 +47,8 @@ + #include + #include + ++#include ++ + #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 +@@ -46,7 +46,7 @@ + #include + + .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 + #include + +-#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 +- * Copyright (C) 2002-2004 Thibaut VARENE ++ * Copyright (C) 2002-2004 Thibaut VARENE + * + * 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 + #include + #include + #include +@@ -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 + #include + +-#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 + #include + +-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 + #include + #include ++#include + + #ifdef CONFIG_COMPAT + #include +@@ -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 + #include + #include + #include +@@ -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 + #include + +-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 + + /* 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 ++ * Copyright (C) 2004 Thibaut VARENE + * + * 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 + */ + +-#include + #include + #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 + #include + #include /* for node_online_map */ ++#include /* for release_pages and page_cache_release */ + + #include + #include +@@ -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 . + +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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PREFIX "HIL KEYB: " ++#define HIL_GENERIC_NAME "HIL keyboard" ++ ++MODULE_AUTHOR("Brian S. Julin "); ++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 ++ * Copyright (C) 1999 Matthew Wilcox ++ * Copyright (C) 1999-2003 Helge Deller ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++MODULE_AUTHOR("Philip Blundell, Matthew Wilcox, Helge Deller"); ++MODULE_DESCRIPTION("HIL keyboard driver (basic functionality)"); ++MODULE_LICENSE("GPL v2"); ++ ++ ++#if defined(CONFIG_PARISC) ++ ++ #include ++ #include ++ #include ++ 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 + * Copyright (c) 2002 Laurent Canet +- * Copyright (c) 2002 Thibaut Varene ++ * Copyright (c) 2002 Thibaut Varene + * Copyright (c) 2000 Xavier Debacker + * + * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++MODULE_AUTHOR("Brian S. Julin "); ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PREFIX "HIL PTR: " ++#define HIL_GENERIC_NAME "HIL pointer device" ++ ++MODULE_AUTHOR("Brian S. Julin "); ++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 + * Copyright (c) 2002 Laurent Canet +- * Copyright (c) 2002 Thibaut Varene ++ * Copyright (c) 2002 Thibaut Varene + * + * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c + * Copyright (c) 1999 Alex deVries +@@ -37,8 +37,8 @@ + #include + #include + +-MODULE_AUTHOR("Laurent Canet , Thibaut Varene , Helge Deller "); +-MODULE_DESCRIPTION("HP GSC PS/2 port driver"); ++MODULE_AUTHOR("Laurent Canet , Thibaut Varene , Helge Deller "); ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++MODULE_AUTHOR("Brian S. Julin "); ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Machine-specific abstraction */ ++ ++#if defined(__hppa__) ++# include ++# define sdc_readb(p) gsc_readb(p) ++# define sdc_writeb(v,p) gsc_writeb((v),(p)) ++#elif defined(__mc68000__) ++# include ++# 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 "); ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PREFIX "HP SDC MLC: " ++ ++static hil_mlc hp_sdc_mlc; ++ ++MODULE_AUTHOR("Brian S. Julin "); ++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 +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 + #include + #include ++#include + + #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 + #include + #include + #include +@@ -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 + #include + #include + #include +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 /* for iosapic_register() */ + #include /* 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 ++ * ++ * 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 ++#include ++#include /* for capable() */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#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 "); ++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 + + #include +-#include + #include + #include + #include +@@ -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; ihw_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 + #include + #include +-#include ++#include "parport_gsc.h" + + + MODULE_AUTHOR("Helge Deller "); +@@ -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 ++ * ++ * ++ * 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 ++ * Phil Blundell ++ * Tim Waugh ++ * Jose Renau ++ * David Campbell ++ * Andrea Arcangeli ++ */ ++ ++#ifndef __DRIVERS_PARPORT_PARPORT_GSC_H ++#define __DRIVERS_PARPORT_PARPORT_GSC_H ++ ++#include ++#include ++ ++#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@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; itryloop + 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; icmd_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 ++#include + #include +-#include +-#include +-#include +-#include ++#include + #include +-#include +-#include ++#include + #include + #include "scsi_priv.h" + #include +@@ -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 + +-#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 +- * +- * 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 +- * Stefan Esser +- * Copyright (C) 1994 Wolfgang Stanglmeier +- * +- * Other major contributions: +- * +- * NVRAM detection and reading. +- * Copyright (C) 1997 Richard Waltham +- * +- *----------------------------------------------------------------------------- +- * +- * 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 +- * Copyright (c) 2003-2004 Matthew Wilcox ++ * Copyright (c) 2003-2005 Matthew Wilcox + * + * This driver is derived from the Linux sym53c8xx driver. + * Copyright (C) 1998-2000 Gerard Roudier +@@ -47,7 +47,6 @@ + #include + #include + #include +-#include + + #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<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 + #include + #include ++#include + #include + +-#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 +- * Copyright (c) 2003-2004 Matthew Wilcox ++ * Copyright (c) 2003-2005 Matthew Wilcox + * + * 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<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) { + 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<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<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;itarget[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 +- * +- * 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 +- * Stefan Esser +- * Copyright (C) 1994 Wolfgang Stanglmeier +- * +- * Other major contributions: +- * +- * NVRAM detection and reading. +- * Copyright (C) 1997 Richard Waltham +- * +- *----------------------------------------------------------------------------- +- * +- * 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 /* for udelay */ + #include + #include ++#include + #include + + #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 ++ ++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 + #include ++#include + #include + #include + +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 + #include +-#include + #include + + typedef struct { +@@ -26,16 +24,6 @@ + + #include /* 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 +- + #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 +- + /* 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 +-#include +- +-#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 +- * Copyright (C) 2002 Thibaut Varene ++ * Copyright (C) 2002 Laurent Canet ++ * Copyright (C) 2002 Thibaut Varene + * + * + * 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 + +-#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 +- + /* + * 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 ++ + /* 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 + +-#ifdef CONFIG_COMPAT ++#ifndef CONFIG_COMPAT ++ ++/* Non-native task requiring compat... doesn't exist */ ++#define is_compat_task(x) 0 ++ ++#else + + #include + #include /* for HZ */ ++#include /* Conditional process compat */ + #include + + #include +@@ -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 ++#include ++ ++#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 ++#include ++ ++/* 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 ++ ++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 ++ ++/* 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 ++#include ++#include ++#include ++#include ++#include ++ ++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 ++#include ++#include ++#include ++#if defined(__hppa__) ++#include ++#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 ++#include + #include + #include + #include +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 + #include ++#include + #include + #include + #include +@@ -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 ++#include ++#include ++#include ++ ++#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 + #include + #include ++#include + #include + #include + #include +@@ -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 + * +- * this ALSA driver is based on OSS driver by: +- * Copyright 2000 (c) Linuxcare Canada, Alex deVries +- * Copyright 2000-2002 (c) Helge Deller +- * Copyright 2001 (c) Matthieu Delahaye ++ * 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 +-#include + #include +-#include + #include + #include + #include +-#include ++#include ++#include ++#include ++#include ++#include ++ ++#include + #include +-#include + #include ++#include + #include + #include + #include +-#include ++ + #include ++#include + #include + +-MODULE_AUTHOR("Laurent Canet "); +-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 \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 "); ++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 ++ */ ++ ++#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 ++ * Based on the OSS AD1889 driver by Randolph Chung ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_SND_AD1889_OPL3 ++#include ++#endif ++ ++#include ++ ++#include "ad1889.h" ++ ++MODULE_AUTHOR("Kyle McMartin "); ++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 ++ */ ++ ++#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__ */ diff --git a/debian/rules b/debian/rules index 354fe5dd1..0596b77a1 100755 --- a/debian/rules +++ b/debian/rules @@ -13,6 +13,7 @@ karch := $(shell dpkg-architecture -qDEB_HOST_ARCH) 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 @@ endif # 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 @@ debian/source-stamp: debian/patch-stamp 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 @@ debian/tree-stamp: 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 @@ ppkg := linux-patch-debian-$(version) 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 @@ clean: unpatch 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 diff --git a/debian/templates/control.main.in b/debian/templates/control.main.in index 9971d196b..0aa85d991 100644 --- a/debian/templates/control.main.in +++ b/debian/templates/control.main.in @@ -14,24 +14,24 @@ Description: Linux kernel source for version @version@ with Debian patches which has been designed to ease the task of creating kernel image packages. -Package: linux-docs-@version@ +Package: linux-doc-@version@ Architecture: all Section: doc Priority: optional -Provides: linux-docs-@major@ +Provides: linux-doc-@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-@version@/Documentation/00-INDEX for a list of what + /usr/share/doc/linux-doc-@version@/Documentation/00-INDEX for a list of what is contained in each file. Package: linux-patch-debian-@version@ Architecture: all Section: devel Priority: optional -Depends: bzip2 +Depends: bzip2, ${kpatch:Depends} Suggests: linux-source-@version@ Description: Debian patches to version @version@ of the Linux kernel This package includes the patches used to produce the prepackaged