r2305 - in trunk/kernel: . mips mips/kernel-latest-mips mips/kernel-latest-mips/debian mips/kernel-latest-mips/debian/control.in mips/kernel-patch-2.6.10-mips-2.6.10 mips/kernel-patch-2.6.10-mips-2.6.10/debian mips/kernel-patch-2.6.10-mips-2.6.10/debian/config mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mipsel mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4

Thiemo Seufer ths-guest at costa.debian.org
Fri Oct 19 11:06:12 UTC 2007


Author: ths-guest
Date: 2005-01-15 20:55:52 +0100 (Sat, 15 Jan 2005)
New Revision: 2305

Added:
   trunk/kernel/mips/
   trunk/kernel/mips/kernel-latest-mips/
   trunk/kernel/mips/kernel-latest-mips/debian/
   trunk/kernel/mips/kernel-latest-mips/debian/changelog
   trunk/kernel/mips/kernel-latest-mips/debian/compat
   trunk/kernel/mips/kernel-latest-mips/debian/control
   trunk/kernel/mips/kernel-latest-mips/debian/control.in/
   trunk/kernel/mips/kernel-latest-mips/debian/control.in/headers
   trunk/kernel/mips/kernel-latest-mips/debian/control.in/stub
   trunk/kernel/mips/kernel-latest-mips/debian/control.in/template
   trunk/kernel/mips/kernel-latest-mips/debian/copyright
   trunk/kernel/mips/kernel-latest-mips/debian/flavours.mips
   trunk/kernel/mips/kernel-latest-mips/debian/flavours.mipsel
   trunk/kernel/mips/kernel-latest-mips/debian/rules
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/changelog
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/compat
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/r10k-ip27
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/r4k-ip22
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/r5k-ip32
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/sb1-swarm-bn
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mipsel/
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mipsel/sb1-swarm-bn
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r10k-ip27
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r3k-kn02
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r4k-ip22
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r4k-kn04
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r5k-cobalt
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r5k-ip32
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r5k-lasat
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/sb1-swarm-bn
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/stub
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/xxs1500
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/copyright
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/elf2ecoff.8
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/flavours.mips
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/flavours.mipsel
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/mips-tools.dirs
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/mips-tools.manpages
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/05_linux-mips-makefile.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/10_cobalt-patch.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/20_sb1-mipsrtc.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/21_sb-duart.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/22_swarm-pcmcia.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/30_dec-initrd.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/31_dec-pmadaa.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/32_dec-loadkeys.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/40_ip22-hal2.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/50_xxs1500-boardreset.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/00_linux-mips.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/00list
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/01_more-linux-mips.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/10_arch-makefile.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/11_byteorder-proc.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/20_addrspace-64bit.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/21_r4k-cache.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/30_ip22-eisa-update.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/40_ip27-horribles.dpatch
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/post-install
   trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/rules
Log:
Initial mips support for 2.6 kernels.


Added: trunk/kernel/mips/kernel-latest-mips/debian/changelog
===================================================================
--- trunk/kernel/mips/kernel-latest-mips/debian/changelog	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-latest-mips/debian/changelog	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,5 @@
+kernel-latest-mips (2.6.10-1-0) UNRELEASED; urgency=low
+
+  * Meta package for easier upgrading of mips/mipsel kernels.
+
+ -- Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>  Sat, 15 Jan 2005 11:36:10 +0100

Added: trunk/kernel/mips/kernel-latest-mips/debian/compat
===================================================================
--- trunk/kernel/mips/kernel-latest-mips/debian/compat	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-latest-mips/debian/compat	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1 @@
+4

Added: trunk/kernel/mips/kernel-latest-mips/debian/control
===================================================================
--- trunk/kernel/mips/kernel-latest-mips/debian/control	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-latest-mips/debian/control	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,98 @@
+Source: kernel-latest-mips
+Section: devel
+Priority: optional
+Maintainer: Debian kernel team <debian-kernel at lists.debian.org>
+Uploaders: Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+Standards-Version: 3.6.1
+Build-Depends: debhelper (>= 4)
+
+Package: kernel-headers-2.6
+Architecture: mips
+Section: devel
+Priority: optional
+Depends: kernel-headers-2.6.10-1
+Description: Linux kernel headers 2.6 for mips
+ This package will always depend on the latest 2.6 kernel headers
+ available for mips.
+
+Package: kernel-headers
+Architecture: mips
+Section: devel
+Priority: optional
+Depends: kernel-headers-2.6
+Description: Linux kernel headers for mips
+ This package will always depend on the latest kernel headers
+ available for mips.
+
+Package: kernel-image-2.6-r4k-ip22
+Architecture: mips
+Section: base
+Priority: optional
+Depends: kernel-image-2.6.10-1-r4k-ip22
+Description: Linux kernel image for version 2.6 on mips r4k-ip22
+ This package will always depend on the latest 2.6 kernel image
+ available for the mips r4k-ip22 subarchitecture.
+
+Package: kernel-image-r4k-ip22
+Architecture: mips
+Section: base
+Priority: optional
+Depends: kernel-image-2.6-r4k-ip22
+Description: Linux kernel image for mips r4k-ip22
+ This package will always depend on the latest kernel image
+ available for the mips r4k-ip22 subarchitecture.
+
+Package: kernel-image-2.6-r10k-ip27
+Architecture: mips
+Section: base
+Priority: optional
+Depends: kernel-image-2.6.10-1-r10k-ip27
+Description: Linux kernel image for version 2.6 on mips r10k-ip27
+ This package will always depend on the latest 2.6 kernel image
+ available for the mips r10k-ip27 subarchitecture.
+
+Package: kernel-image-r10k-ip27
+Architecture: mips
+Section: base
+Priority: optional
+Depends: kernel-image-2.6-r10k-ip27
+Description: Linux kernel image for mips r10k-ip27
+ This package will always depend on the latest kernel image
+ available for the mips r10k-ip27 subarchitecture.
+
+Package: kernel-image-2.6-r5k-ip32
+Architecture: mips
+Section: base
+Priority: optional
+Depends: kernel-image-2.6.10-1-r5k-ip32
+Description: Linux kernel image for version 2.6 on mips r5k-ip32
+ This package will always depend on the latest 2.6 kernel image
+ available for the mips r5k-ip32 subarchitecture.
+
+Package: kernel-image-r5k-ip32
+Architecture: mips
+Section: base
+Priority: optional
+Depends: kernel-image-2.6-r5k-ip32
+Description: Linux kernel image for mips r5k-ip32
+ This package will always depend on the latest kernel image
+ available for the mips r5k-ip32 subarchitecture.
+
+Package: kernel-image-2.6-sb1-swarm-bn
+Architecture: mips
+Section: base
+Priority: optional
+Depends: kernel-image-2.6.10-1-sb1-swarm-bn
+Description: Linux kernel image for version 2.6 on mips sb1-swarm-bn
+ This package will always depend on the latest 2.6 kernel image
+ available for the mips sb1-swarm-bn subarchitecture.
+
+Package: kernel-image-sb1-swarm-bn
+Architecture: mips
+Section: base
+Priority: optional
+Depends: kernel-image-2.6-sb1-swarm-bn
+Description: Linux kernel image for mips sb1-swarm-bn
+ This package will always depend on the latest kernel image
+ available for the mips sb1-swarm-bn subarchitecture.
+

Added: trunk/kernel/mips/kernel-latest-mips/debian/control.in/headers
===================================================================
--- trunk/kernel/mips/kernel-latest-mips/debian/control.in/headers	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-latest-mips/debian/control.in/headers	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,17 @@
+Package: kernel-headers-@@KERNMAJ@@
+Architecture: @@ARCH@@
+Section: devel
+Priority: optional
+Depends: kernel-headers-@@KERNVER@@-@@ABIVER@@
+Description: Linux kernel headers @@KERNMAJ@@ for @@ARCH@@
+ This package will always depend on the latest @@KERNMAJ@@ kernel headers
+ available for @@ARCH@@.
+
+Package: kernel-headers
+Architecture: @@ARCH@@
+Section: devel
+Priority: optional
+Depends: kernel-headers-@@KERNMAJ@@
+Description: Linux kernel headers for @@ARCH@@
+ This package will always depend on the latest kernel headers
+ available for @@ARCH@@.

Added: trunk/kernel/mips/kernel-latest-mips/debian/control.in/stub
===================================================================
--- trunk/kernel/mips/kernel-latest-mips/debian/control.in/stub	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-latest-mips/debian/control.in/stub	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,7 @@
+Source: kernel-latest-mips
+Section: devel
+Priority: optional
+Maintainer: Debian kernel team <debian-kernel at lists.debian.org>
+Uploaders: Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+Standards-Version: 3.6.1
+Build-Depends: debhelper (>= 4)

Added: trunk/kernel/mips/kernel-latest-mips/debian/control.in/template
===================================================================
--- trunk/kernel/mips/kernel-latest-mips/debian/control.in/template	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-latest-mips/debian/control.in/template	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,17 @@
+Package: kernel-image-@@KERNMAJ@@-@@SUBARCH@@
+Architecture: @@ARCH@@
+Section: base
+Priority: optional
+Depends: kernel-image-@@KERNVER@@-@@ABIVER@@-@@SUBARCH@@
+Description: Linux kernel image for version @@KERNMAJ@@ on @@ARCH@@ @@SUBARCH@@
+ This package will always depend on the latest @@KERNMAJ@@ kernel image
+ available for the @@ARCH@@ @@SUBARCH@@ subarchitecture.
+
+Package: kernel-image-@@SUBARCH@@
+Architecture: @@ARCH@@
+Section: base
+Priority: optional
+Depends: kernel-image-@@KERNMAJ@@-@@SUBARCH@@
+Description: Linux kernel image for @@ARCH@@ @@SUBARCH@@
+ This package will always depend on the latest kernel image
+ available for the @@ARCH@@ @@SUBARCH@@ subarchitecture.

Added: trunk/kernel/mips/kernel-latest-mips/debian/copyright
===================================================================
--- trunk/kernel/mips/kernel-latest-mips/debian/copyright	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-latest-mips/debian/copyright	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,26 @@
+This is the Debian GNU/Linux prepackaged version of the Linux kernel.
+Linux was written by Linus Torvalds <Linus.Torvalds at cs.Helsinki.FI>
+and others.
+
+This package was put together by Simon Horman <horms at debian.org>
+and provides meta packages only. As such there is no upstream.
+
+The adaptions for mips/mipsel were made by
+Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; version 2 dated June, 1991.
+
+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.
+
+On Debian GNU/Linux systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL'.

Added: trunk/kernel/mips/kernel-latest-mips/debian/flavours.mips
===================================================================
--- trunk/kernel/mips/kernel-latest-mips/debian/flavours.mips	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-latest-mips/debian/flavours.mips	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,5 @@
+# Kernel flavours we build for mips
+r4k-ip22
+r10k-ip27
+r5k-ip32
+sb1-swarm-bn

Added: trunk/kernel/mips/kernel-latest-mips/debian/flavours.mipsel
===================================================================
--- trunk/kernel/mips/kernel-latest-mips/debian/flavours.mipsel	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-latest-mips/debian/flavours.mipsel	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,7 @@
+# Kernel flavours we build for mipsel
+#r3k-kn02
+#r4k-kn04
+#r5k-cobalt
+#r5k-lasat
+sb1-swarm-bn
+#xxs1500

Added: trunk/kernel/mips/kernel-latest-mips/debian/rules
===================================================================
--- trunk/kernel/mips/kernel-latest-mips/debian/rules	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-latest-mips/debian/rules	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,92 @@
+#!/usr/bin/make -f
+#
+# debian/rules for kernel-latest-*-mips
+#
+# GNU copyright 1997 to 1999 by Joey Hess.
+# Copyright (c) 1999-2002 Herbert Xu <herbert at debian.org>
+# Copyright (C) 2005 Thiemo Seufer
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+SHELL := sh -e
+
+ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH)
+
+# we derive all kernel versions from the changelog, which has to follow
+# <kernel upstream>-<abi version>-<debian revision> convention
+# e.g. 2.6.10-1-1
+
+# upstream kernel version and module abi, e.g. 2.6.10-1
+VERSION := $(shell dpkg-parsechangelog |grep '^Version:' \
+	|sed -e 's/^Version: //' -e 's/-[^-]*$$//')
+
+# upstream kernel version, e.g. 2.6.10
+KERNVER := $(shell echo $(VERSION) |sed 's/-[^-]*$$//')
+
+# kernel "major" version, e.g. 2.6
+KERNMAJ := $(shell echo $(KERNVER) |sed 's/\.[0-9]*$$//')
+
+# the module abi version
+ABIVER := $(shell echo $(VERSION) |sed 's/^.*-//')
+
+# the flavours we're building for
+FLAVOURS := $(shell grep -v ^\# debian/flavours.$(ARCH))
+BINARY_ARCH := $(FLAVOURS:=.binary-arch)
+
+build: debian/control
+
+debian/control: debian/changelog \
+		debian/control.in/stub debian/control.in/headers \
+		debian/control.in/template debian/flavours.$(ARCH)
+	cat debian/control.in/stub >$@ && echo '' >> $@
+	sed -e 's/@@KERNVER@@/$(KERNVER)/g' \
+		-e 's/@@ARCH@@/$(ARCH)/g' \
+		-e 's/@@KERNMAJ@@/$(KERNMAJ)/g' \
+		-e 's/@@ABIVER@@/$(ABIVER)/g' \
+		debian/control.in/headers >>$@ \
+		&& echo '' >> $@
+	$(foreach flavour,$(FLAVOURS), \
+		sed -e 's/@@KERNVER@@/$(KERNVER)/g' \
+			-e 's/@@ARCH@@/$(ARCH)/g' \
+			-e 's/@@KERNMAJ@@/$(KERNMAJ)/g' \
+			-e 's/@@ABIVER@@/$(ABIVER)/g' \
+			-e 's/@@SUBARCH@@/$(flavour)/g' \
+			debian/control.in/template >>$@ \
+			&& echo '' >> $@ &&) :
+
+clean:
+	dh_testdir
+	dh_clean
+
+install: build
+	dh_testdir
+	dh_clean -k
+	dh_installdirs
+
+# Build architecture-independent files here.
+binary-indep:
+
+%.binary-arch-pkg:
+	dh_testroot
+	dh_testdir
+	dh_clean -k --package=$*
+	dh_installdirs --package=$*
+	dh_installdocs --package=$*
+	dh_installchangelogs --package=$*
+	dh_compress --package=$*
+	dh_fixperms --package=$*
+	dh_installdeb --package=$*
+	dh_gencontrol --package=$*
+	dh_md5sums --package=$*
+	dh_builddeb --package=$*
+
+%.binary-arch: kernel-headers-$(KERNMAJ).binary-arch-pkg kernel-headers.binary-arch-pkg \
+		kernel-image-$(KERNMAJ)-%.binary-arch-pkg kernel-image-%.binary-arch-pkg
+	@:
+
+# Build architecture-dependent files here.
+binary-arch: install $(BINARY_ARCH)
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install unpack


Property changes on: trunk/kernel/mips/kernel-latest-mips/debian/rules
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/changelog
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/changelog	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/changelog	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,5 @@
+kernel-patch-2.6.10-mips (2.6.10-1-0) UNRELEASED; urgency=low
+
+  * Initial mips/mipsel 2.6 kernel.
+
+ -- Thiemo Seufer <seufer at csv.ica-uni-stuttgart.de>  Sat, 15 Jan 2005 20:09:34 +0100

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/compat
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/compat	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/compat	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1 @@
+4

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/r10k-ip27
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/r10k-ip27	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/r10k-ip27	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,914 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10
+# Wed Jan 12 17:05:32 2005
+#
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
+CONFIG_64BIT=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+CONFIG_BROKEN=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=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=15
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=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 is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+CONFIG_SGI_IP27=y
+# CONFIG_SGI_SN0_N_MODE is not set
+CONFIG_DISCONTIGMEM=y
+# CONFIG_NUMA is not set
+# CONFIG_MAPPED_KERNEL is not set
+# CONFIG_REPLICATE_KTEXT is not set
+# CONFIG_REPLICATE_EXHANDLERS is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_ARC=y
+CONFIG_DMA_IP27=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_MIPS_L1_CACHE_SHIFT=7
+CONFIG_ARC64=y
+CONFIG_BOOT_ELF64=y
+CONFIG_QL_ISP_A64=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+CONFIG_CPU_R10000=y
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=64
+# CONFIG_PREEMPT is not set
+# CONFIG_MIPS_INSANE_LARGE is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+
+#
+# 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 is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD 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 is not set
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_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 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+CONFIG_SCSI_QLOGIC_ISP=y
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=y
+CONFIG_MD_RAID1=y
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=y
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# 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=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+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 is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_DEBUG=y
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_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_CONNMARK=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_LOCAL=y
+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_TARGET_CONNMARK=m
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
+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
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+CONFIG_SCTP_DBG_MSG=y
+CONFIG_SCTP_DBG_OBJCNT=y
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# 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 is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SGI_IOC3_ETH=y
+CONFIG_SGI_IOC3_ETH_HW_RX_CSUM=y
+CONFIG_SGI_IOC3_ETH_HW_TX_CSUM=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# 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_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP 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 is not set
+
+#
+# Userland interfaces
+#
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_RAW=m
+
+#
+# Input Device Drivers
+#
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+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_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+CONFIG_SGI_IP27_RTC=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# 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
+
+#
+# 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=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+CONFIG_JBD_DEBUG=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_QUOTA is not set
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+# CONFIG_AUTOFS4_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+# CONFIG_TMPFS 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_ASFS_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 is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+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 is not set
+# CONFIG_CIFS 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+# CONFIG_NLS is not set
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_CROSSCOMPILE is not set
+CONFIG_CMDLINE=""
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/r4k-ip22
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/r4k-ip22	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/r4k-ip22	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,1172 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10
+# Wed Jan 12 18:49:03 2005
+#
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
+CONFIG_64BIT=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 is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=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 is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+CONFIG_SGI_IP22=y
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_ARC=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_IRQ_CPU=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_ARC32=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_ARC_CONSOLE=y
+CONFIG_ARC_PROMLIB=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+CONFIG_CPU_R4X00=y
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_IP22_CPU_SCACHE=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_ISA=y
+CONFIG_EISA=y
+CONFIG_EISA_NAMES=y
+CONFIG_MMU=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=y
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+# CONFIG_PARPORT_PC is not set
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=m
+CONFIG_IOSCHED_DEADLINE=m
+CONFIG_IOSCHED_CFQ=m
+
+#
+# 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=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+CONFIG_SGIWD93_SCSI=y
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+# CONFIG_MD_MULTIPATH is not set
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+
+#
+# Networking support
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK_DEV=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+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=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=y
+CONFIG_IP_TCPDIAG_IPV6=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=y
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_CT_PROTO_SCTP is not set
+CONFIG_IP_NF_FTP=y
+CONFIG_IP_NF_IRC=y
+CONFIG_IP_NF_TFTP=y
+CONFIG_IP_NF_AMANDA=y
+CONFIG_IP_NF_QUEUE=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_LIMIT=y
+CONFIG_IP_NF_MATCH_IPRANGE=y
+CONFIG_IP_NF_MATCH_MAC=y
+CONFIG_IP_NF_MATCH_PKTTYPE=y
+CONFIG_IP_NF_MATCH_MARK=y
+CONFIG_IP_NF_MATCH_MULTIPORT=y
+CONFIG_IP_NF_MATCH_TOS=y
+CONFIG_IP_NF_MATCH_RECENT=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_DSCP=y
+CONFIG_IP_NF_MATCH_AH_ESP=y
+CONFIG_IP_NF_MATCH_LENGTH=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_MATCH_TCPMSS=y
+CONFIG_IP_NF_MATCH_HELPER=y
+CONFIG_IP_NF_MATCH_STATE=y
+CONFIG_IP_NF_MATCH_CONNTRACK=y
+CONFIG_IP_NF_MATCH_OWNER=y
+CONFIG_IP_NF_MATCH_ADDRTYPE=y
+CONFIG_IP_NF_MATCH_REALM=y
+CONFIG_IP_NF_MATCH_SCTP=y
+CONFIG_IP_NF_MATCH_COMMENT=y
+CONFIG_IP_NF_MATCH_CONNMARK=y
+CONFIG_IP_NF_MATCH_HASHLIMIT=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_LOG=y
+CONFIG_IP_NF_TARGET_ULOG=y
+CONFIG_IP_NF_TARGET_TCPMSS=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_SAME=y
+CONFIG_IP_NF_NAT_LOCAL=y
+CONFIG_IP_NF_NAT_SNMP_BASIC=y
+CONFIG_IP_NF_NAT_IRC=y
+CONFIG_IP_NF_NAT_FTP=y
+CONFIG_IP_NF_NAT_TFTP=y
+CONFIG_IP_NF_NAT_AMANDA=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_TOS=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_DSCP=y
+CONFIG_IP_NF_TARGET_MARK=y
+CONFIG_IP_NF_TARGET_CLASSIFY=y
+CONFIG_IP_NF_TARGET_CONNMARK=y
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_TARGET_NOTRACK=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_LIMIT=y
+CONFIG_IP6_NF_MATCH_MAC=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_MULTIPORT=y
+CONFIG_IP6_NF_MATCH_OWNER=y
+CONFIG_IP6_NF_MATCH_MARK=y
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+CONFIG_IP6_NF_MATCH_AHESP=y
+CONFIG_IP6_NF_MATCH_LENGTH=y
+CONFIG_IP6_NF_MATCH_EUI64=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_LOG=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_TARGET_MARK=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=y
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# 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=m
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+CONFIG_SGISEEQ=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_MOUSEDEV_PSAUX_ENABLE=y
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+CONFIG_SERIO_RAW=y
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_MOUSE_VSXXXAA 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 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_IP22_ZILOG=y
+CONFIG_SERIAL_IP22_ZILOG_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+# CONFIG_TIPAR is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_INDYDOG=m
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+CONFIG_RTC=m
+CONFIG_SGI_DS1286=y
+CONFIG_GEN_RTC=m
+CONFIG_GEN_RTC_X=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+CONFIG_I2C_ALGO_SGI=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ELEKTOR is not set
+# CONFIG_I2C_ISA is not set
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Hardware Sensors Chip support
+#
+# CONFIG_I2C_SENSOR is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+
+#
+# Other I2C Chip support
+#
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_VIDEO_BWQCAM is not set
+# CONFIG_VIDEO_CQCAM is not set
+# CONFIG_VIDEO_W9966 is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_VINO is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_SF16FMR2 is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_SGI_NEWPORT_CONSOLE=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FONT_8x16=y
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_LOGO_SGI_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_BIT32_EMUL=m
+CONFIG_SND_RTCTIMER=m
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ISA devices
+#
+# CONFIG_SND_AD1848 is not set
+# CONFIG_SND_CS4231 is not set
+# CONFIG_SND_CS4232 is not set
+# CONFIG_SND_CS4236 is not set
+# CONFIG_SND_ES1688 is not set
+# CONFIG_SND_ES18XX is not set
+# CONFIG_SND_GUSCLASSIC is not set
+# CONFIG_SND_GUSEXTREME is not set
+# CONFIG_SND_GUSMAX is not set
+# CONFIG_SND_INTERWAVE is not set
+# CONFIG_SND_INTERWAVE_STB is not set
+# CONFIG_SND_OPTI92X_AD1848 is not set
+# CONFIG_SND_OPTI92X_CS4231 is not set
+# CONFIG_SND_OPTI93X is not set
+# CONFIG_SND_SB8 is not set
+# CONFIG_SND_SB16 is not set
+# CONFIG_SND_SBAWE is not set
+# CONFIG_SND_WAVEFRONT is not set
+# CONFIG_SND_CMI8330 is not set
+# CONFIG_SND_OPL3SA2 is not set
+# CONFIG_SND_SGALAXY is not set
+# CONFIG_SND_SSCAPE is not set
+
+#
+# ALSA MIPS devices
+#
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_SONICVIBES is not set
+CONFIG_SOUND_HAL2=y
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+# CONFIG_SOUND_AD1980 is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# 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=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_TMPFS_SECURITY=y
+# 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_ASFS_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 is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_CROSSCOMPILE is not set
+CONFIG_CMDLINE=""
+
+#
+# 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=y
+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=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/r5k-ip32
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/r5k-ip32	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/r5k-ip32	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,1239 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10
+# Wed Jan 12 17:06:54 2005
+#
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
+CONFIG_64BIT=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 is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# 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 is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+CONFIG_SGI_IP32=y
+# CONFIG_SIBYTE_SB1xxx_SOC is not set
+# CONFIG_SNI_RM200_PCI is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_ARC=y
+CONFIG_DMA_NONCOHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_ARC32=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_ARC_MEMORY=y
+CONFIG_ARC_PROMLIB=y
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+CONFIG_CPU_R5000=y
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_BOARD_SCACHE=y
+CONFIG_R5000_CPU_SCACHE=y
+CONFIG_RM7000_CPU_SCACHE=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# 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=m
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=y
+# CONFIG_PARPORT_PC is not set
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_PARIDE 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 is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD 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
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=y
+# CONFIG_SCSI_FC_ATTRS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+CONFIG_SCSI_AIC7XXX=y
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
+CONFIG_AIC7XXX_RESET_DELAY_MS=1000
+CONFIG_AIC7XXX_DEBUG_ENABLE=y
+CONFIG_AIC7XXX_DEBUG_MASK=0
+CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
+# 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_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# 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 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+# CONFIG_MD_MULTIPATH is not set
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# 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=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+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=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_TUNNEL=y
+CONFIG_IP_TCPDIAG=y
+CONFIG_IP_TCPDIAG_IPV6=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=y
+CONFIG_IP_NF_CT_ACCT=y
+CONFIG_IP_NF_CONNTRACK_MARK=y
+# CONFIG_IP_NF_CT_PROTO_SCTP is not set
+CONFIG_IP_NF_FTP=y
+CONFIG_IP_NF_IRC=y
+CONFIG_IP_NF_TFTP=y
+CONFIG_IP_NF_AMANDA=y
+CONFIG_IP_NF_QUEUE=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_LIMIT=y
+CONFIG_IP_NF_MATCH_IPRANGE=y
+CONFIG_IP_NF_MATCH_MAC=y
+CONFIG_IP_NF_MATCH_PKTTYPE=y
+CONFIG_IP_NF_MATCH_MARK=y
+CONFIG_IP_NF_MATCH_MULTIPORT=y
+CONFIG_IP_NF_MATCH_TOS=y
+CONFIG_IP_NF_MATCH_RECENT=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_DSCP=y
+CONFIG_IP_NF_MATCH_AH_ESP=y
+CONFIG_IP_NF_MATCH_LENGTH=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_MATCH_TCPMSS=y
+CONFIG_IP_NF_MATCH_HELPER=y
+CONFIG_IP_NF_MATCH_STATE=y
+CONFIG_IP_NF_MATCH_CONNTRACK=y
+CONFIG_IP_NF_MATCH_OWNER=y
+CONFIG_IP_NF_MATCH_ADDRTYPE=y
+CONFIG_IP_NF_MATCH_REALM=y
+CONFIG_IP_NF_MATCH_SCTP=y
+CONFIG_IP_NF_MATCH_COMMENT=y
+CONFIG_IP_NF_MATCH_CONNMARK=m
+CONFIG_IP_NF_MATCH_HASHLIMIT=m
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_LOG=y
+CONFIG_IP_NF_TARGET_ULOG=y
+CONFIG_IP_NF_TARGET_TCPMSS=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_SAME=y
+CONFIG_IP_NF_NAT_LOCAL=y
+CONFIG_IP_NF_NAT_SNMP_BASIC=y
+CONFIG_IP_NF_NAT_IRC=y
+CONFIG_IP_NF_NAT_FTP=y
+CONFIG_IP_NF_NAT_TFTP=y
+CONFIG_IP_NF_NAT_AMANDA=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_TARGET_TOS=y
+CONFIG_IP_NF_TARGET_ECN=y
+CONFIG_IP_NF_TARGET_DSCP=y
+CONFIG_IP_NF_TARGET_MARK=y
+CONFIG_IP_NF_TARGET_CLASSIFY=y
+CONFIG_IP_NF_TARGET_CONNMARK=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_TARGET_NOTRACK=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_LIMIT=y
+CONFIG_IP6_NF_MATCH_MAC=y
+CONFIG_IP6_NF_MATCH_RT=y
+CONFIG_IP6_NF_MATCH_OPTS=y
+CONFIG_IP6_NF_MATCH_FRAG=y
+CONFIG_IP6_NF_MATCH_HL=y
+CONFIG_IP6_NF_MATCH_MULTIPORT=y
+CONFIG_IP6_NF_MATCH_OWNER=y
+CONFIG_IP6_NF_MATCH_MARK=y
+CONFIG_IP6_NF_MATCH_IPV6HEADER=y
+CONFIG_IP6_NF_MATCH_AHESP=y
+CONFIG_IP6_NF_MATCH_LENGTH=y
+CONFIG_IP6_NF_MATCH_EUI64=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_LOG=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_TARGET_MARK=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=y
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+# CONFIG_NET_SCH_CLK_JIFFIES is not set
+CONFIG_NET_SCH_CLK_GETTIMEOFDAY=y
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_HFSC=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_SCH_RED=y
+CONFIG_NET_SCH_SFQ=y
+CONFIG_NET_SCH_TEQL=y
+CONFIG_NET_SCH_TBF=y
+CONFIG_NET_SCH_GRED=y
+CONFIG_NET_SCH_DSMARK=y
+CONFIG_NET_SCH_NETEM=y
+CONFIG_NET_SCH_INGRESS=y
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=y
+CONFIG_NET_CLS_ROUTE4=y
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=y
+CONFIG_NET_CLS_U32=y
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_CLS_RSVP=y
+CONFIG_NET_CLS_RSVP6=y
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# 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 is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SGI_O2MACE_ETH=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_PCI is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# 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_TIGON3 is not set
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
+# CONFIG_S2IO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_MOUSEDEV_PSAUX_ENABLE=y
+# 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=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_MACEPS2=y
+CONFIG_SERIO_RAW=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA 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=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+# CONFIG_TIPAR is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_RTC 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_DRM is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+CONFIG_I2C_ALGO_SGI=m
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISA is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Hardware Sensors Chip support
+#
+# CONFIG_I2C_SENSOR is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+
+#
+# Other I2C Chip support
+#
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP 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=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_GBE=y
+CONFIG_FB_GBE_MEM=2
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON_OLD is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_E1356 is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+CONFIG_LOGO_SGI_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_BIT32_EMUL is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# PCI devices
+#
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VX222 is not set
+
+#
+# ALSA MIPS devices
+#
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+# CONFIG_SOUND_ALI5455 is not set
+# CONFIG_SOUND_FORTE is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_AD1980 is not set
+
+#
+# USB support
+#
+# CONFIG_USB 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=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=y
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_TMPFS_SECURITY=y
+# 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_ASFS_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=m
+# 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 is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_CROSSCOMPILE is not set
+CONFIG_CMDLINE=""
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_KGDB is not set
+# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_MIPS_UNCACHED 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=y
+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=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/sb1-swarm-bn
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/sb1-swarm-bn	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mips/sb1-swarm-bn	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,1637 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10
+# Wed Jan 12 18:53:22 2005
+#
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
+CONFIG_64BIT=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+CONFIG_BROKEN=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=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 is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+CONFIG_SIBYTE_SB1xxx_SOC=y
+CONFIG_SIBYTE_SWARM=y
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_UNKNOWN is not set
+CONFIG_SIBYTE_BOARD=y
+CONFIG_SIBYTE_SB1250=y
+# CONFIG_CPU_SB1_PASS_1 is not set
+# CONFIG_CPU_SB1_PASS_2_1250 is not set
+CONFIG_CPU_SB1_PASS_2_2=y
+# CONFIG_CPU_SB1_PASS_4 is not set
+# CONFIG_CPU_SB1_PASS_2_112x is not set
+# CONFIG_CPU_SB1_PASS_3 is not set
+CONFIG_SIBYTE_HAS_LDT=y
+# CONFIG_SIMULATION is not set
+CONFIG_SIBYTE_CFE=y
+CONFIG_SIBYTE_CFE_CONSOLE=y
+# CONFIG_SIBYTE_BUS_WATCHER is not set
+# CONFIG_SIBYTE_SB1250_PROF is not set
+# CONFIG_SIBYTE_TBPROF is not set
+# CONFIG_SNI_RM200_PCI is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_COHERENT=y
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+CONFIG_CPU_SB1=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_SIBYTE_DMA_PAGEOPS=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_VTAG_ICACHE=y
+CONFIG_SB1_PASS_2_WORKAROUNDS=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=32
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA_OBSOLETE=y
+CONFIG_PCMCIA=m
+# CONFIG_CARDBUS is not set
+
+#
+# PC-card bridges
+#
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+# CONFIG_TCIC is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+
+#
+# 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 is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD 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=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_IDEFLOPPY=m
+CONFIG_BLK_DEV_IDESCSI=m
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_OPTI621=m
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=m
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=m
+CONFIG_BLK_DEV_TRIFLEX=m
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+CONFIG_BLK_DEV_HPT34X=m
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=m
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_NS87415=m
+CONFIG_BLK_DEV_PDC202XX_OLD=m
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=m
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+CONFIG_BLK_DEV_SIIMAGE=m
+# CONFIG_BLK_DEV_SLC90E66 is not set
+CONFIG_BLK_DEV_TRM290=m
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_IDE_SWARM=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+# CONFIG_SCSI_3W_9XXX is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=32
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+CONFIG_SCSI_SATA=y
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_CPQFCTS is not set
+CONFIG_SCSI_DMX3191D=m
+CONFIG_SCSI_EATA=m
+# CONFIG_SCSI_EATA_TAGGED_QUEUE is not set
+# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set
+CONFIG_SCSI_EATA_MAX_TAGS=16
+CONFIG_SCSI_EATA_PIO=m
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_SYM53C8XX_2=m
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# 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
+CONFIG_SCSI_QLOGIC_ISP=m
+CONFIG_SCSI_QLOGIC_FC=m
+CONFIG_SCSI_QLOGIC_FC_FIRMWARE=y
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLOGIC_1280_1040=y
+# CONFIG_SCSI_DC395x is not set
+CONFIG_SCSI_DC390T=m
+CONFIG_SCSI_DEBUG=m
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# 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=m
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+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=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+# CONFIG_IP_NF_MATCH_IPRANGE is not set
+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 is not set
+# CONFIG_IP_NF_MATCH_REALM is not set
+CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_COMMENT is not set
+CONFIG_IP_NF_MATCH_CONNMARK=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 is not set
+# CONFIG_IP_NF_TARGET_SAME is not set
+CONFIG_IP_NF_NAT_LOCAL=y
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+# CONFIG_IP_NF_TARGET_CLASSIFY is not set
+CONFIG_IP_NF_TARGET_CONNMARK=m
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
+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=m
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=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=m
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+
+#
+# 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=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_HP100=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+# CONFIG_FORCEDETH is not set
+CONFIG_EEPRO100=m
+# CONFIG_EEPRO100_PIO is not set
+CONFIG_E100=m
+CONFIG_E100_NAPI=y
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+CONFIG_SUNDANCE_MMIO=y
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+# CONFIG_LAN_SAA9730 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_NET_SB1250_MAC=y
+CONFIG_SK98LIN=m
+CONFIG_VIA_VELOCITY=m
+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 is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV_PSAUX_ENABLE is not set
+CONFIG_INPUT_JOYDEV=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA 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=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+CONFIG_SIBYTE_SB1250_DUART=y
+CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+CONFIG_I2C_ALGO_SIBYTE=m
+# CONFIG_I2C_ALGO_SGI is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISA is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+CONFIG_I2C_SIBYTE=m
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+CONFIG_I2C_STUB=m
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Hardware Sensors Chip support
+#
+# CONFIG_I2C_SENSOR is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+
+#
+# Other I2C Chip support
+#
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_SWARM_7114H is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_ZR36120 is not set
+# CONFIG_VIDEO_SAA7134 is not set
+# CONFIG_VIDEO_MXB is not set
+# CONFIG_VIDEO_DPC is not set
+# CONFIG_VIDEO_HEXIUM_ORION is not set
+# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_VIDEO_CX88 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+CONFIG_FB_PM2=m
+CONFIG_FB_PM2_FIFO_DISCONNECT=y
+CONFIG_FB_CYBER2000=m
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G450=y
+CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+# CONFIG_FB_RADEON_OLD is not set
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+# CONFIG_FB_ATY_GENERIC_LCD is not set
+# CONFIG_FB_ATY_XL_INIT is not set
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=m
+CONFIG_FB_SAVAGE_ACCEL=m
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+CONFIG_FB_3DFX=m
+# CONFIG_FB_3DFX_ACCEL is not set
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+# CONFIG_FB_TRIDENT_ACCEL is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_E1356 is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_BIT32_EMUL=m
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_OPL3_LIB=m
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# PCI devices
+#
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+CONFIG_SND_CS46XX=m
+# CONFIG_SND_CS46XX_NEW_DSP is not set
+CONFIG_SND_CS4281=m
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VX222 is not set
+
+#
+# ALSA MIPS devices
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y is not set
+
+#
+# PCMCIA devices
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_AUDIO=m
+CONFIG_USB_BLUETOOTH_TTY=m
+CONFIG_USB_MIDI=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_RW_DETECT=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+CONFIG_USB_HIDINPUT=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_MTOUCH=m
+CONFIG_USB_EGALAX=m
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_HPUSBSCSI=m
+
+#
+# USB Multimedia devices
+#
+CONFIG_USB_VICAM=m
+CONFIG_USB_DSBR=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+
+#
+# USB Host-to-Host Cables
+#
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_GENESYS=y
+CONFIG_USB_NET1080=y
+CONFIG_USB_PL2301=y
+CONFIG_USB_KC2190=y
+
+#
+# Intelligent USB Devices/Gadgets
+#
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_ZAURUS=y
+CONFIG_USB_CDCETHER=y
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_AX8817X=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_TIGL=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYTHERM=m
+# CONFIG_USB_PHIDGETKIT is not set
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_TEST=m
+
+#
+# USB ATM/DSL drivers
+#
+
+#
+# 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=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+# CONFIG_JFS_DEBUG is not set
+CONFIG_JFS_STATISTICS=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=m
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_TMPFS_SECURITY=y
+# 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_ASFS_FS is not set
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# 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 is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS 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=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_CROSSCOMPILE is not set
+CONFIG_CMDLINE=""
+# CONFIG_SB1XXX_CORELIS 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=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=m
+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=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mipsel/sb1-swarm-bn
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mipsel/sb1-swarm-bn	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/config/mipsel/sb1-swarm-bn	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,1637 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.10
+# Wed Jan 12 18:58:15 2005
+#
+CONFIG_MIPS=y
+CONFIG_MIPS64=y
+CONFIG_64BIT=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_CLEAN_COMPILE is not set
+CONFIG_BROKEN=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=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 is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MIPS_EV64120 is not set
+# CONFIG_MIPS_EV96100 is not set
+# CONFIG_MIPS_IVR is not set
+# CONFIG_LASAT is not set
+# CONFIG_MIPS_ITE8172 is not set
+# CONFIG_MIPS_ATLAS is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SEAD is not set
+# CONFIG_MOMENCO_OCELOT is not set
+# CONFIG_MOMENCO_OCELOT_G is not set
+# CONFIG_MOMENCO_OCELOT_C is not set
+# CONFIG_MOMENCO_OCELOT_3 is not set
+# CONFIG_MOMENCO_JAGUAR_ATX is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_DDB5074 is not set
+# CONFIG_DDB5476 is not set
+# CONFIG_DDB5477 is not set
+# CONFIG_NEC_OSPREY is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP32 is not set
+CONFIG_SIBYTE_SB1xxx_SOC=y
+CONFIG_SIBYTE_SWARM=y
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_PTSWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_UNKNOWN is not set
+CONFIG_SIBYTE_BOARD=y
+CONFIG_SIBYTE_SB1250=y
+# CONFIG_CPU_SB1_PASS_1 is not set
+# CONFIG_CPU_SB1_PASS_2_1250 is not set
+CONFIG_CPU_SB1_PASS_2_2=y
+# CONFIG_CPU_SB1_PASS_4 is not set
+# CONFIG_CPU_SB1_PASS_2_112x is not set
+# CONFIG_CPU_SB1_PASS_3 is not set
+CONFIG_SIBYTE_HAS_LDT=y
+# CONFIG_SIMULATION is not set
+CONFIG_SIBYTE_CFE=y
+CONFIG_SIBYTE_CFE_CONSOLE=y
+# CONFIG_SIBYTE_BUS_WATCHER is not set
+# CONFIG_SIBYTE_SB1250_PROF is not set
+# CONFIG_SIBYTE_TBPROF is not set
+# CONFIG_SNI_RM200_PCI is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_HAVE_DEC_LOCK=y
+CONFIG_DMA_COHERENT=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_BOOT_ELF32=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+
+#
+# CPU selection
+#
+# CONFIG_CPU_MIPS32 is not set
+# CONFIG_CPU_MIPS64 is not set
+# CONFIG_CPU_R3000 is not set
+# CONFIG_CPU_TX39XX is not set
+# CONFIG_CPU_VR41XX is not set
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+CONFIG_CPU_SB1=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_SIBYTE_DMA_PAGEOPS=y
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_VTAG_ICACHE=y
+CONFIG_SB1_PASS_2_WORKAROUNDS=y
+CONFIG_CPU_HAS_LLSC=y
+CONFIG_CPU_HAS_LLDSCD=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_SMP=y
+CONFIG_NR_CPUS=32
+# CONFIG_PREEMPT is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+CONFIG_HW_HAS_PCI=y
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY_PROC=y
+CONFIG_PCI_NAMES=y
+CONFIG_MMU=y
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA_OBSOLETE=y
+CONFIG_PCMCIA=m
+# CONFIG_CARDBUS is not set
+
+#
+# PC-card bridges
+#
+# CONFIG_PD6729 is not set
+# CONFIG_I82092 is not set
+# CONFIG_TCIC is not set
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_BUILD_ELF64 is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+
+#
+# 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 is not set
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CDROM_PKTCDVD 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=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+CONFIG_BLK_DEV_IDECS=m
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_IDEFLOPPY=m
+CONFIG_BLK_DEV_IDESCSI=m
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_OPTI621=m
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+CONFIG_BLK_DEV_AEC62XX=m
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+CONFIG_BLK_DEV_CMD64X=m
+CONFIG_BLK_DEV_TRIFLEX=m
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+CONFIG_BLK_DEV_HPT34X=m
+# CONFIG_HPT34X_AUTODMA is not set
+CONFIG_BLK_DEV_HPT366=m
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+CONFIG_BLK_DEV_NS87415=m
+CONFIG_BLK_DEV_PDC202XX_OLD=m
+# CONFIG_PDC202XX_BURST is not set
+CONFIG_BLK_DEV_PDC202XX_NEW=m
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+CONFIG_BLK_DEV_SIIMAGE=m
+# CONFIG_BLK_DEV_SLC90E66 is not set
+CONFIG_BLK_DEV_TRM290=m
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_IDE_SWARM=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI=m
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=m
+CONFIG_CHR_DEV_SCH=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI Transport Attributes
+#
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+
+#
+# SCSI low-level drivers
+#
+CONFIG_BLK_DEV_3W_XXXX_RAID=m
+# CONFIG_SCSI_3W_9XXX is not set
+CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AACRAID=m
+CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
+# CONFIG_AIC7XXX_DEBUG_ENABLE is not set
+CONFIG_AIC7XXX_DEBUG_MASK=0
+# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set
+CONFIG_SCSI_AIC7XXX_OLD=m
+CONFIG_SCSI_AIC79XX=m
+CONFIG_AIC79XX_CMDS_PER_DEVICE=32
+CONFIG_AIC79XX_RESET_DELAY_MS=15000
+# CONFIG_AIC79XX_ENABLE_RD_STRM is not set
+# CONFIG_AIC79XX_DEBUG_ENABLE is not set
+CONFIG_AIC79XX_DEBUG_MASK=0
+# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+CONFIG_SCSI_SATA=y
+CONFIG_SCSI_SATA_AHCI=m
+CONFIG_SCSI_SATA_SVW=m
+# CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_NV is not set
+CONFIG_SCSI_SATA_PROMISE=m
+CONFIG_SCSI_SATA_SX4=m
+CONFIG_SCSI_SATA_SIL=m
+CONFIG_SCSI_SATA_SIS=m
+CONFIG_SCSI_SATA_ULI=m
+CONFIG_SCSI_SATA_VIA=m
+CONFIG_SCSI_SATA_VITESSE=m
+CONFIG_SCSI_BUSLOGIC=m
+# CONFIG_SCSI_OMIT_FLASHPOINT is not set
+# CONFIG_SCSI_CPQFCTS is not set
+CONFIG_SCSI_DMX3191D=m
+CONFIG_SCSI_EATA=m
+# CONFIG_SCSI_EATA_TAGGED_QUEUE is not set
+# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set
+CONFIG_SCSI_EATA_MAX_TAGS=16
+CONFIG_SCSI_EATA_PIO=m
+CONFIG_SCSI_FUTURE_DOMAIN=m
+CONFIG_SCSI_GDTH=m
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+CONFIG_SCSI_INIA100=m
+CONFIG_SCSI_SYM53C8XX_2=m
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# 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
+CONFIG_SCSI_QLOGIC_ISP=m
+CONFIG_SCSI_QLOGIC_FC=m
+CONFIG_SCSI_QLOGIC_FC_FIRMWARE=y
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLOGIC_1280_1040=y
+# CONFIG_SCSI_DC395x is not set
+CONFIG_SCSI_DC390T=m
+CONFIG_SCSI_DEBUG=m
+
+#
+# PCMCIA SCSI adapter support
+#
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID5=m
+CONFIG_MD_RAID6=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# 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=m
+CONFIG_UNIX=y
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_FWMARK=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_TUNNEL=m
+CONFIG_IP_TCPDIAG=y
+# CONFIG_IP_TCPDIAG_IPV6 is not set
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+CONFIG_IPV6=m
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_IPV6_TUNNEL=m
+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=y
+CONFIG_IP_NF_CT_PROTO_SCTP=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_IRC=m
+CONFIG_IP_NF_TFTP=m
+CONFIG_IP_NF_AMANDA=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+# CONFIG_IP_NF_MATCH_IPRANGE is not set
+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 is not set
+# CONFIG_IP_NF_MATCH_REALM is not set
+CONFIG_IP_NF_MATCH_SCTP=m
+# CONFIG_IP_NF_MATCH_COMMENT is not set
+CONFIG_IP_NF_MATCH_CONNMARK=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 is not set
+# CONFIG_IP_NF_TARGET_SAME is not set
+CONFIG_IP_NF_NAT_LOCAL=y
+CONFIG_IP_NF_NAT_SNMP_BASIC=m
+CONFIG_IP_NF_NAT_IRC=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_NAT_TFTP=m
+CONFIG_IP_NF_NAT_AMANDA=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+# CONFIG_IP_NF_TARGET_CLASSIFY is not set
+CONFIG_IP_NF_TARGET_CONNMARK=m
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
+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=m
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_LIMIT=m
+CONFIG_IP6_NF_MATCH_MAC=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_MULTIPORT=m
+CONFIG_IP6_NF_MATCH_OWNER=m
+CONFIG_IP6_NF_MATCH_MARK=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_AHESP=m
+CONFIG_IP6_NF_MATCH_LENGTH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_TARGET_MARK=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+CONFIG_IP_SCTP=m
+# CONFIG_SCTP_DBG_MSG is not set
+# CONFIG_SCTP_DBG_OBJCNT is not set
+# CONFIG_SCTP_HMAC_NONE is not set
+# CONFIG_SCTP_HMAC_SHA1 is not set
+CONFIG_SCTP_HMAC_MD5=y
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CLK_JIFFIES=y
+# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
+# CONFIG_NET_SCH_CLK_CPU is not set
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_QOS=y
+CONFIG_NET_ESTIMATOR=y
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_ROUTE=y
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+# CONFIG_CLS_U32_PERF is not set
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_CLS_POLICE=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=m
+CONFIG_TUN=m
+CONFIG_ETHERTAP=m
+
+#
+# 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=m
+CONFIG_TULIP=m
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_TULIP_NAPI is not set
+CONFIG_DE4X5=m
+CONFIG_WINBOND_840=m
+CONFIG_DM9102=m
+CONFIG_HP100=m
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+CONFIG_AMD8111_ETH=m
+CONFIG_AMD8111E_NAPI=y
+CONFIG_ADAPTEC_STARFIRE=m
+CONFIG_ADAPTEC_STARFIRE_NAPI=y
+CONFIG_B44=m
+# CONFIG_FORCEDETH is not set
+CONFIG_EEPRO100=m
+# CONFIG_EEPRO100_PIO is not set
+CONFIG_E100=m
+CONFIG_E100_NAPI=y
+CONFIG_FEALNX=m
+CONFIG_NATSEMI=m
+CONFIG_NE2K_PCI=m
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+CONFIG_8139TOO_PIO=y
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_OLD_RX_RESET is not set
+CONFIG_SIS900=m
+CONFIG_EPIC100=m
+CONFIG_SUNDANCE=m
+CONFIG_SUNDANCE_MMIO=y
+CONFIG_VIA_RHINE=m
+CONFIG_VIA_RHINE_MMIO=y
+# CONFIG_LAN_SAA9730 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
+CONFIG_NS83820=m
+CONFIG_HAMACHI=m
+CONFIG_YELLOWFIN=m
+CONFIG_R8169=m
+CONFIG_R8169_NAPI=y
+CONFIG_NET_SB1250_MAC=y
+CONFIG_SK98LIN=m
+CONFIG_VIA_VELOCITY=m
+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 is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+CONFIG_PPP=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPPOE=m
+CONFIG_SLIP=m
+CONFIG_SLIP_COMPRESSED=y
+CONFIG_SLIP_SMART=y
+CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+
+#
+# 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=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_MOUSEDEV_PSAUX_ENABLE is not set
+CONFIG_INPUT_JOYDEV=m
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_RAW is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA 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=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_SYNCLINKMP is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+CONFIG_SIBYTE_SB1250_DUART=y
+CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=m
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+CONFIG_SYNCLINK_CS=m
+# CONFIG_RAW_DRIVER is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+CONFIG_I2C_ALGO_SIBYTE=m
+# CONFIG_I2C_ALGO_SGI is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISA is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_PROSAVAGE is not set
+# CONFIG_I2C_SAVAGE4 is not set
+CONFIG_I2C_SIBYTE=m
+# CONFIG_SCx200_ACB is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+CONFIG_I2C_STUB=m
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Hardware Sensors Chip support
+#
+# CONFIG_I2C_SENSOR is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+
+#
+# Other I2C Chip support
+#
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_SWARM_7114H is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_ZR36120 is not set
+# CONFIG_VIDEO_SAA7134 is not set
+# CONFIG_VIDEO_MXB is not set
+# CONFIG_VIDEO_DPC is not set
+# CONFIG_VIDEO_HEXIUM_ORION is not set
+# CONFIG_VIDEO_HEXIUM_GEMINI is not set
+# CONFIG_VIDEO_CX88 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_CIRRUS=m
+CONFIG_FB_PM2=m
+CONFIG_FB_PM2_FIFO_DISCONNECT=y
+CONFIG_FB_CYBER2000=m
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_RIVA=m
+# CONFIG_FB_RIVA_I2C is not set
+# CONFIG_FB_RIVA_DEBUG is not set
+CONFIG_FB_MATROX=m
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G450=y
+CONFIG_FB_MATROX_G100=y
+CONFIG_FB_MATROX_I2C=m
+CONFIG_FB_MATROX_MAVEN=m
+CONFIG_FB_MATROX_MULTIHEAD=y
+# CONFIG_FB_RADEON_OLD is not set
+CONFIG_FB_RADEON=m
+CONFIG_FB_RADEON_I2C=y
+# CONFIG_FB_RADEON_DEBUG is not set
+CONFIG_FB_ATY128=m
+CONFIG_FB_ATY=m
+CONFIG_FB_ATY_CT=y
+# CONFIG_FB_ATY_GENERIC_LCD is not set
+# CONFIG_FB_ATY_XL_INIT is not set
+CONFIG_FB_ATY_GX=y
+CONFIG_FB_SAVAGE=m
+CONFIG_FB_SAVAGE_I2C=m
+CONFIG_FB_SAVAGE_ACCEL=m
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+CONFIG_FB_3DFX=m
+# CONFIG_FB_3DFX_ACCEL is not set
+CONFIG_FB_VOODOO1=m
+CONFIG_FB_TRIDENT=m
+# CONFIG_FB_TRIDENT_ACCEL is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_E1356 is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=m
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+
+#
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_BIT32_EMUL=m
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+CONFIG_SND_OPL3_LIB=m
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# PCI devices
+#
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_ATIIXP is not set
+# CONFIG_SND_ATIIXP_MODEM is not set
+# CONFIG_SND_AU8810 is not set
+# CONFIG_SND_AU8820 is not set
+# CONFIG_SND_AU8830 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_BT87X is not set
+CONFIG_SND_CS46XX=m
+# CONFIG_SND_CS46XX_NEW_DSP is not set
+CONFIG_SND_CS4281=m
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_MIXART is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_MAESTRO3 is not set
+# CONFIG_SND_FM801 is not set
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VX222 is not set
+
+#
+# ALSA MIPS devices
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_USX2Y is not set
+
+#
+# PCMCIA devices
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+
+#
+# USB Host Controller Drivers
+#
+CONFIG_USB_EHCI_HCD=m
+# CONFIG_USB_EHCI_SPLIT_ISO is not set
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_AUDIO=m
+CONFIG_USB_BLUETOOTH_TTY=m
+CONFIG_USB_MIDI=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_RW_DETECT=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+CONFIG_USB_HIDINPUT=y
+CONFIG_HID_FF=y
+CONFIG_HID_PID=y
+CONFIG_LOGITECH_FF=y
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_USB_HIDDEV=y
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_AIPTEK=m
+CONFIG_USB_WACOM=m
+CONFIG_USB_KBTAB=m
+CONFIG_USB_POWERMATE=m
+CONFIG_USB_MTOUCH=m
+CONFIG_USB_EGALAX=m
+CONFIG_USB_XPAD=m
+CONFIG_USB_ATI_REMOTE=m
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_MDC800=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_HPUSBSCSI=m
+
+#
+# USB Multimedia devices
+#
+CONFIG_USB_VICAM=m
+CONFIG_USB_DSBR=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=m
+
+#
+# USB Host-to-Host Cables
+#
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_GENESYS=y
+CONFIG_USB_NET1080=y
+CONFIG_USB_PL2301=y
+CONFIG_USB_KC2190=y
+
+#
+# Intelligent USB Devices/Gadgets
+#
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_ZAURUS=y
+CONFIG_USB_CDCETHER=y
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_AX8817X=y
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_TIGL=m
+CONFIG_USB_AUERSWALD=m
+CONFIG_USB_RIO500=m
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+CONFIG_USB_LED=m
+CONFIG_USB_CYTHERM=m
+# CONFIG_USB_PHIDGETKIT is not set
+CONFIG_USB_PHIDGETSERVO=m
+CONFIG_USB_TEST=m
+
+#
+# USB ATM/DSL drivers
+#
+
+#
+# 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=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+CONFIG_REISERFS_FS=m
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+# CONFIG_JFS_DEBUG is not set
+CONFIG_JFS_STATISTICS=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_RT is not set
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_SECURITY=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_QUOTA=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=m
+CONFIG_QUOTACTL=y
+CONFIG_DNOTIFY=y
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_ZISOFS_FS=m
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_SYSFS=y
+CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS_XATTR=y
+CONFIG_DEVPTS_FS_SECURITY=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_TMPFS_SECURITY=y
+# 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_ASFS_FS is not set
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# 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 is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V4 is not set
+CONFIG_NFS_DIRECTIO=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V4 is not set
+CONFIG_NFSD_TCP=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS 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=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
+
+#
+# Profiling support
+#
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=m
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_CROSSCOMPILE is not set
+CONFIG_CMDLINE=""
+# CONFIG_SB1XXX_CORELIS 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=m
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DES=m
+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=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+CONFIG_CRC32=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,80 @@
+Source: kernel-patch-2.6.10-mips
+Section: devel
+Priority: optional
+Build-Depends: kernel-source-2.6.10 (>=2.6.10-3), kernel-package, debhelper (>=4.1.0), module-init-tools, dpatch, bzip2
+Maintainer: Debian kernel team <debian-kernel at lists.debian.org>
+Uploaders: Thiemo Seufer <ths at debian.org>
+Standards-Version: 3.6.1
+
+Package: kernel-headers-2.6.10-1
+Architecture: mips
+Section: devel
+Priority: optional
+Depends: coreutils, kernel-kbuild-2.6-3
+Provides: kernel-headers, kernel-headers-2.6
+Description: Header files related to Linux kernel version 2.6.10
+ This package provides kernel header files for version 2.6.10, for
+ sites that want the latest kernel headers. Please read
+ /usr/share/doc/kernel-headers-2.6.10-1/debian.README.gz
+ for details.
+
+Package: mips-tools
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: MIPS specific kernel tools
+ This package provides tools used on the MIPS architecture to convert
+ the kernel into an ECOFF image.
+
+Package: kernel-image-2.6.10-1-r4k-ip22
+Section: base
+Architecture: mips
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-2.6.10, arcboot (>=0.3.1)
+Description: Linux kernel image for 2.6.10-r4k-ip22
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for the SGI Indy and Indigo2.
+
+Package: kernel-image-2.6.10-1-r10k-ip27
+Section: base
+Architecture: mips
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-2.6.10
+Description: Linux kernel image for 2.6.10-r10k-ip27
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for the SGI Origin with R1X000 processors.
+
+Package: kernel-image-2.6.10-1-r5k-ip32
+Section: base
+Architecture: mips
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-2.6.10, arcboot (>=0.3.8)
+Description: Linux kernel image for 2.6.10-r5k-ip32
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for the SGI O2 with R5000/R5200/RM7000 processors.
+
+Package: kernel-image-2.6.10-1-sb1-swarm-bn
+Section: base
+Architecture: mips
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-2.6.10, sibyl
+Description: Linux kernel image for 2.6.10-sb1-swarm-bn
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for the Broadcom BCM91250A (aka SWARM), pass 2.2 and
+ later.
+

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r10k-ip27
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r10k-ip27	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r10k-ip27	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,12 @@
+Package: kernel-image-@@KERNVER@@-@@ABIVER@@-r10k-ip27
+Section: base
+Architecture: @@ARCH@@
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-@@KERNVER@@
+Description: Linux kernel image for @@KERNVER@@-r10k-ip27
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for the SGI Origin with R1X000 processors.

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r3k-kn02
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r3k-kn02	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r3k-kn02	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,14 @@
+Package: kernel-image-@@KERNVER@@-@@ABIVER@@-r3k-kn02
+Section: base
+Architecture: @@ARCH@@
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-@@KERNVER@@, delo
+Description: Linux kernel image for @@KERNVER@@-r3k-kn02
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for R3000 based DECstations with KN02 (or compatible)
+ mainboard, such as the DECstation 5000/1xx series with xx=20,25,33
+ and the DECstation 5000/240.

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r4k-ip22
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r4k-ip22	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r4k-ip22	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,12 @@
+Package: kernel-image-@@KERNVER@@-@@ABIVER@@-r4k-ip22
+Section: base
+Architecture: @@ARCH@@
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-@@KERNVER@@, arcboot (>=0.3.1)
+Description: Linux kernel image for @@KERNVER@@-r4k-ip22
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for the SGI Indy and Indigo2.

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r4k-kn04
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r4k-kn04	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r4k-kn04	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,14 @@
+Package: kernel-image-@@KERNVER@@-@@ABIVER@@-r4k-kn04
+Section: base
+Architecture: @@ARCH@@
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-@@KERNVER@@, delo
+Description: Linux kernel image for @@KERNVER@@-r4k-kn04
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for R4X00 based DECstations with KN04 (or compatible)
+ mainboard, such as the DECstation 5000/150, the Personal DECstation
+ 5000/50 and the DECstation 5000/260.

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r5k-cobalt
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r5k-cobalt	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r5k-cobalt	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,13 @@
+Package: kernel-image-@@KERNVER@@-@@ABIVER@@-r5k-cobalt
+Section: base
+Architecture: @@ARCH@@
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-@@KERNVER@@, colo
+Description: Linux kernel image for @@KERNVER@@-r5k-cobalt
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for MIPS based Cobalt machines (such as the Qube,
+ RaQ, Qube2 and RaQ2).

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r5k-ip32
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r5k-ip32	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r5k-ip32	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,12 @@
+Package: kernel-image-@@KERNVER@@-@@ABIVER@@-r5k-ip32
+Section: base
+Architecture: @@ARCH@@
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-@@KERNVER@@, arcboot (>=0.3.8)
+Description: Linux kernel image for @@KERNVER@@-r5k-ip32
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for the SGI O2 with R5000/R5200/RM7000 processors.

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r5k-lasat
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r5k-lasat	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/r5k-lasat	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,12 @@
+Package: kernel-image-@@KERNVER@@-@@ABIVER@@-r5k-lasat
+Section: base
+Architecture: @@ARCH@@
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-@@KERNVER@@
+Description: Linux kernel image for @@KERNVER@@-r5k-lasat
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for R5000 processors on the Lasat Masquerade Pro.

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/sb1-swarm-bn
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/sb1-swarm-bn	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/sb1-swarm-bn	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,13 @@
+Package: kernel-image-@@KERNVER@@-@@ABIVER@@-sb1-swarm-bn
+Section: base
+Architecture: @@ARCH@@
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-@@KERNVER@@, sibyl
+Description: Linux kernel image for @@KERNVER@@-sb1-swarm-bn
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for the Broadcom BCM91250A (aka SWARM), pass 2.2 and
+ later.

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/stub
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/stub	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/stub	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,26 @@
+Source: kernel-patch-@@KERNVER@@-mips
+Section: devel
+Priority: optional
+Build-Depends: kernel-source-@@KERNVER@@ (>=@@KERNVER@@-3), kernel-package, debhelper (>=4.1.0), module-init-tools, dpatch, bzip2
+Maintainer: Debian kernel team <debian-kernel at lists.debian.org>
+Uploaders: Thiemo Seufer <ths at debian.org>
+Standards-Version: 3.6.1
+
+Package: kernel-headers-@@KERNVER@@-@@ABIVER@@
+Architecture: @@ARCH@@
+Section: devel
+Priority: optional
+Depends: coreutils, kernel-kbuild-2.6-3
+Provides: kernel-headers, kernel-headers-2.6
+Description: Header files related to Linux kernel version @@KERNVER@@
+ This package provides kernel header files for version @@KERNVER@@, for
+ sites that want the latest kernel headers. Please read
+ /usr/share/doc/kernel-headers-@@KERNVER@@-@@ABIVER@@/debian.README.gz
+ for details.
+
+Package: mips-tools
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: MIPS specific kernel tools
+ This package provides tools used on the MIPS architecture to convert
+ the kernel into an ECOFF image.

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/xxs1500
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/xxs1500	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/control.in/xxs1500	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,12 @@
+Package: kernel-image-@@KERNVER@@-@@ABIVER@@-xxs1500
+Section: base
+Architecture: @@ARCH@@
+Priority: optional
+Provides: kernel-image, kernel-image-2.6
+Depends: initrd-tools (>= 0.1.76), coreutils, module-init-tools
+Suggests: kernel-doc-@@KERNVER@@
+Description: Linux kernel image for @@KERNVER@@-xxs1500
+ This package contains the Linux/MIPS kernel image, the System.map
+ file, and the modules built by the package.
+ .
+ This version is for the Au1500 based XXS1500 board.

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/copyright
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/copyright	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/copyright	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,14 @@
+This is the Debian GNU/Linux prepackaged version of diffs to the
+mainline kernel source for use on the MIPS architecture.  They come
+from the linux-mips.org cvs repository. For more information visit:
+		     <http://www.linux-mips.org>
+
+This package was created by Thiemo Seufer.
+
+Linux is copyrighted by Linus Torvalds and others, and is licensed
+under the GNU General Public License; these patches are under the
+same terms. On Debian GNU/Linux systems, the complete text of the
+GNU General Public License can be found in
+/usr/share/common-licenses/GPL.
+
+Linux® is a registered trademark of Linus Torvalds.

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/elf2ecoff.8
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/elf2ecoff.8	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/elf2ecoff.8	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,26 @@
+.TH "ELF2ECOFF" "8" "06 December 2001" "" ""
+.SH NAME
+elf2ecoff \- convert ELF binary to ECOFF binary
+.SH SYNOPSIS
+
+\fBelf2ecoff\fR \fIelf-executable\fR \fIecoff-executable\fR.
+
+.SH "DESCRIPTION"
+.PP
+This manual page documents briefly the
+\fBelf2ecoff\fR command
+.PP
+This manual page was written for the Debian GNU/Linux distribution
+because the original program does not have a manual page.
+.PP
+\fBelf2ecoff\fR is used on the Linux/MIPS architecture to convert
+an ELF kernel into an ECOFF image.
+.SH "AUTHOR"
+.PP
+This manual page was written by Guido Guenther <agx at debian.org> for
+the Debian GNU/Linux system (but may be used by others).  Permission is
+granted to copy, distribute and/or modify this document under
+the terms of the GNU Free Documentation
+License, Version 1.1 or any later version published by the Free
+Software Foundation; with no Invariant Sections, no Front-Cover
+Texts and no Back-Cover Texts.

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/flavours.mips
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/flavours.mips	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/flavours.mips	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,5 @@
+# Kernel flavours we build for mips
+r4k-ip22
+r10k-ip27
+r5k-ip32
+sb1-swarm-bn

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/flavours.mipsel
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/flavours.mipsel	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/flavours.mipsel	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,7 @@
+# Kernel flavours we build for mipsel
+#r3k-kn02
+#r4k-kn04
+#r5k-cobalt
+#r5k-lasat 
+sb1-swarm-bn
+#xxs1500

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/mips-tools.dirs
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/mips-tools.dirs	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/mips-tools.dirs	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1 @@
+/usr/bin

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/mips-tools.manpages
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/mips-tools.manpages	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/mips-tools.manpages	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1 @@
+debian/elf2ecoff.8

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/00_linux-mips.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/00_linux-mips.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/00_linux-mips.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,62141 @@
+#! /bin/sh -e
+## 00_linux-mips.dpatch by Thiemo Seufer <ths at debian.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Diff between kernel.org 2.6.10 and linux-mips.org, CVS HEAD,
+## DP: taken at 2005-01-11.
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p1 ${patch_opts} < $0;;
+    -unpatch) patch -R -p1 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+diff -urpNX dontdiff linux-2.6.10/Makefile linux-2.6.10-mips/Makefile
+--- linux-2.6.10/Makefile	2004-12-24 22:35:01.000000000 +0100
++++ linux-2.6.10-mips/Makefile	2004-12-28 20:06:06.000000000 +0100
+@@ -167,9 +167,7 @@ KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$
+ # then ARCH is assigned, getting whatever value it gets normally, and 
+ # SUBARCH is subsequently ignored.
+ 
+-SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+-				  -e s/arm.*/arm/ -e s/sa110/arm/ \
+-				  -e s/s390x/s390/ -e s/parisc64/parisc/ )
++SUBARCH := mips
+ 
+ # Cross compiling and selecting different set of gcc/bin-utils
+ # ---------------------------------------------------------------------------
+@@ -529,7 +527,7 @@ endif
+ include $(srctree)/arch/$(ARCH)/Makefile
+ 
+ # warn about C99 declaration after statement
+-CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
++#CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
+ 
+ # Default kernel image to build when no specific target is given.
+ # KBUILD_IMAGE may be overruled on the commandline or
+diff -urpNX dontdiff linux-2.6.10/arch/mips/Kconfig linux-2.6.10-mips/arch/mips/Kconfig
+--- linux-2.6.10/arch/mips/Kconfig	2004-12-24 22:34:45.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/Kconfig	2005-01-11 00:40:22.000000000 +0100
+@@ -29,6 +29,10 @@ menu "Machine selection"
+ 
+ config MACH_JAZZ
+ 	bool "Support for the Jazz family of machines"
++	select ARC
++	select ARC32
++	select GENERIC_ISA_DMA
++	select I8259
+ 	select ISA
+ 	help
+ 	 This a family of machines based on the MIPS R4030 chipset which was
+@@ -69,6 +73,21 @@ config OLIVETTI_M700
+ config MACH_VR41XX
+ 	bool "Support for NEC VR41XX-based machines"
+ 
++config NEC_CMBVR4133
++	bool "Support for NEC CMB-VR4133"
++	depends on MACH_VR41XX
++	select CPU_VR41XX
++	select DMA_NONCOHERENT
++	select IRQ_CPU
++	select HW_HAS_PCI
++	select PCI_VR41XX
++
++config ROCKHOPPER
++	bool "Support for Rockhopper baseboard"
++	depends on NEC_CMBVR4133
++	select I8259
++	select HAVE_STD_PC_SERIAL_PORT
++
+ config CASIO_E55
+ 	bool "Support for CASIO CASSIOPEIA E-10/15/55/65"
+ 	depends on MACH_VR41XX
+@@ -103,6 +122,10 @@ config TANBAC_TB0229
+ 	  The TANBAC TB0229 (VR4131DIMM) is a MIPS-based platform manufactured by TANBAC.
+ 	  Please refer to <http://www.tanbac.co.jp/> about VR4131DIMM.
+ 
++config TANBAC_TB0219
++	bool "Added TANBAC TB0219 Base board support"
++	depends on TANBAC_TB0229
++
+ config VICTOR_MPC30X
+ 	bool "Support for Victor MP-C303/304"
+ 	select DMA_NONCOHERENT
+@@ -145,10 +168,12 @@ config MIPS_COBALT
+ 	depends on EXPERIMENTAL
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
++	select I8259
+ 	select IRQ_CPU
+ 
+ config MACH_DECSTATION
+ 	bool "Support for DECstations"
++	select BOOT_ELF32
+ 	select DMA_NONCOHERENT
+ 	select IRQ_CPU
+ 	depends on MIPS32 || EXPERIMENTAL
+@@ -172,6 +197,7 @@ config MIPS_EV64120
+ 	depends on EXPERIMENTAL
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
++	select MIPS_GT64120
+ 	help
+ 	  This is an evaluation board based on the Galileo GT-64120
+ 	  single-chip system controller that contains a MIPS R5000 compatible
+@@ -213,6 +239,7 @@ config LASAT
+ 	bool "Support for LASAT Networks platforms"
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
++	select MIPS_GT64120
+ 	select R5000_CPU_SCACHE
+ 
+ config PICVUE
+@@ -253,8 +280,10 @@ config IT8172_REVC
+ 
+ config MIPS_ATLAS
+ 	bool "Support for MIPS Atlas board"
++	select BOOT_ELF32
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
++	select MIPS_GT64120
+ 	select SWAP_IO_SPACE
+ 	help
+ 	  This enables support for the QED R5231-based MIPS Atlas evaluation
+@@ -262,9 +291,12 @@ config MIPS_ATLAS
+ 
+ config MIPS_MALTA
+ 	bool "Support for MIPS Malta board"
++	select BOOT_ELF32
+ 	select HAVE_STD_PC_SERIAL_PORT
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
++	select I8259
++	select MIPS_GT64120
+ 	select SWAP_IO_SPACE
+ 	help
+ 	  This enables support for the VR5000-based MIPS Malta evaluation
+@@ -282,6 +314,7 @@ config MOMENCO_OCELOT
+ 	select HW_HAS_PCI
+ 	select IRQ_CPU
+ 	select IRQ_CPU_RM7K
++	select MIPS_GT64120
+ 	select RM7000_CPU_SCACHE
+ 	select SWAP_IO_SPACE
+ 	help
+@@ -316,6 +349,7 @@ config MOMENCO_OCELOT_C
+ 
+ config MOMENCO_OCELOT_3
+ 	bool "Support for Momentum Ocelot-3 board"
++	select BOOT_ELF32
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
+ 	select IRQ_CPU
+@@ -330,6 +364,7 @@ config MOMENCO_OCELOT_3
+ 
+ config MOMENCO_JAGUAR_ATX
+ 	bool "Support for Momentum Jaguar board"
++	select BOOT_ELF32
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
+ 	select IRQ_CPU
+@@ -356,6 +391,7 @@ config PMC_YOSEMITE
+ 	select HW_HAS_PCI
+ 	select IRQ_CPU
+ 	select IRQ_CPU_RM7K
++	select IRQ_CPU_RM9K
+ 	select SWAP_IO_SPACE
+ 	help
+ 	  Yosemite is an evaluation board for the RM9000x2 processor
+@@ -372,6 +408,7 @@ config DDB5074
+ 	select HAVE_STD_PC_SERIAL_PORT
+ 	select HW_HAS_PCI
+ 	select IRQ_CPU
++	select I8259
+ 	select ISA
+ 	help
+ 	  This enables support for the VR5000-based NEC DDB Vrc-5074
+@@ -383,6 +420,7 @@ config DDB5476
+ 	select HAVE_STD_PC_SERIAL_PORT
+ 	select HW_HAS_PCI
+ 	select IRQ_CPU
++	select I8259
+ 	select ISA
+ 	help
+ 	  This enables support for the R5432-based NEC DDB Vrc-5476
+@@ -396,6 +434,7 @@ config DDB5477
+ 	bool "Support for NEC DDB Vrc-5477"
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
++	select I8259
+ 	select IRQ_CPU
+ 	help
+ 	  This enables support for the R5432-based NEC DDB Vrc-5477,
+@@ -416,6 +455,9 @@ config NEC_OSPREY
+ 
+ config SGI_IP22
+ 	bool "Support for SGI IP22 (Indy/Indigo2)"
++	select ARC
++	select ARC32
++	select BOOT_ELF32
+ 	select DMA_NONCOHERENT
+ 	select IP22_CPU_SCACHE
+ 	select IRQ_CPU
+@@ -428,6 +470,8 @@ config SGI_IP22
+ config SGI_IP27
+ 	bool "Support for SGI IP27 (Origin200/2000)"
+ 	depends on MIPS64
++	select ARC
++	select ARC64
+ 	select DMA_IP27
+ 	select HW_HAS_PCI
+ 	select PCI_DOMAINS
+@@ -494,6 +538,9 @@ config REPLICATE_EXHANDLERS
+ config SGI_IP32
+ 	bool "Support for SGI IP32 (O2) (EXPERIMENTAL)"
+ 	depends on MIPS64 && EXPERIMENTAL
++	select ARC
++	select ARC32
++	select BOOT_ELF32
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
+ 	select R5000_CPU_SCACHE
+@@ -508,31 +555,31 @@ config SOC_AU1X00
+ choice
+ 	prompt "Au1X00 SOC Type"
+ 	depends on SOC_AU1X00
+-        help
+-           Say Y here to enable support for one of three AMD/Alchemy
+-           SOCs. For additional documentation see www.amd.com.
++	help
++	  Say Y here to enable support for one of three AMD/Alchemy
++	  SOCs. For additional documentation see www.amd.com.
+ 
+ config SOC_AU1000
+-        bool "SOC_AU1000"
++	bool "SOC_AU1000"
+ config SOC_AU1100
+-        bool "SOC_AU1100"
++	bool "SOC_AU1100"
+ config SOC_AU1500
+-        bool "SOC_AU1500"
++	bool "SOC_AU1500"
+ config SOC_AU1550
+-        bool "SOC_AU1550"
++	bool "SOC_AU1550"
+ 
+ endchoice
+ 
+ choice
+-        prompt "AMD/Alchemy Au1x00 board support"
+-        depends on SOC_AU1X00
++	prompt "AMD/Alchemy Au1x00 board support"
++	depends on SOC_AU1X00
+ 	help
+ 	  These are evaluation boards built by AMD/Alchemy to
+ 	  showcase their Au1X00 Internet Edge Processors. The SOC design
+ 	  is based on the MIPS32 architecture running at 266/400/500MHz
+-          with many integrated peripherals. Further information can be
+-          found at their website, <http://www.amd.com/>. Say Y here if you
+-          wish to build a kernel for this platform.
++	  with many integrated peripherals. Further information can be
++	  found at their website, <http://www.amd.com/>. Say Y here if you
++	  wish to build a kernel for this platform.
+ 
+ config MIPS_PB1000
+ 	bool "PB1000 board"
+@@ -604,6 +651,7 @@ config MIPS_XXS1500
+ config MIPS_MTX1
+ 	bool "4G Systems MTX-1 board"
+ 	depends on SOC_AU1500
++	select HW_HAS_PCI
+ 	select DMA_NONCOHERENT
+ 
+ endchoice
+@@ -611,6 +659,7 @@ endchoice
+ config SIBYTE_SB1xxx_SOC
+ 	bool "Support for Broadcom BCM1xxx SOCs (EXPERIMENTAL)"
+ 	depends on EXPERIMENTAL
++	select BOOT_ELF32
+ 	select DMA_COHERENT
+ 	select SWAP_IO_SPACE
+ 
+@@ -721,6 +770,7 @@ choice
+ config CPU_SB1_PASS_1
+ 	bool "1250 Pass1"
+ 	depends on SIBYTE_SB1250
++	select CPU_HAS_PREFETCH
+ 
+ config CPU_SB1_PASS_2_1250
+ 	bool "1250 An"
+@@ -732,12 +782,14 @@ config CPU_SB1_PASS_2_1250
+ config CPU_SB1_PASS_2_2
+ 	bool "1250 Bn"
+ 	depends on SIBYTE_SB1250
++	select CPU_HAS_PREFETCH
+ 	help
+ 	  Also called BCM1250 Pass 2.2
+ 
+ config CPU_SB1_PASS_4
+ 	bool "1250 Cn"
+ 	depends on SIBYTE_SB1250
++	select CPU_HAS_PREFETCH
+ 	help
+ 	  Also called BCM1250 Pass 3
+ 
+@@ -749,6 +801,7 @@ config CPU_SB1_PASS_2_112x
+ config CPU_SB1_PASS_3
+ 	bool "112x An"
+ 	depends on SIBYTE_BCM112X
++	select CPU_HAS_PREFETCH
+ 
+ endchoice
+ 
+@@ -819,9 +872,14 @@ config SIBYTE_TBPROF
+ 
+ config SNI_RM200_PCI
+ 	bool "Support for SNI RM200 PCI"
++	select ARC
++	select ARC32
++	select BOOT_ELF32
+ 	select DMA_NONCOHERENT
++	select GENERIC_ISA_DMA
+ 	select HAVE_STD_PC_SERIAL_PORT
+ 	select HW_HAS_PCI
++	select I8259
+ 	select ISA
+ 	help
+ 	  The SNI RM200 PCI was a MIPS-based platform manufactured by Siemens
+@@ -861,8 +919,6 @@ config HAVE_DEC_LOCK
+ #
+ config ARC
+ 	bool
+-	depends on SNI_RM200_PCI || SGI_IP32 || SGI_IP27 || SGI_IP22 || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61
+-	default y
+ 
+ config	DMA_COHERENT
+ 	bool
+@@ -880,13 +936,9 @@ config EARLY_PRINTK
+ 
+ config GENERIC_ISA_DMA
+ 	bool
+-	depends on SNI_RM200_PCI || MIPS_MAGNUM_4000 || OLIVETTI_M700 || ACER_PICA_61 || MIPS_MALTA
+-	default y
+ 
+ config I8259
+ 	bool
+-	depends on SNI_RM200_PCI || DDB5477 || DDB5476 || DDB5074 || MACH_JAZZ || MIPS_MALTA || MIPS_COBALT
+-	default y
+ 
+ config LIMITED_DMA
+ 	bool
+@@ -925,6 +977,9 @@ config IRQ_CPU
+ config IRQ_CPU_RM7K
+ 	bool
+ 
++config IRQ_CPU_RM9K
++	bool
++
+ config IRQ_MV64340
+ 	bool
+ 
+@@ -945,8 +1000,6 @@ config MIPS_GT64111
+ 
+ config MIPS_GT64120
+ 	bool
+-	depends on MIPS_EV64120 || MIPS_EV96100 || LASAT || MIPS_ATLAS || MIPS_MALTA || MOMENCO_OCELOT
+-	default y
+ 
+ config MIPS_TX3927
+ 	bool
+@@ -986,6 +1039,9 @@ config SYSCLK_100
+ 
+ endchoice
+ 
++config ARC32
++	bool
++
+ config AU1000_USB_DEVICE
+ 	bool
+ 	depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000
+@@ -993,11 +1049,7 @@ config AU1000_USB_DEVICE
+ 
+ config MIPS_GT96100
+ 	bool
+-	depends on MIPS_EV96100
+-	default y
+-	help
+-	  Say Y here to support the Galileo Technology GT96100 communications
+-	  controller card.  There is a web page at <http://www.galileot.com/>.
++	select MIPS_GT64120
+ 
+ config IT8172_CIR
+ 	bool
+@@ -1011,8 +1063,6 @@ config IT8712
+ 
+ config BOOT_ELF32
+ 	bool
+-	depends on MACH_DECSTATION || MIPS_ATLAS || MIPS_MALTA || MOMENCO_JAGUAR_ATX || MOMENCO_OCELOT_3 || SIBYTE_SB1xxx_SOC || SGI_IP32 || SGI_IP22 || SNI_RM200_PCI
+-	default y
+ 
+ config MIPS_L1_CACHE_SHIFT
+ 	int
+@@ -1020,46 +1070,6 @@ config MIPS_L1_CACHE_SHIFT
+ 	default "7" if SGI_IP27
+ 	default "5"
+ 
+-config ARC32
+-	bool
+-	depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP32
+-	default y
+-
+-config FB
+-	bool
+-	depends on MIPS_MAGNUM_4000 || OLIVETTI_M700
+-	default y
+-	---help---
+-	  The frame buffer device provides an abstraction for the graphics
+-	  hardware. It represents the frame buffer of some video hardware and
+-	  allows application software to access the graphics hardware through
+-	  a well-defined interface, so the software doesn't need to know
+-	  anything about the low-level (hardware register) stuff.
+-
+-	  Frame buffer devices work identically across the different
+-	  architectures supported by Linux and make the implementation of
+-	  application programs easier and more portable; at this point, an X
+-	  server exists which uses the frame buffer device exclusively.
+-	  On several non-X86 architectures, the frame buffer device is the
+-	  only way to use the graphics hardware.
+-
+-	  The device is accessed through special device nodes, usually located
+-	  in the /dev directory, i.e. /dev/fb*.
+-
+-	  You need an utility program called fbset to make full use of frame
+-	  buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
+-	  and the Framebuffer-HOWTO at <http://www.tldp.org/docs.html#howto>
+-	  for more information.
+-
+-	  Say Y here and to the driver for your graphics board below if you
+-	  are compiling a kernel for a non-x86 architecture.
+-
+-	  If you are compiling for the x86 architecture, you can say Y if you
+-	  want to play with it, but it is not essential. Please note that
+-	  running graphical applications that directly touch the hardware
+-	  (e.g. an accelerated X server) and that are not frame buffer
+-	  device-aware may cause unexpected results. If unsure, say N.
+-
+ config HAVE_STD_PC_SERIAL_PORT
+ 	bool
+ 
+@@ -1084,19 +1094,12 @@ config ARC_PROMLIB
+ 
+ config ARC64
+ 	bool
+-	depends on SGI_IP27
+-	default y
+ 
+ config BOOT_ELF64
+ 	bool
+ 	depends on SGI_IP27
+ 	default y
+ 
+-#config MAPPED_PCI_IO y
+-#	bool
+-#	depends on SGI_IP27
+-#	default y
+-
+ config QL_ISP_A64
+ 	bool
+ 	depends on SGI_IP27
+@@ -1107,10 +1110,6 @@ config TOSHIBA_BOARDS
+ 	depends on TOSHIBA_JMR3927 || TOSHIBA_RBTX4927
+ 	default y
+ 
+-config TANBAC_TB0219
+-	bool "Added TANBAC TB0219 Base board support"
+-	depends on TANBAC_TB0229
+-
+ endmenu
+ 
+ menu "CPU selection"
+@@ -1121,9 +1120,11 @@ choice
+ 
+ config CPU_MIPS32
+ 	bool "MIPS32"
++	select CPU_HAS_PREFETCH
+ 
+ config CPU_MIPS64
+ 	bool "MIPS64"
++	select CPU_HAS_PREFETCH
+ 
+ config CPU_R3000
+ 	bool "R3000"
+@@ -1185,20 +1186,24 @@ config CPU_NEVADA
+ config CPU_R8000
+ 	bool "R8000"
+ 	depends on MIPS64 && EXPERIMENTAL
++	select CPU_HAS_PREFETCH
+ 	help
+ 	  MIPS Technologies R8000 processors.  Note these processors are
+ 	  uncommon and the support for them is incomplete.
+ 
+ config CPU_R10000
+ 	bool "R10000"
++	select CPU_HAS_PREFETCH
+ 	help
+ 	  MIPS Technologies R10000-series processors.
+ 
+ config CPU_RM7000
+ 	bool "RM7000"
++	select CPU_HAS_PREFETCH
+ 
+ config CPU_RM9000
+ 	bool "RM9000"
++	select CPU_HAS_PREFETCH
+ 
+ config CPU_SB1
+ 	bool "SB1"
+@@ -1273,8 +1278,7 @@ config SIBYTE_DMA_PAGEOPS
+ 	  SiByte Linux port.  Seems to give a small performance benefit.
+ 
+ config CPU_HAS_PREFETCH
+-	bool "Enable prefetches" if CPU_SB1 && !CPU_SB1_PASS_2
+-	default y if CPU_MIPS32 || CPU_MIPS64 || CPU_RM7000 || CPU_RM9000 || CPU_R10000
++	bool
+ 
+ config VTAG_ICACHE
+ 	bool "Support for Virtual Tagged I-cache" if CPU_MIPS64 || CPU_MIPS32
+@@ -1579,6 +1583,8 @@ source "drivers/Kconfig"
+ 
+ source "fs/Kconfig"
+ 
++source "arch/mips/oprofile/Kconfig"
++
+ source "arch/mips/Kconfig.debug"
+ 
+ source "security/Kconfig"
+diff -urpNX dontdiff linux-2.6.10/arch/mips/Makefile linux-2.6.10-mips/arch/mips/Makefile
+--- linux-2.6.10/arch/mips/Makefile	2004-12-24 22:33:49.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/Makefile	2005-01-11 00:40:22.000000000 +0100
+@@ -482,6 +482,12 @@ core-$(CONFIG_MACH_VR41XX)	+= arch/mips/
+ cflags-$(CONFIG_MACH_VR41XX)	+= -Iinclude/asm-mips/mach-vr41xx
+ 
+ #
++# NEC VR4133
++#
++core-$(CONFIG_NEC_CMBVR4133)	+= arch/mips/vr41xx/nec-cmbvr4133/
++load-$(CONFIG_NEC_CMBVR4133)	+= 0xffffffff80100000
++
++#
+ # ZAO Networks Capcella (VR4131)
+ #
+ core-$(CONFIG_ZAO_CAPCELLA)	+= arch/mips/vr41xx/zao-capcella/
+@@ -673,6 +679,8 @@ libs-$(CONFIG_MIPS64)	+= arch/mips/lib-6
+ 
+ core-y			+= arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/
+ 
++drivers-$(CONFIG_OPROFILE)	+= arch/mips/oprofile/
++
+ ifdef CONFIG_LASAT
+ rom.bin rom.sw: vmlinux
+ 	$(call descend,arch/mips/lasat/image,$@)
+diff -urpNX dontdiff linux-2.6.10/arch/mips/au1000/common/dbdma.c linux-2.6.10-mips/arch/mips/au1000/common/dbdma.c
+--- linux-2.6.10/arch/mips/au1000/common/dbdma.c	2004-12-24 22:34:29.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/au1000/common/dbdma.c	2005-01-10 15:13:22.000000000 +0100
+@@ -370,7 +370,7 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int 
+ 	 * and if we try that first we are likely to not waste larger
+ 	 * slabs of memory.
+ 	 */
+-	desc_base = kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL);
++	desc_base = (u32)kmalloc(entries * sizeof(au1x_ddma_desc_t), GFP_KERNEL);
+ 	if (desc_base == 0)
+ 		return 0;
+ 
+@@ -381,7 +381,7 @@ au1xxx_dbdma_ring_alloc(u32 chanid, int 
+ 		kfree((const void *)desc_base);
+ 		i = entries * sizeof(au1x_ddma_desc_t);
+ 		i += (sizeof(au1x_ddma_desc_t) - 1);
+-		if ((desc_base = kmalloc(i, GFP_KERNEL)) == 0)
++		if ((desc_base = (u32)kmalloc(i, GFP_KERNEL)) == 0)
+ 			return 0;
+ 
+ 		desc_base = ALIGN_ADDR(desc_base, sizeof(au1x_ddma_desc_t));
+diff -urpNX dontdiff linux-2.6.10/arch/mips/au1000/common/pci.c linux-2.6.10-mips/arch/mips/au1000/common/pci.c
+--- linux-2.6.10/arch/mips/au1000/common/pci.c	2004-12-24 22:35:25.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/au1000/common/pci.c	2004-12-03 12:31:40.000000000 +0100
+@@ -78,10 +78,13 @@ static int __init au1x_pci_setup(void)
+ 
+ #ifdef CONFIG_DMA_NONCOHERENT
+ 	/* 
+-	 *  Set the NC bit in controller for pre-AC silicon
++         *  Set the NC bit in controller for Au1500 pre-AC silicon
+ 	 */
+-	au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG);
+-	printk("Non-coherent PCI accesses enabled\n");
++	u32 prid = read_c0_prid();
++	if ( (prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
++	       au_writel( 1<<16 | au_readl(Au1500_PCI_CFG), Au1500_PCI_CFG);
++	       printk("Non-coherent PCI accesses enabled\n");
++	}
+ #endif
+ 
+ 	set_io_port_base(virt_io_addr);
+diff -urpNX dontdiff linux-2.6.10/arch/mips/au1000/common/time.c linux-2.6.10-mips/arch/mips/au1000/common/time.c
+--- linux-2.6.10/arch/mips/au1000/common/time.c	2004-12-24 22:34:31.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/au1000/common/time.c	2005-01-10 15:13:22.000000000 +0100
+@@ -304,8 +304,7 @@ unsigned long cal_r4koff(void)
+ 
+ /* This is for machines which generate the exact clock. */
+ #define USECS_PER_JIFFY (1000000/HZ)
+-#define USECS_PER_JIFFY_FRAC (0x100000000*1000000/HZ&0xffffffff)
+-
++#define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff)
+ 
+ static unsigned long
+ div64_32(unsigned long v1, unsigned long v2, unsigned long v3)
+@@ -407,10 +406,6 @@ void au1xxx_timer_setup(struct irqaction
+ 	r4k_cur = (read_c0_count() + r4k_offset);
+ 	write_c0_compare(r4k_cur);
+ 
+-	/* no RTC on the pb1000 */
+-	xtime.tv_sec = 0;
+-	//xtime.tv_usec = 0;
+-
+ #ifdef CONFIG_PM
+ 	/*
+ 	 * setup counter 0, since it keeps ticking after a
+diff -urpNX dontdiff linux-2.6.10/arch/mips/au1000/mtx-1/board_setup.c linux-2.6.10-mips/arch/mips/au1000/mtx-1/board_setup.c
+--- linux-2.6.10/arch/mips/au1000/mtx-1/board_setup.c	2004-12-24 22:33:51.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/au1000/mtx-1/board_setup.c	2004-12-03 12:31:40.000000000 +0100
+@@ -34,24 +34,24 @@
+ #include <linux/ioport.h>
+ #include <linux/mm.h>
+ #include <linux/console.h>
+-#include <linux/mc146818rtc.h>
+ #include <linux/delay.h>
+ 
+ #include <asm/cpu.h>
+ #include <asm/bootinfo.h>
+ #include <asm/irq.h>
+-#include <asm/keyboard.h>
+ #include <asm/mipsregs.h>
+ #include <asm/reboot.h>
+ #include <asm/pgtable.h>
+-#include <asm/au1000.h>
++#include <asm/mach-au1x00/au1000.h>
+ 
+-extern struct rtc_ops no_rtc_ops;
++void board_reset (void)
++{
++	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
++	au_writel(0x00000000, 0xAE00001C);
++}
+ 
+ void __init board_setup(void)
+ {
+-	rtc_ops = &no_rtc_ops;
+-
+ #if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
+ #ifdef CONFIG_AU1X00_USB_DEVICE
+ 	// 2nd USB port is USB device
+diff -urpNX dontdiff linux-2.6.10/arch/mips/au1000/mtx-1/init.c linux-2.6.10-mips/arch/mips/au1000/mtx-1/init.c
+--- linux-2.6.10/arch/mips/au1000/mtx-1/init.c	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/au1000/mtx-1/init.c	2004-12-03 12:31:40.000000000 +0100
+@@ -50,25 +50,24 @@ const char *get_system_type(void)
+ 	return "MTX-1";
+ }
+ 
+-int __init prom_init(int argc, char **argv, char **envp, int *prom_vec)
++void __init prom_init(void)
+ {
+ 	unsigned char *memsize_str;
+ 	unsigned long memsize;
+ 
+-	prom_argc = argc;
+-	prom_argv = argv;
+-	prom_envp = envp;
++	prom_argc = fw_arg0;
++	prom_argv = (char **) fw_arg1;
++	prom_envp = (char **) fw_arg2;
+ 
+ 	mips_machgroup = MACH_GROUP_ALCHEMY;
+ 	mips_machtype = MACH_MTX1;	/* set the platform # */
++	
+ 	prom_init_cmdline();
+ 
+ 	memsize_str = prom_getenv("memsize");
+-	if (!memsize_str) {
++	if (!memsize_str)
+ 		memsize = 0x04000000;
+-	} else {
++	else
+ 		memsize = simple_strtol(memsize_str, NULL, 0);
+-	}
+ 	add_memory_region(0, memsize, BOOT_MEM_RAM);
+-	return 0;
+ }
+diff -urpNX dontdiff linux-2.6.10/arch/mips/au1000/mtx-1/irqmap.c linux-2.6.10-mips/arch/mips/au1000/mtx-1/irqmap.c
+--- linux-2.6.10/arch/mips/au1000/mtx-1/irqmap.c	2004-12-24 22:34:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/au1000/mtx-1/irqmap.c	2004-12-03 12:31:40.000000000 +0100
+@@ -45,12 +45,14 @@
+ #include <asm/io.h>
+ #include <asm/mipsregs.h>
+ #include <asm/system.h>
+-#include <asm/au1000.h>
++#include <asm/mach-au1x00/au1000.h>
+ 
+-/* Need to define this.
+-*/
+ au1xxx_irq_map_t au1xxx_irq_map[] = {
+-	{ 0. 0. 0}
++       { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0},
++       { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
++       { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
++       { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
++       { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
+ };
+ 
+-int au1xxx_nr_irqs = 0;
++int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t);
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/atlas_defconfig linux-2.6.10-mips/arch/mips/configs/atlas_defconfig
+--- linux-2.6.10/arch/mips/configs/atlas_defconfig	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/atlas_defconfig	2004-12-28 20:06:20.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:55 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:51 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -89,7 +89,6 @@ CONFIG_MIPS_GT64120=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -176,6 +175,7 @@ CONFIG_BLK_DEV_LOOP=y
+ # 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=4096
+ # CONFIG_BLK_DEV_INITRD is not set
+ CONFIG_INITRAMFS_SOURCE=""
+@@ -253,7 +253,6 @@ CONFIG_BLK_DEV_SD=y
+ # CONFIG_SCSI_QLOGIC_ISP is not set
+ # CONFIG_SCSI_QLOGIC_FC is not set
+ # CONFIG_SCSI_QLOGIC_1280 is not set
+-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
+ CONFIG_SCSI_QLA2XXX=y
+ # CONFIG_SCSI_QLA21XX is not set
+ # CONFIG_SCSI_QLA22XX is not set
+@@ -513,7 +512,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -544,6 +542,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -564,11 +563,20 @@ 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
+@@ -661,6 +669,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/capcella_defconfig linux-2.6.10-mips/arch/mips/configs/capcella_defconfig
+--- linux-2.6.10/arch/mips/configs/capcella_defconfig	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/capcella_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:55 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:51 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -58,6 +58,7 @@ CONFIG_KMOD=y
+ #
+ # CONFIG_MACH_JAZZ is not set
+ CONFIG_MACH_VR41XX=y
++# CONFIG_NEC_CMBVR4133 is not set
+ # CONFIG_CASIO_E55 is not set
+ # CONFIG_IBM_WORKPAD is not set
+ # CONFIG_TANBAC_TB0226 is not set
+@@ -98,7 +99,6 @@ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -180,6 +180,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -484,7 +485,6 @@ CONFIG_WATCHDOG=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -515,6 +515,7 @@ CONFIG_WATCHDOG=y
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -535,11 +536,20 @@ 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
+@@ -633,6 +643,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/cobalt_defconfig linux-2.6.10-mips/arch/mips/configs/cobalt_defconfig
+--- linux-2.6.10/arch/mips/configs/cobalt_defconfig	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/cobalt_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:55 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:52 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -86,7 +86,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_GT64111=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -171,6 +170,7 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=y
+@@ -459,7 +459,6 @@ CONFIG_COBALT_LCD=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -490,6 +489,7 @@ CONFIG_COBALT_LCD=y
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -510,11 +510,20 @@ 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
+@@ -609,6 +618,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/db1000_defconfig linux-2.6.10-mips/arch/mips/configs/db1000_defconfig
+--- linux-2.6.10/arch/mips/configs/db1000_defconfig	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/db1000_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:56 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:52 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -105,7 +105,6 @@ CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -204,6 +203,7 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -479,7 +479,6 @@ CONFIG_RTC=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ 
+ #
+@@ -515,6 +514,7 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -534,11 +534,20 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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
+@@ -686,6 +695,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ # CONFIG_NLS_UTF8 is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/db1100_defconfig linux-2.6.10-mips/arch/mips/configs/db1100_defconfig
+--- linux-2.6.10/arch/mips/configs/db1100_defconfig	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/db1100_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:56 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:52 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -105,7 +105,6 @@ CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -202,6 +201,7 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -474,7 +474,6 @@ CONFIG_RTC=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ 
+ #
+@@ -510,6 +509,7 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -529,11 +529,20 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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
+@@ -681,6 +690,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ # CONFIG_NLS_UTF8 is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/db1500_defconfig linux-2.6.10-mips/arch/mips/configs/db1500_defconfig
+--- linux-2.6.10/arch/mips/configs/db1500_defconfig	2004-12-24 22:34:32.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/db1500_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:56 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:53 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -106,7 +106,6 @@ CONFIG_DMA_COHERENT=y
+ CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -288,6 +287,7 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_UB is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -609,7 +609,6 @@ CONFIG_RTC=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ 
+ #
+@@ -645,6 +644,7 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Sound
+@@ -705,6 +705,7 @@ CONFIG_USB_ARCH_HAS_OHCI=y
+ # CONFIG_USB_EHCI_HCD is not set
+ CONFIG_USB_OHCI_HCD=y
+ # CONFIG_USB_UHCI_HCD is not set
++# CONFIG_USB_SL811_HCD is not set
+ 
+ #
+ # USB Device Class drivers
+@@ -714,6 +715,10 @@ CONFIG_USB_OHCI_HCD=y
+ # CONFIG_USB_MIDI is not set
+ # CONFIG_USB_ACM is not set
+ # CONFIG_USB_PRINTER is not set
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
++#
+ # CONFIG_USB_STORAGE is not set
+ 
+ #
+@@ -789,6 +794,11 @@ CONFIG_USB_HIDINPUT=y
+ # CONFIG_USB_GADGET is not set
+ 
+ #
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
+ # File systems
+ #
+ CONFIG_EXT2_FS=y
+@@ -938,6 +948,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ # CONFIG_NLS_UTF8 is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/db1550_defconfig linux-2.6.10-mips/arch/mips/configs/db1550_defconfig
+--- linux-2.6.10/arch/mips/configs/db1550_defconfig	2004-12-24 22:34:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/db1550_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:57 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:53 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -106,7 +106,6 @@ CONFIG_DMA_COHERENT=y
+ CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -291,6 +290,7 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -649,7 +649,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ 
+ #
+@@ -685,6 +684,7 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Sound
+@@ -699,11 +699,20 @@ 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
+@@ -853,6 +862,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ # CONFIG_NLS_UTF8 is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/ddb5476_defconfig linux-2.6.10-mips/arch/mips/configs/ddb5476_defconfig
+--- linux-2.6.10/arch/mips/configs/ddb5476_defconfig	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/ddb5476_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:57 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:54 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -86,7 +86,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_DDB5XXX_COMMON=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-CONFIG_FB=y
+ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+ 
+ #
+@@ -174,6 +173,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=y
+@@ -478,7 +478,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -509,6 +508,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++CONFIG_FB=y
+ # CONFIG_FB_MODE_HELPERS is not set
+ # CONFIG_FB_TILEBLITTING is not set
+ # CONFIG_FB_CIRRUS is not set
+@@ -558,11 +558,20 @@ 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
+@@ -654,6 +663,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/ddb5477_defconfig linux-2.6.10-mips/arch/mips/configs/ddb5477_defconfig
+--- linux-2.6.10/arch/mips/configs/ddb5477_defconfig	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/ddb5477_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:58 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:54 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -87,7 +87,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_DDB5XXX_COMMON=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -171,6 +170,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=y
+@@ -460,7 +460,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -491,6 +490,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -511,11 +511,20 @@ 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
+@@ -609,6 +618,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/decstation_defconfig linux-2.6.10-mips/arch/mips/configs/decstation_defconfig
+--- linux-2.6.10/arch/mips/configs/decstation_defconfig	2004-12-24 22:35:01.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/decstation_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:58 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:54 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -92,7 +92,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=4
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -166,6 +165,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_LOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -219,7 +219,6 @@ CONFIG_SCSI_CONSTANTS=y
+ CONFIG_SCSI_DECNCR=y
+ # CONFIG_SCSI_DECSII is not set
+ # CONFIG_SCSI_SATA is not set
+-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
+ # CONFIG_SCSI_DEBUG is not set
+ 
+ #
+@@ -434,7 +433,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -465,6 +463,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -484,11 +483,20 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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
+@@ -590,6 +598,11 @@ CONFIG_ULTRIX_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/e55_defconfig linux-2.6.10-mips/arch/mips/configs/e55_defconfig
+--- linux-2.6.10/arch/mips/configs/e55_defconfig	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/e55_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:58 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:55 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -58,6 +58,7 @@ CONFIG_KMOD=y
+ #
+ # CONFIG_MACH_JAZZ is not set
+ CONFIG_MACH_VR41XX=y
++# CONFIG_NEC_CMBVR4133 is not set
+ CONFIG_CASIO_E55=y
+ # CONFIG_IBM_WORKPAD is not set
+ # CONFIG_TANBAC_TB0226 is not set
+@@ -97,7 +98,6 @@ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -173,6 +173,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_LOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -463,7 +464,6 @@ CONFIG_WATCHDOG=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -494,6 +494,7 @@ CONFIG_WATCHDOG=y
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -514,11 +515,20 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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
+@@ -611,6 +621,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/ev64120_defconfig linux-2.6.10-mips/arch/mips/configs/ev64120_defconfig
+--- linux-2.6.10/arch/mips/configs/ev64120_defconfig	2004-12-24 22:34:32.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/ev64120_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:59 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:55 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -94,7 +94,6 @@ CONFIG_MIPS_GT64120=y
+ # CONFIG_SYSCLK_83 is not set
+ CONFIG_SYSCLK_100=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -179,6 +178,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -454,7 +454,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -485,6 +484,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -505,11 +505,20 @@ 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
+@@ -601,6 +610,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/ev96100_defconfig linux-2.6.10-mips/arch/mips/configs/ev96100_defconfig
+--- linux-2.6.10/arch/mips/configs/ev96100_defconfig	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/ev96100_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:59 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:55 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -93,7 +93,6 @@ CONFIG_MIPS_GT64120=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_MIPS_GT96100=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -174,6 +173,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_LOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -410,7 +410,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -441,6 +440,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -460,11 +460,20 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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
+@@ -556,6 +565,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/ip22_defconfig linux-2.6.10-mips/arch/mips/configs/ip22_defconfig
+--- linux-2.6.10/arch/mips/configs/ip22_defconfig	2004-12-24 22:34:31.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/ip22_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:59 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:56 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -92,10 +92,9 @@ CONFIG_DMA_NONCOHERENT=y
+ # CONFIG_CPU_LITTLE_ENDIAN is not set
+ CONFIG_IRQ_CPU=y
+ CONFIG_SWAP_IO_SPACE=y
++CONFIG_ARC32=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-CONFIG_ARC32=y
+-# CONFIG_FB is not set
+ CONFIG_ARC_CONSOLE=y
+ CONFIG_ARC_PROMLIB=y
+ 
+@@ -176,6 +175,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_LOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -229,7 +229,6 @@ CONFIG_SCSI_SPI_ATTRS=m
+ #
+ CONFIG_SGIWD93_SCSI=y
+ # CONFIG_SCSI_SATA is not set
+-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
+ # CONFIG_SCSI_DEBUG is not set
+ 
+ #
+@@ -627,7 +626,6 @@ CONFIG_SGI_DS1286=m
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ CONFIG_RAW_DRIVER=m
+ CONFIG_MAX_RAW_DEVS=256
+@@ -659,6 +657,7 @@ CONFIG_MAX_RAW_DEVS=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -689,11 +688,20 @@ CONFIG_LOGO_SGI_CLUT224=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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=m
+@@ -798,7 +806,7 @@ CONFIG_SMB_NLS_REMOTE="cp437"
+ CONFIG_CIFS=m
+ # CONFIG_CIFS_STATS is not set
+ # CONFIG_CIFS_XATTR is not set
+-# CONFIG_CIFS_POSIX is not set
++# CONFIG_CIFS_EXPERIMENTAL is not set
+ # CONFIG_NCP_FS is not set
+ CONFIG_CODA_FS=m
+ # CONFIG_CODA_FS_OLD_API is not set
+@@ -869,6 +877,11 @@ CONFIG_NLS_KOI8_U=m
+ CONFIG_NLS_UTF8=m
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/ip27_defconfig linux-2.6.10-mips/arch/mips/configs/ip27_defconfig
+--- linux-2.6.10/arch/mips/configs/ip27_defconfig	2004-12-24 22:34:32.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/ip27_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:00 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:56 2004
+ #
+ CONFIG_MIPS=y
+ CONFIG_MIPS64=y
+@@ -96,7 +96,6 @@ CONFIG_ARC=y
+ CONFIG_DMA_IP27=y
+ # CONFIG_CPU_LITTLE_ENDIAN is not set
+ CONFIG_MIPS_L1_CACHE_SHIFT=7
+-# CONFIG_FB is not set
+ CONFIG_ARC64=y
+ CONFIG_BOOT_ELF64=y
+ CONFIG_QL_ISP_A64=y
+@@ -193,6 +192,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_CDROM_PKTCDVD=m
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -266,7 +266,6 @@ CONFIG_SCSI_SPI_ATTRS=y
+ CONFIG_SCSI_QLOGIC_ISP=y
+ # CONFIG_SCSI_QLOGIC_FC is not set
+ # CONFIG_SCSI_QLOGIC_1280 is not set
+-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
+ CONFIG_SCSI_QLA2XXX=y
+ # CONFIG_SCSI_QLA21XX is not set
+ # CONFIG_SCSI_QLA22XX is not set
+@@ -562,7 +561,6 @@ CONFIG_SGI_IP27_RTC=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -593,6 +591,7 @@ CONFIG_SGI_IP27_RTC=y
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Sound
+@@ -607,11 +606,20 @@ 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
+@@ -732,6 +740,11 @@ CONFIG_SGI_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/ip32_defconfig linux-2.6.10-mips/arch/mips/configs/ip32_defconfig
+--- linux-2.6.10/arch/mips/configs/ip32_defconfig	2004-12-24 22:34:29.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/ip32_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:00 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:57 2004
+ #
+ CONFIG_MIPS=y
+ CONFIG_MIPS64=y
+@@ -82,10 +82,9 @@ CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_ARC=y
+ CONFIG_DMA_NONCOHERENT=y
+ # CONFIG_CPU_LITTLE_ENDIAN is not set
++CONFIG_ARC32=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-CONFIG_ARC32=y
+-# CONFIG_FB is not set
+ CONFIG_ARC_MEMORY=y
+ CONFIG_ARC_PROMLIB=y
+ 
+@@ -179,6 +178,7 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_CDROM_PKTCDVD=y
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -258,7 +258,6 @@ CONFIG_AIC7XXX_REG_PRETTY_PRINT=y
+ # CONFIG_SCSI_QLOGIC_ISP is not set
+ # CONFIG_SCSI_QLOGIC_FC is not set
+ # CONFIG_SCSI_QLOGIC_1280 is not set
+-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
+ CONFIG_SCSI_QLA2XXX=y
+ # CONFIG_SCSI_QLA21XX is not set
+ # CONFIG_SCSI_QLA22XX is not set
+@@ -519,7 +518,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -550,6 +548,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -570,11 +569,20 @@ 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
+@@ -678,6 +686,11 @@ CONFIG_SGI_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/it8172_defconfig linux-2.6.10-mips/arch/mips/configs/it8172_defconfig
+--- linux-2.6.10/arch/mips/configs/it8172_defconfig	2004-12-24 22:34:02.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/it8172_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:00 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:57 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -94,7 +94,6 @@ CONFIG_ITE_BOARD_GEN=y
+ CONFIG_IT8172_CIR=y
+ CONFIG_IT8712=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -239,6 +238,7 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -500,7 +500,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -531,6 +530,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -570,11 +570,20 @@ CONFIG_SOUND_IT8172=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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
+@@ -668,6 +677,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/ivr_defconfig linux-2.6.10-mips/arch/mips/configs/ivr_defconfig
+--- linux-2.6.10/arch/mips/configs/ivr_defconfig	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/ivr_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:01 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:57 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -92,7 +92,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_ITE_BOARD_GEN=y
+ CONFIG_IT8172_CIR=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -176,6 +175,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -468,7 +468,6 @@ CONFIG_RTC=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -499,6 +498,7 @@ CONFIG_RTC=y
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -519,11 +519,20 @@ 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
+@@ -615,6 +624,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/jaguar-atx_defconfig linux-2.6.10-mips/arch/mips/configs/jaguar-atx_defconfig
+--- linux-2.6.10/arch/mips/configs/jaguar-atx_defconfig	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/jaguar-atx_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:01 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:58 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -89,7 +89,6 @@ CONFIG_PCI_MARVELL=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -178,6 +177,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -430,7 +430,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -461,6 +460,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Sound
+@@ -475,11 +475,20 @@ 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 is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/jmr3927_defconfig linux-2.6.10-mips/arch/mips/configs/jmr3927_defconfig
+--- linux-2.6.10/arch/mips/configs/jmr3927_defconfig	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/jmr3927_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:01 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:58 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -85,7 +85,6 @@ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_MIPS_TX3927=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-CONFIG_FB=y
+ CONFIG_TOSHIBA_BOARDS=y
+ 
+ #
+@@ -169,6 +168,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=y
+@@ -452,7 +452,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -483,6 +482,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++CONFIG_FB=y
+ # CONFIG_FB_MODE_HELPERS is not set
+ # CONFIG_FB_TILEBLITTING is not set
+ # CONFIG_FB_CIRRUS is not set
+@@ -531,11 +531,20 @@ 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 is not set
+@@ -624,6 +633,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/lasat200_defconfig linux-2.6.10-mips/arch/mips/configs/lasat200_defconfig
+--- linux-2.6.10/arch/mips/configs/lasat200_defconfig	2004-12-24 22:34:58.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/lasat200_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:02 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:58 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -95,7 +95,6 @@ CONFIG_MIPS_NILE4=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_MIPS_GT64120=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -250,6 +249,7 @@ CONFIG_MTD_LASAT=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -565,7 +565,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -596,6 +595,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -616,11 +616,20 @@ 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
+@@ -719,6 +728,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/malta_defconfig linux-2.6.10-mips/arch/mips/configs/malta_defconfig
+--- linux-2.6.10/arch/mips/configs/malta_defconfig	2004-12-24 22:35:25.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/malta_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:02 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:59 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -87,7 +87,6 @@ CONFIG_MIPS_MALTA=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
+ CONFIG_HAVE_DEC_LOCK=y
+ CONFIG_DMA_NONCOHERENT=y
+-CONFIG_GENERIC_ISA_DMA=y
+ CONFIG_I8259=y
+ CONFIG_MIPS_BONITO64=y
+ CONFIG_MIPS_MSC=y
+@@ -97,7 +96,6 @@ CONFIG_MIPS_GT64120=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+ 
+ #
+@@ -184,6 +182,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # 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=4096
+ # CONFIG_BLK_DEV_INITRD is not set
+ CONFIG_INITRAMFS_SOURCE=""
+@@ -473,7 +472,6 @@ CONFIG_RTC=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -504,6 +502,7 @@ CONFIG_RTC=y
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -524,11 +523,20 @@ 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
+@@ -624,6 +632,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/mpc30x_defconfig linux-2.6.10-mips/arch/mips/configs/mpc30x_defconfig
+--- linux-2.6.10/arch/mips/configs/mpc30x_defconfig	2004-12-24 22:35:27.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/mpc30x_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:02 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:59 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -58,6 +58,7 @@ CONFIG_KMOD=y
+ #
+ # CONFIG_MACH_JAZZ is not set
+ CONFIG_MACH_VR41XX=y
++# CONFIG_NEC_CMBVR4133 is not set
+ # CONFIG_CASIO_E55 is not set
+ # CONFIG_IBM_WORKPAD is not set
+ # CONFIG_TANBAC_TB0226 is not set
+@@ -98,7 +99,6 @@ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -180,6 +180,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -450,7 +451,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -481,6 +481,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -501,11 +502,20 @@ 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
+@@ -597,6 +607,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/ocelot_3_defconfig linux-2.6.10-mips/arch/mips/configs/ocelot_3_defconfig
+--- linux-2.6.10/arch/mips/configs/ocelot_3_defconfig	2004-12-24 22:34:31.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/ocelot_3_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:03 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:00 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -96,7 +96,6 @@ CONFIG_PCI_MARVELL=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-CONFIG_FB=y
+ 
+ #
+ # CPU selection
+@@ -187,6 +186,7 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ # CONFIG_CDROM_PKTCDVD is not set
+@@ -260,7 +260,6 @@ CONFIG_SCSI_PROC_FS=y
+ # CONFIG_SCSI_QLOGIC_ISP is not set
+ # CONFIG_SCSI_QLOGIC_FC is not set
+ # CONFIG_SCSI_QLOGIC_1280 is not set
+-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
+ CONFIG_SCSI_QLA2XXX=m
+ # CONFIG_SCSI_QLA21XX is not set
+ # CONFIG_SCSI_QLA22XX is not set
+@@ -577,7 +576,6 @@ CONFIG_RTC=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -608,6 +606,7 @@ CONFIG_RTC=y
+ #
+ # Graphics support
+ #
++CONFIG_FB=y
+ CONFIG_FB_MODE_HELPERS=y
+ # CONFIG_FB_TILEBLITTING is not set
+ # CONFIG_FB_CIRRUS is not set
+@@ -662,11 +661,20 @@ 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
+@@ -817,6 +825,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ # CONFIG_NLS_UTF8 is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/ocelot_c_defconfig linux-2.6.10-mips/arch/mips/configs/ocelot_c_defconfig
+--- linux-2.6.10/arch/mips/configs/ocelot_c_defconfig	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/ocelot_c_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:03 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:00 2004
+ #
+ CONFIG_MIPS=y
+ CONFIG_MIPS64=y
+@@ -85,7 +85,6 @@ CONFIG_IRQ_MV64340=y
+ CONFIG_PCI_MARVELL=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -176,6 +175,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_CDROM_PKTCDVD=y
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -444,7 +444,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -475,6 +474,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -495,11 +495,20 @@ 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
+@@ -593,6 +602,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/ocelot_defconfig linux-2.6.10-mips/arch/mips/configs/ocelot_defconfig
+--- linux-2.6.10/arch/mips/configs/ocelot_defconfig	2004-12-24 22:34:32.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/ocelot_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:04 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:00 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -90,7 +90,6 @@ CONFIG_SWAP_IO_SPACE=y
+ # CONFIG_SYSCLK_83 is not set
+ CONFIG_SYSCLK_100=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -171,6 +170,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_LOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=y
+@@ -406,7 +406,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -437,6 +436,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -456,11 +456,20 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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
+@@ -554,6 +563,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/ocelot_g_defconfig linux-2.6.10-mips/arch/mips/configs/ocelot_g_defconfig
+--- linux-2.6.10/arch/mips/configs/ocelot_g_defconfig	2004-12-24 22:34:57.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/ocelot_g_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:04 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:01 2004
+ #
+ CONFIG_MIPS=y
+ CONFIG_MIPS64=y
+@@ -88,7 +88,6 @@ CONFIG_SWAP_IO_SPACE=y
+ # CONFIG_SYSCLK_83 is not set
+ CONFIG_SYSCLK_100=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -179,6 +178,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_CDROM_PKTCDVD=y
+ CONFIG_CDROM_PKTCDVD_BUFFERS=8
+@@ -447,7 +447,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -478,6 +477,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -498,11 +498,20 @@ 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
+@@ -596,6 +605,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/osprey_defconfig linux-2.6.10-mips/arch/mips/configs/osprey_defconfig
+--- linux-2.6.10/arch/mips/configs/osprey_defconfig	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/osprey_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:04 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:01 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -90,7 +90,6 @@ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ CONFIG_VR4181=y
+ 
+ #
+@@ -164,6 +163,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_LOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -400,7 +400,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -431,6 +430,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -450,11 +450,20 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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
+@@ -548,6 +557,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/pb1100_defconfig linux-2.6.10-mips/arch/mips/configs/pb1100_defconfig
+--- linux-2.6.10/arch/mips/configs/pb1100_defconfig	2004-12-24 22:34:57.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/pb1100_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:05 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:02 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -107,7 +107,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_SWAP_IO_SPACE=y
+ # CONFIG_AU1000_USB_DEVICE is not set
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -275,6 +274,7 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -539,7 +539,6 @@ CONFIG_RTC=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ 
+ #
+@@ -575,6 +574,7 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -594,11 +594,20 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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
+@@ -748,6 +757,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ # CONFIG_NLS_UTF8 is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/pb1500_defconfig linux-2.6.10-mips/arch/mips/configs/pb1500_defconfig
+--- linux-2.6.10/arch/mips/configs/pb1500_defconfig	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/pb1500_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:05 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:02 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -106,7 +106,6 @@ CONFIG_DMA_COHERENT=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ # CONFIG_AU1000_USB_DEVICE is not set
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -217,6 +216,7 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -575,7 +575,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ 
+ #
+@@ -611,6 +610,7 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Sound
+@@ -625,11 +625,20 @@ 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
+@@ -777,6 +786,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ # CONFIG_NLS_UTF8 is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/pb1550_defconfig linux-2.6.10-mips/arch/mips/configs/pb1550_defconfig
+--- linux-2.6.10/arch/mips/configs/pb1550_defconfig	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/pb1550_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:05 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:02 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -106,7 +106,6 @@ CONFIG_DMA_COHERENT=y
+ CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -217,6 +216,7 @@ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -567,7 +567,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ 
+ #
+@@ -603,6 +602,7 @@ CONFIG_SYNCLINK_CS=m
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Sound
+@@ -617,11 +617,20 @@ 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
+@@ -769,6 +778,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
+ # CONFIG_NLS_UTF8 is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/rm200_defconfig linux-2.6.10-mips/arch/mips/configs/rm200_defconfig
+--- linux-2.6.10/arch/mips/configs/rm200_defconfig	2004-12-24 22:34:29.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/rm200_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:06 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:03 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -93,10 +93,9 @@ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_GENERIC_ISA_DMA=y
+ CONFIG_I8259=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
++CONFIG_ARC32=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-CONFIG_ARC32=y
+-# CONFIG_FB is not set
+ CONFIG_HAVE_STD_PC_SERIAL_PORT=y
+ CONFIG_ARC_CONSOLE=y
+ CONFIG_ARC_MEMORY=y
+@@ -229,6 +228,7 @@ CONFIG_BLK_DEV_NBD=m
+ CONFIG_BLK_DEV_SX8=m
+ CONFIG_BLK_DEV_UB=m
+ CONFIG_BLK_DEV_RAM=m
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=4096
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+@@ -326,7 +326,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+ # CONFIG_SCSI_QLOGIC_ISP is not set
+ # CONFIG_SCSI_QLOGIC_FC is not set
+ # CONFIG_SCSI_QLOGIC_1280 is not set
+-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
+ CONFIG_SCSI_QLA2XXX=y
+ # CONFIG_SCSI_QLA21XX is not set
+ # CONFIG_SCSI_QLA22XX is not set
+@@ -859,7 +858,6 @@ CONFIG_RTC=m
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -874,7 +872,7 @@ CONFIG_RTC=m
+ CONFIG_W1=m
+ CONFIG_W1_MATROX=m
+ CONFIG_W1_DS9490=m
+-CONFIG_W1_DS9490R_BRIDGE=m
++CONFIG_W1_DS9490_BRIDGE=m
+ CONFIG_W1_THERM=m
+ CONFIG_W1_SMEM=m
+ 
+@@ -895,6 +893,7 @@ CONFIG_W1_SMEM=m
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -932,6 +931,7 @@ CONFIG_USB_EHCI_HCD=m
+ # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+ CONFIG_USB_OHCI_HCD=m
+ CONFIG_USB_UHCI_HCD=m
++# CONFIG_USB_SL811_HCD is not set
+ 
+ #
+ # USB Device Class drivers
+@@ -939,6 +939,10 @@ CONFIG_USB_UHCI_HCD=m
+ CONFIG_USB_BLUETOOTH_TTY=m
+ CONFIG_USB_ACM=m
+ CONFIG_USB_PRINTER=m
++
++#
++# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
++#
+ CONFIG_USB_STORAGE=m
+ # CONFIG_USB_STORAGE_DEBUG is not set
+ # CONFIG_USB_STORAGE_RW_DETECT is not set
+@@ -1097,6 +1101,11 @@ CONFIG_USB_TEST=m
+ # CONFIG_USB_GADGET is not set
+ 
+ #
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
+ # File systems
+ #
+ CONFIG_EXT2_FS=m
+@@ -1208,7 +1217,7 @@ CONFIG_SMB_FS=m
+ CONFIG_CIFS=m
+ # CONFIG_CIFS_STATS is not set
+ # CONFIG_CIFS_XATTR is not set
+-# CONFIG_CIFS_POSIX is not set
++# CONFIG_CIFS_EXPERIMENTAL is not set
+ CONFIG_NCP_FS=m
+ CONFIG_NCPFS_PACKET_SIGNING=y
+ CONFIG_NCPFS_IOCTL_LOCKING=y
+@@ -1288,6 +1297,11 @@ CONFIG_NLS_KOI8_U=m
+ CONFIG_NLS_UTF8=m
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/sb1250-swarm_defconfig linux-2.6.10-mips/arch/mips/configs/sb1250-swarm_defconfig
+--- linux-2.6.10/arch/mips/configs/sb1250-swarm_defconfig	2004-12-24 22:35:40.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/sb1250-swarm_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:06 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:03 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -116,7 +116,6 @@ CONFIG_DMA_COHERENT=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -143,7 +142,7 @@ CONFIG_PAGE_SIZE_4KB=y
+ # CONFIG_PAGE_SIZE_16KB is not set
+ # CONFIG_PAGE_SIZE_64KB is not set
+ # CONFIG_SIBYTE_DMA_PAGEOPS is not set
+-# CONFIG_CPU_HAS_PREFETCH is not set
++CONFIG_CPU_HAS_PREFETCH=y
+ CONFIG_VTAG_ICACHE=y
+ CONFIG_SB1_PASS_1_WORKAROUNDS=y
+ # CONFIG_64BIT_PHYS_ADDR is not set
+@@ -208,6 +207,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # 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=9220
+ CONFIG_BLK_DEV_INITRD=y
+ CONFIG_INITRAMFS_SOURCE=""
+@@ -454,6 +454,7 @@ CONFIG_SERIO_RAW=m
+ CONFIG_SERIAL_NONSTANDARD=y
+ # CONFIG_ROCKETPORT is not set
+ # CONFIG_CYCLADES is not set
++# CONFIG_MOXA_SMARTIO is not set
+ # CONFIG_SYNCLINK is not set
+ # CONFIG_SYNCLINKMP is not set
+ # CONFIG_N_HDLC is not set
+@@ -491,7 +492,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -522,6 +522,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Sound
+@@ -536,11 +537,20 @@ 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
+@@ -636,6 +646,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/sead_defconfig linux-2.6.10-mips/arch/mips/configs/sead_defconfig
+--- linux-2.6.10/arch/mips/configs/sead_defconfig	2004-12-24 22:34:58.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/sead_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:06 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:04 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -83,7 +83,6 @@ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_BOARDS_GEN=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -160,6 +159,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=18432
+ CONFIG_BLK_DEV_INITRD=y
+ CONFIG_INITRAMFS_SOURCE=""
+@@ -298,7 +298,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -328,6 +327,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -347,11 +347,20 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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
+@@ -425,6 +434,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/tb0226_defconfig linux-2.6.10-mips/arch/mips/configs/tb0226_defconfig
+--- linux-2.6.10/arch/mips/configs/tb0226_defconfig	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/tb0226_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:07 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:04 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -58,6 +58,7 @@ CONFIG_KMOD=y
+ #
+ # CONFIG_MACH_JAZZ is not set
+ CONFIG_MACH_VR41XX=y
++# CONFIG_NEC_CMBVR4133 is not set
+ # CONFIG_CASIO_E55 is not set
+ # CONFIG_IBM_WORKPAD is not set
+ CONFIG_TANBAC_TB0226=y
+@@ -96,7 +97,6 @@ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-CONFIG_FB=y
+ 
+ #
+ # CPU selection
+@@ -172,6 +172,7 @@ CONFIG_BLK_DEV_LOOP=m
+ # CONFIG_BLK_DEV_CRYPTOLOOP is not set
+ CONFIG_BLK_DEV_NBD=m
+ CONFIG_BLK_DEV_RAM=m
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=4096
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+@@ -247,7 +248,6 @@ CONFIG_SCSI_CONSTANTS=y
+ # SCSI low-level drivers
+ #
+ # CONFIG_SCSI_SATA is not set
+-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
+ # CONFIG_SCSI_DEBUG is not set
+ 
+ #
+@@ -473,7 +473,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -504,6 +503,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++CONFIG_FB=y
+ # CONFIG_FB_MODE_HELPERS is not set
+ # CONFIG_FB_TILEBLITTING is not set
+ # CONFIG_FB_VIRTUAL is not set
+@@ -542,11 +542,20 @@ CONFIG_SOUND=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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
+@@ -690,6 +699,11 @@ CONFIG_NLS_ISO8859_1=m
+ # CONFIG_NLS_UTF8 is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/tb0229_defconfig linux-2.6.10-mips/arch/mips/configs/tb0229_defconfig
+--- linux-2.6.10/arch/mips/configs/tb0229_defconfig	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/tb0229_defconfig	2004-12-28 20:06:21.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:07 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:05 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -58,14 +58,16 @@ CONFIG_KMOD=y
+ #
+ # CONFIG_MACH_JAZZ is not set
+ CONFIG_MACH_VR41XX=y
++# CONFIG_NEC_CMBVR4133 is not set
+ # CONFIG_CASIO_E55 is not set
+ # CONFIG_IBM_WORKPAD is not set
+ # CONFIG_TANBAC_TB0226 is not set
+ CONFIG_TANBAC_TB0229=y
++CONFIG_TANBAC_TB0219=y
+ # CONFIG_VICTOR_MPC30X is not set
+ # CONFIG_ZAO_CAPCELLA is not set
+ CONFIG_PCI_VR41XX=y
+-CONFIG_VRC4173=y
++# CONFIG_VRC4173 is not set
+ # CONFIG_TOSHIBA_JMR3927 is not set
+ # CONFIG_MIPS_COBALT is not set
+ # CONFIG_MACH_DECSTATION is not set
+@@ -98,8 +100,6 @@ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+-CONFIG_TANBAC_TB0219=y
+ 
+ #
+ # CPU selection
+@@ -182,6 +182,7 @@ CONFIG_BLK_DEV_LOOP=m
+ CONFIG_BLK_DEV_NBD=m
+ # CONFIG_BLK_DEV_SX8 is not set
+ CONFIG_BLK_DEV_RAM=y
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_BLK_DEV_RAM_SIZE=4096
+ # CONFIG_BLK_DEV_INITRD is not set
+ CONFIG_INITRAMFS_SOURCE=""
+@@ -315,7 +316,7 @@ CONFIG_DUMMY=m
+ # Ethernet (10 or 100Mbit)
+ #
+ CONFIG_NET_ETHERNET=y
+-# CONFIG_MII is not set
++CONFIG_MII=y
+ # CONFIG_HAPPYMEAL is not set
+ # CONFIG_SUNGEM is not set
+ # CONFIG_NET_VENDOR_3COM is not set
+@@ -325,7 +326,27 @@ CONFIG_NET_ETHERNET=y
+ #
+ # CONFIG_NET_TULIP is not set
+ # CONFIG_HP100 is not set
+-# CONFIG_NET_PCI is not set
++CONFIG_NET_PCI=y
++CONFIG_PCNET32=y
++# 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=y
++# CONFIG_EEPRO100_PIO is not set
++# CONFIG_E100 is not set
++# CONFIG_FEALNX is not set
++# CONFIG_NATSEMI is not set
++# CONFIG_NE2K_PCI is not set
++# CONFIG_8139CP is not set
++# CONFIG_8139TOO is not set
++# CONFIG_SIS900 is not set
++# CONFIG_EPIC100 is not set
++# CONFIG_SUNDANCE is not set
++# CONFIG_TLAN is not set
++# CONFIG_VIA_RHINE is not set
++# CONFIG_LAN_SAA9730 is not set
+ 
+ #
+ # Ethernet (1000 Mbit)
+@@ -338,6 +359,7 @@ CONFIG_NET_ETHERNET=y
+ # CONFIG_YELLOWFIN is not set
+ # CONFIG_R8169 is not set
+ # CONFIG_SK98LIN is not set
++# CONFIG_VIA_VELOCITY is not set
+ # CONFIG_TIGON3 is not set
+ 
+ #
+@@ -468,7 +490,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -499,6 +520,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -519,11 +541,20 @@ 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
+@@ -680,11 +711,16 @@ CONFIG_NLS_ISO8859_1=m
+ # CONFIG_NLS_UTF8 is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+ CONFIG_CROSSCOMPILE=y
+-CONFIG_CMDLINE=""
++CONFIG_CMDLINE="mem=64M console=ttyS0,38400 ip=bootp root=/dev/nfs"
+ 
+ #
+ # Security options
+@@ -702,7 +738,7 @@ CONFIG_KEYS_DEBUG_PROC_KEYS=y
+ # Library routines
+ #
+ CONFIG_CRC_CCITT=m
+-# CONFIG_CRC32 is not set
++CONFIG_CRC32=y
+ # CONFIG_LIBCRC32C is not set
+ CONFIG_ZLIB_INFLATE=y
+ CONFIG_ZLIB_DEFLATE=m
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/workpad_defconfig linux-2.6.10-mips/arch/mips/configs/workpad_defconfig
+--- linux-2.6.10/arch/mips/configs/workpad_defconfig	2004-12-24 22:35:24.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/workpad_defconfig	2004-12-28 20:06:22.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:12:08 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:05 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -58,6 +58,7 @@ CONFIG_KMOD=y
+ #
+ # CONFIG_MACH_JAZZ is not set
+ CONFIG_MACH_VR41XX=y
++# CONFIG_NEC_CMBVR4133 is not set
+ # CONFIG_CASIO_E55 is not set
+ CONFIG_IBM_WORKPAD=y
+ # CONFIG_TANBAC_TB0226 is not set
+@@ -97,7 +98,6 @@ CONFIG_DMA_NONCOHERENT=y
+ CONFIG_CPU_LITTLE_ENDIAN=y
+ CONFIG_IRQ_CPU=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -173,6 +173,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_LOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -463,7 +464,6 @@ CONFIG_WATCHDOG=y
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -494,6 +494,7 @@ CONFIG_WATCHDOG=y
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -514,11 +515,20 @@ CONFIG_DUMMY_CONSOLE=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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
+@@ -615,6 +625,11 @@ CONFIG_MSDOS_PARTITION=y
+ # CONFIG_NLS is not set
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/configs/yosemite_defconfig linux-2.6.10-mips/arch/mips/configs/yosemite_defconfig
+--- linux-2.6.10/arch/mips/configs/yosemite_defconfig	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/configs/yosemite_defconfig	2004-12-28 20:06:22.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Fri Nov 26 00:00:39 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:11:05 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -85,9 +85,9 @@ CONFIG_DMA_COHERENT=y
+ # CONFIG_CPU_LITTLE_ENDIAN is not set
+ CONFIG_IRQ_CPU=y
+ CONFIG_IRQ_CPU_RM7K=y
++CONFIG_IRQ_CPU_RM9K=y
+ CONFIG_SWAP_IO_SPACE=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-# CONFIG_FB is not set
+ 
+ #
+ # CPU selection
+@@ -176,6 +176,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -401,7 +402,8 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # CONFIG_WATCHDOG is not set
+ # CONFIG_RTC is not set
+-# CONFIG_GEN_RTC 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
+@@ -409,7 +411,6 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ # CONFIG_RAW_DRIVER is not set
+ 
+@@ -440,6 +441,7 @@ CONFIG_LEGACY_PTY_COUNT=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Sound
+@@ -454,11 +456,20 @@ 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 is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/defconfig linux-2.6.10-mips/arch/mips/defconfig
+--- linux-2.6.10/arch/mips/defconfig	2004-12-24 22:34:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/defconfig	2004-12-28 20:06:20.000000000 +0100
+@@ -1,7 +1,7 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.10-rc2
+-# Sun Nov 21 14:11:54 2004
++# Linux kernel version: 2.6.10
++# Mon Dec 27 19:10:50 2004
+ #
+ CONFIG_MIPS=y
+ # CONFIG_MIPS64 is not set
+@@ -92,10 +92,9 @@ CONFIG_DMA_NONCOHERENT=y
+ # CONFIG_CPU_LITTLE_ENDIAN is not set
+ CONFIG_IRQ_CPU=y
+ CONFIG_SWAP_IO_SPACE=y
++CONFIG_ARC32=y
+ CONFIG_BOOT_ELF32=y
+ CONFIG_MIPS_L1_CACHE_SHIFT=5
+-CONFIG_ARC32=y
+-# CONFIG_FB is not set
+ CONFIG_ARC_CONSOLE=y
+ CONFIG_ARC_PROMLIB=y
+ 
+@@ -176,6 +175,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
+ # CONFIG_BLK_DEV_LOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
++CONFIG_BLK_DEV_RAM_COUNT=16
+ CONFIG_INITRAMFS_SOURCE=""
+ # CONFIG_LBD is not set
+ CONFIG_CDROM_PKTCDVD=m
+@@ -229,7 +229,6 @@ CONFIG_SCSI_SPI_ATTRS=m
+ #
+ CONFIG_SGIWD93_SCSI=y
+ # CONFIG_SCSI_SATA is not set
+-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
+ # CONFIG_SCSI_DEBUG is not set
+ 
+ #
+@@ -627,7 +626,6 @@ CONFIG_SGI_DS1286=m
+ #
+ # Ftape, the floppy tape device driver
+ #
+-# CONFIG_AGP is not set
+ # CONFIG_DRM is not set
+ CONFIG_RAW_DRIVER=m
+ CONFIG_MAX_RAW_DEVS=256
+@@ -659,6 +657,7 @@ CONFIG_MAX_RAW_DEVS=256
+ #
+ # Graphics support
+ #
++# CONFIG_FB is not set
+ 
+ #
+ # Console display driver support
+@@ -689,11 +688,20 @@ CONFIG_LOGO_SGI_CLUT224=y
+ # CONFIG_USB_ARCH_HAS_OHCI is not set
+ 
+ #
++# 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=m
+@@ -798,7 +806,7 @@ CONFIG_SMB_NLS_REMOTE="cp437"
+ CONFIG_CIFS=m
+ # CONFIG_CIFS_STATS is not set
+ # CONFIG_CIFS_XATTR is not set
+-# CONFIG_CIFS_POSIX is not set
++# CONFIG_CIFS_EXPERIMENTAL is not set
+ # CONFIG_NCP_FS is not set
+ CONFIG_CODA_FS=m
+ # CONFIG_CODA_FS_OLD_API is not set
+@@ -869,6 +877,11 @@ CONFIG_NLS_KOI8_U=m
+ CONFIG_NLS_UTF8=m
+ 
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ # CONFIG_DEBUG_KERNEL is not set
+diff -urpNX dontdiff linux-2.6.10/arch/mips/gt64120/ev64120/irq.c linux-2.6.10-mips/arch/mips/gt64120/ev64120/irq.c
+--- linux-2.6.10/arch/mips/gt64120/ev64120/irq.c	2004-12-24 22:35:24.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/gt64120/ev64120/irq.c	2005-01-06 00:00:26.000000000 +0100
+@@ -119,7 +119,7 @@ void gt64120_irq_setup(void)
+ 	/* Sets the exception_handler array. */
+ 	set_except_vector(0, galileo_handle_int);
+ 
+-	cli();
++	local_irq_disable();
+ 
+ 	/*
+ 	 * Enable timer.  Other interrupts will be enabled as they are
+diff -urpNX dontdiff linux-2.6.10/arch/mips/gt64120/momenco_ocelot/setup.c linux-2.6.10-mips/arch/mips/gt64120/momenco_ocelot/setup.c
+--- linux-2.6.10/arch/mips/gt64120/momenco_ocelot/setup.c	2004-12-24 22:34:46.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/gt64120/momenco_ocelot/setup.c	2004-12-21 03:25:14.000000000 +0100
+@@ -304,7 +304,7 @@ static void __init momenco_ocelot_setup(
+ 	}
+ 
+ 	/* Fix up the DiskOnChip mapping */
+-	GT_WRITE(0x468, 0xfef73);
++	GT_WRITE(GT_DEV_B3_OFS, 0xfef73);
+ }
+ 
+ early_initcall(momenco_ocelot_setup);
+@@ -322,8 +322,8 @@ static void __init setup_l3cache(unsigne
+ 	printk("Enabling L3 cache...");
+ 
+ 	/* Enable the L3 cache in the GT64120A's CPU Configuration register */
+-	tmp =  GT_READ(0);
+-	GT_WRITE(0, tmp | (1<<14));
++	tmp = GT_READ(GT_CPU_OFS);
++	GT_WRITE(GT_CPU_OFS, tmp | (1<<14));
+ 
+ 	/* Enable the L3 cache in the CPU */
+ 	set_c0_config(1<<12 /* CONF_TE */);
+diff -urpNX dontdiff linux-2.6.10/arch/mips/ite-boards/generic/irq.c linux-2.6.10-mips/arch/mips/ite-boards/generic/irq.c
+--- linux-2.6.10/arch/mips/ite-boards/generic/irq.c	2004-12-24 22:34:58.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/ite-boards/generic/irq.c	2004-12-21 03:25:15.000000000 +0100
+@@ -57,14 +57,6 @@
+ #include <asm/it8172/it8172_int.h>
+ #include <asm/it8172/it8172_dbg.h>
+ 
+-#undef DEBUG_IRQ
+-#ifdef DEBUG_IRQ
+-/* note: prints function name for you */
+-#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
+-#else
+-#define DPRINTK(fmt, args...)
+-#endif
+-
+ /* revisit */
+ #define EXT_IRQ0_TO_IP 2 /* IP 2 */
+ #define EXT_IRQ5_TO_IP 7 /* IP 7 */
+@@ -81,111 +73,50 @@ extern asmlinkage void it8172_IRQ(void);
+ struct it8172_intc_regs volatile *it8172_hw0_icregs =
+ 	(struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE));
+ 
+-/* Function for careful CP0 interrupt mask access */
+-static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask)
+-{
+-        unsigned long status = read_c0_status();
+-        status &= ~((clr_mask & 0xFF) << 8);
+-        status |=   (set_mask & 0xFF) << 8;
+-        write_c0_status(status);
+-}
+-
+-static inline void mask_irq(unsigned int irq_nr)
+-{
+-        modify_cp0_intmask(irq_nr, 0);
+-}
+-
+-static inline void unmask_irq(unsigned int irq_nr)
+-{
+-        modify_cp0_intmask(0, irq_nr);
+-}
+-
+-void local_disable_irq(unsigned int irq_nr)
+-{
+-        unsigned long flags;
+-
+-        local_irq_save(flags);
+-	disable_it8172_irq(irq_nr);
+-        local_irq_restore(flags);
+-}
+-
+-void local_enable_irq(unsigned int irq_nr)
++static void disable_it8172_irq(unsigned int irq_nr)
+ {
+-	unsigned long flags;
+-
+-        local_irq_save(flags);
+-	enable_it8172_irq(irq_nr);
+-        local_irq_restore(flags);
+-}
+-
+-
+-void disable_it8172_irq(unsigned int irq_nr)
+-{
+-	DPRINTK("disable_it8172_irq %d\n", irq_nr);
+-
+ 	if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
+ 		/* LPC interrupt */
+-		DPRINTK("DB lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
+ 		it8172_hw0_icregs->lpc_mask |=
+ 			(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
+-		DPRINTK("DA lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
+-	}
+-	else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
++	} else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
+ 		/* Local Bus interrupt */
+-		DPRINTK("DB lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
+ 		it8172_hw0_icregs->lb_mask |=
+ 			(1 << (irq_nr - IT8172_LB_IRQ_BASE));
+-		DPRINTK("DA lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
+-	}
+-	else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
++	} else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
+ 		/* PCI and other interrupts */
+-		DPRINTK("DB pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
+ 		it8172_hw0_icregs->pci_mask |=
+ 			(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
+-		DPRINTK("DA pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
+-	}
+-	else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
++	} else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
+ 		/* NMI interrupts */
+-		DPRINTK("DB nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
+ 		it8172_hw0_icregs->nmi_mask |=
+ 			(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
+-		DPRINTK("DA nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
+-	}
+-	else {
++	} else {
+ 		panic("disable_it8172_irq: bad irq %d", irq_nr);
+ 	}
+ }
+ 
+-void enable_it8172_irq(unsigned int irq_nr)
++static void enable_it8172_irq(unsigned int irq_nr)
+ {
+-	DPRINTK("enable_it8172_irq %d\n", irq_nr);
+ 	if ( (irq_nr >= IT8172_LPC_IRQ_BASE) && (irq_nr <= IT8172_SERIRQ_15)) {
+ 		/* LPC interrupt */
+-		DPRINTK("EB before lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
+ 		it8172_hw0_icregs->lpc_mask &=
+ 			~(1 << (irq_nr - IT8172_LPC_IRQ_BASE));
+-		DPRINTK("EA after lpc_mask  %x\n", it8172_hw0_icregs->lpc_mask);
+ 	}
+ 	else if ( (irq_nr >= IT8172_LB_IRQ_BASE) && (irq_nr <= IT8172_IOCHK_IRQ)) {
+ 		/* Local Bus interrupt */
+-		DPRINTK("EB lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
+ 		it8172_hw0_icregs->lb_mask &=
+ 			~(1 << (irq_nr - IT8172_LB_IRQ_BASE));
+-		DPRINTK("EA lb_mask  %x\n", it8172_hw0_icregs->lb_mask);
+ 	}
+ 	else if ( (irq_nr >= IT8172_PCI_DEV_IRQ_BASE) && (irq_nr <= IT8172_DMA_IRQ)) {
+ 		/* PCI and other interrupts */
+-		DPRINTK("EB pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
+ 		it8172_hw0_icregs->pci_mask &=
+ 			~(1 << (irq_nr - IT8172_PCI_DEV_IRQ_BASE));
+-		DPRINTK("EA pci_mask  %x\n", it8172_hw0_icregs->pci_mask);
+ 	}
+ 	else if ( (irq_nr >= IT8172_NMI_IRQ_BASE) && (irq_nr <= IT8172_POWER_NMI_IRQ)) {
+ 		/* NMI interrupts */
+-		DPRINTK("EB nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
+ 		it8172_hw0_icregs->nmi_mask &=
+ 			~(1 << (irq_nr - IT8172_NMI_IRQ_BASE));
+-		DPRINTK("EA nmi_mask  %x\n", it8172_hw0_icregs->nmi_mask);
+ 	}
+ 	else {
+ 		panic("enable_it8172_irq: bad irq %d", irq_nr);
+@@ -243,7 +174,7 @@ void enable_cpu_timer(void)
+         unsigned long flags;
+ 
+         local_irq_save(flags);
+-	unmask_irq(1<<EXT_IRQ5_TO_IP); /* timer interrupt */
++	set_c0_status(0x100 << EXT_IRQ5_TO_IP);
+         local_irq_restore(flags);
+ }
+ 
+@@ -305,7 +236,6 @@ void mips_spurious_interrupt(struct pt_r
+ 	cause = read_c0_cause();
+ 	printk("status %x cause %x\n", status, cause);
+ 	printk("epc %x badvaddr %x \n", regs->cp0_epc, regs->cp0_badvaddr);
+-//	while(1);
+ #endif
+ }
+ 
+@@ -326,9 +256,7 @@ void it8172_hw0_irqdispatch(struct pt_re
+ 			status >>= 1;
+ 		}
+ 		irq += IT8172_PCI_DEV_IRQ_BASE;
+-		//printk("pci int %d\n", irq);
+-	}
+-	else if (intstatus & 0x1) {
++	} else if (intstatus & 0x1) {
+ 		/* Local Bus interrupt */
+ 		irq = 0;
+ 		status |= it8172_hw0_icregs->lb_req;
+@@ -337,9 +265,7 @@ void it8172_hw0_irqdispatch(struct pt_re
+ 			status >>= 1;
+ 		}
+ 		irq += IT8172_LB_IRQ_BASE;
+-		//printk("lb int %d\n", irq);
+-	}
+-	else if (intstatus & 0x2) {
++	} else if (intstatus & 0x2) {
+ 		/* LPC interrupt */
+ 		/* Since some lpc interrupts are edge triggered,
+ 		 * we could lose an interrupt this way because
+@@ -353,7 +279,6 @@ void it8172_hw0_irqdispatch(struct pt_re
+ 			status >>= 1;
+ 		}
+ 		irq += IT8172_LPC_IRQ_BASE;
+-		//printk("LPC int %d\n", irq);
+ 	} else
+ 		return;
+ 
+diff -urpNX dontdiff linux-2.6.10/arch/mips/jmr3927/rbhma3100/irq.c linux-2.6.10-mips/arch/mips/jmr3927/rbhma3100/irq.c
+--- linux-2.6.10/arch/mips/jmr3927/rbhma3100/irq.c	2004-12-24 22:34:32.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/jmr3927/rbhma3100/irq.c	2004-12-21 03:25:15.000000000 +0100
+@@ -89,34 +89,6 @@ static unsigned char irc_level[TX3927_NU
+ 	6, 6, 6			/* TMR */
+ };
+ 
+-static inline void mask_irq(unsigned int irq_nr)
+-{
+-	struct tb_irq_space* sp;
+-	for (sp = tb_irq_spaces; sp; sp = sp->next) {
+-		if (sp->start_irqno <= irq_nr &&
+-		    irq_nr < sp->start_irqno + sp->nr_irqs) {
+-			if (sp->mask_func)
+-				sp->mask_func(irq_nr - sp->start_irqno,
+-					      sp->space_id);
+-			break;
+-		}
+-	}
+-}
+-
+-static inline void unmask_irq(unsigned int irq_nr)
+-{
+-	struct tb_irq_space* sp;
+-	for (sp = tb_irq_spaces; sp; sp = sp->next) {
+-		if (sp->start_irqno <= irq_nr &&
+-		    irq_nr < sp->start_irqno + sp->nr_irqs) {
+-			if (sp->unmask_func)
+-				sp->unmask_func(irq_nr - sp->start_irqno,
+-						sp->space_id);
+-			break;
+-		}
+-	}
+-}
+-
+ static void jmr3927_irq_disable(unsigned int irq_nr);
+ static void jmr3927_irq_enable(unsigned int irq_nr);
+ 
+@@ -133,9 +105,8 @@ static unsigned int jmr3927_irq_startup(
+ 
+ static void jmr3927_irq_ack(unsigned int irq)
+ {
+-	if (irq == JMR3927_IRQ_IRC_TMR0) {
++	if (irq == JMR3927_IRQ_IRC_TMR0)
+ 		jmr3927_tmrptr->tisr = 0;       /* ack interrupt */
+-	}
+ 
+ 	jmr3927_irq_disable(irq);
+ }
+@@ -147,19 +118,37 @@ static void jmr3927_irq_end(unsigned int
+ 
+ static void jmr3927_irq_disable(unsigned int irq_nr)
+ {
++	struct tb_irq_space* sp;
+ 	unsigned long flags;
+ 
+ 	spinlock_irqsave(&jmr3927_irq_lock, flags);
+-	mask_irq(irq_nr);
++	for (sp = tb_irq_spaces; sp; sp = sp->next) {
++		if (sp->start_irqno <= irq_nr &&
++		    irq_nr < sp->start_irqno + sp->nr_irqs) {
++			if (sp->mask_func)
++				sp->mask_func(irq_nr - sp->start_irqno,
++					      sp->space_id);
++			break;
++		}
++	}
+ 	spinlock_irqrestore(&jmr3927_irq_lock, flags);
+ }
+ 
+ static void jmr3927_irq_enable(unsigned int irq_nr)
+ {
++	struct tb_irq_space* sp;
+ 	unsigned long flags;
+ 
+ 	spinlock_irqsave(&jmr3927_irq_lock, flags);
+-	unmask_irq(irq_nr);
++	for (sp = tb_irq_spaces; sp; sp = sp->next) {
++		if (sp->start_irqno <= irq_nr &&
++		    irq_nr < sp->start_irqno + sp->nr_irqs) {
++			if (sp->unmask_func)
++				sp->unmask_func(irq_nr - sp->start_irqno,
++						sp->space_id);
++			break;
++		}
++	}
+ 	spinlock_irqrestore(&jmr3927_irq_lock, flags);
+ }
+ 
+diff -urpNX dontdiff linux-2.6.10/arch/mips/jmr3927/rbhma3100/setup.c linux-2.6.10-mips/arch/mips/jmr3927/rbhma3100/setup.c
+--- linux-2.6.10/arch/mips/jmr3927/rbhma3100/setup.c	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/jmr3927/rbhma3100/setup.c	2005-01-06 00:00:26.000000000 +0100
+@@ -108,7 +108,7 @@ static inline void do_reset(void)
+ 
+ static void jmr3927_machine_restart(char *command)
+ {
+-	cli();
++	local_irq_disable();
+ 	puts("Rebooting...");
+ 	do_reset();
+ }
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/Makefile linux-2.6.10-mips/arch/mips/kernel/Makefile
+--- linux-2.6.10/arch/mips/kernel/Makefile	2004-12-24 22:34:32.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/Makefile	2005-01-07 15:38:08.000000000 +0100
+@@ -8,6 +8,9 @@ obj-y		+= cpu-probe.o branch.o entry.o g
+ 		   ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \
+ 		   time.o traps.o unaligned.o
+ 
++binfmt_irix-objs	:= irixelf.o irixinv.o irixioctl.o irixsig.o	\
++			   irix5sys.o sysirix.o
++
+ ifdef CONFIG_MODULES
+ obj-y				+= mips_ksyms.o module.o
+ obj-$(CONFIG_MIPS32)		+= module-elf32.o
+@@ -35,15 +38,16 @@ obj-$(CONFIG_CPU_R6000)		+= r6000_fpu.o 
+ 
+ obj-$(CONFIG_SMP)		+= smp.o
+ 
++obj-$(CONFIG_NO_ISA)		+= dma-no-isa.o
+ obj-$(CONFIG_I8259)		+= i8259.o
+ obj-$(CONFIG_IRQ_CPU)		+= irq_cpu.o
+ obj-$(CONFIG_IRQ_CPU_RM7K)	+= irq-rm7000.o
++obj-$(CONFIG_IRQ_CPU_RM9K)	+= irq-rm9000.o
+ obj-$(CONFIG_IRQ_MV64340)	+= irq-mv6434x.o
+ 
+ obj-$(CONFIG_MIPS32)		+= scall32-o32.o
+ obj-$(CONFIG_MIPS64)		+= scall64-64.o
+-obj-$(CONFIG_BINFMT_IRIX)	+= irixelf.o irixioctl.o irixsig.o sysirix.o \
+-				   irixinv.o
++obj-$(CONFIG_BINFMT_IRIX)	+= binfmt_irix.o
+ obj-$(CONFIG_MIPS32_COMPAT)	+= ioctl32.o linux32.o signal32.o
+ obj-$(CONFIG_MIPS32_N32)	+= binfmt_elfn32.o scall64-n32.o signal_n32.o
+ obj-$(CONFIG_MIPS32_O32)	+= binfmt_elfo32.o scall64-o32.o ptrace32.o
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/dma-no-isa.c linux-2.6.10-mips/arch/mips/kernel/dma-no-isa.c
+--- linux-2.6.10/arch/mips/kernel/dma-no-isa.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/dma-no-isa.c	2004-12-28 10:09:19.000000000 +0100
+@@ -0,0 +1,28 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2004 by Ralf Baechle
++ *
++ * Dummy ISA DMA functions for systems that don't have ISA but share drivers
++ * with ISA such as legacy free PCI.
++ */
++#include <linux/errno.h>
++#include <linux/module.h>
++#include <linux/spinlock.h>
++
++spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
++
++int request_dma(unsigned int dmanr, const char * device_id)
++{
++	return -EINVAL;
++}
++
++void free_dma(unsigned int dmanr)
++{
++}
++
++EXPORT_SYMBOL(dma_spin_lock);
++EXPORT_SYMBOL(request_dma);
++EXPORT_SYMBOL(free_dma);
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/entry.S linux-2.6.10-mips/arch/mips/kernel/entry.S
+--- linux-2.6.10/arch/mips/kernel/entry.S	2004-12-24 22:34:02.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/entry.S	2004-12-21 03:25:15.000000000 +0100
+@@ -19,11 +19,11 @@
+ #include <asm/war.h>
+ 
+ #ifdef CONFIG_PREEMPT
+-	.macro	preempt_stop reg=t0
++	.macro	preempt_stop
+ 	.endm
+ #else
+-	.macro	preempt_stop reg=t0
+-	local_irq_disable \reg
++	.macro	preempt_stop
++	local_irq_disable
+ 	.endm
+ #define resume_kernel	restore_all
+ #endif
+@@ -37,17 +37,17 @@ FEXPORT(ret_from_irq)
+ 	andi	t0, t0, KU_USER
+ 	beqz	t0, resume_kernel
+ 
+-FEXPORT(resume_userspace)
+-	local_irq_disable	t0	# make sure we dont miss an
++resume_userspace:
++	local_irq_disable		# make sure we dont miss an
+ 					# interrupt setting need_resched
+ 					# between sampling and return
+ 	LONG_L	a2, TI_FLAGS($28)	# current->work
+-	andi	a2, _TIF_WORK_MASK	# (ignoring syscall_trace)
+-	bnez	a2, work_pending
++	andi	t0, a2, _TIF_WORK_MASK	# (ignoring syscall_trace)
++	bnez	t0, work_pending
+ 	j	restore_all
+ 
+ #ifdef CONFIG_PREEMPT
+-ENTRY(resume_kernel)
++resume_kernel:
+ 	lw	t0, TI_PRE_COUNT($28)
+ 	bnez	t0, restore_all
+ need_resched:
+@@ -59,10 +59,10 @@ need_resched:
+ 	beqz	t0, restore_all
+ 	li	t0, PREEMPT_ACTIVE
+ 	sw	t0, TI_PRE_COUNT($28)
+-	local_irq_enable t0
++	local_irq_enable
+ 	jal	schedule
+ 	sw	zero, TI_PRE_COUNT($28)
+-	local_irq_disable t0
++	local_irq_disable
+ 	b	need_resched
+ #endif
+ 
+@@ -88,13 +88,13 @@ FEXPORT(restore_partial)		# restore part
+ 	RESTORE_SP_AND_RET
+ 	.set	at
+ 
+-FEXPORT(work_pending)
+-	andi	t0, a2, _TIF_NEED_RESCHED
++work_pending:
++	andi	t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS
+ 	beqz	t0, work_notifysig
+ work_resched:
+ 	jal	schedule
+ 
+-	local_irq_disable t0		# make sure need_resched and
++	local_irq_disable		# make sure need_resched and
+ 					# signals dont change between
+ 					# sampling and return
+ 	LONG_L	a2, TI_FLAGS($28)
+@@ -113,11 +113,10 @@ work_notifysig:				# deal with pending s
+ 
+ FEXPORT(syscall_exit_work_partial)
+ 	SAVE_STATIC
+-FEXPORT(syscall_exit_work)
+-	LONG_L	t0, TI_FLAGS($28)
+-	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+-	and	t0, t1
+-	beqz	t0, work_pending	# trace bit is set
++syscall_exit_work:
++	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
++	and	t0, a2			# a2 is preloaded with TI_FLAGS
++	beqz	t0, work_pending	# trace bit set?
+ 	local_irq_enable		# could let do_syscall_trace()
+ 					# call schedule() instead
+ 	move	a0, sp
+@@ -128,28 +127,25 @@ FEXPORT(syscall_exit_work)
+ /*
+  * Common spurious interrupt handler.
+  */
+-	.text
+-	.align  5
+ LEAF(spurious_interrupt)
+ 	/*
+ 	 * Someone tried to fool us by sending an interrupt but we
+ 	 * couldn't find a cause for it.
+ 	 */
++	PTR_LA	t1, irq_err_count
+ #ifdef CONFIG_SMP
+-	lui     t1, %hi(irq_err_count)
+-1:	ll      t0, %lo(irq_err_count)(t1)
++1:	ll      t0, (t1)
+ 	addiu   t0, 1
+-	sc      t0, %lo(irq_err_count)(t1)
++	sc      t0, (t1)
+ #if R10000_LLSC_WAR
+ 	beqzl	t0, 1b
+ #else
+ 	beqz	t0, 1b
+ #endif
+ #else
+-	lui     t1, %hi(irq_err_count)
+-	lw      t0, %lo(irq_err_count)(t1)
++	lw      t0, (t1)
+ 	addiu   t0, 1
+-	sw      t0, %lo(irq_err_count)(t1)
++	sw      t0, (t1)
+ #endif
+ 	j	ret_from_irq
+ 	END(spurious_interrupt)
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/gdb-stub.c linux-2.6.10-mips/arch/mips/kernel/gdb-stub.c
+--- linux-2.6.10/arch/mips/kernel/gdb-stub.c	2004-12-24 22:35:40.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/gdb-stub.c	2004-12-28 20:06:23.000000000 +0100
+@@ -637,15 +637,18 @@ static struct gdb_bp_save async_bp;
+  * and only one can be active at a time.
+  */
+ extern spinlock_t smp_call_lock;
++
+ void set_async_breakpoint(unsigned long *epc)
+ {
+ 	/* skip breaking into userland */
+ 	if ((*epc & 0x80000000) == 0)
+ 		return;
+ 
++#ifdef CONFIG_SMP
+ 	/* avoid deadlock if someone is make IPC */
+ 	if (spin_is_locked(&smp_call_lock))
+ 		return;
++#endif
+ 
+ 	async_bp.addr = *epc;
+ 	*epc = (unsigned long)async_breakpoint;
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/genex.S linux-2.6.10-mips/arch/mips/kernel/genex.S
+--- linux-2.6.10/arch/mips/kernel/genex.S	2004-12-24 22:34:29.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/genex.S	2004-12-21 03:25:15.000000000 +0100
+@@ -82,7 +82,7 @@ NESTED(except_vec3_r4000, 0, sp)
+ 	 li	k0, 14<<2
+ 	beq	k1, k0, handle_vcei
+ #ifdef CONFIG_MIPS64
+-	dsll	k1, k1, 1
++	 dsll	k1, k1, 1
+ #endif
+ 	.set	pop
+ 	PTR_L	k0, exception_handlers(k1)
+@@ -90,17 +90,17 @@ NESTED(except_vec3_r4000, 0, sp)
+ 
+ 	/*
+ 	 * Big shit, we now may have two dirty primary cache lines for the same
+-	 * physical address.  We can savely invalidate the line pointed to by
++	 * physical address.  We can safely invalidate the line pointed to by
+ 	 * c0_badvaddr because after return from this exception handler the
+ 	 * load / store will be re-executed.
+ 	 */
+ handle_vced:
+-	DMFC0	k0, CP0_BADVADDR
++	MFC0	k0, CP0_BADVADDR
+ 	li	k1, -4					# Is this ...
+ 	and	k0, k1					# ... really needed?
+ 	mtc0	zero, CP0_TAGLO
+-	cache	Index_Store_Tag_D,(k0)
+-	cache	Hit_Writeback_Inv_SD,(k0)
++	cache	Index_Store_Tag_D, (k0)
++	cache	Hit_Writeback_Inv_SD, (k0)
+ #ifdef CONFIG_PROC_FS
+ 	PTR_LA	k0, vced_count
+ 	lw	k1, (k0)
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/head.S linux-2.6.10-mips/arch/mips/kernel/head.S
+--- linux-2.6.10/arch/mips/kernel/head.S	2004-12-24 22:35:01.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/head.S	2004-12-05 02:22:08.000000000 +0100
+@@ -200,19 +200,13 @@ NESTED(smp_bootstrap, 16, sp)
+ 	.comm	fw_arg2, SZREG, SZREG
+ 	.comm	fw_arg3, SZREG, SZREG
+ 
+-	.macro	page name, order=0
+-	.globl	\name
+-\name:	.size	\name, (_PAGE_SIZE << \order)
+-	.org	. + (_PAGE_SIZE << \order)
+-	.type	\name, @object
++	.macro page name, order
++	.comm	\name, (_PAGE_SIZE << \order), (_PAGE_SIZE << \order)
+ 	.endm
+ 
+-	.data
+-	.align	PAGE_SHIFT
+-
+ 	/*
+-	 * ... but on 64-bit we've got three-level pagetables with a
+-	 * slightly different layout ...
++	 * On 64-bit we've got three-level pagetables with a slightly
++	 * different layout ...
+ 	 */
+ 	page	swapper_pg_dir, _PGD_ORDER
+ #ifdef CONFIG_MIPS64
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/irix5sys.S linux-2.6.10-mips/arch/mips/kernel/irix5sys.S
+--- linux-2.6.10/arch/mips/kernel/irix5sys.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/irix5sys.S	2005-01-07 05:26:49.000000000 +0100
+@@ -0,0 +1,1041 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * 32-bit IRIX5 ABI system call table derived from original file 'irix5sys.h'
++ * created by David S. Miller.
++ *
++ * Copyright (C) 1996 - 2004 David S. Miller <dm at engr.sgi.com>
++ * Copyright (C) 2004 Steven J. Hill <sjhill at realitydiluted.com>
++ */
++#include <asm/asm.h>
++
++	/*
++	 * Key:
++	 *         V == Valid and should work as expected for most cases.
++	 *        HV == Half Valid, some things will work, some likely will not
++	 *        IV == InValid, certainly will not work at all yet
++	 *        ?V == ?'ably Valid, I have not done enough looking into it
++	 *        DC == Don't Care, a rats ass we couldn't give
++	 */
++
++	.macro	irix5syscalltable
++
++	sys	sys_syscall	0	/* 1000  sysindir()	       V*/
++	sys	sys_exit	1	/* 1001  exit()		       V*/
++	sys	sys_fork	0	/* 1002  fork()		       V*/
++	sys	sys_read	3	/* 1003  read()		       V*/
++	sys	sys_write	3	/* 1004  write()	       V*/
++	sys	sys_open	3	/* 1005  open()		       V*/
++	sys	sys_close	1	/* 1006  close()	       V*/
++	sys	irix_unimp	0	/* 1007  (XXX IRIX 4 wait)     V*/
++	sys	sys_creat	2	/* 1008  creat()	       V*/
++	sys	sys_link	2	/* 1009  link()		       V*/
++	sys	sys_unlink	1	/* 1010  unlink()	       V*/
++	sys	irix_exec	0	/* 1011  exec()		       V*/
++	sys	sys_chdir	1	/* 1012  chdir()	       V*/
++	sys	irix_gtime	0	/* 1013  time()		       V*/
++	sys	irix_unimp	0	/* 1014  (XXX IRIX 4 mknod)    V*/
++	sys	sys_chmod	2	/* 1015  chmod()	       V*/
++	sys	sys_chown	3	/* 1016  chown()	       V*/
++	sys	irix_brk	1	/* 1017  break()	       V*/
++	sys	irix_unimp	0	/* 1018  (XXX IRIX 4 stat)     V*/
++	sys	sys_lseek	3	/* 1019  lseek()     XXX64bit HV*/
++	sys	irix_getpid	0	/* 1020  getpid()	       V*/
++	sys	irix_mount	6	/* 1021  mount()	      IV*/
++	sys	sys_umount	1	/* 1022  umount()	       V*/
++	sys	sys_setuid	1	/* 1023  setuid()	       V*/
++	sys	irix_getuid	0	/* 1024  getuid()	       V*/
++	sys	irix_stime	1	/* 1025  stime()	       V*/
++	sys	irix_unimp	4	/* 1026  XXX ptrace()	      IV*/
++	sys	irix_alarm	1	/* 1027  alarm()	       V*/
++	sys	irix_unimp	0	/* 1028  (XXX IRIX 4 fstat)    V*/
++	sys	irix_pause	0	/* 1029  pause()	       V*/
++	sys	sys_utime	2	/* 1030  utime()	       V*/
++	sys	irix_unimp	0	/* 1031  nuthin'	       V*/
++	sys	irix_unimp	0	/* 1032  nobody home man...    V*/
++	sys	sys_access	2	/* 1033  access()	       V*/
++	sys	sys_nice	1	/* 1034  nice()		       V*/
++	sys	irix_statfs	2	/* 1035  statfs()	       V*/
++	sys	sys_sync	0	/* 1036  sync()		       V*/
++	sys	sys_kill	2	/* 1037  kill()		       V*/
++	sys	irix_fstatfs	2	/* 1038  fstatfs()	       V*/
++	sys	irix_setpgrp	1	/* 1039  setpgrp()	       V*/
++	sys	irix_syssgi	0	/* 1040  syssgi()	      HV*/
++	sys	sys_dup		1	/* 1041  dup()		       V*/
++	sys	sys_pipe	0	/* 1042  pipe()		       V*/
++	sys	irix_times	1	/* 1043  times()	       V*/
++	sys	irix_unimp	0	/* 1044  XXX profil()	      IV*/
++	sys	irix_unimp	0	/* 1045  XXX lock()	      IV*/
++	sys	sys_setgid	1	/* 1046  setgid()	       V*/
++	sys	irix_getgid	0	/* 1047  getgid()	       V*/
++	sys	irix_unimp	0	/* 1048  (XXX IRIX 4 ssig)     V*/
++	sys	irix_msgsys	6	/* 1049  sys_msgsys	       V*/
++	sys	sys_sysmips	4	/* 1050  sysmips()	      HV*/
++	sys	irix_unimp	0	/* 1051	 XXX sysacct()	      IV*/
++	sys	irix_shmsys	5	/* 1052  sys_shmsys	       V*/
++	sys	irix_semsys	0	/* 1053  sys_semsys	       V*/
++	sys	irix_ioctl	3	/* 1054  ioctl()	      HV*/
++	sys	irix_uadmin	0	/* 1055  XXX sys_uadmin()     HC*/
++	sys	irix_sysmp	0	/* 1056  sysmp()	      HV*/
++	sys	irix_utssys	4	/* 1057  sys_utssys()	      HV*/
++	sys	irix_unimp	0	/* 1058  nada enchilada	       V*/
++	sys	irix_exece	0	/* 1059  exece()	       V*/
++	sys	sys_umask	1	/* 1060  umask()	       V*/
++	sys	sys_chroot	1	/* 1061  chroot()	       V*/
++	sys	irix_fcntl	3	/* 1062  fcntl()	      ?V*/
++	sys	irix_ulimit	2	/* 1063  ulimit()	      HV*/
++	sys	irix_unimp	0	/* 1064  XXX AFS shit	      DC*/
++	sys	irix_unimp	0	/* 1065  XXX AFS shit	      DC*/
++	sys	irix_unimp	0	/* 1066  XXX AFS shit	      DC*/
++	sys	irix_unimp	0	/* 1067  XXX AFS shit	      DC*/
++	sys	irix_unimp	0	/* 1068  XXX AFS shit	      DC*/
++	sys	irix_unimp	0	/* 1069  XXX AFS shit	      DC*/
++	sys	irix_unimp	0	/* 1070  XXX AFS shit	      DC*/
++	sys	irix_unimp	0	/* 1071  XXX AFS shit	      DC*/
++	sys	irix_unimp	0	/* 1072  XXX AFS shit	      DC*/
++	sys	irix_unimp	0	/* 1073  XXX AFS shit	      DC*/
++	sys	irix_unimp	0	/* 1074  nuttin'	       V*/
++	sys	irix_unimp	0	/* 1075  XXX sys_getrlimit64()IV*/
++	sys	irix_unimp	0	/* 1076  XXX sys_setrlimit64()IV*/
++	sys	sys_nanosleep	2	/* 1077  nanosleep()	       V*/
++	sys	irix_lseek64	5	/* 1078  lseek64()	      ?V*/
++	sys	sys_rmdir	1	/* 1079  rmdir()	       V*/
++	sys	sys_mkdir	2	/* 1080  mkdir()	       V*/
++	sys	sys_getdents	3	/* 1081  getdents()	       V*/
++	sys	irix_sginap	1	/* 1082  sys_sginap()	       V*/
++	sys	irix_sgikopt	3	/* 1083  sys_sgikopt()	      DC*/
++	sys	sys_sysfs	3	/* 1084  sysfs()	      ?V*/
++	sys	irix_unimp	0	/* 1085  XXX sys_getmsg()     DC*/
++	sys	irix_unimp	0	/* 1086  XXX sys_putmsg()     DC*/
++	sys	sys_poll	3	/* 1087  poll()	               V*/
++	sys	irix_sigreturn	0	/* 1088  sigreturn()	      ?V*/
++	sys	sys_accept	3	/* 1089  accept()	       V*/
++	sys	sys_bind	3	/* 1090  bind()		       V*/
++	sys	sys_connect	3	/* 1091  connect()	       V*/
++	sys	irix_gethostid	0	/* 1092  sys_gethostid()      ?V*/
++	sys	sys_getpeername	3	/* 1093  getpeername()	       V*/
++	sys	sys_getsockname	3	/* 1094  getsockname()	       V*/
++	sys	sys_getsockopt	5	/* 1095  getsockopt()	       V*/
++	sys	sys_listen	2	/* 1096  listen()	       V*/
++	sys	sys_recv	4	/* 1097  recv()		       V*/
++	sys	sys_recvfrom	6	/* 1098  recvfrom()	       V*/
++	sys	sys_recvmsg	3	/* 1099  recvmsg()	       V*/
++	sys	sys_select	5	/* 1100  select()	       V*/
++	sys	sys_send	4	/* 1101  send()		       V*/
++	sys	sys_sendmsg	3	/* 1102  sendmsg()	       V*/
++	sys	sys_sendto	6	/* 1103  sendto()	       V*/
++	sys	irix_sethostid	1	/* 1104  sys_sethostid()      ?V*/
++	sys	sys_setsockopt	5	/* 1105  setsockopt()	       V*/
++	sys	sys_shutdown	2	/* 1106  shutdown()	      ?V*/
++	sys	irix_socket	3	/* 1107  socket()	       V*/
++	sys	sys_gethostname	2	/* 1108  sys_gethostname()    ?V*/
++	sys	sys_sethostname	2	/* 1109  sethostname()	      ?V*/
++	sys	irix_getdomainname 2	/* 1110  sys_getdomainname()  ?V*/
++	sys	sys_setdomainname 2	/* 1111  setdomainname()      ?V*/
++	sys	sys_truncate	2	/* 1112  truncate()	       V*/
++	sys	sys_ftruncate	2	/* 1113  ftruncate()	       V*/
++	sys	sys_rename	2	/* 1114  rename()	       V*/
++	sys	sys_symlink	2	/* 1115  symlink()	       V*/
++	sys	sys_readlink	3	/* 1116  readlink()	       V*/
++	sys	irix_unimp	0	/* 1117  XXX IRIX 4 lstat()   DC*/
++	sys	irix_unimp	0	/* 1118  nothin'	       V*/
++	sys	irix_unimp	0	/* 1119  XXX nfs_svc()	      DC*/
++	sys	irix_unimp	0	/* 1120  XXX nfs_getfh()      DC*/
++	sys	irix_unimp	0	/* 1121  XXX async_daemon()   DC*/
++	sys	irix_unimp	0	/* 1122  XXX exportfs()	      DC*/
++	sys	sys_setregid	2	/* 1123  setregid()	       V*/
++	sys	sys_setreuid	2	/* 1124  setreuid()	       V*/
++	sys	sys_getitimer	2	/* 1125  getitimer()	       V*/
++	sys	sys_setitimer	3	/* 1126  setitimer()	       V*/
++	sys	irix_unimp	1	/* 1127  XXX adjtime() 	      IV*/
++	sys	irix_gettimeofday 1	/* 1128  gettimeofday()	       V*/
++	sys	irix_unimp	0	/* 1129  XXX sproc()	      IV*/
++	sys	irix_prctl	0	/* 1130  prctl()	      HV*/
++	sys	irix_unimp	0	/* 1131  XXX procblk()	      IV*/
++	sys	irix_unimp	0	/* 1132  XXX sprocsp()	      IV*/
++	sys	irix_unimp	0	/* 1133  XXX sgigsc()	      IV*/
++	sys	irix_mmap32	6	/* 1134  mmap()	   XXXflags?  ?V*/
++	sys	sys_munmap	2	/* 1135  munmap()	       V*/
++	sys	sys_mprotect	3	/* 1136  mprotect()	       V*/
++	sys	sys_msync	4	/* 1137  msync()	       V*/
++	sys	irix_madvise	3	/* 1138  madvise()	      DC*/
++	sys	irix_pagelock	3	/* 1139  pagelock()	      IV*/
++	sys	irix_getpagesize 0	/* 1140  getpagesize()         V*/
++	sys	irix_quotactl	0	/* 1141  quotactl()	       V*/
++	sys	irix_unimp	0	/* 1142  nobody home man       V*/
++	sys	sys_getpgid	1	/* 1143  BSD getpgrp()	       V*/
++	sys	irix_BSDsetpgrp 2	/* 1143  BSD setpgrp()	       V*/
++	sys	sys_vhangup	0	/* 1144  vhangup()	       V*/
++	sys	sys_fsync	1	/* 1145  fsync()	       V*/
++	sys	sys_fchdir	1	/* 1146  fchdir()	       V*/
++	sys	sys_getrlimit	2	/* 1147  getrlimit()	      ?V*/
++	sys	sys_setrlimit	2	/* 1148  setrlimit()	      ?V*/
++	sys	sys_cacheflush	3	/* 1150  cacheflush()	      HV*/
++	sys	sys_cachectl	3	/* 1151  cachectl()	      HV*/
++	sys	sys_fchown	3	/* 1152  fchown()	      ?V*/
++	sys	sys_fchmod	2	/* 1153  fchmod()	      ?V*/
++	sys	irix_unimp	0	/* 1154  XXX IRIX 4 wait3()    V*/
++	sys	sys_socketpair	4	/* 1155  socketpair()	       V*/
++	sys	irix_systeminfo	3	/* 1156  systeminfo()	      IV*/
++	sys	irix_uname	1	/* 1157  uname()	      IV*/
++	sys	irix_xstat	3	/* 1158  xstat()	       V*/
++	sys	irix_lxstat	3	/* 1159  lxstat()	       V*/
++	sys	irix_fxstat	3	/* 1160  fxstat()	       V*/
++	sys	irix_xmknod	0	/* 1161  xmknod()	      ?V*/
++	sys	irix_sigaction	4	/* 1162  sigaction()	      ?V*/
++	sys	irix_sigpending	1	/* 1163  sigpending()	      ?V*/
++	sys	irix_sigprocmask 3	/* 1164  sigprocmask()	      ?V*/
++	sys	irix_sigsuspend	0	/* 1165  sigsuspend()	      ?V*/
++	sys	irix_sigpoll_sys 3	/* 1166  sigpoll_sys()	      IV*/
++	sys	irix_swapctl	2	/* 1167  swapctl()	      IV*/
++	sys	irix_getcontext	0	/* 1168  getcontext()	      HV*/
++	sys	irix_setcontext	0	/* 1169  setcontext()	      HV*/
++	sys	irix_waitsys	5	/* 1170  waitsys()	      IV*/
++	sys	irix_sigstack	2	/* 1171  sigstack()	      HV*/
++	sys	irix_sigaltstack 2	/* 1172  sigaltstack()	      HV*/
++	sys	irix_sigsendset	2	/* 1173  sigsendset()	      IV*/
++	sys	irix_statvfs	2	/* 1174  statvfs()	       V*/
++	sys	irix_fstatvfs	2	/* 1175  fstatvfs()	       V*/
++	sys	irix_unimp	0	/* 1176  XXX getpmsg()	      DC*/
++	sys	irix_unimp	0	/* 1177  XXX putpmsg()	      DC*/
++	sys	sys_lchown	3	/* 1178  lchown()	       V*/
++	sys	irix_priocntl	0	/* 1179  priocntl()	      DC*/
++	sys	irix_sigqueue	4	/* 1180  sigqueue()	      IV*/
++	sys	sys_readv	3	/* 1181  readv()	       V*/
++	sys	sys_writev	3	/* 1182  writev()	       V*/
++	sys	irix_truncate64 4	/* 1183  truncate64() XX32bit HV*/
++	sys	irix_ftruncate64 4	/* 1184  ftruncate64()XX32bit HV*/
++	sys	irix_mmap64	0	/* 1185  mmap64()     XX32bit HV*/
++	sys	irix_dmi	0	/* 1186  dmi()		      DC*/
++	sys	irix_pread	6	/* 1187  pread()	      IV*/
++	sys	irix_pwrite	6	/* 1188  pwrite()	      IV*/
++	sys	sys_fsync	1	/* 1189  fdatasync()  XXPOSIX HV*/
++	sys	irix_sgifastpath 7	/* 1190  sgifastpath() WHEEE  IV*/
++	sys	irix_unimp	0	/* 1191  XXX attr_get()	      DC*/
++	sys	irix_unimp	0	/* 1192  XXX attr_getf()      DC*/
++	sys	irix_unimp	0	/* 1193  XXX attr_set()	      DC*/
++	sys	irix_unimp	0	/* 1194  XXX attr_setf()      DC*/
++	sys	irix_unimp	0	/* 1195  XXX attr_remove()    DC*/
++	sys	irix_unimp	0	/* 1196  XXX attr_removef()   DC*/
++	sys	irix_unimp	0	/* 1197  XXX attr_list()      DC*/
++	sys	irix_unimp	0	/* 1198  XXX attr_listf()     DC*/
++	sys	irix_unimp	0	/* 1199  XXX attr_multi()     DC*/
++	sys	irix_unimp	0	/* 1200  XXX attr_multif()    DC*/
++	sys	irix_statvfs64	2	/* 1201  statvfs64()	       V*/
++	sys	irix_fstatvfs64	2	/* 1202  fstatvfs64()	       V*/
++	sys	irix_getmountid	2	/* 1203  getmountid()XXXfsids HV*/
++	sys	irix_nsproc	5	/* 1204  nsproc()	      IV*/
++	sys	irix_getdents64 3	/* 1205  getdents64()	      HV*/
++	sys	irix_unimp	0	/* 1206  XXX DFS garbage      DC*/
++	sys	irix_ngetdents	4	/* 1207  ngetdents() XXXeop   HV*/
++	sys	irix_ngetdents64 4	/* 1208  ngetdents64() XXXeop HV*/
++	sys	irix_unimp	0	/* 1209  nothin'	       V*/
++	sys	irix_unimp	0	/* 1210  XXX pidsprocsp()	*/
++	sys	irix_unimp	0	/* 1211  XXX rexec()		*/
++	sys	irix_unimp	0	/* 1212  XXX timer_create()	*/
++	sys	irix_unimp	0	/* 1213  XXX timer_delete()	*/
++	sys	irix_unimp	0	/* 1214  XXX timer_settime()	*/
++	sys	irix_unimp	0	/* 1215  XXX timer_gettime()	*/
++	sys	irix_unimp	0	/* 1216  XXX timer_setoverrun()	*/
++	sys	sys_sched_rr_get_interval 2		/* 1217  sched_rr_get_interval()V*/
++	sys	sys_sched_yield	0	/* 1218  sched_yield()	       V*/
++	sys	sys_sched_getscheduler 1 /* 1219  sched_getscheduler()  V*/
++	sys	sys_sched_setscheduler 3 /* 1220  sched_setscheduler()  V*/
++	sys	sys_sched_getparam 2	/* 1221  sched_getparam()      V*/
++	sys	sys_sched_setparam 2	/* 1222  sched_setparam()      V*/
++	sys	irix_unimp	0	/* 1223  XXX usync_cntl()	*/
++	sys	irix_unimp	0	/* 1224  XXX psema_cntl()	*/
++	sys	irix_unimp	0	/* 1225  XXX restartreturn()	*/
++
++	/* Just to pad things out nicely. */
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++	sys	irix_unimp	0
++
++	.endm
++
++	/*
++	 * Pre-compute the number of _instruction_ bytes needed to load
++	 * or store the arguments 6-8. Negative values are ignored.
++	 */
++	.macro  sys function, nargs
++	PTR	\function
++	LONG	(\nargs << 2) - (5 << 2)
++	.endm
++
++	.align	4
++EXPORT(sys_call_table_irix5)
++	irix5syscalltable
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/irix5sys.h linux-2.6.10-mips/arch/mips/kernel/irix5sys.h
+--- linux-2.6.10/arch/mips/kernel/irix5sys.h	2004-12-24 22:33:49.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/irix5sys.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,1029 +0,0 @@
+-/*
+- * irix5sys.h: 32-bit IRIX5 ABI system call table.
+- *
+- * Copyright (C) 1996 David S. Miller (dm at engr.sgi.com)
+- */
+-
+-/* This file is being included twice - once to build a list of all
+- * syscalls and once to build a table of how many arguments each syscall
+- * accepts.  Syscalls that receive a pointer to the saved registers are
+- * marked as having zero arguments.
+- */
+-#include <linux/config.h>
+-
+-/* Keys:
+- *         V == Valid and should work as expected for most cases.
+- *        HV == Half Valid, some things will work, some likely will not
+- *        IV == InValid, certainly will not work at all yet
+- *        ?V == ?'ably Valid, I have not done enough looking into it
+- *        DC == Don't Care, a rats ass we couldn't give
+- */
+-
+-#ifdef CONFIG_BINFMT_IRIX
+-	sys	sys_syscall	0	/* 1000  sysindir()	       V*/
+-	sys	sys_exit	1	/* 1001  exit()		       V*/
+-	sys	sys_fork	0	/* 1002  fork()		       V*/
+-	sys	sys_read	3	/* 1003  read()		       V*/
+-	sys	sys_write	3	/* 1004  write()	       V*/
+-	sys	sys_open	3	/* 1005  open()		       V*/
+-	sys	sys_close	1	/* 1006  close()	       V*/
+-	sys	irix_unimp	0	/* 1007  (XXX IRIX 4 wait)     V*/
+-	sys	sys_creat	2	/* 1008  creat()	       V*/
+-	sys	sys_link	2	/* 1009  link()		       V*/
+-	sys	sys_unlink	1	/* 1010  unlink()	       V*/
+-	sys	irix_exec	0	/* 1011  exec()		       V*/
+-	sys	sys_chdir	1	/* 1012  chdir()	       V*/
+-	sys	irix_gtime	0	/* 1013  time()		       V*/
+-	sys	irix_unimp	0	/* 1014  (XXX IRIX 4 mknod)    V*/
+-	sys	sys_chmod	2	/* 1015  chmod()	       V*/
+-	sys	sys_chown	3	/* 1016  chown()	       V*/
+-	sys	irix_brk	1	/* 1017  break()	       V*/
+-	sys	irix_unimp	0	/* 1018  (XXX IRIX 4 stat)     V*/
+-	sys	sys_lseek	3	/* 1019  lseek()     XXX64bit HV*/
+-	sys	irix_getpid	0	/* 1020  getpid()	       V*/
+-	sys	irix_mount	6	/* 1021  mount()	      IV*/
+-	sys	sys_umount	1	/* 1022  umount()	       V*/
+-	sys	sys_setuid	1	/* 1023  setuid()	       V*/
+-	sys	irix_getuid	0	/* 1024  getuid()	       V*/
+-	sys	irix_stime	1	/* 1025  stime()	       V*/
+-	sys	irix_unimp	4	/* 1026  XXX ptrace()	      IV*/
+-	sys	irix_alarm	1	/* 1027  alarm()	       V*/
+-	sys	irix_unimp	0	/* 1028  (XXX IRIX 4 fstat)    V*/
+-	sys	irix_pause	0	/* 1029  pause()	       V*/
+-	sys	sys_utime	2	/* 1030  utime()	       V*/
+-	sys	irix_unimp	0	/* 1031  nuthin'	       V*/
+-	sys	irix_unimp	0	/* 1032  nobody home man...    V*/
+-	sys	sys_access	2	/* 1033  access()	       V*/
+-	sys	sys_nice	1	/* 1034  nice()		       V*/
+-	sys	irix_statfs	2	/* 1035  statfs()	       V*/
+-	sys	sys_sync	0	/* 1036  sync()		       V*/
+-	sys	sys_kill	2	/* 1037  kill()		       V*/
+-	sys	irix_fstatfs	2	/* 1038  fstatfs()	       V*/
+-	sys	irix_setpgrp	1	/* 1039  setpgrp()	       V*/
+-	sys	irix_syssgi	0	/* 1040  syssgi()	      HV*/
+-	sys	sys_dup		1	/* 1041  dup()		       V*/
+-	sys	sys_pipe	0	/* 1042  pipe()		       V*/
+-	sys	irix_times	1	/* 1043  times()	       V*/
+-	sys	irix_unimp	0	/* 1044  XXX profil()	      IV*/
+-	sys	irix_unimp	0	/* 1045  XXX lock()	      IV*/
+-	sys	sys_setgid	1	/* 1046  setgid()	       V*/
+-	sys	irix_getgid	0	/* 1047  getgid()	       V*/
+-	sys	irix_unimp	0	/* 1048  (XXX IRIX 4 ssig)     V*/
+-	sys	irix_msgsys	6	/* 1049  sys_msgsys	       V*/
+-	sys	sys_sysmips	4	/* 1050  sysmips()	      HV*/
+-	sys	irix_unimp	0	/* 1051	 XXX sysacct()	      IV*/
+-	sys	irix_shmsys	5	/* 1052  sys_shmsys	       V*/
+-	sys	irix_semsys	0	/* 1053  sys_semsys	       V*/
+-	sys	irix_ioctl	3	/* 1054  ioctl()	      HV*/
+-	sys	irix_uadmin	0	/* 1055  XXX sys_uadmin()     HC*/
+-	sys	irix_sysmp	0	/* 1056  sysmp()	      HV*/
+-	sys	irix_utssys	4	/* 1057  sys_utssys()	      HV*/
+-	sys	irix_unimp	0	/* 1058  nada enchilada	       V*/
+-	sys	irix_exece	0	/* 1059  exece()	       V*/
+-	sys	sys_umask	1	/* 1060  umask()	       V*/
+-	sys	sys_chroot	1	/* 1061  chroot()	       V*/
+-	sys	irix_fcntl	3	/* 1062  fcntl()	      ?V*/
+-	sys	irix_ulimit	2	/* 1063  ulimit()	      HV*/
+-	sys	irix_unimp	0	/* 1064  XXX AFS shit	      DC*/
+-	sys	irix_unimp	0	/* 1065  XXX AFS shit	      DC*/
+-	sys	irix_unimp	0	/* 1066  XXX AFS shit	      DC*/
+-	sys	irix_unimp	0	/* 1067  XXX AFS shit	      DC*/
+-	sys	irix_unimp	0	/* 1068  XXX AFS shit	      DC*/
+-	sys	irix_unimp	0	/* 1069  XXX AFS shit	      DC*/
+-	sys	irix_unimp	0	/* 1070  XXX AFS shit	      DC*/
+-	sys	irix_unimp	0	/* 1071  XXX AFS shit	      DC*/
+-	sys	irix_unimp	0	/* 1072  XXX AFS shit	      DC*/
+-	sys	irix_unimp	0	/* 1073  XXX AFS shit	      DC*/
+-	sys	irix_unimp	0	/* 1074  nuttin'	       V*/
+-	sys	irix_unimp	0	/* 1075  XXX sys_getrlimit64()IV*/
+-	sys	irix_unimp	0	/* 1076  XXX sys_setrlimit64()IV*/
+-	sys	sys_nanosleep	2	/* 1077  nanosleep()	       V*/
+-	sys	irix_lseek64	5	/* 1078  lseek64()	      ?V*/
+-	sys	sys_rmdir	1	/* 1079  rmdir()	       V*/
+-	sys	sys_mkdir	2	/* 1080  mkdir()	       V*/
+-	sys	sys_getdents	3	/* 1081  getdents()	       V*/
+-	sys	irix_sginap	1	/* 1082  sys_sginap()	       V*/
+-	sys	irix_sgikopt	3	/* 1083  sys_sgikopt()	      DC*/
+-	sys	sys_sysfs	3	/* 1084  sysfs()	      ?V*/
+-	sys	irix_unimp	0	/* 1085  XXX sys_getmsg()     DC*/
+-	sys	irix_unimp	0	/* 1086  XXX sys_putmsg()     DC*/
+-	sys	sys_poll	3	/* 1087  poll()	               V*/
+-	sys	irix_sigreturn	0	/* 1088  sigreturn()	      ?V*/
+-	sys	sys_accept	3	/* 1089  accept()	       V*/
+-	sys	sys_bind	3	/* 1090  bind()		       V*/
+-	sys	sys_connect	3	/* 1091  connect()	       V*/
+-	sys	irix_gethostid	0	/* 1092  sys_gethostid()      ?V*/
+-	sys	sys_getpeername	3	/* 1093  getpeername()	       V*/
+-	sys	sys_getsockname	3	/* 1094  getsockname()	       V*/
+-	sys	sys_getsockopt	5	/* 1095  getsockopt()	       V*/
+-	sys	sys_listen	2	/* 1096  listen()	       V*/
+-	sys	sys_recv	4	/* 1097  recv()		       V*/
+-	sys	sys_recvfrom	6	/* 1098  recvfrom()	       V*/
+-	sys	sys_recvmsg	3	/* 1099  recvmsg()	       V*/
+-	sys	sys_select	5	/* 1100  select()	       V*/
+-	sys	sys_send	4	/* 1101  send()		       V*/
+-	sys	sys_sendmsg	3	/* 1102  sendmsg()	       V*/
+-	sys	sys_sendto	6	/* 1103  sendto()	       V*/
+-	sys	irix_sethostid	1	/* 1104  sys_sethostid()      ?V*/
+-	sys	sys_setsockopt	5	/* 1105  setsockopt()	       V*/
+-	sys	sys_shutdown	2	/* 1106  shutdown()	      ?V*/
+-	sys	irix_socket	3	/* 1107  socket()	       V*/
+-	sys	sys_gethostname	2	/* 1108  sys_gethostname()    ?V*/
+-	sys	sys_sethostname	2	/* 1109  sethostname()	      ?V*/
+-	sys	irix_getdomainname 2	/* 1110  sys_getdomainname()  ?V*/
+-	sys	sys_setdomainname 2	/* 1111  setdomainname()      ?V*/
+-	sys	sys_truncate	2	/* 1112  truncate()	       V*/
+-	sys	sys_ftruncate	2	/* 1113  ftruncate()	       V*/
+-	sys	sys_rename	2	/* 1114  rename()	       V*/
+-	sys	sys_symlink	2	/* 1115  symlink()	       V*/
+-	sys	sys_readlink	3	/* 1116  readlink()	       V*/
+-	sys	irix_unimp	0	/* 1117  XXX IRIX 4 lstat()   DC*/
+-	sys	irix_unimp	0	/* 1118  nothin'	       V*/
+-	sys	irix_unimp	0	/* 1119  XXX nfs_svc()	      DC*/
+-	sys	irix_unimp	0	/* 1120  XXX nfs_getfh()      DC*/
+-	sys	irix_unimp	0	/* 1121  XXX async_daemon()   DC*/
+-	sys	irix_unimp	0	/* 1122  XXX exportfs()	      DC*/
+-	sys	sys_setregid	2	/* 1123  setregid()	       V*/
+-	sys	sys_setreuid	2	/* 1124  setreuid()	       V*/
+-	sys	sys_getitimer	2	/* 1125  getitimer()	       V*/
+-	sys	sys_setitimer	3	/* 1126  setitimer()	       V*/
+-	sys	irix_unimp	1	/* 1127  XXX adjtime() 	      IV*/
+-	sys	irix_gettimeofday 1	/* 1128  gettimeofday()	       V*/
+-	sys	irix_unimp	0	/* 1129  XXX sproc()	      IV*/
+-	sys	irix_prctl	0	/* 1130  prctl()	      HV*/
+-	sys	irix_unimp	0	/* 1131  XXX procblk()	      IV*/
+-	sys	irix_unimp	0	/* 1132  XXX sprocsp()	      IV*/
+-	sys	irix_unimp	0	/* 1133  XXX sgigsc()	      IV*/
+-	sys	irix_mmap32	6	/* 1134  mmap()	   XXXflags?  ?V*/
+-	sys	sys_munmap	2	/* 1135  munmap()	       V*/
+-	sys	sys_mprotect	3	/* 1136  mprotect()	       V*/
+-	sys	sys_msync	4	/* 1137  msync()	       V*/
+-	sys	irix_madvise	3	/* 1138  madvise()	      DC*/
+-	sys	irix_pagelock	3	/* 1139  pagelock()	      IV*/
+-	sys	irix_getpagesize 0	/* 1140  getpagesize()         V*/
+-	sys	irix_quotactl	0	/* 1141  quotactl()	       V*/
+-	sys	irix_unimp	0	/* 1142  nobody home man       V*/
+-	sys	sys_getpgid	1	/* 1143  BSD getpgrp()	       V*/
+-	sys	irix_BSDsetpgrp 2	/* 1143  BSD setpgrp()	       V*/
+-	sys	sys_vhangup	0	/* 1144  vhangup()	       V*/
+-	sys	sys_fsync	1	/* 1145  fsync()	       V*/
+-	sys	sys_fchdir	1	/* 1146  fchdir()	       V*/
+-	sys	sys_getrlimit	2	/* 1147  getrlimit()	      ?V*/
+-	sys	sys_setrlimit	2	/* 1148  setrlimit()	      ?V*/
+-	sys	sys_cacheflush	3	/* 1150  cacheflush()	      HV*/
+-	sys	sys_cachectl	3	/* 1151  cachectl()	      HV*/
+-	sys	sys_fchown	3	/* 1152  fchown()	      ?V*/
+-	sys	sys_fchmod	2	/* 1153  fchmod()	      ?V*/
+-	sys	irix_unimp	0	/* 1154  XXX IRIX 4 wait3()    V*/
+-	sys	sys_socketpair	4	/* 1155  socketpair()	       V*/
+-	sys	irix_systeminfo	3	/* 1156  systeminfo()	      IV*/
+-	sys	irix_uname	1	/* 1157  uname()	      IV*/
+-	sys	irix_xstat	3	/* 1158  xstat()	       V*/
+-	sys	irix_lxstat	3	/* 1159  lxstat()	       V*/
+-	sys	irix_fxstat	3	/* 1160  fxstat()	       V*/
+-	sys	irix_xmknod	0	/* 1161  xmknod()	      ?V*/
+-	sys	irix_sigaction	4	/* 1162  sigaction()	      ?V*/
+-	sys	irix_sigpending	1	/* 1163  sigpending()	      ?V*/
+-	sys	irix_sigprocmask 3	/* 1164  sigprocmask()	      ?V*/
+-	sys	irix_sigsuspend	0	/* 1165  sigsuspend()	      ?V*/
+-	sys	irix_sigpoll_sys 3	/* 1166  sigpoll_sys()	      IV*/
+-	sys	irix_swapctl	2	/* 1167  swapctl()	      IV*/
+-	sys	irix_getcontext	0	/* 1168  getcontext()	      HV*/
+-	sys	irix_setcontext	0	/* 1169  setcontext()	      HV*/
+-	sys	irix_waitsys	5	/* 1170  waitsys()	      IV*/
+-	sys	irix_sigstack	2	/* 1171  sigstack()	      HV*/
+-	sys	irix_sigaltstack 2	/* 1172  sigaltstack()	      HV*/
+-	sys	irix_sigsendset	2	/* 1173  sigsendset()	      IV*/
+-	sys	irix_statvfs	2	/* 1174  statvfs()	       V*/
+-	sys	irix_fstatvfs	2	/* 1175  fstatvfs()	       V*/
+-	sys	irix_unimp	0	/* 1176  XXX getpmsg()	      DC*/
+-	sys	irix_unimp	0	/* 1177  XXX putpmsg()	      DC*/
+-	sys	sys_lchown	3	/* 1178  lchown()	       V*/
+-	sys	irix_priocntl	0	/* 1179  priocntl()	      DC*/
+-	sys	irix_sigqueue	4	/* 1180  sigqueue()	      IV*/
+-	sys	sys_readv	3	/* 1181  readv()	       V*/
+-	sys	sys_writev	3	/* 1182  writev()	       V*/
+-	sys	irix_truncate64 4	/* 1183  truncate64() XX32bit HV*/
+-	sys	irix_ftruncate64 4	/* 1184  ftruncate64()XX32bit HV*/
+-	sys	irix_mmap64	0	/* 1185  mmap64()     XX32bit HV*/
+-	sys	irix_dmi	0	/* 1186  dmi()		      DC*/
+-	sys	irix_pread	6	/* 1187  pread()	      IV*/
+-	sys	irix_pwrite	6	/* 1188  pwrite()	      IV*/
+-	sys	sys_fsync	1	/* 1189  fdatasync()  XXPOSIX HV*/
+-	sys	irix_sgifastpath 7	/* 1190  sgifastpath() WHEEE  IV*/
+-	sys	irix_unimp	0	/* 1191  XXX attr_get()	      DC*/
+-	sys	irix_unimp	0	/* 1192  XXX attr_getf()      DC*/
+-	sys	irix_unimp	0	/* 1193  XXX attr_set()	      DC*/
+-	sys	irix_unimp	0	/* 1194  XXX attr_setf()      DC*/
+-	sys	irix_unimp	0	/* 1195  XXX attr_remove()    DC*/
+-	sys	irix_unimp	0	/* 1196  XXX attr_removef()   DC*/
+-	sys	irix_unimp	0	/* 1197  XXX attr_list()      DC*/
+-	sys	irix_unimp	0	/* 1198  XXX attr_listf()     DC*/
+-	sys	irix_unimp	0	/* 1199  XXX attr_multi()     DC*/
+-	sys	irix_unimp	0	/* 1200  XXX attr_multif()    DC*/
+-	sys	irix_statvfs64	2	/* 1201  statvfs64()	       V*/
+-	sys	irix_fstatvfs64	2	/* 1202  fstatvfs64()	       V*/
+-	sys	irix_getmountid	2	/* 1203  getmountid()XXXfsids HV*/
+-	sys	irix_nsproc	5	/* 1204  nsproc()	      IV*/
+-	sys	irix_getdents64 3	/* 1205  getdents64()	      HV*/
+-	sys	irix_unimp	0	/* 1206  XXX DFS garbage      DC*/
+-	sys	irix_ngetdents	4	/* 1207  ngetdents() XXXeop   HV*/
+-	sys	irix_ngetdents64 4	/* 1208  ngetdents64() XXXeop HV*/
+-	sys	irix_unimp	0	/* 1209  nothin'	       V*/
+-	sys	irix_unimp	0	/* 1210  XXX pidsprocsp()	*/
+-	sys	irix_unimp	0	/* 1211  XXX rexec()		*/
+-	sys	irix_unimp	0	/* 1212  XXX timer_create()	*/
+-	sys	irix_unimp	0	/* 1213  XXX timer_delete()	*/
+-	sys	irix_unimp	0	/* 1214  XXX timer_settime()	*/
+-	sys	irix_unimp	0	/* 1215  XXX timer_gettime()	*/
+-	sys	irix_unimp	0	/* 1216  XXX timer_setoverrun()	*/
+-	sys	sys_sched_rr_get_interval 2		/* 1217  sched_rr_get_interval()V*/
+-	sys	sys_sched_yield	0	/* 1218  sched_yield()	       V*/
+-	sys	sys_sched_getscheduler 1 /* 1219  sched_getscheduler()  V*/
+-	sys	sys_sched_setscheduler 3 /* 1220  sched_setscheduler()  V*/
+-	sys	sys_sched_getparam 2	/* 1221  sched_getparam()      V*/
+-	sys	sys_sched_setparam 2	/* 1222  sched_setparam()      V*/
+-	sys	irix_unimp	0	/* 1223  XXX usync_cntl()	*/
+-	sys	irix_unimp	0	/* 1224  XXX psema_cntl()	*/
+-	sys	irix_unimp	0	/* 1225  XXX restartreturn()	*/
+-
+-/* Just to pad things out nicely. */
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-	sys	irix_unimp	0
+-#else
+-	mille	sys_ni_syscall	0
+-#endif
+-
+-/* YEEEEEEEEEEEEEEEEEE!!!! */
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/irixelf.c linux-2.6.10-mips/arch/mips/kernel/irixelf.c
+--- linux-2.6.10/arch/mips/kernel/irixelf.c	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/irixelf.c	2005-01-07 15:38:08.000000000 +0100
+@@ -1,15 +1,16 @@
+ /*
+- * irixelf.c: Code to load IRIX ELF executables which conform to
+- *            the MIPS ABI.
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
+  *
+- * Copyright (C) 1996 David S. Miller (dm at engr.sgi.com)
++ * irixelf.c: Code to load IRIX ELF executables conforming to the MIPS ABI.
++ *            Based off of work by Eric Youngdale.
+  *
+- * Based upon work which is:
+- * Copyright 1993, 1994: Eric Youngdale (ericy at cais.com).
++ * Copyright (C) 1993 - 1994 Eric Youngdale <ericy at cais.com>
++ * Copyright (C) 1996 - 2004 David S. Miller <dm at engr.sgi.com>
++ * Copyright (C) 2004 Steven J. Hill <sjhill at realitydiluted.com>
+  */
+-
+ #include <linux/module.h>
+-
+ #include <linux/fs.h>
+ #include <linux/stat.h>
+ #include <linux/sched.h>
+@@ -209,13 +210,13 @@ unsigned long * create_irix_tables(char 
+ 		__put_user((unsigned long)p,argv++);
+ 		p += strlen_user(p);
+ 	}
+-	__put_user(NULL, argv);
++	__put_user((unsigned long) NULL, argv);
+ 	current->mm->arg_end = current->mm->env_start = (unsigned long) p;
+ 	while (envc-->0) {
+ 		__put_user((unsigned long)p,envp++);
+ 		p += strlen_user(p);
+ 	}
+-	__put_user(NULL, envp);
++	__put_user((unsigned long) NULL, envp);
+ 	current->mm->env_end = (unsigned long) p;
+ 	return sp;
+ }
+@@ -616,6 +617,7 @@ static int load_irix_binary(struct linux
+ 	}
+ 
+ 	retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *)elf_phdata, size);
++
+ 	if (retval < 0)
+ 		goto out_free_ph;
+ 
+@@ -925,7 +927,8 @@ unsigned long irix_mapelf(int fd, struct
+ 	}
+ 
+ #ifdef DEBUG_ELF
+-	printk("irix_mapelf: Success, returning %08lx\n", user_phdrp->p_vaddr);
++	printk("irix_mapelf: Success, returning %08lx\n",
++		(unsigned long) user_phdrp->p_vaddr);
+ #endif
+ 	fput(filp);
+ 	return user_phdrp->p_vaddr;
+@@ -1288,6 +1291,20 @@ end_coredump:
+ 
+ static int __init init_irix_binfmt(void)
+ {
++	int init_inventory(void);
++	extern asmlinkage unsigned long sys_call_table;
++	extern asmlinkage unsigned long sys_call_table_irix5;
++
++	init_inventory();
++
++	/*
++	 * Copy the IRIX5 syscall table (8000 bytes) into the main syscall
++	 * table. The IRIX5 calls are located by an offset of 8000 bytes
++	 * from the beginning of the main table.
++	 */
++	memcpy((void *) ((unsigned long) &sys_call_table + 8000),
++		&sys_call_table_irix5, 8000);
++
+ 	return register_binfmt(&irix_format);
+ }
+ 
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/irixinv.c linux-2.6.10-mips/arch/mips/kernel/irixinv.c
+--- linux-2.6.10/arch/mips/kernel/irixinv.c	2004-12-24 22:33:51.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/irixinv.c	2005-01-07 15:38:08.000000000 +0100
+@@ -6,10 +6,8 @@
+  * Miguel de Icaza, 1997.
+  */
+ #include <linux/mm.h>
+-#include <linux/init.h>
+-#include <linux/slab.h>
+-#include <asm/uaccess.h>
+ #include <asm/inventory.h>
++#include <asm/uaccess.h>
+ 
+ #define MAX_INVENTORY 50
+ int inventory_items = 0;
+@@ -49,7 +47,7 @@ int dump_inventory_to_user (void *userbu
+ 	return inventory_items * sizeof (inventory_t);
+ }
+ 
+-static int __init init_inventory(void)
++int __init init_inventory(void)
+ {
+ 	/*
+ 	 * gross hack while we put the right bits all over the kernel
+@@ -77,5 +75,3 @@ static int __init init_inventory(void)
+ 
+ 	return 0;
+ }
+-
+-module_init(init_inventory);
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/irixsig.c linux-2.6.10-mips/arch/mips/kernel/irixsig.c
+--- linux-2.6.10/arch/mips/kernel/irixsig.c	2004-12-24 22:35:25.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/irixsig.c	2005-01-06 15:59:59.000000000 +0100
+@@ -627,7 +627,7 @@ repeat:
+ 			}
+ 			goto end_waitsys;
+ 
+-		case TASK_ZOMBIE:
++		case EXIT_ZOMBIE:
+ 			current->signal->cutime += p->utime + p->signal->cutime;
+ 			current->signal->cstime += p->stime + p->signal->cstime;
+ 			if (ru != NULL)
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/irq-rm9000.c linux-2.6.10-mips/arch/mips/kernel/irq-rm9000.c
+--- linux-2.6.10/arch/mips/kernel/irq-rm9000.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/irq-rm9000.c	2004-12-12 03:14:02.000000000 +0100
+@@ -0,0 +1,149 @@
++/*
++ * Copyright (C) 2003 Ralf Baechle
++ *
++ * 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.
++ *
++ * Handler for RM9000 extended interrupts.  These are a non-standard
++ * feature so we handle them separately from standard interrupts.
++ */
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++
++#include <asm/irq_cpu.h>
++#include <asm/mipsregs.h>
++#include <asm/system.h>
++
++static int irq_base;
++
++static inline void unmask_rm9k_irq(unsigned int irq)
++{
++	set_c0_intcontrol(0x1000 << (irq - irq_base));
++}
++
++static inline void mask_rm9k_irq(unsigned int irq)
++{
++	clear_c0_intcontrol(0x1000 << (irq - irq_base));
++}
++
++static inline void rm9k_cpu_irq_enable(unsigned int irq)
++{
++	unsigned long flags;
++
++	local_irq_save(flags);
++	unmask_rm9k_irq(irq);
++	local_irq_restore(flags);
++}
++
++static void rm9k_cpu_irq_disable(unsigned int irq)
++{
++	unsigned long flags;
++
++	local_irq_save(flags);
++	mask_rm9k_irq(irq);
++	local_irq_restore(flags);
++}
++
++static unsigned int rm9k_cpu_irq_startup(unsigned int irq)
++{
++	rm9k_cpu_irq_enable(irq);
++
++	return 0;
++}
++
++#define	rm9k_cpu_irq_shutdown	rm9k_cpu_irq_disable
++
++/*
++ * Performance counter interrupts are global on all processors.
++ */
++static void local_rm9k_perfcounter_irq_startup(void *args)
++{
++	unsigned int irq = (unsigned int) args;
++
++	rm9k_cpu_irq_enable(irq);
++}
++
++static unsigned int rm9k_perfcounter_irq_startup(unsigned int irq)
++{
++	on_each_cpu(local_rm9k_perfcounter_irq_startup, (void *) irq, 0, 1);
++
++	return 0;
++}
++
++static void local_rm9k_perfcounter_irq_shutdown(void *args)
++{
++	unsigned int irq = (unsigned int) args;
++	unsigned long flags;
++
++	local_irq_save(flags);
++	mask_rm9k_irq(irq);
++	local_irq_restore(flags);
++}
++
++static void rm9k_perfcounter_irq_shutdown(unsigned int irq)
++{
++	on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 0, 1);
++}
++
++
++/*
++ * While we ack the interrupt interrupts are disabled and thus we don't need
++ * to deal with concurrency issues.  Same for rm9k_cpu_irq_end.
++ */
++static void rm9k_cpu_irq_ack(unsigned int irq)
++{
++	mask_rm9k_irq(irq);
++}
++
++static void rm9k_cpu_irq_end(unsigned int irq)
++{
++	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
++		unmask_rm9k_irq(irq);
++}
++
++static hw_irq_controller rm9k_irq_controller = {
++	"RM9000",
++	rm9k_cpu_irq_startup,
++	rm9k_cpu_irq_shutdown,
++	rm9k_cpu_irq_enable,
++	rm9k_cpu_irq_disable,
++	rm9k_cpu_irq_ack,
++	rm9k_cpu_irq_end,
++};
++
++static hw_irq_controller rm9k_perfcounter_irq = {
++	"RM9000",
++	rm9k_perfcounter_irq_startup,
++	rm9k_perfcounter_irq_shutdown,
++	rm9k_cpu_irq_enable,
++	rm9k_cpu_irq_disable,
++	rm9k_cpu_irq_ack,
++	rm9k_cpu_irq_end,
++};
++
++unsigned int rm9000_perfcount_irq;
++
++EXPORT_SYMBOL(rm9000_perfcount_irq);
++
++void __init rm9k_cpu_irq_init(int base)
++{
++	int i;
++
++	clear_c0_intcontrol(0x0000f000);		/* Mask all */
++
++	for (i = base; i < base + 4; i++) {
++		irq_desc[i].status = IRQ_DISABLED;
++		irq_desc[i].action = NULL;
++		irq_desc[i].depth = 1;
++		irq_desc[i].handler = &rm9k_irq_controller;
++	}
++
++	rm9000_perfcount_irq = base + 1;
++	irq_desc[rm9000_perfcount_irq].handler = &rm9k_perfcounter_irq;
++
++	irq_base = base;
++}
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/linux32.c linux-2.6.10-mips/arch/mips/kernel/linux32.c
+--- linux-2.6.10/arch/mips/kernel/linux32.c	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/linux32.c	2004-10-27 02:12:47.000000000 +0200
+@@ -99,7 +99,7 @@ int cp_compat_stat(struct kstat *stat, s
+ }
+ 
+ asmlinkage unsigned long
+-sys32_mmap2(unsigned long addr, size_t len, unsigned long prot,
++sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+          unsigned long flags, unsigned long fd, unsigned long pgoff)
+ {
+ 	struct file * file = NULL;
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/mips_ksyms.c linux-2.6.10-mips/arch/mips/kernel/mips_ksyms.c
+--- linux-2.6.10/arch/mips/kernel/mips_ksyms.c	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/mips_ksyms.c	2004-12-28 20:06:23.000000000 +0100
+@@ -8,6 +8,7 @@
+  * Copyright (C) 1996, 97, 98, 99, 2000, 01, 03 by Ralf Baechle
+  * Copyright (C) 1999, 2000, 01 Silicon Graphics, Inc.
+  */
++#include <linux/interrupt.h>
+ #include <linux/module.h>
+ #include <asm/checksum.h>
+ #include <asm/pgtable.h>
+@@ -60,3 +61,6 @@ EXPORT_SYMBOL(__strnlen_user_asm);
+ EXPORT_SYMBOL(csum_partial);
+ 
+ EXPORT_SYMBOL(invalid_pte_table);
++#ifdef CONFIG_GENERIC_IRQ_PROBE
++EXPORT_SYMBOL(probe_irq_mask);
++#endif
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/process.c linux-2.6.10-mips/arch/mips/kernel/process.c
+--- linux-2.6.10/arch/mips/kernel/process.c	2004-12-24 22:34:32.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/process.c	2005-01-07 15:38:08.000000000 +0100
+@@ -113,19 +113,15 @@ int copy_thread(int nr, unsigned long cl
+ 	*childregs = *regs;
+ 	childregs->regs[7] = 0;	/* Clear error flag */
+ 
+-#ifdef CONFIG_BINFMT_IRIX
++#if defined(CONFIG_BINFMT_IRIX)
+ 	if (current->personality != PER_LINUX) {
+ 		/* Under IRIX things are a little different. */
+-		childregs->regs[2] = 0;
+ 		childregs->regs[3] = 1;
+-		regs->regs[2] = p->pid;
+ 		regs->regs[3] = 0;
+-	} else
+-#endif
+-	{
+-		childregs->regs[2] = 0;	/* Child gets zero as return value */
+-		regs->regs[2] = p->pid;
+ 	}
++#endif
++	childregs->regs[2] = 0;	/* Child gets zero as return value */
++	regs->regs[2] = p->pid;
+ 
+ 	if (childregs->cp0_status & ST0_CU0) {
+ 		childregs->regs[28] = (unsigned long) ti;
+@@ -263,7 +259,6 @@ arch_initcall(frame_info_init);
+  */
+ unsigned long thread_saved_pc(struct task_struct *tsk)
+ {
+-	extern void ret_from_fork(void);
+ 	struct thread_struct *t = &tsk->thread;
+ 
+ 	/* New born processes are a special case */
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/scall32-o32.S linux-2.6.10-mips/arch/mips/kernel/scall32-o32.S
+--- linux-2.6.10/arch/mips/kernel/scall32-o32.S	2004-12-24 22:33:59.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/scall32-o32.S	2005-01-07 17:47:06.000000000 +0100
+@@ -5,6 +5,7 @@
+  *
+  * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle
+  * Copyright (C) 2001 MIPS Technologies, Inc.
++ * Copyright (C) 2004 Thiemo Seufer
+  */
+ #include <linux/config.h>
+ #include <linux/errno.h>
+@@ -32,26 +33,30 @@ NESTED(handle_sys, PT_SIZE, sp)
+ 
+ 	lw	t1, PT_EPC(sp)		# skip syscall on return
+ 
++#if defined(CONFIG_BINFMT_IRIX)
+ 	sltiu	t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
++#else
++	subu	v0, v0, __NR_O32_Linux	# check syscall number
++	sltiu	t0, v0, __NR_O32_Linux_syscalls + 1
++#endif
+ 	addiu	t1, 4			# skip to next instruction
+ 	sw	t1, PT_EPC(sp)
+ 	beqz	t0, illegal_syscall
+ 
+-	/* XXX Put both in one cacheline, should save a bit. */
+-	sll	t0, v0, 2
+-	lw	t2, sys_call_table(t0)	# syscall routine
+-	lbu	t3, sys_narg_table(v0)	# number of arguments
+-	beqz	t2, illegal_syscall;
++	sll	t0, v0, 3
++	la	t1, sys_call_table
++	addu	t1, t0
++	lw	t2, (t1)		# syscall routine
++	lw	t3, 4(t1)		# >= 0 if we need stack arguments
++	beqz	t2, illegal_syscall
+ 
+-	subu	t0, t3, 5		# 5 or more arguments?
+ 	sw	a3, PT_R26(sp)		# save a3 for syscall restarting
+-	bgez	t0, stackargs
++	bgez	t3, stackargs
+ 
+ stack_done:
+-	sw	a3, PT_R26(sp)          # save for syscall restart
+-	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
++	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?
+ 	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+-	and	t0, t1, t0
++	and	t0, t1
+ 	bnez	t0, syscall_trace_entry	# -> yes
+ 
+ 	jalr	t2			# Do The Real Thing (TM)
+@@ -70,9 +75,9 @@ o32_syscall_exit:
+ 	local_irq_disable		# make sure need_resched and
+ 					# signals dont change between
+ 					# sampling and return
+-	LONG_L	a2, TI_FLAGS($28)	# current->work
++	lw	a2, TI_FLAGS($28)	# current->work
+ 	li	t0, _TIF_ALLWORK_MASK
+-	and	t0, a2, t0
++	and	t0, a2
+ 	bnez	t0, o32_syscall_exit_work
+ 
+ 	j	restore_partial
+@@ -116,49 +121,48 @@ syscall_trace_entry:
+ 	 */
+ stackargs:
+ 	lw	t0, PT_R29(sp)		# get old user stack pointer
+-	subu	t3, 4
+-	sll	t1, t3, 2		# stack valid?
+ 
+-	addu	t1, t0			# end address
+-	or	t0, t1
+-	bltz	t0, bad_stack		# -> sp is bad
+-
+-	lw	t0, PT_R29(sp)		# get old user stack pointer
+-	PTR_LA	t1, 4f			# copy 1 to 3 arguments
+-	sll	t3, t3, 4
+-	subu	t1, t3
+-	jr	t1
+-
+-	/* Ok, copy the args from the luser stack to the kernel stack */
+ 	/*
+-	 * I know Ralf doesn't like nops but this avoids code
+-	 * duplication for R3000 targets (and this is the
+-	 * only place where ".set reorder" doesn't help).
+-	 * Harald.
++	 * We intentionally keep the kernel stack a little below the top of
++	 * userspace so we don't have to do a slower byte accurate check here.
++	 */
++	lw	t5, TI_ADDR_LIMIT($28)
++	addu	t4, t0, 32
++	and	t5, t4
++	bltz	t5, bad_stack		# -> sp is bad
++
++	/* Ok, copy the args from the luser stack to the kernel stack.
++	 * t3 is the precomputed number of instruction bytes needed to
++	 * load or store arguments 6-8.
+ 	 */
++
++	la	t1, 5f			# load up to 3 arguments
++	subu	t1, t3
++1:	lw	t5, 16(t0)		# argument #5 from usp
+ 	.set    push
+ 	.set    noreorder
+ 	.set	nomacro
+-1:	lw	t1, 24(t0)		# argument #7 from usp
+-	nop
+-	sw	t1, 24(sp)
+-	nop
+-2:	lw	t1, 20(t0)		# argument #5 from usp
+-	nop
+-	sw	t1, 20(sp)
+-	nop
+-3:	lw	t1, 16(t0)		# argument #5 from usp
+-	nop
+-	sw	t1, 16(sp)
+-	nop
+-4:	.set	pop
++	jr	t1
++	 addiu	t1, 6f - 5f
+ 
+-	j	stack_done		# go back
++2:	lw	t8, 28(t0)		# argument #8 from usp
++3:	lw	t7, 24(t0)		# argument #7 from usp
++4:	lw	t6, 20(t0)		# argument #6 from usp
++5:	jr	t1
++	 sw	t5, 16(sp)		# argument #5 to ksp
++
++	sw	t8, 28(sp)		# argument #8 to ksp
++	sw	t7, 24(sp)		# argument #7 to ksp
++	sw	t6, 20(sp)		# argument #6 to ksp
++6:	j	stack_done		# go back
++	 nop
++	.set	pop
+ 
+ 	.section __ex_table,"a"
+ 	PTR	1b,bad_stack
+ 	PTR	2b,bad_stack
+ 	PTR	3b,bad_stack
++	PTR	4b,bad_stack
+ 	.previous
+ 
+ 	/*
+@@ -177,7 +181,7 @@ bad_stack:
+ 	 * The system call does not exist in this kernel
+ 	 */
+ illegal_syscall:
+-	li	v0, ENOSYS			# error
++	li	v0, -ENOSYS			# error
+ 	sw	v0, PT_R2(sp)
+ 	li	t0, 1				# set error flag
+ 	sw	t0, PT_R7(sp)
+@@ -238,12 +242,12 @@ illegal_syscall:
+ 	sw	v0, PT_R2(sp)		# result
+ 
+ 	/* Success, so skip usual error handling garbage.  */
+-	LONG_L	a2, TI_FLAGS($28)	# syscall tracing enabled?
++	lw	a2, TI_FLAGS($28)	# syscall tracing enabled?
+ 	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+ 	and	t0, a2, t0
+ 	bnez	t0, 1f
+ 
+-	b	o32_syscall_exit
++	j	o32_syscall_exit
+ 
+ 1:	SAVE_STATIC
+ 	move	a0, sp
+@@ -269,69 +273,49 @@ bad_alignment:
+ 	END(sys_sysmips)
+ 
+ 	LEAF(sys_syscall)
+-	lw	t0, PT_R29(sp)			# user sp
+-
+-	sltu	v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
+-	beqz	v0, enosys
+-
+-	sll	v0, a0, 2
+-	la	v1, sys_syscall
+-	lw	t2, sys_call_table(v0)		# function pointer
+-	lbu	t4, sys_narg_table(a0)		# number of arguments
+-
+-	li	v0, -EINVAL
+-	beq	t2, v1, out			# do not recurse
++#if defined(CONFIG_BINFMT_IRIX)
++	sltiu	v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
++#else
++	subu	t0, a0, __NR_O32_Linux	# check syscall number
++	sltiu	v0, t0, __NR_O32_Linux_syscalls + 1
++#endif
++	sll	t1, t0, 3
++	beqz	v0, einval
+ 
+-	beqz	t2, enosys			# null function pointer?
++	lw	t2, sys_call_table(t1)		# syscall routine
+ 
+-	andi	v0, t0, 0x3			# unaligned stack pointer?
+-	bnez	v0, sigsegv
++#if defined(CONFIG_BINFMT_IRIX)
++	li	v1, 4000			# nr of sys_syscall
++#else
++	li	v1, 4000 - __NR_O32_Linux	# index of sys_syscall
++#endif
++	beq	t0, v1, einval			# do not recurse
+ 
+-	addu	v0, t0, 16			# v0 = usp + 16
+-	addu	t1, v0, 12			# 3 32-bit arguments
+-	lw	v1, TI_ADDR_LIMIT($28)
+-	or	v0, v0, t1
+-	and	v1, v1, v0
+-	bltz	v1, efault
++	/* Some syscalls like execve get their arguments from struct pt_regs
++	   and claim zero arguments in the syscall table. Thus we have to
++	   assume the worst case and shuffle around all potential arguments.
++	   If you want performance, don't use indirect syscalls. */
+ 
+ 	move	a0, a1				# shift argument registers
+ 	move	a1, a2
+ 	move	a2, a3
+-
+-1:	lw	a3, 16(t0)
+-2:	lw	t3, 20(t0)
+-3:	lw	t4, 24(t0)
+-
+-	.section	__ex_table, "a"
+-	.word	1b, efault
+-	.word	2b, efault
+-	.word	3b, efault
+-	.previous
+-
+-	sw	t3, 16(sp)			# put into new stackframe
+-	sw	t4, 20(sp)
+-
+-	bnez	t4, 1f				# zero arguments?
+-	addu	a0, sp, 32			# then pass sp in a0
+-1:
+-
+-	sw	t3, 16(sp)
+-	sw	v1, 20(sp)
++	lw	a3, 16(sp)
++	lw	t4, 20(sp)
++	lw	t5, 24(sp)
++	lw	t6, 28(sp)
++	sw	t4, 16(sp)
++	sw	t5, 20(sp)
++	sw	t6, 24(sp)
++	sw	a0, PT_R4(sp)			# .. and push back a0 - a3, some
++	sw	a1, PT_R5(sp)			# syscalls expect them there
++	sw	a2, PT_R6(sp)
++	sw	a3, PT_R7(sp)
++	sw	a3, PT_R26(sp)			# update a3 for syscall restarting
+ 	jr	t2
+ 	/* Unreached */
+ 
+-enosys:	li	v0, -ENOSYS
+-	b	out
+-
+-sigsegv:
+-	li	a0, _SIGSEGV
+-	move	a1, $28
+-	jal	force_sig
+-	/* Fall through */
+-
+-efault:	li	v0, -EFAULT
+-
+-out:	jr	ra
++einval:	li	v0, -EINVAL
++	jr	ra
+ 	END(sys_syscall)
+ 
+ 	.macro	fifty ptr, nargs, from=1, to=50
+@@ -349,12 +333,14 @@ out:	jr	ra
+ 	.endm
+ 
+ 	.macro	syscalltable
++#if defined(CONFIG_BINFMT_IRIX)
+ 	mille	sys_ni_syscall		0	/*    0 -  999 SVR4 flavour */
+-	#include "irix5sys.h"			/* 1000 - 1999 32-bit IRIX */
++	mille	sys_ni_syscall		0	/* 1000 - 1999 32-bit IRIX */
+ 	mille	sys_ni_syscall		0	/* 2000 - 2999 BSD43 flavour */
+ 	mille	sys_ni_syscall		0	/* 3000 - 3999 POSIX flavour */
++#endif
+ 
+-	sys	sys_syscall		0	/* 4000 */
++	sys	sys_syscall		8	/* 4000 */
+ 	sys	sys_exit		1
+ 	sys	sys_fork		0
+ 	sys	sys_read		3
+@@ -405,7 +391,7 @@ out:	jr	ra
+ 	sys	sys_ni_syscall		0	/* was signal(2) */
+ 	sys	sys_geteuid		0
+ 	sys	sys_getegid		0	/* 4050 */
+-	sys	sys_acct		0
++	sys	sys_acct		1
+ 	sys	sys_umount		2
+ 	sys	sys_ni_syscall		0
+ 	sys	sys_ioctl		3
+@@ -485,7 +471,7 @@ out:	jr	ra
+ 	sys	sys_init_module		5
+ 	sys	sys_delete_module	1
+ 	sys	sys_ni_syscall		0	/* 4130	was get_kernel_syms */
+-	sys	sys_quotactl		0
++	sys	sys_quotactl		4
+ 	sys	sys_getpgid		1
+ 	sys	sys_fchdir		1
+ 	sys	sys_bdflush		2
+@@ -506,7 +492,7 @@ out:	jr	ra
+ 	sys	sys_sysmips		4
+ 	sys	sys_ni_syscall		0	/* 4150 */
+ 	sys	sys_getsid		1
+-	sys	sys_fdatasync		0
++	sys	sys_fdatasync		1
+ 	sys	sys_sysctl		1
+ 	sys	sys_mlock		2
+ 	sys	sys_munlock		2	/* 4155 */
+@@ -640,19 +626,16 @@ out:	jr	ra
+ 
+ 	.endm
+ 
++	/* We pre-compute the number of _instruction_ bytes needed to
++	   load or store the arguments 6-8. Negative values are ignored. */
++
+ 	.macro  sys function, nargs
+ 	PTR	\function
++	LONG	(\nargs << 2) - (5 << 2)
+ 	.endm
+ 
+ 	.align	3
+-sys_call_table:
++	.type	sys_call_table, at object
++EXPORT(sys_call_table)
+ 	syscalltable
+ 	.size	sys_call_table, . - sys_call_table
+-
+-	.macro	sys function, nargs
+-	.byte	\nargs
+-	.endm
+-
+-sys_narg_table:
+-	syscalltable
+-	.size	sys_narg_table, . - sys_narg_table
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/scall64-64.S linux-2.6.10-mips/arch/mips/kernel/scall64-64.S
+--- linux-2.6.10/arch/mips/kernel/scall64-64.S	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/scall64-64.S	2005-01-07 17:54:04.000000000 +0100
+@@ -53,8 +53,10 @@ NESTED(handle_sys64, PT_SIZE, sp)
+ 
+ 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
+ 
+-	LONG_L	t0, TI_FLAGS($28)
+-	bltz	t0, syscall_trace_entry	# syscall tracing enabled?
++	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
++	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
++	and	t0, t1, t0
++	bnez	t0, syscall_trace_entry
+ 
+ 	jalr	t2			# Do The Real Thing (TM)
+ 
+@@ -112,7 +114,7 @@ syscall_trace_entry:
+ 
+ illegal_syscall:
+ 	/* This also isn't a 64-bit syscall, throw an error.  */
+-	li	v0, ENOSYS			# error
++	li	v0, -ENOSYS			# error
+ 	sd	v0, PT_R2(sp)
+ 	li	t0, 1				# set error flag
+ 	sd	t0, PT_R7(sp)
+@@ -173,8 +175,8 @@ illegal_syscall:
+ 	sd	v0, PT_R2(sp)		# result
+ 
+ 	/* Success, so skip usual error handling garbage.  */
+-	LONG_L	a2, TI_FLAGS($28)	# syscall tracing enabled?
+ 	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
++	LONG_L	a2, TI_FLAGS($28)	# syscall tracing enabled?
+ 	and	t0, a2, t0
+ 	bnez	t0, 1f
+ 
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/scall64-o32.S linux-2.6.10-mips/arch/mips/kernel/scall64-o32.S
+--- linux-2.6.10/arch/mips/kernel/scall64-o32.S	2004-12-24 22:33:47.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/scall64-o32.S	2005-01-07 17:47:25.000000000 +0100
+@@ -6,6 +6,7 @@
+  * Copyright (C) 1995 - 2000, 2001 by Ralf Baechle
+  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
+  * Copyright (C) 2001 MIPS Technologies, Inc.
++ * Copyright (C) 2004 Thiemo Seufer
+  *
+  * Hairy, the userspace application uses a different argument passing
+  * convention than the kernel, so we have to translate things from o32
+@@ -43,6 +44,8 @@ NESTED(handle_sys, PT_SIZE, sp)
+  RESTORE_ALL
+ #endif
+ 
++	/* We don't want to stumble over broken sign extensions from
++	   userland. O32 does never use the upper half. */
+ 	sll	a0, a0, 0
+ 	sll	a1, a1, 0
+ 	sll	a2, a2, 0
+@@ -68,11 +71,13 @@ NESTED(handle_sys, PT_SIZE, sp)
+ 1:	lw	a4, 16(t0)		# argument #5 from usp
+ 2:	lw	a5, 20(t0)		# argument #6 from usp
+ 3:	lw	a6, 24(t0)		# argument #7 from usp
++4:	lw	a7, 28(t0)		# argument #8 from usp (for indirect syscalls)
+ 
+ 	.section __ex_table,"a"
+ 	PTR	1b, bad_stack
+ 	PTR	2b, bad_stack
+ 	PTR	3b, bad_stack
++	PTR	4b, bad_stack
+ 	.previous
+ 
+ 	li	t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+@@ -91,7 +96,7 @@ NESTED(handle_sys, PT_SIZE, sp)
+ 	sd	v0, PT_R0(sp)		# flag for syscall restarting
+ 1:	sd	v0, PT_R2(sp)		# result
+ 
+-FEXPORT(o32_syscall_exit)
++o32_syscall_exit:
+ 	local_irq_disable		# make need_resched and
+ 					# signals dont change between
+ 					# sampling and return
+@@ -109,12 +114,12 @@ o32_syscall_exit_work:
+ 
+ trace_a_syscall:
+ 	SAVE_STATIC
+-	sd	a4, PT_R8(sp)
++	sd	a4, PT_R8(sp)		# Save argument registers
+ 	sd	a5, PT_R9(sp)
+ 	sd	a6, PT_R10(sp)
+-	sd	a7, PT_R11(sp)
++	sd	a7, PT_R11(sp)		# For indirect syscalls
+ 
+-	move	s0, t2
++	move	s0, t2			# Save syscall pointer
+ 	move	a0, sp
+ 	li	a1, 0
+ 	jal	do_syscall_trace
+@@ -125,7 +130,8 @@ trace_a_syscall:
+ 	ld	a3, PT_R7(sp)
+ 	ld	a4, PT_R8(sp)
+ 	ld	a5, PT_R9(sp)
+-	ld	a6, PT_R10(sp)		# For indirect syscalls
++	ld	a6, PT_R10(sp)
++	ld	a7, PT_R11(sp)		# For indirect syscalls
+ 	jalr	s0
+ 
+ 	li	t0, -EMAXERRNO - 1	# error?
+@@ -162,40 +168,17 @@ not_o32_scall:
+ #else
+ 	j	handle_sys64
+ #endif
+-
+-illegal_syscall:
+-	/* This also isn't a 64-bit syscall, throw an error.  */
+-	li	v0, ENOSYS		# error
+-	sd	v0, PT_R2(sp)
+-	li	t0, 1			# set error flag
+-	sd	t0, PT_R7(sp)
+-	j	o32_syscall_exit
+ 	END(handle_sys)
+ 
+ LEAF(sys32_syscall)
+-	ld	t0, PT_R29(sp)		# user sp
+-
+ 	sltu	v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
+-	beqz	v0, enosys
++	beqz	v0, einval
+ 
+ 	dsll	v0, a0, 3
+-	dla	v1, sys32_syscall
+ 	ld	t2, (sys_call_table - (__NR_O32_Linux * 8))(v0)
+ 
+-	li	v0, -EINVAL
+-	beq	t2, v1, out		# do not recurse
+-
+-	beqz	t2, enosys		# null function pointer?
+-
+-	andi	v0, t0, 0x3		# unaligned stack pointer?
+-	bnez	v0, sigsegv
+-
+-	daddiu	v0, t0, 16		# v0 = usp + 16
+-	daddu	t1, v0, 12		# 3 32-bit arguments
+-	ld	v1, TI_ADDR_LIMIT($28)
+-	or	v0, v0, t1
+-	and	v1, v1, v0
+-	bnez	v1, efault
++	li	v1, 4000		# indirect syscall number
++	beq	a0, v1, einval		# do not recurse
+ 
+ 	move	a0, a1			# shift argument registers
+ 	move	a1, a2
+@@ -203,25 +186,21 @@ LEAF(sys32_syscall)
+ 	move	a3, a4
+ 	move	a4, a5
+ 	move	a5, a6
++	move	a6, a7
++	sd	a0, PT_R4(sp)		# ... and push back a0 - a3, some
++	sd	a1, PT_R5(sp)		# syscalls expect them there
++	sd	a2, PT_R6(sp)
++	sd	a3, PT_R7(sp)
++	sd	a3, PT_R26(sp)		# update a3 for syscall restarting
+ 	jr	t2
+ 	/* Unreached */
+ 
+-enosys:	li	v0, -ENOSYS
+-	b	out
+-
+-sigsegv:
+-	li	a0, _SIGSEGV
+-	move	a1, $28
+-	jal	force_sig
+-	/* Fall through */
+-
+-efault:	li	v0, -EFAULT
+-
+-out:	jr	ra
++einval:	li	v0, -EINVAL
++	jr	ra
+ 	END(sys32_syscall)
+ 
+ 	.align	3
+-	.type	sys_call_table, at object;
++	.type	sys_call_table, at object
+ sys_call_table:
+ 	PTR	sys32_syscall			/* 4000 */
+ 	PTR	sys_exit
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/setup.c linux-2.6.10-mips/arch/mips/kernel/setup.c
+--- linux-2.6.10/arch/mips/kernel/setup.c	2004-12-24 22:34:02.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/setup.c	2005-01-08 01:42:32.000000000 +0100
+@@ -281,12 +281,12 @@ static inline void bootmem_init(void)
+ 		initrd_reserve_bootmem = 1;
+ 	} else {
+ 		unsigned long tmp;
+-		unsigned long *initrd_header;
++		u32 *initrd_header;
+ 
+-		tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
++		tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - sizeof(u32) * 2;
+ 		if (tmp < reserved_end)
+ 			tmp += PAGE_SIZE;
+-		initrd_header = (unsigned long *)tmp;
++		initrd_header = (u32 *)tmp;
+ 		if (initrd_header[0] == 0x494E5244) {
+ 			initrd_start = (unsigned long)&initrd_header[2];
+ 			initrd_end = initrd_start + initrd_header[1];
+@@ -425,8 +425,10 @@ static inline void bootmem_init(void)
+ 		if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) {
+ 			printk("initrd extends beyond end of memory "
+ 			       "(0x%0*Lx > 0x%0*Lx)\ndisabling initrd\n",
+-			       sizeof(long) * 2, CPHYSADDR(initrd_end),
+-			       sizeof(long) * 2, PFN_PHYS(max_low_pfn));
++			       sizeof(long) * 2,
++			       (unsigned long long)CPHYSADDR(initrd_end),
++			       sizeof(long) * 2,
++			       (unsigned long long)PFN_PHYS(max_low_pfn));
+ 			initrd_start = initrd_end = 0;
+ 			initrd_reserve_bootmem = 0;
+ 		}
+@@ -441,10 +443,21 @@ static inline void resource_init(void)
+ {
+ 	int i;
+ 
++#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
++	/*
++	 * The 64bit code in 32bit object format trick can't represent
++	 * 64bit wide relocations for linker script symbols.
++	 */
++	code_resource.start = CPHYSADDR(&_text);
++	code_resource.end = CPHYSADDR(&_etext) - 1;
++	data_resource.start = CPHYSADDR(&_etext);
++	data_resource.end = CPHYSADDR(&_edata) - 1;
++#else
+ 	code_resource.start = virt_to_phys(&_text);
+ 	code_resource.end = virt_to_phys(&_etext) - 1;
+ 	data_resource.start = virt_to_phys(&_etext);
+ 	data_resource.end = virt_to_phys(&_edata) - 1;
++#endif
+ 
+ 	/*
+ 	 * Request address space for all standard RAM.
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/signal-common.h linux-2.6.10-mips/arch/mips/kernel/signal-common.h
+--- linux-2.6.10/arch/mips/kernel/signal-common.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/signal-common.h	2005-01-09 13:23:55.000000000 +0100
+@@ -0,0 +1,135 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 1991, 1992  Linus Torvalds
++ * Copyright (C) 1994 - 2000  Ralf Baechle
++ * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
++ */
++
++static inline int
++setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
++{
++	int err = 0;
++
++	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
++	err |= __put_user(regs->cp0_status, &sc->sc_status);
++
++#define save_gp_reg(i) do {						\
++	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
++} while(0)
++	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
++	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
++	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
++	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
++	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
++	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
++	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
++	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
++	save_gp_reg(31);
++#undef save_gp_reg
++
++	err |= __put_user(regs->hi, &sc->sc_mdhi);
++	err |= __put_user(regs->lo, &sc->sc_mdlo);
++	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
++	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
++
++	err |= __put_user(current->used_math, &sc->sc_used_math);
++
++	if (!current->used_math)
++		goto out;
++
++	/*
++	 * Save FPU state to signal context.  Signal handler will "inherit"
++	 * current FPU state.
++	 */
++	preempt_disable();
++
++	if (!is_fpu_owner()) {
++		own_fpu();
++		restore_fp(current);
++	}
++	err |= save_fp_context(sc);
++
++	preempt_enable();
++
++out:
++	return err;
++}
++
++static inline int
++restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
++{
++	int err = 0;
++
++	/* Always make any pending restarted system calls return -EINTR */
++	current_thread_info()->restart_block.fn = do_no_restart_syscall;
++
++	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
++	err |= __get_user(regs->hi, &sc->sc_mdhi);
++	err |= __get_user(regs->lo, &sc->sc_mdlo);
++
++#define restore_gp_reg(i) do {						\
++	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
++} while(0)
++	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
++	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
++	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
++	restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
++	restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
++	restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
++	restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
++	restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
++	restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
++	restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
++	restore_gp_reg(31);
++#undef restore_gp_reg
++
++	err |= __get_user(current->used_math, &sc->sc_used_math);
++
++	preempt_disable();
++
++	if (current->used_math) {
++		/* restore fpu context if we have used it before */
++		own_fpu();
++		err |= restore_fp_context(sc);
++	} else {
++		/* signal handler may have used FPU.  Give it up. */
++		lose_fpu();
++	}
++
++	preempt_enable();
++
++	return err;
++}
++
++/*
++ * Determine which stack to use..
++ */
++static inline void *
++get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
++{
++	unsigned long sp, almask;
++
++	/* Default to using normal stack */
++	sp = regs->regs[29];
++
++	/*
++ 	 * FPU emulator may have it's own trampoline active just
++ 	 * above the user stack, 16-bytes before the next lowest
++ 	 * 16 byte boundary.  Try to avoid trashing it.
++ 	 */
++ 	sp -= 32;
++
++	/* This is the X/Open sanctioned signal stack switching.  */
++	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
++		sp = current->sas_ss_sp + current->sas_ss_size;
++
++	if (PLAT_TRAMPOLINE_STUFF_LINE)
++		almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
++	else
++		almask = ALMASK;
++
++	return (void *)((sp - frame_size) & almask);
++}
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/signal.c linux-2.6.10-mips/arch/mips/kernel/signal.c
+--- linux-2.6.10/arch/mips/kernel/signal.c	2004-12-24 22:35:59.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/signal.c	2005-01-09 13:23:55.000000000 +0100
+@@ -29,12 +29,15 @@
+ #include <asm/sim.h>
+ #include <asm/uaccess.h>
+ #include <asm/ucontext.h>
++#include <asm/cpu-features.h>
++
++#include "signal-common.h"
+ 
+ #define DEBUG_SIG 0
+ 
+ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+ 
+-extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
++static int do_signal(sigset_t *oldset, struct pt_regs *regs);
+ 
+ /*
+  * Atomically swap in the new signal mask, and wait for a signal.
+@@ -152,51 +155,6 @@ asmlinkage int sys_sigaltstack(nabi_no_r
+ 	return do_sigaltstack(uss, uoss, usp);
+ }
+ 
+-asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+-{
+-	int err = 0;
+-
+-	/* Always make any pending restarted system calls return -EINTR */
+-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+-
+-	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
+-	err |= __get_user(regs->hi, &sc->sc_mdhi);
+-	err |= __get_user(regs->lo, &sc->sc_mdlo);
+-
+-#define restore_gp_reg(i) do {						\
+-	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
+-} while(0)
+-	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
+-	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
+-	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
+-	restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
+-	restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
+-	restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
+-	restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
+-	restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
+-	restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
+-	restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
+-	restore_gp_reg(31);
+-#undef restore_gp_reg
+-
+-	err |= __get_user(current->used_math, &sc->sc_used_math);
+-
+-	preempt_disable();
+-
+-	if (current->used_math) {
+-		/* restore fpu context if we have used it before */
+-		own_fpu();
+-		err |= restore_fp_context(sc);
+-	} else {
+-		/* signal handler may have used FPU.  Give it up. */
+-		lose_fpu();
+-	}
+-
+-	preempt_enable();
+-
+-	return err;
+-}
+-
+ #if PLAT_TRAMPOLINE_STUFF_LINE
+ #define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
+ #else
+@@ -220,7 +178,9 @@ struct rt_sigframe {
+ };
+ 
+ #ifdef CONFIG_TRAD_SIGNALS
+-asmlinkage void sys_sigreturn(struct pt_regs regs)
++save_static_function(sys_sigreturn);
++__attribute_used__ noinline static void
++_sys_sigreturn(nabi_no_regargs struct pt_regs regs)
+ {
+ 	struct sigframe *frame;
+ 	sigset_t blocked;
+@@ -257,7 +217,9 @@ badframe:
+ }
+ #endif
+ 
+-asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
++save_static_function(sys_rt_sigreturn);
++__attribute_used__ noinline static void
++_sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+ {
+ 	struct rt_sigframe *frame;
+ 	sigset_t set;
+@@ -298,85 +260,6 @@ badframe:
+ 	force_sig(SIGSEGV, current);
+ }
+ 
+-inline int setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
+-{
+-	int err = 0;
+-
+-	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
+-	err |= __put_user(regs->cp0_status, &sc->sc_status);
+-
+-#define save_gp_reg(i) do {						\
+-	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
+-} while(0)
+-	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
+-	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
+-	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
+-	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
+-	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
+-	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
+-	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
+-	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
+-	save_gp_reg(31);
+-#undef save_gp_reg
+-
+-	err |= __put_user(regs->hi, &sc->sc_mdhi);
+-	err |= __put_user(regs->lo, &sc->sc_mdlo);
+-	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
+-	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
+-
+-	err |= __put_user(current->used_math, &sc->sc_used_math);
+-
+-	if (!current->used_math)
+-		goto out;
+-
+-	/*
+-	 * Save FPU state to signal context.  Signal handler will "inherit"
+-	 * current FPU state.
+-	 */
+-	preempt_disable();
+-
+-	if (!is_fpu_owner()) {
+-		own_fpu();
+-		restore_fp(current);
+-	}
+-	err |= save_fp_context(sc);
+-
+-	preempt_enable();
+-
+-out:
+-	return err;
+-}
+-
+-/*
+- * Determine which stack to use..
+- */
+-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+-	size_t frame_size)
+-{
+-	unsigned long sp, almask;
+-
+-	/* Default to using normal stack */
+-	sp = regs->regs[29];
+-
+-	/*
+- 	 * FPU emulator may have it's own trampoline active just
+- 	 * above the user stack, 16-bytes before the next lowest
+- 	 * 16 byte boundary.  Try to avoid trashing it.
+- 	 */
+- 	sp -= 32;
+-
+-	/* This is the X/Open sanctioned signal stack switching.  */
+-	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
+-		sp = current->sas_ss_sp + current->sas_ss_size;
+-
+-	if (PLAT_TRAMPOLINE_STUFF_LINE)
+-		almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
+-	else
+-		almask = ALMASK;
+-
+-	return (void *)((sp - frame_size) & ~(PLAT_TRAMPOLINE_STUFF_LINE - 1));
+-}
+-
+ #ifdef CONFIG_TRAD_SIGNALS
+ static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
+ 	int signr, sigset_t *set)
+@@ -395,8 +278,7 @@ static void inline setup_frame(struct k_
+ 	 *         syscall
+ 	 */
+ 	if (PLAT_TRAMPOLINE_STUFF_LINE)
+-		__builtin_memset(frame->sf_code, '0',
+-		                 PLAT_TRAMPOLINE_STUFF_LINE);
++		__clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE);
+ 	err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0);
+ 	err |= __put_user(0x0000000c                 , frame->sf_code + 1);
+ 	flush_cache_sigtramp((unsigned long) frame->sf_code);
+@@ -452,8 +334,7 @@ static void inline setup_rt_frame(struct
+ 	 *         syscall
+ 	 */
+ 	if (PLAT_TRAMPOLINE_STUFF_LINE)
+-		__builtin_memset(frame->rs_code, '0',
+-		                 PLAT_TRAMPOLINE_STUFF_LINE);
++		__clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
+ 	err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0);
+ 	err |= __put_user(0x0000000c                    , frame->rs_code + 1);
+ 	flush_cache_sigtramp((unsigned long) frame->rs_code);
+@@ -557,7 +438,7 @@ static inline void handle_signal(unsigne
+ extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+ extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
+ 
+-asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
++static int do_signal(sigset_t *oldset, struct pt_regs *regs)
+ {
+ 	struct k_sigaction ka;
+ 	siginfo_t info;
+@@ -613,8 +494,6 @@ no_signal:
+ 	return 0;
+ }
+ 
+-extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
+-
+ /*
+  * notification of userspace execution resumption
+  * - triggered by current->work.notify_resume
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/signal32.c linux-2.6.10-mips/arch/mips/kernel/signal32.c
+--- linux-2.6.10/arch/mips/kernel/signal32.c	2004-12-24 22:34:46.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/signal32.c	2004-12-21 03:25:15.000000000 +0100
+@@ -106,7 +106,7 @@ typedef struct siginfo32 {
+ 
+ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+ 
+-extern asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs);
++extern int do_signal32(sigset_t *oldset, struct pt_regs *regs);
+ 
+ /* 32-bit compatibility types */
+ 
+@@ -192,6 +192,7 @@ static inline int get_sigset(sigset_t *k
+ /*
+  * Atomically swap in the new signal mask, and wait for a signal.
+  */
++
+ save_static_function(sys32_sigsuspend);
+ __attribute_used__ noinline static int
+ _sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
+@@ -333,8 +334,7 @@ asmlinkage int sys32_sigaltstack(nabi_no
+ 	return ret;
+ }
+ 
+-static asmlinkage int restore_sigcontext32(struct pt_regs *regs,
+-					   struct sigcontext32 *sc)
++static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)
+ {
+ 	int err = 0;
+ 
+@@ -440,7 +440,9 @@ static int copy_siginfo_to_user32(siginf
+ 	return err;
+ }
+ 
+-asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
++save_static_function(sys32_sigreturn);
++__attribute_used__ noinline static void
++_sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
+ {
+ 	struct sigframe *frame;
+ 	sigset_t blocked;
+@@ -476,7 +478,9 @@ badframe:
+ 	force_sig(SIGSEGV, current);
+ }
+ 
+-asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
++save_static_function(sys32_rt_sigreturn);
++__attribute_used__ noinline static void
++_sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+ {
+ 	struct rt_sigframe32 *frame;
+ 	sigset_t set;
+@@ -759,7 +763,7 @@ static inline void handle_signal(unsigne
+ 	}
+ }
+ 
+-asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs *regs)
++int do_signal32(sigset_t *oldset, struct pt_regs *regs)
+ {
+ 	struct k_sigaction ka;
+ 	siginfo_t info;
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/signal_n32.c linux-2.6.10-mips/arch/mips/kernel/signal_n32.c
+--- linux-2.6.10/arch/mips/kernel/signal_n32.c	2004-12-24 22:34:58.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/signal_n32.c	2005-01-08 01:13:17.000000000 +0100
+@@ -35,9 +35,12 @@
+ #include <asm/ucontext.h>
+ #include <asm/system.h>
+ #include <asm/fpu.h>
++#include <asm/cpu-features.h>
++
++#include "signal-common.h"
+ 
+ /*
+- * Including <asm/unistd.h would give use the 64-bit syscall numbers ...
++ * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
+  */
+ #define __NR_N32_rt_sigreturn		6211
+ #define __NR_N32_restart_syscall	6214
+@@ -59,17 +62,22 @@ struct ucontextn32 {
+ 	sigset_t            uc_sigmask;   /* mask last for extensibility */
+ };
+ 
++#if PLAT_TRAMPOLINE_STUFF_LINE
++#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
++#else
++#define __tramp
++#endif
++
+ struct rt_sigframe_n32 {
+ 	u32 rs_ass[4];			/* argument save space for o32 */
+-	u32 rs_code[2];			/* signal trampoline */
+-	struct siginfo rs_info;
++	u32 rs_code[2] __tramp;		/* signal trampoline */
++	struct siginfo rs_info __tramp;
+ 	struct ucontextn32 rs_uc;
+ };
+ 
+-extern asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc);
+-extern int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc);
+-
+-asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
++save_static_function(sysn32_rt_sigreturn);
++__attribute_used__ noinline static void
++_sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
+ {
+ 	struct rt_sigframe_n32 *frame;
+ 	sigset_t set;
+@@ -118,31 +126,6 @@ badframe:
+ 	force_sig(SIGSEGV, current);
+ }
+ 
+-/*
+- * Determine which stack to use..
+- */
+-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+-	size_t frame_size)
+-{
+-	unsigned long sp;
+-
+-	/* Default to using normal stack */
+-	sp = regs->regs[29];
+-
+-	/*
+- 	 * FPU emulator may have it's own trampoline active just
+- 	 * above the user stack, 16-bytes before the next lowest
+- 	 * 16 byte boundary.  Try to avoid trashing it.
+- 	 */
+- 	sp -= 32;
+-
+-	/* This is the X/Open sanctioned signal stack switching.  */
+-	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
+-		sp = current->sas_ss_sp + current->sas_ss_size;
+-
+-	return (void *)((sp - frame_size) & ALMASK);
+-}
+-
+ void setup_rt_frame_n32(struct k_sigaction * ka,
+ 	struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
+ {
+@@ -160,8 +143,10 @@ void setup_rt_frame_n32(struct k_sigacti
+ 	 *         li      v0, __NR_rt_sigreturn
+ 	 *         syscall
+ 	 */
++	if (PLAT_TRAMPOLINE_STUFF_LINE)
++		__clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
+ 	err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0);
+-	err |= __put_user(0x0000000c                    , frame->rs_code + 1);
++	err |= __put_user(0x0000000c                        , frame->rs_code + 1);
+ 	flush_cache_sigtramp((unsigned long) frame->rs_code);
+ 
+ 	/* Create siginfo.  */
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/smp.c linux-2.6.10-mips/arch/mips/kernel/smp.c
+--- linux-2.6.10/arch/mips/kernel/smp.c	2004-12-24 22:34:01.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/smp.c	2004-12-21 03:25:15.000000000 +0100
+@@ -94,6 +94,7 @@ static void smp_tune_scheduling (void)
+ }
+ 
+ extern void __init calibrate_delay(void);
++extern ATTRIB_NORET void cpu_idle(void);
+ 
+ /*
+  * First C code run on the secondary CPUs after being started up by
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/syscall.c linux-2.6.10-mips/arch/mips/kernel/syscall.c
+--- linux-2.6.10/arch/mips/kernel/syscall.c	2004-12-24 22:35:24.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/syscall.c	2004-10-27 02:12:47.000000000 +0200
+@@ -116,7 +116,7 @@ unsigned long arch_get_unmapped_area(str
+ }
+ 
+ /* common code for old and new mmaps */
+-static inline long
++static inline unsigned long
+ do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+         unsigned long flags, unsigned long fd, unsigned long pgoff)
+ {
+@@ -140,8 +140,9 @@ out:
+ 	return error;
+ }
+ 
+-asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot,
+-                                  int flags, int fd, off_t offset)
++asmlinkage unsigned long
++old_mmap(unsigned long addr, unsigned long len, int prot,
++	int flags, int fd, off_t offset)
+ {
+ 	unsigned long result;
+ 
+@@ -155,7 +156,7 @@ out:
+ 	return result;
+ }
+ 
+-asmlinkage long
++asmlinkage unsigned long
+ sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+           unsigned long flags, unsigned long fd, unsigned long pgoff)
+ {
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/sysirix.c linux-2.6.10-mips/arch/mips/kernel/sysirix.c
+--- linux-2.6.10/arch/mips/kernel/sysirix.c	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/sysirix.c	2005-01-03 18:57:15.000000000 +0100
+@@ -1648,7 +1648,7 @@ asmlinkage int irix_statvfs64(char *fnam
+ 	struct kstatfs kbuf;
+ 	int error, i;
+ 
+-	printk("[%s:%d] Wheee.. irix_statvfs(%s,%p)\n",
++	printk("[%s:%d] Wheee.. irix_statvfs64(%s,%p)\n",
+ 	       current->comm, current->pid, fname, buf);
+ 	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs64));
+ 	if(error)
+@@ -1694,7 +1694,7 @@ asmlinkage int irix_fstatvfs64(int fd, s
+ 	struct file *file;
+ 	int error, i;
+ 
+-	printk("[%s:%d] Wheee.. irix_fstatvfs(%d,%p)\n",
++	printk("[%s:%d] Wheee.. irix_fstatvfs64(%d,%p)\n",
+ 	       current->comm, current->pid, fd, buf);
+ 
+ 	error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/traps.c linux-2.6.10-mips/arch/mips/kernel/traps.c
+--- linux-2.6.10/arch/mips/kernel/traps.c	2004-12-24 22:34:32.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/traps.c	2004-12-31 02:55:45.000000000 +0100
+@@ -38,12 +38,9 @@
+ #include <asm/watch.h>
+ #include <asm/types.h>
+ 
+-extern asmlinkage void handle_mod(void);
++extern asmlinkage void handle_tlbm(void);
+ extern asmlinkage void handle_tlbl(void);
+ extern asmlinkage void handle_tlbs(void);
+-extern asmlinkage void __xtlb_mod(void);
+-extern asmlinkage void __xtlb_tlbl(void);
+-extern asmlinkage void __xtlb_tlbs(void);
+ extern asmlinkage void handle_adel(void);
+ extern asmlinkage void handle_ades(void);
+ extern asmlinkage void handle_ibe(void);
+@@ -82,7 +79,12 @@ void show_stack(struct task_struct *task
+ 	long stackdata;
+ 	int i;
+ 
+-	sp = sp ? sp : (unsigned long *) &sp;
++	if (!sp) {
++		if (task && task != current)
++			sp = (unsigned long *) task->thread.reg29;
++		else
++			sp = (unsigned long *) &sp;
++	}
+ 
+ 	printk("Stack :");
+ 	i = 0;
+@@ -110,8 +112,12 @@ void show_trace(struct task_struct *task
+ 	const int field = 2 * sizeof(unsigned long);
+ 	unsigned long addr;
+ 
+-	if (!stack)
+-		stack = (unsigned long*)&stack;
++	if (!stack) {
++		if (task && task != current)
++			stack = (unsigned long *) task->thread.reg29;
++		else
++			stack = (unsigned long *) &stack;
++	}
+ 
+ 	printk("Call Trace:");
+ #ifdef CONFIG_KALLSYMS
+@@ -1001,16 +1007,10 @@ void __init trap_init(void)
+ 	if (board_be_init)
+ 		board_be_init();
+ 
+-#ifdef CONFIG_MIPS32
+-	set_except_vector(1, handle_mod);
++	set_except_vector(1, handle_tlbm);
+ 	set_except_vector(2, handle_tlbl);
+ 	set_except_vector(3, handle_tlbs);
+-#endif
+-#ifdef CONFIG_MIPS64
+-	set_except_vector(1, __xtlb_mod);
+-	set_except_vector(2, __xtlb_tlbl);
+-	set_except_vector(3, __xtlb_tlbs);
+-#endif
++
+ 	set_except_vector(4, handle_adel);
+ 	set_except_vector(5, handle_ades);
+ 
+@@ -1047,7 +1047,7 @@ void __init trap_init(void)
+ 		 * unaligned ldc1/sdc1 exception.  The handlers have not been
+ 		 * written yet.  Well, anyway there is no R6000 machine on the
+ 		 * current list of targets for Linux/MIPS.
+-		 * (Duh, crap, there is someone with a tripple R6k machine)
++		 * (Duh, crap, there is someone with a triple R6k machine)
+ 		 */
+ 		//set_except_vector(14, handle_mc);
+ 		//set_except_vector(15, handle_ndc);
+diff -urpNX dontdiff linux-2.6.10/arch/mips/kernel/vmlinux.lds.S linux-2.6.10-mips/arch/mips/kernel/vmlinux.lds.S
+--- linux-2.6.10/arch/mips/kernel/vmlinux.lds.S	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/kernel/vmlinux.lds.S	2004-12-30 14:54:28.000000000 +0100
+@@ -156,6 +156,7 @@ SECTIONS
+ 	*(.options)
+ 	*(.pdr)
+ 	*(.reginfo)
++	*(.mdebug*)
+   }
+ 
+   /* This is the MIPS specific mdebug section.  */
+diff -urpNX dontdiff linux-2.6.10/arch/mips/lib-64/dump_tlb.c linux-2.6.10-mips/arch/mips/lib-64/dump_tlb.c
+--- linux-2.6.10/arch/mips/lib-64/dump_tlb.c	2004-12-24 22:35:59.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/lib-64/dump_tlb.c	2005-01-09 13:23:56.000000000 +0100
+@@ -148,16 +148,16 @@ void dump_list_process(struct task_struc
+ 	printk("tasks->mm.pgd        == %08lx\n", (unsigned long) t->mm->pgd);
+ 
+ 	page_dir = pgd_offset(t->mm, 0);
+-	printk("page_dir == %08lx\n", (unsigned long) page_dir);
++	printk("page_dir == %016lx\n", (unsigned long) page_dir);
+ 
+ 	pgd = pgd_offset(t->mm, addr);
+-	printk("pgd == %08lx, ", (unsigned long) pgd);
++	printk("pgd == %016lx\n", (unsigned long) pgd);
+ 
+ 	pmd = pmd_offset(pgd, addr);
+-	printk("pmd == %08lx, ", (unsigned long) pmd);
++	printk("pmd == %016lx\n", (unsigned long) pmd);
+ 
+ 	pte = pte_offset(pmd, addr);
+-	printk("pte == %08lx, ", (unsigned long) pte);
++	printk("pte == %016lx\n", (unsigned long) pte);
+ 
+ 	page = *pte;
+ 	printk("page == %08lx\n", pte_val(page));
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mips-boards/malta/malta_int.c linux-2.6.10-mips/arch/mips/mips-boards/malta/malta_int.c
+--- linux-2.6.10/arch/mips/mips-boards/malta/malta_int.c	2004-12-24 22:34:27.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mips-boards/malta/malta_int.c	2004-12-21 03:25:16.000000000 +0100
+@@ -1,6 +1,6 @@
+ /*
+  * Carsten Langgaard, carstenl at mips.com
+- * Copyright (C) 2000, 2001 MIPS Technologies, Inc.
++ * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
+  * Copyright (C) 2001 Ralf Baechle
+  *
+  *  This program is free software; you can distribute it and/or modify it
+@@ -155,9 +155,9 @@ void corehi_irqdispatch(struct pt_regs *
+         case MIPS_REVISION_CORID_CORE_FPGAR2:
+                 data = GT_READ(GT_INTRCAUSE_OFS);
+                 printk("GT_INTRCAUSE = %08x\n", data);
+-                data = GT_READ(0x70);
+-                datahi = GT_READ(0x78);
+-                printk("GT_CPU_ERR_ADDR = %02x%08x\n", datahi, data);
++                data = GT_READ(GT_CPUERR_ADDRLO_OFS);
++                datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
++                printk("GT_CPUERR_ADDR = %02x%08x\n", datahi, data);
+                 break;
+         case MIPS_REVISION_CORID_BONITO64:
+         case MIPS_REVISION_CORID_CORE_20K:
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/Makefile linux-2.6.10-mips/arch/mips/mm/Makefile
+--- linux-2.6.10/arch/mips/mm/Makefile	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/Makefile	2005-01-11 00:40:22.000000000 +0100
+@@ -3,7 +3,7 @@
+ #
+ 
+ obj-y				+= cache.o extable.o fault.o init.o pgtable.o \
+-				   tlbex.o
++				   tlbex.o tlbex-fault.o
+ 
+ obj-$(CONFIG_MIPS32)		+= ioremap.o pgtable-32.o
+ obj-$(CONFIG_MIPS64)		+= pgtable-64.o
+@@ -27,40 +27,6 @@ obj-$(CONFIG_CPU_TX39XX)	+= c-tx39.o pg-
+ obj-$(CONFIG_CPU_TX49XX)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+ obj-$(CONFIG_CPU_VR41XX)	+= c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o
+ 
+-#
+-# TLB exception handling code differs between 32-bit and 64-bit kernels.
+-#
+-ifdef CONFIG_MIPS32
+-obj-$(CONFIG_CPU_R3000)		+= tlbex32-r3k.o
+-obj-$(CONFIG_CPU_TX49XX)	+= tlbex32-r4k.o
+-obj-$(CONFIG_CPU_R4300)		+= tlbex32-r4k.o
+-obj-$(CONFIG_CPU_R4X00)		+= tlbex32-r4k.o
+-obj-$(CONFIG_CPU_VR41XX)	+= tlbex32-r4k.o
+-obj-$(CONFIG_CPU_R5000)		+= tlbex32-r4k.o
+-obj-$(CONFIG_CPU_NEVADA)	+= tlbex32-r4k.o
+-obj-$(CONFIG_CPU_R5432)		+= tlbex32-r4k.o
+-obj-$(CONFIG_CPU_RM7000)	+= tlbex32-r4k.o
+-obj-$(CONFIG_CPU_RM9000)	+= tlbex32-r4k.o
+-obj-$(CONFIG_CPU_R10000)	+= tlbex32-r4k.o
+-obj-$(CONFIG_CPU_MIPS32)	+= tlbex32-mips32.o
+-obj-$(CONFIG_CPU_MIPS64)	+= tlbex32-r4k.o
+-obj-$(CONFIG_CPU_SB1)		+= tlbex32-r4k.o
+-obj-$(CONFIG_CPU_TX39XX)	+= tlbex32-r3k.o
+-endif
+-ifdef CONFIG_MIPS64
+-obj-$(CONFIG_CPU_R4300)		+= tlb64-glue-r4k.o
+-obj-$(CONFIG_CPU_R4X00)		+= tlb64-glue-r4k.o
+-obj-$(CONFIG_CPU_R5000)		+= tlb64-glue-r4k.o
+-obj-$(CONFIG_CPU_NEVADA)	+= tlb64-glue-r4k.o
+-obj-$(CONFIG_CPU_R5432)		+= tlb64-glue-r4k.o
+-obj-$(CONFIG_CPU_RM7000)	+= tlb64-glue-r4k.o
+-obj-$(CONFIG_CPU_RM9000)	+= tlb64-glue-r4k.o
+-obj-$(CONFIG_CPU_R10000)	+= tlb64-glue-r4k.o
+-obj-$(CONFIG_CPU_SB1)		+= tlb64-glue-sb1.o
+-obj-$(CONFIG_CPU_MIPS64)	+= tlb64-glue-r4k.o
+-endif
+-
+-
+ obj-$(CONFIG_IP22_CPU_SCACHE)	+= sc-ip22.o
+ obj-$(CONFIG_R5000_CPU_SCACHE)  += sc-r5k.o
+ obj-$(CONFIG_RM7000_CPU_SCACHE)	+= sc-rm7k.o
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/c-r4k.c linux-2.6.10-mips/arch/mips/mm/c-r4k.c
+--- linux-2.6.10/arch/mips/mm/c-r4k.c	2004-12-24 22:35:29.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/c-r4k.c	2005-01-11 00:40:22.000000000 +0100
+@@ -238,6 +238,22 @@ static inline void r4k_blast_scache_page
+ 		r4k_blast_scache_page = blast_scache128_page;
+ }
+ 
++static void (* r4k_blast_scache_page_indexed)(unsigned long addr);
++
++static inline void r4k_blast_scache_page_indexed_setup(void)
++{
++	unsigned long sc_lsize = cpu_scache_line_size();
++
++	if (sc_lsize == 16)
++		r4k_blast_scache_page_indexed = blast_scache16_page_indexed;
++	else if (sc_lsize == 32)
++		r4k_blast_scache_page_indexed = blast_scache32_page_indexed;
++	else if (sc_lsize == 64)
++		r4k_blast_scache_page_indexed = blast_scache64_page_indexed;
++	else if (sc_lsize == 128)
++		r4k_blast_scache_page_indexed = blast_scache128_page_indexed;
++}
++
+ static void (* r4k_blast_scache)(void);
+ 
+ static inline void r4k_blast_scache_setup(void)
+@@ -318,9 +334,6 @@ static inline void local_r4k_flush_cache
+ {
+ 	struct mm_struct *mm = args;
+ 
+-	if (!cpu_has_dc_aliases)
+-		return;
+-
+ 	if (!cpu_context(smp_processor_id(), mm))
+ 		return;
+ 
+@@ -340,6 +353,9 @@ static inline void local_r4k_flush_cache
+ 
+ static void r4k_flush_cache_mm(struct mm_struct *mm)
+ {
++	if (!cpu_has_dc_aliases)
++		return;
++
+ 	on_each_cpu(local_r4k_flush_cache_mm, mm, 1, 1);
+ }
+ 
+@@ -359,13 +375,6 @@ static inline void local_r4k_flush_cache
+ 	pmd_t *pmdp;
+ 	pte_t *ptep;
+ 
+-	/*
+-	 * If ownes no valid ASID yet, cannot possibly have gotten
+-	 * this page into the cache.
+-	 */
+-	if (cpu_context(smp_processor_id(), mm) == 0)
+-		return;
+-
+ 	page &= PAGE_MASK;
+ 	pgdp = pgd_offset(mm, page);
+ 	pmdp = pmd_offset(pgdp, page);
+@@ -385,8 +394,11 @@ static inline void local_r4k_flush_cache
+ 	 * in that case, which doesn't overly flush the cache too much.
+ 	 */
+ 	if ((mm == current->active_mm) && (pte_val(*ptep) & _PAGE_VALID)) {
+-		if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
++		if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
+ 			r4k_blast_dcache_page(page);
++			if (exec && !cpu_icache_snoops_remote_store)
++				r4k_blast_scache_page(page);
++		}
+ 		if (exec)
+ 			r4k_blast_icache_page(page);
+ 
+@@ -398,8 +410,11 @@ static inline void local_r4k_flush_cache
+ 	 * to work correctly.
+ 	 */
+ 	page = INDEX_BASE + (page & (dcache_size - 1));
+-	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
++	if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
+ 		r4k_blast_dcache_page_indexed(page);
++		if (exec && !cpu_icache_snoops_remote_store)
++			r4k_blast_scache_page_indexed(page);
++	}
+ 	if (exec) {
+ 		if (cpu_has_vtag_icache) {
+ 			int cpu = smp_processor_id();
+@@ -416,6 +431,13 @@ static void r4k_flush_cache_page(struct 
+ {
+ 	struct flush_cache_page_args args;
+ 
++	/*
++	 * If ownes no valid ASID yet, cannot possibly have gotten
++	 * this page into the cache.
++	 */
++	if (cpu_context(smp_processor_id(), vma->vm_mm) == 0)
++		return;
++
+ 	args.vma = vma;
+ 	args.page = page;
+ 
+@@ -442,14 +464,15 @@ static inline void local_r4k_flush_icach
+ 	struct flush_icache_range_args *fir_args = args;
+ 	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
+ 	unsigned long ic_lsize = current_cpu_data.icache.linesz;
++	unsigned long sc_lsize = current_cpu_data.scache.linesz;
+ 	unsigned long start = fir_args->start;
+ 	unsigned long end = fir_args->end;
+ 	unsigned long addr, aend;
+ 
+ 	if (!cpu_has_ic_fills_f_dc) {
+-		if (end - start > dcache_size)
++		if (end - start > dcache_size) {
+ 			r4k_blast_dcache();
+-		else {
++		} else {
+ 			addr = start & ~(dc_lsize - 1);
+ 			aend = (end - 1) & ~(dc_lsize - 1);
+ 
+@@ -461,6 +484,23 @@ static inline void local_r4k_flush_icach
+ 				addr += dc_lsize;
+ 			}
+ 		}
++
++		if (!cpu_icache_snoops_remote_store) {
++			if (end - start > scache_size) {
++				r4k_blast_scache();
++			} else {
++				addr = start & ~(sc_lsize - 1);
++				aend = (end - 1) & ~(sc_lsize - 1);
++
++				while (1) {
++					/* Hit_Writeback_Inv_D */
++					protected_writeback_scache_line(addr);
++					if (addr == aend)
++						break;
++					addr += sc_lsize;
++				}
++			}
++		}
+ 	}
+ 
+ 	if (end - start > icache_size)
+@@ -527,6 +567,8 @@ static inline void local_r4k_flush_icach
+ 	if (!cpu_has_ic_fills_f_dc) {
+ 		unsigned long addr = (unsigned long) page_address(page);
+ 		r4k_blast_dcache_page(addr);
++		if (!cpu_icache_snoops_remote_store)
++			r4k_blast_scache_page(addr);
+ 		ClearPageDcacheDirty(page);
+ 	}
+ 
+@@ -669,10 +711,13 @@ static void local_r4k_flush_cache_sigtra
+ {
+ 	unsigned long ic_lsize = current_cpu_data.icache.linesz;
+ 	unsigned long dc_lsize = current_cpu_data.dcache.linesz;
++	unsigned long sc_lsize = current_cpu_data.scache.linesz;
+ 	unsigned long addr = (unsigned long) arg;
+ 
+ 	R4600_HIT_CACHEOP_WAR_IMPL;
+ 	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
++	if (!cpu_icache_snoops_remote_store)
++		protected_writeback_scache_line(addr & ~(sc_lsize - 1));
+ 	protected_flush_icache_line(addr & ~(ic_lsize - 1));
+ 	if (MIPS4K_ICACHE_REFILL_WAR) {
+ 		__asm__ __volatile__ (
+@@ -739,8 +784,8 @@ static inline void rm7k_erratum31(void)
+ 	}
+ }
+ 
+-static char *way_string[] = { NULL, "direct mapped", "2-way", "3-way", "4-way",
+-	"5-way", "6-way", "7-way", "8-way"
++static char *way_string[] __initdata = { NULL, "direct mapped", "2-way",
++	"3-way", "4-way", "5-way", "6-way", "7-way", "8-way"
+ };
+ 
+ static void __init probe_pcache(void)
+@@ -1178,6 +1223,7 @@ void __init ld_mmu_r4xx0(void)
+ 	r4k_blast_icache_page_indexed_setup();
+ 	r4k_blast_icache_setup();
+ 	r4k_blast_scache_page_setup();
++	r4k_blast_scache_page_indexed_setup();
+ 	r4k_blast_scache_setup();
+ 
+ 	/*
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/c-sb1.c linux-2.6.10-mips/arch/mips/mm/c-sb1.c
+--- linux-2.6.10/arch/mips/mm/c-sb1.c	2004-12-24 22:34:45.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/c-sb1.c	2004-12-21 03:25:16.000000000 +0100
+@@ -503,7 +503,7 @@ void ld_mmu_sb1(void)
+ 	/* Special cache error handler for SB1 */
+ 	memcpy((void *)(CAC_BASE   + 0x100), &except_vec2_sb1, 0x80);
+ 	memcpy((void *)(UNCAC_BASE + 0x100), &except_vec2_sb1, 0x80);
+-	memcpy((void *)KSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80);
++	memcpy((void *)CKSEG1ADDR(&handle_vec2_sb1), &handle_vec2_sb1, 0x80);
+ 
+ 	probe_cache_sizes();
+ 
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/cache.c linux-2.6.10-mips/arch/mips/mm/cache.c
+--- linux-2.6.10/arch/mips/mm/cache.c	2004-12-24 22:34:31.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/cache.c	2004-12-21 03:25:16.000000000 +0100
+@@ -45,10 +45,17 @@ EXPORT_SYMBOL(_dma_cache_inv);
+ 
+ #endif /* CONFIG_DMA_NONCOHERENT */
+ 
+-asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
++/*
++ * We could optimize the case where the cache argument is not BCACHE but
++ * that seems very atypical use ...
++ */
++asmlinkage int sys_cacheflush(unsigned long addr, unsigned long int bytes,
++	unsigned int cache)
+ {
+-	/* This should flush more selectivly ...  */
+-	__flush_cache_all();
++	if (verify_area(VERIFY_WRITE, (void *) addr, bytes))
++		return -EFAULT;
++
++	flush_icache_range(addr, addr + bytes);
+ 
+ 	return 0;
+ }
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/cerr-sb1.c linux-2.6.10-mips/arch/mips/mm/cerr-sb1.c
+--- linux-2.6.10/arch/mips/mm/cerr-sb1.c	2004-12-24 22:35:24.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/cerr-sb1.c	2004-12-21 03:25:16.000000000 +0100
+@@ -251,14 +251,14 @@ static const uint8_t parity[256] = {
+ 
+ /* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */
+ static const uint64_t mask_72_64[8] = {
+-	0x0738C808099264FFL,
+-	0x38C808099264FF07L,
+-	0xC808099264FF0738L,
+-	0x08099264FF0738C8L,
+-	0x099264FF0738C808L,
+-	0x9264FF0738C80809L,
+-	0x64FF0738C8080992L,
+-	0xFF0738C808099264L
++	0x0738C808099264FFULL,
++	0x38C808099264FF07ULL,
++	0xC808099264FF0738ULL,
++	0x08099264FF0738C8ULL,
++	0x099264FF0738C808ULL,
++	0x9264FF0738C80809ULL,
++	0x64FF0738C8080992ULL,
++	0xFF0738C808099264ULL
+ };
+ 
+ /* Calculate the parity on a range of bits */
+@@ -330,9 +330,9 @@ static uint32_t extract_ic(unsigned shor
+ 				    ((lru >> 4) & 0x3),
+ 				    ((lru >> 6) & 0x3));
+ 		}
+-		va = (taglo & 0xC0000FFFFFFFE000) | addr;
++		va = (taglo & 0xC0000FFFFFFFE000ULL) | addr;
+ 		if ((taglo & (1 << 31)) && (((taglo >> 62) & 0x3) == 3))
+-			va |= 0x3FFFF00000000000;
++			va |= 0x3FFFF00000000000ULL;
+ 		valid = ((taghi >> 29) & 1);
+ 		if (valid) {
+ 			tlo_tmp = taglo & 0xfff3ff;
+@@ -473,7 +473,7 @@ static uint32_t extract_dc(unsigned shor
+ 		: "r" ((way << 13) | addr));
+ 
+ 		taglo = ((unsigned long long)taglohi << 32) | taglolo;
+-		pa = (taglo & 0xFFFFFFE000) | addr;
++		pa = (taglo & 0xFFFFFFE000ULL) | addr;
+ 		if (way == 0) {
+ 			lru = (taghi >> 14) & 0xff;
+ 			prom_printf("[Bank %d Set 0x%02x]  LRU > %d %d %d %d > MRU\n",
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/pg-sb1.c linux-2.6.10-mips/arch/mips/mm/pg-sb1.c
+--- linux-2.6.10/arch/mips/mm/pg-sb1.c	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/pg-sb1.c	2005-01-06 23:40:01.000000000 +0100
+@@ -2,6 +2,7 @@
+  * Copyright (C) 1996 David S. Miller (dm at engr.sgi.com)
+  * Copyright (C) 1997, 2001 Ralf Baechle (ralf at gnu.org)
+  * Copyright (C) 2000 SiByte, Inc.
++ * Copyright (C) 2005 Thiemo Seufer
+  *
+  * Written by Justin Carlson of SiByte, Inc.
+  *         and Kip Walker of Broadcom Corp.
+@@ -39,11 +40,7 @@
+ #define SB1_PREF_STORE_STREAMED_HINT "5"
+ #endif
+ 
+-#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
+ static inline void clear_page_cpu(void *page)
+-#else
+-void clear_page(void *page)
+-#endif
+ {
+ 	unsigned char *addr = (unsigned char *) page;
+ 	unsigned char *end = addr + PAGE_SIZE;
+@@ -57,90 +54,143 @@ void clear_page(void *page)
+ 	 * since we know we're on an SB1, we force the assembler to take
+ 	 * 64-bit operands to speed things up
+ 	 */
+-	do {
+-		__asm__ __volatile__(
+-		"	.set	mips4		\n"
++	__asm__ __volatile__(
++	"	.set	push		\n"
++	"	.set	mips4		\n"
++	"	.set	noreorder	\n"
+ #ifdef CONFIG_CPU_HAS_PREFETCH
+-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  0(%0)  \n"  /* Prefetch the first 4 lines */
+-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ", 32(%0)  \n"
+-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ", 64(%0)  \n"
+-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ", 96(%0)  \n"
+-#endif
+-		"1:	sd	$0,  0(%0)	\n"  /* Throw out a cacheline of 0's */
+-		"	sd	$0,  8(%0)	\n"
+-		"	sd	$0, 16(%0)	\n"
+-		"	sd	$0, 24(%0)	\n"
+-#ifdef CONFIG_CPU_HAS_PREFETCH
+-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ",128(%0)  \n"  /* Prefetch 4 lines ahead     */
++	"	daddiu	%0, %0, 128	\n"
++	"	pref	" SB1_PREF_STORE_STREAMED_HINT ", -128(%0)  \n"  /* Prefetch the first 4 lines */
++	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -96(%0)  \n"
++	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -64(%0)  \n"
++	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%0)  \n"
++	"1:	sd	$0, -128(%0)	\n"  /* Throw out a cacheline of 0's */
++	"	sd	$0, -120(%0)	\n"
++	"	sd	$0, -112(%0)	\n"
++	"	sd	$0, -104(%0)	\n"
++	"	daddiu	%0, %0, 32	\n"
++	"	bnel	%0, %1, 1b	\n"
++	"	 pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%0)  \n"
++	"	daddiu	%0, %0, -128	\n"
+ #endif
+-		"	.set	mips0		\n"
+-		:
+-		: "r" (addr)
+-		: "memory");
+-		addr += 32;
+-	} while (addr != end);
++	"	sd	$0, 0(%0)	\n"  /* Throw out a cacheline of 0's */
++	"1:	sd	$0, 8(%0)	\n"
++	"	sd	$0, 16(%0)	\n"
++	"	sd	$0, 24(%0)	\n"
++	"	daddiu	%0, %0, 32	\n"
++	"	bnel	%0, %1, 1b	\n"
++	"	 sd	$0, 0(%0)	\n"
++	"	.set	pop		\n"
++	: "+r" (addr)
++	: "r" (end)
++	: "memory");
+ }
+ 
+-#ifdef CONFIG_SIBYTE_DMA_PAGEOPS
+ static inline void copy_page_cpu(void *to, void *from)
+-#else
+-void copy_page(void *to, void *from)
+-#endif
+ {
+-	unsigned char *src = from;
+-	unsigned char *dst = to;
++	unsigned char *src = (unsigned char *)from;
++	unsigned char *dst = (unsigned char *)to;
+ 	unsigned char *end = src + PAGE_SIZE;
+ 
+ 	/*
+-	 * This should be optimized in assembly...can't use ld/sd, though,
+-	 * because the top 32 bits could be nuked if we took an interrupt
+-	 * during the routine.	And this is not a good place to be cli()'ing
+-	 *
+ 	 * The pref's used here are using "streaming" hints, which cause the
+ 	 * copied data to be kicked out of the cache sooner.  A page copy often
+ 	 * ends up copying a lot more data than is commonly used, so this seems
+ 	 * to make sense in terms of reducing cache pollution, but I've no real
+ 	 * performance data to back this up
+ 	 */
+-
+-	do {
+-		__asm__ __volatile__(
+-		"	.set	mips4					\n"
++	__asm__ __volatile__(
++	"	.set	push		\n"
++	"	.set	mips4		\n"
++	"	.set	noreorder	\n"
+ #ifdef CONFIG_CPU_HAS_PREFETCH
+-		"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  0(%0)\n"  /* Prefetch the first 3 lines */
+-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  0(%1)\n"
+-		"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  32(%0)\n"
+-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  32(%1)\n"
+-		"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  64(%0)\n"
+-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  64(%1)\n"
+-#endif
+-		"1:	lw	$2,  0(%0)	\n"  /* Block copy a cacheline */
+-		"	lw	$3,  4(%0)	\n"
+-		"	lw	$4,  8(%0)	\n"
+-		"	lw	$5, 12(%0)	\n"
+-		"	lw	$6, 16(%0)	\n"
+-		"	lw	$7, 20(%0)	\n"
+-		"	lw	$8, 24(%0)	\n"
+-		"	lw	$9, 28(%0)	\n"
+-#ifdef CONFIG_CPU_HAS_PREFETCH
+-		"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ", 96(%0)  \n"  /* Prefetch ahead         */
+-		"	pref	" SB1_PREF_STORE_STREAMED_HINT ", 96(%1)  \n"
++	"	daddiu	%0, %0, 128	\n"
++	"	daddiu	%1, %1, 128	\n"
++	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ", -128(%0)\n"  /* Prefetch the first 4 lines */
++	"	pref	" SB1_PREF_STORE_STREAMED_HINT ", -128(%1)\n"
++	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -96(%0)\n"
++	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -96(%1)\n"
++	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -64(%0)\n"
++	"	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -64(%1)\n"
++	"	pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -32(%0)\n"
++	"1:	pref	" SB1_PREF_STORE_STREAMED_HINT ",  -32(%1)\n"
++# ifdef CONFIG_MIPS64
++	"	ld	$8, -128(%0)	\n"  /* Block copy a cacheline */
++	"	ld	$9, -120(%0)	\n"
++	"	ld	$10, -112(%0)	\n"
++	"	ld	$11, -104(%0)	\n"
++	"	sd	$8, -128(%1)	\n"
++	"	sd	$9, -120(%1)	\n"
++	"	sd	$10, -112(%1)	\n"
++	"	sd	$11, -104(%1)	\n"
++# else
++	"	lw	$2, -128(%0)	\n"  /* Block copy a cacheline */
++	"	lw	$3, -124(%0)	\n"
++	"	lw	$6, -120(%0)	\n"
++	"	lw	$7, -116(%0)	\n"
++	"	lw	$8, -112(%0)	\n"
++	"	lw	$9, -108(%0)	\n"
++	"	lw	$10, -104(%0)	\n"
++	"	lw	$11, -100(%0)	\n"
++	"	sw	$2, -128(%1)	\n"
++	"	sw	$3, -124(%1)	\n"
++	"	sw	$6, -120(%1)	\n"
++	"	sw	$7, -116(%1)	\n"
++	"	sw	$8, -112(%1)	\n"
++	"	sw	$9, -108(%1)	\n"
++	"	sw	$10, -104(%1)	\n"
++	"	sw	$11, -100(%1)	\n"
++# endif
++	"	daddiu	%0, %0, 32	\n"
++	"	daddiu	%1, %1, 32	\n"
++	"	bnel	%0, %2, 1b	\n"
++	"	 pref	" SB1_PREF_LOAD_STREAMED_HINT  ",  -32(%0)\n"
++	"	daddiu	%0, %0, -128	\n"
++	"	daddiu	%1, %1, -128	\n"
++#endif
++#ifdef CONFIG_MIPS64
++	"	ld	$8, 0(%0)	\n"  /* Block copy a cacheline */
++	"1:	ld	$9, 8(%0)	\n"
++	"	ld	$10, 16(%0)	\n"
++	"	ld	$11, 24(%0)	\n"
++	"	sd	$8, 0(%1)	\n"
++	"	sd	$9, 8(%1)	\n"
++	"	sd	$10, 16(%1)	\n"
++	"	sd	$11, 24(%1)	\n"
++#else
++	"	lw	$2, 0(%0)	\n"  /* Block copy a cacheline */
++	"1:	lw	$3, 4(%0)	\n"
++	"	lw	$6, 8(%0)	\n"
++	"	lw	$7, 12(%0)	\n"
++	"	lw	$8, 16(%0)	\n"
++	"	lw	$9, 20(%0)	\n"
++	"	lw	$10, 24(%0)	\n"
++	"	lw	$11, 28(%0)	\n"
++	"	sw	$2, 0(%1)	\n"
++	"	sw	$3, 4(%1)	\n"
++	"	sw	$6, 8(%1)	\n"
++	"	sw	$7, 12(%1)	\n"
++	"	sw	$8, 16(%1)	\n"
++	"	sw	$9, 20(%1)	\n"
++	"	sw	$10, 24(%1)	\n"
++	"	sw	$11, 28(%1)	\n"
++#endif
++	"	daddiu	%0, %0, 32	\n"
++	"	daddiu	%1, %1, 32	\n"
++	"	bnel	%0, %2, 1b	\n"
++#ifdef CONFIG_MIPS64
++	"	 ld	$8, 0(%0)	\n"
++#else
++	"	 lw	$2, 0(%0)	\n"
++#endif
++	"	.set	pop		\n"
++	: "+r" (src), "+r" (dst)
++	: "r" (end)
++#ifdef CONFIG_MIPS64
++	: "$8","$9","$10","$11","memory");
++#else
++	: "$2","$3","$6","$7","$8","$9","$10","$11","memory");
+ #endif
+-		"	sw	$2,  0(%1)	\n"
+-		"	sw	$3,  4(%1)	\n"
+-		"	sw	$4,  8(%1)	\n"
+-		"	sw	$5, 12(%1)	\n"
+-		"	sw	$6, 16(%1)	\n"
+-		"	sw	$7, 20(%1)	\n"
+-		"	sw	$8, 24(%1)	\n"
+-		"	sw	$9, 28(%1)	\n"
+-		"	.set	mips0		\n"
+-		:
+-		: "r" (src), "r" (dst)
+-		: "$2","$3","$4","$5","$6","$7","$8","$9","memory");
+-		src += 32;
+-		dst += 32;
+-	} while (src != end);
+ }
+ 
+ 
+@@ -151,10 +201,10 @@ void copy_page(void *to, void *from)
+  * particular CPU. 
+  */
+ typedef struct dmadscr_s {
+-	uint64_t  dscr_a;
+-	uint64_t  dscr_b;
+-	uint64_t  pad_a;
+-	uint64_t  pad_b;
++	u64 dscr_a;
++	u64 dscr_b;
++	u64 pad_a;
++	u64 pad_b;
+ } dmadscr_t;
+ 
+ static dmadscr_t page_descr[NR_CPUS] __attribute__((aligned(SMP_CACHE_BYTES)));
+@@ -162,14 +212,14 @@ static dmadscr_t page_descr[NR_CPUS] __a
+ void sb1_dma_init(void)
+ {
+ 	int cpu = smp_processor_id();
+-	uint64_t base_val = PHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1);
++	u64 base_val = CPHYSADDR(&page_descr[cpu]) | V_DM_DSCR_BASE_RINGSZ(1);
+ 
+-	__raw_writeq(base_val,
+-		     IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+-	__raw_writeq(base_val | M_DM_DSCR_BASE_RESET,
+-		     IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+-	__raw_writeq(base_val | M_DM_DSCR_BASE_ENABL,
+-		     IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
++	bus_writeq(base_val,
++		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
++	bus_writeq(base_val | M_DM_DSCR_BASE_RESET,
++		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
++	bus_writeq(base_val | M_DM_DSCR_BASE_ENABL,
++		   (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+ }
+ 
+ void clear_page(void *page)
+@@ -177,46 +227,61 @@ void clear_page(void *page)
+ 	int cpu = smp_processor_id();
+ 
+ 	/* if the page is above Kseg0, use old way */
+-	if (KSEGX(page) != CAC_BASE)
++	if ((long)KSEGX(page) != (long)CKSEG0)
+ 		return clear_page_cpu(page);
+ 
+-	page_descr[cpu].dscr_a = PHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
++	page_descr[cpu].dscr_a = CPHYSADDR(page) | M_DM_DSCRA_ZERO_MEM | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+ 	page_descr[cpu].dscr_b = V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
+-	__raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
++	bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+ 
+ 	/*
+ 	 * Don't really want to do it this way, but there's no
+ 	 * reliable way to delay completion detection.
+ 	 */
+-	while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)))
++	while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
++			   M_DM_DSCR_BASE_INTERRUPT))))
+ 		;
+-	__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
++	bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+ }
+ 
+ void copy_page(void *to, void *from)
+ {
+-	unsigned long from_phys = PHYSADDR(from);
+-	unsigned long to_phys = PHYSADDR(to);
++	unsigned long from_phys = CPHYSADDR(from);
++	unsigned long to_phys = CPHYSADDR(to);
+ 	int cpu = smp_processor_id();
+ 
+ 	/* if either page is above Kseg0, use old way */
+-	if ((KSEGX(to) != CAC_BASE) || (KSEGX(from) != CAC_BASE))
++	if ((long)KSEGX(to) != (long)CKSEG0
++	    || (long)KSEGX(from) != (long)CKSEG0)
+ 		return copy_page_cpu(to, from);
+ 
+-	page_descr[cpu].dscr_a = PHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
+-	page_descr[cpu].dscr_b = PHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
+-	__raw_writeq(1, IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
++	page_descr[cpu].dscr_a = CPHYSADDR(to_phys) | M_DM_DSCRA_L2C_DEST | M_DM_DSCRA_INTERRUPT;
++	page_descr[cpu].dscr_b = CPHYSADDR(from_phys) | V_DM_DSCRB_SRC_LENGTH(PAGE_SIZE);
++	bus_writeq(1, (void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_COUNT)));
+ 
+ 	/*
+ 	 * Don't really want to do it this way, but there's no
+ 	 * reliable way to delay completion detection.
+ 	 */
+-	while (!(__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) & M_DM_DSCR_BASE_INTERRUPT)))
++	while (!(bus_readq((void *)(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE_DEBUG)) &
++				    M_DM_DSCR_BASE_INTERRUPT))))
+ 		;
+-	__raw_readq(IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
++	bus_readq((void *)IOADDR(A_DM_REGISTER(cpu, R_DM_DSCR_BASE)));
+ }
+ 
+-#endif
++#else /* !CONFIG_SIBYTE_DMA_PAGEOPS */
++
++void clear_page(void *page)
++{
++	return clear_page_cpu(page);
++}
++
++void copy_page(void *to, void *from)
++{
++	return copy_page_cpu(to, from);
++}
++
++#endif /* !CONFIG_SIBYTE_DMA_PAGEOPS */
+ 
+ EXPORT_SYMBOL(clear_page);
+ EXPORT_SYMBOL(copy_page);
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/pgtable-32.c linux-2.6.10-mips/arch/mips/mm/pgtable-32.c
+--- linux-2.6.10/arch/mips/mm/pgtable-32.c	2004-12-24 22:34:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/pgtable-32.c	2004-12-21 03:25:16.000000000 +0100
+@@ -71,8 +71,8 @@ void __init pagetable_init(void)
+ 
+ 	/* Initialize the entire pgd.  */
+ 	pgd_init((unsigned long)swapper_pg_dir);
+-	pgd_init((unsigned long)swapper_pg_dir +
+-	         sizeof(pgd_t ) * USER_PTRS_PER_PGD);
++	pgd_init((unsigned long)swapper_pg_dir
++		 + sizeof(pgd_t) * USER_PTRS_PER_PGD);
+ 
+ #ifdef CONFIG_HIGHMEM
+ 	pgd_base = swapper_pg_dir;
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/pgtable-64.c linux-2.6.10-mips/arch/mips/mm/pgtable-64.c
+--- linux-2.6.10/arch/mips/mm/pgtable-64.c	2004-12-24 22:34:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/pgtable-64.c	2004-12-05 01:36:53.000000000 +0100
+@@ -55,5 +55,4 @@ void __init pagetable_init(void)
+ 	/* Initialize the entire pgd.  */
+ 	pgd_init((unsigned long)swapper_pg_dir);
+ 	pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);
+-	memset((void *)invalid_pte_table, 0, sizeof(pte_t) * PTRS_PER_PTE);
+ }
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/sc-rm7k.c linux-2.6.10-mips/arch/mips/mm/sc-rm7k.c
+--- linux-2.6.10/arch/mips/mm/sc-rm7k.c	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/sc-rm7k.c	2005-01-11 00:40:22.000000000 +0100
+@@ -96,13 +96,13 @@ static void rm7k_sc_inv(unsigned long ad
+ }
+ 
+ /*
+- * This function is executed in the uncached segment KSEG1.
++ * This function is executed in the uncached segment CKSEG1.
+  * It must not touch the stack, because the stack pointer still points
+- * into KSEG0.
++ * into CKSEG0.
+  *
+  * Three options:
+  *	- Write it in assembly and guarantee that we don't use the stack.
+- *	- Disable caching for KSEG0 before calling it.
++ *	- Disable caching for CKSEG0 before calling it.
+  *	- Pray that GCC doesn't randomly start using the stack.
+  *
+  * This being Linux, we obviously take the least sane of those options -
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/tlb-sb1.c linux-2.6.10-mips/arch/mips/mm/tlb-sb1.c
+--- linux-2.6.10/arch/mips/mm/tlb-sb1.c	2004-12-24 22:35:40.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/tlb-sb1.c	2004-12-21 03:25:16.000000000 +0100
+@@ -25,7 +25,7 @@
+ 
+ extern void build_tlb_refill_handler(void);
+ 
+-#define UNIQUE_ENTRYHI(idx) (KSEG0 + ((idx) << (PAGE_SHIFT + 1)))
++#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
+ 
+ /* Dump the current entry* and pagemask registers */
+ static inline void dump_cur_tlb_regs(void)
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/tlb64-glue-r4k.S linux-2.6.10-mips/arch/mips/mm/tlb64-glue-r4k.S
+--- linux-2.6.10/arch/mips/mm/tlb64-glue-r4k.S	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/tlb64-glue-r4k.S	1970-01-01 01:00:00.000000000 +0100
+@@ -1,41 +0,0 @@
+-/*
+- * This file is subject to the terms and conditions of the GNU General Public
+- * License.  See the file "COPYING" in the main directory of this archive
+- * for more details.
+- *
+- * Copyright (C) 1999 Ralf Baechle
+- * Copyright (C) 1999 Silicon Graphics, Inc.
+- */
+-#include <linux/init.h>
+-#include <asm/mipsregs.h>
+-#include <asm/regdef.h>
+-#include <asm/stackframe.h>
+-
+-	.macro	__BUILD_cli
+-	CLI
+-	.endm
+-
+-	.macro	__BUILD_sti
+-	STI
+-	.endm
+-
+-	.macro	__BUILD_kmode
+-	KMODE
+-	.endm
+-
+-	.macro	tlb_handler name interruptible writebit
+-	NESTED(__\name, PT_SIZE, sp)
+-	SAVE_ALL
+-	dmfc0	a2, CP0_BADVADDR
+-	__BUILD_\interruptible
+-	li	a1, \writebit
+-	sd	a2, PT_BVADDR(sp)
+-	move	a0, sp
+-	jal	do_page_fault
+-	j	ret_from_exception
+-	END(__\name)
+-	.endm
+-
+-	tlb_handler	xtlb_mod kmode 1
+-	tlb_handler	xtlb_tlbl kmode 0
+-	tlb_handler	xtlb_tlbs kmode 1
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/tlb64-glue-sb1.S linux-2.6.10-mips/arch/mips/mm/tlb64-glue-sb1.S
+--- linux-2.6.10/arch/mips/mm/tlb64-glue-sb1.S	2004-12-24 22:35:39.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/tlb64-glue-sb1.S	1970-01-01 01:00:00.000000000 +0100
+@@ -1,66 +0,0 @@
+-/*
+- * This file is subject to the terms and conditions of the GNU General Public
+- * License.  See the file "COPYING" in the main directory of this archive
+- * for more details.
+- *
+- * Copyright (C) 1999 Ralf Baechle
+- * Copyright (C) 1999 Silicon Graphics, Inc.
+- */
+-#include <linux/init.h>
+-#include <asm/mipsregs.h>
+-#include <asm/page.h>
+-#include <asm/regdef.h>
+-#include <asm/stackframe.h>
+-#include <asm/war.h>
+-
+-	.macro	__BUILD_cli
+-	CLI
+-	.endm
+-
+-	.macro	__BUILD_sti
+-	STI
+-	.endm
+-
+-	.macro	__BUILD_kmode
+-	KMODE
+-	.endm
+-
+-	.macro	tlb_handler name interruptible writebit
+-	NESTED(__\name, PT_SIZE, sp)
+-	SAVE_ALL
+-	dmfc0	a2, CP0_BADVADDR
+-	__BUILD_\interruptible
+-	li	a1, \writebit
+-	sd	a2, PT_BVADDR(sp)
+-	move	a0, sp
+-	jal	do_page_fault
+-	j	ret_from_exception
+-	END(__\name)
+-	.endm
+-
+-	.macro	tlb_handler_m3 name interruptible writebit
+-	NESTED(__\name, PT_SIZE, sp)
+-	dmfc0	k0, CP0_BADVADDR
+-	dmfc0	k1, CP0_ENTRYHI
+-	xor	k0, k1
+-	dsrl	k0, k0, PAGE_SHIFT + 1
+-	bnez	k0, 1f
+-	SAVE_ALL
+-	dmfc0	a2, CP0_BADVADDR
+-	__BUILD_\interruptible
+-	li	a1, \writebit
+-	sd	a2, PT_BVADDR(sp)
+-	move	a0, sp
+-	jal	do_page_fault
+-1:
+-	j	ret_from_exception
+-	END(__\name)
+-	.endm
+-
+-	tlb_handler	xtlb_mod kmode 1
+-#if BCM1250_M3_WAR
+-	tlb_handler_m3	xtlb_tlbl kmode 0
+-#else
+-	tlb_handler	xtlb_tlbl kmode 0
+-#endif
+-	tlb_handler	xtlb_tlbs kmode 1
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/tlbex-fault.S linux-2.6.10-mips/arch/mips/mm/tlbex-fault.S
+--- linux-2.6.10/arch/mips/mm/tlbex-fault.S	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/tlbex-fault.S	2004-12-30 22:52:30.000000000 +0100
+@@ -0,0 +1,28 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 1999 Ralf Baechle
++ * Copyright (C) 1999 Silicon Graphics, Inc.
++ */
++#include <asm/mipsregs.h>
++#include <asm/page.h>
++#include <asm/regdef.h>
++#include <asm/stackframe.h>
++
++	.macro tlb_do_page_fault, write
++	NESTED(tlb_do_page_fault_\write, PT_SIZE, sp)
++	SAVE_ALL
++	MFC0	a2, CP0_BADVADDR
++	KMODE
++	move	a0, sp
++	REG_S	a2, PT_BVADDR(sp)
++	li	a1, \write
++	jal	do_page_fault
++	j	ret_from_exception
++	END(tlb_do_page_fault_\write)
++	.endm
++
++	tlb_do_page_fault 0
++	tlb_do_page_fault 1
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/tlbex.c linux-2.6.10-mips/arch/mips/mm/tlbex.c
+--- linux-2.6.10/arch/mips/mm/tlbex.c	2004-12-24 22:34:01.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/tlbex.c	2005-01-10 15:22:02.000000000 +0100
+@@ -5,7 +5,7 @@
+  *
+  * Synthesize TLB refill handlers at runtime.
+  *
+- * Copyright (C) 2004 by Thiemo Seufer
++ * Copyright (C) 2004,2005 by Thiemo Seufer
+  */
+ 
+ #include <stdarg.h>
+@@ -19,11 +19,11 @@
+ 
+ #include <asm/pgtable.h>
+ #include <asm/cacheflush.h>
+-#include <asm/cacheflush.h>
+ #include <asm/mmu_context.h>
+ #include <asm/inst.h>
+ #include <asm/elf.h>
+ #include <asm/smp.h>
++#include <asm/war.h>
+ 
+ /* #define DEBUG_TLB */
+ 
+@@ -44,6 +44,11 @@ static __init int __attribute__((unused)
+ 	return BCM1250_M3_WAR;
+ }
+ 
++static __init int __attribute__((unused)) r10000_llsc_war(void)
++{
++	return R10000_LLSC_WAR;
++}
++
+ /*
+  * A little micro-assembler, intended for TLB refill handler
+  * synthesizing. It is intentionally kept simple, does only support
+@@ -84,13 +89,14 @@ enum fields
+ enum opcode {
+ 	insn_invalid,
+ 	insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
+-	insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, insn_bne,
+-	insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
++	insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
++	insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0,
+ 	insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32,
+ 	insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld,
+-	insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_ori, insn_rfe,
+-	insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw,
+-	insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori
++	insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0,
++	insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
++	insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi,
++	insn_tlbwr, insn_xor, insn_xori
+ };
+ 
+ struct insn {
+@@ -114,6 +120,7 @@ static __initdata struct insn insn_table
+ 	{ insn_and, M(spec_op,0,0,0,0,and_op), RS | RT | RD },
+ 	{ insn_andi, M(andi_op,0,0,0,0,0), RS | RT | UIMM },
+ 	{ insn_beq, M(beq_op,0,0,0,0,0), RS | RT | BIMM },
++	{ insn_beql, M(beql_op,0,0,0,0,0), RS | RT | BIMM },
+ 	{ insn_bgez, M(bcond_op,0,bgez_op,0,0,0), RS | BIMM },
+ 	{ insn_bgezl, M(bcond_op,0,bgezl_op,0,0,0), RS | BIMM },
+ 	{ insn_bltz, M(bcond_op,0,bltz_op,0,0,0), RS | BIMM },
+@@ -134,12 +141,16 @@ static __initdata struct insn insn_table
+ 	{ insn_jal, M(jal_op,0,0,0,0,0), JIMM },
+ 	{ insn_jr, M(spec_op,0,0,0,0,jr_op), RS },
+ 	{ insn_ld, M(ld_op,0,0,0,0,0), RS | RT | SIMM },
++	{ insn_ll, M(ll_op,0,0,0,0,0), RS | RT | SIMM },
++	{ insn_lld, M(lld_op,0,0,0,0,0), RS | RT | SIMM },
+ 	{ insn_lui, M(lui_op,0,0,0,0,0), RT | SIMM },
+ 	{ insn_lw, M(lw_op,0,0,0,0,0), RS | RT | SIMM },
+ 	{ insn_mfc0, M(cop0_op,mfc_op,0,0,0,0), RT | RD },
+ 	{ insn_mtc0, M(cop0_op,mtc_op,0,0,0,0), RT | RD },
+ 	{ insn_ori, M(ori_op,0,0,0,0,0), RS | RT | UIMM },
+ 	{ insn_rfe, M(cop0_op,cop_op,0,0,0,rfe_op), 0 },
++	{ insn_sc, M(sc_op,0,0,0,0,0), RS | RT | SIMM },
++	{ insn_scd, M(scd_op,0,0,0,0,0), RS | RT | SIMM },
+ 	{ insn_sd, M(sd_op,0,0,0,0,0), RS | RT | SIMM },
+ 	{ insn_sll, M(spec_op,0,0,0,0,sll_op), RT | RD | RE },
+ 	{ insn_sra, M(spec_op,0,0,0,0,sra_op), RT | RD | RE },
+@@ -341,6 +352,7 @@ I_u3u1u2(_addu);
+ I_u2u1u3(_andi);
+ I_u3u1u2(_and);
+ I_u1u2s3(_beq);
++I_u1u2s3(_beql);
+ I_u1s2(_bgez);
+ I_u1s2(_bgezl);
+ I_u1s2(_bltz);
+@@ -361,12 +373,16 @@ I_u1(_j);
+ I_u1(_jal);
+ I_u1(_jr);
+ I_u2s3u1(_ld);
++I_u2s3u1(_ll);
++I_u2s3u1(_lld);
+ I_u1s2(_lui);
+ I_u2s3u1(_lw);
+ I_u1u2(_mfc0);
+ I_u1u2(_mtc0);
+ I_u2u1u3(_ori);
+ I_0(_rfe);
++I_u2s3u1(_sc);
++I_u2s3u1(_scd);
+ I_u2s3u1(_sd);
+ I_u2u1u3(_sll);
+ I_u2u1u3(_sra);
+@@ -389,8 +405,14 @@ enum label_id {
+ 	label_leave,
+ 	label_vmalloc,
+ 	label_vmalloc_done,
+-	label_tlbwr_hazard,
+-	label_split
++	label_tlbw_hazard,
++	label_split,
++	label_nopage_tlbl,
++	label_nopage_tlbs,
++	label_nopage_tlbm,
++	label_smp_pgtable_change,
++	label_r3000_write_probe_fail,
++	label_r3000_write_probe_ok
+ };
+ 
+ struct label {
+@@ -416,8 +438,14 @@ L_LA(_second_part)
+ L_LA(_leave)
+ L_LA(_vmalloc)
+ L_LA(_vmalloc_done)
+-L_LA(_tlbwr_hazard)
++L_LA(_tlbw_hazard)
+ L_LA(_split)
++L_LA(_nopage_tlbl)
++L_LA(_nopage_tlbs)
++L_LA(_nopage_tlbm)
++L_LA(_smp_pgtable_change)
++L_LA(_r3000_write_probe_fail)
++L_LA(_r3000_write_probe_ok)
+ 
+ /* convenience macros for instructions */
+ #ifdef CONFIG_MIPS64
+@@ -431,6 +459,8 @@ L_LA(_split)
+ # define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val)
+ # define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd)
+ # define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd)
++# define i_LL(buf, rs, rt, off) i_lld(buf, rs, rt, off)
++# define i_SC(buf, rs, rt, off) i_scd(buf, rs, rt, off)
+ #else
+ # define i_LW(buf, rs, rt, off) i_lw(buf, rs, rt, off)
+ # define i_SW(buf, rs, rt, off) i_sw(buf, rs, rt, off)
+@@ -442,28 +472,33 @@ L_LA(_split)
+ # define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val)
+ # define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd)
+ # define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd)
++# define i_LL(buf, rs, rt, off) i_ll(buf, rs, rt, off)
++# define i_SC(buf, rs, rt, off) i_sc(buf, rs, rt, off)
+ #endif
+ 
+ #define i_b(buf, off) i_beq(buf, 0, 0, off)
++#define i_beqz(buf, rs, off) i_beq(buf, rs, 0, off)
++#define i_beqzl(buf, rs, off) i_beql(buf, rs, 0, off)
+ #define i_bnez(buf, rs, off) i_bne(buf, rs, 0, off)
++#define i_bnezl(buf, rs, off) i_bnel(buf, rs, 0, off)
+ #define i_move(buf, a, b) i_ADDU(buf, a, 0, b)
+ #define i_nop(buf) i_sll(buf, 0, 0, 0)
+ #define i_ssnop(buf) i_sll(buf, 0, 0, 1)
+ #define i_ehb(buf) i_sll(buf, 0, 0, 3)
+ 
+-#if CONFIG_MIPS64
+-static __init int in_compat_space_p(long addr)
++#ifdef CONFIG_MIPS64
++static __init int __attribute__((unused)) in_compat_space_p(long addr)
+ {
+ 	/* Is this address in 32bit compat space? */
+ 	return (((addr) & 0xffffffff00000000) == 0xffffffff00000000);
+ }
+ 
+-static __init int rel_highest(long val)
++static __init int __attribute__((unused)) rel_highest(long val)
+ {
+ 	return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000;
+ }
+ 
+-static __init int rel_higher(long val)
++static __init int __attribute__((unused)) rel_higher(long val)
+ {
+ 	return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000;
+ }
+@@ -550,22 +585,33 @@ static __init void resolve_relocs(struct
+ 				__resolve_relocs(rel, l);
+ }
+ 
+-static __init void copy_handler(struct reloc *rel, struct label *lab,
+-				u32 *first, u32 *end, u32* target)
++static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end,
++			       long off)
+ {
+-	long off = (long)(target - first);
+-
+-	memcpy(target, first, (end - first) * sizeof(u32));
+-
+ 	for (; rel->lab != label_invalid; rel++)
+ 		if (rel->addr >= first && rel->addr < end)
+ 			rel->addr += off;
++}
+ 
++static __init void move_labels(struct label *lab, u32 *first, u32 *end,
++			       long off)
++{
+ 	for (; lab->lab != label_invalid; lab++)
+ 		if (lab->addr >= first && lab->addr < end)
+ 			lab->addr += off;
+ }
+ 
++static __init void copy_handler(struct reloc *rel, struct label *lab,
++				u32 *first, u32 *end, u32 *target)
++{
++	long off = (long)(target - first);
++
++	memcpy(target, first, (end - first) * sizeof(u32));
++
++	move_relocs(rel, first, end, off);
++	move_labels(lab, first, end, off);
++}
++
+ static __init int __attribute__((unused)) insn_has_bdelay(struct reloc *rel,
+ 							  u32 *addr)
+ {
+@@ -594,6 +640,20 @@ static void __attribute__((unused)) il_b
+ 	i_b(p, 0);
+ }
+ 
++static void il_beqz(u32 **p, struct reloc **r, unsigned int reg,
++		    enum label_id l)
++{
++	r_mips_pc16(r, *p, l);
++	i_beqz(p, reg, 0);
++}
++
++static void __attribute__((unused))
++il_beqzl(u32 **p, struct reloc **r, unsigned int reg, enum label_id l)
++{
++	r_mips_pc16(r, *p, l);
++	i_beqzl(p, reg, 0);
++}
++
+ static void il_bnez(u32 **p, struct reloc **r, unsigned int reg,
+ 		    enum label_id l)
+ {
+@@ -608,7 +668,7 @@ static void il_bgezl(u32 **p, struct rel
+ 	i_bgezl(p, reg, 0);
+ }
+ 
+-/* The only registers allowed in TLB handlers. */
++/* The only general purpose registers allowed in TLB handlers. */
+ #define K0		26
+ #define K1		27
+ 
+@@ -642,7 +702,6 @@ static __initdata u32 tlb_handler[128];
+ static __initdata struct label labels[128];
+ static __initdata struct reloc relocs[128];
+ 
+-#ifdef CONFIG_MIPS32
+ /*
+  * The R3000 TLB handler is simple.
+  */
+@@ -676,10 +735,11 @@ static void __init build_r3000_tlb_refil
+ 		panic("TLB refill handler space exceeded");
+ 
+ 	printk("Synthesized TLB handler (%u instructions).\n",
+-	       p - tlb_handler);
++	       (unsigned int)(p - tlb_handler));
+ #ifdef DEBUG_TLB
+ 	{
+ 		int i;
++
+ 		for (i = 0; i < (p - tlb_handler); i++)
+ 			printk("%08x\n", tlb_handler[i]);
+ 	}
+@@ -688,7 +748,6 @@ static void __init build_r3000_tlb_refil
+ 	memcpy((void *)CAC_BASE, tlb_handler, 0x80);
+ 	flush_icache_range(CAC_BASE, CAC_BASE + 0x80);
+ }
+-#endif /* CONFIG_MIPS32 */
+ 
+ /*
+  * The R4000 TLB handler is much more complicated. We have two
+@@ -738,12 +797,22 @@ static __init void __attribute__((unused
+ }
+ 
+ /*
+- * Write random TLB entry, and care about the hazards from the
+- * preceeding mtc0 and for the following eret.
++ * Write random or indexed TLB entry, and care about the hazards from
++ * the preceeding mtc0 and for the following eret.
+  */
+-static __init void build_tlb_write_random_entry(u32 **p, struct label **l,
+-						struct reloc **r)
++enum tlb_write_entry { tlb_random, tlb_indexed };
++
++static __init void build_tlb_write_entry(u32 **p, struct label **l,
++					 struct reloc **r,
++					 enum tlb_write_entry wmode)
+ {
++	void(*tlbw)(u32 **) = NULL;
++
++	switch (wmode) {
++	case tlb_random: tlbw = i_tlbwr; break;
++	case tlb_indexed: tlbw = i_tlbwi; break;
++	}
++
+ 	switch (current_cpu_data.cputype) {
+ 	case CPU_R4000PC:
+ 	case CPU_R4000SC:
+@@ -753,11 +822,11 @@ static __init void build_tlb_write_rando
+ 	case CPU_R4400MC:
+ 		/*
+ 		 * This branch uses up a mtc0 hazard nop slot and saves
+-		 * two nops after the tlbwr.
++		 * two nops after the tlbw instruction.
+ 		 */
+-		il_bgezl(p, r, 0, label_tlbwr_hazard);
+-		i_tlbwr(p);
+-		l_tlbwr_hazard(l, *p);
++		il_bgezl(p, r, 0, label_tlbw_hazard);
++		tlbw(p);
++		l_tlbw_hazard(l, *p);
+ 		i_nop(p);
+ 		break;
+ 
+@@ -766,12 +835,13 @@ static __init void build_tlb_write_rando
+ 	case CPU_R5000:
+ 	case CPU_R5000A:
+ 	case CPU_5KC:
++	case CPU_TX49XX:
+ 	case CPU_AU1000:
+ 	case CPU_AU1100:
+ 	case CPU_AU1500:
+ 	case CPU_AU1550:
+ 		i_nop(p);
+-		i_tlbwr(p);
++		tlbw(p);
+ 		break;
+ 
+ 	case CPU_R10000:
+@@ -781,24 +851,32 @@ static __init void build_tlb_write_rando
+ 	case CPU_4KSC:
+ 	case CPU_20KC:
+ 	case CPU_25KF:
+-		i_tlbwr(p);
++		tlbw(p);
+ 		break;
+ 
+ 	case CPU_NEVADA:
+ 		i_nop(p); /* QED specifies 2 nops hazard */
+ 		/*
+ 		 * This branch uses up a mtc0 hazard nop slot and saves
+-		 * a nop after the tlbwr.
++		 * a nop after the tlbw instruction.
+ 		 */
+-		il_bgezl(p, r, 0, label_tlbwr_hazard);
+-		i_tlbwr(p);
+-		l_tlbwr_hazard(l, *p);
++		il_bgezl(p, r, 0, label_tlbw_hazard);
++		tlbw(p);
++		l_tlbw_hazard(l, *p);
++		break;
++
++	case CPU_RM7000:
++		i_nop(p);
++		i_nop(p);
++		i_nop(p);
++		i_nop(p);
++		tlbw(p);
+ 		break;
+ 
+ 	case CPU_4KEC:
+ 	case CPU_24K:
+ 		i_ehb(p);
+-		i_tlbwr(p);
++		tlbw(p);
+ 		break;
+ 
+ 	case CPU_RM9000:
+@@ -812,13 +890,32 @@ static __init void build_tlb_write_rando
+ 		i_ssnop(p);
+ 		i_ssnop(p);
+ 		i_ssnop(p);
+-		i_tlbwr(p);
++		tlbw(p);
+ 		i_ssnop(p);
+ 		i_ssnop(p);
+ 		i_ssnop(p);
+ 		i_ssnop(p);
+ 		break;
+ 
++	case CPU_VR4111:
++	case CPU_VR4121:
++	case CPU_VR4122:
++	case CPU_VR4181:
++	case CPU_VR4181A:
++		i_nop(p);
++		i_nop(p);
++		tlbw(p);
++		i_nop(p);
++		i_nop(p);
++		break;
++
++	case CPU_VR4131:
++	case CPU_VR4133:
++		i_nop(p);
++		i_nop(p);
++		tlbw(p);
++		break;
++
+ 	default:
+ 		panic("No TLB refill handler yet (CPU type: %d)",
+ 		      current_cpu_data.cputype);
+@@ -826,7 +923,7 @@ static __init void build_tlb_write_rando
+ 	}
+ }
+ 
+-#if CONFIG_MIPS64
++#ifdef CONFIG_MIPS64
+ /*
+  * TMP and PTR are scratch.
+  * TMP will be clobbered, PTR will hold the pmd entry.
+@@ -844,7 +941,7 @@ build_get_pmde64(u32 **p, struct label *
+ 	il_bltz(p, r, tmp, label_vmalloc);
+ 	/* No i_nop needed here, since the next insn doesn't touch TMP. */
+ 
+-# ifdef CONFIG_SMP
++#ifdef CONFIG_SMP
+ 	/*
+ 	 * 64 bit SMP has the lower part of &pgd_current[smp_processor_id()]
+ 	 * stored in CONTEXT.
+@@ -852,7 +949,17 @@ build_get_pmde64(u32 **p, struct label *
+ 	if (in_compat_space_p(pgdc)) {
+ 		i_dmfc0(p, ptr, C0_CONTEXT);
+ 		i_dsra(p, ptr, ptr, 23);
++		i_ld(p, ptr, 0, ptr);
+ 	} else {
++#ifdef CONFIG_BUILD_ELF64
++		i_dmfc0(p, ptr, C0_CONTEXT);
++		i_dsrl(p, ptr, ptr, 23);
++		i_dsll(p, ptr, ptr, 3);
++		i_LA_mostly(p, tmp, pgdc);
++		i_daddu(p, ptr, ptr, tmp);
++		i_dmfc0(p, tmp, C0_BADVADDR);
++		i_ld(p, ptr, rel_lo(pgdc), ptr);
++#else
+ 		i_dmfc0(p, ptr, C0_CONTEXT);
+ 		i_lui(p, tmp, rel_highest(pgdc));
+ 		i_dsll(p, ptr, ptr, 9);
+@@ -860,12 +967,13 @@ build_get_pmde64(u32 **p, struct label *
+ 		i_dsrl32(p, ptr, ptr, 0);
+ 		i_and(p, ptr, ptr, tmp);
+ 		i_dmfc0(p, tmp, C0_BADVADDR);
++		i_ld(p, ptr, 0, ptr);
++#endif
+ 	}
+-	i_ld(p, ptr, 0, ptr);
+-# else
++#else
+ 	i_LA_mostly(p, ptr, pgdc);
+ 	i_ld(p, ptr, rel_lo(pgdc), ptr);
+-# endif
++#endif
+ 
+ 	l_vmalloc_done(l, *p);
+ 	i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */
+@@ -902,13 +1010,14 @@ build_get_pgd_vmalloc64(u32 **p, struct 
+ 	}
+ }
+ 
+-#else /* CONFIG_MIPS32 */
++#else /* !CONFIG_MIPS64 */
+ 
+ /*
+  * TMP and PTR are scratch.
+  * TMP will be clobbered, PTR will hold the pgd entry.
+  */
+-static __init void build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
++static __init void __attribute__((unused))
++build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr)
+ {
+ 	long pgdc = (long)pgd_current;
+ 
+@@ -928,17 +1037,13 @@ static __init void build_get_pgde32(u32 
+ 	i_sll(p, tmp, tmp, PGD_T_LOG2);
+ 	i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
+ }
+-#endif /* CONFIG_MIPS32 */
++
++#endif /* !CONFIG_MIPS64 */
+ 
+ static __init void build_adjust_context(u32 **p, unsigned int ctx)
+ {
+-	unsigned int shift = 0;
+-	unsigned int mask = 0xff0;
+-
+-#if !defined(CONFIG_MIPS64) && !defined(CONFIG_64BIT_PHYS_ADDR)
+-	shift++;
+-	mask |= 0x008;
+-#endif
++	unsigned int shift = 4 - (PTE_T_LOG2 + 1);
++	unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1);
+ 
+ 	switch (current_cpu_data.cputype) {
+ 	case CPU_VR41XX:
+@@ -1049,20 +1154,20 @@ static void __init build_r4000_tlb_refil
+ 		i_MFC0(&p, K0, C0_BADVADDR);
+ 		i_MFC0(&p, K1, C0_ENTRYHI);
+ 		i_xor(&p, K0, K0, K1);
+-		i_SRL(&p, K0, K0, PAGE_SHIFT+1);
++		i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
+ 		il_bnez(&p, &r, K0, label_leave);
+ 		/* No need for i_nop */
+ 	}
+ 
+ #ifdef CONFIG_MIPS64
+-	build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd ptr in K1 */
++	build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
+ #else
+-	build_get_pgde32(&p, K0, K1); /* get pgd ptr in K1 */
++	build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
+ #endif
+ 
+ 	build_get_ptep(&p, K0, K1);
+ 	build_update_entries(&p, K0, K1);
+-	build_tlb_write_random_entry(&p, &l, &r);
++	build_tlb_write_entry(&p, &l, &r, tlb_random);
+ 	l_leave(&l, p);
+ 	i_eret(&p); /* return from trap */
+ 
+@@ -1121,6 +1226,7 @@ static void __init build_r4000_tlb_refil
+ 			i_nop(&f);
+ 		else {
+ 			copy_handler(relocs, labels, split, split + 1, f);
++			move_labels(labels, f, f + 1, -1);
+ 			f++;
+ 			split++;
+ 		}
+@@ -1132,7 +1238,8 @@ static void __init build_r4000_tlb_refil
+ #endif /* CONFIG_MIPS64 */
+ 
+ 	resolve_relocs(relocs, labels);
+-	printk("Synthesized TLB handler (%u instructions).\n", final_len);
++	printk("Synthesized TLB refill handler (%u instructions).\n",
++	       final_len);
+ 
+ #ifdef DEBUG_TLB
+ 	{
+@@ -1147,10 +1254,530 @@ static void __init build_r4000_tlb_refil
+ 	flush_icache_range(CAC_BASE, CAC_BASE + 0x100);
+ }
+ 
++/*
++ * TLB load/store/modify handlers.
++ * 
++ * Only the fastpath gets synthesized at runtime, the slowpath for
++ * do_page_fault remains normal asm.
++ */
++extern void tlb_do_page_fault_0(void);
++extern void tlb_do_page_fault_1(void);
++
++#define __tlb_handler_align \
++	__attribute__((__aligned__(1 << CONFIG_MIPS_L1_CACHE_SHIFT)))
++
++/*
++ * 128 instructions for the fastpath handler is generous and should
++ * never be exceeded.
++ */
++#define FASTPATH_SIZE 128
++
++u32 __tlb_handler_align handle_tlbl[FASTPATH_SIZE];
++u32 __tlb_handler_align handle_tlbs[FASTPATH_SIZE];
++u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE];
++
++static void __init
++iPTE_LW(u32 **p, struct label **l, unsigned int pte, int offset,
++	unsigned int ptr)
++{
++#ifdef CONFIG_SMP
++# ifdef CONFIG_64BIT_PHYS_ADDR
++	if (cpu_has_64bit_gp_regs)
++		i_lld(p, pte, offset, ptr);
++	else
++# endif
++		i_LL(p, pte, offset, ptr);
++#else
++# ifdef CONFIG_64BIT_PHYS_ADDR
++	if (cpu_has_64bit_gp_regs)
++		i_ld(p, pte, offset, ptr);
++	else
++# endif
++		i_LW(p, pte, offset, ptr);
++#endif
++}
++
++static void __init
++iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset,
++	unsigned int ptr)
++{
++#ifdef CONFIG_SMP
++# ifdef CONFIG_64BIT_PHYS_ADDR
++	if (cpu_has_64bit_gp_regs)
++		i_scd(p, pte, offset, ptr);
++	else
++# endif
++		i_SC(p, pte, offset, ptr);
++
++	if (r10000_llsc_war())
++		il_beqzl(p, r, pte, label_smp_pgtable_change);
++	else
++		il_beqz(p, r, pte, label_smp_pgtable_change);
++
++# ifdef CONFIG_64BIT_PHYS_ADDR
++	if (!cpu_has_64bit_gp_regs) {
++		/* no i_nop needed */
++		i_ll(p, pte, sizeof(pte_t) / 2, ptr);
++		i_ori(p, pte, pte, _PAGE_VALID);
++		i_sc(p, pte, sizeof(pte_t) / 2, ptr);
++		il_beqz(p, r, pte, label_smp_pgtable_change);
++		/* no i_nop needed */
++		i_lw(p, pte, 0, ptr);
++	} else
++		i_nop(p);
++# else
++	i_nop(p);
++# endif
++#else
++# ifdef CONFIG_64BIT_PHYS_ADDR
++	if (cpu_has_64bit_gp_regs)
++		i_sd(p, pte, offset, ptr);
++	else
++# endif
++		i_SW(p, pte, offset, ptr);
++
++# ifdef CONFIG_64BIT_PHYS_ADDR
++	if (!cpu_has_64bit_gp_regs) {
++		i_lw(p, pte, sizeof(pte_t) / 2, ptr);
++		i_ori(p, pte, pte, _PAGE_VALID);
++		i_sw(p, pte, sizeof(pte_t) / 2, ptr);
++		i_lw(p, pte, 0, ptr);
++	}
++# endif
++#endif
++}
++
++/*
++ * Check if PTE is present, if not then jump to LABEL. PTR points to
++ * the page table where this PTE is located, PTE will be re-loaded
++ * with it's original value.
++ */
++static void __init
++build_pte_present(u32 **p, struct label **l, struct reloc **r,
++		  unsigned int pte, unsigned int ptr, enum label_id lid)
++{
++	i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
++	i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ);
++	il_bnez(p, r, pte, lid);
++	iPTE_LW(p, l, pte, 0, ptr);
++}
++
++/* Make PTE valid, store result in PTR. */
++static void __init
++build_make_valid(u32 **p, struct reloc **r, unsigned int pte,
++		 unsigned int ptr)
++{
++	i_ori(p, pte, pte, _PAGE_VALID | _PAGE_ACCESSED);
++	iPTE_SW(p, r, pte, 0, ptr);
++}
++
++/*
++ * Check if PTE can be written to, if not branch to LABEL. Regardless
++ * restore PTE with value from PTR when done.
++ */
++static void __init
++build_pte_writable(u32 **p, struct label **l, struct reloc **r,
++		   unsigned int pte, unsigned int ptr, enum label_id lid)
++{
++	i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
++	i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE);
++	il_bnez(p, r, pte, lid);
++	iPTE_LW(p, l, pte, 0, ptr);
++}
++
++/* Make PTE writable, update software status bits as well, then store
++ * at PTR.
++ */
++static void __init
++build_make_write(u32 **p, struct reloc **r, unsigned int pte,
++		 unsigned int ptr)
++{
++	i_ori(p, pte, pte,
++	      _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY);
++	iPTE_SW(p, r, pte, 0, ptr);
++}
++
++/*
++ * Check if PTE can be modified, if not branch to LABEL. Regardless
++ * restore PTE with value from PTR when done.
++ */
++static void __init
++build_pte_modifiable(u32 **p, struct label **l, struct reloc **r,
++		     unsigned int pte, unsigned int ptr, enum label_id lid)
++{
++	i_andi(p, pte, pte, _PAGE_WRITE);
++	il_beqz(p, r, pte, lid);
++	iPTE_LW(p, l, pte, 0, ptr);
++}
++
++/*
++ * R3000 style TLB load/store/modify handlers.
++ */
++
++/* This places the pte in the page table at PTR into ENTRYLO0. */
++static void __init
++build_r3000_pte_reload(u32 **p, unsigned int ptr)
++{
++	i_lw(p, ptr, 0, ptr);
++	i_nop(p); /* load delay */
++	i_mtc0(p, ptr, C0_ENTRYLO0);
++	i_nop(p); /* cp0 delay */
++}
++
++/*
++ * The index register may have the probe fail bit set,
++ * because we would trap on access kseg2, i.e. without refill.
++ */
++static void __init
++build_r3000_tlb_write(u32 **p, struct label **l, struct reloc **r,
++		      unsigned int tmp)
++{
++	i_mfc0(p, tmp, C0_INDEX);
++	i_nop(p); /* cp0 delay */
++	il_bltz(p, r, tmp, label_r3000_write_probe_fail);
++	i_nop(p); /* branch delay */
++	i_tlbwi(p);
++	il_b(p, r, label_r3000_write_probe_ok);
++	i_nop(p); /* branch delay */
++	l_r3000_write_probe_fail(l, *p);
++	i_tlbwr(p);
++	l_r3000_write_probe_ok(l, *p);
++}
++
++static void __init
++build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte,
++				   unsigned int ptr)
++{
++	long pgdc = (long)pgd_current;
++
++	i_mfc0(p, pte, C0_BADVADDR);
++	i_lui(p, ptr, rel_hi(pgdc)); /* cp0 delay */
++	i_lw(p, ptr, rel_lo(pgdc), ptr);
++	i_srl(p, pte, pte, 22); /* load delay */
++	i_sll(p, pte, pte, 2);
++	i_addu(p, ptr, ptr, pte);
++	i_mfc0(p, pte, C0_CONTEXT);
++	i_lw(p, ptr, 0, ptr); /* cp0 delay */
++	i_andi(p, pte, pte, 0xffc); /* load delay */
++	i_addu(p, ptr, ptr, pte);
++	i_lw(p, pte, 0, ptr);
++	i_nop(p); /* load delay */
++	i_tlbp(p);
++}
++
++static void __init
++build_r3000_tlbchange_handler_tail(u32 **p, unsigned int tmp)
++{
++	i_mfc0(p, tmp, C0_EPC);
++	i_nop(p); /* cp0 delay */
++	i_jr(p, tmp);
++	i_rfe(p); /* branch delay */
++}
++
++static void __init build_r3000_tlb_load_handler(void)
++{
++	u32 *p = handle_tlbl;
++	struct label *l = labels;
++	struct reloc *r = relocs;
++
++	memset(handle_tlbl, 0, sizeof(handle_tlbl));
++	memset(labels, 0, sizeof(labels));
++	memset(relocs, 0, sizeof(relocs));
++
++	build_r3000_tlbchange_handler_head(&p, K0, K1);
++	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
++	build_make_valid(&p, &r, K0, K1);
++	build_r3000_pte_reload(&p, K1);
++	build_r3000_tlb_write(&p, &l, &r, K0);
++	build_r3000_tlbchange_handler_tail(&p, K0);
++
++	l_nopage_tlbl(&l, p);
++	i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
++	i_nop(&p);
++
++	if ((p - handle_tlbl) > FASTPATH_SIZE)
++		panic("TLB load handler fastpath space exceeded");
++
++	resolve_relocs(relocs, labels);
++	printk("Synthesized TLB load handler fastpath (%u instructions).\n",
++	       (unsigned int)(p - handle_tlbl));
++
++#ifdef DEBUG_TLB
++	{
++		int i;
++
++		for (i = 0; i < FASTPATH_SIZE; i++)
++			printk("%08x\n", handle_tlbl[i]);
++	}
++#endif
++
++	flush_icache_range((unsigned long)handle_tlbl,
++			   (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
++}
++
++static void __init build_r3000_tlb_store_handler(void)
++{
++	u32 *p = handle_tlbs;
++	struct label *l = labels;
++	struct reloc *r = relocs;
++
++	memset(handle_tlbs, 0, sizeof(handle_tlbs));
++	memset(labels, 0, sizeof(labels));
++	memset(relocs, 0, sizeof(relocs));
++
++	build_r3000_tlbchange_handler_head(&p, K0, K1);
++	build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
++	build_make_write(&p, &r, K0, K1);
++	build_r3000_pte_reload(&p, K1);
++	build_r3000_tlb_write(&p, &l, &r, K0);
++	build_r3000_tlbchange_handler_tail(&p, K0);
++
++	l_nopage_tlbs(&l, p);
++	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
++	i_nop(&p);
++
++	if ((p - handle_tlbs) > FASTPATH_SIZE)
++		panic("TLB store handler fastpath space exceeded");
++
++	resolve_relocs(relocs, labels);
++	printk("Synthesized TLB store handler fastpath (%u instructions).\n",
++	       (unsigned int)(p - handle_tlbs));
++
++#ifdef DEBUG_TLB
++	{
++		int i;
++
++		for (i = 0; i < FASTPATH_SIZE; i++)
++			printk("%08x\n", handle_tlbs[i]);
++	}
++#endif
++
++	flush_icache_range((unsigned long)handle_tlbs,
++			   (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
++}
++
++static void __init build_r3000_tlb_modify_handler(void)
++{
++	u32 *p = handle_tlbm;
++	struct label *l = labels;
++	struct reloc *r = relocs;
++
++	memset(handle_tlbm, 0, sizeof(handle_tlbm));
++	memset(labels, 0, sizeof(labels));
++	memset(relocs, 0, sizeof(relocs));
++
++	build_r3000_tlbchange_handler_head(&p, K0, K1);
++	build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
++	build_make_write(&p, &r, K0, K1);
++	build_r3000_pte_reload(&p, K1);
++	i_tlbwi(&p);
++	build_r3000_tlbchange_handler_tail(&p, K0);
++
++	l_nopage_tlbm(&l, p);
++	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
++	i_nop(&p);
++
++	if ((p - handle_tlbm) > FASTPATH_SIZE)
++		panic("TLB modify handler fastpath space exceeded");
++
++	resolve_relocs(relocs, labels);
++	printk("Synthesized TLB modify handler fastpath (%u instructions).\n",
++	       (unsigned int)(p - handle_tlbm));
++
++#ifdef DEBUG_TLB
++	{
++		int i;
++
++		for (i = 0; i < FASTPATH_SIZE; i++)
++			printk("%08x\n", handle_tlbm[i]);
++	}
++#endif
++
++	flush_icache_range((unsigned long)handle_tlbm,
++			   (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
++}
++
++/*
++ * R4000 style TLB load/store/modify handlers.
++ */
++static void __init
++build_r4000_tlbchange_handler_head(u32 **p, struct label **l,
++				   struct reloc **r, unsigned int pte,
++				   unsigned int ptr)
++{
++#ifdef CONFIG_MIPS64
++	build_get_pmde64(p, l, r, pte, ptr); /* get pmd in ptr */
++#else
++	build_get_pgde32(p, pte, ptr); /* get pgd in ptr */
++#endif
++
++	i_MFC0(p, pte, C0_BADVADDR);
++	i_LW(p, ptr, 0, ptr);
++	i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2);
++	i_andi(p, pte, pte, (PTRS_PER_PTE - 1) << PTE_T_LOG2);
++	i_ADDU(p, ptr, ptr, pte);
++
++#ifdef CONFIG_SMP
++	l_smp_pgtable_change(l, *p);
++# endif
++	iPTE_LW(p, l, pte, 0, ptr); /* get even pte */
++	build_tlb_probe_entry(p);
++}
++
++static void __init
++build_r4000_tlbchange_handler_tail(u32 **p, struct label **l,
++				   struct reloc **r, unsigned int tmp,
++				   unsigned int ptr)
++{
++	i_ori(p, ptr, ptr, sizeof(pte_t));
++	i_xori(p, ptr, ptr, sizeof(pte_t));
++	build_update_entries(p, tmp, ptr);
++	build_tlb_write_entry(p, l, r, tlb_indexed);
++	l_leave(l, *p);
++	i_eret(p); /* return from trap */
++
++#ifdef CONFIG_MIPS64
++	build_get_pgd_vmalloc64(p, l, r, tmp, ptr);
++#endif
++}
++
++static void __init build_r4000_tlb_load_handler(void)
++{
++	u32 *p = handle_tlbl;
++	struct label *l = labels;
++	struct reloc *r = relocs;
++
++	memset(handle_tlbl, 0, sizeof(handle_tlbl));
++	memset(labels, 0, sizeof(labels));
++	memset(relocs, 0, sizeof(relocs));
++
++	if (bcm1250_m3_war()) {
++		i_MFC0(&p, K0, C0_BADVADDR);
++		i_MFC0(&p, K1, C0_ENTRYHI);
++		i_xor(&p, K0, K0, K1);
++		i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
++		il_bnez(&p, &r, K0, label_leave);
++		/* No need for i_nop */
++	}
++
++	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
++	build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl);
++	build_make_valid(&p, &r, K0, K1);
++	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
++
++	l_nopage_tlbl(&l, p);
++	i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff);
++	i_nop(&p);
++
++	if ((p - handle_tlbl) > FASTPATH_SIZE)
++		panic("TLB load handler fastpath space exceeded");
++
++	resolve_relocs(relocs, labels);
++	printk("Synthesized TLB load handler fastpath (%u instructions).\n",
++	       (unsigned int)(p - handle_tlbl));
++
++#ifdef DEBUG_TLB
++	{
++		int i;
++
++		for (i = 0; i < FASTPATH_SIZE; i++)
++			printk("%08x\n", handle_tlbl[i]);
++	}
++#endif
++
++	flush_icache_range((unsigned long)handle_tlbl,
++			   (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32));
++}
++
++static void __init build_r4000_tlb_store_handler(void)
++{
++	u32 *p = handle_tlbs;
++	struct label *l = labels;
++	struct reloc *r = relocs;
++
++	memset(handle_tlbs, 0, sizeof(handle_tlbs));
++	memset(labels, 0, sizeof(labels));
++	memset(relocs, 0, sizeof(relocs));
++
++	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
++	build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs);
++	build_make_write(&p, &r, K0, K1);
++	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
++
++	l_nopage_tlbs(&l, p);
++	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
++	i_nop(&p);
++
++	if ((p - handle_tlbs) > FASTPATH_SIZE)
++		panic("TLB store handler fastpath space exceeded");
++
++	resolve_relocs(relocs, labels);
++	printk("Synthesized TLB store handler fastpath (%u instructions).\n",
++	       (unsigned int)(p - handle_tlbs));
++
++#ifdef DEBUG_TLB
++	{
++		int i;
++
++		for (i = 0; i < FASTPATH_SIZE; i++)
++			printk("%08x\n", handle_tlbs[i]);
++	}
++#endif
++
++	flush_icache_range((unsigned long)handle_tlbs,
++			   (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32));
++}
++
++static void __init build_r4000_tlb_modify_handler(void)
++{
++	u32 *p = handle_tlbm;
++	struct label *l = labels;
++	struct reloc *r = relocs;
++
++	memset(handle_tlbm, 0, sizeof(handle_tlbm));
++	memset(labels, 0, sizeof(labels));
++	memset(relocs, 0, sizeof(relocs));
++
++	build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1);
++	build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm);
++	/* Present and writable bits set, set accessed and dirty bits. */
++	build_make_write(&p, &r, K0, K1);
++	build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1);
++
++	l_nopage_tlbm(&l, p);
++	i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff);
++	i_nop(&p);
++
++	if ((p - handle_tlbm) > FASTPATH_SIZE)
++		panic("TLB modify handler fastpath space exceeded");
++
++	resolve_relocs(relocs, labels);
++	printk("Synthesized TLB modify handler fastpath (%u instructions).\n",
++	       (unsigned int)(p - handle_tlbm));
++
++#ifdef DEBUG_TLB
++	{
++		int i;
++
++		for (i = 0; i < FASTPATH_SIZE; i++)
++			printk("%08x\n", handle_tlbm[i]);
++	}
++#endif
++
++	flush_icache_range((unsigned long)handle_tlbm,
++			   (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32));
++}
++
+ void __init build_tlb_refill_handler(void)
+ {
++	/*
++	 * The refill handler is generated per-CPU, multi-node systems
++	 * may have local storage for it. The other handlers are only
++	 * needed once.
++	 */
++	static int run_once = 0;
++
+ 	switch (current_cpu_data.cputype) {
+-#ifdef CONFIG_MIPS32
+ 	case CPU_R2000:
+ 	case CPU_R3000:
+ 	case CPU_R3000A:
+@@ -1159,13 +1786,18 @@ void __init build_tlb_refill_handler(voi
+ 	case CPU_TX3922:
+ 	case CPU_TX3927:
+ 		build_r3000_tlb_refill_handler();
++		if (!run_once) {
++			build_r3000_tlb_load_handler();
++			build_r3000_tlb_store_handler();
++			build_r3000_tlb_modify_handler();
++			run_once++;
++		}
+ 		break;
+ 
+ 	case CPU_R6000:
+ 	case CPU_R6000A:
+ 		panic("No R6000 TLB refill handler yet");
+ 		break;
+-#endif
+ 
+ 	case CPU_R8000:
+ 		panic("No R8000 TLB refill handler yet");
+@@ -1173,5 +1805,11 @@ void __init build_tlb_refill_handler(voi
+ 
+ 	default:
+ 		build_r4000_tlb_refill_handler();
++		if (!run_once) {
++			build_r4000_tlb_load_handler();
++			build_r4000_tlb_store_handler();
++			build_r4000_tlb_modify_handler();
++			run_once++;
++		}
+ 	}
+ }
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/tlbex32-mips32.S linux-2.6.10-mips/arch/mips/mm/tlbex32-mips32.S
+--- linux-2.6.10/arch/mips/mm/tlbex32-mips32.S	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/tlbex32-mips32.S	1970-01-01 01:00:00.000000000 +0100
+@@ -1,253 +0,0 @@
+-/*
+- * TLB exception handling code for MIPS32 CPUs.
+- *
+- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
+- *
+- * Multi-cpu abstraction and reworking:
+- * Copyright (C) 1996 David S. Miller (dm at engr.sgi.com)
+- *
+- * Carsten Langgaard, carstenl at mips.com
+- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+- *
+- * Pete Popov, ppopov at pacbell.net
+- * Added 36 bit phys address support.
+- * Copyright (C) 2002 MontaVista Software, Inc.
+- */
+-#include <linux/init.h>
+-#include <asm/asm.h>
+-#include <asm/cachectl.h>
+-#include <asm/fpregdef.h>
+-#include <asm/mipsregs.h>
+-#include <asm/page.h>
+-#include <asm/pgtable-bits.h>
+-#include <asm/regdef.h>
+-#include <asm/stackframe.h>
+-
+-#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
+-
+-#ifdef CONFIG_64BIT_PHYS_ADDR
+-
+-/* We really only support 36 bit physical addresses on MIPS32 */
+-#define PTE_L		lw
+-#define PTE_S		sw
+-#define PTE_SRL		srl
+-#define P_MTC0		mtc0
+-#define PTE_HALF        4 /* pte_high contains pre-shifted, ready to go entry */
+-#define PTE_SIZE        8
+-#define PTEP_INDX_MSK	0xff0
+-#define PTE_INDX_MSK	0xff8
+-#define PTE_INDX_SHIFT 9
+-#define CONVERT_PTE(pte)
+-#define PTE_MAKEWRITE_HIGH(pte, ptr) \
+-	lw	pte, PTE_HALF(ptr); \
+-	ori	pte, (_PAGE_VALID | _PAGE_DIRTY); \
+-	sw	pte, PTE_HALF(ptr); \
+-	lw	pte, 0(ptr);
+-
+-#define PTE_MAKEVALID_HIGH(pte, ptr) \
+-	lw	pte, PTE_HALF(ptr); \
+-	ori	pte, pte, _PAGE_VALID; \
+-	sw	pte, PTE_HALF(ptr); \
+-	lw	pte, 0(ptr);
+-
+-#else
+-
+-#define PTE_L		lw
+-#define PTE_S		sw
+-#define PTE_SRL		srl
+-#define P_MTC0		mtc0
+-#define PTE_HALF        0
+-#define PTE_SIZE	4
+-#define PTEP_INDX_MSK	0xff8
+-#define PTE_INDX_MSK	0xffc
+-#define PTE_INDX_SHIFT	10
+-#define CONVERT_PTE(pte) srl pte, pte, 6
+-#define PTE_MAKEWRITE_HIGH(pte, ptr)
+-#define PTE_MAKEVALID_HIGH(pte, ptr)
+-
+-#endif  /* CONFIG_64BIT_PHYS_ADDR */
+-
+-#ifdef CONFIG_64BIT_PHYS_ADDR
+-#define GET_PTE_OFF(reg)
+-#else
+-#define GET_PTE_OFF(reg)	srl	reg, reg, 1
+-#endif
+-
+-/*
+- * ABUSE of CPP macros 101.
+- *
+- * After this macro runs, the pte faulted on is
+- * in register PTE, a ptr into the table in which
+- * the pte belongs is in PTR.
+- */
+-
+-#ifdef CONFIG_SMP
+-#define GET_PGD(scratch, ptr)        \
+-	mfc0    ptr, CP0_CONTEXT;    \
+-	la      scratch, pgd_current;\
+-	srl     ptr, 23;             \
+-	sll     ptr, 2;              \
+-	addu    ptr, scratch, ptr;   \
+-	lw      ptr, (ptr);
+-#else
+-#define GET_PGD(scratch, ptr)    \
+-	lw	ptr, pgd_current;
+-#endif
+-
+-#define LOAD_PTE(pte, ptr) \
+-	GET_PGD(pte, ptr)          \
+-	mfc0	pte, CP0_BADVADDR; \
+-	srl	pte, pte, _PGDIR_SHIFT; \
+-	sll	pte, pte, 2; \
+-	addu	ptr, ptr, pte; \
+-	mfc0	pte, CP0_BADVADDR; \
+-	lw	ptr, (ptr); \
+-	srl	pte, pte, PTE_INDX_SHIFT; \
+-	and	pte, pte, PTE_INDX_MSK; \
+-	addu	ptr, ptr, pte; \
+-	PTE_L	pte, (ptr);
+-
+-	/* This places the even/odd pte pair in the page
+-	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
+-	 * TMP as a scratch register.
+-	 */
+-#define PTE_RELOAD(ptr, tmp) \
+-	ori	ptr, ptr, PTE_SIZE; \
+-	xori	ptr, ptr, PTE_SIZE; \
+-	PTE_L	tmp, (PTE_HALF+PTE_SIZE)(ptr); \
+-	CONVERT_PTE(tmp); \
+-	P_MTC0	tmp, CP0_ENTRYLO1; \
+-	PTE_L	ptr, PTE_HALF(ptr); \
+-	CONVERT_PTE(ptr); \
+-	P_MTC0	ptr, CP0_ENTRYLO0;
+-
+-#define DO_FAULT(write) \
+-	.set	noat; \
+-	SAVE_ALL; \
+-	mfc0	a2, CP0_BADVADDR; \
+-	KMODE; \
+-	.set	at; \
+-	move	a0, sp; \
+-	jal	do_page_fault; \
+-	 li	a1, write; \
+-	j	ret_from_exception; \
+-	 nop; \
+-	.set	noat;
+-
+-	/* Check is PTE is present, if not then jump to LABEL.
+-	 * PTR points to the page table where this PTE is located,
+-	 * when the macro is done executing PTE will be restored
+-	 * with it's original value.
+-	 */
+-#define PTE_PRESENT(pte, ptr, label) \
+-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+-	bnez	pte, label; \
+-	PTE_L	pte, (ptr);
+-
+-	/* Make PTE valid, store result in PTR. */
+-#define PTE_MAKEVALID(pte, ptr) \
+-	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
+-	PTE_S	pte, (ptr);
+-
+-	/* Check if PTE can be written to, if not branch to LABEL.
+-	 * Regardless restore PTE with value from PTR when done.
+-	 */
+-#define PTE_WRITABLE(pte, ptr, label) \
+-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+-	bnez	pte, label; \
+-	PTE_L	pte, (ptr);
+-
+-	/* Make PTE writable, update software status bits as well,
+-	 * then store at PTR.
+-	 */
+-#define PTE_MAKEWRITE(pte, ptr) \
+-	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
+-			   _PAGE_VALID | _PAGE_DIRTY); \
+-	PTE_S	pte, (ptr);
+-
+-	.set	noreorder
+-
+-	.align	5
+-	NESTED(handle_tlbl, PT_SIZE, sp)
+-	.set	noat
+-invalid_tlbl:
+-#ifdef TLB_OPTIMIZE
+-	/* Test present bit in entry. */
+-	LOAD_PTE(k0, k1)
+-	tlbp
+-	PTE_PRESENT(k0, k1, nopage_tlbl)
+-	PTE_MAKEVALID_HIGH(k0, k1)
+-	PTE_MAKEVALID(k0, k1)
+-	PTE_RELOAD(k1, k0)
+-	nop
+-	b	1f
+-	 tlbwi
+-1:
+-	nop
+-	.set	mips3
+-	eret
+-	.set	mips0
+-#endif
+-
+-nopage_tlbl:
+-	DO_FAULT(0)
+-	END(handle_tlbl)
+-
+-	.align	5
+-	NESTED(handle_tlbs, PT_SIZE, sp)
+-	.set	noat
+-#ifdef TLB_OPTIMIZE
+-	.set	mips3
+-        li      k0,0
+-	LOAD_PTE(k0, k1)
+-	tlbp				# find faulting entry
+-	PTE_WRITABLE(k0, k1, nopage_tlbs)
+-	PTE_MAKEWRITE(k0, k1)
+-	PTE_MAKEWRITE_HIGH(k0, k1)
+-	PTE_RELOAD(k1, k0)
+-	nop
+-	b	1f
+-	 tlbwi
+-1:
+-	nop
+-	.set	mips3
+-	eret
+-	.set	mips0
+-#endif
+-
+-nopage_tlbs:
+-	DO_FAULT(1)
+-	END(handle_tlbs)
+-
+-	.align	5
+-	NESTED(handle_mod, PT_SIZE, sp)
+-	.set	noat
+-#ifdef TLB_OPTIMIZE
+-	.set	mips3
+-	LOAD_PTE(k0, k1)
+-	tlbp					# find faulting entry
+-	andi	k0, k0, _PAGE_WRITE
+-	beqz	k0, nowrite_mod
+-	PTE_L	k0, (k1)
+-
+-	/* Present and writable bits set, set accessed and dirty bits. */
+-	PTE_MAKEWRITE(k0, k1)
+-	PTE_MAKEWRITE_HIGH(k0, k1)
+-	/* Now reload the entry into the tlb. */
+-	PTE_RELOAD(k1, k0)
+-	nop
+-	b	1f
+-	 tlbwi
+-1:
+-	nop
+-	.set	mips3
+-	eret
+-	.set	mips0
+-#endif
+-
+-nowrite_mod:
+-	DO_FAULT(1)
+-	END(handle_mod)
+-
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/tlbex32-r3k.S linux-2.6.10-mips/arch/mips/mm/tlbex32-r3k.S
+--- linux-2.6.10/arch/mips/mm/tlbex32-r3k.S	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/tlbex32-r3k.S	1970-01-01 01:00:00.000000000 +0100
+@@ -1,194 +0,0 @@
+-/*
+- * TLB exception handling code for R2000/R3000.
+- *
+- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
+- *
+- * Multi-CPU abstraction reworking:
+- * Copyright (C) 1996 David S. Miller (dm at engr.sgi.com)
+- *
+- * Further modifications to make this work:
+- * Copyright (c) 1998 Harald Koerfgen
+- * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov
+- * Copyright (c) 2001 Ralf Baechle
+- * Copyright (c) 2001 MIPS Technologies, Inc.
+- */
+-#include <linux/init.h>
+-#include <asm/asm.h>
+-#include <asm/cachectl.h>
+-#include <asm/fpregdef.h>
+-#include <asm/mipsregs.h>
+-#include <asm/page.h>
+-#include <asm/pgtable-bits.h>
+-#include <asm/regdef.h>
+-#include <asm/stackframe.h>
+-
+-#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
+-
+-	/* ABUSE of CPP macros 101. */
+-
+-	/* After this macro runs, the pte faulted on is
+-	 * in register PTE, a ptr into the table in which
+-	 * the pte belongs is in PTR.
+-	 */
+-#define LOAD_PTE(pte, ptr) \
+-	mfc0	pte, CP0_BADVADDR; \
+-	lw	ptr, pgd_current; \
+-	srl	pte, pte, 22; \
+-	sll	pte, pte, 2; \
+-	addu	ptr, ptr, pte; \
+-	mfc0	pte, CP0_CONTEXT; \
+-	lw	ptr, (ptr); \
+-	andi	pte, pte, 0xffc; \
+-	addu	ptr, ptr, pte; \
+-	lw	pte, (ptr); \
+-	nop;
+-
+-	/* This places the even/odd pte pair in the page
+-	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
+-	 * TMP as a scratch register.
+-	 */
+-#define PTE_RELOAD(ptr) \
+-	lw	ptr, (ptr)	; \
+-	nop			; \
+-	mtc0	ptr, CP0_ENTRYLO0; \
+-	nop;
+-
+-#define DO_FAULT(write) \
+-	.set	noat; \
+-	.set	macro; \
+-	SAVE_ALL; \
+-	mfc0	a2, CP0_BADVADDR; \
+-	KMODE; \
+-	.set	at; \
+-	move	a0, sp; \
+-	jal	do_page_fault; \
+-	 li	a1, write; \
+-	j	ret_from_exception; \
+-	 nop; \
+-	.set	noat; \
+-	.set	nomacro;
+-
+-	/* Check is PTE is present, if not then jump to LABEL.
+-	 * PTR points to the page table where this PTE is located,
+-	 * when the macro is done executing PTE will be restored
+-	 * with it's original value.
+-	 */
+-#define PTE_PRESENT(pte, ptr, label) \
+-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+-	bnez	pte, label; \
+-	.set	push;       \
+-	.set	reorder;    \
+-	 lw	pte, (ptr); \
+-	.set	pop;
+-
+-	/* Make PTE valid, store result in PTR. */
+-#define PTE_MAKEVALID(pte, ptr) \
+-	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
+-	sw	pte, (ptr);
+-
+-	/* Check if PTE can be written to, if not branch to LABEL.
+-	 * Regardless restore PTE with value from PTR when done.
+-	 */
+-#define PTE_WRITABLE(pte, ptr, label) \
+-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+-	bnez	pte, label; \
+-	.set    push;       \
+-	.set    reorder;    \
+-	lw      pte, (ptr); \
+-	.set    pop;
+-
+-
+-	/* Make PTE writable, update software status bits as well,
+-	 * then store at PTR.
+-	 */
+-#define PTE_MAKEWRITE(pte, ptr) \
+-	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
+-			   _PAGE_VALID | _PAGE_DIRTY); \
+-	sw	pte, (ptr);
+-
+-/*
+- * The index register may have the probe fail bit set,
+- * because we would trap on access kseg2, i.e. without refill.
+- */
+-#define TLB_WRITE(reg) \
+-	mfc0	reg, CP0_INDEX; \
+-	nop; \
+-	bltz    reg, 1f; \
+-	 nop; \
+-	tlbwi; \
+-	j	2f; \
+-	 nop; \
+-1:	tlbwr; \
+-2:
+-
+-#define RET(reg) \
+-	mfc0	reg, CP0_EPC; \
+-	nop; \
+-	jr	reg; \
+-	 rfe
+-
+-	.set	noreorder
+-
+-	.align	5
+-NESTED(handle_tlbl, PT_SIZE, sp)
+-	.set	noat
+-
+-#ifdef TLB_OPTIMIZE
+-	/* Test present bit in entry. */
+-	LOAD_PTE(k0, k1)
+-        tlbp
+-        PTE_PRESENT(k0, k1, nopage_tlbl)
+-        PTE_MAKEVALID(k0, k1)
+-        PTE_RELOAD(k1)
+-	TLB_WRITE(k0)
+-	RET(k0)
+-nopage_tlbl:
+-#endif
+-
+-	DO_FAULT(0)
+-END(handle_tlbl)
+-
+-NESTED(handle_tlbs, PT_SIZE, sp)
+-	.set	noat
+-
+-#ifdef TLB_OPTIMIZE
+-	LOAD_PTE(k0, k1)
+-	tlbp                            # find faulting entry
+-	PTE_WRITABLE(k0, k1, nopage_tlbs)
+-	PTE_MAKEWRITE(k0, k1)
+-	PTE_RELOAD(k1)
+-	TLB_WRITE(k0)
+-	RET(k0)
+-nopage_tlbs:
+-#endif
+-
+-	DO_FAULT(1)
+-END(handle_tlbs)
+-
+-	.align	5
+-NESTED(handle_mod, PT_SIZE, sp)
+-	.set	noat
+-#ifdef TLB_OPTIMIZE
+-	LOAD_PTE(k0, k1)
+-	tlbp					# find faulting entry
+-	andi	k0, k0, _PAGE_WRITE
+-	beqz	k0, nowrite_mod
+-	.set	push
+-	.set    reorder
+-	lw	k0, (k1)
+-	.set    pop
+-
+-	/* Present and writable bits set, set accessed and dirty bits. */
+-	PTE_MAKEWRITE(k0, k1)
+-
+-	/* Now reload the entry into the tlb. */
+-	PTE_RELOAD(k1)
+-	tlbwi
+-	RET(k0)
+-#endif
+-
+-nowrite_mod:
+-	DO_FAULT(1)
+-END(handle_mod)
+diff -urpNX dontdiff linux-2.6.10/arch/mips/mm/tlbex32-r4k.S linux-2.6.10-mips/arch/mips/mm/tlbex32-r4k.S
+--- linux-2.6.10/arch/mips/mm/tlbex32-r4k.S	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/mm/tlbex32-r4k.S	1970-01-01 01:00:00.000000000 +0100
+@@ -1,262 +0,0 @@
+-/*
+- * TLB exception handling code for r4k.
+- *
+- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
+- *
+- * Multi-cpu abstraction and reworking:
+- * Copyright (C) 1996 David S. Miller (dm at engr.sgi.com)
+- *
+- * Carsten Langgaard, carstenl at mips.com
+- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+- */
+-#include <linux/init.h>
+-#include <linux/config.h>
+-
+-#include <asm/asm.h>
+-#include <asm/offset.h>
+-#include <asm/cachectl.h>
+-#include <asm/fpregdef.h>
+-#include <asm/mipsregs.h>
+-#include <asm/page.h>
+-#include <asm/pgtable-bits.h>
+-#include <asm/regdef.h>
+-#include <asm/stackframe.h>
+-#include <asm/war.h>
+-
+-#define TLB_OPTIMIZE /* If you are paranoid, disable this. */
+-
+-#ifdef CONFIG_64BIT_PHYS_ADDR
+-#define PTE_L		ld
+-#define PTE_S		sd
+-#define PTE_SRL		dsrl
+-#define P_MTC0		dmtc0
+-#define PTE_SIZE	8
+-#define PTEP_INDX_MSK	0xff0
+-#define PTE_INDX_MSK	0xff8
+-#define PTE_INDX_SHIFT	9
+-#else
+-#define PTE_L		lw
+-#define PTE_S		sw
+-#define PTE_SRL		srl
+-#define P_MTC0		mtc0
+-#define PTE_SIZE	4
+-#define PTEP_INDX_MSK	0xff8
+-#define PTE_INDX_MSK	0xffc
+-#define PTE_INDX_SHIFT	10
+-#endif
+-
+-/*
+- * ABUSE of CPP macros 101.
+- *
+- * After this macro runs, the pte faulted on is
+- * in register PTE, a ptr into the table in which
+- * the pte belongs is in PTR.
+- */
+-
+-#ifdef CONFIG_SMP
+-#define GET_PGD(scratch, ptr)        \
+-	mfc0    ptr, CP0_CONTEXT;    \
+-	la      scratch, pgd_current;\
+-	srl     ptr, 23;             \
+-	sll     ptr, 2;              \
+-	addu    ptr, scratch, ptr;   \
+-	lw      ptr, (ptr);
+-#else
+-#define GET_PGD(scratch, ptr)    \
+-	lw	ptr, pgd_current;
+-#endif
+-
+-#define LOAD_PTE(pte, ptr) \
+-	GET_PGD(pte, ptr)          \
+-	mfc0	pte, CP0_BADVADDR; \
+-	srl	pte, pte, _PGDIR_SHIFT; \
+-	sll	pte, pte, 2; \
+-	addu	ptr, ptr, pte; \
+-	mfc0	pte, CP0_BADVADDR; \
+-	lw	ptr, (ptr); \
+-	srl	pte, pte, PTE_INDX_SHIFT; \
+-	and	pte, pte, PTE_INDX_MSK; \
+-	addu	ptr, ptr, pte; \
+-	PTE_L	pte, (ptr);
+-
+-	/* This places the even/odd pte pair in the page
+-	 * table at PTR into ENTRYLO0 and ENTRYLO1 using
+-	 * TMP as a scratch register.
+-	 */
+-#define PTE_RELOAD(ptr, tmp) \
+-	ori	ptr, ptr, PTE_SIZE; \
+-	xori	ptr, ptr, PTE_SIZE; \
+-	PTE_L	tmp, PTE_SIZE(ptr); \
+-	PTE_L	ptr, 0(ptr); \
+-	PTE_SRL	tmp, tmp, 6; \
+-	P_MTC0	tmp, CP0_ENTRYLO1; \
+-	PTE_SRL	ptr, ptr, 6; \
+-	P_MTC0	ptr, CP0_ENTRYLO0;
+-
+-#define DO_FAULT(write) \
+-	.set	noat; \
+-	SAVE_ALL; \
+-	mfc0	a2, CP0_BADVADDR; \
+-	KMODE; \
+-	.set	at; \
+-	move	a0, sp; \
+-	jal	do_page_fault; \
+-	 li	a1, write; \
+-	j	ret_from_exception; \
+-	 nop; \
+-	.set	noat;
+-
+-	/* Check is PTE is present, if not then jump to LABEL.
+-	 * PTR points to the page table where this PTE is located,
+-	 * when the macro is done executing PTE will be restored
+-	 * with it's original value.
+-	 */
+-#define PTE_PRESENT(pte, ptr, label) \
+-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_READ); \
+-	bnez	pte, label; \
+-	 PTE_L	pte, (ptr);
+-
+-	/* Make PTE valid, store result in PTR. */
+-#define PTE_MAKEVALID(pte, ptr) \
+-	ori	pte, pte, (_PAGE_VALID | _PAGE_ACCESSED); \
+-	PTE_S	pte, (ptr);
+-
+-	/* Check if PTE can be written to, if not branch to LABEL.
+-	 * Regardless restore PTE with value from PTR when done.
+-	 */
+-#define PTE_WRITABLE(pte, ptr, label) \
+-	andi	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+-	xori	pte, pte, (_PAGE_PRESENT | _PAGE_WRITE); \
+-	bnez	pte, label; \
+-	 PTE_L	pte, (ptr);
+-
+-	/* Make PTE writable, update software status bits as well,
+-	 * then store at PTR.
+-	 */
+-#define PTE_MAKEWRITE(pte, ptr) \
+-	ori	pte, pte, (_PAGE_ACCESSED | _PAGE_MODIFIED | \
+-			   _PAGE_VALID | _PAGE_DIRTY); \
+-	PTE_S	pte, (ptr);
+-
+-
+-	.set	noreorder
+-
+-/*
+- * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0:
+- * 2. A timing hazard exists for the TLBP instruction.
+- *
+- *      stalling_instruction
+- *      TLBP
+- *
+- * The JTLB is being read for the TLBP throughout the stall generated by the
+- * previous instruction. This is not really correct as the stalling instruction
+- * can modify the address used to access the JTLB.  The failure symptom is that
+- * the TLBP instruction will use an address created for the stalling instruction
+- * and not the address held in C0_ENHI and thus report the wrong results.
+- *
+- * The software work-around is to not allow the instruction preceding the TLBP
+- * to stall - make it an NOP or some other instruction guaranteed not to stall.
+- *
+- * Errata 2 will not be fixed.  This errata is also on the R5000.
+- *
+- * As if we MIPS hackers wouldn't know how to nop pipelines happy ...
+- */
+-#define R5K_HAZARD nop
+-
+-	/*
+-	 * Note for many R4k variants tlb probes cannot be executed out
+-	 * of the instruction cache else you get bogus results.
+-	 */
+-	.align	5
+-	NESTED(handle_tlbl, PT_SIZE, sp)
+-	.set	noat
+-#if BCM1250_M3_WAR
+-	mfc0	k0, CP0_BADVADDR
+-	mfc0	k1, CP0_ENTRYHI
+-	xor	k0, k1
+-	srl	k0, k0, PAGE_SHIFT+1
+-	beqz	k0, 1f
+-	 nop
+-	.set	mips3
+-	eret
+-	.set	mips0
+-1:
+-#endif
+-invalid_tlbl:
+-#ifdef TLB_OPTIMIZE
+-	.set	mips3
+-	/* Test present bit in entry. */
+-	LOAD_PTE(k0, k1)
+-	R5K_HAZARD
+-	tlbp
+-	PTE_PRESENT(k0, k1, nopage_tlbl)
+-	PTE_MAKEVALID(k0, k1)
+-	PTE_RELOAD(k1, k0)
+-	mtc0_tlbw_hazard
+-	tlbwi
+-	nop
+-	tlbw_eret_hazard
+-	.set	mips3
+-	eret
+-	.set	mips0
+-#endif
+-
+-nopage_tlbl:
+-	DO_FAULT(0)
+-	END(handle_tlbl)
+-
+-	.align	5
+-	NESTED(handle_tlbs, PT_SIZE, sp)
+-	.set	noat
+-#ifdef TLB_OPTIMIZE
+-	.set	mips3
+-        li      k0,0
+-	LOAD_PTE(k0, k1)
+-	R5K_HAZARD
+-	tlbp				# find faulting entry
+-	PTE_WRITABLE(k0, k1, nopage_tlbs)
+-	PTE_MAKEWRITE(k0, k1)
+-	PTE_RELOAD(k1, k0)
+-	mtc0_tlbw_hazard
+-	tlbwi
+-	nop
+-	tlbw_eret_hazard
+-	.set	mips3
+-	eret
+-	.set	mips0
+-#endif
+-
+-nopage_tlbs:
+-	DO_FAULT(1)
+-	END(handle_tlbs)
+-
+-	.align	5
+-	NESTED(handle_mod, PT_SIZE, sp)
+-	.set	noat
+-#ifdef TLB_OPTIMIZE
+-	.set	mips3
+-	LOAD_PTE(k0, k1)
+-	R5K_HAZARD
+-	tlbp					# find faulting entry
+-	andi	k0, k0, _PAGE_WRITE
+-	beqz	k0, nowrite_mod
+-	 PTE_L	k0, (k1)
+-
+-	/* Present and writable bits set, set accessed and dirty bits. */
+-	PTE_MAKEWRITE(k0, k1)
+-
+-	/* Now reload the entry into the tlb. */
+-	PTE_RELOAD(k1, k0)
+-	mtc0_tlbw_hazard
+-	tlbwi
+-	nop
+-	tlbw_eret_hazard
+-	.set	mips3
+-	eret
+-	.set	mips0
+-#endif
+-
+-nowrite_mod:
+-	DO_FAULT(1)
+-	END(handle_mod)
+diff -urpNX dontdiff linux-2.6.10/arch/mips/oprofile/Kconfig linux-2.6.10-mips/arch/mips/oprofile/Kconfig
+--- linux-2.6.10/arch/mips/oprofile/Kconfig	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/oprofile/Kconfig	2004-12-12 03:22:46.000000000 +0100
+@@ -0,0 +1,23 @@
++
++menu "Profiling support"
++	depends on EXPERIMENTAL
++
++config PROFILING
++	bool "Profiling support (EXPERIMENTAL)"
++	help
++	  Say Y here to enable the extended profiling support mechanisms used
++	  by profilers such as OProfile.
++	  
++
++config OPROFILE
++	tristate "OProfile system profiling (EXPERIMENTAL)"
++	depends on PROFILING
++	help
++	  OProfile is a profiling system capable of profiling the
++	  whole system, include the kernel, kernel modules, libraries,
++	  and applications.
++
++	  If unsure, say N.
++
++endmenu
++
+diff -urpNX dontdiff linux-2.6.10/arch/mips/oprofile/Makefile linux-2.6.10-mips/arch/mips/oprofile/Makefile
+--- linux-2.6.10/arch/mips/oprofile/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/oprofile/Makefile	2004-12-12 03:22:46.000000000 +0100
+@@ -0,0 +1,13 @@
++EXTRA_CFLAGS := -Werror -Wno-sign-compare
++
++obj-$(CONFIG_OPROFILE) += oprofile.o
++
++DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
++		oprof.o cpu_buffer.o buffer_sync.o \
++		event_buffer.o oprofile_files.o \
++		oprofilefs.o oprofile_stats.o \
++		timer_int.o )
++
++oprofile-y				:= $(DRIVER_OBJS) common.o
++
++oprofile-$(CONFIG_CPU_RM9000)		+= op_model_rm9000.o
+diff -urpNX dontdiff linux-2.6.10/arch/mips/oprofile/common.c linux-2.6.10-mips/arch/mips/oprofile/common.c
+--- linux-2.6.10/arch/mips/oprofile/common.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/oprofile/common.c	2004-12-12 03:22:46.000000000 +0100
+@@ -0,0 +1,110 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2004 by Ralf Baechle
++ */
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/oprofile.h>
++#include <linux/smp.h>
++#include <asm/cpu-info.h>
++
++#include "op_impl.h"
++
++extern struct op_mips_model op_model_rm9000 __attribute__((weak));
++
++static struct op_mips_model *model;
++
++static struct op_counter_config ctr[20];
++
++static int op_mips_setup(void)
++{
++	/* Pre-compute the values to stuff in the hardware registers.  */
++	model->reg_setup(ctr);
++
++	/* Configure the registers on all cpus.  */
++	on_each_cpu(model->cpu_setup, 0, 0, 1);
++
++        return 0;
++}
++
++static int op_mips_create_files(struct super_block * sb, struct dentry * root)
++{
++	int i;
++
++	for (i = 0; i < model->num_counters; ++i) {
++		struct dentry *dir;
++		char buf[3];
++
++		snprintf(buf, sizeof buf, "%d", i);
++		dir = oprofilefs_mkdir(sb, root, buf);
++
++		oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
++		oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
++		oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
++		/* Dummies.  */
++		oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
++		oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
++		oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
++		oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
++	}
++
++	return 0;
++}
++
++static int op_mips_start(void)
++{
++	on_each_cpu(model->cpu_start, NULL, 0, 1);
++
++	return 0;
++}
++
++static void op_mips_stop(void)
++{
++	/* Disable performance monitoring for all counters.  */
++	on_each_cpu(model->cpu_stop, NULL, 0, 1);
++}
++
++static struct oprofile_operations oprof_mips_ops = {
++	.create_files	= op_mips_create_files,
++	.setup		= op_mips_setup,
++	.start		= op_mips_start,
++	.stop		= op_mips_stop,
++	.cpu_type	= NULL
++};
++
++int __init oprofile_arch_init(struct oprofile_operations **ops)
++{
++	struct op_mips_model *lmodel = NULL;
++	int res;
++
++	switch (current_cpu_data.cputype) {
++	case CPU_RM9000:
++		lmodel = &op_model_rm9000;
++		break;
++	};
++
++	if (!lmodel)
++		return -ENODEV;
++
++	res = lmodel->init();
++	if (res)
++		return res;
++
++	model = lmodel;
++
++	oprof_mips_ops.cpu_type = lmodel->cpu_type;
++	*ops = &oprof_mips_ops;
++
++	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
++	       lmodel->cpu_type);
++
++	return 0;
++}
++
++void oprofile_arch_exit(void)
++{
++	model->exit();
++}
+diff -urpNX dontdiff linux-2.6.10/arch/mips/oprofile/op_impl.h linux-2.6.10-mips/arch/mips/oprofile/op_impl.h
+--- linux-2.6.10/arch/mips/oprofile/op_impl.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/oprofile/op_impl.h	2004-12-12 03:22:46.000000000 +0100
+@@ -0,0 +1,37 @@
++/**
++ * @file arch/alpha/oprofile/op_impl.h
++ *
++ * @remark Copyright 2002 OProfile authors
++ * @remark Read the file COPYING
++ *
++ * @author Richard Henderson <rth at twiddle.net>
++ */
++
++#ifndef OP_IMPL_H
++#define OP_IMPL_H 1
++
++/* Per-counter configuration as set via oprofilefs.  */
++struct op_counter_config {
++	unsigned long enabled;
++	unsigned long event;
++	unsigned long count;
++	/* Dummies because I am too lazy to hack the userspace tools.  */
++	unsigned long kernel;
++	unsigned long user;
++	unsigned long exl;
++	unsigned long unit_mask;
++};
++
++/* Per-architecture configury and hooks.  */
++struct op_mips_model {
++	void (*reg_setup) (struct op_counter_config *);
++	void (*cpu_setup) (void * dummy);
++	int (*init)(void);
++	void (*exit)(void);
++	void (*cpu_start)(void *args);
++	void (*cpu_stop)(void *args);
++	char *cpu_type;
++	unsigned char num_counters;
++};
++
++#endif
+diff -urpNX dontdiff linux-2.6.10/arch/mips/oprofile/op_model_rm9000.c linux-2.6.10-mips/arch/mips/oprofile/op_model_rm9000.c
+--- linux-2.6.10/arch/mips/oprofile/op_model_rm9000.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/oprofile/op_model_rm9000.c	2004-12-15 21:30:48.000000000 +0100
+@@ -0,0 +1,139 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2004 by Ralf Baechle
++ */
++#include <linux/oprofile.h>
++#include <linux/interrupt.h>
++#include <linux/smp.h>
++
++#include "op_impl.h"
++
++#define RM9K_COUNTER1_EVENT(event)	((event) << 0)
++#define RM9K_COUNTER1_SUPERVISOR	(1ULL    <<  7)
++#define RM9K_COUNTER1_KERNEL		(1ULL    <<  8)
++#define RM9K_COUNTER1_USER		(1ULL    <<  9)
++#define RM9K_COUNTER1_ENABLE		(1ULL    << 10)
++#define RM9K_COUNTER1_OVERFLOW		(1ULL    << 15)
++
++#define RM9K_COUNTER2_EVENT(event)	((event) << 16)
++#define RM9K_COUNTER2_SUPERVISOR	(1ULL    << 23)
++#define RM9K_COUNTER2_KERNEL		(1ULL    << 24)
++#define RM9K_COUNTER2_USER		(1ULL    << 25)
++#define RM9K_COUNTER2_ENABLE		(1ULL    << 26)
++#define RM9K_COUNTER2_OVERFLOW		(1ULL    << 31)
++
++extern unsigned int rm9000_perfcount_irq;
++
++static struct rm9k_register_config {
++	unsigned int control;
++	unsigned int reset_counter1;
++	unsigned int reset_counter2;
++} reg;
++
++/* Compute all of the registers in preparation for enabling profiling.  */
++
++static void rm9000_reg_setup(struct op_counter_config *ctr)
++{
++	unsigned int control = 0;
++
++	/* Compute the performance counter control word.  */
++	/* For now count kernel and user mode */
++	if (ctr[0].enabled)
++		control |= RM9K_COUNTER1_EVENT(ctr[0].event) |
++		           RM9K_COUNTER1_KERNEL |
++		           RM9K_COUNTER1_USER |
++		           RM9K_COUNTER1_ENABLE;
++	if (ctr[1].enabled)
++		control |= RM9K_COUNTER2_EVENT(ctr[1].event) |
++		           RM9K_COUNTER2_KERNEL |
++		           RM9K_COUNTER2_USER |
++		           RM9K_COUNTER2_ENABLE;
++	reg.control = control;
++
++	reg.reset_counter1 = 0x80000000 - ctr[0].count;
++	reg.reset_counter2 = 0x80000000 - ctr[1].count;
++}
++
++/* Program all of the registers in preparation for enabling profiling.  */
++
++static void rm9000_cpu_setup (void *args)
++{
++	uint64_t perfcount;
++
++	perfcount = ((uint64_t) reg.reset_counter2 << 32) | reg.reset_counter1;
++	write_c0_perfcount(perfcount);
++}
++
++static void rm9000_cpu_start(void *args)
++{
++	/* Start all counters on current CPU */
++	write_c0_perfcontrol(reg.control);
++}
++
++static void rm9000_cpu_stop(void *args)
++{
++	/* Stop all counters on current CPU */
++	write_c0_perfcontrol(0);
++}
++
++static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id,
++	struct pt_regs *regs)
++{
++	unsigned int control = read_c0_perfcontrol();
++	uint32_t counter1, counter2;
++	uint64_t counters;
++
++	/*
++	 * RM9000 combines two 32-bit performance counters into a single
++	 * 64-bit coprocessor zero register.  To avoid a race updating the
++	 * registers we need to stop the counters while we're messing with
++	 * them ...
++	 */
++	write_c0_perfcontrol(0);
++
++	counters = read_c0_perfcount();
++	counter1 = counters;
++	counter2 = counters >> 32;
++
++	if (control & RM9K_COUNTER1_OVERFLOW) {
++		oprofile_add_sample(regs->cp0_epc, !user_mode(regs),
++		                    0, smp_processor_id());
++		counter1 = reg.reset_counter1;
++	}
++	if (control & RM9K_COUNTER2_OVERFLOW) {
++		oprofile_add_sample(regs->cp0_epc, !user_mode(regs),
++		                    1, smp_processor_id());
++		counter2 = reg.reset_counter2;
++	}
++
++	counters = ((uint64_t)counter2 << 32) | counter1;
++	write_c0_perfcount(counters);
++	write_c0_perfcontrol(reg.control);
++
++	return IRQ_HANDLED;
++}
++
++static int rm9000_init(void)
++{
++	return request_irq(rm9000_perfcount_irq, rm9000_perfcount_handler,
++	                   0, "Perfcounter", NULL);
++}
++
++static void rm9000_exit(void)
++{
++	free_irq(rm9000_perfcount_irq, NULL);
++}
++
++struct op_mips_model op_model_rm9000 = {
++	.reg_setup	= rm9000_reg_setup,
++	.cpu_setup	= rm9000_cpu_setup,
++	.init		= rm9000_init,
++	.exit		= rm9000_exit,
++	.cpu_start	= rm9000_cpu_start,
++	.cpu_stop	= rm9000_cpu_stop,
++	.cpu_type	= "mips/rm9000",
++	.num_counters	= 2
++};
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pci/Makefile linux-2.6.10-mips/arch/mips/pci/Makefile
+--- linux-2.6.10/arch/mips/pci/Makefile	2004-12-24 22:33:49.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pci/Makefile	2004-12-21 03:25:17.000000000 +0100
+@@ -17,6 +17,7 @@ obj-$(CONFIG_MIPS_MSC)		+= ops-msc.o
+ obj-$(CONFIG_MIPS_NILE4)	+= ops-nile4.o
+ obj-$(CONFIG_MIPS_TX3927)	+= ops-jmr3927.o
+ obj-$(CONFIG_PCI_VR41XX)	+= ops-vr41xx.o pci-vr41xx.o
++obj-$(CONFIG_NEC_CMBVR4133)	+= fixup-vr4133.o
+ 
+ #
+ # These are still pretty much in the old state, watch, go blind.
+@@ -43,7 +44,7 @@ obj-$(CONFIG_PMC_YOSEMITE)	+= fixup-yose
+ 				   pci-yosemite.o
+ obj-$(CONFIG_SGI_IP27)		+= pci-ip27.o
+ obj-$(CONFIG_SGI_IP32)		+= fixup-ip32.o ops-mace.o pci-ip32.o
+-obj-$(CONFIG_SIBYTE_SB1250)	+= pci-sb1250.o
++obj-$(CONFIG_SIBYTE_SB1250)	+= fixup-sb1250.o pci-sb1250.o
+ obj-$(CONFIG_SNI_RM200_PCI)	+= fixup-sni.o ops-sni.o
+ obj-$(CONFIG_TANBAC_TB0219)	+= fixup-tb0219.o
+ obj-$(CONFIG_TANBAC_TB0226)	+= fixup-tb0226.o
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pci/fixup-au1000.c linux-2.6.10-mips/arch/mips/pci/fixup-au1000.c
+--- linux-2.6.10/arch/mips/pci/fixup-au1000.c	2004-12-24 22:33:59.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pci/fixup-au1000.c	2004-12-03 12:31:40.000000000 +0100
+@@ -98,6 +98,19 @@ static char irq_tab_alchemy[][5] __initd
+ };
+ #endif
+ 
++#ifdef CONFIG_MIPS_MTX1
++static char irq_tab_alchemy[][5] __initdata = {
++ [0] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 00 - AdapterA-Slot0 (top)    */
++ [1] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 01 - AdapterA-Slot1 (bottom) */
++ [2] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 02 - AdapterB-Slot0 (top)    */
++ [3] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 03 - AdapterB-Slot1 (bottom) */
++ [4] = { -1, INTA, INTB, INTX, INTX},   /* IDSEL 04 - AdapterC-Slot0 (top)    */
++ [5] = { -1, INTB, INTA, INTX, INTX},   /* IDSEL 05 - AdapterC-Slot1 (bottom) */
++ [6] = { -1, INTC, INTD, INTX, INTX},   /* IDSEL 06 - AdapterD-Slot0 (top)    */
++ [7] = { -1, INTD, INTC, INTX, INTX},   /* IDSEL 07 - AdapterD-Slot1 (bottom) */
++};
++#endif
++
+ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+ {
+ 	return irq_tab_alchemy[slot][pin];
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pci/fixup-sb1250.c linux-2.6.10-mips/arch/mips/pci/fixup-sb1250.c
+--- linux-2.6.10/arch/mips/pci/fixup-sb1250.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pci/fixup-sb1250.c	2004-12-18 23:28:20.000000000 +0100
+@@ -0,0 +1,24 @@
++/*
++ *	arch/mips/pci/fixup-sb1250.c
++ *
++ *	Copyright (C) 2004  MIPS Technologies, Inc.  All rights reserved.
++ *	    Author:	Maciej W. Rozycki <macro at mips.com>
++ *
++ *	This program is free software; you can redistribute it and/or
++ *	modify it under the terms of the GNU General Public License
++ *	as published by the Free Software Foundation; either version
++ *	2 of the License, or (at your option) any later version.
++ */
++
++#include <linux/init.h>
++#include <linux/pci.h>
++
++/*
++ * The BCM1250, etc. PCI/HT bridge reports as a host bridge.
++ */
++static void __init quirk_sb1250_ht(struct pci_dev *dev)
++{
++	dev->class = PCI_CLASS_BRIDGE_PCI << 8;
++}
++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SIBYTE, PCI_DEVICE_ID_BCM1250_HT,
++			quirk_sb1250_ht);
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pci/fixup-vr4133.c linux-2.6.10-mips/arch/mips/pci/fixup-vr4133.c
+--- linux-2.6.10/arch/mips/pci/fixup-vr4133.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pci/fixup-vr4133.c	2004-12-15 15:08:18.000000000 +0100
+@@ -0,0 +1,204 @@
++/*
++ * arch/mips/vr41xx/nec-cmbvr4133/pci_fixup.c
++ *
++ * The NEC CMB-VR4133 Board specific PCI fixups.
++ *
++ * Author: Yoichi Yuasa <yyuasa at mvista.com, or source at mvista.com> and
++ *         Alex Sapkov <asapkov at ru.mvista.com>
++ *
++ * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under
++ * the terms of the GNU General Public License version 2. This program
++ * is licensed "as is" without any warranty of any kind, whether express
++ * or implied.
++ *
++ * Modified for support in 2.6 
++ * Author: Manish Lachwani (mlachwani at mvista.com)
++ * 
++ */
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/pci.h>
++
++#include <asm/io.h>
++#include <asm/vr41xx/cmbvr4133.h>
++
++extern int vr4133_rockhopper;
++extern void ali_m1535plus_init(struct pci_dev *dev);
++extern void ali_m5229_init(struct pci_dev *dev);
++
++/* Do platform specific device initialization at pci_enable_device() time */
++int pcibios_plat_dev_init(struct pci_dev *dev)
++{
++	/* 
++	 * We have to reset AMD PCnet adapter on Rockhopper since
++	 * PMON leaves it enabled and generating interrupts. This leads
++	 * to a lock if some PCI device driver later enables the IRQ line
++	 * shared with PCnet and there is no AMD PCnet driver to catch its
++	 * interrupts. 
++	 */
++#ifdef CONFIG_ROCKHOPPER
++	if (dev->vendor == PCI_VENDOR_ID_AMD && 
++		dev->device == PCI_DEVICE_ID_AMD_LANCE) {
++		inl(pci_resource_start(dev, 0) + 0x18);
++	}
++#endif
++
++	/* 
++	 * we have to open the bridges' windows down to 0 because otherwise
++ 	 * we cannot access ISA south bridge I/O registers that get mapped from
++	 * 0. for example, 8259 PIC would be unaccessible without that
++	 */
++	if(dev->vendor == PCI_VENDOR_ID_INTEL && dev->device == PCI_DEVICE_ID_INTEL_S21152BB) {
++		pci_write_config_byte(dev, PCI_IO_BASE, 0);
++		if(dev->bus->number == 0) {
++			pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 0);
++		} else {
++			pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 1);
++		}
++	}
++
++	return 0;
++}
++
++/* 
++ * M1535 IRQ mapping 
++ * Feel free to change this, although it shouldn't be needed
++ */
++#define M1535_IRQ_INTA  7
++#define M1535_IRQ_INTB  9
++#define M1535_IRQ_INTC  10
++#define M1535_IRQ_INTD  11
++
++#define M1535_IRQ_USB   9
++#define M1535_IRQ_IDE   14
++#define M1535_IRQ_IDE2  15
++#define M1535_IRQ_PS2   12
++#define M1535_IRQ_RTC   8
++#define M1535_IRQ_FDC   6
++#define M1535_IRQ_AUDIO 5
++#define M1535_IRQ_COM1  4
++#define M1535_IRQ_COM2  4
++#define M1535_IRQ_IRDA  3
++#define M1535_IRQ_KBD   1
++#define M1535_IRQ_TMR   0
++
++/* Rockhopper "slots" assignment; this is hard-coded ... */
++#define ROCKHOPPER_M5451_SLOT  1
++#define ROCKHOPPER_M1535_SLOT  2
++#define ROCKHOPPER_M5229_SLOT  11
++#define ROCKHOPPER_M5237_SLOT  15
++#define ROCKHOPPER_PMU_SLOT    12
++/* ... and hard-wired. */
++#define ROCKHOPPER_PCI1_SLOT   3
++#define ROCKHOPPER_PCI2_SLOT   4
++#define ROCKHOPPER_PCI3_SLOT   5
++#define ROCKHOPPER_PCI4_SLOT   6
++#define ROCKHOPPER_PCNET_SLOT  1
++
++#define M1535_IRQ_MASK(n) (1 << (n))
++
++#define M1535_IRQ_EDGE  (M1535_IRQ_MASK(M1535_IRQ_TMR)  | \
++                         M1535_IRQ_MASK(M1535_IRQ_KBD)  | \
++                         M1535_IRQ_MASK(M1535_IRQ_COM1) | \
++                         M1535_IRQ_MASK(M1535_IRQ_COM2) | \
++                         M1535_IRQ_MASK(M1535_IRQ_IRDA) | \
++                         M1535_IRQ_MASK(M1535_IRQ_RTC)  | \
++                         M1535_IRQ_MASK(M1535_IRQ_FDC)  | \
++                         M1535_IRQ_MASK(M1535_IRQ_PS2))
++
++#define M1535_IRQ_LEVEL (M1535_IRQ_MASK(M1535_IRQ_IDE)  | \
++                         M1535_IRQ_MASK(M1535_IRQ_USB)  | \
++                         M1535_IRQ_MASK(M1535_IRQ_INTA) | \
++                         M1535_IRQ_MASK(M1535_IRQ_INTB) | \
++                         M1535_IRQ_MASK(M1535_IRQ_INTC) | \
++                         M1535_IRQ_MASK(M1535_IRQ_INTD))
++
++struct irq_map_entry {
++	u16 bus;
++	u8 slot;
++	u8 irq;
++};
++static struct irq_map_entry int_map[] = {
++	{1, ROCKHOPPER_M5451_SLOT, M1535_IRQ_AUDIO},	/* Audio controller */
++	{1, ROCKHOPPER_PCI1_SLOT, M1535_IRQ_INTD},	/* PCI slot #1 */
++	{1, ROCKHOPPER_PCI2_SLOT, M1535_IRQ_INTC},	/* PCI slot #2 */
++	{1, ROCKHOPPER_M5237_SLOT, M1535_IRQ_USB},	/* USB host controller */
++	{1, ROCKHOPPER_M5229_SLOT, IDE_PRIMARY_IRQ},	/* IDE controller */
++	{2, ROCKHOPPER_PCNET_SLOT, M1535_IRQ_INTD},	/* AMD Am79c973 on-board 
++							   ethernet */
++	{2, ROCKHOPPER_PCI3_SLOT, M1535_IRQ_INTB},	/* PCI slot #3 */
++	{2, ROCKHOPPER_PCI4_SLOT, M1535_IRQ_INTC}	/* PCI slot #4 */
++};
++
++static int pci_intlines[] =
++    { M1535_IRQ_INTA, M1535_IRQ_INTB, M1535_IRQ_INTC, M1535_IRQ_INTD };
++
++/* Determine the Rockhopper IRQ line number for the PCI device */
++int rockhopper_get_irq(struct pci_dev *dev, u8 pin, u8 slot)
++{
++	struct pci_bus *bus;
++	int i;
++
++	bus = dev->bus;
++	if (bus == NULL)
++		return -1;
++
++	for (i = 0; i < sizeof (int_map) / sizeof (int_map[0]); i++) {
++		if (int_map[i].bus == bus->number && int_map[i].slot == slot) {
++			int line;
++			for (line = 0; line < 4; line++)
++				if (pci_intlines[line] == int_map[i].irq)
++					break;
++			if (line < 4)
++				return pci_intlines[(line + (pin - 1)) % 4];
++			else
++				return int_map[i].irq;
++		}
++	}
++	return -1;
++}
++
++#ifdef CONFIG_ROCKHOPPER
++void i8259_init(void)
++{
++	outb(0x11, 0x20);		/* Master ICW1 */
++	outb(I8259_IRQ_BASE, 0x21);	/* Master ICW2 */
++	outb(0x04, 0x21);		/* Master ICW3 */
++	outb(0x01, 0x21);		/* Master ICW4 */
++	outb(0xff, 0x21);		/* Master IMW */
++
++	outb(0x11, 0xa0);		/* Slave ICW1 */
++	outb(I8259_IRQ_BASE + 8, 0xa1);	/* Slave ICW2 */
++	outb(0x02, 0xa1);		/* Slave ICW3 */
++	outb(0x01, 0xa1);		/* Slave ICW4 */
++	outb(0xff, 0xa1);		/* Slave IMW */
++
++	outb(0x00, 0x4d0);
++	outb(0x02, 0x4d1);	/* USB IRQ9 is level */
++}
++#endif
++
++int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
++{
++	extern int pci_probe_only;
++	pci_probe_only = 1;
++
++#ifdef CONFIG_ROCKHOPPER
++	if( dev->bus->number == 1 && vr4133_rockhopper )  {
++		if(slot == ROCKHOPPER_PCI1_SLOT || slot == ROCKHOPPER_PCI2_SLOT)
++			dev->irq = CMBVR41XX_INTA_IRQ;
++		else
++			dev->irq = rockhopper_get_irq(dev, pin, slot);
++	} else
++		dev->irq = CMBVR41XX_INTA_IRQ;
++#else
++	dev->irq = CMBVR41XX_INTA_IRQ;
++#endif
++
++	return dev->irq;
++}
++
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, ali_m1535plus_init);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, ali_m5229_init);
++
++
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pci/ops-sni.c linux-2.6.10-mips/arch/mips/pci/ops-sni.c
+--- linux-2.6.10/arch/mips/pci/ops-sni.c	2004-12-24 22:34:58.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pci/ops-sni.c	2004-12-21 03:25:17.000000000 +0100
+@@ -21,9 +21,9 @@
+  *
+  * ASIC PCI only supports type 1 config cycles.
+  */
+-static int set_config_address(unsigned char busno, unsigned int devfn, int reg)
++static int set_config_address(unsigned int busno, unsigned int devfn, int reg)
+ {
+-	if ((busno > 255) || (devfn > 255) || (reg > 255))
++	if ((devfn > 255) || (reg > 255))
+ 		return PCIBIOS_BAD_REGISTER_NUMBER;
+ 
+ 	if (busno == 0 && devfn >= PCI_DEVFN(8, 0))
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pci/ops-titan.c linux-2.6.10-mips/arch/mips/pci/ops-titan.c
+--- linux-2.6.10/arch/mips/pci/ops-titan.c	2004-12-24 22:34:27.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pci/ops-titan.c	2004-12-21 03:25:17.000000000 +0100
+@@ -22,91 +22,69 @@
+  *  with this program; if not, write  to the Free Software Foundation, Inc.,
+  *  675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+-#include <linux/init.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+ #include <linux/kernel.h>
+-#include <linux/slab.h>
+-#include <linux/version.h>
+ 
+-#include <asm/pci.h>
+-#include <asm/io.h>
+ #include <asm/titan_dep.h>
+ 
+-/*
+- * Titan PCI Config Read Byte
+- */
+ static int titan_read_config(struct pci_bus *bus, unsigned int devfn, int reg,
+ 	int size, u32 * val)
+ {
++	uint32_t address, tmp;
+ 	int dev, busno, func;
+-	uint32_t address_reg, data_reg;
+-	uint32_t address;
+ 
+ 	busno = bus->number;
+ 	dev = PCI_SLOT(devfn);
+ 	func = PCI_FUNC(devfn);
+ 
+-	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
+-	data_reg = TITAN_PCI_0_CONFIG_DATA;
+-
+ 	address = (busno << 16) | (dev << 11) | (func << 8) |
+ 	          (reg & 0xfc) | 0x80000000;
+ 
++
+ 	/* start the configuration cycle */
+-	TITAN_WRITE(address_reg, address);
++	TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address);
++	tmp = TITAN_READ(TITAN_PCI_0_CONFIG_DATA) >> ((reg & 3) << 3);
+ 
+ 	switch (size) {
+ 	case 1:
+-		*val = TITAN_READ_8(data_reg + (~reg & 0x3));
+-		break;
+-
++		tmp &= 0xff;
+ 	case 2:
+-		*val = TITAN_READ_16(data_reg + (~reg & 0x2));
+-		break;
+-
+-	case 4:
+-		*val = TITAN_READ(data_reg);
+-		break;
++		tmp &= 0xffff;
+ 	}
++	*val = tmp;
+ 
+ 	return PCIBIOS_SUCCESSFUL;
+ }
+ 
+-/*
+- * Titan PCI Config Byte Write
+- */
+ static int titan_write_config(struct pci_bus *bus, unsigned int devfn, int reg,
+ 	int size, u32 val)
+ {
+-	uint32_t address_reg, data_reg, address;
++	uint32_t address;
+ 	int dev, busno, func;
+ 
+ 	busno = bus->number;
+ 	dev = PCI_SLOT(devfn);
+ 	func = PCI_FUNC(devfn);
+ 
+-	address_reg = TITAN_PCI_0_CONFIG_ADDRESS;
+-	data_reg = TITAN_PCI_0_CONFIG_DATA;
+-
+ 	address = (busno << 16) | (dev << 11) | (func << 8) |
+ 		(reg & 0xfc) | 0x80000000;
+ 
+ 	/* start the configuration cycle */
+-	TITAN_WRITE(address_reg, address);
++	TITAN_WRITE(TITAN_PCI_0_CONFIG_ADDRESS, address);
+ 
+ 	/* write the data */
+ 	switch (size) {
+ 	case 1:
+-		TITAN_WRITE_8(data_reg + (~reg & 0x3), val);
++		TITAN_WRITE_8(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x3), val);
+ 		break;
+ 
+ 	case 2:
+-		TITAN_WRITE_16(data_reg + (~reg & 0x2), val);
++		TITAN_WRITE_16(TITAN_PCI_0_CONFIG_DATA + (~reg & 0x2), val);
+ 		break;
+ 
+ 	case 4:
+-		TITAN_WRITE(data_reg, val);
++		TITAN_WRITE(TITAN_PCI_0_CONFIG_DATA, val);
+ 		break;
+ 	}
+ 
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pci/pci-sb1250.c linux-2.6.10-mips/arch/mips/pci/pci-sb1250.c
+--- linux-2.6.10/arch/mips/pci/pci-sb1250.c	2004-12-24 22:34:01.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pci/pci-sb1250.c	2004-12-21 03:25:18.000000000 +0100
+@@ -182,8 +182,8 @@ static int sb1250_pcibios_write(struct p
+ }
+ 
+ struct pci_ops sb1250_pci_ops = {
+-	.read = sb1250_pcibios_read,
+-	.write = sb1250_pcibios_write
++	.read	= sb1250_pcibios_read,
++	.write	= sb1250_pcibios_write,
+ };
+ 
+ static struct resource sb1250_mem_resource = {
+@@ -192,7 +192,7 @@ static struct resource sb1250_mem_resour
+ 	.end	= 0x5fffffffUL,
+ 	.flags	= IORESOURCE_MEM,
+ };
+-                                                                                
++
+ static struct resource sb1250_io_resource = {
+ 	.name	= "SB1250 PCI I/O",
+ 	.start	= 0x00000000UL,
+@@ -215,9 +215,13 @@ static int __init sb1250_pcibios_init(vo
+ 	/* CFE will assign PCI resources */
+ 	pci_probe_only = 1;
+ 
++	/* Avoid ISA compat ranges.  */
++	PCIBIOS_MIN_IO = 0x00008000UL;
++	PCIBIOS_MIN_MEM = 0x01000000UL;
++
+ 	/* Set I/O resource limits.  */
+-	ioport_resource.end = 0x01ffffff;	/* 32MB accessible by sb1250 */
+-	iomem_resource.end = 0xffffffff;	/* no HT support yet */
++	ioport_resource.end = 0x01ffffffUL;	/* 32MB accessible by sb1250 */
++	iomem_resource.end = 0xffffffffUL;	/* no HT support yet */
+ 
+ 	cfg_space =
+ 	    ioremap(A_PHYS_LDTPCI_CFG_MATCH_BITS, 16 * 1024 * 1024);
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pci/pci-yosemite.c linux-2.6.10-mips/arch/mips/pci/pci-yosemite.c
+--- linux-2.6.10/arch/mips/pci/pci-yosemite.c	2004-12-24 22:35:29.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pci/pci-yosemite.c	2004-12-21 03:25:18.000000000 +0100
+@@ -9,7 +9,7 @@
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/pci.h>
+-#include <asm/gt64240.h>
++#include <asm/titan_dep.h>
+ 
+ extern struct pci_ops titan_pci_ops;
+ 
+@@ -23,6 +23,7 @@ static struct resource py_mem_resource =
+  * anyway.  So we just claim 64kB here.
+  */
+ #define TITAN_IO_SIZE	0x0000ffffUL
++#define TITAN_IO_BASE	0xe8000000UL
+ 
+ static struct resource py_io_resource = {
+ 	"Titan IO MEM", 0x00001000UL, TITAN_IO_SIZE - 1, IORESOURCE_IO,
+@@ -42,11 +43,12 @@ static int __init pmc_yosemite_setup(voi
+ {
+ 	unsigned long io_v_base;
+ 
+-	io_v_base = (unsigned long) ioremap(0xe0000000UL,TITAN_IO_SIZE);
++	io_v_base = (unsigned long) ioremap(TITAN_IO_BASE, TITAN_IO_SIZE);
+ 	if (!io_v_base)
+ 		panic(ioremap_failed);
+ 
+ 	set_io_port_base(io_v_base);
++	TITAN_WRITE(RM9000x2_OCD_LKM7, TITAN_READ(RM9000x2_OCD_LKM7) | 1);
+ 
+ 	ioport_resource.end = TITAN_IO_SIZE - 1;
+ 
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pci/pci.c linux-2.6.10-mips/arch/mips/pci/pci.c
+--- linux-2.6.10/arch/mips/pci/pci.c	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pci/pci.c	2005-01-11 00:40:22.000000000 +0100
+@@ -59,7 +59,7 @@ pcibios_align_resource(void *data, struc
+ 
+ 	if (res->flags & IORESOURCE_IO) {
+ 		/* Make sure we start at our min on all hoses */
+-		if (start - hose->io_resource->start < PCIBIOS_MIN_IO)
++		if (start < PCIBIOS_MIN_IO + hose->io_resource->start)
+ 			start = PCIBIOS_MIN_IO + hose->io_resource->start;
+ 
+ 		/*
+@@ -69,7 +69,7 @@ pcibios_align_resource(void *data, struc
+ 			start = (start + 0x3ff) & ~0x3ff;
+ 	} else if (res->flags & IORESOURCE_MEM) {
+ 		/* Make sure we start at our min on all hoses */
+-		if (start - hose->mem_resource->start < PCIBIOS_MIN_MEM)
++		if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start)
+ 			start = PCIBIOS_MIN_MEM + hose->mem_resource->start;
+ 	}
+ 
+@@ -294,6 +294,8 @@ pcibios_resource_to_bus(struct pci_dev *
+ 
+ #ifdef CONFIG_HOTPLUG
+ EXPORT_SYMBOL(pcibios_resource_to_bus);
++EXPORT_SYMBOL(PCIBIOS_MIN_IO);
++EXPORT_SYMBOL(PCIBIOS_MIN_MEM);
+ #endif
+ 
+ char *pcibios_setup(char *str)
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pmc-sierra/yosemite/dbg_io.c linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/dbg_io.c
+--- linux-2.6.10/arch/mips/pmc-sierra/yosemite/dbg_io.c	2004-12-24 22:35:25.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/dbg_io.c	2004-12-28 20:06:24.000000000 +0100
+@@ -31,9 +31,6 @@
+  * the interrupt came from channel A or B.
+  */
+ 
+-#include <linux/config.h>
+-
+-#ifdef CONFIG_KGDB
+ #include <asm/serial.h>
+ 
+ /*
+@@ -181,4 +178,3 @@ int putDebugChar(unsigned char byte)
+ 
+ 	return 1;
+ }
+-#endif
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pmc-sierra/yosemite/irq-handler.S linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/irq-handler.S
+--- linux-2.6.10/arch/mips/pmc-sierra/yosemite/irq-handler.S	2004-12-24 22:35:25.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/irq-handler.S	2004-12-21 03:25:18.000000000 +0100
+@@ -34,37 +34,24 @@
+ 
+ 		and	t0, t2
+ 
++		andi	t2, t0, STATUSF_IP7	/* INTB5 hardware line */
++		bnez	t2, ll_timer_irq	/* Timer */
+ 		andi	t1, t0, STATUSF_IP2	/* INTB0 hardware line */
+ 		bnez	t1, ll_pcia_irq		/* 64-bit PCI */
+-		andi	t1, t0, STATUSF_IP3	/* INTB1 hardware line */
+-		bnez	t1, ll_pcib_irq		/* second 64-bit PCI slot */
++		andi	t2, t0, STATUSF_IP3	/* INTB1 hardware line */
++		bnez	t2, ll_pcib_irq		/* second 64-bit PCI slot */
+ 		andi	t1, t0, STATUSF_IP4	/* INTB2 hardware line */
+ 		bnez	t1, ll_duart_irq	/* UART	*/
+-		andi    t1, t0, STATUSF_IP5	/* SMP inter-core interrupts */
+-		bnez    t1, ll_smp_irq
++		andi    t2, t0, STATUSF_IP5	/* SMP inter-core interrupts */
++		bnez    t2, ll_smp_irq
+ 		andi	t1, t0, STATUSF_IP6
+ 		bnez	t1, ll_ht_irq		/* Hypertransport */
+-		andi	t1, t0, STATUSF_IP7	/* INTB5 hardware line */
+-		bnez	t1, ll_timer_irq	/* Timer */
+ 
+-		nop
+-		nop
+-
+-		/* Extended interrupts */
+-                mfc0    t0, CP0_CAUSE
+-                cfc0    t1, CP0_S1_INTCONTROL
+-
+-                sll     t2, t1, 8
+-
+-                and     t0, t2
+-                srl     t0, t0, 16
+-
+-		.set	reorder
+-
+-		j	spurious_interrupt
+-		nop
++		move	a0, sp
++		j	do_extended_irq
+ 		END(titan_handle_int)
+ 
++		.set	reorder
+ 		.align	5
+ 
+ ll_pcia_irq:
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pmc-sierra/yosemite/irq.c linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/irq.c
+--- linux-2.6.10/arch/mips/pmc-sierra/yosemite/irq.c	2004-12-24 22:35:24.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/irq.c	2004-12-21 03:25:18.000000000 +0100
+@@ -58,7 +58,7 @@
+ extern asmlinkage void titan_handle_int(void);
+ extern void jaguar_mailbox_irq(struct pt_regs *);
+ 
+-/* 
++/*
+  * Handle hypertransport & SMP interrupts. The interrupt lines are scarce.
+  * For interprocessor interrupts, the best thing to do is to use the INTMSG
+  * register. We use the same external interrupt line, i.e. INTB3 and monitor
+@@ -66,15 +66,15 @@ extern void jaguar_mailbox_irq(struct pt
+  */
+ asmlinkage void ll_ht_smp_irq_handler(int irq, struct pt_regs *regs)
+ {
+-        u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
++	u32 status = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
+ 
+ 	/* Ack all the bits that correspond to the interrupt sources */
+ 	if (status != 0)
+-	        OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS);
++		OCD_WRITE(RM9000x2_OCD_INTP0STATUS4, IRQ_ACK_BITS);
+ 
+ 	status = OCD_READ(RM9000x2_OCD_INTP1STATUS4);
+ 	if (status != 0)
+-                OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS);
++		OCD_WRITE(RM9000x2_OCD_INTP1STATUS4, IRQ_ACK_BITS);
+ 
+ #ifdef CONFIG_HT_LEVEL_TRIGGER
+ 	/*
+@@ -110,6 +110,21 @@ asmlinkage void ll_ht_smp_irq_handler(in
+ 	do_IRQ(irq, regs);
+ }
+ 
++asmlinkage void do_extended_irq(struct pt_regs *regs)
++{
++	unsigned int intcontrol = read_c0_intcontrol();
++	unsigned int cause = read_c0_cause();
++	unsigned int status = read_c0_status();
++	unsigned int pending_sr, pending_ic;
++
++	pending_sr = status & cause & 0xff00;
++	pending_ic = (cause >> 8) & intcontrol & 0xff00;
++
++	if (pending_ic & (1 << 13))
++		do_IRQ(13, regs);
++
++}
++
+ #ifdef CONFIG_KGDB
+ extern void init_second_port(void);
+ #endif
+@@ -124,6 +139,7 @@ void __init arch_init_irq(void)
+ 	set_except_vector(0, titan_handle_int);
+ 	mips_cpu_irq_init(0);
+ 	rm7k_cpu_irq_init(8);
++	rm9k_cpu_irq_init(12);
+ 
+ #ifdef CONFIG_KGDB
+ 	/* At this point, initialize the second serial port */
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pmc-sierra/yosemite/prom.c linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/prom.c
+--- linux-2.6.10/arch/mips/pmc-sierra/yosemite/prom.c	2004-12-24 22:36:01.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/prom.c	2004-12-21 03:25:18.000000000 +0100
+@@ -43,7 +43,7 @@ const char *get_system_type(void)
+ 
+ static void prom_cpu0_exit(void *arg)
+ {
+-	void *nvram = (void *) YOSEMITE_NVRAM_BASE_ADDR;
++	void *nvram = (void *) YOSEMITE_RTC_BASE;
+ 
+ 	/* Ask the NVRAM/RTC/watchdog chip to assert reset in 1/16 second */
+ 	writeb(0x84, nvram + 0xff7);
+@@ -94,8 +94,6 @@ void __init prom_init(void)
+ 	_machine_halt = prom_halt;
+ 	_machine_power_off = prom_halt;
+ 
+-#ifdef CONFIG_MIPS32
+-
+ 	debug_vectors = cv;
+ 	arcs_cmdline[0] = '\0';
+ 
+@@ -109,6 +107,11 @@ void __init prom_init(void)
+ 		strcat(arcs_cmdline, " ");
+ 	}
+ 
++#ifdef CONFIG_SERIAL_8250_CONSOLE
++	if ((strstr(arcs_cmdline, "console=ttyS")) == NULL)
++		strcat(arcs_cmdline, "console=ttyS0,115200");
++#endif
++
+ 	while (*env) {
+ 		if (strncmp("ocd_base", *env, strlen("ocd_base")) == 0)
+ 			yosemite_base =
+@@ -122,7 +125,6 @@ void __init prom_init(void)
+ 
+ 		env++;
+ 	}
+-#endif /* CONFIG_MIPS32 */
+ 
+ 	mips_machgroup = MACH_GROUP_TITAN;
+ 	mips_machtype = MACH_TITAN_YOSEMITE;
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pmc-sierra/yosemite/py-console.c linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/py-console.c
+--- linux-2.6.10/arch/mips/pmc-sierra/yosemite/py-console.c	2004-12-24 22:34:45.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/py-console.c	2004-12-21 03:25:18.000000000 +0100
+@@ -48,9 +48,12 @@ struct yo_uartregs {
+ #define iu_iir u3.iir
+ #define iu_fcr u3.fcr
+ 
++#define ssnop()		__asm__ __volatile__("sll	$0, $0, 1\n");
++#define ssnop_4()	do { ssnop(); ssnop(); ssnop(); ssnop(); } while (0)
++
+ #define IO_BASE_64	0x9000000000000000ULL
+ 
+-static unsigned char readb_outer_space(unsigned long phys)
++static unsigned char readb_outer_space(unsigned long long phys)
+ {
+ 	unsigned long long vaddr = IO_BASE_64 | phys;
+ 	unsigned char res;
+@@ -58,29 +61,23 @@ static unsigned char readb_outer_space(u
+ 
+ 	sr = read_c0_status();
+ 	write_c0_status((sr | ST0_KX) & ~ ST0_IE);
+-	__asm__("sll	$0, $0, 2\n");
+-	__asm__("sll	$0, $0, 2\n");
+-	__asm__("sll	$0, $0, 2\n");
+-	__asm__("sll	$0, $0, 2\n");
++	ssnop_4();
+ 
+ 	__asm__ __volatile__ (
+ 	"	.set	mips3		\n"
+-	"	ld	%0, (%0)	\n"
++	"	ld	%0, %1		\n"
+ 	"	lbu	%0, (%0)	\n"
+ 	"	.set	mips0		\n"
+ 	: "=r" (res)
+-	: "0" (&vaddr));
++	: "m" (vaddr));
+ 
+ 	write_c0_status(sr);
+-	__asm__("sll	$0, $0, 2\n");
+-	__asm__("sll	$0, $0, 2\n");
+-	__asm__("sll	$0, $0, 2\n");
+-	__asm__("sll	$0, $0, 2\n");
++	ssnop_4();
+ 
+ 	return res;
+ }
+ 
+-static void writeb_outer_space(unsigned long phys, unsigned char c)
++static void writeb_outer_space(unsigned long long phys, unsigned char c)
+ {
+ 	unsigned long long vaddr = IO_BASE_64 | phys;
+ 	unsigned long tmp;
+@@ -88,30 +85,24 @@ static void writeb_outer_space(unsigned 
+ 
+ 	sr = read_c0_status();
+ 	write_c0_status((sr | ST0_KX) & ~ ST0_IE);
+-	__asm__("sll	$0, $0, 2\n");
+-	__asm__("sll	$0, $0, 2\n");
+-	__asm__("sll	$0, $0, 2\n");
+-	__asm__("sll	$0, $0, 2\n");
++	ssnop_4();
+ 
+ 	__asm__ __volatile__ (
+ 	"	.set	mips3		\n"
+-	"	ld	%0, (%1)	\n"
++	"	ld	%0, %1		\n"
+ 	"	sb	%2, (%0)	\n"
+ 	"	.set	mips0		\n"
+-	: "=r" (tmp)
+-	: "r" (&vaddr), "r" (c));
++	: "=&r" (tmp)
++	: "m" (vaddr), "r" (c));
+ 
+ 	write_c0_status(sr);
+-	__asm__("sll	$0, $0, 2\n");
+-	__asm__("sll	$0, $0, 2\n");
+-	__asm__("sll	$0, $0, 2\n");
+-	__asm__("sll	$0, $0, 2\n");
++	ssnop_4();
+ }
+ 
+ void prom_putchar(char c)
+ {
+-	unsigned long lsr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_lsr);
+-	unsigned long thr = 0xfd000008UL + offsetof(struct yo_uartregs, iu_thr);
++	unsigned long lsr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_lsr);
++	unsigned long thr = 0xfd000008ULL + offsetof(struct yo_uartregs, iu_thr);
+ 
+ 	while ((readb_outer_space(lsr) & 0x20) == 0);
+ 	writeb_outer_space(thr, c);
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pmc-sierra/yosemite/setup.c linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/setup.c
+--- linux-2.6.10/arch/mips/pmc-sierra/yosemite/setup.c	2004-12-24 22:33:47.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/setup.c	2004-12-21 03:25:18.000000000 +0100
+@@ -35,6 +35,10 @@
+ #include <linux/sched.h>
+ #include <linux/interrupt.h>
+ #include <linux/timex.h>
++#include <linux/termios.h>
++#include <linux/tty.h>
++#include <linux/serial.h>
++#include <linux/serial_core.h>
+ 
+ #include <asm/time.h>
+ #include <asm/bootinfo.h>
+@@ -45,84 +49,80 @@
+ #include <asm/ptrace.h>
+ #include <asm/reboot.h>
+ #include <asm/serial.h>
+-#include <linux/termios.h>
+-#include <linux/tty.h>
+-#include <linux/serial.h>
+-#include <linux/serial_core.h>
+ #include <asm/titan_dep.h>
++#include <asm/m48t37.h>
+ 
+ #include "setup.h"
+ 
+ unsigned char titan_ge_mac_addr_base[6] = {
+-	0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00
++	// 0x00, 0x03, 0xcc, 0x1d, 0x22, 0x00
++	0x00, 0xe0, 0x04, 0x00, 0x00, 0x21
+ };
+ 
+ unsigned long cpu_clock;
+ unsigned long yosemite_base;
+ 
++static struct m48t37_rtc *m48t37_base;
++
+ void __init bus_error_init(void)
+ {
+ 	/* Do nothing */
+ }
+ 
++
+ unsigned long m48t37y_get_time(void)
+ {
+-	//unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE;
+-	unsigned char *rtc_base = (unsigned char *) 0xfc000000UL;
+ 	unsigned int year, month, day, hour, min, sec;
+-return;
+ 
+ 	/* Stop the update to the time */
+-	rtc_base[0x7ff8] = 0x40;
++	m48t37_base->control = 0x40;
+ 
+-	year = BCD2BIN(rtc_base[0x7fff]);
+-	year += BCD2BIN(rtc_base[0x7fff1]) * 100;
++	year = BCD2BIN(m48t37_base->year);
++	year += BCD2BIN(m48t37_base->century) * 100;
+ 
+-	month = BCD2BIN(rtc_base[0x7ffe]);
+-	day = BCD2BIN(rtc_base[0x7ffd]);
+-	hour = BCD2BIN(rtc_base[0x7ffb]);
+-	min = BCD2BIN(rtc_base[0x7ffa]);
+-	sec = BCD2BIN(rtc_base[0x7ff9]);
++	month = BCD2BIN(m48t37_base->month);
++	day = BCD2BIN(m48t37_base->date);
++	hour = BCD2BIN(m48t37_base->hour);
++	min = BCD2BIN(m48t37_base->min);
++	sec = BCD2BIN(m48t37_base->sec);
+ 
+ 	/* Start the update to the time again */
+-	rtc_base[0x7ff8] = 0x00;
++	m48t37_base->control = 0x00;
+ 
+ 	return mktime(year, month, day, hour, min, sec);
+ }
+ 
+ int m48t37y_set_time(unsigned long sec)
+ {
+-	unsigned char *rtc_base = (unsigned char *) YOSEMITE_RTC_BASE;
+ 	struct rtc_time tm;
+-return;
+ 
+ 	/* convert to a more useful format -- note months count from 0 */
+ 	to_tm(sec, &tm);
+ 	tm.tm_mon += 1;
+ 
+ 	/* enable writing */
+-	rtc_base[0x7ff8] = 0x80;
++	m48t37_base->control = 0x80;
+ 
+ 	/* year */
+-	rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
+-	rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
++	m48t37_base->year = BIN2BCD(tm.tm_year % 100);
++	m48t37_base->century = BIN2BCD(tm.tm_year / 100);
+ 
+ 	/* month */
+-	rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
++	m48t37_base->month = BIN2BCD(tm.tm_mon);
+ 
+ 	/* day */
+-	rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
++	m48t37_base->date = BIN2BCD(tm.tm_mday);
+ 
+ 	/* hour/min/sec */
+-	rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
+-	rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
+-	rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
++	m48t37_base->hour = BIN2BCD(tm.tm_hour);
++	m48t37_base->min = BIN2BCD(tm.tm_min);
++	m48t37_base->sec = BIN2BCD(tm.tm_sec);
+ 
+ 	/* day of week -- not really used, but let's keep it up-to-date */
+-	rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
++	m48t37_base->day = BIN2BCD(tm.tm_wday + 1);
+ 
+ 	/* disable writing */
+-	rtc_base[0x7ff8] = 0x00;
++	m48t37_base->control = 0x00;
+ 
+ 	return 0;
+ }
+@@ -136,13 +136,9 @@ void yosemite_time_init(void)
+ {
+ 	board_timer_setup = yosemite_timer_setup;
+ 	mips_hpt_frequency = cpu_clock / 2;
+-
+-	rtc_get_time = m48t37y_get_time;
+-	rtc_set_time = m48t37y_set_time;
++mips_hpt_frequency = 33000000 * 3 * 5;
+ }
+ 
+-unsigned long uart_base = 0xfd000000L;
+-
+ /* No other usable initialization hook than this ...  */
+ extern void (*late_time_init)(void);
+ 
+@@ -161,16 +157,18 @@ EXPORT_SYMBOL(ocd_base);
+ 
+ static void __init py_map_ocd(void)
+ {
+-        struct uart_port up;
+-
+-	/*
+-	 * Not specifically interrupt stuff but in case of SMP core_send_ipi
+-	 * needs this first so I'm mapping it here ...
+-	 */
+ 	ocd_base = (unsigned long) ioremap(OCD_BASE, OCD_SIZE);
+ 	if (!ocd_base)
+ 		panic("Mapping OCD failed - game over.  Your score is 0.");
+ 
++	/* Kludge for PMON bug ... */
++	OCD_WRITE(0x0710, 0x0ffff029);
++}
++
++static void __init py_uart_setup(void)
++{
++	struct uart_port up;
++
+ 	/*
+ 	 * Register to interrupt zero because we share the interrupt with
+ 	 * the serial driver which we don't properly support yet.
+@@ -188,12 +186,36 @@ static void __init py_map_ocd(void)
+ 		printk(KERN_ERR "Early serial init of port 0 failed\n");
+ }
+ 
+-static int __init pmc_yosemite_setup(void)
++static void __init py_rtc_setup(void)
++{
++	m48t37_base = ioremap(YOSEMITE_RTC_BASE, YOSEMITE_RTC_SIZE);
++	if (!m48t37_base)
++		printk(KERN_ERR "Mapping the RTC failed\n");
++
++	rtc_get_time = m48t37y_get_time;
++	rtc_set_time = m48t37y_set_time;
++
++	write_seqlock(&xtime_lock);
++	xtime.tv_sec = m48t37y_get_time();
++	xtime.tv_nsec = 0;
++
++	set_normalized_timespec(&wall_to_monotonic,
++	                        -xtime.tv_sec, -xtime.tv_nsec);
++	write_sequnlock(&xtime_lock);
++}
++
++/* Not only time init but that's what the hook it's called through is named */
++static void __init py_late_time_init(void)
+ {
+-	extern void pmon_smp_bootstrap(void);
++	py_map_ocd();
++	py_uart_setup();
++	py_rtc_setup();
++}
+ 
++static int __init pmc_yosemite_setup(void)
++{
+ 	board_time_init = yosemite_time_init;
+-	late_time_init = py_map_ocd;
++	late_time_init = py_late_time_init;
+ 
+ 	/* Add memory regions */
+ 	add_memory_region(0x00000000, 0x10000000, BOOT_MEM_RAM);
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pmc-sierra/yosemite/setup.h linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/setup.h
+--- linux-2.6.10/arch/mips/pmc-sierra/yosemite/setup.h	2004-12-24 22:34:44.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/setup.h	2004-12-21 03:25:18.000000000 +0100
+@@ -1,6 +1,7 @@
+ /*
+- * Copyright 2003 PMC-Sierra
++ * Copyright 2003, 04 PMC-Sierra
+  * Author: Manish Lachwani (lachwani at pmc-sierra.com)
++ * Copyright 2004 Ralf Baechle <ralf at linux-mips.org>
+  *
+  * Board specific definititions for the PMC-Sierra Yosemite
+  *
+@@ -12,9 +13,9 @@
+ #ifndef __SETUP_H__
+ #define __SETUP_H__
+ 
+-/* NVRAM Base */
+-#define	YOSEMITE_NVRAM_BASE_ADDR	0xbb000678	/* XXX Need change */
+-#define	YOSEMITE_RTC_BASE		0xbb000679	/* XXX Need change */
++/* M48T37 RTC + NVRAM */
++#define	YOSEMITE_RTC_BASE		0xfc800000
++#define	YOSEMITE_RTC_SIZE		0x00800000
+ 
+ #define HYPERTRANSPORT_BAR0_ADDR        0x00000006
+ #define HYPERTRANSPORT_SIZE0            0x0fffffff
+diff -urpNX dontdiff linux-2.6.10/arch/mips/pmc-sierra/yosemite/smp.c linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/smp.c
+--- linux-2.6.10/arch/mips/pmc-sierra/yosemite/smp.c	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/pmc-sierra/yosemite/smp.c	2004-12-21 03:25:18.000000000 +0100
+@@ -4,6 +4,9 @@
+ #include <asm/pmon.h>
+ #include <asm/titan_dep.h>
+ 
++extern unsigned int (*mips_hpt_read)(void);
++extern void (*mips_hpt_init)(unsigned int);
++
+ #define LAUNCHSTACK_SIZE 256
+ 
+ static spinlock_t launch_lock __initdata;
+@@ -37,8 +40,8 @@ void __init prom_grab_secondary(void)
+ {
+ 	spin_lock(&launch_lock);
+ 
+-	debug_vectors->cpustart(1, &prom_smp_bootstrap,
+-	                        launchstack + LAUNCHSTACK_SIZE, 0);
++	pmon_cpustart(1, &prom_smp_bootstrap,
++	              launchstack + LAUNCHSTACK_SIZE, 0);
+ }
+ 
+ /*
+@@ -47,23 +50,38 @@ void __init prom_grab_secondary(void)
+  * We don't want to start the secondary CPU yet nor do we have a nice probing
+  * feature in PMON so we just assume presence of the secondary core.
+  */
+-void prom_prepare_cpus(unsigned int max_cpus)
++static char maxcpus_string[] __initdata =
++	KERN_WARNING "max_cpus set to 0; using 1 instead\n";
++
++void __init prom_prepare_cpus(unsigned int max_cpus)
+ {
++	int enabled = 0, i;
++
++	if (max_cpus == 0) {
++		printk(maxcpus_string);
++		max_cpus = 1;
++	}
++
+ 	cpus_clear(phys_cpu_present_map);
+ 
+-	/*
+-	 * The boot CPU
+-	 */
+-	cpu_set(0, phys_cpu_present_map);
+-	__cpu_number_map[0]	= 0;
+-	__cpu_logical_map[0]	= 0;
++	for (i = 0; i < 2; i++) {
++		if (i == max_cpus)
++			break;
++
++		/*
++		 * The boot CPU
++		 */
++		cpu_set(i, phys_cpu_present_map);
++		__cpu_number_map[i]	= i;
++		__cpu_logical_map[i]	= i;
++		enabled++;
++	}
+ 
+ 	/*
+-	 * The secondary core
++	 * Be paranoid.  Enable the IPI only if we're really about to go SMP.
+ 	 */
+-	cpu_set(1, phys_cpu_present_map);
+-	__cpu_number_map[1]	= 1;
+-	__cpu_logical_map[1]	= 1;
++	if (enabled > 1)
++		set_c0_status(STATUSF_IP5);
+ }
+ 
+ /*
+@@ -95,6 +113,8 @@ void prom_cpus_done(void)
+  */
+ void prom_init_secondary(void)
+ {
++	mips_hpt_init(mips_hpt_read());
++
+ 	set_c0_status(ST0_CO | ST0_IE | ST0_IM);
+ }
+ 
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sgi-ip22/ip22-nvram.c linux-2.6.10-mips/arch/mips/sgi-ip22/ip22-nvram.c
+--- linux-2.6.10/arch/mips/sgi-ip22/ip22-nvram.c	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sgi-ip22/ip22-nvram.c	2004-11-20 02:09:24.000000000 +0100
+@@ -26,7 +26,7 @@
+ #define EEPROM_DATO	0x08	/* Data out */
+ #define EEPROM_DATI	0x10	/* Data in */
+ 
+-/* We need to use this functions early... */
++/* We need to use these functions early... */
+ #define delay()	({						\
+ 	int x;							\
+ 	for (x=0; x<100000; x++) __asm__ __volatile__(""); })
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sgi-ip22/ip22-setup.c linux-2.6.10-mips/arch/mips/sgi-ip22/ip22-setup.c
+--- linux-2.6.10/arch/mips/sgi-ip22/ip22-setup.c	2004-12-24 22:33:50.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sgi-ip22/ip22-setup.c	2004-12-21 03:25:18.000000000 +0100
+@@ -120,9 +120,8 @@ static int __init ip22_setup(void)
+ 	}
+ #endif
+ 
+-#ifdef CONFIG_VT
+-#ifdef CONFIG_SGI_NEWPORT_CONSOLE
+-	if (ctype && *ctype == 'g'){
++#if defined(CONFIG_VT) && defined(CONFIG_SGI_NEWPORT_CONSOLE)
++	{
+ 		ULONG *gfxinfo;
+ 		ULONG * (*__vec)(void) = (void *) (long)
+ 			*((_PULONG *)(long)((PROMBLOCK)->pvector + 0x20));
+@@ -138,7 +137,6 @@ static int __init ip22_setup(void)
+ 		}
+ 	}
+ #endif
+-#endif
+ 
+ 	return 0;
+ }
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sgi-ip27/Makefile linux-2.6.10-mips/arch/mips/sgi-ip27/Makefile
+--- linux-2.6.10/arch/mips/sgi-ip27/Makefile	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sgi-ip27/Makefile	2004-12-28 20:06:24.000000000 +0100
+@@ -6,6 +6,7 @@ obj-y	:= ip27-berr.o ip27-console.o ip27
+ 	   ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \
+ 	   ip27-timer.o ip27-hubio.o ip27-xtalk.o
+ 
++obj-$(CONFIG_KGDB)	+= ip27-dbgio.o
+ obj-$(CONFIG_SMP)	+= ip27-smp.o
+ 
+ EXTRA_AFLAGS := $(CFLAGS)
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sgi-ip27/ip27-dbgio.c linux-2.6.10-mips/arch/mips/sgi-ip27/ip27-dbgio.c
+--- linux-2.6.10/arch/mips/sgi-ip27/ip27-dbgio.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sgi-ip27/ip27-dbgio.c	2004-12-28 08:50:21.000000000 +0100
+@@ -0,0 +1,60 @@
++/*
++ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  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.
++ *
++ * Copyright 2004 Ralf Baechle <ralf at linux-mips.org>
++ */
++#include <asm/sn/addrs.h>
++#include <asm/sn/sn0/hub.h>
++#include <asm/sn/klconfig.h>
++#include <asm/sn/ioc3.h>
++#include <asm/sn/sn_private.h>
++
++#include <linux/serial.h>
++#include <linux/serial_core.h>
++#include <linux/serial_reg.h>
++
++#define IOC3_CLK        (22000000 / 3)
++#define IOC3_FLAGS      (0)
++
++static inline struct ioc3_uartregs *console_uart(void)
++{
++	struct ioc3 *ioc3;
++
++	ioc3 = (struct ioc3 *)KL_CONFIG_CH_CONS_INFO(get_nasid())->memory_base;
++
++	return &ioc3->sregs.uarta;
++}
++
++unsigned char getDebugChar(void)
++{
++	struct ioc3_uartregs *uart = console_uart();
++
++	while ((uart->iu_lsr & UART_LSR_DR) == 0);
++	return uart->iu_rbr;
++}
++
++void putDebugChar(unsigned char c)
++{
++	struct ioc3_uartregs *uart = console_uart();
++
++	while ((uart->iu_lsr & UART_LSR_THRE) == 0);
++	uart->iu_thr = c;
++}
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sgi-ip27/ip27-init.c linux-2.6.10-mips/arch/mips/sgi-ip27/ip27-init.c
+--- linux-2.6.10/arch/mips/sgi-ip27/ip27-init.c	2004-12-24 22:35:29.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sgi-ip27/ip27-init.c	2004-12-28 20:06:24.000000000 +0100
+@@ -78,15 +78,14 @@ static void __init per_hub_init(cnodeid_
+ 	 * copy over the caliased exception handlers.
+ 	 */
+ 	if (get_compact_nodeid() == cnode) {
+-		extern char except_vec0, except_vec1_r4k;
+ 		extern char except_vec2_generic, except_vec3_generic;
++		extern void build_tlb_refill_handler(void);
+ 
+-		memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80);
+-		memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x80);
+-		memcpy((void *)KSEG0, &except_vec0, 0x80);
+-		memcpy((void *)KSEG0 + 0x080, &except_vec1_r4k, 0x80);
+-		memcpy((void *)(KSEG0 + 0x100), (void *) KSEG0, 0x80);
+-		memcpy((void *)(KSEG0 + 0x180), &except_vec3_generic, 0x100);
++		memcpy((void *)(CKSEG0 + 0x100), &except_vec2_generic, 0x80);
++		memcpy((void *)(CKSEG0 + 0x180), &except_vec3_generic, 0x80);
++		build_tlb_refill_handler();
++		memcpy((void *)(CKSEG0 + 0x100), (void *) CKSEG0, 0x80);
++		memcpy((void *)(CKSEG0 + 0x180), &except_vec3_generic, 0x100);
+ 		__flush_cache_all();
+ 	}
+ #endif
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sgi-ip27/ip27-irq-glue.S linux-2.6.10-mips/arch/mips/sgi-ip27/ip27-irq-glue.S
+--- linux-2.6.10/arch/mips/sgi-ip27/ip27-irq-glue.S	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sgi-ip27/ip27-irq-glue.S	2005-01-09 13:23:56.000000000 +0100
+@@ -21,7 +21,7 @@ NESTED(ip27_irq, PT_SIZE, sp)
+ 	mfc0	t0, CP0_STATUS
+ 	and	s0, t0
+ 	move	a0, sp
+-	la	ra, ret_from_irq
++	PTR_LA	ra, ret_from_irq
+ 
+ 	/* First check for RT interrupt.  */
+ 	andi	t0, s0, CAUSEF_IP4
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sgi-ip27/ip27-klnuma.c linux-2.6.10-mips/arch/mips/sgi-ip27/ip27-klnuma.c
+--- linux-2.6.10/arch/mips/sgi-ip27/ip27-klnuma.c	2004-12-24 22:34:31.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sgi-ip27/ip27-klnuma.c	2005-01-09 13:23:56.000000000 +0100
+@@ -124,12 +124,12 @@ void __init replicate_kernel_text(int ma
+  */
+ pfn_t node_getfirstfree(cnodeid_t cnode)
+ {
+-	unsigned long loadbase = CKSEG0;
++	unsigned long loadbase = REP_BASE;
+ 	nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode);
+ 	unsigned long offset;
+ 
+ #ifdef CONFIG_MAPPED_KERNEL
+-	loadbase = CKSSEG + 16777216;
++	loadbase += 16777216;
+ #endif
+ 	offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase;
+ 	if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask)))
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sgi-ip32/ip32-reset.c linux-2.6.10-mips/arch/mips/sgi-ip32/ip32-reset.c
+--- linux-2.6.10/arch/mips/sgi-ip32/ip32-reset.c	2004-12-24 22:35:25.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sgi-ip32/ip32-reset.c	2005-01-10 02:13:59.000000000 +0100
+@@ -189,11 +189,13 @@ static __init int ip32_reboot_setup(void
+ 	_machine_restart = ip32_machine_restart;
+ 	_machine_halt = ip32_machine_halt;
+ 	_machine_power_off = ip32_machine_power_off;
+-	request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL);
++
+ 	init_timer(&blink_timer);
+ 	blink_timer.function = blink_timeout;
+ 	notifier_chain_register(&panic_notifier_list, &panic_block);
+ 
++	request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL);
++
+ 	return 0;
+ }
+ 
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sibyte/sb1250/bcm1250_tbprof.c linux-2.6.10-mips/arch/mips/sibyte/sb1250/bcm1250_tbprof.c
+--- linux-2.6.10/arch/mips/sibyte/sb1250/bcm1250_tbprof.c	2004-12-24 22:34:32.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sibyte/sb1250/bcm1250_tbprof.c	2004-12-21 03:25:18.000000000 +0100
+@@ -64,24 +64,24 @@ static void arm_tb(void)
+ 	u_int64_t tb_options = M_SCD_TRACE_CFG_FREEZE_FULL;
+ 	/* Generate an SCD_PERFCNT interrupt in TB_PERIOD Zclks to
+ 	   trigger start of trace.  XXX vary sampling period */
+-	__raw_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
+-	scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
++	bus_writeq(0, IOADDR(A_SCD_PERF_CNT_1));
++	scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+ 	/* Unfortunately, in Pass 2 we must clear all counters to knock down
+ 	   a previous interrupt request.  This means that bus profiling
+ 	   requires ALL of the SCD perf counters. */
+-	__raw_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is
++	bus_writeq((scdperfcnt & ~M_SPC_CFG_SRC1) | // keep counters 0,2,3 as is
+ 		   M_SPC_CFG_ENABLE |		 // enable counting
+ 		   M_SPC_CFG_CLEAR |		 // clear all counters
+ 		   V_SPC_CFG_SRC1(1),		 // counter 1 counts cycles
+-	      IOADDR(A_SCD_PERF_CNT_CFG));
+-	__raw_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
++		   IOADDR(A_SCD_PERF_CNT_CFG));
++	bus_writeq(next, IOADDR(A_SCD_PERF_CNT_1));
+ 	/* Reset the trace buffer */
+-	__raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
++	bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ #if 0 && defined(M_SCD_TRACE_CFG_FORCECNT)
+ 	/* XXXKW may want to expose control to the data-collector */
+ 	tb_options |= M_SCD_TRACE_CFG_FORCECNT;
+ #endif
+-	__raw_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG));
++	bus_writeq(tb_options, IOADDR(A_SCD_TRACE_CFG));
+ 	sbp.tb_armed = 1;
+ }
+ 
+@@ -93,22 +93,23 @@ static irqreturn_t sbprof_tb_intr(int ir
+ 		/* XXX should use XKPHYS to make writes bypass L2 */
+ 		u_int64_t *p = sbp.sbprof_tbbuf[sbp.next_tb_sample++];
+ 		/* Read out trace */
+-		__raw_writeq(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
++		bus_writeq(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
+ 		__asm__ __volatile__ ("sync" : : : "memory");
+ 		/* Loop runs backwards because bundles are read out in reverse order */
+ 		for (i = 256 * 6; i > 0; i -= 6) {
+ 			// Subscripts decrease to put bundle in the order
+ 			//   t0 lo, t0 hi, t1 lo, t1 hi, t2 lo, t2 hi
+-			p[i-1] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 hi
+-			p[i-2] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 lo
+-			p[i-3] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 hi
+-			p[i-4] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 lo
+-			p[i-5] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 hi
+-			p[i-6] = __raw_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 lo
++			p[i-1] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 hi
++			p[i-2] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t2 lo
++			p[i-3] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 hi
++			p[i-4] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t1 lo
++			p[i-5] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 hi
++			p[i-6] = bus_readq(IOADDR(A_SCD_TRACE_READ)); // read t0 lo
+ 		}
+ 		if (!sbp.tb_enable) {
+ 			DBG(printk(DEVNAME ": tb_intr shutdown\n"));
+-			__raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
++			bus_writeq(M_SCD_TRACE_CFG_RESET,
++				   IOADDR(A_SCD_TRACE_CFG));
+ 			sbp.tb_armed = 0;
+ 			wake_up(&sbp.tb_sync);
+ 		} else {
+@@ -117,7 +118,7 @@ static irqreturn_t sbprof_tb_intr(int ir
+ 	} else {
+ 		/* No more trace buffer samples */
+ 		DBG(printk(DEVNAME ": tb_intr full\n"));
+-		__raw_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
++		bus_writeq(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ 		sbp.tb_armed = 0;
+ 		if (!sbp.tb_enable) {
+ 			wake_up(&sbp.tb_sync);
+@@ -151,13 +152,13 @@ int sbprof_zbprof_start(struct file *fil
+ 		return -EBUSY;
+ 	}
+ 	/* Make sure there isn't a perf-cnt interrupt waiting */
+-	scdperfcnt = __raw_readq(IOADDR(A_SCD_PERF_CNT_CFG));
++	scdperfcnt = bus_readq(IOADDR(A_SCD_PERF_CNT_CFG));
+ 	/* Disable and clear counters, override SRC_1 */
+-	__raw_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) |
++	bus_writeq((scdperfcnt & ~(M_SPC_CFG_SRC1 | M_SPC_CFG_ENABLE)) |
+ 		   M_SPC_CFG_ENABLE |
+ 		   M_SPC_CFG_CLEAR |
+ 		   V_SPC_CFG_SRC1(1),
+-	      IOADDR(A_SCD_PERF_CNT_CFG));
++		   IOADDR(A_SCD_PERF_CNT_CFG));
+ 
+ 	/* We grab this interrupt to prevent others from trying to use
+            it, even though we don't want to service the interrupts
+@@ -171,52 +172,55 @@ int sbprof_zbprof_start(struct file *fil
+ 	/* I need the core to mask these, but the interrupt mapper to
+ 	   pass them through.  I am exploiting my knowledge that
+ 	   cp0_status masks out IP[5]. krw */
+-	__raw_writeq(K_INT_MAP_I3,
+-		     IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) + (K_INT_PERF_CNT<<3)));
++	bus_writeq(K_INT_MAP_I3,
++		   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
++			  (K_INT_PERF_CNT << 3)));
+ 
+ 	/* Initialize address traps */
+-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_0));
+-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_1));
+-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_2));
+-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_UP_3));
+-
+-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0));
+-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1));
+-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2));
+-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3));
+-
+-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0));
+-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1));
+-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2));
+-	__raw_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
++	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_0));
++	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_1));
++	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_2));
++	bus_writeq(0, IOADDR(A_ADDR_TRAP_UP_3));
++
++	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_0));
++	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_1));
++	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_2));
++	bus_writeq(0, IOADDR(A_ADDR_TRAP_DOWN_3));
++
++	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_0));
++	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_1));
++	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_2));
++	bus_writeq(0, IOADDR(A_ADDR_TRAP_CFG_3));
+ 
+ 	/* Initialize Trace Event 0-7 */
+ 	//				when interrupt
+-	__raw_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
++	bus_writeq(M_SCD_TREVT_INTERRUPT, IOADDR(A_SCD_TRACE_EVENT_0));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_1));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_2));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_3));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_4));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_5));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_6));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_EVENT_7));
+ 
+ 	/* Initialize Trace Sequence 0-7 */
+ 	//				     Start on event 0 (interrupt)
+-	__raw_writeq(V_SCD_TRSEQ_FUNC_START|0x0fff,
+-		     IOADDR(A_SCD_TRACE_SEQUENCE_0));
++	bus_writeq(V_SCD_TRSEQ_FUNC_START | 0x0fff,
++		   IOADDR(A_SCD_TRACE_SEQUENCE_0));
+ 	//			  dsamp when d used | asamp when a used
+-	__raw_writeq(M_SCD_TRSEQ_ASAMPLE|M_SCD_TRSEQ_DSAMPLE|K_SCD_TRSEQ_TRIGGER_ALL,
+-		     IOADDR(A_SCD_TRACE_SEQUENCE_1));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6));
+-	__raw_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7));
++	bus_writeq(M_SCD_TRSEQ_ASAMPLE | M_SCD_TRSEQ_DSAMPLE |
++		   K_SCD_TRSEQ_TRIGGER_ALL,
++		   IOADDR(A_SCD_TRACE_SEQUENCE_1));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_2));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_3));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_4));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_5));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_6));
++	bus_writeq(0, IOADDR(A_SCD_TRACE_SEQUENCE_7));
+ 
+ 	/* Now indicate the PERF_CNT interrupt as a trace-relevant interrupt */
+-	__raw_writeq((1ULL << K_INT_PERF_CNT), IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)));
++	bus_writeq((1ULL << K_INT_PERF_CNT),
++		   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_TRACE)));
+ 
+ 	arm_tb();
+ 
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sibyte/sb1250/bus_watcher.c linux-2.6.10-mips/arch/mips/sibyte/sb1250/bus_watcher.c
+--- linux-2.6.10/arch/mips/sibyte/sb1250/bus_watcher.c	2004-12-24 22:34:44.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sibyte/sb1250/bus_watcher.c	2004-12-21 03:25:18.000000000 +0100
+@@ -188,7 +188,8 @@ static irqreturn_t sibyte_bw_int(int irq
+ 	csr_out32(M_SCD_TRACE_CFG_START_READ, IOADDR(A_SCD_TRACE_CFG));
+ 
+ 	for (i=0; i<256*6; i++)
+-		printk("%016llx\n", (unsigned long long)__raw_readq(IOADDR(A_SCD_TRACE_READ)));
++		printk("%016llx\n",
++		       (unsigned long long)bus_readq(IOADDR(A_SCD_TRACE_READ)));
+ 
+ 	csr_out32(M_SCD_TRACE_CFG_RESET, IOADDR(A_SCD_TRACE_CFG));
+ 	csr_out32(M_SCD_TRACE_CFG_START, IOADDR(A_SCD_TRACE_CFG));
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sibyte/sb1250/irq.c linux-2.6.10-mips/arch/mips/sibyte/sb1250/irq.c
+--- linux-2.6.10/arch/mips/sibyte/sb1250/irq.c	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sibyte/sb1250/irq.c	2004-12-21 03:25:18.000000000 +0100
+@@ -96,9 +96,11 @@ void sb1250_mask_irq(int cpu, int irq)
+ 	u64 cur_ints;
+ 
+ 	spin_lock_irqsave(&sb1250_imr_lock, flags);
+-	cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK));
++	cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
++				      R_IMR_INTERRUPT_MASK));
+ 	cur_ints |= (((u64) 1) << irq);
+-	____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK));
++	__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
++				      R_IMR_INTERRUPT_MASK));
+ 	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+ }
+ 
+@@ -108,9 +110,11 @@ void sb1250_unmask_irq(int cpu, int irq)
+ 	u64 cur_ints;
+ 
+ 	spin_lock_irqsave(&sb1250_imr_lock, flags);
+-	cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK));
++	cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
++				      R_IMR_INTERRUPT_MASK));
+ 	cur_ints &= ~(((u64) 1) << irq);
+-	____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK));
++	__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
++				      R_IMR_INTERRUPT_MASK));
+ 	spin_unlock_irqrestore(&sb1250_imr_lock, flags);
+ }
+ 
+@@ -145,19 +149,23 @@ static void sb1250_set_affinity(unsigned
+ 
+ 	/* Swizzle each CPU's IMR (but leave the IP selection alone) */
+ 	old_cpu = sb1250_irq_owner[irq];
+-	cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(old_cpu) + R_IMR_INTERRUPT_MASK));
++	cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(old_cpu) +
++			       R_IMR_INTERRUPT_MASK));
+ 	int_on = !(cur_ints & (((u64) 1) << irq));
+ 	if (int_on) {
+ 		/* If it was on, mask it */
+ 		cur_ints |= (((u64) 1) << irq);
+-		____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) + R_IMR_INTERRUPT_MASK));
++		__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(old_cpu) +
++					      R_IMR_INTERRUPT_MASK));
+ 	}
+ 	sb1250_irq_owner[irq] = cpu;
+ 	if (int_on) {
+ 		/* unmask for the new CPU */
+-		cur_ints = ____raw_readq(IOADDR(A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK));
++		cur_ints = __bus_readq(IOADDR(A_IMR_MAPPER(cpu) +
++				       R_IMR_INTERRUPT_MASK));
+ 		cur_ints &= ~(((u64) 1) << irq);
+-		____raw_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) + R_IMR_INTERRUPT_MASK));
++		__bus_writeq(cur_ints, IOADDR(A_IMR_MAPPER(cpu) +
++					      R_IMR_INTERRUPT_MASK));
+ 	}
+ 	spin_unlock(&sb1250_imr_lock);
+ 	spin_unlock_irqrestore(&desc->lock, flags);
+@@ -200,8 +208,8 @@ static void ack_sb1250_irq(unsigned int 
+ 	 * deliver the interrupts to all CPUs (which makes affinity
+ 	 * changing easier for us)
+ 	 */
+-	pending = __raw_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
+-						    R_IMR_LDT_INTERRUPT)));
++	pending = bus_readq(IOADDR(A_IMR_REGISTER(sb1250_irq_owner[irq],
++						  R_IMR_LDT_INTERRUPT)));
+ 	pending &= ((u64)1 << (irq));
+ 	if (pending) {
+ 		int i;
+@@ -216,8 +224,9 @@ static void ack_sb1250_irq(unsigned int 
+ 			 * Clear for all CPUs so an affinity switch
+ 			 * doesn't find an old status
+ 			 */
+-			__raw_writeq(pending, 
+-				     IOADDR(A_IMR_REGISTER(cpu, R_IMR_LDT_INTERRUPT_CLR)));
++			bus_writeq(pending, 
++				   IOADDR(A_IMR_REGISTER(cpu,
++						R_IMR_LDT_INTERRUPT_CLR)));
+ 		}
+ 
+ 		/*
+@@ -331,14 +340,12 @@ void __init arch_init_irq(void)
+ 
+ 	/* Default everything to IP2 */
+ 	for (i = 0; i < SB1250_NR_IRQS; i++) {	/* was I0 */
+-		__raw_writeq(IMR_IP2_VAL,
+-			     IOADDR(A_IMR_REGISTER(0,
+-						   R_IMR_INTERRUPT_MAP_BASE) +
+-				    (i << 3)));
+-		__raw_writeq(IMR_IP2_VAL,
+-			     IOADDR(A_IMR_REGISTER(1,
+-						    R_IMR_INTERRUPT_MAP_BASE) +
+-				    (i << 3)));
++		bus_writeq(IMR_IP2_VAL,
++			   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
++				  (i << 3)));
++		bus_writeq(IMR_IP2_VAL,
++			   IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
++				  (i << 3)));
+ 	}
+ 
+ 	init_sb1250_irqs();
+@@ -348,21 +355,23 @@ void __init arch_init_irq(void)
+ 	 * inter-cpu messages
+ 	 */
+ 	/* Was I1 */
+-	__raw_writeq(IMR_IP3_VAL, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+-					 (K_INT_MBOX_0 << 3)));
+-	__raw_writeq(IMR_IP3_VAL, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
+-					 (K_INT_MBOX_0 << 3)));
++	bus_writeq(IMR_IP3_VAL,
++		   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
++			  (K_INT_MBOX_0 << 3)));
++	bus_writeq(IMR_IP3_VAL,
++		   IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MAP_BASE) +
++			  (K_INT_MBOX_0 << 3)));
+ 
+ 	/* Clear the mailboxes.  The firmware may leave them dirty */
+-	__raw_writeq(0xffffffffffffffff,
+-		     IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
+-	__raw_writeq(0xffffffffffffffff,
+-		     IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
++	bus_writeq(0xffffffffffffffffULL,
++		   IOADDR(A_IMR_REGISTER(0, R_IMR_MAILBOX_CLR_CPU)));
++	bus_writeq(0xffffffffffffffffULL,
++		   IOADDR(A_IMR_REGISTER(1, R_IMR_MAILBOX_CLR_CPU)));
+ 
+ 	/* Mask everything except the mailbox registers for both cpus */
+ 	tmp = ~((u64) 0) ^ (((u64) 1) << K_INT_MBOX_0);
+-	__raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
+-	__raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
++	bus_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
++	bus_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
+ 
+ 	sb1250_steal_irq(K_INT_MBOX_0);
+ 
+@@ -387,12 +396,12 @@ void __init arch_init_irq(void)
+ 		sb1250_duart_present[kgdb_port] = 0;
+ #endif
+ 		/* Setup uart 1 settings, mapper */
+-		__raw_writeq(M_DUART_IMR_BRK, IOADDR(A_DUART_IMRREG(kgdb_port)));
++		bus_writeq(M_DUART_IMR_BRK, IOADDR(A_DUART_IMRREG(kgdb_port)));
+ 
+ 		sb1250_steal_irq(kgdb_irq);
+-		__raw_writeq(IMR_IP6_VAL,
+-			     IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
+-				    (kgdb_irq<<3)));
++		bus_writeq(IMR_IP6_VAL,
++			   IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MAP_BASE) +
++				  (kgdb_irq<<3)));
+ 		sb1250_unmask_irq(0, kgdb_irq);
+ 	}
+ #endif
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sibyte/sb1250/irq_handler.S linux-2.6.10-mips/arch/mips/sibyte/sb1250/irq_handler.S
+--- linux-2.6.10/arch/mips/sibyte/sb1250/irq_handler.S	2004-12-24 22:34:44.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sibyte/sb1250/irq_handler.S	2004-12-21 03:25:18.000000000 +0100
+@@ -123,7 +123,7 @@
+ 	 * check the 1250 interrupt registers to figure out what to do
+ 	 * Need to detect which CPU we're on, now that smp_affinity is supported.
+ 	 */
+-	PTR_LA	v0, KSEG1 + A_IMR_CPU0_BASE
++	PTR_LA	v0, CKSEG1 + A_IMR_CPU0_BASE
+ #ifdef CONFIG_SMP
+ 	lw	t1, TI_CPU($28)
+ 	sll	t1, IMR_REGISTER_SPACING_SHIFT
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sibyte/sb1250/setup.c linux-2.6.10-mips/arch/mips/sibyte/sb1250/setup.c
+--- linux-2.6.10/arch/mips/sibyte/sb1250/setup.c	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sibyte/sb1250/setup.c	2004-12-21 03:25:18.000000000 +0100
+@@ -153,7 +153,7 @@ void sb1250_setup(void)
+ 	int bad_config = 0;
+ 
+ 	sb1_pass = read_c0_prid() & 0xff;
+-	sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
++	sys_rev = bus_readq(IOADDR(A_SCD_SYSTEM_REVISION));
+ 	soc_type = SYS_SOC_TYPE(sys_rev);
+ 	soc_pass = G_SYS_REVISION(sys_rev);
+ 
+@@ -162,7 +162,7 @@ void sb1250_setup(void)
+ 		machine_restart(NULL);
+ 	}
+ 
+-	plldiv = G_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
++	plldiv = G_SYS_PLL_DIV(bus_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+ 	zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
+ 
+ 	prom_printf("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n",
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sibyte/sb1250/smp.c linux-2.6.10-mips/arch/mips/sibyte/sb1250/smp.c
+--- linux-2.6.10/arch/mips/sibyte/sb1250/smp.c	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sibyte/sb1250/smp.c	2004-12-21 03:25:18.000000000 +0100
+@@ -73,7 +73,7 @@ void sb1250_smp_finish(void)
+  */
+ void core_send_ipi(int cpu, unsigned int action)
+ {
+-	__raw_writeq((((u64)action)<< 48), mailbox_set_regs[cpu]);
++	bus_writeq((((u64)action) << 48), mailbox_set_regs[cpu]);
+ }
+ 
+ void sb1250_mailbox_interrupt(struct pt_regs *regs)
+@@ -83,10 +83,10 @@ void sb1250_mailbox_interrupt(struct pt_
+ 
+ 	kstat_this_cpu.irqs[K_INT_MBOX_0]++;
+ 	/* Load the mailbox register to figure out what we're supposed to do */
+-	action = (____raw_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
++	action = (__bus_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
+ 
+ 	/* Clear the mailbox to clear the interrupt */
+-	____raw_writeq(((u64)action)<<48, mailbox_clear_regs[cpu]);
++	__bus_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
+ 
+ 	/*
+ 	 * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sibyte/sb1250/time.c linux-2.6.10-mips/arch/mips/sibyte/sb1250/time.c
+--- linux-2.6.10/arch/mips/sibyte/sb1250/time.c	2004-12-24 22:34:58.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sibyte/sb1250/time.c	2004-12-21 03:25:18.000000000 +0100
+@@ -67,21 +67,24 @@ void sb1250_time_init(void)
+ 	sb1250_mask_irq(cpu, irq);
+ 
+ 	/* Map the timer interrupt to ip[4] of this cpu */
+-	__raw_writeq(IMR_IP4_VAL, IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
+-					 (irq << 3)));
++	bus_writeq(IMR_IP4_VAL,
++		   IOADDR(A_IMR_REGISTER(cpu, R_IMR_INTERRUPT_MAP_BASE) +
++			  (irq << 3)));
+ 
+ 	/* the general purpose timer ticks at 1 Mhz independent if the rest of the system */
+ 	/* Disable the timer and set up the count */
+-	__raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
++	bus_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ #ifdef CONFIG_SIMULATION
+-	__raw_writeq(50000 / HZ, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
++	bus_writeq(50000 / HZ,
++		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+ #else
+-	__raw_writeq(1000000/HZ, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
++	bus_writeq(1000000/HZ,
++		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)));
+ #endif
+ 
+ 	/* Set the timer running */
+-	__raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
+-		     IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
++	bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
++		   IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ 
+ 	sb1250_unmask_irq(cpu, irq);
+ 	sb1250_steal_irq(irq);
+@@ -102,8 +105,8 @@ void sb1250_timer_interrupt(struct pt_re
+ 	int irq = K_INT_TIMER_0 + cpu;
+ 
+ 	/* Reset the timer */
+-	____raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
+-		       IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
++	__bus_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
++		     IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ 
+ 	/*
+ 	 * CPU 0 handles the global timer interrupt job
+@@ -127,7 +130,7 @@ void sb1250_timer_interrupt(struct pt_re
+ unsigned long sb1250_gettimeoffset(void)
+ {
+ 	unsigned long count =
+-		__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
++		bus_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
+ 
+ 	return 1000000/HZ - count;
+  }
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sibyte/swarm/rtc_m41t81.c linux-2.6.10-mips/arch/mips/sibyte/swarm/rtc_m41t81.c
+--- linux-2.6.10/arch/mips/sibyte/swarm/rtc_m41t81.c	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sibyte/swarm/rtc_m41t81.c	2004-12-21 13:06:27.000000000 +0100
+@@ -82,57 +82,59 @@
+ #define M41T81REG_SQW	0x13		/* square wave register */
+ 
+ #define M41T81_CCR_ADDRESS	0x68
+-#define SMB_CSR(reg) (IOADDR(A_SMB_REGISTER(1, reg)))
++#define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg))))
+ 
+ static int m41t81_read(uint8_t addr)
+ {
+-	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ 		;
+ 
+-	__raw_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
+-	__raw_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE), SMB_CSR(R_SMB_START));
++	bus_writeq(addr & 0xff, SMB_CSR(R_SMB_CMD));
++	bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR1BYTE),
++		   SMB_CSR(R_SMB_START));
+ 
+-	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ 		;
+ 
+-	__raw_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START));
++	bus_writeq((V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
++		   SMB_CSR(R_SMB_START));
+ 
+-	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ 		;
+ 
+-	if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
++	if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ 		/* Clear error bit by writing a 1 */
+-		__raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
++		bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ 		return -1;
+ 	}
+ 
+-	return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
++	return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+ }
+ 
+ static int m41t81_write(uint8_t addr, int b)
+ {
+-	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ 		;
+ 
+-	__raw_writeq((addr & 0xFF), SMB_CSR(R_SMB_CMD));
+-	__raw_writeq((b & 0xff), SMB_CSR(R_SMB_DATA));
+-	__raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
+-	      SMB_CSR(R_SMB_START));
++	bus_writeq((addr & 0xFF), SMB_CSR(R_SMB_CMD));
++	bus_writeq((b & 0xff), SMB_CSR(R_SMB_DATA));
++	bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_WR2BYTE,
++		   SMB_CSR(R_SMB_START));
+ 
+-	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ 		;
+ 
+-	if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
++	if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+ 		/* Clear error bit by writing a 1 */
+-		__raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
++		bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+ 		return -1;
+ 	} 
+ 
+ 	/* read the same byte again to make sure it is written */
+-	__raw_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
+-	      SMB_CSR(R_SMB_START));
++	bus_writeq(V_SMB_ADDR(M41T81_CCR_ADDRESS) | V_SMB_TT_RD1BYTE,
++		   SMB_CSR(R_SMB_START));
+ 
+-	while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++	while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+ 		;
+ 	
+ 	return 0;
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sibyte/swarm/rtc_xicor1241.c linux-2.6.10-mips/arch/mips/sibyte/swarm/rtc_xicor1241.c
+--- linux-2.6.10/arch/mips/sibyte/swarm/rtc_xicor1241.c	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sibyte/swarm/rtc_xicor1241.c	2004-12-21 13:06:27.000000000 +0100
+@@ -57,50 +57,52 @@
+ 
+ #define X1241_CCR_ADDRESS	0x6F
+ 
+-#define SMB_CSR(reg) (IOADDR(A_SMB_REGISTER(1, reg)))
++#define SMB_CSR(reg) ((u8 *) (IOADDR(A_SMB_REGISTER(1, reg))))
+ 
+ static int xicor_read(uint8_t addr)
+ {
+-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-	__raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+-	__raw_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
+-	__raw_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE), SMB_CSR(R_SMB_START));
++	bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
++	bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
++	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE),
++		   SMB_CSR(R_SMB_START));
+ 
+-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-	__raw_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START));
++	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
++		   SMB_CSR(R_SMB_START));
+ 
+-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
++        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                 /* Clear error bit by writing a 1 */
+-                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
++                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                 return -1;
+         }
+ 
+-	return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
++	return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+ }
+ 
+ static int xicor_write(uint8_t addr, int b)
+ {
+-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-	__raw_writeq(addr, SMB_CSR(R_SMB_CMD));
+-	__raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+-	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+-	      SMB_CSR(R_SMB_START));
++	bus_writeq(addr, SMB_CSR(R_SMB_CMD));
++	bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
++	bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
++		   SMB_CSR(R_SMB_START));
+ 
+-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
++        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                 /* Clear error bit by writing a 1 */
+-                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
++                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                 return -1;
+         } else {
+ 		return 0;
+diff -urpNX dontdiff linux-2.6.10/arch/mips/sibyte/swarm/time.c linux-2.6.10-mips/arch/mips/sibyte/swarm/time.c
+--- linux-2.6.10/arch/mips/sibyte/swarm/time.c	2004-12-24 22:34:29.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/sibyte/swarm/time.c	2004-12-21 03:25:18.000000000 +0100
+@@ -79,46 +79,48 @@ static unsigned int usec_bias = 0;
+ 
+ static int xicor_read(uint8_t addr)
+ {
+-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-	__raw_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
+-	__raw_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
+-	__raw_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE), SMB_CSR(R_SMB_START));
++	bus_writeq((addr >> 8) & 0x7, SMB_CSR(R_SMB_CMD));
++	bus_writeq((addr & 0xff), SMB_CSR(R_SMB_DATA));
++	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR2BYTE),
++		   SMB_CSR(R_SMB_START));
+ 
+-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-	__raw_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE), SMB_CSR(R_SMB_START));
++	bus_writeq((V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_RD1BYTE),
++		   SMB_CSR(R_SMB_START));
+ 
+-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
++        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                 /* Clear error bit by writing a 1 */
+-                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
++                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                 return -1;
+         }
+ 
+-	return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
++	return (bus_readq(SMB_CSR(R_SMB_DATA)) & 0xff);
+ }
+ 
+ static int xicor_write(uint8_t addr, int b)
+ {
+-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-	__raw_writeq(addr, SMB_CSR(R_SMB_CMD));
+-	__raw_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
+-	__raw_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
+-	      SMB_CSR(R_SMB_START));
++	bus_writeq(addr, SMB_CSR(R_SMB_CMD));
++	bus_writeq((addr & 0xff) | ((b & 0xff) << 8), SMB_CSR(R_SMB_DATA));
++	bus_writeq(V_SMB_ADDR(X1241_CCR_ADDRESS) | V_SMB_TT_WR3BYTE,
++		   SMB_CSR(R_SMB_START));
+ 
+-        while (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
++        while (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_BUSY)
+                 ;
+ 
+-        if (__raw_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
++        if (bus_readq(SMB_CSR(R_SMB_STATUS)) & M_SMB_ERROR) {
+                 /* Clear error bit by writing a 1 */
+-                __raw_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
++                bus_writeq(M_SMB_ERROR, SMB_CSR(R_SMB_STATUS));
+                 return -1;
+         } else {
+ 		return 0;
+@@ -226,8 +228,8 @@ void __init swarm_time_init(void)
+ 	/* Establish communication with the Xicor 1241 RTC */
+ 	/* XXXKW how do I share the SMBus with the I2C subsystem? */
+ 
+-	__raw_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
+-	__raw_writeq(0, SMB_CSR(R_SMB_CONTROL));
++	bus_writeq(K_SMB_FREQ_400KHZ, SMB_CSR(R_SMB_FREQ));
++	bus_writeq(0, SMB_CSR(R_SMB_CONTROL));
+ 
+ 	if ((status = xicor_read(X1241REG_SR_RTCF)) < 0) {
+ 		printk("x1241: couldn't detect on SWARM SMBus 1\n");
+diff -urpNX dontdiff linux-2.6.10/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c linux-2.6.10-mips/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c
+--- linux-2.6.10/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c	2005-01-06 00:00:26.000000000 +0100
+@@ -669,7 +669,7 @@ void __init arch_init_irq(void)
+ {
+ 	extern void tx4927_irq_init(void);
+ 
+-	cli();
++	local_irq_disable();
+ 
+ 	tx4927_irq_init();
+ 	toshiba_rbtx4927_irq_ioc_init();
+diff -urpNX dontdiff linux-2.6.10/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c linux-2.6.10-mips/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+--- linux-2.6.10/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c	2005-01-06 00:00:26.000000000 +0100
+@@ -727,7 +727,7 @@ void toshiba_rbtx4927_restart(char *comm
+ 	reg_wr08(RBTX4927_SW_RESET_DO, RBTX4927_SW_RESET_DO_SET);
+ 
+ 	/* do something passive while waiting for reset */
+-	cli();
++	local_irq_disable();
+ 	while (1)
+ 		asm_wait();
+ 
+@@ -738,7 +738,7 @@ void toshiba_rbtx4927_restart(char *comm
+ void toshiba_rbtx4927_halt(void)
+ {
+ 	printk(KERN_NOTICE "System Halted\n");
+-	cli();
++	local_irq_disable();
+ 	while (1) {
+ 		asm_wait();
+ 	}
+diff -urpNX dontdiff linux-2.6.10/arch/mips/vr41xx/common/bcu.c linux-2.6.10-mips/arch/mips/vr41xx/common/bcu.c
+--- linux-2.6.10/arch/mips/vr41xx/common/bcu.c	2004-12-24 22:35:27.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/vr41xx/common/bcu.c	2004-12-02 10:42:33.000000000 +0100
+@@ -30,6 +30,7 @@
+  */
+ #include <linux/init.h>
+ #include <linux/ioport.h>
++#include <linux/kernel.h>
+ #include <linux/smp.h>
+ #include <linux/types.h>
+ 
+diff -urpNX dontdiff linux-2.6.10/arch/mips/vr41xx/common/pmu.c linux-2.6.10-mips/arch/mips/vr41xx/common/pmu.c
+--- linux-2.6.10/arch/mips/vr41xx/common/pmu.c	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/vr41xx/common/pmu.c	2004-12-02 10:42:33.000000000 +0100
+@@ -18,6 +18,7 @@
+  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+  */
+ #include <linux/init.h>
++#include <linux/kernel.h>
+ #include <linux/smp.h>
+ #include <linux/types.h>
+ 
+diff -urpNX dontdiff linux-2.6.10/arch/mips/vr41xx/nec-cmbvr4133/Makefile linux-2.6.10-mips/arch/mips/vr41xx/nec-cmbvr4133/Makefile
+--- linux-2.6.10/arch/mips/vr41xx/nec-cmbvr4133/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/vr41xx/nec-cmbvr4133/Makefile	2004-12-15 15:08:18.000000000 +0100
+@@ -0,0 +1,8 @@
++#
++# Makefile for the NEC-CMBVR4133
++#
++
++obj-y				:= init.o setup.o
++
++obj-$(CONFIG_PCI)		+= m1535plus.o
++obj-$(CONFIG_ROCKHOPPER)	+= irq.o
+diff -urpNX dontdiff linux-2.6.10/arch/mips/vr41xx/nec-cmbvr4133/init.c linux-2.6.10-mips/arch/mips/vr41xx/nec-cmbvr4133/init.c
+--- linux-2.6.10/arch/mips/vr41xx/nec-cmbvr4133/init.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/vr41xx/nec-cmbvr4133/init.c	2004-12-15 15:08:18.000000000 +0100
+@@ -0,0 +1,78 @@
++/*
++ * arch/mips/vr41xx/nec-cmbvr4133/init.c
++ *
++ * PROM library initialisation code for NEC CMB-VR4133 board.
++ *
++ * Author: Yoichi Yuasa <yyuasa at mvista.com, or source at mvista.com> and
++ *         Jun Sun <jsun at mvista.com, or source at mvista.com> and
++ *         Alex Sapkov <asapkov at ru.mvista.com>
++ *
++ * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
++ * the terms of the GNU General Public License version 2. This program
++ * is licensed "as is" without any warranty of any kind, whether express
++ * or implied.
++ *
++ * Support for NEC-CMBVR4133 in 2.6 
++ * Manish Lachwani (mlachwani at mvista.com)
++ */
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++
++#include <asm/bootinfo.h>
++
++#ifdef CONFIG_ROCKHOPPER
++#include <asm/io.h>
++#include <linux/pci.h>
++
++#define PCICONFDREG	0xaf000c14
++#define PCICONFAREG	0xaf000c18
++#endif
++
++const char *get_system_type(void)
++{
++	return "NEC CMB-VR4133";
++}
++
++#ifdef CONFIG_ROCKHOPPER
++void disable_pcnet(void)
++{
++	u32 data;
++
++	/* 
++	 * Workaround for the bug in PMON on VR4133. PMON leaves
++	 * AMD PCNet controller (on Rockhopper) initialized and running in
++	 * bus master mode. We have do disable it before doing any
++	 * further initialization. Or we get problems with PCI bus 2
++	 * and random lockups and crashes.
++	 */
++
++	writel((2 << 16)		|
++	       (PCI_DEVFN(1,0) << 8)	|
++	       (0 & 0xfc)		|
++               1UL,
++	       PCICONFAREG);
++
++	data = readl(PCICONFDREG);
++
++	writel((2 << 16)		|
++	       (PCI_DEVFN(1,0) << 8)	|
++	       (4 & 0xfc)		|
++               1UL,
++	       PCICONFAREG);
++
++	data = readl(PCICONFDREG);
++
++	writel((2 << 16)		|
++	       (PCI_DEVFN(1,0) << 8)	|
++	       (4 & 0xfc)		|
++               1UL,
++	       PCICONFAREG);
++	
++	data &= ~4;
++
++	writel(data, PCICONFDREG);
++}
++#endif
++
+diff -urpNX dontdiff linux-2.6.10/arch/mips/vr41xx/nec-cmbvr4133/irq.c linux-2.6.10-mips/arch/mips/vr41xx/nec-cmbvr4133/irq.c
+--- linux-2.6.10/arch/mips/vr41xx/nec-cmbvr4133/irq.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/vr41xx/nec-cmbvr4133/irq.c	2004-12-15 15:08:18.000000000 +0100
+@@ -0,0 +1,114 @@
++/*
++ * arch/mips/vr41xx/nec-cmbvr4133/irq.c
++ *
++ * Interrupt routines for the NEC CMB-VR4133 board.
++ *
++ * Author: Yoichi Yuasa <yyuasa at mvista.com, or source at mvista.com> and
++ *         Alex Sapkov <asapkov at ru.mvista.com>
++ *
++ * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under
++ * the terms of the GNU General Public License version 2. This program
++ * is licensed "as is" without any warranty of any kind, whether express
++ * or implied.
++ *
++ * Support for NEC-CMBVR4133 in 2.6
++ * Manish Lachwani (mlachwani at mvista.com)
++ */
++#include <linux/bitops.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++
++#include <asm/io.h>
++#include <asm/vr41xx/cmbvr4133.h>
++
++extern void enable_8259A_irq(unsigned int irq);
++extern void disable_8259A_irq(unsigned int irq);
++extern void mask_and_ack_8259A(unsigned int irq);
++extern void init_8259A(int hoge);
++                                                                                                    
++extern int vr4133_rockhopper;
++                                                                                                    
++static unsigned int startup_i8259_irq(unsigned int irq)
++{
++	enable_8259A_irq(irq - I8259_IRQ_BASE);
++	return 0;
++}
++
++static void shutdown_i8259_irq(unsigned int irq)
++{
++	disable_8259A_irq(irq - I8259_IRQ_BASE);
++}
++
++static void enable_i8259_irq(unsigned int irq)
++{
++	enable_8259A_irq(irq - I8259_IRQ_BASE);
++}
++
++static void disable_i8259_irq(unsigned int irq)
++{
++	disable_8259A_irq(irq - I8259_IRQ_BASE);
++}
++
++static void ack_i8259_irq(unsigned int irq)
++{
++	mask_and_ack_8259A(irq - I8259_IRQ_BASE);
++}
++
++static void end_i8259_irq(unsigned int irq)
++{
++	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
++		enable_8259A_irq(irq - I8259_IRQ_BASE);
++}
++
++static struct hw_interrupt_type i8259_irq_type = {
++	.typename       = "XT-PIC",
++	.startup        = startup_i8259_irq,
++	.shutdown       = shutdown_i8259_irq,
++	.enable         = enable_i8259_irq,
++	.disable        = disable_i8259_irq,
++	.ack            = ack_i8259_irq,
++	.end            = end_i8259_irq,
++};
++
++static int i8259_get_irq_number(int irq)
++{
++	unsigned long isr;
++
++	isr = inb(0x20);
++	irq = ffz(~isr);
++	if (irq == 2) {
++		isr = inb(0xa0);
++		irq = 8 + ffz(~isr);
++	}
++
++	if (irq < 0 || irq > 15)
++		return -EINVAL;
++
++	return I8259_IRQ_BASE + irq;
++}
++
++static struct irqaction i8259_slave_cascade = {
++	.handler        = &no_action,
++	.name           = "cascade",
++};
++
++void __init rockhopper_init_irq(void)
++{
++	int i;
++
++	if(!vr4133_rockhopper) {
++		printk(KERN_ERR "Not a Rockhopper Board \n");
++		return;
++	}
++
++	for (i = I8259_IRQ_BASE; i <= I8259_IRQ_LAST; i++)
++		irq_desc[i].handler = &i8259_irq_type;
++
++	setup_irq(I8259_SLAVE_IRQ, &i8259_slave_cascade);
++
++	vr41xx_set_irq_trigger(CMBVR41XX_INTC_PIN, TRIGGER_LEVEL, SIGNAL_THROUGH);
++	vr41xx_set_irq_level(CMBVR41XX_INTC_PIN, LEVEL_HIGH);
++	vr41xx_cascade_irq(CMBVR41XX_INTC_IRQ, i8259_get_irq_number);
++}
+diff -urpNX dontdiff linux-2.6.10/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c linux-2.6.10-mips/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c
+--- linux-2.6.10/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c	2004-12-15 15:08:18.000000000 +0100
+@@ -0,0 +1,250 @@
++/*
++ * arch/mips/vr41xx/nec-cmbvr4133/m1535plus.c
++ *
++ * Initialize for ALi M1535+(included M5229 and M5237).
++ *
++ * Author: Yoichi Yuasa <yyuasa at mvista.com, or source at mvista.com> and
++ *         Alex Sapkov <asapkov at ru.mvista.com>
++ *
++ * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under
++ * the terms of the GNU General Public License version 2. This program
++ * is licensed "as is" without any warranty of any kind, whether express
++ * or implied.
++ *
++ * Support for NEC-CMBVR4133 in 2.6
++ * Author: Manish Lachwani (mlachwani at mvista.com)
++ */
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/serial.h>
++
++#include <asm/vr41xx/cmbvr4133.h>
++#include <linux/pci.h>
++#include <asm/io.h>
++
++#define CONFIG_PORT(port)	((port) ? 0x3f0 : 0x370)
++#define DATA_PORT(port)		((port) ? 0x3f1 : 0x371)
++#define INDEX_PORT(port)	CONFIG_PORT(port)
++
++#define ENTER_CONFIG_MODE(port)				\
++	do {						\
++		outb_p(0x51, CONFIG_PORT(port));	\
++		outb_p(0x23, CONFIG_PORT(port));	\
++	} while(0)
++
++#define SELECT_LOGICAL_DEVICE(port, dev_no)		\
++	do {						\
++		outb_p(0x07, INDEX_PORT(port));		\
++		outb_p((dev_no), DATA_PORT(port));	\
++	} while(0)
++
++#define WRITE_CONFIG_DATA(port,index,data)		\
++	do {						\
++		outb_p((index), INDEX_PORT(port));	\
++		outb_p((data), DATA_PORT(port));	\
++	} while(0)
++
++#define EXIT_CONFIG_MODE(port)	outb(0xbb, CONFIG_PORT(port))
++
++#define PCI_CONFIG_ADDR	KSEG1ADDR(0x0f000c18)
++#define PCI_CONFIG_DATA	KSEG1ADDR(0x0f000c14)
++
++#ifdef CONFIG_BLK_DEV_FD
++
++void __devinit ali_m1535plus_fdc_init(int port)
++{
++	ENTER_CONFIG_MODE(port);
++	SELECT_LOGICAL_DEVICE(port, 0);		/* FDC */
++	WRITE_CONFIG_DATA(port, 0x30, 0x01);	/* FDC: enable */
++	WRITE_CONFIG_DATA(port, 0x60, 0x03);	/* I/O port base: 0x3f0 */
++	WRITE_CONFIG_DATA(port, 0x61, 0xf0);
++	WRITE_CONFIG_DATA(port, 0x70, 0x06);	/* IRQ: 6 */
++	WRITE_CONFIG_DATA(port, 0x74, 0x02);	/* DMA: channel 2 */
++	WRITE_CONFIG_DATA(port, 0xf0, 0x08);
++	WRITE_CONFIG_DATA(port, 0xf1, 0x00);
++	WRITE_CONFIG_DATA(port, 0xf2, 0xff);
++	WRITE_CONFIG_DATA(port, 0xf4, 0x00);
++	EXIT_CONFIG_MODE(port);
++}
++
++#endif
++
++void __devinit ali_m1535plus_parport_init(int port)
++{
++	ENTER_CONFIG_MODE(port);
++	SELECT_LOGICAL_DEVICE(port, 3);		/* Parallel Port */
++	WRITE_CONFIG_DATA(port, 0x30, 0x01);
++	WRITE_CONFIG_DATA(port, 0x60, 0x03);	/* I/O port base: 0x378 */
++	WRITE_CONFIG_DATA(port, 0x61, 0x78);
++	WRITE_CONFIG_DATA(port, 0x70, 0x07);	/* IRQ: 7 */
++	WRITE_CONFIG_DATA(port, 0x74, 0x04);	/* DMA: None */
++	WRITE_CONFIG_DATA(port, 0xf0, 0x8c);	/* IRQ polarity: Active Low */
++	WRITE_CONFIG_DATA(port, 0xf1, 0xc5);
++	EXIT_CONFIG_MODE(port);
++}
++
++void __devinit ali_m1535plus_keyboard_init(int port)
++{
++	ENTER_CONFIG_MODE(port);
++	SELECT_LOGICAL_DEVICE(port, 7);		/* KEYBOARD */
++	WRITE_CONFIG_DATA(port, 0x30, 0x01);	/* KEYBOARD: eable */
++	WRITE_CONFIG_DATA(port, 0x70, 0x01);	/* IRQ: 1 */
++	WRITE_CONFIG_DATA(port, 0x72, 0x0c);	/* PS/2 Mouse IRQ: 12 */
++	WRITE_CONFIG_DATA(port, 0xf0, 0x00);
++	EXIT_CONFIG_MODE(port);
++}
++
++void __devinit ali_m1535plus_hotkey_init(int port)
++{
++	ENTER_CONFIG_MODE(port);
++	SELECT_LOGICAL_DEVICE(port, 0xc);	/* HOTKEY */
++	WRITE_CONFIG_DATA(port, 0x30, 0x00);
++	WRITE_CONFIG_DATA(port, 0xf0, 0x35);
++	WRITE_CONFIG_DATA(port, 0xf1, 0x14);
++	WRITE_CONFIG_DATA(port, 0xf2, 0x11);
++	WRITE_CONFIG_DATA(port, 0xf3, 0x71);
++	WRITE_CONFIG_DATA(port, 0xf5, 0x05);
++	EXIT_CONFIG_MODE(port);
++}
++
++void ali_m1535plus_init(struct pci_dev *dev)
++{
++	pci_write_config_byte(dev, 0x40, 0x18); /* PCI Interface Control */
++	pci_write_config_byte(dev, 0x41, 0xc0); /* PS2 keyb & mouse enable */
++	pci_write_config_byte(dev, 0x42, 0x41); /* ISA bus cycle control */
++	pci_write_config_byte(dev, 0x43, 0x00); /* ISA bus cycle control 2 */
++	pci_write_config_byte(dev, 0x44, 0x5d); /* IDE enable & IRQ 14 */
++	pci_write_config_byte(dev, 0x45, 0x0b); /* PCI int polling mode */
++	pci_write_config_byte(dev, 0x47, 0x00); /* BIOS chip select control */
++
++	/* IRQ routing */
++	pci_write_config_byte(dev, 0x48, 0x03); /* INTA IRQ10, INTB disable */
++	pci_write_config_byte(dev, 0x49, 0x00); /* INTC and INTD disable */
++	pci_write_config_byte(dev, 0x4a, 0x00); /* INTE and INTF disable */
++	pci_write_config_byte(dev, 0x4b, 0x90); /* Audio IRQ11, Modem disable */
++
++	pci_write_config_word(dev, 0x50, 0x4000); /* Parity check IDE enable */
++	pci_write_config_word(dev, 0x52, 0x0000); /* USB & RTC disable */
++	pci_write_config_word(dev, 0x54, 0x0002); /* ??? no info */
++	pci_write_config_word(dev, 0x56, 0x0002); /* PCS1J signal disable */
++
++	pci_write_config_byte(dev, 0x59, 0x00); /* PCSDS */
++	pci_write_config_byte(dev, 0x5a, 0x00);
++	pci_write_config_byte(dev, 0x5b, 0x00);
++	pci_write_config_word(dev, 0x5c, 0x0000);
++	pci_write_config_byte(dev, 0x5e, 0x00);
++	pci_write_config_byte(dev, 0x5f, 0x00);
++	pci_write_config_word(dev, 0x60, 0x0000);
++
++	pci_write_config_byte(dev, 0x6c, 0x00);
++	pci_write_config_byte(dev, 0x6d, 0x48); /* ROM address mapping */
++	pci_write_config_byte(dev, 0x6e, 0x00); /* ??? what for? */
++
++	pci_write_config_byte(dev, 0x70, 0x12); /* Serial IRQ control */
++	pci_write_config_byte(dev, 0x71, 0xEF); /* DMA channel select */
++	pci_write_config_byte(dev, 0x72, 0x03); /* USB IDSEL */
++	pci_write_config_byte(dev, 0x73, 0x00); /* ??? no info */
++
++	/*
++	 * IRQ setup ALi M5237 USB Host Controller
++	 * IRQ: 9
++	 */
++	pci_write_config_byte(dev, 0x74, 0x01); /* USB IRQ9 */
++
++	pci_write_config_byte(dev, 0x75, 0x1f); /* IDE2 IRQ 15  */
++	pci_write_config_byte(dev, 0x76, 0x80); /* ACPI disable */
++	pci_write_config_byte(dev, 0x77, 0x40); /* Modem disable */
++	pci_write_config_dword(dev, 0x78, 0x20000000); /* Pin select 2 */
++	pci_write_config_byte(dev, 0x7c, 0x00); /* Pin select 3 */
++	pci_write_config_byte(dev, 0x81, 0x00); /* ID read/write control */
++	pci_write_config_byte(dev, 0x90, 0x00); /* PCI PM block control */
++	pci_write_config_word(dev, 0xa4, 0x0000); /* PMSCR */
++
++#ifdef CONFIG_BLK_DEV_FD
++	ali_m1535plus_fdc_init(1);
++#endif
++
++	ali_m1535plus_keyboard_init(1);
++	ali_m1535plus_hotkey_init(1);
++}
++
++static inline void ali_config_writeb(u8 reg, u8 val, int devfn)
++{
++	u32 data;
++	int shift;
++
++	writel((1 << 16) | (devfn << 8) | (reg & 0xfc) | 1UL, PCI_CONFIG_ADDR);
++        data = readl(PCI_CONFIG_DATA);
++
++	shift = (reg & 3) << 3;
++	data &= ~(0xff << shift);
++	data |= (((u32)val) << shift);
++
++	writel(data, PCI_CONFIG_DATA);
++}
++
++static inline u8 ali_config_readb(u8 reg, int devfn)
++{
++	u32 data;
++
++	writel((1 << 16) | (devfn << 8) | (reg & 0xfc) | 1UL, PCI_CONFIG_ADDR);
++	data = readl(PCI_CONFIG_DATA);
++
++	return (u8)(data >> ((reg & 3) << 3));
++}
++
++static inline u16 ali_config_readw(u8 reg, int devfn)
++{
++	u32 data;
++
++	writel((1 << 16) | (devfn << 8) | (reg & 0xfc) | 1UL, PCI_CONFIG_ADDR);
++	data = readl(PCI_CONFIG_DATA);
++
++	return (u16)(data >> ((reg & 2) << 3));
++}
++
++int vr4133_rockhopper = 0;
++void __init ali_m5229_preinit(void)
++{
++	if (ali_config_readw(PCI_VENDOR_ID,16) == PCI_VENDOR_ID_AL &&
++	    ali_config_readw(PCI_DEVICE_ID,16) == PCI_DEVICE_ID_AL_M1533) {
++		printk(KERN_INFO "Found an NEC Rockhopper \n");
++		vr4133_rockhopper = 1;
++		/*
++		 * Enable ALi M5229 IDE Controller (both channels)
++		 * IDSEL: A27
++		 */
++		ali_config_writeb(0x58, 0x4c, 16);
++	}
++}
++
++void __init ali_m5229_init(struct pci_dev *dev)
++{
++	/*
++	 * Enable Primary/Secondary Channel Cable Detect 40-Pin
++	 */
++	pci_write_config_word(dev, 0x4a, 0xc023);
++
++	/*
++	 * Set only the 3rd byteis for the master IDE's cycle and
++	 * enable Internal IDE Function
++	 */
++	pci_write_config_byte(dev, 0x50, 0x23); /* Class code attr register */
++
++	pci_write_config_byte(dev, 0x09, 0xff); /* Set native mode & stuff */
++	pci_write_config_byte(dev, 0x52, 0x00); /* use timing registers */
++	pci_write_config_byte(dev, 0x58, 0x02); /* Primary addr setup timing */
++	pci_write_config_byte(dev, 0x59, 0x22); /* Primary cmd block timing */
++	pci_write_config_byte(dev, 0x5a, 0x22); /* Pr drv 0 R/W timing */
++	pci_write_config_byte(dev, 0x5b, 0x22); /* Pr drv 1 R/W timing */
++	pci_write_config_byte(dev, 0x5c, 0x02); /* Sec addr setup timing */
++	pci_write_config_byte(dev, 0x5d, 0x22); /* Sec cmd block timing */
++	pci_write_config_byte(dev, 0x5e, 0x22); /* Sec drv 0 R/W timing */
++	pci_write_config_byte(dev, 0x5f, 0x22); /* Sec drv 1 R/W timing */
++	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
++	pci_write_config_word(dev, PCI_COMMAND,
++	                           PCI_COMMAND_PARITY | PCI_COMMAND_MASTER |
++				   PCI_COMMAND_IO);
++}
++
+diff -urpNX dontdiff linux-2.6.10/arch/mips/vr41xx/nec-cmbvr4133/setup.c linux-2.6.10-mips/arch/mips/vr41xx/nec-cmbvr4133/setup.c
+--- linux-2.6.10/arch/mips/vr41xx/nec-cmbvr4133/setup.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/arch/mips/vr41xx/nec-cmbvr4133/setup.c	2004-12-15 15:08:18.000000000 +0100
+@@ -0,0 +1,108 @@
++/*
++ * arch/mips/vr41xx/nec-cmbvr4133/setup.c
++ *
++ * Setup for the NEC CMB-VR4133.
++ *
++ * Author: Yoichi Yuasa <yyuasa at mvista.com, or source at mvista.com> and
++ *         Alex Sapkov <asapkov at ru.mvista.com>
++ *
++ * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
++ * the terms of the GNU General Public License version 2. This program
++ * is licensed "as is" without any warranty of any kind, whether express
++ * or implied.
++ *
++ * Support for CMBVR4133 board in 2.6
++ * Author: Manish Lachwani (mlachwani at mvista.com)
++ */
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/ide.h>
++#include <linux/ioport.h>
++
++#include <asm/reboot.h>
++#include <asm/time.h>
++#include <asm/vr41xx/cmbvr4133.h>
++#include <asm/bootinfo.h>
++
++#ifdef CONFIG_MTD
++#include <linux/mtd/physmap.h>
++#include <linux/mtd/partitions.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/map.h>
++
++static struct mtd_partition cmbvr4133_mtd_parts[] = {
++	{
++		.name =		"User FS",
++		.size =		0x1be0000,
++		.offset =	0,
++		.mask_flags = 	0,
++	}, 
++	{
++		.name =		"PMON",
++		.size =		0x140000,
++		.offset =	MTDPART_OFS_APPEND,
++		.mask_flags =	MTD_WRITEABLE,  /* force read-only */
++	}, 
++	{
++		.name =		"User FS2",
++		.size =		MTDPART_SIZ_FULL,
++		.offset =	MTDPART_OFS_APPEND,
++		.mask_flags = 	0,
++	}
++};
++
++#define number_partitions (sizeof(cmbvr4133_mtd_parts)/sizeof(struct mtd_partition))
++#endif
++
++extern void (*late_time_init)(void);
++
++static void __init vr4133_serial_init(void)
++{
++	vr41xx_select_siu_interface(SIU_RS232C, IRDA_NONE);
++	vr41xx_siu_init();
++	vr41xx_dsiu_init();
++}
++
++extern void i8259_init(void);
++
++static int __init nec_cmbvr4133_setup(void)
++{
++#ifdef CONFIG_ROCKHOPPER
++	extern void disable_pcnet(void);
++
++	disable_pcnet();
++#endif
++	set_io_port_base(KSEG1ADDR(0x16000000));
++
++	mips_machgroup = MACH_GROUP_NEC_VR41XX;
++	mips_machtype = MACH_NEC_CMBVR4133;
++
++	late_time_init = vr4133_serial_init;
++
++#ifdef CONFIG_PCI
++#ifdef CONFIG_ROCKHOPPER
++	ali_m5229_preinit();
++#endif
++#endif
++
++#ifdef CONFIG_ROCKHOPPER
++	rockhopper_init_irq();
++#endif
++
++#ifdef CONFIG_MTD
++	/* we use generic physmap mapping driver and we use partitions */
++	physmap_configure(0x1C000000, 0x02000000, 4, NULL);
++	physmap_set_partitions(cmbvr4133_mtd_parts, number_partitions);
++#endif
++
++	/* 128 MB memory support */
++	add_memory_region(0, 0x08000000, BOOT_MEM_RAM);
++
++#ifdef CONFIG_ROCKHOPPER
++	i8259_init();
++#endif
++	return 0;
++}
++
++early_initcall(nec_cmbvr4133_setup);
+diff -urpNX dontdiff linux-2.6.10/drivers/char/Kconfig linux-2.6.10-mips/drivers/char/Kconfig
+--- linux-2.6.10/drivers/char/Kconfig	2004-12-24 22:33:49.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/Kconfig	2004-12-28 20:06:31.000000000 +0100
+@@ -348,9 +348,25 @@ config ISTALLION
+ 	  To compile this driver as a module, choose M here: the
+ 	  module will be called istallion.
+ 
++config AU1X00_GPIO
++	tristate "Alchemy Au1000 GPIO device support"
++	depends on MIPS && SOC_AU1X00
++
++config TS_AU1X00_ADS7846
++	tristate "Au1000/ADS7846 touchscreen support"
++	depends on MIPS && SOC_AU1X00
++
++config AU1X00_USB_TTY
++	tristate "Au1000 USB TTY Device support"
++	depends on MIPS && MIPS_AU1000 && AU1000_USB_DEVICE=y && AU1000_USB_DEVICE
++
++config AU1X00_USB_RAW
++	tristate "Au1000 USB Raw Device support"
++	depends on MIPS && MIPS_AU1000 && AU1000_USB_DEVICE=y && AU1000_USB_TTY!=y && AU1X00_USB_DEVICE
++
+ config SERIAL_TX3912
+ 	bool "TX3912/PR31700 serial port support"
+-	depends on SERIAL_NONSTANDARD && MIPS && BROKEN_ON_SMP
++	depends on MIPS && CPU_TX39XX=y
+ 	help
+ 	  The TX3912 is a Toshiba RISC processor based o the MIPS 3900 core;
+ 	  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
+@@ -364,23 +380,33 @@ config SERIAL_TX3912_CONSOLE
+ 	  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
+ 	  Say Y here to direct console I/O to the on-board serial port.
+ 
+-config AU1000_UART
+-	bool "Enable Au1000 UART Support"
+-	depends on SERIAL_NONSTANDARD && MIPS
+-	help
+-	  If you have an Alchemy AU1000 processor (MIPS based) and you want
+-	  to use serial ports, say Y.  Otherwise, say N.
+-
+-config AU1000_SERIAL_CONSOLE
+-	bool "Enable Au1000 serial console"
+-	depends on AU1000_UART
+-	help
+-	  If you have an Alchemy AU1000 processor (MIPS based) and you want
+-	  to use a console on a serial port, say Y.  Otherwise, say N.
++config TXX927_SERIAL
++	bool "TXx927 SIO support"
++	depends on MIPS && CPU_TX39XX=y
++
++config TXX927_SERIAL_CONSOLE
++	bool "TXx927 SIO Console support"
++	depends on TXX927_SERIAL
++
++config SERIAL_TXX9
++	bool "TMPTX39XX/49XX SIO support"
++	depends on MIPS && TOSHIBA_BOARDS=y
++
++config SERIAL_TXX9_CONSOLE
++	bool "TMPTX39XX/49XX SIO Console support"
++	depends on SERIAL_TXX9
++
++config SIBYTE_SB1250_DUART
++	bool "Support for BCM1xxx onchip DUART"
++	depends on MIPS && SIBYTE_SB1xxx_SOC=y
++
++config SIBYTE_SB1250_DUART_CONSOLE
++	bool "Console on BCM1xxx DUART"
++	depends on SIBYTE_SB1250_DUART
+ 
+ config QTRONIX_KEYBOARD
+ 	bool "Enable Qtronix 990P Keyboard Support"
+-	depends on IT8712
++	depends on MIPS && (MIPS_ITE8172 || MIPS_IVR)
+ 	help
+ 	  Images of Qtronix keyboards are at
+ 	  <http://www.qtronix.com/keyboard.html>.
+@@ -392,7 +418,7 @@ config IT8172_CIR
+ 
+ config IT8172_SCR0
+ 	bool "Enable Smart Card Reader 0 Support "
+-	depends on IT8712
++	depends on MIPS && (MIPS_ITE8172 || MIPS_IVR)
+ 	help
+ 	  Say Y here to support smart-card reader 0 (SCR0) on the Integrated
+ 	  Technology Express, Inc. ITE8172 SBC.  Vendor page at
+@@ -401,13 +427,17 @@ config IT8172_SCR0
+ 
+ config IT8172_SCR1
+ 	bool "Enable Smart Card Reader 1 Support "
+-	depends on IT8712
++	depends on MIPS && (MIPS_ITE8172 || MIPS_IVR) && MIPS_ITE8172
+ 	help
+ 	  Say Y here to support smart-card reader 1 (SCR1) on the Integrated
+ 	  Technology Express, Inc. ITE8172 SBC.  Vendor page at
+ 	  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
+ 	  board at <http://www.mvista.com/partners/semiconductor/ite.html>.
+ 
++config ITE_GPIO
++	tristate "ITE GPIO"
++	depends on MIPS && MIPS_ITE8172
++
+ config A2232
+ 	tristate "Commodore A2232 serial support (EXPERIMENTAL)"
+ 	depends on EXPERIMENTAL && ZORRO && BROKEN_ON_SMP
+diff -urpNX dontdiff linux-2.6.10/drivers/char/Makefile linux-2.6.10-mips/drivers/char/Makefile
+--- linux-2.6.10/drivers/char/Makefile	2004-12-24 22:35:29.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/Makefile	2004-11-19 01:14:22.000000000 +0100
+@@ -21,6 +21,7 @@ obj-$(CONFIG_MVME147_SCC)	+= generic_ser
+ obj-$(CONFIG_MVME162_SCC)	+= generic_serial.o vme_scc.o
+ obj-$(CONFIG_BVME6000_SCC)	+= generic_serial.o vme_scc.o
+ obj-$(CONFIG_SERIAL_TX3912)	+= generic_serial.o serial_tx3912.o
++obj-$(CONFIG_SERIAL_TXX9)	+= generic_serial.o serial_txx9.o
+ obj-$(CONFIG_ROCKETPORT)	+= rocket.o
+ obj-$(CONFIG_SERIAL167)		+= serial167.o
+ obj-$(CONFIG_CYCLADES)		+= cyclades.o
+@@ -33,6 +34,7 @@ obj-$(CONFIG_MOXA_INTELLIO)	+= moxa.o
+ obj-$(CONFIG_A2232)		+= ser_a2232.o generic_serial.o
+ obj-$(CONFIG_ATARI_DSP56K)	+= dsp56k.o
+ obj-$(CONFIG_MOXA_SMARTIO)	+= mxser.o
++obj-$(CONFIG_SIBYTE_SB1250_DUART) += sb1250_duart.o
+ obj-$(CONFIG_COMPUTONE)		+= ip2.o ip2main.o
+ obj-$(CONFIG_RISCOM8)		+= riscom8.o
+ obj-$(CONFIG_ISI)		+= isicom.o
+@@ -77,6 +79,10 @@ obj-$(CONFIG_HW_RANDOM) += hw_random.o
+ obj-$(CONFIG_QIC02_TAPE) += tpqic02.o
+ obj-$(CONFIG_FTAPE) += ftape/
+ obj-$(CONFIG_COBALT_LCD) += lcd.o
++obj-$(CONFIG_ITE_GPIO) += ite_gpio.o
++obj-$(CONFIG_AU1000_GPIO) += au1000_gpio.o
++obj-$(CONFIG_AU1000_USB_TTY) += au1000_usbtty.o
++obj-$(CONFIG_AU1000_USB_RAW) += au1000_usbraw.o
+ obj-$(CONFIG_PPDEV) += ppdev.o
+ obj-$(CONFIG_NWBUTTON) += nwbutton.o
+ obj-$(CONFIG_NWFLASH) += nwflash.o
+@@ -92,7 +98,7 @@ obj-$(CONFIG_IPMI_HANDLER) += ipmi/
+ obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
+ 
+ # Files generated that shall be removed upon make clean
+-clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c
++clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c ibm_workpad_keymap.c
+ 
+ quiet_cmd_conmk = CONMK   $@
+       cmd_conmk = scripts/conmakehash $< > $@
+@@ -104,6 +110,8 @@ $(obj)/defkeymap.o:  $(obj)/defkeymap.c
+ 
+ $(obj)/qtronixmap.o: $(obj)/qtronixmap.c
+ 
++$(obj)/ibm_workpad_keymap.o: $(obj)/ibm_workpad_keymap.c
++
+ # Uncomment if you're changing the keymap and have an appropriate
+ # loadkeys version for the map. By default, we'll use the shipped
+ # versions.
+@@ -111,7 +119,8 @@ $(obj)/qtronixmap.o: $(obj)/qtronixmap.c
+ 
+ ifdef GENERATE_KEYMAP
+ 
+-$(obj)/defkeymap.c $(obj)/qtronixmap.c: $(obj)/%.c: $(src)/%.map
++$(obj)/defkeymap.c $(obj)/qtronixmap.c $(obj)/ibm_workpad_keymap.c: \
++		$(obj)/%.c: $(src)/%.map
+ 	loadkeys --mktable $< > $@.tmp
+ 	sed -e 's/^static *//' $@.tmp > $@
+ 	rm $@.tmp
+diff -urpNX dontdiff linux-2.6.10/drivers/char/agp/Kconfig linux-2.6.10-mips/drivers/char/agp/Kconfig
+--- linux-2.6.10/drivers/char/agp/Kconfig	2004-12-24 22:34:58.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/agp/Kconfig	2004-12-28 20:06:31.000000000 +0100
+@@ -1,5 +1,5 @@
+ config AGP
+-	tristate "/dev/agpgart (AGP Support)" if !GART_IOMMU && !M68K && !ARM
++	tristate "/dev/agpgart (AGP Support)" if !GART_IOMMU && !M68K && !ARM && !MIPS
+ 	default y if GART_IOMMU
+ 	---help---
+ 	  AGP (Accelerated Graphics Port) is a bus system mainly used to
+diff -urpNX dontdiff linux-2.6.10/drivers/char/au1000_gpio.c linux-2.6.10-mips/drivers/char/au1000_gpio.c
+--- linux-2.6.10/drivers/char/au1000_gpio.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/au1000_gpio.c	2004-10-27 02:14:17.000000000 +0200
+@@ -0,0 +1,266 @@
++/*
++ * FILE NAME au1000_gpio.c
++ *
++ * BRIEF MODULE DESCRIPTION
++ *  Driver for Alchemy Au1000 GPIO.
++ *
++ *  Author: MontaVista Software, Inc.  <source at mvista.com>
++ *          Steve Longerbeam <stevel at mvista.com>
++ *
++ * Copyright 2001 MontaVista Software Inc.
++ *
++ *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO  EVENT  SHALL   THE AUTHOR  BE	LIABLE FOR ANY   DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  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.
++ */
++
++#include <linux/module.h>
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/kernel.h>
++#include <linux/miscdevice.h>
++#include <linux/init.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++#include <asm/au1000.h>
++#include <asm/au1000_gpio.h>
++
++#define VERSION "0.01"
++
++static const struct {
++	u32 active_hi;
++	u32 avail_mask;
++} pinfunc_to_avail[15] = {
++	{1,  0x7<<16},   // 0  = SSI0     / GPIO[18:16]
++	{-1, 0},         // 1  = AC97     / SSI1
++	{1,  1<<19},     // 2  = IRDA     / GPIO19
++	{1,  1<<20},     // 3  = UART0    / GPIO20
++	{1,  0x1f<<24},  // 4  = NIC2     / GPIO[28:24]
++	{1,  0x7<<29},   // 5  = I2S      / GPIO[31:29]
++	{0,  1<<8},      // 6  = I2SDI    / GPIO8
++	{0,  0x3f<<9},   // 7  = UART3    / GPIO[14:9]
++	{0,  1<<15},     // 8  = IRFIRSEL / GPIO15
++	{0,  1<<2},      // 9  = EXTCLK0 or OSC / GPIO2
++	{0,  1<<3},      // 10 = EXTCLK1  / GPIO3
++	{0,  1<<6},      // 11 = SMROMCKE / GPIO6
++	{1,  1<<21},     // 12 = UART1    / GPIO21
++	{1,  1<<22},     // 13 = UART2    / GPIO22
++	{1,  1<<23}      // 14 = UART3    / GPIO23
++};
++
++	
++u32 get_au1000_avail_gpio_mask(void)
++{
++	int i;
++	u32 pinfunc = inl(SYS_PINFUNC);
++	u32 avail_mask = 0; // start with no gpio available
++
++	// first, check for GPIO's reprogrammed as peripheral pins
++	for (i=0; i<15; i++) {
++		if (pinfunc_to_avail[i].active_hi < 0)
++			continue;
++		if (!(pinfunc_to_avail[i].active_hi ^
++		      ((pinfunc & (1<<i)) ? 1:0)))
++			avail_mask |= pinfunc_to_avail[i].avail_mask;
++	}
++
++	// check for GPIO's used as interrupt sources
++	avail_mask &= ~(inl(IC1_MASKRD) &
++			(inl(IC1_CFG0RD) | inl(IC1_CFG1RD)));
++
++#ifdef CONFIG_USB_OHCI
++	avail_mask &= ~((1<<4) | (1<<11));
++#ifndef CONFIG_AU1X00_USB_DEVICE
++	avail_mask &= ~((1<<5) | (1<<13));
++#endif
++#endif
++	
++	return avail_mask;
++}
++
++
++/*
++ * Tristate the requested GPIO pins specified in data.
++ * Only available GPIOs will be tristated.
++ */
++int au1000gpio_tristate(u32 data)
++{
++	data &= get_au1000_avail_gpio_mask();
++
++	if (data)
++		outl(data, SYS_TRIOUTCLR);
++
++	return 0;
++}
++
++
++/*
++ * Return the pin state. Pins configured as outputs will return
++ * the output state, and pins configured as inputs (tri-stated)
++ * will return input pin state.
++ */
++int au1000gpio_in(u32 *data)
++{
++	*data = inl(SYS_PINSTATERD);
++	return 0;
++}
++
++
++/*
++ * Set/clear GPIO pins. Only available GPIOs will be affected.
++ */
++int au1000gpio_set(u32 data)
++{
++	data &= get_au1000_avail_gpio_mask();
++
++	if (data)
++		outl(data, SYS_OUTPUTSET);
++	return 0;
++}
++
++int au1000gpio_clear(u32 data)
++{
++	data &= get_au1000_avail_gpio_mask();
++
++	if (data)
++		outl(data, SYS_OUTPUTCLR);
++	return 0;
++}
++
++/*
++ * Output data to GPIO pins. Only available GPIOs will be affected.
++ */
++int au1000gpio_out(u32 data)
++{
++	au1000gpio_set(data);
++	au1000gpio_clear(~data);
++	return 0;
++}
++
++
++EXPORT_SYMBOL(get_au1000_avail_gpio_mask);
++EXPORT_SYMBOL(au1000gpio_tristate);
++EXPORT_SYMBOL(au1000gpio_in);
++EXPORT_SYMBOL(au1000gpio_set);
++EXPORT_SYMBOL(au1000gpio_clear);
++EXPORT_SYMBOL(au1000gpio_out);
++
++
++static int au1000gpio_open(struct inode *inode, struct file *file)
++{
++	return 0;
++}
++
++
++static int au1000gpio_release(struct inode *inode, struct file *file)
++{
++	return 0;
++}
++
++
++static int au1000gpio_ioctl(struct inode *inode, struct file *file,
++			    unsigned int cmd, unsigned long arg)
++{
++	int status;
++	u32 val;
++	
++	switch(cmd) {
++	case AU1000GPIO_IN:
++		
++		status = au1000gpio_in(&val);
++		if (status != 0)
++			return status;
++
++		return put_user(val, (u32 *)arg);
++
++	case AU1000GPIO_OUT:
++
++		if (get_user(val, (u32 *)arg)) 
++			return -EFAULT;
++
++		return au1000gpio_out(val);
++
++	case AU1000GPIO_SET:
++
++		if (get_user(val, (u32 *)arg)) 
++			return -EFAULT;
++
++		return au1000gpio_set(val);
++		
++	case AU1000GPIO_CLEAR:
++
++		if (get_user(val, (u32 *)arg)) 
++			return -EFAULT;
++
++		return au1000gpio_clear(val);
++
++	case AU1000GPIO_TRISTATE:
++
++		if (get_user(val, (u32 *)arg)) 
++			return -EFAULT;
++
++		return au1000gpio_tristate(val);
++
++	case AU1000GPIO_AVAIL_MASK:
++		
++		return put_user(get_au1000_avail_gpio_mask(),
++				(u32 *)arg);
++		
++	default:
++		return -ENOIOCTLCMD;
++
++	}
++
++	return 0;
++}
++
++
++static struct file_operations au1000gpio_fops =
++{
++	owner:		THIS_MODULE,
++	ioctl:		au1000gpio_ioctl,
++	open:		au1000gpio_open,
++	release:	au1000gpio_release,
++};
++
++
++static struct miscdevice au1000gpio_miscdev =
++{
++	MISC_DYNAMIC_MINOR,
++	"au1000_gpio",
++	&au1000gpio_fops
++};
++
++
++int __init au1000gpio_init(void)
++{
++	misc_register(&au1000gpio_miscdev);
++	printk("Au1000 gpio driver, version %s\n", VERSION);
++	return 0;
++}	
++
++
++void __exit au1000gpio_exit(void)
++{
++	misc_deregister(&au1000gpio_miscdev);
++}
++
++
++module_init(au1000gpio_init);
++module_exit(au1000gpio_exit);
+diff -urpNX dontdiff linux-2.6.10/drivers/char/au1000_ts.c linux-2.6.10-mips/drivers/char/au1000_ts.c
+--- linux-2.6.10/drivers/char/au1000_ts.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/au1000_ts.c	2004-10-27 02:14:17.000000000 +0200
+@@ -0,0 +1,677 @@
++/*
++ *      au1000_ts.c  --  Touch screen driver for the Alchemy Au1000's
++ *                       SSI Port 0 talking to the ADS7846 touch screen
++ *                       controller.
++ *
++ * Copyright 2001 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc.
++ *         	stevel at mvista.com or source at mvista.com
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ *
++ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  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.
++ *
++ * Notes:
++ *
++ *  Revision history
++ *    06.27.2001  Initial version
++ */
++
++#include <linux/module.h>
++#include <linux/version.h>
++
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/delay.h>
++#include <linux/poll.h>
++#include <linux/string.h>
++#include <linux/ioport.h>       /* request_region */
++#include <linux/interrupt.h>    /* mark_bh */
++#include <asm/uaccess.h>        /* get_user,copy_to_user */
++#include <asm/io.h>
++#include <asm/au1000.h>
++
++#define TS_NAME "au1000-ts"
++#define TS_MAJOR 11
++
++#define PFX TS_NAME
++#define AU1000_TS_DEBUG 1
++
++#ifdef AU1000_TS_DEBUG
++#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)
++#else
++#define dbg(format, arg...) do {} while (0)
++#endif
++#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
++#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
++#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
++
++
++// SSI Status register bit defines
++#define SSISTAT_BF    (1<<4)
++#define SSISTAT_OF    (1<<3)
++#define SSISTAT_UF    (1<<2)
++#define SSISTAT_DONE  (1<<1)
++#define SSISTAT_BUSY  (1<<0)
++
++// SSI Interrupt Pending and Enable register bit defines
++#define SSIINT_OI     (1<<3)
++#define SSIINT_UI     (1<<2)
++#define SSIINT_DI     (1<<1)
++
++// SSI Address/Data register bit defines
++#define SSIADAT_D         (1<<24)
++#define SSIADAT_ADDR_BIT  16
++#define SSIADAT_ADDR_MASK (0xff<<SSIADAT_ADDR_BIT)
++#define SSIADAT_DATA_BIT  0
++#define SSIADAT_DATA_MASK (0xfff<<SSIADAT_DATA_BIT)
++
++// SSI Enable register bit defines
++#define SSIEN_CD (1<<1)
++#define SSIEN_E  (1<<0)
++
++// SSI Config register bit defines
++#define SSICFG_AO (1<<24)
++#define SSICFG_DO (1<<23)
++#define SSICFG_ALEN_BIT 20
++#define SSICFG_ALEN_MASK (0x7<<SSICFG_ALEN_BIT)
++#define SSICFG_DLEN_BIT 16
++#define SSICFG_DLEN_MASK (0xf<<SSICFG_DLEN_BIT)
++#define SSICFG_DD (1<<11)
++#define SSICFG_AD (1<<10)
++#define SSICFG_BM_BIT 8
++#define SSICFG_BM_MASK (0x3<<SSICFG_BM_BIT)
++#define SSICFG_CE (1<<7)
++#define SSICFG_DP (1<<6)
++#define SSICFG_DL (1<<5)
++#define SSICFG_EP (1<<4)
++
++// Bus Turnaround Selection
++#define SCLK_HOLD_HIGH 0
++#define SCLK_HOLD_LOW  1
++#define SCLK_CYCLE     2
++
++/*
++ * Default config for SSI0:
++ *
++ *   - transmit MSBit first
++ *   - expect MSBit first on data receive
++ *   - address length 7 bits
++ *   - expect data length 12 bits
++ *   - do not disable Direction bit
++ *   - do not disable Address bits
++ *   - SCLK held low during bus turnaround
++ *   - Address and Data bits clocked out on falling edge of SCLK
++ *   - Direction bit high is a read, low is a write
++ *   - Direction bit precedes Address bits
++ *   - Active low enable signal
++ */
++
++#define DEFAULT_SSI_CONFIG \
++    (SSICFG_AO | SSICFG_DO | (6<<SSICFG_ALEN_BIT) | (11<<SSICFG_DLEN_BIT) |\
++    (SCLK_HOLD_LOW<<SSICFG_BM_BIT) | SSICFG_DP | SSICFG_EP)
++
++
++// ADS7846 Control Byte bit defines
++#define ADS7846_ADDR_BIT  4
++#define ADS7846_ADDR_MASK (0x7<<ADS7846_ADDR_BIT)
++#define   ADS7846_MEASURE_X  (0x5<<ADS7846_ADDR_BIT)
++#define   ADS7846_MEASURE_Y  (0x1<<ADS7846_ADDR_BIT)
++#define   ADS7846_MEASURE_Z1 (0x3<<ADS7846_ADDR_BIT)
++#define   ADS7846_MEASURE_Z2 (0x4<<ADS7846_ADDR_BIT)
++#define ADS7846_8BITS     (1<<3)
++#define ADS7846_12BITS    0
++#define ADS7846_SER       (1<<2)
++#define ADS7846_DFR       0
++#define ADS7846_PWR_BIT   0
++#define   ADS7846_PD      0
++#define   ADS7846_ADC_ON  (0x1<<ADS7846_PWR_BIT)
++#define   ADS7846_REF_ON  (0x2<<ADS7846_PWR_BIT)
++#define   ADS7846_REF_ADC_ON (0x3<<ADS7846_PWR_BIT)
++
++#define MEASURE_12BIT_X \
++    (ADS7846_MEASURE_X | ADS7846_12BITS | ADS7846_DFR | ADS7846_PD)
++#define MEASURE_12BIT_Y \
++    (ADS7846_MEASURE_Y | ADS7846_12BITS | ADS7846_DFR | ADS7846_PD)
++#define MEASURE_12BIT_Z1 \
++    (ADS7846_MEASURE_Z1 | ADS7846_12BITS | ADS7846_DFR | ADS7846_PD)
++#define MEASURE_12BIT_Z2 \
++    (ADS7846_MEASURE_Z2 | ADS7846_12BITS | ADS7846_DFR | ADS7846_PD)
++
++typedef enum {
++	IDLE = 0,
++	ACQ_X,
++	ACQ_Y,
++	ACQ_Z1,
++	ACQ_Z2
++} acq_state_t;
++
++/* +++++++++++++ Lifted from include/linux/h3600_ts.h ++++++++++++++*/
++typedef struct {
++	unsigned short pressure;  // touch pressure
++	unsigned short x;         // calibrated X
++	unsigned short y;         // calibrated Y
++	unsigned short millisecs; // timestamp of this event
++} TS_EVENT;
++
++typedef struct {
++	int xscale;
++	int xtrans;
++	int yscale;
++	int ytrans;
++	int xyswap;
++} TS_CAL;
++
++/* Use 'f' as magic number */
++#define IOC_MAGIC  'f'
++
++#define TS_GET_RATE             _IO(IOC_MAGIC, 8)
++#define TS_SET_RATE             _IO(IOC_MAGIC, 9)
++#define TS_GET_CAL              _IOR(IOC_MAGIC, 10, TS_CAL)
++#define TS_SET_CAL              _IOW(IOC_MAGIC, 11, TS_CAL)
++
++/* +++++++++++++ Done lifted from include/linux/h3600_ts.h +++++++++*/
++
++
++#define EVENT_BUFSIZE 128
++
++/*
++ * Which pressure equation to use from ADS7846 datasheet.
++ * The first equation requires knowing only the X plate
++ * resistance, but needs 4 measurements (X, Y, Z1, Z2).
++ * The second equation requires knowing both X and Y plate
++ * resistance, but only needs 3 measurements (X, Y, Z1).
++ * The second equation is preferred because of the shorter
++ * acquisition time required.
++ */
++enum {
++	PRESSURE_EQN_1 = 0,
++	PRESSURE_EQN_2
++};
++
++
++/*
++ * The touch screen's X and Y plate resistances, used by
++ * pressure equations.
++ */
++#define DEFAULT_X_PLATE_OHMS 580
++#define DEFAULT_Y_PLATE_OHMS 580
++
++/*
++ * Pen up/down pressure resistance thresholds.
++ *
++ * FIXME: these are bogus and will have to be found empirically.
++ *
++ * These are hysteresis points. If pen state is up and pressure
++ * is greater than pen-down threshold, pen transitions to down.
++ * If pen state is down and pressure is less than pen-up threshold,
++ * pen transitions to up. If pressure is in-between, pen status
++ * doesn't change.
++ *
++ * This wouldn't be needed if PENIRQ* from the ADS7846 were
++ * routed to an interrupt line on the Au1000. This would issue
++ * an interrupt when the panel is touched.
++ */
++#define DEFAULT_PENDOWN_THRESH_OHMS 100
++#define DEFAULT_PENUP_THRESH_OHMS    80
++
++typedef struct {
++	int baudrate;
++	u32 clkdiv;
++	acq_state_t acq_state;            // State of acquisition state machine
++	int x_raw, y_raw, z1_raw, z2_raw; // The current raw acquisition values
++	TS_CAL cal;                       // Calibration values
++	// The X and Y plate resistance, needed to calculate pressure
++	int x_plate_ohms, y_plate_ohms;
++	// pressure resistance at which pen is considered down/up
++	int pendown_thresh_ohms;
++	int penup_thresh_ohms;
++	int pressure_eqn;                 // eqn to use for pressure calc
++	int pendown;                      // 1 = pen is down, 0 = pen is up
++	TS_EVENT event_buf[EVENT_BUFSIZE];// The event queue
++	int nextIn, nextOut;
++	int event_count;
++	struct fasync_struct *fasync;     // asynch notification
++	struct timer_list acq_timer;      // Timer for triggering acquisitions
++	wait_queue_head_t wait;           // read wait queue
++	spinlock_t lock;
++	struct tq_struct chug_tq;
++} au1000_ts_t;
++
++static au1000_ts_t au1000_ts;
++
++
++static inline u32
++calc_clkdiv(int baud)
++{
++	u32 sys_busclk =
++		(get_au1000_speed() / (int)(inl(PM_POWERUP_CONTROL)&0x03) + 2);
++	return (sys_busclk / (2 * baud)) - 1;
++}
++
++static inline int
++calc_baudrate(u32 clkdiv)
++{
++	u32 sys_busclk =
++		(get_au1000_speed() / (int)(inl(PM_POWERUP_CONTROL)&0x03) + 2);
++	return sys_busclk / (2 * (clkdiv + 1));
++}
++
++
++/*
++ * This is a bottom-half handler that is scheduled after
++ * raw X,Y,Z1,Z2 coordinates have been acquired, and does
++ * the following:
++ *
++ *   - computes touch screen pressure resistance
++ *   - if pressure is above a threshold considered to be pen-down:
++ *         - compute calibrated X and Y coordinates
++ *         - queue a new TS_EVENT
++ *         - signal asynchronously and wake up any read
++ */
++static void
++chug_raw_data(void* private)
++{
++	au1000_ts_t* ts = (au1000_ts_t*)private;
++	TS_EVENT event;
++	int Rt, Xcal, Ycal;
++	unsigned long flags;
++
++	// timestamp this new event.
++	event.millisecs = jiffies;
++
++	// Calculate touch pressure resistance
++	if (ts->pressure_eqn == PRESSURE_EQN_2) {
++		Rt = (ts->x_plate_ohms * ts->x_raw *
++		      (4096 - ts->z1_raw)) / ts->z1_raw;
++		Rt -= (ts->y_plate_ohms * ts->y_raw);
++		Rt = (Rt + 2048) >> 12; // round up to nearest ohm
++	} else {
++		Rt = (ts->x_plate_ohms * ts->x_raw *
++		      (ts->z2_raw - ts->z1_raw)) / ts->z1_raw;
++		Rt = (Rt + 2048) >> 12; // round up to nearest ohm
++	}
++
++	// hysteresis
++	if (!ts->pendown && Rt > ts->pendown_thresh_ohms)
++		ts->pendown = 1;
++	else if (ts->pendown && Rt < ts->penup_thresh_ohms)
++		ts->pendown = 0;
++
++	if (ts->pendown) {
++		// Pen is down
++		// Calculate calibrated X,Y
++		Xcal = ((ts->cal.xscale * ts->x_raw) >> 8) + ts->cal.xtrans;
++		Ycal = ((ts->cal.yscale * ts->y_raw) >> 8) + ts->cal.ytrans;
++
++		event.x = (unsigned short)Xcal;
++		event.y = (unsigned short)Ycal;
++		event.pressure = (unsigned short)Rt;
++
++		// add this event to the event queue
++		spin_lock_irqsave(&ts->lock, flags);
++		ts->event_buf[ts->nextIn++] = event;
++		if (ts->nextIn == EVENT_BUFSIZE)
++			ts->nextIn = 0;
++		if (ts->event_count < EVENT_BUFSIZE) {
++			ts->event_count++;
++		} else {
++			// throw out the oldest event
++			if (++ts->nextOut == EVENT_BUFSIZE)
++				ts->nextOut = 0;
++		}
++		spin_unlock_irqrestore(&ts->lock, flags);
++
++		// async notify
++		if (ts->fasync)
++			kill_fasync(&ts->fasync, SIGIO, POLL_IN);
++		// wake up any read call
++		if (waitqueue_active(&ts->wait))
++			wake_up_interruptible(&ts->wait);
++	}
++}
++
++
++/*
++ * Raw X,Y,pressure acquisition timer function. This triggers
++ * the start of a new acquisition. Its duration between calls
++ * is the touch screen polling rate.
++ */
++static void
++au1000_acq_timer(unsigned long data)
++{
++	au1000_ts_t* ts = (au1000_ts_t*)data;
++	unsigned long flags;
++
++	spin_lock_irqsave(&ts->lock, flags);
++
++	// start acquisition with X coordinate
++	ts->acq_state = ACQ_X;
++	// start me up
++	outl(SSIADAT_D | (MEASURE_12BIT_X << SSIADAT_ADDR_BIT), SSI0_ADATA);
++
++	// schedule next acquire
++	ts->acq_timer.expires = jiffies + HZ / 100;
++	add_timer(&ts->acq_timer);
++
++	spin_unlock_irqrestore(&ts->lock, flags);
++}
++
++static void
++ssi0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	au1000_ts_t *ts = (au1000_ts_t*)dev_id;
++	u32 stat, int_stat, data;
++
++	spin_lock(&ts->lock);
++
++	stat = inl(SSI0_STATUS);
++	// clear sticky status bits
++	outl(stat & (SSISTAT_OF|SSISTAT_UF|SSISTAT_DONE), SSI0_STATUS);
++
++	int_stat = inl(SSI0_INT);
++	// clear sticky intr status bits
++	outl(int_stat & (SSIINT_OI|SSIINT_UI|SSIINT_DI), SSI0_INT);
++
++	if ((int_stat & (SSIINT_OI|SSIINT_UI|SSIINT_DI)) != SSIINT_DI) {
++		if (int_stat & SSIINT_OI)
++			err("overflow");
++		if (int_stat & SSIINT_UI)
++			err("underflow");
++		spin_unlock(&ts->lock);
++		return;
++	}
++
++	data = inl(SSI0_ADATA) & SSIADAT_DATA_MASK;
++
++	switch (ts->acq_state) {
++	case IDLE:
++		break;
++	case ACQ_X:
++		ts->x_raw = data;
++		ts->acq_state = ACQ_Y;
++		// trigger Y acq
++		outl(SSIADAT_D | (MEASURE_12BIT_Y << SSIADAT_ADDR_BIT),
++		     SSI0_ADATA);
++		break;
++	case ACQ_Y:
++		ts->y_raw = data;
++		ts->acq_state = ACQ_Z1;
++		// trigger Z1 acq
++		outl(SSIADAT_D | (MEASURE_12BIT_Z1 << SSIADAT_ADDR_BIT),
++		     SSI0_ADATA);
++		break;
++	case ACQ_Z1:
++		ts->z1_raw = data;
++		if (ts->pressure_eqn == PRESSURE_EQN_2) {
++			// don't acq Z2, using 2nd eqn for touch pressure
++			ts->acq_state = IDLE;
++			// got the raw stuff, now mark BH
++			queue_task(&ts->chug_tq, &tq_immediate);
++			mark_bh(IMMEDIATE_BH);
++		} else {
++			ts->acq_state = ACQ_Z2;
++			// trigger Z2 acq
++			outl(SSIADAT_D | (MEASURE_12BIT_Z2<<SSIADAT_ADDR_BIT),
++			     SSI0_ADATA);
++		}
++		break;
++	case ACQ_Z2:
++		ts->z2_raw = data;
++		ts->acq_state = IDLE;
++		// got the raw stuff, now mark BH
++		queue_task(&ts->chug_tq, &tq_immediate);
++		mark_bh(IMMEDIATE_BH);
++		break;
++	}
++
++	spin_unlock(&ts->lock);
++}
++
++
++/* +++++++++++++ File operations ++++++++++++++*/
++
++static int
++au1000_fasync(int fd, struct file *filp, int mode)
++{
++	au1000_ts_t* ts = (au1000_ts_t*)filp->private_data;
++	return fasync_helper(fd, filp, mode, &ts->fasync);
++}
++
++static int
++au1000_ioctl(struct inode * inode, struct file *filp,
++	     unsigned int cmd, unsigned long arg)
++{
++	au1000_ts_t* ts = (au1000_ts_t*)filp->private_data;
++
++	switch(cmd) {
++	case TS_GET_RATE:       /* TODO: what is this? */
++		break;
++	case TS_SET_RATE:       /* TODO: what is this? */
++		break;
++	case TS_GET_CAL:
++		copy_to_user((char *)arg, (char *)&ts->cal, sizeof(TS_CAL));
++		break;
++	case TS_SET_CAL:
++		copy_from_user((char *)&ts->cal, (char *)arg, sizeof(TS_CAL));
++		break;
++	default:
++		err("unknown cmd %04x", cmd);
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++static unsigned int
++au1000_poll(struct file * filp, poll_table * wait)
++{
++	au1000_ts_t* ts = (au1000_ts_t*)filp->private_data;
++	poll_wait(filp, &ts->wait, wait);
++	if (ts->event_count)
++		return POLLIN | POLLRDNORM;
++	return 0;
++}
++
++static ssize_t
++au1000_read(struct file * filp, char * buf, size_t count, loff_t * l)
++{
++	au1000_ts_t* ts = (au1000_ts_t*)filp->private_data;
++	unsigned long flags;
++	TS_EVENT event;
++	int i;
++
++	if (ts->event_count == 0) {
++		if (filp->f_flags & O_NONBLOCK)
++			return -EAGAIN;
++		interruptible_sleep_on(&ts->wait);
++		if (signal_pending(current))
++			return -ERESTARTSYS;
++	}
++
++	for (i = count;
++	     i >= sizeof(TS_EVENT);
++	     i -= sizeof(TS_EVENT), buf += sizeof(TS_EVENT)) {
++		if (ts->event_count == 0)
++			break;
++		spin_lock_irqsave(&ts->lock, flags);
++		event = ts->event_buf[ts->nextOut++];
++		if (ts->nextOut == EVENT_BUFSIZE)
++			ts->nextOut = 0;
++		if (ts->event_count)
++			ts->event_count--;
++		spin_unlock_irqrestore(&ts->lock, flags);
++		copy_to_user(buf, &event, sizeof(TS_EVENT));
++	}
++
++	return count - i;
++}
++
++
++static int
++au1000_open(struct inode * inode, struct file * filp)
++{
++	au1000_ts_t* ts;
++	unsigned long flags;
++
++	filp->private_data = ts = &au1000_ts;
++
++	spin_lock_irqsave(&ts->lock, flags);
++
++	// setup SSI0 config
++	outl(DEFAULT_SSI_CONFIG, SSI0_CONFIG);
++
++	// clear out SSI0 status bits
++	outl(SSISTAT_OF|SSISTAT_UF|SSISTAT_DONE, SSI0_STATUS);
++	// clear out SSI0 interrupt pending bits
++	outl(SSIINT_OI|SSIINT_UI|SSIINT_DI, SSI0_INT);
++
++	// enable SSI0 interrupts
++	outl(SSIINT_OI|SSIINT_UI|SSIINT_DI, SSI0_INT_ENABLE);
++
++	/*
++	 * init bh handler that chugs the raw data (calibrates and
++	 * calculates touch pressure).
++	 */
++	ts->chug_tq.routine = chug_raw_data;
++	ts->chug_tq.data = ts;
++	ts->pendown = 0; // pen up
++	
++	// flush event queue
++	ts->nextIn = ts->nextOut = ts->event_count = 0;
++	
++	// Start acquisition timer function
++	init_timer(&ts->acq_timer);
++	ts->acq_timer.function = au1000_acq_timer;
++	ts->acq_timer.data = (unsigned long)ts;
++	ts->acq_timer.expires = jiffies + HZ / 100;
++	add_timer(&ts->acq_timer);
++
++	spin_unlock_irqrestore(&ts->lock, flags);
++
++	return 0;
++}
++
++static int
++au1000_release(struct inode * inode, struct file * filp)
++{
++	au1000_ts_t* ts = (au1000_ts_t*)filp->private_data;
++	unsigned long flags;
++	
++	au1000_fasync(-1, filp, 0);
++	del_timer_sync(&ts->acq_timer);
++
++	spin_lock_irqsave(&ts->lock, flags);
++	// disable SSI0 interrupts
++	outl(0, SSI0_INT_ENABLE);
++	spin_unlock_irqrestore(&ts->lock, flags);
++
++	return 0;
++}
++
++
++static struct file_operations ts_fops = {
++	read:           au1000_read,
++	poll:           au1000_poll,
++	ioctl:		au1000_ioctl,
++	fasync:         au1000_fasync,
++	open:		au1000_open,
++	release:	au1000_release,
++};
++
++/* +++++++++++++ End File operations ++++++++++++++*/
++
++
++int __init
++au1000ts_init_module(void)
++{
++	au1000_ts_t* ts = &au1000_ts;
++	int ret;
++
++	/* register our character device */
++	if ((ret = register_chrdev(TS_MAJOR, TS_NAME, &ts_fops)) < 0) {
++		err("can't get major number");
++		return ret;
++	}
++	info("registered");
++
++	memset(ts, 0, sizeof(au1000_ts_t));
++	init_waitqueue_head(&ts->wait);
++	spin_lock_init(&ts->lock);
++
++	if (!request_region(virt_to_phys((void*)SSI0_STATUS), 0x100, TS_NAME)) {
++		err("SSI0 ports in use");
++		return -ENXIO;
++	}
++
++	if ((ret = request_irq(AU1000_SSI0_INT, ssi0_interrupt,
++			       SA_SHIRQ | SA_INTERRUPT, TS_NAME, ts))) {
++		err("could not get IRQ");
++		return ret;
++	}
++
++	// initial calibration values
++	ts->cal.xscale = -93;
++	ts->cal.xtrans = 346;
++	ts->cal.yscale = -64;
++	ts->cal.ytrans = 251;
++
++	// init pen up/down hysteresis points
++	ts->pendown_thresh_ohms = DEFAULT_PENDOWN_THRESH_OHMS;
++	ts->penup_thresh_ohms = DEFAULT_PENUP_THRESH_OHMS;
++	ts->pressure_eqn = PRESSURE_EQN_2;
++	// init X and Y plate resistances
++	ts->x_plate_ohms = DEFAULT_X_PLATE_OHMS;
++	ts->y_plate_ohms = DEFAULT_Y_PLATE_OHMS;
++
++	// set GPIO to SSI0 function
++	outl(inl(PIN_FUNCTION) & ~1, PIN_FUNCTION);
++	
++	// enable SSI0 clock and bring SSI0 out of reset
++	outl(0, SSI0_CONTROL);
++	udelay(1000);
++	outl(SSIEN_E, SSI0_CONTROL);
++	udelay(100);
++	
++	// FIXME: is this a working baudrate?
++	ts->clkdiv = 0;
++	ts->baudrate = calc_baudrate(ts->clkdiv);
++	outl(ts->clkdiv, SSI0_CLKDIV);
++
++	info("baudrate = %d Hz", ts->baudrate);
++	
++	return 0;
++}
++
++void
++au1000ts_cleanup_module(void)
++{
++	// disable clocks and hold in reset
++	outl(SSIEN_CD, SSI0_CONTROL);
++	free_irq(AU1000_SSI0_INT, &au1000_ts);
++	release_region(virt_to_phys((void*)SSI0_STATUS), 0x100);
++	unregister_chrdev(TS_MAJOR, TS_NAME);
++}
++
++/* Module information */
++MODULE_AUTHOR("Steve Longerbeam, stevel at mvista.com, www.mvista.com");
++MODULE_DESCRIPTION("Au1000/ADS7846 Touch Screen Driver");
++
++module_init(au1000ts_init_module);
++module_exit(au1000ts_cleanup_module);
+diff -urpNX dontdiff linux-2.6.10/drivers/char/au1000_usbraw.c linux-2.6.10-mips/drivers/char/au1000_usbraw.c
+--- linux-2.6.10/drivers/char/au1000_usbraw.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/au1000_usbraw.c	2004-10-27 02:14:17.000000000 +0200
+@@ -0,0 +1,573 @@
++/*
++ * BRIEF MODULE DESCRIPTION
++ *	Au1x00 USB Device-Side Raw Block Driver (function layer)
++ *
++ * Copyright 2001-2002 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc.
++ *		stevel at mvista.com or source at mvista.com
++ *
++ *  This program is free software; you can redistribute	 it and/or modify it
++ *  under  the terms of	 the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the	License, or (at your
++ *  option) any later version.
++ *
++ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
++ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
++ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  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.
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/signal.h>
++#include <linux/errno.h>
++#include <linux/poll.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/fcntl.h>
++#include <linux/module.h>
++#include <linux/spinlock.h>
++#include <linux/list.h>
++#include <linux/smp_lock.h>
++#undef DEBUG
++#include <linux/usb.h>
++
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/irq.h>
++#include <asm/au1000.h>
++#include <asm/au1000_usbdev.h>
++
++#define USBRAW_MAJOR 190 // FIXME: need a legal major
++#define USBRAW_NAME "usbraw"
++
++#define MAX_NUM_PORTS 2
++
++#define IN_MAX_PACKET_SIZE  64
++#define OUT_MAX_PACKET_SIZE 64
++
++// FIXME: when Au1x00 endpoints 3 and 5 are fixed, make NUM_PORTS=2
++#define NUM_PORTS 1
++#define NUM_EP 2*NUM_PORTS
++
++#define CONFIG_DESC_LEN \
++ USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + NUM_EP*USB_DT_ENDPOINT_SIZE
++
++/* must be power of two */
++#define READ_BUF_SIZE (1<<12)
++
++struct usb_raw_port {
++	unsigned char number;
++	spinlock_t port_lock;
++
++	struct usb_endpoint_descriptor* out_desc;
++	struct usb_endpoint_descriptor* in_desc;
++
++	int out_ep_addr; /* endpoint address of OUT endpoint */
++	int in_ep_addr;  /* endpoint address of IN endpoint */
++	
++	__u8 read_buf[READ_BUF_SIZE]; // FIXME: allocate with get_free_pages
++	int read_nextin, read_nextout;
++	int read_count;
++
++	wait_queue_head_t wait;
++	struct fasync_struct *fasync;     // asynch notification
++
++	int active;	/* someone has this device open */
++	int open_count;	/* number of times this port has been opened */
++};
++
++static struct usb_serial {
++	struct usb_device_descriptor* dev_desc;
++	struct usb_config_descriptor* config_desc;
++	struct usb_interface_descriptor* if_desc;
++	struct usb_string_descriptor * str_desc[6];
++	void* str_desc_buf;
++
++	usbdev_state_t dev_state;
++
++	struct usb_raw_port port[NUM_PORTS];
++} usbraw;
++
++static struct usb_device_descriptor dev_desc = {
++	bLength:USB_DT_DEVICE_SIZE,
++	bDescriptorType:USB_DT_DEVICE,
++	bcdUSB:USBDEV_REV,		//usb rev
++	bDeviceClass:USB_CLASS_PER_INTERFACE,	//class    (none)
++	bDeviceSubClass:0x00,	//subclass (none)
++	bDeviceProtocol:0x00,	//protocol (none)
++	bMaxPacketSize0:USBDEV_EP0_MAX_PACKET_SIZE, //max packet size for ep0
++	idVendor:0x6d04,	//vendor  id
++	idProduct:0x0bc0,	//product id
++	bcdDevice:0x0001,	//BCD rev 0.1
++	iManufacturer:0x01,	//manufactuer string index
++	iProduct:0x02,		//product string index
++	iSerialNumber:0x03,	//serial# string index
++	bNumConfigurations:0x01	//num configurations
++};
++
++static struct usb_endpoint_descriptor ep_desc[] = {
++	{
++		// Bulk IN for Port 0
++		bLength:USB_DT_ENDPOINT_SIZE,
++		bDescriptorType:USB_DT_ENDPOINT,
++		bEndpointAddress:USB_DIR_IN,
++		bmAttributes:USB_ENDPOINT_XFER_BULK,
++		wMaxPacketSize:IN_MAX_PACKET_SIZE,
++		bInterval:0x00	// ignored for bulk
++	},
++	{
++		// Bulk OUT for Port 0
++		bLength:USB_DT_ENDPOINT_SIZE,
++		bDescriptorType:USB_DT_ENDPOINT,
++		bEndpointAddress:USB_DIR_OUT,
++		bmAttributes:USB_ENDPOINT_XFER_BULK,
++		wMaxPacketSize:OUT_MAX_PACKET_SIZE,
++		bInterval:0x00	// ignored for bulk
++	},
++	{
++		// Bulk IN for Port 1
++		bLength:USB_DT_ENDPOINT_SIZE,
++		bDescriptorType:USB_DT_ENDPOINT,
++		bEndpointAddress:USB_DIR_IN,
++		bmAttributes:USB_ENDPOINT_XFER_BULK,
++		wMaxPacketSize:IN_MAX_PACKET_SIZE,
++		bInterval:0x00	// ignored for bulk
++	},
++	{
++		// Bulk OUT for Port 1
++		bLength:USB_DT_ENDPOINT_SIZE,
++		bDescriptorType:USB_DT_ENDPOINT,
++		bEndpointAddress:USB_DIR_OUT,
++		bmAttributes:USB_ENDPOINT_XFER_BULK,
++		wMaxPacketSize:OUT_MAX_PACKET_SIZE,
++		bInterval:0x00	// ignored for bulk
++	}
++};
++
++static struct usb_interface_descriptor if_desc = {
++	bLength:USB_DT_INTERFACE_SIZE,
++	bDescriptorType:USB_DT_INTERFACE,
++	bInterfaceNumber:0x00,
++	bAlternateSetting:0x00,
++	bNumEndpoints:NUM_EP,
++	bInterfaceClass:0xff,
++	bInterfaceSubClass:0xab,
++	bInterfaceProtocol:0x00,
++	iInterface:0x05
++};
++
++static struct usb_config_descriptor config_desc = {
++	bLength:USB_DT_CONFIG_SIZE,
++	bDescriptorType:USB_DT_CONFIG,
++	wTotalLength:CONFIG_DESC_LEN,
++	bNumInterfaces:0x01,
++	bConfigurationValue:0x01,
++	iConfiguration:0x04,	// configuration string
++	bmAttributes:0xc0,	// self-powered
++	MaxPower:20		// 40 mA
++};
++
++// String[0] is a list of Language IDs supported by this device
++static struct usb_string_descriptor string_desc0 = {
++	bLength:4,
++	bDescriptorType:USB_DT_STRING,
++	wData:{0x0409} // English, US
++};
++
++// These strings will be converted to Unicode in string_desc[]
++static char *strings[5] = {
++	"Alchemy Semiconductor",  // iManufacturer
++	"USB Raw Block Device",   // iProduct
++	"0.1",                    // iSerialNumber
++	"USB Raw Config",         // iConfiguration
++	"USB Raw Interface"       // iInterface
++};
++
++
++static void
++receive_callback(struct usb_raw_port *port)
++{
++	int i, pkt_size;
++	usbdev_pkt_t* pkt;
++	
++	if ((pkt_size = usbdev_receive_packet(port->out_ep_addr,
++					      &pkt)) <= 0) {
++		dbg(__FUNCTION__ ": usbdev_receive_packet returns %d",
++		    pkt_size);
++		return;
++	}
++
++	dbg(__FUNCTION__ ": ep%d, size=%d", port->out_ep_addr, pkt_size);
++
++	spin_lock(&port->port_lock);
++	for (i=0; i < pkt_size; i++) {
++		port->read_buf[port->read_nextin++] = pkt->payload[i];
++		port->read_nextin &= (READ_BUF_SIZE - 1);
++		if (++port->read_count == READ_BUF_SIZE)
++			break;
++	}
++	spin_unlock(&port->port_lock);
++
++	/* free the packet */
++	kfree(pkt);
++	
++	// async notify
++	if (port->fasync)
++		kill_fasync(&port->fasync, SIGIO, POLL_IN);
++	// wake up any read call
++	if (waitqueue_active(&port->wait))
++		wake_up_interruptible(&port->wait);
++}
++
++static void
++transmit_callback(struct usb_raw_port *port, usbdev_pkt_t* pkt)
++{
++	dbg(__FUNCTION__ ": ep%d", port->in_ep_addr);
++	/* just free the returned packet */
++	kfree(pkt);
++}
++
++
++static void
++usbraw_callback(usbdev_cb_type_t cb_type, unsigned long arg, void* data)
++{
++	usbdev_pkt_t* pkt;
++	int i;
++	
++	switch (cb_type) {
++	case CB_NEW_STATE:
++		usbraw.dev_state = (usbdev_state_t)arg;
++		break;
++	case CB_PKT_COMPLETE:
++		pkt = (usbdev_pkt_t*)arg;
++		for (i=0; i<NUM_PORTS; i++) {
++			struct usb_raw_port *port = &usbraw.port[i];
++			if (pkt->ep_addr == port->in_ep_addr) {
++				transmit_callback(port, pkt);
++				break;
++			} else if (pkt->ep_addr == port->out_ep_addr) {
++				receive_callback(port);
++				break;
++			}
++		}
++		break;
++	}
++}
++
++/*****************************************************************************
++ * Here begins the driver interface functions
++ *****************************************************************************/
++
++static unsigned int usbraw_poll(struct file * filp, poll_table * wait)
++{
++	struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data;
++	unsigned long flags;
++	int count;
++	
++	poll_wait(filp, &port->wait, wait);
++
++	spin_lock_irqsave(&port->port_lock, flags);
++	count = port->read_count;
++	spin_unlock_irqrestore(&port->port_lock, flags);
++
++	if (count > 0) {
++		dbg(__FUNCTION__ ": count=%d", count);
++		return POLLIN | POLLRDNORM;
++	}
++	
++	return 0;
++}
++
++static int usbraw_fasync(int fd, struct file *filp, int mode)
++{
++	struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data;
++	return fasync_helper(fd, filp, mode, &port->fasync);
++}
++
++static int usbraw_open(struct inode * inode, struct file *filp)
++{
++	int portNumber;
++	struct usb_raw_port *port;
++	unsigned long flags;
++
++	/*
++	 * the device-layer must be in the configured state before the
++	 * function layer can operate.
++	 */
++	if (usbraw.dev_state != CONFIGURED)
++		return -ENODEV;
++	
++	/* set up our port structure making the tty driver remember
++	   our port object, and us it */
++	portNumber = MINOR(inode->i_rdev);
++	port = &usbraw.port[portNumber];
++	filp->private_data = port;
++
++	dbg(__FUNCTION__ ": port %d", port->number);
++
++	spin_lock_irqsave(&port->port_lock, flags);
++
++	++port->open_count;
++
++	if (!port->active) {
++		port->active = 1;
++	}
++
++	/* flush read buffer */
++	port->read_nextin = port->read_nextout = port->read_count = 0;
++
++	spin_unlock_irqrestore(&port->port_lock, flags);
++
++	return 0;
++}
++
++static int usbraw_release(struct inode * inode, struct file * filp)
++{
++	struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data;
++	unsigned long flags;
++
++	dbg(__FUNCTION__ ": port %d", port->number);
++
++	if (!port->active) {
++		err(__FUNCTION__ ": port not opened");
++		return -ENODEV;
++	}
++
++	usbraw_fasync(-1, filp, 0);
++
++	spin_lock_irqsave(&port->port_lock, flags);
++
++	--port->open_count;
++
++	if (port->open_count <= 0) {
++		port->active = 0;
++		port->open_count = 0;
++	}
++
++	spin_unlock_irqrestore(&port->port_lock, flags);
++
++	return 0;
++}
++
++
++static ssize_t usbraw_read(struct file * filp, char * buf,
++			   size_t count, loff_t * l)
++{
++	struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data;
++	unsigned long flags;
++	int i, cnt;
++
++	/*
++	 * the device-layer must be in the configured state before the
++	 * function layer can operate.
++	 */
++	if (usbraw.dev_state != CONFIGURED)
++		return -ENODEV;
++
++	do { 
++		spin_lock_irqsave(&port->port_lock, flags);
++		cnt = port->read_count;
++		spin_unlock_irqrestore(&port->port_lock, flags);
++		if (cnt == 0) {
++			if (filp->f_flags & O_NONBLOCK)
++				return -EAGAIN;
++			interruptible_sleep_on(&port->wait);
++			if (signal_pending(current))
++				return -ERESTARTSYS;
++		}
++	} while (cnt == 0);
++
++	count = (count > cnt) ? cnt : count;
++
++	for (i=0; i<count; i++) {
++		put_user(port->read_buf[port->read_nextout++], &buf[i]);
++		port->read_nextout &= (READ_BUF_SIZE - 1);
++		spin_lock_irqsave(&port->port_lock, flags);
++		port->read_count--;
++		spin_unlock_irqrestore(&port->port_lock, flags);
++		if (port->read_count == 0)
++			break;
++	}
++
++	return i+1;
++}
++
++static ssize_t usbraw_write(struct file * filp, const char * buf,
++			    size_t count, loff_t *ppos)
++{
++	struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data;
++	usbdev_pkt_t* pkt;
++	int ret, max_pkt_sz;
++	
++	/*
++	 * the device-layer must be in the configured state before the
++	 * function layer can operate.
++	 */
++	if (usbraw.dev_state != CONFIGURED)
++		return -ENODEV;
++
++	if (!port->active) {
++		err(__FUNCTION__ ": port not opened");
++		return -EINVAL;
++	}
++
++	if (count == 0) {
++		dbg(__FUNCTION__ ": write request of 0 bytes");
++		return (0);
++	}
++
++	max_pkt_sz = port->in_desc->wMaxPacketSize;
++	count = (count > max_pkt_sz) ? max_pkt_sz : count;
++
++	if ((ret = usbdev_alloc_packet(port->in_ep_addr, count, &pkt)) < 0)
++		return ret;
++
++	copy_from_user(pkt->payload, buf, count);
++	
++	return usbdev_send_packet(port->in_ep_addr, pkt);
++}
++
++static int usbraw_ioctl(struct inode *inode, struct file *filp,
++			unsigned int cmd, unsigned long arg)
++{
++	struct usb_raw_port *port = (struct usb_raw_port *)filp->private_data;
++
++	if (!port->active) {
++		err(__FUNCTION__ ": port not open");
++		return -ENODEV;
++	}
++	// FIXME: need any IOCTLs?
++
++	return -ENOIOCTLCMD;
++}
++
++
++static struct file_operations usbraw_fops = {
++        owner:          THIS_MODULE,
++        write:          usbraw_write,
++	read:           usbraw_read,
++	poll:           usbraw_poll,
++	ioctl:		usbraw_ioctl,
++	fasync:         usbraw_fasync,
++	open:		usbraw_open,
++	release:	usbraw_release,
++};
++
++void usbfn_raw_exit(void)
++{
++	/* kill the device layer */
++	usbdev_exit();
++
++	unregister_chrdev(USBRAW_MAJOR, USBRAW_NAME);
++
++	if (usbraw.str_desc_buf)
++		kfree(usbraw.str_desc_buf);
++}
++
++
++int usbfn_raw_init(void)
++{
++	int ret = 0, i, str_desc_len;
++
++	/* register our character device */
++	if ((ret = register_chrdev(USBRAW_MAJOR, USBRAW_NAME,
++				   &usbraw_fops)) < 0) {
++		err("can't get major number");
++		return ret;
++	}
++	info("registered");
++
++	/*
++	 * initialize pointers to descriptors
++	 */
++	usbraw.dev_desc = &dev_desc;
++	usbraw.config_desc = &config_desc;
++	usbraw.if_desc = &if_desc;
++
++	/*
++	 * initialize the string descriptors
++	 */
++
++	/* alloc buffer big enough for all string descriptors */
++	str_desc_len = string_desc0.bLength;
++	for (i = 0; i < 5; i++)
++		str_desc_len += 2 + 2 * strlen(strings[i]);
++	usbraw.str_desc_buf = (void *) kmalloc(str_desc_len, GFP_KERNEL);
++	if (!usbraw.str_desc_buf) {
++		err(__FUNCTION__ ": failed to alloc string descriptors");
++		ret = -ENOMEM;
++		goto out;
++	}
++
++	usbraw.str_desc[0] =
++		(struct usb_string_descriptor *)usbraw.str_desc_buf;
++	memcpy(usbraw.str_desc[0], &string_desc0, string_desc0.bLength);
++	usbraw.str_desc[1] = (struct usb_string_descriptor *)
++		(usbraw.str_desc_buf + string_desc0.bLength);
++	for (i = 1; i < 6; i++) {
++		struct usb_string_descriptor *desc = usbraw.str_desc[i];
++		char *str = strings[i - 1];
++		int j, str_len = strlen(str);
++
++		desc->bLength = 2 + 2 * str_len;
++		desc->bDescriptorType = USB_DT_STRING;
++		for (j = 0; j < str_len; j++) {
++			desc->wData[j] = (u16) str[j];
++		}
++		if (i < 5)
++			usbraw.str_desc[i + 1] =
++				(struct usb_string_descriptor *)
++				((u8 *) desc + desc->bLength);
++	}
++
++	/*
++	 * start the device layer. The device layer assigns us
++	 * our endpoint addresses
++	 */
++	if ((ret = usbdev_init(&dev_desc, &config_desc, &if_desc, ep_desc,
++			       usbraw.str_desc, usbraw_callback, NULL))) {
++		err(__FUNCTION__ ": device-layer init failed");
++		goto out;
++	}
++	
++	/* initialize the devfs nodes for this device and let the user
++	   know what ports we are bound to */
++	for (i = 0; i < NUM_PORTS; ++i) {
++		struct usb_raw_port *port = &usbraw.port[i];
++
++		port->number = i;
++		port->in_desc = &ep_desc[NUM_PORTS*i];
++		port->out_desc = &ep_desc[NUM_PORTS*i + 1];
++		port->in_ep_addr = port->in_desc->bEndpointAddress & 0x0f;
++		port->out_ep_addr = port->out_desc->bEndpointAddress & 0x0f;
++		init_waitqueue_head(&port->wait);
++		spin_lock_init(&port->port_lock);
++	}
++
++ out:
++	if (ret)
++		usbfn_raw_exit();
++	return ret;
++}
++
++
++/* Module information */
++MODULE_AUTHOR("Steve Longerbeam, stevel at mvista.com, www.mvista.com");
++MODULE_DESCRIPTION("Au1x00 USB Device-Side Raw Block Driver");
++MODULE_LICENSE("GPL");
++
++module_init(usbfn_raw_init);
++module_exit(usbfn_raw_exit);
+diff -urpNX dontdiff linux-2.6.10/drivers/char/au1000_usbtty.c linux-2.6.10-mips/drivers/char/au1000_usbtty.c
+--- linux-2.6.10/drivers/char/au1000_usbtty.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/au1000_usbtty.c	2004-10-27 02:14:17.000000000 +0200
+@@ -0,0 +1,761 @@
++/*
++ * BRIEF MODULE DESCRIPTION
++ *	Au1x00 USB Device-Side Serial TTY Driver (function layer)
++ *
++ * Copyright 2001-2002 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc.
++ *		stevel at mvista.com or source at mvista.com
++ *
++ *  Derived from drivers/usb/serial/usbserial.c:
++ *
++ *  Copyright (C) 1999 - 2001 Greg Kroah-Hartman (greg at kroah.com)
++ *  Copyright (c) 2000 Peter Berger (pberger at brimson.com)
++ *  Copyright (c) 2000 Al Borchers (borchers at steinerpoint.com)
++ *
++ *  This program is free software; you can redistribute	 it and/or modify it
++ *  under  the terms of	 the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the	License, or (at your
++ *  option) any later version.
++ *
++ *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
++ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
++ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  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.
++ */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/signal.h>
++#include <linux/errno.h>
++#include <linux/poll.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/fcntl.h>
++#include <linux/tty.h>
++#include <linux/tty_driver.h>
++#include <linux/tty_flip.h>
++#include <linux/module.h>
++#include <linux/spinlock.h>
++#include <linux/list.h>
++#include <linux/smp_lock.h>
++#undef DEBUG
++#include <linux/usb.h>
++
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/irq.h>
++#include <asm/au1000.h>
++#include <asm/au1000_usbdev.h>
++
++
++/* local function prototypes */
++static int serial_open(struct tty_struct *tty, struct file *filp);
++static void serial_close(struct tty_struct *tty, struct file *filp);
++static int serial_write(struct tty_struct *tty, int from_user,
++			const unsigned char *buf, int count);
++static int serial_write_room(struct tty_struct *tty);
++static int serial_chars_in_buffer(struct tty_struct *tty);
++static void serial_throttle(struct tty_struct *tty);
++static void serial_unthrottle(struct tty_struct *tty);
++static int serial_ioctl(struct tty_struct *tty, struct file *file,
++			unsigned int cmd, unsigned long arg);
++static void serial_set_termios (struct tty_struct *tty, struct termios * old);
++
++#define SERIAL_TTY_MAJOR 189 // FIXME: need a legal major
++
++#define MAX_NUM_PORTS 2
++
++#define IN_MAX_PACKET_SIZE  32
++#define OUT_MAX_PACKET_SIZE 32
++
++// FIXME: when Au1x00 endpoints 3 and 5 are fixed, make NUM_PORTS=2
++#define NUM_PORTS 2
++#define NUM_EP 2*NUM_PORTS
++
++#define CONFIG_DESC_LEN \
++ USB_DT_CONFIG_SIZE + USB_DT_INTERFACE_SIZE + NUM_EP*USB_DT_ENDPOINT_SIZE
++
++struct usb_serial_port {
++	struct tty_struct *tty;	   /* the coresponding tty for this port */
++	unsigned char number;
++	spinlock_t port_lock;
++
++	struct usb_endpoint_descriptor* out_desc;
++	struct usb_endpoint_descriptor* in_desc;
++
++	int out_ep_addr; /* endpoint address of OUT endpoint */
++	int in_ep_addr;  /* endpoint address of IN endpoint */
++	
++	/* task queue for line discipline waking up on send packet complete */
++	struct tq_struct send_complete_tq;
++	/* task queue for line discipline wakeup on receive packet complete */
++	struct tq_struct receive_complete_tq;
++
++	int active;	/* someone has this device open */
++	int writing;    /* a packet write is in progress */
++	int open_count;	/* number of times this port has been opened */
++
++};
++
++static struct usb_serial {
++	usbdev_state_t dev_state; // current state of device layer
++	struct usb_device_descriptor* dev_desc;
++	struct usb_config_descriptor* config_desc;
++	struct usb_interface_descriptor* if_desc;
++	struct usb_string_descriptor * str_desc[6];
++	void* str_desc_buf;
++
++	struct usb_serial_port port[NUM_PORTS];
++} usbtty;
++
++static int                 serial_refcount;
++static struct tty_driver   serial_tty_driver;
++static struct tty_struct * serial_tty[NUM_PORTS];
++static struct termios *    serial_termios[NUM_PORTS];
++static struct termios *    serial_termios_locked[NUM_PORTS];
++
++static struct usb_device_descriptor dev_desc = {
++	bLength:USB_DT_DEVICE_SIZE,
++	bDescriptorType:USB_DT_DEVICE,
++	bcdUSB:USBDEV_REV,		//usb rev
++	bDeviceClass:USB_CLASS_PER_INTERFACE,	//class    (none)
++	bDeviceSubClass:0x00,	//subclass (none)
++	bDeviceProtocol:0x00,	//protocol (none)
++	bMaxPacketSize0:USBDEV_EP0_MAX_PACKET_SIZE, //max packet size for ep0
++	idVendor:0x6d04,	//vendor  id
++	idProduct:0x0bc0,	//product id
++	bcdDevice:0x0001,	//BCD rev 0.1
++	iManufacturer:0x01,	//manufactuer string index
++	iProduct:0x02,		//product string index
++	iSerialNumber:0x03,	//serial# string index
++	bNumConfigurations:0x01	//num configurations
++};
++
++static struct usb_endpoint_descriptor ep_desc[] = {
++	{
++		// Bulk IN for Port 0
++		bLength:USB_DT_ENDPOINT_SIZE,
++		bDescriptorType:USB_DT_ENDPOINT,
++		bEndpointAddress:USB_DIR_IN,
++		bmAttributes:USB_ENDPOINT_XFER_BULK,
++		wMaxPacketSize:IN_MAX_PACKET_SIZE,
++		bInterval:0x00	// ignored for bulk
++	},
++	{
++		// Bulk OUT for Port 0
++		bLength:USB_DT_ENDPOINT_SIZE,
++		bDescriptorType:USB_DT_ENDPOINT,
++		bEndpointAddress:USB_DIR_OUT,
++		bmAttributes:USB_ENDPOINT_XFER_BULK,
++		wMaxPacketSize:OUT_MAX_PACKET_SIZE,
++		bInterval:0x00	// ignored for bulk
++	},
++	{
++		// Bulk IN for Port 1
++		bLength:USB_DT_ENDPOINT_SIZE,
++		bDescriptorType:USB_DT_ENDPOINT,
++		bEndpointAddress:USB_DIR_IN,
++		bmAttributes:USB_ENDPOINT_XFER_BULK,
++		wMaxPacketSize:IN_MAX_PACKET_SIZE,
++		bInterval:0x00	// ignored for bulk
++	},
++	{
++		// Bulk OUT for Port 1
++		bLength:USB_DT_ENDPOINT_SIZE,
++		bDescriptorType:USB_DT_ENDPOINT,
++		bEndpointAddress:USB_DIR_OUT,
++		bmAttributes:USB_ENDPOINT_XFER_BULK,
++		wMaxPacketSize:OUT_MAX_PACKET_SIZE,
++		bInterval:0x00	// ignored for bulk
++	}
++};
++
++static struct usb_interface_descriptor if_desc = {
++	bLength:USB_DT_INTERFACE_SIZE,
++	bDescriptorType:USB_DT_INTERFACE,
++	bInterfaceNumber:0x00,
++	bAlternateSetting:0x00,
++	bNumEndpoints:NUM_EP,
++	bInterfaceClass:0xff,
++	bInterfaceSubClass:0xab,
++	bInterfaceProtocol:0x00,
++	iInterface:0x05
++};
++
++static struct usb_config_descriptor config_desc = {
++	bLength:USB_DT_CONFIG_SIZE,
++	bDescriptorType:USB_DT_CONFIG,
++	wTotalLength:CONFIG_DESC_LEN,
++	bNumInterfaces:0x01,
++	bConfigurationValue:0x01,
++	iConfiguration:0x04,	// configuration string
++	bmAttributes:0xc0,	// self-powered
++	MaxPower:20		// 40 mA
++};
++
++// String[0] is a list of Language IDs supported by this device
++static struct usb_string_descriptor string_desc0 = {
++	bLength:4,
++	bDescriptorType:USB_DT_STRING,
++	wData:{0x0409} // English, US
++};
++
++// These strings will be converted to Unicode in string_desc[]
++static char *strings[5] = {
++	"Alchemy Semiconductor",  // iManufacturer
++	"WutzAMattaU",            // iProduct
++	"1.0.doh!",               // iSerialNumber
++	"Au1000 TTY Config",      // iConfiguration
++	"Au1000 TTY Interface"    // iInterface
++};
++
++static inline int
++port_paranoia_check(struct usb_serial_port *port, const char *function)
++{
++	if (!port) {
++		err("%s: port is NULL", function);
++		return -1;
++	}
++	if (!port->tty) {
++		err("%s: port->tty is NULL", function);
++		return -1;
++	}
++
++	return 0;
++}
++
++
++static void
++port_rx_callback(struct usb_serial_port *port)
++{
++	dbg(__FUNCTION__ ": ep%d", port->out_ep_addr);
++	// mark a bh to push this data up to the tty
++	queue_task(&port->receive_complete_tq, &tq_immediate);
++	mark_bh(IMMEDIATE_BH);
++}
++
++static void
++port_tx_callback(struct usb_serial_port *port, usbdev_pkt_t* pkt)
++{
++	dbg(__FUNCTION__ ": ep%d", port->in_ep_addr);
++	// mark a bh to wakeup any tty write system call on the port.
++	queue_task(&port->send_complete_tq, &tq_immediate);
++	mark_bh(IMMEDIATE_BH);
++
++	/* free the returned packet */
++	kfree(pkt);
++}
++
++static void
++usbtty_callback(usbdev_cb_type_t cb_type, unsigned long arg, void* data)
++{
++	usbdev_pkt_t* pkt;
++	int i;
++	
++	switch (cb_type) {
++	case CB_NEW_STATE:
++		dbg(__FUNCTION__ ": new dev_state=%d", (int)arg);
++		usbtty.dev_state = (usbdev_state_t)arg;
++		break;
++	case CB_PKT_COMPLETE:
++		pkt = (usbdev_pkt_t*)arg;
++		for (i=0; i<NUM_PORTS; i++) {
++			struct usb_serial_port *port = &usbtty.port[i];
++			if (pkt->ep_addr == port->in_ep_addr) {
++				port_tx_callback(port, pkt);
++				break;
++			} else if (pkt->ep_addr == port->out_ep_addr) {
++				port_rx_callback(port);
++				break;
++			}
++		}
++		break;
++	}
++}
++
++
++/*****************************************************************************
++ * Here begins the tty driver interface functions
++ *****************************************************************************/
++
++static int serial_open(struct tty_struct *tty, struct file *filp)
++{
++	int portNumber;
++	struct usb_serial_port *port;
++	unsigned long flags;
++
++	/* initialize the pointer incase something fails */
++	tty->driver_data = NULL;
++
++	/* set up our port structure making the tty driver remember
++	   our port object, and us it */
++	portNumber = MINOR(tty->device);
++	port = &usbtty.port[portNumber];
++	tty->driver_data = port;
++	port->tty = tty;
++
++	if (usbtty.dev_state != CONFIGURED ||
++	    port_paranoia_check(port, __FUNCTION__)) {
++		/*
++		 * the device-layer must be in the configured state before
++		 * the function layer can operate.
++		 */
++		return -ENODEV;
++	}
++	
++	dbg(__FUNCTION__ ": port %d", port->number);
++
++	spin_lock_irqsave(&port->port_lock, flags);
++
++	++port->open_count;
++
++	if (!port->active) {
++		port->active = 1;
++
++		/*
++		 * force low_latency on so that our tty_push actually forces
++		 * the data through, otherwise it is scheduled, and with high
++		 * data rates (like with OHCI) data can get lost.
++		 */
++		port->tty->low_latency = 1;
++
++	}
++
++	spin_unlock_irqrestore(&port->port_lock, flags);
++
++	return 0;
++}
++
++
++static void serial_close(struct tty_struct *tty, struct file *filp)
++{
++	struct usb_serial_port *port =
++		(struct usb_serial_port *) tty->driver_data;
++	unsigned long flags;
++
++	dbg(__FUNCTION__ ": port %d", port->number);
++
++	if (!port->active) {
++		err(__FUNCTION__ ": port not opened");
++		return;
++	}
++
++	spin_lock_irqsave(&port->port_lock, flags);
++
++	--port->open_count;
++
++	if (port->open_count <= 0) {
++		port->active = 0;
++		port->open_count = 0;
++	}
++
++	spin_unlock_irqrestore(&port->port_lock, flags);
++	MOD_DEC_USE_COUNT;
++}
++
++
++static int serial_write(struct tty_struct *tty, int from_user,
++			const unsigned char *buf, int count)
++{
++	struct usb_serial_port *port =
++		(struct usb_serial_port *) tty->driver_data;
++	usbdev_pkt_t* pkt;
++	int max_pkt_sz, ret;
++	unsigned long flags;
++	
++	/*
++	 * the device-layer must be in the configured state before the
++	 * function layer can operate.
++	 */
++	if (usbtty.dev_state != CONFIGURED)
++		return -ENODEV;
++
++	if (!port->active) {
++		err(__FUNCTION__ ": port not open");
++		return -EINVAL;
++	}
++
++	if (count == 0) {
++		dbg(__FUNCTION__ ": request of 0 bytes");
++		return (0);
++	}
++
++#if 0
++	if (port->writing) {
++		dbg(__FUNCTION__ ": already writing");
++		return 0;
++	}
++#endif
++	
++	max_pkt_sz = port->in_desc->wMaxPacketSize;
++	count = (count > max_pkt_sz) ? max_pkt_sz : count;
++
++	if ((ret = usbdev_alloc_packet(port->in_ep_addr, count, &pkt)))
++		return ret;
++
++	if (from_user)
++		copy_from_user(pkt->payload, buf, count);
++	else
++		memcpy(pkt->payload, buf, count);
++	
++	ret = usbdev_send_packet(port->in_ep_addr, pkt);
++
++	spin_lock_irqsave(&port->port_lock, flags);
++	port->writing = 1;
++	spin_unlock_irqrestore(&port->port_lock, flags);
++
++	return ret;
++}
++
++
++static int serial_write_room(struct tty_struct *tty)
++{
++	struct usb_serial_port *port =
++		(struct usb_serial_port *) tty->driver_data;
++	int room = 0;
++	
++	/*
++	 * the device-layer must be in the configured state before the
++	 * function layer can operate.
++	 */
++	if (usbtty.dev_state != CONFIGURED)
++		return -ENODEV;
++
++	if (!port->active) {
++		err(__FUNCTION__ ": port not open");
++		return -EINVAL;
++	}
++
++	//room = port->writing ? 0 : port->in_desc->wMaxPacketSize;
++	room = port->in_desc->wMaxPacketSize;
++	
++	dbg(__FUNCTION__ ": %d", room);
++	return room;
++}
++
++
++static int serial_chars_in_buffer(struct tty_struct *tty)
++{
++	struct usb_serial_port *port =
++		(struct usb_serial_port *) tty->driver_data;
++	int chars = 0;
++	
++	/*
++	 * the device-layer must be in the configured state before the
++	 * function layer can operate.
++	 */
++	if (usbtty.dev_state != CONFIGURED)
++		return -ENODEV;
++
++	if (!port->active) {
++		err(__FUNCTION__ ": port not open");
++		return -EINVAL;
++	}
++
++	//chars = port->writing ? usbdev_get_byte_count(port->in_ep_addr) : 0;
++	chars = usbdev_get_byte_count(port->in_ep_addr);
++
++	dbg(__FUNCTION__ ": %d", chars);
++	return chars;
++}
++
++
++static void serial_throttle(struct tty_struct *tty)
++{
++	struct usb_serial_port *port =
++		(struct usb_serial_port *) tty->driver_data;
++
++	if (!port->active || usbtty.dev_state != CONFIGURED) {
++		err(__FUNCTION__ ": port not open");
++		return;
++	}
++
++	// FIXME: anything to do?
++	dbg(__FUNCTION__);
++}
++
++
++static void serial_unthrottle(struct tty_struct *tty)
++{
++	struct usb_serial_port *port =
++		(struct usb_serial_port *) tty->driver_data;
++
++	if (!port->active || usbtty.dev_state != CONFIGURED) {
++		err(__FUNCTION__ ": port not open");
++		return;
++	}
++
++	// FIXME: anything to do?
++	dbg(__FUNCTION__);
++}
++
++
++static int serial_ioctl(struct tty_struct *tty, struct file *file,
++			unsigned int cmd, unsigned long arg)
++{
++	struct usb_serial_port *port =
++		(struct usb_serial_port *) tty->driver_data;
++
++	if (!port->active) {
++		err(__FUNCTION__ ": port not open");
++		return -ENODEV;
++	}
++	// FIXME: need any IOCTLs?
++	dbg(__FUNCTION__);
++
++	return -ENOIOCTLCMD;
++}
++
++
++static void serial_set_termios(struct tty_struct *tty, struct termios *old)
++{
++	struct usb_serial_port *port =
++		(struct usb_serial_port *) tty->driver_data;
++
++	if (!port->active || usbtty.dev_state != CONFIGURED)  {
++		err(__FUNCTION__ ": port not open");
++		return;
++	}
++
++	dbg(__FUNCTION__);
++	// FIXME: anything to do?
++}
++
++
++static void serial_break(struct tty_struct *tty, int break_state)
++{
++	struct usb_serial_port *port =
++		(struct usb_serial_port *) tty->driver_data;
++
++	if (!port->active || usbtty.dev_state != CONFIGURED)  {
++		err(__FUNCTION__ ": port not open");
++		return;
++	}
++
++	dbg(__FUNCTION__);
++	// FIXME: anything to do?
++}
++
++
++static void port_send_complete(void *private)
++{
++	struct usb_serial_port *port = (struct usb_serial_port *) private;
++	struct tty_struct *tty;
++	unsigned long flags;
++
++	dbg(__FUNCTION__ ": port %d, ep%d", port->number, port->in_ep_addr);
++
++	tty = port->tty;
++	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
++	    tty->ldisc.write_wakeup) {
++		dbg(__FUNCTION__ ": write wakeup call.");
++		(tty->ldisc.write_wakeup) (tty);
++	}
++
++	wake_up_interruptible(&tty->write_wait);
++
++	spin_lock_irqsave(&port->port_lock, flags);
++	port->writing = usbdev_get_byte_count(port->in_ep_addr) <= 0 ? 0 : 1;
++	spin_unlock_irqrestore(&port->port_lock, flags);
++}
++
++
++static void port_receive_complete(void *private)
++{
++	struct usb_serial_port *port = (struct usb_serial_port *) private;
++	struct tty_struct *tty = port->tty;
++	usbdev_pkt_t* pkt = NULL;
++	int i, count;
++
++	/* while there is a packet available */
++	while ((count = usbdev_receive_packet(port->out_ep_addr,
++					      &pkt)) != -ENODATA) {
++		if (count < 0) {
++			if (pkt)
++				kfree(pkt);
++			break; /* exit if error other than ENODATA */
++		}
++		
++		dbg(__FUNCTION__ ": port %d, ep%d, size=%d",
++		    port->number, port->out_ep_addr, count);
++
++		for (i = 0; i < count; i++) {
++			/* if we insert more than TTY_FLIPBUF_SIZE characters,
++			   we drop them. */
++			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
++				tty_flip_buffer_push(tty);
++			}
++			/* this doesn't actually push the data through
++			   unless tty->low_latency is set */
++			tty_insert_flip_char(tty, pkt->payload[i], 0);
++		}
++		tty_flip_buffer_push(tty);
++
++		kfree(pkt); /* make sure we free the packet */
++	}
++
++}
++
++
++static struct tty_driver serial_tty_driver = {
++	magic:TTY_DRIVER_MAGIC,
++	driver_name:"usbfn-tty",
++	name:"usb/ttsdev/%d",
++	major:SERIAL_TTY_MAJOR,
++	minor_start:0,
++	num:NUM_PORTS,
++	type:TTY_DRIVER_TYPE_SERIAL,
++	subtype:SERIAL_TYPE_NORMAL,
++	flags:TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
++	refcount:&serial_refcount,
++	table:serial_tty,
++	termios:serial_termios,
++	termios_locked:serial_termios_locked,
++
++	open:serial_open,
++	close:serial_close,
++	write:serial_write,
++	write_room:serial_write_room,
++	ioctl:serial_ioctl,
++	set_termios:serial_set_termios,
++	throttle:serial_throttle,
++	unthrottle:serial_unthrottle,
++	break_ctl:serial_break,
++	chars_in_buffer:serial_chars_in_buffer,
++};
++
++
++void usbfn_tty_exit(void)
++{
++	int i;
++	
++	/* kill the device layer */
++	usbdev_exit();
++
++	for (i=0; i < NUM_PORTS; i++) {
++		tty_unregister_devfs(&serial_tty_driver, i);
++		info("usb serial converter now disconnected from ttyUSBdev%d",
++		     i);
++	}
++
++	tty_unregister_driver(&serial_tty_driver);
++
++	if (usbtty.str_desc_buf)
++		kfree(usbtty.str_desc_buf);
++}
++
++
++int usbfn_tty_init(void)
++{
++	int ret = 0, i, str_desc_len;
++
++	/* register the tty driver */
++	serial_tty_driver.init_termios = tty_std_termios;
++	serial_tty_driver.init_termios.c_cflag =
++		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
++	
++	if (tty_register_driver(&serial_tty_driver)) {
++		err(__FUNCTION__ ": failed to register tty driver");
++		ret = -ENXIO;
++		goto out;
++	}
++
++	/*
++	 * initialize pointers to descriptors
++	 */
++	usbtty.dev_desc = &dev_desc;
++	usbtty.config_desc = &config_desc;
++	usbtty.if_desc = &if_desc;
++
++	/*
++	 * initialize the string descriptors
++	 */
++
++	/* alloc buffer big enough for all string descriptors */
++	str_desc_len = string_desc0.bLength;
++	for (i = 0; i < 5; i++)
++		str_desc_len += 2 + 2 * strlen(strings[i]);
++	usbtty.str_desc_buf = (void *) kmalloc(str_desc_len, GFP_KERNEL);
++	if (!usbtty.str_desc_buf) {
++		err(__FUNCTION__ ": failed to alloc string descriptors");
++		ret = -ENOMEM;
++		goto out;
++	}
++
++	usbtty.str_desc[0] =
++		(struct usb_string_descriptor *)usbtty.str_desc_buf;
++	memcpy(usbtty.str_desc[0], &string_desc0, string_desc0.bLength);
++	usbtty.str_desc[1] = (struct usb_string_descriptor *)
++		(usbtty.str_desc_buf + string_desc0.bLength);
++	for (i = 1; i < 6; i++) {
++		struct usb_string_descriptor *desc = usbtty.str_desc[i];
++		char *str = strings[i - 1];
++		int j, str_len = strlen(str);
++
++		desc->bLength = 2 + 2 * str_len;
++		desc->bDescriptorType = USB_DT_STRING;
++		for (j = 0; j < str_len; j++) {
++			desc->wData[j] = (u16) str[j];
++		}
++		if (i < 5)
++			usbtty.str_desc[i + 1] =
++				(struct usb_string_descriptor *)
++				((u8 *) desc + desc->bLength);
++	}
++
++	/*
++	 * start the device layer. The device layer assigns us
++	 * our endpoint addresses
++	 */
++	if ((ret = usbdev_init(&dev_desc, &config_desc, &if_desc, ep_desc,
++			       usbtty.str_desc, usbtty_callback, NULL))) {
++		err(__FUNCTION__ ": device-layer init failed");
++		goto out;
++	}
++	
++	/* initialize the devfs nodes for this device and let the user
++	   know what ports we are bound to */
++	for (i = 0; i < NUM_PORTS; ++i) {
++		struct usb_serial_port *port;
++		tty_register_devfs(&serial_tty_driver, 0, i);
++		info("usbdev serial attached to ttyUSBdev%d "
++		     "(or devfs usb/ttsdev/%d)", i, i);
++		port = &usbtty.port[i];
++		port->number = i;
++		port->in_desc = &ep_desc[NUM_PORTS*i];
++		port->out_desc = &ep_desc[NUM_PORTS*i + 1];
++		port->in_ep_addr = port->in_desc->bEndpointAddress & 0x0f;
++		port->out_ep_addr = port->out_desc->bEndpointAddress & 0x0f;
++		port->send_complete_tq.routine = port_send_complete;
++		port->send_complete_tq.data = port;
++		port->receive_complete_tq.routine = port_receive_complete;
++		port->receive_complete_tq.data = port;
++		spin_lock_init(&port->port_lock);
++	}
++
++ out:
++	if (ret)
++		usbfn_tty_exit();
++	return ret;
++}
++
++
++/* Module information */
++MODULE_AUTHOR("Steve Longerbeam, stevel at mvista.com, www.mvista.com");
++MODULE_DESCRIPTION("Au1x00 USB Device-Side Serial TTY Driver");
++MODULE_LICENSE("GPL");
++
++module_init(usbfn_tty_init);
++module_exit(usbfn_tty_exit);
+diff -urpNX dontdiff linux-2.6.10/drivers/char/decserial.c linux-2.6.10-mips/drivers/char/decserial.c
+--- linux-2.6.10/drivers/char/decserial.c	2004-12-24 22:33:51.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/decserial.c	2004-09-21 13:10:14.000000000 +0200
+@@ -14,87 +14,85 @@
+  *      device. Added support for PROM console in drivers/char/tty_io.c
+  *      instead. Although it may work to enable more than one 
+  *      console device I strongly recommend to use only one.
++ *
++ *	Copyright (C) 2004  Maciej W. Rozycki
+  */
+ 
+ #include <linux/config.h>
++#include <linux/errno.h>
+ #include <linux/init.h>
+-#include <asm/dec/machtype.h>
+-
+-#ifdef CONFIG_ZS
+-extern int zs_init(void);
+-#endif
+ 
+-#ifdef CONFIG_DZ
+-extern int dz_init(void);
+-#endif
++#include <asm/dec/machtype.h>
++#include <asm/dec/serial.h>
+ 
+-#ifdef CONFIG_SERIAL_CONSOLE
++extern int register_zs_hook(unsigned int channel,
++			    struct dec_serial_hook *hook);
++extern int unregister_zs_hook(unsigned int channel);
+ 
++int register_dec_serial_hook(unsigned int channel,
++			     struct dec_serial_hook *hook)
++{
+ #ifdef CONFIG_ZS
+-extern void zs_serial_console_init(void);
+-#endif
+-
+-#ifdef CONFIG_DZ
+-extern void dz_serial_console_init(void);
++	if (IOASIC)
++		return register_zs_hook(channel, hook);
+ #endif
++	return 0;
++}
+ 
++int unregister_dec_serial_hook(unsigned int channel)
++{
++#ifdef CONFIG_ZS
++	if (IOASIC)
++		return unregister_zs_hook(channel);
+ #endif
++	return 0;
++}
+ 
+-/* rs_init - starts up the serial interface -
+-   handle normal case of starting up the serial interface */
+ 
+-#ifdef CONFIG_SERIAL
++extern int zs_init(void);
++extern int dz_init(void);
+ 
++/*
++ * rs_init - starts up the serial interface -
++ * handle normal case of starting up the serial interface
++ */
+ int __init rs_init(void)
+ {
+-
+-#if defined(CONFIG_ZS) && defined(CONFIG_DZ)
+-    if (IOASIC)
+-	return zs_init();
+-    else
+-	return dz_init();
+-#else
+-
+ #ifdef CONFIG_ZS
+-    return zs_init();
++	if (IOASIC)
++		return zs_init();
+ #endif
+-
+ #ifdef CONFIG_DZ
+-    return dz_init();
+-#endif
+-
++	if (!IOASIC)
++		return dz_init();
+ #endif
++	return -ENXIO;
+ }
+ 
+ __initcall(rs_init);
+ 
+-#endif
+ 
+-#ifdef CONFIG_SERIAL_CONSOLE
++#ifdef CONFIG_SERIAL_DEC_CONSOLE
++
++extern void zs_serial_console_init(void);
++extern void dz_serial_console_init(void);
+ 
+-/* serial_console_init handles the special case of starting
+- *   up the console on the serial port
++/*
++ * dec_serial_console_init handles the special case of starting
++ * up the console on the serial port
+  */
+-static int __init decserial_console_init(void)
++static int __init dec_serial_console_init(void)
+ {
+-#if defined(CONFIG_ZS) && defined(CONFIG_DZ)
+-    if (IOASIC)
+-	zs_serial_console_init();
+-    else
+-	dz_serial_console_init();
+-#else
+-
+ #ifdef CONFIG_ZS
+-    zs_serial_console_init();
++	if (IOASIC)
++		zs_serial_console_init();
+ #endif
+-
+ #ifdef CONFIG_DZ
+-    dz_serial_console_init();
+-#endif
+-
++	if (!IOASIC)
++		dz_serial_console_init();
+ #endif
+     return 0;
+ }
+-console_initcall(decserial_console_init);
++console_initcall(dec_serial_console_init);
+ 
+ #endif
+diff -urpNX dontdiff linux-2.6.10/drivers/char/generic_serial.c linux-2.6.10-mips/drivers/char/generic_serial.c
+--- linux-2.6.10/drivers/char/generic_serial.c	2004-12-24 22:34:45.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/generic_serial.c	2004-11-19 01:14:22.000000000 +0100
+@@ -21,6 +21,7 @@
+ 
+ #include <linux/module.h>
+ #include <linux/kernel.h>
++#include <linux/interrupt.h>
+ #include <linux/tty.h>
+ #include <linux/serial.h>
+ #include <linux/mm.h>
+diff -urpNX dontdiff linux-2.6.10/drivers/char/ibm_workpad_keymap.map linux-2.6.10-mips/drivers/char/ibm_workpad_keymap.map
+--- linux-2.6.10/drivers/char/ibm_workpad_keymap.map	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/ibm_workpad_keymap.map	2003-12-20 15:18:07.000000000 +0100
+@@ -0,0 +1,343 @@
++# Keymap for IBM Workpad z50
++# US Mapping
++#
++# by Michael Klar <wyldfier at iname.com>
++#
++# This is a great big mess on account of how the Caps Lock key is handled as
++# LeftShift-RightShift.  Right shift key had to be broken out, so don't use
++# use this map file as a basis for other keyboards that don't do the same
++# thing with Caps Lock.
++#
++# This file is subject to the terms and conditions of the GNU General Public
++# License.  See the file "COPYING" in the main directory of this archive
++# for more details.
++
++keymaps 0-2,4-5,8,12,32-33,36-37
++strings as usual
++
++keycode 0 = F1 F11 Console_13
++	shiftr keycode 0 = F11
++	shift shiftr keycode 0 = F11
++	control keycode 0 = F1
++	alt keycode 0 = Console_1
++	control alt keycode 0 = Console_1
++keycode 1 = F3 F13 Console_15
++	shiftr keycode 1 = F13
++	shift shiftr keycode 1 = F13
++	control keycode 1 = F3
++	alt keycode 1 = Console_3
++	control alt keycode 1 = Console_3
++keycode 2 = F5 F15 Console_17
++	shiftr keycode 2 = F15
++	shift shiftr keycode 2 = F15
++	control keycode 2 = F5
++	alt keycode 2 = Console_5
++	control alt keycode 2 = Console_5
++keycode 3 = F7 F17 Console_19
++	shiftr keycode 3 = F17
++	shift shiftr keycode 3 = F17
++	control keycode 3 = F7
++	alt keycode 3 = Console_7
++	control alt keycode 3 = Console_7
++keycode 4 = F9 F19 Console_21
++	shiftr keycode 4 = F19
++	shift shiftr keycode 4 = F19
++	control keycode 4 = F9
++	alt keycode 4 = Console_9
++	control alt keycode 4 = Console_9
++#keycode 5 is contrast down
++#keycode 6 is contrast up
++keycode 7 = F11 F11 Console_23
++	shiftr keycode 7 = F11
++	shift shiftr keycode 7 = F11
++	control keycode 7 = F11
++	alt keycode 7 = Console_11
++	control alt keycode 7 = Console_11
++keycode 8 = F2 F12 Console_14
++	shiftr keycode 8 = F12
++	shift shiftr keycode 8 = F12
++	control keycode 8 = F2
++	alt keycode 8 = Console_2
++	control alt keycode 8 = Console_2
++keycode 9 = F4 F14 Console_16
++	shiftr keycode 9 = F14
++	shift shiftr keycode 9 = F14
++	control keycode 9 = F4
++	alt keycode 9 = Console_4
++	control alt keycode 9 = Console_4
++keycode 10 = F6 F16 Console_18
++	shiftr keycode 10 = F16
++	shift shiftr keycode 10 = F16
++	control keycode 10 = F6
++	alt keycode 10 = Console_6
++	control alt keycode 10 = Console_6
++keycode 11 = F8 F18 Console_20
++	shiftr keycode 11 = F18
++	shift shiftr keycode 11 = F18
++	control keycode 11 = F8
++	alt keycode 11 = Console_8
++	control alt keycode 11 = Console_8
++keycode 12 = F10 F20 Console_22
++	shiftr keycode 12 = F20
++	shift shiftr keycode 12 = F20
++	control keycode 12 = F10
++	alt keycode 12 = Console_10
++	control alt keycode 12 = Console_10
++#keycode 13 is brightness down
++#keycode 14 is brightness up
++keycode 15 = F12 F12 Console_24
++	shiftr keycode 15 = F12
++	shift shiftr keycode 15 = F12
++	control keycode 15 = F12
++	alt keycode 15 = Console_12
++	control alt keycode 15 = Console_12
++keycode 16 = apostrophe quotedbl
++	shiftr keycode 16 = quotedbl
++	shift shiftr keycode 16 = quotedbl
++	control keycode 16 = Control_g
++	alt keycode 16 = Meta_apostrophe
++keycode 17 = bracketleft braceleft
++	shiftr keycode 17 = braceleft
++	shift shiftr keycode 17 = braceleft
++	control keycode 17 = Escape
++	alt keycode 17 = Meta_bracketleft
++keycode 18 = minus underscore backslash       
++	shiftr keycode 18 = underscore
++	shift shiftr keycode 18 = underscore
++	control keycode 18 = Control_underscore
++	shift control keycode 18 = Control_underscore
++	shiftr control keycode 18 = Control_underscore
++	shift shiftr control keycode 18 = Control_underscore
++	alt keycode 18 = Meta_minus
++keycode 19 = zero parenright braceright
++	shiftr keycode 19 = parenright
++	shift shiftr keycode 19 = parenright
++	alt keycode 19 = Meta_zero
++keycode 20 = p
++	shiftr keycode 20 = +P
++	shift shiftr keycode 20 = +p
++keycode 21 = semicolon colon
++	shiftr keycode 21 = colon
++	shift shiftr keycode 21 = colon
++	alt keycode 21 = Meta_semicolon
++keycode 22 = Up Scroll_Backward
++	shiftr keycode 22 = Scroll_Backward
++	shift shiftr keycode 22 = Scroll_Backward
++	alt keycode 22 = Prior
++keycode 23 = slash question
++	shiftr keycode 23 = question
++	shift shiftr keycode 23 = question
++	control keycode 23 = Delete
++	alt keycode 23 = Meta_slash
++
++keycode 27 = nine parenleft bracketright
++	shiftr keycode 27 = parenleft
++	shift shiftr keycode 27 = parenleft
++	alt keycode 27 = Meta_nine
++keycode 28 = o
++	shiftr keycode 28 = +O
++	shift shiftr keycode 28 = +o
++keycode 29 = l
++	shiftr keycode 29 = +L
++	shift shiftr keycode 29 = +l
++keycode 30 = period greater
++	shiftr keycode 30 = greater
++	shift shiftr keycode 30 = greater
++	control keycode 30 = Compose
++	alt keycode 30 = Meta_period
++
++keycode 32 = Left Decr_Console
++	shiftr keycode 32 = Decr_Console
++	shift shiftr keycode 32 = Decr_Console
++	alt keycode 32 = Home
++keycode 33 = bracketright braceright asciitilde      
++	shiftr keycode 33 = braceright
++	shift shiftr keycode 33 = braceright
++	control keycode 33 = Control_bracketright
++	alt keycode 33 = Meta_bracketright
++keycode 34 = equal plus
++	shiftr keycode 34 = plus
++	shift shiftr keycode 34 = plus
++	alt keycode 34 = Meta_equal
++keycode 35 = eight asterisk bracketleft
++	shiftr keycode 35 = asterisk
++	shift shiftr keycode 35 = asterisk
++	control keycode 35 = Delete
++	alt keycode 35 = Meta_eight
++keycode 36 = i
++	shiftr keycode 36 = +I
++	shift shiftr keycode 36 = +i
++keycode 37 = k
++	shiftr keycode 37 = +K
++	shift shiftr keycode 37 = +k
++keycode 38 = comma less
++	shiftr keycode 38 = less
++	shift shiftr keycode 38 = less
++	alt keycode 38 = Meta_comma
++
++keycode 40 = h
++	shiftr keycode 40 = +H
++	shift shiftr keycode 40 = +h
++keycode 41 = y
++	shiftr keycode 41 = +Y
++	shift shiftr keycode 41 = +y
++keycode 42 = six asciicircum
++	shiftr keycode 42 = asciicircum
++	shift shiftr keycode 42 = asciicircum
++	control keycode 42 = Control_asciicircum
++	alt keycode 42 = Meta_six
++keycode 43 = seven ampersand braceleft
++	shiftr keycode 43 = ampersand
++	shift shiftr keycode 43 = ampersand
++	control keycode 43 = Control_underscore
++	alt keycode 43 = Meta_seven
++keycode 44 = u
++	shiftr keycode 44 = +U
++	shift shiftr keycode 44 = +u
++keycode 45 = j
++	shiftr keycode 45 = +J
++	shift shiftr keycode 45 = +j
++keycode 46 = m
++	shiftr keycode 46 = +M
++	shift shiftr keycode 46 = +m
++keycode 47 = n
++	shiftr keycode 47 = +N
++	shift shiftr keycode 47 = +n
++
++# This is the "Backspace" key:
++keycode 49 = Delete Delete
++	shiftr keycode 49 = Delete
++	shift shiftr keycode 49 = Delete
++	control keycode 49 = BackSpace
++	alt keycode 49 = Meta_Delete
++keycode 50 = Num_Lock
++	shift keycode 50 = Bare_Num_Lock
++	shiftr keycode 50 = Bare_Num_Lock
++	shift shiftr keycode 50 = Bare_Num_Lock
++# This is the "Delete" key:
++keycode 51 = Remove
++	control alt keycode 51 = Boot
++
++keycode 53 = backslash bar
++	shiftr keycode 53 = bar
++	shift shiftr keycode 53 = bar
++	control keycode 53 = Control_backslash
++	alt keycode 53 = Meta_backslash
++keycode 54 = Return
++	alt keycode 54 = Meta_Control_m
++keycode 55 = space space           
++	shiftr keycode 55 = space
++	shift shiftr keycode 55 = space
++	control keycode 55 = nul
++	alt keycode 55 = Meta_space
++keycode 56 = g
++	shiftr keycode 56 = +G
++	shift shiftr keycode 56 = +g
++keycode 57 = t
++	shiftr keycode 57 = +T
++	shift shiftr keycode 57 = +t
++keycode 58 = five percent
++	shiftr keycode 58 = percent
++	shift shiftr keycode 58 = percent
++	control keycode 58 = Control_bracketright
++	alt keycode 58 = Meta_five
++keycode 59 = four dollar dollar
++	shiftr keycode 59 = dollar
++	shift shiftr keycode 59 = dollar
++	control keycode 59 = Control_backslash
++	alt keycode 59 = Meta_four
++keycode 60 = r
++	shiftr keycode 60 = +R
++	shift shiftr keycode 60 = +r
++keycode 61 = f
++	shiftr keycode 61 = +F
++	shift shiftr keycode 61 = +f
++	altgr keycode 61 = Hex_F
++keycode 62 = v
++	shiftr keycode 62 = +V
++	shift shiftr keycode 62 = +v
++keycode 63 = b
++	shiftr keycode 63 = +B
++	shift shiftr keycode 63 = +b
++	altgr keycode 63 = Hex_B
++
++keycode 67 = three numbersign
++	shiftr keycode 67 = numbersign
++	shift shiftr keycode 67 = numbersign
++	control keycode 67 = Escape
++	alt keycode 67 = Meta_three
++keycode 68 = e
++	shiftr keycode 68 = +E
++	shift shiftr keycode 68 = +e
++	altgr keycode 68 = Hex_E
++keycode 69 = d
++	shiftr keycode 69 = +D
++	shift shiftr keycode 69 = +d
++	altgr keycode 69 = Hex_D
++keycode 70 = c
++	shiftr keycode 70 = +C
++	shift shiftr keycode 70 = +c
++	altgr keycode 70 = Hex_C
++keycode 71 = Right Incr_Console
++	shiftr keycode 71 = Incr_Console
++	shift shiftr keycode 71 = Incr_Console
++	alt keycode 71 = End
++
++keycode 75 = two at at
++	shiftr keycode 75 = at
++	shift shiftr keycode 75 = at
++	control keycode 75 = nul
++	shift control keycode 75 = nul
++	shiftr control keycode 75 = nul
++	shift shiftr control keycode 75 = nul
++	alt keycode 75 = Meta_two
++keycode 76 = w
++	shiftr keycode 76 = +W
++	shift shiftr keycode 76 = +w
++keycode 77 = s
++	shiftr keycode 77 = +S
++	shift shiftr keycode 77 = +s
++keycode 78 = x
++	shiftr keycode 78 = +X
++	shift shiftr keycode 78 = +x
++keycode 79 = Down Scroll_Forward
++	shiftr keycode 79 = Scroll_Forward
++	shift shiftr keycode 79 = Scroll_Forward
++	alt keycode 79 = Next
++keycode 80 = Escape Escape
++	shiftr keycode 80 = Escape
++	shift shiftr keycode 80 = Escape
++	alt keycode 80 = Meta_Escape
++keycode 81 = Tab Tab             
++	shiftr keycode 81 = Tab
++	shift shiftr keycode 81 = Tab
++	alt keycode 81 = Meta_Tab
++keycode 82 = grave asciitilde
++	shiftr keycode 82 = asciitilde
++	shift shiftr keycode 82 = asciitilde
++	control keycode 82 = nul
++	alt keycode 82 = Meta_grave
++keycode 83 = one exclam
++	shiftr keycode 83 = exclam
++	shift shiftr keycode 83 = exclam
++	alt keycode 83 = Meta_one
++keycode 84 = q
++	shiftr keycode 84 = +Q
++	shift shiftr keycode 84 = +q
++keycode 85 = a
++	shiftr keycode 85 = +A
++	shift shiftr keycode 85 = +a
++	altgr keycode 85 = Hex_A
++keycode 86 = z
++	shiftr keycode 86 = +Z
++	shift shiftr keycode 86 = +z
++
++# This is the windows key:
++keycode 88 = Decr_Console
++keycode 89 = Shift
++keycode 90 = Control
++keycode 91 = Control
++keycode 92 = Alt
++keycode 93 = AltGr
++keycode 94 = ShiftR
++	shift keycode 94 = Caps_Lock
+diff -urpNX dontdiff linux-2.6.10/drivers/char/ite_gpio.c linux-2.6.10-mips/drivers/char/ite_gpio.c
+--- linux-2.6.10/drivers/char/ite_gpio.c	2004-12-24 22:35:15.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/ite_gpio.c	2003-12-28 20:00:16.000000000 +0100
+@@ -30,9 +30,7 @@
+  *  with this program; if not, write  to the Free Software Foundation, Inc.,
+  *  675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+-
+ #include <linux/module.h>
+-#include <linux/config.h>
+ #include <linux/types.h>
+ #include <linux/kernel.h>
+ #include <linux/miscdevice.h>
+@@ -238,10 +236,6 @@ EXPORT_SYMBOL(ite_gpio_int_wait);
+ 
+ static int ite_gpio_open(struct inode *inode, struct file *file)
+ {
+-	unsigned int minor = iminor(inode); 
+-	if (minor != GPIO_MINOR)
+-		return -ENODEV;
+-
+ 	return 0;
+ }
+ 
+@@ -255,7 +249,6 @@ static int ite_gpio_release(struct inode
+ static int ite_gpio_ioctl(struct inode *inode, struct file *file,
+ 	unsigned int cmd, unsigned long arg)
+ {
+-
+ 	static struct ite_gpio_ioctl_data ioctl_data;
+ 
+ 	if (copy_from_user(&ioctl_data, (struct ite_gpio_ioctl_data *)arg,
+@@ -314,10 +307,12 @@ static int ite_gpio_ioctl(struct inode *
+ 			return -ENOIOCTLCMD;
+ 
+ 	}
++
+ 	return 0;
+ }
+ 
+-static void ite_gpio_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
++static void ite_gpio_irq_handler(int this_irq, void *dev_id,
++	struct pt_regs *regs)
+ {
+ 	int i,line;
+ 
+@@ -362,18 +357,15 @@ DEB(printk("interrupt 0x%x %d\n",ITE_GPA
+ 	}
+ }
+ 
+-static struct file_operations ite_gpio_fops =
+-{
++static struct file_operations ite_gpio_fops = {
+ 	.owner		= THIS_MODULE,
+ 	.ioctl		= ite_gpio_ioctl,
+ 	.open		= ite_gpio_open,
+ 	.release	= ite_gpio_release,
+ };
+ 
+-/* GPIO_MINOR in include/linux/miscdevice.h */
+-static struct miscdevice ite_gpio_miscdev =
+-{
+-	GPIO_MINOR,
++static struct miscdevice ite_gpio_miscdev = {
++	MISC_DYNAMIC_MINOR,
+ 	"ite_gpio",
+ 	&ite_gpio_fops
+ };
+@@ -416,7 +408,7 @@ int __init ite_gpio_init(void)
+ 	return 0;
+ }	
+ 
+-void __exit ite_gpio_exit(void)
++static void __exit ite_gpio_exit(void)
+ {
+ 	misc_deregister(&ite_gpio_miscdev);
+ }
+diff -urpNX dontdiff linux-2.6.10/drivers/char/qtronix.c linux-2.6.10-mips/drivers/char/qtronix.c
+--- linux-2.6.10/drivers/char/qtronix.c	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/qtronix.c	2004-10-27 02:14:18.000000000 +0200
+@@ -537,7 +537,7 @@ repeat:
+ 		i--;
+ 	}
+ 	if (count-i) {
+-		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
++		file->f_dentry->d_inode->i_atime = get_seconds();
+ 		return count-i;
+ 	}
+ 	if (signal_pending(current))
+diff -urpNX dontdiff linux-2.6.10/drivers/char/rtc.c linux-2.6.10-mips/drivers/char/rtc.c
+--- linux-2.6.10/drivers/char/rtc.c	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/rtc.c	2004-09-21 13:10:14.000000000 +0200
+@@ -35,23 +35,21 @@
+  *	1.09a	Pete Zaitcev: Sun SPARC
+  *	1.09b	Jeff Garzik: Modularize, init cleanup
+  *	1.09c	Jeff Garzik: SMP cleanup
+- *	1.10    Paul Barton-Davis: add support for async I/O
++ *	1.10	Paul Barton-Davis: add support for async I/O
+  *	1.10a	Andrea Arcangeli: Alpha updates
+  *	1.10b	Andrew Morton: SMP lock fix
+  *	1.10c	Cesar Barros: SMP locking fixes and cleanup
+  *	1.10d	Paul Gortmaker: delete paranoia check in rtc_exit
+  *	1.10e	Maciej W. Rozycki: Handle DECstation's year weirdness.
+- *      1.11    Takashi Iwai: Kernel access functions
++ *	1.11	Takashi Iwai: Kernel access functions
+  *			      rtc_register/rtc_unregister/rtc_control
+  *      1.11a   Daniele Bellucci: Audit create_proc_read_entry in rtc_init
+- *	1.12	Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer
++ *	1.12    Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer
+  *		CONFIG_HPET_EMULATE_RTC
+- *
++ *	1.12a	Maciej W. Rozycki: Handle memory-mapped chips properly.
+  */
+ 
+-#define RTC_VERSION		"1.12"
+-
+-#define RTC_IO_EXTENT	0x8
++#define RTC_VERSION		"1.12a"
+ 
+ /*
+  *	Note that *all* calls to CMOS_READ and CMOS_WRITE are done with
+@@ -323,7 +321,15 @@ static ssize_t rtc_read(struct file *fil
+ 	if (rtc_has_irq == 0)
+ 		return -EIO;
+ 
+-	if (count < sizeof(unsigned))
++	/*
++	 * Historically this function used to assume that sizeof(unsigned long)
++	 * is the same in userspace and kernelspace.  This lead to problems
++	 * for configurations with multiple ABIs such a the MIPS o32 and 64
++	 * ABIs supported on the same kernel.  So now we support read of both
++	 * 4 and 8 bytes and assume that's the sizeof(unsigned long) in the
++	 * userspace ABI.
++	 */
++	if (count != sizeof(unsigned int) && count !=  sizeof(unsigned long))
+ 		return -EINVAL;
+ 
+ 	add_wait_queue(&rtc_wait, &wait);
+@@ -354,10 +360,12 @@ static ssize_t rtc_read(struct file *fil
+ 		schedule();
+ 	} while (1);
+ 
+-	if (count < sizeof(unsigned long))
+-		retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int); 
++	if (count == sizeof(unsigned int))
++		retval = put_user(data, (unsigned int __user *)buf) ?: sizeof(int);
+ 	else
+ 		retval = put_user(data, (unsigned long __user *)buf) ?: sizeof(long);
++	if (!retval)
++		retval = count;
+  out:
+ 	current->state = TASK_RUNNING;
+ 	remove_wait_queue(&rtc_wait, &wait);
+@@ -897,6 +905,9 @@ static int __init rtc_init(void)
+ 	struct sparc_isa_device *isa_dev;
+ #endif
+ #endif
++#ifndef __sparc__
++	void *r;
++#endif
+ 
+ #ifdef __sparc__
+ 	for_each_ebus(ebus) {
+@@ -943,8 +954,13 @@ found:
+ 	}
+ no_irq:
+ #else
+-	if (!request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc")) {
+-		printk(KERN_ERR "rtc: I/O port %d is not free.\n", RTC_PORT (0));
++	if (RTC_IOMAPPED)
++		r = request_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
++	else
++		r = request_mem_region(RTC_PORT(0), RTC_IO_EXTENT, "rtc");
++	if (!r) {
++		printk(KERN_ERR "rtc: I/O resource %lx is not free.\n",
++		       (long)(RTC_PORT(0)));
+ 		return -EIO;
+ 	}
+ 
+@@ -958,7 +974,10 @@ no_irq:
+ 	if(request_irq(RTC_IRQ, rtc_int_handler_ptr, SA_INTERRUPT, "rtc", NULL)) {
+ 		/* Yeah right, seeing as irq 8 doesn't even hit the bus. */
+ 		printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
+-		release_region(RTC_PORT(0), RTC_IO_EXTENT);
++		if (RTC_IOMAPPED)
++			release_region(RTC_PORT(0), RTC_IO_EXTENT);
++		else
++			release_mem_region(RTC_PORT(0), RTC_IO_EXTENT);
+ 		return -EIO;
+ 	}
+ 	hpet_rtc_timer_init();
+@@ -1059,7 +1078,10 @@ static void __exit rtc_exit (void)
+ 	if (rtc_has_irq)
+ 		free_irq (rtc_irq, &rtc_port);
+ #else
+-	release_region (RTC_PORT (0), RTC_IO_EXTENT);
++	if (RTC_IOMAPPED)
++		release_region(RTC_PORT(0), RTC_IO_EXTENT);
++	else
++		release_mem_region(RTC_PORT(0), RTC_IO_EXTENT);
+ #ifdef RTC_IRQ
+ 	if (rtc_has_irq)
+ 		free_irq (RTC_IRQ, NULL);
+diff -urpNX dontdiff linux-2.6.10/drivers/char/sb1250_duart.c linux-2.6.10-mips/drivers/char/sb1250_duart.c
+--- linux-2.6.10/drivers/char/sb1250_duart.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/sb1250_duart.c	2005-01-09 13:23:58.000000000 +0100
+@@ -0,0 +1,897 @@
++/*
++ * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
++ *
++ * 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.
++ */
++
++/* 
++ * Driver support for the on-chip sb1250 dual-channel serial port,
++ * running in asynchronous mode.  Also, support for doing a serial console
++ * on one of those ports 
++ */
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/serial.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/console.h>
++#include <linux/kdev_t.h>
++#include <linux/major.h>
++#include <linux/termios.h>
++#include <linux/spinlock.h>
++#include <linux/irq.h>
++#include <linux/errno.h>
++#include <linux/tty.h>
++#include <linux/sched.h>
++#include <linux/tty_flip.h>
++#include <linux/timer.h>
++#include <linux/init.h>
++#include <linux/mm.h>
++#include <asm/delay.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/sibyte/swarm.h>
++#include <asm/sibyte/sb1250_regs.h>
++#include <asm/sibyte/sb1250_uart.h>
++#include <asm/sibyte/sb1250_int.h>
++#include <asm/sibyte/sb1250.h>
++#include <asm/war.h>
++
++/* Toggle spewing of debugging output */
++#undef DUART_SPEW
++
++#define DEFAULT_CFLAGS          (CS8 | B115200)
++
++#define TX_INTEN          1
++#define DUART_INITIALIZED 2
++
++#ifndef MIN
++#define MIN(a,b)	((a) < (b) ? (a) : (b))
++#endif
++
++#define DUART_MAX_LINE 2
++char sb1250_duart_present[DUART_MAX_LINE] = {1,1};
++EXPORT_SYMBOL(sb1250_duart_present);
++
++/*
++ * Still not sure what the termios structures set up here are for, 
++ *  but we have to supply pointers to them to register the tty driver
++ */
++static struct tty_driver *sb1250_duart_driver; //, sb1250_duart_callout_driver;
++
++/*
++ * This lock protects both the open flags for all the uart states as 
++ * well as the reference count for the module
++ */
++static spinlock_t          open_lock = SPIN_LOCK_UNLOCKED;
++
++typedef struct { 
++	unsigned char       outp_buf[SERIAL_XMIT_SIZE];
++	unsigned int        outp_head;
++	unsigned int        outp_tail;
++	unsigned int        outp_count;
++	spinlock_t          outp_lock;
++	unsigned int        open;
++	unsigned int        line;
++	unsigned int        last_cflags;
++	unsigned long       flags;
++	struct tty_struct   *tty;
++	/* CSR addresses */
++	u32		    *status;
++	u32		    *imr;
++	u32		    *tx_hold;
++	u32		    *rx_hold;
++	u32		    *mode_1;
++	u32		    *mode_2;
++	u32		    *clk_sel;
++	u32		    *cmd;
++} uart_state_t;
++
++static uart_state_t uart_states[DUART_MAX_LINE];
++
++/*
++ * Inline functions local to this module 
++ */
++
++/*
++ * In bug 1956, we get glitches that can mess up uart registers.  This
++ * "write-mode-1 after any register access" is the accepted
++ * workaround.
++ */
++#if SIBYTE_1956_WAR
++static unsigned int last_mode1[DUART_MAX_LINE];
++#endif
++
++static inline u32 READ_SERCSR(u32 *addr, int line)
++{
++	u32 val = csr_in32(addr);
++#if SIBYTE_1956_WAR
++	csr_out32(last_mode1[line], uart_states[line].mode_1);
++#endif
++	return val;
++}
++
++static inline void WRITE_SERCSR(u32 val, u32 *addr, int line)
++{
++	csr_out32(val, addr);
++#if SIBYTE_1956_WAR
++	csr_out32(last_mode1[line], uart_states[line].mode_1);
++#endif
++}
++
++static void init_duart_port(uart_state_t *port, int line)
++{
++	if (!(port->flags & DUART_INITIALIZED)) {
++		port->line = line;
++		port->status = (u32 *)(IOADDR(A_DUART_CHANREG(line, R_DUART_STATUS)));
++		port->imr = (u32 *)(IOADDR(A_DUART_IMRREG(line)));
++		port->tx_hold = (u32 *)(IOADDR(A_DUART_CHANREG(line, R_DUART_TX_HOLD)));
++		port->rx_hold = (u32 *)(IOADDR(A_DUART_CHANREG(line, R_DUART_RX_HOLD)));
++		port->mode_1 = (u32 *)(IOADDR(A_DUART_CHANREG(line, R_DUART_MODE_REG_1)));
++		port->mode_2 = (u32 *)(IOADDR(A_DUART_CHANREG(line, R_DUART_MODE_REG_2)));
++		port->clk_sel = (u32 *)(IOADDR(A_DUART_CHANREG(line, R_DUART_CLK_SEL)));
++		port->cmd = (u32 *)(IOADDR(A_DUART_CHANREG(line, R_DUART_CMD)));
++		port->flags |= DUART_INITIALIZED;
++	}
++}
++
++/*
++ * Mask out the passed interrupt lines at the duart level.  This should be
++ * called while holding the associated outp_lock.
++ */
++static inline void duart_mask_ints(unsigned int line, unsigned int mask)
++{
++	uart_state_t *port = uart_states + line;
++	u64 tmp = READ_SERCSR(port->imr, line);
++	WRITE_SERCSR(tmp & ~mask, port->imr, line);
++}
++
++	
++/* Unmask the passed interrupt lines at the duart level */
++static inline void duart_unmask_ints(unsigned int line, unsigned int mask)
++{
++	uart_state_t *port = uart_states + line;
++	u64 tmp = READ_SERCSR(port->imr, line);
++	WRITE_SERCSR(tmp | mask, port->imr, line);
++}
++
++static inline void transmit_char_pio(uart_state_t *us)
++{
++	struct tty_struct *tty = us->tty;
++	int blocked = 0;
++
++	if (spin_trylock(&us->outp_lock)) {
++		for (;;) {
++			if (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_RDY))
++				break;
++			if (us->outp_count <= 0 || tty->stopped || tty->hw_stopped) {
++				break;
++			} else {
++				WRITE_SERCSR(us->outp_buf[us->outp_head],
++					     us->tx_hold, us->line);
++				us->outp_head = (us->outp_head + 1) & (SERIAL_XMIT_SIZE-1);
++				if (--us->outp_count <= 0)
++					break;
++			}
++			udelay(10);
++		}
++		spin_unlock(&us->outp_lock);
++	} else {
++		blocked = 1;
++	}
++
++	if (!us->outp_count || tty->stopped ||
++	    tty->hw_stopped || blocked) {
++		us->flags &= ~TX_INTEN;
++		duart_mask_ints(us->line, M_DUART_IMR_TX);
++	}
++
++      	if (us->open &&
++	    (us->outp_count < (SERIAL_XMIT_SIZE/2))) {
++		/*
++		 * We told the discipline at one point that we had no
++		 * space, so it went to sleep.  Wake it up when we hit
++		 * half empty
++		 */
++		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
++		    tty->ldisc.write_wakeup)
++			tty->ldisc.write_wakeup(tty);
++		wake_up_interruptible(&tty->write_wait);
++	}
++}
++
++/* 
++ * Generic interrupt handler for both channels.  dev_id is a pointer
++ * to the proper uart_states structure, so from that we can derive 
++ * which port interrupted 
++ */
++
++static irqreturn_t duart_int(int irq, void *dev_id, struct pt_regs *regs)
++{
++	uart_state_t *us = (uart_state_t *)dev_id;
++	struct tty_struct *tty = us->tty;
++	unsigned int status = READ_SERCSR(us->status, us->line);
++
++#ifdef DUART_SPEW
++	printk("DUART INT\n");
++#endif
++
++	if (status & M_DUART_RX_RDY) {
++		int counter = 2048;
++		unsigned int ch;
++
++		if (status & M_DUART_OVRUN_ERR)
++			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
++		if (status & M_DUART_PARITY_ERR) {
++			printk("Parity error!\n");
++		} else if (status & M_DUART_FRM_ERR) {
++			printk("Frame error!\n");
++		}
++
++		while (counter > 0) {
++			if (!(READ_SERCSR(us->status, us->line) & M_DUART_RX_RDY))
++				break;
++			ch = READ_SERCSR(us->rx_hold, us->line);
++			if (tty->flip.count < TTY_FLIPBUF_SIZE) {
++				*tty->flip.char_buf_ptr++ = ch;
++				*tty->flip.flag_buf_ptr++ = 0;
++				tty->flip.count++;
++			}
++			udelay(1);
++			counter--;
++		}
++		tty_flip_buffer_push(tty);
++	}
++
++	if (status & M_DUART_TX_RDY) {
++		transmit_char_pio(us);
++	}
++
++	return IRQ_HANDLED;
++}
++
++/*
++ *  Actual driver functions
++ */
++
++/* Return the number of characters we can accomodate in a write at this instant */
++static int duart_write_room(struct tty_struct *tty)
++{
++	uart_state_t *us = (uart_state_t *) tty->driver_data;
++	int retval;
++
++	retval = SERIAL_XMIT_SIZE - us->outp_count;
++
++#ifdef DUART_SPEW
++	printk("duart_write_room called, returning %i\n", retval);
++#endif
++
++	return retval;
++}
++
++/* memcpy the data from src to destination, but take extra care if the
++   data is coming from user space */
++static inline int copy_buf(char *dest, const char *src, int size, int from_user) 
++{
++	if (from_user) {
++		(void) copy_from_user(dest, src, size); 
++	} else {
++		memcpy(dest, src, size);
++	}
++	return size;
++}
++
++/*
++ * Buffer up to count characters from buf to be written.  If we don't have
++ * other characters buffered, enable the tx interrupt to start sending
++ */
++static int duart_write(struct tty_struct *tty, const unsigned char *buf,
++		       int count)
++{
++	uart_state_t *us;
++	int c, t, total = 0;
++	unsigned long flags;
++
++	if (!tty) return 0;
++
++	us = tty->driver_data;
++	if (!us) return 0;
++
++#ifdef DUART_SPEW
++	printk("duart_write called for %i chars by %i (%s)\n", count, current->pid, current->comm);
++#endif
++
++	spin_lock_irqsave(&us->outp_lock, flags);
++
++	for (;;) {
++		c = count;
++
++		t = SERIAL_XMIT_SIZE - us->outp_tail;
++		if (t < c) c = t;
++
++		t = SERIAL_XMIT_SIZE - 1 - us->outp_count;
++		if (t < c) c = t;
++
++		if (c <= 0) break;
++
++		memcpy(us->outp_buf + us->outp_tail, buf, c);
++
++		us->outp_count += c;
++		us->outp_tail = (us->outp_tail + c) & (SERIAL_XMIT_SIZE - 1);
++		buf += c;
++		count -= c;
++		total += c;
++	}
++
++	spin_unlock_irqrestore(&us->outp_lock, flags);
++
++	if (us->outp_count && !tty->stopped && 
++	    !tty->hw_stopped && !(us->flags & TX_INTEN)) {
++		us->flags |= TX_INTEN;
++		duart_unmask_ints(us->line, M_DUART_IMR_TX);
++	}
++
++	return total;
++}
++
++
++/* Buffer one character to be written.  If there's not room for it, just drop
++   it on the floor.  This is used for echo, among other things */
++static void duart_put_char(struct tty_struct *tty, u_char ch)
++{
++	uart_state_t *us = (uart_state_t *) tty->driver_data;
++	unsigned long flags;
++
++#ifdef DUART_SPEW
++	printk("duart_put_char called.  Char is %x (%c)\n", (int)ch, ch);
++#endif
++
++	spin_lock_irqsave(&us->outp_lock, flags);
++
++	if (us->outp_count == SERIAL_XMIT_SIZE) {
++		spin_unlock_irqrestore(&us->outp_lock, flags);
++		return;
++	}
++
++	us->outp_buf[us->outp_tail] = ch;
++	us->outp_tail = (us->outp_tail + 1) &(SERIAL_XMIT_SIZE-1);
++	us->outp_count++;
++
++	spin_unlock_irqrestore(&us->outp_lock, flags);
++}
++
++static void duart_flush_chars(struct tty_struct * tty)
++{
++	uart_state_t *port;
++
++	if (!tty) return;
++
++	port = tty->driver_data;
++
++	if (!port) return;
++
++	if (port->outp_count <= 0 || tty->stopped || tty->hw_stopped) {
++		return;
++	}
++
++	port->flags |= TX_INTEN;
++	duart_unmask_ints(port->line, M_DUART_IMR_TX);
++}
++
++/* Return the number of characters in the output buffer that have yet to be 
++   written */
++static int duart_chars_in_buffer(struct tty_struct *tty)
++{
++	uart_state_t *us = (uart_state_t *) tty->driver_data;
++	int retval;
++
++	retval = us->outp_count;
++
++#ifdef DUART_SPEW
++	printk("duart_chars_in_buffer returning %i\n", retval);
++#endif
++	return retval;
++}
++
++/* Kill everything we haven't yet shoved into the FIFO.  Turn off the
++   transmit interrupt since we've nothing more to transmit */
++static void duart_flush_buffer(struct tty_struct *tty)
++{
++	uart_state_t *us = (uart_state_t *) tty->driver_data;
++	unsigned long flags;
++
++#ifdef DUART_SPEW
++	printk("duart_flush_buffer called\n");
++#endif
++	spin_lock_irqsave(&us->outp_lock, flags);
++	us->outp_head = us->outp_tail = us->outp_count = 0;
++	spin_unlock_irqrestore(&us->outp_lock, flags);
++
++	wake_up_interruptible(&us->tty->write_wait);
++	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
++	    tty->ldisc.write_wakeup)
++		tty->ldisc.write_wakeup(tty);
++}
++
++
++/* See sb1250 user manual for details on these registers */
++static inline void duart_set_cflag(unsigned int line, unsigned int cflag)
++{
++	unsigned int mode_reg1 = 0, mode_reg2 = 0;
++	unsigned int clk_divisor;
++	uart_state_t *port = uart_states + line;
++
++	switch (cflag & CSIZE) {
++	case CS7:
++		mode_reg1 |= V_DUART_BITS_PER_CHAR_7;
++		
++	default:
++		/* We don't handle CS5 or CS6...is there a way we're supposed to flag this? 
++		   right now we just force them to CS8 */
++		mode_reg1 |= 0x0;
++		break;
++	}
++	if (cflag & CSTOPB) {
++	        mode_reg2 |= M_DUART_STOP_BIT_LEN_2;
++	}
++	if (!(cflag & PARENB)) {
++	        mode_reg1 |= V_DUART_PARITY_MODE_NONE;
++	}
++	if (cflag & PARODD) {
++		mode_reg1 |= M_DUART_PARITY_TYPE_ODD;
++	}
++	
++	/* Formula for this is (5000000/baud)-1, but we saturate
++	   at 12 bits, which means we can't actually do anything less
++	   that 1200 baud */
++	switch (cflag & CBAUD) {
++	case B200:	
++	case B300:	
++	case B1200:	clk_divisor = 4095;		break;
++	case B1800:	clk_divisor = 2776;		break;
++	case B2400:	clk_divisor = 2082;		break;
++	case B4800:	clk_divisor = 1040;		break;
++	default:
++	case B9600:	clk_divisor = 519;		break;
++	case B19200:	clk_divisor = 259;		break;
++	case B38400:	clk_divisor = 129;		break;
++	case B57600:	clk_divisor = 85;		break;
++	case B115200:	clk_divisor = 42;		break;
++	}
++	WRITE_SERCSR(mode_reg1, port->mode_1, port->line);
++	WRITE_SERCSR(mode_reg2, port->mode_2, port->line);
++	WRITE_SERCSR(clk_divisor, port->clk_sel, port->line);
++	port->last_cflags = cflag;
++}
++
++
++/* Handle notification of a termios change.  */
++static void duart_set_termios(struct tty_struct *tty, struct termios *old)
++{
++	uart_state_t *us = (uart_state_t *) tty->driver_data;
++
++#ifdef DUART_SPEW 
++	printk("duart_set_termios called by %i (%s)\n", current->pid, current->comm);
++#endif
++	if (old && tty->termios->c_cflag == old->c_cflag)
++		return;
++	duart_set_cflag(us->line, tty->termios->c_cflag);
++}
++
++static int get_serial_info(uart_state_t *us, struct serial_struct * retinfo) {
++
++	struct serial_struct tmp;
++
++	memset(&tmp, 0, sizeof(tmp));
++
++	tmp.type=PORT_SB1250;
++	tmp.line=us->line;
++	tmp.port=A_DUART_CHANREG(tmp.line,0);
++	tmp.irq=K_INT_UART_0 + tmp.line;
++	tmp.xmit_fifo_size=16; /* fixed by hw */
++	tmp.baud_base=5000000;
++	tmp.io_type=SERIAL_IO_MEM;
++
++	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
++		return -EFAULT;
++
++	return 0;
++}
++
++static int duart_ioctl(struct tty_struct *tty, struct file * file,
++		       unsigned int cmd, unsigned long arg)
++{
++	uart_state_t *us = (uart_state_t *) tty->driver_data;
++
++/*	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
++	return -ENODEV;*/
++	switch (cmd) {
++	case TIOCMGET:
++		printk("Ignoring TIOCMGET\n");
++		break;
++	case TIOCMBIS:
++		printk("Ignoring TIOCMBIS\n");
++		break;
++	case TIOCMBIC:
++		printk("Ignoring TIOCMBIC\n");
++		break;
++	case TIOCMSET:
++		printk("Ignoring TIOCMSET\n");
++		break;
++	case TIOCGSERIAL:
++		return get_serial_info(us,(struct serial_struct *) arg);
++	case TIOCSSERIAL:
++		printk("Ignoring TIOCSSERIAL\n");
++		break;
++	case TIOCSERCONFIG:
++		printk("Ignoring TIOCSERCONFIG\n");
++		break;
++	case TIOCSERGETLSR: /* Get line status register */
++		printk("Ignoring TIOCSERGETLSR\n");
++		break;
++	case TIOCSERGSTRUCT:
++		printk("Ignoring TIOCSERGSTRUCT\n");
++		break;
++	case TIOCMIWAIT:
++		printk("Ignoring TIOCMIWAIT\n");
++		break;
++	case TIOCGICOUNT:
++		printk("Ignoring TIOCGICOUNT\n");
++		break;
++	case TIOCSERGWILD:
++		printk("Ignoring TIOCSERGWILD\n");
++		break;
++	case TIOCSERSWILD:
++		printk("Ignoring TIOCSERSWILD\n");
++		break;
++	default:
++		break;
++	}
++//	printk("Ignoring IOCTL %x from pid %i (%s)\n", cmd, current->pid, current->comm);
++	return -ENOIOCTLCMD;
++}
++
++/* XXXKW locking? */
++static void duart_start(struct tty_struct *tty)
++{
++	uart_state_t *us = (uart_state_t *) tty->driver_data;
++
++#ifdef DUART_SPEW
++	printk("duart_start called\n");
++#endif
++
++	if (us->outp_count && !(us->flags & TX_INTEN)) {
++		us->flags |= TX_INTEN;
++		duart_unmask_ints(us->line, M_DUART_IMR_TX);
++	}
++}
++
++/* XXXKW locking? */
++static void duart_stop(struct tty_struct *tty)
++{
++	uart_state_t *us = (uart_state_t *) tty->driver_data;
++
++#ifdef DUART_SPEW
++	printk("duart_stop called\n");
++#endif
++
++	if (us->outp_count && (us->flags & TX_INTEN)) {
++		us->flags &= ~TX_INTEN;
++		duart_mask_ints(us->line, M_DUART_IMR_TX);
++	}
++}
++
++/* Not sure on the semantics of this; are we supposed to wait until the stuff
++   already in the hardware FIFO drains, or are we supposed to wait until 
++   we've drained the output buffer, too?  I'm assuming the former, 'cause thats
++   what the other drivers seem to assume 
++*/
++
++static void duart_wait_until_sent(struct tty_struct *tty, int timeout)
++{
++	uart_state_t *us = (uart_state_t *) tty->driver_data;
++	unsigned long orig_jiffies;
++
++	orig_jiffies = jiffies;
++#ifdef DUART_SPEW
++	printk("duart_wait_until_sent(%d)+\n", timeout);
++#endif
++	while (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_EMT)) {
++		set_current_state(TASK_INTERRUPTIBLE);
++	 	schedule_timeout(1);
++		if (signal_pending(current))
++			break;
++		if (timeout && time_after(jiffies, orig_jiffies + timeout))
++			break;
++	}
++#ifdef DUART_SPEW
++	printk("duart_wait_until_sent()-\n");
++#endif
++}
++
++/*
++ * duart_hangup() --- called by tty_hangup() when a hangup is signaled.
++ */
++static void duart_hangup(struct tty_struct *tty)
++{
++	uart_state_t *us = (uart_state_t *) tty->driver_data;
++
++	duart_flush_buffer(tty);
++	us->open = 0;
++	us->tty = 0;
++}
++
++/*
++ * Open a tty line.  Note that this can be called multiple times, so ->open can
++ * be >1.  Only set up the tty struct if this is a "new" open, e.g. ->open was
++ * zero
++ */
++static int duart_open(struct tty_struct *tty, struct file *filp)
++{
++	uart_state_t *us;
++	unsigned int line = tty->index;
++	unsigned long flags;
++
++	if ((line >= tty->driver->num) || !sb1250_duart_present[line])
++		return -ENODEV;
++
++#ifdef DUART_SPEW
++	printk("duart_open called by %i (%s), tty is %p, rw is %p, ww is %p\n",
++	       current->pid, current->comm, tty, tty->read_wait,
++	       tty->write_wait);
++#endif
++
++	us = uart_states + line;
++	tty->driver_data = us;
++
++	spin_lock_irqsave(&open_lock, flags);
++	if (!us->open) {
++		us->tty = tty;
++		us->tty->termios->c_cflag = us->last_cflags;
++	}
++	us->open++;
++	us->flags &= ~TX_INTEN;
++	duart_unmask_ints(line, M_DUART_IMR_RX);
++	spin_unlock_irqrestore(&open_lock, flags);
++
++	return 0;
++}
++
++
++/*
++ * Close a reference count out.  If reference count hits zero, null the
++ * tty, kill the interrupts.  The tty_io driver is responsible for making
++ * sure we've cleared out our internal buffers before calling close()
++ */
++static void duart_close(struct tty_struct *tty, struct file *filp)
++{
++	uart_state_t *us = (uart_state_t *) tty->driver_data;
++	unsigned long flags;
++
++#ifdef DUART_SPEW
++	printk("duart_close called by %i (%s)\n", current->pid, current->comm);
++#endif
++
++	if (!us || !us->open)
++		return;
++
++	spin_lock_irqsave(&open_lock, flags);
++	if (tty_hung_up_p(filp)) {
++		spin_unlock_irqrestore(&open_lock, flags);
++		return;
++	}
++
++	if (--us->open < 0) {
++		us->open = 0;
++		printk(KERN_ERR "duart: bad open count: %d\n", us->open);
++	}
++	if (us->open) {
++		spin_unlock_irqrestore(&open_lock, flags);
++		return;
++	}
++
++	spin_unlock_irqrestore(&open_lock, flags);
++
++	tty->closing = 1;
++
++	/* Stop accepting input */
++	duart_mask_ints(us->line, M_DUART_IMR_RX);
++	/* Wait for FIFO to drain */
++	while (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_EMT))
++		;
++
++	if (tty->driver->flush_buffer)
++		tty->driver->flush_buffer(tty);
++	if (tty->ldisc.flush_buffer)
++		tty->ldisc.flush_buffer(tty);
++	tty->closing = 0;
++}
++
++
++static struct tty_operations duart_ops = {
++        .open   = duart_open,
++        .close = duart_close,
++        .write = duart_write,
++        .put_char = duart_put_char,
++        .flush_chars = duart_flush_chars,
++        .write_room = duart_write_room,
++        .chars_in_buffer = duart_chars_in_buffer,
++        .flush_buffer = duart_flush_buffer,
++        .ioctl = duart_ioctl,
++//        .throttle = duart_throttle,
++//        .unthrottle = duart_unthrottle,
++        .set_termios = duart_set_termios,
++        .stop = duart_stop,
++        .start = duart_start,
++        .hangup = duart_hangup,
++	.wait_until_sent = duart_wait_until_sent,
++};
++
++/* Set up the driver and register it, register the 2 1250 UART interrupts.  This
++   is called from tty_init, or as a part of the module init */
++static int __init sb1250_duart_init(void) 
++{
++	int i;
++
++	sb1250_duart_driver = alloc_tty_driver(DUART_MAX_LINE);
++	if (!sb1250_duart_driver)
++		return -ENOMEM;
++
++	sb1250_duart_driver->owner = THIS_MODULE;
++	sb1250_duart_driver->name = "duart";
++	sb1250_duart_driver->devfs_name = "duart/";
++	sb1250_duart_driver->major = TTY_MAJOR;
++	sb1250_duart_driver->minor_start = SB1250_DUART_MINOR_BASE;
++	sb1250_duart_driver->type            = TTY_DRIVER_TYPE_SERIAL;
++	sb1250_duart_driver->subtype         = SERIAL_TYPE_NORMAL;
++	sb1250_duart_driver->init_termios    = tty_std_termios;
++	sb1250_duart_driver->flags           = TTY_DRIVER_REAL_RAW;
++	tty_set_operations(sb1250_duart_driver, &duart_ops);
++
++	for (i=0; i<DUART_MAX_LINE; i++) {
++		uart_state_t *port = uart_states + i;
++
++		if (!sb1250_duart_present[i])
++			continue;
++
++		init_duart_port(port, i);
++		spin_lock_init(&port->outp_lock);
++		duart_mask_ints(i, M_DUART_IMR_ALL);
++		if (request_irq(K_INT_UART_0+i, duart_int, 0, "uart", port)) {
++			panic("Couldn't get uart0 interrupt line");
++		}
++		__raw_writeq(M_DUART_RX_EN|M_DUART_TX_EN,
++			     (u8 *) IOADDR(A_DUART_CHANREG(i, R_DUART_CMD)));
++		duart_set_cflag(i, DEFAULT_CFLAGS);
++	}
++
++	/* Interrupts are now active, our ISR can be called. */
++
++	if (tty_register_driver(sb1250_duart_driver)) {
++		printk(KERN_ERR "Couldn't register sb1250 duart serial driver\n");
++		put_tty_driver(sb1250_duart_driver);
++		return 1;
++	}
++	return 0;
++}
++
++/* Unload the driver.  Unregister stuff, get ready to go away */
++static void __exit sb1250_duart_fini(void)
++{
++	unsigned long flags;
++	int i;
++
++	local_irq_save(flags);
++	tty_unregister_driver(sb1250_duart_driver);
++	put_tty_driver(sb1250_duart_driver);
++
++	for (i=0; i<DUART_MAX_LINE; i++) {
++		if (!sb1250_duart_present[i])
++			continue;
++		free_irq(K_INT_UART_0+i, &uart_states[i]);
++		disable_irq(K_INT_UART_0+i);
++	}
++	local_irq_restore(flags);
++}
++
++module_init(sb1250_duart_init);
++module_exit(sb1250_duart_fini);
++MODULE_DESCRIPTION("SB1250 Duart serial driver");
++MODULE_AUTHOR("Justin Carlson, Broadcom Corp.");
++
++#ifdef CONFIG_SIBYTE_SB1250_DUART_CONSOLE
++
++/*
++ * Serial console stuff.  Very basic, polling driver for doing serial
++ * console output.  The console_sem is held by the caller, so we
++ * shouldn't be interrupted for more console activity.
++ * XXXKW What about getting interrupted by uart driver activity?
++ */
++
++void serial_outc(unsigned char c, int line)
++{
++	uart_state_t *port = uart_states + line;
++	while (!(READ_SERCSR(port->status, line) & M_DUART_TX_RDY)) ;
++	WRITE_SERCSR(c, port->tx_hold, line);
++	while (!(READ_SERCSR(port->status, port->line) & M_DUART_TX_EMT)) ;
++}
++
++static void ser_console_write(struct console *cons, const char *s,
++	unsigned int count)
++{
++	int line = cons->index;
++	uart_state_t *port = uart_states + line;
++	u32 imr;
++
++	imr = READ_SERCSR(port->imr, line);
++	WRITE_SERCSR(0, port->imr, line);
++	while (count--) {
++		if (*s == '\n')
++			serial_outc('\r', line);
++		serial_outc(*s++, line);
++    	}
++	WRITE_SERCSR(imr, port->imr, line);
++}
++
++static struct tty_driver *ser_console_device(struct console *c, int *index)
++{
++	*index = c->index;
++	return sb1250_duart_driver;
++}
++
++static int ser_console_setup(struct console *cons, char *str)
++{
++	int i;
++
++	for (i=0; i<DUART_MAX_LINE; i++) {
++		uart_state_t *port = uart_states + i;
++
++		if (!sb1250_duart_present[i])
++			continue;
++
++		init_duart_port(port, i);
++#if SIBYTE_1956_WAR
++		last_mode1[i] = V_DUART_PARITY_MODE_NONE|V_DUART_BITS_PER_CHAR_8;
++#endif
++		WRITE_SERCSR(V_DUART_PARITY_MODE_NONE|V_DUART_BITS_PER_CHAR_8,
++			     port->mode_1, i);
++		WRITE_SERCSR(M_DUART_STOP_BIT_LEN_1,
++			     port->mode_2, i);
++		WRITE_SERCSR(V_DUART_BAUD_RATE(115200),
++			     port->clk_sel, i);
++		WRITE_SERCSR(M_DUART_RX_EN|M_DUART_TX_EN,
++			     port->cmd, i);
++	}
++	return 0;
++}
++
++static struct console sb1250_ser_cons = {
++	name:		"duart",
++	write:		ser_console_write,
++	device:		ser_console_device,
++	setup:		ser_console_setup,
++	flags:		CON_PRINTBUFFER,
++	index:		-1,
++};
++
++static int __init sb1250_serial_console_init(void)
++{
++	register_console(&sb1250_ser_cons);
++	return 0;
++}
++
++console_initcall(sb1250_serial_console_init);
++
++#endif /* CONFIG_SIBYTE_SB1250_DUART_CONSOLE */
+diff -urpNX dontdiff linux-2.6.10/drivers/char/serial_tx3912.c linux-2.6.10-mips/drivers/char/serial_tx3912.c
+--- linux-2.6.10/drivers/char/serial_tx3912.c	2004-12-24 22:34:57.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/serial_tx3912.c	2004-10-12 19:30:58.000000000 +0200
+@@ -1,8 +1,6 @@
+ /*
+  *  drivers/char/serial_tx3912.c
+  *
+- *  Copyright (C) 1999 Harald Koerfgen
+- *  Copyright (C) 2000 Jim Pick <jim at jimpick.com>
+  *  Copyright (C) 2001 Steven J. Hill (sjhill at realitydiluted.com)
+  * 
+  * This program is free software; you can redistribute it and/or modify
+@@ -15,18 +13,13 @@
+ #include <linux/config.h>
+ #include <linux/tty.h>
+ #include <linux/major.h>
+-#include <linux/ptrace.h>
+ #include <linux/console.h>
+-#include <linux/fs.h>
+-#include <linux/mm.h>
+ #include <linux/slab.h>
+ #include <linux/module.h>
+-#include <linux/delay.h>
+-#include <linux/pm.h>
++#include <linux/serial.h>
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+ #include <asm/delay.h>
+-#include <asm/wbflush.h>
+ #include <asm/tx3912.h>
+ #include "serial_tx3912.h"
+ 
+@@ -57,31 +50,15 @@ static struct real_driver rs_real_driver
+ }; 
+ 
+ /*
+- * Structures and such for TTY sessions and usage counts
++ * Structures and usage counts
+  */
+ static struct tty_driver *rs_driver;
+-struct rs_port *rs_ports;
+-int rs_initialized = 0;
++static struct rs_port *rs_port;
++static int rs_initialized;
++
+ 
+ /*
+- * ----------------------------------------------------------------------
+- *
+- * Here starts the interrupt handling routines.  All of the following
+- * subroutines are declared as inline and are folded into
+- * rs_interrupt().  They were separated out for readability's sake.
+- *
+- * Note: rs_interrupt() is a "fast" interrupt, which means that it
+- * runs with interrupts turned off.  People who may want to modify
+- * rs_interrupt() should try to keep the interrupt handler as fast as
+- * possible.  After you are done making modifications, it is not a bad
+- * idea to do:
+- * 
+- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+- *
+- * and look at the resulting assemble code in serial.s.
+- *
+- * 				- Ted Ts'o (tytso at mit.edu), 7-Mar-93
+- * -----------------------------------------------------------------------
++ * Receive a character
+  */
+ static inline void receive_char_pio(struct rs_port *port)
+ {
+@@ -89,83 +66,34 @@ static inline void receive_char_pio(stru
+ 	unsigned char ch;
+ 	int counter = 2048;
+ 
+-	/* While there are characters, get them ... */
+-	while (counter>0) {
+-		if (!(inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL))
++	/* While there are characters */
++	while (counter > 0) {
++		if (!(inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_RXHOLDFULL))
+ 			break;
+-		ch = inb(port->base + TX3912_UART_DATA);
++		ch = inb(TX3912_UARTA_DATA);
+ 		if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+ 			*tty->flip.char_buf_ptr++ = ch;
+ 			*tty->flip.flag_buf_ptr++ = 0;
+ 			tty->flip.count++;
+ 		}
+-		udelay(1); /* Allow things to happen - it take a while */
++		udelay(1);
+ 		counter--;
+ 	}
+-	if (!counter)
+-		printk( "Ugh, looped in receive_char_pio!\n" );
+-
+-	tty_flip_buffer_push(tty);
+-
+-#if 0
+-	/* Now handle error conditions */
+-	if (*status & (INTTYPE(UART_RXOVERRUN_INT) |
+-			INTTYPE(UART_FRAMEERR_INT) |
+-			INTTYPE(UART_PARITYERR_INT) |
+-			INTTYPE(UART_BREAK_INT))) {
+-
+-		/*
+-		 * Now check to see if character should be
+-		 * ignored, and mask off conditions which
+-		 * should be ignored.
+-	       	 */
+-		if (*status & port->ignore_status_mask) {
+-			goto ignore_char;
+-		}
+-		*status &= port->read_status_mask;
+-		
+-		if (*status & INTTYPE(UART_BREAK_INT)) {
+-			rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "handling break....");
+-			*tty->flip.flag_buf_ptr = TTY_BREAK;
+-		}
+-		else if (*status & INTTYPE(UART_PARITYERR_INT)) {
+-			*tty->flip.flag_buf_ptr = TTY_PARITY;
+-		}
+-		else if (*status & INTTYPE(UART_FRAMEERR_INT)) {
+-			*tty->flip.flag_buf_ptr = TTY_FRAME;
+-		}
+-		if (*status & INTTYPE(UART_RXOVERRUN_INT)) {
+-			/*
+-			 * Overrun is special, since it's
+-			 * reported immediately, and doesn't
+-			 * affect the current character
+-			 */
+-			if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+-				tty->flip.count++;
+-				tty->flip.flag_buf_ptr++;
+-				tty->flip.char_buf_ptr++;
+-				*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+-			}
+-		}
+-	}
+-
+-	tty->flip.flag_buf_ptr++;
+-	tty->flip.char_buf_ptr++;
+-	tty->flip.count++;
+ 
+-ignore_char:
+ 	tty_flip_buffer_push(tty);
+-#endif
+ }
+ 
++/*
++ * Transmit a character
++ */
+ static inline void transmit_char_pio(struct rs_port *port)
+ {
+-	/* While I'm able to transmit ... */
++	/* TX while bytes available */
+ 	for (;;) {
+-		if (!(inl(port->base + TX3912_UART_CTRL1) & UART_TX_EMPTY))
++		if (!(inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_EMPTY))
+ 			break;
+ 		else if (port->x_char) {
+-			outb(port->x_char, port->base + TX3912_UART_DATA);
++			outb(port->x_char, TX3912_UARTA_DATA);
+ 			port->icount.tx++;
+ 			port->x_char = 0;
+ 		}
+@@ -175,14 +103,14 @@ static inline void transmit_char_pio(str
+ 		}
+ 		else {
+ 			outb(port->gs.xmit_buf[port->gs.xmit_tail++],
+-				port->base + TX3912_UART_DATA);
++				TX3912_UARTA_DATA);
+ 			port->icount.tx++;
+ 			port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1;
+ 			if (--port->gs.xmit_cnt <= 0) {
+ 				break;
+ 			}
+ 		}
+-		udelay(10); /* Allow things to happen - it take a while */
++		udelay(10);
+ 	}
+ 
+ 	if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
+@@ -191,344 +119,283 @@ static inline void transmit_char_pio(str
+ 	}
+ 	
+         if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
+-        	tty_wakeup(port->gs.tty);
+-                rs_dprintk (TX3912_UART_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
++		tty_wakeup(port->gs.tty);
++                rs_dprintk(TX3912_UART_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
+                             port->gs.wakeup_chars); 
++                wake_up_interruptible(&port->gs.tty->write_wait);
+        	}	
+ }
+ 
+-
+-
++/*
++ * We don't have MSR
++ */
+ static inline void check_modem_status(struct rs_port *port)
+ {
+-        /* We don't have a carrier detect line - but just respond
+-           like we had one anyways so that open() becomes unblocked */
+ 	wake_up_interruptible(&port->gs.open_wait);
+ }
+ 
+-int count = 0;
+-
+ /*
+- * This is the serial driver's interrupt routine (inlined, because
+- * there are two different versions of this, one for each serial port,
+- * differing only by the bits used in interrupt status 2 register)
++ * RX interrupt handler
+  */
+-
+-static inline void rs_rx_interrupt(int irq, void *dev_id,
+-				  struct pt_regs * regs, int intshift)
++static inline void rs_rx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+-	struct rs_port * port;
+-	unsigned long int2status;
+-	unsigned long flags;
+-	unsigned long ints;
++	unsigned long flags, status;
+ 
+ 	save_and_cli(flags);
+ 
+-	port = (struct rs_port *)dev_id;
+-	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
++	rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "rs_rx_interrupt...");
+ 
+-	/* Get the interrrupts we have enabled */
+-	int2status = IntStatus2 & IntEnable2;
+-
+-	/* Get interrupts in easy to use form */
+-	ints = int2status >> intshift;
++	/* Get the interrupts */
++	status = inl(TX3912_INT2_STATUS);
+ 
+ 	/* Clear any interrupts we might be about to handle */
+-	IntClear2 = int2status & (
+-		(INTTYPE(UART_RXOVERRUN_INT) |
+-		 INTTYPE(UART_FRAMEERR_INT) |
+-		 INTTYPE(UART_BREAK_INT) |
+-		 INTTYPE(UART_PARITYERR_INT) |
+-		 INTTYPE(UART_RX_INT)) << intshift);
++	outl(TX3912_INT2_UARTA_RX_BITS, TX3912_INT2_CLEAR);
+ 
+-	if (!port || !port->gs.tty) {
++	if(!rs_port || !rs_port->gs.tty) {
+ 		restore_flags(flags);
+ 		return;
+ 	}
+ 
+ 	/* RX Receiver Holding Register Overrun */
+-	if (ints & INTTYPE(UART_RXOVERRUN_INT)) {
+-		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "overrun");
+-		port->icount.overrun++;
++	if(status & TX3912_INT2_UARTATXOVERRUNINT) {
++		rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "overrun");
++		rs_port->icount.overrun++;
+ 	}
+ 
+ 	/* RX Frame Error */
+-	if (ints & INTTYPE(UART_FRAMEERR_INT)) {
+-		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "frame error");
+-		port->icount.frame++;
++	if(status & TX3912_INT2_UARTAFRAMEERRINT) {
++		rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "frame error");
++		rs_port->icount.frame++;
+ 	}
+ 
+ 	/* Break signal received */
+-	if (ints & INTTYPE(UART_BREAK_INT)) {
+-		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "break");
+-		port->icount.brk++;
++	if(status & TX3912_INT2_UARTABREAKINT) {
++		rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "break");
++		rs_port->icount.brk++;
+       	}
+ 
+ 	/* RX Parity Error */
+-	if (ints & INTTYPE(UART_PARITYERR_INT)) {
+-		rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "parity error");
+-		port->icount.parity++;
++	if(status & TX3912_INT2_UARTAPARITYINT) {
++		rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "parity error");
++		rs_port->icount.parity++;
+ 	}
+ 
+-	/* Receive byte (non-DMA) */
+-	if (ints & INTTYPE(UART_RX_INT)) {
+-		receive_char_pio(port);
++	/* Byte received */
++	if(status & TX3912_INT2_UARTARXINT) {
++		receive_char_pio(rs_port);
+ 	}
+ 
+ 	restore_flags(flags);
+ 
+-	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
++	rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
+ }
+ 
+-static inline void rs_tx_interrupt(int irq, void *dev_id,
+-				  struct pt_regs * regs, int intshift)
++/*
++ * TX interrupt handler
++ */
++static inline void rs_tx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+-	struct rs_port * port;
+-	unsigned long int2status;
+-	unsigned long flags;
+-	unsigned long ints;
++	unsigned long flags, status;
+ 
+ 	save_and_cli(flags);
+ 
+-	port = (struct rs_port *)dev_id;
+-	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
++	rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "rs_tx_interrupt...");
+ 
+-	/* Get the interrrupts we have enabled */
+-	int2status = IntStatus2 & IntEnable2;
++	/* Get the interrupts */
++	status = inl(TX3912_INT2_STATUS);
+ 
+-	if (!port || !port->gs.tty) {
++	if(!rs_port || !rs_port->gs.tty) {
+ 		restore_flags(flags);
+ 		return;
+ 	}
+ 
+-	/* Get interrupts in easy to use form */
+-	ints = int2status >> intshift;
++	/* Clear interrupts */
++	outl(TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR);
+ 
+-	/* Clear any interrupts we might be about to handle */
+-	IntClear2 = int2status & (
+-		(INTTYPE(UART_TX_INT) |
+-		 INTTYPE(UART_EMPTY_INT) |
+-		 INTTYPE(UART_TXOVERRUN_INT)) << intshift);
+-
+-	/* TX holding register empty, so transmit byte (non-DMA) */
+-	if (ints & (INTTYPE(UART_TX_INT) | INTTYPE(UART_EMPTY_INT))) {
+-		transmit_char_pio(port);
++	/* TX holding register empty - transmit a byte */
++	if(status & TX3912_INT2_UARTAEMPTYINT) {
++		transmit_char_pio(rs_port);
+ 	}
+ 
+ 	/* TX Transmit Holding Register Overrun (shouldn't happen) */
+-	if (ints & INTTYPE(UART_TXOVERRUN_INT)) {
+-		printk ( "rs: TX overrun\n");
++	if(status & TX3912_INT2_UARTATXOVERRUNINT) {
++		printk( "rs_tx_interrupt: TX overrun\n");
+ 	}
+ 
+-	/*
+-	check_modem_status();
+-	*/
+-
+ 	restore_flags(flags);
+ 
+-	rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
+-}
+-
+-static void rs_rx_interrupt_uarta(int irq, void *dev_id,
+-					 struct pt_regs * regs)
+-{
+-	rs_rx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
+-}
+-
+-static void rs_tx_interrupt_uarta(int irq, void *dev_id,
+-					 struct pt_regs * regs)
+-{
+-	rs_tx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
++	rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
+ }
+ 
+ /*
+- ***********************************************************************
+- *                Here are the routines that actually                  *
+- *              interface with the generic_serial driver               *
+- ***********************************************************************
++ * Here are the routines that actually interface with the generic driver
+  */
+ static void rs_disable_tx_interrupts (void * ptr) 
+ {
+-	struct rs_port *port = ptr; 
+ 	unsigned long flags;
+ 
+ 	save_and_cli(flags);
+-        port->gs.flags &= ~GS_TX_INTEN;
+ 
+-	IntEnable2 &= ~((INTTYPE(UART_TX_INT) |
+-			INTTYPE(UART_EMPTY_INT) |
+-			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift);
+-
+-	IntClear2 = (INTTYPE(UART_TX_INT) |
+-			INTTYPE(UART_EMPTY_INT) |
+-			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
++	outl(inl(TX3912_INT2_ENABLE) & ~TX3912_INT2_UARTA_TX_BITS,
++		TX3912_INT2_ENABLE);
++	outl(TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR);
+ 
+ 	restore_flags(flags);
+ }
+ 
+ static void rs_enable_tx_interrupts (void * ptr) 
+ {
+-	struct rs_port *port = ptr; 
+ 	unsigned long flags;
+ 
+ 	save_and_cli(flags);
+ 
+-	IntClear2 = (INTTYPE(UART_TX_INT) |
+-			INTTYPE(UART_EMPTY_INT) |
+-			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
+-
+-	IntEnable2 |= (INTTYPE(UART_TX_INT) |
+-			INTTYPE(UART_EMPTY_INT) |
+-			INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
+-
+-	/* Send a char to start TX interrupts happening */
+-	transmit_char_pio(port);
++	outl(TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR);
++	outl(inl(TX3912_INT2_ENABLE) | TX3912_INT2_UARTA_TX_BITS,
++		TX3912_INT2_ENABLE);
++	transmit_char_pio(rs_port);
+ 
+ 	restore_flags(flags);
+ }
+ 
+ static void rs_disable_rx_interrupts (void * ptr) 
+ {
+-	struct rs_port *port = ptr;
+ 	unsigned long flags;
+ 
+ 	save_and_cli(flags);
+ 
+-	IntEnable2 &= ~((INTTYPE(UART_RX_INT) |
+-			 INTTYPE(UART_RXOVERRUN_INT) |
+-			 INTTYPE(UART_FRAMEERR_INT) |
+-			 INTTYPE(UART_BREAK_INT) |
+-			 INTTYPE(UART_PARITYERR_INT)) << port->intshift);
+-
+-	IntClear2 = (INTTYPE(UART_RX_INT) |
+-			 INTTYPE(UART_RXOVERRUN_INT) |
+-			 INTTYPE(UART_FRAMEERR_INT) |
+-			 INTTYPE(UART_BREAK_INT) |
+-			 INTTYPE(UART_PARITYERR_INT)) << port->intshift;
++	outl(inl(TX3912_INT2_ENABLE) & ~TX3912_INT2_UARTA_RX_BITS,
++		TX3912_INT2_ENABLE);
++	outl(TX3912_INT2_UARTA_RX_BITS, TX3912_INT2_CLEAR);
+ 
+ 	restore_flags(flags);
+ }
+ 
+ static void rs_enable_rx_interrupts (void * ptr) 
+ {
+-	struct rs_port *port = ptr;
+ 	unsigned long flags;
+ 
+ 	save_and_cli(flags);
+ 
+-	IntEnable2 |= (INTTYPE(UART_RX_INT) |
+-			 INTTYPE(UART_RXOVERRUN_INT) |
+-			 INTTYPE(UART_FRAMEERR_INT) |
+-			 INTTYPE(UART_BREAK_INT) |
+-			 INTTYPE(UART_PARITYERR_INT)) << port->intshift;
+-
+-	/* Empty the input buffer - apparently this is *vital* */
+-	while (inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL) { 
+-		inb(port->base + TX3912_UART_DATA);
+-	}
+-
+-	IntClear2 = (INTTYPE(UART_RX_INT) |
+-			 INTTYPE(UART_RXOVERRUN_INT) |
+-			 INTTYPE(UART_FRAMEERR_INT) |
+-			 INTTYPE(UART_BREAK_INT) |
+-			 INTTYPE(UART_PARITYERR_INT)) << port->intshift;
++	outl(inl(TX3912_INT2_ENABLE) | TX3912_INT2_UARTA_RX_BITS,
++		TX3912_INT2_ENABLE);
++	while (inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_RXHOLDFULL)
++		inb(TX3912_UARTA_DATA);
++	outl(TX3912_INT2_UARTA_RX_BITS, TX3912_INT2_CLEAR);
+ 
+ 	restore_flags(flags);
+ }
+ 
+-
++/*
++ * We have no CD
++ */
+ static int rs_get_CD (void * ptr) 
+ {
+-	/* No Carried Detect in Hardware - just return true */
+-	func_exit();
+-	return (1);
++	return 1;
+ }
+ 
++/*
++ * Shut down the port
++ */
+ static void rs_shutdown_port (void * ptr) 
+ {
+-	struct rs_port *port = ptr; 
+-
+ 	func_enter();
+-
+-	port->gs.flags &= ~GS_ACTIVE;
+-
++	rs_port->gs.flags &= ~GS_ACTIVE;
+ 	func_exit();
+ }
+ 
+ static int rs_set_real_termios (void *ptr)
+ {
+-	struct rs_port *port = ptr;
+-	int t;
++	unsigned int ctrl1 = 0;
++	unsigned int ctrl2 = 0;
+ 
+-	switch (port->gs.baud) {
+-		/* Save some typing work... */
+-#define e(x) case x:t= TX3912_UART_CTRL2_B ## x ; break
+-		e(300);e(600);e(1200);e(2400);e(4800);e(9600);
+-		e(19200);e(38400);e(57600);e(76800);e(115200);e(230400);
+-	case 0      :t = -1;
+-		break;
+-	default:
+-		/* Can I return "invalid"? */
+-		t = TX3912_UART_CTRL2_B9600;
+-		printk (KERN_INFO "rs: unsupported baud rate: %d.\n", port->gs.baud);
+-		break;
+-	}
+-#undef e
+-	if (t >= 0) {
+-		/* Jim: Set Hardware Baud rate - there is some good
+-		   code in drivers/char/serial.c */
+-
+-	  	/* Program hardware for parity, data bits, stop bits (note: these are hardcoded to 8N1 */
+-		UartA_Ctrl1 &= 0xf000000f;
+-		UartA_Ctrl1 &= ~(UART_DIS_TXD | SER_SEVEN_BIT | SER_EVEN_PARITY | SER_TWO_STOP);
+-
+-#define CFLAG port->gs.tty->termios->c_cflag
+-		if (C_PARENB(port->gs.tty)) {
+-			if (!C_PARODD(port->gs.tty))
+-				UartA_Ctrl1 |= SER_EVEN_PARITY;
+-			else
+-				UartA_Ctrl1 |= SER_ODD_PARITY;
+-		}
+-		if ((CFLAG & CSIZE)==CS6)
+-			printk(KERN_ERR "6 bits not supported\n");
+-		if ((CFLAG & CSIZE)==CS5)
+-			printk(KERN_ERR "5 bits not supported\n");
+-		if ((CFLAG & CSIZE)==CS7)
+-			UartA_Ctrl1 |= SER_SEVEN_BIT;
+-		if (C_CSTOPB(port->gs.tty))
+-			UartA_Ctrl1 |= SER_TWO_STOP;
+-
+-		outl(t, port->base + TX3912_UART_CTRL2);
+-		outl(0, port->base + TX3912_UART_DMA_CTRL1);
+-		outl(0, port->base + TX3912_UART_DMA_CTRL2);
+-        	UartA_Ctrl1 |= TX3912_UART_CTRL1_UARTON;
++	/* Set baud rate */
++	switch (rs_port->gs.baud) {
++		case 0:
++			goto done;
++		case 1200:
++			ctrl2 = TX3912_UART_CTRL2_B1200;
++			break;
++		case 2400:
++			ctrl2 = TX3912_UART_CTRL2_B2400;
++			break;
++		case 4800:
++			ctrl2 = TX3912_UART_CTRL2_B4800;
++			break;
++		case 9600:
++			ctrl2 = TX3912_UART_CTRL2_B9600;
++			break;
++		case 19200:
++			ctrl2 = TX3912_UART_CTRL2_B19200;
++			break;
++		case 38400:
++			ctrl2 = TX3912_UART_CTRL2_B38400;
++			break;
++		case 57600:
++			ctrl2 = TX3912_UART_CTRL2_B57600;
++			break;
++		case 115200:
++		default:
++			ctrl2 = TX3912_UART_CTRL2_B115200;
++			break;
++	}
++
++  	/* Clear current UARTA settings */
++	ctrl1 = inl(TX3912_UARTA_CTRL1) & 0xf000000f;
+ 
+-        /* wait until UARTA is stable */
+-        while (~UartA_Ctrl1 & TX3912_UART_CTRL1_UARTON);
++	/* Set parity */
++	if(C_PARENB(rs_port->gs.tty)) {
++		if (!C_PARODD(rs_port->gs.tty))
++			ctrl1 |= (TX3912_UART_CTRL1_ENPARITY |
++				 TX3912_UART_CTRL1_EVENPARITY);
++		else
++			ctrl1 |= TX3912_UART_CTRL1_ENPARITY;
+ 	}
+ 
+-	func_exit ();
+-        return 0;
++	/* Set data size */
++	switch(rs_port->gs.tty->termios->c_cflag & CSIZE) {
++		case CS7:
++			ctrl1 |= TX3912_UART_CTRL1_BIT_7;
++			break;
++		case CS5:
++		case CS6:
++			printk(KERN_ERR "Data byte size unsupported. Defaulting to CS8\n");
++		case CS8:
++		default:
++			ctrl1 &= ~TX3912_UART_CTRL1_BIT_7;
++	}
++
++	/* Set stop bits */
++	if(C_CSTOPB(rs_port->gs.tty))
++		ctrl1 |= TX3912_UART_CTRL1_TWOSTOP;
++
++	/* Write the control registers */
++	outl(ctrl2, TX3912_UARTA_CTRL2);
++	outl(0, TX3912_UARTA_DMA_CTRL1);
++	outl(0, TX3912_UARTA_DMA_CTRL2);
++	outl(ctrl1, TX3912_UARTA_CTRL1);
++
++	/* Loop until the UART is on */
++	while(~inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_UARTON);
++
++done:
++	func_exit();
++	return 0;
+ }
+ 
++/*
++ * Anyone in the buffer?
++ */
+ static int rs_chars_in_buffer (void * ptr) 
+ {
+-	struct rs_port *port = ptr;
+-	int scratch;
+-
+-	scratch = inl(port->base + TX3912_UART_CTRL1);
+-
+-	return ((scratch & UART_TX_EMPTY) ? 0 : 1);
++	return ((inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_EMPTY) ? 0 : 1);
+ }
+ 
+-/* ********************************************************************** *
+- *                Here are the routines that actually                     *
+- *               interface with the rest of the system                    *
+- * ********************************************************************** */
+-static int rs_open  (struct tty_struct * tty, struct file * filp)
++/*
++ * Open the serial port
++ */
++static int rs_open(struct tty_struct * tty, struct file * filp)
+ {
+-	struct rs_port *port;
+-	int retval, line;
++	int retval;
+ 
+ 	func_enter();
+ 
+@@ -536,132 +403,95 @@ static int rs_open  (struct tty_struct *
+ 		return -EIO;
+ 	}
+ 
+-	line = tty->index;
+-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p)\n", 
+-	            (int) current->pid, line, tty, current->tty);
+-
+-	if ((line < 0) || (line >= TX3912_UART_NPORTS))
+-		return -ENODEV;
+-
+-	/* Pre-initialized already */
+-	port = & rs_ports[line];
+-
+-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "port = %p\n", port);
+-
+-	tty->driver_data = port;
+-	port->gs.tty = tty;
+-	port->gs.count++;
++	rs_dprintk(TX3912_UART_DEBUG_OPEN, "Serial opening...\n");
+ 
+-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "starting port\n");
++	tty->driver_data = rs_port;
++	rs_port->gs.tty = tty;
++	rs_port->gs.count++;
+ 
+ 	/*
+ 	 * Start up serial port
+ 	 */
+-	retval = gs_init_port(&port->gs);
+-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "done gs_init\n");
+-	if (retval) {
+-		port->gs.count--;
++	retval = gs_init_port(&rs_port->gs);
++	rs_dprintk(TX3912_UART_DEBUG_OPEN, "Finished gs_init...\n");
++	if(retval) {
++		rs_port->gs.count--;
+ 		return retval;
+ 	}
+ 
+-	port->gs.flags |= GS_ACTIVE;
++	rs_port->gs.flags |= GS_ACTIVE;
+ 
+-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "before inc_use_count (count=%d.\n", 
+-	            port->gs.count);
+-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "after inc_use_count\n");
++	rs_enable_rx_interrupts(rs_port);
++	rs_enable_tx_interrupts(rs_port);
+ 
+-	/* Jim: Initialize port hardware here */
+-
+-	/* Enable high-priority interrupts for UARTA */
+-	IntEnable6 |= INT6_UARTARXINT; 
+-	rs_enable_rx_interrupts(&rs_ports[0]); 
+-
+-	retval = gs_block_til_ready(&port->gs, filp);
+-	rs_dprintk (TX3912_UART_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", 
+-	            retval, port->gs.count);
+-
+-	if (retval) {
+-		port->gs.count--;
++	retval = gs_block_til_ready(&rs_port->gs, filp);
++	if(retval) {
++		rs_port->gs.count--;
+ 		return retval;
+ 	}
+-	/* tty->low_latency = 1; */
+ 
+ 	func_exit();
+ 
+-	/* Jim */
+-/*	cli(); */
+-
+ 	return 0;
+-
+ }
+ 
+-
+-static int rs_ioctl (struct tty_struct * tty, struct file * filp, 
++/*
++ * Serial ioctl call
++ */
++static int rs_ioctl(struct tty_struct * tty, struct file * filp, 
+                      unsigned int cmd, unsigned long arg)
+ {
+-	int rc;
+-	struct rs_port *port = tty->driver_data;
+-	int ival;
++	int ival, rc;
+ 
+ 	rc = 0;
+ 	switch (cmd) {
+-	case TIOCGSOFTCAR:
+-		rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
++		case TIOCGSOFTCAR:
++			rc = put_user((tty->termios->c_cflag & CLOCAL) ? 1 : 0,
+ 		              (unsigned int *) arg);
+-		break;
+-	case TIOCSSOFTCAR:
+-		if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
+-			tty->termios->c_cflag =
+-				(tty->termios->c_cflag & ~CLOCAL) |
+-				(ival ? CLOCAL : 0);
+-		}
+-		break;
+-	case TIOCGSERIAL:
+-		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+-		                      sizeof(struct serial_struct))) == 0)
+-			rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
+-		break;
+-	case TIOCSSERIAL:
+-		if ((rc = verify_area(VERIFY_READ, (void *) arg,
+-		                      sizeof(struct serial_struct))) == 0)
+-			rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
+-		break;
+-	default:
+-		rc = -ENOIOCTLCMD;
+-		break;
++			break;
++		case TIOCSSOFTCAR:
++			if ((rc = get_user(ival, (unsigned int *) arg)) == 0) {
++				tty->termios->c_cflag =
++					(tty->termios->c_cflag & ~CLOCAL) |
++					(ival ? CLOCAL : 0);
++			}
++			break;
++		case TIOCGSERIAL:
++			if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
++				sizeof(struct serial_struct))) == 0)
++				rc = gs_getserial(&rs_port->gs,
++				                  (struct serial_struct *) arg);
++			break;
++		case TIOCSSERIAL:
++			if ((rc = verify_area(VERIFY_READ, (void *) arg,
++				sizeof(struct serial_struct))) == 0)
++				rc = gs_setserial(&rs_port->gs, (struct serial_struct *) arg);
++			break;
++		default:
++			rc = -ENOIOCTLCMD;
++			break;
+ 	}
+ 
+-	/* func_exit(); */
+ 	return rc;
+ }
+ 
+-
+ /*
+- * This function is used to send a high-priority XON/XOFF character to
+- * the device
++ * Send xchar
+  */
+ static void rs_send_xchar(struct tty_struct * tty, char ch)
+ {
+-	struct rs_port *port = (struct rs_port *)tty->driver_data;
+-	func_enter ();
++	func_enter();
+ 	
+-	port->x_char = ch;
++	rs_port->x_char = ch;
+ 	if (ch) {
+-		/* Make sure transmit interrupts are on */
+ 		rs_enable_tx_interrupts(tty);
+ 	}
+ 
+ 	func_exit();
+ }
+ 
+-
+ /*
+- * ------------------------------------------------------------
+- * rs_throttle()
+- * 
+- * This routine is called by the upper-layer tty layer to signal that
+- * incoming characters should be throttled.
+- * ------------------------------------------------------------
++ * Throttle characters as directed by upper tty layer
+  */
+ static void rs_throttle(struct tty_struct * tty)
+ {
+@@ -672,17 +502,19 @@ static void rs_throttle(struct tty_struc
+ 	       tty->ldisc.chars_in_buffer(tty));
+ #endif
+ 
+-	func_enter ();
++	func_enter();
+ 	
+ 	if (I_IXOFF(tty))
+ 		rs_send_xchar(tty, STOP_CHAR(tty));
+ 
+-	func_exit ();
++	func_exit();
+ }
+ 
++/*
++ * Un-throttle characters as directed by upper tty layer
++ */
+ static void rs_unthrottle(struct tty_struct * tty)
+ {
+-	struct rs_port *port = (struct rs_port *)tty->driver_data;
+ #ifdef TX3912_UART_DEBUG_THROTTLE
+ 	char	buf[64];
+ 	
+@@ -693,8 +525,8 @@ static void rs_unthrottle(struct tty_str
+ 	func_enter();
+ 	
+ 	if (I_IXOFF(tty)) {
+-		if (port->x_char)
+-			port->x_char = 0;
++		if (rs_port->x_char)
++			rs_port->x_char = 0;
+ 		else
+ 			rs_send_xchar(tty, START_CHAR(tty));
+ 	}
+@@ -702,68 +534,11 @@ static void rs_unthrottle(struct tty_str
+ 	func_exit();
+ }
+ 
+-
+-
+-
+-
+-/* ********************************************************************** *
+- *                    Here are the initialization routines.               *
+- * ********************************************************************** */
+-
+-void * ckmalloc (int size)
+-{
+-        void *p;
+-
+-        p = kmalloc(size, GFP_KERNEL);
+-        if (p) 
+-                memset(p, 0, size);
+-        return p;
+-}
+-
+-
+-
+-static int rs_init_portstructs(void)
+-{
+-	struct rs_port *port;
+-	int i;
+-
+-	/* Debugging */
+-	func_enter();
+-
+-	rs_ports          = ckmalloc(TX3912_UART_NPORTS * sizeof (struct rs_port));
+-	if (!rs_ports)
+-		return -ENOMEM;
+-
+-	port = rs_ports;
+-	for (i=0; i < TX3912_UART_NPORTS;i++) {
+-		rs_dprintk (TX3912_UART_DEBUG_INIT, "initing port %d\n", i);
+-		port->gs.magic = SERIAL_MAGIC;
+-		port->gs.close_delay = HZ/2;
+-		port->gs.closing_wait = 30 * HZ;
+-		port->gs.rd = &rs_real_driver;
+-#ifdef NEW_WRITE_LOCKING
+-		port->gs.port_write_sem = MUTEX;
+-#endif
+-#ifdef DECLARE_WAITQUEUE
+-		init_waitqueue_head(&port->gs.open_wait);
+-		init_waitqueue_head(&port->gs.close_wait);
+-#endif
+-		port->base = (i == 0) ? TX3912_UARTA_BASE : TX3912_UARTB_BASE;
+-		port->intshift = (i == 0) ? UARTA_SHIFT : UARTB_SHIFT;
+-		rs_dprintk (TX3912_UART_DEBUG_INIT, "base 0x%08lx intshift %d\n",
+-			    port->base, port->intshift);
+-		port++;
+-	}
+-
+-	func_exit();
+-	return 0;
+-}
+-
+ static struct tty_operations rs_ops = {
+-	.open	= rs_open,
++	.open   = rs_open,
+ 	.close = gs_close,
+ 	.write = gs_write,
+-	.put_char = gs_put_char, 
++	.put_char = gs_put_char,
+ 	.flush_chars = gs_flush_chars,
+ 	.write_room = gs_write_room,
+ 	.chars_in_buffer = gs_chars_in_buffer,
+@@ -777,15 +552,62 @@ static struct tty_operations rs_ops = {
+ 	.hangup = gs_hangup,
+ };
+ 
+-static int rs_init_drivers(void)
++/*
++ * Initialize the serial port
++ */
++static void __init tx3912_rs_init(void)
+ {
+-	int error;
+-
+ 	func_enter();
+ 
+ 	rs_driver = alloc_tty_driver(TX3912_UART_NPORTS);
+ 	if (!rs_driver)
+ 		return -ENOMEM;
++
++	rs_dprintk(TX3912_UART_DEBUG_INIT, "Initializing serial...\n");
++
++	/* Allocate critical structures */
++	if(!(rs_tty = kmalloc(sizeof(struct tty_struct), GFP_KERNEL))) {
++		return;
++	}
++	if(!(rs_port = kmalloc(sizeof(struct rs_port), GFP_KERNEL))) {
++		kfree(rs_tty);
++		return;
++	}
++	if(!(rs_termios = kmalloc(sizeof(struct termios), GFP_KERNEL))) {
++		kfree(rs_port);
++		kfree(rs_tty);
++		return;
++	}
++	if(!(rs_termios_locked = kmalloc(sizeof(struct termios), GFP_KERNEL))) {
++		kfree(rs_termios);
++		kfree(rs_port);
++		kfree(rs_tty);
++		return;
++	}
++
++	/* Zero out the structures */
++	memset(rs_tty, 0, sizeof(struct tty_struct));
++	memset(rs_port, 0, sizeof(struct rs_port));
++	memset(rs_termios, 0, sizeof(struct termios));
++	memset(rs_termios_locked, 0, sizeof(struct termios));
++	memset(&rs_driver, 0, sizeof(rs_driver));
++	memset(&rs_callout_driver, 0, sizeof(rs_callout_driver));
++
++	/* Fill in hardware specific port structure */
++	rs_port->gs.callout_termios = tty_std_termios;
++	rs_port->gs.normal_termios	= tty_std_termios;
++	rs_port->gs.magic = SERIAL_MAGIC;
++	rs_port->gs.close_delay = HZ/2;
++	rs_port->gs.closing_wait = 30 * HZ;
++	rs_port->gs.rd = &rs_real_driver;
++#ifdef NEW_WRITE_LOCKING
++	rs_port->gs.port_write_sem = MUTEX;
++#endif
++#ifdef DECLARE_WAITQUEUE
++	init_waitqueue_head(&rs_port->gs.open_wait);
++	init_waitqueue_head(&rs_port->gs.close_wait);
++#endif
++
+ 	rs_driver->owner = THIS_MODULE;
+ 	rs_driver->driver_name = "serial";
+ 	rs_driver->name = "ttyS";
+@@ -798,78 +620,48 @@ static int rs_init_drivers(void)
+ 		B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+ 	tty_set_operations(rs_driver, &rs_ops);
+ 	if ((error = tty_register_driver(rs_driver))) {
+-		printk(KERN_ERR "Couldn't register serial driver, error = %d\n",
+-		       error);
++		printk(KERN_ERR "Unable to register serial driver\n");
+ 		put_tty_driver(rs_driver);
+-		return 1;
++		goto error;
+ 	}
+-	return 0;
+-}
+-
+ 
+-static void __init tx3912_rs_init(void)
+-{
+-	int rc;
+-
+-
+-	func_enter();
+-	rs_dprintk (TX3912_UART_DEBUG_INIT, "Initing serial module... (rs_debug=%d)\n", rs_debug);
++	/* Assign IRQs */
++	if(request_irq(2, rs_tx_interrupt, SA_SHIRQ,
++		"uarta_tx", rs_port)) {
++		printk(KERN_ERR "Cannot allocate IRQ for UARTA_TX.\n");
++		goto error;
++	}
+ 
+-	rc = rs_init_portstructs ();
+-	rs_init_drivers ();
+-	if (request_irq(2, rs_tx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
+-			"serial", &rs_ports[0])) {
+-		printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
+-		rc = 0;
+-	}
+-	if (request_irq(3, rs_rx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
+-			"serial", &rs_ports[0])) {
+-		printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
+-		rc = 0;
++	if(request_irq(3, rs_rx_interrupt, SA_SHIRQ,
++		"uarta_rx", rs_port)) {
++		printk(KERN_ERR "Cannot allocate IRQ for UARTA_RX.\n");
++		goto error;
+ 	}
+ 
+-	IntEnable6 |= INT6_UARTARXINT; 
+-	rs_enable_rx_interrupts(&rs_ports[0]); 
++	/* Enable the serial receive interrupt */
++	rs_enable_rx_interrupts(rs_port); 
+ 
+ #ifndef CONFIG_SERIAL_TX3912_CONSOLE
+-{
+-	unsigned int scratch = 0;
++	/* Write the control registers */
++	outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_CTRL2);
++	outl(0x00000000, TX3912_UARTA_DMA_CTRL1);
++	outl(0x00000000, TX3912_UARTA_DMA_CTRL2);
++	outl(inl(TX3912_UARTA_CTRL1) | TX3912_UART_CTRL1_ENUART,
++		TX3912_UARTA_CTRL1);
+ 
+-	/* Setup master clock for UART */
+-	scratch = inl(TX3912_CLK_CTRL_BASE);
+-	scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
+-	scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
+-				TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
+-			| TX3912_CLK_CTRL_SIBMCLKDIR
+-			| TX3912_CLK_CTRL_ENSIBMCLK
+-			| TX3912_CLK_CTRL_CSERSEL;
+-	outl(scratch, TX3912_CLK_CTRL_BASE);
+-
+-	/* Configure UARTA clock */
+-	scratch = inl(TX3912_CLK_CTRL_BASE);
+-	scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
+-				TX3912_CLK_CTRL_CSERDIV_MASK)
+-			| TX3912_CLK_CTRL_ENCSERCLK
+-			| TX3912_CLK_CTRL_ENUARTACLK;
+-	outl(scratch, TX3912_CLK_CTRL_BASE);
+-		
+-	/* Setup UARTA for 115200,8N1 */
+-	outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+-	outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
+-	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
+-	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
+-
+-	/* Enable UARTA */
+-	outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+-	while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
+-		TX3912_UART_CTRL1_UARTON);
+-}
++	/* Loop until the UART is on */
++	while(~inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_UARTON);
+ #endif
+ 
+-	/* Note: I didn't do anything to enable the second UART */
+-	if (rc >= 0) 
+-		rs_initialized++;
++	rs_initialized = 1;
++	func_exit();
++	return;
+ 
++error:
++	kfree(rs_termios_locked);
++	kfree(rs_termios);
++	kfree(rs_port);
++	kfree(rs_tty);
+ 	func_exit();
+ }
+ module_init(tx3912_rs_init);
+@@ -878,40 +670,37 @@ module_init(tx3912_rs_init);
+  * Begin serial console routines
+  */
+ #ifdef CONFIG_SERIAL_TX3912_CONSOLE
+-
+ void serial_outc(unsigned char c)
+ {
+ 	int i;
+ 	unsigned long int2;
+-	#define BUSY_WAIT 10000
+-
+-	/*
+-	 * Turn UARTA interrupts off
+-	 */
+-	int2 = IntEnable2;
+-	IntEnable2 &=
+-		~(INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY);
+-
+-	/*
+-	 * The UART_TX_EMPTY bit in UartA_Ctrl1 seems
+-	 * not to be very reliable :-(
+-	 *
+-	 * Wait for the Tx register to become empty
+-	 */
+-	for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
+ 
+-	IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
+-	UartA_Data = c;
+-	for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
+-	IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
++	/* Disable UARTA_TX interrupts */
++	int2 = inl(TX3912_INT2_ENABLE);
++	outl(inl(TX3912_INT2_ENABLE) & ~TX3912_INT2_UARTA_TX_BITS,
++		 TX3912_INT2_ENABLE);
++
++	/* Wait for UARTA_TX register to empty */
++	i = 10000;
++	while(!(inl(TX3912_INT2_STATUS) & TX3912_INT2_UARTATXINT) && i--);
++	outl(TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR);
++
++	/* Send the character */
++	outl(c, TX3912_UARTA_DATA);
++
++	/* Wait for UARTA_TX register to empty */
++	i = 10000;
++	while(!(inl(TX3912_INT2_STATUS) & TX3912_INT2_UARTATXINT) && i--);
++	outl(TX3912_INT2_UARTA_TX_BITS, TX3912_INT2_CLEAR);
+ 
+-	IntEnable2 = int2;
++	/* Enable UARTA_TX interrupts */
++	outl(int2, TX3912_INT2_ENABLE);
+ }
+ 
+ static void serial_console_write(struct console *co, const char *s,
+-		unsigned count)
++	unsigned count)
+ {
+-    	unsigned int i;
++	unsigned int i;
+ 
+ 	for (i = 0; i < count; i++) {
+ 		if (*s == '\n')
+@@ -928,36 +717,78 @@ static struct tty_driver *serial_console
+ 
+ static __init int serial_console_setup(struct console *co, char *options)
+ {
+-	unsigned int scratch = 0;
++	int baud = 115200;
++	int bits = 8;
++	int parity = 'n';
++	char *s;
++	unsigned int ctrl1 = 0;
++	unsigned int ctrl2 = 0;
++
++	if (options) {
++		baud = simple_strtoul(options, NULL, 10);
++		s = options;
++		while(*s >= '0' && *s <= '9')
++			s++;
++		if (*s) parity = *s++;
++		if (*s) bits   = *s++ - '0';
++	}
++
++	switch(baud) {
++		case 1200:
++			ctrl2 = TX3912_UART_CTRL2_B1200;
++			break;
++		case 2400:
++			ctrl2 = TX3912_UART_CTRL2_B2400;
++			break;
++		case 4800:
++			ctrl2 = TX3912_UART_CTRL2_B4800;
++			break;
++		case 9600:
++			ctrl2 = TX3912_UART_CTRL2_B9600;
++			break;
++		case 19200:
++			ctrl2 = TX3912_UART_CTRL2_B19200;
++			break;
++		case 38400:
++			ctrl2 = TX3912_UART_CTRL2_B38400;
++			break;
++		case 57600:
++			ctrl2 = TX3912_UART_CTRL2_B57600;
++			break;
++		case 115200:
++		default:
++			ctrl2 = TX3912_UART_CTRL2_B115200;
++			break;
++	}
++
++	switch(bits) {
++		case 7:
++			ctrl1 = TX3912_UART_CTRL1_BIT_7;
++			break;
++		default:
++			break;
++	}
++
++	switch(parity) {
++		case 'o': case 'O':
++			ctrl1 |= TX3912_UART_CTRL1_ENPARITY;
++			break;
++		case 'e': case 'E':
++			ctrl1 |= (TX3912_UART_CTRL1_ENPARITY |
++				 TX3912_UART_CTRL1_EVENPARITY);
++			break;
++		default:
++			break;
++	}
++
++	/* Write the control registers */
++	outl(ctrl2, TX3912_UARTA_CTRL2);
++	outl(0x00000000, TX3912_UARTA_DMA_CTRL1);
++	outl(0x00000000, TX3912_UARTA_DMA_CTRL2);
++	outl((ctrl1 | TX3912_UART_CTRL1_ENUART), TX3912_UARTA_CTRL1);
+ 
+-	/* Setup master clock for UART */
+-	scratch = inl(TX3912_CLK_CTRL_BASE);
+-	scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
+-	scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
+-				TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
+-			| TX3912_CLK_CTRL_SIBMCLKDIR
+-			| TX3912_CLK_CTRL_ENSIBMCLK
+-			| TX3912_CLK_CTRL_CSERSEL;
+-	outl(scratch, TX3912_CLK_CTRL_BASE);
+-
+-	/* Configure UARTA clock */
+-	scratch = inl(TX3912_CLK_CTRL_BASE);
+-	scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
+-				TX3912_CLK_CTRL_CSERDIV_MASK)
+-			| TX3912_CLK_CTRL_ENCSERCLK
+-			| TX3912_CLK_CTRL_ENUARTACLK;
+-	outl(scratch, TX3912_CLK_CTRL_BASE);
+-		
+-	/* Setup UARTA for 115200,8N1 */
+-	outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+-	outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
+-	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
+-	outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
+-
+-	/* Enable UARTA */
+-	outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+-	while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
+-		TX3912_UART_CTRL1_UARTON);
++	/* Loop until the UART is on */
++	while(~inl(TX3912_UARTA_CTRL1) & TX3912_UART_CTRL1_UARTON);
+ 
+ 	return 0;
+ }
+diff -urpNX dontdiff linux-2.6.10/drivers/char/serial_tx3912.h linux-2.6.10-mips/drivers/char/serial_tx3912.h
+--- linux-2.6.10/drivers/char/serial_tx3912.h	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/serial_tx3912.h	2004-09-21 13:10:14.000000000 +0200
+@@ -1,8 +1,6 @@
+ /*
+  *  drivers/char/serial_tx3912.h
+  *
+- *  Copyright (C) 1999 Harald Koerfgen
+- *  Copyright (C) 2000 Jim Pick <jim at jimpick.com>
+  *  Copyright (C) 2001 Steven J. Hill (sjhill at realitydiluted.com)
+  *
+  * This program is free software; you can redistribute it and/or modify
+@@ -14,27 +12,6 @@
+ #include <linux/serialP.h>
+ #include <linux/generic_serial.h>
+ 
+-/* UART Interrupt (Interrupt 2) bits (UARTA,UARTB) */
+-#define UART_RX_INT         9  /* receiver holding register full  (31, 21) */
+-#define UART_RXOVERRUN_INT  8  /* receiver overrun error          (30, 20) */
+-#define UART_FRAMEERR_INT   7  /* receiver frame error            (29, 19) */
+-#define UART_BREAK_INT      6  /* received break signal           (28, 18) */
+-#define UART_PARITYERR_INT  5  /* receiver parity error           (27, 17) */
+-#define UART_TX_INT         4  /* transmit holding register empty (26, 16) */
+-#define UART_TXOVERRUN_INT  3  /* transmit overrun error          (25, 15) */
+-#define UART_EMPTY_INT      2  /* both trans/recv regs empty      (24, 14) */
+-#define UART_DMAFULL_INT    1  /* DMA at end of buffer            (23, 13) */
+-#define UART_DMAHALF_INT    0  /* DMA halfway through buffer      (22, 12) */
+-
+-#define UARTA_SHIFT        22
+-#define UARTB_SHIFT        12
+-
+-#define INTTYPE(interrupttype)            (1 << interrupttype)
+-
+-/* 
+- * This driver can spew a whole lot of debugging output at you. If you
+- * need maximum performance, you should disable the DEBUG define.
+- */
+ #undef TX3912_UART_DEBUG
+ 
+ #ifdef TX3912_UART_DEBUG
+@@ -53,39 +30,28 @@
+ #define TX3912_UART_DEBUG_FIRMWARE	0x00001000
+ #define TX3912_UART_DEBUG_MEMTEST	0x00002000
+ #define TX3912_UART_DEBUG_THROTTLE	0x00004000
++#define TX3912_UART_DEBUG_NO_TX		0xffffffdf
+ #define TX3912_UART_DEBUG_ALL		0xffffffff
+ 
+-int rs_debug = TX3912_UART_DEBUG_ALL & ~TX3912_UART_DEBUG_TRANSMIT;
+-
+-#define rs_dprintk(f, str...) if (rs_debug & f) printk (str)
+-#define func_enter() rs_dprintk (TX3912_UART_DEBUG_FLOW,	\
++#define rs_dprintk(f, str...) if(TX3912_UART_DEBUG_NO_TX & f) printk(str)
++#define func_enter() rs_dprintk(TX3912_UART_DEBUG_FLOW,		\
+ 				"rs: enter %s\n", __FUNCTION__)
+-#define func_exit() rs_dprintk (TX3912_UART_DEBUG_FLOW,	\
++#define func_exit() rs_dprintk(TX3912_UART_DEBUG_FLOW,		\
+ 				"rs: exit %s\n", __FUNCTION__)
+-
+ #else
+ #define rs_dprintk(f, str...)
+ #define func_enter()
+ #define func_exit()
+-
+-#endif	/* TX3912_UART_DEBUG */
+-
+-/*
+- * Number of serial ports
+- */
+-#define TX3912_UART_NPORTS  2
++#endif
+ 
+ /*
+  * Hardware specific serial port structure
+  */
+ struct rs_port { 	
+ 	struct gs_port		gs;		/* Must be first field! */
+-
+-	unsigned long		base;
+-	int			intshift;	/* Register shift */
+ 	struct wait_queue	*shutdown_wait; 
+ 	int			stat_flags;
+-        struct async_icount	icount;		/* Counters for 4 input IRQs */
++	struct async_icount	icount;		/* Counters for 4 input IRQs */
+ 	int			read_status_mask;
+ 	int			ignore_status_mask;
+ 	int			x_char;		/* XON/XOFF character */
+diff -urpNX dontdiff linux-2.6.10/drivers/char/serial_txx9.c linux-2.6.10-mips/drivers/char/serial_txx9.c
+--- linux-2.6.10/drivers/char/serial_txx9.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/serial_txx9.c	2004-11-12 16:25:02.000000000 +0100
+@@ -0,0 +1,1744 @@
++/*
++ *  drivers/char/serial_txx9.c
++ *
++ *  Copyright (C) 1999 Harald Koerfgen
++ *  Copyright (C) 2000 Jim Pick <jim at jimpick.com>
++ *  Copyright (C) 2001 Steven J. Hill (sjhill at realitydiluted.com)
++ *  Copyright (C) 2000-2002 Toshiba Corporation
++ *
++ * 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.
++ *
++ * Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller
++ *
++ * Copyright (C) 2004 MontaVista Software Inc.
++ * Author: Manish Lachwani, mlachwani at mvista.com
++ */
++#include <linux/init.h>
++#include <linux/config.h>
++#include <linux/tty.h>
++#include <linux/major.h>
++#include <linux/ptrace.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/fs.h>
++#include <linux/mm.h>
++#include <linux/ioport.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/pm.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/delay.h>
++#include <linux/serial.h>
++#include <linux/generic_serial.h>
++#include <linux/pci.h>
++#ifdef CONFIG_MAGIC_SYSRQ
++#include <linux/sysrq.h>
++#endif
++#include <asm/irq.h>
++
++#define  DEBUG
++#ifdef  DEBUG
++#define DBG(x...)       printk(x)
++#else
++#define DBG(x...)       
++#endif
++
++static char *serial_version = "0.30-mvl";
++static char *serial_name = "TX39/49 Serial driver";
++static struct tty_driver *serial_driver;
++
++#define GS_INTERNAL_FLAGS (GS_TX_INTEN|GS_RX_INTEN|GS_ACTIVE)
++
++#define TXX9_SERIAL_MAGIC 0x39274927
++
++#ifdef CONFIG_SERIAL
++/* "ttyS","cua" is used for standard serial driver */
++#define TXX9_TTY_NAME "ttyTX"
++#define TXX9_TTY_DEVFS_NAME "tts/TX%d"
++#define TXX9_TTY_MINOR_START	(64 + 64)	/* ttyTX0(128), ttyTX1(129) */
++#define TXX9_CU_NAME "cuatx"
++#define TXX9_CU_DEVFS_NAME "cua/TX%d"
++#else
++/* acts like standard serial driver */
++#define TXX9_TTY_NAME "ttyS"
++#define TXX9_TTY_DEVFS_NAME "tts/%d"
++#define TXX9_TTY_MINOR_START	64
++#define TXX9_CU_NAME "cua"
++#define TXX9_CU_DEVFS_NAME "cua/%d"
++#endif
++#define TXX9_TTY_MAJOR	TTY_MAJOR
++#define TXX9_TTYAUX_MAJOR	TTYAUX_MAJOR
++
++#define TXX9_SERIAL_HAVE_CTS_LINE	1
++
++#ifdef CONFIG_PCI
++/* support for Toshiba TC86C001 SIO */
++#define ENABLE_SERIAL_TXX9_PCI
++#endif
++
++/*
++ * Number of serial ports
++ */
++#ifdef ENABLE_SERIAL_TXX9_PCI
++#define NR_PCI_BOARDS	4
++#define NR_PORTS  (2 + NR_PCI_BOARDS)
++#else
++#define NR_PORTS  2
++#endif
++
++/*
++ * Hardware specific serial port structure
++ */
++static struct rs_port {
++	struct gs_port		gs;		/* Must be first field! */
++
++	unsigned long		base;
++	int			irq;
++	int			baud_base;
++	int			flags;
++        struct async_icount	icount;
++	int			x_char;		/* XON/XOFF character */
++	int			read_status_mask;
++	int			ignore_status_mask;
++	int			quot;
++	char			io_type;
++#ifdef ENABLE_SERIAL_TXX9_PCI
++	struct pci_dev *	pci_dev;
++#endif
++} rs_ports[NR_PORTS]
++#ifdef CONFIG_TOSHIBA_RBTX4925
++= {
++	/* NR_PORTS = 0 */
++	{base:		0xff1f0000 + 0xf300,
++	 irq:		36,
++	 baud_base:	40000000 / 16 / 2,
++	 io_type:	-1,		/* virtual memory mapped */
++	 flags: 	TXX9_SERIAL_HAVE_CTS_LINE,},
++	/* NR_PORTS = 1 */
++	{base:		0xff1f0000 + 0xf400,
++	 irq:		37,
++	 baud_base:	40000000 / 16 / 2,
++	 io_type:	-1,		/* virtual memory mapped */
++	 flags: 	TXX9_SERIAL_HAVE_CTS_LINE,}
++};
++#endif
++#ifdef CONFIG_TOSHIBA_RBTX4927
++= {
++	/* NR_PORTS = 0 */
++	{base:		0xff1f0000 + 0xf300,
++	 irq:		32,
++	 baud_base:	50000000 / 16 / 2,
++	 io_type:	-1,		/* virtual memory mapped */
++	 flags: 	TXX9_SERIAL_HAVE_CTS_LINE,},
++	/* NR_PORTS = 1 */
++	{base:		0xff1f0000 + 0xf400,
++	 irq:		33,
++	 baud_base:	50000000 / 16 / 2,
++	 io_type:	-1,		/* virtual memory mapped */
++	 flags: 	TXX9_SERIAL_HAVE_CTS_LINE,}
++};
++#endif
++
++/* TXX9 Serial Registers */
++#define TXX9_SILCR	0x00
++#define TXX9_SIDICR	0x04
++#define TXX9_SIDISR	0x08
++#define TXX9_SICISR	0x0c
++#define TXX9_SIFCR	0x10
++#define TXX9_SIFLCR	0x14
++#define TXX9_SIBGR	0x18
++#define TXX9_SITFIFO	0x1c
++#define TXX9_SIRFIFO	0x20
++
++/* SILCR : Line Control */
++#define TXX9_SILCR_SCS_MASK	0x00000060
++#define TXX9_SILCR_SCS_IMCLK	0x00000000
++#define TXX9_SILCR_SCS_IMCLK_BG	0x00000020
++#define TXX9_SILCR_SCS_SCLK	0x00000040
++#define TXX9_SILCR_SCS_SCLK_BG	0x00000060
++#define TXX9_SILCR_UEPS	0x00000010
++#define TXX9_SILCR_UPEN	0x00000008
++#define TXX9_SILCR_USBL_MASK	0x00000004
++//#define TXX9_SILCR_USBL_1BIT	0x00000004
++//#define TXX9_SILCR_USBL_2BIT	0x00000000
++#define TXX9_SILCR_USBL_1BIT	0x00000000
++#define TXX9_SILCR_USBL_2BIT	0x00000004
++#define TXX9_SILCR_UMODE_MASK	0x00000003
++#define TXX9_SILCR_UMODE_8BIT	0x00000000
++#define TXX9_SILCR_UMODE_7BIT	0x00000001
++
++/* SIDICR : DMA/Int. Control */
++#define TXX9_SIDICR_TDE	0x00008000
++#define TXX9_SIDICR_RDE	0x00004000
++#define TXX9_SIDICR_TIE	0x00002000
++#define TXX9_SIDICR_RIE	0x00001000
++#define TXX9_SIDICR_SPIE	0x00000800
++#define TXX9_SIDICR_CTSAC	0x00000600
++#define TXX9_SIDICR_STIE_MASK	0x0000003f
++#define TXX9_SIDICR_STIE_OERS		0x00000020
++#define TXX9_SIDICR_STIE_CTSS		0x00000010
++#define TXX9_SIDICR_STIE_RBRKD	0x00000008
++#define TXX9_SIDICR_STIE_TRDY		0x00000004
++#define TXX9_SIDICR_STIE_TXALS	0x00000002
++#define TXX9_SIDICR_STIE_UBRKD	0x00000001
++
++/* SIDISR : DMA/Int. Status */
++#define TXX9_SIDISR_UBRK	0x00008000
++#define TXX9_SIDISR_UVALID	0x00004000
++#define TXX9_SIDISR_UFER	0x00002000
++#define TXX9_SIDISR_UPER	0x00001000
++#define TXX9_SIDISR_UOER	0x00000800
++#define TXX9_SIDISR_ERI	0x00000400
++#define TXX9_SIDISR_TOUT	0x00000200
++#define TXX9_SIDISR_TDIS	0x00000100
++#define TXX9_SIDISR_RDIS	0x00000080
++#define TXX9_SIDISR_STIS	0x00000040
++#define TXX9_SIDISR_RFDN_MASK	0x0000001f
++
++/* SICISR : Change Int. Status */
++#define TXX9_SICISR_OERS	0x00000020
++#define TXX9_SICISR_CTSS	0x00000010
++#define TXX9_SICISR_RBRKD	0x00000008
++#define TXX9_SICISR_TRDY	0x00000004
++#define TXX9_SICISR_TXALS	0x00000002
++#define TXX9_SICISR_UBRKD	0x00000001
++
++/* SIFCR : FIFO Control */
++#define TXX9_SIFCR_SWRST	0x00008000
++#define TXX9_SIFCR_RDIL_MASK	0x00000180
++#define TXX9_SIFCR_RDIL_1	0x00000000
++#define TXX9_SIFCR_RDIL_4	0x00000080
++#define TXX9_SIFCR_RDIL_8	0x00000100
++#define TXX9_SIFCR_RDIL_12	0x00000180
++#define TXX9_SIFCR_RDIL_MAX	0x00000180
++#define TXX9_SIFCR_TDIL_MASK	0x00000018
++#define TXX9_SIFCR_TDIL_MASK	0x00000018
++#define TXX9_SIFCR_TDIL_1	0x00000000
++#define TXX9_SIFCR_TDIL_4	0x00000001
++#define TXX9_SIFCR_TDIL_8	0x00000010
++#define TXX9_SIFCR_TDIL_MAX	0x00000010
++#define TXX9_SIFCR_TFRST	0x00000004
++#define TXX9_SIFCR_RFRST	0x00000002
++#define TXX9_SIFCR_FRSTE	0x00000001
++#define TXX9_SIO_TX_FIFO	8
++#define TXX9_SIO_RX_FIFO	16
++
++/* SIFLCR : Flow Control */
++#define TXX9_SIFLCR_RCS	0x00001000
++#define TXX9_SIFLCR_TES	0x00000800
++#define TXX9_SIFLCR_RTSSC	0x00000200
++#define TXX9_SIFLCR_RSDE	0x00000100
++#define TXX9_SIFLCR_TSDE	0x00000080
++#define TXX9_SIFLCR_RTSTL_MASK	0x0000001e
++#define TXX9_SIFLCR_RTSTL_MAX	0x0000001e
++#define TXX9_SIFLCR_TBRK	0x00000001
++
++/* SIBGR : Baudrate Control */
++#define TXX9_SIBGR_BCLK_MASK	0x00000300
++#define TXX9_SIBGR_BCLK_T0	0x00000000
++#define TXX9_SIBGR_BCLK_T2	0x00000100
++#define TXX9_SIBGR_BCLK_T4	0x00000200
++#define TXX9_SIBGR_BCLK_T6	0x00000300
++#define TXX9_SIBGR_BRD_MASK	0x000000ff
++
++static /*inline*/ unsigned int
++sio_in(struct rs_port *port, int offset)
++{
++	if (port->io_type < 0)
++		/* don't use __raw_readl that does swapping for big endian */
++		return (*(volatile unsigned long*)(port->base + offset));
++	else
++		return inl(port->base + offset);
++}
++
++static /*inline*/ void
++sio_out(struct rs_port *port, int offset, unsigned int value)
++{
++	if (port->io_type < 0)
++		/* don't use __raw_writel that does swapping for big endian */
++                (*(volatile unsigned long*)(port->base + offset))=(value);
++	else
++		outl(value, port->base + offset);
++}
++
++static inline void
++sio_mask(struct rs_port *port, int offset, unsigned int value)
++{
++	sio_out(port, offset, sio_in(port, offset) & ~value);
++}
++static inline void
++sio_set(struct rs_port *port, int offset, unsigned int value)
++{
++	sio_out(port, offset, sio_in(port, offset) | value);
++}
++
++/*
++ * Forward declarations for serial routines
++ */
++static void rs_disable_tx_interrupts (void * ptr);
++static void rs_enable_tx_interrupts (void * ptr);
++static void rs_disable_rx_interrupts (void * ptr);
++static void rs_enable_rx_interrupts (void * ptr);
++static int rs_get_CD (void * ptr);
++static void rs_shutdown_port (void * ptr);
++static int rs_set_real_termios (void *ptr);
++static int rs_chars_in_buffer (void * ptr);
++static void rs_hungup (void *ptr);
++static void rs_getserial (void*, struct serial_struct *sp);
++static void rs_close (void *ptr);
++
++/*
++ * Used by generic serial driver to access hardware
++ */
++static struct real_driver rs_real_driver = {
++	disable_tx_interrupts: rs_disable_tx_interrupts,
++	enable_tx_interrupts:  rs_enable_tx_interrupts,
++	disable_rx_interrupts: rs_disable_rx_interrupts,
++	enable_rx_interrupts:  rs_enable_rx_interrupts,
++	get_CD:                rs_get_CD,
++	shutdown_port:         rs_shutdown_port,
++	set_real_termios:      rs_set_real_termios,
++	chars_in_buffer:       rs_chars_in_buffer,
++	close:                 rs_close,
++	hungup:                rs_hungup,
++	getserial:             rs_getserial,
++};
++
++/*
++ * Structures and such for TTY sessions and usage counts
++ */
++static struct tty_driver rs_driver, rs_callout_driver;
++static struct tty_struct *rs_table[NR_PORTS];
++static struct termios *rs_termios[NR_PORTS];
++static struct termios *rs_termios_locked[NR_PORTS];
++int rs_refcount;
++int rs_initialized = 0;
++
++#ifdef CONFIG_SERIAL_TXX9_CONSOLE
++static struct console sercons;
++#endif
++#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
++static unsigned long break_pressed; /* break, really ... */
++#endif
++
++static inline void receive_chars(struct rs_port *port,
++				 int *status, struct pt_regs *regs)
++{
++	struct tty_struct *tty = port->gs.tty;
++	unsigned char ch;
++	struct	async_icount *icount;
++	int	max_count = 256;
++
++	icount = &port->icount;
++	do {
++		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
++				return;
++		}
++		ch = sio_in(port, TXX9_SIRFIFO);
++		*tty->flip.char_buf_ptr = ch;
++		icount->rx++;
++
++		*tty->flip.flag_buf_ptr = 0;
++		if (*status & (TXX9_SIDISR_UBRK | TXX9_SIDISR_UPER |
++			       TXX9_SIDISR_UFER | TXX9_SIDISR_UOER)) {
++			/*
++			 * For statistics only
++			 */
++			if (*status & TXX9_SIDISR_UBRK) {
++				*status &= ~(TXX9_SIDISR_UFER | TXX9_SIDISR_UPER);
++				icount->brk++;
++				/*
++				 * We do the SysRQ and SAK checking
++				 * here because otherwise the break
++				 * may get masked by ignore_status_mask
++				 * or read_status_mask.
++				 */
++#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
++				if (port == &rs_ports[sercons.index]) {
++					if (!break_pressed) {
++						break_pressed = jiffies;
++						goto ignore_char;
++					}
++					break_pressed = 0;
++				}
++#endif
++				if (port->gs.flags & ASYNC_SAK)
++					do_SAK(tty);
++			} else if (*status & TXX9_SIDISR_UPER)
++				icount->parity++;
++			else if (*status & TXX9_SIDISR_UFER)
++				icount->frame++;
++			if (*status & TXX9_SIDISR_UOER)
++				icount->overrun++;
++
++			/*
++			 * Mask off conditions which should be ignored.
++			 */
++			*status &= port->read_status_mask;
++
++#ifdef CONFIG_SERIAL_TXX9_CONSOLE
++			/* Break flag is updated by reading RFIFO. */
++#endif
++			if (*status & (TXX9_SIDISR_UBRK)) {
++				*tty->flip.flag_buf_ptr = TTY_BREAK;
++			} else if (*status & TXX9_SIDISR_UPER)
++				*tty->flip.flag_buf_ptr = TTY_PARITY;
++			else if (*status & TXX9_SIDISR_UFER)
++				*tty->flip.flag_buf_ptr = TTY_FRAME;
++		}
++#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
++		if (break_pressed && port == &rs_ports[sercons.index]) {
++			if (ch != 0 &&
++			    time_before(jiffies, break_pressed + HZ*5)) {
++				handle_sysrq(ch, regs, NULL, NULL);
++				break_pressed = 0;
++				goto ignore_char;
++			}
++			break_pressed = 0;
++		}
++#endif
++		if ((*status & port->ignore_status_mask) == 0) {
++			tty->flip.flag_buf_ptr++;
++			tty->flip.char_buf_ptr++;
++			tty->flip.count++;
++		}
++		if ((*status & TXX9_SIDISR_UOER) &&
++		    (tty->flip.count < TTY_FLIPBUF_SIZE)) {
++			/*
++			 * Overrun is special, since it's reported
++			 * immediately, and doesn't affect the current
++			 * character
++			 */
++			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
++			tty->flip.count++;
++			tty->flip.flag_buf_ptr++;
++			tty->flip.char_buf_ptr++;
++		}
++#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
++	ignore_char:
++#endif
++		*status = sio_in(port, TXX9_SIDISR);
++	} while ((!(*status & TXX9_SIDISR_UVALID)) && (max_count-- > 0));
++	tty_flip_buffer_push(tty);
++}
++
++static inline void transmit_chars(struct rs_port *port)
++{
++	int count;
++
++	if (port->x_char) {
++		sio_out(port, TXX9_SITFIFO, port->x_char);
++		port->icount.tx++;
++		port->x_char = 0;
++		return;
++	}
++	if (port->gs.xmit_cnt <= 0
++	    || port->gs.tty->stopped
++	    || port->gs.tty->hw_stopped) {
++		rs_disable_tx_interrupts(port);
++		return;
++	}
++
++	count = TXX9_SIO_TX_FIFO;
++	do {
++		sio_out(port, TXX9_SITFIFO, port->gs.xmit_buf[port->gs.xmit_tail++]);
++		port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1;
++		port->icount.tx++;
++		if (--port->gs.xmit_cnt <= 0)
++			break;
++	} while (--count > 0);
++
++	if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
++	     port->gs.tty->hw_stopped) {
++		rs_disable_tx_interrupts(port);
++	}
++
++	if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
++                if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
++                    port->gs.tty->ldisc.write_wakeup)
++                        (port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
++                wake_up_interruptible(&port->gs.tty->write_wait);
++	}
++}
++
++static inline void check_modem_status(struct rs_port *port)
++{
++        /* We don't have a carrier detect line - but just respond
++           like we had one anyways so that open() becomes unblocked */
++	wake_up_interruptible(&port->gs.open_wait);
++}
++
++#define RS_ISR_PASS_LIMIT 256
++
++static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
++{
++	struct rs_port * port = (struct rs_port *)dev_id;
++	unsigned long flags;
++	int status;
++	int pass_counter = 0;
++
++	local_irq_save(flags);
++
++	if (!port || !port->gs.tty) {
++		local_irq_restore(flags);
++		return;
++	}
++
++	do {
++		status = sio_in(port, TXX9_SIDISR);
++		if (!(sio_in(port, TXX9_SIDICR) & TXX9_SIDICR_TIE))
++			status &= ~TXX9_SIDISR_TDIS;
++		if (!(status & (TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS |
++				TXX9_SIDISR_TOUT)))
++			break;
++
++		if (status & TXX9_SIDISR_RDIS)
++			receive_chars(port, &status, regs);
++#if 0		/* RTS/CTS are controled by HW. (if possible) */
++		check_modem_status(port);
++#endif
++		if (status & TXX9_SIDISR_TDIS)
++			transmit_chars(port);
++		/* Clear TX/RX Int. Status */
++		sio_mask(port, TXX9_SIDISR,
++			 TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS |
++			 TXX9_SIDISR_TOUT);
++
++		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
++			break;
++		}
++	} while (1);
++	local_irq_restore(flags);
++}
++
++/*
++ ***********************************************************************
++ *                Here are the routines that actually                  *
++ *              interface with the generic_serial driver               *
++ ***********************************************************************
++ */
++static void rs_disable_tx_interrupts (void * ptr)
++{
++	struct rs_port *port = ptr;
++	unsigned long flags;
++
++	local_irq_save(flags);
++        port->gs.flags &= ~GS_TX_INTEN;
++	sio_mask(port, TXX9_SIDICR, TXX9_SIDICR_TIE);
++	local_irq_restore(flags);
++}
++
++static void rs_enable_tx_interrupts (void * ptr)
++{
++	struct rs_port *port = ptr;
++	unsigned long flags;
++
++	local_irq_save(flags);
++	sio_set(port, TXX9_SIDICR, TXX9_SIDICR_TIE);
++	local_irq_restore(flags);
++}
++
++static void rs_disable_rx_interrupts (void * ptr)
++{
++	struct rs_port *port = ptr;
++	unsigned long flags;
++
++	local_irq_save(flags);
++	port->read_status_mask &= ~TXX9_SIDISR_RDIS;
++#if 0
++	sio_mask(port, TXX9_SIDICR, TXX9_SIDICR_RIE);
++#endif
++	local_irq_restore(flags);
++}
++
++static void rs_enable_rx_interrupts (void * ptr)
++{
++	struct rs_port *port = ptr;
++	sio_set(port, TXX9_SIDICR, TXX9_SIDICR_RIE);
++}
++
++
++static int rs_get_CD (void * ptr)
++{
++	/* No Carried Detect in Hardware - just return true */
++	return (1);
++}
++
++static void rs_shutdown_port (void * ptr)
++{
++	struct rs_port *port = ptr;
++
++	port->gs.flags &= ~GS_ACTIVE;
++
++	free_irq(port->irq, port);
++	sio_out(port, TXX9_SIDICR, 0);	/* disable all intrs */
++	/* disable break condition */
++	sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_TBRK);
++
++#ifdef CONFIG_SERIAL_TXX9_CONSOLE
++	if (port == &rs_ports[sercons.index]) {
++#endif
++	if (!port->gs.tty || (port->gs.tty->termios->c_cflag & HUPCL)) {
++		/* drop RTS */
++		sio_set(port, TXX9_SIFLCR,
++			TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
++		/* TXX9-SIO can not control DTR... */
++	}
++
++	/* reset FIFO's */
++	sio_set(port, TXX9_SIFCR,
++		TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE);
++	/* clear reset */
++	sio_mask(port, TXX9_SIFCR,
++		 TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST | TXX9_SIFCR_FRSTE);
++	/* Disable RX/TX */
++	sio_set(port, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE);
++#ifdef CONFIG_SERIAL_TXX9_CONSOLE
++	}
++#endif
++}
++
++static int rs_set_real_termios (void *ptr)
++{
++	struct rs_port *port = ptr;
++	int	quot = 0, baud_base, baud;
++	unsigned cflag, cval, fcr = 0;
++	int	bits;
++	unsigned long	flags;
++
++	if (!port->gs.tty || !port->gs.tty->termios)
++		return 0;
++	cflag = port->gs.tty->termios->c_cflag;
++	cval = sio_in(port, TXX9_SILCR);
++	/* byte size and parity */
++	cval &= ~TXX9_SILCR_UMODE_MASK;
++	switch (cflag & CSIZE) {
++	case CS7:
++		cval |= TXX9_SILCR_UMODE_7BIT;
++		bits = 9;
++		break;
++	case CS5:	/* not supported */
++	case CS6:	/* not supported */
++	case CS8:
++	default:
++		cval |= TXX9_SILCR_UMODE_8BIT;
++		bits = 10;
++		break;
++	}
++	cval &= ~TXX9_SILCR_USBL_MASK;
++	if (cflag & CSTOPB) {
++		cval |= TXX9_SILCR_USBL_2BIT;
++		bits++;
++	} else {
++		cval |= TXX9_SILCR_USBL_1BIT;
++	}
++
++	cval &= ~(TXX9_SILCR_UPEN | TXX9_SILCR_UEPS);
++	if (cflag & PARENB) {
++		cval |= TXX9_SILCR_UPEN;
++		bits++;
++	}
++	if (!(cflag & PARODD))
++		cval |= TXX9_SILCR_UEPS;
++
++	/* Determine divisor based on baud rate */
++	baud = tty_get_baud_rate(port->gs.tty);
++	if (!baud)
++		baud = 9600;	/* B0 transition handled in rs_set_termios */
++	baud_base = port->baud_base;
++	quot = (baud_base + baud / 2) / baud;
++	/* As a last resort, if the quotient is zero, default to 9600 bps */
++	if (!quot)
++		quot = (baud_base + 9600 / 2) / 9600;
++	port->quot = quot;
++
++	/* Set up FIFO's */
++	/* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
++	fcr = TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1;
++
++	/* CTS flow control flag */
++	if (cflag & CRTSCTS) {
++		port->gs.flags |= ASYNC_CTS_FLOW;
++		if (port->flags & TXX9_SERIAL_HAVE_CTS_LINE)
++			sio_out(port, TXX9_SIFLCR,
++				TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES |
++				TXX9_SIFLCR_RTSTL_MAX /* 15 */);
++	} else {
++		port->gs.flags &= ~ASYNC_CTS_FLOW;
++		sio_mask(port, TXX9_SIFLCR,
++			 TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES |
++			 TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE);
++	}
++
++	/*
++	 * Set up parity check flag
++	 */
++#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
++
++	port->read_status_mask = TXX9_SIDISR_UOER |
++		TXX9_SIDISR_TDIS | TXX9_SIDISR_RDIS;
++	if (I_INPCK(port->gs.tty))
++		port->read_status_mask |= TXX9_SIDISR_UFER | TXX9_SIDISR_UPER;
++	if (I_BRKINT(port->gs.tty) || I_PARMRK(port->gs.tty))
++		port->read_status_mask |= TXX9_SIDISR_UBRK;
++
++	/*
++	 * Characters to ignore
++	 */
++	port->ignore_status_mask = 0;
++	if (I_IGNPAR(port->gs.tty))
++		port->ignore_status_mask |= TXX9_SIDISR_UPER | TXX9_SIDISR_UFER;
++	if (I_IGNBRK(port->gs.tty)) {
++		port->ignore_status_mask |= TXX9_SIDISR_UBRK;
++		/*
++		 * If we're ignore parity and break indicators, ignore
++		 * overruns too.  (For real raw support).
++		 */
++		if (I_IGNPAR(port->gs.tty))
++			port->ignore_status_mask |= TXX9_SIDISR_UOER;
++	}
++#if 0	/* XXX: This cause problem with some programs(init, mingetty, etc) */
++	/*
++	 * !!! ignore all characters if CREAD is not set
++	 */
++	if ((cflag & CREAD) == 0)
++		port->ignore_status_mask |= TXX9_SIDISR_RDIS;
++#endif
++	local_irq_save(flags);
++	cval &= ~TXX9_SILCR_SCS_IMCLK;
++	sio_out(port, TXX9_SILCR, cval | TXX9_SILCR_SCS_IMCLK_BG);
++	sio_out(port, TXX9_SIBGR, quot | TXX9_SIBGR_BCLK_T0);
++	sio_out(port, TXX9_SIFCR, fcr);
++	local_irq_restore(flags);
++	return 0;
++}
++
++static int rs_chars_in_buffer (void * ptr)
++{
++	struct rs_port *port = ptr;
++
++	/* return 0 if transmitter disabled. */
++	if (sio_in(port, TXX9_SIFLCR) & TXX9_SIFLCR_TSDE)
++		return 0;
++	return (sio_in(port, TXX9_SICISR) & TXX9_SICISR_TXALS) ? 0 : 1;
++}
++
++/* ********************************************************************** *
++ *                Here are the routines that actually                     *
++ *               interface with the rest of the system                    *
++ * ********************************************************************** */
++static int rs_open (struct tty_struct * tty, struct file * filp)
++{
++	struct rs_port *port;
++	int retval, line;
++
++	if (!rs_initialized) {
++		return -EIO;
++	}
++
++	line = tty->index;
++
++	if ((line < 0) || (line >= NR_PORTS))
++		return -ENODEV;
++
++	/* Pre-initialized already */
++	port = & rs_ports[line];
++
++	if (!port->base) 
++		return -ENODEV;
++
++	tty->driver_data = port;
++	port->gs.tty = tty;
++	port->gs.count++;
++
++	/*
++	 * Start up serial port
++	 */
++	retval = gs_init_port(&port->gs);
++	if (retval) {
++		port->gs.count--;
++		return retval;
++	}
++
++	port->gs.flags |= GS_ACTIVE;
++
++	if (port->gs.count == 1) {
++		/*
++		 * Clear the FIFO buffers and disable them
++		 * (they will be reenabled in rs_set_real_termios())
++		 */
++		sio_set(port, TXX9_SIFCR,
++			TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST |
++			TXX9_SIFCR_FRSTE);
++		/* clear reset */
++		sio_mask(port, TXX9_SIFCR,
++			 TXX9_SIFCR_TFRST | TXX9_SIFCR_RFRST |
++			 TXX9_SIFCR_FRSTE);
++		sio_out(port, TXX9_SIDICR, 0);
++
++		retval = request_irq(port->irq, rs_interrupt, SA_SHIRQ,
++				     "serial_txx9", port);
++		if (retval) {
++			printk(KERN_ERR "serial_txx9: request_irq: err %d\n",
++			       retval);
++			port->gs.count--;
++			return retval;
++		}
++		/*
++		 * Clear the interrupt registers.
++		 */
++		sio_out(port, TXX9_SIDISR, 0);
++
++		/* HW RTS/CTS control */
++		if (port->flags & TXX9_SERIAL_HAVE_CTS_LINE)
++			sio_out(port, TXX9_SIFLCR,
++				TXX9_SIFLCR_RCS | TXX9_SIFLCR_TES |
++				TXX9_SIFLCR_RTSTL_MAX /* 15 */);
++	}
++
++	/* Enable RX/TX */
++	sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE);
++
++	/*
++	 * Finally, enable interrupts
++	 */
++	rs_enable_rx_interrupts(port);
++
++	/*
++	 * and set the speed of the serial port
++	 */
++	rs_set_real_termios(port);
++
++	retval = gs_block_til_ready(&port->gs, filp);
++
++	if (retval) {
++		if (port->gs.count == 1) {
++			free_irq(port->irq, port);
++		}
++		port->gs.count--;
++		return retval;
++	}
++	/* tty->low_latency = 1; */
++
++	if (port->gs.count == 1) 
++		rs_set_real_termios(port);
++
++#ifdef CONFIG_SERIAL_TXX9_CONSOLE
++	if (sercons.cflag && sercons.index == line) {
++		tty->termios->c_cflag = sercons.cflag;
++		sercons.cflag = 0;
++		rs_set_real_termios(port);
++	}
++#endif
++	return 0;
++}
++
++/*
++ * /proc fs routines....
++ */
++
++static inline int line_info(char *buf, struct rs_port *port)
++{
++	char	stat_buf[30];
++	int	ret;
++	unsigned long flags;
++
++	ret = sprintf(buf, "%d: uart:txx9 io%s:%lx irq:%d",
++		      port - &rs_ports[0],
++		      port->io_type < 0 ? "mem" : "port",
++		      port->base, port->irq);
++
++	if (!port->base) {
++		ret += sprintf(buf+ret, "\n");
++		return ret;
++	}
++
++	/*
++	 * Figure out the current RS-232 lines
++	 */
++	stat_buf[0] = 0;
++	stat_buf[1] = 0;
++	local_irq_save(flags);
++	if (!(sio_in(port, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC))
++		strcat(stat_buf, "|RTS");
++	if (!(sio_in(port, TXX9_SICISR) & TXX9_SICISR_CTSS))
++		strcat(stat_buf, "|CTS");
++	local_irq_restore(flags);
++
++	if (port->quot) {
++		ret += sprintf(buf+ret, " baud:%d",
++			       port->baud_base / port->quot);
++	}
++
++	ret += sprintf(buf+ret, " tx:%d rx:%d",
++		       port->icount.tx, port->icount.rx);
++
++	if (port->icount.frame)
++		ret += sprintf(buf+ret, " fe:%d", port->icount.frame);
++
++	if (port->icount.parity)
++		ret += sprintf(buf+ret, " pe:%d", port->icount.parity);
++
++	if (port->icount.brk)
++		ret += sprintf(buf+ret, " brk:%d", port->icount.brk);
++
++	if (port->icount.overrun)
++		ret += sprintf(buf+ret, " oe:%d", port->icount.overrun);
++
++	/*
++	 * Last thing is the RS-232 status lines
++	 */
++	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
++	return ret;
++}
++
++static int rs_read_proc(char *page, char **start, off_t off, int count,
++			int *eof, void *data)
++{
++	int i, len = 0, l;
++	off_t	begin = 0;
++
++	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
++	for (i = 0; i < NR_PORTS && len < 4000; i++) {
++		l = line_info(page + len, &rs_ports[i]);
++		len += l;
++		if (len+begin > off+count)
++			goto done;
++		if (len+begin < off) {
++			begin += len;
++			len = 0;
++		}
++	}
++	*eof = 1;
++done:
++	if (off >= len+begin)
++		return 0;
++	*start = page + (begin-off);
++	return ((count < begin+len-off) ? count : begin+len-off);
++}
++
++static void rs_close (void *ptr)
++{
++#if 0
++	struct rs_port *port = ptr;
++	free_irq(port->irq, port);
++#endif
++}
++
++/* I haven't the foggiest why the decrement use count has to happen
++   here. The whole linux serial drivers stuff needs to be redesigned.
++   My guess is that this is a hack to minimize the impact of a bug
++   elsewhere. Thinking about it some more. (try it sometime) Try
++   running minicom on a serial port that is driven by a modularized
++   driver. Have the modem hangup. Then remove the driver module. Then
++   exit minicom.  I expect an "oops".  -- REW */
++static void rs_hungup (void *ptr)
++{
++}
++
++static void rs_getserial (void *ptr, struct serial_struct *sp)
++{
++	struct rs_port *port = ptr;
++	struct tty_struct *tty = port->gs.tty;
++	/* some applications (busybox, dbootstrap, etc.) look this */
++	sp->line = tty->index;
++}
++
++/*
++ * rs_break() --- routine which turns the break handling on or off
++ */
++static void rs_break(struct tty_struct *tty, int break_state)
++{
++	struct rs_port *port = tty->driver_data;
++	unsigned long flags;
++
++	if (!port->base)
++		return;
++	local_irq_save(flags);
++	if (break_state == -1)
++		sio_set(port, TXX9_SIFLCR, TXX9_SIFLCR_TBRK);
++	else
++		sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_TBRK);
++	local_irq_restore(flags);
++}
++
++static int get_modem_info(struct rs_port *port, unsigned int *value)
++{
++	unsigned int result;
++	unsigned long flags;
++
++	local_irq_save(flags);
++	result =  ((sio_in(port, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
++		| ((sio_in(port, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS);
++	local_irq_restore(flags);
++	return put_user(result,value);
++}
++
++static int set_modem_info(struct rs_port *port, unsigned int cmd,
++			  unsigned int *value)
++{
++	int error = 0;
++	unsigned int arg;
++	unsigned long flags;
++
++	if (copy_from_user(&arg, value, sizeof(int)))
++		return -EFAULT;
++
++	local_irq_save(flags);
++	switch (cmd) {
++	case TIOCMBIS:
++		if (arg & TIOCM_RTS)
++			sio_mask(port, TXX9_SIFLCR,
++				 TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
++		break;
++	case TIOCMBIC:
++		if (arg & TIOCM_RTS)
++			sio_set(port, TXX9_SIFLCR,
++				TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
++		break;
++	case TIOCMSET:
++		if (arg & TIOCM_RTS)
++			sio_mask(port, TXX9_SIFLCR,
++				 TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
++		else
++			sio_set(port, TXX9_SIFLCR,
++				TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
++		break;
++	default:
++		error = -EINVAL;
++	}
++	local_irq_restore(flags);
++	return error;
++}
++
++static int rs_ioctl (struct tty_struct * tty, struct file * filp,
++                     unsigned int cmd, unsigned long arg)
++{
++	int rc;
++	struct rs_port *port = tty->driver_data;
++	int ival;
++
++	rc = 0;
++	switch (cmd) {
++	case TIOCMGET:
++		return get_modem_info(port, (unsigned int *) arg);
++	case TIOCMBIS:
++	case TIOCMBIC:
++	case TIOCMSET:
++		return set_modem_info(port, cmd, (unsigned int *) arg);
++		return 0;
++	case TIOCGSOFTCAR:
++		rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
++		              (unsigned int *) arg);
++		break;
++	case TIOCSSOFTCAR:
++		if ((rc = verify_area(VERIFY_READ, (void *) arg,
++		                      sizeof(int))) == 0) {
++			get_user(ival, (unsigned int *) arg);
++			tty->termios->c_cflag =
++				(tty->termios->c_cflag & ~CLOCAL) |
++				(ival ? CLOCAL : 0);
++		}
++		break;
++	case TIOCGSERIAL:
++		if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
++		                      sizeof(struct serial_struct))) == 0)
++			rc = gs_getserial(&port->gs, (struct serial_struct *) arg);
++		break;
++	case TIOCSSERIAL:
++		if ((rc = verify_area(VERIFY_READ, (void *) arg,
++		                      sizeof(struct serial_struct))) == 0)
++			rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
++		break;
++	default:
++		rc = -ENOIOCTLCMD;
++		break;
++	}
++
++	return rc;
++}
++
++
++/*
++ * This function is used to send a high-priority XON/XOFF character to
++ * the device
++ */
++static void rs_send_xchar(struct tty_struct * tty, char ch)
++{
++	struct rs_port *port = (struct rs_port *)tty->driver_data;
++
++	port->x_char = ch;
++	if (ch) {
++		/* Make sure transmit interrupts are on */
++		rs_enable_tx_interrupts(tty);
++	}
++}
++
++
++/*
++ * ------------------------------------------------------------
++ * rs_throttle()
++ *
++ * This routine is called by the upper-layer tty layer to signal that
++ * incoming characters should be throttled.
++ * ------------------------------------------------------------
++ */
++static void rs_throttle(struct tty_struct * tty)
++{
++	struct rs_port *port = (struct rs_port *)tty->driver_data;
++	unsigned long flags;
++
++	if (I_IXOFF(tty))
++		rs_send_xchar(tty, STOP_CHAR(tty));
++	if (tty->termios->c_cflag & CRTSCTS) {
++		local_irq_save(flags);
++		/* drop RTS */
++		sio_set(port, TXX9_SIFLCR,
++			TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
++		local_irq_restore(flags);
++	}
++}
++
++static void rs_unthrottle(struct tty_struct * tty)
++{
++	struct rs_port *port = tty->driver_data;
++	unsigned long flags;
++
++	if (I_IXOFF(tty)) {
++		if (port->x_char)
++			port->x_char = 0;
++		else
++			rs_send_xchar(tty, START_CHAR(tty));
++	}
++	if (tty->termios->c_cflag & CRTSCTS) {
++		local_irq_save(flags);
++		sio_mask(port, TXX9_SIFLCR,
++			 TXX9_SIFLCR_RTSSC | TXX9_SIFLCR_RSDE);
++		local_irq_restore(flags);
++	}
++}
++
++/* ********************************************************************** *
++ *                    Here are the initialization routines.               *
++ * ********************************************************************** */
++
++static inline void show_serial_version(void)
++{
++ 	printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
++}
++
++static int rs_init_portstructs(void)
++{
++	struct rs_port *port;
++	int i;
++
++	/* Adjust the values in the "driver" */
++	rs_driver.termios = rs_termios;
++	rs_driver.termios_locked = rs_termios_locked;
++
++	port = rs_ports;
++	for (i=0; i < NR_PORTS;i++) {
++		port->gs.magic = TXX9_SERIAL_MAGIC;
++		port->gs.close_delay = HZ/2;
++		port->gs.closing_wait = 30 * HZ;
++		port->gs.rd = &rs_real_driver;
++#ifdef NEW_WRITE_LOCKING
++		port->gs.port_write_sem = MUTEX;
++#endif
++#ifdef DECLARE_WAITQUEUE
++		init_waitqueue_head(&port->gs.open_wait);
++		init_waitqueue_head(&port->gs.close_wait);
++#endif
++		port++;
++	}
++
++	return 0;
++}
++
++static int rs_init_drivers(void)
++{
++	int error;
++
++	memset(&rs_driver, 0, sizeof(rs_driver));
++	rs_driver.magic = TTY_DRIVER_MAGIC;
++	rs_driver.driver_name = "serial_txx9";
++#if defined(CONFIG_DEVFS_FS)
++	rs_driver.name = TXX9_TTY_DEVFS_NAME;
++#else
++	rs_driver.name = TXX9_TTY_NAME;
++#endif
++	rs_driver.major = TXX9_TTY_MAJOR;
++	rs_driver.minor_start = TXX9_TTY_MINOR_START;
++	rs_driver.num = NR_PORTS;
++	rs_driver.type = TTY_DRIVER_TYPE_SERIAL;
++	rs_driver.subtype = SERIAL_TYPE_NORMAL;
++	rs_driver.init_termios = tty_std_termios;
++	rs_driver.init_termios.c_cflag =
++		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
++	rs_driver.refcount = &rs_refcount;
++	rs_driver.termios = rs_termios;
++	rs_driver.termios_locked = rs_termios_locked;
++
++	rs_driver.open	= rs_open;
++	rs_driver.close = gs_close;
++	rs_driver.write = gs_write;
++	rs_driver.put_char = gs_put_char;
++	rs_driver.flush_chars = gs_flush_chars;
++	rs_driver.write_room = gs_write_room;
++	rs_driver.chars_in_buffer = gs_chars_in_buffer;
++	rs_driver.flush_buffer = gs_flush_buffer;
++	rs_driver.ioctl = rs_ioctl;
++	rs_driver.throttle = rs_throttle;
++	rs_driver.unthrottle = rs_unthrottle;
++	rs_driver.set_termios = gs_set_termios;
++	rs_driver.stop = gs_stop;
++	rs_driver.start = gs_start;
++	rs_driver.hangup = gs_hangup;
++	rs_driver.break_ctl = rs_break;
++	rs_driver.read_proc = rs_read_proc;
++
++	rs_callout_driver = rs_driver;
++#if defined(CONFIG_DEVFS_FS)
++	rs_callout_driver.name = TXX9_CU_DEVFS_NAME;
++#else
++	rs_callout_driver.name = TXX9_CU_NAME;
++#endif
++	if ((error = tty_register_driver(&rs_driver))) {
++		printk(KERN_ERR
++		       "Couldn't register serial driver, error = %d\n",
++		       error);
++		return 1;
++	}
++
++	return 0;
++}
++
++/*
++ * This routine is called by txx9_rs_init() to initialize a specific serial
++ * port.
++ */
++static void txx9_config(struct rs_port *port)
++{
++	unsigned long flags;
++
++	if (port - &rs_ports[0] != sercons.index) {
++		local_irq_save(flags);
++		/*
++		 * Reset the UART.
++		 */
++		sio_out(port, TXX9_SIFCR, TXX9_SIFCR_SWRST);
++#ifdef CONFIG_CPU_TX49XX
++		/* TX4925 BUG WORKAROUND.  Accessing SIOC register
++		 * immediately after soft reset causes bus error. */
++		wbflush();/* change iob(); */
++		udelay(1);
++#endif
++		while (sio_in(port, TXX9_SIFCR) & TXX9_SIFCR_SWRST)
++			;
++		/* TX Int by FIFO Empty, RX Int by Receiving 1 char. */
++		sio_set(port, TXX9_SIFCR,
++			TXX9_SIFCR_TDIL_MAX | TXX9_SIFCR_RDIL_1);
++		/* initial settings */
++		sio_out(port, TXX9_SILCR,
++			TXX9_SILCR_UMODE_8BIT | TXX9_SILCR_USBL_1BIT |
++			TXX9_SILCR_SCS_IMCLK_BG);
++		sio_out(port, TXX9_SIBGR,
++			((port->baud_base + 9600 / 2) / 9600) |
++			TXX9_SIBGR_BCLK_T0);
++		local_irq_restore(flags);
++	}
++	DBG("txx9_config: port->io_type is %d\n", port->io_type);
++	if (port->io_type < 0)
++		request_mem_region(port->base, 36, "serial_txx9");
++	else
++		request_region(port->base, 36, "serial_txx9");
++}
++
++#ifdef ENABLE_SERIAL_TXX9_PCI
++static int __devinit serial_txx9_init_one(struct pci_dev *dev,
++					  const struct pci_device_id *ent)
++{
++	int rc, i;
++	struct rs_port *port;
++
++	rc = pci_enable_device(dev);
++	if (rc) return rc;
++
++	/* find empty slot */
++	for (i = 0; i < NR_PORTS && rs_ports[i].base; i++)
++		;
++	if (i == NR_PORTS)
++		return -ENODEV;
++	port = &rs_ports[i];
++	DBG("port number is %d\n",i);
++
++	port->pci_dev = dev;
++	port->base = pci_resource_start(dev, 1);
++
++	DBG("port->base is %x\n",(u32)port->base);
++	port->io_type = SERIAL_IO_PORT;
++	port->irq = dev->irq;
++	port->flags |= TXX9_SERIAL_HAVE_CTS_LINE;
++	port->baud_base = 66670000 / 16 / 2;	/* 66.67MHz */
++	DBG("port->baud_base %x\n",port->baud_base);
++
++	txx9_config(port);
++
++	printk(KERN_INFO
++		"%s%d at 0x%08lx (irq = %d) is a TX39/49 SIO\n",
++		TXX9_TTY_NAME, i, port->base, port->irq);
++	return 0;
++}
++
++static void __devexit serial_txx9_remove_one(struct pci_dev *dev)
++{
++	int i;
++	for (i = 0; i < NR_PORTS; i++) {
++		if (rs_ports[i].pci_dev == dev) {
++			rs_ports[i].irq = 0;
++			rs_ports[i].base = 0;
++			rs_ports[i].pci_dev = 0;
++			/* XXX NOT IMPLEMENTED YET */
++			break;
++		}
++	}
++}
++
++static struct pci_device_id serial_txx9_pci_tbl[] __devinitdata = {
++#ifdef PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC
++	{	PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC,
++		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
++		0 },
++#endif
++       { 0, }
++};
++
++MODULE_DEVICE_TABLE(pci, serial_txx9_pci_tbl);
++
++static struct pci_driver serial_txx9_pci_driver = {
++       name:           "serial_txx9",
++       probe:          serial_txx9_init_one,
++       remove:	       __devexit_p(serial_txx9_remove_one),
++       id_table:       serial_txx9_pci_tbl,
++};
++
++/*
++ * Query PCI space for known serial boards
++ * If found, add them to the PCI device space in rs_table[]
++ */
++static void __devinit probe_serial_txx9_pci(void) 
++{
++	/* Register call PCI serial devices.  Null out
++	 * the driver name upon failure, as a signal
++	 * not to attempt to unregister the driver later
++	 */
++	if (pci_module_init (&serial_txx9_pci_driver) != 0)
++		serial_txx9_pci_driver.name = "";
++
++	return;
++}
++#endif /* ENABLE_SERIAL_TXX9_PCI */
++
++static int __init txx9_rs_init(void)
++{
++	int rc;
++	struct rs_port *port;
++	int i;
++
++#ifndef ENABLE_SERIAL_TXX9_PCI
++	for (i = 0, port = &rs_ports[0]; i < NR_PORTS; i++,port++) {
++		if (port->base)
++			goto config_ok;
++	}
++	return -ENODEV;
++ config_ok:
++#endif
++
++	show_serial_version();
++	rc = rs_init_portstructs ();
++	rs_init_drivers ();
++	for (i = 0, port = &rs_ports[0]; i < NR_PORTS; i++,port++) {
++		if (!port->base)
++			continue;
++		if (port->io_type < 0) {
++			if (check_mem_region(port->base, 36))
++				continue;
++		} else {
++			if (check_region(port->base, 36))
++				continue;
++		}
++		txx9_config(port);
++		printk(KERN_INFO
++		       "%s%d at 0x%08lx (irq = %d) is a TX39/49 SIO\n",
++		       TXX9_TTY_NAME, i, port->base, port->irq);
++	}
++
++	/* Note: I didn't do anything to enable the second UART */
++	if (rc >= 0)
++		rs_initialized++;
++
++#ifdef ENABLE_SERIAL_TXX9_PCI
++	probe_serial_txx9_pci();
++#endif
++	return 0;
++}
++
++/*
++ * This is for use by architectures that know their serial console
++ * attributes only at run time. Not to be invoked after rs_init().
++ */
++int __init early_serial_txx9_setup(int line, unsigned long base, int irq,
++				   int baud_base, int have_cts)
++{
++	if (line >= NR_PORTS)
++		return(-ENOENT);
++	rs_ports[line].base = base;
++	rs_ports[line].irq = irq;
++	rs_ports[line].baud_base = baud_base;
++	rs_ports[line].io_type = -1;	/* virtual memory mapped */
++	if (have_cts)
++		rs_ports[line].flags |= TXX9_SERIAL_HAVE_CTS_LINE;
++	return(0);
++}
++
++static void __exit txx9_rs_fini(void)
++{
++	unsigned long flags;
++	int e1, e2;
++	int i;
++
++	local_irq_save(flags);
++	if ((e1 = tty_unregister_driver(&rs_driver)))
++		printk("serial: failed to unregister serial driver (%d)\n",
++		       e1);
++	if ((e2 = tty_unregister_driver(&rs_callout_driver)))
++		printk("serial: failed to unregister callout driver (%d)\n",
++		       e2);
++	local_irq_restore(flags);
++
++	for (i = 0; i < NR_PORTS; i++) {
++		if (!rs_ports[i].base)
++			continue;
++		if (rs_ports[i].io_type < 0)
++			release_mem_region(rs_ports[i].base, 36);
++		else
++			release_region(rs_ports[i].base, 36);
++	}
++
++#ifdef ENABLE_SERIAL_PCI
++	if (serial_txx9_pci_driver.name[0])
++		pci_unregister_driver (&serial_txx9_pci_driver);
++#endif
++}
++
++module_init(txx9_rs_init);
++module_exit(txx9_rs_fini);
++MODULE_DESCRIPTION("TX39/49 serial driver");
++MODULE_AUTHOR("TOSHIBA Corporation");
++MODULE_LICENSE("GPL");
++
++/*
++ * Begin serial console routines
++ */
++#ifdef CONFIG_SERIAL_TXX9_CONSOLE
++
++/*
++ *	Wait for transmitter & holding register to empty
++ */
++static inline void wait_for_xmitr(struct rs_port *port)
++{
++	unsigned int tmout = 1000000;
++
++	do {
++		if (--tmout == 0) break;
++	} while (!(sio_in(port, TXX9_SICISR) & TXX9_SICISR_TXALS));
++
++	/* Wait for flow control if necessary */
++#if (ASYNC_INTERNAL_FLAGS & GS_INTERNAL_FLAGS) == 0	/* check conflict... */
++	if (port->gs.flags & ASYNC_CONS_FLOW) {
++		tmout = 1000000;
++		while (--tmout &&
++		       (sio_in(port, TXX9_SICISR) & TXX9_SICISR_CTSS));
++	}
++#endif
++}
++
++/*
++ *	Print a string to the serial port trying not to disturb
++ *	any possible real use of the port...
++ *
++ *	The console_lock must be held when we get here.
++ */
++static void serial_console_write(struct console *co, const char *s,
++				 unsigned count)
++{
++	struct rs_port *port = &rs_ports[co->index];
++	int ier;
++	unsigned i;
++
++	/*
++	 *	First save the IER then disable the interrupts
++	 */
++	ier = sio_in(port, TXX9_SIDICR);
++	sio_out(port, TXX9_SIDICR, 0);
++
++	/*
++	 *	Now, do each character
++	 */
++	for (i = 0; i < count; i++, s++) {
++		wait_for_xmitr(port);
++
++		/*
++		 *	Send the character out.
++		 *	If a LF, also do CR...
++		 */
++		sio_out(port, TXX9_SITFIFO, *s);
++		if (*s == 10) {
++			wait_for_xmitr(port);
++			sio_out(port, TXX9_SITFIFO, 13);
++		}
++	}
++
++	/*
++	 *	Finally, Wait for transmitter & holding register to empty
++	 * 	and restore the IER
++	 */
++	wait_for_xmitr(port);
++	sio_out(port, TXX9_SIDICR, ier);
++}
++
++static struct tty_driver *serial_console_device(struct console *c, int *index)
++{
++	*index = c->index;
++	return &rs_driver;
++}
++
++static int serial_console_setup(struct console *co, char *options)
++{
++	struct rs_port *port;
++	unsigned cval;
++	int	baud = 9600; 
++	int	bits = 8;
++	int	parity = 'n';
++	int	doflow = 0;
++	int	cflag = CREAD | HUPCL | CLOCAL;
++	int	quot = 0;
++	char	*s;
++
++	if (co->index < 0 || co->index >= NR_PORTS)
++		return -1;
++	if (options) {
++		baud = simple_strtoul(options, NULL, 10);
++		s = options;
++		while(*s >= '0' && *s <= '9')
++			s++;
++		if (*s) parity = *s++;
++		if (*s) bits   = *s - '0';
++		if (*s) doflow = (*s++ == 'r');
++	}
++
++	/*
++	 *	Now construct a cflag setting.
++	 */
++	switch(baud) {
++	case 1200:	cflag |= B1200;	break;
++	case 2400:	cflag |= B2400;	break;
++	case 4800:	cflag |= B4800;	break;
++	case 19200:	cflag |= B19200;	break;
++	case 38400:	cflag |= B38400;	break;
++	case 57600:	cflag |= B57600;	break;
++	case 115200:	cflag |= B115200;	break;
++	default:
++		/*
++		 * Set this to a sane value to prevent a divide error
++		 */
++		baud  = 9600;
++	case 9600:	cflag |= B9600;		break;
++	}
++	
++	switch(bits) {
++	case 7:		cflag |= CS7;	break;
++	default:
++	case 8:		cflag |= CS8;	break;
++	}
++	switch(parity) {
++	case 'o': case 'O':	cflag |= PARODD;	break;
++	case 'e': case 'E':	cflag |= PARENB;	break;
++	}
++	co->cflag = cflag;
++
++	port = &rs_ports[co->index];
++	if (!port->base)
++		return -1;
++
++	/*
++	 *	Divisor, bytesize and parity
++	 */
++#if (ASYNC_INTERNAL_FLAGS & GS_INTERNAL_FLAGS) == 0	/* check conflict... */
++	if (doflow)
++		port->gs.flags |= ASYNC_CONS_FLOW;
++#endif
++	quot = port->baud_base / baud;
++	switch (cflag & CSIZE) {
++	case CS7: cval = TXX9_SILCR_UMODE_7BIT; break;
++	default:
++	case CS8: cval = TXX9_SILCR_UMODE_8BIT; break;
++	}
++	if (cflag & CSTOPB)
++		cval |= TXX9_SILCR_USBL_2BIT;
++	else
++		cval |= TXX9_SILCR_USBL_1BIT;
++	if (cflag & PARENB)
++		cval |= TXX9_SILCR_UPEN;
++	if (!(cflag & PARODD))
++		cval |= TXX9_SILCR_UEPS;
++
++	/*
++	 *	Disable UART interrupts, set DTR and RTS high
++	 *	and set speed.
++	 */
++	sio_out(port, TXX9_SIDICR, 0);
++	sio_out(port, TXX9_SILCR, cval | TXX9_SILCR_SCS_IMCLK_BG);
++	sio_out(port, TXX9_SIBGR, quot | TXX9_SIBGR_BCLK_T0);
++	/* no RTS/CTS control */
++	sio_out(port, TXX9_SIFLCR, TXX9_SIFLCR_RTSTL_MAX /* 15 */);
++	/* Enable RX/TX */
++	sio_mask(port, TXX9_SIFLCR, TXX9_SIFLCR_RSDE | TXX9_SIFLCR_TSDE);
++
++	/* console port should not use RTC/CTS. */
++	port->flags &= ~TXX9_SERIAL_HAVE_CTS_LINE;
++	return 0;
++}
++
++static struct console sercons = {
++	name:		TXX9_TTY_NAME,
++	write:		serial_console_write,
++	device:		serial_console_device,
++	setup:		serial_console_setup,
++	flags:		CON_PRINTBUFFER,
++	index:		-1,
++};
++
++static int __init txx9_serial_console_init(void)
++{
++	register_console(&sercons);
++
++	return 0;
++}
++
++console_initcall(txx9_serial_console_init);
++
++#endif
++
++/******************************************************************************/
++/* BEG: KDBG Routines                                                         */
++/******************************************************************************/
++
++#ifdef CONFIG_KGDB
++int kgdb_init_count = 0;
++
++void txx9_sio_kgdb_hook(unsigned int port, unsigned int baud_rate)
++{
++	static struct resource kgdb_resource;
++	int ret;
++
++	/* prevent initialization by driver */
++	kgdb_resource.name = "serial_txx9(debug)";
++	kgdb_resource.start = rs_ports[port].base;
++	kgdb_resource.end = rs_ports[port].base + 36 - 1;
++	kgdb_resource.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
++
++	ret = request_resource(&iomem_resource, &kgdb_resource);
++	if(ret == -EBUSY)
++		printk(" serial_txx9(debug): request_resource failed\n");
++
++	return;
++}
++void
++txx9_sio_kdbg_init( unsigned int port_number )
++{
++  if ( port_number == 1 ) {
++    txx9_sio_kgdb_hook( port_number, 38400 );
++  } else {
++	printk("Bad Port Number [%u] != [1]\n",port_number);
++  }
++  return; 
++}
++
++u8 
++txx9_sio_kdbg_rd( void )
++{
++    unsigned int status,ch;
++
++  if ( kgdb_init_count == 0 )
++  {
++    txx9_sio_kdbg_init( 1 );
++    kgdb_init_count = 1;
++  }
++
++  while ( 1 )
++  {
++    status = sio_in(&rs_ports[1], TXX9_SIDISR);
++    if ( status & 0x1f )
++    {
++      ch = sio_in(&rs_ports[1], TXX9_SIRFIFO );
++      break;
++    }
++  }
++
++  return( ch );
++}
++
++int 
++txx9_sio_kdbg_wr( u8 ch )
++{
++    unsigned int status;
++
++  if ( kgdb_init_count == 0 )
++  {
++    txx9_sio_kdbg_init( 1 );
++    kgdb_init_count = 1;
++  }
++
++  while ( 1 )
++  {
++    status = sio_in(&rs_ports[1], TXX9_SICISR);
++    if (status & TXX9_SICISR_TRDY)
++    {
++      if ( ch == '\n' )
++      {
++        txx9_sio_kdbg_wr( '\r' );
++      }
++      sio_out(&rs_ports[1], TXX9_SITFIFO, (u32)ch );
++
++      break;
++    }
++  }
++
++  return( 1 );
++}
++#endif /* CONFIG_KGDB */
++
++
++/******************************************************************************/
++/* END: KDBG Routines                                                         */
++/******************************************************************************/
++
++
++void txx9_raw_output(char c)
++{
++	struct rs_port *port = &rs_ports[0];
++	if ( c == '\n' )
++	{
++	  sio_out(port, TXX9_SITFIFO, '\r');
++	  wait_for_xmitr(port);
++	}
++	sio_out(port, TXX9_SITFIFO, c);
++	wait_for_xmitr(port);
++	return;
++}
++
++
+diff -urpNX dontdiff linux-2.6.10/drivers/char/serial_txx927.c linux-2.6.10-mips/drivers/char/serial_txx927.c
+--- linux-2.6.10/drivers/char/serial_txx927.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/char/serial_txx927.c	2002-10-28 05:39:20.000000000 +0100
+@@ -0,0 +1,2331 @@
++/*
++ *  drivers/char/serial_txx927.c
++ *  driver for TX[34]927 SIO
++ *
++ * Copyright 2001 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc. 
++ *                ahennessy at mvista.com
++ *
++ * Based on drivers/char/serial.c
++ *
++ * Copyright (C) 2000-2001 Toshiba Corporation
++ *
++ * 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
++ * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
++ * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * 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.
++ */
++
++#define SERIAL_DO_RESTART
++
++/* Set of debugging defines */
++
++#undef SERIAL_DEBUG_INTR
++#undef SERIAL_DEBUG_OPEN
++#undef SERIAL_DEBUG_FLOW
++#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
++#undef SERIAL_DEBUG_PCI
++#undef SERIAL_DEBUG_AUTOCONF   
++
++#ifdef MODULE
++#undef CONFIG_TXX927_SERIAL_CONSOLE
++#endif                               
++
++#define CONFIG_SERIAL_RSA
++
++#define RS_STROBE_TIME (10*HZ)
++#define RS_ISR_PASS_LIMIT 256     
++
++/*
++ * End of serial driver configuration section.
++ */
++
++#ifdef MODVERSIONS
++#include <linux/modversions.h>
++#endif
++#include <linux/module.h>    
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/signal.h>
++#include <linux/sched.h>
++#include <linux/timer.h>
++#include <linux/interrupt.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial.h>
++#include <linux/circ_buf.h>
++#include <linux/serial_reg.h>
++#include <linux/major.h>
++#include <linux/string.h>
++#include <linux/fcntl.h>
++#include <linux/ptrace.h>
++#include <linux/ioport.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/serialP.h>
++#include <linux/delay.h>
++#ifdef CONFIG_TXX927_SERIAL_CONSOLE
++#include <linux/console.h>
++#endif
++#ifdef CONFIG_MAGIC_SYSRQ
++#include <linux/sysrq.h>
++#endif            
++
++#include <asm/system.h>
++#include <asm/serial.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/uaccess.h>
++#include <asm/bitops.h>
++#include <asm/jmr3927/txx927.h>
++#include <asm/bootinfo.h>
++#ifdef CONFIG_TOSHIBA_JMR3927
++#include <asm/jmr3927/jmr3927.h>
++#endif
++
++#define _INLINE_ inline
++
++#ifdef CONFIG_MAC_SERIAL
++#define SERIAL_DEV_OFFSET	2
++#else
++#define SERIAL_DEV_OFFSET	0
++#endif
++	
++static char *serial_name = "TXx927 Serial driver";
++static char *serial_version = "0.02";
++
++static DECLARE_TASK_QUEUE(tq_serial);
++
++static struct tty_driver serial_driver, callout_driver;
++static int serial_refcount;
++
++static struct timer_list serial_timer;
++
++extern unsigned long get_txx927_uart_baud(void);
++
++/* serial subtype definitions */
++#ifndef SERIAL_TYPE_NORMAL
++#define SERIAL_TYPE_NORMAL      1
++#define SERIAL_TYPE_CALLOUT     2
++#endif                          
++
++/* number of characters left in xmit buffer before we ask for more */
++#define WAKEUP_CHARS 256
++
++/*
++ * IRQ_timeout		- How long the timeout should be for each IRQ
++ * 				should be after the IRQ has been active.
++ */
++
++static struct async_struct *IRQ_ports[NR_IRQS];
++static int IRQ_timeout[NR_IRQS];
++#ifdef CONFIG_TXX927_SERIAL_CONSOLE
++static struct console sercons;
++#endif
++#if defined(CONFIG_TXX927_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
++static unsigned long break_pressed; /* break, really ... */
++#endif                                                        
++
++static void change_speed(struct async_struct *info, struct termios *old);
++static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
++
++#ifndef PREPARE_FUNC
++#define PREPARE_FUNC(dev)  (dev->prepare)
++#define ACTIVATE_FUNC(dev)  (dev->activate)
++#define DEACTIVATE_FUNC(dev)  (dev->deactivate)
++#endif
++
++#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
++
++
++#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
++#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
++ kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s)
++#else
++#define DBG_CNT(s)
++#endif                                     
++	
++#define SERIAL_DRIVER_NAME "TXx927SIO"
++
++#ifdef CONFIG_SERIAL
++/* "ttyS","cua" is used for standard serial driver */
++#define TXX927_TTY_NAME "ttySC"
++#define TXX927_TTY_MINOR_START	(64 + 16)	/* ttySC0(80), ttySC1(81) */
++#define TXX927_CU_NAME "cuac"
++#define TXX927_SERIAL_BH	TXX927SERIAL_BH
++#else
++/* acts like standard serial driver */
++#define TXX927_TTY_NAME "ttyS"
++#define TXX927_TTY_MINOR_START	64
++#define TXX927_CU_NAME "cua"
++#define TXX927_SERIAL_BH	SERIAL_BH
++#endif
++#define TXX927_TTY_MAJOR	TTY_MAJOR
++#define TXX927_TTYAUX_MAJOR	TTYAUX_MAJOR
++
++#define ASYNC_HAVE_CTS_LINE		ASYNC_BOOT_AUTOCONF	/* reuse */
++
++static struct serial_state rs_table[RS_TABLE_SIZE] = {
++	SERIAL_PORT_DFNS	/* Defined in serial.h */
++};
++
++#define NR_PORTS	(sizeof(rs_table)/sizeof(struct serial_state))
++
++static struct tty_struct *serial_table[NR_PORTS];
++static struct termios *serial_termios[NR_PORTS];
++static struct termios *serial_termios_locked[NR_PORTS];
++
++#ifndef MIN
++#define MIN(a,b)	((a) < (b) ? (a) : (b))
++#endif
++
++/*
++ * tmp_buf is used as a temporary buffer by serial_write.  We need to
++ * lock it in case the copy_from_user blocks while swapping in a page,
++ * and some other program tries to do a serial write at the same time.
++ * Since the lock will only come under contention when the system is
++ * swapping and available memory is low, it makes sense to share one
++ * buffer across all the serial ports, since it significantly saves
++ * memory if large numbers of serial ports are open.
++ */
++static unsigned char *tmp_buf;
++#ifdef DECLARE_MUTEX
++static DECLARE_MUTEX(tmp_buf_sem);
++#else
++static struct semaphore tmp_buf_sem = MUTEX;
++#endif                                 
++
++static inline int serial_paranoia_check(struct async_struct *info,
++					kdev_t device, const char *routine)
++{
++#ifdef SERIAL_PARANOIA_CHECK
++	static const char *badmagic =
++		"Warning: bad magic number for serial struct (%s) in %s\n";
++	static const char *badinfo =
++		"Warning: null async_struct for (%s) in %s\n";
++
++	if (!info) {
++		printk(badinfo, kdevname(device), routine);
++		return 1;
++	}
++	if (info->magic != SERIAL_MAGIC) {
++		printk(badmagic, kdevname(device), routine);
++		return 1;
++	}
++#endif
++	return 0;
++}
++
++static inline struct txx927_sio_reg *sio_reg(struct async_struct *info)
++{
++	return (struct txx927_sio_reg *)info->port;
++}
++
++/*
++ *	Wait for transmitter & holding register to empty
++ */
++static inline void wait_for_xmitr(struct async_struct *info)
++{
++	unsigned int tmout = 1000000;
++
++	do {
++		if (--tmout == 0) break;
++	} while (!(sio_reg(info)->cisr & TXx927_SICISR_TXALS));
++}
++
++/*
++ * ------------------------------------------------------------
++ * rs_stop() and rs_start()
++ *
++ * This routines are called before setting or resetting tty->stopped.
++ * They enable or disable transmitter interrupts, as necessary.
++ * ------------------------------------------------------------
++ */
++static void rs_stop(struct tty_struct *tty)
++{
++	struct async_struct *info = (struct async_struct *)tty->driver_data;
++	unsigned long flags;
++
++	if (serial_paranoia_check(info, tty->device, "rs_stop"))
++		return;
++	
++	save_flags(flags); cli();
++	if (info->IER & UART_IER_THRI) {
++		info->IER &= ~UART_IER_THRI;
++	        sio_reg(info)->dicr &= ~TXx927_SIDICR_TIE;
++	}
++	restore_flags(flags);
++}
++
++static void rs_start(struct tty_struct *tty)
++{
++	struct async_struct *info = (struct async_struct *)tty->driver_data;
++	unsigned long flags;
++	
++	if (serial_paranoia_check(info, tty->device, "rs_start"))
++		return;
++	
++	save_flags(flags); cli();
++	if (info->xmit.head != info->xmit.tail
++	    && info->xmit.buf
++	    && !(info->IER & UART_IER_THRI)) {
++		info->IER |= UART_IER_THRI;
++	        sio_reg(info)->dicr |= TXx927_SIDICR_TIE;
++	}
++	restore_flags(flags);
++}
++
++/*
++ * ----------------------------------------------------------------------
++ *
++ * Here starts the interrupt handling routines.  All of the following
++ * subroutines are declared as inline and are folded into
++ * rs_interrupt().  They were separated out for readability's sake.
++ *
++ * Note: rs_interrupt() is a "fast" interrupt, which means that it
++ * runs with interrupts turned off.  People who may want to modify
++ * rs_interrupt() should try to keep the interrupt handler as fast as
++ * possible.  After you are done making modifications, it is not a bad
++ * idea to do:
++ * 
++ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
++ *
++ * and look at the resulting assemble code in serial.s.
++ *
++ * 				- Ted Ts'o (tytso at mit.edu), 7-Mar-93
++ * -----------------------------------------------------------------------
++ */
++
++/*
++ * This routine is used by the interrupt handler to schedule
++ * processing in the software interrupt portion of the driver.
++ */
++static _INLINE_ void rs_sched_event(struct async_struct *info,
++				  int event)
++{
++	info->event |= 1 << event;
++	queue_task(&info->tqueue, &tq_serial);
++	mark_bh(TXX927_SERIAL_BH);
++}
++
++static _INLINE_ void receive_chars(struct async_struct *info,
++				 int *status)
++{
++	struct tty_struct *tty = info->tty;
++	unsigned char ch;
++	int ignored = 0;
++	struct	async_icount *icount;
++
++	icount = &info->state->icount;
++	do {
++		ch = sio_reg(info)->rfifo;
++		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
++			break;
++		*tty->flip.char_buf_ptr = ch;
++		icount->rx++;
++		
++#ifdef SERIAL_DEBUG_INTR
++		printk("DR%02x:%02x...", ch, *status);
++#endif
++		*tty->flip.flag_buf_ptr = 0;
++		if (*status & (TXx927_SIDISR_UBRK | TXx927_SIDISR_UPER |
++			       TXx927_SIDISR_UFER | TXx927_SIDISR_UOER)) {
++			/*
++			 * For statistics only
++			 */
++			if (*status & TXx927_SIDISR_UBRK) {
++				*status &= ~(TXx927_SIDISR_UFER | TXx927_SIDISR_UPER);
++				icount->brk++;
++			} else if (*status & TXx927_SIDISR_UPER)
++				icount->parity++;
++			else if (*status & TXx927_SIDISR_UFER)
++				icount->frame++;
++			if (*status & TXx927_SIDISR_UOER)
++				icount->overrun++;
++
++			/*
++			 * Now check to see if character should be
++			 * ignored, and mask off conditions which
++			 * should be ignored.
++			 */
++			if (*status & info->ignore_status_mask) {
++				if (++ignored > 100)
++					break;
++				goto ignore_char;
++			}
++			*status &= info->read_status_mask;
++		
++			if (*status & (TXx927_SIDISR_UBRK)) {
++#ifdef SERIAL_DEBUG_INTR
++				printk("handling break....");
++#endif
++				*tty->flip.flag_buf_ptr = TTY_BREAK;
++				if (info->flags & ASYNC_SAK)
++					do_SAK(tty);
++			} else if (*status & TXx927_SIDISR_UPER)
++				*tty->flip.flag_buf_ptr = TTY_PARITY;
++			else if (*status & TXx927_SIDISR_UFER)
++				*tty->flip.flag_buf_ptr = TTY_FRAME;
++			if (*status & TXx927_SIDISR_UOER) {
++				/*
++				 * Overrun is special, since it's
++				 * reported immediately, and doesn't
++				 * affect the current character
++				 */
++				if (tty->flip.count < TTY_FLIPBUF_SIZE) {
++					tty->flip.count++;
++					tty->flip.flag_buf_ptr++;
++					tty->flip.char_buf_ptr++;
++					*tty->flip.flag_buf_ptr = TTY_OVERRUN;
++				}
++			}
++		}
++		tty->flip.flag_buf_ptr++;
++		tty->flip.char_buf_ptr++;
++		tty->flip.count++;
++	ignore_char:
++		*status = sio_reg(info)->disr;
++	} while (!(*status & TXx927_SIDISR_UVALID));
++
++	tty_flip_buffer_push(tty);
++}
++
++static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
++{
++	int count;
++	
++	wait_for_xmitr(info);
++
++	if (info->x_char) {
++		sio_reg(info)->tfifo = info->x_char;
++		info->state->icount.tx++;
++		info->x_char = 0;
++		if (intr_done)
++			*intr_done = 0;
++		return;
++	}
++	 
++	if (info->xmit.head == info->xmit.tail
++	    || info->tty->stopped
++	    || info->tty->hw_stopped) {
++		sio_reg(info)->dicr &= ~TXx927_SIDICR_TIE;
++		return;
++	}
++	
++	count = info->xmit_fifo_size;
++	do {
++		sio_reg(info)->tfifo = info->xmit.buf[info->xmit.tail++];
++		info->xmit.tail = info->xmit.tail & (SERIAL_XMIT_SIZE-1);
++		info->state->icount.tx++;
++		if (info->xmit.head == info->xmit.tail)
++			break;
++	} while (--count > 0);
++	
++	if (CIRC_CNT(info->xmit.head,
++		     info->xmit.tail,
++		     SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
++		rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
++
++#ifdef SERIAL_DEBUG_INTR
++	printk("THRE...");
++#endif
++	if (intr_done)
++		*intr_done = 0;
++
++	if (info->xmit.head == info->xmit.tail) {
++		sio_reg(info)->dicr &= ~TXx927_SIDICR_TIE;
++	}
++}
++
++static _INLINE_ void check_modem_status(struct async_struct *info)
++{
++	/* RTS/CTS are controled by HW. (if possible) */
++}
++
++/*
++ * This is the serial driver's interrupt routine for a single port
++ */
++static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
++{
++	int status;
++	int pass_counter = 0;
++	struct async_struct * info;
++	
++#ifdef SERIAL_DEBUG_INTR
++	printk("rs_interrupt_single(%d)...", irq);
++#endif
++
++	info = IRQ_ports[irq];
++	if (!info || !info->tty)
++		return;
++
++	do {
++		status = sio_reg(info)->disr;
++#ifdef SERIAL_DEBUG_INTR
++		printk("status = %x...", status);
++#endif
++		if (!(sio_reg(info)->dicr & TXx927_SIDICR_TIE))
++			status &= ~TXx927_SIDISR_TDIS;
++		if (!(status & (TXx927_SIDISR_TDIS | TXx927_SIDISR_RDIS | TXx927_SIDISR_TOUT)))
++			break;
++
++		if (status & TXx927_SIDISR_RDIS)
++			receive_chars(info, &status);
++		check_modem_status(info);
++		if (status & TXx927_SIDISR_TDIS)
++			transmit_chars(info, 0);
++		/* Clear TX/RX Int. Status */
++		sio_reg(info)->disr &= ~(TXx927_SIDISR_TDIS | TXx927_SIDISR_RDIS | TXx927_SIDISR_TOUT);
++
++		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
++#ifdef SERIAL_DEBUG_INTR
++			printk("rs_single loop break.\n");
++#endif
++			break;
++		}
++	} while (1);
++	info->last_active = jiffies;
++#ifdef SERIAL_DEBUG_INTR
++	printk("end.\n");
++#endif
++}
++
++/*
++ * -------------------------------------------------------------------
++ * Here ends the serial interrupt routines.
++ * -------------------------------------------------------------------
++ */
++
++/*
++ * This routine is used to handle the "bottom half" processing for the
++ * serial driver, known also the "software interrupt" processing.
++ * This processing is done at the kernel interrupt level, after the
++ * rs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
++ * is where time-consuming activities which can not be done in the
++ * interrupt driver proper are done; the interrupt driver schedules
++ * them using rs_sched_event(), and they get done here.
++ */
++static void do_serial_bh(void)
++{
++	run_task_queue(&tq_serial);
++}
++
++static void do_softint(void *private_)
++{
++	struct async_struct	*info = (struct async_struct *) private_;
++	struct tty_struct	*tty;
++	
++	tty = info->tty;
++	if (!tty)
++		return;
++
++	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
++		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
++		    tty->ldisc.write_wakeup)
++			(tty->ldisc.write_wakeup)(tty);
++		wake_up_interruptible(&tty->write_wait);
++#ifdef SERIAL_HAVE_POLL_WAIT
++		wake_up_interruptible(&tty->poll_wait);
++#endif                                                    
++	}
++}
++
++/*
++ * This subroutine is called when the RS_TIMER goes off.  It is used
++ * by the serial driver to handle ports that do not have an interrupt
++ * (irq=0).  This doesn't work very well for 16450's, but gives barely
++ * passable results for a 16550A.  (Although at the expense of much
++ * CPU overhead).
++ */
++static void rs_timer(unsigned long dummy)
++{
++	static unsigned long last_strobe;
++	struct async_struct *info;
++	unsigned int	i;
++	unsigned long flags;
++
++	if ((jiffies - last_strobe) >= RS_STROBE_TIME) {
++		for (i=0; i < NR_IRQS; i++) {
++			info = IRQ_ports[i];
++			if (!info)
++				continue;
++			save_flags(flags); cli();
++				rs_interrupt_single(i, NULL, NULL);
++			restore_flags(flags);
++		}
++	}
++	last_strobe = jiffies;
++	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
++
++#if 0
++	if (IRQ_ports[0]) {
++		save_flags(flags); cli();
++		rs_interrupt_single(0, NULL, NULL);
++		restore_flags(flags);
++
++		mod_timer(&serial_timer, jiffies + IRQ_timeout[0]);
++	}
++#endif
++}
++
++/*
++ * ---------------------------------------------------------------
++ * Low level utility subroutines for the serial driver:  routines to
++ * figure out the appropriate timeout for an interrupt chain, routines
++ * to initialize and startup a serial port, and routines to shutdown a
++ * serial port.  Useful stuff like that.
++ * ---------------------------------------------------------------
++ */
++
++/*
++ * This routine figures out the correct timeout for a particular IRQ.
++ * It uses the smallest timeout of all of the serial ports in a
++ * particular interrupt chain.  Now only used for IRQ 0....
++ */
++static void figure_IRQ_timeout(int irq)
++{
++	struct	async_struct	*info;
++	int	timeout = 60*HZ;	/* 60 seconds === a long time :-) */
++
++	info = IRQ_ports[irq];
++	if (!info) {
++		IRQ_timeout[irq] = 60*HZ;
++		return;
++	}
++	while (info) {
++		if (info->timeout < timeout)
++			timeout = info->timeout;
++		info = info->next_port;
++	}
++	if (!irq)
++		timeout = timeout / 2;
++	IRQ_timeout[irq] = timeout ? timeout : 1;
++}
++
++static int startup(struct async_struct * info)
++{
++	unsigned long flags;
++	int	retval=0;
++	struct serial_state *state= info->state;
++	unsigned long page;
++
++	page = get_zeroed_page(GFP_KERNEL);
++	if (!page)
++		return -ENOMEM;
++
++	save_flags(flags); cli();
++
++	if (info->flags & ASYNC_INITIALIZED) {
++		free_page(page);
++		goto errout;
++	}
++
++	if (!state->port) {
++		if (info->tty)
++			set_bit(TTY_IO_ERROR, &info->tty->flags);
++		free_page(page);
++		goto errout;
++	}
++	if (info->xmit.buf)
++		free_page(page);
++	else
++		info->xmit.buf = (unsigned char *) page;
++
++#ifdef SERIAL_DEBUG_OPEN
++	printk("starting up ttys%d (irq %d)...", info->line, state->irq);
++#endif
++
++	/*
++	 * Clear the FIFO buffers and disable them
++	 * (they will be reenabled in change_speed())
++	 */
++	sio_reg(info)->fcr |= TXx927_SIFCR_TFRST | TXx927_SIFCR_RFRST |
++		TXx927_SIFCR_FRSTE;
++	/* clear reset */
++	sio_reg(info)->fcr &= ~(TXx927_SIFCR_TFRST | TXx927_SIFCR_RFRST |
++				TXx927_SIFCR_FRSTE);
++
++	/*
++	 * Allocate the IRQ if necessary
++	 */
++	if (state->irq && (!IRQ_ports[state->irq] ||
++			  !IRQ_ports[state->irq]->next_port)) {
++		if (IRQ_ports[state->irq]) {
++			retval = -EBUSY;
++			goto errout;
++		}
++
++		retval = request_irq(state->irq, rs_interrupt_single,
++				     SA_INTERRUPT,
++				     "txx927serial", NULL);
++		if (retval) {
++			if (capable(CAP_SYS_ADMIN)) {
++				if (info->tty)
++					set_bit(TTY_IO_ERROR,
++						&info->tty->flags);
++				retval = 0;
++			}
++			goto errout;
++		}
++	}
++
++	/*
++	 * Insert serial port into IRQ chain.
++	 */
++	info->prev_port = 0;
++	info->next_port = IRQ_ports[state->irq];
++	if (info->next_port)
++		info->next_port->prev_port = info;
++	IRQ_ports[state->irq] = info;
++	figure_IRQ_timeout(state->irq);
++
++	/*
++	 * Clear the interrupt registers.
++	 */
++	sio_reg(info)->disr = 0;
++
++	/*
++	 * Now, initialize the UART 
++	 */
++	/* HW RTS/CTS control */
++	if (state->flags & ASYNC_HAVE_CTS_LINE)
++		sio_reg(info)->flcr = TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES |
++			TXx927_SIFLCR_RTSTL_MAX /* 15 */;
++	/* Enable RX/TX */
++	sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RSDE | TXx927_SIFLCR_TSDE);
++	
++	/*
++	 * Finally, enable interrupts
++	 */
++	sio_reg(info)->dicr = TXx927_SIDICR_RIE;
++
++	if (info->tty)
++		clear_bit(TTY_IO_ERROR, &info->tty->flags);
++	info->xmit.head = info->xmit.tail = 0;
++
++	/*
++	 * Set up the tty->alt_speed kludge
++	 */
++	if (info->tty) {
++		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
++			info->tty->alt_speed = 57600;
++		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
++			info->tty->alt_speed = 115200;
++		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
++			info->tty->alt_speed = 230400;
++		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
++			info->tty->alt_speed = 460800;
++	}
++	
++	/*
++	 * and set the speed of the serial port
++	 */
++	change_speed(info, 0);
++
++	info->flags |= ASYNC_INITIALIZED;
++	restore_flags(flags);
++	return 0;
++	
++errout:
++	restore_flags(flags);
++	return retval;
++}
++
++/*
++ * This routine will shutdown a serial port; interrupts are disabled, and
++ * DTR is dropped if the hangup on close termio flag is on.
++ */
++static void shutdown(struct async_struct * info)
++{
++	unsigned long	flags;
++	struct serial_state *state;
++	int		retval;
++
++	if (!(info->flags & ASYNC_INITIALIZED))
++		return;
++
++	state = info->state;
++
++#ifdef SERIAL_DEBUG_OPEN
++	printk("Shutting down serial port %d (irq %d)....", info->line,
++	       state->irq);
++#endif
++	
++	save_flags(flags); cli(); /* Disable interrupts */
++
++	/*
++	 * First unlink the serial port from the IRQ chain...
++	 */
++	if (info->next_port)
++		info->next_port->prev_port = info->prev_port;
++	if (info->prev_port)
++		info->prev_port->next_port = info->next_port;
++	else
++		IRQ_ports[state->irq] = info->next_port;
++	figure_IRQ_timeout(state->irq);
++	
++	/*
++	 * Free the IRQ, if necessary
++	 */
++	if (state->irq && (!IRQ_ports[state->irq] ||
++			  !IRQ_ports[state->irq]->next_port)) {
++		if (IRQ_ports[state->irq]) {
++			free_irq(state->irq, NULL);
++			retval = request_irq(state->irq, rs_interrupt_single,
++					     SA_INTERRUPT, "txx927serial", NULL);
++			
++			if (retval)
++				printk(KERN_WARNING "txx927serial shutdown: request_irq: error %d"
++				       "  Couldn't reacquire IRQ.\n", retval);
++		} else
++			free_irq(state->irq, NULL);
++	}
++
++	if (info->xmit.buf) {
++		free_page((unsigned long) info->xmit.buf);
++		info->xmit.buf = 0;
++	}
++
++	sio_reg(info)->dicr = 0;	/* disable all intrs */
++	
++	/* disable break condition */
++	sio_reg(info)->flcr &= ~TXx927_SIFLCR_TBRK;
++
++	if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
++		/* drop RTS */
++		sio_reg(info)->flcr |= TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE;
++		/* TXx927-SIO can not control DTR... */
++	}
++
++	/* reset FIFO's */	
++	sio_reg(info)->fcr |= TXx927_SIFCR_TFRST | TXx927_SIFCR_RFRST |
++		TXx927_SIFCR_FRSTE;
++	/* clear reset */
++	sio_reg(info)->fcr &= ~(TXx927_SIFCR_TFRST | TXx927_SIFCR_RFRST |
++				TXx927_SIFCR_FRSTE);
++
++	/* DON'T disable Rx/Tx here, ie. DON'T set either
++	 * TXx927_SIFLCR_RSDE or TXx927_SIFLCR_TSDE in flcr
++	 */
++
++	if (info->tty)
++		set_bit(TTY_IO_ERROR, &info->tty->flags);
++
++	info->flags &= ~ASYNC_INITIALIZED;
++	restore_flags(flags);
++}
++
++/*
++ * This routine is called to set the UART divisor registers to match
++ * the specified baud rate for a serial port.
++ */
++static void change_speed(struct async_struct *info,
++			 struct termios *old_termios)
++{
++	int	quot = 0, baud_base, baud;
++	unsigned cflag, cval;
++	int	bits;
++	unsigned long	flags;
++
++	if (!info->tty || !info->tty->termios)
++		return;
++	cflag = info->tty->termios->c_cflag;
++	if (!info->port)
++		return;
++
++	cval = sio_reg(info)->lcr;
++	/* byte size and parity */
++	cval &= ~TXx927_SILCR_UMODE_MASK;
++	switch (cflag & CSIZE) {
++	case CS7:
++		cval |= TXx927_SILCR_UMODE_7BIT;
++		bits = 9;
++		break;
++	case CS5:	/* not supported */
++	case CS6:	/* not supported */
++	case CS8:
++	default:
++		cval |= TXx927_SILCR_UMODE_8BIT;
++		bits = 10;
++		break;
++	}
++	cval &= ~TXx927_SILCR_USBL_MASK;
++	if (cflag & CSTOPB) {
++		cval |= TXx927_SILCR_USBL_2BIT;
++		bits++;
++	} else {
++		cval |= TXx927_SILCR_USBL_1BIT;
++	}
++
++	cval &= ~(TXx927_SILCR_UPEN|TXx927_SILCR_UEPS);
++	if (cflag & PARENB) {
++		cval |= TXx927_SILCR_UPEN;
++		bits++;
++	}
++	if (!(cflag & PARODD))
++		cval |= TXx927_SILCR_UEPS;
++
++	/* Determine divisor based on baud rate */
++	baud = tty_get_baud_rate(info->tty);
++	if (!baud)
++		baud = 9600;	/* B0 transition handled in rs_set_termios */
++	baud_base = info->state->baud_base;
++	quot = (baud_base + baud / 2) / baud;
++	/* If the quotient is zero refuse the change */
++	if (!quot && old_termios) {
++		info->tty->termios->c_cflag &= ~CBAUD;
++		info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
++		baud = tty_get_baud_rate(info->tty);
++		if (!baud)
++			baud = 9600;
++		quot = (baud_base + baud / 2) / baud;
++	}
++	/* As a last resort, if the quotient is zero, default to 9600 bps */
++	if (!quot)
++		quot = (baud_base + 9600 / 2) / 9600;
++	info->quot = quot;
++	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
++	info->timeout += HZ/50;		/* Add .02 seconds of slop */
++
++	/* CTS flow control flag */
++	if (cflag & CRTSCTS) {
++		info->flags |= ASYNC_CTS_FLOW;
++		if (info->state->flags & ASYNC_HAVE_CTS_LINE)
++			sio_reg(info)->flcr = TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES |
++				TXx927_SIFLCR_RTSTL_MAX /* 15 */;
++	} else {
++		info->flags &= ~ASYNC_CTS_FLOW;
++		sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES | TXx927_SIFLCR_RSDE | TXx927_SIFLCR_TSDE);
++	}
++
++	/*
++	 * Set up parity check flag
++	 */
++#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
++
++	info->read_status_mask = TXx927_SIDISR_UOER |
++		TXx927_SIDISR_TDIS | TXx927_SIDISR_RDIS;
++	if (I_INPCK(info->tty))
++		info->read_status_mask |= TXx927_SIDISR_UFER | TXx927_SIDISR_UPER;
++	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
++		info->read_status_mask |= TXx927_SIDISR_UBRK;
++	
++	/*
++	 * Characters to ignore
++	 */
++	info->ignore_status_mask = 0;
++	if (I_IGNPAR(info->tty))
++		info->ignore_status_mask |= TXx927_SIDISR_UPER | TXx927_SIDISR_UFER;
++	if (I_IGNBRK(info->tty)) {
++		info->ignore_status_mask |= TXx927_SIDISR_UBRK;
++		/*
++		 * If we're ignore parity and break indicators, ignore 
++		 * overruns too.  (For real raw support).
++		 */
++		if (I_IGNPAR(info->tty))
++			info->ignore_status_mask |= TXx927_SIDISR_UOER;
++	}
++	/*
++	 * !!! ignore all characters if CREAD is not set
++	 */
++	if ((cflag & CREAD) == 0)
++		info->ignore_status_mask |= TXx927_SIDISR_RDIS;
++	save_flags(flags); cli();
++	sio_reg(info)->lcr = cval | TXx927_SILCR_SCS_IMCLK_BG;
++	sio_reg(info)->bgr = quot | TXx927_SIBGR_BCLK_T0;
++	restore_flags(flags);
++}
++
++static void rs_put_char(struct tty_struct *tty, unsigned char ch)
++{
++	struct async_struct *info = (struct async_struct *)tty->driver_data;
++	unsigned long flags;
++
++	if (serial_paranoia_check(info, tty->device, "rs_put_char"))
++		return;                                          
++
++	if (!tty || !info->xmit.buf)
++		return;
++
++	save_flags(flags); cli();
++	if (CIRC_SPACE(info->xmit.head,
++		       info->xmit.tail,
++		       SERIAL_XMIT_SIZE) == 0) {
++		restore_flags(flags);
++		return;
++	}
++
++	info->xmit.buf[info->xmit.head++] = ch;
++	info->xmit.head &= SERIAL_XMIT_SIZE-1;
++	restore_flags(flags);
++}
++
++static void rs_flush_chars(struct tty_struct *tty)
++{
++	struct async_struct *info = (struct async_struct *)tty->driver_data;
++	unsigned long flags;
++
++	if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
++		return;                                                  
++	
++	if (info->xmit.head == info->xmit.tail
++	    || tty->stopped
++	    || tty->hw_stopped
++	    || !info->xmit.buf)
++		return;
++
++	save_flags(flags); cli();
++	sio_reg(info)->dicr |= TXx927_SIDICR_TIE;
++	restore_flags(flags);
++}
++
++static int rs_write(struct tty_struct * tty, int from_user,
++		    const unsigned char *buf, int count)
++{
++	int	c, ret = 0;
++	struct async_struct *info = (struct async_struct *)tty->driver_data;
++	unsigned long flags;
++				
++	if (serial_paranoia_check(info, tty->device, "rs_write"))
++		return 0;
++
++	if (!tty || !info->xmit.buf || !tmp_buf)
++		return 0;
++
++	save_flags(flags);
++
++	if (from_user) {
++		down(&tmp_buf_sem);
++		while (1) {
++			int c1;
++			c = CIRC_SPACE_TO_END(info->xmit.head,
++					      info->xmit.tail,
++					      SERIAL_XMIT_SIZE);
++
++			if (count < c)
++				c = count;
++			if (c <= 0)
++				break;
++
++			c -= copy_from_user(tmp_buf, buf, c);
++			if (!c) {
++				if (!ret)
++					ret = -EFAULT;
++				break;
++			}
++			cli();
++			c1 = CIRC_SPACE_TO_END(info->xmit.head,
++					       info->xmit.tail,
++					       SERIAL_XMIT_SIZE);
++
++			if (c1 < c)
++				c = c1;
++			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
++			info->xmit.head = ((info->xmit.head + c) &
++					   (SERIAL_XMIT_SIZE-1));
++			restore_flags(flags);
++			buf += c;
++			count -= c;
++			ret += c;
++		}
++		up(&tmp_buf_sem);
++	} else {
++		cli();
++		while (1) {
++			c = CIRC_SPACE_TO_END(info->xmit.head,
++					      info->xmit.tail,
++					      SERIAL_XMIT_SIZE);
++
++			if (count < c)
++				c = count;
++			if (c <= 0) {
++				break;
++			}
++			memcpy(info->xmit.buf + info->xmit.head, buf, c);
++			info->xmit.head = ((info->xmit.head + c) &
++					   (SERIAL_XMIT_SIZE-1));
++			buf += c;
++			count -= c;
++			ret += c;
++		}
++		restore_flags(flags);
++	}
++	if (info->xmit.head != info->xmit.tail
++	    && !tty->stopped
++	    && !tty->hw_stopped
++	    && !(info->IER & UART_IER_THRI)) 
++		sio_reg(info)->dicr |= TXx927_SIDICR_TIE;
++
++	return ret;
++}
++
++static int rs_write_room(struct tty_struct *tty)
++{
++	struct async_struct *info = (struct async_struct *)tty->driver_data;
++				
++	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
++	        return 0;                                           
++
++	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
++}
++
++static int rs_chars_in_buffer(struct tty_struct *tty)
++{
++	struct async_struct *info = (struct async_struct *)tty->driver_data;
++				
++	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
++		return 0;                                                     
++
++	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
++}
++
++static void rs_flush_buffer(struct tty_struct *tty)
++{
++	struct async_struct *info = (struct async_struct *)tty->driver_data;
++	unsigned long flags;
++	
++	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
++		return;
++	save_flags(flags); cli();
++	info->xmit.head = info->xmit.tail = 0;
++	restore_flags(flags);
++	wake_up_interruptible(&tty->write_wait);
++#ifdef SERIAL_HAVE_POLL_WAIT
++	wake_up_interruptible(&tty->poll_wait);
++#endif
++	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
++	    tty->ldisc.write_wakeup)
++		(tty->ldisc.write_wakeup)(tty);
++}
++
++/*
++ * This function is used to send a high-priority XON/XOFF character to
++ * the device
++ */
++static void rs_send_xchar(struct tty_struct *tty, char ch)
++{
++	struct async_struct *info = (struct async_struct *)tty->driver_data;
++
++
++	if (serial_paranoia_check(info, tty->device, "rs_send_char"))
++		return;                                        
++
++	info->x_char = ch;
++	if (ch) {
++		/* Make sure transmit interrupts are on */
++		sio_reg(info)->dicr |= TXx927_SIDICR_TIE;
++	}
++}
++
++/*
++ * ------------------------------------------------------------
++ * rs_throttle()
++ * 
++ * This routine is called by the upper-layer tty layer to signal that
++ * incoming characters should be throttled.
++ * ------------------------------------------------------------
++ */
++static void rs_throttle(struct tty_struct * tty)
++{
++	struct async_struct *info = (struct async_struct *)tty->driver_data;
++	unsigned long flags;
++#ifdef SERIAL_DEBUG_THROTTLE
++	char	buf[64];
++	
++	printk("throttle %s: %d....\n", tty_name(tty, buf),
++	       tty->ldisc.chars_in_buffer(tty));
++#endif
++
++	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
++		return;                                              
++
++	if (I_IXOFF(tty))
++		rs_send_xchar(tty, STOP_CHAR(tty));
++
++	if (tty->termios->c_cflag & CRTSCTS) {
++		save_flags(flags); cli();
++		/* drop RTS */
++		sio_reg(info)->flcr |= TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE;
++		restore_flags(flags);
++	}
++}
++
++static void rs_unthrottle(struct tty_struct * tty)
++{
++	struct async_struct *info = (struct async_struct *)tty->driver_data;
++	unsigned long flags;
++#ifdef SERIAL_DEBUG_THROTTLE
++	char	buf[64];
++	
++	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
++	       tty->ldisc.chars_in_buffer(tty));
++#endif
++
++	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
++		return;                                              
++
++	if (I_IXOFF(tty)) {
++		if (info->x_char)
++			info->x_char = 0;
++		else
++			rs_send_xchar(tty, START_CHAR(tty));
++	}
++	if (tty->termios->c_cflag & CRTSCTS) {
++		save_flags(flags); cli();
++		sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE);
++		restore_flags(flags);
++	}
++}
++
++/*
++ * ------------------------------------------------------------
++ * rs_ioctl() and friends
++ * ------------------------------------------------------------
++ */
++
++static int get_modem_info(struct async_struct * info, unsigned int *value)
++{
++	unsigned int result;
++	unsigned long flags;
++
++	save_flags(flags); cli();
++	result =  ((sio_reg(info)->flcr & TXx927_SIFLCR_RTSSC) ? 0 : TIOCM_RTS)
++		| ((sio_reg(info)->cisr & TXx927_SICISR_CTSS) ? 0 : TIOCM_CTS);
++	restore_flags(flags);
++	return put_user(result,value);
++}
++
++static int set_modem_info(struct async_struct * info, unsigned int cmd,
++			  unsigned int *value)
++{
++	int error;
++	unsigned int arg;
++	unsigned long flags;
++
++	error = get_user(arg, value);
++	if (error)
++		return error;
++	save_flags(flags); cli();
++	switch (cmd) {
++	case TIOCMBIS: 
++		if (arg & TIOCM_RTS)
++			sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE);
++		break;
++	case TIOCMBIC:
++		if (arg & TIOCM_RTS)
++			sio_reg(info)->flcr |= TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE;
++		break;
++	case TIOCMSET:
++		sio_reg(info)->flcr =
++			(sio_reg(info)->flcr & ~(TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE)) |
++			((arg & TIOCM_RTS) ? 0 : TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE);
++		break;
++	default:
++		error = -EINVAL;
++	}
++	restore_flags(flags);
++	return error;
++}
++
++/*
++ * rs_break() --- routine which turns the break handling on or off
++ */
++static void rs_break(struct tty_struct *tty, int break_state)
++{
++	struct async_struct * info = (struct async_struct *)tty->driver_data;
++	unsigned long flags;
++
++	if (serial_paranoia_check(info, tty->device, "rs_break"))
++		return;                                             
++	
++	if (!info->port)
++		return;
++	save_flags(flags); cli();
++	if (break_state == -1)
++		sio_reg(info)->flcr |= TXx927_SIFLCR_TBRK;
++	else
++		sio_reg(info)->flcr &= ~TXx927_SIFLCR_TBRK;
++	restore_flags(flags);
++}
++
++static int rs_ioctl(struct tty_struct *tty, struct file * file,
++		    unsigned int cmd, unsigned long arg)
++{
++	struct async_struct * info = (struct async_struct *)tty->driver_data;
++	
++	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
++		return -ENODEV;                                
++
++	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
++	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
++	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
++		if (tty->flags & (1 << TTY_IO_ERROR))
++		    return -EIO;
++	}
++	
++	switch (cmd) {
++		case TIOCMGET:
++			return get_modem_info(info, (unsigned int *) arg);
++		case TIOCMBIS:
++		case TIOCMBIC:
++		case TIOCMSET:
++			return set_modem_info(info, cmd, (unsigned int *) arg);
++			return 0;
++		case TIOCGSERIAL:
++			printk("TIOCGSERIAL\n");
++			return 0;
++		case TIOCSSERIAL:
++			printk("TIOCSSERIAL\n");
++			return 0;
++		case TIOCSERCONFIG:
++			printk("TIOCSERCONFIG\n");
++			return 0;
++
++		case TIOCSERGETLSR: /* Get line status register */
++			printk("TIOCSERGETLSR\n");
++			return 0;
++
++		case TIOCSERGSTRUCT:
++			printk("TIOCSERGSTRUCT\n");
++			return 0;
++
++		/*
++		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
++		 * - mask passed in arg for lines of interest
++ 		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
++		 * Caller should use TIOCGICOUNT to see which one it was
++		 */
++		case TIOCMIWAIT:
++			printk("TIOCMIWAIT\n");
++			return 0;
++
++		/* 
++		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
++		 * Return: write counters to the user passed counter struct
++		 * NB: both 1->0 and 0->1 transitions are counted except for
++		 *     RI where only 0->1 is counted.
++		 */
++		case TIOCGICOUNT:
++			printk("TIOCGICOUNT\n");
++			return 0;
++
++		case TIOCSERGWILD:
++		case TIOCSERSWILD:
++			/* "setserial -W" is called in Debian boot */
++			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
++			return 0;
++
++		default:
++			return -ENOIOCTLCMD;
++		}
++	return 0;
++}
++
++static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
++{
++	struct async_struct *info = (struct async_struct *)tty->driver_data;
++	unsigned long flags;
++	unsigned int cflag = tty->termios->c_cflag;
++	
++	if (   (cflag == old_termios->c_cflag)
++	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
++		== RELEVANT_IFLAG(old_termios->c_iflag)))
++	  return;
++
++	change_speed(info, old_termios);
++
++	/* Handle transition to B0 status */
++	if ((old_termios->c_cflag & CBAUD) &&
++	    !(cflag & CBAUD)) {
++		save_flags(flags); cli();
++		sio_reg(info)->flcr |= TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE;
++		restore_flags(flags);
++	}
++	
++	/* Handle transition away from B0 status */
++	if (!(old_termios->c_cflag & CBAUD) &&
++	    (cflag & CBAUD)) {
++		if (!(tty->termios->c_cflag & CRTSCTS) || 
++		    !test_bit(TTY_THROTTLED, &tty->flags)) {
++			save_flags(flags); cli();
++			sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE);
++			restore_flags(flags);
++		}
++	}
++	
++	/* Handle turning off CRTSCTS */
++	if ((old_termios->c_cflag & CRTSCTS) &&
++	    !(tty->termios->c_cflag & CRTSCTS)) {
++		tty->hw_stopped = 0;
++		rs_start(tty);
++	}
++}
++
++/*
++ * ------------------------------------------------------------
++ * rs_close()
++ * 
++ * This routine is called when the serial port gets closed.  First, we
++ * wait for the last remaining data to be sent.  Then, we unlink its
++ * async structure from the interrupt chain if necessary, and we free
++ * that IRQ if nothing is left in the chain.
++ * ------------------------------------------------------------
++ */
++static void rs_close(struct tty_struct *tty, struct file * filp)
++{
++	struct async_struct * info = (struct async_struct *)tty->driver_data;
++	struct serial_state *state;
++	unsigned long flags;
++
++	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
++		return;
++
++	state = info->state;
++	
++	save_flags(flags); cli();
++	
++	if (tty_hung_up_p(filp)) {
++		restore_flags(flags);
++		return;
++	}
++	
++#ifdef SERIAL_DEBUG_OPEN
++	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
++#endif
++	if ((tty->count == 1) && (state->count != 1)) {
++		/*
++		 * Uh, oh.  tty->count is 1, which means that the tty
++		 * structure will be freed.  state->count should always
++		 * be one in these conditions.  If it's greater than
++		 * one, we've got real problems, since it means the
++		 * serial port won't be shutdown.
++		 */
++		printk(KERN_WARNING "rs_close: bad serial port count; tty->count is 1, "
++		       "state->count is %d\n", state->count);
++		state->count = 1;
++	}
++	if (--state->count < 0) {
++		printk(KERN_WARNING "rs_close: bad serial port count for ttys%d: %d\n",
++		       info->line, state->count);
++		state->count = 0;
++	}
++	if (state->count) {
++		restore_flags(flags);
++		return;
++	}
++	info->flags |= ASYNC_CLOSING;
++	/*
++	 * Save the termios structure, since this port may have
++	 * separate termios for callout and dialin.
++	 */
++	if (info->flags & ASYNC_NORMAL_ACTIVE)
++		info->state->normal_termios = *tty->termios;
++	if (info->flags & ASYNC_CALLOUT_ACTIVE)
++		info->state->callout_termios = *tty->termios;
++	/*
++	 * Now we wait for the transmit buffer to clear; and we notify 
++	 * the line discipline to only process XON/XOFF characters.
++	 */
++	tty->closing = 1;
++	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
++		tty_wait_until_sent(tty, info->closing_wait);
++	/*
++	 * At this point we stop accepting input.  To do this, we
++	 * disable the receive line status interrupts, and tell the
++	 * interrupt driver to stop checking the data ready bit in the
++	 * line status register.
++	 */
++	info->read_status_mask &= ~TXx927_SIDISR_RDIS;
++	if (info->flags & ASYNC_INITIALIZED) {
++#if 0
++		sio_reg(info)->dicr &= ~TXx927_SIDICR_RIE;
++#endif
++		/*
++		 * Before we drop DTR, make sure the UART transmitter
++		 * has completely drained; this is especially
++		 * important if there is a transmit FIFO!
++		 */
++		rs_wait_until_sent(tty, info->timeout);
++	}
++	shutdown(info);
++	if (tty->driver.flush_buffer)
++		tty->driver.flush_buffer(tty);
++	if (tty->ldisc.flush_buffer)
++		tty->ldisc.flush_buffer(tty);
++	tty->closing = 0;
++	info->event = 0;
++	info->tty = 0;
++	if (info->blocked_open) {
++		if (info->close_delay) {
++			current->state = TASK_INTERRUPTIBLE;
++			schedule_timeout(info->close_delay);
++		}
++		wake_up_interruptible(&info->open_wait);
++	}
++	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
++			 ASYNC_CLOSING);
++	wake_up_interruptible(&info->close_wait);
++	restore_flags(flags);
++}
++
++/*
++ * rs_wait_until_sent() --- wait until the transmitter is empty
++ */
++static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
++{
++	struct async_struct * info = (struct async_struct *)tty->driver_data;
++	unsigned long orig_jiffies, char_time;
++	int cisr;
++
++	if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
++		return;                                            
++
++	if (info->xmit_fifo_size == 0)
++		return; /* Just in case.... */
++
++	orig_jiffies = jiffies;
++	/*
++	 * Set the check interval to be 1/5 of the estimated time to
++	 * send a single character, and make it at least 1.  The check
++	 * interval should also be less than the timeout.
++	 * 
++	 * Note: we have to use pretty tight timings here to satisfy
++	 * the NIST-PCTS.
++	 */
++	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
++	char_time = char_time / 5;
++	if (char_time == 0)
++		char_time = 1;
++	if (timeout)
++	  char_time = MIN(char_time, timeout);
++	/*
++	 * If the transmitter hasn't cleared in twice the approximate
++	 * amount of time to send the entire FIFO, it probably won't
++	 * ever clear.  This assumes the UART isn't doing flow
++	 * control, which is currently the case.  Hence, if it ever
++	 * takes longer than info->timeout, this is probably due to a
++	 * UART bug of some kind.  So, we clamp the timeout parameter at
++	 * 2*info->timeout.
++	 */
++	if (!timeout || timeout > 2*info->timeout)
++		timeout = 2*info->timeout;
++#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
++	printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
++	printk("jiff=%lu...", jiffies);
++#endif
++	while (!((cisr = sio_reg(info)->cisr) & TXx927_SICISR_TXALS)) {
++#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
++		printk("cisr = %d (jiff=%lu)...", cisr, jiffies);
++#endif
++		__set_current_state(TASK_INTERRUPTIBLE);
++		schedule_timeout(char_time);
++		if (signal_pending(current))
++			break;
++		if (timeout && time_after(jiffies, orig_jiffies + timeout))
++			break;
++	}
++	current->state = TASK_RUNNING;
++#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
++	printk("cisr = %d (jiff=%lu)...done\n", cisr, jiffies);
++#endif
++}
++
++/*
++ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
++ */
++static void rs_hangup(struct tty_struct *tty)
++{
++	struct async_struct * info = (struct async_struct *)tty->driver_data;
++	struct serial_state *state = info->state;
++	
++	if (serial_paranoia_check(info, tty->device, "rs_hangup"))
++		return;                                           
++
++	state = info->state;
++	
++	rs_flush_buffer(tty);
++	shutdown(info);
++	info->event = 0;
++	state->count = 0;
++	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
++	info->tty = 0;
++	wake_up_interruptible(&info->open_wait);
++}
++
++/*
++ * ------------------------------------------------------------
++ * rs_open() and friends
++ * ------------------------------------------------------------
++ */
++static int block_til_ready(struct tty_struct *tty, struct file * filp,
++			   struct async_struct *info)
++{
++	DECLARE_WAITQUEUE(wait, current);
++	struct serial_state *state = info->state;
++	int		retval;
++	int		do_clocal = 0, extra_count = 0;
++	unsigned long	flags;
++
++	/*
++	 * If the device is in the middle of being closed, then block
++	 * until it's done, and then try again.
++	 */
++	if (tty_hung_up_p(filp) ||
++	    (info->flags & ASYNC_CLOSING)) {
++		if (info->flags & ASYNC_CLOSING)
++			interruptible_sleep_on(&info->close_wait);
++#ifdef SERIAL_DO_RESTART
++		return ((info->flags & ASYNC_HUP_NOTIFY) ?
++			-EAGAIN : -ERESTARTSYS);
++#else
++		return -EAGAIN;
++#endif
++	}
++
++	/*
++	 * If this is a callout device, then just make sure the normal
++	 * device isn't being used.
++	 */
++	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
++		if (info->flags & ASYNC_NORMAL_ACTIVE)
++			return -EBUSY;
++		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
++		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
++		    (info->session != current->session))
++		    return -EBUSY;
++		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
++		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
++		    (info->pgrp != current->pgrp))
++		    return -EBUSY;
++		info->flags |= ASYNC_CALLOUT_ACTIVE;
++		return 0;
++	}
++	
++	/*
++	 * If non-blocking mode is set, or the port is not enabled,
++	 * then make the check up front and then exit.
++	 */
++	if ((filp->f_flags & O_NONBLOCK) ||
++	    (tty->flags & (1 << TTY_IO_ERROR))) {
++		if (info->flags & ASYNC_CALLOUT_ACTIVE)
++			return -EBUSY;
++		info->flags |= ASYNC_NORMAL_ACTIVE;
++		return 0;
++	}
++
++	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
++		if (state->normal_termios.c_cflag & CLOCAL)
++			do_clocal = 1;
++	} else {
++		if (tty->termios->c_cflag & CLOCAL)
++			do_clocal = 1;
++	}
++	
++	/*
++	 * Block waiting for the carrier detect and the line to become
++	 * free (i.e., not in use by the callout).  While we are in
++	 * this loop, state->count is dropped by one, so that
++	 * rs_close() knows when to free things.  We restore it upon
++	 * exit, either normal or abnormal.
++	 */
++	retval = 0;
++	add_wait_queue(&info->open_wait, &wait);
++#ifdef SERIAL_DEBUG_OPEN
++	printk("block_til_ready before block: ttys%d, count = %d\n",
++	       state->line, state->count);
++#endif
++	save_flags(flags); cli();
++	if (!tty_hung_up_p(filp)) {
++		extra_count = 1;
++		state->count--;
++	}
++	restore_flags(flags);
++	info->blocked_open++;
++	while (1) {
++		save_flags(flags); cli();
++		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
++		    (tty->termios->c_cflag & CBAUD))
++			sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RTSSC|TXx927_SIFLCR_RSDE);
++		restore_flags(flags);
++		current->state = TASK_INTERRUPTIBLE;
++		if (tty_hung_up_p(filp) ||
++		    !(info->flags & ASYNC_INITIALIZED)) {
++#ifdef SERIAL_DO_RESTART
++			if (info->flags & ASYNC_HUP_NOTIFY)
++				retval = -EAGAIN;
++			else
++				retval = -ERESTARTSYS;	
++#else
++			retval = -EAGAIN;
++#endif
++			break;
++		}
++		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
++		    !(info->flags & ASYNC_CLOSING))
++			break;
++		if (signal_pending(current)) {
++			retval = -ERESTARTSYS;
++			break;
++		}
++#ifdef SERIAL_DEBUG_OPEN
++		printk("block_til_ready blocking: ttys%d, count = %d\n",
++		       info->line, state->count);
++#endif
++		schedule();
++	}
++	current->state = TASK_RUNNING;
++	remove_wait_queue(&info->open_wait, &wait);
++	if (extra_count)
++		state->count++;
++	info->blocked_open--;
++#ifdef SERIAL_DEBUG_OPEN
++	printk("block_til_ready after blocking: ttys%d, count = %d\n",
++	       info->line, state->count);
++#endif
++	if (retval)
++		return retval;
++	info->flags |= ASYNC_NORMAL_ACTIVE;
++	return 0;
++}
++
++static int get_async_struct(int line, struct async_struct **ret_info)
++{
++	struct async_struct *info;
++	struct serial_state *sstate;
++
++#ifdef REMOTE_DEBUG
++	if (kdb_port_info.state && line == kdb_port_info.line)
++		return -ENODEV;
++#endif
++	sstate = rs_table + line;
++	sstate->count++;
++	if (sstate->info) {
++		*ret_info = sstate->info;
++		return 0;
++	}
++	info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
++	if (!info) {
++		sstate->count--;
++		return -ENOMEM;
++	}
++	memset(info, 0, sizeof(struct async_struct));
++	init_waitqueue_head(&info->open_wait);
++	init_waitqueue_head(&info->close_wait);
++	init_waitqueue_head(&info->delta_msr_wait);
++	info->magic = SERIAL_MAGIC;
++	info->port = sstate->port;
++	info->flags = sstate->flags;
++	info->io_type = sstate->io_type;
++	info->xmit_fifo_size = sstate->xmit_fifo_size;
++	info->line = line;
++	info->tqueue.routine = do_softint;
++	info->tqueue.data = info;
++	info->state = sstate;
++	if (sstate->info) {
++		kfree(info);
++		*ret_info = sstate->info;
++		return 0;
++	}
++	*ret_info = sstate->info = info;
++	return 0;
++}
++
++/*
++ * This routine is called whenever a serial port is opened.  It
++ * enables interrupts for a serial port, linking in its async structure into
++ * the IRQ chain.   It also performs the serial-specific
++ * initialization for the tty structure.
++ */
++static int rs_open(struct tty_struct *tty, struct file * filp)
++{
++	struct async_struct	*info;
++	int 			retval, line;
++	unsigned long		page;
++
++	line = minor(tty->device) - tty->driver.minor_start;
++	if ((line < 0) || (line >= NR_PORTS)) {
++		return -ENODEV;
++	}
++	retval = get_async_struct(line, &info);
++	if (retval) {
++		return retval;
++	}
++	tty->driver_data = info;
++	info->tty = tty;
++
++#ifdef SERIAL_DEBUG_OPEN
++	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
++	       info->state->count);
++#endif
++	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
++
++	if (!tmp_buf) {
++		page = get_free_page(GFP_KERNEL);
++		if (!page) {
++			return -ENOMEM;
++		}
++		if (tmp_buf)
++			free_page(page);
++		else
++			tmp_buf = (unsigned char *) page;
++	}
++
++	/*
++	 * If the port is the middle of closing, bail out now
++	 */
++	if (tty_hung_up_p(filp) ||
++	    (info->flags & ASYNC_CLOSING)) {
++		if (info->flags & ASYNC_CLOSING)
++			interruptible_sleep_on(&info->close_wait);
++#ifdef SERIAL_DO_RESTART
++		return ((info->flags & ASYNC_HUP_NOTIFY) ?
++			-EAGAIN : -ERESTARTSYS);
++#else
++		return -EAGAIN;
++#endif
++	}
++
++	/*
++	 * Start up serial port
++	 */
++	retval = startup(info);
++	if (retval) {
++		return retval;
++	}
++
++	retval = block_til_ready(tty, filp, info);
++	if (retval) {
++#ifdef SERIAL_DEBUG_OPEN
++		printk("rs_open returning after block_til_ready with %d\n",
++		       retval);
++#endif
++		return retval;
++	}
++
++	if ((info->state->count == 1) &&
++	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
++		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
++			*tty->termios = info->state->normal_termios;
++		else 
++			*tty->termios = info->state->callout_termios;
++		change_speed(info, 0);
++	}
++#ifdef CONFIG_TXX927_SERIAL_CONSOLE
++	if (sercons.cflag && sercons.index == line) {
++		tty->termios->c_cflag = sercons.cflag;
++		sercons.cflag = 0;
++		change_speed(info, 0);
++	}
++#endif
++	info->session = current->session;
++	info->pgrp = current->pgrp;
++
++#ifdef SERIAL_DEBUG_OPEN
++	printk("rs_open ttys%d successful...", info->line);
++#endif
++	return 0;
++}
++
++/*
++ * /proc fs routines....
++ */
++
++static inline int line_info(char *buf, struct serial_state *state)
++{
++	struct async_struct *info = state->info, scr_info;
++	char	stat_buf[30];
++	int	ret;
++	unsigned long flags;
++
++	ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d",
++		      state->line, SERIAL_DRIVER_NAME, 
++		      state->port, state->irq);
++
++	if (!state->port) {
++		ret += sprintf(buf+ret, "\n");
++		return ret;
++	}
++
++	/*
++	 * Figure out the current RS-232 lines
++	 */
++	if (!info) {
++		info = &scr_info;	/* This is just for serial_{in,out} */
++
++		info->magic = SERIAL_MAGIC;
++		info->port = state->port;
++		info->flags = state->flags;
++		info->quot = 0;
++		info->tty = 0;
++	}
++	
++	stat_buf[0] = 0;
++	stat_buf[1] = 0;
++	save_flags(flags); cli();
++	if (!(sio_reg(info)->flcr & TXx927_SIFLCR_RTSSC))
++		strcat(stat_buf, "|RTS");
++	if (!(sio_reg(info)->cisr & TXx927_SICISR_CTSS))
++		strcat(stat_buf, "|CTS");
++	restore_flags(flags); 
++
++	if (info->quot) {
++		ret += sprintf(buf+ret, " baud:%d",
++			       state->baud_base / info->quot);
++	}
++
++	ret += sprintf(buf+ret, " tx:%d rx:%d",
++		      state->icount.tx, state->icount.rx);
++
++	if (state->icount.frame)
++		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
++	
++	if (state->icount.parity)
++		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
++	
++	if (state->icount.brk)
++		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);	
++
++	if (state->icount.overrun)
++		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
++
++	/*
++	 * Last thing is the RS-232 status lines
++	 */
++	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
++	return ret;
++}
++
++static int rs_read_proc(char *page, char **start, off_t off, int count,
++		 int *eof, void *data)
++{
++	int i, len = 0, l;
++	off_t	begin = 0;
++
++	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
++	for (i = 0; i < NR_PORTS && len < 4000; i++) {
++		l = line_info(page + len, &rs_table[i]);
++		len += l;
++		if (len+begin > off+count)
++			goto done;
++		if (len+begin < off) {
++			begin += len;
++			len = 0;
++		}
++	}
++	*eof = 1;
++done:
++	if (off >= len+begin)
++		return 0;
++	*start = page + (begin-off);
++	return ((count < begin+len-off) ? count : begin+len-off);
++}
++
++/*
++ * ---------------------------------------------------------------------
++ * rs_init() and friends
++ *
++ * rs_init() is called at boot-time to initialize the serial driver.
++ * ---------------------------------------------------------------------
++ */
++
++/*
++ * This routine prints out the appropriate serial driver version
++ * number, and identifies which options were configured into this
++ * driver.
++ */
++static _INLINE_ void show_serial_version(void)
++{
++ 	printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
++}
++
++/*
++ * The serial driver boot-time initialization code!
++ */
++static int __init rs_init(void)
++{
++	int i;
++	struct serial_state * state;
++
++	if (rs_table[0].port == 0)
++		return -ENODEV;
++
++	init_bh(TXX927_SERIAL_BH, do_serial_bh);
++	init_timer(&serial_timer);
++	serial_timer.function = rs_timer;
++	mod_timer(&serial_timer, jiffies + RS_STROBE_TIME);
++
++	for (i = 0; i < NR_IRQS; i++) {
++		IRQ_ports[i] = 0;
++		IRQ_timeout[i] = 0;
++	}
++#ifdef CONFIG_TXX927_SERIAL_CONSOLE
++	/*
++	 *	The interrupt of the serial console port
++	 *	can't be shared.
++	 */
++	if (sercons.flags & CON_CONSDEV) {
++		for(i = 0; i < NR_PORTS; i++)
++			if (i != sercons.index &&
++			    rs_table[i].irq == rs_table[sercons.index].irq)
++				rs_table[i].irq = 0;
++	}
++#endif
++	show_serial_version();
++
++	/* Initialize the tty_driver structure */
++	
++	memset(&serial_driver, 0, sizeof(struct tty_driver));
++	serial_driver.magic = TTY_DRIVER_MAGIC;
++	serial_driver.driver_name = "txx927serial";
++#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
++	serial_driver.name = "tts/%d";
++#else
++	serial_driver.name = "ttyS";
++#endif
++	serial_driver.major = TXX927_TTY_MAJOR;
++	serial_driver.minor_start = TXX927_TTY_MINOR_START + SERIAL_DEV_OFFSET;
++	serial_driver.num = NR_PORTS;
++	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
++	serial_driver.subtype = SERIAL_TYPE_NORMAL;
++	serial_driver.init_termios = tty_std_termios;
++	serial_driver.init_termios.c_cflag =
++		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
++	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
++	serial_driver.refcount = &serial_refcount;
++	serial_driver.table = serial_table;
++	serial_driver.termios = serial_termios;
++	serial_driver.termios_locked = serial_termios_locked;
++
++	serial_driver.open = rs_open;
++	serial_driver.close = rs_close;
++	serial_driver.write = rs_write;
++	serial_driver.put_char = rs_put_char;
++	serial_driver.flush_chars = rs_flush_chars;
++	serial_driver.write_room = rs_write_room;
++	serial_driver.chars_in_buffer = rs_chars_in_buffer;
++	serial_driver.flush_buffer = rs_flush_buffer;
++	serial_driver.ioctl = rs_ioctl;
++	serial_driver.throttle = rs_throttle;
++	serial_driver.unthrottle = rs_unthrottle;
++	serial_driver.send_xchar = rs_send_xchar;
++	serial_driver.set_termios = rs_set_termios;
++	serial_driver.stop = rs_stop;
++	serial_driver.start = rs_start;
++	serial_driver.hangup = rs_hangup;
++	serial_driver.break_ctl = rs_break;
++	serial_driver.wait_until_sent = rs_wait_until_sent;
++	serial_driver.read_proc = rs_read_proc;
++	
++	/*
++	 * The callout device is just like normal device except for
++	 * major number and the subtype code.
++	 */
++	callout_driver = serial_driver;
++#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
++	        callout_driver.name = "cua/%d";
++#else
++		callout_driver.name = "cua";
++#endif                               
++	callout_driver.major = TTYAUX_MAJOR;
++	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
++	callout_driver.read_proc = 0;
++	callout_driver.proc_entry = 0;
++
++	if (tty_register_driver(&serial_driver)){
++		panic("Couldn't register serial driver\n");
++	}
++	if (tty_register_driver(&callout_driver)) {
++		panic("Couldn't register callout driver\n");
++	}
++	
++	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
++		state->magic = SSTATE_MAGIC;
++		state->line = i;
++		state->type = PORT_UNKNOWN;
++		state->custom_divisor = 0;
++		state->close_delay = 5*HZ/10;
++		state->closing_wait = 30*HZ;
++		state->callout_termios = callout_driver.init_termios;
++		state->normal_termios = serial_driver.init_termios;
++		state->icount.cts = state->icount.dsr = 
++			state->icount.rng = state->icount.dcd = 0;
++		state->icount.rx = state->icount.tx = 0;
++		state->icount.frame = state->icount.parity = 0;
++		state->icount.overrun = state->icount.brk = 0;
++		state->irq = irq_cannonicalize(state->irq);
++		state->xmit_fifo_size = TXx927_SIO_TX_FIFO;
++		if (state->hub6)
++			state->io_type = SERIAL_IO_HUB6;
++		if (state->port) {
++			continue;                                
++		}
++	}
++
++	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
++	        if (state->type == PORT_UNKNOWN) {
++		       continue;
++		}                                        
++		printk(KERN_INFO "%s%02d at 0x%04lx (irq = %d) is a %s\n",
++		       TXX927_TTY_NAME,
++		       state->line,
++		       state->port, state->irq,
++		       SERIAL_DRIVER_NAME);
++		tty_register_devfs(&serial_driver, 0,
++		                serial_driver.minor_start + state->line);
++		tty_register_devfs(&callout_driver, 0,
++			       	callout_driver.minor_start + state->line); 
++	}
++	return 0;
++}
++
++static void __exit rs_fini(void) 
++{
++	unsigned long flags;
++	int e1, e2;
++	int i;
++	struct async_struct *info;
++
++	del_timer_sync(&serial_timer);
++	save_flags(flags); cli();
++        remove_bh(TXX927_SERIAL_BH);
++	if ((e1 = tty_unregister_driver(&serial_driver)))
++		printk(KERN_WARNING "serial: failed to unregister serial driver (%d)\n",
++		       e1);
++	if ((e2 = tty_unregister_driver(&callout_driver)))
++		printk(KERN_WARNING "serial: failed to unregister callout driver (%d)\n", 
++		       e2);
++	restore_flags(flags);
++
++	for (i = 0; i < NR_PORTS; i++) {
++		if ((info = rs_table[i].info)) {
++			rs_table[i].info = NULL;
++			kfree(info);
++		}
++	}
++	if (tmp_buf) {
++		unsigned long pg = (unsigned long) tmp_buf;
++		tmp_buf = NULL;
++		free_page(pg);
++	}
++}
++
++module_init(rs_init);
++module_exit(rs_fini);
++MODULE_DESCRIPTION("TXX927 serial driver");
++
++/*
++ * ------------------------------------------------------------
++ * Serial console driver
++ * ------------------------------------------------------------
++ */
++#ifdef CONFIG_TXX927_SERIAL_CONSOLE
++
++static struct async_struct async_sercons;
++
++/*
++ *	Print a string to the serial port trying not to disturb
++ *	any possible real use of the port...
++ */
++static void serial_console_write(struct console *co, const char *s,
++				unsigned count)
++{
++	static struct async_struct *info = &async_sercons;
++	int ier;
++	unsigned i;
++
++	/*
++	 *	First save the IER then disable the interrupts
++	 */
++	ier = sio_reg(info)->dicr;
++	sio_reg(info)->dicr = 0;
++
++
++	/*
++	 *	Now, do each character
++	 */
++	for (i = 0; i < count; i++, s++) {
++		wait_for_xmitr(info);
++
++		/*
++		 *	Send the character out.
++		 *	If a LF, also do CR...
++		 */
++		sio_reg(info)->tfifo = *s;
++		if (*s == 10) {
++			wait_for_xmitr(info);
++			sio_reg(info)->tfifo = 13;
++		}
++	}
++
++	/*
++	 *	Finally, Wait for transmitter & holding register to empty
++	 * 	and restore the IER
++	 */
++	wait_for_xmitr(info);
++	sio_reg(info)->dicr = ier;
++}
++
++static kdev_t serial_console_device(struct console *c)
++{
++	return mk_kdev(TXX927_TTY_MAJOR, TXX927_TTY_MINOR_START + c->index);
++}
++
++/*
++ *	Setup initial baud/bits/parity. We do two things here:
++ *	- construct a cflag setting for the first rs_open()
++ *	- initialize the serial port
++ *	Return non-zero if we didn't find a serial port.
++ */
++static int serial_console_setup(struct console *co, char *options)
++{
++	static struct async_struct *info;
++	struct serial_state *state;
++	unsigned cval;
++	int	baud = 9600;
++	int	bits = 8;
++	int	parity = 'n';
++	int	cflag = CREAD | HUPCL | CLOCAL;
++	int	quot = 0;
++	char	*s;
++
++	if (co->index < 0 || co->index >= NR_PORTS) {
++		return -1;
++	}
++	if (options) {
++		baud = simple_strtoul(options, NULL, 10);
++		s = options;
++		while(*s >= '0' && *s <= '9')
++			s++;
++		if (*s) parity = *s++;
++		if (*s) bits   = *s - '0';
++	}
++
++	/*
++	 *	Now construct a cflag setting.
++	 */
++	switch(baud) {
++		case 1200:
++			cflag |= B1200;
++			break;
++		case 2400:
++			cflag |= B2400;
++			break;
++		case 4800:
++			cflag |= B4800;
++			break;
++		case 19200:
++			cflag |= B19200;
++			break;
++		case 38400:
++			cflag |= B38400;
++			break;
++		case 57600:
++			cflag |= B57600;
++			break;
++		case 115200:
++			cflag |= B115200;
++			break;
++		case 9600:
++		default:
++			cflag |= B9600;
++			break;
++	}
++	switch(bits) {
++		case 7:
++			cflag |= CS7;
++			break;
++		default:
++		case 8:
++			cflag |= CS8;
++			break;
++	}
++	switch(parity) {
++		case 'o': case 'O':
++			cflag |= PARODD;
++			break;
++		case 'e': case 'E':
++			cflag |= PARENB;
++			break;
++	}
++	co->cflag = cflag;
++
++	/*
++	 *	Divisor, bytesize and parity
++	 */
++	state = rs_table + co->index;
++	info = &async_sercons;
++	info->magic = SERIAL_MAGIC;
++	info->state = state;
++	info->port = state->port;
++	info->flags = state->flags;
++	info->io_type = state->io_type;
++	info->iomem_base = state->iomem_base;
++	info->iomem_reg_shift = state->iomem_reg_shift;
++	quot = state->baud_base / baud;
++
++	switch (cflag & CSIZE) {
++	case CS7: cval = TXx927_SILCR_UMODE_7BIT; break;
++	default:
++	case CS8: cval = TXx927_SILCR_UMODE_8BIT; break;
++	}
++	if (cflag & CSTOPB)
++		cval |= TXx927_SILCR_USBL_2BIT;
++	else
++		cval |= TXx927_SILCR_USBL_1BIT;
++	if (cflag & PARENB)
++		cval |= TXx927_SILCR_UPEN;
++	if (!(cflag & PARODD))
++		cval |= TXx927_SILCR_UEPS;
++
++	/*
++	 *	Disable UART interrupts, set DTR and RTS high
++	 *	and set speed.
++	 */
++	sio_reg(info)->dicr = 0;
++	sio_reg(info)->lcr = cval | TXx927_SILCR_SCS_IMCLK_BG;
++	sio_reg(info)->bgr = quot | TXx927_SIBGR_BCLK_T0;
++	/* HW RTS/CTS control */
++	if (info->flags & ASYNC_HAVE_CTS_LINE)
++		sio_reg(info)->flcr = TXx927_SIFLCR_RCS | TXx927_SIFLCR_TES |
++			TXx927_SIFLCR_RTSTL_MAX /* 15 */;
++	/* Enable RX/TX */
++	sio_reg(info)->flcr &= ~(TXx927_SIFLCR_RSDE | TXx927_SIFLCR_TSDE);
++
++	return 0;
++}
++
++static struct console sercons = {
++	name:           TXX927_TTY_NAME,
++	write:          serial_console_write,
++	device:	        serial_console_device,
++	setup:	        serial_console_setup,
++	flags:	        CON_PRINTBUFFER,
++	index:	        -1,
++};
++
++/*
++ *	Register console.
++ */
++void __init txx927_console_init(void)
++{
++	register_console(&sercons);
++}
++#endif
+diff -urpNX dontdiff linux-2.6.10/drivers/i2c/algos/Kconfig linux-2.6.10-mips/drivers/i2c/algos/Kconfig
+--- linux-2.6.10/drivers/i2c/algos/Kconfig	2004-12-24 22:36:01.000000000 +0100
++++ linux-2.6.10-mips/drivers/i2c/algos/Kconfig	2004-09-21 13:10:19.000000000 +0200
+@@ -53,5 +53,18 @@ config I2C_ALGO8XX
+ 	tristate "MPC8xx CPM I2C interface"
+ 	depends on 8xx && I2C
+ 
++config I2C_ALGO_SIBYTE
++	tristate "SiByte SMBus interface"
++	depends on SIBYTE_SB1xxx_SOC && I2C
++	help
++	  Supports the SiByte SOC on-chip I2C interfaces (2 channels).
++
++config I2C_ALGO_SGI
++	tristate "I2C SGI interfaces"
++	depends on I2C
++	help
++	  Supports the SGI interfaces like the ones found on SGI Indy VINO
++	  or SGI O2 MACE.
++
+ endmenu
+ 
+diff -urpNX dontdiff linux-2.6.10/drivers/i2c/algos/Makefile linux-2.6.10-mips/drivers/i2c/algos/Makefile
+--- linux-2.6.10/drivers/i2c/algos/Makefile	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/drivers/i2c/algos/Makefile	2004-09-21 13:10:19.000000000 +0200
+@@ -6,6 +6,8 @@ obj-$(CONFIG_I2C_ALGOBIT)	+= i2c-algo-bi
+ obj-$(CONFIG_I2C_ALGOPCF)	+= i2c-algo-pcf.o
+ obj-$(CONFIG_I2C_ALGOPCA)	+= i2c-algo-pca.o
+ obj-$(CONFIG_I2C_ALGOITE)	+= i2c-algo-ite.o
++obj-$(CONFIG_I2C_ALGO_SIBYTE)	+= i2c-algo-sibyte.o
++obj-$(CONFIG_I2C_ALGO_SGI)	+= i2c-algo-sgi.o
+ 
+ ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
+ EXTRA_CFLAGS += -DDEBUG
+diff -urpNX dontdiff linux-2.6.10/drivers/i2c/algos/i2c-algo-sgi.c linux-2.6.10-mips/drivers/i2c/algos/i2c-algo-sgi.c
+--- linux-2.6.10/drivers/i2c/algos/i2c-algo-sgi.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/i2c/algos/i2c-algo-sgi.c	2003-09-30 16:27:22.000000000 +0200
+@@ -0,0 +1,189 @@
++/*
++ * i2c-algo-sgi.c: i2c driver algorithms for SGI adapters.
++ * 
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License version 2 as published by the Free Software Foundation.
++ *
++ * Copyright (C) 2003 Ladislav Michl <ladis at linux-mips.org>
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include <linux/delay.h>
++
++#include <linux/i2c.h>
++#include <linux/i2c-algo-sgi.h>
++
++
++#define SGI_I2C_FORCE_IDLE	(0 << 0)
++#define SGI_I2C_NOT_IDLE	(1 << 0)
++#define SGI_I2C_WRITE		(0 << 1)
++#define SGI_I2C_READ		(1 << 1)
++#define SGI_I2C_RELEASE_BUS	(0 << 2)
++#define SGI_I2C_HOLD_BUS	(1 << 2)
++#define SGI_I2C_XFER_DONE	(0 << 4)
++#define SGI_I2C_XFER_BUSY	(1 << 4)
++#define SGI_I2C_ACK		(0 << 5)
++#define SGI_I2C_NACK		(1 << 5)
++#define SGI_I2C_BUS_OK		(0 << 7)
++#define SGI_I2C_BUS_ERR		(1 << 7)
++
++#define get_control()		adap->getctrl(adap->data)
++#define set_control(val)	adap->setctrl(adap->data, val)
++#define read_data()		adap->rdata(adap->data)
++#define write_data(val)		adap->wdata(adap->data, val)
++
++
++static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
++{
++	int i;
++
++	for (i = 0; i < adap->xfer_timeout; i++) {
++		if ((get_control() & SGI_I2C_XFER_BUSY) == 0)
++			return 0;
++		udelay(1);
++	}
++
++	return -ETIMEDOUT;
++}
++
++static int wait_ack(struct i2c_algo_sgi_data *adap)
++{
++	int i;
++
++	if (wait_xfer_done(adap))
++		return -ETIMEDOUT;
++	for (i = 0; i < adap->ack_timeout; i++) {
++		if ((get_control() & SGI_I2C_NACK) == 0)
++			return 0;
++		udelay(1);
++	}
++
++	return -ETIMEDOUT;
++}
++
++static int force_idle(struct i2c_algo_sgi_data *adap)
++{
++	int i;
++
++	set_control(SGI_I2C_FORCE_IDLE);
++	for (i = 0; i < adap->xfer_timeout; i++) {
++		if ((get_control() & SGI_I2C_NOT_IDLE) == 0)
++			goto out;
++		udelay(1);
++	}
++	return -ETIMEDOUT;
++out:
++	if (get_control() & SGI_I2C_BUS_ERR)
++		return -EIO;
++	return 0;
++}
++
++static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
++		      int rd)
++{
++	if (rd)
++		set_control(SGI_I2C_NOT_IDLE);
++	/* Check if bus is idle, eventually force it to do so */
++	if (get_control() & SGI_I2C_NOT_IDLE)
++		if (force_idle(adap))
++	                return -EIO;
++	/* Write out the i2c chip address and specify operation */
++	set_control(SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
++	if (rd)
++		addr |= 1;
++	write_data(addr);
++	if (wait_ack(adap))
++		return -EIO;
++	return 0;
++}
++
++static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
++		    unsigned int len)
++{
++	int i;
++
++	set_control(SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
++	for (i = 0; i < len; i++) {
++		if (wait_xfer_done(adap))
++			return -EIO;
++		buf[i] = read_data();
++	}
++	set_control(SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
++
++	return 0;
++
++}
++
++static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
++		     unsigned int len)
++{
++	int i;
++
++	/* We are already in write state */
++	for (i = 0; i < len; i++) {
++		write_data(buf[i]);
++		if (wait_ack(adap))
++			return -EIO;
++	}
++	return 0;
++}
++
++static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[],
++		    int num)
++{
++	struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
++	struct i2c_msg *p;
++	int i, err = 0;
++
++	for (i = 0; !err && i < num; i++) {
++		p = &msgs[i];
++		err = do_address(adap, p->addr, p->flags & I2C_M_RD);
++		if (err || !p->len)
++			continue;
++		if (p->flags & I2C_M_RD)
++			err = i2c_read(adap, p->buf, p->len);
++		else
++			err = i2c_write(adap, p->buf, p->len);
++	}
++
++	return err;
++}
++
++static u32 sgi_func(struct i2c_adapter *adap)
++{
++	return I2C_FUNC_SMBUS_EMUL;
++}
++
++static struct i2c_algorithm sgi_algo = {
++	.name		= "SGI algorithm",
++	.id		= I2C_ALGO_SGI,
++	.master_xfer	= sgi_xfer,
++	.functionality	= sgi_func,
++};
++
++/* 
++ * registering functions to load algorithms at runtime 
++ */
++int i2c_sgi_add_bus(struct i2c_adapter *adap)
++{
++	adap->id |= sgi_algo.id;
++	adap->algo = &sgi_algo;
++
++	return i2c_add_adapter(adap);
++}
++
++
++int i2c_sgi_del_bus(struct i2c_adapter *adap)
++{
++	return i2c_del_adapter(adap);
++}
++
++EXPORT_SYMBOL(i2c_sgi_add_bus);
++EXPORT_SYMBOL(i2c_sgi_del_bus);
++
++MODULE_AUTHOR("Ladislav Michl <ladis at linux-mips.org>");
++MODULE_DESCRIPTION("I2C-Bus SGI algorithm");
++MODULE_LICENSE("GPL");
+diff -urpNX dontdiff linux-2.6.10/drivers/i2c/algos/i2c-algo-sibyte.c linux-2.6.10-mips/drivers/i2c/algos/i2c-algo-sibyte.c
+--- linux-2.6.10/drivers/i2c/algos/i2c-algo-sibyte.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/i2c/algos/i2c-algo-sibyte.c	2004-12-22 18:08:54.000000000 +0100
+@@ -0,0 +1,225 @@
++/* ------------------------------------------------------------------------- */
++/* i2c-algo-sibyte.c i2c driver algorithms for bit-shift adapters		     */
++/* ------------------------------------------------------------------------- */
++/*   Copyright (C) 2001,2002,2003 Broadcom Corporation
++     Copyright (C) 1995-2000 Simon G. Vogl
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++    GNU General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program; if not, write to the Free Software
++    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
++/* ------------------------------------------------------------------------- */
++
++/* With some changes from Kyösti Mälkki <kmalkki at cc.hut.fi> and even
++   Frodo Looijaard <frodol at dds.nl>.  */
++
++/* Ported for SiByte SOCs by Broadcom Corporation.  */
++
++#include <linux/config.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/init.h>
++
++#include <asm/io.h>
++#include <asm/sibyte/sb1250_regs.h>
++#include <asm/sibyte/sb1250_smbus.h>
++
++#include <linux/i2c.h>
++#include <linux/i2c-algo-sibyte.h>
++
++/* ----- global defines ----------------------------------------------- */
++#define SMB_CSR(a,r) ((long)(a->reg_base + r))
++
++/* ----- global variables ---------------------------------------------	*/
++
++/* module parameters:
++ */
++static int bit_scan=0;	/* have a look at what's hanging 'round		*/
++
++
++static int smbus_xfer(struct i2c_adapter *i2c_adap, u16 addr, 
++                      unsigned short flags, char read_write,
++                      u8 command, int size, union i2c_smbus_data * data)
++{
++	struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data;
++        int data_bytes = 0;
++        int error;
++
++        while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY)
++                ;
++
++        switch (size) {
++        case I2C_SMBUS_QUICK:
++                csr_out32((V_SMB_ADDR(addr) | (read_write == I2C_SMBUS_READ ? M_SMB_QDATA : 0) |
++			   V_SMB_TT_QUICKCMD), SMB_CSR(adap, R_SMB_START));
++                break;
++        case I2C_SMBUS_BYTE:
++                if (read_write == I2C_SMBUS_READ) {
++                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_RD1BYTE),
++				  SMB_CSR(adap, R_SMB_START));
++                        data_bytes = 1;
++                } else {
++                        csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD));
++                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR1BYTE),
++				  SMB_CSR(adap, R_SMB_START));
++                }
++                break;
++        case I2C_SMBUS_BYTE_DATA:
++                csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD));
++                if (read_write == I2C_SMBUS_READ) {
++                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD1BYTE),
++				  SMB_CSR(adap, R_SMB_START));
++                        data_bytes = 1;
++                } else {
++                        csr_out32(V_SMB_LB(data->byte), SMB_CSR(adap, R_SMB_DATA));
++                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE),
++				  SMB_CSR(adap, R_SMB_START));
++                }
++                break;
++        case I2C_SMBUS_WORD_DATA:
++                csr_out32(V_SMB_CMD(command), SMB_CSR(adap, R_SMB_CMD));
++                if (read_write == I2C_SMBUS_READ) {
++                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_CMD_RD2BYTE),
++				  SMB_CSR(adap, R_SMB_START));
++                        data_bytes = 2;
++                } else {
++                        csr_out32(V_SMB_LB(data->word & 0xff), SMB_CSR(adap, R_SMB_DATA));
++                        csr_out32(V_SMB_MB(data->word >> 8), SMB_CSR(adap, R_SMB_DATA));
++                        csr_out32((V_SMB_ADDR(addr) | V_SMB_TT_WR2BYTE),
++				  SMB_CSR(adap, R_SMB_START));
++                }
++                break;
++        default:
++                return -1;      /* XXXKW better error code? */
++        }
++
++        while (csr_in32(SMB_CSR(adap, R_SMB_STATUS)) & M_SMB_BUSY)
++                ;
++
++        error = csr_in32(SMB_CSR(adap, R_SMB_STATUS));
++        if (error & M_SMB_ERROR) {
++                /* Clear error bit by writing a 1 */
++                csr_out32(M_SMB_ERROR, SMB_CSR(adap, R_SMB_STATUS));
++                return -1;      /* XXXKW better error code? */
++        }
++
++        if (data_bytes == 1)
++                data->byte = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xff;
++        if (data_bytes == 2)
++                data->word = csr_in32(SMB_CSR(adap, R_SMB_DATA)) & 0xffff;
++
++        return 0;
++}
++
++static int algo_control(struct i2c_adapter *adapter, 
++	unsigned int cmd, unsigned long arg)
++{
++	return 0;
++}
++
++static u32 bit_func(struct i2c_adapter *adap)
++{
++	return (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
++                I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA);
++}
++
++
++/* -----exported algorithm data: -------------------------------------	*/
++
++static struct i2c_algorithm i2c_sibyte_algo = {
++	"SiByte algorithm",
++	I2C_ALGO_SIBYTE,
++	NULL,                           /* master_xfer          */
++	smbus_xfer,                   	/* smbus_xfer           */
++	NULL,				/* slave_xmit		*/
++	NULL,				/* slave_recv		*/
++	algo_control,			/* ioctl		*/
++	bit_func,			/* functionality	*/
++};
++
++/* 
++ * registering functions to load algorithms at runtime 
++ */
++int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed)
++{
++	int i;
++	struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data;
++
++	/* register new adapter to i2c module... */
++
++	i2c_adap->id |= i2c_sibyte_algo.id;
++	i2c_adap->algo = &i2c_sibyte_algo;
++        
++        /* Set the frequency to 100 kHz */
++        csr_out32(speed, SMB_CSR(adap,R_SMB_FREQ));
++        csr_out32(0, SMB_CSR(adap,R_SMB_CONTROL));
++
++	/* scan bus */
++	if (bit_scan) {
++                union i2c_smbus_data data;
++                int rc;
++		printk(KERN_INFO " i2c-algo-sibyte.o: scanning bus %s.\n",
++		       i2c_adap->name);
++		for (i = 0x00; i < 0x7f; i++) {
++                        /* XXXKW is this a realistic probe? */
++                        rc = smbus_xfer(i2c_adap, i, 0, I2C_SMBUS_READ, 0,
++                                        I2C_SMBUS_BYTE_DATA, &data);
++			if (!rc) {
++				printk("(%02x)",i); 
++			} else 
++				printk("."); 
++		}
++		printk("\n");
++	}
++
++	i2c_add_adapter(i2c_adap);
++
++	return 0;
++}
++
++
++int i2c_sibyte_del_bus(struct i2c_adapter *adap)
++{
++	int res;
++
++	if ((res = i2c_del_adapter(adap)) < 0)
++		return res;
++
++	return 0;
++}
++
++int __init i2c_algo_sibyte_init (void)
++{
++	printk("i2c-algo-sibyte.o: i2c SiByte algorithm module\n");
++	return 0;
++}
++
++
++EXPORT_SYMBOL(i2c_sibyte_add_bus);
++EXPORT_SYMBOL(i2c_sibyte_del_bus);
++
++#ifdef MODULE
++MODULE_AUTHOR("Kip Walker, Broadcom Corp.");
++MODULE_DESCRIPTION("SiByte I2C-Bus algorithm");
++MODULE_PARM(bit_scan, "i");
++MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus");
++MODULE_LICENSE("GPL");
++
++int init_module(void) 
++{
++	return i2c_algo_sibyte_init();
++}
++
++void cleanup_module(void) 
++{
++}
++#endif
+diff -urpNX dontdiff linux-2.6.10/drivers/i2c/busses/Kconfig linux-2.6.10-mips/drivers/i2c/busses/Kconfig
+--- linux-2.6.10/drivers/i2c/busses/Kconfig	2004-12-24 22:35:25.000000000 +0100
++++ linux-2.6.10-mips/drivers/i2c/busses/Kconfig	2004-12-04 20:57:20.000000000 +0100
+@@ -323,6 +323,12 @@ config I2C_SAVAGE4
+ 	  This driver can also be built as a module.  If so, the module
+ 	  will be called i2c-savage4.
+ 
++config I2C_SIBYTE
++	tristate "SiByte SMBus interface"
++	depends on SIBYTE_SB1xxx_SOC && I2C
++	help
++	  Supports the SiByte SOC on-chip I2C interfaces (2 channels).
++
+ config SCx200_I2C
+ 	tristate "NatSemi SCx200 I2C using GPIO pins"
+ 	depends on SCx200_GPIO && I2C
+diff -urpNX dontdiff linux-2.6.10/drivers/i2c/busses/Makefile linux-2.6.10-mips/drivers/i2c/busses/Makefile
+--- linux-2.6.10/drivers/i2c/busses/Makefile	2004-12-24 22:33:51.000000000 +0100
++++ linux-2.6.10-mips/drivers/i2c/busses/Makefile	2004-11-19 01:14:23.000000000 +0100
+@@ -29,6 +29,7 @@ obj-$(CONFIG_I2C_PROSAVAGE)	+= i2c-prosa
+ obj-$(CONFIG_I2C_RPXLITE)	+= i2c-rpx.o
+ obj-$(CONFIG_I2C_S3C2410)	+= i2c-s3c2410.o
+ obj-$(CONFIG_I2C_SAVAGE4)	+= i2c-savage4.o
++obj-$(CONFIG_I2C_SIBYTE)	+= i2c-sibyte.o
+ obj-$(CONFIG_I2C_SIS5595)	+= i2c-sis5595.o
+ obj-$(CONFIG_I2C_SIS630)	+= i2c-sis630.o
+ obj-$(CONFIG_I2C_SIS96X)	+= i2c-sis96x.o
+diff -urpNX dontdiff linux-2.6.10/drivers/i2c/busses/i2c-sibyte.c linux-2.6.10-mips/drivers/i2c/busses/i2c-sibyte.c
+--- linux-2.6.10/drivers/i2c/busses/i2c-sibyte.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/i2c/busses/i2c-sibyte.c	2005-01-11 00:40:22.000000000 +0100
+@@ -0,0 +1,71 @@
++/*
++ * Copyright (C) 2004 Steven J. Hill
++ * Copyright (C) 2001,2002,2003 Broadcom Corporation
++ *
++ * 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 <linux/config.h>
++#include <linux/module.h>
++#include <linux/i2c-algo-sibyte.h>
++#include <asm/sibyte/sb1250_regs.h>
++#include <asm/sibyte/sb1250_smbus.h>
++
++static struct i2c_algo_sibyte_data sibyte_board_data[2] = {
++	{ NULL, 0, (void *) (KSEG1+A_SMB_BASE(0)) },
++	{ NULL, 1, (void *) (KSEG1+A_SMB_BASE(1)) }
++};
++
++static struct i2c_adapter sibyte_board_adapter[2] = {
++	{
++		.owner		= THIS_MODULE,
++		.id		= I2C_HW_SIBYTE,
++		.class		= I2C_CLASS_HWMON,
++		.algo		= NULL,
++		.algo_data	= &sibyte_board_data[0],
++		.name		= "SiByte SMBus 0",
++	},
++	{
++		.owner		= THIS_MODULE,
++		.id		= I2C_HW_SIBYTE,
++		.class		= I2C_CLASS_HWMON,
++		.algo		= NULL,
++		.algo_data	= &sibyte_board_data[1],
++		.name		= "SiByte SMBus 1",
++	},
++};
++
++static int __init i2c_sibyte_init(void)
++{
++	printk("i2c-swarm.o: i2c SMBus adapter module for SiByte board\n");
++	if (i2c_sibyte_add_bus(&sibyte_board_adapter[0], K_SMB_FREQ_100KHZ) < 0)
++		return -ENODEV;
++	if (i2c_sibyte_add_bus(&sibyte_board_adapter[1], K_SMB_FREQ_400KHZ) < 0)
++		return -ENODEV;
++	return 0;
++}
++
++static void __exit i2c_sibyte_exit(void)
++{
++	i2c_sibyte_del_bus(&sibyte_board_adapter[0]);
++	i2c_sibyte_del_bus(&sibyte_board_adapter[1]);
++}
++
++module_init(i2c_sibyte_init);
++module_exit(i2c_sibyte_exit);
++
++MODULE_AUTHOR("Kip Walker <kwalker at broadcom.com>, Steven J. Hill <sjhill at realitydiluted.com>");
++MODULE_DESCRIPTION("SMBus adapter routines for SiByte boards");
++MODULE_LICENSE("GPL");
+diff -urpNX dontdiff linux-2.6.10/drivers/ide/Kconfig linux-2.6.10-mips/drivers/ide/Kconfig
+--- linux-2.6.10/drivers/ide/Kconfig	2004-12-24 22:34:44.000000000 +0100
++++ linux-2.6.10-mips/drivers/ide/Kconfig	2004-11-19 01:14:26.000000000 +0100
+@@ -772,6 +772,10 @@ config BLK_DEV_IDE_PMAC_BLINK
+ 	  This option enables the use of the sleep LED as a hard drive
+ 	  activity LED.
+ 
++config BLK_DEV_IDE_SWARM
++	bool "IDE for Sibyte evaluation boards"
++	depends on SIBYTE_SB1xxx_SOC
++
+ config IDE_ARM
+ 	def_bool ARM && (ARCH_A5K || ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK)
+ 
+diff -urpNX dontdiff linux-2.6.10/drivers/ide/Makefile linux-2.6.10-mips/drivers/ide/Makefile
+--- linux-2.6.10/drivers/ide/Makefile	2004-12-24 22:34:45.000000000 +0100
++++ linux-2.6.10-mips/drivers/ide/Makefile	2004-11-19 01:14:26.000000000 +0100
+@@ -50,6 +50,6 @@ obj-$(CONFIG_BLK_DEV_IDECD)		+= ide-cd.o
+ obj-$(CONFIG_BLK_DEV_IDETAPE)		+= ide-tape.o
+ obj-$(CONFIG_BLK_DEV_IDEFLOPPY)		+= ide-floppy.o
+ 
+-obj-$(CONFIG_BLK_DEV_IDE)		+= legacy/ arm/
++obj-$(CONFIG_BLK_DEV_IDE)		+= legacy/ arm/ mips/
+ obj-$(CONFIG_BLK_DEV_HD)		+= legacy/
+ obj-$(CONFIG_ETRAX_IDE)		+= cris/
+diff -urpNX dontdiff linux-2.6.10/drivers/ide/ide.c linux-2.6.10-mips/drivers/ide/ide.c
+--- linux-2.6.10/drivers/ide/ide.c	2004-12-24 22:34:29.000000000 +0100
++++ linux-2.6.10-mips/drivers/ide/ide.c	2004-12-21 03:25:21.000000000 +0100
+@@ -2145,6 +2145,12 @@ static void __init probe_for_hwifs (void
+ 		q40ide_init();
+ 	}
+ #endif /* CONFIG_BLK_DEV_Q40IDE */
++#ifdef CONFIG_BLK_DEV_IDE_SWARM
++	{
++		extern void swarm_ide_probe(void);
++		swarm_ide_probe();
++	}
++#endif /* CONFIG_BLK_IDE_SWARM */
+ #ifdef CONFIG_BLK_DEV_BUDDHA
+ 	{
+ 		extern void buddha_init(void);
+diff -urpNX dontdiff linux-2.6.10/drivers/ide/mips/Makefile linux-2.6.10-mips/drivers/ide/mips/Makefile
+--- linux-2.6.10/drivers/ide/mips/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/ide/mips/Makefile	2004-09-21 13:10:22.000000000 +0200
+@@ -0,0 +1,3 @@
++obj-$(CONFIG_BLK_DEV_IDE_SWARM)		+= swarm.o
++
++EXTRA_CFLAGS	:= -I../
+diff -urpNX dontdiff linux-2.6.10/drivers/ide/mips/swarm.c linux-2.6.10-mips/drivers/ide/mips/swarm.c
+--- linux-2.6.10/drivers/ide/mips/swarm.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/ide/mips/swarm.c	2004-12-21 03:25:21.000000000 +0100
+@@ -0,0 +1,123 @@
++/*
++ * Copyright (C) 2001, 2002, 2003 Broadcom Corporation
++ * Copyright (C) 2004 MontaVista Software Inc.
++ *	Author:	Manish Lachwani, mlachwani at mvista.com
++ * Copyright (C) 2004  MIPS Technologies, Inc.  All rights reserved.
++ *	Author: Maciej W. Rozycki <macro at mips.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ * 
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++ */
++
++/*
++ *  Derived loosely from ide-pmac.c, so:  
++ *  Copyright (C) 1998 Paul Mackerras.
++ *  Copyright (C) 1995-1998 Mark Lord
++ */
++
++/*
++ * Boards with SiByte processors so far have supported IDE devices via
++ * the Generic Bus, PCI bus, and built-in PCMCIA interface.  In all
++ * cases, byte-swapping must be avoided for these devices (whereas
++ * other PCI devices, for example, will require swapping).  Any
++ * SiByte-targetted kernel including IDE support will include this
++ * file.  Probing of a Generic Bus for an IDE device is controlled by
++ * the definition of "SIBYTE_HAVE_IDE", which is provided by
++ * <asm/sibyte/board.h> for Broadcom boards.
++ */
++
++#include <linux/ide.h>
++#include <linux/ioport.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++
++#include <asm/io.h>
++
++#include <asm/sibyte/board.h>
++#include <asm/sibyte/sb1250_genbus.h>
++#include <asm/sibyte/sb1250_regs.h>
++
++#define DRV_NAME "ide-swarm"
++
++static struct resource swarm_ide_resource = {
++	.name	= "SWARM GenBus IDE",
++	.flags	= IORESOURCE_MEM,
++};
++
++/*
++ * swarm_ide_probe - if the board header indicates the existence of
++ * Generic Bus IDE, allocate a HWIF for it.
++ */
++void __init swarm_ide_probe(void)
++{
++	ide_hwif_t *hwif;
++	u8 __iomem *base;
++	phys_t offset, size;
++	int i;
++
++	if (!SIBYTE_HAVE_IDE)
++		return;
++
++	/* Find an empty slot.  */
++	for (i = 0; i < MAX_HWIFS; i++) 
++		if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET])
++			break;
++	if (i >= MAX_HWIFS) {
++		printk(KERN_ERR DRV_NAME ": no free slot for interface\n");
++		return;
++	}
++	hwif = ide_hwifs + i;
++
++	base = ioremap(A_IO_EXT_BASE, 0x800);
++	offset = bus_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS));
++	size = bus_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS));
++	iounmap(base);
++	
++	offset = G_IO_START_ADDR(offset) << S_IO_ADDRBASE;
++	size = (G_IO_MULT_SIZE(size) + 1) << S_IO_REGSIZE;
++	if (offset < A_PHYS_GENBUS || offset >= A_PHYS_GENBUS_END) {
++		printk(KERN_INFO DRV_NAME
++		       ": IDE interface at GenBus disabled\n");
++		return;
++	}
++
++	printk(KERN_INFO DRV_NAME ": IDE interface at GenBus slot %i\n",
++	       IDE_CS);
++
++	swarm_ide_resource.start = offset;
++	swarm_ide_resource.end = offset + size - 1;
++	if (request_resource(&iomem_resource, &swarm_ide_resource)) {
++		printk(KERN_ERR DRV_NAME
++		       ": can't request I/O memory resource\n");
++		return;
++	}
++
++	base = ioremap(offset, size);
++
++	/* Setup MMIO ops.  */
++	default_hwif_mmiops(hwif);
++	/* Prevent resource map manipulation.  */
++	hwif->mmio = 2;
++	hwif->noprobe = 0;
++
++	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
++		hwif->hw.io_ports[i] =
++				(unsigned long)(base + ((0x1f0 + i) << 5));
++	hwif->hw.io_ports[IDE_CONTROL_OFFSET] =
++				(unsigned long)(base + (0x3f6 << 5));
++	hwif->hw.irq = K_INT_GB_IDE;
++
++	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
++	hwif->irq = hwif->hw.irq;
++}
+diff -urpNX dontdiff linux-2.6.10/drivers/input/serio/i8042.h linux-2.6.10-mips/drivers/input/serio/i8042.h
+--- linux-2.6.10/drivers/input/serio/i8042.h	2004-12-24 22:35:24.000000000 +0100
++++ linux-2.6.10-mips/drivers/input/serio/i8042.h	2004-10-12 19:31:03.000000000 +0200
+@@ -15,7 +15,7 @@
+  * Arch-dependent inline functions and defines.
+  */
+ 
+-#if defined(CONFIG_MIPS_JAZZ)
++#if defined(CONFIG_MACH_JAZZ)
+ #include "i8042-jazzio.h"
+ #elif defined(CONFIG_SGI_IP22)
+ #include "i8042-ip22io.h"
+diff -urpNX dontdiff linux-2.6.10/drivers/input/serio/maceps2.c linux-2.6.10-mips/drivers/input/serio/maceps2.c
+--- linux-2.6.10/drivers/input/serio/maceps2.c	2004-12-24 22:34:31.000000000 +0100
++++ linux-2.6.10-mips/drivers/input/serio/maceps2.c	2004-10-27 02:14:22.000000000 +0200
+@@ -62,8 +62,8 @@ static int maceps2_write(struct serio *d
+ 	unsigned int timeout = MACE_PS2_TIMEOUT;
+ 
+ 	do {
+-		if (mace_read(port->status) & PS2_STATUS_TX_EMPTY) {
+-			mace_write(val, port->tx);
++		if (port->status & PS2_STATUS_TX_EMPTY) {
++			port->tx = val;
+ 			return 0;
+ 		}
+ 		udelay(50);
+@@ -72,14 +72,15 @@ static int maceps2_write(struct serio *d
+ 	return -1;
+ }
+ 
+-static irqreturn_t maceps2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t maceps2_interrupt(int irq, void *dev_id,
++				     struct pt_regs *regs)
+ {
+ 	struct serio *dev = dev_id;
+ 	struct mace_ps2port *port = ((struct maceps2_data *)dev->port_data)->port;
+-	unsigned int byte;
++	unsigned long byte;
+ 
+-	if (mace_read(port->status) & PS2_STATUS_RX_FULL) {
+-		byte = mace_read(port->rx);
++	if (port->status & PS2_STATUS_RX_FULL) {
++		byte = port->rx;
+ 		serio_interrupt(dev, byte & 0xff, 0, regs);
+         }
+ 
+@@ -96,13 +97,13 @@ static int maceps2_open(struct serio *de
+ 	}
+ 
+ 	/* Reset port */
+-	mace_write(PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET,
+-		   data->port->control);
++	data->port->control = PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET;
+ 	udelay(100);
+ 
+         /* Enable interrupts */
+-	mace_write(PS2_CONTROL_RX_CLOCK_ENABLE | PS2_CONTROL_TX_ENABLE |
+-		   PS2_CONTROL_RX_INT_ENABLE, data->port->control);
++	data->port->control = PS2_CONTROL_RX_CLOCK_ENABLE |
++			      PS2_CONTROL_TX_ENABLE |
++			      PS2_CONTROL_RX_INT_ENABLE;
+ 
+ 	return 0;
+ }
+@@ -111,8 +112,7 @@ static void maceps2_close(struct serio *
+ {
+ 	struct maceps2_data *data = (struct maceps2_data *)dev->port_data;
+ 
+-	mace_write(PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET,
+-		   data->port->control);
++	data->port->control = PS2_CONTROL_TX_CLOCK_DISABLE | PS2_CONTROL_RESET;
+ 	udelay(100);
+ 	free_irq(data->irq, dev);
+ }
+diff -urpNX dontdiff linux-2.6.10/drivers/media/video/Kconfig linux-2.6.10-mips/drivers/media/video/Kconfig
+--- linux-2.6.10/drivers/media/video/Kconfig	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/drivers/media/video/Kconfig	2004-12-28 20:06:38.000000000 +0100
+@@ -81,6 +81,14 @@ config VIDEO_W9966
+ 	  Check out <file:Documentation/video4linux/w9966.txt> for more
+ 	  information.
+ 
++config VIDEO_SWARM_7114H
++	tristate "Philips SAA7114H for SiByte BCM91250A"
++	depends on SIBYTE_SWARM && VIDEO_DEV && I2C_ALGO_SIBYTE
++	help
++	  Say Y or M to build the video4linux driver for the Philips
++	  SAA7114H video decoder on Broadcom SWARM board (BCM91250A).
++	  The decoder chip is on the BCM1250's "E2" 8-bit FIFO port.
++
+ config VIDEO_CPIA
+ 	tristate "CPiA Video For Linux"
+ 	depends on VIDEO_DEV
+@@ -145,7 +153,8 @@ config TUNER_3036
+ 
+ config VIDEO_VINO
+ 	tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
+-	depends on EXPERIMENTAL && VIDEO_DEV && SGI
++	depends on VIDEO_DEV && I2C && SGI_IP22 && EXPERIMENTAL
++	select I2C_ALGO_SGI
+ 	help
+ 	  Say Y here to build in support for the Vino video input system found
+ 	  on SGI Indy machines.
+diff -urpNX dontdiff linux-2.6.10/drivers/media/video/Makefile linux-2.6.10-mips/drivers/media/video/Makefile
+--- linux-2.6.10/drivers/media/video/Makefile	2004-12-24 22:34:31.000000000 +0100
++++ linux-2.6.10-mips/drivers/media/video/Makefile	2004-11-19 01:14:30.000000000 +0100
+@@ -49,6 +49,9 @@ obj-$(CONFIG_VIDEO_BUF)   += video-buf.o
+ obj-$(CONFIG_VIDEO_BUF_DVB) += video-buf-dvb.o
+ obj-$(CONFIG_VIDEO_BTCX)  += btcx-risc.o
+ 
++obj-$(CONFIG_VIDEO_SWARM_7114H) += swarm_saa7114h.o
++obj-$(CONFIG_TUNER_3036) += tuner-3036.o
++
+ obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
+ 
+ EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
+diff -urpNX dontdiff linux-2.6.10/drivers/media/video/swarm_saa7114h.c linux-2.6.10-mips/drivers/media/video/swarm_saa7114h.c
+--- linux-2.6.10/drivers/media/video/swarm_saa7114h.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/media/video/swarm_saa7114h.c	2005-01-11 00:40:22.000000000 +0100
+@@ -0,0 +1,1691 @@
++/* 
++   saa7114h - Philips SAA7114H video decoder driver
++
++   Copyright (C) 2001,2002,2003 Broadcom Corporation
++
++   From saa7111.c:
++     Copyright (C) 1998 Dave Perks <dperks at ibm.net>
++   From cpia.c:
++     (C) Copyright 1999-2000 Peter Pregler
++     (C) Copyright 1999-2000 Scott J. Bertin
++     (C) Copyright 1999-2000 Johannes Erdfelt <johannes at erdfelt.com>
++
++   This program is free software; you can redistribute it and/or modify
++   it under the terms of the GNU General Public License as published by
++   the Free Software Foundation; either version 2 of the License, or
++   (at your option) any later version.
++
++   This program is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
++   GNU General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, write to the Free Software
++   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++/*
++ * Important note: this driver is reasonably functional, and has been
++ * tested with the "camserv" v4l application.  But it primarily a
++ * proof-of-concept, and example for setting up FIFO-mode.
++ */
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/ctype.h>
++#include <linux/fs.h>
++#include <linux/vmalloc.h>
++#include <linux/kernel.h>
++#include <linux/major.h>
++#include <linux/slab.h>
++#include <linux/mm.h>
++#include <linux/pci.h>
++#include <linux/signal.h>
++#include <linux/proc_fs.h>
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/page.h>
++#include <linux/sched.h>
++#include <asm/segment.h>
++#include <linux/types.h>
++#include <linux/wrapper.h>
++#include <linux/smp_lock.h>
++#include <asm/hardirq.h>
++
++#include <linux/i2c.h>
++#include <linux/videodev.h>
++#include <linux/version.h>
++#include <asm/uaccess.h>
++
++#include <linux/i2c-algo-sibyte.h>
++
++#include <asm/sibyte/sb1250_regs.h>
++#include <asm/sibyte/sb1250_int.h>
++#include <asm/sibyte/sb1250_mac.h>
++#include <asm/sibyte/sb1250_dma.h>
++
++#define SAA_BRIGHTNESS	 0x0a
++#define SAA_CONTRAST	 0x0b
++#define SAA_SATURATION	 0x0c
++#define SAA_HUE		 0x0d
++
++#define DECODER_STATUS	 0x1f
++#define SLICER_STATUS_0	 0x60
++#define SLICER_STATUS_1	 0x61
++#define SLICER_STATUS_2	 0x62
++#define SCALER_STATUS	 0x8f
++
++#define NUM_FRAME	 2
++#define MAX_HORIZ	 720
++#define MAX_VERT	 480
++#define MIN_HORIZ	 180
++#define MIN_VERT	 120
++#define MAX_PER_PIXEL	 3
++#define MAX_FRAME_SIZE	 (MAX_HORIZ*MAX_VERT*MAX_PER_PIXEL)
++#define MAX_MMAP_SIZE	 (PAGE_ALIGN(MAX_FRAME_SIZE*NUM_FRAME))
++#define RAW_PER_PIXEL	 2
++#define RAW_LINE_PAD	 8
++#define RAW_LINE_SIZE	 (((MAX_HORIZ*RAW_PER_PIXEL)+RAW_LINE_PAD+0x1f) & ~0x1f)
++#define RAW_FRAME_SIZE	 (RAW_LINE_SIZE*MAX_VERT)
++
++#define NUM_DESCR	 64
++#define INTR_PKT_CNT	 8
++
++/* Extensions to videodev.h IOCTL definitions */
++#define VIDIOREADREG	_IOR('v', 50, int)
++#define VIDIOWRITEREG	_IOW('v', 50, int)
++#define VIDIOGRABFRAME	_IOR('v', 51, int)
++#define VIDIOSHOWEAV	_IOR('v', 52, int)
++
++#define IF_NAME "saa7114h"
++
++#define MAC2_CSR(r)	   (KSEG1 + A_MAC_REGISTER(2, r))
++#define MAC2_DMARX0_CSR(r) (KSEG1 + A_MAC_DMA_REGISTER(2, DMA_RX, 0, r))
++
++/* Options */
++#define DMA_DEINTERLACE	 1
++#define LAZY_READ	 1
++#define NULL_DMA	 0
++
++/* Debug filters */
++#define DBG_NULL	 0x0000
++#define DBG_IO		 0x0001
++#define DBG_DESCR	 0x0002
++#define DBG_INTR	 0x0004
++#define DBG_CONVERT	 0x0008
++#define DBG_FRAMING	 0x0010
++#define DBG_REGISTER	 0x0020
++#define DBG_CALL	 0x0040
++#define DBG_FRAMING_LOUD 0x0080
++
++/* XXXKW make this settable through /proc... */
++#define DEBUG_LVL	 (DBG_NULL)
++
++#if DEBUG_LVL
++#define DBG(l, p) do { if (DEBUG_LVL & l) p; } while (0)
++#else
++#define DBG(l, p)
++#endif
++
++/* ----------------------------------------------------------------------- */
++
++enum {
++	FRAME_READY,		/* Ready to grab into */
++	FRAME_GRABBING,		/* In the process of being grabbed into */
++	FRAME_DONE,		/* Finished grabbing, but not been synced yet */
++	FRAME_UNUSED,		/* Unused (belongs to driver, but can't be used) */
++};
++
++struct saa_frame {
++	uint8_t		 *data;
++	uint8_t		 *pos;
++	int		  width;
++	int		  height;
++	uint32_t	  size;
++	volatile int	  state;
++	wait_queue_head_t read_wait;
++};
++
++typedef struct fifo_descr_s {
++	uint64_t descr_a;
++	uint64_t descr_b;
++} fifo_descr_t;
++
++typedef unsigned long paddr_t;
++
++typedef struct fifo_s {
++	unsigned	 ringsz;
++	fifo_descr_t	*descrtab;
++	fifo_descr_t	*descrtab_end;
++	fifo_descr_t	*next_descr;
++	paddr_t		 descrtab_phys;
++	void		*dma_buf;	    /* DMA buffer */
++} fifo_t;
++
++struct saa7114h {
++	struct i2c_client    *client;
++	struct video_device  *vd;
++	struct video_window   vw;
++	struct video_picture  vp;
++	uint8_t		      reg[256];
++
++	fifo_t		 ff;
++	void		*frame_buf; /* hold frames for the client */
++	struct saa_frame frame[NUM_FRAME]; /* point into frame_buf */
++	int		 hwframe;
++	int		 swframe;
++
++	uint16_t depth;
++	uint16_t palette;
++	uint8_t	 bright;
++	uint8_t	 contrast;
++	uint8_t	 hue;
++	uint8_t	 sat;
++
++	struct proc_dir_entry *proc_entry;
++	struct semaphore       param_lock;
++	struct semaphore       busy_lock;
++
++	int	dma_enable;
++	int	opened;
++	int	irq;
++	int	interlaced;
++};
++
++static int saa7114h_probe(struct i2c_adapter *adap);
++static int saa7114h_detach(struct i2c_client *device);
++
++struct i2c_driver i2c_driver_saa7114h =
++{
++	name:		"saa7114h",		/* name */
++	id:		I2C_DRIVERID_SAA7114H,	/* ID */
++	flags:		I2C_DF_NOTIFY,		/* XXXKW do I care? */
++	attach_adapter: saa7114h_probe,
++	detach_client:	saa7114h_detach
++};
++
++/* -----------------------------------------------------------------------
++ * VM assist for MMAPed space
++ * ----------------------------------------------------------------------- */
++
++/* Given PGD from the address space's page table, return the kernel
++ * virtual mapping of the physical memory mapped at ADR.
++ */
++static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
++{
++	unsigned long ret = 0UL;
++	pmd_t *pmd;
++	pte_t *ptep, pte;
++
++	if (!pgd_none(*pgd)) {
++		pmd = pmd_offset(pgd, adr);
++		if (!pmd_none(*pmd)) {
++			ptep = pte_offset(pmd, adr);
++			pte = *ptep;
++			if (pte_present(pte)) {
++				ret = (unsigned long) page_address(pte_page(pte));
++				ret |= (adr & (PAGE_SIZE-1));
++			}
++		}
++	}
++	return ret;
++}
++
++/* Here we want the physical address of the memory.
++ * This is used when initializing the contents of the
++ * area and marking the pages as reserved.
++ */
++static inline unsigned long kvirt_to_pa(unsigned long adr)
++{
++	unsigned long va, kva, ret;
++
++	va = VMALLOC_VMADDR(adr);
++	kva = uvirt_to_kva(pgd_offset_k(va), va);
++	ret = __pa(kva);
++	return ret;
++}
++
++static void *rvmalloc(unsigned long size)
++{
++	void *mem;
++	unsigned long adr, page;
++
++	/* Round it off to PAGE_SIZE */
++	size += (PAGE_SIZE - 1);
++	size &= ~(PAGE_SIZE - 1);
++
++	mem = vmalloc_32(size);
++	if (!mem)
++		return NULL;
++
++	memset(mem, 0, size); /* Clear the ram out, no junk to the user */
++	adr = (unsigned long) mem;
++	while (size > 0) {
++		page = kvirt_to_pa(adr);
++		mem_map_reserve(virt_to_page(__va(page)));
++		adr += PAGE_SIZE;
++		if (size > PAGE_SIZE)
++			size -= PAGE_SIZE;
++		else
++			size = 0;
++	}
++
++	return mem;
++}
++
++static void rvfree(void *mem, unsigned long size)
++{
++	unsigned long adr, page;
++
++	if (!mem)
++		return;
++
++	size += (PAGE_SIZE - 1);
++	size &= ~(PAGE_SIZE - 1);
++
++	adr = (unsigned long) mem;
++	while (size > 0) {
++		page = kvirt_to_pa(adr);
++		mem_map_unreserve(virt_to_page(__va(page)));
++		adr += PAGE_SIZE;
++		if (size > PAGE_SIZE)
++			size -= PAGE_SIZE;
++		else
++			size = 0;
++	}
++	vfree(mem);
++}
++
++/* -----------------------------------------------------------------------
++ * Control interface (i2c)
++ * ----------------------------------------------------------------------- */
++
++static int saa7114h_reg_read(struct saa7114h *dev, unsigned char subaddr)
++{
++	return i2c_smbus_read_byte_data(dev->client, subaddr);
++}
++
++static int saa7114h_reg_write(struct saa7114h *dev, unsigned char subaddr, int data)
++{
++	return i2c_smbus_write_byte_data(dev->client, subaddr, data & 0xff);
++}
++
++static int saa7114h_reg_init(struct saa7114h *dev, unsigned const char *data, unsigned int len)
++{
++	int rc = 0;
++	int val;
++
++	while (len && !rc) {
++		dev->reg[data[0]] = data[1];
++		rc = saa7114h_reg_write(dev, data[0], data[1]);
++		if (!rc && (data[0] != 0)) {
++			val = saa7114h_reg_read(dev, data[0]);
++			if ((val < 0) || (val != data[1])) {
++				printk(KERN_ERR
++				       IF_NAME ": init readback mismatch reg %02x = %02x (should be %02x)\n",
++				       data[0], val, data[1]);
++			}
++		}
++		len -= 2;
++		data += 2;
++	}
++	return rc;
++}
++
++/* -----------------------------------------------------------------------
++ * /proc interface
++ * ----------------------------------------------------------------------- */
++
++#ifdef CONFIG_PROC_FS
++static struct proc_dir_entry *saa7114h_proc_root=NULL;
++
++static int decoder_read_proc(char *page, char **start, off_t off,
++			     int count, int *eof, void *data)
++{
++	char *out = page;
++	int len, status;
++	struct saa7114h *decoder = data;
++
++	out += sprintf(out, "  SWARM saa7114h\n------------------\n");
++	status = saa7114h_reg_read(decoder, DECODER_STATUS);
++	out += sprintf(out, "  Decoder status = %02x\n", status);
++	if (status & 0x80)
++		out += sprintf(out, "	 interlaced\n");
++	if (status & 0x40)
++		out += sprintf(out, "	 not locked\n");
++	if (status & 0x02)
++		out += sprintf(out, "	 Macrovision detected\n");
++	if (status & 0x01)
++		out += sprintf(out, "	 color\n");
++	out += sprintf(out, "  Brightness = %02x\n", decoder->bright);
++	out += sprintf(out, "  Contrast	  = %02x\n", decoder->contrast);
++	out += sprintf(out, "  Saturation = %02x\n", decoder->sat);
++	out += sprintf(out, "  Hue	  = %02x\n\n", decoder->hue);
++
++	out += sprintf(out, "  Scaler status  = %02x\n", 
++		       (int)saa7114h_reg_read(decoder, SCALER_STATUS));
++
++	len = out - page;
++	len -= off;
++	if (len < count) {
++		*eof = 1;
++		if (len <= 0) return 0;
++	} else
++		len = count;
++
++	*start = page + off;
++	return len;
++}
++
++static int decoder_write_proc(struct file *file, const char *buffer,
++			       unsigned long count, void *data)
++{
++	struct saa7114h *d = data;
++	int retval;
++	unsigned int cmd, reg, reg_val;
++	
++	if (down_interruptible(&d->param_lock))
++		return -ERESTARTSYS;
++
++#define VALUE \
++	({ \
++		char *_p; \
++		unsigned long int _ret; \
++		while (count && isspace(*buffer)) { \
++			buffer++; \
++			count--; \
++		} \
++		_ret = simple_strtoul(buffer, &_p, 16); \
++		if (_p == buffer) \
++			retval = -EINVAL; \
++		else { \
++			count -= _p - buffer; \
++			buffer = _p; \
++		} \
++		_ret; \
++	})
++	
++	retval = 0;
++	while (count && !retval) {
++		cmd = VALUE;
++		if (retval)
++			break;
++		switch (cmd) {
++		case 1:
++			reg = VALUE;
++			if (retval)
++				break;
++			reg_val = VALUE;
++			if (retval)
++				break;
++			printk(IF_NAME ": write reg %x <- %x\n", reg, reg_val);
++			if (saa7114h_reg_write(d, reg, reg_val) == -1)
++				retval = -EINVAL;
++			break;
++		case 2:
++			reg = VALUE;
++			if (retval)
++				break;
++			reg_val = saa7114h_reg_read(d, reg);
++			if (reg_val == -1)
++				retval = -EINVAL;
++			else
++				printk(IF_NAME ": read reg %x -> %x\n", reg, reg_val);
++			break;
++		default:
++			break;
++		}
++	}
++	up(&d->param_lock);
++	
++	return retval;
++}
++
++static void create_proc_decoder(struct saa7114h *decoder)
++{
++	char name[8];
++	struct proc_dir_entry *ent;
++	
++	if (!saa7114h_proc_root || !decoder)
++		return;
++
++	sprintf(name, "video%d", decoder->vd->minor);
++	
++	ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, saa7114h_proc_root);
++	if (!ent) {
++		printk(KERN_INFO IF_NAME ": Unable to initialize /proc/saa7114h/%s\n", name);
++		return;
++	}
++
++	ent->data = decoder;
++	ent->read_proc = decoder_read_proc;
++	ent->write_proc = decoder_write_proc;
++	ent->size = 3626;	/* XXXKW ??? */
++	decoder->proc_entry = ent;
++}
++
++static void destroy_proc_decoder(struct saa7114h *decoder)
++{
++	char name[7];
++	
++	if (!decoder || !decoder->proc_entry)
++		return;
++	
++	sprintf(name, "video%d", decoder->vd->minor);
++	remove_proc_entry(name, saa7114h_proc_root);
++	decoder->proc_entry = NULL;
++}
++
++static void proc_saa7114h_create(void)
++{
++	saa7114h_proc_root = create_proc_entry("saa7114h", S_IFDIR, 0);
++
++	if (saa7114h_proc_root)
++		saa7114h_proc_root->owner = THIS_MODULE;
++	else
++		printk(KERN_INFO IF_NAME ": Unable to initialize /proc/saa7114h\n");
++}
++
++static void proc_saa7114h_destroy(void)
++{
++	remove_proc_entry("saa7114h", 0);
++}
++#endif /* CONFIG_PROC_FS */
++
++
++/* -----------------------------------------------------------------------
++ * Initialization
++ * ----------------------------------------------------------------------- */
++
++static int dma_setup(struct saa7114h *d)
++{
++	int i;
++	void *curbuf;
++
++	/* Reset the port */
++	__raw_writeq(M_MAC_PORT_RESET, MAC2_CSR(R_MAC_ENABLE));
++	__raw_readq(MAC2_CSR(R_MAC_ENABLE));
++
++	/* Zero everything out, disable filters */
++	__raw_writeq(0, MAC2_CSR(R_MAC_TXD_CTL));
++	__raw_writeq(M_MAC_ALLPKT_EN, MAC2_CSR(R_MAC_ADFILTER_CFG));
++	__raw_writeq(V_MAC_RX_RD_THRSH(4) | V_MAC_RX_RL_THRSH(4),
++	      MAC2_CSR(R_MAC_THRSH_CFG));
++	for (i=0; i<MAC_CHMAP_COUNT; i++) {
++		__raw_writeq(0, MAC2_CSR(R_MAC_CHLO0_BASE+(i*8)));
++		__raw_writeq(0, MAC2_CSR(R_MAC_CHUP0_BASE+(i*8)));
++	}
++	for (i=0; i<MAC_HASH_COUNT; i++) {
++		__raw_writeq(0, MAC2_CSR(R_MAC_HASH_BASE+(i*8)));
++	}
++	for (i=0; i<MAC_ADDR_COUNT; i++) {
++		__raw_writeq(0, MAC2_CSR(R_MAC_ADDR_BASE+(i*8)));
++	}	 
++	
++	__raw_writeq(V_MAC_MAX_FRAMESZ(16*1024) | V_MAC_MIN_FRAMESZ(0),
++	      MAC2_CSR(R_MAC_FRAMECFG));
++
++	/* Select bypass mode */
++	__raw_writeq((M_MAC_BYPASS_SEL | V_MAC_BYPASS_CFG(K_MAC_BYPASS_EOP) | 
++	       M_MAC_FC_SEL | M_MAC_SS_EN | V_MAC_SPEED_SEL_1000MBPS),
++	      MAC2_CSR(R_MAC_CFG));
++
++	/* Set up the descriptor table */
++	d->ff.descrtab = kmalloc(NUM_DESCR * sizeof(fifo_descr_t), GFP_KERNEL);
++	d->ff.descrtab_phys = __pa(d->ff.descrtab);
++	d->ff.descrtab_end = d->ff.descrtab + NUM_DESCR;
++	d->ff.next_descr = d->ff.descrtab;
++	d->ff.ringsz = NUM_DESCR;
++#if 0
++	/* XXXKW this won't work because the physical may not be
++	   contiguous; how do I handle a bigger alloc then? */
++	d->ff.dma_buf = rvmalloc(RAW_LINE_SIZE*NUM_DESCR);
++	printk(KERN_DEBUG IF_NAME ": DMA buffer allocated (%p)\n",
++	       d->ff.dma_buf);
++#else
++	d->ff.dma_buf = kmalloc(RAW_LINE_SIZE*NUM_DESCR, GFP_KERNEL);
++#endif
++	if (!d->ff.dma_buf) {
++		printk(KERN_ERR IF_NAME ": couldn't allocate DMA buffer\n");
++		return -ENOMEM;
++	}
++	memset(d->ff.dma_buf, 0, RAW_LINE_SIZE*NUM_DESCR);
++
++	for (i=0, curbuf=d->ff.dma_buf; i<d->ff.ringsz; i++, curbuf+=RAW_LINE_SIZE) {
++		d->ff.descrtab[i].descr_a = (__pa(curbuf) |
++					     V_DMA_DSCRA_A_SIZE(RAW_LINE_SIZE >> 5));
++		d->ff.descrtab[i].descr_b = 0;
++	}
++
++	__raw_writeq(V_DMA_INT_PKTCNT(INTR_PKT_CNT) | M_DMA_EOP_INT_EN |
++	      V_DMA_RINGSZ(d->ff.ringsz) | M_DMA_TDX_EN,
++	      MAC2_DMARX0_CSR(R_MAC_DMA_CONFIG0));
++	__raw_writeq(M_DMA_L2CA, MAC2_DMARX0_CSR(R_MAC_DMA_CONFIG1));
++	__raw_writeq(d->ff.descrtab_phys, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_BASE));
++
++	/* Enable interrupts and DMA */
++	__raw_writeq(M_MAC_INT_EOP_COUNT<<S_MAC_RX_CH0, MAC2_CSR(R_MAC_INT_MASK));
++	__raw_writeq(M_MAC_RXDMA_EN0 | M_MAC_BYP_RX_ENABLE, MAC2_CSR(R_MAC_ENABLE));
++
++	return 0;
++}
++
++/* -----------------------------------------------------------------------
++ * v4linux helpers - color conversion, etc  (taken from cpia.c)
++ * ----------------------------------------------------------------------- */
++
++#define LIMIT(x) ((((x)>0xffffff)?0xff0000:(((x)<=0xffff)?0:(x)&0xff0000))>>16)
++
++static void yuvconvert_inplace(uint8_t *data, uint32_t in_uyvy, int out_fmt, int mmap)
++{
++	int y, u, v, r, g, b, y1;
++	uint8_t *src, *dst;
++
++	if (out_fmt == VIDEO_PALETTE_RGB24) {
++		src = (uint8_t *)((int)data + in_uyvy);
++		dst = (uint8_t *)((int)data + in_uyvy + (in_uyvy >> 1));
++		DBG(DBG_CONVERT, printk(KERN_DEBUG "inplace: %p %p %p\n", data, src, dst));
++		while (src > data) {
++			if ((int)(src-data) < 4)
++				break;
++				//printk("freaky %p %p\n", src, data);
++			y1 = (*(--src) - 16) * 76310;
++			v = *(--src) - 128;
++			y = (*(--src) - 16) * 76310;
++			u = *(--src) - 128;
++			r = 104635 * v;
++			g = -25690 * u + -53294 * v;
++			b = 132278 * u;
++			/* XXXKW what on earth is up with mmap? */
++			if (mmap) {
++				*(--dst) = LIMIT(r+y1);
++				*(--dst) = LIMIT(g+y1);
++				*(--dst) = LIMIT(b+y1);
++				*(--dst) = LIMIT(r+y);
++				*(--dst) = LIMIT(g+y);
++				*(--dst) = LIMIT(b+y);
++			} else {
++				*(--dst) = LIMIT(b+y1);
++				*(--dst) = LIMIT(g+y1);
++				*(--dst) = LIMIT(r+y1);
++				*(--dst) = LIMIT(b+y);
++				*(--dst) = LIMIT(g+y);
++				*(--dst) = LIMIT(r+y);
++			}
++		}
++	}
++}
++
++static int saa7114h_get_cparams(struct saa7114h *decoder)
++{
++	/* XXX check for error code */
++	decoder->bright	    = saa7114h_reg_read(decoder, SAA_BRIGHTNESS);
++	decoder->contrast   = saa7114h_reg_read(decoder, SAA_CONTRAST);
++	decoder->sat	    = saa7114h_reg_read(decoder, SAA_SATURATION);
++	decoder->hue	    = saa7114h_reg_read(decoder, SAA_HUE);
++
++	decoder->vp.brightness = (uint16_t)decoder->bright << 8;
++	decoder->vp.contrast   = (uint16_t)decoder->contrast << 9;
++	decoder->vp.colour     = decoder->sat << 9;
++	decoder->vp.hue	       = ((int16_t)decoder->hue + 128) << 8;
++	return 0;
++}
++
++static int saa7114h_set_cparams(struct saa7114h *decoder)
++{
++	decoder->bright	  = decoder->vp.brightness >> 8;
++	decoder->contrast = decoder->vp.contrast >> 9;
++	decoder->sat	  = decoder->vp.colour >> 9;
++	decoder->hue	  = (uint8_t)((int8_t)(decoder->vp.hue >> 8) - 128);
++
++	return (saa7114h_reg_write(decoder, SAA_BRIGHTNESS, decoder->bright) ||
++		saa7114h_reg_write(decoder, SAA_CONTRAST, decoder->contrast) ||
++		saa7114h_reg_write(decoder, SAA_SATURATION, decoder->sat) ||
++		saa7114h_reg_write(decoder, SAA_HUE, decoder->hue));
++}
++
++/* -----------------------------------------------------------------------
++ * Custom IOCTL support
++ * ----------------------------------------------------------------------- */
++
++unsigned char eav[625][2];
++static int grab_frame(struct saa7114h *d, void *user_buf, int print_eav)
++{
++	int cur_idx = 0;
++	int to_go = 625;
++	int delta;
++	int i, len, eav_val, sav_val;
++	int started = 0;
++	uint8_t *buf;
++	fifo_descr_t *cur_d;
++	int swptr = d->ff.next_descr - d->ff.descrtab;
++	int hwptr;
++
++	DBG(DBG_CALL, printk(IF_NAME ": grabbing frame\n"));
++
++	/* Check for Macrovision -- if it's on, DMA won't happen */
++	if (saa7114h_reg_read(d, DECODER_STATUS) & 0x2)
++		return -EACCES;
++
++	__raw_writeq(d->ff.ringsz, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT));
++	do {
++		hwptr = (unsigned) (((__raw_readq(MAC2_DMARX0_CSR(R_MAC_DMA_CUR_DSCRADDR)) &
++				      M_DMA_CURDSCR_ADDR) -
++				     d->ff.descrtab_phys) /
++				    sizeof(fifo_descr_t));
++		delta = (hwptr + d->ff.ringsz - swptr) % d->ff.ringsz;
++		
++		if (delta == 0) {
++#if 0
++			uint64_t val = __raw_readq(MAC2_DMARX0_CSR(R_MAC_STATUS));
++			printk("mac status: %08x%08x\n",
++			       (u32)(val >> 32), (u32)(val&0xffffffff));
++#endif
++		}
++
++		for (i=0; i<delta; i++) {
++			cur_d = d->ff.next_descr;
++			if (++d->ff.next_descr == d->ff.descrtab_end)
++				d->ff.next_descr = d->ff.descrtab;
++			
++			if (!(cur_d->descr_a & M_DMA_ETHRX_SOP)) {
++				printk("bogus RX\n");
++				continue;
++			}
++			cur_d->descr_a &= ~M_DMA_ETHRX_SOP;
++			len = G_DMA_DSCRB_PKT_SIZE(cur_d->descr_b);
++			buf = (uint8_t *)__va(cur_d->descr_a & M_DMA_DSCRA_A_ADDR);
++			if (len != (d->vw.width*RAW_PER_PIXEL)+RAW_LINE_PAD) {
++				printk("funny size %d\n", len);
++				continue;
++			}
++			eav_val = buf[1];
++			sav_val = buf[5];
++			if (eav_val == 0xf1) { /* end of field 2, V-blank */
++				if (started) {
++					started = 0;
++					delta = to_go = 0;
++					/* just let DMA finish in background */
++				} else {
++					started = 1;
++				}
++			}
++			if (started) {
++				eav[cur_idx][0] = eav_val;
++				eav[cur_idx++][1] = sav_val;
++				if (copy_to_user(user_buf, &buf[6], 1440))
++					return -EFAULT;
++				user_buf += 1440;
++			}
++		}
++		swptr = hwptr;
++		if (delta) {
++			if (started)
++				to_go -= delta;
++			if (delta > to_go)
++				delta = to_go;
++			__raw_writeq(delta, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT));
++		}
++	} while (to_go);
++
++	if (print_eav) {
++		for (i=0; i<cur_idx; i++) {
++			printk("%3d: %02x | %02x\n", i, eav[i][0], eav[i][1]);
++		}
++	}
++
++	return cur_idx;
++}
++
++/* -----------------------------------------------------------------------
++ * Interrupt handler
++ * ----------------------------------------------------------------------- */
++
++unsigned long int_count = 0;
++
++static void saa7114h_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct saa7114h *d = dev_id;
++	uint64_t status_val;
++	fifo_descr_t *cur_d;
++	int i, delta, len;
++	uint8_t *buf, eav_val;
++	int swptr = d->ff.next_descr - d->ff.descrtab;
++	int hwptr;
++
++	status_val = __raw_readq(MAC2_CSR(R_MAC_STATUS));
++
++	/* Process finished decsriptors */
++	hwptr = (unsigned) (((__raw_readq(MAC2_DMARX0_CSR(R_MAC_DMA_CUR_DSCRADDR)) &
++			      M_DMA_CURDSCR_ADDR) - d->ff.descrtab_phys) /
++			    sizeof(fifo_descr_t));
++	delta = (hwptr + d->ff.ringsz - swptr) % d->ff.ringsz;
++	if (!delta) {
++		if (status_val & M_MAC_INT_EOP_SEEN<<S_MAC_RX_CH0) {
++			/* Must have wrapped since the last interrupt */
++			delta = d->ff.ringsz;
++		} else {
++			/* XXXKW why would this happen? */
++			return;
++		}
++	}
++
++	for (i=0; i<delta; i++) {
++		cur_d = d->ff.next_descr;
++		if (++d->ff.next_descr == d->ff.descrtab_end)
++			d->ff.next_descr = d->ff.descrtab;
++		
++		if (!(cur_d->descr_a & M_DMA_ETHRX_SOP)) {
++			printk(KERN_DEBUG "bogus RX\n");
++			continue;
++		}
++		cur_d->descr_a &= ~M_DMA_ETHRX_SOP;
++		if (!d->dma_enable)
++			continue;
++		
++		len = G_DMA_DSCRB_PKT_SIZE(cur_d->descr_b);
++		buf = (uint8_t *)__va(cur_d->descr_a & M_DMA_DSCRA_A_ADDR);
++		if (len != (d->vw.width*RAW_PER_PIXEL)+RAW_LINE_PAD) {
++			printk(KERN_DEBUG "funny size %d\n", len);
++//				  continue;
++		}
++		len -= RAW_LINE_PAD;
++		eav_val = buf[1];
++		DBG(DBG_FRAMING_LOUD,
++		    printk(KERN_DEBUG "eav: %02x len: %d\n", eav_val, len));
++		if (eav_val == 0xf1) { /* end of field 2, V-blank: start-of-frame */
++			switch (d->frame[d->hwframe].state) {
++			case FRAME_UNUSED:
++				DBG(DBG_FRAMING,
++				    printk(KERN_ERR "capture to unused frame %d\n", 
++					   d->hwframe));
++				break;
++			case FRAME_READY:
++				DBG(DBG_FRAMING,
++				    printk(KERN_DEBUG "frame started %d\n",
++					   d->hwframe));
++				/* start this frame (skip eav/sav) */
++				memcpy(d->frame[d->hwframe].pos, &buf[6], len);
++#if DMA_DEINTERLACE
++				if (!d->interlaced)
++					memcpy(d->frame[d->hwframe].pos-len, &buf[6], len);
++				d->frame[d->hwframe].pos += len*2;
++#else
++				d->frame[d->hwframe].pos += len;
++#endif
++				d->frame[d->hwframe].state = FRAME_GRABBING;
++				/* XXXKW check pos overflow */
++				break;
++			case FRAME_GRABBING:
++				/* kick over to new frame */
++				d->frame[d->hwframe].size = d->frame[d->hwframe].pos -
++					d->frame[d->hwframe].data;
++				d->frame[d->hwframe].state = FRAME_DONE;
++				DBG(DBG_FRAMING,
++				    printk(KERN_DEBUG "frame finished %d\n",
++					   d->frame[d->hwframe].size));
++				/* wake up a waiting reader */
++				DBG(DBG_IO, printk(KERN_DEBUG "wakeup\n"));
++				wake_up(&d->frame[d->hwframe].read_wait);
++				d->hwframe = (d->hwframe + 1) % NUM_FRAME;
++				if (d->frame[d->hwframe].state == FRAME_READY) {
++					/* start this frame */
++					DBG(DBG_FRAMING,
++					    printk(KERN_DEBUG "frame bumped %d\n",
++						   d->hwframe));
++					memcpy(d->frame[d->hwframe].pos, &buf[6], len);
++#if DMA_DEINTERLACE
++					if (!d->interlaced)
++						memcpy(d->frame[d->hwframe].pos-len, &buf[6], len);
++					d->frame[d->hwframe].pos += len*2;
++#else
++					d->frame[d->hwframe].pos += len;
++#endif
++					d->frame[d->hwframe].state = FRAME_GRABBING;
++				} else {
++					/* drop on the floor,
++					   note that we've stopped DMA'ing */
++					DBG(DBG_FRAMING,
++					    printk(KERN_DEBUG "frame capture halted\n"));
++					d->dma_enable = 0;
++				}
++				break;
++			case FRAME_DONE:
++				/* drop on the floor (must be waiting for sw) */
++				DBG(DBG_FRAMING,
++				    printk(KERN_DEBUG "frame capture halted\n"));
++				d->dma_enable = 0;
++				break;
++			}
++		} else {
++			switch (d->frame[d->hwframe].state) {
++			case FRAME_UNUSED:
++				DBG(DBG_FRAMING,
++				    printk(KERN_ERR "capture to unused frame %d\n",
++					   d->hwframe));
++				break;
++			case FRAME_READY:
++				/* drop on the floor (must have dropped something) */
++				DBG(DBG_FRAMING_LOUD,
++				    printk(KERN_DEBUG "missed SOF\n"));
++				break;
++			case FRAME_DONE:
++				/* drop on the floor (must be waiting for sw) */
++				DBG(DBG_FRAMING,
++				    printk(KERN_DEBUG "frame overflow\n"));
++				d->dma_enable = 0;
++				break;
++			case FRAME_GRABBING:
++#if DMA_DEINTERLACE
++				if (eav_val == 0xb6) {
++					d->frame[d->hwframe].pos = d->frame[d->hwframe].data;
++				}
++				memcpy(d->frame[d->hwframe].pos, &buf[6], len);
++				if (!d->interlaced)
++					memcpy(d->frame[d->hwframe].pos-len, &buf[6], len);
++				d->frame[d->hwframe].pos += len*2;
++#else
++				memcpy(d->frame[d->hwframe].pos, &buf[6], len);
++				d->frame[d->hwframe].pos += len;
++#endif
++				/* XXXKW check pos overflow */
++				break;
++			}
++		}
++	}
++	
++	if (d->dma_enable) {
++		__raw_writeq(delta, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT));
++		DBG(DBG_DESCR,
++		    printk(KERN_DEBUG IF_NAME ": interrupt adds %d -> %d descrs\n",
++			   delta, (int)__raw_readq(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT))));
++	}
++}
++
++/* -----------------------------------------------------------------------
++ * /dev/video interface
++ * ----------------------------------------------------------------------- */
++
++static int saa7114h_open(struct video_device *vd, int nb)
++{
++	struct saa7114h *d = vd->priv;
++	uint32_t status;
++
++	if (!d || d->opened)
++		return -EBUSY;
++
++	d->opened = 1;
++	DBG(DBG_CALL, printk(KERN_DEBUG IF_NAME ": open\n"));
++
++	/* XXKW Should check this periodically!? */
++	status = saa7114h_reg_read(d, DECODER_STATUS);
++	d->interlaced = ((status & 0x80) != 0);
++
++#if !NULL_DMA
++	if (d->dma_enable) {
++		printk(IF_NAME ": open found DMA on?!\n");
++#if LAZY_READ
++	}
++#else
++	} else {
++		int descr;
++		d->dma_enable = 1;
++		DBG(DBG_DESCR, printk(IF_NAME ": open enabling DMA\n"));
++		/* Force capture to start into frame buffer 0 */
++		descr = __raw_readq(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT));
++		DBG(DBG_DESCR,
++		    printk(IF_NAME ": open adds %d -> %d descrs\n",
++			   d->ff.ringsz-desc, descr));
++		__raw_writeq(d->ff.ringsz-descr, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT));
++	}
++#endif
++#endif
++
++	return 0;
++}
++
++static void saa7114h_release(struct video_device *vd)
++{
++	struct saa7114h *d = vd->priv;
++
++	DBG(DBG_CALL, printk(KERN_DEBUG IF_NAME ": release\n"));
++	d->opened = 0;
++	d->dma_enable = 0;
++
++	/* XXXKW do a clean drain of outstanding DMAs? toss leftover
++	   buffer contents to avoid stale pictures? */
++
++	return;
++}
++
++static long saa7114h_read(struct video_device *vd, char *buf,
++			  unsigned long count, int noblock)
++{
++	struct saa7114h *d = vd->priv;
++	int descr, status;
++
++	if (!d)
++		return -ENODEV;
++
++	/* XXKW Should check this periodically!? */
++	status = saa7114h_reg_read(d, DECODER_STATUS);
++//	  d->interlaced = ((status & 0x80) != 0);
++	
++#if !NULL_DMA
++#if LAZY_READ
++	if (!d->dma_enable) {
++		DBG(DBG_DESCR, printk(KERN_DEBUG IF_NAME ": enabling DMA\n"));
++		/* Give the buffer to the DMA engine (force ptr reset) */
++		d->swframe = d->hwframe;
++		d->frame[d->swframe].state = FRAME_READY;
++#if DMA_DEINTERLACE
++		d->frame[d->swframe].pos = d->frame[d->swframe].data+d->vw.width*RAW_PER_PIXEL;
++#else
++		d->frame[d->swframe].pos = d->frame[d->swframe].data;
++#endif
++		/* Fire up the DMA engine again if it stopped */
++		d->dma_enable = 1;
++		descr = __raw_readq(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT));
++		__raw_writeq(d->ff.ringsz-descr, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT));
++	}
++#endif
++#endif
++
++	/* XXXKW mmap/read mixture could break the swframe sequence */
++
++	if (d->frame[d->swframe].state != FRAME_DONE) {
++		if (noblock)
++			return -EAGAIN;
++		else {
++			DBG(DBG_IO,
++			    printk(KERN_DEBUG IF_NAME ": sleeping for frame\n"));
++			interruptible_sleep_on(&d->frame[d->swframe].read_wait);
++			DBG(DBG_IO,
++			    printk(KERN_DEBUG IF_NAME ": awakened\n"));
++			if (signal_pending(current))
++				return -ERESTARTSYS;
++		}
++	}
++
++	if (count < d->frame[d->swframe].size)
++		return -EFAULT;
++
++	count = d->frame[d->swframe].size;
++	yuvconvert_inplace(d->frame[d->swframe].data, d->frame[d->swframe].size, d->vp.palette, 0);
++	copy_to_user(buf, d->frame[d->swframe].data, d->frame[d->swframe].size);
++	d->swframe = (d->swframe + 1) % NUM_FRAME;
++	/* XXXKW doesn't do format conversion!!! */
++#if !NULL_DMA
++#if !LAZY_READ
++	/* XXXKW Fire up the DMA engine again if it stopped ??? */
++	if (!d->dma_enable) {
++		DBG(DBG_DESCR, printk(KERN_DEBUG IF_NAME ": enabling DMA\n"));
++		/* Fire up the DMA engine again if it stopped */
++		d->dma_enable = 1;
++		descr = __raw_readq(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT));
++		__raw_writeq(d->ff.ringsz-descr, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT));
++	}
++#endif
++#endif
++
++	return count;
++}
++
++static int saa7114h_ioctl(struct video_device *vd, unsigned int cmd, void *arg)
++{
++	struct saa7114h *d = vd->priv;
++	int val, reg, retval = 0;
++
++	if (!d)
++		return -ENODEV;
++
++	switch (cmd) {
++	case VIDIOCGCHAN:
++	{
++		struct video_channel v;
++
++		if (copy_from_user(&v, arg, sizeof(v))) {
++			retval = -EFAULT;
++			break;
++		}
++		if (v.channel != 0) {
++			retval = -EINVAL;
++			break;
++		}
++
++		v.channel = 0;
++		strcpy(v.name, "Camera");
++		v.tuners = 0;
++		v.flags = 0;
++		v.type = VIDEO_TYPE_CAMERA;
++		v.norm = 0;
++
++		if (copy_to_user(arg, &v, sizeof(v)))
++			retval = -EFAULT;
++		break;
++	}
++	
++	case VIDIOCSCHAN:
++	{
++		int v;
++
++		if (copy_from_user(&v, arg, sizeof(v)))
++			retval = -EFAULT;
++
++		if (retval == 0 && v != 0)
++			retval = -EINVAL;
++
++		break;
++	}
++
++	case VIDIOCGCAP:
++	{
++		struct video_capability b;
++
++		strcpy(b.name, "Philips SAA7114H Decoder");
++		b.type = VID_TYPE_CAPTURE /* | VID_TYPE_TELETEXT */ | VID_TYPE_SCALES;
++		b.channels = 1;
++		b.audios = 0;
++		b.maxwidth = MAX_HORIZ;
++		b.maxheight = MAX_VERT;
++		/* XXXKW find real values */
++		b.minwidth = 48;
++		b.minheight = 48;
++
++		if (copy_to_user(arg, &b, sizeof(b)))
++			retval = -EFAULT;
++
++		break;
++	}
++
++	/* image properties */
++	case VIDIOCGPICT:
++		if (copy_to_user(arg, &d->vp, sizeof(struct video_picture)))
++			retval = -EFAULT;
++		break;
++		
++	case VIDIOCSPICT:
++	{
++		struct video_picture vp;
++
++		/* copy_from_user */
++		if (copy_from_user(&vp, arg, sizeof(vp))) {
++			retval = -EFAULT;
++			break;
++		}
++
++		down(&d->param_lock);
++		/* brightness, colour, contrast need not check 0-65535 */
++		memcpy( &d->vp, &vp, sizeof(vp) );
++		/* update cam->params.colourParams */
++		saa7114h_set_cparams(d);
++		up(&d->param_lock);
++		break;
++	}
++
++	/* get/set capture window */
++	case VIDIOCGWIN:
++		if (copy_to_user(arg, &d->vw, sizeof(struct video_window)))
++			retval = -EFAULT;
++		break;
++	
++	case VIDIOCSWIN:
++	{
++		/* copy_from_user, check validity, copy to internal structure */
++		struct video_window vw;
++		if (copy_from_user(&vw, arg, sizeof(vw))) {
++			retval = -EFAULT;
++			break;
++		}
++
++		if (vw.clipcount != 0) {    /* clipping not supported */
++			retval = -EINVAL;
++			break;
++		}
++		if (vw.clips != NULL) {	    /* clipping not supported */
++			retval = -EINVAL;
++			break;
++		}
++		if ((vw.width > MAX_HORIZ || vw.width < MIN_HORIZ) ||
++		    (vw.height > MAX_VERT || vw.height < MIN_VERT)) {
++			retval = -EINVAL;
++			break;
++		}
++
++		/* we set the video window to something smaller or equal to what
++		 * is requested by the user???
++		 */
++		down(&d->param_lock);
++		if (vw.width != d->vw.width || vw.height != d->vw.height) {
++			uint32_t scale_factor;
++			/* XXXKW base percentage on input stream, not MAX? */
++
++			/* Assert scaler reset */
++			saa7114h_reg_write(d, 0x88, 0x98);
++
++			/* Vertical scaling */
++			scale_factor = (MAX_VERT*1024) / vw.height;
++			saa7114h_reg_write(d, 0x9e, vw.height & 0xff);
++			saa7114h_reg_write(d, 0x9f, (vw.height >> 8) & 0xf);
++			saa7114h_reg_write(d, 0xb0, scale_factor & 0xff);
++			saa7114h_reg_write(d, 0xb1, (scale_factor >> 8) & 0xff);
++			saa7114h_reg_write(d, 0xb2, scale_factor & 0xff);
++			saa7114h_reg_write(d, 0xb3, (scale_factor >> 8) & 0xff);
++			/* Horizontal scaling */
++			scale_factor = (MAX_HORIZ*1024) / vw.width;
++			saa7114h_reg_write(d, 0x9c, vw.width & 0xff);
++			saa7114h_reg_write(d, 0x9d, (vw.width >> 8) & 0xf);
++			saa7114h_reg_write(d, 0xa8, scale_factor & 0xff);
++			saa7114h_reg_write(d, 0xa9, (scale_factor >> 8) & 0xff);
++			saa7114h_reg_write(d, 0xac, (scale_factor >> 1) & 0xff);
++			saa7114h_reg_write(d, 0xad, (scale_factor >> 9) & 0xff);
++#if 0
++			/* prescaler
++			saa7114h_reg_write(d, 0xa0, 2);
++			saa7114h_reg_write(d, 0xa1, 1);
++			saa7114h_reg_write(d, 0xa2, 1);
++			*/
++#endif
++
++			/* Release scaler reset */
++			saa7114h_reg_write(d, 0x88, 0xb8);
++			d->vw.width = vw.width;
++			d->vw.height = vw.height;
++		}
++		up(&d->param_lock);
++		break;
++	}
++
++	/* mmap interface */
++	case VIDIOCGMBUF:
++	{
++		struct video_mbuf vm;
++		int i;
++
++		memset(&vm, 0, sizeof(vm));
++		vm.size = MAX_FRAME_SIZE*NUM_FRAME;
++		vm.frames = NUM_FRAME;
++		for (i = 0; i < NUM_FRAME; i++)
++			vm.offsets[i] = MAX_FRAME_SIZE * i;
++
++		if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
++			retval = -EFAULT;
++
++		break;
++	}
++
++	case VIDIOCMCAPTURE:
++	{
++		struct video_mmap vm;
++		int descr, status;
++
++		if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm))) {
++			retval = -EFAULT;
++			break;
++		}
++		if (vm.frame<0||vm.frame>NUM_FRAME) {
++			retval = -EINVAL;
++			break;
++		}
++
++		DBG(DBG_CALL,
++		    printk(KERN_DEBUG IF_NAME ":ioctl MCAPTURE %d\n", vm.frame));
++
++		d->vp.palette = vm.format;
++		/* XXXKW set depth? */
++		/* XXXKW match/update for vm.width, vm.height */
++
++		/* XXKW Should check this periodically!? */
++		status = saa7114h_reg_read(d, DECODER_STATUS);
++//		  d->interlaced = ((status & 0x80) != 0);
++
++		/* Give the buffer to the DMA engine */
++		/* XXXKW vm.frame vs d->swframe!!  mmap/read mismatch */
++#if DMA_DEINTERLACE
++		d->frame[vm.frame].pos = d->frame[vm.frame].data + d->vw.width*RAW_PER_PIXEL;
++#else
++		d->frame[vm.frame].pos = d->frame[vm.frame].data;
++#endif
++#if !NULL_DMA
++		d->frame[vm.frame].state = FRAME_READY;
++		/* Fire up the DMA engine again if it stopped */
++		if (!d->dma_enable) {
++			d->dma_enable = 1;
++			d->hwframe = d->swframe = vm.frame;
++			descr = __raw_readq(MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT));
++			DBG(DBG_DESCR,
++			    printk(KERN_DEBUG IF_NAME ": capture adds %d -> %d descrs\n",
++				   d->ff.ringsz-descr, descr));
++			__raw_writeq(d->ff.ringsz-descr, MAC2_DMARX0_CSR(R_MAC_DMA_DSCR_CNT));
++		}
++#endif
++		break;
++	}
++
++	case VIDIOCSYNC:
++	{
++		int frame;
++
++		if (copy_from_user((void *)&frame, arg, sizeof(int))) {
++			retval = -EFAULT;
++			break;
++		}
++
++		if (frame<0 || frame >= NUM_FRAME) {
++			retval = -EINVAL;
++			break;
++		}
++
++		DBG(DBG_CALL, printk(KERN_DEBUG IF_NAME ":ioctl CSYNC %d\n", frame));
++
++		switch (d->frame[frame].state) {
++		case FRAME_UNUSED:
++			DBG(DBG_IO,
++			    printk(KERN_ERR IF_NAME ":sync to unused frame %d\n", frame));
++			retval = -EINVAL;
++			break;
++
++		case FRAME_READY:
++		case FRAME_GRABBING:
++			DBG(DBG_IO,
++			    printk(KERN_DEBUG IF_NAME ": sleeping for frame %d\n", frame));
++			interruptible_sleep_on(&d->frame[frame].read_wait);
++			DBG(DBG_IO,
++			    printk(KERN_DEBUG IF_NAME ": awakened\n"));
++			if (signal_pending(current))
++				return -ERESTARTSYS;
++		case FRAME_DONE:
++#if !NULL_DMA
++			yuvconvert_inplace(d->frame[frame].data,
++					   d->frame[frame].size,
++					   d->vp.palette, 1);
++			d->frame[frame].state = FRAME_UNUSED;
++#endif
++			DBG(DBG_IO,
++			    printk(KERN_DEBUG IF_NAME ": sync finished %d\n",
++				   frame));
++			break;
++		}
++		break;
++	}
++
++	case VIDIOREADREG:
++		reg = *(int *)arg;
++		DBG(DBG_REGISTER, printk(KERN_DEBUG IF_NAME ": read of %02x\n", reg));
++		if ((reg > 0xEF) || (reg < 0))
++			return -EINVAL;
++		val = saa7114h_reg_read((struct saa7114h *)vd->priv, reg);
++		if (val == -1)
++			return -EIO;
++		*(int *)arg = val;
++		break;
++	case VIDIOWRITEREG:
++		if (copy_from_user(&reg, arg, sizeof(int)) ||
++		    copy_from_user(&val, arg+sizeof(int), sizeof(int)))
++			return -EFAULT;
++		DBG(DBG_REGISTER, printk(KERN_DEBUG IF_NAME ": write of %02x <- %02x\n", reg, val));
++		if ((reg > 0xEF) || (reg < 0))
++			return -EINVAL;
++		val = saa7114h_reg_write((struct saa7114h *)vd->priv, reg, val);
++		if (val == -1)
++			return -EIO;
++		break;
++	case VIDIOGRABFRAME:
++		return grab_frame((struct saa7114h *)vd->priv, arg, 0);
++	case VIDIOSHOWEAV:
++		return grab_frame((struct saa7114h *)vd->priv, arg, 1);
++	default:
++		retval = -EINVAL;
++		break;
++	}
++
++	return retval;
++}
++
++static int saa7114h_mmap(struct video_device *vd, const char *adr,
++			 unsigned long size)
++{
++	struct saa7114h *d = vd->priv;
++	unsigned long start = (unsigned long)adr;
++	unsigned long page, pos;
++
++	if (!d)
++		return -ENODEV;
++
++	if (size > MAX_MMAP_SIZE) {
++		printk("mmap: bad size %lu > %lu\n", size, MAX_MMAP_SIZE);
++		return -EINVAL;
++	}
++
++	/* make this _really_ smp-safe */
++	if (down_interruptible(&d->busy_lock))
++		return -EINTR;
++
++	pos = (unsigned long)(d->frame_buf);
++	while (size > 0) {
++		page = kvirt_to_pa(pos);
++		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
++			up(&d->busy_lock);
++			return -EAGAIN;
++		}
++		start += PAGE_SIZE;
++		pos += PAGE_SIZE;
++		if (size > PAGE_SIZE)
++			size -= PAGE_SIZE;
++		else
++			size = 0;
++	}
++	up(&d->busy_lock);
++
++	return 0;
++}
++
++/* -----------------------------------------------------------------------
++ * Device probing and initialization
++ * ----------------------------------------------------------------------- */
++
++/* Default values to program into SAA7114H */
++static const unsigned char reg_init[] =	{
++	0x00, 0x00,	/* 00 - ID byte */
++
++	/*front end */
++	0x01, 0x08,	/* 01 - Horizontal increment -> recommended delay */
++	0x02, 0xC4,	/* 02 - AI Control 1 (CVBS AI23) */
++	0x03, 0x10,	/* 03 - AI Control 2 */
++	0x04, 0x90,	/* 04 - AI Control 3 (Gain ch 1) */
++	0x05, 0x90,	/* 05 - AI Control 4 (Gain ch 2) */
++	
++	/* decoder */
++	0x06, 0xEB,	/* 06 - Horiz sync start */
++	0x07, 0xE0,	/* 07 - Horiz sync stop */
++	0x08, 0x98,	/* 08 - Sync control */
++	0x09, 0x40,	/* 09 - L Control */
++	0x0a, 0x80,	/* 0a - L Brightness */
++	0x0b, 0x44,	/* 0b - L Contrast */
++	0x0c, 0x40,	/* 0c - C Saturation */
++	0x0d, 0x00,	/* 0d - C Hue */
++	0x0e, 0x89,	/* 0e - C Control 1 */
++	0x0f, 0x0f,	/* 0f - C Gain (??? 0x2A recommended) */
++	0x10, 0x0E,	/* 10 - C Control 2 */
++	0x11, 0x00,	/* 11 - Mode/Delay */
++	0x12, 0x00,	/* 12 - RT signal control */
++	0x13, 0x00,	/* 13 - RT/X output */
++	0x14, 0x00,	/* 14 - Analog, Compat */
++	0x15, 0x11,	/* 15 - VGATE start */
++	0x16, 0xFE,	/* 16 - VGATE stop */
++	0x17, 0x40,	/* 17 - Misc VGATE (disable LLC2) */
++	0x18, 0x40,	/* 18 - Raw data gain - 128 */
++	0x19, 0x80,	/* 19 - Raw data offset - 0 */
++
++	/* Global settings */
++	0x88, 0x98,	/* 88 - AI1x on, AI2x off; decoder/slicer off; ACLK gen off */
++	0x83, 0x00,	/* 83 - X-port output disabled */
++	0x84, 0xF0,	/* 84 - I-port V/G output framing, IGP1=0=IGP0=0 */
++	0x85, 0x00,	/* 85 - I-port default polarities, X-port signals */
++	0x86, 0x40,	/* 86 - more IGP1/0, FIFO level, only video transmitted */
++	0x87, 0x01,	/* 87 - ICK default, IDQ default, I-port output enabled */
++
++	/* Task A: scaler input config and output format */
++	0x90, 0x00,	/* 90 - Task handling */
++	0x91, 0x08,	/* 91 - Scalar input and format */
++	0x92, 0x10,	/* 92 - Reference signal def */
++	0x93, 0x80,	/* 93 - I-port output */
++
++	/* Task B */
++	0xc0, 0x42,	/* 90 - Task handling */
++	0xc1, 0x08,	/* 91 - Scalar input and format */
++	0xc2, 0x10,	/* 92 - Reference signal def */
++	0xc3, 0x80,	/* 93 - I-port output */
++
++	/* Input and Output windows */
++	0x94, 0x10,	/*  - */
++	0x95, 0x00,	/*  - */
++	0x96, 0xD0,	/*  - */
++	0x97, 0x02,	/*  - */
++	0x98, 0x0A,	/*  - */
++	0x99, 0x00,	/*  - */
++	0x9a, 0xF2,	/*  - */
++	0x9b, 0x00,	/*  - */
++	0x9c, 0xD0,	/*  - */
++	0x9d, 0x02,	/*  - */
++	0xc4, 0x10,	/*  - */
++	0xc5, 0x00,	/*  - */
++	0xc6, 0xD0,	/*  - */
++	0xc7, 0x02,	/*  - */
++	0xc8, 0x0A,	/*  - */
++	0xc9, 0x00,	/*  - */
++	0xca, 0xF2,	/*  - */
++	0xcb, 0x00,	/*  - */
++	0xcc, 0xD0,	/*  - */
++	0xcd, 0x02,	/*  - */
++
++	0x9e, 0xf0,	/*  - */
++	0x9f, 0x00,	/*  - */
++	0xce, 0xf0,	/*  - */
++	0xcf, 0x00,	/*  - */
++
++	/* Prefiltering and prescaling */
++	0xa0, 0x01,	/*  - */
++	0xa1, 0x00,	/*  - */
++	0xa2, 0x00,	/*  - */
++	0xa4, 0x80,	/*  - */
++	0xa5, 0x40,	/*  - */
++	0xa6, 0x40,	/*  - */
++	0xd4, 0x80,	/*  - */
++	0xd5, 0x40,	/*  - */
++	0xd6, 0x40,	/*  - */
++
++	/* Horizontal phase scaling */
++	0xa8, 0x00,	/*  - */
++	0xa9, 0x04,	/*  - */
++	0xaa, 0x00,	/*  - */
++	0xd8, 0x00,	/*  - */
++	0xd9, 0x04,	/*  - */
++	0xda, 0x00,	/*  - */
++
++	0xac, 0x00,	/*  - */
++	0xad, 0x02,	/*  - */
++	0xae, 0x00,	/*  - */
++	0xdc, 0x00,	/*  - */
++	0xdd, 0x02,	/*  - */
++	0xde, 0x00,	/*  - */
++
++	/* Vertical phase scaling */
++	0xb0, 0x00,	/*  - */
++	0xb1, 0x04,	/*  - */
++	0xb2, 0x00,	/*  - */
++	0xb3, 0x04,	/*  - */
++	0xe0, 0x00,	/*  - */
++	0xe1, 0x04,	/*  - */
++	0xe2, 0x00,	/*  - */
++	0xe3, 0x04,	/*  - */
++	0xb4, 0x00,	/* b4 - vscale mode control */
++	0xe4, 0x00,	/* b4 - vscale mode control */
++
++	/* Task enables */
++	0x80, 0x10,	/* 80 - LLC->ICLK, dq->IDQ, scaler->F/V timing, task enables */
++
++	/* Reset the slicer */
++	0x88, 0xb8,	/* 88 - AI1x on, AI2x off; decoder/slicer on; ACLK gen off */
++};
++
++static int saa7114h_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind)
++{
++	struct i2c_client *client;
++	struct video_device *vd;
++	struct saa7114h *decoder;
++	int err;
++	int val, i;
++
++	client = kmalloc(sizeof(*client), GFP_KERNEL);
++	if (client == NULL)
++		return -ENOMEM;
++	client->adapter = adap;
++	client->addr = addr;
++	client->driver = &i2c_driver_saa7114h;
++	strcpy(client->name, IF_NAME);
++
++	decoder = kmalloc(sizeof(*decoder), GFP_KERNEL);
++	if (decoder == NULL) {
++		kfree(client);
++		return -ENOMEM;
++	}
++	memset(decoder, 0, sizeof(struct saa7114h));
++	decoder->client = client;
++	decoder->dma_enable = 0;
++	decoder->palette = VIDEO_PALETTE_UYVY;
++	decoder->depth = 16;
++	decoder->vw.width = MAX_HORIZ;
++	decoder->vw.height = MAX_VERT;
++	decoder->frame_buf = rvmalloc(MAX_FRAME_SIZE*NUM_FRAME);
++	if (!decoder->frame_buf) {
++		kfree(decoder);
++		kfree(client);
++		return -ENOMEM;
++	}
++	/* XXXKW use clear_page? */
++	memset(decoder->frame_buf, 0, MAX_FRAME_SIZE*NUM_FRAME);
++	printk("saa7114h_attach: frame_buf = (fb=%8p / %08lx)\n",
++	       decoder->frame_buf, kvirt_to_pa((int)decoder->frame_buf));
++	for (i=0; i<NUM_FRAME; i++) {
++		decoder->frame[i].data = decoder->frame_buf+i*MAX_FRAME_SIZE;
++#if NULL_DMA
++		decoder->frame[i].state = FRAME_DONE;
++#else
++		decoder->frame[i].state = FRAME_UNUSED;
++#endif
++		init_waitqueue_head(&decoder->frame[i].read_wait);
++	}
++	decoder->irq = K_INT_MAC_2;
++	if (request_irq
++	    (decoder->irq, saa7114h_interrupt, 0, "Philips SAA7114h", decoder)) {
++		rvfree(decoder->frame_buf, MAX_FRAME_SIZE*NUM_FRAME);
++		kfree(decoder);
++		kfree(client);
++		return -ENOMEM;
++	}
++	init_MUTEX(&decoder->param_lock);
++	init_MUTEX(&decoder->busy_lock);
++
++	if ((err = i2c_attach_client(client)) < 0) {
++		kfree(client);
++		kfree(decoder);
++		return err;
++	}
++
++	if (saa7114h_reg_init(decoder, reg_init, sizeof(reg_init)) ||
++	    saa7114h_get_cparams(decoder)) {
++		i2c_detach_client(client);
++		kfree(client);
++		kfree(decoder);
++		return -ENODEV;
++	}
++
++	vd = kmalloc(sizeof(*vd), GFP_KERNEL);
++	memset(vd, 0, sizeof(*vd));
++	if (vd == NULL) {
++		i2c_detach_client(client);
++		kfree(client);
++		kfree(decoder);
++		return -ENOMEM;
++	}
++	vd->priv = decoder;
++	strcpy(vd->name, IF_NAME);
++	vd->type = VID_TYPE_CAPTURE;
++	vd->hardware = VID_HARDWARE_SAA7114H;
++	vd->open =  saa7114h_open;
++	vd->close = saa7114h_release;
++	vd->read =  saa7114h_read;
++	vd->ioctl = saa7114h_ioctl;
++	vd->mmap =  saa7114h_mmap;
++
++	if ((err = video_register_device(vd, VFL_TYPE_GRABBER, -1)) < 0) {
++		i2c_detach_client(client);
++		kfree(client);
++		kfree(decoder);
++		kfree(vd);
++		return err;
++	}
++
++	client->data = vd;
++	decoder->vd = vd;
++
++	/* Turn on the ITRDY - preserve the GENO pin for syncser */
++	val = __raw_readq(KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO));
++	__raw_writeq(M_MAC_MDIO_OUT | (val & M_MAC_GENC),
++	      KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO));
++
++	if ((err = dma_setup(decoder))) {
++		i2c_detach_client(client);
++		kfree(client);
++		kfree(decoder);
++		kfree(vd);
++		return err;
++	}
++
++	printk("saa7114h_attach successful\n");
++
++#ifdef CONFIG_PROC_FS
++	proc_saa7114h_create();
++	create_proc_decoder(vd->priv);
++#endif
++
++	return 0;
++}
++
++/* Addresses to scan */
++static unsigned short normal_i2c[] = {I2C_CLIENT_END};
++static unsigned short normal_i2c_range[] = {0x20, 0x21, I2C_CLIENT_END};
++static unsigned short probe[2]	      = { I2C_CLIENT_END, I2C_CLIENT_END };
++static unsigned short probe_range[2]  = { I2C_CLIENT_END, I2C_CLIENT_END };
++static unsigned short ignore[2]	      = { I2C_CLIENT_END, I2C_CLIENT_END };
++static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
++static unsigned short force[2]	      = { I2C_CLIENT_END, I2C_CLIENT_END };
++
++static struct i2c_client_address_data addr_data = {
++	normal_i2c, normal_i2c_range,
++	probe, probe_range,
++	ignore, ignore_range,
++	force
++};
++
++static int saa7114h_probe(struct i2c_adapter *adap)
++{
++	/* Look for this device on the given adapter (bus) */
++	if (adap->id == (I2C_ALGO_SIBYTE | I2C_HW_SIBYTE))
++		return i2c_probe(adap, &addr_data, &saa7114h_attach);
++	else
++		return 0;
++}
++
++static int saa7114h_detach(struct i2c_client *device)
++{
++#if 0
++	kfree(device->data);
++#endif
++#ifdef CONFIG_PROC_FS
++	destroy_proc_decoder(((struct video_device *)device->data)->priv);
++	proc_saa7114h_destroy();
++#endif
++	return 0;
++}
++
++/* ----------------------------------------------------------------------- */
++
++static int __init swarm_7114h_init(void)
++{
++	return i2c_add_driver(&i2c_driver_saa7114h);
++}
++
++static void __exit swarm_7114h_cleanup(void)
++{
++}
++
++MODULE_AUTHOR("Kip Walker, Broadcom Corp.");
++MODULE_DESCRIPTION("Philips SAA7114H Driver for Broadcom SWARM board");
++
++module_init(swarm_7114h_init);
++module_exit(swarm_7114h_cleanup);
+diff -urpNX dontdiff linux-2.6.10/drivers/media/video/vino.c linux-2.6.10-mips/drivers/media/video/vino.c
+--- linux-2.6.10/drivers/media/video/vino.c	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/drivers/media/video/vino.c	2003-09-24 15:24:56.000000000 +0200
+@@ -1,267 +1,347 @@
+-/* $Id: vino.c,v 1.5 1999/10/09 00:01:14 ralf Exp $
+- * drivers/char/vino.c
++/*
++ * (incomplete) Driver for the VINO (Video In No Out) system found in SGI Indys.
++ * 
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License version 2 as published by the Free Software Foundation.
+  *
+- * (incomplete) Driver for the Vino Video input system found in SGI Indys.
+- *
+- * Copyright (C) 1999 Ulf Carlsson (ulfc at bun.falkenberg.se)
+- *
+- * This isn't complete yet, please don't expect any video until I've written
+- * some more code.
++ * Copyright (C) 2003 Ladislav Michl <ladis at linux-mips.org>
+  */
+ 
+ #include <linux/module.h>
+ #include <linux/init.h>
+ #include <linux/types.h>
+ #include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/wrapper.h>
+ #include <linux/errno.h>
++#include <linux/irq.h>
++#include <linux/delay.h>
+ #include <linux/videodev.h>
++#include <linux/i2c.h>
++#include <linux/i2c-algo-sgi.h>
+ 
+ #include <asm/addrspace.h>
+ #include <asm/system.h>
++#include <asm/bootinfo.h>
++#include <asm/pgtable.h>
++#include <asm/paccess.h>
++#include <asm/io.h>
++#include <asm/sgi/ip22.h>
++#include <asm/sgi/hpc3.h>
++#include <asm/sgi/mc.h>
+ 
+ #include "vino.h"
+ 
++/* debugging? */
++#if 1
++#define DEBUG(x...)     printk(x);
++#else
++#define DEBUG(x...)
++#endif
++
++
++/* VINO ASIC registers */
++struct sgi_vino *vino;
++
++static const char *vinostr = "VINO IndyCam/TV";
++static int threshold_a = 512;
++static int threshold_b = 512;
++
+ struct vino_device {
+ 	struct video_device vdev;
++#define VINO_CHAN_A		1
++#define VINO_CHAN_B		2
++	int chan;
++};
+ 
+-	unsigned long chan;
+-#define VINO_CHAN_A		0
+-#define VINO_CHAN_B		1
+-
+-	unsigned long flags;
+-#define VINO_DMA_ACTIVE		(1<<0)
++struct vino_client {
++	struct i2c_client *driver;
++	int owner;
+ };
+ 
+-/* We can actually receive TV and IndyCam input at the same time. Believe it or
+- * not..
+- */
+-static struct vino_device vino[2];
++struct vino_video {
++	struct vino_device chA;
++	struct vino_device chB;
++
++	struct vino_client decoder;
++	struct vino_client camera;
++
++	struct semaphore input_lock;
++
++	/* Loaded into VINO descriptors to clear End Of Descriptors table
++	 * interupt condition */
++	unsigned long dummy_page;
++	unsigned int dummy_buf[4] __attribute__((aligned(8)));
++};
+ 
+-/* Those registers have to be accessed by either *one* 64 bit write or *one* 64
+- * bit read. We need some asm to fix this. We can't use mips3 as standard
+- * because we just save 32 bits at context switch.
+- */
++static struct vino_video *Vino;
+ 
+-static __inline__ unsigned long long vino_reg_read(unsigned long addr)
++unsigned i2c_vino_getctrl(void *data)
+ {
+-	unsigned long long ret __attribute__ ((aligned (64)));
+-	unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
+-	unsigned long flags;
+-
+-	save_and_cli(flags);
+-	__asm__ __volatile__(
+-		".set\tmips3\n\t"
+-		".set\tnoat\n\t"
+-		"ld\t$1,(%0)\n\t"
+-		"sd\t$1,(%1)\n\t"
+-		".set\tat\n\t"
+-		".set\tmips0"
+-		:
+-		:"r" (virt_addr),
+-		 "r" (&ret)
+-		:"$1");
+-	restore_flags(flags);
+-
+-	return ret;
++	return vino->i2c_control;
+ }
+ 
+-static __inline__ void vino_reg_write(unsigned long long value,
+-				      unsigned long addr)
++void i2c_vino_setctrl(void *data, unsigned val)
+ {
+-	unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
+-	unsigned long flags;
++	vino->i2c_control = val;
++}
+ 
+-	/* we might lose the upper parts of the registers which are not saved
+-	 * if there comes an interrupt in our way, play safe */
++unsigned i2c_vino_rdata(void *data)
++{
++	return vino->i2c_data;
++}
+ 
+-	save_and_cli(flags);
+-	__asm__ __volatile__(
+-		".set\tmips3\n\t"
+-		".set\tnoat\n\t"
+-		"ld\t$1,(%0)\n\t"
+-		"sd\t$1,(%1)\n\t"
+-		".set\tat\n\t"
+-		".set\tmips0"
+-		:
+-		:"r" (&value),
+-		 "r" (virt_addr)
+-		:"$1");
+-	restore_flags(flags);
+-}
+-
+-static __inline__ void vino_reg_and(unsigned long long value,
+-				    unsigned long addr)
+-{
+-	unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
+-	unsigned long flags;
+-
+-	save_and_cli(flags);
+-	__asm__ __volatile__(
+-		".set\tmips3\n\t"
+-		".set\tnoat\n\t"
+-		"ld\t$1,(%0)\n\t"
+-		"ld\t$2,(%1)\n\t"
+-		"and\t$1,$1,$2\n\t"
+-		"sd\t$1,(%0)\n\t"
+-		".set\tat\n\t"
+-		".set\tmips0"
+-		:
+-		:"r" (virt_addr),
+-		 "r" (&value)
+-		:"$1","$2");
+-	restore_flags(flags);
+-}
+-
+-static __inline__ void vino_reg_or(unsigned long long value,
+-				   unsigned long addr)
+-{
+-	unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
+-	unsigned long flags;
+-
+-	save_and_cli(flags);
+-	__asm__ __volatile__(
+-		".set\tmips3\n\t"
+-		".set\tnoat\n\t"
+-		"ld\t$1,(%0)\n\t"
+-		"ld\t$2,(%1)\n\t"
+-		"or\t$1,$1,$2\n\t"
+-		"sd\t$1,(%0)\n\t"
+-		".set\tat\n\t"
+-		".set\tmips0"
+-		:
+-		:"r" (virt_addr),
+-		 "r" (&value)
+-		:"$1","$2");
+-	restore_flags(flags);
++void i2c_vino_wdata(void *data, unsigned val)
++{
++	vino->i2c_data = val;
+ }
+ 
+-static int vino_dma_setup(void)
++static struct i2c_algo_sgi_data i2c_sgi_vino_data =
+ {
+-	return 0;
++	.getctrl = &i2c_vino_getctrl,
++	.setctrl = &i2c_vino_setctrl,
++	.rdata   = &i2c_vino_rdata,
++	.wdata   = &i2c_vino_wdata,
++	.xfer_timeout = 200,
++	.ack_timeout  = 1000,
++};
++
++/*
++ * There are two possible clients on VINO I2C bus, so we limit usage only
++ * to them.
++ */
++static int i2c_vino_client_reg(struct i2c_client *client)
++{
++	int res = 0;
++
++	down(&Vino->input_lock);
++	switch (client->driver->id) {
++	case I2C_DRIVERID_SAA7191:
++		if (Vino->decoder.driver)
++			res = -EBUSY;
++		else
++			Vino->decoder.driver = client;
++		break;
++	case I2C_DRIVERID_INDYCAM:
++		if (Vino->camera.driver)
++			res = -EBUSY;
++		else
++			Vino->camera.driver = client;
++		break;
++	default:
++		res = -ENODEV;
++	}
++	up(&Vino->input_lock);
++
++	return res;
+ }
+ 
+-static void vino_dma_stop(void)
++static int i2c_vino_client_unreg(struct i2c_client *client)
+ {
++	int res = 0;
++	
++	down(&Vino->input_lock);
++	if (client == Vino->decoder.driver) {
++		if (Vino->decoder.owner)
++			res = -EBUSY;
++		else
++			Vino->decoder.driver = NULL;
++	} else if (client == Vino->camera.driver) {
++		if (Vino->camera.owner)
++			res = -EBUSY;
++		else
++			Vino->camera.driver = NULL;
++	}
++	up(&Vino->input_lock);
+ 
++	return res;
+ }
+ 
+-static int vino_init(void)
++static struct i2c_adapter vino_i2c_adapter =
+ {
+-	unsigned long ret;
+-	unsigned short rev, id;
+-	unsigned long long foo;
+-	unsigned long *bar;
+-
+-	bar = (unsigned long *) &foo;
+-
+-	ret = vino_reg_read(VINO_REVID);
+-
+-	rev = (ret & VINO_REVID_REV_MASK);
+-	id = (ret & VINO_REVID_ID_MASK) >> 4;
+-
+-	printk("Vino: ID:%02hx Rev:%02hx\n", id, rev);
+-
+-	foo = vino_reg_read(VINO_A_DESC_DATA0);
+-	printk("0x%lx", bar[0]);
+-	printk("%lx ", bar[1]);
+-	foo = vino_reg_read(VINO_A_DESC_DATA1);
+-	printk("0x%lx", bar[0]);
+-	printk("%lx ", bar[1]);
+-	foo = vino_reg_read(VINO_A_DESC_DATA2);
+-	printk("0x%lx", bar[0]);
+-	printk("%lx ", bar[1]);
+-	foo = vino_reg_read(VINO_A_DESC_DATA3);
+-	printk("0x%lx", bar[0]);
+-	printk("%lx\n", bar[1]);
+-	foo = vino_reg_read(VINO_B_DESC_DATA0);
+-	printk("0x%lx", bar[0]);
+-	printk("%lx ", bar[1]);
+-	foo = vino_reg_read(VINO_B_DESC_DATA1);
+-	printk("0x%lx", bar[0]);
+-	printk("%lx ", bar[1]);
+-	foo = vino_reg_read(VINO_B_DESC_DATA2);
+-	printk("0x%lx", bar[0]);
+-	printk("%lx ", bar[1]);
+-	foo = vino_reg_read(VINO_B_DESC_DATA3);
+-	printk("0x%lx", bar[0]);
+-	printk("%lx\n", bar[1]);
++	.name			= "VINO I2C bus",
++	.id			= I2C_HW_SGI_VINO,
++	.algo_data		= &i2c_sgi_vino_data,
++	.client_register	= &i2c_vino_client_reg,
++	.client_unregister	= &i2c_vino_client_unreg,
++};
+ 
+-	return 0;
++static int vino_i2c_add_bus(void)
++{
++	return i2c_sgi_add_bus(&vino_i2c_adapter);
+ }
+ 
+-static void vino_dma_go(struct vino_device *v)
++static int vino_i2c_del_bus(void)
+ {
+-	
++	return i2c_sgi_del_bus(&vino_i2c_adapter);
+ }
+ 
+-/* Reset the vino back to default state */
+ 
+-static void vino_setup(struct vino_device *v)
++static void vino_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+-	
+ }
+ 
+ static int vino_open(struct video_device *dev, int flags)
+ {
++	struct vino_device *videv = (struct vino_device *)dev;
++
+ 	return 0;
+ }
+ 
+ static void vino_close(struct video_device *dev)
+ {
++	struct vino_device *videv = (struct vino_device *)dev;
+ }
+ 
+-static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
++static int vino_mmap(struct video_device *dev, const char *adr,
++		     unsigned long size)
+ {
+-	return 0;
++	struct vino_device *videv = (struct vino_device *)dev;
++
++	return -EINVAL;
+ }
+ 
+-static int vino_mmap(struct video_device *dev, const char *adr,
+-		     unsigned long size)
++static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+ {
+-	return 0;
++	struct vino_device *videv = (struct vino_device *)dev;
++
++	return -EINVAL;
+ }
+ 
+-static struct video_device vino_dev = {
++static const struct video_device vino_device = {
+ 	.owner		= THIS_MODULE,
+-	.name		= "Vino IndyCam/TV",
+-	.type		= VID_TYPE_CAPTURE,
++	.type		= VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE,
+ 	.hardware	= VID_HARDWARE_VINO,
++	.name		= "VINO",
+ 	.open		= vino_open,
+ 	.close		= vino_close,
+ 	.ioctl		= vino_ioctl,
+ 	.mmap		= vino_mmap,
+ };
+ 
+-int __init init_vino(struct video_device *dev)
++static int __init vino_init(void)
+ {
+-	int err;
+-
+-	err = vino_init();
+-	if (err)
+-		return err;
++	unsigned long rev;
++	int i, ret = 0;
++	
++	/* VINO is Indy specific beast */
++	if (ip22_is_fullhouse())
++		return -ENODEV;
+ 
+-#if 0
+-	if (video_register_device(&vinodev, VFL_TYPE_GRABBER) == -1) {
++	/*
++	 * VINO is in the EISA address space, so the sysid register will tell
++	 * us if the EISA_PRESENT pin on MC has been pulled low.
++	 * 
++	 * If EISA_PRESENT is not set we definitely don't have a VINO equiped
++	 * system.
++	 */
++	if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
++		printk(KERN_ERR "VINO not found\n");
+ 		return -ENODEV;
+ 	}
+-#endif
+ 
+-	return 0;
+-}
++	vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino));
++	if (!vino)
++		return -EIO;
++
++	/* Okay, once we know that VINO is present we'll read its revision
++	 * safe way. One never knows... */
++	if (get_dbe(rev, &(vino->rev_id))) {
++		printk(KERN_ERR "VINO: failed to read revision register\n");
++		ret = -ENODEV;
++		goto out_unmap;
++	}
++	if (VINO_ID_VALUE(rev) != VINO_CHIP_ID) {
++		printk(KERN_ERR "VINO is not VINO (Rev/ID: 0x%04lx)\n", rev);
++		ret = -ENODEV;
++		goto out_unmap;
++	}
++	printk(KERN_INFO "VINO Rev: 0x%02lx\n", VINO_REV_NUM(rev));
+ 
+-#ifdef MODULE
+-int init_module(void)
+-{
+-	int err;
++	Vino = (struct vino_video *)
++		kmalloc(sizeof(struct vino_video), GFP_KERNEL);
++	if (!Vino) {
++		ret = -ENOMEM;
++		goto out_unmap;
++	}
+ 
+-	err = vino_init();
+-	if (err)
+-		return err;
++	Vino->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
++	if (!Vino->dummy_page) {
++		ret = -ENOMEM;
++		goto out_free_vino;
++	}
++	for (i = 0; i < 4; i++)
++		Vino->dummy_buf[i] = PHYSADDR(Vino->dummy_page);
++
++	vino->control = 0;
++	/* prevent VINO from throwing spurious interrupts */
++	vino->a.next_4_desc = PHYSADDR(Vino->dummy_buf);
++	vino->b.next_4_desc = PHYSADDR(Vino->dummy_buf);
++	udelay(5);
++	vino->intr_status = 0;
++        /* set threshold level */
++        vino->a.fifo_thres = threshold_a;
++	vino->b.fifo_thres = threshold_b;
++
++	init_MUTEX(&Vino->input_lock);
++
++	if (request_irq(SGI_VINO_IRQ, vino_interrupt, 0, vinostr, NULL)) {
++		printk(KERN_ERR "VINO: irq%02d registration failed\n",
++		       SGI_VINO_IRQ);
++		ret = -EAGAIN;
++		goto out_free_page;
++	}
++
++	ret = vino_i2c_add_bus();
++	if (ret) {
++		printk(KERN_ERR "VINO: I2C bus registration failed\n");
++		goto out_free_irq;
++	}
++
++	if (video_register_device(&Vino->chA.vdev, VFL_TYPE_GRABBER, -1) < 0) {
++		printk("%s, chnl %d: device registration failed.\n",
++			Vino->chA.vdev.name, Vino->chA.chan);
++		ret = -EINVAL;
++		goto out_i2c_del_bus;
++	}
++	if (video_register_device(&Vino->chB.vdev, VFL_TYPE_GRABBER, -1) < 0) {
++		printk("%s, chnl %d: device registration failed.\n",
++			Vino->chB.vdev.name, Vino->chB.chan);
++		ret = -EINVAL;
++		goto out_unregister_vdev;
++	}
+ 
+ 	return 0;
++
++out_unregister_vdev:
++	video_unregister_device(&Vino->chA.vdev);
++out_i2c_del_bus:
++	vino_i2c_del_bus();
++out_free_irq:
++	free_irq(SGI_VINO_IRQ, NULL);
++out_free_page:
++	free_page(Vino->dummy_page);
++out_free_vino:
++	kfree(Vino);
++out_unmap:
++	iounmap(vino);
++
++	return ret;
+ }
+ 
+-void cleanup_module(void)
++static void __exit vino_exit(void)
+ {
++	video_unregister_device(&Vino->chA.vdev);
++	video_unregister_device(&Vino->chB.vdev);
++	vino_i2c_del_bus();
++	free_irq(SGI_VINO_IRQ, NULL);
++	free_page(Vino->dummy_page);
++	kfree(Vino);
++	iounmap(vino);
+ }
+-#endif
++
++module_init(vino_init);
++module_exit(vino_exit);
++
++MODULE_DESCRIPTION("Video4Linux driver for SGI Indy VINO (IndyCam)");
++MODULE_LICENSE("GPL");
+diff -urpNX dontdiff linux-2.6.10/drivers/media/video/vino.h linux-2.6.10-mips/drivers/media/video/vino.h
+--- linux-2.6.10/drivers/media/video/vino.h	2004-12-24 22:33:50.000000000 +0100
++++ linux-2.6.10-mips/drivers/media/video/vino.h	2003-11-16 09:20:52.000000000 +0100
+@@ -1,64 +1,84 @@
+ /*
+- * Copyright (C) 1999 Ulf Carlsson (ulfc at bun.falkenberg.se)
+- * Copyright (C) 2001 Ralf Baechle (ralf at gnu.org)
++ * Copyright (C) 1999 Ulf Karlsson <ulfc at bun.falkenberg.se>
++ * Copyright (C) 2003 Ladislav Michl <ladis at linux-mips.org>
+  */
+ 
+-#define VINO_BASE		0x00080000	/* In EISA address space */
++#ifndef VINO_H
++#define VINO_H
+ 
+-#define VINO_REVID		0x0000
+-#define VINO_CTRL		0x0008
+-#define VINO_INTSTAT		0x0010	/* Interrupt status */
+-#define VINO_I2C_CTRL		0x0018
+-#define VINO_I2C_DATA		0x0020
+-#define VINO_A_ALPHA		0x0028	/* Channel A ... */
+-#define VINO_A_CLIPS		0x0030	/* Clipping start */
+-#define VINO_A_CLIPE		0x0038	/* Clipping end */
+-#define VINO_A_FRAMERT		0x0040	/* Framerate */
+-#define VINO_A_FLDCNT		0x0048	/* Field counter */
+-#define VINO_A_LNSZ		0x0050
+-#define VINO_A_LNCNT		0x0058
+-#define VINO_A_PGIX		0x0060	/* Page index */
+-#define VINO_A_DESC_PTR		0x0068	/* Ptr to next four descriptors */
+-#define VINO_A_DESC_TLB_PTR	0x0070	/* Ptr to start of descriptor table */
+-#define VINO_A_DESC_DATA0	0x0078	/* Descriptor data 0 */
+-#define VINO_A_DESC_DATA1	0x0080	/* ... */
+-#define VINO_A_DESC_DATA2	0x0088
+-#define VINO_A_DESC_DATA3	0x0090
+-#define VINO_A_FIFO_THRESHOLD	0x0098	/* FIFO threshold */
+-#define VINO_A_FIFO_RP		0x00a0
+-#define VINO_A_FIFO_WP		0x00a8
+-#define VINO_B_ALPHA		0x00b0	/* Channel B ... */
+-#define VINO_B_CLIPS		0x00b8
+-#define VINO_B_CLIPE		0x00c0
+-#define VINO_B_FRAMERT		0x00c8
+-#define VINO_B_FLDCNT		0x00d0
+-#define VINO_B_LNSZ		0x00d8
+-#define VINO_B_LNCNT		0x00e0
+-#define VINO_B_PGIX		0x00e8
+-#define VINO_B_DESC_PTR		0x00f0
+-#define VINO_B_DESC_TLB_PTR	0x00f8
+-#define VINO_B_DESC_DATA0	0x0100
+-#define VINO_B_DESC_DATA1	0x0108
+-#define VINO_B_DESC_DATA2	0x0110
+-#define VINO_B_DESC_DATA3	0x0118
+-#define VINO_B_FIFO_THRESHOLD	0x0120
+-#define VINO_B_FIFO_RP		0x0128
+-#define VINO_B_FIFO_WP		0x0130
++#define VINO_BASE	0x00080000	/* Vino is in the EISA address space,
++					 * but it is not an EISA bus card */
+ 
+-/* Bits in the VINO_REVID register */
+-
+-#define VINO_REVID_REV_MASK		0x000f	/* bits 0:3 */
+-#define VINO_REVID_ID_MASK		0x00f0	/* bits 4:7 */
+-
+-/* Bits in the VINO_CTRL register */
++struct sgi_vino_channel {
++	u32 _pad_alpha;
++	volatile u32 alpha;
++
++#define VINO_CLIP_X(x)		((x) & 0x3ff)		/* bits 0:9 */
++#define VINO_CLIP_ODD(x)	(((x) & 0x1ff) << 10)	/* bits 10:18 */
++#define VINO_CLIP_EVEN(x)	(((x) & 0x1ff) << 19)	/* bits 19:27 */
++	u32 _pad_clip_start;
++	volatile u32 clip_start;
++	u32 _pad_clip_end;
++	volatile u32 clip_end;
++
++#define VINO_FRAMERT_PAL	(1<<0)			/* 0=NTSC 1=PAL */
++#define VINO_FRAMERT_RT(x)	(((x) & 0x1fff) << 1)	/* bits 1:12 */
++	u32 _pad_frame_rate;
++	volatile u32 frame_rate;
++
++	u32 _pad_field_counter;
++	volatile u32 field_counter;
++	u32 _pad_line_size;
++	volatile u32 line_size;
++	u32 _pad_line_count;
++	volatile u32 line_count;
++	u32 _pad_page_index;
++	volatile u32 page_index;
++	u32 _pad_next_4_desc;
++	volatile u32 next_4_desc;
++	u32 _pad_start_desc_tbl;
++	volatile u32 start_desc_tbl;
++
++#define VINO_DESC_JUMP		(1<<30)
++#define VINO_DESC_STOP		(1<<31)
++#define VINO_DESC_VALID		(1<<32)
++	u32 _pad_desc_0;
++	volatile u32 desc_0;
++	u32 _pad_desc_1;
++	volatile u32 desc_1;
++	u32 _pad_desc_2;
++	volatile u32 desc_2;
++	u32 _pad_Bdesc_3;
++	volatile u32 desc_3;
++
++	u32 _pad_fifo_thres;
++	volatile u32 fifo_thres;
++	u32 _pad_fifo_read;
++	volatile u32 fifo_read;
++	u32 _pad_fifo_write;
++	volatile u32 fifo_write;
++};
++
++struct sgi_vino {
++#define VINO_CHIP_ID		0xb
++#define VINO_REV_NUM(x)		((x) & 0x0f)
++#define VINO_ID_VALUE(x)	(((x) & 0xf0) >> 4)
++	u32 _pad_rev_id;
++	volatile u32 rev_id;
+ 
+ #define VINO_CTRL_LITTLE_ENDIAN		(1<<0)
+ #define VINO_CTRL_A_FIELD_TRANS_INT	(1<<1)	/* Field transferred int */
+ #define VINO_CTRL_A_FIFO_OF_INT		(1<<2)	/* FIFO overflow int */
+ #define VINO_CTRL_A_END_DESC_TBL_INT	(1<<3)	/* End of desc table int */
++#define VINO_CTRL_A_INT			(VINO_CTRL_A_FIELD_TRANS_INT | \
++					 VINO_CTRL_A_FIFO_OF_INT | \
++					 VINO_CTRL_A_END_DESC_TBL_INT)
+ #define VINO_CTRL_B_FIELD_TRANS_INT	(1<<4)	/* Field transferred int */
+ #define VINO_CTRL_B_FIFO_OF_INT		(1<<5)	/* FIFO overflow int */
+-#define VINO_CTRL_B_END_DESC_TLB_INT	(1<<6)	/* End of desc table int */
++#define VINO_CTRL_B_END_DESC_TBL_INT	(1<<6)	/* End of desc table int */
++#define VINO_CTRL_B_INT			(VINO_CTRL_B_FIELD_TRANS_INT | \
++					 VINO_CTRL_B_FIFO_OF_INT | \
++					 VINO_CTRL_B_END_DESC_TBL_INT)
+ #define VINO_CTRL_A_DMA_ENBL		(1<<7)
+ #define VINO_CTRL_A_INTERLEAVE_ENBL	(1<<8)
+ #define VINO_CTRL_A_SYNC_ENBL		(1<<9)
+@@ -67,51 +87,45 @@
+ #define VINO_CTRL_A_LUMA_ONLY		(1<<12)
+ #define VINO_CTRL_A_DEC_ENBL		(1<<13)	/* Decimation */
+ #define VINO_CTRL_A_DEC_SCALE_MASK	0x1c000	/* bits 14:17 */
++#define VINO_CTRL_A_DEC_SCALE_SHIFT	(14)
+ #define VINO_CTRL_A_DEC_HOR_ONLY	(1<<17)	/* Horizontal only */
+ #define VINO_CTRL_A_DITHER		(1<<18)	/* 24 -> 8 bit dither */
+ #define VINO_CTRL_B_DMA_ENBL		(1<<19)
+ #define VINO_CTRL_B_INTERLEAVE_ENBL	(1<<20)
+ #define VINO_CTRL_B_SYNC_ENBL		(1<<21)
+ #define VINO_CTRL_B_SELECT		(1<<22)	/* 1=D1 0=Philips */
+-#define VINO_CTRL_B_RGB			(1<<22)	/* 1=RGB 0=YUV */
+-#define VINO_CTRL_B_LUMA_ONLY		(1<<23)
+-#define VINO_CTRL_B_DEC_ENBL		(1<<24)	/* Decimation */
+-#define VINO_CTRL_B_DEC_SCALE_MASK	0x1c000000	/* bits 25:28 */
++#define VINO_CTRL_B_RGB			(1<<23)	/* 1=RGB 0=YUV */
++#define VINO_CTRL_B_LUMA_ONLY		(1<<24)
++#define VINO_CTRL_B_DEC_ENBL		(1<<25)	/* Decimation */
++#define VINO_CTRL_B_DEC_SCALE_MASK	0x1c000000	/* bits 26:28 */
++#define VINO_CTRL_B_DEC_SCALE_SHIFT	(26)
+ #define VINO_CTRL_B_DEC_HOR_ONLY	(1<<29)	/* Decimation horizontal only */
+ #define VINO_CTRL_B_DITHER		(1<<30)	/* ChanB 24 -> 8 bit dither */
+-
+-/* Bits in the Interrupt and Status register */
++	u32 _pad_control;
++	volatile u32 control;
+ 
+ #define VINO_INTSTAT_A_FIELD_TRANS	(1<<0)	/* Field transferred int */
+ #define VINO_INTSTAT_A_FIFO_OF		(1<<1)	/* FIFO overflow int */
+ #define VINO_INTSTAT_A_END_DESC_TBL	(1<<2)	/* End of desc table int */
++#define VINO_INTSTAT_A			(VINO_INTSTAT_A_FIELD_TRANS | \
++					 VINO_INTSTAT_A_FIFO_OF | \
++					 VINO_INTSTAT_A_END_DESC_TBL)
+ #define VINO_INTSTAT_B_FIELD_TRANS	(1<<3)	/* Field transferred int */
+ #define VINO_INTSTAT_B_FIFO_OF		(1<<4)	/* FIFO overflow int */
+ #define VINO_INTSTAT_B_END_DESC_TBL	(1<<5)	/* End of desc table int */
++#define VINO_INTSTAT_B			(VINO_INTSTAT_B_FIELD_TRANS | \
++					 VINO_INTSTAT_B_FIFO_OF | \
++					 VINO_INTSTAT_B_END_DESC_TBL)
++	u32 _pad_intr_status;
++	volatile u32 intr_status;
++
++	u32 _pad_i2c_control;
++	volatile u32 i2c_control;
++	u32 _pad_i2c_data;
++	volatile u32 i2c_data;
++
++	struct sgi_vino_channel a;
++	struct sgi_vino_channel b;
++};
+ 
+-/* Bits in the Clipping Start register */
+-
+-#define VINO_CLIPS_START		0x3ff		/* bits 0:9 */
+-#define VINO_CLIPS_ODD_MASK		0x7fc00		/* bits 10:18 */
+-#define VINO_CLIPS_EVEN_MASK		0xff80000	/* bits 19:27 */
+-
+-/* Bits in the Clipping End register */
+-
+-#define VINO_CLIPE_END			0x3ff		/* bits 0:9 */
+-#define VINO_CLIPE_ODD_MASK		0x7fc00		/* bits 10:18 */
+-#define VINO_CLIPE_EVEN_MASK		0xff80000	/* bits 19:27 */
+-
+-/* Bits in the Frame Rate register */
+-
+-#define VINO_FRAMERT_PAL		(1<<0)	/* 0=NTSC 1=PAL */
+-#define VINO_FRAMERT_RT_MASK		0x1ffe		/* bits 1:12 */
+-
+-/* Bits in the VINO_I2C_CTRL */
+-
+-#define VINO_CTRL_I2C_IDLE		(1<<0)	/* write: 0=force idle
+-						 * read: 0=idle 1=not idle */
+-#define VINO_CTRL_I2C_DIR		(1<<1)	/* 0=read 1=write */
+-#define VINO_CTRL_I2C_MORE_BYTES	(1<<2)	/* 0=last byte 1=more bytes */
+-#define VINO_CTRL_I2C_TRANS_BUSY	(1<<4)	/* 0=trans done 1=trans busy */
+-#define VINO_CTRL_I2C_ACK		(1<<5)	/* 0=ack received 1=ack not */
+-#define VINO_CTRL_I2C_BUS_ERROR		(1<<7)	/* 0=no bus err 1=bus err */
++#endif
+diff -urpNX dontdiff linux-2.6.10/drivers/mtd/devices/Kconfig linux-2.6.10-mips/drivers/mtd/devices/Kconfig
+--- linux-2.6.10/drivers/mtd/devices/Kconfig	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/drivers/mtd/devices/Kconfig	2004-12-04 20:57:26.000000000 +0100
+@@ -47,6 +47,11 @@ config MTD_MS02NV
+ 	  accelerator.  Say Y here if you have a DECstation 5000/2x0 or a
+ 	  DECsystem 5900 equipped with such a module.
+ 
++	  If you want to compile this driver as a module ( = code which can be
++	  inserted in and removed from the running kernel whenever you want),
++	  say M here and read <file:Documentation/modules.txt>.  The module will
++	  be called ms02-nv.o.
++
+ config MTD_SLRAM
+ 	tristate "Uncached system RAM"
+ 	depends on MTD
+diff -urpNX dontdiff linux-2.6.10/drivers/mtd/devices/docprobe.c linux-2.6.10-mips/drivers/mtd/devices/docprobe.c
+--- linux-2.6.10/drivers/mtd/devices/docprobe.c	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/drivers/mtd/devices/docprobe.c	2004-12-04 20:57:26.000000000 +0100
+@@ -84,10 +84,10 @@ static unsigned long __initdata doc_loca
+ 	0xe4000000,
+ #elif defined(CONFIG_MOMENCO_OCELOT)
+ 	0x2f000000,
+-        0xff000000,
++	0xff000000,
+ #elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
+-        0xff000000,
+-##else
++	0xff000000,
++#else
+ #warning Unknown architecture for DiskOnChip. No default probe locations defined
+ #endif
+ 	0xffffffff };
+diff -urpNX dontdiff linux-2.6.10/drivers/mtd/maps/Kconfig linux-2.6.10-mips/drivers/mtd/maps/Kconfig
+--- linux-2.6.10/drivers/mtd/maps/Kconfig	2004-12-24 22:35:39.000000000 +0100
++++ linux-2.6.10-mips/drivers/mtd/maps/Kconfig	2004-10-27 02:14:28.000000000 +0200
+@@ -201,41 +201,12 @@ config MTD_TSUNAMI
+ 	help
+ 	  Support for the flash chip on Tsunami TIG bus.
+ 
+-config MTD_LASAT
+-	tristate "Flash chips on LASAT board"
+-	depends on LASAT
+-	help
+-	  Support for the flash chips on the Lasat 100 and 200 boards.
+-
+ config MTD_NETtel
+ 	tristate "CFI flash device on SnapGear/SecureEdge"
+ 	depends on X86 && MTD_PARTITIONS && MTD_JEDECPROBE
+ 	help
+ 	  Support for flash chips on NETtel/SecureEdge/SnapGear boards.
+ 
+-config MTD_PB1XXX
+-	tristate "Flash devices on Alchemy PB1xxx boards"
+-	depends on MIPS && ( MIPS_PB1000 || MIPS_PB1100 || MIPS_PB1500 )
+-	help
+-	  Flash memory access on Alchemy Pb1000/Pb1100/Pb1500 boards
+-
+-config MTD_PB1XXX_BOOT
+-	bool "PB1x00 boot flash device"
+-	depends on MTD_PB1XXX && ( MIPS_PB1100 || MIPS_PB1500 )
+-	help
+-	  Use the first of the two 32MiB flash banks on Pb1100/Pb1500 board.
+-	  You can say 'Y' to both this and 'MTD_PB1XXX_USER' below, to use
+-	  both banks.
+-
+-config MTD_PB1XXX_USER
+-	bool "PB1x00 user flash device"
+-	depends on MTD_PB1XXX && ( MIPS_PB1100 || MIPS_PB1500 )
+-	default y if MTD_PB1XX_BOOT = n
+-	help
+-	  Use the second of the two 32MiB flash banks on Pb1100/Pb1500 board.
+-	  You can say 'Y' to both this and 'MTD_PB1XXX_BOOT' above, to use
+-	  both banks.
+-
+ config MTD_PB1550
+ 	tristate "Flash devices on Alchemy PB1550 board"
+ 	depends on MIPS && MIPS_PB1550
+@@ -357,6 +328,80 @@ config MTD_CFI_FLAGADM
+ 	  Mapping for the Flaga digital module. If you don´t have one, ignore
+ 	  this setting.
+ 
++config MTD_PB1000
++	tristate "Pb1000 Boot Flash device"
++	depends on MIPS && MIPS_PB1000
++	help
++	  Flash memory access on Alchemy Pb1000
++
++config MTD_PB1100
++	tristate "Pb1100 Flash device"
++	depends on MIPS && MIPS_PB1100
++	help
++	  Flash memory access on Alchemy Pb1100
++
++config MTD_PB1500
++	tristate "Pb1500 Flash device"
++	depends on MIPS && MIPS_PB1500
++	help
++	  Flash memory access on Alchemy Pb1500
++
++config MTD_PB1500_BOOT
++	bool "Pb1100/Pb1500 Boot Flash device"
++	depends on MIPS && (MTD_PB1500 || MTD_PB1100)
++	help
++	  Use the first of the two 32MB flash banks on Pb1100/Pb1500 board.
++	  You can say 'Y' to both this and the USER flash option, to use
++	  both banks.
++
++config MTD_PB1500_USER
++	bool "Pb1100/Pb1500 User Flash device (2nd 32MB bank)"
++	depends on MIPS && (MTD_PB1500 || MTD_PB1100)
++	help
++	  Use the second of the two 32MB flash banks on Pb1100/Pb1500 board.
++	  You can say 'Y' to both this and the BOOT flash option, to use
++	  both banks.
++
++config MTD_DB1X00
++	tristate "Db1X00 Flash device"
++	depends on MIPS && (MIPS_DB1000 || MIPS_DB1100 || MIPS_DB1500)
++	help
++	  Flash memory access on Alchemy Db1X00 Boards
++
++config MTD_DB1X00_BOOT
++	bool "Db1X00 Boot Flash device"
++	depends on MIPS && MTD_DB1X00
++	help
++	  Use the first of the two 32MB flash banks on Db1X00 board.
++	  You can say 'Y' to both this and the USER flash option, to use
++	  both banks.
++
++config MTD_DB1X00_USER
++	bool "Db1X00 User Flash device (2nd 32MB bank)"
++	depends on MIPS && MTD_DB1X00
++	help
++	  Use the second of the two 32MB flash banks on Db1X00 boards.
++	  You can say 'Y' to both this and the BOOT flash option, to use
++	  both banks.
++
++config MTD_BOSPORUS
++	tristate "Bosporus Flash device"
++	depends on MIPS && MIPS_BOSPORUS
++	help
++	  Flash memory access on Alchemy Bosporus Board
++
++config MTD_XXS1500
++	tristate "MyCable XXS1500 Flash device"
++	depends on MIPS && MIPS_XXS1500
++	help
++	  Flash memory access on MyCable XXS1500 Board
++
++config MTD_MTX1
++	tristate "4-G Systems MTX-1 Flash device"
++	depends on MIPS && MIPS_MTX1
++	help
++	  Flash memory access on 4-G Systems MTX-1 Board
++
+ config MTD_BEECH
+ 	tristate "CFI Flash device mapped on IBM 405LP Beech"
+ 	depends on MTD_CFI && PPC32 && 40x && BEECH
+@@ -449,6 +494,12 @@ config MTD_OCELOT
+ 	  NVRAM on the Momenco Ocelot board. If you have one of these boards
+ 	  and would like access to either of these, say 'Y'.
+ 
++config MTD_LASAT
++	tristate "LASAT flash device"
++	depends on LASAT && MTD_CFI
++	help
++	  Support for the flash chips on the Lasat 100 and 200 boards.
++
+ config MTD_SOLUTIONENGINE
+ 	tristate "CFI Flash device mapped on Hitachi SolutionEngine"
+ 	depends on SUPERH && MTD_CFI && MTD_REDBOOT_PARTS
+diff -urpNX dontdiff linux-2.6.10/drivers/mtd/maps/Makefile linux-2.6.10-mips/drivers/mtd/maps/Makefile
+--- linux-2.6.10/drivers/mtd/maps/Makefile	2004-12-24 22:33:47.000000000 +0100
++++ linux-2.6.10-mips/drivers/mtd/maps/Makefile	2004-11-12 16:25:06.000000000 +0100
+@@ -44,11 +44,9 @@ obj-$(CONFIG_MTD_DBOX2)		+= dbox2-flash.
+ obj-$(CONFIG_MTD_OCELOT)	+= ocelot.o
+ obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
+ obj-$(CONFIG_MTD_PCI)		+= pci.o
+-obj-$(CONFIG_MTD_PB1XXX)	+= pb1xxx-flash.o
+-obj-$(CONFIG_MTD_DB1X00)        += db1x00-flash.o
+-obj-$(CONFIG_MTD_PB1550)        += pb1550-flash.o
+-obj-$(CONFIG_MTD_DB1550)        += db1550-flash.o
+ obj-$(CONFIG_MTD_LASAT)		+= lasat.o
++obj-$(CONFIG_MTD_PB1550)	+= pb1550-flash.o
++obj-$(CONFIG_MTD_DB1550)	+= db1550-flash.o
+ obj-$(CONFIG_MTD_AUTCPU12)	+= autcpu12-nvram.o
+ obj-$(CONFIG_MTD_EDB7312)	+= edb7312.o
+ obj-$(CONFIG_MTD_IMPA7)		+= impa7.o
+@@ -69,3 +67,7 @@ obj-$(CONFIG_MTD_IXP4XX)	+= ixp4xx.o
+ obj-$(CONFIG_MTD_IXP2000)	+= ixp2000.o
+ obj-$(CONFIG_MTD_WRSBC8260)	+= wr_sbc82xx_flash.o
+ obj-$(CONFIG_MTD_DMV182)	+= dmv182.o
++obj-$(CONFIG_MTD_PB1000)        += pb1xxx-flash.o
++obj-$(CONFIG_MTD_PB1100)        += pb1xxx-flash.o
++obj-$(CONFIG_MTD_PB1500)        += pb1xxx-flash.o
++obj-$(CONFIG_MTD_DB1X00)        += db1x00-flash.o
+diff -urpNX dontdiff linux-2.6.10/drivers/mtd/maps/db1x00-flash.c linux-2.6.10-mips/drivers/mtd/maps/db1x00-flash.c
+--- linux-2.6.10/drivers/mtd/maps/db1x00-flash.c	2004-12-24 22:33:59.000000000 +0100
++++ linux-2.6.10-mips/drivers/mtd/maps/db1x00-flash.c	2004-12-04 20:57:26.000000000 +0100
+@@ -1,9 +1,9 @@
+ /*
+  * Flash memory access on Alchemy Db1xxx boards
+  * 
+- * $Id: db1x00-flash.c,v 1.6 2004/11/04 13:24:14 gleixner Exp $
++ * $Id: db1x00-flash.c,v 1.3 2004/07/14 17:45:40 dwmw2 Exp $
+  *
+- * (C) 2003 Pete Popov <ppopov at embeddedalley.com>
++ * (C) 2003 Pete Popov <ppopov at pacbell.net>
+  * 
+  */
+ 
+@@ -18,6 +18,8 @@
+ #include <linux/mtd/partitions.h>
+ 
+ #include <asm/io.h>
++#include <asm/au1000.h>
++#include <asm/db1x00.h>
+ 
+ #ifdef 	DEBUG_RW
+ #define	DBG(x...)	printk(x)
+@@ -25,20 +27,11 @@
+ #define	DBG(x...)	
+ #endif
+ 
+-/* MTD CONFIG OPTIONS */
+-#if defined(CONFIG_MTD_DB1X00_BOOT) && defined(CONFIG_MTD_DB1X00_USER)
+-#define DB1X00_BOTH_BANKS
+-#elif defined(CONFIG_MTD_DB1X00_BOOT) && !defined(CONFIG_MTD_DB1X00_USER)
+-#define DB1X00_BOOT_ONLY
+-#elif !defined(CONFIG_MTD_DB1X00_BOOT) && defined(CONFIG_MTD_DB1X00_USER)
+-#define DB1X00_USER_ONLY
+-#endif
+-
+ static unsigned long window_addr;
+ static unsigned long window_size;
+ static unsigned long flash_size;
+ 
+-static unsigned short *bcsr = (unsigned short *)0xAE000000;
++static BCSR * const bcsr = (BCSR *)0xAE000000;
+ static unsigned char flash_bankwidth = 4;
+ 
+ /* 
+@@ -120,7 +113,7 @@ static struct mtd_info *db1xxx_mtd;
+  */
+ int setup_flash_params(void)
+ {
+-	switch ((bcsr[2] >> 14) & 0x3) {
++	switch ((bcsr->status >> 14) & 0x3) {
+ 		case 0: /* 64Mbit devices */
+ 			flash_size = 0x800000; /* 8MB per part */
+ #if defined(DB1X00_BOTH_BANKS)
+@@ -199,7 +192,7 @@ int __init db1x00_mtd_init(void)
+ 	 */
+ 	printk(KERN_NOTICE "Db1xxx flash: probing %d-bit flash bus\n", 
+ 			db1xxx_mtd_map.bankwidth*8);
+-	db1xxx_mtd_map.virt = ioremap(window_addr, window_size);
++	db1xxx_mtd_map.virt = (unsigned long)ioremap(window_addr, window_size);
+ 	db1xxx_mtd = do_map_probe("cfi_probe", &db1xxx_mtd_map);
+ 	if (!db1xxx_mtd) return -ENXIO;
+ 	db1xxx_mtd->owner = THIS_MODULE;
+diff -urpNX dontdiff linux-2.6.10/drivers/mtd/maps/lasat.c linux-2.6.10-mips/drivers/mtd/maps/lasat.c
+--- linux-2.6.10/drivers/mtd/maps/lasat.c	2004-12-24 22:34:01.000000000 +0100
++++ linux-2.6.10-mips/drivers/mtd/maps/lasat.c	2004-12-04 20:57:27.000000000 +0100
+@@ -7,7 +7,7 @@
+  * modify it under the terms of the GNU General Public License version
+  * 2 as published by the Free Software Foundation.
+  *
+- * $Id: lasat.c,v 1.9 2004/11/04 13:24:15 gleixner Exp $
++ * $Id: lasat.c,v 1.7 2004/07/12 21:59:44 dwmw2 Exp $
+  *
+  */
+ 
+@@ -50,7 +50,7 @@ static int __init init_lasat(void)
+ 	ENABLE_VPP((&lasat_map));
+ 
+ 	lasat_map.phys = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER);
+-	lasat_map.virt = ioremap_nocache(
++	lasat_map.virt = (unsigned long)ioremap_nocache(
+ 		        lasat_map.phys, lasat_board_info.li_flash_size);
+ 	lasat_map.size = lasat_board_info.li_flash_size;
+ 
+diff -urpNX dontdiff linux-2.6.10/drivers/mtd/maps/pb1xxx-flash.c linux-2.6.10-mips/drivers/mtd/maps/pb1xxx-flash.c
+--- linux-2.6.10/drivers/mtd/maps/pb1xxx-flash.c	2004-12-24 22:35:40.000000000 +0100
++++ linux-2.6.10-mips/drivers/mtd/maps/pb1xxx-flash.c	2004-12-04 20:57:27.000000000 +0100
+@@ -3,7 +3,7 @@
+  * 
+  * (C) 2001 Pete Popov <ppopov at mvista.com>
+  * 
+- * $Id: pb1xxx-flash.c,v 1.14 2004/11/04 13:24:15 gleixner Exp $
++ * $Id: pb1xxx-flash.c,v 1.11 2004/07/12 21:59:44 dwmw2 Exp $
+  */
+ 
+ #include <linux/config.h>
+@@ -17,6 +17,7 @@
+ #include <linux/mtd/partitions.h>
+ 
+ #include <asm/io.h>
++#include <asm/au1000.h>
+ 
+ #ifdef 	DEBUG_RW
+ #define	DBG(x...)	printk(x)
+@@ -149,7 +150,7 @@ int __init pb1xxx_mtd_init(void)
+ 	 */
+ 	printk(KERN_NOTICE "Pb1xxx flash: probing %d-bit flash bus\n", 
+ 			BUSWIDTH*8);
+-	pb1xxx_mtd_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
++	pb1xxx_mtd_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
+ 
+ 	simple_map_init(&pb1xxx_mtd_map);
+ 
+diff -urpNX dontdiff linux-2.6.10/drivers/net/Kconfig linux-2.6.10-mips/drivers/net/Kconfig
+--- linux-2.6.10/drivers/net/Kconfig	2004-12-24 22:35:25.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/Kconfig	2004-12-04 20:57:27.000000000 +0100
+@@ -444,11 +444,19 @@ config LASI_82596
+ 
+ config MIPS_JAZZ_SONIC
+ 	tristate "MIPS JAZZ onboard SONIC Ethernet support"
+-	depends on NET_ETHERNET && MIPS_JAZZ
++	depends on NET_ETHERNET && MACH_JAZZ
+ 	help
+ 	  This is the driver for the onboard card of MIPS Magnum 4000,
+ 	  Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
+ 
++config GALILEO_64240_ETH
++	tristate "Galileo GT64240 Ethernet support"
++	depends on NET_ETHERNET && MOMENCO_OCELOT_G
++	select MII
++	help
++	  This is the driver for the ethernet interfaces integrated into
++	  the Galileo (now Marvell) GT64240 chipset.
++
+ config MIPS_GT96100ETH
+ 	bool "MIPS GT96100 Ethernet support"
+ 	depends on NET_ETHERNET && MIPS_GT96100
+@@ -463,13 +471,9 @@ config MIPS_AU1X00_ENET
+ 	  If you have an Alchemy Semi AU1X00 based system
+ 	  say Y.  Otherwise, say N.
+ 
+-config NET_SB1250_MAC
+-	tristate "SB1250 Ethernet support"
+-	depends on NET_ETHERNET && SIBYTE_SB1xxx_SOC
+-
+ config SGI_IOC3_ETH
+ 	bool "SGI IOC3 Ethernet"
+-	depends on NET_ETHERNET && SGI_IP27
++	depends on NET_ETHERNET && PCI && SGI_IP27
+ 	select CRC32
+ 	select MII
+ 	help
+@@ -1787,14 +1791,6 @@ config DECLANCE
+ 	  DEC (now Compaq) based on the AMD Lance chipset, including the
+ 	  DEPCA series.  (This chipset is better known via the NE2100 cards.)
+ 
+-config BAGETLANCE
+-	tristate "Baget AMD LANCE support"
+-	depends on NET_ETHERNET && BAGET_MIPS
+-	help
+-	  Say Y to enable kernel support for AMD Lance Ethernet cards on the
+-	  MIPS-32-based Baget embedded system.  This chipset is better known
+-	  via the NE2100 cards.
+-
+ config 68360_ENET
+ 	bool "Motorola 68360 ethernet controller"
+ 	depends on M68360
+@@ -1979,6 +1975,10 @@ config R8169_NAPI
+ 
+ 	  If in doubt, say N.
+ 
++config NET_SB1250_MAC
++	tristate "SB1250 Ethernet support"
++	depends on SIBYTE_SB1xxx_SOC
++
+ config SK98LIN
+ 	tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
+ 	depends on PCI
+@@ -2092,7 +2092,7 @@ config GFAR_NAPI
+ 
+ config MV643XX_ETH
+ 	tristate "MV-643XX Ethernet support"
+-	depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || PPC_CHRP
++	depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MOMENCO_OCELOT_3 || PPC_CHRP
+ 	help
+ 	  This driver supports the gigabit Ethernet on the Marvell MV643XX
+ 	  chipset which is used in the Momenco Ocelot C and Jaguar ATX.
+@@ -2118,6 +2118,20 @@ config MV643XX_ETH_2
+ 	  This enables support for Port 2 of the Marvell MV643XX Gigabit
+ 	  Ethernet.
+ 
++config BIG_SUR_FE
++	bool "PMC-Sierra TITAN Fast Ethernet Support"
++	depends on NET_ETHERNET && PMC_BIG_SUR
++	help
++	  This enables support for the the integrated ethernet of
++	  PMC-Sierra's Big Sur SoC.
++
++config TITAN_GE
++	bool "PMC-Sierra TITAN Gigabit Ethernet Support"
++	depends on PMC_YOSEMITE
++	help
++	  This enables support for the the integrated ethernet of
++	  PMC-Sierra's Titan SoC.
++
+ endmenu
+ 
+ #
+diff -urpNX dontdiff linux-2.6.10/drivers/net/Makefile linux-2.6.10-mips/drivers/net/Makefile
+--- linux-2.6.10/drivers/net/Makefile	2004-12-24 22:34:29.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/Makefile	2004-11-19 01:14:32.000000000 +0100
+@@ -100,6 +100,11 @@ obj-$(CONFIG_NE_H8300) += ne-h8300.o 839
+ 
+ obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
+ 
++obj-$(CONFIG_GALILEO_64240_ETH) += gt64240eth.o
++obj-$(CONFIG_MV64340_ETH) += mv64340_eth.o
++obj-$(CONFIG_BIG_SUR_FE) += big_sur_ge.o
++obj-$(CONFIG_TITAN_GE) += titan_mdio.o titan_ge.o
++
+ obj-$(CONFIG_PPP) += ppp_generic.o slhc.o
+ obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
+ obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
+@@ -162,7 +167,6 @@ obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzson
+ obj-$(CONFIG_MIPS_GT96100ETH) += gt96100eth.o
+ obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
+ obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
+-obj-$(CONFIG_BAGETLANCE) += bagetlance.o
+ obj-$(CONFIG_DECLANCE) += declance.o
+ obj-$(CONFIG_ATARILANCE) += atarilance.o
+ obj-$(CONFIG_ATARI_BIONET) += atari_bionet.o
+diff -urpNX dontdiff linux-2.6.10/drivers/net/Space.c linux-2.6.10-mips/drivers/net/Space.c
+--- linux-2.6.10/drivers/net/Space.c	2004-12-24 22:33:59.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/Space.c	2004-11-19 01:14:32.000000000 +0100
+@@ -302,16 +302,6 @@ static struct devprobe2 m68k_probes[] __
+ 	{NULL, 0},
+ };
+ 
+-static struct devprobe2 mips_probes[] __initdata = {
+-#ifdef CONFIG_MIPS_JAZZ_SONIC
+-	{sonic_probe, 0},
+-#endif
+-#ifdef CONFIG_BAGETLANCE        /* Lance-based Baget ethernet boards */
+-        {bagetlance_probe, 0},
+-#endif
+-	{NULL, 0},
+-};
+-
+ /*
+  * Unified ethernet device probe, segmented per architecture and
+  * per bus interface. This drives the legacy devices only for now.
+@@ -325,7 +315,6 @@ static void __init ethif_probe2(int unit
+ 		return;
+ 
+ 	(void)(	probe_list2(unit, m68k_probes, base_addr == 0) &&
+-		probe_list2(unit, mips_probes, base_addr == 0) &&
+ 		probe_list2(unit, eisa_probes, base_addr == 0) &&
+ 		probe_list2(unit, mca_probes, base_addr == 0) &&
+ 		probe_list2(unit, isa_probes, base_addr == 0) &&
+diff -urpNX dontdiff linux-2.6.10/drivers/net/au1000_eth.c linux-2.6.10-mips/drivers/net/au1000_eth.c
+--- linux-2.6.10/drivers/net/au1000_eth.c	2004-12-24 22:34:57.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/au1000_eth.c	2005-01-10 15:13:24.000000000 +0100
+@@ -1,10 +1,19 @@
+ /*
+- * Alchemy Semi Au1000 ethernet driver
+  *
+- * Copyright 2001 MontaVista Software Inc.
++ * Alchemy Au1x00 ethernet driver
++ *
++ * Copyright 2001,2002,2003 MontaVista Software Inc.
++ * Copyright 2002 TimeSys Corp.
++ * Added ethtool/mii-tool support,
++ * Copyright 2004 Matt Porter <mporter at kernel.crashing.org>
++ * Update: 2004 Bjoern Riemer, riemer at fokus.fraunhofer.de 
++ * or riemer at riemer-nt.de: fixed the link beat detection with 
++ * ioctls (SIOCGMIIPHY)
+  * Author: MontaVista Software, Inc.
+  *         	ppopov at mvista.com or source at mvista.com
+  *
++ * ########################################################################
++ *
+  *  This program is free software; you can distribute it and/or modify it
+  *  under the terms of the GNU General Public License (Version 2) as
+  *  published by the Free Software Foundation.
+@@ -17,46 +26,59 @@
+  *  You should have received a copy of the GNU General Public License along
+  *  with this program; if not, write to the Free Software Foundation, Inc.,
+  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
++ *
++ * ########################################################################
++ *
++ * 
+  */
+-#include <linux/config.h>
+ 
+ #include <linux/module.h>
+ #include <linux/kernel.h>
++#include <linux/sched.h>
+ #include <linux/string.h>
+ #include <linux/timer.h>
+ #include <linux/errno.h>
+ #include <linux/in.h>
+ #include <linux/ioport.h>
++#include <linux/bitops.h>
+ #include <linux/slab.h>
+ #include <linux/interrupt.h>
+ #include <linux/pci.h>
+ #include <linux/init.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
++#include <linux/ethtool.h>
++#include <linux/mii.h>
+ #include <linux/skbuff.h>
+ #include <linux/delay.h>
+-#include <linux/crc32.h>
+-#include <linux/bitops.h>
+-
+ #include <asm/mipsregs.h>
+ #include <asm/irq.h>
+ #include <asm/io.h>
+-#include <asm/au1000.h>
++#include <asm/processor.h>
+ 
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/cpu.h>
+ #include "au1000_eth.h"
+ 
+ #ifdef AU1000_ETH_DEBUG
+-static int au1000_debug = 10;
++static int au1000_debug = 5;
+ #else
+ static int au1000_debug = 3;
+ #endif
+ 
++#define DRV_NAME	"au1000eth"
++#define DRV_VERSION	"1.5"
++#define DRV_AUTHOR	"Pete Popov <ppopov at embeddedalley.com>"
++#define DRV_DESC	"Au1xxx on-chip Ethernet driver"
++
++MODULE_AUTHOR(DRV_AUTHOR);
++MODULE_DESCRIPTION(DRV_DESC);
++MODULE_LICENSE("GPL");
++
+ // prototypes
+-static void *dma_alloc(size_t, dma_addr_t *);
+-static void dma_free(void *, size_t);
+ static void hard_stop(struct net_device *);
+ static void enable_rx_tx(struct net_device *dev);
+-static int __init au1000_probe1(long, int, int);
++static struct net_device * au1000_probe(u32 ioaddr, int irq, int port_num);
+ static int au1000_init(struct net_device *);
+ static int au1000_open(struct net_device *);
+ static int au1000_close(struct net_device *);
+@@ -78,8 +100,7 @@ static void dump_mii(struct net_device *
+ // externs
+ extern  void ack_rise_edge_irq(unsigned int);
+ extern int get_ethernet_addr(char *ethernet_addr);
+-extern inline void str2eaddr(unsigned char *ea, unsigned char *str);
+-extern inline unsigned char str2hexnum(unsigned char c);
++extern void str2eaddr(unsigned char *ea, unsigned char *str);
+ extern char * __init prom_getcmdline(void);
+ 
+ /*
+@@ -97,29 +118,6 @@ extern char * __init prom_getcmdline(voi
+  * complete immediately.
+  */
+ 
+-
+-/*
+- * Base address and interrupt of the Au1xxx ethernet macs
+- */
+-static struct {
+-	unsigned int port;
+-	int irq;
+-} au1000_iflist[NUM_INTERFACES] = {
+-		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
+-		{AU1000_ETH1_BASE, AU1000_ETH1_IRQ}
+-	},
+-  au1500_iflist[NUM_INTERFACES] = {
+-		{AU1500_ETH0_BASE, AU1000_ETH0_IRQ}, 
+-		{AU1500_ETH1_BASE, AU1000_ETH1_IRQ}
+-	},
+-  au1100_iflist[NUM_INTERFACES] = {
+-		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
+-		{0, 0}
+-	};
+-
+-static char version[] __devinitdata =
+-    "au1000eth.c:1.0 ppopov at mvista.com\n";
+-
+ /* These addresses are only used if yamon doesn't tell us what
+  * the mac address is, and the mac address is not passed on the
+  * command line.
+@@ -135,18 +133,401 @@ static unsigned char au1000_mac_addr[6] 
+ #define cpu_to_dma32 cpu_to_be32
+ #define dma32_to_cpu be32_to_cpu
+ 
++struct au1000_private *au_macs[NUM_ETH_INTERFACES];
+ 
+ /* FIXME 
+  * All of the PHY code really should be detached from the MAC 
+  * code.
+  */
+ 
+-int bcm_5201_init(struct net_device *dev, int phy_addr)
++/* Default advertise */
++#define GENMII_DEFAULT_ADVERTISE \
++	ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
++	ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
++	ADVERTISED_Autoneg
++
++#define GENMII_DEFAULT_FEATURES \
++	SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
++	SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
++	SUPPORTED_Autoneg
++
++static char *phy_link[] = 
++{	"unknown", 
++	"10Base2", "10BaseT", 
++	"AUI",
++	"100BaseT", "100BaseTX", "100BaseFX"
++};
++
++int bcm_5201_init(struct net_device *dev, int phy_addr)
++{
++	s16 data;
++	
++	/* Stop auto-negotiation */
++	data = mdio_read(dev, phy_addr, MII_CONTROL);
++	mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO);
++
++	/* Set advertisement to 10/100 and Half/Full duplex
++	 * (full capabilities) */
++	data = mdio_read(dev, phy_addr, MII_ANADV);
++	data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T;
++	mdio_write(dev, phy_addr, MII_ANADV, data);
++	
++	/* Restart auto-negotiation */
++	data = mdio_read(dev, phy_addr, MII_CONTROL);
++	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
++	mdio_write(dev, phy_addr, MII_CONTROL, data);
++
++	if (au1000_debug > 4) 
++		dump_mii(dev, phy_addr);
++	return 0;
++}
++
++int bcm_5201_reset(struct net_device *dev, int phy_addr)
++{
++	s16 mii_control, timeout;
++	
++	mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
++	mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET);
++	mdelay(1);
++	for (timeout = 100; timeout > 0; --timeout) {
++		mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
++		if ((mii_control & MII_CNTL_RESET) == 0)
++			break;
++		mdelay(1);
++	}
++	if (mii_control & MII_CNTL_RESET) {
++		printk(KERN_ERR "%s PHY reset timeout !\n", dev->name);
++		return -1;
++	}
++	return 0;
++}
++
++int 
++bcm_5201_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
++{
++	u16 mii_data;
++	struct au1000_private *aup;
++
++	if (!dev) {
++		printk(KERN_ERR "bcm_5201_status error: NULL dev\n");
++		return -1;
++	}
++	aup = (struct au1000_private *) dev->priv;
++
++	mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS);
++	if (mii_data & MII_STAT_LINK) {
++		*link = 1;
++		mii_data = mdio_read(dev, aup->phy_addr, MII_AUX_CNTRL);
++		if (mii_data & MII_AUX_100) {
++			if (mii_data & MII_AUX_FDX) {
++				*speed = IF_PORT_100BASEFX;
++				dev->if_port = IF_PORT_100BASEFX;
++			}
++			else {
++				*speed = IF_PORT_100BASETX;
++				dev->if_port = IF_PORT_100BASETX;
++			}
++		}
++		else  {
++			*speed = IF_PORT_10BASET;
++			dev->if_port = IF_PORT_10BASET;
++		}
++
++	}
++	else {
++		*link = 0;
++		*speed = 0;
++		dev->if_port = IF_PORT_UNKNOWN;
++	}
++	return 0;
++}
++
++int lsi_80227_init(struct net_device *dev, int phy_addr)
++{
++	if (au1000_debug > 4)
++		printk("lsi_80227_init\n");
++
++	/* restart auto-negotiation */
++	mdio_write(dev, phy_addr, MII_CONTROL,
++		   MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_RST_AUTO); // | MII_CNTL_FDX);
++	mdelay(1);
++
++	/* set up LEDs to correct display */
++#ifdef CONFIG_MIPS_MTX1
++	mdio_write(dev, phy_addr, 17, 0xff80);
++#else
++	mdio_write(dev, phy_addr, 17, 0xffc0);
++#endif
++
++	if (au1000_debug > 4)
++		dump_mii(dev, phy_addr);
++	return 0;
++}
++
++int lsi_80227_reset(struct net_device *dev, int phy_addr)
++{
++	s16 mii_control, timeout;
++	
++	if (au1000_debug > 4) {
++		printk("lsi_80227_reset\n");
++		dump_mii(dev, phy_addr);
++	}
++
++	mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
++	mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET);
++	mdelay(1);
++	for (timeout = 100; timeout > 0; --timeout) {
++		mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
++		if ((mii_control & MII_CNTL_RESET) == 0)
++			break;
++		mdelay(1);
++	}
++	if (mii_control & MII_CNTL_RESET) {
++		printk(KERN_ERR "%s PHY reset timeout !\n", dev->name);
++		return -1;
++	}
++	return 0;
++}
++
++int
++lsi_80227_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
++{
++	u16 mii_data;
++	struct au1000_private *aup;
++
++	if (!dev) {
++		printk(KERN_ERR "lsi_80227_status error: NULL dev\n");
++		return -1;
++	}
++	aup = (struct au1000_private *) dev->priv;
++
++	mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS);
++	if (mii_data & MII_STAT_LINK) {
++		*link = 1;
++		mii_data = mdio_read(dev, aup->phy_addr, MII_LSI_PHY_STAT);
++		if (mii_data & MII_LSI_PHY_STAT_SPD) {
++			if (mii_data & MII_LSI_PHY_STAT_FDX) {
++				*speed = IF_PORT_100BASEFX;
++				dev->if_port = IF_PORT_100BASEFX;
++			}
++			else {
++				*speed = IF_PORT_100BASETX;
++				dev->if_port = IF_PORT_100BASETX;
++			}
++		}
++		else  {
++			*speed = IF_PORT_10BASET;
++			dev->if_port = IF_PORT_10BASET;
++		}
++
++	}
++	else {
++		*link = 0;
++		*speed = 0;
++		dev->if_port = IF_PORT_UNKNOWN;
++	}
++	return 0;
++}
++
++int am79c901_init(struct net_device *dev, int phy_addr)
++{
++	printk("am79c901_init\n");
++	return 0;
++}
++
++int am79c901_reset(struct net_device *dev, int phy_addr)
++{
++	printk("am79c901_reset\n");
++	return 0;
++}
++
++int 
++am79c901_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
++{
++	return 0;
++}
++
++int am79c874_init(struct net_device *dev, int phy_addr)
++{
++	s16 data;
++
++	/* 79c874 has quit resembled bit assignments to BCM5201 */
++	if (au1000_debug > 4)
++		printk("am79c847_init\n");
++
++	/* Stop auto-negotiation */
++	data = mdio_read(dev, phy_addr, MII_CONTROL);
++	mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO);
++
++	/* Set advertisement to 10/100 and Half/Full duplex
++	 * (full capabilities) */
++	data = mdio_read(dev, phy_addr, MII_ANADV);
++	data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T;
++	mdio_write(dev, phy_addr, MII_ANADV, data);
++	
++	/* Restart auto-negotiation */
++	data = mdio_read(dev, phy_addr, MII_CONTROL);
++	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
++
++	mdio_write(dev, phy_addr, MII_CONTROL, data);
++
++	if (au1000_debug > 4) dump_mii(dev, phy_addr);
++	return 0;
++}
++
++int am79c874_reset(struct net_device *dev, int phy_addr)
++{
++	s16 mii_control, timeout;
++	
++	if (au1000_debug > 4)
++		printk("am79c874_reset\n");
++
++	mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
++	mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET);
++	mdelay(1);
++	for (timeout = 100; timeout > 0; --timeout) {
++		mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
++		if ((mii_control & MII_CNTL_RESET) == 0)
++			break;
++		mdelay(1);
++	}
++	if (mii_control & MII_CNTL_RESET) {
++		printk(KERN_ERR "%s PHY reset timeout !\n", dev->name);
++		return -1;
++	}
++	return 0;
++}
++
++int 
++am79c874_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
++{
++	u16 mii_data;
++	struct au1000_private *aup;
++
++	// printk("am79c874_status\n");
++	if (!dev) {
++		printk(KERN_ERR "am79c874_status error: NULL dev\n");
++		return -1;
++	}
++
++	aup = (struct au1000_private *) dev->priv;
++	mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS);
++
++	if (mii_data & MII_STAT_LINK) {
++		*link = 1;
++		mii_data = mdio_read(dev, aup->phy_addr, MII_AMD_PHY_STAT);
++		if (mii_data & MII_AMD_PHY_STAT_SPD) {
++			if (mii_data & MII_AMD_PHY_STAT_FDX) {
++				*speed = IF_PORT_100BASEFX;
++				dev->if_port = IF_PORT_100BASEFX;
++			}
++			else {
++				*speed = IF_PORT_100BASETX;
++				dev->if_port = IF_PORT_100BASETX;
++			}
++		}
++		else {
++			*speed = IF_PORT_10BASET;
++			dev->if_port = IF_PORT_10BASET;
++		}
++
++	}
++	else {
++		*link = 0;
++		*speed = 0;
++		dev->if_port = IF_PORT_UNKNOWN;
++	}
++	return 0;
++}
++
++int lxt971a_init(struct net_device *dev, int phy_addr)
++{
++	if (au1000_debug > 4)
++		printk("lxt971a_init\n");
++
++	/* restart auto-negotiation */
++	mdio_write(dev, phy_addr, MII_CONTROL,
++		   MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_RST_AUTO | MII_CNTL_FDX);
++
++	/* set up LEDs to correct display */
++	mdio_write(dev, phy_addr, 20, 0x0422);
++
++	if (au1000_debug > 4)
++		dump_mii(dev, phy_addr);
++	return 0;
++}
++
++int lxt971a_reset(struct net_device *dev, int phy_addr)
++{
++	s16 mii_control, timeout;
++	
++	if (au1000_debug > 4) {
++		printk("lxt971a_reset\n");
++		dump_mii(dev, phy_addr);
++	}
++
++	mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
++	mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET);
++	mdelay(1);
++	for (timeout = 100; timeout > 0; --timeout) {
++		mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
++		if ((mii_control & MII_CNTL_RESET) == 0)
++			break;
++		mdelay(1);
++	}
++	if (mii_control & MII_CNTL_RESET) {
++		printk(KERN_ERR "%s PHY reset timeout !\n", dev->name);
++		return -1;
++	}
++	return 0;
++}
++
++int
++lxt971a_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
++{
++	u16 mii_data;
++	struct au1000_private *aup;
++
++	if (!dev) {
++		printk(KERN_ERR "lxt971a_status error: NULL dev\n");
++		return -1;
++	}
++	aup = (struct au1000_private *) dev->priv;
++
++	mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS);
++	if (mii_data & MII_STAT_LINK) {
++		*link = 1;
++		mii_data = mdio_read(dev, aup->phy_addr, MII_INTEL_PHY_STAT);
++		if (mii_data & MII_INTEL_PHY_STAT_SPD) {
++			if (mii_data & MII_INTEL_PHY_STAT_FDX) {
++				*speed = IF_PORT_100BASEFX;
++				dev->if_port = IF_PORT_100BASEFX;
++			}
++			else {
++				*speed = IF_PORT_100BASETX;
++				dev->if_port = IF_PORT_100BASETX;
++			}
++		}
++		else  {
++			*speed = IF_PORT_10BASET;
++			dev->if_port = IF_PORT_10BASET;
++		}
++
++	}
++	else {
++		*link = 0;
++		*speed = 0;
++		dev->if_port = IF_PORT_UNKNOWN;
++	}
++	return 0;
++}
++
++int ks8995m_init(struct net_device *dev, int phy_addr)
+ {
+ 	s16 data;
+ 	
++//	printk("ks8995m_init\n");
+ 	/* Stop auto-negotiation */
+-	//printk("bcm_5201_init\n");
+ 	data = mdio_read(dev, phy_addr, MII_CONTROL);
+ 	mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO);
+ 
+@@ -161,25 +542,16 @@ int bcm_5201_init(struct net_device *dev
+ 	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
+ 	mdio_write(dev, phy_addr, MII_CONTROL, data);
+ 
+-	/* Enable TX LED instead of FDX */
+-	data = mdio_read(dev, phy_addr, MII_INT);
+-	data &= ~MII_FDX_LED;
+-	mdio_write(dev, phy_addr, MII_INT, data);
+-
+-	/* Enable TX LED instead of FDX */
+-	data = mdio_read(dev, phy_addr, MII_INT);
+-	data &= ~MII_FDX_LED;
+-	mdio_write(dev, phy_addr, MII_INT, data);
+-
+ 	if (au1000_debug > 4) dump_mii(dev, phy_addr);
++
+ 	return 0;
+ }
+ 
+-int bcm_5201_reset(struct net_device *dev, int phy_addr)
++int ks8995m_reset(struct net_device *dev, int phy_addr)
+ {
+ 	s16 mii_control, timeout;
+ 	
+-	//printk("bcm_5201_reset\n");
++//	printk("ks8995m_reset\n");
+ 	mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
+ 	mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET);
+ 	mdelay(1);
+@@ -196,14 +568,13 @@ int bcm_5201_reset(struct net_device *de
+ 	return 0;
+ }
+ 
+-int 
+-bcm_5201_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
++int ks8995m_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
+ {
+ 	u16 mii_data;
+ 	struct au1000_private *aup;
+ 
+ 	if (!dev) {
+-		printk(KERN_ERR "bcm_5201_status error: NULL dev\n");
++		printk(KERN_ERR "ks8995m_status error: NULL dev\n");
+ 		return -1;
+ 	}
+ 	aup = (struct au1000_private *) dev->priv;
+@@ -222,7 +593,7 @@ bcm_5201_status(struct net_device *dev, 
+ 				dev->if_port = IF_PORT_100BASETX;
+ 			}
+ 		}
+-		else  {
++		else  {											
+ 			*speed = IF_PORT_10BASET;
+ 			dev->if_port = IF_PORT_10BASET;
+ 		}
+@@ -236,32 +607,41 @@ bcm_5201_status(struct net_device *dev, 
+ 	return 0;
+ }
+ 
+-int lsi_80227_init(struct net_device *dev, int phy_addr)
++int
++smsc_83C185_init (struct net_device *dev, int phy_addr)
+ {
++	s16 data;
++
+ 	if (au1000_debug > 4)
+-		printk("lsi_80227_init\n");
++		printk("smsc_83C185_init\n");
+ 
+-	/* restart auto-negotiation */
+-	mdio_write(dev, phy_addr, 0, 0x3200);
++	/* Stop auto-negotiation */
++	data = mdio_read(dev, phy_addr, MII_CONTROL);
++	mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO);
+ 
+-	mdelay(1);
++	/* Set advertisement to 10/100 and Half/Full duplex
++	 * (full capabilities) */
++	data = mdio_read(dev, phy_addr, MII_ANADV);
++	data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T;
++	mdio_write(dev, phy_addr, MII_ANADV, data);
++	
++	/* Restart auto-negotiation */
++	data = mdio_read(dev, phy_addr, MII_CONTROL);
++	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
+ 
+-	/* set up LEDs to correct display */
+-	mdio_write(dev, phy_addr, 17, 0xffc0);
++	mdio_write(dev, phy_addr, MII_CONTROL, data);
+ 
+-	if (au1000_debug > 4)
+-		dump_mii(dev, phy_addr);
++	if (au1000_debug > 4) dump_mii(dev, phy_addr);
+ 	return 0;
+ }
+ 
+-int lsi_80227_reset(struct net_device *dev, int phy_addr)
++int
++smsc_83C185_reset (struct net_device *dev, int phy_addr)
+ {
+ 	s16 mii_control, timeout;
+ 	
+-	if (au1000_debug > 4) {
+-		printk("lsi_80227_reset\n");
+-		dump_mii(dev, phy_addr);
+-	}
++	if (au1000_debug > 4)
++		printk("smsc_83C185_reset\n");
+ 
+ 	mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
+ 	mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET);
+@@ -279,24 +659,25 @@ int lsi_80227_reset(struct net_device *d
+ 	return 0;
+ }
+ 
+-int
+-lsi_80227_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
++int 
++smsc_83C185_status (struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
+ {
+ 	u16 mii_data;
+ 	struct au1000_private *aup;
+ 
+ 	if (!dev) {
+-		printk(KERN_ERR "lsi_80227_status error: NULL dev\n");
++		printk(KERN_ERR "smsc_83C185_status error: NULL dev\n");
+ 		return -1;
+ 	}
+-	aup = (struct au1000_private *) dev->priv;
+ 
++	aup = (struct au1000_private *) dev->priv;
+ 	mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS);
++
+ 	if (mii_data & MII_STAT_LINK) {
+ 		*link = 1;
+-		mii_data = mdio_read(dev, aup->phy_addr, MII_LSI_STAT);
+-		if (mii_data & MII_LSI_STAT_SPD) {
+-			if (mii_data & MII_LSI_STAT_FDX) {
++		mii_data = mdio_read(dev, aup->phy_addr, 0x1f);
++		if (mii_data & (1<<3)) {
++			if (mii_data & (1<<4)) {
+ 				*speed = IF_PORT_100BASEFX;
+ 				dev->if_port = IF_PORT_100BASEFX;
+ 			}
+@@ -305,11 +686,10 @@ lsi_80227_status(struct net_device *dev,
+ 				dev->if_port = IF_PORT_100BASETX;
+ 			}
+ 		}
+-		else  {
++		else {
+ 			*speed = IF_PORT_10BASET;
+ 			dev->if_port = IF_PORT_10BASET;
+ 		}
+-
+ 	}
+ 	else {
+ 		*link = 0;
+@@ -319,23 +699,31 @@ lsi_80227_status(struct net_device *dev,
+ 	return 0;
+ }
+ 
+-int am79c901_init(struct net_device *dev, int phy_addr)
++
++#ifdef CONFIG_MIPS_BOSPORUS
++int stub_init(struct net_device *dev, int phy_addr)
+ {
+-	printk("am79c901_init\n");
++	//printk("PHY stub_init\n");
+ 	return 0;
+ }
+ 
+-int am79c901_reset(struct net_device *dev, int phy_addr)
++int stub_reset(struct net_device *dev, int phy_addr)
+ {
+-	printk("am79c901_reset\n");
++	//printk("PHY stub_reset\n");
+ 	return 0;
+ }
+ 
+ int 
+-am79c901_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
++stub_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
+ {
++	//printk("PHY stub_status\n");
++	*link = 1;
++	/* hmmm, revisit */
++	*speed = IF_PORT_100BASEFX;
++	dev->if_port = IF_PORT_100BASEFX;
+ 	return 0;
+ }
++#endif
+ 
+ struct phy_ops bcm_5201_ops = {
+ 	bcm_5201_init,
+@@ -343,6 +731,12 @@ struct phy_ops bcm_5201_ops = {
+ 	bcm_5201_status,
+ };
+ 
++struct phy_ops am79c874_ops = {
++	am79c874_init,
++	am79c874_reset,
++	am79c874_status,
++};
++
+ struct phy_ops am79c901_ops = {
+ 	am79c901_init,
+ 	am79c901_reset,
+@@ -355,26 +749,89 @@ struct phy_ops lsi_80227_ops = { 
+ 	lsi_80227_status,
+ };
+ 
++struct phy_ops lxt971a_ops = { 
++	lxt971a_init,
++	lxt971a_reset,
++	lxt971a_status,
++};
++
++struct phy_ops ks8995m_ops = {
++	ks8995m_init,
++	ks8995m_reset,
++	ks8995m_status,
++};
++
++struct phy_ops smsc_83C185_ops = {
++	smsc_83C185_init,
++	smsc_83C185_reset,
++	smsc_83C185_status,
++};
++
++#ifdef CONFIG_MIPS_BOSPORUS
++struct phy_ops stub_ops = {
++	stub_init,
++	stub_reset,
++	stub_status,
++};
++#endif
++
+ static struct mii_chip_info {
+ 	const char * name;
+ 	u16 phy_id0;
+ 	u16 phy_id1;
+ 	struct phy_ops *phy_ops;	
++	int dual_phy;
+ } mii_chip_table[] = {
+-	{"Broadcom BCM5201 10/100 BaseT PHY",  0x0040, 0x6212, &bcm_5201_ops },
+-	{"AMD 79C901 HomePNA PHY",  0x0000, 0x35c8, &am79c901_ops },
+-	{"LSI 80227 10/100 BaseT PHY", 0x0016, 0xf840, &lsi_80227_ops },
+-	{"Broadcom BCM5221 10/100 BaseT PHY",  0x0040, 0x61e4, &bcm_5201_ops },
++	{"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0},
++	{"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0},
++	{"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1},
++	{"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0},
++	{"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0},
++	{"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0},
++	{"Intel LXT971A Dual Speed PHY",0x0013,0x78e2, &lxt971a_ops,0},
++	{"Kendin KS8995M 10/100 BaseT PHY",0x0022,0x1450, &ks8995m_ops,0},
++	{"SMSC LAN83C185 10/100 BaseT PHY",0x0007,0xc0a3, &smsc_83C185_ops,0},
++#ifdef CONFIG_MIPS_BOSPORUS
++	{"Stub", 0x1234, 0x5678, &stub_ops },
++#endif
+ 	{0,},
+ };
+ 
+ static int mdio_read(struct net_device *dev, int phy_id, int reg)
+ {
+ 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
++	volatile u32 *mii_control_reg;
++	volatile u32 *mii_data_reg;
+ 	u32 timedout = 20;
+ 	u32 mii_control;
+ 
+-	while (aup->mac->mii_control & MAC_MII_BUSY) {
++	#ifdef CONFIG_BCM5222_DUAL_PHY
++	/* First time we probe, it's for the mac0 phy.
++	 * Since we haven't determined yet that we have a dual phy,
++	 * aup->mii->mii_control_reg won't be setup and we'll
++	 * default to the else statement.
++	 * By the time we probe for the mac1 phy, the mii_control_reg
++	 * will be setup to be the address of the mac0 phy control since
++	 * both phys are controlled through mac0.
++	 */
++	if (aup->mii && aup->mii->mii_control_reg) {
++		mii_control_reg = aup->mii->mii_control_reg;
++		mii_data_reg = aup->mii->mii_data_reg;
++	}
++	else if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) {
++		/* assume both phys are controlled through mac0 */
++		mii_control_reg = au_macs[0]->mii->mii_control_reg;
++		mii_data_reg = au_macs[0]->mii->mii_data_reg;
++	}
++	else 
++	#endif
++	{
++		/* default control and data reg addresses */
++		mii_control_reg = &aup->mac->mii_control;
++		mii_data_reg = &aup->mac->mii_data;
++	}
++
++	while (*mii_control_reg & MAC_MII_BUSY) {
+ 		mdelay(1);
+ 		if (--timedout == 0) {
+ 			printk(KERN_ERR "%s: read_MII busy timeout!!\n", 
+@@ -386,10 +843,10 @@ static int mdio_read(struct net_device *
+ 	mii_control = MAC_SET_MII_SELECT_REG(reg) | 
+ 		MAC_SET_MII_SELECT_PHY(phy_id) | MAC_MII_READ;
+ 
+-	aup->mac->mii_control = mii_control;
++	*mii_control_reg = mii_control;
+ 
+ 	timedout = 20;
+-	while (aup->mac->mii_control & MAC_MII_BUSY) {
++	while (*mii_control_reg & MAC_MII_BUSY) {
+ 		mdelay(1);
+ 		if (--timedout == 0) {
+ 			printk(KERN_ERR "%s: mdio_read busy timeout!!\n", 
+@@ -397,16 +854,36 @@ static int mdio_read(struct net_device *
+ 			return -1;
+ 		}
+ 	}
+-	return (int)aup->mac->mii_data;
++	return (int)*mii_data_reg;
+ }
+ 
+ static void mdio_write(struct net_device *dev, int phy_id, int reg, u16 value)
+ {
+ 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
++	volatile u32 *mii_control_reg;
++	volatile u32 *mii_data_reg;
+ 	u32 timedout = 20;
+ 	u32 mii_control;
+ 
+-	while (aup->mac->mii_control & MAC_MII_BUSY) {
++	#ifdef CONFIG_BCM5222_DUAL_PHY
++	if (aup->mii && aup->mii->mii_control_reg) {
++		mii_control_reg = aup->mii->mii_control_reg;
++		mii_data_reg = aup->mii->mii_data_reg;
++	}
++	else if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) {
++		/* assume both phys are controlled through mac0 */
++		mii_control_reg = au_macs[0]->mii->mii_control_reg;
++		mii_data_reg = au_macs[0]->mii->mii_data_reg;
++	}
++	else 
++	#endif
++	{
++		/* default control and data reg addresses */
++		mii_control_reg = &aup->mac->mii_control;
++		mii_data_reg = &aup->mac->mii_data;
++	}
++
++	while (*mii_control_reg & MAC_MII_BUSY) {
+ 		mdelay(1);
+ 		if (--timedout == 0) {
+ 			printk(KERN_ERR "%s: mdio_write busy timeout!!\n", 
+@@ -418,8 +895,8 @@ static void mdio_write(struct net_device
+ 	mii_control = MAC_SET_MII_SELECT_REG(reg) | 
+ 		MAC_SET_MII_SELECT_PHY(phy_id) | MAC_MII_WRITE;
+ 
+-	aup->mac->mii_data = value;
+-	aup->mac->mii_control = mii_control;
++	*mii_data_reg = value;
++	*mii_control_reg = mii_control;
+ }
+ 
+ 
+@@ -437,12 +914,13 @@ static void dump_mii(struct net_device *
+ 	}
+ }
+ 
+-static int __init mii_probe (struct net_device * dev)
++static int mii_probe (struct net_device * dev)
+ {
+ 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ 	int phy_addr;
+-
+-	aup->mii = NULL;
++#ifdef CONFIG_MIPS_BOSPORUS
++	int phy_found=0;
++#endif
+ 
+ 	/* search for total of 32 possible mii phy addresses */
+ 	for (phy_addr = 0; phy_addr < 32; phy_addr++) {
+@@ -450,9 +928,17 @@ static int __init mii_probe (struct net_
+ 		u16 phy_id0, phy_id1;
+ 		int i;
+ 
++		#ifdef CONFIG_BCM5222_DUAL_PHY
++		/* Mask the already found phy, try next one */
++		if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) {
++			if (au_macs[0]->phy_addr == phy_addr)
++				continue;
++		}
++		#endif
++
+ 		mii_status = mdio_read(dev, phy_addr, MII_STATUS);
+ 		if (mii_status == 0xffff || mii_status == 0x0000)
+-			/* the mii is not accessible, try next one */
++			/* the mii is not accessable, try next one */
+ 			continue;
+ 
+ 		phy_id0 = mdio_read(dev, phy_addr, MII_PHY_ID0);
+@@ -462,6 +948,66 @@ static int __init mii_probe (struct net_
+ 		for (i = 0; mii_chip_table[i].phy_id1; i++) {
+ 			if (phy_id0 == mii_chip_table[i].phy_id0 &&
+ 			    phy_id1 == mii_chip_table[i].phy_id1) {
++				struct mii_phy * mii_phy = aup->mii;
++
++				printk(KERN_INFO "%s: %s at phy address %d\n",
++				       dev->name, mii_chip_table[i].name, 
++				       phy_addr);
++#ifdef CONFIG_MIPS_BOSPORUS
++				phy_found = 1;
++#endif
++				mii_phy->chip_info = mii_chip_table+i;
++				aup->phy_addr = phy_addr;
++				aup->want_autoneg = 1;
++				aup->phy_ops = mii_chip_table[i].phy_ops;
++				aup->phy_ops->phy_init(dev,phy_addr);
++
++				// Check for dual-phy and then store required 
++				// values and set indicators. We need to do 
++				// this now since mdio_{read,write} need the 
++				// control and data register addresses.
++				#ifdef CONFIG_BCM5222_DUAL_PHY
++				if ( mii_chip_table[i].dual_phy) {
++
++					/* assume both phys are controlled 
++					 * through MAC0. Board specific? */
++					
++					/* sanity check */
++					if (!au_macs[0] || !au_macs[0]->mii)
++						return -1;
++					aup->mii->mii_control_reg = (u32 *)
++						&au_macs[0]->mac->mii_control;
++					aup->mii->mii_data_reg = (u32 *)
++						&au_macs[0]->mac->mii_data;
++				}
++				#endif
++				goto found;
++			}
++		}
++	}
++found:
++
++#ifdef CONFIG_MIPS_BOSPORUS
++	/* This is a workaround for the Micrel/Kendin 5 port switch
++	   The second MAC doesn't see a PHY connected... so we need to
++	   trick it into thinking we have one.
++		
++	   If this kernel is run on another Au1500 development board
++	   the stub will be found as well as the actual PHY. However,
++	   the last found PHY will be used... usually at Addr 31 (Db1500).	
++	*/
++	if ( (!phy_found) )
++	{
++		u16 phy_id0, phy_id1;
++		int i;
++
++		phy_id0 = 0x1234;
++		phy_id1 = 0x5678;
++
++		/* search our mii table for the current mii */ 
++		for (i = 0; mii_chip_table[i].phy_id1; i++) {
++			if (phy_id0 == mii_chip_table[i].phy_id0 &&
++			    phy_id1 == mii_chip_table[i].phy_id1) {
+ 				struct mii_phy * mii_phy;
+ 
+ 				printk(KERN_INFO "%s: %s at phy address %d\n",
+@@ -471,31 +1017,39 @@ static int __init mii_probe (struct net_
+ 						GFP_KERNEL);
+ 				if (mii_phy) {
+ 					mii_phy->chip_info = mii_chip_table+i;
+-					mii_phy->phy_addr = phy_addr;
++					aup->phy_addr = phy_addr;
+ 					mii_phy->next = aup->mii;
+ 					aup->phy_ops = 
+ 						mii_chip_table[i].phy_ops;
+ 					aup->mii = mii_phy;
+ 					aup->phy_ops->phy_init(dev,phy_addr);
+ 				} else {
+-					printk(KERN_ERR "%s: out of memory\n",
++					printk(KERN_ERR "%s: out of memory\n", 
+ 							dev->name);
+ 					return -1;
+ 				}
+-				/* the current mii is on our mii_info_table,
+-				   try next address */
++				mii_phy->chip_info = mii_chip_table+i;
++				aup->phy_addr = phy_addr;
++				aup->phy_ops = mii_chip_table[i].phy_ops;
++				aup->phy_ops->phy_init(dev,phy_addr);
+ 				break;
+ 			}
+ 		}
+ 	}
++	if (aup->mac_id == 0) {
++		/* the Bosporus phy responds to addresses 0-5 but 
++		 * 5 is the correct one.
++		 */
++		aup->phy_addr = 5;
++	}
++#endif
+ 
+-	if (aup->mii == NULL) {
+-		printk(KERN_ERR "%s: No MII transceivers found!\n", dev->name);
++	if (aup->mii->chip_info == NULL) {
++		printk(KERN_ERR "%s: Au1x No MII transceivers found!\n",
++				dev->name);
+ 		return -1;
+ 	}
+ 
+-	/* use last PHY */
+-	aup->phy_addr = aup->mii->phy_addr;
+ 	printk(KERN_INFO "%s: Using %s as default\n", 
+ 			dev->name, aup->mii->chip_info->name);
+ 
+@@ -516,7 +1070,6 @@ static db_dest_t *GetFreeDB(struct au100
+ 	if (pDB) {
+ 		aup->pDBfree = pDB->pnext;
+ 	}
+-	//printk("GetFreeDB: %x\n", pDB);
+ 	return pDB;
+ }
+ 
+@@ -528,35 +1081,6 @@ void ReleaseDB(struct au1000_private *au
+ 	aup->pDBfree = pDB;
+ }
+ 
+-
+-/*
+-  DMA memory allocation, derived from pci_alloc_consistent.
+-  However, the Au1000 data cache is coherent (when programmed
+-  so), therefore we return KSEG0 address, not KSEG1.
+-*/
+-static void *dma_alloc(size_t size, dma_addr_t * dma_handle)
+-{
+-	void *ret;
+-	int gfp = GFP_ATOMIC | GFP_DMA;
+-
+-	ret = (void *) __get_free_pages(gfp, get_order(size));
+-
+-	if (ret != NULL) {
+-		memset(ret, 0, size);
+-		*dma_handle = virt_to_bus(ret);
+-		ret = (void *)KSEG0ADDR(ret);
+-	}
+-	return ret;
+-}
+-
+-
+-static void dma_free(void *vaddr, size_t size)
+-{
+-	vaddr = (void *)KSEG0ADDR(vaddr);
+-	free_pages((unsigned long) vaddr, get_order(size));
+-}
+-
+-
+ static void enable_rx_tx(struct net_device *dev)
+ {
+ 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
+@@ -582,6 +1106,7 @@ static void hard_stop(struct net_device 
+ 
+ static void reset_mac(struct net_device *dev)
+ {
++	int i;
+ 	u32 flags;
+ 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
+ 
+@@ -590,13 +1115,32 @@ static void reset_mac(struct net_device 
+ 				dev->name, (unsigned)aup);
+ 
+ 	spin_lock_irqsave(&aup->lock, flags);
+-	del_timer(&aup->timer);
++	if (aup->timer.function == &au1000_timer) {/* check if timer initted */
++		del_timer(&aup->timer);
++	}
++
+ 	hard_stop(dev);
+-	*aup->enable = MAC_EN_CLOCK_ENABLE;
+-	au_sync_delay(2);
+-       	*aup->enable = 0;
+-	au_sync_delay(2);
++	#ifdef CONFIG_BCM5222_DUAL_PHY
++	if (aup->mac_id != 0) {
++	#endif
++		/* If BCM5222, we can't leave MAC0 in reset because then 
++		 * we can't access the dual phy for ETH1 */
++		*aup->enable = MAC_EN_CLOCK_ENABLE;
++		au_sync_delay(2);
++		*aup->enable = 0;
++		au_sync_delay(2);
++	#ifdef CONFIG_BCM5222_DUAL_PHY
++	}
++	#endif
+ 	aup->tx_full = 0;
++	for (i = 0; i < NUM_RX_DMA; i++) {
++		/* reset control bits */
++		aup->rx_dma_ring[i]->buff_stat &= ~0xf;
++	}
++	for (i = 0; i < NUM_TX_DMA; i++) {
++		/* reset control bits */
++		aup->tx_dma_ring[i]->buff_stat &= ~0xf;
++	}
+ 	spin_unlock_irqrestore(&aup->lock, flags);
+ }
+ 
+@@ -611,93 +1155,348 @@ setup_hw_rings(struct au1000_private *au
+ {
+ 	int i;
+ 
+-	for (i=0; i<NUM_RX_DMA; i++) {
++	for (i = 0; i < NUM_RX_DMA; i++) {
+ 		aup->rx_dma_ring[i] = 
+ 			(volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i);
+ 	}
+-	for (i=0; i<NUM_TX_DMA; i++) {
++	for (i = 0; i < NUM_TX_DMA; i++) {
+ 		aup->tx_dma_ring[i] = 
+ 			(volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i);
+ 	}
+ }
+ 
++static struct {
++	int port;
++	u32 base_addr;
++	u32 macen_addr;
++	int irq;
++	struct net_device *dev;
++} iflist[2];
++
++static int num_ifs;
++
++/*
++ * Setup the base address and interupt of the Au1xxx ethernet macs
++ * based on cpu type and whether the interface is enabled in sys_pinfunc
++ * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
++ */
+ static int __init au1000_init_module(void)
+ {
+-	int i;
+-	int prid;
+-	int base_addr, irq;
++	struct cpuinfo_mips *c = &current_cpu_data;
++	int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
++	struct net_device *dev;
++	int i, found_one = 0;
++
++	switch (c->cputype) {
++#ifdef CONFIG_SOC_AU1000
++	case CPU_AU1000:
++		num_ifs = 2 - ni;
++		iflist[0].base_addr = AU1000_ETH0_BASE;
++		iflist[1].base_addr = AU1000_ETH1_BASE;
++		iflist[0].macen_addr = AU1000_MAC0_ENABLE;
++		iflist[1].macen_addr = AU1000_MAC1_ENABLE;
++		iflist[0].irq = AU1000_MAC0_DMA_INT;
++		iflist[1].irq = AU1000_MAC1_DMA_INT;
++		break;
++#endif
++#ifdef CONFIG_SOC_AU1100
++	case CPU_AU1100:
++		num_ifs = 1 - ni;
++		iflist[0].base_addr = AU1100_ETH0_BASE;
++		iflist[0].macen_addr = AU1100_MAC0_ENABLE;
++		iflist[0].irq = AU1100_MAC0_DMA_INT;
++		break;
++#endif
++#ifdef CONFIG_SOC_AU1500
++	case CPU_AU1500:
++		num_ifs = 2 - ni;
++		iflist[0].base_addr = AU1500_ETH0_BASE;
++		iflist[1].base_addr = AU1500_ETH1_BASE;
++		iflist[0].macen_addr = AU1500_MAC0_ENABLE;
++		iflist[1].macen_addr = AU1500_MAC1_ENABLE;
++		iflist[0].irq = AU1500_MAC0_DMA_INT;
++		iflist[1].irq = AU1500_MAC1_DMA_INT;
++		break;
++#endif
++#ifdef CONFIG_SOC_AU1550
++	case CPU_AU1550:
++		num_ifs = 2 - ni;
++		iflist[0].base_addr = AU1550_ETH0_BASE;
++		iflist[1].base_addr = AU1550_ETH1_BASE;
++		iflist[0].macen_addr = AU1550_MAC0_ENABLE;
++		iflist[1].macen_addr = AU1550_MAC1_ENABLE;
++		iflist[0].irq = AU1550_MAC0_DMA_INT;
++		iflist[1].irq = AU1550_MAC1_DMA_INT;
++		break;
++#endif
++	default:
++		num_ifs = 0;
++	}
++	for(i = 0; i < num_ifs; i++) {
++		dev = au1000_probe(iflist[i].base_addr, iflist[i].irq, i);
++		iflist[i].dev = dev;
++		if (dev)
++			found_one++;
++	}
++	if (!found_one)
++		return -ENODEV;
++	return 0;
++}
++
++static int au1000_setup_aneg(struct net_device *dev, u32 advertise)
++{
++	struct au1000_private *aup = (struct au1000_private *)dev->priv;
++	u16 ctl, adv;
++
++	/* Setup standard advertise */
++	adv = mdio_read(dev, aup->phy_addr, MII_ADVERTISE);
++	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
++	if (advertise & ADVERTISED_10baseT_Half)
++		adv |= ADVERTISE_10HALF;
++	if (advertise & ADVERTISED_10baseT_Full)
++		adv |= ADVERTISE_10FULL;
++	if (advertise & ADVERTISED_100baseT_Half)
++		adv |= ADVERTISE_100HALF;
++	if (advertise & ADVERTISED_100baseT_Full)
++		adv |= ADVERTISE_100FULL;
++	mdio_write(dev, aup->phy_addr, MII_ADVERTISE, adv);
++
++	/* Start/Restart aneg */
++	ctl = mdio_read(dev, aup->phy_addr, MII_BMCR);
++	ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
++	mdio_write(dev, aup->phy_addr, MII_BMCR, ctl);
++
++	return 0;
++}
+ 
+-	prid = read_c0_prid();
+-	for (i=0; i<NUM_INTERFACES; i++) {
+-		if ( (prid & 0xffff0000) == 0x00030000 ) {
+-			base_addr = au1000_iflist[i].port;
+-			irq = au1000_iflist[i].irq;
+-		} else if ( (prid & 0xffff0000) == 0x01030000 ) {
+-			base_addr = au1500_iflist[i].port;
+-			irq = au1500_iflist[i].irq;
+-		} else if ( (prid & 0xffff0000) == 0x02030000 ) {
+-			base_addr = au1100_iflist[i].port;
+-			irq = au1100_iflist[i].irq;
++static int au1000_setup_forced(struct net_device *dev, int speed, int fd)
++{
++	struct au1000_private *aup = (struct au1000_private *)dev->priv;
++	u16 ctl;
++
++	ctl = mdio_read(dev, aup->phy_addr, MII_BMCR);
++	ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE);
++
++	/* First reset the PHY */
++	mdio_write(dev, aup->phy_addr, MII_BMCR, ctl | BMCR_RESET);
++
++	/* Select speed & duplex */
++	switch (speed) {
++		case SPEED_10:
++			break;
++		case SPEED_100:
++			ctl |= BMCR_SPEED100;
++			break;
++		case SPEED_1000:
++		default:
++			return -EINVAL;
++	}
++	if (fd == DUPLEX_FULL)
++		ctl |= BMCR_FULLDPLX;
++	mdio_write(dev, aup->phy_addr, MII_BMCR, ctl);
++
++	return 0;
++}
++
++
++static void
++au1000_start_link(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++	struct au1000_private *aup = (struct au1000_private *)dev->priv;
++	u32 advertise;
++	int autoneg;
++	int forced_speed;
++	int forced_duplex;
++
++	/* Default advertise */
++	advertise = GENMII_DEFAULT_ADVERTISE;
++	autoneg = aup->want_autoneg;
++	forced_speed = SPEED_100;
++	forced_duplex = DUPLEX_FULL;
++
++	/* Setup link parameters */
++	if (cmd) {
++		if (cmd->autoneg == AUTONEG_ENABLE) {
++			advertise = cmd->advertising;
++			autoneg = 1;
+ 		} else {
+-			printk(KERN_ERR "au1000 eth: unknown Processor ID\n");
+-			return -ENODEV;
+-		}
+-		// check for valid entries, au1100 only has one entry
+-		if (base_addr && irq) {
+-			if (au1000_probe1(base_addr, irq, i) != 0)
+-				return -ENODEV;
++			autoneg = 0;
++
++			forced_speed = cmd->speed;
++			forced_duplex = cmd->duplex;
+ 		}
+ 	}
++
++	/* Configure PHY & start aneg */
++	aup->want_autoneg = autoneg;
++	if (autoneg)
++		au1000_setup_aneg(dev, advertise);
++	else
++		au1000_setup_forced(dev, forced_speed, forced_duplex);
++	mod_timer(&aup->timer, jiffies + HZ);
++}
++
++static int au1000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++	struct au1000_private *aup = (struct au1000_private *)dev->priv;
++	u16 link, speed;
++
++	cmd->supported = GENMII_DEFAULT_FEATURES;
++	cmd->advertising = GENMII_DEFAULT_ADVERTISE;
++	cmd->port = PORT_MII;
++	cmd->transceiver = XCVR_EXTERNAL;
++	cmd->phy_address = aup->phy_addr;
++	spin_lock_irq(&aup->lock);
++	cmd->autoneg = aup->want_autoneg;
++	aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed);
++	if ((speed == IF_PORT_100BASETX) || (speed == IF_PORT_100BASEFX))
++		cmd->speed = SPEED_100;
++	else if (speed == IF_PORT_10BASET)
++		cmd->speed = SPEED_10;
++	if (link && (dev->if_port == IF_PORT_100BASEFX))
++		cmd->duplex = DUPLEX_FULL;
++	else
++		cmd->duplex = DUPLEX_HALF;
++	spin_unlock_irq(&aup->lock);
+ 	return 0;
+ }
+ 
+-static int __init
+-au1000_probe1(long ioaddr, int irq, int port_num)
++static int au1000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++	 struct au1000_private *aup = (struct au1000_private *)dev->priv;
++	  unsigned long features = GENMII_DEFAULT_FEATURES;
++
++	 if (!capable(CAP_NET_ADMIN))
++		 return -EPERM;
++
++	 if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE)
++		 return -EINVAL;
++	 if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0)
++		 return -EINVAL;
++	 if (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL)
++		 return -EINVAL;
++	 if (cmd->autoneg == AUTONEG_DISABLE)
++		 switch (cmd->speed) {
++		 case SPEED_10:
++			 if (cmd->duplex == DUPLEX_HALF &&
++				 (features & SUPPORTED_10baseT_Half) == 0)
++				 return -EINVAL;
++			 if (cmd->duplex == DUPLEX_FULL &&
++				 (features & SUPPORTED_10baseT_Full) == 0)
++				 return -EINVAL;
++			 break;
++		 case SPEED_100:
++			 if (cmd->duplex == DUPLEX_HALF &&
++				 (features & SUPPORTED_100baseT_Half) == 0)
++				 return -EINVAL;
++			 if (cmd->duplex == DUPLEX_FULL &&
++				 (features & SUPPORTED_100baseT_Full) == 0)
++				 return -EINVAL;
++			 break;
++		 default:
++			 return -EINVAL;
++		 }
++	 else if ((features & SUPPORTED_Autoneg) == 0)
++		 return -EINVAL;
++
++	 spin_lock_irq(&aup->lock);
++	 au1000_start_link(dev, cmd);
++	 spin_unlock_irq(&aup->lock);
++	 return 0;
++}
++
++static int au1000_nway_reset(struct net_device *dev)
++{
++	struct au1000_private *aup = (struct au1000_private *)dev->priv;
++
++	if (!aup->want_autoneg)
++		return -EINVAL;
++	spin_lock_irq(&aup->lock);
++	au1000_start_link(dev, NULL);
++	spin_unlock_irq(&aup->lock);
++	return 0;
++}
++
++static void
++au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
++{
++	struct au1000_private *aup = (struct au1000_private *)dev->priv;
++
++	strcpy(info->driver, DRV_NAME);
++	strcpy(info->version, DRV_VERSION);
++	info->fw_version[0] = '\0';
++	sprintf(info->bus_info, "%s %d", DRV_NAME, aup->mac_id);
++	info->regdump_len = 0;
++}
++
++static u32 au1000_get_link(struct net_device *dev)
++{
++	return netif_carrier_ok(dev);
++}
++
++static struct ethtool_ops au1000_ethtool_ops = {
++	.get_settings = au1000_get_settings,
++	.set_settings = au1000_set_settings,
++	.get_drvinfo = au1000_get_drvinfo,
++	.nway_reset = au1000_nway_reset,
++	.get_link = au1000_get_link
++};
++
++static struct net_device *
++au1000_probe(u32 ioaddr, int irq, int port_num)
+ {
+-	struct net_device *dev;
+ 	static unsigned version_printed = 0;
+ 	struct au1000_private *aup = NULL;
+-	int i, retval = 0;
++	struct net_device *dev = NULL;
+ 	db_dest_t *pDB, *pDBfree;
+ 	char *pmac, *argptr;
+ 	char ethaddr[6];
++	int i, err;
+ 
+-	if (!request_region(PHYSADDR(ioaddr), MAC_IOSIZE, "Au1000 ENET"))
+-		 return -ENODEV;
++	if (!request_mem_region(CPHYSADDR(ioaddr), MAC_IOSIZE, "Au1x00 ENET"))
++		return NULL;
+ 
+-	if (version_printed++ == 0)
+-		printk(version);
+-
+-	retval = -ENOMEM;
++	if (version_printed++ == 0) 
++		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
+ 
+ 	dev = alloc_etherdev(sizeof(struct au1000_private));
+ 	if (!dev) {
+ 		printk (KERN_ERR "au1000 eth: alloc_etherdev failed\n");  
+-		goto out;
++		return NULL;
+ 	}
+ 
+-	SET_MODULE_OWNER(dev);
++	if ((err = register_netdev(dev))) {
++		printk(KERN_ERR "Au1x_eth Cannot register net device err %d\n",
++				err);
++		free_netdev(dev);
++		return NULL;
++	}
+ 
+-	printk("%s: Au1xxx ethernet found at 0x%lx, irq %d\n", 
+-	       dev->name, ioaddr, irq);
++	printk("%s: Au1x Ethernet found at 0x%x, irq %d\n", 
++			dev->name, ioaddr, irq);
+ 
+ 	aup = dev->priv;
+ 
+ 	/* Allocate the data buffers */
+-	aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * 
+-			(NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr);
+-	if (!aup->vaddr)
+-		goto out1;
++	/* Snooping works fine with eth on all au1xxx */
++	aup->vaddr = (u32)dma_alloc_noncoherent(NULL,
++			MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS),
++			&aup->dma_addr,
++			0);
++	if (!aup->vaddr) {
++		free_netdev(dev);
++		release_mem_region(CPHYSADDR(ioaddr), MAC_IOSIZE);
++		return NULL;
++	}
+ 
+ 	/* aup->mac is the base address of the MAC's registers */
+ 	aup->mac = (volatile mac_reg_t *)((unsigned long)ioaddr);
+ 	/* Setup some variables for quick register address access */
+-	switch (ioaddr) {
+-	case AU1000_ETH0_BASE:
+-	case AU1500_ETH0_BASE:
++	if (ioaddr == iflist[0].base_addr)
++	{
+ 		/* check env variables first */
+ 		if (!get_ethernet_addr(ethaddr)) { 
+-			memcpy(au1000_mac_addr, ethaddr, sizeof(dev->dev_addr));
++			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
+ 		} else {
+ 			/* Check command line */
+ 			argptr = prom_getcmdline();
+@@ -708,38 +1507,32 @@ au1000_probe1(long ioaddr, int irq, int 
+ 			} else {
+ 				str2eaddr(ethaddr, pmac + strlen("ethaddr="));
+ 				memcpy(au1000_mac_addr, ethaddr, 
+-						sizeof(dev->dev_addr));
++						sizeof(au1000_mac_addr));
+ 			}
+ 		}
+-		if (ioaddr == AU1000_ETH0_BASE)
+-			aup->enable = (volatile u32 *) 
+-				((unsigned long)AU1000_MAC0_ENABLE);
+-		else
+ 			aup->enable = (volatile u32 *) 
+-				((unsigned long)AU1500_MAC0_ENABLE);
+-		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
++				((unsigned long)iflist[0].macen_addr);
++		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
+ 		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
+-			break;
+-	case AU1000_ETH1_BASE:
+-	case AU1500_ETH1_BASE:
+-		if (ioaddr == AU1000_ETH1_BASE)
+-			aup->enable = (volatile u32 *) 
+-				((unsigned long)AU1000_MAC1_ENABLE);
++		aup->mac_id = 0;
++		au_macs[0] = aup;
++	}
+ 		else
++	if (ioaddr == iflist[1].base_addr)
++	{
+ 			aup->enable = (volatile u32 *) 
+-				((unsigned long)AU1500_MAC1_ENABLE);
+-		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
++				((unsigned long)iflist[1].macen_addr);
++		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
+ 		dev->dev_addr[4] += 0x10;
+ 		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
+-			break;
+-	default:
++		aup->mac_id = 1;
++		au_macs[1] = aup;
++	}
++	else
++	{
+ 		printk(KERN_ERR "%s: bad ioaddr\n", dev->name);
+-		break;
+-
+ 	}
+ 
+-	aup->phy_addr = PHY_ADDRESS;
+-
+ 	/* bring the device out of reset, otherwise probing the mii
+ 	 * will hang */
+ 	*aup->enable = MAC_EN_CLOCK_ENABLE;
+@@ -748,15 +1541,22 @@ au1000_probe1(long ioaddr, int irq, int 
+ 		MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
+ 	au_sync_delay(2);
+ 
+-	retval = mii_probe(dev);
+-	if (retval)
+-		 goto out2;
++	aup->mii = kmalloc(sizeof(struct mii_phy), GFP_KERNEL);
++	if (!aup->mii) {
++		printk(KERN_ERR "%s: out of memory\n", dev->name);
++		goto err_out;
++	}
++	aup->mii->mii_control_reg = 0;
++	aup->mii->mii_data_reg = 0;
++
++	if (mii_probe(dev) != 0) {
++		goto err_out;
++	}
+ 
+-	retval = -EINVAL;
+ 	pDBfree = NULL;
+ 	/* setup the data buffer descriptors and attach a buffer to each one */
+ 	pDB = aup->db;
+-	for (i=0; i<(NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
++	for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
+ 		pDB->pnext = pDBfree;
+ 		pDBfree = pDB;
+ 		pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
+@@ -765,15 +1565,19 @@ au1000_probe1(long ioaddr, int irq, int 
+ 	}
+ 	aup->pDBfree = pDBfree;
+ 
+-	for (i=0; i<NUM_RX_DMA; i++) {
++	for (i = 0; i < NUM_RX_DMA; i++) {
+ 		pDB = GetFreeDB(aup);
+-		if (!pDB) goto out2;
++		if (!pDB) {
++			goto err_out;
++		}
+ 		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+ 		aup->rx_db_inuse[i] = pDB;
+ 	}
+-	for (i=0; i<NUM_TX_DMA; i++) {
++	for (i = 0; i < NUM_TX_DMA; i++) {
+ 		pDB = GetFreeDB(aup);
+-		if (!pDB) goto out2;
++		if (!pDB) {
++			goto err_out;
++		}
+ 		aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
+ 		aup->tx_dma_ring[i]->len = 0;
+ 		aup->tx_db_inuse[i] = pDB;
+@@ -788,6 +1592,7 @@ au1000_probe1(long ioaddr, int irq, int 
+ 	dev->get_stats = au1000_get_stats;
+ 	dev->set_multicast_list = &set_rx_mode;
+ 	dev->do_ioctl = &au1000_ioctl;
++	SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
+ 	dev->set_config = &au1000_set_config;
+ 	dev->tx_timeout = au1000_tx_timeout;
+ 	dev->watchdog_timeo = ETH_TX_TIMEOUT;
+@@ -798,23 +1603,32 @@ au1000_probe1(long ioaddr, int irq, int 
+ 	 */
+ 	reset_mac(dev);
+ 
+-	retval = register_netdev(dev);
+-	if (retval)
+-		goto out2;
+-	return 0;
++	return dev;
+ 
+-out2:
+-	dma_free(aup->vaddr, MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS));
+-out1:
++err_out:
++	/* here we should have a valid dev plus aup-> register addresses
++	 * so we can reset the mac properly.*/
++	reset_mac(dev);
++	if (aup->mii)
++		kfree(aup->mii);
++	for (i = 0; i < NUM_RX_DMA; i++) {
++		if (aup->rx_db_inuse[i])
++			ReleaseDB(aup, aup->rx_db_inuse[i]);
++	}
++	for (i = 0; i < NUM_TX_DMA; i++) {
++		if (aup->tx_db_inuse[i])
++			ReleaseDB(aup, aup->tx_db_inuse[i]);
++	}
++	dma_free_noncoherent(NULL,
++			MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS),
++			(void *)aup->vaddr,
++			aup->dma_addr);
++	unregister_netdev(dev);
+ 	free_netdev(dev);
+-out:
+-	release_region(PHYSADDR(ioaddr), MAC_IOSIZE);
+-	printk(KERN_ERR "%s: au1000_probe1 failed.  Returns %d\n",
+-	       dev->name, retval);
+-	return retval;
++	release_mem_region(CPHYSADDR(ioaddr), MAC_IOSIZE);
++	return NULL;
+ }
+ 
+-
+ /* 
+  * Initialize the interface.
+  *
+@@ -832,7 +1646,8 @@ static int au1000_init(struct net_device
+ 	u32 control;
+ 	u16 link, speed;
+ 
+-	if (au1000_debug > 4) printk("%s: au1000_init\n", dev->name);
++	if (au1000_debug > 4) 
++		printk("%s: au1000_init\n", dev->name);
+ 
+ 	spin_lock_irqsave(&aup->lock, flags);
+ 
+@@ -852,7 +1667,7 @@ static int au1000_init(struct net_device
+ 	aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
+ 		dev->dev_addr[1]<<8 | dev->dev_addr[0];
+ 
+-	for (i=0; i<NUM_RX_DMA; i++) {
++	for (i = 0; i < NUM_RX_DMA; i++) {
+ 		aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
+ 	}
+ 	au_sync();
+@@ -865,7 +1680,13 @@ static int au1000_init(struct net_device
+ 	if (link && (dev->if_port == IF_PORT_100BASEFX)) {
+ 		control |= MAC_FULL_DUPLEX;
+ 	}
++
++	/* fix for startup without cable */
++	if (!link) 
++		dev->flags &= ~IFF_RUNNING;
++
+ 	aup->mac->control = control;
++	aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
+ 	au_sync();
+ 
+ 	spin_unlock_irqrestore(&aup->lock, flags);
+@@ -949,6 +1770,7 @@ static int au1000_open(struct net_device
+ 		return retval;
+ 	}
+ 
++	init_timer(&aup->timer); /* used in ioctl() */
+ 	aup->timer.expires = RUN_AT((3*HZ)); 
+ 	aup->timer.data = (unsigned long)dev;
+ 	aup->timer.function = &au1000_timer; /* timer handler */
+@@ -968,22 +1790,49 @@ static int au1000_close(struct net_devic
+ 	if (au1000_debug > 4)
+ 		printk("%s: close: dev=%p\n", dev->name, dev);
+ 
++	reset_mac(dev);
++
+ 	spin_lock_irqsave(&aup->lock, flags);
+ 	
+ 	/* stop the device */
+-	if (netif_device_present(dev))
+-		netif_stop_queue(dev);
++	netif_stop_queue(dev);
+ 
+ 	/* disable the interrupt */
+ 	free_irq(dev->irq, dev);
+ 	spin_unlock_irqrestore(&aup->lock, flags);
+ 
+-	reset_mac(dev);
+ 	return 0;
+ }
+ 
+ static void __exit au1000_cleanup_module(void)
+ {
++	int i, j;
++	struct net_device *dev;
++	struct au1000_private *aup;
++
++	for (i = 0; i < num_ifs; i++) {
++		dev = iflist[i].dev;
++		if (dev) {
++			aup = (struct au1000_private *) dev->priv;
++			unregister_netdev(dev);
++			if (aup->mii)
++				kfree(aup->mii);
++			for (j = 0; j < NUM_RX_DMA; j++) {
++				if (aup->rx_db_inuse[j])
++					ReleaseDB(aup, aup->rx_db_inuse[j]);
++			}
++			for (j = 0; j < NUM_TX_DMA; j++) {
++				if (aup->tx_db_inuse[j])
++					ReleaseDB(aup, aup->tx_db_inuse[j]);
++			}
++			dma_free_noncoherent(NULL,
++					MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS),
++					(void *)aup->vaddr,
++					aup->dma_addr);
++			free_netdev(dev);
++			release_mem_region(CPHYSADDR(iflist[i].base_addr), MAC_IOSIZE);
++		}
++	}
+ }
+ 
+ 
+@@ -1028,9 +1877,8 @@ static void au1000_tx_ack(struct net_dev
+ 	ptxd = aup->tx_dma_ring[aup->tx_tail];
+ 
+ 	while (ptxd->buff_stat & TX_T_DONE) {
+- 		update_tx_stats(dev, ptxd->status, aup->tx_len[aup->tx_tail]  & 0x3ff);
++		update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff);
+ 		ptxd->buff_stat &= ~TX_T_DONE;
+- 		aup->tx_len[aup->tx_tail] = 0;
+ 		ptxd->len = 0;
+ 		au_sync();
+ 
+@@ -1056,7 +1904,7 @@ static int au1000_tx(struct sk_buff *skb
+ 	db_dest_t *pDB;
+ 	int i;
+ 
+-	if (au1000_debug > 4)
++	if (au1000_debug > 5)
+ 		printk("%s: tx: aup %x len=%d, data=%p, head %d\n", 
+ 				dev->name, (unsigned)aup, skb->len, 
+ 				skb->data, aup->tx_head);
+@@ -1070,8 +1918,7 @@ static int au1000_tx(struct sk_buff *skb
+ 		return 1;
+ 	}
+ 	else if (buff_stat & TX_T_DONE) {
+- 		update_tx_stats(dev, ptxd->status, aup->tx_len[aup->tx_head] & 0x3ff);
+- 		aup->tx_len[aup->tx_head] = 0;
++		update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff);
+ 		ptxd->len = 0;
+ 	}
+ 
+@@ -1082,17 +1929,15 @@ static int au1000_tx(struct sk_buff *skb
+ 
+ 	pDB = aup->tx_db_inuse[aup->tx_head];
+ 	memcpy((void *)pDB->vaddr, skb->data, skb->len);
+-	if (skb->len < MAC_MIN_PKT_SIZE) {
+-		for (i=skb->len; i<MAC_MIN_PKT_SIZE; i++) { 
++	if (skb->len < ETH_ZLEN) {
++		for (i=skb->len; i<ETH_ZLEN; i++) { 
+ 			((char *)pDB->vaddr)[i] = 0;
+ 		}
+- 		aup->tx_len[aup->tx_head] = MAC_MIN_PKT_SIZE;
+-		ptxd->len = MAC_MIN_PKT_SIZE;
++		ptxd->len = ETH_ZLEN;
+ 	}
+-	else {
+- 		aup->tx_len[aup->tx_head] = skb->len;
++	else
+ 		ptxd->len = skb->len;
+-	}
++
+ 	ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
+ 	au_sync();
+ 	dev_kfree_skb(skb);
+@@ -1137,8 +1982,9 @@ static int au1000_rx(struct net_device *
+ 	volatile rx_dma_t *prxd;
+ 	u32 buff_stat, status;
+ 	db_dest_t *pDB;
++	u32	frmlen;
+ 
+-	if (au1000_debug > 4)
++	if (au1000_debug > 5)
+ 		printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);
+ 
+ 	prxd = aup->rx_dma_ring[aup->rx_head];
+@@ -1150,7 +1996,9 @@ static int au1000_rx(struct net_device *
+ 		if (!(status & RX_ERROR))  {
+ 
+ 			/* good frame */
+-			skb = dev_alloc_skb((status & RX_FRAME_LEN_MASK) + 2);
++			frmlen = (status & RX_FRAME_LEN_MASK);
++			frmlen -= 4; /* Remove FCS */
++			skb = dev_alloc_skb(frmlen + 2);
+ 			if (skb == NULL) {
+ 				printk(KERN_ERR
+ 				       "%s: Memory squeeze, dropping packet.\n",
+@@ -1160,9 +2008,9 @@ static int au1000_rx(struct net_device *
+ 			}
+ 			skb->dev = dev;
+ 			skb_reserve(skb, 2);	/* 16 byte IP header align */
+-			eth_copy_and_sum(skb, (unsigned char *)pDB->vaddr, 
+-					status & RX_FRAME_LEN_MASK, 0);
+-			skb_put(skb, status & RX_FRAME_LEN_MASK);
++			eth_copy_and_sum(skb,
++				(unsigned char *)pDB->vaddr, frmlen, 0);
++			skb_put(skb, frmlen);
+ 			skb->protocol = eth_type_trans(skb, dev);
+ 			netif_rx(skb);	/* pass the packet to upper layers */
+ 		}
+@@ -1206,17 +2054,20 @@ static int au1000_rx(struct net_device *
+ /*
+  * Au1000 interrupt service routine.
+  */
+-irqreturn_t au1000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t au1000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	struct net_device *dev = (struct net_device *) dev_id;
+ 
+ 	if (dev == NULL) {
+ 		printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name);
+-		return IRQ_NONE;
++		return IRQ_RETVAL(1);
+ 	}
+-	au1000_tx_ack(dev);
++
++	/* Handle RX interrupts first to minimize chance of overrun */
++
+ 	au1000_rx(dev);
+-	return IRQ_HANDLED;
++	au1000_tx_ack(dev);
++	return IRQ_RETVAL(1);
+ }
+ 
+ 
+@@ -1233,6 +2084,23 @@ static void au1000_tx_timeout(struct net
+ 	netif_wake_queue(dev);
+ }
+ 
++
++static unsigned const ethernet_polynomial = 0x04c11db7U;
++static inline u32 ether_crc(int length, unsigned char *data)
++{
++    int crc = -1;
++
++    while(--length >= 0) {
++		unsigned char current_octet = *data++;
++		int bit;
++		for (bit = 0; bit < 8; bit++, current_octet >>= 1)
++			crc = (crc << 1) ^
++				((crc < 0) ^ (current_octet & 1) ? 
++				 ethernet_polynomial : 0);
++    }
++    return crc;
++}
++
+ static void set_rx_mode(struct net_device *dev)
+ {
+ 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
+@@ -1256,8 +2124,8 @@ static void set_rx_mode(struct net_devic
+ 		mc_filter[1] = mc_filter[0] = 0;
+ 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+ 			 i++, mclist = mclist->next) {
+-			set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr)>>26, 
+-					mc_filter);
++			set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26, 
++					(long *)mc_filter);
+ 		}
+ 		aup->mac->multi_hash_high = mc_filter[1];
+ 		aup->mac->multi_hash_low = mc_filter[0];
+@@ -1269,28 +2137,28 @@ static void set_rx_mode(struct net_devic
+ 
+ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ {
++	struct au1000_private *aup = (struct au1000_private *)dev->priv;
+ 	u16 *data = (u16 *)&rq->ifr_ifru;
+ 
+-	/* fixme */
+ 	switch(cmd) { 
+-	case SIOCGMIIPHY:	/* Get the address of the PHY in use. */
+-		data[0] = PHY_ADDRESS;
+-		return 0;
+-
+-	case SIOCGMIIREG:	/* Read the specified MII register. */
+-		//data[3] = mdio_read(ioaddr, data[0], data[1]); 
+-		return 0;
+-
+-	case SIOCSMIIREG:	/* Write the specified MII register */
+-		if (!capable(CAP_NET_ADMIN))
+-			return -EPERM;
+-
+-		//mdio_write(ioaddr, data[0], data[1], data[2]);
+-		return 0;
+-
+-	default:
+-		return -EOPNOTSUPP;
++		case SIOCDEVPRIVATE:	/* Get the address of the PHY in use. */
++		case SIOCGMIIPHY:
++		        if (!netif_running(dev)) return -EINVAL;
++			data[0] = aup->phy_addr;
++		case SIOCDEVPRIVATE+1:	/* Read the specified MII register. */
++		case SIOCGMIIREG:
++			data[3] =  mdio_read(dev, data[0], data[1]); 
++			return 0;
++		case SIOCDEVPRIVATE+2:	/* Write the specified MII register */
++		case SIOCSMIIREG: 
++			if (!capable(CAP_NET_ADMIN))
++				return -EPERM;
++			mdio_write(dev, data[0], data[1],data[2]);
++			return 0;
++		default:
++			return -EOPNOTSUPP;
+ 	}
++
+ }
+ 
+ 
+@@ -1352,7 +2220,6 @@ static int au1000_set_config(struct net_
+ 			/* set Speed to 100Mbps, Half Duplex */
+ 			/* disable auto negotiation and enable 100MBit Mode */
+ 			control = mdio_read(dev, aup->phy_addr, MII_CONTROL);
+-			printk("read control %x\n", control);
+ 			control &= ~(MII_CNTL_AUTO | MII_CNTL_FDX);
+ 			control |= MII_CNTL_F100;
+ 			mdio_write(dev, aup->phy_addr, MII_CONTROL, control);
+diff -urpNX dontdiff linux-2.6.10/drivers/net/au1000_eth.h linux-2.6.10-mips/drivers/net/au1000_eth.h
+--- linux-2.6.10/drivers/net/au1000_eth.h	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/au1000_eth.h	2004-09-21 13:10:37.000000000 +0200
+@@ -1,10 +1,13 @@
+ /*
+- * Alchemy Semi Au1000 ethernet driver include file
++ *
++ * Alchemy Au1x00 ethernet driver include file
+  *
+  * Author: Pete Popov <ppopov at mvista.com>
+  *
+  * Copyright 2001 MontaVista Software Inc.
+  *
++ * ########################################################################
++ *
+  *  This program is free software; you can distribute it and/or modify it
+  *  under the terms of the GNU General Public License (Version 2) as
+  *  published by the Free Software Foundation.
+@@ -17,14 +20,16 @@
+  *  You should have received a copy of the GNU General Public License along
+  *  with this program; if not, write to the Free Software Foundation, Inc.,
+  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
++ *
++ * ########################################################################
++ *
++ * 
+  */
+-#include <linux/config.h>
+ 
+ 
+-#define NUM_INTERFACES 2
+ #define MAC_IOSIZE 0x10000
+-#define NUM_RX_DMA 4       /* Au1000 has 4 rx hardware descriptors */
+-#define NUM_TX_DMA 4       /* Au1000 has 4 tx hardware descriptors */
++#define NUM_RX_DMA 4       /* Au1x00 has 4 rx hardware descriptors */
++#define NUM_TX_DMA 4       /* Au1x00 has 4 tx hardware descriptors */
+ 
+ #define NUM_RX_BUFFS 4
+ #define NUM_TX_BUFFS 4
+@@ -33,12 +38,6 @@
+ #define ETH_TX_TIMEOUT HZ/4
+ #define MAC_MIN_PKT_SIZE 64
+ 
+-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100)
+-#define PHY_ADDRESS              0
+-#define PHY_CONTROL_DEFAULT 0x3000
+-#define PHY_CONTROL_REG_ADDR     0
+-#endif
+-
+ #define MULTICAST_FILTER_LIMIT 64
+ 
+ /* FIXME 
+@@ -54,11 +53,13 @@
+ #define MII_ANLPAR  0x0005
+ #define MII_AEXP    0x0006
+ #define MII_ANEXT   0x0007
+-#define MII_LSI_CONFIG 0x0011
+-#define MII_LSI_STAT   0x0012
+-#define MII_AUX_CNTRL  0x0018
+-#define MII_INT        0x001A
++#define MII_LSI_PHY_CONFIG 0x0011
++/* Status register */
++#define MII_LSI_PHY_STAT   0x0012
++#define MII_AMD_PHY_STAT   MII_LSI_PHY_STAT
++#define MII_INTEL_PHY_STAT 0x0011
+ 
++#define MII_AUX_CNTRL  0x0018
+ /* mii registers specific to AMD 79C901 */
+ #define	MII_STATUS_SUMMARY = 0x0018
+ 
+@@ -121,23 +122,30 @@
+ #define	MII_STSSUM_AUTO  0x0002
+ #define MII_STSSUM_SPD   0x0001
+ 
+-/* lsi status register */
+-
+-#define MII_LSI_STAT_FDX	0x0040
+-#define MII_LSI_STAT_SPD	0x0080
++/* lsi phy status register */
++#define MII_LSI_PHY_STAT_FDX	0x0040
++#define MII_LSI_PHY_STAT_SPD	0x0080
++
++/* amd phy status register */
++#define MII_AMD_PHY_STAT_FDX	0x0800
++#define MII_AMD_PHY_STAT_SPD	0x0400
++
++/* intel phy status register */
++#define MII_INTEL_PHY_STAT_FDX	0x0200
++#define MII_INTEL_PHY_STAT_SPD	0x4000
+ 
+ /* Auxilliary Control/Status Register */
+ #define MII_AUX_FDX      0x0001
+ #define MII_AUX_100      0x0002
+ #define MII_AUX_F100     0x0004
+ #define MII_AUX_ANEG     0x0008
+-#define MII_FDX_LED	 0x8000
+ 
+ typedef struct mii_phy {
+ 	struct mii_phy * next;
+ 	struct mii_chip_info * chip_info;
+-	int phy_addr;
+ 	u16 status;
++	u32 *mii_control_reg;
++	u32 *mii_data_reg;
+ } mii_phy_t;
+ 
+ struct phy_ops {
+@@ -197,7 +205,6 @@ struct au1000_private {
+ 	db_dest_t db[NUM_RX_BUFFS+NUM_TX_BUFFS];
+ 	volatile rx_dma_t *rx_dma_ring[NUM_RX_DMA];
+ 	volatile tx_dma_t *tx_dma_ring[NUM_TX_DMA];
+-	int tx_len[NUM_TX_DMA];
+ 	db_dest_t *rx_db_inuse[NUM_RX_DMA];
+ 	db_dest_t *tx_db_inuse[NUM_TX_DMA];
+ 	u32 rx_head;
+@@ -205,6 +212,7 @@ struct au1000_private {
+ 	u32 tx_tail;
+ 	u32 tx_full;
+ 
++	int mac_id;
+ 	mii_phy_t *mii;
+ 	struct phy_ops *phy_ops;
+ 	
+@@ -218,9 +226,10 @@ struct au1000_private {
+ 	u8 *hash_table;
+ 	u32 hash_mode;
+ 	u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */
+-	u32 phy_addr;          /* PHY address */
++	int phy_addr;          /* phy address */
+ 	u32 options;           /* User-settable misc. driver options. */
+ 	u32 drv_flags;
++	int want_autoneg;
+ 	struct net_device_stats stats;
+ 	struct timer_list timer;
+ 	spinlock_t lock;       /* Serialise access to device */
+diff -urpNX dontdiff linux-2.6.10/drivers/net/bagetlance.c linux-2.6.10-mips/drivers/net/bagetlance.c
+--- linux-2.6.10/drivers/net/bagetlance.c	2004-12-24 22:33:49.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/bagetlance.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,1368 +0,0 @@
+-/*
+- * bagetlance.c: Ethernet driver for VME Lance cards on Baget/MIPS
+- *      This code stealed and adopted from linux/drivers/net/atarilance.c
+- *      See that for author info
+- *
+- * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
+- */
+-
+-/* 
+- * Driver code for Baget/Lance taken from atarilance.c, which also
+- * works well in case of Besta. Most significant changes made here
+- * related with 16BIT-only access to A24 space.
+- */
+-
+-static char *version = "bagetlance.c: v1.1 11/10/98\n";
+-
+-#include <linux/module.h>
+-#include <linux/stddef.h>
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/errno.h>
+-#include <linux/slab.h>
+-#include <linux/interrupt.h>
+-#include <linux/init.h>
+-#include <linux/netdevice.h>
+-#include <linux/etherdevice.h>
+-#include <linux/skbuff.h>
+-#include <linux/bitops.h>
+-
+-#include <asm/irq.h>
+-#include <asm/io.h>
+-#include <asm/baget/baget.h>
+-
+-#define BAGET_LANCE_IRQ  BAGET_IRQ_MASK(0xdf)
+-
+-/*
+- *  Define following if you don't need 16BIT-only access to Lance memory
+- *  (Normally BAGET needs it)
+- */
+-#undef NORMAL_MEM_ACCESS 
+-
+-/* Debug level:
+- *  0 = silent, print only serious errors
+- *  1 = normal, print error messages
+- *  2 = debug, print debug infos
+- *  3 = debug, print even more debug infos (packet data)
+- */
+-
+-#define	LANCE_DEBUG	1  
+-
+-#ifdef LANCE_DEBUG
+-static int lance_debug = LANCE_DEBUG;
+-#else
+-static int lance_debug = 1;
+-#endif
+-MODULE_PARM(lance_debug, "i");
+-MODULE_PARM_DESC(lance_debug, "Lance debug level (0-3)");
+-MODULE_LICENSE("GPL");
+-
+-/* Print debug messages on probing? */
+-#undef LANCE_DEBUG_PROBE
+-
+-#define	DPRINTK(n,a)							\
+-	do {										\
+-		if (lance_debug >= n)					\
+-			printk a;							\
+-	} while( 0 )
+-
+-#ifdef LANCE_DEBUG_PROBE
+-# define PROBE_PRINT(a)	printk a
+-#else
+-# define PROBE_PRINT(a)
+-#endif
+-
+-/* These define the number of Rx and Tx buffers as log2. (Only powers
+- * of two are valid)
+- * Much more rx buffers (32) are reserved than tx buffers (8), since receiving
+- * is more time critical then sending and packets may have to remain in the
+- * board's memory when main memory is low.
+- */
+-
+-/* Baget Lance has 64K on-board memory, so it looks we can't increase
+-   buffer quantity (40*1.5K is about 64K) */
+-
+-#define TX_LOG_RING_SIZE			3
+-#define RX_LOG_RING_SIZE			5
+-
+-/* These are the derived values */
+-
+-#define TX_RING_SIZE			(1 << TX_LOG_RING_SIZE)
+-#define TX_RING_LEN_BITS		(TX_LOG_RING_SIZE << 5)
+-#define	TX_RING_MOD_MASK		(TX_RING_SIZE - 1)
+-
+-#define RX_RING_SIZE			(1 << RX_LOG_RING_SIZE)
+-#define RX_RING_LEN_BITS		(RX_LOG_RING_SIZE << 5)
+-#define	RX_RING_MOD_MASK		(RX_RING_SIZE - 1)
+-
+-/* The LANCE Rx and Tx ring descriptors. */
+-struct lance_rx_head {
+-	volatile unsigned short	base;		/* Low word of base addr */
+-#ifdef NORMAL_MEM_ACCESS
+-       /* Following two fields are joined into one short to guarantee
+-		  16BIT access to Baget lance registers */
+-	volatile unsigned char	flag;
+-	unsigned char			base_hi;	/* High word of base addr (unused) */
+-#else
+-/* Following macros are used as replecements to 8BIT fields */
+-#define GET_FLAG(h)    (((h)->flag_base_hi >> 8) & 0xff)
+-#define SET_FLAG(h,f)  (h)->flag_base_hi = ((h)->flag_base_hi & 0xff) | \
+-		                                                (((unsigned)(f)) << 8)
+-	volatile unsigned short flag_base_hi; 
+-#endif
+-	volatile short			buf_length;	/* This length is 2s complement! */
+-	volatile short			msg_length;	/* This length is "normal". */
+-};
+-
+-
+-struct lance_tx_head {
+-	volatile unsigned short	base;		/* Low word of base addr */
+-#ifdef NORMAL_MEM_ACCESS 
+-/* See comments above about 8BIT-access Baget A24-space problems */
+-	volatile unsigned char	flag;
+-	unsigned char			base_hi;	/* High word of base addr (unused) */
+-#else
+-	volatile unsigned short  flag_base_hi;
+-#endif
+-	volatile short			length;		/* Length is 2s complement! */
+-	volatile short			misc;
+-};
+-
+-struct ringdesc {
+-	volatile unsigned short	adr_lo;		/* Low 16 bits of address */
+-#ifdef NORMAL_MEM_ACCESS 
+-/* See comments above about 8BIT-access Bage A24-space problems */
+-	unsigned char	len;		/* Length bits */
+-	unsigned char	adr_hi;		/* High 8 bits of address (unused) */
+-#else
+-	volatile unsigned short  len_adr_hi;
+-#endif
+-};
+-
+-/* The LANCE initialization block, described in databook. */
+-struct lance_init_block {
+-	unsigned short	mode;		/* Pre-set mode */
+-	unsigned char	hwaddr[6];	/* Physical ethernet address */
+-	unsigned		filter[2];	/* Multicast filter (unused). */
+-	/* Receive and transmit ring base, along with length bits. */
+-	struct ringdesc	rx_ring;
+-	struct ringdesc	tx_ring;
+-};
+-
+-/* The whole layout of the Lance shared memory */
+-struct lance_memory {
+-	struct lance_init_block	init;
+-	struct lance_tx_head	tx_head[TX_RING_SIZE];
+-	struct lance_rx_head	rx_head[RX_RING_SIZE];
+-	char					packet_area[0];	/* packet data follow after the
+-											 * init block and the ring
+-											 * descriptors and are located
+-											 * at runtime */
+-};
+-
+-/* RieblCard specifics:
+- * The original TOS driver for these cards reserves the area from offset
+- * 0xee70 to 0xeebb for storing configuration data. Of interest to us is the
+- * Ethernet address there, and the magic for verifying the data's validity.
+- * The reserved area isn't touch by packet buffers. Furthermore, offset 0xfffe
+- * is reserved for the interrupt vector number.
+- */
+-#define	RIEBL_RSVD_START	0xee70
+-#define	RIEBL_RSVD_END		0xeec0
+-#define RIEBL_MAGIC			0x09051990
+-#define RIEBL_MAGIC_ADDR	((unsigned long *)(((char *)MEM) + 0xee8a))
+-#define RIEBL_HWADDR_ADDR	((unsigned char *)(((char *)MEM) + 0xee8e))
+-#define RIEBL_IVEC_ADDR		((unsigned short *)(((char *)MEM) + 0xfffe))
+-
+-/* This is a default address for the old RieblCards without a battery
+- * that have no ethernet address at boot time. 00:00:36:04 is the
+- * prefix for Riebl cards, the 00:00 at the end is arbitrary.
+- */
+-
+-static unsigned char OldRieblDefHwaddr[6] = {
+-	0x00, 0x00, 0x36, 0x04, 0x00, 0x00
+-};
+-
+-/* I/O registers of the Lance chip */
+-
+-struct lance_ioreg {
+-/* base+0x0 */	volatile unsigned short	data;
+-/* base+0x2 */	volatile unsigned short	addr;
+-				unsigned char			_dummy1[3];
+-/* base+0x7 */	volatile unsigned char	ivec;
+-				unsigned char			_dummy2[5];
+-/* base+0xd */	volatile unsigned char	eeprom;
+-				unsigned char			_dummy3;
+-/* base+0xf */	volatile unsigned char	mem;
+-};
+-
+-/* Types of boards this driver supports */
+-
+-enum lance_type {
+-	OLD_RIEBL,		/* old Riebl card without battery */
+-	NEW_RIEBL,		/* new Riebl card with battery */
+-	PAM_CARD		/* PAM card with EEPROM */
+-};
+-
+-static char *lance_names[] = {
+-	"Riebl-Card (without battery)",
+-	"Riebl-Card (with battery)",
+-	"PAM intern card"
+-};
+-
+-/* The driver's private device structure */
+-
+-struct lance_private {
+-	enum lance_type		cardtype;
+-	struct lance_ioreg	*iobase;
+-	struct lance_memory	*mem;
+-	int					cur_rx, cur_tx;	/* The next free ring entry */
+-	int					dirty_tx;		/* Ring entries to be freed. */
+-						/* copy function */
+-	void				*(*memcpy_f)( void *, const void *, size_t );
+-	struct net_device_stats stats;
+-/* These two must be longs for set_bit() */
+-	long				tx_full;
+-	long				lock;
+-};
+-
+-/* I/O register access macros */
+-
+-#define	MEM		lp->mem
+-#define	DREG	IO->data
+-#define	AREG	IO->addr
+-#define	REGA(a)	( AREG = (a), DREG )
+-
+-/* Definitions for packet buffer access: */
+-#define PKT_BUF_SZ		1544
+-/* Get the address of a packet buffer corresponding to a given buffer head */
+-#define	PKTBUF_ADDR(head)	(((unsigned char *)(MEM)) + (head)->base)
+-
+-/* Possible memory/IO addresses for probing */
+-
+-struct lance_addr {
+-	unsigned long	memaddr;
+-	unsigned long	ioaddr;
+-	int				slow_flag;
+-} lance_addr_list[] = {
+-	{ BAGET_LANCE_MEM_BASE, BAGET_LANCE_IO_BASE, 1 }	/* Baget Lance */
+-};
+-
+-#define	N_LANCE_ADDR	(sizeof(lance_addr_list)/sizeof(*lance_addr_list))
+-
+-
+-#define LANCE_HI_BASE (0xff & (BAGET_LANCE_MEM_BASE >> 16))
+-
+-/* Definitions for the Lance */
+-
+-/* tx_head flags */
+-#define TMD1_ENP		0x01	/* end of packet */
+-#define TMD1_STP		0x02	/* start of packet */
+-#define TMD1_DEF		0x04	/* deferred */
+-#define TMD1_ONE		0x08	/* one retry needed */
+-#define TMD1_MORE		0x10	/* more than one retry needed */
+-#define TMD1_ERR		0x40	/* error summary */
+-#define TMD1_OWN 		0x80	/* ownership (set: chip owns) */
+-
+-#define TMD1_OWN_CHIP	TMD1_OWN
+-#define TMD1_OWN_HOST	0
+-
+-/* tx_head misc field */
+-#define TMD3_TDR		0x03FF	/* Time Domain Reflectometry counter */
+-#define TMD3_RTRY		0x0400	/* failed after 16 retries */
+-#define TMD3_LCAR		0x0800	/* carrier lost */
+-#define TMD3_LCOL		0x1000	/* late collision */
+-#define TMD3_UFLO		0x4000	/* underflow (late memory) */
+-#define TMD3_BUFF		0x8000	/* buffering error (no ENP) */
+-
+-/* rx_head flags */
+-#define RMD1_ENP		0x01	/* end of packet */
+-#define RMD1_STP		0x02	/* start of packet */
+-#define RMD1_BUFF		0x04	/* buffer error */
+-#define RMD1_CRC		0x08	/* CRC error */
+-#define RMD1_OFLO		0x10	/* overflow */
+-#define RMD1_FRAM		0x20	/* framing error */
+-#define RMD1_ERR		0x40	/* error summary */
+-#define RMD1_OWN 		0x80	/* ownership (set: ship owns) */
+-
+-#define RMD1_OWN_CHIP	RMD1_OWN
+-#define RMD1_OWN_HOST	0
+-
+-/* register names */
+-#define CSR0	0		/* mode/status */
+-#define CSR1	1		/* init block addr (low) */
+-#define CSR2	2		/* init block addr (high) */
+-#define CSR3	3		/* misc */
+-#define CSR8	8	  	/* address filter */
+-#define CSR15	15		/* promiscuous mode */
+-
+-/* CSR0 */
+-/* (R=readable, W=writeable, S=set on write, C=clear on write) */
+-#define CSR0_INIT	0x0001		/* initialize (RS) */
+-#define CSR0_STRT	0x0002		/* start (RS) */
+-#define CSR0_STOP	0x0004		/* stop (RS) */
+-#define CSR0_TDMD	0x0008		/* transmit demand (RS) */
+-#define CSR0_TXON	0x0010		/* transmitter on (R) */
+-#define CSR0_RXON	0x0020		/* receiver on (R) */
+-#define CSR0_INEA	0x0040		/* interrupt enable (RW) */
+-#define CSR0_INTR	0x0080		/* interrupt active (R) */
+-#define CSR0_IDON	0x0100		/* initialization done (RC) */
+-#define CSR0_TINT	0x0200		/* transmitter interrupt (RC) */
+-#define CSR0_RINT	0x0400		/* receiver interrupt (RC) */
+-#define CSR0_MERR	0x0800		/* memory error (RC) */
+-#define CSR0_MISS	0x1000		/* missed frame (RC) */
+-#define CSR0_CERR	0x2000		/* carrier error (no heartbeat :-) (RC) */
+-#define CSR0_BABL	0x4000		/* babble: tx-ed too many bits (RC) */
+-#define CSR0_ERR	0x8000		/* error (RC) */
+-
+-/* CSR3 */
+-#define CSR3_BCON	0x0001		/* byte control */
+-#define CSR3_ACON	0 // fixme: 0x0002		/* ALE control */
+-#define CSR3_BSWP	0x0004		/* byte swap (1=big endian) */
+-
+-
+-
+-/***************************** Prototypes *****************************/
+-
+-static int addr_accessible( volatile void *regp, int wordflag, int
+-                            writeflag );
+-static int lance_probe1( struct net_device *dev, struct lance_addr *init_rec );
+-static int lance_open( struct net_device *dev );
+-static void lance_init_ring( struct net_device *dev );
+-static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev );
+-static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp );
+-static int lance_rx( struct net_device *dev );
+-static int lance_close( struct net_device *dev );
+-static struct net_device_stats *lance_get_stats( struct net_device *dev );
+-static void set_multicast_list( struct net_device *dev );
+-static int lance_set_mac_address( struct net_device *dev, void *addr );
+-
+-/************************* End of Prototypes **************************/
+-
+-/* Network traffic statistic (bytes) */
+-
+-int lance_stat = 0;
+-
+-static void update_lance_stat (int len) {
+-		lance_stat += len;
+-}
+-
+-/* 
+-   This function is used to access Baget/Lance memory to avoid 
+-   8/32BIT access to VAC A24 space 
+-   ALL memcpy calls was chenged to this function to avoid dbe problems
+-   Don't confuse with function name -- it stays from original code
+-*/
+-
+-void *slow_memcpy( void *dst, const void *src, size_t len )
+-
+-{	
+-	unsigned long to     = (unsigned long)dst;
+-	unsigned long from   = (unsigned long)src;
+-	unsigned long to_end = to +len;
+-	
+-	/* Unaligned flags */
+-
+-	int odd_from   = from   & 1;
+-	int odd_to     = to     & 1;
+-	int odd_to_end = to_end & 1;
+-
+-	/* Align for 16BIT-access first */
+-
+-	register unsigned short *from_a   = (unsigned short*) (from   & ~1);
+-	register unsigned short *to_a     = (unsigned short*) (to     & ~1); 
+-	register unsigned short *to_end_a = (unsigned short*) (to_end & ~1);
+-
+-	/* Caching values -- not in loop invariant */
+-
+-	register unsigned short from_v; 
+-	register unsigned short to_v;
+-
+-	/* Invariant is: from_a and to_a are pointers before or exactly to
+-	   currently copying byte */
+-
+-	if (odd_to) { 
+-			/* First byte unaligned case */
+-			from_v = *from_a;
+-			to_v   = *to_a;
+-
+-			to_v &= ~0xff;
+-			to_v |=  0xff & (from_v >> (odd_from ? 0 : 8));
+-			*to_a++ = to_v;
+-
+-			if (odd_from) from_a++;
+-	}
+-    if (odd_from == odd_to) {
+-			/* Same parity */
+-			while (to_a + 7 < to_end_a) {
+-					unsigned long dummy1, dummy2;
+-					unsigned long reg1, reg2, reg3, reg4;
+-
+-					__asm__ __volatile__(
+-					".set\tnoreorder\n\t"
+-					".set\tnoat\n\t"
+-					"lh\t%2,0(%1)\n\t"
+-					"nop\n\t"
+-					 "lh\t%3,2(%1)\n\t"
+-					"sh\t%2,0(%0)\n\t"
+-					   "lh\t%4,4(%1)\n\t"
+-					 "sh\t%3,2(%0)\n\t"
+-					    "lh\t%5,6(%1)\n\t"
+-					   "sh\t%4,4(%0)\n\t"
+-					"lh\t%2,8(%1)\n\t"
+-					    "sh\t%5,6(%0)\n\t"
+-					 "lh\t%3,10(%1)\n\t"
+-					"sh\t%2,8(%0)\n\t"
+-					  "lh\t%4,12(%1)\n\t"
+-					 "sh\t%3,10(%0)\n\t"
+-					    "lh\t%5,14(%1)\n\t"
+-					  "sh\t%4,12(%0)\n\t"
+-					 "nop\n\t"
+-					    "sh\t%5,14(%0)\n\t"
+-					".set\tat\n\t"
+-					".set\treorder"
+-					:"=r" (dummy1), "=r" (dummy2),
+-					"=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
+-					:"0" (to_a), "1" (from_a)
+-					:"memory");
+-
+-					to_a   += 8;
+-					from_a += 8;
+-
+-			}
+-			while (to_a < to_end_a) {
+-					*to_a++ = *from_a++;
+-			}
+-	} else {
+-			/* Different parity */
+-			from_v = *from_a;
+-			while (to_a < to_end_a) {
+-					unsigned short from_v_next;
+-					from_v_next = *++from_a;
+-					*to_a++ = ((from_v & 0xff)<<8) | ((from_v_next>>8) & 0xff);
+-					from_v = from_v_next; 
+-			}
+-
+-	}
+-	if (odd_to_end) {
+-			/* Last byte unaligned case */
+-			to_v = *to_a;
+-			from_v = *from_a;
+-
+-			to_v &= ~0xff00;
+-			if (odd_from == odd_to) {
+-					to_v |= from_v & 0xff00;
+-			} else {
+-					to_v |= (from_v<<8) & 0xff00;
+-			}
+-
+-			*to_a = to_v;
+-	}
+-
+-	update_lance_stat( len );
+-
+-	return( dst );
+-}
+-
+-
+-struct net_device * __init bagetlance_probe(int unit)
+-{
+-	struct net_device *dev;
+-	int i;
+-	static int found;
+-	int err = -ENODEV;
+-
+-	if (found)
+-		/* Assume there's only one board possible... That seems true, since
+-		 * the Riebl/PAM board's address cannot be changed. */
+-		return ERR_PTR(-ENODEV);
+-
+-	dev = alloc_etherdev(sizeof(struct lance_private));
+-	if (!dev)
+-		return ERR_PTR(-ENOMEM);
+-
+-	SET_MODULE_OWNER(dev);
+-
+-	for( i = 0; i < N_LANCE_ADDR; ++i ) {
+-		if (lance_probe1( dev, &lance_addr_list[i] )) {
+-			found = 1;
+-			break;
+-		}
+-	}
+-	if (!found)
+-		goto out;
+-	err = register_netdev(dev);
+-	if (err)
+-		goto out1;
+-	return dev;
+-out1:
+-	free_irq(dev->irq, dev);
+-out:
+-	free_netdev(dev);
+-	return ERR_PTR(err);
+-}
+-
+-/* Derived from hwreg_present() in vme/config.c: */
+-
+-static int __init addr_accessible( volatile void *regp, 
+-				   int wordflag, 
+-				   int writeflag )
+-{	
+-		/* We have a fine function to do it */
+-		extern int try_read(unsigned long, int);
+-		return try_read((unsigned long)regp, sizeof(short)) != -1;   
+-}
+-
+-
+-
+-/* Original atari driver uses it */
+-#define IRQ_TYPE_PRIO SA_INTERRUPT
+-#define IRQ_SOURCE_TO_VECTOR(x) (x)
+-
+-static int __init lance_probe1( struct net_device *dev,
+-				struct lance_addr *init_rec )
+-
+-{	volatile unsigned short *memaddr =
+-		(volatile unsigned short *)init_rec->memaddr;
+-	volatile unsigned short *ioaddr =
+-		(volatile unsigned short *)init_rec->ioaddr;
+-	struct lance_private	*lp;
+-	struct lance_ioreg		*IO;
+-	int 					i;
+-	static int 				did_version;
+-	unsigned short			save1, save2;
+-
+-	PROBE_PRINT(( "Probing for Lance card at mem %#lx io %#lx\n",
+-				  (long)memaddr, (long)ioaddr ));
+-
+-	/* Test whether memory readable and writable */
+-	PROBE_PRINT(( "lance_probe1: testing memory to be accessible\n" ));
+-	if (!addr_accessible( memaddr, 1, 1 )) goto probe_fail;
+-
+-	if ((unsigned long)memaddr >= KSEG2) {
+-			/* FIXME: do we need to undo that on cleanup paths? */
+-			extern int kseg2_alloc_io (unsigned long addr, unsigned long size);
+-			if (kseg2_alloc_io((unsigned long)memaddr, BAGET_LANCE_MEM_SIZE)) {
+-					printk("bagetlance: unable map lance memory\n");
+-					goto probe_fail;
+-			}
+-	}
+-
+-	/* Written values should come back... */
+-	PROBE_PRINT(( "lance_probe1: testing memory to be writable (1)\n" ));
+-	save1 = *memaddr;
+-	*memaddr = 0x0001;
+-	if (*memaddr != 0x0001) goto probe_fail;
+-	PROBE_PRINT(( "lance_probe1: testing memory to be writable (2)\n" ));
+-	*memaddr = 0x0000;
+-	if (*memaddr != 0x0000) goto probe_fail;
+-	*memaddr = save1;
+-
+-	/* First port should be readable and writable */
+-	PROBE_PRINT(( "lance_probe1: testing ioport to be accessible\n" ));
+-	if (!addr_accessible( ioaddr, 1, 1 )) goto probe_fail;
+-
+-	/* and written values should be readable */
+-	PROBE_PRINT(( "lance_probe1: testing ioport to be writeable\n" ));
+-	save2 = ioaddr[1];
+-	ioaddr[1] = 0x0001;
+-	if (ioaddr[1] != 0x0001) goto probe_fail;
+-
+-	/* The CSR0_INIT bit should not be readable */
+-	PROBE_PRINT(( "lance_probe1: testing CSR0 register function (1)\n" ));
+-	save1 = ioaddr[0];
+-	ioaddr[1] = CSR0;
+-	ioaddr[0] = CSR0_INIT | CSR0_STOP;
+-	if (ioaddr[0] != CSR0_STOP) {
+-		ioaddr[0] = save1;
+-		ioaddr[1] = save2;
+-		goto probe_fail;
+-	}
+-	PROBE_PRINT(( "lance_probe1: testing CSR0 register function (2)\n" ));
+-	ioaddr[0] = CSR0_STOP;
+-	if (ioaddr[0] != CSR0_STOP) {
+-		ioaddr[0] = save1;
+-		ioaddr[1] = save2;
+-		goto probe_fail;
+-	}
+-
+-	/* Now ok... */
+-	PROBE_PRINT(( "lance_probe1: Lance card detected\n" ));
+-	goto probe_ok;
+-
+-  probe_fail:
+-	return( 0 );
+-
+-  probe_ok:
+-	lp = netdev_priv(dev);
+-	MEM = (struct lance_memory *)memaddr;
+-	IO = lp->iobase = (struct lance_ioreg *)ioaddr;
+-	dev->base_addr = (unsigned long)ioaddr; /* informational only */
+-	lp->memcpy_f = init_rec->slow_flag ? slow_memcpy : memcpy;
+-
+-	REGA( CSR0 ) = CSR0_STOP;
+-
+-	/* Now test for type: If the eeprom I/O port is readable, it is a
+-	 * PAM card */
+-	if (addr_accessible( &(IO->eeprom), 0, 0 )) {
+-		/* Switch back to Ram */
+-		i = IO->mem;
+-		lp->cardtype = PAM_CARD;
+-	}
+-#ifdef NORMAL_MEM_ACCESS
+-	else if (*RIEBL_MAGIC_ADDR == RIEBL_MAGIC) {
+-#else
+-	else if (({
+-			unsigned short *a = (unsigned short*)RIEBL_MAGIC_ADDR;
+-		    (((int)a[0]) << 16) + ((int)a[1]) == RIEBL_MAGIC;
+-	})) {
+-#endif
+-		lp->cardtype = NEW_RIEBL;
+-	}
+-	else
+-		lp->cardtype = OLD_RIEBL;
+-
+-	if (lp->cardtype == PAM_CARD ||
+-		memaddr == (unsigned short *)0xffe00000) {
+-		/* PAMs card and Riebl on ST use level 5 autovector */
+-		if (request_irq(BAGET_LANCE_IRQ, lance_interrupt, IRQ_TYPE_PRIO,
+-		            "PAM/Riebl-ST Ethernet", dev))
+-			goto probe_fail;
+-		dev->irq = (unsigned short)BAGET_LANCE_IRQ;
+-	}
+-	else {
+-		/* For VME-RieblCards, request a free VME int;
+-		 * (This must be unsigned long, since dev->irq is short and the
+-		 * IRQ_MACHSPEC bit would be cut off...)
+-		 */
+-		unsigned long irq = BAGET_LANCE_IRQ; 
+-		if (!irq) {
+-			printk( "Lance: request for VME interrupt failed\n" );
+-			goto probe_fail;
+-		}
+-		if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
+-		            "Riebl-VME Ethernet", dev))
+-			goto probe_fail;
+-		dev->irq = irq;
+-	}
+-
+-	printk("%s: %s at io %#lx, mem %#lx, irq %d%s, hwaddr ",
+-		   dev->name, lance_names[lp->cardtype],
+-		   (unsigned long)ioaddr,
+-		   (unsigned long)memaddr,
+-		   dev->irq,
+-		   init_rec->slow_flag ? " (slow memcpy)" : "" );
+-
+-	/* Get the ethernet address */
+-	switch( lp->cardtype ) {
+-	  case OLD_RIEBL:
+-		/* No ethernet address! (Set some default address) */
+-		slow_memcpy( dev->dev_addr, OldRieblDefHwaddr, 6 );
+-		break;
+-	  case NEW_RIEBL:
+-		lp->memcpy_f( dev->dev_addr, RIEBL_HWADDR_ADDR, 6 );
+-		break;
+-	  case PAM_CARD:
+-		i = IO->eeprom;
+-		for( i = 0; i < 6; ++i )
+-			dev->dev_addr[i] =
+-				((((unsigned short *)MEM)[i*2] & 0x0f) << 4) |
+-				((((unsigned short *)MEM)[i*2+1] & 0x0f));
+-		i = IO->mem;
+-		break;
+-	}
+-	for( i = 0; i < 6; ++i )
+-		printk( "%02x%s", dev->dev_addr[i], (i < 5) ? ":" : "\n" );
+-	if (lp->cardtype == OLD_RIEBL) {
+-		printk( "%s: Warning: This is a default ethernet address!\n",
+-				dev->name );
+-		printk( "      Use \"ifconfig hw ether ...\" to set the address.\n" );
+-	}
+-
+-	MEM->init.mode = 0x0000;		/* Disable Rx and Tx. */
+-
+-	{
+-			unsigned char hwaddr[6];
+-			for( i = 0; i < 6; i++ ) 
+-					hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */
+-			slow_memcpy(MEM->init.hwaddr, hwaddr, sizeof(hwaddr));
+-	}
+-
+-	MEM->init.filter[0] = 0x00000000;
+-	MEM->init.filter[1] = 0x00000000;
+-	MEM->init.rx_ring.adr_lo = offsetof( struct lance_memory, rx_head );
+-
+-#ifdef NORMAL_MEM_ACCESS
+-	MEM->init.rx_ring.adr_hi = LANCE_HI_BASE; 
+-	MEM->init.rx_ring.len    = RX_RING_LEN_BITS;
+-#else
+-	MEM->init.rx_ring.len_adr_hi = 
+-			((unsigned)RX_RING_LEN_BITS << 8) | LANCE_HI_BASE;
+-#endif
+-
+-
+-	MEM->init.tx_ring.adr_lo = offsetof( struct lance_memory, tx_head );
+-
+-#ifdef NORMAL_MEM_ACCESS
+-	MEM->init.tx_ring.adr_hi = LANCE_HI_BASE; 
+-	MEM->init.tx_ring.len    = TX_RING_LEN_BITS;
+-#else
+-	MEM->init.tx_ring.len_adr_hi = 
+-			((unsigned)TX_RING_LEN_BITS<<8) | LANCE_HI_BASE;
+-#endif
+-
+-	if (lp->cardtype == PAM_CARD)
+-		IO->ivec = IRQ_SOURCE_TO_VECTOR(dev->irq);
+-	else
+-		*RIEBL_IVEC_ADDR = IRQ_SOURCE_TO_VECTOR(dev->irq);
+-
+-	if (did_version++ == 0)
+-		DPRINTK( 1, ( version ));
+-
+-	/* The LANCE-specific entries in the device structure. */
+-	dev->open = &lance_open;
+-	dev->hard_start_xmit = &lance_start_xmit;
+-	dev->stop = &lance_close;
+-	dev->get_stats = &lance_get_stats;
+-	dev->set_multicast_list = &set_multicast_list;
+-	dev->set_mac_address = &lance_set_mac_address;
+-	dev->start = 0;
+-
+-	memset( &lp->stats, 0, sizeof(lp->stats) );
+-
+-	return( 1 );
+-}
+-
+-
+-static int lance_open( struct net_device *dev )
+-
+-{	struct lance_private *lp = netdev_priv(dev);
+-	struct lance_ioreg	 *IO = lp->iobase;
+-	int i;
+-
+-	DPRINTK( 2, ( "%s: lance_open()\n", dev->name ));
+-
+-	lance_init_ring(dev);
+-	/* Re-initialize the LANCE, and start it when done. */
+-
+-	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
+-	REGA( CSR2 ) = 0;
+-	REGA( CSR1 ) = 0;
+-	REGA( CSR0 ) = CSR0_INIT;
+-	/* From now on, AREG is kept to point to CSR0 */
+-
+-	i = 1000000;
+-	while (--i > 0)
+-		if (DREG & CSR0_IDON)
+-			break;
+-	if (i < 0 || (DREG & CSR0_ERR)) {
+-		DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
+-					  dev->name, i, DREG ));
+-		DREG = CSR0_STOP;
+-		return( -EIO );
+-	}
+-	DREG = CSR0_IDON;
+-	DREG = CSR0_STRT;
+-	DREG = CSR0_INEA;
+-
+-	dev->tbusy = 0;
+-	dev->interrupt = 0;
+-	dev->start = 1;
+-
+-	DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG ));
+-	return( 0 );
+-}
+-
+-
+-/* Initialize the LANCE Rx and Tx rings. */
+-
+-static void lance_init_ring( struct net_device *dev )
+-
+-{	struct lance_private *lp = netdev_priv(dev);
+-	int i;
+-	unsigned offset;
+-
+-	lp->lock = 0;
+-	lp->tx_full = 0;
+-	lp->cur_rx = lp->cur_tx = 0;
+-	lp->dirty_tx = 0;
+-
+-	offset = offsetof( struct lance_memory, packet_area );
+-
+-/* If the packet buffer at offset 'o' would conflict with the reserved area
+- * of RieblCards, advance it */
+-#define	CHECK_OFFSET(o)														 \
+-	do {																	 \
+-		if (lp->cardtype == OLD_RIEBL || lp->cardtype == NEW_RIEBL) {		 \
+-			if (((o) < RIEBL_RSVD_START) ? (o)+PKT_BUF_SZ > RIEBL_RSVD_START \
+-										 : (o) < RIEBL_RSVD_END)			 \
+-				(o) = RIEBL_RSVD_END;										 \
+-		}																	 \
+-	} while(0)
+-
+-	for( i = 0; i < TX_RING_SIZE; i++ ) {
+-		CHECK_OFFSET(offset);
+-		MEM->tx_head[i].base = offset;
+-#ifdef NORMAL_MEM_ACCESS
+-		MEM->tx_head[i].flag = TMD1_OWN_HOST;
+- 		MEM->tx_head[i].base_hi = LANCE_HI_BASE;
+-#else
+-		MEM->tx_head[i].flag_base_hi = 
+-				(TMD1_OWN_HOST<<8) | LANCE_HI_BASE;
+-#endif
+-		MEM->tx_head[i].length = 0;
+-		MEM->tx_head[i].misc = 0;
+-		offset += PKT_BUF_SZ;
+-	}
+-
+-	for( i = 0; i < RX_RING_SIZE; i++ ) {
+-		CHECK_OFFSET(offset);
+-		MEM->rx_head[i].base = offset;
+-#ifdef NORMAL_MEM_ACCESS
+-		MEM->rx_head[i].flag = TMD1_OWN_CHIP;
+-		MEM->rx_head[i].base_hi = LANCE_HI_BASE; 
+-#else
+-		MEM->rx_head[i].flag_base_hi = 
+-				(TMD1_OWN_CHIP<<8) | LANCE_HI_BASE;
+-#endif
+-		MEM->rx_head[i].buf_length = -PKT_BUF_SZ;
+-		MEM->rx_head[i].msg_length = 0;
+-		offset += PKT_BUF_SZ;
+-	}
+-}
+-
+-
+-static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
+-
+-{	struct lance_private *lp = netdev_priv(dev);
+-	struct lance_ioreg	 *IO = lp->iobase;
+-	int entry, len;
+-	struct lance_tx_head *head;
+-	unsigned long flags;
+-
+-	/* The old LANCE chips doesn't automatically pad buffers to min. size. */
+-	len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
+-	/* PAM-Card has a bug: Can only send packets with even number of bytes! */
+-	if (lp->cardtype == PAM_CARD && (len & 1))
+-		++len;
+-
+-	if (len > skb->len) {
+-		skb = skb_padto(skb, len);
+-		if (skb == NULL)
+-			return 0;
+-	}	
+-
+-	/* Transmitter timeout, serious problems. */
+-	if (dev->tbusy) {
+-		int tickssofar = jiffies - dev->trans_start;
+-		if (tickssofar < 20)
+-			return( 1 );
+-		AREG = CSR0;
+-		DPRINTK( 1, ( "%s: transmit timed out, status %04x, resetting.\n",
+-					  dev->name, DREG ));
+-		DREG = CSR0_STOP;
+-		/*
+-		 * Always set BSWP after a STOP as STOP puts it back into
+-		 * little endian mode.
+-		 */
+-		REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
+-		lp->stats.tx_errors++;
+-#ifndef final_version
+-		{	int i;
+-			DPRINTK( 2, ( "Ring data: dirty_tx %d cur_tx %d%s cur_rx %d\n",
+-						  lp->dirty_tx, lp->cur_tx,
+-						  lp->tx_full ? " (full)" : "",
+-						  lp->cur_rx ));
+-			for( i = 0 ; i < RX_RING_SIZE; i++ )
+-				DPRINTK( 2, ( "rx #%d: base=%04x blen=%04x mlen=%04x\n",
+-							  i, MEM->rx_head[i].base,
+-							  -MEM->rx_head[i].buf_length,
+-							  MEM->rx_head[i].msg_length ));
+-			for( i = 0 ; i < TX_RING_SIZE; i++ )
+-				DPRINTK( 2, ( "tx #%d: base=%04x len=%04x misc=%04x\n",
+-							  i, MEM->tx_head[i].base,
+-							  -MEM->tx_head[i].length,
+-							  MEM->tx_head[i].misc ));
+-		}
+-#endif
+-		lance_init_ring(dev);
+-		REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
+-
+-		dev->tbusy = 0;
+-		dev->trans_start = jiffies;
+-
+-		return( 0 );
+-	}
+-
+-	DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
+-				  dev->name, DREG ));
+-
+-	/* Block a timer-based transmit from overlapping.  This could better be
+-	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
+-	if (test_and_set_bit( 0, (void*)&dev->tbusy ) != 0) {
+-		DPRINTK( 0, ( "%s: Transmitter access conflict.\n", dev->name ));
+-		return 1;
+-	}
+-
+-	if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) {
+-		DPRINTK( 0, ( "%s: tx queue lock!.\n", dev->name ));
+-		/* don't clear dev->tbusy flag. */
+-		return 1;
+-	}
+-
+-	/* Fill in a Tx ring entry */
+-	if (lance_debug >= 3) {
+-		u_char *p;
+-		int i;
+-		printk( "%s: TX pkt type 0x%04x from ", dev->name,
+-				((u_short *)skb->data)[6]);
+-		for( p = &((u_char *)skb->data)[6], i = 0; i < 6; i++ )
+-			printk("%02x%s", *p++, i != 5 ? ":" : "" );
+-		printk(" to ");
+-		for( p = (u_char *)skb->data, i = 0; i < 6; i++ )
+-			printk("%02x%s", *p++, i != 5 ? ":" : "" );
+-		printk(" data at 0x%08x len %d\n", (int)skb->data,
+-			   (int)skb->len );
+-	}
+-
+-	/* We're not prepared for the int until the last flags are set/reset. And
+-	 * the int may happen already after setting the OWN_CHIP... */
+-	save_flags(flags);
+-	cli();
+-
+-	/* Mask to ring buffer boundary. */
+-	entry = lp->cur_tx & TX_RING_MOD_MASK;
+-	head  = &(MEM->tx_head[entry]);
+-
+-	/* Caution: the write order is important here, set the "ownership" bits
+-	 * last.
+-	 */
+-
+-	head->length = -len;
+-	head->misc = 0;
+-	lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len );
+-#ifdef NORMAL_MEM_ACCESS
+-	head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP;
+-#else
+-    SET_FLAG(head,(TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP));
+-#endif
+-	lp->stats.tx_bytes += skb->len;
+-	dev_kfree_skb( skb );
+-	lp->cur_tx++;
+-	while( lp->cur_tx >= TX_RING_SIZE && lp->dirty_tx >= TX_RING_SIZE ) {
+-		lp->cur_tx -= TX_RING_SIZE;
+-		lp->dirty_tx -= TX_RING_SIZE;
+-	}
+-
+-	/* Trigger an immediate send poll. */
+-	DREG = CSR0_INEA | CSR0_TDMD;
+-	dev->trans_start = jiffies;
+-
+-	lp->lock = 0;
+-#ifdef NORMAL_MEM_ACCESS
+-	if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
+-#else
+-	if ((GET_FLAG(&MEM->tx_head[(entry+1) & TX_RING_MOD_MASK]) & TMD1_OWN) ==
+-#endif
+-		TMD1_OWN_HOST)
+-		dev->tbusy = 0;
+-	else
+-		lp->tx_full = 1;
+-	restore_flags(flags);
+-
+-	return 0;
+-}
+-
+-/* The LANCE interrupt handler. */
+-
+-static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
+-{
+-	struct net_device *dev = dev_id;
+-	struct lance_private *lp;
+-	struct lance_ioreg	 *IO;
+-	int csr0, boguscnt = 10;
+-	int handled = 0;
+-
+-	if (dev == NULL) {
+-		DPRINTK( 1, ( "lance_interrupt(): interrupt for unknown device.\n" ));
+-		return IRQ_NONE;
+-	}
+-
+-	lp = netdev_priv(dev);
+-	IO = lp->iobase;
+-	AREG = CSR0;
+-
+-	if (dev->interrupt) {
+-			DPRINTK( 1, ( "Re-entering CAUSE=%08x STATUS=%08x\n",  
+-						  read_32bit_cp0_register(CP0_CAUSE),  
+-						  read_32bit_cp0_register(CP0_STATUS) ));
+-			panic("lance: interrupt handler reentered !");
+-	}
+-
+-	dev->interrupt = 1;
+-
+-	while( ((csr0 = DREG) & (CSR0_ERR | CSR0_TINT | CSR0_RINT)) &&
+-		   --boguscnt >= 0) {
+-		handled = 1;
+-		/* Acknowledge all of the current interrupt sources ASAP. */
+-		DREG = csr0 & ~(CSR0_INIT | CSR0_STRT | CSR0_STOP |
+-									CSR0_TDMD | CSR0_INEA);
+-
+-		DPRINTK( 2, ( "%s: interrupt  csr0=%04x new csr=%04x.\n",
+-					  dev->name, csr0, DREG ));
+-
+-		if (csr0 & CSR0_RINT)			/* Rx interrupt */
+-			lance_rx( dev );
+-
+-		if (csr0 & CSR0_TINT) {			/* Tx-done interrupt */
+-			int dirty_tx = lp->dirty_tx;
+-
+-			while( dirty_tx < lp->cur_tx) {
+-				int entry = dirty_tx & TX_RING_MOD_MASK;
+-#ifdef NORMAL_MEM_ACCESS
+-				int status = MEM->tx_head[entry].flag;
+-#else
+-				int status = GET_FLAG(&MEM->tx_head[entry]);
+-#endif
+-				if (status & TMD1_OWN_CHIP)
+-					break;			/* It still hasn't been Txed */
+-
+-#ifdef NORMAL_MEM_ACCESS
+-				MEM->tx_head[entry].flag = 0;
+-#else
+-				SET_FLAG(&MEM->tx_head[entry],0);
+-#endif
+-
+-				if (status & TMD1_ERR) {
+-					/* There was an major error, log it. */
+-					int err_status = MEM->tx_head[entry].misc;
+-					lp->stats.tx_errors++;
+-					if (err_status & TMD3_RTRY) lp->stats.tx_aborted_errors++;
+-					if (err_status & TMD3_LCAR) lp->stats.tx_carrier_errors++;
+-					if (err_status & TMD3_LCOL) lp->stats.tx_window_errors++;
+-					if (err_status & TMD3_UFLO) {
+-						/* Ackk!  On FIFO errors the Tx unit is turned off! */
+-						lp->stats.tx_fifo_errors++;
+-						/* Remove this verbosity later! */
+-						DPRINTK( 1, ( "%s: Tx FIFO error! Status %04x\n",
+-									  dev->name, csr0 ));
+-						/* Restart the chip. */
+-						DREG = CSR0_STRT;
+-					}
+-				} else {
+-					if (status & (TMD1_MORE | TMD1_ONE | TMD1_DEF))
+-						lp->stats.collisions++;
+-					lp->stats.tx_packets++;
+-				}
+-				dirty_tx++;
+-			}
+-
+-#ifndef final_version
+-			if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
+-				DPRINTK( 0, ( "out-of-sync dirty pointer,"
+-							  " %d vs. %d, full=%d.\n",
+-							  dirty_tx, lp->cur_tx, lp->tx_full ));
+-				dirty_tx += TX_RING_SIZE;
+-			}
+-#endif
+-
+-			if (lp->tx_full && dev->tbusy
+-				&& dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
+-				/* The ring is no longer full, clear tbusy. */
+-				lp->tx_full = 0;
+-				dev->tbusy = 0;
+-				mark_bh( NET_BH );
+-			}
+-
+-			lp->dirty_tx = dirty_tx;
+-		}
+-
+-		/* Log misc errors. */
+-		if (csr0 & CSR0_BABL) lp->stats.tx_errors++; /* Tx babble. */
+-		if (csr0 & CSR0_MISS) lp->stats.rx_errors++; /* Missed a Rx frame. */
+-		if (csr0 & CSR0_MERR) {
+-			DPRINTK( 1, ( "%s: Bus master arbitration failure (?!?), "
+-						  "status %04x.\n", dev->name, csr0 ));
+-			/* Restart the chip. */
+-			DREG = CSR0_STRT;
+-		}
+-	}
+-
+-    /* Clear any other interrupt, and set interrupt enable. */
+-	DREG = CSR0_BABL | CSR0_CERR | CSR0_MISS | CSR0_MERR |
+-		   CSR0_IDON | CSR0_INEA;
+-
+-	DPRINTK( 2, ( "%s: exiting interrupt, csr0=%#04x.\n",
+-				  dev->name, DREG ));
+-	dev->interrupt = 0;
+-	return IRQ_RETVAL(handled);
+-}
+-
+-
+-static int lance_rx( struct net_device *dev )
+-
+-{	struct lance_private *lp = netdev_priv(dev);
+-	int entry = lp->cur_rx & RX_RING_MOD_MASK;
+-	int i;
+-
+-#ifdef NORMAL_MEM_ACCESS
+-	DPRINTK( 2, ( "%s: rx int, flag=%04x\n", dev->name,
+-				  MEM->rx_head[entry].flag ));
+-#else
+-	DPRINTK( 2, ( "%s: rx int, flag=%04x\n", dev->name,
+-				  GET_FLAG(&MEM->rx_head[entry]) ));
+-#endif
+-
+-	/* If we own the next entry, it's a new packet. Send it up. */
+-#ifdef NORMAL_MEM_ACCESS
+-	while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) {
+-#else
+-	while( (GET_FLAG(&MEM->rx_head[entry]) & RMD1_OWN) == RMD1_OWN_HOST ) {
+-#endif
+-		struct lance_rx_head *head = &(MEM->rx_head[entry]);
+-#ifdef NORMAL_MEM_ACCESS
+-		int status = head->flag;
+-#else
+-		int status = GET_FLAG(head);
+-#endif
+-
+-		if (status != (RMD1_ENP|RMD1_STP)) {		/* There was an error. */
+-			/* There is a tricky error noted by John Murphy,
+-			   <murf at perftech.com> to Russ Nelson: Even with full-sized
+-			   buffers it's possible for a jabber packet to use two
+-			   buffers, with only the last correctly noting the error. */
+-			if (status & RMD1_ENP)	/* Only count a general error at the */
+-				lp->stats.rx_errors++; /* end of a packet.*/
+-			if (status & RMD1_FRAM) lp->stats.rx_frame_errors++;
+-			if (status & RMD1_OFLO) lp->stats.rx_over_errors++;
+-			if (status & RMD1_CRC) lp->stats.rx_crc_errors++;
+-			if (status & RMD1_BUFF) lp->stats.rx_fifo_errors++;
+-#ifdef NORMAL_MEM_ACCESS
+-			head->flag &= (RMD1_ENP|RMD1_STP);
+-#else
+-			SET_FLAG(head,GET_FLAG(head) & (RMD1_ENP|RMD1_STP));
+-#endif
+-		} else {
+-			/* Malloc up new buffer, compatible with net-3. */
+-			short pkt_len = head->msg_length & 0xfff;
+-			struct sk_buff *skb;
+-
+-			if (pkt_len < 60) {
+-				printk( "%s: Runt packet!\n", dev->name );
+-				lp->stats.rx_errors++;
+-			}
+-			else {
+-				skb = dev_alloc_skb( pkt_len+2 );
+-				if (skb == NULL) {
+-					DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
+-								  dev->name ));
+-                          for( i = 0; i < RX_RING_SIZE; i++ )
+-#ifdef NORMAL_MEM_ACCESS
+-                        if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag &
+-#else
+-						if (GET_FLAG(&MEM->rx_head[(entry+i) & \
+-												  RX_RING_MOD_MASK]) &
+-#endif
+-							RMD1_OWN_CHIP)
+-							break;
+-
+-					if (i > RX_RING_SIZE - 2) {
+-						lp->stats.rx_dropped++;
+-#ifdef NORMAL_MEM_ACCESS
+-                        head->flag |= RMD1_OWN_CHIP;
+-#else
+-                        SET_FLAG(head,GET_FLAG(head) | RMD1_OWN_CHIP);
+-#endif
+-						lp->cur_rx++;
+-					}
+-					break;
+-				}
+-
+-				if (lance_debug >= 3) {
+-					u_char *data = PKTBUF_ADDR(head), *p;
+-					printk( "%s: RX pkt type 0x%04x from ", dev->name,
+-							((u_short *)data)[6]);
+-					for( p = &data[6], i = 0; i < 6; i++ )
+-						printk("%02x%s", *p++, i != 5 ? ":" : "" );
+-					printk(" to ");
+-					for( p = data, i = 0; i < 6; i++ )
+-						printk("%02x%s", *p++, i != 5 ? ":" : "" );
+-					printk(" data %02x %02x %02x %02x %02x %02x %02x %02x "
+-						   "len %d\n",
+-						   data[15], data[16], data[17], data[18],
+-						   data[19], data[20], data[21], data[22],
+-						   pkt_len );
+-				}
+-
+-				skb->dev = dev;
+-				skb_reserve( skb, 2 );	/* 16 byte align */
+-				skb_put( skb, pkt_len );	/* Make room */
+-				lp->memcpy_f( skb->data, PKTBUF_ADDR(head), pkt_len );
+-				skb->protocol = eth_type_trans( skb, dev );
+-				netif_rx( skb );
+-				dev->last_rx = jiffies;
+-				lp->stats.rx_packets++;
+-				lp->stats.rx_bytes += pkt_len;
+-			}
+-		}
+-
+-#ifdef NORMAL_MEM_ACCESS
+-		head->flag |= RMD1_OWN_CHIP;
+-#else
+-		SET_FLAG(head,GET_FLAG(head) | RMD1_OWN_CHIP);
+-#endif
+-		entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
+-	}
+-	lp->cur_rx &= RX_RING_MOD_MASK;
+-
+-	/* From lance.c (Donald Becker): */
+-	/* We should check that at least two ring entries are free.	 If not,
+-	   we should free one and mark stats->rx_dropped++. */
+-
+-	return 0;
+-}
+-
+-
+-static int lance_close( struct net_device *dev )
+-
+-{	struct lance_private *lp = netdev_priv(dev);
+-	struct lance_ioreg	 *IO = lp->iobase;
+-
+-	dev->start = 0;
+-	dev->tbusy = 1;
+-
+-	AREG = CSR0;
+-
+-	DPRINTK( 2, ( "%s: Shutting down ethercard, status was %2.2x.\n",
+-				  dev->name, DREG ));
+-
+-	/* We stop the LANCE here -- it occasionally polls
+-	   memory if we don't. */
+-	DREG = CSR0_STOP;
+-
+-	return 0;
+-}
+-
+-
+-static struct net_device_stats *lance_get_stats( struct net_device *dev )
+-
+-{	
+-	struct lance_private *lp = netdev_priv(dev);
+-	return &lp->stats;
+-}
+-
+-
+-/* Set or clear the multicast filter for this adaptor.
+-   num_addrs == -1		Promiscuous mode, receive all packets
+-   num_addrs == 0		Normal mode, clear multicast list
+-   num_addrs > 0		Multicast mode, receive normal and MC packets, and do
+-						best-effort filtering.
+- */
+-
+-static void set_multicast_list( struct net_device *dev )
+-
+-{	struct lance_private *lp = netdev_priv(dev);
+-	struct lance_ioreg	 *IO = lp->iobase;
+-
+-	if (!dev->start)
+-		/* Only possible if board is already started */
+-		return;
+-
+-	/* We take the simple way out and always enable promiscuous mode. */
+-	DREG = CSR0_STOP; /* Temporarily stop the lance. */
+-
+-	if (dev->flags & IFF_PROMISC) {
+-		/* Log any net taps. */
+-		DPRINTK( 1, ( "%s: Promiscuous mode enabled.\n", dev->name ));
+-		REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
+-	} else {
+-		short multicast_table[4];
+-		int num_addrs = dev->mc_count;
+-		int i;
+-		/* We don't use the multicast table, but rely on upper-layer
+-		 * filtering. */
+-		memset( multicast_table, (num_addrs == 0) ? 0 : -1,
+-				sizeof(multicast_table) );
+-		for( i = 0; i < 4; i++ )
+-			REGA( CSR8+i ) = multicast_table[i];
+-		REGA( CSR15 ) = 0; /* Unset promiscuous mode */
+-	}
+-
+-	/*
+-	 * Always set BSWP after a STOP as STOP puts it back into
+-	 * little endian mode.
+-	 */
+-	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
+-
+-	/* Resume normal operation and reset AREG to CSR0 */
+-	REGA( CSR0 ) = CSR0_IDON | CSR0_INEA | CSR0_STRT;
+-}
+-
+-
+-/* This is needed for old RieblCards and possible for new RieblCards */
+-
+-static int lance_set_mac_address( struct net_device *dev, void *addr )
+-
+-{	struct lance_private *lp = netdev_priv(dev);
+-	struct sockaddr *saddr = addr;
+-	int i;
+-
+-	if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL)
+-		return( -EOPNOTSUPP );
+-
+-	if (dev->start) {
+-		/* Only possible while card isn't started */
+-		DPRINTK( 1, ( "%s: hwaddr can be set only while card isn't open.\n",
+-					  dev->name ));
+-		return( -EIO );
+-	}
+-
+-	slow_memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len );
+-
+-	{
+-			unsigned char hwaddr[6];
+-			for( i = 0; i < 6; i++ ) 
+-					hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */
+-			slow_memcpy(MEM->init.hwaddr, hwaddr, sizeof(hwaddr));
+-	}
+-
+-	lp->memcpy_f( RIEBL_HWADDR_ADDR, dev->dev_addr, 6 );
+-	/* set also the magic for future sessions */
+-#ifdef NORMAL_MEM_ACCESS
+-	*RIEBL_MAGIC_ADDR = RIEBL_MAGIC;
+-#else
+-	{
+-			unsigned long magic = RIEBL_MAGIC;
+-			slow_memcpy(RIEBL_MAGIC_ADDR, &magic, sizeof(*RIEBL_MAGIC_ADDR));
+-	}
+-#endif
+-	return( 0 );
+-}
+-
+-
+-#ifdef MODULE
+-static struct net_device *bagetlance_dev;
+-
+-int init_module(void)
+-{
+-	bagetlance_dev = bagetlance_probe(-1);
+-	if (IS_ERR(bagetlance_dev))
+-		return PTR_ERR(bagetlance_dev);
+-	return 0;
+-}
+-
+-void cleanup_module(void)
+-{
+-	unregister_netdev(bagetlance_dev);
+-	free_irq(bagetlance_dev->irq, bagetlance_dev);
+-	free_netdev(bagetlance_dev);
+-}
+-
+-#endif /* MODULE */
+-
+-/*
+- * Local variables:
+- *  c-indent-level: 4
+- *  tab-width: 4
+- * End:
+- */
+diff -urpNX dontdiff linux-2.6.10/drivers/net/big_sur_ge.c linux-2.6.10-mips/drivers/net/big_sur_ge.c
+--- linux-2.6.10/drivers/net/big_sur_ge.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/big_sur_ge.c	2004-10-27 02:14:31.000000000 +0200
+@@ -0,0 +1,2005 @@
++/*
++ * drivers/net/big_sur_ge.c - Driver for PMC-Sierra Big Sur ethernet ports
++ *
++ * Copyright (C) 2003 PMC-Sierra Inc.
++ * Author : Manish Lachwani (lachwani at pmc-sierra.com)
++ * Copyright (C) 2003 Ralf Baechle (ralf at linux-mips.org)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++ *
++ */
++
++/*************************************************************************
++ * Description :
++ *
++ * The driver has three modes of operation: FIFO non-DMA, Simple DMA
++ * and SG DMA. There is also a Polled mode and an Interrupt mode of
++ * operation. SG DMA should do zerocopy and check offload. Probably,
++ * zerocopy on the Rx might also work. Simple DMA is the non-zerocpy
++ * case on the Tx and the Rx.
++ *
++ * We turn on Simple DMA and interrupt mode. Although, support has been
++ * added for the SG mode also but not for the polled mode. This is a
++ * Fast Ethernet driver although there will be support for Gigabit soon.
++ *
++ * The driver is divided into two parts: Hardware dependent and a
++ * Hardware independent. There is currently no support for checksum offload
++ * zerocopy and Rx NAPI. There is support for Interrupt Mitigation.
++ ****************************************************************************/
++
++/*************************************************************
++ * Hardware Indepenent Part of the driver
++ *************************************************************/
++
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/mii.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++
++#include "big_sur_ge.h"
++
++#define TX_TIMEOUT (60*HZ)	/* Transmission timeout is 60 seconds. */
++
++static struct net_device *dev_list = NULL;
++static spinlock_t dev_lock = SPIN_LOCK_UNLOCKED;
++
++typedef enum DUPLEX { UNKNOWN, HALF_DUPLEX, FULL_DUPLEX } DUPLEX;
++
++/* Big Sur Ethernet MAC structure */
++struct big_sur_ge_enet {
++	struct net_device_stats stats;	/* Statistics for this device */
++	struct net_device *next_dev;	/* The next device in dev_list */
++	struct timer_list phy_timer;	/* PHY monitoring timer */
++	u32 index;		/* Which interface is this */
++	u32 save_base_address;	/* Saved physical base address */
++	struct sk_buff *saved_skb;	/* skb being transmitted */
++	spinlock_t lock;	/* For atomic access to saved_skb */
++	u8 mii_addr;		/* The MII address of the PHY */
++	big_sur_ge emac;	/* GE driver structure */
++};
++
++/* Manish : For testing purposes only */
++static unsigned char big_sur_mac_addr_base[6] = "00:11:22:33:44:55";
++
++/*********************************************************************
++ * Function Prototypes (whole bunch of them)
++ *********************************************************************/
++unsigned long big_sur_ge_dma_control(xdma_channel *);
++void big_sur_ge_dma_reset(xdma_channel *);
++static void handle_fifo_intr(big_sur_ge *);
++void big_sur_ge_check_fifo_recv_error(big_sur_ge *);
++void big_sur_ge_check_fifo_send_error(big_sur_ge *);
++static int big_sur_ge_config_fifo(big_sur_ge *);
++big_sur_ge_config *big_sur_ge_lookup_config(unsigned int);
++static int big_sur_ge_config_dma(big_sur_ge *);
++void big_sur_ge_enet_reset(big_sur_ge *);
++void big_sur_ge_check_mac_error(big_sur_ge *, unsigned long);
++
++/*********************************************************************
++ * DMA Channel Initialization
++ **********************************************************************/
++static int big_sur_ge_dma_init(xdma_channel * dma, unsigned long base_address)
++{
++	dma->reg_base_address = base_address;
++	dma->get_ptr = NULL;
++	dma->put_ptr = NULL;
++	dma->commit_ptr = NULL;
++	dma->last_ptr = NULL;
++	dma->total_desc_count = (unsigned long) NULL;
++	dma->active_desc_count = (unsigned long) NULL;
++	dma->ready = 1;		/* DMA channel is ready */
++
++	big_sur_ge_dma_reset(dma);
++
++	return 0;
++}
++
++/*********************************************************************
++ * Is the DMA channel ready yet ?
++ **********************************************************************/
++static int big_sur_ge_dma_ready(xdma_channel * dma)
++{
++	return dma->ready == 1;
++}
++
++/*********************************************************************
++ * Perform the self test on the DMA channel
++ **********************************************************************/
++#define BIG_SUR_GE_CONTROL_REG_RESET_MASK	0x98000000
++
++static int big_sur_ge_dma_self_test(xdma_channel * dma)
++{
++	unsigned long reg_data;
++
++	big_sur_ge_dma_reset(dma);
++
++	reg_data = big_sur_ge_dma_control(dma);
++	if (reg_data != BIG_SUR_GE_CONTROL_REG_RESET_MASK) {
++		printk(KERN_ERR "DMA Channel Self Test Failed \n");
++		return -1;
++	}
++
++	return 0;
++}
++
++/*********************************************************************
++ * Reset the DMA channel
++ **********************************************************************/
++static void big_sur_ge_dma_reset(xdma_channel * dma)
++{
++	BIG_SUR_GE_WRITE(dma->reg_base_address + BIG_SUR_GE_RST_REG_OFFSET,
++			 BIG_SUR_GE_RESET_MASK);
++}
++
++/*********************************************************************
++ * Get control of the DMA channel
++ **********************************************************************/
++static unsigned long big_sur_ge_dma_control(xdma_channel * dma)
++{
++	return BIG_SUR_GE_READ(dma->reg_base_address +
++			       BIG_SUR_GE_DMAC_REG_OFFSET);
++}
++
++/*********************************************************************
++ * Set control of the DMA channel
++ **********************************************************************/
++static void big_sur_ge_set_dma_control(xdma_channel * dma, unsigned long control)
++{
++	BIG_SUR_GE_WRITE(dma->reg_base_address +
++			 BIG_SUR_GE_DMAC_REG_OFFSET, control);
++}
++
++/*********************************************************************
++ * Get the status of the DMA channel
++ *********************************************************************/
++static unsigned long big_sur_ge_dma_status(xdma_channel * dma)
++{
++	return BIG_SUR_GE_READ(dma->reg_base_address +
++			       BIG_SUR_GE_DMAS_REG_OFFSET);
++}
++
++/*********************************************************************
++ * Set the interrupt status of the DMA channel
++ *********************************************************************/
++static void big_sur_ge_set_intr_status(xdma_channel * dma, unsigned long status)
++{
++	BIG_SUR_GE_WRITE(dma->reg_base_address + BIG_SUR_GE_IS_REG_OFFSET,
++			 status);
++}
++
++/*********************************************************************
++ * Get the interrupt status of the DMA channel
++ *********************************************************************/
++static unsigned long big_sur_ge_get_intr_status(xdma_channel * dma)
++{
++	return BIG_SUR_GE_READ(dma->reg_base_address +
++			       BIG_SUR_GE_IS_REG_OFFSET);
++}
++
++/*********************************************************************
++ * Set the Interrupt Enable
++ *********************************************************************/
++static void big_sur_ge_set_intr_enable(xdma_channel * dma, unsigned long enable)
++{
++	BIG_SUR_GE_WRITE(dma->reg_base_address + BIG_SUR_GE_IE_REG_OFFSET,
++			 enable);
++}
++
++/*********************************************************************
++ * Get the Interrupt Enable field to make a check
++ *********************************************************************/
++static unsigned long big_sur_ge_get_intr_enable(xdma_channel * dma)
++{
++	return BIG_SUR_GE_READ(dma->reg_base_address +
++			       BIG_SUR_GE_IE_REG_OFFSET);
++}
++
++/*********************************************************************
++ * Transfer the data over the DMA channel
++ *********************************************************************/
++static void big_sur_ge_dma_transfer(xdma_channel * dma, unsigned long *source,
++			     unsigned long *dest, unsigned long length)
++{
++	BIG_SUR_GE_WRITE(dma->reg_base_address + BIG_SUR_GE_SA_REG_OFFSET,
++			 (unsigned long) source);
++
++	BIG_SUR_GE_WRITE(dma->reg_base_address + BIG_SUR_GE_DA_REG_OFFSET,
++			 (unsigned long) dest);
++
++	BIG_SUR_GE_WRITE(dma->reg_base_address + BIG_SUR_GE_LEN_REG_OFFSET,
++			 length);
++}
++
++/*********************************************************************
++ * Get the DMA descriptor
++ *********************************************************************/
++static int big_sur_ge_get_descriptor(xdma_channel * dma,
++			      xbuf_descriptor ** buffer_desc)
++{
++	unsigned long reg_data;
++
++	reg_data = xbuf_descriptor_GetControl(dma->get_ptr);
++	xbuf_descriptor_SetControl(dma->get_ptr, reg_data |
++				   BIG_SUR_GE_DMACR_SG_DISABLE_MASK);
++
++	*buffer_desc = dma->get_ptr;
++
++	dma->get_ptr = xbuf_descriptor_GetNextPtr(dma->get_ptr);
++	dma->active_desc_count--;
++
++	return 0;
++}
++
++/*********************************************************************
++ * Get the packet count
++ *********************************************************************/
++static int big_sur_ge_get_packet_count(xdma_channel * dma)
++{
++	return (BIG_SUR_GE_READ
++		(dma->reg_base_address + BIG_SUR_GE_UPC_REG_OFFSET));
++}
++
++/*********************************************************************
++ * Descrement the packet count
++ *********************************************************************/
++static void big_sur_ge_decr_packet_count(xdma_channel * dma)
++{
++	unsigned long reg_data;
++
++	reg_data =
++	    BIG_SUR_GE_READ(dma->base_address + BIG_SUR_GE_UPC_REG_OFFSET);
++	if (reg_data > 0)
++		BIG_SUR_GE_WRITE(dma->base_address +
++				 BIG_SUR_GE_UPC_REG_OFFSET, 1);
++}
++
++/****************************************************************************
++ * Start of the code that deals with the Packet Fifo
++ *****************************************************************************/
++
++/****************************************************************************
++ * Init the packet fifo
++ ****************************************************************************/
++static int packet_fifo_init(packet_fifo * fifo, u32 reg, u32 data)
++{
++	fifo->reg_base_addr = reg;
++	fifo->data_base_address = data;
++	fifo->ready_status = 1;
++
++	BIG_SUR_GE_FIFO_RESET(fifo);
++
++	return 0;
++}
++
++/****************************************************************************
++ * Packet fifo self test
++ ****************************************************************************/
++static int packet_fifo_self_test(packet_fifo * fifo, unsigned long type)
++{
++	unsigned long reg_data;
++
++	BIG_SUR_GE_FIFO_RESET(fifo);
++	reg_data =
++	    BIG_SUR_GE_READ(fifo->reg_base_addr +
++			    BIG_SUR_GE_COUNT_STATUS_REG_OFFSET);
++
++	if (type == BIG_SUR_GE_READ_FIFO_TYPE) {
++		if (reg_data != BIG_SUR_GE_EMPTY_FULL_MASK) {
++			printk(KERN_ERR "Read FIFO not empty \n");
++			return -1;
++		}
++	} else if (!(reg_data & BIG_SUR_GE_EMPTY_FULL_MASK)) {
++		printk(KERN_ERR "Write FIFO is full \n");
++		return -1;
++	}
++
++	return 0;
++}
++
++/****************************************************************************
++ * Packet FIFO read
++ ****************************************************************************/
++static int packet_fifo_read(packet_fifo * fifo, u8 * buffer, unsigned int len)
++{
++	unsigned long fifo_count, word_count, extra_byte;
++	unsigned long *buffer_data = (unsigned long *) buffer;
++
++	fifo_count =
++	    BIG_SUR_GE_READ(fifo->reg_base_addr +
++			    BIG_SUR_GE_FIFO_WIDTH_BYTE_COUNT);
++	fifo_count &= BIG_SUR_GE_COUNT_MASK;
++
++	if ((fifo_count * BIG_SUR_GE_FIFO_WIDTH_BYTE_COUNT) < len)
++		return -1;
++
++	word_count = len / BIG_SUR_GE_FIFO_WIDTH_BYTE_COUNT;
++	extra_byte = len % BIG_SUR_GE_FIFO_WIDTH_BYTE_COUNT;
++
++	for (fifo_count = 0; fifo_count < word_count; fifo_count++)
++		buffer_data[fifo_count] =
++		    BIG_SUR_GE_READ(fifo->reg_base_addr);
++
++	if (extra_byte > 0) {
++		unsigned long last_word;
++		int *extra_buffer_data =
++		    (int *) (buffer_data + word_count);
++
++		last_word = BIG_SUR_GE_READ(fifo->data_base_address);
++		if (extra_byte == 1)
++			extra_buffer_data[0] = (int) (last_word << 24);
++		else if (extra_byte == 2) {
++			extra_buffer_data[0] = (int) (last_word << 24);
++			extra_buffer_data[1] = (int) (last_word << 16);
++		} else if (extra_byte == 3) {
++			extra_buffer_data[0] = (int) (last_word << 24);
++			extra_buffer_data[1] = (int) (last_word << 16);
++			extra_buffer_data[2] = (int) (last_word << 8);
++		}
++	}
++
++	return 0;
++}
++
++/*****************************************************************************
++ * Write the data into the packet fifo
++ *****************************************************************************/
++static int packet_fifo_write(packet_fifo * fifo, int *buffer, int len)
++{
++	unsigned long fifo_count, word_count, extra_byte;
++	unsigned long *buffer_data = (unsigned long *) buffer;
++
++	fifo_count =
++	    BIG_SUR_GE_READ(fifo->reg_base_addr +
++			    BIG_SUR_GE_FIFO_WIDTH_BYTE_COUNT);
++	fifo_count &= BIG_SUR_GE_COUNT_MASK;
++
++	word_count = len / BIG_SUR_GE_FIFO_WIDTH_BYTE_COUNT;
++	extra_byte = len % BIG_SUR_GE_FIFO_WIDTH_BYTE_COUNT;
++
++	/* You should see what the ppc driver does here. It just slobbers */
++	if (extra_byte > 0)
++		if (fifo_count > (word_count + 1)) {
++			printk(KERN_ERR
++			       "No room in the packet send fifo \n");
++			return -1;
++		}
++
++	for (fifo_count = 0; fifo_count < word_count; fifo_count++)
++		BIG_SUR_GE_WRITE(fifo->data_base_address,
++				 buffer_data[fifo_count]);
++
++
++	if (extra_byte > 0) {
++		unsigned long last_word = 0;
++		int *extra_buffer_data =
++		    (int *) (buffer_data + word_count);
++
++		if (extra_byte == 1)
++			last_word = extra_buffer_data[0] << 24;
++		else if (extra_byte == 2)
++			last_word = (extra_buffer_data[0] << 24 |
++				     extra_buffer_data[1] << 16);
++
++		else if (extra_byte == 3)
++			last_word = (extra_buffer_data[0] << 24 |
++				     extra_buffer_data[1] << 16 |
++				     extra_buffer_data[2] << 8);
++
++
++		BIG_SUR_GE_WRITE(fifo->data_base_address, last_word);
++	}
++
++	return 0;
++}
++
++
++/*****************************************************************************
++ * Interrupt handlers: We handle any errors associated with the FIFO.
++ * FIFO is for simple dma case and we do want to handle the simple DMA
++ * case. We dont handle the Scatter Gather DMA for now since it is not working.
++ ******************************************************************************/
++
++/*********************************************************************************
++ * FIFO send for Simple DMA with Interrupts
++ **********************************************************************************/
++static int big_sur_ge_enet_fifo_send(big_sur_ge * emac, u8 * buffer,
++			      unsigned long byte_cnt)
++{
++	unsigned long int_status, reg_data;
++
++	/* Silly checks here that we really dont need */
++	if (!emac->started)
++		return -1;
++
++	if (emac->polled)
++		return -1;
++
++	if (emac->dma_sg)
++		return -1;
++
++	int_status =
++	    BIG_SUR_GE_READ(emac->base_address + XIIF_V123B_IISR_OFFSET);
++	if (int_status & BIG_SUR_GE_EIR_XMIT_LFIFO_FULL_MASK) {
++		printk(KERN_ERR "Tx FIFO error: Queue is Full \n");
++		return -1;
++	}
++
++	/*
++	 * Write the data to the FIFO in the hardware
++	 */
++	if ((BIG_SUR_GE_GET_COUNT(&emac->send_fifo) *
++	     sizeof(unsigned long)) < byte_cnt) {
++		printk(KERN_ERR "Send FIFO on chip is full \n");
++		return -1;
++	}
++
++	if (big_sur_ge_dma_status(&emac->send_channel) &
++	    BIG_SUR_GE_DMASR_BUSY_MASK) {
++		printk(KERN_ERR "Send channel FIFO engine busy \n");
++		return -1;
++	}
++
++	big_sur_ge_set_dma_control(&emac->send_channel,
++				   BIG_SUR_GE_DMACR_SOURCE_INCR_MASK |
++				   BIG_SUR_GE_DMACR_DEST_LOCAL_MASK |
++				   BIG_SUR_GE_DMACR_SG_DISABLE_MASK);
++
++	big_sur_ge_dma_transfer(&emac->send_channel,
++				(unsigned long *) buffer,
++				(unsigned long *) (emac->base_address +
++						   BIG_SUR_GE_PFIFO_TXDATA_OFFSET),
++				byte_cnt);
++
++	reg_data = big_sur_ge_dma_status(&emac->send_channel);
++	while (reg_data & BIG_SUR_GE_DMASR_BUSY_MASK) {
++		reg_data = big_sur_ge_dma_status(&emac->recv_channel);
++		if (!(reg_data & BIG_SUR_GE_DMASR_BUSY_MASK))
++			break;
++	}
++
++	if ((reg_data & BIG_SUR_GE_DMASR_BUS_ERROR_MASK) ||
++	    (reg_data & BIG_SUR_GE_DMASR_BUS_TIMEOUT_MASK)) {
++		printk(KERN_ERR "Send side DMA error \n");
++		return -1;
++	}
++
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_TPLR_OFFSET,
++			 byte_cnt);
++
++	return 0;
++}
++
++/*************************************************************************
++ * FIFO receive for Simple DMA case
++ *************************************************************************/
++static int big_sur_ge_enet_fifo_recv(big_sur_ge * emac, u8 * buffer,
++			      unsigned long *byte_cnt)
++{
++	unsigned long int_status, reg_data;
++
++	/* Silly checks here that we really dont need */
++	if (!emac->started)
++		return -1;
++
++	if (emac->polled)
++		return -1;
++
++	if (emac->dma_sg)
++		return -1;
++
++	if (*byte_cnt < BIG_SUR_GE_MAX_FRAME_SIZE)
++		return -1;
++
++	int_status =
++	    BIG_SUR_GE_READ(emac->base_address + XIIF_V123B_IISR_OFFSET);
++	if (int_status & BIG_SUR_GE_EIR_RECV_LFIFO_EMPTY_MASK) {
++		BIG_SUR_GE_WRITE(emac->base_address +
++				 XIIF_V123B_IISR_OFFSET,
++				 BIG_SUR_GE_EIR_RECV_LFIFO_EMPTY_MASK);
++		return -1;
++	}
++
++	if (big_sur_ge_dma_status(&emac->recv_channel) &
++	    BIG_SUR_GE_DMASR_BUSY_MASK) {
++		printk(KERN_ERR "Rx side DMA Engine busy \n");
++		return -1;
++	}
++
++	if (BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_RPLR_OFFSET) ==
++	    0) {
++		printk(KERN_ERR "MAC has the FIFO packet length 0 \n");
++		return -1;
++	}
++
++	/* For the simple DMA case only */
++	big_sur_ge_set_dma_control(&emac->recv_channel,
++				   BIG_SUR_GE_DMACR_DEST_INCR_MASK |
++				   BIG_SUR_GE_DMACR_SOURCE_LOCAL_MASK |
++				   BIG_SUR_GE_DMACR_SG_DISABLE_MASK);
++
++	if (packet_fifo_read(&emac->recv_fifo, buffer,
++			     BIG_SUR_GE_READ(emac->base_address +
++					     BIG_SUR_GE_RPLR_OFFSET)) ==
++	    -1) {
++		printk(KERN_ERR "Not enough space in the FIFO \n");
++		return -1;
++	}
++
++	big_sur_ge_dma_transfer(&emac->recv_channel,
++				(unsigned long *) (emac->base_address +
++						   BIG_SUR_GE_PFIFO_RXDATA_OFFSET),
++				(unsigned long *)
++				buffer,
++				BIG_SUR_GE_READ(emac->base_address +
++						BIG_SUR_GE_RPLR_OFFSET));
++
++	reg_data = big_sur_ge_dma_status(&emac->recv_channel);
++	while (reg_data & BIG_SUR_GE_DMASR_BUSY_MASK) {
++		reg_data = big_sur_ge_dma_status(&emac->recv_channel);
++		if (!(reg_data & BIG_SUR_GE_DMASR_BUSY_MASK))
++			break;
++	}
++
++	if ((reg_data & BIG_SUR_GE_DMASR_BUS_ERROR_MASK) ||
++	    (reg_data & BIG_SUR_GE_DMASR_BUS_TIMEOUT_MASK)) {
++		printk(KERN_ERR "DMA Bus Error \n");
++		return -1;
++	}
++
++	*byte_cnt =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_RPLR_OFFSET);
++
++	return 0;
++}
++
++static irqreturn_t big_sur_ge_int_handler(int irq, void *dev_id,
++				   struct pt_regs *regs)
++{
++	struct net_device *netdev = dev_id;
++	struct big_sur_ge_enet *lp = netdev->priv;
++	big_sur_ge *emac = (big_sur_ge *)emac_ptr;
++	void *emac_ptr = &lp->emac;
++	unsigned long int_status;
++
++	int_status =
++	    BIG_SUR_GE_READ(emac->base_address + XIIF_V123B_DIPR_OFFSET);
++	if (int_status & BIG_SUR_GE_IPIF_EMAC_MASK)
++		handle_fifo_intr(emac);
++
++	if (int_status & BIG_SUR_GE_IPIF_RECV_FIFO_MASK)
++		big_sur_ge_check_fifo_recv_error(emac);
++
++	if (int_status & BIG_SUR_GE_IPIF_SEND_FIFO_MASK)
++		big_sur_ge_check_fifo_send_error(emac);
++
++	if (int_status & XIIF_V123B_ERROR_MASK)
++		BIG_SUR_GE_WRITE(emac->base_address +
++				 XIIF_V123B_DISR_OFFSET,
++				 XIIF_V123B_ERROR_MASK);
++
++	return IRQ_HANDLED;
++}
++
++/****************************************************************************
++ * Set the FIFO send handler
++ ***************************************************************************/
++static void big_sur_ge_set_fifo_send_handler(big_sur_ge * emac, void *call_back,
++				      big_sur_fifo_handler function)
++{
++	emac->big_sur_ge_fifo_send_handler = function;
++	emac->fifo_send_ref = call_back;
++}
++
++/****************************************************************************
++ * Set the FIFO recv handler
++ ***************************************************************************/
++static void big_sur_ge_set_fifo_recv_handler(big_sur_ge * emac, void *call_back,
++				      big_sur_fifo_handler function)
++{
++	emac->big_sur_ge_fifo_recv_handler = function;
++	emac->fifo_recv_ref = call_back;
++}
++
++/****************************************************************************
++ * Main Fifo intr handler
++ ***************************************************************************/
++static void handle_fifo_intr(big_sur_ge * emac)
++{
++	unsigned long int_status;
++
++	/* Ack the interrupts asap */
++	int_status =
++	    BIG_SUR_GE_READ(emac->base_address + XIIF_V123B_IISR_OFFSET);
++	BIG_SUR_GE_WRITE(emac->base_address + XIIF_V123B_IISR_OFFSET,
++			 int_status);
++
++	/* Process the Rx side */
++	if (int_status & BIG_SUR_GE_EIR_RECV_DONE_MASK) {
++		emac->big_sur_ge_fifo_recv_handler(&emac->fifo_recv_ref);
++		BIG_SUR_GE_WRITE(emac->base_address +
++				 XIIF_V123B_IISR_OFFSET,
++				 BIG_SUR_GE_EIR_RECV_DONE_MASK);
++	}
++
++	if (int_status & BIG_SUR_GE_EIR_XMIT_DONE_MASK) {
++		/* We dont collect stats and hence we dont need to get status */
++
++		emac->big_sur_ge_fifo_send_handler(emac->fifo_recv_ref);
++		BIG_SUR_GE_WRITE(emac->base_address +
++				 XIIF_V123B_IISR_OFFSET,
++				 BIG_SUR_GE_EIR_XMIT_DONE_MASK);
++	}
++
++	big_sur_ge_check_mac_error(emac, int_status);
++}
++
++/******************************************************************
++ * Handle the Receive side DMA interrupts. The PPC driver has
++ * callbacks all over the place. This has been eliminated here by
++ * using the following approach:
++ *
++ * The ISR is set to the main interrrupt handler. This will handle
++ * all the interrupts including the ones for DMA. In this main isr,
++ * we determine if we need to call recv or send side intr functions.
++ * Pretty complex but thats the way it is now.
++ *******************************************************************/
++static void big_sur_ge_handle_recv_intr(big_sur_ge * emac)
++{
++	unsigned long int_status;
++
++	int_status = big_sur_ge_get_intr_status(&emac->recv_channel);
++	if (int_status & (BIG_SUR_GE_IXR_PKT_THRESHOLD_MASK |
++			  BIG_SUR_GE_IXR_PKT_WAIT_BOUND_MASK)) {
++		u32 num_packets;
++		u32 num_processed;
++		u32 num_buffers;
++		u32 num_bytes;
++		xbuf_descriptor *first_desc_ptr = NULL;
++		xbuf_descriptor *buffer_desc;
++		int is_last = 0;
++
++		/* The number of packets we need to process on the Rx */
++		num_packets =
++		    big_sur_ge_get_packet_count(&emac->recv_channel);
++
++		for (num_processed = 0; num_processed < num_packets;
++		     num_processed++) {
++			while (!is_last) {
++				if (big_sur_ge_get_descriptor
++				    (&emac->recv_channel,
++				     &buffer_desc) == -1)
++					break;
++
++				if (first_desc_ptr == NULL)
++					first_desc_ptr = buffer_desc;
++
++				num_bytes +=
++				    xbuf_descriptor_GetLength(buffer_desc);
++
++				if (xbuf_descriptor_IsLastStatus
++				    (buffer_desc)) {
++					is_last = 1;
++				}
++
++				num_buffers++;
++			}
++
++			/* Number of buffers is always 1 since we dont do SG */
++
++			/*
++			 * Only for SG DMA which is currently not supported. In the
++			 * future, as we have SG channel working, we will code this
++			 * receive side routine. For now, do nothing. This is never
++			 * called from FIFO mode - Manish
++			 */
++			big_sur_ge_decr_packet_count(&emac->recv_channel);
++		}
++	}
++
++	/* Ack the interrupts */
++	big_sur_ge_set_intr_status(&emac->recv_channel, int_status);
++
++	if (int_status & BIG_SUR_GE_IXR_DMA_ERROR_MASK) {
++		/* We need a reset here */
++	}
++
++	big_sur_ge_set_intr_status(&emac->recv_channel, int_status);
++}
++
++/****************************************************************
++ * Handle the send side DMA interrupt
++ ****************************************************************/
++static void big_sur_ge_handle_send_intr(big_sur_ge * emac)
++{
++	unsigned long int_status;
++
++	int_status = big_sur_ge_get_intr_status(&emac->send_channel);
++
++	if (int_status & (BIG_SUR_GE_IXR_PKT_THRESHOLD_MASK |
++			  BIG_SUR_GE_IXR_PKT_WAIT_BOUND_MASK)) {
++		unsigned long num_frames = 0;
++		unsigned long num_processed = 0;
++		unsigned long num_buffers = 0;
++		unsigned long num_bytes = 0;
++		unsigned long is_last = 0;
++		xbuf_descriptor *first_desc_ptr = NULL;
++		xbuf_descriptor *buffer_desc;
++
++		num_frames =
++		    big_sur_ge_get_packet_count(&emac->send_channel);
++
++		for (num_processed = 0; num_processed < num_frames;
++		     num_processed++) {
++			while (!is_last) {
++				if (big_sur_ge_get_descriptor
++				    (&emac->send_channel, &buffer_desc)
++				    == -1) {
++					break;
++				}
++
++				if (first_desc_ptr == NULL)
++					first_desc_ptr = buffer_desc;
++
++				num_bytes +=
++				    xbuf_descriptor_GetLength(buffer_desc);
++				if (xbuf_descriptor_IsLastControl
++				    (buffer_desc))
++					is_last = 1;
++
++				num_buffers++;
++			}
++
++			/*
++			 * Only for SG DMA which is currently not supported. In the
++			 * future, as we have SG channel working, we will code this
++			 * receive side routine. For now, do nothing. This is never
++			 * called from FIFO mode - Manish
++			 */
++			big_sur_ge_decr_packet_count(&emac->send_channel);
++		}
++	}
++
++	/* Ack the interrupts and reset DMA channel if necessary */
++	big_sur_ge_set_intr_status(&emac->send_channel, int_status);
++	if (int_status & BIG_SUR_GE_IXR_DMA_ERROR_MASK) {
++		/* Manish : need reset */
++	}
++
++	big_sur_ge_set_intr_status(&emac->send_channel, int_status);
++}
++
++/*****************************************************************
++ * For now, the MAC address errors dont trigger a update of the
++ * stats. There is no stats framework in place. Hence, we just
++ * check for the errors below and do a reset if needed.
++ *****************************************************************/
++static void big_sur_ge_check_mac_error(big_sur_ge * emac,
++				unsigned long int_status)
++{
++	if (int_status & (BIG_SUR_GE_EIR_RECV_DFIFO_OVER_MASK |
++			  BIG_SUR_GE_EIR_RECV_LFIFO_OVER_MASK |
++			  BIG_SUR_GE_EIR_RECV_LFIFO_UNDER_MASK |
++			  BIG_SUR_GE_EIR_RECV_ERROR_MASK |
++			  BIG_SUR_GE_EIR_RECV_MISSED_FRAME_MASK |
++			  BIG_SUR_GE_EIR_RECV_COLLISION_MASK |
++			  BIG_SUR_GE_EIR_RECV_FCS_ERROR_MASK |
++			  BIG_SUR_GE_EIR_RECV_LEN_ERROR_MASK |
++			  BIG_SUR_GE_EIR_RECV_SHORT_ERROR_MASK |
++			  BIG_SUR_GE_EIR_RECV_LONG_ERROR_MASK |
++			  BIG_SUR_GE_EIR_RECV_ALIGN_ERROR_MASK |
++			  BIG_SUR_GE_EIR_XMIT_SFIFO_OVER_MASK |
++			  BIG_SUR_GE_EIR_XMIT_LFIFO_OVER_MASK |
++			  BIG_SUR_GE_EIR_XMIT_SFIFO_UNDER_MASK |
++			  BIG_SUR_GE_EIR_XMIT_LFIFO_UNDER_MASK)) {
++
++		BIG_SUR_GE_WRITE(emac->base_address +
++				 XIIF_V123B_IIER_OFFSET, 0);
++		/*
++		 * Manish Reset the MAC here
++		 */
++	}
++}
++
++/*****************************************************************
++ * Check for FIFO Recv errors
++ *****************************************************************/
++static void big_sur_ge_check_fifo_recv_error(big_sur_ge * emac)
++{
++	if (BIG_SUR_GE_IS_DEADLOCKED(&emac->recv_fifo)) {
++		unsigned long intr_enable;
++
++		intr_enable =
++		    BIG_SUR_GE_READ(emac->base_address +
++				    XIIF_V123B_DIER_OFFSET);
++		BIG_SUR_GE_WRITE(emac->base_address +
++				 XIIF_V123B_DIER_OFFSET,
++				 intr_enable &
++				 ~(BIG_SUR_GE_IPIF_RECV_FIFO_MASK));
++
++	}
++}
++
++/*****************************************************************
++ * Check for FIFO Send errors
++ *****************************************************************/
++static void big_sur_ge_check_fifo_send_error(big_sur_ge * emac)
++{
++	if (BIG_SUR_GE_IS_DEADLOCKED(&emac->send_fifo)) {
++		unsigned long intr_enable;
++
++		intr_enable =
++		    BIG_SUR_GE_READ(emac->base_address +
++				    XIIF_V123B_DIER_OFFSET);
++		BIG_SUR_GE_WRITE(emac->base_address +
++				 XIIF_V123B_DIER_OFFSET,
++				 intr_enable &
++				 ~(BIG_SUR_GE_IPIF_SEND_FIFO_MASK));
++	}
++}
++
++/*****************************************************************
++ * GE unit init
++ ****************************************************************/
++static int big_sur_ge_enet_init(big_sur_ge * emac, unsigned int device_id)
++{
++	unsigned long reg_data;
++	big_sur_ge_config *config;
++	int err;
++
++	/* Assume that the device has been stopped */
++
++	config = big_sur_ge_lookup_config(device_id);
++	if (config == NULL)
++		return -1;
++
++	emac->ready = 0;
++	emac->started = 0;
++	emac->dma_sg = 0;	/* This MAC has no support for Scatter Gather DMA */
++	emac->has_mii = config->has_mii;
++	emac->has_mcast_hash_table = 0;
++	emac->dma_config = config->dma_config;
++
++	/*
++	 * Initialize the FIFO send and recv handlers to the stub handlers.
++	 * We only deal with the FIFO mode of operation since SG is not supported.
++	 * Also, there is no error handler. We try to handle as much of error as
++	 * possible and then return. No error codes also.
++	 */
++
++	emac->base_address = config->base_address;
++
++	if (big_sur_ge_config_dma(emac) == -1)
++		return -1;
++
++	err = big_sur_ge_config_fifo(emac);
++	if (err == -1)
++		return err;
++
++	/* Now, we know that the FIFO initialized successfully. So, set the ready flag */
++	emac->ready = 1;
++
++	/* Do we need a PHY reset here also. It did cause problems on some boards */
++	big_sur_ge_enet_reset(emac);
++
++	/* PHY reset code. Remove if causes a problem on the board */
++	reg_data =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_ECR_OFFSET);
++	reg_data &= ~(BIG_SUR_GE_ECR_PHY_ENABLE_MASK);
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_ECR_OFFSET,
++			 reg_data);
++	reg_data |= BIG_SUR_GE_ECR_PHY_ENABLE_MASK;
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_ECR_OFFSET,
++			 reg_data);
++
++	return 0;
++}
++
++/*******************************************************************
++ * Start the GE unit for Tx, Rx and Interrupts
++ *******************************************************************/
++static int big_sur_ge_start(big_sur_ge * emac)
++{
++	unsigned long reg_data;
++
++	/*
++	 * Basic mode of operation is polled and interrupt mode. We disable the polled
++	 * mode for good. We may use the polled mode for Rx NAPI but that does not
++	 * require all the interrupts to be disabled
++	 */
++
++	emac->polled = 0;
++
++	/*
++	 * DMA: Three modes of operation - simple, FIFO, SG. SG is surely not working
++	 * and so is kept off using the dma_sg flag. Simple and FIFO work. But, we may
++	 * not use FIFO at all. So, we enable the interrupts below
++	 */
++
++	BIG_SUR_GE_WRITE(emac->base_address + XIIF_V123B_DIER_OFFSET,
++			 BIG_SUR_GE_IPIF_FIFO_DFT_MASK |
++			 XIIF_V123B_ERROR_MASK);
++
++	BIG_SUR_GE_WRITE(emac->base_address + XIIF_V123B_IIER_OFFSET,
++			 BIG_SUR_GE_EIR_DFT_FIFO_MASK);
++
++	/* Toggle the started flag */
++	emac->started = 1;
++
++	/* Start the Tx and Rx units respectively */
++	reg_data =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_ECR_OFFSET);
++	reg_data &=
++	    ~(BIG_SUR_GE_ECR_XMIT_RESET_MASK |
++	      BIG_SUR_GE_ECR_RECV_RESET_MASK);
++	reg_data |=
++	    (BIG_SUR_GE_ECR_XMIT_ENABLE_MASK |
++	     BIG_SUR_GE_ECR_RECV_ENABLE_MASK);
++
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_ECR_OFFSET,
++			 reg_data);
++
++	return 0;
++}
++
++/**************************************************************************
++ * Stop the GE unit
++ **************************************************************************/
++static int big_sur_ge_stop(big_sur_ge * emac)
++{
++	unsigned long reg_data;
++
++	/* We assume that the device is not already stopped */
++	if (!emac->started)
++		return 0;
++
++	/* Disable the Tx and Rx unit respectively */
++	reg_data =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_ECR_OFFSET);
++	reg_data &=
++	    ~(BIG_SUR_GE_ECR_XMIT_ENABLE_MASK |
++	      BIG_SUR_GE_ECR_RECV_ENABLE_MASK);
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_ECR_OFFSET,
++			 reg_data);
++
++	/* Disable the interrupts */
++	BIG_SUR_GE_WRITE(emac->base_address + XIIF_V123B_DGIER_OFFSET, 0);
++
++	/* Toggle the started flag */
++	emac->started = 0;
++
++	return 0;
++}
++
++/************************************************************************
++ * Reset the GE MAC unit
++ *************************************************************************/
++static void big_sur_ge_enet_reset(big_sur_ge * emac)
++{
++	unsigned long reg_data;
++
++	(void) big_sur_ge_stop(emac);
++
++	BIG_SUR_GE_WRITE(emac->base_address + XIIF_V123B_RESETR_OFFSET,
++			 XIIF_V123B_RESET_MASK);
++
++	/*
++	 * For now, configure the receiver to not strip off FCS and padding since
++	 * this is not currently supported. In the future, just take the default
++	 * and provide the option for the user to change this behavior.
++	 */
++	reg_data =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_ECR_OFFSET);
++	reg_data &=
++	    ~(BIG_SUR_GE_ECR_RECV_PAD_ENABLE_MASK |
++	      BIG_SUR_GE_ECR_RECV_FCS_ENABLE_MASK);
++	reg_data &= ~(BIG_SUR_GE_ECR_RECV_STRIP_ENABLE_MASK);
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_ECR_OFFSET,
++			 reg_data);
++}
++
++/*************************************************************************
++ * Set the MAC address of the GE mac unit
++ *************************************************************************/
++static int big_sur_ge_set_mac_address(big_sur_ge * emac, unsigned char *addr)
++{
++	unsigned long mac_addr = 0;
++
++	/* Device is started and so mac address must be set */
++	if (emac->started == 1)
++		return 0;
++
++	mac_addr = ((addr[0] << 8) | addr[1]);
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_SAH_OFFSET,
++			 mac_addr);
++
++	mac_addr |= ((addr[2] << 24) | (addr[3] << 16) |
++		     (addr[4] << 8) | addr[5]);
++
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_SAL_OFFSET,
++			 mac_addr);
++
++	return 0;
++}
++
++/****************************************************************************
++ * Get the MAC address of the GE MAC unit
++ ***************************************************************************/
++static void big_sur_ge_get_mac_unit(big_sur_ge * emac, unsigned int *addr)
++{
++	unsigned long mac_addr_hi, mac_addr_lo;
++
++	mac_addr_hi =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_SAH_OFFSET);
++	mac_addr_lo =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_SAL_OFFSET);
++
++	addr[0] = (mac_addr_hi >> 8);
++	addr[1] = mac_addr_hi;
++
++	addr[2] = (mac_addr_lo >> 24);
++	addr[3] = (mac_addr_lo >> 16);
++	addr[4] = (mac_addr_lo >> 8);
++	addr[5] = mac_addr_lo;
++}
++
++/*********************************************************************************
++ * Configure the GE MAC for DMA capabilities. Not for Scatter Gather, only Simple
++ *********************************************************************************/
++static int big_sur_ge_config_dma(big_sur_ge * emac)
++{
++	if (big_sur_ge_dma_init(&emac->recv_channel, emac->base_address +
++				BIG_SUR_GE_DMA_RECV_OFFSET) == -1) {
++		printk(KERN_ERR "Could not initialize the DMA unit  \n");
++		return -1;
++	}
++
++	if (big_sur_ge_dma_init(&emac->send_channel, emac->base_address +
++				BIG_SUR_GE_DMA_SEND_OFFSET) == -1) {
++		printk(KERN_ERR "Could not initialize the DMA unit  \n");
++		return -1;
++	}
++
++	return 0;
++}
++
++/******************************************************************************
++ * Configure the FIFO for simple DMA
++ ******************************************************************************/
++static int big_sur_ge_config_fifo(big_sur_ge * emac)
++{
++	int err = 0;
++
++	err = packet_fifo_init(&emac->recv_fifo, emac->base_address +
++			       BIG_SUR_GE_PFIFO_RXREG_OFFSET,
++			       emac->base_address +
++			       BIG_SUR_GE_PFIFO_RXDATA_OFFSET);
++
++	if (err == -1) {
++		printk(KERN_ERR
++		       "Could not initialize Rx packet FIFO for Simple DMA \n");
++		return err;
++	}
++
++	err = packet_fifo_init(&emac->send_fifo, emac->base_address +
++			       BIG_SUR_GE_PFIFO_TXREG_OFFSET,
++			       emac->base_address +
++			       BIG_SUR_GE_PFIFO_TXDATA_OFFSET);
++
++	if (err == -1) {
++		printk(KERN_ERR
++		       "Could not initialize Tx packet FIFO for Simple DMA \n");
++	}
++
++	return err;
++}
++
++#define BIG_SUR_GE_NUM_INSTANCES	2
++
++
++/**********************************************************************************
++ * Look up the config of the MAC
++ **********************************************************************************/
++static big_sur_ge_config *big_sur_ge_lookup_config(unsigned int device_id)
++{
++	big_sur_ge_config *config = NULL;
++	int i = 0;
++
++	for (i = 0; i < BIG_SUR_GE_NUM_INSTANCES; i++) {
++		/* Manish : Init the config here */
++		break;
++	}
++
++	return config;
++}
++
++typedef struct {
++	unsigned long option;
++	unsigned long mask;
++} option_map;
++
++static option_map option_table[] = {
++	{BIG_SUR_GE_UNICAST_OPTION, BIG_SUR_GE_ECR_UNICAST_ENABLE_MASK},
++	{BIG_SUR_GE_BROADCAST_OPTION, BIG_SUR_GE_ECR_BROAD_ENABLE_MASK},
++	{BIG_SUR_GE_PROMISC_OPTION, BIG_SUR_GE_ECR_PROMISC_ENABLE_MASK},
++	{BIG_SUR_GE_FDUPLEX_OPTION, BIG_SUR_GE_ECR_FULL_DUPLEX_MASK},
++	{BIG_SUR_GE_LOOPBACK_OPTION, BIG_SUR_GE_ECR_LOOPBACK_MASK},
++	{BIG_SUR_GE_MULTICAST_OPTION, BIG_SUR_GE_ECR_MULTI_ENABLE_MASK},
++	{BIG_SUR_GE_FLOW_CONTROL_OPTION, BIG_SUR_GE_ECR_PAUSE_FRAME_MASK},
++	{BIG_SUR_GE_INSERT_PAD_OPTION,
++	 BIG_SUR_GE_ECR_XMIT_PAD_ENABLE_MASK},
++	{BIG_SUR_GE_INSERT_FCS_OPTION,
++	 BIG_SUR_GE_ECR_XMIT_FCS_ENABLE_MASK},
++	{BIG_SUR_GE_INSERT_ADDR_OPTION,
++	 BIG_SUR_GE_ECR_XMIT_ADDR_INSERT_MASK},
++	{BIG_SUR_GE_OVWRT_ADDR_OPTION,
++	 BIG_SUR_GE_ECR_XMIT_ADDR_OVWRT_MASK},
++	{BIG_SUR_GE_STRIP_PAD_OPTION, BIG_SUR_GE_ECR_RECV_PAD_ENABLE_MASK},
++	{BIG_SUR_GE_STRIP_FCS_OPTION, BIG_SUR_GE_ECR_RECV_FCS_ENABLE_MASK},
++	{BIG_SUR_GE_STRIP_PAD_FCS_OPTION,
++	 BIG_SUR_GE_ECR_RECV_STRIP_ENABLE_MASK}
++};
++
++#define BIG_SUR_GE_NUM_OPTIONS		(sizeof(option_table) / sizeof(option_map))
++
++/**********************************************************************
++ * Set the options for the GE
++ **********************************************************************/
++static int big_sur_ge_set_options(big_sur_ge * emac, unsigned long option_flag)
++{
++	unsigned long reg_data;
++	unsigned int index;
++
++	/* Assume that the device is stopped before calling this function */
++
++	reg_data =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_ECR_OFFSET);
++	for (index = 0; index < BIG_SUR_GE_NUM_OPTIONS; index++) {
++		if (option_flag & option_table[index].option)
++			reg_data |= option_table[index].mask;
++		else
++			reg_data &= ~(option_table[index].mask);
++
++	}
++
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_ECR_OFFSET,
++			 reg_data);
++
++	/* No polled option */
++	emac->polled = 0;
++
++	return 0;
++}
++
++/*******************************************************
++ * Get the options from the GE
++ *******************************************************/
++static unsigned long big_sur_ge_get_options(big_sur_ge * emac)
++{
++	unsigned long option_flag = 0, reg_data;
++	unsigned int index;
++
++	reg_data =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_ECR_OFFSET);
++
++	for (index = 0; index < BIG_SUR_GE_NUM_OPTIONS; index++) {
++		if (option_flag & option_table[index].option)
++			reg_data |= option_table[index].mask;
++	}
++
++	/* No polled mode */
++
++	return option_flag;
++}
++
++/********************************************************
++ * Set the Inter frame gap
++ ********************************************************/
++static int big_sur_ge_set_frame_gap(big_sur_ge * emac, int part1, int part2)
++{
++	unsigned long config;
++
++	/* Assume that the device is stopped before calling this */
++
++	config = ((part1 << BIG_SUR_GE_IFGP_PART1_SHIFT) |
++		  (part2 << BIG_SUR_GE_IFGP_PART2_SHIFT));
++
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_IFGP_OFFSET,
++			 config);
++
++	return 0;
++}
++
++/********************************************************
++ * Get the Inter frame gap
++ ********************************************************/
++static void big_sur_ge_get_frame_gap(big_sur_ge * emac, int *part1, int *part2)
++{
++	unsigned long config;
++
++	config =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_IFGP_OFFSET);
++	*part1 =
++	    ((config & BIG_SUR_GE_IFGP_PART1_SHIFT) >>
++	     BIG_SUR_GE_IFGP_PART1_SHIFT);
++	*part2 =
++	    ((config & BIG_SUR_GE_IFGP_PART2_SHIFT) >>
++	     BIG_SUR_GE_IFGP_PART2_SHIFT);
++}
++
++/*******************************************************************
++ * PHY specific functions for the MAC
++ *******************************************************************/
++#define BIG_SUR_GE_MAX_PHY_ADDR		32
++#define BIG_SUR_GE_MAX_PHY_REG		32
++
++/*******************************************************************
++ * Read the PHY reg
++ *******************************************************************/
++static int big_sur_ge_phy_read(big_sur_ge * emac, unsigned long addr,
++			unsigned long reg_num, unsigned int *data)
++{
++	unsigned long mii_control, mii_data;
++
++	if (!emac->has_mii)
++		return -1;
++
++	mii_control =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_MGTCR_OFFSET);
++	if (mii_control & BIG_SUR_GE_MGTCR_START_MASK) {
++		printk(KERN_ERR "PHY busy \n");
++		return -1;
++	}
++
++	mii_control = (addr << BIG_SUR_GE_MGTCR_PHY_ADDR_SHIFT);
++	mii_control |= (reg_num << BIG_SUR_GE_MGTCR_REG_ADDR_SHIFT);
++	mii_control |=
++	    (BIG_SUR_GE_MGTCR_RW_NOT_MASK | BIG_SUR_GE_MGTCR_START_MASK |
++	     BIG_SUR_GE_MGTCR_MII_ENABLE_MASK);
++
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_MGTCR_OFFSET,
++			 mii_control);
++
++	while (mii_control & BIG_SUR_GE_MGTCR_START_MASK)
++		if (!(mii_control & BIG_SUR_GE_MGTCR_START_MASK))
++			break;
++
++	mii_data =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_MGTDR_OFFSET);
++	*data = (unsigned int) mii_data;
++
++	return 0;
++}
++
++/**********************************************************************
++ * Write to the PHY register
++ **********************************************************************/
++static int big_sur_ge_phy_write(big_sur_ge * emac, unsigned long addr,
++			 unsigned long reg_num, unsigned int data)
++{
++	unsigned long mii_control;
++
++	if (!emac->has_mii)
++		return -1;
++
++	mii_control =
++	    BIG_SUR_GE_READ(emac->base_address + BIG_SUR_GE_MGTCR_OFFSET);
++	if (mii_control & BIG_SUR_GE_MGTCR_START_MASK) {
++		printk(KERN_ERR "PHY busy \n");
++		return -1;
++	}
++
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_MGTDR_OFFSET,
++			 (unsigned long) data);
++
++	mii_control = (addr << BIG_SUR_GE_MGTCR_PHY_ADDR_SHIFT);
++	mii_control |= (reg_num << BIG_SUR_GE_MGTCR_REG_ADDR_SHIFT);
++	mii_control |=
++	    (BIG_SUR_GE_MGTCR_START_MASK |
++	     BIG_SUR_GE_MGTCR_MII_ENABLE_MASK);
++
++	BIG_SUR_GE_WRITE(emac->base_address + BIG_SUR_GE_MGTCR_OFFSET,
++			 mii_control);
++
++	while (mii_control & BIG_SUR_GE_MGTCR_START_MASK)
++		if (!(mii_control & BIG_SUR_GE_MGTCR_START_MASK))
++			break;
++
++	return 0;
++}
++
++
++
++
++
++
++/********************************************************************
++ * The hardware dependent part of the driver begins here
++ ********************************************************************/
++
++
++/*******************************************************************
++ * Reset the GE system
++ *******************************************************************/
++static void big_sur_ge_reset(struct net_device *netdev, DUPLEX duplex)
++{
++	struct big_sur_ge_enet *lp = netdev->priv;
++	struct sk_buff *skb;
++	unsigned long options;
++	int ifcfg1, ifcfg2;
++
++	/* Stop the queue */
++	netif_stop_queue(netdev);
++
++	big_sur_ge_get_frame_gap(&lp->emac, &ifcfg1, &ifcfg2);
++	options = big_sur_ge_get_options(&lp->emac);
++	switch (duplex) {
++	case HALF_DUPLEX:
++		options &= ~(BIG_SUR_GE_FDUPLEX_OPTION);
++		break;
++
++	case FULL_DUPLEX:
++		options |= BIG_SUR_GE_FDUPLEX_OPTION;
++		break;
++
++	case UNKNOWN:
++		break;
++	}
++
++	/* There is no support for SG DMA in a 100 Mpbs NIC */
++
++	big_sur_ge_enet_reset(&lp->emac);
++
++	/* Set the necessary options for the MAC unit */
++	big_sur_ge_set_mac_address(&lp->emac, netdev->dev_addr);
++	big_sur_ge_set_frame_gap(&lp->emac, ifcfg1, ifcfg2);
++	big_sur_ge_set_options(&lp->emac, options);
++
++	(void) big_sur_ge_start(&lp->emac);
++
++	spin_lock_irq(&lp->lock);
++	skb = lp->saved_skb;
++	lp->saved_skb = NULL;
++	spin_unlock_irq(&lp->lock);
++
++	if (skb)
++		dev_kfree_skb(skb);
++
++	/* Wake the queue */
++	netif_wake_queue(netdev);
++}
++
++/********************************************************************
++ * Get the PHY status
++ *******************************************************************/
++static int big_sur_ge_get_phy_status(struct net_device *netdev,
++				     DUPLEX * duplex, int *linkup)
++{
++	struct big_sur_ge_enet *lp = netdev->priv;
++	unsigned int reg_data;
++	int err = 0;
++
++	err =
++	    big_sur_ge_phy_read(&lp->emac, lp->mii_addr, MII_BMCR,
++				&reg_data);
++	if (err == -1) {
++		printk(KERN_ERR "%s: Could not read PHY control register",
++		       netdev->name);
++		return err;
++	}
++
++	if (!(reg_data & BMCR_ANENABLE)) {
++		if (reg_data & BMCR_FULLDPLX)
++			*duplex = FULL_DUPLEX;
++		else
++			*duplex = HALF_DUPLEX;
++	} else {
++		unsigned int advertise, partner, neg;
++
++		err =
++		    big_sur_ge_phy_read(&lp->emac, lp->mii_addr,
++					MII_ADVERTISE, &advertise);
++		if (err == -1) {
++			printk(KERN_ERR
++			       "%s: Could not read PHY control register",
++			       netdev->name);
++			return err;
++		}
++
++		err =
++		    big_sur_ge_phy_read(&lp->emac, lp->mii_addr, MII_LPA,
++					&partner);
++		if (err == -1) {
++			printk(KERN_ERR
++			       "%s: Could not read PHY control register",
++			       netdev->name);
++			return err;
++		}
++
++		neg = advertise & partner & ADVERTISE_ALL;
++		if (neg & ADVERTISE_100FULL)
++			*duplex = FULL_DUPLEX;
++		else if (neg & ADVERTISE_100HALF)
++			*duplex = HALF_DUPLEX;
++		else if (neg & ADVERTISE_10FULL)
++			*duplex = FULL_DUPLEX;
++		else
++			*duplex = HALF_DUPLEX;
++
++		err =
++		    big_sur_ge_phy_read(&lp->emac, lp->mii_addr, MII_BMSR,
++					&reg_data);
++		if (err == -1) {
++			printk(KERN_ERR
++			       "%s: Could not read PHY control register",
++			       netdev->name);
++			return err;
++		}
++
++		*linkup = (reg_data & BMSR_LSTATUS) != 0;
++
++	}
++	return 0;
++}
++
++/************************************************************
++ * Poll the MII for duplex and link status
++ ***********************************************************/
++static void big_sur_ge_poll_mii(unsigned long data)
++{
++	struct net_device *netdev = (struct net_device *) data;
++	struct big_sur_ge_enet *lp = netdev->priv;
++	unsigned long options;
++	DUPLEX mac_duplex, phy_duplex;
++	int phy_carrier, netif_carrier;
++
++	if (big_sur_ge_get_phy_status(netdev, &phy_duplex, &phy_carrier) ==
++	    -1) {
++		printk(KERN_ERR "%s: Terminating link monitoring.\n",
++		       netdev->name);
++		return;
++	}
++
++	options = big_sur_ge_get_options(&lp->emac);
++	if (options & BIG_SUR_GE_FDUPLEX_OPTION)
++		mac_duplex = FULL_DUPLEX;
++	else
++		mac_duplex = HALF_DUPLEX;
++
++	if (mac_duplex != phy_duplex) {
++		disable_irq(netdev->irq);
++		big_sur_ge_reset(netdev, phy_duplex);
++		enable_irq(netdev->irq);
++	}
++
++	netif_carrier = netif_carrier_ok(netdev) != 0;
++
++	if (phy_carrier != netif_carrier) {
++		if (phy_carrier) {
++			printk(KERN_INFO "%s: Link carrier restored.\n",
++			       netdev->name);
++			netif_carrier_on(netdev);
++		} else {
++			printk(KERN_INFO "%s: Link carrier lost.\n",
++			       netdev->name);
++			netif_carrier_off(netdev);
++		}
++	}
++
++	/* Set up the timer so we'll get called again in 2 seconds. */
++	lp->phy_timer.expires = jiffies + 2 * HZ;
++	add_timer(&lp->phy_timer);
++}
++
++/**************************************************************
++ * Open the network interface
++ *************************************************************/
++static int big_sur_ge_open(struct net_device *netdev)
++{
++	struct big_sur_ge_enet *lp = netdev->priv;
++	unsigned long options;
++	DUPLEX phy_duplex, mac_duplex;
++	int phy_carrier, retval;
++
++	(void) big_sur_ge_stop(&lp->emac);
++
++	if (big_sur_ge_set_mac_address(&lp->emac, netdev->dev_addr) == -1) {
++		printk(KERN_ERR "%s: Could not set MAC address.\n",
++		       netdev->name);
++		return -EIO;
++	}
++
++	options = big_sur_ge_get_options(&lp->emac);
++
++	retval =
++	    request_irq(netdev->irq, &big_sur_ge_int_handler, 0,
++			netdev->name, netdev);
++	if (retval) {
++		printk(KERN_ERR
++		       "%s: Could not allocate interrupt %d.\n",
++		       netdev->name, netdev->irq);
++
++		return retval;
++	}
++
++	if (!
++	    (big_sur_ge_get_phy_status(netdev, &phy_duplex, &phy_carrier)))
++	{
++		if (options & BIG_SUR_GE_FDUPLEX_OPTION)
++			mac_duplex = FULL_DUPLEX;
++		else
++			mac_duplex = HALF_DUPLEX;
++
++		if (mac_duplex != phy_duplex) {
++			switch (phy_duplex) {
++			case HALF_DUPLEX:
++				options &= ~(BIG_SUR_GE_FDUPLEX_OPTION);
++				break;
++			case FULL_DUPLEX:
++				options |= BIG_SUR_GE_FDUPLEX_OPTION;
++				break;
++			case UNKNOWN:
++				break;
++			}
++
++			big_sur_ge_set_options(&lp->emac, options);
++		}
++	}
++
++	if (big_sur_ge_start(&lp->emac) == -1) {
++		printk(KERN_ERR "%s: Could not start device.\n",
++		       netdev->name);
++		free_irq(netdev->irq, netdev);
++		return -EBUSY;
++	}
++
++	netif_start_queue(netdev);
++
++	lp->phy_timer.expires = jiffies + 2 * HZ;
++	lp->phy_timer.data = (unsigned long) netdev;
++	lp->phy_timer.function = &big_sur_ge_poll_mii;
++	add_timer(&lp->phy_timer);
++
++	return 0;
++}
++
++/*********************************************************************
++ * Close the network device interface
++ *********************************************************************/
++static int big_sur_ge_close(struct net_device *netdev)
++{
++	struct big_sur_ge_enet *lp = netdev->priv;
++
++	del_timer_sync(&lp->phy_timer);
++	netif_stop_queue(netdev);
++
++	free_irq(netdev->irq, netdev);
++
++	if (big_sur_ge_stop(&lp->emac) == -1) {
++		printk(KERN_ERR "%s: Could not stop device.\n",
++		       netdev->name);
++		return -EBUSY;
++	}
++
++	return 0;
++}
++
++/*********************************************************************
++ * Get the network device stats. For now, do nothing
++ *********************************************************************/
++static struct net_device_stats *big_sur_ge_get_stats(struct net_device
++						     *netdev)
++{
++	/* Do nothing */
++	return (struct net_device_stats *) 0;
++}
++
++/********************************************************************
++ * FIFO send for a packet that needs to be transmitted
++ ********************************************************************/
++static int big_sur_ge_fifo_send(struct sk_buff *orig_skb,
++				struct net_device *netdev)
++{
++	struct big_sur_ge_enet *lp = netdev->priv;
++	struct sk_buff *new_skb;
++	unsigned int len, align;
++
++	netif_stop_queue(netdev);
++	len = orig_skb->len;
++
++	if (!(new_skb = dev_alloc_skb(len + 4))) {
++		dev_kfree_skb(orig_skb);
++		printk(KERN_ERR
++		       "%s: Could not allocate transmit buffer.\n",
++		       netdev->name);
++		netif_wake_queue(netdev);
++		return -EBUSY;
++	}
++
++	align = 4 - ((unsigned long) new_skb->data & 3);
++	if (align != 4)
++		skb_reserve(new_skb, align);
++
++	skb_put(new_skb, len);
++	memcpy(new_skb->data, orig_skb->data, len);
++
++	dev_kfree_skb(orig_skb);
++
++	lp->saved_skb = new_skb;
++	if (big_sur_ge_enet_fifo_send(&lp->emac, (u8 *) new_skb->data, len)
++	    == -1) {
++		spin_lock_irq(&lp->lock);
++		new_skb = lp->saved_skb;
++		lp->saved_skb = NULL;
++		spin_unlock_irq(&lp->lock);
++
++		dev_kfree_skb(new_skb);
++		printk(KERN_ERR "%s: Could not transmit buffer.\n",
++		       netdev->name);
++		netif_wake_queue(netdev);
++		return -EIO;
++	}
++	return 0;
++}
++
++/**********************************************************************
++ * Call the fifo send handler
++ **********************************************************************/
++static void big_sur_ge_fifo_send_handler(void *callback)
++{
++	struct net_device *netdev = (struct net_device *) callback;
++	struct big_sur_ge_enet *lp = netdev->priv;
++	struct sk_buff *skb;
++
++	spin_lock_irq(&lp->lock);
++	skb = lp->saved_skb;
++	lp->saved_skb = NULL;
++	spin_unlock_irq(&lp->lock);
++
++	if (skb)
++		dev_kfree_skb(skb);
++
++	netif_wake_queue(netdev);
++}
++
++/**********************************************************************
++ * Handle the timeout of the ethernet device
++ **********************************************************************/
++static void big_sur_ge_tx_timeout(struct net_device *netdev)
++{
++	printk
++	    ("%s: Exceeded transmit timeout of %lu ms.	Resetting mac.\n",
++	     netdev->name, TX_TIMEOUT * 1000UL / HZ);
++
++	disable_irq(netdev->irq);
++	big_sur_ge_reset(netdev, UNKNOWN);
++	enable_irq(netdev->irq);
++}
++
++/*********************************************************************
++ * When in FIFO mode, the callback function for packets received
++ *********************************************************************/
++static void big_sur_ge_fifo_recv_handler(void *callback)
++{
++	struct net_device *netdev = (struct net_device *) callback;
++	struct big_sur_ge_enet *lp = netdev->priv;
++	struct sk_buff *skb;
++	unsigned long len = BIG_SUR_GE_MAX_FRAME_SIZE;
++	unsigned int align;
++
++	if (!(skb = dev_alloc_skb(len + 4))) {
++		printk(KERN_ERR "%s: Could not allocate receive buffer.\n",
++		       netdev->name);
++		return;
++	}
++
++	align = 4 - ((unsigned long) skb->data & 3);
++	if (align != 4)
++		skb_reserve(skb, align);
++
++	if (big_sur_ge_enet_fifo_recv(&lp->emac, (u8 *) skb->data, &len) ==
++	    -1) {
++		dev_kfree_skb(skb);
++
++		printk(KERN_ERR "%s: Could not receive buffer \n",
++		       netdev->name);
++		netdev->tx_timeout = NULL;
++		big_sur_ge_reset(netdev, UNKNOWN);
++		netdev->tx_timeout = big_sur_ge_tx_timeout;
++	}
++
++	skb_put(skb, len);	/* Tell the skb how much data we got. */
++	skb->dev = netdev;	/* Fill out required meta-data. */
++	skb->protocol = eth_type_trans(skb, netdev);
++
++	netif_rx(skb);		/* Send the packet upstream. */
++}
++
++/*********************************************************************
++ * Set the Multicast Hash list
++ *********************************************************************/
++static void big_sur_ge_set_multicast_hash_list(struct net_device *netdev)
++{
++	struct big_sur_ge_enet *lp = netdev->priv;
++	unsigned long options;
++
++	disable_irq(netdev->irq);
++	local_bh_disable();
++
++	(void) big_sur_ge_stop(&lp->emac);
++	options = big_sur_ge_get_options(&lp->emac);
++	options &=
++	    ~(BIG_SUR_GE_PROMISC_OPTION | BIG_SUR_GE_MULTICAST_OPTION);
++
++	/* Do nothing for now */
++
++	(void) big_sur_ge_start(&lp->emac);
++	local_bh_enable();
++	enable_irq(netdev->irq);
++}
++
++/***********************************************************************
++ * IOCTL support
++ ***********************************************************************/
++static int big_sur_ge_ioctl(struct net_device *netdev, struct ifreq *rq,
++			    int cmd)
++{
++	struct big_sur_ge_enet *lp = netdev->priv;
++	struct mii_ioctl_data *data =
++	    (struct mii_ioctl_data *) &rq->ifr_data;
++
++	switch (cmd) {
++	case SIOCGMIIPHY:	/* Get address of MII PHY in use. */
++	case SIOCDEVPRIVATE:	/* for binary compat, remove in 2.5 */
++		data->phy_id = lp->mii_addr;
++
++	case SIOCGMIIREG:	/* Read MII PHY register. */
++	case SIOCDEVPRIVATE + 1:	/* for binary compat, remove in 2.5 */
++		if (data->phy_id > 31 || data->reg_num > 31)
++			return -ENXIO;
++
++		del_timer_sync(&lp->phy_timer);
++
++		if (big_sur_ge_phy_read(&lp->emac, data->phy_id,
++					data->reg_num,
++					&data->val_out) == -1) {
++			printk(KERN_ERR "%s: Could not read from PHY",
++			       netdev->name);
++			return -EBUSY;
++		}
++
++		lp->phy_timer.expires = jiffies + 2 * HZ;
++		add_timer(&lp->phy_timer);
++
++		return 0;
++
++	case SIOCSMIIREG:	/* Write MII PHY register. */
++	case SIOCDEVPRIVATE + 2:	/* for binary compat, remove in 2.5 */
++		if (data->phy_id > 31 || data->reg_num > 31)
++			return -ENXIO;
++
++		del_timer_sync(&lp->phy_timer);
++
++		if (big_sur_ge_phy_write
++		    (&lp->emac, data->phy_id, data->reg_num,
++		     data->val_in) == -1) {
++			printk(KERN_ERR "%s: Could not write to PHY",
++			       netdev->name);
++			return -EBUSY;
++		}
++
++		lp->phy_timer.expires = jiffies + 2 * HZ;
++		add_timer(&lp->phy_timer);
++
++		return 0;
++
++	default:
++		return -EOPNOTSUPP;
++	}
++}
++
++/*****************************************************************
++ * Get the config from the config table
++ *****************************************************************/
++static big_sur_ge_config *big_sur_ge_get_config(int index)
++{
++	/* Manish */
++	return (big_sur_ge_config *) 0;
++}
++
++/*****************************************************************
++ * Release the network device structure
++ *****************************************************************/
++static void big_sur_ge_remove_head(void)
++{
++	struct net_device *netdev;
++	struct big_sur_ge_enet *lp;
++	big_sur_ge_config *config;
++
++	spin_lock(&dev_lock);
++	netdev = dev_list;
++	lp = netdev->priv;
++
++	spin_unlock(&dev_lock);
++
++	config = big_sur_ge_get_config(lp->index);
++	iounmap((void *) config->base_address);
++	config->base_address = lp->save_base_address;
++
++	if (lp->saved_skb)
++		dev_kfree_skb(lp->saved_skb);
++	kfree(lp);
++
++	unregister_netdev(netdev);
++	kfree(netdev);
++}
++
++/*****************************************************************
++ * Initial Function to probe the network interface
++ *****************************************************************/
++static int __init big_sur_ge_probe(int index)
++{
++	static const unsigned long remap_size =
++	    BIG_SUR_GE_EMAC_0_HIGHADDR - BIG_SUR_GE_EMAC_0_BASEADDR + 1;
++	struct net_device *netdev;
++	struct big_sur_ge_enet *lp;
++	big_sur_ge_config *config;
++	unsigned int irq;
++	unsigned long maddr;
++	goto err;
++
++	switch (index) {
++	case 0:
++		irq = (31 - BIG_SUR_GE_INTC_0_EMAC_0_VEC_ID);
++		break;
++	case 1:
++		irq = (31 - BIG_SUR_GE_INTC_1_EMAC_1_VEC_ID);
++		break;
++	case 2:
++		irq = (31 - BIG_SUR_GE_INTC_2_EMAC_2_VEC_ID);
++		break;
++	default:
++		err = -ENODEV;
++		goto out;
++	}
++
++	config = big_sur_ge_get_config(index);
++	if (!config) {
++		err = -ENODEV;
++		goto out;
++	}
++
++	netdev = alloc_etherdev(sizeof(big_sur_ge_config));
++
++	if (!netdev) {
++		err = -ENOMEM;
++		goto out;
++	}
++
++	SET_MODULE_OWNER(netdev);
++
++	netdev->irq = irq;
++
++	lp = (struct big_sur_ge_enet *) netdev->priv;
++	memset(lp, 0, sizeof(struct big_sur_ge_enet));
++	spin_lock_init(&lp->lock);
++	spin_lock(&dev_lock);
++	lp->next_dev = dev_list;
++	dev_list = netdev;
++	spin_unlock(&dev_lock);
++
++	lp->save_base_address = config->base_address;
++	config->base_address =
++	    (unsigned long) ioremap(lp->save_base_address, remap_size);
++	if (!config->base_address) {
++		err = -ENOMEM;
++		goto out_unlock;
++	}
++
++	if (big_sur_ge_enet_init(&lp->emac, config->device_id) == -1) {
++		printk(KERN_ERR "%s: Could not initialize device.\n",
++		       netdev->name);
++		err = -ENODEV;
++		goto out_unmap;
++	}
++
++	/* Manish: dev_addr value */
++	memcpy(netdev->dev_addr, big_sur_mac_addr_base, 6);
++	if (big_sur_ge_set_mac_address(&lp->emac, netdev->dev_addr) == -1) {
++		printk(KERN_ERR "%s: Could not set MAC address.\n",
++		       netdev->name);
++		err = -EIO;
++		goto out_unmap;
++	}
++
++	/*
++	 * There is no Scatter Gather support but there is a Simple DMA support
++	 */
++	big_sur_ge_set_fifo_recv_handler(&lp->emac, netdev,
++					 big_sur_ge_fifo_recv_handler);
++	big_sur_ge_set_fifo_send_handler(&lp->emac, netdev,
++					 big_sur_ge_fifo_send_handler);
++	netdev->hard_start_xmit = big_sur_ge_fifo_send;
++
++	lp->mii_addr = 0xFF;
++
++	for (maddr = 0; maddr < 31; maddr++) {
++		unsigned int reg_data;
++
++		if (big_sur_ge_phy_read
++		    (&lp->emac, maddr, MII_BMCR, &reg_data) == 0) {
++			lp->mii_addr = maddr;
++			break;
++		}
++	}
++
++	if (lp->mii_addr == 0xFF) {
++		lp->mii_addr = 0;
++		printk(KERN_WARNING
++		       "%s: No PHY detected.  Assuming a PHY at address %d.\n",
++		       netdev->name, lp->mii_addr);
++	}
++
++	netdev->open = big_sur_ge_open;
++	netdev->stop = big_sur_ge_close;
++	netdev->get_stats = big_sur_ge_get_stats;	/* Does nothing */
++	netdev->do_ioctl = big_sur_ge_ioctl;
++	netdev->tx_timeout = big_sur_ge_tx_timeout;
++	netdev->watchdog_timeo = TX_TIMEOUT;
++
++	err = register_netdev(netdev))
++	if (!err)
++		goto out_unmap;
++
++	printk(KERN_INFO "%s: PMC-Sierra Big Sur Ethernet Device %d  at 0x%08X "
++	       "mapped to 0x%08X, irq=%d\n", netdev->name, index,
++	       lp->save_base_address, config->base_address, netdev->irq);
++
++	return ret;
++
++out_unmap:
++	iounmap(config->base_address);
++
++out_unlock:
++	big_sur_ge_remove_head();
++
++out:
++	return ret;
++}
++
++static int __init big_sur_ge_init(void)
++{
++	int index = 0;
++
++	while (big_sur_ge_probe(index++) == 0);
++
++	return (index > 1) ? 0 : -ENODEV;
++}
++
++static void __exit big_sur_ge_cleanup(void)
++{
++	while (dev_list)
++		big_sur_ge_remove_head();
++}
++
++module_init(big_sur_ge_init);
++module_exit(big_sur_ge_cleanup);
++
++MODULE_AUTHOR("Manish Lachwani <lachwani at pmc-sierra.com>");
++MODULE_DESCRIPTION("PMC-Sierra Big Sur Ethernet MAC Driver");
++MODULE_LICENSE("GPL");
+diff -urpNX dontdiff linux-2.6.10/drivers/net/big_sur_ge.h linux-2.6.10-mips/drivers/net/big_sur_ge.h
+--- linux-2.6.10/drivers/net/big_sur_ge.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/big_sur_ge.h	2003-12-18 22:26:20.000000000 +0100
+@@ -0,0 +1,714 @@
++/*
++ * drivers/net/big_sur_ge.h - Driver for PMC-Sierra Big Sur
++ * ethernet ports
++ *
++ * Copyright (C) 2003 PMC-Sierra Inc.
++ * Author : Manish Lachwani (lachwani at pmc-sierra.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++ *
++ */
++
++#ifndef	__BIG_SUR_GE_H__
++#define	__BIG_SUR_GE_H__
++
++#include <linux/config.h>
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/config.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++
++#define	BIG_SUR_DEVICE_NAME	"big sur"
++#define	BIG_SUR_DEVICE_DESC	"Big Sur Ethernet 10/100 MAC"
++
++#define BIG_SUR_GE_BASE			0xbb000000
++
++#define	BIG_SUR_GE_WRITE(ofs,data)	*(volatile u32 *)(BIG_SUR_GE_BASE+(ofs)) = data
++
++#define	BIG_SUR_GE_READ(ofs)		*(volatile u32 *)(BIG_SUR_GE_BASE+(ofs))
++
++/* Manish : Need to fix these defines later */
++#define	BIG_SUR_GE_EMAC_0_HIGHADDR
++#define	BIG_SUR_GE_EMAC_0_BASEADDR
++#define	BIG_SUR_GE_INTC_0_EMAC_0_VEC_ID		1
++#define	BIG_SUR_GE_INTC_1_EMAC_1_VEC_ID		2
++#define	BIG_SUR_GE_INTC_2_EMAC_2_VEC_ID		3
++#define	BIG_SUR_GE_EMAC_0_ERR_COUNT_EXIST
++#define	BIG_SUR_GE_EMAC_0_DMA_PRESENT
++#define	BIG_SUR_GE_EMAC_0_MII_EXIST
++#define	BIG_SUR_GE_OPB_ETHERNET_0_BASEADDR
++#define	BIG_SUR_GE_EMAC_0_DEVICE_ID
++#define	BIG_SUR_GE_OPB_ETHERNET_0_ERR_COUNT_EXIST
++#define	BIG_SUR_GE_OPB_ETHERNET_0_DMA_PRESENT
++#define	BIG_SUR_GE_OPB_ETHERNET_0_MII_EXIST
++#define	BIG_SUR_GE_OPB_ETHERNET_0_DEVICE_ID
++
++#define	BIG_SUR_GE_FIFO_WIDTH_BYTE_COUNT	4UL
++/* IPIF specific defines */
++#define XIIF_V123B_DISR_OFFSET     0UL  /* device interrupt status register */
++#define XIIF_V123B_DIPR_OFFSET     4UL  /* device interrupt pending register */
++#define XIIF_V123B_DIER_OFFSET     8UL  /* device interrupt enable register */
++#define XIIF_V123B_DIIR_OFFSET     24UL /* device interrupt ID register */
++#define XIIF_V123B_DGIER_OFFSET    28UL /* device global interrupt enable reg */
++#define XIIF_V123B_IISR_OFFSET     32UL /* IP interrupt status register */
++#define XIIF_V123B_IIER_OFFSET     40UL /* IP interrupt enable register */
++#define XIIF_V123B_RESETR_OFFSET   64UL /* reset register */
++#define XIIF_V123B_RESET_MASK             0xAUL
++#define	XIIF_V123B_ERROR_MASK		0x1UL
++
++/* defines */
++#define BIG_SUR_GE_UNICAST_OPTION        	0x00000001
++#define BIG_SUR_GE_BROADCAST_OPTION      	0x00000002
++#define BIG_SUR_GE_PROMISC_OPTION        	0x00000004
++#define BIG_SUR_GE_FDUPLEX_OPTION        	0x00000008
++#define BIG_SUR_GE_POLLED_OPTION         	0x00000010
++#define BIG_SUR_GE_LOOPBACK_OPTION       	0x00000020
++#define BIG_SUR_GE_FLOW_CONTROL_OPTION   	0x00000080
++#define BIG_SUR_GE_INSERT_PAD_OPTION     	0x00000100
++#define BIG_SUR_GE_INSERT_FCS_OPTION     	0x00000200
++#define BIG_SUR_GE_INSERT_ADDR_OPTION    	0x00000400
++#define BIG_SUR_GE_OVWRT_ADDR_OPTION     	0x00000800
++#define BIG_SUR_GE_STRIP_PAD_FCS_OPTION  	0x00002000
++
++/* Not Supported */
++#define BIG_SUR_GE_MULTICAST_OPTION      	0x00000040
++#define BIG_SUR_GE_FLOW_CONTROL_OPTION   	0x00000080
++#define BIG_SUR_GE_INSERT_PAD_OPTION     	0x00000100
++#define BIG_SUR_GE_INSERT_FCS_OPTION     	0x00000200
++#define BIG_SUR_GE_INSERT_ADDR_OPTION    	0x00000400
++#define BIG_SUR_GE_OVWRT_ADDR_OPTION     	0x00000800
++#define BIG_SUR_GE_STRIP_PAD_OPTION      	0x00001000
++#define BIG_SUR_GE_STRIP_FCS_OPTION     	0x00002000
++
++
++/* Defaults for Interrupt Coalescing in the SG DMA Engine */
++#define BIG_SUR_GE_SGDMA_DFT_THRESHOLD     1   /* Default pkt threshold */
++#define BIG_SUR_GE_SGDMA_MAX_THRESHOLD     255 /* Maximum pkt theshold */
++#define BIG_SUR_GE_SGDMA_DFT_WAITBOUND     5   /* Default pkt wait bound (msec) */
++#define BIG_SUR_GE_SGDMA_MAX_WAITBOUND     1023        /* Maximum pkt wait bound (msec) */
++
++/* Direction */
++#define BIG_SUR_GE_SEND    1
++#define BIG_SUR_GE_RECV    2
++
++/* SG DMA */
++#define BIG_SUR_GE_SGDMA_NODELAY     0 /* start SG DMA immediately */
++#define BIG_SUR_GE_SGDMA_DELAY       1 /* do not start SG DMA */
++
++#define BIG_SUR_GE_CFG_NO_IPIF             0   /* Not supported by the driver */
++#define BIG_SUR_GE_CFG_NO_DMA              1   /* No DMA */
++#define BIG_SUR_GE_CFG_SIMPLE_DMA          2   /* Simple DMA */
++#define BIG_SUR_GE_CFG_DMA_SG              3   /* DMA scatter gather */
++
++#define BIG_SUR_GE_MAC_ADDR_SIZE   6   /* six-byte MAC address */
++#define BIG_SUR_GE_MTU             1500        /* max size of Ethernet frame */
++#define BIG_SUR_GE_HDR_SIZE        14  /* size of Ethernet header */
++#define BIG_SUR_GE_HDR_VLAN_SIZE   18  /* size of Ethernet header with VLAN */
++#define BIG_SUR_GE_TRL_SIZE        4   /* size of Ethernet trailer (FCS) */
++#define BIG_SUR_GE_MAX_FRAME_SIZE  \
++		(BIG_SUR_GE_MTU + BIG_SUR_GE_HDR_SIZE + BIG_SUR_GE_TRL_SIZE)
++
++#define BIG_SUR_GE_MAX_VLAN_FRAME_SIZE  \
++		(BIG_SUR_GE_MTU + BIG_SUR_GE_HDR_VLAN_SIZE + BIG_SUR_GE_TRL_SIZE)
++
++/* Send and Receive buffers */
++#define BIG_SUR_GE_MIN_RECV_BUFS   32  /* minimum # of recv buffers */
++#define BIG_SUR_GE_DFT_RECV_BUFS   64  /* default # of recv buffers */
++
++#define BIG_SUR_GE_MIN_SEND_BUFS   16  /* minimum # of send buffers */
++#define BIG_SUR_GE_DFT_SEND_BUFS   32  /* default # of send buffers */
++
++#define BIG_SUR_GE_MIN_BUFFERS     (BIG_SUR_GE_MIN_RECV_BUFS + BIG_SUR_GE_MIN_SEND_BUFS)
++#define BIG_SUR_GE_DFT_BUFFERS     (BIG_SUR_GE_DFT_RECV_BUFS + BIG_SUR_GE_DFT_SEND_BUFS)
++
++/* Send and Receive Descriptors */
++#define BIG_SUR_GE_MIN_RECV_DESC   16  /* minimum # of recv descriptors */
++#define BIG_SUR_GE_DFT_RECV_DESC   32  /* default # of recv descriptors */
++
++#define BIG_SUR_GE_MIN_SEND_DESC   8   /* minimum # of send descriptors */
++#define BIG_SUR_GE_DFT_SEND_DESC   16  /* default # of send descriptors */
++
++/* FIFO Specific Defines */
++#define BIG_SUR_GE_READ_FIFO_TYPE      0       /* a read FIFO */
++#define BIG_SUR_GE_WRITE_FIFO_TYPE     1       /* a write FIFO */
++#define BIG_SUR_GE_RESET_REG_OFFSET            0UL
++#define BIG_SUR_GE_MODULE_INFO_REG_OFFSET      0UL
++#define BIG_SUR_GE_COUNT_STATUS_REG_OFFSET     4UL
++#define BIG_SUR_GE_RESET_FIFO_MASK             0x0000000A
++#define BIG_SUR_GE_COUNT_MASK                  0x0000FFFF
++#define BIG_SUR_GE_DEADLOCK_MASK               0x20000000
++#define BIG_SUR_GE_ALMOST_EMPTY_FULL_MASK      0x40000000
++#define BIG_SUR_GE_EMPTY_FULL_MASK             0x80000000
++
++#define BIG_SUR_GE_FIFO_RESET(fifo)	\
++	BIG_SUR_GE_WRITE((fifo)->reg_base_addr + BIG_SUR_GE_RESET_REG_OFFSET, BIG_SUR_GE_RESET_FIFO_MASK)
++
++#define	BIG_SUR_GE_GET_COUNT(fifo)	\
++	(BIG_SUR_GE_READ((fifo)->reg_base_addr + BIG_SUR_GE_COUNT_STATUS_REG_OFFSET) & 	\
++							BIG_SUR_GE_COUNT_MASK)
++
++#define	BIG_SUR_GE_IS_ALMOST_EMPTY(fifo)	\
++		(BIG_SUR_GE_READ(fifo->reg_base_addr + BIG_SUR_GE_COUNT_STATUS_REG_OFFSET) &	\
++							BIG_SUR_GE_ALMOST_EMPTY_FULL_MASK)
++
++#define	BIG_SUR_GE_IS_ALMOST_FULL(fifo)  \
++		(BIG_SUR_GE_READ(fifo->reg_base_addr + BIG_SUR_GE_COUNT_STATUS_REG_OFFSET) &   \
++							BIG_SUR_GE_ALMOST_EMPTY_FULL_MASK)
++
++#define BIG_SUR_GE_IS_EMPTY(fifo)  \
++		(BIG_SUR_GE_READ(fifo->reg_base_addr + BIG_SUR_GE_COUNT_STATUS_REG_OFFSET) &   \
++							BIG_SUR_GE_EMPTY_FULL_MASK)
++
++#define BIG_SUR_GE_IS_FULL(fifo)  \
++	(BIG_SUR_GE_READ(fifo->reg_base_addr + BIG_SUR_GE_COUNT_STATUS_REG_OFFSET) &   \
++							BIG_SUR_GE_EMPTY_FULL_MASK)
++
++#define	BIG_SUR_GE_IS_DEADLOCKED(fifo)	\
++	(BIG_SUR_GE_READ((fifo)->reg_base_addr + BIG_SUR_GE_COUNT_STATUS_REG_OFFSET) &   \
++							BIG_SUR_GE_DEADLOCK_MASK)
++
++/* Device Config */
++typedef struct _big_sur_ge_config {
++	u16		device_id;
++	u32		base_address;
++	u32		has_counters;
++	u32		has_sg_dma;
++	u8		dma_config;
++	u32		has_mii;
++} big_sur_ge_config;
++
++#define BIG_SUR_GE_SIZE_IN_WORDS           10
++typedef unsigned long xbuf_descriptor[BIG_SUR_GE_SIZE_IN_WORDS];
++
++/* Callback Functions */
++typedef void (*big_sur_sg_handler) (void *callback, xbuf_descriptor *desc, u32 num_desc);
++typedef	void (*big_sur_fifo_handler) (void *callback);
++typedef void (*big_sur_irq_handler) (void *instance);
++
++typedef struct _xdma_channel_tag {
++	u32			reg_base_address;
++        u32                     base_address;
++        u32                     ready;
++        xbuf_descriptor         *put_ptr;
++        xbuf_descriptor         *get_ptr;
++        xbuf_descriptor         *commit_ptr;
++        xbuf_descriptor         *last_ptr;
++
++        u32                     total_desc_count;
++        u32                     active_desc_count;
++} xdma_channel;
++
++typedef struct _packet_fifo {
++        u32             reg_base_addr;
++        u32             ready_status;
++        u32             data_base_address;
++} packet_fifo;
++
++
++/* Big Sur GE driver structure */
++typedef struct _big_sur_ge {
++	u32		base_address;
++	u32		started;
++	u32		ready;
++	u32		polled;
++	u32		dma_sg;
++
++	u8		dma_config;
++	u32		has_mii;
++	u32		has_mcast_hash_table;
++
++	/* For the FIFO and simple DMA case only */
++	packet_fifo	recv_fifo;
++	packet_fifo	send_fifo;
++
++	big_sur_fifo_handler	big_sur_ge_fifo_recv_handler;
++	big_sur_fifo_handler	big_sur_ge_fifo_send_handler;
++
++	void	*fifo_send_ref;
++	void	*fifo_recv_ref;	
++
++	/* For SG DMA only */
++	xdma_channel	recv_channel;
++	xdma_channel	send_channel;
++} big_sur_ge;
++
++/* Offset of the MAC registers from the IPIF base address */
++#define BIG_SUR_GE_REG_OFFSET     0x1100UL
++
++/*
++ * Register offsets for the Ethernet MAC. Each register is 32 bits.
++ */
++#define BIG_SUR_GE_EMIR_OFFSET   (BIG_SUR_GE_REG_OFFSET + 0x0)        /* EMAC Module ID */
++#define BIG_SUR_GE_ECR_OFFSET    (BIG_SUR_GE_REG_OFFSET + 0x4)        /* MAC Control */
++#define BIG_SUR_GE_IFGP_OFFSET   (BIG_SUR_GE_REG_OFFSET + 0x8)        /* Interframe Gap */
++#define BIG_SUR_GE_SAH_OFFSET    (BIG_SUR_GE_REG_OFFSET + 0xC)        /* Station addr, high */
++#define BIG_SUR_GE_SAL_OFFSET    (BIG_SUR_GE_REG_OFFSET + 0x10)       /* Station addr, low */
++#define BIG_SUR_GE_MGTCR_OFFSET  (BIG_SUR_GE_REG_OFFSET + 0x14)       /* MII mgmt control */
++#define BIG_SUR_GE_MGTDR_OFFSET  (BIG_SUR_GE_REG_OFFSET + 0x18)       /* MII mgmt data */
++#define BIG_SUR_GE_RPLR_OFFSET   (BIG_SUR_GE_REG_OFFSET + 0x1C)       /* Rx packet length */
++#define BIG_SUR_GE_TPLR_OFFSET   (BIG_SUR_GE_REG_OFFSET + 0x20)       /* Tx packet length */
++#define BIG_SUR_GE_TSR_OFFSET    (BIG_SUR_GE_REG_OFFSET + 0x24)       /* Tx status */
++#define BIG_SUR_GE_RMFC_OFFSET   (BIG_SUR_GE_REG_OFFSET + 0x28)       /* Rx missed frames */
++#define BIG_SUR_GE_RCC_OFFSET    (BIG_SUR_GE_REG_OFFSET + 0x2C)       /* Rx collisions */
++#define BIG_SUR_GE_RFCSEC_OFFSET (BIG_SUR_GE_REG_OFFSET + 0x30)       /* Rx FCS errors */
++#define BIG_SUR_GE_RAEC_OFFSET   (BIG_SUR_GE_REG_OFFSET + 0x34)       /* Rx alignment errors */
++#define BIG_SUR_GE_TEDC_OFFSET   (BIG_SUR_GE_REG_OFFSET + 0x38)       /* Transmit excess
++                                                         * deferral cnt */
++/*
++ * Register offsets for the IPIF components
++ */
++#define BIG_SUR_GE_ISR_OFFSET           0x20UL /* Interrupt status */
++
++#define BIG_SUR_GE_DMA_OFFSET           0x2300UL
++#define BIG_SUR_GE_DMA_SEND_OFFSET      (BIG_SUR_GE_DMA_OFFSET + 0x0) /* DMA send channel */
++#define BIG_SUR_GE_DMA_RECV_OFFSET      (BIG_SUR_GE_DMA_OFFSET + 0x40)        /* DMA recv channel */
++
++#define BIG_SUR_GE_PFIFO_OFFSET         0x2000UL
++#define BIG_SUR_GE_PFIFO_TXREG_OFFSET   (BIG_SUR_GE_PFIFO_OFFSET + 0x0)       /* Tx registers */
++#define BIG_SUR_GE_PFIFO_RXREG_OFFSET   (BIG_SUR_GE_PFIFO_OFFSET + 0x10)      /* Rx registers */
++#define BIG_SUR_GE_PFIFO_TXDATA_OFFSET  (BIG_SUR_GE_PFIFO_OFFSET + 0x100)     /* Tx keyhole */
++#define BIG_SUR_GE_PFIFO_RXDATA_OFFSET  (BIG_SUR_GE_PFIFO_OFFSET + 0x200)     /* Rx keyhole */
++
++/*
++ * EMAC Module Identification Register (EMIR)
++ */
++#define BIG_SUR_GE_EMIR_VERSION_MASK    0xFFFF0000UL   /* Device version */
++#define BIG_SUR_GE_EMIR_TYPE_MASK       0x0000FF00UL   /* Device type */
++
++/*
++ * EMAC Control Register (ECR)
++ */
++#define BIG_SUR_GE_ECR_FULL_DUPLEX_MASK         0x80000000   /* Full duplex mode */
++#define BIG_SUR_GE_ECR_XMIT_RESET_MASK          0x40000000   /* Reset transmitter */
++#define BIG_SUR_GE_ECR_XMIT_ENABLE_MASK         0x20000000   /* Enable transmitter */
++#define BIG_SUR_GE_ECR_RECV_RESET_MASK          0x10000000   /* Reset receiver */
++#define BIG_SUR_GE_ECR_RECV_ENABLE_MASK         0x08000000   /* Enable receiver */
++#define BIG_SUR_GE_ECR_PHY_ENABLE_MASK          0x04000000   /* Enable PHY */
++#define BIG_SUR_GE_ECR_XMIT_PAD_ENABLE_MASK     0x02000000   /* Enable xmit pad insert */
++#define BIG_SUR_GE_ECR_XMIT_FCS_ENABLE_MASK     0x01000000   /* Enable xmit FCS insert */
++#define BIG_SUR_GE_ECR_XMIT_ADDR_INSERT_MASK    0x00800000   /* Enable xmit source addr insertion */
++#define BIG_SUR_GE_ECR_XMIT_ERROR_INSERT_MASK   0x00400000   /* Insert xmit error */
++#define BIG_SUR_GE_ECR_XMIT_ADDR_OVWRT_MASK     0x00200000   /* Enable xmit source addr overwrite */
++#define BIG_SUR_GE_ECR_LOOPBACK_MASK            0x00100000   /* Enable internal loopback */
++#define BIG_SUR_GE_ECR_RECV_PAD_ENABLE_MASK     0x00080000   /* Enable recv pad strip */
++#define BIG_SUR_GE_ECR_RECV_FCS_ENABLE_MASK     0x00040000   /* Enable recv FCS strip */
++#define BIG_SUR_GE_ECR_RECV_STRIP_ENABLE_MASK   0x00080000   /* Enable recv pad/fcs strip */
++#define BIG_SUR_GE_ECR_UNICAST_ENABLE_MASK      0x00020000   /* Enable unicast addr */
++#define BIG_SUR_GE_ECR_MULTI_ENABLE_MASK        0x00010000   /* Enable multicast addr */
++#define BIG_SUR_GE_ECR_BROAD_ENABLE_MASK        0x00008000   /* Enable broadcast addr */
++#define BIG_SUR_GE_ECR_PROMISC_ENABLE_MASK      0x00004000   /* Enable promiscuous mode */
++#define BIG_SUR_GE_ECR_RECV_ALL_MASK            0x00002000   /* Receive all frames */
++#define BIG_SUR_GE_ECR_RESERVED2_MASK           0x00001000   /* Reserved */
++#define BIG_SUR_GE_ECR_MULTI_HASH_ENABLE_MASK   0x00000800   /* Enable multicast hash */
++#define BIG_SUR_GE_ECR_PAUSE_FRAME_MASK         0x00000400   /* Interpret pause frames */
++#define BIG_SUR_GE_ECR_CLEAR_HASH_MASK          0x00000200   /* Clear hash table */
++#define BIG_SUR_GE_ECR_ADD_HASH_ADDR_MASK       0x00000100  /* Add hash table address */
++
++/*
++ * Interframe Gap Register (IFGR)
++ */
++#define BIG_SUR_GE_IFGP_PART1_MASK         0xF8000000        /* Interframe Gap Part1 */
++#define BIG_SUR_GE_IFGP_PART1_SHIFT        27
++#define BIG_SUR_GE_IFGP_PART2_MASK         0x07C00000        /* Interframe Gap Part2 */
++#define BIG_SUR_GE_IFGP_PART2_SHIFT        22
++
++/*
++ * Station Address High Register (SAH)
++ */
++#define BIG_SUR_GE_SAH_ADDR_MASK           0x0000FFFF        /* Station address high bytes */
++
++/*
++ * Station Address Low Register (SAL)
++ */
++#define BIG_SUR_GE_SAL_ADDR_MASK           0xFFFFFFFF        /* Station address low bytes */
++
++/*
++ * MII Management Control Register (MGTCR)
++ */
++#define BIG_SUR_GE_MGTCR_START_MASK        0x80000000        /* Start/Busy */
++#define BIG_SUR_GE_MGTCR_RW_NOT_MASK       0x40000000        /* Read/Write Not (direction) */
++#define BIG_SUR_GE_MGTCR_PHY_ADDR_MASK     0x3E000000        /* PHY address */
++#define BIG_SUR_GE_MGTCR_PHY_ADDR_SHIFT    25  /* PHY address shift */
++#define BIG_SUR_GE_MGTCR_REG_ADDR_MASK     0x01F00000        /* Register address */
++#define BIG_SUR_GE_MGTCR_REG_ADDR_SHIFT    20  /* Register addr shift */
++#define BIG_SUR_GE_MGTCR_MII_ENABLE_MASK   0x00080000        /* Enable MII from EMAC */
++#define BIG_SUR_GE_MGTCR_RD_ERROR_MASK     0x00040000        /* MII mgmt read error */
++
++/*
++ * MII Management Data Register (MGTDR)
++ */
++#define BIG_SUR_GE_MGTDR_DATA_MASK         0x0000FFFF        /* MII data */
++
++/*
++ * Receive Packet Length Register (RPLR)
++ */
++#define BIG_SUR_GE_RPLR_LENGTH_MASK        0x0000FFFF        /* Receive packet length */
++
++/*
++ * Transmit Packet Length Register (TPLR)
++ */
++#define BIG_SUR_GE_TPLR_LENGTH_MASK        0x0000FFFF       /* Transmit packet length */
++
++/*
++ * Transmit Status Register (TSR)
++ */
++#define BIG_SUR_GE_TSR_EXCESS_DEFERRAL_MASK 0x80000000       /* Transmit excess deferral */
++#define BIG_SUR_GE_TSR_FIFO_UNDERRUN_MASK   0x40000000       /* Packet FIFO underrun */
++#define BIG_SUR_GE_TSR_ATTEMPTS_MASK        0x3E000000      /* Transmission attempts */
++#define BIG_SUR_GE_TSR_LATE_COLLISION_MASK  0x01000000      /* Transmit late collision */
++
++/*
++ * Receive Missed Frame Count (RMFC)
++ */
++#define BIG_SUR_GE_RMFC_DATA_MASK          0x0000FFFF
++
++/*
++ * Receive Collision Count (RCC)
++ */
++#define BIG_SUR_GE_RCC_DATA_MASK           0x0000FFFF
++/*
++ * Receive FCS Error Count (RFCSEC)
++ */
++#define BIG_SUR_GE_RFCSEC_DATA_MASK        0x0000FFFF
++
++/*
++ * Receive Alignment Error Count (RALN)
++ */
++#define BIG_SUR_GE_RAEC_DATA_MASK          0x0000FFFF
++
++/*
++ * Transmit Excess Deferral Count (TEDC)
++ */
++#define BIG_SUR_GE_TEDC_DATA_MASK          0x0000FFFF
++
++/*
++ * EMAC Interrupt Registers (Status and Enable) masks. These registers are
++ * part of the IPIF IP Interrupt registers
++ */
++#define BIG_SUR_GE_EIR_XMIT_DONE_MASK         0x00000001     /* Xmit complete */
++#define BIG_SUR_GE_EIR_RECV_DONE_MASK         0x00000002     /* Recv complete */
++#define BIG_SUR_GE_EIR_XMIT_ERROR_MASK        0x00000004     /* Xmit error */
++#define BIG_SUR_GE_EIR_RECV_ERROR_MASK        0x00000008     /* Recv error */
++#define BIG_SUR_GE_EIR_XMIT_SFIFO_EMPTY_MASK  0x00000010     /* Xmit status fifo empty */
++#define BIG_SUR_GE_EIR_RECV_LFIFO_EMPTY_MASK  0x00000020     /* Recv length fifo empty */
++#define BIG_SUR_GE_EIR_XMIT_LFIFO_FULL_MASK   0x00000040     /* Xmit length fifo full */
++#define BIG_SUR_GE_EIR_RECV_LFIFO_OVER_MASK   0x00000080     /* Recv length fifo overrun */
++#define BIG_SUR_GE_EIR_RECV_LFIFO_UNDER_MASK  0x00000100     /* Recv length fifo underrun */
++#define BIG_SUR_GE_EIR_XMIT_SFIFO_OVER_MASK   0x00000200     /* Xmit status fifo overrun */
++#define BIG_SUR_GE_EIR_XMIT_SFIFO_UNDER_MASK  0x00000400     /* Transmit status fifo underrun */
++#define BIG_SUR_GE_EIR_XMIT_LFIFO_OVER_MASK   0x00000800     /* Transmit length fifo overrun */
++#define BIG_SUR_GE_EIR_XMIT_LFIFO_UNDER_MASK  0x00001000     /* Transmit length fifo underrun */
++#define BIG_SUR_GE_EIR_XMIT_PAUSE_MASK        0x00002000     /* Transmit pause pkt received */
++#define BIG_SUR_GE_EIR_RECV_DFIFO_OVER_MASK   0x00004000     /* Receive data fifo overrun */
++#define BIG_SUR_GE_EIR_RECV_MISSED_FRAME_MASK 0x00008000     /* Receive missed frame error */
++#define BIG_SUR_GE_EIR_RECV_COLLISION_MASK    0x00010000     /* Receive collision error */
++#define BIG_SUR_GE_EIR_RECV_FCS_ERROR_MASK    0x00020000     /* Receive FCS error */
++#define BIG_SUR_GE_EIR_RECV_LEN_ERROR_MASK    0x00040000     /* Receive length field error */
++#define BIG_SUR_GE_EIR_RECV_SHORT_ERROR_MASK  0x00080000     /* Receive short frame error */
++#define BIG_SUR_GE_EIR_RECV_LONG_ERROR_MASK   0x00100000     /* Receive long frame error */
++#define BIG_SUR_GE_EIR_RECV_ALIGN_ERROR_MASK  0x00200000     /* Receive alignment error */
++
++#define	BIG_SUR_GE_READ_REG(base_addr, reg_offset)	\
++		BIG_SUR_GE_READ(base_addr + reg_offset)
++
++#define	BIG_SUR_GE_WRITE_REG(base_addr, reg_offset, data)	\
++		 BIG_SUR_GE_WRITE(base_addr + reg_offset, data)
++
++#define BIG_SUR_GE_CONTROL_REG(base_addr, mask)		\
++		BIG_SUR_GE_WRITE(base_addr + BIG_SUR_GE_ECR_OFFSET, mask)
++
++/* Set the MAC Address */
++#define	big_sur_ge_set_mac(base_addr, address)					\
++{										\
++	u32	mac_addr;							\
++										\
++	mac_addr = ((address[0] << 8) | (address[1]);				\
++	BIG_SUR_GE_WRITE(base_address + BIG_SUR_GE_SAH_OFFSET, mac_address);		\
++										\
++	mac_addr = ((address[2] << 24) | (address[3] << 16) |			\
++			(address[4] << 8) | address[5]);			\
++										\
++	BIG_SUR_GE_WRITE(base_address + BIG_SUR_GE_SAL_OFFSET, mac_address);		\
++										\
++}										
++
++/* Enable the MAC unit */
++#define	big_sur_ge_mac_enable(base_address)					\
++{										\
++	u32	control;							\
++	control = BIG_SUR_GE_READ(base_address + BIG_SUR_GE_ECR_OFFSET);		\
++	control &= ~(BIG_SUR_GE_ECR_XMIT_RESET_MASK | BIG_SUR_GE_ECR_RECV_RESET_MASK);	\
++	control |= (BIG_SUR_GE_ECR_XMIT_ENABLE_MASK | BIG_SUR_GE_ECR_RECV_ENABLE_MASK);	\
++	BIG_SUR_GE_WRITE(base_address + BIG_SUR_GE_ECR_OFFSET, control);		\
++}
++
++/* Disable the MAC unit */
++#define	big_sur_ge_mac_disable(base_address)					\
++{										\
++	u32	control;							\
++	control = BIG_SUR_GE_READ(base_address + BIG_SUR_GE_ECR_OFFSET);		\
++	control &= ~(BIG_SUR_GE_ECR_XMIT_ENABLE_MASK | BIG_SUR_GE_ECR_RECV_ENABLE_MASK);	\
++	BIG_SUR_GE_WRITE(base_address + BIG_SUR_GE_ECR_OFFSET, control);		\
++}
++
++/* Check if the Tx is done */
++#define	big_sur_ge_tx_done(base_address)						\
++	(BIG_SUR_GE_READ(base_address + BIG_SUR_GE_ISR_OFFSET) & BIG_SUR_GE_EIR_XMIT_DONE_MASK)
++
++
++/* Check if Rx FIFO is empty */
++#define	big_sur_ge_rx_empty(base_address)						\
++	(!(BIG_SUR_GE_READ(base_address + BIG_SUR_GE_ISR_OFFSET) & BIG_SUR_GE_EIR_RECV_DONE_MASK))
++
++/* Reset the MAC PHY */
++#define	big_sur_ge_reset_phy(base_address)						\
++{											\
++	u32	control;								\
++	control = BIG_SUR_GE_READ(base_address + BIG_SUR_GE_ECR_OFFSET);			\
++	control &= ~(BIG_SUR_GE_ECR_PHY_ENABLE_MASK);						\
++	BIG_SUR_GE_WRITE(base_address + BIG_SUR_GE_ECR_OFFSET, control);			\
++	control |= BIG_SUR_GE_ECR_PHY_ENABLE_MASK;						\
++	BIG_SUR_GE_WRITE(base_address + BIG_SUR_GE_ECR_OFFSET, control);			\
++}
++
++/* DMA SG defines */
++#define BIG_SUR_GE_CONTROL_LAST_BD_MASK        0x02000000
++#define BIG_SUR_GE_STATUS_LAST_BD_MASK         0x10000000
++#define BIG_SUR_GE_RST_REG_OFFSET      0       /* reset register */
++#define BIG_SUR_GE_MI_REG_OFFSET       0       /* module information register */
++#define BIG_SUR_GE_DMAC_REG_OFFSET     4       /* DMA control register */
++#define BIG_SUR_GE_SA_REG_OFFSET       8       /* source address register */
++#define BIG_SUR_GE_DA_REG_OFFSET       12      /* destination address register */
++#define BIG_SUR_GE_LEN_REG_OFFSET      16      /* length register */
++#define BIG_SUR_GE_DMAS_REG_OFFSET     20      /* DMA status register */
++#define BIG_SUR_GE_BDA_REG_OFFSET      24      /* buffer descriptor address register */
++#define BIG_SUR_GE_SWCR_REG_OFFSET 28  /* software control register */
++#define BIG_SUR_GE_UPC_REG_OFFSET      32      /* unserviced packet count register */
++#define BIG_SUR_GE_PCT_REG_OFFSET      36      /* packet count threshold register */
++#define BIG_SUR_GE_PWB_REG_OFFSET      40      /* packet wait bound register */
++#define BIG_SUR_GE_IS_REG_OFFSET       44      /* interrupt status register */
++#define BIG_SUR_GE_IE_REG_OFFSET       48      /* interrupt enable register */
++
++#define BIG_SUR_GE_RESET_MASK                          0x0000000A
++
++/* Buffer Descriptor Control */
++
++#define BIG_SUR_GE_DEVICE_STATUS_OFFSET    0
++#define BIG_SUR_GE_CONTROL_OFFSET          1
++#define BIG_SUR_GE_SOURCE_OFFSET           2
++#define BIG_SUR_GE_DESTINATION_OFFSET      3
++#define BIG_SUR_GE_LENGTH_OFFSET           4
++#define BIG_SUR_GE_STATUS_OFFSET           5
++#define BIG_SUR_GE_NEXT_PTR_OFFSET         6
++#define BIG_SUR_GE_ID_OFFSET               7
++#define BIG_SUR_GE_FLAGS_OFFSET            8
++#define BIG_SUR_GE_RQSTED_LENGTH_OFFSET    9
++
++#define BIG_SUR_GE_FLAGS_LOCKED_MASK       1
++
++#define	xbuf_descriptor_init(base)				\
++{								\
++	(*((u32 *)base + BIG_SUR_GE_CONTROL_OFFSET) = 0);		\
++	(*((u32 *)base + BIG_SUR_GE_SOURCE_OFFSET) = 0);        \
++    	(*((u32 *)base + BIG_SUR_GE_DESTINATION_OFFSET) = 0);   \
++    	(*((u32 *)base + BIG_SUR_GE_LENGTH_OFFSET) = 0);        \
++    	(*((u32 *)base + BIG_SUR_GE_STATUS_OFFSET) = 0);        \
++    	(*((u32 *)base + BIG_SUR_GE_DEVICE_STATUS_OFFSET) = 0); \
++    	(*((u32 *)base + BIG_SUR_GE_NEXT_PTR_OFFSET) = 0);      \
++    	(*((u32 *)base + BIG_SUR_GE_ID_OFFSET) = 0);            \
++    	(*((u32 *)base + BIG_SUR_GE_FLAGS_OFFSET) = 0);         \
++    	(*((u32 *)base + BIG_SUR_GE_RQSTED_LENGTH_OFFSET) = 0); \
++}
++
++#define xbuf_descriptor_GetControl(base)   \
++    (u32)(*((u32 *)base + BIG_SUR_GE_CONTROL_OFFSET))
++
++#define xbuf_descriptor_SetControl(base, Control)  \
++    (*((u32 *)base + BIG_SUR_GE_CONTROL_OFFSET) = (u32)Control)
++
++#define xbuf_descriptor_IsLastControl(base) \
++    (u32)(*((u32 *)base + BIG_SUR_GE_CONTROL_OFFSET) & \
++               BIG_SUR_GE_CONTROL_LAST_BD_MASK)
++
++#define xbuf_descriptor_SetLast(base) \
++    (*((u32 *)base + BIG_SUR_GE_CONTROL_OFFSET) |= BIG_SUR_GECONTROL_LAST_BD_MASK)
++
++#define xbuf_descriptor_GetSrcAddress(base) \
++    ((u32 *)(*((u32 *)base + BIG_SUR_GE_SOURCE_OFFSET)))
++
++#define xbuf_descriptor_SetSrcAddress(base, Source) \
++    (*((u32 *)base + BIG_SUR_GE_SOURCE_OFFSET) = (u32)Source)
++
++#define xbuf_descriptor_GetDestAddress(base) \
++    ((u32 *)(*((u32 *)base + BIG_SUR_GE_DESTINATION_OFFSET)))
++
++#define xbuf_descriptor_SetDestAddress(base, Destination) \
++    (*((u32 *)base + BIG_SUR_GE_DESTINATION_OFFSET) = (u32)Destination)
++
++#define xbuf_descriptor_GetLength(base)                           \
++    (u32)(*((u32 *)base + BIG_SUR_GE_RQSTED_LENGTH_OFFSET) -    \
++              *((u32 *)base + BIG_SUR_GE_LENGTH_OFFSET))
++
++#define xbuf_descriptor_SetLength(base, Length)                       \
++{                                                                           \
++    (*((u32 *)base + BIG_SUR_GE_LENGTH_OFFSET) = (u32)(Length));    \
++    (*((u32 *)base + BIG_SUR_GE_RQSTED_LENGTH_OFFSET) = (u32)(Length));\
++}
++
++#define xbuf_descriptor_GetStatus(base)    \
++    (u32)(*((u32 *)base + BIG_SUR_GE_STATUS_OFFSET))
++
++#define xbuf_descriptor_SetStatus(base, Status)    \
++    (*((u32 *)base + BIG_SUR_GE_STATUS_OFFSET) = (u32)Status)
++
++#define xbuf_descriptor_IsLastStatus(base) \
++    (u32)(*((u32 *)base + BIG_SUR_GE_STATUS_OFFSET) & \
++               BIG_SUR_GE_STATUS_LAST_BD_MASK)
++
++#define xbuf_descriptor_GetDeviceStatus(base) \
++    ((u32)(*((u32 *)base + BIG_SUR_GE_DEVICE_STATUS_OFFSET)))
++
++#define xbuf_descriptor_SetDeviceStatus(base, Status) \
++    (*((u32 *)base + BIG_SUR_GE_DEVICE_STATUS_OFFSET) = (u32)Status)
++
++#define xbuf_descriptor_GetNextPtr(base) \
++    (xbuf_descriptor *)(*((u32 *)base + BIG_SUR_GE_NEXT_PTR_OFFSET))
++
++#define xbuf_descriptor_SetNextPtr(base, NextPtr) \
++    (*((u32 *)base + BIG_SUR_GE_NEXT_PTR_OFFSET) = (u32)NextPtr)
++
++#define xbuf_descriptor_GetId(base) \
++    (u32)(*((u32 *)base + BIG_SUR_GE_ID_OFFSET))
++
++#define xbuf_descriptor_SetId(base, Id) \
++    (*((u32 *)base + BIG_SUR_GE_ID_OFFSET) = (u32)Id)
++
++#define xbuf_descriptor_GetFlags(base) \
++    (u32)(*((u32 *)base + BIG_SUR_GE_FLAGS_OFFSET))
++
++#define xbuf_descriptor_SetFlags(base, Flags) \
++    (*((u32 *)base + BIG_SUR_GE_FLAGS_OFFSET) = (u32)Flags)
++
++#define xbuf_descriptor_Lock(base) \
++    (*((u32 *)base + BIG_SUR_GE_FLAGS_OFFSET) |= BIG_SUR_GE_FLAGS_LOCKED_MASK)
++
++#define xbuf_descriptor_Unlock(base) \
++    (*((u32 *)base + BIG_SUR_GE_FLAGS_OFFSET) &= ~BIG_SUR_GE_FLAGS_LOCKED_MASK)
++
++#define xbuf_descriptor_IsLocked(base) \
++	(*((u32 *)base + BIG_SUR_GE_FLAGS_OFFSET) & BIG_SUR_GE_FLAGS_LOCKED_MASK)
++
++#define BIG_SUR_GE_DMACR_SOURCE_INCR_MASK      0x80000000UL    /* increment source address */
++#define BIG_SUR_GE_DMACR_DEST_INCR_MASK        0x40000000UL    /* increment dest address */
++#define BIG_SUR_GE_DMACR_SOURCE_LOCAL_MASK 0x20000000UL        /* local source address */
++#define BIG_SUR_GE_DMACR_DEST_LOCAL_MASK       0x10000000UL    /* local dest address */
++#define BIG_SUR_GE_DMACR_SG_DISABLE_MASK       0x08000000UL    /* scatter gather disable */
++#define BIG_SUR_GE_DMACR_GEN_BD_INTR_MASK      0x04000000UL    /* descriptor interrupt */
++#define BIG_SUR_GE_DMACR_LAST_BD_MASK          BIG_SUR_GE_CONTROL_LAST_BD_MASK        /* last buffer */
++#define BIG_SUR_GE_DMASR_BUSY_MASK                     0x80000000UL    /* channel is busy */
++#define BIG_SUR_GE_DMASR_BUS_ERROR_MASK        0x40000000UL    /* bus error occurred */
++#define BIG_SUR_GE_DMASR_BUS_TIMEOUT_MASK      0x20000000UL    /* bus timeout occurred */
++#define BIG_SUR_GE_DMASR_LAST_BD_MASK          BIG_SUR_GE_STATUS_LAST_BD_MASK /* last buffer */
++#define BIG_SUR_GE_DMASR_SG_BUSY_MASK          0x08000000UL    /* scatter gather is busy */
++#define BIG_SUR_GE_IXR_DMA_DONE_MASK           0x1UL   /* dma operation done */
++#define BIG_SUR_GE_IXR_DMA_ERROR_MASK      0x2UL       /* dma operation error */
++#define BIG_SUR_GE_IXR_PKT_DONE_MASK       0x4UL       /* packet done */
++#define BIG_SUR_GE_IXR_PKT_THRESHOLD_MASK      0x8UL   /* packet count threshold */
++#define BIG_SUR_GE_IXR_PKT_WAIT_BOUND_MASK 0x10UL      /* packet wait bound reached */
++#define BIG_SUR_GE_IXR_SG_DISABLE_ACK_MASK 0x20UL      /* scatter gather disable
++                                                   acknowledge occurred */
++#define BIG_SUR_GEIXR_SG_END_MASK                     0x40UL  /* last buffer descriptor
++                                                           disabled scatter gather */
++#define BIG_SUR_GEIXR_BD_MASK                         0x80UL  /* buffer descriptor done */
++
++/* BD control */
++#define BIG_SUR_GE_DFT_SEND_BD_MASK    (BIG_SUR_GEDMACR_SOURCE_INCR_MASK | \
++                                 BIG_SUR_GEDMACR_DEST_LOCAL_MASK)
++#define BIG_SUR_GE_DFT_RECV_BD_MASK    (BIG_SUR_GEDMACR_DEST_INCR_MASK |  \
++                                 BIG_SUR_GEDMACR_SOURCE_LOCAL_MASK)
++
++/* Interrupts */
++#define BIG_SUR_GE_IPIF_EMAC_MASK      0x00000004UL    /* MAC interrupt */
++#define BIG_SUR_GE_IPIF_SEND_DMA_MASK  0x00000008UL    /* Send DMA interrupt */
++#define BIG_SUR_GE_IPIF_RECV_DMA_MASK  0x00000010UL    /* Receive DMA interrupt */
++#define BIG_SUR_GE_IPIF_RECV_FIFO_MASK 0x00000020UL    /* Receive FIFO interrupt */
++#define BIG_SUR_GE_IPIF_SEND_FIFO_MASK 0x00000040UL    /* Send FIFO interrupt */
++
++#define BIG_SUR_GE_IPIF_DMA_DFT_MASK   (BIG_SUR_GE_IPIF_SEND_DMA_MASK |   \
++                                 BIG_SUR_GE_IPIF_RECV_DMA_MASK |   \
++                                 BIG_SUR_GE_IPIF_EMAC_MASK |       \
++                                 BIG_SUR_GE_IPIF_SEND_FIFO_MASK |  \
++                                 BIG_SUR_GE_IPIF_RECV_FIFO_MASK)
++
++#define BIG_SUR_GE_IPIF_FIFO_DFT_MASK  (BIG_SUR_GE_IPIF_EMAC_MASK |       \
++                                 BIG_SUR_GE_IPIF_SEND_FIFO_MASK |  \
++                                 BIG_SUR_GE_IPIF_RECV_FIFO_MASK)
++
++#define BIG_SUR_GE_IPIF_DMA_DEV_INTR_COUNT   7 /* Number of interrupt sources */
++#define BIG_SUR_GE_IPIF_FIFO_DEV_INTR_COUNT  5 /* Number of interrupt sources */
++#define BIG_SUR_GE_IPIF_DEVICE_INTR_COUNT  7   /* Number of interrupt sources */
++#define BIG_SUR_GE_IPIF_IP_INTR_COUNT      22  /* Number of MAC interrupts */
++
++/* a mask for all transmit interrupts, used in polled mode */
++#define BIG_SUR_GE_EIR_XMIT_ALL_MASK   (BIG_SUR_GE_EIR_XMIT_DONE_MASK |           \
++                                 BIG_SUR_GE_EIR_XMIT_ERROR_MASK |          \
++                                 BIG_SUR_GE_EIR_XMIT_SFIFO_EMPTY_MASK |    \
++                                 BIG_SUR_GE_EIR_XMIT_LFIFO_FULL_MASK)
++
++/* a mask for all receive interrupts, used in polled mode */
++#define BIG_SUR_GE_EIR_RECV_ALL_MASK   (BIG_SUR_GE_EIR_RECV_DONE_MASK |           \
++                                 BIG_SUR_GE_EIR_RECV_ERROR_MASK |          \
++                                 BIG_SUR_GE_EIR_RECV_LFIFO_EMPTY_MASK |    \
++                                 BIG_SUR_GE_EIR_RECV_LFIFO_OVER_MASK |     \
++                                 BIG_SUR_GE_EIR_RECV_LFIFO_UNDER_MASK |    \
++                                 BIG_SUR_GE_EIR_RECV_DFIFO_OVER_MASK |     \
++                                 BIG_SUR_GE_EIR_RECV_MISSED_FRAME_MASK |   \
++                                 BIG_SUR_GE_EIR_RECV_COLLISION_MASK |      \
++                                 BIG_SUR_GE_EIR_RECV_FCS_ERROR_MASK |      \
++                                 BIG_SUR_GE_EIR_RECV_LEN_ERROR_MASK |      \
++                                 BIG_SUR_GE_EIR_RECV_SHORT_ERROR_MASK |    \
++                                 BIG_SUR_GE_EIR_RECV_LONG_ERROR_MASK |     \
++                                 BIG_SUR_GE_EIR_RECV_ALIGN_ERROR_MASK)
++
++/* a default interrupt mask for scatter-gather DMA operation */
++#define BIG_SUR_GE_EIR_DFT_SG_MASK    (BIG_SUR_GE_EIR_RECV_ERROR_MASK |           \
++                                BIG_SUR_GE_EIR_RECV_LFIFO_OVER_MASK |      \
++                                BIG_SUR_GE_EIR_RECV_LFIFO_UNDER_MASK |     \
++                                BIG_SUR_GE_EIR_XMIT_SFIFO_OVER_MASK |      \
++                                BIG_SUR_GE_EIR_XMIT_SFIFO_UNDER_MASK |     \
++                                BIG_SUR_GE_EIR_XMIT_LFIFO_OVER_MASK |      \
++                                BIG_SUR_GE_EIR_XMIT_LFIFO_UNDER_MASK |     \
++                                BIG_SUR_GE_EIR_RECV_DFIFO_OVER_MASK |      \
++                                BIG_SUR_GE_EIR_RECV_MISSED_FRAME_MASK |    \
++                                BIG_SUR_GE_EIR_RECV_COLLISION_MASK |       \
++                                BIG_SUR_GE_EIR_RECV_FCS_ERROR_MASK |       \
++                                BIG_SUR_GE_EIR_RECV_LEN_ERROR_MASK |       \
++                                BIG_SUR_GE_EIR_RECV_SHORT_ERROR_MASK |     \
++                                BIG_SUR_GE_EIR_RECV_LONG_ERROR_MASK |      \
++                                BIG_SUR_GE_EIR_RECV_ALIGN_ERROR_MASK)
++
++/* a default interrupt mask for non-DMA operation (direct FIFOs) */
++#define BIG_SUR_GE_EIR_DFT_FIFO_MASK  (BIG_SUR_GE_EIR_XMIT_DONE_MASK |            \
++                                BIG_SUR_GE_EIR_RECV_DONE_MASK |            \
++                                BIG_SUR_GE_EIR_DFT_SG_MASK)
++
++#define BIG_SUR_GE_DMA_SG_INTR_MASK    (BIG_SUR_GEIXR_DMA_ERROR_MASK  |      \
++                                 BIG_SUR_GEIXR_PKT_THRESHOLD_MASK |   \
++                                 BIG_SUR_GEIXR_PKT_WAIT_BOUND_MASK |  \
++                                 BIG_SUR_GEIXR_SG_END_MASK)
++
++#endif
+diff -urpNX dontdiff linux-2.6.10/drivers/net/declance.c linux-2.6.10-mips/drivers/net/declance.c
+--- linux-2.6.10/drivers/net/declance.c	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/declance.c	2004-10-27 02:14:31.000000000 +0200
+@@ -705,8 +705,8 @@ static void lance_dma_merr_int(const int
+ 	printk("%s: DMA error\n", dev->name);
+ }
+ 
+-static irqreturn_t
+-lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t lance_interrupt(const int irq, void *dev_id,
++				   struct pt_regs *regs)
+ {
+ 	struct net_device *dev = (struct net_device *) dev_id;
+ 	struct lance_private *lp = netdev_priv(dev);
+@@ -1260,7 +1260,7 @@ static int __init dec_lance_init(const i
+ 	return 0;
+ 
+ err_out_free_dev:
+-	kfree(dev);
++	free_netdev(dev);
+ 
+ err_out:
+ 	return ret;
+@@ -1306,6 +1306,7 @@ static void __exit dec_lance_cleanup(voi
+ 	while (root_lance_dev) {
+ 		struct net_device *dev = root_lance_dev;
+ 		struct lance_private *lp = netdev_priv(dev);
++
+ 		unregister_netdev(dev);
+ #ifdef CONFIG_TC
+ 		if (lp->slot >= 0)
+diff -urpNX dontdiff linux-2.6.10/drivers/net/gt64240eth.c linux-2.6.10-mips/drivers/net/gt64240eth.c
+--- linux-2.6.10/drivers/net/gt64240eth.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/gt64240eth.c	2004-10-27 02:14:32.000000000 +0200
+@@ -0,0 +1,1672 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2001 Patton Electronics Company
++ * Copyright (C) 2002 Momentum Computer
++ *
++ * Copyright 2000 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc.
++ *         	stevel at mvista.com or support at mvista.com
++ *
++ *  This program is free software; you can distribute 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 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.
++ *
++ * Ethernet driver for the MIPS GT96100 Advanced Communication Controller.
++ * 
++ * Modified for the Gallileo/Marvell GT-64240 Communication Controller.
++ *
++ * Support for Rx NAPI, Rx checksum offload, IOCTL and ETHTOOL added
++ * Manish Lachwani (lachwani at pmc-sierra.com) - 09/16/2003
++ *
++ * Modified for later version of Linux 2.4 kernel
++ * Manish Lachwani (lachwani at pmc-sierra.com) - 04/29/2004
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/string.h>
++#include <linux/timer.h>
++#include <linux/errno.h>
++#include <linux/in.h>
++#include <linux/ioport.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <linux/pci.h>
++#include <linux/init.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/ethtool.h>
++#include <linux/skbuff.h>
++#include <linux/delay.h>
++#include <linux/ctype.h>
++#include <linux/mii.h>
++
++#include <asm/irq.h>
++#include <asm/bitops.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++
++#define DESC_DATA_BE 1
++
++#include "gt64240eth.h"
++
++// enable this port (set hash size to 1/2K)
++//- #define PORT_CONFIG pcrHS
++#define PORT_CONFIG (pcrHS | pcrHD)
++//- #define PORT_CONFIG pcrHS |pcrPM |pcrPBF|pcrHDM
++//- GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG, pcrEN | pcrHS);
++//- GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG, pcrEN | pcrHS | pcrPM);
++//- GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG, pcrEN | pcrHS | pcrPM | 1<<pcrLPBKBit);
++
++// clear all the MIB ctr regs
++#define EXT_CONFIG_CLEAR (pcxrFCTL | pcxrFCTLen | pcxrFLP | pcxrDPLXen | pcxrPRIOrxOverride | pcxrRMIIen)
++
++/*
++ * _debug level:
++ * <= 2	none.
++ *  > 2	some warnings such as queue full, .....
++ *  > 3	lots of change-of-state messages.
++ *  > 4	EXTENSIVE data/descriptor dumps.
++ */
++
++#ifdef GT64240_DEBUG
++static int gt64240_debug = GT64240_DEBUG;
++#else
++static int gt64240_debug = 0;
++#endif
++
++static int debug = -1;
++
++#define GT64240_MSG_ENABLE	(NETIF_MSG_DRV          | \
++				NETIF_MSG_PROBE        | \
++				NETIF_MSG_LINK)
++
++
++/********************************************************/
++
++// prototypes
++static void gt64240_delay(int msec);
++static int gt64240_add_hash_entry(struct net_device *dev,
++				  unsigned char *addr);
++static void read_mib_counters(struct gt64240_private *gp);
++static void dump_MII(struct net_device *dev);
++static void dump_tx_desc(struct net_device *dev, int i);
++static void dump_rx_desc(struct net_device *dev, int i);
++static void dump_hw_addr(unsigned char *addr_str);
++static void update_stats(struct gt64240_private *gp);
++static void abort(struct net_device *dev, u32 abort_bits);
++static void hard_stop(struct net_device *dev);
++static void enable_ether_irq(struct net_device *dev);
++static void disable_ether_irq(struct net_device *dev);
++static int __init gt64240_probe1(unsigned long ioaddr, int irq, int port_num);
++static void reset_tx(struct net_device *dev);
++static void reset_rx(struct net_device *dev);
++static int gt64240_init(struct net_device *dev);
++static int gt64240_open(struct net_device *dev);
++static int gt64240_close(struct net_device *dev);
++static int gt64240_tx(struct sk_buff *skb, struct net_device *dev);
++#ifdef GT64240_NAPI
++static int gt64240_poll(struct net_device *dev, int *budget);
++static int gt64240_rx(struct net_device *dev, u32 status, int budget);
++#else
++static int gt64240_rx(struct net_device *dev, u32 status);
++#endif
++static void gt64240_tx_timeout(struct net_device *dev);
++static void gt64240_set_rx_mode(struct net_device *dev);
++static struct net_device_stats *gt64240_get_stats(struct net_device *dev);
++
++extern char *__init prom_getcmdline(void);
++extern int prom_get_mac_addrs(unsigned char
++			      station_addr[NUM_INTERFACES][6]);
++
++static char version[] __devinitdata =
++	"gt64240eth.o: version 0.1, <www.patton.com>\n";
++
++// PHY device addresses
++static u32 gt64240_phy_addr[NUM_INTERFACES] __devinitdata = { 0x8, 0x1, 0xa };
++
++// Need real Ethernet addresses -- in parse_mac_addr_options(),
++// these will be replaced by prom_get_mac_addrs() and/or prom_getcmdline().
++static unsigned char gt64240_station_addr[NUM_INTERFACES][6] = {
++	{0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
++	{0x01, 0x02, 0x03, 0x04, 0x05, 0x06},
++	{0x02, 0x03, 0x04, 0x05, 0x06, 0x07}
++};
++
++static int max_interrupt_work = 32;
++
++/*
++ * Base address and interupt of the GT64240 ethernet controllers
++ */
++static struct {
++	unsigned int port;
++	int irq;
++} gt64240_iflist[NUM_INTERFACES] = {
++	{
++	GT64240_ETH0_BASE, 8}, {
++	GT64240_ETH1_BASE, 8}, {
++	GT64240_ETH2_BASE, 8}
++};
++
++static void gt64240_delay(int ms)
++{
++	if (in_interrupt())
++		return;
++	else {
++		current->state = TASK_INTERRUPTIBLE;
++		schedule_timeout(ms * HZ / 1000);
++	}
++}
++
++unsigned char prom_mac_addr_base[6];
++
++int prom_get_mac_addrs(unsigned char station_addr[NUM_INTERFACES][6])
++{
++	memcpy(station_addr[0], prom_mac_addr_base, 6);
++	memcpy(station_addr[1], prom_mac_addr_base, 6);
++	memcpy(station_addr[2], prom_mac_addr_base, 6);
++
++	station_addr[1][5] += 1;
++	station_addr[2][5] += 2;
++
++	return 0;
++}
++
++void parse_mac_addr_options(void)
++{
++	prom_get_mac_addrs(gt64240_station_addr);
++}
++
++static int read_MII(struct net_device *dev, int phy, int reg)
++{
++	int timedout = 20;
++	u32 smir = smirOpCode | (phy << smirPhyAdBit) |
++	    (reg << smirRegAdBit);
++
++	// wait for last operation to complete
++	while ((GT64240_READ(GT64240_ETH_SMI_REG)) & smirBusy) {
++		// snooze for 1 msec and check again
++		gt64240_delay(1);
++
++		if (--timedout == 0) {
++			printk("%s: read_MII busy timeout!!\n", dev->name);
++			return -1;
++		}
++	}
++
++	GT64240_WRITE(GT64240_ETH_SMI_REG, smir);
++
++	timedout = 20;
++	// wait for read to complete
++	while (!
++	       ((smir =
++		 GT64240_READ(GT64240_ETH_SMI_REG)) & smirReadValid)) {
++		// snooze for 1 msec and check again
++		gt64240_delay(1);
++
++		if (--timedout == 0) {
++			printk("%s: read_MII timeout!!\n", dev->name);
++			return -1;
++		}
++	}
++
++	return (int) (smir & smirDataMask);
++}
++
++static void gp_get_drvinfo (struct net_device *dev, 
++				struct ethtool_drvinfo *info)
++{
++	strcpy(info->driver, "gt64260");
++	strcpy(info->version, version);
++}
++
++static int gp_get_settings(struct net_device *dev, 
++				struct ethtool_cmd *cmd)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	int rc;
++
++	spin_lock_irq(&gp->lock);
++	rc = mii_ethtool_gset(&gp->mii_if, cmd);
++	spin_unlock_irq(&gp->lock);
++	return rc;
++}
++
++static int gp_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	int rc;
++
++	spin_lock_irq(&gp->lock);
++	rc = mii_ethtool_sset(&gp->mii_if, cmd);
++	spin_unlock_irq(&gp->lock);
++	return rc;
++}
++
++static int gp_nway_reset(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	return mii_nway_restart(&gp->mii_if);
++}
++
++static u32 gp_get_link(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	return mii_link_ok(&gp->mii_if);
++}
++
++static u32 gp_get_msglevel(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	return gp->msg_enable;
++}
++
++static void gp_set_msglevel(struct net_device *dev, u32 value)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	gp->msg_enable = value;
++}
++
++static struct ethtool_ops gp_ethtool_ops = {
++	.get_drvinfo		= gp_get_drvinfo,
++	.get_settings		= gp_get_settings,
++	.set_settings		= gp_set_settings,
++	.nway_reset		= gp_nway_reset,
++	.get_link		= gp_get_link,
++	.get_msglevel		= gp_get_msglevel,
++	.set_msglevel		= gp_set_msglevel,
++};
++
++static int gt64240_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	struct mii_ioctl_data *data =
++	    (struct mii_ioctl_data *) &rq->ifr_data;
++	int retval;
++
++	if (!netif_running(dev))
++		return -EINVAL;
++
++	spin_lock_irq(&gp->lock);
++	retval = generic_mii_ioctl(&gp->mii_if, data, cmd, NULL);
++	spin_unlock_irq(&gp->lock);
++
++	return retval;
++}
++
++static void dump_tx_desc(struct net_device *dev, int i)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	gt64240_td_t *td = &gp->tx_ring[i];
++
++	printk("%s:tx[%d]: self=%p cmd=%08x, cnt=%4d. bufp=%08x, next=%08x\n",
++	       dev->name, i, td, td->cmdstat, td->byte_cnt, td->buff_ptr,
++	       td->next);
++}
++
++static void dump_rx_desc(struct net_device *dev, int i)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	gt64240_rd_t *rd = &gp->rx_ring[i];
++
++	printk("%s:rx_dsc[%d]: self=%p cst=%08x,size=%4d. cnt=%4d. "
++	       "bufp=%08x, next=%08x\n",
++	       dev->name, i, rd, rd->cmdstat, rd->buff_sz, rd->byte_cnt,
++	       rd->buff_ptr, rd->next);
++}
++
++// These routines work, just disabled to avoid compile warnings
++static void write_MII(struct net_device *dev, int phy, int reg, int data)
++{
++	u32 smir = (phy << smirPhyAdBit) | (reg << smirRegAdBit) | data;
++	int timedout = 20;
++
++	// wait for last operation to complete
++	while (GT64240_READ(GT64240_ETH_SMI_REG) & smirBusy) {
++		// snooze for 1 msec and check again
++		gt64240_delay(1);
++
++		if (--timedout == 0) {
++			printk("%s: write_MII busy timeout!!\n",
++			       dev->name);
++			return;
++		}
++	}
++
++	GT64240_WRITE(GT64240_ETH_SMI_REG, smir);
++}
++
++static void dump_MII(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	int i, val;
++
++	for (i = 0; i < 7; i++) {
++		if ((val = read_MII(dev, gp->phy_addr, i)) >= 0)
++			printk("%s: MII Reg %d=%x\n", dev->name, i, val);
++	}
++	for (i = 16; i < 21; i++) {
++		if ((val = read_MII(dev, gp->phy_addr, i)) >= 0)
++			printk("%s: MII Reg %d=%x\n", dev->name, i, val);
++	}
++}
++
++
++static void dump_hw_addr(unsigned char *addr_str)
++{
++	int i;
++	for (i = 0; i < 6; i++) {
++		printk("%2.2x", addr_str[i]);
++		printk(i < 5 ? ":" : "\n");
++	}
++}
++
++static int gt64240_add_hash_entry(struct net_device *dev,
++				  unsigned char *addr)
++{
++	static unsigned char swapped[256];
++	struct gt64240_private *gp;
++	u32 value1, value0, *entry;
++	unsigned char hash_ea[6];
++	static int flag = 0;
++	u16 hashResult;
++	int i;
++
++	if (flag == 0) {	/* Create table to swap bits in a byte  */
++		flag = 1;
++		for (i = 0; i < 256; i++) {
++			swapped[i] = (i & 0x01) << 7;
++			swapped[i] |= (i & 0x02) << 5;
++			swapped[i] |= (i & 0x04) << 3;
++			swapped[i] |= (i & 0x08) << 1;
++			swapped[i] |= (i & 0x10) >> 1;
++			swapped[i] |= (i & 0x20) >> 3;
++			swapped[i] |= (i & 0x40) >> 5;
++			swapped[i] |= (i & 0x80) >> 7;
++		}
++	}
++
++	for (i = 0; i < 6; i++) {	/* swap bits from mac to create hash mac */
++		hash_ea[i] = swapped[addr[i]];
++	}
++
++	gp = netdev_priv(dev);
++
++	/* create hash entry address    */
++	hashResult = (((hash_ea[5] >> 2) & 0x3F) << 9) & 0x7E00;
++	hashResult |= ((hash_ea[4] & 0x7F) << 2) | (hash_ea[5] & 0x03);
++	hashResult ^=
++	    ((hash_ea[3] & 0xFF) << 1) | ((hash_ea[4] >> 7) & 0x01);
++	hashResult ^= ((hash_ea[1] & 0x01) << 8) | (hash_ea[2] & 0xFF);
++
++	value0 = hteValid | hteRD;	/* Create hash table entry value */
++	value0 |= (u32) addr[0] << 3;
++	value0 |= (u32) addr[1] << 11;
++	value0 |= (u32) addr[2] << 19;
++	value0 |= ((u32) addr[3] & 0x1f) << 27;
++
++	value1 = ((u32) addr[3] >> 5) & 0x07;
++	value1 |= (u32) addr[4] << 3;
++	value1 |= (u32) addr[5] << 11;
++
++	/* Inset entry value into hash table */
++	for (i = 0; i < HASH_HOP_NUMBER; i++) {
++		entry = (u32 *) ((u32) gp->hash_table +
++				 (((u32) hashResult & 0x07ff) << 3));
++		if ((*entry & hteValid) && !(*entry & hteSkip)) {
++			hashResult += 2;	/* oops, occupied, go to next entry */
++		} else {
++#ifdef __LITTLE_ENDIAN
++			entry[1] = value1;
++			entry[0] = value0;
++#else
++			entry[0] = value1;
++			entry[1] = value0;
++#endif
++			break;
++		}
++	}
++	if (i >= HASH_HOP_NUMBER) {
++		printk("%s: gt64240_add_hash_entry expired!\n", dev->name);
++		return (-1);
++	}
++	return (0);
++}
++
++
++static void read_mib_counters(struct gt64240_private *gp)
++{
++	u32 *mib_regs = (u32 *) & gp->mib;
++	int i;
++
++	for (i = 0; i < sizeof(mib_counters_t) / sizeof(u32); i++)
++		mib_regs[i] =
++		    GT64240ETH_READ(gp,
++				    GT64240_ETH_MIB_COUNT_BASE +
++				    i * sizeof(u32));
++}
++
++
++static void update_stats(struct gt64240_private *gp)
++{
++	mib_counters_t *mib = &gp->mib;
++	struct net_device_stats *stats = &gp->stats;
++
++	read_mib_counters(gp);
++
++	stats->rx_packets = mib->totalFramesReceived;
++	stats->tx_packets = mib->framesSent;
++	stats->rx_bytes = mib->totalByteReceived;
++	stats->tx_bytes = mib->byteSent;
++	stats->rx_errors = mib->totalFramesReceived - mib->framesReceived;
++	//the tx error counters are incremented by the ISR
++	//rx_dropped incremented by gt64240_rx
++	//tx_dropped incremented by gt64240_tx
++	stats->multicast = mib->multicastFramesReceived;
++	// collisions incremented by gt64240_tx_complete
++	stats->rx_length_errors = mib->oversizeFrames + mib->fragments;
++	// The RxError condition means the Rx DMA encountered a
++	// CPU owned descriptor, which, if things are working as
++	// they should, means the Rx ring has overflowed.
++	stats->rx_over_errors = mib->macRxError;
++	stats->rx_crc_errors = mib->cRCError;
++}
++
++static void abort(struct net_device *dev, u32 abort_bits)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	int timedout = 100;	// wait up to 100 msec for hard stop to complete
++
++	if (gt64240_debug > 3)
++		printk("%s: abort\n", dev->name);
++
++	// Return if neither Rx or Tx abort bits are set
++	if (!(abort_bits & (sdcmrAR | sdcmrAT)))
++		return;
++
++	// make sure only the Rx/Tx abort bits are set
++	abort_bits &= (sdcmrAR | sdcmrAT);
++
++	spin_lock(&gp->lock);
++
++	// abort any Rx/Tx DMA immediately
++	GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM, abort_bits);
++
++	if (gt64240_debug > 3)
++		printk("%s: abort: SDMA cmd  = %x/%x\n",
++		       dev->name, abort_bits, GT64240ETH_READ(gp,
++							      GT64240_ETH_SDMA_COMM));
++
++	// wait for abort to complete
++	while ((GT64240ETH_READ(gp, GT64240_ETH_SDMA_COMM)) & abort_bits) {
++		// snooze for 20 msec and check again
++		gt64240_delay(1);
++
++		if (--timedout == 0) {
++			printk("%s: abort timeout!!\n", dev->name);
++			break;
++		}
++	}
++
++	spin_unlock(&gp->lock);
++}
++
++
++static void hard_stop(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++
++	if (gt64240_debug > 3)
++		printk("%s: hard stop\n", dev->name);
++
++	disable_ether_irq(dev);
++
++	abort(dev, sdcmrAR | sdcmrAT);
++
++	// disable port
++	GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG, 0);
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_hard_stop: Port Config=%x\n",
++		       dev->name, GT64240ETH_READ(gp,
++						  GT64240_ETH_PORT_CONFIG));
++
++}
++
++static void gt64240_tx_complete(struct net_device *dev, u32 status)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	int nextOut, cdp;
++	gt64240_td_t *td;
++	u32 cmdstat;
++
++	cdp = (GT64240ETH_READ(gp, GT64240_ETH_CURR_TX_DESC_PTR0)
++	       - gp->tx_ring_dma) / sizeof(gt64240_td_t);
++
++	if (gt64240_debug > 3) {	/*+prk17aug01 */
++		nextOut = gp->tx_next_out;
++		printk
++		    ("%s: tx_complete: TX_PTR0=0x%08x, cdp=%d. nextOut=%d.\n",
++		     dev->name, GT64240ETH_READ(gp,
++						GT64240_ETH_CURR_TX_DESC_PTR0),
++		     cdp, nextOut);
++		td = &gp->tx_ring[nextOut];
++	}
++
++/*** NEED to check and CLEAR these errors every time thru here: ***/
++	if (gt64240_debug > 2) {
++		if (GT64240_READ(COMM_UNIT_INTERRUPT_CAUSE))
++			printk
++			    ("%s: gt64240_tx_complete: CIU Cause=%08x, Mask=%08x, EAddr=%08x\n",
++			     dev->name,
++			     GT64240_READ(COMM_UNIT_INTERRUPT_CAUSE),
++			     GT64240_READ(COMM_UNIT_INTERRUPT_MASK),
++			     GT64240_READ(COMM_UNIT_ERROR_ADDRESS));
++		GT64240_WRITE(COMM_UNIT_INTERRUPT_CAUSE, 0);
++	}
++	// Continue until we reach the current descriptor pointer
++	for (nextOut = gp->tx_next_out; nextOut != cdp;
++	     nextOut = (nextOut + 1) % TX_RING_SIZE) {
++
++		if (--gp->intr_work_done == 0)
++			break;
++
++		td = &gp->tx_ring[nextOut];
++		cmdstat = td->cmdstat;
++
++		if (cmdstat & (u32) txOwn) {
++			// DMA is not finished writing descriptor???
++			// Leave and come back later to pick-up where we left off.
++			break;
++		}
++		// increment Tx error stats
++		if (cmdstat & (u32) txErrorSummary) {
++			if (gt64240_debug > 2)
++				printk
++				    ("%s: tx_complete: Tx error, cmdstat = %x\n",
++				     dev->name, cmdstat);
++			gp->stats.tx_errors++;
++			if (cmdstat & (u32) txReTxLimit)
++				gp->stats.tx_aborted_errors++;
++			if (cmdstat & (u32) txUnderrun)
++				gp->stats.tx_fifo_errors++;
++			if (cmdstat & (u32) txLateCollision)
++				gp->stats.tx_window_errors++;
++		}
++
++		if (cmdstat & (u32) txCollision)
++			gp->stats.collisions +=
++			    (unsigned long) ((cmdstat & txReTxCntMask) >>
++					     txReTxCntBit);
++
++		// Wake the queue if the ring was full
++		if (gp->tx_full) {
++			gp->tx_full = 0;
++			if (gp->last_psr & psrLink) {
++				netif_wake_queue(dev);
++			}
++		}
++		// decrement tx ring buffer count
++		if (gp->tx_count)
++			gp->tx_count--;
++
++		// free the skb
++		if (gp->tx_skbuff[nextOut]) {
++			if (gt64240_debug > 3)
++				printk
++				    ("%s: tx_complete: good Tx, skb=%p\n",
++				     dev->name, gp->tx_skbuff[nextOut]);
++			dev_kfree_skb_irq(gp->tx_skbuff[nextOut]);
++			gp->tx_skbuff[nextOut] = NULL;
++		} else {
++			printk("%s: tx_complete: no skb!\n", dev->name);
++		}
++	}
++
++	gp->tx_next_out = nextOut;
++
++	if ((status & icrTxEndLow) && gp->tx_count != 0) {
++		// we must restart the DMA
++		GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM,
++				 sdcmrERD | sdcmrTXDL);
++	}
++}
++
++static irqreturn_t gt64240_interrupt(int irq, void *dev_id,
++	struct pt_regs *regs)
++{
++	struct net_device *dev = (struct net_device *) dev_id;
++	struct gt64240_private *gp = netdev_priv(dev);
++	u32 status;
++
++	if (dev == NULL) {
++		printk("%s: isr: null dev ptr\n", dev->name);
++		return IRQ_NONE;
++	}
++
++	spin_lock(&gp->lock);
++
++	if (gt64240_debug > 3)
++		printk("%s: isr: entry\n", dev->name);
++
++	gp->intr_work_done = max_interrupt_work;
++
++	while (gp->intr_work_done > 0) {
++
++		status = GT64240ETH_READ(gp, GT64240_ETH_INT_CAUSE);
++#ifdef GT64240_NAPI
++		/* dont ack Rx interrupts */
++		if (!(status & icrRxBuffer))
++			GT64240ETH_WRITE(gp, GT64240_ETH_INT_CAUSE, 0);
++#else
++		// ACK interrupts
++		GT64240ETH_WRITE(gp, GT64240_ETH_INT_CAUSE, 0);
++#endif
++
++		if (gt64240_debug > 3)
++			printk("%s: isr: work=%d., icr=%x\n", dev->name,
++			       gp->intr_work_done, status);
++
++		if ((status & icrEtherIntSum) == 0) {
++			if (!(status &
++			      (icrTxBufferLow | icrTxBufferHigh |
++			       icrRxBuffer))) {
++				/* exit from the while() loop */
++				break;
++			}
++		}
++
++		if (status & icrMIIPhySTC) {
++			u32 psr =
++			    GT64240ETH_READ(gp, GT64240_ETH_PORT_STATUS);
++			if (gp->last_psr != psr) {
++				printk("%s: port status: 0x%08x\n",
++				       dev->name, psr);
++				printk
++				    ("%s:    %s MBit/s, %s-duplex, flow-control %s, link is %s,\n",
++				     dev->name,
++				     psr & psrSpeed ? "100" : "10",
++				     psr & psrDuplex ? "full" : "half",
++				     psr & psrFctl ? "disabled" :
++				     "enabled",
++				     psr & psrLink ? "up" : "down");
++				printk
++				    ("%s:    TxLowQ is %s, TxHighQ is %s, Transmitter is %s\n",
++				     dev->name,
++				     psr & psrTxLow ? "running" :
++				     "stopped",
++				     psr & psrTxHigh ? "running" :
++				     "stopped",
++				     psr & psrTxInProg ? "on" : "off");
++
++				if ((psr & psrLink) && !gp->tx_full &&
++				    netif_queue_stopped(dev)) {
++					printk
++					    ("%s: isr: Link up, waking queue.\n",
++					     dev->name);
++					netif_wake_queue(dev);
++				} else if (!(psr & psrLink)
++					   && !netif_queue_stopped(dev)) {
++					printk
++					    ("%s: isr: Link down, stopping queue.\n",
++					     dev->name);
++					netif_stop_queue(dev);
++				}
++
++				gp->last_psr = psr;
++			}
++		}
++
++		if (status & (icrTxBufferLow | icrTxEndLow))
++			gt64240_tx_complete(dev, status);
++
++		if (status & icrRxBuffer) {
++#ifdef GT64240_NAPI
++			if (netif_rx_schedule_prep(dev)) {
++				disable_ether_irq(dev);
++				__netif_rx_schedule(dev);
++			}
++#else
++			gt64240_rx(dev, status);
++#endif
++		}
++		// Now check TX errors (RX errors were handled in gt64240_rx)
++		if (status & icrTxErrorLow) {
++			printk("%s: isr: Tx resource error\n", dev->name);
++		}
++
++		if (status & icrTxUdr) {
++			printk("%s: isr: Tx underrun error\n", dev->name);
++		}
++	}
++
++	if (gp->intr_work_done == 0) {
++		// ACK any remaining pending interrupts
++		GT64240ETH_WRITE(gp, GT64240_ETH_INT_CAUSE, 0);
++		if (gt64240_debug > 3)
++			printk("%s: isr: hit max work\n", dev->name);
++	}
++
++	if (gt64240_debug > 3)
++		printk("%s: isr: exit, icr=%x\n",
++		       dev->name, GT64240ETH_READ(gp,
++						  GT64240_ETH_INT_CAUSE));
++
++	spin_unlock(&gp->lock);
++
++	return IRQ_HANDLED;
++}
++
++static void enable_ether_irq(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	u32 intMask;
++
++	intMask =
++	    icrTxBufferLow | icrTxEndLow | icrTxErrorLow |
++	    icrTxBufferHigh | icrTxEndHigh | icrTxErrorHigh | icrTxUdr |
++	    icrRxBuffer | icrRxOVR | icrRxError | icrMIIPhySTC |
++	    icrEtherIntSum;
++
++
++//- GT64240ETH_WRITE(gp, GT64240_ETH_INT_CAUSE, 0); /* CLEAR existing ints */
++	// unmask device interrupts:
++	GT64240ETH_WRITE(gp, GT64240_ETH_INT_MASK, intMask);
++
++	// now route ethernet interrupts to GT PCI1 (eth0 and eth1 will be
++	// sharing it).
++	intMask = MV_READ(PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH);
++	intMask |= 1 << gp->port_num;
++	MV_WRITE(PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH, intMask);
++}
++
++static void disable_ether_irq(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	u32 intMask;
++
++	intMask = MV_READ(PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH);
++	intMask &= ~(1 << gp->port_num);
++	MV_WRITE(PCI_1INTERRUPT_CAUSE_MASK_REGISTER_HIGH, intMask);
++
++	// mask all device interrupts: 
++	GT64240ETH_WRITE(gp, GT64240_ETH_INT_MASK, 0);
++}
++
++/*
++ * Probe for a GT64240 ethernet controller.
++ */
++static int __init gt64240_probe(void)
++{
++	int found = 0;
++	int i;
++
++	parse_mac_addr_options();
++
++	for (i = 0; i < NUM_INTERFACES; i++) {
++		unsigned long base_addr = gt64240_iflist[i].port;
++
++		if (check_region(base_addr, GT64240_ETH_IO_SIZE)) {
++			printk("gt64240_probe: ioaddr 0x%lx taken?\n",
++			       base_addr);
++			continue;
++		}
++
++		if (gt64240_probe1(base_addr, gt64240_iflist[i].irq, i) == 0) {
++			/*
++			 * Does not seem to be the "traditional" way folks do
++			 * this, but I want to init both eth ports if at all
++			 * possible!
++			 *
++			 * So, until I find out the "correct" way to do this:
++			 */
++			if (++found == NUM_INTERFACES)	/* That's all of them */
++				return 0;
++		}
++	}
++
++	if (found)
++		return 0;	/* as long as we found at least one! */
++
++	return -ENODEV;
++}
++
++module_init(gt64240_probe);
++
++static int __init gt64240_probe1(unsigned long ioaddr, int irq, int port_num)
++{
++	struct net_device *dev = NULL;
++	static unsigned version_printed = 0;
++	struct gt64240_private *gp = NULL;
++	int retval;
++	u32 cpuConfig;
++
++	dev = alloc_etherdev(sizeof(struct gt64240_private));
++	if (!dev)
++		return -ENOMEM;
++
++	if (irq < 0) {
++		printk
++		    ("gt64240_probe1: irq unknown - probing not supported\n");
++		return -ENODEV;
++	}
++#if 1				/* KLUDGE Alert: no check on return value: */
++	if (!request_region(ioaddr, GT64240_ETH_IO_SIZE, "gt64240eth"))
++		printk("*** request_region() failed!\n");
++#endif
++
++	cpuConfig = GT64240_READ(CPU_CONFIGURATION);
++	printk("gt64240_probe1: cpu in %s-endian mode\n",
++	       (cpuConfig & (1 << 12)) ? "little" : "big");
++
++	printk("%s: GT64240 found at ioaddr 0x%lx, irq %d.\n",
++	       dev->name, ioaddr, irq);
++
++	if (gt64240_debug && version_printed++ == 0)
++		printk("%s: %s", dev->name, version);
++
++	/* private struct aligned and zeroed by init_etherdev */
++	/* Fill in the 'dev' fields. */
++	dev->base_addr = ioaddr;
++	dev->irq = irq;
++	memcpy(dev->dev_addr, gt64240_station_addr[port_num],
++	       sizeof(dev->dev_addr));
++
++	printk("%s: HW Address ", dev->name);
++	dump_hw_addr(dev->dev_addr);
++
++	gp = dev->priv;
++
++	gp->msg_enable = (debug < 0 ? GT64240_MSG_ENABLE : debug);
++	gp->port_num = port_num;
++	gp->io_size = GT64240_ETH_IO_SIZE;
++	gp->port_offset = port_num * GT64240_ETH_IO_SIZE;
++	gp->phy_addr = gt64240_phy_addr[port_num];
++
++	printk("%s: GT64240 ethernet port %d\n", dev->name, gp->port_num);
++
++#ifdef GT64240_NAPI
++	printk("Rx NAPI supported \n");
++#endif
++
++/* MII Initialization */
++	gp->mii_if.dev = dev;
++	gp->mii_if.phy_id = dev->base_addr;
++	gp->mii_if.mdio_read = read_MII;
++	gp->mii_if.mdio_write = write_MII;
++	gp->mii_if.advertising = read_MII(dev, gp->phy_addr, MII_ADVERTISE);
++
++	// Allocate Rx and Tx descriptor rings
++	if (gp->rx_ring == NULL) {
++		// All descriptors in ring must be 16-byte aligned
++		gp->rx_ring = dma_alloc_noncoherent(NULL,
++					sizeof(gt64240_rd_t) * RX_RING_SIZE +
++					sizeof(gt64240_td_t) * TX_RING_SIZE,
++					&gp->rx_ring_dma, GFP_KERNEL);
++		if (gp->rx_ring == NULL) {
++			retval = -ENOMEM;
++			goto free_region;
++		}
++
++		gp->tx_ring = (gt64240_td_t *) (gp->rx_ring + RX_RING_SIZE);
++		gp->tx_ring_dma =
++			gp->rx_ring_dma + sizeof(gt64240_rd_t) * RX_RING_SIZE;
++	}
++	// Allocate the Rx Data Buffers
++	if (gp->rx_buff == NULL) {
++		gp->rx_buff = dma_alloc_coherent(NULL,
++				PKT_BUF_SZ * RX_RING_SIZE, &gp->rx_buff_dma,
++				GFP_KERNEL);
++		if (gp->rx_buff == NULL) {
++			dma_free_noncoherent(NULL,
++				sizeof(gt64240_rd_t) * RX_RING_SIZE +
++				sizeof(gt64240_td_t) * TX_RING_SIZE,
++				gp->rx_ring, gp->rx_ring_dma);
++			retval = -ENOMEM;
++			goto free_region;
++		}
++	}
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_probe1, rx_ring=%p, tx_ring=%p\n",
++		       dev->name, gp->rx_ring, gp->tx_ring);
++
++	// Allocate Rx Hash Table
++	if (gp->hash_table == NULL) {
++		gp->hash_table = dma_alloc_coherent(NULL,
++				RX_HASH_TABLE_SIZE, &gp->hash_table_dma,
++				GFP_KERNEL);
++		if (gp->hash_table == NULL) {
++			dma_free_noncoherent(NULL,
++				sizeof(gt64240_rd_t) * RX_RING_SIZE +
++				sizeof(gt64240_td_t) * TX_RING_SIZE,
++				gp->rx_ring, gp->rx_ring_dma);
++			dma_free_noncoherent(NULL, PKT_BUF_SZ * RX_RING_SIZE,
++				gp->rx_buff, gp->rx_buff_dma);
++			retval = -ENOMEM;
++			goto free_region;
++		}
++	}
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_probe1, hash=%p\n",
++		       dev->name, gp->hash_table);
++
++	spin_lock_init(&gp->lock);
++
++	dev->open = gt64240_open;
++	dev->hard_start_xmit = gt64240_tx;
++	dev->stop = gt64240_close;
++	dev->get_stats = gt64240_get_stats;
++	dev->do_ioctl = gt64240_ioctl;
++	dev->set_multicast_list = gt64240_set_rx_mode;
++	dev->tx_timeout = gt64240_tx_timeout;
++	dev->watchdog_timeo = GT64240ETH_TX_TIMEOUT;
++
++#ifdef GT64240_NAPI
++	dev->poll = gt64240_poll;
++	dev->weight = 64;
++#endif
++	dev->ethtool_ops = &gp_ethtool_ops;
++
++	/* Fill in the fields of the device structure with ethernet values. */
++	return 0;
++
++free_region:
++	release_region(ioaddr, gp->io_size);
++	unregister_netdev(dev);
++	free_netdev(dev);
++	printk("%s: gt64240_probe1 failed.  Returns %d\n",
++	       dev->name, retval);
++	return retval;
++}
++
++
++static void reset_tx(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	int i;
++
++	abort(dev, sdcmrAT);
++
++	for (i = 0; i < TX_RING_SIZE; i++) {
++		if (gp->tx_skbuff[i]) {
++			if (in_interrupt())
++				dev_kfree_skb_irq(gp->tx_skbuff[i]);
++			else
++				dev_kfree_skb(gp->tx_skbuff[i]);
++			gp->tx_skbuff[i] = NULL;
++		}
++//-     gp->tx_ring[i].cmdstat = 0; // CPU owns
++		gp->tx_ring[i].cmdstat =
++		    (u32) (txGenCRC | txEI | txPad | txFirst | txLast);
++		gp->tx_ring[i].byte_cnt = 0;
++		gp->tx_ring[i].buff_ptr = 0;
++		gp->tx_ring[i].next =
++		    gp->tx_ring_dma + sizeof(gt64240_td_t) * (i + 1);
++		if (gt64240_debug > 4)
++			dump_tx_desc(dev, i);
++	}
++	/* Wrap the ring. */
++	gp->tx_ring[i - 1].next = gp->tx_ring_dma;
++	if (gt64240_debug > 4)
++		dump_tx_desc(dev, i - 1);
++
++	// setup only the lowest priority TxCDP reg
++	GT64240ETH_WRITE(gp, GT64240_ETH_CURR_TX_DESC_PTR0,
++			 gp->tx_ring_dma);
++//- GT64240ETH_WRITE(gp, GT64240_ETH_CURR_TX_DESC_PTR0, 0);     /* ROLLINS */
++//- GT64240ETH_WRITE(gp, GT64240_ETH_CURR_TX_DESC_PTR0,virt_to_phys(&gp->tx_ring[0]));  /* ROLLINS */
++
++	GT64240ETH_WRITE(gp, GT64240_ETH_CURR_TX_DESC_PTR1, 0);
++
++	// init Tx indeces and pkt counter
++	gp->tx_next_in = gp->tx_next_out = 0;
++	gp->tx_count = 0;
++}
++
++static void reset_rx(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	int i;
++
++	abort(dev, sdcmrAR);
++
++	for (i = 0; i < RX_RING_SIZE; i++) {
++		gp->rx_ring[i].next =
++		    gp->rx_ring_dma + sizeof(gt64240_rd_t) * (i + 1);
++		gp->rx_ring[i].buff_ptr = gp->rx_buff_dma + i * PKT_BUF_SZ;
++		gp->rx_ring[i].buff_sz = PKT_BUF_SZ;
++		gp->rx_ring[i].byte_cnt = 0;	/* just for debug printk's */
++		// Give ownership to device, set first and last, enable interrupt
++		gp->rx_ring[i].cmdstat =
++		    (uint32_t) (rxFirst | rxLast | rxOwn | rxEI);
++		if (gt64240_debug > 4)
++			dump_rx_desc(dev, i);
++	}
++	/* Wrap the ring. */
++	gp->rx_ring[i - 1].next = gp->rx_ring_dma;
++	if (gt64240_debug > 4)
++		dump_rx_desc(dev, i - 1);
++
++	// Setup only the lowest priority RxFDP and RxCDP regs
++	for (i = 0; i < 4; i++) {
++		if (i == 0) {
++			GT64240ETH_WRITE(gp, GT64240_ETH_1ST_RX_DESC_PTR0,
++					 gp->rx_ring_dma);
++			GT64240ETH_WRITE(gp, GT64240_ETH_CURR_RX_DESC_PTR0,
++					 gp->rx_ring_dma);
++		} else {
++			GT64240ETH_WRITE(gp,
++					 GT64240_ETH_1ST_RX_DESC_PTR0 +
++					 i * 4, 0);
++			GT64240ETH_WRITE(gp,
++					 GT64240_ETH_CURR_RX_DESC_PTR0 +
++					 i * 4, 0);
++		}
++	}
++
++	// init Rx NextOut index
++	gp->rx_next_out = 0;
++}
++
++
++static int gt64240_init(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++
++	if (gt64240_debug > 3) {
++		printk("%s: gt64240_init: dev=%p\n", dev->name, dev);
++		printk("%s: gt64240_init: scs0_lo=%04x, scs0_hi=%04x\n",
++		       dev->name, GT64240_READ(0x008),
++		       GT64240_READ(0x010));
++		printk("%s: gt64240_init: scs1_lo=%04x, scs1_hi=%04x\n",
++		       dev->name, GT64240_READ(0x208),
++		       GT64240_READ(0x210));
++		printk("%s: gt64240_init: scs2_lo=%04x, scs2_hi=%04x\n",
++		       dev->name, GT64240_READ(0x018),
++		       GT64240_READ(0x020));
++		printk("%s: gt64240_init: scs3_lo=%04x, scs3_hi=%04x\n",
++		       dev->name, GT64240_READ(0x218),
++		       GT64240_READ(0x220));
++	}
++	// Stop and disable Port
++	hard_stop(dev);
++
++	GT64240_WRITE(COMM_UNIT_INTERRUPT_MASK, 0x07070777);	/*+prk21aug01 */
++	if (gt64240_debug > 2)
++		printk
++		    ("%s: gt64240_init: CIU Cause=%08x, Mask=%08x, EAddr=%08x\n",
++		     dev->name, GT64240_READ(COMM_UNIT_INTERRUPT_CAUSE),
++		     GT64240_READ(COMM_UNIT_INTERRUPT_MASK),
++		     GT64240_READ(COMM_UNIT_ERROR_ADDRESS));
++
++	// Set-up hash table
++	memset(gp->hash_table, 0, RX_HASH_TABLE_SIZE);	// clear it
++	gp->hash_mode = 0;
++	// Add a single entry to hash table - our ethernet address
++	gt64240_add_hash_entry(dev, dev->dev_addr);
++	// Set-up DMA ptr to hash table
++	GT64240ETH_WRITE(gp, GT64240_ETH_HASH_TBL_PTR, gp->hash_table_dma);
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_init: Hash Tbl Ptr=%x\n", dev->name,
++		       GT64240ETH_READ(gp, GT64240_ETH_HASH_TBL_PTR));
++
++	// Setup Tx
++	reset_tx(dev);
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_init: Curr Tx Desc Ptr0=%x\n",
++		       dev->name, GT64240ETH_READ(gp,
++						  GT64240_ETH_CURR_TX_DESC_PTR0));
++
++	// Setup Rx
++	reset_rx(dev);
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_init: 1st/Curr Rx Desc Ptr0=%x/%x\n",
++		       dev->name, GT64240ETH_READ(gp,
++						  GT64240_ETH_1ST_RX_DESC_PTR0),
++		       GT64240ETH_READ(gp, GT64240_ETH_CURR_RX_DESC_PTR0));
++
++	if (gt64240_debug > 3)
++		dump_MII(dev);
++
++	/* force a PHY reset -- self-clearing! */
++	write_MII(dev, gp->phy_addr, 0, 0x8000);
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_init: PhyAD=%x\n", dev->name,
++		       GT64240_READ(GT64240_ETH_PHY_ADDR_REG));
++
++	// setup DMA
++	// We want the Rx/Tx DMA to write/read data to/from memory in
++	// Big Endian mode. Also set DMA Burst Size to 8 64Bit words.
++#ifdef DESC_DATA_BE
++	GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_CONFIG,
++			 (0xf << sdcrRCBit) | sdcrRIFB | (3 <<
++							  sdcrBSZBit));
++#else
++	GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_CONFIG, sdcrBLMR | sdcrBLMT |
++//-                  (0xf<<sdcrRCBit) | sdcrRIFB | (3<<sdcrBSZBit));
++			 (0xf << sdcrRCBit) | sdcrRIFB | (2 <<
++							  sdcrBSZBit));
++#endif
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_init: SDMA Config=%x\n", dev->name,
++		       GT64240ETH_READ(gp, GT64240_ETH_SDMA_CONFIG));
++
++#if 0
++	// start Rx DMA
++	GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM, sdcmrERD);
++#endif
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_init: SDMA Cmd =%x\n", dev->name,
++		       GT64240ETH_READ(gp, GT64240_ETH_SDMA_COMM));
++
++#if 1
++	GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG, PORT_CONFIG);
++#endif
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_init: Port Config=%x\n", dev->name,
++		       GT64240ETH_READ(gp, GT64240_ETH_PORT_CONFIG));
++
++	/*
++	 * Disable all Type-of-Service queueing. All Rx packets will be
++	 * treated normally and will be sent to the lowest priority
++	 * queue.
++	 *
++	 * Disable flow-control for now. FIX! support flow control?
++	 */
++
++#if 1
++	// clear all the MIB ctr regs
++	GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG_EXT,
++			 EXT_CONFIG_CLEAR);
++	read_mib_counters(gp);
++	GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG_EXT,
++			 EXT_CONFIG_CLEAR | pcxrMIBclrMode);
++
++#endif
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_init: Port Config Ext=%x\n", dev->name,
++		       GT64240ETH_READ(gp, GT64240_ETH_PORT_CONFIG_EXT));
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_init: Port Command=%x\n", dev->name,
++		       GT64240ETH_READ(gp, GT64240_ETH_PORT_COMMAND));
++	GT64240ETH_WRITE(gp, GT64240_ETH_PORT_COMMAND, 0x0);
++
++	netif_start_queue(dev);
++
++	/* enable the port */
++	GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG,
++			 (PORT_CONFIG | pcrEN));
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_init: Port Config=%x\n", dev->name,
++		       GT64240ETH_READ(gp, GT64240_ETH_PORT_CONFIG));
++#if 1
++	// start Rx DMA
++	GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM, sdcmrERD);
++#endif
++
++
++	// enable interrupts
++	enable_ether_irq(dev);
++
++//---    gp->last_psr |= psrLink;   /* KLUDGE ALERT */
++
++	// we should now be receiving frames
++	return 0;
++}
++
++
++static int gt64240_open(struct net_device *dev)
++{
++	int retval;
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_open: dev=%p\n", dev->name, dev);
++
++	if ((retval = request_irq(dev->irq, &gt64240_interrupt,
++				  SA_SHIRQ, dev->name, dev))) {
++		printk("%s: unable to get IRQ %d\n", dev->name, dev->irq);
++
++		return retval;
++	}
++	// Initialize and startup the GT-64240 ethernet port
++	if ((retval = gt64240_init(dev))) {
++		printk("%s: error in gt64240_open\n", dev->name);
++		free_irq(dev->irq, dev);
++
++		return retval;
++	}
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_open: Initialization done.\n",
++		       dev->name);
++
++	return 0;
++}
++
++static int gt64240_close(struct net_device *dev)
++{
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_close: dev=%p\n", dev->name, dev);
++
++	// stop the device
++	if (netif_device_present(dev)) {
++		netif_stop_queue(dev);
++		hard_stop(dev);
++	}
++
++	free_irq(dev->irq, dev);
++
++	return 0;
++}
++
++#ifdef GT64240_NAPI
++/*
++ * Function will release Tx skbs which are now complete
++ */
++static void gt64240_tx_fill(struct net_device *dev, u32 status)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	int nextOut, cdp;
++	gt64240_td_t *td;
++	u32 cmdstat;
++
++	cdp = (GT64240ETH_READ(gp, GT64240_ETH_CURR_TX_DESC_PTR0)
++	       - gp->tx_ring_dma) / sizeof(gt64240_td_t);
++
++	for (nextOut = gp->tx_next_out; nextOut != cdp;
++	     nextOut = (nextOut + 1) % TX_RING_SIZE) {
++		if (--gp->intr_work_done == 0)
++			break;
++
++		td = &gp->tx_ring[nextOut];
++		cmdstat = td->cmdstat;
++
++		if (cmdstat & (u32) txOwn)
++			break;
++
++		if (gp->tx_full) {
++			gp->tx_full = 0;
++			if (gp->last_psr & psrLink) {
++				netif_wake_queue(dev);
++			}
++		}
++		// decrement tx ring buffer count
++		if (gp->tx_count)
++			gp->tx_count--;
++
++		// free the skb
++		if (gp->tx_skbuff[nextOut]) {
++			dev_kfree_skb_irq(gp->tx_skbuff[nextOut]);
++			gp->tx_skbuff[nextOut] = NULL;
++		}
++	}
++
++	gp->tx_next_out = nextOut;
++
++	if ((status & icrTxEndLow) && gp->tx_count != 0)
++		// we must restart the DMA
++		GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM,
++				 sdcmrERD | sdcmrTXDL);
++}
++
++/*
++ * Main function for NAPI
++ */
++static int gt64240_poll(struct net_device *dev, int *budget)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	unsigned long flags;
++	int done = 1, orig_budget, work_done;
++	u32 status = GT64240ETH_READ(gp, GT64240_ETH_INT_CAUSE);
++
++	spin_lock_irqsave(&gp->lock, flags);
++	gt64240_tx_fill(dev, status);
++
++	if (GT64240ETH_READ(gp, GT64240_ETH_CURR_RX_DESC_PTR0) !=
++	    gp->rx_next_out) {
++		orig_budget = *budget;
++		if (orig_budget > dev->quota)
++			orig_budget = dev->quota;
++
++		work_done = gt64240_rx(dev, status, orig_budget);
++		*budget -= work_done;
++		dev->quota -= work_done;
++		if (work_done >= orig_budget)
++			done = 0;
++		if (done) {
++			__netif_rx_complete(dev);
++			enable_ether_irq(dev);
++		}
++	}
++
++	spin_unlock_irqrestore(&gp->lock, flags);
++
++	return (done ? 0 : 1);
++}
++#endif
++
++static int gt64240_tx(struct sk_buff *skb, struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	unsigned long flags;
++	int nextIn;
++
++	spin_lock_irqsave(&gp->lock, flags);
++
++	nextIn = gp->tx_next_in;
++
++	if (gt64240_debug > 3) {
++		printk("%s: gt64240_tx: nextIn=%d.\n", dev->name, nextIn);
++	}
++
++	if (gp->tx_count >= TX_RING_SIZE) {
++		printk("%s: Tx Ring full, pkt dropped.\n", dev->name);
++		gp->stats.tx_dropped++;
++		spin_unlock_irqrestore(&gp->lock, flags);
++		return 1;
++	}
++
++	if (!(gp->last_psr & psrLink)) {
++		printk("%s: gt64240_tx: Link down, pkt dropped.\n",
++		       dev->name);
++		gp->stats.tx_dropped++;
++		spin_unlock_irqrestore(&gp->lock, flags);
++//---   dump_MII(dev);          /* KLUDGE ALERT !!! */
++		return 1;
++	}
++
++	if (gp->tx_ring[nextIn].cmdstat & txOwn) {
++		printk
++		    ("%s: gt64240_tx: device owns descriptor, pkt dropped.\n",
++		     dev->name);
++		gp->stats.tx_dropped++;
++		// stop the queue, so Tx timeout can fix it
++		netif_stop_queue(dev);
++		spin_unlock_irqrestore(&gp->lock, flags);
++		return 1;
++	}
++	// Prepare the Descriptor at tx_next_in
++	gp->tx_skbuff[nextIn] = skb;
++	gp->tx_ring[nextIn].byte_cnt = skb->len;
++	gp->tx_ring[nextIn].buff_ptr = virt_to_phys(skb->data);
++
++	// make sure packet gets written back to memory
++	dma_cache_wback_inv((unsigned long) (skb->data), skb->len);
++	mb();
++
++	// Give ownership to device, set first and last desc, enable interrupt
++	// Setting of ownership bit must be *last*!
++	gp->tx_ring[nextIn].cmdstat =
++	    txOwn | txGenCRC | txEI | txPad | txFirst | txLast;
++
++	if (gt64240_debug > 5) {
++		dump_tx_desc(dev, nextIn);
++	}
++	// increment tx_next_in with wrap
++	gp->tx_next_in = (nextIn + 1) % TX_RING_SIZE;
++
++//+prk20aug01:
++	if (0) {		/* ROLLINS */
++		GT64240ETH_WRITE(gp, GT64240_ETH_CURR_TX_DESC_PTR0,
++				 virt_to_phys(&gp->tx_ring[nextIn]));
++	}
++
++	if (gt64240_debug > 3) {	/*+prk17aug01 */
++		printk
++		    ("%s: gt64240_tx: TX_PTR0=0x%08x, EthPortStatus=0x%08x\n",
++		     dev->name, GT64240ETH_READ(gp,
++						GT64240_ETH_CURR_TX_DESC_PTR0),
++		     GT64240ETH_READ(gp, GT64240_ETH_PORT_STATUS));
++	}
++	// If DMA is stopped, restart
++	if (!((GT64240ETH_READ(gp, GT64240_ETH_PORT_STATUS)) & psrTxLow)) {
++		GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM,
++				 sdcmrERD | sdcmrTXDL);
++	}
++
++	if (gt64240_debug > 3) {	/*+prk17aug01 */
++		printk
++		    ("%s: gt64240_tx: TX_PTR0=0x%08x, EthPortStatus=0x%08x\n",
++		     dev->name, GT64240ETH_READ(gp,
++						GT64240_ETH_CURR_TX_DESC_PTR0),
++		     GT64240ETH_READ(gp, GT64240_ETH_PORT_STATUS));
++	}
++	// increment count and stop queue if full
++	if (++gp->tx_count >= TX_RING_SIZE) {
++		gp->tx_full = 1;
++		netif_stop_queue(dev);
++	}
++
++	dev->trans_start = jiffies;
++	spin_unlock_irqrestore(&gp->lock, flags);
++
++	return 0;
++}
++
++
++static int
++#ifdef GT64240_NAPI
++gt64240_rx(struct net_device *dev, u32 status, int budget)
++#else
++gt64240_rx(struct net_device *dev, u32 status)
++#endif
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	struct sk_buff *skb;
++	int pkt_len, nextOut, cdp;
++	gt64240_rd_t *rd;
++	u32 cmdstat;
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_rx: dev=%p, status=%x\n",
++		       dev->name, dev, status);
++
++	cdp = (GT64240ETH_READ(gp, GT64240_ETH_CURR_RX_DESC_PTR0)
++	       - gp->rx_ring_dma) / sizeof(gt64240_rd_t);
++
++	// Continue until we reach the current descriptor pointer
++	for (nextOut = gp->rx_next_out; nextOut != cdp;
++	     nextOut = (nextOut + 1) % RX_RING_SIZE) {
++
++#ifdef GT64240_NAPI
++		if (budget <= 0)
++			break;
++
++		budget--;
++#endif
++
++		if (--gp->intr_work_done == 0)
++			break;
++
++		if (gt64240_debug > 4)
++			dump_rx_desc(dev, nextOut);
++
++		rd = &gp->rx_ring[nextOut];
++		cmdstat = rd->cmdstat;
++
++		if (gt64240_debug > 3)
++			printk("%s: isr: Rx desc cmdstat=%x, nextOut=%d\n",
++			       dev->name, cmdstat, nextOut);
++
++		if (cmdstat & (u32) rxOwn) {
++			if (gt64240_debug > 2)
++				printk
++				    ("%s: gt64240_rx: device owns descriptor!\n",
++				     dev->name);
++			// DMA is not finished updating descriptor???
++			// Leave and come back later to pick-up where we left off.
++			break;
++		}
++		// must be first and last (ie only) buffer of packet
++		if (!(cmdstat & (u32) rxFirst)
++		    || !(cmdstat & (u32) rxLast)) {
++			printk
++			    ("%s: gt64240_rx: desc not first and last!\n",
++			     dev->name);
++			cmdstat |= (u32) rxOwn;
++			rd->cmdstat = cmdstat;
++			continue;
++		}
++		// Drop this received pkt if there were any errors
++		if ((cmdstat & (u32) rxErrorSummary)
++		    || (status & icrRxError)) {
++			// update the detailed rx error counters that are not covered
++			// by the MIB counters.
++			if (cmdstat & (u32) rxOverrun)
++				gp->stats.rx_fifo_errors++;
++			cmdstat |= (u32) rxOwn;
++			rd->cmdstat = cmdstat;
++			continue;
++		}
++
++		pkt_len = rd->byte_cnt;
++
++		/* Create new skb. */
++//      skb = dev_alloc_skb(pkt_len+2);
++		skb = dev_alloc_skb(1538);
++		if (skb == NULL) {
++			printk("%s: Memory squeeze, dropping packet.\n",
++			       dev->name);
++			gp->stats.rx_dropped++;
++			cmdstat |= (u32) rxOwn;
++			rd->cmdstat = cmdstat;
++			continue;
++		}
++		skb->dev = dev;
++		skb_reserve(skb, 2);	/* 16 byte IP header align */
++		memcpy(skb_put(skb, pkt_len),
++		       &gp->rx_buff[nextOut * PKT_BUF_SZ], pkt_len);
++		skb->protocol = eth_type_trans(skb, dev);
++
++		/* NIC performed some checksum computation */
++		skb->ip_summed = CHECKSUM_UNNECESSARY;
++#ifdef GT64240_NAPI
++		netif_receive_skb(skb);
++#else
++		netif_rx(skb);	/* pass the packet to upper layers */
++#endif
++
++		// now we can release ownership of this desc back to device
++		cmdstat |= (u32) rxOwn;
++		rd->cmdstat = cmdstat;
++
++		dev->last_rx = jiffies;
++	}
++
++	if (gt64240_debug > 3 && nextOut == gp->rx_next_out)
++		printk("%s: gt64240_rx: RxCDP did not increment?\n",
++		       dev->name);
++
++	gp->rx_next_out = nextOut;
++	return 0;
++}
++
++
++static void gt64240_tx_timeout(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	unsigned long flags;
++
++	spin_lock_irqsave(&gp->lock, flags);
++
++
++	if (!(gp->last_psr & psrLink)) {
++		spin_unlock_irqrestore(&gp->lock, flags);
++	} else {
++		printk("======------> gt64240_tx_timeout: %d jiffies \n",
++		       GT64240ETH_TX_TIMEOUT);
++
++		disable_ether_irq(dev);
++		spin_unlock_irqrestore(&gp->lock, flags);
++		reset_tx(dev);
++		enable_ether_irq(dev);
++
++		netif_wake_queue(dev);
++	}
++}
++
++
++static void gt64240_set_rx_mode(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	unsigned long flags;
++	struct dev_mc_list *mcptr;
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_set_rx_mode: dev=%p, flags=%x\n",
++		       dev->name, dev, dev->flags);
++
++	// stop the Receiver DMA
++	abort(dev, sdcmrAR);
++
++	spin_lock_irqsave(&gp->lock, flags);
++
++	if (dev->flags & IFF_PROMISC)
++		GT64240ETH_SETBIT(gp, GT64240_ETH_PORT_CONFIG, pcrPM);
++	else
++		GT64240ETH_CLRBIT(gp, GT64240_ETH_PORT_CONFIG, pcrPM);
++/*
++	GT64240ETH_WRITE(gp, GT64240_ETH_PORT_CONFIG,
++		(PORT_CONFIG | pcrPM | pcrEN));
++*/
++
++	memset(gp->hash_table, 0, RX_HASH_TABLE_SIZE);	// clear hash table
++	// Add our ethernet address
++	gt64240_add_hash_entry(dev, dev->dev_addr);
++	if (dev->mc_count) {
++		for (mcptr = dev->mc_list; mcptr; mcptr = mcptr->next) {
++			if (gt64240_debug > 2) {
++				printk("%s: gt64240_set_rx_mode: addr=\n",
++				       dev->name);
++				dump_hw_addr(mcptr->dmi_addr);
++			}
++			gt64240_add_hash_entry(dev, mcptr->dmi_addr);
++		}
++	}
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_set_rx: Port Config=%x\n", dev->name,
++		       GT64240ETH_READ(gp, GT64240_ETH_PORT_CONFIG));
++
++	// restart Rx DMA
++	GT64240ETH_WRITE(gp, GT64240_ETH_SDMA_COMM, sdcmrERD);
++
++	spin_unlock_irqrestore(&gp->lock, flags);
++}
++
++static struct net_device_stats *gt64240_get_stats(struct net_device *dev)
++{
++	struct gt64240_private *gp = netdev_priv(dev);
++	unsigned long flags;
++
++	if (gt64240_debug > 3)
++		printk("%s: gt64240_get_stats: dev=%p\n", dev->name, dev);
++
++	if (netif_device_present(dev)) {
++		spin_lock_irqsave(&gp->lock, flags);
++		update_stats(gp);
++		spin_unlock_irqrestore(&gp->lock, flags);
++	}
++
++	return &gp->stats;
++}
+diff -urpNX dontdiff linux-2.6.10/drivers/net/gt64240eth.h linux-2.6.10-mips/drivers/net/gt64240eth.h
+--- linux-2.6.10/drivers/net/gt64240eth.h	2004-12-24 22:33:49.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/gt64240eth.h	2004-09-21 13:10:38.000000000 +0200
+@@ -108,10 +108,10 @@
+ #define REV_GT64240A 0x10
+ 
+ #define GT64240ETH_READ(gp, offset)					\
+-	GT_READ((gp)->port_offset + (offset))
++	MV_READ((gp)->port_offset + (offset))
+ 
+ #define GT64240ETH_WRITE(gp, offset, data)				\
+-	GT_WRITE((gp)->port_offset + (offset), (data))
++	MV_WRITE((gp)->port_offset + (offset), (data))
+ 
+ #define GT64240ETH_SETBIT(gp, offset, bits)				\
+ 	GT64240ETH_WRITE((gp), (offset),				\
+@@ -121,8 +121,8 @@
+ 	GT64240ETH_WRITE((gp), (offset),				\
+ 	                 GT64240ETH_READ((gp), (offset)) & ~(bits))
+ 
+-#define GT64240_READ(ofs)		GT_READ(ofs)
+-#define GT64240_WRITE(ofs, data)	GT_WRITE((ofs), (data))
++#define GT64240_READ(ofs)		MV_READ(ofs)
++#define GT64240_WRITE(ofs, data)	MV_WRITE((ofs), (data))
+ 
+ /* Bit definitions of the SMI Reg */
+ enum {
+diff -urpNX dontdiff linux-2.6.10/drivers/net/hamradio/6pack.c linux-2.6.10-mips/drivers/net/hamradio/6pack.c
+--- linux-2.6.10/drivers/net/hamradio/6pack.c	2004-12-24 22:34:01.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/hamradio/6pack.c	2004-10-27 02:14:37.000000000 +0200
+@@ -727,7 +727,7 @@ out:
+  */
+ static void sixpack_close(struct tty_struct *tty)
+ {
+-	struct sixpack *sp = (struct sixpack *) tty->disc_data;
++	struct sixpack *sp;
+ 
+ 	write_lock(&disc_data_lock);
+ 	sp = tty->disc_data;
+diff -urpNX dontdiff linux-2.6.10/drivers/net/ioc3-eth.c linux-2.6.10-mips/drivers/net/ioc3-eth.c
+--- linux-2.6.10/drivers/net/ioc3-eth.c	2004-12-24 22:33:51.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/ioc3-eth.c	2004-12-28 20:06:42.000000000 +0100
+@@ -463,6 +463,29 @@ static void ioc3_get_eaddr(struct ioc3_p
+ 	printk(".\n");
+ }
+ 
++static void __ioc3_set_mac_address(struct net_device *dev)
++{
++	struct ioc3_private *ip = netdev_priv(dev);
++	struct ioc3 *ioc3 = ip->regs;
++
++	ioc3_w_emar_h((dev->dev_addr[5] <<  8) | dev->dev_addr[4]);
++	ioc3_w_emar_l((dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) |
++	              (dev->dev_addr[1] <<  8) | dev->dev_addr[0]);
++}
++
++static int ioc3_set_mac_address(struct net_device *dev, void *addr)
++{
++	struct ioc3_private *ip = netdev_priv(dev);
++	struct sockaddr *sa = addr;
++
++	memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
++
++	spin_lock_irq(&ip->ioc3_lock);
++	__ioc3_set_mac_address(dev);
++	spin_unlock_irq(&ip->ioc3_lock);
++
++	return 0;
++}
+ 
+ /*
+  * Caller must hold the ioc3_lock ever for MII readers.  This is also
+@@ -1014,9 +1037,7 @@ static void ioc3_init(struct net_device 
+ 	(void) ioc3_r_etcdc();			/* Clear on read */
+ 	ioc3_w_ercsr(15);			/* RX low watermark  */
+ 	ioc3_w_ertr(0);				/* Interrupt immediately */
+-	ioc3_w_emar_h((dev->dev_addr[5] <<  8) | dev->dev_addr[4]);
+-	ioc3_w_emar_l((dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) |
+-	              (dev->dev_addr[1] <<  8) | dev->dev_addr[0]);
++	__ioc3_set_mac_address(dev);
+ 	ioc3_w_ehar_h(ip->ehar_h);
+ 	ioc3_w_ehar_l(ip->ehar_l);
+ 	ioc3_w_ersr(42);			/* XXX should be random */
+@@ -1100,6 +1121,7 @@ static inline int ioc3_is_menet(struct p
+ 	       && dev->device == PCI_DEVICE_ID_SGI_IOC3;
+ }
+ 
++#ifdef CONFIG_SERIAL_8250
+ /*
+  * Note about serial ports and consoles:
+  * For console output, everyone uses the IOC3 UARTA (offset 0x178)
+@@ -1121,15 +1143,14 @@ static inline int ioc3_is_menet(struct p
+  * "device" routine referred to in this console structure
+  * (ip27prom_console_dev).
+  *
+- * Also look in ip27-pci.c:pci_fixuop_ioc3() for some comments on working
++ * Also look in ip27-pci.c:pci_fixup_ioc3() for some comments on working
+  * around ioc3 oddities in this respect.
+  *
+  * The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
+  * (IOC3_BAUD = (22000000 / (3*16)))
+  */
+ 
+-static inline void ioc3_serial_probe(struct pci_dev *pdev,
+-				struct ioc3 *ioc3)
++static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
+ {
+ 	struct serial_struct req;
+ 
+@@ -1160,9 +1181,9 @@ static inline void ioc3_serial_probe(str
+ 	req.iomem_base      = (unsigned char *) &ioc3->sregs.uartb;
+ 	register_serial(&req);
+ }
++#endif
+ 
+-static int __devinit ioc3_probe(struct pci_dev *pdev,
+-	                        const struct pci_device_id *ent)
++static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+ 	unsigned int sw_physid1, sw_physid2;
+ 	struct net_device *dev = NULL;
+@@ -1170,11 +1191,39 @@ static int __devinit ioc3_probe(struct p
+ 	struct ioc3 *ioc3;
+ 	unsigned long ioc3_base, ioc3_size;
+ 	u32 vendor, model, rev;
+-	int err;
++	int err, pci_using_dac;
++
++	/* Configure DMA attributes. */
++	err = pci_set_dma_mask(pdev, 0xffffffffffffffffULL);
++	if (!err) {
++		pci_using_dac = 1;
++		err = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
++		if (err < 0) {
++			printk(KERN_ERR "%s: Unable to obtain 64 bit DMA "
++			       "for consistent allocations\n", pci_name(pdev));
++			goto out;
++		}
++	} else {
++		err = pci_set_dma_mask(pdev, 0xffffffffULL);
++		if (err) {
++			printk(KERN_ERR "%s: No usable DMA configuration, "
++			       "aborting.\n", pci_name(pdev));
++			goto out;
++		}
++		pci_using_dac = 0;
++	}
++
++	if (pci_enable_device(pdev))
++		return -ENODEV;
+ 
+ 	dev = alloc_etherdev(sizeof(struct ioc3_private));
+-	if (!dev)
+-		return -ENOMEM;
++	if (!dev) {
++		err = -ENOMEM;
++		goto out_disable;
++	}
++
++	if (pci_using_dac)
++		dev->features |= NETIF_F_HIGHDMA;
+ 
+ 	err = pci_request_regions(pdev, "ioc3");
+ 	if (err)
+@@ -1237,6 +1286,7 @@ static int __devinit ioc3_probe(struct p
+ 	dev->get_stats		= ioc3_get_stats;
+ 	dev->do_ioctl		= ioc3_ioctl;
+ 	dev->set_multicast_list	= ioc3_set_multicast_list;
++	dev->set_mac_address	= ioc3_set_mac_address;
+ 	dev->ethtool_ops	= &ioc3_ethtool_ops;
+ #ifdef CONFIG_SGI_IOC3_ETH_HW_TX_CSUM
+ 	dev->features		= NETIF_F_IP_CSUM;
+@@ -1269,6 +1319,12 @@ out_res:
+ 	pci_release_regions(pdev);
+ out_free:
+ 	free_netdev(dev);
++out_disable:
++	/*
++	 * We should call pci_disable_device(pdev); here if the IOC3 wasn't
++	 * such a weird device ...
++	 */
++out:
+ 	return err;
+ }
+ 
+@@ -1282,6 +1338,10 @@ static void __devexit ioc3_remove_one (s
+ 	iounmap(ioc3);
+ 	pci_release_regions(pdev);
+ 	free_netdev(dev);
++	/*
++	 * We should call pci_disable_device(pdev); here if the IOC3 wasn't
++	 * such a weird device ...
++	 */
+ }
+ 
+ static struct pci_device_id ioc3_pci_tbl[] = {
+diff -urpNX dontdiff linux-2.6.10/drivers/net/jazzsonic.c linux-2.6.10-mips/drivers/net/jazzsonic.c
+--- linux-2.6.10/drivers/net/jazzsonic.c	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/jazzsonic.c	2004-11-04 19:10:48.000000000 +0100
+@@ -14,6 +14,7 @@
+  */
+ 
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/types.h>
+ #include <linux/fcntl.h>
+ #include <linux/interrupt.h>
+@@ -28,6 +29,7 @@
+ #include <linux/etherdevice.h>
+ #include <linux/skbuff.h>
+ #include <linux/bitops.h>
++#include <linux/device.h>
+ 
+ #include <asm/bootinfo.h>
+ #include <asm/system.h>
+@@ -37,7 +39,10 @@
+ #include <asm/jazz.h>
+ #include <asm/jazzdma.h>
+ 
+-#define DRV_NAME "jazzsonic"
++static char jazz_sonic_string[] = "jazzsonic";
++static struct platform_device *jazz_sonic_device;
++
++#define SONIC_MEM_SIZE	0x100
+ 
+ #define SREGS_PAD(n)    u16 n;
+ 
+@@ -50,8 +55,8 @@
+ 
+ #define SONIC_WRITE(reg,val)						\
+ do {									\
+-	*((volatile unsigned int *)base_addr+reg) = val;		\
+-}
++	*((volatile unsigned int *)base_addr+(reg)) = (val);		\
++} while (0)
+ 
+ 
+ /* use 0 for production, 1 for verification, >2 for debug */
+@@ -80,70 +85,7 @@ static unsigned short known_revisions[] 
+ 	0xffff			/* end of list */
+ };
+ 
+-/* Index to functions, as function prototypes. */
+-
+-static int sonic_probe1(struct net_device *dev, unsigned int base_addr,
+-                        unsigned int irq);
+-
+-
+-/*
+- * Probe for a SONIC ethernet controller on a Mips Jazz board.
+- * Actually probing is superfluous but we're paranoid.
+- */
+-struct net_device * __init sonic_probe(int unit)
+-{
+-	struct net_device *dev;
+-	struct sonic_local *lp;
+-	unsigned int base_addr;
+-	int err = 0;
+-	int i;
+-
+-	/*
+-	 * Don't probe if we're not running on a Jazz board.
+-	 */
+-	if (mips_machgroup != MACH_GROUP_JAZZ)
+-		return ERR_PTR(-ENODEV);
+-
+-	dev = alloc_etherdev(0);
+-	if (!dev)
+-		return ERR_PTR(-ENOMEM);
+-
+-	sprintf(dev->name, "eth%d", unit);
+-	netdev_boot_setup_check(dev);
+-	base_addr = dev->base_addr;
+-
+-	if (base_addr >= KSEG0)	{ /* Check a single specified location. */
+-		err = sonic_probe1(dev, base_addr, dev->irq);
+-	} else if (base_addr != 0) { /* Don't probe at all. */
+-		err = -ENXIO;
+-	} else {
+-		for (i = 0; sonic_portlist[i].port; i++) {
+-			int io = sonic_portlist[i].port;
+-			if (sonic_probe1(dev, io, sonic_portlist[i].irq) == 0)
+-				break;
+-		}
+-		if (!sonic_portlist[i].port)
+-			err = -ENODEV;
+-	}
+-	if (err)
+-		goto out;
+-	err = register_netdev(dev);
+-	if (err)
+-		goto out1;
+-	return dev;
+-out1:
+-	lp = dev->priv;
+-	vdma_free(lp->rba_laddr);
+-	kfree(lp->rba);
+-	vdma_free(lp->cda_laddr);
+-	kfree(lp);
+-	release_region(dev->base_addr, 0x100);
+-out:
+-	free_netdev(dev);
+-	return ERR_PTR(err);
+-}
+-
+-static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
++static int __init sonic_probe1(struct net_device *dev, unsigned long base_addr,
+                                unsigned int irq)
+ {
+ 	static unsigned version_printed;
+@@ -153,7 +95,7 @@ static int __init sonic_probe1(struct ne
+ 	int err = -ENODEV;
+ 	int i;
+ 
+-	if (!request_region(base_addr, 0x100, DRV_NAME))
++	if (!request_mem_region(base_addr, SONIC_MEM_SIZE, jazz_sonic_string))
+ 		return -EBUSY;
+ 	/*
+ 	 * get the Silicon Revision ID. If this is one of the known
+@@ -233,7 +175,7 @@ static int __init sonic_probe1(struct ne
+ 		memset(lp, 0, sizeof(struct sonic_local));
+ 
+ 		/* get the virtual dma address */
+-		lp->cda_laddr = vdma_alloc(PHYSADDR(lp),sizeof(*lp));
++		lp->cda_laddr = vdma_alloc(CPHYSADDR(lp),sizeof(*lp));
+ 		if (lp->cda_laddr == ~0UL) {
+ 			printk("%s: couldn't get DMA page entry for "
+ 			       "descriptors\n", dev->name);
+@@ -254,7 +196,7 @@ static int __init sonic_probe1(struct ne
+ 		}
+ 
+ 		/* get virtual dma address */
+-		lp->rba_laddr = vdma_alloc(PHYSADDR(lp->rba),
++		lp->rba_laddr = vdma_alloc(CPHYSADDR(lp->rba),
+ 		                           SONIC_NUM_RRS * SONIC_RBSIZE);
+ 		if (lp->rba_laddr == ~0UL) {
+ 			printk("%s: couldn't get DMA page entry for receive "
+@@ -291,7 +233,66 @@ out2:
+ out1:
+ 	kfree(lp);
+ out:
+-	release_region(base_addr, 0x100);
++	release_region(base_addr, SONIC_MEM_SIZE);
++	return err;
++}
++
++/*
++ * Probe for a SONIC ethernet controller on a Mips Jazz board.
++ * Actually probing is superfluous but we're paranoid.
++ */
++static int __init jazz_sonic_probe(struct device *device)
++{
++	struct net_device *dev;
++	struct sonic_local *lp;
++	unsigned long base_addr;
++	int err = 0;
++	int i;
++
++	/*
++	 * Don't probe if we're not running on a Jazz board.
++	 */
++	if (mips_machgroup != MACH_GROUP_JAZZ)
++		return -ENODEV;
++
++	dev = alloc_etherdev(0);
++	if (!dev)
++		return -ENOMEM;
++
++	netdev_boot_setup_check(dev);
++	base_addr = dev->base_addr;
++
++	if (base_addr >= KSEG0)	{ /* Check a single specified location. */
++		err = sonic_probe1(dev, base_addr, dev->irq);
++	} else if (base_addr != 0) { /* Don't probe at all. */
++		err = -ENXIO;
++	} else {
++		for (i = 0; sonic_portlist[i].port; i++) {
++			int io = sonic_portlist[i].port;
++			if (sonic_probe1(dev, io, sonic_portlist[i].irq) == 0)
++				break;
++		}
++		if (!sonic_portlist[i].port)
++			err = -ENODEV;
++	}
++	if (err)
++		goto out;
++	err = register_netdev(dev);
++	if (err)
++		goto out1;
++
++	return 0;
++
++out1:
++	lp = dev->priv;
++	vdma_free(lp->rba_laddr);
++	kfree(lp->rba);
++	vdma_free(lp->cda_laddr);
++	kfree(lp);
++	release_region(dev->base_addr, SONIC_MEM_SIZE);
++out:
++	free_netdev(dev);
++
+ 	return err;
+ }
+ 
+@@ -304,3 +305,77 @@ out:
+ #define sonic_chiptomem(x)      KSEG1ADDR(vdma_log2phys(x))
+ 
+ #include "sonic.c"
++
++static int __devexit jazz_sonic_device_remove (struct device *device)
++{
++	struct net_device *dev = device->driver_data;
++
++	unregister_netdev (dev);
++	release_region (dev->base_addr, SONIC_MEM_SIZE);
++	free_netdev (dev);
++
++	return 0;
++}
++
++static struct device_driver jazz_sonic_driver = {
++	.name	= jazz_sonic_string,
++	.bus	= &platform_bus_type,
++	.probe	= jazz_sonic_probe,
++	.remove	= __devexit_p(jazz_sonic_device_remove),
++};
++                                                                                
++static void jazz_sonic_platform_release (struct device *device)
++{
++	struct platform_device *pldev;
++
++	/* free device */
++	pldev = to_platform_device (device);
++	kfree (pldev);
++}
++
++static int __init jazz_sonic_init_module(void)
++{
++	struct platform_device *pldev;
++
++	if (driver_register(&jazz_sonic_driver)) {
++		printk(KERN_ERR "Driver registration failed\n");
++		return -ENOMEM;
++	}
++
++	jazz_sonic_device = NULL;
++
++	if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
++		goto out_unregister;
++	}
++
++	memset(pldev, 0, sizeof (*pldev));
++	pldev->name		= jazz_sonic_string;
++	pldev->id		= 0;
++	pldev->dev.release	= jazz_sonic_platform_release;
++	jazz_sonic_device	= pldev;
++
++	if (platform_device_register (pldev)) {
++		kfree(pldev);
++		jazz_sonic_device = NULL;
++	}
++
++	return 0;
++
++out_unregister:
++	platform_device_unregister(pldev);
++
++	return -ENOMEM;
++}
++
++static void __exit jazz_sonic_cleanup_module(void)
++{
++	driver_unregister(&jazz_sonic_driver);
++
++	if (jazz_sonic_device) {
++		platform_device_unregister(jazz_sonic_device);
++		jazz_sonic_device = NULL;
++	}
++}
++
++module_init(jazz_sonic_init_module);
++module_exit(jazz_sonic_cleanup_module);
+diff -urpNX dontdiff linux-2.6.10/drivers/net/meth.c linux-2.6.10-mips/drivers/net/meth.c
+--- linux-2.6.10/drivers/net/meth.c	2004-12-24 22:35:24.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/meth.c	2005-01-11 00:40:22.000000000 +0100
+@@ -27,7 +27,7 @@
+ #include <linux/ip.h>          /* struct iphdr */
+ #include <linux/tcp.h>         /* struct tcphdr */
+ #include <linux/skbuff.h>
+-#include <linux/mii.h> /*MII definitions */
++#include <linux/mii.h>         /* MII definitions */
+ 
+ #include <asm/ip32/mace.h>
+ #include <asm/ip32/ip32_ints.h>
+@@ -105,27 +105,27 @@ static inline void load_eaddr(struct net
+ 		(int)o2meth_eaddr[3]&0xFF,(int)o2meth_eaddr[4]&0xFF,(int)o2meth_eaddr[5]&0xFF);
+ 	for (i = 0; i < 6; i++)
+ 		dev->dev_addr[i] = o2meth_eaddr[i];
+-	mace_eth_write((*(u64*)o2meth_eaddr)>>16, mac_addr);
++	mace->eth.mac_addr = (*(unsigned long*)o2meth_eaddr) >> 16;
+ }
+ 
+ /*
+  * Waits for BUSY status of mdio bus to clear
+  */
+-#define WAIT_FOR_PHY(___rval)						\
+-	while ((___rval = mace_eth_read(phy_data)) & MDIO_BUSY) {	\
+-		udelay(25);						\
++#define WAIT_FOR_PHY(___rval)					\
++	while ((___rval = mace->eth.phy_data) & MDIO_BUSY) {	\
++		udelay(25);					\
+ 	}
+ /*read phy register, return value read */
+ static unsigned long mdio_read(struct meth_private *priv, unsigned long phyreg)
+ {
+ 	unsigned long rval;
+ 	WAIT_FOR_PHY(rval);
+-	mace_eth_write((priv->phy_addr << 5) | (phyreg & 0x1f), phy_regs);
++	mace->eth.phy_regs = (priv->phy_addr << 5) | (phyreg & 0x1f);
+ 	udelay(25);
+-	mace_eth_write(1, phy_trans_go);
++	mace->eth.phy_trans_go = 1;
+ 	udelay(25);
+ 	WAIT_FOR_PHY(rval);
+-	return rval&MDIO_DATA_MASK;
++	return rval & MDIO_DATA_MASK;
+ }
+ 
+ static int mdio_probe(struct meth_private *priv)
+@@ -191,7 +191,7 @@ static void meth_check_link(struct net_d
+ 			priv->mac_ctrl |= METH_PHY_FDX;
+ 		else
+ 			priv->mac_ctrl &= ~METH_PHY_FDX;
+-		mace_eth_write(priv->mac_ctrl, mac_ctrl);
++		mace->eth.mac_ctrl = priv->mac_ctrl;
+ 	}
+ 
+ 	if ((priv->mac_ctrl & METH_100MBIT) ^ speed) {
+@@ -200,7 +200,7 @@ static void meth_check_link(struct net_d
+ 			priv->mac_ctrl |= METH_100MBIT;
+ 		else
+ 			priv->mac_ctrl &= ~METH_100MBIT;
+-		mace_eth_write(priv->mac_ctrl, mac_ctrl);
++		mace->eth.mac_ctrl = priv->mac_ctrl;
+ 	}
+ }
+ 
+@@ -214,26 +214,28 @@ static int meth_init_tx_ring(struct meth
+ 		return -ENOMEM;
+ 	memset(priv->tx_ring, 0, TX_RING_BUFFER_SIZE);
+ 	priv->tx_count = priv->tx_read = priv->tx_write = 0;
+-	mace_eth_write(priv->tx_ring_dma, tx_ring_base);
++	mace->eth.tx_ring_base = priv->tx_ring_dma;
+ 	/* Now init skb save area */
+-	memset(priv->tx_skbs,0,sizeof(priv->tx_skbs));
+-	memset(priv->tx_skb_dmas,0,sizeof(priv->tx_skb_dmas));
++	memset(priv->tx_skbs, 0, sizeof(priv->tx_skbs));
++	memset(priv->tx_skb_dmas, 0, sizeof(priv->tx_skb_dmas));
+ 	return 0;
+ }
+ 
+ static int meth_init_rx_ring(struct meth_private *priv)
+ {
+ 	int i;
+-	for(i=0;i<RX_RING_ENTRIES;i++){
+-		priv->rx_skbs[i]=alloc_skb(METH_RX_BUFF_SIZE,0);
+-		/* 8byte status vector+3quad padding + 2byte padding,
+-		   to put data on 64bit aligned boundary */
++
++	for (i = 0; i < RX_RING_ENTRIES; i++) {
++		priv->rx_skbs[i] = alloc_skb(METH_RX_BUFF_SIZE, 0);
++		/* 8byte status vector + 3quad padding + 2byte padding,
++		 * to put data on 64bit aligned boundary */
+ 		skb_reserve(priv->rx_skbs[i],METH_RX_HEAD);
+ 		priv->rx_ring[i]=(rx_packet*)(priv->rx_skbs[i]->head);
+ 		/* I'll need to re-sync it after each RX */
+-		priv->rx_ring_dmas[i]=dma_map_single(NULL,priv->rx_ring[i],
+-						     METH_RX_BUFF_SIZE,DMA_FROM_DEVICE);
+-		mace_eth_write(priv->rx_ring_dmas[i], rx_fifo);
++		priv->rx_ring_dmas[i] = 
++			dma_map_single(NULL, priv->rx_ring[i],
++				       METH_RX_BUFF_SIZE, DMA_FROM_DEVICE);
++		mace->eth.rx_fifo = priv->rx_ring_dmas[i];
+ 	}
+         priv->rx_write = 0;
+ 	return 0;
+@@ -257,10 +259,11 @@ static void meth_free_rx_ring(struct met
+ {
+ 	int i;
+ 
+-	for(i=0;i<RX_RING_ENTRIES;i++) {
+-		dma_unmap_single(NULL,priv->rx_ring_dmas[i],METH_RX_BUFF_SIZE,DMA_FROM_DEVICE);
+-		priv->rx_ring[i]=0;
+-		priv->rx_ring_dmas[i]=0;
++	for (i = 0; i < RX_RING_ENTRIES; i++) {
++		dma_unmap_single(NULL, priv->rx_ring_dmas[i],
++				 METH_RX_BUFF_SIZE, DMA_FROM_DEVICE);
++		priv->rx_ring[i] = 0;
++		priv->rx_ring_dmas[i] = 0;
+ 		kfree_skb(priv->rx_skbs[i]);
+ 	}
+ }
+@@ -270,8 +273,9 @@ int meth_reset(struct net_device *dev)
+ 	struct meth_private *priv = (struct meth_private *) dev->priv;
+ 
+ 	/* Reset card */
+-	mace_eth_write(SGI_MAC_RESET, mac_ctrl);
+-	mace_eth_write(0, mac_ctrl);
++	mace->eth.mac_ctrl = SGI_MAC_RESET;
++	udelay(1);
++	mace->eth.mac_ctrl = 0;
+ 	udelay(25);
+ 
+ 	/* Load ethernet address */
+@@ -279,24 +283,24 @@ int meth_reset(struct net_device *dev)
+ 	/* Should load some "errata", but later */
+ 	
+ 	/* Check for device */
+-	if(mdio_probe(priv) < 0) {
++	if (mdio_probe(priv) < 0) {
+ 		DPRINTK("Unable to find PHY\n");
+ 		return -ENODEV;
+ 	}
+ 
+ 	/* Initial mode: 10 | Half-duplex | Accept normal packets */
+ 	priv->mac_ctrl = METH_ACCEPT_MCAST | METH_DEFAULT_IPG;
+-	if(dev->flags | IFF_PROMISC)
++	if (dev->flags | IFF_PROMISC)
+ 		priv->mac_ctrl |= METH_PROMISC;
+-	mace_eth_write(priv->mac_ctrl, mac_ctrl);
++	mace->eth.mac_ctrl = priv->mac_ctrl;
+ 
+ 	/* Autonegotiate speed and duplex mode */
+ 	meth_check_link(dev);
+ 
+ 	/* Now set dma control, but don't enable DMA, yet */
+-	priv->dma_ctrl= (4 << METH_RX_OFFSET_SHIFT) |
+-		(RX_RING_ENTRIES << METH_RX_DEPTH_SHIFT);
+-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
++	priv->dma_ctrl = (4 << METH_RX_OFFSET_SHIFT) |
++			 (RX_RING_ENTRIES << METH_RX_DEPTH_SHIFT);
++	mace->eth.dma_ctrl = priv->dma_ctrl;
+ 
+ 	return 0;
+ }
+@@ -335,7 +339,7 @@ static int meth_open(struct net_device *
+ 	/* Start DMA */
+ 	priv->dma_ctrl |= METH_DMA_TX_EN | /*METH_DMA_TX_INT_EN |*/
+ 			  METH_DMA_RX_EN | METH_DMA_RX_INT_EN;
+-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
++	mace->eth.dma_ctrl = priv->dma_ctrl;
+ 
+ 	DPRINTK("About to start queue\n");
+ 	netif_start_queue(dev);
+@@ -359,7 +363,7 @@ static int meth_release(struct net_devic
+ 	/* shut down DMA */
+ 	priv->dma_ctrl &= ~(METH_DMA_TX_EN | METH_DMA_TX_INT_EN |
+ 			    METH_DMA_RX_EN | METH_DMA_RX_INT_EN);
+-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
++	mace->eth.dma_ctrl = priv->dma_ctrl;
+ 	free_irq(dev->irq, dev);
+ 	meth_free_tx_ring(priv);
+ 	meth_free_rx_ring(priv);
+@@ -373,56 +377,57 @@ static int meth_release(struct net_devic
+ static void meth_rx(struct net_device* dev, unsigned long int_status)
+ {
+ 	struct sk_buff *skb;
++	unsigned long status;
+ 	struct meth_private *priv = (struct meth_private *) dev->priv;
+-	unsigned long fifo_rptr=(int_status&METH_INT_RX_RPTR_MASK)>>8;
++	unsigned long fifo_rptr = (int_status & METH_INT_RX_RPTR_MASK) >> 8;
++
+ 	spin_lock(&priv->meth_lock);
+-	priv->dma_ctrl&=~METH_DMA_RX_INT_EN;
+-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
++	priv->dma_ctrl &= ~METH_DMA_RX_INT_EN;
++	mace->eth.dma_ctrl = priv->dma_ctrl;
+ 	spin_unlock(&priv->meth_lock);
+ 
+-	if (int_status & METH_INT_RX_UNDERFLOW){
+-		fifo_rptr=(fifo_rptr-1)&(0xF);
++	if (int_status & METH_INT_RX_UNDERFLOW) {
++		fifo_rptr = (fifo_rptr - 1) & 0x0f;
+ 	}
+-	while(priv->rx_write != fifo_rptr) {
+-		u64 status;
+-		dma_unmap_single(NULL,priv->rx_ring_dmas[priv->rx_write],
+-				 METH_RX_BUFF_SIZE,DMA_FROM_DEVICE);
+-		status=priv->rx_ring[priv->rx_write]->status.raw;
++	while (priv->rx_write != fifo_rptr) {
++		dma_unmap_single(NULL, priv->rx_ring_dmas[priv->rx_write],
++				 METH_RX_BUFF_SIZE, DMA_FROM_DEVICE);
++		status = priv->rx_ring[priv->rx_write]->status.raw;
+ #if MFE_DEBUG
+-		if(!(status&METH_RX_ST_VALID)) {
++		if (!(status & METH_RX_ST_VALID)) {
+ 			DPRINTK("Not received? status=%016lx\n",status);
+ 		}
+ #endif
+-		if((!(status&METH_RX_STATUS_ERRORS))&&(status&METH_RX_ST_VALID)){
+-			int len=(status&0xFFFF) - 4; /* omit CRC */
++		if ((!(status & METH_RX_STATUS_ERRORS)) && (status & METH_RX_ST_VALID)) {
++			int len = (status & 0xffff) - 4; /* omit CRC */
+ 			/* length sanity check */
+-			if(len < 60 || len > 1518) {
+-				printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2lx.\n",
++			if (len < 60 || len > 1518) {
++				printk(KERN_DEBUG "%s: bogus packet size: %ld, status=%#2lx.\n",
+ 				       dev->name, priv->rx_write,
+ 				       priv->rx_ring[priv->rx_write]->status.raw);
+ 				priv->stats.rx_errors++;
+ 				priv->stats.rx_length_errors++;
+-				skb=priv->rx_skbs[priv->rx_write];
++				skb = priv->rx_skbs[priv->rx_write];
+ 			} else {
+-				skb=alloc_skb(METH_RX_BUFF_SIZE,GFP_ATOMIC|GFP_DMA);
+-				if(!skb){
++				skb = alloc_skb(METH_RX_BUFF_SIZE, GFP_ATOMIC | GFP_DMA);
++				if (!skb) {
+ 					/* Ouch! No memory! Drop packet on the floor */
+ 					DPRINTK("No mem: dropping packet\n");
+ 					priv->stats.rx_dropped++;
+-					skb=priv->rx_skbs[priv->rx_write];
++					skb = priv->rx_skbs[priv->rx_write];
+ 				} else {
+-					struct sk_buff *skb_c=priv->rx_skbs[priv->rx_write];
+-					/* 8byte status vector+3quad padding + 2byte padding,
+-					   to put data on 64bit aligned boundary */
+-					skb_reserve(skb,METH_RX_HEAD);
++					struct sk_buff *skb_c = priv->rx_skbs[priv->rx_write];
++					/* 8byte status vector + 3quad padding + 2byte padding,
++					 * to put data on 64bit aligned boundary */
++					skb_reserve(skb, METH_RX_HEAD);
+ 					/* Write metadata, and then pass to the receive level */
+-					skb_put(skb_c,len);
+-					priv->rx_skbs[priv->rx_write]=skb;
++					skb_put(skb_c, len);
++					priv->rx_skbs[priv->rx_write] = skb;
+ 					skb_c->dev = dev;
+ 					skb_c->protocol = eth_type_trans(skb_c, dev);
+ 					dev->last_rx = jiffies;
+ 					priv->stats.rx_packets++;
+-					priv->stats.rx_bytes+=len;
++					priv->stats.rx_bytes += len;
+ 					netif_rx(skb_c);
+ 				}
+ 			}
+@@ -445,18 +450,19 @@ static void meth_rx(struct net_device* d
+ 				printk(KERN_WARNING "Carrier Event Seen\n");
+ #endif
+ 		}
+-		priv->rx_ring[priv->rx_write]=(rx_packet*)skb->head;
+-		priv->rx_ring[priv->rx_write]->status.raw=0;
+-		priv->rx_ring_dmas[priv->rx_write]=dma_map_single(NULL,priv->rx_ring[priv->rx_write],
+-								  METH_RX_BUFF_SIZE,DMA_FROM_DEVICE);
+-		mace_eth_write(priv->rx_ring_dmas[priv->rx_write], rx_fifo);
++		priv->rx_ring[priv->rx_write] = (rx_packet*)skb->head;
++		priv->rx_ring[priv->rx_write]->status.raw = 0;
++		priv->rx_ring_dmas[priv->rx_write] = 
++			dma_map_single(NULL, priv->rx_ring[priv->rx_write],
++				       METH_RX_BUFF_SIZE, DMA_FROM_DEVICE);
++		mace->eth.rx_fifo = priv->rx_ring_dmas[priv->rx_write];
+ 		ADVANCE_RX_PTR(priv->rx_write);
+ 	}
+ 	spin_lock(&priv->meth_lock);
+ 	/* In case there was underflow, and Rx DMA was disabled */
+-	priv->dma_ctrl|=METH_DMA_RX_INT_EN|METH_DMA_RX_EN;
+-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
+-	mace_eth_write(METH_INT_RX_THRESHOLD, int_stat);
++	priv->dma_ctrl |= METH_DMA_RX_INT_EN | METH_DMA_RX_EN;
++	mace->eth.dma_ctrl = priv->dma_ctrl;
++	mace->eth.int_stat = METH_INT_RX_THRESHOLD;
+ 	spin_unlock(&priv->meth_lock);
+ }
+ 
+@@ -464,31 +470,31 @@ static int meth_tx_full(struct net_devic
+ {
+ 	struct meth_private *priv = (struct meth_private *) dev->priv;
+ 
+-	return(priv->tx_count >= TX_RING_ENTRIES-1);
++	return (priv->tx_count >= TX_RING_ENTRIES - 1);
+ }
+ 
+ static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status)
+ {
+ 	struct meth_private *priv = dev->priv;
+-	u64 status;
++	unsigned long status;
+ 	struct sk_buff *skb;
+-	unsigned long rptr=(int_status&TX_INFO_RPTR)>>16;
++	unsigned long rptr = (int_status&TX_INFO_RPTR) >> 16;
+ 
+ 	spin_lock(&priv->meth_lock);
+ 
+ 	/* Stop DMA notification */
+ 	priv->dma_ctrl &= ~(METH_DMA_TX_INT_EN);
+-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
++	mace->eth.dma_ctrl = priv->dma_ctrl;
+ 
+-	while(priv->tx_read != rptr){
++	while (priv->tx_read != rptr) {
+ 		skb = priv->tx_skbs[priv->tx_read];
+ 		status = priv->tx_ring[priv->tx_read].header.raw;
+ #if MFE_DEBUG>=1
+-		if(priv->tx_read==priv->tx_write)
+-			DPRINTK("Auchi! tx_read=%d,tx_write=%d,rptr=%d?\n",priv->tx_read,priv->tx_write,rptr);
++		if (priv->tx_read == priv->tx_write)
++			DPRINTK("Auchi! tx_read=%d,tx_write=%d,rptr=%d?\n", priv->tx_read, priv->tx_write,rptr);
+ #endif
+-		if(status & METH_TX_ST_DONE) {
+-			if(status & METH_TX_ST_SUCCESS){
++		if (status & METH_TX_ST_DONE) {
++			if (status & METH_TX_ST_SUCCESS){
+ 				priv->stats.tx_packets++;
+ 				priv->stats.tx_bytes += skb->len;
+ 			} else {
+@@ -518,19 +524,19 @@ static void meth_tx_cleanup(struct net_d
+ 		priv->tx_skbs[priv->tx_read] = NULL;
+ 		priv->tx_ring[priv->tx_read].header.raw = 0;
+ 		priv->tx_read = (priv->tx_read+1)&(TX_RING_ENTRIES-1);
+-		priv->tx_count --;
++		priv->tx_count--;
+ 	}
+ 
+ 	/* wake up queue if it was stopped */
+-	if (netif_queue_stopped(dev) && ! meth_tx_full(dev)) {
++	if (netif_queue_stopped(dev) && !meth_tx_full(dev)) {
+ 		netif_wake_queue(dev);
+ 	}
+ 
+-	mace_eth_write(METH_INT_TX_EMPTY | METH_INT_TX_PKT, int_stat);
++	mace->eth.int_stat = METH_INT_TX_EMPTY | METH_INT_TX_PKT;
+ 	spin_unlock(&priv->meth_lock);
+ }
+ 
+-static void meth_error(struct net_device* dev, u32 status)
++static void meth_error(struct net_device* dev, unsigned status)
+ {
+ 	struct meth_private *priv = (struct meth_private *) dev->priv;
+ 
+@@ -548,17 +554,16 @@ static void meth_error(struct net_device
+ 	if (status & (METH_INT_RX_UNDERFLOW)) {
+ 		printk(KERN_WARNING "meth: Rx underflow\n");
+ 		spin_lock(&priv->meth_lock);
+-		mace_eth_write(METH_INT_RX_UNDERFLOW, int_stat);
++		mace->eth.int_stat = METH_INT_RX_UNDERFLOW;
+ 		/* more underflow interrupts will be delivered, 
+-		   effectively throwing us into an infinite loop.
+-		   Thus I stop processing Rx in this case.
+-		*/
+-		priv->dma_ctrl&=~METH_DMA_RX_EN;
+-		mace_eth_write(priv->dma_ctrl, dma_ctrl);
++		 * effectively throwing us into an infinite loop.
++		 *  Thus I stop processing Rx in this case. */
++		priv->dma_ctrl &= ~METH_DMA_RX_EN;
++		mace->eth.dma_ctrl = priv->dma_ctrl;
+ 		DPRINTK("Disabled meth Rx DMA temporarily\n");
+ 		spin_unlock(&priv->meth_lock);
+ 	}
+-	mace_eth_write(METH_INT_ERROR, int_stat);
++	mace->eth.int_stat = METH_INT_ERROR;
+ }
+ 
+ /*
+@@ -570,12 +575,12 @@ static irqreturn_t meth_interrupt(int ir
+ 	struct meth_private *priv = (struct meth_private *) dev->priv;
+ 	unsigned long status;
+ 
+-	status = mace_eth_read(int_stat);
+-	while (status & 0xFF) {
++	status = mace->eth.int_stat;
++	while (status & 0xff) {
+ 		/* First handle errors - if we get Rx underflow,
+-		   Rx DMA will be disabled, and Rx handler will reenable
+-		   it. I don't think it's possible to get Rx underflow,
+-		   without getting Rx interrupt */
++		 * Rx DMA will be disabled, and Rx handler will reenable
++		 * it. I don't think it's possible to get Rx underflow,
++		 * without getting Rx interrupt */
+ 		if (status & METH_INT_ERROR) {
+ 			meth_error(dev, status);
+ 		}
+@@ -589,7 +594,7 @@ static irqreturn_t meth_interrupt(int ir
+ 			/* send it to meth_rx for handling */
+ 			meth_rx(dev, status);
+ 		}
+-		status = mace_eth_read(int_stat);
++		status = mace->eth.int_stat;
+ 	}
+ 
+ 	return IRQ_HANDLED;
+@@ -601,45 +606,45 @@ static irqreturn_t meth_interrupt(int ir
+ static void meth_tx_short_prepare(struct meth_private *priv,
+ 				  struct sk_buff *skb)
+ {
+-	tx_packet *desc=&priv->tx_ring[priv->tx_write];
+-	int len = (skb->len<ETH_ZLEN)?ETH_ZLEN:skb->len;
++	tx_packet *desc = &priv->tx_ring[priv->tx_write];
++	int len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
+ 
+-	desc->header.raw=METH_TX_CMD_INT_EN|(len-1)|((128-len)<<16);
++	desc->header.raw = METH_TX_CMD_INT_EN | (len-1) | ((128-len) << 16);
+ 	/* maybe I should set whole thing to 0 first... */
+-	memcpy(desc->data.dt+(120-len),skb->data,skb->len);
+-	if(skb->len < len)
+-		memset(desc->data.dt+120-len+skb->len,0,len-skb->len);
++	memcpy(desc->data.dt + (120 - len), skb->data, skb->len);
++	if (skb->len < len)
++		memset(desc->data.dt + 120 - len + skb->len, 0, len-skb->len);
+ }
+ #define TX_CATBUF1 BIT(25)
+ static void meth_tx_1page_prepare(struct meth_private *priv,
+ 				  struct sk_buff *skb)
+ {
+-	tx_packet *desc=&priv->tx_ring[priv->tx_write];
++	tx_packet *desc = &priv->tx_ring[priv->tx_write];
+ 	void *buffer_data = (void *)(((unsigned long)skb->data + 7) & ~7);
+ 	int unaligned_len = (int)((unsigned long)buffer_data - (unsigned long)skb->data);
+ 	int buffer_len = skb->len - unaligned_len;
+ 	dma_addr_t catbuf;
+ 
+-	desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|(skb->len-1);
++	desc->header.raw = METH_TX_CMD_INT_EN | TX_CATBUF1 | (skb->len - 1);
+ 
+ 	/* unaligned part */
+-	if(unaligned_len){
+-		memcpy(desc->data.dt+(120-unaligned_len),
++	if (unaligned_len) {
++		memcpy(desc->data.dt + (120 - unaligned_len),
+ 		       skb->data, unaligned_len);
+-		desc->header.raw |= (128-unaligned_len) << 16;
++		desc->header.raw |= (128 - unaligned_len) << 16;
+ 	}
+ 
+ 	/* first page */
+ 	catbuf = dma_map_single(NULL, buffer_data, buffer_len,
+ 				DMA_TO_DEVICE);
+ 	desc->data.cat_buf[0].form.start_addr = catbuf >> 3;
+-	desc->data.cat_buf[0].form.len = buffer_len-1;
++	desc->data.cat_buf[0].form.len = buffer_len - 1;
+ }
+ #define TX_CATBUF2 BIT(26)
+ static void meth_tx_2page_prepare(struct meth_private *priv,
+ 				  struct sk_buff *skb)
+ {
+-	tx_packet *desc=&priv->tx_ring[priv->tx_write];
++	tx_packet *desc = &priv->tx_ring[priv->tx_write];
+ 	void *buffer1_data = (void *)(((unsigned long)skb->data + 7) & ~7);
+ 	void *buffer2_data = (void *)PAGE_ALIGN((unsigned long)skb->data);
+ 	int unaligned_len = (int)((unsigned long)buffer1_data - (unsigned long)skb->data);
+@@ -647,44 +652,44 @@ static void meth_tx_2page_prepare(struct
+ 	int buffer2_len = skb->len - buffer1_len - unaligned_len;
+ 	dma_addr_t catbuf1, catbuf2;
+ 
+-	desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|TX_CATBUF2|(skb->len-1);
++	desc->header.raw = METH_TX_CMD_INT_EN | TX_CATBUF1 | TX_CATBUF2| (skb->len - 1);
+ 	/* unaligned part */
+-	if(unaligned_len){
+-		memcpy(desc->data.dt+(120-unaligned_len),
++	if (unaligned_len){
++		memcpy(desc->data.dt + (120 - unaligned_len),
+ 		       skb->data, unaligned_len);
+-		desc->header.raw |= (128-unaligned_len) << 16;
++		desc->header.raw |= (128 - unaligned_len) << 16;
+ 	}
+ 
+ 	/* first page */
+ 	catbuf1 = dma_map_single(NULL, buffer1_data, buffer1_len,
+ 				 DMA_TO_DEVICE);
+ 	desc->data.cat_buf[0].form.start_addr = catbuf1 >> 3;
+-	desc->data.cat_buf[0].form.len = buffer1_len-1;
++	desc->data.cat_buf[0].form.len = buffer1_len - 1;
+ 	/* second page */
+ 	catbuf2 = dma_map_single(NULL, buffer2_data, buffer2_len,
+ 				 DMA_TO_DEVICE);
+ 	desc->data.cat_buf[1].form.start_addr = catbuf2 >> 3;
+-	desc->data.cat_buf[1].form.len = buffer2_len-1;
++	desc->data.cat_buf[1].form.len = buffer2_len - 1;
+ }
+ 
+ static void meth_add_to_tx_ring(struct meth_private *priv, struct sk_buff *skb)
+ {
+ 	/* Remember the skb, so we can free it at interrupt time */
+ 	priv->tx_skbs[priv->tx_write] = skb;
+-	if(skb->len <= 120) {
++	if (skb->len <= 120) {
+ 		/* Whole packet fits into descriptor */
+-		meth_tx_short_prepare(priv,skb);
+-	} else if(PAGE_ALIGN((unsigned long)skb->data) !=
+-		  PAGE_ALIGN((unsigned long)skb->data+skb->len-1)) {
++		meth_tx_short_prepare(priv, skb);
++	} else if (PAGE_ALIGN((unsigned long)skb->data) !=
++		   PAGE_ALIGN((unsigned long)skb->data + skb->len - 1)) {
+ 		/* Packet crosses page boundary */
+-		meth_tx_2page_prepare(priv,skb);
++		meth_tx_2page_prepare(priv, skb);
+ 	} else {
+ 		/* Packet is in one page */
+-		meth_tx_1page_prepare(priv,skb);
++		meth_tx_1page_prepare(priv, skb);
+ 	}
+-	priv->tx_write = (priv->tx_write+1) & (TX_RING_ENTRIES-1);
+-	mace_eth_write(priv->tx_write, tx_info);
+-	priv->tx_count ++;
++	priv->tx_write = (priv->tx_write + 1) & (TX_RING_ENTRIES - 1);
++	mace->eth.tx_info = priv->tx_write;
++	priv->tx_count++;
+ }
+ 
+ /*
+@@ -695,10 +700,10 @@ static int meth_tx(struct sk_buff *skb, 
+ 	struct meth_private *priv = (struct meth_private *) dev->priv;
+ 	unsigned long flags;
+ 
+-	spin_lock_irqsave(&priv->meth_lock,flags);
++	spin_lock_irqsave(&priv->meth_lock, flags);
+ 	/* Stop DMA notification */
+ 	priv->dma_ctrl &= ~(METH_DMA_TX_INT_EN);
+-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
++	mace->eth.dma_ctrl = priv->dma_ctrl;
+ 
+ 	meth_add_to_tx_ring(priv, skb);
+ 	dev->trans_start = jiffies; /* save the timestamp */
+@@ -711,9 +716,9 @@ static int meth_tx(struct sk_buff *skb, 
+ 
+ 	/* Restart DMA notification */
+ 	priv->dma_ctrl |= METH_DMA_TX_INT_EN;
+-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
++	mace->eth.dma_ctrl = priv->dma_ctrl;
+ 
+-	spin_unlock_irqrestore(&priv->meth_lock,flags);
++	spin_unlock_irqrestore(&priv->meth_lock, flags);
+ 
+ 	return 0;
+ }
+@@ -743,11 +748,11 @@ static void meth_tx_timeout(struct net_d
+ 	meth_init_rx_ring(priv);
+ 
+ 	/* Restart dma */
+-	priv->dma_ctrl|=METH_DMA_TX_EN|METH_DMA_RX_EN|METH_DMA_RX_INT_EN;
+-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
++	priv->dma_ctrl |= METH_DMA_TX_EN | METH_DMA_RX_EN | METH_DMA_RX_INT_EN;
++	mace->eth.dma_ctrl = priv->dma_ctrl;
+ 
+ 	/* Enable interrupt */
+-	spin_unlock_irqrestore(&priv->meth_lock,flags);
++	spin_unlock_irqrestore(&priv->meth_lock, flags);
+ 
+ 	dev->trans_start = jiffies;
+ 	netif_wake_queue(dev);
+@@ -760,8 +765,14 @@ static void meth_tx_timeout(struct net_d
+  */
+ static int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ {
+-	DPRINTK("ioctl\n");
+-	return 0;
++	/* XXX Not yet implemented */
++	switch(cmd) { 
++	case SIOCGMIIPHY:
++	case SIOCGMIIREG:
++	case SIOCSMIIREG:
++	default:
++		return -EOPNOTSUPP;
++	}
+ }
+ 
+ /*
+@@ -808,7 +819,7 @@ static struct net_device *meth_init(void
+ 	}
+ 
+ 	printk(KERN_INFO "%s: SGI MACE Ethernet rev. %d\n",
+-	       dev->name, (unsigned int)mace_eth_read(mac_ctrl) >> 29);
++	       dev->name, (unsigned int)(mace->eth.mac_ctrl >> 29));
+ 	return 0;
+ }
+ 
+diff -urpNX dontdiff linux-2.6.10/drivers/net/meth.h linux-2.6.10-mips/drivers/net/meth.h
+--- linux-2.6.10/drivers/net/meth.h	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/meth.h	2004-09-21 13:10:38.000000000 +0200
+@@ -29,7 +29,7 @@
+ #define RX_BUCKET_SIZE 256
+ 
+ #undef BIT
+-#define BIT(x)	(1 << (x))
++#define BIT(x)	(1UL << (x))
+ 
+ /* For more detailed explanations of what each field menas,
+    see Nick's great comments to #defines below (or docs, if
+diff -urpNX dontdiff linux-2.6.10/drivers/net/mv643xx_eth.c linux-2.6.10-mips/drivers/net/mv643xx_eth.c
+--- linux-2.6.10/drivers/net/mv643xx_eth.c	2004-12-24 22:34:31.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/mv643xx_eth.c	2004-12-17 10:35:53.000000000 +0100
+@@ -1349,7 +1349,6 @@ static struct net_device *mv64340_eth_in
+ 
+ #ifdef MV64340_CHECKSUM_OFFLOAD_TX
+ #ifdef MAX_SKB_FRAGS
+-#ifndef CONFIG_JAGUAR_DMALOW
+         /*
+          * Zero copy can only work if we use Discovery II memory. Else, we will
+          * have to map the buffers to ISA memory which is only 16 MB
+@@ -1357,7 +1356,6 @@ static struct net_device *mv64340_eth_in
+         dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HW_CSUM;
+ #endif
+ #endif
+-#endif
+ 
+ 	mp->port_num = port_num;
+ 
+diff -urpNX dontdiff linux-2.6.10/drivers/net/s2io.c linux-2.6.10-mips/drivers/net/s2io.c
+--- linux-2.6.10/drivers/net/s2io.c	2004-12-24 22:35:01.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/s2io.c	2004-12-29 17:12:00.000000000 +0100
+@@ -40,28 +40,29 @@
+  * in PCI Configuration space.
+  ************************************************************************/
+ 
+-#include<linux/config.h>
+-#include<linux/module.h>
+-#include<linux/types.h>
+-#include<linux/errno.h>
+-#include<linux/ioport.h>
+-#include<linux/pci.h>
+-#include<linux/kernel.h>
+-#include<linux/netdevice.h>
+-#include<linux/etherdevice.h>
+-#include<linux/skbuff.h>
+-#include<linux/init.h>
+-#include<linux/delay.h>
+-#include<linux/stddef.h>
+-#include<linux/ioctl.h>
+-#include<linux/timex.h>
+-#include<linux/sched.h>
+-#include<linux/ethtool.h>
+-#include<asm/system.h>
+-#include<asm/uaccess.h>
+-#include<linux/version.h>
+-#include<asm/io.h>
+-#include<linux/workqueue.h>
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/ioport.h>
++#include <linux/pci.h>
++#include <linux/kernel.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/stddef.h>
++#include <linux/ioctl.h>
++#include <linux/timex.h>
++#include <linux/sched.h>
++#include <linux/ethtool.h>
++#include <linux/version.h>
++#include <linux/workqueue.h>
++
++#include <asm/io.h>
++#include <asm/system.h>
++#include <asm/uaccess.h>
+ 
+ /* local include */
+ #include "s2io.h"
+diff -urpNX dontdiff linux-2.6.10/drivers/net/saa9730.c linux-2.6.10-mips/drivers/net/saa9730.c
+--- linux-2.6.10/drivers/net/saa9730.c	2004-12-24 22:34:58.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/saa9730.c	2004-12-28 20:06:42.000000000 +0100
+@@ -2,8 +2,6 @@
+  * Carsten Langgaard, carstenl at mips.com
+  * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+  *
+- * ########################################################################
+- *
+  *  This program is free software; you can distribute it and/or modify it
+  *  under the terms of the GNU General Public License (Version 2) as
+  *  published by the Free Software Foundation.
+@@ -17,8 +15,6 @@
+  *  with this program; if not, write to the Free Software Foundation, Inc.,
+  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+  *
+- * ########################################################################
+- *
+  * SAA9730 ethernet driver.
+  *
+  * Changes:
+@@ -51,7 +47,7 @@ int lan_saa9730_debug;
+ #define DRV_MODULE_NAME "saa9730"
+ 
+ static struct pci_device_id saa9730_pci_tbl[] = {
+-	{ PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA9370,
++	{ PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA9730,
+           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ 	{ 0, }
+ };
+@@ -98,13 +94,13 @@ static void evm_saa9730_unblock_lan_int(
+ 	     &lp->evm_saa9730_regs->InterruptBlock1);
+ }
+ 
+-static void show_saa9730_regs(struct lan_saa9730_private *lp)
++static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp)
+ {
+ 	int i, j;
+-	printk("TxmBufferA = %x\n", lp->TxmBuffer[0][0]);
+-	printk("TxmBufferB = %x\n", lp->TxmBuffer[1][0]);
+-	printk("RcvBufferA = %x\n", lp->RcvBuffer[0][0]);
+-	printk("RcvBufferB = %x\n", lp->RcvBuffer[1][0]);
++	printk("TxmBufferA = %p\n", lp->TxmBuffer[0][0]);
++	printk("TxmBufferB = %p\n", lp->TxmBuffer[1][0]);
++	printk("RcvBufferA = %p\n", lp->RcvBuffer[0][0]);
++	printk("RcvBufferB = %p\n", lp->RcvBuffer[1][0]);
+ 	for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
+ 		for (j = 0; j < LAN_SAA9730_TXM_Q_SIZE; j++) {
+ 			printk("TxmBuffer[%d][%d] = %x\n", i, j,
+@@ -214,33 +210,12 @@ static void lan_saa9730_buffer_init(stru
+ 	}
+ }
+ 
+-static int lan_saa9730_allocate_buffers(struct lan_saa9730_private *lp)
++static int lan_saa9730_allocate_buffers(struct pci_dev *pdev, struct lan_saa9730_private *lp)
+ {
+-	unsigned int mem_size;
+ 	void *Pa;
+ 	unsigned int i, j, RcvBufferSize, TxmBufferSize;
+-	unsigned int buffer_start;
+-
+-	/* 
+-	 * Allocate all RX and TX packets in one chunk. 
+-	 * The Rx and Tx packets must be PACKET_SIZE aligned.
+-	 */
+-	mem_size = ((LAN_SAA9730_RCV_Q_SIZE + LAN_SAA9730_TXM_Q_SIZE) *
+-		    LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_BUFFERS) +
+-	    LAN_SAA9730_PACKET_SIZE;
+-	buffer_start =
+-	    (unsigned int) kmalloc(mem_size, GFP_DMA | GFP_KERNEL);
+ 
+-	if (!buffer_start)
+-		return -ENOMEM;
+-
+-	/* 
+-	 * Set DMA buffer to kseg1 (uncached).
+-	 * Make sure to flush before using it uncached.
+-	 */
+-	Pa = (void *) KSEG1ADDR((buffer_start + LAN_SAA9730_PACKET_SIZE) &
+-				~(LAN_SAA9730_PACKET_SIZE - 1));
+-	dma_cache_wback_inv((unsigned long) Pa, mem_size);
++	Pa = (void *)ALIGN((unsigned long)lp->buffer_start, LAN_SAA9730_PACKET_SIZE);
+ 
+ 	/* Initialize buffer space */
+ 	RcvBufferSize = LAN_SAA9730_PACKET_SIZE;
+@@ -248,13 +223,14 @@ static int lan_saa9730_allocate_buffers(
+ 	lp->DmaRcvPackets = LAN_SAA9730_RCV_Q_SIZE;
+ 	lp->DmaTxmPackets = LAN_SAA9730_TXM_Q_SIZE;
+ 
++	
+ 	/* Init RX buffers */
+ 	for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
+ 		for (j = 0; j < LAN_SAA9730_RCV_Q_SIZE; j++) {
+ 			*(unsigned int *) Pa =
+ 			    cpu_to_le32(RXSF_READY <<
+ 					RX_STAT_CTL_OWNER_SHF);
+-			lp->RcvBuffer[i][j] = (unsigned int) Pa;
++			lp->RcvBuffer[i][j] = Pa;
+ 			Pa += RcvBufferSize;
+ 		}
+ 	}
+@@ -265,7 +241,7 @@ static int lan_saa9730_allocate_buffers(
+ 			*(unsigned int *) Pa =
+ 			    cpu_to_le32(TXSF_EMPTY <<
+ 					TX_STAT_CTL_OWNER_SHF);
+-			lp->TxmBuffer[i][j] = (unsigned int) Pa;
++			lp->TxmBuffer[i][j] = Pa;
+ 			Pa += TxmBufferSize;
+ 		}
+ 	}
+@@ -274,16 +250,14 @@ static int lan_saa9730_allocate_buffers(
+ 	 * Set rx buffer A and rx buffer B to point to the first two buffer 
+ 	 * spaces.
+ 	 */
+-	OUTL(PHYSADDR(lp->RcvBuffer[0][0]),
+-	     &lp->lan_saa9730_regs->RxBuffA);
+-	OUTL(PHYSADDR(lp->RcvBuffer[1][0]),
+-	     &lp->lan_saa9730_regs->RxBuffB);
++	OUTL(lp->dma_addr + (lp->RcvBuffer[0][0] - (void *)lp), &lp->lan_saa9730_regs->RxBuffA);
++	OUTL(lp->dma_addr + (lp->RcvBuffer[1][0] - (void *)lp), &lp->lan_saa9730_regs->RxBuffB);
+ 
+ 	/* Initialize Buffer Index */
+ 	lp->NextRcvPacketIndex = 0;
+ 	lp->NextRcvToUseIsA = 1;
+ 
+-	/* Set current buffer index & next availble packet index */
++	/* Set current buffer index & next available packet index */
+ 	lp->NextTxmPacketIndex = 0;
+ 	lp->NextTxmBufferIndex = 0;
+ 	lp->PendingTxmPacketIndex = 0;
+@@ -293,10 +267,8 @@ static int lan_saa9730_allocate_buffers(
+ 	 * Set txm_buf_a and txm_buf_b to point to the first two buffer
+ 	 * space 
+ 	 */
+-	OUTL(PHYSADDR(lp->TxmBuffer[0][0]),
+-	     &lp->lan_saa9730_regs->TxBuffA);
+-	OUTL(PHYSADDR(lp->TxmBuffer[1][0]),
+-	     &lp->lan_saa9730_regs->TxBuffB);
++	OUTL(lp->dma_addr + (lp->TxmBuffer[0][0] - (void *)lp), &lp->lan_saa9730_regs->TxBuffA);
++	OUTL(lp->dma_addr + (lp->TxmBuffer[1][0] - (void *)lp), &lp->lan_saa9730_regs->TxBuffB);
+ 
+ 	/* Set packet number */
+ 	OUTL((lp->DmaRcvPackets << PK_COUNT_RX_A_SHF) |
+@@ -328,8 +300,7 @@ static int lan_saa9730_cam_load(struct l
+ 
+ static int lan_saa9730_cam_init(struct net_device *dev)
+ {
+-	struct lan_saa9730_private *lp =
+-	    (struct lan_saa9730_private *) dev->priv;
++	struct lan_saa9730_private *lp = netdev_priv(dev);
+ 	unsigned int i;
+ 
+ 	/* Copy MAC-address into all entries. */
+@@ -572,8 +543,7 @@ static int lan_saa9730_restart(struct la
+ 
+ static int lan_saa9730_tx(struct net_device *dev)
+ {
+-	struct lan_saa9730_private *lp =
+-	    (struct lan_saa9730_private *) dev->priv;
++	struct lan_saa9730_private *lp = netdev_priv(dev);
+ 	unsigned int *pPacket;
+ 	unsigned int tx_status;
+ 
+@@ -649,8 +619,7 @@ static int lan_saa9730_tx(struct net_dev
+ 
+ static int lan_saa9730_rx(struct net_device *dev)
+ {
+-	struct lan_saa9730_private *lp =
+-	    (struct lan_saa9730_private *) dev->priv;
++	struct lan_saa9730_private *lp = netdev_priv(dev);
+ 	int len = 0;
+ 	struct sk_buff *skb = 0;
+ 	unsigned int rx_status;
+@@ -767,8 +736,7 @@ static irqreturn_t lan_saa9730_interrupt
+ 				  struct pt_regs *regs)
+ {
+ 	struct net_device *dev = (struct net_device *) dev_id;
+-	struct lan_saa9730_private *lp =
+-	    (struct lan_saa9730_private *) dev->priv;
++	struct lan_saa9730_private *lp = netdev_priv(dev);
+ 
+ 	if (lan_saa9730_debug > 5)
+ 		printk("lan_saa9730_interrupt\n");
+@@ -801,8 +769,7 @@ static int lan_saa9730_open_fail(struct 
+ 
+ static int lan_saa9730_open(struct net_device *dev)
+ {
+-	struct lan_saa9730_private *lp =
+-	    (struct lan_saa9730_private *) dev->priv;
++	struct lan_saa9730_private *lp = netdev_priv(dev);
+ 
+ 	/* Associate IRQ with lan_saa9730_interrupt */
+ 	if (request_irq(dev->irq, &lan_saa9730_interrupt, 0, "SAA9730 Eth",
+@@ -834,8 +801,7 @@ static int lan_saa9730_write(struct lan_
+ 	int PacketIndex;
+ 
+ 	if (lan_saa9730_debug > 5)
+-		printk("lan_saa9730_write: skb=%08x\n",
+-		       (unsigned int) skb);
++		printk("lan_saa9730_write: skb=%p\n", skb);
+ 
+ 	BufferIndex = lp->NextTxmBufferIndex;
+ 	PacketIndex = lp->NextTxmPacketIndex;
+@@ -879,8 +845,7 @@ static int lan_saa9730_write(struct lan_
+ 
+ static void lan_saa9730_tx_timeout(struct net_device *dev)
+ {
+-	struct lan_saa9730_private *lp =
+-	    (struct lan_saa9730_private *) dev->priv;
++	struct lan_saa9730_private *lp = netdev_priv(dev);
+ 
+ 	/* Transmitter timeout, serious problems */
+ 	lp->stats.tx_errors++;
+@@ -895,14 +860,13 @@ static void lan_saa9730_tx_timeout(struc
+ static int lan_saa9730_start_xmit(struct sk_buff *skb,
+ 				  struct net_device *dev)
+ {
+-	struct lan_saa9730_private *lp =
+-	    (struct lan_saa9730_private *) dev->priv;
++	struct lan_saa9730_private *lp = netdev_priv(dev);
+ 	unsigned long flags;
+ 	int skblen;
+ 	int len;
+ 
+ 	if (lan_saa9730_debug > 4)
+-		printk("Send packet: skb=%08x\n", (unsigned int) skb);
++		printk("Send packet: skb=%p\n", skb);
+ 
+ 	skblen = skb->len;
+ 
+@@ -912,8 +876,7 @@ static int lan_saa9730_start_xmit(struct
+ 
+ 	if (lan_saa9730_write(lp, skb, skblen)) {
+ 		spin_unlock_irqrestore(&lp->lock, flags);
+-		printk("Error when writing packet to controller: skb=%08x\n",
+-		     (unsigned int) skb);
++		printk("Error when writing packet to controller: skb=%p\n", skb);
+ 		netif_stop_queue(dev);
+ 		return -1;
+ 	}
+@@ -932,8 +895,7 @@ static int lan_saa9730_start_xmit(struct
+ 
+ static int lan_saa9730_close(struct net_device *dev)
+ {
+-	struct lan_saa9730_private *lp =
+-	    (struct lan_saa9730_private *) dev->priv;
++	struct lan_saa9730_private *lp = netdev_priv(dev);
+ 
+ 	if (lan_saa9730_debug > 1)
+ 		printk("lan_saa9730_close:\n");
+@@ -955,16 +917,14 @@ static int lan_saa9730_close(struct net_
+ static struct net_device_stats *lan_saa9730_get_stats(struct net_device
+ 						      *dev)
+ {
+-	struct lan_saa9730_private *lp =
+-	    (struct lan_saa9730_private *) dev->priv;
++	struct lan_saa9730_private *lp = netdev_priv(dev);
+ 
+ 	return &lp->stats;
+ }
+ 
+ static void lan_saa9730_set_multicast(struct net_device *dev)
+ {
+-	struct lan_saa9730_private *lp =
+-	    (struct lan_saa9730_private *) dev->priv;
++	struct lan_saa9730_private *lp = netdev_priv(dev);
+ 
+ 	/* Stop the controller */
+ 	lan_saa9730_stop(lp);
+@@ -997,10 +957,6 @@ static void __devexit saa9730_remove_one
+ 
+         if (dev) {
+                 unregister_netdev(dev);
+-
+-		if (dev->priv)
+-			kfree(dev->priv);
+-
+                 free_netdev(dev);
+                 pci_release_regions(pdev);
+                 pci_disable_device(pdev);
+@@ -1009,38 +965,27 @@ static void __devexit saa9730_remove_one
+ }
+ 
+ 
+-static int lan_saa9730_init(struct net_device *dev, int ioaddr, int irq)
++static int lan_saa9730_init(struct net_device *dev, struct pci_dev *pdev,
++	unsigned long ioaddr, int irq)
+ {
+-	struct lan_saa9730_private *lp;
++	struct lan_saa9730_private *lp = netdev_priv(dev);
++	dma_addr_t lp_dma_addr;
+ 	unsigned char ethernet_addr[6];
+ 	int ret = 0;
+ 
+ 	dev->open = lan_saa9730_open_fail;
+ 
+-	if (get_ethernet_addr(ethernet_addr))
+-		return -ENODEV;
+-	
++	if (get_ethernet_addr(ethernet_addr)) {
++		ret = -ENODEV;
++		goto out_free_netdev;
++	}
++
+ 	memcpy(dev->dev_addr, ethernet_addr, 6);
+ 	dev->base_addr = ioaddr;
+ 	dev->irq = irq;
+-	
+-	/* 
+-	 * Make certain the data structures used by the controller are aligned 
+-	 * and DMAble. 
+-	 */
+-	/*
+-	 *  XXX: that is obviously broken - kfree() won't be happy with us.
+-	 */
+-	lp = (struct lan_saa9730_private *) (((unsigned long)
+-					      kmalloc(sizeof(*lp) + 7,
+-						      GFP_DMA | GFP_KERNEL)
+-					      + 7) & ~7);
+-
+-	if (!lp)
+-		return -ENOMEM;
+ 
+-	dev->priv = lp;
+-	memset(lp, 0, sizeof(*lp));
++	lp->dma_addr = lp_dma_addr;
++	lp->pci_dev = pdev;
+ 
+ 	/* Set SAA9730 LAN base address. */
+ 	lp->lan_saa9730_regs = (t_lan_saa9730_regmap *) (ioaddr +
+@@ -1052,32 +997,32 @@ static int lan_saa9730_init(struct net_d
+ 
+ 	/* Allocate LAN RX/TX frame buffer space. */
+ 	/* FIXME: a leak */
+-	if ((ret = lan_saa9730_allocate_buffers(lp)))
+-		goto out;
++	if ((ret = lan_saa9730_allocate_buffers(pdev, lp)))
++		goto out_free_lp;
+ 
+ 	/* Stop LAN controller. */
+ 	if ((ret = lan_saa9730_stop(lp))) 
+-		goto out;
++		goto out_free_lp;
+ 	
+ 	/* Initialize CAM registers. */
+ 	if ((ret = lan_saa9730_cam_init(dev)))
+-		goto out;
++		goto out_free_lp;
+ 
+ 	/* Initialize MII registers. */
+ 	if ((ret = lan_saa9730_mii_init(lp)))
+-		goto out;
++		goto out_free_lp;
+ 
+ 	/* Initialize control registers. */
+ 	if ((ret = lan_saa9730_control_init(lp))) 
+-		goto out;
++		goto out_free_lp;
+         
+ 	/* Load CAM registers. */
+ 	if ((ret = lan_saa9730_cam_load(lp))) 
+-		goto out;
++		goto out_free_lp;
+ 	
+ 	/* Initialize DMA context registers. */
+ 	if ((ret = lan_saa9730_dma_init(lp)))
+-		goto out;
++		goto out_free_lp;
+ 	
+ 	spin_lock_init(&lp->lock);
+ 		
+@@ -1089,71 +1034,70 @@ static int lan_saa9730_init(struct net_d
+ 	dev->tx_timeout = lan_saa9730_tx_timeout;
+ 	dev->watchdog_timeo = (HZ >> 1);
+ 	dev->dma = 0;
+-	
+-	ret = register_netdev(dev);
++
++	ret = register_netdev (dev);
+ 	if (ret)
+-		goto out;
++		goto out_free_lp;
++	
+ 	return 0;
+ 
+- out:
+-	if (dev->priv)
+-		kfree(dev->priv);
++out_free_lp:
++	/* FIXME: a leak */
++out_free_netdev:
++	free_netdev(dev);
++
+ 	return ret;
+ }
+ 
+ 
+ static int __devinit saa9730_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+-	struct net_device *dev;
+-	unsigned int pci_ioaddr;
++	struct net_device *dev = NULL;
++	unsigned long pci_ioaddr;
+ 	int err;
+ 
+ 	if (lan_saa9730_debug > 1)
+ 		printk("saa9730.c: PCI bios is present, checking for devices...\n");
+ 
+-	err = -ENOMEM;
+-	dev = alloc_etherdev(0);
+-	if (!dev)
+-		goto out;
+-
+-	SET_MODULE_OWNER(dev);
+-
+ 	err = pci_enable_device(pdev);
+         if (err) {
+                 printk(KERN_ERR "Cannot enable PCI device, aborting.\n");
+-                goto out1;
++                goto out;
+         }
+ 
+ 	err = pci_request_regions(pdev, DRV_MODULE_NAME);
+ 	if (err) {
+ 		printk(KERN_ERR "Cannot obtain PCI resources, aborting.\n");
+-		goto out2;
++		goto out_disable_pdev;
+ 	}
+ 
+ 	pci_irq_line = pdev->irq;
+ 	/* LAN base address in located at BAR 1. */
+-
++	
+ 	pci_ioaddr = pci_resource_start(pdev, 1);
+ 	pci_set_master(pdev);
+-
+-	printk("Found SAA9730 (PCI) at %#x, irq %d.\n",
++	
++	printk("Found SAA9730 (PCI) at %lx, irq %d.\n",
+ 	       pci_ioaddr, pci_irq_line);
+ 
+-	err = lan_saa9730_init(dev, pci_ioaddr, pci_irq_line);
++	dev = alloc_etherdev(sizeof(struct lan_saa9730_private));
++	if (!dev) 
++		goto out_disable_pdev;
++	
++	err = lan_saa9730_init(dev, pdev, pci_ioaddr, pci_irq_line);
+ 	if (err) {
+ 		printk("Lan init failed");
+-		goto out2;
++		goto out_disable_pdev;
+ 	}
+-
++	
+ 	pci_set_drvdata(pdev, dev);
+ 	SET_NETDEV_DEV(dev, &pdev->dev);
+ 	return 0;
+ 	
+-out2:
++ out_disable_pdev:
+ 	pci_disable_device(pdev);
+-out1:
+-	free_netdev(dev);
+-out:
++ out:
++	pci_set_drvdata(pdev, NULL);
+ 	return err;
+ }
+ 
+@@ -1173,12 +1117,10 @@ static int __init saa9730_init(void)
+ 
+ static void __exit saa9730_cleanup(void)
+ {
+-        pci_unregister_driver(&saa9730_driver);
++	pci_unregister_driver(&saa9730_driver);
+ }
+ 
+ module_init(saa9730_init);
+ module_exit(saa9730_cleanup);
+ 
+-
+-
+ MODULE_LICENSE("GPL");
+diff -urpNX dontdiff linux-2.6.10/drivers/net/saa9730.h linux-2.6.10-mips/drivers/net/saa9730.h
+--- linux-2.6.10/drivers/net/saa9730.h	2004-12-24 22:35:20.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/saa9730.h	2003-11-16 09:20:53.000000000 +0100
+@@ -329,6 +329,17 @@ typedef volatile struct evm_saa9730_regm
+ 
+ 
+ struct lan_saa9730_private {
++	/* Rx/Tx packet buffers. The Rx and Tx packets must be PACKET_SIZE aligned. */
++	char	buffer_start[(LAN_SAA9730_RCV_Q_SIZE + LAN_SAA9730_TXM_Q_SIZE)
++			     * LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_BUFFERS
++			     + LAN_SAA9730_PACKET_SIZE - 1];
++
++	/* DMA address of beginning of this object, returned by pci_alloc_consistent */
++	dma_addr_t	dma_addr;
++
++	/* Pointer to the associated pci device structure */
++	struct pci_dev	*pci_dev;
++
+ 	/* Pointer for the SAA9730 LAN controller register set. */
+ 	t_lan_saa9730_regmap *lan_saa9730_regs;
+ 
+@@ -356,10 +367,8 @@ struct lan_saa9730_private {
+ 	unsigned char RcvAIndex;	/* index into RcvBufferSpace[] for Blk A */
+ 	unsigned char RcvBIndex;	/* index into RcvBufferSpace[] for Blk B */
+ 
+-	unsigned int
+-	    TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
+-	unsigned int
+-	    RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
++	void	      *TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
++	void	      *RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
+ 	unsigned int TxBufferFree[LAN_SAA9730_BUFFERS];
+ 
+ 	unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6];
+diff -urpNX dontdiff linux-2.6.10/drivers/net/sb1250-mac.c linux-2.6.10-mips/drivers/net/sb1250-mac.c
+--- linux-2.6.10/drivers/net/sb1250-mac.c	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/sb1250-mac.c	2005-01-03 16:08:18.000000000 +0100
+@@ -14,47 +14,11 @@
+  * 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.
++ *
++ *
++ * This driver is designed for the Broadcom SiByte SOC built-in
++ * Ethernet controllers. Written by Mitch Lichtenberg at Broadcom Corp.
+  */
+-
+-/*
+-  This driver is designed for the Broadcom SiByte SOC built-in
+-  Ethernet controllers.
+-  
+-  Written by Mitch Lichtenberg at Broadcom Corp.
+-*/
+-
+-
+-
+-#define CONFIG_SBMAC_COALESCE
+-
+-/* A few user-configurable values.
+-   These may be modified when a driver module is loaded. */
+-
+-static int debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */
+-static int noisy_mii = 1;		/* mii status msgs */
+-
+-/* Used to pass the media type, etc.
+-   Both 'options[]' and 'full_duplex[]' should exist for driver
+-   interoperability.
+-   The media type is usually passed in 'options[]'.
+-*/
+-
+-#define MAX_UNITS 3		/* More are supported, limit only on options */
+-#ifdef MODULE
+-static int options[MAX_UNITS] = {-1, -1, -1};
+-static int full_duplex[MAX_UNITS] = {-1, -1, -1};
+-#endif
+-
+-#ifdef CONFIG_SBMAC_COALESCE
+-static int int_pktcnt = 0;
+-static int int_timeout = 0;
+-#endif
+-
+-/* Operational parameters that usually are not changed. */
+-
+-/* Time in jiffies before concluding the transmitter is hung. */
+-#define TX_TIMEOUT  (2*HZ)
+-
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+@@ -89,16 +53,56 @@ static char version1[] __devinitdata =
+ #endif
+ 
+ 
++/* Operational parameters that usually are not changed. */
++
++#define CONFIG_SBMAC_COALESCE
++
++#define MAX_UNITS 3		/* More are supported, limit only on options */
++
++/* Time in jiffies before concluding the transmitter is hung. */
++#define TX_TIMEOUT  (2*HZ)
++
+ 
+ MODULE_AUTHOR("Mitch Lichtenberg (Broadcom Corp.)");
+ MODULE_DESCRIPTION("Broadcom SiByte SOC GB Ethernet driver");
+-MODULE_PARM(debug, "i");
+-MODULE_PARM(noisy_mii, "i");
+-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+ 
+-MODULE_PARM(int_pktcnt, "i");
+-MODULE_PARM(int_timeout, "i");
++/* A few user-configurable values which may be modified when a driver
++   module is loaded. */
++
++/* 1 normal messages, 0 quiet .. 7 verbose. */
++static int debug = 1;
++module_param(debug, int, S_IRUGO);
++MODULE_PARM_DESC(debug, "Debug messages");
++
++/* mii status msgs */
++static int noisy_mii = 1;
++module_param(noisy_mii, int, S_IRUGO);
++MODULE_PARM_DESC(noisy_mii, "MII status messages");
++
++/* Used to pass the media type, etc.
++   Both 'options[]' and 'full_duplex[]' should exist for driver
++   interoperability.
++   The media type is usually passed in 'options[]'.
++*/
++#ifdef MODULE
++static int options[MAX_UNITS] = {-1, -1, -1};
++module_param_array(options, int, NULL, S_IRUGO);
++MODULE_PARM_DESC(options, "1-" __MODULE_STRING(MAX_UNITS));
++
++static int full_duplex[MAX_UNITS] = {-1, -1, -1};
++module_param_array(full_duplex, int, NULL, S_IRUGO);
++MODULE_PARM_DESC(full_duplex, "1-" __MODULE_STRING(MAX_UNITS));
++#endif
++
++#ifdef CONFIG_SBMAC_COALESCE
++static int int_pktcnt = 0;
++module_param(int_pktcnt, int, S_IRUGO);
++MODULE_PARM_DESC(int_pktcnt, "Packet count");
++
++static int int_timeout = 0;
++module_param(int_timeout, int, S_IRUGO);
++MODULE_PARM_DESC(int_timeout, "Timeout value");
++#endif
+ 
+ #include <asm/sibyte/sb1250.h>
+ #include <asm/sibyte/sb1250_defs.h>
+@@ -1811,8 +1815,6 @@ static void sbmac_set_iphdr_offset(struc
+ 	
+ 	/* read system identification to determine revision */
+ 	if (periph_rev >= 2) {
+-		printk(KERN_INFO "%s: enabling TCP rcv checksum\n",
+-		       sc->sbm_dev->name);
+ 		sc->rx_hw_checksum = ENABLE;
+ 	} else {
+ 		sc->rx_hw_checksum = DISABLE;
+@@ -2417,6 +2419,11 @@ static int sbmac_init(struct net_device 
+ 	if (err)
+ 		goto out_uninit;
+ 
++	if (periph_rev >= 2) {
++		printk(KERN_INFO "%s: enabling TCP rcv checksum\n",
++			sc->sbm_dev->name);
++	}
++
+ 	/*
+ 	 * Display Ethernet address (this is called during the config
+ 	 * process so we need to finish off the config message that
+@@ -2879,12 +2886,12 @@ sbmac_init_module(void)
+ 		dev->mem_end = 0;
+ 		if (sbmac_init(dev, idx)) {
+ 			port = A_MAC_CHANNEL_BASE(idx);
+-			SBMAC_WRITECSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR),
+-					sbmac_orig_hwaddr[idx] );
++			SBMAC_WRITECSR(IOADDR(port+R_MAC_ETHERNET_ADDR),
++				       sbmac_orig_hwaddr[idx]);
+ 			free_netdev(dev);
+ 			continue;
+ 		}
+-		dev_sbmac[idx++] = dev;
++		dev_sbmac[idx] = dev;
+ 	}
+ 	return 0;
+ }
+diff -urpNX dontdiff linux-2.6.10/drivers/net/sgiseeq.c linux-2.6.10-mips/drivers/net/sgiseeq.c
+--- linux-2.6.10/drivers/net/sgiseeq.c	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/sgiseeq.c	2004-11-19 01:14:36.000000000 +0100
+@@ -136,9 +136,10 @@ static inline void seeq_go(struct sgisee
+ 	hregs->rx_ctrl = HPC3_ERXCTRL_ACTIVE;
+ }
+ 
+-static inline void seeq_load_eaddr(struct net_device *dev,
+-				   struct sgiseeq_regs *sregs)
++static inline void __sgiseeq_set_mac_address(struct net_device *dev)
+ {
++	struct sgiseeq_private *sp = netdev_priv(dev);
++	struct sgiseeq_regs *sregs = sp->sregs;
+ 	int i;
+ 
+ 	sregs->tstat = SEEQ_TCMD_RB0;
+@@ -146,6 +147,20 @@ static inline void seeq_load_eaddr(struc
+ 		sregs->rw.eth_addr[i] = dev->dev_addr[i];
+ }
+ 
++static int sgiseeq_set_mac_address(struct net_device *dev, void *addr)
++{
++	struct sgiseeq_private *sp = netdev_priv(dev);
++	struct sockaddr *sa = addr;
++
++	memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
++
++	spin_lock_irq(&sp->tx_lock);
++	__sgiseeq_set_mac_address(dev);
++	spin_unlock_irq(&sp->tx_lock);
++
++	return 0;
++}
++
+ #define TCNTINFO_INIT (HPCDMA_EOX | HPCDMA_ETXD)
+ #define RCNTCFG_INIT  (HPCDMA_OWN | HPCDMA_EORP | HPCDMA_XIE)
+ #define RCNTINFO_INIT (RCNTCFG_INIT | (PKT_BUF_SZ & HPCDMA_BCNT))
+@@ -159,13 +174,7 @@ static int seeq_init_ring(struct net_dev
+ 	sp->rx_new = sp->tx_new = 0;
+ 	sp->rx_old = sp->tx_old = 0;
+ 
+-	seeq_load_eaddr(dev, sp->sregs);
+-
+-	/* XXX for now just accept packets directly to us
+-	 * XXX and ether-broadcast.  Will do multicast and
+-	 * XXX promiscuous mode later. -davem
+-	 */
+-	sp->mode = SEEQ_RCMD_RBCAST;
++	__sgiseeq_set_mac_address(dev);
+ 
+ 	/* Setup tx ring. */
+ 	for(i = 0; i < SEEQ_TX_BUFFERS; i++) {
+@@ -175,7 +184,7 @@ static int seeq_init_ring(struct net_dev
+ 			buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
+ 			if (!buffer)
+ 				return -ENOMEM;
+-			sp->tx_desc[i].buf_vaddr = KSEG1ADDR(buffer);
++			sp->tx_desc[i].buf_vaddr = CKSEG1ADDR(buffer);
+ 			sp->tx_desc[i].tdma.pbuf = CPHYSADDR(buffer);
+ 		}
+ 		sp->tx_desc[i].tdma.cntinfo = TCNTINFO_INIT;
+@@ -189,7 +198,7 @@ static int seeq_init_ring(struct net_dev
+ 			buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
+ 			if (!buffer)
+ 				return -ENOMEM;
+-			sp->rx_desc[i].buf_vaddr = KSEG1ADDR(buffer);
++			sp->rx_desc[i].buf_vaddr = CKSEG1ADDR(buffer);
+ 			sp->rx_desc[i].rdma.pbuf = CPHYSADDR(buffer);
+ 		}
+ 		sp->rx_desc[i].rdma.cntinfo = RCNTINFO_INIT;
+@@ -331,10 +340,17 @@ static inline void sgiseeq_rx(struct net
+ 				/* Copy out of kseg1 to avoid silly cache flush. */
+ 				eth_copy_and_sum(skb, pkt_pointer + 2, len, 0);
+ 				skb->protocol = eth_type_trans(skb, dev);
+-				netif_rx(skb);
+-				dev->last_rx = jiffies;
+-				sp->stats.rx_packets++;
+-				sp->stats.rx_bytes += len;
++
++				/* We don't want to receive our own packets */
++				if (memcmp(eth_hdr(skb)->h_source, dev->dev_addr, ETH_ALEN)) {
++					netif_rx(skb);
++					dev->last_rx = jiffies;
++					sp->stats.rx_packets++;
++					sp->stats.rx_bytes += len;
++				} else {
++					/* Silently drop my own packets */
++					dev_kfree_skb_irq(skb);
++				}
+ 			} else {
+ 				printk (KERN_NOTICE "%s: Memory squeeze, deferring packet.\n",
+ 					dev->name);
+@@ -373,7 +389,7 @@ static inline void kick_tx(struct sgisee
+ 	 */
+ 	while ((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) ==
+ 	      (HPCDMA_XIU | HPCDMA_ETXD))
+-		td = (struct sgiseeq_tx_desc *)(long) KSEG1ADDR(td->tdma.pnext);
++		td = (struct sgiseeq_tx_desc *)(long) CKSEG1ADDR(td->tdma.pnext);
+ 	if (td->tdma.cntinfo & HPCDMA_XIU) {
+ 		hregs->tx_ndptr = CPHYSADDR(td);
+ 		hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
+@@ -583,6 +599,22 @@ static struct net_device_stats *sgiseeq_
+ 
+ static void sgiseeq_set_multicast(struct net_device *dev)
+ {
++	struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
++	unsigned char oldmode = sp->mode;
++
++	if(dev->flags & IFF_PROMISC)
++		sp->mode = SEEQ_RCMD_RANY;
++	else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count)
++		sp->mode = SEEQ_RCMD_RBMCAST;
++	else
++		sp->mode = SEEQ_RCMD_RBCAST;
++
++	/* XXX I know this sucks, but is there a better way to reprogram
++	 * XXX the receiver? At least, this shouldn't happen too often.
++	 */
++
++	if (oldmode != sp->mode)
++		sgiseeq_reset(dev);
+ }
+ 
+ static inline void setup_tx_ring(struct sgiseeq_tx_desc *buf, int nbufs)
+@@ -651,13 +683,14 @@ static int sgiseeq_init(struct hpc3_regs
+ 	sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0];
+ 	sp->hregs = &hpc3c0->ethregs;
+ 	sp->name = sgiseeqstr;
++	sp->mode = SEEQ_RCMD_RBCAST;
+ 
+ 	sp->rx_desc = (struct sgiseeq_rx_desc *)
+-	              KSEG1ADDR(ALIGNED(&sp->srings->rxvector[0]));
++	              CKSEG1ADDR(ALIGNED(&sp->srings->rxvector[0]));
+ 	dma_cache_wback_inv((unsigned long)&sp->srings->rxvector,
+ 	                    sizeof(sp->srings->rxvector));
+ 	sp->tx_desc = (struct sgiseeq_tx_desc *)
+-	              KSEG1ADDR(ALIGNED(&sp->srings->txvector[0]));
++	              CKSEG1ADDR(ALIGNED(&sp->srings->txvector[0]));
+ 	dma_cache_wback_inv((unsigned long)&sp->srings->txvector,
+ 	                    sizeof(sp->srings->txvector));
+ 
+@@ -681,6 +714,7 @@ static int sgiseeq_init(struct hpc3_regs
+ 	dev->watchdog_timeo	= (200 * HZ) / 1000;
+ 	dev->get_stats		= sgiseeq_get_stats;
+ 	dev->set_multicast_list	= sgiseeq_set_multicast;
++	dev->set_mac_address	= sgiseeq_set_mac_address;
+ 	dev->irq		= irq;
+ 
+ 	if (register_netdev(dev)) {
+diff -urpNX dontdiff linux-2.6.10/drivers/net/sonic.c linux-2.6.10-mips/drivers/net/sonic.c
+--- linux-2.6.10/drivers/net/sonic.c	2004-12-24 22:35:39.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/sonic.c	2004-10-09 20:50:28.000000000 +0200
+@@ -116,7 +116,7 @@ static int sonic_send_packet(struct sk_b
+ 	/*
+ 	 * Map the packet data into the logical DMA address space
+ 	 */
+-	if ((laddr = vdma_alloc(PHYSADDR(skb->data), skb->len)) == ~0UL) {
++	if ((laddr = vdma_alloc(CPHYSADDR(skb->data), skb->len)) == ~0UL) {
+ 		printk("%s: no VDMA entry for transmit available.\n",
+ 		       dev->name);
+ 		dev_kfree_skb(skb);
+@@ -223,7 +223,7 @@ static irqreturn_t sonic_interrupt(int i
+ 
+ 			/* We must free the original skb */
+ 			if (lp->tx_skb[entry]) {
+-				dev_kfree_skb(lp->tx_skb[entry]);
++				dev_kfree_skb_irq(lp->tx_skb[entry]);
+ 				lp->tx_skb[entry] = 0;
+ 			}
+ 			/* and the VDMA address */
+diff -urpNX dontdiff linux-2.6.10/drivers/net/titan_ge.c linux-2.6.10-mips/drivers/net/titan_ge.c
+--- linux-2.6.10/drivers/net/titan_ge.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/titan_ge.c	2005-01-09 13:24:00.000000000 +0100
+@@ -0,0 +1,2067 @@
++/*
++ * drivers/net/titan_ge.c - Driver for Titan ethernet ports
++ *
++ * Copyright (C) 2003 PMC-Sierra Inc.
++ * Author : Manish Lachwani (lachwani at pmc-sierra.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++ */
++
++/*
++ * The MAC unit of the Titan consists of the following:
++ *
++ * -> XDMA Engine to move data to from the memory to the MAC packet FIFO
++ * -> FIFO is where the incoming and outgoing data is placed
++ * -> TRTG is the unit that pulls the data from the FIFO for Tx and pushes
++ *    the data into the FIFO for Rx
++ * -> TMAC is the outgoing MAC interface and RMAC is the incoming.
++ * -> AFX is the address filtering block
++ * -> GMII block to communicate with the PHY
++ *
++ * Rx will look like the following:
++ * GMII --> RMAC --> AFX --> TRTG --> Rx FIFO --> XDMA --> CPU memory
++ *
++ * Tx will look like the following:
++ * CPU memory --> XDMA --> Tx FIFO --> TRTG --> TMAC --> GMII
++ *
++ * The Titan driver has support for the following performance features:
++ * -> Rx side checksumming
++ * -> Jumbo Frames
++ * -> Interrupt Coalscing
++ * -> Rx NAPI
++ * -> SKB Recycling
++ * -> Transmit/Receive descriptors in SRAM
++ * -> Fast routing for IP forwarding
++ */
++
++#include <linux/config.h>
++#include <linux/dma-mapping.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <linux/errno.h>
++#include <linux/ip.h>
++#include <linux/init.h>
++#include <linux/in.h>
++
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++#include <linux/mii.h>
++#include <linux/delay.h>
++#include <linux/skbuff.h>
++#include <linux/prefetch.h>
++
++/* For MII specifc registers, titan_mdio.h should be included */
++#include <net/ip.h>
++
++#include <asm/bitops.h>
++#include <asm/io.h>
++#include <asm/types.h>
++#include <asm/pgtable.h>
++#include <asm/system.h>
++#include <asm/titan_dep.h>
++
++#include "titan_ge.h"
++#include "titan_mdio.h"
++
++/* Static Function Declarations	 */
++static int titan_ge_eth_open(struct net_device *);
++static void titan_ge_eth_stop(struct net_device *);
++static struct net_device_stats *titan_ge_get_stats(struct net_device *);
++static int titan_ge_init_rx_desc_ring(titan_ge_port_info *, int, int,
++				      unsigned long, unsigned long,
++				      unsigned long);
++static int titan_ge_init_tx_desc_ring(titan_ge_port_info *, int,
++				      unsigned long, unsigned long);
++
++static int titan_ge_open(struct net_device *);
++static int titan_ge_start_xmit(struct sk_buff *, struct net_device *);
++static int titan_ge_stop(struct net_device *);
++
++static unsigned long titan_ge_tx_coal(unsigned long, int);
++
++static void titan_ge_port_reset(unsigned int);
++static int titan_ge_free_tx_queue(titan_ge_port_info *);
++static int titan_ge_rx_task(struct net_device *, titan_ge_port_info *);
++static int titan_ge_port_start(struct net_device *, titan_ge_port_info *);
++
++static int titan_ge_return_tx_desc(titan_ge_port_info *, int);
++
++/*
++ * Some configuration for the FIFO and the XDMA channel needs
++ * to be done only once for all the ports. This flag controls
++ * that
++ */
++static unsigned long config_done;
++
++/*
++ * One time out of memory flag
++ */
++static unsigned int oom_flag;
++
++static int titan_ge_poll(struct net_device *netdev, int *budget);
++
++static int titan_ge_receive_queue(struct net_device *, unsigned int);
++
++static struct platform_device *titan_ge_device[3];
++
++/* MAC Address */
++extern unsigned char titan_ge_mac_addr_base[6];
++
++unsigned long titan_ge_base;
++static unsigned long titan_ge_sram;
++
++static char titan_string[] = "titan";
++
++/*
++ * The Titan GE has two alignment requirements:
++ * -> skb->data to be cacheline aligned (32 byte)
++ * -> IP header alignment to 16 bytes
++ *
++ * The latter is not implemented. So, that results in an extra copy on
++ * the Rx. This is a big performance hog. For the former case, the
++ * dev_alloc_skb() has been replaced with titan_ge_alloc_skb(). The size
++ * requested is calculated:
++ *
++ * Ethernet Frame Size : 1518
++ * Ethernet Header     : 14
++ * Future Titan change for IP header alignment : 2
++ *
++ * Hence, we allocate (1518 + 14 + 2+ 64) = 1580 bytes.  For IP header
++ * alignment, we use skb_reserve().
++ */
++
++#define ALIGNED_RX_SKB_ADDR(addr) \
++	((((unsigned long)(addr) + (64UL - 1UL)) \
++	& ~(64UL - 1UL)) - (unsigned long)(addr))
++
++#define titan_ge_alloc_skb(__length, __gfp_flags) \
++({      struct sk_buff *__skb; \
++	__skb = alloc_skb((__length) + 64, (__gfp_flags)); \
++	if(__skb) { \
++		int __offset = (int) ALIGNED_RX_SKB_ADDR(__skb->data); \
++		if(__offset) \
++			skb_reserve(__skb, __offset); \
++	} \
++	__skb; \
++})
++
++/*
++ * Configure the GMII block of the Titan based on what the PHY tells us
++ */
++static void titan_ge_gmii_config(int port_num)
++{
++	unsigned int reg_data = 0, phy_reg;
++	int err;
++
++	err = titan_ge_mdio_read(port_num, TITAN_GE_MDIO_PHY_STATUS, &phy_reg);
++
++	if (err == TITAN_GE_MDIO_ERROR) {
++		printk(KERN_ERR
++		       "Could not read PHY control register 0x11 \n");
++		printk(KERN_ERR
++			"Setting speed to 1000 Mbps and Duplex to Full \n");
++
++		return;
++	}
++
++	err = titan_ge_mdio_write(port_num, TITAN_GE_MDIO_PHY_IE, 0);
++
++	if (phy_reg & 0x8000) {
++		if (phy_reg & 0x2000) {
++			/* Full Duplex and 1000 Mbps */
++			TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
++					(port_num << 12)), 0x201);
++		}  else {
++			/* Half Duplex and 1000 Mbps */
++			TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
++					(port_num << 12)), 0x2201);
++			}
++	}
++	if (phy_reg & 0x4000) {
++		if (phy_reg & 0x2000) {
++			/* Full Duplex and 100 Mbps */
++			TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
++					(port_num << 12)), 0x100);
++		} else {
++			/* Half Duplex and 100 Mbps */
++			TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_MODE +
++					(port_num << 12)), 0x2100);
++		}
++	}
++	reg_data = TITAN_GE_READ(TITAN_GE_GMII_CONFIG_GENERAL +
++				(port_num << 12));
++	reg_data |= 0x3;
++	TITAN_GE_WRITE((TITAN_GE_GMII_CONFIG_GENERAL +
++			(port_num << 12)), reg_data);
++}
++
++/*
++ * Enable the TMAC if it is not
++ */
++static void titan_ge_enable_tx(unsigned int port_num)
++{
++	unsigned long reg_data;
++
++	reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 + (port_num << 12));
++	if (!(reg_data & 0x8000)) {
++		printk("TMAC disabled for port %d!! \n", port_num);
++
++		reg_data |= 0x0001;	/* Enable TMAC */
++		reg_data |= 0x4000;	/* CRC Check Enable */
++		reg_data |= 0x2000;	/* Padding enable */
++		reg_data |= 0x0800;	/* CRC Add enable */
++		reg_data |= 0x0080;	/* PAUSE frame */
++
++		TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 +
++				(port_num << 12)), reg_data);
++	}
++}
++
++/*
++ * Tx Timeout function
++ */
++static void titan_ge_tx_timeout(struct net_device *netdev)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++
++	printk(KERN_INFO "%s: TX timeout  ", netdev->name);
++	printk(KERN_INFO "Resetting card \n");
++
++	/* Do the reset outside of interrupt context */
++	schedule_work(&titan_ge_eth->tx_timeout_task);
++}
++
++/*
++ * Update the AFX tables for UC and MC for slice 0 only
++ */
++static void titan_ge_update_afx(titan_ge_port_info * titan_ge_eth)
++{
++	int port = titan_ge_eth->port_num;
++	unsigned int i;
++	volatile unsigned long reg_data = 0;
++	u8 p_addr[6];
++
++	memcpy(p_addr, titan_ge_eth->port_mac_addr, 6);
++
++	/* Set the MAC address here for TMAC and RMAC */
++	TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_HI + (port << 12)),
++		       ((p_addr[5] << 8) | p_addr[4]));
++	TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_MID + (port << 12)),
++		       ((p_addr[3] << 8) | p_addr[2]));
++	TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_LOW + (port << 12)),
++		       ((p_addr[1] << 8) | p_addr[0]));
++
++	TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_HI + (port << 12)),
++		       ((p_addr[5] << 8) | p_addr[4]));
++	TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_MID + (port << 12)),
++		       ((p_addr[3] << 8) | p_addr[2]));
++	TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_LOW + (port << 12)),
++		       ((p_addr[1] << 8) | p_addr[0]));
++
++	TITAN_GE_WRITE((0x112c | (port << 12)), 0x1);
++	/* Configure the eight address filters */
++	for (i = 0; i < 8; i++) {
++		/* Select each of the eight filters */
++		TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_2 +
++				(port << 12)), i);
++
++		/* Configure the match */
++		reg_data = 0x9;	/* Forward Enable Bit */
++		TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_0 +
++				(port << 12)), reg_data);
++
++		/* Finally, AFX Exact Match Address Registers */
++		TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_LOW + (port << 12)),
++			       ((p_addr[1] << 8) | p_addr[0]));
++		TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_MID + (port << 12)),
++			       ((p_addr[3] << 8) | p_addr[2]));
++		TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_HIGH + (port << 12)),
++			       ((p_addr[5] << 8) | p_addr[4]));
++
++		/* VLAN id set to 0 */
++		TITAN_GE_WRITE((TITAN_GE_AFX_EXACT_MATCH_VID +
++				(port << 12)), 0);
++	}
++}
++
++/*
++ * Actual Routine to reset the adapter when the timeout occurred
++ */
++static void titan_ge_tx_timeout_task(struct net_device *netdev)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++	int port = titan_ge_eth->port_num;
++
++	printk("Titan GE: Transmit timed out. Resetting ... \n");
++
++	/* Dump debug info */
++	printk(KERN_ERR "TRTG cause : %x \n",
++			TITAN_GE_READ(0x100c + (port << 12)));
++
++	/* Fix this for the other ports */
++	printk(KERN_ERR "FIFO cause : %x \n", TITAN_GE_READ(0x482c));
++	printk(KERN_ERR "IE cause : %x \n", TITAN_GE_READ(0x0040));
++	printk(KERN_ERR "XDMA GDI ERROR : %x \n",
++			TITAN_GE_READ(0x5008 + (port << 8)));
++	printk(KERN_ERR "CHANNEL ERROR: %x \n",
++			TITAN_GE_READ(TITAN_GE_CHANNEL0_INTERRUPT
++						+ (port << 8)));
++
++	netif_device_detach(netdev);
++	titan_ge_port_reset(titan_ge_eth->port_num);
++	titan_ge_port_start(netdev, titan_ge_eth);
++	netif_device_attach(netdev);
++}
++
++/*
++ * Change the MTU of the Ethernet Device
++ */
++static int titan_ge_change_mtu(struct net_device *netdev, int new_mtu)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++	unsigned long flags;
++
++	if ((new_mtu > 9500) || (new_mtu < 64))
++		return -EINVAL;
++
++	spin_lock_irqsave(&titan_ge_eth->lock, flags);
++
++	netdev->mtu = new_mtu;
++
++	/* Now we have to reopen the interface so that SKBs with the new
++	 * size will be allocated */
++
++	if (netif_running(netdev)) {
++		titan_ge_eth_stop(netdev);
++
++		if (titan_ge_eth_open(netdev) != TITAN_OK) {
++			printk(KERN_ERR
++			       "%s: Fatal error on opening device\n",
++			       netdev->name);
++			spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++			return -1;
++		}
++	}
++
++	spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++	return 0;
++}
++
++/*
++ * Titan Gbe Interrupt Handler. All the three ports send interrupt to one line
++ * only. Once an interrupt is triggered, figure out the port and then check
++ * the channel.
++ */
++static irqreturn_t titan_ge_int_handler(int irq, void *dev_id,
++	struct pt_regs *regs)
++{
++	struct net_device *netdev = (struct net_device *) dev_id;
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++	unsigned int port_num = titan_ge_eth->port_num;
++	unsigned int reg_data;
++	unsigned int eth_int_cause_error = 0, is;
++	unsigned long eth_int_cause1;
++	int err = 0;
++#ifdef CONFIG_SMP
++	unsigned long eth_int_cause2;
++#endif
++
++	/* Ack the CPU interrupt */
++	switch (port_num) {
++	case 0:
++		is = OCD_READ(RM9000x2_OCD_INTP0STATUS1);
++		OCD_WRITE(RM9000x2_OCD_INTP0CLEAR1, is);
++
++#ifdef CONFIG_SMP
++		is = OCD_READ(RM9000x2_OCD_INTP1STATUS1);
++		OCD_WRITE(RM9000x2_OCD_INTP1CLEAR1, is);
++#endif
++		break;
++
++	case 1:
++		is = OCD_READ(RM9000x2_OCD_INTP0STATUS0);
++		OCD_WRITE(RM9000x2_OCD_INTP0CLEAR0, is);
++
++#ifdef CONFIG_SMP
++		is = OCD_READ(RM9000x2_OCD_INTP1STATUS0);
++		OCD_WRITE(RM9000x2_OCD_INTP1CLEAR0, is);
++#endif
++		break;
++
++	case 2:
++		is = OCD_READ(RM9000x2_OCD_INTP0STATUS4);
++		OCD_WRITE(RM9000x2_OCD_INTP0CLEAR4, is);
++
++#ifdef CONFIG_SMP
++		is = OCD_READ(RM9000x2_OCD_INTP1STATUS4);
++		OCD_WRITE(RM9000x2_OCD_INTP1CLEAR4, is);
++#endif
++	}
++
++	eth_int_cause1 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_A);
++#ifdef CONFIG_SMP
++	eth_int_cause2 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_B);
++#endif
++
++	/* Spurious interrupt */
++#ifdef CONFIG_SMP
++	if ( (eth_int_cause1 == 0) && (eth_int_cause2 == 0)) {
++#else
++	if (eth_int_cause1 == 0) {
++#endif
++		eth_int_cause_error = TITAN_GE_READ(TITAN_GE_CHANNEL0_INTERRUPT +
++					(port_num << 8));
++
++		if (eth_int_cause_error == 0)
++			return IRQ_NONE;
++	}
++
++	/* Handle Tx first. No need to ack interrupts */
++#ifdef CONFIG_SMP
++	if ( (eth_int_cause1 & 0x20202) ||
++		(eth_int_cause2 & 0x20202) )
++#else
++	if (eth_int_cause1 & 0x20202)
++#endif
++		titan_ge_free_tx_queue(titan_ge_eth);
++
++	/* Handle the Rx next */
++#ifdef CONFIG_SMP
++	if ( (eth_int_cause1 & 0x10101) ||
++		(eth_int_cause2 & 0x10101)) {
++#else
++	if (eth_int_cause1 & 0x10101) {
++#endif
++		if (netif_rx_schedule_prep(netdev)) {
++			unsigned int ack;
++
++			ack = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE);
++			/* Disable Tx and Rx both */
++			if (port_num == 0)
++				ack &= ~(0x3);
++			if (port_num == 1)
++				ack &= ~(0x300);
++
++			if (port_num == 2)
++				ack &= ~(0x30000);
++
++			/* Interrupts have been disabled */
++			TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, ack);
++
++			__netif_rx_schedule(netdev);
++		}
++	}
++
++	/* Handle error interrupts */
++	if (eth_int_cause_error && (eth_int_cause_error != 0x2)) {
++		printk(KERN_ERR
++			"XDMA Channel Error : %x  on port %d\n",
++			eth_int_cause_error, port_num);
++
++		printk(KERN_ERR
++			"XDMA GDI Hardware error : %x  on port %d\n",
++			TITAN_GE_READ(0x5008 + (port_num << 8)), port_num);
++
++		printk(KERN_ERR
++			"XDMA currently has %d Rx descriptors \n",
++			TITAN_GE_READ(0x5048 + (port_num << 8)));
++
++		printk(KERN_ERR
++			"XDMA currently has prefetcted %d Rx descriptors \n",
++			TITAN_GE_READ(0x505c + (port_num << 8)));
++
++		TITAN_GE_WRITE((TITAN_GE_CHANNEL0_INTERRUPT +
++			       (port_num << 8)), eth_int_cause_error);
++	}
++
++	/*
++	 * PHY interrupt to inform abt the changes. Reading the
++	 * PHY Status register will clear the interrupt
++	 */
++	if ((!(eth_int_cause1 & 0x30303)) &&
++		(eth_int_cause_error == 0)) {
++		err =
++		    titan_ge_mdio_read(port_num,
++			       TITAN_GE_MDIO_PHY_IS, &reg_data);
++
++		if (reg_data & 0x0400) {
++			/* Link status change */
++			titan_ge_mdio_read(port_num,
++				   TITAN_GE_MDIO_PHY_STATUS, &reg_data);
++			if (!(reg_data & 0x0400)) {
++				/* Link is down */
++				netif_carrier_off(netdev);
++				netif_stop_queue(netdev);
++			} else {
++				/* Link is up */
++				netif_carrier_on(netdev);
++				netif_wake_queue(netdev);
++
++				/* Enable the queue */
++				titan_ge_enable_tx(port_num);
++			}
++		}
++	}
++
++	return IRQ_HANDLED;
++}
++
++/*
++ * Multicast and Promiscuous mode set. The
++ * set_multi entry point is called whenever the
++ * multicast address list or the network interface
++ * flags are updated.
++ */
++static void titan_ge_set_multi(struct net_device *netdev)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++	unsigned int port_num = titan_ge_eth->port_num;
++	unsigned long reg_data;
++
++	reg_data = TITAN_GE_READ(TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 +
++				(port_num << 12));
++
++	if (netdev->flags & IFF_PROMISC) {
++		reg_data |= 0x2;
++	}
++	else if (netdev->flags & IFF_ALLMULTI) {
++		reg_data |= 0x01;
++		reg_data |= 0x400; /* Use the 64-bit Multicast Hash bin */
++	}
++	else {
++		reg_data = 0x2;
++	}
++
++	TITAN_GE_WRITE((TITAN_GE_AFX_ADDRS_FILTER_CTRL_1 +
++			(port_num << 12)), reg_data);
++	if (reg_data & 0x01) {
++		TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_LOW +
++				(port_num << 12)), 0xffff);
++		TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_MIDLOW +
++				(port_num << 12)), 0xffff);
++		TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_MIDHI +
++				(port_num << 12)), 0xffff);
++		TITAN_GE_WRITE((TITAN_GE_AFX_MULTICAST_HASH_HI +
++				(port_num << 12)), 0xffff);
++	}
++}
++
++/*
++ * Open the network device
++ */
++static int titan_ge_open(struct net_device *netdev)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++	unsigned int port_num = titan_ge_eth->port_num;
++	unsigned int irq = TITAN_ETH_PORT_IRQ - port_num;
++	int retval;
++
++	retval = request_irq(irq, titan_ge_int_handler,
++		     SA_INTERRUPT | SA_SAMPLE_RANDOM , netdev->name, netdev);
++
++	if (retval != 0) {
++		printk(KERN_ERR "Cannot assign IRQ number to TITAN GE \n");
++		return -1;
++	}
++
++	netdev->irq = irq;
++	printk(KERN_INFO "Assigned IRQ %d to port %d\n", irq, port_num);
++
++	spin_lock_irq(&(titan_ge_eth->lock));
++
++	if (titan_ge_eth_open(netdev) != TITAN_OK) {
++		spin_unlock_irq(&(titan_ge_eth->lock));
++		printk("%s: Error opening interface \n", netdev->name);
++		free_irq(netdev->irq, netdev);
++		return -EBUSY;
++	}
++
++	spin_unlock_irq(&(titan_ge_eth->lock));
++
++	return 0;
++}
++
++/*
++ * Allocate the SKBs for the Rx ring. Also used
++ * for refilling the queue
++ */
++static int titan_ge_rx_task(struct net_device *netdev,
++				titan_ge_port_info *titan_ge_port)
++{
++	struct device *device = &titan_ge_device[titan_ge_port->port_num]->dev;
++	volatile titan_ge_rx_desc *rx_desc;
++	struct sk_buff *skb;
++	int rx_used_desc;
++	int count = 0;
++
++	while (titan_ge_port->rx_ring_skbs < titan_ge_port->rx_ring_size) {
++
++	/* First try to get the skb from the recycler */
++#ifdef TITAN_GE_JUMBO_FRAMES
++		skb = titan_ge_alloc_skb(TITAN_GE_JUMBO_BUFSIZE, GFP_ATOMIC);
++#else
++		skb = titan_ge_alloc_skb(TITAN_GE_STD_BUFSIZE, GFP_ATOMIC);
++#endif
++		if (unlikely(!skb)) {
++			/* OOM, set the flag */
++			printk("OOM \n");
++			oom_flag = 1;
++			break;
++		}
++		count++;
++		skb->dev = netdev;
++
++		titan_ge_port->rx_ring_skbs++;
++
++		rx_used_desc = titan_ge_port->rx_used_desc_q;
++		rx_desc = &(titan_ge_port->rx_desc_area[rx_used_desc]);
++
++#ifdef TITAN_GE_JUMBO_FRAMES
++		rx_desc->buffer_addr = dma_map_single(device, skb->data,
++				TITAN_GE_JUMBO_BUFSIZE - 2, DMA_FROM_DEVICE);
++#else
++		rx_desc->buffer_addr = dma_map_single(device, skb->data,
++				TITAN_GE_STD_BUFSIZE - 2, DMA_FROM_DEVICE);
++#endif
++
++		titan_ge_port->rx_skb[rx_used_desc] = skb;
++		rx_desc->cmd_sts = TITAN_GE_RX_BUFFER_OWNED;
++
++		titan_ge_port->rx_used_desc_q =
++			(rx_used_desc + 1) % TITAN_GE_RX_QUEUE;
++	}
++
++	return count;
++}
++
++/*
++ * Actual init of the Tital GE port. There is one register for
++ * the channel configuration
++ */
++static void titan_port_init(struct net_device *netdev,
++			    titan_ge_port_info * titan_ge_eth)
++{
++	unsigned long reg_data;
++
++	titan_ge_port_reset(titan_ge_eth->port_num);
++
++	/* First reset the TMAC */
++	reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
++	reg_data |= 0x80000000;
++	TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
++
++	udelay(30);
++
++	reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
++	reg_data &= ~(0xc0000000);
++	TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
++
++	/* Now reset the RMAC */
++	reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
++	reg_data |= 0x00080000;
++	TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
++
++	udelay(30);
++
++	reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG);
++	reg_data &= ~(0x000c0000);
++	TITAN_GE_WRITE(TITAN_GE_CHANNEL0_CONFIG, reg_data);
++}
++
++/*
++ * Start the port. All the hardware specific configuration
++ * for the XDMA, Tx FIFO, Rx FIFO, TMAC, RMAC, TRTG and AFX
++ * go here
++ */
++static int titan_ge_port_start(struct net_device *netdev,
++				titan_ge_port_info * titan_port)
++{
++	volatile unsigned long reg_data, reg_data1;
++	int port_num = titan_port->port_num;
++	int count = 0;
++	unsigned long reg_data_1;
++
++	if (config_done == 0) {
++		reg_data = TITAN_GE_READ(0x0004);
++		reg_data |= 0x100;
++		TITAN_GE_WRITE(0x0004, reg_data);
++
++		reg_data &= ~(0x100);
++		TITAN_GE_WRITE(0x0004, reg_data);
++
++		/* Turn on GMII/MII mode and turn off TBI mode */
++		reg_data = TITAN_GE_READ(TITAN_GE_TSB_CTRL_1);
++		reg_data |= 0x00000700;
++		reg_data &= ~(0x00800000); /* Fencing */
++
++		TITAN_GE_WRITE(0x000c, 0x00001100);
++
++		TITAN_GE_WRITE(TITAN_GE_TSB_CTRL_1, reg_data);
++
++		/* Set the CPU Resource Limit register */
++		TITAN_GE_WRITE(0x00f8, 0x8);
++
++		/* Be conservative when using the BIU buffers */
++		TITAN_GE_WRITE(0x0068, 0x4);
++	}
++
++	titan_port->tx_threshold = 0;
++	titan_port->rx_threshold = 0;
++
++	/* We need to write the descriptors for Tx and Rx */
++	TITAN_GE_WRITE((TITAN_GE_CHANNEL0_TX_DESC + (port_num << 8)),
++		       (unsigned long) titan_port->tx_dma);
++	TITAN_GE_WRITE((TITAN_GE_CHANNEL0_RX_DESC + (port_num << 8)),
++		       (unsigned long) titan_port->rx_dma);
++
++	if (config_done == 0) {
++		/* Step 1:  XDMA config	*/
++		reg_data = TITAN_GE_READ(TITAN_GE_XDMA_CONFIG);
++		reg_data &= ~(0x80000000);      /* clear reset */
++		reg_data |= 0x1 << 29;	/* sparse tx descriptor spacing */
++		reg_data |= 0x1 << 28;	/* sparse rx descriptor spacing */
++		reg_data |= (0x1 << 23) | (0x1 << 24);  /* Descriptor Coherency */
++		reg_data |= (0x1 << 21) | (0x1 << 22);  /* Data Coherency */
++		TITAN_GE_WRITE(TITAN_GE_XDMA_CONFIG, reg_data);
++	}
++
++	/* IR register for the XDMA */
++	reg_data = TITAN_GE_READ(TITAN_GE_GDI_INTERRUPT_ENABLE + (port_num << 8));
++	reg_data |= 0x80068000; /* No Rx_OOD */
++	TITAN_GE_WRITE((TITAN_GE_GDI_INTERRUPT_ENABLE + (port_num << 8)), reg_data);
++
++	/* Start the Tx and Rx XDMA controller */
++	reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG + (port_num << 8));
++	reg_data &= 0x4fffffff;     /* Clear tx reset */
++	reg_data &= 0xfff4ffff;     /* Clear rx reset */
++
++#ifdef TITAN_GE_JUMBO_FRAMES
++	reg_data |= 0xa0 | 0x30030000;
++#else
++	reg_data |= 0x40 | 0x20030000;
++#endif
++
++#ifndef CONFIG_SMP
++	reg_data &= ~(0x10);
++	reg_data |= 0x0f; /* All of the packet */
++#endif
++
++	TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG + (port_num << 8)), reg_data);
++
++	/* Rx desc count */
++	count = titan_ge_rx_task(netdev, titan_port);
++	TITAN_GE_WRITE((0x5048 + (port_num << 8)), count);
++	count = TITAN_GE_READ(0x5048 + (port_num << 8));
++
++	udelay(30);
++
++	/*
++	 * Step 2:  Configure the SDQPF, i.e. FIFO
++	 */
++	if (config_done == 0) {
++		reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_CTL);
++		reg_data = 0x1;
++		TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data);
++		reg_data &= ~(0x1);
++		TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data);
++		reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_CTL);
++		TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_CTL, reg_data);
++
++		reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_CTL);
++		reg_data = 0x1;
++		TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data);
++		reg_data &= ~(0x1);
++		TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data);
++		reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_CTL);
++		TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_CTL, reg_data);
++	}
++	/*
++	 * Enable RX FIFO 0, 4 and 8
++	 */
++	if (port_num == 0) {
++		reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_RXFIFO_0);
++
++		reg_data |= 0x100000;
++		reg_data |= (0xff << 10);
++
++		TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_0, reg_data);
++		/*
++		 * BAV2,BAV and DAV settings for the Rx FIFO
++		 */
++		reg_data1 = TITAN_GE_READ(0x4844);
++		reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
++		TITAN_GE_WRITE(0x4844, reg_data1);
++
++		reg_data &= ~(0x00100000);
++		reg_data |= 0x200000;
++
++		TITAN_GE_WRITE(TITAN_GE_SDQPF_RXFIFO_0, reg_data);
++
++		reg_data = TITAN_GE_READ(TITAN_GE_SDQPF_TXFIFO_0);
++		reg_data |= 0x100000;
++
++		TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data);
++
++		reg_data |= (0xff << 10);
++
++		TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data);
++
++		/*
++		 * BAV2, BAV and DAV settings for the Tx FIFO
++		 */
++		reg_data1 = TITAN_GE_READ(0x4944);
++		reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
++
++		TITAN_GE_WRITE(0x4944, reg_data1);
++
++		reg_data &= ~(0x00100000);
++		reg_data |= 0x200000;
++
++		TITAN_GE_WRITE(TITAN_GE_SDQPF_TXFIFO_0, reg_data);
++
++	}
++
++	if (port_num == 1) {
++		reg_data = TITAN_GE_READ(0x4870);
++
++		reg_data |= 0x100000;
++		reg_data |= (0xff << 10) | (0xff + 1);
++
++		TITAN_GE_WRITE(0x4870, reg_data);
++		/*
++		 * BAV2,BAV and DAV settings for the Rx FIFO
++		 */
++		reg_data1 = TITAN_GE_READ(0x4874);
++		reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
++		TITAN_GE_WRITE(0x4874, reg_data1);
++
++		reg_data &= ~(0x00100000);
++		reg_data |= 0x200000;
++
++		TITAN_GE_WRITE(0x4870, reg_data);
++
++		reg_data = TITAN_GE_READ(0x494c);
++		reg_data |= 0x100000;
++
++		TITAN_GE_WRITE(0x494c, reg_data);
++		reg_data |= (0xff << 10) | (0xff + 1);
++		TITAN_GE_WRITE(0x494c, reg_data);
++
++		/*
++		 * BAV2, BAV and DAV settings for the Tx FIFO
++		 */
++		reg_data1 = TITAN_GE_READ(0x4950);
++		reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
++
++		TITAN_GE_WRITE(0x4950, reg_data1);
++
++		reg_data &= ~(0x00100000);
++		reg_data |= 0x200000;
++
++		TITAN_GE_WRITE(0x494c, reg_data);
++	}
++
++	/*
++	 * Titan 1.2 revision does support port #2
++	 */
++	if (port_num == 2) {
++		/*
++		 * Put the descriptors in the SRAM
++		 */
++		reg_data = TITAN_GE_READ(0x48a0);
++
++		reg_data |= 0x100000;
++		reg_data |= (0xff << 10) | (2*(0xff + 1));
++
++		TITAN_GE_WRITE(0x48a0, reg_data);
++		/*
++		 * BAV2,BAV and DAV settings for the Rx FIFO
++		 */
++		reg_data1 = TITAN_GE_READ(0x48a4);
++		reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
++		TITAN_GE_WRITE(0x48a4, reg_data1);
++
++		reg_data &= ~(0x00100000);
++		reg_data |= 0x200000;
++
++		TITAN_GE_WRITE(0x48a0, reg_data);
++		
++		reg_data = TITAN_GE_READ(0x4958);
++		reg_data |= 0x100000;
++
++		TITAN_GE_WRITE(0x4958, reg_data);
++		reg_data |= (0xff << 10) | (2*(0xff + 1));
++		TITAN_GE_WRITE(0x4958, reg_data);
++
++		/*
++		 * BAV2, BAV and DAV settings for the Tx FIFO
++		 */
++		reg_data1 = TITAN_GE_READ(0x495c);
++		reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
++
++		TITAN_GE_WRITE(0x495c, reg_data1);
++
++		reg_data &= ~(0x00100000);
++		reg_data |= 0x200000;
++
++		TITAN_GE_WRITE(0x4958, reg_data);
++	}
++
++	if (port_num == 2) {
++		reg_data = TITAN_GE_READ(0x48a0);
++
++		reg_data |= 0x100000;
++		reg_data |= (0xff << 10) | (2*(0xff + 1));
++
++		TITAN_GE_WRITE(0x48a0, reg_data);
++		/*
++		 * BAV2,BAV and DAV settings for the Rx FIFO
++		 */
++		reg_data1 = TITAN_GE_READ(0x48a4);
++		reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
++		TITAN_GE_WRITE(0x48a4, reg_data1);
++
++		reg_data &= ~(0x00100000);
++		reg_data |= 0x200000;
++
++		TITAN_GE_WRITE(0x48a0, reg_data);
++
++		reg_data = TITAN_GE_READ(0x4958);
++		reg_data |= 0x100000;
++
++		TITAN_GE_WRITE(0x4958, reg_data);
++		reg_data |= (0xff << 10) | (2*(0xff + 1));
++		TITAN_GE_WRITE(0x4958, reg_data);
++
++		/*
++		 * BAV2, BAV and DAV settings for the Tx FIFO
++		 */
++		reg_data1 = TITAN_GE_READ(0x495c);
++		reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
++
++		TITAN_GE_WRITE(0x495c, reg_data1);
++
++		reg_data &= ~(0x00100000);
++		reg_data |= 0x200000;
++
++		TITAN_GE_WRITE(0x4958, reg_data);
++	}
++
++	/*
++	 * Step 3:  TRTG block enable
++	 */
++	reg_data = TITAN_GE_READ(TITAN_GE_TRTG_CONFIG + (port_num << 12));
++
++	/*
++	 * This is the 1.2 revision of the chip. It has fix for the
++	 * IP header alignment. Now, the IP header begins at an
++	 * aligned address and this wont need an extra copy in the
++	 * driver. This performance drawback existed in the previous
++	 * versions of the silicon
++	 */
++	reg_data_1 = TITAN_GE_READ(0x103c + (port_num << 12));
++	reg_data_1 |= 0x40000000;
++	TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
++
++	reg_data_1 |= 0x04000000;
++	TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
++
++	mdelay(5);
++
++	reg_data_1 &= ~(0x04000000);
++	TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
++
++	mdelay(5);
++
++	reg_data |= 0x0001;
++	TITAN_GE_WRITE((TITAN_GE_TRTG_CONFIG + (port_num << 12)), reg_data);
++
++	/*
++	 * Step 4:  Start the Tx activity
++	 */
++	TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_2 + (port_num << 12)), 0xe197);
++#ifdef TITAN_GE_JUMBO_FRAMES
++	TITAN_GE_WRITE((0x1258 + (port_num << 12)), 0x4000);
++#endif
++	reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 + (port_num << 12));
++	reg_data |= 0x0001;	/* Enable TMAC */
++	reg_data |= 0x6c70;	/* PAUSE also set */
++
++	TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 + (port_num << 12)), reg_data);
++
++	udelay(30);
++
++	/* Destination Address drop bit */
++	reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_2 + (port_num << 12));
++	reg_data |= 0x218;        /* DA_DROP bit and pause */
++	TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_2 + (port_num << 12)), reg_data);
++
++	TITAN_GE_WRITE((0x1218 + (port_num << 12)), 0x3);
++
++#ifdef TITAN_GE_JUMBO_FRAMES
++	TITAN_GE_WRITE((0x1208 + (port_num << 12)), 0x4000);
++#endif
++	/* Start the Rx activity */
++	reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 + (port_num << 12));
++	reg_data |= 0x0001;	/* RMAC Enable */
++	reg_data |= 0x0010;	/* CRC Check enable */
++	reg_data |= 0x0040;	/* Min Frame check enable */
++	reg_data |= 0x4400;	/* Max Frame check enable */
++
++	TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 + (port_num << 12)), reg_data);
++
++	udelay(30);
++
++	/*
++	 * Enable the Interrupts for Tx and Rx
++	 */
++	reg_data1 = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE);
++
++	if (port_num == 0) {
++		reg_data1 |= 0x3;
++#ifdef CONFIG_SMP
++		TITAN_GE_WRITE(0x0038, 0x003);
++#else
++		TITAN_GE_WRITE(0x0038, 0x303);
++#endif
++	}
++
++	if (port_num == 1) {
++		reg_data1 |= 0x300;
++	}
++
++	if (port_num == 2)
++		reg_data1 |= 0x30000;
++
++	TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, reg_data1);
++	TITAN_GE_WRITE(0x003c, 0x300);
++
++	if (config_done == 0) {
++		TITAN_GE_WRITE(0x0024, 0x04000024);	/* IRQ vector */
++		TITAN_GE_WRITE(0x0020, 0x000fb000);	/* INTMSG base */
++	}
++
++	/* Priority */
++	reg_data = TITAN_GE_READ(0x1038 + (port_num << 12));
++	reg_data &= ~(0x00f00000);
++	TITAN_GE_WRITE((0x1038 + (port_num << 12)), reg_data);
++
++	/* Step 5:  GMII config */
++	titan_ge_gmii_config(port_num);
++
++	if (config_done == 0) {
++		TITAN_GE_WRITE(0x1a80, 0);
++		config_done = 1;
++	}
++
++	return TITAN_OK;
++}
++
++/*
++ * Function to queue the packet for the Ethernet device
++ */
++static void titan_ge_tx_queue(titan_ge_port_info * titan_ge_eth,
++				struct sk_buff * skb)
++{
++	struct device *device = &titan_ge_device[titan_ge_eth->port_num]->dev;
++	unsigned int curr_desc = titan_ge_eth->tx_curr_desc_q;
++	volatile titan_ge_tx_desc *tx_curr;
++	int port_num = titan_ge_eth->port_num;
++
++	tx_curr = &(titan_ge_eth->tx_desc_area[curr_desc]);
++	tx_curr->buffer_addr =
++		dma_map_single(device, skb->data, skb_headlen(skb),
++			       DMA_TO_DEVICE);
++
++	titan_ge_eth->tx_skb[curr_desc] = (struct sk_buff *) skb;
++	tx_curr->buffer_len = skb_headlen(skb);
++
++	/* Last descriptor enables interrupt and changes ownership */
++	tx_curr->cmd_sts = 0x1 | (1 << 15) | (1 << 5);
++
++	/* Kick the XDMA to start the transfer from memory to the FIFO */
++	TITAN_GE_WRITE((0x5044 + (port_num << 8)), 0x1);
++
++	/* Current descriptor updated */
++	titan_ge_eth->tx_curr_desc_q = (curr_desc + 1) % TITAN_GE_TX_QUEUE;
++
++	/* Prefetch the next descriptor */
++	prefetch((const void *)
++		 &titan_ge_eth->tx_desc_area[titan_ge_eth->tx_curr_desc_q]);
++}
++
++/*
++ * Actually does the open of the Ethernet device
++ */
++static int titan_ge_eth_open(struct net_device *netdev)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++	unsigned int port_num = titan_ge_eth->port_num;
++	struct device *device = &titan_ge_device[port_num]->dev;
++	unsigned long reg_data;
++	unsigned int phy_reg;
++	int err = 0;
++
++	/* Stop the Rx activity */
++	reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 + (port_num << 12));
++	reg_data &= ~(0x00000001);
++	TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 + (port_num << 12)), reg_data);
++
++	/* Clear the port interrupts */
++	TITAN_GE_WRITE((TITAN_GE_CHANNEL0_INTERRUPT + (port_num << 8)), 0x0);
++
++	if (config_done == 0) {
++		TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0);
++		TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_B, 0);
++	}
++
++	/* Set the MAC Address */
++	memcpy(titan_ge_eth->port_mac_addr, netdev->dev_addr, 6);
++
++	if (config_done == 0)
++		titan_port_init(netdev, titan_ge_eth);
++
++	titan_ge_update_afx(titan_ge_eth);
++
++	/* Allocate the Tx ring now */
++	titan_ge_eth->tx_ring_skbs = 0;
++	titan_ge_eth->tx_ring_size = TITAN_GE_TX_QUEUE;
++
++	/* Allocate space in the SRAM for the descriptors */
++	titan_ge_eth->tx_desc_area = (titan_ge_tx_desc *)
++		(titan_ge_sram + TITAN_TX_RING_BYTES * port_num);
++	titan_ge_eth->tx_dma = TITAN_SRAM_BASE + TITAN_TX_RING_BYTES * port_num;
++
++	if (!titan_ge_eth->tx_desc_area) {
++		printk(KERN_ERR
++		       "%s: Cannot allocate Tx Ring (size %d bytes) for port %d\n",
++		       netdev->name, TITAN_TX_RING_BYTES, port_num);
++		return -ENOMEM;
++	}
++
++	memset(titan_ge_eth->tx_desc_area, 0, titan_ge_eth->tx_desc_area_size);
++
++	/* Now initialize the Tx descriptor ring */
++	titan_ge_init_tx_desc_ring(titan_ge_eth,
++				   titan_ge_eth->tx_ring_size,
++				   (unsigned long) titan_ge_eth->tx_desc_area,
++				   (unsigned long) titan_ge_eth->tx_dma);
++
++	/* Allocate the Rx ring now */
++	titan_ge_eth->rx_ring_size = TITAN_GE_RX_QUEUE;
++	titan_ge_eth->rx_ring_skbs = 0;
++
++	titan_ge_eth->rx_desc_area =
++		(titan_ge_rx_desc *)(titan_ge_sram + 0x1000 + TITAN_RX_RING_BYTES * port_num);
++
++	titan_ge_eth->rx_dma = TITAN_SRAM_BASE + 0x1000 + TITAN_RX_RING_BYTES * port_num;
++
++	if (!titan_ge_eth->rx_desc_area) {
++		printk(KERN_ERR "%s: Cannot allocate Rx Ring (size %d bytes)\n",
++		       netdev->name, TITAN_RX_RING_BYTES);
++
++		printk(KERN_ERR "%s: Freeing previously allocated TX queues...",
++		       netdev->name);
++
++		dma_free_coherent(device, titan_ge_eth->tx_desc_area_size,
++				    (void *) titan_ge_eth->tx_desc_area,
++				    titan_ge_eth->tx_dma);
++
++		return -ENOMEM;
++	}
++
++	memset(titan_ge_eth->rx_desc_area, 0, titan_ge_eth->rx_desc_area_size);
++
++	/* Now initialize the Rx ring */
++#ifdef TITAN_GE_JUMBO_FRAMES
++	if ((titan_ge_init_rx_desc_ring
++	    (titan_ge_eth, titan_ge_eth->rx_ring_size, TITAN_GE_JUMBO_BUFSIZE,
++	     (unsigned long) titan_ge_eth->rx_desc_area, 0,
++	      (unsigned long) titan_ge_eth->rx_dma)) == 0)
++#else
++	if ((titan_ge_init_rx_desc_ring
++	     (titan_ge_eth, titan_ge_eth->rx_ring_size, TITAN_GE_STD_BUFSIZE,
++	      (unsigned long) titan_ge_eth->rx_desc_area, 0,
++	      (unsigned long) titan_ge_eth->rx_dma)) == 0)
++#endif
++		panic("%s: Error initializing RX Ring\n", netdev->name);
++
++	/* Fill the Rx ring with the SKBs */
++	titan_ge_port_start(netdev, titan_ge_eth);
++
++	/*
++	 * Check if Interrupt Coalscing needs to be turned on. The
++	 * values specified in the register is multiplied by
++	 * (8 x 64 nanoseconds) to determine when an interrupt should
++	 * be sent to the CPU.
++	 */
++
++	if (TITAN_GE_TX_COAL) {
++		titan_ge_eth->tx_int_coal =
++		    titan_ge_tx_coal(TITAN_GE_TX_COAL, port_num);
++	}
++
++	err = titan_ge_mdio_read(port_num, TITAN_GE_MDIO_PHY_STATUS, &phy_reg);
++	if (err == TITAN_GE_MDIO_ERROR) {
++		printk(KERN_ERR
++		       "Could not read PHY control register 0x11 \n");
++		return TITAN_ERROR;
++	}
++	if (!(phy_reg & 0x0400)) {
++		netif_carrier_off(netdev);
++		netif_stop_queue(netdev);
++		return TITAN_ERROR;
++	} else {
++		netif_carrier_on(netdev);
++		netif_start_queue(netdev);
++	}
++
++	return TITAN_OK;
++}
++
++/*
++ * Queue the packet for Tx. Currently no support for zero copy,
++ * checksum offload and Scatter Gather. The chip does support
++ * Scatter Gather only. But, that wont help here since zero copy
++ * requires support for Tx checksumming also.
++ */
++int titan_ge_start_xmit(struct sk_buff *skb, struct net_device *netdev)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++	unsigned long flags;
++	struct net_device_stats *stats;
++//printk("titan_ge_start_xmit\n");
++
++	stats = &titan_ge_eth->stats;
++	spin_lock_irqsave(&titan_ge_eth->lock, flags);
++
++	if ((TITAN_GE_TX_QUEUE - titan_ge_eth->tx_ring_skbs) <=
++	    (skb_shinfo(skb)->nr_frags + 1)) {
++		netif_stop_queue(netdev);
++		spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++		printk(KERN_ERR "Tx OOD \n");
++		return 1;
++	}
++
++	titan_ge_tx_queue(titan_ge_eth, skb);
++	titan_ge_eth->tx_ring_skbs++;
++
++	if (TITAN_GE_TX_QUEUE <= (titan_ge_eth->tx_ring_skbs + 4)) {
++		spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++		titan_ge_free_tx_queue(titan_ge_eth);
++		spin_lock_irqsave(&titan_ge_eth->lock, flags);
++	}
++
++	stats->tx_bytes += skb->len;
++	stats->tx_packets++;
++
++	spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++
++	netdev->trans_start = jiffies;
++
++	return 0;
++}
++
++/*
++ * Actually does the Rx. Rx side checksumming supported.
++ */
++static int titan_ge_rx(struct net_device *netdev, int port_num,
++			titan_ge_port_info * titan_ge_port,
++		       titan_ge_packet * packet)
++{
++	int rx_curr_desc, rx_used_desc;
++	volatile titan_ge_rx_desc *rx_desc;
++
++	rx_curr_desc = titan_ge_port->rx_curr_desc_q;
++	rx_used_desc = titan_ge_port->rx_used_desc_q;
++
++	if (((rx_curr_desc + 1) % TITAN_GE_RX_QUEUE) == rx_used_desc)
++		return TITAN_ERROR;
++
++	rx_desc = &(titan_ge_port->rx_desc_area[rx_curr_desc]);
++
++	if (rx_desc->cmd_sts & TITAN_GE_RX_BUFFER_OWNED)
++		return TITAN_ERROR;
++
++	packet->skb = titan_ge_port->rx_skb[rx_curr_desc];
++	packet->len = (rx_desc->cmd_sts & 0x7fff);
++
++	/*
++	 * At this point, we dont know if the checksumming
++	 * actually helps relieve CPU. So, keep it for
++	 * port 0 only
++	 */
++	packet->checksum = ntohs((rx_desc->buffer & 0xffff0000) >> 16);
++	packet->cmd_sts = rx_desc->cmd_sts;
++
++	titan_ge_port->rx_curr_desc_q = (rx_curr_desc + 1) % TITAN_GE_RX_QUEUE;
++
++	/* Prefetch the next descriptor */
++	prefetch((const void *)
++	       &titan_ge_port->rx_desc_area[titan_ge_port->rx_curr_desc_q + 1]);
++
++	return TITAN_OK;
++}
++
++/*
++ * Free the Tx queue of the used SKBs
++ */
++static int titan_ge_free_tx_queue(titan_ge_port_info *titan_ge_eth)
++{
++	unsigned long flags;
++
++	/* Take the lock */
++	spin_lock_irqsave(&(titan_ge_eth->lock), flags);
++
++	while (titan_ge_return_tx_desc(titan_ge_eth, titan_ge_eth->port_num) == 0)
++		if (titan_ge_eth->tx_ring_skbs != 1)
++			titan_ge_eth->tx_ring_skbs--;
++
++	spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++
++	return TITAN_OK;
++}
++
++/*
++ * Threshold beyond which we do the cleaning of
++ * Tx queue and new allocation for the Rx
++ * queue
++ */
++#define	TX_THRESHOLD	4
++#define	RX_THRESHOLD	10
++
++/*
++ * Receive the packets and send it to the kernel.
++ */
++static int titan_ge_receive_queue(struct net_device *netdev, unsigned int max)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++	unsigned int port_num = titan_ge_eth->port_num;
++	titan_ge_packet packet;
++	struct net_device_stats *stats;
++	struct sk_buff *skb;
++	unsigned long received_packets = 0;
++	unsigned int ack;
++
++	stats = &titan_ge_eth->stats;
++
++	while ((--max)
++	       && (titan_ge_rx(netdev, port_num, titan_ge_eth, &packet) == TITAN_OK)) {
++		skb = (struct sk_buff *) packet.skb;
++
++		titan_ge_eth->rx_ring_skbs--;
++
++		if (--titan_ge_eth->rx_work_limit < 0)
++			break;
++		received_packets++;
++
++		stats->rx_packets++;
++		stats->rx_bytes += packet.len;
++
++		if ((packet.cmd_sts & TITAN_GE_RX_PERR) ||
++			(packet.cmd_sts & TITAN_GE_RX_OVERFLOW_ERROR) ||
++			(packet.cmd_sts & TITAN_GE_RX_TRUNC) ||
++			(packet.cmd_sts & TITAN_GE_RX_CRC_ERROR)) {
++				stats->rx_dropped++;
++				dev_kfree_skb_any(skb);
++
++				continue;
++		}
++		/*
++		 * Either support fast path or slow path. Decision
++		 * making can really slow down the performance. The
++		 * idea is to cut down the number of checks and improve
++		 * the fastpath.
++		 */
++
++		skb_put(skb, packet.len - 2);
++
++		/*
++		 * Increment data pointer by two since thats where
++		 * the MAC starts
++		 */
++		skb_reserve(skb, 2);
++		skb->protocol = eth_type_trans(skb, netdev);
++		netif_receive_skb(skb);
++
++		if (titan_ge_eth->rx_threshold > RX_THRESHOLD) {
++			ack = titan_ge_rx_task(netdev, titan_ge_eth);
++			TITAN_GE_WRITE((0x5048 + (port_num << 8)), ack);
++			titan_ge_eth->rx_threshold = 0;
++		} else
++			titan_ge_eth->rx_threshold++;
++
++		if (titan_ge_eth->tx_threshold > TX_THRESHOLD) {
++			titan_ge_eth->tx_threshold = 0;
++			titan_ge_free_tx_queue(titan_ge_eth);
++		}
++		else
++			titan_ge_eth->tx_threshold++;
++
++	}
++	return received_packets;
++}
++
++
++/*
++ * Enable the Rx side interrupts
++ */
++static void titan_ge_enable_int(unsigned int port_num,
++			titan_ge_port_info *titan_ge_eth,
++			struct net_device *netdev)
++{
++	unsigned long reg_data = TITAN_GE_READ(TITAN_GE_INTR_XDMA_IE);
++
++	if (port_num == 0)
++		reg_data |= 0x3;
++	if (port_num == 1)
++		reg_data |= 0x300;
++	if (port_num == 2)
++		reg_data |= 0x30000;
++
++	/* Re-enable interrupts */
++	TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, reg_data);
++}
++
++/*
++ * Main function to handle the polling for Rx side NAPI.
++ * Receive interrupts have been disabled at this point.
++ * The poll schedules the transmit followed by receive.
++ */
++static int titan_ge_poll(struct net_device *netdev, int *budget)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++	int port_num = titan_ge_eth->port_num;
++	int work_done = 0;
++	unsigned long flags, status;
++
++	titan_ge_eth->rx_work_limit = *budget;
++	if (titan_ge_eth->rx_work_limit > netdev->quota)
++		titan_ge_eth->rx_work_limit = netdev->quota;
++
++	do {
++		/* Do the transmit cleaning work here */
++		titan_ge_free_tx_queue(titan_ge_eth);
++
++		/* Ack the Rx interrupts */
++		if (port_num == 0)
++			TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x3);
++		if (port_num == 1)
++			TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x300);
++		if (port_num == 2)
++			TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_CORE_A, 0x30000);
++
++		work_done += titan_ge_receive_queue(netdev, 0);
++
++		/* Out of quota and there is work to be done */
++		if (titan_ge_eth->rx_work_limit < 0)
++			goto not_done;
++
++		/* Receive alloc_skb could lead to OOM */
++		if (oom_flag == 1) {
++			oom_flag = 0;
++			goto oom;
++		}
++
++		status = TITAN_GE_READ(TITAN_GE_INTR_XDMA_CORE_A);
++	} while (status & 0x30300);
++
++	/* If we are here, then no more interrupts to process */
++	goto done;
++
++not_done:
++	*budget -= work_done;
++	netdev->quota -= work_done;
++	return 1;
++
++oom:
++	printk(KERN_ERR "OOM \n");
++	netif_rx_complete(netdev);
++	return 0;
++
++done:
++	/*
++	 * No more packets on the poll list. Turn the interrupts
++	 * back on and we should be able to catch the new
++	 * packets in the interrupt handler
++	 */
++	if (!work_done)
++		work_done = 1;
++
++	*budget -= work_done;
++	netdev->quota -= work_done;
++
++	spin_lock_irqsave(&titan_ge_eth->lock, flags);
++
++	/* Remove us from the poll list */
++	netif_rx_complete(netdev);
++
++	/* Re-enable interrupts */
++	titan_ge_enable_int(port_num, titan_ge_eth, netdev);
++
++	spin_unlock_irqrestore(&titan_ge_eth->lock, flags);
++
++	return 0;
++}
++
++/*
++ * Close the network device
++ */
++int titan_ge_stop(struct net_device *netdev)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++
++	spin_lock_irq(&(titan_ge_eth->lock));
++	titan_ge_eth_stop(netdev);
++	free_irq(netdev->irq, netdev);
++	spin_unlock_irq(&titan_ge_eth->lock);
++
++	return TITAN_OK;
++}
++
++/*
++ * Free the Tx ring
++ */
++static void titan_ge_free_tx_rings(struct net_device *netdev)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++	unsigned int port_num = titan_ge_eth->port_num;
++	unsigned int curr;
++	unsigned long reg_data;
++
++	/* Stop the Tx DMA */
++	reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG +
++				(port_num << 8));
++	reg_data |= 0xc0000000;
++	TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG +
++			(port_num << 8)), reg_data);
++
++	/* Disable the TMAC */
++	reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 +
++				(port_num << 12));
++	reg_data &= ~(0x00000001);
++	TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 +
++			(port_num << 12)), reg_data);
++
++	for (curr = 0;
++	     (titan_ge_eth->tx_ring_skbs) && (curr < TITAN_GE_TX_QUEUE);
++	     curr++) {
++		if (titan_ge_eth->tx_skb[curr]) {
++			dev_kfree_skb(titan_ge_eth->tx_skb[curr]);
++			titan_ge_eth->tx_ring_skbs--;
++		}
++	}
++
++	if (titan_ge_eth->tx_ring_skbs != 0)
++		printk
++		    ("%s: Error on Tx descriptor free - could not free %d"
++		     " descriptors\n", netdev->name,
++		     titan_ge_eth->tx_ring_skbs);
++
++#ifndef TITAN_RX_RING_IN_SRAM
++	dma_free_coherent(&titan_ge_device[port_num]->dev,
++			  titan_ge_eth->tx_desc_area_size,
++			  (void *) titan_ge_eth->tx_desc_area,
++			  titan_ge_eth->tx_dma);
++#endif
++}
++
++/*
++ * Free the Rx ring
++ */
++static void titan_ge_free_rx_rings(struct net_device *netdev)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++	unsigned int port_num = titan_ge_eth->port_num;
++	unsigned int curr;
++	unsigned long reg_data;
++
++	/* Stop the Rx DMA */
++	reg_data = TITAN_GE_READ(TITAN_GE_CHANNEL0_CONFIG +
++				(port_num << 8));
++	reg_data |= 0x000c0000;
++	TITAN_GE_WRITE((TITAN_GE_CHANNEL0_CONFIG +
++			(port_num << 8)), reg_data);
++
++	/* Disable the RMAC */
++	reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 +
++				(port_num << 12));
++	reg_data &= ~(0x00000001);
++	TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 +
++			(port_num << 12)), reg_data);
++
++	for (curr = 0;
++	     titan_ge_eth->rx_ring_skbs && (curr < TITAN_GE_RX_QUEUE);
++	     curr++) {
++		if (titan_ge_eth->rx_skb[curr]) {
++			dev_kfree_skb(titan_ge_eth->rx_skb[curr]);
++			titan_ge_eth->rx_ring_skbs--;
++		}
++	}
++
++	if (titan_ge_eth->rx_ring_skbs != 0)
++		printk(KERN_ERR
++		       "%s: Error in freeing Rx Ring. %d skb's still"
++		       " stuck in RX Ring - ignoring them\n", netdev->name,
++		       titan_ge_eth->rx_ring_skbs);
++
++#ifndef TITAN_RX_RING_IN_SRAM
++	dma_free_coherent(&titan_ge_device[port_num]->dev,
++			  titan_ge_eth->rx_desc_area_size,
++			  (void *) titan_ge_eth->rx_desc_area,
++			  titan_ge_eth->rx_dma);
++#endif
++}
++
++/*
++ * Actually does the stop of the Ethernet device
++ */
++static void titan_ge_eth_stop(struct net_device *netdev)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++
++	netif_stop_queue(netdev);
++
++	titan_ge_port_reset(titan_ge_eth->port_num);
++
++	titan_ge_free_tx_rings(netdev);
++	titan_ge_free_rx_rings(netdev);
++
++	/* Disable the Tx and Rx Interrupts for all channels */
++	TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, 0x0);
++}
++
++/*
++ * Update the MAC address. Note that we have to write the
++ * address in three station registers, 16 bits each. And this
++ * has to be done for TMAC and RMAC
++ */
++static void titan_ge_update_mac_address(struct net_device *netdev)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++	unsigned int port_num = titan_ge_eth->port_num;
++	u8 p_addr[6];
++
++	memcpy(titan_ge_eth->port_mac_addr, netdev->dev_addr, 6);
++	memcpy(p_addr, netdev->dev_addr, 6);
++
++	/* Update the Address Filtering Match tables */
++	titan_ge_update_afx(titan_ge_eth);
++
++	printk("Station MAC : %d %d %d %d %d %d  \n",
++		p_addr[5], p_addr[4], p_addr[3],
++		p_addr[2], p_addr[1], p_addr[0]);
++
++	/* Set the MAC address here for TMAC and RMAC */
++	TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_HI + (port_num << 12)),
++		       ((p_addr[5] << 8) | p_addr[4]));
++	TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_MID + (port_num << 12)),
++		       ((p_addr[3] << 8) | p_addr[2]));
++	TITAN_GE_WRITE((TITAN_GE_TMAC_STATION_LOW + (port_num << 12)),
++		       ((p_addr[1] << 8) | p_addr[0]));
++
++	TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_HI + (port_num << 12)),
++		       ((p_addr[5] << 8) | p_addr[4]));
++	TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_MID + (port_num << 12)),
++		       ((p_addr[3] << 8) | p_addr[2]));
++	TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_LOW + (port_num << 12)),
++		       ((p_addr[1] << 8) | p_addr[0]));
++}
++
++/*
++ * Set the MAC address of the Ethernet device
++ */
++static int titan_ge_set_mac_address(struct net_device *dev, void *addr)
++{
++	titan_ge_port_info *tp = netdev_priv(dev);
++	struct sockaddr *sa = addr;
++
++	memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
++
++	spin_lock_irq(&tp->lock);
++	titan_ge_update_mac_address(dev);
++	spin_unlock_irq(&tp->lock);
++
++	return 0;
++}
++
++/*
++ * Get the Ethernet device stats
++ */
++static struct net_device_stats *titan_ge_get_stats(struct net_device *netdev)
++{
++	titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
++
++	return &titan_ge_eth->stats;
++}
++
++/*
++ * Initialize the Rx descriptor ring for the Titan Ge
++ */
++static int titan_ge_init_rx_desc_ring(titan_ge_port_info * titan_eth_port,
++				      int rx_desc_num,
++				      int rx_buff_size,
++				      unsigned long rx_desc_base_addr,
++				      unsigned long rx_buff_base_addr,
++				      unsigned long rx_dma)
++{
++	volatile titan_ge_rx_desc *rx_desc;
++	unsigned long buffer_addr;
++	int index;
++	unsigned long titan_ge_rx_desc_bus = rx_dma;
++
++	buffer_addr = rx_buff_base_addr;
++	rx_desc = (titan_ge_rx_desc *) rx_desc_base_addr;
++
++	/* Check alignment */
++	if (rx_buff_base_addr & 0xF)
++		return 0;
++
++	/* Check Rx buffer size */
++	if ((rx_buff_size < 8) || (rx_buff_size > TITAN_GE_MAX_RX_BUFFER))
++		return 0;
++
++	/* 64-bit alignment
++	if ((rx_buff_base_addr + rx_buff_size) & 0x7)
++		return 0; */
++
++	/* Initialize the Rx desc ring */
++	for (index = 0; index < rx_desc_num; index++) {
++		titan_ge_rx_desc_bus += sizeof(titan_ge_rx_desc);
++		rx_desc[index].cmd_sts = 0;
++		rx_desc[index].buffer_addr = buffer_addr;
++		titan_eth_port->rx_skb[index] = NULL;
++		buffer_addr += rx_buff_size;
++	}
++
++	titan_eth_port->rx_curr_desc_q = 0;
++	titan_eth_port->rx_used_desc_q = 0;
++
++	titan_eth_port->rx_desc_area = (titan_ge_rx_desc *) rx_desc_base_addr;
++	titan_eth_port->rx_desc_area_size =
++	    rx_desc_num * sizeof(titan_ge_rx_desc);
++
++	titan_eth_port->rx_dma = rx_dma;
++
++	return TITAN_OK;
++}
++
++/*
++ * Initialize the Tx descriptor ring. Descriptors in the SRAM
++ */
++static int titan_ge_init_tx_desc_ring(titan_ge_port_info * titan_ge_port,
++				      int tx_desc_num,
++				      unsigned long tx_desc_base_addr,
++				      unsigned long tx_dma)
++{
++	titan_ge_tx_desc *tx_desc;
++	int index;
++	unsigned long titan_ge_tx_desc_bus = tx_dma;
++
++	if (tx_desc_base_addr & 0xF)
++		return 0;
++
++	tx_desc = (titan_ge_tx_desc *) tx_desc_base_addr;
++
++	for (index = 0; index < tx_desc_num; index++) {
++		titan_ge_port->tx_dma_array[index] =
++		    (dma_addr_t) titan_ge_tx_desc_bus;
++		titan_ge_tx_desc_bus += sizeof(titan_ge_tx_desc);
++		tx_desc[index].cmd_sts = 0x0000;
++		tx_desc[index].buffer_len = 0;
++		tx_desc[index].buffer_addr = 0x00000000;
++		titan_ge_port->tx_skb[index] = NULL;
++	}
++
++	titan_ge_port->tx_curr_desc_q = 0;
++	titan_ge_port->tx_used_desc_q = 0;
++
++	titan_ge_port->tx_desc_area = (titan_ge_tx_desc *) tx_desc_base_addr;
++	titan_ge_port->tx_desc_area_size =
++	    tx_desc_num * sizeof(titan_ge_tx_desc);
++
++	titan_ge_port->tx_dma = tx_dma;
++	return TITAN_OK;
++}
++
++/*
++ * Initialize the device as an Ethernet device
++ */
++static int __init titan_ge_probe(struct device *device)
++{
++	titan_ge_port_info *titan_ge_eth;
++	struct net_device *netdev;
++	int port = to_platform_device(device)->id;
++	int err;
++
++	netdev = alloc_etherdev(sizeof(titan_ge_port_info));
++	if (!netdev) {
++		err = -ENODEV;
++		goto out;
++	}
++
++	netdev->open = titan_ge_open;
++	netdev->stop = titan_ge_stop;
++	netdev->hard_start_xmit = titan_ge_start_xmit;
++	netdev->get_stats = titan_ge_get_stats;
++	netdev->set_multicast_list = titan_ge_set_multi;
++	netdev->set_mac_address = titan_ge_set_mac_address;
++
++	/* Tx timeout */
++	netdev->tx_timeout = titan_ge_tx_timeout;
++	netdev->watchdog_timeo = 2 * HZ;
++
++	/* Set these to very high values */
++	netdev->poll = titan_ge_poll;
++	netdev->weight = 64;
++
++	netdev->tx_queue_len = TITAN_GE_TX_QUEUE;
++	netif_carrier_off(netdev);
++	netdev->base_addr = 0;
++
++	netdev->change_mtu = titan_ge_change_mtu;
++
++	titan_ge_eth = netdev_priv(netdev);
++	/* Allocation of memory for the driver structures */
++
++	titan_ge_eth->port_num = port;
++
++	/* Configure the Tx timeout handler */
++	INIT_WORK(&titan_ge_eth->tx_timeout_task,
++		  (void (*)(void *)) titan_ge_tx_timeout_task, netdev);
++
++	spin_lock_init(&titan_ge_eth->lock);
++
++	/* set MAC addresses */
++	memcpy(netdev->dev_addr, titan_ge_mac_addr_base, 6);
++	netdev->dev_addr[5] += port;
++
++	err = register_netdev(netdev);
++
++	if (err)
++		goto out_free_netdev;
++
++	printk(KERN_NOTICE
++	       "%s: port %d with MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
++	       netdev->name, port, netdev->dev_addr[0],
++	       netdev->dev_addr[1], netdev->dev_addr[2],
++	       netdev->dev_addr[3], netdev->dev_addr[4],
++	       netdev->dev_addr[5]);
++
++	printk(KERN_NOTICE "Rx NAPI supported, Tx Coalescing ON \n");
++
++	return 0;
++
++out_free_netdev:
++	kfree(netdev);
++
++out:
++	return err;
++}
++
++/*
++ * Reset the Ethernet port
++ */
++static void titan_ge_port_reset(unsigned int port_num)
++{
++	unsigned int reg_data;
++
++	/* Stop the Tx port activity */
++	reg_data = TITAN_GE_READ(TITAN_GE_TMAC_CONFIG_1 +
++				(port_num << 12));
++	reg_data &= ~(0x0001);
++	TITAN_GE_WRITE((TITAN_GE_TMAC_CONFIG_1 +
++			(port_num << 12)), reg_data);
++
++	/* Stop the Rx port activity */
++	reg_data = TITAN_GE_READ(TITAN_GE_RMAC_CONFIG_1 +
++				(port_num << 12));
++	reg_data &= ~(0x0001);
++	TITAN_GE_WRITE((TITAN_GE_RMAC_CONFIG_1 +
++			(port_num << 12)), reg_data);
++
++	return;
++}
++
++/*
++ * Return the Tx desc after use by the XDMA
++ */
++static int titan_ge_return_tx_desc(titan_ge_port_info * titan_ge_eth, int port)
++{
++	int tx_desc_used;
++	struct sk_buff *skb;
++
++	tx_desc_used = titan_ge_eth->tx_used_desc_q;
++
++	/* return right away */
++	if (tx_desc_used == titan_ge_eth->tx_curr_desc_q)
++		return TITAN_ERROR;
++
++	/* Now the critical stuff */
++	skb = titan_ge_eth->tx_skb[tx_desc_used];
++
++	dev_kfree_skb_any(skb);
++
++	titan_ge_eth->tx_skb[tx_desc_used] = NULL;
++	titan_ge_eth->tx_used_desc_q =
++	    (tx_desc_used + 1) % TITAN_GE_TX_QUEUE;
++
++	return 0;
++}
++
++/*
++ * Coalescing for the Tx path
++ */
++static unsigned long titan_ge_tx_coal(unsigned long delay, int port)
++{
++	unsigned long rx_delay;
++
++	rx_delay = TITAN_GE_READ(TITAN_GE_INT_COALESCING);
++	delay = (delay << 16) | rx_delay;
++
++	TITAN_GE_WRITE(TITAN_GE_INT_COALESCING, delay);
++	TITAN_GE_WRITE(0x5038, delay);
++
++	return delay;
++}
++
++static struct device_driver titan_soc_driver = {
++	.name   = titan_string,
++	.bus    = &platform_bus_type,
++	.probe  = titan_ge_probe,
++	.remove = __devexit_p(titan_device_remove),
++};
++
++static void titan_platform_release (struct device *device)
++{
++	struct platform_device *pldev;
++
++	/* free device */
++	pldev = to_platform_device (device);
++	kfree (pldev);
++}
++
++/*
++ * Register the Titan GE with the kernel
++ */
++static int __init titan_ge_init_module(void)
++{
++	struct platform_device *pldev;
++	unsigned int version, device;
++	int i;
++
++	printk(KERN_NOTICE
++	       "PMC-Sierra TITAN 10/100/1000 Ethernet Driver \n");
++
++	titan_ge_base = (unsigned long) ioremap(TITAN_GE_BASE, TITAN_GE_SIZE);
++	if (!titan_ge_base) {
++		printk("Mapping Titan GE failed\n");
++		goto out;
++	}
++
++	device = TITAN_GE_READ(TITAN_GE_DEVICE_ID);
++	version = (device & 0x000f0000) >> 16;
++	device &= 0x0000ffff;
++
++	printk(KERN_NOTICE "Device Id : %x,  Version : %x \n", device, version);
++
++#ifdef TITAN_RX_RING_IN_SRAM
++	titan_ge_sram = (unsigned long) ioremap(TITAN_SRAM_BASE,
++						TITAN_SRAM_SIZE);
++	if (!titan_ge_sram) {
++		printk("Mapping Titan SRAM failed\n");
++		goto out_unmap_ge;
++	}
++#endif
++
++	if (driver_register(&titan_soc_driver)) {
++		printk(KERN_ERR "Driver registration failed\n");
++		goto out_unmap_sram;
++	}
++
++	for (i = 0; i < 3; i++) {
++		titan_ge_device[i] = NULL;
++
++	        if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL)))
++	                continue;
++
++                memset (pldev, 0, sizeof (*pldev));
++                pldev->name		= titan_string;
++                pldev->id		= i;
++                pldev->dev.release	= titan_platform_release;
++                titan_ge_device[i]	= pldev;
++
++                if (platform_device_register (pldev)) {
++                        kfree (pldev);
++                        titan_ge_device[i] = NULL;
++                        continue;
++                }
++                                                                                
++                if (!pldev->dev.driver) {
++	                /*
++			 * The driver was not bound to this device, there was
++	                 * no hardware at this address. Unregister it, as the
++	                 * release fuction will take care of freeing the
++	                 * allocated structure
++			 */
++                        titan_ge_device[i] = NULL;
++                        platform_device_unregister (pldev);
++                }
++        }
++
++	return 0;
++
++out_unmap_sram:
++	iounmap((void *)titan_ge_sram);
++
++out_unmap_ge:
++	iounmap((void *)titan_ge_base);
++
++out:
++	return -ENOMEM;
++}
++
++/*
++ * Unregister the Titan GE from the kernel
++ */
++static void __exit titan_ge_cleanup_module(void)
++{
++	int i;
++
++	driver_unregister(&titan_soc_driver);
++
++	for (i = 0; i < 3; i++) {
++		if (titan_ge_device[i]) {
++			platform_device_unregister (titan_ge_device[i]);
++			titan_ge_device[i] = NULL;
++		}
++	}
++
++	iounmap((void *)titan_ge_sram);
++	iounmap((void *)titan_ge_base);
++}
++
++MODULE_AUTHOR("Manish Lachwani <lachwani at pmc-sierra.com>");
++MODULE_DESCRIPTION("Titan GE Ethernet driver");
++MODULE_LICENSE("GPL");
++
++module_init(titan_ge_init_module);
++module_exit(titan_ge_cleanup_module);
+diff -urpNX dontdiff linux-2.6.10/drivers/net/titan_ge.h linux-2.6.10-mips/drivers/net/titan_ge.h
+--- linux-2.6.10/drivers/net/titan_ge.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/titan_ge.h	2004-12-06 06:36:23.000000000 +0100
+@@ -0,0 +1,418 @@
++#ifndef _TITAN_GE_H_
++#define _TITAN_GE_H_
++
++#include <linux/config.h>
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/config.h>
++#include <linux/spinlock.h>
++#include <asm/byteorder.h>
++
++/*
++ * These functions should be later moved to a more generic location since there
++ * will be others accessing it also
++ */
++
++/*
++ * This is the way it works: LKB5 Base is at 0x0128. TITAN_BASE is defined in
++ * include/asm/titan_dep.h. TITAN_GE_BASE is the value in the TITAN_GE_LKB5
++ * register.
++ */
++
++#define	TITAN_GE_BASE	0xfe000000UL
++#define	TITAN_GE_SIZE	0x10000UL
++
++extern unsigned long titan_ge_base;
++
++#define	TITAN_GE_WRITE(offset, data) \
++		*(volatile u32 *)(titan_ge_base + (offset)) = (data)
++
++#define TITAN_GE_READ(offset) *(volatile u32 *)(titan_ge_base + (offset))
++
++#ifndef msec_delay
++#define msec_delay(x)   do { if(in_interrupt()) { \
++				/* Don't mdelay in interrupt context! */ \
++				BUG(); \
++			} else { \
++				set_current_state(TASK_UNINTERRUPTIBLE); \
++				schedule_timeout((x * HZ)/1000); \
++			} } while(0)
++#endif
++
++#define TITAN_GE_PORT_0
++
++#define	TITAN_SRAM_BASE		((OCD_READ(RM9000x2_OCD_LKB13) & ~1) << 4)
++#define	TITAN_SRAM_SIZE		0x2000UL
++
++extern unsigned long titan_ge_sram;
++
++/*
++ * We may need these constants
++ */
++#define TITAN_BIT0    0x00000001
++#define TITAN_BIT1    0x00000002
++#define TITAN_BIT2    0x00000004
++#define TITAN_BIT3    0x00000008
++#define TITAN_BIT4    0x00000010
++#define TITAN_BIT5    0x00000020
++#define TITAN_BIT6    0x00000040
++#define TITAN_BIT7    0x00000080
++#define TITAN_BIT8    0x00000100
++#define TITAN_BIT9    0x00000200
++#define TITAN_BIT10   0x00000400
++#define TITAN_BIT11   0x00000800
++#define TITAN_BIT12   0x00001000
++#define TITAN_BIT13   0x00002000
++#define TITAN_BIT14   0x00004000
++#define TITAN_BIT15   0x00008000
++#define TITAN_BIT16   0x00010000
++#define TITAN_BIT17   0x00020000
++#define TITAN_BIT18   0x00040000
++#define TITAN_BIT19   0x00080000
++#define TITAN_BIT20   0x00100000
++#define TITAN_BIT21   0x00200000
++#define TITAN_BIT22   0x00400000
++#define TITAN_BIT23   0x00800000
++#define TITAN_BIT24   0x01000000
++#define TITAN_BIT25   0x02000000
++#define TITAN_BIT26   0x04000000
++#define TITAN_BIT27   0x08000000
++#define TITAN_BIT28   0x10000000
++#define TITAN_BIT29   0x20000000
++#define TITAN_BIT30   0x40000000
++#define TITAN_BIT31   0x80000000
++
++/* Flow Control */
++#define	TITAN_GE_FC_NONE	0x0
++#define	TITAN_GE_FC_FULL	0x1
++#define	TITAN_GE_FC_TX_PAUSE	0x2
++#define	TITAN_GE_FC_RX_PAUSE	0x3
++
++/* Duplex Settings */
++#define	TITAN_GE_FULL_DUPLEX	0x1
++#define	TITAN_GE_HALF_DUPLEX	0x2
++
++/* Speed settings */
++#define	TITAN_GE_SPEED_1000	0x1
++#define	TITAN_GE_SPEED_100	0x2
++#define	TITAN_GE_SPEED_10	0x3
++
++/* Debugging info only */
++#undef TITAN_DEBUG
++
++/* Keep the rings in the Titan's SSRAM */
++#define TITAN_RX_RING_IN_SRAM
++
++#ifdef CONFIG_MIPS64
++#define	TITAN_GE_IE_MASK	0xfffffffffb001b64
++#define	TITAN_GE_IE_STATUS	0xfffffffffb001b60
++#else
++#define	TITAN_GE_IE_MASK	0xfb001b64
++#define	TITAN_GE_IE_STATUS	0xfb001b60
++#endif
++
++/* Support for Jumbo Frames */
++#undef TITAN_GE_JUMBO_FRAMES
++
++/* Rx buffer size */
++#ifdef TITAN_GE_JUMBO_FRAMES
++#define	TITAN_GE_JUMBO_BUFSIZE	9080
++#else
++#define	TITAN_GE_STD_BUFSIZE	1580
++#endif
++
++/*
++ * Tx and Rx Interrupt Coalescing parameter. These values are
++ * for 1 Ghz processor. Rx coalescing can be taken care of
++ * by NAPI. NAPI is adaptive and hence useful. Tx coalescing
++ * is not adaptive. Hence, these values need to be adjusted
++ * based on load, CPU speed etc.
++ */
++#define	TITAN_GE_RX_COAL	150
++#define	TITAN_GE_TX_COAL	300
++
++#if defined(__BIG_ENDIAN)
++
++/* Define the Rx descriptor */
++typedef struct eth_rx_desc {
++	u32     reserved;	/* Unused 		*/
++	u32     buffer_addr;	/* CPU buffer address 	*/
++	u32	cmd_sts;	/* Command and Status	*/
++	u32	buffer;		/* XDMA buffer address	*/
++} titan_ge_rx_desc;
++
++/* Define the Tx descriptor */
++typedef struct eth_tx_desc {
++	u16     cmd_sts;	/* Command, Status and Buffer count */
++	u16	buffer_len;	/* Length of the buffer	*/
++	u32     buffer_addr;	/* Physical address of the buffer */
++} titan_ge_tx_desc;
++
++#elif defined(__LITTLE_ENDIAN)
++
++/* Define the Rx descriptor */
++typedef struct eth_rx_desc {
++	u32	buffer_addr;	/* Buffer address inclusive of checksum */
++	u32     cmd_sts;	/* Command and Status info */
++} titan_ge_rx_desc;
++
++/* Define the Tx descriptor */
++typedef struct eth_tx_desc {
++	u32     buffer_addr;	/* Physical address of the buffer */
++	u16     buffer_len;     /* Length of the buffer */
++	u16     cmd_sts;        /* Command, Status and Buffer count */
++} titan_ge_tx_desc;
++#endif
++
++/* Default Tx Queue Size */
++#define	TITAN_GE_TX_QUEUE	128
++#define TITAN_TX_RING_BYTES	(TITAN_GE_TX_QUEUE * sizeof(struct eth_tx_desc))
++
++/* Default Rx Queue Size */
++#define	TITAN_GE_RX_QUEUE	64
++#define TITAN_RX_RING_BYTES	(TITAN_GE_RX_QUEUE * sizeof(struct eth_rx_desc))
++
++/* Packet Structure */
++typedef struct _pkt_info {
++	unsigned int           len;
++	unsigned int            cmd_sts;
++	unsigned int            buffer;
++	struct sk_buff          *skb;
++	unsigned int		checksum;
++} titan_ge_packet;
++
++
++#define	PHYS_CNT	3
++
++/* Titan Port specific data structure */
++typedef struct _eth_port_ctrl {
++	unsigned int		port_num;
++	u8			port_mac_addr[6];
++
++	/* Rx descriptor pointers */
++	int 			rx_curr_desc_q, rx_used_desc_q;
++
++	/* Tx descriptor pointers */
++	int 			tx_curr_desc_q, tx_used_desc_q;
++
++	/* Rx descriptor area */
++	volatile titan_ge_rx_desc	*rx_desc_area;
++	unsigned int			rx_desc_area_size;
++	struct sk_buff*			rx_skb[TITAN_GE_RX_QUEUE];
++
++	/* Tx Descriptor area */
++	volatile titan_ge_tx_desc	*tx_desc_area;
++	unsigned int                    tx_desc_area_size;
++	struct sk_buff*                 tx_skb[TITAN_GE_TX_QUEUE];
++
++	/* Timeout task */
++	struct work_struct		tx_timeout_task;
++
++	/* DMA structures and handles */
++	dma_addr_t			tx_dma;
++	dma_addr_t			rx_dma;
++	dma_addr_t			tx_dma_array[TITAN_GE_TX_QUEUE];
++
++	/* Device lock */
++	spinlock_t			lock;
++
++	unsigned int			tx_ring_skbs;
++	unsigned int			rx_ring_size;
++	unsigned int			tx_ring_size;
++	unsigned int			rx_ring_skbs;
++
++	struct net_device_stats		stats;
++
++	/* Tx and Rx coalescing */
++	unsigned long			rx_int_coal;
++	unsigned long			tx_int_coal;
++
++	/* Threshold for replenishing the Rx and Tx rings */
++	unsigned int			tx_threshold;
++	unsigned int			rx_threshold;
++
++	/* NAPI work limit */
++	unsigned int			rx_work_limit;
++} titan_ge_port_info;
++
++/* Titan specific constants */
++#define	TITAN_ETH_PORT_IRQ		3
++
++/* Max Rx buffer */
++#define	TITAN_GE_MAX_RX_BUFFER		65536
++
++/* Tx and Rx Error */
++#define	TITAN_GE_ERROR
++
++/* Rx Descriptor Command and Status */
++
++#define	TITAN_GE_RX_CRC_ERROR		TITAN_BIT27	/* crc error */
++#define	TITAN_GE_RX_OVERFLOW_ERROR	TITAN_BIT15	/* overflow */
++#define TITAN_GE_RX_BUFFER_OWNED	TITAN_BIT21	/* buffer ownership */
++#define	TITAN_GE_RX_STP			TITAN_BIT31	/* start of packet */
++#define	TITAN_GE_RX_BAM			TITAN_BIT30	/* broadcast address match */
++#define TITAN_GE_RX_PAM			TITAN_BIT28	/* physical address match */
++#define TITAN_GE_RX_LAFM		TITAN_BIT29	/* logical address filter match */
++#define TITAN_GE_RX_VLAN		TITAN_BIT26	/* virtual lans */
++#define TITAN_GE_RX_PERR		TITAN_BIT19	/* packet error */
++#define TITAN_GE_RX_TRUNC		TITAN_BIT20	/* packet size greater than 32 buffers */
++
++/* Tx Descriptor Command */
++#define	TITAN_GE_TX_BUFFER_OWNED	TITAN_BIT5	/* buffer ownership */
++#define	TITAN_GE_TX_ENABLE_INTERRUPT	TITAN_BIT15	/* Interrupt Enable */
++
++/* Return Status */
++#define	TITAN_OK	0x1	/* Good Status */
++#define	TITAN_ERROR	0x2	/* Error Status */
++
++/* MIB specific register offset */
++#define TITAN_GE_MSTATX_STATS_BASE_LOW       0x0800  /* MSTATX COUNTL[15:0] */
++#define TITAN_GE_MSTATX_STATS_BASE_MID       0x0804  /* MSTATX COUNTM[15:0] */
++#define TITAN_GE_MSTATX_STATS_BASE_HI        0x0808  /* MSTATX COUNTH[7:0] */
++#define TITAN_GE_MSTATX_CONTROL              0x0828  /* MSTATX Control */
++#define TITAN_GE_MSTATX_VARIABLE_SELECT      0x082C  /* MSTATX Variable Select */
++
++/* MIB counter offsets, add to the TITAN_GE_MSTATX_STATS_BASE_XXX */
++#define TITAN_GE_MSTATX_RXFRAMESOK                   0x0040
++#define TITAN_GE_MSTATX_RXOCTETSOK                   0x0050
++#define TITAN_GE_MSTATX_RXFRAMES                     0x0060
++#define TITAN_GE_MSTATX_RXOCTETS                     0x0070
++#define TITAN_GE_MSTATX_RXUNICASTFRAMESOK            0x0080
++#define TITAN_GE_MSTATX_RXBROADCASTFRAMESOK          0x0090
++#define TITAN_GE_MSTATX_RXMULTICASTFRAMESOK          0x00A0
++#define TITAN_GE_MSTATX_RXTAGGEDFRAMESOK             0x00B0
++#define TITAN_GE_MSTATX_RXMACPAUSECONTROLFRAMESOK    0x00C0
++#define TITAN_GE_MSTATX_RXMACCONTROLFRAMESOK         0x00D0
++#define TITAN_GE_MSTATX_RXFCSERROR                   0x00E0
++#define TITAN_GE_MSTATX_RXALIGNMENTERROR             0x00F0
++#define TITAN_GE_MSTATX_RXSYMBOLERROR                0x0100
++#define TITAN_GE_MSTATX_RXLAYER1ERROR                0x0110
++#define TITAN_GE_MSTATX_RXINRANGELENGTHERROR         0x0120
++#define TITAN_GE_MSTATX_RXLONGLENGTHERROR            0x0130
++#define TITAN_GE_MSTATX_RXLONGLENGTHCRCERROR         0x0140
++#define TITAN_GE_MSTATX_RXSHORTLENGTHERROR           0x0150
++#define TITAN_GE_MSTATX_RXSHORTLLENGTHCRCERROR       0x0160
++#define TITAN_GE_MSTATX_RXFRAMES64OCTETS             0x0170
++#define TITAN_GE_MSTATX_RXFRAMES65TO127OCTETS        0x0180
++#define TITAN_GE_MSTATX_RXFRAMES128TO255OCTETS       0x0190
++#define TITAN_GE_MSTATX_RXFRAMES256TO511OCTETS       0x01A0
++#define TITAN_GE_MSTATX_RXFRAMES512TO1023OCTETS      0x01B0
++#define TITAN_GE_MSTATX_RXFRAMES1024TO1518OCTETS     0x01C0
++#define TITAN_GE_MSTATX_RXFRAMES1519TOMAXSIZE        0x01D0
++#define TITAN_GE_MSTATX_RXSTATIONADDRESSFILTERED     0x01E0
++#define TITAN_GE_MSTATX_RXVARIABLE                   0x01F0
++#define TITAN_GE_MSTATX_GENERICADDRESSFILTERED       0x0200
++#define TITAN_GE_MSTATX_UNICASTFILTERED              0x0210
++#define TITAN_GE_MSTATX_MULTICASTFILTERED            0x0220
++#define TITAN_GE_MSTATX_BROADCASTFILTERED            0x0230
++#define TITAN_GE_MSTATX_HASHFILTERED                 0x0240
++#define TITAN_GE_MSTATX_TXFRAMESOK                   0x0250
++#define TITAN_GE_MSTATX_TXOCTETSOK                   0x0260
++#define TITAN_GE_MSTATX_TXOCTETS                     0x0270
++#define TITAN_GE_MSTATX_TXTAGGEDFRAMESOK             0x0280
++#define TITAN_GE_MSTATX_TXMACPAUSECONTROLFRAMESOK    0x0290
++#define TITAN_GE_MSTATX_TXFCSERROR                   0x02A0
++#define TITAN_GE_MSTATX_TXSHORTLENGTHERROR           0x02B0
++#define TITAN_GE_MSTATX_TXLONGLENGTHERROR            0x02C0
++#define TITAN_GE_MSTATX_TXSYSTEMERROR                0x02D0
++#define TITAN_GE_MSTATX_TXMACERROR                   0x02E0
++#define TITAN_GE_MSTATX_TXCARRIERSENSEERROR          0x02F0
++#define TITAN_GE_MSTATX_TXSQETESTERROR               0x0300
++#define TITAN_GE_MSTATX_TXUNICASTFRAMESOK            0x0310
++#define TITAN_GE_MSTATX_TXBROADCASTFRAMESOK          0x0320
++#define TITAN_GE_MSTATX_TXMULTICASTFRAMESOK          0x0330
++#define TITAN_GE_MSTATX_TXUNICASTFRAMESATTEMPTED     0x0340
++#define TITAN_GE_MSTATX_TXBROADCASTFRAMESATTEMPTED   0x0350
++#define TITAN_GE_MSTATX_TXMULTICASTFRAMESATTEMPTED   0x0360
++#define TITAN_GE_MSTATX_TXFRAMES64OCTETS             0x0370
++#define TITAN_GE_MSTATX_TXFRAMES65TO127OCTETS        0x0380
++#define TITAN_GE_MSTATX_TXFRAMES128TO255OCTETS       0x0390
++#define TITAN_GE_MSTATX_TXFRAMES256TO511OCTETS       0x03A0
++#define TITAN_GE_MSTATX_TXFRAMES512TO1023OCTETS      0x03B0
++#define TITAN_GE_MSTATX_TXFRAMES1024TO1518OCTETS     0x03C0
++#define TITAN_GE_MSTATX_TXFRAMES1519TOMAXSIZE        0x03D0
++#define TITAN_GE_MSTATX_TXVARIABLE                   0x03E0
++#define TITAN_GE_MSTATX_RXSYSTEMERROR                0x03F0
++#define TITAN_GE_MSTATX_SINGLECOLLISION              0x0400
++#define TITAN_GE_MSTATX_MULTIPLECOLLISION            0x0410
++#define TITAN_GE_MSTATX_DEFERREDXMISSIONS            0x0420
++#define TITAN_GE_MSTATX_LATECOLLISIONS               0x0430
++#define TITAN_GE_MSTATX_ABORTEDDUETOXSCOLLS          0x0440
++
++/* Interrupt specific defines */
++#define TITAN_GE_DEVICE_ID         0x0000  /* Device ID */
++#define TITAN_GE_RESET             0x0004  /* Reset reg */
++#define TITAN_GE_TSB_CTRL_0        0x000C  /* TSB Control reg 0 */
++#define TITAN_GE_TSB_CTRL_1        0x0010  /* TSB Control reg 1 */
++#define TITAN_GE_INTR_GRP0_STATUS  0x0040  /* General Interrupt Group 0 Status */
++#define TITAN_GE_INTR_XDMA_CORE_A  0x0048  /* XDMA Channel Interrupt Status, Core A*/
++#define TITAN_GE_INTR_XDMA_CORE_B  0x004C  /* XDMA Channel Interrupt Status, Core B*/
++#define	TITAN_GE_INTR_XDMA_IE	   0x0058  /* XDMA Channel Interrupt Enable */
++#define TITAN_GE_SDQPF_ECC_INTR    0x480C  /* SDQPF ECC Interrupt Status */
++#define TITAN_GE_SDQPF_RXFIFO_CTL  0x4828  /* SDQPF RxFifo Control and Interrupt Enb*/
++#define TITAN_GE_SDQPF_RXFIFO_INTR 0x482C  /* SDQPF RxFifo Interrupt Status */
++#define TITAN_GE_SDQPF_TXFIFO_CTL  0x4928  /* SDQPF TxFifo Control and Interrupt Enb*/
++#define TITAN_GE_SDQPF_TXFIFO_INTR 0x492C  /* SDQPF TxFifo Interrupt Status */
++#define	TITAN_GE_SDQPF_RXFIFO_0	   0x4840  /* SDQPF RxFIFO Enable */
++#define	TITAN_GE_SDQPF_TXFIFO_0	   0x4940  /* SDQPF TxFIFO Enable */
++#define TITAN_GE_XDMA_CONFIG       0x5000  /* XDMA Global Configuration */
++#define TITAN_GE_XDMA_INTR_SUMMARY 0x5010  /* XDMA Interrupt Summary */
++#define TITAN_GE_XDMA_BUFADDRPRE   0x5018  /* XDMA Buffer Address Prefix */
++#define TITAN_GE_XDMA_DESCADDRPRE  0x501C  /* XDMA Descriptor Address Prefix */
++#define TITAN_GE_XDMA_PORTWEIGHT   0x502C  /* XDMA Port Weight Configuration */
++
++/* Rx MAC defines */
++#define TITAN_GE_RMAC_CONFIG_1               0x1200  /* RMAC Configuration 1 */
++#define TITAN_GE_RMAC_CONFIG_2               0x1204  /* RMAC Configuration 2 */
++#define TITAN_GE_RMAC_MAX_FRAME_LEN          0x1208  /* RMAC Max Frame Length */
++#define TITAN_GE_RMAC_STATION_HI             0x120C  /* Rx Station Address High */
++#define TITAN_GE_RMAC_STATION_MID            0x1210  /* Rx Station Address Middle */
++#define TITAN_GE_RMAC_STATION_LOW            0x1214  /* Rx Station Address Low */
++#define TITAN_GE_RMAC_LINK_CONFIG            0x1218  /* RMAC Link Configuration */
++
++/* Tx MAC defines */
++#define TITAN_GE_TMAC_CONFIG_1               0x1240  /* TMAC Configuration 1 */
++#define TITAN_GE_TMAC_CONFIG_2               0x1244  /* TMAC Configuration 2 */
++#define TITAN_GE_TMAC_IPG                    0x1248  /* TMAC Inter-Packet Gap */
++#define TITAN_GE_TMAC_STATION_HI             0x124C  /* Tx Station Address High */
++#define TITAN_GE_TMAC_STATION_MID            0x1250  /* Tx Station Address Middle */
++#define TITAN_GE_TMAC_STATION_LOW            0x1254  /* Tx Station Address Low */
++#define TITAN_GE_TMAC_MAX_FRAME_LEN          0x1258  /* TMAC Max Frame Length */
++#define TITAN_GE_TMAC_MIN_FRAME_LEN          0x125C  /* TMAC Min Frame Length */
++#define TITAN_GE_TMAC_PAUSE_FRAME_TIME       0x1260  /* TMAC Pause Frame Time */
++#define TITAN_GE_TMAC_PAUSE_FRAME_INTERVAL   0x1264  /* TMAC Pause Frame Interval */
++
++/* GMII register */
++#define TITAN_GE_GMII_INTERRUPT_STATUS       0x1348  /* GMII Interrupt Status */
++#define TITAN_GE_GMII_CONFIG_GENERAL         0x134C  /* GMII Configuration General */
++#define TITAN_GE_GMII_CONFIG_MODE            0x1350  /* GMII Configuration Mode */
++
++/* Tx and Rx XDMA defines */
++#define	TITAN_GE_INT_COALESCING		     0x5030 /* Interrupt Coalescing */
++#define	TITAN_GE_CHANNEL0_CONFIG	     0x5040 /* Channel 0 XDMA config */
++#define	TITAN_GE_CHANNEL0_INTERRUPT	     0x504c /* Channel 0 Interrupt Status */
++#define	TITAN_GE_GDI_INTERRUPT_ENABLE        0x5050 /* IE for the GDI Errors */
++#define	TITAN_GE_CHANNEL0_PACKET	     0x5060 /* Channel 0 Packet count */
++#define	TITAN_GE_CHANNEL0_BYTE		     0x5064 /* Channel 0 Byte count */
++#define	TITAN_GE_CHANNEL0_TX_DESC	     0x5054 /* Channel 0 Tx first desc */
++#define	TITAN_GE_CHANNEL0_RX_DESC	     0x5058 /* Channel 0 Rx first desc */
++
++/* AFX (Address Filter Exact) register offsets for Slice 0 */
++#define TITAN_GE_AFX_EXACT_MATCH_LOW         0x1100  /* AFX Exact Match Address Low*/
++#define TITAN_GE_AFX_EXACT_MATCH_MID         0x1104  /* AFX Exact Match Address Mid*/
++#define TITAN_GE_AFX_EXACT_MATCH_HIGH        0x1108  /* AFX Exact Match Address Hi */
++#define TITAN_GE_AFX_EXACT_MATCH_VID         0x110C  /* AFX Exact Match VID */
++#define TITAN_GE_AFX_MULTICAST_HASH_LOW      0x1110  /* AFX Multicast HASH Low */
++#define TITAN_GE_AFX_MULTICAST_HASH_MIDLOW   0x1114  /* AFX Multicast HASH MidLow */
++#define TITAN_GE_AFX_MULTICAST_HASH_MIDHI    0x1118  /* AFX Multicast HASH MidHi */
++#define TITAN_GE_AFX_MULTICAST_HASH_HI       0x111C  /* AFX Multicast HASH Hi */
++#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_0     0x1120  /* AFX Address Filter Ctrl 0 */
++#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_1     0x1124  /* AFX Address Filter Ctrl 1 */
++#define TITAN_GE_AFX_ADDRS_FILTER_CTRL_2     0x1128  /* AFX Address Filter Ctrl 2 */
++
++/* Traffic Groomer block */
++#define        TITAN_GE_TRTG_CONFIG	     0x1000  /* TRTG Config */
++
++#endif 				/* _TITAN_GE_H_ */
++
+diff -urpNX dontdiff linux-2.6.10/drivers/net/titan_mdio.c linux-2.6.10-mips/drivers/net/titan_mdio.c
+--- linux-2.6.10/drivers/net/titan_mdio.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/titan_mdio.c	2004-10-20 17:57:59.000000000 +0200
+@@ -0,0 +1,217 @@
++/*
++ * drivers/net/titan_mdio.c - Driver for Titan ethernet ports
++ *
++ * Copyright (C) 2003 PMC-Sierra Inc.
++ * Author : Manish Lachwani (lachwani at pmc-sierra.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
++ *
++ * Management Data IO (MDIO) driver for the Titan GMII. Interacts with the Marvel PHY
++ * on the Titan. No support for the TBI as yet.
++ *
++ */
++
++#include	"titan_mdio.h"
++
++#define MDIO_DEBUG
++
++/*
++ * Local constants
++ */
++#define MAX_CLKA            1023
++#define MAX_PHY_DEV         31
++#define MAX_PHY_REG         31
++#define WRITEADDRS_OPCODE   0x0
++#define	READ_OPCODE	    0x2
++#define WRITE_OPCODE        0x1
++#define MAX_MDIO_POLL       100
++
++/*
++ * Titan MDIO and SCMB registers
++ */
++#define TITAN_GE_SCMB_CONTROL                0x01c0  /* SCMB Control */
++#define TITAN_GE_SCMB_CLKA	             0x01c4  /* SCMB Clock A */
++#define TITAN_GE_MDIO_COMMAND                0x01d0  /* MDIO Command */
++#define TITAN_GE_MDIO_DEVICE_PORT_ADDRESS    0x01d4  /* MDIO Device and Port addrs */
++#define TITAN_GE_MDIO_DATA                   0x01d8  /* MDIO Data */
++#define TITAN_GE_MDIO_INTERRUPTS             0x01dC  /* MDIO Interrupts */
++
++/*
++ * Function to poll the MDIO
++ */
++static int titan_ge_mdio_poll(void)
++{
++	int	i, val;
++
++	for (i = 0; i < MAX_MDIO_POLL; i++) {
++		val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
++
++		if (!(val & 0x8000))
++			return TITAN_GE_MDIO_GOOD;
++	}
++
++	return TITAN_GE_MDIO_ERROR;
++}
++
++
++/*
++ * Initialize and configure the MDIO
++ */
++int titan_ge_mdio_setup(titan_ge_mdio_config *titan_mdio)
++{
++	unsigned long	val;
++
++	/* Reset the SCMB and program into MDIO mode*/
++	TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x9000);
++	TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CONTROL, 0x1000);
++
++	/* CLK A */
++	val = TITAN_GE_MDIO_READ(TITAN_GE_SCMB_CLKA);
++	val = ( (val & ~(0x03ff)) | (titan_mdio->clka & 0x03ff));
++	TITAN_GE_MDIO_WRITE(TITAN_GE_SCMB_CLKA, val);
++
++	/* Preamble Suppresion */
++	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
++	val = ( (val & ~(0x0001)) | (titan_mdio->mdio_spre & 0x0001));
++	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
++
++	/* MDIO mode */
++	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
++	val = ( (val & ~(0x4000)) | (titan_mdio->mdio_mode & 0x4000));
++	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
++
++	return TITAN_GE_MDIO_GOOD;
++}
++
++/*
++ * Set the PHY address in indirect mode
++ */
++int titan_ge_mdio_inaddrs(int dev_addr, int reg_addr)
++{
++	volatile unsigned long	val;
++
++	/* Setup the PHY device */
++	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
++	val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
++	val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
++	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
++
++	/* Write the new address */
++	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
++	val = ( (val & ~(0x0300)) | ( (WRITEADDRS_OPCODE << 8) & 0x0300));
++	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
++
++	return TITAN_GE_MDIO_GOOD;
++}
++
++/*
++ * Read the MDIO register. This is what the individual parametes mean:
++ *
++ * dev_addr : PHY ID
++ * reg_addr : register offset
++ *
++ * See the spec for the Titan MAC. We operate in the Direct Mode.
++ */
++
++#define MAX_RETRIES	2
++
++int titan_ge_mdio_read(int dev_addr, int reg_addr, unsigned int *pdata)
++{
++	volatile unsigned long	val;
++	int retries = 0;
++
++	/* Setup the PHY device */
++
++again:
++	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
++	val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
++	val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
++	val |= 0x4000;
++	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
++
++	udelay(30);
++
++	/* Issue the read command */
++	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
++	val = ( (val & ~(0x0300)) | ( (READ_OPCODE << 8) & 0x0300));
++	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
++
++	udelay(30);
++
++	if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
++		return TITAN_GE_MDIO_ERROR;
++
++	*pdata = (unsigned int)TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DATA);
++	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS);
++
++	udelay(30);
++
++	if (val & 0x2) {
++		if (retries == MAX_RETRIES)
++			return TITAN_GE_MDIO_ERROR;
++		else {
++			retries++;
++			goto again;
++		}
++	}
++
++	return TITAN_GE_MDIO_GOOD;
++}
++
++/*
++ * Write to the MDIO register
++ *
++ * dev_addr : PHY ID
++ * reg_addr : register that needs to be written to
++ *
++ */
++int titan_ge_mdio_write(int dev_addr, int reg_addr, unsigned int data)
++{
++	volatile unsigned long	val;
++
++	if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
++		return TITAN_GE_MDIO_ERROR;
++
++	/* Setup the PHY device */
++	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS);
++	val = ( (val & ~(0x1f00)) | ( (dev_addr << 8) & 0x1f00));
++	val = ( (val & ~(0x001f)) | ( reg_addr & 0x001f));
++	val |= 0x4000;
++	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DEVICE_PORT_ADDRESS, val);
++
++	udelay(30);
++
++	/* Setup the data to write */
++	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_DATA, data);
++
++	udelay(30);
++
++	/* Issue the write command */
++	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_COMMAND);
++	val = ( (val & ~(0x0300)) | ( (WRITE_OPCODE << 8) & 0x0300));
++	TITAN_GE_MDIO_WRITE(TITAN_GE_MDIO_COMMAND, val);
++
++	udelay(30);
++
++	if (titan_ge_mdio_poll() != TITAN_GE_MDIO_GOOD)
++		return TITAN_GE_MDIO_ERROR;
++
++	val = TITAN_GE_MDIO_READ(TITAN_GE_MDIO_INTERRUPTS);
++	if (val & 0x2)
++		return TITAN_GE_MDIO_ERROR;
++
++	return TITAN_GE_MDIO_GOOD;
++}
++
+diff -urpNX dontdiff linux-2.6.10/drivers/net/titan_mdio.h linux-2.6.10-mips/drivers/net/titan_mdio.h
+--- linux-2.6.10/drivers/net/titan_mdio.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/net/titan_mdio.h	2004-10-20 17:57:59.000000000 +0200
+@@ -0,0 +1,56 @@
++/*
++ * MDIO used to interact with the PHY when using GMII/MII
++ */
++#ifndef _TITAN_MDIO_H
++#define _TITAN_MDIO_H
++
++#include <linux/netdevice.h>
++#include <linux/workqueue.h>
++#include <linux/delay.h>
++#include "titan_ge.h"
++
++
++#define	TITAN_GE_MDIO_ERROR	(-9000)
++#define	TITAN_GE_MDIO_GOOD	0
++
++#define	TITAN_GE_MDIO_BASE		titan_ge_base
++
++#define	TITAN_GE_MDIO_READ(offset)	\
++	*(volatile u32 *)(titan_ge_base + (offset))
++
++#define	TITAN_GE_MDIO_WRITE(offset, data)	\
++	*(volatile u32 *)(titan_ge_base + (offset)) = (data)
++
++
++/* GMII specific registers */
++#define	TITAN_GE_MARVEL_PHY_ID		0x00
++#define	TITAN_PHY_AUTONEG_ADV		0x04
++#define	TITAN_PHY_LP_ABILITY		0x05
++#define	TITAN_GE_MDIO_MII_CTRL		0x09
++#define	TITAN_GE_MDIO_MII_EXTENDED	0x0f
++#define	TITAN_GE_MDIO_PHY_CTRL		0x10
++#define	TITAN_GE_MDIO_PHY_STATUS	0x11
++#define	TITAN_GE_MDIO_PHY_IE		0x12
++#define	TITAN_GE_MDIO_PHY_IS		0x13
++#define	TITAN_GE_MDIO_PHY_LED		0x18
++#define	TITAN_GE_MDIO_PHY_LED_OVER	0x19
++#define	PHY_ANEG_TIME_WAIT		45	/* 45 seconds wait time */
++
++/*
++ * MDIO Config Structure
++ */
++typedef struct {
++	unsigned int		clka;
++	int			mdio_spre;
++	int			mdio_mode;
++} titan_ge_mdio_config;
++
++/*
++ * Function Prototypes
++ */
++int titan_ge_mdio_setup(titan_ge_mdio_config *);
++int titan_ge_mdio_inaddrs(int, int);
++int titan_ge_mdio_read(int, int, unsigned int *);
++int titan_ge_mdio_write(int, int, unsigned int);
++
++#endif /* _TITAN_MDIO_H */
+diff -urpNX dontdiff linux-2.6.10/drivers/pci/pci.ids linux-2.6.10-mips/drivers/pci/pci.ids
+--- linux-2.6.10/drivers/pci/pci.ids	2004-12-24 22:34:57.000000000 +0100
++++ linux-2.6.10-mips/drivers/pci/pci.ids	2004-10-27 02:14:43.000000000 +0200
+@@ -4433,6 +4433,7 @@
+ 11ab  Marvell Technology Group Ltd.
+ 	0146  GT-64010/64010A System Controller
+ 	1fa6  Marvell W8300 802.11 Adapter
++	4146  GT-64011/GT-64111 System Controller
+ 	4320  Yukon Gigabit Ethernet 10/100/1000Base-T Adapter
+ 	4611  GT-64115 System Controller
+ 	4620  GT-64120/64120A/64121A System Controller
+@@ -6257,7 +6258,7 @@
+ 14d8  HOPF Elektronik GmBH
+ # Formerly SiPackets, Inc., formerly API NetWorks, Inc., formerly Alpha Processor, Inc.
+ 14d9  Alliance Semiconductor Corporation
+-	0010  AP1011/SP1011 HyperTransport-PCI Bridge [Sturgeon]
++	0010  AP1011 HyperTransport-PCI Bridge [Sturgeon]
+ 14da  National Aerospace Laboratories
+ 14db  AFAVLAB Technology Inc
+ 	2120  TK9902
+diff -urpNX dontdiff linux-2.6.10/drivers/pci/probe.c linux-2.6.10-mips/drivers/pci/probe.c
+--- linux-2.6.10/drivers/pci/probe.c	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/drivers/pci/probe.c	2004-12-21 03:25:24.000000000 +0100
+@@ -490,6 +490,7 @@ static int pci_setup_device(struct pci_d
+ 
+ 	/* Early fixups, before probing the BARs */
+ 	pci_fixup_device(pci_fixup_early, dev);
++	class = dev->class >> 8;
+ 
+ 	switch (dev->hdr_type) {		    /* header type */
+ 	case PCI_HEADER_TYPE_NORMAL:		    /* standard header */
+diff -urpNX dontdiff linux-2.6.10/drivers/pci/quirks.c linux-2.6.10-mips/drivers/pci/quirks.c
+--- linux-2.6.10/drivers/pci/quirks.c	2004-12-24 22:33:49.000000000 +0100
++++ linux-2.6.10-mips/drivers/pci/quirks.c	2004-12-21 03:25:24.000000000 +0100
+@@ -1237,6 +1237,8 @@ static void pci_do_fixups(struct pci_dev
+ 	}
+ }
+ 
++extern struct pci_fixup __start_pci_fixups_early[];
++extern struct pci_fixup __end_pci_fixups_early[];
+ extern struct pci_fixup __start_pci_fixups_header[];
+ extern struct pci_fixup __end_pci_fixups_header[];
+ extern struct pci_fixup __start_pci_fixups_final[];
+@@ -1250,6 +1252,11 @@ void pci_fixup_device(enum pci_fixup_pas
+ 	struct pci_fixup *start, *end;
+ 
+ 	switch(pass) {
++	case pci_fixup_early:
++		start = __start_pci_fixups_early;
++		end = __end_pci_fixups_early;
++		break;
++
+ 	case pci_fixup_header:
+ 		start = __start_pci_fixups_header;
+ 		end = __end_pci_fixups_header;
+diff -urpNX dontdiff linux-2.6.10/drivers/pcmcia/Kconfig linux-2.6.10-mips/drivers/pcmcia/Kconfig
+--- linux-2.6.10/drivers/pcmcia/Kconfig	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/drivers/pcmcia/Kconfig	2004-10-27 02:14:43.000000000 +0200
+@@ -141,6 +141,10 @@ config HD64465_PCMCIA
+ 	tristate "HD64465 host bridge support"
+ 	depends on HD64465 && PCMCIA
+ 
++config PCMCIA_AU1X00
++	tristate "Au1x00 pcmcia support"
++	depends on SOC_AU1X00 && PCMCIA
++
+ config PCMCIA_SA1100
+ 	tristate "SA1100 support"
+ 	depends on ARM && ARCH_SA1100 && PCMCIA
+@@ -190,4 +194,13 @@ config M32R_CFC_NUM
+ 	help
+ 	  Set the number of M32R CF slots.
+ 
++config PCMCIA_VRC4171
++	tristate "NEC VRC4171 Card Controllers support"
++	depends on VRC4171 && PCMCIA
++
++config PCMCIA_VRC4173
++	tristate "NEC VRC4173 CARDU support"
++	depends on CPU_VR41XX && PCI && PCMCIA
++
+ endmenu
++
+diff -urpNX dontdiff linux-2.6.10/drivers/pcmcia/Makefile linux-2.6.10-mips/drivers/pcmcia/Makefile
+--- linux-2.6.10/drivers/pcmcia/Makefile	2004-12-24 22:35:24.000000000 +0100
++++ linux-2.6.10-mips/drivers/pcmcia/Makefile	2004-11-19 01:14:38.000000000 +0100
+@@ -26,8 +26,12 @@ obj-$(CONFIG_HD64465_PCMCIA)			+= hd6446
+ obj-$(CONFIG_PCMCIA_SA1100)			+= sa11xx_core.o sa1100_cs.o
+ obj-$(CONFIG_PCMCIA_SA1111)			+= sa11xx_core.o sa1111_cs.o
+ obj-$(CONFIG_PCMCIA_PXA2XX)                     += pxa2xx_core.o pxa2xx_cs.o
+-obj-$(CONFIG_M32R_PCC)				+= m32r_pcc.o
+-obj-$(CONFIG_M32R_CFC)				+= m32r_cfc.o
++obj-$(CONFIG_PCMCIA_VRC4171)			+= vrc4171_card.o
++obj-$(CONFIG_PCMCIA_VRC4173)			+= vrc4173_cardu.o
++obj-$(CONFIG_PCMCIA_AU1X00)			+= au1x00_ss.o
++
++pcmcia_core-y					+= cistpl.o rsrc_mgr.o bulkmem.o cs.o socket_sysfs.o
++pcmcia_core-$(CONFIG_CARDBUS)			+= cardbus.o
+ 
+ sa11xx_core-y					+= soc_common.o sa11xx_base.o
+ pxa2xx_core-y					+= soc_common.o pxa2xx_base.o
+@@ -37,6 +41,16 @@ sa1111_cs-$(CONFIG_ASSABET_NEPONSET)		+=
+ sa1111_cs-$(CONFIG_SA1100_BADGE4)		+= sa1100_badge4.o
+ sa1111_cs-$(CONFIG_SA1100_JORNADA720)		+= sa1100_jornada720.o
+ 
++au1x00_ss-y					+= au1000_generic.o
++au1x00_ss-$(CONFIG_MIPS_PB1000)			+= au1000_pb1x00.o
++au1x00_ss-$(CONFIG_MIPS_PB1100)			+= au1000_pb1x00.o
++au1x00_ss-$(CONFIG_MIPS_PB1500)			+= au1000_pb1x00.o
++au1x00_ss-$(CONFIG_MIPS_DB1000)			+= au1000_db1x00.o
++au1x00_ss-$(CONFIG_MIPS_DB1100)			+= au1000_db1x00.o
++au1x00_ss-$(CONFIG_MIPS_DB1500)			+= au1000_db1x00.o
++au1x00_ss-$(CONFIG_MIPS_DB1550)			+= au1000_db1x00.o
++au1x00_ss-$(CONFIG_MIPS_XXS1500)	 	+= au1000_xxs1500.o
++
+ sa1100_cs-y					+= sa1100_generic.o
+ sa1100_cs-$(CONFIG_SA1100_ASSABET)		+= sa1100_assabet.o
+ sa1100_cs-$(CONFIG_SA1100_CERF)			+= sa1100_cerf.o
+diff -urpNX dontdiff linux-2.6.10/drivers/pcmcia/au1000_db1x00.c linux-2.6.10-mips/drivers/pcmcia/au1000_db1x00.c
+--- linux-2.6.10/drivers/pcmcia/au1000_db1x00.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/pcmcia/au1000_db1x00.c	2004-10-27 02:14:43.000000000 +0200
+@@ -0,0 +1,288 @@
++/*
++ *
++ * Alchemy Semi Db1x00 boards specific pcmcia routines.
++ *
++ * Copyright 2002 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc.
++ *         	ppopov at mvista.com or source at mvista.com
++ *
++ * Copyright 2004 Pete Popov, updated the driver to 2.6.
++ * Followed the sa11xx API and largely copied many of the hardware
++ * independent functions. 
++ *
++ * ########################################################################
++ *
++ *  This program is free software; you can distribute 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 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 <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/interrupt.h>
++#include <linux/device.h>
++#include <linux/init.h>
++
++#include <asm/irq.h>
++#include <asm/signal.h>
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-db1x00/db1x00.h>
++
++#include "au1000_generic.h"
++
++#if 0
++#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
++#else
++#define debug(x,args...)
++#endif
++
++static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
++
++struct au1000_pcmcia_socket au1000_pcmcia_socket[PCMCIA_NUM_SOCKS];
++extern int au1x00_pcmcia_socket_probe(struct device *, struct pcmcia_low_level *, int, int);
++
++static int db1x00_pcmcia_hw_init(struct au1000_pcmcia_socket *skt)
++{
++#ifdef CONFIG_MIPS_DB1550
++	skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_3;
++#else
++	skt->irq = skt->nr ? AU1000_GPIO_5 : AU1000_GPIO_2;
++#endif
++	return 0;
++}
++
++static void db1x00_pcmcia_shutdown(struct au1000_pcmcia_socket *skt)
++{
++	bcsr->pcmcia = 0; /* turn off power */
++	au_sync_delay(2);
++}
++
++static void 
++db1x00_pcmcia_socket_state(struct au1000_pcmcia_socket *skt, struct pcmcia_state *state)
++{
++	u32 inserted;
++	unsigned char vs;
++
++	state->ready = 0;
++	state->vs_Xv = 0;
++	state->vs_3v = 0;
++	state->detect = 0;
++
++	switch (skt->nr) {
++	case 0:
++		vs = bcsr->status & 0x3;
++		inserted = !(bcsr->status & (1<<4));
++		break;
++	case 1:
++		vs = (bcsr->status & 0xC)>>2;
++		inserted = !(bcsr->status & (1<<5));
++		break;
++	default:/* should never happen */
++		return;
++	}
++
++	if (inserted) 
++		debug("db1x00 socket %d: inserted %d, vs %d pcmcia %x\n", 
++				skt->nr, inserted, vs, bcsr->pcmcia);
++
++	if (inserted) {
++		switch (vs) {
++			case 0:
++			case 2:
++				state->vs_3v=1;
++				break;
++			case 3: /* 5V */
++				break;
++			default:
++				/* return without setting 'detect' */
++				printk(KERN_ERR "db1x00 bad VS (%d)\n",
++						vs);
++		}
++		state->detect = 1;
++		state->ready = 1;
++	}
++	else {
++		/* if the card was previously inserted and then ejected,
++		 * we should turn off power to it
++		 */
++		if ((skt->nr == 0) && (bcsr->pcmcia & BCSR_PCMCIA_PC0RST)) {
++			bcsr->pcmcia &= ~(BCSR_PCMCIA_PC0RST | 
++					BCSR_PCMCIA_PC0DRVEN |
++					BCSR_PCMCIA_PC0VPP |
++					BCSR_PCMCIA_PC0VCC);
++			au_sync_delay(10);
++		}
++		else if ((skt->nr == 1) && bcsr->pcmcia & BCSR_PCMCIA_PC1RST) {
++			bcsr->pcmcia &= ~(BCSR_PCMCIA_PC1RST | 
++					BCSR_PCMCIA_PC1DRVEN |
++					BCSR_PCMCIA_PC1VPP |
++					BCSR_PCMCIA_PC1VCC);
++			au_sync_delay(10);
++		}
++	}
++
++	state->bvd1=1;
++	state->bvd2=1;
++	state->wrprot=0; 
++}
++
++static int 
++db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_state_t *state)
++{
++	u16 pwr;
++	int sock = skt->nr;
++
++	debug("config_skt %d Vcc %dV Vpp %dV, reset %d\n", 
++			sock, state->Vcc, state->Vpp, 
++			state->flags & SS_RESET);
++
++	/* pcmcia reg was set to zero at init time. Be careful when
++	 * initializing a socket not to wipe out the settings of the 
++	 * other socket.
++	 */
++	pwr = bcsr->pcmcia;
++	pwr &= ~(0xf << sock*8); /* clear voltage settings */
++
++	state->Vpp = 0;
++	switch(state->Vcc){
++		case 0:  /* Vcc 0 */
++			pwr |= SET_VCC_VPP(0,0,sock);
++			break;
++		case 50: /* Vcc 5V */
++			switch(state->Vpp) {
++				case 0:
++					pwr |= SET_VCC_VPP(2,0,sock);
++					break;
++				case 50:
++					pwr |= SET_VCC_VPP(2,1,sock);
++					break;
++				case 12:
++					pwr |= SET_VCC_VPP(2,2,sock);
++					break;
++				case 33:
++				default:
++					pwr |= SET_VCC_VPP(0,0,sock);
++					printk("%s: bad Vcc/Vpp (%d:%d)\n", 
++							__FUNCTION__, 
++							state->Vcc, 
++							state->Vpp);
++					break;
++			}
++			break;
++		case 33: /* Vcc 3.3V */
++			switch(state->Vpp) {
++				case 0:
++					pwr |= SET_VCC_VPP(1,0,sock);
++					break;
++				case 12:
++					pwr |= SET_VCC_VPP(1,2,sock);
++					break;
++				case 33:
++					pwr |= SET_VCC_VPP(1,1,sock);
++					break;
++				case 50:
++				default:
++					pwr |= SET_VCC_VPP(0,0,sock);
++					printk("%s: bad Vcc/Vpp (%d:%d)\n", 
++							__FUNCTION__, 
++							state->Vcc, 
++							state->Vpp);
++					break;
++			}
++			break;
++		default: /* what's this ? */
++			pwr |= SET_VCC_VPP(0,0,sock);
++			printk(KERN_ERR "%s: bad Vcc %d\n", 
++					__FUNCTION__, state->Vcc);
++			break;
++	}
++
++	bcsr->pcmcia = pwr;
++	au_sync_delay(300);
++
++	if (sock == 0) {
++		if (!(state->flags & SS_RESET)) {
++			pwr |= BCSR_PCMCIA_PC0DRVEN;
++			bcsr->pcmcia = pwr;
++			au_sync_delay(300);
++			pwr |= BCSR_PCMCIA_PC0RST;
++			bcsr->pcmcia = pwr;
++			au_sync_delay(100);
++		}
++		else {
++			pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN);
++			bcsr->pcmcia = pwr;
++			au_sync_delay(100);
++		}
++	}
++	else {
++		if (!(state->flags & SS_RESET)) {
++			pwr |= BCSR_PCMCIA_PC1DRVEN;
++			bcsr->pcmcia = pwr;
++			au_sync_delay(300);
++			pwr |= BCSR_PCMCIA_PC1RST;
++			bcsr->pcmcia = pwr;
++			au_sync_delay(100);
++		}
++		else {
++			pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN);
++			bcsr->pcmcia = pwr;
++			au_sync_delay(100);
++		}
++	}
++	return 0;
++}
++
++/*
++ * Enable card status IRQs on (re-)initialisation.  This can
++ * be called at initialisation, power management event, or
++ * pcmcia event.
++ */
++void db1x00_socket_init(struct au1000_pcmcia_socket *skt)
++{
++	/* nothing to do for now */
++}
++
++/*
++ * Disable card status IRQs and PCMCIA bus on suspend.
++ */
++void db1x00_socket_suspend(struct au1000_pcmcia_socket *skt)
++{
++	/* nothing to do for now */
++}
++
++struct pcmcia_low_level db1x00_pcmcia_ops = { 
++	.owner			= THIS_MODULE,
++
++	.hw_init 		= db1x00_pcmcia_hw_init,
++	.hw_shutdown		= db1x00_pcmcia_shutdown,
++
++	.socket_state		= db1x00_pcmcia_socket_state,
++	.configure_socket	= db1x00_pcmcia_configure_socket,
++
++	.socket_init		= db1x00_socket_init,
++	.socket_suspend		= db1x00_socket_suspend
++};
++
++int __init au1x_board_init(struct device *dev)
++{
++	int ret = -ENODEV;
++	bcsr->pcmcia = 0; /* turn off power, if it's not already off */
++	au_sync_delay(2);
++	ret = au1x00_pcmcia_socket_probe(dev, &db1x00_pcmcia_ops, 0, 2);
++	return ret;
++}
+diff -urpNX dontdiff linux-2.6.10/drivers/pcmcia/au1000_generic.c linux-2.6.10-mips/drivers/pcmcia/au1000_generic.c
+--- linux-2.6.10/drivers/pcmcia/au1000_generic.c	2004-12-24 22:34:58.000000000 +0100
++++ linux-2.6.10-mips/drivers/pcmcia/au1000_generic.c	2005-01-03 18:57:20.000000000 +0100
+@@ -2,9 +2,13 @@
+  *
+  * Alchemy Semi Au1000 pcmcia driver
+  *
+- * Copyright 2001 MontaVista Software Inc.
++ * Copyright 2001-2003 MontaVista Software Inc.
+  * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
++ *         	ppopov at embeddedalley.com or source at mvista.com
++ *
++ * Copyright 2004 Pete Popov, Embedded Alley Solutions, Inc.
++ * Updated the driver to 2.6. Followed the sa11xx API and largely 
++ * copied many of the hardware independent functions. 
+  *
+  * ########################################################################
+  *
+@@ -25,450 +29,254 @@
+  *
+  * 
+  */
++
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+ #include <linux/init.h>
+ #include <linux/config.h>
+-#include <linux/delay.h>
++#include <linux/cpufreq.h>
+ #include <linux/ioport.h>
+ #include <linux/kernel.h>
+-#include <linux/tqueue.h>
+ #include <linux/timer.h>
+ #include <linux/mm.h>
+-#include <linux/proc_fs.h>
+-#include <linux/types.h>
+-#include <linux/vmalloc.h>
+-
+-#include <pcmcia/version.h>
+-#include <pcmcia/cs_types.h>
+-#include <pcmcia/cs.h>
+-#include <pcmcia/ss.h>
+-#include <pcmcia/bulkmem.h>
+-#include <pcmcia/cistpl.h>
+-#include <pcmcia/bus_ops.h>
+-#include "cs_internal.h"
++#include <linux/notifier.h>
++#include <linux/interrupt.h>
++#include <linux/spinlock.h>
++#include <linux/device.h>
+ 
+ #include <asm/io.h>
+ #include <asm/irq.h>
+ #include <asm/system.h>
+ 
+-#include <asm/au1000.h>
+-#include <asm/au1000_pcmcia.h>
+-
+-#ifdef DEBUG
+-static int pc_debug;
+-
+-module_param(pc_debug, int, 0644);
+-
+-#define debug(lvl,fmt) do {			\
+-	if (pc_debug > (lvl))			\
+-		printk(KERN_DEBUG fmt);		\
+-} while (0)
+-#else
+-#define debug(lvl,fmt) do { } while (0)
+-#endif
++#include <asm/mach-au1x00/au1000.h>
++#include "au1000_generic.h"
+ 
+ MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("Pete Popov, MontaVista Software <ppopov at mvista.com>");
++MODULE_AUTHOR("Pete Popov <ppopov at embeddedalley.com>");
+ MODULE_DESCRIPTION("Linux PCMCIA Card Services: Au1x00 Socket Controller");
+ 
+-#define MAP_SIZE 0x1000000
+-
+-/* This structure maintains housekeeping state for each socket, such
+- * as the last known values of the card detect pins, or the Card Services
+- * callback value associated with the socket:
+- */
+-static struct au1000_pcmcia_socket *pcmcia_socket;
+-static int socket_count;
+-
+-
+-/* Returned by the low-level PCMCIA interface: */
+-static struct pcmcia_low_level *pcmcia_low_level;
+-
+-/* Event poll timer structure */
+-static struct timer_list poll_timer;
+-
+-
+-/* Prototypes for routines which are used internally: */
+-
+-static int  au1000_pcmcia_driver_init(void);
+-static void au1000_pcmcia_driver_shutdown(void);
+-static void au1000_pcmcia_task_handler(void *data);
+-static void au1000_pcmcia_poll_event(unsigned long data);
+-static void au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs);
+-static struct tq_struct au1000_pcmcia_task;
+-
+-#ifdef CONFIG_PROC_FS
+-static int au1000_pcmcia_proc_status(char *buf, char **start, 
+-		off_t pos, int count, int *eof, void *data);
++#if 0
++#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
++#else
++#define debug(x,args...)
+ #endif
+ 
++#define MAP_SIZE 0x100000
++extern struct au1000_pcmcia_socket au1000_pcmcia_socket[];
++#define PCMCIA_SOCKET(x)	(au1000_pcmcia_socket + (x))
++#define to_au1000_socket(x)	container_of(x, struct au1000_pcmcia_socket, socket)
+ 
+-/* Prototypes for operations which are exported to the
+- * new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core:
++/* Some boards like to support CF cards as IDE root devices, so they
++ * grab pcmcia sockets directly.
+  */
++u32 *pcmcia_base_vaddrs[2];
++extern const unsigned long mips_io_port_base;
+ 
+-static int au1000_pcmcia_init(u32 sock);
+-static int au1000_pcmcia_suspend(u32 sock);
+-static int au1000_pcmcia_register_callback(u32 sock, 
+-		void (*handler)(void *, u32), void *info);
+-static int au1000_pcmcia_inquire_socket(u32 sock, socket_cap_t *cap);
+-static int au1000_pcmcia_get_status(u32 sock, u_int *value);
+-static int au1000_pcmcia_get_socket(u32 sock, socket_state_t *state);
+-static int au1000_pcmcia_set_socket(u32 sock, socket_state_t *state);
+-static int au1000_pcmcia_get_io_map(u32 sock, struct pccard_io_map *io);
+-static int au1000_pcmcia_set_io_map(u32 sock, struct pccard_io_map *io);
+-static int au1000_pcmcia_get_mem_map(u32 sock, struct pccard_mem_map *mem);
+-static int au1000_pcmcia_set_mem_map(u32 sock, struct pccard_mem_map *mem);
+-#ifdef CONFIG_PROC_FS
+-static void au1000_pcmcia_proc_setup(u32 sock, struct proc_dir_entry *base);
+-#endif
++DECLARE_MUTEX(pcmcia_sockets_lock);
+ 
+-static struct pccard_operations au1000_pcmcia_operations = {
+-	au1000_pcmcia_init,
+-	au1000_pcmcia_suspend,
+-	au1000_pcmcia_register_callback,
+-	au1000_pcmcia_inquire_socket,
+-	au1000_pcmcia_get_status,
+-	au1000_pcmcia_get_socket,
+-	au1000_pcmcia_set_socket,
+-	au1000_pcmcia_get_io_map,
+-	au1000_pcmcia_set_io_map,
+-	au1000_pcmcia_get_mem_map,
+-	au1000_pcmcia_set_mem_map,
+-#ifdef CONFIG_PROC_FS
+-	au1000_pcmcia_proc_setup
+-#endif
++static int (*au1x00_pcmcia_hw_init[])(struct device *dev) = {
++	au1x_board_init,
+ };
+ 
+-static spinlock_t pcmcia_lock = SPIN_LOCK_UNLOCKED;
+-
+-static int __init au1000_pcmcia_driver_init(void)
++static int 
++au1x00_pcmcia_skt_state(struct au1000_pcmcia_socket *skt)
+ {
+-	struct pcmcia_init pcmcia_init;
+ 	struct pcmcia_state state;
+-	unsigned int i;
+-
+-	printk("\nAu1x00 PCMCIA\n");
++	unsigned int stat;
+ 
+-#ifndef CONFIG_64BIT_PHYS_ADDR
+-	printk(KERN_ERR "Au1x00 PCMCIA 36 bit IO support not enabled\n");
+-	return -1;
+-#endif
++	memset(&state, 0, sizeof(struct pcmcia_state));
+ 
+-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500)
+-	pcmcia_low_level=&pb1x00_pcmcia_ops;
+-#else
+-#error Unsupported AU1000 board.
+-#endif
++	skt->ops->socket_state(skt, &state);
+ 
+-	pcmcia_init.handler=au1000_pcmcia_interrupt;
+-	if((socket_count=pcmcia_low_level->init(&pcmcia_init))<0) {
+-		printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
+-		return -EIO;
+-	}
++	stat = state.detect  ? SS_DETECT : 0;
++	stat |= state.ready  ? SS_READY  : 0;
++	stat |= state.wrprot ? SS_WRPROT : 0;
++	stat |= state.vs_3v  ? SS_3VCARD : 0;
++	stat |= state.vs_Xv  ? SS_XVCARD : 0;
++	stat |= skt->cs_state.Vcc ? SS_POWERON : 0;
+ 
+-	/* NOTE: the chip select must already be setup */
+-
+-	pcmcia_socket = 
+-		kmalloc(sizeof(struct au1000_pcmcia_socket) * socket_count, 
+-				GFP_KERNEL);
+-	if (!pcmcia_socket) {
+-		printk(KERN_ERR "Card Services can't get memory \n");
+-		return -1;
++	if (skt->cs_state.flags & SS_IOCARD)
++		stat |= state.bvd1 ? SS_STSCHG : 0;
++	else {
++		if (state.bvd1 == 0)
++			stat |= SS_BATDEAD;
++		else if (state.bvd2 == 0)
++			stat |= SS_BATWARN;
+ 	}
+-	memset(pcmcia_socket, 0,
+-			sizeof(struct au1000_pcmcia_socket) * socket_count);
+-			
+-	/* 
+-	 * Assuming max of 2 sockets, which the Au1000 supports.
+-	 * WARNING: the Pb1000 has two sockets, and both work, but you
+-	 * can't use them both at the same time due to glue logic conflicts.
+-	 */
+-	for(i=0; i < socket_count; i++) {
++	return stat;
++}
+ 
+-		if(pcmcia_low_level->socket_state(i, &state)<0){
+-			printk(KERN_ERR "Unable to get PCMCIA status\n");
+-			return -EIO;
+-		}
+-		pcmcia_socket[i].k_state=state;
+-		pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
+-		
+-		if (i == 0) {
+-			pcmcia_socket[i].virt_io = 
+-				(u32)ioremap((ioaddr_t)0xF00000000, 0x1000);
+-			pcmcia_socket[i].phys_attr = (memaddr_t)0xF40000000;
+-			pcmcia_socket[i].phys_mem = (memaddr_t)0xF80000000;
+-		}
+-		else  {
+-			pcmcia_socket[i].virt_io = 
+-				(u32)ioremap((ioaddr_t)0xF08000000, 0x1000);
+-			pcmcia_socket[i].phys_attr = (memaddr_t)0xF48000000;
+-			pcmcia_socket[i].phys_mem = (memaddr_t)0xF88000000;
+-		}
+-	}
++/*
++ * au100_pcmcia_config_skt
++ *
++ * Convert PCMCIA socket state to our socket configure structure.
++ */
++static int
++au1x00_pcmcia_config_skt(struct au1000_pcmcia_socket *skt, socket_state_t *state)
++{
++	int ret;
+ 
+-	/* Only advertise as many sockets as we can detect: */
+-	if(register_ss_entry(socket_count, &au1000_pcmcia_operations)<0){
+-		printk(KERN_ERR "Unable to register socket service routine\n");
+-		return -ENXIO;
++	ret = skt->ops->configure_socket(skt, state);
++	if (ret == 0) {
++		skt->cs_state = *state;
+ 	}
+ 
+-	/* Start the event poll timer.  
+-	 * It will reschedule by itself afterwards. 
+-	 */
+-	au1000_pcmcia_poll_event(0);
+-
+-	debug(1, "au1000: initialization complete\n");
+-	return 0;
++	if (ret < 0)
++		debug("unable to configure socket %d\n", skt->nr);
+ 
+-}  /* au1000_pcmcia_driver_init() */
+-
+-module_init(au1000_pcmcia_driver_init);
+-
+-static void __exit au1000_pcmcia_driver_shutdown(void)
+-{
+-	int i;
+-
+-	del_timer_sync(&poll_timer);
+-	unregister_ss_entry(&au1000_pcmcia_operations);
+-	pcmcia_low_level->shutdown();
+-	flush_scheduled_tasks();
+-	for(i=0; i < socket_count; i++) {
+-		if (pcmcia_socket[i].virt_io) 
+-			iounmap((void *)pcmcia_socket[i].virt_io);
+-	}
+-	debug(1, "au1000: shutdown complete\n");
++	return ret;
+ }
+ 
+-module_exit(au1000_pcmcia_driver_shutdown);
++/* au1x00_pcmcia_sock_init()
++ *
++ * (Re-)Initialise the socket, turning on status interrupts
++ * and PCMCIA bus.  This must wait for power to stabilise
++ * so that the card status signals report correctly.
++ *
++ * Returns: 0
++ */
++static int au1x00_pcmcia_sock_init(struct pcmcia_socket *sock)
++{
++	struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
+ 
+-static int au1000_pcmcia_init(unsigned int sock) { return 0; }
++	debug("initializing socket %u\n", skt->nr);
+ 
+-static int au1000_pcmcia_suspend(unsigned int sock)
+-{
++	skt->ops->socket_init(skt);
+ 	return 0;
+ }
+ 
+-
+-static inline unsigned 
+-au1000_pcmcia_events(struct pcmcia_state *state, 
+-		struct pcmcia_state *prev_state, 
+-		unsigned int mask, unsigned int flags)
++/*
++ * au1x00_pcmcia_suspend()
++ *
++ * Remove power on the socket, disable IRQs from the card.
++ * Turn off status interrupts, and disable the PCMCIA bus.
++ *
++ * Returns: 0
++ */
++static int au1x00_pcmcia_suspend(struct pcmcia_socket *sock)
+ {
+-	unsigned int events=0;
++	struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
++	int ret;
+ 
+-	if(state->detect!=prev_state->detect){
+-		debug(2, "%s(): card detect value %u\n", 
+-				__FUNCTION__, state->detect);
+-		events |= mask&SS_DETECT;
+-	}
++	debug("suspending socket %u\n", skt->nr);
+ 
++	ret = au1x00_pcmcia_config_skt(skt, &dead_socket);
++	if (ret == 0)
++		skt->ops->socket_suspend(skt);
+ 
+-	if(state->ready!=prev_state->ready){
+-		debug(2, "%s(): card ready value %u\n", 
+-				__FUNCTION__, state->ready);
+-		events |= mask&((flags&SS_IOCARD)?0:SS_READY);
+-	}
+-
+-	*prev_state=*state;
+-	return events;
+-
+-}  /* au1000_pcmcia_events() */
+-
++	return ret;
++}
+ 
+-/* 
+- * Au1000_pcmcia_task_handler()
+- * Processes socket events.
++static spinlock_t status_lock = SPIN_LOCK_UNLOCKED;
++/*
++ * au1x00_check_status()
+  */
+-static void au1000_pcmcia_task_handler(void *data) 
++static void au1x00_check_status(struct au1000_pcmcia_socket *skt)
+ {
+-	struct pcmcia_state state;
+-	int i, events, irq_status;
+-
+-	for(i=0; i<socket_count; i++)  {
+-		if((irq_status = pcmcia_low_level->socket_state(i, &state))<0)
+-			printk(KERN_ERR "low-level PCMCIA error\n");
+-
+-		events = au1000_pcmcia_events(&state, 
+-				&pcmcia_socket[i].k_state, 
+-				pcmcia_socket[i].cs_state.csc_mask, 
+-				pcmcia_socket[i].cs_state.flags);
+-		if(pcmcia_socket[i].handler!=NULL) {
+-			pcmcia_socket[i].handler(pcmcia_socket[i].handler_info,
+-					events);
+-		}
+-	}
+-
+-}  /* au1000_pcmcia_task_handler() */
+-
+-static struct tq_struct au1000_pcmcia_task = {
+-	routine: au1000_pcmcia_task_handler
+-};
++	unsigned int events;
+ 
++	debug("entering PCMCIA monitoring thread\n");
+ 
+-static void au1000_pcmcia_poll_event(unsigned long dummy)
+-{
+-	poll_timer.function = au1000_pcmcia_poll_event;
+-	poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD;
+-	add_timer(&poll_timer);
+-	schedule_task(&au1000_pcmcia_task);
++	do {
++		unsigned int status;
++		unsigned long flags;
++
++		status = au1x00_pcmcia_skt_state(skt);
++
++		spin_lock_irqsave(&status_lock, flags);
++		events = (status ^ skt->status) & skt->cs_state.csc_mask;
++		skt->status = status;
++		spin_unlock_irqrestore(&status_lock, flags);
++
++		debug("events: %s%s%s%s%s%s\n",
++			events == 0         ? "<NONE>"   : "",
++			events & SS_DETECT  ? "DETECT "  : "",
++			events & SS_READY   ? "READY "   : "",
++			events & SS_BATDEAD ? "BATDEAD " : "",
++			events & SS_BATWARN ? "BATWARN " : "",
++			events & SS_STSCHG  ? "STSCHG "  : "");
++
++		if (events)
++			pcmcia_parse_events(&skt->socket, events);
++	} while (events);
+ }
+ 
+-
+ /* 
+- * au1000_pcmcia_interrupt()
+- * The actual interrupt work is performed by au1000_pcmcia_task(), 
+- * because the Card Services event handling code performs scheduling 
+- * operations which cannot be executed from within an interrupt context.
++ * au1x00_pcmcia_poll_event()
++ * Let's poll for events in addition to IRQs since IRQ only is unreliable...
+  */
+-static void 
+-au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
++static void au1x00_pcmcia_poll_event(unsigned long dummy)
+ {
+-	schedule_task(&au1000_pcmcia_task);
+-}
++	struct au1000_pcmcia_socket *skt = (struct au1000_pcmcia_socket *)dummy;
++	debug("polling for events\n");
+ 
++	mod_timer(&skt->poll_timer, jiffies + AU1000_PCMCIA_POLL_PERIOD);
+ 
+-static int 
+-au1000_pcmcia_register_callback(unsigned int sock, 
+-		void (*handler)(void *, unsigned int), void *info)
+-{
+-	if(handler==NULL){
+-		pcmcia_socket[sock].handler=NULL;
+-		MOD_DEC_USE_COUNT;
+-	} else {
+-		MOD_INC_USE_COUNT;
+-		pcmcia_socket[sock].handler=handler;
+-		pcmcia_socket[sock].handler_info=info;
+-	}
+-	return 0;
++	au1x00_check_status(skt);
+ }
+ 
+-
+-/* au1000_pcmcia_inquire_socket()
+- *
+- * From the sa1100 socket driver : 
++/* au1x00_pcmcia_get_status()
+  *
+- * Implements the inquire_socket() operation for the in-kernel PCMCIA
+- * service (formerly SS_InquireSocket in Card Services).  We set 
+- * SS_CAP_STATIC_MAP, which disables the memory resource database check. 
+- * (Mapped memory is set up within the socket driver itself.)
++ * From the sa11xx_core.c:
++ * Implements the get_status() operation for the in-kernel PCMCIA
++ * service (formerly SS_GetStatus in Card Services). Essentially just
++ * fills in bits in `status' according to internal driver state or
++ * the value of the voltage detect chipselect register.
++ *
++ * As a debugging note, during card startup, the PCMCIA core issues
++ * three set_socket() commands in a row the first with RESET deasserted,
++ * the second with RESET asserted, and the last with RESET deasserted
++ * again. Following the third set_socket(), a get_status() command will
++ * be issued. The kernel is looking for the SS_READY flag (see
++ * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
+  *
+- * In conjunction with the STATIC_MAP capability is a new field,
+- * `io_offset', recommended by David Hinds. Rather than go through
+- * the SetIOMap interface (which is not quite suited for communicating
+- * window locations up from the socket driver), we just pass up 
+- * an offset which is applied to client-requested base I/O addresses
+- * in alloc_io_space().
+- *
+- * Returns: 0 on success, -1 if no pin has been configured for `sock'
++ * Returns: 0
+  */
+-static int au1000_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
++static int
++au1x00_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
+ {
+-	struct pcmcia_irq_info irq_info;
++	struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
+ 
+-	if(sock > socket_count){
+-		printk(KERN_ERR "au1000: socket %u not configured\n", sock);
+-		return -1;
+-	}
+-
+-	/* from the sa1100_generic driver: */
+-
+-	/* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
+-	*   force_low argument to validate_mem() in rsrc_mgr.c -- since in
+-	*   general, the mapped * addresses of the PCMCIA memory regions
+-	*   will not be within 0xffff, setting force_low would be
+-	*   undesirable.
+-	*
+-	* SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
+-	*   resource database; we instead pass up physical address ranges
+-	*   and allow other parts of Card Services to deal with remapping.
+-	*
+-	* SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
+-	*   not 32-bit CardBus devices.
+-	*/
+-	cap->features=(SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
+-
+-	irq_info.sock=sock;
+-	irq_info.irq=-1;
+-
+-	if(pcmcia_low_level->get_irq_info(&irq_info)<0){
+-		printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock);
+-		return -1;
+-	}
+-
+-	cap->irq_mask=0;
+-	cap->map_size=MAP_SIZE;
+-	cap->pci_irq=irq_info.irq;
+-	cap->io_offset=pcmcia_socket[sock].virt_io;
++	skt->status = au1x00_pcmcia_skt_state(skt);
++	*status = skt->status;
+ 
+ 	return 0;
++}
+ 
+-}  /* au1000_pcmcia_inquire_socket() */
+-
+-
+-static int 
+-au1000_pcmcia_get_status(unsigned int sock, unsigned int *status)
++/* au1x00_pcmcia_get_socket()
++ * Implements the get_socket() operation for the in-kernel PCMCIA
++ * service (formerly SS_GetSocket in Card Services). Not a very 
++ * exciting routine.
++ *
++ * Returns: 0
++ */
++static int
++au1x00_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
+ {
+-	struct pcmcia_state state;
+-
+-
+-	if((pcmcia_low_level->socket_state(sock, &state))<0){
+-		printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
+-		return -1;
+-	}
++  struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
+ 
+-	pcmcia_socket[sock].k_state = state;
+-
+-	*status = state.detect?SS_DETECT:0;
+-
+-	*status |= state.ready?SS_READY:0;
+-
+-	*status |= pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;
+-
+-	if(pcmcia_socket[sock].cs_state.flags&SS_IOCARD)
+-		*status |= state.bvd1?SS_STSCHG:0;
+-	else {
+-		if(state.bvd1==0)
+-			*status |= SS_BATDEAD;
+-		else if(state.bvd2 == 0)
+-			*status |= SS_BATWARN;
+-	}
+-
+-	*status|=state.vs_3v?SS_3VCARD:0;
+-
+-	*status|=state.vs_Xv?SS_XVCARD:0;
+-
+-	debug(2, "\tstatus: %s%s%s%s%s%s%s%s\n",
+-	(*status&SS_DETECT)?"DETECT ":"",
+-	(*status&SS_READY)?"READY ":"", 
+-	(*status&SS_BATDEAD)?"BATDEAD ":"",
+-	(*status&SS_BATWARN)?"BATWARN ":"",
+-	(*status&SS_POWERON)?"POWERON ":"",
+-	(*status&SS_STSCHG)?"STSCHG ":"",
+-	(*status&SS_3VCARD)?"3VCARD ":"",
+-	(*status&SS_XVCARD)?"XVCARD ":"");
+-
+-	return 0;
+-
+-}  /* au1000_pcmcia_get_status() */
+-
+-
+-static int 
+-au1000_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
+-{
+-	*state = pcmcia_socket[sock].cs_state;
+-	return 0;
++  debug("for sock %u\n", skt->nr);
++  *state = skt->cs_state;
++  return 0;
+ }
+ 
+-
+-static int 
+-au1000_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
++/* au1x00_pcmcia_set_socket()
++ * Implements the set_socket() operation for the in-kernel PCMCIA
++ * service (formerly SS_SetSocket in Card Services). We more or
++ * less punt all of this work and let the kernel handle the details
++ * of power configuration, reset, &c. We also record the value of
++ * `state' in order to regurgitate it to the PCMCIA core later.
++ *
++ * Returns: 0
++ */
++static int
++au1x00_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
+ {
+-	struct pcmcia_configure configure;
++  struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
+ 
+-	debug(2, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
+-	"\tVcc %d  Vpp %d  irq %d\n",
++  debug("for sock %u\n", skt->nr);
++
++  debug("\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n",
+ 	(state->csc_mask==0)?"<NONE>":"",
+ 	(state->csc_mask&SS_DETECT)?"DETECT ":"",
+ 	(state->csc_mask&SS_READY)?"READY ":"",
+@@ -480,217 +288,294 @@ au1000_pcmcia_set_socket(unsigned int so
+ 	(state->flags&SS_IOCARD)?"IOCARD ":"",
+ 	(state->flags&SS_RESET)?"RESET ":"",
+ 	(state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
+-	(state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
++	(state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"");
++  debug("\tVcc %d  Vpp %d  irq %d\n",
+ 	state->Vcc, state->Vpp, state->io_irq);
+ 
+-	configure.sock=sock;
+-	configure.vcc=state->Vcc;
+-	configure.vpp=state->Vpp;
+-	configure.output=(state->flags&SS_OUTPUT_ENA)?1:0;
+-	configure.speaker=(state->flags&SS_SPKR_ENA)?1:0;
+-	configure.reset=(state->flags&SS_RESET)?1:0;
+-
+-	if(pcmcia_low_level->configure_socket(&configure)<0){
+-		printk(KERN_ERR "Unable to configure socket %u\n", sock);
+-		return -1;
+-	}
+-
+-	pcmcia_socket[sock].cs_state = *state;
+-	return 0;
+-
+-}  /* au1000_pcmcia_set_socket() */
+-
+-
+-static int 
+-au1000_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
+-{
+-	debug(1, "au1000_pcmcia_get_io_map: sock %d\n", sock);
+-	if(map->map>=MAX_IO_WIN){
+-		printk(KERN_ERR "%s(): map (%d) out of range\n", 
+-				__FUNCTION__, map->map);
+-		return -1;
+-	}
+-	*map=pcmcia_socket[sock].io_map[map->map];
+-	return 0;
++  return au1x00_pcmcia_config_skt(skt, state);
+ }
+ 
+-
+ int 
+-au1000_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
++au1x00_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
+ {
++	struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
+ 	unsigned int speed;
+-	unsigned long start;
+ 
+ 	if(map->map>=MAX_IO_WIN){
+-		printk(KERN_ERR "%s(): map (%d) out of range\n", 
+-				__FUNCTION__, map->map);
++		debug("map (%d) out of range\n", map->map);
+ 		return -1;
+ 	}
+ 
+ 	if(map->flags&MAP_ACTIVE){
+ 		speed=(map->speed>0)?map->speed:AU1000_PCMCIA_IO_SPEED;
+-		pcmcia_socket[sock].speed_io=speed;
++		skt->spd_io[map->map] = speed;
+ 	}
+ 
+-	start=map->start;
+-
+-	if(map->stop==1) {
+-		map->stop=PAGE_SIZE-1;
+-	}
+-
+-	map->start=pcmcia_socket[sock].virt_io;
+-	map->stop=map->start+(map->stop-start);
+-	pcmcia_socket[sock].io_map[map->map]=*map;
+-	debug(3, "set_io_map %d start %x stop %x\n", 
+-			map->map, map->start, map->stop);
++	map->start=(ioaddr_t)(u32)skt->virt_io;
++	map->stop=map->start+MAP_SIZE;
+ 	return 0;
+ 
+-}  /* au1000_pcmcia_set_io_map() */
++}  /* au1x00_pcmcia_set_io_map() */
+ 
+ 
+ static int 
+-au1000_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
++au1x00_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map)
+ {
++	struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
++	unsigned short speed = map->speed;
+ 
+-	if(map->map>=MAX_WIN) {
+-		printk(KERN_ERR "%s(): map (%d) out of range\n", 
+-				__FUNCTION__, map->map);
++	if(map->map>=MAX_WIN){
++		debug("map (%d) out of range\n", map->map);
+ 		return -1;
+ 	}
+-	*map=pcmcia_socket[sock].mem_map[map->map];
++
++	if (map->flags & MAP_ATTRIB) {
++		skt->spd_attr[map->map] = speed;
++		skt->spd_mem[map->map] = 0;
++	} else {
++		skt->spd_attr[map->map] = 0;
++		skt->spd_mem[map->map] = speed;
++	}
++
++	if (map->flags & MAP_ATTRIB) {
++		map->static_start = skt->phys_attr + map->card_start;
++	}
++	else {
++		map->static_start = skt->phys_mem + map->card_start;
++	}
++
++	debug("set_mem_map %d start %08lx card_start %08x\n", 
++			map->map, map->static_start, map->card_start);
+ 	return 0;
+-}
+ 
++}  /* au1x00_pcmcia_set_mem_map() */
+ 
+-static int 
+-au1000_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
++static struct pccard_operations au1x00_pcmcia_operations = {
++	.init			= au1x00_pcmcia_sock_init,
++	.suspend		= au1x00_pcmcia_suspend,
++	.get_status		= au1x00_pcmcia_get_status,
++	.get_socket		= au1x00_pcmcia_get_socket,
++	.set_socket		= au1x00_pcmcia_set_socket,
++	.set_io_map		= au1x00_pcmcia_set_io_map,
++	.set_mem_map		= au1x00_pcmcia_set_mem_map,
++};
++
++static const char *skt_names[] = {
++	"PCMCIA socket 0",
++	"PCMCIA socket 1",
++};
++
++struct skt_dev_info {
++	int nskt;
++};
++
++int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
+ {
+-	unsigned int speed;
+-	u_long flags;
++	struct skt_dev_info *sinfo;
++	int ret, i;
+ 
+-	if(map->map>=MAX_WIN){
+-		printk(KERN_ERR "%s(): map (%d) out of range\n", 
+-				__FUNCTION__, map->map);
+-		return -1;
++	sinfo = kmalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
++	if (!sinfo) {
++		ret = -ENOMEM;
++		goto out;
+ 	}
+ 
+-	if(map->flags&MAP_ACTIVE){
+-		speed=(map->speed>0)?map->speed:AU1000_PCMCIA_MEM_SPEED;
++	memset(sinfo, 0, sizeof(struct skt_dev_info));
++	sinfo->nskt = nr;
+ 
+-		/* TBD */
+-		if(map->flags&MAP_ATTRIB){
+-			pcmcia_socket[sock].speed_attr=speed;
+-		} 
+-		else {
+-			pcmcia_socket[sock].speed_mem=speed;
++	/*
++	 * Initialise the per-socket structure.
++	 */
++	for (i = 0; i < nr; i++) {
++		struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
++		memset(skt, 0, sizeof(*skt));
++
++		skt->socket.ops = &au1x00_pcmcia_operations;
++		skt->socket.owner = ops->owner;
++		skt->socket.dev.dev = dev;
++
++		init_timer(&skt->poll_timer);
++		skt->poll_timer.function = au1x00_pcmcia_poll_event;
++		skt->poll_timer.data = (unsigned long)skt;
++		skt->poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD;
++
++		skt->nr		= first + i;
++		skt->irq	= 255;
++		skt->dev	= dev;
++		skt->ops	= ops;
++
++		skt->res_skt.name	= skt_names[skt->nr];
++		skt->res_io.name	= "io";
++		skt->res_io.flags	= IORESOURCE_MEM | IORESOURCE_BUSY;
++		skt->res_mem.name	= "memory";
++		skt->res_mem.flags	= IORESOURCE_MEM;
++		skt->res_attr.name	= "attribute";
++		skt->res_attr.flags	= IORESOURCE_MEM;
++		
++		/*
++		 * PCMCIA client drivers use the inb/outb macros to access the
++		 * IO registers. Since mips_io_port_base is added to the 
++		 * access address of the mips implementation of inb/outb, 
++		 * we need to subtract it here because we want to access the
++		 * I/O or MEM address directly, without going through this
++		 * "mips_io_port_base" mechanism.
++		 */
++		if (i == 0) {
++			skt->virt_io = (void *)
++				(ioremap((phys_t)AU1X_SOCK0_IO, 0x1000) -
++				(u32)mips_io_port_base);
++			skt->phys_attr = AU1X_SOCK0_PSEUDO_PHYS_ATTR;
++			skt->phys_mem = AU1X_SOCK0_PSEUDO_PHYS_MEM;
+ 		}
+-	}
++#ifndef CONFIG_MIPS_XXS1500
++		else  {
++			skt->virt_io = (void *)
++				(ioremap((phys_t)AU1X_SOCK1_IO, 0x1000) -
++				(u32)mips_io_port_base);
++			skt->phys_attr = AU1X_SOCK1_PSEUDO_PHYS_ATTR;
++			skt->phys_mem = AU1X_SOCK1_PSEUDO_PHYS_MEM;
++		}
++#endif
++		pcmcia_base_vaddrs[i] = (u32 *)skt->virt_io;
++		ret = ops->hw_init(skt);
+ 
+-	spin_lock_irqsave(&pcmcia_lock, flags);
+-	if (map->flags & MAP_ATTRIB) {
+-		map->static_start = pcmcia_socket[sock].phys_attr + 
+-			map->card_start;
+-	}
+-	else {
+-		map->static_start = pcmcia_socket[sock].phys_mem + 
+-			map->card_start;
++		skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
++		skt->socket.irq_mask = 0;
++		skt->socket.map_size = MAP_SIZE;
++		skt->socket.pci_irq = skt->irq;
++		skt->socket.io_offset = (unsigned long)skt->virt_io;
++
++		skt->status = au1x00_pcmcia_skt_state(skt);
++
++		ret = pcmcia_register_socket(&skt->socket);
++		if (ret)
++			goto out_err;
++
++		WARN_ON(skt->socket.sock != i);
++
++		add_timer(&skt->poll_timer);
+ 	}
+ 
+-	pcmcia_socket[sock].mem_map[map->map]=*map;
+-	spin_unlock_irqrestore(&pcmcia_lock, flags);
+-	debug(3, "set_mem_map %d start %x card_start %x\n", 
+-			map->map, map->static_start,
+-			map->card_start);
++	dev_set_drvdata(dev, sinfo);
+ 	return 0;
+ 
+-}  /* au1000_pcmcia_set_mem_map() */
++	do {
++		struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
++		
++		del_timer_sync(&skt->poll_timer);
++		pcmcia_unregister_socket(&skt->socket);
++out_err:
++		flush_scheduled_work();
++		ops->hw_shutdown(skt);
++
++		i--;
++	} while (i > 0);
++	kfree(sinfo);
++out:
++	return ret;
++}
+ 
++int au1x00_drv_pcmcia_remove(struct device *dev)
++{
++	struct skt_dev_info *sinfo = dev_get_drvdata(dev);
++	int i;
+ 
+-#if defined(CONFIG_PROC_FS)
++	down(&pcmcia_sockets_lock);
++	dev_set_drvdata(dev, NULL);
+ 
+-static void 
+-au1000_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
++	for (i = 0; i < sinfo->nskt; i++) {
++		struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
++
++		del_timer_sync(&skt->poll_timer);
++		pcmcia_unregister_socket(&skt->socket);
++		flush_scheduled_work();
++		skt->ops->hw_shutdown(skt);
++		au1x00_pcmcia_config_skt(skt, &dead_socket);
++		iounmap(skt->virt_io);
++		skt->virt_io = NULL;
++	}
++
++	kfree(sinfo);
++	up(&pcmcia_sockets_lock);
++	return 0;
++}
++
++
++/*
++ * PCMCIA "Driver" API
++ */
++
++static int au1x00_drv_pcmcia_probe(struct device *dev)
+ {
+-	struct proc_dir_entry *entry;
++	int i, ret = -ENODEV;
+ 
+-	if((entry=create_proc_entry("status", 0, base))==NULL){
+-		printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
+-		return;
++	down(&pcmcia_sockets_lock);
++	for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) {
++		ret = au1x00_pcmcia_hw_init[i](dev);
++		if (ret == 0)
++			break;
+ 	}
++	up(&pcmcia_sockets_lock);
++	return ret;
++}
+ 
+-	entry->read_proc=au1000_pcmcia_proc_status;
+-	entry->data=(void *)sock;
++
++static int au1x00_drv_pcmcia_suspend(struct device *dev, u32 state, u32 level)
++{
++	int ret = 0;
++	if (level == SUSPEND_SAVE_STATE)
++		ret = pcmcia_socket_dev_suspend(dev, state);
++	return ret;
+ }
+ 
++static int au1x00_drv_pcmcia_resume(struct device *dev, u32 level)
++{
++	int ret = 0;
++	if (level == RESUME_RESTORE_STATE)
++		ret = pcmcia_socket_dev_resume(dev);
++	return ret;
++}
++
++
++static struct device_driver au1x00_pcmcia_driver = {
++	.probe		= au1x00_drv_pcmcia_probe,
++	.remove		= au1x00_drv_pcmcia_remove,
++	.name		= "au1x00-pcmcia",
++	.bus		= &platform_bus_type,
++	.suspend	= au1x00_drv_pcmcia_suspend,
++	.resume		= au1x00_drv_pcmcia_resume
++};
++
++static struct platform_device au1x00_device = {
++	.name = "au1x00-pcmcia",
++	.id = 0,
++};
+ 
+-/* au1000_pcmcia_proc_status()
+- * Implements the /proc/bus/pccard/??/status file.
++/* au1x00_pcmcia_init()
+  *
+- * Returns: the number of characters added to the buffer
++ * This routine performs low-level PCMCIA initialization and then
++ * registers this socket driver with Card Services.
++ *
++ * Returns: 0 on success, -ve error code on failure
+  */
+-static int 
+-au1000_pcmcia_proc_status(char *buf, char **start, off_t pos, 
+-		int count, int *eof, void *data)
++static int __init au1x00_pcmcia_init(void)
+ {
+-	char *p=buf;
+-	unsigned int sock=(unsigned int)data;
+-
+-	p+=sprintf(p, "k_flags  : %s%s%s%s%s%s%s\n", 
+-	     pcmcia_socket[sock].k_state.detect?"detect ":"",
+-	     pcmcia_socket[sock].k_state.ready?"ready ":"",
+-	     pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"",
+-	     pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"",
+-	     pcmcia_socket[sock].k_state.wrprot?"wrprot ":"",
+-	     pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"",
+-	     pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":"");
+-
+-	p+=sprintf(p, "status   : %s%s%s%s%s%s%s%s%s\n",
+-	     pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"",
+-	     pcmcia_socket[sock].k_state.ready?"SS_READY ":"",
+-	     pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"",
+-	     pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
+-	     "SS_IOCARD ":"",
+-	     (pcmcia_socket[sock].cs_state.flags&SS_IOCARD &&
+-	      pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"",
+-	     ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
+-	      (pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"",
+-	     ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
+-	      (pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"",
+-	     pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"",
+-	     pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":"");
+-
+-	p+=sprintf(p, "mask     : %s%s%s%s%s\n",
+-	     pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?\
+-	     "SS_DETECT ":"",
+-	     pcmcia_socket[sock].cs_state.csc_mask&SS_READY?\
+-	     "SS_READY ":"",
+-	     pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?\
+-	     "SS_BATDEAD ":"",
+-	     pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?\
+-	     "SS_BATWARN ":"",
+-	     pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?\
+-	     "SS_STSCHG ":"");
+-
+-	p+=sprintf(p, "cs_flags : %s%s%s%s%s\n",
+-	     pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?\
+-	     "SS_PWR_AUTO ":"",
+-	     pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
+-	     "SS_IOCARD ":"",
+-	     pcmcia_socket[sock].cs_state.flags&SS_RESET?\
+-	     "SS_RESET ":"",
+-	     pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?\
+-	     "SS_SPKR_ENA ":"",
+-	     pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?\
+-	     "SS_OUTPUT_ENA ":"");
+-
+-	p+=sprintf(p, "Vcc      : %d\n", pcmcia_socket[sock].cs_state.Vcc);
+-	p+=sprintf(p, "Vpp      : %d\n", pcmcia_socket[sock].cs_state.Vpp);
+-	p+=sprintf(p, "irq      : %d\n", pcmcia_socket[sock].cs_state.io_irq);
+-	p+=sprintf(p, "I/O      : %u\n", pcmcia_socket[sock].speed_io);
+-	p+=sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr);
+-	p+=sprintf(p, "common   : %u\n", pcmcia_socket[sock].speed_mem);
+-	return p-buf;
++	int error = 0;
++	if ((error = driver_register(&au1x00_pcmcia_driver)))
++		return error;
++	platform_device_register(&au1x00_device);
++	return error;
+ }
+ 
++/* au1x00_pcmcia_exit()
++ * Invokes the low-level kernel service to free IRQs associated with this
++ * socket controller and reset GPIO edge detection.
++ */
++static void __exit au1x00_pcmcia_exit(void)
++{
++	driver_unregister(&au1x00_pcmcia_driver);
++	platform_device_unregister(&au1x00_device);
++}
+ 
+-#endif  /* defined(CONFIG_PROC_FS) */
++module_init(au1x00_pcmcia_init);
++module_exit(au1x00_pcmcia_exit);
+diff -urpNX dontdiff linux-2.6.10/drivers/pcmcia/au1000_generic.h linux-2.6.10-mips/drivers/pcmcia/au1000_generic.h
+--- linux-2.6.10/drivers/pcmcia/au1000_generic.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/pcmcia/au1000_generic.h	2004-10-27 02:14:43.000000000 +0200
+@@ -0,0 +1,150 @@
++/*
++ * Alchemy Semi Au1000 pcmcia driver include file
++ *
++ * Copyright 2001 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc.
++ *         	ppopov at mvista.com or source at mvista.com
++ *
++ *  This program is free software; you can distribute 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 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 __ASM_AU1000_PCMCIA_H
++#define __ASM_AU1000_PCMCIA_H
++
++/* include the world */
++#include <pcmcia/version.h>
++#include <pcmcia/cs_types.h>
++#include <pcmcia/cs.h>
++#include <pcmcia/ss.h>
++#include <pcmcia/bulkmem.h>
++#include <pcmcia/cistpl.h>
++#include "cs_internal.h"
++
++#define AU1000_PCMCIA_POLL_PERIOD    (2*HZ)
++#define AU1000_PCMCIA_IO_SPEED       (255)
++#define AU1000_PCMCIA_MEM_SPEED      (300)
++
++#define AU1X_SOCK0_IO        0xF00000000
++#define AU1X_SOCK0_PHYS_ATTR 0xF40000000
++#define AU1X_SOCK0_PHYS_MEM  0xF80000000
++/* pseudo 32 bit phys addresses, which get fixed up to the
++ * real 36 bit address in fixup_bigphys_addr() */
++#define AU1X_SOCK0_PSEUDO_PHYS_ATTR 0xF4000000
++#define AU1X_SOCK0_PSEUDO_PHYS_MEM  0xF8000000
++
++/* pcmcia socket 1 needs external glue logic so the memory map
++ * differs from board to board.
++ */
++#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1550)
++#define AU1X_SOCK1_IO        0xF08000000
++#define AU1X_SOCK1_PHYS_ATTR 0xF48000000
++#define AU1X_SOCK1_PHYS_MEM  0xF88000000
++#define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4800000
++#define AU1X_SOCK1_PSEUDO_PHYS_MEM  0xF8800000
++#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
++#define AU1X_SOCK1_IO        0xF04000000
++#define AU1X_SOCK1_PHYS_ATTR 0xF44000000
++#define AU1X_SOCK1_PHYS_MEM  0xF84000000
++#define AU1X_SOCK1_PSEUDO_PHYS_ATTR 0xF4400000
++#define AU1X_SOCK1_PSEUDO_PHYS_MEM  0xF8400000
++#endif
++
++struct pcmcia_state {
++  unsigned detect: 1,
++            ready: 1,
++           wrprot: 1,
++	     bvd1: 1,
++	     bvd2: 1,
++            vs_3v: 1,
++            vs_Xv: 1;
++};
++
++struct pcmcia_configure {
++  unsigned sock: 8,
++            vcc: 8,
++            vpp: 8,
++         output: 1,
++        speaker: 1,
++          reset: 1;
++};
++
++struct pcmcia_irqs {
++	int sock;
++	int irq;
++	const char *str;
++};
++
++
++struct au1000_pcmcia_socket {
++	struct pcmcia_socket socket;
++
++	/* 
++	 * Info from low level handler
++	 */
++	struct device		*dev;
++	unsigned int		nr;
++	unsigned int		irq;
++
++	/*
++	 * Core PCMCIA state
++	 */
++	struct pcmcia_low_level *ops;
++
++	unsigned int 		status;
++	socket_state_t		cs_state;
++
++	unsigned short		spd_io[MAX_IO_WIN];
++	unsigned short		spd_mem[MAX_WIN];
++	unsigned short		spd_attr[MAX_WIN];
++
++	struct resource		res_skt;
++	struct resource		res_io;
++	struct resource		res_mem;
++	struct resource		res_attr;
++
++	void *                 	virt_io;
++	ioaddr_t              	phys_io;
++	unsigned int           	phys_attr;
++	unsigned int           	phys_mem;
++	unsigned short        	speed_io, speed_attr, speed_mem;
++
++	unsigned int		irq_state;
++
++	struct timer_list	poll_timer;
++};
++
++struct pcmcia_low_level {
++	struct module *owner;
++
++	int (*hw_init)(struct au1000_pcmcia_socket *);
++	void (*hw_shutdown)(struct au1000_pcmcia_socket *);
++
++	void (*socket_state)(struct au1000_pcmcia_socket *, struct pcmcia_state *);
++	int (*configure_socket)(struct au1000_pcmcia_socket *, struct socket_state_t *);
++
++	/*
++	 * Enable card status IRQs on (re-)initialisation.  This can
++	 * be called at initialisation, power management event, or
++	 * pcmcia event.
++	 */
++	void (*socket_init)(struct au1000_pcmcia_socket *);
++
++	/*
++	 * Disable card status IRQs and PCMCIA bus on suspend.
++	 */
++	void (*socket_suspend)(struct au1000_pcmcia_socket *);
++};
++
++extern int au1x_board_init(struct device *dev);
++
++#endif /* __ASM_AU1000_PCMCIA_H */
+diff -urpNX dontdiff linux-2.6.10/drivers/pcmcia/au1000_pb1x00.c linux-2.6.10-mips/drivers/pcmcia/au1000_pb1x00.c
+--- linux-2.6.10/drivers/pcmcia/au1000_pb1x00.c	2004-12-24 22:34:29.000000000 +0100
++++ linux-2.6.10-mips/drivers/pcmcia/au1000_pb1x00.c	2004-09-21 13:10:50.000000000 +0200
+@@ -30,6 +30,7 @@
+ #include <linux/timer.h>
+ #include <linux/mm.h>
+ #include <linux/proc_fs.h>
++#include <linux/version.h>
+ #include <linux/types.h>
+ 
+ #include <pcmcia/version.h>
+@@ -55,7 +56,7 @@
+ #define PCMCIA_IRQ AU1000_GPIO_15
+ #elif defined (CONFIG_MIPS_PB1500)
+ #include <asm/pb1500.h>
+-#define PCMCIA_IRQ AU1000_GPIO_11   /* fixme */
++#define PCMCIA_IRQ AU1500_GPIO_203
+ #elif defined (CONFIG_MIPS_PB1100)
+ #include <asm/pb1100.h>
+ #define PCMCIA_IRQ AU1000_GPIO_11
+@@ -82,9 +83,9 @@ static int pb1x00_pcmcia_init(struct pcm
+ #else /* fixme -- take care of the Pb1500 at some point */
+ 
+ 	u16 pcr;
+-	pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; /* turn off power */
+-	pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN);
+-	au_writew(pcr, PB1100_MEM_PCMCIA);
++	pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */
++	pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
++	au_writew(pcr, PCMCIA_BOARD_REG);
+ 	au_sync_delay(500);
+ 	return PCMCIA_NUM_SOCKS;
+ #endif
+@@ -102,9 +103,9 @@ static int pb1x00_pcmcia_shutdown(void)
+ 	return 0;
+ #else
+ 	u16 pcr;
+-	pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf; /* turn off power */
+-	pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN);
+-	au_writew(pcr, PB1100_MEM_PCMCIA);
++	pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf; /* turn off power */
++	pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
++	au_writew(pcr, PCMCIA_BOARD_REG);
+ 	au_sync_delay(2);
+ 	return 0;
+ #endif
+@@ -123,9 +124,14 @@ pb1x00_pcmcia_socket_state(unsigned sock
+ 	vs0 = (vs0 >> 4) & 0x3;
+ 	vs1 = (vs1 >> 12) & 0x3;
+ #else
+-	vs0 = (au_readw(PB1100_BOARD_STATUS) >> 4) & 0x3;
++	vs0 = (au_readw(BOARD_STATUS_REG) >> 4) & 0x3;
++#ifdef CONFIG_MIPS_PB1500
++	inserted0 = !((au_readl(GPIO2_PINSTATE) >> 1) & 0x1); /* gpio 201 */
++#else /* Pb1100 */
+ 	inserted0 = !((au_readl(SYS_PINSTATERD) >> 9) & 0x1); /* gpio 9 */
+ #endif
++	inserted1 = 0;
++#endif
+ 
+ 	state->ready = 0;
+ 	state->vs_Xv = 0;
+@@ -145,7 +151,7 @@ pb1x00_pcmcia_socket_state(unsigned sock
+ 					/* return without setting 'detect' */
+ 					printk(KERN_ERR "pb1x00 bad VS (%d)\n",
+ 							vs0);
+-					return;
++					return 0;
+ 			}
+ 			state->detect = 1;
+ 		}
+@@ -163,7 +169,7 @@ pb1x00_pcmcia_socket_state(unsigned sock
+ 					/* return without setting 'detect' */
+ 					printk(KERN_ERR "pb1x00 bad VS (%d)\n",
+ 							vs1);
+-					return;
++					return 0;
+ 			}
+ 			state->detect = 1;
+ 		}
+@@ -324,7 +330,7 @@ pb1x00_pcmcia_configure_socket(const str
+ 
+ #else
+ 
+-	pcr = au_readw(PB1100_MEM_PCMCIA) & ~0xf;
++	pcr = au_readw(PCMCIA_BOARD_REG) & ~0xf;
+ 
+ 	debug("Vcc %dV Vpp %dV, pcr %x, reset %d\n", 
+ 			configure->vcc, configure->vpp, pcr, configure->reset);
+@@ -383,26 +389,27 @@ pb1x00_pcmcia_configure_socket(const str
+ 			break;
+ 	}
+ 
+-	au_writew(pcr, PB1100_MEM_PCMCIA);
++	au_writew(pcr, PCMCIA_BOARD_REG);
+ 	au_sync_delay(300);
+ 
+ 	if (!configure->reset) {
+-		pcr |= PB1100_PC_DRV_EN;
+-		au_writew(pcr, PB1100_MEM_PCMCIA);
++		pcr |= PC_DRV_EN;
++		au_writew(pcr, PCMCIA_BOARD_REG);
+ 		au_sync_delay(100);
+-		pcr |= PB1100_PC_DEASSERT_RST;
+-		au_writew(pcr, PB1100_MEM_PCMCIA);
++		pcr |= PC_DEASSERT_RST;
++		au_writew(pcr, PCMCIA_BOARD_REG);
+ 		au_sync_delay(100);
+ 	}
+ 	else {
+-		pcr &= ~(PB1100_PC_DEASSERT_RST | PB1100_PC_DRV_EN);
+-		au_writew(pcr, PB1100_MEM_PCMCIA);
++		pcr &= ~(PC_DEASSERT_RST | PC_DRV_EN);
++		au_writew(pcr, PCMCIA_BOARD_REG);
+ 		au_sync_delay(100);
+ 	}
+ #endif
+ 	return 0;
+ }
+ 
++
+ struct pcmcia_low_level pb1x00_pcmcia_ops = { 
+ 	pb1x00_pcmcia_init,
+ 	pb1x00_pcmcia_shutdown,
+diff -urpNX dontdiff linux-2.6.10/drivers/pcmcia/au1000_xxs1500.c linux-2.6.10-mips/drivers/pcmcia/au1000_xxs1500.c
+--- linux-2.6.10/drivers/pcmcia/au1000_xxs1500.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/pcmcia/au1000_xxs1500.c	2004-10-27 02:14:43.000000000 +0200
+@@ -0,0 +1,191 @@
++/*
++ *
++ * MyCable board specific pcmcia routines.
++ *
++ * Copyright 2003 MontaVista Software Inc.
++ * Author: Pete Popov, MontaVista Software, Inc.
++ *         	ppopov at mvista.com or source at mvista.com
++ *
++ * ########################################################################
++ *
++ *  This program is free software; you can distribute 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 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 <linux/module.h>
++#include <linux/init.h>
++#include <linux/config.h>
++#include <linux/delay.h>
++#include <linux/ioport.h>
++#include <linux/kernel.h>
++#include <linux/tqueue.h>
++#include <linux/timer.h>
++#include <linux/mm.h>
++#include <linux/proc_fs.h>
++#include <linux/version.h>
++#include <linux/types.h>
++
++#include <pcmcia/version.h>
++#include <pcmcia/cs_types.h>
++#include <pcmcia/cs.h>
++#include <pcmcia/ss.h>
++#include <pcmcia/bulkmem.h>
++#include <pcmcia/cistpl.h>
++#include <pcmcia/bus_ops.h>
++#include "cs_internal.h"
++
++#include <asm/io.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++
++#include <asm/au1000.h>
++#include <asm/au1000_pcmcia.h>
++#include <asm/xxs1500.h>
++
++#if 0
++#define DEBUG(x,args...)	printk(__FUNCTION__ ": " x,##args)
++#else
++#define DEBUG(x,args...)
++#endif
++
++static int xxs1500_pcmcia_init(struct pcmcia_init *init)
++{
++	return PCMCIA_NUM_SOCKS;
++}
++
++static int xxs1500_pcmcia_shutdown(void)
++{
++	/* turn off power */
++	au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30),
++			GPIO2_OUTPUT);
++	au_sync_delay(100);
++
++	/* assert reset */
++	au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20), 
++			GPIO2_OUTPUT);
++	au_sync_delay(100);
++	return 0;
++}
++
++
++static int 
++xxs1500_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
++{
++	u32 inserted; u32 vs;
++	unsigned long gpio, gpio2;
++
++	if(sock > PCMCIA_MAX_SOCK) return -1;
++
++	gpio = au_readl(SYS_PINSTATERD);
++	gpio2 = au_readl(GPIO2_PINSTATE);
++
++	vs = gpio2 & ((1<<8) | (1<<9));
++	inserted = (!(gpio & 0x1) && !(gpio & 0x2));
++
++	state->ready = 0;
++	state->vs_Xv = 0;
++	state->vs_3v = 0;
++	state->detect = 0;
++
++	if (inserted) {
++		switch (vs) {
++			case 0:
++			case 1:
++			case 2:
++				state->vs_3v=1;
++				break;
++			case 3: /* 5V */
++			default:
++				/* return without setting 'detect' */
++				printk(KERN_ERR "au1x00_cs: unsupported VS\n",
++						vs);
++				return;
++		}
++		state->detect = 1;
++	}
++
++	if (state->detect) {
++		state->ready = 1;
++	}
++
++	state->bvd1= gpio2 & (1<<10);
++	state->bvd2 = gpio2 & (1<<11);
++	state->wrprot=0; 
++	return 1;
++}
++
++
++static int xxs1500_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
++{
++
++	if(info->sock > PCMCIA_MAX_SOCK) return -1;
++	info->irq = PCMCIA_IRQ;
++	return 0;
++}
++
++
++static int 
++xxs1500_pcmcia_configure_socket(const struct pcmcia_configure *configure)
++{
++
++	if(configure->sock > PCMCIA_MAX_SOCK) return -1;
++
++	DEBUG("Vcc %dV Vpp %dV, reset %d\n", 
++			configure->vcc, configure->vpp, configure->reset);
++
++	switch(configure->vcc){
++		case 33: /* Vcc 3.3V */
++			/* turn on power */
++			DEBUG("turn on power\n");
++			au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30),
++					GPIO2_OUTPUT);
++			au_sync_delay(100);
++			break;
++		case 50: /* Vcc 5V */
++		default: /* what's this ? */
++			printk(KERN_ERR "au1x00_cs: unsupported VCC\n");
++		case 0:  /* Vcc 0 */
++			/* turn off power */
++			au_sync_delay(100);
++			au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30),
++					GPIO2_OUTPUT);
++			break;
++	}
++
++	if (!configure->reset) {
++		DEBUG("deassert reset\n");
++		au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<4))|(1<<20), 
++				GPIO2_OUTPUT);
++		au_sync_delay(100);
++		au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<5))|(1<<21), 
++				GPIO2_OUTPUT);
++	}
++	else {
++		DEBUG("assert reset\n");
++		au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20), 
++				GPIO2_OUTPUT);
++	}
++	au_sync_delay(100);
++	return 0;
++}
++
++struct pcmcia_low_level xxs1500_pcmcia_ops = { 
++	xxs1500_pcmcia_init,
++	xxs1500_pcmcia_shutdown,
++	xxs1500_pcmcia_socket_state,
++	xxs1500_pcmcia_get_irq_info,
++	xxs1500_pcmcia_configure_socket
++};
+diff -urpNX dontdiff linux-2.6.10/drivers/pcmcia/vrc4171_card.c linux-2.6.10-mips/drivers/pcmcia/vrc4171_card.c
+--- linux-2.6.10/drivers/pcmcia/vrc4171_card.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/pcmcia/vrc4171_card.c	2004-02-25 03:09:31.000000000 +0100
+@@ -0,0 +1,744 @@
++/*
++ * vrc4171_card.c, NEC VRC4171 Card Controller driver for Socket Services.
++ *
++ * Copyright (C) 2003  Yoichi Yuasa <yuasa at hh.iij4u.or.jp>
++ *
++ *  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 <linux/init.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/spinlock.h>
++#include <linux/sched.h>
++#include <linux/types.h>
++
++#include <asm/io.h>
++#include <asm/vr41xx/vrc4171.h>
++
++#include <pcmcia/ss.h>
++
++#include "i82365.h"
++
++MODULE_DESCRIPTION("NEC VRC4171 Card Controllers driver for Socket Services");
++MODULE_AUTHOR("Yoichi Yuasa <yuasa at hh.iij4u.or.jp>");
++MODULE_LICENSE("GPL");
++
++#define CARD_MAX_SLOTS		2
++#define CARD_SLOTA		0
++#define CARD_SLOTB		1
++#define CARD_SLOTB_OFFSET	0x40
++
++#define CARD_MEM_START		0x10000000
++#define CARD_MEM_END		0x13ffffff
++#define CARD_MAX_MEM_OFFSET	0x3ffffff
++#define CARD_MAX_MEM_SPEED	1000
++
++#define CARD_CONTROLLER_INDEX	0x03e0
++#define CARD_CONTROLLER_DATA	0x03e1
++#define CARD_CONTROLLER_SIZE	2
++ /* Power register */
++  #define VPP_GET_VCC		0x01
++  #define POWER_ENABLE		0x10
++ #define CARD_VOLTAGE_SENSE	0x1f
++  #define VCC_3VORXV_CAPABLE	0x00
++  #define VCC_XV_ONLY		0x01
++  #define VCC_3V_CAPABLE	0x02
++  #define VCC_5V_ONLY		0x03
++ #define CARD_VOLTAGE_SELECT	0x2f
++  #define VCC_3V		0x01
++  #define VCC_5V		0x00
++  #define VCC_XV		0x02
++  #define VCC_STATUS_3V		0x02
++  #define VCC_STATUS_5V		0x01
++  #define VCC_STATUS_XV		0x03
++ #define GLOBAL_CONTROL		0x1e
++  #define EXWRBK		0x04
++  #define IRQPM_EN		0x08
++  #define CLRPMIRQ		0x10
++
++#define IO_MAX_MAPS	2
++#define MEM_MAX_MAPS	5
++
++enum {
++	SLOT_PROBE = 0,
++	SLOT_NOPROBE_IO,
++	SLOT_NOPROBE_MEM,
++	SLOT_NOPROBE_ALL
++};
++
++typedef struct vrc4171_socket {
++	int noprobe;
++	struct pcmcia_socket pcmcia_socket;
++	char name[24];
++	int csc_irq;
++	int io_irq;
++} vrc4171_socket_t;
++
++static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS];
++static int vrc4171_slotb = SLOTB_IS_NONE;
++static unsigned int vrc4171_irq;
++static uint16_t vrc4171_irq_mask = 0xdeb8;
++
++static inline uint8_t exca_read_byte(int slot, uint8_t index)
++{
++	if (slot == CARD_SLOTB)
++		index += CARD_SLOTB_OFFSET;
++
++	outb(index, CARD_CONTROLLER_INDEX);
++	return inb(CARD_CONTROLLER_DATA);
++}
++
++static inline uint16_t exca_read_word(int slot, uint8_t index)
++{
++	uint16_t data;
++
++	if (slot == CARD_SLOTB)
++		index += CARD_SLOTB_OFFSET;
++
++	outb(index++, CARD_CONTROLLER_INDEX);
++	data = inb(CARD_CONTROLLER_DATA);
++
++	outb(index, CARD_CONTROLLER_INDEX);
++	data |= ((uint16_t)inb(CARD_CONTROLLER_DATA)) << 8;
++
++	return data;
++}
++
++static inline uint8_t exca_write_byte(int slot, uint8_t index, uint8_t data)
++{
++	if (slot == CARD_SLOTB)
++		index += CARD_SLOTB_OFFSET;
++
++	outb(index, CARD_CONTROLLER_INDEX);
++	outb(data, CARD_CONTROLLER_DATA);
++
++	return data;
++}
++
++static inline uint16_t exca_write_word(int slot, uint8_t index, uint16_t data)
++{
++	if (slot == CARD_SLOTB)
++		index += CARD_SLOTB_OFFSET;
++
++	outb(index++, CARD_CONTROLLER_INDEX);
++	outb(data, CARD_CONTROLLER_DATA);
++
++	outb(index, CARD_CONTROLLER_INDEX);
++	outb((uint8_t)(data >> 8), CARD_CONTROLLER_DATA);
++
++	return data;
++}
++
++static inline int search_nonuse_irq(void)
++{
++	int i;
++
++	for (i = 0; i < 16; i++) {
++		if (vrc4171_irq_mask & (1 << i)) {
++			vrc4171_irq_mask &= ~(1 << i);
++			return i;
++		}
++	}
++
++	return -1;
++}
++
++static int pccard_init(struct pcmcia_socket *sock)
++{
++	vrc4171_socket_t *socket;
++	unsigned int slot;
++
++	sock->features |= SS_CAP_PCCARD | SS_CAP_PAGE_REGS;
++	sock->irq_mask = 0;
++	sock->map_size = 0x1000;
++	sock->pci_irq = vrc4171_irq;
++
++	slot = sock->sock;
++	socket = &vrc4171_sockets[slot];
++	socket->csc_irq = search_nonuse_irq();
++	socket->io_irq = search_nonuse_irq();
++
++	return 0;
++}
++
++static int pccard_suspend(struct pcmcia_socket *sock)
++{
++	return -EINVAL;
++}
++
++static int pccard_get_status(struct pcmcia_socket *sock, u_int *value)
++{
++	unsigned int slot;
++	uint8_t status, sense;
++	u_int val = 0;
++
++	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || value == NULL)
++		return -EINVAL;
++
++	slot = sock->sock;
++
++	status = exca_read_byte(slot, I365_STATUS);
++	if (exca_read_byte(slot, I365_INTCTL) & I365_PC_IOCARD) {
++		if (status & I365_CS_STSCHG)
++			val |= SS_STSCHG;
++	} else {
++		if (!(status & I365_CS_BVD1))
++			val |= SS_BATDEAD;
++		else if ((status & (I365_CS_BVD1 | I365_CS_BVD2)) == I365_CS_BVD1)
++			val |= SS_BATWARN;
++	}
++	if ((status & I365_CS_DETECT) == I365_CS_DETECT)
++		val |= SS_DETECT;
++	if (status & I365_CS_WRPROT)
++		val |= SS_WRPROT;
++	if (status & I365_CS_READY)
++		val |= SS_READY;
++	if (status & I365_CS_POWERON)
++		val |= SS_POWERON;
++
++	sense = exca_read_byte(slot, CARD_VOLTAGE_SENSE);
++	switch (sense) {
++	case VCC_3VORXV_CAPABLE:
++		val |= SS_3VCARD | SS_XVCARD;
++		break;
++	case VCC_XV_ONLY:
++		val |= SS_XVCARD;
++		break;
++	case VCC_3V_CAPABLE:
++		val |= SS_3VCARD;
++		break;
++	default:
++		/* 5V only */
++		break;
++	}
++
++	*value = val;
++
++	return 0;
++}
++
++static inline u_char get_Vcc_value(uint8_t voltage)
++{
++	switch (voltage) {
++	case VCC_STATUS_3V:
++		return 33;
++	case VCC_STATUS_5V:
++		return 50;
++	default:
++		break;
++	}
++
++	return 0;
++}
++
++static inline u_char get_Vpp_value(uint8_t power, u_char Vcc)
++{
++	if ((power & 0x03) == 0x01 || (power & 0x03) == 0x02)
++		return Vcc;
++
++	return 0;
++}
++
++static int pccard_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
++{
++	unsigned int slot;
++	uint8_t power, voltage, control, cscint;
++
++	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || state == NULL)
++		return -EINVAL;
++
++	slot = sock->sock;
++
++	power = exca_read_byte(slot, I365_POWER);
++	voltage = exca_read_byte(slot, CARD_VOLTAGE_SELECT);
++
++	state->Vcc = get_Vcc_value(voltage);
++	state->Vpp = get_Vpp_value(power, state->Vcc);
++
++	state->flags = 0;
++	if (power & POWER_ENABLE)
++		state->flags |= SS_PWR_AUTO;
++	if (power & I365_PWR_OUT)
++		state->flags |= SS_OUTPUT_ENA;
++
++	control = exca_read_byte(slot, I365_INTCTL);
++	if (control & I365_PC_IOCARD)
++		state->flags |= SS_IOCARD;
++	if (!(control & I365_PC_RESET))
++		state->flags |= SS_RESET;
++
++        cscint = exca_read_byte(slot, I365_CSCINT);
++	state->csc_mask = 0;
++	if (state->flags & SS_IOCARD) {
++		if (cscint & I365_CSC_STSCHG)
++			state->flags |= SS_STSCHG;
++	} else {
++		if (cscint & I365_CSC_BVD1)  
++			state->csc_mask |= SS_BATDEAD;
++		if (cscint & I365_CSC_BVD2)  
++			state->csc_mask |= SS_BATWARN;
++	}
++	if (cscint & I365_CSC_READY)
++		state->csc_mask |= SS_READY;
++	if (cscint & I365_CSC_DETECT)
++		state->csc_mask |= SS_DETECT;
++
++	return 0;
++}
++
++static inline uint8_t set_Vcc_value(u_char Vcc)
++{
++	switch (Vcc) {
++	case 33:
++		return VCC_3V;
++	case 50:
++		return VCC_5V;
++	}
++
++	/* Small voltage is chosen for safety. */
++	return VCC_3V;
++}
++
++static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
++{
++	vrc4171_socket_t *socket;
++	unsigned int slot;
++	uint8_t voltage, power, control, cscint;
++
++	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS ||
++	    (state->Vpp != state->Vcc && state->Vpp != 0) ||
++	    (state->Vcc != 50 && state->Vcc != 33 && state->Vcc != 0))
++		return -EINVAL;
++
++	slot = sock->sock;
++	socket = &vrc4171_sockets[slot];
++
++	spin_lock_irq(&sock->lock);
++
++	voltage = set_Vcc_value(state->Vcc);
++	exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage);
++
++	power = POWER_ENABLE;
++	if (state->Vpp == state->Vcc)
++		power |= VPP_GET_VCC;
++	if (state->flags & SS_OUTPUT_ENA)
++		power |= I365_PWR_OUT;
++	exca_write_byte(slot, I365_POWER, power);
++
++	control = 0;
++	if (state->io_irq != 0)
++		control |= socket->io_irq;
++	if (state->flags & SS_IOCARD)
++		control |= I365_PC_IOCARD;
++	if (state->flags & SS_RESET)
++		control	&= ~I365_PC_RESET;
++	else
++		control |= I365_PC_RESET;
++	exca_write_byte(slot, I365_INTCTL, control);
++
++        cscint = 0;
++        exca_write_byte(slot, I365_CSCINT, cscint);
++	exca_read_byte(slot, I365_CSC);	/* clear CardStatus change */
++	if (state->csc_mask != 0)
++		cscint |= socket->csc_irq << 8;
++	if (state->flags & SS_IOCARD) {
++		if (state->csc_mask & SS_STSCHG)
++			cscint |= I365_CSC_STSCHG;
++	} else {
++		if (state->csc_mask & SS_BATDEAD)
++			cscint |= I365_CSC_BVD1;
++		if (state->csc_mask & SS_BATWARN)
++			cscint |= I365_CSC_BVD2;
++	}
++	if (state->csc_mask & SS_READY)
++		cscint |= I365_CSC_READY;
++	if (state->csc_mask & SS_DETECT)
++		cscint |= I365_CSC_DETECT;
++        exca_write_byte(slot, I365_CSCINT, cscint);
++
++	spin_unlock_irq(&sock->lock);
++
++	return 0;
++}
++
++static int pccard_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
++{
++	unsigned int slot;
++	uint8_t ioctl, addrwin;
++	u_char map;
++
++	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS ||
++	    io == NULL || io->map >= IO_MAX_MAPS ||
++	    io->start > 0xffff || io->stop > 0xffff || io->start > io->stop)
++		return -EINVAL;
++
++	slot = sock->sock;
++	map = io->map;
++
++	addrwin = exca_read_byte(slot, I365_ADDRWIN);
++	if (addrwin & I365_ENA_IO(map)) {
++		addrwin &= ~I365_ENA_IO(map);
++		exca_write_byte(slot, I365_ADDRWIN, addrwin);
++	}
++
++	exca_write_word(slot, I365_IO(map)+I365_W_START, io->start);
++	exca_write_word(slot, I365_IO(map)+I365_W_STOP, io->stop);
++
++	ioctl = 0;
++	if (io->speed > 0)
++		ioctl |= I365_IOCTL_WAIT(map);
++	if (io->flags & MAP_16BIT)
++		ioctl |= I365_IOCTL_16BIT(map);
++	if (io->flags & MAP_AUTOSZ)
++		ioctl |= I365_IOCTL_IOCS16(map);
++	if (io->flags & MAP_0WS)
++		ioctl |= I365_IOCTL_0WS(map);
++	exca_write_byte(slot, I365_IOCTL, ioctl);
++
++	if (io->flags & MAP_ACTIVE) {
++		addrwin |= I365_ENA_IO(map);
++		exca_write_byte(slot, I365_ADDRWIN, addrwin);
++	}
++
++	return 0;
++}
++
++static int pccard_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
++{
++	unsigned int slot;
++	uint16_t start, stop, offset;
++	uint8_t addrwin;
++	u_char map;
++
++	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS ||
++	    mem == NULL || mem->map >= MEM_MAX_MAPS ||
++	    mem->sys_start < CARD_MEM_START || mem->sys_start > CARD_MEM_END ||
++	    mem->sys_stop < CARD_MEM_START || mem->sys_stop > CARD_MEM_END ||
++	    mem->sys_start > mem->sys_stop ||
++	    mem->card_start > CARD_MAX_MEM_OFFSET ||
++	    mem->speed > CARD_MAX_MEM_SPEED)
++		return -EINVAL;
++
++	slot = sock->sock;
++	map = mem->map;
++
++	addrwin = exca_read_byte(slot, I365_ADDRWIN);
++	if (addrwin & I365_ENA_MEM(map)) {
++		addrwin &= ~I365_ENA_MEM(map);
++		exca_write_byte(slot, I365_ADDRWIN, addrwin);
++	}
++
++	start = (mem->sys_start >> 12) & 0x3fff;
++	if (mem->flags & MAP_16BIT)
++		start |= I365_MEM_16BIT;
++	exca_write_word(slot, I365_MEM(map)+I365_W_START, start);
++
++	stop = (mem->sys_stop >> 12) & 0x3fff;
++	switch (mem->speed) {
++	case 0:
++		break;
++	case 1:
++		stop |= I365_MEM_WS0;
++		break;
++	case 2:
++		stop |= I365_MEM_WS1;
++		break;
++	default:
++		stop |= I365_MEM_WS0 | I365_MEM_WS1;
++		break;
++	}
++	exca_write_word(slot, I365_MEM(map)+I365_W_STOP, stop);
++
++	offset = (mem->card_start >> 12) & 0x3fff;
++	if (mem->flags & MAP_ATTRIB)
++		offset |= I365_MEM_REG;
++	if (mem->flags & MAP_WRPROT)
++		offset |= I365_MEM_WRPROT;
++	exca_write_word(slot, I365_MEM(map)+I365_W_OFF, offset);
++
++	if (mem->flags & MAP_ACTIVE) {
++		addrwin |= I365_ENA_MEM(map);
++		exca_write_byte(slot, I365_ADDRWIN, addrwin);
++	}
++
++	return 0;
++}
++
++static struct pccard_operations vrc4171_pccard_operations = {
++	.init			= pccard_init,
++	.suspend		= pccard_suspend,
++	.get_status		= pccard_get_status,
++	.get_socket		= pccard_get_socket,
++	.set_socket		= pccard_set_socket,
++	.set_io_map		= pccard_set_io_map,
++	.set_mem_map		= pccard_set_mem_map,
++};
++
++static inline unsigned int get_events(int slot)
++{
++	unsigned int events = 0;
++	uint8_t status, csc;
++
++	status = exca_read_byte(slot, I365_STATUS);
++	csc = exca_read_byte(slot, I365_CSC);
++
++	if (exca_read_byte(slot, I365_INTCTL) & I365_PC_IOCARD) {
++		if ((csc & I365_CSC_STSCHG) && (status & I365_CS_STSCHG))
++			events |= SS_STSCHG;
++	} else {
++		if (csc & (I365_CSC_BVD1 | I365_CSC_BVD2)) {
++			if (!(status & I365_CS_BVD1))
++				events |= SS_BATDEAD;
++			else if ((status & (I365_CS_BVD1 | I365_CS_BVD2)) == I365_CS_BVD1)
++				events |= SS_BATWARN;
++		}
++	}
++	if ((csc & I365_CSC_READY) && (status & I365_CS_READY))
++		events |= SS_READY;
++	if ((csc & I365_CSC_DETECT) && ((status & I365_CS_DETECT) == I365_CS_DETECT))
++		events |= SS_DETECT;
++
++	return events;
++}
++
++static irqreturn_t pccard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	vrc4171_socket_t *socket;
++	unsigned int events;
++	irqreturn_t retval = IRQ_NONE;
++	uint16_t status;
++
++	status = vrc4171_get_irq_status();
++	if (status & IRQ_A) {
++		socket = &vrc4171_sockets[CARD_SLOTA];
++		if (socket->noprobe == SLOT_PROBE) {
++			if (status & (1 << socket->csc_irq)) {
++				events = get_events(CARD_SLOTA);
++				if (events != 0) {
++					pcmcia_parse_events(&socket->pcmcia_socket, events);
++					retval = IRQ_HANDLED;
++				}
++			}
++		}
++	}
++
++	if (status & IRQ_B) {
++		socket = &vrc4171_sockets[CARD_SLOTB];
++		if (socket->noprobe == SLOT_PROBE) {
++			if (status & (1 << socket->csc_irq)) {
++				events = get_events(CARD_SLOTB);
++				if (events != 0) {
++					pcmcia_parse_events(&socket->pcmcia_socket, events);
++					retval = IRQ_HANDLED;
++				}
++			}
++		}
++	}
++
++	return retval;
++}
++
++static inline void reserve_using_irq(int slot)
++{
++	unsigned int irq;
++
++	irq = exca_read_byte(slot, I365_INTCTL);
++	irq &= 0x0f;
++	vrc4171_irq_mask &= ~(1 << irq);
++
++	irq = exca_read_byte(slot, I365_CSCINT);
++	irq = (irq & 0xf0) >> 4;
++	vrc4171_irq_mask &= ~(1 << irq);
++}
++
++static int __devinit vrc4171_add_socket(int slot)
++{
++	vrc4171_socket_t *socket;
++	int retval;
++
++	if (slot >= CARD_MAX_SLOTS)
++		return -EINVAL;
++
++	socket = &vrc4171_sockets[slot];
++	if (socket->noprobe != SLOT_PROBE) {
++		uint8_t addrwin;
++
++		switch (socket->noprobe) {
++		case SLOT_NOPROBE_MEM:
++			addrwin = exca_read_byte(slot, I365_ADDRWIN);
++			addrwin &= 0x1f;
++			exca_write_byte(slot, I365_ADDRWIN, addrwin);
++			break;
++		case SLOT_NOPROBE_IO:
++			addrwin = exca_read_byte(slot, I365_ADDRWIN);
++			addrwin &= 0xc0;
++			exca_write_byte(slot, I365_ADDRWIN, addrwin);
++			break;
++		default:
++			break;
++		}
++
++		reserve_using_irq(slot);
++
++		return 0;
++	}
++
++	sprintf(socket->name, "NEC VRC4171 Card Slot %1c", 'A' + slot);
++
++	socket->pcmcia_socket.ops = &vrc4171_pccard_operations;
++
++	retval = pcmcia_register_socket(&socket->pcmcia_socket);
++	if (retval != 0)
++		return retval;
++
++	exca_write_byte(slot, I365_ADDRWIN, 0);
++
++	exca_write_byte(slot, GLOBAL_CONTROL, 0);
++
++	return 0;
++}
++
++static void vrc4171_remove_socket(int slot)
++{
++	vrc4171_socket_t *socket;
++
++	if (slot >= CARD_MAX_SLOTS)
++		return;
++
++	socket = &vrc4171_sockets[slot];
++
++	pcmcia_unregister_socket(&socket->pcmcia_socket);
++}
++
++static int __devinit vrc4171_card_setup(char *options)
++{
++	if (options == NULL || *options == '\0')
++		return 0;
++
++	if (strncmp(options, "irq:", 4) == 0) {
++		int irq;
++		options += 4;
++		irq = simple_strtoul(options, &options, 0);
++		if (irq >= 0 && irq < NR_IRQS)
++			vrc4171_irq = irq;
++
++		if (*options != ',')
++			return 0;
++		options++;
++	}
++
++	if (strncmp(options, "slota:", 6) == 0) {
++		options += 6;
++		if (*options != '\0') {
++			if (strncmp(options, "memnoprobe", 10) == 0) {
++				vrc4171_sockets[CARD_SLOTA].noprobe = SLOT_NOPROBE_MEM;
++				options += 10;
++			} else if (strncmp(options, "ionoprobe", 9) == 0) {
++				vrc4171_sockets[CARD_SLOTA].noprobe = SLOT_NOPROBE_IO;
++				options += 9;
++			} else if ( strncmp(options, "noprobe", 7) == 0) {
++				vrc4171_sockets[CARD_SLOTA].noprobe = SLOT_NOPROBE_ALL;
++				options += 7;
++			}
++
++			if (*options != ',')
++				return 0;
++			options++;
++		} else
++			return 0;
++
++	}
++
++	if (strncmp(options, "slotb:", 6) == 0) {
++		options += 6;
++		if (*options != '\0') {
++			if (strncmp(options, "pccard", 6) == 0) {
++				vrc4171_slotb = SLOTB_IS_PCCARD;
++				options += 6;
++			} else if (strncmp(options, "cf", 2) == 0) {
++				vrc4171_slotb = SLOTB_IS_CF;
++				options += 2;
++			} else if (strncmp(options, "flashrom", 8) == 0) {
++				vrc4171_slotb = SLOTB_IS_FLASHROM;
++				options += 8;
++			} else if (strncmp(options, "none", 4) == 0) {
++				vrc4171_slotb = SLOTB_IS_NONE;
++				options += 4;
++			}
++
++			if (*options != ',')
++				return 0;
++			options++;
++
++			if (strncmp(options, "memnoprobe", 10) == 0)
++				vrc4171_sockets[CARD_SLOTB].noprobe = SLOT_NOPROBE_MEM;
++			if (strncmp(options, "ionoprobe", 9) == 0)
++				vrc4171_sockets[CARD_SLOTB].noprobe = SLOT_NOPROBE_IO;
++			if (strncmp(options, "noprobe", 7) == 0)
++				vrc4171_sockets[CARD_SLOTB].noprobe = SLOT_NOPROBE_ALL;
++		}
++	}
++
++	return 0;
++}
++
++__setup("vrc4171_card=", vrc4171_card_setup);
++
++static int __devinit vrc4171_card_init(void)
++{
++	int retval, slot;
++
++	vrc4171_set_multifunction_pin(vrc4171_slotb);
++
++	if (request_region(CARD_CONTROLLER_INDEX, CARD_CONTROLLER_SIZE,
++	                       "NEC VRC4171 Card Controller") == NULL)
++		return -EBUSY;
++
++	for (slot = 0; slot < CARD_MAX_SLOTS; slot++) {
++		if (slot == CARD_SLOTB && vrc4171_slotb == SLOTB_IS_NONE)
++			break;
++
++		retval = vrc4171_add_socket(slot);
++		if (retval != 0)
++			return retval;
++	}
++
++	retval = request_irq(vrc4171_irq, pccard_interrupt, SA_SHIRQ,
++	                     "NEC VRC4171 Card Controller", vrc4171_sockets);
++	if (retval < 0) {
++		for (slot = 0; slot < CARD_MAX_SLOTS; slot++)
++			vrc4171_remove_socket(slot);
++
++		return retval;
++	}
++
++	printk(KERN_INFO "NEC VRC4171 Card Controller, connected to IRQ %d\n", vrc4171_irq);
++
++	return 0;
++}
++
++static void __devexit vrc4171_card_exit(void)
++{
++	int slot;
++
++	for (slot = 0; slot < CARD_MAX_SLOTS; slot++)
++		vrc4171_remove_socket(slot);
++
++	release_region(CARD_CONTROLLER_INDEX, CARD_CONTROLLER_SIZE);
++}
++
++module_init(vrc4171_card_init);
++module_exit(vrc4171_card_exit);
+diff -urpNX dontdiff linux-2.6.10/drivers/pcmcia/vrc4173_cardu.c linux-2.6.10-mips/drivers/pcmcia/vrc4173_cardu.c
+--- linux-2.6.10/drivers/pcmcia/vrc4173_cardu.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/pcmcia/vrc4173_cardu.c	2004-10-27 02:14:44.000000000 +0200
+@@ -0,0 +1,622 @@
++/*
++ * FILE NAME
++ *	drivers/pcmcia/vrc4173_cardu.c
++ *
++ * BRIEF MODULE DESCRIPTION
++ * 	NEC VRC4173 CARDU driver for Socket Services
++ *	(This device doesn't support CardBus. it is supporting only 16bit PC Card.)
++ *
++ * Copyright 2002,2003 Yoichi Yuasa <yuasa at hh.iij4u.or.jp>
++ *
++ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
++ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
++ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  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.
++ */
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++#include <linux/spinlock.h>
++#include <linux/types.h>
++
++#include <asm/io.h>
++
++#include <pcmcia/ss.h>
++
++#include "vrc4173_cardu.h"
++
++MODULE_DESCRIPTION("NEC VRC4173 CARDU driver for Socket Services");
++MODULE_AUTHOR("Yoichi Yuasa <yuasa at hh.iij4u.or.jp>");
++MODULE_LICENSE("GPL");
++
++static int vrc4173_cardu_slots;
++
++static vrc4173_socket_t cardu_sockets[CARDU_MAX_SOCKETS];
++
++extern struct socket_info_t *pcmcia_register_socket (int slot,
++                                                     struct pccard_operations *vtable,
++                                                     int use_bus_pm);
++extern void pcmcia_unregister_socket(struct socket_info_t *s);
++
++static inline uint8_t exca_readb(vrc4173_socket_t *socket, uint16_t offset)
++{
++	return readb(socket->base + EXCA_REGS_BASE + offset);
++}
++
++static inline uint16_t exca_readw(vrc4173_socket_t *socket, uint16_t offset)
++{
++	uint16_t val;
++
++	val = readb(socket->base + EXCA_REGS_BASE + offset);
++	val |= (u16)readb(socket->base + EXCA_REGS_BASE + offset + 1) << 8;
++
++	return val;
++}
++
++static inline void exca_writeb(vrc4173_socket_t *socket, uint16_t offset, uint8_t val)
++{
++	writeb(val, socket->base + EXCA_REGS_BASE + offset);
++}
++
++static inline void exca_writew(vrc4173_socket_t *socket, uint8_t offset, uint16_t val)
++{
++	writeb((u8)val, socket->base + EXCA_REGS_BASE + offset);
++	writeb((u8)(val >> 8), socket->base + EXCA_REGS_BASE + offset + 1);
++}
++
++static inline uint32_t cardbus_socket_readl(vrc4173_socket_t *socket, u16 offset)
++{
++	return readl(socket->base + CARDBUS_SOCKET_REGS_BASE + offset);
++}
++
++static inline void cardbus_socket_writel(vrc4173_socket_t *socket, u16 offset, uint32_t val)
++{
++	writel(val, socket->base + CARDBUS_SOCKET_REGS_BASE + offset);
++}
++
++static void cardu_pciregs_init(struct pci_dev *dev)
++{
++	u32 syscnt;
++	u16 brgcnt;
++	u8 devcnt;
++
++	pci_write_config_dword(dev, 0x1c, 0x10000000);
++	pci_write_config_dword(dev, 0x20, 0x17fff000);
++	pci_write_config_dword(dev, 0x2c, 0);
++	pci_write_config_dword(dev, 0x30, 0xfffc);
++
++	pci_read_config_word(dev, BRGCNT, &brgcnt);
++	brgcnt &= ~IREQ_INT;
++	pci_write_config_word(dev, BRGCNT, brgcnt);
++
++	pci_read_config_dword(dev, SYSCNT, &syscnt);
++	syscnt &= ~(BAD_VCC_REQ_DISB|PCPCI_EN|CH_ASSIGN_MASK|SUB_ID_WR_EN|PCI_CLK_RIN);
++	syscnt |= (CH_ASSIGN_NODMA|ASYN_INT_MODE);
++	pci_write_config_dword(dev, SYSCNT, syscnt);
++
++	pci_read_config_byte(dev, DEVCNT, &devcnt);
++	devcnt &= ~(ZOOM_VIDEO_EN|SR_PCI_INT_SEL_MASK|PCI_INT_MODE|IRQ_MODE);
++	devcnt |= (SR_PCI_INT_SEL_NONE|IFG);
++	pci_write_config_byte(dev, DEVCNT, devcnt);
++
++	pci_write_config_byte(dev, CHIPCNT, S_PREF_DISB);
++
++	pci_write_config_byte(dev, SERRDIS, 0);
++}
++
++static int cardu_init(unsigned int slot)
++{
++	vrc4173_socket_t *socket = &cardu_sockets[slot];
++
++	cardu_pciregs_init(socket->dev);
++
++	/* CARD_SC bits are cleared by reading CARD_SC. */
++	exca_writeb(socket, GLO_CNT, 0);
++
++	socket->cap.features |= SS_CAP_PCCARD | SS_CAP_PAGE_REGS;
++	socket->cap.irq_mask = 0;
++	socket->cap.map_size = 0x1000;
++	socket->cap.pci_irq  = socket->dev->irq;
++	socket->events = 0;
++	spin_lock_init(socket->event_lock);
++
++	/* Enable PC Card status interrupts */
++	exca_writeb(socket, CARD_SCI, CARD_DT_EN|RDY_EN|BAT_WAR_EN|BAT_DEAD_EN);
++
++	return 0;
++}
++
++static int cardu_suspend(unsigned int slot)
++{
++	return -EINVAL;
++}
++
++static int cardu_register_callback(unsigned int sock,
++                                           void (*handler)(void *, unsigned int),
++                                           void * info)
++{
++	vrc4173_socket_t *socket = &cardu_sockets[sock];
++
++	socket->handler = handler;
++	socket->info = info;
++
++	return 0;
++}
++
++static int cardu_inquire_socket(unsigned int sock, socket_cap_t *cap)
++{
++	vrc4173_socket_t *socket = &cardu_sockets[sock];
++
++	*cap = socket->cap;
++
++	return 0;
++}
++
++static int cardu_get_status(unsigned int sock, u_int *value)
++{
++	vrc4173_socket_t *socket = &cardu_sockets[sock];
++	uint32_t state;
++	uint8_t status;
++	u_int val = 0;
++
++	status = exca_readb(socket, IF_STATUS);
++	if (status & CARD_PWR) val |= SS_POWERON;
++	if (status & READY) val |= SS_READY;
++	if (status & CARD_WP) val |= SS_WRPROT;
++	if ((status & (CARD_DETECT1|CARD_DETECT2)) == (CARD_DETECT1|CARD_DETECT2))
++		val |= SS_DETECT;
++	if (exca_readb(socket, INT_GEN_CNT) & CARD_TYPE_IO) {
++		if (status & STSCHG) val |= SS_STSCHG;
++	} else {
++		status &= BV_DETECT_MASK;
++		if (status != BV_DETECT_GOOD) {
++			if (status == BV_DETECT_WARN) val |= SS_BATWARN;
++			else val |= SS_BATDEAD;
++		}
++	}
++
++	state = cardbus_socket_readl(socket, SKT_PRE_STATE);
++	if (state & VOL_3V_CARD_DT) val |= SS_3VCARD;
++	if (state & VOL_XV_CARD_DT) val |= SS_XVCARD;
++	if (state & CB_CARD_DT) val |= SS_CARDBUS;
++	if (!(state &
++	      (VOL_YV_CARD_DT|VOL_XV_CARD_DT|VOL_3V_CARD_DT|VOL_5V_CARD_DT|CCD20|CCD10)))
++		val |= SS_PENDING;
++
++	*value = val;
++
++	return 0;
++}
++
++static inline u_char get_Vcc_value(uint8_t val)
++{
++	switch (val & VCC_MASK) {
++	case VCC_3V:
++		return 33;
++	case VCC_5V:
++		return 50;
++	}
++
++	return 0;
++}
++
++static inline u_char get_Vpp_value(uint8_t val)
++{
++	switch (val & VPP_MASK) {
++	case VPP_12V:
++		return 120;
++	case VPP_VCC:
++		return get_Vcc_value(val);
++	}
++
++	return 0;
++}
++
++static int cardu_get_socket(unsigned int sock, socket_state_t *state)
++{
++	vrc4173_socket_t *socket = &cardu_sockets[sock];
++	uint8_t val;
++
++	val = exca_readb(socket, PWR_CNT);
++	state->Vcc = get_Vcc_value(val);
++	state->Vpp = get_Vpp_value(val);
++	state->flags = 0;
++	if (val & CARD_OUT_EN) state->flags |= SS_OUTPUT_ENA;
++
++	val = exca_readb(socket, INT_GEN_CNT);
++	if (!(val & CARD_REST0)) state->flags |= SS_RESET;
++	if (val & CARD_TYPE_IO) state->flags |= SS_IOCARD;
++
++	return 0;
++}
++
++static inline uint8_t set_Vcc_value(u_char Vcc)
++{
++	switch (Vcc) {
++	case 33:
++		return VCC_3V;
++	case 50:
++		return VCC_5V;
++	}
++
++	return VCC_0V;
++}
++
++static inline uint8_t set_Vpp_value(u_char Vpp)
++{
++	switch (Vpp) {
++	case 33:
++	case 50:
++		return VPP_VCC;
++	case 120:
++		return VPP_12V;
++	}
++
++	return VPP_0V;
++}
++
++static int cardu_set_socket(unsigned int sock, socket_state_t *state)
++{
++	vrc4173_socket_t *socket = &cardu_sockets[sock];
++	uint8_t val;
++
++	if (((state->Vpp == 33) || (state->Vpp == 50)) && (state->Vpp != state->Vcc))
++			return -EINVAL;
++
++	val = set_Vcc_value(state->Vcc);
++	val |= set_Vpp_value(state->Vpp);
++	if (state->flags & SS_OUTPUT_ENA) val |= CARD_OUT_EN;
++	exca_writeb(socket, PWR_CNT, val);
++
++	val = exca_readb(socket, INT_GEN_CNT) & CARD_REST0;
++	if (state->flags & SS_RESET) val &= ~CARD_REST0;
++	else val |= CARD_REST0;
++	if (state->flags & SS_IOCARD) val |= CARD_TYPE_IO;
++	exca_writeb(socket, INT_GEN_CNT, val);
++
++	return 0;
++}
++
++static int cardu_get_io_map(unsigned int sock, struct pccard_io_map *io)
++{
++	vrc4173_socket_t *socket = &cardu_sockets[sock];
++	uint8_t ioctl, window;
++	u_char map;
++
++	map = io->map;
++	if (map > 1)
++		return -EINVAL; 
++
++	io->start = exca_readw(socket, IO_WIN_SA(map));
++	io->stop = exca_readw(socket, IO_WIN_EA(map));
++
++	ioctl = exca_readb(socket, IO_WIN_CNT);
++	window = exca_readb(socket, ADR_WIN_EN);
++	io->flags  = (window & IO_WIN_EN(map)) ? MAP_ACTIVE : 0;
++	if (ioctl & IO_WIN_DATA_AUTOSZ(map))
++		io->flags |= MAP_AUTOSZ;
++	else if (ioctl & IO_WIN_DATA_16BIT(map))
++		io->flags |= MAP_16BIT;
++
++	return 0;
++}
++
++static int cardu_set_io_map(unsigned int sock, struct pccard_io_map *io)
++{
++	vrc4173_socket_t *socket = &cardu_sockets[sock];
++	uint16_t ioctl;
++	uint8_t window, enable;
++	u_char map;
++
++	map = io->map;
++	if (map > 1)
++		return -EINVAL;
++
++	window = exca_readb(socket, ADR_WIN_EN);
++	enable = IO_WIN_EN(map);
++
++	if (window & enable) {
++		window &= ~enable;
++		exca_writeb(socket, ADR_WIN_EN, window);
++	}
++
++	exca_writew(socket, IO_WIN_SA(map), io->start);
++	exca_writew(socket, IO_WIN_EA(map), io->stop);
++
++	ioctl = exca_readb(socket, IO_WIN_CNT) & ~IO_WIN_CNT_MASK(map);
++	if (io->flags & MAP_AUTOSZ) ioctl |= IO_WIN_DATA_AUTOSZ(map);
++	else if (io->flags & MAP_16BIT) ioctl |= IO_WIN_DATA_16BIT(map);
++	exca_writeb(socket, IO_WIN_CNT, ioctl);
++
++	if (io->flags & MAP_ACTIVE)
++		exca_writeb(socket, ADR_WIN_EN, window | enable);
++
++	return 0;
++}
++
++static int cardu_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
++{
++	vrc4173_socket_t *socket = &cardu_sockets[sock];
++	uint32_t start, stop, offset, page;
++	uint8_t window;
++	u_char map;
++
++	map = mem->map;
++	if (map > 4)
++		return -EINVAL;
++
++	window = exca_readb(socket, ADR_WIN_EN);
++	mem->flags = (window & MEM_WIN_EN(map)) ? MAP_ACTIVE : 0;
++
++	start = exca_readw(socket, MEM_WIN_SA(map));
++	mem->flags |= (start & MEM_WIN_DSIZE) ? MAP_16BIT : 0;
++	start = (start & 0x0fff) << 12;
++
++	stop = exca_readw(socket, MEM_WIN_EA(map));
++	stop = ((stop & 0x0fff) << 12) + 0x0fff;
++
++	offset = exca_readw(socket, MEM_WIN_OA(map));
++	mem->flags |= (offset & MEM_WIN_WP) ? MAP_WRPROT : 0;
++	mem->flags |= (offset & MEM_WIN_REGSET) ? MAP_ATTRIB : 0;
++	offset = ((offset & 0x3fff) << 12) + start;
++	mem->card_start = offset & 0x03ffffff;
++
++	page = exca_readb(socket, MEM_WIN_SAU(map)) << 24;
++	mem->sys_start = start + page;
++	mem->sys_stop = start + page;
++
++	return 0;
++}
++
++static int cardu_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
++{
++	vrc4173_socket_t *socket = &cardu_sockets[sock];
++	uint16_t value;
++	uint8_t window, enable;
++	u_long sys_start, sys_stop, card_start;
++	u_char map;
++
++	map = mem->map;
++	sys_start = mem->sys_start;
++	sys_stop = mem->sys_stop;
++	card_start = mem->card_start;
++
++	if (map > 4 || sys_start > sys_stop || ((sys_start ^ sys_stop) >> 24) ||
++	    (card_start >> 26))
++		return -EINVAL;
++
++	window = exca_readb(socket, ADR_WIN_EN);
++	enable = MEM_WIN_EN(map);
++	if (window & enable) {
++		window &= ~enable;
++		exca_writeb(socket, ADR_WIN_EN, window);
++	}
++
++	exca_writeb(socket, MEM_WIN_SAU(map), sys_start >> 24);
++
++	value = (sys_start >> 12) & 0x0fff;
++	if (mem->flags & MAP_16BIT) value |= MEM_WIN_DSIZE;
++	exca_writew(socket, MEM_WIN_SA(map), value);
++
++	value = (sys_stop >> 12) & 0x0fff;
++	exca_writew(socket, MEM_WIN_EA(map), value);
++
++	value = ((card_start - sys_start) >> 12) & 0x3fff;
++	if (mem->flags & MAP_WRPROT) value |= MEM_WIN_WP;
++	if (mem->flags & MAP_ATTRIB) value |= MEM_WIN_REGSET;
++	exca_writew(socket, MEM_WIN_OA(map), value);
++
++	if (mem->flags & MAP_ACTIVE)
++		exca_writeb(socket, ADR_WIN_EN, window | enable);
++
++	return 0;
++}
++
++static void cardu_proc_setup(unsigned int sock, struct proc_dir_entry *base)
++{
++}
++
++static struct pccard_operations cardu_operations = {
++	.init			= cardu_init,
++	.suspend		= cardu_suspend,
++	.register_callback	= cardu_register_callback,
++	.inquire_socket		= cardu_inquire_socket,
++	.get_status		= cardu_get_status,
++	.get_socket		= cardu_get_socket,
++	.set_socket		= cardu_set_socket,
++	.get_io_map		= cardu_get_io_map,
++	.set_io_map		= cardu_set_io_map,
++	.get_mem_map		= cardu_get_mem_map,
++	.set_mem_map		= cardu_set_mem_map,
++	.proc_setup		= cardu_proc_setup,
++};
++
++static void cardu_bh(void *data)
++{
++	vrc4173_socket_t *socket = (vrc4173_socket_t *)data;
++	uint16_t events;
++
++	spin_lock_irq(&socket->event_lock);
++	events = socket->events;
++	socket->events = 0;
++	spin_unlock_irq(&socket->event_lock);
++
++	if (socket->handler)
++		socket->handler(socket->info, events);
++}
++
++static uint16_t get_events(vrc4173_socket_t *socket)
++{
++	uint16_t events = 0;
++	uint8_t csc, status;
++
++	status = exca_readb(socket, IF_STATUS);
++	csc = exca_readb(socket, CARD_SC);
++	if ((csc & CARD_DT_CHG) && 
++	    ((status & (CARD_DETECT1|CARD_DETECT2)) == (CARD_DETECT1|CARD_DETECT2)))
++		events |= SS_DETECT;
++
++	if ((csc & RDY_CHG) && (status & READY))
++		events |= SS_READY;
++
++	if (exca_readb(socket, INT_GEN_CNT) & CARD_TYPE_IO) {
++		if ((csc & BAT_DEAD_ST_CHG) && (status & STSCHG))
++			events |= SS_STSCHG;
++	} else {
++		if (csc & (BAT_WAR_CHG|BAT_DEAD_ST_CHG)) {
++			if ((status & BV_DETECT_MASK) != BV_DETECT_GOOD) {
++				if (status == BV_DETECT_WARN) events |= SS_BATWARN;
++				else events |= SS_BATDEAD;
++			}
++		}
++	}
++
++	return events;
++}
++
++static void cardu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	vrc4173_socket_t *socket = (vrc4173_socket_t *)dev_id;
++	uint16_t events;
++
++	INIT_WORK(&socket->tq_work, cardu_bh, socket);
++
++	events = get_events(socket);
++	if (events) {
++		spin_lock(&socket->event_lock);
++		socket->events |= events;
++		spin_unlock(&socket->event_lock);
++		schedule_work(&socket->tq_work);
++	}
++}
++
++static int __devinit vrc4173_cardu_probe(struct pci_dev *dev,
++                                         const struct pci_device_id *ent)
++{
++	vrc4173_socket_t *socket;
++	unsigned long start, len, flags;
++	int slot, err;
++
++	slot = vrc4173_cardu_slots++;
++	socket = &cardu_sockets[slot];
++	if (socket->noprobe != 0)
++		return -EBUSY;
++
++	sprintf(socket->name, "NEC VRC4173 CARDU%1d", slot+1);
++
++	if ((err = pci_enable_device(dev)) < 0)
++		return err;
++
++	start = pci_resource_start(dev, 0);
++	if (start == 0)
++		return -ENODEV;
++
++	len = pci_resource_len(dev, 0);
++	if (len == 0)
++		return -ENODEV;
++
++	if (((flags = pci_resource_flags(dev, 0)) & IORESOURCE_MEM) == 0)
++		return -EBUSY;
++
++	if ((err = pci_request_regions(dev, socket->name)) < 0)
++		return err;
++
++	socket->base = ioremap(start, len);
++	if (socket->base == NULL)
++		return -ENODEV;
++
++	socket->dev = dev;
++
++	socket->pcmcia_socket = pcmcia_register_socket(slot, &cardu_operations, 1);
++	if (socket->pcmcia_socket == NULL) {
++		iounmap(socket->base);
++		socket->base = NULL;
++		return -ENOMEM;
++	}
++
++	if (request_irq(dev->irq, cardu_interrupt, SA_SHIRQ, socket->name, socket) < 0) {
++		pcmcia_unregister_socket(socket->pcmcia_socket);
++		socket->pcmcia_socket = NULL;
++		iounmap(socket->base);
++		socket->base = NULL;
++		return -EBUSY;
++	}
++
++	printk(KERN_INFO "%s at %#08lx, IRQ %d\n", socket->name, start, dev->irq);
++
++	return 0;
++}
++
++static int __devinit vrc4173_cardu_setup(char *options)
++{
++	if (options == NULL || *options == '\0')
++		return 0;
++
++	if (strncmp(options, "cardu1:", 7) == 0) {
++		options += 7;
++		if (*options != '\0') {
++			if (strncmp(options, "noprobe", 7) == 0) {
++				cardu_sockets[CARDU1].noprobe = 1;
++				options += 7;
++			}
++
++			if (*options != ',')
++				return 0;
++		} else
++			return 0;
++	}
++
++	if (strncmp(options, "cardu2:", 7) == 0) {
++		options += 7;
++		if ((*options != '\0') && (strncmp(options, "noprobe", 7) == 0))
++			cardu_sockets[CARDU2].noprobe = 1;
++	}
++
++	return 0;
++}
++
++__setup("vrc4173_cardu=", vrc4173_cardu_setup);
++
++static struct pci_device_id vrc4173_cardu_id_table[] __devinitdata = {
++	{	.vendor		= PCI_VENDOR_ID_NEC,
++		.device		= PCI_DEVICE_ID_NEC_NAPCCARD,
++		.subvendor	= PCI_ANY_ID,
++		.subdevice	= PCI_ANY_ID, },
++        {0, }
++};
++
++static struct pci_driver vrc4173_cardu_driver = {
++	.name		= "NEC VRC4173 CARDU",
++	.probe		= vrc4173_cardu_probe,
++	.id_table	= vrc4173_cardu_id_table,
++};
++
++static int __devinit vrc4173_cardu_init(void)
++{
++	vrc4173_cardu_slots = 0;
++
++	return pci_module_init(&vrc4173_cardu_driver);
++}
++
++static void __devexit vrc4173_cardu_exit(void)
++{
++	pci_unregister_driver(&vrc4173_cardu_driver);
++}
++
++module_init(vrc4173_cardu_init);
++module_exit(vrc4173_cardu_exit);
+diff -urpNX dontdiff linux-2.6.10/drivers/pcmcia/vrc4173_cardu.h linux-2.6.10-mips/drivers/pcmcia/vrc4173_cardu.h
+--- linux-2.6.10/drivers/pcmcia/vrc4173_cardu.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/pcmcia/vrc4173_cardu.h	2003-11-16 09:21:03.000000000 +0100
+@@ -0,0 +1,247 @@
++/*
++ * FILE NAME
++ *	drivers/pcmcia/vrc4173_cardu.h
++ *
++ * BRIEF MODULE DESCRIPTION
++ *	Include file for NEC VRC4173 CARDU.
++ *
++ * Copyright 2002 Yoichi Yuasa <yuasa at hh.iij4u.or.jp>
++ *
++ *  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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
++ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
++ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
++ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
++ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
++ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  You should have received a copy of the GNU General Public License along
++ *  with this program; if not, write to the Free Software Foundation, Inc.,
++ *  675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++#ifndef _VRC4173_CARDU_H
++#define _VRC4173_CARDU_H
++
++#include <linux/pci.h>
++
++#include <pcmcia/ss.h>
++
++#define CARDU_MAX_SOCKETS	2
++#define CARDU1			0
++#define CARDU2			1
++
++/*
++ * PCI Configuration Registers
++ */
++#define BRGCNT			0x3e
++ #define POST_WR_EN		0x0400
++ #define MEM1_PREF_EN		0x0200
++ #define MEM0_PREF_EN		0x0100
++ #define IREQ_INT		0x0080
++ #define CARD_RST		0x0040
++ #define MABORT_MODE		0x0020
++ #define VGA_EN			0x0008
++ #define ISA_EN			0x0004
++ #define SERR_EN		0x0002
++ #define PERR_EN		0x0001
++
++#define SYSCNT			0x80
++ #define BAD_VCC_REQ_DISB	0x00200000
++ #define PCPCI_EN		0x00080000
++ #define CH_ASSIGN_MASK		0x00070000
++ #define CH_ASSIGN_NODMA	0x00040000
++ #define SUB_ID_WR_EN		0x00000008
++ #define ASYN_INT_MODE		0x00000004
++ #define PCI_CLK_RIN		0x00000002
++
++#define DEVCNT			0x91
++ #define ZOOM_VIDEO_EN		0x40
++ #define SR_PCI_INT_SEL_MASK	0x18
++ #define SR_PCI_INT_SEL_NONE	0x00
++ #define PCI_INT_MODE		0x04
++ #define IRQ_MODE		0x02
++ #define IFG			0x01
++
++#define CHIPCNT			0x9c
++ #define S_PREF_DISB		0x10
++
++#define SERRDIS			0x9f
++ #define SERR_DIS_MAB		0x10
++ #define SERR_DIS_TAB		0x08
++ #define SERR_DIS_DT_PERR	0x04
++
++/*
++ * ExCA Registers
++ */
++#define EXCA_REGS_BASE		0x800
++#define EXCA_REGS_SIZE		0x800
++
++#define ID_REV			0x000
++ #define IF_TYPE_16BIT		0x80
++
++#define IF_STATUS		0x001
++ #define CARD_PWR		0x40
++ #define READY			0x20
++ #define CARD_WP		0x10
++ #define CARD_DETECT2		0x08
++ #define CARD_DETECT1		0x04
++ #define BV_DETECT_MASK		0x03
++ #define BV_DETECT_GOOD		0x03	/* Memory card */
++ #define BV_DETECT_WARN		0x02
++ #define BV_DETECT_BAD1		0x01
++ #define BV_DETECT_BAD0		0x00
++ #define STSCHG			0x02	/* I/O card */
++ #define SPKR			0x01
++
++#define PWR_CNT			0x002
++ #define CARD_OUT_EN		0x80
++ #define VCC_MASK		0x18
++ #define VCC_3V			0x18
++ #define VCC_5V			0x10
++ #define VCC_0V			0x00
++ #define VPP_MASK		0x03
++ #define VPP_12V		0x02
++ #define VPP_VCC		0x01
++ #define VPP_0V			0x00
++
++#define INT_GEN_CNT		0x003
++ #define CARD_REST0		0x40
++ #define CARD_TYPE_MASK		0x20
++ #define CARD_TYPE_IO		0x20
++ #define CARD_TYPE_MEM		0x00
++
++#define CARD_SC			0x004
++ #define CARD_DT_CHG		0x08
++ #define RDY_CHG		0x04
++ #define BAT_WAR_CHG		0x02
++ #define BAT_DEAD_ST_CHG	0x01
++
++#define CARD_SCI		0x005
++ #define CARD_DT_EN		0x08
++ #define RDY_EN			0x04
++ #define BAT_WAR_EN		0x02
++ #define BAT_DEAD_EN		0x01
++
++#define ADR_WIN_EN		0x006
++ #define IO_WIN_EN(x)		(0x40 << (x))
++ #define MEM_WIN_EN(x)		(0x01 << (x))
++
++#define IO_WIN_CNT		0x007
++ #define IO_WIN_CNT_MASK(x)	(0x03 << ((x) << 2))
++ #define IO_WIN_DATA_AUTOSZ(x)	(0x02 << ((x) << 2))	
++ #define IO_WIN_DATA_16BIT(x)	(0x01 << ((x) << 2))	
++
++#define IO_WIN_SA(x)		(0x008 + ((x) << 2))
++#define IO_WIN_EA(x)		(0x00a + ((x) << 2))
++
++#define MEM_WIN_SA(x)		(0x010 + ((x) << 3))
++ #define MEM_WIN_DSIZE		0x8000
++
++#define MEM_WIN_EA(x)		(0x012 + ((x) << 3))
++
++#define MEM_WIN_OA(x)		(0x014 + ((x) << 3))
++ #define MEM_WIN_WP		0x8000
++ #define MEM_WIN_REGSET		0x4000
++
++#define GEN_CNT			0x016
++ #define VS2_STATUS		0x80
++ #define VS1_STATUS		0x40
++ #define EXCA_REG_RST_EN	0x02
++
++#define GLO_CNT			0x01e
++ #define FUN_INT_LEV		0x08
++ #define INT_WB_CLR		0x04
++ #define CSC_INT_LEV		0x02
++
++#define IO_WIN_OAL(x)		(0x036 + ((x) << 1))
++#define IO_WIN_OAH(x)		(0x037 + ((x) << 1))
++
++#define MEM_WIN_SAU(x)		(0x040 + (x))
++
++#define IO_SETUP_TIM		0x080
++#define IO_CMD_TIM		0x081
++#define IO_HOLD_TIM		0x082
++#define MEM_SETUP_TIM(x)	(0x084 + ((x) << 2))
++#define MEM_CMD_TIM(x)		(0x085 + ((x) << 2))
++#define MEM_HOLD_TIM(x)		(0x086 + ((x) << 2))
++ #define TIM_CLOCKS(x)		((x) - 1)
++
++#define MEM_TIM_SEL1		0x08c
++#define MEM_TIM_SEL2		0x08d
++ #define MEM_WIN_TIMSEL1(x)	(0x03 << (((x) & 3) << 1))
++
++#define MEM_WIN_PWEN		0x091
++ #define POSTWEN		0x01
++
++/*
++ * CardBus Socket Registers
++ */
++#define CARDBUS_SOCKET_REGS_BASE	0x000
++#define CARDBUS_SOCKET_REGS_SIZE	0x800
++
++#define SKT_EV			0x000
++ #define POW_CYC_EV		0x00000008
++ #define CCD2_EV		0x00000004
++ #define CCD1_EV		0x00000002
++ #define CSTSCHG_EV		0x00000001
++
++#define SKT_MASK		0x004
++ #define POW_CYC_MASK		0x00000008
++ #define CCD_MASK		0x00000006
++ #define CSC_MASK		0x00000001
++
++#define SKT_PRE_STATE		0x008
++#define SKT_FORCE_EV		0x00c
++ #define VOL_3V_SKT		0x20000000
++ #define VOL_5V_SKT		0x10000000
++ #define CVS_TEST		0x00004000
++ #define VOL_YV_CARD_DT		0x00002000
++ #define VOL_XV_CARD_DT		0x00001000
++ #define VOL_3V_CARD_DT		0x00000800
++ #define VOL_5V_CARD_DT		0x00000400
++ #define BAD_VCC_REQ		0x00000200
++ #define DATA_LOST		0x00000100
++ #define NOT_A_CARD		0x00000080
++ #define CREADY			0x00000040
++ #define CB_CARD_DT		0x00000020
++ #define R2_CARD_DT		0x00000010
++ #define POW_UP			0x00000008
++ #define CCD20			0x00000004
++ #define CCD10			0x00000002
++ #define CSTSCHG		0x00000001
++
++#define SKT_CNT			0x010
++ #define STP_CLK_EN		0x00000080
++ #define VCC_CNT_MASK		0x00000070
++ #define VCC_CNT_3V		0x00000030
++ #define VCC_CNT_5V		0x00000020
++ #define VCC_CNT_0V		0x00000000
++ #define VPP_CNT_MASK		0x00000007
++ #define VPP_CNT_3V		0x00000003
++ #define VPP_CNT_5V		0x00000002
++ #define VPP_CNT_12V		0x00000001
++ #define VPP_CNT_0V		0x00000000
++
++typedef struct vrc4173_socket {
++	int noprobe;
++	struct pci_dev *dev;
++	void *base;
++	void (*handler)(void *, unsigned int);
++	void *info;
++	socket_cap_t cap;
++	spinlock_t event_lock;
++	uint16_t events;
++	struct socket_info_t *pcmcia_socket;
++	struct work_struct tq_work;
++	char name[20];
++} vrc4173_socket_t;
++
++#endif /* _VRC4173_CARDU_H */
+diff -urpNX dontdiff linux-2.6.10/drivers/scsi/Kconfig linux-2.6.10-mips/drivers/scsi/Kconfig
+--- linux-2.6.10/drivers/scsi/Kconfig	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/drivers/scsi/Kconfig	2004-12-28 20:06:46.000000000 +0100
+@@ -217,14 +217,14 @@ config SGIWD93_SCSI
+ 
+ config SCSI_DECNCR
+ 	tristate "DEC NCR53C94 Scsi Driver"
+-	depends on DECSTATION && TC && SCSI
++	depends on MACH_DECSTATION && SCSI && TC
+ 	help
+ 	  Say Y here to support the NCR53C94 SCSI controller chips on IOASIC
+ 	  based TURBOchannel DECstations and TURBOchannel PMAZ-A cards.
+ 
+ config SCSI_DECSII
+ 	tristate "DEC SII Scsi Driver"
+-	depends on DECSTATION && SCSI
++	depends on MACH_DECSTATION && SCSI && MIPS32
+ 
+ config BLK_DEV_3W_XXXX_RAID
+ 	tristate "3ware 5/6/7/8xxx ATA-RAID support"
+diff -urpNX dontdiff linux-2.6.10/drivers/scsi/NCR53C9x.h linux-2.6.10-mips/drivers/scsi/NCR53C9x.h
+--- linux-2.6.10/drivers/scsi/NCR53C9x.h	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/drivers/scsi/NCR53C9x.h	2004-03-23 20:43:39.000000000 +0100
+@@ -145,12 +145,7 @@
+ 
+ #ifndef MULTIPLE_PAD_SIZES
+ 
+-#ifdef CONFIG_CPU_HAS_WB
+-#include <asm/wbflush.h>
+-#define esp_write(__reg, __val) do{(__reg) = (__val); wbflush();} while(0)
+-#else
+-#define esp_write(__reg, __val) ((__reg) = (__val))
+-#endif
++#define esp_write(__reg, __val) do{(__reg) = (__val); iob();} while(0)
+ #define esp_read(__reg) (__reg)
+ 
+ struct ESP_regs {
+diff -urpNX dontdiff linux-2.6.10/drivers/scsi/dec_esp.c linux-2.6.10-mips/drivers/scsi/dec_esp.c
+--- linux-2.6.10/drivers/scsi/dec_esp.c	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/drivers/scsi/dec_esp.c	2004-10-27 02:14:47.000000000 +0200
+@@ -17,6 +17,8 @@
+  *            data.
+  * 20001005	- Initialization fixes for 2.4.0-test9
+  * 			  Florian Lohoff <flo at rfc822.org>
++ *
++ *	Copyright (C) 2002, 2003  Maciej W. Rozycki
+  */
+ 
+ #include <linux/kernel.h>
+@@ -26,58 +28,51 @@
+ #include <linux/slab.h>
+ #include <linux/blkdev.h>
+ #include <linux/proc_fs.h>
++#include <linux/spinlock.h>
+ #include <linux/stat.h>
+ 
+-#include "scsi.h"
+-#include <scsi/scsi_host.h>
+-#include "NCR53C9x.h"
+-
+-#include <asm/irq.h>
+-#include <asm/jazz.h>
+-#include <asm/jazzdma.h>
+ #include <asm/dma.h>
+-
++#include <asm/irq.h>
+ #include <asm/pgtable.h>
++#include <asm/system.h>
+ 
+-#include <asm/dec/tc.h>
+ #include <asm/dec/interrupts.h>
++#include <asm/dec/ioasic.h>
+ #include <asm/dec/ioasic_addrs.h>
+ #include <asm/dec/ioasic_ints.h>
+ #include <asm/dec/machtype.h>
++#include <asm/dec/tc.h>
+ 
+ #define DEC_SCSI_SREG 0
+ #define DEC_SCSI_DMAREG 0x40000
+ #define DEC_SCSI_SRAM 0x80000
+ #define DEC_SCSI_DIAG 0xC0000
+ 
+-/*
+- * Once upon a time the pmaz code used to be working but
+- * it hasn't been maintained for quite some time.
+- * It isn't working anymore but I'll leave here as a
+- * starting point. #define this an be prepared for tons
+- * of warnings and errors :)
+- */
++#include "scsi.h"
++#include <scsi/scsi_host.h>
++#include "NCR53C9x.h"
++
+ static int  dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
+ static void dma_drain(struct NCR_ESP *esp);
+ static int  dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd * sp);
+ static void dma_dump_state(struct NCR_ESP *esp);
+-static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
+-static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
++static void dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length);
++static void dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length);
+ static void dma_ints_off(struct NCR_ESP *esp);
+ static void dma_ints_on(struct NCR_ESP *esp);
+ static int  dma_irq_p(struct NCR_ESP *esp);
+ static int  dma_ports_p(struct NCR_ESP *esp);
+-static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
++static void dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write);
+ static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp);
+ static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp);
+ static void dma_advance_sg(Scsi_Cmnd * sp);
+ 
+ static void pmaz_dma_drain(struct NCR_ESP *esp);
+-static void pmaz_dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
+-static void pmaz_dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
++static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length);
++static void pmaz_dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length);
+ static void pmaz_dma_ints_off(struct NCR_ESP *esp);
+ static void pmaz_dma_ints_on(struct NCR_ESP *esp);
+-static void pmaz_dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
++static void pmaz_dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write);
+ static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp);
+ 
+ #define TC_ESP_RAM_SIZE 0x20000
+@@ -88,7 +83,7 @@ static void pmaz_dma_mmu_get_scsi_one(st
+ #define TC_ESP_DMAR_WRITE 0x80000000
+ #define TC_ESP_DMA_ADDR(x) ((unsigned)(x) & TC_ESP_DMAR_MASK)
+ 
+-__u32 esp_virt_buffer;
++u32 esp_virt_buffer;
+ int scsi_current_length;
+ 
+ volatile unsigned char cmd_buffer[16];
+@@ -98,14 +93,9 @@ volatile unsigned char pmaz_cmd_buffer[1
+ 				 * via PIO.
+ 				 */
+ 
+-volatile unsigned long *scsi_dma_ptr;
+-volatile unsigned long *scsi_next_ptr;
+-volatile unsigned long *scsi_scr;
+-volatile unsigned long *ioasic_ssr;
+-volatile unsigned long *scsi_sdr0;
+-volatile unsigned long *scsi_sdr1;
+-
+-static void scsi_dma_int(int, void *, struct pt_regs *);
++static irqreturn_t scsi_dma_merr_int(int, void *, struct pt_regs *);
++static irqreturn_t scsi_dma_err_int(int, void *, struct pt_regs *);
++static irqreturn_t scsi_dma_int(int, void *, struct pt_regs *);
+ 
+ int dec_esp_detect(Scsi_Host_Template * tpnt);
+ 
+@@ -152,17 +142,10 @@ int dec_esp_detect(Scsi_Host_Template * 
+ 	if (IOASIC) {
+ 		esp_dev = 0;
+ 		esp = esp_allocate(tpnt, (void *) esp_dev);
+-	
+-		scsi_dma_ptr = (unsigned long *) (system_base + IOCTL + SCSI_DMA_P);
+-		scsi_next_ptr = (unsigned long *) (system_base + IOCTL + SCSI_DMA_BP);
+-		scsi_scr = (unsigned long *) (system_base + IOCTL + SCSI_SCR);
+-		ioasic_ssr = (unsigned long *) (system_base + IOCTL + SSR);
+-		scsi_sdr0 = (unsigned long *) (system_base + IOCTL + SCSI_SDR0);
+-		scsi_sdr1 = (unsigned long *) (system_base + IOCTL + SCSI_SDR1);
+ 
+ 		/* Do command transfer with programmed I/O */
+ 		esp->do_pio_cmds = 1;
+-	
++
+ 		/* Required functions */
+ 		esp->dma_bytes_sent = &dma_bytes_sent;
+ 		esp->dma_can_transfer = &dma_can_transfer;
+@@ -185,7 +168,7 @@ int dec_esp_detect(Scsi_Host_Template * 
+ 		esp->dma_reset = 0;
+ 		esp->dma_led_off = 0;
+ 		esp->dma_led_on = 0;
+-		
++
+ 		/* virtual DMA functions */
+ 		esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one;
+ 		esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl;
+@@ -197,38 +180,42 @@ int dec_esp_detect(Scsi_Host_Template * 
+ 		/* SCSI chip speed */
+ 		esp->cfreq = 25000000;
+ 
+-		/*
+-		 * we don't give the address of DMA channel, but the number
+-		 * of DMA channel, so we can use the jazz DMA functions
+-		 *
+-		 */
+-		esp->dregs = JAZZ_SCSI_DMA;
+-	
++		esp->dregs = 0;
++
+ 		/* ESP register base */
+-		esp->eregs = (struct ESP_regs *) (system_base + SCSI);
+-	
++		esp->eregs = (struct ESP_regs *) (system_base + IOASIC_SCSI);
++
+ 		/* Set the command buffer */
+ 		esp->esp_command = (volatile unsigned char *) cmd_buffer;
+-	
++
+ 		/* get virtual dma address for command buffer */
+-		esp->esp_command_dvma = (__u32) KSEG1ADDR((volatile unsigned char *) cmd_buffer);
+-	
+-		esp->irq = SCSI_INT;
++		esp->esp_command_dvma = virt_to_phys(cmd_buffer);
++
++		esp->irq = dec_interrupt[DEC_IRQ_ASC];
+ 
+ 		esp->scsi_id = 7;
+-		
++
+ 		/* Check for differential SCSI-bus */
+ 		esp->diff = 0;
+ 
+ 		esp_initialize(esp);
+ 
+-		if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, 
+-				"NCR 53C94 SCSI", esp->ehost))
++		if (request_irq(esp->irq, esp_intr, SA_INTERRUPT,
++				"ncr53c94", esp->ehost))
+ 			goto err_dealloc;
+-		if (request_irq(SCSI_DMA_INT, scsi_dma_int, SA_INTERRUPT, 
+-				"JUNKIO SCSI DMA", esp->ehost))
++		if (request_irq(dec_interrupt[DEC_IRQ_ASC_MERR],
++				scsi_dma_merr_int, SA_INTERRUPT,
++				"ncr53c94 error", esp->ehost))
+ 			goto err_free_irq;
+- 			
++		if (request_irq(dec_interrupt[DEC_IRQ_ASC_ERR],
++				scsi_dma_err_int, SA_INTERRUPT,
++				"ncr53c94 overrun", esp->ehost))
++			goto err_free_irq_merr;
++		if (request_irq(dec_interrupt[DEC_IRQ_ASC_DMA],
++				scsi_dma_int, SA_INTERRUPT,
++				"ncr53c94 dma", esp->ehost))
++			goto err_free_irq_err;
++
+ 	}
+ 
+ 	if (TURBOCHANNEL) {
+@@ -241,7 +228,7 @@ int dec_esp_detect(Scsi_Host_Template * 
+ 			mem_start = get_tc_base_addr(slot);
+ 
+ 			/* Store base addr into esp struct */
+-			esp->slot = mem_start;
++			esp->slot = PHYSADDR(mem_start);
+ 
+ 			esp->dregs = 0;
+ 			esp->eregs = (struct ESP_regs *) (mem_start + DEC_SCSI_SREG);
+@@ -251,7 +238,7 @@ int dec_esp_detect(Scsi_Host_Template * 
+ 			esp->esp_command = (volatile unsigned char *) pmaz_cmd_buffer;
+ 
+ 			/* get virtual dma address for command buffer */
+-			esp->esp_command_dvma = (__u32) KSEG0ADDR((volatile unsigned char *) pmaz_cmd_buffer);
++			esp->esp_command_dvma = virt_to_phys(pmaz_cmd_buffer);
+ 
+ 			esp->cfreq = get_tc_speed();
+ 
+@@ -286,7 +273,7 @@ int dec_esp_detect(Scsi_Host_Template * 
+ 			esp->dma_mmu_release_scsi_sgl = 0;
+ 			esp->dma_advance_sg = 0;
+ 
+- 			if (request_irq(esp->irq, esp_intr, SA_INTERRUPT, 
++ 			if (request_irq(esp->irq, esp_intr, SA_INTERRUPT,
+  					 "PMAZ_AA", esp->ehost)) {
+  				esp_deallocate(esp);
+  				release_tc_card(slot);
+@@ -305,72 +292,85 @@ int dec_esp_detect(Scsi_Host_Template * 
+ 	}
+ 	return 0;
+ 
+- err_free_irq:
++err_free_irq_err:
++	free_irq(dec_interrupt[DEC_IRQ_ASC_ERR], scsi_dma_err_int);
++err_free_irq_merr:
++	free_irq(dec_interrupt[DEC_IRQ_ASC_MERR], scsi_dma_merr_int);
++err_free_irq:
+ 	free_irq(esp->irq, esp_intr);
+- err_dealloc:
++err_dealloc:
+ 	esp_deallocate(esp);
+ 	return 0;
+ }
+ 
+ /************************************************************* DMA Functions */
+-static void scsi_dma_int(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t scsi_dma_merr_int(int irq, void *dev_id, struct pt_regs *regs)
+ {
+-	extern volatile unsigned int *isr;
+-	unsigned int dummy;
++	printk("Got unexpected SCSI DMA Interrupt! < ");
++	printk("SCSI_DMA_MEMRDERR ");
++	printk(">\n");
+ 
+-	if (*isr & SCSI_PTR_LOADED) {
+-		/* next page */
+-		*scsi_next_ptr = ((*scsi_dma_ptr + PAGE_SIZE) & PAGE_MASK) << 3;
+-		*isr &= ~SCSI_PTR_LOADED;
+-	} else {
+-		if (*isr & SCSI_PAGOVRRUN)
+-			*isr &= ~SCSI_PAGOVRRUN;
+-		if (*isr & SCSI_DMA_MEMRDERR) {
+-			printk("Got unexpected SCSI DMA Interrupt! < ");
+-			printk("SCSI_DMA_MEMRDERR ");
+-		printk(">\n");
+-			*isr &= ~SCSI_DMA_MEMRDERR;
+-		}
+-	}
++	return IRQ_HANDLED;
++}
+ 
+-	/*
+-	 * This routine will only work on IOASIC machines
+-	 * so we can avoid an indirect function call here
+-	 * and flush the writeback buffer the fast way
+-	 */
+-	dummy = *isr;
+-	dummy = *isr;
++static irqreturn_t scsi_dma_err_int(int irq, void *dev_id, struct pt_regs *regs)
++{
++	/* empty */
++
++	return IRQ_HANDLED;
++}
++
++static irqreturn_t scsi_dma_int(int irq, void *dev_id, struct pt_regs *regs)
++{
++	u32 scsi_next_ptr;
++
++	scsi_next_ptr = ioasic_read(IO_REG_SCSI_DMA_P);
++
++	/* next page */
++	scsi_next_ptr = (((scsi_next_ptr >> 3) + PAGE_SIZE) & PAGE_MASK) << 3;
++	ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr);
++	fast_iob();
++
++	return IRQ_HANDLED;
+ }
+ 
+ static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
+ {
+-    return fifo_count;
++	return fifo_count;
+ }
+ 
+ static void dma_drain(struct NCR_ESP *esp)
+ {
+-	unsigned long nw = *scsi_scr;
+-	unsigned short *p = (unsigned short *)KSEG1ADDR((*scsi_dma_ptr) >> 3);
++	u32 nw, data0, data1, scsi_data_ptr;
++	u16 *p;
++
++	nw = ioasic_read(IO_REG_SCSI_SCR);
+ 
+-    /*
++	/*
+ 	 * Is there something in the dma buffers left?
+-     */
++	 */
+ 	if (nw) {
++		scsi_data_ptr = ioasic_read(IO_REG_SCSI_DMA_P) >> 3;
++		p = phys_to_virt(scsi_data_ptr);
+ 		switch (nw) {
+ 		case 1:
+-			*p = (unsigned short) *scsi_sdr0;
++			data0 = ioasic_read(IO_REG_SCSI_SDR0);
++			p[0] = data0 & 0xffff;
+ 			break;
+ 		case 2:
+-			*p++ = (unsigned short) (*scsi_sdr0);
+-			*p = (unsigned short) ((*scsi_sdr0) >> 16);
++			data0 = ioasic_read(IO_REG_SCSI_SDR0);
++			p[0] = data0 & 0xffff;
++			p[1] = (data0 >> 16) & 0xffff;
+ 			break;
+ 		case 3:
+-			*p++ = (unsigned short) (*scsi_sdr0);
+-			*p++ = (unsigned short) ((*scsi_sdr0) >> 16);
+-			*p = (unsigned short) (*scsi_sdr1);
++			data0 = ioasic_read(IO_REG_SCSI_SDR0);
++			data1 = ioasic_read(IO_REG_SCSI_SDR1);
++			p[0] = data0 & 0xffff;
++			p[1] = (data0 >> 16) & 0xffff;
++			p[2] = data1 & 0xffff;
+ 			break;
+ 		default:
+-			printk("Strange: %d words in dma buffer left\n", (int) nw);
++			printk("Strange: %d words in dma buffer left\n", nw);
+ 			break;
+ 		}
+ 	}
+@@ -383,153 +383,168 @@ static int dma_can_transfer(struct NCR_E
+ 
+ static void dma_dump_state(struct NCR_ESP *esp)
+ {
+-/*
+-    ESPLOG(("esp%d: dma -- enable <%08x> residue <%08x\n",
+-	    esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_resdiue((int)esp->dregs)));
+- */
+ }
+ 
+-static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
++static void dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length)
+ {
+-	extern volatile unsigned int *isr;
+-	unsigned int dummy;
++	u32 scsi_next_ptr, ioasic_ssr;
++	unsigned long flags;
+ 
+ 	if (vaddress & 3)
+-		panic("dec_efs.c: unable to handle partial word transfers, yet...");
++		panic("dec_esp.c: unable to handle partial word transfers, yet...");
+ 
+ 	dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress), length);
+ 
+-	*ioasic_ssr &= ~SCSI_DMA_EN;
+-	*scsi_scr = 0;
+-	*scsi_dma_ptr = vaddress << 3;
++	spin_lock_irqsave(&ioasic_ssr_lock, flags);
++
++	fast_mb();
++	ioasic_ssr = ioasic_read(IO_REG_SSR);
++
++	ioasic_ssr &= ~IO_SSR_SCSI_DMA_EN;
++	ioasic_write(IO_REG_SSR, ioasic_ssr);
++
++	fast_wmb();
++	ioasic_write(IO_REG_SCSI_SCR, 0);
++	ioasic_write(IO_REG_SCSI_DMA_P, vaddress << 3);
+ 
+ 	/* prepare for next page */
+-	*scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3;
+-	*ioasic_ssr |= (SCSI_DMA_DIR | SCSI_DMA_EN);
++	scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3;
++	ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr);
+ 
+-	/*
+-	 * see above
+-	 */
+-	dummy = *isr;
+-	dummy = *isr;
++	ioasic_ssr |= (IO_SSR_SCSI_DMA_DIR | IO_SSR_SCSI_DMA_EN);
++	fast_wmb();
++	ioasic_write(IO_REG_SSR, ioasic_ssr);
++
++	fast_iob();
++	spin_unlock_irqrestore(&ioasic_ssr_lock, flags);
+ }
+ 
+-static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
++static void dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length)
+ {
+-	extern volatile unsigned int *isr;
+-	unsigned int dummy;
++	u32 scsi_next_ptr, ioasic_ssr;
++	unsigned long flags;
+ 
+ 	if (vaddress & 3)
+-		panic("dec_efs.c: unable to handle partial word transfers, yet...");
++		panic("dec_esp.c: unable to handle partial word transfers, yet...");
+ 
+ 	dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress), length);
+ 
+-	*ioasic_ssr &= ~(SCSI_DMA_DIR | SCSI_DMA_EN);
+-	*scsi_scr = 0;
+-	*scsi_dma_ptr = vaddress << 3;
++	spin_lock_irqsave(&ioasic_ssr_lock, flags);
++
++	fast_mb();
++	ioasic_ssr = ioasic_read(IO_REG_SSR);
++
++	ioasic_ssr &= ~(IO_SSR_SCSI_DMA_DIR | IO_SSR_SCSI_DMA_EN);
++	ioasic_write(IO_REG_SSR, ioasic_ssr);
++
++	fast_wmb();
++	ioasic_write(IO_REG_SCSI_SCR, 0);
++	ioasic_write(IO_REG_SCSI_DMA_P, vaddress << 3);
+ 
+ 	/* prepare for next page */
+-	*scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3;
+-	*ioasic_ssr |= SCSI_DMA_EN;
++	scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3;
++	ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr);
+ 
+-	/*
+-	 * see above
+-	 */
+-	dummy = *isr;
+-	dummy = *isr;
++	ioasic_ssr |= IO_SSR_SCSI_DMA_EN;
++	fast_wmb();
++	ioasic_write(IO_REG_SSR, ioasic_ssr);
++
++	fast_iob();
++	spin_unlock_irqrestore(&ioasic_ssr_lock, flags);
+ }
+ 
+ static void dma_ints_off(struct NCR_ESP *esp)
+ {
+-	disable_irq(SCSI_DMA_INT);
++	disable_irq(dec_interrupt[DEC_IRQ_ASC_DMA]);
+ }
+ 
+ static void dma_ints_on(struct NCR_ESP *esp)
+ {
+-	enable_irq(SCSI_DMA_INT);
++	enable_irq(dec_interrupt[DEC_IRQ_ASC_DMA]);
+ }
+ 
+ static int dma_irq_p(struct NCR_ESP *esp)
+ {
+-    return (esp->eregs->esp_status & ESP_STAT_INTR);
++	return (esp->eregs->esp_status & ESP_STAT_INTR);
+ }
+ 
+ static int dma_ports_p(struct NCR_ESP *esp)
+ {
+-/*
+- * FIXME: what's this good for?
+- */
++	/*
++	 * FIXME: what's this good for?
++	 */
+ 	return 1;
+ }
+ 
+-static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
++static void dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write)
+ {
+-    /*
+-     * On the Sparc, DMA_ST_WRITE means "move data from device to memory"
+-     * so when (write) is true, it actually means READ!
+-     */
+-	if (write) {
+-	dma_init_read(esp, addr, count);
+-    } else {
+-	dma_init_write(esp, addr, count);
+-    }
++	/*
++	 * DMA_ST_WRITE means "move data from device to memory"
++	 * so when (write) is true, it actually means READ!
++	 */
++	if (write)
++		dma_init_read(esp, addr, count);
++	else
++		dma_init_write(esp, addr, count);
+ }
+ 
+-/*
+- * These aren't used yet
+- */
+ static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp)
+ {
+-	sp->SCp.ptr = (char *)PHYSADDR(sp->SCp.buffer);
++	sp->SCp.ptr = (char *)virt_to_phys(sp->request_buffer);
+ }
+ 
+ static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd * sp)
+ {
+-    int sz = sp->SCp.buffers_residual;
+-    struct mmu_sglist *sg = (struct mmu_sglist *) sp->SCp.buffer;
++	int sz = sp->SCp.buffers_residual;
++	struct scatterlist *sg = sp->SCp.buffer;
+ 
+-    while (sz >= 0) {
+-		sg[sz].dvma_addr = PHYSADDR(sg[sz].addr);
+-	sz--;
+-    }
+-	sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dvma_address);
++	while (sz >= 0) {
++		sg[sz].dma_address = page_to_phys(sg[sz].page) + sg[sz].offset;
++		sz--;
++	}
++	sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address);
+ }
+ 
+ static void dma_advance_sg(Scsi_Cmnd * sp)
+ {
+-	sp->SCp.ptr = (char *) ((unsigned long) sp->SCp.buffer->dvma_address);
++	sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address);
+ }
+ 
+ static void pmaz_dma_drain(struct NCR_ESP *esp)
+ {
+-	memcpy((void *) (KSEG0ADDR(esp_virt_buffer)),
+-		(void *) ( esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE),
++	memcpy(phys_to_virt(esp_virt_buffer),
++		(void *)KSEG1ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE),
+ 		scsi_current_length);
+ }
+ 
+-static void pmaz_dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length)
++static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length)
+ {
+-	volatile int *dmareg = (volatile int *) (esp->slot + DEC_SCSI_DMAREG);
++	volatile u32 *dmareg =
++		(volatile u32 *)KSEG1ADDR(esp->slot + DEC_SCSI_DMAREG);
+ 
+ 	if (length > ESP_TGT_DMA_SIZE)
+ 		length = ESP_TGT_DMA_SIZE;
+ 
+-	*dmareg = TC_ESP_DMA_ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE);
++	*dmareg = TC_ESP_DMA_ADDR(ESP_TGT_DMA_SIZE);
++
++	iob();
+ 
+ 	esp_virt_buffer = vaddress;
+ 	scsi_current_length = length;
+ }
+ 
+-static void pmaz_dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length)
++static void pmaz_dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length)
+ {
+-	volatile int *dmareg = (volatile int *) ( esp->slot + DEC_SCSI_DMAREG );
++	volatile u32 *dmareg =
++		(volatile u32 *)KSEG1ADDR(esp->slot + DEC_SCSI_DMAREG);
+ 
+-	memcpy((void *)(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE),
+-	       (void *)KSEG0ADDR(vaddress), length);
++	memcpy((void *)KSEG1ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE),
++	       phys_to_virt(vaddress), length);
+ 
+-	*dmareg = TC_ESP_DMAR_WRITE | 
+-		TC_ESP_DMA_ADDR(esp->slot + DEC_SCSI_SRAM + ESP_TGT_DMA_SIZE);
++	wmb();
++	*dmareg = TC_ESP_DMAR_WRITE | TC_ESP_DMA_ADDR(ESP_TGT_DMA_SIZE);
+ 
++	iob();
+ }
+ 
+ static void pmaz_dma_ints_off(struct NCR_ESP *esp)
+@@ -540,20 +555,19 @@ static void pmaz_dma_ints_on(struct NCR_
+ {
+ }
+ 
+-static void pmaz_dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
++static void pmaz_dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write)
+ {
+ 	/*
+-	 * On the Sparc, DMA_ST_WRITE means "move data from device to memory"
++	 * DMA_ST_WRITE means "move data from device to memory"
+ 	 * so when (write) is true, it actually means READ!
+ 	 */
+-	if (write) {
++	if (write)
+ 		pmaz_dma_init_read(esp, addr, count);
+-	} else {
++	else
+ 		pmaz_dma_init_write(esp, addr, count);
+-	}
+ }
+ 
+ static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd * sp)
+ {
+-	sp->SCp.ptr = (char *)KSEG0ADDR((sp->request_buffer));
++	sp->SCp.ptr = (char *)virt_to_phys(sp->request_buffer);
+ }
+diff -urpNX dontdiff linux-2.6.10/drivers/scsi/jazz_esp.c linux-2.6.10-mips/drivers/scsi/jazz_esp.c
+--- linux-2.6.10/drivers/scsi/jazz_esp.c	2004-12-24 22:33:51.000000000 +0100
++++ linux-2.6.10-mips/drivers/scsi/jazz_esp.c	2004-10-27 02:14:48.000000000 +0200
+@@ -6,6 +6,7 @@
+  * jazz_esp is based on David S. Miller's ESP driver and cyber_esp
+  */
+ 
++#include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/delay.h>
+ #include <linux/types.h>
+@@ -51,6 +52,40 @@ static volatile unsigned char cmd_buffer
+ 				 * via PIO.
+ 				 */
+ 
++int jazz_esp_detect(Scsi_Host_Template *tpnt);
++static int jazz_esp_release(struct Scsi_Host *shost)
++{
++	if (shost->irq)
++		free_irq(shost->irq, NULL);
++	if (shost->dma_channel != 0xff)
++		free_dma(shost->dma_channel);
++	if (shost->io_port && shost->n_io_port)
++		release_region(shost->io_port, shost->n_io_port);
++	scsi_unregister(shost);
++	return 0;
++}
++
++static Scsi_Host_Template driver_template = {
++	.proc_name		= "jazz_esp",
++	.proc_info		= &esp_proc_info,
++	.name			= "ESP 100/100a/200",
++	.detect			= jazz_esp_detect,
++	.slave_alloc		= esp_slave_alloc,
++	.slave_destroy		= esp_slave_destroy,
++	.release		= jazz_esp_release,
++	.info			= esp_info,
++	.queuecommand		= esp_queue,
++	.eh_abort_handler	= esp_abort,
++	.eh_bus_reset_handler	= esp_reset,
++	.can_queue		= 7,
++	.this_id		= 7,
++	.sg_tablesize		= SG_ALL,
++	.cmd_per_lun		= 1,
++	.use_clustering		= DISABLE_CLUSTERING,
++};
++
++#include "scsi_module.c"
++
+ /***************************************************************** Detection */
+ int jazz_esp_detect(Scsi_Host_Template *tpnt)
+ {
+@@ -115,7 +150,7 @@ int jazz_esp_detect(Scsi_Host_Template *
+ 	esp->esp_command = (volatile unsigned char *)cmd_buffer;
+ 	
+ 	/* get virtual dma address for command buffer */
+-	esp->esp_command_dvma = vdma_alloc(PHYSADDR(cmd_buffer), sizeof (cmd_buffer));
++	esp->esp_command_dvma = vdma_alloc(CPHYSADDR(cmd_buffer), sizeof (cmd_buffer));
+ 	
+ 	esp->irq = JAZZ_SCSI_IRQ;
+ 	request_irq(JAZZ_SCSI_IRQ, esp_intr, SA_INTERRUPT, "JAZZ SCSI",
+@@ -139,18 +174,6 @@ int jazz_esp_detect(Scsi_Host_Template *
+     return 0;
+ }
+ 
+-static int jazz_esp_release(struct Scsi_Host *shost)
+-{
+-	if (shost->irq)
+-		free_irq(shost->irq, NULL);
+-	if (shost->dma_channel != 0xff)
+-		free_dma(shost->dma_channel);
+-	if (shost->io_port && shost->n_io_port)
+-		release_region(shost->io_port, shost->n_io_port);
+-	scsi_unregister(shost);
+-	return 0;
+-}
+-
+ /************************************************************* DMA Functions */
+ static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
+ {
+@@ -232,20 +255,20 @@ static void dma_setup(struct NCR_ESP *es
+ 
+ static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp)
+ {
+-    sp->SCp.have_data_in = vdma_alloc(PHYSADDR(sp->SCp.buffer), sp->SCp.this_residual);
++    sp->SCp.have_data_in = vdma_alloc(CPHYSADDR(sp->SCp.buffer), sp->SCp.this_residual);
+     sp->SCp.ptr = (char *)((unsigned long)sp->SCp.have_data_in);
+ }
+ 
+ static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
+ {
+     int sz = sp->SCp.buffers_residual;
+-    struct mmu_sglist *sg = (struct mmu_sglist *) sp->SCp.buffer;
++    struct scatterlist *sg = (struct scatterlist *) sp->SCp.buffer;
+     
+     while (sz >= 0) {
+-	sg[sz].dvma_addr = vdma_alloc(PHYSADDR(sg[sz].addr), sg[sz].len);
++	sg[sz].dma_address = vdma_alloc(CPHYSADDR(page_address(sg[sz].page) + sg[sz].offset), sg[sz].length);
+ 	sz--;
+     }
+-    sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dvma_address);
++    sp->SCp.ptr=(char *)(sp->SCp.buffer->dma_address);
+ }    
+ 
+ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp)
+@@ -256,17 +279,17 @@ static void dma_mmu_release_scsi_one (st
+ static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
+ {
+     int sz = sp->use_sg - 1;
+-    struct mmu_sglist *sg = (struct mmu_sglist *)sp->buffer;
++    struct scatterlist *sg = (struct scatterlist *)sp->buffer;
+ 			
+     while(sz >= 0) {
+-	vdma_free(sg[sz].dvma_addr);
++	vdma_free(sg[sz].dma_address);
+ 	sz--;
+     }
+ }
+ 
+ static void dma_advance_sg (Scsi_Cmnd *sp)
+ {
+-    sp->SCp.ptr = (char *)((unsigned long)sp->SCp.buffer->dvma_address);
++    sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address);
+ }
+ 
+ #define JAZZ_HDC_LED   0xe000d100 /* FIXME, find correct address */
+@@ -285,22 +308,3 @@ static void dma_led_on(struct NCR_ESP *e
+ #endif    
+ }
+ 
+-static Scsi_Host_Template driver_template = {
+-	.proc_name		= "jazz_esp",
+-	.proc_info		= &esp_proc_info,
+-	.name			= "ESP 100/100a/200",
+-	.detect			= jazz_esp_detect,
+-	.slave_alloc		= esp_slave_alloc,
+-	.slave_destroy		= esp_slave_destroy,
+-	.release		= jazz_esp_release,
+-	.info			= esp_info,
+-	.queuecommand		= esp_queue,
+-	.eh_abort_handler	= esp_abort,
+-	.eh_bus_reset_handler	= esp_reset,
+-	.can_queue		= 7,
+-	.this_id		= 7,
+-	.sg_tablesize		= SG_ALL,
+-	.cmd_per_lun		= 1,
+-	.use_clustering		= DISABLE_CLUSTERING,
+-};
+-
+diff -urpNX dontdiff linux-2.6.10/drivers/scsi/sym53c8xx_defs.h linux-2.6.10-mips/drivers/scsi/sym53c8xx_defs.h
+--- linux-2.6.10/drivers/scsi/sym53c8xx_defs.h	2004-12-24 22:35:59.000000000 +0100
++++ linux-2.6.10-mips/drivers/scsi/sym53c8xx_defs.h	2004-12-04 20:57:33.000000000 +0100
+@@ -52,6 +52,10 @@
+ **    Copyright (C) 1997 Richard Waltham <dormouse at farsrobt.demon.co.uk>
+ **
+ **  Added support for MIPS big endian systems.
++**  Carsten Langgaard, carstenl at mips.com
++**  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
++**
++**  Added support for MIPS big endian systems.
+ **    Carsten Langgaard, carstenl at mips.com
+ **    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ **
+@@ -317,6 +321,16 @@
+ #define	readl_raw(a)	__raw_readl((unsigned long)(a))
+ #define	writew_raw	__raw_writew
+ #define	writel_raw(v,a)	__raw_writel(v,(unsigned long)(a))
++#else /* Other big-endian */
++#elif defined(__mips__)
++#define readw_l2b	readw
++#define readl_l2b	readl
++#define writew_b2l	writew
++#define writel_b2l	writel
++#define inw_l2b 	inw
++#define inl_l2b 	inl
++#define outw_b2l	outw
++#define outl_b2l	outl
+ #else	/* Other big-endian */
+ #define	readw_l2b	readw
+ #define	readl_l2b	readl
+diff -urpNX dontdiff linux-2.6.10/drivers/serial/au1x00_uart.c linux-2.6.10-mips/drivers/serial/au1x00_uart.c
+--- linux-2.6.10/drivers/serial/au1x00_uart.c	2004-12-24 22:33:59.000000000 +0100
++++ linux-2.6.10-mips/drivers/serial/au1x00_uart.c	2004-11-19 01:14:46.000000000 +0100
+@@ -67,30 +67,7 @@
+ #define is_real_interrupt(irq)	((irq) != 0)
+ 
+ static struct old_serial_port old_serial_port[] = {
+-	{	.baud_base = 0,
+-		.iomem_base = (u8 *)UART0_ADDR,
+-		.irq = AU1000_UART0_INT,
+-		.flags = STD_COM_FLAGS,
+-		.iomem_reg_shift = 2,
+-	}, {
+-		.baud_base = 0,
+-		.iomem_base = (u8 *)UART1_ADDR,
+-		.irq = AU1000_UART1_INT,
+-		.flags = STD_COM_FLAGS,
+-		.iomem_reg_shift = 2
+-	}, {
+-		.baud_base = 0,
+-		.iomem_base = (u8 *)UART2_ADDR,
+-		.irq = AU1000_UART2_INT,
+-		.flags = STD_COM_FLAGS,
+-		.iomem_reg_shift = 2
+-	}, {
+-		.baud_base = 0,
+-		.iomem_base = (u8 *)UART3_ADDR,
+-		.irq = AU1000_UART3_INT,
+-		.flags = STD_COM_FLAGS,
+-		.iomem_reg_shift = 2
+-	}
++	SERIAL_PORT_DFNS
+ };
+ 
+ #define UART_NR	ARRAY_SIZE(old_serial_port)
+@@ -801,7 +778,6 @@ serial8250_set_termios(struct uart_port 
+ 	 */
+ 	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
+ 	quot = serial8250_get_divisor(port, baud);
+-	quot = 0x35; /* FIXME */
+ 
+ 	/*
+ 	 * Work around a bug in the Oxford Semiconductor 952 rev B
+@@ -1069,7 +1045,7 @@ static void __init serial8250_isa_init_p
+ 	     i++, up++) {
+ 		up->port.iobase   = old_serial_port[i].port;
+ 		up->port.irq      = old_serial_port[i].irq;
+-		up->port.uartclk  = get_au1x00_uart_baud_base();
++		up->port.uartclk  = get_au1x00_uart_baud_base() * 16;
+ 		up->port.flags    = old_serial_port[i].flags;
+ 		up->port.hub6     = old_serial_port[i].hub6;
+ 		up->port.membase  = old_serial_port[i].iomem_base;
+diff -urpNX dontdiff linux-2.6.10/drivers/serial/ip22zilog.c linux-2.6.10-mips/drivers/serial/ip22zilog.c
+--- linux-2.6.10/drivers/serial/ip22zilog.c	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/serial/ip22zilog.c	2004-11-20 13:54:30.000000000 +0100
+@@ -47,8 +47,6 @@
+ 
+ #include "ip22zilog.h"
+ 
+-int ip22serial_current_minor = 64;
+-
+ void ip22_do_break(void);
+ 
+ /*
+@@ -59,10 +57,10 @@ void ip22_do_break(void);
+ #define ZSDELAY_LONG()		udelay(20)
+ #define ZS_WSYNC(channel)	do { } while (0)
+ 
+-#define NUM_IP22ZILOG	1
+-#define NUM_CHANNELS	(NUM_IP22ZILOG * 2)
++#define NUM_IP22ZILOG		1
++#define NUM_CHANNELS		(NUM_IP22ZILOG * 2)
+ 
+-#define ZS_CLOCK		4915200 /* Zilog input clock rate. */
++#define ZS_CLOCK		3672000	/* Zilog input clock rate. */
+ #define ZS_CLOCK_DIVISOR	16      /* Divisor this driver uses. */
+ 
+ /*
+@@ -86,7 +84,7 @@ struct uart_ip22zilog_port {
+ #define IP22ZILOG_FLAG_TX_STOPPED	0x00000080
+ #define IP22ZILOG_FLAG_TX_ACTIVE	0x00000100
+ 
+-	unsigned int cflag;
++	unsigned int			cflag;
+ 
+ 	/* L1-A keyboard break state.  */
+ 	int				kbd_id;
+@@ -642,36 +640,28 @@ static void ip22zilog_start_tx(struct ua
+ 	}
+ }
+ 
+-/* The port lock is not held.  */
++/* The port lock is held and interrupts are disabled.  */
+ static void ip22zilog_stop_rx(struct uart_port *port)
+ {
+ 	struct uart_ip22zilog_port *up = UART_ZILOG(port);
+ 	struct zilog_channel *channel;
+-	unsigned long flags;
+ 
+ 	if (ZS_IS_CONS(up))
+ 		return;
+ 
+-	spin_lock_irqsave(&port->lock, flags);
+-
+ 	channel = ZILOG_CHANNEL_FROM_PORT(port);
+ 
+ 	/* Disable all RX interrupts.  */
+ 	up->curregs[R1] &= ~RxINT_MASK;
+ 	ip22zilog_maybe_update_regs(up, channel);
+-
+-	spin_unlock_irqrestore(&port->lock, flags);
+ }
+ 
+-/* The port lock is not held.  */
++/* The port lock is held.  */
+ static void ip22zilog_enable_ms(struct uart_port *port)
+ {
+ 	struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port;
+ 	struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
+ 	unsigned char new_reg;
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&port->lock, flags);
+ 
+ 	new_reg = up->curregs[R15] | (DCDIE | SYNCIE | CTSIE);
+ 	if (new_reg != up->curregs[R15]) {
+@@ -680,8 +670,6 @@ static void ip22zilog_enable_ms(struct u
+ 		/* NOTE: Not subject to 'transmitter active' rule.  */ 
+ 		write_zsreg(channel, R15, up->curregs[R15]);
+ 	}
+-
+-	spin_unlock_irqrestore(&port->lock, flags);
+ }
+ 
+ /* The port lock is not held.  */
+@@ -807,7 +795,7 @@ ip22zilog_convert_to_zs(struct uart_ip22
+ 	up->curregs[R4] |= X16CLK;
+ 	up->curregs[R12] = brg & 0xff;
+ 	up->curregs[R13] = (brg >> 8) & 0xff;
+-	up->curregs[R14] = BRSRC | BRENAB;
++	up->curregs[R14] = BRENAB;
+ 
+ 	/* Character size, stop bits, and parity. */
+ 	up->curregs[3] &= ~RxN_MASK;
+@@ -950,13 +938,6 @@ static struct zilog_layout **ip22zilog_c
+ static struct uart_ip22zilog_port *ip22zilog_irq_chain;
+ static int zilog_irq = -1;
+ 
+-static struct uart_driver ip22zilog_reg = {
+-	.owner		=	THIS_MODULE,
+-	.driver_name	=	"ttyS",
+-	.devfs_name	=	"tty/",
+-	.major		=	TTY_MAJOR,
+-};
+-
+ static void * __init alloc_one_table(unsigned long size)
+ {
+ 	void *ret;
+@@ -990,7 +971,7 @@ static struct zilog_layout * __init get_
+ 	}
+ 
+ 	/* Not probe-able, hard code it. */
+-	base = (unsigned long) &sgioc->serport;
++	base = (unsigned long) &sgioc->uart;
+ 
+ 	zilog_irq = SGI_SERIAL_IRQ;
+ 	request_mem_region(base, 8, "IP22-Zilog");
+@@ -1047,9 +1028,6 @@ ip22serial_console_termios(struct consol
+ 	int parity = 'n';
+ 	int flow = 'n';
+ 
+-	if (!serial_console)
+-		return;
+-
+ 	if (options)
+ 		uart_parse_options(options, &baud, &parity, &bits, &flow);
+ 
+@@ -1077,8 +1055,7 @@ static int __init ip22zilog_console_setu
+ 	unsigned long flags;
+ 	int baud, brg;
+ 
+-	printk("Console: ttyS%d (IP22-Zilog)\n",
+-	       (ip22zilog_reg.minor - 64) + con->index);
++	printk("Console: ttyS%d (IP22-Zilog)\n", con->index);
+ 
+ 	/* Get firmware console settings.  */
+ 	ip22serial_console_termios(con, options);
+@@ -1112,6 +1089,8 @@ static int __init ip22zilog_console_setu
+ 	return 0;
+ }
+ 
++static struct uart_driver ip22zilog_reg;
++
+ static struct console ip22zilog_console = {
+ 	.name	=	"ttyS",
+ 	.write	=	ip22zilog_console_write,
+@@ -1121,32 +1100,20 @@ static struct console ip22zilog_console 
+ 	.index	=	-1,
+ 	.data	=	&ip22zilog_reg,
+ };
+-#define IP22ZILOG_CONSOLE	(&ip22zilog_console)
+-
+-static int __init ip22zilog_console_init(void)
+-{
+-	int i;
+-
+-	if (con_is_present())
+-		return 0;
+-
+-	for (i = 0; i < NUM_CHANNELS; i++) {
+-		int this_minor = ip22zilog_reg.minor + i;
++#endif /* CONFIG_SERIAL_IP22_ZILOG_CONSOLE */
+ 
+-		if ((this_minor - 64) == (serial_console - 1))
+-			break;
+-	}
+-	if (i == NUM_CHANNELS)
+-		return 0;
+-
+-	ip22zilog_console.index = i;
+-	register_console(&ip22zilog_console);
+-	return 0;
+-}
+-#else /* CONFIG_SERIAL_IP22_ZILOG_CONSOLE */
+-#define IP22ZILOG_CONSOLE		(NULL)
+-#define ip22zilog_console_init()	do { } while (0)
++static struct uart_driver ip22zilog_reg = {
++	.owner		= THIS_MODULE,
++	.driver_name	= "serial",
++	.devfs_name	= "tts/",
++	.dev_name	= "ttyS",
++	.major		= TTY_MAJOR,
++	.minor		= 64,
++	.nr		= NUM_CHANNELS,
++#ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE
++	.cons		= &ip22zilog_console,
+ #endif
++};
+ 
+ static void __init ip22zilog_prepare(void)
+ {
+@@ -1160,17 +1127,24 @@ static void __init ip22zilog_prepare(voi
+ 	for (channel = 0; channel < NUM_CHANNELS; channel++)
+ 		spin_lock_init(&ip22zilog_port_table[channel].port.lock);
+ 
+-	ip22zilog_irq_chain = up = &ip22zilog_port_table[0];
+-	for (channel = 0; channel < NUM_CHANNELS - 1; channel++)
+-		up[channel].next = &up[channel + 1];
++	ip22zilog_irq_chain = &ip22zilog_port_table[NUM_CHANNELS - 1];
++        up = &ip22zilog_port_table[0];
++	for (channel = NUM_CHANNELS - 1 ; channel > 0; channel--)
++		up[channel].next = &up[channel - 1];
+ 	up[channel].next = NULL;
+ 
+ 	for (chip = 0; chip < NUM_IP22ZILOG; chip++) {
+ 		if (!ip22zilog_chip_regs[chip]) {
+ 			ip22zilog_chip_regs[chip] = rp = get_zs(chip);
+ 
+-			up[(chip * 2) + 0].port.membase = (char *) &rp->channelA;
+-			up[(chip * 2) + 1].port.membase = (char *) &rp->channelB;
++			up[(chip * 2) + 0].port.membase = (char *) &rp->channelB;
++			up[(chip * 2) + 1].port.membase = (char *) &rp->channelA;
++
++			/* In theory mapbase is the physical address ...  */
++			up[(chip * 2) + 0].port.mapbase =
++				(unsigned long) ioremap((unsigned long) &rp->channelB, 8);
++			up[(chip * 2) + 1].port.mapbase =
++				(unsigned long) ioremap((unsigned long) &rp->channelA, 8);
+ 		}
+ 
+ 		/* Channel A */
+@@ -1182,7 +1156,7 @@ static void __init ip22zilog_prepare(voi
+ 		up[(chip * 2) + 0].port.type = PORT_IP22ZILOG;
+ 		up[(chip * 2) + 0].port.flags = 0;
+ 		up[(chip * 2) + 0].port.line = (chip * 2) + 0;
+-		up[(chip * 2) + 0].flags |= IP22ZILOG_FLAG_IS_CHANNEL_A;
++		up[(chip * 2) + 0].flags = 0;
+ 
+ 		/* Channel B */
+ 		up[(chip * 2) + 1].port.iotype = UPIO_MEM;
+@@ -1191,9 +1165,9 @@ static void __init ip22zilog_prepare(voi
+ 		up[(chip * 2) + 1].port.fifosize = 1;
+ 		up[(chip * 2) + 1].port.ops = &ip22zilog_pops;
+ 		up[(chip * 2) + 1].port.type = PORT_IP22ZILOG;
+-		up[(chip * 2) + 1].port.flags = 0;
++		up[(chip * 2) + 1].port.flags |= IP22ZILOG_FLAG_IS_CHANNEL_A;
+ 		up[(chip * 2) + 1].port.line = (chip * 2) + 1;
+-		up[(chip * 2) + 1].flags |= 0;
++		up[(chip * 2) + 1].flags = 0;
+ 	}
+ }
+ 
+@@ -1228,8 +1202,10 @@ static void __init ip22zilog_init_hw(voi
+ 		brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
+ 		up->curregs[R12] = (brg & 0xff);
+ 		up->curregs[R13] = (brg >> 8) & 0xff;
+-		up->curregs[R14] = BRSRC | BRENAB;
++		up->curregs[R14] = BRENAB;
+ 		__load_zsregs(channel, up->curregs);
++	        /* set master interrupt enable */
++	        write_zsreg(channel, R9, up->curregs[R9]);
+ 
+ 		spin_unlock_irqrestore(&up->port.lock, flags);
+ 	}
+@@ -1250,15 +1226,6 @@ static int __init ip22zilog_ports_init(v
+ 
+ 	ip22zilog_init_hw();
+ 
+-	/* We can only init this once we have probed the Zilogs
+-	 * in the system.
+-	 */
+-	ip22zilog_reg.nr = NUM_CHANNELS;
+-	ip22zilog_reg.cons = IP22ZILOG_CONSOLE;
+-
+-	ip22zilog_reg.minor = ip22serial_current_minor;
+-	ip22serial_current_minor += NUM_CHANNELS;
+-
+ 	ret = uart_register_driver(&ip22zilog_reg);
+ 	if (ret == 0) {
+ 		int i;
+@@ -1276,11 +1243,8 @@ static int __init ip22zilog_ports_init(v
+ static int __init ip22zilog_init(void)
+ {
+ 	/* IP22 Zilog setup is hard coded, no probing to do.  */
+-
+ 	ip22zilog_alloc_tables();
+-
+ 	ip22zilog_ports_init();
+-	ip22zilog_console_init();
+ 
+ 	return 0;
+ }
+diff -urpNX dontdiff linux-2.6.10/drivers/tc/lk201.c linux-2.6.10-mips/drivers/tc/lk201.c
+--- linux-2.6.10/drivers/tc/lk201.c	2004-12-24 22:35:40.000000000 +0100
++++ linux-2.6.10-mips/drivers/tc/lk201.c	2004-09-21 13:11:10.000000000 +0200
+@@ -4,20 +4,44 @@
+  * License.  See the file "COPYING" in the main directory of this archive
+  * for more details.
+  *
++ * Copyright (C) 1999-2002 Harald Koerfgen <hkoerfg at web.de>
++ * Copyright (C) 2001, 2002, 2003, 2004  Maciej W. Rozycki
+  */
++
++#include <linux/config.h>
++
+ #include <linux/errno.h>
++#include <linux/sched.h>
+ #include <linux/tty.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/delay.h>
+ #include <linux/kbd_ll.h>
+-#include <asm/wbflush.h>
++#include <linux/kbd_kern.h>
++#include <linux/vt_kern.h>
++
++#include <asm/keyboard.h>
+ #include <asm/dec/tc.h>
+ #include <asm/dec/machtype.h>
++#include <asm/dec/serial.h>
+ 
+-#include "zs.h"
+ #include "lk201.h"
+ 
++/*
++ * Only handle DECstations that have an LK201 interface.
++ * Maxine uses LK501 at the Access.Bus and various DECsystems
++ * have no keyboard interface at all.
++ */
++#define LK_IFACE	(mips_machtype == MACH_DS23100    || \
++			 mips_machtype == MACH_DS5000_200 || \
++			 mips_machtype == MACH_DS5000_1XX || \
++			 mips_machtype == MACH_DS5000_2X0)
++/*
++ * These use the Z8530 SCC.  Others use the DZ11.
++ */
++#define LK_IFACE_ZS	(mips_machtype == MACH_DS5000_1XX || \
++			 mips_machtype == MACH_DS5000_2X0)
++
+ /* Simple translation table for the SysRq keys */
+ 
+ #ifdef CONFIG_MAGIC_SYSRQ
+@@ -27,25 +51,29 @@
+  */
+ unsigned char lk201_sysrq_xlate[128];
+ unsigned char *kbd_sysrq_xlate = lk201_sysrq_xlate;
++
++unsigned char kbd_sysrq_key = -1;
+ #endif
+ 
+ #define KEYB_LINE	3
+ 
+-static int __init lk201_init(struct dec_serial *);
+-static void __init lk201_info(struct dec_serial *);
+-static void lk201_kbd_rx_char(unsigned char, unsigned char);
+-
+-struct zs_hook lk201_kbdhook = {
+-	.init_channel   = lk201_init,
+-	.init_info      = lk201_info,
+-	.cflags         = B4800 | CS8 | CSTOPB | CLOCAL
++static int __init lk201_init(void *);
++static void __init lk201_info(void *);
++static void lk201_rx_char(unsigned char, unsigned char);
++
++static struct dec_serial_hook lk201_hook = {
++	.init_channel	= lk201_init,
++	.init_info	= lk201_info,
++	.rx_char	= NULL,
++	.poll_rx_char	= NULL,
++	.poll_tx_char	= NULL,
++	.cflags		= B4800 | CS8 | CSTOPB | CLOCAL,
+ };
+ 
+ /*
+  * This is used during keyboard initialisation
+  */
+ static unsigned char lk201_reset_string[] = {
+-	LK_CMD_LEDS_ON, LK_PARAM_LED_MASK(0xf),	/* show we are resetting */
+ 	LK_CMD_SET_DEFAULTS,
+ 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 1),
+ 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 2),
+@@ -61,28 +89,199 @@ static unsigned char lk201_reset_string[
+ 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 12),
+ 	LK_CMD_MODE(LK_MODE_DOWN, 13),
+ 	LK_CMD_MODE(LK_MODE_RPT_DOWN, 14),
+-	LK_CMD_ENB_RPT,
+ 	LK_CMD_DIS_KEYCLK,
+-	LK_CMD_RESUME,
+ 	LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4),
+-	LK_CMD_LEDS_OFF, LK_PARAM_LED_MASK(0xf)
+ };
+ 
+-static int __init lk201_reset(struct dec_serial *info)
++static void *lk201_handle;
++
++static int lk201_send(unsigned char ch)
++{
++	if (lk201_hook.poll_tx_char(lk201_handle, ch)) {
++		printk(KERN_ERR "lk201: transmit timeout\n");
++		return -EIO;
++	}
++	return 0;
++}
++
++static inline int lk201_get_id(void)
++{
++	return lk201_send(LK_CMD_REQ_ID);
++}
++
++static int lk201_reset(void)
++{
++	int i, r;
++
++	for (i = 0; i < sizeof(lk201_reset_string); i++) {
++		r = lk201_send(lk201_reset_string[i]);
++		if (r < 0)
++			return r;
++	}
++	return 0;
++}
++
++static void lk201_report(unsigned char id[6])
++{
++	char *report = "lk201: keyboard attached, ";
++
++	switch (id[2]) {
++	case LK_STAT_PWRUP_OK:
++		printk(KERN_INFO "%sself-test OK\n", report);
++		break;
++	case LK_STAT_PWRUP_KDOWN:
++		/* The keyboard will resend the power-up ID
++		   after all keys are released, so we don't
++		   bother handling the error specially.  Still
++		   there may be a short-circuit inside.
++		 */
++		printk(KERN_ERR "%skey down (stuck?), code: 0x%02x\n",
++		       report, id[3]);
++		break;
++	case LK_STAT_PWRUP_ERROR:
++		printk(KERN_ERR "%sself-test failure\n", report);
++		break;
++	default:
++		printk(KERN_ERR "%sunknown error: 0x%02x\n",
++		       report, id[2]);
++	}
++}
++
++static void lk201_id(unsigned char id[6])
++{
++	/*
++	 * Report whether there is an LK201 or an LK401
++	 * The LK401 has ALT keys...
++	 */
++	switch (id[4]) {
++	case 1:
++		printk(KERN_INFO "lk201: LK201 detected\n");
++		break;
++	case 2:
++		printk(KERN_INFO "lk201: LK401 detected\n");
++		break;
++	case 3:
++		printk(KERN_INFO "lk201: LK443 detected\n");
++		break;
++	case 4:
++		printk(KERN_INFO "lk201: LK421 detected\n");
++		break;
++	default:
++		printk(KERN_WARNING
++		       "lk201: unknown keyboard detected, ID %d\n", id[4]);
++		printk(KERN_WARNING "lk201: ... please report to "
++		       "<linux-mips at linux-mips.org>\n");
++	}
++}
++
++#define DEFAULT_KEYB_REP_DELAY	(250/5)	/* [5ms] */
++#define DEFAULT_KEYB_REP_RATE	30	/* [cps] */
++
++static struct kbd_repeat kbdrate = {
++	DEFAULT_KEYB_REP_DELAY,
++	DEFAULT_KEYB_REP_RATE
++};
++
++static void parse_kbd_rate(struct kbd_repeat *r)
+ {
++	if (r->delay <= 0)
++		r->delay = kbdrate.delay;
++	if (r->rate <= 0)
++		r->rate = kbdrate.rate;
++
++	if (r->delay < 5)
++		r->delay = 5;
++	if (r->delay > 630)
++		r->delay = 630;
++	if (r->rate < 12)
++		r->rate = 12;
++	if (r->rate > 127)
++		r->rate = 127;
++	if (r->rate == 125)
++		r->rate = 124;
++}
++
++static int write_kbd_rate(struct kbd_repeat *rep)
++{
++	int delay, rate;
+ 	int i;
+ 
+-	for (i = 0; i < sizeof(lk201_reset_string); i++)
+-		if (info->hook->poll_tx_char(info, lk201_reset_string[i])) {
+-			printk("%s transmit timeout\n", __FUNCTION__);
+-			return -EIO;
+-		}
++	delay = rep->delay / 5;
++	rate = rep->rate;
++	for (i = 0; i < 4; i++) {
++		if (lk201_hook.poll_tx_char(lk201_handle,
++					    LK_CMD_RPT_RATE(i)))
++			return 1;
++		if (lk201_hook.poll_tx_char(lk201_handle,
++					    LK_PARAM_DELAY(delay)))
++			return 1;
++		if (lk201_hook.poll_tx_char(lk201_handle,
++					    LK_PARAM_RATE(rate)))
++			return 1;
++	}
+ 	return 0;
+ }
+ 
++static int lk201_kbd_rate(struct kbd_repeat *rep)
++{
++	if (rep == NULL)
++		return -EINVAL;
++
++	parse_kbd_rate(rep);
++
++	if (write_kbd_rate(rep)) {
++		memcpy(rep, &kbdrate, sizeof(struct kbd_repeat));
++		return -EIO;
++	}
++
++	memcpy(&kbdrate, rep, sizeof(struct kbd_repeat));
++
++	return 0;
++}
++
++static void lk201_kd_mksound(unsigned int hz, unsigned int ticks)
++{
++	if (!ticks)
++		return;
++
++	/*
++	 * Can't set frequency and we "approximate"
++	 * duration by volume. ;-)
++	 */
++	ticks /= HZ / 32;
++	if (ticks > 7)
++		ticks = 7;
++	ticks = 7 - ticks;
++
++	if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_ENB_BELL))
++		return;
++	if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_VOLUME(ticks)))
++		return;
++	if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_BELL))
++		return;
++}
++
+ void kbd_leds(unsigned char leds)
+ {
+-	return;
++	unsigned char l = 0;
++
++	if (!lk201_handle)		/* FIXME */
++		return;
++
++	/* FIXME -- Only Hold and Lock LEDs for now. --macro */
++	if (leds & LED_SCR)
++		l |= LK_LED_HOLD;
++	if (leds & LED_CAP)
++		l |= LK_LED_LOCK;
++
++	if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_LEDS_ON))
++		return;
++	if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_LED_MASK(l)))
++		return;
++	if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_LEDS_OFF))
++		return;
++	if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_LED_MASK(~l)))
++		return;
+ }
+ 
+ int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
+@@ -107,128 +306,136 @@ char kbd_unexpected_up(unsigned char key
+ 	return 0x80;
+ }
+ 
+-static void lk201_kbd_rx_char(unsigned char ch, unsigned char stat)
++static void lk201_rx_char(unsigned char ch, unsigned char fl)
+ {
++	static unsigned char id[6];
++	static int id_i;
++
+ 	static int shift_state = 0;
+ 	static int prev_scancode;
+ 	unsigned char c = scancodeRemap[ch];
+ 
+-	if (!stat || stat == 4) {
+-		switch (ch) {
+-		case LK_KEY_ACK:
+-			break;
+-		case LK_KEY_LOCK:
+-			shift_state ^= LK_LOCK;
+-			handle_scancode(c, shift_state && LK_LOCK ? 1 : 0);
+-			break;
+-		case LK_KEY_SHIFT:
+-			shift_state ^= LK_SHIFT;
+-			handle_scancode(c, shift_state && LK_SHIFT ? 1 : 0);
+-			break;
+-		case LK_KEY_CTRL:
+-			shift_state ^= LK_CTRL;
+-			handle_scancode(c, shift_state && LK_CTRL ? 1 : 0);
+-			break;
+-		case LK_KEY_COMP:
+-			shift_state ^= LK_COMP;
+-			handle_scancode(c, shift_state && LK_COMP ? 1 : 0);
+-			break;
+-		case LK_KEY_RELEASE:
+-			if (shift_state & LK_SHIFT)
+-				handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
+-			if (shift_state & LK_CTRL)
+-				handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
+-			if (shift_state & LK_COMP)
+-				handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
+-			if (shift_state & LK_LOCK)
+-				handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
+-			shift_state = 0;
+-			break;
+-		case LK_KEY_REPEAT:
+-			handle_scancode(prev_scancode, 1);
+-			break;
+-		default:
+-			prev_scancode = c;
+-			handle_scancode(c, 1);
+-			break;
++	if (fl != TTY_NORMAL && fl != TTY_OVERRUN) {
++		printk(KERN_ERR "lk201: keyboard receive error: 0x%02x\n", fl);
++		return;
++	}
++
++	/* Assume this is a power-up ID. */
++	if (ch == LK_STAT_PWRUP_ID && !id_i) {
++		id[id_i++] = ch;
++		return;
++	}
++
++	/* Handle the power-up sequence. */
++	if (id_i) {
++		id[id_i++] = ch;
++		if (id_i == 4) {
++			/* OK, the power-up concluded. */
++			lk201_report(id);
++			if (id[2] == LK_STAT_PWRUP_OK)
++				lk201_get_id();
++			else {
++				id_i = 0;
++				printk(KERN_ERR "lk201: keyboard power-up "
++				       "error, skipping initialization\n");
++			}
++		} else if (id_i == 6) {
++			/* We got the ID; report it and start operation. */
++			id_i = 0;
++			lk201_id(id);
++			lk201_reset();
+ 		}
+-	} else
+-		printk("Error reading LKx01 keyboard: 0x%02x\n", stat);
++		return;
++	}
++
++	/* Everything else is a scancode/status response. */
++	id_i = 0;
++	switch (ch) {
++	case LK_STAT_RESUME_ERR:
++	case LK_STAT_ERROR:
++	case LK_STAT_INHIBIT_ACK:
++	case LK_STAT_TEST_ACK:
++	case LK_STAT_MODE_KEYDOWN:
++	case LK_STAT_MODE_ACK:
++		break;
++	case LK_KEY_LOCK:
++		shift_state ^= LK_LOCK;
++		handle_scancode(c, (shift_state & LK_LOCK) ? 1 : 0);
++		break;
++	case LK_KEY_SHIFT:
++		shift_state ^= LK_SHIFT;
++		handle_scancode(c, (shift_state & LK_SHIFT) ? 1 : 0);
++		break;
++	case LK_KEY_CTRL:
++		shift_state ^= LK_CTRL;
++		handle_scancode(c, (shift_state & LK_CTRL) ? 1 : 0);
++		break;
++	case LK_KEY_COMP:
++		shift_state ^= LK_COMP;
++		handle_scancode(c, (shift_state & LK_COMP) ? 1 : 0);
++		break;
++	case LK_KEY_RELEASE:
++		if (shift_state & LK_SHIFT)
++			handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
++		if (shift_state & LK_CTRL)
++			handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
++		if (shift_state & LK_COMP)
++			handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
++		if (shift_state & LK_LOCK)
++			handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
++		shift_state = 0;
++		break;
++	case LK_KEY_REPEAT:
++		handle_scancode(prev_scancode, 1);
++		break;
++	default:
++		prev_scancode = c;
++		handle_scancode(c, 1);
++		break;
++	}
++	tasklet_schedule(&keyboard_tasklet);
+ }
+ 
+-static void __init lk201_info(struct dec_serial *info)
++static void __init lk201_info(void *handle)
+ {
+ }
+ 
+-static int __init lk201_init(struct dec_serial *info)
++static int __init lk201_init(void *handle)
+ {
+-	unsigned int ch, id = 0;
+-	int result;
+-
+-	printk("DECstation LK keyboard driver v0.04... ");
++	/* First install handlers. */
++	lk201_handle = handle;
++	kbd_rate = lk201_kbd_rate;
++	kd_mksound = lk201_kd_mksound;
+ 
+-	result = lk201_reset(info);
+-	if (result)
+-		return result;
+-	mdelay(10);
+-
+-	/*
+-	 * Detect whether there is an LK201 or an LK401
+-	 * The LK401 has ALT keys...
+-	 */
+-	info->hook->poll_tx_char(info, LK_CMD_REQ_ID);
+-	while ((ch = info->hook->poll_rx_char(info)) > 0)
+-		id = ch;
+-
+-	switch (id) {
+-	case 1:
+-		printk("LK201 detected\n");
+-		break;
+-	case 2:
+-		printk("LK401 detected\n");
+-		break;
+-	default:
+-		printk("unknown keyboard, ID %d,\n", id);
+-		printk("... please report to <linux-mips at oss.sgi.com>\n");
+-	}
++	lk201_hook.rx_char = lk201_rx_char;
+ 
+-	/*
+-	 * now we're ready
+-	 */
+-	info->hook->rx_char = lk201_kbd_rx_char;
++	/* Then just issue a reset -- the handlers will do the rest. */
++	lk201_send(LK_CMD_POWER_UP);
+ 
+ 	return 0;
+ }
+ 
+ void __init kbd_init_hw(void)
+ {
+-	extern int register_zs_hook(unsigned int, struct zs_hook *);
+-	extern int unregister_zs_hook(unsigned int);
++	/* Maxine uses LK501 at the Access.Bus. */
++	if (!LK_IFACE)
++		return;
+ 
+-	if (TURBOCHANNEL) {
+-		if (mips_machtype != MACH_DS5000_XX) {
+-			/*
+-			 * This is not a MAXINE, so:
+-			 *
+-			 * kbd_init_hw() is being called before
+-			 * rs_init() so just register the kbd hook
+-			 * and let zs_init do the rest :-)
+-			 */
+-			if (mips_machtype == MACH_DS5000_200)
+-				printk("LK201 Support for DS5000/200 not yet ready ...\n");
+-			else
+-				if(!register_zs_hook(KEYB_LINE, &lk201_kbdhook))
+-					unregister_zs_hook(KEYB_LINE);
+-		}
++	printk(KERN_INFO "lk201: DECstation LK keyboard driver v0.05.\n");
++
++	if (LK_IFACE_ZS) {
++		/*
++		 * kbd_init_hw() is being called before
++		 * rs_init() so just register the kbd hook
++		 * and let zs_init do the rest :-)
++		 */
++		if (!register_dec_serial_hook(KEYB_LINE, &lk201_hook))
++			unregister_dec_serial_hook(KEYB_LINE);
+ 	} else {
+ 		/*
+ 		 * TODO: modify dz.c to allow similar hooks
+ 		 * for LK201 handling on DS2100, DS3100, and DS5000/200
+ 		 */
+-		printk("LK201 Support for DS3100 not yet ready ...\n");
++		printk(KERN_ERR "lk201: support for DZ11 not yet ready.\n");
+ 	}
+ }
+-
+-
+-
+-
+diff -urpNX dontdiff linux-2.6.10/drivers/tc/lk201.h linux-2.6.10-mips/drivers/tc/lk201.h
+--- linux-2.6.10/drivers/tc/lk201.h	2004-12-24 22:34:44.000000000 +0100
++++ linux-2.6.10-mips/drivers/tc/lk201.h	2003-11-16 09:21:10.000000000 +0100
+@@ -2,52 +2,124 @@
+  *	Commands to the keyboard processor
+  */
+ 
+-#define	LK_PARAM		0x80	/* start/end parameter list */
++#define LK_PARAM		0x80	/* start/end parameter list */
+ 
+-#define	LK_CMD_RESUME		0x8b
+-#define	LK_CMD_INHIBIT		0xb9
+-#define	LK_CMD_LEDS_ON		0x13	/* 1 param: led bitmask */
+-#define	LK_CMD_LEDS_OFF		0x11	/* 1 param: led bitmask */
+-#define	LK_CMD_DIS_KEYCLK	0x99
+-#define	LK_CMD_ENB_KEYCLK	0x1b	/* 1 param: volume */
+-#define	LK_CMD_DIS_CTLCLK	0xb9
+-#define	LK_CMD_ENB_CTLCLK	0xbb
+-#define	LK_CMD_SOUND_CLK	0x9f
+-#define	LK_CMD_DIS_BELL		0xa1
+-#define	LK_CMD_ENB_BELL		0x23	/* 1 param: volume */
+-#define	LK_CMD_BELL		0xa7
+-#define	LK_CMD_TMP_NORPT	0xc1
+-#define	LK_CMD_ENB_RPT		0xe3
+-#define	LK_CMD_DIS_RPT		0xe1
+-#define	LK_CMD_RPT_TO_DOWN	0xd9
+-#define	LK_CMD_REQ_ID		0xab
+-#define	LK_CMD_POWER_UP		0xfd
+-#define	LK_CMD_TEST_MODE	0xcb
+-#define	LK_CMD_SET_DEFAULTS	0xd3
++#define LK_CMD_RESUME		0x8b	/* resume transmission to the host */
++#define LK_CMD_INHIBIT		0x89	/* stop transmission to the host */
++#define LK_CMD_LEDS_ON		0x13	/* light LEDs */
++					/* 1st param: led bitmask */
++#define LK_CMD_LEDS_OFF		0x11	/* turn off LEDs */
++					/* 1st param: led bitmask */
++#define LK_CMD_DIS_KEYCLK	0x99	/* disable the keyclick */
++#define LK_CMD_ENB_KEYCLK	0x1b	/* enable the keyclick */
++					/* 1st param: volume */
++#define LK_CMD_DIS_CTLCLK	0xb9	/* disable the Ctrl keyclick */
++#define LK_CMD_ENB_CTLCLK	0xbb	/* enable the Ctrl keyclick */
++#define LK_CMD_SOUND_CLK	0x9f	/* emit a keyclick */
++#define LK_CMD_DIS_BELL		0xa1	/* disable the bell */
++#define LK_CMD_ENB_BELL		0x23	/* enable the bell */
++					/* 1st param: volume */
++#define LK_CMD_BELL		0xa7	/* emit a bell */
++#define LK_CMD_TMP_NORPT	0xd1	/* disable typematic */
++					/* for the currently pressed key */
++#define LK_CMD_ENB_RPT		0xe3	/* enable typematic */
++					/* for RPT_DOWN groups */
++#define LK_CMD_DIS_RPT		0xe1	/* disable typematic */
++					/* for RPT_DOWN groups */
++#define LK_CMD_RPT_TO_DOWN	0xd9	/* set RPT_DOWN groups to DOWN */
++#define LK_CMD_REQ_ID		0xab	/* request the keyboard ID */
++#define LK_CMD_POWER_UP		0xfd	/* init power-up sequence */
++#define LK_CMD_TEST_MODE	0xcb	/* enter the factory test mode */
++#define LK_CMD_TEST_EXIT	0x80	/* exit the factory test mode */
++#define LK_CMD_SET_DEFAULTS	0xd3	/* set power-up defaults */
++
++#define LK_CMD_MODE(m,div)	(LK_PARAM|(((div)&0xf)<<3)|(((m)&0x3)<<1))
++					/* select the repeat mode */
++					/* for the selected key group */
++#define LK_CMD_MODE_AR(m,div)	((((div)&0xf)<<3)|(((m)&0x3)<<1))
++					/* select the repeat mode */
++					/* and the repeat register */
++					/* for the selected key group */
++					/* 1st param: register number */
++#define LK_CMD_RPT_RATE(r)	(0x78|(((r)&0x3)<<1))
++					/* set the delay and repeat rate */
++					/* for the selected repeat register */
++					/* 1st param: initial delay */
++					/* 2nd param: repeat rate */
+ 
+ /* there are 4 leds, represent them in the low 4 bits of a byte */
+-#define	LK_PARAM_LED_MASK(ledbmap)	(LK_PARAM|(ledbmap))
++#define LK_PARAM_LED_MASK(ledbmap)	(LK_PARAM|((ledbmap)&0xf))
++#define LK_LED_WAIT		0x1	/* Wait LED */
++#define LK_LED_COMP		0x2	/* Compose LED */
++#define LK_LED_LOCK		0x4	/* Lock LED */
++#define LK_LED_HOLD		0x8	/* Hold Screen LED */
+ 
+ /* max volume is 0, lowest is 0x7 */
+-#define	LK_PARAM_VOLUME(v)		(LK_PARAM|((v)&0x7))
++#define LK_PARAM_VOLUME(v)		(LK_PARAM|((v)&0x7))
+ 
+-/* mode set command(s) details */
+-#define	LK_MODE_DOWN		0x0
+-#define	LK_MODE_RPT_DOWN	0x2
+-#define	LK_MODE_DOWN_UP		0x6
+-#define	LK_CMD_MODE(m,div)	(LK_PARAM|(div<<3)|m)
++/* mode set command details, div is a key group number */
++#define LK_MODE_DOWN		0x0	/* make only */
++#define LK_MODE_RPT_DOWN	0x1	/* make and typematic */
++#define LK_MODE_DOWN_UP		0x3	/* make and release */
++
++/* there are 4 repeat registers */
++#define LK_PARAM_AR(r)		(LK_PARAM|((v)&0x3))
++
++/*
++ * Mappings between key groups and keycodes are as follows:
++ *
++ *  1: 0xbf - 0xff -- alphanumeric,
++ *  2: 0x91 - 0xa5 -- numeric keypad,
++ *  3: 0xbc        -- Backspace,
++ *  4: 0xbd - 0xbe -- Tab, Return,
++ *  5: 0xb0 - 0xb2 -- Lock, Compose Character,
++ *  6: 0xad - 0xaf -- Ctrl, Shift,
++ *  7: 0xa6 - 0xa8 -- Left Arrow, Right Arrow,
++ *  8: 0xa9 - 0xac -- Up Arrow, Down Arrow, Right Shift,
++ *  9: 0x88 - 0x90 -- editor keypad,
++ * 10: 0x56 - 0x62 -- F1 - F5,
++ * 11: 0x63 - 0x6e -- F6 - F10,
++ * 12: 0x6f - 0x7a -- F11 - F14,
++ * 13: 0x7b - 0x7d -- Help, Do,
++ * 14: 0x7e - 0x87 -- F17 - F20.
++ *
++ * Notes:
++ * 1. Codes in the 0x00 - 0x40 range are reserved.
++ * 2. The assignment of the 0x41 - 0x55 range is undiscovered, probably 10.
++ */
++
++/* delay is 5 - 630 ms; 0x00 and 0x7f are reserved */
++#define LK_PARAM_DELAY(t)	((t)&0x7f)
++
++/* rate is 12 - 127 Hz; 0x00 - 0x0b and 0x7d (power-up!) are reserved */
++#define LK_PARAM_RATE(r)	(LK_PARAM|((r)&0x7f))
+ 
+ #define LK_SHIFT 1<<0
+ #define LK_CTRL 1<<1
+ #define LK_LOCK 1<<2
+ #define LK_COMP 1<<3
+ 
+-#define LK_KEY_SHIFT 174
+-#define LK_KEY_CTRL 175
+-#define LK_KEY_LOCK 176
+-#define LK_KEY_COMP 177
+-#define LK_KEY_RELEASE 179
+-#define LK_KEY_REPEAT 180
+-#define LK_KEY_ACK 186
++#define LK_KEY_SHIFT		0xae
++#define LK_KEY_CTRL		0xaf
++#define LK_KEY_LOCK		0xb0
++#define LK_KEY_COMP		0xb1
++
++#define LK_KEY_RELEASE		0xb3	/* all keys released */
++#define LK_KEY_REPEAT		0xb4	/* repeat the last key */
++
++/* status responses */
++#define LK_STAT_RESUME_ERR	0xb5	/* keystrokes lost while inhibited */
++#define LK_STAT_ERROR		0xb6	/* an invalid command received */
++#define LK_STAT_INHIBIT_ACK	0xb7	/* transmission inhibited */
++#define LK_STAT_TEST_ACK	0xb8	/* the factory test mode entered */
++#define LK_STAT_MODE_KEYDOWN	0xb9	/* a key is down on a change */
++					/* to the DOWN_UP mode; */
++					/* the keycode follows */
++#define LK_STAT_MODE_ACK	0xba	/* the mode command succeeded */
++
++#define LK_STAT_PWRUP_ID	0x01	/* the power-up response start mark */
++#define LK_STAT_PWRUP_OK	0x00	/* the power-up self test OK */
++#define LK_STAT_PWRUP_KDOWN	0x3d	/* a key was down during the test */
++#define LK_STAT_PWRUP_ERROR	0x3e	/* keyboard self test failure */
+ 
+-extern unsigned char scancodeRemap[256];
+\ No newline at end of file
++extern unsigned char scancodeRemap[256];
+diff -urpNX dontdiff linux-2.6.10/drivers/tc/tc.c linux-2.6.10-mips/drivers/tc/tc.c
+--- linux-2.6.10/drivers/tc/tc.c	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/drivers/tc/tc.c	2003-09-13 10:00:14.000000000 +0200
+@@ -8,46 +8,46 @@
+  * for more details.
+  *
+  * Copyright (c) Harald Koerfgen, 1998
++ * Copyright (c) 2001, 2003  Maciej W. Rozycki
+  */
+ #include <linux/string.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++
+ #include <asm/addrspace.h>
+ #include <asm/errno.h>
+ #include <asm/dec/machtype.h>
++#include <asm/dec/prom.h>
+ #include <asm/dec/tcinfo.h>
+ #include <asm/dec/tcmodule.h>
+ #include <asm/dec/interrupts.h>
+-
++#include <asm/paccess.h>
+ #include <asm/ptrace.h>
+-#include <linux/kernel.h>
+-#include <linux/module.h>
+ 
+ #define TC_DEBUG
+ 
+ MODULE_LICENSE("GPL");
+ slot_info tc_bus[MAX_SLOT];
+-static int max_tcslot;
++static int num_tcslots;
+ static tcinfo *info;
+ 
+ unsigned long system_base;
+ 
+-extern void (*dbe_board_handler)(struct pt_regs *regs);
+-extern unsigned long *(*rex_slot_address)(int);
+-extern void *(*rex_gettcinfo)(void);
+-
+ /*
+  * Interface to the world. Read comment in include/asm-mips/tc.h.
+  */
+ 
+-int search_tc_card(char *name)
++int search_tc_card(const char *name)
+ {
+ 	int slot;
+ 	slot_info *sip;
+ 
+-	for (slot = 0; slot <= max_tcslot; slot++) {
++	for (slot = 0; slot < num_tcslots; slot++) {
+ 		sip = &tc_bus[slot];
+-		if ((sip->flags & FREE) && (strncmp(sip->name, name, strlen(name)) == 0)) {
++		if ((sip->flags & FREE) &&
++		    (strncmp(sip->name, name, strlen(name)) == 0)) {
+ 			return slot;
+ 		}
+ 	}
+@@ -68,7 +68,8 @@ void claim_tc_card(int slot)
+ void release_tc_card(int slot)
+ {
+ 	if (tc_bus[slot].flags & FREE) {
+-		printk("release_tc_card: attempting to release a card already free\n");
++		printk("release_tc_card: "
++		       "attempting to release a card already free\n");
+ 		return;
+ 	}
+ 	tc_bus[slot].flags &= ~IN_USE;
+@@ -93,73 +94,84 @@ unsigned long get_tc_speed(void)
+ /*
+  * Probing for TURBOchannel modules
+  */
+-static void __init my_dbe_handler(struct pt_regs *regs)
++static void __init tc_probe(unsigned long startaddr, unsigned long size,
++			    int slots)
+ {
+-	regs->cp0_epc += 4;
+-}
+-
+-static void __init tc_probe(unsigned long startaddr, unsigned long size, int max_slot)
+-{
+-	int i, slot;
++	int i, slot, err;
+ 	long offset;
++	unsigned char pattern[4];
+ 	unsigned char *module;
+-	void (*old_be_handler)(struct pt_regs *regs);
+-
+-	/* Install our exception handler temporarily */
+ 
+-	old_be_handler = dbe_board_handler;
+-	dbe_board_handler = my_dbe_handler;
+-	for (slot = 0; slot <= max_slot; slot++) {
++	for (slot = 0; slot < slots; slot++) {
+ 		module = (char *)(startaddr + slot * size);
+-		offset = -1;
+-		if (module[OLDCARD + TC_PATTERN0] == 0x55 && module[OLDCARD + TC_PATTERN1] == 0x00
+-		  && module[OLDCARD + TC_PATTERN2] == 0xaa && module[OLDCARD + TC_PATTERN3] == 0xff)
+-			offset = OLDCARD;
+-		if (module[TC_PATTERN0] == 0x55 && module[TC_PATTERN1] == 0x00
+-		  && module[TC_PATTERN2] == 0xaa && module[TC_PATTERN3] == 0xff)
+-			offset = 0;
+-
+-		if (offset != -1) {
+-			tc_bus[slot].base_addr = (unsigned long)module;
+-			for(i = 0; i < 8; i++) {
+-				tc_bus[slot].firmware[i] = module[TC_FIRM_VER + offset + 4 * i];
+-				tc_bus[slot].vendor[i] = module[TC_VENDOR + offset + 4 * i];
+-				tc_bus[slot].name[i] = module[TC_MODULE + offset + 4 * i];
+-			}
+-			tc_bus[slot].firmware[8] = 0;
+-			tc_bus[slot].vendor[8] = 0;
+-			tc_bus[slot].name[8] = 0;
+-			/*
+-			 * Looks unneccesary, but we may change
+-			 * TC? in the future
+-			 */
+-			switch (slot) {
+-			case 0:
+-				tc_bus[slot].interrupt = TC0;
+-				break;
+-			case 1:
+-				tc_bus[slot].interrupt = TC1;
+-				break;
+-			case 2:
+-				tc_bus[slot].interrupt = TC2;
+-				break;
+-			/*
+-			 * Yuck! DS5000/200 onboard devices
+-			 */
+-			case 5:
+-				tc_bus[slot].interrupt = SCSI_INT;
+-				break;
+-			case 6:
+-				tc_bus[slot].interrupt = ETHER;
+-				break;
+-			default:
+-				tc_bus[slot].interrupt = -1;
+-				break;
+-			}	
++
++		offset = OLDCARD;
++
++		err = 0;
++		err |= get_dbe(pattern[0], module + OLDCARD + TC_PATTERN0);
++		err |= get_dbe(pattern[1], module + OLDCARD + TC_PATTERN1);
++		err |= get_dbe(pattern[2], module + OLDCARD + TC_PATTERN2);
++		err |= get_dbe(pattern[3], module + OLDCARD + TC_PATTERN3);
++		if (err)
++			continue;
++
++		if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
++		    pattern[2] != 0xaa || pattern[3] != 0xff) {
++			offset = NEWCARD;
++
++			err = 0;
++			err |= get_dbe(pattern[0], module + TC_PATTERN0);
++			err |= get_dbe(pattern[1], module + TC_PATTERN1);
++			err |= get_dbe(pattern[2], module + TC_PATTERN2);
++			err |= get_dbe(pattern[3], module + TC_PATTERN3);
++			if (err)
++				continue;
+ 		}
+-	}
+ 
+-	dbe_board_handler = old_be_handler;
++		if (pattern[0] != 0x55 || pattern[1] != 0x00 ||
++		    pattern[2] != 0xaa || pattern[3] != 0xff)
++			continue;
++
++		tc_bus[slot].base_addr = (unsigned long)module;
++		for(i = 0; i < 8; i++) {
++			tc_bus[slot].firmware[i] =
++				module[TC_FIRM_VER + offset + 4 * i];
++			tc_bus[slot].vendor[i] =
++				module[TC_VENDOR + offset + 4 * i];
++			tc_bus[slot].name[i] =
++				module[TC_MODULE + offset + 4 * i];
++		}
++		tc_bus[slot].firmware[8] = 0;
++		tc_bus[slot].vendor[8] = 0;
++		tc_bus[slot].name[8] = 0;
++		/*
++		 * Looks unneccesary, but we may change
++		 * TC? in the future
++		 */
++		switch (slot) {
++		case 0:
++			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC0];
++			break;
++		case 1:
++			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC1];
++			break;
++		case 2:
++			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC2];
++			break;
++		/*
++		 * Yuck! DS5000/200 onboard devices
++		 */
++		case 5:
++			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC5];
++			break;
++		case 6:
++			tc_bus[slot].interrupt = dec_interrupt[DEC_IRQ_TC6];
++			break;
++		default:
++			tc_bus[slot].interrupt = -1;
++			break;
++		}
++	}
+ }
+ 
+ /*
+@@ -189,15 +201,16 @@ void __init tc_init(void)
+ 
+ 	switch (mips_machtype) {
+ 	case MACH_DS5000_200:
+-		max_tcslot = 6;
++		num_tcslots = 7;
+ 		break;
+ 	case MACH_DS5000_1XX:
+ 	case MACH_DS5000_2X0:
+-		max_tcslot = 2;
++	case MACH_DS5900:
++		num_tcslots = 3;
+ 		break;
+ 	case MACH_DS5000_XX:
+ 	default:
+-		max_tcslot = 1;
++		num_tcslots = 2;
+ 		break;
+ 	}
+ 
+@@ -210,22 +223,22 @@ void __init tc_init(void)
+ 
+ 		slot_size = info->slot_size << 20;
+ 
+-		tc_probe(slot0addr, slot_size, max_tcslot);
++		tc_probe(slot0addr, slot_size, num_tcslots);
+ 
+   		/*
+   		 * All TURBOchannel DECstations have the onboard devices
+- 		 * where the (max_tcslot + 1 or 2 on DS5k/xx) Option Module
++ 		 * where the (num_tcslots + 0 or 1 on DS5k/xx) Option Module
+  		 * would be.
+  		 */
+  		if(mips_machtype == MACH_DS5000_XX)
+- 			i = 2;
+-		else
+  			i = 1;
+- 		
+- 	        system_base = slot0addr + slot_size * (max_tcslot + i);
++		else
++ 			i = 0;
++
++ 	        system_base = slot0addr + slot_size * (num_tcslots + i);
+ 
+ #ifdef TC_DEBUG
+-		for (i = 0; i <= max_tcslot; i++)
++		for (i = 0; i < num_tcslots; i++)
+ 			if (tc_bus[i].base_addr) {
+ 				printk("    slot %d: ", i);
+ 				printk("%s %s %s\n", tc_bus[i].vendor,
+@@ -244,4 +257,4 @@ EXPORT_SYMBOL(release_tc_card);
+ EXPORT_SYMBOL(get_tc_base_addr);
+ EXPORT_SYMBOL(get_tc_irq_nr);
+ EXPORT_SYMBOL(get_tc_speed);
+-
++EXPORT_SYMBOL(system_base);
+diff -urpNX dontdiff linux-2.6.10/drivers/tc/zs.c linux-2.6.10-mips/drivers/tc/zs.c
+--- linux-2.6.10/drivers/tc/zs.c	2004-12-24 22:35:25.000000000 +0100
++++ linux-2.6.10-mips/drivers/tc/zs.c	2004-10-27 02:14:57.000000000 +0200
+@@ -6,7 +6,7 @@
+  *
+  * DECstation changes
+  * Copyright (C) 1998-2000 Harald Koerfgen
+- * Copyright (C) 2000,2001 Maciej W. Rozycki <macro at ds2.pg.gda.pl>
++ * Copyright (C) 2000, 2001, 2002, 2003, 2004  Maciej W. Rozycki
+  *
+  * For the rest of the code the original Copyright applies:
+  * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras at cs.anu.edu.au)
+@@ -55,8 +55,7 @@
+ #include <linux/delay.h>
+ #include <linux/init.h>
+ #include <linux/ioport.h>
+-#include <linux/bitops.h>
+-#ifdef CONFIG_SERIAL_CONSOLE
++#ifdef CONFIG_SERIAL_DEC_CONSOLE
+ #include <linux/console.h>
+ #endif
+ 
+@@ -65,18 +64,15 @@
+ #include <asm/irq.h>
+ #include <asm/system.h>
+ #include <asm/uaccess.h>
+-#include <asm/wbflush.h>
+ #include <asm/bootinfo.h>
++#include <asm/dec/serial.h>
++
+ #ifdef CONFIG_MACH_DECSTATION
+ #include <asm/dec/interrupts.h>
+ #include <asm/dec/machtype.h>
+ #include <asm/dec/tc.h>
+ #include <asm/dec/ioasic_addrs.h>
+ #endif
+-#ifdef CONFIG_BAGET_MIPS
+-#include <asm/baget/baget.h>
+-unsigned long system_base;
+-#endif
+ #ifdef CONFIG_KGDB
+ #include <asm/kgdb.h>
+ #endif
+@@ -94,7 +90,7 @@ unsigned long system_base;
+ #define NUM_SERIAL	2		/* Max number of ZS chips supported */
+ #define NUM_CHANNELS	(NUM_SERIAL * 2)	/* 2 channels per chip */
+ #define CHANNEL_A_NR  (zs_parms->channel_a_offset > zs_parms->channel_b_offset)
+-                                        /* Number of channel A in the chip */ 
++                                        /* Number of channel A in the chip */
+ #define ZS_CHAN_IO_SIZE 8
+ #define ZS_CLOCK        7372800 	/* Z8530 RTxC input clock rate */
+ 
+@@ -105,7 +101,8 @@ struct zs_parms {
+ 	unsigned long scc1;
+ 	int channel_a_offset;
+ 	int channel_b_offset;
+-	int irq;
++	int irq0;
++	int irq1;
+ 	int clock;
+ };
+ 
+@@ -113,24 +110,15 @@ static struct zs_parms *zs_parms;
+ 
+ #ifdef CONFIG_MACH_DECSTATION
+ static struct zs_parms ds_parms = {
+-	scc0 : SCC0,
+-	scc1 : SCC1,
++	scc0 : IOASIC_SCC0,
++	scc1 : IOASIC_SCC1,
+ 	channel_a_offset : 1,
+ 	channel_b_offset : 9,
+-	irq : SERIAL,
++	irq0 : -1,
++	irq1 : -1,
+ 	clock : ZS_CLOCK
+ };
+ #endif
+-#ifdef CONFIG_BAGET_MIPS
+-static struct zs_parms baget_parms = {
+-	scc0 : UNI_SCC0,
+-	scc1 : UNI_SCC1,
+-	channel_a_offset : 9,
+-	channel_b_offset : 1,
+-	irq : BAGET_SCC_IRQ,
+-	clock : 14745000
+-};
+-#endif
+ 
+ #ifdef CONFIG_MACH_DECSTATION
+ #define DS_BUS_PRESENT (IOASIC)
+@@ -138,13 +126,7 @@ static struct zs_parms baget_parms = {
+ #define DS_BUS_PRESENT 0
+ #endif
+ 
+-#ifdef CONFIG_BAGET_MIPS
+-#define BAGET_BUS_PRESENT (mips_machtype == MACH_BAGET202)
+-#else
+-#define BAGET_BUS_PRESENT 0
+-#endif
+-
+-#define BUS_PRESENT (DS_BUS_PRESENT || BAGET_BUS_PRESENT)
++#define BUS_PRESENT (DS_BUS_PRESENT)
+ 
+ struct dec_zschannel zs_channels[NUM_CHANNELS];
+ struct dec_serial zs_soft[NUM_CHANNELS];
+@@ -153,28 +135,28 @@ struct dec_serial *zs_chain;	/* list of 
+ 
+ struct tty_struct zs_ttys[NUM_CHANNELS];
+ 
+-#ifdef CONFIG_SERIAL_CONSOLE
++#ifdef CONFIG_SERIAL_DEC_CONSOLE
+ static struct console sercons;
+ #endif
+-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) \
+-    && !defined(MODULE)
++#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \
++   !defined(MODULE)
+ static unsigned long break_pressed; /* break, really ... */
+ #endif
+ 
+ static unsigned char zs_init_regs[16] __initdata = {
+-	0,                           /* write 0 */
+-	0,			     /* write 1 */
+-	0xf0,                        /* write 2 */
+-	(Rx8),                       /* write 3 */
+-	(X16CLK | SB1),              /* write 4 */
+-	(Tx8),                       /* write 5 */
+-	0, 0, 0,                     /* write 6, 7, 8 */
+-	(VIS),                       /* write 9 */
+-	(NRZ),                       /* write 10 */
+-	(TCBR | RCBR),               /* write 11 */
+-	0, 0,                        /* BRG time constant, write 12 + 13 */
+-	(BRSRC | BRENABL),           /* write 14 */
+-	0 			     /* write 15 */
++	0,				/* write 0 */
++	0,				/* write 1 */
++	0,				/* write 2 */
++	0,				/* write 3 */
++	(X16CLK),			/* write 4 */
++	0,				/* write 5 */
++	0, 0, 0,			/* write 6, 7, 8 */
++	(MIE | DLC | NV),		/* write 9 */
++	(NRZ),				/* write 10 */
++	(TCBR | RCBR),			/* write 11 */
++	0, 0,				/* BRG time constant, write 12 + 13 */
++	(BRSRC | BRENABL),		/* write 14 */
++	0				/* write 15 */
+ };
+ 
+ DECLARE_TASK_QUEUE(tq_zs_serial);
+@@ -190,7 +172,6 @@ static struct tty_driver *serial_driver;
+ /*
+  * Debugging.
+  */
+-#undef SERIAL_DEBUG_INTR
+ #undef SERIAL_DEBUG_OPEN
+ #undef SERIAL_DEBUG_FLOW
+ #undef SERIAL_DEBUG_THROTTLE
+@@ -251,7 +232,7 @@ static int baud_table[] = {
+ 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
+ 	9600, 19200, 38400, 57600, 115200, 0 };
+ 
+-/* 
++/*
+  * Reading and writing Z8530 registers.
+  */
+ static inline unsigned char read_zsreg(struct dec_zschannel *channel,
+@@ -261,7 +242,7 @@ static inline unsigned char read_zsreg(s
+ 
+ 	if (reg != 0) {
+ 		*channel->control = reg & 0xf;
+-		wbflush(); RECOVERY_DELAY;
++		fast_iob(); RECOVERY_DELAY;
+ 	}
+ 	retval = *channel->control;
+ 	RECOVERY_DELAY;
+@@ -273,10 +254,10 @@ static inline void write_zsreg(struct de
+ {
+ 	if (reg != 0) {
+ 		*channel->control = reg & 0xf;
+-		wbflush(); RECOVERY_DELAY;
++		fast_iob(); RECOVERY_DELAY;
+ 	}
+ 	*channel->control = value;
+-	wbflush(); RECOVERY_DELAY;
++	fast_iob(); RECOVERY_DELAY;
+ 	return;
+ }
+ 
+@@ -293,7 +274,7 @@ static inline void write_zsdata(struct d
+ 				unsigned char value)
+ {
+ 	*channel->data = value;
+-	wbflush(); RECOVERY_DELAY;
++	fast_iob(); RECOVERY_DELAY;
+ 	return;
+ }
+ 
+@@ -303,9 +284,9 @@ static inline void load_zsregs(struct de
+ /*	ZS_CLEARERR(channel);
+ 	ZS_CLEARFIFO(channel); */
+ 	/* Load 'em up */
+-	write_zsreg(channel, R4, regs[R4]);
+ 	write_zsreg(channel, R3, regs[R3] & ~RxENABLE);
+ 	write_zsreg(channel, R5, regs[R5] & ~TxENAB);
++	write_zsreg(channel, R4, regs[R4]);
+ 	write_zsreg(channel, R9, regs[R9]);
+ 	write_zsreg(channel, R1, regs[R1]);
+ 	write_zsreg(channel, R2, regs[R2]);
+@@ -372,8 +353,6 @@ static inline void rs_recv_clear(struct 
+  * -----------------------------------------------------------------------
+  */
+ 
+-static int tty_break;	/* Set whenever BREAK condition is detected.  */
+-
+ /*
+  * This routine is used by the interrupt handler to schedule
+  * processing in the software interrupt portion of the driver.
+@@ -397,23 +376,18 @@ static _INLINE_ void receive_chars(struc
+ 		stat = read_zsreg(info->zs_channel, R1);
+ 		ch = read_zsdata(info->zs_channel);
+ 
+-		if (!tty && !info->hook && !info->hook->rx_char)
++		if (!tty && (!info->hook || !info->hook->rx_char))
+ 			continue;
+ 
+-		if (tty_break) {
+-			tty_break = 0;
+-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
+-			if (info->line == sercons.index) {
+-				if (!break_pressed) {
+-					break_pressed = jiffies;
+-					goto ignore_char;
+-				}
+-				break_pressed = 0;
+-			}
+-#endif
++		flag = TTY_NORMAL;
++		if (info->tty_break) {
++			info->tty_break = 0;
+ 			flag = TTY_BREAK;
+ 			if (info->flags & ZILOG_SAK)
+ 				do_SAK(tty);
++			/* Ignore the null char got when BREAK is removed.  */
++			if (ch == 0)
++				continue;
+ 		} else {
+ 			if (stat & Rx_OVR) {
+ 				flag = TTY_OVERRUN;
+@@ -421,20 +395,22 @@ static _INLINE_ void receive_chars(struc
+ 				flag = TTY_FRAME;
+ 			} else if (stat & PAR_ERR) {
+ 				flag = TTY_PARITY;
+-			} else
+-				flag = 0;
+-			if (flag)
++			}
++			if (flag != TTY_NORMAL)
+ 				/* reset the error indication */
+ 				write_zsreg(info->zs_channel, R0, ERR_RES);
+ 		}
+ 
+-#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
++#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \
++   !defined(MODULE)
+ 		if (break_pressed && info->line == sercons.index) {
+-			if (ch != 0 &&
+-			    time_before(jiffies, break_pressed + HZ*5)) {
++			/* Ignore the null char got when BREAK is removed.  */
++			if (ch == 0)
++				continue;
++			if (time_before(jiffies, break_pressed + HZ * 5)) {
+ 				handle_sysrq(ch, regs, NULL);
+ 				break_pressed = 0;
+-				goto ignore_char;
++				continue;
+ 			}
+ 			break_pressed = 0;
+ 		}
+@@ -444,22 +420,8 @@ static _INLINE_ void receive_chars(struc
+ 			(*info->hook->rx_char)(ch, flag);
+ 			return;
+   		}
+-		
+-		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+-			static int flip_buf_ovf;
+-			++flip_buf_ovf;
+-			continue;
+-		}
+-		tty->flip.count++;
+-		{
+-			static int flip_max_cnt;
+-			if (flip_max_cnt < tty->flip.count)
+-				flip_max_cnt = tty->flip.count;
+-		}
+ 
+-		*tty->flip.flag_buf_ptr++ = flag;
+-		*tty->flip.char_buf_ptr++ = ch;
+-	ignore_char:
++		tty_insert_flip_char(tty, ch, flag);
+ 	}
+ 	if (tty)
+ 		tty_flip_buffer_push(tty);
+@@ -501,18 +463,22 @@ static _INLINE_ void status_handle(struc
+ 	/* Get status from Read Register 0 */
+ 	stat = read_zsreg(info->zs_channel, R0);
+ 
+-	if (stat & BRK_ABRT) {
+-#ifdef SERIAL_DEBUG_INTR
+-		printk("handling break....");
++	if ((stat & BRK_ABRT) && !(info->read_reg_zero & BRK_ABRT)) {
++#if defined(CONFIG_SERIAL_DEC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && \
++   !defined(MODULE)
++		if (info->line == sercons.index) {
++			if (!break_pressed)
++				break_pressed = jiffies;
++		} else
+ #endif
+-		tty_break = 1;
++			info->tty_break = 1;
+ 	}
+ 
+ 	if (info->zs_channel != info->zs_chan_a) {
+ 
+-		/* FIXEM: Check for DCD transitions */
+-		if (((stat ^ info->read_reg_zero) & DCD) != 0
+-		    && info->tty && !C_CLOCAL(info->tty)) {
++		/* Check for DCD transitions */
++		if (info->tty && !C_CLOCAL(info->tty) &&
++		    ((stat ^ info->read_reg_zero) & DCD) != 0 ) {
+ 			if (stat & DCD) {
+ 				wake_up_interruptible(&info->open_wait);
+ 			} else {
+@@ -563,7 +529,7 @@ void rs_interrupt(int irq, void *dev_id,
+ 		shift = 0;	/* Channel B */
+ 
+ 	for (;;) {
+-		zs_intreg = read_zsreg(info->zs_chan_a, R3) >> shift; 
++		zs_intreg = read_zsreg(info->zs_chan_a, R3) >> shift;
+ 		if ((zs_intreg & CHAN_IRQMASK) == 0)
+ 			break;
+ 
+@@ -577,7 +543,7 @@ void rs_interrupt(int irq, void *dev_id,
+ 			status_handle(info);
+ 		}
+ 	}
+-	
++
+ 	/* Why do we need this ? */
+ 	write_zsreg(info->zs_channel, 0, RES_H_IUS);
+ }
+@@ -586,14 +552,14 @@ void rs_interrupt(int irq, void *dev_id,
+ void zs_dump (void) {
+ 	int i, j;
+ 	for (i = 0; i < zs_channels_found; i++) {
+-		struct dec_zschannel *ch = &zs_channels[i]; 
++		struct dec_zschannel *ch = &zs_channels[i];
+ 		if ((long)ch->control == UNI_IO_BASE+UNI_SCC1A_CTRL) {
+ 			for (j = 0; j < 15; j++) {
+-				printk("W%d = 0x%x\t", 
++				printk("W%d = 0x%x\t",
+ 				       j, (int)ch->curregs[j]);
+ 			}
+ 			for (j = 0; j < 15; j++) {
+-				printk("R%d = 0x%x\t", 
++				printk("R%d = 0x%x\t",
+ 				       j, (int)read_zsreg(ch,j));
+ 			}
+ 			printk("\n\n");
+@@ -622,7 +588,7 @@ static void rs_stop(struct tty_struct *t
+ 
+ 	if (serial_paranoia_check(info, tty->name, "rs_stop"))
+ 		return;
+-	
++
+ #if 1
+ 	save_flags(flags); cli();
+ 	if (info->zs_channel->curregs[5] & TxENAB) {
+@@ -637,10 +603,10 @@ static void rs_start(struct tty_struct *
+ {
+ 	struct dec_serial *info = (struct dec_serial *)tty->driver_data;
+ 	unsigned long flags;
+-	
++
+ 	if (serial_paranoia_check(info, tty->name, "rs_start"))
+ 		return;
+-	
++
+ 	save_flags(flags); cli();
+ #if 1
+ 	if (info->xmit_cnt && info->xmit_buf && !(info->zs_channel->curregs[5] & TxENAB)) {
+@@ -673,7 +639,7 @@ static void do_softint(void *private_)
+ {
+ 	struct dec_serial	*info = (struct dec_serial *) private_;
+ 	struct tty_struct	*tty;
+-	
++
+ 	tty = info->tty;
+ 	if (!tty)
+ 		return;
+@@ -711,8 +677,13 @@ int zs_startup(struct dec_serial * info)
+ 	/*
+ 	 * Clear the interrupt registers.
+ 	 */
+-	write_zsreg(info->zs_channel, 0, ERR_RES);
+-	write_zsreg(info->zs_channel, 0, RES_H_IUS);
++	write_zsreg(info->zs_channel, R0, ERR_RES);
++	write_zsreg(info->zs_channel, R0, RES_H_IUS);
++
++	/*
++	 * Set the speed of the serial port
++	 */
++	change_speed(info);
+ 
+ 	/*
+ 	 * Turn on RTS and DTR.
+@@ -722,35 +693,30 @@ int zs_startup(struct dec_serial * info)
+ 	/*
+ 	 * Finally, enable sequencing and interrupts
+ 	 */
+-	info->zs_channel->curregs[1] = (info->zs_channel->curregs[1] & ~0x18) | (EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB);
+-	info->zs_channel->curregs[3] |= (RxENABLE | Rx8);
+-	info->zs_channel->curregs[5] |= (TxENAB | Tx8);
+-	info->zs_channel->curregs[15] |= (DCDIE | CTSIE | TxUIE | BRKIE);
+-	info->zs_channel->curregs[9] |= (VIS | MIE);
+-	write_zsreg(info->zs_channel, 1, info->zs_channel->curregs[1]);
+-	write_zsreg(info->zs_channel, 3, info->zs_channel->curregs[3]);
+-	write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]);
+-	write_zsreg(info->zs_channel, 15, info->zs_channel->curregs[15]);
+-	write_zsreg(info->zs_channel, 9, info->zs_channel->curregs[9]);
++	info->zs_channel->curregs[R1] &= ~RxINT_MASK;
++	info->zs_channel->curregs[R1] |= (RxINT_ALL | TxINT_ENAB |
++					  EXT_INT_ENAB);
++	info->zs_channel->curregs[R3] |= RxENABLE;
++	info->zs_channel->curregs[R5] |= TxENAB;
++	info->zs_channel->curregs[R15] |= (DCDIE | CTSIE | TxUIE | BRKIE);
++	write_zsreg(info->zs_channel, R1, info->zs_channel->curregs[R1]);
++	write_zsreg(info->zs_channel, R3, info->zs_channel->curregs[R3]);
++	write_zsreg(info->zs_channel, R5, info->zs_channel->curregs[R5]);
++	write_zsreg(info->zs_channel, R15, info->zs_channel->curregs[R15]);
+ 
+ 	/*
+ 	 * And clear the interrupt registers again for luck.
+ 	 */
+-	write_zsreg(info->zs_channel, 0, ERR_RES);
+-	write_zsreg(info->zs_channel, 0, RES_H_IUS);
++	write_zsreg(info->zs_channel, R0, ERR_RES);
++	write_zsreg(info->zs_channel, R0, RES_H_IUS);
++
++	/* Save the current value of RR0 */
++	info->read_reg_zero = read_zsreg(info->zs_channel, R0);
+ 
+ 	if (info->tty)
+ 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
+ 
+-	/*
+-	 * Set the speed of the serial port
+-	 */
+-	change_speed(info);
+-
+-	/* Save the current value of RR0 */
+-	info->read_reg_zero = read_zsreg(info->zs_channel, 0);
+-
+ 	info->flags |= ZILOG_INITIALIZED;
+ 	restore_flags(flags);
+ 	return 0;
+@@ -771,9 +737,9 @@ static void shutdown(struct dec_serial *
+ 	printk("Shutting down serial port %d (irq %d)....", info->line,
+ 	       info->irq);
+ #endif
+-	
++
+ 	save_flags(flags); cli(); /* Disable interrupts */
+-	
++
+ 	if (info->xmit_buf) {
+ 		free_page((unsigned long) info->xmit_buf);
+ 		info->xmit_buf = 0;
+@@ -833,13 +799,11 @@ static void change_speed(struct dec_seri
+ 
+ 	save_flags(flags); cli();
+ 	info->zs_baud = baud_table[i];
+-	info->clk_divisor = 16;
+ 	if (info->zs_baud) {
+-		info->zs_channel->curregs[4] = X16CLK;
+ 		brg = BPS_TO_BRG(info->zs_baud, zs_parms->clock/info->clk_divisor);
+ 		info->zs_channel->curregs[12] = (brg & 255);
+ 		info->zs_channel->curregs[13] = ((brg >> 8) & 255);
+-		zs_rtsdtr(info, DTR, 1); 
++		zs_rtsdtr(info, DTR, 1);
+ 	} else {
+ 		zs_rtsdtr(info, RTS | DTR, 0);
+ 		return;
+@@ -942,13 +906,21 @@ static int rs_write(struct tty_struct * 
+ 
+ 	save_flags(flags);
+ 	while (1) {
+-		cli();		
+-		c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+-					  SERIAL_XMIT_SIZE - info->xmit_head));
++		cli();
++		c = min(count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
++				   SERIAL_XMIT_SIZE - info->xmit_head));
+ 		if (c <= 0)
+ 			break;
+ 
+-		memcpy(info->xmit_buf + info->xmit_head, buf, c);
++		if (from_user) {
++			down(&tmp_buf_sem);
++			copy_from_user(tmp_buf, buf, c);
++			c = min(c, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
++				       SERIAL_XMIT_SIZE - info->xmit_head));
++			memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
++			up(&tmp_buf_sem);
++		} else
++			memcpy(info->xmit_buf + info->xmit_head, buf, c);
+ 		info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+ 		info->xmit_cnt += c;
+ 		restore_flags(flags);
+@@ -968,7 +940,7 @@ static int rs_write_room(struct tty_stru
+ {
+ 	struct dec_serial *info = (struct dec_serial *)tty->driver_data;
+ 	int	ret;
+-				
++
+ 	if (serial_paranoia_check(info, tty->name, "rs_write_room"))
+ 		return 0;
+ 	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
+@@ -980,7 +952,7 @@ static int rs_write_room(struct tty_stru
+ static int rs_chars_in_buffer(struct tty_struct *tty)
+ {
+ 	struct dec_serial *info = (struct dec_serial *)tty->driver_data;
+-			
++
+ 	if (serial_paranoia_check(info, tty->name, "rs_chars_in_buffer"))
+ 		return 0;
+ 	return info->xmit_cnt;
+@@ -989,7 +961,7 @@ static int rs_chars_in_buffer(struct tty
+ static void rs_flush_buffer(struct tty_struct *tty)
+ {
+ 	struct dec_serial *info = (struct dec_serial *)tty->driver_data;
+-				
++
+ 	if (serial_paranoia_check(info, tty->name, "rs_flush_buffer"))
+ 		return;
+ 	cli();
+@@ -1001,7 +973,7 @@ static void rs_flush_buffer(struct tty_s
+ /*
+  * ------------------------------------------------------------
+  * rs_throttle()
+- * 
++ *
+  * This routine is called by the upper-layer tty layer to signal that
+  * incoming characters should be throttled.
+  * ------------------------------------------------------------
+@@ -1013,14 +985,14 @@ static void rs_throttle(struct tty_struc
+ 
+ #ifdef SERIAL_DEBUG_THROTTLE
+ 	char	buf[64];
+-	
++
+ 	printk("throttle %s: %d....\n", _tty_name(tty, buf),
+ 	       tty->ldisc.chars_in_buffer(tty));
+ #endif
+ 
+ 	if (serial_paranoia_check(info, tty->name, "rs_throttle"))
+ 		return;
+-	
++
+ 	if (I_IXOFF(tty)) {
+ 		save_flags(flags); cli();
+ 		info->x_char = STOP_CHAR(tty);
+@@ -1041,14 +1013,14 @@ static void rs_unthrottle(struct tty_str
+ 
+ #ifdef SERIAL_DEBUG_THROTTLE
+ 	char	buf[64];
+-	
++
+ 	printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
+ 	       tty->ldisc.chars_in_buffer(tty));
+ #endif
+ 
+ 	if (serial_paranoia_check(info, tty->name, "rs_unthrottle"))
+ 		return;
+-	
++
+ 	if (I_IXOFF(tty)) {
+ 		save_flags(flags); cli();
+ 		if (info->x_char)
+@@ -1145,7 +1117,7 @@ check_and_exit:
+  * 	    release the bus after transmitting. This must be done when
+  * 	    the transmit shift register is empty, not be done when the
+  * 	    transmit holding register is empty.  This functionality
+- * 	    allows an RS485 driver to be written in user space. 
++ * 	    allows an RS485 driver to be written in user space.
+  */
+ static int get_lsr_info(struct dec_serial * info, unsigned int *value)
+ {
+@@ -1192,7 +1164,7 @@ static int rs_tiocmget(struct tty_struct
+ }
+ 
+ static int rs_tiocmset(struct tty_struct *tty, struct file *file,
+-		       unsigned int set, unsigned int clear)
++                       unsigned int set, unsigned int clear)
+ {
+ 	struct dec_serial * info = (struct dec_serial *)tty->driver_data;
+ 	int error;
+@@ -1210,6 +1182,7 @@ static int rs_tiocmset(struct tty_struct
+ 	if (info->zs_channel == info->zs_chan_a)
+ 		return 0;
+ 
++	get_user(arg, value);
+ 	cli();
+ 	if (set & TIOCM_RTS)
+ 		info->zs_chan_a->curregs[5] |= RTS;
+@@ -1264,38 +1237,38 @@ static int rs_ioctl(struct tty_struct *t
+ 		if (tty->flags & (1 << TTY_IO_ERROR))
+ 		    return -EIO;
+ 	}
+-	
++
+ 	switch (cmd) {
+-		case TIOCGSERIAL:
+-			error = verify_area(VERIFY_WRITE, (void *) arg,
+-						sizeof(struct serial_struct));
+-			if (error)
+-				return error;
+-			return get_serial_info(info,
+-					       (struct serial_struct *) arg);
+-		case TIOCSSERIAL:
+-			return set_serial_info(info,
+-					       (struct serial_struct *) arg);
+-		case TIOCSERGETLSR: /* Get line status register */
+-			error = verify_area(VERIFY_WRITE, (void *) arg,
+-				sizeof(unsigned int));
+-			if (error)
+-				return error;
+-			else
+-			    return get_lsr_info(info, (unsigned int *) arg);
++	case TIOCGSERIAL:
++		error = verify_area(VERIFY_WRITE, (void *)arg,
++				    sizeof(struct serial_struct));
++		if (error)
++			return error;
++		return get_serial_info(info, (struct serial_struct *)arg);
++
++	case TIOCSSERIAL:
++		return set_serial_info(info, (struct serial_struct *)arg);
++
++	case TIOCSERGETLSR:			/* Get line status register */
++		error = verify_area(VERIFY_WRITE, (void *)arg,
++				    sizeof(unsigned int));
++		if (error)
++			return error;
++		else
++			return get_lsr_info(info, (unsigned int *)arg);
++
++	case TIOCSERGSTRUCT:
++		error = verify_area(VERIFY_WRITE, (void *)arg,
++				    sizeof(struct dec_serial));
++		if (error)
++			return error;
++		copy_from_user((struct dec_serial *)arg, info,
++			       sizeof(struct dec_serial));
++		return 0;
+ 
+-		case TIOCSERGSTRUCT:
+-			error = verify_area(VERIFY_WRITE, (void *) arg,
+-						sizeof(struct dec_serial));
+-			if (error)
+-				return error;
+-			copy_from_user((struct dec_serial *) arg,
+-				       info, sizeof(struct dec_serial));
+-			return 0;
+-			
+-		default:
+-			return -ENOIOCTLCMD;
+-		}
++	default:
++		return -ENOIOCTLCMD;
++	}
+ 	return 0;
+ }
+ 
+@@ -1317,7 +1290,7 @@ static void rs_set_termios(struct tty_st
+ /*
+  * ------------------------------------------------------------
+  * rs_close()
+- * 
++ *
+  * This routine is called when the serial port gets closed.
+  * Wait for the last remaining data to be sent.
+  * ------------------------------------------------------------
+@@ -1329,14 +1302,14 @@ static void rs_close(struct tty_struct *
+ 
+ 	if (!info || serial_paranoia_check(info, tty->name, "rs_close"))
+ 		return;
+-	
++
+ 	save_flags(flags); cli();
+-	
++
+ 	if (tty_hung_up_p(filp)) {
+ 		restore_flags(flags);
+ 		return;
+ 	}
+-	
++
+ #ifdef SERIAL_DEBUG_OPEN
+ 	printk("rs_close ttyS%d, count = %d\n", info->line, info->count);
+ #endif
+@@ -1363,7 +1336,7 @@ static void rs_close(struct tty_struct *
+ 	}
+ 	info->flags |= ZILOG_CLOSING;
+ 	/*
+-	 * Now we wait for the transmit buffer to clear; and we notify 
++	 * Now we wait for the transmit buffer to clear; and we notify
+ 	 * the line discipline to only process XON/XOFF characters.
+ 	 */
+ 	tty->closing = 1;
+@@ -1411,7 +1384,8 @@ static void rs_close(struct tty_struct *
+ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+ {
+ 	struct dec_serial *info = (struct dec_serial *) tty->driver_data;
+-	unsigned long orig_jiffies, char_time;
++	unsigned long orig_jiffies;
++	int char_time;
+ 
+ 	if (serial_paranoia_check(info, tty->name, "rs_wait_until_sent"))
+ 		return;
+@@ -1427,7 +1401,7 @@ static void rs_wait_until_sent(struct tt
+ 	if (char_time == 0)
+ 		char_time = 1;
+ 	if (timeout)
+-		char_time = min_t(unsigned long, char_time, timeout);
++		char_time = min(char_time, timeout);
+ 	while ((read_zsreg(info->zs_channel, 1) & Tx_BUF_EMP) == 0) {
+ 		current->state = TASK_INTERRUPTIBLE;
+ 		schedule_timeout(char_time);
+@@ -1485,11 +1459,6 @@ static int block_til_ready(struct tty_st
+ 	}
+ 
+ 	/*
+-	 * If this is a callout device, then just make sure the normal
+-	 * device isn't being used.
+-	 */
+-	
+-	/*
+ 	 * If non-blocking mode is set, or the port is not enabled,
+ 	 * then make the check up front and then exit.
+ 	 */
+@@ -1516,7 +1485,7 @@ static int block_til_ready(struct tty_st
+ 	       info->line, info->count);
+ #endif
+ 	cli();
+-	if (!tty_hung_up_p(filp)) 
++	if (!tty_hung_up_p(filp))
+ 		info->count--;
+ 	sti();
+ 	info->blocked_open++;
+@@ -1532,7 +1501,7 @@ static int block_til_ready(struct tty_st
+ 			if (info->flags & ZILOG_HUP_NOTIFY)
+ 				retval = -EAGAIN;
+ 			else
+-				retval = -ERESTARTSYS;	
++				retval = -ERESTARTSYS;
+ #else
+ 			retval = -EAGAIN;
+ #endif
+@@ -1564,7 +1533,7 @@ static int block_til_ready(struct tty_st
+ 		return retval;
+ 	info->flags |= ZILOG_NORMAL_ACTIVE;
+ 	return 0;
+-}	
++}
+ 
+ /*
+  * This routine is called whenever a serial port is opened.  It
+@@ -1626,7 +1595,7 @@ int rs_open(struct tty_struct *tty, stru
+ 		return retval;
+ 	}
+ 
+-#ifdef CONFIG_SERIAL_CONSOLE
++#ifdef CONFIG_SERIAL_DEC_CONSOLE
+ 	if (sercons.cflag && sercons.index == line) {
+ 		tty->termios->c_cflag = sercons.cflag;
+ 		sercons.cflag = 0;
+@@ -1645,7 +1614,7 @@ int rs_open(struct tty_struct *tty, stru
+ 
+ static void __init show_serial_version(void)
+ {
+-	printk("DECstation Z8530 serial driver version 0.05\n");
++	printk("DECstation Z8530 serial driver version 0.09\n");
+ }
+ 
+ /*  Initialize Z8530s zs_channels
+@@ -1655,6 +1624,7 @@ static void __init probe_sccs(void)
+ {
+ 	struct dec_serial **pp;
+ 	int i, n, n_chips = 0, n_channels, chip, channel;
++	unsigned long flags;
+ 
+ 	/*
+ 	 * did we get here by accident?
+@@ -1663,7 +1633,7 @@ static void __init probe_sccs(void)
+ 		printk("Not on JUNKIO machine, skipping probe_sccs\n");
+ 		return;
+ 	}
+-	
++
+ 	/*
+ 	 * When serial console is activated, tc_init has not been called yet
+ 	 * and system_base is undefined. Unfortunately we have to hardcode
+@@ -1672,27 +1642,25 @@ static void __init probe_sccs(void)
+ 	switch(mips_machtype) {
+ #ifdef CONFIG_MACH_DECSTATION
+ 	case MACH_DS5000_2X0:
+-		system_base = 0xbf800000;
++	case MACH_DS5900:
++		system_base = KSEG1ADDR(0x1f800000);
+ 		n_chips = 2;
+ 		zs_parms = &ds_parms;
++		zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
++		zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
+ 		break;
+ 	case MACH_DS5000_1XX:
+-		system_base = 0xbc000000;
++		system_base = KSEG1ADDR(0x1c000000);
+ 		n_chips = 2;
+ 		zs_parms = &ds_parms;
++		zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
++		zs_parms->irq1 = dec_interrupt[DEC_IRQ_SCC1];
+ 		break;
+ 	case MACH_DS5000_XX:
+-		system_base = 0xbc000000;
++		system_base = KSEG1ADDR(0x1c000000);
+ 		n_chips = 1;
+ 		zs_parms = &ds_parms;
+-		break;
+-#endif
+-#ifdef CONFIG_BAGET_MIPS
+-	case MACH_BAGET202:
+-		system_base = UNI_IO_BASE;
+-		n_chips = 2;
+-		zs_parms = &baget_parms;
+-		zs_init_regs[2] = 0x8;
++		zs_parms->irq0 = dec_interrupt[DEC_IRQ_SCC0];
+ 		break;
+ #endif
+ 	default:
+@@ -1710,15 +1678,15 @@ static void __init probe_sccs(void)
+ 			/*
+ 			 * The sccs reside on the high byte of the 16 bit IOBUS
+ 			 */
+-			zs_channels[n_channels].control = 
+-				(volatile unsigned char *)system_base + 
+-			  (0 == chip ? zs_parms->scc0 : zs_parms->scc1) + 
+-			  (0 == channel ? zs_parms->channel_a_offset : 
++			zs_channels[n_channels].control =
++				(volatile unsigned char *)system_base +
++			  (0 == chip ? zs_parms->scc0 : zs_parms->scc1) +
++			  (0 == channel ? zs_parms->channel_a_offset :
+ 			                  zs_parms->channel_b_offset);
+-			zs_channels[n_channels].data = 
++			zs_channels[n_channels].data =
+ 				zs_channels[n_channels].control + 4;
+ 
+-#ifndef CONFIG_SERIAL_CONSOLE
++#ifndef CONFIG_SERIAL_DEC_CONSOLE
+ 			/*
+ 			 * We're called early and memory managment isn't up, yet.
+ 			 * Thus check_region would fail.
+@@ -1729,20 +1697,24 @@ static void __init probe_sccs(void)
+ 				panic("SCC I/O region is not free");
+ #endif
+ 			zs_soft[n_channels].zs_channel = &zs_channels[n_channels];
+-			zs_soft[n_channels].irq = zs_parms->irq;
++			/* HACK alert! */
++			if (!(chip & 1))
++				zs_soft[n_channels].irq = zs_parms->irq0;
++			else
++				zs_soft[n_channels].irq = zs_parms->irq1;
+ 
+-			/* 
++			/*
+ 			 *  Identification of channel A. Location of channel A
+                          *  inside chip depends on mapping of internal address
+ 			 *  the chip decodes channels by.
+-			 *  CHANNEL_A_NR returns either 0 (in case of 
++			 *  CHANNEL_A_NR returns either 0 (in case of
+ 			 *  DECstations) or 1 (in case of Baget).
+ 			 */
+ 			if (CHANNEL_A_NR == channel)
+-				zs_soft[n_channels].zs_chan_a = 
++				zs_soft[n_channels].zs_chan_a =
+ 				    &zs_channels[n_channels+1-2*CHANNEL_A_NR];
+ 			else
+-				zs_soft[n_channels].zs_chan_a = 
++				zs_soft[n_channels].zs_chan_a =
+ 				    &zs_channels[n_channels];
+ 
+ 			*pp = &zs_soft[n_channels];
+@@ -1760,16 +1732,17 @@ static void __init probe_sccs(void)
+ 		}
+ 	}
+ 
+-/*	save_and_cli(flags);
++	save_and_cli(flags);
+ 	for (n = 0; n < zs_channels_found; n++) {
+-		if (((int)zs_channels[n].control & 0xf) == 1) {
++		if (n % 2 == 0) {
+ 			write_zsreg(zs_soft[n].zs_chan_a, R9, FHWRES);
+-			mdelay(10);
++			udelay(10);
+ 			write_zsreg(zs_soft[n].zs_chan_a, R9, 0);
+ 		}
+-		load_zsregs(zs_soft[n].zs_channel, zs_soft[n].zs_channel->curregs);
+-	} 
+-	restore_flags(flags); */
++		load_zsregs(zs_soft[n].zs_channel,
++			    zs_soft[n].zs_channel->curregs);
++	}
++	restore_flags(flags);
+ }
+ 
+ static struct tty_operations serial_ops = {
+@@ -1797,7 +1770,6 @@ static struct tty_operations serial_ops 
+ int __init zs_init(void)
+ {
+ 	int channel, i;
+-	unsigned long flags;
+ 	struct dec_serial *info;
+ 
+ 	if(!BUS_PRESENT)
+@@ -1809,7 +1781,6 @@ int __init zs_init(void)
+ 	/* Find out how many Z8530 SCCs we have */
+ 	if (zs_chain == 0)
+ 		probe_sccs();
+-
+ 	serial_driver = alloc_tty_driver(zs_channels_found);
+ 	if (!serial_driver)
+ 		return -ENOMEM;
+@@ -1833,39 +1804,25 @@ int __init zs_init(void)
+ 	tty_set_operations(serial_driver, &serial_ops);
+ 
+ 	if (tty_register_driver(serial_driver))
+-		panic("Couldn't register serial driver\n");
+-
+-	save_flags(flags); cli();
+-
+-	for (channel = 0; channel < zs_channels_found; ++channel) {
+-		if (zs_soft[channel].hook &&
+-		    zs_soft[channel].hook->init_channel)
+-			(*zs_soft[channel].hook->init_channel)
+-				(&zs_soft[channel]);
++		panic("Couldn't register serial driver");
+ 
+-		zs_soft[channel].clk_divisor = 16;
+-		zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);
++	for (info = zs_chain, i = 0; info; info = info->zs_next, i++) {
+ 
+-		if (request_irq(zs_parms->irq, rs_interrupt, SA_SHIRQ,
+-				"SCC", &zs_soft[channel]))
+-			printk(KERN_ERR "decserial: can't get irq %d\n",
+-			       zs_parms->irq);
+-	}
++		/* Needed before interrupts are enabled. */
++		info->tty = 0;
++		info->x_char = 0;
+ 
+-	for (info = zs_chain, i = 0; info; info = info->zs_next, i++)
+-	{
+ 		if (info->hook && info->hook->init_info) {
+ 			(*info->hook->init_info)(info);
+ 			continue;
+ 		}
++
+ 		info->magic = SERIAL_MAGIC;
+ 		info->port = (int) info->zs_channel->control;
+ 		info->line = i;
+-		info->tty = 0;
+ 		info->custom_divisor = 16;
+ 		info->close_delay = 50;
+ 		info->closing_wait = 3000;
+-		info->x_char = 0;
+ 		info->event = 0;
+ 		info->count = 0;
+ 		info->blocked_open = 0;
+@@ -1873,94 +1830,83 @@ int __init zs_init(void)
+ 		info->tqueue.data = info;
+ 		init_waitqueue_head(&info->open_wait);
+ 		init_waitqueue_head(&info->close_wait);
+-		printk("ttyS%d at 0x%08x (irq = %d)", info->line,
+-		       info->port, info->irq);
+-		printk(" is a Z85C30 SCC\n");
++		printk("ttyS%02d at 0x%08x (irq = %d) is a Z85C30 SCC\n",
++		       info->line, info->port, info->irq);
+ 		tty_register_device(serial_driver, info->line, NULL);
++
+ 	}
+ 
+-	restore_flags(flags);
++	for (channel = 0; channel < zs_channels_found; ++channel) {
++		zs_soft[channel].clk_divisor = 16;
++		zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);
+ 
+-	return 0;
+-}
++		if (request_irq(zs_soft[channel].irq, rs_interrupt, SA_SHIRQ,
++				"scc", &zs_soft[channel]))
++			printk(KERN_ERR "decserial: can't get irq %d\n",
++			       zs_soft[channel].irq);
+ 
+-/*
+- * register_serial and unregister_serial allows for serial ports to be
+- * configured at run-time, to support PCMCIA modems.
+- */
+-/* PowerMac: Unused at this time, just here to make things link. */
+-int register_serial(struct serial_struct *req)
+-{
+-	return -1;
+-}
++		if (zs_soft[channel].hook) {
++			zs_startup(&zs_soft[channel]);
++			if (zs_soft[channel].hook->init_channel)
++				(*zs_soft[channel].hook->init_channel)
++					(&zs_soft[channel]);
++		}
++	}
+ 
+-void unregister_serial(int line)
+-{
+-	return;
++	return 0;
+ }
+ 
+ /*
+  * polling I/O routines
+  */
+ static int
+-zs_poll_tx_char(struct dec_serial *info, unsigned char ch)
++zs_poll_tx_char(void *handle, unsigned char ch)
+ {
++	struct dec_serial *info = handle;
+ 	struct dec_zschannel *chan = info->zs_channel;
+ 	int    ret;
+ 
+ 	if(chan) {
+ 		int loops = 10000;
+-//		int nine = read_zsreg(chan, R9);
+-
+-		RECOVERY_DELAY;
+-//        	write_zsreg(chan, R9, nine & ~MIE);
+-               	wbflush();
+-		RECOVERY_DELAY;
+-
+-        	while (!(*(chan->control) & Tx_BUF_EMP) && --loops)
+-	        	RECOVERY_DELAY;
+-
+-                if (loops) {
+-                        ret = 0;
+-        	        *(chan->data) = ch;
+-                	wbflush();
+-			RECOVERY_DELAY;
+-                } else
+-                        ret = -EAGAIN;
+ 
+-//        	write_zsreg(chan, R9, nine);
+-               	wbflush();
+-		RECOVERY_DELAY;
++		while (loops && !(read_zsreg(chan, 0) & Tx_BUF_EMP))
++			loops--;
+ 
+-                return ret;
+-        }
++		if (loops) {
++			write_zsdata(chan, ch);
++			ret = 0;
++		} else
++			ret = -EAGAIN;
+ 
+-	return -ENODEV;
++		return ret;
++	} else
++		return -ENODEV;
+ }
+ 
+ static int
+-zs_poll_rx_char(struct dec_serial *info)
++zs_poll_rx_char(void *handle)
+ {
++	struct dec_serial *info = handle;
+         struct dec_zschannel *chan = info->zs_channel;
+         int    ret;
+ 
+ 	if(chan) {
+                 int loops = 10000;
+ 
+-                while((read_zsreg(chan, 0) & Rx_CH_AV) == 0)
+-		        loops--;
++		while (loops && !(read_zsreg(chan, 0) & Rx_CH_AV))
++			loops--;
+ 
+                 if (loops)
+                         ret = read_zsdata(chan);
+                 else
+                         ret = -EAGAIN;
+ 
+-                return ret;
+-        } else
+-                return -ENODEV;
++		return ret;
++	} else
++		return -ENODEV;
+ }
+ 
+-unsigned int register_zs_hook(unsigned int channel, struct zs_hook *hook)
++int register_zs_hook(unsigned int channel, struct dec_serial_hook *hook)
+ {
+ 	struct dec_serial *info = &zs_soft[channel];
+ 
+@@ -1970,22 +1916,15 @@ unsigned int register_zs_hook(unsigned i
+ 
+ 		return 0;
+ 	} else {
+-		info->hook = hook;
+-
+-		if (zs_chain == 0)
+-			probe_sccs();
+-
+-		if (!(info->flags & ZILOG_INITIALIZED))
+-			zs_startup(info);
+-
+ 		hook->poll_rx_char = zs_poll_rx_char;
+ 		hook->poll_tx_char = zs_poll_tx_char;
++		info->hook = hook;
+ 
+ 		return 1;
+ 	}
+ }
+ 
+-unsigned int unregister_zs_hook(unsigned int channel)
++int unregister_zs_hook(unsigned int channel)
+ {
+ 	struct dec_serial *info = &zs_soft[channel];
+ 
+@@ -2004,7 +1943,7 @@ unsigned int unregister_zs_hook(unsigned
+  * Serial console driver
+  * ------------------------------------------------------------
+  */
+-#ifdef CONFIG_SERIAL_CONSOLE
++#ifdef CONFIG_SERIAL_DEC_CONSOLE
+ 
+ 
+ /*
+@@ -2041,11 +1980,13 @@ static struct tty_driver *serial_console
+ static int __init serial_console_setup(struct console *co, char *options)
+ {
+ 	struct dec_serial *info;
+-	int	baud = 9600;
+-	int	bits = 8;
+-	int	parity = 'n';
+-	int	cflag = CREAD | HUPCL | CLOCAL;
+-	char	*s;
++	int baud = 9600;
++	int bits = 8;
++	int parity = 'n';
++	int cflag = CREAD | HUPCL | CLOCAL;
++	int clk_divisor = 16;
++	int brg;
++	char *s;
+ 	unsigned long flags;
+ 
+ 	if(!BUS_PRESENT)
+@@ -2097,6 +2038,10 @@ static int __init serial_console_setup(s
+ 	case 9600:
+ 	default:
+ 		cflag |= B9600;
++		/*
++		 * Set this to a sane value to prevent a divide error.
++		 */
++		baud  = 9600;
+ 		break;
+ 	}
+ 	switch(bits) {
+@@ -2117,43 +2062,64 @@ static int __init serial_console_setup(s
+ 		break;
+ 	}
+ 	co->cflag = cflag;
+-#if 1 
++
+ 	save_and_cli(flags);
+ 
+ 	/*
++	 * Set up the baud rate generator.
++	 */
++	brg = BPS_TO_BRG(baud, zs_parms->clock / clk_divisor);
++	info->zs_channel->curregs[R12] = (brg & 255);
++	info->zs_channel->curregs[R13] = ((brg >> 8) & 255);
++
++	/*
++	 * Set byte size and parity.
++	 */
++	if (bits == 7) {
++		info->zs_channel->curregs[R3] |= Rx7;
++		info->zs_channel->curregs[R5] |= Tx7;
++	} else {
++		info->zs_channel->curregs[R3] |= Rx8;
++		info->zs_channel->curregs[R5] |= Tx8;
++	}
++	if (cflag & PARENB) {
++		info->zs_channel->curregs[R4] |= PAR_ENA;
++	}
++	if (!(cflag & PARODD)) {
++		info->zs_channel->curregs[R4] |= PAR_EVEN;
++	}
++	info->zs_channel->curregs[R4] |= SB1;
++
++	/*
+ 	 * Turn on RTS and DTR.
+ 	 */
+ 	zs_rtsdtr(info, RTS | DTR, 1);
+ 
+ 	/*
+-	 * Finally, enable sequencing
++	 * Finally, enable sequencing.
+ 	 */
+-	info->zs_channel->curregs[3] |= (RxENABLE | Rx8);
+-	info->zs_channel->curregs[5] |= (TxENAB | Tx8);
+-	info->zs_channel->curregs[9] |= (VIS);
+-	write_zsreg(info->zs_channel, 3, info->zs_channel->curregs[3]);
+-	write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]);
+-	write_zsreg(info->zs_channel, 9, info->zs_channel->curregs[9]);
++	info->zs_channel->curregs[R3] |= RxENABLE;
++	info->zs_channel->curregs[R5] |= TxENAB;
+ 
+ 	/*
+ 	 * Clear the interrupt registers.
+ 	 */
+-	write_zsreg(info->zs_channel, 0, ERR_RES);
+-	write_zsreg(info->zs_channel, 0, RES_H_IUS);
++	write_zsreg(info->zs_channel, R0, ERR_RES);
++	write_zsreg(info->zs_channel, R0, RES_H_IUS);
+ 
+ 	/*
+-	 * Set the speed of the serial port
++	 * Load up the new values.
+ 	 */
+-	change_speed(info);
++	load_zsregs(info->zs_channel, info->zs_channel->curregs);
+ 
+ 	/* Save the current value of RR0 */
+-	info->read_reg_zero = read_zsreg(info->zs_channel, 0);
++	info->read_reg_zero = read_zsreg(info->zs_channel, R0);
+ 
+-	zs_soft[co->index].clk_divisor = 16;
++	zs_soft[co->index].clk_divisor = clk_divisor;
+ 	zs_soft[co->index].zs_baud = get_zsbaud(&zs_soft[co->index]);
+ 
+ 	restore_flags(flags);
+-#endif
++
+ 	return 0;
+ }
+ 
+@@ -2173,7 +2139,7 @@ void __init zs_serial_console_init(void)
+ {
+ 	register_console(&sercons);
+ }
+-#endif /* ifdef CONFIG_SERIAL_CONSOLE */
++#endif /* ifdef CONFIG_SERIAL_DEC_CONSOLE */
+ 
+ #ifdef CONFIG_KGDB
+ struct dec_zschannel *zs_kgdbchan;
+@@ -2211,7 +2177,7 @@ void kgdb_interruptible(int yes)
+ 	int one, nine;
+ 	nine = read_zsreg(chan, 9);
+ 	if (yes == 1) {
+-		one = EXT_INT_ENAB|INT_ALL_Rx;
++		one = EXT_INT_ENAB|RxINT_ALL;
+ 		nine |= MIE;
+ 		printk("turning serial ints on\n");
+ 	} else {
+@@ -2223,22 +2189,23 @@ void kgdb_interruptible(int yes)
+ 	write_zsreg(chan, 9, nine);
+ }
+ 
+-static int kgdbhook_init_channel(struct dec_serial* info) 
++static int kgdbhook_init_channel(void *handle)
+ {
+ 	return 0;
+ }
+ 
+-static void kgdbhook_init_info(struct dec_serial* info)
++static void kgdbhook_init_info(void *handle)
+ {
+ }
+ 
+-static void kgdbhook_rx_char(struct dec_serial* info, 
+-			     unsigned char ch, unsigned char stat)
++static void kgdbhook_rx_char(void *handle, unsigned char ch, unsigned char fl)
+ {
++	struct dec_serial *info = handle;
++
++	if (fl != TTY_NORMAL)
++		return;
+ 	if (ch == 0x03 || ch == '$')
+ 		breakpoint();
+-	if (stat & (Rx_OVR|FRM_ERR|PAR_ERR))
+-		write_zsreg(info->zs_channel, 0, ERR_RES);
+ }
+ 
+ /* This sets up the serial port we're using, and turns on
+@@ -2264,11 +2231,11 @@ static inline void kgdb_chaninit(struct 
+  * for /dev/ttyb which is determined in setup_arch() from the
+  * boot command line flags.
+  */
+-struct zs_hook zs_kgdbhook = {
+-	init_channel : kgdbhook_init_channel,
+-	init_info    : kgdbhook_init_info,
+-	cflags       : B38400|CS8|CLOCAL,
+-	rx_char      : kgdbhook_rx_char,
++struct dec_serial_hook zs_kgdbhook = {
++	.init_channel	= kgdbhook_init_channel,
++	.init_info	= kgdbhook_init_info,
++	.rx_char	= kgdbhook_rx_char,
++	.cflags		= B38400 | CS8 | CLOCAL,
+ }
+ 
+ void __init zs_kgdb_hook(int tty_num)
+diff -urpNX dontdiff linux-2.6.10/drivers/tc/zs.h linux-2.6.10-mips/drivers/tc/zs.h
+--- linux-2.6.10/drivers/tc/zs.h	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/drivers/tc/zs.h	2004-09-21 13:11:11.000000000 +0200
+@@ -1,14 +1,18 @@
+ /*
+- * macserial.h: Definitions for the Macintosh Z8530 serial driver.
++ * drivers/tc/zs.h: Definitions for the DECstation Z85C30 serial driver.
+  *
+  * Adapted from drivers/sbus/char/sunserial.h by Paul Mackerras.
++ * Adapted from drivers/macintosh/macserial.h by Harald Koerfgen.
+  *
+  * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras at cs.anu.edu.au)
+  * Copyright (C) 1995 David S. Miller (davem at caip.rutgers.edu)
++ * Copyright (C) 2004  Maciej W. Rozycki
+  */
+ #ifndef _DECSERIAL_H
+ #define _DECSERIAL_H
+ 
++#include <asm/dec/serial.h>
++
+ #define NUM_ZSREGS    16
+ 
+ struct serial_struct {
+@@ -89,61 +93,48 @@ struct dec_zschannel {
+ 	unsigned char curregs[NUM_ZSREGS];
+ };
+ 
+-struct dec_serial;
+-
+-struct zs_hook {
+-	int (*init_channel)(struct dec_serial* info);
+-	void (*init_info)(struct dec_serial* info);
+-	void (*rx_char)(unsigned char ch, unsigned char stat);
+-	int  (*poll_rx_char)(struct dec_serial* info);
+-	int  (*poll_tx_char)(struct dec_serial* info,
+-			     unsigned char ch);
+-	unsigned cflags;
+-};
+-
+ struct dec_serial {
+-	struct dec_serial *zs_next;	/* For IRQ servicing chain */
+-	struct dec_zschannel *zs_channel; /* Channel registers */
+-	struct dec_zschannel *zs_chan_a;	/* A side registers */
+-	unsigned char read_reg_zero;
+-
+-	char soft_carrier;  /* Use soft carrier on this channel */
+-	char break_abort;   /* Is serial console in, so process brk/abrt */
+-	struct zs_hook *hook;  /* Hook on this channel */
+-	char is_cons;       /* Is this our console. */
+-	unsigned char tx_active; /* character is being xmitted */
+-	unsigned char tx_stopped; /* output is suspended */
+-
+-	/* We need to know the current clock divisor
+-	 * to read the bps rate the chip has currently
+-	 * loaded.
++	struct dec_serial	*zs_next;	/* For IRQ servicing chain.  */
++	struct dec_zschannel	*zs_channel;	/* Channel registers.  */
++	struct dec_zschannel	*zs_chan_a;	/* A side registers.  */
++	unsigned char		read_reg_zero;
++
++	struct dec_serial_hook	*hook;		/* Hook on this channel.  */
++	int			tty_break;	/* Set on BREAK condition.  */
++	int			is_cons;	/* Is this our console.  */
++	int			tx_active;	/* Char is being xmitted.  */
++	int			tx_stopped;	/* Output is suspended.  */
++
++	/*
++	 * We need to know the current clock divisor
++	 * to read the bps rate the chip has currently loaded.
+ 	 */
+-	unsigned char clk_divisor;  /* May be 1, 16, 32, or 64 */
+-	int zs_baud;
++	int			clk_divisor;	/* May be 1, 16, 32, or 64.  */
++	int			zs_baud;
+ 
+-	char change_needed;
++	char			change_needed;
+ 
+ 	int			magic;
+ 	int			baud_base;
+ 	int			port;
+ 	int			irq;
+-	int			flags; 		/* defined in tty.h */
+-	int			type; 		/* UART type */
++	int			flags; 		/* Defined in tty.h.  */
++	int			type; 		/* UART type.  */
+ 	struct tty_struct 	*tty;
+ 	int			read_status_mask;
+ 	int			ignore_status_mask;
+ 	int			timeout;
+ 	int			xmit_fifo_size;
+ 	int			custom_divisor;
+-	int			x_char;	/* xon/xoff character */
++	int			x_char;		/* XON/XOFF character.  */
+ 	int			close_delay;
+ 	unsigned short		closing_wait;
+ 	unsigned short		closing_wait2;
+ 	unsigned long		event;
+ 	unsigned long		last_active;
+ 	int			line;
+-	int			count;	    /* # of fd on device */
+-	int			blocked_open; /* # of blocked opens */
++	int			count;		/* # of fds on device.  */
++	int			blocked_open;	/* # of blocked opens.  */
+ 	unsigned char 		*xmit_buf;
+ 	int			xmit_head;
+ 	int			xmit_tail;
+@@ -219,8 +210,9 @@ struct dec_serial {
+ 
+ #define	RxINT_DISAB	0	/* Rx Int Disable */
+ #define	RxINT_FCERR	0x8	/* Rx Int on First Character Only or Error */
+-#define	INT_ALL_Rx	0x10	/* Int on all Rx Characters or error */
+-#define	INT_ERR_Rx	0x18	/* Int on error only */
++#define	RxINT_ALL	0x10	/* Int on all Rx Characters or error */
++#define	RxINT_ERR	0x18	/* Int on error only */
++#define	RxINT_MASK	0x18
+ 
+ #define	WT_RDY_RT	0x20	/* Wait/Ready on R/T */
+ #define	WT_FN_RDYFN	0x40	/* Wait/FN/Ready FN */
+diff -urpNX dontdiff linux-2.6.10/drivers/usb/gadget/net2280.c linux-2.6.10-mips/drivers/usb/gadget/net2280.c
+--- linux-2.6.10/drivers/usb/gadget/net2280.c	2004-12-24 22:33:51.000000000 +0100
++++ linux-2.6.10-mips/drivers/usb/gadget/net2280.c	2004-11-19 01:14:48.000000000 +0100
+@@ -437,7 +437,8 @@ net2280_free_request (struct usb_ep *_ep
+ #elif	defined(CONFIG_PPC) && !defined(CONFIG_NOT_COHERENT_CACHE)
+ #define USE_KMALLOC
+ 
+-#elif	defined(CONFIG_MIPS) && !defined(CONFIG_NONCOHERENT_IO)
++#elif	defined(CONFIG_MIPS) && \
++	(defined(CONFIG_DMA_COHERENT) || defined(CONFIG_DMA_IP27))
+ #define USE_KMALLOC
+ 
+ /* FIXME there are other cases, including an x86-64 one ...  */
+diff -urpNX dontdiff linux-2.6.10/drivers/usb/host/ohci-au1xxx.c linux-2.6.10-mips/drivers/usb/host/ohci-au1xxx.c
+--- linux-2.6.10/drivers/usb/host/ohci-au1xxx.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/usb/host/ohci-au1xxx.c	2004-11-22 03:33:52.000000000 +0100
+@@ -0,0 +1,372 @@
++/*
++ * OHCI HCD (Host Controller Driver) for USB.
++ *
++ * (C) Copyright 1999 Roman Weissgaerber <weissg at vienna.at>
++ * (C) Copyright 2000-2002 David Brownell <dbrownell at users.sourceforge.net>
++ * (C) Copyright 2002 Hewlett-Packard Company
++ *
++ * Bus Glue for AMD Alchemy Au1xxx
++ *
++ * Written by Christopher Hoover <ch at hpl.hp.com>
++ * Based on fragments of previous driver by Rusell King et al.
++ *
++ * Modified for LH7A404 from ohci-sa1111.c
++ *  by Durgesh Pattamatta <pattamattad at sharpsec.com>
++ * Modified for AMD Alchemy Au1xxx
++ *  by Matt Porter <mporter at kernel.crashing.org>
++ *
++ * This file is licenced under the GPL.
++ */
++
++#include <asm/mach-au1x00/au1000.h>
++
++#define USBH_ENABLE_BE (1<<0)
++#define USBH_ENABLE_C  (1<<1)
++#define USBH_ENABLE_E  (1<<2)
++#define USBH_ENABLE_CE (1<<3)
++#define USBH_ENABLE_RD (1<<4)
++
++#ifdef __LITTLE_ENDIAN
++#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C)
++#elif __BIG_ENDIAN
++#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | USBH_ENABLE_BE)
++#else
++#error not byte order defined
++#endif
++
++extern int usb_disabled(void);
++
++/*-------------------------------------------------------------------------*/
++
++static void au1xxx_start_hc(struct platform_device *dev)
++{
++	printk(KERN_DEBUG __FILE__
++		": starting Au1xxx OHCI USB Controller\n");
++
++	/* enable host controller */
++	au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG);
++	udelay(1000);
++	au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG);
++	udelay(1000);
++
++	/* wait for reset complete (read register twice; see au1500 errata) */
++	while (au_readl(USB_HOST_CONFIG),
++		!(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD)) 
++		udelay(1000);
++
++	printk(KERN_DEBUG __FILE__
++	": Clock to USB host has been enabled \n");
++}
++
++static void au1xxx_stop_hc(struct platform_device *dev)
++{
++	printk(KERN_DEBUG __FILE__
++	       ": stopping Au1xxx OHCI USB Controller\n");
++
++	/* Disable clock */
++	au_writel(readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
++}
++
++
++/*-------------------------------------------------------------------------*/
++
++
++static irqreturn_t usb_hcd_au1xxx_hcim_irq (int irq, void *__hcd,
++					     struct pt_regs * r)
++{
++	struct usb_hcd *hcd = __hcd;
++
++	return usb_hcd_irq(irq, hcd, r);
++}
++
++/*-------------------------------------------------------------------------*/
++
++void usb_hcd_au1xxx_remove (struct usb_hcd *, struct platform_device *);
++
++/* configure so an HC device and id are always provided */
++/* always called with process context; sleeping is OK */
++
++
++/**
++ * usb_hcd_au1xxx_probe - initialize Au1xxx-based HCDs
++ * Context: !in_interrupt()
++ *
++ * Allocates basic resources for this USB host controller, and
++ * then invokes the start() method for the HCD associated with it
++ * through the hotplug entry's driver_data.
++ *
++ */
++int usb_hcd_au1xxx_probe (const struct hc_driver *driver,
++			  struct usb_hcd **hcd_out,
++			  struct platform_device *dev)
++{
++	int retval;
++	struct usb_hcd *hcd = 0;
++
++	unsigned int *addr = NULL;
++
++	if (!request_mem_region(dev->resource[0].start,
++				dev->resource[0].end
++				- dev->resource[0].start + 1, hcd_name)) {
++		pr_debug("request_mem_region failed");
++		return -EBUSY;
++	}
++	
++	au1xxx_start_hc(dev);
++	
++	addr = ioremap(dev->resource[0].start,
++		       dev->resource[0].end
++		       - dev->resource[0].start + 1);
++	if (!addr) {
++		pr_debug("ioremap failed");
++		retval = -ENOMEM;
++		goto err1;
++	}
++	
++
++	hcd = driver->hcd_alloc ();
++	if (hcd == NULL){
++		pr_debug ("hcd_alloc failed");
++		retval = -ENOMEM;
++		goto err1;
++	}
++
++	if(dev->resource[1].flags != IORESOURCE_IRQ){
++		pr_debug ("resource[1] is not IORESOURCE_IRQ");
++		retval = -ENOMEM;
++		goto err1;
++	}
++
++	hcd->driver = (struct hc_driver *) driver;
++	hcd->description = driver->description;
++	hcd->irq = dev->resource[1].start;
++	hcd->regs = addr;
++	hcd->self.controller = &dev->dev;
++
++	retval = hcd_buffer_create (hcd);
++	if (retval != 0) {
++		pr_debug ("pool alloc fail");
++		goto err1;
++	}
++
++	retval = request_irq (hcd->irq, usb_hcd_au1xxx_hcim_irq, SA_INTERRUPT,
++			      hcd->description, hcd);
++	if (retval != 0) {
++		pr_debug("request_irq failed");
++		retval = -EBUSY;
++		goto err2;
++	}
++
++	pr_debug ("%s (Au1xxx) at 0x%p, irq %d",
++	     hcd->description, hcd->regs, hcd->irq);
++
++	usb_bus_init (&hcd->self);
++	hcd->self.op = &usb_hcd_operations;
++	hcd->self.hcpriv = (void *) hcd;
++	hcd->self.bus_name = "au1xxx";
++	hcd->product_desc = "Au1xxx OHCI";
++
++	INIT_LIST_HEAD (&hcd->dev_list);
++
++	usb_register_bus (&hcd->self);
++
++	if ((retval = driver->start (hcd)) < 0)
++	{
++		usb_hcd_au1xxx_remove(hcd, dev);
++		printk("bad driver->start\n");
++		return retval;
++	}
++
++	*hcd_out = hcd;
++	return 0;
++
++ err2:
++	hcd_buffer_destroy (hcd);
++ err1:
++	kfree(hcd);
++	au1xxx_stop_hc(dev);
++	release_mem_region(dev->resource[0].start,
++				dev->resource[0].end
++			   - dev->resource[0].start + 1);
++	return retval;
++}
++
++
++/* may be called without controller electrically present */
++/* may be called with controller, bus, and devices active */
++
++/**
++ * usb_hcd_au1xxx_remove - shutdown processing for Au1xxx-based HCDs
++ * @dev: USB Host Controller being removed
++ * Context: !in_interrupt()
++ *
++ * Reverses the effect of usb_hcd_au1xxx_probe(), first invoking
++ * the HCD's stop() method.  It is always called from a thread
++ * context, normally "rmmod", "apmd", or something similar.
++ *
++ */
++void usb_hcd_au1xxx_remove (struct usb_hcd *hcd, struct platform_device *dev)
++{
++	pr_debug ("remove: %s, state %x", hcd->self.bus_name, hcd->state);
++
++	if (in_interrupt ())
++		BUG ();
++
++	hcd->state = USB_STATE_QUIESCING;
++
++	pr_debug ("%s: roothub graceful disconnect", hcd->self.bus_name);
++	usb_disconnect (&hcd->self.root_hub);
++
++	hcd->driver->stop (hcd);
++	hcd->state = USB_STATE_HALT;
++
++	free_irq (hcd->irq, hcd);
++	hcd_buffer_destroy (hcd);
++
++	usb_deregister_bus (&hcd->self);
++
++	au1xxx_stop_hc(dev);
++	release_mem_region(dev->resource[0].start,
++			   dev->resource[0].end
++			   - dev->resource[0].start + 1);
++}
++
++/*-------------------------------------------------------------------------*/
++
++static int __devinit
++ohci_au1xxx_start (struct usb_hcd *hcd)
++{
++	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
++	int		ret;
++
++	ohci_dbg (ohci, "ohci_au1xxx_start, ohci:%p", ohci);
++			
++	if ((ret = ohci_init (ohci)) < 0)
++		return ret;
++
++	if ((ret = ohci_run (ohci)) < 0) {
++		err ("can't start %s", ohci->hcd.self.bus_name);
++		ohci_stop (hcd);
++		return ret;
++	}
++
++	return 0;
++}
++
++/*-------------------------------------------------------------------------*/
++
++static const struct hc_driver ohci_au1xxx_hc_driver = {
++	.description =		hcd_name,
++
++	/*
++	 * generic hardware linkage
++	 */
++	.irq =			ohci_irq,
++	.flags =		HCD_USB11,
++
++	/*
++	 * basic lifecycle operations
++	 */
++	.start =		ohci_au1xxx_start,
++#ifdef	CONFIG_PM
++	/* suspend:		ohci_au1xxx_suspend,  -- tbd */
++	/* resume:		ohci_au1xxx_resume,   -- tbd */
++#endif /*CONFIG_PM*/
++	.stop =			ohci_stop,
++
++	/*
++	 * memory lifecycle (except per-request)
++	 */
++	.hcd_alloc =		ohci_hcd_alloc,
++
++	/*
++	 * managing i/o requests and associated device resources
++	 */
++	.urb_enqueue =		ohci_urb_enqueue,
++	.urb_dequeue =		ohci_urb_dequeue,
++	.endpoint_disable =	ohci_endpoint_disable,
++
++	/*
++	 * scheduling support
++	 */
++	.get_frame_number =	ohci_get_frame,
++
++	/*
++	 * root hub support
++	 */
++	.hub_status_data =	ohci_hub_status_data,
++	.hub_control =		ohci_hub_control,
++};
++
++/*-------------------------------------------------------------------------*/
++
++static int ohci_hcd_au1xxx_drv_probe(struct device *dev)
++{
++	struct platform_device *pdev = to_platform_device(dev);
++	struct usb_hcd *hcd = NULL;
++	int ret;
++
++	pr_debug ("In ohci_hcd_au1xxx_drv_probe");
++
++	if (usb_disabled())
++		return -ENODEV;
++
++	ret = usb_hcd_au1xxx_probe(&ohci_au1xxx_hc_driver, &hcd, pdev);
++
++	if (ret == 0)
++		dev_set_drvdata(dev, hcd);
++
++	return ret;
++}
++
++static int ohci_hcd_au1xxx_drv_remove(struct device *dev)
++{
++	struct platform_device *pdev = to_platform_device(dev);
++	struct usb_hcd *hcd = dev_get_drvdata(dev);
++
++	usb_hcd_au1xxx_remove(hcd, pdev);
++	dev_set_drvdata(dev, NULL);
++	return 0;
++}
++	/*TBD*/
++/*static int ohci_hcd_au1xxx_drv_suspend(struct device *dev)
++{
++	struct platform_device *pdev = to_platform_device(dev);
++	struct usb_hcd *hcd = dev_get_drvdata(dev);
++
++	return 0;
++}
++static int ohci_hcd_au1xxx_drv_resume(struct device *dev)
++{
++	struct platform_device *pdev = to_platform_device(dev);
++	struct usb_hcd *hcd = dev_get_drvdata(dev);
++
++	return 0;
++}
++*/
++
++static struct device_driver ohci_hcd_au1xxx_driver = {
++	.name		= "au1xxx-ohci",
++	.bus		= &platform_bus_type,
++	.probe		= ohci_hcd_au1xxx_drv_probe,
++	.remove		= ohci_hcd_au1xxx_drv_remove,
++	/*.suspend	= ohci_hcd_au1xxx_drv_suspend, */
++	/*.resume	= ohci_hcd_au1xxx_drv_resume, */
++};
++
++static int __init ohci_hcd_au1xxx_init (void)
++{
++	pr_debug (DRIVER_INFO " (Au1xxx)");
++	pr_debug ("block sizes: ed %d td %d\n",
++		sizeof (struct ed), sizeof (struct td));
++
++	return driver_register(&ohci_hcd_au1xxx_driver);
++}
++
++static void __exit ohci_hcd_au1xxx_cleanup (void)
++{
++	driver_unregister(&ohci_hcd_au1xxx_driver);
++}
++
++module_init (ohci_hcd_au1xxx_init);
++module_exit (ohci_hcd_au1xxx_cleanup);
+diff -urpNX dontdiff linux-2.6.10/drivers/usb/host/ohci-hcd.c linux-2.6.10-mips/drivers/usb/host/ohci-hcd.c
+--- linux-2.6.10/drivers/usb/host/ohci-hcd.c	2004-12-24 22:33:52.000000000 +0100
++++ linux-2.6.10-mips/drivers/usb/host/ohci-hcd.c	2004-11-19 01:14:48.000000000 +0100
+@@ -896,25 +896,15 @@ MODULE_LICENSE ("GPL");
+ #include "ohci-lh7a404.c"
+ #endif
+ 
+-#ifdef CONFIG_PXA27x
+-#include "ohci-pxa27x.c"
++#ifdef CONFIG_SOC_AU1X00
++#include "ohci-au1xxx.c"
+ #endif
+ 
+ #if !(defined(CONFIG_PCI) \
+       || defined(CONFIG_SA1111) \
+       || defined(CONFIG_ARCH_OMAP) \
+       || defined (CONFIG_ARCH_LH7A404) \
+-      || defined (CONFIG_PXA27x) \
++      || defined (CONFIG_SOC_AU1X00) \
+ 	)
+ #error "missing bus glue for ohci-hcd"
+ #endif
+-
+-#if	!defined(HAVE_HNP) && defined(CONFIG_USB_OTG)
+-
+-#warning non-OTG configuration, too many HCDs
+-
+-static void start_hnp(struct ohci_hcd *ohci)
+-{
+-	/* "can't happen" */
+-}
+-#endif
+diff -urpNX dontdiff linux-2.6.10/drivers/video/Kconfig linux-2.6.10-mips/drivers/video/Kconfig
+--- linux-2.6.10/drivers/video/Kconfig	2004-12-24 22:33:49.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/Kconfig	2004-11-25 19:29:17.000000000 +0100
+@@ -939,6 +939,42 @@ config FB_PM3
+ 	  similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
+ 	  and maybe other boards.
+ 
++config FB_E1356
++	tristate "Epson SED1356 framebuffer support"
++	depends on FB && EXPERIMENTAL && PCI && MIPS
++
++config PB1000_CRT
++	bool "Use CRT on Pb1000 (J65)"
++	depends on MIPS_PB1000=y && FB_E1356
++
++config PB1000_NTSC
++	bool "Use Compsite NTSC on Pb1000 (J63)"
++	depends on MIPS_PB1000=y && FB_E1356
++
++config PB1000_TFT
++	bool "Use TFT Panel on Pb1000 (J64)"
++	depends on MIPS_PB1000=y && FB_E1356
++
++config PB1500_CRT
++	bool "Use CRT on Pb1500 " if MIPS_PB1500=y
++	depends on FB_E1356
++
++config PB1500_CRT
++	prompt "Use CRT on Pb1100 "
++	depends on FB_E1356 && MIPS_PB1100=y
++
++config PB1500_TFT
++	bool "Use TFT Panel on Pb1500 " if MIPS_PB1500=y
++	depends on FB_E1356
++
++config PB1500_TFT
++	prompt "Use TFT Panel on Pb1100 "
++	depends on FB_E1356 && MIPS_PB1100=y
++
++config FB_AU1100
++	bool "Au1100 LCD Driver"
++	depends on FB && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y
++
+ config FB_SBUS
+ 	bool "SBUS and UPA framebuffers"
+ 	depends on FB && (SPARC32 || SPARC64)
+@@ -998,29 +1034,35 @@ config FB_HIT
+ 	  This is the frame buffer device driver for the Hitachi HD64461 LCD
+ 	  frame buffer card.
+ 
++config FB_PMAG_AA
++	bool "PMAG-AA TURBOchannel framebuffer support"
++	depends on FB && MACH_DECSTATION && TC
++	help
++	  Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
++	  used mainly in the MIPS-based DECstation series.
++
+ config FB_PMAG_BA
+ 	bool "PMAG-BA TURBOchannel framebuffer support"
+-	depends on FB && DECSTATION && TC
++	depends on FB && MACH_DECSTATION && TC
+ 	help
+-	  Say Y here to directly support the on-board PMAG-BA framebuffer in
+-	  the 5000/1xx versions of the DECstation.  There is a page dedicated
+-	  to Linux on DECstations at <http://decstation.unix-ag.org/>.
++	  Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
++	  used mainly in the MIPS-based DECstation series.
+ 
+ config FB_PMAGB_B
+-	bool "PMAGB-B TURBOchannel framebuffer spport"
+-	depends on FB && DECSTATION && TC
++	bool "PMAGB-B TURBOchannel framebuffer support"
++	depends on FB && MACH_DECSTATION && TC
+ 	help
+-	  Say Y here to directly support the on-board PMAGB-B framebuffer in
+-	  the 5000/1xx versions of the DECstation.  There is a page dedicated
+-	  to Linux on DECstations at <http://decstation.unix-ag.org/>.
++	  Support for the PMAGB-B TURBOchannel framebuffer card used mainly
++	  in the MIPS-based DECstation series. The card is currently only 
++	  supported in 1280x1024x8 mode.  
+ 
+ config FB_MAXINE
+-	bool "Maxine (Personal DECstation) onboard framebuffer spport"
+-	depends on FB && DECSTATION && TC
++	bool "Maxine (Personal DECstation) onboard framebuffer support"
++	depends on FB && MACH_DECSTATION && TC
+ 	help
+-	  Say Y here to directly support the on-board framebuffer in the
+-	  Maxine (5000/20, /25, /33) version of the DECstation.  There is a
+-	  page dedicated to Linux on DECstations at <http://decstation.unix-ag.org/>.
++	  Support for the onboard framebuffer (1024x768x8) in the Personal
++	  DECstation series (Personal DECstation 5000/20, /25, /33, /50,
++	  Codename "Maxine").
+ 
+ config FB_TX3912
+ 	bool "TMPTX3912/PR31700 frame buffer support"
+@@ -1031,6 +1073,13 @@ config FB_TX3912
+ 
+ 	  Say Y here to enable kernel support for the on-board framebuffer.
+ 
++config FB_G364
++	bool
++	depends on MIPS_MAGNUM_4000 || OLIVETTI_M700
++	help
++	  The G364 driver is the framebuffer used in MIPS Magnum 4000 and
++	  Olivetti M700-10 systems.
++
+ config FB_68328
+ 	bool "Motorola 68328 native frame buffer support"
+ 	depends on (M68328 || M68EZ328 || M68VZ328)
+diff -urpNX dontdiff linux-2.6.10/drivers/video/Makefile linux-2.6.10-mips/drivers/video/Makefile
+--- linux-2.6.10/drivers/video/Makefile	2004-12-24 22:33:59.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/Makefile	2004-11-19 01:14:52.000000000 +0100
+@@ -81,12 +81,7 @@ obj-$(CONFIG_FB_G364)             += g36
+ obj-$(CONFIG_FB_SA1100)           += sa1100fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_SUN3)             += sun3fb.o
+ obj-$(CONFIG_FB_HIT)              += hitfb.o cfbfillrect.o cfbimgblt.o
+-obj-$(CONFIG_FB_TX3912)           += tx3912fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+-obj-$(CONFIG_FB_EPSON1355)	  += epson1355fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_PVR2)             += pvr2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+-obj-$(CONFIG_FB_PMAG_BA)          += pmag-ba-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+-obj-$(CONFIG_FB_PMAGB_B)          += pmagb-b-fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+-obj-$(CONFIG_FB_MAXINE)           += maxinefb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_VOODOO1)          += sstfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_ARMCLCD)	  += amba-clcd.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_68328)            += 68328fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+@@ -94,6 +89,13 @@ obj-$(CONFIG_FB_GBE)              += gbe
+ obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o
+ obj-$(CONFIG_FB_ASILIANT)	  += asiliantfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+ obj-$(CONFIG_FB_PXA)		  += pxafb.o cfbimgblt.o cfbcopyarea.o cfbfillrect.o
++obj-$(CONFIG_FB_PMAG_AA)	  += pmag-aa-fb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_PMAG_BA)	  += pmag-ba-fb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_PMAGB_B)	  += pmagb-b-fb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_MAXINE)		  += maxinefb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_TX3912)		  += tx3912fb.o  cfbfillrect.o cfbcopyarea.o cfbimgblt.o
++obj-$(CONFIG_FB_AU1100)		  += au1100fb.o fbgen.o
++
+ 
+ # Platform or fallback drivers go here
+ obj-$(CONFIG_FB_VESA)             += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+diff -urpNX dontdiff linux-2.6.10/drivers/video/au1100fb.c linux-2.6.10-mips/drivers/video/au1100fb.c
+--- linux-2.6.10/drivers/video/au1100fb.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/au1100fb.c	2004-10-27 02:15:03.000000000 +0200
+@@ -0,0 +1,676 @@
++/*
++ * BRIEF MODULE DESCRIPTION
++ *	Au1100 LCD Driver.
++ *
++ * Copyright 2002 MontaVista Software
++ * Author: MontaVista Software, Inc.
++ *		ppopov at mvista.com or source at mvista.com
++ *
++ * Copyright 2002 Alchemy Semiconductor
++ * Author: Alchemy Semiconductor
++ *
++ * Based on:
++ * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
++ *  Created 28 Dec 1997 by Geert Uytterhoeven
++ *
++ *  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  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
++ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
++ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  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.
++ */
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/tty.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++#include <linux/pci.h>
++
++#include <asm/au1000.h>
++#include <asm/pb1100.h>
++#include "au1100fb.h"
++
++#include <video/fbcon.h>
++#include <video/fbcon-mfb.h>
++#include <video/fbcon-cfb2.h>
++#include <video/fbcon-cfb4.h>
++#include <video/fbcon-cfb8.h>
++#include <video/fbcon-cfb16.h>
++
++/* 
++ * Sanity check. If this is a new Au1100 based board, search for
++ * the PB1100 ifdefs to make sure you modify the code accordingly.
++ */
++#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || defined(CONFIG_MIPS_HYDROGEN3)
++#else
++error Unknown Au1100 board
++#endif
++
++#define CMAPSIZE 16
++
++static int my_lcd_index; /* default is zero */
++struct known_lcd_panels *p_lcd;
++AU1100_LCD *p_lcd_reg = (AU1100_LCD *)AU1100_LCD_ADDR;
++
++struct au1100fb_info {
++	struct fb_info_gen gen;
++	unsigned long fb_virt_start;
++	unsigned long fb_size;
++	unsigned long fb_phys;
++	int mmaped;
++	int nohwcursor;
++
++	struct { unsigned red, green, blue, pad; } palette[256];
++
++#if defined(FBCON_HAS_CFB16)
++	u16 fbcon_cmap16[16];
++#endif
++};
++
++
++struct au1100fb_par {
++        struct fb_var_screeninfo var;
++	
++	int line_length;  // in bytes
++	int cmap_len;     // color-map length
++};
++
++
++static struct au1100fb_info fb_info;
++static struct au1100fb_par current_par;
++static struct display disp;
++
++int au1100fb_init(void);
++void au1100fb_setup(char *options, int *ints);
++static int au1100fb_mmap(struct fb_info *fb, struct file *file, 
++		struct vm_area_struct *vma);
++static int au1100_blank(int blank_mode, struct fb_info_gen *info);
++static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
++			  u_long arg, int con, struct fb_info *info);
++
++void au1100_nocursor(struct display *p, int mode, int xx, int yy){};
++
++static struct fb_ops au1100fb_ops = {
++	owner:		THIS_MODULE,
++	fb_get_fix:	fbgen_get_fix,
++	fb_get_var:	fbgen_get_var,
++	fb_set_var:	fbgen_set_var,
++	fb_get_cmap:	fbgen_get_cmap,
++	fb_set_cmap:	fbgen_set_cmap,
++	fb_pan_display: fbgen_pan_display,
++        fb_ioctl:       au1100fb_ioctl,
++	fb_mmap:        au1100fb_mmap,
++};
++
++static void au1100_detect(void)
++{
++	/*
++	 *  This function should detect the current video mode settings 
++	 *  and store it as the default video mode
++	 */
++
++	/*
++	 * Yeh, well, we're not going to change any settings so we're
++	 * always stuck with the default ...
++	 */
++
++}
++
++static int au1100_encode_fix(struct fb_fix_screeninfo *fix, 
++		const void *_par, struct fb_info_gen *_info)
++{
++        struct au1100fb_info *info = (struct au1100fb_info *) _info;
++        struct au1100fb_par *par = (struct au1100fb_par *) _par;
++	struct fb_var_screeninfo *var = &par->var;
++
++	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
++
++	fix->smem_start = info->fb_phys;
++	fix->smem_len = info->fb_size;
++	fix->type = FB_TYPE_PACKED_PIXELS;
++	fix->type_aux = 0;
++        fix->visual = (var->bits_per_pixel == 8) ?
++	       	FB_VISUAL_PSEUDOCOLOR	: FB_VISUAL_TRUECOLOR;
++	fix->ywrapstep = 0;
++	fix->xpanstep = 1;
++	fix->ypanstep = 1;
++	fix->line_length = current_par.line_length;
++	return 0;
++}
++
++static void set_color_bitfields(struct fb_var_screeninfo *var)
++{
++	switch (var->bits_per_pixel) {
++	case 8:
++		var->red.offset = 0;
++		var->red.length = 8;
++		var->green.offset = 0;
++		var->green.length = 8;
++		var->blue.offset = 0;
++		var->blue.length = 8;
++		var->transp.offset = 0;
++		var->transp.length = 0;
++		break;
++	case 16:	/* RGB 565 */
++		var->red.offset = 11;
++		var->red.length = 5;
++		var->green.offset = 5;
++		var->green.length = 6;
++		var->blue.offset = 0;
++		var->blue.length = 5;
++		var->transp.offset = 0;
++		var->transp.length = 0;
++		break;
++	}
++
++	var->red.msb_right = 0;
++	var->green.msb_right = 0;
++	var->blue.msb_right = 0;
++	var->transp.msb_right = 0;
++}
++
++static int au1100_decode_var(const struct fb_var_screeninfo *var, 
++		void *_par, struct fb_info_gen *_info)
++{
++
++	struct au1100fb_par *par = (struct au1100fb_par *)_par;
++
++	/*
++	 * Don't allow setting any of these yet: xres and yres don't
++	 * make sense for LCD panels.
++	 */
++	if (var->xres != p_lcd->xres ||
++	    var->yres != p_lcd->yres ||
++	    var->xres != p_lcd->xres ||
++	    var->yres != p_lcd->yres) {
++		return -EINVAL;
++	}
++	if(var->bits_per_pixel != p_lcd->bpp) {
++		return -EINVAL;
++	}
++
++	memset(par, 0, sizeof(struct au1100fb_par));
++	par->var = *var;
++	
++	/* FIXME */
++	switch (var->bits_per_pixel) {
++		case 8:
++			par->var.bits_per_pixel = 8;
++			break;
++		case 16:
++			par->var.bits_per_pixel = 16;
++			break;
++		default:
++			printk("color depth %d bpp not supported\n",
++					var->bits_per_pixel);
++			return -EINVAL;
++
++	}
++	set_color_bitfields(&par->var);
++	par->cmap_len = (par->var.bits_per_pixel == 8) ? 256 : 16;
++	return 0;
++}
++
++static int au1100_encode_var(struct fb_var_screeninfo *var, 
++		const void *par, struct fb_info_gen *_info)
++{
++
++	*var = ((struct au1100fb_par *)par)->var;
++	return 0;
++}
++
++static void 
++au1100_get_par(void *_par, struct fb_info_gen *_info)
++{
++	*(struct au1100fb_par *)_par = current_par;
++}
++
++static void au1100_set_par(const void *par, struct fb_info_gen *info)
++{
++	/* nothing to do: we don't change any settings */
++}
++
++static int au1100_getcolreg(unsigned regno, unsigned *red, unsigned *green,
++			 unsigned *blue, unsigned *transp,
++			 struct fb_info *info)
++{
++
++	struct au1100fb_info* i = (struct au1100fb_info*)info;
++
++	if (regno > 255)
++		return 1;
++   
++	*red    = i->palette[regno].red; 
++	*green  = i->palette[regno].green; 
++	*blue   = i->palette[regno].blue; 
++	*transp = 0;
++
++	return 0;
++}
++
++static int au1100_setcolreg(unsigned regno, unsigned red, unsigned green,
++			 unsigned blue, unsigned transp,
++			 struct fb_info *info)
++{
++	struct au1100fb_info* i = (struct au1100fb_info *)info;
++	u32 rgbcol;
++
++	if (regno > 255)
++		return 1;
++
++	i->palette[regno].red    = red;
++	i->palette[regno].green  = green;
++	i->palette[regno].blue   = blue;
++   
++	switch(p_lcd->bpp) {
++#ifdef FBCON_HAS_CFB8
++	case 8:
++		red >>= 10;
++		green >>= 10;
++		blue >>= 10;
++		p_lcd_reg->lcd_pallettebase[regno] = (blue&0x1f) | 
++			((green&0x3f)<<5) | ((red&0x1f)<<11);
++		break;
++#endif
++#ifdef FBCON_HAS_CFB16
++	case 16:
++		i->fbcon_cmap16[regno] =
++			((red & 0xf800) >> 0) |
++			((green & 0xfc00) >> 5) |
++			((blue & 0xf800) >> 11);
++		break;
++#endif
++	default:
++		break;
++	}
++
++	return 0;
++}
++
++
++static int  au1100_blank(int blank_mode, struct fb_info_gen *_info)
++{
++
++	switch (blank_mode) {
++	case VESA_NO_BLANKING:
++		/* turn on panel */
++		//printk("turn on panel\n");
++#ifdef CONFIG_MIPS_PB1100
++		p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
++		au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight, 
++			PB1100_G_CONTROL);
++#endif
++#ifdef CONFIG_MIPS_HYDROGEN3
++		/*  Turn controller & power supply on,  GPIO213 */
++		au_writel(0x20002000, 0xB1700008);
++		au_writel(0x00040000, 0xB1900108);
++		au_writel(0x01000100, 0xB1700008);
++#endif
++		au_sync();
++		break;
++
++	case VESA_VSYNC_SUSPEND:
++	case VESA_HSYNC_SUSPEND:
++	case VESA_POWERDOWN:
++		/* turn off panel */
++		//printk("turn off panel\n");
++#ifdef CONFIG_MIPS_PB1100
++		au_writew(au_readw(PB1100_G_CONTROL) & ~p_lcd->mode_backlight, 
++			PB1100_G_CONTROL);
++		p_lcd_reg->lcd_control &= ~LCD_CONTROL_GO;
++#endif
++		au_sync();
++		break;
++	default: 
++		break;
++
++	}
++	return 0;
++}
++
++static void au1100_set_disp(const void *unused, struct display *disp,
++			 struct fb_info_gen *info)
++{
++	disp->screen_base = (char *)fb_info.fb_virt_start;
++
++	switch (disp->var.bits_per_pixel) {
++#ifdef FBCON_HAS_CFB8
++	case 8:
++		disp->dispsw = &fbcon_cfb8;
++		if (fb_info.nohwcursor)
++			fbcon_cfb8.cursor = au1100_nocursor;
++		break;
++#endif
++#ifdef FBCON_HAS_CFB16
++	case 16:
++		disp->dispsw = &fbcon_cfb16;
++		disp->dispsw_data = fb_info.fbcon_cmap16;
++		if (fb_info.nohwcursor)
++			fbcon_cfb16.cursor = au1100_nocursor;
++		break;
++#endif
++	default:
++		disp->dispsw = &fbcon_dummy;
++		disp->dispsw_data = NULL;
++		break;
++	}
++}
++
++static int
++au1100fb_mmap(struct fb_info *_fb,
++	     struct file *file,
++	     struct vm_area_struct *vma)
++{
++	unsigned int len;
++	unsigned long start=0, off;
++	struct au1100fb_info *fb = (struct au1100fb_info *)_fb;
++
++	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
++		return -EINVAL;
++	}
++    
++	start = fb_info.fb_phys & PAGE_MASK;
++	len = PAGE_ALIGN((start & ~PAGE_MASK) + fb_info.fb_size);
++
++	off = vma->vm_pgoff << PAGE_SHIFT;
++
++	if ((vma->vm_end - vma->vm_start + off) > len) {
++		return -EINVAL;
++	}
++
++	off += start;
++	vma->vm_pgoff = off >> PAGE_SHIFT;
++
++	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
++	//pgprot_val(vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT;
++	pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6
++
++	/* This is an IO map - tell maydump to skip this VMA */
++	vma->vm_flags |= VM_IO;
++    
++	if (io_remap_page_range(vma->vm_start, off,
++				vma->vm_end - vma->vm_start,
++				vma->vm_page_prot)) {
++		return -EAGAIN;
++	}
++
++	fb->mmaped = 1;
++	return 0;
++}
++
++int au1100_pan_display(const struct fb_var_screeninfo *var,
++		       struct fb_info_gen *info)
++{
++	return 0;
++}
++
++static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
++			  u_long arg, int con, struct fb_info *info)
++{
++	/* nothing to do yet */
++	return -EINVAL;
++}
++
++static struct fbgen_hwswitch au1100_switch = {
++	au1100_detect, 
++	au1100_encode_fix, 
++	au1100_decode_var, 
++	au1100_encode_var, 
++	au1100_get_par, 
++	au1100_set_par, 
++	au1100_getcolreg, 
++	au1100_setcolreg, 
++	au1100_pan_display, 
++	au1100_blank, 
++	au1100_set_disp
++};
++
++
++int au1100_setmode(void) 
++{
++	int words;
++
++	/* FIXME Need to accomodate for swivel mode and 12bpp, <8bpp*/
++	switch (p_lcd->mode_control & LCD_CONTROL_SM)
++	{
++		case LCD_CONTROL_SM_0:
++		case LCD_CONTROL_SM_180:
++		words = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 32;
++			break;
++		case LCD_CONTROL_SM_90:
++		case LCD_CONTROL_SM_270:
++			/* is this correct? */
++		words = (p_lcd->xres * p_lcd->bpp) / 8;
++			break;
++		default:
++			printk("mode_control reg not initialized\n");
++			return -EINVAL;
++	}
++
++	/*
++	 * Setup LCD controller
++	 */
++
++	p_lcd_reg->lcd_control = p_lcd->mode_control;
++	p_lcd_reg->lcd_intstatus = 0;
++	p_lcd_reg->lcd_intenable = 0;
++	p_lcd_reg->lcd_horztiming = p_lcd->mode_horztiming;
++	p_lcd_reg->lcd_verttiming = p_lcd->mode_verttiming;
++	p_lcd_reg->lcd_clkcontrol = p_lcd->mode_clkcontrol;
++	p_lcd_reg->lcd_words = words - 1;
++	p_lcd_reg->lcd_dmaaddr0 = fb_info.fb_phys;
++
++	/* turn on panel */
++#ifdef CONFIG_MIPS_PB1100
++	au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight, 
++			PB1100_G_CONTROL);
++#endif
++#ifdef CONFIG_MIPS_HYDROGEN3
++	/*  Turn controller & power supply on,  GPIO213 */
++	au_writel(0x20002000, 0xB1700008);
++	au_writel(0x00040000, 0xB1900108);
++	au_writel(0x01000100, 0xB1700008);
++#endif
++
++	p_lcd_reg->lcd_control |= LCD_CONTROL_GO;
++
++	return 0;
++}
++
++
++int __init au1100fb_init(void)
++{
++	uint32 sys_clksrc;
++	unsigned long page;
++
++	/*
++	* Get the panel information/display mode and update the registry
++	*/
++	p_lcd = &panels[my_lcd_index];
++
++	switch (p_lcd->mode_control & LCD_CONTROL_SM)
++	{
++		case LCD_CONTROL_SM_0:
++		case LCD_CONTROL_SM_180:
++		p_lcd->xres = 
++			(p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;
++		p_lcd->yres = 
++			(p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;
++			break;
++		case LCD_CONTROL_SM_90:
++		case LCD_CONTROL_SM_270:
++		p_lcd->yres = 
++			(p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;
++		p_lcd->xres = 
++			(p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;
++			break;
++	}
++
++	/*
++	 * Panel dimensions x bpp must be divisible by 32
++	 */
++	if (((p_lcd->yres * p_lcd->bpp) % 32) != 0) 
++		printk("VERT %% 32\n");
++	if (((p_lcd->xres * p_lcd->bpp) % 32) != 0) 
++		printk("HORZ %% 32\n");
++
++	/*
++	 * Allocate LCD framebuffer from system memory
++	 */
++	fb_info.fb_size = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 8;
++	
++	current_par.var.xres = p_lcd->xres;
++	current_par.var.xres_virtual = p_lcd->xres;
++	current_par.var.yres = p_lcd->yres;
++	current_par.var.yres_virtual = p_lcd->yres;
++	current_par.var.bits_per_pixel = p_lcd->bpp;
++
++	/* FIX!!! only works for 8/16 bpp */
++	current_par.line_length = p_lcd->xres * p_lcd->bpp / 8; /* in bytes */
++	fb_info.fb_virt_start = (unsigned long )
++		__get_free_pages(GFP_ATOMIC | GFP_DMA, 
++				get_order(fb_info.fb_size + 0x1000));
++	if (!fb_info.fb_virt_start) {
++		printk("Unable to allocate fb memory\n");
++		return -ENOMEM;
++	}
++	fb_info.fb_phys = virt_to_bus((void *)fb_info.fb_virt_start);
++
++	/*
++	 * Set page reserved so that mmap will work. This is necessary
++	 * since we'll be remapping normal memory.
++	 */
++	for (page = fb_info.fb_virt_start;
++	     page < PAGE_ALIGN(fb_info.fb_virt_start + fb_info.fb_size); 
++	     page += PAGE_SIZE) {
++		SetPageReserved(virt_to_page(page));
++	}
++
++	memset((void *)fb_info.fb_virt_start, 0, fb_info.fb_size);
++
++	/* set freqctrl now to allow more time to stabilize */
++	/* zero-out out LCD bits */
++	sys_clksrc = au_readl(SYS_CLKSRC) & ~0x000003e0; 
++	sys_clksrc |= p_lcd->mode_toyclksrc;
++	au_writel(sys_clksrc, SYS_CLKSRC);
++
++	/* FIXME add check to make sure auxpll is what is expected! */
++	au1100_setmode();
++
++	fb_info.gen.parsize = sizeof(struct au1100fb_par);
++	fb_info.gen.fbhw = &au1100_switch;
++
++	strcpy(fb_info.gen.info.modename, "Au1100 LCD");
++	fb_info.gen.info.changevar = NULL;
++	fb_info.gen.info.node = -1;
++
++	fb_info.gen.info.fbops = &au1100fb_ops;
++	fb_info.gen.info.disp = &disp;
++	fb_info.gen.info.switch_con = &fbgen_switch;
++	fb_info.gen.info.updatevar = &fbgen_update_var;
++	fb_info.gen.info.blank = &fbgen_blank;
++	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
++
++	/* This should give a reasonable default video mode */
++	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
++	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
++	fbgen_set_disp(-1, &fb_info.gen);
++	fbgen_install_cmap(0, &fb_info.gen);
++	if (register_framebuffer(&fb_info.gen.info) < 0)
++		return -EINVAL;
++	printk(KERN_INFO "fb%d: %s frame buffer device\n", 
++			GET_FB_IDX(fb_info.gen.info.node), 
++			fb_info.gen.info.modename);
++
++	return 0;
++}
++
++
++void au1100fb_cleanup(struct fb_info *info)
++{
++	unregister_framebuffer(info);
++}
++
++
++void au1100fb_setup(char *options, int *ints)
++{
++	char* this_opt;
++	int i;
++	int num_panels = sizeof(panels)/sizeof(struct known_lcd_panels);
++
++    
++	if (!options || !*options)
++		return;
++
++	for(this_opt=strtok(options, ","); this_opt;
++	    this_opt=strtok(NULL, ",")) {
++		if (!strncmp(this_opt, "panel:", 6)) {
++#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100)
++			/* Read Pb1100 Switch S10 ? */
++			if (!strncmp(this_opt+6, "s10", 3))
++			{
++				int panel;
++				panel = *(volatile int *)0xAE000008; /* BCSR SWITCHES */
++				panel >>= 8;
++				panel &= 0x0F;
++				if (panel >= num_panels) panel = 0;
++				my_lcd_index = panel;
++			}
++			else
++#endif
++			/* Get the panel name, everything else if fixed */
++			for (i=0; i<num_panels; i++) {
++				if (!strncmp(this_opt+6, panels[i].panel_name, 
++							strlen(this_opt))) {
++					my_lcd_index = i;
++					break;
++				}
++			}
++		}
++		else if (!strncmp(this_opt, "nohwcursor", 10)) {
++			printk("nohwcursor\n");
++			fb_info.nohwcursor = 1;
++		}
++	} 
++
++	printk("au1100fb: Panel %d %s\n", my_lcd_index,
++		panels[my_lcd_index].panel_name);
++}
++
++
++
++#ifdef MODULE
++MODULE_LICENSE("GPL");
++int init_module(void)
++{
++	return au1100fb_init();
++}
++
++void cleanup_module(void)
++{
++	au1100fb_cleanup(void);
++}
++
++MODULE_AUTHOR("Pete Popov <ppopov at mvista.com>");
++MODULE_DESCRIPTION("Au1100 LCD framebuffer device driver");
++#endif /* MODULE */
+diff -urpNX dontdiff linux-2.6.10/drivers/video/au1100fb.h linux-2.6.10-mips/drivers/video/au1100fb.h
+--- linux-2.6.10/drivers/video/au1100fb.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/au1100fb.h	2002-07-14 23:33:34.000000000 +0200
+@@ -0,0 +1,381 @@
++/*
++ * BRIEF MODULE DESCRIPTION
++ *	Hardware definitions for the Au1100 LCD controller
++ *
++ * Copyright 2002 MontaVista Software
++ * Copyright 2002 Alchemy Semiconductor
++ * Author:	Alchemy Semiconductor, MontaVista Software
++ *
++ *  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  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
++ *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
++ *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  You should have received a copy of the  GNU General Public License along
++ *  with this program; if not, write  to the Free Software Foundation, Inc.,
++ *  675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef _AU1100LCD_H
++#define _AU1100LCD_H
++
++/********************************************************************/
++#define uint32 unsigned long
++typedef volatile struct
++{
++	uint32	lcd_control;
++	uint32	lcd_intstatus;
++	uint32	lcd_intenable;
++	uint32	lcd_horztiming;
++	uint32	lcd_verttiming;
++	uint32	lcd_clkcontrol;
++	uint32	lcd_dmaaddr0;
++	uint32	lcd_dmaaddr1;
++	uint32	lcd_words;
++	uint32	lcd_pwmdiv;
++	uint32	lcd_pwmhi;
++	uint32	reserved[(0x0400-0x002C)/4];
++	uint32	lcd_pallettebase[256];
++
++} AU1100_LCD;
++
++/********************************************************************/
++
++#define AU1100_LCD_ADDR		0xB5000000
++
++/*
++ * Register bit definitions
++ */
++
++/* lcd_control */
++#define LCD_CONTROL_SBPPF		(7<<18)
++#define LCD_CONTROL_SBPPF_655	(0<<18)
++#define LCD_CONTROL_SBPPF_565	(1<<18)
++#define LCD_CONTROL_SBPPF_556	(2<<18)
++#define LCD_CONTROL_SBPPF_1555	(3<<18)
++#define LCD_CONTROL_SBPPF_5551	(4<<18)
++#define LCD_CONTROL_WP			(1<<17)
++#define LCD_CONTROL_WD			(1<<16)
++#define LCD_CONTROL_C			(1<<15)
++#define LCD_CONTROL_SM			(3<<13)
++#define LCD_CONTROL_SM_0		(0<<13)
++#define LCD_CONTROL_SM_90		(1<<13)
++#define LCD_CONTROL_SM_180		(2<<13)
++#define LCD_CONTROL_SM_270		(3<<13)
++#define LCD_CONTROL_DB			(1<<12)
++#define LCD_CONTROL_CCO			(1<<11)
++#define LCD_CONTROL_DP			(1<<10)
++#define LCD_CONTROL_PO			(3<<8)
++#define LCD_CONTROL_PO_00		(0<<8)
++#define LCD_CONTROL_PO_01		(1<<8)
++#define LCD_CONTROL_PO_10		(2<<8)
++#define LCD_CONTROL_PO_11		(3<<8)
++#define LCD_CONTROL_MPI			(1<<7)
++#define LCD_CONTROL_PT			(1<<6)
++#define LCD_CONTROL_PC			(1<<5)
++#define LCD_CONTROL_BPP			(7<<1)
++#define LCD_CONTROL_BPP_1		(0<<1)
++#define LCD_CONTROL_BPP_2		(1<<1)
++#define LCD_CONTROL_BPP_4		(2<<1)
++#define LCD_CONTROL_BPP_8		(3<<1)
++#define LCD_CONTROL_BPP_12		(4<<1)
++#define LCD_CONTROL_BPP_16		(5<<1)
++#define LCD_CONTROL_GO			(1<<0)
++
++/* lcd_intstatus, lcd_intenable */
++#define LCD_INT_SD				(1<<7)
++#define LCD_INT_OF				(1<<6)
++#define LCD_INT_UF				(1<<5)
++#define LCD_INT_SA				(1<<3)
++#define LCD_INT_SS				(1<<2)
++#define LCD_INT_S1				(1<<1)
++#define LCD_INT_S0				(1<<0)
++
++/* lcd_horztiming */
++#define LCD_HORZTIMING_HN2		(255<<24)
++#define LCD_HORZTIMING_HN2_N(N)	(((N)-1)<<24)
++#define LCD_HORZTIMING_HN1		(255<<16)
++#define LCD_HORZTIMING_HN1_N(N)	(((N)-1)<<16)
++#define LCD_HORZTIMING_HPW		(63<<10)
++#define LCD_HORZTIMING_HPW_N(N)	(((N)-1)<<10)
++#define LCD_HORZTIMING_PPL		(1023<<0)
++#define LCD_HORZTIMING_PPL_N(N)	(((N)-1)<<0)
++
++/* lcd_verttiming */
++#define LCD_VERTTIMING_VN2		(255<<24)
++#define LCD_VERTTIMING_VN2_N(N)	(((N)-1)<<24)
++#define LCD_VERTTIMING_VN1		(255<<16)
++#define LCD_VERTTIMING_VN1_N(N)	(((N)-1)<<16)
++#define LCD_VERTTIMING_VPW		(63<<10)
++#define LCD_VERTTIMING_VPW_N(N)	(((N)-1)<<10)
++#define LCD_VERTTIMING_LPP		(1023<<0)
++#define LCD_VERTTIMING_LPP_N(N)	(((N)-1)<<0)
++
++/* lcd_clkcontrol */
++#define LCD_CLKCONTROL_IB		(1<<18)
++#define LCD_CLKCONTROL_IC		(1<<17)
++#define LCD_CLKCONTROL_IH		(1<<16)
++#define LCD_CLKCONTROL_IV		(1<<15)
++#define LCD_CLKCONTROL_BF		(31<<10)
++#define LCD_CLKCONTROL_BF_N(N)	(((N)-1)<<10)
++#define LCD_CLKCONTROL_PCD		(1023<<0)
++#define LCD_CLKCONTROL_PCD_N(N)	((N)<<0)
++
++/* lcd_pwmdiv */
++#define LCD_PWMDIV_EN			(1<<12)
++#define LCD_PWMDIV_PWMDIV		(2047<<0)
++#define LCD_PWMDIV_PWMDIV_N(N)	(((N)-1)<<0)
++
++/* lcd_pwmhi */
++#define LCD_PWMHI_PWMHI1		(2047<<12)
++#define LCD_PWMHI_PWMHI1_N(N)	((N)<<12)
++#define LCD_PWMHI_PWMHI0		(2047<<0)
++#define LCD_PWMHI_PWMHI0_N(N)	((N)<<0)
++
++/* lcd_pallettebase - MONOCHROME */
++#define LCD_PALLETTE_MONO_MI		(15<<0)
++#define LCD_PALLETTE_MONO_MI_N(N)	((N)<<0)
++
++/* lcd_pallettebase - COLOR */
++#define LCD_PALLETTE_COLOR_BI		(15<<8)
++#define LCD_PALLETTE_COLOR_BI_N(N)	((N)<<8)
++#define LCD_PALLETTE_COLOR_GI		(15<<4)
++#define LCD_PALLETTE_COLOR_GI_N(N)	((N)<<4)
++#define LCD_PALLETTE_COLOR_RI		(15<<0)
++#define LCD_PALLETTE_COLOR_RI_N(N)	((N)<<0)
++
++/* lcd_palletebase - COLOR TFT PALLETIZED */
++#define LCD_PALLETTE_TFT_DC			(65535<<0)
++#define LCD_PALLETTE_TFT_DC_N(N)	((N)<<0)
++
++/********************************************************************/
++
++struct known_lcd_panels
++{
++	uint32 xres;
++	uint32 yres;
++	uint32 bpp;
++	unsigned char  panel_name[256];
++	uint32 mode_control;
++	uint32 mode_horztiming;
++	uint32 mode_verttiming;
++	uint32 mode_clkcontrol;
++	uint32 mode_pwmdiv;
++	uint32 mode_pwmhi;
++	uint32 mode_toyclksrc;
++	uint32 mode_backlight;
++
++};
++
++#if defined(__BIG_ENDIAN)
++#define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_11
++#else
++#define LCD_DEFAULT_PIX_FORMAT LCD_CONTROL_PO_00
++#endif
++
++/*
++ * The fb driver assumes that AUX PLL is at 48MHz.  That can
++ * cover up to 800x600 resolution; if you need higher resolution,
++ * you should modify the driver as needed, not just this structure.
++ */
++struct known_lcd_panels panels[] =
++{
++	{ /* 0: Pb1100 LCDA: Sharp 320x240 TFT panel */
++		320, /* xres */
++		240, /* yres */
++		16,  /* bpp  */
++		
++		"Sharp_320x240_16",
++		/* mode_control */
++		( LCD_CONTROL_SBPPF_565
++		/*LCD_CONTROL_WP*/
++		/*LCD_CONTROL_WD*/
++		| LCD_CONTROL_C
++		| LCD_CONTROL_SM_0
++		/*LCD_CONTROL_DB*/
++		/*LCD_CONTROL_CCO*/
++		/*LCD_CONTROL_DP*/
++		| LCD_DEFAULT_PIX_FORMAT
++		/*LCD_CONTROL_MPI*/
++		| LCD_CONTROL_PT
++		| LCD_CONTROL_PC
++		| LCD_CONTROL_BPP_16 ),
++
++		/* mode_horztiming */
++		( LCD_HORZTIMING_HN2_N(8)
++		| LCD_HORZTIMING_HN1_N(60)
++		| LCD_HORZTIMING_HPW_N(12)
++		| LCD_HORZTIMING_PPL_N(320) ),
++
++		/* mode_verttiming */
++		( LCD_VERTTIMING_VN2_N(5)
++		| LCD_VERTTIMING_VN1_N(17)
++		| LCD_VERTTIMING_VPW_N(1)
++		| LCD_VERTTIMING_LPP_N(240) ),
++
++		/* mode_clkcontrol */
++		( 0
++		/*LCD_CLKCONTROL_IB*/
++		/*LCD_CLKCONTROL_IC*/
++		/*LCD_CLKCONTROL_IH*/
++		/*LCD_CLKCONTROL_IV*/
++		| LCD_CLKCONTROL_PCD_N(1) ),
++
++		/* mode_pwmdiv */
++		0,
++
++		/* mode_pwmhi */
++		0,
++
++		/* mode_toyclksrc */
++		((1<<7) | (1<<6) | (1<<5)),
++
++		/* mode_backlight */
++		6
++	},
++
++	{ /* 1: Pb1100 LCDC 640x480 TFT panel */
++		640, /* xres */
++		480, /* yres */
++		16,  /* bpp  */
++
++		"Generic_640x480_16",
++
++		/* mode_control */
++		0x004806a | LCD_DEFAULT_PIX_FORMAT,
++
++		/* mode_horztiming */
++		0x3434d67f,
++
++		/* mode_verttiming */
++		0x0e0e39df,
++
++		/* mode_clkcontrol */
++		( 0
++		/*LCD_CLKCONTROL_IB*/
++		/*LCD_CLKCONTROL_IC*/
++		/*LCD_CLKCONTROL_IH*/
++		/*LCD_CLKCONTROL_IV*/
++		| LCD_CLKCONTROL_PCD_N(1) ),
++
++		/* mode_pwmdiv */
++		0,
++
++		/* mode_pwmhi */
++		0,
++
++		/* mode_toyclksrc */
++		((1<<7) | (1<<6) | (0<<5)),
++
++		/* mode_backlight */
++		7
++	},
++
++	{ /* 2: Pb1100 LCDB 640x480 PrimeView TFT panel */
++		640, /* xres */
++		480, /* yres */
++		16,  /* bpp  */
++
++		"PrimeView_640x480_16",
++
++		/* mode_control */
++		0x0004886a | LCD_DEFAULT_PIX_FORMAT,
++
++		/* mode_horztiming */
++		0x0e4bfe7f,
++
++		/* mode_verttiming */
++		0x210805df,
++
++		/* mode_clkcontrol */
++		0x00038001,
++
++		/* mode_pwmdiv */
++		0,
++
++		/* mode_pwmhi */
++		0,
++
++		/* mode_toyclksrc */
++		((1<<7) | (1<<6) | (0<<5)),
++
++		/* mode_backlight */
++		7
++	},
++
++	{ /* 3: Pb1100 800x600x16bpp NEON CRT */
++		800, /* xres */
++		600, /* yres */
++		16,  /* bpp */
++
++		"NEON_800x600_16",
++
++		/* mode_control */
++		0x0004886A | LCD_DEFAULT_PIX_FORMAT,
++
++		/* mode_horztiming */
++		0x005AFF1F,
++
++		/* mode_verttiming */
++		0x16000E57,
++
++		/* mode_clkcontrol */
++		0x00020000,
++
++		/* mode_pwmdiv */
++		0,
++
++		/* mode_pwmhi */
++		0,
++
++		/* mode_toyclksrc */
++		((1<<7) | (1<<6) | (0<<5)),
++
++		/* mode_backlight */
++		7
++	},
++
++	{ /* 4: Pb1100 640x480x16bpp NEON CRT */
++		640, /* xres */
++		480, /* yres */
++		16,  /* bpp */
++
++		"NEON_640x480_16",
++
++		/* mode_control */
++		0x0004886A | LCD_DEFAULT_PIX_FORMAT,
++
++		/* mode_horztiming */
++		0x0052E27F,
++
++		/* mode_verttiming */
++		0x18000DDF,
++
++		/* mode_clkcontrol */
++		0x00020000,
++
++		/* mode_pwmdiv */
++		0,
++
++		/* mode_pwmhi */
++		0,
++
++		/* mode_toyclksrc */
++		((1<<7) | (1<<6) | (0<<5)),
++
++		/* mode_backlight */
++		7
++	},
++};
++#endif /* _AU1100LCD_H */
+diff -urpNX dontdiff linux-2.6.10/drivers/video/bt431.h linux-2.6.10-mips/drivers/video/bt431.h
+--- linux-2.6.10/drivers/video/bt431.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/bt431.h	2003-11-16 09:21:14.000000000 +0100
+@@ -0,0 +1,236 @@
++/*
++ *	linux/drivers/video/bt431.h
++ *
++ *	Copyright 2003  Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
++ *
++ *	This file is subject to the terms and conditions of the GNU General
++ *	Public License. See the file COPYING in the main directory of this
++ *	archive for more details.
++ */
++#include <linux/types.h>
++#include <asm/system.h>
++
++/*
++ * Bt431 cursor generator registers, 32-bit aligned.
++ * Two twin Bt431 are used on the DECstation's PMAG-AA.
++ */
++struct bt431_regs {
++	volatile u16 addr_lo;
++	u16 pad0;
++	volatile u16 addr_hi;
++	u16 pad1;
++	volatile u16 addr_cmap;
++	u16 pad2;
++	volatile u16 addr_reg;
++	u16 pad3;
++};
++
++static inline u16 bt431_set_value(u8 val)
++{
++	return ((val << 8) | (val & 0xff)) & 0xffff;
++}
++
++static inline u8 bt431_get_value(u16 val)
++{
++	return val & 0xff;
++}
++
++/*
++ * Additional registers addressed indirectly.
++ */
++#define BT431_REG_CMD		0x0000
++#define BT431_REG_CXLO		0x0001
++#define BT431_REG_CXHI		0x0002
++#define BT431_REG_CYLO		0x0003
++#define BT431_REG_CYHI		0x0004
++#define BT431_REG_WXLO		0x0005
++#define BT431_REG_WXHI		0x0006
++#define BT431_REG_WYLO		0x0007
++#define BT431_REG_WYHI		0x0008
++#define BT431_REG_WWLO		0x0009
++#define BT431_REG_WWHI		0x000a
++#define BT431_REG_WHLO		0x000b
++#define BT431_REG_WHHI		0x000c
++
++#define BT431_REG_CRAM_BASE	0x0000
++#define BT431_REG_CRAM_END	0x01ff
++
++/*
++ * Command register.
++ */
++#define BT431_CMD_CURS_ENABLE	0x40
++#define BT431_CMD_XHAIR_ENABLE	0x20
++#define BT431_CMD_OR_CURSORS	0x10
++#define BT431_CMD_AND_CURSORS	0x00
++#define BT431_CMD_1_1_MUX	0x00
++#define BT431_CMD_4_1_MUX	0x04
++#define BT431_CMD_5_1_MUX	0x08
++#define BT431_CMD_xxx_MUX	0x0c
++#define BT431_CMD_THICK_1	0x00
++#define BT431_CMD_THICK_3	0x01
++#define BT431_CMD_THICK_5	0x02
++#define BT431_CMD_THICK_7	0x03
++
++static inline void bt431_select_reg(struct bt431_regs *regs, int ir)
++{
++	/*
++	 * The compiler splits the write in two bytes without these
++	 * helper variables.
++	 */
++	volatile u16 *lo = &(regs->addr_lo);
++	volatile u16 *hi = &(regs->addr_hi);
++
++	mb();
++	*lo = bt431_set_value(ir & 0xff);
++	wmb();
++	*hi = bt431_set_value((ir >> 8) & 0xff);
++}
++
++/* Autoincrement read/write. */
++static inline u8 bt431_read_reg_inc(struct bt431_regs *regs)
++{
++	/*
++	 * The compiler splits the write in two bytes without the
++	 * helper variable.
++	 */
++	volatile u16 *r = &(regs->addr_reg);
++
++	mb();
++	return bt431_get_value(*r);
++}
++
++static inline void bt431_write_reg_inc(struct bt431_regs *regs, u8 value)
++{
++	/*
++	 * The compiler splits the write in two bytes without the
++	 * helper variable.
++	 */
++	volatile u16 *r = &(regs->addr_reg);
++
++	mb();
++	*r = bt431_set_value(value);
++}
++
++static inline u8 bt431_read_reg(struct bt431_regs *regs, int ir)
++{
++	bt431_select_reg(regs, ir);
++	return bt431_read_reg_inc(regs);
++}
++
++static inline void bt431_write_reg(struct bt431_regs *regs, int ir, u8 value)
++{
++	bt431_select_reg(regs, ir);
++	bt431_write_reg_inc(regs, value);
++}
++
++/* Autoincremented read/write for the cursor map. */
++static inline u16 bt431_read_cmap_inc(struct bt431_regs *regs)
++{
++	/*
++	 * The compiler splits the write in two bytes without the
++	 * helper variable.
++	 */
++	volatile u16 *r = &(regs->addr_cmap);
++
++	mb();
++	return *r;
++}
++
++static inline void bt431_write_cmap_inc(struct bt431_regs *regs, u16 value)
++{
++	/*
++	 * The compiler splits the write in two bytes without the
++	 * helper variable.
++	 */
++	volatile u16 *r = &(regs->addr_cmap);
++
++	mb();
++	*r = value;
++}
++
++static inline u16 bt431_read_cmap(struct bt431_regs *regs, int cr)
++{
++	bt431_select_reg(regs, cr);
++	return bt431_read_cmap_inc(regs);
++}
++
++static inline void bt431_write_cmap(struct bt431_regs *regs, int cr, u16 value)
++{
++	bt431_select_reg(regs, cr);
++	bt431_write_cmap_inc(regs, value);
++}
++
++static inline void bt431_enable_cursor(struct bt431_regs *regs)
++{
++	bt431_write_reg(regs, BT431_REG_CMD,
++			BT431_CMD_CURS_ENABLE | BT431_CMD_OR_CURSORS
++			| BT431_CMD_4_1_MUX | BT431_CMD_THICK_1);
++}
++
++static inline void bt431_erase_cursor(struct bt431_regs *regs)
++{
++	bt431_write_reg(regs, BT431_REG_CMD, BT431_CMD_4_1_MUX);
++}
++
++static inline void bt431_position_cursor(struct bt431_regs *regs, u16 x, u16 y)
++{
++	/*
++	 * Magic from the MACH sources.
++	 * 
++	 * Cx = x + D + H - P
++	 *  P = 37 if 1:1, 52 if 4:1, 57 if 5:1
++	 *  D = pixel skew between outdata and external data
++	 *  H = pixels between HSYNCH falling and active video
++	 *
++	 * Cy = y + V - 32
++	 *  V = scanlines between HSYNCH falling, two or more
++	 *      clocks after VSYNCH falling, and active video
++	 */
++	x += 412 - 52;
++	y += 68 - 32;
++
++	/* Use autoincrement. */
++	bt431_select_reg(regs, BT431_REG_CXLO);
++	bt431_write_reg_inc(regs, x & 0xff); /* BT431_REG_CXLO */
++	bt431_write_reg_inc(regs, (x >> 8) & 0x0f); /* BT431_REG_CXHI */
++	bt431_write_reg_inc(regs, y & 0xff); /* BT431_REG_CYLO */
++	bt431_write_reg_inc(regs, (y >> 8) & 0x0f); /* BT431_REG_CYHI */
++}
++
++static inline void bt431_set_font(struct bt431_regs *regs, u8 fgc,
++				  u16 width, u16 height)
++{
++	int i;
++	u16 fgp = fgc ? 0xffff : 0x0000;
++	u16 bgp = fgc ? 0x0000 : 0xffff;
++
++	bt431_select_reg(regs, BT431_REG_CRAM_BASE);
++	for (i = BT431_REG_CRAM_BASE; i <= BT431_REG_CRAM_END; i++) {
++		u16 value;
++
++		if (height << 6 <= i << 3)
++			value = bgp;
++		else if (width <= i % 8 << 3)
++			value = bgp;
++		else if (((width >> 3) & 0xffff) > i % 8)
++			value = fgp;
++		else
++			value = fgp & ~(bgp << (width % 8 << 1));
++
++		bt431_write_cmap_inc(regs, value);
++	}
++}
++
++static inline void bt431_init_cursor(struct bt431_regs *regs)
++{
++	/* no crosshair window */
++	bt431_select_reg(regs, BT431_REG_WXLO);
++	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WXLO */
++	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WXHI */
++	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WYLO */
++	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WYHI */
++	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WWLO */
++	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WWHI */
++	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WHLO */
++	bt431_write_reg_inc(regs, 0x00); /* BT431_REG_WHHI */
++}
+diff -urpNX dontdiff linux-2.6.10/drivers/video/bt455.h linux-2.6.10-mips/drivers/video/bt455.h
+--- linux-2.6.10/drivers/video/bt455.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/bt455.h	2003-11-16 09:21:14.000000000 +0100
+@@ -0,0 +1,95 @@
++/*
++ *	linux/drivers/video/bt455.h
++ *
++ *	Copyright 2003  Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
++ *
++ *	This file is subject to the terms and conditions of the GNU General
++ *	Public License. See the file COPYING in the main directory of this
++ *	archive for more details.
++ */
++#include <linux/types.h>
++#include <asm/system.h>
++
++/*
++ * Bt455 byte-wide registers, 32-bit aligned.
++ */
++struct bt455_regs {
++	volatile u8 addr_cmap;
++	u8 pad0[3];
++	volatile u8 addr_cmap_data;
++	u8 pad1[3];
++	volatile u8 addr_clr;
++	u8 pad2[3];
++	volatile u8 addr_ovly;
++	u8 pad3[3];
++};
++
++static inline void bt455_select_reg(struct bt455_regs *regs, int ir)
++{
++	mb();
++	regs->addr_cmap = ir & 0x0f;
++}
++
++/*
++ * Read/write to a Bt455 color map register.
++ */
++static inline void bt455_read_cmap_entry(struct bt455_regs *regs, int cr,
++					 u8* red, u8* green, u8* blue)
++{
++	bt455_select_reg(regs, cr);
++	mb();
++	*red = regs->addr_cmap_data & 0x0f;
++	rmb();
++	*green = regs->addr_cmap_data & 0x0f;
++	rmb();
++	*blue = regs->addr_cmap_data & 0x0f;
++}
++
++static inline void bt455_write_cmap_entry(struct bt455_regs *regs, int cr,
++					  u8 red, u8 green, u8 blue)
++{
++	bt455_select_reg(regs, cr);
++	wmb();
++	regs->addr_cmap_data = red & 0x0f;
++	wmb();
++	regs->addr_cmap_data = green & 0x0f;
++	wmb();
++	regs->addr_cmap_data = blue & 0x0f;
++}
++
++static inline void bt455_write_ovly_entry(struct bt455_regs *regs, int cr,
++					  u8 red, u8 green, u8 blue)
++{
++	bt455_select_reg(regs, cr);
++	wmb();
++	regs->addr_ovly = red & 0x0f;
++	wmb();
++	regs->addr_ovly = green & 0x0f;
++	wmb();
++	regs->addr_ovly = blue & 0x0f;
++}
++
++static inline void bt455_set_cursor(struct bt455_regs *regs)
++{
++	mb();
++	regs->addr_ovly = 0x0f;
++	wmb();
++	regs->addr_ovly = 0x0f;
++	wmb();
++	regs->addr_ovly = 0x0f;
++}
++
++static inline void bt455_erase_cursor(struct bt455_regs *regs)
++{
++	/* bt455_write_cmap_entry(regs, 8, 0x00, 0x00, 0x00); */
++	/* bt455_write_cmap_entry(regs, 9, 0x00, 0x00, 0x00); */
++	bt455_write_ovly_entry(regs, 8, 0x03, 0x03, 0x03);
++	bt455_write_ovly_entry(regs, 9, 0x07, 0x07, 0x07);
++
++	wmb();
++	regs->addr_ovly = 0x09;
++	wmb();
++	regs->addr_ovly = 0x09;
++	wmb();
++	regs->addr_ovly = 0x09;
++}
+diff -urpNX dontdiff linux-2.6.10/drivers/video/console/newport_con.c linux-2.6.10-mips/drivers/video/console/newport_con.c
+--- linux-2.6.10/drivers/video/console/newport_con.c	2004-12-24 22:36:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/console/newport_con.c	2005-01-07 17:16:38.000000000 +0100
+@@ -21,6 +21,7 @@
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ 
++#include <asm/io.h>
+ #include <asm/uaccess.h>
+ #include <asm/system.h>
+ #include <asm/page.h>
+@@ -73,7 +74,7 @@ static int newport_set_def_font(int unit
+ static inline void newport_render_background(int xstart, int ystart,
+ 					     int xend, int yend, int ci)
+ {
+-	newport_wait();
++	newport_wait(npregs);
+ 	npregs->set.wrmask = 0xffffffff;
+ 	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
+ 				 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
+@@ -90,7 +91,7 @@ static inline void newport_init_cmap(voi
+ 	unsigned short i;
+ 
+ 	for (i = 0; i < 16; i++) {
+-		newport_bfwait();
++		newport_bfwait(npregs);
+ 		newport_cmap_setaddr(npregs, color_table[i]);
+ 		newport_cmap_setrgb(npregs,
+ 				    default_red[i],
+@@ -107,19 +108,19 @@ static void newport_show_logo(void)
+ 	unsigned long i;
+ 
+ 	for (i = 0; i < logo->clutsize; i++) {
+-		newport_bfwait();
++		newport_bfwait(npregs);
+ 		newport_cmap_setaddr(npregs, i + 0x20);
+ 		newport_cmap_setrgb(npregs, clut[0], clut[1], clut[2]);
+ 		clut += 3;
+ 	}
+ 
+-	newport_wait();
++	newport_wait(npregs);
+ 	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
+ 				 NPORT_DMODE0_CHOST);
+ 
+ 	npregs->set.xystarti = ((newport_xsize - logo->width) << 16) | (0);
+ 	npregs->set.xyendi = ((newport_xsize - 1) << 16);
+-	newport_wait();
++	newport_wait(npregs);
+ 
+ 	for (i = 0; i < logo->width*logo->height; i++)
+ 		npregs->go.hostrw0 = *data++ << 24;
+@@ -132,7 +133,7 @@ static inline void newport_clear_screen(
+ 	if (logo_active)
+ 		return;
+ 
+-	newport_wait();
++	newport_wait(npregs);
+ 	npregs->set.wrmask = 0xffffffff;
+ 	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
+ 				 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
+@@ -154,7 +155,7 @@ void newport_reset(void)
+ 	unsigned short treg;
+ 	int i;
+ 
+-	newport_wait();
++	newport_wait(npregs);
+ 	treg = newport_vc2_get(npregs, VC2_IREG_CONTROL);
+ 	newport_vc2_set(npregs, VC2_IREG_CONTROL,
+ 			(treg | VC2_CTRL_EVIDEO));
+@@ -164,7 +165,7 @@ void newport_reset(void)
+ 	npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
+ 			       NPORT_DMODE_W2 | VC2_PROTOCOL);
+ 	for (i = 0; i < 128; i++) {
+-		newport_bfwait();
++		newport_bfwait(npregs);
+ 		if (i == 92 || i == 94)
+ 			npregs->set.dcbdata0.byshort.s1 = 0xff00;
+ 		else
+@@ -204,7 +205,7 @@ void newport_get_screensize(void)
+ 	npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
+ 			       NPORT_DMODE_W2 | VC2_PROTOCOL);
+ 	for (i = 0; i < 128; i++) {
+-		newport_bfwait();
++		newport_bfwait(npregs);
+ 		linetable[i] = npregs->set.dcbdata0.byshort.s1;
+ 	}
+ 
+@@ -215,12 +216,12 @@ void newport_get_screensize(void)
+ 		npregs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
+ 				       NPORT_DMODE_W2 | VC2_PROTOCOL);
+ 		do {
+-			newport_bfwait();
++			newport_bfwait(npregs);
+ 			treg = npregs->set.dcbdata0.byshort.s1;
+ 			if ((treg & 1) == 0)
+ 				cols += (treg >> 7) & 0xfe;
+ 			if ((treg & 0x80) == 0) {
+-				newport_bfwait();
++				newport_bfwait(npregs);
+ 				treg = npregs->set.dcbdata0.byshort.s1;
+ 			}
+ 		} while ((treg & 0x8000) == 0);
+@@ -290,16 +291,16 @@ static const char *newport_startup(void)
+ 
+ 	if (!sgi_gfxaddr)
+ 		return NULL;
+-	npregs = (struct newport_regs *) (KSEG1 + sgi_gfxaddr);
++	npregs = (struct newport_regs *)	/* ioremap cannot fail */
++		 ioremap(sgi_gfxaddr, sizeof(struct newport_regs));
+ 	npregs->cset.config = NPORT_CFG_GD0;
+ 
+-	if (newport_wait()) {
+-		return NULL;
+-	}
++	if (newport_wait(npregs))
++		goto out_unmap;
+ 
+ 	npregs->set.xstarti = TESTVAL;
+ 	if (npregs->set._xstart.word != XSTI_TO_FXSTART(TESTVAL))
+-		return NULL;
++		goto out_unmap;
+ 
+ 	for (i = 0; i < MAX_NR_CONSOLES; i++)
+ 		font_data[i] = FONT_DATA;
+@@ -309,6 +310,10 @@ static const char *newport_startup(void)
+ 	newport_get_screensize();
+ 
+ 	return "SGI Newport";
++
++out_unmap:
++	iounmap((void *)npregs);
++	return NULL;
+ }
+ 
+ static void newport_init(struct vc_data *vc, int init)
+@@ -362,7 +367,7 @@ static void newport_putc(struct vc_data 
+ 				  (charattr & 0xf0) >> 4);
+ 
+ 	/* Set the color and drawing mode. */
+-	newport_wait();
++	newport_wait(npregs);
+ 	npregs->set.colori = charattr & 0xf;
+ 	npregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
+ 				 NPORT_DMODE0_STOPX | NPORT_DMODE0_ZPENAB |
+@@ -371,7 +376,7 @@ static void newport_putc(struct vc_data 
+ 	/* Set coordinates for bitmap operation. */
+ 	npregs->set.xystarti = (xpos << 16) | ((ypos + topscan) & 0x3ff);
+ 	npregs->set.xyendi = ((xpos + 7) << 16);
+-	newport_wait();
++	newport_wait(npregs);
+ 
+ 	/* Go, baby, go... */
+ 	RENDER(npregs, p);
+@@ -395,7 +400,7 @@ static void newport_putcs(struct vc_data
+ 					  xpos + ((count - 1) << 3), ypos,
+ 					  (charattr & 0xf0) >> 4);
+ 
+-	newport_wait();
++	newport_wait(npregs);
+ 
+ 	/* Set the color and drawing mode. */
+ 	npregs->set.colori = charattr & 0xf;
+@@ -406,7 +411,7 @@ static void newport_putcs(struct vc_data
+ 	for (i = 0; i < count; i++, xpos += 8) {
+ 		p = &font_data[vc->vc_num][(scr_readw(s++) & 0xff) << 4];
+ 
+-		newport_wait();
++		newport_wait(npregs);
+ 
+ 		/* Set coordinates for bitmap operation. */
+ 		npregs->set.xystarti =
+@@ -459,7 +464,7 @@ static int newport_switch(struct vc_data
+ 	return 1;
+ }
+ 
+-static int newport_blank(struct vc_data *c, int blank)
++static int newport_blank(struct vc_data *c, int blank, int mode_switch)
+ {
+ 	unsigned short treg;
+ 
+@@ -684,7 +689,7 @@ static void newport_bmove(struct vc_data
+ 		xe = xs;
+ 		xs = tmp;
+ 	}
+-	newport_wait();
++	newport_wait(npregs);
+ 	npregs->set.drawmode0 = (NPORT_DMODE0_S2S | NPORT_DMODE0_BLOCK |
+ 				 NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX
+ 				 | NPORT_DMODE0_STOPY);
+@@ -701,24 +706,24 @@ static int newport_dummy(struct vc_data 
+ #define DUMMY (void *) newport_dummy
+ 
+ const struct consw newport_con = {
+-    .owner =		THIS_MODULE,
+-    .con_startup =	newport_startup,
+-    .con_init =		newport_init,
+-    .con_deinit =	newport_deinit,
+-    .con_clear =	newport_clear,
+-    .con_putc =		newport_putc,
+-    .con_putcs =	newport_putcs,
+-    .con_cursor =	newport_cursor,
+-    .con_scroll =	newport_scroll,
+-    .con_bmove =	newport_bmove,
+-    .con_switch =	newport_switch,
+-    .con_blank =	newport_blank,
+-    .con_font_set =	newport_font_set,
+-    .con_font_default =	newport_font_default,
+-    .con_set_palette =	newport_set_palette,
+-    .con_scrolldelta =	newport_scrolldelta,
+-    .con_set_origin =	DUMMY,
+-    .con_save_screen =	DUMMY
++	.owner		  = THIS_MODULE,
++	.con_startup	  = newport_startup,
++	.con_init	  = newport_init,
++	.con_deinit	  = newport_deinit,
++	.con_clear	  = newport_clear,
++	.con_putc	  = newport_putc,
++	.con_putcs	  = newport_putcs,
++	.con_cursor	  = newport_cursor,
++	.con_scroll	  = newport_scroll,
++	.con_bmove 	  = newport_bmove,
++	.con_switch	  = newport_switch,
++	.con_blank	  = newport_blank,
++	.con_font_set	  = newport_font_set,
++	.con_font_default = newport_font_default,
++	.con_set_palette  = newport_set_palette,
++	.con_scrolldelta  = newport_scrolldelta,
++	.con_set_origin	  = DUMMY,
++	.con_save_screen  = DUMMY
+ };
+ 
+ #ifdef MODULE
+@@ -730,6 +735,7 @@ static int __init newport_console_init(v
+ static void __exit newport_console_exit(void)
+ {
+ 	give_up_console(&newport_con);
++	iounmap((void *)npregs);
+ }
+ 
+ module_init(newport_console_init);
+diff -urpNX dontdiff linux-2.6.10/drivers/video/epson1356fb.c linux-2.6.10-mips/drivers/video/epson1356fb.c
+--- linux-2.6.10/drivers/video/epson1356fb.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/epson1356fb.c	2004-10-27 02:15:04.000000000 +0200
+@@ -0,0 +1,3117 @@
++/*
++ *      epson1356fb.c  --  Epson SED1356 Framebuffer Driver
++ *
++ * Copyright 2001, 2002 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc.
++ *         	stevel at mvista.com or source at mvista.com
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ *
++ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  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:
++ *
++ *  Revision history
++ *    03.12.2001  0.1   Initial release
++ *
++ */
++
++#include <linux/config.h>
++#include <linux/version.h>
++#include <linux/module.h>
++
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/mm.h>
++#include <linux/tty.h>
++#include <linux/slab.h>
++#include <linux/vmalloc.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/fb.h>
++#include <linux/selection.h>
++#include <linux/console.h>
++#include <linux/init.h>
++#include <linux/pci.h>
++#include <linux/nvram.h>
++#include <linux/kd.h>
++#include <linux/vt_kern.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <linux/timer.h>
++#include <linux/pagemap.h>
++
++#include <asm/pgalloc.h>
++#include <asm/uaccess.h>
++#include <asm/tlb.h>
++
++#ifdef CONFIG_MTRR
++#include <asm/mtrr.h>
++#endif
++
++#include <video/fbcon.h>
++#include <video/fbcon-cfb8.h>
++#include <video/fbcon-cfb16.h>
++#include <video/fbcon-cfb24.h>
++#include <video/fbcon-cfb32.h>
++
++#include <linux/spinlock.h>
++
++#include <linux/e1356fb.h>
++
++#ifdef CONFIG_MIPS_AU1000
++#include <asm/au1000.h>
++#endif
++
++#define E1356FB_DEBUG 1
++#undef E1356FB_VERBOSE_DEBUG
++#undef SHADOW_FRAME_BUFFER
++#include "epson1356fb.h"
++
++static char *options;
++MODULE_PARM(options, "s");
++
++/*
++ *  Frame buffer device API
++ */
++static int e1356fb_open(struct fb_info *fb, int user);
++static int e1356fb_release(struct fb_info *fb, int user);
++static int e1356fb_get_fix(struct fb_fix_screeninfo* fix, 
++			   int con,
++			   struct fb_info* fb);
++static int e1356fb_get_var(struct fb_var_screeninfo* var, 
++			   int con,
++			   struct fb_info* fb);
++static int e1356fb_set_var(struct fb_var_screeninfo* var,
++			   int con,
++			   struct fb_info* fb);
++static int e1356fb_pan_display(struct fb_var_screeninfo* var, 
++			       int con,
++			       struct fb_info* fb);
++static int e1356fb_get_cmap(struct fb_cmap *cmap, 
++			    int kspc, 
++			    int con,
++			    struct fb_info* info);
++static int e1356fb_set_cmap(struct fb_cmap* cmap, 
++			    int kspc, 
++			    int con,
++			    struct fb_info* info);
++static int e1356fb_ioctl(struct inode* inode, 
++			 struct file* file, 
++			 u_int cmd,
++			 u_long arg, 
++			 int con, 
++			 struct fb_info* info);
++static int e1356fb_mmap(struct fb_info *info,
++			struct file *file,
++			struct vm_area_struct *vma);
++
++/*
++ *  Interface to the low level console driver
++ */
++static int  e1356fb_switch_con(int con, 
++			       struct fb_info* fb);
++static int  e1356fb_updatevar(int con, 
++			      struct fb_info* fb);
++static void e1356fb_blank(int blank, 
++			  struct fb_info* fb);
++
++/*
++ *  Internal routines
++ */
++static void e1356fb_set_par(const struct e1356fb_par* par,
++			    struct fb_info_e1356* 
++			    info);
++static int  e1356fb_var_to_par(const struct fb_var_screeninfo *var,
++			       struct e1356fb_par* par,
++			       const struct fb_info_e1356* info);
++static int  e1356fb_par_to_var(struct fb_var_screeninfo* var,
++			       struct e1356fb_par* par,
++			       const struct fb_info_e1356* info);
++static int  e1356fb_encode_fix(struct fb_fix_screeninfo* fix,
++			       const struct e1356fb_par* par,
++			       const struct fb_info_e1356* info);
++static void e1356fb_set_dispsw(struct display* disp, 
++			       struct fb_info_e1356* info,
++			       int bpp, 
++			       int accel);
++static int  e1356fb_getcolreg(u_int regno,
++			      u_int* red, 
++			      u_int* green, 
++			      u_int* blue,
++			      u_int* transp, 
++			      struct fb_info* fb);
++static int  e1356fb_setcolreg(u_int regno, 
++			      u_int red, 
++			      u_int green, 
++			      u_int blue,
++			      u_int transp, 
++			      struct fb_info* fb);
++static void  e1356fb_install_cmap(struct display *d, 
++				  struct fb_info *info);
++
++static void e1356fb_hwcursor_init(struct fb_info_e1356* info);
++static void e1356fb_createcursorshape(struct display* p);
++static void e1356fb_createcursor(struct display * p);  
++
++/*
++ * do_xxx: Hardware-specific functions
++ */
++static void  do_pan_var(struct fb_var_screeninfo* var,
++			struct fb_info_e1356* i);
++static void  do_flashcursor(unsigned long ptr);
++static void  doBlt_Move(const struct e1356fb_par* par,
++			struct fb_info_e1356* i,
++			blt_info_t* blt);
++static void  doBlt_SolidFill(const struct e1356fb_par* par,
++			     struct fb_info_e1356* i,
++			     blt_info_t* blt);
++
++/*
++ *  Interface used by the world
++ */
++int e1356fb_init(void);
++void e1356fb_setup(char *options, int *ints);
++
++static int currcon = 0;
++
++static struct fb_ops e1356fb_ops = {
++	owner:	THIS_MODULE,
++	fb_open:        e1356fb_open,
++	fb_release:     e1356fb_release,
++	fb_get_fix:	e1356fb_get_fix,
++	fb_get_var:	e1356fb_get_var,
++	fb_set_var:	e1356fb_set_var,
++	fb_get_cmap:    e1356fb_get_cmap,
++	fb_set_cmap:    e1356fb_set_cmap,
++	fb_pan_display: e1356fb_pan_display,
++	fb_mmap:        e1356fb_mmap,
++};
++
++#define PCI_VENDOR_ID_EPSON         0x10f4
++#define PCI_DEVICE_ID_EPSON_SDU1356 0x1300
++
++
++static struct fb_info_e1356 fb_info;
++static struct e1356fb_fix boot_fix; // boot options
++static struct e1356fb_par boot_par; // boot options
++
++static int e1356_remap_page_range(unsigned long from, phys_t phys_addr, unsigned long size, pgprot_t prot);
++
++
++/* ------------------------------------------------------------------------- 
++ *                      Hardware-specific funcions
++ * ------------------------------------------------------------------------- */
++
++/*
++ * The SED1356 has only a 16-bit wide data bus, so some embedded
++ * implementations with 32-bit CPU's (Alchemy Pb1000) may not
++ * correctly emulate a 32-bit write to the framebuffer by splitting
++ * the write into two seperate 16-bit writes. So it is safest to
++ * only do byte or half-word writes to the fb. This routine assumes
++ * fbaddr is atleast aligned on a half-word boundary.
++ */
++static inline void
++fbfill(u16* fbaddr, u8 val, int size)
++{
++	u16 valw = (u16)val | ((u16)val << 8);
++	for ( ; size >= 2; size -= 2)
++		writew(valw, fbaddr++);
++	if (size)
++		writeb(val, (u8*)fbaddr);
++}
++
++static inline int
++e1356_wait_bitclr(u8* reg, u8 bit, int timeout)
++{
++	while (readb(reg) & bit) {
++		udelay(10);
++		if (!--timeout)
++			break;
++	}
++	return timeout;
++}
++
++static inline int
++e1356_wait_bitset(u8* reg, u8 bit, int timeout)
++{
++	while (!(readb(reg) & bit)) {
++		udelay(10);
++		if (!--timeout)
++			break;
++	}
++	return timeout;
++}
++
++
++static struct fb_videomode panel_modedb[] = {
++	{
++		/* 320x240 @ 109 Hz, 33.3 kHz hsync */
++		NULL, 109, 320, 240, KHZ2PICOS(MAX_PIXCLOCK/3),
++		16, 16, 32, 24, 48, 8,
++		0, FB_VMODE_NONINTERLACED
++	}, {
++		/* 640x480 @ 84 Hz, 48.1 kHz hsync */
++		NULL, 84, 640, 480, KHZ2PICOS(MAX_PIXCLOCK/1),
++		96, 32, 32, 48, 64, 8,
++		0, FB_VMODE_NONINTERLACED
++	}, {
++		/* 800x600 @ 76 Hz, 46.3 kHz hsync */
++		NULL, 76, 800, 600, KHZ2PICOS(MAX_PIXCLOCK/1),
++		32, 10, 1, 1, 22, 1,
++		0, FB_VMODE_NONINTERLACED
++	}
++};
++static struct fb_videomode crt_modedb[] = {
++	{
++		/* 320x240 @ 84 Hz, 31.25 kHz hsync */
++		NULL, 84, 320, 240, KHZ2PICOS(MAX_PIXCLOCK/2),
++		128, 128, 60, 60, 64, 8,
++		0, FB_VMODE_NONINTERLACED
++	}, {
++		/* 320x240 @ 109 Hz, 33.3 kHz hsync */
++		NULL, 109, 320, 240, KHZ2PICOS(MAX_PIXCLOCK/3),
++		16, 16, 32, 24, 48, 8,
++		0, FB_VMODE_NONINTERLACED
++	}, {
++		/* 512x384 @ 77 Hz, 31.25 kHz hsync */
++		NULL, 77, 512, 384, KHZ2PICOS(MAX_PIXCLOCK/2),
++		48, 16, 16, 1, 64, 3,
++		0, FB_VMODE_NONINTERLACED
++	}, {
++		/* 640x400 @ 88 Hz, 43.1 kHz hsync */
++		NULL, 88, 640, 400, KHZ2PICOS(MAX_PIXCLOCK/1),
++		128, 96, 32, 48, 64, 8,
++		0, FB_VMODE_NONINTERLACED
++	}, {
++		/* 640x480 @ 84 Hz, 48.1 kHz hsync */
++		NULL, 84, 640, 480, KHZ2PICOS(MAX_PIXCLOCK/1),
++		96, 32, 32, 48, 64, 8,
++		0, FB_VMODE_NONINTERLACED
++	}, {
++		/* 768x576 @ 62 Hz, 38.5 kHz hsync */
++		NULL, 62, 768, 576, KHZ2PICOS(MAX_PIXCLOCK/1),
++		144, 16, 28, 6, 112, 4,
++		0, FB_VMODE_NONINTERLACED
++	}, {
++		/* 800x600 @ 60 Hz, 37.9 kHz hsync */
++		NULL, 60, 800, 600, KHZ2PICOS(MAX_PIXCLOCK/1),
++		88, 40, 23, 1, 128, 4,
++		FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,
++		FB_VMODE_NONINTERLACED
++	}
++};
++
++static struct fb_videomode ntsc_modedb[] = {
++	{
++		/* 640x480 @ 62 Hz, requires flicker filter */
++		//NULL, 62, 640, 480, 34921, 213, 57, 20, 2, 0, 0,
++		NULL, 62, 640, 480, KHZ2PICOS(2*NTSC_PIXCLOCK),
++		200, 70, 15, 7, 0, 0,
++		FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
++	}
++};
++static struct fb_videomode pal_modedb[] = {
++	{
++		/* 640x480 @ 56 Hz, requires flicker filter */
++		NULL, 56, 640, 480, KHZ2PICOS(2*PAL_PIXCLOCK),
++		350, 145, 49, 23, 0, 0,
++		FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
++	}
++};
++
++
++static inline void
++fb_videomode_to_var(struct fb_videomode* mode,
++		    struct fb_var_screeninfo*var)
++{
++	var->xres = mode->xres;
++	var->yres = mode->yres;
++	var->pixclock = mode->pixclock;
++	var->left_margin = mode->left_margin;
++	var->right_margin = mode->right_margin;
++	var->upper_margin = mode->upper_margin;
++	var->lower_margin = mode->lower_margin;
++	var->hsync_len = mode->hsync_len;
++	var->vsync_len = mode->vsync_len;
++	var->sync = mode->sync;
++	var->vmode = mode->vmode;
++}
++
++
++static int
++e1356fb_get_mode(const struct fb_info_e1356 *info,
++		 int xres,
++		 int yres,
++		 struct fb_videomode ** modedb,
++		 struct fb_videomode ** mode)
++{
++	struct fb_videomode * ret;
++	int i, dbsize;
++
++	if (IS_PANEL(info->fix.disp_type)) {
++		ret = panel_modedb;
++		dbsize = sizeof(panel_modedb)/sizeof(struct fb_videomode);
++	} else if (info->fix.disp_type == DISP_TYPE_CRT) {
++		ret = crt_modedb;
++		dbsize = sizeof(crt_modedb)/sizeof(struct fb_videomode);
++	} else if (info->fix.disp_type == DISP_TYPE_NTSC) {
++		ret = ntsc_modedb;
++		dbsize = sizeof(ntsc_modedb)/sizeof(struct fb_videomode);
++	} else {
++		ret = pal_modedb;
++		dbsize = sizeof(pal_modedb)/sizeof(struct fb_videomode);
++	}
++	
++	if (modedb)
++		*modedb = ret;
++	for (i=0; i<dbsize; i++) {
++		if (xres == ret[i].xres && yres == ret[i].yres) {
++			*mode = &ret[i];
++			break;
++		}
++	}
++	if (i == dbsize)
++		return -EINVAL;
++	return dbsize;
++}
++
++
++
++#ifdef E1356FB_VERBOSE_DEBUG
++static void
++dump_par(const struct e1356fb_par* par)
++{
++	DPRINTK("width:       %d\n", par->width);
++	DPRINTK("height:      %d\n", par->height);
++	DPRINTK("width_virt:  %d\n", par->width_virt);
++	DPRINTK("height_virt: %d\n", par->height_virt);
++	DPRINTK("bpp:         %d\n", par->bpp);
++	DPRINTK("pixclock:    %d\n", par->ipclk.pixclk);
++	DPRINTK("horiz_ndp:   %d\n", par->horiz_ndp);
++	DPRINTK("vert_ndp:    %d\n", par->vert_ndp);
++	DPRINTK("hsync_pol:   %d\n", par->hsync_pol);
++	DPRINTK("hsync_start: %d\n", par->hsync_start);
++	DPRINTK("hsync_width: %d\n", par->hsync_width);
++	DPRINTK("vsync_pol:   %d\n", par->vsync_pol);
++	DPRINTK("vsync_start: %d\n", par->vsync_start);
++	DPRINTK("vsync_width: %d\n", par->vsync_width);
++	DPRINTK("cmap_len:    %d\n", par->cmap_len);
++}
++
++static void
++dump_display_regs(reg_dispcfg_t* dispcfg, reg_dispmode_t* dispmode)
++{
++	DPRINTK("hdw:            0x%02x\n", readb(&dispcfg->hdw));
++	DPRINTK("hndp:           0x%02x\n", readb(&dispcfg->hndp));
++	DPRINTK("hsync_start:    0x%02x\n", readb(&dispcfg->hsync_start));
++	DPRINTK("hsync_pulse:    0x%02x\n", readb(&dispcfg->hsync_pulse));
++	DPRINTK("vdh0:           0x%02x\n", readb(&dispcfg->vdh0));
++	DPRINTK("vdh1:           0x%02x\n", readb(&dispcfg->vdh1));
++	DPRINTK("vndp:           0x%02x\n", readb(&dispcfg->vndp));
++	DPRINTK("vsync_start:    0x%02x\n", readb(&dispcfg->vsync_start));
++	DPRINTK("vsync_pulse:    0x%02x\n", readb(&dispcfg->vsync_pulse));
++	DPRINTK("tv_output_ctrl: 0x%02x\n\n", readb(&dispcfg->tv_output_ctrl));
++
++	DPRINTK("disp_mode:        0x%02x\n", readb(&dispmode->disp_mode));
++	DPRINTK("lcd_misc:         0x%02x\n", readb(&dispmode->lcd_misc));
++	DPRINTK("start_addr0:      0x%02x\n", readb(&dispmode->start_addr0));
++	DPRINTK("start_addr1:      0x%02x\n", readb(&dispmode->start_addr1));
++	DPRINTK("start_addr2:      0x%02x\n", readb(&dispmode->start_addr2));
++	DPRINTK("mem_addr_offset0: 0x%02x\n", readb(&dispmode->mem_addr_offset0));
++	DPRINTK("mem_addr_offset1: 0x%02x\n", readb(&dispmode->mem_addr_offset1));
++	DPRINTK("pixel_panning:    0x%02x\n", readb(&dispmode->pixel_panning));
++	DPRINTK("fifo_high_thresh: 0x%02x\n", readb(&dispmode->fifo_high_thresh));
++	DPRINTK("fifo_low_thresh:  0x%02x\n", readb(&dispmode->fifo_low_thresh));
++}
++
++static void
++dump_fb(u8* base, int len)
++{
++	int i;
++	DPRINTK("FB memory dump, start 0x%p, len %d", base, len);
++	for (i=0; i<len; i++) {
++		if (!(i%16))
++			printk("\n%p: %02x ", &base[i], readb(&base[i]));
++		else
++			printk("%02x ", readb(&base[i]));
++	}
++	printk("\n");
++}
++
++#endif // E1356FB_VERBOSE_DEBUG
++
++
++
++// Input:  ipclk->clksrc, ipclk->pixclk_d
++// Output: ipclk->pixclk, ipclk->error, and ipclk->divisor
++static int
++get_nearest_pixclk_div(pixclock_info_t* ipclk, int x2)
++{
++	int pixclk_d = ipclk->pixclk_d;
++	int clksrc = ipclk->clksrc;
++
++	if (x2) clksrc *= 2;
++
++	if (clksrc < (3*pixclk_d+1)/2)
++		ipclk->divisor = 1;
++	else if (clksrc < (5*pixclk_d+1)/2)
++		ipclk->divisor = 2;
++	else if (clksrc < (7*pixclk_d+1)/2)
++		ipclk->divisor = 3;
++	else if (clksrc < (9*pixclk_d+1)/2)
++		ipclk->divisor = 4;
++	else
++		return -ENXIO;
++
++	ipclk->pixclk = clksrc / ipclk->divisor;
++	ipclk->error = (100*(pixclk_d - ipclk->pixclk)) / pixclk_d;
++	return 0;
++}
++
++static int
++e1356_calc_pixclock(const struct fb_info_e1356 *info,
++		    pixclock_info_t* ipclk)
++{
++	int src_sel=-1, flicker_mult=0;
++	pixclock_info_t test, ret;
++    
++	if (ipclk->pixclk > info->max_pixclock)
++		return -ENXIO;
++
++	test.pixclk_d = ipclk->pixclk_d;
++	ret.error = 100;
++	
++	if (IS_TV(info->fix.disp_type) &&
++	    (info->fix.tv_filt & TV_FILT_FLICKER))
++		flicker_mult = 0x80;
++	
++	test.clksrc = info->fix.busclk;
++	if (get_nearest_pixclk_div(&test, flicker_mult != 0) == 0 &&
++	    abs(test.error) < abs(ret.error)) {
++		ret = test;
++		src_sel = 0x01;
++	}
++
++	test.clksrc = info->fix.mclk;
++	if (get_nearest_pixclk_div(&test, flicker_mult != 0) == 0 &&
++	    abs(test.error) < abs(ret.error)) {
++		ret = test;
++		src_sel = 0x03;
++	}
++
++	test.clksrc = info->fix.clki;
++	if (get_nearest_pixclk_div(&test, flicker_mult != 0) == 0 &&
++	    abs(test.error) < abs(ret.error)) {
++		ret = test;
++		src_sel = 0x00;
++	}
++
++	test.clksrc = info->fix.clki2;
++	if (get_nearest_pixclk_div(&test, flicker_mult != 0) == 0 &&
++	    abs(test.error) < abs(ret.error)) {
++		ret = test;
++		src_sel = 0x02;
++	}
++
++	if (ret.error > MAX_PCLK_ERROR_LOWER ||
++	    ret.error < MAX_PCLK_ERROR_HIGHER)
++		return -ENXIO;
++    
++	ret.pixclk_bits = flicker_mult | ((ret.divisor-1)<<4) | src_sel;
++	*ipclk = ret;
++	return 0;
++}
++
++static inline int
++e1356_engine_wait_complete(reg_bitblt_t* bltreg)
++{
++	return e1356_wait_bitclr(&bltreg->ctrl0, 0x80, 5000);
++}
++static inline int
++e1356_engine_wait_busy(reg_bitblt_t* bltreg)
++{
++	return e1356_wait_bitset(&bltreg->ctrl0, 0x80, 5000);
++}
++
++static void
++e1356fb_engine_init(const struct e1356fb_par* par,
++		    struct fb_info_e1356* info)
++{
++	reg_bitblt_t* bltreg = info->reg.bitblt;
++    
++	e1356_engine_wait_complete(bltreg);
++
++	writeb(0, &bltreg->ctrl0);
++	writeb(0, &bltreg->ctrl1);
++	writeb(0, &bltreg->rop_code);
++	writeb(0, &bltreg->operation);
++	writeb(0, &bltreg->src_start_addr0);
++	writeb(0, &bltreg->src_start_addr1);
++	writeb(0, &bltreg->src_start_addr2);
++	writeb(0, &bltreg->dest_start_addr0);
++	writeb(0, &bltreg->dest_start_addr1);
++	writeb(0, &bltreg->dest_start_addr2);
++	writew(0, &bltreg->mem_addr_offset0);
++	writew(0, &bltreg->width0);
++	writew(0, &bltreg->height0);
++	writew(0, &bltreg->bg_color0);
++	writew(0, &bltreg->fg_color0);
++}
++
++
++static void doBlt_Write(const struct e1356fb_par* par,
++			struct fb_info_e1356* info,
++			blt_info_t* blt)
++{
++	reg_bitblt_t* bltreg = info->reg.bitblt;
++	int nWords, nTotalWords;
++	u32 srcphase, dstAddr;
++	u16* w16;
++	u32 stride = par->width_virt * par->Bpp;
++
++	dstAddr = blt->dst_x * par->Bpp + blt->dst_y * stride;
++	srcphase = (u32)blt->src & 1;
++    
++	if (blt->attribute & BLT_ATTR_TRANSPARENT)
++		writew(blt->bg_color, &bltreg->bg_color0);
++	else
++		writeb(blt->rop, &bltreg->rop_code);
++    
++	writeb(blt->operation, &bltreg->operation);
++	writeb((u8)srcphase, &bltreg->src_start_addr0);
++	writew(stride/2, &bltreg->mem_addr_offset0);
++
++	writeb(dstAddr, &bltreg->dest_start_addr0);
++	writeb(dstAddr>>8, &bltreg->dest_start_addr1);
++	writeb(dstAddr>>16, &bltreg->dest_start_addr2);
++
++	writew(blt->dst_width-1, &bltreg->width0);
++	writew(blt->dst_height-1, &bltreg->height0);
++
++	// program color format operation
++	writeb(par->bpp == 8 ? 0x00 : 0x01, &bltreg->ctrl1);
++
++	// start it up
++	writeb(0x80, &bltreg->ctrl0);
++
++	// wait for it to actually start
++	e1356_engine_wait_busy(bltreg);
++
++	// calculate the number of 16 bit words per one blt line
++
++	nWords = srcphase + ((blt->dst_width - srcphase)*par->Bpp + 1) / 2;
++	nTotalWords = nWords*blt->dst_height;
++	w16 = (u16*)((u32)blt->src & 0xfffffffe);   // Word aligned
++
++	while (nTotalWords > 0) {
++		int j, nFIFO;
++		u8 ctrl0;
++
++		// read the FIFO status
++		ctrl0 = readb(&bltreg->ctrl0);
++
++		if ((ctrl0 & 0x30) == 0x20)
++			// FIFO is at least half full, but not full
++			nFIFO = 1;
++		else if ((ctrl0 & 0x40) == 0)
++			// FIFO is empty
++			nFIFO = 16;
++		else
++			// FIFO is full
++			continue;
++
++		for (j = 0; j < nFIFO && nTotalWords > 0; j++,nTotalWords--)
++			writew(*w16++, info->reg.bitblt_data);
++	}
++
++	e1356_engine_wait_complete(bltreg);
++}
++
++
++static void
++doBlt_SolidFill(const struct e1356fb_par* par,
++		struct fb_info_e1356* info,
++		blt_info_t* blt)
++{
++	reg_bitblt_t* bltreg = info->reg.bitblt;
++	u32 width = blt->dst_width, height = blt->dst_height;
++	u32 stride = par->width_virt * par->Bpp;
++	u32 dest_addr = (blt->dst_y * stride) + (blt->dst_x * par->Bpp);
++
++	if (width == 0 || height == 0)
++		return;
++
++	// program dest address
++	writeb(dest_addr & 0x00ff, &bltreg->dest_start_addr0);
++	writeb((dest_addr>>8) & 0x00ff, &bltreg->dest_start_addr1);
++	writeb((dest_addr>>16) & 0x00ff, &bltreg->dest_start_addr2);
++
++	// program width and height of solid-fill blit
++	writew(width-1, &bltreg->width0);
++	writew(height-1, &bltreg->height0);
++
++	// program color of fill
++	writew(blt->fg_color, &bltreg->fg_color0);
++	// select solid-fill BLIT
++	writeb(BLT_SOLID_FILL, &bltreg->operation);
++	// program color format operation
++	writeb(par->bpp == 8 ? 0x00 : 0x01, &bltreg->ctrl1);
++	// program BLIT memory offset
++	writew(stride/2, &bltreg->mem_addr_offset0);
++
++	// start it up (self completes)
++	writeb(0x80, &bltreg->ctrl0);
++
++	e1356_engine_wait_complete(bltreg);
++}
++
++
++static void
++doBlt_Move(const struct e1356fb_par* par,
++	   struct fb_info_e1356* info,
++	   blt_info_t* blt)
++{
++	reg_bitblt_t* bltreg = info->reg.bitblt;
++	int neg_dir=0;
++	u32 dest_addr, src_addr;
++	u32 bpp = par->bpp;
++	u32 stride = par->width_virt * par->Bpp; // virt line length in bytes
++	u32 srcx = blt->src_x, srcy = blt->src_y;
++	u32 dstx = blt->dst_x, dsty = blt->dst_y;
++	u32 width = blt->dst_width, height = blt->dst_height;
++    
++	if (width == 0 || height == 0)
++		return;
++   
++	src_addr = srcx*par->Bpp + srcy*stride;
++	dest_addr = dstx*par->Bpp + dsty*stride;
++
++	/*
++	 * See if regions overlap and dest region is beyond source region.
++	 * If so, we need to do a move BLT in negative direction. Only applies
++	 * if the BLT is not transparent.
++	 */
++	if (!(blt->attribute & BLT_ATTR_TRANSPARENT)) {
++		if ((srcx + width  > dstx) && (srcx < dstx + width) &&
++		    (srcy + height > dsty) && (srcy < dsty + height) &&
++		    (dest_addr > src_addr)) {
++			neg_dir = 1;
++			// negative direction : get the coords of lower right corner
++			src_addr += stride * (height-1) + par->Bpp * (width-1);
++			dest_addr += stride * (height-1) + par->Bpp * (width-1);
++		}
++	}
++    
++	// program BLIT memory offset
++	writew(stride/2, &bltreg->mem_addr_offset0);
++
++	// program src and dest addresses
++	writeb(src_addr & 0x00ff, &bltreg->src_start_addr0);
++	writeb((src_addr>>8) & 0x00ff, &bltreg->src_start_addr1);
++	writeb((src_addr>>16) & 0x00ff, &bltreg->src_start_addr2);
++	writeb(dest_addr & 0x00ff, &bltreg->dest_start_addr0);
++	writeb((dest_addr>>8) & 0x00ff, &bltreg->dest_start_addr1);
++	writeb((dest_addr>>16) & 0x00ff, &bltreg->dest_start_addr2);
++
++	// program width and height of blit
++	writew(width-1, &bltreg->width0);
++	writew(height-1, &bltreg->height0);
++
++	// program color format operation
++	writeb(bpp == 8 ? 0x00 : 0x01, &bltreg->ctrl1);
++
++	// set the blt type
++	if (blt->attribute & BLT_ATTR_TRANSPARENT) {
++		writew(blt->bg_color, &bltreg->bg_color0);
++		writeb(BLT_MOVE_POS_TRANSP, &bltreg->operation); 
++	} else {
++		writeb(blt->rop, &bltreg->rop_code);
++		// select pos/neg move BLIT
++		writeb(neg_dir ? BLT_MOVE_NEG_ROP : BLT_MOVE_POS_ROP,
++		       &bltreg->operation); 
++	}
++
++	// start it up (self completes)
++	writeb(0x80, &bltreg->ctrl0);
++
++	e1356_engine_wait_complete(bltreg);
++}
++
++
++static void doBlt_ColorExpand(const struct e1356fb_par* par,
++			      struct fb_info_e1356* info,
++			      blt_info_t* blt)
++{
++	reg_bitblt_t* bltreg = info->reg.bitblt;
++	int i, j, nWords, Sx, Sy;
++	u32 dstAddr;
++	u16* wpt, *wpt1;
++	u32 stride = par->width_virt * par->Bpp;
++
++	if (blt->dst_width == 0 || blt->dst_height == 0)
++		return;
++
++	Sx = blt->src_x;
++	Sy = blt->src_y;
++
++	writeb((7 - Sx%8), &bltreg->rop_code);
++
++	writeb(blt->operation, &bltreg->operation);
++
++	writeb((u8)(Sx & 1), &bltreg->src_start_addr0);
++
++	dstAddr = blt->dst_x*par->Bpp + blt->dst_y * stride;
++	writeb(dstAddr, &bltreg->dest_start_addr0);
++	writeb(dstAddr>>8, &bltreg->dest_start_addr1);
++	writeb(dstAddr>>16, &bltreg->dest_start_addr2);
++
++	// program color format operation
++	writeb(par->bpp == 8 ? 0x00 : 0x01, &bltreg->ctrl1);
++	writew(stride/2, &bltreg->mem_addr_offset0);
++	writew(blt->dst_width-1, &bltreg->width0);
++	writew(blt->dst_height-1, &bltreg->height0);
++	writew(blt->bg_color, &bltreg->bg_color0);
++	writew(blt->fg_color, &bltreg->fg_color0);
++
++	// start it up
++	writeb(0x80, &bltreg->ctrl0);
++
++	// wait for it to actually start
++	e1356_engine_wait_busy(bltreg);
++
++	// calculate the number of 16 bit words per one blt line
++
++	nWords = (Sx%16 + blt->dst_width + 15)/16;
++
++	wpt = blt->src + (Sy*blt->srcstride + Sx/16)/2;
++
++	for (i = 0; i < blt->dst_height; i++) {
++		wpt1 = wpt;
++
++		for (j = 0; j < nWords; j++) {
++			// loop until FIFO becomes empty...
++			e1356_wait_bitclr(&bltreg->ctrl0, 0x40, 10000);
++			writew(*wpt1++, info->reg.bitblt_data);
++		}
++	
++		wpt += blt->srcstride/2;
++	}
++
++	e1356_engine_wait_complete(bltreg);
++}
++
++
++/*
++ * The BitBLT operation dispatcher
++ */
++static int
++doBlt(const struct e1356fb_par* par,
++      struct fb_info_e1356* info,
++      blt_info_t* blt)
++{
++	/*
++	 * Make sure we're not reentering in the middle of an
++	 * active BitBLT operation. ALWAYS call this dispatcher
++	 * and not one of the above BLT routines directly, or you
++	 * run the risk of overlapping BLT operations, which can
++	 * cause complete system hangs.
++     */
++	if (readb(&info->reg.bitblt->ctrl0) & 0x80)
++		return -ENXIO;
++    
++	switch (blt->operation) {
++	case BLT_MOVE_POS_ROP:
++	case BLT_MOVE_NEG_ROP:
++	case BLT_MOVE_POS_TRANSP:
++		doBlt_Move(par, info, blt);
++		break;
++	case BLT_COLOR_EXP:
++	case BLT_COLOR_EXP_TRANSP:
++		doBlt_ColorExpand(par, info, blt);
++		break;
++	case BLT_SOLID_FILL:
++		doBlt_SolidFill(par, info, blt);
++		break;
++	case BLT_WRITE_ROP:
++	case BLT_WRITE_TRANSP:
++		doBlt_Write(par, info, blt);
++		break;
++	case BLT_READ:
++	case BLT_PAT_FILL_ROP:
++	case BLT_PAT_FILL_TRANSP:
++	case BLT_MOVE_COLOR_EXP:
++	case BLT_MOVE_COLOR_EXP_TRANSP:
++		DPRINTK("BitBLT operation 0x%02x not implemented yet\n",
++			blt->operation);
++		return -ENXIO;
++	default:
++		DPRINTK("Unknown BitBLT operation 0x%02x\n", blt->operation);
++		return -ENXIO;
++	}
++    
++	return 0;
++}
++
++
++// Initializes blt->src and blt->srcstride
++static void fill_putcs_buffer(struct display *p,
++			      blt_info_t* blt,
++			      const unsigned short* str,
++			      int count)
++{   
++	int row, i, j;
++	u8* b1, *b2;
++	u32 fw = fontwidth(p);
++	u32 fwb = (fw + 7) >> 3;
++	u32 fh = fontheight(p);
++	int bytesPerChar = fwb * fh;
++
++	if (count*bytesPerChar > PAGE_SIZE) {
++		// Truncate the string if it overflows putcs_buffer, which is
++		// one page in size.
++		count = PAGE_SIZE/bytesPerChar - 1;
++	}
++
++	blt->srcstride = (fwb*count + 1) & ~1; //round up to be even
++	
++	b1 = (u8*)blt->src;
++
++	for (row = 0; row < fh; row++) {
++		b2 = b1;
++		for (i = 0; i < count; i++) {
++			for (j=0; j<fwb; j++)
++				*b2++ = p->fontdata[(str[i] & p->charmask) *
++						   bytesPerChar +
++						   row*fwb + j];
++		}
++		b1 += blt->srcstride;
++	}
++}
++
++
++/*
++ * Set the color of a palette entry in 8bpp mode 
++ */
++static inline void
++do_setpalentry(reg_lut_t* lut, unsigned regno,
++	       u8 r, u8 g, u8 b)
++{
++	writeb(0x00, &lut->mode);
++	writeb((u8)regno, &lut->addr);
++	writeb(r&0xf0, &lut->data);
++	writeb(g&0xf0, &lut->data);
++	writeb(b&0xf0, &lut->data);
++}
++
++   
++static void
++do_pan_var(struct fb_var_screeninfo* var, struct fb_info_e1356* info)
++{
++	u32 pixel_start, start_addr;
++	u8 pixel_pan;
++	struct e1356fb_par* par = &info->current_par;
++	reg_misc_t* misc = info->reg.misc;
++	reg_dispmode_t* dispmode = (IS_PANEL(info->fix.disp_type)) ?
++		info->reg.lcd_mode : info->reg.crttv_mode;
++	
++	pixel_start = var->yoffset * par->width_virt + var->xoffset;
++	start_addr = (pixel_start * par->Bpp) / 2;
++	pixel_pan = (par->bpp == 8) ? (u8)(pixel_start & 1) : 0;
++    
++	if (readb(&misc->disp_mode) != 0) {
++		reg_dispcfg_t* dispcfg = (IS_PANEL(info->fix.disp_type)) ?
++			info->reg.lcd_cfg : info->reg.crttv_cfg;
++
++		// wait for the end of the current VNDP
++		e1356_wait_bitclr(&dispcfg->vndp, 0x80, 5000);
++		// now wait for the start of a new VNDP
++		e1356_wait_bitset(&dispcfg->vndp, 0x80, 5000);
++	}
++    
++	writeb((u8)(start_addr & 0xff), &dispmode->start_addr0);
++	writeb((u8)((start_addr>>8) & 0xff), &dispmode->start_addr1);
++	writeb((u8)((start_addr>>16) & 0xff), &dispmode->start_addr2);
++	writeb(pixel_pan, &dispmode->pixel_panning);
++}
++
++
++/*
++ * Invert the hardware cursor image (timerfunc)  
++ */
++static void
++do_flashcursor(unsigned long ptr)
++{
++	u8 curs_ctrl;
++	struct fb_info_e1356* info = (struct fb_info_e1356 *)ptr;
++	reg_inkcurs_t* inkcurs = (IS_PANEL(info->fix.disp_type)) ?
++		info->reg.lcd_inkcurs : info->reg.crttv_inkcurs;
++
++	spin_lock(&info->cursor.lock);
++	// toggle cursor enable bit
++	curs_ctrl = readb(&inkcurs->ctrl);
++	writeb((curs_ctrl ^ 0x01) & 0x01, &inkcurs->ctrl);
++	info->cursor.timer.expires = jiffies+HZ/2;
++	add_timer(&info->cursor.timer);
++	spin_unlock(&info->cursor.lock);
++}
++
++#ifdef SHADOW_FRAME_BUFFER
++/*
++ * Write BLT the shadow frame buffer to the real fb (timerfunc)  
++ */
++static void
++do_write_shadow_fb(unsigned long ptr)
++{
++	blt_info_t blt;
++	struct fb_info_e1356 *info = (struct fb_info_e1356*)ptr;
++	struct fb_info* fb = &info->fb_info;
++	struct e1356fb_par* par = &info->current_par;
++	u32 stride = par->width_virt * par->Bpp;
++
++	unsigned long j_start = jiffies;
++    
++	blt.src_x = blt.src_y = 0;
++	blt.attribute = 0;
++	blt.dst_width = par->width;
++	blt.dst_height = par->height;
++	blt.dst_y = fb->var.yoffset;
++	blt.dst_x = fb->var.xoffset;
++	blt.operation = BLT_WRITE_ROP;
++	blt.rop = 0x0c; // ROP: destination = source
++	blt.src = (u16*)(info->shadow.fb + blt.dst_x * par->Bpp +
++			 blt.dst_y * stride);
++
++	doBlt(par, info, &blt);
++    
++	info->shadow.timer.expires = jiffies+HZ/2;
++	add_timer(&info->shadow.timer);
++
++	//DPRINTK("delta jiffies = %ld\n", jiffies - j_start);
++}
++#endif
++
++
++/* ------------------------------------------------------------------------- 
++ *              Hardware independent part, interface to the world
++ * ------------------------------------------------------------------------- */
++
++static void
++e1356_cfbX_clear_margins(struct vc_data* conp, struct display* p,
++			 int bottom_only)
++{
++	blt_info_t blt;
++	unsigned int cw=fontwidth(p);
++	unsigned int ch=fontheight(p);
++	unsigned int rw=p->var.xres % cw;
++	unsigned int bh=p->var.yres % ch;
++	unsigned int rs=p->var.xres - rw;
++	unsigned int bs=p->var.yres - bh;
++
++	//DPRINTK("\n");
++
++	if (!bottom_only && rw) { 
++		blt.dst_x = p->var.xoffset+rs;
++		blt.dst_y = p->var.yoffset;
++		blt.dst_height = p->var.yres;
++		blt.dst_width = rw;
++		blt.attribute = 0;
++		blt.fg_color = 0;
++		blt.operation = BLT_SOLID_FILL;
++		doBlt (&fb_info.current_par, &fb_info, &blt);
++	}
++    
++	if (bh) { 
++		blt.dst_x = p->var.xoffset;
++		blt.dst_y = p->var.yoffset+bs;
++		blt.dst_height = bh;
++		blt.dst_width = rs;
++		blt.attribute = 0;
++		blt.fg_color = 0;
++		blt.operation = BLT_SOLID_FILL;
++		doBlt (&fb_info.current_par, &fb_info, &blt);
++	}
++}
++
++static void
++e1356_cfbX_bmove(struct display* p, 
++		 int sy, 
++		 int sx, 
++		 int dy,
++		 int dx, 
++		 int height, 
++		 int width)
++{
++	blt_info_t blt;
++    
++	//DPRINTK("(%d,%d) to (%d,%d) size (%d,%d)\n", sx,sy,dx,dy,width,height);
++
++	blt.src_x = fontwidth_x8(p)*sx;
++	blt.src_y = fontheight(p)*sy;
++	blt.dst_x = fontwidth_x8(p)*dx;
++	blt.dst_y = fontheight(p)*dy;
++	blt.src_height = blt.dst_height = fontheight(p)*height;
++	blt.src_width = blt.dst_width = fontwidth_x8(p)*width;
++	blt.attribute = 0;
++	blt.rop = 0x0c;
++	/*
++	 * The move BLT routine will actually decide between a pos/neg
++	 * move BLT. This is just so that the BLT dispatcher knows to
++	 * call the move BLT routine.
++	 */
++	blt.operation = BLT_MOVE_POS_ROP;
++
++	doBlt (&fb_info.current_par, &fb_info, &blt);
++}
++
++static void
++e1356_cfb8_putc(struct vc_data* conp,
++		struct display* p,
++		int c, int yy,int xx)
++{   
++	blt_info_t blt;
++	u32 fgx,bgx;
++	u32 fw = fontwidth_x8(p);
++	u32 fh = fontheight(p);
++	u16 cs = (u16)c;
++
++	fgx = attr_fgcol(p, c);
++	bgx = attr_bgcol(p, c);
++
++	blt.src_x = blt.src_y = 0;
++	blt.attribute = 0;
++	blt.dst_width = fw;
++	blt.dst_height = fh;
++	blt.dst_y = yy * fh;
++	blt.dst_x = xx * fw;
++	blt.bg_color = bgx;
++	blt.fg_color = fgx;
++	blt.operation = BLT_COLOR_EXP;
++	blt.src = fb_info.putcs_buffer;
++	fill_putcs_buffer(p, &blt, &cs, 1);
++
++	doBlt(&fb_info.current_par, &fb_info, &blt);
++
++}
++
++static void
++e1356_cfb16_putc(struct vc_data* conp,
++		 struct display* p,
++		 int c, int yy,int xx)
++{   
++	blt_info_t blt;
++	u32 fgx,bgx;
++	u32 fw = fontwidth_x8(p);
++	u32 fh = fontheight(p);
++	u16 cs = (u16)c;
++    
++	fgx = ((u16*)p->dispsw_data)[attr_fgcol(p,c)];
++	bgx = ((u16*)p->dispsw_data)[attr_bgcol(p,c)];
++
++	blt.src_x = blt.src_y = 0;
++	blt.attribute = 0;
++	blt.dst_width = fw;
++	blt.dst_height = fh;
++	blt.dst_y = yy * fh;
++	blt.dst_x = xx * fw;
++	blt.bg_color = bgx;
++	blt.fg_color = fgx;
++	blt.operation = BLT_COLOR_EXP;
++	blt.src = fb_info.putcs_buffer;
++	fill_putcs_buffer(p, &blt, &cs, 1);
++
++	doBlt(&fb_info.current_par, &fb_info, &blt);
++}
++
++
++static void
++e1356_cfb8_putcs(struct vc_data* conp,
++		 struct display* p,
++		 const unsigned short *s,int count,int yy,int xx)
++{
++	blt_info_t blt;
++	u32 fgx,bgx;
++	u32 fw = fontwidth_x8(p);
++	u32 fh = fontheight(p);
++
++	//DPRINTK("\n");
++
++	fgx=attr_fgcol(p, *s);
++	bgx=attr_bgcol(p, *s);
++
++	blt.src_x = blt.src_y = 0;
++	blt.attribute = 0;
++	blt.dst_width = count * fw;
++	blt.dst_height = fh;
++	blt.dst_y = yy * fh;
++	blt.dst_x = xx * fw;
++	blt.bg_color = bgx;
++	blt.fg_color = fgx;
++	blt.operation = BLT_COLOR_EXP;
++	blt.src = fb_info.putcs_buffer;
++	fill_putcs_buffer(p, &blt, s, count);
++
++	doBlt(&fb_info.current_par, &fb_info, &blt);
++}
++
++static void
++e1356_cfb16_putcs(struct vc_data* conp,
++		  struct display* p,
++		  const unsigned short *s,int count,int yy,int xx)
++{
++	blt_info_t blt;
++	u32 fgx,bgx;
++	u32 fw = fontwidth_x8(p);
++	u32 fh = fontheight(p);
++
++	//DPRINTK("\n");
++
++	fgx=((u16*)p->dispsw_data)[attr_fgcol(p,*s)];
++	bgx=((u16*)p->dispsw_data)[attr_bgcol(p,*s)];
++
++	blt.src_x = blt.src_y = 0;
++	blt.attribute = 0;
++	blt.dst_width = count * fw;
++	blt.dst_height = fh;
++	blt.dst_y = yy * fh;
++	blt.dst_x = xx * fw;
++	blt.bg_color = bgx;
++	blt.fg_color = fgx;
++	blt.operation = BLT_COLOR_EXP;
++	blt.src = fb_info.putcs_buffer;
++	fill_putcs_buffer(p, &blt, s, count);
++
++	doBlt(&fb_info.current_par, &fb_info, &blt);
++}
++
++
++static void
++e1356_cfb8_clear(struct vc_data* conp, 
++		 struct display* p, 
++		 int sy,
++		 int sx, 
++		 int height, 
++		 int width)
++{
++	blt_info_t blt;
++	u32 bg = attr_bgcol_ec(p,conp);
++
++	//DPRINTK("(%d,%d) size (%d,%d)\n", sx,sy,width,height);
++
++	blt.dst_x = fontwidth_x8(p)*sx;
++	blt.dst_y = fontheight(p)*sy;
++	blt.dst_height = fontheight(p)*height;
++	blt.dst_width = fontwidth_x8(p)*width;
++	blt.attribute = 0;
++	blt.fg_color = bg;
++	blt.operation = BLT_SOLID_FILL;
++
++	doBlt (&fb_info.current_par, &fb_info, &blt);
++}
++
++static void
++e1356_cfb16_clear(struct vc_data* conp, 
++		  struct display* p, 
++		  int sy,
++		  int sx, 
++		  int height, 
++		  int width)
++{
++	blt_info_t blt;
++	u32 bg = ((u16*)p->dispsw_data)[attr_bgcol_ec(p,conp)];
++
++	//DPRINTK("(%d,%d) size (%d,%d)\n", sx,sy,width,height);
++
++	blt.dst_x = fontwidth_x8(p)*sx;
++	blt.dst_y = fontheight(p)*sy;
++	blt.dst_height = fontheight(p)*height;
++	blt.dst_width = fontwidth_x8(p)*width;
++	blt.attribute = 0;
++	blt.fg_color = bg;
++	blt.operation = BLT_SOLID_FILL;
++
++	doBlt (&fb_info.current_par, &fb_info, &blt);
++}
++
++
++static void
++e1356_cfbX_revc(struct display *p, int xx, int yy)
++{
++	// not used if h/w cursor
++	//DPRINTK("\n");
++}
++
++static void
++e1356_cfbX_cursor(struct display *p, int mode, int x, int y) 
++{
++	unsigned long flags;
++	struct fb_info_e1356 *info=(struct fb_info_e1356 *)p->fb_info;
++	reg_inkcurs_t* inkcurs = (IS_PANEL(info->fix.disp_type)) ?
++		info->reg.lcd_inkcurs : info->reg.crttv_inkcurs;
++    
++	//DPRINTK("\n");
++
++	if (mode == CM_ERASE) {
++		if (info->cursor.state != CM_ERASE) {
++			spin_lock_irqsave(&info->cursor.lock,flags);
++			info->cursor.state = CM_ERASE;
++			del_timer(&(info->cursor.timer));
++			writeb(0x00, &inkcurs->ctrl);
++			spin_unlock_irqrestore(&info->cursor.lock,flags);
++		}
++		return;
++	}
++    
++	if ((p->conp->vc_cursor_type & CUR_HWMASK) != info->cursor.type)
++		e1356fb_createcursor(p);
++    
++	x *= fontwidth_x8(p);
++	y *= fontheight(p);
++	x -= p->var.xoffset;
++	y -= p->var.yoffset;
++    
++	spin_lock_irqsave(&info->cursor.lock,flags);
++	if ((x != info->cursor.x) || (y != info->cursor.y) ||
++	    (info->cursor.redraw)) {
++		info->cursor.x = x;
++		info->cursor.y = y;
++		info->cursor.redraw = 0;
++		writeb(0x01, &inkcurs->ctrl);
++		writew(x, &inkcurs->x_pos0);
++		writew(y, &inkcurs->y_pos0);
++		/* fix cursor color - XFree86 forgets to restore it properly */
++		writeb(0x00, &inkcurs->blue0);
++		writeb(0x00, &inkcurs->green0);
++		writeb(0x00, &inkcurs->red0);
++		writeb(0x1f, &inkcurs->blue1);
++		writeb(0x3f, &inkcurs->green1);
++		writeb(0x1f, &inkcurs->red1);
++	}
++
++	info->cursor.state = CM_DRAW;
++	mod_timer(&info->cursor.timer, jiffies+HZ/2);
++	spin_unlock_irqrestore(&info->cursor.lock,flags);
++}
++
++#ifdef FBCON_HAS_CFB8
++static struct display_switch fbcon_e1356_8 = {
++	setup:		fbcon_cfb8_setup, 
++	bmove:		e1356_cfbX_bmove, 
++	clear:		e1356_cfb8_clear, 
++	putc:		e1356_cfb8_putc,
++	putcs:		e1356_cfb8_putcs, 
++	revc:		e1356_cfbX_revc,   
++	cursor:		e1356_cfbX_cursor, 
++	clear_margins:	e1356_cfbX_clear_margins,
++	fontwidthmask:	FONTWIDTHRANGE(6,16)
++};
++#endif
++
++#ifdef FBCON_HAS_CFB16
++static struct display_switch fbcon_e1356_16 = {
++	setup:		fbcon_cfb16_setup, 
++	bmove:		e1356_cfbX_bmove, 
++	clear:		e1356_cfb16_clear, 
++	putc:		e1356_cfb16_putc,
++	putcs:		e1356_cfb16_putcs, 
++	revc:		e1356_cfbX_revc, 
++	cursor:		e1356_cfbX_cursor, 
++	clear_margins:	e1356_cfbX_clear_margins,
++	fontwidthmask:	FONTWIDTHRANGE(6,16)
++};
++#endif
++
++/* ------------------------------------------------------------------------- */
++
++static void
++e1356fb_set_par(const struct e1356fb_par* par,
++		struct fb_info_e1356* info)
++{
++	reg_dispcfg_t* dispcfg=NULL;
++	reg_dispmode_t* dispmode=NULL;
++	u8* pclk_cfg=NULL;
++	u8 width, hndp=0, hsync_start=0, hsync_width=0;
++	u8 vndp, vsync_start, vsync_width=0, display_mode;
++	u8 main_display_mode=0;
++	u16 height, addr_offset;
++	int disp_type = info->fix.disp_type;
++
++	DPRINTK("%dx%d-%dbpp @ %d Hz, %d kHz hsync\n",
++		par->width, par->height, par->bpp,
++		par->vsync_freq, (((2*par->hsync_freq)/1000)+1)/2);
++#ifdef E1356FB_VERBOSE_DEBUG
++	dump_par(par);
++#endif
++    
++	info->current_par = *par;
++
++	width = (par->width >> 3) - 1;
++	display_mode = (par->bpp == 8) ? 0x03 : 0x05;
++	addr_offset = (par->width_virt * par->Bpp) / 2;
++	vsync_start = (disp_type == DISP_TYPE_LCD) ? 0 : par->vsync_start - 1;
++	height = par->height - 1;
++	vndp = par->vert_ndp - 1;
++
++	switch (disp_type) {
++	case DISP_TYPE_LCD:
++		dispcfg = info->reg.lcd_cfg;
++		dispmode = info->reg.lcd_mode;
++		pclk_cfg = &info->reg.clk_cfg->lcd_pclk_cfg;
++		hndp = (par->horiz_ndp >> 3) - 1;
++		hsync_start = 0;
++		hsync_width = par->hsync_pol ? 0x00 : 0x80;
++		vsync_width = par->vsync_pol ? 0x00 : 0x80;
++		main_display_mode = 0x01;
++		break;
++	case DISP_TYPE_TFT:
++		dispcfg = info->reg.lcd_cfg;
++		dispmode = info->reg.lcd_mode;
++		pclk_cfg = &info->reg.clk_cfg->lcd_pclk_cfg;
++		hndp = (par->horiz_ndp >> 3) - 1;
++		hsync_start = (par->bpp == 8) ?
++			(par->hsync_start - 4) >> 3 :
++				(par->hsync_start - 6) >> 3;
++		hsync_width =
++			(par->hsync_pol ? 0x80 : 0x00) |
++			((par->hsync_width >> 3) - 1);
++		vsync_width =
++			(par->vsync_pol ? 0x80 : 0x00) |
++			(par->vsync_width - 1);
++		main_display_mode = 0x01;
++		break;
++	case DISP_TYPE_CRT:
++		dispcfg = info->reg.crttv_cfg;
++		dispmode = info->reg.crttv_mode;
++		pclk_cfg = &info->reg.clk_cfg->crttv_pclk_cfg;
++		hndp = (par->horiz_ndp >> 3) - 1;
++		hsync_start = (par->bpp == 8) ?
++			(par->hsync_start - 3) >> 3 :
++				(par->hsync_start - 5) >> 3;
++		hsync_width =
++			(par->hsync_pol ? 0x80 : 0x00) |
++			((par->hsync_width >> 3) - 1);
++		vsync_width =
++			(par->vsync_pol ? 0x80 : 0x00) |
++			(par->vsync_width - 1);
++		main_display_mode = 0x02;
++		break;
++	case DISP_TYPE_NTSC:
++	case DISP_TYPE_PAL:
++		dispcfg = info->reg.crttv_cfg;
++		dispmode = info->reg.crttv_mode;
++		pclk_cfg = &info->reg.clk_cfg->crttv_pclk_cfg;
++		hndp = (disp_type == DISP_TYPE_PAL) ?
++			(par->horiz_ndp - 7) >> 3 :
++				(par->horiz_ndp - 6) >> 3;
++		hsync_start = (par->bpp == 8) ?
++			(par->hsync_start + 7) >> 3 :
++				(par->hsync_start + 5) >> 3;
++		hsync_width = 0;
++		vsync_width = 0;
++		main_display_mode = (info->fix.tv_filt & TV_FILT_FLICKER) ?
++			0x06 : 0x04;
++		break;
++	}
++
++	// Blast the regs!
++	// note: reset panning/scrolling (set start-addr and
++	// pixel pan regs to 0). Panning is handled by pan_display.
++
++	e1356_engine_wait_complete(info->reg.bitblt);
++
++	// disable display while initializing
++	writeb(0, &info->reg.misc->disp_mode);
++
++	writeb(par->ipclk.pixclk_bits, pclk_cfg);
++
++	writeb(width, &dispcfg->hdw);
++	writeb(hndp, &dispcfg->hndp);
++	writeb(hsync_start, &dispcfg->hsync_start);
++	writeb(hsync_width, &dispcfg->hsync_pulse);
++	writew(height, &dispcfg->vdh0);
++	writeb(vndp, &dispcfg->vndp);
++	writeb(vsync_start, &dispcfg->vsync_start);
++	writeb(vsync_width, &dispcfg->vsync_pulse);
++
++	writeb(display_mode, &dispmode->disp_mode);
++	if (info->fix.mmunalign && info->mmaped)
++		writeb(1, &dispmode->start_addr0);
++	else
++		writeb(0, &dispmode->start_addr0);
++	writeb(0, &dispmode->start_addr1);
++	writeb(0, &dispmode->start_addr2);
++	writew(addr_offset, &dispmode->mem_addr_offset0);
++	writeb(0, &dispmode->pixel_panning);
++
++	// reset BitBlt engine
++	e1356fb_engine_init(par, info);
++
++#ifdef E1356FB_VERBOSE_DEBUG
++	dump_display_regs(dispcfg, dispmode);
++#endif
++
++	/* clear out framebuffer memory */
++	fbfill(fb_info.membase_virt, 0, fb_info.fb_size);
++	// finally, enable display!
++	writeb(main_display_mode, &info->reg.misc->disp_mode); 
++}
++
++
++static int
++e1356fb_verify_timing(struct e1356fb_par* par,
++		      const struct fb_info_e1356* info)
++{
++	int disp_type = info->fix.disp_type;
++
++	// timing boundary checks
++	if (par->horiz_ndp > max_hndp[disp_type]) {
++		DPRINTK("horiz_ndp too big: %d\n", par->horiz_ndp);
++		return -EINVAL;
++	}
++	if (par->vert_ndp > max_vndp[disp_type]) {
++		DPRINTK("vert_ndp too big: %d\n", par->vert_ndp);
++		return -EINVAL;
++	}
++
++	if (disp_type != DISP_TYPE_LCD) {
++		if (par->hsync_start >
++		    max_hsync_start[(par->bpp==16)][disp_type]) {
++			DPRINTK("hsync_start too big: %d\n",
++				par->hsync_start);
++			return -EINVAL;
++		}
++		if (par->vsync_start > max_vsync_start[disp_type]) {
++			DPRINTK("vsync_start too big: %d\n",
++				par->vsync_start);
++			return -EINVAL;
++		}
++		if (!IS_TV(disp_type)) {
++			if (par->hsync_width > max_hsync_width[disp_type]) {
++				DPRINTK("hsync_width too big: %d\n",
++					par->hsync_width);
++				return -EINVAL;
++			}
++			if (par->vsync_width > max_vsync_width[disp_type]) {
++				DPRINTK("vsync_width too big: %d\n",
++					par->vsync_width);
++				return -EINVAL;
++			}
++		}
++	}
++
++	if (IS_TV(disp_type)) {
++		int tv_pixclk = (disp_type == DISP_TYPE_NTSC) ?
++			NTSC_PIXCLOCK : PAL_PIXCLOCK;
++		if (info->fix.tv_filt & TV_FILT_FLICKER)
++			tv_pixclk *= 2;
++		
++		if (par->ipclk.pixclk_d != tv_pixclk) {
++			DPRINTK("invalid TV pixel clock %u kHz\n",
++				par->ipclk.pixclk_d);
++			return -EINVAL;
++		}
++	}
++	
++	if (e1356_calc_pixclock(info, &par->ipclk) < 0) {
++		DPRINTK("can't set pixel clock %u kHz\n",
++			par->ipclk.pixclk_d);
++		return -EINVAL;
++	}
++ 
++#ifdef E1356FB_VERBOSE_DEBUG
++	DPRINTK("desired pixclock = %d kHz, actual = %d kHz, error = %d%%\n",
++		par->ipclk.pixclk_d, par->ipclk.pixclk, par->ipclk.error);
++#endif
++    
++	if (disp_type != DISP_TYPE_LCD) {
++		if (par->horiz_ndp < par->hsync_start + par->hsync_width) {
++			DPRINTK("invalid horiz. timing\n");
++			return -EINVAL;
++		}
++		if (par->vert_ndp < par->vsync_start + par->vsync_width) {
++			DPRINTK("invalid vert. timing\n");
++			return -EINVAL;
++		}
++
++		// SED1356 Hardware Functional Spec, section 13.5
++		if (disp_type == DISP_TYPE_NTSC &&
++		    ((par->width + par->horiz_ndp != 910) ||
++		     (par->height + 2*par->vert_ndp+1 != 525))) {
++			DPRINTK("invalid NTSC timing\n");
++			return -EINVAL;
++		} else if (disp_type == DISP_TYPE_PAL &&
++			   ((par->width + par->horiz_ndp != 1135) ||
++			    (par->height + 2*par->vert_ndp+1 != 625))) {
++			DPRINTK("invalid PAL timing\n");
++			return -EINVAL;
++		}
++	}
++    
++	par->hsync_freq = (1000 * par->ipclk.pixclk) /
++		(par->width + par->horiz_ndp);
++	par->vsync_freq = par->hsync_freq / (par->height + par->vert_ndp);
++	
++	if (par->hsync_freq < 30000 || par->hsync_freq > 90000) {
++		DPRINTK("hsync freq too %s: %u Hz\n",
++			par->hsync_freq < 30000 ? "low" : "high",
++			par->hsync_freq);
++		return -EINVAL;
++	}
++	if (par->vsync_freq < 50 || par->vsync_freq > 110) {
++		DPRINTK("vsync freq too %s: %u Hz\n",
++			par->vsync_freq < 50 ? "low" : "high",
++			par->vsync_freq);
++		return -EINVAL;
++	}
++
++	return 0;
++}
++
++static int
++e1356fb_verify_par(struct e1356fb_par* par,
++		   const struct fb_info_e1356* info)
++{
++	int disp_type = info->fix.disp_type;
++    
++	if (par->bpp != 8 && par->bpp != 16) {
++		DPRINTK("depth not supported: %u bpp\n", par->bpp);
++		return -EINVAL;
++	}
++
++	if (par->width > par->width_virt) {
++		DPRINTK("virtual x resolution < physical x resolution not possible\n");
++		return -EINVAL;
++	}
++
++	if (par->height > par->height_virt) {
++		DPRINTK("virtual y resolution < physical y resolution not possible\n");
++		return -EINVAL;
++	}
++
++	if (par->width < 320 || par->width > 1024) {
++		DPRINTK("width not supported: %u\n", par->width);
++		return -EINVAL;
++	}
++
++	if ((disp_type == DISP_TYPE_LCD && (par->width % 16)) ||
++	    (disp_type == DISP_TYPE_TFT && (par->width % 8))) {
++		DPRINTK("invalid width for panel type: %u\n", par->width);
++		return -EINVAL;
++	}
++
++	if (par->height < 200 || par->height > 1024) {
++		DPRINTK("height not supported: %u\n", par->height);
++		return -EINVAL;
++	}
++
++	if (par->width_virt * par->height_virt * par->Bpp >
++	    info->fb_size) {
++		DPRINTK("not enough memory for virtual screen (%ux%ux%u)\n",
++			par->width_virt, par->height_virt, par->bpp);
++		return -EINVAL;
++	}
++
++	return e1356fb_verify_timing(par, info);
++}
++
++
++static int
++e1356fb_var_to_par(const struct fb_var_screeninfo* var,
++		   struct e1356fb_par* par,
++		   const struct fb_info_e1356* info)
++{
++	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
++		DPRINTK("interlace not supported\n");
++		return -EINVAL;
++	}
++
++	memset(par, 0, sizeof(struct e1356fb_par));
++
++	par->width       = (var->xres + 15) & ~15; /* could sometimes be 8 */
++	par->width_virt  = var->xres_virtual;
++	par->height      = var->yres;
++	par->height_virt = var->yres_virtual;
++	par->bpp         = var->bits_per_pixel;
++	par->Bpp         = (par->bpp + 7) >> 3;
++
++	par->ipclk.pixclk_d = PICOS2KHZ(var->pixclock);
++
++	par->hsync_start = var->right_margin;
++	par->hsync_width = var->hsync_len;
++
++	par->vsync_start = var->lower_margin;
++	par->vsync_width = var->vsync_len;
++
++	par->horiz_ndp = var->left_margin + var->right_margin + var->hsync_len;
++	par->vert_ndp = var->upper_margin + var->lower_margin + var->vsync_len;
++
++	par->hsync_pol = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? 1 : 0;
++	par->vsync_pol = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? 1 : 0;
++
++	par->cmap_len  = (par->bpp == 8) ? 256 : 16;
++
++	return e1356fb_verify_par(par, info);
++}
++
++static int
++e1356fb_par_to_var(struct fb_var_screeninfo* var,
++		   struct e1356fb_par* par,
++		   const struct fb_info_e1356* info)
++{
++	struct fb_var_screeninfo v;
++	int ret;
++    
++	// First, make sure par is valid.
++	if ((ret = e1356fb_verify_par(par, info)))
++		return ret;
++
++	memset(&v, 0, sizeof(struct fb_var_screeninfo));
++	v.xres_virtual   = par->width_virt;
++	v.yres_virtual   = par->height_virt;
++	v.xres           = par->width;
++	v.yres           = par->height;
++	v.right_margin   = par->hsync_start;
++	v.hsync_len      = par->hsync_width;
++	v.left_margin    = par->horiz_ndp - par->hsync_start - par->hsync_width;
++	v.lower_margin   = par->vsync_start;
++	v.vsync_len      = par->vsync_width;
++	v.upper_margin   = par->vert_ndp - par->vsync_start - par->vsync_width;
++	v.bits_per_pixel = par->bpp;
++
++	switch(par->bpp) {
++	case 8:
++		v.red.offset = v.green.offset = v.blue.offset = 0;
++		v.red.length = v.green.length = v.blue.length = 4;
++		break;
++	case 16:
++		v.red.offset   = 11;
++		v.red.length   = 5;
++		v.green.offset = 5;
++		v.green.length = 6;
++		v.blue.offset  = 0;
++		v.blue.length  = 5;
++		break;
++	}
++
++	v.height = v.width = -1;
++	v.pixclock = KHZ2PICOS(par->ipclk.pixclk);
++
++	if (par->hsync_pol)
++		v.sync |= FB_SYNC_HOR_HIGH_ACT;
++	if (par->vsync_pol)
++		v.sync |= FB_SYNC_VERT_HIGH_ACT;
++
++	*var = v;
++	return 0;
++}
++
++static int
++e1356fb_encode_fix(struct fb_fix_screeninfo*  fix,
++		   const struct e1356fb_par*   par,
++		   const struct fb_info_e1356* info)
++{
++	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
++    
++	strcpy(fix->id, "Epson SED1356");
++	fix->smem_start  = info->fix.membase_phys;
++	fix->smem_len    = info->fb_size;
++	fix->mmio_start  = info->fix.regbase_phys;
++	fix->mmio_len    = info->regbase_size;
++	fix->accel       = FB_ACCEL_EPSON_SED1356;
++	fix->type        = FB_TYPE_PACKED_PIXELS;
++	fix->type_aux    = 0;
++	fix->line_length = par->width_virt * par->Bpp;
++	fix->visual      =
++		(par->bpp == 8) ? FB_VISUAL_PSEUDOCOLOR	: FB_VISUAL_TRUECOLOR;
++    
++	fix->xpanstep    = info->fix.nopan ? 0 : 1;
++	fix->ypanstep    = info->fix.nopan ? 0 : 1;
++	fix->ywrapstep   = 0;
++    
++	return 0;
++}
++
++static int e1356fb_open(struct fb_info *fb, int user)
++{
++	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
++        if (user) {
++                info->open++;
++	}
++
++	return 0;
++}
++
++static int e1356fb_release(struct fb_info *fb, int user)
++{
++	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
++        if (user && info->open) {
++                info->open--;
++		if (info->open == 0)
++                        info->mmaped = 0;
++	}
++
++	return 0;
++}
++
++static int
++e1356fb_get_fix(struct fb_fix_screeninfo *fix, 
++		int con,
++		struct fb_info *fb)
++{
++	const struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
++	struct e1356fb_par par;
++
++	//DPRINTK("\n");
++
++	if (con == -1)
++		par = info->current_par;
++	else
++		e1356fb_var_to_par(&fb_display[con].var, &par, info);
++	e1356fb_encode_fix(fix, &par, info);
++	return 0;
++}
++
++static int
++e1356fb_get_var(struct fb_var_screeninfo *var, 
++		int con,
++		struct fb_info *fb)
++{
++	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
++
++	//DPRINTK("\n");
++
++	if (con == -1)
++		e1356fb_par_to_var(var, &info->current_par, info);
++	else
++		*var = fb_display[con].var;
++	return 0;
++}
++ 
++static void
++e1356fb_set_dispsw(struct display *disp, 
++		   struct fb_info_e1356 *info,
++		   int bpp, 
++		   int accel)
++{
++	struct e1356fb_fix* fix = &info->fix;
++	//DPRINTK("\n");
++
++	if (disp->dispsw && disp->conp) 
++		fb_con.con_cursor(disp->conp, CM_ERASE);
++	switch (bpp) {
++#ifdef FBCON_HAS_CFB8
++	case 8:
++		disp->dispsw = fix->noaccel ? &fbcon_cfb8 : &fbcon_e1356_8;
++		if (fix->nohwcursor)
++			fbcon_e1356_8.cursor = NULL;
++		break;
++#endif
++#ifdef FBCON_HAS_CFB16
++	case 16:
++		disp->dispsw = fix->noaccel ? &fbcon_cfb16 : &fbcon_e1356_16;
++		disp->dispsw_data = info->fbcon_cmap16;
++		if (fix->nohwcursor)
++			fbcon_e1356_16.cursor = NULL;
++		break;
++#endif
++	default:
++		disp->dispsw = &fbcon_dummy;
++	}
++   
++}
++
++static int
++e1356fb_set_var(struct fb_var_screeninfo *var, 
++		int con,
++		struct fb_info *fb)
++{
++	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
++	struct e1356fb_par par;
++	struct display *display;
++	int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, err;
++	int activate = var->activate;
++	int j,k;
++    
++	DPRINTK("\n");
++	
++	if (con >= 0)
++		display = &fb_display[con];
++	else
++		display = fb->disp;	/* used during initialization */
++   
++	if ((err = e1356fb_var_to_par(var, &par, info))) {
++		struct fb_videomode *dm;
++		/*
++		 * this mode didn't pass the tests. Try the
++		 * corresponding mode from our own modedb.
++		 */
++		DPRINTK("req mode failed, trying SED1356 %dx%d mode\n",
++			var->xres, var->yres);
++		if (e1356fb_get_mode(info, var->xres,
++				     var->yres, NULL, &dm) < 0) {
++			DPRINTK("no SED1356 %dx%d mode found, failed\n",
++				var->xres, var->yres);
++			return err;
++		}
++		fb_videomode_to_var(dm, var);
++		if ((err = e1356fb_var_to_par(var, &par, info))) {
++			DPRINTK("SED1356 %dx%d mode failed\n",
++				var->xres, var->yres);
++			return err;
++		}
++	}
++	
++	if (info->fix.tv_filt & TV_FILT_FLICKER)
++		printk("e1356fb: TV flicker filter enabled\n");
++    
++	e1356fb_par_to_var(var, &par, info);
++   
++	if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
++		oldxres  = display->var.xres;
++		oldyres  = display->var.yres;
++		oldvxres = display->var.xres_virtual;
++		oldvyres = display->var.yres_virtual;
++		oldbpp   = display->var.bits_per_pixel;
++		oldaccel = display->var.accel_flags;
++		display->var = *var;
++		if (con < 0                         ||
++		    oldxres  != var->xres           || 
++		    oldyres  != var->yres           ||
++		    oldvxres != var->xres_virtual   || 
++		    oldvyres != var->yres_virtual   ||
++		    oldbpp   != var->bits_per_pixel || 
++		    oldaccel != var->accel_flags) {
++			struct fb_fix_screeninfo fix;
++	    
++			e1356fb_encode_fix(&fix, &par, info);
++			display->screen_base    = info->membase_virt;
++			display->visual         = fix.visual;
++			display->type           = fix.type;
++			display->type_aux       = fix.type_aux;
++			display->ypanstep       = fix.ypanstep;
++			display->ywrapstep      = fix.ywrapstep;
++			display->line_length    = fix.line_length;
++			display->next_line      = fix.line_length;
++			display->can_soft_blank = 1;
++			display->inverse        = 0;
++			accel = var->accel_flags & FB_ACCELF_TEXT;
++			e1356fb_set_dispsw(display, info, par.bpp, accel);
++	 
++			if (info->fix.nopan)
++				display->scrollmode = SCROLL_YREDRAW;
++	
++			if (info->fb_info.changevar)
++				(*info->fb_info.changevar)(con);
++		}
++		if (var->bits_per_pixel==8)
++			for(j = 0; j < 16; j++) {
++				k = color_table[j];
++				fb_info.palette[j].red   = default_red[k];
++				fb_info.palette[j].green = default_grn[k];
++				fb_info.palette[j].blue  = default_blu[k];
++			}
++      
++		del_timer(&(info->cursor.timer)); 
++		fb_info.cursor.state=CM_ERASE;
++	
++		if (!info->fb_info.display_fg ||
++		    info->fb_info.display_fg->vc_num == con || con < 0)
++			e1356fb_set_par(&par, info);
++
++		if (!info->fix.nohwcursor) 
++			if (display && display->conp)
++				e1356fb_createcursor( display );
++		info->cursor.redraw = 1;
++
++		if (oldbpp != var->bits_per_pixel || con < 0) {
++			if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
++				return err;
++			e1356fb_install_cmap(display, &(info->fb_info));
++		}
++	}
++  
++	return 0;
++}
++
++static int
++e1356fb_pan_display(struct fb_var_screeninfo* var, 
++		    int con,
++		    struct fb_info* fb)
++{
++	struct fb_info_e1356* info = (struct fb_info_e1356*)fb;
++	struct e1356fb_par* par = &info->current_par;
++    
++	//DPRINTK("\n");
++
++	if (info->fix.nopan)
++		return -EINVAL;
++
++	if ((int)var->xoffset < 0 ||
++	    var->xoffset + par->width > par->width_virt ||
++	    (int)var->yoffset < 0 ||
++	    var->yoffset + par->height > par->height_virt)
++		return -EINVAL;
++    
++	if (con == currcon)
++		do_pan_var(var, info);
++    
++	fb_display[con].var.xoffset = var->xoffset;
++	fb_display[con].var.yoffset = var->yoffset; 
++
++	return 0;
++}
++
++static int
++e1356fb_get_cmap(struct fb_cmap *cmap, 
++		 int kspc, 
++		 int con,
++		 struct fb_info *fb)
++{
++	struct fb_info_e1356* info = (struct fb_info_e1356*)fb;
++	struct display *d = (con<0) ? fb->disp : fb_display + con;
++   
++	//DPRINTK("\n");
++
++	if (con == currcon) {
++		/* current console? */
++		return fb_get_cmap(cmap, kspc, e1356fb_getcolreg, fb);
++	} else if (d->cmap.len) {
++		/* non default colormap? */
++		fb_copy_cmap(&d->cmap, cmap, kspc ? 0 : 2);
++	} else {
++		fb_copy_cmap(fb_default_cmap(info->current_par.cmap_len),
++			     cmap, kspc ? 0 : 2);
++	}
++	return 0;
++}
++
++static int
++e1356fb_set_cmap(struct fb_cmap *cmap, 
++		 int kspc, 
++		 int con,
++		 struct fb_info *fb)
++{
++	struct display *d = (con<0) ? fb->disp : fb_display + con;
++	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
++	int cmap_len = (info->current_par.bpp == 8) ? 256 : 16;
++
++	//DPRINTK("\n");
++
++	if (d->cmap.len!=cmap_len) {
++		int err;
++		if ((err = fb_alloc_cmap(&d->cmap, cmap_len, 0)))
++			return err;
++	}
++    
++	if (con == currcon) {
++		/* current console? */
++		return fb_set_cmap(cmap, kspc, e1356fb_setcolreg, fb);
++	} else {
++		fb_copy_cmap(cmap, &d->cmap, kspc ? 0 : 1);
++	}
++	return 0;
++}
++
++static int
++e1356fb_mmap(struct fb_info *fb,
++	     struct file *file,
++	     struct vm_area_struct *vma)
++{
++	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
++	unsigned int len;
++#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
++	u64 start=0, off;
++#else
++	unsigned long start=0, off;
++#endif
++
++	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
++		DPRINTK("invalid vma->vm_pgoff\n");
++		return -EINVAL;
++	}
++    
++#ifdef SHADOW_FRAME_BUFFER
++	if (!info->shadow.fb) {
++		int order = 0;
++		while (info->fb_size > (PAGE_SIZE * (1 << order)))
++			order++;
++		info->shadow.fb = (void*)__get_free_pages(GFP_KERNEL, order);
++		if (!info->shadow.fb) {
++			DPRINTK("shadow fb alloc failed\n");
++			return -ENXIO;
++		}
++		memset(info->shadow.fb, 0, info->fb_size);
++		init_timer(&info->shadow.timer);
++		info->shadow.timer.function = do_write_shadow_fb;
++		info->shadow.timer.data = (unsigned long)info;
++	}
++	mod_timer(&info->shadow.timer, jiffies+HZ/2);
++	start = virt_to_phys(info->shadow.fb) & PAGE_MASK;
++#else
++	start = info->fix.membase_phys & PAGE_MASK;
++#endif
++
++	len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fb_size);
++
++	off = vma->vm_pgoff << PAGE_SHIFT;
++    
++	if ((vma->vm_end - vma->vm_start + off) > len) {
++		DPRINTK("invalid vma\n");
++		return -EINVAL;
++	}
++
++	off += start;
++	vma->vm_pgoff = off >> PAGE_SHIFT;
++
++	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
++#ifdef SHADOW_FRAME_BUFFER
++	vma->vm_flags |= VM_RESERVED;
++	pgprot_val(vma->vm_page_prot) &= ~_CACHE_UNCACHED;
++#else
++	pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED;
++#endif
++
++	/* This is an IO map - tell maydump to skip this VMA */
++	vma->vm_flags |= VM_IO;
++	// FIXME: shouldn't have to do this. If the pages are marked writeable,
++	// the TLB fault handlers should set these.
++	pgprot_val(vma->vm_page_prot) |= (_PAGE_DIRTY | _PAGE_VALID);
++    
++	/*
++	 * The SED1356 has only a 16-bit wide data bus, and some
++	 * embedded platforms, such as the Pb1000, do not automatically
++	 * split 32-bit word accesses to the framebuffer into
++	 * seperate half-word accesses. Hence the upper half-word
++	 * never gets to the framebuffer. The following solution is
++	 * to intentionally return a non-32-bit-aligned VA. As long
++	 * as the user app assumes (and doesn't check) that the returned
++	 * VA is 32-bit aligned, all (assumed aligned) 32-bit accesses
++	 * will actually be unaligned and will get trapped by the MIPS
++	 * unaligned exception handler. This handler will emulate the
++	 * load/store instructions by splitting up the load/store
++	 * into two 16-bit load/stores. (This emulation is currently
++	 * enabled by default, but may be disabled in the future, when
++	 * alignment problems in user-level programs get fixed. When
++	 * that happens, this solution won't work anymore, unless the
++	 * process that mmap's the fb also calls sysmips(MIPS_FIXADE, 1),
++	 * which turns address-error emulation back on).
++	 *
++	 * Furthermore, this solution only seems to work for TinyX
++	 * (Xfbdev). Others, like Qt/E, do snoop the returned VA
++	 * and compensate, or do originally unaligned 32-bit accesses
++	 * which then become aligned, hence breaking this solution.
++	 */
++	if (info->fix.mmunalign)
++		vma->vm_start += 2;
++	
++#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
++	if (e1356_remap_page_range(vma->vm_start, off,
++				vma->vm_end - vma->vm_start,
++				vma->vm_page_prot))
++		return -EAGAIN;
++#else
++	if (io_remap_page_range(vma->vm_start, off,
++				vma->vm_end - vma->vm_start,
++				vma->vm_page_prot))
++		return -EAGAIN;
++#endif
++
++	info->mmaped = 1;
++	return 0;
++}
++
++
++int __init
++e1356fb_init(void)
++{
++	struct fb_var_screeninfo var;
++	struct e1356fb_fix * epfix = &fb_info.fix;
++	e1356_reg_t* reg;
++	void* regbase;
++	char* name = "SED1356";
++	int periodMCLK, periodBCLK;
++	int dram_timing, rr_div, mclk_src;
++	u8 rev_code, btmp, mclk_cfg;
++
++	if (options) {
++		e1356fb_setup(options, 0);
++	}
++
++	// clear out fb_info
++	memset(&fb_info, 0, sizeof(struct fb_info_e1356));
++
++	// copy boot options
++	fb_info.fix = boot_fix;
++	fb_info.default_par = boot_par;
++
++	fb_info.regbase_size = E1356_REG_SIZE;
++
++	if (!epfix->system) {
++		printk(KERN_ERR "e1356/86fb: no valid system found\n");
++		return -ENODEV;
++	}
++
++	if (epfix->system == SYS_SDU1356) {
++		// it's the SDU1356B0C PCI eval card.
++		struct pci_dev *pdev = NULL;
++		if (!pci_present())   /* No PCI bus in this machine! */
++			return -ENODEV;
++		if (!(pdev = pci_find_device(PCI_VENDOR_ID_EPSON,
++					     PCI_DEVICE_ID_EPSON_SDU1356, pdev)))
++			return -ENODEV;
++		if (pci_enable_device(pdev))
++			return -ENODEV;
++		epfix->regbase_phys = pci_resource_start(pdev, 0);
++		epfix->membase_phys = epfix->regbase_phys + E1356_REG_SIZE;
++	}
++	
++	fb_info.regbase_virt = ioremap_nocache(epfix->regbase_phys,
++					       E1356_REG_SIZE);
++
++	if (!fb_info.regbase_virt) {
++		printk("e1356fb: Can't remap %s register area.\n", name);
++		return -ENXIO;
++	}
++
++	regbase = fb_info.regbase_virt;
++	reg = &fb_info.reg;
++    
++	// Initialize the register pointers
++	reg->basic =         (reg_basic_t*)   (regbase + REG_BASE_BASIC);
++	reg->genio =         (reg_genio_t*)   (regbase + REG_BASE_GENIO);
++	reg->md_cfg =        (reg_mdcfg_t*)   (regbase + REG_BASE_MDCFG);
++	reg->clk_cfg =       (reg_clkcfg_t*)  (regbase + REG_BASE_CLKCFG);
++	reg->mem_cfg =       (reg_memcfg_t*)  (regbase + REG_BASE_MEMCFG);
++	reg->panel_cfg =     (reg_panelcfg_t*)(regbase + REG_BASE_PANELCFG);
++	reg->lcd_cfg =       (reg_dispcfg_t*) (regbase + REG_BASE_LCD_DISPCFG);
++	reg->crttv_cfg =     (reg_dispcfg_t*) (regbase + REG_BASE_CRTTV_DISPCFG);
++	reg->lcd_mode =      (reg_dispmode_t*)(regbase + REG_BASE_LCD_DISPMODE);
++	reg->crttv_mode =    (reg_dispmode_t*)(regbase + REG_BASE_CRTTV_DISPMODE);
++	reg->lcd_inkcurs =   (reg_inkcurs_t*) (regbase + REG_BASE_LCD_INKCURS);
++	reg->crttv_inkcurs = (reg_inkcurs_t*) (regbase + REG_BASE_CRTTV_INKCURS);
++	reg->bitblt =        (reg_bitblt_t*)  (regbase + REG_BASE_BITBLT);
++	reg->lut =           (reg_lut_t*)     (regbase + REG_BASE_LUT);
++	reg->pwr_save =      (reg_pwrsave_t*) (regbase + REG_BASE_PWRSAVE);
++	reg->misc =          (reg_misc_t*)    (regbase + REG_BASE_MISC);
++	reg->mediaplug =     (reg_mediaplug_t*)(regbase + REG_BASE_MEDIAPLUG);
++	reg->bitblt_data =   (u16*)           (regbase + REG_BASE_BITBLT_DATA);
++    
++	// Enable all register access
++	writeb(0, &reg->basic->misc);
++
++	rev_code = readb(&reg->basic->rev_code);
++	if ((rev_code >> 2) == 0x04) {
++		printk("Found EPSON1356 Display Controller\n");
++	}
++	else if ((rev_code >> 2) == 0x07) {
++		printk("Found EPSON13806 Display Controller\n");
++	}
++	else {
++		iounmap(fb_info.regbase_virt);
++		printk("e1356/806fb: %s not found, rev_code=0x%02x.\n",
++		       name, rev_code);
++		return -ENODEV;
++	}
++
++	fb_info.chip_rev = rev_code & 0x03;
++
++	// Determine frame-buffer size
++	switch (readb(&reg->md_cfg->md_cfg_stat0) >> 6) {
++	case 0:
++	case 2:
++		fb_info.fb_size = 0x80000;   /* 512K bytes */
++		break;
++	case 1:
++		if ((rev_code >> 2) == 7) /* 806 */
++			fb_info.fb_size = 0x140000;  /* 1.2M bytes */
++		else
++			fb_info.fb_size = 0x200000;  /* 2M bytes */
++		break;
++	default:
++		fb_info.fb_size = 0x200000;  /* 2M bytes */
++		break;
++	}
++
++	fb_info.membase_virt = ioremap_nocache(epfix->membase_phys,
++					       fb_info.fb_size);
++    
++	if (!fb_info.membase_virt) {
++		printk("e1356fb: Can't remap %s framebuffer.\n", name);
++		iounmap(fb_info.regbase_virt);
++		return -ENXIO;
++	}
++    
++	printk("e1356/806fb: Detected  %dKB framebuffer\n", 
++			(unsigned)fb_info.fb_size/1000);
++
++#ifdef CONFIG_MTRR
++	if (!epfix->nomtrr) {
++		fb_info.mtrr_idx = mtrr_add(epfix->membase_phys, fb_info.fb_size,
++					    MTRR_TYPE_WRCOMB, 1);
++		printk("e1356fb: MTRR's turned on\n");
++	}
++#endif
++    
++	if (!boot_fix.noaccel) {
++		/*
++		  Allocate a page for string BLTs. A 4K page is
++		  enough for a 256 character string at an 8x16 font.
++		*/
++		fb_info.putcs_buffer = (void*)__get_free_pages(GFP_KERNEL, 0);
++		if (fb_info.putcs_buffer == NULL) {
++			printk("e1356fb: Can't allocate putcs buffer\n");
++			goto unmap_ret_enxio;
++		}
++	}
++
++	// Begin SED1356 initialization
++
++	// disable display while initializing
++	writeb(0, &reg->misc->disp_mode);
++	// Set the GPIO1 and 2 to inputs
++	writeb(0, &reg->genio->gpio_cfg);
++	writeb(0, &reg->genio->gpio_ctrl);
++	if (fb_info.chip_rev == 7) /* 806 */
++		writeb(0, &reg->genio->gpio_ctrl2);
++
++	/*
++	 * Program the clocks
++	 */
++
++#ifdef CONFIG_MIPS_AU1000
++	if ((epfix->system == SYS_PB1000) || (epfix->system == SYS_PB1500))
++		epfix->busclk = get_au1000_lcd_clock();
++#endif
++	
++	if (epfix->busclk > 80000) {
++		printk("e1356fb: specified busclk too high\n");
++		goto ret_enxio;
++	}
++
++	epfix->mclk = mclk_cfg = 0;
++	if (epfix->system == SYS_PB1500) {
++		epfix->mclk = epfix->busclk;
++		mclk_cfg = 0x01;
++	}
++	else {
++		// Find the highest allowable MCLK
++		if (epfix->busclk <= MAX_PIXCLOCK && 
++				epfix->busclk > epfix->mclk) {
++			epfix->mclk = epfix->busclk;
++			mclk_cfg = 0x01;
++		}
++		if (epfix->clki <= MAX_PIXCLOCK && epfix->clki > epfix->mclk) {
++			epfix->mclk = epfix->clki;
++			mclk_cfg = 0x00;
++		}
++		if (epfix->busclk/2 <= MAX_PIXCLOCK && 
++				epfix->busclk/2 > epfix->mclk) {
++			epfix->mclk = epfix->busclk/2;
++			mclk_cfg = 0x11;
++		}
++		if (epfix->clki/2 <= MAX_PIXCLOCK && 
++				epfix->clki/2 > epfix->mclk) {
++			epfix->mclk = epfix->clki/2;
++			mclk_cfg = 0x10;
++		}
++	}
++	
++	if (!epfix->mclk) {
++		printk("e1356fb: couldn't find an allowable MCLK!\n");
++		goto ret_enxio;
++	}
++
++	// When changing mclk src, you must first set bit 4 to 1.
++	writeb(readb(&reg->clk_cfg->mem_clk_cfg) | 0x10,
++	       &reg->clk_cfg->mem_clk_cfg);
++	writeb(mclk_cfg, &reg->clk_cfg->mem_clk_cfg);
++
++	printk("e1356fb: clocks (kHz): busclk=%d mclk=%d clki=%d clki2=%d\n",
++	       epfix->busclk, epfix->mclk, epfix->clki, epfix->clki2);
++
++	// Set max pixel clock
++	switch (epfix->disp_type) {
++	case DISP_TYPE_LCD:
++	case DISP_TYPE_TFT:
++	case DISP_TYPE_CRT:
++		fb_info.max_pixclock = epfix->mclk;
++		break;
++	case DISP_TYPE_NTSC:
++	case DISP_TYPE_PAL:
++		fb_info.max_pixclock = (epfix->disp_type == DISP_TYPE_NTSC) ?
++			NTSC_PIXCLOCK : PAL_PIXCLOCK;
++		if (epfix->tv_filt & TV_FILT_FLICKER)
++			fb_info.max_pixclock *= 2;
++		break;
++	default:
++		printk("e1356fb: invalid specified display type\n");
++		goto ret_enxio;
++	}
++
++	periodMCLK = 1000000L / epfix->mclk;   // in nano-seconds
++	periodBCLK = 1000000L / epfix->busclk; // in nano-seconds
++	if (readb(&reg->md_cfg->md_cfg_stat1) & (1<<4))
++		periodBCLK *= 2;
++    
++	if ((epfix->system == SYS_PB1000) || (epfix->system == SYS_PB1500))
++		writeb(0x00, &reg->clk_cfg->cpu2mem_wait_sel);
++	else if (periodMCLK - 4 > periodBCLK)
++		writeb(0x02, &reg->clk_cfg->cpu2mem_wait_sel);
++	else if (2*periodMCLK - 4 > periodBCLK)
++		writeb(0x01, &reg->clk_cfg->cpu2mem_wait_sel);
++	else
++		writeb(0x00, &reg->clk_cfg->cpu2mem_wait_sel);
++
++	// Program memory config
++	if (epfix->mem_type < MEM_TYPE_EDO_2CAS ||
++	    epfix->mem_type > MEM_TYPE_EMBEDDED_SDRAM) {
++		printk("e1356fb: bad memory type specified\n");
++		goto ret_enxio;
++	}
++	writeb((u8)epfix->mem_type, &reg->mem_cfg->mem_cfg);
++
++	// calc closest refresh rate
++	rr_div = 7;
++	mclk_src = (mclk_cfg & 1) ? epfix->busclk : epfix->clki;
++	while ((mclk_src >> (6 + rr_div)) < epfix->mem_refresh)
++		if (--rr_div < 0) {
++			printk("e1356fb: can't set specified refresh rate\n");
++			goto ret_enxio;
++		}
++    
++	DPRINTK("refresh rate = %d kHz\n", (mclk_src >> (6 + rr_div)));
++
++	// add Suspend-Mode Refresh bits
++	if (epfix->mem_smr < MEM_SMR_CBR || epfix->mem_smr > MEM_SMR_NONE) {
++		printk("e1356fb: invalid specified suspend-mode refresh type\n");
++		goto ret_enxio;
++	}
++	writeb(rr_div | (epfix->mem_smr << 6), &reg->mem_cfg->dram_refresh);
++
++	// set DRAM speed
++	switch (epfix->mem_speed) {
++	case 50:
++		dram_timing = epfix->mclk >= 33000 ? 0x0101 : 0x0212;
++		break;
++	case 60:
++		if (epfix->mclk >= 30000)
++			dram_timing = 0x0101;
++		else if (epfix->mclk >= 25000)
++			dram_timing =
++				(epfix->mem_type == MEM_TYPE_EDO_2CAS ||
++				 epfix->mem_type == MEM_TYPE_EDO_2WE) ?
++				0x0212 : 0x0101;
++		else
++			dram_timing = 0x0212;
++		break;
++	case 70:
++		if (epfix->mclk >= 30000)
++			dram_timing = 0x0000;
++		else if (epfix->mclk >= 25000)
++			dram_timing = 0x0101;
++		else
++			dram_timing =
++				(epfix->mem_type == MEM_TYPE_EDO_2CAS ||
++				 epfix->mem_type == MEM_TYPE_EDO_2WE) ?
++				0x0212 : 0x0211;
++		break;
++	case 80:
++		if (epfix->mclk >= 25000)
++			dram_timing = 0x0100;
++		else
++			dram_timing = 0x0101;
++		break;
++	default:
++		printk("e1356fb: invalid specified memory speed\n");
++		goto ret_enxio;
++	}
++
++	writew(dram_timing, &reg->mem_cfg->dram_timings_ctrl0);
++    
++	currcon = -1;
++	if (!epfix->nohwcursor)
++		e1356fb_hwcursor_init(&fb_info);
++    
++	init_timer(&fb_info.cursor.timer);
++	fb_info.cursor.timer.function = do_flashcursor; 
++	fb_info.cursor.timer.data = (unsigned long)(&fb_info);
++	fb_info.cursor.state = CM_ERASE;
++	spin_lock_init(&fb_info.cursor.lock);
++    
++	strcpy(fb_info.fb_info.modename, "Epson "); 
++	strcat(fb_info.fb_info.modename, name);
++	fb_info.fb_info.changevar  = NULL;
++	fb_info.fb_info.node       = -1;
++
++	fb_info.fb_info.fbops      = &e1356fb_ops;
++	fb_info.fb_info.disp       = &fb_info.disp;
++	strcpy(fb_info.fb_info.fontname, epfix->fontname);
++	fb_info.fb_info.switch_con = &e1356fb_switch_con;
++	fb_info.fb_info.updatevar  = &e1356fb_updatevar;
++	fb_info.fb_info.blank      = &e1356fb_blank;
++	fb_info.fb_info.flags      = FBINFO_FLAG_DEFAULT;
++    
++	// Set-up display
++	// clear out unused stuff
++	writeb(0, &reg->panel_cfg->mod_rate);
++	writeb(0x01, &reg->lcd_mode->lcd_misc);
++	writeb(0, &reg->lcd_mode->fifo_high_thresh);
++	writeb(0, &reg->lcd_mode->fifo_low_thresh);
++	writeb(0, &reg->crttv_mode->fifo_high_thresh);
++	writeb(0, &reg->crttv_mode->fifo_low_thresh);
++    
++	switch (epfix->disp_type) {
++	case DISP_TYPE_LCD:
++		switch (epfix->panel_width) {
++		case 4: btmp = (u8)(((epfix->panel_el & 1)<<7) | 0x04); break;
++		case 8: btmp = (u8)(((epfix->panel_el & 1)<<7) | 0x14); break;
++		case 16: btmp = (u8)(((epfix->panel_el & 1)<<7) | 0x24); break;
++		default:
++			printk("e1356fb: invalid specified LCD panel data width\n");
++			goto ret_enxio;
++		}
++		writeb(btmp, &reg->panel_cfg->panel_type);
++		break;
++	case DISP_TYPE_TFT:
++		switch (epfix->panel_width) {
++		case 9: btmp = (u8)(((epfix->panel_el & 1)<<7) | 0x05); break;
++		case 12: btmp = (u8)(((epfix->panel_el & 1)<<7) | 0x15); break;
++		case 18: btmp = (u8)(((epfix->panel_el & 1)<<7) | 0x25); break;
++		default:
++			printk("e1356fb: invalid specified TFT panel data width\n");
++			goto ret_enxio;
++		}
++		writeb(btmp, &reg->panel_cfg->panel_type);
++		break;
++	case DISP_TYPE_CRT:
++		writeb(0x00, &reg->crttv_cfg->tv_output_ctrl);
++		break;
++	case DISP_TYPE_NTSC:
++	case DISP_TYPE_PAL:
++		if (epfix->tv_fmt < TV_FMT_COMPOSITE ||
++		    epfix->tv_fmt > TV_FMT_S_VIDEO) {
++			printk("e1356fb: invalid specified TV output format\n");
++			goto ret_enxio;
++		}
++		btmp = epfix->disp_type == DISP_TYPE_PAL ? 0x01 : 0x00;
++		btmp |= (epfix->tv_fmt == TV_FMT_S_VIDEO ? 0x02 : 0x00);
++		btmp |= ((epfix->tv_filt & TV_FILT_LUM) ? 0x10 : 0x00);
++		btmp |= ((epfix->tv_filt & TV_FILT_CHROM) ? 0x20 : 0x00);
++		writeb(btmp, &reg->crttv_cfg->tv_output_ctrl);
++		break;
++	}
++
++	memset(&var, 0, sizeof(var));
++	/*
++	 * If mode_option wasn't given at boot, assume all the boot
++	 * option timing parameters were specified individually, in
++	 * which case we convert par_to_var instead of calling
++	 * fb_find_mode.
++	 */
++	if (epfix->mode_option) {
++		struct fb_videomode* modedb, *dm;
++		int dbsize = e1356fb_get_mode(&fb_info, 640, 480, &modedb, &dm);
++
++		// first try the generic modedb
++		if (!fb_find_mode(&var, &fb_info.fb_info, epfix->mode_option,
++				  NULL, 0, NULL, boot_par.bpp)) {
++			printk("e1356fb: mode %s failed, trying e1356 modedb\n",
++			       epfix->mode_option);
++			// didn't work in generic modedb, try ours
++			if (!fb_find_mode(&var, &fb_info.fb_info,
++					  epfix->mode_option,
++					  modedb, dbsize, dm, boot_par.bpp)) {
++				printk("e1356fb: mode %s failed e1356 modedb too, sorry\n",
++				       epfix->mode_option);
++				
++				goto ret_enxio;
++			}
++		}
++
++		var.xres_virtual = boot_par.width_virt ?
++			boot_par.width_virt : boot_par.width;
++		var.yres_virtual = boot_par.height_virt ?
++			boot_par.height_virt : boot_par.height;
++	} else {
++		if (e1356fb_par_to_var(&var, &fb_info.default_par, &fb_info)) {
++			printk("e1356fb: boot option mode failed\n");
++			goto ret_enxio;
++		}
++	}
++    
++	if (boot_fix.noaccel)
++		var.accel_flags &= ~FB_ACCELF_TEXT;
++	else
++		var.accel_flags |= FB_ACCELF_TEXT;
++    
++	if (e1356fb_var_to_par(&var, &fb_info.default_par, &fb_info)) {
++		/*
++		 * Can't use the mode from the mode db or the default
++		 * mode or the boot options - give up
++		 */
++		printk("e1356fb: mode failed var_to_par\n");
++		goto ret_enxio;
++	}
++    
++	fb_info.disp.screen_base    = fb_info.membase_virt;
++	fb_info.disp.var            = var; // struct copy
++    
++	// here's where the screen is actually initialized and enabled
++	if (e1356fb_set_var(&var, -1, &fb_info.fb_info)) {
++		printk("e1356fb: can't set video mode\n");
++		goto ret_enxio;
++	}
++    
++	writeb(0, &reg->pwr_save->cfg);     // disable power-save mode
++	writeb(0, &reg->misc->cpu2mem_watchdog); // disable watchdog timer
++
++#ifdef E1356FB_VERBOSE_DEBUG
++	dump_fb(fb_info.membase_virt + 0x100000, 512);
++#endif
++
++	if (register_framebuffer(&fb_info.fb_info) < 0) {
++		writeb(0, &reg->misc->disp_mode); 
++		printk("e1356fb: can't register framebuffer\n");
++		goto ret_enxio;
++	}
++    
++	printk("fb%d: %s frame buffer device\n", 
++	       GET_FB_IDX(fb_info.fb_info.node),
++	       fb_info.fb_info.modename);
++    
++    
++	return 0;
++
++ ret_enxio:
++	free_pages((unsigned long)fb_info.putcs_buffer, 0);
++ unmap_ret_enxio:
++	iounmap(fb_info.regbase_virt);
++	iounmap(fb_info.membase_virt);
++	return -ENXIO;
++}
++
++/**
++ *	e1356fb_exit - Driver cleanup
++ *
++ *	Releases all resources allocated during the
++ *	course of the driver's lifetime.
++ *
++ *	FIXME - do results of fb_alloc_cmap need disposal?
++ */
++static void __exit
++e1356fb_exit (void)
++{
++	unregister_framebuffer(&fb_info.fb_info);
++	del_timer_sync(&fb_info.cursor.timer);
++
++#ifdef CONFIG_MTRR
++	if (!fb_info.fix.nomtrr) {
++		mtrr_del(fb_info.mtrr_idx, fb_info.fix.membase_phys,
++			 fb_info.fb_size);
++		printk("fb: MTRR's  turned off\n");
++	}
++#endif
++
++	free_pages((unsigned long)fb_info.putcs_buffer, 0);
++	iounmap(fb_info.regbase_virt);
++	iounmap(fb_info.membase_virt);
++}
++
++MODULE_AUTHOR("Steve Longerbeam <stevel at mvista.com>");
++MODULE_DESCRIPTION("SED1356 framebuffer device driver");
++
++#ifdef MODULE
++module_init(e1356fb_init);
++#endif
++module_exit(e1356fb_exit);
++
++
++void
++e1356fb_setup(char *options, int *ints)
++{
++	char* this_opt;
++    
++	memset(&boot_fix, 0, sizeof(struct e1356fb_fix));
++	memset(&boot_par, 0, sizeof(struct e1356fb_par));
++	boot_fix.system = -1;
++    
++	if (!options || !*options)
++		return;
++    
++	for(this_opt=strtok(options, ","); this_opt;
++	    this_opt=strtok(NULL, ",")) {
++		if (!strncmp(this_opt, "noaccel", 7)) {
++			boot_fix.noaccel = 1;
++		} else if (!strncmp(this_opt, "nopan", 5)) {
++			boot_fix.nopan = 1;
++		} else if (!strncmp(this_opt, "nohwcursor", 10)) {
++			boot_fix.nohwcursor = 1;
++		} else if (!strncmp(this_opt, "mmunalign:", 10)) {
++			boot_fix.mmunalign = simple_strtoul(this_opt+10,
++							    NULL, 0);
++#ifdef CONFIG_MTRR
++		} else if (!strncmp(this_opt, "nomtrr", 6)) {
++			boot_fix.nomtrr = 1;
++#endif
++		} else if (!strncmp(this_opt, "font:", 5)) {
++			strncpy(boot_fix.fontname, this_opt+5,
++				sizeof(boot_fix.fontname)-1);
++		} else if (!strncmp(this_opt, "regbase:", 8)) {
++			boot_fix.regbase_phys = simple_strtoul(this_opt+8,
++							       NULL, 0);
++		} else if (!strncmp(this_opt, "membase:", 8)) {
++			boot_fix.membase_phys = simple_strtoul(this_opt+8,
++							       NULL, 0);
++		} else if (!strncmp(this_opt, "memsp:", 6)) {
++			boot_fix.mem_speed = simple_strtoul(this_opt+6,
++							    NULL, 0);
++		} else if (!strncmp(this_opt, "memtyp:", 7)) {
++			boot_fix.mem_type = simple_strtoul(this_opt+7,
++							   NULL, 0);
++		} else if (!strncmp(this_opt, "memref:", 7)) {
++			boot_fix.mem_refresh = simple_strtoul(this_opt+7,
++							      NULL, 0);
++		} else if (!strncmp(this_opt, "memsmr:", 7)) {
++			boot_fix.mem_smr = simple_strtoul(this_opt+7, NULL, 0);
++		} else if (!strncmp(this_opt, "busclk:", 7)) {
++			boot_fix.busclk = simple_strtoul(this_opt+7, NULL, 0);
++		} else if (!strncmp(this_opt, "clki:", 5)) {
++			boot_fix.clki = simple_strtoul(this_opt+5, NULL, 0);
++		} else if (!strncmp(this_opt, "clki2:", 6)) {
++			boot_fix.clki2 = simple_strtoul(this_opt+6, NULL, 0);
++		} else if (!strncmp(this_opt, "display:", 8)) {
++			if (!strncmp(this_opt+8, "lcd", 3))
++				boot_fix.disp_type = DISP_TYPE_LCD;
++			else if (!strncmp(this_opt+8, "tft", 3))
++				boot_fix.disp_type = DISP_TYPE_TFT;
++			else if (!strncmp(this_opt+8, "crt", 3))
++				boot_fix.disp_type = DISP_TYPE_CRT;
++			else if (!strncmp(this_opt+8, "pal", 3))
++				boot_fix.disp_type = DISP_TYPE_PAL;
++			else if (!strncmp(this_opt+8, "ntsc", 4))
++				boot_fix.disp_type = DISP_TYPE_NTSC;
++		} else if (!strncmp(this_opt, "width:", 6)) {
++			boot_par.width = simple_strtoul(this_opt+6, NULL, 0);
++		} else if (!strncmp(this_opt, "height:", 7)) {
++			boot_par.height = simple_strtoul(this_opt+7, NULL, 0);
++		} else if (!strncmp(this_opt, "bpp:", 4)) {
++			boot_par.bpp = simple_strtoul(this_opt+4, NULL, 0);
++			boot_par.cmap_len = (boot_par.bpp == 8) ? 256 : 16;
++		} else if (!strncmp(this_opt, "elpanel:", 8)) {
++			boot_fix.panel_el = simple_strtoul(this_opt+8,
++							   NULL, 0);
++		} else if (!strncmp(this_opt, "pdataw:", 7)) {
++			boot_fix.panel_width = simple_strtoul(this_opt+7,
++							      NULL, 0);
++		} else if (!strncmp(this_opt, "hndp:", 5)) {
++			boot_par.horiz_ndp = simple_strtoul(this_opt+5,
++							    NULL, 0);
++		} else if (!strncmp(this_opt, "vndp:", 5)) {
++			boot_par.vert_ndp = simple_strtoul(this_opt+5,
++							   NULL, 0);
++		} else if (!strncmp(this_opt, "hspol:", 6)) {
++			boot_par.hsync_pol = simple_strtoul(this_opt+6,
++							    NULL, 0);
++		} else if (!strncmp(this_opt, "vspol:", 6)) {
++			boot_par.vsync_pol = simple_strtoul(this_opt+6,
++							    NULL, 0);
++		} else if (!strncmp(this_opt, "hsstart:", 8)) {
++			boot_par.hsync_start = simple_strtoul(this_opt+8,
++							      NULL, 0);
++		} else if (!strncmp(this_opt, "hswidth:", 8)) {
++			boot_par.hsync_width = simple_strtoul(this_opt+8,
++							      NULL, 0);
++		} else if (!strncmp(this_opt, "vsstart:", 8)) {
++			boot_par.vsync_start = simple_strtoul(this_opt+8,
++							      NULL, 0);
++		} else if (!strncmp(this_opt, "vswidth:", 8)) {
++			boot_par.vsync_width = simple_strtoul(this_opt+8,
++							      NULL, 0);
++		} else if (!strncmp(this_opt, "tvfilt:", 7)) {
++			boot_fix.tv_filt = simple_strtoul(this_opt+7, NULL, 0);
++		} else if (!strncmp(this_opt, "tvfmt:", 6)) {
++			boot_fix.tv_fmt = simple_strtoul(this_opt+6, NULL, 0);
++		} else if (!strncmp(this_opt, "system:", 7)) {
++			if (!strncmp(this_opt+7, "pb1000", 10)) {
++				boot_fix = systems[SYS_PB1000].fix;
++				boot_par = systems[SYS_PB1000].par;
++			} else if (!strncmp(this_opt+7, "pb1500", 7)) {
++				boot_fix = systems[SYS_PB1500].fix;
++				boot_par = systems[SYS_PB1500].par;
++			} else if (!strncmp(this_opt+7, "sdu1356", 7)) {
++				boot_fix = systems[SYS_SDU1356].fix;
++				boot_par = systems[SYS_SDU1356].par;
++			} else if (!strncmp(this_opt+7, "clio1050", 7)) {
++				boot_fix = systems[SYS_CLIO1050].fix;
++				boot_par = systems[SYS_CLIO1050].par;
++			}
++		} else {
++			boot_fix.mode_option = this_opt;
++		}
++	} 
++}
++
++
++/*
++ * FIXME: switching consoles could be dangerous. What if switching
++ * from a panel to a CRT/TV, or vice versa? More needs to be
++ * done here.
++ */
++static int
++e1356fb_switch_con(int con, struct fb_info *fb)
++{
++	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
++	struct e1356fb_par par;
++	int old_con = currcon;
++	int set_par = 1;
++
++	//DPRINTK("\n");
++
++	/* Do we have to save the colormap? */
++	if (currcon>=0)
++		if (fb_display[currcon].cmap.len)
++			fb_get_cmap(&fb_display[currcon].cmap, 1,
++				    e1356fb_getcolreg, fb);
++   
++	currcon = con;
++	fb_display[currcon].var.activate = FB_ACTIVATE_NOW; 
++	e1356fb_var_to_par(&fb_display[con].var, &par, info);
++	if (old_con>=0 && vt_cons[old_con]->vc_mode!=KD_GRAPHICS) {
++		/* check if we have to change video registers */
++		struct e1356fb_par old_par;
++		e1356fb_var_to_par(&fb_display[old_con].var, &old_par, info);
++		if (!memcmp(&par,&old_par,sizeof(par)))
++			set_par = 0;	/* avoid flicker */
++	}
++	if (set_par)
++		e1356fb_set_par(&par, info);
++    
++	if (fb_display[con].dispsw && fb_display[con].conp)
++		fb_con.con_cursor(fb_display[con].conp, CM_ERASE);
++   
++	del_timer(&(info->cursor.timer));
++	fb_info.cursor.state=CM_ERASE; 
++   
++	if (!info->fix.nohwcursor) 
++		if (fb_display[con].conp)
++			e1356fb_createcursor( &fb_display[con] );
++   
++	info->cursor.redraw=1;
++   
++	e1356fb_set_dispsw(&fb_display[con], 
++			   info, 
++			   par.bpp,
++			   fb_display[con].var.accel_flags & FB_ACCELF_TEXT);
++   
++	e1356fb_install_cmap(&fb_display[con], fb);
++	e1356fb_updatevar(con, fb);
++   
++	return 1;
++}
++
++/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
++static void
++e1356fb_blank(int blank, struct fb_info *fb)
++{
++	struct fb_info_e1356 *info = (struct fb_info_e1356*)fb;
++	reg_dispmode_t* dispmode = (IS_PANEL(info->fix.disp_type)) ?
++		info->reg.lcd_mode : info->reg.crttv_mode;
++	reg_pwrsave_t* pwrsave = info->reg.pwr_save;
++
++	//DPRINTK("\n");
++
++	switch (blank) {
++	case 0:
++		// Get out of power save mode
++		writeb(0x00, &pwrsave->cfg);
++		writeb(readb(&dispmode->disp_mode) & ~0x80,
++		       &dispmode->disp_mode);
++		break;
++	case 1:
++		// Get out of power save mode
++		writeb(0x00, &pwrsave->cfg);
++		writeb(readb(&dispmode->disp_mode) | 0x80,
++		       &dispmode->disp_mode);
++		break;
++		// No support for turning off horiz or vert sync, so just treat
++		// it as a power off.
++	case 2:
++	case 3:
++	case 4:
++		writeb(0x01, &pwrsave->cfg);
++		break;
++	}
++}
++
++
++static int
++e1356fb_updatevar(int con, struct fb_info* fb)
++{
++	struct fb_info_e1356* i = (struct fb_info_e1356*)fb;
++
++	//DPRINTK("\n");
++
++	if ((con==currcon) && (!i->fix.nopan)) 
++		do_pan_var(&fb_display[con].var,i);
++	return 0;
++}
++
++static int
++e1356fb_getcolreg(unsigned        regno, 
++		  unsigned*       red, 
++		  unsigned*       green,
++		  unsigned*       blue, 
++		  unsigned*       transp,
++		  struct fb_info* fb)
++{
++	struct fb_info_e1356* i = (struct fb_info_e1356*)fb;
++
++	if (regno > i->current_par.cmap_len)
++		return 1;
++   
++	*red    = i->palette[regno].red; 
++	*green  = i->palette[regno].green; 
++	*blue   = i->palette[regno].blue; 
++	*transp = 0;
++   
++	return 0;
++}
++
++static int
++e1356fb_setcolreg(unsigned        regno, 
++		  unsigned        red, 
++		  unsigned        green,
++		  unsigned        blue, 
++		  unsigned        transp,
++		  struct fb_info* info)
++{
++	struct fb_info_e1356* i = (struct fb_info_e1356*)info;
++
++	if (regno > 255)
++		return 1;
++
++	i->palette[regno].red    = red;
++	i->palette[regno].green  = green;
++	i->palette[regno].blue   = blue;
++   
++	switch(i->current_par.bpp) {
++#ifdef FBCON_HAS_CFB8
++	case 8:
++		do_setpalentry(i->reg.lut, regno,
++			       (u8)(red>>8), (u8)(green>>8), (u8)(blue>>8));
++		break;
++#endif
++#ifdef FBCON_HAS_CFB16
++	case 16:
++		i->fbcon_cmap16[regno] = (regno << 10) | (regno << 5) | regno;
++		break;
++#endif
++	default:
++		DPRINTK("bad depth %u\n", i->current_par.bpp);
++		break;
++	}
++	return 0;
++}
++
++static void
++e1356fb_install_cmap(struct display *d, struct fb_info *info) 
++{
++	struct fb_info_e1356* i = (struct fb_info_e1356*)info;
++
++	//DPRINTK("\n");
++
++	if (d->cmap.len) {
++		fb_set_cmap(&(d->cmap), 1, e1356fb_setcolreg, info);
++	} else {
++		fb_set_cmap(fb_default_cmap(i->current_par.cmap_len), 1,
++			    e1356fb_setcolreg, info);
++	}
++}
++
++static void
++e1356fb_createcursorshape(struct display* p) 
++{
++	int h,u;
++   
++	h = fontheight(p);
++
++	fb_info.cursor.type = p->conp->vc_cursor_type & CUR_HWMASK;
++
++	switch (fb_info.cursor.type) {
++	case CUR_NONE: 
++		u = h; 
++		break;
++	case CUR_UNDERLINE: 
++		u = h - 2; 
++		break;
++	case CUR_LOWER_THIRD: 
++		u = (h * 2) / 3; 
++		break;
++	case CUR_LOWER_HALF: 
++		u = h / 2; 
++		break;
++	case CUR_TWO_THIRDS: 
++		u = h / 3; 
++		break;
++	case CUR_BLOCK:
++	default:
++		u = 0;
++		break;
++	}
++    
++	fb_info.cursor.w = fontwidth_x8(p);
++	fb_info.cursor.u = u;
++	fb_info.cursor.h = h;
++}
++   
++static void
++e1356fb_createcursor(struct display *p)
++{
++	void* memcursor;
++	int y, w, h, u;
++    
++	e1356fb_createcursorshape(p);
++
++	h = fb_info.cursor.h;
++	w = fb_info.cursor.w;
++	u = fb_info.cursor.u;
++	memcursor = fb_info.membase_virt + fb_info.fb_size;
++
++	// write cursor to display memory
++	for (y=0; y<64; y++) {
++		if (y >= h || y < u) {
++			fbfill((u16*)memcursor, 0xaa, 16); // b/g
++		} else {
++			fbfill((u16*)memcursor, 0xff, w/4); // inverted b/g
++			fbfill((u16*)memcursor + w/4, 0xaa, (64 - w)/4); // b/g
++		}
++		memcursor += 16;
++	}
++}
++   
++static void
++e1356fb_hwcursor_init(struct fb_info_e1356* info)
++{
++	reg_inkcurs_t* inkcurs = (IS_PANEL(info->fix.disp_type)) ?
++		info->reg.lcd_inkcurs : info->reg.crttv_inkcurs;
++
++	fb_info.fb_size -= 1024;
++	// program cursor base address
++	writeb(0x00, &inkcurs->start_addr);
++	printk("e1356fb: reserving 1024 bytes for the hwcursor at %p\n",
++	       fb_info.membase_virt + fb_info.fb_size);
++}
++
++#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
++
++/*
++ * Return indicates whether a page was freed so caller can adjust rss
++ */
++static inline void forget_pte(pte_t page)
++{
++	if (!pte_none(page)) {
++		printk("forget_pte: old mapping existed!\n");
++		BUG();
++	}
++}
++
++/*
++ * maps a range of physical memory into the requested pages. the old
++ * mappings are removed. any references to nonexistent pages results
++ * in null mappings (currently treated as "copy-on-access")
++ */
++static inline void e1356_remap_pte_range(pte_t * pte, unsigned long address, unsigned long size,
++	phys_t phys_addr, pgprot_t prot)
++{
++	unsigned long end;
++
++	address &= ~PMD_MASK;
++	end = address + size;
++	if (end > PMD_SIZE)
++		end = PMD_SIZE;
++	do {
++		struct page *page;
++		pte_t oldpage;
++		oldpage = ptep_get_and_clear(pte);
++
++		page = virt_to_page(__va(phys_addr));
++		if ((!VALID_PAGE(page)) || PageReserved(page))
++ 			set_pte(pte, mk_pte_phys(phys_addr, prot));
++		forget_pte(oldpage);
++		address += PAGE_SIZE;
++		phys_addr += PAGE_SIZE;
++		pte++;
++	} while (address && (address < end));
++}
++
++static inline int e1356_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned long address, unsigned long size,
++	phys_t phys_addr, pgprot_t prot)
++{
++	unsigned long end;
++
++	address &= ~PGDIR_MASK;
++	end = address + size;
++	if (end > PGDIR_SIZE)
++		end = PGDIR_SIZE;
++	phys_addr -= address;
++	do {
++		pte_t * pte = pte_alloc(mm, pmd, address);
++		if (!pte)
++			return -ENOMEM;
++		e1356_remap_pte_range(pte, address, end - address, address + phys_addr, prot);
++		address = (address + PMD_SIZE) & PMD_MASK;
++		pmd++;
++	} while (address && (address < end));
++	return 0;
++}
++
++/*  Note: this is only safe if the mm semaphore is held when called. */
++static int e1356_remap_page_range(unsigned long from, phys_t phys_addr, unsigned long size, pgprot_t prot)
++{
++	int error = 0;
++	pgd_t * dir;
++	phys_t beg = from;
++	phys_t end = from + size;
++	struct mm_struct *mm = current->mm;
++
++	phys_addr -= from;
++	dir = pgd_offset(mm, from);
++	flush_cache_range(mm, beg, end);
++	if (from >= end)
++		BUG();
++
++	spin_lock(&mm->page_table_lock);
++	do {
++		pmd_t *pmd = pmd_alloc(mm, dir, from);
++		error = -ENOMEM;
++		if (!pmd)
++			break;
++		error = e1356_remap_pmd_range(mm, pmd, from, end - from, phys_addr + from, prot);
++		if (error)
++			break;
++		from = (from + PGDIR_SIZE) & PGDIR_MASK;
++		dir++;
++	} while (from && (from < end));
++	spin_unlock(&mm->page_table_lock);
++	flush_tlb_range(mm, beg, end);
++	return error;
++}
++#endif
+diff -urpNX dontdiff linux-2.6.10/drivers/video/epson1356fb.h linux-2.6.10-mips/drivers/video/epson1356fb.h
+--- linux-2.6.10/drivers/video/epson1356fb.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/epson1356fb.h	2002-08-15 11:27:24.000000000 +0200
+@@ -0,0 +1,646 @@
++/*
++ *      epson1356fb.h  --  Epson SED1356 Framebuffer Driver
++ *
++ * Copyright 2001 MontaVista Software Inc.
++ * Author: MontaVista Software, Inc.
++ *         	stevel at mvista.com or source at mvista.com
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ *
++ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  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.
++ */
++
++#ifdef E1356FB_DEBUG
++#define DPRINTK(a,b...) printk(KERN_DEBUG "e1356fb: %s: " a, __FUNCTION__ , ## b)
++#else
++#define DPRINTK(a,b...)
++#endif 
++
++#define E1356_REG_SIZE  0x200000
++
++#define PICOS2KHZ(a) (1000000000UL/(a))
++#define KHZ2PICOS(a) (1000000000UL/(a))
++
++#define MAX_PIXCLOCK  40000 // KHz
++#define NTSC_PIXCLOCK 14318 // KHz
++#define PAL_PIXCLOCK  17734 // KHz
++
++/*
++ * Maximum percent errors between desired pixel clock and
++ * supported pixel clock. Lower-than and higher-than desired
++ * clock percent errors.
++ */
++#define MAX_PCLK_ERROR_LOWER  10
++#define MAX_PCLK_ERROR_HIGHER -1
++
++#define fontwidth_x8(p) (((fontwidth(p) + 7) >> 3) << 3)
++
++/*
++ * Register Structures
++ */
++
++// Basic
++#define REG_BASE_BASIC     0x00
++typedef struct {
++	u8 rev_code;           // 00
++	u8 misc;               // 01
++} reg_basic_t;
++
++// General IO Pins
++#define REG_BASE_GENIO     0x04
++typedef struct {
++	u8 gpio_cfg;           // 04
++	u8 gpio_cfg2;          // 05 SED13806
++	u8 spacer[2];          // 06
++	u8 gpio_ctrl;          // 08
++	u8 gpio_ctrl2;         // 09 SED13806
++} reg_genio_t;
++
++// MD Config Readback
++#define REG_BASE_MDCFG     0x0c
++typedef struct {
++	u8 md_cfg_stat0;       // 0C
++	u8 md_cfg_stat1;       // 0D
++} reg_mdcfg_t;
++
++// Clock Config
++#define REG_BASE_CLKCFG    0x10
++typedef struct {
++	u8 mem_clk_cfg;        // 10
++	u8 spacer1[3];         // 11
++	u8 lcd_pclk_cfg;       // 14
++	u8 spacer2[3];         // 15
++	u8 crttv_pclk_cfg;     // 18
++	u8 spacer3[3];         // 19
++	u8 mpclk_cfg;          // 1C
++	u8 spacer4;            // 1D
++	u8 cpu2mem_wait_sel;   // 1E
++} reg_clkcfg_t;
++
++// Memory Config
++#define REG_BASE_MEMCFG    0x20
++typedef struct {
++	u8 mem_cfg;            // 20
++	u8 dram_refresh;       // 21
++	u8 spacer[8];          // 22
++	u8 dram_timings_ctrl0; // 2A
++	u8 dram_timings_ctrl1; // 2B
++} reg_memcfg_t;
++
++// Panel Config
++#define REG_BASE_PANELCFG  0x30
++typedef struct {
++	u8 panel_type;         // 30
++	u8 mod_rate;           // 31
++} reg_panelcfg_t;
++
++// LCD and CRTTV Display Config
++#define REG_BASE_LCD_DISPCFG   0x32
++#define REG_BASE_CRTTV_DISPCFG 0x50
++typedef struct {
++	u8 hdw;                // 32 or 50
++	u8 spacer1;            // 33 or 51
++	u8 hndp;               // 34 or 52
++	u8 hsync_start;        // 35 or 53
++	u8 hsync_pulse;        // 36 or 54
++	u8 spacer2;            // 37 or 55
++	u8 vdh0;               // 38 or 56
++	u8 vdh1;               // 39 or 57
++	u8 vndp;               // 3A or 58
++	u8 vsync_start;        // 3B or 59
++	u8 vsync_pulse;        // 3C or 5A
++	u8 tv_output_ctrl;     // 5B (TV only)
++} reg_dispcfg_t;
++
++// LCD and CRTTV Display Mode
++#define REG_BASE_LCD_DISPMODE   0x40
++#define REG_BASE_CRTTV_DISPMODE 0x60
++typedef struct {
++	u8 disp_mode;          // 40 or 60
++	u8 lcd_misc;           // 41 (LCD only)
++	u8 start_addr0;        // 42 or 62
++	u8 start_addr1;        // 43 or 63
++	u8 start_addr2;        // 44 or 64
++	u8 spacer1;            // 45 or 65
++	u8 mem_addr_offset0;   // 46 or 66
++	u8 mem_addr_offset1;   // 47 or 67
++	u8 pixel_panning;      // 48 or 68
++	u8 spacer2;            // 49 or 69
++	u8 fifo_high_thresh;   // 4A or 6A
++	u8 fifo_low_thresh;    // 4B or 6B
++} reg_dispmode_t;
++
++// LCD and CRTTV Ink/Cursor
++#define REG_BASE_LCD_INKCURS   0x70
++#define REG_BASE_CRTTV_INKCURS 0x80
++typedef struct {
++	u8 ctrl;               // 70 or 80
++	u8 start_addr;         // 71 or 81
++	u8 x_pos0;             // 72 or 82
++	u8 x_pos1;             // 73 or 83
++	u8 y_pos0;             // 74 or 84
++	u8 y_pos1;             // 75 or 85
++	u8 blue0;              // 76 or 86
++	u8 green0;             // 77 or 87
++	u8 red0;               // 78 or 88
++	u8 spacer1;            // 79 or 89
++	u8 blue1;              // 7A or 8A
++	u8 green1;             // 7B or 8B
++	u8 red1;               // 7C or 8C
++	u8 spacer2;            // 7D or 8D
++	u8 fifo;               // 7E or 8E
++} reg_inkcurs_t;
++
++// BitBlt Config
++#define REG_BASE_BITBLT        0x100
++typedef struct {
++	u8 ctrl0;              // 100
++	u8 ctrl1;              // 101
++	u8 rop_code;           // 102
++	u8 operation;          // 103
++	u8 src_start_addr0;    // 104
++	u8 src_start_addr1;    // 105
++	u8 src_start_addr2;    // 106
++	u8 spacer1;            // 107
++	u8 dest_start_addr0;   // 108
++	u8 dest_start_addr1;   // 109
++	u8 dest_start_addr2;   // 10A
++	u8 spacer2;            // 10B
++	u8 mem_addr_offset0;   // 10C
++	u8 mem_addr_offset1;   // 10D
++	u8 spacer3[2];         // 10E
++	u8 width0;             // 110
++	u8 width1;             // 111
++	u8 height0;            // 112
++	u8 height1;            // 113
++	u8 bg_color0;          // 114
++	u8 bg_color1;          // 115
++	u8 spacer4[2];         // 116
++	u8 fg_color0;          // 118
++	u8 fg_color1;          // 119
++} reg_bitblt_t;
++
++// LUT
++#define REG_BASE_LUT           0x1e0
++typedef struct {
++	u8 mode;               // 1E0
++	u8 spacer1;            // 1E1
++	u8 addr;               // 1E2
++	u8 spacer2;            // 1E3
++	u8 data;               // 1E4
++} reg_lut_t;
++
++// Power Save Config
++#define REG_BASE_PWRSAVE       0x1f0
++typedef struct {
++	u8 cfg;                // 1F0
++	u8 status;             // 1F1
++} reg_pwrsave_t;
++
++// Misc
++#define REG_BASE_MISC          0x1f4
++typedef struct {
++	u8 cpu2mem_watchdog;   // 1F4
++	u8 spacer[7];          // 1F5
++	u8 disp_mode;          // 1FC
++} reg_misc_t;
++
++// MediaPlug
++#define REG_BASE_MEDIAPLUG     0x1000
++typedef struct {
++	u8 lcmd;               // 1000
++	u8 spacer1;            // 1001
++	u8 reserved_lcmd;      // 1002
++	u8 spacer2;            // 1003
++	u8 cmd;                // 1004
++	u8 spacer3;            // 1005
++	u8 reserved_cmd;       // 1006
++	u8 spacer4;            // 1007
++	u8 data;               // 1008
++} reg_mediaplug_t;
++
++// BitBlt data register. 16-bit access only
++#define REG_BASE_BITBLT_DATA   0x100000
++
++typedef struct {
++	reg_basic_t* basic;
++	reg_genio_t* genio;
++	reg_mdcfg_t* md_cfg;
++	reg_clkcfg_t* clk_cfg;
++	reg_memcfg_t* mem_cfg;
++	reg_panelcfg_t* panel_cfg;
++	reg_dispcfg_t* lcd_cfg;
++	reg_dispcfg_t* crttv_cfg;
++	reg_dispmode_t* lcd_mode;
++	reg_dispmode_t* crttv_mode;
++	reg_inkcurs_t* lcd_inkcurs;
++	reg_inkcurs_t* crttv_inkcurs;
++	reg_bitblt_t* bitblt;
++	reg_lut_t* lut;
++	reg_pwrsave_t* pwr_save;
++	reg_misc_t* misc;
++	reg_mediaplug_t* mediaplug;
++	u16* bitblt_data;
++} e1356_reg_t;
++
++
++/*--------------------------------------------------------*/
++
++enum mem_type_t {
++	MEM_TYPE_EDO_2CAS = 0,
++	MEM_TYPE_FPM_2CAS,
++	MEM_TYPE_EDO_2WE,
++	MEM_TYPE_FPM_2WE,
++	MEM_TYPE_EMBEDDED_SDRAM = 0x80
++};
++
++enum mem_smr_t {
++	MEM_SMR_CBR = 0,
++	MEM_SMR_SELF,
++	MEM_SMR_NONE
++};
++
++enum disp_type_t {
++	DISP_TYPE_LCD = 0,
++	DISP_TYPE_TFT,
++	DISP_TYPE_CRT,
++	DISP_TYPE_PAL,
++	DISP_TYPE_NTSC
++};
++
++/*
++ * Maximum timing values, as determined by the SED1356 register
++ * field sizes. All are indexed by display type, except
++ * max_hsync_start which is first indexed by color depth,
++ * then by display type.
++ */
++static const int max_hndp[5] = {256, 256, 512, 511, 510};
++static const int max_hsync_start[2][5] = {
++	{0, 252, 507, 505, 505}, // 8 bpp
++	{0, 254, 509, 507, 507}  // 16 bpp
++};
++static const int max_hsync_width[5] = {0, 128, 128, 0, 0};
++static const int max_vndp[5] = {64, 64, 128, 128, 128};
++static const int max_vsync_start[5] = {0, 64, 128, 128, 128};
++static const int max_vsync_width[5] = {0, 8, 8, 0, 0};
++
++#define IS_PANEL(disp_type) \
++    (disp_type == DISP_TYPE_LCD || disp_type == DISP_TYPE_TFT)
++#define IS_CRT(disp_type) (disp_type == DISP_TYPE_CRT)
++#define IS_TV(disp_type) \
++    (disp_type == DISP_TYPE_NTSC || disp_type == DISP_TYPE_PAL)
++
++
++enum tv_filters_t {
++	TV_FILT_LUM = 1,
++	TV_FILT_CHROM = 2,
++	TV_FILT_FLICKER = 4
++};
++
++enum tv_format_t {
++	TV_FMT_COMPOSITE = 0,
++	TV_FMT_S_VIDEO
++};
++
++
++struct e1356fb_fix {
++	int system;       // the number of a pre-packaged system
++	u64 regbase_phys; // phys start address of registers
++	u64 membase_phys; // phys start address of fb memory
++
++	// Memory parameters
++	int mem_speed;    // speed: 50, 60, 70, or 80 (nsec)
++	int mem_type;     // mem type: EDO-2CAS, FPM-2CAS, EDO-2WE, FPM-2WE
++	int mem_refresh;  // refresh rate in KHz
++	int mem_smr;      // suspend mode refresh: CAS_BEFORE_RAS, SELF, or NONE
++	// Clocks
++	int busclk;       // BUSCLK frequency, in KHz
++	int mclk;         // MCLK freq, in KHz, will either be BUSCLK or BUSCLK/2
++	int clki;         // CLKI frequency, in KHz
++	int clki2;        // CLKI2 frequency, in KHz
++
++	int disp_type;    // LCD, TFT, CRT, PAL, or NTSC
++
++	// TV Options
++	u8  tv_filt;      // TV Filter mask, LUM, CHROM, and FLICKER
++	int tv_fmt;       // TV output format, COMPOSITE or S_VIDEO
++    
++	// Panel (LCD,TFT) Options
++	int panel_el;     // enable support for EL-type panels
++	int panel_width;  // Panel data width: LCD: 4/8/16, TFT: 9/12/18
++    
++	// Misc
++	int noaccel;
++	int nopan;
++#ifdef CONFIG_MTRR
++	int nomtrr;
++#endif
++	int nohwcursor;
++	int mmunalign;    // force unaligned returned VA in mmap()
++	char fontname[40];
++
++	char *mode_option;
++};
++
++
++typedef struct {
++	int pixclk_d;     // Desired Pixel Clock, KHz
++	int pixclk;       // Closest supported clock to desired clock, KHz
++	int error;        // percent error between pixclock and pixclock_d
++	int clksrc;       // equal to busclk, mclk, clki, or clki2, KHz
++	int divisor;      // pixclk = clksrc/divisor, where divisor = 1,2,3, or 4
++	u8  pixclk_bits;  // pixclock register value for above settings
++} pixclock_info_t;
++
++
++struct e1356fb_par {
++	int width;
++	int height;
++	int width_virt;   // Width in pixels
++	int height_virt;  // Height in lines
++	int bpp;          // bits-per-pixel
++	int Bpp;          // Bytes-per-pixel
++
++	// Timing
++	pixclock_info_t ipclk;
++	int horiz_ndp;    // Horiz. Non-Display Period, pixels
++	int vert_ndp;     // Vert. Non-Display Period, lines
++	int hsync_pol;    // Polarity of horiz. sync signal (HRTC for CRT/TV,
++	// FPLINE for TFT). 0=active lo, 1=active hi
++	int hsync_start;  // Horiz. Sync Start position, pixels
++	int hsync_width;  // Horiz. Sync Pulse width, pixels
++	int hsync_freq;   // calculated horizontal sync frequency
++	int vsync_pol;    // Polarity of vert. sync signal (VRTC for CRT/TV,
++	// FPFRAME for TFT). 0=active lo, 1=active hi
++	int vsync_start;  // Vert. Sync Start position, lines
++	int vsync_width;  // Vert. Sync Pulse width, lines
++	int vsync_freq;   // calculated vertical sync frequency
++
++	int cmap_len;     // color-map length
++};
++
++
++
++struct fb_info_e1356 {
++	struct fb_info fb_info;
++
++	void *regbase_virt;
++	unsigned long regbase_size;
++	void *membase_virt;
++	unsigned long fb_size;
++
++	e1356_reg_t reg;
++
++	void* putcs_buffer;
++    
++	int max_pixclock;   // Max supported pixel clock, KHz
++	int open, mmaped;   // open count, is mmap'ed
++	
++	u8 chip_rev;
++    
++#ifdef CONFIG_MTRR
++	int mtrr_idx;
++#endif
++
++#ifdef SHADOW_FRAME_BUFFER
++	struct {
++		void* fb;
++		struct timer_list timer;
++	} shadow;
++#endif
++
++	struct { unsigned red, green, blue, pad; } palette[256];
++	struct display disp;
++
++#if defined(FBCON_HAS_CFB16)
++	u16 fbcon_cmap16[16];
++#endif
++    
++	struct {
++		int type;
++		int state;
++		int w,h,u;
++		int x,y,redraw;
++		unsigned long enable,disable;
++		struct timer_list timer;
++		spinlock_t lock; 
++	} cursor;
++ 
++	struct e1356fb_fix fix;
++	struct e1356fb_par default_par;
++	struct e1356fb_par current_par;
++};
++
++
++// The following are boot options for particular SED1356-based target systems
++
++enum {
++	SYS_NULL,
++	SYS_PB1000,
++	SYS_PB1500,
++	SYS_SDU1356,
++	SYS_CLIO1050,
++	NUM_SYSTEMS // must be last
++};
++
++static struct {
++	struct e1356fb_fix fix;
++	struct e1356fb_par par;
++} systems[NUM_SYSTEMS] = {
++
++	/*
++	 * NULL system to help us detect missing options
++ 	 * when the driver is compiled as a module.
++	 */
++	{
++		{   // fix
++			SYS_NULL,
++		},
++		{   // par
++		}
++	},
++
++	/*
++	 * Alchemy Pb1000 evaluation board, SED1356
++	 */
++	{
++		{   // fix
++			SYS_PB1000,
++			/*
++			 * Note!: these are "pseudo" physical addresses;
++			 * the SED1356 is not actually mapped here, but rather
++			 * at the 36-bit address of 0xE 0000 0000. There is an
++			 * ugly hack in the Au1000 TLB refill handler that will
++			 * translate pte_t's in the range 0xE000 0000 -->
++			 * 0xEFFF FFFF to the 36-bit range 0xE 0000 0000 -->
++			 * 0xE 0FFF FFFF. The long-term solution is to support
++			 * 36-bit physical addresses in linux-mips32 mm, since
++			 * the mips32 specification specifically supports this.
++			 */
++			0xE00000000, 0xE00200000,
++			60, MEM_TYPE_EDO_2CAS, 64, MEM_SMR_CBR,
++			0, 0,   // BUSCLK and MCLK are calculated at run-time
++			40000, 14318, // CLKI, CLKI2
++#ifdef CONFIG_PB1000_CRT
++			DISP_TYPE_CRT,
++			0, 0, // TV Options
++			0, 0, // Panel options
++#elif defined (CONFIG_PB1000_NTSC)
++			DISP_TYPE_NTSC,
++			TV_FILT_FLICKER|TV_FILT_LUM|TV_FILT_CHROM,
++			TV_FMT_COMPOSITE,
++			0, 0, // Panel options
++#elif defined (CONFIG_PB1000_TFT)
++			DISP_TYPE_TFT,
++			0, 0, // TV Options
++			0, 12, // Panel options, EL panel?, data width?
++#else
++			DISP_TYPE_PAL,
++			TV_FILT_FLICKER|TV_FILT_LUM|TV_FILT_CHROM,
++			TV_FMT_COMPOSITE,
++			0, 0, // Panel options
++#endif
++			0, 0,
++#ifdef CONFIG_MTRR
++			0,
++#endif
++			0,
++			0,
++			{0},
++			"800x600 at 60"
++		},
++		{   // par
++			0, 0, 800, 600, 8, 1,
++			// timings will be set by modedb
++			{0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++			256
++		}
++	},
++
++	/*
++	 * Alchemy Pb1500 evaluation board, SED13806
++	 */
++	{
++		{   // fix
++			SYS_PB1500,
++			/*
++			 * Note!: these are "pseudo" physical addresses;
++			 * the SED1356 is not actually mapped here, but rather
++			 * at the 36-bit address of 0xE 0000 0000. There is an
++			 * ugly hack in the Au1000 TLB refill handler that will
++			 * translate pte_t's in the range 0xE000 0000 -->
++			 * 0xEFFF FFFF to the 36-bit range 0xE 0000 0000 -->
++			 * 0xE 0FFF FFFF. The long-term solution is to support
++			 * 36-bit physical addresses in linux-mips32 mm, since
++			 * the mips32 specification specifically supports this.
++			 */
++			0xE1B000000, 0xE1B200000,
++			50, MEM_TYPE_EMBEDDED_SDRAM, 64, MEM_SMR_CBR,
++			0, 0,   // BUSCLK and MCLK are calculated at run-time
++			40000, 14318, // CLKI, CLKI2
++#ifdef CONFIG_PB1500_CRT
++			DISP_TYPE_CRT,
++			0, 0, // TV Options
++			0, 0, // Panel options
++#else
++			DISP_TYPE_TFT,
++			0, 0, // TV Options
++			0, 12, // Panel options, EL panel?, data width?
++#endif
++			0, 0,
++#ifdef CONFIG_MTRR
++			0,
++#endif
++			0,
++			0,
++			{0},
++			"800x600 at 60"
++		},
++		{   // par
++			0, 0, 800, 600, 8, 1,
++			// timings will be set by modedb
++			{0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++			256
++		}
++	},
++
++	/*
++	 * Epson SDU1356B0C PCI eval card. These settings assume the
++	 * card is configured for PCI, the MediaPlug is disabled,
++	 * and the onboard clock synthesizer is at the power-up
++	 * clock settings.
++	 */
++	{
++		{   // fix
++			SYS_SDU1356,
++			0x0, 0x0,  // addresses obtained from PCI config space
++			// FIXME: just guess for now
++			60, MEM_TYPE_EDO_2CAS, 64, MEM_SMR_CBR,
++			33000, 0, 40000, 25175, // BUSCLK, MCLK, CLKI, CLKI2
++			DISP_TYPE_CRT,
++			0, 0,
++			0, 0,
++			0, 0,
++#ifdef CONFIG_MTRR
++			0,
++#endif
++			0,
++			0,
++			{0},
++			"800x600 at 60"
++		},
++		{   // par
++			0, 0, 1024, 768, 8, 1,
++			// timings will be set by modedb
++			{0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++			256
++		}
++	},
++
++	/*
++	 * Vadem Clio 1050 - this is for the benefit of the Linux-VR project.
++	 * FIXME: Most of these settings are just guesses, until I can get a
++	 * Clio 1050 and dump the registers that WinCE has setup.
++	 */
++	{
++		{   // fix
++			SYS_CLIO1050,
++			0x0a000000, 0x0a200000,
++			60, MEM_TYPE_EDO_2CAS, 64, MEM_SMR_CBR,
++			40000, 40000, 14318, 14318,
++			DISP_TYPE_TFT,
++			0, 0,
++			0, 16,
++			0, 0,
++#ifdef CONFIG_MTRR
++			0,
++#endif
++			0,
++			0,
++			{0},
++			"640x480 at 85"
++		},
++		{   // par
++			0, 0, 1024, 768, 16, 2,
++			// timings will be set by modedb
++			{0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++			16
++		}
++	}
++};
+diff -urpNX dontdiff linux-2.6.10/drivers/video/g364fb.c linux-2.6.10-mips/drivers/video/g364fb.c
+--- linux-2.6.10/drivers/video/g364fb.c	2004-12-24 22:33:59.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/g364fb.c	2004-10-12 19:31:17.000000000 +0200
+@@ -15,6 +15,7 @@
+  */
+ 
+ #include <linux/module.h>
++#include <linux/console.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+diff -urpNX dontdiff linux-2.6.10/drivers/video/gbefb.c linux-2.6.10-mips/drivers/video/gbefb.c
+--- linux-2.6.10/drivers/video/gbefb.c	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/gbefb.c	2004-11-21 18:39:55.000000000 +0100
+@@ -85,7 +85,6 @@ static struct {
+ 
+ static int gbe_revision;
+ 
+-static struct fb_info fb_info;
+ static int ypan, ywrap;
+ 
+ static uint32_t pseudo_palette[256];
+@@ -190,8 +189,6 @@ struct fb_var_screeninfo *default_var = 
+ 
+ static int flat_panel_enabled = 0;
+ 
+-static struct gbefb_par par_current;
+-
+ static void gbe_reset(void)
+ {
+ 	/* Turn on dotclock PLL */
+@@ -1045,6 +1042,36 @@ static struct fb_ops gbefb_ops = {
+ };
+ 
+ /*
++ * sysfs
++ */
++
++static ssize_t gbefb_show_memsize(struct device *dev, char *buf)
++{
++	return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
++}
++
++static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
++
++static ssize_t gbefb_show_rev(struct device *device, char *buf)
++{
++	return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
++}
++
++static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
++
++static void __devexit gbefb_remove_sysfs(struct device *dev)
++{
++	device_remove_file(dev, &dev_attr_size);
++	device_remove_file(dev, &dev_attr_revision);
++}
++
++static void gbefb_create_sysfs(struct device *dev) 
++{
++	device_create_file(dev, &dev_attr_size);
++	device_create_file(dev, &dev_attr_revision);
++}
++
++/*
+  * Initialization
+  */
+ 
+@@ -1079,13 +1106,21 @@ int __init gbefb_setup(char *options)
+ 	return 0;
+ }
+ 
+-int __init gbefb_init(void)
++static int __init gbefb_probe(struct device *dev)
+ {
+ 	int i, ret = 0;
+-
++	struct fb_info *info;
++	struct gbefb_par *par;
++	struct platform_device *p_dev = to_platform_device(dev);
+ #ifndef MODULE
+ 	char *options = NULL;
++#endif
+ 
++	info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
++	if (!info)
++		return -ENOMEM;
++
++#ifndef MODULE
+ 	if (fb_get_options("gbefb", &options))
+ 		return -ENODEV;
+ 	gbefb_setup(options);
+@@ -1093,7 +1128,8 @@ int __init gbefb_init(void)
+ 
+ 	if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
+ 		printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
+-		return -EBUSY;
++		ret = -EBUSY;
++		goto out_release_framebuffer;
+ 	}
+ 
+ 	gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
+@@ -1113,7 +1149,6 @@ int __init gbefb_init(void)
+ 		goto out_unmap;
+ 	}
+ 
+-
+ 	if (gbe_mem_phys) {
+ 		/* memory was allocated at boot time */
+ 		gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
+@@ -1140,32 +1175,35 @@ int __init gbefb_init(void)
+ 	for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
+ 		gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
+ 
+-	fb_info.fbops = &gbefb_ops;
+-	fb_info.pseudo_palette = pseudo_palette;
+-	fb_info.flags = FBINFO_DEFAULT;
+-	fb_info.screen_base = gbe_mem;
+-	fb_alloc_cmap(&fb_info.cmap, 256, 0);
++	info->fbops = &gbefb_ops;
++	info->pseudo_palette = pseudo_palette;
++	info->flags = FBINFO_DEFAULT;
++	info->screen_base = gbe_mem;
++	fb_alloc_cmap(&info->cmap, 256, 0);
+ 
+ 	/* reset GBE */
+ 	gbe_reset();
+ 
++	par = info->par;
+ 	/* turn on default video mode */
+-	if (fb_find_mode(&par_current.var, &fb_info, mode_option, NULL, 0,
++	if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
+ 			 default_mode, 8) == 0)
+-		par_current.var = *default_var;
+-	fb_info.var = par_current.var;
+-	gbefb_check_var(&par_current.var, &fb_info);
+-	gbefb_encode_fix(&fb_info.fix, &fb_info.var);
+-	fb_info.par = &par_current;
++		par->var = *default_var;
++	info->var = par->var;
++	gbefb_check_var(&par->var, info);
++	gbefb_encode_fix(&info->fix, &info->var);
+ 
+-	if (register_framebuffer(&fb_info) < 0) {
+-		ret = -ENXIO;
++	if (register_framebuffer(info) < 0) {
+ 		printk(KERN_ERR "gbefb: couldn't register framebuffer\n");
++		ret = -ENXIO;
+ 		goto out_gbe_unmap;
+ 	}
+ 
++	dev_set_drvdata(&p_dev->dev, info);
++	gbefb_create_sysfs(dev);
++
+ 	printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
+-	       fb_info.node, fb_info.fix.id, gbe_revision, (unsigned) GBE_BASE,
++	       info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
+ 	       gbe_mem_size >> 10);
+ 
+ 	return 0;
+@@ -1182,12 +1220,18 @@ out_unmap:
+ 	iounmap(gbe);
+ out_release_mem_region:
+ 	release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
++out_release_framebuffer:
++	framebuffer_release(info);
++
+ 	return ret;
+ }
+ 
+-void __exit gbefb_exit(void)
++static int __devexit gbefb_remove(struct device* dev)
+ {
+-	unregister_framebuffer(&fb_info);
++	struct platform_device *p_dev = to_platform_device(dev);
++	struct fb_info *info = dev_get_drvdata(&p_dev->dev);
++
++	unregister_framebuffer(info);
+ 	gbe_turn_off();
+ 	if (gbe_dma_addr)
+ 		dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
+@@ -1197,12 +1241,40 @@ void __exit gbefb_exit(void)
+ 			  (void *)gbe_tiles.cpu, gbe_tiles.dma);
+ 	release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
+ 	iounmap(gbe);
++	gbefb_remove_sysfs(dev);
++	framebuffer_release(info);
++
++	return 0;
+ }
+ 
+-module_init(gbefb_init);
++static struct device_driver gbefb_driver = {
++	.name = "gbefb",
++	.bus = &platform_bus_type,
++	.probe = gbefb_probe,
++	.remove = __devexit_p(gbefb_remove),
++};
++
++static struct platform_device gbefb_device = {
++	.name = "gbefb",
++};
+ 
+-#ifdef MODULE
++int __init gbefb_init(void)
++{
++	int ret = driver_register(&gbefb_driver);
++	if (!ret) {
++		ret = platform_device_register(&gbefb_device);
++		if (ret)
++			driver_unregister(&gbefb_driver);
++	}
++	return ret;
++}
++
++void __exit gbefb_exit(void)
++{
++	 driver_unregister(&gbefb_driver);
++}
++
++module_init(gbefb_init);
+ module_exit(gbefb_exit);
+-#endif
+ 
+ MODULE_LICENSE("GPL");
+diff -urpNX dontdiff linux-2.6.10/drivers/video/logo/Kconfig linux-2.6.10-mips/drivers/video/logo/Kconfig
+--- linux-2.6.10/drivers/video/logo/Kconfig	2004-12-24 22:34:32.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/logo/Kconfig	2004-03-23 20:43:53.000000000 +0100
+@@ -25,7 +25,7 @@ config LOGO_LINUX_CLUT224
+ 
+ config LOGO_DEC_CLUT224
+ 	bool "224-color Digital Equipment Corporation Linux logo"
+-	depends on LOGO && DECSTATION
++	depends on LOGO && MACH_DECSTATION
+ 	default y
+ 
+ config LOGO_MAC_CLUT224
+diff -urpNX dontdiff linux-2.6.10/drivers/video/maxinefb.c linux-2.6.10-mips/drivers/video/maxinefb.c
+--- linux-2.6.10/drivers/video/maxinefb.c	2004-12-24 22:34:27.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/maxinefb.c	2004-10-12 19:31:18.000000000 +0200
+@@ -43,31 +43,25 @@
+ static struct fb_info fb_info;
+ 
+ static struct fb_var_screeninfo maxinefb_defined = {
+-	.xres 		= 1024,
+-	.yres 		= 768,
+-	.xres_virtual 	= 1024,
+-	.yres_virtual 	= 768,
+-	.bits_per_pixel = 8,
+-	.red.length	= 8,
+-	.green.length	= 8,
+-	.blue.length	= 8,
+-	.activate 	= FB_ACTIVATE_NOW,
+-	.height 	= -1,
+-	.width 		= -1,
+-	.vmode 		= FB_VMODE_NONINTERLACED,
++	.xres =		1024,
++	.yres =		768,
++	.xres_virtual =	1024,
++	.yres_virtual =	768,
++	.bits_per_pixel =8,
++	.activate =	FB_ACTIVATE_NOW,
++	.height =	-1,
++	.width =	-1,
++	.vmode =	FB_VMODE_NONINTERLACED,
+ };
+ 
+ static struct fb_fix_screeninfo maxinefb_fix = {
+-	.id 		= "Maxine onboard graphics 1024x768x8",
+-	.smem_len 	= (1024*768),
+-	.type 		= FB_TYPE_PACKED_PIXELS,
+-	.visual 	= FB_VISUAL_PSEUDOCOLOR,
+-	.line_length 	= 1024,
++	.id =		"Maxine onboard graphics 1024x768x8",
++	.smem_len =	(1024*768),
++	.type =		FB_TYPE_PACKED_PIXELS,
++	.visual =	FB_VISUAL_PSEUDOCOLOR,
++	.line_length =	1024,
+ };
+ 
+-/* Reference to machine type set in arch/mips/dec/prom/identify.c, KM */
+-extern unsigned long mips_machtype;
+-
+ /* Handle the funny Inmos RamDAC/video controller ... */
+ 
+ void maxinefb_ims332_write_register(int regno, register unsigned int val)
+@@ -100,12 +94,12 @@ static int maxinefb_setcolreg(unsigned r
+ 	/* value to be written into the palette reg. */
+ 	unsigned long hw_colorvalue = 0;
+ 
+-	red   >>= 8;	/* The cmap fields are 16 bits    */
+-	green >>= 8;	/* wide, but the harware colormap */
+-	blue  >>= 8;	/* registers are only 8 bits wide */
++	red   >>= 8;    /* The cmap fields are 16 bits    */
++	green >>= 8;    /* wide, but the harware colormap */
++	blue  >>= 8;    /* registers are only 8 bits wide */
+ 
+ 	hw_colorvalue = (blue << 16) + (green << 8) + (red);
+-	
++
+ 	maxinefb_ims332_write_register(IMS332_REG_COLOR_PALETTE + regno,
+ 				       hw_colorvalue);
+ 	return 0;
+@@ -113,16 +107,18 @@ static int maxinefb_setcolreg(unsigned r
+ 
+ static struct fb_ops maxinefb_ops = {
+ 	.owner		= THIS_MODULE,
+-	.fb_setcolreg	= maxinefb_setcolreg,	
++	.fb_get_fix	= gen_get_fix,
++	.fb_get_var	= gen_get_var,
++	.fb_setcolreg	= maxinefb_setcolreg,     
+ 	.fb_fillrect	= cfb_fillrect,
+ 	.fb_copyarea	= cfb_copyarea,
+-	.fb_imageblit	= cfb_imageblit,		
++	.fb_imageblit	= cfb_imageblit,
+ 	.fb_cursor	= soft_cursor,
+ };
+ 
+ int __init maxinefb_init(void)
+ {
+-	volatile unsigned char *fboff;
++	unsigned long fboff;
+ 	unsigned long fb_start;
+ 	int i;
+ 
+@@ -142,7 +138,7 @@ int __init maxinefb_init(void)
+ 
+ 	/* Clear screen */
+ 	for (fboff = fb_start; fboff < fb_start + 0x1ffff; fboff++)
+-		*fboff = 0x0;
++		*(volatile unsigned char *)fboff = 0x0;
+ 
+ 	maxinefb_fix.smem_start = fb_start;
+ 	
+@@ -159,7 +155,7 @@ int __init maxinefb_init(void)
+ 	}
+ 
+ 	fb_info.fbops = &maxinefb_ops;
+-	fb_info.screen_base = (char *) maxinefb_fix.smem_start;
++	fb_info.screen_base = (char *)maxinefb_fix.smem_start;
+ 	fb_info.var = maxinefb_defined;
+ 	fb_info.fix = maxinefb_fix;
+ 	fb_info.flags = FBINFO_DEFAULT;
+diff -urpNX dontdiff linux-2.6.10/drivers/video/pmag-aa-fb.c linux-2.6.10-mips/drivers/video/pmag-aa-fb.c
+--- linux-2.6.10/drivers/video/pmag-aa-fb.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/pmag-aa-fb.c	2003-12-18 22:47:09.000000000 +0100
+@@ -0,0 +1,514 @@
++/*
++ *	linux/drivers/video/pmag-aa-fb.c
++ *	Copyright 2002 Karsten Merker <merker at debian.org>
++ *
++ *	PMAG-AA TurboChannel framebuffer card support ... derived from
++ *	pmag-ba-fb.c, which is Copyright (C) 1999, 2000, 2001 by
++ *	Michael Engel <engel at unix-ag.org>, Karsten Merker <merker at debian.org>
++ *	and Harald Koerfgen <hkoerfg at web.de>, which itself is derived from
++ *	"HP300 Topcat framebuffer support (derived from macfb of all things)
++ *	Phil Blundell <philb at gnu.org> 1998"
++ *
++ *	This file is subject to the terms and conditions of the GNU General
++ *	Public License.  See the file COPYING in the main directory of this
++ *	archive for more details.
++ *
++ *	2002-09-28  Karsten Merker <merker at linuxtag.org>
++ *		Version 0.01: First try to get a PMAG-AA running.
++ *
++ *	2003-02-24  Thiemo Seufer  <seufer at csv.ica.uni-stuttgart.de>
++ *		Version 0.02: Major code cleanup.
++ *
++ *	2003-09-21  Thiemo Seufer  <seufer at csv.ica.uni-stuttgart.de>
++ *		Hardware cursor support.
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/errno.h>
++#include <linux/string.h>
++#include <linux/timer.h>
++#include <linux/mm.h>
++#include <linux/tty.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/init.h>
++#include <linux/fb.h>
++#include <linux/console.h>
++
++#include <asm/bootinfo.h>
++#include <asm/dec/machtype.h>
++#include <asm/dec/tc.h>
++
++#include <video/fbcon.h>
++#include <video/fbcon-cfb8.h>
++
++#include "bt455.h"
++#include "bt431.h"
++
++/* Version information */
++#define DRIVER_VERSION "0.02"
++#define DRIVER_AUTHOR "Karsten Merker <merker at linuxtag.org>"
++#define DRIVER_DESCRIPTION "PMAG-AA Framebuffer Driver"
++
++/* Prototypes */
++static int aafb_set_var(struct fb_var_screeninfo *var, int con,
++			struct fb_info *info);
++
++/*
++ * Bt455 RAM DAC register base offset (rel. to TC slot base address).
++ */
++#define PMAG_AA_BT455_OFFSET		0x100000
++
++/*
++ * Bt431 cursor generator offset (rel. to TC slot base address).
++ */
++#define PMAG_AA_BT431_OFFSET		0x180000
++
++/*
++ * Begin of PMAG-AA framebuffer memory relative to TC slot address,
++ * resolution is 1280x1024x1 (8 bits deep, but only LSB is used).
++ */
++#define PMAG_AA_ONBOARD_FBMEM_OFFSET	0x200000
++
++struct aafb_cursor {
++	struct timer_list timer;
++	int enable;
++	int on;
++	int vbl_cnt;
++	int blink_rate;
++	u16 x, y, width, height;
++};
++
++#define CURSOR_TIMER_FREQ	(HZ / 50)
++#define CURSOR_BLINK_RATE	(20)
++#define CURSOR_DRAW_DELAY	(2)
++
++struct aafb_info {
++	struct fb_info info;
++	struct display disp;
++	struct aafb_cursor cursor;
++	struct bt455_regs *bt455;
++	struct bt431_regs *bt431;
++	unsigned long fb_start;
++	unsigned long fb_size;
++	unsigned long fb_line_length;
++};
++
++/*
++ * Max 3 TURBOchannel slots -> max 3 PMAG-AA.
++ */
++static struct aafb_info my_fb_info[3];
++
++static struct aafb_par {
++} current_par;
++
++static int currcon = -1;
++
++static void aafb_set_cursor(struct aafb_info *info, int on)
++{
++	struct aafb_cursor *c = &info->cursor;
++
++	if (on) {
++		bt431_position_cursor(info->bt431, c->x, c->y);
++		bt431_enable_cursor(info->bt431);
++	} else
++		bt431_erase_cursor(info->bt431);
++}
++
++static void aafbcon_cursor(struct display *disp, int mode, int x, int y)
++{
++	struct aafb_info *info = (struct aafb_info *)disp->fb_info;
++	struct aafb_cursor *c = &info->cursor;
++
++	x *= fontwidth(disp);
++	y *= fontheight(disp);
++
++	if (c->x == x && c->y == y && (mode == CM_ERASE) == !c->enable)
++		return;
++
++	c->enable = 0;
++	if (c->on)
++		aafb_set_cursor(info, 0);
++	c->x = x - disp->var.xoffset;
++	c->y = y - disp->var.yoffset;
++
++	switch (mode) {
++		case CM_ERASE:
++			c->on = 0;
++			break;
++		case CM_DRAW:
++		case CM_MOVE:
++			if (c->on)
++				aafb_set_cursor(info, c->on);
++			else
++				c->vbl_cnt = CURSOR_DRAW_DELAY;
++			c->enable = 1;
++			break;
++	}
++}
++
++static int aafbcon_set_font(struct display *disp, int width, int height)
++{
++	struct aafb_info *info = (struct aafb_info *)disp->fb_info;
++	struct aafb_cursor *c = &info->cursor;
++	u8 fgc = ~attr_bgcol_ec(disp, disp->conp);
++
++	if (width > 64 || height > 64 || width < 0 || height < 0)
++		return -EINVAL;
++
++	c->height = height;
++	c->width = width;
++
++	bt431_set_font(info->bt431, fgc, width, height);
++
++	return 1;
++}
++
++static void aafb_cursor_timer_handler(unsigned long data)
++{
++	struct aafb_info *info = (struct aafb_info *)data;
++	struct aafb_cursor *c = &info->cursor;
++
++	if (!c->enable)
++		goto out;
++
++	if (c->vbl_cnt && --c->vbl_cnt == 0) {
++		c->on ^= 1;
++		aafb_set_cursor(info, c->on);
++		c->vbl_cnt = c->blink_rate;
++	}
++
++out:
++	c->timer.expires = jiffies + CURSOR_TIMER_FREQ;
++	add_timer(&c->timer);
++}
++
++static void __init aafb_cursor_init(struct aafb_info *info)
++{
++	struct aafb_cursor *c = &info->cursor;
++
++	c->enable = 1;
++	c->on = 1;
++	c->x = c->y = 0;
++	c->width = c->height = 0;
++	c->vbl_cnt = CURSOR_DRAW_DELAY;
++	c->blink_rate = CURSOR_BLINK_RATE;
++
++	init_timer(&c->timer);
++	c->timer.data = (unsigned long)info;
++	c->timer.function = aafb_cursor_timer_handler;
++	mod_timer(&c->timer, jiffies + CURSOR_TIMER_FREQ);
++}
++
++static void __exit aafb_cursor_exit(struct aafb_info *info)
++{
++	struct aafb_cursor *c = &info->cursor;
++
++	del_timer_sync(&c->timer);
++}
++
++static struct display_switch aafb_switch8 = {
++	.setup = fbcon_cfb8_setup,
++	.bmove = fbcon_cfb8_bmove,
++	.clear = fbcon_cfb8_clear,
++	.putc = fbcon_cfb8_putc,
++	.putcs = fbcon_cfb8_putcs,
++	.revc = fbcon_cfb8_revc,
++	.cursor = aafbcon_cursor,
++	.set_font = aafbcon_set_font,
++	.clear_margins = fbcon_cfb8_clear_margins,
++	.fontwidthmask = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
++};
++
++static void aafb_get_par(struct aafb_par *par)
++{
++	*par = current_par;
++}
++
++static int aafb_get_fix(struct fb_fix_screeninfo *fix, int con,
++			struct fb_info *info)
++{
++	struct aafb_info *ip = (struct aafb_info *)info;
++
++	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
++	strcpy(fix->id, "PMAG-AA");
++	fix->smem_start = ip->fb_start;
++	fix->smem_len = ip->fb_size;
++	fix->type = FB_TYPE_PACKED_PIXELS;
++	fix->ypanstep = 1;
++	fix->ywrapstep = 1;
++	fix->visual = FB_VISUAL_MONO10;
++	fix->line_length = 1280;
++	fix->accel = FB_ACCEL_NONE;
++
++	return 0;
++}
++
++static void aafb_set_disp(struct display *disp, int con,
++			  struct aafb_info *info)
++{
++	struct fb_fix_screeninfo fix;
++
++	disp->fb_info = &info->info;
++	aafb_set_var(&disp->var, con, &info->info);
++	if (disp->conp && disp->conp->vc_sw && disp->conp->vc_sw->con_cursor)
++		disp->conp->vc_sw->con_cursor(disp->conp, CM_ERASE);
++	disp->dispsw = &aafb_switch8;
++	disp->dispsw_data = 0;
++
++	aafb_get_fix(&fix, con, &info->info);
++	disp->screen_base = (u8 *) fix.smem_start;
++	disp->visual = fix.visual;
++	disp->type = fix.type;
++	disp->type_aux = fix.type_aux;
++	disp->ypanstep = fix.ypanstep;
++	disp->ywrapstep = fix.ywrapstep;
++	disp->line_length = fix.line_length;
++	disp->next_line = 2048;
++	disp->can_soft_blank = 1;
++	disp->inverse = 0;
++	disp->scrollmode = SCROLL_YREDRAW;
++
++	aafbcon_set_font(disp, fontwidth(disp), fontheight(disp));
++}
++
++static int aafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
++			 struct fb_info *info)
++{
++	static u16 color[2] = {0x0000, 0x000f};
++	static struct fb_cmap aafb_cmap = {0, 2, color, color, color, NULL};
++
++	fb_copy_cmap(&aafb_cmap, cmap, kspc ? 0 : 2);
++	return 0;
++}
++
++static int aafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
++			 struct fb_info *info)
++{
++	u16 color[2] = {0x0000, 0x000f};
++
++	if (cmap->start == 0
++	    && cmap->len == 2
++	    && memcmp(cmap->red, color, sizeof(color)) == 0
++	    && memcmp(cmap->green, color, sizeof(color)) == 0
++	    && memcmp(cmap->blue, color, sizeof(color)) == 0
++	    && cmap->transp == NULL)
++		return 0;
++	else
++		return -EINVAL;
++}
++
++static int aafb_ioctl(struct inode *inode, struct file *file, u32 cmd,
++		      unsigned long arg, int con, struct fb_info *info)
++{
++	/* TODO: Not yet implemented */
++	return -ENOIOCTLCMD;
++}
++
++static int aafb_switch(int con, struct fb_info *info)
++{
++	struct aafb_info *ip = (struct aafb_info *)info;
++	struct display *old = (currcon < 0) ? &ip->disp : (fb_display + currcon);
++	struct display *new = (con < 0) ? &ip->disp : (fb_display + con);
++
++	if (old->conp && old->conp->vc_sw && old->conp->vc_sw->con_cursor)
++		old->conp->vc_sw->con_cursor(old->conp, CM_ERASE);
++
++	/* Set the current console. */
++	currcon = con;
++	aafb_set_disp(new, con, ip);
++
++	return 0;
++}
++
++static void aafb_encode_var(struct fb_var_screeninfo *var,
++			    struct aafb_par *par)
++{
++	var->xres = 1280;
++	var->yres = 1024;
++	var->xres_virtual = 2048;
++	var->yres_virtual = 1024;
++	var->xoffset = 0;
++	var->yoffset = 0;
++	var->bits_per_pixel = 8;
++	var->grayscale = 1;
++	var->red.offset = 0;
++	var->red.length = 0;
++	var->red.msb_right = 0;
++	var->green.offset = 0;
++	var->green.length = 1;
++	var->green.msb_right = 0;
++	var->blue.offset = 0;
++	var->blue.length = 0;
++	var->blue.msb_right = 0;
++	var->transp.offset = 0;
++	var->transp.length = 0;
++	var->transp.msb_right = 0;
++	var->nonstd = 0;
++	var->activate &= ~FB_ACTIVATE_MASK & FB_ACTIVATE_NOW;
++	var->accel_flags = 0;
++	var->sync = FB_SYNC_ON_GREEN;
++	var->vmode &= ~FB_VMODE_MASK & FB_VMODE_NONINTERLACED;
++}
++
++static int aafb_get_var(struct fb_var_screeninfo *var, int con,
++			struct fb_info *info)
++{
++	if (con < 0) {
++		struct aafb_par par;
++
++		memset(var, 0, sizeof(struct fb_var_screeninfo));
++		aafb_get_par(&par);
++		aafb_encode_var(var, &par);
++	} else
++		*var = info->var;
++
++	return 0;
++}
++
++static int aafb_set_var(struct fb_var_screeninfo *var, int con,
++			struct fb_info *info)
++{
++	struct aafb_par par;
++
++	aafb_get_par(&par);
++	aafb_encode_var(var, &par);
++	info->var = *var;
++
++	return 0;
++}
++
++static int aafb_update_var(int con, struct fb_info *info)
++{
++	struct aafb_info *ip = (struct aafb_info *)info;
++	struct display *disp = (con < 0) ? &ip->disp : (fb_display + con);
++
++	if (con == currcon)
++		aafbcon_cursor(disp, CM_ERASE, ip->cursor.x, ip->cursor.y);
++
++	return 0;
++}
++
++/* 0 unblanks, any other blanks. */
++
++static void aafb_blank(int blank, struct fb_info *info)
++{
++	struct aafb_info *ip = (struct aafb_info *)info;
++	u8 val = blank ? 0x00 : 0x0f;
++
++	bt455_write_cmap_entry(ip->bt455, 1, val, val, val);
++	aafbcon_cursor(&ip->disp, CM_ERASE, ip->cursor.x, ip->cursor.y);
++}
++
++static struct fb_ops aafb_ops = {
++	.owner = THIS_MODULE,
++	.fb_get_fix = aafb_get_fix,
++	.fb_get_var = aafb_get_var,
++	.fb_set_var = aafb_set_var,
++	.fb_get_cmap = aafb_get_cmap,
++	.fb_set_cmap = aafb_set_cmap,
++	.fb_ioctl = aafb_ioctl
++};
++
++static int __init init_one(int slot)
++{
++	unsigned long base_addr = get_tc_base_addr(slot);
++	struct aafb_info *ip = &my_fb_info[slot];
++
++	memset(ip, 0, sizeof(struct aafb_info));
++
++	/*
++	 * Framebuffer display memory base address and friends.
++	 */
++	ip->bt455 = (struct bt455_regs *) (base_addr + PMAG_AA_BT455_OFFSET);
++	ip->bt431 = (struct bt431_regs *) (base_addr + PMAG_AA_BT431_OFFSET);
++	ip->fb_start = base_addr + PMAG_AA_ONBOARD_FBMEM_OFFSET;
++	ip->fb_size = 2048 * 1024; /* fb_fix_screeninfo.smem_length
++				      seems to be physical */
++	ip->fb_line_length = 2048;
++
++	/*
++	 * Let there be consoles..
++	 */
++	strcpy(ip->info.modename, "PMAG-AA");
++	ip->info.node = -1;
++	ip->info.flags = FBINFO_FLAG_DEFAULT;
++	ip->info.fbops = &aafb_ops;
++	ip->info.disp = &ip->disp;
++	ip->info.changevar = NULL;
++	ip->info.switch_con = &aafb_switch;
++	ip->info.updatevar = &aafb_update_var;
++	ip->info.blank = &aafb_blank;
++
++	aafb_set_disp(&ip->disp, currcon, ip);
++
++	/*
++	 * Configure the RAM DACs.
++	 */
++	bt455_erase_cursor(ip->bt455);
++
++	/* Init colormap. */
++	bt455_write_cmap_entry(ip->bt455, 0, 0x00, 0x00, 0x00);
++	bt455_write_cmap_entry(ip->bt455, 1, 0x0f, 0x0f, 0x0f);
++
++	/* Init hardware cursor. */
++	bt431_init_cursor(ip->bt431);
++	aafb_cursor_init(ip);
++
++	/* Clear the screen. */
++	memset ((void *)ip->fb_start, 0, ip->fb_size);
++
++	if (register_framebuffer(&ip->info) < 0)
++		return -EINVAL;
++
++	printk(KERN_INFO "fb%d: %s frame buffer in TC slot %d\n",
++	       GET_FB_IDX(ip->info.node), ip->info.modename, slot);
++
++	return 0;
++}
++
++static int __exit exit_one(int slot)
++{
++	struct aafb_info *ip = &my_fb_info[slot];
++
++	if (unregister_framebuffer(&ip->info) < 0)
++		return -EINVAL;
++
++	return 0;
++}
++
++/* 
++ * Initialise the framebuffer.
++ */
++int __init pmagaafb_init(void)
++{
++	int sid;
++	int found = 0;
++
++	while ((sid = search_tc_card("PMAG-AA")) >= 0) {
++		found = 1;
++		claim_tc_card(sid);
++		init_one(sid);
++	}
++
++	return found ? 0 : -ENXIO;
++}
++
++static void __exit pmagaafb_exit(void)
++{
++	int sid;
++
++	while ((sid = search_tc_card("PMAG-AA")) >= 0) {
++		exit_one(sid);
++		release_tc_card(sid);
++	}
++}
++
++MODULE_AUTHOR(DRIVER_AUTHOR);
++MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
++MODULE_LICENSE("GPL");
++#ifdef MODULE
++module_init(pmagaafb_init);
++module_exit(pmagaafb_exit);
++#endif
+diff -urpNX dontdiff linux-2.6.10/drivers/video/pmag-ba-fb.c linux-2.6.10-mips/drivers/video/pmag-ba-fb.c
+--- linux-2.6.10/drivers/video/pmag-ba-fb.c	2004-12-24 22:35:39.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/pmag-ba-fb.c	2004-10-12 19:31:18.000000000 +0200
+@@ -52,27 +52,27 @@ struct pmag_ba_ramdac_regs {
+ static struct fb_info pmagba_fb_info[3];
+ 
+ static struct fb_var_screeninfo pmagbafb_defined = {
+-	.xres 		= 1024,
++	.xres		= 1024,
+ 	.yres		= 864,
+-	.xres_virtual 	= 1024,
+-	.yres_virtual 	= 864,
+-	.bits_per_pixel = 8,
++	.xres_virtual	= 1024,
++	.yres_virtual	= 864,
++	.bits_per_pixel	= 8,
+ 	.red.length	= 8,
+ 	.green.length	= 8,
+ 	.blue.length	= 8,
+-	.activate 	= FB_ACTIVATE_NOW, 
+-	.height 	= 274,	
+-	.width 		= 195,
+-	.accel 		= FB_ACCEL_NONE,
+-	.vmode 		= FB_VMODE_NONINTERLACED,
++	.activate	= FB_ACTIVATE_NOW,
++	.height		= 274,
++	.width		= 195,
++	.accel		= FB_ACCEL_NONE,
++	.vmode		= FB_VMODE_NONINTERLACED,
+ };
+-
++                                                                                
+ static struct fb_fix_screeninfo pmagbafb_fix = {
+-	.id 		= "PMAG-BA",
+-	.smem_len 	= (1024 * 864),
+-	.type 		= FB_TYPE_PACKED_PIXELS,
+-	.visual 	= FB_VISUAL_PSEUDOCOLOR,
+-	.line_length 	= 1024,
++	.id		= "PMAG-BA",
++	.smem_len	= (1024 * 864),
++	.type		= FB_TYPE_PACKED_PIXELS,
++	.visual		= FB_VISUAL_PSEUDOCOLOR,
++	.line_length	= 1024,
+ };
+ 
+ /*
+@@ -89,10 +89,10 @@ void pmagbafb_erase_cursor(struct pmag_b
+  * Set the palette. 
+  */
+ static int pmagbafb_setcolreg(unsigned regno, unsigned red, unsigned green,
+-                              unsigned blue, unsigned transp,
+-                              struct fb_info *info)
++			      unsigned blue, unsigned transp,
++			      struct fb_info *info)
+ {
+-	struct pmag_ba_ramdac_regs *bt459_regs = (struct pmag_ba_ramdac_regs *) info->par; 
++	struct pmag_ba_ramdac_regs *bt459_regs = (struct pmag_ba_ramdac_regs *) info->par;
+ 
+ 	if (regno >= info->cmap.len)
+ 		return 1;
+@@ -111,6 +111,8 @@ static int pmagbafb_setcolreg(unsigned r
+ 
+ static struct fb_ops pmagbafb_ops = {
+ 	.owner		= THIS_MODULE,
++	.fb_get_fix	= gen_get_fix,
++	.fb_get_var	= gen_get_var,
+ 	.fb_setcolreg	= pmagbafb_setcolreg,
+ 	.fb_fillrect	= cfb_fillrect,
+ 	.fb_copyarea	= cfb_copyarea,
+@@ -122,6 +124,7 @@ int __init pmagbafb_init_one(int slot)
+ {
+ 	unsigned long base_addr = get_tc_base_addr(slot);
+ 	struct fb_info *info = &pmagba_fb_info[slot]; 
++	struct display *disp = &pmagba_disp[slot];
+ 
+ 	printk("PMAG-BA framebuffer in slot %d\n", slot);
+ 	/*
+@@ -145,7 +148,7 @@ int __init pmagbafb_init_one(int slot)
+ 	info->flags = FBINFO_DEFAULT;
+ 
+ 	fb_alloc_cmap(&fb_info.cmap, 256, 0);
+-	
++
+ 	if (register_framebuffer(info) < 0)
+ 		return 1;
+ 	return 0;
+diff -urpNX dontdiff linux-2.6.10/drivers/video/pmagb-b-fb.c linux-2.6.10-mips/drivers/video/pmagb-b-fb.c
+--- linux-2.6.10/drivers/video/pmagb-b-fb.c	2004-12-24 22:34:58.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/pmagb-b-fb.c	2004-10-12 19:31:18.000000000 +0200
+@@ -55,27 +55,27 @@ struct pmagb_b_ramdac_regs {
+ static struct fb_info pmagbb_fb_info[3];
+ 
+ static struct fb_var_screeninfo pmagbbfb_defined = {
+-	.xres 		= 1280,
+-	.yres 		= 1024,
+-	.xres_virtual 	= 1280,
+-	.yres_virtual 	= 1024,
+-	.bits_per_pixel = 8,
++	.xres		= 1280,
++	.yres		= 1024,
++	.xres_virtual	= 1280,
++	.yres_virtual	= 1024,
++	.bits_per_pixel	= 8,
+ 	.red.length	= 8,
+ 	.green.length	= 8,
+ 	.blue.length	= 8,
+-	.activate 	= FB_ACTIVATE_NOW,
+-	.height 	= 274,
+-	.width 		= 195,
+-	.accel_flags 	= FB_ACCEL_NONE,
+-	.vmode 		= FB_VMODE_NONINTERLACED,
++	.activate	= FB_ACTIVATE_NOW,
++	.height		= 274,
++	.width		= 195,
++	.accel_flags	= FB_ACCEL_NONE,
++	.vmode		= FB_VMODE_NONINTERLACED,
+ };
+ 
+ static struct fb_fix_screeninfo pmagbafb_fix = {
+-	.id 		= "PMAGB-BA",
+-	.smem_len 	= (1280 * 1024),
+-	.type 		= FB_TYPE_PACKED_PIXELS,
+-	.visual 	= FB_VISUAL_PSEUDOCOLOR,
+-	.line_length 	= 1280,
++	.id		= "PMAGB-BA",
++	.smem_len	= (1280 * 1024),
++	.type		= FB_TYPE_PACKED_PIXELS,
++	.visual		= FB_VISUAL_PSEUDOCOLOR,
++	.line_length	= 1280,
+ }
+ 
+ /*
+diff -urpNX dontdiff linux-2.6.10/drivers/video/tx3912fb.c linux-2.6.10-mips/drivers/video/tx3912fb.c
+--- linux-2.6.10/drivers/video/tx3912fb.c	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/tx3912fb.c	2004-10-12 19:31:18.000000000 +0200
+@@ -10,7 +10,6 @@
+  *
+  *  Framebuffer for LCD controller in TMPR3912/05 and PR31700 processors
+  */
+-#include <linux/config.h>
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
+@@ -35,11 +34,7 @@ static u32 cfb8[16];
+ 
+ static struct fb_fix_screeninfo tx3912fb_fix __initdata = {
+ 	.id =		"tx3912fb",
+-#ifdef CONFIG_NINO_16MB
+-	.smem_len =	(240 * 320),
+-#else
+ 	.smem_len =	((240 * 320)/2),
+-#endif
+ 	.type =		FB_TYPE_PACKED_PIXELS,
+ 	.visual =	FB_VISUAL_TRUECOLOR, 
+ 	.xpanstep =	1,
+@@ -53,17 +48,10 @@ static struct fb_var_screeninfo tx3912fb
+ 	.yres =		320,
+ 	.xres_virtual =	240,
+ 	.yres_virtual =	320,
+-#ifdef CONFIG_NINO_16MB
+-	.bits_per_pixel =8,
+-	.red =		{ 5, 3, 0 },	/* RGB 332 */
+-	.green =	{ 2, 3, 0 },
+-	.blue =		{ 0, 2, 0 },
+-#else
+ 	.bits_per_pixel =4,
+ 	.red =		{ 0, 4, 0 },	/* ??? */
+ 	.green =	{ 0, 4, 0 },
+ 	.blue =		{ 0, 4, 0 },
+-#endif
+ 	.activate =	FB_ACTIVATE_NOW,
+ 	.width =	-1,
+ 	.height =	-1,
+diff -urpNX dontdiff linux-2.6.10/drivers/video/tx3912fb.h linux-2.6.10-mips/drivers/video/tx3912fb.h
+--- linux-2.6.10/drivers/video/tx3912fb.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/drivers/video/tx3912fb.h	2003-06-27 10:36:30.000000000 +0200
+@@ -0,0 +1,65 @@
++/*
++ *  drivers/video/tx3912fb.h
++ *
++ *  Copyright (C) 2001 Steven Hill (sjhill at realitydiluted.com)
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License. See the file COPYING in the main directory of this archive for
++ * more details.
++ *
++ *  Includes for TMPR3912/05 and PR31700 LCD controller registers
++ */
++#include <linux/config.h>
++
++/*
++ * Begin platform specific configurations
++ */
++#if defined(CONFIG_FBCON_CFB4)
++#define FB_BPP         4
++#else
++#if defined(CONFIG_FBCON_CFB2)
++#define FB_BPP         2
++#else
++#define FB_BPP         1
++#endif
++#endif
++#define FB_IS_GREY     1
++#define FB_IS_INVERSE  0
++
++/*
++ * Define virtual resolutions if necessary
++ */
++#ifndef FB_X_VIRTUAL_RES
++#define FB_X_VIRTUAL_RES FB_X_RES
++#endif
++#ifndef FB_Y_VIRTUAL_RES
++#define FB_Y_VIRTUAL_RES FB_Y_RES
++#endif
++
++/*
++ * Framebuffer address and size
++ */
++u_long tx3912fb_paddr = 0;
++u_long tx3912fb_vaddr = 0;
++u_long tx3912fb_size = (FB_X_RES * FB_Y_RES * FB_BPP / 8);
++
++/*
++ * Framebuffer info structure
++ */
++static struct fb_var_screeninfo tx3912fb_info = {
++	FB_X_RES, FB_Y_RES,
++	FB_X_VIRTUAL_RES, FB_Y_VIRTUAL_RES,
++	0, 0,
++	FB_BPP, FB_IS_GREY,
++	{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
++	0, FB_ACTIVATE_NOW,
++	-1, -1, 0, 20000,
++	64, 64, 32, 32, 64, 2,
++	0, FB_VMODE_NONINTERLACED,
++	{0,0,0,0,0,0}
++};
++
++/*
++ * Framebuffer name
++ */
++static char TX3912FB_NAME[16] = "tx3912fb";
+diff -urpNX dontdiff linux-2.6.10/fs/binfmt_elf.c linux-2.6.10-mips/fs/binfmt_elf.c
+--- linux-2.6.10/fs/binfmt_elf.c	2004-12-24 22:34:33.000000000 +0100
++++ linux-2.6.10-mips/fs/binfmt_elf.c	2004-12-04 20:57:37.000000000 +0100
+@@ -1154,7 +1154,11 @@ static inline void fill_elf_header(struc
+ 	elf->e_entry = 0;
+ 	elf->e_phoff = sizeof(struct elfhdr);
+ 	elf->e_shoff = 0;
++#ifdef ELF_CORE_EFLAGS
++	elf->e_flags = ELF_CORE_EFLAGS;
++#else
+ 	elf->e_flags = 0;
++#endif
+ 	elf->e_ehsize = sizeof(struct elfhdr);
+ 	elf->e_phentsize = sizeof(struct elf_phdr);
+ 	elf->e_phnum = segs;
+diff -urpNX dontdiff linux-2.6.10/fs/partitions/Kconfig linux-2.6.10-mips/fs/partitions/Kconfig
+--- linux-2.6.10/fs/partitions/Kconfig	2004-12-24 22:35:27.000000000 +0100
++++ linux-2.6.10-mips/fs/partitions/Kconfig	2004-11-19 01:14:58.000000000 +0100
+@@ -188,14 +188,14 @@ config LDM_DEBUG
+ 
+ config SGI_PARTITION
+ 	bool "SGI partition support" if PARTITION_ADVANCED
+-	default y if (SGI_IP22 || SGI_IP27)
++	default y if (SGI_IP22 || SGI_IP27 || ((MACH_JAZZ || SNI_RM200_PCI) && !CPU_LITTLE_ENDIAN))
+ 	help
+ 	  Say Y here if you would like to be able to read the hard disk
+ 	  partition table format used by SGI machines.
+ 
+ config ULTRIX_PARTITION
+ 	bool "Ultrix partition table support" if PARTITION_ADVANCED
+-	default y if DECSTATION
++	default y if MACH_DECSTATION
+ 	help
+ 	  Say Y here if you would like to be able to read the hard disk
+ 	  partition table format used by DEC (now Compaq) Ultrix machines.
+diff -urpNX dontdiff linux-2.6.10/fs/partitions/check.c linux-2.6.10-mips/fs/partitions/check.c
+--- linux-2.6.10/fs/partitions/check.c	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/fs/partitions/check.c	2004-12-28 20:06:56.000000000 +0100
+@@ -73,6 +73,9 @@ static int (*check_part[])(struct parsed
+ #ifdef CONFIG_EFI_PARTITION
+ 	efi_partition,		/* this must come before msdos */
+ #endif
++#ifdef CONFIG_SGI_PARTITION
++	sgi_partition,
++#endif
+ #ifdef CONFIG_LDM_PARTITION
+ 	ldm_partition,		/* this must come before msdos */
+ #endif
+@@ -97,9 +100,6 @@ static int (*check_part[])(struct parsed
+ #ifdef CONFIG_MAC_PARTITION
+ 	mac_partition,
+ #endif
+-#ifdef CONFIG_SGI_PARTITION
+-	sgi_partition,
+-#endif
+ #ifdef CONFIG_ULTRIX_PARTITION
+ 	ultrix_partition,
+ #endif
+diff -urpNX dontdiff linux-2.6.10/fs/partitions/sgi.c linux-2.6.10-mips/fs/partitions/sgi.c
+--- linux-2.6.10/fs/partitions/sgi.c	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/fs/partitions/sgi.c	2004-10-12 19:31:25.000000000 +0200
+@@ -69,8 +69,12 @@ int sgi_partition(struct parsed_partitio
+ 	for(i = 0; i < 16; i++, p++) {
+ 		blocks = be32_to_cpu(p->num_blocks);
+ 		start  = be32_to_cpu(p->first_block);
+-		if (blocks)
+-			put_partition(state, slot++, start, blocks);
++		if (blocks) {
++			put_partition(state, slot, start, blocks);
++			if (be32_to_cpu(p->type) == LINUX_RAID_PARTITION)
++				state->parts[slot].flags = 1;
++		}
++		slot++;
+ 	}
+ 	printk("\n");
+ 	put_dev_sector(sect);
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/addrspace.h linux-2.6.10-mips/include/asm-mips/addrspace.h
+--- linux-2.6.10/include/asm-mips/addrspace.h	2004-12-24 22:33:49.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/addrspace.h	2004-12-28 20:07:02.000000000 +0100
+@@ -126,6 +126,7 @@
+     || defined (CONFIG_CPU_R4X00)					\
+     || defined (CONFIG_CPU_R5000)					\
+     || defined (CONFIG_CPU_NEVADA)					\
++    || defined (CONFIG_CPU_TX49XX)					\
+     || defined (CONFIG_CPU_MIPS64)
+ #define	KUSIZE			0x0000010000000000	/* 2^^40 */
+ #define	KUSIZE_64		0x0000010000000000	/* 2^^40 */
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/bitops.h linux-2.6.10-mips/include/asm-mips/bitops.h
+--- linux-2.6.10/include/asm-mips/bitops.h	2004-12-24 22:33:51.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/bitops.h	2005-01-09 13:24:02.000000000 +0100
+@@ -92,7 +92,7 @@ static inline void set_bit(unsigned long
+ 		__bi_flags;
+ 
+ 		a += nr >> SZLONG_LOG;
+-		mask = 1 << (nr & SZLONG_MASK);
++		mask = 1UL << (nr & SZLONG_MASK);
+ 		__bi_local_irq_save(flags);
+ 		*a |= mask;
+ 		__bi_local_irq_restore(flags);
+@@ -152,7 +152,7 @@ static inline void clear_bit(unsigned lo
+ 		__bi_flags;
+ 
+ 		a += nr >> SZLONG_LOG;
+-		mask = 1 << (nr & SZLONG_MASK);
++		mask = 1UL << (nr & SZLONG_MASK);
+ 		__bi_local_irq_save(flags);
+ 		*a &= ~mask;
+ 		__bi_local_irq_restore(flags);
+@@ -214,7 +214,7 @@ static inline void change_bit(unsigned l
+ 		__bi_flags;
+ 
+ 		a += nr >> SZLONG_LOG;
+-		mask = 1 << (nr & SZLONG_MASK);
++		mask = 1UL << (nr & SZLONG_MASK);
+ 		__bi_local_irq_save(flags);
+ 		*a ^= mask;
+ 		__bi_local_irq_restore(flags);
+@@ -293,7 +293,7 @@ static inline int test_and_set_bit(unsig
+ 		__bi_flags;
+ 
+ 		a += nr >> SZLONG_LOG;
+-		mask = 1 << (nr & SZLONG_MASK);
++		mask = 1UL << (nr & SZLONG_MASK);
+ 		__bi_local_irq_save(flags);
+ 		retval = (mask & *a) != 0;
+ 		*a |= mask;
+@@ -320,7 +320,7 @@ static inline int __test_and_set_bit(uns
+ 	int retval;
+ 
+ 	a += nr >> SZLONG_LOG;
+-	mask = 1 << (nr & SZLONG_MASK);
++	mask = 1UL << (nr & SZLONG_MASK);
+ 	retval = (mask & *a) != 0;
+ 	*a |= mask;
+ 
+@@ -385,7 +385,7 @@ static inline int test_and_clear_bit(uns
+ 		__bi_flags;
+ 
+ 		a += nr >> SZLONG_LOG;
+-		mask = 1 << (nr & SZLONG_MASK);
++		mask = 1UL << (nr & SZLONG_MASK);
+ 		__bi_local_irq_save(flags);
+ 		retval = (mask & *a) != 0;
+ 		*a &= ~mask;
+@@ -474,7 +474,7 @@ static inline int test_and_change_bit(un
+ 		__bi_flags;
+ 
+ 		a += nr >> SZLONG_LOG;
+-		mask = 1 << (nr & SZLONG_MASK);
++		mask = 1UL << (nr & SZLONG_MASK);
+ 		__bi_local_irq_save(flags);
+ 		retval = (mask & *a) != 0;
+ 		*a ^= mask;
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/bootinfo.h linux-2.6.10-mips/include/asm-mips/bootinfo.h
+--- linux-2.6.10/include/asm-mips/bootinfo.h	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/bootinfo.h	2004-12-17 10:36:03.000000000 +0100
+@@ -195,6 +195,7 @@
+ #define  MACH_CASIO_E55		5	/* CASIO CASSIOPEIA E-10/15/55/65 */
+ #define  MACH_TANBAC_TB0226	6	/* TANBAC TB0226 (Mbase) */
+ #define  MACH_TANBAC_TB0229	7	/* TANBAC TB0229 (VR4131DIMM) */
++#define  MACH_NEC_CMBVR4133	8	/* CMB VR4133 Board */
+ 
+ #define MACH_GROUP_HP_LJ	20	/* Hewlett Packard LaserJet	*/
+ #define  MACH_HP_LASERJET	1
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/break.h linux-2.6.10-mips/include/asm-mips/break.h
+--- linux-2.6.10/include/asm-mips/break.h	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/break.h	2004-12-28 20:07:02.000000000 +0100
+@@ -27,7 +27,7 @@
+ #define BRK_STACKOVERFLOW 9	/* For Ada stackchecking */
+ #define BRK_NORLD	10	/* No rld found - not used by Linux/MIPS */
+ #define _BRK_THREADBP	11	/* For threads, user bp (used by debuggers) */
+-#define BRK_MULOVF	1023	/* Multiply overflow */
+ #define BRK_BUG		512	/* Used by BUG() */
++#define BRK_MULOVF	1023	/* Multiply overflow */
+ 
+ #endif /* __ASM_BREAK_H */
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/cpu-features.h linux-2.6.10-mips/include/asm-mips/cpu-features.h
+--- linux-2.6.10/include/asm-mips/cpu-features.h	2004-12-24 22:35:25.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/cpu-features.h	2004-12-17 10:36:03.000000000 +0100
+@@ -3,11 +3,13 @@
+  * License.  See the file "COPYING" in the main directory of this archive
+  * for more details.
+  *
+- * Copyright (C) 2003 Ralf Baechle
++ * Copyright (C) 2003, 2004 Ralf Baechle
+  */
+ #ifndef __ASM_CPU_FEATURES_H
+ #define __ASM_CPU_FEATURES_H
+ 
++#include <linux/config.h>
++
+ #include <asm/cpu.h>
+ #include <asm/cpu-info.h>
+ #include <cpu-feature-overrides.h>
+@@ -75,6 +77,25 @@
+ #endif
+ 
+ /*
++ * I-Cache snoops remote store.  This only matters on SMP.  Some multiprocessors
++ * such as the R10000 have I-Caches that snoop local stores; the embedded ones
++ * don't.  For maintaining I-cache coherency this means we need to flush the
++ * D-cache all the way back to whever the I-cache does refills from, so the
++ * I-cache has a chance to see the new data at all.  Then we have to flush the
++ * I-cache also.
++ * Note we may have been rescheduled and may no longer be running on the CPU
++ * that did the store so we can't optimize this into only doing the flush on
++ * the local CPU.
++ */
++#ifndef cpu_icache_snoops_remote_store
++#ifdef CONFIG_SMP
++#define cpu_icache_snoops_remote_store	(cpu_data[0].icache.flags & MIPS_IC_SNOOPS_REMOTE)
++#else
++#define cpu_icache_snoops_remote_store	1
++#endif
++#endif
++
++/*
+  * Certain CPUs may throw bizarre exceptions if not the whole cacheline
+  * contains valid instructions.  For these we ensure proper alignment of
+  * signal trampolines and pad them to the size of a full cache lines with
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/cpu-info.h linux-2.6.10-mips/include/asm-mips/cpu-info.h
+--- linux-2.6.10/include/asm-mips/cpu-info.h	2004-12-24 22:34:44.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/cpu-info.h	2004-12-17 10:36:03.000000000 +0100
+@@ -37,6 +37,7 @@ struct cache_desc {
+ #define MIPS_CACHE_VTAG		0x00000002	/* Virtually tagged cache */
+ #define MIPS_CACHE_ALIASES	0x00000004	/* Cache could have aliases */
+ #define MIPS_CACHE_IC_F_DC	0x00000008	/* Ic can refill from D-cache */
++#define MIPS_IC_SNOOPS_REMOTE	0x00000010	/* Ic snoops remote stores */
+ 
+ struct cpuinfo_mips {
+ 	unsigned long		udelay_val;
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/elf.h linux-2.6.10-mips/include/asm-mips/elf.h
+--- linux-2.6.10/include/asm-mips/elf.h	2004-12-24 22:34:32.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/elf.h	2005-01-06 16:00:08.000000000 +0100
+@@ -23,7 +23,8 @@
+ #define EF_MIPS_ABI_O64		0x00002000	/* O32 extended for 64 bit.  */
+ 
+ #define PT_MIPS_REGINFO		0x70000000
+-#define PT_MIPS_OPTIONS		0x70000001
++#define PT_MIPS_RTPROC		0x70000001
++#define PT_MIPS_OPTIONS		0x70000002
+ 
+ /* Flags in the e_flags field of the header */
+ #define EF_MIPS_NOREORDER	0x00000001
+@@ -40,9 +41,10 @@
+ #define DT_MIPS_ICHECKSUM	0x70000003
+ #define DT_MIPS_IVERSION	0x70000004
+ #define DT_MIPS_FLAGS		0x70000005
+-  #define RHF_NONE		  0
+-  #define RHF_HARDWAY		  1
+-  #define RHF_NOTPOT		  2
++	#define RHF_NONE	0x00000000
++	#define RHF_HARDWAY	0x00000001
++	#define RHF_NOTPOT	0x00000002
++	#define RHF_SGI_ONLY	0x00000010
+ #define DT_MIPS_BASE_ADDRESS	0x70000006
+ #define DT_MIPS_CONFLICT	0x70000008
+ #define DT_MIPS_LIBLIST		0x70000009
+@@ -225,7 +227,7 @@ do {	current->thread.mflags &= ~MF_ABI_M
+ #endif /* __KERNEL__ */
+ 
+ /* This one accepts IRIX binaries.  */
+-#define irix_elf_check_arch(hdr)	((hdr)->e_machine == EM_MIPS)
++#define irix_elf_check_arch(hdr)	((hdr)->e_flags & RHF_SGI_ONLY)
+ 
+ #define USE_ELF_CORE_DUMP
+ #define ELF_EXEC_PAGESIZE	PAGE_SIZE
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/gt64120.h linux-2.6.10-mips/include/asm-mips/gt64120.h
+--- linux-2.6.10/include/asm-mips/gt64120.h	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/gt64120.h	2004-12-17 10:36:03.000000000 +0100
+@@ -1,6 +1,7 @@
+ /*
+- * Carsten Langgaard, carstenl at mips.com
+- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
++ * Copyright (C) 2000, 2004  MIPS Technologies, Inc.  All rights reserved.
++ *	Authors: Carsten Langgaard <carstenl at mips.com>
++ *		 Maciej W. Rozycki <macro at mips.com>
+  *
+  *  This program is free software; you can distribute it and/or modify it
+  *  under the terms of the GNU General Public License (Version 2) as
+@@ -22,16 +23,17 @@
+ #include <asm/addrspace.h>
+ #include <asm/byteorder.h>
+ 
+-#define MSK(n)                    ((1 << (n)) - 1)
++#define MSK(n)			((1 << (n)) - 1)
+ 
+ /*
+  *  Register offset addresses
+  */
++/* CPU Configuration.  */
+ #define GT_CPU_OFS		0x000
+ 
+-/*
+- * Interrupt Registers
+- */
++#define GT_MULTI_OFS		0x120
++
++/* CPU Address Decode.  */
+ #define GT_SCS10LD_OFS		0x008
+ #define GT_SCS10HD_OFS		0x010
+ #define GT_SCS32LD_OFS		0x018
+@@ -45,6 +47,7 @@
+ #define GT_PCI0M0LD_OFS		0x058
+ #define GT_PCI0M0HD_OFS		0x060
+ #define GT_ISD_OFS		0x068
++
+ #define GT_PCI0M1LD_OFS		0x080
+ #define GT_PCI0M1HD_OFS		0x088
+ #define GT_PCI1IOLD_OFS		0x090
+@@ -53,10 +56,14 @@
+ #define GT_PCI1M0HD_OFS		0x0a8
+ #define GT_PCI1M1LD_OFS		0x0b0
+ #define GT_PCI1M1HD_OFS		0x0b8
++#define GT_PCI1M1LD_OFS		0x0b0
++#define GT_PCI1M1HD_OFS		0x0b8
++
++#define GT_SCS10AR_OFS		0x0d0
++#define GT_SCS32AR_OFS		0x0d8
++#define GT_CS20R_OFS		0x0e0
++#define GT_CS3BOOTR_OFS		0x0e8
+ 
+-/*
+- * GT64120A only
+- */
+ #define GT_PCI0IOREMAP_OFS	0x0f0
+ #define GT_PCI0M0REMAP_OFS	0x0f8
+ #define GT_PCI0M1REMAP_OFS	0x100
+@@ -64,6 +71,19 @@
+ #define GT_PCI1M0REMAP_OFS	0x110
+ #define GT_PCI1M1REMAP_OFS	0x118
+ 
++/* CPU Error Report.  */
++#define GT_CPUERR_ADDRLO_OFS	0x070
++#define GT_CPUERR_ADDRHI_OFS	0x078
++
++#define GT_CPUERR_DATALO_OFS	0x128			/* GT-64120A only  */
++#define GT_CPUERR_DATAHI_OFS	0x130			/* GT-64120A only  */
++#define GT_CPUERR_PARITY_OFS	0x138			/* GT-64120A only  */
++
++/* CPU Sync Barrier.  */
++#define GT_PCI0SYNC_OFS		0x0c0
++#define GT_PCI1SYNC_OFS		0x0c8
++
++/* SDRAM and Device Address Decode.  */
+ #define GT_SCS0LD_OFS		0x400
+ #define GT_SCS0HD_OFS		0x404
+ #define GT_SCS1LD_OFS		0x408
+@@ -83,37 +103,138 @@
+ #define GT_BOOTLD_OFS		0x440
+ #define GT_BOOTHD_OFS		0x444
+ 
+-#define GT_SDRAM_B0_OFS	    	0x44c
++#define GT_ADERR_OFS		0x470
++
++/* SDRAM Configuration.  */
+ #define GT_SDRAM_CFG_OFS	0x448
+-#define GT_SDRAM_B2_OFS		0x454
++
+ #define GT_SDRAM_OPMODE_OFS	0x474
+ #define GT_SDRAM_BM_OFS		0x478
+ #define GT_SDRAM_ADDRDECODE_OFS	0x47c
+ 
+-#define GT_PCI0_CMD_OFS		0xc00	/* GT64120A only */
++/* SDRAM Parameters.  */
++#define GT_SDRAM_B0_OFS		0x44c
++#define GT_SDRAM_B1_OFS		0x450
++#define GT_SDRAM_B2_OFS		0x454
++#define GT_SDRAM_B3_OFS		0x458
++
++/* Device Parameters.  */
++#define GT_DEV_B0_OFS		0x45c
++#define GT_DEV_B1_OFS		0x460
++#define GT_DEV_B2_OFS		0x464
++#define GT_DEV_B3_OFS		0x468
++#define GT_DEV_BOOT_OFS		0x46c
++
++/* ECC.  */
++#define GT_ECC_ERRDATALO	0x480			/* GT-64120A only  */
++#define GT_ECC_ERRDATAHI	0x484			/* GT-64120A only  */
++#define GT_ECC_MEM		0x488			/* GT-64120A only  */
++#define GT_ECC_CALC		0x48c			/* GT-64120A only  */
++#define GT_ECC_ERRADDR		0x490			/* GT-64120A only  */
++
++/* DMA Record.  */
++#define GT_DMA0_CNT_OFS		0x800
++#define GT_DMA1_CNT_OFS		0x804
++#define GT_DMA2_CNT_OFS		0x808
++#define GT_DMA3_CNT_OFS		0x80c
++#define GT_DMA0_SA_OFS		0x810
++#define GT_DMA1_SA_OFS		0x814
++#define GT_DMA2_SA_OFS		0x818
++#define GT_DMA3_SA_OFS		0x81c
++#define GT_DMA0_DA_OFS		0x820
++#define GT_DMA1_DA_OFS		0x824
++#define GT_DMA2_DA_OFS		0x828
++#define GT_DMA3_DA_OFS		0x82c
++#define GT_DMA0_NEXT_OFS	0x830
++#define GT_DMA1_NEXT_OFS	0x834
++#define GT_DMA2_NEXT_OFS	0x838
++#define GT_DMA3_NEXT_OFS	0x83c
++
++#define GT_DMA0_CUR_OFS		0x870
++#define GT_DMA1_CUR_OFS		0x874
++#define GT_DMA2_CUR_OFS		0x878
++#define GT_DMA3_CUR_OFS		0x87c
++
++/* DMA Channel Control.  */
++#define GT_DMA0_CTRL_OFS	0x840
++#define GT_DMA1_CTRL_OFS	0x844
++#define GT_DMA2_CTRL_OFS	0x848
++#define GT_DMA3_CTRL_OFS	0x84c
++
++/* DMA Arbiter.  */
++#define GT_DMA_ARB_OFS		0x860
++
++/* Timer/Counter.  */
++#define GT_TC0_OFS		0x850
++#define GT_TC1_OFS		0x854
++#define GT_TC2_OFS		0x858
++#define GT_TC3_OFS		0x85c
++
++#define GT_TC_CONTROL_OFS	0x864
++
++/* PCI Internal.  */
++#define GT_PCI0_CMD_OFS		0xc00
+ #define GT_PCI0_TOR_OFS		0xc04
+-#define GT_PCI0_BS_SCS10_OFS    0xc08
+-#define GT_PCI0_BS_SCS32_OFS    0xc0c
+-#define GT_INTRCAUSE_OFS	0xc18
+-#define GT_INTRMASK_OFS		0xc1c	/* GT64120A only */
++#define GT_PCI0_BS_SCS10_OFS	0xc08
++#define GT_PCI0_BS_SCS32_OFS	0xc0c
++#define GT_PCI0_BS_CS20_OFS	0xc10
++#define GT_PCI0_BS_CS3BT_OFS	0xc14
++
++#define GT_PCI1_IACK_OFS	0xc30
+ #define GT_PCI0_IACK_OFS	0xc34
++
+ #define GT_PCI0_BARE_OFS	0xc3c
+-#define GT_HINTRCAUSE_OFS	0xc98	/* GT64120A only */
+-#define GT_HINTRMASK_OFS	0xc9c	/* GT64120A only */
+-#define GT_PCI1_CFGADDR_OFS	0xcf0	/* GT64120A only */
+-#define GT_PCI1_CFGDATA_OFS	0xcf4	/* GT64120A only */
++#define GT_PCI0_PREFMBR_OFS	0xc40
++
++#define GT_PCI0_SCS10_BAR_OFS	0xc48
++#define GT_PCI0_SCS32_BAR_OFS	0xc4c
++#define GT_PCI0_CS20_BAR_OFS	0xc50
++#define GT_PCI0_CS3BT_BAR_OFS	0xc54
++#define GT_PCI0_SSCS10_BAR_OFS	0xc58
++#define GT_PCI0_SSCS32_BAR_OFS	0xc5c
++
++#define GT_PCI0_SCS3BT_BAR_OFS	0xc64
++
++#define GT_PCI1_CMD_OFS		0xc80
++#define GT_PCI1_TOR_OFS		0xc84
++#define GT_PCI1_BS_SCS10_OFS	0xc88
++#define GT_PCI1_BS_SCS32_OFS	0xc8c
++#define GT_PCI1_BS_CS20_OFS	0xc90
++#define GT_PCI1_BS_CS3BT_OFS	0xc94
++
++#define GT_PCI1_BARE_OFS	0xcbc
++#define GT_PCI1_PREFMBR_OFS	0xcc0
++
++#define GT_PCI1_SCS10_BAR_OFS	0xcc8
++#define GT_PCI1_SCS32_BAR_OFS	0xccc
++#define GT_PCI1_CS20_BAR_OFS	0xcd0
++#define GT_PCI1_CS3BT_BAR_OFS	0xcd4
++#define GT_PCI1_SSCS10_BAR_OFS	0xcd8
++#define GT_PCI1_SSCS32_BAR_OFS	0xcdc
++
++#define GT_PCI1_SCS3BT_BAR_OFS	0xce4
++
++#define GT_PCI1_CFGADDR_OFS	0xcf0
++#define GT_PCI1_CFGDATA_OFS	0xcf4
+ #define GT_PCI0_CFGADDR_OFS	0xcf8
+ #define GT_PCI0_CFGDATA_OFS	0xcfc
+ 
++/* Interrupts.  */
++#define GT_INTRCAUSE_OFS	0xc18
++#define GT_INTRMASK_OFS		0xc1c
++
++#define GT_PCI0_ICMASK_OFS	0xc24
++#define GT_PCI0_SERR0MASK_OFS	0xc28
++
++#define GT_CPU_INTSEL_OFS	0xc70
++#define GT_PCI0_INTSEL_OFS	0xc74
++
++#define GT_HINTRCAUSE_OFS	0xc98
++#define GT_HINTRMASK_OFS	0xc9c
++
++#define GT_PCI0_HICMASK_OFS	0xca4
++#define GT_PCI1_SERR1MASK_OFS	0xca8
+ 
+-/*
+- * Timer/Counter.  GT64120A only.
+- */
+-#define GT_TC0_OFS		0x850
+-#define GT_TC1_OFS		0x854
+-#define GT_TC2_OFS		0x858
+-#define GT_TC3_OFS		0x85C
+-#define GT_TC_CONTROL_OFS	0x864
+ 
+ /*
+  * I2O Support Registers
+@@ -167,9 +288,9 @@
+ /*
+  *  Register encodings
+  */
+-#define GT_CPU_ENDIAN_SHF       12
+-#define GT_CPU_ENDIAN_MSK       (MSK(1) << GT_CPU_ENDIAN_SHF)
+-#define GT_CPU_ENDIAN_BIT       GT_CPU_ENDIAN_MSK
++#define GT_CPU_ENDIAN_SHF	12
++#define GT_CPU_ENDIAN_MSK	(MSK(1) << GT_CPU_ENDIAN_SHF)
++#define GT_CPU_ENDIAN_BIT	GT_CPU_ENDIAN_MSK
+ #define GT_CPU_WR_SHF		16
+ #define GT_CPU_WR_MSK		(MSK(1) << GT_CPU_WR_SHF)
+ #define GT_CPU_WR_BIT		GT_CPU_WR_MSK
+@@ -177,6 +298,15 @@
+ #define GT_CPU_WR_DDDD		1
+ 
+ 
++#define GT_PCI_DCRM_SHF		21
++#define GT_PCI_LD_SHF		0
++#define GT_PCI_LD_MSK		(MSK(15) << GT_PCI_LD_SHF)
++#define GT_PCI_HD_SHF		0
++#define GT_PCI_HD_MSK		(MSK(7) << GT_PCI_LD_SHF)
++#define GT_PCI_REMAP_SHF	0
++#define GT_PCI_REMAP_MSK	(MSK(11) << GT_PCI_LD_SHF)
++
++
+ #define GT_CFGADDR_CFGEN_SHF	31
+ #define GT_CFGADDR_CFGEN_MSK	(MSK(1) << GT_CFGADDR_CFGEN_SHF)
+ #define GT_CFGADDR_CFGEN_BIT	GT_CFGADDR_CFGEN_MSK
+@@ -285,7 +415,7 @@
+ #define GT_SDRAM_CFG_REFINT_MSK		(MSK(14) << GT_SDRAM_CFG_REFINT_SHF)
+ 
+ #define GT_SDRAM_CFG_NINTERLEAVE_SHF	14
+-#define GT_SDRAM_CFG_NINTERLEAVE_MSK    (MSK(1) << GT_SDRAM_CFG_NINTERLEAVE_SHF)
++#define GT_SDRAM_CFG_NINTERLEAVE_MSK	(MSK(1) << GT_SDRAM_CFG_NINTERLEAVE_SHF)
+ #define GT_SDRAM_CFG_NINTERLEAVE_BIT	GT_SDRAM_CFG_NINTERLEAVE_MSK
+ 
+ #define GT_SDRAM_CFG_RMW_SHF		15
+@@ -370,7 +500,7 @@
+ #define GT_PCI0_CFGADDR_REGNUM_SHF	2
+ #define GT_PCI0_CFGADDR_REGNUM_MSK	(MSK(6) << GT_PCI0_CFGADDR_REGNUM_SHF)
+ #define GT_PCI0_CFGADDR_FUNCTNUM_SHF	8
+-#define GT_PCI0_CFGADDR_FUNCTNUM_MSK    (MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF)
++#define GT_PCI0_CFGADDR_FUNCTNUM_MSK	(MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF)
+ #define GT_PCI0_CFGADDR_DEVNUM_SHF	11
+ #define GT_PCI0_CFGADDR_DEVNUM_MSK	(MSK(5) << GT_PCI0_CFGADDR_DEVNUM_SHF)
+ #define GT_PCI0_CFGADDR_BUSNUM_SHF	16
+@@ -379,18 +509,18 @@
+ #define GT_PCI0_CFGADDR_CONFIGEN_MSK	(MSK(1) << GT_PCI0_CFGADDR_CONFIGEN_SHF)
+ #define GT_PCI0_CFGADDR_CONFIGEN_BIT	GT_PCI0_CFGADDR_CONFIGEN_MSK
+ 
+-#define GT_PCI0_CMD_MBYTESWAP_SHF       0
+-#define GT_PCI0_CMD_MBYTESWAP_MSK       (MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF)
+-#define GT_PCI0_CMD_MBYTESWAP_BIT       GT_PCI0_CMD_MBYTESWAP_MSK
+-#define GT_PCI0_CMD_MWORDSWAP_SHF       10
+-#define GT_PCI0_CMD_MWORDSWAP_MSK       (MSK(1) << GT_PCI0_CMD_MWORDSWAP_SHF)
+-#define GT_PCI0_CMD_MWORDSWAP_BIT       GT_PCI0_CMD_MWORDSWAP_MSK
+-#define GT_PCI0_CMD_SBYTESWAP_SHF       16
+-#define GT_PCI0_CMD_SBYTESWAP_MSK       (MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF)
+-#define GT_PCI0_CMD_SBYTESWAP_BIT       GT_PCI0_CMD_SBYTESWAP_MSK
+-#define GT_PCI0_CMD_SWORDSWAP_SHF       11
+-#define GT_PCI0_CMD_SWORDSWAP_MSK       (MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF)
+-#define GT_PCI0_CMD_SWORDSWAP_BIT       GT_PCI0_CMD_SWORDSWAP_MSK
++#define GT_PCI0_CMD_MBYTESWAP_SHF	0
++#define GT_PCI0_CMD_MBYTESWAP_MSK	(MSK(1) << GT_PCI0_CMD_MBYTESWAP_SHF)
++#define GT_PCI0_CMD_MBYTESWAP_BIT	GT_PCI0_CMD_MBYTESWAP_MSK
++#define GT_PCI0_CMD_MWORDSWAP_SHF	10
++#define GT_PCI0_CMD_MWORDSWAP_MSK	(MSK(1) << GT_PCI0_CMD_MWORDSWAP_SHF)
++#define GT_PCI0_CMD_MWORDSWAP_BIT	GT_PCI0_CMD_MWORDSWAP_MSK
++#define GT_PCI0_CMD_SBYTESWAP_SHF	16
++#define GT_PCI0_CMD_SBYTESWAP_MSK	(MSK(1) << GT_PCI0_CMD_SBYTESWAP_SHF)
++#define GT_PCI0_CMD_SBYTESWAP_BIT	GT_PCI0_CMD_SBYTESWAP_MSK
++#define GT_PCI0_CMD_SWORDSWAP_SHF	11
++#define GT_PCI0_CMD_SWORDSWAP_MSK	(MSK(1) << GT_PCI0_CMD_SWORDSWAP_SHF)
++#define GT_PCI0_CMD_SWORDSWAP_BIT	GT_PCI0_CMD_SWORDSWAP_MSK
+ 
+ /*
+  *  Misc
+@@ -401,8 +531,8 @@
+ #define GT_DEF_PCI0_MEM0_SIZE	0x02000000UL
+ #define GT_DEF_BASE		0x14000000UL
+ 
+-#define GT_MAX_BANKSIZE		(256 * 1024 * 1024)   /* Max 256MB bank */
+-#define GT_LATTIM_MIN    	6		      /* Minimum lat	*/
++#define GT_MAX_BANKSIZE		(256 * 1024 * 1024)	/* Max 256MB bank  */
++#define GT_LATTIM_MIN		6			/* Minimum lat  */
+ 
+ /*
+  * The gt64120_dep.h file must define the following macros
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/hazards.h linux-2.6.10-mips/include/asm-mips/hazards.h
+--- linux-2.6.10/include/asm-mips/hazards.h	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/hazards.h	2004-12-06 06:36:25.000000000 +0100
+@@ -16,6 +16,10 @@
+ 	sll	$0, $0, 1
+ 	.endm
+ 
++	.macro	_ehb
++	sll	$0, $0, 3
++	.endm
++
+ /*
+  * RM9000 hazards.  When the JTLB is updated by tlbwi or tlbwr, a subsequent
+  * use of the JTLB for instructions should not occur for 4 cpu cycles and use
+@@ -23,17 +27,19 @@
+  */
+ #ifdef CONFIG_CPU_RM9000
+ 
+-#define mtc0_tlbw_hazard						\
+-	.set	push;							\
+-	.set	mips32;							\
+-	_ssnop; _ssnop; _ssnop; _ssnop;					\
++	.macro	mtc0_tlbw_hazard
++	.set	push
++	.set	mips32
++	_ssnop; _ssnop; _ssnop; _ssnop
+ 	.set	pop
++	.endm
+ 
+-#define tlbw_eret_hazard						\
+-	.set	push;							\
+-	.set	mips32;							\
+-	_ssnop; _ssnop; _ssnop; _ssnop;					\
++	.macro	tlbw_eret_hazard
++	.set	push
++	.set	mips32
++	_ssnop; _ssnop; _ssnop; _ssnop
+ 	.set	pop
++	.endm
+ 
+ #else
+ 
+@@ -43,9 +49,12 @@
+  * hazard so this is nice trick to have an optimal code for a range of
+  * processors.
+  */
+-#define mtc0_tlbw_hazard						\
++	.macro	mtc0_tlbw_hazard
+ 	b	. + 8
+-#define tlbw_eret_hazard
++	.endm
++
++	.macro	tlbw_eret_hazard
++	.endm
+ #endif
+ 
+ /*
+@@ -58,31 +67,51 @@
+ /*
+  * Use a macro for ehb unless explicit support for MIPSR2 is enabled
+  */
+-	.macro	ehb
+-	sll	$0, $0, 3
+-	.endm
+ 
+-#define irq_enable_hazard						\
+-	ehb		# irq_enable_hazard
++#define irq_enable_hazard
++	_ehb
+ 
+-#define irq_disable_hazard						\
+-	ehb		# irq_disable_hazard
++#define irq_disable_hazard
++	_ehb
+ 
+-#else
++#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000)
++
++/*
++ * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
++ */
+ 
+ #define irq_enable_hazard
++
+ #define irq_disable_hazard
+ 
++#else
++
++/*
++ * Classic MIPS needs 1 - 3 nops or ssnops
++ */
++#define irq_enable_hazard
++#define irq_disable_hazard						\
++	_ssnop; _ssnop; _ssnop
++
+ #endif
+ 
+ #else /* __ASSEMBLY__ */
+ 
++__asm__(
++	"	.macro	_ssnop					\n\t"
++	"	sll	$0, $2, 1				\n\t"
++	"	.endm						\n\t"
++	"							\n\t"
++	"	.macro	_ehb					\n\t"
++	"	sll	$0, $0, 3				\n\t"
++	"	.endm						\n\t");
++
++#ifdef CONFIG_CPU_RM9000
+ /*
+  * RM9000 hazards.  When the JTLB is updated by tlbwi or tlbwr, a subsequent
+  * use of the JTLB for instructions should not occur for 4 cpu cycles and use
+  * for data translations should not occur for 3 cpu cycles.
+  */
+-#ifdef CONFIG_CPU_RM9000
+ 
+ #define mtc0_tlbw_hazard()						\
+ 	__asm__ __volatile__(						\
+@@ -125,27 +154,23 @@
+  * Use a macro for ehb unless explicit support for MIPSR2 is enabled
+  */
+ __asm__(
+-	"	.macro	ehb					\n\t"
+-	"	sll	$0, $0, 3				\n\t"
+-	"	.endm						\n\t"
+-	"							\n\t"
+ 	"	.macro\tirq_enable_hazard			\n\t"
+-	"	ehb						\n\t"
++	"	_ehb						\n\t"
+ 	"	.endm						\n\t"
+ 	"							\n\t"
+ 	"	.macro\tirq_disable_hazard			\n\t"
+-	"	ehb						\n\t"
++	"	_ehb						\n\t"
+ 	"	.endm");
+ 
+ #define irq_enable_hazard()						\
+ 	__asm__ __volatile__(						\
+-	"ehb\t\t\t\t# irq_enable_hazard")
++	"_ehb\t\t\t\t# irq_enable_hazard")
+ 
+ #define irq_disable_hazard()						\
+ 	__asm__ __volatile__(						\
+-	"ehb\t\t\t\t# irq_disable_hazard")
++	"_ehb\t\t\t\t# irq_disable_hazard")
+ 
+-#elif defined(CONFIG_CPU_R10000)
++#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000)
+ 
+ /*
+  * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
+@@ -170,10 +195,6 @@ __asm__(
+  */
+ 
+ __asm__(
+-	"	.macro	_ssnop					\n\t"
+-	"	sll	$0, $2, 1				\n\t"
+-	"	.endm						\n\t"
+-	"							\n\t"
+ 	"	#						\n\t"
+ 	"	# There is a hazard but we do not care		\n\t"
+ 	"	#						\n\t"
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/io.h linux-2.6.10-mips/include/asm-mips/io.h
+--- linux-2.6.10/include/asm-mips/io.h	2004-12-24 22:34:31.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/io.h	2005-01-11 17:51:31.000000000 +0100
+@@ -6,21 +6,26 @@
+  * Copyright (C) 1994, 1995 Waldorf GmbH
+  * Copyright (C) 1994 - 2000 Ralf Baechle
+  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
++ * Copyright (C) 2004  MIPS Technologies, Inc.  All rights reserved.
++ *	Author:	Maciej W. Rozycki <macro at mips.com>
+  */
+ #ifndef _ASM_IO_H
+ #define _ASM_IO_H
+ 
+ #include <linux/config.h>
+ #include <linux/compiler.h>
++#include <linux/kernel.h>
+ #include <linux/types.h>
+ 
+ #include <asm/addrspace.h>
++#include <asm/bug.h>
++#include <asm/byteorder.h>
+ #include <asm/cpu.h>
+ #include <asm/cpu-features.h>
+ #include <asm/page.h>
+ #include <asm/pgtable-bits.h>
+ #include <asm/processor.h>
+-#include <asm/byteorder.h>
++
+ #include <mangle-port.h>
+ 
+ /*
+@@ -29,34 +34,52 @@
+ #undef CONF_SLOWDOWN_IO
+ 
+ /*
+- * Sane hardware offers swapping of I/O space accesses in hardware; less
+- * sane hardware forces software to fiddle with this ...
++ * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware;
++ * less sane hardware forces software to fiddle with this...
+  */
+-#if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
++#if defined(CONFIG_SWAP_IO_SPACE)
+ 
+-#define __ioswab8(x) (x)
+-
+-#ifdef CONFIG_SGI_IP22
++# define ioswabb(x)		(x)
++# define __raw_ioswabb(x)	(x)
++# ifdef CONFIG_SGI_IP22
+ /*
+  * IP22 seems braindead enough to swap 16bits values in hardware, but
+  * not 32bits.  Go figure... Can't tell without documentation.
+  */
+-#define __ioswab16(x) (x)
+-#else
+-#define __ioswab16(x) swab16(x)
+-#endif
+-#define __ioswab32(x) swab32(x)
+-#define __ioswab64(x) swab64(x)
++#  define ioswabw(x)		(x)
++#  define __raw_ioswabw(x)	le16_to_cpu(x)
++# else
++#  define ioswabw(x)		le16_to_cpu(x)
++#  define __raw_ioswabw(x)	(x)
++# endif
++# define ioswabl(x)		le32_to_cpu(x)
++# define __raw_ioswabl(x)	(x)
++# define ioswabq(x)		le64_to_cpu(x)
++# define __raw_ioswabq(x)	(x)
+ 
+ #else
+ 
+-#define __ioswab8(x) (x)
+-#define __ioswab16(x) (x)
+-#define __ioswab32(x) (x)
+-#define __ioswab64(x) (x)
++# define ioswabb(x)		(x)
++# define __raw_ioswabb(x)	(x)
++# define ioswabw(x)		(x)
++# define __raw_ioswabw(x)	cpu_to_le16(x)
++# define ioswabl(x)		(x)
++# define __raw_ioswabl(x)	cpu_to_le32(x)
++# define ioswabq(x)		(x)
++# define __raw_ioswabq(x)	cpu_to_le64(x)
+ 
+ #endif
+ 
++/*
++ * Native bus accesses never swapped.
++ */
++#define bus_ioswabb(x)		(x)
++#define bus_ioswabw(x)		(x)
++#define bus_ioswabl(x)		(x)
++#define bus_ioswabq(x)		(x)
++
++#define __bus_ioswabq		bus_ioswabq
++
+ #define IO_SPACE_LIMIT 0xffff
+ 
+ /*
+@@ -239,114 +262,213 @@ static inline void * __ioremap_mode(phys
+ 
+ static inline void iounmap(volatile void __iomem *addr)
+ {
+-	if (cpu_has_64bits)
++	if (cpu_has_64bit_addresses)
+ 		return;
+ 
+ 	__iounmap(addr);
+ }
+ 
+-#define __raw_readb(addr)						\
+-	(*(volatile unsigned char *) __swizzle_addr_b((unsigned long)(addr)))
+-#define __raw_readw(addr)						\
+-	(*(volatile unsigned short *) __swizzle_addr_w((unsigned long)(addr)))
+-#define __raw_readl(addr)						\
+-	(*(volatile unsigned int *) __swizzle_addr_l((unsigned long)(addr)))
+-#ifdef CONFIG_MIPS32
+-#define ____raw_readq(addr)						\
+-({									\
+-	u64 __res;							\
+-									\
+-	__asm__ __volatile__ (						\
+-		"	.set	mips3		# ____raw_readq	\n"	\
+-		"	ld	%L0, (%1)			\n"	\
+-		"	dsra32	%M0, %L0, 0			\n"	\
+-		"	sll	%L0, %L0, 0			\n"	\
+-		"	.set	mips0				\n"	\
+-		: "=r" (__res)						\
+-		: "r" (__swizzle_addr_q((unsigned long)(addr))));	\
+-	__res;								\
+-})
+-#define __raw_readq(addr)						\
+-({									\
+-	unsigned long __flags;						\
+-	u64 __res;							\
+-									\
+-	local_irq_save(__flags);					\
+-	__res = ____raw_readq(addr);					\
+-	local_irq_restore(__flags);					\
+-	__res;								\
+-})
+-#endif
+-#ifdef CONFIG_MIPS64
+-#define ____raw_readq(addr)						\
+-	(*(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr)))
+-#define __raw_readq(addr)	____raw_readq(addr)
+-#endif
+ 
+-#define readb(addr)		__ioswab8(__raw_readb(addr))
+-#define readw(addr)		__ioswab16(__raw_readw(addr))
+-#define readl(addr)		__ioswab32(__raw_readl(addr))
+-#define readq(addr)		__ioswab64(__raw_readq(addr))
+-#define readb_relaxed(addr)	readb(addr)
+-#define readw_relaxed(addr)	readw(addr)
+-#define readl_relaxed(addr)	readl(addr)
+-#define readq_relaxed(addr)	readq(addr)
+-
+-#define __raw_writeb(b,addr)						\
+-do {									\
+-	((*(volatile unsigned char *)__swizzle_addr_b((unsigned long)(addr))) = (b));	\
+-} while (0)
+-
+-#define __raw_writew(w,addr)						\
+-do {									\
+-	((*(volatile unsigned short *)__swizzle_addr_w((unsigned long)(addr))) = (w));	\
+-} while (0)
+-
+-#define __raw_writel(l,addr)						\
+-do {									\
+-	((*(volatile unsigned int *)__swizzle_addr_l((unsigned long)(addr))) = (l));	\
+-} while (0)
+-
+-#ifdef CONFIG_MIPS32
+-#define ____raw_writeq(val,addr)					\
+-do {									\
+-	u64 __tmp;							\
+-									\
+-	__asm__ __volatile__ (						\
+-		"	.set	mips3				\n"	\
+-		"	dsll32	%L0, %L0, 0	# ____raw_writeq\n"	\
+-		"	dsrl32	%L0, %L0, 0			\n"	\
+-		"	dsll32	%M0, %M0, 0			\n"	\
+-		"	or	%L0, %L0, %M0			\n"	\
+-		"	sd	%L0, (%2)			\n"	\
+-		"	.set	mips0				\n"	\
+-		: "=r" (__tmp)						\
+-		: "0" ((unsigned long long)val),			\
+-		  "r" (__swizzle_addr_q((unsigned long)(addr))));	\
+-} while (0)
+-
+-#define __raw_writeq(val,addr)						\
+-do {									\
+-	unsigned long __flags;						\
+-									\
+-	local_irq_save(__flags);					\
+-	____raw_writeq(val, addr);					\
+-	local_irq_restore(__flags);					\
+-} while (0)
+-#endif
+-#ifdef CONFIG_MIPS64
+-#define ____raw_writeq(q,addr)						\
+-do {									\
+-	*(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr)) = (q);	\
+-} while (0)
++#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq)			\
++									\
++static inline void pfx##write##bwlq(type val, void *mem)		\
++{									\
++	volatile type *__mem;						\
++	type __val;							\
++									\
++	__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem));	\
++									\
++	__val = pfx##ioswab##bwlq(val);					\
++									\
++	if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long))	\
++		*__mem = __val;						\
++	else if (cpu_has_64bits) {					\
++		unsigned long __flags;					\
++		type __tmp;						\
++									\
++		if (irq)						\
++			local_irq_save(__flags);			\
++		__asm__ __volatile__(					\
++			".set	mips3"		"\t\t# __writeq""\n\t"	\
++			"dsll32	%L0, %L0, 0"			"\n\t"	\
++			"dsrl32	%L0, %L0, 0"			"\n\t"	\
++			"dsll32	%M0, %M0, 0"			"\n\t"	\
++			"or	%L0, %L0, %M0"			"\n\t"	\
++			"sd	%L0, %2"			"\n\t"	\
++			".set	mips0"				"\n"	\
++			: "=r" (__tmp)					\
++			: "0" (__val), "m" (*__mem));			\
++		if (irq)						\
++			local_irq_restore(__flags);			\
++	} else								\
++		BUG();							\
++}									\
++									\
++static inline type pfx##read##bwlq(void *mem)				\
++{									\
++	volatile type *__mem;						\
++	type __val;							\
++									\
++	__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem));	\
++									\
++	if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long))	\
++		__val = *__mem;						\
++	else if (cpu_has_64bits) {					\
++		unsigned long __flags;					\
++									\
++		local_irq_save(__flags);				\
++		__asm__ __volatile__(					\
++			".set	mips3"		"\t\t# __readq"	"\n\t"	\
++			"ld	%L0, %1"			"\n\t"	\
++			"dsra32	%M0, %L0, 0"			"\n\t"	\
++			"sll	%L0, %L0, 0"			"\n\t"	\
++			".set	mips0"				"\n"	\
++			: "=r" (__val)					\
++			: "m" (*__mem));				\
++		local_irq_restore(__flags);				\
++	} else {							\
++		__val = 0;						\
++		BUG();							\
++	}								\
++									\
++	return pfx##ioswab##bwlq(__val);				\
++}
+ 
+-#define __raw_writeq(q,addr)	____raw_writeq(q, addr)
+-#endif
++#define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow)			\
++									\
++static inline void pfx##out##bwlq##p(type val, unsigned long port)	\
++{									\
++	volatile type *__addr;						\
++	type __val;							\
++									\
++	port = __swizzle_addr_##bwlq(port);				\
++	__addr = (void *)(mips_io_port_base + port);			\
++									\
++	__val = pfx##ioswab##bwlq(val);					\
++									\
++	if (sizeof(type) != sizeof(u64)) {				\
++		*__addr = __val;					\
++		slow;							\
++	} else								\
++		BUILD_BUG();						\
++}									\
++									\
++static inline type pfx##in##bwlq##p(unsigned long port)			\
++{									\
++	volatile type *__addr;						\
++	type __val;							\
++									\
++	port = __swizzle_addr_##bwlq(port);				\
++	__addr = (void *)(mips_io_port_base + port);			\
++									\
++	if (sizeof(type) != sizeof(u64)) {				\
++		__val = *__addr;					\
++		slow;							\
++	} else {							\
++		__val = 0;						\
++		BUILD_BUG();						\
++	}								\
++									\
++	return pfx##ioswab##bwlq(__val);				\
++}
++
++#define __BUILD_MEMORY_PFX(bus, bwlq, type)				\
++									\
++__BUILD_MEMORY_SINGLE(bus, bwlq, type, 1)
++
++#define __BUILD_IOPORT_PFX(bus, bwlq, type)				\
++									\
++__BUILD_IOPORT_SINGLE(bus, bwlq, type, ,)				\
++__BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO)
++
++#define BUILDIO(bwlq, type)						\
++									\
++__BUILD_MEMORY_PFX(, bwlq, type)					\
++__BUILD_MEMORY_PFX(__raw_, bwlq, type)					\
++__BUILD_MEMORY_PFX(bus_, bwlq, type)					\
++__BUILD_IOPORT_PFX(, bwlq, type)					\
++__BUILD_IOPORT_PFX(__raw_, bwlq, type)
++
++#define __BUILDIO(bwlq, type)						\
++									\
++__BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0)
++
++BUILDIO(b, u8)
++BUILDIO(w, u16)
++BUILDIO(l, u32)
++BUILDIO(q, u64)
++
++__BUILDIO(q, u64)
++
++#define readb_relaxed			readb
++#define readw_relaxed			readw
++#define readl_relaxed			readl
++#define readq_relaxed			readq
++
++/*
++ * Some code tests for these symbols
++ */
++#define readq				readq
++#define writeq				writeq
++
++#define __BUILD_MEMORY_STRING(bwlq, type)				\
++									\
++static inline void writes##bwlq(void *mem, void *addr,			\
++				unsigned int count)			\
++{									\
++	volatile type *__addr = addr;					\
++									\
++	while (count--) {						\
++		__raw_write##bwlq(*__addr, mem);			\
++		__addr++;						\
++	}								\
++}									\
++									\
++static inline void reads##bwlq(void *mem, void *addr,			\
++			       unsigned int count)			\
++{									\
++	volatile type *__addr = addr;					\
++									\
++	while (count--) {						\
++		*__addr = __raw_read##bwlq(mem);			\
++		__addr++;						\
++	}								\
++}
++
++#define __BUILD_IOPORT_STRING(bwlq, type)				\
++									\
++static inline void outs##bwlq(unsigned long port, void *addr,		\
++			      unsigned int count)			\
++{									\
++	volatile type *__addr = addr;					\
++									\
++	while (count--) {						\
++		__raw_out##bwlq(*__addr, port);				\
++		__addr++;						\
++	}								\
++}									\
++									\
++static inline void ins##bwlq(unsigned long port, void *addr,		\
++			     unsigned int count)			\
++{									\
++	volatile type *__addr = addr;					\
++									\
++	while (count--) {						\
++		*__addr = __raw_in##bwlq(port);				\
++		__addr++;						\
++	}								\
++}
++
++#define BUILDSTRING(bwlq, type)						\
++									\
++__BUILD_MEMORY_STRING(bwlq, type)					\
++__BUILD_IOPORT_STRING(bwlq, type)
++
++BUILDSTRING(b, u8)
++BUILDSTRING(w, u16)
++BUILDSTRING(l, u32)
++BUILDSTRING(q, u64)
+ 
+-#define writeb(b,addr)		__raw_writeb(__ioswab8(b),(addr))
+-#define writew(w,addr)		__raw_writew(__ioswab16(w),(addr))
+-#define writel(l,addr)		__raw_writel(__ioswab32(l),(addr))
+-#define writeq(q,addr)		__raw_writeq(__ioswab64(q),(addr))
+ 
+ /* Depends on MIPS II instruction set */
+ #define mmiowb() asm volatile ("sync" ::: "memory")
+@@ -394,7 +516,7 @@ do {									\
+  *     address should have been obtained by ioremap.
+  *     Returns 1 on a match.
+  */
+-static inline int check_signature(unsigned long io_addr,
++static inline int check_signature(char __iomem *io_addr,
+ 	const unsigned char *signature, int length)
+ {
+ 	int retval = 0;
+@@ -410,177 +532,6 @@ out:
+ 	return retval;
+ }
+ 
+-static inline void __outb(unsigned char val, unsigned long port)
+-{
+-	port = __swizzle_addr_b(port);
+-
+-	*(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val);
+-}
+-
+-static inline void __outw(unsigned short val, unsigned long port)
+-{
+-	port = __swizzle_addr_w(port);
+-
+-	*(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val);
+-}
+-
+-static inline void __outl(unsigned int val, unsigned long port)
+-{
+-	port = __swizzle_addr_l(port);
+-
+-	*(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val);
+-}
+-
+-static inline void __outb_p(unsigned char val, unsigned long port)
+-{
+-	port = __swizzle_addr_b(port);
+-
+-	*(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val);
+-	SLOW_DOWN_IO;
+-}
+-
+-static inline void __outw_p(unsigned short val, unsigned long port)
+-{
+-	port = __swizzle_addr_w(port);
+-
+-	*(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val);
+-	SLOW_DOWN_IO;
+-}
+-
+-static inline void __outl_p(unsigned int val, unsigned long port)
+-{
+-	port = __swizzle_addr_l(port);
+-
+-	*(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val);
+-	SLOW_DOWN_IO;
+-}
+-
+-#define outb(val, port)		__outb(val, port)
+-#define outw(val, port)		__outw(val, port)
+-#define outl(val, port)		__outl(val, port)
+-#define outb_p(val, port)	__outb_p(val, port)
+-#define outw_p(val, port)	__outw_p(val, port)
+-#define outl_p(val, port)	__outl_p(val, port)
+-
+-static inline unsigned char __inb(unsigned long port)
+-{
+-	port = __swizzle_addr_b(port);
+-
+-	return __ioswab8(*(volatile u8 *)(mips_io_port_base + port));
+-}
+-
+-static inline unsigned short __inw(unsigned long port)
+-{
+-	port = __swizzle_addr_w(port);
+-
+-	return __ioswab16(*(volatile u16 *)(mips_io_port_base + port));
+-}
+-
+-static inline unsigned int __inl(unsigned long port)
+-{
+-	port = __swizzle_addr_l(port);
+-
+-	return __ioswab32(*(volatile u32 *)(mips_io_port_base + port));
+-}
+-
+-static inline unsigned char __inb_p(unsigned long port)
+-{
+-	u8 __val;
+-
+-	port = __swizzle_addr_b(port);
+-
+-	__val = *(volatile u8 *)(mips_io_port_base + port);
+-	SLOW_DOWN_IO;
+-
+-	return __ioswab8(__val);
+-}
+-
+-static inline unsigned short __inw_p(unsigned long port)
+-{
+-	u16 __val;
+-
+-	port = __swizzle_addr_w(port);
+-
+-	__val = *(volatile u16 *)(mips_io_port_base + port);
+-	SLOW_DOWN_IO;
+-
+-	return __ioswab16(__val);
+-}
+-
+-static inline unsigned int __inl_p(unsigned long port)
+-{
+-	u32 __val;
+-
+-	port = __swizzle_addr_l(port);
+-
+-	__val = *(volatile u32 *)(mips_io_port_base + port);
+-	SLOW_DOWN_IO;
+-
+-	return __ioswab32(__val);
+-}
+-
+-#define inb(port)	__inb(port)
+-#define inw(port)	__inw(port)
+-#define inl(port)	__inl(port)
+-#define inb_p(port)	__inb_p(port)
+-#define inw_p(port)	__inw_p(port)
+-#define inl_p(port)	__inl_p(port)
+-
+-static inline void __outsb(unsigned long port, void *addr, unsigned int count)
+-{
+-	while (count--) {
+-		outb(*(u8 *)addr, port);
+-		addr++;
+-	}
+-}
+-
+-static inline void __insb(unsigned long port, void *addr, unsigned int count)
+-{
+-	while (count--) {
+-		*(u8 *)addr = inb(port);
+-		addr++;
+-	}
+-}
+-
+-static inline void __outsw(unsigned long port, void *addr, unsigned int count)
+-{
+-	while (count--) {
+-		outw(*(u16 *)addr, port);
+-		addr += 2;
+-	}
+-}
+-
+-static inline void __insw(unsigned long port, void *addr, unsigned int count)
+-{
+-	while (count--) {
+-		*(u16 *)addr = inw(port);
+-		addr += 2;
+-	}
+-}
+-
+-static inline void __outsl(unsigned long port, void *addr, unsigned int count)
+-{
+-	while (count--) {
+-		outl(*(u32 *)addr, port);
+-		addr += 4;
+-	}
+-}
+-
+-static inline void __insl(unsigned long port, void *addr, unsigned int count)
+-{
+-	while (count--) {
+-		*(u32 *)addr = inl(port);
+-		addr += 4;
+-	}
+-}
+-
+-#define outsb(port, addr, count)	__outsb(port, addr, count)
+-#define insb(port, addr, count)		__insb(port, addr, count)
+-#define outsw(port, addr, count)	__outsw(port, addr, count)
+-#define insw(port, addr, count)		__insw(port, addr, count)
+-#define outsl(port, addr, count)	__outsl(port, addr, count)
+-#define insl(port, addr, count)		__insl(port, addr, count)
+-
+ /*
+  * The caches on some architectures aren't dma-coherent and have need to
+  * handle this in software.  There are three types of operations that
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/irq_cpu.h linux-2.6.10-mips/include/asm-mips/irq_cpu.h
+--- linux-2.6.10/include/asm-mips/irq_cpu.h	2004-12-24 22:34:32.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/irq_cpu.h	2004-12-17 10:36:03.000000000 +0100
+@@ -15,5 +15,6 @@
+ 
+ extern void mips_cpu_irq_init(int irq_base);
+ extern void rm7k_cpu_irq_init(int irq_base);
++extern void rm9k_cpu_irq_init(int irq_base);
+ 
+ #endif /* _ASM_IRQ_CPU_H */
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/it8172/it8172_lpc.h linux-2.6.10-mips/include/asm-mips/it8172/it8172_lpc.h
+--- linux-2.6.10/include/asm-mips/it8172/it8172_lpc.h	2004-12-24 22:35:40.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/it8172/it8172_lpc.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,29 +0,0 @@
+-/*
+- *
+- * BRIEF MODULE DESCRIPTION
+- *	IT8172 system controller defines.
+- *
+- * Copyright 2000 MontaVista Software Inc.
+- * Author: MontaVista Software, Inc.
+- *         	ppopov at mvista.com or source at mvista.com
+- *
+- *  This program is free software; you can redistribute  it and/or modify it
+- *  under  the terms of  the GNU General  Public License as published by the
+- *  Free Software Foundation;  either version 2 of the  License, or (at your
+- *  option) any later version.
+- *
+- *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+- *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+- *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+- *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+- *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+- *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+- *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+- *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- *
+- *  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.
+- */
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/m48t37.h linux-2.6.10-mips/include/asm-mips/m48t37.h
+--- linux-2.6.10/include/asm-mips/m48t37.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/m48t37.h	2004-12-09 20:17:01.000000000 +0100
+@@ -0,0 +1,35 @@
++/*
++ *  Registers for the SGS-Thomson M48T37 Timekeeper RAM chip
++ */
++#ifndef _ASM_M48T37_H
++#define _ASM_M48T37_H
++
++#include <linux/spinlock.h>
++
++extern spinlock_t rtc_lock;
++
++struct m48t37_rtc {
++	volatile u8	pad[0x7ff0];    /* NVRAM */
++	volatile u8	flags;
++	volatile u8	century;
++	volatile u8	alarm_sec;
++	volatile u8	alarm_min;
++	volatile u8	alarm_hour;
++	volatile u8	alarm_data;
++	volatile u8	interrupts;
++	volatile u8	watchdog;
++	volatile u8	control;
++	volatile u8	sec;
++	volatile u8	min;
++	volatile u8	hour;
++	volatile u8	day;
++	volatile u8	date;
++	volatile u8	month;
++	volatile u8	year;
++};
++
++#define M48T37_RTC_SET		0x80
++#define M48T37_RTC_STOPPED	0x80
++#define M48T37_RTC_READ		0x40
++
++#endif /* _ASM_M48T37_H */
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mach-ev64120/mach-gt64120.h linux-2.6.10-mips/include/asm-mips/mach-ev64120/mach-gt64120.h
+--- linux-2.6.10/include/asm-mips/mach-ev64120/mach-gt64120.h	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mach-ev64120/mach-gt64120.h	2004-12-17 10:36:04.000000000 +0100
+@@ -18,29 +18,29 @@ extern unsigned long gt64120_base;
+ /*
+  *   PCI Bus allocation
+  */
+-#define GT_PCI_MEM_BASE    0x12000000UL
+-#define GT_PCI_MEM_SIZE    0x02000000UL
+-#define GT_PCI_IO_BASE     0x10000000UL
+-#define GT_PCI_IO_SIZE     0x02000000UL
+-#define GT_ISA_IO_BASE     PCI_IO_BASE
++#define GT_PCI_MEM_BASE	0x12000000UL
++#define GT_PCI_MEM_SIZE	0x02000000UL
++#define GT_PCI_IO_BASE	0x10000000UL
++#define GT_PCI_IO_SIZE	0x02000000UL
++#define GT_ISA_IO_BASE	PCI_IO_BASE
+ 
+ /*
+  *   Duart I/O ports.
+  */
+-#define EV64120_COM1_BASE_ADDR  (0x1d000000 + 0x20)
+-#define EV64120_COM2_BASE_ADDR  (0x1d000000 + 0x00)
++#define EV64120_COM1_BASE_ADDR	(0x1d000000 + 0x20)
++#define EV64120_COM2_BASE_ADDR	(0x1d000000 + 0x00)
+ 
+ 
+ /*
+  *   EV64120 interrupt controller register base.
+  */
+-#define EV64120_ICTRL_REGS_BASE   (KSEG1ADDR(0x1f000000))
++#define EV64120_ICTRL_REGS_BASE	(KSEG1ADDR(0x1f000000))
+ 
+ /*
+  *   EV64120 UART register base.
+  */
+-#define EV64120_UART0_REGS_BASE    (KSEG1ADDR(EV64120_COM1_BASE_ADDR))
+-#define EV64120_UART1_REGS_BASE    (KSEG1ADDR(EV64120_COM2_BASE_ADDR))
++#define EV64120_UART0_REGS_BASE	(KSEG1ADDR(EV64120_COM1_BASE_ADDR))
++#define EV64120_UART1_REGS_BASE	(KSEG1ADDR(EV64120_COM2_BASE_ADDR))
+ #define EV64120_BASE_BAUD ( 3686400 / 16 )
+ 
+ /*
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mach-ev96100/mach-gt64120.h linux-2.6.10-mips/include/asm-mips/mach-ev96100/mach-gt64120.h
+--- linux-2.6.10/include/asm-mips/mach-ev96100/mach-gt64120.h	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mach-ev96100/mach-gt64120.h	2004-12-17 10:36:04.000000000 +0100
+@@ -18,29 +18,29 @@
+  *
+  *   (Guessing ...)
+  */
+-#define GT_PCI_MEM_BASE    0x12000000UL
+-#define GT_PCI_MEM_SIZE    0x02000000UL
+-#define GT_PCI_IO_BASE     0x10000000UL
+-#define GT_PCI_IO_SIZE     0x02000000UL
+-#define GT_ISA_IO_BASE     PCI_IO_BASE
++#define GT_PCI_MEM_BASE	0x12000000UL
++#define GT_PCI_MEM_SIZE	0x02000000UL
++#define GT_PCI_IO_BASE	0x10000000UL
++#define GT_PCI_IO_SIZE	0x02000000UL
++#define GT_ISA_IO_BASE	PCI_IO_BASE
+ 
+ /*
+  *   Duart I/O ports.
+  */
+-#define EV96100_COM1_BASE_ADDR  (0xBD000000 + 0x20)
+-#define EV96100_COM2_BASE_ADDR  (0xBD000000 + 0x00)
++#define EV96100_COM1_BASE_ADDR	(0xBD000000 + 0x20)
++#define EV96100_COM2_BASE_ADDR	(0xBD000000 + 0x00)
+ 
+ 
+ /*
+  *   EV96100 interrupt controller register base.
+  */
+-#define EV96100_ICTRL_REGS_BASE   (KSEG1ADDR(0x1f000000))
++#define EV96100_ICTRL_REGS_BASE	(KSEG1ADDR(0x1f000000))
+ 
+ /*
+  *   EV96100 UART register base.
+  */
+-#define EV96100_UART0_REGS_BASE    EV96100_COM1_BASE_ADDR
+-#define EV96100_UART1_REGS_BASE    EV96100_COM2_BASE_ADDR
+-#define EV96100_BASE_BAUD ( 3686400 / 16 )
++#define EV96100_UART0_REGS_BASE	EV96100_COM1_BASE_ADDR
++#define EV96100_UART1_REGS_BASE	EV96100_COM2_BASE_ADDR
++#define EV96100_BASE_BAUD	( 3686400 / 16 )
+ 
+ #endif /* _ASM_GT64120_EV96100_GT64120_DEP_H */
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mach-generic/ide.h linux-2.6.10-mips/include/asm-mips/mach-generic/ide.h
+--- linux-2.6.10/include/asm-mips/mach-generic/ide.h	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mach-generic/ide.h	2005-01-10 03:08:12.000000000 +0100
+@@ -16,6 +16,8 @@
+ #ifdef __KERNEL__
+ 
+ #include <linux/config.h>
++#include <linux/pci.h>
++#include <linux/stddef.h>
+ 
+ #ifndef MAX_HWIFS
+ # ifdef CONFIG_BLK_DEV_IDEPCI
+@@ -27,32 +29,68 @@
+ 
+ #define IDE_ARCH_OBSOLETE_DEFAULTS
+ 
++static __inline__ int ide_probe_legacy(void)
++{
++#ifdef CONFIG_PCI
++	struct pci_dev *dev;
++	if ((dev = pci_get_class(PCI_CLASS_BRIDGE_EISA << 8, NULL)) != NULL ||
++	    (dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL)) != NULL) {
++		pci_dev_put(dev);
++
++		return 1;
++	}
++	return 0;
++#elif defined(CONFIG_EISA) || defined(CONFIG_ISA)
++	return 1;
++#else
++	return 0;
++#endif
++}
++
+ static __inline__ int ide_default_irq(unsigned long base)
+ {
+-	switch (base) {
+-		case 0x1f0: return 14;
+-		case 0x170: return 15;
+-		case 0x1e8: return 11;
+-		case 0x168: return 10;
+-		case 0x1e0: return 8;
+-		case 0x160: return 12;
++	if (ide_probe_legacy())
++		switch (base) {
++		case 0x1f0:
++			return 14;
++		case 0x170:
++			return 15;
++		case 0x1e8:
++			return 11;
++		case 0x168:
++			return 10;
++		case 0x1e0:
++			return 8;
++		case 0x160:
++			return 12;
+ 		default:
+ 			return 0;
+-	}
++		}
++	else
++		return 0;
+ }
+ 
+ static __inline__ unsigned long ide_default_io_base(int index)
+ {
+-	switch (index) {
+-		case 0:	return 0x1f0;
+-		case 1:	return 0x170;
+-		case 2: return 0x1e8;
+-		case 3: return 0x168;
+-		case 4: return 0x1e0;
+-		case 5: return 0x160;
++	if (ide_probe_legacy())
++		switch (index) {
++		case 0:
++			return 0x1f0;
++		case 1:
++			return 0x170;
++		case 2:
++			return 0x1e8;
++		case 3:
++			return 0x168;
++		case 4:
++			return 0x1e0;
++		case 5:
++			return 0x160;
+ 		default:
+ 			return 0;
+-	}
++		}
++	else
++		return 0;
+ }
+ 
+ #define IDE_ARCH_OBSOLETE_INIT
+@@ -64,7 +102,17 @@ static __inline__ unsigned long ide_defa
+ #define ide_init_default_irq(base)	ide_default_irq(base)
+ #endif
+ 
+-#include <asm-generic/ide_iops.h>
++/* MIPS port and memory-mapped I/O string operations.  */
++
++#define __ide_insw	insw
++#define __ide_insl	insl
++#define __ide_outsw	outsw
++#define __ide_outsl	outsl
++
++#define __ide_mm_insw	readsw
++#define __ide_mm_insl	readsl
++#define __ide_mm_outsw	writesw
++#define __ide_mm_outsl	writesl
+ 
+ #endif /* __KERNEL__ */
+ 
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mach-ip27/cpu-feature-overrides.h linux-2.6.10-mips/include/asm-mips/mach-ip27/cpu-feature-overrides.h
+--- linux-2.6.10/include/asm-mips/mach-ip27/cpu-feature-overrides.h	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mach-ip27/cpu-feature-overrides.h	2004-12-17 10:36:04.000000000 +0100
+@@ -25,6 +25,7 @@
+ #define cpu_has_vtag_icache	0
+ #define cpu_has_dc_aliases	0
+ #define cpu_has_ic_fills_f_dc	0
++#define cpu_icache_snoops_remote_store	1
+ 
+ #define cpu_has_nofpuex		0
+ #define cpu_has_64bits		1
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mach-ip32/mc146818rtc.h linux-2.6.10-mips/include/asm-mips/mach-ip32/mc146818rtc.h
+--- linux-2.6.10/include/asm-mips/mach-ip32/mc146818rtc.h	2004-12-24 22:33:52.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mach-ip32/mc146818rtc.h	2005-01-09 18:06:26.000000000 +0100
+@@ -15,7 +15,6 @@
+ #include <asm/ip32/mace.h>
+ 
+ #define RTC_PORT(x)	(0x70 + (x))
+-#define RTC_IRQ		MACEISA_RTC_IRQ
+ 
+ static unsigned char CMOS_READ(unsigned long addr)
+ {
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mach-ja/cpu-feature-overrides.h linux-2.6.10-mips/include/asm-mips/mach-ja/cpu-feature-overrides.h
+--- linux-2.6.10/include/asm-mips/mach-ja/cpu-feature-overrides.h	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mach-ja/cpu-feature-overrides.h	2004-12-17 10:36:04.000000000 +0100
+@@ -25,6 +25,7 @@
+ #define cpu_has_vtag_icache	0
+ #define cpu_has_dc_aliases	0
+ #define cpu_has_ic_fills_f_dc	0
++#define cpu_icache_snoops_remote_store	0
+ 
+ #define cpu_has_nofpuex		0
+ #define cpu_has_64bits		1
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mach-lasat/mach-gt64120.h linux-2.6.10-mips/include/asm-mips/mach-lasat/mach-gt64120.h
+--- linux-2.6.10/include/asm-mips/mach-lasat/mach-gt64120.h	2004-12-24 22:33:59.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mach-lasat/mach-gt64120.h	2004-12-17 10:36:04.000000000 +0100
+@@ -18,10 +18,10 @@
+  *
+  *   (Guessing ...)
+  */
+-#define GT_PCI_MEM_BASE    0x12000000UL
+-#define GT_PCI_MEM_SIZE    0x02000000UL
+-#define GT_PCI_IO_BASE     0x10000000UL
+-#define GT_PCI_IO_SIZE     0x02000000UL
+-#define GT_ISA_IO_BASE     PCI_IO_BASE
++#define GT_PCI_MEM_BASE	0x12000000UL
++#define GT_PCI_MEM_SIZE	0x02000000UL
++#define GT_PCI_IO_BASE	0x10000000UL
++#define GT_PCI_IO_SIZE	0x02000000UL
++#define GT_ISA_IO_BASE	PCI_IO_BASE
+ 
+ #endif /* _ASM_GT64120_LASAT_GT64120_DEP_H */
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mach-mips/mach-gt64120.h linux-2.6.10-mips/include/asm-mips/mach-mips/mach-gt64120.h
+--- linux-2.6.10/include/asm-mips/mach-mips/mach-gt64120.h	2004-12-24 22:34:44.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mach-mips/mach-gt64120.h	2004-12-17 10:36:04.000000000 +0100
+@@ -8,7 +8,7 @@
+ #ifndef _ASM_MACH_MIPS_MACH_GT64120_DEP_H
+ #define _ASM_MACH_MIPS_MACH_GT64120_DEP_H
+ 
+-#define MIPS_GT_BASE    0x1be00000
++#define MIPS_GT_BASE	0x1be00000
+ 
+ extern unsigned long _pcictrl_gt64120;
+ /*
+@@ -19,10 +19,10 @@ extern unsigned long _pcictrl_gt64120;
+ /*
+  *   PCI Bus allocation
+  */
+-#define GT_PCI_MEM_BASE    0x12000000UL
+-#define GT_PCI_MEM_SIZE    0x02000000UL
+-#define GT_PCI_IO_BASE     0x10000000UL
+-#define GT_PCI_IO_SIZE     0x02000000UL
+-#define GT_ISA_IO_BASE     PCI_IO_BASE
++#define GT_PCI_MEM_BASE	0x12000000UL
++#define GT_PCI_MEM_SIZE	0x02000000UL
++#define GT_PCI_IO_BASE	0x10000000UL
++#define GT_PCI_IO_SIZE	0x02000000UL
++#define GT_ISA_IO_BASE	PCI_IO_BASE
+ 
+ #endif /* _ASM_MACH_MIPS_MACH_GT64120_DEP_H */
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mach-ocelot/mach-gt64120.h linux-2.6.10-mips/include/asm-mips/mach-ocelot/mach-gt64120.h
+--- linux-2.6.10/include/asm-mips/mach-ocelot/mach-gt64120.h	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mach-ocelot/mach-gt64120.h	2004-12-17 10:36:04.000000000 +0100
+@@ -13,14 +13,14 @@
+ /*
+  * PCI address allocation
+  */
+-#define GT_PCI_MEM_BASE    (0x22000000UL)
+-#define GT_PCI_MEM_SIZE    GT_DEF_PCI0_MEM0_SIZE
+-#define GT_PCI_IO_BASE     (0x20000000UL)
+-#define GT_PCI_IO_SIZE     GT_DEF_PCI0_IO_SIZE
++#define GT_PCI_MEM_BASE	(0x22000000UL)
++#define GT_PCI_MEM_SIZE	GT_DEF_PCI0_MEM0_SIZE
++#define GT_PCI_IO_BASE	(0x20000000UL)
++#define GT_PCI_IO_SIZE	GT_DEF_PCI0_IO_SIZE
+ 
+ extern unsigned long gt64120_base;
+ 
+-#define GT64120_BASE       (gt64120_base)
++#define GT64120_BASE	(gt64120_base)
+ 
+ /*
+  * GT timer irq
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h linux-2.6.10-mips/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
+--- linux-2.6.10/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h	2004-12-17 10:36:04.000000000 +0100
+@@ -28,6 +28,7 @@
+ #define cpu_has_vtag_icache	0
+ #define cpu_has_dc_aliases	0
+ #define cpu_has_ic_fills_f_dc	0
++#define cpu_icache_snoops_remote_store	0
+ 
+ #define cpu_has_nofpuex 	0
+ #define cpu_has_64bits		1
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mach-sibyte/cpu-feature-overrides.h linux-2.6.10-mips/include/asm-mips/mach-sibyte/cpu-feature-overrides.h
+--- linux-2.6.10/include/asm-mips/mach-sibyte/cpu-feature-overrides.h	2004-12-24 22:34:45.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mach-sibyte/cpu-feature-overrides.h	2004-12-17 10:36:04.000000000 +0100
+@@ -25,6 +25,7 @@
+ #define cpu_has_vtag_icache	1
+ #define cpu_has_dc_aliases	0
+ #define cpu_has_ic_fills_f_dc	0
++#define cpu_icache_snoops_remote_store	0
+ 
+ #define cpu_has_nofpuex		0
+ #define cpu_has_64bits		1
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mach-yosemite/cpu-feature-overrides.h linux-2.6.10-mips/include/asm-mips/mach-yosemite/cpu-feature-overrides.h
+--- linux-2.6.10/include/asm-mips/mach-yosemite/cpu-feature-overrides.h	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mach-yosemite/cpu-feature-overrides.h	2004-12-17 10:36:04.000000000 +0100
+@@ -25,6 +25,7 @@
+ #define cpu_has_vtag_icache	0
+ #define cpu_has_dc_aliases	0
+ #define cpu_has_ic_fills_f_dc	0
++#define cpu_icache_snoops_remote_store	0
+ 
+ #define cpu_has_nofpuex		0
+ #define cpu_has_64bits		1
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mipsregs.h linux-2.6.10-mips/include/asm-mips/mipsregs.h
+--- linux-2.6.10/include/asm-mips/mipsregs.h	2004-12-24 22:34:45.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mipsregs.h	2004-12-21 03:25:28.000000000 +0100
+@@ -533,31 +533,50 @@
+ #ifndef __ASSEMBLY__
+ 
+ /*
+- * Functions to access the r10k performance counter and control registers
++ * Functions to access the R10000 performance counters.  These are basically
++ * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit
++ * performance counter number encoded into bits 1 ... 5 of the instruction.
++ * Only performance counters 0 to 1 actually exist, so for a non-R10000 aware
++ * disassembler these will look like an access to sel 0 or 1.
+  */
+-#define read_r10k_perf_cntr(counter)                            \
+-({ unsigned int __res;                                          \
+-        __asm__ __volatile__(                                   \
+-        "mfpc\t%0, "STR(counter)                                \
+-        : "=r" (__res));                                        \
+-        __res;})
++#define read_r10k_perf_cntr(counter)				\
++({								\
++	unsigned int __res;					\
++	__asm__ __volatile__(					\
++	"mfpc\t%0, %1"						\
++        : "=r" (__res)						\
++	: "i" (counter));					\
++								\
++        __res;							\
++})
+ 
+ #define write_r10k_perf_cntr(counter,val)                       \
+-        __asm__ __volatile__(                                   \
+-        "mtpc\t%0, "STR(counter)                                \
+-        : : "r" (val));
+-
+-#define read_r10k_perf_cntl(counter)                            \
+-({ unsigned int __res;                                          \
+-        __asm__ __volatile__(                                   \
+-        "mfps\t%0, "STR(counter)                                \
+-        : "=r" (__res));                                        \
+-        __res;})
++do {								\
++	__asm__ __volatile__(					\
++	"mtpc\t%0, %1"						\
++	:							\
++	: "r" (val), "i" (counter));				\
++} while (0)
++
++#define read_r10k_perf_event(counter)				\
++({								\
++	unsigned int __res;					\
++	__asm__ __volatile__(					\
++	"mfps\t%0, %1"						\
++        : "=r" (__res)						\
++	: "i" (counter));					\
++								\
++        __res;							\
++})
+ 
+ #define write_r10k_perf_cntl(counter,val)                       \
+-        __asm__ __volatile__(                                   \
+-        "mtps\t%0, "STR(counter)                                \
+-        : : "r" (val));
++do {								\
++	__asm__ __volatile__(					\
++	"mtps\t%0, %1"						\
++	:							\
++	: "r" (val), "i" (counter));				\
++} while (0)
++
+ 
+ /*
+  * Macros to access the system control coprocessor
+@@ -579,8 +598,10 @@
+ })
+ 
+ #define __read_64bit_c0_register(source, sel)				\
+-({ unsigned long __res;							\
+-	if (sel == 0)							\
++({ unsigned long long __res;						\
++	if (sizeof(unsigned long) == 4)					\
++		__res = __read_64bit_c0_split(source, sel);		\
++	else if (sel == 0)						\
+ 		__asm__ __volatile__(					\
+ 			".set\tmips3\n\t"				\
+ 			"dmfc0\t%0, " #source "\n\t"			\
+@@ -611,7 +632,9 @@ do {									\
+ 
+ #define __write_64bit_c0_register(register, sel, value)			\
+ do {									\
+-	if (sel == 0)							\
++	if (sizeof(unsigned long) == 4)					\
++		__write_64bit_c0_split(register, sel, value);		\
++	else if (sel == 0)						\
+ 		__asm__ __volatile__(					\
+ 			".set\tmips3\n\t"				\
+ 			"dmtc0\t%z0, " #register "\n\t"			\
+@@ -627,8 +650,8 @@ do {									\
+ 
+ #define __read_ulong_c0_register(reg, sel)				\
+ 	((sizeof(unsigned long) == 4) ?					\
+-	__read_32bit_c0_register(reg, sel) :				\
+-	__read_64bit_c0_register(reg, sel))
++	(unsigned long) __read_32bit_c0_register(reg, sel) :		\
++	(unsigned long) __read_64bit_c0_register(reg, sel))
+ 
+ #define __write_ulong_c0_register(reg, sel, val)			\
+ do {									\
+@@ -822,6 +845,10 @@ do {									\
+ #define read_c0_framemask()	__read_32bit_c0_register($21, 0)
+ #define write_c0_framemask(val)	__write_32bit_c0_register($21, 0, val)
+ 
++/* RM9000 PerfControl performance counter control register */
++#define read_c0_perfcontrol()	__read_32bit_c0_register($22, 0)
++#define write_c0_perfcontrol(val) __write_32bit_c0_register($22, 0, val)
++
+ #define read_c0_diag()		__read_32bit_c0_register($22, 0)
+ #define write_c0_diag(val)	__write_32bit_c0_register($22, 0, val)
+ 
+@@ -846,6 +873,10 @@ do {									\
+ #define read_c0_depc()		__read_ulong_c0_register($24, 0)
+ #define write_c0_depc(val)	__write_ulong_c0_register($24, 0, val)
+ 
++/* RM9000 PerfCount performance counter register */
++#define read_c0_perfcount()	__read_64bit_c0_register($25, 0)
++#define write_c0_perfcount(val)	__write_64bit_c0_register($25, 0, val)
++
+ #define read_c0_ecc()		__read_32bit_c0_register($26, 0)
+ #define write_c0_ecc(val)	__write_32bit_c0_register($26, 0, val)
+ 
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/mmu_context.h linux-2.6.10-mips/include/asm-mips/mmu_context.h
+--- linux-2.6.10/include/asm-mips/mmu_context.h	2004-12-24 22:34:44.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/mmu_context.h	2005-01-09 13:24:02.000000000 +0100
+@@ -19,26 +19,30 @@
+ #include <asm/tlbflush.h>
+ 
+ /*
+- * For the fast tlb miss handlers, we currently keep a per cpu array
+- * of pointers to the current pgd for each processor. Also, the proc.
+- * id is stuffed into the context register. This should be changed to
+- * use the processor id via current->processor, where current is stored
+- * in watchhi/lo. The context register should be used to contiguously
+- * map the page tables.
++ * For the fast tlb miss handlers, we keep a per cpu array of pointers
++ * to the current pgd for each processor. Also, the proc. id is stuffed
++ * into the context register.
+  */
++extern unsigned long pgd_current[];
++
+ #define TLBMISS_HANDLER_SETUP_PGD(pgd) \
+ 	pgd_current[smp_processor_id()] = (unsigned long)(pgd)
++
+ #ifdef CONFIG_MIPS32
+-#define TLBMISS_HANDLER_SETUP() \
+-	write_c0_context((unsigned long) smp_processor_id() << 23); \
++#define TLBMISS_HANDLER_SETUP()						\
++	write_c0_context((unsigned long) smp_processor_id() << 23);	\
+ 	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
+ #endif
+-#ifdef CONFIG_MIPS64
+-#define TLBMISS_HANDLER_SETUP() \
++#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
++#define TLBMISS_HANDLER_SETUP()						\
+ 	write_c0_context((unsigned long) &pgd_current[smp_processor_id()] << 23); \
+ 	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
+ #endif
+-extern unsigned long pgd_current[];
++#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64)
++#define TLBMISS_HANDLER_SETUP()						\
++	write_c0_context((unsigned long) smp_processor_id() << 23);	\
++	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
++#endif
+ 
+ #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
+ 
+@@ -150,7 +154,7 @@ static inline void
+ activate_mm(struct mm_struct *prev, struct mm_struct *next)
+ {
+ 	unsigned long flags;
+-	int cpu = smp_processor_id();
++	unsigned int cpu = smp_processor_id();
+ 
+ 	local_irq_save(flags);
+ 
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/ng1.h linux-2.6.10-mips/include/asm-mips/ng1.h
+--- linux-2.6.10/include/asm-mips/ng1.h	2004-12-24 22:35:29.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/ng1.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,55 +0,0 @@
+-/*
+- * This file is subject to the terms and conditions of the GNU General Public
+- * License.  See the file "COPYING" in the main directory of this archive
+- * for more details.
+- *
+- * SGI/Newport video card ioctl definitions
+- */
+-#ifndef _ASM_NG1_H
+-#define _ASM_NG1_H
+-
+-typedef struct {
+-        int flags;
+-        __u16 w, h;
+-        __u16 fields_sec;
+-} ng1_vof_info_t;
+-
+-struct ng1_info {
+-	struct gfx_info gfx_info;
+-	__u8 boardrev;
+-        __u8 rex3rev;
+-        __u8 vc2rev;
+-        __u8 monitortype;
+-        __u8 videoinstalled;
+-        __u8 mcrev;
+-        __u8 bitplanes;
+-        __u8 xmap9rev;
+-        __u8 cmaprev;
+-        ng1_vof_info_t ng1_vof_info;
+-        __u8 bt445rev;
+-        __u8 paneltype;
+-};
+-
+-#define GFX_NAME_NEWPORT "NG1"
+-
+-/* ioctls */
+-#define NG1_SET_CURSOR_HOTSPOT 21001
+-struct ng1_set_cursor_hotspot {
+-	unsigned short xhot;
+-        unsigned short yhot;
+-};
+-
+-#define NG1_SETDISPLAYMODE     21006
+-struct ng1_setdisplaymode_args {
+-        int wid;
+-        unsigned int mode;
+-};
+-
+-#define NG1_SETGAMMARAMP0      21007
+-struct ng1_setgammaramp_args {
+-        unsigned char red   [256];
+-        unsigned char green [256];
+-        unsigned char blue  [256];
+-};
+-
+-#endif /* _ASM_NG1_H */
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/ng1hw.h linux-2.6.10-mips/include/asm-mips/ng1hw.h
+--- linux-2.6.10/include/asm-mips/ng1hw.h	2004-12-24 22:35:22.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/ng1hw.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,219 +0,0 @@
+-/*
+- * ng1hw.h: Tweaks the newport.h structures and definitions to be compatible
+- * 	    with IRIX.  Quite ugly, but it works.
+- *
+- * Copyright (C) 1999 Ulf Carlsson (ulfc at thepuffingroup.com)
+- */
+-#ifndef _SGI_NG1HW_H
+-#define _SGI_NG1HW_H
+-
+-#include <video/newport.h>
+-
+-#define rex3regs	newport_rexregs
+-#define configregs	newport_cregs
+-#define float_long	npfreg_t
+-
+-typedef struct newport_rexregs Rex3regs;
+-typedef struct newport_cregs Configregs;
+-typedef union np_dcb DCB_reg;
+-
+-
+-/* It looks like I can't do a simple tweak with this structure because the IRIX
+- * version is just *too* stupid.  Ok, here's a new version of it..
+- */
+-
+-struct rex3chip {
+-	struct newport_rexregs set;
+-	unsigned long _unused0[0x16e];
+-	struct newport_rexregs go;
+-	unsigned long _unused1[0x22e];
+-	struct {
+-		struct newport_cregs set;
+-		unsigned long _unused2[0x1ef];
+-		struct newport_cregs go;
+-	} p1;
+-};
+-
+-typedef struct rex3chip rex3Chip;
+-typedef struct rex3chip Rex3chip;
+-
+-/* Tweak the defines .. */
+-
+-#define DM0_OPCODE		NPORT_DMODE0_OPMASK
+-#define DM0_NOP			NPORT_DMODE0_NOP
+-#define DM0_READ		NPORT_DMODE0_RD
+-#define DM0_DRAW		NPORT_DMODE0_DRAW
+-#define DM0_SCR2SCR		NPORT_DMODE0_S2S
+-
+-#define DM0_ADRMODE_SHIFT	2
+-#define DM0_ADRMODE		NPORT_DMODE0_AMMASK
+-#define DM0_SPAN		NPORT_DMODE0_SPAN
+-#define DM0_BLOCK		NPORT_DMODE0_BLOCK
+-#define DM0_ILINE		NPORT_DMODE0_ILINE
+-#define DM0_FLINE		NPORT_DMODE0_FLINE
+-#define DM0_ALINE		NPORT_DMODE0_ALINE
+-#define DM0_TLINE		NPORT_DMODE0_TLINE
+-#define DM0_BLINE               NPORT_DMODE0_BLINE
+-
+-#define DM0_DOSETUP		NPORT_DMODE0_DOSETUP
+-#define DM0_COLORHOST		NPORT_DMODE0_CHOST
+-#define DM0_ALPHAHOST		NPORT_DMODE0_AHOST
+-#define DM0_STOPONX		NPORT_DMODE0_STOPX
+-#define DM0_STOPONY		NPORT_DMODE0_STOPY
+-#define DM0_STOPONXY		(NPORT_DMODE0_STOPX | NPORT_DMODE0_STOPY)
+-#define DM0_SKIPFIRST		NPORT_DMODE0_SK1ST
+-#define DM0_SKIPLAST		NPORT_DMODE0_SKLST
+-#define DM0_ENZPATTERN		NPORT_DMODE0_ZPENAB
+-#define DM0_ENLSPATTERN		NPORT_DMODE0_LISPENAB
+-#define DM0_LSADVLAST		NPORT_DMODE0_LISLST
+-#define DM0_LENGTH32		NPORT_DMODE0_L32
+-#define DM0_ZOPAQUE		NPORT_DMODE0_ZOPQ
+-#define DM0_LSOPAQUE		NPORT_DMODE0_LISOPQ
+-#define DM0_SHADE		NPORT_DMODE0_SHADE
+-#define DM0_LRONLY		NPORT_DMODE0_LRONLY
+-#define DM0_XYOFFSET		NPORT_DMODE0_XYOFF
+-#define DM0_CICLAMP		NPORT_DMODE0_CLAMP
+-#define DM0_ENDPTFILTER		NPORT_DMODE0_ENDPF
+-#define	DM0_YSTRIDE		NPORT_DMODE0_YSTR
+-
+-#define DM1_PLANES_SHIFT	0
+-/* The rest of the DM1 planes defines are in newport.h */
+-
+-#define DM1_DRAWDEPTH_SHIFT	3
+-#define DM1_DRAWDEPTH_MASK	NPORT_DMODE1_DDMASK
+-#define DM1_DRAWDEPTH		NPORT_DMODE1_DD24 /* An alias? */
+-#define DM1_DRAWDEPTH4		NPORT_DMODE1_DD4
+-#define DM1_DRAWDEPTH8		NPORT_DMODE1_DD8
+-#define DM1_DRAWDEPTH12		NPORT_DMODE1_DD12
+-#define DM1_DRAWDEPTH24		NPORT_DMODE1_DD24
+-
+-#define DM1_DBLSRC		NPORT_DMODE1_DSRC
+-#define DM1_YFLIP		NPORT_DMODE1_YFLIP
+-#define DM1_RWPACKED		NPORT_DMODE1_RWPCKD
+-
+-#define DM1_HOSTDEPTH_SHIFT 	8
+-#define DM1_HOSTDEPTH_MASK	NPORT_DMODE1_HDMASK
+-#define DM1_HOSTDEPTH		NPORT_DMODE1_HD32 /* An alias? */
+-#define DM1_HOSTDEPTH4		NPORT_DMODE1_HD4
+-#define DM1_HOSTDEPTH8		NPORT_DMODE1_HD8
+-#define DM1_HOSTDEPTH12		NPORT_DMODE1_HD12
+-#define DM1_HOSTDEPTH32		NPORT_DMODE1_HD32
+-
+-#define DM1_RWDOUBLE		NPORT_DMODE1_RWDBL
+-#define DM1_SWAPENDIAN		NPORT_DMODE1_ESWAP
+-
+-#define DM1_COLORCOMPARE_SHIFT	12
+-#define DM1_COLORCOMPARE_MASK	NPORT_DMODE1_CCMASK
+-#define DM1_COLORCOMPARE	NPORT_DMODE1_CCMASK
+-#define DM1_COLORCOMPLT		NPORT_DMODE1_CCLT
+-#define DM1_COLORCOMPEQ		NPORT_DMODE1_CCEQ
+-#define DM1_COLORCOMPGT		NPORT_DMODE1_CCGT
+-
+-#define DM1_RGBMODE		NPORT_DMODE1_RGBMD
+-#define DM1_ENDITHER		NPORT_DMODE1_DENAB
+-#define DM1_FASTCLEAR		NPORT_DMODE1_FCLR
+-#define DM1_ENBLEND		NPORT_DMODE1_BENAB
+-
+-#define DM1_SF_SHIFT		19
+-#define DM1_SF_MASK   		NPORT_DMODE1_SFMASK
+-#define DM1_SF			NPORT_DMODE1_SFMASK
+-#define DM1_SF_ZERO		NPORT_DMODE1_SF0
+-#define DM1_SF_ONE		NPORT_DMODE1_SF1
+-#define DM1_SF_DC		NPORT_DMODE1_SFDC
+-#define DM1_SF_MDC		NPORT_DMODE1_SFMDC
+-#define DM1_SF_SA		NPORT_DMODE1_SFSA
+-#define DM1_SF_MSA		NPORT_DMODE1_SFMSA
+-
+-#define DM1_DF_SHIFT		22	/* dfactor(2:0)	*/
+-#define DM1_DF_MASK		NPORT_DMODE1_DFMASK
+-#define DM1_DF			NPORT_DMODE1_DFMASK
+-#define DM1_DF_ZERO		NPORT_DMODE1_DF0
+-#define DM1_DF_ONE		NPORT_DMODE1_DF1
+-#define DM1_DF_SC		NPORT_DMODE1_DFSC
+-#define DM1_DF_MSC		NPORT_DMODE1_DFMSC
+-#define DM1_DF_SA		NPORT_DMODE1_DFSA
+-#define DM1_DF_MSA		NPORT_DMODE1_DFMSA
+-
+-#define DM1_ENBACKBLEND		NPORT_DMODE1_BBENAB
+-#define DM1_ENPREFETCH		NPORT_DMODE1_PFENAB
+-#define DM1_BLENDALPHA		NPORT_DMODE1_ABLEND
+-
+-#define DM1_LO_SHIFT		28
+-#define DM1_LO			NPORT_DMODE1_LOMASK
+-#define DM1_LO_MASK      	NPORT_DMODE1_LOMASK
+-#define DM1_LO_ZERO		NPORT_DMODE1_LOZERO
+-#define DM1_LO_AND		NPORT_DMODE1_LOAND
+-#define DM1_LO_ANDR		NPORT_DMODE1_LOANDR
+-#define DM1_LO_SRC		NPORT_DMODE1_LOSRC
+-#define DM1_LO_ANDI		NPORT_DMODE1_LOANDI
+-#define DM1_LO_DST		NPORT_DMODE1_LODST
+-#define DM1_LO_XOR		NPORT_DMODE1_LOXOR
+-#define DM1_LO_OR		NPORT_DMODE1_LOOR
+-#define DM1_LO_NOR		NPORT_DMODE1_LONOR
+-#define DM1_LO_XNOR		NPORT_DMODE1_LOXNOR
+-#define DM1_LO_NDST		NPORT_DMODE1_LONDST
+-#define DM1_LO_ORR		NPORT_DMODE1_LOORR
+-#define DM1_LO_NSRC		NPORT_DMODE1_LONSRC
+-#define DM1_LO_ORI		NPORT_DMODE1_LOORI
+-#define DM1_LO_NAND		NPORT_DMODE1_LONAND
+-#define DM1_LO_ONE		NPORT_DMODE1_LOONE
+-
+-#define SMASK0			NPORT_CMODE_SM0
+-#define SMASK1			NPORT_CMODE_SM1
+-#define SMASK2			NPORT_CMODE_SM2
+-#define SMASK3			NPORT_CMODE_SM3
+-#define SMASK4			NPORT_CMODE_SM4
+-#define ALL_SMASKS		0x1f
+-
+-#define CM_CIDMATCH_SHIFT       9
+-#define CM_CIDMATCH_MASK        NPORT_CMODE_CMSK
+-
+-#define REX3VERSION_MASK	NPORT_STAT_VERS
+-#define GFXBUSY        		NPORT_STAT_GBUSY
+-#define BACKBUSY        	NPORT_STAT_BBUSY
+-#define VRINT           	NPORT_STAT_VRINT
+-#define VIDEOINT        	NPORT_STAT_VIDINT
+-#define GFIFO_LEVEL_SHIFT       7
+-#define GFIFO_LEVEL_MASK        NPORT_STAT_GLMSK
+-#define BFIFO_LEVEL_SHIFT       13
+-#define BFIFO_LEVEL_MASK        NPORT_STAT_BLMSK
+-#define BFIFO_INT        	NPORT_STAT_BFIRQ
+-#define GFIFO_INT        	NPORT_STAT_GFIRQ
+-
+-#define GIO32MODE		NPORT_CFG_G32MD
+-#define BUSWIDTH		NPORT_CFG_BWIDTH
+-#define EXTREGXCVR		NPORT_CFG_ERCVR
+-#define BFIFODEPTH_SHIFT	3
+-#define BFIFODEPTH_MASK		NPORT_CFG_BDMSK
+-#define BFIFOABOVEINT		NPORT_CFG_BFAINT
+-#define GFIFODEPTH_SHIFT        8
+-#define GFIFODEPTH_MASK		NPORT_CFG_GDMSK
+-#define GFIFOABOVEINT		NPORT_CFG_GFAINT
+-#define TIMEOUT_SHIFT		14
+-#define TIMEOUT_MASK		NPORT_CFG_TOMSK
+-#define VREFRESH_SHIFT		17
+-#define VREFRESH_MASK		NPORT_CFG_VRMSK
+-#define FB_TYPE			NPORT_CFG_FBTYP
+-
+-#define DCB_DATAWIDTH_MASK	(0x3)
+-
+-#define DCB_CRS_MASK		(0x7 << DCB_CRS_SHIFT)
+-#define DCB_ADDR_MASK		(0xf << DCB_ADDR_SHIFT)
+-#define DCB_CSWIDTH_MASK	(0x1f << DCB_CSWIDTH_SHIFT)
+-#define DCB_CSHOLD_MASK		(0x1f << DCB_CSHOLD_SHIFT)
+-#define DCB_CSSETUP_MASK	(0x1f << DCB_CSSETUP_SHIFT)
+-
+-#define DCB_SWAPENDIAN		(1 << 28)
+-
+-#define REX3WAIT(rex3)  while ((rex3)->p1.set.status & GFXBUSY)
+-#define BFIFOWAIT(rex3)  while ((rex3)->p1.set.status & BACKBUSY)
+-
+-#define REX3_GIO_ADDR_0         0x1f0f0000
+-#define REX3_GIO_ADDR_1         0x1f4f0000
+-#define REX3_GIO_ADDR_2         0x1f8f0000
+-#define REX3_GIO_ADDR_3         0x1fcf0000
+-
+-#define NG1_XSIZE		1280
+-#define NG1_YSIZE		1024
+-
+-#endif
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/pgtable-32.h linux-2.6.10-mips/include/asm-mips/pgtable-32.h
+--- linux-2.6.10/include/asm-mips/pgtable-32.h	2004-12-24 22:34:57.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/pgtable-32.h	2004-12-04 20:57:41.000000000 +0100
+@@ -98,7 +98,7 @@ extern int add_temporary_entry(unsigned 
+ 
+ extern void load_pgd(unsigned long pg_dir);
+ 
+-extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)];
++extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)];
+ 
+ /*
+  * Empty pgd/pmd entries point to the invalid_pte_table.
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/pmon.h linux-2.6.10-mips/include/asm-mips/pmon.h
+--- linux-2.6.10/include/asm-mips/pmon.h	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/pmon.h	2004-12-06 06:36:25.000000000 +0100
+@@ -4,22 +4,43 @@
+  * for more details.
+  *
+  * Copyright (C) 2004 by Ralf Baechle
++ *
++ * The cpustart method is a PMC-Sierra's function to start the secondary CPU.
++ * Stock PMON 2000 has the smpfork, semlock and semunlock methods instead.
+  */
+ #ifndef _ASM_PMON_H
+ #define _ASM_PMON_H
+ 
+ struct callvectors {
+-	int	(*open) (char*, int, int);		/*	 0 */
+-	int	(*close) (int);				/*	 4 */
+-	int	(*read) (int, void*, int);		/*	 8 */
+-	int	(*write) (int, void*, int);		/*	12 */
+-	off_t	(*lseek) (int, off_t, int);		/*	16 */
+-	int	(*printf) (const char*, ...);		/*	20 */
+-	void	(*cacheflush) (void);			/*	24 */
+-	char*	(*gets) (char*);			/*	28 */
+-	int	(*cpustart) (int, void *, int, int);	/*	32 */
++	int	(*open) (char*, int, int);
++	int	(*close) (int);
++	int	(*read) (int, void*, int);
++	int	(*write) (int, void*, int);
++	off_t	(*lseek) (int, off_t, int);
++	int	(*printf) (const char*, ...);
++	void	(*cacheflush) (void);
++	char*	(*gets) (char*);
++	union {
++		int	(*smpfork) (unsigned long cp, char *sp);
++		int	(*cpustart) (long, long, long, long);
++	} _s;
++	int	(*semlock) (int sem);
++	void	(*semunlock) (int sem);
+ };
+ 
+ extern struct callvectors *debug_vectors;
+ 
++#define pmon_open(name, flags, mode)	debug_vectors->open(name, flage, mode)
++#define pmon_close(fd)			debug_vectors->close(fd)
++#define pmon_read(fd, buf, count)	debug_vectors->read(fd, buf, count)
++#define pmon_write(fd, buf, count)	debug_vectors->write(fd, buf, count)
++#define pmon_lseek(fd, off, whence)	debug_vectors->lseek(fd, off, whence)
++#define pmon_printf(fmt...)		debug_vectors->printf(fmt)
++#define pmon_cacheflush()		debug_vectors->cacheflush()
++#define pmon_gets(s)			debug_vectors->gets(s)
++#define pmon_cpustart(n, f, sp, gp)	debug_vectors->_s.cpustart(n, f, sp, gp)
++#define pmon_smpfork(cp, sp)		debug_vectors->_s.smpfork(cp, sp)
++#define pmon_semlock(sem)		debug_vectors->semlock(sem)
++#define pmon_semunlock(sem)		debug_vectors->semunlock(sem)
++
+ #endif /* _ASM_PMON_H */
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/r4kcache.h linux-2.6.10-mips/include/asm-mips/r4kcache.h
+--- linux-2.6.10/include/asm-mips/r4kcache.h	2004-12-24 22:33:51.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/r4kcache.h	2004-12-17 10:36:04.000000000 +0100
+@@ -117,6 +117,21 @@ static inline void protected_writeback_d
+ 		: "i" (Hit_Writeback_Inv_D), "r" (addr));
+ }
+ 
++static inline void protected_writeback_scache_line(unsigned long addr)
++{
++	__asm__ __volatile__(
++		".set noreorder\n\t"
++		".set mips3\n"
++		"1:\tcache %0,(%1)\n"
++		"2:\t.set mips0\n\t"
++		".set reorder\n\t"
++		".section\t__ex_table,\"a\"\n\t"
++		STR(PTR)"\t1b,2b\n\t"
++		".previous"
++		:
++		: "i" (Hit_Writeback_Inv_SD), "r" (addr));
++}
++
+ /*
+  * This one is RM7000-specific
+  */
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/sgi/sgi.h linux-2.6.10-mips/include/asm-mips/sgi/sgi.h
+--- linux-2.6.10/include/asm-mips/sgi/sgi.h	2004-12-24 22:35:14.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/sgi/sgi.h	2004-10-27 02:12:48.000000000 +0200
+@@ -28,8 +28,8 @@ enum sgi_mach {
+ 	ip26,	/* TFP UP, Indigo2 */
+ 	ip27,	/* R10k MP, R12k MP, Origin */
+ 	ip28,	/* R10k UP, Indigo2 */
+-	ip30,
+-	ip32,
++	ip30,	/* Octane */
++	ip32,	/* O2 */
+ };
+ 
+ extern enum sgi_mach sgimach;
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/sibyte/sb1250.h linux-2.6.10-mips/include/asm-mips/sibyte/sb1250.h
+--- linux-2.6.10/include/asm-mips/sibyte/sb1250.h	2004-12-24 22:35:24.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/sibyte/sb1250.h	2005-01-06 23:31:28.000000000 +0100
+@@ -58,6 +58,6 @@ extern void prom_printf(char *fmt, ...);
+ 
+ #endif
+ 
+-#define IOADDR(a) (UNCAC_BASE + (a))
++#define IOADDR(a) (IO_BASE + (a))
+ 
+ #endif
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/sigcontext.h linux-2.6.10-mips/include/asm-mips/sigcontext.h
+--- linux-2.6.10/include/asm-mips/sigcontext.h	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/sigcontext.h	2004-12-21 03:25:28.000000000 +0100
+@@ -41,8 +41,6 @@ struct sigcontext {
+                                                                                 
+ #if _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32
+ 
+-#include <linux/types.h>
+-
+ /*
+  * Keep this struct definition in sync with the sigcontext fragment
+  * in arch/mips/tools/offset.c
+@@ -66,6 +64,9 @@ struct sigcontext {
+ };
+ 
+ #ifdef __KERNEL__
++
++#include <linux/posix_types.h>
++
+ struct sigcontext32 {
+ 	__u32	sc_regmask;		/* Unused */
+ 	__u32	sc_status;
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/sn/mapped_kernel.h linux-2.6.10-mips/include/asm-mips/sn/mapped_kernel.h
+--- linux-2.6.10/include/asm-mips/sn/mapped_kernel.h	2004-12-24 22:34:33.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/sn/mapped_kernel.h	2005-01-09 13:24:02.000000000 +0100
+@@ -23,10 +23,16 @@
+ #include <linux/config.h>
+ #include <asm/addrspace.h>
+ 
++#ifdef CONFIG_BUILD_ELF64
++#define REP_BASE	CAC_BASE
++#else
++#define REP_BASE	CKSEG0
++#endif
++
+ #ifdef CONFIG_MAPPED_KERNEL
+ 
+-#define MAPPED_ADDR_RO_TO_PHYS(x)	(x - CKSSEG)
+-#define MAPPED_ADDR_RW_TO_PHYS(x)	(x - CKSSEG - 16777216)
++#define MAPPED_ADDR_RO_TO_PHYS(x)	(x - REP_BASE)
++#define MAPPED_ADDR_RW_TO_PHYS(x)	(x - REP_BASE - 16777216)
+ 
+ #define MAPPED_KERN_RO_PHYSBASE(n) \
+ 			(PLAT_NODE_DATA(n)->kern_vars.kv_ro_baseaddr)
+@@ -42,8 +48,8 @@
+ 
+ #else /* CONFIG_MAPPED_KERNEL */
+ 
+-#define MAPPED_KERN_RO_TO_PHYS(x)	(x - CKSEG0)
+-#define MAPPED_KERN_RW_TO_PHYS(x)	(x - CKSEG0)
++#define MAPPED_KERN_RO_TO_PHYS(x)	(x - REP_BASE)
++#define MAPPED_KERN_RW_TO_PHYS(x)	(x - REP_BASE)
+ 
+ #endif /* CONFIG_MAPPED_KERNEL */
+ 
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/sn/sn0/hubio.h linux-2.6.10-mips/include/asm-mips/sn/sn0/hubio.h
+--- linux-2.6.10/include/asm-mips/sn/sn0/hubio.h	2004-12-24 22:33:59.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/sn/sn0/hubio.h	2004-12-28 20:07:03.000000000 +0100
+@@ -486,6 +486,7 @@ typedef union h1_icrba_u {
+ #define ICRBN_A_CERR_SHFT	54
+ #define ICRBN_A_ERR_MASK	0x3ff
+ 
++#if 0	/* Disabled, this causes namespace polution and break allmodconfig */
+ /*
+  * Easy access macros.
+  */
+@@ -499,6 +500,7 @@ typedef union h1_icrba_u {
+ #define	a_addr		icrba_fields_s.addr
+ #define	a_valid		icrba_fields_s.valid
+ #define	a_iow		icrba_fields_s.iow
++#endif
+ 
+ #endif /* !__ASSEMBLY__ */
+ 
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/stackframe.h linux-2.6.10-mips/include/asm-mips/stackframe.h
+--- linux-2.6.10/include/asm-mips/stackframe.h	2004-12-24 22:33:49.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/stackframe.h	2005-01-09 13:24:02.000000000 +0100
+@@ -64,7 +64,7 @@
+ 		addu	k1, k0
+ 		LONG_L	k1, %lo(kernelsp)(k1)
+ #endif
+-#ifdef CONFIG_MIPS64
++#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
+ 		MFC0	k1, CP0_CONTEXT
+ 		dsra	k1, 23
+ 		lui	k0, %hi(pgd_current)
+@@ -74,6 +74,12 @@
+ 		daddu	k1, k0
+ 		LONG_L	k1, %lo(kernelsp)(k1)
+ #endif
++#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64)
++		MFC0	k1, CP0_CONTEXT
++		dsrl	k1, 23
++		dsll	k1, k1, 3
++		LONG_L	k1, kernelsp(k1)
++#endif
+ 		.endm
+ 
+ 		.macro	set_saved_sp stackp temp temp2
+@@ -83,13 +89,18 @@
+ 		sll	\temp, 2
+ 		LONG_S	\stackp, kernelsp(\temp)
+ #endif
+-#ifdef CONFIG_MIPS64
++#if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64)
+ 		lw	\temp, TI_CPU(gp)
+ 		dsll	\temp, 3
+ 		lui	\temp2, %hi(kernelsp)
+ 		daddu	\temp, \temp2
+ 		LONG_S	\stackp, %lo(kernelsp)(\temp)
+ #endif
++#if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64)
++		lw	\temp, TI_CPU(gp)
++		dsll	\temp, 3
++		LONG_S	\stackp, kernelsp(\temp)
++#endif
+ 		.endm
+ #else
+ 		.macro	get_saved_sp	/* Uniprocessor variation */
+@@ -104,6 +115,7 @@
+ 
+ 		.macro	SAVE_SOME
+ 		.set	push
++		.set	noat
+ 		.set	reorder
+ 		mfc0	k0, CP0_STATUS
+ 		sll	k0, 3		/* extract cu0 bit */
+@@ -278,16 +290,16 @@
+ 
+ 		.macro	RESTORE_ALL
+ 		RESTORE_TEMP
+-		RESTORE_AT
+ 		RESTORE_STATIC
++		RESTORE_AT
+ 		RESTORE_SOME
+ 		RESTORE_SP
+ 		.endm
+ 
+ 		.macro	RESTORE_ALL_AND_RET
+ 		RESTORE_TEMP
+-		RESTORE_AT
+ 		RESTORE_STATIC
++		RESTORE_AT
+ 		RESTORE_SOME
+ 		RESTORE_SP_AND_RET
+ 		.endm
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/string.h linux-2.6.10-mips/include/asm-mips/string.h
+--- linux-2.6.10/include/asm-mips/string.h	2004-12-24 22:33:48.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/string.h	2004-12-04 20:57:41.000000000 +0100
+@@ -18,6 +18,8 @@
+  */
+ #ifdef CONFIG_MIPS32
+ 
++#ifndef IN_STRING_C
++
+ #define __HAVE_ARCH_STRCPY
+ static __inline__ char *strcpy(char *__dest, __const__ char *__src)
+ {
+@@ -96,6 +98,8 @@ static __inline__ int strcmp(__const__ c
+   return __res;
+ }
+ 
++#endif /* !defined(IN_STRING_C) */
++
+ #define __HAVE_ARCH_STRNCMP
+ static __inline__ int
+ strncmp(__const__ char *__cs, __const__ char *__ct, size_t __count)
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/uaccess.h linux-2.6.10-mips/include/asm-mips/uaccess.h
+--- linux-2.6.10/include/asm-mips/uaccess.h	2004-12-24 22:33:49.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/uaccess.h	2004-11-29 10:28:57.000000000 +0100
+@@ -150,7 +150,7 @@ static inline int verify_area(int type, 
+  * Returns zero on success, or -EFAULT on error.
+  */
+ #define put_user(x,ptr)	\
+-	__put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
++	__put_user_check((x),(ptr),sizeof(*(ptr)))
+ 
+ /*
+  * get_user: - Get a simple variable from user space.
+@@ -170,7 +170,7 @@ static inline int verify_area(int type, 
+  * On error, the variable @x is set to zero.
+  */
+ #define get_user(x,ptr) \
+-	__get_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
++	__get_user_check((x),(ptr),sizeof(*(ptr)))
+ 
+ /*
+  * __put_user: - Write a simple value into user space, with less checking.
+@@ -192,7 +192,7 @@ static inline int verify_area(int type, 
+  * Returns zero on success, or -EFAULT on error.
+  */
+ #define __put_user(x,ptr) \
+-	__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
++	__put_user_nocheck((x),(ptr),sizeof(*(ptr)))
+ 
+ /*
+  * __get_user: - Get a simple variable from user space, with less checking.
+@@ -215,7 +215,7 @@ static inline int verify_area(int type, 
+  * On error, the variable @x is set to zero.
+  */
+ #define __get_user(x,ptr) \
+-	__get_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
++	__get_user_nocheck((x),(ptr),sizeof(*(ptr)))
+ 
+ struct __large_struct { unsigned long buf[100]; };
+ #define __m(x) (*(struct __large_struct *)(x))
+@@ -232,9 +232,10 @@ struct __large_struct { unsigned long bu
+ 
+ #define __get_user_nocheck(x,ptr,size)					\
+ ({									\
+-	long __gu_err = 0;						\
+ 	__typeof(*(ptr)) __gu_val = 0;					\
+ 	long __gu_addr;							\
++	long __gu_err = 0;						\
++									\
+ 	might_sleep();							\
+ 	__gu_addr = (long) (ptr);					\
+ 	switch (size) {							\
+@@ -244,17 +245,18 @@ struct __large_struct { unsigned long bu
+ 	case 8: __GET_USER_DW(__gu_err); break;				\
+ 	default: __get_user_unknown(); break;				\
+ 	}								\
+-	 x = (__typeof__(*(ptr))) __gu_val;				\
++	x = (__typeof__(*(ptr))) __gu_val;				\
+ 	__gu_err;							\
+ })
+ 
+ #define __get_user_check(x,ptr,size)					\
+ ({									\
+ 	__typeof__(*(ptr)) __gu_val = 0;				\
+-	long __gu_addr = (long) (ptr);					\
++	long __gu_addr;							\
+ 	long __gu_err;							\
+ 									\
+ 	might_sleep();							\
++	__gu_addr = (long) (ptr);					\
+ 	__gu_err = verify_area(VERIFY_READ, (void *) __gu_addr, size);	\
+ 									\
+ 	if (likely(!__gu_err)) {					\
+@@ -267,7 +269,7 @@ struct __large_struct { unsigned long bu
+ 		}							\
+ 	}								\
+ 	x = (__typeof__(*(ptr))) __gu_val;				\
+-	 __gu_err;							\
++	__gu_err;							\
+ })
+ 
+ #define __get_user_asm(insn,__gu_err)					\
+@@ -324,9 +326,10 @@ extern void __get_user_unknown(void);
+ 
+ #define __put_user_nocheck(x,ptr,size)					\
+ ({									\
+-	long __pu_err = 0;						\
+ 	__typeof__(*(ptr)) __pu_val;					\
+ 	long __pu_addr;							\
++	long __pu_err = 0;						\
++									\
+ 	might_sleep();							\
+ 	__pu_val = (x);							\
+ 	__pu_addr = (long) (ptr);					\
+@@ -342,11 +345,13 @@ extern void __get_user_unknown(void);
+ 
+ #define __put_user_check(x,ptr,size)					\
+ ({									\
+-	__typeof__(*(ptr)) __pu_val = (x);				\
+-	long __pu_addr = (long) (ptr);					\
++	__typeof__(*(ptr)) __pu_val;					\
++	long __pu_addr;							\
+ 	long __pu_err;							\
+ 									\
+ 	might_sleep();							\
++	__pu_val = (x);							\
++	__pu_addr = (long) (ptr);					\
+ 	__pu_err = verify_area(VERIFY_WRITE, (void *) __pu_addr, size);	\
+ 									\
+ 	if (likely(!__pu_err)) {					\
+diff -urpNX dontdiff linux-2.6.10/include/asm-mips/vr41xx/cmbvr4133.h linux-2.6.10-mips/include/asm-mips/vr41xx/cmbvr4133.h
+--- linux-2.6.10/include/asm-mips/vr41xx/cmbvr4133.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/include/asm-mips/vr41xx/cmbvr4133.h	2004-12-15 15:08:18.000000000 +0100
+@@ -0,0 +1,63 @@
++/*
++ * include/asm-mips/vr41xx/cmbvr4133.h
++ *
++ * Include file for NEC CMB-VR4133.
++ *
++ * Author: Yoichi Yuasa <yyuasa at mvista.com, or source at mvista.com> and
++ *         Jun Sun <jsun at mvista.com, or source at mvista.com> and
++ *         Alex Sapkov <asapkov at ru.mvista.com>
++ *
++ * 2002-2004 (c) MontaVista, Software, Inc. This file is licensed under
++ * the terms of the GNU General Public License version 2. This program
++ * is licensed "as is" without any warranty of any kind, whether express
++ * or implied.
++ */
++#ifndef __NEC_CMBVR4133_H
++#define __NEC_CMBVR4133_H
++
++#include <linux/config.h>
++
++#include <asm/addrspace.h>
++#include <asm/vr41xx/vr41xx.h>
++
++/*
++ * General-Purpose I/O Pin Number
++ */
++#define CMBVR41XX_INTA_PIN		1
++#define CMBVR41XX_INTB_PIN		1
++#define CMBVR41XX_INTC_PIN		3
++#define CMBVR41XX_INTD_PIN		1
++#define CMBVR41XX_INTE_PIN		1
++
++/*
++ * Interrupt Number
++ */
++#define CMBVR41XX_INTA_IRQ		GIU_IRQ(CMBVR41XX_INTA_PIN)
++#define CMBVR41XX_INTB_IRQ		GIU_IRQ(CMBVR41XX_INTB_PIN)
++#define CMBVR41XX_INTC_IRQ		GIU_IRQ(CMBVR41XX_INTC_PIN)
++#define CMBVR41XX_INTD_IRQ		GIU_IRQ(CMBVR41XX_INTD_PIN)
++#define CMBVR41XX_INTE_IRQ		GIU_IRQ(CMBVR41XX_INTE_PIN)
++
++#define I8259_IRQ_BASE			72
++#define I8259_IRQ(x)			(I8259_IRQ_BASE + (x))
++#define TIMER_IRQ			I8259_IRQ(0)
++#define KEYBOARD_IRQ			I8259_IRQ(1)
++#define I8259_SLAVE_IRQ			I8259_IRQ(2)
++#define UART3_IRQ			I8259_IRQ(3)
++#define UART1_IRQ			I8259_IRQ(4)
++#define UART2_IRQ			I8259_IRQ(5)
++#define FDC_IRQ				I8259_IRQ(6)
++#define PARPORT_IRQ			I8259_IRQ(7)
++#define RTC_IRQ				I8259_IRQ(8)
++#define USB_IRQ				I8259_IRQ(9)
++#define I8259_INTA_IRQ			I8259_IRQ(10)
++#define AUDIO_IRQ			I8259_IRQ(11)
++#define AUX_IRQ				I8259_IRQ(12)
++#define IDE_PRIMARY_IRQ			I8259_IRQ(14)
++#define IDE_SECONDARY_IRQ		I8259_IRQ(15)
++#define I8259_IRQ_LAST			IDE_SECONDARY_IRQ
++
++#define RTC_PORT(x)	(0xaf000100 + (x))
++#define RTC_IO_EXTENT	0x140
++
++#endif /* __NEC_CMBVR4133_H */
+diff -urpNX dontdiff linux-2.6.10/include/linux/ac97_codec.h linux-2.6.10-mips/include/linux/ac97_codec.h
+--- linux-2.6.10/include/linux/ac97_codec.h	2004-12-24 22:33:50.000000000 +0100
++++ linux-2.6.10-mips/include/linux/ac97_codec.h	2003-08-04 02:28:52.000000000 +0200
+@@ -176,6 +176,39 @@
+ #define AC97_EXTSTAT_PRK          0x2000
+ #define AC97_EXTSTAT_PRL          0x4000
+ 
++/* extended audio ID register bit defines */
++#define AC97_EXTID_VRA            0x0001
++#define AC97_EXTID_DRA            0x0002
++#define AC97_EXTID_SPDIF          0x0004
++#define AC97_EXTID_VRM            0x0008
++#define AC97_EXTID_DSA0           0x0010
++#define AC97_EXTID_DSA1           0x0020
++#define AC97_EXTID_CDAC           0x0040
++#define AC97_EXTID_SDAC           0x0080
++#define AC97_EXTID_LDAC           0x0100
++#define AC97_EXTID_AMAP           0x0200
++#define AC97_EXTID_REV0           0x0400
++#define AC97_EXTID_REV1           0x0800
++#define AC97_EXTID_ID0            0x4000
++#define AC97_EXTID_ID1            0x8000
++
++/* extended status register bit defines */
++#define AC97_EXTSTAT_VRA          0x0001
++#define AC97_EXTSTAT_DRA          0x0002
++#define AC97_EXTSTAT_SPDIF        0x0004
++#define AC97_EXTSTAT_VRM          0x0008
++#define AC97_EXTSTAT_SPSA0        0x0010
++#define AC97_EXTSTAT_SPSA1        0x0020
++#define AC97_EXTSTAT_CDAC         0x0040
++#define AC97_EXTSTAT_SDAC         0x0080
++#define AC97_EXTSTAT_LDAC         0x0100
++#define AC97_EXTSTAT_MADC         0x0200
++#define AC97_EXTSTAT_SPCV         0x0400
++#define AC97_EXTSTAT_PRI          0x0800
++#define AC97_EXTSTAT_PRJ          0x1000
++#define AC97_EXTSTAT_PRK          0x2000
++#define AC97_EXTSTAT_PRL          0x4000
++
+ /* useful power states */
+ #define AC97_PWR_D0               0x0000      /* everything on */
+ #define AC97_PWR_D1              AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4
+diff -urpNX dontdiff linux-2.6.10/include/linux/ds17287rtc.h linux-2.6.10-mips/include/linux/ds17287rtc.h
+--- linux-2.6.10/include/linux/ds17287rtc.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/include/linux/ds17287rtc.h	2003-04-07 04:28:45.000000000 +0200
+@@ -0,0 +1,68 @@
++/* 
++ * ds17287rtc.h - register definitions for the ds1728[57] RTC / CMOS RAM
++ *
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ * 
++ * (C) 2003 Guido Guenther <agx at sigxcpu.org>
++ *
++ */
++
++#ifndef _DS17287RTC_H
++#define _DS17287RTC_H
++
++#include <asm/io.h>
++#include <linux/rtc.h>			/* get the user-level API */
++#include <linux/spinlock.h>		/* spinlock_t */
++#include <linux/mc146818rtc.h>
++
++/* Register A */
++#define DS_REGA_DV2 0x40		/* countdown chain */
++#define DS_REGA_DV1 0x20		/* oscillator enable */
++#define DS_REGA_DV0 0x10		/* bank select */
++
++/* bank 1 registers */
++#define DS_B1_MODEL	 0x40		/* model number byte */
++#define DS_B1_SN1 	 0x41		/* serial number byte 1 */
++#define DS_B1_SN2 	 0x42		/* serial number byte 2 */
++#define DS_B1_SN3 	 0x43		/* serial number byte 3 */
++#define DS_B1_SN4 	 0x44		/* serial number byte 4 */
++#define DS_B1_SN5 	 0x45		/* serial number byte 5 */
++#define DS_B1_SN6 	 0x46		/* serial number byte 6 */
++#define DS_B1_CRC 	 0x47		/* CRC byte */
++#define DS_B1_CENTURY 	 0x48		/* Century byte */
++#define DS_B1_DALARM 	 0x49		/* date alarm */
++#define DS_B1_XCTRL4A	 0x4a		/* extendec control register 4a */
++#define DS_B1_XCTRL4B	 0x4b		/* extendec control register 4b */
++#define DS_B1_RTCADDR2 	 0x4e		/* rtc address 2 */
++#define DS_B1_RTCADDR3 	 0x4f		/* rtc address 3 */
++#define DS_B1_RAMLSB	 0x50		/* extended ram LSB */
++#define DS_B1_RAMMSB	 0x51		/* extended ram MSB */
++#define DS_B1_RAMDPORT	 0x53		/* extended ram data port */
++
++/* register details */
++/* extended control register 4a */
++#define DS_XCTRL4A_VRT2  0x80 		/* valid ram and time */
++#define DS_XCTRL4A_INCR  0x40		/* increment progress status */
++#define DS_XCTRL4A_BME   0x20		/* burst mode enable */
++#define DS_XCTRL4A_PAB   0x08		/* power active bar ctrl */
++#define DS_XCTRL4A_RF    0x04		/* ram clear flag */
++#define DS_XCTRL4A_WF    0x02		/* wake up alarm flag */
++#define DS_XCTRL4A_KF    0x01		/* kickstart flag */
++/* interrupt causes */
++#define DS_XCTRL4A_IFS	(DS_XCTRL4A_RF|DS_XCTRL4A_WF|DS_XCTRL4A_KF)
++
++/* extended control register 4b */
++#define DS_XCTRL4B_ABE   0x80 		/* auxiliary battery enable */
++#define DS_XCTRL4B_E32K	 0x40		/* enable 32.768 kHz Output */
++#define DS_XCTRL4B_CS    0x20		/* crystal select */
++#define DS_XCTRL4B_RCE   0x10		/* ram clear enable */
++#define DS_XCTRL4B_PRS   0x08		/* PAB resec select */
++#define DS_XCTRL4B_RIE   0x04		/* ram clear interrupt enable */
++#define DS_XCTRL4B_WFE   0x02		/* wake up alarm interrupt enable */
++#define DS_XCTRL4B_KFE   0x01		/* kickstart interrupt enable */
++/* interrupt enable bits */
++#define DS_XCTRL4B_IFES	(DS_XCTRL4B_RIE|DS_XCTRL4B_WFE|DS_XCTRL4B_KFE)
++
++#endif /* _DS17287RTC_H */
+diff -urpNX dontdiff linux-2.6.10/include/linux/ds1742rtc.h linux-2.6.10-mips/include/linux/ds1742rtc.h
+--- linux-2.6.10/include/linux/ds1742rtc.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/include/linux/ds1742rtc.h	2003-11-18 06:15:20.000000000 +0100
+@@ -0,0 +1,53 @@
++/*
++ * ds1742rtc.h - register definitions for the Real-Time-Clock / CMOS RAM
++ *
++ * Copyright (C) 1999-2001 Toshiba Corporation
++ * Copyright (C) 2003 Ralf Baechle (ralf at linux-mips.org)
++ *
++ * Permission is hereby granted to copy, modify and redistribute this code
++ * in terms of the GNU Library General Public License, Version 2 or later,
++ * at your option.
++ */
++#ifndef __LINUX_DS1742RTC_H
++#define __LINUX_DS1742RTC_H
++
++#include <asm/ds1742.h>
++
++#define RTC_BRAM_SIZE		0x800
++#define RTC_OFFSET		0x7f8
++
++/*
++ * Register summary
++ */
++#define RTC_CONTROL		(RTC_OFFSET + 0)
++#define RTC_CENTURY		(RTC_OFFSET + 0)
++#define RTC_SECONDS		(RTC_OFFSET + 1)
++#define RTC_MINUTES		(RTC_OFFSET + 2)
++#define RTC_HOURS		(RTC_OFFSET + 3)
++#define RTC_DAY			(RTC_OFFSET + 4)
++#define RTC_DATE		(RTC_OFFSET + 5)
++#define RTC_MONTH		(RTC_OFFSET + 6)
++#define RTC_YEAR		(RTC_OFFSET + 7)
++
++#define RTC_CENTURY_MASK	0x3f
++#define RTC_SECONDS_MASK	0x7f
++#define RTC_DAY_MASK		0x07
++
++/*
++ * Bits in the Control/Century register
++ */
++#define RTC_WRITE		0x80
++#define RTC_READ		0x40
++
++/*
++ * Bits in the Seconds register
++ */
++#define RTC_STOP		0x80
++
++/*
++ * Bits in the Day register
++ */
++#define RTC_BATT_FLAG		0x80
++#define RTC_FREQ_TEST		0x40
++
++#endif /* __LINUX_DS1742RTC_H */
+diff -urpNX dontdiff linux-2.6.10/include/linux/elf.h linux-2.6.10-mips/include/linux/elf.h
+--- linux-2.6.10/include/linux/elf.h	2004-12-24 22:34:01.000000000 +0100
++++ linux-2.6.10-mips/include/linux/elf.h	2004-10-12 19:31:34.000000000 +0200
+@@ -65,7 +65,7 @@ typedef __s64	Elf64_Sxword;
+ 
+ #define EM_MIPS		8	/* MIPS R3000 (officially, big-endian only) */
+ 
+-#define EM_MIPS_RS4_BE 10	/* MIPS R4000 big-endian */
++#define EM_MIPS_RS3_LE 10	/* MIPS R3000 little-endian */
+ 
+ #define EM_PARISC      15	/* HPPA */
+ 
+diff -urpNX dontdiff linux-2.6.10/include/linux/i2c-algo-sgi.h linux-2.6.10-mips/include/linux/i2c-algo-sgi.h
+--- linux-2.6.10/include/linux/i2c-algo-sgi.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/include/linux/i2c-algo-sgi.h	2003-11-16 09:21:30.000000000 +0100
+@@ -0,0 +1,27 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License version 2 as published by the Free Software Foundation.
++ *
++ * Copyright (C) 2003 Ladislav Michl <ladis at linux-mips.org>
++ */
++
++#ifndef I2C_ALGO_SGI_H
++#define I2C_ALGO_SGI_H 1
++
++#include <linux/i2c.h>
++
++struct i2c_algo_sgi_data {
++	void *data;	/* private data for lowlevel routines */
++	unsigned (*getctrl)(void *data);
++	void (*setctrl)(void *data, unsigned val);
++	unsigned (*rdata)(void *data);
++	void (*wdata)(void *data, unsigned val);
++
++	int xfer_timeout;
++	int ack_timeout;
++};
++
++int i2c_sgi_add_bus(struct i2c_adapter *);
++int i2c_sgi_del_bus(struct i2c_adapter *);
++
++#endif /* I2C_ALGO_SGI_H */
+diff -urpNX dontdiff linux-2.6.10/include/linux/i2c-algo-sibyte.h linux-2.6.10-mips/include/linux/i2c-algo-sibyte.h
+--- linux-2.6.10/include/linux/i2c-algo-sibyte.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/include/linux/i2c-algo-sibyte.h	2003-11-16 09:21:30.000000000 +0100
+@@ -0,0 +1,33 @@
++/*
++ * Copyright (C) 2001,2002,2003 Broadcom Corporation
++ *
++ * 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 I2C_ALGO_SIBYTE_H
++#define I2C_ALGO_SIBYTE_H 1
++
++#include <linux/i2c.h>
++
++struct i2c_algo_sibyte_data {
++	void *data;		/* private data */
++        int   bus;		/* which bus */
++        void *reg_base;		/* CSR base */
++};
++
++int i2c_sibyte_add_bus(struct i2c_adapter *, int speed);
++int i2c_sibyte_del_bus(struct i2c_adapter *);
++
++#endif /* I2C_ALGO_SIBYTE_H */
+diff -urpNX dontdiff linux-2.6.10/include/linux/i2c-id.h linux-2.6.10-mips/include/linux/i2c-id.h
+--- linux-2.6.10/include/linux/i2c-id.h	2004-12-24 22:33:50.000000000 +0100
++++ linux-2.6.10-mips/include/linux/i2c-id.h	2004-09-21 13:12:02.000000000 +0200
+@@ -109,6 +109,7 @@
+ #define I2C_DRIVERID_OVCAMCHIP	61	/* OmniVision CMOS image sens.	*/
+ #define I2C_DRIVERID_TDA7313	62	/* TDA7313 audio processor	*/
+ #define I2C_DRIVERID_MAX6900	63	/* MAX6900 real-time clock	*/
++#define I2C_DRIVERID_SAA7114H	64	/* video decoder		*/
+ 
+ 
+ #define I2C_DRIVERID_EXP0	0xF0	/* experimental use id's	*/
+@@ -196,6 +197,9 @@
+ #define I2C_ALGO_OCP_IOP3XX  0x140000	/* XSCALE IOP3XX On-chip I2C alg */
+ #define I2C_ALGO_PCA	0x150000	/* PCA 9564 style adapters	*/
+ 
++#define I2C_ALGO_SIBYTE 0x150000	/* Broadcom SiByte SOCs		*/
++#define I2C_ALGO_SGI	0x160000        /* SGI algorithm                */
++
+ #define I2C_ALGO_EXP	0x800000	/* experimental			*/
+ 
+ #define I2C_ALGO_MASK	0xff0000	/* Mask for algorithms		*/
+@@ -258,6 +262,13 @@
+ /* --- PowerPC on-chip adapters						*/
+ #define I2C_HW_OCP 0x00	/* IBM on-chip I2C adapter 	*/
+ 
++/* --- Broadcom SiByte adapters						*/
++#define I2C_HW_SIBYTE	0x00
++
++/* --- SGI adapters							*/
++#define I2C_HW_SGI_VINO	0x00
++#define I2C_HW_SGI_MACE	0x01
++
+ /* --- XSCALE on-chip adapters                          */
+ #define I2C_HW_IOP321 0x00
+ 
+diff -urpNX dontdiff linux-2.6.10/include/linux/init.h linux-2.6.10-mips/include/linux/init.h
+--- linux-2.6.10/include/linux/init.h	2004-12-24 22:33:50.000000000 +0100
++++ linux-2.6.10-mips/include/linux/init.h	2004-09-21 13:12:02.000000000 +0200
+@@ -86,6 +86,8 @@ extern char saved_command_line[];
+ 	static initcall_t __initcall_##fn __attribute_used__ \
+ 	__attribute__((__section__(".initcall" level ".init"))) = fn
+ 
++#define early_initcall(fn)		__define_initcall(".early1",fn)
++
+ #define core_initcall(fn)		__define_initcall("1",fn)
+ #define postcore_initcall(fn)		__define_initcall("2",fn)
+ #define arch_initcall(fn)		__define_initcall("3",fn)
+diff -urpNX dontdiff linux-2.6.10/include/linux/init_task.h linux-2.6.10-mips/include/linux/init_task.h
+--- linux-2.6.10/include/linux/init_task.h	2004-12-24 22:33:52.000000000 +0100
++++ linux-2.6.10-mips/include/linux/init_task.h	2004-12-21 03:25:28.000000000 +0100
+@@ -55,7 +55,7 @@
+ 
+ #define INIT_SIGHAND(sighand) {	\
+ 	.count		= ATOMIC_INIT(1), 		\
+-	.action		= { {{NULL,}}, },		\
++	.action		= { {{ .sa_handler = NULL,}}, },		\
+ 	.siglock	= SPIN_LOCK_UNLOCKED, 		\
+ }
+ 
+diff -urpNX dontdiff linux-2.6.10/include/linux/mc146818rtc.h linux-2.6.10-mips/include/linux/mc146818rtc.h
+--- linux-2.6.10/include/linux/mc146818rtc.h	2004-12-24 22:35:25.000000000 +0100
++++ linux-2.6.10-mips/include/linux/mc146818rtc.h	2004-12-04 20:57:43.000000000 +0100
+@@ -89,4 +89,12 @@ extern spinlock_t rtc_lock;		/* serializ
+ # define RTC_VRT 0x80		/* valid RAM and time */
+ /**********************************************************************/
+ 
++#ifndef RTC_IO_EXTENT
++#define RTC_IO_EXTENT	0x8
++#endif
++
++#ifndef RTC_IOMAPPED
++#define RTC_IOMAPPED	1	/* Default to I/O mapping. */
++#endif
++
+ #endif /* _MC146818RTC_H */
+diff -urpNX dontdiff linux-2.6.10/include/linux/pci.h linux-2.6.10-mips/include/linux/pci.h
+--- linux-2.6.10/include/linux/pci.h	2004-12-24 22:34:44.000000000 +0100
++++ linux-2.6.10-mips/include/linux/pci.h	2004-11-21 16:28:14.000000000 +0100
+@@ -1011,7 +1011,7 @@ enum pci_fixup_pass {
+ 
+ /* Anonymous variables would be nice... */
+ #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook)	\
+-	static struct pci_fixup __pci_fixup_##name __attribute_used__	\
++	static const struct pci_fixup __pci_fixup_##name __attribute_used__ \
+ 	__attribute__((__section__(#section))) = { vendor, device, hook };
+ #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook)			\
+ 	DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early,			\
+diff -urpNX dontdiff linux-2.6.10/include/linux/pci_ids.h linux-2.6.10-mips/include/linux/pci_ids.h
+--- linux-2.6.10/include/linux/pci_ids.h	2004-12-24 22:35:50.000000000 +0100
++++ linux-2.6.10-mips/include/linux/pci_ids.h	2004-12-28 20:07:07.000000000 +0100
+@@ -569,6 +569,7 @@
+ #define PCI_DEVICE_ID_NEC_CBUS_2	0x002d /* PCI-Cbus Bridge */
+ #define PCI_DEVICE_ID_NEC_USB		0x0035 /* PCI-USB Host */
+ #define PCI_DEVICE_ID_NEC_CBUS_3	0x003b
++#define PCI_DEVICE_ID_NEC_NAPCCARD	0x003e
+ #define PCI_DEVICE_ID_NEC_PCX2		0x0046 /* PowerVR */
+ #define PCI_DEVICE_ID_NEC_NILE4		0x005a
+ #define PCI_DEVICE_ID_NEC_VRC5476       0x009b
+@@ -1016,6 +1017,7 @@
+ #define PCI_DEVICE_ID_AL_M1523		0x1523
+ #define PCI_DEVICE_ID_AL_M1531		0x1531
+ #define PCI_DEVICE_ID_AL_M1533		0x1533
++#define PCI_DEVICE_ID_AL_M1535 		0x1535
+ #define PCI_DEVICE_ID_AL_M1541		0x1541
+ #define PCI_DEVICE_ID_AL_M1563		0x1563
+ #define PCI_DEVICE_ID_AL_M1621		0x1621
+@@ -1906,6 +1908,9 @@
+ #define PCI_DEVICE_ID_PANACOM_QUADMODEM	0x0400
+ #define PCI_DEVICE_ID_PANACOM_DUALMODEM	0x0402
+ 
++#define PCI_VENDOR_ID_SIPACKETS		0x14d9
++#define PCI_DEVICE_ID_SP_HT		0x0010
++
+ #define PCI_VENDOR_ID_AFAVLAB		0x14db
+ #define PCI_DEVICE_ID_AFAVLAB_P028	0x2180
+ #define PCI_DEVICE_ID_AFAVLAB_P030	0x2182
+@@ -1989,6 +1994,9 @@
+ #define PCI_DEVICE_ID_FARSITE_TE1       0x1610
+ #define PCI_DEVICE_ID_FARSITE_TE1C      0x1612
+ 
++#define PCI_VENDOR_ID_SIBYTE		0x166d
++#define PCI_DEVICE_ID_BCM1250_HT	0x0002
++
+ #define PCI_VENDOR_ID_LINKSYS		0x1737
+ #define PCI_DEVICE_ID_LINKSYS_EG1032	0x1032
+ #define PCI_DEVICE_ID_LINKSYS_EG1064	0x1064
+@@ -2280,6 +2288,7 @@
+ #define PCI_DEVICE_ID_INTEL_IXP4XX	0x8500
+ #define PCI_DEVICE_ID_INTEL_IXP2400	0x9001
+ #define PCI_DEVICE_ID_INTEL_IXP2800	0x9004
++#define PCI_DEVICE_ID_INTEL_S21152BB	0xb152
+ 
+ #define PCI_VENDOR_ID_COMPUTONE		0x8e0e
+ #define PCI_DEVICE_ID_COMPUTONE_IP2EX	0x0291
+diff -urpNX dontdiff linux-2.6.10/include/linux/serial.h linux-2.6.10-mips/include/linux/serial.h
+--- linux-2.6.10/include/linux/serial.h	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/include/linux/serial.h	2004-12-23 22:54:30.000000000 +0100
+@@ -75,7 +75,8 @@ struct serial_struct {
+ #define PORT_16654	11
+ #define PORT_16850	12
+ #define PORT_RSA	13	/* RSA-DV II/S card */
+-#define PORT_MAX	13
++#define PORT_SB1250	14
++#define PORT_MAX	14
+ 
+ #define SERIAL_IO_PORT	0
+ #define SERIAL_IO_HUB6	1
+diff -urpNX dontdiff linux-2.6.10/include/video/maxinefb.h linux-2.6.10-mips/include/video/maxinefb.h
+--- linux-2.6.10/include/video/maxinefb.h	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/include/video/maxinefb.h	2003-06-05 12:06:43.000000000 +0200
+@@ -8,17 +8,18 @@
+  *      archive for more details.
+  */
+ 
++#include <asm/addrspace.h>
+ 
+ /*
+  * IMS332 video controller register base address
+  */
+-#define MAXINEFB_IMS332_ADDRESS                  0xbc140000
++#define MAXINEFB_IMS332_ADDRESS		KSEG1ADDR(0x1c140000)
+ 
+ /*
+  * Begin of DECstation 5000/xx onboard framebuffer memory, default resolution
+  * is 1024x768x8
+  */
+-#define DS5000_xx_ONBOARD_FBMEM_START	0xaa000000
++#define DS5000_xx_ONBOARD_FBMEM_START	KSEG1ADDR(0x0a000000)
+ 
+ /*
+  *      The IMS 332 video controller used in the DECstation 5000/xx series
+diff -urpNX dontdiff linux-2.6.10/include/video/newport.h linux-2.6.10-mips/include/video/newport.h
+--- linux-2.6.10/include/video/newport.h	2004-12-24 22:35:00.000000000 +0100
++++ linux-2.6.10-mips/include/video/newport.h	2004-12-10 17:11:02.000000000 +0100
+@@ -291,8 +291,6 @@ struct newport_regs {
+ 	unsigned int _unused2[0x1ef];
+ 	struct newport_cregs cgo;
+ };
+-extern struct newport_regs *npregs;
+-
+ 
+ typedef struct {
+ 	unsigned int drawmode1;
+@@ -450,38 +448,26 @@ static __inline__ void newport_cmap_setr
+ 
+ /* Miscellaneous NEWPORT routines. */
+ #define BUSY_TIMEOUT 100000
+-static __inline__ int newport_wait(void)
++static __inline__ int newport_wait(struct newport_regs *regs)
+ {
+-	int i = 0;
++	int t = BUSY_TIMEOUT;
+ 
+-	while(i < BUSY_TIMEOUT)
+-		if(!(npregs->cset.status & NPORT_STAT_GBUSY))
++	while (t--)
++		if (!(regs->cset.status & NPORT_STAT_GBUSY))
+ 			break;
+-	if(i == BUSY_TIMEOUT)
+-		return 1;
+-	return 0;
++	return !t;
+ }
+ 
+-static __inline__ int newport_bfwait(void)
++static __inline__ int newport_bfwait(struct newport_regs *regs)
+ {
+-	int i = 0;
++	int t = BUSY_TIMEOUT;
+ 
+-	while(i < BUSY_TIMEOUT)
+-		if(!(npregs->cset.status & NPORT_STAT_BBUSY))
++	while (t--)
++		if(!(regs->cset.status & NPORT_STAT_BBUSY))
+ 			break;
+-	if(i == BUSY_TIMEOUT)
+-		return 1;
+-	return 0;
++	return !t;
+ }
+ 
+-/* newport.c and cons_newport.c routines */
+-extern struct graphics_ops *newport_probe (int, const char **);
+-
+-void newport_save    (void *);
+-void newport_restore (void *);
+-void newport_reset   (void);
+-int  newport_ioctl   (int card, int cmd, unsigned long arg);
+-
+ /*
+  * DCBMODE register defines:
+  */
+@@ -564,7 +550,7 @@ xmap9FIFOWait (struct newport_regs *rex)
+ {
+         rex->set.dcbmode = DCB_XMAP0 | XM9_CRS_FIFO_AVAIL |
+ 		DCB_DATAWIDTH_1 | R_DCB_XMAP9_PROTOCOL;
+-        newport_bfwait ();
++        newport_bfwait (rex);
+ 	
+         while ((rex->set.dcbdata0.bybytes.b3 & 3) != XM9_FIFO_EMPTY)
+ 		;
+diff -urpNX dontdiff linux-2.6.10/lib/string.c linux-2.6.10-mips/lib/string.c
+--- linux-2.6.10/lib/string.c	2004-12-24 22:35:25.000000000 +0100
++++ linux-2.6.10-mips/lib/string.c	2004-09-21 13:12:10.000000000 +0200
+@@ -444,7 +444,7 @@ EXPORT_SYMBOL(strsep);
+  *
+  * Do not use memset() to access IO space, use memset_io() instead.
+  */
+-void * memset(void * s,int c,size_t count)
++void * memset(void * s,int c, size_t count)
+ {
+ 	char *xs = (char *) s;
+ 
+@@ -566,14 +566,15 @@ EXPORT_SYMBOL(memcmp);
+ void * memscan(void * addr, int c, size_t size)
+ {
+ 	unsigned char * p = (unsigned char *) addr;
++	unsigned char * e = p + size;
+ 
+-	while (size) {
+-		if (*p == c)
++	while (p != e) {
++		if (*p == (unsigned char)c)
+ 			return (void *) p;
+ 		p++;
+-		size--;
+ 	}
+-  	return (void *) p;
++
++	return (void *) p;
+ }
+ EXPORT_SYMBOL(memscan);
+ #endif
+diff -urpNX dontdiff linux-2.6.10/net/ax25/af_ax25.c linux-2.6.10-mips/net/ax25/af_ax25.c
+--- linux-2.6.10/net/ax25/af_ax25.c	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/net/ax25/af_ax25.c	2004-11-19 01:15:13.000000000 +0100
+@@ -1681,16 +1681,12 @@ static int ax25_ioctl(struct socket *soc
+ 		/* These two are safe on a single CPU system as only user tasks fiddle here */
+ 		if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
+ 			amount = skb->len;
+-		res = put_user(amount, (int __user *)argp);
++		res = put_user(amount, (int __user *) argp);
+ 		break;
+ 	}
+ 
+ 	case SIOCGSTAMP:
+-		if (sk != NULL) {
+-			res = sock_get_timestamp(sk, argp);
+-			break;
+-	 	}
+-		res = -EINVAL;
++		res = sock_get_timestamp(sk, arg);
+ 		break;
+ 
+ 	case SIOCAX25ADDUID:	/* Add a uid to the uid/call map table */
+diff -urpNX dontdiff linux-2.6.10/net/netrom/af_netrom.c linux-2.6.10-mips/net/netrom/af_netrom.c
+--- linux-2.6.10/net/netrom/af_netrom.c	2004-12-24 22:34:45.000000000 +0100
++++ linux-2.6.10-mips/net/netrom/af_netrom.c	2004-10-12 19:31:43.000000000 +0200
+@@ -1176,7 +1176,7 @@ static int nr_ioctl(struct socket *sock,
+ {
+ 	struct sock *sk = sock->sk;
+ 	void __user *argp = (void __user *)arg;
+-	int ret;
++	int ret = 0;
+ 
+ 	lock_sock(sk);
+ 	switch (cmd) {
+@@ -1200,9 +1200,7 @@ static int nr_ioctl(struct socket *sock,
+ 	}
+ 
+ 	case SIOCGSTAMP:
+-		ret = -EINVAL;
+-		if (sk != NULL)
+-			ret = sock_get_timestamp(sk, argp);
++		ret = sock_get_timestamp(sk, argp);
+ 		release_sock(sk);
+ 		return ret;
+ 
+diff -urpNX dontdiff linux-2.6.10/net/netrom/nr_dev.c linux-2.6.10-mips/net/netrom/nr_dev.c
+--- linux-2.6.10/net/netrom/nr_dev.c	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/net/netrom/nr_dev.c	2004-03-23 20:44:20.000000000 +0100
+@@ -46,7 +46,7 @@
+ 
+ int nr_rx_ip(struct sk_buff *skb, struct net_device *dev)
+ {
+-	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
++	struct net_device_stats *stats = netdev_priv(dev);
+ 
+ 	if (!netif_running(dev)) {
+ 		stats->rx_errors++;
+@@ -73,7 +73,7 @@ int nr_rx_ip(struct sk_buff *skb, struct
+ static int nr_rebuild_header(struct sk_buff *skb)
+ {
+ 	struct net_device *dev = skb->dev;
+-	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
++	struct net_device_stats *stats = netdev_priv(dev);
+ 	struct sk_buff *skbn;
+ 	unsigned char *bp = skb->data;
+ 	int len;
+@@ -186,7 +186,7 @@ static int nr_close(struct net_device *d
+ 
+ static int nr_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+-	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
++	struct net_device_stats *stats = netdev_priv(dev);
+ 	dev_kfree_skb(skb);
+ 	stats->tx_errors++;
+ 	return 0;
+@@ -194,7 +194,7 @@ static int nr_xmit(struct sk_buff *skb, 
+ 
+ static struct net_device_stats *nr_get_stats(struct net_device *dev)
+ {
+-	return (struct net_device_stats *)dev->priv;
++	return netdev_priv(dev);
+ }
+ 
+ void nr_setup(struct net_device *dev)
+diff -urpNX dontdiff linux-2.6.10/net/rose/af_rose.c linux-2.6.10-mips/net/rose/af_rose.c
+--- linux-2.6.10/net/rose/af_rose.c	2004-12-24 22:34:45.000000000 +0100
++++ linux-2.6.10-mips/net/rose/af_rose.c	2004-10-12 19:31:43.000000000 +0200
+@@ -1249,6 +1249,7 @@ static int rose_ioctl(struct socket *soc
+ 	struct sock *sk = sock->sk;
+ 	rose_cb *rose = rose_sk(sk);
+ 	void __user *argp = (void __user *)arg;
++	int err = 0;
+ 
+ 	switch (cmd) {
+ 	case TIOCOUTQ: {
+@@ -1256,7 +1257,7 @@ static int rose_ioctl(struct socket *soc
+ 		amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
+ 		if (amount < 0)
+ 			amount = 0;
+-		return put_user(amount, (unsigned int __user *)argp);
++		return put_user(amount, (int __user *)argp);
+ 	}
+ 
+ 	case TIOCINQ: {
+@@ -1265,13 +1266,11 @@ static int rose_ioctl(struct socket *soc
+ 		/* These two are safe on a single CPU system as only user tasks fiddle here */
+ 		if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
+ 			amount = skb->len;
+-		return put_user(amount, (unsigned int __user *)argp);
++		return put_user(amount, (int __user *)argp);
+ 	}
+ 
+ 	case SIOCGSTAMP:
+-		if (sk != NULL) 
+-			return sock_get_timestamp(sk, (struct timeval __user *)argp);
+-		return -EINVAL;
++		return sock_get_timestamp(sk, (struct timeval __user *)argp);
+ 
+ 	case SIOCGIFADDR:
+ 	case SIOCSIFADDR:
+@@ -1338,7 +1337,7 @@ static int rose_ioctl(struct socket *soc
+ 		return dev_ioctl(cmd, argp);
+ 	}
+ 
+-	return 0;
++	return err;
+ }
+ 
+ #ifdef CONFIG_PROC_FS
+diff -urpNX dontdiff linux-2.6.10/net/rose/rose_dev.c linux-2.6.10-mips/net/rose/rose_dev.c
+--- linux-2.6.10/net/rose/rose_dev.c	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/net/rose/rose_dev.c	2004-03-23 20:44:20.000000000 +0100
+@@ -43,7 +43,7 @@
+ 
+ int rose_rx_ip(struct sk_buff *skb, struct net_device *dev)
+ {
+-	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
++	struct net_device_stats *stats = netdev_priv(dev);
+ 
+ #ifdef CONFIG_INET
+ 	if (!netif_running(dev)) {
+@@ -89,7 +89,7 @@ static int rose_header(struct sk_buff *s
+ static int rose_rebuild_header(struct sk_buff *skb)
+ {
+ 	struct net_device *dev = skb->dev;
+-	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
++	struct net_device_stats *stats = netdev_priv(dev);
+ 	unsigned char *bp = (unsigned char *)skb->data;
+ 	struct sk_buff *skbn;
+ 
+@@ -149,7 +149,7 @@ static int rose_close(struct net_device 
+ 
+ static int rose_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+-	struct net_device_stats *stats = (struct net_device_stats *)dev->priv;
++	struct net_device_stats *stats = netdev_priv(dev);
+ 
+ 	if (!netif_running(dev)) {
+ 		printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n");
+@@ -162,7 +162,7 @@ static int rose_xmit(struct sk_buff *skb
+ 
+ static struct net_device_stats *rose_get_stats(struct net_device *dev)
+ {
+-	return (struct net_device_stats *)dev->priv;
++	return netdev_priv(dev);
+ }
+ 
+ void rose_setup(struct net_device *dev)
+diff -urpNX dontdiff linux-2.6.10/scripts/genksyms/Makefile linux-2.6.10-mips/scripts/genksyms/Makefile
+--- linux-2.6.10/scripts/genksyms/Makefile	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/scripts/genksyms/Makefile	2004-09-21 13:12:23.000000000 +0200
+@@ -47,3 +47,5 @@ clean-files	+= parse.output
+ endif
+ 
+ targets += keywords.c lex.c parse.c parse.h
++
++clean-files := keywords.c lex.c parse.c parse.h
+diff -urpNX dontdiff linux-2.6.10/scripts/reference_discarded.pl linux-2.6.10-mips/scripts/reference_discarded.pl
+--- linux-2.6.10/scripts/reference_discarded.pl	2004-12-24 22:34:33.000000000 +0100
++++ linux-2.6.10-mips/scripts/reference_discarded.pl	2004-11-19 01:15:20.000000000 +0100
+@@ -90,6 +90,7 @@ foreach $object (keys(%object)) {
+ 		     $from !~ /\.data\.exit$/ &&
+ 		     $from !~ /\.exit\.data$/ &&
+ 		     $from !~ /\.altinstructions$/ &&
++		     $from !~ /\.pdr$/ &&
+ 		     $from !~ /\.debug_info$/ &&
+ 		     $from !~ /\.debug_aranges$/ &&
+ 		     $from !~ /\.debug_ranges$/ &&
+diff -urpNX dontdiff linux-2.6.10/scripts/reference_init.pl linux-2.6.10-mips/scripts/reference_init.pl
+--- linux-2.6.10/scripts/reference_init.pl	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/scripts/reference_init.pl	2004-11-19 05:27:08.000000000 +0100
+@@ -95,6 +95,7 @@ foreach $object (sort(keys(%object))) {
+ 		     $from !~ /\.text\.lock$/ &&
+ 		     $from !~ /\.pci_fixup_header$/ &&
+ 		     $from !~ /\.pci_fixup_final$/ &&
++		     $from !~ /\.pdr$/ &&
+ 		     $from !~ /\__param$/ &&
+ 		     $from !~ /\.debug_/)) {
+ 			printf("Error: %s %s refers to %s\n", $object, $from, $line);
+diff -urpNX dontdiff linux-2.6.10/sound/Kconfig linux-2.6.10-mips/sound/Kconfig
+--- linux-2.6.10/sound/Kconfig	2004-12-24 22:35:28.000000000 +0100
++++ linux-2.6.10-mips/sound/Kconfig	2004-10-27 13:21:20.000000000 +0200
+@@ -55,6 +55,8 @@ source "sound/ppc/Kconfig"
+ 
+ source "sound/arm/Kconfig"
+ 
++source "sound/mips/Kconfig"
++
+ # the following will depenend on the order of config.
+ # here assuming USB is defined before ALSA
+ source "sound/usb/Kconfig"
+diff -urpNX dontdiff linux-2.6.10/sound/Makefile linux-2.6.10-mips/sound/Makefile
+--- linux-2.6.10/sound/Makefile	2004-12-24 22:34:30.000000000 +0100
++++ linux-2.6.10-mips/sound/Makefile	2004-10-27 13:21:20.000000000 +0200
+@@ -4,7 +4,7 @@
+ obj-$(CONFIG_SOUND) += soundcore.o
+ obj-$(CONFIG_SOUND_PRIME) += oss/
+ obj-$(CONFIG_DMASOUND) += oss/
+-obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/
++obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/
+ 
+ ifeq ($(CONFIG_SND),y)
+   obj-y += last.o
+diff -urpNX dontdiff linux-2.6.10/sound/mips/Kconfig linux-2.6.10-mips/sound/mips/Kconfig
+--- linux-2.6.10/sound/mips/Kconfig	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/sound/mips/Kconfig	2004-10-27 07:12:38.000000000 +0200
+@@ -0,0 +1,15 @@
++# ALSA MIPS drivers
++
++menu "ALSA MIPS devices"
++	depends on SND!=n && MIPS
++
++config SND_AU1X00
++	tristate "Au1x00 AC97 Port Driver"
++	depends on (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && SND
++	select SND_PCM
++	select SND_AC97_CODEC
++	help
++	  ALSA Sound driver for the Au1x00's AC97 port.
++
++endmenu
++
+diff -urpNX dontdiff linux-2.6.10/sound/mips/Makefile linux-2.6.10-mips/sound/mips/Makefile
+--- linux-2.6.10/sound/mips/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/sound/mips/Makefile	2004-10-27 07:10:46.000000000 +0200
+@@ -0,0 +1,8 @@
++#
++# Makefile for ALSA
++#
++
++snd-au1x00-objs := au1x00.o
++
++# Toplevel Module Dependency
++obj-$(CONFIG_SND_AU1X00) += snd-au1x00.o
+diff -urpNX dontdiff linux-2.6.10/sound/mips/au1x00.c linux-2.6.10-mips/sound/mips/au1x00.c
+--- linux-2.6.10/sound/mips/au1x00.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/sound/mips/au1x00.c	2004-10-27 07:10:46.000000000 +0200
+@@ -0,0 +1,686 @@
++/*
++ * BRIEF MODULE DESCRIPTION
++ *  Driver for AMD Au1000 MIPS Processor, AC'97 Sound Port
++ *
++ * Copyright 2004 Cooper Street Innovations Inc.
++ * Author: Charles Eidsness	<charles at cooper-street.com>
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ *
++ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  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.
++ *
++ * History:
++ *
++ * 2004-09-09 Charles Eidsness	-- Original verion -- based on
++ * 				  sa11xx-uda1341.c ALSA driver and the
++ *				  au1000.c OSS driver.
++ * 2004-09-09 Matt Porter	-- Added support for ALSA 1.0.6
++ *
++ */
++
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <sound/driver.h>
++#include <linux/init.h>
++#include <linux/slab.h>
++#include <linux/version.h>
++#include <sound/core.h>
++#include <sound/initval.h>
++#include <sound/pcm.h>
++#include <sound/ac97_codec.h>
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-au1x00/au1000_dma.h>
++
++MODULE_AUTHOR("Charles Eidsness <charles at cooper-street.com>");
++MODULE_DESCRIPTION("Au1000 AC'97 ALSA Driver");
++MODULE_LICENSE("GPL");
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
++MODULE_SUPPORTED_DEVICE("{{AMD,Au1000 AC'97}}");
++#else
++MODULE_CLASSES("{sound}");
++MODULE_DEVICES("{{AMD,Au1000 AC'97}}");
++#endif
++
++#define chip_t au1000_t
++
++#define PLAYBACK 0
++#define CAPTURE 1
++#define AC97_SLOT_3 0x01
++#define AC97_SLOT_4 0x02
++#define AC97_SLOT_6 0x08
++#define AC97_CMD_IRQ 31
++#define READ 0
++#define WRITE 1
++#define READ_WAIT 2
++#define RW_DONE 3
++
++DECLARE_WAIT_QUEUE_HEAD(ac97_command_wq);
++
++typedef struct au1000_period au1000_period_t;
++struct au1000_period
++{
++	u32 start;
++	u32 relative_end;	/*realtive to start of buffer*/
++	au1000_period_t * next;
++};
++
++/*Au1000 AC97 Port Control Reisters*/
++typedef struct au1000_ac97_reg au1000_ac97_reg_t;
++struct au1000_ac97_reg {
++	u32 volatile config;
++	u32 volatile status;
++	u32 volatile data;
++	u32 volatile cmd;
++	u32 volatile cntrl;
++};
++
++typedef struct audio_stream audio_stream_t;
++struct audio_stream {
++	snd_pcm_substream_t * substream;
++	int dma;
++	spinlock_t dma_lock;
++	au1000_period_t * buffer;
++	unsigned long period_size;
++};
++
++typedef struct snd_card_au1000 {
++	snd_card_t *card;
++	au1000_ac97_reg_t volatile *ac97_ioport;
++	
++	struct resource *ac97_res_port;
++	spinlock_t ac97_lock;
++	ac97_t *ac97;
++
++	snd_pcm_t *pcm;
++	audio_stream_t *stream[2];	/* playback & capture */
++} au1000_t;
++
++static au1000_t *au1000 = NULL;
++
++/*--------------------------- Local Functions --------------------------------*/
++static void
++au1000_set_ac97_xmit_slots(long xmit_slots)
++{
++	u32 volatile ac97_config;
++
++	spin_lock(&au1000->ac97_lock);
++	ac97_config = au1000->ac97_ioport->config;
++	ac97_config = ac97_config & ~AC97C_XMIT_SLOTS_MASK;
++	ac97_config |= (xmit_slots << AC97C_XMIT_SLOTS_BIT);
++	au1000->ac97_ioport->config = ac97_config;
++	spin_unlock(&au1000->ac97_lock);
++}
++
++static void
++au1000_set_ac97_recv_slots(long recv_slots)
++{
++	u32 volatile ac97_config;
++
++	spin_lock(&au1000->ac97_lock);
++	ac97_config = au1000->ac97_ioport->config;
++	ac97_config = ac97_config & ~AC97C_RECV_SLOTS_MASK;
++	ac97_config |= (recv_slots << AC97C_RECV_SLOTS_BIT);
++	au1000->ac97_ioport->config = ac97_config;
++	spin_unlock(&au1000->ac97_lock);
++}
++
++
++static void
++au1000_dma_stop(audio_stream_t *stream)
++{
++	unsigned long   flags;
++	au1000_period_t * pointer;
++	au1000_period_t * pointer_next;
++
++	if (stream->buffer != NULL) {
++		spin_lock_irqsave(&stream->dma_lock, flags);
++		disable_dma(stream->dma);
++		spin_unlock_irqrestore(&stream->dma_lock, flags);
++
++		pointer = stream->buffer;
++		pointer_next = stream->buffer->next;
++
++		do {
++			kfree(pointer);
++			pointer = pointer_next;
++			pointer_next = pointer->next;
++		} while (pointer != stream->buffer);
++
++		stream->buffer = NULL;
++	}
++}
++
++static void 
++au1000_dma_start(audio_stream_t *stream)
++{
++	snd_pcm_substream_t *substream = stream->substream;
++	snd_pcm_runtime_t *runtime = substream->runtime;
++
++	unsigned long flags, dma_start;
++	int i;
++	au1000_period_t * pointer;
++
++	if (stream->buffer == NULL) {
++		dma_start = virt_to_phys(runtime->dma_area);
++
++		stream->period_size = frames_to_bytes(runtime, 
++			runtime->period_size);
++		stream->buffer = kmalloc(sizeof(au1000_period_t), GFP_KERNEL);
++		pointer = stream->buffer;
++		for (i = 0 ; i < runtime->periods ; i++) {
++			pointer->start = (u32)(dma_start + 
++				(i * stream->period_size));
++			pointer->relative_end = (u32)
++				(((i+1) * stream->period_size) - 0x1);
++			if ( i < runtime->periods - 1) {
++				pointer->next = kmalloc(sizeof(au1000_period_t)
++					, GFP_KERNEL);
++				pointer = pointer->next;
++			}
++		}
++		pointer->next = stream->buffer;
++	
++		spin_lock_irqsave(&stream->dma_lock, flags);
++		init_dma(stream->dma);
++		if (get_dma_active_buffer(stream->dma) == 0) {
++			clear_dma_done0(stream->dma);
++			set_dma_addr0(stream->dma, stream->buffer->start);
++			set_dma_count0(stream->dma, stream->period_size >> 1);
++			set_dma_addr1(stream->dma, stream->buffer->next->start);
++			set_dma_count1(stream->dma, stream->period_size >> 1);
++		} else {
++			clear_dma_done1(stream->dma);
++			set_dma_addr1(stream->dma, stream->buffer->start);
++			set_dma_count1(stream->dma, stream->period_size >> 1);
++			set_dma_addr0(stream->dma, stream->buffer->next->start);
++			set_dma_count0(stream->dma, stream->period_size >> 1);
++		}
++		enable_dma_buffers(stream->dma);
++		start_dma(stream->dma);
++		spin_unlock_irqrestore(&stream->dma_lock, flags);
++	}
++}
++
++static irqreturn_t
++au1000_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	audio_stream_t *stream = (audio_stream_t *) dev_id;
++	snd_pcm_substream_t *substream = stream->substream;
++
++	spin_lock(&stream->dma_lock);
++	switch (get_dma_buffer_done(stream->dma)) {
++	case DMA_D0:
++		stream->buffer = stream->buffer->next;
++		clear_dma_done0(stream->dma);
++		set_dma_addr0(stream->dma, stream->buffer->next->start);
++		set_dma_count0(stream->dma, stream->period_size >> 1);
++		enable_dma_buffer0(stream->dma);
++		break;
++	case DMA_D1:
++		stream->buffer = stream->buffer->next;
++		clear_dma_done1(stream->dma);
++		set_dma_addr1(stream->dma, stream->buffer->next->start);
++		set_dma_count1(stream->dma, stream->period_size >> 1);
++		enable_dma_buffer1(stream->dma);
++		break;
++	case (DMA_D0 | DMA_D1):
++		spin_unlock(&stream->dma_lock);
++		printk(KERN_ERR "DMA %d missed interrupt.\n",stream->dma);
++		au1000_dma_stop(stream);
++		au1000_dma_start(stream);
++		spin_lock(&stream->dma_lock);
++		break;
++	case (~DMA_D0 & ~DMA_D1):
++		printk(KERN_ERR "DMA %d empty irq.\n",stream->dma);		
++	}
++	spin_unlock(&stream->dma_lock);
++	snd_pcm_period_elapsed(substream);
++	return IRQ_HANDLED;
++}
++
++/*-------------------------- PCM Audio Streams -------------------------------*/
++
++static unsigned int rates[] = {8000, 11025, 16000, 22050};
++static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
++	.count	=  sizeof(rates) / sizeof(rates[0]),
++	.list	= rates,
++	.mask	= 0,
++};
++
++static snd_pcm_hardware_t snd_au1000 =
++{
++	.info			= (SNDRV_PCM_INFO_INTERLEAVED | \
++				SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
++	.formats		= SNDRV_PCM_FMTBIT_S16_LE,
++	.rates			= (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | 
++				SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050),
++	.rate_min		= 8000,
++	.rate_max		= 22050,
++	.channels_min		= 1,
++	.channels_max		= 2,
++	.buffer_bytes_max	= 128*1024,
++	.period_bytes_min	= 32,
++	.period_bytes_max	= 16*1024,
++	.periods_min		= 8,
++	.periods_max		= 255,
++	.fifo_size		= 16,
++};
++
++static int
++snd_au1000_playback_open(snd_pcm_substream_t * substream)
++{
++	au1000->stream[PLAYBACK]->substream = substream;
++	au1000->stream[PLAYBACK]->buffer = NULL;
++	substream->private_data = au1000->stream[PLAYBACK];
++	substream->runtime->hw = snd_au1000;
++	return (snd_pcm_hw_constraint_list(substream->runtime, 0,
++		SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates) < 0);
++}
++
++static int
++snd_au1000_capture_open(snd_pcm_substream_t * substream)
++{
++	au1000->stream[CAPTURE]->substream = substream;
++	au1000->stream[CAPTURE]->buffer = NULL;
++	substream->private_data = au1000->stream[CAPTURE];
++	substream->runtime->hw = snd_au1000;
++	return (snd_pcm_hw_constraint_list(substream->runtime, 0,
++		SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates) < 0);
++
++}
++
++static int
++snd_au1000_playback_close(snd_pcm_substream_t * substream)
++{
++	au1000->stream[PLAYBACK]->substream = NULL;
++	return 0;
++}
++
++static int
++snd_au1000_capture_close(snd_pcm_substream_t * substream)
++{
++	au1000->stream[CAPTURE]->substream = NULL;
++	return 0;
++}
++
++static int
++snd_au1000_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_au1000_hw_free(snd_pcm_substream_t * substream)
++{
++	return snd_pcm_lib_free_pages(substream);
++}
++
++static int
++snd_au1000_playback_prepare(snd_pcm_substream_t * substream)
++{
++	snd_pcm_runtime_t *runtime = substream->runtime;
++
++	if (runtime->channels == 1 )
++		au1000_set_ac97_xmit_slots(AC97_SLOT_4);
++	else
++		au1000_set_ac97_xmit_slots(AC97_SLOT_3 | AC97_SLOT_4);
++	snd_ac97_set_rate(au1000->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
++	return 0;
++}
++
++static int
++snd_au1000_capture_prepare(snd_pcm_substream_t * substream)
++{
++	snd_pcm_runtime_t *runtime = substream->runtime;
++
++	if (runtime->channels == 1 )
++		au1000_set_ac97_recv_slots(AC97_SLOT_4);
++	else
++		au1000_set_ac97_recv_slots(AC97_SLOT_3 | AC97_SLOT_4);
++	snd_ac97_set_rate(au1000->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
++	return 0;
++}
++
++static int
++snd_au1000_trigger(snd_pcm_substream_t * substream, int cmd)
++{
++	audio_stream_t *stream = substream->private_data;
++	int err = 0;
++	
++	switch (cmd) {
++	case SNDRV_PCM_TRIGGER_START:
++		au1000_dma_start(stream);
++		break;
++	case SNDRV_PCM_TRIGGER_STOP:
++		au1000_dma_stop(stream);
++		break;
++	default:
++		err = -EINVAL;
++		break;
++	}
++	return err;
++}
++
++static snd_pcm_uframes_t
++snd_au1000_pointer(snd_pcm_substream_t * substream)
++{
++	audio_stream_t *stream = substream->private_data;
++	snd_pcm_runtime_t *runtime = substream->runtime;
++	unsigned long flags;
++	long location;
++
++	spin_lock_irqsave(&stream->dma_lock, flags);
++	location = get_dma_residue(stream->dma);
++	spin_unlock_irqrestore(&stream->dma_lock, flags);
++	location = stream->buffer->relative_end - location;
++	if (location == -1)
++		location = 0;
++	return bytes_to_frames(runtime,location);
++}
++
++static snd_pcm_ops_t snd_card_au1000_playback_ops = {
++	.open			= snd_au1000_playback_open,
++	.close			= snd_au1000_playback_close,
++	.ioctl			= snd_pcm_lib_ioctl,
++	.hw_params	        = snd_au1000_hw_params,
++	.hw_free	        = snd_au1000_hw_free,
++	.prepare		= snd_au1000_playback_prepare,
++	.trigger		= snd_au1000_trigger,
++	.pointer		= snd_au1000_pointer,
++};
++
++static snd_pcm_ops_t snd_card_au1000_capture_ops = {
++	.open			= snd_au1000_capture_open,
++	.close			= snd_au1000_capture_close,
++	.ioctl			= snd_pcm_lib_ioctl,
++	.hw_params	        = snd_au1000_hw_params,
++	.hw_free	        = snd_au1000_hw_free,
++	.prepare		= snd_au1000_capture_prepare,
++	.trigger		= snd_au1000_trigger,
++	.pointer		= snd_au1000_pointer,
++};
++
++static int __devinit
++snd_au1000_pcm_new(void)
++{
++	snd_pcm_t *pcm;
++	int err;
++	unsigned long flags;
++
++	if ((err = snd_pcm_new(au1000->card, "AU1000 AC97 PCM", 0, 1, 1, &pcm)) < 0)
++		return err;
++
++	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
++		snd_dma_continuous_data(GFP_KERNEL), 128*1024, 128*1024);
++
++	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
++		&snd_card_au1000_playback_ops);
++	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
++		&snd_card_au1000_capture_ops);
++		
++	pcm->private_data = au1000;
++	pcm->info_flags = 0;
++	strcpy(pcm->name, "Au1000 AC97 PCM");
++
++	flags = claim_dma_lock();
++	if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX,
++			"AC97 TX", au1000_dma_interrupt, SA_INTERRUPT,
++			au1000->stream[PLAYBACK])) < 0) {
++		release_dma_lock(flags);
++		return -EBUSY;
++	}
++	if ((au1000->stream[CAPTURE]->dma = request_au1000_dma(DMA_ID_AC97C_RX,
++			"AC97 RX", au1000_dma_interrupt, SA_INTERRUPT,
++			au1000->stream[CAPTURE])) < 0){
++		release_dma_lock(flags);
++		return -EBUSY;
++	}
++	/* enable DMA coherency in read/write DMA channels */
++	set_dma_mode(au1000->stream[PLAYBACK]->dma,
++		     get_dma_mode(au1000->stream[PLAYBACK]->dma) & ~DMA_NC);
++	set_dma_mode(au1000->stream[CAPTURE]->dma,
++		     get_dma_mode(au1000->stream[CAPTURE]->dma) & ~DMA_NC);
++	release_dma_lock(flags);
++	spin_lock_init(&au1000->stream[PLAYBACK]->dma_lock);
++	spin_lock_init(&au1000->stream[CAPTURE]->dma_lock);
++	au1000->pcm = pcm;
++	return 0;
++}
++
++
++/*-------------------------- AC97 CODEC Control ------------------------------*/
++
++static unsigned short 
++snd_au1000_ac97_read(ac97_t *ac97, unsigned short reg)
++{
++	u32 volatile cmd;
++	u16 volatile data;
++	int             i;
++	spin_lock(au1000->ac97_lock);
++/* would rather use the interupt than this polling but it works and I can't
++get the interupt driven case to work efficiently */
++	for (i = 0; i < 0x5000; i++)
++		if (!(au1000->ac97_ioport->status & AC97C_CP))
++			break;
++	if (i == 0x5000)
++		printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n");
++
++	cmd = (u32) reg & AC97C_INDEX_MASK;
++	cmd |= AC97C_READ;
++	au1000->ac97_ioport->cmd = cmd;
++
++	/* now wait for the data */
++	for (i = 0; i < 0x5000; i++)
++		if (!(au1000->ac97_ioport->status & AC97C_CP))
++			break;
++	if (i == 0x5000) {
++		printk(KERN_ERR "au1000 AC97: AC97 command read timeout\n");
++		return 0;
++	}
++
++	data = au1000->ac97_ioport->cmd & 0xffff;
++	spin_unlock(au1000->ac97_lock);
++
++	return data;
++	
++}
++
++
++static void
++snd_au1000_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
++{
++	u32 cmd;
++	int i;
++	spin_lock(au1000->ac97_lock);
++/* would rather use the interupt than this polling but it works and I can't
++get the interupt driven case to work efficiently */
++	for (i = 0; i < 0x5000; i++)
++		if (!(au1000->ac97_ioport->status & AC97C_CP))
++			break;
++	if (i == 0x5000)
++		printk(KERN_ERR "au1000 AC97: AC97 command write timeout\n");
++
++	cmd = (u32) reg & AC97C_INDEX_MASK;
++	cmd &= ~AC97C_READ;
++	cmd |= ((u32) val << AC97C_WD_BIT);
++	au1000->ac97_ioport->cmd = cmd;
++	spin_unlock(au1000->ac97_lock);
++}
++static void
++snd_au1000_ac97_free(ac97_t *ac97)
++{
++	au1000->ac97 = NULL;
++}
++
++static int __devinit
++snd_au1000_ac97_new(void)
++{
++	int err;
++
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
++	ac97_bus_t *pbus;
++	ac97_template_t ac97;
++ 	static ac97_bus_ops_t ops = {
++		.write = snd_au1000_ac97_write,
++		.read = snd_au1000_ac97_read,
++	};
++#else
++	ac97_bus_t bus, *pbus;
++	ac97_t ac97;
++#endif
++
++	if ((au1000->ac97_res_port = request_region(AC97C_CONFIG,
++	       		sizeof(au1000_ac97_reg_t), "Au1x00 AC97")) == NULL) {
++		snd_printk(KERN_ERR "ALSA AC97: can't grap AC97 port\n");
++		return -EBUSY;
++	}
++	au1000->ac97_ioport = (au1000_ac97_reg_t *) au1000->ac97_res_port->start;
++
++	spin_lock_init(&au1000->ac97_lock);
++
++	spin_lock(&au1000->ac97_lock);
++
++	/* configure pins for AC'97
++	TODO: move to board_setup.c */
++	au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
++
++	/* Initialise Au1000's AC'97 Control Block */
++	au1000->ac97_ioport->cntrl = AC97C_RS | AC97C_CE;
++	udelay(10);
++	au1000->ac97_ioport->cntrl = AC97C_CE;
++	udelay(10);
++
++	/* Initialise External CODEC -- cold reset */
++	au1000->ac97_ioport->config = AC97C_RESET;
++	udelay(10);
++	au1000->ac97_ioport->config = 0x0;
++	mdelay(5);
++
++	spin_unlock(&au1000->ac97_lock);
++
++	/* Initialise AC97 middle-layer */
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
++	if ((err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus)) < 0)
++ 		return err;
++#else
++	memset(&bus, 0, sizeof(bus));
++	bus.write = snd_au1000_ac97_write;
++	bus.read = snd_au1000_ac97_read;
++	if ((err = snd_ac97_bus(au1000->card, &bus, &pbus)) < 0)
++		return err;
++#endif
++	memset(&ac97, 0, sizeof(ac97));
++	ac97.private_data = au1000;
++	ac97.private_free = snd_au1000_ac97_free;
++	if ((err = snd_ac97_mixer(pbus, &ac97, &au1000->ac97)) < 0)
++		return err;
++	return 0;
++
++}
++
++/*------------------------------ Setup / Destroy ----------------------------*/
++
++void
++snd_au1000_free(snd_card_t *card)
++{
++
++	if (au1000->ac97_res_port) {
++		/* put internal AC97 block into reset */
++		au1000->ac97_ioport->cntrl = AC97C_RS;
++		au1000->ac97_ioport = NULL;
++		release_resource(au1000->ac97_res_port);
++		kfree_nocheck(au1000->ac97_res_port);
++	}
++
++	if (au1000->stream[PLAYBACK]->dma >= 0)
++		free_au1000_dma(au1000->stream[PLAYBACK]->dma);
++
++	if (au1000->stream[CAPTURE]->dma >= 0)
++		free_au1000_dma(au1000->stream[CAPTURE]->dma);
++
++	kfree(au1000->stream[PLAYBACK]);
++	au1000->stream[PLAYBACK] = NULL;
++	kfree(au1000->stream[CAPTURE]);
++	au1000->stream[CAPTURE] = NULL;
++	kfree(au1000);
++	au1000 = NULL;
++
++}
++
++static int __init 
++au1000_init(void)
++{
++	int err;
++
++	au1000 = kmalloc(sizeof(au1000_t), GFP_KERNEL);
++	if (au1000 == NULL)
++		return -ENOMEM;
++	au1000->stream[PLAYBACK] = kmalloc(sizeof(audio_stream_t), GFP_KERNEL);
++	if (au1000->stream[PLAYBACK] == NULL)
++		return -ENOMEM;
++	au1000->stream[CAPTURE] = kmalloc(sizeof(audio_stream_t), GFP_KERNEL);
++	if (au1000->stream[CAPTURE] == NULL)
++		return -ENOMEM;
++	/* so that snd_au1000_free will work as intended */
++	au1000->stream[PLAYBACK]->dma = -1;
++	au1000->stream[CAPTURE]->dma = -1;
++ 	au1000->ac97_res_port = NULL;
++
++	au1000->card = snd_card_new(-1, "AC97", THIS_MODULE, sizeof(au1000_t));
++	if (au1000->card == NULL) {
++		snd_au1000_free(au1000->card);
++		return -ENOMEM;
++	}
++
++	au1000->card->private_data = (au1000_t *)au1000;
++	au1000->card->private_free = snd_au1000_free;
++
++	if ((err = snd_au1000_ac97_new()) < 0 ) {
++		snd_card_free(au1000->card);
++		return err;
++	}
++
++	if ((err = snd_au1000_pcm_new()) < 0) {
++		snd_card_free(au1000->card);
++		return err;
++	}
++
++	strcpy(au1000->card->driver, "AMD-Au1000-AC97");
++	strcpy(au1000->card->shortname, "Au1000-AC97");
++	sprintf(au1000->card->longname, "AMD Au1000--AC97 ALSA Driver");
++
++	if ((err = snd_card_register(au1000->card)) < 0) {
++		snd_card_free(au1000->card);
++		return err;
++	}
++
++	printk( KERN_INFO "ALSA AC97: Driver Initialized\n" );
++	return 0;
++}
++
++static void __exit au1000_exit(void)
++{
++	snd_card_free(au1000->card);
++}
++
++module_init(au1000_init);
++module_exit(au1000_exit);
++
+diff -urpNX dontdiff linux-2.6.10/sound/oss/Kconfig linux-2.6.10-mips/sound/oss/Kconfig
+--- linux-2.6.10/sound/oss/Kconfig	2004-12-24 22:35:24.000000000 +0100
++++ linux-2.6.10-mips/sound/oss/Kconfig	2004-10-20 12:46:14.000000000 +0200
+@@ -100,6 +100,16 @@ config SOUND_CS4281
+ 	  Picture and feature list at
+ 	  <http://www.pcbroker.com/crystal4281.html>.
+ 
++config SOUND_BCM_CS4297A
++	tristate "Crystal Sound CS4297a (for Swarm)"
++	depends on SOUND_PRIME!=n && SIBYTE_SWARM && SOUND
++	help
++	  The BCM91250A has a Crystal CS4297a on synchronous serial
++	  port B (in addition to the DB-9 serial port).  Say Y or M
++	  here to enable the sound chip instead of the UART.  Also
++	  note that CONFIG_KGDB should not be enabled at the same
++	  time, since it also attempts to use this UART port.
++
+ config SOUND_ES1370
+ 	tristate "Ensoniq AudioPCI (ES1370)"
+ 	depends on SOUND_PRIME!=n && SOUND && PCI && SOUND_GAMEPORT
+@@ -192,7 +202,11 @@ config SOUND_HAL2
+ 	depends on SOUND_PRIME!=n && SOUND && SGI_IP22 && EXPERIMENTAL
+ 	help
+ 	  Say Y or M if you have an SGI Indy system and want to be able to
+-	  use it's on-board A2 audio system.
++	  use it's on-board A2 audio system
++
++config SOUND_IT8172
++	tristate "IT8172G Sound"
++	depends on SOUND_PRIME!=n && (MIPS_ITE8172 || MIPS_IVR) && SOUND
+ 
+ config SOUND_VRC5477
+ 	tristate "NEC Vrc5477 AC97 sound"
+@@ -202,6 +216,14 @@ config SOUND_VRC5477
+ 	  integrated, multi-function controller chip for MIPS CPUs.  Works
+ 	  with the AC97 codec.
+ 
++config SOUND_AU1000
++	tristate "Au1000 Sound"
++	depends on SOUND_PRIME!=n && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && SOUND
++
++config SOUND_AU1550_AC97
++	tristate "Au1550 AC97 Sound"
++	depends on SOUND_PRIME!=n && SOC_AU1550 && SOUND
++
+ config SOUND_TRIDENT
+ 	tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core"
+ 	depends on SOUND_PRIME!=n && SOUND && SOUND_GAMEPORT
+diff -urpNX dontdiff linux-2.6.10/sound/oss/Makefile linux-2.6.10-mips/sound/oss/Makefile
+--- linux-2.6.10/sound/oss/Makefile	2004-12-24 22:34:29.000000000 +0100
++++ linux-2.6.10-mips/sound/oss/Makefile	2004-10-20 12:46:14.000000000 +0200
+@@ -64,6 +64,8 @@ endif
+ obj-$(CONFIG_SOUND_ES1370)	+= es1370.o
+ obj-$(CONFIG_SOUND_ES1371)	+= es1371.o ac97_codec.o
+ obj-$(CONFIG_SOUND_VRC5477)	+= nec_vrc5477.o ac97_codec.o
++obj-$(CONFIG_SOUND_AU1000)	+= au1000.o ac97_codec.o  
++obj-$(CONFIG_SOUND_AU1550_AC97)	+= au1550_ac97.o ac97_codec.o  
+ obj-$(CONFIG_SOUND_ESSSOLO1)	+= esssolo1.o
+ obj-$(CONFIG_SOUND_FUSION)	+= cs46xx.o ac97_codec.o
+ obj-$(CONFIG_SOUND_MAESTRO)	+= maestro.o
+@@ -71,6 +73,7 @@ obj-$(CONFIG_SOUND_MAESTRO3)	+= maestro3
+ obj-$(CONFIG_SOUND_TRIDENT)	+= trident.o ac97_codec.o
+ obj-$(CONFIG_SOUND_HARMONY)	+= harmony.o
+ obj-$(CONFIG_SOUND_EMU10K1)	+= ac97_codec.o
++obj-$(CONFIG_SOUND_BCM_CS4297A)	+= swarm_cs4297a.o
+ obj-$(CONFIG_SOUND_RME96XX)     += rme96xx.o
+ obj-$(CONFIG_SOUND_BT878)	+= btaudio.o
+ obj-$(CONFIG_SOUND_ALI5455)	+= ali5455.o ac97_codec.o
+diff -urpNX dontdiff linux-2.6.10/sound/oss/ac97_codec.c linux-2.6.10-mips/sound/oss/ac97_codec.c
+--- linux-2.6.10/sound/oss/ac97_codec.c	2004-12-24 22:34:00.000000000 +0100
++++ linux-2.6.10-mips/sound/oss/ac97_codec.c	2004-09-21 13:12:30.000000000 +0200
+@@ -173,6 +173,7 @@ static const struct {
+ 	{0x83847608, "SigmaTel STAC9708",	&sigmatel_9708_ops},
+ 	{0x83847609, "SigmaTel STAC9721/23",	&sigmatel_9721_ops},
+ 	{0x83847644, "SigmaTel STAC9744/45",	&sigmatel_9744_ops},
++	{0x83847652, "SigmaTel STAC9752/53",	&default_ops},
+ 	{0x83847656, "SigmaTel STAC9756/57",	&sigmatel_9744_ops},
+ 	{0x83847666, "SigmaTel STAC9750T",	&sigmatel_9744_ops},
+ 	{0x83847684, "SigmaTel STAC9783/84?",	&null_ops},
+diff -urpNX dontdiff linux-2.6.10/sound/oss/au1000.c linux-2.6.10-mips/sound/oss/au1000.c
+--- linux-2.6.10/sound/oss/au1000.c	2004-12-24 22:35:01.000000000 +0100
++++ linux-2.6.10-mips/sound/oss/au1000.c	2004-10-27 02:15:28.000000000 +0200
+@@ -59,6 +59,7 @@
+ #include <linux/slab.h>
+ #include <linux/soundcard.h>
+ #include <linux/init.h>
++#include <linux/page-flags.h>
+ #include <linux/poll.h>
+ #include <linux/pci.h>
+ #include <linux/bitops.h>
+@@ -66,21 +67,18 @@
+ #include <linux/spinlock.h>
+ #include <linux/smp_lock.h>
+ #include <linux/ac97_codec.h>
+-#include <linux/wrapper.h>
+ #include <linux/interrupt.h>
+ #include <asm/io.h>
+ #include <asm/uaccess.h>
+-#include <asm/au1000.h>
+-#include <asm/au1000_dma.h>
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-au1x00/au1000_dma.h>
+ 
+ /* --------------------------------------------------------------------- */
+ 
+ #undef OSS_DOCUMENTED_MIXER_SEMANTICS
+-#define AU1000_DEBUG
++#undef AU1000_DEBUG
+ #undef AU1000_VERBOSE_DEBUG
+ 
+-#define USE_COHERENT_DMA
+-
+ #define AU1000_MODULE_NAME "Au1000 audio"
+ #define PFX AU1000_MODULE_NAME
+ 
+@@ -116,7 +114,7 @@ struct au1000_state {
+ 	struct proc_dir_entry *ac97_ps;
+ #endif				/* AU1000_DEBUG */
+ 
+-	struct ac97_codec *codec;
++	struct ac97_codec codec;
+ 	unsigned        codec_base_caps;// AC'97 reg 00h, "Reset Register"
+ 	unsigned        codec_ext_caps;	// AC'97 reg 28h, "Extended Audio ID"
+ 	int             no_vra;	// do not use VRA
+@@ -191,35 +189,6 @@ static inline unsigned ld2(unsigned int 
+ 	return r;
+ }
+ 
+-
+-#ifdef USE_COHERENT_DMA
+-static inline void * dma_alloc(size_t size, dma_addr_t * dma_handle)
+-{
+-	void* ret = (void *)__get_free_pages(GFP_ATOMIC | GFP_DMA,
+-					     get_order(size));
+-	if (ret != NULL) {
+-		memset(ret, 0, size);
+-		*dma_handle = virt_to_phys(ret);
+-	}
+-	return ret;
+-}
+-
+-static inline void dma_free(size_t size, void* va, dma_addr_t dma_handle)
+-{
+-	free_pages((unsigned long)va, get_order(size));
+-}
+-#else
+-static inline void * dma_alloc(size_t size, dma_addr_t * dma_handle)
+-{
+-	return pci_alloc_consistent(NULL, size, dma_handle);
+-}
+-
+-static inline void dma_free(size_t size, void* va, dma_addr_t dma_handle)
+-{
+-	pci_free_consistent(NULL, size, va, dma_handle);
+-}
+-#endif
+-
+ /* --------------------------------------------------------------------- */
+ 
+ static void au1000_delay(int msec)
+@@ -356,17 +325,17 @@ static void set_adc_rate(struct au1000_s
+ 
+ 	adc->src_factor = 1;
+ 
+-	ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
++	ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
+ 
+ 	rate = rate > 48000 ? 48000 : rate;
+ 
+ 	// enable VRA
+-	wrcodec(s->codec, AC97_EXTENDED_STATUS,
++	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+ 		ac97_extstat | AC97_EXTSTAT_VRA);
+ 	// now write the sample rate
+-	wrcodec(s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
++	wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
+ 	// read it back for actual supported rate
+-	adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
++	adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
+ 
+ #ifdef AU1000_VERBOSE_DEBUG
+ 	dbg("%s: set to %d Hz", __FUNCTION__, adc_rate);
+@@ -374,11 +343,11 @@ static void set_adc_rate(struct au1000_s
+ 
+ 	// some codec's don't allow unequal DAC and ADC rates, in which case
+ 	// writing one rate reg actually changes both.
+-	dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
++	dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
+ 	if (dac->num_channels > 2)
+-		wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
++		wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
+ 	if (dac->num_channels > 4)
+-		wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
++		wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
+ 
+ 	adc->sample_rate = adc_rate;
+ 	dac->sample_rate = dac_rate;
+@@ -401,23 +370,23 @@ static void set_dac_rate(struct au1000_s
+ 
+ 	dac->src_factor = 1;
+ 
+-	ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
++	ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
+ 
+ 	rate = rate > 48000 ? 48000 : rate;
+ 
+ 	// enable VRA
+-	wrcodec(s->codec, AC97_EXTENDED_STATUS,
++	wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+ 		ac97_extstat | AC97_EXTSTAT_VRA);
+ 	// now write the sample rate
+-	wrcodec(s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
++	wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
+ 	// I don't support different sample rates for multichannel,
+ 	// so make these channels the same.
+ 	if (dac->num_channels > 2)
+-		wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
++		wrcodec(&s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
+ 	if (dac->num_channels > 4)
+-		wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
++		wrcodec(&s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
+ 	// read it back for actual supported rate
+-	dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
++	dac_rate = rdcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE);
+ 
+ #ifdef AU1000_VERBOSE_DEBUG
+ 	dbg("%s: set to %d Hz", __FUNCTION__, dac_rate);
+@@ -425,7 +394,7 @@ static void set_dac_rate(struct au1000_s
+ 
+ 	// some codec's don't allow unequal DAC and ADC rates, in which case
+ 	// writing one rate reg actually changes both.
+-	adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
++	adc_rate = rdcodec(&s->codec, AC97_PCM_LR_ADC_RATE);
+ 
+ 	dac->sample_rate = dac_rate;
+ 	adc->sample_rate = adc_rate;
+@@ -603,8 +572,11 @@ extern inline void dealloc_dmabuf(struct
+ 		pend = virt_to_page(db->rawbuf +
+ 				    (PAGE_SIZE << db->buforder) - 1);
+ 		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+-			mem_map_unreserve(page);
+-		dma_free(PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr);
++			ClearPageReserved(page);
++		dma_free_noncoherent(NULL,
++				PAGE_SIZE << db->buforder,
++				db->rawbuf,
++				db->dmaaddr);
+ 	}
+ 	db->rawbuf = db->nextIn = db->nextOut = NULL;
+ 	db->mapped = db->ready = 0;
+@@ -622,8 +594,10 @@ static int prog_dmabuf(struct au1000_sta
+ 		db->ready = db->mapped = 0;
+ 		for (order = DMABUF_DEFAULTORDER;
+ 		     order >= DMABUF_MINORDER; order--)
+-			if ((db->rawbuf = dma_alloc(PAGE_SIZE << order,
+-						  &db->dmaaddr)))
++			if ((db->rawbuf = dma_alloc_noncoherent(NULL,
++						PAGE_SIZE << order,
++						&db->dmaaddr,
++						0)))
+ 				break;
+ 		if (!db->rawbuf)
+ 			return -ENOMEM;
+@@ -633,7 +607,7 @@ static int prog_dmabuf(struct au1000_sta
+ 		pend = virt_to_page(db->rawbuf +
+ 				    (PAGE_SIZE << db->buforder) - 1);
+ 		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+-			mem_map_reserve(page);
++			SetPageReserved(page);
+ 	}
+ 
+ 	db->cnt_factor = 1;
+@@ -708,7 +682,7 @@ extern inline int prog_dmabuf_dac(struct
+ 
+ 
+ /* hold spinlock for the following */
+-static void dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	struct au1000_state *s = (struct au1000_state *) dev_id;
+ 	struct dmabuf  *dac = &s->dma_dac;
+@@ -723,7 +697,7 @@ static void dac_dma_interrupt(int irq, v
+ 
+ 	if ((buff_done = get_dma_buffer_done(dac->dmanr)) == 0) {
+ 		/* fastpath out, to ease interrupt sharing */
+-		return;
++		return IRQ_HANDLED;
+ 	}
+ 
+ 	spin_lock(&s->lock);
+@@ -786,10 +760,12 @@ static void dac_dma_interrupt(int irq, v
+ 		wake_up(&dac->wait);
+ 
+ 	spin_unlock(&s->lock);
++
++	return IRQ_HANDLED;
+ }
+ 
+ 
+-static void adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	struct au1000_state *s = (struct au1000_state *) dev_id;
+ 	struct dmabuf  *adc = &s->dma_adc;
+@@ -804,7 +780,7 @@ static void adc_dma_interrupt(int irq, v
+ 
+ 	if ((buff_done = get_dma_buffer_done(adc->dmanr)) == 0) {
+ 		/* fastpath out, to ease interrupt sharing */
+-		return;
++		return IRQ_HANDLED;
+ 	}
+ 
+ 	spin_lock(&s->lock);
+@@ -816,7 +792,7 @@ static void adc_dma_interrupt(int irq, v
+ 			stop_adc(s);
+ 			adc->error++;
+ 			err("adc overrun");
+-			return;
++			return IRQ_NONE;
+ 		}
+ 
+ 		adc->nextIn += adc->dma_fragsize;
+@@ -853,7 +829,7 @@ static void adc_dma_interrupt(int irq, v
+ 			adc->error++;
+ 			err("adc overrun");
+ 			spin_unlock(&s->lock);
+-			return;
++			return IRQ_NONE;
+ 		}
+ 
+ 		adc->nextIn += 2*adc->dma_fragsize;
+@@ -873,6 +849,8 @@ static void adc_dma_interrupt(int irq, v
+ 		wake_up(&adc->wait);
+ 
+ 	spin_unlock(&s->lock);
++
++	return IRQ_HANDLED;
+ }
+ 
+ /* --------------------------------------------------------------------- */
+@@ -904,7 +882,7 @@ static int au1000_ioctl_mixdev(struct in
+ 			       unsigned int cmd, unsigned long arg)
+ {
+ 	struct au1000_state *s = (struct au1000_state *)file->private_data;
+-	struct ac97_codec *codec = s->codec;
++	struct ac97_codec *codec = &s->codec;
+ 
+ 	return mixdev_ioctl(codec, cmd, arg);
+ }
+@@ -1338,8 +1316,7 @@ static int au1000_mmap(struct file *file
+ 		ret = -EINVAL;
+ 		goto out;
+ 	}
+-	if (remap_pfn_range(vma->vm_start,
+-			     virt_to_phys(db->rawbuf) >> PAGE_SHIFT,
++	if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(db->rawbuf),
+ 			     size, vma->vm_page_prot)) {
+ 		ret = -EAGAIN;
+ 		goto out;
+@@ -1500,9 +1477,9 @@ static int au1000_ioctl(struct inode *in
+ 			s->dma_dac.num_channels = val ? 2 : 1;
+ 			if (s->codec_ext_caps & AC97_EXT_DACS) {
+ 				// disable surround and center/lfe in AC'97
+-				u16 ext_stat = rdcodec(s->codec,
++				u16 ext_stat = rdcodec(&s->codec,
+ 						       AC97_EXTENDED_STATUS);
+-				wrcodec(s->codec, AC97_EXTENDED_STATUS,
++				wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+ 					ext_stat | (AC97_EXTSTAT_PRI |
+ 						    AC97_EXTSTAT_PRJ |
+ 						    AC97_EXTSTAT_PRK));
+@@ -1552,9 +1529,9 @@ static int au1000_ioctl(struct inode *in
+ 					// disable surround and center/lfe
+ 					// channels in AC'97
+ 					u16             ext_stat =
+-						rdcodec(s->codec,
++						rdcodec(&s->codec,
+ 							AC97_EXTENDED_STATUS);
+-					wrcodec(s->codec,
++					wrcodec(&s->codec,
+ 						AC97_EXTENDED_STATUS,
+ 						ext_stat | (AC97_EXTSTAT_PRI |
+ 							    AC97_EXTSTAT_PRJ |
+@@ -1563,14 +1540,14 @@ static int au1000_ioctl(struct inode *in
+ 					// enable surround, center/lfe
+ 					// channels in AC'97
+ 					u16             ext_stat =
+-						rdcodec(s->codec,
++						rdcodec(&s->codec,
+ 							AC97_EXTENDED_STATUS);
+ 					ext_stat &= ~AC97_EXTSTAT_PRJ;
+ 					if (val == 6)
+ 						ext_stat &=
+ 							~(AC97_EXTSTAT_PRI |
+ 							  AC97_EXTSTAT_PRK);
+-					wrcodec(s->codec,
++					wrcodec(&s->codec,
+ 						AC97_EXTENDED_STATUS,
+ 						ext_stat);
+ 				}
+@@ -1832,7 +1809,7 @@ static int au1000_ioctl(struct inode *in
+ 		return -EINVAL;
+ 	}
+ 
+-	return mixdev_ioctl(s->codec, cmd, arg);
++	return mixdev_ioctl(&s->codec, cmd, arg);
+ }
+ 
+ 
+@@ -1983,7 +1960,7 @@ static int proc_au1000_dump(char *buf, c
+ 	len += sprintf(buf + len, "----------------------\n");
+ 	for (cnt = 0; cnt <= 0x7e; cnt += 2)
+ 		len += sprintf(buf + len, "reg %02x = %04x\n",
+-			       cnt, rdcodec(s->codec, cnt));
++			       cnt, rdcodec(&s->codec, cnt));
+ 
+ 	if (fpos >= len) {
+ 		*start = buf;
+@@ -2010,7 +1987,9 @@ static int __devinit au1000_probe(void)
+ {
+ 	struct au1000_state *s = &au1000_state;
+ 	int             val;
++#ifdef AU1000_DEBUG
+ 	char            proc_str[80];
++#endif
+ 
+ 	memset(s, 0, sizeof(struct au1000_state));
+ 
+@@ -2019,23 +1998,16 @@ static int __devinit au1000_probe(void)
+ 	init_waitqueue_head(&s->open_wait);
+ 	init_MUTEX(&s->open_sem);
+ 	spin_lock_init(&s->lock);
+-	
+-	s->codec = ac97_alloc_codec();
+-	if(s->codec == NULL)
+-	{
+-		error("Out of memory");
+-		return -1;
+-	}
+-	s->codec->private_data = s;
+-	s->codec->id = 0;
+-	s->codec->codec_read = rdcodec;
+-	s->codec->codec_write = wrcodec;
+-	s->codec->codec_wait = waitcodec;
++	s->codec.private_data = s;
++	s->codec.id = 0;
++	s->codec.codec_read = rdcodec;
++	s->codec.codec_write = wrcodec;
++	s->codec.codec_wait = waitcodec;
+ 
+-	if (!request_region(virt_to_phys((void *) AC97C_CONFIG),
++	if (!request_mem_region(CPHYSADDR(AC97C_CONFIG),
+ 			    0x14, AU1000_MODULE_NAME)) {
+ 		err("AC'97 ports in use");
+-		goto err_codec;
++		return -1;
+ 	}
+ 	// Allocate the DMA Channels
+ 	if ((s->dma_dac.dmanr = request_au1000_dma(DMA_ID_AC97C_TX,
+@@ -2057,25 +2029,17 @@ static int __devinit au1000_probe(void)
+ 	     s->dma_dac.dmanr, get_dma_done_irq(s->dma_dac.dmanr),
+ 	     s->dma_adc.dmanr, get_dma_done_irq(s->dma_adc.dmanr));
+ 
+-#ifdef USE_COHERENT_DMA
+ 	// enable DMA coherency in read/write DMA channels
+ 	set_dma_mode(s->dma_dac.dmanr,
+ 		     get_dma_mode(s->dma_dac.dmanr) & ~DMA_NC);
+ 	set_dma_mode(s->dma_adc.dmanr,
+ 		     get_dma_mode(s->dma_adc.dmanr) & ~DMA_NC);
+-#else
+-	// disable DMA coherency in read/write DMA channels
+-	set_dma_mode(s->dma_dac.dmanr,
+-		     get_dma_mode(s->dma_dac.dmanr) | DMA_NC);
+-	set_dma_mode(s->dma_adc.dmanr,
+-		     get_dma_mode(s->dma_adc.dmanr) | DMA_NC);
+-#endif
+ 
+ 	/* register devices */
+ 
+ 	if ((s->dev_audio = register_sound_dsp(&au1000_audio_fops, -1)) < 0)
+ 		goto err_dev1;
+-	if ((s->codec->dev_mixer =
++	if ((s->codec.dev_mixer =
+ 	     register_sound_mixer(&au1000_mixer_fops, -1)) < 0)
+ 		goto err_dev2;
+ 
+@@ -2108,11 +2072,11 @@ static int __devinit au1000_probe(void)
+ 	au_writel(0, AC97C_CONFIG);
+ 
+ 	/* codec init */
+-	if (!ac97_probe_codec(s->codec))
++	if (!ac97_probe_codec(&s->codec))
+ 		goto err_dev3;
+ 
+-	s->codec_base_caps = rdcodec(s->codec, AC97_RESET);
+-	s->codec_ext_caps = rdcodec(s->codec, AC97_EXTENDED_ID);
++	s->codec_base_caps = rdcodec(&s->codec, AC97_RESET);
++	s->codec_ext_caps = rdcodec(&s->codec, AC97_EXTENDED_ID);
+ 	info("AC'97 Base/Extended ID = %04x/%04x",
+ 	     s->codec_base_caps, s->codec_ext_caps);
+ 
+@@ -2124,12 +2088,12 @@ static int __devinit au1000_probe(void)
+ 	 * ALTPCM). ac97_codec.c does not handle detection
+ 	 * of this channel correctly.
+ 	 */
+-	s->codec->supported_mixers |= SOUND_MASK_ALTPCM;
++	s->codec.supported_mixers |= SOUND_MASK_ALTPCM;
+ 	/*
+ 	 * Now set AUX_OUT's default volume.
+ 	 */
+ 	val = 0x4343;
+-	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_ALTPCM,
++	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_ALTPCM,
+ 		     (unsigned long) &val);
+ 	
+ 	if (!(s->codec_ext_caps & AC97_EXTID_VRA)) {
+@@ -2137,8 +2101,8 @@ static int __devinit au1000_probe(void)
+ 		s->no_vra = 1;
+ 	} else if (!vra) {
+ 		// Boot option says disable VRA
+-		u16 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
+-		wrcodec(s->codec, AC97_EXTENDED_STATUS,
++		u16 ac97_extstat = rdcodec(&s->codec, AC97_EXTENDED_STATUS);
++		wrcodec(&s->codec, AC97_EXTENDED_STATUS,
+ 			ac97_extstat & ~AC97_EXTSTAT_VRA);
+ 		s->no_vra = 1;
+ 	}
+@@ -2147,20 +2111,38 @@ static int __devinit au1000_probe(void)
+ 
+ 	/* set mic to be the recording source */
+ 	val = SOUND_MASK_MIC;
+-	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC,
++	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
+ 		     (unsigned long) &val);
+ 
+ #ifdef AU1000_DEBUG
+ 	sprintf(proc_str, "driver/%s/%d/ac97", AU1000_MODULE_NAME,
+-		s->codec->id);
++		s->codec.id);
+ 	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
+-					     ac97_read_proc, s->codec);
++					     ac97_read_proc, &s->codec);
++#endif
++
++#ifdef CONFIG_MIPS_XXS1500
++	/* deassert eapd */
++	wrcodec(&s->codec, AC97_POWER_CONTROL, 
++			rdcodec(&s->codec, AC97_POWER_CONTROL) & ~0x8000);
++	/* mute a number of signals which seem to be causing problems
++	 * if not muted.
++	 */
++	wrcodec(&s->codec, AC97_PCBEEP_VOL, 0x8000);
++	wrcodec(&s->codec, AC97_PHONE_VOL, 0x8008);
++	wrcodec(&s->codec, AC97_MIC_VOL, 0x8008);
++	wrcodec(&s->codec, AC97_LINEIN_VOL, 0x8808);
++	wrcodec(&s->codec, AC97_CD_VOL, 0x8808);
++	wrcodec(&s->codec, AC97_VIDEO_VOL, 0x8808);
++	wrcodec(&s->codec, AC97_AUX_VOL, 0x8808);
++	wrcodec(&s->codec, AC97_PCMOUT_VOL, 0x0808);
++	wrcodec(&s->codec, AC97_GENERAL_PURPOSE, 0x2000);
+ #endif
+ 
+ 	return 0;
+ 
+  err_dev3:
+-	unregister_sound_mixer(s->codec->dev_mixer);
++	unregister_sound_mixer(s->codec.dev_mixer);
+  err_dev2:
+ 	unregister_sound_dsp(s->dev_audio);
+  err_dev1:
+@@ -2168,9 +2150,7 @@ static int __devinit au1000_probe(void)
+  err_dma2:
+ 	free_au1000_dma(s->dma_dac.dmanr);
+  err_dma1:
+-	release_region(virt_to_phys((void *) AC97C_CONFIG), 0x14);
+- err_codec:
+- 	ac97_release_codec(s->codec);
++	release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14);
+ 	return -1;
+ }
+ 
+@@ -2187,10 +2167,9 @@ static void au1000_remove(void)
+ 	synchronize_irq();
+ 	free_au1000_dma(s->dma_adc.dmanr);
+ 	free_au1000_dma(s->dma_dac.dmanr);
+-	release_region(virt_to_phys((void *) AC97C_CONFIG), 0x14);
++	release_mem_region(CPHYSADDR(AC97C_CONFIG), 0x14);
+ 	unregister_sound_dsp(s->dev_audio);
+-	unregister_sound_mixer(s->codec->dev_mixer);
+-	ac97_release_codec(s->codec);
++	unregister_sound_mixer(s->codec.dev_mixer);
+ }
+ 
+ static int __init init_au1000(void)
+@@ -2219,7 +2198,7 @@ static int __init au1000_setup(char *opt
+ 	if (!options || !*options)
+ 		return 0;
+ 
+-	while (this_opt = strsep(&options, ",")) {
++	while ((this_opt = strsep(&options, ","))) {
+ 		if (!*this_opt)
+ 			continue;
+ 		if (!strncmp(this_opt, "vra", 3)) {
+diff -urpNX dontdiff linux-2.6.10/sound/oss/au1550_ac97.c linux-2.6.10-mips/sound/oss/au1550_ac97.c
+--- linux-2.6.10/sound/oss/au1550_ac97.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.10-mips/sound/oss/au1550_ac97.c	2004-10-27 02:15:28.000000000 +0200
+@@ -0,0 +1,2119 @@
++/*
++ * au1550_ac97.c  --  Sound driver for Alchemy Au1550 MIPS Internet Edge
++ *                    Processor.
++ *
++ * Copyright 2004 Embedded Edge, LLC
++ *	dan at embeddededge.com
++ *
++ * Mostly copied from the au1000.c driver and some from the
++ * PowerMac dbdma driver.
++ * We assume the processor can do memory coherent DMA.
++ *
++ * Ported to 2.6 by Matt Porter <mporter at kernel.crashing.org>
++ *
++ *  This program is free software; you can redistribute  it and/or modify it
++ *  under  the terms of  the GNU General  Public License as published by the
++ *  Free Software Foundation;  either version 2 of the  License, or (at your
++ *  option) any later version.
++ *
++ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
++ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ *  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.
++ *
++ */
++
++#undef DEBUG
++
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/ioport.h>
++#include <linux/sched.h>
++#include <linux/delay.h>
++#include <linux/sound.h>
++#include <linux/slab.h>
++#include <linux/soundcard.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/kernel.h>
++#include <linux/poll.h>
++#include <linux/pci.h>
++#include <linux/bitops.h>
++#include <linux/spinlock.h>
++#include <linux/smp_lock.h>
++#include <linux/ac97_codec.h>
++#include <asm/io.h>
++#include <asm/uaccess.h>
++#include <asm/hardirq.h>
++#include <asm/mach-au1x00/au1000.h>
++#include <asm/mach-au1x00/au1xxx_psc.h>
++#include <asm/mach-au1x00/au1xxx_dbdma.h>
++
++#undef OSS_DOCUMENTED_MIXER_SEMANTICS
++
++/* misc stuff */
++#define POLL_COUNT   0x50000
++#define AC97_EXT_DACS (AC97_EXTID_SDAC | AC97_EXTID_CDAC | AC97_EXTID_LDAC)
++
++/* The number of DBDMA ring descriptors to allocate.  No sense making
++ * this too large....if you can't keep up with a few you aren't likely
++ * to be able to with lots of them, either.
++ */
++#define NUM_DBDMA_DESCRIPTORS 4
++
++#define err(format, arg...) printk(KERN_ERR format "\n" , ## arg)
++
++/* Boot options
++ * 0 = no VRA, 1 = use VRA if codec supports it
++ */
++static int      vra = 1;
++MODULE_PARM(vra, "i");
++MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it");
++
++static struct au1550_state {
++	/* soundcore stuff */
++	int             dev_audio;
++
++	struct ac97_codec *codec;
++	unsigned        codec_base_caps; /* AC'97 reg 00h, "Reset Register" */
++	unsigned        codec_ext_caps;  /* AC'97 reg 28h, "Extended Audio ID" */
++	int             no_vra;		/* do not use VRA */
++
++	spinlock_t      lock;
++	struct semaphore open_sem;
++	struct semaphore sem;
++	mode_t          open_mode;
++	wait_queue_head_t open_wait;
++
++	struct dmabuf {
++		u32		dmanr;
++		unsigned        sample_rate;
++		unsigned	src_factor;
++		unsigned        sample_size;
++		int             num_channels;
++		int		dma_bytes_per_sample;
++		int		user_bytes_per_sample;
++		int		cnt_factor;
++
++		void		*rawbuf;
++		unsigned        buforder;
++		unsigned	numfrag;
++		unsigned        fragshift;
++		void		*nextIn;
++		void		*nextOut;
++		int		count;
++		unsigned        total_bytes;
++		unsigned        error;
++		wait_queue_head_t wait;
++
++		/* redundant, but makes calculations easier */
++		unsigned	fragsize;
++		unsigned	dma_fragsize;
++		unsigned	dmasize;
++		unsigned	dma_qcount;
++
++		/* OSS stuff */
++		unsigned        mapped:1;
++		unsigned        ready:1;
++		unsigned        stopped:1;
++		unsigned        ossfragshift;
++		int             ossmaxfrags;
++		unsigned        subdivision;
++	} dma_dac, dma_adc;
++} au1550_state;
++
++static unsigned
++ld2(unsigned int x)
++{
++	unsigned        r = 0;
++
++	if (x >= 0x10000) {
++		x >>= 16;
++		r += 16;
++	}
++	if (x >= 0x100) {
++		x >>= 8;
++		r += 8;
++	}
++	if (x >= 0x10) {
++		x >>= 4;
++		r += 4;
++	}
++	if (x >= 4) {
++		x >>= 2;
++		r += 2;
++	}
++	if (x >= 2)
++		r++;
++	return r;
++}
++
++static void
++au1550_delay(int msec)
++{
++	unsigned long   tmo;
++	signed long     tmo2;
++
++	if (in_interrupt())
++		return;
++
++	tmo = jiffies + (msec * HZ) / 1000;
++	for (;;) {
++		tmo2 = tmo - jiffies;
++		if (tmo2 <= 0)
++			break;
++		schedule_timeout(tmo2);
++	}
++}
++
++static u16
++rdcodec(struct ac97_codec *codec, u8 addr)
++{
++	struct au1550_state *s = (struct au1550_state *)codec->private_data;
++	unsigned long   flags;
++	u32             cmd, val;
++	u16             data;
++	int             i;
++
++	spin_lock_irqsave(&s->lock, flags);
++
++	for (i = 0; i < POLL_COUNT; i++) {
++		val = au_readl(PSC_AC97STAT);
++		au_sync();
++		if (!(val & PSC_AC97STAT_CP))
++			break;
++	}
++	if (i == POLL_COUNT)
++		err("rdcodec: codec cmd pending expired!");
++
++	cmd = (u32)PSC_AC97CDC_INDX(addr);
++	cmd |= PSC_AC97CDC_RD;	/* read command */
++	au_writel(cmd, PSC_AC97CDC);
++	au_sync();
++
++	/* now wait for the data
++	*/
++	for (i = 0; i < POLL_COUNT; i++) {
++		val = au_readl(PSC_AC97STAT);
++		au_sync();
++		if (!(val & PSC_AC97STAT_CP))
++			break;
++	}
++	if (i == POLL_COUNT) {
++		err("rdcodec: read poll expired!");
++		return 0;
++	}
++
++	/* wait for command done?
++	*/
++	for (i = 0; i < POLL_COUNT; i++) {
++		val = au_readl(PSC_AC97EVNT);
++		au_sync();
++		if (val & PSC_AC97EVNT_CD)
++			break;
++	}
++	if (i == POLL_COUNT) {
++		err("rdcodec: read cmdwait expired!");
++		return 0;
++	}
++
++	data = au_readl(PSC_AC97CDC) & 0xffff;
++	au_sync();
++
++	/* Clear command done event.
++	*/
++	au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT);
++	au_sync();
++
++	spin_unlock_irqrestore(&s->lock, flags);
++
++	return data;
++}
++
++
++static void
++wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
++{
++	struct au1550_state *s = (struct au1550_state *)codec->private_data;
++	unsigned long   flags;
++	u32             cmd, val;
++	int             i;
++
++	spin_lock_irqsave(&s->lock, flags);
++
++	for (i = 0; i < POLL_COUNT; i++) {
++		val = au_readl(PSC_AC97STAT);
++		au_sync();
++		if (!(val & PSC_AC97STAT_CP))
++			break;
++	}
++	if (i == POLL_COUNT)
++		err("wrcodec: codec cmd pending expired!");
++
++	cmd = (u32)PSC_AC97CDC_INDX(addr);
++	cmd |= (u32)data;
++	au_writel(cmd, PSC_AC97CDC);
++	au_sync();
++
++	for (i = 0; i < POLL_COUNT; i++) {
++		val = au_readl(PSC_AC97STAT);
++		au_sync();
++		if (!(val & PSC_AC97STAT_CP))
++			break;
++	}
++	if (i == POLL_COUNT)
++		err("wrcodec: codec cmd pending expired!");
++
++	for (i = 0; i < POLL_COUNT; i++) {
++		val = au_readl(PSC_AC97EVNT);
++		au_sync();
++		if (val & PSC_AC97EVNT_CD)
++			break;
++	}
++	if (i == POLL_COUNT)
++		err("wrcodec: read cmdwait expired!");
++
++	/* Clear command done event.
++	*/
++	au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT);
++	au_sync();
++
++	spin_unlock_irqrestore(&s->lock, flags);
++}
++
++static void
++waitcodec(struct ac97_codec *codec)
++{
++	u16	temp;
++	u32	val;
++	int	i;
++
++	/* codec_wait is used to wait for a ready state after
++	 * an AC97C_RESET.
++	 */
++	au1550_delay(10);
++
++	/* first poll the CODEC_READY tag bit
++	*/
++	for (i = 0; i < POLL_COUNT; i++) {
++		val = au_readl(PSC_AC97STAT);
++		au_sync();
++		if (val & PSC_AC97STAT_CR)
++			break;
++	}
++	if (i == POLL_COUNT) {
++		err("waitcodec: CODEC_READY poll expired!");
++		return;
++	}
++
++	/* get AC'97 powerdown control/status register
++	*/
++	temp = rdcodec(codec, AC97_POWER_CONTROL);
++
++	/* If anything is powered down, power'em up
++	*/
++	if (temp & 0x7f00) {
++		/* Power on
++		*/
++		wrcodec(codec, AC97_POWER_CONTROL, 0);
++		au1550_delay(100);
++
++		/* Reread
++		*/
++		temp = rdcodec(codec, AC97_POWER_CONTROL);
++	}
++    
++	/* Check if Codec REF,ANL,DAC,ADC ready
++	*/
++	if ((temp & 0x7f0f) != 0x000f)
++		err("codec reg 26 status (0x%x) not ready!!", temp);
++}
++
++/* stop the ADC before calling */
++static void
++set_adc_rate(struct au1550_state *s, unsigned rate)
++{
++	struct dmabuf  *adc = &s->dma_adc;
++	struct dmabuf  *dac = &s->dma_dac;
++	unsigned        adc_rate, dac_rate;
++	u16             ac97_extstat;
++
++	if (s->no_vra) {
++		/* calc SRC factor
++		*/
++		adc->src_factor = ((96000 / rate) + 1) >> 1;
++		adc->sample_rate = 48000 / adc->src_factor;
++		return;
++	}
++
++	adc->src_factor = 1;
++
++	ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
++
++	rate = rate > 48000 ? 48000 : rate;
++
++	/* enable VRA
++	*/
++	wrcodec(s->codec, AC97_EXTENDED_STATUS,
++		ac97_extstat | AC97_EXTSTAT_VRA);
++
++	/* now write the sample rate
++	*/
++	wrcodec(s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate);
++
++	/* read it back for actual supported rate
++	*/
++	adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
++
++	pr_debug("set_adc_rate: set to %d Hz\n", adc_rate);
++
++	/* some codec's don't allow unequal DAC and ADC rates, in which case
++	 * writing one rate reg actually changes both.
++	 */
++	dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
++	if (dac->num_channels > 2)
++		wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate);
++	if (dac->num_channels > 4)
++		wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate);
++
++	adc->sample_rate = adc_rate;
++	dac->sample_rate = dac_rate;
++}
++
++/* stop the DAC before calling */
++static void
++set_dac_rate(struct au1550_state *s, unsigned rate)
++{
++	struct dmabuf  *dac = &s->dma_dac;
++	struct dmabuf  *adc = &s->dma_adc;
++	unsigned        adc_rate, dac_rate;
++	u16             ac97_extstat;
++
++	if (s->no_vra) {
++		/* calc SRC factor
++		*/
++		dac->src_factor = ((96000 / rate) + 1) >> 1;
++		dac->sample_rate = 48000 / dac->src_factor;
++		return;
++	}
++
++	dac->src_factor = 1;
++
++	ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
++
++	rate = rate > 48000 ? 48000 : rate;
++
++	/* enable VRA
++	*/
++	wrcodec(s->codec, AC97_EXTENDED_STATUS,
++		ac97_extstat | AC97_EXTSTAT_VRA);
++
++	/* now write the sample rate
++	*/
++	wrcodec(s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate);
++
++	/* I don't support different sample rates for multichannel,
++	 * so make these channels the same.
++	 */
++	if (dac->num_channels > 2)
++		wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate);
++	if (dac->num_channels > 4)
++		wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate);
++	/* read it back for actual supported rate
++	*/
++	dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE);
++
++	pr_debug("set_dac_rate: set to %d Hz\n", dac_rate);
++
++	/* some codec's don't allow unequal DAC and ADC rates, in which case
++	 * writing one rate reg actually changes both.
++	 */
++	adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE);
++
++	dac->sample_rate = dac_rate;
++	adc->sample_rate = adc_rate;
++}
++
++static void
++stop_dac(struct au1550_state *s)
++{
++	struct dmabuf  *db = &s->dma_dac;
++	u32		stat;
++	unsigned long   flags;
++
++	if (db->stopped)
++		return;
++
++	spin_lock_irqsave(&s->lock, flags);
++
++	au_writel(PSC_AC97PCR_TP, PSC_AC97PCR);
++	au_sync();
++
++	/* Wait for Transmit Busy to show disabled.
++	*/
++	do {
++		stat = readl(PSC_AC97STAT);
++		au_sync();
++	} while ((stat & PSC_AC97STAT_TB) != 0);
++
++	au1xxx_dbdma_reset(db->dmanr);
++
++	db->stopped = 1;
++
++	spin_unlock_irqrestore(&s->lock, flags);
++}
++
++static void
++stop_adc(struct au1550_state *s)
++{
++	struct dmabuf  *db = &s->dma_adc;
++	unsigned long   flags;
++	u32		stat;
++
++	if (db->stopped)
++		return;
++
++	spin_lock_irqsave(&s->lock, flags);
++
++	au_writel(PSC_AC97PCR_RP, PSC_AC97PCR);
++	au_sync();
++
++	/* Wait for Receive Busy to show disabled.
++	*/
++	do {
++		stat = readl(PSC_AC97STAT);
++		au_sync();
++	} while ((stat & PSC_AC97STAT_RB) != 0);
++
++	au1xxx_dbdma_reset(db->dmanr);
++
++	db->stopped = 1;
++
++	spin_unlock_irqrestore(&s->lock, flags);
++}
++
++
++static void
++set_xmit_slots(int num_channels)
++{
++	u32	ac97_config, stat;
++
++	ac97_config = au_readl(PSC_AC97CFG);
++	au_sync();
++	ac97_config &= ~(PSC_AC97CFG_TXSLOT_MASK | PSC_AC97CFG_DE_ENABLE);
++	au_writel(ac97_config, PSC_AC97CFG);
++	au_sync();
++
++	switch (num_channels) {
++	case 6:		/* stereo with surround and center/LFE,
++			 * slots 3,4,6,7,8,9
++			 */
++		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(6);
++		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(9);
++
++	case 4:		/* stereo with surround, slots 3,4,7,8 */
++		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(7);
++		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(8);
++
++	case 2:		/* stereo, slots 3,4 */
++	case 1:		/* mono */
++		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(3);
++		ac97_config |= PSC_AC97CFG_TXSLOT_ENA(4);
++	}
++
++	au_writel(ac97_config, PSC_AC97CFG);
++	au_sync();
++
++	ac97_config |= PSC_AC97CFG_DE_ENABLE;
++	au_writel(ac97_config, PSC_AC97CFG);
++	au_sync();
++
++	/* Wait for Device ready.
++	*/
++	do {
++		stat = readl(PSC_AC97STAT);
++		au_sync();
++	} while ((stat & PSC_AC97STAT_DR) == 0);
++}
++
++static void
++set_recv_slots(int num_channels)
++{
++	u32	ac97_config, stat;
++
++	ac97_config = au_readl(PSC_AC97CFG);
++	au_sync();
++	ac97_config &= ~(PSC_AC97CFG_RXSLOT_MASK | PSC_AC97CFG_DE_ENABLE);
++	au_writel(ac97_config, PSC_AC97CFG);
++	au_sync();
++
++	/* Always enable slots 3 and 4 (stereo). Slot 6 is
++	 * optional Mic ADC, which we don't support yet.
++	 */
++	ac97_config |= PSC_AC97CFG_RXSLOT_ENA(3);
++	ac97_config |= PSC_AC97CFG_RXSLOT_ENA(4);
++
++	au_writel(ac97_config, PSC_AC97CFG);
++	au_sync();
++
++	ac97_config |= PSC_AC97CFG_DE_ENABLE;
++	au_writel(ac97_config, PSC_AC97CFG);
++	au_sync();
++
++	/* Wait for Device ready.
++	*/
++	do {
++		stat = readl(PSC_AC97STAT);
++		au_sync();
++	} while ((stat & PSC_AC97STAT_DR) == 0);
++}
++
++static void
++start_dac(struct au1550_state *s)
++{
++	struct dmabuf  *db = &s->dma_dac;
++	unsigned long   flags;
++
++	if (!db->stopped)
++		return;
++
++	spin_lock_irqsave(&s->lock, flags);
++
++	set_xmit_slots(db->num_channels);
++	au_writel(PSC_AC97PCR_TC, PSC_AC97PCR);
++	au_sync();
++	au_writel(PSC_AC97PCR_TS, PSC_AC97PCR);
++	au_sync();
++
++	au1xxx_dbdma_start(db->dmanr);
++
++	db->stopped = 0;
++
++	spin_unlock_irqrestore(&s->lock, flags);
++}
++
++static void
++start_adc(struct au1550_state *s)
++{
++	struct dmabuf  *db = &s->dma_adc;
++	int	i;
++
++	if (!db->stopped)
++		return;
++
++	/* Put two buffers on the ring to get things started.
++	*/
++	for (i=0; i<2; i++) {
++		au1xxx_dbdma_put_dest(db->dmanr, db->nextIn, db->dma_fragsize);
++
++		db->nextIn += db->dma_fragsize;
++		if (db->nextIn >= db->rawbuf + db->dmasize)
++			db->nextIn -= db->dmasize;
++	}
++
++	set_recv_slots(db->num_channels);
++	au1xxx_dbdma_start(db->dmanr);
++	au_writel(PSC_AC97PCR_RC, PSC_AC97PCR);
++	au_sync();
++	au_writel(PSC_AC97PCR_RS, PSC_AC97PCR);
++	au_sync();
++
++	db->stopped = 0;
++}
++
++static int
++prog_dmabuf(struct au1550_state *s, struct dmabuf *db)
++{
++	unsigned user_bytes_per_sec;
++	unsigned        bufs;
++	unsigned        rate = db->sample_rate;
++
++	if (!db->rawbuf) {
++		db->ready = db->mapped = 0;
++		db->buforder = 5;	/* 32 * PAGE_SIZE */
++		db->rawbuf = kmalloc((PAGE_SIZE << db->buforder), GFP_KERNEL);
++		if (!db->rawbuf)
++			return -ENOMEM;
++	}
++
++	db->cnt_factor = 1;
++	if (db->sample_size == 8)
++		db->cnt_factor *= 2;
++	if (db->num_channels == 1)
++		db->cnt_factor *= 2;
++	db->cnt_factor *= db->src_factor;
++
++	db->count = 0;
++	db->dma_qcount = 0;
++	db->nextIn = db->nextOut = db->rawbuf;
++
++	db->user_bytes_per_sample = (db->sample_size>>3) * db->num_channels;
++	db->dma_bytes_per_sample = 2 * ((db->num_channels == 1) ?
++					2 : db->num_channels);
++
++	user_bytes_per_sec = rate * db->user_bytes_per_sample;
++	bufs = PAGE_SIZE << db->buforder;
++	if (db->ossfragshift) {
++		if ((1000 << db->ossfragshift) < user_bytes_per_sec)
++			db->fragshift = ld2(user_bytes_per_sec/1000);
++		else
++			db->fragshift = db->ossfragshift;
++	} else {
++		db->fragshift = ld2(user_bytes_per_sec / 100 /
++				    (db->subdivision ? db->subdivision : 1));
++		if (db->fragshift < 3)
++			db->fragshift = 3;
++	}
++
++	db->fragsize = 1 << db->fragshift;
++	db->dma_fragsize = db->fragsize * db->cnt_factor;
++	db->numfrag = bufs / db->dma_fragsize;
++
++	while (db->numfrag < 4 && db->fragshift > 3) {
++		db->fragshift--;
++		db->fragsize = 1 << db->fragshift;
++		db->dma_fragsize = db->fragsize * db->cnt_factor;
++		db->numfrag = bufs / db->dma_fragsize;
++	}
++
++	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
++		db->numfrag = db->ossmaxfrags;
++
++	db->dmasize = db->dma_fragsize * db->numfrag;
++	memset(db->rawbuf, 0, bufs);
++
++	pr_debug("prog_dmabuf: rate=%d, samplesize=%d, channels=%d\n",
++	    rate, db->sample_size, db->num_channels);
++	pr_debug("prog_dmabuf: fragsize=%d, cnt_factor=%d, dma_fragsize=%d\n",
++	    db->fragsize, db->cnt_factor, db->dma_fragsize);
++	pr_debug("prog_dmabuf: numfrag=%d, dmasize=%d\n", db->numfrag, db->dmasize);
++
++	db->ready = 1;
++	return 0;
++}
++
++static int
++prog_dmabuf_adc(struct au1550_state *s)
++{
++	stop_adc(s);
++	return prog_dmabuf(s, &s->dma_adc);
++
++}
++
++static int
++prog_dmabuf_dac(struct au1550_state *s)
++{
++	stop_dac(s);
++	return prog_dmabuf(s, &s->dma_dac);
++}
++
++
++/* hold spinlock for the following */
++static void
++dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct au1550_state *s = (struct au1550_state *) dev_id;
++	struct dmabuf  *db = &s->dma_dac;
++	u32	ac97c_stat;
++
++	ac97c_stat = au_readl(PSC_AC97STAT);
++	if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE))
++		pr_debug("AC97C status = 0x%08x\n", ac97c_stat);
++	db->dma_qcount--;
++
++	if (db->count >= db->fragsize) {
++		if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut,
++							db->fragsize) == 0) {
++			err("qcount < 2 and no ring room!");
++		}
++		db->nextOut += db->fragsize;
++		if (db->nextOut >= db->rawbuf + db->dmasize)
++			db->nextOut -= db->dmasize;
++		db->count -= db->fragsize;
++		db->total_bytes += db->dma_fragsize;
++		db->dma_qcount++;
++	}
++
++	/* wake up anybody listening */
++	if (waitqueue_active(&db->wait))
++		wake_up(&db->wait);
++}
++
++
++static void
++adc_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct	au1550_state *s = (struct au1550_state *)dev_id;
++	struct	dmabuf  *dp = &s->dma_adc;
++	u32	obytes;
++	char	*obuf;
++
++	/* Pull the buffer from the dma queue.
++	*/
++	au1xxx_dbdma_get_dest(dp->dmanr, (void *)(&obuf), &obytes);
++
++	if ((dp->count + obytes) > dp->dmasize) {
++		/* Overrun. Stop ADC and log the error
++		*/
++		stop_adc(s);
++		dp->error++;
++		err("adc overrun");
++		return;
++	}
++
++	/* Put a new empty buffer on the destination DMA.
++	*/
++	au1xxx_dbdma_put_dest(dp->dmanr, dp->nextIn, dp->dma_fragsize);
++
++	dp->nextIn += dp->dma_fragsize;
++	if (dp->nextIn >= dp->rawbuf + dp->dmasize)
++		dp->nextIn -= dp->dmasize;
++
++	dp->count += obytes;
++	dp->total_bytes += obytes;
++
++	/* wake up anybody listening
++	*/
++	if (waitqueue_active(&dp->wait))
++		wake_up(&dp->wait);
++
++}
++
++static loff_t
++au1550_llseek(struct file *file, loff_t offset, int origin)
++{
++	return -ESPIPE;
++}
++
++
++static int
++au1550_open_mixdev(struct inode *inode, struct file *file)
++{
++	file->private_data = &au1550_state;
++	return 0;
++}
++
++static int
++au1550_release_mixdev(struct inode *inode, struct file *file)
++{
++	return 0;
++}
++
++static int
++mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
++                        unsigned long arg)
++{
++	return codec->mixer_ioctl(codec, cmd, arg);
++}
++
++static int
++au1550_ioctl_mixdev(struct inode *inode, struct file *file,
++			       unsigned int cmd, unsigned long arg)
++{
++	struct au1550_state *s = (struct au1550_state *)file->private_data;
++	struct ac97_codec *codec = s->codec;
++
++	return mixdev_ioctl(codec, cmd, arg);
++}
++
++static /*const */ struct file_operations au1550_mixer_fops = {
++	owner:THIS_MODULE,
++	llseek:au1550_llseek,
++	ioctl:au1550_ioctl_mixdev,
++	open:au1550_open_mixdev,
++	release:au1550_release_mixdev,
++};
++
++static int
++drain_dac(struct au1550_state *s, int nonblock)
++{
++	unsigned long   flags;
++	int             count, tmo;
++
++	if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped)
++		return 0;
++
++	for (;;) {
++		spin_lock_irqsave(&s->lock, flags);
++		count = s->dma_dac.count;
++		spin_unlock_irqrestore(&s->lock, flags);
++		if (count <= s->dma_dac.fragsize)
++			break;
++		if (signal_pending(current))
++			break;
++		if (nonblock)
++			return -EBUSY;
++		tmo = 1000 * count / (s->no_vra ?
++				      48000 : s->dma_dac.sample_rate);
++		tmo /= s->dma_dac.dma_bytes_per_sample;
++		au1550_delay(tmo);
++	}
++	if (signal_pending(current))
++		return -ERESTARTSYS;
++	return 0;
++}
++
++static inline u8 S16_TO_U8(s16 ch)
++{
++	return (u8) (ch >> 8) + 0x80;
++}
++static inline s16 U8_TO_S16(u8 ch)
++{
++	return (s16) (ch - 0x80) << 8;
++}
++
++/*
++ * Translates user samples to dma buffer suitable for AC'97 DAC data:
++ *     If mono, copy left channel to right channel in dma buffer.
++ *     If 8 bit samples, cvt to 16-bit before writing to dma buffer.
++ *     If interpolating (no VRA), duplicate every audio frame src_factor times.
++ */
++static int
++translate_from_user(struct dmabuf *db, char* dmabuf, char* userbuf,
++							       int dmacount)
++{
++	int             sample, i;
++	int             interp_bytes_per_sample;
++	int             num_samples;
++	int             mono = (db->num_channels == 1);
++	char            usersample[12];
++	s16             ch, dmasample[6];
++
++	if (db->sample_size == 16 && !mono && db->src_factor == 1) {
++		/* no translation necessary, just copy
++		*/
++		if (copy_from_user(dmabuf, userbuf, dmacount))
++			return -EFAULT;
++		return dmacount;
++	}
++
++	interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
++	num_samples = dmacount / interp_bytes_per_sample;
++
++	for (sample = 0; sample < num_samples; sample++) {
++		if (copy_from_user(usersample, userbuf,
++				   db->user_bytes_per_sample)) {
++			return -EFAULT;
++		}
++
++		for (i = 0; i < db->num_channels; i++) {
++			if (db->sample_size == 8)
++				ch = U8_TO_S16(usersample[i]);
++			else
++				ch = *((s16 *) (&usersample[i * 2]));
++			dmasample[i] = ch;
++			if (mono)
++				dmasample[i + 1] = ch;	/* right channel */
++		}
++
++		/* duplicate every audio frame src_factor times
++		*/
++		for (i = 0; i < db->src_factor; i++)
++			memcpy(dmabuf, dmasample, db->dma_bytes_per_sample);
++
++		userbuf += db->user_bytes_per_sample;
++		dmabuf += interp_bytes_per_sample;
++	}
++
++	return num_samples * interp_bytes_per_sample;
++}
++
++/*
++ * Translates AC'97 ADC samples to user buffer:
++ *     If mono, send only left channel to user buffer.
++ *     If 8 bit samples, cvt from 16 to 8 bit before writing to user buffer.
++ *     If decimating (no VRA), skip over src_factor audio frames.
++ */
++static int
++translate_to_user(struct dmabuf *db, char* userbuf, char* dmabuf,
++							     int dmacount)
++{
++	int             sample, i;
++	int             interp_bytes_per_sample;
++	int             num_samples;
++	int             mono = (db->num_channels == 1);
++	char            usersample[12];
++
++	if (db->sample_size == 16 && !mono && db->src_factor == 1) {
++		/* no translation necessary, just copy
++		*/
++		if (copy_to_user(userbuf, dmabuf, dmacount))
++			return -EFAULT;
++		return dmacount;
++	}
++
++	interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor;
++	num_samples = dmacount / interp_bytes_per_sample;
++
++	for (sample = 0; sample < num_samples; sample++) {
++		for (i = 0; i < db->num_channels; i++) {
++			if (db->sample_size == 8)
++				usersample[i] =
++					S16_TO_U8(*((s16 *) (&dmabuf[i * 2])));
++			else
++				*((s16 *) (&usersample[i * 2])) =
++					*((s16 *) (&dmabuf[i * 2]));
++		}
++
++		if (copy_to_user(userbuf, usersample,
++				 db->user_bytes_per_sample)) {
++			return -EFAULT;
++		}
++
++		userbuf += db->user_bytes_per_sample;
++		dmabuf += interp_bytes_per_sample;
++	}
++
++	return num_samples * interp_bytes_per_sample;
++}
++
++/*
++ * Copy audio data to/from user buffer from/to dma buffer, taking care
++ * that we wrap when reading/writing the dma buffer. Returns actual byte
++ * count written to or read from the dma buffer.
++ */
++static int
++copy_dmabuf_user(struct dmabuf *db, char* userbuf, int count, int to_user)
++{
++	char           *bufptr = to_user ? db->nextOut : db->nextIn;
++	char           *bufend = db->rawbuf + db->dmasize;
++	int             cnt, ret;
++
++	if (bufptr + count > bufend) {
++		int             partial = (int) (bufend - bufptr);
++		if (to_user) {
++			if ((cnt = translate_to_user(db, userbuf,
++						     bufptr, partial)) < 0)
++				return cnt;
++			ret = cnt;
++			if ((cnt = translate_to_user(db, userbuf + partial,
++						     db->rawbuf,
++						     count - partial)) < 0)
++				return cnt;
++			ret += cnt;
++		} else {
++			if ((cnt = translate_from_user(db, bufptr, userbuf,
++						       partial)) < 0)
++				return cnt;
++			ret = cnt;
++			if ((cnt = translate_from_user(db, db->rawbuf,
++						       userbuf + partial,
++						       count - partial)) < 0)
++				return cnt;
++			ret += cnt;
++		}
++	} else {
++		if (to_user)
++			ret = translate_to_user(db, userbuf, bufptr, count);
++		else
++			ret = translate_from_user(db, bufptr, userbuf, count);
++	}
++
++	return ret;
++}
++
++
++static ssize_t
++au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
++{
++	struct au1550_state *s = (struct au1550_state *)file->private_data;
++	struct dmabuf  *db = &s->dma_adc;
++	DECLARE_WAITQUEUE(wait, current);
++	ssize_t         ret;
++	unsigned long   flags;
++	int             cnt, usercnt, avail;
++
++	if (db->mapped)
++		return -ENXIO;
++	if (!access_ok(VERIFY_WRITE, buffer, count))
++		return -EFAULT;
++	ret = 0;
++
++	count *= db->cnt_factor;
++
++	down(&s->sem);
++	add_wait_queue(&db->wait, &wait);
++
++	while (count > 0) {
++		/* wait for samples in ADC dma buffer
++		*/
++		do {
++			if (db->stopped)
++				start_adc(s);
++			spin_lock_irqsave(&s->lock, flags);
++			avail = db->count;
++			if (avail <= 0)
++				__set_current_state(TASK_INTERRUPTIBLE);
++			spin_unlock_irqrestore(&s->lock, flags);
++			if (avail <= 0) {
++				if (file->f_flags & O_NONBLOCK) {
++					if (!ret)
++						ret = -EAGAIN;
++					goto out;
++				}
++				up(&s->sem);
++				schedule();
++				if (signal_pending(current)) {
++					if (!ret)
++						ret = -ERESTARTSYS;
++					goto out2;
++				}
++				down(&s->sem);
++			}
++		} while (avail <= 0);
++
++		/* copy from nextOut to user
++		*/
++		if ((cnt = copy_dmabuf_user(db, buffer,
++					    count > avail ?
++					    avail : count, 1)) < 0) {
++			if (!ret)
++				ret = -EFAULT;
++			goto out;
++		}
++
++		spin_lock_irqsave(&s->lock, flags);
++		db->count -= cnt;
++		db->nextOut += cnt;
++		if (db->nextOut >= db->rawbuf + db->dmasize)
++			db->nextOut -= db->dmasize;
++		spin_unlock_irqrestore(&s->lock, flags);
++
++		count -= cnt;
++		usercnt = cnt / db->cnt_factor;
++		buffer += usercnt;
++		ret += usercnt;
++	}			/* while (count > 0) */
++
++out:
++	up(&s->sem);
++out2:
++	remove_wait_queue(&db->wait, &wait);
++	set_current_state(TASK_RUNNING);
++	return ret;
++}
++
++static ssize_t
++au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
++{
++	struct au1550_state *s = (struct au1550_state *)file->private_data;
++	struct dmabuf  *db = &s->dma_dac;
++	DECLARE_WAITQUEUE(wait, current);
++	ssize_t         ret = 0;
++	unsigned long   flags;
++	int             cnt, usercnt, avail;
++
++	pr_debug("write: count=%d\n", count);
++
++	if (db->mapped)
++		return -ENXIO;
++	if (!access_ok(VERIFY_READ, buffer, count))
++		return -EFAULT;
++
++	count *= db->cnt_factor;
++
++	down(&s->sem);	
++	add_wait_queue(&db->wait, &wait);
++
++	while (count > 0) {
++		/* wait for space in playback buffer
++		*/
++		do {
++			spin_lock_irqsave(&s->lock, flags);
++			avail = (int) db->dmasize - db->count;
++			if (avail <= 0)
++				__set_current_state(TASK_INTERRUPTIBLE);
++			spin_unlock_irqrestore(&s->lock, flags);
++			if (avail <= 0) {
++				if (file->f_flags & O_NONBLOCK) {
++					if (!ret)
++						ret = -EAGAIN;
++					goto out;
++				}
++				up(&s->sem);
++				schedule();
++				if (signal_pending(current)) {
++					if (!ret)
++						ret = -ERESTARTSYS;
++					goto out2;
++				}
++				down(&s->sem);
++			}
++		} while (avail <= 0);
++
++		/* copy from user to nextIn
++		*/
++		if ((cnt = copy_dmabuf_user(db, (char *) buffer,
++					    count > avail ?
++					    avail : count, 0)) < 0) {
++			if (!ret)
++				ret = -EFAULT;
++			goto out;
++		}
++
++		spin_lock_irqsave(&s->lock, flags);
++		db->count += cnt;
++		db->nextIn += cnt;
++		if (db->nextIn >= db->rawbuf + db->dmasize)
++			db->nextIn -= db->dmasize;
++
++		/* If the data is available, we want to keep two buffers
++		 * on the dma queue.  If the queue count reaches zero,
++		 * we know the dma has stopped.
++		 */
++		while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) {
++			if (au1xxx_dbdma_put_source(db->dmanr, db->nextOut,
++							db->fragsize) == 0) {
++				err("qcount < 2 and no ring room!");
++			}
++			db->nextOut += db->fragsize;
++			if (db->nextOut >= db->rawbuf + db->dmasize)
++				db->nextOut -= db->dmasize;
++			db->total_bytes += db->dma_fragsize;
++			if (db->dma_qcount == 0)
++				start_dac(s);
++			db->dma_qcount++;
++		}
++		spin_unlock_irqrestore(&s->lock, flags);
++
++		count -= cnt;
++		usercnt = cnt / db->cnt_factor;
++		buffer += usercnt;
++		ret += usercnt;
++	}			/* while (count > 0) */
++
++out:
++	up(&s->sem);
++out2:
++	remove_wait_queue(&db->wait, &wait);
++	set_current_state(TASK_RUNNING);
++	return ret;
++}
++
++
++/* No kernel lock - we have our own spinlock */
++static unsigned int
++au1550_poll(struct file *file, struct poll_table_struct *wait)
++{
++	struct au1550_state *s = (struct au1550_state *)file->private_data;
++	unsigned long   flags;
++	unsigned int    mask = 0;
++
++	if (file->f_mode & FMODE_WRITE) {
++		if (!s->dma_dac.ready)
++			return 0;
++		poll_wait(file, &s->dma_dac.wait, wait);
++	}
++	if (file->f_mode & FMODE_READ) {
++		if (!s->dma_adc.ready)
++			return 0;
++		poll_wait(file, &s->dma_adc.wait, wait);
++	}
++
++	spin_lock_irqsave(&s->lock, flags);
++	
++	if (file->f_mode & FMODE_READ) {
++		if (s->dma_adc.count >= (signed)s->dma_adc.dma_fragsize)
++			mask |= POLLIN | POLLRDNORM;
++	}
++	if (file->f_mode & FMODE_WRITE) {
++		if (s->dma_dac.mapped) {
++			if (s->dma_dac.count >=
++			    (signed)s->dma_dac.dma_fragsize) 
++				mask |= POLLOUT | POLLWRNORM;
++		} else {
++			if ((signed) s->dma_dac.dmasize >=
++			    s->dma_dac.count + (signed)s->dma_dac.dma_fragsize)
++				mask |= POLLOUT | POLLWRNORM;
++		}
++	}
++	spin_unlock_irqrestore(&s->lock, flags);
++	return mask;
++}
++
++static int
++au1550_mmap(struct file *file, struct vm_area_struct *vma)
++{
++	struct au1550_state *s = (struct au1550_state *)file->private_data;
++	struct dmabuf  *db;
++	unsigned long   size;
++	int ret = 0;
++
++	lock_kernel();
++	down(&s->sem);
++	if (vma->vm_flags & VM_WRITE)
++		db = &s->dma_dac;
++	else if (vma->vm_flags & VM_READ)
++		db = &s->dma_adc;
++	else {
++		ret = -EINVAL;
++		goto out;
++	}
++	if (vma->vm_pgoff != 0) {
++		ret = -EINVAL;
++		goto out;
++	}
++	size = vma->vm_end - vma->vm_start;
++	if (size > (PAGE_SIZE << db->buforder)) {
++		ret = -EINVAL;
++		goto out;
++	}
++	if (remap_page_range(vma, vma->vm_start, virt_to_phys(db->rawbuf),
++			     size, vma->vm_page_prot)) {
++		ret = -EAGAIN;
++		goto out;
++	}
++	vma->vm_flags &= ~VM_IO;
++	db->mapped = 1;
++out:
++	up(&s->sem);
++	unlock_kernel();
++	return ret;
++}
++
++#ifdef DEBUG
++static struct ioctl_str_t {
++	unsigned int    cmd;
++	const char     *str;
++} ioctl_str[] = {
++	{SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
++	{SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
++	{SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
++	{SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
++	{SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
++	{SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
++	{SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
++	{SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
++	{SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
++	{SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
++	{SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
++	{SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
++	{SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
++	{SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
++	{SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
++	{SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
++	{SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
++	{SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
++	{SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
++	{SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
++	{SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
++	{SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
++	{SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
++	{SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
++	{SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
++	{SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
++	{SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
++	{SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
++	{SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
++	{OSS_GETVERSION, "OSS_GETVERSION"},
++	{SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
++	{SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
++	{SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
++	{SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
++};
++#endif
++
++static int
++dma_count_done(struct dmabuf *db)
++{
++	if (db->stopped)
++		return 0;
++
++	return db->dma_fragsize - au1xxx_get_dma_residue(db->dmanr);
++}
++
++
++static int
++au1550_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
++							unsigned long arg)
++{
++	struct au1550_state *s = (struct au1550_state *)file->private_data;
++	unsigned long   flags;
++	audio_buf_info  abinfo;
++	count_info      cinfo;
++	int             count;
++	int             val, mapped, ret, diff;
++
++	mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
++		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
++
++#ifdef DEBUG
++	for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
++		if (ioctl_str[count].cmd == cmd)
++			break;
++	}
++	if (count < sizeof(ioctl_str) / sizeof(ioctl_str[0]))
++		pr_debug("ioctl %s, arg=0x%lxn", ioctl_str[count].str, arg);
++	else
++		pr_debug("ioctl 0x%x unknown, arg=0x%lx\n", cmd, arg);
++#endif
++
++	switch (cmd) {
++	case OSS_GETVERSION:
++		return put_user(SOUND_VERSION, (int *) arg);
++
++	case SNDCTL_DSP_SYNC:
++		if (file->f_mode & FMODE_WRITE)
++			return drain_dac(s, file->f_flags & O_NONBLOCK);
++		return 0;
++
++	case SNDCTL_DSP_SETDUPLEX:
++		return 0;
++
++	case SNDCTL_DSP_GETCAPS:
++		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
++				DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
++
++	case SNDCTL_DSP_RESET:
++		if (file->f_mode & FMODE_WRITE) {
++			stop_dac(s);
++			synchronize_irq();
++			s->dma_dac.count = s->dma_dac.total_bytes = 0;
++			s->dma_dac.nextIn = s->dma_dac.nextOut =
++				s->dma_dac.rawbuf;
++		}
++		if (file->f_mode & FMODE_READ) {
++			stop_adc(s);
++			synchronize_irq();
++			s->dma_adc.count = s->dma_adc.total_bytes = 0;
++			s->dma_adc.nextIn = s->dma_adc.nextOut =
++				s->dma_adc.rawbuf;
++		}
++		return 0;
++
++	case SNDCTL_DSP_SPEED:
++		if (get_user(val, (int *) arg))
++			return -EFAULT;
++		if (val >= 0) {
++			if (file->f_mode & FMODE_READ) {
++				stop_adc(s);
++				set_adc_rate(s, val);
++			}
++			if (file->f_mode & FMODE_WRITE) {
++				stop_dac(s);
++				set_dac_rate(s, val);
++			}
++			if (s->open_mode & FMODE_READ)
++				if ((ret = prog_dmabuf_adc(s)))
++					return ret;
++			if (s->open_mode & FMODE_WRITE)
++				if ((ret = prog_dmabuf_dac(s)))
++					return ret;
++		}
++		return put_user((file->f_mode & FMODE_READ) ?
++				s->dma_adc.sample_rate :
++				s->dma_dac.sample_rate,
++				(int *)arg);
++
++	case SNDCTL_DSP_STEREO:
++		if (get_user(val, (int *) arg))
++			return -EFAULT;
++		if (file->f_mode & FMODE_READ) {
++			stop_adc(s);
++			s->dma_adc.num_channels = val ? 2 : 1;
++			if ((ret = prog_dmabuf_adc(s)))
++				return ret;
++		}
++		if (file->f_mode & FMODE_WRITE) {
++			stop_dac(s);
++			s->dma_dac.num_channels = val ? 2 : 1;
++			if (s->codec_ext_caps & AC97_EXT_DACS) {
++				/* disable surround and center/lfe in AC'97
++				*/
++				u16 ext_stat = rdcodec(s->codec,
++						       AC97_EXTENDED_STATUS);
++				wrcodec(s->codec, AC97_EXTENDED_STATUS,
++					ext_stat | (AC97_EXTSTAT_PRI |
++						    AC97_EXTSTAT_PRJ |
++						    AC97_EXTSTAT_PRK));
++			}
++			if ((ret = prog_dmabuf_dac(s)))
++				return ret;
++		}
++		return 0;
++
++	case SNDCTL_DSP_CHANNELS:
++		if (get_user(val, (int *) arg))
++			return -EFAULT;
++		if (val != 0) {
++			if (file->f_mode & FMODE_READ) {
++				if (val < 0 || val > 2)
++					return -EINVAL;
++				stop_adc(s);
++				s->dma_adc.num_channels = val;
++				if ((ret = prog_dmabuf_adc(s)))
++					return ret;
++			}
++			if (file->f_mode & FMODE_WRITE) {
++				switch (val) {
++				case 1:
++				case 2:
++					break;
++				case 3:
++				case 5:
++					return -EINVAL;
++				case 4:
++					if (!(s->codec_ext_caps &
++					      AC97_EXTID_SDAC))
++						return -EINVAL;
++					break;
++				case 6:
++					if ((s->codec_ext_caps &
++					     AC97_EXT_DACS) != AC97_EXT_DACS)
++						return -EINVAL;
++					break;
++				default:
++					return -EINVAL;
++				}
++
++				stop_dac(s);
++				if (val <= 2 &&
++				    (s->codec_ext_caps & AC97_EXT_DACS)) {
++					/* disable surround and center/lfe
++					 * channels in AC'97
++					 */
++					u16             ext_stat =
++						rdcodec(s->codec,
++							AC97_EXTENDED_STATUS);
++					wrcodec(s->codec,
++						AC97_EXTENDED_STATUS,
++						ext_stat | (AC97_EXTSTAT_PRI |
++							    AC97_EXTSTAT_PRJ |
++							    AC97_EXTSTAT_PRK));
++				} else if (val >= 4) {
++					/* enable surround, center/lfe
++					 * channels in AC'97
++					 */
++					u16             ext_stat =
++						rdcodec(s->codec,
++							AC97_EXTENDED_STATUS);
++					ext_stat &= ~AC97_EXTSTAT_PRJ;
++					if (val == 6)
++						ext_stat &=
++							~(AC97_EXTSTAT_PRI |
++							  AC97_EXTSTAT_PRK);
++					wrcodec(s->codec,
++						AC97_EXTENDED_STATUS,
++						ext_stat);
++				}
++
++				s->dma_dac.num_channels = val;
++				if ((ret = prog_dmabuf_dac(s)))
++					return ret;
++			}
++		}
++		return put_user(val, (int *) arg);
++
++	case SNDCTL_DSP_GETFMTS:	/* Returns a mask */
++		return put_user(AFMT_S16_LE | AFMT_U8, (int *) arg);
++
++	case SNDCTL_DSP_SETFMT:	/* Selects ONE fmt */
++		if (get_user(val, (int *) arg))
++			return -EFAULT;
++		if (val != AFMT_QUERY) {
++			if (file->f_mode & FMODE_READ) {
++				stop_adc(s);
++				if (val == AFMT_S16_LE)
++					s->dma_adc.sample_size = 16;
++				else {
++					val = AFMT_U8;
++					s->dma_adc.sample_size = 8;
++				}
++				if ((ret = prog_dmabuf_adc(s)))
++					return ret;
++			}
++			if (file->f_mode & FMODE_WRITE) {
++				stop_dac(s);
++				if (val == AFMT_S16_LE)
++					s->dma_dac.sample_size = 16;
++				else {
++					val = AFMT_U8;
++					s->dma_dac.sample_size = 8;
++				}
++				if ((ret = prog_dmabuf_dac(s)))
++					return ret;
++			}
++		} else {
++			if (file->f_mode & FMODE_READ)
++				val = (s->dma_adc.sample_size == 16) ?
++					AFMT_S16_LE : AFMT_U8;
++			else
++				val = (s->dma_dac.sample_size == 16) ?
++					AFMT_S16_LE : AFMT_U8;
++		}
++		return put_user(val, (int *) arg);
++
++	case SNDCTL_DSP_POST:
++		return 0;
++
++	case SNDCTL_DSP_GETTRIGGER:
++		val = 0;
++		spin_lock_irqsave(&s->lock, flags);
++		if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
++			val |= PCM_ENABLE_INPUT;
++		if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
++			val |= PCM_ENABLE_OUTPUT;
++		spin_unlock_irqrestore(&s->lock, flags);
++		return put_user(val, (int *) arg);
++
++	case SNDCTL_DSP_SETTRIGGER:
++		if (get_user(val, (int *) arg))
++			return -EFAULT;
++		if (file->f_mode & FMODE_READ) {
++			if (val & PCM_ENABLE_INPUT)
++				start_adc(s);
++			else
++				stop_adc(s);
++		}
++		if (file->f_mode & FMODE_WRITE) {
++			if (val & PCM_ENABLE_OUTPUT)
++				start_dac(s);
++			else
++				stop_dac(s);
++		}
++		return 0;
++
++	case SNDCTL_DSP_GETOSPACE:
++		if (!(file->f_mode & FMODE_WRITE))
++			return -EINVAL;
++		abinfo.fragsize = s->dma_dac.fragsize;
++		spin_lock_irqsave(&s->lock, flags);
++		count = s->dma_dac.count;
++		count -= dma_count_done(&s->dma_dac);
++		spin_unlock_irqrestore(&s->lock, flags);
++		if (count < 0)
++			count = 0;
++		abinfo.bytes = (s->dma_dac.dmasize - count) /
++			s->dma_dac.cnt_factor;
++		abinfo.fragstotal = s->dma_dac.numfrag;
++		abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
++		pr_debug("ioctl SNDCTL_DSP_GETOSPACE: bytes=%d, fragments=%d\n", abinfo.bytes, abinfo.fragments);
++		return copy_to_user((void *) arg, &abinfo,
++				    sizeof(abinfo)) ? -EFAULT : 0;
++
++	case SNDCTL_DSP_GETISPACE:
++		if (!(file->f_mode & FMODE_READ))
++			return -EINVAL;
++		abinfo.fragsize = s->dma_adc.fragsize;
++		spin_lock_irqsave(&s->lock, flags);
++		count = s->dma_adc.count;
++		count += dma_count_done(&s->dma_adc);
++		spin_unlock_irqrestore(&s->lock, flags);
++		if (count < 0)
++			count = 0;
++		abinfo.bytes = count / s->dma_adc.cnt_factor;
++		abinfo.fragstotal = s->dma_adc.numfrag;
++		abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
++		return copy_to_user((void *) arg, &abinfo,
++				    sizeof(abinfo)) ? -EFAULT : 0;
++
++	case SNDCTL_DSP_NONBLOCK:
++		file->f_flags |= O_NONBLOCK;
++		return 0;
++
++	case SNDCTL_DSP_GETODELAY:
++		if (!(file->f_mode & FMODE_WRITE))
++			return -EINVAL;
++		spin_lock_irqsave(&s->lock, flags);
++		count = s->dma_dac.count;
++		count -= dma_count_done(&s->dma_dac);
++		spin_unlock_irqrestore(&s->lock, flags);
++		if (count < 0)
++			count = 0;
++		count /= s->dma_dac.cnt_factor;
++		return put_user(count, (int *) arg);
++
++	case SNDCTL_DSP_GETIPTR:
++		if (!(file->f_mode & FMODE_READ))
++			return -EINVAL;
++		spin_lock_irqsave(&s->lock, flags);
++		cinfo.bytes = s->dma_adc.total_bytes;
++		count = s->dma_adc.count;
++		if (!s->dma_adc.stopped) {
++			diff = dma_count_done(&s->dma_adc);
++			count += diff;
++			cinfo.bytes += diff;
++			cinfo.ptr =  virt_to_phys(s->dma_adc.nextIn) + diff -
++				virt_to_phys(s->dma_adc.rawbuf);
++		} else
++			cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) -
++				virt_to_phys(s->dma_adc.rawbuf);
++		if (s->dma_adc.mapped)
++			s->dma_adc.count &= (s->dma_adc.dma_fragsize-1);
++		spin_unlock_irqrestore(&s->lock, flags);
++		if (count < 0)
++			count = 0;
++		cinfo.blocks = count >> s->dma_adc.fragshift;
++		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
++
++	case SNDCTL_DSP_GETOPTR:
++		if (!(file->f_mode & FMODE_READ))
++			return -EINVAL;
++		spin_lock_irqsave(&s->lock, flags);
++		cinfo.bytes = s->dma_dac.total_bytes;
++		count = s->dma_dac.count;
++		if (!s->dma_dac.stopped) {
++			diff = dma_count_done(&s->dma_dac);
++			count -= diff;
++			cinfo.bytes += diff;
++			cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) + diff -
++				virt_to_phys(s->dma_dac.rawbuf);
++		} else
++			cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) -
++				virt_to_phys(s->dma_dac.rawbuf);
++		if (s->dma_dac.mapped)
++			s->dma_dac.count &= (s->dma_dac.dma_fragsize-1);
++		spin_unlock_irqrestore(&s->lock, flags);
++		if (count < 0)
++			count = 0;
++		cinfo.blocks = count >> s->dma_dac.fragshift;
++		return copy_to_user((void *) arg, &cinfo, sizeof(cinfo));
++
++	case SNDCTL_DSP_GETBLKSIZE:
++		if (file->f_mode & FMODE_WRITE)
++			return put_user(s->dma_dac.fragsize, (int *) arg);
++		else
++			return put_user(s->dma_adc.fragsize, (int *) arg);
++
++	case SNDCTL_DSP_SETFRAGMENT:
++		if (get_user(val, (int *) arg))
++			return -EFAULT;
++		if (file->f_mode & FMODE_READ) {
++			stop_adc(s);
++			s->dma_adc.ossfragshift = val & 0xffff;
++			s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
++			if (s->dma_adc.ossfragshift < 4)
++				s->dma_adc.ossfragshift = 4;
++			if (s->dma_adc.ossfragshift > 15)
++				s->dma_adc.ossfragshift = 15;
++			if (s->dma_adc.ossmaxfrags < 4)
++				s->dma_adc.ossmaxfrags = 4;
++			if ((ret = prog_dmabuf_adc(s)))
++				return ret;
++		}
++		if (file->f_mode & FMODE_WRITE) {
++			stop_dac(s);
++			s->dma_dac.ossfragshift = val & 0xffff;
++			s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
++			if (s->dma_dac.ossfragshift < 4)
++				s->dma_dac.ossfragshift = 4;
++			if (s->dma_dac.ossfragshift > 15)
++				s->dma_dac.ossfragshift = 15;
++			if (s->dma_dac.ossmaxfrags < 4)
++				s->dma_dac.ossmaxfrags = 4;
++			if ((ret = prog_dmabuf_dac(s)))
++				return ret;
++		}
++		return 0;
++
++	case SNDCTL_DSP_SUBDIVIDE:
++		if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
++		    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
++			return -EINVAL;
++		if (get_user(val, (int *) arg))
++			return -EFAULT;
++		if (val != 1 && val != 2 && val != 4)
++			return -EINVAL;
++		if (file->f_mode & FMODE_READ) {
++			stop_adc(s);
++			s->dma_adc.subdivision = val;
++			if ((ret = prog_dmabuf_adc(s)))
++				return ret;
++		}
++		if (file->f_mode & FMODE_WRITE) {
++			stop_dac(s);
++			s->dma_dac.subdivision = val;
++			if ((ret = prog_dmabuf_dac(s)))
++				return ret;
++		}
++		return 0;
++
++	case SOUND_PCM_READ_RATE:
++		return put_user((file->f_mode & FMODE_READ) ?
++				s->dma_adc.sample_rate :
++				s->dma_dac.sample_rate,
++				(int *)arg);
++
++	case SOUND_PCM_READ_CHANNELS:
++		if (file->f_mode & FMODE_READ)
++			return put_user(s->dma_adc.num_channels, (int *)arg);
++		else
++			return put_user(s->dma_dac.num_channels, (int *)arg);
++
++	case SOUND_PCM_READ_BITS:
++		if (file->f_mode & FMODE_READ)
++			return put_user(s->dma_adc.sample_size, (int *)arg);
++		else
++			return put_user(s->dma_dac.sample_size, (int *)arg);
++
++	case SOUND_PCM_WRITE_FILTER:
++	case SNDCTL_DSP_SETSYNCRO:
++	case SOUND_PCM_READ_FILTER:
++		return -EINVAL;
++	}
++
++	return mixdev_ioctl(s->codec, cmd, arg);
++}
++
++
++static int
++au1550_open(struct inode *inode, struct file *file)
++{
++	int             minor = MINOR(inode->i_rdev);
++	DECLARE_WAITQUEUE(wait, current);
++	struct au1550_state *s = &au1550_state;
++	int             ret;
++
++#ifdef DEBUG
++	if (file->f_flags & O_NONBLOCK)
++		pr_debug("open: non-blocking\n");
++	else
++		pr_debug("open: blocking\n");
++#endif
++	
++	file->private_data = s;
++	/* wait for device to become free */
++	down(&s->open_sem);
++	while (s->open_mode & file->f_mode) {
++		if (file->f_flags & O_NONBLOCK) {
++			up(&s->open_sem);
++			return -EBUSY;
++		}
++		add_wait_queue(&s->open_wait, &wait);
++		__set_current_state(TASK_INTERRUPTIBLE);
++		up(&s->open_sem);
++		schedule();
++		remove_wait_queue(&s->open_wait, &wait);
++		set_current_state(TASK_RUNNING);
++		if (signal_pending(current))
++			return -ERESTARTSYS;
++		down(&s->open_sem);
++	}
++
++	stop_dac(s);
++	stop_adc(s);
++
++	if (file->f_mode & FMODE_READ) {
++		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
++			s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
++		s->dma_adc.num_channels = 1;
++		s->dma_adc.sample_size = 8;
++		set_adc_rate(s, 8000);
++		if ((minor & 0xf) == SND_DEV_DSP16)
++			s->dma_adc.sample_size = 16;
++	}
++
++	if (file->f_mode & FMODE_WRITE) {
++		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
++			s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
++		s->dma_dac.num_channels = 1;
++		s->dma_dac.sample_size = 8;
++		set_dac_rate(s, 8000);
++		if ((minor & 0xf) == SND_DEV_DSP16)
++			s->dma_dac.sample_size = 16;
++	}
++
++	if (file->f_mode & FMODE_READ) {
++		if ((ret = prog_dmabuf_adc(s)))
++			return ret;
++	}
++	if (file->f_mode & FMODE_WRITE) {
++		if ((ret = prog_dmabuf_dac(s)))
++			return ret;
++	}
++
++	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
++	up(&s->open_sem);
++	init_MUTEX(&s->sem);
++	return 0;
++}
++
++static int
++au1550_release(struct inode *inode, struct file *file)
++{
++	struct au1550_state *s = (struct au1550_state *)file->private_data;
++
++	lock_kernel();
++	
++	if (file->f_mode & FMODE_WRITE) {
++		unlock_kernel();
++		drain_dac(s, file->f_flags & O_NONBLOCK);
++		lock_kernel();
++	}
++
++	down(&s->open_sem);
++	if (file->f_mode & FMODE_WRITE) {
++		stop_dac(s);
++		kfree(s->dma_dac.rawbuf);
++		s->dma_dac.rawbuf = NULL;
++	}
++	if (file->f_mode & FMODE_READ) {
++		stop_adc(s);
++		kfree(s->dma_adc.rawbuf);
++		s->dma_adc.rawbuf = NULL;
++	}
++	s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE));
++	up(&s->open_sem);
++	wake_up(&s->open_wait);
++	unlock_kernel();
++	return 0;
++}
++
++static /*const */ struct file_operations au1550_audio_fops = {
++	owner:		THIS_MODULE,
++	llseek:		au1550_llseek,
++	read:		au1550_read,
++	write:		au1550_write,
++	poll:		au1550_poll,
++	ioctl:		au1550_ioctl,
++	mmap:		au1550_mmap,
++	open:		au1550_open,
++	release:	au1550_release,
++};
++
++MODULE_AUTHOR("Advanced Micro Devices (AMD), dan at embeddededge.com");
++MODULE_DESCRIPTION("Au1550 AC97 Audio Driver");
++
++static int __devinit
++au1550_probe(void)
++{
++	struct au1550_state *s = &au1550_state;
++	int             val;
++
++	memset(s, 0, sizeof(struct au1550_state));
++
++	init_waitqueue_head(&s->dma_adc.wait);
++	init_waitqueue_head(&s->dma_dac.wait);
++	init_waitqueue_head(&s->open_wait);
++	init_MUTEX(&s->open_sem);
++	spin_lock_init(&s->lock);
++
++	s->codec = ac97_alloc_codec();
++	if(s->codec == NULL) {
++		err("Out of memory");
++		return -1;
++	}
++	s->codec->private_data = s;
++	s->codec->id = 0;
++	s->codec->codec_read = rdcodec;
++	s->codec->codec_write = wrcodec;
++	s->codec->codec_wait = waitcodec;
++
++	if (!request_mem_region(CPHYSADDR(AC97_PSC_SEL),
++			    0x30, "Au1550 AC97")) {
++		err("AC'97 ports in use");
++	}
++
++	/* Allocate the DMA Channels
++	*/
++	if ((s->dma_dac.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_MEM_CHAN,
++	    DBDMA_AC97_TX_CHAN, dac_dma_interrupt, (void *)s)) == 0) {
++		err("Can't get DAC DMA");
++		goto err_dma1;
++	}
++	au1xxx_dbdma_set_devwidth(s->dma_dac.dmanr, 16);
++	if (au1xxx_dbdma_ring_alloc(s->dma_dac.dmanr,
++					NUM_DBDMA_DESCRIPTORS) == 0) {
++		err("Can't get DAC DMA descriptors");
++		goto err_dma1;
++	}
++
++	if ((s->dma_adc.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_AC97_RX_CHAN,
++	    DBDMA_MEM_CHAN, adc_dma_interrupt, (void *)s)) == 0) {
++		err("Can't get ADC DMA");
++		goto err_dma2;
++	}
++	au1xxx_dbdma_set_devwidth(s->dma_adc.dmanr, 16);
++	if (au1xxx_dbdma_ring_alloc(s->dma_adc.dmanr,
++					NUM_DBDMA_DESCRIPTORS) == 0) {
++		err("Can't get ADC DMA descriptors");
++		goto err_dma2;
++	}
++
++	pr_info("DAC: DMA%d, ADC: DMA%d", DBDMA_AC97_TX_CHAN, DBDMA_AC97_RX_CHAN);
++
++	/* register devices */
++
++	if ((s->dev_audio = register_sound_dsp(&au1550_audio_fops, -1)) < 0)
++		goto err_dev1;
++	if ((s->codec->dev_mixer =
++	     register_sound_mixer(&au1550_mixer_fops, -1)) < 0)
++		goto err_dev2;
++
++	/* The GPIO for the appropriate PSC was configured by the
++	 * board specific start up.
++	 *
++	 * configure PSC for AC'97
++	 */
++	au_writel(0, AC97_PSC_CTRL);	/* Disable PSC */
++	au_sync();
++	au_writel((PSC_SEL_CLK_SERCLK | PSC_SEL_PS_AC97MODE), AC97_PSC_SEL);
++	au_sync();
++
++	/* cold reset the AC'97
++	*/
++	au_writel(PSC_AC97RST_RST, PSC_AC97RST);
++	au_sync();
++	au1550_delay(10);
++	au_writel(0, PSC_AC97RST);
++	au_sync();
++
++	/* need to delay around 500msec(bleech) to give
++	   some CODECs enough time to wakeup */
++	au1550_delay(500);
++
++	/* warm reset the AC'97 to start the bitclk
++	*/
++	au_writel(PSC_AC97RST_SNC, PSC_AC97RST);
++	au_sync();
++	udelay(100);
++	au_writel(0, PSC_AC97RST);
++	au_sync();
++
++	/* Enable PSC
++	*/
++	au_writel(PSC_CTRL_ENABLE, AC97_PSC_CTRL);
++	au_sync();
++
++	/* Wait for PSC ready.
++	*/
++	do {
++		val = readl(PSC_AC97STAT);
++		au_sync();
++	} while ((val & PSC_AC97STAT_SR) == 0);
++
++	/* Configure AC97 controller.
++	 * Deep FIFO, 16-bit sample, DMA, make sure DMA matches fifo size.
++	 */
++	val = PSC_AC97CFG_SET_LEN(16);
++	val |= PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8;
++
++	/* Enable device so we can at least
++	 * talk over the AC-link.
++	 */
++	au_writel(val, PSC_AC97CFG);
++	au_writel(PSC_AC97MSK_ALLMASK, PSC_AC97MSK);
++	au_sync();
++	val |= PSC_AC97CFG_DE_ENABLE;
++	au_writel(val, PSC_AC97CFG);
++	au_sync();
++
++	/* Wait for Device ready.
++	*/
++	do {
++		val = readl(PSC_AC97STAT);
++		au_sync();
++	} while ((val & PSC_AC97STAT_DR) == 0);
++
++	/* codec init */
++	if (!ac97_probe_codec(s->codec))
++		goto err_dev3;
++
++	s->codec_base_caps = rdcodec(s->codec, AC97_RESET);
++	s->codec_ext_caps = rdcodec(s->codec, AC97_EXTENDED_ID);
++	pr_info("AC'97 Base/Extended ID = %04x/%04x",
++	     s->codec_base_caps, s->codec_ext_caps);
++
++	if (!(s->codec_ext_caps & AC97_EXTID_VRA)) {
++		/* codec does not support VRA
++		*/
++		s->no_vra = 1;
++	} else if (!vra) {
++		/* Boot option says disable VRA
++		*/
++		u16 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS);
++		wrcodec(s->codec, AC97_EXTENDED_STATUS,
++			ac97_extstat & ~AC97_EXTSTAT_VRA);
++		s->no_vra = 1;
++	}
++	if (s->no_vra)
++		pr_info("no VRA, interpolating and decimating");
++
++	/* set mic to be the recording source */
++	val = SOUND_MASK_MIC;
++	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC,
++		     (unsigned long) &val);
++
++	return 0;
++
++ err_dev3:
++	unregister_sound_mixer(s->codec->dev_mixer);
++ err_dev2:
++	unregister_sound_dsp(s->dev_audio);
++ err_dev1:
++	au1xxx_dbdma_chan_free(s->dma_adc.dmanr);
++ err_dma2:
++	au1xxx_dbdma_chan_free(s->dma_dac.dmanr);
++ err_dma1:
++	release_mem_region(CPHYSADDR(AC97_PSC_SEL), 0x30);
++
++	ac97_release_codec(s->codec);
++	return -1;
++}
++
++static void __devinit
++au1550_remove(void)
++{
++	struct au1550_state *s = &au1550_state;
++
++	if (!s)
++		return;
++	synchronize_irq();
++	au1xxx_dbdma_chan_free(s->dma_adc.dmanr);
++	au1xxx_dbdma_chan_free(s->dma_dac.dmanr);
++	release_mem_region(CPHYSADDR(AC97_PSC_SEL), 0x30);
++	unregister_sound_dsp(s->dev_audio);
++	unregister_sound_mixer(s->codec->dev_mixer);
++	ac97_release_codec(s->codec);
++}
++
++static int __init
++init_au1550(void)
++{
++	return au1550_probe();
++}
++
++static void __exit
++cleanup_au1550(void)
++{
++	au1550_remove();
++}
++
++module_init(init_au1550);
++module_exit(cleanup_au1550);
++
++#ifndef MODULE
++
++static int __init
++au1550_setup(char *options)
++{
++	char           *this_opt;
++
++	if (!options || !*options)
++		return 0;
++
++	while ((this_opt = strsep(&options, ","))) {
++		if (!*this_opt)
++			continue;
++		if (!strncmp(this_opt, "vra", 3)) {
++			vra = 1;
++		}
++	}
++
++	return 1;
++}
++
++__setup("au1550_audio=", au1550_setup);
++
++#endif /* MODULE */
+diff -urpNX dontdiff linux-2.6.10/sound/oss/ite8172.c linux-2.6.10-mips/sound/oss/ite8172.c
+--- linux-2.6.10/sound/oss/ite8172.c	2004-12-24 22:34:26.000000000 +0100
++++ linux-2.6.10-mips/sound/oss/ite8172.c	2004-10-27 02:15:29.000000000 +0200
+@@ -96,6 +96,19 @@
+ #define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
+ 
+ 
++#define IT8172_MODULE_NAME "IT8172 audio"
++#define PFX IT8172_MODULE_NAME
++
++#ifdef IT8172_DEBUG
++#define dbg(format, arg...) printk(KERN_DEBUG PFX ": " format "\n" , ## arg)
++#else
++#define dbg(format, arg...) do {} while (0)
++#endif
++#define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
++#define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
++#define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
++
++
+ static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+ 
+ 
+@@ -285,7 +298,7 @@ struct it8172_state {
+ 	struct proc_dir_entry *ac97_ps;
+ #endif /* IT8172_DEBUG */
+ 
+-	struct ac97_codec *codec;
++	struct ac97_codec codec;
+ 
+ 	unsigned short pcc, capcc;
+ 	unsigned dacrate, adcrate;
+@@ -664,7 +677,7 @@ static inline void dealloc_dmabuf(struct
+ 		pend = virt_to_page(db->rawbuf +
+ 				    (PAGE_SIZE << db->buforder) - 1);
+ 		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+-			mem_map_unreserve(page);
++			ClearPageReserved(page);
+ 		pci_free_consistent(s->dev, PAGE_SIZE << db->buforder,
+ 				    db->rawbuf, db->dmaaddr);
+ 	}
+@@ -697,7 +710,7 @@ static int prog_dmabuf(struct it8172_sta
+ 		pend = virt_to_page(db->rawbuf +
+ 				    (PAGE_SIZE << db->buforder) - 1);
+ 		for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+-			mem_map_reserve(page);
++			SetPageReserved(page);
+ 	}
+ 
+ 	db->count = 0;
+@@ -858,12 +871,6 @@ static irqreturn_t it8172_interrupt(int 
+ 
+ /* --------------------------------------------------------------------- */
+ 
+-static loff_t it8172_llseek(struct file *file, loff_t offset, int origin)
+-{
+-	return -ESPIPE;
+-}
+-
+-
+ static int it8172_open_mixdev(struct inode *inode, struct file *file)
+ {
+ 	int minor = iminor(inode);
+@@ -874,7 +881,7 @@ static int it8172_open_mixdev(struct ino
+ 		if (list == &devs)
+ 			return -ENODEV;
+ 		s = list_entry(list, struct it8172_state, devs);
+-		if (s->codec->dev_mixer == minor)
++		if (s->codec.dev_mixer == minor)
+ 			break;
+ 	}
+ 	file->private_data = s;
+@@ -998,14 +1005,14 @@ static int it8172_ioctl_mixdev(struct in
+ 			       unsigned int cmd, unsigned long arg)
+ {
+ 	struct it8172_state *s = (struct it8172_state *)file->private_data;
+-	struct ac97_codec *codec = s->codec;
++	struct ac97_codec *codec = &s->codec;
+ 
+ 	return mixdev_ioctl(codec, cmd, arg);
+ }
+ 
+ static /*const*/ struct file_operations it8172_mixer_fops = {
+ 	.owner		= THIS_MODULE,
+-	.llseek		= it8172_llseek,
++	.llseek		= no_llseek,
+ 	.ioctl		= it8172_ioctl_mixdev,
+ 	.open		= it8172_open_mixdev,
+ 	.release	= it8172_release_mixdev,
+@@ -1409,14 +1416,14 @@ static int it8172_ioctl(struct inode *in
+ 	case SNDCTL_DSP_RESET:
+ 		if (file->f_mode & FMODE_WRITE) {
+ 			stop_dac(s);
+-			synchronize_irq();
++			synchronize_irq(s->irq);
+ 			s->dma_dac.count = s->dma_dac.total_bytes = 0;
+ 			s->dma_dac.nextIn = s->dma_dac.nextOut =
+ 				s->dma_dac.rawbuf;
+ 		}
+ 		if (file->f_mode & FMODE_READ) {
+ 			stop_adc(s);
+-			synchronize_irq();
++			synchronize_irq(s->irq);
+ 			s->dma_adc.count = s->dma_adc.total_bytes = 0;
+ 			s->dma_adc.nextIn = s->dma_adc.nextOut =
+ 				s->dma_adc.rawbuf;
+@@ -1651,7 +1658,9 @@ static int it8172_ioctl(struct inode *in
+ 		if (count < 0)
+ 			count = 0;
+ 		cinfo.blocks = count >> s->dma_adc.fragshift;
+-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
++		if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
++			return -EFAULT;
++		return 0;
+ 
+ 	case SNDCTL_DSP_GETOPTR:
+ 		if (!(file->f_mode & FMODE_READ))
+@@ -1674,7 +1683,9 @@ static int it8172_ioctl(struct inode *in
+ 		if (count < 0)
+ 			count = 0;
+ 		cinfo.blocks = count >> s->dma_dac.fragshift;
+-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
++		if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
++			return -EFAULT;
++		return 0;
+ 
+ 	case SNDCTL_DSP_GETBLKSIZE:
+ 		if (file->f_mode & FMODE_WRITE)
+@@ -1761,7 +1772,7 @@ static int it8172_ioctl(struct inode *in
+ 		return -EINVAL;
+ 	}
+ 
+-	return mixdev_ioctl(s->codec, cmd, arg);
++	return mixdev_ioctl(&s->codec, cmd, arg);
+ }
+ 
+ 
+@@ -1871,7 +1882,7 @@ static int it8172_release(struct inode *
+ 
+ static /*const*/ struct file_operations it8172_audio_fops = {
+ 	.owner		= THIS_MODULE,
+-	.llseek		= it8172_llseek,
++	.llseek		= no_llseek,
+ 	.read		= it8172_read,
+ 	.write		= it8172_write,
+ 	.poll		= it8172_poll,
+@@ -1929,7 +1940,7 @@ static int proc_it8172_dump (char *buf, 
+ 	len += sprintf (buf + len, "----------------------\n");
+ 	for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
+ 		len+= sprintf (buf + len, "reg %02x = %04x\n",
+-			       cnt, rdcodec(s->codec, cnt));
++			       cnt, rdcodec(&s->codec, cnt));
+ 
+ 	if (fpos >=len){
+ 		*start = buf;
+@@ -1994,16 +2005,11 @@ static int __devinit it8172_probe(struct
+ 	s->vendor = pcidev->vendor;
+ 	s->device = pcidev->device;
+ 	pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
+-	
+-	s->codec = ac97_alloc_codec();
+-	if(s->codec == NULL)
+-		goto err_codec;
+-		
+-	s->codec->private_data = s;
+-	s->codec->id = 0;
+-	s->codec->codec_read = rdcodec;
+-	s->codec->codec_write = wrcodec;
+-	s->codec->codec_wait = waitcodec;
++	s->codec.private_data = s;
++	s->codec.id = 0;
++	s->codec.codec_read = rdcodec;
++	s->codec.codec_write = wrcodec;
++	s->codec.codec_wait = waitcodec;
+ 
+ 	if (!request_region(s->io, pci_resource_len(pcidev,0),
+ 			    IT8172_MODULE_NAME)) {
+@@ -2022,12 +2028,12 @@ static int __devinit it8172_probe(struct
+ 	/* register devices */
+ 	if ((s->dev_audio = register_sound_dsp(&it8172_audio_fops, -1)) < 0)
+ 		goto err_dev1;
+-	if ((s->codec->dev_mixer =
++	if ((s->codec.dev_mixer =
+ 	     register_sound_mixer(&it8172_mixer_fops, -1)) < 0)
+ 		goto err_dev2;
+ 
+ #ifdef IT8172_DEBUG
+-	/* intialize the debug proc device */
++	/* initialize the debug proc device */
+ 	s->ps = create_proc_read_entry(IT8172_MODULE_NAME, 0, NULL,
+ 				       proc_it8172_dump, NULL);
+ #endif /* IT8172_DEBUG */
+@@ -2093,11 +2099,11 @@ static int __devinit it8172_probe(struct
+ 	outw(0, s->io+IT_AC_CODECC);
+     
+ 	/* codec init */
+-	if (!ac97_probe_codec(s->codec))
++	if (!ac97_probe_codec(&s->codec))
+ 		goto err_dev3;
+ 
+ 	/* add I2S as allowable recording source */
+-	s->codec->record_sources |= SOUND_MASK_I2S;
++	s->codec.record_sources |= SOUND_MASK_I2S;
+ 	
+ 	/* Enable Volume button interrupts */
+ 	imc = inb(s->io+IT_AC_IMC);
+@@ -2117,23 +2123,23 @@ static int __devinit it8172_probe(struct
+ 
+ 	/* set mic to be the recording source */
+ 	val = SOUND_MASK_MIC;
+-	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC,
++	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC,
+ 		     (unsigned long)&val);
+ 
+ 	/* mute AC'97 master and PCM when in S/PDIF mode */
+ 	if (s->spdif_volume != -1) {
+ 		val = 0x0000;
+-		s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_VOLUME,
++		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME,
+ 				     (unsigned long)&val);
+-		s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_PCM,
++		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM,
+ 				     (unsigned long)&val);
+ 	}
+     
+ #ifdef IT8172_DEBUG
+ 	sprintf(proc_str, "driver/%s/%d/ac97", IT8172_MODULE_NAME,
+-		s->codec->id);
++		s->codec.id);
+ 	s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
+-					     ac97_read_proc, s->codec);
++					     ac97_read_proc, &s->codec);
+ #endif
+     
+ 	/* store it in the driver field */
+@@ -2147,7 +2153,7 @@ static int __devinit it8172_probe(struct
+ 	return 0;
+ 
+  err_dev3:
+-	unregister_sound_mixer(s->codec->dev_mixer);
++	unregister_sound_mixer(s->codec.dev_mixer);
+  err_dev2:
+ 	unregister_sound_dsp(s->dev_audio);
+  err_dev1:
+@@ -2156,8 +2162,6 @@ static int __devinit it8172_probe(struct
+  err_irq:
+ 	release_region(s->io, pci_resource_len(pcidev,0));
+  err_region:
+- 	ac97_release_codec(s->codec);
+- err_codec:
+ 	kfree(s);
+ 	return -1;
+ }
+@@ -2173,12 +2177,11 @@ static void __devexit it8172_remove(stru
+ 	if (s->ps)
+ 		remove_proc_entry(IT8172_MODULE_NAME, NULL);
+ #endif /* IT8172_DEBUG */
+-	synchronize_irq();
++	synchronize_irq(s->irq);
+ 	free_irq(s->irq, s);
+ 	release_region(s->io, pci_resource_len(dev,0));
+ 	unregister_sound_dsp(s->dev_audio);
+-	unregister_sound_mixer(s->codec->dev_mixer);
+-	ac97_codec_release(s->codec);
++	unregister_sound_mixer(s->codec.dev_mixer);
+ 	kfree(s);
+ 	pci_set_drvdata(dev, NULL);
+ }
+@@ -2202,8 +2205,6 @@ static struct pci_driver it8172_driver =
+ 
+ static int __init init_it8172(void)
+ {
+-	if (!pci_present())   /* No PCI bus in this machine! */
+-		return -ENODEV;
+ 	info("version v0.5 time " __TIME__ " " __DATE__);
+ 	return pci_module_init(&it8172_driver);
+ }
+diff -urpNX dontdiff linux-2.6.10/sound/oss/nec_vrc5477.c linux-2.6.10-mips/sound/oss/nec_vrc5477.c
+--- linux-2.6.10/sound/oss/nec_vrc5477.c	2004-12-24 22:35:23.000000000 +0100
++++ linux-2.6.10-mips/sound/oss/nec_vrc5477.c	2004-09-21 13:12:32.000000000 +0200
+@@ -78,7 +78,6 @@
+ #include <linux/spinlock.h>
+ #include <linux/smp_lock.h>
+ #include <linux/ac97_codec.h>
+-#include <linux/interrupt.h>
+ #include <asm/io.h>
+ #include <asm/dma.h>
+ #include <asm/uaccess.h>
+@@ -396,10 +395,47 @@ static void set_dac_rate(struct vrc5477_
+ 	}
+ }
+ 
++static int ac97_codec_not_present(struct ac97_codec *codec)
++{
++	struct vrc5477_ac97_state *s = 
++		(struct vrc5477_ac97_state *)codec->private_data;
++	unsigned long flags;
++	unsigned short count  = 0xffff; 
++
++	spin_lock_irqsave(&s->lock, flags);
++
++	/* wait until we can access codec registers */
++	do {
++	       if (!(inl(s->io + VRC5477_CODEC_WR) & 0x80000000))
++		       break;
++	} while (--count);
++
++	if (count == 0) {
++		spin_unlock_irqrestore(&s->lock, flags);
++		return -1;
++	}
++
++	/* write 0 to reset */
++	outl((AC97_RESET << 16) | 0, s->io + VRC5477_CODEC_WR);
++
++	/* test whether we get a response from ac97 chip */
++	count  = 0xffff; 
++	do { 
++	       if (!(inl(s->io + VRC5477_CODEC_WR) & 0x80000000))
++		       break;
++	} while (--count);
++
++	if (count == 0) {
++		spin_unlock_irqrestore(&s->lock, flags);
++		return -1;
++	}
++	spin_unlock_irqrestore(&s->lock, flags);
++	return 0;
++}
+ 
+ /* --------------------------------------------------------------------- */
+ 
+-static inline void 
++extern inline void 
+ stop_dac(struct vrc5477_ac97_state *s)
+ {
+ 	struct dmabuf* db = &s->dma_dac;
+@@ -517,7 +553,7 @@ static void start_dac(struct vrc5477_ac9
+ 	spin_unlock_irqrestore(&s->lock, flags);
+ }	
+ 
+-static inline void stop_adc(struct vrc5477_ac97_state *s)
++extern inline void stop_adc(struct vrc5477_ac97_state *s)
+ {
+ 	struct dmabuf* db = &s->dma_adc;
+ 	unsigned long flags;
+@@ -616,7 +652,7 @@ static void start_adc(struct vrc5477_ac9
+ #define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
+ #define DMABUF_MINORDER 1
+ 
+-static inline void dealloc_dmabuf(struct vrc5477_ac97_state *s, 
++extern inline void dealloc_dmabuf(struct vrc5477_ac97_state *s, 
+ 				  struct dmabuf *db)
+ {
+ 	if (db->lbuf) {
+@@ -1858,6 +1894,13 @@ static int __devinit vrc5477_ac97_probe(
+ 
+         }
+ 
++	/* test if get response from ac97, if not return */
++        if (ac97_codec_not_present(&(s->codec))) {
++		printk(KERN_ERR PFX "no ac97 codec\n");
++		goto err_region;
++
++        }
++
+ 	if (!request_region(s->io, pci_resource_len(pcidev,0),
+ 			    VRC5477_AC97_MODULE_NAME)) {
+ 		printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n",
+@@ -1973,7 +2016,7 @@ static void __devexit vrc5477_ac97_remov
+ 		remove_proc_entry(VRC5477_AC97_MODULE_NAME, NULL);
+ #endif /* VRC5477_AC97_DEBUG */
+ 
+-	synchronize_irq(s->irq);
++	synchronize_irq();
+ 	free_irq(s->irq, s);
+ 	release_region(s->io, pci_resource_len(dev,0));
+ 	unregister_sound_dsp(s->dev_audio);
+@@ -1996,7 +2039,7 @@ static struct pci_driver vrc5477_ac97_dr
+ 	.name		= VRC5477_AC97_MODULE_NAME,
+ 	.id_table	= id_table,
+ 	.probe		= vrc5477_ac97_probe,
+-	.remove		= __devexit_p(vrc5477_ac97_remove),
++	.remove		= __devexit_p(vrc5477_ac97_remove)
+ };
+ 
+ static int __init init_vrc5477_ac97(void)
+diff -urpNX dontdiff linux-2.6.10/sound/oss/swarm_cs4297a.c linux-2.6.10-mips/sound/oss/swarm_cs4297a.c
+--- linux-2.6.10/sound/oss/swarm_cs4297a.c	2004-12-24 22:34:58.000000000 +0100
++++ linux-2.6.10-mips/sound/oss/swarm_cs4297a.c	2005-01-10 03:08:20.000000000 +0100
+@@ -10,7 +10,9 @@
+ *               (audio at crystal.cirrus.com).
+ *            -- adapted from cs4281 PCI driver for cs4297a on
+ *               BCM1250 Synchronous Serial interface
+-*               (kwalker at broadcom.com)
++*               (Kip Walker, Broadcom Corp.)
++*      Copyright (C) 2004  Maciej W. Rozycki
++*      Copyright (C) 2005 Ralf Baechle (ralf at linux-mips.org)
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+@@ -71,12 +73,13 @@
+ #include <linux/pci.h>
+ #include <linux/bitops.h>
+ #include <linux/interrupt.h>
+-#include <asm/io.h>
+-#include <asm/dma.h>
+ #include <linux/init.h>
+ #include <linux/poll.h>
+ #include <linux/smp_lock.h>
+-#include <linux/wrapper.h>
++
++#include <asm/byteorder.h>
++#include <asm/dma.h>
++#include <asm/io.h>
+ #include <asm/uaccess.h>
+ 
+ #include <asm/sibyte/sb1250_regs.h>
+@@ -86,7 +89,6 @@
+ #include <asm/sibyte/sb1250_syncser.h>
+ #include <asm/sibyte/sb1250_mac.h>
+ #include <asm/sibyte/sb1250.h>
+-#include <asm/sibyte/64bit.h>
+ 
+ struct cs4297a_state;
+ 
+@@ -561,44 +563,44 @@ static int ser_init(struct cs4297a_state
+         CS_DBGOUT(CS_INIT, 2, 
+                   printk(KERN_INFO "cs4297a: Setting up serial parameters\n"));
+ 
+-        out64(M_SYNCSER_CMD_RX_RESET | M_SYNCSER_CMD_TX_RESET, SS_CSR(R_SER_CMD));
++        __raw_writeq(M_SYNCSER_CMD_RX_RESET | M_SYNCSER_CMD_TX_RESET, SS_CSR(R_SER_CMD));
+ 
+-        out64(M_SYNCSER_MSB_FIRST, SS_CSR(R_SER_MODE));
+-        out64(32, SS_CSR(R_SER_MINFRM_SZ));
+-        out64(32, SS_CSR(R_SER_MAXFRM_SZ));
+-
+-        out64(1, SS_CSR(R_SER_TX_RD_THRSH));
+-        out64(4, SS_CSR(R_SER_TX_WR_THRSH));
+-        out64(8, SS_CSR(R_SER_RX_RD_THRSH));
++        __raw_writeq(M_SYNCSER_MSB_FIRST, SS_CSR(R_SER_MODE));
++        __raw_writeq(32, SS_CSR(R_SER_MINFRM_SZ));
++        __raw_writeq(32, SS_CSR(R_SER_MAXFRM_SZ));
++
++        __raw_writeq(1, SS_CSR(R_SER_TX_RD_THRSH));
++        __raw_writeq(4, SS_CSR(R_SER_TX_WR_THRSH));
++        __raw_writeq(8, SS_CSR(R_SER_RX_RD_THRSH));
+ 
+         /* This looks good from experimentation */
+-        out64((M_SYNCSER_TXSYNC_INT | V_SYNCSER_TXSYNC_DLY(0) | M_SYNCSER_TXCLK_EXT |
++        __raw_writeq((M_SYNCSER_TXSYNC_INT | V_SYNCSER_TXSYNC_DLY(0) | M_SYNCSER_TXCLK_EXT |
+                M_SYNCSER_RXSYNC_INT | V_SYNCSER_RXSYNC_DLY(1) | M_SYNCSER_RXCLK_EXT | M_SYNCSER_RXSYNC_EDGE),
+               SS_CSR(R_SER_LINE_MODE));
+ 
+         /* This looks good from experimentation */
+-        out64(V_SYNCSER_SEQ_COUNT(14) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE,
++        __raw_writeq(V_SYNCSER_SEQ_COUNT(14) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE,
+               SS_TXTBL(0));
+-        out64(V_SYNCSER_SEQ_COUNT(15) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
++        __raw_writeq(V_SYNCSER_SEQ_COUNT(15) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
+               SS_TXTBL(1));
+-        out64(V_SYNCSER_SEQ_COUNT(13) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
++        __raw_writeq(V_SYNCSER_SEQ_COUNT(13) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
+               SS_TXTBL(2));
+-        out64(V_SYNCSER_SEQ_COUNT( 0) | M_SYNCSER_SEQ_ENABLE |
++        __raw_writeq(V_SYNCSER_SEQ_COUNT( 0) | M_SYNCSER_SEQ_ENABLE |
+               M_SYNCSER_SEQ_STROBE | M_SYNCSER_SEQ_LAST, SS_TXTBL(3));
+ 
+-        out64(V_SYNCSER_SEQ_COUNT(14) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE,
++        __raw_writeq(V_SYNCSER_SEQ_COUNT(14) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE,
+               SS_RXTBL(0));
+-        out64(V_SYNCSER_SEQ_COUNT(15) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
++        __raw_writeq(V_SYNCSER_SEQ_COUNT(15) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
+               SS_RXTBL(1));
+-        out64(V_SYNCSER_SEQ_COUNT(13) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
++        __raw_writeq(V_SYNCSER_SEQ_COUNT(13) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_BYTE,
+               SS_RXTBL(2));
+-        out64(V_SYNCSER_SEQ_COUNT( 0) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE |
++        __raw_writeq(V_SYNCSER_SEQ_COUNT( 0) | M_SYNCSER_SEQ_ENABLE | M_SYNCSER_SEQ_STROBE |
+               M_SYNCSER_SEQ_LAST, SS_RXTBL(3));
+ 
+         for (i=4; i<16; i++) {
+                 /* Just in case... */
+-                out64(M_SYNCSER_SEQ_LAST, SS_TXTBL(i));
+-                out64(M_SYNCSER_SEQ_LAST, SS_RXTBL(i));
++                __raw_writeq(M_SYNCSER_SEQ_LAST, SS_TXTBL(i));
++                __raw_writeq(M_SYNCSER_SEQ_LAST, SS_RXTBL(i));
+         }
+ 
+         return 0;
+@@ -620,7 +622,7 @@ static int init_serdma(serdma_t *dma)
+         memset(dma->descrtab, 0, dma->ringsz * sizeof(serdma_descr_t));
+         dma->descrtab_end = dma->descrtab + dma->ringsz;
+ 	/* XXX bloddy mess, use proper DMA API here ...  */
+-	dma->descrtab_phys = PHYSADDR((int)dma->descrtab);
++	dma->descrtab_phys = CPHYSADDR((long)dma->descrtab);
+         dma->descr_add = dma->descr_rem = dma->descrtab;
+ 
+         /* Frame buffer area */
+@@ -631,7 +633,7 @@ static int init_serdma(serdma_t *dma)
+                 return -1;
+         }
+         memset(dma->dma_buf, 0, DMA_BUF_SIZE);
+-        dma->dma_buf_phys = PHYSADDR((int)dma->dma_buf);
++        dma->dma_buf_phys = CPHYSADDR((long)dma->dma_buf);
+ 
+         /* Samples buffer area */
+         dma->sbufsz = SAMPLE_BUF_SIZE;
+@@ -665,8 +667,8 @@ static int dma_init(struct cs4297a_state
+             init_serdma(&s->dma_dac))
+                 return -1;
+ 
+-        if (in64(SS_CSR(R_SER_DMA_DSCR_COUNT_RX))||
+-            in64(SS_CSR(R_SER_DMA_DSCR_COUNT_TX))) {
++        if (__raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_RX))||
++            __raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_TX))) {
+                 panic("DMA state corrupted?!");
+         }
+ 
+@@ -681,38 +683,38 @@ static int dma_init(struct cs4297a_state
+                 s->dma_adc.descrtab[i].descr_b = 0;
+         }
+ 
+-        out64((M_DMA_EOP_INT_EN | V_DMA_INT_PKTCNT(DMA_INT_CNT) |
++        __raw_writeq((M_DMA_EOP_INT_EN | V_DMA_INT_PKTCNT(DMA_INT_CNT) |
+                V_DMA_RINGSZ(DMA_DESCR) | M_DMA_TDX_EN),
+               SS_CSR(R_SER_DMA_CONFIG0_RX));
+-        out64(M_DMA_L2CA, SS_CSR(R_SER_DMA_CONFIG1_RX));
+-        out64(s->dma_adc.descrtab_phys, SS_CSR(R_SER_DMA_DSCR_BASE_RX));
++        __raw_writeq(M_DMA_L2CA, SS_CSR(R_SER_DMA_CONFIG1_RX));
++        __raw_writeq(s->dma_adc.descrtab_phys, SS_CSR(R_SER_DMA_DSCR_BASE_RX));
+ 
+-        out64(V_DMA_RINGSZ(DMA_DESCR), SS_CSR(R_SER_DMA_CONFIG0_TX));
+-        out64(M_DMA_L2CA | M_DMA_NO_DSCR_UPDT, SS_CSR(R_SER_DMA_CONFIG1_TX));
+-        out64(s->dma_dac.descrtab_phys, SS_CSR(R_SER_DMA_DSCR_BASE_TX));
++        __raw_writeq(V_DMA_RINGSZ(DMA_DESCR), SS_CSR(R_SER_DMA_CONFIG0_TX));
++        __raw_writeq(M_DMA_L2CA | M_DMA_NO_DSCR_UPDT, SS_CSR(R_SER_DMA_CONFIG1_TX));
++        __raw_writeq(s->dma_dac.descrtab_phys, SS_CSR(R_SER_DMA_DSCR_BASE_TX));
+ 
+         /* Prep the receive DMA descriptor ring */
+-        out64(DMA_DESCR, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
++        __raw_writeq(DMA_DESCR, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
+ 
+-        out64(M_SYNCSER_DMA_RX_EN | M_SYNCSER_DMA_TX_EN, SS_CSR(R_SER_DMA_ENABLE));
++        __raw_writeq(M_SYNCSER_DMA_RX_EN | M_SYNCSER_DMA_TX_EN, SS_CSR(R_SER_DMA_ENABLE));
+ 
+-        out64((M_SYNCSER_RX_SYNC_ERR | M_SYNCSER_RX_OVERRUN | M_SYNCSER_RX_EOP_COUNT),
++        __raw_writeq((M_SYNCSER_RX_SYNC_ERR | M_SYNCSER_RX_OVERRUN | M_SYNCSER_RX_EOP_COUNT),
+               SS_CSR(R_SER_INT_MASK));
+ 
+         /* Enable the rx/tx; let the codec warm up to the sync and
+            start sending good frames before the receive FIFO is
+            enabled */
+-        out64(M_SYNCSER_CMD_TX_EN, SS_CSR(R_SER_CMD));
++        __raw_writeq(M_SYNCSER_CMD_TX_EN, SS_CSR(R_SER_CMD));
+         udelay(1000);
+-        out64(M_SYNCSER_CMD_RX_EN | M_SYNCSER_CMD_TX_EN, SS_CSR(R_SER_CMD));
++        __raw_writeq(M_SYNCSER_CMD_RX_EN | M_SYNCSER_CMD_TX_EN, SS_CSR(R_SER_CMD));
+ 
+         /* XXXKW is this magic? (the "1" part) */
+-        while ((in64(SS_CSR(R_SER_STATUS)) & 0xf1) != 1)
++        while ((__raw_readq(SS_CSR(R_SER_STATUS)) & 0xf1) != 1)
+                 ;
+ 
+         CS_DBGOUT(CS_INIT, 4, 
+                   printk(KERN_INFO "cs4297a: status: %08x\n",
+-                         (unsigned int)(in64(SS_CSR(R_SER_STATUS)) & 0xffffffff)));
++                         (unsigned int)(__raw_readq(SS_CSR(R_SER_STATUS)) & 0xffffffff)));
+ 
+         return 0;
+ }
+@@ -752,8 +754,8 @@ static int serdma_reg_access(struct cs42
+ 
+                 descr = &d->descrtab[swptr];
+                 data_p = &d->dma_buf[swptr * 4];
+-                *data_p = data;
+-                out64(1, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
++		*data_p = cpu_to_be64(data);
++                __raw_writeq(1, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
+                 CS_DBGOUT(CS_DESCR, 4,
+                           printk(KERN_INFO "cs4297a: add_tx  %p (%x -> %x)\n",
+                                  data_p, swptr, d->hwptr));
+@@ -807,7 +809,7 @@ static void stop_dac(struct cs4297a_stat
+         /* XXXKW what do I really want here?  My theory for now is
+            that I just flip the "ena" bit, and the interrupt handler
+            will stop processing the xmit channel */
+-        out64((s->ena & FMODE_READ) ? M_SYNCSER_DMA_RX_EN : 0,
++        __raw_writeq((s->ena & FMODE_READ) ? M_SYNCSER_DMA_RX_EN : 0,
+               SS_CSR(R_SER_DMA_ENABLE));
+ #endif
+ 
+@@ -926,11 +928,11 @@ static void cs4297a_update_ptr(struct cs
+         serdma_descr_t *descr;
+ 
+ 	// update ADC pointer 
+-        status = intflag ? in64(SS_CSR(R_SER_STATUS)) : 0;
++        status = intflag ? __raw_readq(SS_CSR(R_SER_STATUS)) : 0;
+ 
+ 	if ((s->ena & FMODE_READ) || (status & (M_SYNCSER_RX_EOP_COUNT))) {
+                 d = &s->dma_adc;
+-                hwptr = (unsigned) (((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
++                hwptr = (unsigned) (((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
+                                      d->descrtab_phys) / sizeof(serdma_descr_t));
+ 
+                 if (s->ena & FMODE_READ) {
+@@ -944,12 +946,12 @@ static void cs4297a_update_ptr(struct cs
+                         s_ptr = (u32 *)&(d->dma_buf[d->swptr*4]);
+                         descr = &d->descrtab[d->swptr];
+                         while (diff2--) {
+-                                u64 data = *(u64 *)s_ptr;
++				u64 data = be64_to_cpu(*(u64 *)s_ptr);
+                                 u64 descr_a;
+                                 u16 left, right;
+                                 descr_a = descr->descr_a;
+                                 descr->descr_a &= ~M_DMA_SERRX_SOP;
+-                                if ((descr_a & M_DMA_DSCRA_A_ADDR) != PHYSADDR((int)s_ptr)) {
++                                if ((descr_a & M_DMA_DSCRA_A_ADDR) != CPHYSADDR((long)s_ptr)) {
+                                         printk(KERN_ERR "cs4297a: RX Bad address (read)\n");
+                                 }
+                                 if (((data & 0x9800000000000000) != 0x9800000000000000) ||
+@@ -971,10 +973,11 @@ static void cs4297a_update_ptr(struct cs
+                                         continue;
+                                 }
+                                 good_diff++;
+-                                left = ((s_ptr[1] & 0xff) << 8) | ((s_ptr[2] >> 24) & 0xff);
+-                                right = (s_ptr[2] >> 4) & 0xffff;
+-                                *d->sb_hwptr++ = left;
+-                                *d->sb_hwptr++ = right;
++				left = ((be32_to_cpu(s_ptr[1]) & 0xff) << 8) |
++				       ((be32_to_cpu(s_ptr[2]) >> 24) & 0xff);
++				right = (be32_to_cpu(s_ptr[2]) >> 4) & 0xffff;
++				*d->sb_hwptr++ = cpu_to_be16(left);
++				*d->sb_hwptr++ = cpu_to_be16(right);
+                                 if (d->sb_hwptr == d->sb_end)
+                                         d->sb_hwptr = d->sample_buf;
+                                 descr++;
+@@ -991,7 +994,7 @@ static void cs4297a_update_ptr(struct cs
+                                 printk(KERN_ERR "cs4297a: bogus receive overflow!!\n");
+                         }
+                         d->swptr = (d->swptr + diff) % d->ringsz;
+-                        out64(diff, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
++                        __raw_writeq(diff, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
+                         if (d->mapped) {
+                                 if (d->count >= (signed) d->fragsize)
+                                         wake_up(&d->wait);
+@@ -1019,11 +1022,11 @@ static void cs4297a_update_ptr(struct cs
+                            here because of an interrupt, so there must
+                            be a buffer to process. */
+                         do {
+-                                data = *data_p;
+-                                if ((descr->descr_a & M_DMA_DSCRA_A_ADDR) != PHYSADDR((int)data_p)) {
+-                                        printk(KERN_ERR "cs4297a: RX Bad address %d (%x %x)\n", d->swptr,
+-                                               (int)(descr->descr_a & M_DMA_DSCRA_A_ADDR),
+-                                               (int)PHYSADDR((int)data_p));
++				data = be64_to_cpu(*data_p);
++                                if ((descr->descr_a & M_DMA_DSCRA_A_ADDR) != CPHYSADDR((long)data_p)) {
++                                        printk(KERN_ERR "cs4297a: RX Bad address %d (%llx %lx)\n", d->swptr,
++                                               (long long)(descr->descr_a & M_DMA_DSCRA_A_ADDR),
++                                               (long)CPHYSADDR((long)data_p));
+                                 }
+                                 if (!(data & (1LL << 63)) ||
+                                     !(descr->descr_a & M_DMA_SERRX_SOP) ||
+@@ -1047,7 +1050,7 @@ static void cs4297a_update_ptr(struct cs
+                                         d->swptr = 0;
+                                         data_p = d->dma_buf;
+                                 }
+-                                out64(1, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
++                                __raw_writeq(1, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
+                         } while (--diff);
+                         d->hwptr = hwptr;
+ 
+@@ -1072,7 +1075,7 @@ static void cs4297a_update_ptr(struct cs
+ 	//
+ 	if (s->ena & FMODE_WRITE) {
+                 serdma_t *d = &s->dma_dac;
+-                hwptr = (unsigned) (((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
++                hwptr = (unsigned) (((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
+                                      d->descrtab_phys) / sizeof(serdma_descr_t));
+                 diff = (d->ringsz + hwptr - d->hwptr) % d->ringsz;
+                 CS_DBGOUT(CS_WAVE_WRITE, 4, printk(KERN_INFO
+@@ -1611,7 +1614,7 @@ static int drain_dac(struct cs4297a_stat
+         if (nonblock)
+                 return -EBUSY;
+ 	add_wait_queue(&s->dma_dac.wait, &wait);
+-        while ((count = in64(SS_CSR(R_SER_DMA_DSCR_COUNT_TX))) ||
++        while ((count = __raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_TX))) ||
+                (s->dma_dac.count > 0)) {
+                 if (!signal_pending(current)) {
+                         set_current_state(TASK_INTERRUPTIBLE);
+@@ -1624,7 +1627,7 @@ static int drain_dac(struct cs4297a_stat
+         }
+         spin_lock_irqsave(&s->lock, flags);
+         /* Reset the bookkeeping */
+-        hwptr = (int)(((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
++        hwptr = (int)(((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
+                        s->dma_dac.descrtab_phys) / sizeof(serdma_descr_t));
+         s->dma_dac.hwptr = s->dma_dac.swptr = hwptr;
+         spin_unlock_irqrestore(&s->lock, flags);
+@@ -1787,7 +1790,6 @@ static ssize_t cs4297a_write(struct file
+                 u32 *s_tmpl;
+                 u32 *t_tmpl;
+                 u32 left, right;
+-                /* XXXKW check system endian here ... */
+                 int swap = (s->prop_dac.fmt == AFMT_S16_LE) || (s->prop_dac.fmt == AFMT_U16_LE);
+                 
+                 /* XXXXXX this is broken for BLOAT_FACTOR */
+@@ -1798,7 +1800,7 @@ static ssize_t cs4297a_write(struct file
+ 		}
+ 		if (d->underrun) {
+ 			d->underrun = 0;
+-                        hwptr = (unsigned) (((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
++                        hwptr = (unsigned) (((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
+                                              d->descrtab_phys) / sizeof(serdma_descr_t));
+ 			d->swptr = d->hwptr = hwptr;
+ 		}
+@@ -1828,21 +1830,21 @@ static ssize_t cs4297a_write(struct file
+ 
+                 /* XXXKW assuming 16-bit stereo! */
+                 do {
+-                        t_tmpl[0] = 0x98000000;
+-                        left = s_tmpl[0] >> 16;
+-                        if (left & 0x8000)
+-                                left |= 0xf0000;
+-                        right = s_tmpl[0] & 0xffff;
+-                        if (right & 0x8000)
+-                                right |= 0xf0000;
+-                        if (swap) {
+-                          t_tmpl[1] = left & 0xff;
+-                          t_tmpl[2] = ((left & 0xff00) << 16) | ((right & 0xff) << 12) |
+-                              ((right & 0xff00) >> 4);
+-                        } else {
+-                          t_tmpl[1] = left >> 8;
+-                          t_tmpl[2] = ((left & 0xff) << 24) | (right << 4);
+-                        }
++			u32 tmp;
++
++			t_tmpl[0] = cpu_to_be32(0x98000000);
++
++			tmp = be32_to_cpu(s_tmpl[0]);
++			left = tmp & 0xffff;
++			right = tmp >> 16;
++			if (swap) {
++				left = swab16(left);
++				right = swab16(right);
++			}
++			t_tmpl[1] = cpu_to_be32(left >> 8);
++			t_tmpl[2] = cpu_to_be32(((left & 0xff) << 24) |
++						(right << 4));
++
+                         s_tmpl++;
+                         t_tmpl += 8;
+                         copy_cnt -= 4;
+@@ -1850,7 +1852,8 @@ static ssize_t cs4297a_write(struct file
+ 
+                 /* Mux in any pending read/write accesses */
+                 if (s->reg_request) {
+-                        *(u64 *)(d->dma_buf + (swptr * 4)) |= s->reg_request;
++			*(u64 *)(d->dma_buf + (swptr * 4)) |=
++				cpu_to_be64(s->reg_request);
+                         s->reg_request = 0;
+                         wake_up(&s->dma_dac.reg_wait);
+                 }
+@@ -1860,7 +1863,7 @@ static ssize_t cs4297a_write(struct file
+                                  "cs4297a: copy in %d to swptr %x\n", cnt, swptr));
+ 
+ 		swptr = (swptr + (cnt/FRAME_SAMPLE_BYTES)) % d->ringsz;
+-                out64(cnt/FRAME_SAMPLE_BYTES, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
++                __raw_writeq(cnt/FRAME_SAMPLE_BYTES, SS_CSR(R_SER_DMA_DSCR_COUNT_TX));
+ 		spin_lock_irqsave(&s->lock, flags);
+ 		d->swptr = swptr;
+ 		d->count += cnt;
+@@ -1993,20 +1996,20 @@ static int cs4297a_ioctl(struct inode *i
+ 			 "cs4297a: cs4297a_ioctl(): DSP_RESET\n"));
+ 		if (file->f_mode & FMODE_WRITE) {
+ 			stop_dac(s);
+-			synchronize_irq();
++			synchronize_irq(s->irq);
+                         s->dma_dac.count = s->dma_dac.total_bytes =
+                                 s->dma_dac.blocks = s->dma_dac.wakeup = 0;
+ 			s->dma_dac.swptr = s->dma_dac.hwptr =
+-                                (int)(((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
++                                (int)(((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_TX)) & M_DMA_CURDSCR_ADDR) -
+                                        s->dma_dac.descrtab_phys) / sizeof(serdma_descr_t));
+ 		}
+ 		if (file->f_mode & FMODE_READ) {
+ 			stop_adc(s);
+-			synchronize_irq();
++			synchronize_irq(s->irq);
+                         s->dma_adc.count = s->dma_adc.total_bytes =
+                                 s->dma_adc.blocks = s->dma_dac.wakeup = 0;
+ 			s->dma_adc.swptr = s->dma_adc.hwptr =
+-                                (int)(((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
++                                (int)(((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
+                                        s->dma_adc.descrtab_phys) / sizeof(serdma_descr_t));
+ 		}
+ 		return 0;
+@@ -2378,7 +2381,7 @@ static int cs4297a_open(struct inode *in
+ 		"cs4297a: cs4297a_open(): inode=0x%.8x file=0x%.8x f_mode=0x%x\n",
+ 			(unsigned) inode, (unsigned) file, file->f_mode));
+ 	CS_DBGOUT(CS_FUNCTION | CS_OPEN, 2, printk(KERN_INFO
+-                "cs4297a: status = %08x\n", (int)in64(SS_CSR(R_SER_STATUS_DEBUG))));
++                "cs4297a: status = %08x\n", (int)__raw_readq(SS_CSR(R_SER_STATUS_DEBUG))));
+ 
+ 	list_for_each(entry, &cs4297a_devs)
+ 	{
+@@ -2404,9 +2407,9 @@ static int cs4297a_open(struct inode *in
+ 		return -ENODEV;
+ 	}
+ 	if (file->f_mode & FMODE_WRITE) {
+-                if (in64(SS_CSR(R_SER_DMA_DSCR_COUNT_TX)) != 0) {
++                if (__raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_TX)) != 0) {
+                         printk(KERN_ERR "cs4297a: TX pipe needs to drain\n");
+-                        while (in64(SS_CSR(R_SER_DMA_DSCR_COUNT_TX)))
++                        while (__raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_TX)))
+                                 ;
+                 }
+           
+@@ -2501,12 +2504,12 @@ static /*const */ struct file_operations
+ 	.release	= cs4297a_release,
+ };
+ 
+-static irqreturn_t cs4297a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++static void cs4297a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	struct cs4297a_state *s = (struct cs4297a_state *) dev_id;
+         u32 status;
+ 
+-        status = in64(SS_CSR(R_SER_STATUS_DEBUG));
++        status = __raw_readq(SS_CSR(R_SER_STATUS_DEBUG));
+ 
+         CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
+                  "cs4297a: cs4297a_interrupt() HISR=0x%.8x\n", status));
+@@ -2514,16 +2517,16 @@ static irqreturn_t cs4297a_interrupt(int
+ #if 0
+         /* XXXKW what check *should* be done here? */
+         if (!(status & (M_SYNCSER_RX_EOP_COUNT | M_SYNCSER_RX_OVERRUN | M_SYNCSER_RX_SYNC_ERR))) {
+-                status = in64(SS_CSR(R_SER_STATUS));
++                status = __raw_readq(SS_CSR(R_SER_STATUS));
+                 printk(KERN_ERR "cs4297a: unexpected interrupt (status %08x)\n", status);
+-                return IRQ_HANDLED;
++                return;
+         }
+ #endif
+ 
+         if (status & M_SYNCSER_RX_SYNC_ERR) {
+-                status = in64(SS_CSR(R_SER_STATUS));
++                status = __raw_readq(SS_CSR(R_SER_STATUS));
+                 printk(KERN_ERR "cs4297a: rx sync error (status %08x)\n", status);
+-                return IRQ_HANDLED;
++                return;
+         }
+ 
+         if (status & M_SYNCSER_RX_OVERRUN) {
+@@ -2533,9 +2536,9 @@ static irqreturn_t cs4297a_interrupt(int
+ 
+                 /* Fix things up: get the receive descriptor pool
+                    clean and give them back to the hardware */
+-                while (in64(SS_CSR(R_SER_DMA_DSCR_COUNT_RX)))
++                while (__raw_readq(SS_CSR(R_SER_DMA_DSCR_COUNT_RX)))
+                         ;
+-                newptr = (unsigned) (((in64(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
++                newptr = (unsigned) (((__raw_readq(SS_CSR(R_SER_DMA_CUR_DSCR_ADDR_RX)) & M_DMA_CURDSCR_ADDR) -
+                                      s->dma_adc.descrtab_phys) / sizeof(serdma_descr_t));
+                 for (i=0; i<DMA_DESCR; i++) {
+                         s->dma_adc.descrtab[i].descr_a &= ~M_DMA_SERRX_SOP;
+@@ -2543,7 +2546,7 @@ static irqreturn_t cs4297a_interrupt(int
+                 s->dma_adc.swptr = s->dma_adc.hwptr = newptr;
+                 s->dma_adc.count = 0;
+                 s->dma_adc.sb_swptr = s->dma_adc.sb_hwptr = s->dma_adc.sample_buf;
+-                out64(DMA_DESCR, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
++                __raw_writeq(DMA_DESCR, SS_CSR(R_SER_DMA_DSCR_COUNT_RX));
+         }
+ 
+ 	spin_lock(&s->lock);
+@@ -2552,9 +2555,9 @@ static irqreturn_t cs4297a_interrupt(int
+ 
+ 	CS_DBGOUT(CS_INTERRUPT, 6, printk(KERN_INFO
+ 		  "cs4297a: cs4297a_interrupt()-\n"));
+-	return IRQ_HANDLED;
+ }
+ 
++#if 0
+ static struct initvol {
+ 	int mixch;
+ 	int vol;
+@@ -2570,26 +2573,31 @@ static struct initvol {
+ 	{SOUND_MIXER_WRITE_SPEAKER, 0x4040},
+ 	{SOUND_MIXER_WRITE_MIC, 0x0000}
+ };
++#endif
+ 
+ static int __init cs4297a_init(void)
+ {
+ 	struct cs4297a_state *s;
+-        u64 cfg;
+-        u32 pwr, id;
++	u32 pwr, id;
+ 	mm_segment_t fs;
+-        int rval, mdio_val;
++	int rval;
++#ifndef CONFIG_BCM_CS4297A_CSWARM
++	u64 cfg;
++	int mdio_val;
++#endif
+ 
+ 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2, printk(KERN_INFO 
+ 		"cs4297a: cs4297a_init_module()+ \n"));
+ 
+-        mdio_val = in64(KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO)) &
++#ifndef CONFIG_BCM_CS4297A_CSWARM
++        mdio_val = __raw_readq(KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO)) &
+                 (M_MAC_MDIO_DIR|M_MAC_MDIO_OUT);
+ 
+         /* Check syscfg for synchronous serial on port 1 */
+-        cfg = in64(KSEG1 + A_SCD_SYSTEM_CFG);
++        cfg = __raw_readq(KSEG1 + A_SCD_SYSTEM_CFG);
+         if (!(cfg & M_SYS_SER1_ENABLE)) {
+-                out64(cfg | M_SYS_SER1_ENABLE, KSEG1+A_SCD_SYSTEM_CFG);
+-                cfg = in64(KSEG1 + A_SCD_SYSTEM_CFG);
++                __raw_writeq(cfg | M_SYS_SER1_ENABLE, KSEG1+A_SCD_SYSTEM_CFG);
++                cfg = __raw_readq(KSEG1 + A_SCD_SYSTEM_CFG);
+                 if (!(cfg & M_SYS_SER1_ENABLE)) {
+                   printk(KERN_INFO "cs4297a: serial port 1 not configured for synchronous operation\n");
+                   return -1;
+@@ -2599,14 +2607,15 @@ static int __init cs4297a_init(void)
+                 
+                 /* Force the codec (on SWARM) to reset by clearing
+                    GENO, preserving MDIO (no effect on CSWARM) */
+-                out64(mdio_val, KSEG1+A_MAC_REGISTER(2, R_MAC_MDIO));
++                __raw_writeq(mdio_val, KSEG1+A_MAC_REGISTER(2, R_MAC_MDIO));
+                 udelay(10);
+         }
+ 
+         /* Now set GENO */
+-        out64(mdio_val | M_MAC_GENC, KSEG1+A_MAC_REGISTER(2, R_MAC_MDIO));
++        __raw_writeq(mdio_val | M_MAC_GENC, KSEG1+A_MAC_REGISTER(2, R_MAC_MDIO));
+         /* Give the codec some time to finish resetting (start the bit clock) */
+         udelay(100);
++#endif
+ 
+ 	if (!(s = kmalloc(sizeof(struct cs4297a_state), GFP_KERNEL))) {
+ 		CS_DBGOUT(CS_ERROR, 1, printk(KERN_ERR
+@@ -2659,6 +2668,8 @@ static int __init cs4297a_init(void)
+         } while (!rval && (pwr != 0xf));
+ 
+         if (!rval) {
++		char *sb1250_duart_present;
++
+                 fs = get_fs();
+                 set_fs(KERNEL_DS);
+ #if 0
+@@ -2679,7 +2690,11 @@ static int __init cs4297a_init(void)
+                 list_add(&s->list, &cs4297a_devs);
+ 
+                 cs4297a_read_ac97(s, AC97_VENDOR_ID1, &id);
+-                
++
++		sb1250_duart_present = symbol_get(sb1250_duart_present);
++		if (sb1250_duart_present)
++			sb1250_duart_present[1] = 0;
++
+                 printk(KERN_INFO "cs4297a: initialized (vendor id = %x)\n", id);
+ 
+                 CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
+@@ -2718,9 +2733,7 @@ static void __exit cs4297a_cleanup(void)
+ 
+ // --------------------------------------------------------------------- 
+ 
+-EXPORT_NO_SYMBOLS;
+-
+-MODULE_AUTHOR("Kip Walker, kwalker at broadcom.com");
++MODULE_AUTHOR("Kip Walker, Broadcom Corp.");
+ MODULE_DESCRIPTION("Cirrus Logic CS4297a Driver for Broadcom SWARM board");
+ 
+ // --------------------------------------------------------------------- 


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/00_linux-mips.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/00list
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/00list	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/00list	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,8 @@
+00_linux-mips.dpatch
+01_more-linux-mips.dpatch
+10_arch-makefile.dpatch
+11_byteorder-proc.dpatch
+20_addrspace-64bit.dpatch
+21_r4k-cache.dpatch
+30_ip22-eisa-update.dpatch
+40_ip27-horribles.dpatch

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/01_more-linux-mips.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/01_more-linux-mips.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/01_more-linux-mips.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,809 @@
+#! /bin/sh -e
+## 01_more-linux-mips.dpatch by Thiemo Seufer <ths at debian.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Diff between linux-mips.org, CVS HEAD, taken at 2005-01-11,
+## DP: and linux-mips.org, CVS tag linux_2_6_10, taken at 2005-01-13.
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p0 ${patch_opts} < $0;;
+    -unpatch) patch -R -p0 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+Index: arch/mips/Kconfig
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/Kconfig,v
+retrieving revision 1.126
+retrieving revision 1.127
+diff -u -p -r1.126 -r1.127
+--- arch/mips/Kconfig	27 Dec 2004 18:23:53 -0000	1.126
++++ arch/mips/Kconfig	12 Jan 2005 00:10:42 -0000	1.127
+@@ -541,6 +541,8 @@ config SGI_IP32
+ 	select ARC
+ 	select ARC32
+ 	select BOOT_ELF32
++	select OWN_DMA
++	select DMA_IP32
+ 	select DMA_NONCOHERENT
+ 	select HW_HAS_PCI
+ 	select R5000_CPU_SCACHE
+@@ -926,6 +928,12 @@ config	DMA_COHERENT
+ config	DMA_IP27
+ 	bool
+ 
++config	DMA_IP32
++	bool
++
++config	OWN_DMA
++	bool
++
+ config	DMA_NONCOHERENT
+ 	bool
+ 
+Index: arch/mips/mm/Makefile
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/mm/Makefile,v
+retrieving revision 1.74
+retrieving revision 1.75
+diff -u -p -r1.74 -r1.75
+--- arch/mips/mm/Makefile	7 Jan 2005 18:58:34 -0000	1.74
++++ arch/mips/mm/Makefile	12 Jan 2005 00:10:42 -0000	1.75
+@@ -34,8 +34,11 @@ obj-$(CONFIG_RM7000_CPU_SCACHE)	+= sc-rm
+ #
+ # Choose one DMA coherency model
+ #
++ifndef CONFIG_OWN_DMA
+ obj-$(CONFIG_DMA_COHERENT)	+= dma-coherent.o
+ obj-$(CONFIG_DMA_NONCOHERENT)	+= dma-noncoherent.o
++endif
+ obj-$(CONFIG_DMA_IP27)		+= dma-ip27.o
++obj-$(CONFIG_DMA_IP32)		+= dma-ip32.o
+ 
+ EXTRA_AFLAGS := $(CFLAGS)
+Index: arch/mips/mm/dma-ip32.c
+===================================================================
+RCS file: arch/mips/mm/dma-ip32.c
+diff -N arch/mips/mm/dma-ip32.c
+--- /dev/null	1 Jan 1970 00:00:00 -0000
++++ arch/mips/mm/dma-ip32.c	12 Jan 2005 01:53:37 -0000	1.2
+@@ -0,0 +1,383 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2000  Ani Joshi <ajoshi at unixbox.com>
++ * Copyright (C) 2000, 2001  Ralf Baechle <ralf at gnu.org>
++ * Copyright (C) 2005 Ilya A. Volynets-Evenbakh <ilya at total-knowledge.com>
++ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
++ * IP32 changes by Ilya.
++ */
++#include <linux/config.h>
++#include <linux/types.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/dma-mapping.h>
++
++#include <asm/cache.h>
++#include <asm/io.h>
++#include <asm/ip32/crime.h>
++
++/*
++ * Warning on the terminology - Linux calls an uncached area coherent;
++ * MIPS terminology calls memory areas with hardware maintained coherency
++ * coherent.
++ */
++
++/*
++ * Few notes.
++ * 1. CPU sees memory as two chunks: 0-256M at 0x0, and the rest @0x40000000+256M
++ * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x40000000 for native-endian)
++ * 3. All other devices see memory as one big chunk at 0x40000000
++ * 4. Non-PCI devices will pass NULL as struct device*
++ * Thus we translate differently, depending on device.
++ */
++
++#define RAM_OFFSET_MASK	0x3fffffff
++
++void *dma_alloc_noncoherent(struct device *dev, size_t size,
++	dma_addr_t * dma_handle, int gfp)
++{
++	void *ret;
++	/* ignore region specifiers */
++	gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
++
++	if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
++		gfp |= GFP_DMA;
++	ret = (void *) __get_free_pages(gfp, get_order(size));
++
++	if (ret != NULL) {
++		unsigned long addr = virt_to_phys(ret)&RAM_OFFSET_MASK;
++		memset(ret, 0, size);
++		if(dev==NULL)
++		    addr+= CRIME_HI_MEM_BASE;
++		*dma_handle = addr;
++	}
++
++	return ret;
++}
++
++EXPORT_SYMBOL(dma_alloc_noncoherent);
++
++void *dma_alloc_coherent(struct device *dev, size_t size,
++	dma_addr_t * dma_handle, int gfp)
++{
++	void *ret;
++
++	ret = dma_alloc_noncoherent(dev, size, dma_handle, gfp);
++	if (ret) {
++		dma_cache_wback_inv((unsigned long) ret, size);
++		ret = UNCAC_ADDR(ret);
++	}
++
++	return ret;
++}
++
++EXPORT_SYMBOL(dma_alloc_coherent);
++
++void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
++	dma_addr_t dma_handle)
++{
++	free_pages((unsigned long) vaddr, get_order(size));
++}
++
++EXPORT_SYMBOL(dma_free_noncoherent);
++
++void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
++	dma_addr_t dma_handle)
++{
++	unsigned long addr = (unsigned long) vaddr;
++
++	addr = CAC_ADDR(addr);
++	free_pages(addr, get_order(size));
++}
++
++EXPORT_SYMBOL(dma_free_coherent);
++
++static inline void __dma_sync(unsigned long addr, size_t size,
++	enum dma_data_direction direction)
++{
++	switch (direction) {
++	case DMA_TO_DEVICE:
++		dma_cache_wback(addr, size);
++		break;
++
++	case DMA_FROM_DEVICE:
++		dma_cache_inv(addr, size);
++		break;
++
++	case DMA_BIDIRECTIONAL:
++		dma_cache_wback_inv(addr, size);
++		break;
++
++	default:
++		BUG();
++	}
++}
++
++dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
++	enum dma_data_direction direction)
++{
++	unsigned long addr = (unsigned long) ptr;
++
++	switch (direction) {
++	case DMA_TO_DEVICE:
++		dma_cache_wback(addr, size);
++		break;
++
++	case DMA_FROM_DEVICE:
++		dma_cache_inv(addr, size);
++		break;
++
++	case DMA_BIDIRECTIONAL:
++		dma_cache_wback_inv(addr, size);
++		break;
++
++	default:
++		BUG();
++	}
++
++	addr = virt_to_phys(ptr)&RAM_OFFSET_MASK;;
++	if(dev == NULL)
++	    addr+=CRIME_HI_MEM_BASE;
++	return (dma_addr_t)addr;
++}
++
++EXPORT_SYMBOL(dma_map_single);
++
++void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
++	enum dma_data_direction direction)
++{
++	switch (direction) {
++	case DMA_TO_DEVICE:
++		break;
++
++	case DMA_FROM_DEVICE:
++		break;
++
++	case DMA_BIDIRECTIONAL:
++		break;
++
++	default:
++		BUG();
++	}
++}
++
++EXPORT_SYMBOL(dma_unmap_single);
++
++int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
++	enum dma_data_direction direction)
++{
++	int i;
++
++	BUG_ON(direction == DMA_NONE);
++
++	for (i = 0; i < nents; i++, sg++) {
++		unsigned long addr;
++ 
++		addr = (unsigned long) page_address(sg->page)+sg->offset;
++		if (addr)
++			__dma_sync(addr, sg->length, direction);
++		addr = __pa(addr)&RAM_OFFSET_MASK;;
++		if(dev == NULL)
++			addr +=  CRIME_HI_MEM_BASE;
++		sg->dma_address = (dma_addr_t)addr;
++	}
++
++	return nents;
++}
++
++EXPORT_SYMBOL(dma_map_sg);
++
++dma_addr_t dma_map_page(struct device *dev, struct page *page,
++	unsigned long offset, size_t size, enum dma_data_direction direction)
++{
++	unsigned long addr;
++
++	BUG_ON(direction == DMA_NONE);
++
++	addr = (unsigned long) page_address(page) + offset;
++	dma_cache_wback_inv(addr, size);
++	addr = __pa(addr)&RAM_OFFSET_MASK;;
++	if(dev == NULL)
++		addr +=  CRIME_HI_MEM_BASE;
++
++	return (dma_addr_t)addr;
++}
++
++EXPORT_SYMBOL(dma_map_page);
++
++void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
++	enum dma_data_direction direction)
++{
++	BUG_ON(direction == DMA_NONE);
++
++	if (direction != DMA_TO_DEVICE) {
++		unsigned long addr;
++
++		dma_address&=RAM_OFFSET_MASK;
++		addr = dma_address + PAGE_OFFSET;
++		if(dma_address>=256*1024*1024)
++			addr+=CRIME_HI_MEM_BASE;
++		dma_cache_wback_inv(addr, size);
++	}
++}
++
++EXPORT_SYMBOL(dma_unmap_page);
++
++void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
++	enum dma_data_direction direction)
++{
++	unsigned long addr;
++	int i;
++
++	BUG_ON(direction == DMA_NONE);
++
++	if (direction == DMA_TO_DEVICE)
++		return;
++
++	for (i = 0; i < nhwentries; i++, sg++) {
++		addr = (unsigned long) page_address(sg->page);
++		if (!addr)
++			continue;
++		dma_cache_wback_inv(addr + sg->offset, sg->length);
++	}
++}
++
++EXPORT_SYMBOL(dma_unmap_sg);
++
++void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
++	size_t size, enum dma_data_direction direction)
++{
++	unsigned long addr;
++ 
++	BUG_ON(direction == DMA_NONE);
++ 
++	dma_handle&=RAM_OFFSET_MASK;
++	addr = dma_handle + PAGE_OFFSET;
++	if(dma_handle>=256*1024*1024)
++	    addr+=CRIME_HI_MEM_BASE;
++	__dma_sync(addr, size, direction);
++}
++
++EXPORT_SYMBOL(dma_sync_single_for_cpu);
++
++void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
++	size_t size, enum dma_data_direction direction)
++{
++	unsigned long addr;
++
++	BUG_ON(direction == DMA_NONE);
++
++	dma_handle&=RAM_OFFSET_MASK;
++	addr = dma_handle + PAGE_OFFSET;
++	if(dma_handle>=256*1024*1024)
++	    addr+=CRIME_HI_MEM_BASE;
++	__dma_sync(addr, size, direction);
++}
++
++EXPORT_SYMBOL(dma_sync_single_for_device);
++
++void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
++	unsigned long offset, size_t size, enum dma_data_direction direction)
++{
++	unsigned long addr;
++
++	BUG_ON(direction == DMA_NONE);
++
++	dma_handle&=RAM_OFFSET_MASK;
++	addr = dma_handle + offset + PAGE_OFFSET;
++	if(dma_handle>=256*1024*1024)
++	    addr+=CRIME_HI_MEM_BASE;
++	__dma_sync(addr, size, direction);
++}
++
++EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
++
++void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
++	unsigned long offset, size_t size, enum dma_data_direction direction)
++{
++	unsigned long addr;
++
++	BUG_ON(direction == DMA_NONE);
++
++	dma_handle&=RAM_OFFSET_MASK;
++	addr = dma_handle + offset + PAGE_OFFSET;
++	if(dma_handle>=256*1024*1024)
++	    addr+=CRIME_HI_MEM_BASE;
++	__dma_sync(addr, size, direction);
++}
++
++EXPORT_SYMBOL(dma_sync_single_range_for_device);
++
++void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
++	enum dma_data_direction direction)
++{
++	int i;
++ 
++	BUG_ON(direction == DMA_NONE);
++ 
++	/* Make sure that gcc doesn't leave the empty loop body.  */
++	for (i = 0; i < nelems; i++, sg++)
++		__dma_sync((unsigned long)page_address(sg->page),
++		           sg->length, direction);
++}
++
++EXPORT_SYMBOL(dma_sync_sg_for_cpu);
++
++void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
++	enum dma_data_direction direction)
++{
++	int i;
++
++	BUG_ON(direction == DMA_NONE);
++
++	/* Make sure that gcc doesn't leave the empty loop body.  */
++	for (i = 0; i < nelems; i++, sg++)
++		__dma_sync((unsigned long)page_address(sg->page),
++		           sg->length, direction);
++}
++
++EXPORT_SYMBOL(dma_sync_sg_for_device);
++
++int dma_mapping_error(dma_addr_t dma_addr)
++{
++	return 0;
++}
++
++EXPORT_SYMBOL(dma_mapping_error);
++
++int dma_supported(struct device *dev, u64 mask)
++{
++	/*
++	 * we fall back to GFP_DMA when the mask isn't all 1s,
++	 * so we can't guarantee allocations that must be
++	 * within a tighter range than GFP_DMA..
++	 */
++	if (mask < 0x00ffffff)
++		return 0;
++
++	return 1;
++}
++
++EXPORT_SYMBOL(dma_supported);
++
++int dma_is_consistent(dma_addr_t dma_addr)
++{
++	return 1;
++}
++
++EXPORT_SYMBOL(dma_is_consistent);
++
++void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction)
++{
++	if (direction == DMA_NONE)
++		return;
++
++	dma_cache_wback_inv((unsigned long)vaddr, size);
++}
++
++EXPORT_SYMBOL(dma_cache_sync);
++
+Index: arch/mips/mm/pg-r4k.c
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/mm/pg-r4k.c,v
+retrieving revision 1.13
+retrieving revision 1.15
+diff -u -p -r1.13 -r1.15
+--- arch/mips/mm/pg-r4k.c	16 Nov 2004 16:19:45 -0000	1.13
++++ arch/mips/mm/pg-r4k.c	12 Jan 2005 17:03:10 -0000	1.15
+@@ -58,12 +58,6 @@ void copy_page(void *to, void *from) __a
+ EXPORT_SYMBOL(copy_page);
+ 
+ /*
+- * An address fits into a single register so it's safe to use 64-bit registers
+- * if we have 64-bit adresses.
+- */
+-#define cpu_has_64bit_registers	cpu_has_64bit_addresses
+-
+-/*
+  * This is suboptimal for 32-bit kernels; we assume that R10000 is only used
+  * with 64-bit kernels.  The prefetch offsets have been experimentally tuned
+  * an Origin 200.
+@@ -145,7 +139,7 @@ static inline void __build_load_reg(int 
+ 	union mips_instruction mi;
+ 	unsigned int width;
+ 
+-	if (cpu_has_64bit_registers) {
++	if (cpu_has_64bit_gp_regs) {
+ 		mi.i_format.opcode     = ld_op;
+ 		width = 8;
+ 	} else {
+@@ -266,7 +260,7 @@ static inline void build_addiu_a2_a0(uns
+ 
+ 	BUG_ON(offset > 0x7fff);
+ 
+-	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
++	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
+ 	mi.i_format.rs         = 4;		/* $a0 */
+ 	mi.i_format.rt         = 6;		/* $a2 */
+ 	mi.i_format.simmediate = offset;
+@@ -280,7 +274,7 @@ static inline void build_addiu_a1(unsign
+ 
+ 	BUG_ON(offset > 0x7fff);
+ 
+-	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
++	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
+ 	mi.i_format.rs         = 5;		/* $a1 */
+ 	mi.i_format.rt         = 5;		/* $a1 */
+ 	mi.i_format.simmediate = offset;
+@@ -296,7 +290,7 @@ static inline void build_addiu_a0(unsign
+ 
+ 	BUG_ON(offset > 0x7fff);
+ 
+-	mi.i_format.opcode     = cpu_has_64bit_addresses ? daddiu_op : addiu_op;
++	mi.i_format.opcode     = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op;
+ 	mi.i_format.rs         = 4;		/* $a0 */
+ 	mi.i_format.rt         = 4;		/* $a0 */
+ 	mi.i_format.simmediate = offset;
+Index: arch/mips/mm/tlbex.c
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/mm/tlbex.c,v
+retrieving revision 1.14
+retrieving revision 1.16
+diff -u -p -r1.14 -r1.16
+--- arch/mips/mm/tlbex.c	8 Jan 2005 15:03:53 -0000	1.14
++++ arch/mips/mm/tlbex.c	12 Jan 2005 16:38:50 -0000	1.16
+@@ -1099,7 +1099,7 @@ static __init void build_update_entries(
+ 	 * Kernel is a special case. Only a few CPUs use it.
+ 	 */
+ #ifdef CONFIG_64BIT_PHYS_ADDR
+-	if (cpu_has_64bit_gp_regs) {
++	if (cpu_has_64bits) {
+ 		i_ld(p, tmp, 0, ptep); /* get even pte */
+ 		i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
+ 		i_dsrl(p, tmp, tmp, 6); /* convert to entrylo0 */
+@@ -1282,14 +1282,14 @@ iPTE_LW(u32 **p, struct label **l, unsig
+ {
+ #ifdef CONFIG_SMP
+ # ifdef CONFIG_64BIT_PHYS_ADDR
+-	if (cpu_has_64bit_gp_regs)
++	if (cpu_has_64bits)
+ 		i_lld(p, pte, offset, ptr);
+ 	else
+ # endif
+ 		i_LL(p, pte, offset, ptr);
+ #else
+ # ifdef CONFIG_64BIT_PHYS_ADDR
+-	if (cpu_has_64bit_gp_regs)
++	if (cpu_has_64bits)
+ 		i_ld(p, pte, offset, ptr);
+ 	else
+ # endif
+@@ -1303,7 +1303,7 @@ iPTE_SW(u32 **p, struct reloc **r, unsig
+ {
+ #ifdef CONFIG_SMP
+ # ifdef CONFIG_64BIT_PHYS_ADDR
+-	if (cpu_has_64bit_gp_regs)
++	if (cpu_has_64bits)
+ 		i_scd(p, pte, offset, ptr);
+ 	else
+ # endif
+@@ -1315,7 +1315,7 @@ iPTE_SW(u32 **p, struct reloc **r, unsig
+ 		il_beqz(p, r, pte, label_smp_pgtable_change);
+ 
+ # ifdef CONFIG_64BIT_PHYS_ADDR
+-	if (!cpu_has_64bit_gp_regs) {
++	if (!cpu_has_64bits) {
+ 		/* no i_nop needed */
+ 		i_ll(p, pte, sizeof(pte_t) / 2, ptr);
+ 		i_ori(p, pte, pte, _PAGE_VALID);
+@@ -1324,14 +1324,14 @@ iPTE_SW(u32 **p, struct reloc **r, unsig
+ # endif
+ #else
+ # ifdef CONFIG_64BIT_PHYS_ADDR
+-	if (cpu_has_64bit_gp_regs)
++	if (cpu_has_64bits)
+ 		i_sd(p, pte, offset, ptr);
+ 	else
+ # endif
+ 		i_SW(p, pte, offset, ptr);
+ 
+ # ifdef CONFIG_64BIT_PHYS_ADDR
+-	if (!cpu_has_64bit_gp_regs) {
++	if (!cpu_has_64bits) {
+ 		i_lw(p, pte, sizeof(pte_t) / 2, ptr);
+ 		i_ori(p, pte, pte, _PAGE_VALID);
+ 		i_sw(p, pte, sizeof(pte_t) / 2, ptr);
+Index: arch/mips/sgi-ip32/Makefile
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/sgi-ip32/Makefile,v
+retrieving revision 1.9
+retrieving revision 1.10
+diff -u -p -r1.9 -r1.10
+--- arch/mips/sgi-ip32/Makefile	26 Feb 2004 09:09:09 -0000	1.9
++++ arch/mips/sgi-ip32/Makefile	12 Jan 2005 00:10:42 -0000	1.10
+@@ -4,6 +4,6 @@
+ #
+ 
+ obj-y	+= ip32-berr.o ip32-irq.o ip32-irq-glue.o ip32-setup.o ip32-reset.o \
+-	   crime.o
++	   crime.o ip32-memory.o
+ 
+ EXTRA_AFLAGS := $(CFLAGS)
+Index: arch/mips/sgi-ip32/crime.c
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/sgi-ip32/crime.c,v
+retrieving revision 1.6
+retrieving revision 1.7
+diff -u -p -r1.6 -r1.7
+--- arch/mips/sgi-ip32/crime.c	31 Aug 2004 16:49:32 -0000	1.6
++++ arch/mips/sgi-ip32/crime.c	12 Jan 2005 00:10:42 -0000	1.7
+@@ -4,6 +4,7 @@
+  * for more details.
+  *
+  * Copyright (C) 2001, 2003 Keith M Wesolowski
++ * Copyright (C) 2005 Ilya A. Volynets <ilya at total-knowledge.com>
+  */
+ #include <linux/types.h>
+ #include <linux/init.h>
+@@ -24,7 +25,8 @@ void __init crime_init(void)
+ {
+ 	unsigned int id, rev;
+ 	const int field = 2 * sizeof(unsigned long);
+-	
++
++	set_io_port_base((unsigned long) ioremap(MACEPCI_LOW_IO, 0x2000000));	
+ 	crime = ioremap(CRIME_BASE, sizeof(struct sgi_crime));
+ 	mace = ioremap(MACE_BASE, sizeof(struct sgi_mace));
+ 
+Index: arch/mips/sgi-ip32/ip32-memory.c
+===================================================================
+RCS file: arch/mips/sgi-ip32/ip32-memory.c
+diff -N arch/mips/sgi-ip32/ip32-memory.c
+--- /dev/null	1 Jan 1970 00:00:00 -0000
++++ arch/mips/sgi-ip32/ip32-memory.c	12 Jan 2005 00:10:42 -0000	1.1
+@@ -0,0 +1,49 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2003 Keith M Wesolowski
++ * Copyright (C) 2005 Ilya A. Volynets (Total Knowledge)
++ */
++#include <linux/types.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/mm.h>
++
++#include <asm/ip32/crime.h>
++#include <asm/bootinfo.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/pgalloc.h>
++
++extern void crime_init(void);
++
++void __init prom_meminit (void)
++{
++	u64 base, size;
++	int bank;
++
++	crime_init();
++
++	for (bank=0; bank < CRIME_MAXBANKS; bank++) {
++		u64 bankctl = crime->bank_ctrl[bank];
++		base = (bankctl & CRIME_MEM_BANK_CONTROL_ADDR) << 25;
++		if (bank != 0 && base == 0)
++			continue;
++		size = (bankctl & CRIME_MEM_BANK_CONTROL_SDRAM_SIZE) ? 128 : 32;
++		size <<= 20;
++		if (base + size > (256 << 20))
++			base += CRIME_HI_MEM_BASE;
++
++		printk("CRIME MC: bank %u base 0x%016lx size %luMB\n",
++			bank, base, size);
++		add_memory_region (base, size, BOOT_MEM_RAM);
++	}
++}
++
++
++unsigned long __init prom_free_prom_memory (void)
++{
++	return 0;
++}
+Index: arch/mips/sgi-ip32/ip32-setup.c
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/sgi-ip32/ip32-setup.c,v
+retrieving revision 1.22
+retrieving revision 1.23
+diff -u -p -r1.22 -r1.23
+--- arch/mips/sgi-ip32/ip32-setup.c	31 Aug 2004 16:49:32 -0000	1.22
++++ arch/mips/sgi-ip32/ip32-setup.c	12 Jan 2005 00:10:42 -0000	1.23
+@@ -94,10 +94,6 @@ void __init ip32_timer_setup(struct irqa
+ 
+ static int __init ip32_setup(void)
+ {
+-	set_io_port_base((unsigned long) ioremap(MACEPCI_LOW_IO, 0x2000000));
+-
+-	crime_init();
+-
+ 	board_be_init = ip32_be_init;
+ 
+ 	rtc_get_time = mc146818_get_cmos_time;
+Index: include/asm-mips/ip32/crime.h
+===================================================================
+RCS file: /home/cvs/linux/include/asm-mips/ip32/crime.h,v
+retrieving revision 1.6
+retrieving revision 1.7
+diff -u -p -r1.6 -r1.7
+--- include/asm-mips/ip32/crime.h	4 Dec 2004 18:16:09 -0000	1.6
++++ include/asm-mips/ip32/crime.h	12 Jan 2005 00:10:42 -0000	1.7
+@@ -156,4 +156,6 @@ struct sgi_crime {
+ 
+ extern struct sgi_crime *crime;
+ 
++#define CRIME_HI_MEM_BASE	0x40000000	/* this is where whole 1G of RAM is mapped */
++
+ #endif /* __ASM_CRIME_H__ */
+Index: include/asm-mips/mach-ip32/cpu-feature-overrides.h
+===================================================================
+RCS file: include/asm-mips/mach-ip32/cpu-feature-overrides.h
+diff -N include/asm-mips/mach-ip32/cpu-feature-overrides.h
+--- /dev/null	1 Jan 1970 00:00:00 -0000
++++ include/asm-mips/mach-ip32/cpu-feature-overrides.h	12 Jan 2005 09:50:47 -0000	1.2
+@@ -0,0 +1,38 @@
++/*
++ * This file is subject to the terms and conditions of the GNU General Public
++ * License.  See the file "COPYING" in the main directory of this archive
++ * for more details.
++ *
++ * Copyright (C) 2005 Ilya A. Volynets-Evenbakh
++ */
++#ifndef __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H
++#define __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H
++
++/*
++ * R5000 has an interesting "restriction":  ll(d)/sc(d)
++ * instructions to XKPHYS region simply do uncached bus
++ * requests. This breaks all the atomic bitops functions.
++ * so, for 64bit IP32 kernel we just don't use ll/sc.
++ * This does not affect luserland.
++ */
++#if defined(CONFIG_CPU_R5000) && defined(CONFIG_MIPS64)
++#define cpu_has_llsc		0
++#else
++#define cpu_has_llsc		1
++#endif
++
++/* Settings which are common for all ip32 CPUs */
++#define cpu_has_tlb		1
++#define cpu_has_4kex		1
++#define cpu_has_fpu		1
++#define cpu_has_32fpr		1
++#define cpu_has_counter		1
++#define cpu_has_mips16		0
++#define cpu_has_vce		0
++#define cpu_has_cache_cdex_s	0
++#define cpu_has_mcheck		0
++#define cpu_has_ejtag		0
++#define cpu_has_vtag_icache	0
++#define cpu_has_ic_fills_f_dc	0
++
++#endif /* __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H */
+Index: include/asm-mips/mach-ip32/spaces.h
+===================================================================
+RCS file: /home/cvs/linux/include/asm-mips/mach-ip32/spaces.h,v
+retrieving revision 1.1
+retrieving revision 1.2
+diff -u -p -r1.1 -r1.2
+--- include/asm-mips/mach-ip32/spaces.h	15 Oct 2004 02:09:12 -0000	1.1
++++ include/asm-mips/mach-ip32/spaces.h	12 Jan 2005 00:10:42 -0000	1.2
+@@ -12,10 +12,6 @@
+ 
+ #include <linux/config.h>
+ 
+-/*
+- * This handles the memory map.
+- */
+-#define PAGE_OFFSET		0xffffffff80000000
+ 
+ /*
+  * Memory above this physical address will be considered highmem.
+@@ -26,11 +22,7 @@
+ #define HIGHMEM_START		(1UL << 59UL)
+ #endif
+ 
+-#ifdef CONFIG_DMA_NONCOHERENT
+ #define CAC_BASE		0x9800000000000000
+-#else
+-#define CAC_BASE		0xa800000000000000
+-#endif
+ #define IO_BASE			0x9000000000000000
+ #define UNCAC_BASE		0x9000000000000000
+ #define MAP_BASE		0xc000000000000000
+@@ -39,4 +31,9 @@
+ #define TO_CAC(x)		(CAC_BASE   | ((x) & TO_PHYS_MASK))
+ #define TO_UNCAC(x)		(UNCAC_BASE | ((x) & TO_PHYS_MASK))
+ 
++/*
++ * This handles the memory map.
++ */
++#define PAGE_OFFSET		CAC_BASE
++
+ #endif /* __ASM_MACH_IP32_SPACES_H */


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/01_more-linux-mips.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/10_arch-makefile.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/10_arch-makefile.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/10_arch-makefile.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,119 @@
+#! /bin/sh -e
+## 10_arch-makefile.dpatch by Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Fix Makefile for 64bit compiles with modern toolchains.
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p0 ${patch_opts} < $0;;
+    -unpatch) patch -R -p0 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+Index: arch/mips/Makefile
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/Makefile,v
+retrieving revision 1.186
+diff -u -p -r1.186 Makefile
+--- arch/mips/Makefile	18 Dec 2004 01:15:52 -0000	1.186
++++ arch/mips/Makefile	10 Jan 2005 22:10:32 -0000
+@@ -16,7 +16,7 @@ as-option = $(shell if $(CC) $(CFLAGS) $
+ 	     -xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \
+ 	     else echo "$(2)"; fi ;)
+ 
+-cflags-y :=
++cflags-y := -ffreestanding
+ 
+ #
+ # Select the object file format to substitute into the linker script.
+@@ -24,16 +24,26 @@ cflags-y :=
+ ifdef CONFIG_CPU_LITTLE_ENDIAN
+ 32bit-tool-prefix	= mipsel-linux-
+ 64bit-tool-prefix	= mips64el-linux-
++#ifdef CONFIG_MIPS64
++#32bit-bfd		= elf32-ntradlittlemips
++#32bit-emul		= elf32ltsmipn32
++#else
+ 32bit-bfd		= elf32-tradlittlemips
+-64bit-bfd		= elf64-tradlittlemips
+ 32bit-emul		= elf32ltsmip
++#endif
++64bit-bfd		= elf64-tradlittlemips
+ 64bit-emul		= elf64ltsmip
+ else
+ 32bit-tool-prefix	= mips-linux-
+ 64bit-tool-prefix	= mips64-linux-
++#ifdef CONFIG_MIPS64
++#32bit-bfd		= elf32-ntradbigmips
++#32bit-emul		= elf32btsmipn32
++#else
+ 32bit-bfd		= elf32-tradbigmips
+-64bit-bfd		= elf64-tradbigmips
+ 32bit-emul		= elf32btsmip
++#endif
++64bit-bfd		= elf64-tradbigmips
+ 64bit-emul		= elf64btsmip
+ endif
+ 
+@@ -58,7 +68,13 @@ ld-emul			= $(64bit-emul)
+ vmlinux-32		= vmlinux.32
+ vmlinux-64		= vmlinux
+ else
++ifdef CONFIG_MIPS64
++#gas-abi			= n32
++gas-abi			= o64
++endif
++ifdef CONFIG_MIPS32
+ gas-abi			= 32
++endif
+ ld-emul			= $(32bit-emul)
+ vmlinux-32		= vmlinux
+ vmlinux-64		= vmlinux.64
+@@ -79,7 +95,7 @@ endif
+ cflags-y			+= -I $(TOPDIR)/include/asm/gcc
+ cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe
+ cflags-y			+= $(call cc-option, -finline-limit=100000)
+-LDFLAGS_vmlinux			+= -G 0 -static -n
++LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib
+ MODFLAGS			+= -mlong-calls
+ 
+ cflags-$(CONFIG_SB1XXX_CORELIS)	+= -mno-sched-prolog -fno-omit-frame-pointer
+@@ -118,7 +134,7 @@ if $(CC) $$gcc_abi -S -o /dev/null -xc /
+ else \
+ 	gcc_abi=; gcc_isa=-$(5); \
+ fi; \
+-gas_abi=-Wa,-$(gcc-abi); gas_cpu=$$cpu; gas_isa=-Wa,$$isa; \
++gas_abi=-Wa,-mabi=$(gcc-abi); gas_cpu=$$cpu; gas_isa=-Wa,$$isa; \
+ while :; do \
+ 	for gas_opt in -Wa,-march= -Wa,-mcpu=; do \
+ 		$(CC) $$gas_abi $$gas_opt$$cpu $$gas_isa -Wa,-Z -c \
+@@ -129,7 +145,7 @@ while :; do \
+ 	break; \
+ done; \
+ if test "$(gcc-abi)" != "$(gas-abi)"; then \
+-	gas_abi="-Wa,-$(gas-abi) -Wa,-mgp$(gcc-abi)"; \
++	gas_abi="-Wa,-mabi=$(gas-abi) -Wa,-mgp$(gcc-abi)"; \
+ fi; \
+ if test "$$gcc_opt" = -march= && test -n "$$gcc_abi"; then \
+ 	$(CC) $$gcc_abi $$gcc_opt$$gcc_cpu -S -o /dev/null \
+@@ -581,7 +597,7 @@ endif
+ # will break.
+ #
+ core-$(CONFIG_SGI_IP32)		+= arch/mips/sgi-ip32/
+-cflags-$(CONFIG_SGI_IP32)	+= -Iinclude/asm-mips/mach-ip32
++cflags-$(CONFIG_SGI_IP32)	+= -Iinclude/asm-mips/mach-ip32 -Wa,-mfix7000
+ load-$(CONFIG_SGI_IP32)		+= 0xffffffff80004000
+ 
+ #


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/10_arch-makefile.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/11_byteorder-proc.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/11_byteorder-proc.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/11_byteorder-proc.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,43 @@
+#! /bin/sh -e
+## 11_byteorder-proc.dpatch by ???
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Add byteorder info to /proc/cpuinfo
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p0 ${patch_opts} < $0;;
+    -unpatch) patch -R -p0 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+Index: arch/mips/kernel/proc.c
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/kernel/proc.c,v
+retrieving revision 1.27.2.17
+diff -u -p -u -r1.27.2.17 proc.c
+--- arch/mips/kernel/proc.c	27 Apr 2003 23:34:46 -0000	1.27.2.17
++++ arch/mips/kernel/proc.c	21 Sep 2003 00:14:13 -0000
+@@ -100,6 +100,11 @@ static int show_cpuinfo(struct seq_file 
+ 	seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n",
+ 	              loops_per_jiffy / (500000/HZ),
+ 	              (loops_per_jiffy / (5000/HZ)) % 100);
++#ifdef __MIPSEB__
++	seq_printf(m, "byteorder\t\t: big endian\n");
++#else
++	seq_printf(m, "byteorder\t\t: little endian\n");
++#endif
+ 	seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no");
+ 	seq_printf(m, "microsecond timers\t: %s\n",
+ 	              cpu_has_counter ? "yes" : "no");


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/11_byteorder-proc.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/20_addrspace-64bit.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/20_addrspace-64bit.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/20_addrspace-64bit.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,103 @@
+#! /bin/sh -e
+## 20_addrspace-64bit.dpatch by Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: 64bit address space fixes
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p0 ${patch_opts} < $0;;
+    -unpatch) patch -R -p0 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+Index: arch/mips/mm/sc-rm7k.c
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/mm/sc-rm7k.c,v
+retrieving revision 1.7
+diff -u -p -r1.7 sc-rm7k.c
+--- arch/mips/mm/sc-rm7k.c	15 Dec 2004 20:39:23 -0000	1.7
++++ arch/mips/mm/sc-rm7k.c	10 Jan 2005 22:10:33 -0000
+@@ -127,13 +127,13 @@ static __init void __rm7k_sc_enable(void
+ 		      ".set mips0\n\t"
+ 		      ".set reorder"
+ 		      :
+-		      : "r" (KSEG0ADDR(i)), "i" (Index_Store_Tag_SD));
++		      : "r" (CKSEG0ADDR(i)), "i" (Index_Store_Tag_SD));
+ 	}
+ }
+ 
+ static __init void rm7k_sc_enable(void)
+ {
+-	void (*func)(void) = (void *) KSEG1ADDR(&__rm7k_sc_enable);
++	void (*func)(void) = (void *) CKSEG1ADDR(&__rm7k_sc_enable);
+ 
+ 	if (read_c0_config() & 0x08)			/* CONF_SE */
+ 		return;
+Index: drivers/i2c/busses/i2c-sibyte.c
+===================================================================
+RCS file: /home/cvs/linux/drivers/i2c/busses/i2c-sibyte.c,v
+retrieving revision 1.6
+diff -u -p -r1.6 i2c-sibyte.c
+--- drivers/i2c/busses/i2c-sibyte.c	18 Dec 2004 01:15:32 -0000	1.6
++++ drivers/i2c/busses/i2c-sibyte.c	10 Jan 2005 22:10:33 -0000
+@@ -24,8 +24,8 @@
+ #include <asm/sibyte/sb1250_smbus.h>
+ 
+ static struct i2c_algo_sibyte_data sibyte_board_data[2] = {
+-	{ NULL, 0, (void *) (KSEG1+A_SMB_BASE(0)) },
+-	{ NULL, 1, (void *) (KSEG1+A_SMB_BASE(1)) }
++	{ NULL, 0, (void *) (CKSEG1+A_SMB_BASE(0)) },
++	{ NULL, 1, (void *) (CKSEG1+A_SMB_BASE(1)) }
+ };
+ 
+ static struct i2c_adapter sibyte_board_adapter[2] = {
+Index: drivers/media/video/swarm_saa7114h.c
+===================================================================
+RCS file: /home/cvs/linux/drivers/media/video/swarm_saa7114h.c,v
+retrieving revision 1.4
+diff -u -p -r1.4 swarm_saa7114h.c
+--- drivers/media/video/swarm_saa7114h.c	26 Oct 2004 02:20:47 -0000	1.4
++++ drivers/media/video/swarm_saa7114h.c	10 Jan 2005 22:10:34 -0000
+@@ -51,7 +51,6 @@
+ #include <linux/sched.h>
+ #include <asm/segment.h>
+ #include <linux/types.h>
+-#include <linux/wrapper.h>
+ #include <linux/smp_lock.h>
+ #include <asm/hardirq.h>
+ 
+@@ -102,8 +101,8 @@
+ 
+ #define IF_NAME "saa7114h"
+ 
+-#define MAC2_CSR(r)	   (KSEG1 + A_MAC_REGISTER(2, r))
+-#define MAC2_DMARX0_CSR(r) (KSEG1 + A_MAC_DMA_REGISTER(2, DMA_RX, 0, r))
++#define MAC2_CSR(r)	   (CKSEG1 + A_MAC_REGISTER(2, r))
++#define MAC2_DMARX0_CSR(r) (CKSEG1 + A_MAC_DMA_REGISTER(2, DMA_RX, 0, r))
+ 
+ /* Options */
+ #define DMA_DEINTERLACE	 1
+@@ -1614,9 +1613,9 @@ static int saa7114h_attach(struct i2c_ad
+ 	decoder->vd = vd;
+ 
+ 	/* Turn on the ITRDY - preserve the GENO pin for syncser */
+-	val = __raw_readq(KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO));
++	val = __raw_readq(CKSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO));
+ 	__raw_writeq(M_MAC_MDIO_OUT | (val & M_MAC_GENC),
+-	      KSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO));
++	      CKSEG1 + A_MAC_REGISTER(2, R_MAC_MDIO));
+ 
+ 	if ((err = dma_setup(decoder))) {
+ 		i2c_detach_client(client);


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/20_addrspace-64bit.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/21_r4k-cache.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/21_r4k-cache.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/21_r4k-cache.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,59 @@
+#! /bin/sh -e
+## 21_r4k-cache.dpatch by Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Fix for SMP crashes with r4k caches.
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p0 ${patch_opts} < $0;;
+    -unpatch) patch -R -p0 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+Index: arch/mips/mm/c-r4k.c
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/mm/c-r4k.c,v
+retrieving revision 1.96
+diff -u -p -r1.96 c-r4k.c
+--- arch/mips/mm/c-r4k.c	7 Dec 2004 02:33:02 -0000	1.96
++++ arch/mips/mm/c-r4k.c	10 Jan 2005 22:10:33 -0000
+@@ -375,6 +375,13 @@ static inline void local_r4k_flush_cache
+ 	pmd_t *pmdp;
+ 	pte_t *ptep;
+ 
++	/*
++	 * If ownes no valid ASID yet, cannot possibly have gotten
++	 * this page into the cache.
++	 */
++	if (cpu_context(smp_processor_id(), mm) == 0)
++		return;
++
+ 	page &= PAGE_MASK;
+ 	pgdp = pgd_offset(mm, page);
+ 	pmdp = pmd_offset(pgdp, page);
+@@ -431,13 +438,6 @@ static void r4k_flush_cache_page(struct 
+ {
+ 	struct flush_cache_page_args args;
+ 
+-	/*
+-	 * If ownes no valid ASID yet, cannot possibly have gotten
+-	 * this page into the cache.
+-	 */
+-	if (cpu_context(smp_processor_id(), vma->vm_mm) == 0)
+-		return;
+-
+ 	args.vma = vma;
+ 	args.page = page;
+ 


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/21_r4k-cache.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/30_ip22-eisa-update.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/30_ip22-eisa-update.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/30_ip22-eisa-update.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,297 @@
+#! /bin/sh -e
+## 30_ip22-eisa-update.dpatch by Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Minimal update for ip22 EISA support. This should use the generic
+## DP: EISA bus support instead.
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p0 ${patch_opts} < $0;;
+    -unpatch) patch -R -p0 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+Index: arch/mips/sgi-ip22/ip22-eisa.c
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/sgi-ip22/ip22-eisa.c,v
+retrieving revision 1.7
+diff -u -p -r1.7 ip22-eisa.c
+--- arch/mips/sgi-ip22/ip22-eisa.c	30 Sep 2003 14:27:18 -0000	1.7
++++ arch/mips/sgi-ip22/ip22-eisa.c	27 Oct 2004 23:30:46 -0000
+@@ -29,6 +29,7 @@
+ #include <linux/sched.h>
+ #include <linux/interrupt.h>
+ #include <linux/delay.h>
++#include <asm/io.h>
+ #include <asm/irq.h>
+ #include <asm/mipsregs.h>
+ #include <asm/addrspace.h>
+@@ -37,42 +38,29 @@
+ #include <asm/sgi/mc.h>
+ #include <asm/sgi/ip22.h>
+ 
+-#define EISA_MAX_SLOTS		  4
++/* I2 has four EISA slots. */
++#define IP22_EISA_MAX_SLOTS	  4
+ #define EISA_MAX_IRQ             16
+ 
+-#define EISA_TO_PHYS(x)  (0x00080000 | (x))
+-#define EISA_TO_KSEG1(x) ((void *) KSEG1ADDR(EISA_TO_PHYS((x))))
++#define EIU_MODE_REG     0x0001ffc0
++#define EIU_STAT_REG     0x0001ffc4
++#define EIU_PREMPT_REG   0x0001ffc8
++#define EIU_QUIET_REG    0x0001ffcc
++#define EIU_INTRPT_ACK   0x00010004
++
++static char __init *decode_eisa_sig(unsigned long addr)
++{
++        static char sig_str[EISA_SIG_LEN];
++	u8 sig[4];
++        u16 rev;
++	int i;
+ 
+-#define EIU_MODE_REG     0x0009ffc0
+-#define EIU_STAT_REG     0x0009ffc4
+-#define EIU_PREMPT_REG   0x0009ffc8
+-#define EIU_QUIET_REG    0x0009ffcc
+-#define EIU_INTRPT_ACK   0x00090004
+-
+-#define EISA_DMA1_STATUS            8
+-#define EISA_INT1_CTRL           0x20
+-#define EISA_INT1_MASK           0x21
+-#define EISA_INT2_CTRL           0xA0
+-#define EISA_INT2_MASK           0xA1
+-#define EISA_DMA2_STATUS         0xD0
+-#define EISA_DMA2_WRITE_SINGLE   0xD4
+-#define EISA_EXT_NMI_RESET_CTRL 0x461
+-#define EISA_INT1_EDGE_LEVEL    0x4D0
+-#define EISA_INT2_EDGE_LEVEL    0x4D1
+-#define EISA_VENDOR_ID_OFFSET   0xC80
+-
+-#define EIU_WRITE_32(x,y) { *((u32 *) KSEG1ADDR(x)) = (u32) (y); mb(); }
+-#define EIU_READ_8(x) *((u8 *) KSEG1ADDR(x))
+-#define EISA_WRITE_8(x,y) { *((u8 *) EISA_TO_KSEG1(x)) = (u8) (y); mb(); }
+-#define EISA_READ_8(x) *((u8 *) EISA_TO_KSEG1(x))
++	for (i = 0; i < 4; i++) {
++		sig[i] = inb (addr + i);
+ 
+-static char *decode_eisa_sig(u8 * sig)
+-{
+-	static char sig_str[8];
+-	u16 rev;
+-
+-	if (sig[0] & 0x80)
+-		return NULL;
++		if (!i && (sig[0] & 0x80))
++			return NULL;
++	}
+ 
+ 	sig_str[0] = ((sig[0] >> 2) & 0x1f) + ('A' - 1);
+ 	sig_str[1] = (((sig[0] & 3) << 3) | (sig[1] >> 5)) + ('A' - 1);
+@@ -83,23 +71,26 @@ static char *decode_eisa_sig(u8 * sig)
+ 	return sig_str;
+ }
+ 
+-static void ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
++static irqreturn_t ip22_eisa_intr(int irq, void *dev_id, struct pt_regs *regs)
+ {
+ 	u8 eisa_irq;
+ 	u8 dma1, dma2;
+ 
+-	eisa_irq = EIU_READ_8(EIU_INTRPT_ACK);
+-	dma1 = EISA_READ_8(EISA_DMA1_STATUS);
+-	dma2 = EISA_READ_8(EISA_DMA2_STATUS);
+-
+-	if (eisa_irq >= EISA_MAX_IRQ) {
+-		/* Oops, Bad Stuff Happened... */
+-		printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq);
+-
+-		EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
+-		EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
+-	} else
++	eisa_irq = inb(EIU_INTRPT_ACK);
++	dma1 = inb(EISA_DMA1_STATUS);
++	dma2 = inb(EISA_DMA2_STATUS);
++
++	if (eisa_irq < EISA_MAX_IRQ) {
+ 		do_IRQ(eisa_irq, regs);
++		return IRQ_HANDLED;
++	}
++
++	/* Oops, Bad Stuff Happened... */
++	printk(KERN_ERR "eisa_irq %d out of bound\n", eisa_irq);
++
++	outb(0x20, EISA_INT2_CTRL);
++	outb(0x20, EISA_INT1_CTRL);
++	return IRQ_NONE;
+ }
+ 
+ static void enable_eisa1_irq(unsigned int irq)
+@@ -109,9 +100,9 @@ static void enable_eisa1_irq(unsigned in
+ 
+ 	local_irq_save(flags);
+ 
+-	mask = EISA_READ_8(EISA_INT1_MASK);
++	mask = inb(EISA_INT1_MASK);
+ 	mask &= ~((u8) (1 << irq));
+-	EISA_WRITE_8(EISA_INT1_MASK, mask);
++	outb(mask, EISA_INT1_MASK);
+ 
+ 	local_irq_restore(flags);
+ }
+@@ -122,9 +113,9 @@ static unsigned int startup_eisa1_irq(un
+ 
+ 	/* Only use edge interrupts for EISA */
+ 
+-	edge = EISA_READ_8(EISA_INT1_EDGE_LEVEL);
++	edge = inb(EISA_INT1_EDGE_LEVEL);
+ 	edge &= ~((u8) (1 << irq));
+-	EISA_WRITE_8(EISA_INT1_EDGE_LEVEL, edge);
++	outb(edge, EISA_INT1_EDGE_LEVEL);
+ 
+ 	enable_eisa1_irq(irq);
+ 	return 0;
+@@ -134,9 +125,9 @@ static void disable_eisa1_irq(unsigned i
+ {
+ 	u8 mask;
+ 
+-	mask = EISA_READ_8(EISA_INT1_MASK);
++	mask = inb(EISA_INT1_MASK);
+ 	mask |= ((u8) (1 << irq));
+-	EISA_WRITE_8(EISA_INT1_MASK, mask);
++	outb(mask, EISA_INT1_MASK);
+ }
+ 
+ #define shutdown_eisa1_irq	disable_eisa1_irq
+@@ -145,7 +136,7 @@ static void mask_and_ack_eisa1_irq(unsig
+ {
+ 	disable_eisa1_irq(irq);
+ 
+-	EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
++	outb(0x20, EISA_INT1_CTRL);
+ }
+ 
+ static void end_eisa1_irq(unsigned int irq)
+@@ -171,9 +162,9 @@ static void enable_eisa2_irq(unsigned in
+ 
+ 	local_irq_save(flags);
+ 
+-	mask = EISA_READ_8(EISA_INT2_MASK);
++	mask = inb(EISA_INT2_MASK);
+ 	mask &= ~((u8) (1 << (irq - 8)));
+-	EISA_WRITE_8(EISA_INT2_MASK, mask);
++	outb(mask, EISA_INT2_MASK);
+ 
+ 	local_irq_restore(flags);
+ }
+@@ -184,9 +175,9 @@ static unsigned int startup_eisa2_irq(un
+ 
+ 	/* Only use edge interrupts for EISA */
+ 
+-	edge = EISA_READ_8(EISA_INT2_EDGE_LEVEL);
++	edge = inb(EISA_INT2_EDGE_LEVEL);
+ 	edge &= ~((u8) (1 << (irq - 8)));
+-	EISA_WRITE_8(EISA_INT2_EDGE_LEVEL, edge);
++	outb(edge, EISA_INT2_EDGE_LEVEL);
+ 
+ 	enable_eisa2_irq(irq);
+ 	return 0;
+@@ -196,9 +187,9 @@ static void disable_eisa2_irq(unsigned i
+ {
+ 	u8 mask;
+ 
+-	mask = EISA_READ_8(EISA_INT2_MASK);
++	mask = inb(EISA_INT2_MASK);
+ 	mask |= ((u8) (1 << (irq - 8)));
+-	EISA_WRITE_8(EISA_INT2_MASK, mask);
++	outb(mask, EISA_INT2_MASK);
+ }
+ 
+ #define shutdown_eisa2_irq	disable_eisa2_irq
+@@ -207,8 +198,7 @@ static void mask_and_ack_eisa2_irq(unsig
+ {
+ 	disable_eisa2_irq(irq);
+ 
+-	EISA_WRITE_8(EISA_INT2_CTRL, 0x20);
+-	EISA_WRITE_8(EISA_INT1_CTRL, 0x20);
++	outb(0x20, EISA_INT2_CTRL);
+ }
+ 
+ static void end_eisa2_irq(unsigned int irq)
+@@ -241,7 +231,6 @@ int __init ip22_eisa_init(void)
+ {
+ 	int i, c;
+ 	char *str;
+-	u8 *slot_addr;
+ 	
+ 	if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
+ 		printk(KERN_INFO "EISA: bus not present.\n");
+@@ -249,11 +238,8 @@ int __init ip22_eisa_init(void)
+ 	}
+ 
+ 	printk(KERN_INFO "EISA: Probing bus...\n");
+-	for (c = 0, i = 1; i <= EISA_MAX_SLOTS; i++) {
+-		slot_addr =
+-		    (u8 *) EISA_TO_KSEG1((0x1000 * i) +
+-					 EISA_VENDOR_ID_OFFSET);
+-		if ((str = decode_eisa_sig(slot_addr))) {
++	for (c = 0, i = 1; i <= IP22_EISA_MAX_SLOTS; i++) {
++		if ((str = decode_eisa_sig(0x1000 * i + EISA_VENDOR_ID_OFFSET))) {
+ 			printk(KERN_INFO "EISA: slot %d : %s detected.\n",
+ 			       i, str);
+ 			c++;
+@@ -268,25 +254,25 @@ int __init ip22_eisa_init(void)
+ 	   Please wave your favorite dead chicken over the busses */
+ 
+ 	/* First say hello to the EIU */
+-	EIU_WRITE_32(EIU_PREMPT_REG, 0x0000FFFF);
+-	EIU_WRITE_32(EIU_QUIET_REG, 1);
+-	EIU_WRITE_32(EIU_MODE_REG, 0x40f3c07F);
++	outl(0x0000FFFF, EIU_PREMPT_REG);
++	outl(1, EIU_QUIET_REG);
++	outl(0x40f3c07F, EIU_MODE_REG);
+ 
+ 	/* Now be nice to the EISA chipset */
+-	EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 1);
+-	for (i = 0; i < 10000; i++);	/* Wait long enough for the dust to settle */
+-	EISA_WRITE_8(EISA_EXT_NMI_RESET_CTRL, 0);
+-	EISA_WRITE_8(EISA_INT1_CTRL, 0x11);
+-	EISA_WRITE_8(EISA_INT2_CTRL, 0x11);
+-	EISA_WRITE_8(EISA_INT1_MASK, 0);
+-	EISA_WRITE_8(EISA_INT2_MASK, 8);
+-	EISA_WRITE_8(EISA_INT1_MASK, 4);
+-	EISA_WRITE_8(EISA_INT2_MASK, 2);
+-	EISA_WRITE_8(EISA_INT1_MASK, 1);
+-	EISA_WRITE_8(EISA_INT2_MASK, 1);
+-	EISA_WRITE_8(EISA_INT1_MASK, 0xfb);
+-	EISA_WRITE_8(EISA_INT2_MASK, 0xff);
+-	EISA_WRITE_8(EISA_DMA2_WRITE_SINGLE, 0);
++	outb(1, EISA_EXT_NMI_RESET_CTRL);
++	udelay(50);	/* Wait long enough for the dust to settle */
++	outb(0, EISA_EXT_NMI_RESET_CTRL);
++	outb(0x11, EISA_INT1_CTRL);
++	outb(0x11, EISA_INT2_CTRL);
++	outb(0, EISA_INT1_MASK);
++	outb(8, EISA_INT2_MASK);
++	outb(4, EISA_INT1_MASK);
++	outb(2, EISA_INT2_MASK);
++	outb(1, EISA_INT1_MASK);
++	outb(1, EISA_INT2_MASK);
++	outb(0xfb, EISA_INT1_MASK);
++	outb(0xff, EISA_INT2_MASK);
++	outb(0, EISA_DMA2_WRITE_SINGLE);
+ 
+ 	for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) {
+ 		irq_desc[i].status = IRQ_DISABLED;


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/30_ip22-eisa-update.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/40_ip27-horribles.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/40_ip27-horribles.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/40_ip27-horribles.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,161 @@
+#! /bin/sh -e
+## 40_ip27-horribles.dpatch by Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Some horrible hacks to make ip27 appear to work.
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p0 ${patch_opts} < $0;;
+    -unpatch) patch -R -p0 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+Index: arch/mips/pci/pci.c
+===================================================================
+RCS file: /home/cvs/linux/arch/mips/pci/pci.c,v
+retrieving revision 1.30
+diff -u -p -r1.30 pci.c
+--- arch/mips/pci/pci.c	16 Dec 2004 12:55:01 -0000	1.30
++++ arch/mips/pci/pci.c	10 Jan 2005 22:10:33 -0000
+@@ -20,11 +20,11 @@
+  * Make this long-lived  so that we know when shutting down
+  * whether we probed only or not.
+  */
+-int pci_probe_only;
++int pci_probe_only = 1;
+ 
+ #define PCI_ASSIGN_ALL_BUSSES	1
+ 
+-unsigned int pci_probe = PCI_ASSIGN_ALL_BUSSES;
++unsigned int pci_probe = 0; // PCI_ASSIGN_ALL_BUSSES;
+ 
+ /*
+  * The PCI controller list.
+Index: drivers/md/md.c
+===================================================================
+RCS file: /home/cvs/linux/drivers/md/md.c,v
+retrieving revision 1.78
+diff -u -p -r1.78 md.c
+--- drivers/md/md.c	4 Dec 2004 18:16:04 -0000	1.78
++++ drivers/md/md.c	10 Jan 2005 22:10:33 -0000
+@@ -429,6 +429,7 @@ abort:
+ 	return ret;
+ }
+ 
++#if 0
+ static unsigned int calc_sb_csum(mdp_super_t * sb)
+ {
+ 	unsigned int disk_csum, csum;
+@@ -439,6 +440,23 @@ static unsigned int calc_sb_csum(mdp_sup
+ 	sb->sb_csum = disk_csum;
+ 	return csum;
+ }
++#else
++unsigned long calc_sb_csum(mdp_super_t *super)
++{
++        unsigned int  oldcsum = super->sb_csum;
++        unsigned long long newcsum = 0;
++        unsigned long csum;
++        int i;
++        unsigned int *superc = (int*) super;
++        super->sb_csum = 0;
++                                                                                
++        for(i=0; i<MD_SB_BYTES/4; i++)
++                newcsum+= superc[i];
++        csum = (newcsum& 0xffffffff) + (newcsum>>32);
++        super->sb_csum = oldcsum;
++        return csum;
++}
++#endif
+ 
+ 
+ /*
+Index: drivers/scsi/qlogicisp.c
+===================================================================
+RCS file: /home/cvs/linux/drivers/scsi/qlogicisp.c,v
+retrieving revision 1.40
+diff -u -p -r1.40 qlogicisp.c
+--- drivers/scsi/qlogicisp.c	25 Oct 2004 20:44:35 -0000	1.40
++++ drivers/scsi/qlogicisp.c	10 Jan 2005 22:10:34 -0000
+@@ -1044,28 +1044,31 @@ void isp1020_intr_handler(int irq, void 
+ 
+ 		DEBUG_INTR(isp1020_print_status_entry(sts));
+ 
+-		if (sts->hdr.entry_type == ENTRY_STATUS)
+-			Cmnd->result = isp1020_return_status(sts);
+-		else
+-			Cmnd->result = DID_ERROR << 16;
+-
+-		if (Cmnd->use_sg)
+-			pci_unmap_sg(hostdata->pci_dev,
+-				     (struct scatterlist *)Cmnd->buffer,
+-				     Cmnd->use_sg,
+-				     scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+-		else if (Cmnd->request_bufflen)
+-			pci_unmap_single(hostdata->pci_dev,
++		if (Cmnd) {
++			if (sts->hdr.entry_type == ENTRY_STATUS)
++				Cmnd->result = isp1020_return_status(sts);
++			else
++				Cmnd->result = DID_ERROR << 16;
++
++			if (Cmnd->use_sg)
++				pci_unmap_sg(hostdata->pci_dev,
++					     (struct scatterlist *)Cmnd->buffer,
++					     Cmnd->use_sg,
++					     scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
++			else if (Cmnd->request_bufflen)
++				pci_unmap_single(hostdata->pci_dev,
+ #ifdef CONFIG_QL_ISP_A64
+-					 (dma_addr_t)((long)Cmnd->SCp.ptr),
++						 (dma_addr_t)((long)Cmnd->SCp.ptr),
+ #else
+-					 (u32)((long)Cmnd->SCp.ptr),
++						 (u32)((long)Cmnd->SCp.ptr),
+ #endif
+-					 Cmnd->request_bufflen,
+-					 scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
++						 Cmnd->request_bufflen,
++						 scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
+ 
+ 		isp_outw(out_ptr, host, MBOX5);
+ 		(*Cmnd->scsi_done)(Cmnd);
++		} else
++			printk(KERN_CRIT "qlogic: Cmnd == NULL");
+ 	}
+ 	hostdata->res_out_ptr = out_ptr;
+ 
+@@ -1233,6 +1236,13 @@ int isp1020_reset(Scsi_Cmnd *Cmnd, unsig
+ 	return return_status;
+ }
+ 
++static int
++isp1020_eh_abort(struct scsi_cmnd * cmd)
++{
++	printk(KERN_WARNING "ISP1020 is toast\n");
++	return -ENODEV;
++}
++
+ 
+ int isp1020_biosparam(struct scsi_device *sdev, struct block_device *n,
+ 		sector_t capacity, int ip[])
+@@ -1984,6 +1994,7 @@ static Scsi_Host_Template driver_templat
+ 	.release		= isp1020_release,
+ 	.info			= isp1020_info,	
+ 	.queuecommand		= isp1020_queuecommand,
++	.eh_abort_handler	= isp1020_eh_abort,
+ 	.bios_param		= isp1020_biosparam,
+ 	.can_queue		= QLOGICISP_REQ_QUEUE_LEN,
+ 	.this_id		= -1,


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches/40_ip27-horribles.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/05_linux-mips-makefile.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/05_linux-mips-makefile.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/05_linux-mips-makefile.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,161 @@
+#! /bin/sh -e
+## 05_linux-mips-makefile.dpatch by Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Sanitize compiler/assembler flags
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p0 ${patch_opts} < $0;;
+    -unpatch) patch -R -p0 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+--- arch/mips/Makefile.old	2004-05-18 00:46:58.000000000 +0200
++++ arch/mips/Makefile	2004-05-18 17:49:53.000000000 +0200
+@@ -57,117 +57,54 @@ endif
+ endif
+ 
+ #
+-# Use: $(call set_gccflags,<cpu0>,<isa0>,<cpu1>,<isa1>,<isa2>)
+-#
+-# <cpu0>,<isa0> -- preferred CPU and ISA designations (may require
+-#                  recent tools)
+-# <cpu1>,<isa1> -- fallback CPU and ISA designations (have to work
+-#                  with up to the oldest supported tools)
+-# <isa2>        -- an ISA designation used as an ABI selector for
+-#                  gcc versions that do not support "-mabi=32"
+-#                  (depending on the CPU type, either "mips1" or
+-#                  "mips2")
+-#
+-set_gccflags = $(shell \
+-while :; do \
+-	cpu=$(1); isa=-$(2); \
+-	for gcc_opt in -march= -mcpu=; do \
+-		$(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \
+-			-xc /dev/null > /dev/null 2>&1 && \
+-			break 2; \
+-	done; \
+-	cpu=$(3); isa=-$(4); \
+-	for gcc_opt in -march= -mcpu=; do \
+-		$(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \
+-			-xc /dev/null > /dev/null 2>&1 && \
+-			break 2; \
+-	done; \
+-	break; \
+-done; \
+-gcc_abi=-mabi=32; gcc_cpu=$$cpu; \
+-if $(CC) $$gcc_abi -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then \
+-	gcc_isa=$$isa; \
+-else \
+-	gcc_abi=; gcc_isa=-$(5); \
+-fi; \
+-gas_abi=-Wa,-32; gas_cpu=$$cpu; gas_isa=-Wa,$$isa; \
+-while :; do \
+-	for gas_opt in -Wa,-march= -Wa,-mcpu=; do \
+-		$(CC) $$gas_abi $$gas_opt$$cpu $$gas_isa -Wa,-Z -c \
+-			-o /dev/null -xassembler /dev/null > /dev/null 2>&1 && \
+-			break 2; \
+-	done; \
+-	gas_abi=; gas_opt=; gas_cpu=; gas_isa=; \
+-	break; \
+-done; \
+-if test "$$gcc_opt" = -march= && test -n "$$gcc_abi"; then \
+-	$(CC) $$gcc_abi $$gcc_opt$$gcc_cpu -S -o /dev/null \
+-		-xc /dev/null > /dev/null 2>&1 && \
+-		gcc_isa=; \
+-fi; \
+-echo $$gcc_abi $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_abi $$gas_opt$$gas_cpu $$gas_isa)
+-
+-#
+ # CPU-dependent compiler/assembler options for optimization.
+ #
+ ifdef CONFIG_CPU_R3000
+-GCCFLAGS	+= $(call set_gccflags,r3000,mips1,r3000,mips1,mips1)
++GCCFLAGS	+= -march=r3000
+ endif
+ ifdef CONFIG_CPU_TX39XX
+-GCCFLAGS	+= $(call set_gccflags,r3900,mips1,r3000,mips1,mips1)
++GCCFLAGS	+= -march=r3900
+ endif
+ ifdef CONFIG_CPU_R6000
+-GCCFLAGS	+= $(call set_gccflags,r6000,mips2,r6000,mips2,mips2) \
+-		   -Wa,--trap
++GCCFLAGS	+= -march=r6000 -Wa,--trap
+ endif
+ ifdef CONFIG_CPU_R4300
+-GCCFLAGS	+= $(call set_gccflags,r4300,mips3,r4300,mips3,mips2) \
+-		   -Wa,--trap
++GCCFLAGS	+= -march=vr4300 -Wa,--trap
+ endif
+ ifdef CONFIG_CPU_VR41XX
+-GCCFLAGS	+= $(call set_gccflags,r4100,mips3,r4600,mips3,mips2) \
+-		   -Wa,--trap
++GCCFLAGS	+= -march=vr4100 -Wa,--trap
+ endif
+ ifdef CONFIG_CPU_R4X00
+-GCCFLAGS	+= $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \
+-		   -Wa,--trap
++GCCFLAGS	+= -march=r4600 -Wa,--trap
+ endif
+ ifdef CONFIG_CPU_TX49XX
+-GCCFLAGS	+= $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \
+-		   -Wa,--trap
++GCCFLAGS	+= -march=r4600 -Wa,--trap
+ endif
+ ifdef CONFIG_CPU_MIPS32
+-GCCFLAGS	+= $(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \
+-		   -Wa,--trap
++GCCFLAGS	+= -march=mips32 -Wa,--trap
+ endif
+ ifdef CONFIG_CPU_MIPS64
+-GCCFLAGS	+= $(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \
+-		   -Wa,--trap
++GCCFLAGS	+= -march=mips64 -Wa,--trap
+ endif
+ ifdef CONFIG_CPU_R5000
+-GCCFLAGS	+= $(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \
+-		   -Wa,--trap
++GCCFLAGS	+= -march=vr5000 -Wa,--trap
+ endif
+ ifdef CONFIG_CPU_R5432
+-GCCFLAGS	+= $(call set_gccflags,r5400,mips4,r5000,mips4,mips2) \
+-		   -Wa,--trap
++GCCFLAGS	+= -march=vr5400 -Wa,--trap
+ endif
+ ifdef CONFIG_CPU_NEVADA
+-GCCFLAGS	+= $(call set_gccflags,rm5200,mips4,r5000,mips4,mips2) \
+-		   -Wa,--trap
+-#GCCFLAGS	+= $(call check_gcc,-mmad,)
++GCCFLAGS	+= -march=vr5000 -Wa,--trap
+ endif
+ ifdef CONFIG_CPU_RM7000
+-GCCFLAGS	+= $(call set_gccflags,rm7000,mips4,r5000,mips4,mips2) \
+-		   -Wa,--trap
++# rm7000 available since gcc 3.4
++GCCFLAGS	+= $(call check_gcc,-march=rm7000,-march=vr5000) -Wa,--trap
+ endif
+ ifdef CONFIG_CPU_RM9000
+-GCCFLAGS	+= $(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \
+-		   -Wa,--trap
++# rm9000 available since gcc 3.4
++GCCFLAGS	+= $(call check_gcc,-march=rm9000,-march=vr5000) -Wa,--trap
+ endif
+ ifdef CONFIG_CPU_SB1
+-GCCFLAGS	+= $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \
+-		   -Wa,--trap
++GCCFLAGS	+= -march=sb1 -Wa,--trap
+ ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
+ MODFLAGS	+= -msb1-pass1-workarounds
+ endif


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/05_linux-mips-makefile.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/10_cobalt-patch.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/10_cobalt-patch.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/10_cobalt-patch.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,492 @@
+#! /bin/sh -e
+## 10_cobalt-patch.dpatch by Karsten Merker <karsten at excalibur.cologne.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Cobalt fixes for 2.4 from http://www.colonel-panic.org/cobalt-mips/
+## DP: cobalt-patch-2.4.x-20040411
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p1 ${patch_opts} < $0;;
+    -unpatch) patch -R -p1 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+diff -urN linux.cvs/arch/mips/cobalt/pci.c linux.pdh/arch/mips/cobalt/pci.c
+--- linux.cvs/arch/mips/cobalt/pci.c	2003-07-05 14:17:03.000000000 +0100
++++ linux.pdh/arch/mips/cobalt/pci.c	2004-04-11 16:27:59.000000000 +0100
+@@ -211,7 +211,14 @@
+ 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
+ 	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7);
+ 
+-	/* On all machines prior to Q2, we had the STOP line disconnected
++	/* The code described by the comment below has been removed
++	 * as it causes bus mastering by the Ethernet controllers
++	 * to break under any kind of network load. We always set
++	 * the retry timeouts to their maximum.
++	 *
++	 * --x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--x--
++	 *
++	 * On all machines prior to Q2, we had the STOP line disconnected
+ 	 * from Galileo to VIA on PCI.  The new Galileo does not function
+ 	 * correctly unless we have it connected.
+ 	 *
+@@ -220,10 +227,16 @@
+ 	 */
+ 	pci_read_config_word(dev, PCI_REVISION_ID, &galileo_id);
+ 	galileo_id &= 0xff;     /* mask off class info */
++
++	printk("Galileo ID: %u\n", galileo_id);
++
++#if 0
+ 	if (galileo_id >= 0x10) {
+ 		/* New Galileo, assumes PCI stop line to VIA is connected. */
+ 		GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS);
+-	} else if (galileo_id == 0x1 || galileo_id == 0x2) {
++	} else if (galileo_id == 0x1 || galileo_id == 0x2)
++#endif
++	{
+ 		signed int timeo;
+ 		/* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */
+ 		timeo = GALILEO_INL(GT_PCI0_TOR_OFS);
+diff -urN linux.cvs/arch/mips/cobalt/setup.c linux.pdh/arch/mips/cobalt/setup.c
+--- linux.cvs/arch/mips/cobalt/setup.c	2003-07-05 14:17:03.000000000 +0100
++++ linux.pdh/arch/mips/cobalt/setup.c	2004-04-11 17:50:11.000000000 +0100
+@@ -34,6 +34,8 @@
+ extern struct rtc_ops std_rtc_ops;
+ extern struct ide_ops std_ide_ops;
+ 
++extern int cobalt_board_id;
++
+ 
+ char arcs_cmdline[CL_SIZE] = {
+  "console=ttyS0,115200 "
+@@ -49,6 +51,16 @@
+ 
+ const char *get_system_type(void)
+ {
++	switch (cobalt_board_id) {
++		case COBALT_BRD_ID_QUBE1:
++			return "Cobalt Qube";
++		case COBALT_BRD_ID_RAQ1:
++			return "Cobalt RaQ";
++		case COBALT_BRD_ID_QUBE2:
++			return "Cobalt Qube2";
++		case COBALT_BRD_ID_RAQ2:
++			return "Cobalt RaQ2";
++	}
+ 	return "MIPS Cobalt";
+ }
+ 
+@@ -98,13 +110,96 @@
+ 	/*ns16550_setup_console();*/
+ }
+ 
++#ifdef CONFIG_BLK_DEV_INITRD
++
++static int __init initrd_setup(unsigned long memsz)
++{
++	extern unsigned long initrd_start, initrd_end;
++	extern char __rd_start, __rd_end;
++
++	unsigned long start, size, phys;
++	char *ptr;
++
++	if (!memcmp(arcs_cmdline, "initrd=", 7))
++		ptr = arcs_cmdline;
++	else {
++		ptr = strstr(arcs_cmdline, " initrd=");
++		if (!ptr)
++			return 0;
++		++ptr;
++	}
++
++	size = simple_strtoul(ptr + 7, &ptr, 16);
++	if (*ptr != '@')
++		goto invalid;
++
++	start = simple_strtoul(ptr + 1, &ptr, 16);
++	if (*ptr && *ptr != ' ')
++		goto invalid;
++
++	phys = CPHYSADDR(start);
++	if (phys + size > memsz) {
++invalid:
++		printk(KERN_WARNING "initrd: command line parameter invalid\n");
++		return 0;
++	}
++
++	if (!size)
++		return 0;
++
++	/* an embedded ramdisk overrides us (arch/mips/kernel/setup.c) */
++
++	if (&__rd_start != &__rd_end) {
++		printk(KERN_WARNING "initrd: overridden by embedded ramdisk\n");
++		return 0;
++	}
++
++	initrd_start = start;
++	initrd_end = start + size;
++
++	add_memory_region(0x0, phys, BOOT_MEM_RAM);
++	add_memory_region(phys, size, BOOT_MEM_RESERVED);
++	phys += size;
++	add_memory_region(phys, memsz - phys, BOOT_MEM_RAM);
++
++	return 1;
++}
++
++#endif /* CONFIG_BLK_DEV_INITRD */
++
+ /* Prom init. We read our one and only communication with the
+-    firmware. Grab the amount of installed memory */
+-void __init prom_init(int argc)
++    firmware. Grab the amount of installed memory.
++    Better boot loaders pass a command line too :-) */
++void __init prom_init(int argc, char *argv[])
+ {
++	int indx, posn, nchr;
++	unsigned long memsz;
++
+ 	mips_machgroup = MACH_GROUP_COBALT;
+ 
+-	add_memory_region(0x0, argc & 0x7fffffff, BOOT_MEM_RAM);
++	memsz = argc & 0x7fff0000;
++	argc &= 0xffff;
++
++	if (argc) {
++		arcs_cmdline[0] = '\0';
++		posn = 0;
++		for (indx = 1; indx < argc; ++indx) {
++			nchr = strlen(argv[indx]);
++			if (posn + 1 + nchr + 1 > sizeof(arcs_cmdline))
++				break;
++			if (posn)
++				arcs_cmdline[posn++] = ' ';
++			strcpy(arcs_cmdline + posn, argv[indx]);
++			posn += nchr;
++		}
++	}
++
++#ifdef CONFIG_BLK_DEV_INITRD
++	if (!initrd_setup(memsz))
++#endif
++	{
++		add_memory_region(0x0, memsz, BOOT_MEM_RAM);
++	}
+ }
+ 
+ void __init prom_free_prom_memory(void)
+diff -urN linux.cvs/arch/mips/defconfig-cobalt linux.pdh/arch/mips/defconfig-cobalt
+--- linux.cvs/arch/mips/defconfig-cobalt	2004-03-15 20:50:55.000000000 +0000
++++ linux.pdh/arch/mips/defconfig-cobalt	2004-04-11 16:27:59.000000000 +0100
+@@ -13,7 +13,9 @@
+ #
+ # Loadable module support
+ #
+-# CONFIG_MODULES is not set
++CONFIG_MODULES=y
++# CONFIG_MODVERSIONS is not set
++CONFIG_KMOD=y
+ 
+ #
+ # Machine selection
+@@ -168,7 +170,7 @@
+ # CONFIG_BLK_DEV_DAC960 is not set
+ # CONFIG_BLK_DEV_UMEM is not set
+ # CONFIG_BLK_DEV_SX8 is not set
+-CONFIG_BLK_DEV_LOOP=y
++# CONFIG_BLK_DEV_LOOP is not set
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
+ # CONFIG_BLK_DEV_INITRD is not set
+@@ -624,15 +626,15 @@
+ #
+ # CONFIG_CODA_FS is not set
+ # CONFIG_INTERMEZZO_FS is not set
+-CONFIG_NFS_FS=y
++# CONFIG_NFS_FS is not set
+ # CONFIG_NFS_V3 is not set
+ # CONFIG_NFS_DIRECTIO is not set
+ # CONFIG_ROOT_NFS is not set
+ # CONFIG_NFSD is not set
+ # CONFIG_NFSD_V3 is not set
+ # CONFIG_NFSD_TCP is not set
+-CONFIG_SUNRPC=y
+-CONFIG_LOCKD=y
++# CONFIG_SUNRPC is not set
++# CONFIG_LOCKD is not set
+ # CONFIG_SMB_FS is not set
+ # CONFIG_NCP_FS is not set
+ # CONFIG_NCPFS_PACKET_SIGNING is not set
+@@ -648,22 +650,8 @@
+ #
+ # Partition Types
+ #
+-CONFIG_PARTITION_ADVANCED=y
+-# CONFIG_ACORN_PARTITION is not set
+-# CONFIG_OSF_PARTITION is not set
+-# CONFIG_AMIGA_PARTITION is not set
+-# CONFIG_ATARI_PARTITION is not set
+-# CONFIG_MAC_PARTITION is not set
++# CONFIG_PARTITION_ADVANCED is not set
+ CONFIG_MSDOS_PARTITION=y
+-# CONFIG_BSD_DISKLABEL is not set
+-# CONFIG_MINIX_SUBPARTITION is not set
+-# CONFIG_SOLARIS_X86_PARTITION is not set
+-# CONFIG_UNIXWARE_DISKLABEL is not set
+-# CONFIG_LDM_PARTITION is not set
+-CONFIG_SGI_PARTITION=y
+-# CONFIG_ULTRIX_PARTITION is not set
+-# CONFIG_SUN_PARTITION is not set
+-# CONFIG_EFI_PARTITION is not set
+ # CONFIG_SMB_NLS is not set
+ # CONFIG_NLS is not set
+ 
+@@ -695,7 +683,7 @@
+ #
+ # Kernel hacking
+ #
+-CONFIG_CROSSCOMPILE=y
++# CONFIG_CROSSCOMPILE is not set
+ # CONFIG_RUNTIME_DEBUG is not set
+ # CONFIG_KGDB is not set
+ # CONFIG_GDB_CONSOLE is not set
+diff -urN linux.cvs/arch/mips/ld.script.in linux.pdh/arch/mips/ld.script.in
+--- linux.cvs/arch/mips/ld.script.in	2004-02-06 15:14:07.000000000 +0000
++++ linux.pdh/arch/mips/ld.script.in	2004-04-11 16:27:59.000000000 +0100
+@@ -30,6 +30,10 @@
+   __ksymtab : { *(__ksymtab) }
+   __stop___ksymtab = .;
+ 
++  __start___kallsyms = .;	/* All kernel symbols */
++  __kallsyms : { *(__kallsyms) }
++  __stop___kallsyms = .;
++
+   _etext = .;
+ 
+   . = ALIGN(8192);
+diff -urN linux.cvs/arch/mips/lib/dump_tlb.c linux.pdh/arch/mips/lib/dump_tlb.c
+--- linux.cvs/arch/mips/lib/dump_tlb.c	2004-02-11 15:05:10.000000000 +0000
++++ linux.pdh/arch/mips/lib/dump_tlb.c	2004-04-11 16:27:59.000000000 +0100
+@@ -32,6 +32,7 @@
+ 	case PM_256M:	return "256Mb";
+ #endif
+ 	}
++	return "???";
+ }
+ 
+ void dump_tlb(int first, int last)
+diff -urN linux.cvs/arch/mips/lib/rtc-no.c linux.pdh/arch/mips/lib/rtc-no.c
+--- linux.cvs/arch/mips/lib/rtc-no.c	2004-01-08 18:31:49.000000000 +0000
++++ linux.pdh/arch/mips/lib/rtc-no.c	2004-04-11 16:27:59.000000000 +0100
+@@ -29,5 +29,3 @@
+     .rtc_write_data = (void *) &shouldnt_happen,
+     .rtc_bcd_mode   = (void *) &shouldnt_happen
+ };
+-
+-EXPORT_SYMBOL(rtc_ops);
+diff -urN linux.cvs/drivers/net/tulip/eeprom.c linux.pdh/drivers/net/tulip/eeprom.c
+--- linux.cvs/drivers/net/tulip/eeprom.c	2003-02-25 22:03:08.000000000 +0000
++++ linux.pdh/drivers/net/tulip/eeprom.c	2004-04-11 16:27:59.000000000 +0100
+@@ -62,6 +62,22 @@
+ 	 */
+ 	{ 0x1e00, 0x0000, 0x000b, 0x8f01, 0x0103, 0x0300, 0x0821, 0x000, 0x0001, 0x0000, 0x01e1 }
+   },
++  {"Cobalt Microserver", 0, 0x10, 0xE0, {0x1e00, /* 0 == controller #, 1e == offset	*/
++					 0x0000, /* 0 == high offset, 0 == gap		*/
++					 0x0800, /* Default Autoselect			*/
++					 0x8001, /* 1 leaf, extended type, bogus len	*/
++					 0x0003, /* Type 3 (MII), PHY #0		*/
++					 0x0400, /* 0 init instr, 4 reset instr		*/
++					 0x0801, /* Set control mode, GP0 output	*/
++					 0x0000, /* Drive GP0 Low (RST is active low)	*/
++					 0x0800, /* control mode, GP0 input (undriven)	*/
++					 0x0000, /* clear control mode			*/
++					 0x7800, /* 100TX FDX + HDX, 10bT FDX + HDX	*/
++					 0x01e0, /* Advertise all above			*/
++					 0x5000, /* FDX all above			*/
++					 0x1800, /* Set fast TTM in 100bt modes		*/
++					 0x0000, /* PHY cannot be unplugged		*/
++  }},
+   {0, 0, 0, 0, {}}};
+ 
+ 
+diff -urN linux.cvs/drivers/net/tulip/media.c linux.pdh/drivers/net/tulip/media.c
+--- linux.cvs/drivers/net/tulip/media.c	2003-02-25 22:03:08.000000000 +0000
++++ linux.pdh/drivers/net/tulip/media.c	2004-04-11 16:27:59.000000000 +0100
+@@ -400,6 +400,9 @@
+ 	}
+ 
+ 	tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
++
++	udelay(1000);
++
+ 	return;
+ }
+ 
+diff -urN linux.cvs/drivers/net/tulip/tulip_core.c linux.pdh/drivers/net/tulip/tulip_core.c
+--- linux.cvs/drivers/net/tulip/tulip_core.c	2003-11-19 18:49:50.000000000 +0000
++++ linux.pdh/drivers/net/tulip/tulip_core.c	2004-04-11 16:27:59.000000000 +0100
+@@ -1595,8 +1595,8 @@
+                     (PCI_SLOT(pdev->devfn) == 12))) {
+                        /* Cobalt MAC address in first EEPROM locations. */
+                        sa_offset = 0;
+-                       /* No media table either */
+-                       tp->flags &= ~HAS_MEDIA_TABLE;
++		       /* Ensure our media table fixup get's applied */
++		       memcpy(ee_data + 16, ee_data, 8);
+                }
+ #endif
+ #ifdef __hppa__
+diff -urN linux.cvs/include/asm-mips/cobalt/ide.h linux.pdh/include/asm-mips/cobalt/ide.h
+--- linux.cvs/include/asm-mips/cobalt/ide.h	1970-01-01 01:00:00.000000000 +0100
++++ linux.pdh/include/asm-mips/cobalt/ide.h	2004-04-11 16:27:59.000000000 +0100
+@@ -0,0 +1,71 @@
++/*
++ * PIO "in" transfers can cause D-cache lines to be allocated
++ * to the data being read. If the target is the page cache then
++ * the kernel can create a user space mapping of the same page
++ * without flushing it from the D-cache. This has large potential
++ * to create cache aliases. The Cobalts seem to trigger this
++ * problem easily.
++ *
++ * MIPs doesn't have a flush_dcache_range() so we roll
++ * our own.
++ *
++ * -- pdh
++ */
++
++#include <asm/r4kcache.h>
++
++static inline void __flush_dcache(void)
++{
++	unsigned long dc_size, dc_line, addr, end;
++
++	dc_size = current_cpu_data.dcache.ways << current_cpu_data.dcache.waybit;
++	dc_line = current_cpu_data.dcache.linesz;
++
++	addr = KSEG0;
++	end = addr + dc_size;
++
++	for (; addr < end; addr += dc_line)
++		flush_dcache_line_indexed(addr);
++}
++
++static inline void __flush_dcache_range(unsigned long start, unsigned long end)
++{
++	unsigned long dc_size, dc_line, addr;
++
++	dc_size = current_cpu_data.dcache.ways << current_cpu_data.dcache.waybit;
++	dc_line = current_cpu_data.dcache.linesz;
++
++	addr = start & ~(dc_line - 1);
++	end += dc_line - 1;
++
++	if (end - addr < dc_size)
++		for (; addr < end; addr += dc_line)
++			flush_dcache_line(addr);
++	else
++		__flush_dcache();
++}
++
++static inline void __ide_insw(unsigned long port, void *addr, unsigned int count)
++{
++	__insw(port, addr, count);
++
++	__flush_dcache_range((unsigned long) addr, (unsigned long) addr + count * 2);
++}
++
++static inline void __ide_insl(unsigned long port, void *addr, unsigned int count)
++{
++	__insl(port, addr, count);
++
++	__flush_dcache_range((unsigned long) addr, (unsigned long) addr + count * 4);
++}
++
++#undef insw
++#undef insl
++
++#define insw(p,a,n)		__ide_insw((p),(a),(n))
++#define insl(p,a,n)		__ide_insl((p),(a),(n))
++
++#define __ide_mm_insw(p,a,n)	do{BUG();}while(0)
++#define __ide_mm_insl(p,a,n)	do{BUG();}while(0)
++#define __ide_mm_outsw(p,a,n)	do{BUG();}while(0)
++#define __ide_mm_outsl(p,a,n)	do{BUG();}while(0)
+diff -urN linux.cvs/include/asm-mips/ide.h linux.pdh/include/asm-mips/ide.h
+--- linux.cvs/include/asm-mips/ide.h	2003-07-15 16:08:33.000000000 +0100
++++ linux.pdh/include/asm-mips/ide.h	2004-04-11 17:21:40.000000000 +0100
+@@ -68,7 +68,11 @@
+ #define ide_ack_intr(hwif)	((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
+ #endif
+ 
++#ifdef CONFIG_MIPS_COBALT
++#include <asm/cobalt/ide.h>
++#else
+ #include <asm-generic/ide_iops.h>
++#endif
+ 
+ #endif /* __KERNEL__ */
+ 
+diff -urN linux.cvs/include/linux/udf_fs_sb.h linux.pdh/include/linux/udf_fs_sb.h
+--- linux.cvs/include/linux/udf_fs_sb.h	2002-06-26 23:36:46.000000000 +0100
++++ linux.pdh/include/linux/udf_fs_sb.h	2004-04-11 16:27:59.000000000 +0100
+@@ -18,7 +18,7 @@
+ #ifndef _UDF_FS_SB_H
+ #define _UDF_FS_SB_H 1
+ 
+-#pragma pack(1)
++//#pragma pack(1)
+ 
+ #define UDF_MAX_BLOCK_LOADED	8
+ 
+@@ -31,13 +31,13 @@
+ {
+ 	__u16	s_packet_len;
+ 	struct buffer_head *s_spar_map[4];
+-};
++} __attribute__((packed));
+ 
+ struct udf_virtual_data
+ {
+ 	__u32	s_num_entries;
+ 	__u16	s_start_offset;
+-};
++} __attribute__((packed));
+ 
+ struct udf_bitmap
+ {
+@@ -45,7 +45,7 @@
+ 	__u32			s_extPosition;
+ 	__u16			s_nr_groups;
+ 	struct buffer_head 	**s_block_bitmap;
+-};
++} __attribute__((packed));
+ 
+ struct udf_part_map
+ {
+@@ -71,9 +71,9 @@
+ 	__u32	(*s_partition_func)(struct super_block *, __u32, __u16, __u32);
+ 	__u16	s_volumeseqnum;
+ 	__u16	s_partition_flags;
+-};
++} __attribute__((packed));
+ 
+-#pragma pack()
++//#pragma pack()
+ 
+ struct udf_sb_info
+ {


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/10_cobalt-patch.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/20_sb1-mipsrtc.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/20_sb1-mipsrtc.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/20_sb1-mipsrtc.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,37 @@
+#! /bin/sh -e
+## 20_sb1-mipsrtc.dpatch by Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: SWARM needs CONFIG_MIPS_RTC
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p1 ${patch_opts} < $0;;
+    -unpatch) patch -R -p1 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+--- kernel-source-2.4.27/arch/mips/config-shared.in.old	2004-08-18 16:06:03.000000000 +0200
++++ kernel-source-2.4.27/arch/mips/config-shared.in	2004-08-18 16:06:16.000000000 +0200
+@@ -202,6 +202,10 @@ if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]
+         "$CONFIG_SIBYTE_STANDALONE" != "y" ]; then
+       define_bool CONFIG_SMP_CAPABLE y
+    fi
++
++   if [ "$CONFIG_SIBYTE_SWARM" = "y" ]; then
++      define_bool CONFIG_MIPS_RTC y
++   fi
+ fi
+ bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI
+ bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/20_sb1-mipsrtc.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/21_sb-duart.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/21_sb-duart.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/21_sb-duart.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,45 @@
+#! /bin/sh -e
+## 21_sb-duart.dpatch by Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Export sb1250_duart_present
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p0 ${patch_opts} < $0;;
+    -unpatch) patch -R -p0 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+--- drivers/char/Makefile.old	2004-05-08 09:54:05.000000000 +0200
++++ drivers/char/Makefile	2004-05-08 09:54:29.000000000 +0200
+@@ -25,7 +25,7 @@ export-objs     :=	busmouse.o console.o 
+ 			misc.o pty.o random.o selection.o serial.o \
+ 			sonypi.o tty_io.o tty_ioctl.o generic_serial.o \
+ 			au1000_gpio.o vac-serial.o hp_psaux.o nvram.o \
+-			scx200.o fetchop.o hydrogen3_buttons.o
++			scx200.o fetchop.o hydrogen3_buttons.o sb1250_duart.o
+ 
+ mod-subdirs	:=	joystick ftape drm drm-4.0 pcmcia
+ 
+--- drivers/char/sb1250_duart.c.old	2004-05-08 09:52:43.000000000 +0200
++++ drivers/char/sb1250_duart.c	2004-05-08 09:53:45.000000000 +0200
+@@ -953,3 +953,7 @@ void __init sb1250_serial_console_init(v
+ }
+ 
+ #endif /* CONFIG_SIBYTE_SB1250_DUART_CONSOLE */
++
++EXPORT_SYMBOL(sb1250_duart_present);
++
++MODULE_LICENSE("GPL");


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/21_sb-duart.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/22_swarm-pcmcia.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/22_swarm-pcmcia.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/22_swarm-pcmcia.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,42 @@
+#! /bin/sh -e
+## 22_swarm-pcmcia.dpatch by Peter de Schrijver <p2 at mind.be>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Fix PCMCIA initialization.
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p1 ${patch_opts} < $0;;
+    -unpatch) patch -R -p1 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+--- kernel-source-2.4.26/drivers/pcmcia/cs.c.old	2004-02-21 04:47:08.000000000 +0100
++++ kernel-source-2.4.26/drivers/pcmcia/cs.c	2004-05-11 20:26:35.000000000 +0200
+@@ -1720,6 +1720,7 @@ int pcmcia_request_configuration(client_
+ 	c->Copy = req->Copy;
+ 	write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy);
+     }
++#ifndef CONFIG_SIBYTE_SB1xxx_SOC
+     if (req->Present & PRESENT_OPTION) {
+ 	if (s->functions == 1) {
+ 	    c->Option = req->ConfigIndex & COR_CONFIG_MASK;
+@@ -1735,6 +1736,7 @@ int pcmcia_request_configuration(client_
+ 	write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option);
+ 	mdelay(40);
+     }
++#endif
+     if (req->Present & PRESENT_STATUS) {
+ 	c->Status = req->Status;
+ 	write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &c->Status);


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/22_swarm-pcmcia.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/30_dec-initrd.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/30_dec-initrd.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/30_dec-initrd.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,51 @@
+#! /bin/sh -e
+## 30_dec-initrd.dpatch by Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Remove broken DECstation initrd initialization.
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p1 ${patch_opts} < $0;;
+    -unpatch) patch -R -p1 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+diff -Nur linux-mips-cvs-20040326/arch/mips/dec/setup.c linux-mips-cvs-20040326.patched/arch/mips/dec/setup.c
+--- linux-mips-cvs-20040326/arch/mips/dec/setup.c	2003-12-11 16:06:48.000000000 +0000
++++ linux-mips-cvs-20040326.patched/arch/mips/dec/setup.c	2004-04-01 21:19:44.000000000 +0000
+@@ -48,11 +48,6 @@
+ 
+ extern asmlinkage void decstation_handle_int(void);
+ 
+-#ifdef CONFIG_BLK_DEV_INITRD
+-extern unsigned long initrd_start, initrd_end;
+-extern void * __rd_start, * __rd_end;
+-#endif
+-
+ spinlock_t ioasic_ssr_lock;
+ 
+ volatile u32 *ioasic_base;
+@@ -136,11 +131,6 @@
+ 
+ void __init decstation_setup(void)
+ {
+-#ifdef CONFIG_BLK_DEV_INITRD
+-	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+-	initrd_start = (unsigned long)&__rd_start;
+-	initrd_end = (unsigned long)&__rd_end;
+-#endif
+ 	board_be_init = dec_be_init;
+ 	board_time_init = dec_time_init;
+ 	board_timer_setup = dec_timer_setup;


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/30_dec-initrd.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/31_dec-pmadaa.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/31_dec-pmadaa.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/31_dec-pmadaa.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,1359 @@
+#! /bin/sh -e
+## 31_dec-pmadaa.dpatch by Karsten Merker <karsten at excalibur.cologne.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: DECstation PMAD-AA support.
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p1 ${patch_opts} < $0;;
+    -unpatch) patch -R -p1 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+diff -Nur linux/drivers/net/Config.in linux-patched/drivers/net/Config.in
+--- linux/drivers/net/Config.in	Sun Mar 21 21:31:50 2004
++++ linux-patched/drivers/net/Config.in	Sun Mar 21 19:44:40 2004
+@@ -240,6 +240,9 @@
+    if [ "$CONFIG_DECSTATION" = "y" ]; then
+       tristate '  DEC LANCE ethernet controller support' CONFIG_DECLANCE
+    fi
++   if [ "$CONFIG_DECSTATION" = "y" ]; then
++      tristate '  PMAD-AA TC ethernet controller support' CONFIG_PMADAA
++   fi
+    if [ "$CONFIG_BAGET_MIPS" = "y" ]; then
+       tristate '  Baget AMD LANCE support' CONFIG_BAGETLANCE
+    fi
+diff -Nur linux/drivers/net/Makefile linux-patched/drivers/net/Makefile
+--- linux/drivers/net/Makefile	Sun Mar 21 21:31:50 2004
++++ linux-patched/drivers/net/Makefile	Sun Mar 21 19:45:27 2004
+@@ -225,6 +225,7 @@
+ obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
+ obj-$(CONFIG_BAGETLANCE) += bagetlance.o
+ obj-$(CONFIG_DECLANCE) += declance.o
++obj-$(CONFIG_PMADAA) += pmadaa.o
+ obj-$(CONFIG_ATARILANCE) += atarilance.o
+ obj-$(CONFIG_ATARI_BIONET) += atari_bionet.o
+ obj-$(CONFIG_ATARI_PAMSNET) += atari_pamsnet.o
+diff -Nur linux/drivers/net/declance.c linux-patched/drivers/net/declance.c
+--- linux/drivers/net/declance.c	Sun Mar 21 21:31:51 2004
++++ linux-patched/drivers/net/declance.c	Sun Mar 21 20:54:26 2004
+@@ -1279,6 +1279,10 @@
+ static int __init dec_lance_probe(void)
+ {
+ 	int count = 0;
++#if 0
++/* We handle only onboard devices in declance.c
++ * The PMAD-AA TC board is handled by pmadaa.c
++ */
+ 
+ 	/* Scan slots for PMAD-AA cards first. */
+ #ifdef CONFIG_TC
+@@ -1292,7 +1296,7 @@
+ 		}
+ 	}
+ #endif
+-
++#endif
+ 	/* Then handle onboard devices. */
+ 	if (dec_interrupt[DEC_IRQ_LANCE] >= 0) {
+ 		if (dec_interrupt[DEC_IRQ_LANCE_MERR] >= 0) {
+diff -Nur linux/drivers/net/pmadaa.c linux-patched/drivers/net/pmadaa.c
+--- linux/drivers/net/pmadaa.c	Thu Jan  1 01:00:00 1970
++++ linux-patched/drivers/net/pmadaa.c	Sun Mar 21 21:21:53 2004
+@@ -0,0 +1,1284 @@
++/*     
++ *    Lance ethernet driver for the MIPS processor based
++ *      DECstation family
++ *
++ *
++ *	********** DECSTATION 5000/200 AND PMAD-AA ONLY **********
++ *
++ *      adopted from sunlance.c by Richard van den Berg
++ *
++ *      Copyright (C) 2002  Maciej W. Rozycki
++ *
++ *      additional sources:
++ *      - PMAD-AA TURBOchannel Ethernet Module Functional Specification,
++ *        Revision 1.2
++ *
++ *      History:
++ *
++ *      v0.001: The kernel accepts the code and it shows the hardware address.
++ *
++ *      v0.002: Removed most sparc stuff, left only some module and dma stuff.
++ *
++ *      v0.003: Enhanced base address calculation from proposals by
++ *              Harald Koerfgen and Thomas Riemer.
++ *
++ *      v0.004: lance-regs is pointing at the right addresses, added prom
++ *              check. First start of address mapping and DMA.
++ *
++ *      v0.005: started to play around with LANCE-DMA. This driver will not
++ *              work for non IOASIC lances. HK
++ *
++ *      v0.006: added pointer arrays to lance_private and setup routine for
++ *              them in dec_lance_init. HK
++ *
++ *      v0.007: Big shit. The LANCE seems to use a different DMA mechanism to
++ *              access the init block. This looks like one (short) word at a
++ *              time, but the smallest amount the IOASIC can transfer is a
++ *              (long) word. So we have a 2-2 padding here. Changed
++ *              lance_init_block accordingly. The 16-16 padding for the buffers
++ *              seems to be correct. HK
++ *
++ *      v0.008: mods to make PMAX_LANCE work. 01/09/1999 triemer
++ *
++ *      v0.009: Module support fixes, multiple interfaces support, various
++ *              bits. macro
++ *
++ * This version of the driver only works on the DS5000/200 and maybe on some 
++ * non-Turbochannel machines.. - Dave Airlie 1999 (airlied at linux.ie)
++ * 
++ * 2002/12/23 The driver now also correctly supports the PMAD-AA
++ *            TurboChannel card (Code by Maciej W. Rozycki,
++ *            (macro at ds2.pg.gda.pl)
++ *
++ * 2004/03/25 Adapted to changes in kernel version 2.4.25 
++ *            (some symbolic names for registers and functions
++ *            have changed, in particular SSR became IO_REG_SSR,
++ *            LANCE_DMA_EN became IO_SSR_LANCE_DMA_EN, 
++ *            ESAR became IOASIC_ESAR, LANCE_DMA_P became IO_REG_LANCE_DMA_P
++ *            and the LANCE address offset was relabeled from LANCE to 
++ *            IOASIC_LANCE).
++ *            Bumped up version to 0.010 to reflect the change.
++ *            Karsten Merker (merker at debian.org)
++ */
++
++#include <linux/config.h>
++#include <linux/crc32.h>
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/if_ether.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/stddef.h>
++#include <linux/string.h>
++
++#include <asm/addrspace.h>
++#include <asm/dec/interrupts.h>
++#include <asm/dec/ioasic.h>
++#include <asm/dec/ioasic_addrs.h>
++#include <asm/dec/kn01.h>
++#include <asm/dec/machtype.h>
++#include <asm/dec/tc.h>
++#include <asm/system.h>
++
++static char version[] __devinitdata =
++"pmadaa.c: v0.010 by Linux MIPS DECstation task force\n";
++
++MODULE_AUTHOR("Linux MIPS DECstation task force");
++MODULE_DESCRIPTION("PMAD-AA driver");
++MODULE_LICENSE("GPL");
++
++/*
++ * card types
++ */
++#define ASIC_LANCE 1
++#define PMAD_LANCE 2
++#define PMAX_LANCE 3
++
++#ifndef CONFIG_TC
++unsigned long system_base;
++unsigned long dmaptr;
++#endif
++
++#define LE_CSR0 0
++#define LE_CSR1 1
++#define LE_CSR2 2
++#define LE_CSR3 3
++
++#define LE_MO_PROM      0x8000	/* Enable promiscuous mode */
++
++#define	LE_C0_ERR	0x8000	/* Error: set if BAB, SQE, MISS or ME is set */
++#define	LE_C0_BABL	0x4000	/* BAB:  Babble: tx timeout. */
++#define	LE_C0_CERR	0x2000	/* SQE:  Signal quality error */
++#define	LE_C0_MISS	0x1000	/* MISS: Missed a packet */
++#define	LE_C0_MERR	0x0800	/* ME:   Memory error */
++#define	LE_C0_RINT	0x0400	/* Received interrupt */
++#define	LE_C0_TINT	0x0200	/* Transmitter Interrupt */
++#define	LE_C0_IDON	0x0100	/* IFIN: Init finished. */
++#define	LE_C0_INTR	0x0080	/* Interrupt or error */
++#define	LE_C0_INEA	0x0040	/* Interrupt enable */
++#define	LE_C0_RXON	0x0020	/* Receiver on */
++#define	LE_C0_TXON	0x0010	/* Transmitter on */
++#define	LE_C0_TDMD	0x0008	/* Transmitter demand */
++#define	LE_C0_STOP	0x0004	/* Stop the card */
++#define	LE_C0_STRT	0x0002	/* Start the card */
++#define	LE_C0_INIT	0x0001	/* Init the card */
++
++#define	LE_C3_BSWP	0x4	/* SWAP */
++#define	LE_C3_ACON	0x2	/* ALE Control */
++#define	LE_C3_BCON	0x1	/* Byte control */
++
++/* Receive message descriptor 1 */
++#define LE_R1_OWN       0x80	/* Who owns the entry */
++#define LE_R1_ERR       0x40	/* Error: if FRA, OFL, CRC or BUF is set */
++#define LE_R1_FRA       0x20	/* FRA: Frame error */
++#define LE_R1_OFL       0x10	/* OFL: Frame overflow */
++#define LE_R1_CRC       0x08	/* CRC error */
++#define LE_R1_BUF       0x04	/* BUF: Buffer error */
++#define LE_R1_SOP       0x02	/* Start of packet */
++#define LE_R1_EOP       0x01	/* End of packet */
++#define LE_R1_POK       0x03	/* Packet is complete: SOP + EOP */
++
++#define LE_T1_OWN       0x80	/* Lance owns the packet */
++#define LE_T1_ERR       0x40	/* Error summary */
++#define LE_T1_EMORE     0x10	/* Error: more than one retry needed */
++#define LE_T1_EONE      0x08	/* Error: one retry needed */
++#define LE_T1_EDEF      0x04	/* Error: deferred */
++#define LE_T1_SOP       0x02	/* Start of packet */
++#define LE_T1_EOP       0x01	/* End of packet */
++#define LE_T1_POK	0x03	/* Packet is complete: SOP + EOP */
++
++#define LE_T3_BUF       0x8000	/* Buffer error */
++#define LE_T3_UFL       0x4000	/* Error underflow */
++#define LE_T3_LCOL      0x1000	/* Error late collision */
++#define LE_T3_CLOS      0x0800	/* Error carrier loss */
++#define LE_T3_RTY       0x0400	/* Error retry */
++#define LE_T3_TDR       0x03ff	/* Time Domain Reflectometry counter */
++
++/* Define: 2^4 Tx buffers and 2^4 Rx buffers */
++
++#ifndef LANCE_LOG_TX_BUFFERS
++#define LANCE_LOG_TX_BUFFERS 4
++#define LANCE_LOG_RX_BUFFERS 4
++#endif
++
++#define TX_RING_SIZE			(1 << (LANCE_LOG_TX_BUFFERS))
++#define TX_RING_MOD_MASK		(TX_RING_SIZE - 1)
++
++#define RX_RING_SIZE			(1 << (LANCE_LOG_RX_BUFFERS))
++#define RX_RING_MOD_MASK		(RX_RING_SIZE - 1)
++
++#define PKT_BUF_SZ		1536
++#define RX_BUFF_SIZE            PKT_BUF_SZ
++#define TX_BUFF_SIZE            PKT_BUF_SZ
++
++#undef TEST_HITS
++#define ZERO 0
++
++/* The DS2000/3000 have a linear 64 KB buffer.
++
++ * The PMAD-AA has 128 kb buffer on-board. 
++ *
++ * The IOASIC LANCE devices use a shared memory region. This region as seen 
++ * from the CPU is (max) 128 KB long and has to be on an 128 KB boundary.
++ * The LANCE sees this as a 64 KB long continuous memory region.
++ *
++ * The LANCE's DMA address is used as an index in this buffer and DMA takes
++ * place in bursts of eight 16-Bit words which are packed into four 32-Bit words
++ * by the IOASIC. This leads to a strange padding: 16 bytes of valid data followed
++ * by a 16 byte gap :-(.
++ */
++
++struct lance_rx_desc {
++	unsigned short rmd0;		/* low address of packet */
++	unsigned char rmd1_hadr;	/* high address of packet */
++	unsigned char rmd1_bits;	/* descriptor bits */
++	short length;			/* 2s complement (negative!)
++					   of buffer length */
++	unsigned short mblength;	/* actual number of bytes received */
++};
++
++struct lance_tx_desc {
++	unsigned short tmd0;		/* low address of packet */
++	unsigned char tmd1_hadr;	/* high address of packet */
++	unsigned char tmd1_bits;	/* descriptor bits */
++	short length;			/* 2s complement (negative!)
++					   of buffer length */
++	unsigned short misc;
++};
++
++
++/* First part of the LANCE initialization block, described in databook. */
++struct lance_init_block {
++	unsigned short mode;		/* pre-set mode (reg. 15) */
++
++	unsigned char phys_addr[6];	/* physical ethernet address */
++	unsigned short filter[4];	/* multicast filter */
++
++	/* Receive and transmit ring base, along with extra bits. */
++	unsigned short rx_ptr;		/* receive descriptor addr */
++	unsigned short rx_len;		/* receive len and high addr */
++	unsigned short tx_ptr;		/* transmit descriptor addr */
++	unsigned short tx_len;		/* transmit len and high addr */
++	short gap0[4];
++
++	/* The buffer descriptors */
++	struct lance_rx_desc brx_ring[RX_RING_SIZE];
++	struct lance_tx_desc btx_ring[TX_RING_SIZE];
++};
++
++#define BUF_OFFSET_CPU sizeof(struct lance_init_block)
++#define BUF_OFFSET_LNC sizeof(struct lance_init_block)
++
++#define libdesc_offset(rt, elem) \
++((__u32)(((unsigned long)(&(((struct lance_init_block *)0)->rt[elem])))))
++
++/*
++ * This works *only* for the ring descriptors
++ */
++#define LANCE_ADDR(x) (PHYSADDR(x))
++
++struct lance_private {
++	struct net_device *next;
++	int type;
++	int slot;
++	int dma_irq;
++	volatile struct lance_regs *ll;
++	volatile struct lance_init_block *init_block;
++
++	spinlock_t	lock;
++
++	int rx_new, tx_new;
++	int rx_old, tx_old;
++
++	struct net_device_stats stats;
++
++	unsigned short busmaster_regval;
++
++	struct timer_list       multicast_timer;
++
++	/* Pointers to the ring buffers as seen from the CPU */
++	char *rx_buf_ptr_cpu[RX_RING_SIZE];
++	char *tx_buf_ptr_cpu[TX_RING_SIZE];
++
++	/* Pointers to the ring buffers as seen from the LANCE */
++	char *rx_buf_ptr_lnc[RX_RING_SIZE];
++	char *tx_buf_ptr_lnc[TX_RING_SIZE];
++};
++
++#define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
++			lp->tx_old+TX_RING_MOD_MASK-lp->tx_new:\
++			lp->tx_old - lp->tx_new-1)
++
++/* The lance control ports are at an absolute address, machine and tc-slot
++ * dependant.
++ * DECstations do only 32-bit access and the LANCE uses 16 bit addresses,
++ * so we have to give the structure an extra member making rap pointing
++ * at the right address
++ */
++struct lance_regs {
++	volatile unsigned short rdp;	/* register data port */
++	unsigned short pad;
++	volatile unsigned short rap;	/* register address port */
++};
++
++int PMADAA_dec_lance_debug = 2;
++
++static struct net_device *root_lance_dev;
++
++static inline void writereg(volatile unsigned short *regptr, short value)
++{
++	*regptr = value;
++	iob();
++}
++
++/* Load the CSR registers */
++static void load_csrs(struct lance_private *lp)
++{
++	volatile struct lance_regs *ll = lp->ll;
++	int leptr;
++
++	/* The address space as seen from the LANCE
++	 * begins at address 0. HK
++	 */
++	leptr = 0;
++
++	writereg(&ll->rap, LE_CSR1);
++	writereg(&ll->rdp, (leptr & 0xFFFF));
++	writereg(&ll->rap, LE_CSR2);
++	writereg(&ll->rdp, leptr >> 16);
++	writereg(&ll->rap, LE_CSR3);
++	writereg(&ll->rdp, lp->busmaster_regval);
++
++	/* Point back to csr0 */
++	writereg(&ll->rap, LE_CSR0);
++}
++
++/*
++ * Our specialized copy routines
++ *
++ */
++void PMADAA_cp_to_buf(const int type, void *to, const void *from, int len)
++{
++	unsigned short *tp, *fp, clen;
++	unsigned char *rtp, *rfp;
++
++	if (type == PMAD_LANCE) {
++		memcpy(to, from, len);
++	} else if (type == PMAX_LANCE) {
++		clen = len >> 1;
++		tp = (unsigned short *) to;
++		fp = (unsigned short *) from;
++
++		while (clen--) {
++			*tp++ = *fp++;
++			tp++;
++		}
++
++		clen = len & 1;
++		rtp = (unsigned char *) tp;
++		rfp = (unsigned char *) fp;
++		while (clen--) {
++			*rtp++ = *rfp++;
++		}
++	} else {
++		/*
++		 * copy 16 Byte chunks
++		 */
++		clen = len >> 4;
++		tp = (unsigned short *) to;
++		fp = (unsigned short *) from;
++		while (clen--) {
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			tp += 8;
++		}
++
++		/*
++		 * do the rest, if any.
++		 */
++		clen = len & 15;
++		rtp = (unsigned char *) tp;
++		rfp = (unsigned char *) fp;
++		while (clen--) {
++			*rtp++ = *rfp++;
++		}
++	}
++
++	iob();
++}
++
++void PMADAA_cp_from_buf(const int type, void *to, const void *from, int len)
++{
++	unsigned short *tp, *fp, clen;
++	unsigned char *rtp, *rfp;
++
++	if (type == PMAD_LANCE) {
++		memcpy(to, from, len);
++	} else if (type == PMAX_LANCE) {
++		clen = len >> 1;
++		tp = (unsigned short *) to;
++		fp = (unsigned short *) from;
++		while (clen--) {
++			*tp++ = *fp++;
++			fp++;
++		}
++
++		clen = len & 1;
++
++		rtp = (unsigned char *) tp;
++		rfp = (unsigned char *) fp;
++
++		while (clen--) {
++			*rtp++ = *rfp++;
++		}
++	} else {
++
++		/*
++		 * copy 16 Byte chunks
++		 */
++		clen = len >> 4;
++		tp = (unsigned short *) to;
++		fp = (unsigned short *) from;
++		while (clen--) {
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			*tp++ = *fp++;
++			fp += 8;
++		}
++
++		/*
++		 * do the rest, if any.
++		 */
++		clen = len & 15;
++		rtp = (unsigned char *) tp;
++		rfp = (unsigned char *) fp;
++		while (clen--) {
++			*rtp++ = *rfp++;
++		}
++
++
++	}
++
++}
++
++/* Setup the Lance Rx and Tx rings */
++static void lance_init_ring(struct net_device *dev)
++{
++	struct lance_private *lp = (struct lance_private *) dev->priv;
++	volatile struct lance_init_block *ib;
++	int leptr;
++	int i;
++
++	ib = (struct lance_init_block *) (dev->mem_start);
++
++	/* Lock out other processes while setting up hardware */
++	netif_stop_queue(dev);
++	lp->rx_new = lp->tx_new = 0;
++	lp->rx_old = lp->tx_old = 0;
++
++	/* Copy the ethernet address to the lance init block.
++	 * XXX bit 0 of the physical address registers has to be zero
++	 */
++	ib->phys_addr[0] = dev->dev_addr[0];
++	ib->phys_addr[1] = dev->dev_addr[1];
++	ib->phys_addr[2] = dev->dev_addr[2];
++	ib->phys_addr[3] = dev->dev_addr[3];
++	ib->phys_addr[4] = dev->dev_addr[4];
++	ib->phys_addr[5] = dev->dev_addr[5];
++	/* Setup the initialization block */
++
++	/* Setup rx descriptor pointer */
++	leptr = LANCE_ADDR(libdesc_offset(brx_ring, 0));
++	ib->rx_len = (LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16);
++	ib->rx_ptr = leptr;
++	if (ZERO)
++		printk("RX ptr: %8.8x(%8.8x)\n", leptr, libdesc_offset(brx_ring, 0));
++
++	/* Setup tx descriptor pointer */
++	leptr = LANCE_ADDR(libdesc_offset(btx_ring, 0));
++	ib->tx_len = (LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16);
++	ib->tx_ptr = leptr;
++	if (ZERO)
++		printk("TX ptr: %8.8x(%8.8x)\n", leptr, libdesc_offset(btx_ring, 0));
++
++	if (ZERO)
++		printk("TX rings:\n");
++
++	/* Setup the Tx ring entries */
++	for (i = 0; i < TX_RING_SIZE; i++) {
++		leptr = (int) lp->tx_buf_ptr_lnc[i];
++		ib->btx_ring[i].tmd0 = leptr;
++		ib->btx_ring[i].tmd1_hadr = leptr >> 16;
++		ib->btx_ring[i].tmd1_bits = 0;
++		ib->btx_ring[i].length = 0xf000;	/* The ones required by tmd2 */
++		ib->btx_ring[i].misc = 0;
++		if (i < 3 && ZERO)
++			printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->tx_buf_ptr_cpu[i]);
++	}
++
++	/* Setup the Rx ring entries */
++	if (ZERO)
++		printk("RX rings:\n");
++	for (i = 0; i < RX_RING_SIZE; i++) {
++		leptr = (int) lp->rx_buf_ptr_lnc[i];
++		ib->brx_ring[i].rmd0 = leptr;
++		ib->brx_ring[i].rmd1_hadr = leptr >> 16;
++		ib->brx_ring[i].rmd1_bits = LE_R1_OWN;
++		ib->brx_ring[i].length = -RX_BUFF_SIZE | 0xf000;
++		ib->brx_ring[i].mblength = 0;
++		if (i < 3 && ZERO)
++			printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->rx_buf_ptr_cpu[i]);
++	}
++	iob();
++}
++
++static int init_restart_lance(struct lance_private *lp)
++{
++	volatile struct lance_regs *ll = lp->ll;
++	int i;
++
++	writereg(&ll->rap, LE_CSR0);
++	writereg(&ll->rdp, LE_C0_INIT);
++
++	/* Wait for the lance to complete initialization */
++	for (i = 0; (i < 100) && !(ll->rdp & LE_C0_IDON); i++) {
++		udelay(10);
++	}
++	if ((i == 100) || (ll->rdp & LE_C0_ERR)) {
++		printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, ll->rdp);
++		return -1;
++	}
++	if ((ll->rdp & LE_C0_ERR)) {
++		printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, ll->rdp);
++		return -1;
++	}
++	writereg(&ll->rdp, LE_C0_IDON);
++	writereg(&ll->rdp, LE_C0_STRT);
++	writereg(&ll->rdp, LE_C0_INEA);
++
++	return 0;
++}
++
++static int lance_rx(struct net_device *dev)
++{
++	struct lance_private *lp = (struct lance_private *) dev->priv;
++	volatile struct lance_init_block *ib;
++	volatile struct lance_rx_desc *rd = 0;
++	unsigned char bits;
++	int len = 0;
++	struct sk_buff *skb = 0;
++	ib = (struct lance_init_block *) (dev->mem_start);
++
++#ifdef TEST_HITS
++	{
++		int i;
++
++		printk("[");
++		for (i = 0; i < RX_RING_SIZE; i++) {
++			if (i == lp->rx_new)
++				printk("%s", ib->brx_ring[i].rmd1_bits &
++					     LE_R1_OWN ? "_" : "X");
++			else
++				printk("%s", ib->brx_ring[i].rmd1_bits &
++					     LE_R1_OWN ? "." : "1");
++		}
++		printk("]");
++	}
++#endif
++
++	for (rd = &ib->brx_ring[lp->rx_new];
++	     !((bits = rd->rmd1_bits) & LE_R1_OWN);
++	     rd = &ib->brx_ring[lp->rx_new]) {
++
++		/* We got an incomplete frame? */
++		if ((bits & LE_R1_POK) != LE_R1_POK) {
++			lp->stats.rx_over_errors++;
++			lp->stats.rx_errors++;
++		} else if (bits & LE_R1_ERR) {
++			/* Count only the end frame as a rx error,
++			 * not the beginning
++			 */
++			if (bits & LE_R1_BUF)
++				lp->stats.rx_fifo_errors++;
++			if (bits & LE_R1_CRC)
++				lp->stats.rx_crc_errors++;
++			if (bits & LE_R1_OFL)
++				lp->stats.rx_over_errors++;
++			if (bits & LE_R1_FRA)
++				lp->stats.rx_frame_errors++;
++			if (bits & LE_R1_EOP)
++				lp->stats.rx_errors++;
++		} else {
++			len = (rd->mblength & 0xfff) - 4;
++			skb = dev_alloc_skb(len + 2);
++
++			if (skb == 0) {
++				printk("%s: Memory squeeze, deferring packet.\n",
++				       dev->name);
++				lp->stats.rx_dropped++;
++				rd->mblength = 0;
++				rd->rmd1_bits = LE_R1_OWN;
++				lp->rx_new = (lp->rx_new + 1) & RX_RING_MOD_MASK;
++				return 0;
++			}
++			lp->stats.rx_bytes += len;
++
++			skb->dev = dev;
++			skb_reserve(skb, 2);	/* 16 byte align */
++			skb_put(skb, len);	/* make room */
++
++			PMADAA_cp_from_buf(lp->type, skb->data,
++				    (char *)lp->rx_buf_ptr_cpu[lp->rx_new],
++				    len);
++
++			skb->protocol = eth_type_trans(skb, dev);
++			netif_rx(skb);
++			dev->last_rx = jiffies;
++			lp->stats.rx_packets++;
++		}
++
++		/* Return the packet to the pool */
++		rd->mblength = 0;
++		rd->length = -RX_BUFF_SIZE | 0xf000;
++		rd->rmd1_bits = LE_R1_OWN;
++		lp->rx_new = (lp->rx_new + 1) & RX_RING_MOD_MASK;
++	}
++	return 0;
++}
++
++static void lance_tx(struct net_device *dev)
++{
++	struct lance_private *lp = (struct lance_private *) dev->priv;
++	volatile struct lance_init_block *ib;
++	volatile struct lance_regs *ll = lp->ll;
++	volatile struct lance_tx_desc *td;
++	int i, j;
++	int status;
++	ib = (struct lance_init_block *) (dev->mem_start);
++	j = lp->tx_old;
++
++	spin_lock(&lp->lock);
++
++	for (i = j; i != lp->tx_new; i = j) {
++		td = &ib->btx_ring[i];
++		/* If we hit a packet not owned by us, stop */
++		if (td->tmd1_bits & LE_T1_OWN)
++			break;
++
++		if (td->tmd1_bits & LE_T1_ERR) {
++			status = td->misc;
++
++			lp->stats.tx_errors++;
++			if (status & LE_T3_RTY)
++				lp->stats.tx_aborted_errors++;
++			if (status & LE_T3_LCOL)
++				lp->stats.tx_window_errors++;
++
++			if (status & LE_T3_CLOS) {
++				lp->stats.tx_carrier_errors++;
++				printk("%s: Carrier Lost\n", dev->name);
++				/* Stop the lance */
++				writereg(&ll->rap, LE_CSR0);
++				writereg(&ll->rdp, LE_C0_STOP);
++				lance_init_ring(dev);
++				load_csrs(lp);
++				init_restart_lance(lp);
++				goto out;
++			}
++			/* Buffer errors and underflows turn off the
++			 * transmitter, restart the adapter.
++			 */
++			if (status & (LE_T3_BUF | LE_T3_UFL)) {
++				lp->stats.tx_fifo_errors++;
++
++				printk("%s: Tx: ERR_BUF|ERR_UFL, restarting\n",
++				       dev->name);
++				/* Stop the lance */
++				writereg(&ll->rap, LE_CSR0);
++				writereg(&ll->rdp, LE_C0_STOP);
++				lance_init_ring(dev);
++				load_csrs(lp);
++				init_restart_lance(lp);
++				goto out;
++			}
++		} else if ((td->tmd1_bits & LE_T1_POK) == LE_T1_POK) {
++			/*
++			 * So we don't count the packet more than once.
++			 */
++			td->tmd1_bits &= ~(LE_T1_POK);
++
++			/* One collision before packet was sent. */
++			if (td->tmd1_bits & LE_T1_EONE)
++				lp->stats.collisions++;
++
++			/* More than one collision, be optimistic. */
++			if (td->tmd1_bits & LE_T1_EMORE)
++				lp->stats.collisions += 2;
++
++			lp->stats.tx_packets++;
++		}
++		j = (j + 1) & TX_RING_MOD_MASK;
++	}
++	lp->tx_old = j;
++out:
++	if (netif_queue_stopped(dev) &&
++	    TX_BUFFS_AVAIL > 0)
++		netif_wake_queue(dev);
++
++	spin_unlock(&lp->lock);
++}
++
++static void lance_dma_merr_int(const int irq, void *dev_id,
++				struct pt_regs *regs)
++{
++	struct net_device *dev = (struct net_device *) dev_id;
++
++	printk("%s: DMA error\n", dev->name);
++}
++
++static void lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs)
++{
++	struct net_device *dev = (struct net_device *) dev_id;
++	struct lance_private *lp = (struct lance_private *) dev->priv;
++	volatile struct lance_regs *ll = lp->ll;
++	int csr0;
++
++	writereg(&ll->rap, LE_CSR0);
++	csr0 = ll->rdp;
++
++	/* Acknowledge all the interrupt sources ASAP */
++	writereg(&ll->rdp, csr0 & (LE_C0_INTR | LE_C0_TINT | LE_C0_RINT));
++
++	if ((csr0 & LE_C0_ERR)) {
++		/* Clear the error condition */
++		writereg(&ll->rdp, LE_C0_BABL | LE_C0_ERR | LE_C0_MISS |
++			 LE_C0_CERR | LE_C0_MERR);
++	}
++	if (csr0 & LE_C0_RINT)
++		lance_rx(dev);
++
++	if (csr0 & LE_C0_TINT)
++		lance_tx(dev);
++
++	if (csr0 & LE_C0_BABL)
++		lp->stats.tx_errors++;
++
++	if (csr0 & LE_C0_MISS)
++		lp->stats.rx_errors++;
++
++	if (csr0 & LE_C0_MERR) {
++		printk("%s: Memory error, status %04x\n", dev->name, csr0);
++
++		writereg(&ll->rdp, LE_C0_STOP);
++
++		lance_init_ring(dev);
++		load_csrs(lp);
++		init_restart_lance(lp);
++		netif_wake_queue(dev);
++	}
++
++	writereg(&ll->rdp, LE_C0_INEA);
++	writereg(&ll->rdp, LE_C0_INEA);
++}
++
++struct net_device *PMADAA_last_dev = 0;
++
++static int lance_open(struct net_device *dev)
++{
++	volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start);
++	struct lance_private *lp = (struct lance_private *) dev->priv;
++	volatile struct lance_regs *ll = lp->ll;
++	int status = 0;
++
++	PMADAA_last_dev = dev;
++
++	/* Stop the Lance */
++	writereg(&ll->rap, LE_CSR0);
++	writereg(&ll->rdp, LE_C0_STOP);
++
++	/* Set mode and clear multicast filter only at device open,
++	 * so that lance_init_ring() called at any error will not
++	 * forget multicast filters.
++	 *
++	 * BTW it is common bug in all lance drivers! --ANK
++	 */
++	ib->mode = 0;
++	ib->filter [0] = 0;
++	ib->filter [1] = 0;
++	ib->filter [2] = 0;
++	ib->filter [3] = 0;
++
++	lance_init_ring(dev);
++	load_csrs(lp);
++
++	netif_start_queue(dev);
++
++	/* Associate IRQ with lance_interrupt */
++	if (request_irq(dev->irq, &lance_interrupt, 0, "lance", dev)) {
++		printk("lance: Can't get IRQ %d\n", dev->irq);
++		return -EAGAIN;
++	}
++	if (lp->dma_irq >= 0) {
++		if (request_irq(lp->dma_irq, &lance_dma_merr_int, 0,
++				"lance error", dev)) {
++			free_irq(dev->irq, dev);
++			printk("lance: Can't get DMA IRQ %d\n", lp->dma_irq);
++			return -EAGAIN;
++		}
++		/* Enable I/O ASIC LANCE DMA.  */
++		fast_wmb();
++		ioasic_write(IO_REG_SSR, ioasic_read(IO_REG_SSR) | IO_SSR_LANCE_DMA_EN);
++	}
++
++	status = init_restart_lance(lp);
++
++	/*
++	 * if (!status)
++	 *      MOD_INC_USE_COUNT;
++	 */
++
++	return status;
++}
++
++static int lance_close(struct net_device *dev)
++{
++	struct lance_private *lp = (struct lance_private *) dev->priv;
++	volatile struct lance_regs *ll = lp->ll;
++
++	netif_stop_queue(dev);
++	del_timer_sync(&lp->multicast_timer);
++
++	/* Stop the card */
++	writereg(&ll->rap, LE_CSR0);
++	writereg(&ll->rdp, LE_C0_STOP);
++
++	if (lp->dma_irq >= 0) {
++		/* Disable I/O ASIC LANCE DMA.  */
++		ioasic_write(IO_REG_SSR, ioasic_read(IO_REG_SSR) & ~IO_SSR_LANCE_DMA_EN);
++		fast_iob();
++		free_irq(lp->dma_irq, dev);
++	}
++	free_irq(dev->irq, dev);
++	/*
++	   MOD_DEC_USE_COUNT;
++	 */
++	return 0;
++}
++
++static inline int lance_reset(struct net_device *dev)
++{
++	struct lance_private *lp = (struct lance_private *) dev->priv;
++	volatile struct lance_regs *ll = lp->ll;
++	int status;
++
++	/* Stop the lance */
++	writereg(&ll->rap, LE_CSR0);
++	writereg(&ll->rdp, LE_C0_STOP);
++
++	lance_init_ring(dev);
++	load_csrs(lp);
++	dev->trans_start = jiffies;
++	status = init_restart_lance(lp);
++	return status;
++}
++
++static void lance_tx_timeout(struct net_device *dev)
++{
++	struct lance_private *lp = (struct lance_private *) dev->priv;
++	volatile struct lance_regs *ll = lp->ll;
++
++	printk(KERN_ERR "%s: transmit timed out, status %04x, reset\n",
++			       dev->name, ll->rdp);
++			lance_reset(dev);
++	netif_wake_queue(dev);
++}
++
++static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++	struct lance_private *lp = (struct lance_private *) dev->priv;
++	volatile struct lance_regs *ll = lp->ll;
++	volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start);
++	int entry, skblen, len;
++
++	skblen = skb->len;
++
++	len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;
++
++	lp->stats.tx_bytes += len;
++
++	entry = lp->tx_new & TX_RING_MOD_MASK;
++	ib->btx_ring[entry].length = (-len);
++	ib->btx_ring[entry].misc = 0;
++
++	PMADAA_cp_to_buf(lp->type, (char *)lp->tx_buf_ptr_cpu[entry], skb->data,
++		  skblen);
++
++	/* Clear the slack of the packet, do I need this? */
++	/* For a firewall its a good idea - AC */
++/*
++   if (len != skblen)
++   memset ((char *) &ib->tx_buf [entry][skblen], 0, (len - skblen) << 1);
++ */
++
++	/* Now, give the packet to the lance */
++	ib->btx_ring[entry].tmd1_bits = (LE_T1_POK | LE_T1_OWN);
++	lp->tx_new = (lp->tx_new + 1) & TX_RING_MOD_MASK;
++
++	if (TX_BUFFS_AVAIL <= 0)
++		netif_stop_queue(dev);
++
++	/* Kick the lance: transmit now */
++	writereg(&ll->rdp, LE_C0_INEA | LE_C0_TDMD);
++
++	spin_unlock_irq(&lp->lock);
++
++	dev->trans_start = jiffies;
++	dev_kfree_skb(skb);
++
++ 	return 0;
++}
++
++static struct net_device_stats *lance_get_stats(struct net_device *dev)
++{
++	struct lance_private *lp = (struct lance_private *) dev->priv;
++
++	return &lp->stats;
++}
++
++static void lance_load_multicast(struct net_device *dev)
++{
++	volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start);
++	volatile u16 *mcast_table = (u16 *) & ib->filter;
++	struct dev_mc_list *dmi = dev->mc_list;
++	char *addrs;
++	int i, j, bit, byte;
++	u32 crc;
++
++	/* set all multicast bits */
++	if (dev->flags & IFF_ALLMULTI) {
++		ib->filter[0] = 0xffff;
++		ib->filter[1] = 0xffff;
++		ib->filter[2] = 0xffff;
++		ib->filter[3] = 0xffff;
++		return;
++	}
++	/* clear the multicast filter */
++	ib->filter[0] = 0;
++	ib->filter[1] = 0;
++	ib->filter[2] = 0;
++	ib->filter[3] = 0;
++
++	/* Add addresses */
++	for (i = 0; i < dev->mc_count; i++) {
++		addrs = dmi->dmi_addr;
++		dmi = dmi->next;
++
++		/* multicast address? */
++		if (!(*addrs & 1))
++			continue;
++
++		crc = ether_crc_le(ETH_ALEN, addrs);
++		crc = crc >> 26;
++		mcast_table[crc >> 4] |= 1 << (crc & 0xf);
++	}
++	return;
++}
++
++static void lance_set_multicast(struct net_device *dev)
++{
++	struct lance_private *lp = (struct lance_private *) dev->priv;
++	volatile struct lance_init_block *ib;
++	volatile struct lance_regs *ll = lp->ll;
++
++	ib = (struct lance_init_block *) (dev->mem_start);
++
++	if (!netif_running(dev))
++		return;
++
++	if (lp->tx_old != lp->tx_new) {
++		mod_timer(&lp->multicast_timer, jiffies + 4);
++		netif_wake_queue(dev);
++		return;
++	}
++
++	netif_stop_queue(dev);
++
++	writereg(&ll->rap, LE_CSR0);
++	writereg(&ll->rdp, LE_C0_STOP);
++
++	lance_init_ring(dev);
++
++	if (dev->flags & IFF_PROMISC) {
++		ib->mode |= LE_MO_PROM;
++	} else {
++		ib->mode &= ~LE_MO_PROM;
++		lance_load_multicast(dev);
++	}
++	load_csrs(lp);
++	init_restart_lance(lp);
++	netif_wake_queue(dev);
++}
++
++static void lance_set_multicast_retry(unsigned long _opaque)
++{
++	struct net_device *dev = (struct net_device *) _opaque;
++
++	lance_set_multicast(dev);
++}
++
++static int __init dec_lance_init(const int type, const int slot)
++{
++	static unsigned version_printed;
++	struct net_device *dev;
++	struct lance_private *lp;
++	volatile struct lance_regs *ll;
++	int i, ret;
++	unsigned long esar_base;
++	unsigned char *esar;
++
++#ifndef CONFIG_TC
++	system_base = KN01_LANCE_BASE;
++#endif
++
++	if (PMADAA_dec_lance_debug && version_printed++ == 0)
++		printk(version);
++
++	dev = init_etherdev(NULL, sizeof(struct lance_private));
++	if (!dev)
++		return -ENOMEM;
++	SET_MODULE_OWNER(dev);
++
++	/*
++	 * init_etherdev ensures the data structures used by the LANCE
++	 * are aligned.
++	 */
++	lp = (struct lance_private *) dev->priv;
++	spin_lock_init(&lp->lock);
++
++	lp->type = type;
++	lp->slot = slot;
++	switch (type) {
++#ifdef CONFIG_TC
++	case ASIC_LANCE:
++		dev->base_addr = system_base + IOASIC_LANCE;
++
++		/* buffer space for the on-board LANCE shared memory */
++		/*
++		 * FIXME: ugly hack!
++		 */
++		dev->mem_start = KSEG1ADDR(0x00020000);
++		dev->mem_end = dev->mem_start + 0x00020000;
++		dev->irq = dec_interrupt[DEC_IRQ_LANCE];
++		esar_base = system_base + IOASIC_ESAR;
++
++		/* Workaround crash with booting KN04 2.1k from Disk */
++		memset((void *)dev->mem_start, 0,
++		       dev->mem_end - dev->mem_start);
++
++		/*
++		 * setup the pointer arrays, this sucks [tm] :-(
++		 */
++		for (i = 0; i < RX_RING_SIZE; i++) {
++			lp->rx_buf_ptr_cpu[i] =
++				(char *)(dev->mem_start + BUF_OFFSET_CPU +
++					 2 * i * RX_BUFF_SIZE);
++			lp->rx_buf_ptr_lnc[i] =
++				(char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
++		}
++		for (i = 0; i < TX_RING_SIZE; i++) {
++			lp->tx_buf_ptr_cpu[i] =
++				(char *)(dev->mem_start + BUF_OFFSET_CPU +
++					 2 * RX_RING_SIZE * RX_BUFF_SIZE +
++					 2 * i * TX_BUFF_SIZE);
++			lp->tx_buf_ptr_lnc[i] =
++				(char *)(BUF_OFFSET_LNC +
++					 RX_RING_SIZE * RX_BUFF_SIZE +
++					 i * TX_BUFF_SIZE);
++		}
++
++		/* Setup I/O ASIC LANCE DMA.  */
++		lp->dma_irq = dec_interrupt[DEC_IRQ_LANCE_MERR];
++		ioasic_write(IO_REG_LANCE_DMA_P, PHYSADDR(dev->mem_start) << 3);
++
++		break;
++
++	case PMAD_LANCE:
++		claim_tc_card(slot);
++
++		dev->mem_start = get_tc_base_addr(slot);
++		dev->base_addr = dev->mem_start + 0x100000;
++		dev->irq = get_tc_irq_nr(slot);
++		esar_base = dev->mem_start + 0x1c0002;
++		lp->dma_irq = -1;
++
++		for (i = 0; i < RX_RING_SIZE; i++) {
++			lp->rx_buf_ptr_cpu[i] =
++				(char *)(dev->mem_start + BUF_OFFSET_CPU +
++					 i * RX_BUFF_SIZE);
++			lp->rx_buf_ptr_lnc[i] =
++				(char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
++		}
++		for (i = 0; i < TX_RING_SIZE; i++) {
++			lp->tx_buf_ptr_cpu[i] =
++				(char *)(dev->mem_start + BUF_OFFSET_CPU +
++					 RX_RING_SIZE * RX_BUFF_SIZE +
++					 i * TX_BUFF_SIZE);
++			lp->tx_buf_ptr_lnc[i] =
++				(char *)(BUF_OFFSET_LNC +
++					 RX_RING_SIZE * RX_BUFF_SIZE +
++					 i * TX_BUFF_SIZE);
++		}
++
++		break;
++#endif
++
++	case PMAX_LANCE:
++		dev->irq = dec_interrupt[DEC_IRQ_LANCE];
++		dev->base_addr = KN01_LANCE_BASE;
++		dev->mem_start = KN01_LANCE_BASE + 0x01000000;
++		esar_base = KN01_RTC_BASE + 1;
++		lp->dma_irq = -1;
++
++		/*
++		 * setup the pointer arrays, this sucks [tm] :-(
++		 */
++		for (i = 0; i < RX_RING_SIZE; i++) {
++			lp->rx_buf_ptr_cpu[i] =
++				(char *)(dev->mem_start + BUF_OFFSET_CPU +
++					 2 * i * RX_BUFF_SIZE);
++			lp->rx_buf_ptr_lnc[i] =
++				(char *)(BUF_OFFSET_LNC + i * RX_BUFF_SIZE);
++		}
++		for (i = 0; i < TX_RING_SIZE; i++) {
++			lp->tx_buf_ptr_cpu[i] =
++				(char *)(dev->mem_start + BUF_OFFSET_CPU +
++					 2 * RX_RING_SIZE * RX_BUFF_SIZE +
++					 2 * i * TX_BUFF_SIZE);
++			lp->tx_buf_ptr_lnc[i] =
++				(char *)(BUF_OFFSET_LNC +
++					 RX_RING_SIZE * RX_BUFF_SIZE +
++					 i * TX_BUFF_SIZE);
++		}
++
++		break;
++
++	default:
++		printk("declance_init called with unknown type\n");
++		ret = -ENODEV;
++		goto err_out;
++	}
++
++	ll = (struct lance_regs *) dev->base_addr;
++	esar = (unsigned char *) esar_base;
++
++	/* prom checks */
++	/* First, check for test pattern */
++	if (esar[0x60] != 0xff && esar[0x64] != 0x00 &&
++	    esar[0x68] != 0x55 && esar[0x6c] != 0xaa) {
++		printk("Ethernet station address prom not found!\n");
++		ret = -ENODEV;
++		goto err_out;
++	}
++	/* Check the prom contents */
++	for (i = 0; i < 8; i++) {
++		if (esar[i * 4] != esar[0x3c - i * 4] &&
++		    esar[i * 4] != esar[0x40 + i * 4] &&
++		    esar[0x3c - i * 4] != esar[0x40 + i * 4]) {
++			printk("Something is wrong with the ethernet "
++			       "station address prom!\n");
++			ret = -ENODEV;
++			goto err_out;
++		}
++	}
++
++	lp->next = root_lance_dev;
++	root_lance_dev = dev;
++
++	/* Copy the ethernet address to the device structure, later to the
++	 * lance initialization block so the lance gets it every time it's
++	 * (re)initialized.
++	 */
++	switch (type) {
++	case ASIC_LANCE:
++		printk("%s: IOASIC onboard LANCE, addr = ", dev->name);
++		break;
++	case PMAD_LANCE:
++		printk("%s: PMAD-AA, addr = ", dev->name);
++		break;
++	case PMAX_LANCE:
++		printk("%s: PMAX onboard LANCE, addr = ", dev->name);
++		break;
++	}
++	for (i = 0; i < 6; i++) {
++		dev->dev_addr[i] = esar[i * 4];
++		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? ',' : ':');
++	}
++
++	printk(" irq = %d\n", dev->irq);
++
++	dev->open = &lance_open;
++	dev->stop = &lance_close;
++	dev->hard_start_xmit = &lance_start_xmit;
++	dev->tx_timeout = &lance_tx_timeout;
++	dev->watchdog_timeo = 5*HZ;
++	dev->get_stats = &lance_get_stats;
++	dev->set_multicast_list = &lance_set_multicast;
++
++	/* lp->ll is the location of the registers for lance card */
++	lp->ll = ll;
++
++	/* busmaster_regval (CSR3) should be zero according to the PMAD-AA
++	 * specification.
++	 */
++	lp->busmaster_regval = 0;
++
++	dev->dma = 0;
++
++	/* We cannot sleep if the chip is busy during a
++	 * multicast list update event, because such events
++	 * can occur from interrupts (ex. IPv6).  So we
++	 * use a timer to try again later when necessary. -DaveM
++	 */
++	init_timer(&lp->multicast_timer);
++	lp->multicast_timer.data = (unsigned long) dev;
++	lp->multicast_timer.function = &lance_set_multicast_retry;
++
++	return 0;
++
++err_out:
++	unregister_netdev(dev);
++	kfree(dev);
++	return ret;
++}
++
++
++/* Find all the lance cards on the system and initialize them */
++static int __init dec_lance_probe(void)
++{
++	int count = 0;
++
++	/* Scan slots for PMAD-AA cards first. */
++#ifdef CONFIG_TC
++	if (TURBOCHANNEL) {
++		int slot;
++
++		while ((slot = search_tc_card("PMAD-AA")) >= 0) {
++			if (dec_lance_init(PMAD_LANCE, slot) < 0)
++				break;
++			count++;
++		}
++	}
++#endif
++
++#if 0 
++  /* we want to handle only the PMAG-AA with this driver */
++
++	/* Then handle onboard devices. */
++	if (dec_interrupt[DEC_IRQ_LANCE] >= 0) {
++		if (dec_interrupt[DEC_IRQ_LANCE_MERR] >= 0) {
++#ifdef CONFIG_TC
++			if (dec_lance_init(ASIC_LANCE, -1) >= 0)
++				count++;
++#endif
++		} else if (!TURBOCHANNEL) {
++			if (dec_lance_init(PMAX_LANCE, -1) >= 0)
++				count++;
++		}
++	}
++#endif
++
++	return (count > 0) ? 0 : -ENODEV;
++}
++
++static void __exit dec_lance_cleanup(void)
++{
++	while (root_lance_dev) {
++		struct net_device *dev = root_lance_dev;
++		struct lance_private *lp = (struct lance_private *)dev->priv;
++
++#ifdef CONFIG_TC
++		if (lp->slot >= 0)
++			release_tc_card(lp->slot);
++#endif
++		root_lance_dev = lp->next;
++		unregister_netdev(dev);
++		kfree(dev);
++	}
++}
++
++module_init(dec_lance_probe);
++module_exit(dec_lance_cleanup);


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/31_dec-pmadaa.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/32_dec-loadkeys.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/32_dec-loadkeys.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/32_dec-loadkeys.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,54 @@
+#! /bin/sh -e
+## 32_dec-loadkeys.dpatch by Karsten Merker <karsten at excalibur.cologne.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Don't regenerate keymap, it breaks on keyboardless machines.
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p1 ${patch_opts} < $0;;
+    -unpatch) patch -R -p1 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+diff -Nur linux-mips-cvs-20040326/Makefile linux-mips-cvs-20040326-with-loadkeys-patch/Makefile
+--- linux-mips-cvs-20040326/Makefile	2004-02-20 01:22:10.000000000 +0000
++++ linux-mips-cvs-20040326-with-loadkeys-patch/Makefile	2004-03-27 07:15:50.000000000 +0000
+@@ -220,7 +220,6 @@
+ 	drivers/scsi/aic7xxx/aicasm/aicdb.h \
+ 	drivers/scsi/aic7xxx/aicasm/y.tab.h \
+ 	drivers/scsi/53c700_d.h \
+-	drivers/tc/lk201-map.c \
+ 	net/khttpd/make_times_h \
+ 	net/khttpd/times.h \
+ 	submenu*
+diff -Nur linux-mips-cvs-20040326/drivers/tc/Makefile linux-mips-cvs-20040326-with-loadkeys-patch/drivers/tc/Makefile
+--- linux-mips-cvs-20040326/drivers/tc/Makefile	2001-01-12 20:44:17.000000000 +0000
++++ linux-mips-cvs-20040326-with-loadkeys-patch/drivers/tc/Makefile	2004-03-27 07:27:13.000000000 +0000
+@@ -38,5 +38,13 @@
+ 
+ include $(TOPDIR)/Rules.make
+ 
+-lk201-map.c: lk201-map.map
+-	loadkeys --mktable lk201-map.map > lk201-map.c
++# FIXME
++# Commented out generation of lk201-map.c as current loadkeys is built
++# using kernel 2.5/2.6 headers which causes the resulting file being 
++# incompatible with kernel 2.4.
++# Added lk201-map.c generated with old, kernel 2.4-compatible loadkeys
++# Karsten Merker <merker at debian.org>, 2004/03/26
++#
++# lk201-map.c: lk201-map.map
++#	loadkeys --mktable lk201-map.map > lk201-map.c
++


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/32_dec-loadkeys.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/40_ip22-hal2.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/40_ip22-hal2.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/40_ip22-hal2.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,47 @@
+#! /bin/sh -e
+## 40_ip22-hal2.dpatch by Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: SGI IP22 hal2 config fix.
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p1 ${patch_opts} < $0;;
+    -unpatch) patch -R -p1 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+diff -urpNX ./dontdiff kernel-source-2.4.25/drivers/sound/Config.in linux-mips-cvs-20040415/drivers/sound/Config.in
+--- kernel-source-2.4.25/drivers/sound/Config.in	2 Mar 2004 05:13:34 -0000
++++ linux-mips-cvs-20040415/drivers/sound/Config.in	15 Apr 2004 08:47:32 -0000
+@@ -62,10 +62,6 @@ dep_tristate '  S3 SonicVibes' CONFIG_SO
+ if [ "$CONFIG_VISWS" = "y" ]; then
+     dep_tristate '  SGI Visual Workstation sound' CONFIG_SOUND_VWSND $CONFIG_SOUND
+ fi
+-if [ "$CONFIG_SGI_IP22" = "y" ] ; then
+-   dep_tristate '  SGI HAL2 sound (EXPERIMENTAL)' CONFIG_SOUND_HAL2 $CONFIG_SOUND $CONFIG_SGI_IP22 $CONFIG_EXPERIMENTAL
+-fi
+-
+ if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then
+     dep_tristate '  IT8172G Sound' CONFIG_SOUND_IT8172 $CONFIG_SOUND
+ fi
+@@ -137,6 +133,8 @@ dep_tristate '  OSS sound modules' CONFI
+ if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
+    bool '      Verbose initialisation' CONFIG_SOUND_TRACEINIT
+    bool '      Persistent DMA buffers' CONFIG_SOUND_DMAP
++
++   dep_tristate '    SGI HAL2 sound (EXPERIMENTAL)' CONFIG_SOUND_HAL2 $CONFIG_SGI_IP22 $CONFIG_EXPERIMENTAL $CONFIG_SOUND_OSS
+ 
+    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+       dep_tristate '    AD1816(A) based cards (EXPERIMENTAL)' CONFIG_SOUND_AD1816 $CONFIG_SOUND_OSS


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/40_ip22-hal2.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/50_xxs1500-boardreset.dpatch
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/50_xxs1500-boardreset.dpatch	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/50_xxs1500-boardreset.dpatch	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,39 @@
+#! /bin/sh -e
+## 50_xxs1500-boardreset.dpatch by Thiemo Seufer <seufer at csv.ica.uni-stuttgart.de>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: xxs1500 board_reset function.
+
+if [ $# -lt 1 ]; then
+    echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+    exit 1
+fi
+
+[ -f debian/patches/00patch-opts ] && . debian/patches/00patch-opts
+patch_opts="${patch_opts:--f --no-backup-if-mismatch} ${2:+-d $2}"
+
+case "$1" in
+    -patch) patch -p1 ${patch_opts} < $0;;
+    -unpatch) patch -R -p1 ${patch_opts} < $0;;
+    *)
+        echo "`basename $0`: script expects -patch|-unpatch as argument" >&2
+        exit 1;;
+esac
+
+exit 0
+
+--- linux_2_4/arch/mips/au1000/xxs1500/board_setup.c.old	2004-08-17 16:12:39.000000000 +0200
++++ linux_2_4/arch/mips/au1000/xxs1500/board_setup.c	2004-08-17 16:15:29.000000000 +0200
+@@ -47,6 +47,12 @@
+ 
+ extern struct rtc_ops no_rtc_ops;
+ 
++void board_reset (void)
++{
++	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
++	au_writel(0x00000000, 0xAE00001C);
++}
++
+ void __init board_setup(void)
+ {
+ 	u32 pin_func;


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/patches-2.4/50_xxs1500-boardreset.dpatch
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/post-install
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/post-install	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/post-install	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -e
+
+# For now, do nothing.
+
+exit 0


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/post-install
___________________________________________________________________
Name: svn:executable
   + *

Added: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/rules
===================================================================
--- trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/rules	2005-01-15 19:54:03 UTC (rev 2304)
+++ trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/rules	2005-01-15 19:55:52 UTC (rev 2305)
@@ -0,0 +1,184 @@
+#!/usr/bin/make -f
+#
+# debian/rules for kernel-patch-mips
+#
+# Copyright (C) 2005 Thiemo Seufer
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+SHELL := sh -e
+
+DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
+
+# The package version should be
+# <kernel upstream>-<abi version>-<debian revision>
+# e.g. 2.6.10-1-1
+debver := $(shell dpkg-parsechangelog |grep '^Version: ' |sed -e 's/^Version: //')
+kernabiver := $(shell echo $(debver) |sed 's/-[^-]*$$//')
+kernver := $(shell echo $(kernabiver) |sed 's/-[^-]*$$//')
+abiver := $(shell echo $(kernabiver) |sed 's/.*-//g')
+
+mtdir := mips-tools
+kdir := build-tmp/kernel-source-$(kernver)
+
+# the flavours we're building for
+flavours := $(shell grep -v ^\# debian/flavours.$(DEB_HOST_ARCH))
+
+# handle mips-tools package build
+MT_CFLAGS = -W -Wall -g -pipe
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+  MT_CFLAGS += -O0
+else
+  MT_CFLAGS += -O2
+endif
+
+MT_INSTALL = install -m 755 -o root -g root
+ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
+  MT_INSTALL += -s
+endif
+
+NUM_CPUS=`cat /proc/cpuinfo | grep '^processor[:space:]*' | wc -l`
+
+unpack: stamps/source-unpack-stamp
+stamps/source-unpack-stamp:
+	rm -rf stamps build-tmp
+	mkdir stamps build-tmp
+	tar -C build-tmp --bzip2 -xf /usr/src/kernel-source-$(kernver).tar.bz2
+	ln -sf asm-mips $(kdir)/include/asm
+	touch $@
+
+patch: stamps/source-patch-stamp
+stamps/source-patch-stamp: stamps/source-unpack-stamp
+	dpatch -d $(kdir) apply-all
+	dpatch cat-all > $@
+
+unpatch:
+ifneq (,$(wildcard stamps/source-patch-stamp))
+	dpatch -d $(kdir) deapply-all
+	rm -f stamps/source-patch-stamp
+endif
+
+debian/control: debian/changelog debian/flavours.$(DEB_HOST_ARCH) \
+		debian/control.in/stub \
+		$(foreach sub,$(flavours),debian/control.in/$(sub))
+	sed -e 's/@@KERNVER@@/$(kernver)/g' \
+		-e 's/@@ABIVER@@/$(abiver)/g' \
+		-e 's/@@ARCH@@/$(DEB_HOST_ARCH)/g' \
+		debian/control.in/stub >$@ && echo '' >> $@
+	$(foreach sub,$(flavours), \
+		sed -e 's/@@KERNVER@@/$(kernver)/g' \
+			-e 's/@@ABIVER@@/$(abiver)/g' \
+			-e 's/@@ARCH@@/$(DEB_HOST_ARCH)/g' \
+			debian/control.in/$(sub) >>$@ \
+			&& echo '' >> $@ &&) :
+
+clean:
+	dh_testdir
+	rm -rf stamps build-tmp
+	dh_clean
+
+# We can't use the build target because the tree is mangled by the
+# binary targets afterwards
+build: debian/control
+
+install: stamps/source-patch-stamp
+	dh_testdir
+	dh_testroot
+	dh_clean -k
+	dh_installdirs -p$(mtdir)
+
+	# build the mips-tools
+	cd $(kdir) && make-kpkg clean && make-kpkg debian
+	cd $(kdir)/arch/mips/boot \
+		&& gcc $(MT_CFLAGS) -o elf2ecoff elf2ecoff.c
+
+	# install files for mips-tools package
+	$(MT_INSTALL) -D $(kdir)/arch/mips/boot/elf2ecoff debian/$(mtdir)/usr/bin/elf2ecoff
+
+binary-headers: install
+	dh_testdir
+	dh_testroot
+ifneq ($(flavours),)
+	cd $(kdir) && make-kpkg clean && make-kpkg debian
+	cp -p debian/changelog debian/control debian/copyright debian/post-install $(kdir)/debian/
+	echo official > $(kdir)/debian/official
+	# We use a random config. If this is not generic enough, we
+	# have to switch to flavour-specific header packages.
+	cp debian/config/mips/r4k-ip22 $(kdir)/.config
+	cd $(kdir) && make-kpkg --append-to-version=-$(abiver) kernel_headers
+	mv build-tmp/kernel-headers-$(kernabiver)_$(debver)_$(DEB_HOST_ARCH).deb ..
+endif
+
+binary-images: stamps/source-patch-stamp
+	dh_testdir
+	dh_testroot
+	#chmod a+x ./scripts/copy-modules
+
+	# Messes up version detection with kernel-package - but that's good
+	$(foreach sub,$(flavours), \
+		echo "Building subarch $(sub)" && \
+		( cd $(kdir) && make-kpkg clean && make-kpkg debian ) && \
+		cp -p debian/changelog debian/control debian/copyright \
+			debian/post-install $(kdir)/debian/ && \
+		echo official > $(kdir)/debian/official && \
+		cp debian/config/$(DEB_HOST_ARCH)/$(sub) $(kdir)/.config && \
+		( cd $(kdir) && CONCURRENCY_LEVEL=$(NUM_CPUS) make-kpkg \
+		  --subarch $(sub) --append-to-version=-$(abiver)-$(sub) kernel_image ) && \
+		mv build-tmp/kernel-image-$(kernabiver)-$(sub)_$(debver)_$(DEB_HOST_ARCH).deb .. && ) :
+
+binary-arch: binary-images binary-headers
+	dh_testdir
+	dh_testroot
+	dh_installdocs -p$(mtdir)
+	dh_installexamples -p$(mtdir) -X.svn
+	dh_installmodules -p$(mtdir)
+	dh_installchangelogs -p$(mtdir)
+	dh_installman -p$(mtdir)
+
+	dh_shlibdeps -p$(mtdir)
+	dh_compress -p$(mtdir) -X.stub
+	dh_link -p$(mtdir)
+	dh_strip -p$(mtdir)
+	dh_fixperms -p$(mtdir)
+	dh_installdeb -p$(mtdir)
+	dh_gencontrol -p$(mtdir)
+	dh_md5sums -p$(mtdir)
+	dh_builddeb -p$(mtdir)
+	# finally add the kernel images and headers
+	$(foreach sub,$(flavours), \
+		dpkg-distaddfile kernel-image-$(kernabiver)-$(sub)_$(debver)_$(DEB_HOST_ARCH).deb base optional && ) :
+ifneq ($(flavours),)
+	dpkg-distaddfile kernel-headers-$(kernabiver)_$(debver)_$(DEB_HOST_ARCH).deb devel optional
+endif
+
+binary-indep:
+
+binary: binary-arch binary-indep
+
+.PHONY: binary binary-arch binary-indep binary-images binary-headers build \
+	clean install patch unpatch
+
+#############################################################
+
+## environment for make-kpkg
+#export INITRD=Yes
+#export INITRD_OK=WeKnowWhatWeAreDoing
+
+#stamp-configure-prepare:
+#	-$(MAKE) -s -C config default > $(KSOURCE)/.config
+
+## copy build infrastructure for kernel modules
+#	cd $(KFLAVOUR); find scripts -type f ! -name '*.o' | cpio -pd $(KSRC)
+#	cat debian/build-files | ( cd $(KFLAVOUR); cpio -pd $(KSRC) )
+
+#install-clean:
+#	for file in debian/*.m4; do rm -f $${file%.m4}; done
+#	for dir in debian/kernel-*; do if test -d $$dir; then rm -rf $$dir; fi; done
+#	rm -f stamp-install-*
+
+#############################################################
+
+# Local Variables:
+# mode:Makefile
+# End:


Property changes on: trunk/kernel/mips/kernel-patch-2.6.10-mips-2.6.10/debian/rules
___________________________________________________________________
Name: svn:executable
   + *




More information about the Kernel-svn-changes mailing list