[kernel] r16408 - in dists/sid/linux-2.6/debian: . config/m68k patches/bugfix/m68k/fp patches/series

Stephen Marenka smarenka at alioth.debian.org
Thu Oct 7 02:04:52 UTC 2010


Author: smarenka
Date: Thu Oct  7 02:04:46 2010
New Revision: 16408

Log:
m68k: add missing linux-m68k patches. Build in rtc class on atari.

Added:
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0001-m68k-Atari-ARAnyM-support.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0002-m68k-Export-ARAnyM-native-feature-API.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0003-m68k-Add-support-for-ARAnyM-block-and-console-acces.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0004-m68k-ARAnyM-early_param-does-not-exist-in-the-mod.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0005-m68k-Wrap-nfblock-natfeat-calls.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0006-m68k-Atari-EtherNAT-SMC91C111-driver.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0007-m68k-Atari-EtherNAT-updates.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0008-m68k-Atari-EtherNAT-warning-fixes.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0009-m68k-section-mismatch-fixes-EtherNAT.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0010-m68k-Atari-ROM-port-ISA-adapter-support.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0011-m68k-Atari-io.h-fixes-for-EtherNAT-driver.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0012-m68k-Atari-EtherNEC-driver.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0013-atari-ethernec-fixes.diff.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0014-m68k-Atari-SCC-serial-driver-needs-atari_SCC_init_d.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0015-m68k-Atari-SCC-serial-driver-needs-CONFIG_ATARI_SCC.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0016-m68k-Atari-SCC-serial-driver.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0017-m68k-Atari-SCC-serial-driver-checkpatch-cleanups.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0018-m68k-Atari-SCC-serial-driver-gs-update.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0019-m68k-Atari-SCC-serial-driver-break_ctl-update.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0020-m68k-Disable-Atari-serial-console-support-if-modula.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0021-m68k-Atari-SCC-support-for-ST.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0022-m68k-atari_scc-kill-warn_unused_result-warnings.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0023-m68k-atari_scc-kill-fake-config-variables.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0024-Revert-msdos-fs-remove-unsettable-atari-option.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0025-Atari-FAT-updates.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0026-Add-Amiga-Zorro-bus-modalias-support.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0027-m68k-Fix-debug-mem-on-Amiga.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0028-m68k-allow-all-kernel-traps-to-be-handled-via-except.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0029-m68k-Add-support-for-EARLY_PRINTK-on-MVME16x.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0030-Update-for-m68k-Add-support-for-EARLY_PRINTK-on-MVM.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0031-m68k-atari_scc-Upstream-updates.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0032-m68k-atari-Rename-mfp-to-st_mfp.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0033-atari-Use-the-correct-mouse-interrupt-hook.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0034-m68k-Fix-atarimouse-init.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0035-ADB-raw-packets.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0036-m68k-Update-defconfigs-for-new-m68k-features.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0037-arch-m68k-emu-nfeth.c-doesn-t-need-obsolete-net-iee.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0038-m68k-z2ram-correct-printing-of-sector_t.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0039-m68k-Atari-SCC-verbosity-fix.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0040-m68k-Atari-EtherNAT-replace-bus_id-with-dev_name.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0041-m68k-Atari-EtherNAT-use-struct-net_device_ops.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0042-m68k-Hydra-Ethernet-correct-printing-of-resource_.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0043-scsi-Clean-up-mvme147.c.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0044-zorro-use-dev_name-instead-of-obsolete-device.bus.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0045-m68k-Atari-GEMDOS-FAT-option-fix-use-correct-logic.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0046-M68k-SERIAL_PORT_DFNS-only-if-CONFIG_ISA.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0047-aranym-Update-for-v2.6.31-block-layer-changes.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0048-aranym-Convert-to-net_device_ops.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0049-ethernec-Convert-to-net_device_ops.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0050-rtc-Add-an-RTC-driver-for-the-Oki-MSM6242.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0051-rtc-Add-an-RTC-driver-for-the-Ricoh-RP5C01.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0052-m68k-use-generic-code-for-ptrace-requests.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0053-m68k-ptrace-fixes.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0054-m68knommu-define-arch_has_single_step-and-friends.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0055-m68k-Make-thread_info.h-usable-from-assembly.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0056-m68k-Cleanup-linker-scripts-using-new-linker-script.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0057-m68k-Remove-the-BKL-from-sys_execve.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0058-fbdev-atafb-add-palette-register-check.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0059-m68k-don-t-export-static-inline-functions.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0060-m68k-parport_mfc3-Not-makes-it-a-bool-before-the.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0061-Keys-KEYCTL_SESSION_TO_PARENT-needs-TIF_NOTIFY_RESU.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0062-m68k-Fix-asm-swab.h-for-ColdFire.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0063-m68k-Add-NPTL-support.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0064-m68knommu-NPTL-support-for-uClinux.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0065-m68k-Allow-ioremapping-top-of-memory.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0066-m68k-nommu-h8300-Remove-obsolete-comment-about-ma.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0067-m68k-vme_scc-__init-annotations.patch
   dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0068-m68k-Use-DIV_ROUND_CLOSEST.patch
Modified:
   dists/sid/linux-2.6/debian/changelog
   dists/sid/linux-2.6/debian/config/m68k/config.atari
   dists/sid/linux-2.6/debian/patches/series/25

Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog	Thu Oct  7 01:58:53 2010	(r16407)
+++ dists/sid/linux-2.6/debian/changelog	Thu Oct  7 02:04:46 2010	(r16408)
@@ -12,6 +12,8 @@
   * m68k: fix missing io macros.
   * m68k: modular swim on mac.
   * m68k: never build staging drivers on m68k.
+  * m68k: add missing linux-m68k patches.
+  * m68k: build in rtc class on atari.
 
   [ Ian Campbell ]
   * xen: do not truncate machine address on gnttab_copy_grant_page hypercall

Modified: dists/sid/linux-2.6/debian/config/m68k/config.atari
==============================================================================
--- dists/sid/linux-2.6/debian/config/m68k/config.atari	Thu Oct  7 01:58:53 2010	(r16407)
+++ dists/sid/linux-2.6/debian/config/m68k/config.atari	Thu Oct  7 02:04:46 2010	(r16408)
@@ -106,7 +106,7 @@
 ##
 ## file: drivers/rtc/Kconfig
 ##
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_CLASS=y
 
 ##
 ## file: drivers/scsi/Kconfig

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0001-m68k-Atari-ARAnyM-support.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0001-m68k-Atari-ARAnyM-support.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,542 @@
+From cee40e323ddcb7c4c908dc31e0e417a7c27086ae Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at opal.biophys.uni-duesseldorf.de>
+Date: Tue, 18 Nov 2008 21:02:18 +0100
+Subject: [PATCH] m68k: Atari ARAnyM support
+
+This isn't really my kettle of fish, but I post it anyway unless Petr
+complains :-)
+
+This is what makes it possible for me to test 2.6 builds on the
+emulator...
+
+Should be signed off by Petr, really.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/Kconfig               |   15 ++
+ arch/m68k/Makefile              |    1 +
+ arch/m68k/emu/Makefile          |    7 +
+ arch/m68k/emu/natfeat.c         |  113 ++++++++++++++++
+ arch/m68k/emu/nfeth.c           |  284 +++++++++++++++++++++++++++++++++++++++
+ arch/m68k/include/asm/natfeat.h |   22 +++
+ arch/m68k/kernel/setup.c        |    5 +
+ 7 files changed, 447 insertions(+), 0 deletions(-)
+ create mode 100644 arch/m68k/emu/Makefile
+ create mode 100644 arch/m68k/emu/natfeat.c
+ create mode 100644 arch/m68k/emu/nfeth.c
+ create mode 100644 arch/m68k/include/asm/natfeat.h
+
+diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
+index ecdc19a..5c371e3 100644
+--- a/arch/m68k/Kconfig
++++ b/arch/m68k/Kconfig
+@@ -250,6 +250,21 @@ config SUN3
+ 
+ 	  If you don't want to compile a kernel exclusively for a Sun 3, say N.
+ 
++config NATFEAT
++	bool "ARAnyM emulator support"
++	depends on ATARI
++	help
++	  This option enables support for ARAnyM native features, such as
++	  access to a disk image as /dev/hda. Useful with the ARANYM option.
++
++config NFETH
++	tristate "NatFeat Ethernet support"
++	depends on NET_ETHERNET && NATFEAT
++	help
++	  Say Y to include support for the ARAnyM NatFeat network device
++	  which will emulate a regular ethernet device while presenting an
++	  ethertap device to the host system.
++
+ comment "Processor type"
+ 
+ config M68020
+diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile
+index 570d85c..d0881b3 100644
+--- a/arch/m68k/Makefile
++++ b/arch/m68k/Makefile
+@@ -76,6 +76,7 @@ core-$(CONFIG_MVME16x)		+= arch/m68k/mvme16x/
+ core-$(CONFIG_BVME6000)		+= arch/m68k/bvme6000/
+ core-$(CONFIG_SUN3X)		+= arch/m68k/sun3x/	arch/m68k/sun3/
+ core-$(CONFIG_SUN3)		+= arch/m68k/sun3/	arch/m68k/sun3/prom/
++core-$(CONFIG_NATFEAT)		+= arch/m68k/emu/
+ core-$(CONFIG_M68040)		+= arch/m68k/fpsp040/
+ core-$(CONFIG_M68060)		+= arch/m68k/ifpsp060/
+ core-$(CONFIG_M68KFPU_EMU)	+= arch/m68k/math-emu/
+diff --git a/arch/m68k/emu/Makefile b/arch/m68k/emu/Makefile
+new file mode 100644
+index 0000000..9fb7219
+--- /dev/null
++++ b/arch/m68k/emu/Makefile
+@@ -0,0 +1,7 @@
++#
++# Makefile for Linux arch/m68k/emu source directory
++#
++
++obj-y			+= natfeat.o
++
++obj-$(CONFIG_NFETH)	+= nfeth.o
+diff --git a/arch/m68k/emu/natfeat.c b/arch/m68k/emu/natfeat.c
+new file mode 100644
+index 0000000..b0eac0c
+--- /dev/null
++++ b/arch/m68k/emu/natfeat.c
+@@ -0,0 +1,113 @@
++/*
++ * natfeat.c - ARAnyM hardware support via Native Features (natfeats)
++ *
++ * Copyright (c) 2005 Petr Stehlik of ARAnyM dev team
++ *
++ * Reworked for Linux by Roman Zippel <zippel at linux-m68k.org>
++ *
++ * This software may be used and distributed according to the terms of
++ * the GNU General Public License (GPL), incorporated herein by reference.
++ */
++
++#include <linux/types.h>
++#include <linux/console.h>
++#include <linux/string.h>
++#include <linux/kernel.h>
++#include <linux/io.h>
++#include <asm/machdep.h>
++#include <asm/natfeat.h>
++
++asm("\n"
++"	.global nf_get_id,nf_call\n"
++"nf_get_id:\n"
++"	.short	0x7300\n"
++"	rts\n"
++"nf_call:\n"
++"	.short	0x7301\n"
++"	rts\n"
++"1:	moveq.l	#0,%d0\n"
++"	rts\n"
++"	.section __ex_table,\"a\"\n"
++"	.long	nf_get_id,1b\n"
++"	.long	nf_call,1b\n"
++"	.previous");
++
++static int stderr_id;
++
++static void nf_write(struct console *co, const char *str, unsigned int count)
++{
++	char buf[68];
++
++	buf[64] = 0;
++	while (count > 64) {
++		memcpy(buf, str, 64);
++		nf_call(stderr_id, buf);
++		str += 64;
++		count -= 64;
++	}
++	memcpy(buf, str, count);
++	buf[count] = 0;
++	nf_call(stderr_id, buf);
++}
++
++void nfprint(const char *fmt, ...)
++{
++	static char buf[256];
++	va_list ap;
++	int n;
++
++	va_start(ap, fmt);
++	n = vsnprintf(buf, 256, fmt, ap);
++	nf_call(nf_get_id("NF_STDERR"), buf);
++	va_end(ap);
++}
++
++static struct console nf_console_driver = {
++	.name	= "debug",
++	.write	= nf_write,
++	.flags	= CON_PRINTBUFFER,
++	.index	= -1,
++};
++
++static int __init nf_debug_setup(char *arg)
++{
++	if (strcmp(arg, "emu"))
++		return 0;
++
++	stderr_id = nf_get_id("NF_STDERR");
++	if (stderr_id)
++		register_console(&nf_console_driver);
++	return 0;
++}
++
++early_param("debug", nf_debug_setup);
++
++static void nf_poweroff(void)
++{
++	long id = nf_get_id("NF_SHUTDOWN");
++
++	if (id)
++		nf_call(id);
++}
++
++void nf_init(void)
++{
++	unsigned long id, version;
++	char buf[256];
++
++	id = nf_get_id("NF_VERSION");
++	if (!id)
++		return;
++	version = nf_call(id);
++
++	id = nf_get_id("NF_NAME");
++	if (!id)
++		return;
++	nf_call(id, buf, 256);
++	buf[255] = 0;
++
++	pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16,
++		version & 0xffff);
++
++	mach_power_off = nf_poweroff;
++}
+diff --git a/arch/m68k/emu/nfeth.c b/arch/m68k/emu/nfeth.c
+new file mode 100644
+index 0000000..de7cdad
+--- /dev/null
++++ b/arch/m68k/emu/nfeth.c
+@@ -0,0 +1,284 @@
++/*
++ * atari_nfeth.c - ARAnyM ethernet card driver for GNU/Linux
++ *
++ * Copyright (c) 2005 Milan Jurik, Petr Stehlik of ARAnyM dev team
++ *
++ * Based on ARAnyM driver for FreeMiNT written by Standa Opichal
++ *
++ * This software may be used and distributed according to the terms of
++ * the GNU General Public License (GPL), incorporated herein by reference.
++ */
++
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/module.h>
++#include <net/ieee80211.h>
++#include <asm/natfeat.h>
++#include <asm/virtconvert.h>
++
++enum {
++	GET_VERSION = 0,	/* no parameters, return NFAPI_VERSION in d0 */
++	XIF_INTLEVEL,		/* no parameters, return Interrupt Level in d0 */
++	XIF_IRQ,		/* acknowledge interrupt from host */
++	XIF_START,		/* (ethX), called on 'ifup', start receiver thread */
++	XIF_STOP,		/* (ethX), called on 'ifdown', stop the thread */
++	XIF_READLENGTH,		/* (ethX), return size of network data block to read */
++	XIF_READBLOCK,		/* (ethX, buffer, size), read block of network data */
++	XIF_WRITEBLOCK,		/* (ethX, buffer, size), write block of network data */
++	XIF_GET_MAC,		/* (ethX, buffer, size), return MAC HW addr in buffer */
++	XIF_GET_IPHOST,		/* (ethX, buffer, size), return IP address of host */
++	XIF_GET_IPATARI,	/* (ethX, buffer, size), return IP address of atari */
++	XIF_GET_NETMASK		/* (ethX, buffer, size), return IP netmask */
++};
++
++#define DRV_NAME	"nfeth"
++#define DRV_VERSION	"0.3"
++#define DRV_RELDATE	"10/12/2005"
++
++#define MAX_UNIT	8
++
++/* These identify the driver base version and may not be removed. */
++static char version[] __devinitdata =
++KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " S.Opichal, M.Jurik, P.Stehlik\n"
++KERN_INFO "  http://aranym.atari.org/\n";
++
++MODULE_AUTHOR("Milan Jurik");
++MODULE_DESCRIPTION("Atari NFeth driver");
++MODULE_LICENSE("GPL");
++/*
++MODULE_PARM(nfeth_debug, "i");
++MODULE_PARM_DESC(nfeth_debug, "nfeth_debug level (1-2)");
++*/
++
++
++static long nfEtherID;
++static int nfEtherIRQ;
++
++struct nfeth_private {
++	int ethX;
++	struct net_device_stats	stats;
++};
++
++static struct net_device *nfeth_dev[MAX_UNIT];
++
++int nfeth_open(struct net_device *dev);
++int nfeth_stop(struct net_device *dev);
++irqreturn_t nfeth_interrupt(int irq, void *dev_id);
++int nfeth_xmit(struct sk_buff *skb, struct net_device *dev);
++
++int nfeth_open(struct net_device *dev)
++{
++	struct nfeth_private *priv = netdev_priv(dev);
++	int res;
++
++	res = nf_call(nfEtherID + XIF_START, priv->ethX);
++
++	/* Clean statistics */
++	memset(&priv->stats, 0, sizeof(struct net_device_stats));
++
++	pr_debug(DRV_NAME ": open %d\n", res);
++
++	/* Ready for data */
++	netif_start_queue(dev);
++
++	return 0;
++}
++
++int nfeth_stop(struct net_device *dev)
++{
++	struct nfeth_private *priv = netdev_priv(dev);
++
++	/* No more data */
++	netif_stop_queue(dev);
++
++	nf_call(nfEtherID + XIF_STOP, priv->ethX);
++
++	return 0;
++}
++
++/*
++ * Read a packet out of the adapter and pass it to the upper layers
++ */
++static inline void recv_packet(struct net_device *dev)
++{
++	struct nfeth_private *priv = netdev_priv(dev);
++	int handled = 0;
++	unsigned short pktlen;
++	struct sk_buff *skb;
++
++	/* read packet length (excluding 32 bit crc) */
++	pktlen = nf_call(nfEtherID + XIF_READLENGTH, priv->ethX);
++
++	pr_debug(DRV_NAME ": recv_packet: %i\n", pktlen);
++
++	if (!pktlen) {
++		pr_debug(DRV_NAME ": recv_packet: pktlen == 0\n");
++		priv->stats.rx_errors++;
++		return;
++	}
++
++	skb = dev_alloc_skb(pktlen + 2);
++	if (!skb) {
++		pr_debug(DRV_NAME
++			 ": recv_packet: out of mem (buf_alloc failed)\n");
++		priv->stats.rx_dropped++;
++		return;
++	}
++
++	skb->dev = dev;
++	skb_reserve(skb, 2);		/* 16 Byte align  */
++	skb_put(skb, pktlen);		/* make room */
++	nf_call(nfEtherID + XIF_READBLOCK, priv->ethX, virt_to_phys(skb->data),
++		pktlen);
++
++	skb->protocol = eth_type_trans(skb, dev);
++	netif_rx(skb);
++	dev->last_rx = jiffies;
++	priv->stats.rx_packets++;
++	priv->stats.rx_bytes += pktlen;
++
++	/* and enqueue packet */
++	handled = 1;
++	return;
++}
++
++irqreturn_t nfeth_interrupt(int irq, void *dev_id)
++{
++	int i, m, mask;
++
++	mask = nf_call(nfEtherID + XIF_IRQ, 0);
++	for (i = 0, m = 1; i < MAX_UNIT; m <<= 1, i++) {
++		if (mask & m && nfeth_dev[i]) {
++			recv_packet(nfeth_dev[i]);
++			nf_call(nfEtherID + XIF_IRQ, m);
++		}
++	}
++	return IRQ_HANDLED;
++}
++
++int nfeth_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++	int len;
++	char *data, shortpkt[ETH_ZLEN];
++	struct nfeth_private *priv = netdev_priv(dev);
++
++	data = skb->data;
++	len = skb->len;
++	if (len < ETH_ZLEN) {
++		memset(shortpkt, 0, ETH_ZLEN);
++		memcpy(shortpkt, data, len);
++		data = shortpkt;
++		len = ETH_ZLEN;
++	}
++
++	dev->trans_start = jiffies;
++
++	pr_debug(DRV_NAME ": send %d bytes\n", len);
++	nf_call(nfEtherID + XIF_WRITEBLOCK, priv->ethX, virt_to_phys(data),
++		len);
++
++	priv->stats.tx_packets++;
++	priv->stats.tx_bytes += len;
++
++	dev_kfree_skb(skb);
++	return 0;
++}
++
++static void nfeth_tx_timeout(struct net_device *dev)
++{
++	struct nfeth_private *priv = netdev_priv(dev);
++	priv->stats.tx_errors++;
++	netif_wake_queue(dev);
++}
++
++static struct net_device_stats *nfeth_get_stats(struct net_device *dev)
++{
++	struct nfeth_private *priv = netdev_priv(dev);
++	return &priv->stats;
++}
++
++struct net_device * __init nfeth_probe(int unit)
++{
++	struct net_device *dev;
++	struct nfeth_private *priv;
++	char mac[ETH_ALEN], host_ip[32], local_ip[32];
++	DECLARE_MAC_BUF(macfmt);
++	int err;
++
++	if (!nf_call(nfEtherID + XIF_GET_MAC, unit, mac, ETH_ALEN))
++		return NULL;
++
++	dev = alloc_etherdev(sizeof(struct nfeth_private));
++	if (!dev)
++		return NULL;
++
++	dev->irq = nfEtherIRQ;
++	dev->open = nfeth_open;
++	dev->stop = nfeth_stop;
++	dev->hard_start_xmit = nfeth_xmit;
++	dev->tx_timeout = nfeth_tx_timeout;
++	dev->get_stats = nfeth_get_stats;
++	dev->flags |= NETIF_F_NO_CSUM;
++	memcpy(dev->dev_addr, mac, ETH_ALEN);
++
++	priv = netdev_priv(dev);
++	priv->ethX = unit;
++
++	err = register_netdev(dev);
++	if (err) {
++		free_netdev(dev);
++		return NULL;
++	}
++
++	nf_call(nfEtherID + XIF_GET_IPHOST, unit,
++		host_ip, sizeof(host_ip));
++	nf_call(nfEtherID + XIF_GET_IPATARI, unit,
++		local_ip, sizeof(local_ip));
++
++	pr_info("%s: nfeth addr:%s (%s) HWaddr:%s\n", dev->name, host_ip,
++		local_ip, print_mac(macfmt, mac));
++
++	return dev;
++}
++
++int __init nfeth_init(void)
++{
++	long ver;
++	int i;
++
++	nfEtherID = nf_get_id("ETHERNET");
++	if (!nfEtherID)
++		return -ENODEV;
++
++	ver = nf_call(nfEtherID + GET_VERSION);
++	pr_info("nfeth API %lu\n", ver);
++
++	nfEtherIRQ = nf_call(nfEtherID + XIF_INTLEVEL);
++	if (request_irq(nfEtherIRQ, nfeth_interrupt, IRQF_SHARED,
++			"eth emu", nfeth_interrupt)) {
++		printk(KERN_ERR "nfeth: request for irq %d failed",
++		       nfEtherIRQ);
++		return -ENODEV;
++	}
++
++	for (i = 0; i < MAX_UNIT; i++)
++		nfeth_dev[i] = nfeth_probe(i);
++
++	return 0;
++}
++
++void __exit nfeth_cleanup(void)
++{
++	int i;
++
++	for (i = 0; i < MAX_UNIT; i++) {
++		if (nfeth_dev[i]) {
++			unregister_netdev(nfeth_dev[0]);
++			free_netdev(nfeth_dev[0]);
++		}
++	}
++	free_irq(nfEtherIRQ, nfeth_interrupt);
++}
++
++module_init(nfeth_init);
++module_exit(nfeth_cleanup);
+diff --git a/arch/m68k/include/asm/natfeat.h b/arch/m68k/include/asm/natfeat.h
+new file mode 100644
+index 0000000..a3521b8
+--- /dev/null
++++ b/arch/m68k/include/asm/natfeat.h
+@@ -0,0 +1,22 @@
++/*
++ * ARAnyM hardware support via Native Features (natfeats)
++ *
++ * Copyright (c) 2005 Petr Stehlik of ARAnyM dev team
++ *
++ * This software may be used and distributed according to the terms of
++ * the GNU General Public License (GPL), incorporated herein by reference.
++ */
++
++#ifndef _NATFEAT_H
++#define _NATFEAT_H
++
++long nf_get_id(const char *feature_name);
++long nf_call(long id, ...);
++
++void nf_init(void);
++void nf_shutdown(void);
++
++void nfprint(const char *fmt, ...)
++	__attribute__ ((format (printf, 1, 2)));
++
++# endif /* _NATFEAT_H */
+diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
+index 303730a..17b2b62 100644
+--- a/arch/m68k/kernel/setup.c
++++ b/arch/m68k/kernel/setup.c
+@@ -42,6 +42,7 @@
+ #ifdef CONFIG_SUN3X
+ #include <asm/dvma.h>
+ #endif
++#include <asm/natfeat.h>
+ 
+ #if !FPSTATESIZE || !NR_IRQS
+ #warning No CPU/platform type selected, your kernel will not work!
+@@ -324,6 +325,10 @@ void __init setup_arch(char **cmdline_p)
+ 		panic("No configuration setup");
+ 	}
+ 
++#ifdef CONFIG_NATFEAT
++	nf_init();
++#endif
++
+ 	paging_init();
+ 
+ #ifndef CONFIG_SUN3
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0002-m68k-Export-ARAnyM-native-feature-API.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0002-m68k-Export-ARAnyM-native-feature-API.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,41 @@
+From b13bde61271f2baa06caa0c2712d8a86076c4fea Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 21:02:19 +0100
+Subject: [PATCH] m68k: Export ARAnyM native feature API
+
+ERROR: "nf_get_id" [arch/m68k/emu/nfeth.ko] undefined!
+ERROR: "nf_call" [arch/m68k/emu/nfeth.ko] undefined!
+ERROR: "nf_get_id" [arch/m68k/emu/nfcon.ko] undefined!
+ERROR: "nf_call" [arch/m68k/emu/nfcon.ko] undefined!
+ERROR: "nf_call" [arch/m68k/emu/nfblock.ko] undefined!
+ERROR: "nf_get_id" [arch/m68k/emu/nfblock.ko] undefined!
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/emu/natfeat.c |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/arch/m68k/emu/natfeat.c b/arch/m68k/emu/natfeat.c
+index b0eac0c..987d773 100644
+--- a/arch/m68k/emu/natfeat.c
++++ b/arch/m68k/emu/natfeat.c
+@@ -13,6 +13,7 @@
+ #include <linux/console.h>
+ #include <linux/string.h>
+ #include <linux/kernel.h>
++#include <linux/module.h>
+ #include <linux/io.h>
+ #include <asm/machdep.h>
+ #include <asm/natfeat.h>
+@@ -31,6 +32,8 @@ asm("\n"
+ "	.long	nf_get_id,1b\n"
+ "	.long	nf_call,1b\n"
+ "	.previous");
++EXPORT_SYMBOL_GPL(nf_get_id);
++EXPORT_SYMBOL_GPL(nf_call);
+ 
+ static int stderr_id;
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0003-m68k-Add-support-for-ARAnyM-block-and-console-acces.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0003-m68k-Add-support-for-ARAnyM-block-and-console-acces.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,471 @@
+From 5ea21a7661054480d64825f37d826e6613ddecb1 Mon Sep 17 00:00:00 2001
+From: Roman Zippel <zippel at linux-m68k.org>
+Date: Tue, 18 Nov 2008 21:02:19 +0100
+Subject: [PATCH] m68k: Add support for ARAnyM block and console access
+
+Add support for ARAnyM block and console access
+
+Signed-off-by: Roman Zippel <zippel at linux-m68k.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/Kconfig       |   16 ++++
+ arch/m68k/emu/Makefile  |    2 +
+ arch/m68k/emu/natfeat.c |   38 ----------
+ arch/m68k/emu/nfblock.c |  180 +++++++++++++++++++++++++++++++++++++++++++++++
+ arch/m68k/emu/nfcon.c   |  164 ++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 362 insertions(+), 38 deletions(-)
+ create mode 100644 arch/m68k/emu/nfblock.c
+ create mode 100644 arch/m68k/emu/nfcon.c
+
+diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
+index 5c371e3..3073675 100644
+--- a/arch/m68k/Kconfig
++++ b/arch/m68k/Kconfig
+@@ -265,6 +265,22 @@ config NFETH
+ 	  which will emulate a regular ethernet device while presenting an
+ 	  ethertap device to the host system.
+ 
++config NFBLOCK
++	tristate "NatFeat block device support"
++	depends on BLOCK && NATFEAT
++	help
++	  Say Y to include support for the ARAnyM NatFeat block device
++	  which allows direct access to the hard drives without using
++	  the hardware emulation.
++
++config NFCON
++	tristate "NatFeat console driver"
++	depends on NATFEAT
++	help
++	  Say Y to include support for the ARAnyM NatFeat console driver
++	  which allows the console output to be redirected to the stderr
++	  output of ARAnyM.
++
+ comment "Processor type"
+ 
+ config M68020
+diff --git a/arch/m68k/emu/Makefile b/arch/m68k/emu/Makefile
+index 9fb7219..34f9a4d 100644
+--- a/arch/m68k/emu/Makefile
++++ b/arch/m68k/emu/Makefile
+@@ -5,3 +5,5 @@
+ obj-y			+= natfeat.o
+ 
+ obj-$(CONFIG_NFETH)	+= nfeth.o
++obj-$(CONFIG_NFBLOCK)	+= nfblock.o
++obj-$(CONFIG_NFCON)	+= nfcon.o
+diff --git a/arch/m68k/emu/natfeat.c b/arch/m68k/emu/natfeat.c
+index 987d773..2291a7d 100644
+--- a/arch/m68k/emu/natfeat.c
++++ b/arch/m68k/emu/natfeat.c
+@@ -35,24 +35,6 @@ asm("\n"
+ EXPORT_SYMBOL_GPL(nf_get_id);
+ EXPORT_SYMBOL_GPL(nf_call);
+ 
+-static int stderr_id;
+-
+-static void nf_write(struct console *co, const char *str, unsigned int count)
+-{
+-	char buf[68];
+-
+-	buf[64] = 0;
+-	while (count > 64) {
+-		memcpy(buf, str, 64);
+-		nf_call(stderr_id, buf);
+-		str += 64;
+-		count -= 64;
+-	}
+-	memcpy(buf, str, count);
+-	buf[count] = 0;
+-	nf_call(stderr_id, buf);
+-}
+-
+ void nfprint(const char *fmt, ...)
+ {
+ 	static char buf[256];
+@@ -65,26 +47,6 @@ void nfprint(const char *fmt, ...)
+ 	va_end(ap);
+ }
+ 
+-static struct console nf_console_driver = {
+-	.name	= "debug",
+-	.write	= nf_write,
+-	.flags	= CON_PRINTBUFFER,
+-	.index	= -1,
+-};
+-
+-static int __init nf_debug_setup(char *arg)
+-{
+-	if (strcmp(arg, "emu"))
+-		return 0;
+-
+-	stderr_id = nf_get_id("NF_STDERR");
+-	if (stderr_id)
+-		register_console(&nf_console_driver);
+-	return 0;
+-}
+-
+-early_param("debug", nf_debug_setup);
+-
+ static void nf_poweroff(void)
+ {
+ 	long id = nf_get_id("NF_SHUTDOWN");
+diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
+new file mode 100644
+index 0000000..3d987c7
+--- /dev/null
++++ b/arch/m68k/emu/nfblock.c
+@@ -0,0 +1,180 @@
++/*
++ * ARAnyM block device driver
++ *
++ * 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/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++
++#include <linux/kernel.h>
++#include <linux/errno.h>
++#include <linux/types.h>
++#include <linux/genhd.h>
++#include <linux/blkdev.h>
++#include <linux/hdreg.h>
++
++#include <asm/natfeat.h>
++
++static long nfhd_id;
++
++enum {
++	/* emulation entry points */
++	NFHD_READ_WRITE = 10,
++	NFHD_GET_CAPACITY = 14,
++
++	/* skip ACSI devices */
++	NFHD_DEV_OFFSET = 8,
++};
++
++static LIST_HEAD(nfhd_list);
++
++static int major_num;
++module_param(major_num, int, 0);
++
++struct nfhd_device {
++	struct list_head list;
++	int id;
++	u32 blocks, bsize;
++	int bshift;
++	struct request_queue *queue;
++	struct gendisk *disk;
++};
++
++static int nfhd_make_request(struct request_queue *queue, struct bio *bio)
++{
++	struct nfhd_device *dev = queue->queuedata;
++	struct bio_vec *bvec;
++	int i, dir, len, shift;
++	sector_t sec = bio->bi_sector;
++
++	dir = bio_data_dir(bio);
++	shift = dev->bshift;
++	bio_for_each_segment(bvec, bio, i) {
++		len = bvec->bv_len;
++		len >>= 9;
++		nf_call(nfhd_id + NFHD_READ_WRITE, dev->id, 0, dir,
++			sec >> shift, len >> shift, bvec_to_phys(bvec));
++		sec += len;
++	}
++	bio_endio(bio, 0);
++	return 0;
++}
++
++int nfhd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
++{
++	struct nfhd_device *dev = bdev->bd_disk->private_data;
++
++	geo->cylinders = dev->blocks >> (6 - dev->bshift);
++	geo->heads = 4;
++	geo->sectors = 16;
++
++	return 0;
++}
++
++static struct block_device_operations nfhd_ops = {
++	.owner	= THIS_MODULE,
++	.getgeo	= nfhd_getgeo,
++};
++
++static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
++{
++	struct nfhd_device *dev;
++	int dev_id = id - NFHD_DEV_OFFSET;
++
++	printk(KERN_INFO "nfhd%u: found device with %u blocks (%u bytes)\n",
++		dev_id, blocks, bsize);
++
++	if (bsize < 512 || (bsize & (bsize - 1))) {
++		printk(KERN_WARNING "nfhd%u: invalid block size\n", dev_id);
++		return -EINVAL;
++	}
++
++	dev = kmalloc(sizeof(struct nfhd_device), GFP_KERNEL);
++	if (!dev)
++		goto out;
++
++	dev->id = id;
++	dev->blocks = blocks;
++	dev->bsize = bsize;
++	dev->bshift = ffs(bsize) - 10;
++
++	dev->queue = blk_alloc_queue(GFP_KERNEL);
++	if (dev->queue == NULL)
++		goto free_dev;
++
++	dev->queue->queuedata = dev;
++	blk_queue_make_request(dev->queue, nfhd_make_request);
++	blk_queue_hardsect_size(dev->queue, bsize);
++
++	dev->disk = alloc_disk(16);
++	if (!dev->disk)
++		goto free_queue;
++
++	dev->disk->major = major_num;
++	dev->disk->first_minor = dev_id * 16;
++	dev->disk->fops = &nfhd_ops;
++	dev->disk->private_data = dev;
++	sprintf(dev->disk->disk_name, "nfhd%u", dev_id);
++	set_capacity(dev->disk, (sector_t)blocks * (bsize / 512));
++	dev->disk->queue = dev->queue;
++
++	add_disk(dev->disk);
++
++	list_add_tail(&dev->list, &nfhd_list);
++
++	return 0;
++
++free_queue:
++	blk_cleanup_queue(dev->queue);
++free_dev:
++	kfree(dev);
++out:
++	return -ENOMEM;
++}
++
++static int __init nfhd_init(void)
++{
++	u32 blocks, bsize;
++	int i;
++
++	nfhd_id = nf_get_id("XHDI");
++	if (!nfhd_id)
++		return -ENODEV;
++
++	major_num = register_blkdev(major_num, "nfhd");
++	if (major_num <= 0) {
++		printk(KERN_WARNING "nfhd: unable to get major number\n");
++		return -ENODEV;
++	}
++
++	for (i = NFHD_DEV_OFFSET; i < 24; i++) {
++		if (nf_call(nfhd_id + NFHD_GET_CAPACITY, i, 0, &blocks, &bsize))
++			continue;
++		nfhd_init_one(i, blocks, bsize);
++	}
++
++	return 0;
++}
++
++static void __exit nfhd_exit(void)
++{
++	struct nfhd_device *dev, *next;
++
++	list_for_each_entry_safe(dev, next, &nfhd_list, list) {
++		list_del(&dev->list);
++		del_gendisk(dev->disk);
++		put_disk(dev->disk);
++		blk_cleanup_queue(dev->queue);
++		kfree(dev);
++	}
++	unregister_blkdev(major_num, "nfhd");
++}
++
++module_init(nfhd_init);
++module_exit(nfhd_exit);
++
++MODULE_LICENSE("GPL");
+diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c
+new file mode 100644
+index 0000000..91984fe
+--- /dev/null
++++ b/arch/m68k/emu/nfcon.c
+@@ -0,0 +1,164 @@
++/*
++ * ARAnyM console driver
++ *
++ * 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/module.h>
++#include <linux/init.h>
++#include <linux/console.h>
++#include <linux/tty.h>
++#include <linux/tty_driver.h>
++#include <linux/tty_flip.h>
++#include <linux/slab.h>
++#include <linux/err.h>
++#include <linux/uaccess.h>
++
++#include <asm/natfeat.h>
++
++static int stderr_id;
++static struct tty_driver *nfcon_tty_driver;
++
++static void nfcon_write(struct console *con, const char *str, unsigned int count)
++{
++	char buf[68];
++
++	buf[64] = 0;
++	while (count > 64) {
++		memcpy(buf, str, 64);
++		nf_call(stderr_id, buf);
++		str += 64;
++		count -= 64;
++	}
++	memcpy(buf, str, count);
++	buf[count] = 0;
++	nf_call(stderr_id, buf);
++}
++
++struct tty_driver *nfcon_device(struct console *con, int *index)
++{
++	*index = 0;
++	return (con->flags & CON_ENABLED) ? nfcon_tty_driver : NULL;
++}
++
++static struct console nf_console = {
++	.name	= "nfcon",
++	.write	= nfcon_write,
++	.device	= nfcon_device,
++	.flags	= CON_PRINTBUFFER,
++	.index	= -1,
++};
++
++
++static int nfcon_tty_open(struct tty_struct *tty, struct file *filp)
++{
++	return 0;
++}
++
++static void nfcon_tty_close(struct tty_struct *tty, struct file *filp)
++{
++}
++
++static int nfcon_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
++{
++	char temp[68];
++	int i = count;
++
++	temp[64] = 0;
++	while (i > 64) {
++		memcpy(temp, buf, 64);
++		nf_call(stderr_id, temp);
++		buf += 64;
++		i -= 64;
++	}
++	memcpy(temp, buf, i);
++	temp[i] = 0;
++	nf_call(stderr_id, temp);
++
++	return count;
++}
++
++static int nfcon_tty_put_char(struct tty_struct *tty, unsigned char ch)
++{
++	char temp[2] = { ch, 0 };
++
++	nf_call(stderr_id, temp);
++	return 1;
++}
++
++static int nfcon_tty_write_room(struct tty_struct *tty)
++{
++	return 64;
++}
++
++static const struct tty_operations nfcon_tty_ops = {
++	.open		= nfcon_tty_open,
++	.close		= nfcon_tty_close,
++	.write		= nfcon_tty_write,
++	.put_char	= nfcon_tty_put_char,
++	.write_room	= nfcon_tty_write_room,
++};
++
++static int __init nf_debug_setup(char *arg)
++{
++	if (strcmp(arg, "nfcon"))
++		return 0;
++
++	stderr_id = nf_get_id("NF_STDERR");
++	if (stderr_id) {
++		nf_console.flags |= CON_ENABLED;
++		register_console(&nf_console);
++	}
++
++	return 0;
++}
++
++early_param("debug", nf_debug_setup);
++
++static int __init nfcon_init(void)
++{
++	int res;
++
++	stderr_id = nf_get_id("NF_STDERR");
++	if (!stderr_id)
++		return -ENODEV;
++
++	nfcon_tty_driver = alloc_tty_driver(1);
++	if (!nfcon_tty_driver)
++		return -ENOMEM;
++
++	nfcon_tty_driver->owner = THIS_MODULE;
++	nfcon_tty_driver->driver_name = "nfcon";
++	nfcon_tty_driver->name = "nfcon";
++	nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
++	nfcon_tty_driver->subtype = SYSTEM_TYPE_TTY;
++	nfcon_tty_driver->init_termios = tty_std_termios;
++	nfcon_tty_driver->flags = TTY_DRIVER_REAL_RAW;
++
++	tty_set_operations(nfcon_tty_driver, &nfcon_tty_ops);
++	res = tty_register_driver(nfcon_tty_driver);
++	if (res) {
++		printk(KERN_ERR "failed to register nfcon tty driver\n");
++		put_tty_driver(nfcon_tty_driver);
++		return res;
++	}
++
++	if (!(nf_console.flags & CON_ENABLED))
++		register_console(&nf_console);
++
++	return 0;
++}
++
++static void __exit nfcon_exit(void)
++{
++	unregister_console(&nf_console);
++	tty_unregister_driver(nfcon_tty_driver);
++	put_tty_driver(nfcon_tty_driver);
++}
++
++module_init(nfcon_init);
++module_exit(nfcon_exit);
++
++MODULE_LICENSE("GPL");
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0004-m68k-ARAnyM-early_param-does-not-exist-in-the-mod.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0004-m68k-ARAnyM-early_param-does-not-exist-in-the-mod.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,37 @@
+From 7b123998cd2b822d41e5e758f2523641c85aa39e Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 21:02:20 +0100
+Subject: [PATCH] m68k/ARAnyM: early_param() does not exist in the modular case
+
+early_param() does not exist in the modular case
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/emu/nfcon.c |    4 ++++
+ 1 files changed, 4 insertions(+), 0 deletions(-)
+
+diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c
+index 91984fe..f82af58 100644
+--- a/arch/m68k/emu/nfcon.c
++++ b/arch/m68k/emu/nfcon.c
+@@ -101,6 +101,8 @@ static const struct tty_operations nfcon_tty_ops = {
+ 	.write_room	= nfcon_tty_write_room,
+ };
+ 
++#ifndef MODULE
++
+ static int __init nf_debug_setup(char *arg)
+ {
+ 	if (strcmp(arg, "nfcon"))
+@@ -117,6 +119,8 @@ static int __init nf_debug_setup(char *arg)
+ 
+ early_param("debug", nf_debug_setup);
+ 
++#endif /* !MODULE */
++
+ static int __init nfcon_init(void)
+ {
+ 	int res;
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0005-m68k-Wrap-nfblock-natfeat-calls.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0005-m68k-Wrap-nfblock-natfeat-calls.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,63 @@
+From 192413a02eb1e798e53c3d8bf94f782dd62539d1 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 21:02:20 +0100
+Subject: [PATCH] m68k: Wrap nfblock natfeat calls
+
+Add wrappers with proper prototypes for the natfeat calls in nfblock.
+This fixes the problem where sector_t was pushed on the stack as a 64-bit value
+if CONFIG_LBD=y, while all parameters of the nf_call() varargs function are
+32-bit.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/emu/nfblock.c |   20 +++++++++++++++++---
+ 1 files changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
+index 3d987c7..c131121 100644
+--- a/arch/m68k/emu/nfblock.c
++++ b/arch/m68k/emu/nfblock.c
+@@ -30,6 +30,20 @@ enum {
+ 	NFHD_DEV_OFFSET = 8,
+ };
+ 
++static inline s32 nfhd_read_write(u32 major, u32 minor, u32 rwflag, u32 recno,
++				  u32 count, u32 buf)
++{
++	return nf_call(nfhd_id + NFHD_READ_WRITE, major, minor, rwflag, recno,
++		       count, buf);
++}
++
++static inline s32 nfhd_get_capacity(u32 major, u32 minor, u32 *blocks,
++				    u32 *blocksize)
++{
++	return nf_call(nfhd_id + NFHD_GET_CAPACITY, major, minor, blocks,
++		       blocksize);
++}
++
+ static LIST_HEAD(nfhd_list);
+ 
+ static int major_num;
+@@ -56,8 +70,8 @@ static int nfhd_make_request(struct request_queue *queue, struct bio *bio)
+ 	bio_for_each_segment(bvec, bio, i) {
+ 		len = bvec->bv_len;
+ 		len >>= 9;
+-		nf_call(nfhd_id + NFHD_READ_WRITE, dev->id, 0, dir,
+-			sec >> shift, len >> shift, bvec_to_phys(bvec));
++		nfhd_read_write(dev->id, 0, dir, sec >> shift, len >> shift,
++				bvec_to_phys(bvec));
+ 		sec += len;
+ 	}
+ 	bio_endio(bio, 0);
+@@ -152,7 +166,7 @@ static int __init nfhd_init(void)
+ 	}
+ 
+ 	for (i = NFHD_DEV_OFFSET; i < 24; i++) {
+-		if (nf_call(nfhd_id + NFHD_GET_CAPACITY, i, 0, &blocks, &bsize))
++		if (nfhd_get_capacity(i, 0, &blocks, &bsize))
+ 			continue;
+ 		nfhd_init_one(i, blocks, bsize);
+ 	}
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0006-m68k-Atari-EtherNAT-SMC91C111-driver.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0006-m68k-Atari-EtherNAT-SMC91C111-driver.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,2665 @@
+From b1e1902e9c1ddbd559e6807951acc13132d92136 Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at opal.biophys.uni-duesseldorf.de>
+Date: Tue, 18 Nov 2008 21:07:39 +0100
+Subject: [PATCH] m68k: Atari EtherNAT (SMC91C111) driver
+
+SMC91C111 driver aka EtherNAT driver for the Atari Falcon
+
+Signed-off-by: Michael Schmitz <schmitz at biophys.uni-duesseldorf.de>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+
+FIXME checkpatch
+---
+ arch/m68k/atari/config.c   |   41 +
+ drivers/net/Kconfig        |   10 +
+ drivers/net/Makefile       |    1 +
+ drivers/net/atari_91C111.c | 2548 ++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 2600 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/net/atari_91C111.c
+
+diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
+index ae2d96e..055a5bc 100644
+--- a/arch/m68k/atari/config.c
++++ b/arch/m68k/atari/config.c
+@@ -31,6 +31,7 @@
+ #include <linux/init.h>
+ #include <linux/delay.h>
+ #include <linux/ioport.h>
++#include <linux/platform_device.h>
+ #include <linux/vt_kern.h>
+ #include <linux/module.h>
+ 
+@@ -656,3 +657,43 @@ static void atari_get_hardware_list(struct seq_file *m)
+ 	ATARIHW_ANNOUNCE(VME, "VME Bus");
+ 	ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor");
+ }
++
++/*
++ * MSch: initial platform device support for Atari, required for EtherNAT
++ */
++
++#define ATARI_ETHERNAT_PHYS_ADDR	0x80000000
++#define ATARI_ETHERNAT_IRQ		0xc3
++
++static struct resource smc91x_resources[] = {
++	[0] = {
++		.name	= "smc91x-regs",
++		.start	= ATARI_ETHERNAT_PHYS_ADDR,
++		.end	= ATARI_ETHERNAT_PHYS_ADDR + 0xfffff,
++		.flags	= IORESOURCE_MEM,
++	},
++	[1] = {
++		.name	= "smc91x-irq",
++		.start	= ATARI_ETHERNAT_IRQ,
++		.end	= ATARI_ETHERNAT_IRQ,
++		.flags	= IORESOURCE_IRQ,
++	},
++};
++
++static struct platform_device smc91x_device = {
++	.name		= "smc91x",
++	.id		= -1,
++	.num_resources	= ARRAY_SIZE(smc91x_resources),
++	.resource	= smc91x_resources,
++};
++
++static struct platform_device *atari_platform_devices[] __initdata = {
++	&smc91x_device
++};
++
++int __init atari_platform_init(void)
++{
++	return platform_add_devices(atari_platform_devices, ARRAY_SIZE(atari_platform_devices));
++}
++
++arch_initcall(atari_platform_init);
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index b2f71f7..3671552 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -406,6 +406,16 @@ config ATARILANCE
+ 	  on the AMD Lance chipset: RieblCard (with or without battery), or
+ 	  PAMCard VME (also the version by Rhotron, with different addresses).
+ 
++config ATARI_ETHERNAT
++	tristate "Atari EtherNAT Ethernet support"
++	select CRC32
++	select MII
++	depends on NET_ETHERNET && ATARI
++	help
++	  Say Y to include support for the EtherNAT network adapter for the
++	  CT/60 extension port. The driver works by polling instead of
++	  interrupts, so it is quite slow.
++
+ config SUN3LANCE
+ 	tristate "Sun3/Sun3x on-board LANCE support"
+ 	depends on SUN3 || SUN3X
+diff --git a/drivers/net/Makefile b/drivers/net/Makefile
+index 246323d..d550e30 100644
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -219,6 +219,7 @@ obj-$(CONFIG_MIPS_SIM_NET) += mipsnet.o
+ obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
+ obj-$(CONFIG_DECLANCE) += declance.o
+ obj-$(CONFIG_ATARILANCE) += atarilance.o
++obj-$(CONFIG_ATARI_ETHERNAT) += atari_91C111.o
+ obj-$(CONFIG_A2065) += a2065.o
+ obj-$(CONFIG_HYDRA) += hydra.o 8390.o
+ obj-$(CONFIG_ARIADNE) += ariadne.o
+diff --git a/drivers/net/atari_91C111.c b/drivers/net/atari_91C111.c
+new file mode 100644
+index 0000000..9b87d04
+--- /dev/null
++++ b/drivers/net/atari_91C111.c
+@@ -0,0 +1,2548 @@
++/*
++ * smc91x.c
++ * This is a driver for SMSC's 91C9x/91C1xx single-chip Ethernet devices.
++ *
++ * Copyright (C) 1996 by Erik Stahlman
++ * Copyright (C) 2001 Standard Microsystems Corporation
++ *	Developed by Simple Network Magic Corporation
++ * Copyright (C) 2003 Monta Vista Software, Inc.
++ *	Unified SMC91x driver by Nicolas Pitre
++ *
++ * 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
++ *
++ * Arguments:
++ * 	io	= for the base address
++ *	irq	= for the IRQ
++ *	nowait	= 0 for normal wait states, 1 eliminates additional wait states
++ *
++ * original author:
++ * 	Erik Stahlman <erik at vt.edu>
++ *
++ * hardware multicast code:
++ *    Peter Cammaert <pc at denkart.be>
++ *
++ * contributors:
++ * 	Daris A Nevil <dnevil at snmc.com>
++ *      Nicolas Pitre <nico at cam.org>
++ *	Russell King <rmk at arm.linux.org.uk>
++ *
++ * History:
++ *   08/20/00  Arnaldo Melo       fix kfree(skb) in smc_hardware_send_packet
++ *   12/15/00  Christian Jullien  fix "Warning: kfree_skb on hard IRQ"
++ *   03/16/01  Daris A Nevil      modified smc9194.c for use with LAN91C111
++ *   08/22/01  Scott Anderson     merge changes from smc9194 to smc91111
++ *   08/21/01  Pramod B Bhardwaj  added support for RevB of LAN91C111
++ *   12/20/01  Jeff Sutherland    initial port to Xscale PXA with DMA support
++ *   04/07/03  Nicolas Pitre      unified SMC91x driver, killed irq races,
++ *                                more bus abstraction, big cleanup, etc.
++ *   29/09/03  Russell King       - add driver model support
++ *                                - ethtool support
++ *                                - convert to use generic MII interface
++ *                                - add link up/down notification
++ *                                - don't try to handle full negotiation in
++ *                                  smc_phy_configure
++ *                                - clean up (and fix stack overrun) in PHY
++ *                                  MII read/write functions
++ *   22/09/04  Nicolas Pitre      big update (see commit log for details)
++ */
++static const char version[] =
++	"smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico at cam.org>\n";
++
++#define SMC_DEBUG 1
++
++/* Debugging level */
++#ifndef SMC_DEBUG
++#define SMC_DEBUG		0
++#endif
++
++
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/slab.h>
++#include <linux/delay.h>
++#include <linux/interrupt.h>
++#include <linux/errno.h>
++#include <linux/ioport.h>
++#include <linux/crc32.h>
++#include <linux/platform_device.h>
++#include <linux/spinlock.h>
++#include <linux/ethtool.h>
++#include <linux/mii.h>
++#include <linux/workqueue.h>
++
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/skbuff.h>
++
++#include <asm/hwtest.h>
++#include <asm/atariints.h>
++#include <asm/io.h>
++#include <asm/irq.h>
++
++#include "smc91x.h"
++
++#ifdef CONFIG_ISA
++/*
++ * the LAN91C111 can be at any of the following port addresses.  To change,
++ * for a slightly different card, you can add it to the array.  Keep in
++ * mind that the array must end in zero.
++ */
++static unsigned int smc_portlist[] __initdata = {
++	0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
++	0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0
++};
++
++#endif  /* CONFIG_ISA */
++
++#ifndef SMC_IOADDR
++# define SMC_IOADDR		-1
++#endif
++static unsigned long io = SMC_IOADDR;
++module_param(io, ulong, 0400);
++MODULE_PARM_DESC(io, "I/O base address");
++
++#ifndef SMC_IRQ
++# define SMC_IRQ		-1
++#endif
++static int irq = SMC_IRQ;
++module_param(irq, int, 0400);
++MODULE_PARM_DESC(irq, "IRQ number");
++
++
++#ifndef SMC_NOWAIT
++# define SMC_NOWAIT		0
++#endif
++static int nowait = SMC_NOWAIT;
++module_param(nowait, int, 0400);
++MODULE_PARM_DESC(nowait, "set to 1 for no wait state");
++
++/*
++ * Transmit timeout, default 5 seconds.
++ */
++static int watchdog = 1000;
++module_param(watchdog, int, 0400);
++MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
++
++MODULE_LICENSE("GPL");
++MODULE_ALIAS("platform:smc91x");
++
++/*
++ * The internal workings of the driver.  If you are changing anything
++ * here with the SMC stuff, you should have the datasheet and know
++ * what you are doing.
++ */
++#define CARDNAME "smc91x"
++
++/*
++ * Use power-down feature of the chip
++ */
++#define POWER_DOWN		1
++
++/*
++ * Wait time for memory to be free.  This probably shouldn't be
++ * tuned that much, as waiting for this means nothing else happens
++ * in the system
++ */
++#define MEMORY_WAIT_TIME	16
++
++/*
++ * The maximum number of processing loops allowed for each call to the
++ * IRQ handler.
++ */
++#define MAX_IRQ_LOOPS		8
++
++/*
++ * This selects whether TX packets are sent one by one to the SMC91x internal
++ * memory and throttled until transmission completes.  This may prevent
++ * RX overruns a litle by keeping much of the memory free for RX packets
++ * but to the expense of reduced TX throughput and increased IRQ overhead.
++ * Note this is not a cure for a too slow data bus or too high IRQ latency.
++ */
++#define THROTTLE_TX_PKTS	1
++
++/*
++ * The MII clock high/low times.  2x this number gives the MII clock period
++ * in microseconds. (was 50, but this gives 6.4ms for each MII transaction!)
++ */
++#define MII_DELAY		1
++
++#if SMC_DEBUG > 0
++#define DBG(n, args...)					\
++	do {						\
++		if (SMC_DEBUG >= (n))			\
++			printk(args);	\
++	} while (0)
++
++#define PRINTK(args...)   printk(args)
++#else
++#define DBG(n, args...)   do { } while(0)
++#define PRINTK(args...)   printk(KERN_DEBUG args)
++#endif
++
++#if SMC_DEBUG > 3
++static void PRINT_PKT(u_char *buf, int length)
++{
++	int i;
++	int remainder;
++	int lines;
++
++	lines = length / 16;
++	remainder = length % 16;
++
++	for (i = 0; i < lines ; i ++) {
++		int cur;
++		for (cur = 0; cur < 8; cur++) {
++			u_char a, b;
++			a = *buf++;
++			b = *buf++;
++			printk("%02x%02x ", a, b);
++		}
++		printk("\n");
++	}
++	for (i = 0; i < remainder/2 ; i++) {
++		u_char a, b;
++		a = *buf++;
++		b = *buf++;
++		printk("%02x%02x ", a, b);
++	}
++	printk("\n");
++}
++#else
++#define PRINT_PKT(x...)  do { } while(0)
++#endif
++
++
++/* this enables an interrupt in the interrupt mask register */
++#define SMC_ENABLE_INT(lp, x) do {						\
++	unsigned char mask;						\
++	spin_lock_irq(&lp->lock);					\
++	mask = SMC_GET_INT_MASK(lp);					\
++	mask |= (x);							\
++	SMC_SET_INT_MASK(lp, mask);					\
++	spin_unlock_irq(&lp->lock);					\
++} while (0)
++
++/* this disables an interrupt from the interrupt mask register */
++#define SMC_DISABLE_INT(lp, x) do {						\
++	unsigned char mask;						\
++	spin_lock_irq(&lp->lock);					\
++	mask = SMC_GET_INT_MASK(lp);					\
++	mask &= ~(x);							\
++	SMC_SET_INT_MASK(lp, mask);					\
++	spin_unlock_irq(&lp->lock);					\
++} while (0)
++
++/*
++ * Wait while MMU is busy.  This is usually in the order of a few nanosecs
++ * if at all, but let's avoid deadlocking the system if the hardware
++ * decides to go south.
++ */
++#define SMC_WAIT_MMU_BUSY(lp) do {					\
++	if (unlikely(SMC_GET_MMU_CMD(lp) & MC_BUSY)) {			\
++		unsigned long timeout = jiffies + 2;			\
++		while (SMC_GET_MMU_CMD(lp) & MC_BUSY) {			\
++			if (time_after(jiffies, timeout)) {		\
++				printk("%s: timeout %s line %d\n",	\
++					dev->name, __FILE__, __LINE__);	\
++				break;					\
++			}						\
++			cpu_relax();					\
++		}							\
++	}								\
++} while (0)
++
++/*
++ * Timer based operation on Atari
++ */
++static irqreturn_t smc_interrupt(int irq, void *dev_id);
++
++static int use_poll = 0;
++module_param(use_poll, int, 0);
++MODULE_PARM_DESC(use_poll, "Use scheduling timer to poll driver");
++
++/* This is used by cleanup, to prevent the module from being unloaded while
++ * intrpt_routine is still in the task queue
++ */
++static wait_queue_head_t WaitQ;
++
++static struct delayed_work tqueue;
++
++static struct net_device *poll_dev = NULL;
++
++static void atari_ethernat_int(struct work_struct *work)
++{
++	struct net_device *dev  = poll_dev;
++
++        if(!dev) {
++	        /* If cleanup wants us to die */
++                if (waitqueue_active(&WaitQ))
++                  wake_up(&WaitQ);               /* Now cleanup_module can return */
++                else
++                  /* Put ourselves back in the task queue */
++                  schedule_delayed_work(&tqueue, 1);
++		return;
++        }
++
++        /* This actually does not appear to work during probe */
++	if (netif_running(dev)) {
++		smc_interrupt(dev->irq, dev);
++        }
++
++	/* If cleanup wants us to die */
++	if (waitqueue_active(&WaitQ))
++		wake_up(&WaitQ);               /* Now cleanup_module can return */
++	else
++		/* Put ourselves back in the task queue */
++		schedule_delayed_work(&tqueue, 0); /* reduced delay from 1 */
++}
++
++static void atari_ethernat_start_poll(struct net_device *dev)
++{
++	poll_dev = dev;
++
++	init_waitqueue_head(&WaitQ);
++
++	/* MSch: need to insert dev into work struct?? */
++
++	INIT_DELAYED_WORK(&tqueue, atari_ethernat_int);
++	schedule_delayed_work(&tqueue, 1);
++}
++
++static void atari_ethernat_stop_poll(struct net_device *dev)
++{
++	if (dev && (dev == poll_dev)) {
++	        sleep_on(&WaitQ);
++	}
++	poll_dev = NULL;
++}
++
++/*
++ * this does a soft reset on the device
++ */
++static void smc_reset(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	unsigned int ctl, cfg;
++	struct sk_buff *pending_skb;
++
++	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++
++	/* Disable all interrupts, block TX tasklet */
++	spin_lock_irq(&lp->lock);
++	SMC_SELECT_BANK(lp, 2);
++	SMC_SET_INT_MASK(lp, 0);
++	pending_skb = lp->pending_tx_skb;
++	lp->pending_tx_skb = NULL;
++	spin_unlock_irq(&lp->lock);
++
++	/* free any pending tx skb */
++	if (pending_skb) {
++		dev_kfree_skb(pending_skb);
++		dev->stats.tx_errors++;
++		dev->stats.tx_aborted_errors++;
++	}
++
++	/*
++	 * This resets the registers mostly to defaults, but doesn't
++	 * affect EEPROM.  That seems unnecessary
++	 */
++	SMC_SELECT_BANK(lp, 0);
++	SMC_SET_RCR(lp, RCR_SOFTRST);
++
++	/*
++	 * Setup the Configuration Register
++	 * This is necessary because the CONFIG_REG is not affected
++	 * by a soft reset
++	 */
++	SMC_SELECT_BANK(lp, 1);
++
++	cfg = CONFIG_DEFAULT;
++
++	/*
++	 * Setup for fast accesses if requested.  If the card/system
++	 * can't handle it then there will be no recovery except for
++	 * a hard reset or power cycle
++	 */
++	if (nowait)
++		cfg |= CONFIG_NO_WAIT;
++
++	/*
++	 * Release from possible power-down state
++	 * Configuration register is not affected by Soft Reset
++	 */
++	cfg |= CONFIG_EPH_POWER_EN;
++
++	SMC_SET_CONFIG(lp, cfg);
++
++	/* this should pause enough for the chip to be happy */
++	/*
++	 * elaborate?  What does the chip _need_? --jgarzik
++	 *
++	 * This seems to be undocumented, but something the original
++	 * driver(s) have always done.  Suspect undocumented timing
++	 * info/determined empirically. --rmk
++	 */
++	udelay(1);
++
++	/* Disable transmit and receive functionality */
++	SMC_SELECT_BANK(lp, 0);
++	SMC_SET_RCR(lp, RCR_CLEAR);
++	SMC_SET_TCR(lp, TCR_CLEAR);
++
++	SMC_SELECT_BANK(lp, 1);
++	ctl = SMC_GET_CTL(lp) | CTL_LE_ENABLE;
++
++	/*
++	 * Set the control register to automatically release successfully
++	 * transmitted packets, to make the best use out of our limited
++	 * memory
++	 */
++	if(!THROTTLE_TX_PKTS)
++		ctl |= CTL_AUTO_RELEASE;
++	else
++		ctl &= ~CTL_AUTO_RELEASE;
++	SMC_SET_CTL(lp, ctl);
++
++	/* Reset the MMU */
++	SMC_SELECT_BANK(lp, 2);
++	SMC_SET_MMU_CMD(lp, MC_RESET);
++	SMC_WAIT_MMU_BUSY(lp);
++}
++
++/*
++ * Enable Interrupts, Receive, and Transmit
++ */
++static void smc_enable(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	int mask;
++
++	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++
++	/* see the header file for options in TCR/RCR DEFAULT */
++	SMC_SELECT_BANK(lp, 0);
++	SMC_SET_TCR(lp, lp->tcr_cur_mode);
++	SMC_SET_RCR(lp, lp->rcr_cur_mode);
++
++	SMC_SELECT_BANK(lp, 1);
++	SMC_SET_MAC_ADDR(lp, dev->dev_addr);
++
++	/* now, enable interrupts */
++	mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT;
++	if (lp->version >= (CHIP_91100 << 4))
++		mask |= IM_MDINT;
++	SMC_SELECT_BANK(lp, 2);
++	SMC_SET_INT_MASK(lp, mask);
++
++	/*
++	 * From this point the register bank must _NOT_ be switched away
++	 * to something else than bank 2 without proper locking against
++	 * races with any tasklet or interrupt handlers until smc_shutdown()
++	 * or smc_reset() is called.
++	 */
++}
++
++/*
++ * this puts the device in an inactive state
++ */
++static void smc_shutdown(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	struct sk_buff *pending_skb;
++
++	DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
++
++	/* no more interrupts for me */
++	spin_lock_irq(&lp->lock);
++	SMC_SELECT_BANK(lp, 2);
++	SMC_SET_INT_MASK(lp, 0);
++	pending_skb = lp->pending_tx_skb;
++	lp->pending_tx_skb = NULL;
++	spin_unlock_irq(&lp->lock);
++	if (pending_skb)
++		dev_kfree_skb(pending_skb);
++
++	/* and tell the card to stay away from that nasty outside world */
++	SMC_SELECT_BANK(lp, 0);
++	SMC_SET_RCR(lp, RCR_CLEAR);
++	SMC_SET_TCR(lp, TCR_CLEAR);
++
++#ifdef POWER_DOWN
++	/* finally, shut the chip down */
++	SMC_SELECT_BANK(lp, 1);
++	SMC_SET_CONFIG(lp, SMC_GET_CONFIG(lp) & ~CONFIG_EPH_POWER_EN);
++#endif
++}
++
++/*
++ * This is the procedure to handle the receipt of a packet.
++ */
++static inline void  smc_rcv(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	unsigned int packet_number, status, packet_len;
++
++	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
++
++	packet_number = SMC_GET_RXFIFO(lp);
++	if (unlikely(packet_number & RXFIFO_REMPTY)) {
++		PRINTK("%s: smc_rcv with nothing on FIFO.\n", dev->name);
++		return;
++	}
++
++	/* read from start of packet */
++	SMC_SET_PTR(lp, PTR_READ | PTR_RCV | PTR_AUTOINC);
++
++	/* First two words are status and packet length */
++	SMC_GET_PKT_HDR(lp, status, packet_len);
++	packet_len &= 0x07ff;  /* mask off top bits */
++	DBG(2, "%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n",
++		dev->name, packet_number, status,
++		packet_len, packet_len);
++
++	back:
++	if (unlikely(packet_len < 6 || status & RS_ERRORS)) {
++		if (status & RS_TOOLONG && packet_len <= (1514 + 4 + 6)) {
++			/* accept VLAN packets */
++			status &= ~RS_TOOLONG;
++			goto back;
++		}
++		if (packet_len < 6) {
++			/* bloody hardware */
++			printk(KERN_ERR "%s: fubar (rxlen %u status %x\n",
++					dev->name, packet_len, status);
++			status |= RS_TOOSHORT;
++		}
++		SMC_WAIT_MMU_BUSY(lp);
++		SMC_SET_MMU_CMD(lp, MC_RELEASE);
++		dev->stats.rx_errors++;
++		if (status & RS_ALGNERR)
++			dev->stats.rx_frame_errors++;
++		if (status & (RS_TOOSHORT | RS_TOOLONG))
++			dev->stats.rx_length_errors++;
++		if (status & RS_BADCRC)
++			dev->stats.rx_crc_errors++;
++	} else {
++		struct sk_buff *skb;
++		unsigned char *data;
++		unsigned int data_len;
++
++		/* set multicast stats */
++		if (status & RS_MULTICAST)
++			dev->stats.multicast++;
++
++		/*
++		 * Actual payload is packet_len - 6 (or 5 if odd byte).
++		 * We want skb_reserve(2) and the final ctrl word
++		 * (2 bytes, possibly containing the payload odd byte).
++		 * Furthermore, we add 2 bytes to allow rounding up to
++		 * multiple of 4 bytes on 32 bit buses.
++		 * Hence packet_len - 6 + 2 + 2 + 2.
++		 */
++		skb = dev_alloc_skb(packet_len);
++		if (unlikely(skb == NULL)) {
++			printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
++				dev->name);
++			SMC_WAIT_MMU_BUSY(lp);
++			SMC_SET_MMU_CMD(lp, MC_RELEASE);
++			dev->stats.rx_dropped++;
++			return;
++		}
++
++		/* Align IP header to 32 bits */
++		skb_reserve(skb, 2);
++
++		/* BUG: the LAN91C111 rev A never sets this bit. Force it. */
++		if (lp->version == 0x90)
++			status |= RS_ODDFRAME;
++
++		/*
++		 * If odd length: packet_len - 5,
++		 * otherwise packet_len - 6.
++		 * With the trailing ctrl byte it's packet_len - 4.
++		 */
++		data_len = packet_len - ((status & RS_ODDFRAME) ? 5 : 6);
++		data = skb_put(skb, data_len);
++		SMC_PULL_DATA(lp, data, packet_len - 4);
++
++		SMC_WAIT_MMU_BUSY(lp);
++		SMC_SET_MMU_CMD(lp, MC_RELEASE);
++
++		PRINT_PKT(data, packet_len - 4);
++
++		dev->last_rx = jiffies;
++		skb->protocol = eth_type_trans(skb, dev);
++		netif_rx(skb);
++		dev->stats.rx_packets++;
++		dev->stats.rx_bytes += data_len;
++	}
++}
++
++#ifdef CONFIG_SMP
++/*
++ * On SMP we have the following problem:
++ *
++ * 	A = smc_hardware_send_pkt()
++ * 	B = smc_hard_start_xmit()
++ * 	C = smc_interrupt()
++ *
++ * A and B can never be executed simultaneously.  However, at least on UP,
++ * it is possible (and even desirable) for C to interrupt execution of
++ * A or B in order to have better RX reliability and avoid overruns.
++ * C, just like A and B, must have exclusive access to the chip and
++ * each of them must lock against any other concurrent access.
++ * Unfortunately this is not possible to have C suspend execution of A or
++ * B taking place on another CPU. On UP this is no an issue since A and B
++ * are run from softirq context and C from hard IRQ context, and there is
++ * no other CPU where concurrent access can happen.
++ * If ever there is a way to force at least B and C to always be executed
++ * on the same CPU then we could use read/write locks to protect against
++ * any other concurrent access and C would always interrupt B. But life
++ * isn't that easy in a SMP world...
++ */
++#define smc_special_trylock(lock)					\
++({									\
++	int __ret;							\
++	local_irq_disable();						\
++	__ret = spin_trylock(lock);					\
++	if (!__ret)							\
++		local_irq_enable();					\
++	__ret;								\
++})
++#define smc_special_lock(lock)		spin_lock_irq(lock)
++#define smc_special_unlock(lock)	spin_unlock_irq(lock)
++#else
++#define smc_special_trylock(lock)	(1)
++#define smc_special_lock(lock)		do { } while (0)
++#define smc_special_unlock(lock)	do { } while (0)
++#endif
++
++
++/*
++ * MSch: EtherNAT is 32 bit, so the misaligned data buffer hack applies. 
++ * This appears to hurt quite a lot ... need to fudge with the data pointer
++ * to compensate
++ */
++
++#define SMC_outw_be(v, a, r)	writew_be(v, (a) + (r))
++
++#define SMC_PUSH_DATA_BE(lp, p, l)					\
++	do {								\
++		if (SMC_32BIT(lp)) {				\
++			void *__ptr = (p);				\
++			int __len = (l);				\
++			void __iomem *__ioaddr = ioaddr;		\
++			if (__len >= 2 && (unsigned long)__ptr & 2) {	\
++				__len -= 2;				\
++				SMC_outw_be(*(u16 *)__ptr, ioaddr,		\
++					DATA_REG(lp));		\
++				__ptr += 2;				\
++			}						\
++			if (SMC_CAN_USE_DATACS && lp->datacs)		\
++				__ioaddr = lp->datacs;			\
++			SMC_outsl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
++			if (__len & 2) {				\
++				__ptr += (__len & ~3);			\
++				SMC_outw_be(*((u16 *)__ptr), ioaddr,	\
++					 DATA_REG(lp));		\
++			}						\
++		} else if (SMC_16BIT(lp))				\
++			SMC_outsw(ioaddr, DATA_REG(lp), (u16 *) p, (l) >> 1);	\
++		else if (SMC_8BIT(lp))				\
++			SMC_outsb(ioaddr, DATA_REG(lp), p, l);	\
++	} while (0)
++
++
++
++
++/*
++ * This is called to actually send a packet to the chip.
++ */
++static void smc_hardware_send_pkt(unsigned long data)
++{
++	struct net_device *dev = (struct net_device *)data;
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	struct sk_buff *skb;
++	unsigned int packet_no, len;
++	unsigned char *buf;
++
++	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
++
++	if (!smc_special_trylock(&lp->lock)) {
++		netif_stop_queue(dev);
++		tasklet_schedule(&lp->tx_task);
++		return;
++	}
++
++	skb = lp->pending_tx_skb;
++	if (unlikely(!skb)) {
++		smc_special_unlock(&lp->lock);
++		return;
++	}
++	lp->pending_tx_skb = NULL;
++
++	packet_no = SMC_GET_AR(lp);
++	if (unlikely(packet_no & AR_FAILED)) {
++		printk("%s: Memory allocation failed.\n", dev->name);
++		dev->stats.tx_errors++;
++		dev->stats.tx_fifo_errors++;
++		smc_special_unlock(&lp->lock);
++		goto done;
++	}
++
++	/* point to the beginning of the packet */
++	SMC_SET_PN(lp, packet_no);
++	SMC_SET_PTR(lp, PTR_AUTOINC);
++
++	buf = skb->data;
++	len = skb->len;
++	DBG(2, "%s: TX PNR 0x%x LENGTH 0x%04x (%d) BUF 0x%p\n",
++		dev->name, packet_no, len, len, buf);
++	PRINT_PKT(buf, len);
++
++	/*
++	 * Send the packet length (+6 for status words, length, and ctl.
++	 * The card will pad to 64 bytes with zeroes if packet is too small.
++	 */
++	SMC_PUT_PKT_HDR(lp, 0, len + 6);
++
++	/* send the actual data */
++	SMC_PUSH_DATA_BE(lp, buf, len & ~1);
++
++	/* Send final ctl word with the last byte if there is one */
++	SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG(lp));
++
++	/*
++	 * If THROTTLE_TX_PKTS is set, we stop the queue here. This will
++	 * have the effect of having at most one packet queued for TX
++	 * in the chip's memory at all time.
++	 *
++	 * If THROTTLE_TX_PKTS is not set then the queue is stopped only
++	 * when memory allocation (MC_ALLOC) does not succeed right away.
++	 */
++	if (THROTTLE_TX_PKTS)
++		netif_stop_queue(dev);
++
++	/* queue the packet for TX */
++	SMC_SET_MMU_CMD(lp, MC_ENQUEUE);
++	smc_special_unlock(&lp->lock);
++
++	dev->trans_start = jiffies;
++	dev->stats.tx_packets++;
++	dev->stats.tx_bytes += len;
++
++	SMC_ENABLE_INT(lp, IM_TX_INT | IM_TX_EMPTY_INT);
++
++done:	if (!THROTTLE_TX_PKTS)
++		netif_wake_queue(dev);
++
++	dev_kfree_skb(skb);
++}
++
++/*
++ * Since I am not sure if I will have enough room in the chip's ram
++ * to store the packet, I call this routine which either sends it
++ * now, or set the card to generates an interrupt when ready
++ * for the packet.
++ */
++static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	unsigned int numPages, poll_count, status;
++
++	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
++
++	BUG_ON(lp->pending_tx_skb != NULL);
++
++	/*
++	 * The MMU wants the number of pages to be the number of 256 bytes
++	 * 'pages', minus 1 (since a packet can't ever have 0 pages :))
++	 *
++	 * The 91C111 ignores the size bits, but earlier models don't.
++	 *
++	 * Pkt size for allocating is data length +6 (for additional status
++	 * words, length and ctl)
++	 *
++	 * If odd size then last byte is included in ctl word.
++	 */
++	numPages = ((skb->len & ~1) + (6 - 1)) >> 8;
++	if (unlikely(numPages > 7)) {
++		printk("%s: Far too big packet error.\n", dev->name);
++		dev->stats.tx_errors++;
++		dev->stats.tx_dropped++;
++		dev_kfree_skb(skb);
++		return 0;
++	}
++
++	smc_special_lock(&lp->lock);
++
++	/* now, try to allocate the memory */
++	SMC_SET_MMU_CMD(lp, MC_ALLOC | numPages);
++
++	/*
++	 * Poll the chip for a short amount of time in case the
++	 * allocation succeeds quickly.
++	 */
++	poll_count = MEMORY_WAIT_TIME;
++	do {
++		status = SMC_GET_INT(lp);
++		if (status & IM_ALLOC_INT) {
++			SMC_ACK_INT(lp, IM_ALLOC_INT);
++  			break;
++		}
++   	} while (--poll_count);
++
++	smc_special_unlock(&lp->lock);
++
++	lp->pending_tx_skb = skb;
++   	if (!poll_count) {
++		/* oh well, wait until the chip finds memory later */
++		netif_stop_queue(dev);
++		DBG(2, "%s: TX memory allocation deferred.\n", dev->name);
++		SMC_ENABLE_INT(lp, IM_ALLOC_INT);
++   	} else {
++		/*
++		 * Allocation succeeded: push packet to the chip's own memory
++		 * immediately.
++		 */
++		smc_hardware_send_pkt((unsigned long)dev);
++	}
++
++	return 0;
++}
++
++/*
++ * This handles a TX interrupt, which is only called when:
++ * - a TX error occurred, or
++ * - CTL_AUTO_RELEASE is not set and TX of a packet completed.
++ */
++static void smc_tx(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	unsigned int saved_packet, packet_no, tx_status, pkt_len;
++
++	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
++
++	/* If the TX FIFO is empty then nothing to do */
++	packet_no = SMC_GET_TXFIFO(lp);
++	if (unlikely(packet_no & TXFIFO_TEMPTY)) {
++		PRINTK("%s: smc_tx with nothing on FIFO.\n", dev->name);
++		return;
++	}
++
++	/* select packet to read from */
++	saved_packet = SMC_GET_PN(lp);
++	SMC_SET_PN(lp, packet_no);
++
++	/* read the first word (status word) from this packet */
++	SMC_SET_PTR(lp, PTR_AUTOINC | PTR_READ);
++	SMC_GET_PKT_HDR(lp, tx_status, pkt_len);
++	DBG(2, "%s: TX STATUS 0x%04x PNR 0x%02x\n",
++		dev->name, tx_status, packet_no);
++
++	if (!(tx_status & ES_TX_SUC))
++		dev->stats.tx_errors++;
++
++	if (tx_status & ES_LOSTCARR)
++		dev->stats.tx_carrier_errors++;
++
++	if (tx_status & (ES_LATCOL | ES_16COL)) {
++		PRINTK("%s: %s occurred on last xmit\n", dev->name,
++		       (tx_status & ES_LATCOL) ?
++			"late collision" : "too many collisions");
++		dev->stats.tx_window_errors++;
++		if (!(dev->stats.tx_window_errors & 63) && net_ratelimit()) {
++			printk(KERN_INFO "%s: unexpectedly large number of "
++			       "bad collisions. Please check duplex "
++			       "setting.\n", dev->name);
++		}
++	}
++
++	/* kill the packet */
++	SMC_WAIT_MMU_BUSY(lp);
++	SMC_SET_MMU_CMD(lp, MC_FREEPKT);
++
++	/* Don't restore Packet Number Reg until busy bit is cleared */
++	SMC_WAIT_MMU_BUSY(lp);
++	SMC_SET_PN(lp, saved_packet);
++
++	/* re-enable transmit */
++	SMC_SELECT_BANK(lp, 0);
++	SMC_SET_TCR(lp, lp->tcr_cur_mode);
++	SMC_SELECT_BANK(lp, 2);
++}
++
++
++/*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/
++
++static void smc_mii_out(struct net_device *dev, unsigned int val, int bits)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	unsigned int mii_reg, mask;
++
++	mii_reg = SMC_GET_MII(lp) & ~(MII_MCLK | MII_MDOE | MII_MDO);
++	mii_reg |= MII_MDOE;
++
++	for (mask = 1 << (bits - 1); mask; mask >>= 1) {
++		if (val & mask)
++			mii_reg |= MII_MDO;
++		else
++			mii_reg &= ~MII_MDO;
++
++		SMC_SET_MII(lp, mii_reg);
++		udelay(MII_DELAY);
++		SMC_SET_MII(lp, mii_reg | MII_MCLK);
++		udelay(MII_DELAY);
++	}
++}
++
++static unsigned int smc_mii_in(struct net_device *dev, int bits)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	unsigned int mii_reg, mask, val;
++
++	mii_reg = SMC_GET_MII(lp) & ~(MII_MCLK | MII_MDOE | MII_MDO);
++	SMC_SET_MII(lp, mii_reg);
++
++	for (mask = 1 << (bits - 1), val = 0; mask; mask >>= 1) {
++		if (SMC_GET_MII(lp) & MII_MDI)
++			val |= mask;
++
++		SMC_SET_MII(lp, mii_reg);
++		udelay(MII_DELAY);
++		SMC_SET_MII(lp, mii_reg | MII_MCLK);
++		udelay(MII_DELAY);
++	}
++
++	return val;
++}
++
++/*
++ * Reads a register from the MII Management serial interface
++ */
++static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	unsigned int phydata;
++
++	SMC_SELECT_BANK(lp, 3);
++
++	/* Idle - 32 ones */
++	smc_mii_out(dev, 0xffffffff, 32);
++
++	/* Start code (01) + read (10) + phyaddr + phyreg */
++	smc_mii_out(dev, 6 << 10 | phyaddr << 5 | phyreg, 14);
++
++	/* Turnaround (2bits) + phydata */
++	phydata = smc_mii_in(dev, 18);
++
++	/* Return to idle state */
++	SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO));
++
++	DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
++		__FUNCTION__, phyaddr, phyreg, phydata);
++
++	SMC_SELECT_BANK(lp, 2);
++	return phydata;
++}
++
++/*
++ * Writes a register to the MII Management serial interface
++ */
++static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
++			  int phydata)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++
++	SMC_SELECT_BANK(lp, 3);
++
++	/* Idle - 32 ones */
++	smc_mii_out(dev, 0xffffffff, 32);
++
++	/* Start code (01) + write (01) + phyaddr + phyreg + turnaround + phydata */
++	smc_mii_out(dev, 5 << 28 | phyaddr << 23 | phyreg << 18 | 2 << 16 | phydata, 32);
++
++	/* Return to idle state */
++	SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO));
++
++	DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
++		__FUNCTION__, phyaddr, phyreg, phydata);
++
++	SMC_SELECT_BANK(lp, 2);
++}
++
++/*
++ * Finds and reports the PHY address
++ */
++static void smc_phy_detect(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	int phyaddr;
++
++	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++
++	lp->phy_type = 0;
++
++	/*
++	 * Scan all 32 PHY addresses if necessary, starting at
++	 * PHY#1 to PHY#31, and then PHY#0 last.
++	 */
++	for (phyaddr = 1; phyaddr < 33; ++phyaddr) {
++		unsigned int id1, id2;
++
++		/* Read the PHY identifiers */
++		id1 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID1);
++		id2 = smc_phy_read(dev, phyaddr & 31, MII_PHYSID2);
++
++		DBG(3, "%s: phy_id1=0x%x, phy_id2=0x%x\n",
++			dev->name, id1, id2);
++
++		/* Make sure it is a valid identifier */
++		if (id1 != 0x0000 && id1 != 0xffff && id1 != 0x8000 &&
++		    id2 != 0x0000 && id2 != 0xffff && id2 != 0x8000) {
++			/* Save the PHY's address */
++			lp->mii.phy_id = phyaddr & 31;
++			lp->phy_type = id1 << 16 | id2;
++			break;
++		}
++	}
++}
++
++/*
++ * Sets the PHY to a configuration as determined by the user
++ */
++static int smc_phy_fixed(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	int phyaddr = lp->mii.phy_id;
++	int bmcr, cfg1;
++
++	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
++
++	/* Enter Link Disable state */
++	cfg1 = smc_phy_read(dev, phyaddr, PHY_CFG1_REG);
++	cfg1 |= PHY_CFG1_LNKDIS;
++	smc_phy_write(dev, phyaddr, PHY_CFG1_REG, cfg1);
++
++	/*
++	 * Set our fixed capabilities
++	 * Disable auto-negotiation
++	 */
++	bmcr = 0;
++
++	if (lp->ctl_rfduplx)
++		bmcr |= BMCR_FULLDPLX;
++
++	if (lp->ctl_rspeed == 100)
++		bmcr |= BMCR_SPEED100;
++
++	/* Write our capabilities to the phy control register */
++	smc_phy_write(dev, phyaddr, MII_BMCR, bmcr);
++
++	/* Re-Configure the Receive/Phy Control register */
++	SMC_SELECT_BANK(lp, 0);
++	SMC_SET_RPC(lp, lp->rpc_cur_mode);
++	SMC_SELECT_BANK(lp, 2);
++
++	return 1;
++}
++
++/*
++ * smc_phy_reset - reset the phy
++ * @dev: net device
++ * @phy: phy address
++ *
++ * Issue a software reset for the specified PHY and
++ * wait up to 100ms for the reset to complete.  We should
++ * not access the PHY for 50ms after issuing the reset.
++ *
++ * The time to wait appears to be dependent on the PHY.
++ *
++ * Must be called with lp->lock locked.
++ */
++static int smc_phy_reset(struct net_device *dev, int phy)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	unsigned int bmcr;
++	int timeout;
++
++	smc_phy_write(dev, phy, MII_BMCR, BMCR_RESET);
++
++	for (timeout = 2; timeout; timeout--) {
++		spin_unlock_irq(&lp->lock);
++		msleep(50);
++		spin_lock_irq(&lp->lock);
++
++		bmcr = smc_phy_read(dev, phy, MII_BMCR);
++		if (!(bmcr & BMCR_RESET))
++			break;
++	}
++
++	return bmcr & BMCR_RESET;
++}
++
++/*
++ * smc_phy_powerdown - powerdown phy
++ * @dev: net device
++ *
++ * Power down the specified PHY
++ */
++static void smc_phy_powerdown(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	unsigned int bmcr;
++	int phy = lp->mii.phy_id;
++
++	if (lp->phy_type == 0)
++		return;
++
++	/* We need to ensure that no calls to smc_phy_configure are
++	   pending.
++	*/
++	cancel_work_sync(&lp->phy_configure);
++
++	bmcr = smc_phy_read(dev, phy, MII_BMCR);
++	smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN);
++}
++
++/*
++ * smc_phy_check_media - check the media status and adjust TCR
++ * @dev: net device
++ * @init: set true for initialisation
++ *
++ * Select duplex mode depending on negotiation state.  This
++ * also updates our carrier state.
++ */
++static void smc_phy_check_media(struct net_device *dev, int init)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++
++	if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
++		/* duplex state has changed */
++		if (lp->mii.full_duplex) {
++			lp->tcr_cur_mode |= TCR_SWFDUP;
++		} else {
++			lp->tcr_cur_mode &= ~TCR_SWFDUP;
++		}
++
++		SMC_SELECT_BANK(lp, 0);
++		SMC_SET_TCR(lp, lp->tcr_cur_mode);
++	}
++}
++
++/*
++ * Configures the specified PHY through the MII management interface
++ * using Autonegotiation.
++ * Calls smc_phy_fixed() if the user has requested a certain config.
++ * If RPC ANEG bit is set, the media selection is dependent purely on
++ * the selection by the MII (either in the MII BMCR reg or the result
++ * of autonegotiation.)  If the RPC ANEG bit is cleared, the selection
++ * is controlled by the RPC SPEED and RPC DPLX bits.
++ */
++static void smc_phy_configure(struct work_struct *work)
++{
++	struct smc_local *lp =
++		container_of(work, struct smc_local, phy_configure);
++	struct net_device *dev = lp->dev;
++	void __iomem *ioaddr = lp->base;
++	int phyaddr = lp->mii.phy_id;
++	int my_phy_caps; /* My PHY capabilities */
++	int my_ad_caps; /* My Advertised capabilities */
++	int status;
++
++	DBG(3, "%s:smc_program_phy()\n", dev->name);
++
++	spin_lock_irq(&lp->lock);
++
++	/*
++	 * We should not be called if phy_type is zero.
++	 */
++	if (lp->phy_type == 0)
++		goto smc_phy_configure_exit;
++
++	if (smc_phy_reset(dev, phyaddr)) {
++		printk("%s: PHY reset timed out\n", dev->name);
++		goto smc_phy_configure_exit;
++	}
++
++	/*
++	 * Enable PHY Interrupts (for register 18)
++	 * Interrupts listed here are disabled
++	 */
++	smc_phy_write(dev, phyaddr, PHY_MASK_REG,
++		PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD |
++		PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB |
++		PHY_INT_SPDDET | PHY_INT_DPLXDET);
++
++	/* Configure the Receive/Phy Control register */
++	SMC_SELECT_BANK(lp, 0);
++	SMC_SET_RPC(lp, lp->rpc_cur_mode);
++
++	/* If the user requested no auto neg, then go set his request */
++	if (lp->mii.force_media) {
++		smc_phy_fixed(dev);
++		goto smc_phy_configure_exit;
++	}
++
++	/* Copy our capabilities from MII_BMSR to MII_ADVERTISE */
++	my_phy_caps = smc_phy_read(dev, phyaddr, MII_BMSR);
++
++	if (!(my_phy_caps & BMSR_ANEGCAPABLE)) {
++		printk(KERN_INFO "Auto negotiation NOT supported\n");
++		smc_phy_fixed(dev);
++		goto smc_phy_configure_exit;
++	}
++
++	my_ad_caps = ADVERTISE_CSMA; /* I am CSMA capable */
++
++	if (my_phy_caps & BMSR_100BASE4)
++		my_ad_caps |= ADVERTISE_100BASE4;
++	if (my_phy_caps & BMSR_100FULL)
++		my_ad_caps |= ADVERTISE_100FULL;
++	if (my_phy_caps & BMSR_100HALF)
++		my_ad_caps |= ADVERTISE_100HALF;
++	if (my_phy_caps & BMSR_10FULL)
++		my_ad_caps |= ADVERTISE_10FULL;
++	if (my_phy_caps & BMSR_10HALF)
++		my_ad_caps |= ADVERTISE_10HALF;
++
++	/* Disable capabilities not selected by our user */
++	if (lp->ctl_rspeed != 100)
++		my_ad_caps &= ~(ADVERTISE_100BASE4|ADVERTISE_100FULL|ADVERTISE_100HALF);
++
++	if (!lp->ctl_rfduplx)
++		my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL);
++
++	/* Update our Auto-Neg Advertisement Register */
++	smc_phy_write(dev, phyaddr, MII_ADVERTISE, my_ad_caps);
++	lp->mii.advertising = my_ad_caps;
++
++	/*
++	 * Read the register back.  Without this, it appears that when
++	 * auto-negotiation is restarted, sometimes it isn't ready and
++	 * the link does not come up.
++	 */
++	status = smc_phy_read(dev, phyaddr, MII_ADVERTISE);
++
++	DBG(2, "%s: phy caps=%x\n", dev->name, my_phy_caps);
++	DBG(2, "%s: phy advertised caps=%x\n", dev->name, my_ad_caps);
++
++	/* Restart auto-negotiation process in order to advertise my caps */
++	smc_phy_write(dev, phyaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
++
++	smc_phy_check_media(dev, 1);
++
++smc_phy_configure_exit:
++	SMC_SELECT_BANK(lp, 2);
++	spin_unlock_irq(&lp->lock);
++}
++
++/*
++ * smc_phy_interrupt
++ *
++ * Purpose:  Handle interrupts relating to PHY register 18. This is
++ *  called from the "hard" interrupt handler under our private spinlock.
++ */
++static void smc_phy_interrupt(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	int phyaddr = lp->mii.phy_id;
++	int phy18;
++
++	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++
++	if (lp->phy_type == 0)
++		return;
++
++	for(;;) {
++		smc_phy_check_media(dev, 0);
++
++		/* Read PHY Register 18, Status Output */
++		phy18 = smc_phy_read(dev, phyaddr, PHY_INT_REG);
++		if ((phy18 & PHY_INT_INT) == 0)
++			break;
++	}
++}
++
++/*--- END PHY CONTROL AND CONFIGURATION-------------------------------------*/
++
++static void smc_10bt_check_media(struct net_device *dev, int init)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	unsigned int old_carrier, new_carrier;
++
++	old_carrier = netif_carrier_ok(dev) ? 1 : 0;
++
++	SMC_SELECT_BANK(lp, 0);
++	new_carrier = (SMC_GET_EPH_STATUS(lp) & ES_LINK_OK) ? 1 : 0;
++	SMC_SELECT_BANK(lp, 2);
++
++	if (init || (old_carrier != new_carrier)) {
++		if (!new_carrier) {
++			netif_carrier_off(dev);
++		} else {
++			netif_carrier_on(dev);
++		}
++		if (netif_msg_link(lp))
++			printk(KERN_INFO "%s: link %s\n", dev->name,
++			       new_carrier ? "up" : "down");
++	}
++}
++
++static void smc_eph_interrupt(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	unsigned int ctl;
++
++	smc_10bt_check_media(dev, 0);
++
++	SMC_SELECT_BANK(lp, 1);
++	ctl = SMC_GET_CTL(lp);
++	SMC_SET_CTL(lp, ctl & ~CTL_LE_ENABLE);
++	SMC_SET_CTL(lp, ctl);
++	SMC_SELECT_BANK(lp, 2);
++}
++
++/*
++ * This is the main routine of the driver, to handle the device when
++ * it needs some attention.
++ */
++static irqreturn_t smc_interrupt(int irq, void *dev_id)
++{
++	struct net_device *dev = dev_id;
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	int status, mask, timeout, card_stats;
++	int saved_pointer;
++
++	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
++
++	spin_lock(&lp->lock);
++
++	/* A preamble may be used when there is a potential race
++	 * between the interruptible transmit functions and this
++	 * ISR. */
++	SMC_INTERRUPT_PREAMBLE;
++
++	saved_pointer = SMC_GET_PTR(lp);
++	mask = SMC_GET_INT_MASK(lp);
++	SMC_SET_INT_MASK(lp, 0);
++
++	/* set a timeout value, so I don't stay here forever */
++	timeout = MAX_IRQ_LOOPS;
++
++	do {
++		status = SMC_GET_INT(lp);
++
++		DBG(3, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
++			dev->name, status, mask,
++			({ int meminfo; SMC_SELECT_BANK(lp, 0);
++			   meminfo = SMC_GET_MIR(lp);
++			   SMC_SELECT_BANK(lp, 2); meminfo; }),
++			SMC_GET_FIFO(lp));
++
++		status &= mask;
++		if (!status)
++			break;
++
++		if (status & IM_TX_INT) {
++			/* do this before RX as it will free memory quickly */
++			DBG(2, "%s: TX int\n", dev->name);
++			smc_tx(dev);
++			SMC_ACK_INT(lp, IM_TX_INT);
++			if (THROTTLE_TX_PKTS)
++				netif_wake_queue(dev);
++		} else if (status & IM_RCV_INT) {
++			DBG(2, "%s: RX irq\n", dev->name);
++			smc_rcv(dev);
++		} else if (status & IM_ALLOC_INT) {
++			DBG(1, "%s: Allocation irq\n", dev->name);
++			tasklet_hi_schedule(&lp->tx_task);
++			mask &= ~IM_ALLOC_INT;
++		} else if (status & IM_TX_EMPTY_INT) {
++			DBG(2, "%s: TX empty\n", dev->name);
++			mask &= ~IM_TX_EMPTY_INT;
++
++			/* update stats */
++			SMC_SELECT_BANK(lp, 0);
++			card_stats = SMC_GET_COUNTER(lp);
++			SMC_SELECT_BANK(lp, 2);
++
++			/* single collisions */
++			dev->stats.collisions += card_stats & 0xF;
++			card_stats >>= 4;
++
++			/* multiple collisions */
++			dev->stats.collisions += card_stats & 0xF;
++		} else if (status & IM_RX_OVRN_INT) {
++			DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name,
++			       ({ int eph_st; SMC_SELECT_BANK(lp, 0);
++				  eph_st = SMC_GET_EPH_STATUS(lp);
++				  SMC_SELECT_BANK(lp, 2); eph_st; }) );
++			SMC_ACK_INT(lp, IM_RX_OVRN_INT);
++			dev->stats.rx_errors++;
++			dev->stats.rx_fifo_errors++;
++		} else if (status & IM_EPH_INT) {
++			DBG(1, "%s: eph interrupt\n", dev->name);
++			smc_eph_interrupt(dev);
++		} else if (status & IM_MDINT) {
++			DBG(1, "%s: phy interrupt\n", dev->name);
++			SMC_ACK_INT(lp, IM_MDINT);
++			smc_phy_interrupt(dev);
++		} else if (status & IM_ERCV_INT) {
++			SMC_ACK_INT(lp, IM_ERCV_INT);
++			PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n", dev->name);
++		}
++	} while (--timeout);
++
++	/* restore register states */
++	SMC_SET_PTR(lp, saved_pointer);
++	SMC_SET_INT_MASK(lp, mask);
++	spin_unlock(&lp->lock);
++
++#ifndef CONFIG_NET_POLL_CONTROLLER
++#if 0
++	if (timeout == MAX_IRQ_LOOPS)
++		PRINTK("%s: spurious interrupt (mask = 0x%02x)\n",
++		       dev->name, mask);
++#endif
++#endif
++	DBG(3, "%s: Interrupt done (%d loops)\n",
++	       dev->name, MAX_IRQ_LOOPS - timeout);
++
++	/*
++	 * We return IRQ_HANDLED unconditionally here even if there was
++	 * nothing to do.  There is a possibility that a packet might
++	 * get enqueued into the chip right after TX_EMPTY_INT is raised
++	 * but just before the CPU acknowledges the IRQ.
++	 * Better take an unneeded IRQ in some occasions than complexifying
++	 * the code for all cases.
++	 */
++	return IRQ_HANDLED;
++}
++
++#ifdef CONFIG_NET_POLL_CONTROLLER
++/*
++ * Polling receive - used by netconsole and other diagnostic tools
++ * to allow network i/o with interrupts disabled.
++ */
++static void smc_poll_controller(struct net_device *dev)
++{
++	disable_irq(dev->irq);
++	smc_interrupt(dev->irq, dev);
++	enable_irq(dev->irq);
++}
++#endif
++
++/* Our watchdog timed out. Called by the networking layer */
++static void smc_timeout(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	int status, mask, eph_st, meminfo, fifo;
++
++	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++
++	spin_lock_irq(&lp->lock);
++	status = SMC_GET_INT(lp);
++	mask = SMC_GET_INT_MASK(lp);
++	fifo = SMC_GET_FIFO(lp);
++	SMC_SELECT_BANK(lp, 0);
++	eph_st = SMC_GET_EPH_STATUS(lp);
++	meminfo = SMC_GET_MIR(lp);
++	SMC_SELECT_BANK(lp, 2);
++	spin_unlock_irq(&lp->lock);
++	PRINTK( "%s: TX timeout (INT 0x%02x INTMASK 0x%02x "
++		"MEM 0x%04x FIFO 0x%04x EPH_ST 0x%04x)\n",
++		dev->name, status, mask, meminfo, fifo, eph_st );
++
++	smc_reset(dev);
++	smc_enable(dev);
++
++	/*
++	 * Reconfiguring the PHY doesn't seem like a bad idea here, but
++	 * smc_phy_configure() calls msleep() which calls schedule_timeout()
++	 * which calls schedule().  Hence we use a work queue.
++	 */
++	if (lp->phy_type != 0) 
++		schedule_work(&lp->phy_configure);
++
++	/* We can accept TX packets again */
++	dev->trans_start = jiffies;
++	netif_wake_queue(dev);
++}
++
++/*
++ * This routine will, depending on the values passed to it,
++ * either make it accept multicast packets, go into
++ * promiscuous mode (for TCPDUMP and cousins) or accept
++ * a select set of multicast packets
++ */
++static void smc_set_multicast_list(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	void __iomem *ioaddr = lp->base;
++	unsigned char multicast_table[8];
++	int update_multicast = 0;
++
++	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++
++	if (dev->flags & IFF_PROMISC) {
++		DBG(2, "%s: RCR_PRMS\n", dev->name);
++		lp->rcr_cur_mode |= RCR_PRMS;
++	}
++
++/* BUG?  I never disable promiscuous mode if multicasting was turned on.
++   Now, I turn off promiscuous mode, but I don't do anything to multicasting
++   when promiscuous mode is turned on.
++*/
++
++	/*
++	 * Here, I am setting this to accept all multicast packets.
++	 * I don't need to zero the multicast table, because the flag is
++	 * checked before the table is
++	 */
++	else if (dev->flags & IFF_ALLMULTI || dev->mc_count > 16) {
++		DBG(2, "%s: RCR_ALMUL\n", dev->name);
++		lp->rcr_cur_mode |= RCR_ALMUL;
++	}
++
++	/*
++	 * This sets the internal hardware table to filter out unwanted
++	 * multicast packets before they take up memory.
++	 *
++	 * The SMC chip uses a hash table where the high 6 bits of the CRC of
++	 * address are the offset into the table.  If that bit is 1, then the
++	 * multicast packet is accepted.  Otherwise, it's dropped silently.
++	 *
++	 * To use the 6 bits as an offset into the table, the high 3 bits are
++	 * the number of the 8 bit register, while the low 3 bits are the bit
++	 * within that register.
++	 */
++	else if (dev->mc_count)  {
++		int i;
++		struct dev_mc_list *cur_addr;
++
++		/* table for flipping the order of 3 bits */
++		static const unsigned char invert3[] = {0, 4, 2, 6, 1, 5, 3, 7};
++
++		/* start with a table of all zeros: reject all */
++		memset(multicast_table, 0, sizeof(multicast_table));
++
++		cur_addr = dev->mc_list;
++		for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) {
++			int position;
++
++			/* do we have a pointer here? */
++			if (!cur_addr)
++				break;
++			/* make sure this is a multicast address -
++		   	   shouldn't this be a given if we have it here ? */
++			if (!(*cur_addr->dmi_addr & 1))
++				continue;
++
++			/* only use the low order bits */
++			position = crc32_le(~0, cur_addr->dmi_addr, 6) & 0x3f;
++
++			/* do some messy swapping to put the bit in the right spot */
++			multicast_table[invert3[position&7]] |=
++				(1<<invert3[(position>>3)&7]);
++		}
++
++		/* be sure I get rid of flags I might have set */
++		lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL);
++
++		/* now, the table can be loaded into the chipset */
++		update_multicast = 1;
++	} else  {
++		DBG(2, "%s: ~(RCR_PRMS|RCR_ALMUL)\n", dev->name);
++		lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL);
++
++		/*
++		 * since I'm disabling all multicast entirely, I need to
++		 * clear the multicast list
++		 */
++		memset(multicast_table, 0, sizeof(multicast_table));
++		update_multicast = 1;
++	}
++
++	spin_lock_irq(&lp->lock);
++	SMC_SELECT_BANK(lp, 0);
++	SMC_SET_RCR(lp, lp->rcr_cur_mode);
++	if (update_multicast) {
++		SMC_SELECT_BANK(lp, 3);
++		SMC_SET_MCAST(lp, multicast_table);
++	}
++	SMC_SELECT_BANK(lp, 2);
++	spin_unlock_irq(&lp->lock);
++}
++
++
++/*
++ * Open and Initialize the board
++ *
++ * Set up everything, reset the card, etc..
++ */
++static int
++smc_open(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++
++	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++
++	/*
++	 * Check that the address is valid.  If its not, refuse
++	 * to bring the device up.  The user must specify an
++	 * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
++	 */
++	if (!is_valid_ether_addr(dev->dev_addr)) {
++		PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__);
++		return -EINVAL;
++	}
++
++	/* Setup the default Register Modes */
++	lp->tcr_cur_mode = TCR_DEFAULT;
++	lp->rcr_cur_mode = RCR_DEFAULT;
++	lp->rpc_cur_mode = RPC_DEFAULT;
++
++	/*
++	 * If we are not using a MII interface, we need to
++	 * monitor our own carrier signal to detect faults.
++	 */
++	if (lp->phy_type == 0)
++		lp->tcr_cur_mode |= TCR_MON_CSN;
++
++	/* reset the hardware */
++	smc_reset(dev);
++	smc_enable(dev);
++
++	/* Configure the PHY, initialize the link state */
++	if (lp->phy_type != 0)
++		smc_phy_configure(&lp->phy_configure);
++	else {
++		spin_lock_irq(&lp->lock);
++		smc_10bt_check_media(dev, 1);
++		spin_unlock_irq(&lp->lock);
++	}
++
++	netif_start_queue(dev);
++	return 0;
++}
++
++/*
++ * smc_close
++ *
++ * this makes the board clean up everything that it can
++ * and not talk to the outside world.   Caused by
++ * an 'ifconfig ethX down'
++ */
++static int smc_close(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++
++	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++
++	netif_stop_queue(dev);
++	netif_carrier_off(dev);
++
++	/* clear everything */
++	smc_shutdown(dev);
++	tasklet_kill(&lp->tx_task);
++	smc_phy_powerdown(dev);
++	return 0;
++}
++
++/*
++ * Ethtool support
++ */
++static int
++smc_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	int ret;
++
++	cmd->maxtxpkt = 1;
++	cmd->maxrxpkt = 1;
++
++	if (lp->phy_type != 0) {
++		spin_lock_irq(&lp->lock);
++		ret = mii_ethtool_gset(&lp->mii, cmd);
++		spin_unlock_irq(&lp->lock);
++	} else {
++		cmd->supported = SUPPORTED_10baseT_Half |
++				 SUPPORTED_10baseT_Full |
++				 SUPPORTED_TP | SUPPORTED_AUI;
++
++		if (lp->ctl_rspeed == 10)
++			cmd->speed = SPEED_10;
++		else if (lp->ctl_rspeed == 100)
++			cmd->speed = SPEED_100;
++
++		cmd->autoneg = AUTONEG_DISABLE;
++		cmd->transceiver = XCVR_INTERNAL;
++		cmd->port = 0;
++		cmd->duplex = lp->tcr_cur_mode & TCR_SWFDUP ? DUPLEX_FULL : DUPLEX_HALF;
++
++		ret = 0;
++	}
++
++	return ret;
++}
++
++static int
++smc_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	int ret;
++
++	if (lp->phy_type != 0) {
++		spin_lock_irq(&lp->lock);
++		ret = mii_ethtool_sset(&lp->mii, cmd);
++		spin_unlock_irq(&lp->lock);
++	} else {
++		if (cmd->autoneg != AUTONEG_DISABLE ||
++		    cmd->speed != SPEED_10 ||
++		    (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL) ||
++		    (cmd->port != PORT_TP && cmd->port != PORT_AUI))
++			return -EINVAL;
++
++//		lp->port = cmd->port;
++		lp->ctl_rfduplx = cmd->duplex == DUPLEX_FULL;
++
++//		if (netif_running(dev))
++//			smc_set_port(dev);
++
++		ret = 0;
++	}
++
++	return ret;
++}
++
++static void
++smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
++{
++	strncpy(info->driver, CARDNAME, sizeof(info->driver));
++	strncpy(info->version, version, sizeof(info->version));
++	strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
++}
++
++static int smc_ethtool_nwayreset(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	int ret = -EINVAL;
++
++	if (lp->phy_type != 0) {
++		spin_lock_irq(&lp->lock);
++		ret = mii_nway_restart(&lp->mii);
++		spin_unlock_irq(&lp->lock);
++	}
++
++	return ret;
++}
++
++static u32 smc_ethtool_getmsglevel(struct net_device *dev)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	return lp->msg_enable;
++}
++
++static void smc_ethtool_setmsglevel(struct net_device *dev, u32 level)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	lp->msg_enable = level;
++}
++
++static const struct ethtool_ops smc_ethtool_ops = {
++	.get_settings	= smc_ethtool_getsettings,
++	.set_settings	= smc_ethtool_setsettings,
++	.get_drvinfo	= smc_ethtool_getdrvinfo,
++
++	.get_msglevel	= smc_ethtool_getmsglevel,
++	.set_msglevel	= smc_ethtool_setmsglevel,
++	.nway_reset	= smc_ethtool_nwayreset,
++	.get_link	= ethtool_op_get_link,
++//	.get_eeprom	= smc_ethtool_geteeprom,
++//	.set_eeprom	= smc_ethtool_seteeprom,
++};
++
++/*
++ * smc_findirq
++ *
++ * This routine has a simple purpose -- make the SMC chip generate an
++ * interrupt, so an auto-detect routine can detect it, and find the IRQ,
++ */
++/*
++ * does this still work?
++ *
++ * I just deleted auto_irq.c, since it was never built...
++ *   --jgarzik
++ */
++static int __init smc_findirq(struct smc_local *lp)
++{
++	void __iomem *ioaddr = lp->base;
++	int timeout = 20;
++	unsigned long cookie;
++
++	DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
++
++	cookie = probe_irq_on();
++
++	/*
++	 * What I try to do here is trigger an ALLOC_INT. This is done
++	 * by allocating a small chunk of memory, which will give an interrupt
++	 * when done.
++	 */
++	/* enable ALLOCation interrupts ONLY */
++	SMC_SELECT_BANK(lp, 2);
++	SMC_SET_INT_MASK(lp, IM_ALLOC_INT);
++
++	/*
++ 	 * Allocate 512 bytes of memory.  Note that the chip was just
++	 * reset so all the memory is available
++	 */
++	SMC_SET_MMU_CMD(lp, MC_ALLOC | 1);
++
++	/*
++	 * Wait until positive that the interrupt has been generated
++	 */
++	do {
++		int int_status;
++		udelay(10);
++		int_status = SMC_GET_INT(lp);
++		if (int_status & IM_ALLOC_INT)
++			break;		/* got the interrupt */
++	} while (--timeout);
++
++	/*
++	 * there is really nothing that I can do here if timeout fails,
++	 * as autoirq_report will return a 0 anyway, which is what I
++	 * want in this case.   Plus, the clean up is needed in both
++	 * cases.
++	 */
++
++	/* and disable all interrupts again */
++	SMC_SET_INT_MASK(lp, 0);
++
++	/* and return what I found */
++	return probe_irq_off(cookie);
++}
++
++/*
++ * Function: smc_probe(unsigned long ioaddr)
++ *
++ * Purpose:
++ *	Tests to see if a given ioaddr points to an SMC91x chip.
++ *	Returns a 0 on success
++ *
++ * Algorithm:
++ *	(1) see if the high byte of BANK_SELECT is 0x33
++ * 	(2) compare the ioaddr with the base register's address
++ *	(3) see if I recognize the chip ID in the appropriate register
++ *
++ * Here I do typical initialization tasks.
++ *
++ * o  Initialize the structure if needed
++ * o  print out my vanity message if not done so already
++ * o  print out what type of hardware is detected
++ * o  print out the ethernet address
++ * o  find the IRQ
++ * o  set up my private data
++ * o  configure the dev structure with my subroutines
++ * o  actually GRAB the irq.
++ * o  GRAB the region
++ */
++static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
++			   unsigned long irq_flags)
++{
++	struct smc_local *lp = netdev_priv(dev);
++	static int version_printed = 0;
++	int retval;
++	unsigned int val, revision_register;
++	const char *version_string;
++	DECLARE_MAC_BUF(mac);
++
++	DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
++
++        if (!hwreg_present( ioaddr + BANK_SELECT )) {
++		retval = -ENODEV;
++		goto err_out;
++	}
++
++	/* First, see if the high byte is 0x33 */
++	val = SMC_CURRENT_BANK(lp);
++	DBG(2, "%s: bank signature probe returned 0x%04x\n", CARDNAME, val);
++	if ((val & 0xFF00) != 0x3300) {
++		if ((val & 0xFF) == 0x33) {
++			printk(KERN_WARNING
++				"%s: Detected possible byte-swapped interface"
++				" at IOADDR %p\n", CARDNAME, ioaddr);
++		}
++		retval = -ENODEV;
++		goto err_out;
++	}
++
++	/*
++	 * The above MIGHT indicate a device, but I need to write to
++	 * further test this.
++	 */
++	SMC_SELECT_BANK(lp, 0);
++	val = SMC_CURRENT_BANK(lp);
++	if ((val & 0xFF00) != 0x3300) {
++		retval = -ENODEV;
++		goto err_out;
++	}
++
++	/*
++	 * well, we've already written once, so hopefully another
++	 * time won't hurt.  This time, I need to switch the bank
++	 * register to bank 1, so I can access the base address
++	 * register
++	 */
++	SMC_SELECT_BANK(lp, 1);
++	val = SMC_GET_BASE(lp);
++	val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT;
++	if (((unsigned int)ioaddr & (0x3e0 << SMC_IO_SHIFT)) != val) {
++		printk("%s: IOADDR %p doesn't match configuration (%x).\n",
++			CARDNAME, ioaddr, val);
++	}
++
++	/*
++	 * check if the revision register is something that I
++	 * recognize.  These might need to be added to later,
++	 * as future revisions could be added.
++	 */
++	SMC_SELECT_BANK(lp, 3);
++	revision_register = SMC_GET_REV(lp);
++	DBG(2, "%s: revision = 0x%04x\n", CARDNAME, revision_register);
++	version_string = chip_ids[ (revision_register >> 4) & 0xF];
++	if (!version_string || (revision_register & 0xff00) != 0x3300) {
++		/* I don't recognize this chip, so... */
++		printk("%s: IO %p: Unrecognized revision register 0x%04x"
++			", Contact author.\n", CARDNAME,
++			ioaddr, revision_register);
++
++		retval = -ENODEV;
++		goto err_out;
++	}
++
++	/* At this point I'll assume that the chip is an SMC91x. */
++	if (version_printed++ == 0)
++		printk("%s", version);
++
++	/* fill in some of the fields */
++	dev->base_addr = (unsigned long)ioaddr;
++	lp->base = ioaddr;
++	lp->version = revision_register & 0xff;
++	spin_lock_init(&lp->lock);
++
++	/* Get the MAC address */
++	SMC_SELECT_BANK(lp, 1);
++	SMC_GET_MAC_ADDR(lp, dev->dev_addr);
++
++	/* now, reset the chip, and put it into a known state */
++	smc_reset(dev);
++
++	/*
++	 * If dev->irq is 0, then the device has to be banged on to see
++	 * what the IRQ is.
++ 	 *
++	 * This banging doesn't always detect the IRQ, for unknown reasons.
++	 * a workaround is to reset the chip and try again.
++	 *
++	 * Interestingly, the DOS packet driver *SETS* the IRQ on the card to
++	 * be what is requested on the command line.   I don't do that, mostly
++	 * because the card that I have uses a non-standard method of accessing
++	 * the IRQs, and because this _should_ work in most configurations.
++	 *
++	 * Specifying an IRQ is done with the assumption that the user knows
++	 * what (s)he is doing.  No checking is done!!!!
++	 */
++	if (dev->irq < 1) {
++		int trials;
++
++		trials = 3;
++		while (trials--) {
++			dev->irq = smc_findirq(lp);
++			if (dev->irq)
++				break;
++			/* kick the card and try again */
++			smc_reset(dev);
++		}
++	}
++	if (dev->irq == 0) {
++		printk("%s: Couldn't autodetect your IRQ. Use irq=xx.\n",
++			dev->name);
++		retval = -ENODEV;
++		goto err_out;
++	}
++	dev->irq = irq_canonicalize(dev->irq);
++
++	/* Fill in the fields of the device structure with ethernet values. */
++	ether_setup(dev);
++
++	dev->open = smc_open;
++	dev->stop = smc_close;
++	dev->hard_start_xmit = smc_hard_start_xmit;
++	dev->tx_timeout = smc_timeout;
++	dev->watchdog_timeo = msecs_to_jiffies(watchdog);
++	dev->set_multicast_list = smc_set_multicast_list;
++	dev->ethtool_ops = &smc_ethtool_ops;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	dev->poll_controller = smc_poll_controller;
++#endif
++
++	tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
++	INIT_WORK(&lp->phy_configure, smc_phy_configure);
++	lp->dev = dev;
++	lp->mii.phy_id_mask = 0x1f;
++	lp->mii.reg_num_mask = 0x1f;
++	lp->mii.force_media = 0;
++	lp->mii.full_duplex = 0;
++	lp->mii.dev = dev;
++	lp->mii.mdio_read = smc_phy_read;
++	lp->mii.mdio_write = smc_phy_write;
++
++	/*
++	 * Locate the phy, if any.
++	 */
++	if (lp->version >= (CHIP_91100 << 4))
++		smc_phy_detect(dev);
++
++	/* then shut everything down to save power */
++	smc_shutdown(dev);
++	smc_phy_powerdown(dev);
++
++	/* Set default parameters */
++	lp->msg_enable = NETIF_MSG_LINK;
++	lp->ctl_rfduplx = 0;
++	lp->ctl_rspeed = 10;
++
++	if (lp->version >= (CHIP_91100 << 4)) {
++		lp->ctl_rfduplx = 1;
++		lp->ctl_rspeed = 100;
++	}
++
++	/* Grab the IRQ */
++      	retval = request_irq(dev->irq, &smc_interrupt, irq_flags, dev->name, dev);
++      	if (retval) {
++      		use_poll = 1;
++      		//goto err_out;
++	}
++
++#ifdef SMC_USE_PXA_DMA
++	{
++		int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW,
++					  smc_pxa_dma_irq, NULL);
++		if (dma >= 0)
++			dev->dma = dma;
++	}
++#endif
++
++	retval = register_netdev(dev);
++	if (retval == 0) {
++		/* now, print out the card info, in a short format.. */
++		printk("%s: %s (rev %d) at %p IRQ %d",
++			dev->name, version_string, revision_register & 0x0f,
++			lp->base, dev->irq);
++
++		if (dev->dma != (unsigned char)-1)
++			printk(" DMA %d", dev->dma);
++
++		printk("%s%s\n", nowait ? " [nowait]" : "",
++			THROTTLE_TX_PKTS ? " [throttle_tx]" : "");
++
++		if (!is_valid_ether_addr(dev->dev_addr)) {
++			printk("%s: Invalid ethernet MAC address.  Please "
++			       "set proper address using ifconfig\n", dev->name);
++			random_ether_addr(dev->dev_addr);
++			printk("%s: Ethernet addr (random): %s\n",
++			       dev->name, print_mac(mac, dev->dev_addr));
++		} else {
++			/* Print the Ethernet address */
++			printk("%s: Ethernet addr: %s\n",
++			       dev->name, print_mac(mac, dev->dev_addr));
++		}
++
++		if (lp->phy_type == 0) {
++			PRINTK("%s: No PHY found\n", dev->name);
++		} else if ((lp->phy_type & 0xfffffff0) == 0x0016f840) {
++			PRINTK("%s: PHY LAN83C183 (LAN91C111 Internal)\n", dev->name);
++		} else if ((lp->phy_type & 0xfffffff0) == 0x02821c50) {
++			PRINTK("%s: PHY LAN83C180\n", dev->name);
++		}
++
++		if (SMC_32BIT(lp)) {
++			printk("%s: using 32 bit access\n", dev->name);
++		} else if (SMC_16BIT(lp)) {
++			printk("%s: using 16 bit access\n", dev->name);
++		} else {
++			printk("%s: using 8 bit access\n", dev->name);
++		}
++
++	}
++
++err_out:
++#ifdef SMC_USE_PXA_DMA
++	if (retval && dev->dma != (unsigned char)-1)
++		pxa_free_dma(dev->dma);
++#endif
++	return retval;
++}
++
++static int smc_enable_device(struct platform_device *pdev)
++{
++	struct net_device *ndev = platform_get_drvdata(pdev);
++	struct smc_local *lp = netdev_priv(ndev);
++	unsigned long flags;
++	unsigned char ecor, ecsr;
++	void __iomem *addr;
++	struct resource * res;
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
++	if (!res) {
++		printk("smc_enable_device: smc91x-attrib resource not found !\n");
++		return 0;
++	}
++
++        printk("smc_enable_device: smc91x-attrib resource found, start=%x !\n", res->start);
++
++	/*
++	 * Map the attribute space.  This is overkill, but clean.
++	 */
++	addr = ioremap(res->start, ATTRIB_SIZE);
++	if (!addr) {
++		return -ENOMEM;
++	} 
++
++        printk("smc_enable_device :smc91x-attrib resource remapped, start=%p !\n", addr);
++
++        /*
++	 * Reset the device.  We must disable IRQs around this
++	 * since a reset causes the IRQ line become active.
++	 */
++	local_irq_save(flags);
++	ecor = readb(addr + (ECOR << SMC_IO_SHIFT)) & ~ECOR_RESET;
++	writeb(ecor | ECOR_RESET, addr + (ECOR << SMC_IO_SHIFT));
++	readb(addr + (ECOR << SMC_IO_SHIFT));
++
++	/*
++	 * Wait 100us for the chip to reset.
++	 */
++	udelay(100);
++
++	/*
++	 * The device will ignore all writes to the enable bit while
++	 * reset is asserted, even if the reset bit is cleared in the
++	 * same write.  Must clear reset first, then enable the device.
++	 */
++	writeb(ecor, addr + (ECOR << SMC_IO_SHIFT));
++	writeb(ecor | ECOR_ENABLE, addr + (ECOR << SMC_IO_SHIFT));
++
++	/*
++	 * Set the appropriate byte/word mode.
++	 */
++	ecsr = readb(addr + (ECSR << SMC_IO_SHIFT)) & ~ECSR_IOIS8;
++	if (!SMC_16BIT(lp))
++		ecsr |= ECSR_IOIS8;
++	writeb(ecsr, addr + (ECSR << SMC_IO_SHIFT));
++	local_irq_restore(flags);
++
++	iounmap(addr);
++
++	/*
++	 * Wait for the chip to wake up.  We could poll the control
++	 * register in the main register space, but that isn't mapped
++	 * yet.  We know this is going to take 750us.
++	 */
++	msleep(1);
++
++	return 0;
++}
++
++static int smc_request_attrib(struct platform_device *pdev)
++{
++	struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
++
++	if (!res)
++		return 0;
++
++	if (!request_mem_region(res->start, ATTRIB_SIZE, CARDNAME)) {
++		return -EBUSY;
++	}
++	
++	return 0;
++}
++
++static void smc_release_attrib(struct platform_device *pdev)
++{
++	struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
++
++	if (res)
++		release_mem_region(res->start, ATTRIB_SIZE);
++}
++
++static inline void smc_request_datacs(struct platform_device *pdev, struct net_device *ndev)
++{
++	if (SMC_CAN_USE_DATACS) {
++		struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
++		struct smc_local *lp = netdev_priv(ndev);
++
++		if (!res)
++			return;
++
++		if(!request_mem_region(res->start, SMC_DATA_EXTENT, CARDNAME)) {
++			printk(KERN_INFO "%s: failed to request datacs memory region.\n", CARDNAME);
++			return;
++		}
++
++		lp->datacs = ioremap(res->start, SMC_DATA_EXTENT);
++	}
++}
++
++static void smc_release_datacs(struct platform_device *pdev, struct net_device *ndev)
++{
++	if (SMC_CAN_USE_DATACS) {
++		struct smc_local *lp = netdev_priv(ndev);
++		struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-data32");
++
++		if (lp->datacs)
++			iounmap(lp->datacs);
++
++		lp->datacs = NULL;
++
++		if (res)
++			release_mem_region(res->start, SMC_DATA_EXTENT);
++	}
++}
++
++/*
++ * Resources defined and added to platform data in arch/m68k/atari/config.c
++ * These are left here for reference only!
++ */
++
++struct resource ethernat_attr = {
++	.start	= 0x80000000,
++	.end	= 0x800000FF,
++	.name	= "smc91x-attrib",
++	.flags	= IORESOURCE_MEM
++};
++
++struct resource ethernat_datacs = {
++	.start	= 0,
++	.end	= 0,
++	.name	= "smc91x-data32",
++	.flags	= IORESOURCE_MEM
++};
++
++/*
++ * smc_init(void)
++ *   Input parameters:
++ *	dev->base_addr == 0, try to find all possible locations
++ *	dev->base_addr > 0x1ff, this is the address to check
++ *	dev->base_addr == <anything else>, return failure code
++ *
++ *   Output:
++ *	0 --> there is a device
++ *	anything else, error
++ */
++
++static int __init atari_ethernat_pdev_probe(struct platform_device *pdev)
++{
++	struct smc91x_platdata *pd = pdev->dev.platform_data;
++	struct smc_local *lp;
++	struct net_device *ndev;
++	struct resource *res, *ires;
++	unsigned int __iomem *addr;
++	int ret;
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
++	if (!res)
++		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		printk("smc91x-regs resource not found!\n");
++		ret = -ENODEV;
++		goto out;
++	}
++
++	printk("smc91x-regs resource found, start=%x !\n", res->start);
++
++	if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
++		printk("could not request smc91x-regs resource at %ul!\n", res->start);
++		ret = -EBUSY;
++		goto out;
++	}
++
++	ndev = alloc_etherdev(sizeof(struct smc_local));
++	if (!ndev) {
++		printk("%s: could not allocate device.\n", CARDNAME);
++		ret = -ENOMEM;
++		goto out_release_io;
++	}
++	SET_NETDEV_DEV(ndev, &pdev->dev);
++
++	/* get configuration from platform data, only allow use of
++	 * bus width if both SMC_CAN_USE_xxx and SMC91X_USE_xxx are set.
++	 */
++
++	lp = netdev_priv(ndev);
++	lp->cfg.irq_flags = SMC_IRQ_FLAGS;
++
++#ifdef SMC_DYNAMIC_BUS_CONFIG
++	if (pd)
++		memcpy(&lp->cfg, pd, sizeof(lp->cfg));
++	else {
++		lp->cfg.flags = SMC91X_USE_8BIT;  
++		lp->cfg.flags |= SMC91X_USE_16BIT;
++		lp->cfg.flags |= SMC91X_USE_32BIT;
++	}
++
++	lp->cfg.flags &= ~(SMC_CAN_USE_8BIT ? 0 : SMC91X_USE_8BIT);  
++	lp->cfg.flags &= ~(SMC_CAN_USE_16BIT ? 0 : SMC91X_USE_16BIT);
++	lp->cfg.flags &= ~(SMC_CAN_USE_32BIT ? 0 : SMC91X_USE_32BIT);
++#endif
++
++	ndev->dma = (unsigned char)-1;
++
++	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++	if (!ires) {
++		printk("atari_91C111: IRQ resource not found!\n");
++		ret = -ENODEV;
++		goto out_free_netdev;
++	}
++
++	ndev->irq = ires->start;
++	printk("atari_91C111: IRQ resource specified irq=%d\n", ndev->irq);
++
++	/*
++	 * 080720 MSch: testing timer based interrupts - need to set valid
++	 *		interrupt here or request_irq bails out.
++	 *		polling (use_poll == 1) not tested so far
++	 *		Ultimately, this needs to be set in the platform device
++	 *		data, or be overridden by module arguments
++	 *		The actual level6 interrupt is hardwired to vector
++	 *		0xc4 according to the MiNT driver source. Interrupts 
++	 *		are enabled for the device by setting bit 1 at base+0x20
++	 *		or base+0x23!
++	 */
++	ndev->irq = IRQ_MFP_TIMD;
++	ires->start = IRQ_MFP_TIMD;
++	printk("atari_91C111: IRQ forced to irq=%d\n", ndev->irq);
++
++	if (SMC_IRQ_FLAGS == -1)
++		lp->cfg.irq_flags = ires->flags & IRQF_TRIGGER_MASK;
++
++	if (ndev->irq < 0) {
++		printk("atari_91C111: cannot determine interrupt! Using timer D poll...\n");
++		ndev->irq = IRQ_MFP_TIMD;
++		/* timer actually set up later */
++	}
++
++	if (ndev->irq == IRQ_MFP_TIMD) {
++		printk("atari_91C111: Using timer D interrupt - do share!\n");
++		lp->cfg.irq_flags = IRQF_SHARED;
++	}
++
++	ret = smc_request_attrib(pdev);
++	if (ret) {
++		printk("atari_91C111: attrib resource not found!\n");
++		goto out_free_netdev;
++	}
++#if defined(CONFIG_SA1100_ASSABET)
++	NCR_0 |= NCR_ENET_OSC_EN;
++#endif
++	platform_set_drvdata(pdev, ndev);
++	ret = smc_enable_device(pdev);
++	if (ret) {
++		printk("atari_91C111: failed to enable card!\n");
++		goto out_release_attrib;
++	}
++
++	addr = ioremap(res->start, SMC_IO_EXTENT);
++	if (!addr) {
++		ret = -ENOMEM;
++		goto out_release_attrib;
++	}
++
++#ifdef SMC_USE_PXA_DMA
++	{
++		struct smc_local *lp = netdev_priv(ndev);
++		lp->device = &pdev->dev;
++		lp->physaddr = res->start;
++	}
++#endif
++
++	printk("smc91x-regs resource remapped, start=%p!\n", addr);
++
++	/*
++	 * about to probe for device; need to enable net IRQ here!
++	 * EtherNAT has interrupt enable register at 0x20 or 0x23 
++	 * probe for base address + 0x23 or 0x20
++	 */
++
++	ret = smc_probe(ndev, addr, lp->cfg.irq_flags);
++	if (ret != 0)
++		goto out_iounmap;
++
++	printk("smc91x probe done, irq %d!\n", ndev->irq);
++	ndev->irq = IRQ_MFP_TIMD;
++
++	if (ndev->irq < 0) {
++		if (use_poll)
++			atari_ethernat_start_poll(ndev);
++	} else if (ndev->irq == IRQ_MFP_TIMD) {
++        	/* maybe instead use MFP timer C ?? */
++		/* init timer if not already running */
++		/* set Timer D data Register */
++		mfp.tim_dt_d = 123;	/* 200 Hz */
++		/* start timer D, div = 1:100 */
++		mfp.tim_ct_cd = (mfp.tim_ct_cd & 0xf0) | 0x6;
++	}
++
++	smc_request_datacs(pdev, ndev);
++
++	return 0;
++
++ out_iounmap:
++	platform_set_drvdata(pdev, NULL);
++	iounmap(addr);
++ out_release_attrib:
++	smc_release_attrib(pdev);
++ out_free_netdev:
++	free_netdev(ndev);
++ out_release_io:
++	release_mem_region(res->start, SMC_IO_EXTENT);
++ out:
++	printk("%s: not found (%d).\n", CARDNAME, ret);
++
++	return ret;
++}
++
++static int smc_drv_remove(struct platform_device *pdev)
++{
++	struct net_device *ndev = platform_get_drvdata(pdev);
++	struct smc_local *lp = netdev_priv(ndev);
++	struct resource *res;
++
++	platform_set_drvdata(pdev, NULL);
++
++	if (use_poll)
++		atari_ethernat_stop_poll(ndev);
++
++	unregister_netdev(ndev);
++
++	free_irq(ndev->irq, ndev);
++
++#ifdef SMC_USE_PXA_DMA
++	if (ndev->dma != (unsigned char)-1)
++		pxa_free_dma(ndev->dma);
++#endif
++	iounmap(lp->base);
++
++	smc_release_datacs(pdev,ndev);
++	smc_release_attrib(pdev);
++
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
++	if (!res)
++		platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	release_mem_region(res->start, SMC_IO_EXTENT);
++
++	free_netdev(ndev);
++
++	return 0;
++}
++
++static int smc_drv_suspend(struct platform_device *dev, pm_message_t state)
++{
++	struct net_device *ndev = platform_get_drvdata(dev);
++
++	if (ndev) {
++		if (netif_running(ndev)) {
++			netif_device_detach(ndev);
++			smc_shutdown(ndev);
++			smc_phy_powerdown(ndev);
++		}
++	}
++	return 0;
++}
++
++static int smc_drv_resume(struct platform_device *dev)
++{
++	struct net_device *ndev = platform_get_drvdata(dev);
++
++	if (ndev) {
++		struct smc_local *lp = netdev_priv(ndev);
++		smc_enable_device(dev);
++		if (netif_running(ndev)) {
++			smc_reset(ndev);
++			smc_enable(ndev);
++			if (lp->phy_type != 0)
++				smc_phy_configure(&lp->phy_configure);
++			netif_device_attach(ndev);
++		}
++	}
++	return 0;
++}
++
++static struct platform_driver smc_driver = {
++	.probe		= atari_ethernat_pdev_probe,
++	.remove		= smc_drv_remove,
++	.suspend	= smc_drv_suspend,
++	.resume		= smc_drv_resume,
++	.driver		= {
++		.name	= CARDNAME,
++	},
++};
++
++static int __init smc_init(void)
++{
++	if (!MACH_IS_ATARI)
++		return -ENODEV;
++
++#ifdef MODULE
++#ifdef CONFIG_ISA
++	if (io == -1)
++		printk(KERN_WARNING
++			"%s: You shouldn't use auto-probing with insmod!\n",
++			CARDNAME);
++#endif
++#endif
++
++	return platform_driver_register(&smc_driver);
++}
++
++static void __exit smc_cleanup(void)
++{
++	platform_driver_unregister(&smc_driver);
++}
++
++module_init(smc_init);
++module_exit(smc_cleanup);
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0007-m68k-Atari-EtherNAT-updates.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0007-m68k-Atari-EtherNAT-updates.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,1014 @@
+From 6df6693c1c560901e1c807268501e32de474ede8 Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at biophys.uni-duesseldorf.de>
+Date: Tue, 18 Nov 2008 21:07:40 +0100
+Subject: [PATCH] m68k: Atari EtherNAT updates
+
+Here's my EtherNAT update (goes on top of your patch queue as of Oct. 18),
+fixing the various compile errors and generally cleaning up the patch. This
+brings the EtherNAT driver in sync with smc91x.c again (actually, I started
+from a clean slate and patched in only the bare essentials).
+
+Works OK, and can be trimmed a bit further if I preset the interrupt to timer
+D in the platform code. Should be replaced by smc91x.c altogether once I have
+real interrupts sorted. How's that for a perspective?
+
+Signed-off-by: Michael Schmitz <schmitz at debian.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/net/atari_91C111.c |  404 +++++++++++++++----------------------------
+ drivers/net/smc91x.h       |   61 +++++++
+ 2 files changed, 202 insertions(+), 263 deletions(-)
+
+diff --git a/drivers/net/atari_91C111.c b/drivers/net/atari_91C111.c
+index 9b87d04..f6f8a45 100644
+--- a/drivers/net/atari_91C111.c
++++ b/drivers/net/atari_91C111.c
+@@ -60,8 +60,6 @@
+ static const char version[] =
+ 	"smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico at cam.org>\n";
+ 
+-#define SMC_DEBUG 1
+-
+ /* Debugging level */
+ #ifndef SMC_DEBUG
+ #define SMC_DEBUG		0
+@@ -106,7 +104,7 @@ static unsigned int smc_portlist[] __initdata = {
+ 	0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0
+ };
+ 
+-#endif  /* CONFIG_ISA */
++/* MSch FIXME: endif CONFIG_ISA here? */
+ 
+ #ifndef SMC_IOADDR
+ # define SMC_IOADDR		-1
+@@ -122,6 +120,7 @@ static int irq = SMC_IRQ;
+ module_param(irq, int, 0400);
+ MODULE_PARM_DESC(irq, "IRQ number");
+ 
++#endif  /* CONFIG_ISA */
+ 
+ #ifndef SMC_NOWAIT
+ # define SMC_NOWAIT		0
+@@ -172,7 +171,7 @@ MODULE_ALIAS("platform:smc91x");
+  * but to the expense of reduced TX throughput and increased IRQ overhead.
+  * Note this is not a cure for a too slow data bus or too high IRQ latency.
+  */
+-#define THROTTLE_TX_PKTS	1
++#define THROTTLE_TX_PKTS	0	/* MSch FIXME 1 */
+ 
+ /*
+  * The MII clock high/low times.  2x this number gives the MII clock period
+@@ -227,7 +226,7 @@ static void PRINT_PKT(u_char *buf, int length)
+ 
+ 
+ /* this enables an interrupt in the interrupt mask register */
+-#define SMC_ENABLE_INT(lp, x) do {						\
++#define SMC_ENABLE_INT(lp, x) do {					\
+ 	unsigned char mask;						\
+ 	spin_lock_irq(&lp->lock);					\
+ 	mask = SMC_GET_INT_MASK(lp);					\
+@@ -237,7 +236,7 @@ static void PRINT_PKT(u_char *buf, int length)
+ } while (0)
+ 
+ /* this disables an interrupt from the interrupt mask register */
+-#define SMC_DISABLE_INT(lp, x) do {						\
++#define SMC_DISABLE_INT(lp, x) do {					\
+ 	unsigned char mask;						\
+ 	spin_lock_irq(&lp->lock);					\
+ 	mask = SMC_GET_INT_MASK(lp);					\
+@@ -252,9 +251,9 @@ static void PRINT_PKT(u_char *buf, int length)
+  * decides to go south.
+  */
+ #define SMC_WAIT_MMU_BUSY(lp) do {					\
+-	if (unlikely(SMC_GET_MMU_CMD(lp) & MC_BUSY)) {			\
++	if (unlikely(SMC_GET_MMU_CMD(lp) & MC_BUSY)) {		\
+ 		unsigned long timeout = jiffies + 2;			\
+-		while (SMC_GET_MMU_CMD(lp) & MC_BUSY) {			\
++		while (SMC_GET_MMU_CMD(lp) & MC_BUSY) {		\
+ 			if (time_after(jiffies, timeout)) {		\
+ 				printk("%s: timeout %s line %d\n",	\
+ 					dev->name, __FILE__, __LINE__);	\
+@@ -266,70 +265,25 @@ static void PRINT_PKT(u_char *buf, int length)
+ } while (0)
+ 
+ /*
+- * Timer based operation on Atari
+- */
+-static irqreturn_t smc_interrupt(int irq, void *dev_id);
+-
+-static int use_poll = 0;
+-module_param(use_poll, int, 0);
+-MODULE_PARM_DESC(use_poll, "Use scheduling timer to poll driver");
+-
+-/* This is used by cleanup, to prevent the module from being unloaded while
+- * intrpt_routine is still in the task queue
++ * MSch: Interrupt wrapper to prevent calling the main interrupt handler
++ *       from MFP timer D routine before device has been opened.
+  */
+-static wait_queue_head_t WaitQ;
+-
+-static struct delayed_work tqueue;
+ 
+-static struct net_device *poll_dev = NULL;
++static irqreturn_t smc_interrupt(int irq, void *dev_id);
+ 
+-static void atari_ethernat_int(struct work_struct *work)
++static irqreturn_t atari_ethernat_interrupt(int irq, void *dev_id)
+ {
+-	struct net_device *dev  = poll_dev;
+-
+-        if(!dev) {
+-	        /* If cleanup wants us to die */
+-                if (waitqueue_active(&WaitQ))
+-                  wake_up(&WaitQ);               /* Now cleanup_module can return */
+-                else
+-                  /* Put ourselves back in the task queue */
+-                  schedule_delayed_work(&tqueue, 1);
+-		return;
+-        }
+-
+-        /* This actually does not appear to work during probe */
++	struct net_device *dev = (struct net_device *) dev_id;
+ 	if (netif_running(dev)) {
+-		smc_interrupt(dev->irq, dev);
+-        }
+-
+-	/* If cleanup wants us to die */
+-	if (waitqueue_active(&WaitQ))
+-		wake_up(&WaitQ);               /* Now cleanup_module can return */
+-	else
+-		/* Put ourselves back in the task queue */
+-		schedule_delayed_work(&tqueue, 0); /* reduced delay from 1 */
+-}
+-
+-static void atari_ethernat_start_poll(struct net_device *dev)
+-{
+-	poll_dev = dev;
+-
+-	init_waitqueue_head(&WaitQ);
+-
+-	/* MSch: need to insert dev into work struct?? */
+-
+-	INIT_DELAYED_WORK(&tqueue, atari_ethernat_int);
+-	schedule_delayed_work(&tqueue, 1);
+-}
+-
+-static void atari_ethernat_stop_poll(struct net_device *dev)
+-{
+-	if (dev && (dev == poll_dev)) {
+-	        sleep_on(&WaitQ);
++		return smc_interrupt(dev->irq, dev);
+ 	}
+-	poll_dev = NULL;
++	return IRQ_HANDLED;
+ }
+ 
++static int period = 0;
++module_param(period, int, 0);
++MODULE_PARM_DESC(period, "Timer D period (123 for 200Hz)");
++
+ /*
+  * this does a soft reset on the device
+  */
+@@ -340,7 +294,7 @@ static void smc_reset(struct net_device *dev)
+ 	unsigned int ctl, cfg;
+ 	struct sk_buff *pending_skb;
+ 
+-	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(2, "%s: %s\n", dev->name, __func__);
+ 
+ 	/* Disable all interrupts, block TX tasklet */
+ 	spin_lock_irq(&lp->lock);
+@@ -378,7 +332,7 @@ static void smc_reset(struct net_device *dev)
+ 	 * can't handle it then there will be no recovery except for
+ 	 * a hard reset or power cycle
+ 	 */
+-	if (nowait)
++	if (lp->cfg.flags & SMC91X_NOWAIT)
+ 		cfg |= CONFIG_NO_WAIT;
+ 
+ 	/*
+@@ -433,7 +387,7 @@ static void smc_enable(struct net_device *dev)
+ 	void __iomem *ioaddr = lp->base;
+ 	int mask;
+ 
+-	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(2, "%s: %s\n", dev->name, __func__);
+ 
+ 	/* see the header file for options in TCR/RCR DEFAULT */
+ 	SMC_SELECT_BANK(lp, 0);
+@@ -467,7 +421,7 @@ static void smc_shutdown(struct net_device *dev)
+ 	void __iomem *ioaddr = lp->base;
+ 	struct sk_buff *pending_skb;
+ 
+-	DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
++	DBG(2, "%s: %s\n", CARDNAME, __func__);
+ 
+ 	/* no more interrupts for me */
+ 	spin_lock_irq(&lp->lock);
+@@ -500,7 +454,7 @@ static inline void  smc_rcv(struct net_device *dev)
+ 	void __iomem *ioaddr = lp->base;
+ 	unsigned int packet_number, status, packet_len;
+ 
+-	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(3, "%s: %s\n", dev->name, __func__);
+ 
+ 	packet_number = SMC_GET_RXFIFO(lp);
+ 	if (unlikely(packet_number & RXFIFO_REMPTY)) {
+@@ -635,44 +589,10 @@ static inline void  smc_rcv(struct net_device *dev)
+ #define smc_special_unlock(lock)	do { } while (0)
+ #endif
+ 
+-
+ /*
+- * MSch: EtherNAT is 32 bit, so the misaligned data buffer hack applies. 
+- * This appears to hurt quite a lot ... need to fudge with the data pointer
+- * to compensate
++ * MSch FIXME: add SMC_PUSH_DATA_BE(lp, p, l)
+  */
+ 
+-#define SMC_outw_be(v, a, r)	writew_be(v, (a) + (r))
+-
+-#define SMC_PUSH_DATA_BE(lp, p, l)					\
+-	do {								\
+-		if (SMC_32BIT(lp)) {				\
+-			void *__ptr = (p);				\
+-			int __len = (l);				\
+-			void __iomem *__ioaddr = ioaddr;		\
+-			if (__len >= 2 && (unsigned long)__ptr & 2) {	\
+-				__len -= 2;				\
+-				SMC_outw_be(*(u16 *)__ptr, ioaddr,		\
+-					DATA_REG(lp));		\
+-				__ptr += 2;				\
+-			}						\
+-			if (SMC_CAN_USE_DATACS && lp->datacs)		\
+-				__ioaddr = lp->datacs;			\
+-			SMC_outsl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
+-			if (__len & 2) {				\
+-				__ptr += (__len & ~3);			\
+-				SMC_outw_be(*((u16 *)__ptr), ioaddr,	\
+-					 DATA_REG(lp));		\
+-			}						\
+-		} else if (SMC_16BIT(lp))				\
+-			SMC_outsw(ioaddr, DATA_REG(lp), (u16 *) p, (l) >> 1);	\
+-		else if (SMC_8BIT(lp))				\
+-			SMC_outsb(ioaddr, DATA_REG(lp), p, l);	\
+-	} while (0)
+-
+-
+-
+-
+ /*
+  * This is called to actually send a packet to the chip.
+  */
+@@ -685,7 +605,7 @@ static void smc_hardware_send_pkt(unsigned long data)
+ 	unsigned int packet_no, len;
+ 	unsigned char *buf;
+ 
+-	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(3, "%s: %s\n", dev->name, __func__);
+ 
+ 	if (!smc_special_trylock(&lp->lock)) {
+ 		netif_stop_queue(dev);
+@@ -726,7 +646,7 @@ static void smc_hardware_send_pkt(unsigned long data)
+ 	SMC_PUT_PKT_HDR(lp, 0, len + 6);
+ 
+ 	/* send the actual data */
+-	SMC_PUSH_DATA_BE(lp, buf, len & ~1);
++	SMC_PUSH_DATA(lp, buf, len & ~1);
+ 
+ 	/* Send final ctl word with the last byte if there is one */
+ 	SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG(lp));
+@@ -770,7 +690,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	void __iomem *ioaddr = lp->base;
+ 	unsigned int numPages, poll_count, status;
+ 
+-	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(3, "%s: %s\n", dev->name, __func__);
+ 
+ 	BUG_ON(lp->pending_tx_skb != NULL);
+ 
+@@ -842,7 +762,7 @@ static void smc_tx(struct net_device *dev)
+ 	void __iomem *ioaddr = lp->base;
+ 	unsigned int saved_packet, packet_no, tx_status, pkt_len;
+ 
+-	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(3, "%s: %s\n", dev->name, __func__);
+ 
+ 	/* If the TX FIFO is empty then nothing to do */
+ 	packet_no = SMC_GET_TXFIFO(lp);
+@@ -964,7 +884,7 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
+ 	SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO));
+ 
+ 	DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
+-		__FUNCTION__, phyaddr, phyreg, phydata);
++		__func__, phyaddr, phyreg, phydata);
+ 
+ 	SMC_SELECT_BANK(lp, 2);
+ 	return phydata;
+@@ -991,7 +911,7 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
+ 	SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO));
+ 
+ 	DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
+-		__FUNCTION__, phyaddr, phyreg, phydata);
++		__func__, phyaddr, phyreg, phydata);
+ 
+ 	SMC_SELECT_BANK(lp, 2);
+ }
+@@ -1004,7 +924,7 @@ static void smc_phy_detect(struct net_device *dev)
+ 	struct smc_local *lp = netdev_priv(dev);
+ 	int phyaddr;
+ 
+-	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(2, "%s: %s\n", dev->name, __func__);
+ 
+ 	lp->phy_type = 0;
+ 
+@@ -1043,7 +963,7 @@ static int smc_phy_fixed(struct net_device *dev)
+ 	int phyaddr = lp->mii.phy_id;
+ 	int bmcr, cfg1;
+ 
+-	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(3, "%s: %s\n", dev->name, __func__);
+ 
+ 	/* Enter Link Disable state */
+ 	cfg1 = smc_phy_read(dev, phyaddr, PHY_CFG1_REG);
+@@ -1276,7 +1196,7 @@ static void smc_phy_interrupt(struct net_device *dev)
+ 	int phyaddr = lp->mii.phy_id;
+ 	int phy18;
+ 
+-	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(2, "%s: %s\n", dev->name, __func__);
+ 
+ 	if (lp->phy_type == 0)
+ 		return;
+@@ -1344,7 +1264,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
+ 	int status, mask, timeout, card_stats;
+ 	int saved_pointer;
+ 
+-	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(3, "%s: %s\n", dev->name, __func__);
+ 
+ 	spin_lock(&lp->lock);
+ 
+@@ -1363,7 +1283,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
+ 	do {
+ 		status = SMC_GET_INT(lp);
+ 
+-		DBG(3, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
++		DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
+ 			dev->name, status, mask,
+ 			({ int meminfo; SMC_SELECT_BANK(lp, 0);
+ 			   meminfo = SMC_GET_MIR(lp);
+@@ -1376,20 +1296,20 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
+ 
+ 		if (status & IM_TX_INT) {
+ 			/* do this before RX as it will free memory quickly */
+-			DBG(2, "%s: TX int\n", dev->name);
++			DBG(3, "%s: TX int\n", dev->name);
+ 			smc_tx(dev);
+ 			SMC_ACK_INT(lp, IM_TX_INT);
+ 			if (THROTTLE_TX_PKTS)
+ 				netif_wake_queue(dev);
+ 		} else if (status & IM_RCV_INT) {
+-			DBG(2, "%s: RX irq\n", dev->name);
++			DBG(3, "%s: RX irq\n", dev->name);
+ 			smc_rcv(dev);
+ 		} else if (status & IM_ALLOC_INT) {
+-			DBG(1, "%s: Allocation irq\n", dev->name);
++			DBG(3, "%s: Allocation irq\n", dev->name);
+ 			tasklet_hi_schedule(&lp->tx_task);
+ 			mask &= ~IM_ALLOC_INT;
+ 		} else if (status & IM_TX_EMPTY_INT) {
+-			DBG(2, "%s: TX empty\n", dev->name);
++			DBG(3, "%s: TX empty\n", dev->name);
+ 			mask &= ~IM_TX_EMPTY_INT;
+ 
+ 			/* update stats */
+@@ -1407,15 +1327,13 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
+ 			DBG(1, "%s: RX overrun (EPH_ST 0x%04x)\n", dev->name,
+ 			       ({ int eph_st; SMC_SELECT_BANK(lp, 0);
+ 				  eph_st = SMC_GET_EPH_STATUS(lp);
+-				  SMC_SELECT_BANK(lp, 2); eph_st; }) );
++				  SMC_SELECT_BANK(lp, 2); eph_st; }));
+ 			SMC_ACK_INT(lp, IM_RX_OVRN_INT);
+ 			dev->stats.rx_errors++;
+ 			dev->stats.rx_fifo_errors++;
+ 		} else if (status & IM_EPH_INT) {
+-			DBG(1, "%s: eph interrupt\n", dev->name);
+ 			smc_eph_interrupt(dev);
+ 		} else if (status & IM_MDINT) {
+-			DBG(1, "%s: phy interrupt\n", dev->name);
+ 			SMC_ACK_INT(lp, IM_MDINT);
+ 			smc_phy_interrupt(dev);
+ 		} else if (status & IM_ERCV_INT) {
+@@ -1430,12 +1348,10 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
+ 	spin_unlock(&lp->lock);
+ 
+ #ifndef CONFIG_NET_POLL_CONTROLLER
+-#if 0
+-	if (timeout == MAX_IRQ_LOOPS)
++	if (timeout == MAX_IRQ_LOOPS && dev->irq != IRQ_MFP_TIMD)
+ 		PRINTK("%s: spurious interrupt (mask = 0x%02x)\n",
+ 		       dev->name, mask);
+ #endif
+-#endif
+ 	DBG(3, "%s: Interrupt done (%d loops)\n",
+ 	       dev->name, MAX_IRQ_LOOPS - timeout);
+ 
+@@ -1470,7 +1386,7 @@ static void smc_timeout(struct net_device *dev)
+ 	void __iomem *ioaddr = lp->base;
+ 	int status, mask, eph_st, meminfo, fifo;
+ 
+-	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(2, "%s: %s\n", dev->name, __func__);
+ 
+ 	spin_lock_irq(&lp->lock);
+ 	status = SMC_GET_INT(lp);
+@@ -1493,7 +1409,7 @@ static void smc_timeout(struct net_device *dev)
+ 	 * smc_phy_configure() calls msleep() which calls schedule_timeout()
+ 	 * which calls schedule().  Hence we use a work queue.
+ 	 */
+-	if (lp->phy_type != 0) 
++	if (lp->phy_type != 0)
+ 		schedule_work(&lp->phy_configure);
+ 
+ 	/* We can accept TX packets again */
+@@ -1514,7 +1430,7 @@ static void smc_set_multicast_list(struct net_device *dev)
+ 	unsigned char multicast_table[8];
+ 	int update_multicast = 0;
+ 
+-	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(2, "%s: %s\n", dev->name, __func__);
+ 
+ 	if (dev->flags & IFF_PROMISC) {
+ 		DBG(2, "%s: RCR_PRMS\n", dev->name);
+@@ -1617,7 +1533,7 @@ smc_open(struct net_device *dev)
+ {
+ 	struct smc_local *lp = netdev_priv(dev);
+ 
+-	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(2, "%s: %s\n", dev->name, __func__);
+ 
+ 	/*
+ 	 * Check that the address is valid.  If its not, refuse
+@@ -1625,14 +1541,16 @@ smc_open(struct net_device *dev)
+ 	 * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
+ 	 */
+ 	if (!is_valid_ether_addr(dev->dev_addr)) {
+-		PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__);
++		PRINTK("%s: no valid ethernet hw addr\n", __func__);
+ 		return -EINVAL;
+ 	}
+ 
+ 	/* Setup the default Register Modes */
+ 	lp->tcr_cur_mode = TCR_DEFAULT;
+ 	lp->rcr_cur_mode = RCR_DEFAULT;
+-	lp->rpc_cur_mode = RPC_DEFAULT;
++	lp->rpc_cur_mode = RPC_DEFAULT |
++				lp->cfg.leda << RPC_LSXA_SHFT |
++				lp->cfg.ledb << RPC_LSXB_SHFT;
+ 
+ 	/*
+ 	 * If we are not using a MII interface, we need to
+@@ -1669,7 +1587,7 @@ static int smc_close(struct net_device *dev)
+ {
+ 	struct smc_local *lp = netdev_priv(dev);
+ 
+-	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
++	DBG(2, "%s: %s\n", dev->name, __func__);
+ 
+ 	netif_stop_queue(dev);
+ 	netif_carrier_off(dev);
+@@ -1812,7 +1730,7 @@ static int __init smc_findirq(struct smc_local *lp)
+ 	int timeout = 20;
+ 	unsigned long cookie;
+ 
+-	DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
++	DBG(2, "%s: %s\n", CARDNAME, __func__);
+ 
+ 	cookie = probe_irq_on();
+ 
+@@ -1881,7 +1799,7 @@ static int __init smc_findirq(struct smc_local *lp)
+  * o  GRAB the region
+  */
+ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
+-			   unsigned long irq_flags)
++			    unsigned long irq_flags)
+ {
+ 	struct smc_local *lp = netdev_priv(dev);
+ 	static int version_printed = 0;
+@@ -1890,8 +1808,9 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
+ 	const char *version_string;
+ 	DECLARE_MAC_BUF(mac);
+ 
+-	DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
++	DBG(2, "%s: %s\n", CARDNAME, __func__);
+ 
++	/* First, see if there is a card at the expected address! */
+         if (!hwreg_present( ioaddr + BANK_SELECT )) {
+ 		retval = -ENODEV;
+ 		goto err_out;
+@@ -2052,14 +1971,15 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
+ 	}
+ 
+ 	/* Grab the IRQ */
+-      	retval = request_irq(dev->irq, &smc_interrupt, irq_flags, dev->name, dev);
+-      	if (retval) {
+-      		use_poll = 1;
+-      		//goto err_out;
+-	}
++	retval = request_irq(dev->irq, &atari_ethernat_interrupt, irq_flags, dev->name, dev);
++	if (retval)
++		goto err_out;
+ 
+-#ifdef SMC_USE_PXA_DMA
+-	{
++#ifdef CONFIG_ARCH_PXA
++#  ifdef SMC_USE_PXA_DMA
++	lp->cfg.flags |= SMC91X_USE_DMA;
++#  endif
++	if (lp->cfg.flags & SMC91X_USE_DMA) {
+ 		int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW,
+ 					  smc_pxa_dma_irq, NULL);
+ 		if (dma >= 0)
+@@ -2077,14 +1997,15 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
+ 		if (dev->dma != (unsigned char)-1)
+ 			printk(" DMA %d", dev->dma);
+ 
+-		printk("%s%s\n", nowait ? " [nowait]" : "",
++		printk(KERN_INFO "%s%s\n",
++			lp->cfg.flags & SMC91X_NOWAIT ? " [nowait]" : "",
+ 			THROTTLE_TX_PKTS ? " [throttle_tx]" : "");
+ 
+ 		if (!is_valid_ether_addr(dev->dev_addr)) {
+ 			printk("%s: Invalid ethernet MAC address.  Please "
+-			       "set proper address using ifconfig\n", dev->name);
++			       "set using ifconfig\n", dev->name);
+ 			random_ether_addr(dev->dev_addr);
+-			printk("%s: Ethernet addr (random): %s\n",
++			printk(KERN_INFO "%s: Ethernet addr set (random): %s\n",
+ 			       dev->name, print_mac(mac, dev->dev_addr));
+ 		} else {
+ 			/* Print the Ethernet address */
+@@ -2099,19 +2020,10 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
+ 		} else if ((lp->phy_type & 0xfffffff0) == 0x02821c50) {
+ 			PRINTK("%s: PHY LAN83C180\n", dev->name);
+ 		}
+-
+-		if (SMC_32BIT(lp)) {
+-			printk("%s: using 32 bit access\n", dev->name);
+-		} else if (SMC_16BIT(lp)) {
+-			printk("%s: using 16 bit access\n", dev->name);
+-		} else {
+-			printk("%s: using 8 bit access\n", dev->name);
+-		}
+-
+ 	}
+ 
+ err_out:
+-#ifdef SMC_USE_PXA_DMA
++#ifdef CONFIG_ARCH_PXA
+ 	if (retval && dev->dma != (unsigned char)-1)
+ 		pxa_free_dma(dev->dma);
+ #endif
+@@ -2128,24 +2040,17 @@ static int smc_enable_device(struct platform_device *pdev)
+ 	struct resource * res;
+ 
+ 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+-	if (!res) {
+-		printk("smc_enable_device: smc91x-attrib resource not found !\n");
++	if (!res)
+ 		return 0;
+-	}
+-
+-        printk("smc_enable_device: smc91x-attrib resource found, start=%x !\n", res->start);
+ 
+ 	/*
+ 	 * Map the attribute space.  This is overkill, but clean.
+ 	 */
+ 	addr = ioremap(res->start, ATTRIB_SIZE);
+-	if (!addr) {
++	if (!addr)
+ 		return -ENOMEM;
+-	} 
+ 
+-        printk("smc_enable_device :smc91x-attrib resource remapped, start=%p !\n", addr);
+-
+-        /*
++	/*
+ 	 * Reset the device.  We must disable IRQs around this
+ 	 * since a reset causes the IRQ line become active.
+ 	 */
+@@ -2188,23 +2093,26 @@ static int smc_enable_device(struct platform_device *pdev)
+ 	return 0;
+ }
+ 
+-static int smc_request_attrib(struct platform_device *pdev)
++static int smc_request_attrib(struct platform_device *pdev,
++			      struct net_device *ndev)
+ {
+ 	struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
++	struct smc_local *lp = netdev_priv(ndev);
+ 
+ 	if (!res)
+ 		return 0;
+ 
+-	if (!request_mem_region(res->start, ATTRIB_SIZE, CARDNAME)) {
++	if (!request_mem_region(res->start, ATTRIB_SIZE, CARDNAME))
+ 		return -EBUSY;
+-	}
+-	
++
+ 	return 0;
+ }
+ 
+-static void smc_release_attrib(struct platform_device *pdev)
++static void smc_release_attrib(struct platform_device *pdev,
++			       struct net_device *ndev)
+ {
+ 	struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
++	struct smc_local *lp = netdev_priv(ndev);
+ 
+ 	if (res)
+ 		release_mem_region(res->start, ATTRIB_SIZE);
+@@ -2245,25 +2153,6 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device *
+ }
+ 
+ /*
+- * Resources defined and added to platform data in arch/m68k/atari/config.c
+- * These are left here for reference only!
+- */
+-
+-struct resource ethernat_attr = {
+-	.start	= 0x80000000,
+-	.end	= 0x800000FF,
+-	.name	= "smc91x-attrib",
+-	.flags	= IORESOURCE_MEM
+-};
+-
+-struct resource ethernat_datacs = {
+-	.start	= 0,
+-	.end	= 0,
+-	.name	= "smc91x-data32",
+-	.flags	= IORESOURCE_MEM
+-};
+-
+-/*
+  * smc_init(void)
+  *   Input parameters:
+  *	dev->base_addr == 0, try to find all possible locations
+@@ -2274,38 +2163,21 @@ struct resource ethernat_datacs = {
+  *	0 --> there is a device
+  *	anything else, error
+  */
+-
+-static int __init atari_ethernat_pdev_probe(struct platform_device *pdev)
++static int smc_drv_probe(struct platform_device *pdev)
+ {
+ 	struct smc91x_platdata *pd = pdev->dev.platform_data;
+ 	struct smc_local *lp;
+ 	struct net_device *ndev;
+ 	struct resource *res, *ires;
+ 	unsigned int __iomem *addr;
++	unsigned long irq_flags = SMC_IRQ_FLAGS;
+ 	int ret;
+ 
+-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
+-	if (!res)
+-		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-	if (!res) {
+-		printk("smc91x-regs resource not found!\n");
+-		ret = -ENODEV;
+-		goto out;
+-	}
+-
+-	printk("smc91x-regs resource found, start=%x !\n", res->start);
+-
+-	if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
+-		printk("could not request smc91x-regs resource at %ul!\n", res->start);
+-		ret = -EBUSY;
+-		goto out;
+-	}
+-
+ 	ndev = alloc_etherdev(sizeof(struct smc_local));
+ 	if (!ndev) {
+ 		printk("%s: could not allocate device.\n", CARDNAME);
+ 		ret = -ENOMEM;
+-		goto out_release_io;
++		goto out;
+ 	}
+ 	SET_NETDEV_DEV(ndev, &pdev->dev);
+ 
+@@ -2314,32 +2186,47 @@ static int __init atari_ethernat_pdev_probe(struct platform_device *pdev)
+ 	 */
+ 
+ 	lp = netdev_priv(ndev);
+-	lp->cfg.irq_flags = SMC_IRQ_FLAGS;
+ 
+-#ifdef SMC_DYNAMIC_BUS_CONFIG
+-	if (pd)
++	if (pd) {
+ 		memcpy(&lp->cfg, pd, sizeof(lp->cfg));
+-	else {
+-		lp->cfg.flags = SMC91X_USE_8BIT;  
+-		lp->cfg.flags |= SMC91X_USE_16BIT;
+-		lp->cfg.flags |= SMC91X_USE_32BIT;
++		lp->io_shift = SMC91X_IO_SHIFT(lp->cfg.flags);
++	} else {
++		lp->cfg.flags |= (SMC_CAN_USE_8BIT)  ? SMC91X_USE_8BIT  : 0;
++		lp->cfg.flags |= (SMC_CAN_USE_16BIT) ? SMC91X_USE_16BIT : 0;
++		lp->cfg.flags |= (SMC_CAN_USE_32BIT) ? SMC91X_USE_32BIT : 0;
++		lp->cfg.flags |= (nowait) ? SMC91X_NOWAIT : 0;
+ 	}
+ 
+-	lp->cfg.flags &= ~(SMC_CAN_USE_8BIT ? 0 : SMC91X_USE_8BIT);  
+-	lp->cfg.flags &= ~(SMC_CAN_USE_16BIT ? 0 : SMC91X_USE_16BIT);
+-	lp->cfg.flags &= ~(SMC_CAN_USE_32BIT ? 0 : SMC91X_USE_32BIT);
+-#endif
++	if (!lp->cfg.leda && !lp->cfg.ledb) {
++		lp->cfg.leda = RPC_LSA_DEFAULT;
++		lp->cfg.ledb = RPC_LSB_DEFAULT;
++	}
+ 
+ 	ndev->dma = (unsigned char)-1;
+ 
++	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
++	if (!res)
++		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++	if (!res) {
++		ret = -ENODEV;
++		goto out_free_netdev;
++	}
++
++
++	if (!request_mem_region(res->start, SMC_IO_EXTENT, CARDNAME)) {
++		ret = -EBUSY;
++		goto out_free_netdev;
++	}
++
+ 	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ 	if (!ires) {
+-		printk("atari_91C111: IRQ resource not found!\n");
+ 		ret = -ENODEV;
+-		goto out_free_netdev;
++		goto out_release_io;
+ 	}
+ 
+ 	ndev->irq = ires->start;
++
++	if (ndev->irq != IRQ_MFP_TIMD) {
+ 	printk("atari_91C111: IRQ resource specified irq=%d\n", ndev->irq);
+ 
+ 	/*
+@@ -2356,35 +2243,27 @@ static int __init atari_ethernat_pdev_probe(struct platform_device *pdev)
+ 	ndev->irq = IRQ_MFP_TIMD;
+ 	ires->start = IRQ_MFP_TIMD;
+ 	printk("atari_91C111: IRQ forced to irq=%d\n", ndev->irq);
++	}
+ 
+-	if (SMC_IRQ_FLAGS == -1)
+-		lp->cfg.irq_flags = ires->flags & IRQF_TRIGGER_MASK;
++	if (ires->flags & IRQF_TRIGGER_MASK)
++		irq_flags = ires->flags & IRQF_TRIGGER_MASK;
+ 
+-	if (ndev->irq < 0) {
+-		printk("atari_91C111: cannot determine interrupt! Using timer D poll...\n");
+-		ndev->irq = IRQ_MFP_TIMD;
+-		/* timer actually set up later */
+-	}
+ 
+ 	if (ndev->irq == IRQ_MFP_TIMD) {
+-		printk("atari_91C111: Using timer D interrupt - do share!\n");
+-		lp->cfg.irq_flags = IRQF_SHARED;
++		printk(KERN_INFO "atari_91C111: Using timer D interrupt - do share!\n");
++		irq_flags |= IRQF_SHARED;
+ 	}
+ 
+-	ret = smc_request_attrib(pdev);
+-	if (ret) {
+-		printk("atari_91C111: attrib resource not found!\n");
+-		goto out_free_netdev;
+-	}
++	ret = smc_request_attrib(pdev, ndev);
++	if (ret)
++		goto out_release_io;
+ #if defined(CONFIG_SA1100_ASSABET)
+ 	NCR_0 |= NCR_ENET_OSC_EN;
+ #endif
+ 	platform_set_drvdata(pdev, ndev);
+ 	ret = smc_enable_device(pdev);
+-	if (ret) {
+-		printk("atari_91C111: failed to enable card!\n");
++	if (ret)
+ 		goto out_release_attrib;
+-	}
+ 
+ 	addr = ioremap(res->start, SMC_IO_EXTENT);
+ 	if (!addr) {
+@@ -2392,7 +2271,7 @@ static int __init atari_ethernat_pdev_probe(struct platform_device *pdev)
+ 		goto out_release_attrib;
+ 	}
+ 
+-#ifdef SMC_USE_PXA_DMA
++#ifdef CONFIG_ARCH_PXA
+ 	{
+ 		struct smc_local *lp = netdev_priv(ndev);
+ 		lp->device = &pdev->dev;
+@@ -2400,46 +2279,47 @@ static int __init atari_ethernat_pdev_probe(struct platform_device *pdev)
+ 	}
+ #endif
+ 
+-	printk("smc91x-regs resource remapped, start=%p!\n", addr);
+-
+ 	/*
+ 	 * about to probe for device; need to enable net IRQ here!
+ 	 * EtherNAT has interrupt enable register at 0x20 or 0x23 
+ 	 * probe for base address + 0x23 or 0x20
+ 	 */
+ 
+-	ret = smc_probe(ndev, addr, lp->cfg.irq_flags);
++	ret = smc_probe(ndev, addr, irq_flags);
+ 	if (ret != 0)
+ 		goto out_iounmap;
+ 
+-	printk("smc91x probe done, irq %d!\n", ndev->irq);
+-	ndev->irq = IRQ_MFP_TIMD;
++	smc_request_datacs(pdev, ndev);
+ 
+-	if (ndev->irq < 0) {
+-		if (use_poll)
+-			atari_ethernat_start_poll(ndev);
+-	} else if (ndev->irq == IRQ_MFP_TIMD) {
++	if (ndev->irq == IRQ_MFP_TIMD) {
+         	/* maybe instead use MFP timer C ?? */
+ 		/* init timer if not already running */
++
++		int timd = period * 4;
++		if (timd == 0)
++			timd = 192;     /* 200 Hz */
++		else if (timd < 80)
++			timd = 80;
++		else if (timd > 255)
++			timd = 255;
++		printk(KERN_INFO "Timer D frequency: %d Hz\n", (38400UL/(unsigned int)timd));
+ 		/* set Timer D data Register */
+-		mfp.tim_dt_d = 123;	/* 200 Hz */
++		mfp.tim_dt_d = timd;	/* 200 Hz */
+ 		/* start timer D, div = 1:100 */
+-		mfp.tim_ct_cd = (mfp.tim_ct_cd & 0xf0) | 0x6;
++		mfp.tim_ct_cd = (mfp.tim_ct_cd & 0xf0) | 0x5;
+ 	}
+ 
+-	smc_request_datacs(pdev, ndev);
+-
+ 	return 0;
+ 
+  out_iounmap:
+ 	platform_set_drvdata(pdev, NULL);
+ 	iounmap(addr);
+  out_release_attrib:
+-	smc_release_attrib(pdev);
+- out_free_netdev:
+-	free_netdev(ndev);
++	smc_release_attrib(pdev, ndev);
+  out_release_io:
+ 	release_mem_region(res->start, SMC_IO_EXTENT);
++ out_free_netdev:
++	free_netdev(ndev);
+  out:
+ 	printk("%s: not found (%d).\n", CARDNAME, ret);
+ 
+@@ -2454,25 +2334,22 @@ static int smc_drv_remove(struct platform_device *pdev)
+ 
+ 	platform_set_drvdata(pdev, NULL);
+ 
+-	if (use_poll)
+-		atari_ethernat_stop_poll(ndev);
+-
+ 	unregister_netdev(ndev);
+ 
+ 	free_irq(ndev->irq, ndev);
+ 
+-#ifdef SMC_USE_PXA_DMA
++#ifdef CONFIG_ARCH_PXA
+ 	if (ndev->dma != (unsigned char)-1)
+ 		pxa_free_dma(ndev->dma);
+ #endif
+ 	iounmap(lp->base);
+ 
+ 	smc_release_datacs(pdev,ndev);
+-	smc_release_attrib(pdev);
++	smc_release_attrib(pdev, ndev);
+ 
+ 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-regs");
+ 	if (!res)
+-		platform_get_resource(pdev, IORESOURCE_MEM, 0);
++		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ 	release_mem_region(res->start, SMC_IO_EXTENT);
+ 
+ 	free_netdev(ndev);
+@@ -2513,12 +2390,13 @@ static int smc_drv_resume(struct platform_device *dev)
+ }
+ 
+ static struct platform_driver smc_driver = {
+-	.probe		= atari_ethernat_pdev_probe,
++	.probe		= smc_drv_probe,
+ 	.remove		= smc_drv_remove,
+ 	.suspend	= smc_drv_suspend,
+ 	.resume		= smc_drv_resume,
+ 	.driver		= {
+ 		.name	= CARDNAME,
++		.owner	= THIS_MODULE,
+ 	},
+ };
+ 
+diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
+index 3911be7..33749d7 100644
+--- a/drivers/net/smc91x.h
++++ b/drivers/net/smc91x.h
+@@ -345,6 +345,32 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
+ 
+ #include <unit/smc91111.h>
+ 
++#elif defined(CONFIG_ATARI_ETHERNAT) || defined(CONFIG_ATARI_ETHERNAT_MODULE)
++
++#define SMC_CAN_USE_8BIT        1
++#define SMC_CAN_USE_16BIT       1
++#define SMC_CAN_USE_32BIT       1
++#define SMC_NOWAIT              1
++
++#define writew_be(val, addr) out_be16((addr), (val))
++
++#define SMC_inb(a, r)           readb((a) + (r))
++#define SMC_inw(a, r)           readw((a) + (r))
++#define SMC_inl(a, r)           readl((a) + (r))
++#define SMC_outb(v, a, r)       writeb(v, (a) + (r))
++#define SMC_outw(v, a, r)       writew(v, (a) + (r))
++#define SMC_outw_be(v, a, r)    writew_be(v, (a) + (r))
++#define SMC_outl(v, a, r)       writel(v, (a) + (r))
++#define SMC_insw(a, r, p, l)    readsw((a) + (r), p, l)
++#define SMC_outsw(a, r, p, l)   writesw((a) + (r), p, l)
++#define SMC_insl(a, r, p, l)    readsl((a) + (r), p, l)
++#define SMC_outsl(a, r, p, l)   writesl((a) + (r), p, l)
++
++#define RPC_LSA_DEFAULT         RPC_LED_100_10
++#define RPC_LSB_DEFAULT         RPC_LED_TX_RX
++
++#define SMC_DYNAMIC_BUS_CONFIG
++
+ #else
+ 
+ /*
+@@ -1188,6 +1214,40 @@ static const char * chip_ids[ 16 ] =  {
+ 		}							\
+ 	} while (0)
+ 
++#if defined(CONFIG_ATARI_ETHERNAT) || defined(CONFIG_ATARI_ETHERNAT_MODULE)
++/*
++ * MSch: EtherNAT is 32 bit, so the misaligned data buffer hack applies.
++ * This appears to hurt quite a lot ... we actually need to byte swap the
++ * misaligned write because the data end up in the packet buffer swapped
++ * otherwise (resulting in the first two bytes of the target MAC address
++ * being swapped)
++ */
++#define SMC_PUSH_DATA(lp, p, l)					\
++	do {								\
++		if (SMC_32BIT(lp)) {				\
++			void *__ptr = (p);				\
++			int __len = (l);				\
++			void __iomem *__ioaddr = ioaddr;		\
++			if (__len >= 2 && (unsigned long)__ptr & 2) {	\
++				__len -= 2;				\
++				SMC_outw_be(*(u16 *)__ptr, ioaddr,	\
++					DATA_REG(lp));		\
++				__ptr += 2;				\
++			}						\
++			if (SMC_CAN_USE_DATACS && lp->datacs)		\
++				__ioaddr = lp->datacs;			\
++			SMC_outsl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
++			if (__len & 2) {				\
++				__ptr += (__len & ~3);			\
++				SMC_outw_be(*((u16 *)__ptr), ioaddr,	\
++					 DATA_REG(lp));		\
++			}						\
++		} else if (SMC_16BIT(lp))				\
++			SMC_outsw(ioaddr, DATA_REG(lp), (u16 *) p, (l) >> 1); \
++		else if (SMC_8BIT(lp))				\
++			SMC_outsb(ioaddr, DATA_REG(lp), p, l);	\
++	} while (0)
++#else
+ #define SMC_PUSH_DATA(lp, p, l)					\
+ 	do {								\
+ 		if (SMC_32BIT(lp)) {				\
+@@ -1213,6 +1273,7 @@ static const char * chip_ids[ 16 ] =  {
+ 		else if (SMC_8BIT(lp))				\
+ 			SMC_outsb(ioaddr, DATA_REG(lp), p, l);	\
+ 	} while (0)
++#endif
+ 
+ #define SMC_PULL_DATA(lp, p, l)					\
+ 	do {								\
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0008-m68k-Atari-EtherNAT-warning-fixes.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0008-m68k-Atari-EtherNAT-warning-fixes.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,74 @@
+From 26b8bc0f035bf509fddf213e42c541e47816dfc7 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 21:07:40 +0100
+Subject: [PATCH] m68k: Atari EtherNAT warning fixes
+
+drivers/net/atari_91C111.c: In function 'smc_rcv':
+drivers/net/atari_91C111.c:538: warning: passing argument 2 of 'raw_insw' from incompatible pointer type
+drivers/net/atari_91C111.c: In function 'smc_request_attrib':
+drivers/net/atari_91C111.c:2100: warning: unused variable 'lp'
+drivers/net/atari_91C111.c: In function 'smc_release_attrib':
+drivers/net/atari_91C111.c:2115: warning: unused variable 'lp'
+drivers/net/atari_91C111.c: In function 'smc_drv_probe':
+drivers/net/atari_91C111.c:2305: warning: format '%d' expects type 'int', but argument 2 has type 'long unsigned int'
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/net/atari_91C111.c |    4 +---
+ drivers/net/smc91x.h       |    4 ++--
+ 2 files changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/atari_91C111.c b/drivers/net/atari_91C111.c
+index f6f8a45..c441779 100644
+--- a/drivers/net/atari_91C111.c
++++ b/drivers/net/atari_91C111.c
+@@ -2097,7 +2097,6 @@ static int smc_request_attrib(struct platform_device *pdev,
+ 			      struct net_device *ndev)
+ {
+ 	struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+-	struct smc_local *lp = netdev_priv(ndev);
+ 
+ 	if (!res)
+ 		return 0;
+@@ -2112,7 +2111,6 @@ static void smc_release_attrib(struct platform_device *pdev,
+ 			       struct net_device *ndev)
+ {
+ 	struct resource * res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "smc91x-attrib");
+-	struct smc_local *lp = netdev_priv(ndev);
+ 
+ 	if (res)
+ 		release_mem_region(res->start, ATTRIB_SIZE);
+@@ -2302,7 +2300,7 @@ static int smc_drv_probe(struct platform_device *pdev)
+ 			timd = 80;
+ 		else if (timd > 255)
+ 			timd = 255;
+-		printk(KERN_INFO "Timer D frequency: %d Hz\n", (38400UL/(unsigned int)timd));
++		printk(KERN_INFO "Timer D frequency: %u Hz\n", 38400/timd);
+ 		/* set Timer D data Register */
+ 		mfp.tim_dt_d = timd;	/* 200 Hz */
+ 		/* start timer D, div = 1:100 */
+diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
+index 33749d7..c9fa11f 100644
+--- a/drivers/net/smc91x.h
++++ b/drivers/net/smc91x.h
+@@ -1269,7 +1269,7 @@ static const char * chip_ids[ 16 ] =  {
+ 					 DATA_REG(lp));		\
+ 			}						\
+ 		} else if (SMC_16BIT(lp))				\
+-			SMC_outsw(ioaddr, DATA_REG(lp), p, (l) >> 1);	\
++			SMC_outsw(ioaddr, DATA_REG(lp), (u16 *) p, (l) >> 1);	\
+ 		else if (SMC_8BIT(lp))				\
+ 			SMC_outsb(ioaddr, DATA_REG(lp), p, l);	\
+ 	} while (0)
+@@ -1305,7 +1305,7 @@ static const char * chip_ids[ 16 ] =  {
+ 			__len += 2;					\
+ 			SMC_insl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
+ 		} else if (SMC_16BIT(lp))				\
+-			SMC_insw(ioaddr, DATA_REG(lp), p, (l) >> 1);	\
++			SMC_insw(ioaddr, DATA_REG(lp), (u16 *) p, (l) >> 1);	\
+ 		else if (SMC_8BIT(lp))				\
+ 			SMC_insb(ioaddr, DATA_REG(lp), p, l);		\
+ 	} while (0)
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0009-m68k-section-mismatch-fixes-EtherNAT.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0009-m68k-section-mismatch-fixes-EtherNAT.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,68 @@
+From 544e53cda975aa50a949fcc7ab1f4b1636f24455 Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at biophys.uni-duesseldorf.de>
+Date: Sun, 18 Jan 2009 03:10:55 +0100
+Subject: [PATCH] m68k: section mismatch fixes: EtherNAT
+
+add __init annotation
+[geert] Use __dev{in,ex}it
+
+Signed-off-by: Michael Schmitz <schmitz at debian.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/net/atari_91C111.c |   12 ++++++------
+ 1 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/atari_91C111.c b/drivers/net/atari_91C111.c
+index c441779..af2d255 100644
+--- a/drivers/net/atari_91C111.c
++++ b/drivers/net/atari_91C111.c
+@@ -1724,7 +1724,7 @@ static const struct ethtool_ops smc_ethtool_ops = {
+  * I just deleted auto_irq.c, since it was never built...
+  *   --jgarzik
+  */
+-static int __init smc_findirq(struct smc_local *lp)
++static int __devinit smc_findirq(struct smc_local *lp)
+ {
+ 	void __iomem *ioaddr = lp->base;
+ 	int timeout = 20;
+@@ -1798,8 +1798,8 @@ static int __init smc_findirq(struct smc_local *lp)
+  * o  actually GRAB the irq.
+  * o  GRAB the region
+  */
+-static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
+-			    unsigned long irq_flags)
++static int __devinit smc_probe(struct net_device *dev, void __iomem *ioaddr,
++			       unsigned long irq_flags)
+ {
+ 	struct smc_local *lp = netdev_priv(dev);
+ 	static int version_printed = 0;
+@@ -2161,7 +2161,7 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device *
+  *	0 --> there is a device
+  *	anything else, error
+  */
+-static int smc_drv_probe(struct platform_device *pdev)
++static int __devinit smc_drv_probe(struct platform_device *pdev)
+ {
+ 	struct smc91x_platdata *pd = pdev->dev.platform_data;
+ 	struct smc_local *lp;
+@@ -2324,7 +2324,7 @@ static int smc_drv_probe(struct platform_device *pdev)
+ 	return ret;
+ }
+ 
+-static int smc_drv_remove(struct platform_device *pdev)
++static int __devexit smc_drv_remove(struct platform_device *pdev)
+ {
+ 	struct net_device *ndev = platform_get_drvdata(pdev);
+ 	struct smc_local *lp = netdev_priv(ndev);
+@@ -2389,7 +2389,7 @@ static int smc_drv_resume(struct platform_device *dev)
+ 
+ static struct platform_driver smc_driver = {
+ 	.probe		= smc_drv_probe,
+-	.remove		= smc_drv_remove,
++	.remove		= __devexit_p(smc_drv_remove),
+ 	.suspend	= smc_drv_suspend,
+ 	.resume		= smc_drv_resume,
+ 	.driver		= {
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0010-m68k-Atari-ROM-port-ISA-adapter-support.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0010-m68k-Atari-ROM-port-ISA-adapter-support.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,433 @@
+From caaba084daccb301e478d17527f79a8a4bf28240 Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at opal.biophys.uni-duesseldorf.de>
+Date: Tue, 18 Nov 2008 21:01:16 +0100
+Subject: [PATCH] m68k: Atari ROM port ISA adapter support
+
+Atari ROM port ISA adapter support
+
+FIXME missing last hunk of original patch
+
+Signed-off-by: Michael Schmitz <schmitz at debian.org>
+Signed-off-by: Roman Zippel <zippel at linux-m68k.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/Kconfig              |   10 +++
+ arch/m68k/include/asm/io_mm.h  |  140 +++++++++++++++++++++++++++++++++++++++-
+ arch/m68k/include/asm/raw_io.h |  116 ++++++++++++++++++++++++++++++++-
+ arch/m68k/kernel/setup.c       |    6 ++
+ 4 files changed, 268 insertions(+), 4 deletions(-)
+
+diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
+index 3073675..6fe481f 100644
+--- a/arch/m68k/Kconfig
++++ b/arch/m68k/Kconfig
+@@ -130,6 +130,16 @@ config ATARI
+ 	  this kernel on an Atari, say Y here and browse the material
+ 	  available in <file:Documentation/m68k>; otherwise say N.
+ 
++config ATARI_ROM_ISA
++	bool "Atari ROM port ISA adapter support"
++	depends on ATARI
++	help
++	  This option enables support for the ROM port ISA adapter used to
++	  operate ISA cards on Atari. Only 8  bit cards are supported, and
++	  no interrupt lines are connected.
++	  The only driver currently using this adapter is the EtherNEC
++	  driver for RTL8019AS based NE2000 compatible network cards.
++
+ config MAC
+ 	bool "Macintosh support"
+ 	select MMU_MOTOROLA if MMU
+diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h
+index 9e673e3..7277fb2 100644
+--- a/arch/m68k/include/asm/io_mm.h
++++ b/arch/m68k/include/asm/io_mm.h
+@@ -80,9 +80,26 @@ extern unsigned long gg2_isa_base;
+ #endif
+ #endif /* AMIGA_PCMCIA */
+ 
++#ifdef CONFIG_ATARI_ROM_ISA
+ 
++#define enec_isa_read_base  0xfffa0000
++#define enec_isa_write_base 0xfffb0000
+ 
+-#ifdef CONFIG_ISA
++#define ENEC_ISA_IO_B(ioaddr)	(enec_isa_read_base+((((unsigned long)(ioaddr))&0x1F)<<9))
++#define ENEC_ISA_IO_W(ioaddr)	(enec_isa_read_base+((((unsigned long)(ioaddr))&0x1F)<<9))
++#define ENEC_ISA_MEM_B(madr)	(enec_isa_read_base+((((unsigned long)(madr))&0x1F)<<9))
++#define ENEC_ISA_MEM_W(madr)	(enec_isa_read_base+((((unsigned long)(madr))&0x1F)<<9))
++
++#ifndef MULTI_ISA
++#define MULTI_ISA 0
++#else
++#undef MULTI_ISA
++#define MULTI_ISA 1
++#endif
++#endif /* ATARI_ROM_ISA */
++
++
++#if defined(CONFIG_ISA) || defined(CONFIG_ATARI_ROM_ISA)
+ 
+ #if MULTI_ISA == 0
+ #undef MULTI_ISA
+@@ -91,6 +108,7 @@ extern unsigned long gg2_isa_base;
+ #define ISA_TYPE_Q40 (1)
+ #define ISA_TYPE_GG2 (2)
+ #define ISA_TYPE_AG  (3)
++#define ISA_TYPE_ENEC (4)
+ 
+ #if defined(CONFIG_Q40) && !defined(MULTI_ISA)
+ #define ISA_TYPE ISA_TYPE_Q40
+@@ -104,6 +122,10 @@ extern unsigned long gg2_isa_base;
+ #define ISA_TYPE ISA_TYPE_GG2
+ #define ISA_SEX  0
+ #endif
++#if defined(CONFIG_ATARI_ROM_ISA) && !defined(MULTI_ISA)
++#define ISA_TYPE ISA_TYPE_ENEC
++#define ISA_SEX  0
++#endif
+ 
+ #ifdef MULTI_ISA
+ extern int isa_type;
+@@ -131,6 +153,9 @@ static inline u8 __iomem *isa_itb(unsigned long addr)
+ #ifdef CONFIG_AMIGA_PCMCIA
+     case ISA_TYPE_AG: return (u8 __iomem *)AG_ISA_IO_B(addr);
+ #endif
++#ifdef CONFIG_ATARI_ROM_ISA
++    case ISA_TYPE_ENEC: return (u8 __iomem *)ENEC_ISA_IO_B(addr);
++#endif
+     default: return NULL; /* avoid warnings, just in case */
+     }
+ }
+@@ -147,6 +172,9 @@ static inline u16 __iomem *isa_itw(unsigned long addr)
+ #ifdef CONFIG_AMIGA_PCMCIA
+     case ISA_TYPE_AG: return (u16 __iomem *)AG_ISA_IO_W(addr);
+ #endif
++#ifdef CONFIG_ATARI_ROM_ISA
++    case ISA_TYPE_ENEC: return (u16 __iomem *)ENEC_ISA_IO_W(addr);
++#endif
+     default: return NULL; /* avoid warnings, just in case */
+     }
+ }
+@@ -173,6 +201,9 @@ static inline u8 __iomem *isa_mtb(unsigned long addr)
+ #ifdef CONFIG_AMIGA_PCMCIA
+     case ISA_TYPE_AG: return (u8 __iomem *)addr;
+ #endif
++#ifdef CONFIG_ATARI_ROM_ISA
++    case ISA_TYPE_ENEC: return (u8 __iomem *)ENEC_ISA_MEM_B(addr);
++#endif
+     default: return NULL; /* avoid warnings, just in case */
+     }
+ }
+@@ -189,6 +220,9 @@ static inline u16 __iomem *isa_mtw(unsigned long addr)
+ #ifdef CONFIG_AMIGA_PCMCIA
+     case ISA_TYPE_AG: return (u16 __iomem *)addr;
+ #endif
++#ifdef CONFIG_ATARI_ROM_ISA
++    case ISA_TYPE_ENEC: return (u16 __iomem *)ENEC_ISA_MEM_W(addr);
++#endif
+     default: return NULL; /* avoid warnings, just in case */
+     }
+ }
+@@ -210,6 +244,34 @@ static inline u16 __iomem *isa_mtw(unsigned long addr)
+ 	(ISA_SEX ? out_be16(isa_mtw((unsigned long)(p)),(val))	\
+ 		 : out_le16(isa_mtw((unsigned long)(p)),(val)))
+ 
++#ifdef CONFIG_ATARI_ROM_ISA
++#define isa_rom_inb(port)      rom_in_8(isa_itb(port))
++#define isa_rom_inw(port)	\
++	(ISA_SEX ? rom_in_be16(isa_itw(port))	\
++		 : rom_in_le16(isa_itw(port)))
++#define isa_rom_inl(port)	\
++	(ISA_SEX ? rom_in_be32(isa_itw(port))	\
++		 : rom_in_le32(isa_itw(port)))
++
++#define isa_rom_outb(val, port) rom_out_8(isa_itb(port), (val))
++#define isa_rom_outw(val, port)	\
++	(ISA_SEX ? rom_out_be16(isa_itw(port), (val))	\
++		 : rom_out_le16(isa_itw(port), (val)))
++#define isa_rom_outl(val, port)	\
++	(ISA_SEX ? rom_out_be32(isa_itw(port), (val))	\
++		 : rom_out_le32(isa_itw(port), (val)))
++
++#define isa_rom_readb(p)       rom_in_8(isa_mtb((unsigned long)(p)))
++#define isa_rom_readw(p)       \
++	(ISA_SEX ? rom_in_be16(isa_mtw((unsigned long)(p)))	\
++		 : rom_in_le16(isa_mtw((unsigned long)(p))))
++
++#define isa_rom_writeb(val, p)  rom_out_8(isa_mtb((unsigned long)(p)), (val))
++#define isa_rom_writew(val, p)  \
++	(ISA_SEX ? rom_out_be16(isa_mtw((unsigned long)(p)), (val))	\
++		 : rom_out_le16(isa_mtw((unsigned long)(p)), (val)))
++#endif /* CONFIG_ATARI_ROM_ISA */
++
+ static inline void isa_delay(void)
+ {
+   switch(ISA_TYPE)
+@@ -223,6 +285,9 @@ static inline void isa_delay(void)
+ #ifdef CONFIG_AMIGA_PCMCIA
+     case ISA_TYPE_AG: break;
+ #endif
++#ifdef CONFIG_ATARI_ROM_ISA
++    case ISA_TYPE_ENEC: break;
++#endif
+     default: break; /* avoid warnings */
+     }
+ }
+@@ -254,6 +319,39 @@ static inline void isa_delay(void)
+                   raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1))
+ 
+ 
++#ifdef CONFIG_ATARI_ROM_ISA
++#define isa_rom_inb_p(p)	({ u8 _v = isa_rom_inb(p); isa_delay(); _v; })
++#define isa_rom_inw_p(p)	({ u16 _v = isa_rom_inw(p); isa_delay(); _v; })
++#define isa_rom_inl_p(p)	({ u32 _v = isa_rom_inl(p); isa_delay(); _v; })
++#define isa_rom_outb_p(v, p)	({ isa_rom_outb((v), (p)); isa_delay(); })
++#define isa_rom_outw_p(v, p)	({ isa_rom_outw((v), (p)); isa_delay(); })
++#define isa_rom_outl_p(v, p)	({ isa_rom_outl((v), (p)); isa_delay(); })
++
++#define isa_rom_insb(port, buf, nr) raw_rom_insb(isa_itb(port), (u8 *)(buf), (nr))
++
++#define isa_rom_insw(port, buf, nr)     \
++       (ISA_SEX ? raw_rom_insw(isa_itw(port), (u16 *)(buf), (nr)) :    \
++		  raw_rom_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)))
++
++#define isa_rom_insl(port, buf, nr)     \
++       (ISA_SEX ? raw_rom_insl(isa_itw(port), (u32 *)(buf), (nr)) :    \
++                  raw_rom_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1))
++
++#define isa_rom_outsb(port, buf, nr) raw_rom_outsb(isa_itb(port), (u8 *)(buf), (nr))
++
++#define isa_rom_outsw(port, buf, nr)    \
++       (ISA_SEX ? raw_rom_outsw(isa_itw(port), (u16 *)(buf), (nr)) :  \
++		  raw_rom_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)))
++
++#define isa_rom_outsl(port, buf, nr)    \
++       (ISA_SEX ? raw_rom_outsl(isa_itw(port), (u32 *)(buf), (nr)) :  \
++                  raw_rom_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1))
++#endif /* CONFIG_ATARI_ROM_ISA */
++
++#endif  /* CONFIG_ISA || CONFIG_ATARI_ROM_ISA */
++
++
++#if defined(CONFIG_ISA) && !defined(CONFIG_ATARI_ROM_ISA)
+ #define inb     isa_inb
+ #define inb_p   isa_inb_p
+ #define outb    isa_outb
+@@ -276,9 +374,45 @@ static inline void isa_delay(void)
+ #define readw   isa_readw
+ #define writeb  isa_writeb
+ #define writew  isa_writew
++#endif  /* CONFIG_ISA && !CONFIG_ATARI_ROM_ISA */
++
++#ifdef CONFIG_ATARI_ROM_ISA
++/*
++ * kernel with both ROM port ISA and IDE compiled in, those have
++ * conflicting defs for in/out. Simply consider port < 1024
++ * ROM port ISA and everything else regular ISA for IDE. read,write not defined
++ * in this case
++ */
++#define inb(port)	((port) < 1024 ? isa_rom_inb(port) : in_8(port))
++#define inb_p(port)	((port) < 1024 ? isa_rom_inb_p(port) : in_8(port))
++#define inw(port)	((port) < 1024 ? isa_rom_inw(port) : in_le16(port))
++#define inw_p(port)	((port) < 1024 ? isa_rom_inw_p(port) : in_le16(port))
++#define inl(port)	((port) < 1024 ? isa_rom_inl(port) : in_le32(port))
++#define inl_p(port)	((port) < 1024 ? isa_rom_inl_p(port) : in_le32(port))
++
++#define outb(val, port)	((port) < 1024 ? isa_rom_outb((val), (port)) : out_8((port), (val)))
++#define outb_p(val, port) ((port) < 1024 ? isa_rom_outb_p((val), (port)) : out_8((port), (val)))
++#define outw(val, port)	((port) < 1024 ? isa_rom_outw((val), (port)) : out_le16((port), (val)))
++#define outw_p(val, port) ((port) < 1024 ? isa_rom_outw_p((val), (port)) : out_le16((port), (val)))
++#define outl(val, port)	((port) < 1024 ? isa_rom_outl((val), (port)) : out_le32((port), (val)))
++#define outl_p(val, port) ((port) < 1024 ? isa_rom_outl_p((val), (port)) : out_le32((port), (val)))
++
++#define insb    isa_rom_insb
++#define insw    isa_rom_insw
++#define insl    isa_rom_insl
++#define outsb   isa_rom_outsb
++#define outsw   isa_rom_outsw
++#define outsl   isa_rom_outsl
+ 
+-#else  /* CONFIG_ISA */
++#define readb   isa_readb
++#define readw   isa_readw
++#define writeb  isa_writeb
++#define writew  isa_writew
++#define readsl  raw_insl
++#define writesl raw_outsl
++#endif /* CONFIG_ATARI_ROM_ISA */
+ 
++#if !defined(CONFIG_ISA) && !defined(CONFIG_ATARI_ROM_ISA)
+ /*
+  * We need to define dummy functions for GENERIC_IOMAP support.
+  */
+@@ -306,7 +440,7 @@ static inline void isa_delay(void)
+ #define readw(addr)      in_le16(addr)
+ #define writew(val,addr) out_le16((addr),(val))
+ 
+-#endif /* CONFIG_ISA */
++#endif /* !CONFIG_ISA && !CONFIG_ATARI_ROM_ISA */
+ 
+ #define readl(addr)      in_le32(addr)
+ #define writel(val,addr) out_le32((addr),(val))
+diff --git a/arch/m68k/include/asm/raw_io.h b/arch/m68k/include/asm/raw_io.h
+index d9eb983..b1d9119 100644
+--- a/arch/m68k/include/asm/raw_io.h
++++ b/arch/m68k/include/asm/raw_io.h
+@@ -10,7 +10,7 @@
+ 
+ #ifdef __KERNEL__
+ 
+-#include <asm/types.h>
++#include <asm/byteorder.h>
+ 
+ 
+ /* Values for nocacheflag and cmode */
+@@ -60,6 +60,46 @@ extern void __iounmap(void *addr, unsigned long size);
+ #define __raw_writew(val,addr) out_be16((addr),(val))
+ #define __raw_writel(val,addr) out_be32((addr),(val))
+ 
++/*
++ * Atari ROM port (cartridge port) ISA adapter, used for the EtherNEC NE2000
++ * network card driver.
++ * The ISA adapter connects address lines A9-A13 to ISA address lines A0-A4,
++ * and hardwires the rest of the ISA addresses for a base address of 0x300.
++ *
++ * Data lines D8-D15 are connected to ISA data lines D0-D7 for reading.
++ * For writes, address lines A1-A8 are latched to ISA data lines D0-D7
++ * (meaning the bit pattern on A1-A8 can be read back as byte).
++ *
++ * Reads and writes are byte only.
++ */
++
++#if defined(CONFIG_ATARI_ROM_ISA)
++#define rom_in_8(addr) \
++	({ u16 __v = (*(__force volatile u16 *) (addr)); __v >>= 8; __v; })
++#define rom_in_be16(addr) \
++	({ u16 __v = (*(__force volatile u16 *) (addr)); __v >>= 8; __v; })
++#define rom_in_be32(addr) \
++	({ u32 __v = (*(__force volatile u32 *) (addr)); __v >>= 8; __v; })
++#define rom_in_le16(addr) \
++	({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v >>= 8; __v; })
++#define rom_in_le32(addr) \
++	({ u32 __v = le32_to_cpu(*(__force volatile u32 *) (addr)); __v >>= 8; __v; })
++
++#define rom_out_8(addr, b)	({u8 __w, __v = (b); __w = ((*(__force volatile u8 *)  ((addr) + 0x10000 + (__v<<1)))); })
++#define rom_out_be16(addr, w)	({u16 __w, __v = (w); __w = ((*(__force volatile u16 *) ((addr) + 0x10000 + (__v<<1)))); })
++#define rom_out_be32(addr, l)	({u32 __w, __v = (l); __w = ((*(__force volatile u32 *) ((addr) + 0x10000 + (__v<<1)))); })
++#define rom_out_le16(addr, w)	({u16 __w, __v = cpu_to_le16(w); __w = ((*(__force volatile u16 *) ((addr) + 0x10000 + (__v<<1)))); })
++#define rom_out_le32(addr, l)	({u32 __w, __v = cpu_to_le32(l); __w = ((*(__force volatile u32 *) ((addr) + 0x10000 + (__v<<1)))); })
++
++#define raw_rom_inb rom_in_8
++#define raw_rom_inw rom_in_be16
++#define raw_rom_inl rom_in_be32
++
++#define raw_rom_outb(val, port) rom_out_8((port), (val))
++#define raw_rom_outw(val, port) rom_out_be16((port), (val))
++#define raw_rom_outl(val, port) rom_out_be32((port), (val))
++#endif /* CONFIG_ATARI_ROM_ISA */
++
+ static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
+ {
+ 	unsigned int i;
+@@ -342,6 +382,80 @@ static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
+ 		: "d0", "a0", "a1", "d6");
+ }
+ 
++
++#if defined(CONFIG_ATARI_ROM_ISA)
++static inline void raw_rom_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
++{
++	unsigned int i;
++
++	for (i = 0; i < len; i++)
++		*buf++ = rom_in_8(port);
++}
++
++static inline void raw_rom_outsb(volatile u8 __iomem *port, const u8 *buf,
++			     unsigned int len)
++{
++	unsigned int i;
++
++	for (i = 0; i < len; i++)
++		rom_out_8(port, *buf++);
++}
++
++static inline void raw_rom_insw(volatile u16 __iomem *port, u16 *buf,
++				   unsigned int nr)
++{
++	unsigned int i;
++
++	for (i = 0; i < nr; i++)
++		*buf++ = rom_in_be16(port);
++}
++
++static inline void raw_rom_outsw(volatile u16 __iomem *port, const u16 *buf,
++				   unsigned int nr)
++{
++	unsigned int i;
++
++	for (i = 0; i < nr; i++)
++		rom_out_be16(port, *buf++);
++}
++
++static inline void raw_rom_insw_swapw(volatile u16 __iomem *port, u16 *buf,
++				   unsigned int nr)
++{
++	unsigned int i;
++
++	for (i = 0; i < nr; i++)
++		*buf++ = rom_in_le16(port);
++}
++
++static inline void raw_rom_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
++				   unsigned int nr)
++{
++	unsigned int i;
++
++	for (i = 0; i < nr; i++)
++		rom_out_le16(port, *buf++);
++}
++
++static inline void raw_rom_insl(volatile u16 __iomem *port, u32 *buf,
++				   unsigned int nr)
++{
++	unsigned int i;
++
++	for (i = 0; i < nr; i++)
++		*buf++ = rom_in_be32(port);
++}
++
++static inline void raw_rom_outsl(volatile u16 __iomem *port, const u32 *buf,
++				   unsigned int nr)
++{
++	unsigned int i;
++
++	for (i = 0; i < nr; i++)
++		rom_out_be32(port, *buf++);
++}
++#endif /* CONFIG_ATARI_ROM_ISA */
++
+ #endif /* __KERNEL__ */
+ 
+ #endif /* _RAW_IO_H */
+diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
+index 17b2b62..594cbd1 100644
+--- a/arch/m68k/kernel/setup.c
++++ b/arch/m68k/kernel/setup.c
+@@ -376,6 +376,12 @@ void __init setup_arch(char **cmdline_p)
+ 		isa_sex = 1;
+ 	}
+ #endif
++#ifdef CONFIG_ATARI_ROM_ISA
++	if (MACH_IS_ATARI) {
++		isa_type = ISA_TYPE_ENEC;
++		isa_sex = 0;
++	}
++#endif
+ #endif
+ }
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0011-m68k-Atari-io.h-fixes-for-EtherNAT-driver.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0011-m68k-Atari-io.h-fixes-for-EtherNAT-driver.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,75 @@
+From 712aadf6f17cba94d3f2e62cafe654b7af692786 Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at biophys.uni-duesseldorf.de>
+Date: Tue, 18 Nov 2008 21:01:16 +0100
+Subject: [PATCH] m68k: Atari io.h fixes for EtherNAT driver
+
+This patch fixes errors I introduced in preparing the io.h code for ROM port
+ISA access (for the EtherNEC driver, originally).
+
+My assumption was that insb/outsb and friends should be mapped to the ROM
+port accessors unconditionally, and the read*/write* functions should behave
+like regular ISA accesses. As it turned out, it's just the other way 'round.
+"Regular" ISA readb would apply the ROM port address mapping without
+actually using the correct access function.
+
+ins*/outs* are conditionalized now (port < 1024 goes to the ROM port, all
+else via MMIO), read*/write* use straight MMIO no questions asked.
+
+This fixes register access problems for the EtherNAT (SMC91C111) when used
+together with the EtherNEC (ROM port NE2k clone). Tested on my Falcon.
+
+Signed-off-by: Michael Schmitz <schmitz at debian.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/include/asm/io_mm.h |   27 +++++++++++++++------------
+ 1 files changed, 15 insertions(+), 12 deletions(-)
+
+diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h
+index 7277fb2..e2a8981 100644
+--- a/arch/m68k/include/asm/io_mm.h
++++ b/arch/m68k/include/asm/io_mm.h
+@@ -380,8 +380,8 @@ static inline void isa_delay(void)
+ /*
+  * kernel with both ROM port ISA and IDE compiled in, those have
+  * conflicting defs for in/out. Simply consider port < 1024
+- * ROM port ISA and everything else regular ISA for IDE. read,write not defined
+- * in this case
++ * ROM port ISA and everything else regular ISA for IDE. read,write defined
++ * below.
+  */
+ #define inb(port)	((port) < 1024 ? isa_rom_inb(port) : in_8(port))
+ #define inb_p(port)	((port) < 1024 ? isa_rom_inb_p(port) : in_8(port))
+@@ -397,17 +397,20 @@ static inline void isa_delay(void)
+ #define outl(val, port)	((port) < 1024 ? isa_rom_outl((val), (port)) : out_le32((port), (val)))
+ #define outl_p(val, port) ((port) < 1024 ? isa_rom_outl_p((val), (port)) : out_le32((port), (val)))
+ 
+-#define insb    isa_rom_insb
+-#define insw    isa_rom_insw
+-#define insl    isa_rom_insl
+-#define outsb   isa_rom_outsb
+-#define outsw   isa_rom_outsw
+-#define outsl   isa_rom_outsl
++#define insb(port, buf, nr)	((port) < 1024 ? isa_rom_insb((port), (buf), (nr)) : isa_insb((port), (buf), (nr)))
++#define insw(port, buf, nr)	((port) < 1024 ? isa_rom_insw((port), (buf), (nr)) : isa_insw((port), (buf), (nr)))
++#define insl(port, buf, nr)	((port) < 1024 ? isa_rom_insl((port), (buf), (nr)) : isa_insl((port), (buf), (nr)))
++#define outsb(port, buf, nr)	((port) < 1024 ? isa_rom_outsb((port), (buf), (nr)) : isa_outsb((port), (buf), (nr)))
++#define outsw(port, buf, nr)	((port) < 1024 ? isa_rom_outsw((port), (buf), (nr)) : isa_outsw((port), (buf), (nr)))
++#define outsl(port, buf, nr)	((port) < 1024 ? isa_rom_outsl((port), (buf), (nr)) : isa_outsl((port), (buf), (nr)))
+ 
+-#define readb   isa_readb
+-#define readw   isa_readw
+-#define writeb  isa_writeb
+-#define writew  isa_writew
++#define readb(addr)      in_8(addr)
++#define writeb(val,addr) out_8((addr),(val))
++#define readw(addr)      in_le16(addr)
++#define writew(val,addr) out_le16((addr),(val))
++
++#define readsw  raw_insw
++#define writesw raw_outsw
+ #define readsl  raw_insl
+ #define writesl raw_outsl
+ #endif /* CONFIG_ATARI_ROM_ISA */
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0012-m68k-Atari-EtherNEC-driver.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0012-m68k-Atari-EtherNEC-driver.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,1102 @@
+From 1b37a29a709ef3fa50c94570c80c7e0270c95fef Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at opal.biophys.uni-duesseldorf.de>
+Date: Tue, 18 Nov 2008 21:01:17 +0100
+Subject: [PATCH] m68k: Atari EtherNEC driver
+
+Atari EtherNEC driver
+
+Signed-off-by: Michael Schmitz <schmitz at debian.org>
+Signed-off-by: Roman Zippel <zippel at linux-m68k.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/net/Kconfig          |    8 +
+ drivers/net/Makefile         |    1 +
+ drivers/net/Space.c          |    4 +
+ drivers/net/atari_ethernec.c | 1022 ++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 1035 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/net/atari_ethernec.c
+
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index 3671552..9e7c76e 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -416,6 +416,14 @@ config ATARI_ETHERNAT
+ 	  CT/60 extension port. The driver works by polling instead of
+ 	  interrupts, so it is quite slow.
+ 
++config ATARI_ETHERNEC
++	tristate "Atari EtherNEC Ethernet support"
++	depends on NET_ETHERNET && ATARI && ATARI_ROM_ISA
++	help
++	  Say Y to include support for the EtherNEC network adapter for the
++	  ROM port. The driver works by polling instead of interrupts, so it
++	  is quite slow.
++
+ config SUN3LANCE
+ 	tristate "Sun3/Sun3x on-board LANCE support"
+ 	depends on SUN3 || SUN3X
+diff --git a/drivers/net/Makefile b/drivers/net/Makefile
+index d550e30..aaed32c 100644
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -220,6 +220,7 @@ obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
+ obj-$(CONFIG_DECLANCE) += declance.o
+ obj-$(CONFIG_ATARILANCE) += atarilance.o
+ obj-$(CONFIG_ATARI_ETHERNAT) += atari_91C111.o
++obj-$(CONFIG_ATARI_ETHERNEC) += atari_ethernec.o 8390.o
+ obj-$(CONFIG_A2065) += a2065.o
+ obj-$(CONFIG_HYDRA) += hydra.o 8390.o
+ obj-$(CONFIG_ARIADNE) += ariadne.o
+diff --git a/drivers/net/Space.c b/drivers/net/Space.c
+index 3b79c6c..8e6e362 100644
+--- a/drivers/net/Space.c
++++ b/drivers/net/Space.c
+@@ -72,6 +72,7 @@ extern struct net_device *SK_init(int unit);
+ extern struct net_device *seeq8005_probe(int unit);
+ extern struct net_device *smc_init(int unit);
+ extern struct net_device *atarilance_probe(int unit);
++extern struct net_device *atari_ethernec_probe(int unit);
+ extern struct net_device *sun3lance_probe(int unit);
+ extern struct net_device *sun3_82586_probe(int unit);
+ extern struct net_device *apne_probe(int unit);
+@@ -253,6 +254,9 @@ static struct devprobe2 m68k_probes[] __initdata = {
+ #ifdef CONFIG_ATARILANCE	/* Lance-based Atari ethernet boards */
+ 	{atarilance_probe, 0},
+ #endif
++#ifdef CONFIG_ATARI_ETHERNEC	/* NE2000 based ROM port ethernet cards */
++	{atari_ethernec_probe, 0},
++#endif
+ #ifdef CONFIG_SUN3LANCE         /* sun3 onboard Lance chip */
+ 	{sun3lance_probe, 0},
+ #endif
+diff --git a/drivers/net/atari_ethernec.c b/drivers/net/atari_ethernec.c
+new file mode 100644
+index 0000000..97f683a
+--- /dev/null
++++ b/drivers/net/atari_ethernec.c
+@@ -0,0 +1,1022 @@
++/*
++ * atari_ethernec.c: Atari cartridge port ethernet adapter
++ * (C) 2006 Michael Schmitz
++ *
++ * Modified after:
++ */
++
++/* ne.c: A general non-shared-memory NS8390 ethernet driver for linux. */
++/*
++    Written 1992-94 by Donald Becker.
++
++    Copyright 1993 United States Government as represented by the
++    Director, National Security Agency.
++
++    This software may be used and distributed according to the terms
++    of the GNU General Public License, incorporated herein by reference.
++
++    The author may be reached as becker at scyld.com, or C/O
++    Scyld Computing Corporation, 410 Severn Ave., Suite 210, Annapolis MD 21403
++
++    This driver should work with many programmed-I/O 8390-based ethernet
++    boards.  Currently it supports the NE1000, NE2000, many clones,
++    and some Cabletron products.
++
++    Changelog:
++
++    Paul Gortmaker	: use ENISR_RDC to monitor Tx PIO uploads, made
++			  sanity checks and bad clone support optional.
++    Paul Gortmaker	: new reset code, reset card after probe at boot.
++    Paul Gortmaker	: multiple card support for module users.
++    Paul Gortmaker	: Support for PCI ne2k clones, similar to lance.c
++    Paul Gortmaker	: Allow users with bad cards to avoid full probe.
++    Paul Gortmaker	: PCI probe changes, more PCI cards supported.
++    rjohnson at analogic.com : Changed init order so an interrupt will only
++    occur after memory is allocated for dev->priv. Deallocated memory
++    last in cleanup_modue()
++    Richard Guenther    : Added support for ISAPnP cards
++    Paul Gortmaker	: Discontinued PCI support - use ne2k-pci.c instead.
++    Hayato Fujiwara	: Add m32r support.
++
++*/
++
++/*
++ * From the driver distribution kit by Thomas Redelberger:
++ *
++ * Hardware circuit description (see directory ETHERNEC for schematics)
++ *
++ * As there is no reset line on the CP, a resistor and a capacitor are
++ * used to reset the NE card on power up.
++ *
++ * Reading from the NE card is done by a read cycle on the CP at address
++ * /ROM4 + 512*ISA address as the ISA address lines A0-A4 are connected
++ * to CP A9-A13. /ROM4 going low will start the ISA read cycle, enable
++ * the ISA bus buffers of the NE card and start decoding of the ISA IO
++ * address by the NE card. /ROM4 going high ends the cycle and the
++ * processor latches the data.
++ *
++ * Because the CP is read only writing to the NE card must be done with
++ * the trick to read from addresses that stand for the data. Dummy reads
++ * at /ROM3 base address + data*2 + ISA address*512 effect this. You
++ * might wonder why everything appears to be shifted up one bit. There is
++ * no CP "A0" address line. There are the signals /UDS and /LDS instead
++ * typical for the 68000 family. The original design which generated an
++ * "A0" worked on an ST and an STE but did not on a Falcon.
++ *
++ * The falling edge of /ROM3 enables the CP address lines A1-A8 onto the
++ * data bus and starts the ISA write cycle. The rising edge will end the
++ * ISA write cycle and the NE latches the data. The processor will also
++ * see and just read this same data but that is harmless.
++ * Elmar Hilgart reported that the bus buffer IC shall be an TTL F-type
++ * to keep up with the fast cycles on the Falcon.
++ *
++ * Base addresses:
++ * rom4            EQU     $00fa0000       ; ROM4 base address
++ * rom3            EQU     $00fb0000       ; ROM3 base address
++ *
++ */
++
++/* Routines for the NatSemi-based designs (NE[12]000). */
++
++static const char version1[] =
++"ne.c:v1.10 9/23/94 Donald Becker (becker at scyld.com)\n";
++static const char version2[] =
++"atari_ethernec.c 11/10/06 Michael Schmitz (schmitz at debian.org)\n";
++
++
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/wait.h>
++#include <linux/sched.h>
++#include <linux/errno.h>
++#include <linux/isapnp.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/delay.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/jiffies.h>
++#include <linux/workqueue.h>
++
++#include <asm/system.h>
++#include <asm/atarihw.h>
++#include <asm/atariints.h>
++#include <asm/io.h>
++
++#include "8390.h"
++
++#define DRV_NAME "ethernec"
++
++/* Some defines that people can play with if so inclined. */
++
++/* Do we support clones that don't adhere to 14,15 of the SAprom ? */
++#define SUPPORT_NE_BAD_CLONES
++
++/* Do we perform extra sanity checks on stuff ? */
++/* #define NE_SANITY_CHECK */
++
++/* Do we implement the read before write bugfix ? */
++/* #define NE_RW_BUGFIX */
++
++/* Do we have a non std. amount of memory? (in units of 256 byte pages) */
++/* #define PACKETBUF_MEMSIZE	0x40 */
++
++/* A zero-terminated list of I/O addresses to be probed at boot. */
++#ifndef MODULE
++static unsigned int netcard_portlist[] __initdata = {
++	0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0
++};
++#endif
++
++static struct isapnp_device_id isapnp_clone_list[] __initdata = {
++	{	ISAPNP_CARD_ID('A','X','E',0x2011),
++		ISAPNP_VENDOR('A','X','E'), ISAPNP_FUNCTION(0x2011),
++		(long) "NetGear EA201" },
++	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
++		ISAPNP_VENDOR('E','D','I'), ISAPNP_FUNCTION(0x0216),
++		(long) "NN NE2000" },
++	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
++		ISAPNP_VENDOR('P','N','P'), ISAPNP_FUNCTION(0x80d6),
++		(long) "Generic PNP" },
++	{ }	/* terminate list */
++};
++
++MODULE_DEVICE_TABLE(isapnp, isapnp_clone_list);
++
++#ifdef SUPPORT_NE_BAD_CLONES
++/* A list of bad clones that we none-the-less recognize. */
++static struct { const char *name8, *name16; unsigned char SAprefix[4];}
++bad_clone_list[] __initdata = {
++	{"DE100", "DE200", {0x00, 0xDE, 0x01,}},
++	{"DE120", "DE220", {0x00, 0x80, 0xc8,}},
++	{"DFI1000", "DFI2000", {'D', 'F', 'I',}}, /* Original, eh?  */
++	{"EtherNext UTP8", "EtherNext UTP16", {0x00, 0x00, 0x79}},
++	{"NE1000","NE2000-invalid", {0x00, 0x00, 0xd8}}, /* Ancient real NE1000. */
++	{"NN1000", "NN2000",  {0x08, 0x03, 0x08}}, /* Outlaw no-name clone. */
++	{"4-DIM8","4-DIM16", {0x00,0x00,0x4d,}},  /* Outlaw 4-Dimension cards. */
++	{"Con-Intl_8", "Con-Intl_16", {0x00, 0x00, 0x24}}, /* Connect Int'nl */
++	{"ET-100","ET-200", {0x00, 0x45, 0x54}}, /* YANG and YA clone */
++	{"COMPEX","COMPEX16",{0x00,0x80,0x48}}, /* Broken ISA Compex cards */
++	{"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
++	{"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
++	{"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
++#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
++	{"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
++#endif
++	{"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
++	{NULL,}
++};
++#endif
++
++/* ---- No user-serviceable parts below ---- */
++
++#define NE_BASE	 (dev->base_addr)
++#define NE_CMD		0x00
++#define NE_DATAPORT	0x10	/* NatSemi-defined port window offset. */
++#define NE_RESET	0x1f	/* Issue a read to reset, a write to clear. */
++#define NE_IO_EXTENT	0x20
++
++#define NE1SM_START_PG	0x20	/* First page of TX buffer */
++#define NE1SM_STOP_PG	0x40	/* Last page +1 of RX ring */
++#define NESM_START_PG	0x40	/* First page of TX buffer */
++#define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */
++
++#if defined(CONFIG_PLAT_MAPPI)
++#  define DCR_VAL 0x4b
++#elif defined(CONFIG_PLAT_OAKS32R)  || \
++   defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) || \
++   defined(CONFIG_ATARI_ETHERNEC) || defined(CONFIG_ATARI_ETHERNEC_MODULE)
++#  define DCR_VAL 0x48		/* 8-bit mode */
++#else
++#  define DCR_VAL 0x49
++#endif
++
++#if defined(CONFIG_ATARI_ETHERNEC) || defined(CONFIG_ATARI_ETHERNEC_MODULE)
++#  define ETHERNEC_RTL_8019_BASE 0x300
++#  define ETHERNEC_RTL_8019_IRQ IRQ_MFP_TIMD
++#endif
++
++static int ne_probe1(struct net_device *dev, int ioaddr);
++static int ne_probe_isapnp(struct net_device *dev);
++
++static int ne_open(struct net_device *dev);
++static int ne_close(struct net_device *dev);
++
++static void ne_reset_8390(struct net_device *dev);
++static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
++			    int ring_page);
++static void ne_block_input(struct net_device *dev, int count,
++			   struct sk_buff *skb, int ring_offset);
++static void ne_block_output(struct net_device *dev, const int count,
++			    const unsigned char *buf, const int start_page);
++
++
++/*
++ * The Atari ROM port has no interrupt line, so we poll the card instead.
++ */
++
++static int use_poll;
++
++/*
++ * This is used by cleanup, to prevent the module from being unloaded while
++ * intrpt_routine is still in the task queue
++ */
++static wait_queue_head_t WaitQ;
++
++static struct delayed_work tqueue;
++
++static struct net_device *poll_dev = NULL;
++
++static void atari_ethernec_int(struct work_struct *work)
++{
++	struct net_device *dev = poll_dev;
++
++	if (!dev) {
++		/* If cleanup wants us to die */
++		if (waitqueue_active(&WaitQ))
++			wake_up(&WaitQ);	/* Now cleanup_module can return */
++		else
++			/* Put ourselves back in the task queue */
++			schedule_delayed_work(&tqueue, 1);
++		return;
++	}
++
++	if (netif_running(dev))
++		ei_interrupt(dev->irq, dev);
++
++	/* If cleanup wants us to die */
++	if (waitqueue_active(&WaitQ))
++		wake_up(&WaitQ);	/* Now cleanup_module can return */
++	else
++		/* Put ourselves back in the task queue */
++		schedule_delayed_work(&tqueue, 0); /* reduced delay from 1 */
++}
++
++static void atari_ethernec_start_poll(struct net_device *dev)
++{
++	poll_dev = dev;
++
++	init_waitqueue_head(&WaitQ);
++
++	INIT_DELAYED_WORK(&tqueue, atari_ethernec_int);
++	schedule_delayed_work(&tqueue, 1);
++}
++
++static void atari_ethernec_stop_poll(struct net_device *dev)
++{
++	poll_dev = NULL;
++
++	if (dev)
++		sleep_on(&WaitQ);
++}
++
++
++/*  Probe for various non-shared-memory ethercards.
++
++   NEx000-clone boards have a Station Address PROM (SAPROM) in the packet
++   buffer memory space.  NE2000 clones have 0x57,0x57 in bytes 0x0e,0x0f of
++   the SAPROM, while other supposed NE2000 clones must be detected by their
++   SA prefix.
++
++   Reading the SAPROM from a word-wide card with the 8390 set in byte-wide
++   mode results in doubled values, which can be detected and compensated for.
++
++   The probe is also responsible for initializing the card and filling
++   in the 'dev' and 'ei_status' structures.
++
++   We use the minimum memory size for some ethercard product lines, iff we can't
++   distinguish models.  You can increase the packet buffer size by setting
++   PACKETBUF_MEMSIZE.  Reported Cabletron packet buffer locations are:
++	E1010   starts at 0x100 and ends at 0x2000.
++	E1010-x starts at 0x100 and ends at 0x8000. ("-x" means "more memory")
++	E2010	 starts at 0x100 and ends at 0x4000.
++	E2010-x starts at 0x100 and ends at 0xffff.
++*/
++
++static int __init do_ne_probe(struct net_device *dev)
++{
++	unsigned int base_addr = dev->base_addr;
++	int rv;
++#ifndef MODULE
++	int orig_irq = dev->irq;
++#endif
++
++	/* First check any supplied i/o locations. User knows best. <cough> */
++	if (base_addr > 0x1ff) {	/* Check a single specified location. */
++		rv = ne_probe1(dev, base_addr);
++		if (!rv && use_poll) {
++			/* Seems we have a valid device here; set up polling routine */
++			poll_dev = dev;
++			atari_ethernec_start_poll(dev);
++		}
++		return rv;
++	} else if (base_addr != 0)	/* Don't probe at all. */
++		return -ENXIO;
++
++	/* Then look for any installed ISAPnP clones */
++	if (isapnp_present() && (ne_probe_isapnp(dev) == 0))
++		return 0;
++
++#ifndef MODULE
++	/* Last resort. The semi-risky ISA auto-probe. */
++	for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) {
++		int ioaddr = netcard_portlist[base_addr];
++		dev->irq = orig_irq;
++		rv = ne_probe1(dev, ioaddr);
++		if (rv == 0) {
++			if (use_poll) {
++				poll_dev = dev;
++				atari_ethernec_start_poll(dev);
++			}
++			return 0;
++		}
++	}
++#endif
++
++	return -ENODEV;
++}
++
++#ifndef MODULE
++struct net_device * __init atari_ethernec_probe(int unit)
++{
++	struct net_device *dev;
++	int err;
++
++	if (!MACH_IS_ATARI)
++		return ERR_PTR(-ENODEV);
++
++	dev = alloc_ei_netdev();
++	if (!dev)
++		return ERR_PTR(-ENOMEM);
++
++	sprintf(dev->name, "eth%d", unit);
++	netdev_boot_setup_check(dev);
++
++#if defined(CONFIG_ATARI_ETHERNEC)
++	dev->base_addr = ETHERNEC_RTL_8019_BASE;
++	dev->irq = ETHERNEC_RTL_8019_IRQ;
++#endif
++	err = do_ne_probe(dev);
++	if (err)
++		goto out;
++
++	/* Seems we have a valid device here; set up polling routine */
++	return dev;
++out:
++	free_netdev(dev);
++	return ERR_PTR(err);
++}
++#endif
++
++static int __init ne_probe_isapnp(struct net_device *dev)
++{
++	int i;
++
++	for (i = 0; isapnp_clone_list[i].vendor != 0; i++) {
++		struct pnp_dev *idev = NULL;
++
++		while ((idev = pnp_find_dev(NULL,
++					    isapnp_clone_list[i].vendor,
++					    isapnp_clone_list[i].function,
++					    idev))) {
++			/* Avoid already found cards from previous calls */
++			if (pnp_device_attach(idev) < 0)
++				continue;
++			if (pnp_activate_dev(idev) < 0) {
++				pnp_device_detach(idev);
++				continue;
++			}
++			/* if no io and irq, search for next */
++			if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) {
++				pnp_device_detach(idev);
++				continue;
++			}
++			/* found it */
++			dev->base_addr = pnp_port_start(idev, 0);
++			dev->irq = pnp_irq(idev, 0);
++			printk(KERN_INFO "atari_ethernec.c: ISAPnP reports %s at i/o %#lx, irq %d.\n",
++			       (char *) isapnp_clone_list[i].driver_data,
++			       dev->base_addr, dev->irq);
++			if (ne_probe1(dev, dev->base_addr) != 0) {	/* Shouldn't happen. */
++				printk(KERN_ERR "atari_ethernec.c: Probe of ISAPnP card at %#lx failed.\n",
++				       dev->base_addr);
++				pnp_device_detach(idev);
++				return -ENXIO;
++			}
++			ei_status.priv = (unsigned long)idev;
++			break;
++		}
++		if (!idev)
++			continue;
++		return 0;
++	}
++
++	return -ENODEV;
++}
++
++static int __init ne_probe1(struct net_device *dev, int ioaddr)
++{
++	int i;
++	unsigned char SA_prom[32];
++	int wordlength = 2;
++	const char *name = NULL;
++	int start_page, stop_page;
++	int neX000, ctron, copam, bad_card;
++	int reg0, ret;
++	static unsigned version_printed;
++
++	if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME))
++		return -EBUSY;
++
++	reg0 = inb_p(ioaddr);
++	if (reg0 == 0xFF) {
++		ret = -ENODEV;
++		goto err_out;
++	}
++
++	/* Do a preliminary verification that we have a 8390. */
++	{
++		int regd;
++		outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
++		regd = inb_p(ioaddr + 0x0d);
++		outb_p(0xff, ioaddr + 0x0d);
++		outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
++		inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
++		if (inb_p(ioaddr + EN0_COUNTER0) != 0) {
++			outb_p(reg0, ioaddr);
++			outb_p(regd, ioaddr + 0x0d);	/* Restore the old values. */
++			ret = -ENODEV;
++			goto err_out;
++		}
++	}
++
++	if (ei_debug && version_printed++ == 0)
++		printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
++
++	/* A user with a poor card that fails to ack the reset, or that
++	   does not have a valid 0x57,0x57 signature can still use this
++	   without having to recompile. Specifying an i/o address along
++	   with an otherwise unused dev->mem_end value of "0xBAD" will
++	   cause the driver to skip these parts of the probe. */
++
++	bad_card = ((dev->base_addr != 0) && (dev->mem_end == 0xbad));
++
++	/* Reset card. Who knows what dain-bramaged state it was left in. */
++
++	{
++		unsigned long reset_start_time = jiffies;
++
++		/* DON'T change these to inb_p/outb_p or reset will fail on clones. */
++		outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
++
++		while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0) {
++			if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) {
++				if (bad_card) {
++					printk(" (warning: no reset ack)");
++					break;
++				} else {
++					// MSch: ARAnyM exits here
++					printk(" not found (no reset ack).\n");
++					ret = -ENODEV;
++					goto err_out;
++				}
++			}
++		}
++
++		outb_p(0xff, ioaddr + EN0_ISR);		/* Ack all intr. */
++	}
++
++	/* Read the 16 bytes of station address PROM.
++	   We must first initialize registers, similar to NS8390_init(eifdev, 0).
++	   We can't reliably read the SAPROM address without this.
++	   (I learned the hard way!). */
++	{
++		struct {unsigned char value, offset; } program_seq[] =
++		{
++			{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
++			{0x48,	EN0_DCFG},	/* Set byte-wide (0x48) access. */
++			{0x00,	EN0_RCNTLO},	/* Clear the count regs. */
++			{0x00,	EN0_RCNTHI},
++			{0x00,	EN0_IMR},	/* Mask completion irq. */
++			{0xFF,	EN0_ISR},
++			{E8390_RXOFF, EN0_RXCR},	/* 0x20  Set to monitor */
++			{E8390_TXOFF, EN0_TXCR},	/* 0x02  and loopback mode. */
++			{32,	EN0_RCNTLO},
++			{0x00,	EN0_RCNTHI},
++			{0x00,	EN0_RSARLO},	/* DMA starting at 0x0000. */
++			{0x00,	EN0_RSARHI},
++			{E8390_RREAD+E8390_START, E8390_CMD},
++		};
++
++		for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
++			outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
++
++	}
++	for (i = 0; i < 32 /*sizeof(SA_prom)*/; i += 2) {
++		SA_prom[i] = inb(ioaddr + NE_DATAPORT);
++		SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
++		if (SA_prom[i] != SA_prom[i+1])
++			wordlength = 1;
++	}
++
++	if (wordlength == 2) {
++		for (i = 0; i < 16; i++)
++			SA_prom[i] = SA_prom[i+i];
++		/* We must set the 8390 for word mode. */
++		outb_p(DCR_VAL, ioaddr + EN0_DCFG);
++		start_page = NESM_START_PG;
++
++		/*
++		 * Realtek RTL8019AS datasheet says that the PSTOP register
++		 * shouldn't exceed 0x60 in 8-bit mode.
++		 * This chip can be identified by reading the signature from
++		 * the  remote byte count registers (otherwise write-only)...
++		 */
++		if ((DCR_VAL & 0x01) == 0 &&		/* 8-bit mode */
++		    inb(ioaddr + EN0_RCNTLO) == 0x50 &&
++		    inb(ioaddr + EN0_RCNTHI) == 0x70)
++			stop_page = 0x60;
++		else
++			stop_page = NESM_STOP_PG;
++	} else {
++		start_page = NE1SM_START_PG;
++		stop_page  = NE1SM_STOP_PG;
++	}
++
++#if  defined(CONFIG_PLAT_MAPPI) || defined(CONFIG_PLAT_OAKS32R)
++	neX000 = ((SA_prom[14] == 0x57 && SA_prom[15] == 0x57)
++		|| (SA_prom[14] == 0x42 && SA_prom[15] == 0x42));
++#else
++	neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57);
++#endif
++	ctron =  (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
++	copam =  (SA_prom[14] == 0x49 && SA_prom[15] == 0x00);
++
++	/* Set up the rest of the parameters. */
++	if (neX000 || bad_card || copam) {
++		name = (wordlength == 2) ? "NE2000" : "NE1000";
++	} else if (ctron) {
++		name = (wordlength == 2) ? "Ctron-8" : "Ctron-16";
++		start_page = 0x01;
++		stop_page = (wordlength == 2) ? 0x40 : 0x20;
++	} else {
++#ifdef SUPPORT_NE_BAD_CLONES
++		/* Ack!  Well, there might be a *bad* NE*000 clone there.
++		   Check for total bogus addresses. */
++		for (i = 0; bad_clone_list[i].name8; i++) {
++			if (SA_prom[0] == bad_clone_list[i].SAprefix[0] &&
++			    SA_prom[1] == bad_clone_list[i].SAprefix[1] &&
++			    SA_prom[2] == bad_clone_list[i].SAprefix[2]) {
++				if (wordlength == 2) {
++					name = bad_clone_list[i].name16;
++				} else {
++					name = bad_clone_list[i].name8;
++				}
++				break;
++			}
++		}
++		if (bad_clone_list[i].name8 == NULL) {
++			printk(" not found (invalid signature %2.2x %2.2x).\n",
++			       SA_prom[14], SA_prom[15]);
++			ret = -ENXIO;
++			goto err_out;
++		}
++#else
++		printk(" not found.\n");
++		ret = -ENXIO;
++		goto err_out;
++#endif
++	}
++
++	if (dev->irq < 2) {
++		unsigned long cookie = probe_irq_on();
++		outb_p(0x50, ioaddr + EN0_IMR);	/* Enable one interrupt. */
++		outb_p(0x00, ioaddr + EN0_RCNTLO);
++		outb_p(0x00, ioaddr + EN0_RCNTHI);
++		outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */
++		mdelay(10);		/* wait 10ms for interrupt to propagate */
++		outb_p(0x00, ioaddr + EN0_IMR);		/* Mask it again. */
++		dev->irq = probe_irq_off(cookie);
++		if (ei_debug > 2)
++			printk(" autoirq is %d\n", dev->irq);
++	} else if (dev->irq == 2)
++		/* Fixup for users that don't know that IRQ 2 is really IRQ 9,
++		   or don't know which one to set. */
++		dev->irq = 9;
++
++	/*
++	 * use timer based polling!
++	 */
++	if (! dev->irq) {
++		printk(" failed to detect IRQ line. Assuming irq %d\n",
++		       ETHERNEC_RTL_8019_IRQ);
++		dev->irq = ETHERNEC_RTL_8019_IRQ;
++		/* timer routine set up in atari_ethernec_probe() */
++		if (dev->irq == IRQ_MFP_TIMD) {
++			/* set Timer D data Register */
++			mfp.tim_dt_d = 123;	/* 200 Hz */
++			/* start timer D, div = 1:100 */
++			mfp.tim_ct_cd = (mfp.tim_ct_cd & 0xf0) | 0x6;
++		}
++		/* Must make this shared in case other timer ints are needed */
++		ret = request_irq(dev->irq, ei_interrupt, IRQF_SHARED, name, dev);
++		if (ret) {
++			printk(" unable to get IRQ %d (errno=%d), polling instead.\n",
++			       dev->irq, ret);
++			use_poll = 1;
++		}
++	} else {
++
++		/* Snarf the interrupt now.  There's no point in waiting since we cannot
++		   share and the board will usually be enabled. */
++		ret = request_irq(dev->irq, ei_interrupt, 0, name, dev);
++		if (ret) {
++			printk(" unable to get IRQ %d (errno=%d).\n", dev->irq, ret);
++			goto err_out;
++		}
++	}
++	dev->base_addr = ioaddr;
++
++#ifdef CONFIG_PLAT_MAPPI
++	outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
++		ioaddr + E8390_CMD); /* 0x61 */
++	for (i = 0; i < ETHER_ADDR_LEN; i++) {
++		dev->dev_addr[i] = SA_prom[i] = inb_p(ioaddr + EN1_PHYS_SHIFT(i));
++		printk(" %2.2x", SA_prom[i]);
++	}
++#else
++	for (i = 0; i < ETHER_ADDR_LEN; i++) {
++		printk(" %2.2x", SA_prom[i]);
++		dev->dev_addr[i] = SA_prom[i];
++	}
++#endif
++
++	printk("\n%s: %s found at %#x, using IRQ %d.\n",
++		dev->name, name, ioaddr, dev->irq);
++
++	ei_status.name = name;
++	ei_status.tx_start_page = start_page;
++	ei_status.stop_page = stop_page;
++
++	/* Use 16-bit mode only if this wasn't overridden by DCR_VAL */
++	ei_status.word16 = (wordlength == 2 && (DCR_VAL & 0x01));
++
++	ei_status.rx_start_page = start_page + TX_PAGES;
++#ifdef PACKETBUF_MEMSIZE
++	/* Allow the packet buffer size to be overridden by know-it-alls. */
++	ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
++#endif
++
++	ei_status.reset_8390 = &ne_reset_8390;
++	ei_status.block_input = &ne_block_input;
++	ei_status.block_output = &ne_block_output;
++	ei_status.get_8390_hdr = &ne_get_8390_hdr;
++	ei_status.priv = 0;
++	dev->open = &ne_open;
++	dev->stop = &ne_close;
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	dev->poll_controller = ei_poll;
++#endif
++	NS8390_init(dev, 0);
++
++	ret = register_netdev(dev);
++	if (ret)
++		goto out_irq;
++	return 0;
++
++out_irq:
++	free_irq(dev->irq, dev);
++err_out:
++	release_region(ioaddr, NE_IO_EXTENT);
++	return ret;
++}
++
++static int ne_open(struct net_device *dev)
++{
++	ei_open(dev);
++	return 0;
++}
++
++static int ne_close(struct net_device *dev)
++{
++	if (ei_debug > 1)
++		printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
++	ei_close(dev);
++	return 0;
++}
++
++/* Hard reset the card.  This used to pause for the same period that a
++   8390 reset command required, but that shouldn't be necessary. */
++
++static void ne_reset_8390(struct net_device *dev)
++{
++	unsigned long reset_start_time = jiffies;
++
++	if (ei_debug > 1)
++		printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies);
++
++	/* DON'T change these to inb_p/outb_p or reset will fail on clones. */
++	outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
++
++	ei_status.txing = 0;
++	ei_status.dmaing = 0;
++
++	/* This check _should_not_ be necessary, omit eventually. */
++	while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) {
++		if (time_after(jiffies, reset_start_time + 2*HZ/100)) {
++			printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n",
++			       dev->name);
++			break;
++		}
++	}
++	outb_p(ENISR_RESET, NE_BASE + EN0_ISR);	/* Ack intr. */
++}
++
++/* Grab the 8390 specific header. Similar to the block_input routine, but
++   we don't need to be concerned with ring wrap as the header will be at
++   the start of a page, so we optimize accordingly. */
++
++static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
++{
++	int nic_base = dev->base_addr;
++
++	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
++
++	if (ei_status.dmaing)
++	{
++		printk(KERN_EMERG "%s: DMAing conflict in ne_get_8390_hdr "
++			"[DMAstat:%d][irqlock:%d].\n",
++			dev->name, ei_status.dmaing, ei_status.irqlock);
++		return;
++	}
++
++	ei_status.dmaing |= 0x01;
++	outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
++	outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
++	outb_p(0, nic_base + EN0_RCNTHI);
++	outb_p(0, nic_base + EN0_RSARLO);		/* On page boundary */
++	outb_p(ring_page, nic_base + EN0_RSARHI);
++	outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
++
++	if (ei_status.word16)
++		insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
++	else
++		insb(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
++
++	outb_p(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
++	ei_status.dmaing &= ~0x01;
++
++	le16_to_cpus(&hdr->count);
++}
++
++/* Block input and output, similar to the Crynwr packet driver.  If you
++   are porting to a new ethercard, look at the packet driver source for hints.
++   The NEx000 doesn't share the on-board packet memory -- you have to put
++   the packet out through the "remote DMA" dataport using outb. */
++
++static void ne_block_input(struct net_device *dev, int count,
++			   struct sk_buff *skb, int ring_offset)
++{
++#ifdef NE_SANITY_CHECK
++	int xfer_count = count;
++#endif
++	int nic_base = dev->base_addr;
++	char *buf = skb->data;
++
++	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
++	if (ei_status.dmaing) {
++		printk(KERN_EMERG "%s: DMAing conflict in ne_block_input "
++			"[DMAstat:%d][irqlock:%d].\n",
++			dev->name, ei_status.dmaing, ei_status.irqlock);
++		return;
++	}
++	ei_status.dmaing |= 0x01;
++	outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
++	outb_p(count & 0xff, nic_base + EN0_RCNTLO);
++	outb_p(count >> 8, nic_base + EN0_RCNTHI);
++	outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
++	outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
++	outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
++
++	if (ei_status.word16) {
++		insw(NE_BASE + NE_DATAPORT,buf,count>>1);
++		if (count & 0x01) {
++			buf[count-1] = inb(NE_BASE + NE_DATAPORT);
++#ifdef NE_SANITY_CHECK
++			xfer_count++;
++#endif
++		}
++	} else {
++		insb(NE_BASE + NE_DATAPORT, buf, count);
++	}
++
++#ifdef NE_SANITY_CHECK
++	/* This was for the ALPHA version only, but enough people have
++	   been encountering problems so it is still here.  If you see
++	   this message you either 1) have a slightly incompatible clone
++	   or 2) have noise/speed problems with your bus. */
++
++	if (ei_debug > 1) {
++		/* DMA termination address check... */
++		int addr, tries = 20;
++		do {
++			/* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
++			   -- it's broken for Rx on some cards! */
++			int high = inb_p(nic_base + EN0_RSARHI);
++			int low = inb_p(nic_base + EN0_RSARLO);
++			addr = (high << 8) + low;
++			if (((ring_offset + xfer_count) & 0xff) == low)
++				break;
++		} while (--tries > 0);
++		if (tries <= 0)
++			printk(KERN_WARNING "%s: RX transfer address mismatch,"
++				"%#4.4x (expected) vs. %#4.4x (actual).\n",
++				dev->name, ring_offset + xfer_count, addr);
++	}
++#endif
++	outb_p(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
++	ei_status.dmaing &= ~0x01;
++}
++
++static void ne_block_output(struct net_device *dev, int count,
++			    const unsigned char *buf, const int start_page)
++{
++	int nic_base = NE_BASE;
++	unsigned long dma_start;
++#ifdef NE_SANITY_CHECK
++	int retries = 0;
++#endif
++
++	/* Round the count up for word writes.  Do we need to do this?
++	   What effect will an odd byte count have on the 8390?
++	   I should check someday. */
++
++	if (ei_status.word16 && (count & 0x01))
++		count++;
++
++	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
++	if (ei_status.dmaing) {
++		printk(KERN_EMERG "%s: DMAing conflict in ne_block_output."
++			"[DMAstat:%d][irqlock:%d]\n",
++			dev->name, ei_status.dmaing, ei_status.irqlock);
++		return;
++	}
++	ei_status.dmaing |= 0x01;
++	/* We should already be in page 0, but to be safe... */
++	outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
++
++#ifdef NE_SANITY_CHECK
++retry:
++#endif
++
++#ifdef NE8390_RW_BUGFIX
++	/* Handle the read-before-write bug the same way as the
++	   Crynwr packet driver -- the NatSemi method doesn't work.
++	   Actually this doesn't always work either, but if you have
++	   problems with your NEx000 this is better than nothing! */
++
++	outb_p(0x42, nic_base + EN0_RCNTLO);
++	outb_p(0x00,   nic_base + EN0_RCNTHI);
++	outb_p(0x42, nic_base + EN0_RSARLO);
++	outb_p(0x00, nic_base + EN0_RSARHI);
++	outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
++	/* Make certain that the dummy read has occurred. */
++	udelay(6);
++#endif
++
++	outb_p(ENISR_RDC, nic_base + EN0_ISR);
++
++	/* Now the normal output. */
++	outb_p(count & 0xff, nic_base + EN0_RCNTLO);
++	outb_p(count >> 8,   nic_base + EN0_RCNTHI);
++	outb_p(0x00, nic_base + EN0_RSARLO);
++	outb_p(start_page, nic_base + EN0_RSARHI);
++
++	outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
++	if (ei_status.word16)
++		outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
++	else
++		outsb(NE_BASE + NE_DATAPORT, buf, count);
++
++	dma_start = jiffies;
++
++#ifdef NE_SANITY_CHECK
++	/* This was for the ALPHA version only, but enough people have
++	   been encountering problems so it is still here. */
++
++	if (ei_debug > 1) {
++		/* DMA termination address check... */
++		int addr, tries = 20;
++		do {
++			int high = inb_p(nic_base + EN0_RSARHI);
++			int low = inb_p(nic_base + EN0_RSARLO);
++			addr = (high << 8) + low;
++			if ((start_page << 8) + count == addr)
++				break;
++		} while (--tries > 0);
++
++		if (tries <= 0) {
++			printk(KERN_WARNING "%s: Tx packet transfer address mismatch,"
++				"%#4.4x (expected) vs. %#4.4x (actual).\n",
++				dev->name, (start_page << 8) + count, addr);
++			if (retries++ == 0)
++				goto retry;
++		}
++	}
++#endif
++
++	while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) {
++		if (time_after(jiffies, dma_start + 2*HZ/100)) {		/* 20ms */
++			printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
++			ne_reset_8390(dev);
++			NS8390_init(dev, 1);
++			break;
++		}
++	}
++
++	outb_p(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
++	ei_status.dmaing &= ~0x01;
++	return;
++}
++
++
++#ifdef MODULE
++#define MAX_NE_CARDS	4	/* Max number of NE cards per module */
++static struct net_device *dev_ne[MAX_NE_CARDS];
++static int io[MAX_NE_CARDS];
++static int irq[MAX_NE_CARDS];
++static int bad[MAX_NE_CARDS];	/* 0xbad = bad sig or no reset ack */
++
++module_param_array(io, int, NULL, 0);
++module_param_array(irq, int, NULL, 0);
++module_param_array(bad, int, NULL, 0);
++module_param(use_poll, int, 0);
++MODULE_PARM_DESC(io, "I/O base address(es),required");
++MODULE_PARM_DESC(irq, "IRQ number(s)");
++MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures");
++MODULE_PARM_DESC(use_poll, "Use timer interrupt to poll driver");
++MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver");
++MODULE_LICENSE("GPL");
++
++/* This is set up so that no ISA autoprobe takes place. We can't guarantee
++that the ne2k probe is the last 8390 based probe to take place (as it
++is at boot) and so the probe will get confused by any other 8390 cards.
++ISA device autoprobes on a running machine are not recommended anyway. */
++
++int __init init_module(void)
++{
++	int this_dev, found = 0;
++
++	if (!MACH_IS_ATARI)
++		return -ENODEV;
++
++	for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
++		struct net_device *dev = alloc_ei_netdev();
++		if (!dev)
++			break;
++		dev->irq = irq[this_dev];
++		dev->mem_end = bad[this_dev];
++		dev->base_addr = io[this_dev];
++		if (do_ne_probe(dev) == 0) {
++			dev_ne[found++] = dev;
++			continue;
++		}
++		free_netdev(dev);
++		if (found)
++			break;
++		if (io[this_dev] != 0)
++			printk(KERN_WARNING "atari_ethernec.c: No NE*000 card found at i/o = %#x\n", io[this_dev]);
++		else
++			printk(KERN_NOTICE "atari_ethernec.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n");
++		return -ENXIO;
++	}
++	if (found)
++		return 0;
++	return -ENODEV;
++}
++
++static void cleanup_card(struct net_device *dev)
++{
++	struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
++	if (idev)
++		pnp_device_detach(idev);
++	free_irq(dev->irq, dev);
++	release_region(dev->base_addr, NE_IO_EXTENT);
++}
++
++void cleanup_module(void)
++{
++	int this_dev;
++
++	for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
++		struct net_device *dev = dev_ne[this_dev];
++		if (dev) {
++			if (use_poll)
++				atari_ethernec_stop_poll(dev);
++			unregister_netdev(dev);
++			cleanup_card(dev);
++			free_netdev(dev);
++		}
++	}
++}
++#endif /* MODULE */
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0013-atari-ethernec-fixes.diff.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0013-atari-ethernec-fixes.diff.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,72 @@
+From a4e488d703583baaea36ba6e708440e828989aee Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at debian.org>
+Date: Tue, 18 Nov 2008 21:01:18 +0100
+Subject: [PATCH] atari-ethernec-fixes.diff
+
+Use wrapper around ei_interrupt to prevent delivery of (timer!) interrupts
+before card is opened.
+
+Limit IO addresses to 0x300 (this is hardwired on the bus adapter anyway, and
+the card needs to be programmed to use that IO in some way before the adapter
+can work).
+
+Preset io=0x300 for module use.
+
+Signed-off-by: Michael Schmitz <schmitz at debian.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/net/atari_ethernec.c |   16 ++++++++++++----
+ 1 files changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/atari_ethernec.c b/drivers/net/atari_ethernec.c
+index 97f683a..74eeae4 100644
+--- a/drivers/net/atari_ethernec.c
++++ b/drivers/net/atari_ethernec.c
+@@ -124,7 +124,7 @@ static const char version2[] =
+ /* A zero-terminated list of I/O addresses to be probed at boot. */
+ #ifndef MODULE
+ static unsigned int netcard_portlist[] __initdata = {
+-	0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0
++	0x300, 0
+ };
+ #endif
+ 
+@@ -227,6 +227,14 @@ static struct delayed_work tqueue;
+ 
+ static struct net_device *poll_dev = NULL;
+ 
++irqreturn_t atari_ei_interrupt(int irq, void *dev_id)
++{
++	struct net_device *dev = dev_id;
++	if (netif_running(dev))
++		return ei_interrupt(dev->irq, dev);
++	return IRQ_NONE;
++}
++
+ static void atari_ethernec_int(struct work_struct *work)
+ {
+ 	struct net_device *dev = poll_dev;
+@@ -619,7 +627,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
+ 			mfp.tim_ct_cd = (mfp.tim_ct_cd & 0xf0) | 0x6;
+ 		}
+ 		/* Must make this shared in case other timer ints are needed */
+-		ret = request_irq(dev->irq, ei_interrupt, IRQF_SHARED, name, dev);
++		ret = request_irq(dev->irq, atari_ei_interrupt, IRQF_SHARED, name, dev);
+ 		if (ret) {
+ 			printk(" unable to get IRQ %d (errno=%d), polling instead.\n",
+ 			       dev->irq, ret);
+@@ -941,9 +949,9 @@ retry:
+ 
+ 
+ #ifdef MODULE
+-#define MAX_NE_CARDS	4	/* Max number of NE cards per module */
++#define MAX_NE_CARDS	1	/* Max number of NE cards per module */
+ static struct net_device *dev_ne[MAX_NE_CARDS];
+-static int io[MAX_NE_CARDS];
++static int io[MAX_NE_CARDS] = { 0x300 };
+ static int irq[MAX_NE_CARDS];
+ static int bad[MAX_NE_CARDS];	/* 0xbad = bad sig or no reset ack */
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0014-m68k-Atari-SCC-serial-driver-needs-atari_SCC_init_d.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0014-m68k-Atari-SCC-serial-driver-needs-atari_SCC_init_d.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,39 @@
+From 79faa0ebb51dbbf2f6fe6918fb83dc9e1f6605f4 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 20:54:05 +0100
+Subject: [PATCH] m68k: Atari SCC serial driver needs atari_SCC_init_done
+
+commit 5575d0a3c9676b2886adad67dd4b2ac126a49f1f ("m68k/atari/debug.c: possible
+cleanups") removed atari_SCC_init_done, which we now need again
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/atari/debug.c |    5 +++++
+ 1 files changed, 5 insertions(+), 0 deletions(-)
+
+diff --git a/arch/m68k/atari/debug.c b/arch/m68k/atari/debug.c
+index 28efdc3..24dd582 100644
+--- a/arch/m68k/atari/debug.c
++++ b/arch/m68k/atari/debug.c
+@@ -20,6 +20,10 @@
+ #include <asm/atarihw.h>
+ #include <asm/atariints.h>
+ 
++/* Flag that Modem1 port is already initialized and used */
++int atari_SCC_init_done;
++EXPORT_SYMBOL(atari_SCC_init_done);
++
+ /* Can be set somewhere, if a SCC master reset has already be done and should
+  * not be repeated; used by kgdb */
+ int atari_SCC_reset_done;
+@@ -259,6 +263,7 @@ static void __init atari_init_scc_port(int cflag)
+ 	SCC_WRITE(5, reg5 | 8);
+ 
+ 	atari_SCC_reset_done = 1;
++	atari_SCC_init_done = 1;
+ }
+ 
+ static void __init atari_init_midi_port(int cflag)
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0015-m68k-Atari-SCC-serial-driver-needs-CONFIG_ATARI_SCC.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0015-m68k-Atari-SCC-serial-driver-needs-CONFIG_ATARI_SCC.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,48 @@
+From 9d734c3da348553e648414c9e7fd73fc3ad99d4a Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 20:54:05 +0100
+Subject: [PATCH] m68k: Atari SCC serial driver needs CONFIG_ATARI_SCC
+
+commit 7ccaee5cadd7a771773bbb878e139697511ebdde ("m68k/Atari: remove the dead
+ATARI_SCC{,_DMA} options") removed CONFIG_ATARI_SCC, which we now need again
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/Kconfig |   14 +++++++++++++-
+ 1 files changed, 13 insertions(+), 1 deletions(-)
+
+diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
+index 6fe481f..b953982 100644
+--- a/arch/m68k/Kconfig
++++ b/arch/m68k/Kconfig
+@@ -520,6 +520,18 @@ config ATARI_MFPSER
+ 	  Note for Falcon users: You also have an MFP port, it's just not
+ 	  wired to the outside... But you could use the port under Linux.
+ 
++config ATARI_SCC
++	tristate "Atari SCC serial support"
++	depends on ATARI
++	---help---
++	  If you have serial ports based on a Zilog SCC chip (Modem2, Serial2,
++	  LAN) and like to use them under Linux, say Y. All built-in SCC's are
++	  supported (TT, MegaSTE, Falcon), and also the ST-ESCC. If you have
++	  two connectors for channel A (Serial2 and LAN), they are visible as
++	  two separate devices.
++
++	  To compile this driver as a module, choose M here.
++
+ config ATARI_MIDI
+ 	tristate "Atari MIDI serial support"
+ 	depends on ATARI
+@@ -636,7 +648,7 @@ config DN_SERIAL
+ 
+ config SERIAL_CONSOLE
+ 	bool "Support for serial port console"
+-	depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL)
++	depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_SCC=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL)
+ 	---help---
+ 	  If you say Y here, it will be possible to use a serial port as the
+ 	  system console (the system console is the device which receives all
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0016-m68k-Atari-SCC-serial-driver.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0016-m68k-Atari-SCC-serial-driver.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,1745 @@
+From fb336fc657cbefffbd5b2b2ad762554cdad1596b Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at opal.biophys.uni-duesseldorf.de>
+Date: Tue, 18 Nov 2008 20:54:06 +0100
+Subject: [PATCH] m68k: Atari SCC serial driver
+
+Atari SCC serial driver - this one works less well in 2.6 than it did in 2.4,
+most likely due to the way flip buffer push is handled now - i.e. no
+immediate push of received characters to the line disc. if the handler
+runs in interrupt context, and the bottom half for pushing is run as
+delayed task. 9 out of 10 ping packets end up in the bit bucket this way.
+I haven't figured out how to prevent overruns yet, and getting this right
+will require a bit more testing.
+
+Anyway, the basics are working, and maybe someone can figure out a better
+way to push characters up to the ldisc.
+
+Signed-off-by: Michael Schmitz <schmitz at debian.org>
+Signed-off-by: Roman Zippel <zippel at linux-m68k.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/char/Makefile    |    1 +
+ drivers/char/atari_scc.c | 1699 ++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 1700 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/char/atari_scc.c
+
+diff --git a/drivers/char/Makefile b/drivers/char/Makefile
+index 19a79dd..1c782a7 100644
+--- a/drivers/char/Makefile
++++ b/drivers/char/Makefile
+@@ -32,6 +32,7 @@ obj-$(CONFIG_DIGIEPCA)		+= epca.o
+ obj-$(CONFIG_SPECIALIX)		+= specialix.o
+ obj-$(CONFIG_MOXA_INTELLIO)	+= moxa.o
+ obj-$(CONFIG_A2232)		+= ser_a2232.o generic_serial.o
++obj-$(CONFIG_ATARI_SCC)		+= atari_scc.o generic_serial.o
+ obj-$(CONFIG_ATARI_DSP56K)	+= dsp56k.o
+ obj-$(CONFIG_MOXA_SMARTIO)	+= mxser.o
+ obj-$(CONFIG_COMPUTONE)		+= ip2/
+diff --git a/drivers/char/atari_scc.c b/drivers/char/atari_scc.c
+new file mode 100644
+index 0000000..08cb523
+--- /dev/null
++++ b/drivers/char/atari_scc.c
+@@ -0,0 +1,1699 @@
++/*
++ * Atari TT/Falcon Am8530 SCC serial ports implementation.
++ *
++ * Copyright 2005 Michael Schmitz
++ *
++ * Based on:
++ *   drivers/char/vme_scc.c: MVME147, MVME162, BVME6000 SCC serial ports
++ *   implementation.
++ *   Copyright 1999 Richard Hirst <richard at sleepie.demon.co.uk>
++ *
++ * which, in turn, was
++ *
++ * Based on atari_SCC.c which was
++ *   Copyright 1994-95 Roman Hodek <Roman.Hodek at informatik.uni-erlangen.de>
++ *   Partially based on PC-Linux serial.c by Linus Torvalds and Theodore Ts'o
++ *
++ * 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/module.h>
++#include <linux/kdev_t.h>
++#include <asm/io.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/ioport.h>
++#include <linux/interrupt.h>
++#include <linux/errno.h>
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/mm.h>
++#include <linux/serial.h>
++#include <linux/fcntl.h>
++#include <linux/major.h>
++#include <linux/delay.h>
++#include <linux/slab.h>
++#include <linux/miscdevice.h>
++#include <linux/console.h>
++#include <linux/init.h>
++#include <asm/setup.h>
++#include <asm/uaccess.h>
++#include <asm/bootinfo.h>
++
++#include <asm/atarihw.h>
++#include <asm/atariints.h>
++
++#include <linux/generic_serial.h>
++#include "scc.h"
++
++#define CONFIG_TT_SCC     1
++#define CONFIG_FALCON_SCC 1
++
++#define CHANNEL_A	0
++#define CHANNEL_B	1
++
++#define SCC_MINOR_BASE	64
++
++/* Shadows for all SCC write registers */
++static unsigned char scc_shadow[2][16];
++
++/* Location to access for SCC register access delay */
++static volatile unsigned char *scc_del = NULL;
++
++/* To keep track of STATUS_REG state for detection of Ext/Status int source */
++static unsigned char scc_last_status_reg[2];
++
++/***************************** Prototypes *****************************/
++
++/* Function prototypes */
++static void scc_disable_tx_interrupts(void *ptr);
++static void scc_enable_tx_interrupts(void *ptr);
++static void scc_disable_rx_interrupts(void *ptr);
++static void scc_enable_rx_interrupts(void *ptr);
++static int scc_get_CD(void *ptr);
++static void scc_shutdown_port(void *ptr);
++static int scc_set_real_termios(void *ptr);
++static void scc_hungup(void *ptr);
++static void scc_close(void *ptr);
++static int scc_chars_in_buffer(void *ptr);
++static int scc_open(struct tty_struct *tty, struct file *filp);
++static int scc_ioctl(struct tty_struct *tty, struct file *filp,
++		     unsigned int cmd, unsigned long arg);
++static void scc_throttle(struct tty_struct *tty);
++static void scc_unthrottle(struct tty_struct *tty);
++static irqreturn_t scc_tx_int(int irq, void *data);
++static irqreturn_t scc_rx_int(int irq, void *data);
++static irqreturn_t scc_stat_int(int irq, void *data);
++static irqreturn_t scc_spcond_int(int irq, void *data);
++static void scc_setsignals(struct scc_port *port, int dtr, int rts);
++static void scc_break_ctl(struct tty_struct *tty, int break_state);
++
++static struct tty_driver *scc_driver;
++
++static struct scc_port scc_ports[2];
++
++/*
++ * Flags to indicate one of the serial ports has already been initialized by the
++ * serial debug driver. We may want to hold off reinitializing ...
++ */
++
++/* Flag that Modem1 port is already initialized and used */
++extern int atari_SCC_init_done;
++/* Can be set somewhere, if a SCC master reset has already be done and should
++ * not be repeated; used by kgdb */
++extern int atari_SCC_reset_done;
++
++/*---------------------------------------------------------------------------
++ * Interface from generic_serial.c back here
++ *--------------------------------------------------------------------------*/
++
++static struct real_driver scc_real_driver = {
++	.disable_tx_interrupts	= scc_disable_tx_interrupts,
++	.enable_tx_interrupts	= scc_enable_tx_interrupts,
++	.disable_rx_interrupts	= scc_disable_rx_interrupts,
++	.enable_rx_interrupts	= scc_enable_rx_interrupts,
++	.get_CD			= scc_get_CD,
++	.shutdown_port		= scc_shutdown_port,
++	.set_real_termios	= scc_set_real_termios,
++	.chars_in_buffer	= scc_chars_in_buffer,
++	.close			= scc_close,
++	.hungup			= scc_hungup,
++};
++
++static struct tty_operations scc_ops = {
++	.open			= scc_open,
++	.close			= gs_close,
++	.write			= gs_write,
++	.put_char		= gs_put_char,
++	.flush_chars		= gs_flush_chars,
++	.write_room		= gs_write_room,
++	.chars_in_buffer	= gs_chars_in_buffer,
++	.flush_buffer		= gs_flush_buffer,
++	.ioctl			= scc_ioctl,
++	.throttle		= scc_throttle,
++	.unthrottle		= scc_unthrottle,
++	.set_termios		= gs_set_termios,
++	.stop			= gs_stop,
++	.start			= gs_start,
++	.hangup			= gs_hangup,
++	.break_ctl		= scc_break_ctl,
++};
++
++/* BRG values for the standard speeds and the various clock sources */
++
++typedef struct {
++	unsigned clksrc;		/* clock source to use or -1 for not possible */
++	unsigned div;			/* divisor: 1, 2 and 4 correspond to
++					 * direct 1:16, 1:32 and 1:64 modes,
++					 * divisors >= 4 yield a BRG value of
++					 * div/2-2 (in 1:16 mode)
++					 */
++} BAUD_ENTRY;
++
++/* A pointer for each channel to the current baud table */
++static BAUD_ENTRY *scc_baud_table[2];
++
++/* Baud table format:
++ *
++ * Each entry consists of the clock source (CLK_RTxC, CLK_TRxC or
++ * CLK_PCLK) and a divisor. The following rules apply to the divisor:
++ *
++ *   - CLK_RTxC: 1 or even (1, 2 and 4 are the direct modes, > 4 use
++ *               the BRG)
++ *
++ *   - CLK_TRxC: 1, 2 or 4 (no BRG, only direct modes possible)
++ *
++ *   - CLK_PCLK: >= 4 and even (no direct modes, only BRG)
++ *
++ */
++
++/* This table is used if RTxC = 3.672 MHz. This is the case for TT's
++ * channel A and for both channels on the Mega STE/Falcon. (TRxC is unused)
++ */
++
++static BAUD_ENTRY bdtab_norm[20] = {
++	/* B0      */ { 0, 0 },
++	/* B50     */ { CLK_RTxC, 4590 },
++	/* B75     */ { CLK_RTxC, 3060 },
++	/* B110    */ { CLK_PCLK, 4576 },
++	/* B134    */ { CLK_PCLK, 3756 },
++	/* B150    */ { CLK_RTxC, 1530 },
++	/* B200    */ { CLK_PCLK, 2516 },
++	/* B300    */ { CLK_PCLK, 1678 },
++	/* B600    */ { CLK_PCLK, 838 },
++	/* B1200   */ { CLK_PCLK, 420 },
++	/* B1800   */ { CLK_PCLK, 280 },
++	/* B2400   */ { CLK_PCLK, 210 },
++	/* B4800   */ { CLK_RTxC, 48 },
++	/* B9600   */ { CLK_RTxC, 24 },
++	/* B19200  */ { CLK_RTxC, 12 },
++	/* B38400  */ { CLK_RTxC, 6 },   /* #15 spd_extra */
++	/* B57600  */ { CLK_RTxC, 4 },   /* #16 spd_hi */
++	/* B115200 */ { CLK_RTxC, 2 },   /* #17 spd_vhi */
++	/* B230400 */ { CLK_RTxC, 1 },   /* #18 spd_shi */
++	/* B460800 */ { 0, 0 }           /* #19 spd_warp: Impossible */
++};
++
++/* This is a special table for the TT channel B with 307.2 kHz at RTxC
++ * and 2.4576 MHz at TRxC
++ */
++static BAUD_ENTRY bdtab_TTChB[20] = {
++	/* B0      */ { 0, 0 },
++	/* B50     */ { CLK_RTxC, 384 },
++	/* B75     */ { CLK_RTxC, 256 },
++	/* B110    */ { CLK_PCLK, 4576 },
++	/* B134    */ { CLK_PCLK, 3756 },
++	/* B150    */ { CLK_RTxC, 128 },
++	/* B200    */ { CLK_RTxC, 96 },
++	/* B300    */ { CLK_RTxC, 64 },
++	/* B600    */ { CLK_RTxC, 32 },
++	/* B1200   */ { CLK_RTxC, 16 },
++	/* B1800   */ { CLK_PCLK, 280 },
++	/* B2400   */ { CLK_RTxC, 8 },
++	/* B4800   */ { CLK_RTxC, 4 },
++	/* B9600   */ { CLK_RTxC, 2 },
++	/* B19200  */ { CLK_RTxC, 1 },
++	/* B38400  */ { CLK_TRxC, 4 },
++	/* B57600  */ { CLK_TRxC, 2 }, /* 57600 is not possible, use 76800 instead */
++	/* B115200 */ { CLK_TRxC, 1 }, /* 115200 is not possible, use 153600 instead */
++	/* B230400 */ { 0, 0 },        /* #18 spd_shi: Impossible  */
++	/* B460800 */ { 0, 0 }         /* #19 spd_warp: Impossible */
++};
++
++
++/*----------------------------------------------------------------------------
++ * atari_scc_init() and support functions
++ *---------------------------------------------------------------------------*/
++
++static int scc_init_drivers(void)
++{
++	int error;
++
++	scc_driver = alloc_tty_driver(2);
++	if (!scc_driver)
++		return -ENOMEM;
++	scc_driver->owner = THIS_MODULE;
++	scc_driver->driver_name = "scc";
++	scc_driver->name = "ttyS";
++	scc_driver->major = TTY_MAJOR;
++	scc_driver->minor_start = SCC_MINOR_BASE;
++	scc_driver->type = TTY_DRIVER_TYPE_SERIAL;
++	scc_driver->subtype = SERIAL_TYPE_NORMAL;
++	scc_driver->init_termios = tty_std_termios;
++	scc_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
++	scc_driver->flags = TTY_DRIVER_REAL_RAW;
++
++	tty_set_operations(scc_driver, &scc_ops);
++
++	if ((error = tty_register_driver(scc_driver))) {
++		printk(KERN_ERR "scc: Couldn't register scc driver, error = %d\n",
++		       error);
++		put_tty_driver(scc_driver);
++		return 1;
++	}
++
++	return 0;
++}
++
++
++/* ports[] array is indexed by line no (i.e. [0] for ttyS0, [1] for ttyS1).
++ */
++
++static void scc_init_portstructs(void)
++{
++	struct scc_port *port;
++	int i;
++
++	for (i = 0; i < 2; i++) {
++		port = scc_ports + i;
++		port->gs.magic = SCC_MAGIC;
++		port->gs.close_delay = HZ/2;
++		port->gs.closing_wait = 30 * HZ;
++		port->gs.rd = &scc_real_driver;
++#ifdef NEW_WRITE_LOCKING
++		port->gs.port_write_sem = MUTEX;
++#endif
++		init_waitqueue_head(&port->gs.open_wait);
++		init_waitqueue_head(&port->gs.close_wait);
++	}
++}
++
++
++#ifdef CONFIG_TT_SCC
++static int atari_tt_scc_init(void)
++{
++	struct scc_port *port;
++
++	printk(KERN_INFO "SCC: Atari TT Serial Driver\n");
++	/* FIXME channel A may be switchable between modem and LAN port */
++	/* Init channel A */
++	if (atari_SCC_init_done)
++		printk(KERN_INFO "SCC: already initialized, expect trouble!\n");
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: init channel A\n");
++#endif
++	port = &scc_ports[0];
++	port->channel = CHANNEL_A;
++	port->ctrlp = (volatile unsigned char *)&scc.cha_a_ctrl;
++	port->datap = port->ctrlp + 1;
++	port->port_a = &scc_ports[0];
++	port->port_b = &scc_ports[1];
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: request channel A irqs, port = %p\n", port);
++#endif
++	request_irq(IRQ_SCCA_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-A TX", port);
++	request_irq(IRQ_SCCA_STAT, scc_stat_int, IRQ_TYPE_PRIO,
++		    "SCC-A status", port);
++	request_irq(IRQ_SCCA_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-A RX", port);
++	request_irq(IRQ_SCCA_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
++		    "SCC-A special cond", port);
++	{
++		SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: read SCC status\n");
++#endif
++		/* on the first access, read status register to reset internal pointers */
++		SCCread(STATUS_REG);
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: reset SCC\n");
++#endif
++		/* FIXME: master reset, once only */
++		SCCwrite(MASTER_INT_CTRL, MIC_HARD_RESET);
++		udelay(40);
++
++		/* disable interrupts for this channel */
++		SCCwrite(INT_AND_DMA_REG, 0);
++		/* Set the interrupt vector ; 0x60 for all Atari models */
++		SCCwrite(INT_VECTOR_REG, 0x60);
++		/* Interrupt parameters: vector includes status, status low */
++		SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT);
++		SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB);
++
++		/* disable interrupts for this channel */
++		SCCwrite(INT_AND_DMA_REG, 0);
++	}
++
++	if (!atari_SCC_init_done) {
++		/* Init channel B */
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: init channel B\n");
++#endif
++		port = &scc_ports[1];
++		port->channel = CHANNEL_B;
++		port->ctrlp = (volatile unsigned char *)&scc.cha_b_ctrl;
++		port->datap = port->ctrlp + 1;
++		port->port_a = &scc_ports[0];
++		port->port_b = &scc_ports[1];
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: request channel B irqs, port = %p\n", port);
++#endif
++		request_irq(IRQ_SCCB_TX, scc_tx_int, IRQ_TYPE_PRIO,
++			    "SCC-B TX", port);
++		request_irq(IRQ_SCCB_STAT, scc_stat_int, IRQ_TYPE_PRIO,
++			    "SCC-B status", port);
++		request_irq(IRQ_SCCB_RX, scc_rx_int, IRQ_TYPE_PRIO,
++			    "SCC-B RX", port);
++		request_irq(IRQ_SCCB_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
++			    "SCC-B special cond", port);
++		{
++			SCC_ACCESS_INIT(port);
++
++			/* disable interrupts for this channel */
++			SCCwrite(INT_AND_DMA_REG, 0);
++		}
++/* not implemented yet */
++#if 0
++		request_irq(IRQ_TT_MFP_RI, scc_ri_int, IRQ_TYPE_SLOW,
++			    "TT-MFP ring indicator (modem 2)", port);
++#endif
++
++	}
++
++	/* once only: initalize MFP timer C for RTxC */
++	tt_mfp.tim_ct_cd = (tt_mfp.tim_ct_cd & ~0x70) | 0x10;
++	tt_mfp.tim_dt_c = 1;
++	atari_turnoff_irq(IRQ_TT_MFP_TIMC);
++
++	/* set baud tables */
++	scc_baud_table[CHANNEL_A] = bdtab_norm;
++	scc_baud_table[CHANNEL_B] = bdtab_TTChB;
++
++	/* Initialise the tty driver structures and register */
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: scc_init_portstructs()\n");
++#endif
++	scc_init_portstructs();
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: scc_init_drivers()\n");
++#endif
++	scc_init_drivers();
++
++	return 0;
++}
++#endif
++
++
++#ifdef CONFIG_FALCON_SCC
++static int atari_falcon_scc_init(void)
++{
++	struct scc_port *port;
++
++	printk(KERN_INFO "SCC: Atari Falcon Serial Driver\n");
++	if (atari_SCC_init_done)
++		printk(KERN_INFO "SCC: already initialized, expect trouble!\n");
++
++	/* Init channel A */
++	port = &scc_ports[0];
++	port->channel = CHANNEL_A;
++	port->ctrlp = (volatile unsigned char *)&scc.cha_a_ctrl;
++	port->datap = port->ctrlp + 2;
++	port->port_a = &scc_ports[0];
++	port->port_b = &scc_ports[1];
++	request_irq(IRQ_SCCA_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-A TX", port);
++	request_irq(IRQ_SCCA_STAT, scc_stat_int, IRQ_TYPE_PRIO,
++		    "SCC-A status", port);
++	request_irq(IRQ_SCCA_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-A RX", port);
++	request_irq(IRQ_SCCA_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
++		    "SCC-A special cond", port);
++	{
++		SCC_ACCESS_INIT(port);
++
++		/* on the first access, read status register to reset internal pointers */
++		SCCread(STATUS_REG);
++
++		/* FIXME: master reset, once only */
++		SCCwrite(MASTER_INT_CTRL, MIC_HARD_RESET);
++		udelay(40);
++
++		/* disable interrupts for this channel */
++		SCCwrite(INT_AND_DMA_REG, 0);
++		/* Set the interrupt vector */
++		SCCwrite(INT_VECTOR_REG, 0x60);
++		/* Interrupt parameters: vector includes status, status low */
++		SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT);
++		SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB);
++	}
++
++	/* conditionalize if port in use by console ?? */
++	/* Init channel B */
++	port = &scc_ports[1];
++	port->channel = CHANNEL_B;
++	port->ctrlp = (volatile unsigned char *)&scc.cha_b_ctrl;
++	port->datap = port->ctrlp + 2;
++	port->port_a = &scc_ports[0];
++	port->port_b = &scc_ports[1];
++	request_irq(IRQ_SCCB_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-B TX", port);
++	request_irq(IRQ_SCCB_STAT, scc_stat_int, IRQ_TYPE_PRIO,
++		    "SCC-B status", port);
++	request_irq(IRQ_SCCB_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-B RX", port);
++	request_irq(IRQ_SCCB_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
++		    "SCC-B special cond", port);
++
++	{
++		SCC_ACCESS_INIT(port);	/* Either channel will do */
++
++		/* disable interrupts for this channel */
++		SCCwrite(INT_AND_DMA_REG, 0);
++	}
++
++	/* set baud tables */
++	scc_baud_table[CHANNEL_A] = bdtab_norm;
++	scc_baud_table[CHANNEL_B] = bdtab_norm;
++
++	/* Initialise the tty driver structures and register */
++	scc_init_portstructs();
++	scc_init_drivers();
++
++	return 0;
++}
++#endif
++
++
++#ifdef CONFIG_ST_SCC
++static int atari_st_scc_init(void)
++{
++	struct scc_port *port;
++
++	int escc = ATARIHW_PRESENT(ST_ESCC);
++
++	printk(KERN_INFO "SCC: Atari MegaST/E Serial Driver\n");
++	/* FIXME: ports reversed logic */
++	/* Init channel A */
++	port = &scc_ports[1];
++	port->channel = CHANNEL_A;
++	port->ctrlp = (volatile unsigned char *)(escc ? &st_escc.cha_a_ctrl : &scc.cha_a_ctrl);
++	port->datap = port->ctrlp + 4;
++	port->port_a = &scc_ports[1];
++	port->port_b = &scc_ports[0];
++	request_irq(IRQ_SCCA_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-A TX", port);
++	request_irq(IRQ_SCCA_STAT, scc_stat_int, IRQ_TYPE_PRIO,
++		    "SCC-A status", port);
++	request_irq(IRQ_SCCA_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-A RX", port);
++	request_irq(SCCA_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
++		    "SCC-A special cond", port);
++	{
++		SCC_ACCESS_INIT(port);
++
++		/* on the first access, read status register to reset internal pointers */
++		SCCread(STATUS_REG);
++
++		/* FIXME: master reset, once only */
++		SCCwrite(MASTER_INT_CTRL, MIC_HARD_RESET);
++		udelay(40);
++
++		/* disable interrupts for this channel */
++		SCCwrite(INT_AND_DMA_REG, 0);
++		/* Set the interrupt vector */
++		SCCwrite(INT_VECTOR_REG, BVME_IRQ_SCC_BASE);
++		/* Interrupt parameters: vector includes status, status low */
++		SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT);
++		SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB);
++	}
++
++	/* Init channel B */
++	port = &scc_ports[0];
++	port->channel = CHANNEL_B;
++	port->ctrlp = (volatile unsigned char *)(escc ? &st_escc.cha_b_ctrl : &scc.cha_b_ctrl);
++	port->datap = port->ctrlp + 4;
++	port->port_a = &scc_ports[0];
++	port->port_b = &scc_ports[1];
++	request_irq(IRQ_SCCB_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-B TX", port);
++	request_irq(IRQ_SCCB_STAT, scc_stat_int, IRQ_TYPE_PRIO,
++		    "SCC-B status", port);
++	request_irq(IRQ_SCCB_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-B RX", port);
++	request_irq(IRQ_SCCB_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
++		    "SCC-B special cond", port);
++
++	{
++		SCC_ACCESS_INIT(port);	/* Either channel will do */
++
++		/* disable interrupts for this channel */
++		SCCwrite(INT_AND_DMA_REG, 0);
++	}
++
++	/* set baud tables */
++	scc_baud_table[CHANNEL_A] = bdtab_norm;
++	scc_baud_table[CHANNEL_B] = bdtab_norm;
++
++	/* Initialise the tty driver structures and register */
++	scc_init_portstructs();
++	scc_init_drivers();
++
++	return 0;
++}
++#endif
++
++
++int atari_scc_init(void)
++{
++	int res = -ENODEV;
++	static int called = 0;
++
++	if (called)
++		return res;
++	called = 1;
++
++	if (!(ATARIHW_PRESENT(SCC) || ATARIHW_PRESENT(ST_ESCC)))
++		return -ENODEV;
++
++	scc_del = &mfp.par_dt_reg;
++
++#ifdef CONFIG_TT_SCC
++	if (MACH_IS_TT)
++		res = atari_tt_scc_init();
++#endif
++#ifdef CONFIG_FALCON_SCC
++	if (MACH_IS_FALCON)
++		res = atari_falcon_scc_init();
++#endif
++#ifdef CONFIG_ST_SCC
++	if (MACH_IS_ST)
++		res = atari_st_scc_init();
++#endif
++	return res;
++}
++
++void atari_scc_cleanup(void)
++{
++	struct scc_port *port;
++
++	tty_unregister_driver(scc_driver);
++	port = &scc_ports[0];
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: free channel A irqs, port = %p\n", port);
++#endif
++	free_irq(IRQ_SCCA_TX, port);
++	free_irq(IRQ_SCCA_STAT, port);
++	free_irq(IRQ_SCCA_RX, port);
++	free_irq(IRQ_SCCA_SPCOND, port);
++
++	port = &scc_ports[1];
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: free channel A irqs, port = %p\n", port);
++#endif
++	free_irq(IRQ_SCCB_TX, port);
++	free_irq(IRQ_SCCB_STAT, port);
++	free_irq(IRQ_SCCB_RX, port);
++	free_irq(IRQ_SCCB_SPCOND, port);
++
++}
++
++module_init(atari_scc_init);
++module_exit(atari_scc_cleanup);
++
++/*---------------------------------------------------------------------------
++ * Interrupt handlers
++ *--------------------------------------------------------------------------*/
++
++static irqreturn_t scc_rx_int(int irq, void *data)
++{
++	unsigned char ch;
++	struct scc_port *port = data;
++	struct tty_struct *tty = port->gs.tty;
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: rx_int ...\n");
++#endif
++	ch = SCCread_NB(RX_DATA_REG);
++	if (!tty) {
++		printk(KERN_WARNING "scc_rx_int with NULL tty!\n");
++		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
++		return IRQ_HANDLED;
++	}
++	tty_insert_flip_char(tty, ch, 0);
++#if 0
++	if (tty->flip.count < TTY_FLIPBUF_SIZE) {
++		*tty->flip.char_buf_ptr = ch;
++		*tty->flip.flag_buf_ptr = 0;
++		tty->flip.flag_buf_ptr++;
++		tty->flip.char_buf_ptr++;
++		tty->flip.count++;
++	}
++#endif
++	/* Check if another character is already ready; in that case, the
++	 * spcond_int() function must be used, because this character may have an
++	 * error condition that isn't signalled by the interrupt vector used!
++	 */
++	if (SCCread(INT_PENDING_REG) &
++	    (port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) {
++		scc_spcond_int(irq, data);
++		return IRQ_HANDLED;
++	}
++
++	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
++
++	tty_flip_buffer_push(tty);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: rx_int done\n");
++#endif
++	return IRQ_HANDLED;
++}
++
++
++static irqreturn_t scc_spcond_int(int irq, void *data)
++{
++	struct scc_port *port = data;
++	struct tty_struct *tty = port->gs.tty;
++	unsigned char stat, ch, err;
++	int int_pending_mask = port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX;
++
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: spcond_int ...\n");
++#endif
++	if (!tty) {
++		printk(KERN_WARNING "scc_spcond_int with NULL tty!\n");
++		SCCwrite(COMMAND_REG, CR_ERROR_RESET);
++		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
++		return IRQ_HANDLED;
++	}
++	do {
++		stat = SCCread(SPCOND_STATUS_REG);
++		ch = SCCread_NB(RX_DATA_REG);
++
++		if (stat & SCSR_RX_OVERRUN)
++			err = TTY_OVERRUN;
++		else if (stat & SCSR_PARITY_ERR)
++			err = TTY_PARITY;
++		else if (stat & SCSR_CRC_FRAME_ERR)
++			err = TTY_FRAME;
++		else
++			err = 0;
++
++		tty_insert_flip_char(tty, ch, err);
++#if 0
++		if (tty->flip.count < TTY_FLIPBUF_SIZE) {
++			*tty->flip.char_buf_ptr = ch;
++			*tty->flip.flag_buf_ptr = err;
++			tty->flip.flag_buf_ptr++;
++			tty->flip.char_buf_ptr++;
++			tty->flip.count++;
++		}
++#endif
++		/* ++TeSche: *All* errors have to be cleared manually,
++		 * else the condition persists for the next chars
++		 */
++		if (err)
++			SCCwrite(COMMAND_REG, CR_ERROR_RESET);
++
++	} while (SCCread(INT_PENDING_REG) & int_pending_mask);
++
++	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
++
++	tty_flip_buffer_push(tty);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: spcond_int done\n");
++#endif
++	return IRQ_HANDLED;
++}
++
++/* not implemented yet */
++#if 0
++static void scc_ri_int(int irq, void *data)
++{
++	struct scc_port *port = data;
++	/* update input line counter */
++	port->icount.rng++;
++	wake_up_interruptible(&port->delta_msr_wait);
++}
++#endif
++
++static irqreturn_t scc_tx_int(int irq, void *data)
++{
++	struct scc_port *port = data;
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: tx_int irq %d port %p ...\n", irq, data);
++#endif
++	if (!port->gs.tty) {
++		printk(KERN_WARNING "scc_tx_int with NULL tty!\n");
++		SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
++		SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);
++		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
++		return IRQ_HANDLED;
++	}
++	while ((SCCread_NB(STATUS_REG) & SR_TX_BUF_EMPTY)) {
++		if (port->x_char) {
++#ifdef DEBUG
++			printk(KERN_INFO "SCC: tx_int writing char %c\n",
++			       port->x_char);
++#endif
++			SCCwrite(TX_DATA_REG, port->x_char);
++			port->x_char = 0;
++		} else if ((port->gs.xmit_cnt <= 0) || port->gs.tty->stopped ||
++			   port->gs.tty->hw_stopped) {
++#ifdef DEBUG
++			printk(KERN_INFO "SCC: nothing to do!\n");
++#endif
++			break;
++		} else {
++#ifdef DEBUG
++			printk(KERN_INFO "SCC: tx_int writing buf %c\n",
++			       port->gs.xmit_buf[port->gs.xmit_tail]);
++#endif
++			SCCwrite(TX_DATA_REG, port->gs.xmit_buf[port->gs.xmit_tail++]);
++			port->gs.xmit_tail = port->gs.xmit_tail & (SERIAL_XMIT_SIZE-1);
++			if (--port->gs.xmit_cnt <= 0)
++				break;
++		}
++	}
++	if ((port->gs.xmit_cnt <= 0) || port->gs.tty->stopped ||
++	    port->gs.tty->hw_stopped) {
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: nothing to do, disabling int\n");
++#endif
++		/* disable tx interrupts */
++		SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
++		SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);	/* disable tx_int on next tx underrun? */
++		port->gs.flags &= ~GS_TX_INTEN;
++	}
++	if (port->gs.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) {
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: waking up tty!\n");
++#endif
++		tty_wakeup(port->gs.tty);
++	}
++
++	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: tx_int done\n");
++#endif
++	return IRQ_HANDLED;
++}
++
++
++static irqreturn_t scc_stat_int(int irq, void *data)
++{
++	struct scc_port *port = data;
++	unsigned channel = port->channel;
++	unsigned char last_sr, sr, changed;
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: stat_int ...\n");
++#endif
++	last_sr = scc_last_status_reg[channel];
++	sr = scc_last_status_reg[channel] = SCCread_NB(STATUS_REG);
++	changed = last_sr ^ sr;
++
++	if (changed & SR_DCD) {
++		port->c_dcd = !!(sr & SR_DCD);
++		if (!(port->gs.flags & ASYNC_CHECK_CD))
++			;	/* Don't report DCD changes */
++		else if (port->c_dcd) {
++			/* Are we blocking in open? */
++			wake_up_interruptible(&port->gs.open_wait);
++		} else {
++			if (port->gs.tty)
++				tty_hangup(port->gs.tty);
++		}
++	}
++
++	// FIXME: CTS and DSR status changes?
++
++	SCCwrite(COMMAND_REG, CR_EXTSTAT_RESET);
++	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: stat_int done\n");
++#endif
++	return IRQ_HANDLED;
++}
++
++
++/*---------------------------------------------------------------------------
++ * generic_serial.c callback funtions
++ *--------------------------------------------------------------------------*/
++
++static void scc_disable_tx_interrupts(void *ptr)
++{
++	struct scc_port *port = ptr;
++	unsigned long flags;
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: disable_tx_int ...\n");
++#endif
++	local_irq_save(flags);
++	SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
++	port->gs.flags &= ~GS_TX_INTEN;
++	local_irq_restore(flags);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: disable_tx_int done!\n");
++#endif
++}
++
++
++static void scc_enable_tx_interrupts(void *ptr)
++{
++	struct scc_port *port = ptr;
++	unsigned long flags;
++
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: enable_tx_int ...\n");
++#endif
++	local_irq_save(flags);
++	SCCmod(INT_AND_DMA_REG, 0xff, IDR_TX_INT_ENAB);
++	/* restart the transmitter */
++	scc_tx_int(0, port);
++	local_irq_restore(flags);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: enable_tx_int done!\n");
++#endif
++}
++
++
++static void scc_disable_rx_interrupts(void *ptr)
++{
++	struct scc_port *port = ptr;
++	unsigned long flags;
++
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: disable_rx_int ...\n");
++#endif
++	local_irq_save(flags);
++	SCCmod(INT_AND_DMA_REG,
++	       ~(IDR_RX_INT_MASK|IDR_PARERR_AS_SPCOND|IDR_EXTSTAT_INT_ENAB), 0);
++	local_irq_restore(flags);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: disable_rx_int done!\n");
++#endif
++}
++
++
++static void scc_enable_rx_interrupts(void *ptr)
++{
++	struct scc_port *port = ptr;
++	unsigned long flags;
++
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: enable_rx_int ...\n");
++#endif
++	local_irq_save(flags);
++	SCCmod(INT_AND_DMA_REG, 0xff,
++	       IDR_EXTSTAT_INT_ENAB|IDR_PARERR_AS_SPCOND|IDR_RX_INT_ALL);
++	local_irq_restore(flags);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: enable_rx_int done!\n");
++#endif
++}
++
++
++static int scc_get_CD(void *ptr)
++{
++	struct scc_port *port = ptr;
++	unsigned channel = port->channel;
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: get_CD!\n");
++#endif
++	return !!(scc_last_status_reg[channel] & SR_DCD);
++}
++
++
++static void scc_shutdown_port(void *ptr)
++{
++	struct scc_port *port = ptr;
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: shutdown_port ...\n");
++#endif
++	port->gs.flags &= ~GS_ACTIVE;
++	if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL)
++		scc_setsignals(port, 0, 0);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: shutdown_port done!\n");
++#endif
++}
++
++
++static int scc_set_real_termios(void *ptr)
++{
++	/* the SCC has char sizes 5,7,6,8 in that order! */
++	static int chsize_map[4] = { 0, 2, 1, 3 };
++	unsigned int cflag, baud, baudbits, baudidx, brgmode;
++	unsigned int clkmode, clksrc, div, chsize, channel, brgval = 0;
++	unsigned long flags;
++	struct scc_port *port = ptr;
++	SCC_ACCESS_INIT(port);
++
++	if (!port->gs.tty || !port->gs.tty->termios)
++		return 0;
++
++	channel = port->channel;
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: termios for channel %p\n", channel);
++#endif
++	cflag = port->gs.tty->termios->c_cflag;
++	baud = port->gs.baud;
++	baudbits = cflag & CBAUD;
++	chsize = (cflag & CSIZE) >> 4;
++
++	if (baud == 0) {
++		/* speed == 0 -> drop DTR */
++		local_irq_save(flags);
++		SCCmod(TX_CTRL_REG, ~TCR_DTR, 0);
++		local_irq_restore(flags);
++		return 0;
++	} else if ((MACH_IS_TT && (baud < 50 || baud > 115200)) ||
++		   (MACH_IS_FALCON && (baud < 50 || baud > 230400))) {
++		printk(KERN_NOTICE "SCC: Bad speed requested, %d\n", baud);
++		return 0;
++	}
++
++	if (cflag & CLOCAL)
++		port->gs.flags &= ~ASYNC_CHECK_CD;
++	else
++		port->gs.flags |= ASYNC_CHECK_CD;
++
++	// calculate brgval for Atari; enable direct modes!
++
++	/* convert baud rate from gs.baud to table index, set custom divisor eventually */
++
++	div     = 0;
++	clksrc  = 0;
++	baudidx = 0;
++
++	switch (baud) {
++	case 50:
++		baudidx = 1;
++		break;
++	case 75:
++		baudidx = 2;
++		break;
++	case 110:
++		baudidx = 3;
++		break;
++	case 134:
++		baudidx = 4;
++		break;
++	case 150:
++		baudidx = 5;
++		break;
++	case 200:
++		baudidx = 6;
++		break;
++	case 300:
++		baudidx = 7;
++		break;
++	case 600:
++		baudidx = 8;
++		break;
++	case 1200:
++		baudidx = 9;
++		break;
++	case 1800:
++		baudidx = 10;
++		break;
++	case 2400:
++		baudidx = 11;
++		break;
++	case 4800:
++		baudidx = 12;
++		break;
++	case 9600:
++		baudidx = 13;
++		break;
++	case 19200:
++		baudidx = 14;
++		break;
++	case 38400:
++		baudidx = 15;
++		break;
++	case 57600:
++		baudidx = 16;
++		break;
++	case 115200:
++		baudidx = 17;
++		break;
++	case 230400:
++		baudidx = 18;
++		break;
++	default:
++		baudidx = 15;
++		break;
++	}
++
++	/* do we have a custom divisor ?? */
++	if (!div) {
++		if (baudidx > 19)
++			baudidx = 19;
++		clksrc = scc_baud_table[channel][baudidx].clksrc;
++		div = scc_baud_table[channel][baudidx].div;
++		if (!div) {
++			printk(" SCC_change_speed: divisor = 0 !!!");
++			return 0;
++		}
++	}
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: termios baud %d baudbits %d baudidx %d \n clksrc %d div %d\n",
++		baud, baudbits, baudidx, clksrc, div);
++#endif
++	/* compute the SCC's clock source, clock mode, BRG mode and BRG
++	 * value from clksrc and div
++	 */
++	if (div <= 4) {
++		clkmode = (div == 1 ? A1CR_CLKMODE_x16 :
++			   div == 2 ? A1CR_CLKMODE_x32 :
++				      A1CR_CLKMODE_x64);
++		clksrc  = (clksrc == CLK_RTxC
++			   ? CCR_TXCLK_RTxC | CCR_RXCLK_RTxC
++			   : CCR_TXCLK_TRxC | CCR_RXCLK_TRxC);
++		brgmode = 0; /* off */
++		brgval  = 0;
++	} else {
++		brgval  = div/2 - 2;
++		brgmode = (DCR_BRG_ENAB |
++			   (clksrc == CLK_PCLK ? DCR_BRG_USE_PCLK : 0));
++		clkmode = A1CR_CLKMODE_x16;
++		clksrc  = CCR_TXCLK_BRG | CCR_RXCLK_BRG;
++	}
++
++	//printk(KERN_INFO "SCC: termios baud %d baudbits %d baudidx %d \n clksrc %d clkmode %d div %d brgval %d brgmode %d\n",
++	//	baud, baudbits, baudidx, clksrc, clkmode, div, brgval, brgmode);
++
++	/* Now we have all parameters and can go to set them: */
++	local_irq_save(flags);
++
++#ifdef DEBUG
++	printk("  brgval=%d brgmode=%02x clkmode=%02x clksrc=%02x\n",
++		brgval, brgmode, clkmode, clksrc);
++#endif
++	/* receiver's character size and auto-enables */
++#if 0	// auto-enable considered harmful ...
++	SCCmod(RX_CTRL_REG, ~(RCR_CHSIZE_MASK|RCR_AUTO_ENAB_MODE),
++	       (chsize_map[chsize] << 6) |
++	       ((cflag & CRTSCTS) ? RCR_AUTO_ENAB_MODE : 0));
++#else
++	/* receiver's character size */
++	SCCmod(RX_CTRL_REG, ~RCR_CHSIZE_MASK, chsize_map[chsize] << 6);
++#endif
++#ifdef DEBUG
++	printk("  RX_CTRL_REG <- %02x\n", SCCread( RX_CTRL_REG ));
++#endif
++
++	// clock mode changes depending on baud rate
++	/* parity and stop bits (both, Tx and Rx) and clock mode */
++	SCCmod(AUX1_CTRL_REG,
++		~(A1CR_PARITY_MASK | A1CR_MODE_MASK | A1CR_CLKMODE_MASK),
++		((cflag & PARENB
++		  ? (cflag & PARODD ? A1CR_PARITY_ODD : A1CR_PARITY_EVEN)
++		  : A1CR_PARITY_NONE)
++		 | (cflag & CSTOPB ? A1CR_MODE_ASYNC_2 : A1CR_MODE_ASYNC_1)
++		 | clkmode));
++
++#ifdef DEBUG
++	printk("  AUX1_CTRL_REG <- %02x\n", SCCread(AUX1_CTRL_REG));
++#endif
++	/* sender's character size, set DTR for valid baud rate */
++	SCCmod(TX_CTRL_REG, ~TCR_CHSIZE_MASK, chsize_map[chsize] << 5 | TCR_DTR);
++#ifdef DEBUG
++	printk("  TX_CTRL_REG <- %02x\n", SCCread(TX_CTRL_REG));
++#endif
++
++	// clock sources change for TT !!
++	/* clock sources never change */
++	/* clock sources */
++	SCCmod(CLK_CTRL_REG, ~(CCR_TXCLK_MASK | CCR_RXCLK_MASK), clksrc);
++#ifdef DEBUG
++	printk("  CLK_CTRL_REG <- %02x\n", SCCread(CLK_CTRL_REG));
++#endif
++
++	/* disable BRG before changing the value */
++	SCCmod(DPLL_CTRL_REG, ~DCR_BRG_ENAB, 0);
++	/* BRG value */
++	SCCwrite(TIMER_LOW_REG, brgval & 0xff);
++	SCCwrite(TIMER_HIGH_REG, (brgval >> 8) & 0xff);
++	/* BRG enable, and clock source never changes */
++	//SCCmod(DPLL_CTRL_REG, 0xff, DCR_BRG_ENAB);
++	SCCmod(DPLL_CTRL_REG, ~(DCR_BRG_ENAB | DCR_BRG_USE_PCLK), brgmode);
++#ifdef DEBUG
++	printk("  TIMER_LOW_REG <- %02x\n", SCCread(TIMER_LOW_REG));
++	printk("  TIMER_HIGH_REG <- %02x\n", SCCread(TIMER_HIGH_REG));
++#endif
++#ifdef DEBUG
++	printk("  DPLL_CTRL_REG <- %02x\n", SCCread(DPLL_CTRL_REG));
++#endif
++
++	local_irq_restore(flags);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: done termios for channel %d\n", channel);
++#endif
++	return 0;
++}
++
++
++static int scc_chars_in_buffer(void *ptr)
++{
++	struct scc_port *port = ptr;
++#ifdef DEBUG
++	int rv;
++#endif
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	rv = (SCCread(SPCOND_STATUS_REG) & SCSR_ALL_SENT) ? 0  : 1;
++	printk(KERN_INFO "SCC: chars_in_buffer: %d\n", rv);
++	return rv;
++#else
++	return (SCCread(SPCOND_STATUS_REG) & SCSR_ALL_SENT) ? 0  : 1;
++#endif
++}
++
++
++/* Comment taken from sx.c (2.4.0):
++   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 scc_hungup(void *ptr)
++{
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: hungup ...\n");
++#endif
++	scc_disable_tx_interrupts(ptr);
++	scc_disable_rx_interrupts(ptr);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: hungup done\n");
++#endif
++}
++
++
++static void scc_close(void *ptr)
++{
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: close ...\n");
++#endif
++	scc_disable_tx_interrupts(ptr);
++	scc_disable_rx_interrupts(ptr);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: close done\n");
++#endif
++}
++
++
++/*---------------------------------------------------------------------------
++ * Internal support functions
++ *--------------------------------------------------------------------------*/
++
++static void scc_setsignals(struct scc_port *port, int dtr, int rts)
++{
++	unsigned long flags;
++	unsigned char t;
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: setsignals dtr %d rts %d...\n", dtr, rts);
++#endif
++	local_irq_save(flags);
++	t = SCCread(TX_CTRL_REG);
++	if (dtr >= 0)
++		t = dtr? (t | TCR_DTR): (t & ~TCR_DTR);
++	if (rts >= 0)
++		t = rts? (t | TCR_RTS): (t & ~TCR_RTS);
++	SCCwrite(TX_CTRL_REG, t);
++	local_irq_restore(flags);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: setsignals done\n");
++#endif
++}
++
++
++static void scc_send_xchar(struct tty_struct *tty, char ch)
++{
++	struct scc_port *port = (struct scc_port *)tty->driver_data;
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: send_xchar ...\n");
++#endif
++	port->x_char = ch;
++	if (ch)
++		scc_enable_tx_interrupts(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: send_xchar done\n");
++#endif
++}
++
++
++/*---------------------------------------------------------------------------
++ * Driver entrypoints referenced from above
++ *--------------------------------------------------------------------------*/
++
++static int scc_open(struct tty_struct *tty, struct file *filp)
++{
++	int line = tty->index;
++	int retval;
++	struct scc_port *port = &scc_ports[line];
++	int i, channel = port->channel;
++	unsigned long flags;
++	SCC_ACCESS_INIT(port);
++
++	static const struct {
++		unsigned reg, val;
++	} scc_init_tab[] = {
++		/* no parity, 1 stop bit, async, 1:16 */
++		{ AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x64 },
++		/* parity error is special cond, ints disabled, no DMA */
++		{ INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB },
++		/* Rx 8 bits/char, no auto enable, Rx off */
++		{ RX_CTRL_REG, RCR_CHSIZE_8 },
++		/* DTR off, Tx 8 bits/char, RTS off, Tx off */
++		{ TX_CTRL_REG, TCR_CHSIZE_8 },
++		/* special features off */
++		{ AUX2_CTRL_REG, 0 },
++		/* RTxC is XTAL, TRxC is input, both clocks = RTxC */
++		{ CLK_CTRL_REG, CCR_TRxCOUT_XTAL | CCR_TXCLK_RTxC | CCR_RXCLK_RTxC },
++		{ DPLL_CTRL_REG, 0 },
++		/* Start Rx */
++		{ RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 },
++		/* Start Tx */
++		{ TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 },
++		/* Ext/Stat ints: CTS, DCD, SYNC (DSR) */
++		{ INT_CTRL_REG, ICR_ENAB_DCD_INT | ICR_ENAB_CTS_INT | ICR_ENAB_SYNC_INT },
++		/* Reset Ext/Stat ints */
++		{ COMMAND_REG, CR_EXTSTAT_RESET },
++		/* ...again */
++		{ COMMAND_REG, CR_EXTSTAT_RESET },
++		/* Rx int always, TX int off, Ext/Stat int on */
++		{ INT_AND_DMA_REG, IDR_EXTSTAT_INT_ENAB |
++		  IDR_PARERR_AS_SPCOND | IDR_RX_INT_ALL }
++	};
++
++	if (atari_SCC_init_done && line == 1)
++		return -ENODEV;
++
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: open port ...\n");
++#endif
++	if (!(port->gs.flags & ASYNC_INITIALIZED)) {
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: init port ...\n");
++#endif
++		local_irq_save(flags);
++
++		SCCmod(MASTER_INT_CTRL, 0x3f,
++		       channel == 0 ? MIC_CH_A_RESET : MIC_CH_B_RESET);
++		udelay(40);		/* extra delay after a reset */
++
++		for (i = 0; i < sizeof(scc_init_tab)/sizeof(*scc_init_tab); ++i)
++			SCCwrite(scc_init_tab[i].reg, scc_init_tab[i].val);
++
++
++		/* remember status register for detection of DCD and CTS changes */
++		scc_last_status_reg[channel] = SCCread(STATUS_REG);
++
++		port->c_dcd = 0;	/* Prevent initial 1->0 interrupt */
++		scc_setsignals(port, 1, 1);
++		local_irq_restore(flags);
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: init port done!\n");
++#endif
++	}
++
++	tty->driver_data = port;
++	port->gs.tty = tty;
++	port->gs.count++;
++#ifdef DEBUG
++	printk(KERN_WARNING "SCC: gs init port ...\n");
++#endif
++	retval = gs_init_port(&port->gs);
++	if (retval) {
++		port->gs.count--;
++		return retval;
++	}
++#ifdef DEBUG
++	printk(KERN_WARNING "SCC: gs init port done!\n");
++#endif
++	port->gs.flags |= GS_ACTIVE;
++
++#ifdef DEBUG
++	printk(KERN_WARNING "SCC: gs wait ready ...\n");
++#endif
++	retval = gs_block_til_ready(port, filp);
++#ifdef DEBUG
++	printk(KERN_WARNING "SCC: gs wait ready done!\n");
++#endif
++	if (retval) {
++		port->gs.count--;
++		return retval;
++	}
++
++	port->c_dcd = scc_get_CD(port);
++
++#ifdef DEBUG
++	printk(KERN_WARNING "SCC: enable rx ints ...\n");
++#endif
++	scc_enable_rx_interrupts(port);
++#ifdef DEBUG
++	printk(KERN_WARNING "SCC: enable rx ints done!\n");
++
++	printk(KERN_INFO "SCC: open port done!\n");
++#endif
++	return 0;
++}
++
++
++static void scc_throttle(struct tty_struct *tty)
++{
++	struct scc_port *port = (struct scc_port *)tty->driver_data;
++	unsigned long flags;
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: throttle ...\n");
++#endif
++	if (tty->termios->c_cflag & CRTSCTS) {
++		local_irq_save(flags);
++		SCCmod(TX_CTRL_REG, ~TCR_RTS, 0);
++		local_irq_restore(flags);
++	}
++	if (I_IXOFF(tty))
++		scc_send_xchar(tty, STOP_CHAR(tty));
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: throttle done!\n");
++#endif
++}
++
++
++static void scc_unthrottle(struct tty_struct *tty)
++{
++	struct scc_port *port = (struct scc_port *)tty->driver_data;
++	unsigned long flags;
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: unthrottle ...\n");
++#endif
++	if (tty->termios->c_cflag & CRTSCTS) {
++		local_irq_save(flags);
++		SCCmod(TX_CTRL_REG, 0xff, TCR_RTS);
++		local_irq_restore(flags);
++	}
++	if (I_IXOFF(tty))
++		scc_send_xchar(tty, START_CHAR(tty));
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: unthrottle done!\n");
++#endif
++}
++
++
++static int scc_ioctl(struct tty_struct *tty, struct file *file,
++		     unsigned int cmd, unsigned long arg)
++{
++	struct scc_port *port = (struct scc_port *)tty->driver_data;
++	int retval;
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: ioctl! cmd %d, arg %p \n", cmd, arg);
++#endif
++	//if (serial_paranoia_check(info, tty->device, "zs_ioctl"))
++	//	return -ENODEV;
++
++	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
++	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
++	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
++		if (tty->flags & (1 << TTY_IO_ERROR))
++			return -EIO;
++	}
++
++	switch (cmd) {
++	case TCSBRK:	/* SVID version: non-zero arg --> no break */
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: ioctl TCSBRK\n");
++#endif
++		retval = tty_check_change(tty);
++		if (retval)
++			return retval;
++		tty_wait_until_sent(tty, 0);
++		//if (!arg)
++		//	send_break(info, HZ/4);	/* 1/4 second */
++		return 0;
++	case TCSBRKP:	/* support for POSIX tcsendbreak() */
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: ioctl TCSBRKP\n");
++#endif
++		retval = tty_check_change(tty);
++		if (retval)
++			return retval;
++		tty_wait_until_sent(tty, 0);
++		//send_break(info, arg ? arg*(HZ/10) : HZ/4);
++		return 0;
++	case TIOCGSOFTCAR:
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: ioctl TIOCGSOFTCAR\n");
++#endif
++		if (put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg))
++			return -EFAULT;
++		return 0;
++	case TIOCSSOFTCAR:
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: ioctl TIOCSSOFTCAR\n");
++#endif
++		if (get_user(arg, (unsigned long *)arg))
++			return -EFAULT;
++		tty->termios->c_cflag =
++			((tty->termios->c_cflag & ~CLOCAL) |
++			 (arg ? CLOCAL : 0));
++		return 0;
++	case TIOCMGET:
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: ioctl TIOCMGET\n");
++#endif
++		//return get_modem_info(info, (unsigned int *)arg);
++		return 0;
++	case TIOCMBIS:
++	case TIOCMBIC:
++	case TIOCMSET:
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: ioctl TIOCMSET\n");
++#endif
++		//return set_modem_info(info, cmd, (unsigned int *)arg);
++		return 0;
++	case TIOCGSERIAL:
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: ioctl TIOCGSERIAL\n");
++#endif
++		return 0;
++		//return get_serial_info(info,
++		//		       (struct serial_struct *)arg);
++	case TIOCSSERIAL:
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: ioctl TIOCSSERIAL\n");
++#endif
++		return 0;
++		//return set_serial_info(info,
++		//		       (struct serial_struct *)arg);
++	case TIOCSERGETLSR: /* Get line status register */
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: ioctl TIOCSERGETLSR\n");
++#endif
++		return 0;
++		//return get_lsr_info(info, (unsigned int *)arg);
++
++	case TIOCSERGSTRUCT:
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: ioctl TIOCSERGSTRUCT\n");
++#endif
++		return 0;
++		if (copy_to_user((struct scc_port *)arg,
++				 port, sizeof(struct scc_port)))
++			return -EFAULT;
++		return 0;
++
++	default:
++#ifdef DEBUG
++		printk(KERN_INFO "SCC: ioctl default\n");
++#endif
++		return -ENOIOCTLCMD;
++	}
++	return 0;
++}
++
++
++static void scc_break_ctl(struct tty_struct *tty, int break_state)
++{
++	struct scc_port *port = (struct scc_port *)tty->driver_data;
++	unsigned long flags;
++	SCC_ACCESS_INIT(port);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: break ctl ...\n");
++#endif
++	local_irq_save(flags);
++	SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK, break_state ? TCR_SEND_BREAK : 0);
++	local_irq_restore(flags);
++#ifdef DEBUG
++	printk(KERN_INFO "SCC: break ctl done!\n");
++#endif
++}
++
++
++/*---------------------------------------------------------------------------
++ * Serial console stuff...
++ *--------------------------------------------------------------------------*/
++#if 1
++#define scc_delay() \
++	asm volatile ("tstb %0" : : "m" (*scc_del) : "cc")
++
++#define SCC_WRITE(reg,val)				\
++	do {						\
++		scc.cha_b_ctrl = (reg);			\
++		scc_delay();				\
++		scc.cha_b_ctrl = (val);			\
++		scc_delay();				\
++	} while (0)
++
++/* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a
++ * delay of ~ 60us. */
++#define LONG_DELAY()					\
++	do {						\
++		int i;					\
++		for (i = 100; i > 0; --i)		\
++			scc_delay();			\
++	} while (0)
++
++static void atari_init_scc_port(int cflag)
++{
++	extern int atari_SCC_reset_done;
++	static int clksrc_table[9] =
++		/* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */
++		{ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 };
++	static int brgsrc_table[9] =
++		/* reg 14: 0 = RTxC, 2 = PCLK */
++		{ 2, 2, 2, 2, 2, 2, 0, 2, 2 };
++	static int clkmode_table[9] =
++		/* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */
++		{ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 };
++	static int div_table[9] =
++		/* reg12 (BRG low) */
++		{ 208, 138, 103, 50, 24, 11, 1, 0, 0 };
++
++	int baud = cflag & CBAUD;
++	int clksrc, clkmode, div, reg3, reg5;
++
++	scc_del = &mfp.par_dt_reg;
++
++	if (cflag & CBAUDEX)
++		baud += B38400;
++	if (baud < B1200 || baud > B38400+2)
++		baud = B9600;		/* use default 9600bps for non-implemented rates */
++	baud -= B1200;			/* tables starts at 1200bps */
++
++	clksrc  = clksrc_table[baud];
++	clkmode = clkmode_table[baud];
++	div     = div_table[baud];
++	if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) {
++		/* special treatment for TT, where rates >= 38400 are done via TRxC */
++		clksrc = 0x28; /* TRxC */
++		clkmode = baud == 6 ? 0xc0 :
++			  baud == 7 ? 0x80 : /* really 76800bps */
++				      0x40;  /* really 153600bps */
++		div = 0;
++	}
++
++	reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40;
++	reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */;
++
++	(void)scc.cha_b_ctrl;		/* reset reg pointer */
++	SCC_WRITE(9, 0xc0);		/* reset */
++	LONG_DELAY();			/* extra delay after WR9 access */
++	SCC_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 |
++		  0x04 /* 1 stopbit */ |
++		  clkmode);
++	SCC_WRITE(3, reg3);
++	SCC_WRITE(5, reg5);
++	SCC_WRITE(9, 0);		/* no interrupts */
++	LONG_DELAY();			/* extra delay after WR9 access */
++	SCC_WRITE(10, 0);		/* NRZ mode */
++	SCC_WRITE(11, clksrc);		/* main clock source */
++	SCC_WRITE(12, div);		/* BRG value */
++	SCC_WRITE(13, 0);		/* BRG high byte */
++	SCC_WRITE(14, brgsrc_table[baud]);
++	SCC_WRITE(14, brgsrc_table[baud] | (div ? 1 : 0));
++	SCC_WRITE(3, reg3 | 1);
++	SCC_WRITE(5, reg5 | 8);
++
++	atari_SCC_reset_done = 1;
++	atari_SCC_init_done = 1;
++}
++
++static void scc_ch_write(char ch)
++{
++	volatile char *p = NULL;
++
++	if (MACH_IS_TT || MACH_IS_FALCON)
++		p = (volatile char *)&scc.cha_b_ctrl;
++
++	if (MACH_IS_ST)
++		p = (volatile char *)&scc.cha_b_ctrl;
++
++	if (MACH_IS_STE)
++		p = (volatile char *)&st_escc.cha_b_ctrl;
++
++	do {
++		scc_delay();
++	}
++	while (!(*p & 4));
++	// scc_delay();
++	// *p = 8;
++	scc_delay();
++	*(p+1) = ch;
++}
++
++/* The console must be locked when we get here. */
++
++static void scc_console_write(struct console *co, const char *str, unsigned count)
++{
++	unsigned long flags;
++
++	//printk("scc_console_write: %s\n", str);
++	local_irq_save(flags);
++
++	while (count--) {
++		if (*str == '\n')
++			scc_ch_write('\r');
++		scc_ch_write(*str++);
++	}
++	local_irq_restore(flags);
++	//printk("scc_console_write done!\n");
++}
++
++static struct tty_driver *scc_console_device(struct console *c, int *index)
++{
++	*index = c->index;
++	return scc_driver;
++}
++
++
++static int __init scc_console_setup(struct console *co, char *options)
++{
++	printk("scc_console_setup: initializing SCC port B\n");
++	atari_init_scc_port(B9600|CS8);
++	printk("scc_console_setup: done!\n");
++	return 0;
++}
++
++
++static struct console sercons = {
++	.name		= "ttyS",
++	.write		= scc_console_write,
++	.device		= scc_console_device,
++	.setup		= scc_console_setup,
++	.flags		= CON_PRINTBUFFER,
++	.index		= -1,
++};
++
++
++static int __init vme_scc_console_init(void)
++{
++	if (MACH_IS_TT || MACH_IS_ST || MACH_IS_FALCON)
++		register_console(&sercons);
++	return 0;
++}
++
++console_initcall(vme_scc_console_init);
++#endif
++
++/***************************** End of Functions *********************/
++
++MODULE_AUTHOR("Michael Schmitz");
++MODULE_DESCRIPTION("Atari Amd8350 SCC serial driver");
++MODULE_LICENSE("GPL");
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0017-m68k-Atari-SCC-serial-driver-checkpatch-cleanups.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0017-m68k-Atari-SCC-serial-driver-checkpatch-cleanups.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,1336 @@
+From 4e76cee5a86b062ee4ff469aa3cea29ad5280ec3 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 20:54:06 +0100
+Subject: [PATCH] m68k: Atari SCC serial driver checkpatch cleanups
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/atari/ataints.c       |    2 -
+ arch/m68k/atari/debug.c         |    6 +-
+ arch/m68k/include/asm/atarihw.h |    3 +
+ drivers/char/atari_scc.c        |  570 +++++++++++++++------------------------
+ 4 files changed, 232 insertions(+), 349 deletions(-)
+
+diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
+index 39478dd..eaa23c7 100644
+--- a/arch/m68k/atari/ataints.c
++++ b/arch/m68k/atari/ataints.c
+@@ -318,8 +318,6 @@ __ALIGN_STR "\n\t"
+ 
+ extern void atari_microwire_cmd(int cmd);
+ 
+-extern int atari_SCC_reset_done;
+-
+ static int atari_startup_irq(unsigned int irq)
+ {
+ 	m68k_irq_startup(irq);
+diff --git a/arch/m68k/atari/debug.c b/arch/m68k/atari/debug.c
+index 24dd582..422770f 100644
+--- a/arch/m68k/atari/debug.c
++++ b/arch/m68k/atari/debug.c
+@@ -20,6 +20,11 @@
+ #include <asm/atarihw.h>
+ #include <asm/atariints.h>
+ 
++/*
++ * Flags to indicate one of the serial ports has already been initialized by the
++ * serial debug driver. We may want to hold off reinitializing ...
++ */
++
+ /* Flag that Modem1 port is already initialized and used */
+ int atari_SCC_init_done;
+ EXPORT_SYMBOL(atari_SCC_init_done);
+@@ -206,7 +211,6 @@ static void __init atari_init_mfp_port(int cflag)
+ 
+ static void __init atari_init_scc_port(int cflag)
+ {
+-	extern int atari_SCC_reset_done;
+ 	static int clksrc_table[9] =
+ 		/* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */
+ 		{ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 };
+diff --git a/arch/m68k/include/asm/atarihw.h b/arch/m68k/include/asm/atarihw.h
+index a714e1a..141e544 100644
+--- a/arch/m68k/include/asm/atarihw.h
++++ b/arch/m68k/include/asm/atarihw.h
+@@ -30,6 +30,9 @@ extern u_long atari_switches;
+ extern int atari_rtc_year_offset;
+ extern int atari_dont_touch_floppy_select;
+ 
++extern int atari_SCC_init_done;
++extern int atari_SCC_reset_done;
++
+ /* convenience macros for testing machine type */
+ #define MACH_IS_ST	((atari_mch_cookie >> 16) == ATARI_MCH_ST)
+ #define MACH_IS_STE	((atari_mch_cookie >> 16) == ATARI_MCH_STE && \
+diff --git a/drivers/char/atari_scc.c b/drivers/char/atari_scc.c
+index 08cb523..982de52 100644
+--- a/drivers/char/atari_scc.c
++++ b/drivers/char/atari_scc.c
+@@ -22,7 +22,7 @@
+ 
+ #include <linux/module.h>
+ #include <linux/kdev_t.h>
+-#include <asm/io.h>
++#include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/sched.h>
+ #include <linux/ioport.h>
+@@ -39,14 +39,14 @@
+ #include <linux/miscdevice.h>
+ #include <linux/console.h>
+ #include <linux/init.h>
++#include <linux/uaccess.h>
++#include <linux/generic_serial.h>
++
+ #include <asm/setup.h>
+-#include <asm/uaccess.h>
+ #include <asm/bootinfo.h>
+-
+ #include <asm/atarihw.h>
+ #include <asm/atariints.h>
+ 
+-#include <linux/generic_serial.h>
+ #include "scc.h"
+ 
+ #define CONFIG_TT_SCC     1
+@@ -61,7 +61,7 @@
+ static unsigned char scc_shadow[2][16];
+ 
+ /* Location to access for SCC register access delay */
+-static volatile unsigned char *scc_del = NULL;
++static volatile unsigned char *scc_del;
+ 
+ /* To keep track of STATUS_REG state for detection of Ext/Status int source */
+ static unsigned char scc_last_status_reg[2];
+@@ -95,16 +95,6 @@ static struct tty_driver *scc_driver;
+ 
+ static struct scc_port scc_ports[2];
+ 
+-/*
+- * Flags to indicate one of the serial ports has already been initialized by the
+- * serial debug driver. We may want to hold off reinitializing ...
+- */
+-
+-/* Flag that Modem1 port is already initialized and used */
+-extern int atari_SCC_init_done;
+-/* Can be set somewhere, if a SCC master reset has already be done and should
+- * not be repeated; used by kgdb */
+-extern int atari_SCC_reset_done;
+ 
+ /*---------------------------------------------------------------------------
+  * Interface from generic_serial.c back here
+@@ -144,17 +134,17 @@ static struct tty_operations scc_ops = {
+ 
+ /* BRG values for the standard speeds and the various clock sources */
+ 
+-typedef struct {
+-	unsigned clksrc;		/* clock source to use or -1 for not possible */
+-	unsigned div;			/* divisor: 1, 2 and 4 correspond to
+-					 * direct 1:16, 1:32 and 1:64 modes,
+-					 * divisors >= 4 yield a BRG value of
+-					 * div/2-2 (in 1:16 mode)
+-					 */
+-} BAUD_ENTRY;
++struct baud_entry {
++	unsigned clksrc;	/* clock source to use or -1 for not possible */
++	unsigned div;		/* divisor: 1, 2 and 4 correspond to
++				 * direct 1:16, 1:32 and 1:64 modes,
++				 * divisors >= 4 yield a BRG value of
++				 * div/2-2 (in 1:16 mode)
++				 */
++};
+ 
+ /* A pointer for each channel to the current baud table */
+-static BAUD_ENTRY *scc_baud_table[2];
++static struct baud_entry *scc_baud_table[2];
+ 
+ /* Baud table format:
+  *
+@@ -174,7 +164,7 @@ static BAUD_ENTRY *scc_baud_table[2];
+  * channel A and for both channels on the Mega STE/Falcon. (TRxC is unused)
+  */
+ 
+-static BAUD_ENTRY bdtab_norm[20] = {
++static struct baud_entry bdtab_norm[20] = {
+ 	/* B0      */ { 0, 0 },
+ 	/* B50     */ { CLK_RTxC, 4590 },
+ 	/* B75     */ { CLK_RTxC, 3060 },
+@@ -200,7 +190,7 @@ static BAUD_ENTRY bdtab_norm[20] = {
+ /* This is a special table for the TT channel B with 307.2 kHz at RTxC
+  * and 2.4576 MHz at TRxC
+  */
+-static BAUD_ENTRY bdtab_TTChB[20] = {
++static struct baud_entry bdtab_TTChB[20] = {
+ 	/* B0      */ { 0, 0 },
+ 	/* B50     */ { CLK_RTxC, 384 },
+ 	/* B75     */ { CLK_RTxC, 256 },
+@@ -217,8 +207,10 @@ static BAUD_ENTRY bdtab_TTChB[20] = {
+ 	/* B9600   */ { CLK_RTxC, 2 },
+ 	/* B19200  */ { CLK_RTxC, 1 },
+ 	/* B38400  */ { CLK_TRxC, 4 },
+-	/* B57600  */ { CLK_TRxC, 2 }, /* 57600 is not possible, use 76800 instead */
+-	/* B115200 */ { CLK_TRxC, 1 }, /* 115200 is not possible, use 153600 instead */
++	/* 57600 is not possible, use 76800 instead */
++	/* B57600  */ { CLK_TRxC, 2 },
++	/* 115200 is not possible, use 153600 instead */
++	/* B115200 */ { CLK_TRxC, 1 },
+ 	/* B230400 */ { 0, 0 },        /* #18 spd_shi: Impossible  */
+ 	/* B460800 */ { 0, 0 }         /* #19 spd_warp: Impossible */
+ };
+@@ -248,8 +240,9 @@ static int scc_init_drivers(void)
+ 
+ 	tty_set_operations(scc_driver, &scc_ops);
+ 
+-	if ((error = tty_register_driver(scc_driver))) {
+-		printk(KERN_ERR "scc: Couldn't register scc driver, error = %d\n",
++	error = tty_register_driver(scc_driver);
++	if (error) {
++		pr_err("scc: Couldn't register scc driver, error = %d\n",
+ 		       error);
+ 		put_tty_driver(scc_driver);
+ 		return 1;
+@@ -287,23 +280,19 @@ static int atari_tt_scc_init(void)
+ {
+ 	struct scc_port *port;
+ 
+-	printk(KERN_INFO "SCC: Atari TT Serial Driver\n");
++	pr_info("SCC: Atari TT Serial Driver\n");
+ 	/* FIXME channel A may be switchable between modem and LAN port */
+ 	/* Init channel A */
+ 	if (atari_SCC_init_done)
+-		printk(KERN_INFO "SCC: already initialized, expect trouble!\n");
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: init channel A\n");
+-#endif
++		pr_warning("SCC: already initialized, expect trouble!\n");
++	pr_debug("SCC: init channel A\n");
+ 	port = &scc_ports[0];
+ 	port->channel = CHANNEL_A;
+ 	port->ctrlp = (volatile unsigned char *)&scc.cha_a_ctrl;
+ 	port->datap = port->ctrlp + 1;
+ 	port->port_a = &scc_ports[0];
+ 	port->port_b = &scc_ports[1];
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: request channel A irqs, port = %p\n", port);
+-#endif
++	pr_debug("SCC: request channel A irqs, port = %p\n", port);
+ 	request_irq(IRQ_SCCA_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-A TX", port);
+ 	request_irq(IRQ_SCCA_STAT, scc_stat_int, IRQ_TYPE_PRIO,
+ 		    "SCC-A status", port);
+@@ -312,14 +301,13 @@ static int atari_tt_scc_init(void)
+ 		    "SCC-A special cond", port);
+ 	{
+ 		SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: read SCC status\n");
+-#endif
+-		/* on the first access, read status register to reset internal pointers */
++		pr_debug("SCC: read SCC status\n");
++		/*
++		 * on the first access, read status register to reset internal
++		 * pointers
++		 */
+ 		SCCread(STATUS_REG);
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: reset SCC\n");
+-#endif
++		pr_debug("SCC: reset SCC\n");
+ 		/* FIXME: master reset, once only */
+ 		SCCwrite(MASTER_INT_CTRL, MIC_HARD_RESET);
+ 		udelay(40);
+@@ -338,18 +326,14 @@ static int atari_tt_scc_init(void)
+ 
+ 	if (!atari_SCC_init_done) {
+ 		/* Init channel B */
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: init channel B\n");
+-#endif
++		pr_debug("SCC: init channel B\n");
+ 		port = &scc_ports[1];
+ 		port->channel = CHANNEL_B;
+ 		port->ctrlp = (volatile unsigned char *)&scc.cha_b_ctrl;
+ 		port->datap = port->ctrlp + 1;
+ 		port->port_a = &scc_ports[0];
+ 		port->port_b = &scc_ports[1];
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: request channel B irqs, port = %p\n", port);
+-#endif
++		pr_debug("SCC: request channel B irqs, port = %p\n", port);
+ 		request_irq(IRQ_SCCB_TX, scc_tx_int, IRQ_TYPE_PRIO,
+ 			    "SCC-B TX", port);
+ 		request_irq(IRQ_SCCB_STAT, scc_stat_int, IRQ_TYPE_PRIO,
+@@ -382,13 +366,9 @@ static int atari_tt_scc_init(void)
+ 	scc_baud_table[CHANNEL_B] = bdtab_TTChB;
+ 
+ 	/* Initialise the tty driver structures and register */
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: scc_init_portstructs()\n");
+-#endif
++	pr_debug("SCC: scc_init_portstructs()\n");
+ 	scc_init_portstructs();
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: scc_init_drivers()\n");
+-#endif
++	pr_debug("SCC: scc_init_drivers()\n");
+ 	scc_init_drivers();
+ 
+ 	return 0;
+@@ -401,9 +381,9 @@ static int atari_falcon_scc_init(void)
+ {
+ 	struct scc_port *port;
+ 
+-	printk(KERN_INFO "SCC: Atari Falcon Serial Driver\n");
++	pr_info("SCC: Atari Falcon Serial Driver\n");
+ 	if (atari_SCC_init_done)
+-		printk(KERN_INFO "SCC: already initialized, expect trouble!\n");
++		pr_warning("SCC: already initialized, expect trouble!\n");
+ 
+ 	/* Init channel A */
+ 	port = &scc_ports[0];
+@@ -421,7 +401,10 @@ static int atari_falcon_scc_init(void)
+ 	{
+ 		SCC_ACCESS_INIT(port);
+ 
+-		/* on the first access, read status register to reset internal pointers */
++		/*
++		 * on the first access, read status register to reset internal
++		 * pointers
++		 */
+ 		SCCread(STATUS_REG);
+ 
+ 		/* FIXME: master reset, once only */
+@@ -476,15 +459,15 @@ static int atari_falcon_scc_init(void)
+ static int atari_st_scc_init(void)
+ {
+ 	struct scc_port *port;
+-
+ 	int escc = ATARIHW_PRESENT(ST_ESCC);
+ 
+-	printk(KERN_INFO "SCC: Atari MegaST/E Serial Driver\n");
++	pr_info("SCC: Atari MegaST/E Serial Driver\n");
+ 	/* FIXME: ports reversed logic */
+ 	/* Init channel A */
+ 	port = &scc_ports[1];
+ 	port->channel = CHANNEL_A;
+-	port->ctrlp = (volatile unsigned char *)(escc ? &st_escc.cha_a_ctrl : &scc.cha_a_ctrl);
++	port->ctrlp = (volatile unsigned char *)(escc ? &st_escc.cha_a_ctrl
++						      : &scc.cha_a_ctrl);
+ 	port->datap = port->ctrlp + 4;
+ 	port->port_a = &scc_ports[1];
+ 	port->port_b = &scc_ports[0];
+@@ -497,7 +480,10 @@ static int atari_st_scc_init(void)
+ 	{
+ 		SCC_ACCESS_INIT(port);
+ 
+-		/* on the first access, read status register to reset internal pointers */
++		/*
++		 * on the first access, read status register to reset internal
++		 * pointers
++		 */
+ 		SCCread(STATUS_REG);
+ 
+ 		/* FIXME: master reset, once only */
+@@ -516,7 +502,8 @@ static int atari_st_scc_init(void)
+ 	/* Init channel B */
+ 	port = &scc_ports[0];
+ 	port->channel = CHANNEL_B;
+-	port->ctrlp = (volatile unsigned char *)(escc ? &st_escc.cha_b_ctrl : &scc.cha_b_ctrl);
++	port->ctrlp = (volatile unsigned char *)(escc ? &st_escc.cha_b_ctrl
++						      : &scc.cha_b_ctrl);
+ 	port->datap = port->ctrlp + 4;
+ 	port->port_a = &scc_ports[0];
+ 	port->port_b = &scc_ports[1];
+@@ -550,7 +537,7 @@ static int atari_st_scc_init(void)
+ int atari_scc_init(void)
+ {
+ 	int res = -ENODEV;
+-	static int called = 0;
++	static int called;
+ 
+ 	if (called)
+ 		return res;
+@@ -582,18 +569,14 @@ void atari_scc_cleanup(void)
+ 
+ 	tty_unregister_driver(scc_driver);
+ 	port = &scc_ports[0];
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: free channel A irqs, port = %p\n", port);
+-#endif
++	pr_debug("SCC: free channel A irqs, port = %p\n", port);
+ 	free_irq(IRQ_SCCA_TX, port);
+ 	free_irq(IRQ_SCCA_STAT, port);
+ 	free_irq(IRQ_SCCA_RX, port);
+ 	free_irq(IRQ_SCCA_SPCOND, port);
+ 
+ 	port = &scc_ports[1];
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: free channel A irqs, port = %p\n", port);
+-#endif
++	pr_debug("SCC: free channel A irqs, port = %p\n", port);
+ 	free_irq(IRQ_SCCB_TX, port);
+ 	free_irq(IRQ_SCCB_STAT, port);
+ 	free_irq(IRQ_SCCB_RX, port);
+@@ -613,13 +596,12 @@ static irqreturn_t scc_rx_int(int irq, void *data)
+ 	unsigned char ch;
+ 	struct scc_port *port = data;
+ 	struct tty_struct *tty = port->gs.tty;
++
+ 	SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: rx_int ...\n");
+-#endif
++	pr_debug("SCC: rx_int ...\n");
+ 	ch = SCCread_NB(RX_DATA_REG);
+ 	if (!tty) {
+-		printk(KERN_WARNING "scc_rx_int with NULL tty!\n");
++		pr_warning("scc_rx_int with NULL tty!\n");
+ 		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
+ 		return IRQ_HANDLED;
+ 	}
+@@ -633,9 +615,11 @@ static irqreturn_t scc_rx_int(int irq, void *data)
+ 		tty->flip.count++;
+ 	}
+ #endif
+-	/* Check if another character is already ready; in that case, the
+-	 * spcond_int() function must be used, because this character may have an
+-	 * error condition that isn't signalled by the interrupt vector used!
++	/*
++	 * Check if another character is already ready; in that case, the
++	 * spcond_int() function must be used, because this character may have
++	 * an * error condition that isn't signalled by the interrupt vector
++	 * used!
+ 	 */
+ 	if (SCCread(INT_PENDING_REG) &
+ 	    (port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX)) {
+@@ -646,9 +630,7 @@ static irqreturn_t scc_rx_int(int irq, void *data)
+ 	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
+ 
+ 	tty_flip_buffer_push(tty);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: rx_int done\n");
+-#endif
++	pr_debug("SCC: rx_int done\n");
+ 	return IRQ_HANDLED;
+ }
+ 
+@@ -661,11 +643,9 @@ static irqreturn_t scc_spcond_int(int irq, void *data)
+ 	int int_pending_mask = port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX;
+ 
+ 	SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: spcond_int ...\n");
+-#endif
++	pr_debug("SCC: spcond_int ...\n");
+ 	if (!tty) {
+-		printk(KERN_WARNING "scc_spcond_int with NULL tty!\n");
++		pr_warning("scc_spcond_int with NULL tty!\n");
+ 		SCCwrite(COMMAND_REG, CR_ERROR_RESET);
+ 		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
+ 		return IRQ_HANDLED;
+@@ -704,9 +684,7 @@ static irqreturn_t scc_spcond_int(int irq, void *data)
+ 	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
+ 
+ 	tty_flip_buffer_push(tty);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: spcond_int done\n");
+-#endif
++	pr_debug("SCC: spcond_int done\n");
+ 	return IRQ_HANDLED;
+ }
+ 
+@@ -724,12 +702,11 @@ static void scc_ri_int(int irq, void *data)
+ static irqreturn_t scc_tx_int(int irq, void *data)
+ {
+ 	struct scc_port *port = data;
++
+ 	SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: tx_int irq %d port %p ...\n", irq, data);
+-#endif
++	pr_debug("SCC: tx_int irq %d port %p ...\n", irq, data);
+ 	if (!port->gs.tty) {
+-		printk(KERN_WARNING "scc_tx_int with NULL tty!\n");
++		pr_warning("scc_tx_int with NULL tty!\n");
+ 		SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
+ 		SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);
+ 		SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
+@@ -737,50 +714,40 @@ static irqreturn_t scc_tx_int(int irq, void *data)
+ 	}
+ 	while ((SCCread_NB(STATUS_REG) & SR_TX_BUF_EMPTY)) {
+ 		if (port->x_char) {
+-#ifdef DEBUG
+-			printk(KERN_INFO "SCC: tx_int writing char %c\n",
+-			       port->x_char);
+-#endif
++			pr_debug("SCC: tx_int writing char %c\n", port->x_char);
+ 			SCCwrite(TX_DATA_REG, port->x_char);
+ 			port->x_char = 0;
+ 		} else if ((port->gs.xmit_cnt <= 0) || port->gs.tty->stopped ||
+ 			   port->gs.tty->hw_stopped) {
+-#ifdef DEBUG
+-			printk(KERN_INFO "SCC: nothing to do!\n");
+-#endif
++			pr_debug("SCC: nothing to do!\n");
+ 			break;
+ 		} else {
+-#ifdef DEBUG
+-			printk(KERN_INFO "SCC: tx_int writing buf %c\n",
+-			       port->gs.xmit_buf[port->gs.xmit_tail]);
+-#endif
+-			SCCwrite(TX_DATA_REG, port->gs.xmit_buf[port->gs.xmit_tail++]);
+-			port->gs.xmit_tail = port->gs.xmit_tail & (SERIAL_XMIT_SIZE-1);
++			pr_debug("SCC: tx_int writing buf %c\n",
++				 port->gs.xmit_buf[port->gs.xmit_tail]);
++			SCCwrite(TX_DATA_REG,
++				 port->gs.xmit_buf[port->gs.xmit_tail++]);
++			port->gs.xmit_tail = port->gs.xmit_tail &
++					     (SERIAL_XMIT_SIZE-1);
+ 			if (--port->gs.xmit_cnt <= 0)
+ 				break;
+ 		}
+ 	}
+ 	if ((port->gs.xmit_cnt <= 0) || port->gs.tty->stopped ||
+ 	    port->gs.tty->hw_stopped) {
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: nothing to do, disabling int\n");
+-#endif
++		pr_debug("SCC: nothing to do, disabling int\n");
+ 		/* disable tx interrupts */
+ 		SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
+-		SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);	/* disable tx_int on next tx underrun? */
++		/* disable tx_int on next tx underrun? */
++		SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);
+ 		port->gs.flags &= ~GS_TX_INTEN;
+ 	}
+ 	if (port->gs.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) {
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: waking up tty!\n");
+-#endif
++		pr_debug("SCC: waking up tty!\n");
+ 		tty_wakeup(port->gs.tty);
+ 	}
+ 
+ 	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: tx_int done\n");
+-#endif
++	pr_debug("SCC: tx_int done\n");
+ 	return IRQ_HANDLED;
+ }
+ 
+@@ -790,10 +757,9 @@ static irqreturn_t scc_stat_int(int irq, void *data)
+ 	struct scc_port *port = data;
+ 	unsigned channel = port->channel;
+ 	unsigned char last_sr, sr, changed;
++
+ 	SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: stat_int ...\n");
+-#endif
++	pr_debug("SCC: stat_int ...\n");
+ 	last_sr = scc_last_status_reg[channel];
+ 	sr = scc_last_status_reg[channel] = SCCread_NB(STATUS_REG);
+ 	changed = last_sr ^ sr;
+@@ -811,13 +777,11 @@ static irqreturn_t scc_stat_int(int irq, void *data)
+ 		}
+ 	}
+ 
+-	// FIXME: CTS and DSR status changes?
++	/* FIXME: CTS and DSR status changes? */
+ 
+ 	SCCwrite(COMMAND_REG, CR_EXTSTAT_RESET);
+ 	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: stat_int done\n");
+-#endif
++	pr_debug("SCC: stat_int done\n");
+ 	return IRQ_HANDLED;
+ }
+ 
+@@ -830,17 +794,14 @@ static void scc_disable_tx_interrupts(void *ptr)
+ {
+ 	struct scc_port *port = ptr;
+ 	unsigned long flags;
++
+ 	SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: disable_tx_int ...\n");
+-#endif
++	pr_debug("SCC: disable_tx_int ...\n");
+ 	local_irq_save(flags);
+ 	SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
+ 	port->gs.flags &= ~GS_TX_INTEN;
+ 	local_irq_restore(flags);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: disable_tx_int done!\n");
+-#endif
++	pr_debug("SCC: disable_tx_int done!\n");
+ }
+ 
+ 
+@@ -850,17 +811,13 @@ static void scc_enable_tx_interrupts(void *ptr)
+ 	unsigned long flags;
+ 
+ 	SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: enable_tx_int ...\n");
+-#endif
++	pr_debug("SCC: enable_tx_int ...\n");
+ 	local_irq_save(flags);
+ 	SCCmod(INT_AND_DMA_REG, 0xff, IDR_TX_INT_ENAB);
+ 	/* restart the transmitter */
+ 	scc_tx_int(0, port);
+ 	local_irq_restore(flags);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: enable_tx_int done!\n");
+-#endif
++	pr_debug("SCC: enable_tx_int done!\n");
+ }
+ 
+ 
+@@ -870,16 +827,12 @@ static void scc_disable_rx_interrupts(void *ptr)
+ 	unsigned long flags;
+ 
+ 	SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: disable_rx_int ...\n");
+-#endif
++	pr_debug("SCC: disable_rx_int ...\n");
+ 	local_irq_save(flags);
+ 	SCCmod(INT_AND_DMA_REG,
+ 	       ~(IDR_RX_INT_MASK|IDR_PARERR_AS_SPCOND|IDR_EXTSTAT_INT_ENAB), 0);
+ 	local_irq_restore(flags);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: disable_rx_int done!\n");
+-#endif
++	pr_debug("SCC: disable_rx_int done!\n");
+ }
+ 
+ 
+@@ -889,16 +842,12 @@ static void scc_enable_rx_interrupts(void *ptr)
+ 	unsigned long flags;
+ 
+ 	SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: enable_rx_int ...\n");
+-#endif
++	pr_debug("SCC: enable_rx_int ...\n");
+ 	local_irq_save(flags);
+ 	SCCmod(INT_AND_DMA_REG, 0xff,
+ 	       IDR_EXTSTAT_INT_ENAB|IDR_PARERR_AS_SPCOND|IDR_RX_INT_ALL);
+ 	local_irq_restore(flags);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: enable_rx_int done!\n");
+-#endif
++	pr_debug("SCC: enable_rx_int done!\n");
+ }
+ 
+ 
+@@ -906,9 +855,8 @@ static int scc_get_CD(void *ptr)
+ {
+ 	struct scc_port *port = ptr;
+ 	unsigned channel = port->channel;
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: get_CD!\n");
+-#endif
++
++	pr_debug("SCC: get_CD!\n");
+ 	return !!(scc_last_status_reg[channel] & SR_DCD);
+ }
+ 
+@@ -916,15 +864,12 @@ static int scc_get_CD(void *ptr)
+ static void scc_shutdown_port(void *ptr)
+ {
+ 	struct scc_port *port = ptr;
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: shutdown_port ...\n");
+-#endif
++
++	pr_debug("SCC: shutdown_port ...\n");
+ 	port->gs.flags &= ~GS_ACTIVE;
+ 	if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL)
+ 		scc_setsignals(port, 0, 0);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: shutdown_port done!\n");
+-#endif
++	pr_debug("SCC: shutdown_port done!\n");
+ }
+ 
+ 
+@@ -936,15 +881,14 @@ static int scc_set_real_termios(void *ptr)
+ 	unsigned int clkmode, clksrc, div, chsize, channel, brgval = 0;
+ 	unsigned long flags;
+ 	struct scc_port *port = ptr;
++
+ 	SCC_ACCESS_INIT(port);
+ 
+ 	if (!port->gs.tty || !port->gs.tty->termios)
+ 		return 0;
+ 
+ 	channel = port->channel;
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: termios for channel %p\n", channel);
+-#endif
++	pr_debug("SCC: termios for channel %u\n", channel);
+ 	cflag = port->gs.tty->termios->c_cflag;
+ 	baud = port->gs.baud;
+ 	baudbits = cflag & CBAUD;
+@@ -958,7 +902,7 @@ static int scc_set_real_termios(void *ptr)
+ 		return 0;
+ 	} else if ((MACH_IS_TT && (baud < 50 || baud > 115200)) ||
+ 		   (MACH_IS_FALCON && (baud < 50 || baud > 230400))) {
+-		printk(KERN_NOTICE "SCC: Bad speed requested, %d\n", baud);
++		pr_debug("SCC: Bad speed requested, %d\n", baud);
+ 		return 0;
+ 	}
+ 
+@@ -967,10 +911,12 @@ static int scc_set_real_termios(void *ptr)
+ 	else
+ 		port->gs.flags |= ASYNC_CHECK_CD;
+ 
+-	// calculate brgval for Atari; enable direct modes!
+-
+-	/* convert baud rate from gs.baud to table index, set custom divisor eventually */
++	/* calculate brgval for Atari; enable direct modes! */
+ 
++	/*
++	 * convert baud rate from gs.baud to table index, set custom divisor
++	 * eventually
++	 */
+ 	div     = 0;
+ 	clksrc  = 0;
+ 	baudidx = 0;
+@@ -1042,14 +988,12 @@ static int scc_set_real_termios(void *ptr)
+ 		clksrc = scc_baud_table[channel][baudidx].clksrc;
+ 		div = scc_baud_table[channel][baudidx].div;
+ 		if (!div) {
+-			printk(" SCC_change_speed: divisor = 0 !!!");
++			pr_debug("SCC_change_speed: divisor = 0 !!!\n");
+ 			return 0;
+ 		}
+ 	}
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: termios baud %d baudbits %d baudidx %d \n clksrc %d div %d\n",
+-		baud, baudbits, baudidx, clksrc, div);
+-#endif
++	pr_debug("SCC: termios baud %d baudbits %d baudidx %d \n clksrc %d "
++		 "div %d\n", baud, baudbits, baudidx, clksrc, div);
+ 	/* compute the SCC's clock source, clock mode, BRG mode and BRG
+ 	 * value from clksrc and div
+ 	 */
+@@ -1070,18 +1014,19 @@ static int scc_set_real_termios(void *ptr)
+ 		clksrc  = CCR_TXCLK_BRG | CCR_RXCLK_BRG;
+ 	}
+ 
+-	//printk(KERN_INFO "SCC: termios baud %d baudbits %d baudidx %d \n clksrc %d clkmode %d div %d brgval %d brgmode %d\n",
+-	//	baud, baudbits, baudidx, clksrc, clkmode, div, brgval, brgmode);
++	/*
++	 * pr_info("SCC: termios baud %d baudbits %d baudidx %d \n clksrc %d "
++	 *         "clkmode %d div %d brgval %d brgmode %d\n", baud, baudbits,
++	 *         baudidx, clksrc, clkmode, div, brgval, brgmode);
++	 */
+ 
+ 	/* Now we have all parameters and can go to set them: */
+ 	local_irq_save(flags);
+ 
+-#ifdef DEBUG
+-	printk("  brgval=%d brgmode=%02x clkmode=%02x clksrc=%02x\n",
+-		brgval, brgmode, clkmode, clksrc);
+-#endif
++	pr_debug("  brgval=%d brgmode=%02x clkmode=%02x clksrc=%02x\n", brgval,
++		 brgmode, clkmode, clksrc);
+ 	/* receiver's character size and auto-enables */
+-#if 0	// auto-enable considered harmful ...
++#if 0	/* auto-enable considered harmful ... */
+ 	SCCmod(RX_CTRL_REG, ~(RCR_CHSIZE_MASK|RCR_AUTO_ENAB_MODE),
+ 	       (chsize_map[chsize] << 6) |
+ 	       ((cflag & CRTSCTS) ? RCR_AUTO_ENAB_MODE : 0));
+@@ -1089,11 +1034,9 @@ static int scc_set_real_termios(void *ptr)
+ 	/* receiver's character size */
+ 	SCCmod(RX_CTRL_REG, ~RCR_CHSIZE_MASK, chsize_map[chsize] << 6);
+ #endif
+-#ifdef DEBUG
+-	printk("  RX_CTRL_REG <- %02x\n", SCCread( RX_CTRL_REG ));
+-#endif
++	pr_debug("  RX_CTRL_REG <- %02x\n", SCCread(RX_CTRL_REG));
+ 
+-	// clock mode changes depending on baud rate
++	/* clock mode changes depending on baud rate */
+ 	/* parity and stop bits (both, Tx and Rx) and clock mode */
+ 	SCCmod(AUX1_CTRL_REG,
+ 		~(A1CR_PARITY_MASK | A1CR_MODE_MASK | A1CR_CLKMODE_MASK),
+@@ -1103,22 +1046,17 @@ static int scc_set_real_termios(void *ptr)
+ 		 | (cflag & CSTOPB ? A1CR_MODE_ASYNC_2 : A1CR_MODE_ASYNC_1)
+ 		 | clkmode));
+ 
+-#ifdef DEBUG
+-	printk("  AUX1_CTRL_REG <- %02x\n", SCCread(AUX1_CTRL_REG));
+-#endif
++	pr_debug("  AUX1_CTRL_REG <- %02x\n", SCCread(AUX1_CTRL_REG));
+ 	/* sender's character size, set DTR for valid baud rate */
+-	SCCmod(TX_CTRL_REG, ~TCR_CHSIZE_MASK, chsize_map[chsize] << 5 | TCR_DTR);
+-#ifdef DEBUG
+-	printk("  TX_CTRL_REG <- %02x\n", SCCread(TX_CTRL_REG));
+-#endif
++	SCCmod(TX_CTRL_REG, ~TCR_CHSIZE_MASK,
++	       chsize_map[chsize] << 5 | TCR_DTR);
++	pr_debug("  TX_CTRL_REG <- %02x\n", SCCread(TX_CTRL_REG));
+ 
+-	// clock sources change for TT !!
++	/* clock sources change for TT !! */
+ 	/* clock sources never change */
+ 	/* clock sources */
+ 	SCCmod(CLK_CTRL_REG, ~(CCR_TXCLK_MASK | CCR_RXCLK_MASK), clksrc);
+-#ifdef DEBUG
+-	printk("  CLK_CTRL_REG <- %02x\n", SCCread(CLK_CTRL_REG));
+-#endif
++	pr_debug("  CLK_CTRL_REG <- %02x\n", SCCread(CLK_CTRL_REG));
+ 
+ 	/* disable BRG before changing the value */
+ 	SCCmod(DPLL_CTRL_REG, ~DCR_BRG_ENAB, 0);
+@@ -1126,20 +1064,14 @@ static int scc_set_real_termios(void *ptr)
+ 	SCCwrite(TIMER_LOW_REG, brgval & 0xff);
+ 	SCCwrite(TIMER_HIGH_REG, (brgval >> 8) & 0xff);
+ 	/* BRG enable, and clock source never changes */
+-	//SCCmod(DPLL_CTRL_REG, 0xff, DCR_BRG_ENAB);
++	/* SCCmod(DPLL_CTRL_REG, 0xff, DCR_BRG_ENAB); */
+ 	SCCmod(DPLL_CTRL_REG, ~(DCR_BRG_ENAB | DCR_BRG_USE_PCLK), brgmode);
+-#ifdef DEBUG
+-	printk("  TIMER_LOW_REG <- %02x\n", SCCread(TIMER_LOW_REG));
+-	printk("  TIMER_HIGH_REG <- %02x\n", SCCread(TIMER_HIGH_REG));
+-#endif
+-#ifdef DEBUG
+-	printk("  DPLL_CTRL_REG <- %02x\n", SCCread(DPLL_CTRL_REG));
+-#endif
++	pr_debug("  TIMER_LOW_REG <- %02x\n", SCCread(TIMER_LOW_REG));
++	pr_debug("  TIMER_HIGH_REG <- %02x\n", SCCread(TIMER_HIGH_REG));
++	pr_debug("  DPLL_CTRL_REG <- %02x\n", SCCread(DPLL_CTRL_REG));
+ 
+ 	local_irq_restore(flags);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: done termios for channel %d\n", channel);
+-#endif
++	pr_debug("SCC: done termios for channel %d\n", channel);
+ 	return 0;
+ }
+ 
+@@ -1150,10 +1082,11 @@ static int scc_chars_in_buffer(void *ptr)
+ #ifdef DEBUG
+ 	int rv;
+ #endif
++
+ 	SCC_ACCESS_INIT(port);
+ #ifdef DEBUG
+ 	rv = (SCCread(SPCOND_STATUS_REG) & SCSR_ALL_SENT) ? 0  : 1;
+-	printk(KERN_INFO "SCC: chars_in_buffer: %d\n", rv);
++	pr_debug("SCC: chars_in_buffer: %d\n", rv);
+ 	return rv;
+ #else
+ 	return (SCCread(SPCOND_STATUS_REG) & SCSR_ALL_SENT) ? 0  : 1;
+@@ -1172,27 +1105,19 @@ static int scc_chars_in_buffer(void *ptr)
+ 
+ static void scc_hungup(void *ptr)
+ {
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: hungup ...\n");
+-#endif
++	pr_debug("SCC: hungup ...\n");
+ 	scc_disable_tx_interrupts(ptr);
+ 	scc_disable_rx_interrupts(ptr);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: hungup done\n");
+-#endif
++	pr_debug("SCC: hungup done\n");
+ }
+ 
+ 
+ static void scc_close(void *ptr)
+ {
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: close ...\n");
+-#endif
++	pr_debug("SCC: close ...\n");
+ 	scc_disable_tx_interrupts(ptr);
+ 	scc_disable_rx_interrupts(ptr);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: close done\n");
+-#endif
++	pr_debug("SCC: close done\n");
+ }
+ 
+ 
+@@ -1204,10 +1129,9 @@ static void scc_setsignals(struct scc_port *port, int dtr, int rts)
+ {
+ 	unsigned long flags;
+ 	unsigned char t;
++
+ 	SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: setsignals dtr %d rts %d...\n", dtr, rts);
+-#endif
++	pr_debug("SCC: setsignals dtr %d rts %d...\n", dtr, rts);
+ 	local_irq_save(flags);
+ 	t = SCCread(TX_CTRL_REG);
+ 	if (dtr >= 0)
+@@ -1216,24 +1140,19 @@ static void scc_setsignals(struct scc_port *port, int dtr, int rts)
+ 		t = rts? (t | TCR_RTS): (t & ~TCR_RTS);
+ 	SCCwrite(TX_CTRL_REG, t);
+ 	local_irq_restore(flags);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: setsignals done\n");
+-#endif
++	pr_debug("SCC: setsignals done\n");
+ }
+ 
+ 
+ static void scc_send_xchar(struct tty_struct *tty, char ch)
+ {
+ 	struct scc_port *port = (struct scc_port *)tty->driver_data;
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: send_xchar ...\n");
+-#endif
++
++	pr_debug("SCC: send_xchar ...\n");
+ 	port->x_char = ch;
+ 	if (ch)
+ 		scc_enable_tx_interrupts(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: send_xchar done\n");
+-#endif
++	pr_debug("SCC: send_xchar done\n");
+ }
+ 
+ 
+@@ -1254,7 +1173,8 @@ static int scc_open(struct tty_struct *tty, struct file *filp)
+ 		unsigned reg, val;
+ 	} scc_init_tab[] = {
+ 		/* no parity, 1 stop bit, async, 1:16 */
+-		{ AUX1_CTRL_REG, A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x64 },
++		{ AUX1_CTRL_REG,
++		  A1CR_PARITY_NONE|A1CR_MODE_ASYNC_1|A1CR_CLKMODE_x64 },
+ 		/* parity error is special cond, ints disabled, no DMA */
+ 		{ INT_AND_DMA_REG, IDR_PARERR_AS_SPCOND | IDR_RX_INT_DISAB },
+ 		/* Rx 8 bits/char, no auto enable, Rx off */
+@@ -1264,14 +1184,16 @@ static int scc_open(struct tty_struct *tty, struct file *filp)
+ 		/* special features off */
+ 		{ AUX2_CTRL_REG, 0 },
+ 		/* RTxC is XTAL, TRxC is input, both clocks = RTxC */
+-		{ CLK_CTRL_REG, CCR_TRxCOUT_XTAL | CCR_TXCLK_RTxC | CCR_RXCLK_RTxC },
++		{ CLK_CTRL_REG,
++		  CCR_TRxCOUT_XTAL | CCR_TXCLK_RTxC | CCR_RXCLK_RTxC },
+ 		{ DPLL_CTRL_REG, 0 },
+ 		/* Start Rx */
+ 		{ RX_CTRL_REG, RCR_RX_ENAB | RCR_CHSIZE_8 },
+ 		/* Start Tx */
+ 		{ TX_CTRL_REG, TCR_TX_ENAB | TCR_RTS | TCR_DTR | TCR_CHSIZE_8 },
+ 		/* Ext/Stat ints: CTS, DCD, SYNC (DSR) */
+-		{ INT_CTRL_REG, ICR_ENAB_DCD_INT | ICR_ENAB_CTS_INT | ICR_ENAB_SYNC_INT },
++		{ INT_CTRL_REG,
++		  ICR_ENAB_DCD_INT | ICR_ENAB_CTS_INT | ICR_ENAB_SYNC_INT },
+ 		/* Reset Ext/Stat ints */
+ 		{ COMMAND_REG, CR_EXTSTAT_RESET },
+ 		/* ...again */
+@@ -1284,57 +1206,46 @@ static int scc_open(struct tty_struct *tty, struct file *filp)
+ 	if (atari_SCC_init_done && line == 1)
+ 		return -ENODEV;
+ 
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: open port ...\n");
+-#endif
++	pr_debug("SCC: open port ...\n");
+ 	if (!(port->gs.flags & ASYNC_INITIALIZED)) {
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: init port ...\n");
+-#endif
++		pr_debug("SCC: init port ...\n");
+ 		local_irq_save(flags);
+ 
+ 		SCCmod(MASTER_INT_CTRL, 0x3f,
+ 		       channel == 0 ? MIC_CH_A_RESET : MIC_CH_B_RESET);
+ 		udelay(40);		/* extra delay after a reset */
+ 
+-		for (i = 0; i < sizeof(scc_init_tab)/sizeof(*scc_init_tab); ++i)
++		for (i = 0; i < ARRAY_SIZE(scc_init_tab); ++i)
+ 			SCCwrite(scc_init_tab[i].reg, scc_init_tab[i].val);
+ 
+ 
+-		/* remember status register for detection of DCD and CTS changes */
++		/*
++		 * remember status register for detection of DCD and CTS
++		 * changes
++		 */
+ 		scc_last_status_reg[channel] = SCCread(STATUS_REG);
+ 
+ 		port->c_dcd = 0;	/* Prevent initial 1->0 interrupt */
+ 		scc_setsignals(port, 1, 1);
+ 		local_irq_restore(flags);
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: init port done!\n");
+-#endif
++		pr_debug("SCC: init port done!\n");
+ 	}
+ 
+ 	tty->driver_data = port;
+ 	port->gs.tty = tty;
+ 	port->gs.count++;
+-#ifdef DEBUG
+-	printk(KERN_WARNING "SCC: gs init port ...\n");
+-#endif
++	pr_debug(KERN_WARNING "SCC: gs init port ...\n");
+ 	retval = gs_init_port(&port->gs);
+ 	if (retval) {
+ 		port->gs.count--;
+ 		return retval;
+ 	}
+-#ifdef DEBUG
+-	printk(KERN_WARNING "SCC: gs init port done!\n");
+-#endif
++	pr_debug(KERN_WARNING "SCC: gs init port done!\n");
+ 	port->gs.flags |= GS_ACTIVE;
+ 
+-#ifdef DEBUG
+-	printk(KERN_WARNING "SCC: gs wait ready ...\n");
+-#endif
++	pr_debug(KERN_WARNING "SCC: gs wait ready ...\n");
+ 	retval = gs_block_til_ready(port, filp);
+-#ifdef DEBUG
+-	printk(KERN_WARNING "SCC: gs wait ready done!\n");
+-#endif
++	pr_debug(KERN_WARNING "SCC: gs wait ready done!\n");
+ 	if (retval) {
+ 		port->gs.count--;
+ 		return retval;
+@@ -1342,15 +1253,10 @@ static int scc_open(struct tty_struct *tty, struct file *filp)
+ 
+ 	port->c_dcd = scc_get_CD(port);
+ 
+-#ifdef DEBUG
+-	printk(KERN_WARNING "SCC: enable rx ints ...\n");
+-#endif
++	pr_debug(KERN_WARNING "SCC: enable rx ints ...\n");
+ 	scc_enable_rx_interrupts(port);
+-#ifdef DEBUG
+-	printk(KERN_WARNING "SCC: enable rx ints done!\n");
+-
+-	printk(KERN_INFO "SCC: open port done!\n");
+-#endif
++	pr_debug(KERN_WARNING "SCC: enable rx ints done!\n");
++	pr_info("SCC: open port done!\n");
+ 	return 0;
+ }
+ 
+@@ -1359,10 +1265,9 @@ static void scc_throttle(struct tty_struct *tty)
+ {
+ 	struct scc_port *port = (struct scc_port *)tty->driver_data;
+ 	unsigned long flags;
++
+ 	SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: throttle ...\n");
+-#endif
++	pr_debug("SCC: throttle ...\n");
+ 	if (tty->termios->c_cflag & CRTSCTS) {
+ 		local_irq_save(flags);
+ 		SCCmod(TX_CTRL_REG, ~TCR_RTS, 0);
+@@ -1370,9 +1275,7 @@ static void scc_throttle(struct tty_struct *tty)
+ 	}
+ 	if (I_IXOFF(tty))
+ 		scc_send_xchar(tty, STOP_CHAR(tty));
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: throttle done!\n");
+-#endif
++	pr_debug("SCC: throttle done!\n");
+ }
+ 
+ 
+@@ -1380,10 +1283,9 @@ static void scc_unthrottle(struct tty_struct *tty)
+ {
+ 	struct scc_port *port = (struct scc_port *)tty->driver_data;
+ 	unsigned long flags;
++
+ 	SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: unthrottle ...\n");
+-#endif
++	pr_debug("SCC: unthrottle ...\n");
+ 	if (tty->termios->c_cflag & CRTSCTS) {
+ 		local_irq_save(flags);
+ 		SCCmod(TX_CTRL_REG, 0xff, TCR_RTS);
+@@ -1391,9 +1293,7 @@ static void scc_unthrottle(struct tty_struct *tty)
+ 	}
+ 	if (I_IXOFF(tty))
+ 		scc_send_xchar(tty, START_CHAR(tty));
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: unthrottle done!\n");
+-#endif
++	pr_debug("SCC: unthrottle done!\n");
+ }
+ 
+ 
+@@ -1402,11 +1302,10 @@ static int scc_ioctl(struct tty_struct *tty, struct file *file,
+ {
+ 	struct scc_port *port = (struct scc_port *)tty->driver_data;
+ 	int retval;
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: ioctl! cmd %d, arg %p \n", cmd, arg);
+-#endif
+-	//if (serial_paranoia_check(info, tty->device, "zs_ioctl"))
+-	//	return -ENODEV;
++
++	pr_debug("SCC: ioctl! cmd %d, arg %lu\n", cmd, arg);
++	/* if (serial_paranoia_check(info, tty->device, "zs_ioctl")) */
++	/*	return -ENODEV; */
+ 
+ 	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+ 	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) &&
+@@ -1417,37 +1316,29 @@ static int scc_ioctl(struct tty_struct *tty, struct file *file,
+ 
+ 	switch (cmd) {
+ 	case TCSBRK:	/* SVID version: non-zero arg --> no break */
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: ioctl TCSBRK\n");
+-#endif
++		pr_debug("SCC: ioctl TCSBRK\n");
+ 		retval = tty_check_change(tty);
+ 		if (retval)
+ 			return retval;
+ 		tty_wait_until_sent(tty, 0);
+-		//if (!arg)
+-		//	send_break(info, HZ/4);	/* 1/4 second */
++		/* if (!arg) */
++		/*	send_break(info, HZ/4);	*/
+ 		return 0;
+ 	case TCSBRKP:	/* support for POSIX tcsendbreak() */
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: ioctl TCSBRKP\n");
+-#endif
++		pr_debug("SCC: ioctl TCSBRKP\n");
+ 		retval = tty_check_change(tty);
+ 		if (retval)
+ 			return retval;
+ 		tty_wait_until_sent(tty, 0);
+-		//send_break(info, arg ? arg*(HZ/10) : HZ/4);
++		/* send_break(info, arg ? arg*(HZ/10) : HZ/4); */
+ 		return 0;
+ 	case TIOCGSOFTCAR:
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: ioctl TIOCGSOFTCAR\n");
+-#endif
++		pr_debug("SCC: ioctl TIOCGSOFTCAR\n");
+ 		if (put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long *) arg))
+ 			return -EFAULT;
+ 		return 0;
+ 	case TIOCSSOFTCAR:
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: ioctl TIOCSSOFTCAR\n");
+-#endif
++		pr_debug("SCC: ioctl TIOCSSOFTCAR\n");
+ 		if (get_user(arg, (unsigned long *)arg))
+ 			return -EFAULT;
+ 		tty->termios->c_cflag =
+@@ -1455,54 +1346,38 @@ static int scc_ioctl(struct tty_struct *tty, struct file *file,
+ 			 (arg ? CLOCAL : 0));
+ 		return 0;
+ 	case TIOCMGET:
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: ioctl TIOCMGET\n");
+-#endif
+-		//return get_modem_info(info, (unsigned int *)arg);
++		pr_debug("SCC: ioctl TIOCMGET\n");
++		/* return get_modem_info(info, (unsigned int *)arg); */
+ 		return 0;
+ 	case TIOCMBIS:
+ 	case TIOCMBIC:
+ 	case TIOCMSET:
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: ioctl TIOCMSET\n");
+-#endif
+-		//return set_modem_info(info, cmd, (unsigned int *)arg);
++		pr_debug("SCC: ioctl TIOCMSET\n");
++		/* return set_modem_info(info, cmd, (unsigned int *)arg); */
+ 		return 0;
+ 	case TIOCGSERIAL:
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: ioctl TIOCGSERIAL\n");
+-#endif
++		pr_debug("SCC: ioctl TIOCGSERIAL\n");
+ 		return 0;
+-		//return get_serial_info(info,
+-		//		       (struct serial_struct *)arg);
++		/* return get_serial_info(info, (struct serial_struct *)arg); */
+ 	case TIOCSSERIAL:
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: ioctl TIOCSSERIAL\n");
+-#endif
++		pr_debug("SCC: ioctl TIOCSSERIAL\n");
+ 		return 0;
+-		//return set_serial_info(info,
+-		//		       (struct serial_struct *)arg);
++		/* return set_serial_info(info, (struct serial_struct *)arg); */
+ 	case TIOCSERGETLSR: /* Get line status register */
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: ioctl TIOCSERGETLSR\n");
+-#endif
++		pr_debug("SCC: ioctl TIOCSERGETLSR\n");
+ 		return 0;
+-		//return get_lsr_info(info, (unsigned int *)arg);
++		/* return get_lsr_info(info, (unsigned int *)arg); */
+ 
+ 	case TIOCSERGSTRUCT:
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: ioctl TIOCSERGSTRUCT\n");
+-#endif
++		pr_debug("SCC: ioctl TIOCSERGSTRUCT\n");
+ 		return 0;
+-		if (copy_to_user((struct scc_port *)arg,
+-				 port, sizeof(struct scc_port)))
++		if (copy_to_user((struct scc_port *)arg, port,
++				 sizeof(struct scc_port)))
+ 			return -EFAULT;
+ 		return 0;
+ 
+ 	default:
+-#ifdef DEBUG
+-		printk(KERN_INFO "SCC: ioctl default\n");
+-#endif
++		pr_debug("SCC: ioctl default\n");
+ 		return -ENOIOCTLCMD;
+ 	}
+ 	return 0;
+@@ -1513,16 +1388,13 @@ static void scc_break_ctl(struct tty_struct *tty, int break_state)
+ {
+ 	struct scc_port *port = (struct scc_port *)tty->driver_data;
+ 	unsigned long flags;
++
+ 	SCC_ACCESS_INIT(port);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: break ctl ...\n");
+-#endif
++	pr_debug("SCC: break ctl ...\n");
+ 	local_irq_save(flags);
+ 	SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK, break_state ? TCR_SEND_BREAK : 0);
+ 	local_irq_restore(flags);
+-#ifdef DEBUG
+-	printk(KERN_INFO "SCC: break ctl done!\n");
+-#endif
++	pr_debug("SCC: break ctl done!\n");
+ }
+ 
+ 
+@@ -1541,18 +1413,19 @@ static void scc_break_ctl(struct tty_struct *tty, int break_state)
+ 		scc_delay();				\
+ 	} while (0)
+ 
+-/* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a
+- * delay of ~ 60us. */
++/*
++ * loops_per_jiffy isn't initialized yet, so we can't use udelay().
++ * This does a delay of ~ 60us.
++ */
+ #define LONG_DELAY()					\
+ 	do {						\
+ 		int i;					\
+-		for (i = 100; i > 0; --i)		\
++		for (i = 100; i > 0; i--)		\
+ 			scc_delay();			\
+ 	} while (0)
+ 
+ static void atari_init_scc_port(int cflag)
+ {
+-	extern int atari_SCC_reset_done;
+ 	static int clksrc_table[9] =
+ 		/* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */
+ 		{ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 };
+@@ -1573,15 +1446,20 @@ static void atari_init_scc_port(int cflag)
+ 
+ 	if (cflag & CBAUDEX)
+ 		baud += B38400;
+-	if (baud < B1200 || baud > B38400+2)
+-		baud = B9600;		/* use default 9600bps for non-implemented rates */
++	if (baud < B1200 || baud > B38400+2) {
++		/* use default 9600bps for non-implemented rates */
++		baud = B9600;
++	}
+ 	baud -= B1200;			/* tables starts at 1200bps */
+ 
+ 	clksrc  = clksrc_table[baud];
+ 	clkmode = clkmode_table[baud];
+ 	div     = div_table[baud];
+ 	if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) {
+-		/* special treatment for TT, where rates >= 38400 are done via TRxC */
++		/*
++		 * special treatment for TT, where rates >= 38400 are done via
++		 * TRxC
++		 */
+ 		clksrc = 0x28; /* TRxC */
+ 		clkmode = baud == 6 ? 0xc0 :
+ 			  baud == 7 ? 0x80 : /* really 76800bps */
+@@ -1630,21 +1508,21 @@ static void scc_ch_write(char ch)
+ 
+ 	do {
+ 		scc_delay();
+-	}
+-	while (!(*p & 4));
+-	// scc_delay();
+-	// *p = 8;
++	} while (!(*p & 4));
++	/* scc_delay(); */
++	/* *p = 8; */
+ 	scc_delay();
+ 	*(p+1) = ch;
+ }
+ 
+ /* The console must be locked when we get here. */
+ 
+-static void scc_console_write(struct console *co, const char *str, unsigned count)
++static void scc_console_write(struct console *co, const char *str,
++			      unsigned count)
+ {
+ 	unsigned long flags;
+ 
+-	//printk("scc_console_write: %s\n", str);
++	/* printk("scc_console_write: %s\n", str); */
+ 	local_irq_save(flags);
+ 
+ 	while (count--) {
+@@ -1653,7 +1531,7 @@ static void scc_console_write(struct console *co, const char *str, unsigned coun
+ 		scc_ch_write(*str++);
+ 	}
+ 	local_irq_restore(flags);
+-	//printk("scc_console_write done!\n");
++	/* printk("scc_console_write done!\n"); */
+ }
+ 
+ static struct tty_driver *scc_console_device(struct console *c, int *index)
+@@ -1665,9 +1543,9 @@ static struct tty_driver *scc_console_device(struct console *c, int *index)
+ 
+ static int __init scc_console_setup(struct console *co, char *options)
+ {
+-	printk("scc_console_setup: initializing SCC port B\n");
++	pr_debug("scc_console_setup: initializing SCC port B\n");
+ 	atari_init_scc_port(B9600|CS8);
+-	printk("scc_console_setup: done!\n");
++	pr_debug("scc_console_setup: done!\n");
+ 	return 0;
+ }
+ 
+@@ -1682,14 +1560,14 @@ static struct console sercons = {
+ };
+ 
+ 
+-static int __init vme_scc_console_init(void)
++static int __init atari_scc_console_init(void)
+ {
+ 	if (MACH_IS_TT || MACH_IS_ST || MACH_IS_FALCON)
+ 		register_console(&sercons);
+ 	return 0;
+ }
+ 
+-console_initcall(vme_scc_console_init);
++console_initcall(atari_scc_console_init);
+ #endif
+ 
+ /***************************** End of Functions *********************/
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0018-m68k-Atari-SCC-serial-driver-gs-update.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0018-m68k-Atari-SCC-serial-driver-gs-update.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,197 @@
+From bc7dd832186894a7f25f2788deec031c6f1d43e3 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 20:54:07 +0100
+Subject: [PATCH] m68k: Atari SCC serial driver gs update
+
+Update for commit commit b5391e29f428d11755ca2c91074c6db6f5c69d7c ("gs: use
+tty_port"), which moved some fields
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/char/atari_scc.c |   59 +++++++++++++++++++++++----------------------
+ 1 files changed, 30 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/char/atari_scc.c b/drivers/char/atari_scc.c
+index 982de52..335aeca 100644
+--- a/drivers/char/atari_scc.c
++++ b/drivers/char/atari_scc.c
+@@ -269,8 +269,8 @@ static void scc_init_portstructs(void)
+ #ifdef NEW_WRITE_LOCKING
+ 		port->gs.port_write_sem = MUTEX;
+ #endif
+-		init_waitqueue_head(&port->gs.open_wait);
+-		init_waitqueue_head(&port->gs.close_wait);
++		init_waitqueue_head(&port->gs.port.open_wait);
++		init_waitqueue_head(&port->gs.port.close_wait);
+ 	}
+ }
+ 
+@@ -595,7 +595,7 @@ static irqreturn_t scc_rx_int(int irq, void *data)
+ {
+ 	unsigned char ch;
+ 	struct scc_port *port = data;
+-	struct tty_struct *tty = port->gs.tty;
++	struct tty_struct *tty = port->gs.port.tty;
+ 
+ 	SCC_ACCESS_INIT(port);
+ 	pr_debug("SCC: rx_int ...\n");
+@@ -638,7 +638,7 @@ static irqreturn_t scc_rx_int(int irq, void *data)
+ static irqreturn_t scc_spcond_int(int irq, void *data)
+ {
+ 	struct scc_port *port = data;
+-	struct tty_struct *tty = port->gs.tty;
++	struct tty_struct *tty = port->gs.port.tty;
+ 	unsigned char stat, ch, err;
+ 	int int_pending_mask = port->channel == CHANNEL_A ? IPR_A_RX : IPR_B_RX;
+ 
+@@ -705,7 +705,7 @@ static irqreturn_t scc_tx_int(int irq, void *data)
+ 
+ 	SCC_ACCESS_INIT(port);
+ 	pr_debug("SCC: tx_int irq %d port %p ...\n", irq, data);
+-	if (!port->gs.tty) {
++	if (!port->gs.port.tty) {
+ 		pr_warning("scc_tx_int with NULL tty!\n");
+ 		SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
+ 		SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);
+@@ -717,8 +717,9 @@ static irqreturn_t scc_tx_int(int irq, void *data)
+ 			pr_debug("SCC: tx_int writing char %c\n", port->x_char);
+ 			SCCwrite(TX_DATA_REG, port->x_char);
+ 			port->x_char = 0;
+-		} else if ((port->gs.xmit_cnt <= 0) || port->gs.tty->stopped ||
+-			   port->gs.tty->hw_stopped) {
++		} else if ((port->gs.xmit_cnt <= 0) ||
++			   port->gs.port.tty->stopped ||
++			   port->gs.port.tty->hw_stopped) {
+ 			pr_debug("SCC: nothing to do!\n");
+ 			break;
+ 		} else {
+@@ -732,18 +733,18 @@ static irqreturn_t scc_tx_int(int irq, void *data)
+ 				break;
+ 		}
+ 	}
+-	if ((port->gs.xmit_cnt <= 0) || port->gs.tty->stopped ||
+-	    port->gs.tty->hw_stopped) {
++	if ((port->gs.xmit_cnt <= 0) || port->gs.port.tty->stopped ||
++	    port->gs.port.tty->hw_stopped) {
+ 		pr_debug("SCC: nothing to do, disabling int\n");
+ 		/* disable tx interrupts */
+ 		SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
+ 		/* disable tx_int on next tx underrun? */
+ 		SCCwrite(COMMAND_REG, CR_TX_PENDING_RESET);
+-		port->gs.flags &= ~GS_TX_INTEN;
++		port->gs.port.flags &= ~GS_TX_INTEN;
+ 	}
+-	if (port->gs.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) {
++	if (port->gs.port.tty && port->gs.xmit_cnt <= port->gs.wakeup_chars) {
+ 		pr_debug("SCC: waking up tty!\n");
+-		tty_wakeup(port->gs.tty);
++		tty_wakeup(port->gs.port.tty);
+ 	}
+ 
+ 	SCCwrite_NB(COMMAND_REG, CR_HIGHEST_IUS_RESET);
+@@ -766,14 +767,14 @@ static irqreturn_t scc_stat_int(int irq, void *data)
+ 
+ 	if (changed & SR_DCD) {
+ 		port->c_dcd = !!(sr & SR_DCD);
+-		if (!(port->gs.flags & ASYNC_CHECK_CD))
++		if (!(port->gs.port.flags & ASYNC_CHECK_CD))
+ 			;	/* Don't report DCD changes */
+ 		else if (port->c_dcd) {
+ 			/* Are we blocking in open? */
+-			wake_up_interruptible(&port->gs.open_wait);
++			wake_up_interruptible(&port->gs.port.open_wait);
+ 		} else {
+-			if (port->gs.tty)
+-				tty_hangup(port->gs.tty);
++			if (port->gs.port.tty)
++				tty_hangup(port->gs.port.tty);
+ 		}
+ 	}
+ 
+@@ -799,7 +800,7 @@ static void scc_disable_tx_interrupts(void *ptr)
+ 	pr_debug("SCC: disable_tx_int ...\n");
+ 	local_irq_save(flags);
+ 	SCCmod(INT_AND_DMA_REG, ~IDR_TX_INT_ENAB, 0);
+-	port->gs.flags &= ~GS_TX_INTEN;
++	port->gs.port.flags &= ~GS_TX_INTEN;
+ 	local_irq_restore(flags);
+ 	pr_debug("SCC: disable_tx_int done!\n");
+ }
+@@ -866,8 +867,8 @@ static void scc_shutdown_port(void *ptr)
+ 	struct scc_port *port = ptr;
+ 
+ 	pr_debug("SCC: shutdown_port ...\n");
+-	port->gs.flags &= ~GS_ACTIVE;
+-	if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL)
++	port->gs.port.flags &= ~GS_ACTIVE;
++	if (port->gs.port.tty && port->gs.port.tty->termios->c_cflag & HUPCL)
+ 		scc_setsignals(port, 0, 0);
+ 	pr_debug("SCC: shutdown_port done!\n");
+ }
+@@ -884,12 +885,12 @@ static int scc_set_real_termios(void *ptr)
+ 
+ 	SCC_ACCESS_INIT(port);
+ 
+-	if (!port->gs.tty || !port->gs.tty->termios)
++	if (!port->gs.port.tty || !port->gs.port.tty->termios)
+ 		return 0;
+ 
+ 	channel = port->channel;
+ 	pr_debug("SCC: termios for channel %u\n", channel);
+-	cflag = port->gs.tty->termios->c_cflag;
++	cflag = port->gs.port.tty->termios->c_cflag;
+ 	baud = port->gs.baud;
+ 	baudbits = cflag & CBAUD;
+ 	chsize = (cflag & CSIZE) >> 4;
+@@ -907,9 +908,9 @@ static int scc_set_real_termios(void *ptr)
+ 	}
+ 
+ 	if (cflag & CLOCAL)
+-		port->gs.flags &= ~ASYNC_CHECK_CD;
++		port->gs.port.flags &= ~ASYNC_CHECK_CD;
+ 	else
+-		port->gs.flags |= ASYNC_CHECK_CD;
++		port->gs.port.flags |= ASYNC_CHECK_CD;
+ 
+ 	/* calculate brgval for Atari; enable direct modes! */
+ 
+@@ -1207,7 +1208,7 @@ static int scc_open(struct tty_struct *tty, struct file *filp)
+ 		return -ENODEV;
+ 
+ 	pr_debug("SCC: open port ...\n");
+-	if (!(port->gs.flags & ASYNC_INITIALIZED)) {
++	if (!(port->gs.port.flags & ASYNC_INITIALIZED)) {
+ 		pr_debug("SCC: init port ...\n");
+ 		local_irq_save(flags);
+ 
+@@ -1232,22 +1233,22 @@ static int scc_open(struct tty_struct *tty, struct file *filp)
+ 	}
+ 
+ 	tty->driver_data = port;
+-	port->gs.tty = tty;
+-	port->gs.count++;
++	port->gs.port.tty = tty;
++	port->gs.port.count++;
+ 	pr_debug(KERN_WARNING "SCC: gs init port ...\n");
+ 	retval = gs_init_port(&port->gs);
+ 	if (retval) {
+-		port->gs.count--;
++		port->gs.port.count--;
+ 		return retval;
+ 	}
+ 	pr_debug(KERN_WARNING "SCC: gs init port done!\n");
+-	port->gs.flags |= GS_ACTIVE;
++	port->gs.port.flags |= GS_ACTIVE;
+ 
+ 	pr_debug(KERN_WARNING "SCC: gs wait ready ...\n");
+ 	retval = gs_block_til_ready(port, filp);
+ 	pr_debug(KERN_WARNING "SCC: gs wait ready done!\n");
+ 	if (retval) {
+-		port->gs.count--;
++		port->gs.port.count--;
+ 		return retval;
+ 	}
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0019-m68k-Atari-SCC-serial-driver-break_ctl-update.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0019-m68k-Atari-SCC-serial-driver-break_ctl-update.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,47 @@
+From a1c391377c8728e1122b48d5bdcd6a516d203adf Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 20:54:08 +0100
+Subject: [PATCH] m68k: Atari SCC serial driver break_ctl update
+
+Update for commit 9e98966c7bb94355689478bc84cc3e0c190f977e ("tty: rework break
+handling"), which made break_ctl return an error code.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/char/atari_scc.c |    6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/char/atari_scc.c b/drivers/char/atari_scc.c
+index 335aeca..f1ade4a 100644
+--- a/drivers/char/atari_scc.c
++++ b/drivers/char/atari_scc.c
+@@ -89,7 +89,7 @@ static irqreturn_t scc_rx_int(int irq, void *data);
+ static irqreturn_t scc_stat_int(int irq, void *data);
+ static irqreturn_t scc_spcond_int(int irq, void *data);
+ static void scc_setsignals(struct scc_port *port, int dtr, int rts);
+-static void scc_break_ctl(struct tty_struct *tty, int break_state);
++static int scc_break_ctl(struct tty_struct *tty, int break_state);
+ 
+ static struct tty_driver *scc_driver;
+ 
+@@ -1385,7 +1385,7 @@ static int scc_ioctl(struct tty_struct *tty, struct file *file,
+ }
+ 
+ 
+-static void scc_break_ctl(struct tty_struct *tty, int break_state)
++static int scc_break_ctl(struct tty_struct *tty, int break_state)
+ {
+ 	struct scc_port *port = (struct scc_port *)tty->driver_data;
+ 	unsigned long flags;
+@@ -1396,6 +1396,8 @@ static void scc_break_ctl(struct tty_struct *tty, int break_state)
+ 	SCCmod(TX_CTRL_REG, ~TCR_SEND_BREAK, break_state ? TCR_SEND_BREAK : 0);
+ 	local_irq_restore(flags);
+ 	pr_debug("SCC: break ctl done!\n");
++
++	return 0;
+ }
+ 
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0020-m68k-Disable-Atari-serial-console-support-if-modula.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0020-m68k-Disable-Atari-serial-console-support-if-modula.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,53 @@
+From a5377d75c7af3df155bbe04f06f401da84d72f24 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 20:54:08 +0100
+Subject: [PATCH] m68k: Disable Atari serial console support if modular
+
+If CONFIG_ATARI_SCC=m, I get the following warnings:
+
+| drivers/char/atari_scc.c: At top level:
+| drivers/char/atari_scc.c:1573: warning: data definition has no type or storage class
+| drivers/char/atari_scc.c:1573: warning: type defaults to 'int' in declaration of 'console_initcall'
+| drivers/char/atari_scc.c:1573: warning: parameter names (without types) in function declaration
+| drivers/char/atari_scc.c:1567: warning: 'atari_scc_console_init' defined but not used
+
+Apparently console_initcall() is not defined in the modular case.
+
+Disable serial console support if the driver is modular.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/char/atari_scc.c |    7 +++++--
+ 1 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/char/atari_scc.c b/drivers/char/atari_scc.c
+index f1ade4a..800193c 100644
+--- a/drivers/char/atari_scc.c
++++ b/drivers/char/atari_scc.c
+@@ -1401,10 +1401,12 @@ static int scc_break_ctl(struct tty_struct *tty, int break_state)
+ }
+ 
+ 
++#if defined(CONFIG_SERIAL_CONSOLE) && !defined(MODULE)
++
+ /*---------------------------------------------------------------------------
+  * Serial console stuff...
+  *--------------------------------------------------------------------------*/
+-#if 1
++
+ #define scc_delay() \
+ 	asm volatile ("tstb %0" : : "m" (*scc_del) : "cc")
+ 
+@@ -1571,7 +1573,8 @@ static int __init atari_scc_console_init(void)
+ }
+ 
+ console_initcall(atari_scc_console_init);
+-#endif
++
++#endif /* CONFIG_SERIAL_CONSOLE && !MODULE */
+ 
+ /***************************** End of Functions *********************/
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0021-m68k-Atari-SCC-support-for-ST.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0021-m68k-Atari-SCC-support-for-ST.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,45 @@
+From 52938348287a135a907260077b008edf9f1c7623 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Mon, 29 Dec 2008 16:48:41 +0100
+Subject: [PATCH] m68k: Atari SCC support for ST
+
+Enable support for Atari ST, and fix 2 obvious typos in the ST support code.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/char/atari_scc.c |    5 +++--
+ 1 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/char/atari_scc.c b/drivers/char/atari_scc.c
+index 800193c..e407aa8 100644
+--- a/drivers/char/atari_scc.c
++++ b/drivers/char/atari_scc.c
+@@ -51,6 +51,7 @@
+ 
+ #define CONFIG_TT_SCC     1
+ #define CONFIG_FALCON_SCC 1
++#define CONFIG_ST_SCC     1
+ 
+ #define CHANNEL_A	0
+ #define CHANNEL_B	1
+@@ -475,7 +476,7 @@ static int atari_st_scc_init(void)
+ 	request_irq(IRQ_SCCA_STAT, scc_stat_int, IRQ_TYPE_PRIO,
+ 		    "SCC-A status", port);
+ 	request_irq(IRQ_SCCA_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-A RX", port);
+-	request_irq(SCCA_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
++	request_irq(IRQ_SCCA_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
+ 		    "SCC-A special cond", port);
+ 	{
+ 		SCC_ACCESS_INIT(port);
+@@ -493,7 +494,7 @@ static int atari_st_scc_init(void)
+ 		/* disable interrupts for this channel */
+ 		SCCwrite(INT_AND_DMA_REG, 0);
+ 		/* Set the interrupt vector */
+-		SCCwrite(INT_VECTOR_REG, BVME_IRQ_SCC_BASE);
++		SCCwrite(INT_VECTOR_REG, 0x60);
+ 		/* Interrupt parameters: vector includes status, status low */
+ 		SCCwrite(MASTER_INT_CTRL, MIC_VEC_INCL_STAT);
+ 		SCCmod(MASTER_INT_CTRL, 0xff, MIC_MASTER_INT_ENAB);
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0022-m68k-atari_scc-kill-warn_unused_result-warnings.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0022-m68k-atari_scc-kill-warn_unused_result-warnings.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,281 @@
+From f37eaf7c68797f1e2ed9029313aeabb310400163 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 30 Dec 2008 14:06:05 +0100
+Subject: [PATCH] m68k: atari_scc - kill warn_unused_result warnings
+
+warning: ignoring return value of 'request_irq', declared with attribute
+warn_unused_result
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/char/atari_scc.c |  177 +++++++++++++++++++++++++++++++++-------------
+ 1 files changed, 128 insertions(+), 49 deletions(-)
+
+diff --git a/drivers/char/atari_scc.c b/drivers/char/atari_scc.c
+index e407aa8..5dc59ff 100644
+--- a/drivers/char/atari_scc.c
++++ b/drivers/char/atari_scc.c
+@@ -276,10 +276,99 @@ static void scc_init_portstructs(void)
+ }
+ 
+ 
++static int atari_scc_a_request_irqs(struct scc_port *port)
++{
++	int error;
++
++	error = request_irq(IRQ_SCCA_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-A TX",
++			    port);
++	if (error)
++		goto fail;
++
++	error = request_irq(IRQ_SCCA_STAT, scc_stat_int, IRQ_TYPE_PRIO,
++			    "SCC-A status", port);
++	if (error)
++		goto fail_free_a_tx;
++
++	error = request_irq(IRQ_SCCA_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-A RX",
++			    port);
++	if (error)
++		goto fail_free_a_stat;
++
++	error = request_irq(IRQ_SCCA_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
++			    "SCC-A special cond", port);
++	if (error)
++		goto fail_free_a_rx;
++
++	return 0;
++
++fail_free_a_rx:
++	free_irq(IRQ_SCCA_RX, port);
++fail_free_a_stat:
++	free_irq(IRQ_SCCA_STAT, port);
++fail_free_a_tx:
++	free_irq(IRQ_SCCA_TX, port);
++fail:
++	return error;
++}
++
++static void atari_scc_a_free_irqs(struct scc_port *port)
++{
++	free_irq(IRQ_SCCA_TX, port);
++	free_irq(IRQ_SCCA_STAT, port);
++	free_irq(IRQ_SCCA_RX, port);
++	free_irq(IRQ_SCCA_SPCOND, port);
++}
++
++static int atari_scc_b_request_irqs(struct scc_port *port)
++{
++	int error;
++
++	error = request_irq(IRQ_SCCB_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-B TX",
++			    port);
++	if (error)
++		goto fail;
++
++	error = request_irq(IRQ_SCCB_STAT, scc_stat_int, IRQ_TYPE_PRIO,
++			    "SCC-B status", port);
++	if (error)
++		goto fail_free_b_tx;
++
++	error = request_irq(IRQ_SCCB_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-B RX",
++			    port);
++	if (error)
++		goto fail_free_b_stat;
++
++	error = request_irq(IRQ_SCCB_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
++			    "SCC-B special cond", port);
++	if (error)
++		goto fail_free_b_rx;
++
++	return 0;
++
++fail_free_b_rx:
++	free_irq(IRQ_SCCB_RX, port);
++fail_free_b_stat:
++	free_irq(IRQ_SCCB_STAT, port);
++fail_free_b_tx:
++	free_irq(IRQ_SCCB_TX, port);
++fail:
++	return error;
++}
++
++static void atari_scc_b_free_irqs(struct scc_port *port)
++{
++	free_irq(IRQ_SCCB_TX, port);
++	free_irq(IRQ_SCCB_STAT, port);
++	free_irq(IRQ_SCCB_RX, port);
++	free_irq(IRQ_SCCB_SPCOND, port);
++}
++
+ #ifdef CONFIG_TT_SCC
+ static int atari_tt_scc_init(void)
+ {
+ 	struct scc_port *port;
++	int error;
+ 
+ 	pr_info("SCC: Atari TT Serial Driver\n");
+ 	/* FIXME channel A may be switchable between modem and LAN port */
+@@ -294,12 +383,10 @@ static int atari_tt_scc_init(void)
+ 	port->port_a = &scc_ports[0];
+ 	port->port_b = &scc_ports[1];
+ 	pr_debug("SCC: request channel A irqs, port = %p\n", port);
+-	request_irq(IRQ_SCCA_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-A TX", port);
+-	request_irq(IRQ_SCCA_STAT, scc_stat_int, IRQ_TYPE_PRIO,
+-		    "SCC-A status", port);
+-	request_irq(IRQ_SCCA_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-A RX", port);
+-	request_irq(IRQ_SCCA_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
+-		    "SCC-A special cond", port);
++	error = atari_scc_a_request_irqs(port);
++	if (error)
++		return error;
++
+ 	{
+ 		SCC_ACCESS_INIT(port);
+ 		pr_debug("SCC: read SCC status\n");
+@@ -335,14 +422,12 @@ static int atari_tt_scc_init(void)
+ 		port->port_a = &scc_ports[0];
+ 		port->port_b = &scc_ports[1];
+ 		pr_debug("SCC: request channel B irqs, port = %p\n", port);
+-		request_irq(IRQ_SCCB_TX, scc_tx_int, IRQ_TYPE_PRIO,
+-			    "SCC-B TX", port);
+-		request_irq(IRQ_SCCB_STAT, scc_stat_int, IRQ_TYPE_PRIO,
+-			    "SCC-B status", port);
+-		request_irq(IRQ_SCCB_RX, scc_rx_int, IRQ_TYPE_PRIO,
+-			    "SCC-B RX", port);
+-		request_irq(IRQ_SCCB_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
+-			    "SCC-B special cond", port);
++		error = atari_scc_b_request_irqs(port);
++		if (error) {
++			atari_scc_a_free_irqs(port);
++			return error;
++		}
++
+ 		{
+ 			SCC_ACCESS_INIT(port);
+ 
+@@ -351,8 +436,13 @@ static int atari_tt_scc_init(void)
+ 		}
+ /* not implemented yet */
+ #if 0
+-		request_irq(IRQ_TT_MFP_RI, scc_ri_int, IRQ_TYPE_SLOW,
+-			    "TT-MFP ring indicator (modem 2)", port);
++		error = request_irq(IRQ_TT_MFP_RI, scc_ri_int, IRQ_TYPE_SLOW,
++				    "TT-MFP ring indicator (modem 2)", port);
++		if (error) {
++			atari_scc_b_free_irqs(port);
++			atari_scc_a_free_irqs(port);
++			return error;
++		}
+ #endif
+ 
+ 	}
+@@ -381,6 +471,7 @@ static int atari_tt_scc_init(void)
+ static int atari_falcon_scc_init(void)
+ {
+ 	struct scc_port *port;
++	int error;
+ 
+ 	pr_info("SCC: Atari Falcon Serial Driver\n");
+ 	if (atari_SCC_init_done)
+@@ -393,12 +484,10 @@ static int atari_falcon_scc_init(void)
+ 	port->datap = port->ctrlp + 2;
+ 	port->port_a = &scc_ports[0];
+ 	port->port_b = &scc_ports[1];
+-	request_irq(IRQ_SCCA_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-A TX", port);
+-	request_irq(IRQ_SCCA_STAT, scc_stat_int, IRQ_TYPE_PRIO,
+-		    "SCC-A status", port);
+-	request_irq(IRQ_SCCA_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-A RX", port);
+-	request_irq(IRQ_SCCA_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
+-		    "SCC-A special cond", port);
++	error = atari_scc_a_request_irqs(port);
++	if (error)
++		return error;
++
+ 	{
+ 		SCC_ACCESS_INIT(port);
+ 
+@@ -429,12 +518,11 @@ static int atari_falcon_scc_init(void)
+ 	port->datap = port->ctrlp + 2;
+ 	port->port_a = &scc_ports[0];
+ 	port->port_b = &scc_ports[1];
+-	request_irq(IRQ_SCCB_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-B TX", port);
+-	request_irq(IRQ_SCCB_STAT, scc_stat_int, IRQ_TYPE_PRIO,
+-		    "SCC-B status", port);
+-	request_irq(IRQ_SCCB_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-B RX", port);
+-	request_irq(IRQ_SCCB_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
+-		    "SCC-B special cond", port);
++	error = atari_scc_b_request_irqs(port);
++	if (error) {
++		atari_scc_a_free_irqs(port);
++		return error;
++	}
+ 
+ 	{
+ 		SCC_ACCESS_INIT(port);	/* Either channel will do */
+@@ -461,6 +549,7 @@ static int atari_st_scc_init(void)
+ {
+ 	struct scc_port *port;
+ 	int escc = ATARIHW_PRESENT(ST_ESCC);
++	int error;
+ 
+ 	pr_info("SCC: Atari MegaST/E Serial Driver\n");
+ 	/* FIXME: ports reversed logic */
+@@ -472,12 +561,10 @@ static int atari_st_scc_init(void)
+ 	port->datap = port->ctrlp + 4;
+ 	port->port_a = &scc_ports[1];
+ 	port->port_b = &scc_ports[0];
+-	request_irq(IRQ_SCCA_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-A TX", port);
+-	request_irq(IRQ_SCCA_STAT, scc_stat_int, IRQ_TYPE_PRIO,
+-		    "SCC-A status", port);
+-	request_irq(IRQ_SCCA_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-A RX", port);
+-	request_irq(IRQ_SCCA_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
+-		    "SCC-A special cond", port);
++	error = atari_scc_a_request_irqs(port);
++	if (error)
++		return error;
++
+ 	{
+ 		SCC_ACCESS_INIT(port);
+ 
+@@ -508,12 +595,11 @@ static int atari_st_scc_init(void)
+ 	port->datap = port->ctrlp + 4;
+ 	port->port_a = &scc_ports[0];
+ 	port->port_b = &scc_ports[1];
+-	request_irq(IRQ_SCCB_TX, scc_tx_int, IRQ_TYPE_PRIO, "SCC-B TX", port);
+-	request_irq(IRQ_SCCB_STAT, scc_stat_int, IRQ_TYPE_PRIO,
+-		    "SCC-B status", port);
+-	request_irq(IRQ_SCCB_RX, scc_rx_int, IRQ_TYPE_PRIO, "SCC-B RX", port);
+-	request_irq(IRQ_SCCB_SPCOND, scc_spcond_int, IRQ_TYPE_PRIO,
+-		    "SCC-B special cond", port);
++	error = atari_scc_b_request_irqs(port);
++	if (error) {
++		atari_scc_a_free_irqs(port);
++		return error;
++	}
+ 
+ 	{
+ 		SCC_ACCESS_INIT(port);	/* Either channel will do */
+@@ -571,18 +657,11 @@ void atari_scc_cleanup(void)
+ 	tty_unregister_driver(scc_driver);
+ 	port = &scc_ports[0];
+ 	pr_debug("SCC: free channel A irqs, port = %p\n", port);
+-	free_irq(IRQ_SCCA_TX, port);
+-	free_irq(IRQ_SCCA_STAT, port);
+-	free_irq(IRQ_SCCA_RX, port);
+-	free_irq(IRQ_SCCA_SPCOND, port);
++	atari_scc_a_free_irqs(port);
+ 
+ 	port = &scc_ports[1];
+ 	pr_debug("SCC: free channel A irqs, port = %p\n", port);
+-	free_irq(IRQ_SCCB_TX, port);
+-	free_irq(IRQ_SCCB_STAT, port);
+-	free_irq(IRQ_SCCB_RX, port);
+-	free_irq(IRQ_SCCB_SPCOND, port);
+-
++	atari_scc_b_free_irqs(port);
+ }
+ 
+ module_init(atari_scc_init);
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0023-m68k-atari_scc-kill-fake-config-variables.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0023-m68k-atari_scc-kill-fake-config-variables.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,111 @@
+From c8e847cb71ec44e7e8e5d1a164c77324efb3d1a2 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 30 Dec 2008 14:35:46 +0100
+Subject: [PATCH] m68k: atari_scc - kill fake config variables
+
+Rename CONFIG_{TT,FALCON,ST}_SCC to SUPPORT_{TT,FALCON,ST}_SCC and reduce ifdef
+clutter
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/char/atari_scc.c |   39 ++++++++++++++++++++++++---------------
+ 1 files changed, 24 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/char/atari_scc.c b/drivers/char/atari_scc.c
+index 5dc59ff..fefff96 100644
+--- a/drivers/char/atari_scc.c
++++ b/drivers/char/atari_scc.c
+@@ -49,9 +49,9 @@
+ 
+ #include "scc.h"
+ 
+-#define CONFIG_TT_SCC     1
+-#define CONFIG_FALCON_SCC 1
+-#define CONFIG_ST_SCC     1
++#define SUPPORT_TT_SCC     1
++#define SUPPORT_FALCON_SCC 1
++#define SUPPORT_ST_SCC     1
+ 
+ #define CHANNEL_A	0
+ #define CHANNEL_B	1
+@@ -364,7 +364,7 @@ static void atari_scc_b_free_irqs(struct scc_port *port)
+ 	free_irq(IRQ_SCCB_SPCOND, port);
+ }
+ 
+-#ifdef CONFIG_TT_SCC
++#ifdef SUPPORT_TT_SCC
+ static int atari_tt_scc_init(void)
+ {
+ 	struct scc_port *port;
+@@ -464,10 +464,15 @@ static int atari_tt_scc_init(void)
+ 
+ 	return 0;
+ }
+-#endif
++#else /* !SUPPORT_TT_SCC */
++static inline int atari_tt_scc_init(void)
++{
++	return -ENODEV;
++}
++#endif /* !SUPPORT_TT_SCC */
+ 
+ 
+-#ifdef CONFIG_FALCON_SCC
++#ifdef SUPPORT_FALCON_SCC
+ static int atari_falcon_scc_init(void)
+ {
+ 	struct scc_port *port;
+@@ -541,10 +546,15 @@ static int atari_falcon_scc_init(void)
+ 
+ 	return 0;
+ }
+-#endif
++#else /* !SUPPORT_FALCON_SCC */
++static inline int atari_falcon_scc_init(void)
++{
++	return -ENODEV;
++}
++#endif /* !SUPPORT_FALCON_SCC */
+ 
+ 
+-#ifdef CONFIG_ST_SCC
++#ifdef SUPPORT_ST_SCC
+ static int atari_st_scc_init(void)
+ {
+ 	struct scc_port *port;
+@@ -618,7 +628,12 @@ static int atari_st_scc_init(void)
+ 
+ 	return 0;
+ }
+-#endif
++#else /* !SUPPORT_ST_SCC */
++static inline int atari_st_scc_init(void)
++{
++	return -ENODEV;
++}
++#endif /* !SUPPORT_ST_SCC */
+ 
+ 
+ int atari_scc_init(void)
+@@ -635,18 +650,12 @@ int atari_scc_init(void)
+ 
+ 	scc_del = &mfp.par_dt_reg;
+ 
+-#ifdef CONFIG_TT_SCC
+ 	if (MACH_IS_TT)
+ 		res = atari_tt_scc_init();
+-#endif
+-#ifdef CONFIG_FALCON_SCC
+ 	if (MACH_IS_FALCON)
+ 		res = atari_falcon_scc_init();
+-#endif
+-#ifdef CONFIG_ST_SCC
+ 	if (MACH_IS_ST)
+ 		res = atari_st_scc_init();
+-#endif
+ 	return res;
+ }
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0024-Revert-msdos-fs-remove-unsettable-atari-option.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0024-Revert-msdos-fs-remove-unsettable-atari-option.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,80 @@
+From ee46c99f8440f34e394f4d0fc5992fb53fd4ac7d Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 20:59:13 +0100
+Subject: [PATCH] Revert "msdos fs: remove unsettable atari option"
+
+Revert commit 7557bc66be629d19a402e752673708bfbb8b5e86 ("msdos fs: remove
+unsettable atari option")
+---
+ fs/fat/fat.h         |    1 +
+ fs/fat/namei_msdos.c |   18 ++++++++++++------
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/fs/fat/fat.h b/fs/fat/fat.h
+index 7db0979..9687897 100644
+--- a/fs/fat/fat.h
++++ b/fs/fat/fat.h
+@@ -40,6 +40,7 @@ struct fat_mount_options {
+ 		 utf8:1,	  /* Use of UTF-8 character set (Default) */
+ 		 unicode_xlate:1, /* create escape sequences for unhandled Unicode */
+ 		 numtail:1,       /* Does first alias have a numeric '~1' type tail? */
++		 atari:1,         /* Use Atari GEMDOS variation of MS-DOS fs */
+ 		 flush:1,	  /* write things quickly */
+ 		 nocase:1,	  /* Does this need case conversion? 0=need case conversion*/
+ 		 usefree:1,	  /* Use free_clusters for FAT32 */
+diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
+index bbc94ae..f28b55e 100644
+--- a/fs/fat/namei_msdos.c
++++ b/fs/fat/namei_msdos.c
+@@ -13,7 +13,12 @@
+ 
+ /* Characters that are undesirable in an MS-DOS file name */
+ static unsigned char bad_chars[] = "*?<>|\"";
+-static unsigned char bad_if_strict[] = "+=,; ";
++static unsigned char bad_if_strict_pc[] = "+=,; ";
++/* GEMDOS is less restrictive */
++static unsigned char bad_if_strict_atari[] = " ";
++
++#define bad_if_strict(opts) \
++	((opts)->atari ? bad_if_strict_atari : bad_if_strict_pc)
+ 
+ /***** Formats an MS-DOS file name. Rejects invalid names. */
+ static int msdos_format_name(const unsigned char *name, int len,
+@@ -34,20 +39,21 @@ static int msdos_format_name(const unsigned char *name, int len,
+ 			/* Get rid of dot - test for it elsewhere */
+ 			name++;
+ 			len--;
+-		} else
++		} else if (!opts->atari)
+ 			return -EINVAL;
+ 	}
+ 	/*
+-	 * disallow names that _really_ start with a dot
++	 * disallow names that _really_ start with a dot for MS-DOS,
++	 * GEMDOS does not care
+ 	 */
+-	space = 1;
++	space = !opts->atari;
+ 	c = 0;
+ 	for (walk = res; len && walk - res < 8; walk++) {
+ 		c = *name++;
+ 		len--;
+ 		if (opts->name_check != 'r' && strchr(bad_chars, c))
+ 			return -EINVAL;
+-		if (opts->name_check == 's' && strchr(bad_if_strict, c))
++		if (opts->name_check == 's' && strchr(bad_if_strict(opts), c))
+ 			return -EINVAL;
+ 		if (c >= 'A' && c <= 'Z' && opts->name_check == 's')
+ 			return -EINVAL;
+@@ -87,7 +93,7 @@ static int msdos_format_name(const unsigned char *name, int len,
+ 			if (opts->name_check != 'r' && strchr(bad_chars, c))
+ 				return -EINVAL;
+ 			if (opts->name_check == 's' &&
+-			    strchr(bad_if_strict, c))
++			    strchr(bad_if_strict(opts), c))
+ 				return -EINVAL;
+ 			if (c < ' ' || c == ':' || c == '\\')
+ 				return -EINVAL;
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0025-Atari-FAT-updates.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0025-Atari-FAT-updates.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,105 @@
+From 24866e4bd232d7dc8ab08fc5d5545dda20002483 Mon Sep 17 00:00:00 2001
+From: Linux/m68k legacy <xxx at linux-m68k.org>
+Date: Tue, 18 Nov 2008 20:59:14 +0100
+Subject: [PATCH] Atari FAT updates
+
+Add support for the Atari-variant of the FAT filesystem
+---
+ fs/fat/inode.c |   46 +++++++++++++++++++++++++++++++++++++++++++---
+ 1 files changed, 43 insertions(+), 3 deletions(-)
+
+diff --git a/fs/fat/inode.c b/fs/fat/inode.c
+index 76b7961..ccb5c6e 100644
+--- a/fs/fat/inode.c
++++ b/fs/fat/inode.c
+@@ -27,6 +27,7 @@
+ #include <linux/writeback.h>
+ #include <linux/log2.h>
+ #include <linux/hash.h>
++#include <linux/major.h>
+ #include <asm/unaligned.h>
+ #include "fat.h"
+ 
+@@ -866,7 +867,7 @@ enum {
+ 	Opt_check_n, Opt_check_r, Opt_check_s, Opt_uid, Opt_gid,
+ 	Opt_umask, Opt_dmask, Opt_fmask, Opt_allow_utime, Opt_codepage,
+ 	Opt_usefree, Opt_nocase, Opt_quiet, Opt_showexec, Opt_debug,
+-	Opt_immutable, Opt_dots, Opt_nodots,
++	Opt_immutable, Opt_dots, Opt_nodots, Opt_atari_no, Opt_atari_yes,
+ 	Opt_charset, Opt_shortname_lower, Opt_shortname_win95,
+ 	Opt_shortname_winnt, Opt_shortname_mixed, Opt_utf8_no, Opt_utf8_yes,
+ 	Opt_uni_xl_no, Opt_uni_xl_yes, Opt_nonumtail_no, Opt_nonumtail_yes,
+@@ -899,6 +900,9 @@ static const match_table_t fat_tokens = {
+ 	{Opt_err_cont, "errors=continue"},
+ 	{Opt_err_panic, "errors=panic"},
+ 	{Opt_err_ro, "errors=remount-ro"},
++	{Opt_atari_yes, "atari=yes"},
++	{Opt_atari_yes, "atari"},
++	{Opt_atari_no, "atari=no"},
+ 	{Opt_obsolate, "conv=binary"},
+ 	{Opt_obsolate, "conv=text"},
+ 	{Opt_obsolate, "conv=auto"},
+@@ -980,6 +984,13 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
+ 	opts->usefree = opts->nocase = 0;
+ 	opts->tz_utc = 0;
+ 	opts->errors = FAT_ERRORS_RO;
++	opts->atari = 0;
++
++#ifdef CONFIG_ATARI
++	if (MACH_IS_ATARI)
++	/* make Atari GEMDOS format the default if machine is an Atari */
++		opts->atari = 1;
++#endif
+ 	*debug = 0;
+ 
+ 	if (!options)
+@@ -1031,6 +1042,12 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
+ 		case Opt_immutable:
+ 			opts->sys_immutable = 1;
+ 			break;
++		case Opt_atari_yes:
++			opts->atari = 1;
++			break;
++		case Opt_atari_no:
++			opts->atari = 0;
++			break;
+ 		case Opt_uid:
+ 			if (match_int(&args[0], &option))
+ 				return 0;
+@@ -1396,8 +1413,31 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
+ 
+ 	total_clusters = (total_sectors - sbi->data_start) / sbi->sec_per_clus;
+ 
+-	if (sbi->fat_bits != 32)
+-		sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
++	if (!sbi->options.atari) {
++		if (sbi->fat_bits != 32)
++			sbi->fat_bits = (total_clusters > MAX_FAT12) ? 16 : 12;
++	} else {
++		int sectors;
++		/* Atari GEMDOS partitions always have 16-bit fat */
++		if (sbi->fat_bits != 32)
++			sbi->fat_bits = 16;
++		/* If more clusters than fat entries in 16-bit fat, we assume
++		 * it's a real MSDOS partition with 12-bit fat.
++		 */
++		if (sbi->fat_bits != 32 && total_clusters+2 > sbi->
++			fat_length*SECTOR_SIZE*8/sbi->fat_bits)
++			sbi->fat_bits = 12;
++		/* if it's a floppy disk --> 12bit fat */
++		if (sbi->fat_bits != 32 && MAJOR(sb->s_dev) == FLOPPY_MAJOR)
++			sbi->fat_bits = 12;
++		/* if it's a ramdisk or loopback device and has one of the usual
++		 * floppy sizes -> 12bit FAT  */
++		sectors = total_sectors + sbi->data_start;
++		if (sbi->fat_bits != 32 && (MAJOR(sb->s_dev) == RAMDISK_MAJOR ||
++			 MAJOR(sb->s_dev) == LOOP_MAJOR) &&
++			(sectors == 720 || sectors == 1440 || sectors == 2880))
++			sbi->fat_bits = 12;
++	}
+ 
+ 	/* check that FAT table does not overflow */
+ 	fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0026-Add-Amiga-Zorro-bus-modalias-support.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0026-Add-Amiga-Zorro-bus-modalias-support.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,266 @@
+From 1c0b783336156414b46d3c7f1244862773a52488 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 21:13:53 +0100
+Subject: [PATCH] Add Amiga Zorro bus modalias support
+
+Add Amiga Zorro bus modalias and uevent support
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/net/a2065.c             |    1 +
+ drivers/net/ariadne.c           |    1 +
+ drivers/net/hydra.c             |    1 +
+ drivers/net/zorro8390.c         |    1 +
+ drivers/scsi/zorro7xx.c         |    1 +
+ drivers/video/cirrusfb.c        |    1 +
+ drivers/video/fm2fb.c           |    1 +
+ drivers/zorro/zorro-driver.c    |   24 ++++++++++++++++++++++++
+ drivers/zorro/zorro-sysfs.c     |   11 +++++++++++
+ include/linux/mod_devicetable.h |    9 +++++++++
+ include/linux/zorro.h           |   13 +------------
+ scripts/mod/file2alias.c        |   14 ++++++++++++++
+ 12 files changed, 66 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
+index b7ec036..f77ae09 100644
+--- a/drivers/net/a2065.c
++++ b/drivers/net/a2065.c
+@@ -677,6 +677,7 @@ static struct zorro_device_id a2065_zorro_tbl[] __devinitdata = {
+ 	{ ZORRO_PROD_AMERISTAR_A2065 },
+ 	{ 0 }
+ };
++MODULE_DEVICE_TABLE(zorro, a2065_zorro_tbl);
+ 
+ static struct zorro_driver a2065_driver = {
+ 	.name		= "a2065",
+diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c
+index c35af3e..894159a 100644
+--- a/drivers/net/ariadne.c
++++ b/drivers/net/ariadne.c
+@@ -148,6 +148,7 @@ static struct zorro_device_id ariadne_zorro_tbl[] __devinitdata = {
+     { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE },
+     { 0 }
+ };
++MODULE_DEVICE_TABLE(zorro, ariadne_zorro_tbl);
+ 
+ static struct zorro_driver ariadne_driver = {
+     .name	= "ariadne",
+diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c
+index d496b6f..8a6d070 100644
+--- a/drivers/net/hydra.c
++++ b/drivers/net/hydra.c
+@@ -72,6 +72,7 @@ static struct zorro_device_id hydra_zorro_tbl[] __devinitdata = {
+     { ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET },
+     { 0 }
+ };
++MODULE_DEVICE_TABLE(zorro, hydra_zorro_tbl);
+ 
+ static struct zorro_driver hydra_driver = {
+     .name	= "hydra",
+diff --git a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c
+index 81c753a..9548cbb 100644
+--- a/drivers/net/zorro8390.c
++++ b/drivers/net/zorro8390.c
+@@ -102,6 +102,7 @@ static struct zorro_device_id zorro8390_zorro_tbl[] __devinitdata = {
+     { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, },
+     { 0 }
+ };
++MODULE_DEVICE_TABLE(zorro, zorro8390_zorro_tbl);
+ 
+ static struct zorro_driver zorro8390_driver = {
+     .name	= "zorro8390",
+diff --git a/drivers/scsi/zorro7xx.c b/drivers/scsi/zorro7xx.c
+index 64d40a2..b416fa4 100644
+--- a/drivers/scsi/zorro7xx.c
++++ b/drivers/scsi/zorro7xx.c
+@@ -68,6 +68,7 @@ static struct zorro_device_id zorro7xx_zorro_tbl[] __devinitdata = {
+ 	},
+ 	{ 0 }
+ };
++MODULE_DEVICE_TABLE(zorro, zorro7xx_zorro_tbl);
+ 
+ static int __devinit zorro7xx_init_one(struct zorro_dev *z,
+ 				       const struct zorro_device_id *ent)
+diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
+index 4c2bf92..dc5d201 100644
+--- a/drivers/video/cirrusfb.c
++++ b/drivers/video/cirrusfb.c
+@@ -300,6 +300,7 @@ static const struct zorro_device_id cirrusfb_zorro_table[] = {
+ 	},
+ 	{ 0 }
+ };
++MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table);
+ 
+ static const struct {
+ 	zorro_id id2;
+diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
+index 6c91c61..1b0feb8 100644
+--- a/drivers/video/fm2fb.c
++++ b/drivers/video/fm2fb.c
+@@ -219,6 +219,7 @@ static struct zorro_device_id fm2fb_devices[] __devinitdata = {
+ 	{ ZORRO_PROD_HELFRICH_RAINBOW_II },
+ 	{ 0 }
+ };
++MODULE_DEVICE_TABLE(zorro, fm2fb_devices);
+ 
+ static struct zorro_driver fm2fb_driver = {
+ 	.name		= "fm2fb",
+diff --git a/drivers/zorro/zorro-driver.c b/drivers/zorro/zorro-driver.c
+index e6c4390..aeb0615 100644
+--- a/drivers/zorro/zorro-driver.c
++++ b/drivers/zorro/zorro-driver.c
+@@ -137,10 +137,34 @@ static int zorro_bus_match(struct device *dev, struct device_driver *drv)
+ 	return 0;
+ }
+ 
++static int zorro_uevent(struct device *dev, struct kobj_uevent_env *env)
++{
++#ifdef CONFIG_HOTPLUG
++	struct zorro_dev *z;
++
++	if (!dev)
++		return -ENODEV;
++
++	z = to_zorro_dev(dev);
++	if (!z)
++		return -ENODEV;
++
++	if (add_uevent_var(env, "ZORRO_ID=%08X", z->id) ||
++	    add_uevent_var(env, "ZORRO_SLOT_NAME=%s", z->dev.bus_id) ||
++	    add_uevent_var(env, "ZORRO_SLOT_ADDR=%04X", z->slotaddr) ||
++	    add_uevent_var(env, "MODALIAS=" ZORRO_DEVICE_MODALIAS_FMT, z->id))
++		return -ENOMEM;
++
++	return 0;
++#else /* !CONFIG_HOTPLUG */
++	return -ENODEV;
++#endif /* !CONFIG_HOTPLUG */
++}
+ 
+ struct bus_type zorro_bus_type = {
+ 	.name	= "zorro",
+ 	.match	= zorro_bus_match,
++	.uevent	= zorro_uevent,
+ 	.probe	= zorro_device_probe,
+ 	.remove	= zorro_device_remove,
+ };
+diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c
+index 1d2a772..eb924e0 100644
+--- a/drivers/zorro/zorro-sysfs.c
++++ b/drivers/zorro/zorro-sysfs.c
+@@ -77,6 +77,16 @@ static struct bin_attribute zorro_config_attr = {
+ 	.read = zorro_read_config,
+ };
+ 
++static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
++			     char *buf)
++{
++	struct zorro_dev *z = to_zorro_dev(dev);
++
++	return sprintf(buf, ZORRO_DEVICE_MODALIAS_FMT "\n", z->id);
++}
++
++static DEVICE_ATTR(modalias, S_IRUGO, modalias_show, NULL);
++
+ int zorro_create_sysfs_dev_files(struct zorro_dev *z)
+ {
+ 	struct device *dev = &z->dev;
+@@ -89,6 +99,7 @@ int zorro_create_sysfs_dev_files(struct zorro_dev *z)
+ 	    (error = device_create_file(dev, &dev_attr_slotaddr)) ||
+ 	    (error = device_create_file(dev, &dev_attr_slotsize)) ||
+ 	    (error = device_create_file(dev, &dev_attr_resource)) ||
++	    (error = device_create_file(dev, &dev_attr_modalias)) ||
+ 	    (error = sysfs_create_bin_file(&dev->kobj, &zorro_config_attr)))
+ 		return error;
+ 
+diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
+index f58e9d8..56fde43 100644
+--- a/include/linux/mod_devicetable.h
++++ b/include/linux/mod_devicetable.h
+@@ -474,4 +474,13 @@ struct platform_device_id {
+ 			__attribute__((aligned(sizeof(kernel_ulong_t))));
+ };
+ 
++struct zorro_device_id {
++	__u32 id;			/* Device ID or ZORRO_WILDCARD */
++	kernel_ulong_t driver_data;	/* Data private to the driver */
++};
++
++#define ZORRO_WILDCARD			(0xffffffff)	/* not official */
++
++#define ZORRO_DEVICE_MODALIAS_FMT	"zorro:i%08X"
++
+ #endif /* LINUX_MOD_DEVICETABLE_H */
+diff --git a/include/linux/zorro.h b/include/linux/zorro.h
+index 913bfc2..908db1b 100644
+--- a/include/linux/zorro.h
++++ b/include/linux/zorro.h
+@@ -38,8 +38,6 @@
+ typedef __u32 zorro_id;
+ 
+ 
+-#define ZORRO_WILDCARD		(0xffffffff)	/* not official */
+-
+ /* Include the ID list */
+ #include <linux/zorro_ids.h>
+ 
+@@ -116,6 +114,7 @@ struct ConfigDev {
+ 
+ #include <linux/init.h>
+ #include <linux/ioport.h>
++#include <linux/mod_devicetable.h>
+ 
+ #include <asm/zorro.h>
+ 
+@@ -155,16 +154,6 @@ extern struct bus_type zorro_bus_type;
+ 
+ 
+     /*
+-     *  Zorro device IDs
+-     */
+-
+-struct zorro_device_id {
+-	zorro_id id;			/* Device ID or ZORRO_WILDCARD */
+-	unsigned long driver_data;	/* Data private to the driver */
+-};
+-
+-
+-    /*
+      *  Zorro device drivers
+      */
+ 
+diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
+index 62a9025..e9186c9 100644
+--- a/scripts/mod/file2alias.c
++++ b/scripts/mod/file2alias.c
+@@ -727,6 +727,16 @@ static int do_platform_entry(const char *filename,
+ 	return 1;
+ }
+ 
++/* Looks like: zorro:iN. */
++static int do_zorro_entry(const char *filename, struct zorro_device_id *id,
++			  char *alias)
++{
++	id->id = TO_NATIVE(id->id);
++	strcpy(alias, "zorro:");
++	ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id);
++	return 1;
++}
++
+ /* Ignore any prefix, eg. some architectures prepend _ */
+ static inline int sym_is(const char *symbol, const char *name)
+ {
+@@ -874,6 +884,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
+ 		do_table(symval, sym->st_size,
+ 			 sizeof(struct platform_device_id), "platform",
+ 			 do_platform_entry, mod);
++	else if (sym_is(symname, "__mod_zorro_device_table"))
++		do_table(symval, sym->st_size,
++			 sizeof(struct zorro_device_id), "zorro",
++			 do_zorro_entry, mod);
+ 	free(zeros);
+ }
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0027-m68k-Fix-debug-mem-on-Amiga.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0027-m68k-Fix-debug-mem-on-Amiga.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,100 @@
+From 76a76ad128719560f44b618b763de46bcd0f7316 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 21:25:15 +0100
+Subject: [PATCH] m68k: Fix debug=mem on Amiga
+
+`debug=mem' on Amiga has been broken for a while.
+early_param() processing is done very/too early, i.e. before
+amiga_hw_present.CHIP_RAM has been set in amiga_identify(), causing
+amiga_savekmsg_setup() not to find any Chip RAM.
+
+The quick hack below makes it work again by introducing an additional
+intermediate flag, but I don't like it.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+
+TODO: Suggestion from Roman Zippel <zippel at linux-m68k.org>:
+
+The alternative to pull some of the setup ahead of the early_param() call.
+It shouldn't be a big problem to move the call after the config calls, as
+these should only do a very basic setup, everything else should be done
+via init calls (e.g. amiga_init_sound() might be such a candidate).
+---
+ arch/m68k/amiga/config.c |   30 +++++++++++++++++++++---------
+ 1 files changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
+index 6c74751..dd349a1 100644
+--- a/arch/m68k/amiga/config.c
++++ b/arch/m68k/amiga/config.c
+@@ -106,6 +106,7 @@ static void amiga_reset(void);
+ extern void amiga_init_sound(void);
+ static void amiga_mem_console_write(struct console *co, const char *b,
+ 				    unsigned int count);
++static void __init amiga_savekmsg_init(void);
+ #ifdef CONFIG_HEARTBEAT
+ static void amiga_heartbeat(int on);
+ #endif
+@@ -116,6 +117,8 @@ static struct console amiga_console_driver = {
+ 	.index	= -1,
+ };
+ 
++static int __initdata amiga_enable_debug_mem;
++
+ 
+     /*
+      *  Motherboard Resources present in all Amiga models
+@@ -461,6 +464,9 @@ void __init config_amiga(void)
+ 	/* initialize chipram allocator */
+ 	amiga_chip_init();
+ 
++	if (amiga_enable_debug_mem && AMIGAHW_PRESENT(CHIP_RAM))
++		amiga_savekmsg_init();
++
+ 	/* our beloved beeper */
+ 	if (AMIGAHW_PRESENT(AMI_AUDIO))
+ 		amiga_init_sound();
+@@ -782,18 +788,10 @@ static void amiga_mem_console_write(struct console *co, const char *s,
+ 	}
+ }
+ 
+-static int __init amiga_savekmsg_setup(char *arg)
++static void __init amiga_savekmsg_init(void)
+ {
+ 	static struct resource debug_res = { .name = "Debug" };
+ 
+-	if (!MACH_IS_AMIGA || strcmp(arg, "mem"))
+-		goto done;
+-
+-	if (!AMIGAHW_PRESENT(CHIP_RAM)) {
+-		printk("Warning: no chipram present for debugging\n");
+-		goto done;
+-	}
+-
+ 	savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res);
+ 	savekmsg->magic1 = SAVEKMSG_MAGIC1;
+ 	savekmsg->magic2 = SAVEKMSG_MAGIC2;
+@@ -802,6 +800,20 @@ static int __init amiga_savekmsg_setup(char *arg)
+ 
+ 	amiga_console_driver.write = amiga_mem_console_write;
+ 	register_console(&amiga_console_driver);
++}
++
++static int __init amiga_savekmsg_setup(char *arg)
++{
++	if (!MACH_IS_AMIGA || strcmp(arg, "mem"))
++		goto done;
++
++	if (!AMIGAHW_PRESENT(CHIP_RAM)) {
++		printk("Warning: no chipram present for debugging\n");
++		amiga_enable_debug_mem = 1;
++		goto done;
++	}
++
++	amiga_savekmsg_init();
+ 
+ done:
+ 	return 0;
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0028-m68k-allow-all-kernel-traps-to-be-handled-via-except.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0028-m68k-allow-all-kernel-traps-to-be-handled-via-except.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,197 @@
+From 7880c4c6a87eb0c119543eacc6de4b3da8af1d6f Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <andreas at ubb.ca>
+Date: Tue, 18 Nov 2008 21:25:17 +0100
+Subject: [PATCH] m68k-allow-all-kernel-traps-to-be-handled-via-exception-fixups-all.diff
+
+Allow all kernel traps to be handled via exception fixups.
+
+Signed-off-by: Andreas Schwab <schwab at suse.de>
+
+--------------------
+
+From: Roman Zippel <zippel at linux-m68k.org>
+
+Add helper function handle_kernel_fault() in signal.c, so
+frame_extra_sizes can become static and to reduce code duplication.
+Use base_trap_init() to initialize vectors, so basic initialization is
+all in one place.
+Remove the VEC_TRACE check from trap_c, I can only guess it's left from
+an old kgdb patch, as right now it does nothing.
+
+Signed-off-by: Roman Zippel <zippel at linux-m68k.org>
+
+--------------------
+
+From: Andreas Schwab <andreas at ubb.ca>
+
+Reinstate VEC_TRACE check, needed for 68020/30.
+
+Signed-off-by: Andreas Schwab <schwab at suse.de>
+
+--------------------
+
+From: Roman Zippel <zippel at ubb.ca>
+
+no need to set TIF_DELAYED_TRACE
+
+Signed-off-by: Roman Zippel <zippel at linux-m68k.org>
+---
+ arch/m68k/include/asm/processor.h |    2 ++
+ arch/m68k/kernel/signal.c         |   24 +++++++++++++++++++++++-
+ arch/m68k/kernel/traps.c          |   20 ++++++++++++--------
+ arch/m68k/mm/fault.c              |   16 +---------------
+ 4 files changed, 38 insertions(+), 24 deletions(-)
+
+diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h
+index 74fd674..62cee63 100644
+--- a/arch/m68k/include/asm/processor.h
++++ b/arch/m68k/include/asm/processor.h
+@@ -167,4 +167,6 @@ unsigned long get_wchan(struct task_struct *p);
+ 
+ #define cpu_relax()	barrier()
+ 
++extern int handle_kernel_fault(struct pt_regs *regs);
++
+ #endif
+diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
+index de2d05d..842bfd9 100644
+--- a/arch/m68k/kernel/signal.c
++++ b/arch/m68k/kernel/signal.c
+@@ -42,6 +42,7 @@
+ #include <linux/personality.h>
+ #include <linux/tty.h>
+ #include <linux/binfmts.h>
++#include <linux/module.h>
+ 
+ #include <asm/setup.h>
+ #include <asm/uaccess.h>
+@@ -53,7 +54,7 @@
+ 
+ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+ 
+-const int frame_extra_sizes[16] = {
++static const int frame_extra_sizes[16] = {
+   [1]	= -1, /* sizeof(((struct frame *)0)->un.fmt1), */
+   [2]	= sizeof(((struct frame *)0)->un.fmt2),
+   [3]	= sizeof(((struct frame *)0)->un.fmt3),
+@@ -71,6 +72,27 @@ const int frame_extra_sizes[16] = {
+   [15]	= -1, /* sizeof(((struct frame *)0)->un.fmtf), */
+ };
+ 
++int handle_kernel_fault(struct pt_regs *regs)
++{
++	const struct exception_table_entry *fixup;
++	struct pt_regs *tregs;
++
++	/* Are we prepared to handle this kernel fault? */
++	fixup = search_exception_tables(regs->pc);
++	if (!fixup)
++		return 0;
++
++	/* Create a new four word stack frame, discarding the old one. */
++	regs->stkadj = frame_extra_sizes[regs->format];
++	tregs =	(struct pt_regs *)((long)regs + regs->stkadj);
++	tregs->vector = regs->vector;
++	tregs->format = 0;
++	tregs->pc = fixup->fixup;
++	tregs->sr = regs->sr;
++
++	return 1;
++}
++
+ /*
+  * Atomically swap in the new signal mask, and wait for a signal.
+  */
+diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
+index aacd6d1..2c2b80b 100644
+--- a/arch/m68k/kernel/traps.c
++++ b/arch/m68k/kernel/traps.c
+@@ -48,10 +48,7 @@ asmlinkage void nmihandler(void);
+ asmlinkage void fpu_emu(void);
+ #endif
+ 
+-e_vector vectors[256] = {
+-	[VEC_BUSERR]	= buserr,
+-	[VEC_SYS]	= system_call,
+-};
++e_vector vectors[256];
+ 
+ /* nmi handler for the Amiga */
+ asm(".text\n"
+@@ -61,10 +58,11 @@ asm(".text\n"
+ /*
+  * this must be called very early as the kernel might
+  * use some instruction that are emulated on the 060
++ * and so we're prepared for early probe attempts (e.g. nf_init).
+  */
+ void __init base_trap_init(void)
+ {
+-	if(MACH_IS_SUN3X) {
++	if (MACH_IS_SUN3X) {
+ 		extern e_vector *sun3x_prom_vbr;
+ 
+ 		__asm__ volatile ("movec %%vbr, %0" : "=r" (sun3x_prom_vbr));
+@@ -79,6 +77,10 @@ void __init base_trap_init(void)
+ 
+ 		vectors[VEC_UNIMPII] = unimp_vec;
+ 	}
++
++	vectors[VEC_BUSERR] = buserr;
++	vectors[VEC_ILLEGAL] = trap;
++	vectors[VEC_SYS] = system_call;
+ }
+ 
+ void __init trap_init (void)
+@@ -1055,9 +1057,11 @@ asmlinkage void trap_c(struct frame *fp)
+ 	siginfo_t info;
+ 
+ 	if (fp->ptregs.sr & PS_S) {
+-		if ((fp->ptregs.vector >> 2) == VEC_TRACE) {
+-			/* traced a trapping instruction */
+-		} else
++		if (fp->ptregs.vector == VEC_TRACE << 2) {
++			/* traced a trapping instruction on a 68020/30,
++			 * real exception will be executed afterwards.
++			 */
++		} else if (!handle_kernel_fault(&fp->ptregs))
+ 			bad_super_trap(fp);
+ 		return;
+ 	}
+diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
+index d0e35cf..933d315 100644
+--- a/arch/m68k/mm/fault.c
++++ b/arch/m68k/mm/fault.c
+@@ -18,7 +18,6 @@
+ #include <asm/pgalloc.h>
+ 
+ extern void die_if_kernel(char *, struct pt_regs *, long);
+-extern const int frame_extra_sizes[]; /* in m68k/kernel/signal.c */
+ 
+ int send_fault_sig(struct pt_regs *regs)
+ {
+@@ -35,21 +34,8 @@ int send_fault_sig(struct pt_regs *regs)
+ 		force_sig_info(siginfo.si_signo,
+ 			       &siginfo, current);
+ 	} else {
+-		const struct exception_table_entry *fixup;
+-
+-		/* Are we prepared to handle this kernel fault? */
+-		if ((fixup = search_exception_tables(regs->pc))) {
+-			struct pt_regs *tregs;
+-			/* Create a new four word stack frame, discarding the old
+-			   one.  */
+-			regs->stkadj = frame_extra_sizes[regs->format];
+-			tregs =	(struct pt_regs *)((ulong)regs + regs->stkadj);
+-			tregs->vector = regs->vector;
+-			tregs->format = 0;
+-			tregs->pc = fixup->fixup;
+-			tregs->sr = regs->sr;
++		if (handle_kernel_fault(regs))
+ 			return -1;
+-		}
+ 
+ 		//if (siginfo.si_signo == SIGBUS)
+ 		//	force_sig_info(siginfo.si_signo,
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0029-m68k-Add-support-for-EARLY_PRINTK-on-MVME16x.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0029-m68k-Add-support-for-EARLY_PRINTK-on-MVME16x.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,215 @@
+From 1cf0096e7ed3c8e2344bc8e8f7b927f99a6e8fc1 Mon Sep 17 00:00:00 2001
+From: Kars de Jong <jongk at linux-m68k.org>
+Date: Thu, 20 Nov 2008 13:47:18 +0100
+Subject: [PATCH] m68k: Add support for EARLY_PRINTK on MVME16x
+
+Added support for EARLY_PRINTK when running on an MVME16x board.
+
+Signed-off-by: Kars de Jong <jongk at linux-m68k.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/Kconfig.debug    |   11 +++
+ arch/m68k/mvme16x/config.c |  160 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 171 insertions(+), 0 deletions(-)
+
+diff --git a/arch/m68k/Kconfig.debug b/arch/m68k/Kconfig.debug
+index f53b6d5..e0283a0 100644
+--- a/arch/m68k/Kconfig.debug
++++ b/arch/m68k/Kconfig.debug
+@@ -2,4 +2,15 @@ menu "Kernel hacking"
+ 
+ source "lib/Kconfig.debug"
+ 
++config EARLY_PRINTK
++	bool "Early printk" if EMBEDDED
++	depends on MVME16x
++	default y
++	help
++          Write kernel log output directly to a serial port.
++
++          This is useful for kernel debugging when your machine crashes very
++          early before the console code is initialized.
++          You should normally say N here, unless you want to debug such a crash.
++
+ endmenu
+diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
+index 11edf61..318b514 100644
+--- a/arch/m68k/mvme16x/config.c
++++ b/arch/m68k/mvme16x/config.c
+@@ -124,6 +124,163 @@ static void __init mvme16x_init_IRQ (void)
+ #define PccSCCMICR	0x1d
+ #define PccSCCTICR	0x1e
+ #define PccSCCRICR	0x1f
++#define PccTPIACKR	0x25
++
++#ifdef CONFIG_EARLY_PRINTK
++
++/**** cd2401 registers ****/
++#define CD2401_ADDR	(0xfff45000)
++
++#define CyGFRCR         (0x81)
++#define CyCCR		(0x13)
++#define      CyCLR_CHAN		(0x40)
++#define      CyINIT_CHAN	(0x20)
++#define      CyCHIP_RESET	(0x10)
++#define      CyENB_XMTR		(0x08)
++#define      CyDIS_XMTR		(0x04)
++#define      CyENB_RCVR		(0x02)
++#define      CyDIS_RCVR		(0x01)
++#define CyCAR		(0xee)
++#define CyIER		(0x11)
++#define      CyMdmCh		(0x80)
++#define      CyRxExc		(0x20)
++#define      CyRxData		(0x08)
++#define      CyTxMpty		(0x02)
++#define      CyTxRdy		(0x01)
++#define CyLICR		(0x26)
++#define CyRISR		(0x89)
++#define      CyTIMEOUT		(0x80)
++#define      CySPECHAR		(0x70)
++#define      CyOVERRUN		(0x08)
++#define      CyPARITY		(0x04)
++#define      CyFRAME		(0x02)
++#define      CyBREAK		(0x01)
++#define CyREOIR		(0x84)
++#define CyTEOIR		(0x85)
++#define CyMEOIR		(0x86)
++#define      CyNOTRANS		(0x08)
++#define CyRFOC		(0x30)
++#define CyRDR		(0xf8)
++#define CyTDR		(0xf8)
++#define CyMISR		(0x8b)
++#define CyRISR		(0x89)
++#define CyTISR		(0x8a)
++#define CyMSVR1		(0xde)
++#define CyMSVR2		(0xdf)
++#define      CyDSR		(0x80)
++#define      CyDCD		(0x40)
++#define      CyCTS		(0x20)
++#define      CyDTR		(0x02)
++#define      CyRTS		(0x01)
++#define CyRTPRL		(0x25)
++#define CyRTPRH		(0x24)
++#define CyCOR1		(0x10)
++#define      CyPARITY_NONE	(0x00)
++#define      CyPARITY_E		(0x40)
++#define      CyPARITY_O		(0xC0)
++#define      Cy_5_BITS		(0x04)
++#define      Cy_6_BITS		(0x05)
++#define      Cy_7_BITS		(0x06)
++#define      Cy_8_BITS		(0x07)
++#define CyCOR2		(0x17)
++#define      CyETC		(0x20)
++#define      CyCtsAE		(0x02)
++#define CyCOR3		(0x16)
++#define      Cy_1_STOP		(0x02)
++#define      Cy_2_STOP		(0x04)
++#define CyCOR4		(0x15)
++#define      CyREC_FIFO		(0x0F)  /* Receive FIFO threshold */
++#define CyCOR5		(0x14)
++#define CyCOR6		(0x18)
++#define CyCOR7		(0x07)
++#define CyRBPR		(0xcb)
++#define CyRCOR		(0xc8)
++#define CyTBPR		(0xc3)
++#define CyTCOR		(0xc0)
++#define CySCHR1		(0x1f)
++#define CySCHR2 	(0x1e)
++#define CyTPR		(0xda)
++#define CyPILR1		(0xe3)
++#define CyPILR2		(0xe0)
++#define CyPILR3		(0xe1)
++#define CyCMR		(0x1b)
++#define      CyASYNC		(0x02)
++#define CyLICR          (0x26)
++#define CyLIVR          (0x09)
++#define CySCRL		(0x23)
++#define CySCRH		(0x22)
++#define CyTFTC		(0x80)
++
++static void cons_write(struct console *co, const char *str, unsigned count)
++{
++	volatile unsigned char *base_addr = (u_char *)CD2401_ADDR;
++	volatile u_char sink;
++	u_char ier;
++	int port;
++	u_char do_lf = 0;
++	int i = 0;
++
++	/* Ensure transmitter is enabled! */
++
++	port = 0;
++	base_addr[CyCAR] = (u_char)port;
++	while (base_addr[CyCCR])
++		;
++	base_addr[CyCCR] = CyENB_XMTR;
++
++	ier = base_addr[CyIER];
++	base_addr[CyIER] = CyTxMpty;
++
++	while (1) {
++		if (pcc2chip[PccSCCTICR] & 0x20)
++		{
++			/* We have a Tx int. Acknowledge it */
++			sink = pcc2chip[PccTPIACKR];
++			if ((base_addr[CyLICR] >> 2) == port) {
++				if (i == count) {
++					/* Last char of string is now output */
++					base_addr[CyTEOIR] = CyNOTRANS;
++					break;
++				}
++				if (do_lf) {
++					base_addr[CyTDR] = '\n';
++					str++;
++					i++;
++					do_lf = 0;
++				}
++				else if (*str == '\n') {
++					base_addr[CyTDR] = '\r';
++					do_lf = 1;
++				}
++				else {
++					base_addr[CyTDR] = *str++;
++					i++;
++				}
++				base_addr[CyTEOIR] = 0;
++			}
++			else
++				base_addr[CyTEOIR] = CyNOTRANS;
++		}
++	}
++
++	base_addr[CyIER] = ier;
++}
++
++static struct console cons_info =
++{
++	.name	= "sercon",
++	.write	= cons_write,
++	.flags	= CON_PRINTBUFFER | CON_BOOT,
++	.index	= -1,
++};
++
++void __init mvme16x_early_console(void)
++{
++	register_console(&cons_info);
++
++	printk(KERN_INFO "MVME16x: early console registered\n");
++}
++#endif
+ 
+ void __init config_mvme16x(void)
+ {
+@@ -183,6 +340,9 @@ void __init config_mvme16x(void)
+ 	pcc2chip[PccSCCMICR] = 0x10;
+ 	pcc2chip[PccSCCTICR] = 0x10;
+ 	pcc2chip[PccSCCRICR] = 0x10;
++#ifdef CONFIG_EARLY_PRINTK
++	mvme16x_early_console();
++#endif
+     }
+ }
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0030-Update-for-m68k-Add-support-for-EARLY_PRINTK-on-MVM.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0030-Update-for-m68k-Add-support-for-EARLY_PRINTK-on-MVM.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,26 @@
+From 65a7baf501ed5e2c21b3e72fc9d36e51e0fcf348 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Mon, 24 Nov 2008 21:24:57 +0100
+Subject: [PATCH] Update for m68k: Add support for EARLY_PRINTK on MVME16x
+
+Make mvme16x_early_console static
+---
+ arch/m68k/mvme16x/config.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
+index 318b514..fbdced1 100644
+--- a/arch/m68k/mvme16x/config.c
++++ b/arch/m68k/mvme16x/config.c
+@@ -274,7 +274,7 @@ static struct console cons_info =
+ 	.index	= -1,
+ };
+ 
+-void __init mvme16x_early_console(void)
++static void __init mvme16x_early_console(void)
+ {
+ 	register_console(&cons_info);
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0031-m68k-atari_scc-Upstream-updates.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0031-m68k-atari_scc-Upstream-updates.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,132 @@
+From f744b926b144a56b5d58f6d1ecf34a898b51daba Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Sun, 11 Jan 2009 11:05:25 +0100
+Subject: [PATCH] m68k: atari_scc - Upstream updates
+
+Port a few upstream updates from vme_scc.c to atari_scc.c:
+  - commit 31f35939d1d9bcfb3099b32c67b896d2792603f9 ("tty_port: Add a port
+    level carrier detect operation")
+  - commit 36c621d82b956ff6ff72273f848af53e6c581aba ("tty: Introduce a tty_port
+    generic block_til_ready")
+  - commit c9f19e96a2f33cd56c2bd19f87a0c4982d011c2b ("tty: Remove some
+    pointless casts")
+
+The first 2 were needed to fix a compilation problem.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/char/atari_scc.c |   27 ++++++++++++++++-----------
+ 1 files changed, 16 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/char/atari_scc.c b/drivers/char/atari_scc.c
+index fefff96..23fc4ed 100644
+--- a/drivers/char/atari_scc.c
++++ b/drivers/char/atari_scc.c
+@@ -74,7 +74,7 @@ static void scc_disable_tx_interrupts(void *ptr);
+ static void scc_enable_tx_interrupts(void *ptr);
+ static void scc_disable_rx_interrupts(void *ptr);
+ static void scc_enable_rx_interrupts(void *ptr);
+-static int scc_get_CD(void *ptr);
++static int scc_carrier_raised(struct tty_port *port);
+ static void scc_shutdown_port(void *ptr);
+ static int scc_set_real_termios(void *ptr);
+ static void scc_hungup(void *ptr);
+@@ -106,7 +106,6 @@ static struct real_driver scc_real_driver = {
+ 	.enable_tx_interrupts	= scc_enable_tx_interrupts,
+ 	.disable_rx_interrupts	= scc_disable_rx_interrupts,
+ 	.enable_rx_interrupts	= scc_enable_rx_interrupts,
+-	.get_CD			= scc_get_CD,
+ 	.shutdown_port		= scc_shutdown_port,
+ 	.set_real_termios	= scc_set_real_termios,
+ 	.chars_in_buffer	= scc_chars_in_buffer,
+@@ -133,6 +132,10 @@ static struct tty_operations scc_ops = {
+ 	.break_ctl		= scc_break_ctl,
+ };
+ 
++static const struct tty_port_operations scc_port_ops = {
++	.carrier_raised = scc_carrier_raised,
++};
++
+ /* BRG values for the standard speeds and the various clock sources */
+ 
+ struct baud_entry {
+@@ -263,6 +266,8 @@ static void scc_init_portstructs(void)
+ 
+ 	for (i = 0; i < 2; i++) {
+ 		port = scc_ports + i;
++		tty_port_init(&port->gs.port);
++		port->gs.port.ops = &scc_port_ops;
+ 		port->gs.magic = SCC_MAGIC;
+ 		port->gs.close_delay = HZ/2;
+ 		port->gs.closing_wait = 30 * HZ;
+@@ -941,10 +946,10 @@ static void scc_enable_rx_interrupts(void *ptr)
+ }
+ 
+ 
+-static int scc_get_CD(void *ptr)
++static int scc_carrier_raised(struct tty_port *port)
+ {
+-	struct scc_port *port = ptr;
+-	unsigned channel = port->channel;
++	struct scc_port *sc = container_of(port, struct scc_port, gs.port);
++	unsigned channel = sc->channel;
+ 
+ 	pr_debug("SCC: get_CD!\n");
+ 	return !!(scc_last_status_reg[channel] & SR_DCD);
+@@ -1236,7 +1241,7 @@ static void scc_setsignals(struct scc_port *port, int dtr, int rts)
+ 
+ static void scc_send_xchar(struct tty_struct *tty, char ch)
+ {
+-	struct scc_port *port = (struct scc_port *)tty->driver_data;
++	struct scc_port *port = tty->driver_data;
+ 
+ 	pr_debug("SCC: send_xchar ...\n");
+ 	port->x_char = ch;
+@@ -1341,7 +1346,7 @@ static int scc_open(struct tty_struct *tty, struct file *filp)
+ 		return retval;
+ 	}
+ 
+-	port->c_dcd = scc_get_CD(port);
++	port->c_dcd = tty_port_carrier_raised(&port->gs.port);
+ 
+ 	pr_debug(KERN_WARNING "SCC: enable rx ints ...\n");
+ 	scc_enable_rx_interrupts(port);
+@@ -1353,7 +1358,7 @@ static int scc_open(struct tty_struct *tty, struct file *filp)
+ 
+ static void scc_throttle(struct tty_struct *tty)
+ {
+-	struct scc_port *port = (struct scc_port *)tty->driver_data;
++	struct scc_port *port = tty->driver_data;
+ 	unsigned long flags;
+ 
+ 	SCC_ACCESS_INIT(port);
+@@ -1371,7 +1376,7 @@ static void scc_throttle(struct tty_struct *tty)
+ 
+ static void scc_unthrottle(struct tty_struct *tty)
+ {
+-	struct scc_port *port = (struct scc_port *)tty->driver_data;
++	struct scc_port *port = tty->driver_data;
+ 	unsigned long flags;
+ 
+ 	SCC_ACCESS_INIT(port);
+@@ -1390,7 +1395,7 @@ static void scc_unthrottle(struct tty_struct *tty)
+ static int scc_ioctl(struct tty_struct *tty, struct file *file,
+ 		     unsigned int cmd, unsigned long arg)
+ {
+-	struct scc_port *port = (struct scc_port *)tty->driver_data;
++	struct scc_port *port = tty->driver_data;
+ 	int retval;
+ 
+ 	pr_debug("SCC: ioctl! cmd %d, arg %lu\n", cmd, arg);
+@@ -1476,7 +1481,7 @@ static int scc_ioctl(struct tty_struct *tty, struct file *file,
+ 
+ static int scc_break_ctl(struct tty_struct *tty, int break_state)
+ {
+-	struct scc_port *port = (struct scc_port *)tty->driver_data;
++	struct scc_port *port = tty->driver_data;
+ 	unsigned long flags;
+ 
+ 	SCC_ACCESS_INIT(port);
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0032-m68k-atari-Rename-mfp-to-st_mfp.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0032-m68k-atari-Rename-mfp-to-st_mfp.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,84 @@
+From 38aa24dfffc2cc63493453757817c6e06df11aef Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Thu, 5 Feb 2009 22:06:03 +0100
+Subject: [PATCH] m68k: atari - Rename "mfp" to "st_mfp"
+
+http://kisskb.ellerman.id.au/kisskb/buildresult/72115/:
+| net/mac80211/ieee80211_i.h:327: error: syntax error before 'volatile'
+| net/mac80211/ieee80211_i.h:350: error: syntax error before '}' token
+| net/mac80211/ieee80211_i.h:455: error: field 'sta' has incomplete type
+| distcc[19430] ERROR: compile net/mac80211/main.c on sprygo/32 failed
+
+This is caused by
+
+| # define mfp ((*(volatile struct MFP*)MFP_BAS))
+
+in arch/m68k/include/asm/atarihw.h, which conflicts with the new "mfp" enum in
+net/mac80211/ieee80211_i.h.
+
+Rename "mfp" to "st_mfp", as it's a way too generic name for a global #define.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/char/atari_scc.c     |    4 ++--
+ drivers/net/atari_91C111.c   |    4 ++--
+ drivers/net/atari_ethernec.c |    4 ++--
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/char/atari_scc.c b/drivers/char/atari_scc.c
+index 23fc4ed..2bbd44c 100644
+--- a/drivers/char/atari_scc.c
++++ b/drivers/char/atari_scc.c
+@@ -653,7 +653,7 @@ int atari_scc_init(void)
+ 	if (!(ATARIHW_PRESENT(SCC) || ATARIHW_PRESENT(ST_ESCC)))
+ 		return -ENODEV;
+ 
+-	scc_del = &mfp.par_dt_reg;
++	scc_del = &st_mfp.par_dt_reg;
+ 
+ 	if (MACH_IS_TT)
+ 		res = atari_tt_scc_init();
+@@ -1541,7 +1541,7 @@ static void atari_init_scc_port(int cflag)
+ 	int baud = cflag & CBAUD;
+ 	int clksrc, clkmode, div, reg3, reg5;
+ 
+-	scc_del = &mfp.par_dt_reg;
++	scc_del = &st_mfp.par_dt_reg;
+ 
+ 	if (cflag & CBAUDEX)
+ 		baud += B38400;
+diff --git a/drivers/net/atari_91C111.c b/drivers/net/atari_91C111.c
+index af2d255..a82ba3d 100644
+--- a/drivers/net/atari_91C111.c
++++ b/drivers/net/atari_91C111.c
+@@ -2302,9 +2302,9 @@ static int __devinit smc_drv_probe(struct platform_device *pdev)
+ 			timd = 255;
+ 		printk(KERN_INFO "Timer D frequency: %u Hz\n", 38400/timd);
+ 		/* set Timer D data Register */
+-		mfp.tim_dt_d = timd;	/* 200 Hz */
++		st_mfp.tim_dt_d = timd;	/* 200 Hz */
+ 		/* start timer D, div = 1:100 */
+-		mfp.tim_ct_cd = (mfp.tim_ct_cd & 0xf0) | 0x5;
++		st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 0xf0) | 0x5;
+ 	}
+ 
+ 	return 0;
+diff --git a/drivers/net/atari_ethernec.c b/drivers/net/atari_ethernec.c
+index 74eeae4..05b5e2e 100644
+--- a/drivers/net/atari_ethernec.c
++++ b/drivers/net/atari_ethernec.c
+@@ -622,9 +622,9 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
+ 		/* timer routine set up in atari_ethernec_probe() */
+ 		if (dev->irq == IRQ_MFP_TIMD) {
+ 			/* set Timer D data Register */
+-			mfp.tim_dt_d = 123;	/* 200 Hz */
++			st_mfp.tim_dt_d = 123;	/* 200 Hz */
+ 			/* start timer D, div = 1:100 */
+-			mfp.tim_ct_cd = (mfp.tim_ct_cd & 0xf0) | 0x6;
++			st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 0xf0) | 0x6;
+ 		}
+ 		/* Must make this shared in case other timer ints are needed */
+ 		ret = request_irq(dev->irq, atari_ei_interrupt, IRQF_SHARED, name, dev);
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0033-atari-Use-the-correct-mouse-interrupt-hook.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0033-atari-Use-the-correct-mouse-interrupt-hook.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,77 @@
+From 7ddb9cf69e80b2b65511626ce372a2e307c053f4 Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at biophys.uni-duesseldorf.de>
+Date: Tue, 16 Dec 2008 21:26:03 +0100
+Subject: [PATCH] atari: Use the correct mouse interrupt hook
+
+The Atari keyboard driver calls atari_mouse_interrupt_hook if it's set, not
+atari_input_mouse_interrupt_hook. Fix below.
+
+[geert] Killed off atari_mouse_interrupt_hook completely, after fixing another
+incorrect assignment in atarimouse.c.
+
+Signed-off-by: Michael Schmitz <schmitz at debian.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/atari/atakeyb.c        |    7 ++-----
+ arch/m68k/include/asm/atarikb.h  |    2 --
+ drivers/input/mouse/atarimouse.c |    2 +-
+ 3 files changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c
+index 4add96d..8e0c692 100644
+--- a/arch/m68k/atari/atakeyb.c
++++ b/arch/m68k/atari/atakeyb.c
+@@ -36,13 +36,10 @@
+ 
+ /* Hook for MIDI serial driver */
+ void (*atari_MIDI_interrupt_hook) (void);
+-/* Hook for mouse driver */
+-void (*atari_mouse_interrupt_hook) (char *);
+ /* Hook for keyboard inputdev  driver */
+ void (*atari_input_keyboard_interrupt_hook) (unsigned char, char);
+ /* Hook for mouse inputdev  driver */
+ void (*atari_input_mouse_interrupt_hook) (char *);
+-EXPORT_SYMBOL(atari_mouse_interrupt_hook);
+ EXPORT_SYMBOL(atari_input_keyboard_interrupt_hook);
+ EXPORT_SYMBOL(atari_input_mouse_interrupt_hook);
+ 
+@@ -263,8 +260,8 @@ repeat:
+ 			kb_state.buf[kb_state.len++] = scancode;
+ 			if (kb_state.len == 3) {
+ 				kb_state.state = KEYBOARD;
+-				if (atari_mouse_interrupt_hook)
+-					atari_mouse_interrupt_hook(kb_state.buf);
++				if (atari_input_mouse_interrupt_hook)
++					atari_input_mouse_interrupt_hook(kb_state.buf);
+ 			}
+ 			break;
+ 
+diff --git a/arch/m68k/include/asm/atarikb.h b/arch/m68k/include/asm/atarikb.h
+index 546e7da..68f3622 100644
+--- a/arch/m68k/include/asm/atarikb.h
++++ b/arch/m68k/include/asm/atarikb.h
+@@ -34,8 +34,6 @@ void ikbd_joystick_disable(void);
+ 
+ /* Hook for MIDI serial driver */
+ extern void (*atari_MIDI_interrupt_hook) (void);
+-/* Hook for mouse driver */
+-extern void (*atari_mouse_interrupt_hook) (char *);
+ /* Hook for keyboard inputdev  driver */
+ extern void (*atari_input_keyboard_interrupt_hook) (unsigned char, char);
+ /* Hook for mouse inputdev  driver */
+diff --git a/drivers/input/mouse/atarimouse.c b/drivers/input/mouse/atarimouse.c
+index adf45b3..a57143c 100644
+--- a/drivers/input/mouse/atarimouse.c
++++ b/drivers/input/mouse/atarimouse.c
+@@ -108,7 +108,7 @@ static int atamouse_open(struct input_dev *dev)
+ static void atamouse_close(struct input_dev *dev)
+ {
+ 	ikbd_mouse_disable();
+-	atari_mouse_interrupt_hook = NULL;
++	atari_input_mouse_interrupt_hook = NULL;
+ }
+ 
+ static int __init atamouse_init(void)
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0034-m68k-Fix-atarimouse-init.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0034-m68k-Fix-atarimouse-init.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,30 @@
+From 0dad8d8d336010719b748a38d673cbc45f4bdc10 Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at biophys.uni-duesseldorf.de>
+Date: Sun, 28 Dec 2008 23:00:45 +0100
+Subject: [PATCH] m68k: Fix atarimouse init
+
+Atarimouse fails to load as a module (with ENODEV), due to a brown paper
+bag bug, misinterpreting the semantics of atari_keyb_init().
+
+Signed-off-by: Michael Schmitz <schmitz at debian.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/input/mouse/atarimouse.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/input/mouse/atarimouse.c b/drivers/input/mouse/atarimouse.c
+index a57143c..1b5f4dd 100644
+--- a/drivers/input/mouse/atarimouse.c
++++ b/drivers/input/mouse/atarimouse.c
+@@ -118,7 +118,7 @@ static int __init atamouse_init(void)
+ 	if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP))
+ 		return -ENODEV;
+ 
+-	if (!atari_keyb_init())
++	if (atari_keyb_init())
+ 		return -ENODEV;
+ 
+ 	atamouse_dev = input_allocate_device();
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0035-ADB-raw-packets.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0035-ADB-raw-packets.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,48 @@
+From 9bd0232b2cbe128a771b1937e7f8accbadae3c21 Mon Sep 17 00:00:00 2001
+From: Linux/m68k legacy <xxx at linux-m68k.org>
+Date: Tue, 18 Nov 2008 21:22:20 +0100
+Subject: [PATCH] ADB raw packets
+
+ADB: add support for raw packets
+---
+ drivers/macintosh/adb.c |    7 ++++---
+ include/linux/adb.h     |    1 +
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
+index 23741ce..57790a0 100644
+--- a/drivers/macintosh/adb.c
++++ b/drivers/macintosh/adb.c
+@@ -412,13 +412,14 @@ adb_request(struct adb_request *req, void (*done)(struct adb_request *),
+ 	if (nbytes < 1)
+ 		return -EINVAL;
+ 
+-	req->nbytes = nbytes+1;
++	i = (flags & ADBREQ_RAW) ? 0 : 1;
++	req->nbytes = nbytes+i;
+ 	req->done = done;
+ 	req->reply_expected = flags & ADBREQ_REPLY;
+ 	req->data[0] = ADB_PACKET;
+ 	va_start(list, nbytes);
+-	for (i = 0; i < nbytes; ++i)
+-		req->data[i+1] = va_arg(list, int);
++	while (i < req->nbytes)
++		req->data[i++] = va_arg(list, int);
+ 	va_end(list);
+ 
+ 	if (flags & ADBREQ_NOSEND)
+diff --git a/include/linux/adb.h b/include/linux/adb.h
+index 63bca50..1cf0e7d 100644
+--- a/include/linux/adb.h
++++ b/include/linux/adb.h
+@@ -76,6 +76,7 @@ struct adb_driver {
+ #define ADBREQ_REPLY	1	/* expect reply */
+ #define ADBREQ_SYNC	2	/* poll until done */
+ #define ADBREQ_NOSEND	4	/* build the request, but don't send it */
++#define ADBREQ_RAW	8	/* send raw packet (don't prepend ADB_PACKET) */
+ 
+ /* Messages sent thru the client_list notifier. You should NOT stop
+    the operation, at least not with this version */
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0036-m68k-Update-defconfigs-for-new-m68k-features.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0036-m68k-Update-defconfigs-for-new-m68k-features.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,114 @@
+From 76bccc22ef7ae013e479977de6d593538a63317b Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Sun, 29 Mar 2009 14:23:44 +0200
+Subject: [PATCH] m68k: Update defconfigs for new m68k features
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/configs/atari_defconfig   |    8 ++++++++
+ arch/m68k/configs/multi_defconfig   |    9 +++++++++
+ arch/m68k/configs/mvme16x_defconfig |    1 +
+ 3 files changed, 18 insertions(+), 0 deletions(-)
+
+diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
+index d92a90e..ac255b2 100644
+--- a/arch/m68k/configs/atari_defconfig
++++ b/arch/m68k/configs/atari_defconfig
+@@ -123,12 +123,17 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
+ #
+ # CONFIG_AMIGA is not set
+ CONFIG_ATARI=y
++CONFIG_ATARI_ROM_ISA=y
+ # CONFIG_MAC is not set
+ # CONFIG_APOLLO is not set
+ # CONFIG_VME is not set
+ # CONFIG_HP300 is not set
+ # CONFIG_SUN3X is not set
+ # CONFIG_Q40 is not set
++CONFIG_NATFEAT=y
++CONFIG_NFETH=y
++CONFIG_NFBLOCK=y
++CONFIG_NFCON=y
+ 
+ #
+ # Processor type
+@@ -574,6 +579,8 @@ CONFIG_VETH=m
+ CONFIG_NET_ETHERNET=y
+ CONFIG_MII=y
+ CONFIG_ATARILANCE=y
++CONFIG_ATARI_ETHERNAT=m
++CONFIG_ATARI_ETHERNEC=y
+ # CONFIG_ETHOC is not set
+ # CONFIG_DNET is not set
+ # CONFIG_IBM_NEW_EMAC_ZMII is not set
+@@ -838,6 +845,7 @@ CONFIG_HIDRAW=y
+ # Character devices
+ #
+ CONFIG_ATARI_MFPSER=y
++CONFIG_ATARI_SCC=y
+ CONFIG_ATARI_MIDI=y
+ CONFIG_ATARI_DSP56K=m
+ CONFIG_SERIAL_CONSOLE=y
+diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
+index 69c43e2..159c1d4 100644
+--- a/arch/m68k/configs/multi_defconfig
++++ b/arch/m68k/configs/multi_defconfig
+@@ -123,6 +123,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
+ #
+ CONFIG_AMIGA=y
+ CONFIG_ATARI=y
++CONFIG_ATARI_ROM_ISA=y
+ CONFIG_MAC=y
+ CONFIG_NUBUS=y
+ CONFIG_M68K_L2_CACHE=y
+@@ -135,6 +136,10 @@ CONFIG_HP300=y
+ CONFIG_DIO=y
+ CONFIG_SUN3X=y
+ CONFIG_Q40=y
++CONFIG_NATFEAT=y
++CONFIG_NFETH=y
++CONFIG_NFBLOCK=y
++CONFIG_NFCON=y
+ 
+ #
+ # Processor type
+@@ -647,6 +652,8 @@ CONFIG_MVME147_NET=y
+ CONFIG_MVME16x_NET=y
+ CONFIG_BVME6000_NET=y
+ CONFIG_ATARILANCE=y
++CONFIG_ATARI_ETHERNAT=m
++CONFIG_ATARI_ETHERNEC=y
+ CONFIG_SUN3LANCE=y
+ CONFIG_HPLANCE=y
+ # CONFIG_NET_VENDOR_3COM is not set
+@@ -978,6 +985,7 @@ CONFIG_HIDRAW=y
+ # Character devices
+ #
+ CONFIG_ATARI_MFPSER=y
++CONFIG_ATARI_SCC=y
+ CONFIG_ATARI_MIDI=y
+ CONFIG_ATARI_DSP56K=m
+ CONFIG_AMIGA_BUILTIN_SERIAL=y
+@@ -1196,6 +1204,7 @@ CONFIG_DEBUG_MEMORY_INIT=y
+ # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+ CONFIG_SYSCTL_SYSCALL_CHECK=y
+ # CONFIG_SAMPLES is not set
++CONFIG_EARLY_PRINTK=y
+ 
+ #
+ # Security options
+diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
+index 890594f..cc17547 100644
+--- a/arch/m68k/configs/mvme16x_defconfig
++++ b/arch/m68k/configs/mvme16x_defconfig
+@@ -961,6 +961,7 @@ CONFIG_DEBUG_MEMORY_INIT=y
+ # CONFIG_RCU_CPU_STALL_DETECTOR is not set
+ CONFIG_SYSCTL_SYSCALL_CHECK=y
+ # CONFIG_SAMPLES is not set
++CONFIG_EARLY_PRINTK=y
+ 
+ #
+ # Security options
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0037-arch-m68k-emu-nfeth.c-doesn-t-need-obsolete-net-iee.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0037-arch-m68k-emu-nfeth.c-doesn-t-need-obsolete-net-iee.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,29 @@
+From bca66685ebc6cd236a8abecb1942d218113638c4 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Sun, 29 Mar 2009 11:03:25 +0200
+Subject: [PATCH] arch/m68k/emu/nfeth.c doesn't need obsolete <net/ieee80211.h>
+
+commit f3734ee6df3ac57151e02d091f47d5e52e646539 ("make net/ieee80211.h private
+to ipw2x00") removed <net/ieee80211.h>, breaking the build of
+arch/m68k/emu/nfeth.c. Remove the #include, as it's not needed anyway.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/emu/nfeth.c |    1 -
+ 1 files changed, 0 insertions(+), 1 deletions(-)
+
+diff --git a/arch/m68k/emu/nfeth.c b/arch/m68k/emu/nfeth.c
+index de7cdad..5b118e9 100644
+--- a/arch/m68k/emu/nfeth.c
++++ b/arch/m68k/emu/nfeth.c
+@@ -12,7 +12,6 @@
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+ #include <linux/module.h>
+-#include <net/ieee80211.h>
+ #include <asm/natfeat.h>
+ #include <asm/virtconvert.h>
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0038-m68k-z2ram-correct-printing-of-sector_t.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0038-m68k-z2ram-correct-printing-of-sector_t.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,33 @@
+From a7f0e350acbaad44040aefde7b637722ddeef150 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Sun, 29 Mar 2009 21:15:40 +0200
+Subject: [PATCH] m68k: z2ram - correct printing of sector_t
+
+If CONFIG_LBDAF=y, `sector_t' becomes `u64' instead of `unsigned long':
+
+| drivers/block/z2ram.c:79: warning: format '%lu' expects type 'long unsigned int', but argument 2 has type 'sector_t'
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/block/z2ram.c |    5 +++--
+ 1 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
+index 64f941e..1d336f9 100644
+--- a/drivers/block/z2ram.c
++++ b/drivers/block/z2ram.c
+@@ -77,8 +77,9 @@ static void do_z2_request(struct request_queue *q)
+ 		int err = 0;
+ 
+ 		if (start + len > z2ram_size) {
+-			printk( KERN_ERR DEVICE_NAME ": bad access: block=%lu, count=%u\n",
+-				blk_rq_pos(req), blk_rq_cur_sectors(req));
++			pr_err(DEVICE_NAME ": bad access: block=%llu, count=%u\n",
++				(unsigned long long)blk_rq_pos(req),
++				blk_rq_cur_sectors(req));
+ 			err = -EIO;
+ 			goto done;
+ 		}
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0039-m68k-Atari-SCC-verbosity-fix.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0039-m68k-Atari-SCC-verbosity-fix.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,30 @@
+From ebf36266d52a5936a5440174ee08227c74d096e4 Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at biophys.uni-duesseldorf.de>
+Date: Sun, 19 Apr 2009 03:24:40 +0200
+Subject: [PATCH] m68k: Atari SCC verbosity fix
+
+Fix verbosity level of SCC driver (leftover 'info' message) as reported by
+Patrice Mandin.
+
+Signed-off-by: Michael Schmitz <schmitz at debian.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/char/atari_scc.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/char/atari_scc.c b/drivers/char/atari_scc.c
+index 2bbd44c..7d7abe5 100644
+--- a/drivers/char/atari_scc.c
++++ b/drivers/char/atari_scc.c
+@@ -1351,7 +1351,7 @@ static int scc_open(struct tty_struct *tty, struct file *filp)
+ 	pr_debug(KERN_WARNING "SCC: enable rx ints ...\n");
+ 	scc_enable_rx_interrupts(port);
+ 	pr_debug(KERN_WARNING "SCC: enable rx ints done!\n");
+-	pr_info("SCC: open port done!\n");
++	pr_debug("SCC: open port done!\n");
+ 	return 0;
+ }
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0040-m68k-Atari-EtherNAT-replace-bus_id-with-dev_name.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0040-m68k-Atari-EtherNAT-replace-bus_id-with-dev_name.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,29 @@
+From a9e737e117ed73bc8dca54e24316b92e9de8e780 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Sun, 29 Mar 2009 11:22:18 +0200
+Subject: [PATCH] m68k: Atari EtherNAT - replace bus_id with dev_name()
+
+Cfr. commit db1d7bf70f42124f73675fca62fe32f3ab1111b4 ("net: struct device -
+replace bus_id with dev_name(), dev_set_name()") for drivers/net/smc91x.c.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/net/atari_91C111.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/net/atari_91C111.c b/drivers/net/atari_91C111.c
+index a82ba3d..cac5ede 100644
+--- a/drivers/net/atari_91C111.c
++++ b/drivers/net/atari_91C111.c
+@@ -1670,7 +1670,7 @@ smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+ {
+ 	strncpy(info->driver, CARDNAME, sizeof(info->driver));
+ 	strncpy(info->version, version, sizeof(info->version));
+-	strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
++	strncpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
+ }
+ 
+ static int smc_ethtool_nwayreset(struct net_device *dev)
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0041-m68k-Atari-EtherNAT-use-struct-net_device_ops.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0041-m68k-Atari-EtherNAT-use-struct-net_device_ops.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,58 @@
+From 03ab8d9175c96a273bfcd381aae4c67c17c01044 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Sun, 29 Mar 2009 11:23:40 +0200
+Subject: [PATCH] m68k: Atari EtherNAT - use struct net_device_ops
+
+Cfr. commit a528079e01aa9cf6cddc852d5ab5cf4908974745 ("smc91x: struct
+net_device_ops").
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/net/atari_91C111.c |   22 ++++++++++++++--------
+ 1 files changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/atari_91C111.c b/drivers/net/atari_91C111.c
+index cac5ede..87e2327 100644
+--- a/drivers/net/atari_91C111.c
++++ b/drivers/net/atari_91C111.c
+@@ -1712,6 +1712,19 @@ static const struct ethtool_ops smc_ethtool_ops = {
+ //	.set_eeprom	= smc_ethtool_seteeprom,
+ };
+ 
++static const struct net_device_ops smc_netdev_ops = {
++	.ndo_open		= smc_open,
++	.ndo_stop		= smc_close,
++	.ndo_start_xmit		= smc_hard_start_xmit,
++	.ndo_tx_timeout		= smc_timeout,
++	.ndo_set_multicast_list	= smc_set_multicast_list,
++	.ndo_validate_addr	= eth_validate_addr,
++	.ndo_set_mac_address 	= eth_mac_addr,
++#ifdef CONFIG_NET_POLL_CONTROLLER
++	.ndo_poll_controller	= smc_poll_controller,
++#endif
++};
++
+ /*
+  * smc_findirq
+  *
+@@ -1928,16 +1941,9 @@ static int __devinit smc_probe(struct net_device *dev, void __iomem *ioaddr,
+ 	/* Fill in the fields of the device structure with ethernet values. */
+ 	ether_setup(dev);
+ 
+-	dev->open = smc_open;
+-	dev->stop = smc_close;
+-	dev->hard_start_xmit = smc_hard_start_xmit;
+-	dev->tx_timeout = smc_timeout;
+ 	dev->watchdog_timeo = msecs_to_jiffies(watchdog);
+-	dev->set_multicast_list = smc_set_multicast_list;
++	dev->netdev_ops = &smc_netdev_ops;
+ 	dev->ethtool_ops = &smc_ethtool_ops;
+-#ifdef CONFIG_NET_POLL_CONTROLLER
+-	dev->poll_controller = smc_poll_controller;
+-#endif
+ 
+ 	tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
+ 	INIT_WORK(&lp->phy_configure, smc_phy_configure);
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0042-m68k-Hydra-Ethernet-correct-printing-of-resource_.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0042-m68k-Hydra-Ethernet-correct-printing-of-resource_.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,34 @@
+From 62c7cb5839b24329445716b23dd98756b09757d3 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Sun, 29 Mar 2009 22:33:57 +0200
+Subject: [PATCH] m68k: Hydra Ethernet - correct printing of resource_size_t
+
+| drivers/net/hydra.c:179: warning: format '%08lx' expects type 'long unsigned int', but argument 3 has type 'resource_size_t'
+
+resource_size_t changed from `unsigned long' to `u32' on 32-bit. Print
+the whole resource to make it future-proof.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/net/hydra.c |    5 ++---
+ 1 files changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c
+index 8a6d070..18257e6 100644
+--- a/drivers/net/hydra.c
++++ b/drivers/net/hydra.c
+@@ -174,9 +174,8 @@ static int __devinit hydra_init(struct zorro_dev *z)
+ 
+     zorro_set_drvdata(z, dev);
+ 
+-    printk(KERN_INFO "%s: Hydra at 0x%08llx, address "
+-	   "%pM (hydra.c " HYDRA_VERSION ")\n",
+-	   dev->name, (unsigned long long)z->resource.start, dev->dev_addr);
++    pr_info("%s: Hydra at %pR, address %pM (hydra.c " HYDRA_VERSION ")\n",
++	    dev->name, &z->resource, dev->dev_addr);
+ 
+     return 0;
+ }
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0043-scsi-Clean-up-mvme147.c.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0043-scsi-Clean-up-mvme147.c.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,30 @@
+From 7efa5677e78b679749a8475e298a4299068ede26 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Tue, 18 Nov 2008 21:25:15 +0100
+Subject: [PATCH] scsi: Clean up mvme147.c
+
+FIXME a few more to take care of
+FIXME merge include files that are included only once into the .c file
+
+git grep HOSTS_C
+---
+ drivers/scsi/mvme147.c |    3 ---
+ 1 files changed, 0 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c
+index d722235..99d2ae2 100644
+--- a/drivers/scsi/mvme147.c
++++ b/drivers/scsi/mvme147.c
+@@ -128,9 +128,6 @@ static int mvme147_bus_reset(struct scsi_cmnd *cmd)
+ 	return SUCCESS;
+ }
+ 
+-#define HOSTS_C
+-
+-#include "mvme147.h"
+ 
+ static struct scsi_host_template driver_template = {
+ 	.proc_name		= "MVME147",
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0044-zorro-use-dev_name-instead-of-obsolete-device.bus.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0044-zorro-use-dev_name-instead-of-obsolete-device.bus.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,30 @@
+From 5ac5c362ad56b384af6ca753667dc666994b2c3c Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Sun, 29 Mar 2009 11:14:59 +0200
+Subject: [PATCH] zorro: use dev_name() instead of obsolete device.bus_id
+
+device.bus_id got removed in commit 1fa5ae857bb14f6046205171d98506d8112dd74e
+("driver core: get rid of struct device's bus_id string array"), so use
+dev_name() instead.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/zorro/zorro-driver.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/zorro/zorro-driver.c b/drivers/zorro/zorro-driver.c
+index aeb0615..409244b 100644
+--- a/drivers/zorro/zorro-driver.c
++++ b/drivers/zorro/zorro-driver.c
+@@ -150,7 +150,7 @@ static int zorro_uevent(struct device *dev, struct kobj_uevent_env *env)
+ 		return -ENODEV;
+ 
+ 	if (add_uevent_var(env, "ZORRO_ID=%08X", z->id) ||
+-	    add_uevent_var(env, "ZORRO_SLOT_NAME=%s", z->dev.bus_id) ||
++	    add_uevent_var(env, "ZORRO_SLOT_NAME=%s", dev_name(dev)) ||
+ 	    add_uevent_var(env, "ZORRO_SLOT_ADDR=%04X", z->slotaddr) ||
+ 	    add_uevent_var(env, "MODALIAS=" ZORRO_DEVICE_MODALIAS_FMT, z->id))
+ 		return -ENOMEM;
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0045-m68k-Atari-GEMDOS-FAT-option-fix-use-correct-logic.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0045-m68k-Atari-GEMDOS-FAT-option-fix-use-correct-logic.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,35 @@
+From 4054de71aa8da1ac4c68ad0502d09d002ac0bd86 Mon Sep 17 00:00:00 2001
+From: Michael Schmitz <schmitz at biophys.uni-duesseldorf.de>
+Date: Sun, 19 Apr 2009 03:20:17 +0200
+Subject: [PATCH] m68k: Atari GEMDOS FAT option fix: use correct logical sector size
+
+Fix erroneous use of device blocksize instead of logical sector size in
+Atari GEMDOS FAT code (GEMDOS uses a 16 bit FAT and a constant 2 logical
+sectors per cluster, and modifies the logical sector size to cope with the
+limits imposed by the 16 bit FAT). The bug was probably introduced by me when
+porting this code forward from 2.4.
+With this fix, I can successfully mount GEMDOS partitons up to 256 MB in size as
+prepared by Petr Stehlik. 512 MB require 8k sector size, sorry.
+
+Signed-off-by: Michael Schmitz <schmitz at debian.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ fs/fat/inode.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/fs/fat/inode.c b/fs/fat/inode.c
+index ccb5c6e..4a2e049 100644
+--- a/fs/fat/inode.c
++++ b/fs/fat/inode.c
+@@ -1425,7 +1425,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
+ 		 * it's a real MSDOS partition with 12-bit fat.
+ 		 */
+ 		if (sbi->fat_bits != 32 && total_clusters+2 > sbi->
+-			fat_length*SECTOR_SIZE*8/sbi->fat_bits)
++			fat_length*sb->s_blocksize*8/sbi->fat_bits)
+ 			sbi->fat_bits = 12;
+ 		/* if it's a floppy disk --> 12bit fat */
+ 		if (sbi->fat_bits != 32 && MAJOR(sb->s_dev) == FLOPPY_MAJOR)
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0046-M68k-SERIAL_PORT_DFNS-only-if-CONFIG_ISA.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0046-M68k-SERIAL_PORT_DFNS-only-if-CONFIG_ISA.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,33 @@
+From e4cfaf4ea283cfdd6b70d970e232ab6efb6f7d81 Mon Sep 17 00:00:00 2001
+From: Kars de Jong <jongk at linux-m68k.org>
+Date: Tue, 18 Nov 2008 21:22:22 +0100
+Subject: [PATCH] M68k SERIAL_PORT_DFNS only if CONFIG_ISA
+
+M68k serial: Only define SERIAL_PORT_DFNS when CONFIG_ISA is defined. Otherwise
+the first 4 slots in the 8250 driver are unavailable on non-ISA machines.
+
+Signed-off-by: Kars de Jong <jongk at linux-m68k.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/include/asm/serial.h |    2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+
+diff --git a/arch/m68k/include/asm/serial.h b/arch/m68k/include/asm/serial.h
+index 2b90d6e..7267536 100644
+--- a/arch/m68k/include/asm/serial.h
++++ b/arch/m68k/include/asm/serial.h
+@@ -25,9 +25,11 @@
+ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF
+ #endif
+ 
++#ifdef CONFIG_ISA
+ #define SERIAL_PORT_DFNS			\
+ 	/* UART CLK   PORT IRQ     FLAGS        */			\
+ 	{ 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },	/* ttyS0 */	\
+ 	{ 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },	/* ttyS1 */	\
+ 	{ 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },	/* ttyS2 */	\
+ 	{ 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },	/* ttyS3 */
++#endif
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0047-aranym-Update-for-v2.6.31-block-layer-changes.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0047-aranym-Update-for-v2.6.31-block-layer-changes.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,26 @@
+From 9dfb7658ed3c31c986e5c724c1e4b9333ebf990c Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Mon, 17 Aug 2009 22:03:44 +0200
+Subject: [PATCH] aranym: Update for v2.6.31 block layer changes
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/emu/nfblock.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c
+index c131121..3d584f1 100644
+--- a/arch/m68k/emu/nfblock.c
++++ b/arch/m68k/emu/nfblock.c
+@@ -122,7 +122,7 @@ static int __init nfhd_init_one(int id, u32 blocks, u32 bsize)
+ 
+ 	dev->queue->queuedata = dev;
+ 	blk_queue_make_request(dev->queue, nfhd_make_request);
+-	blk_queue_hardsect_size(dev->queue, bsize);
++	blk_queue_logical_block_size(dev->queue, bsize);
+ 
+ 	dev->disk = alloc_disk(16);
+ 	if (!dev->disk)
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0048-aranym-Convert-to-net_device_ops.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0048-aranym-Convert-to-net_device_ops.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,50 @@
+From 507eeec8dadb53c77e52934c8c998541f7add9a9 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Mon, 17 Aug 2009 22:04:29 +0200
+Subject: [PATCH] aranym: Convert to net_device_ops
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+Tested-by: Andreas Schwab <schwab at linux-m68k.org>
+---
+ arch/m68k/emu/nfeth.c |   18 +++++++++++++-----
+ 1 files changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/arch/m68k/emu/nfeth.c b/arch/m68k/emu/nfeth.c
+index 5b118e9..f55dfd3 100644
+--- a/arch/m68k/emu/nfeth.c
++++ b/arch/m68k/emu/nfeth.c
+@@ -196,6 +196,17 @@ static struct net_device_stats *nfeth_get_stats(struct net_device *dev)
+ 	return &priv->stats;
+ }
+ 
++static const struct net_device_ops nfeth_netdev_ops = {
++	.ndo_open		= nfeth_open,
++	.ndo_stop		= nfeth_stop,
++	.ndo_start_xmit		= nfeth_xmit,
++	.ndo_tx_timeout		= nfeth_tx_timeout,
++	.ndo_get_stats		= nfeth_get_stats,
++	.ndo_validate_addr	= eth_validate_addr,
++	.ndo_change_mtu		= eth_change_mtu,
++	.ndo_set_mac_address	= eth_mac_addr,
++};
++
+ struct net_device * __init nfeth_probe(int unit)
+ {
+ 	struct net_device *dev;
+@@ -212,11 +223,8 @@ struct net_device * __init nfeth_probe(int unit)
+ 		return NULL;
+ 
+ 	dev->irq = nfEtherIRQ;
+-	dev->open = nfeth_open;
+-	dev->stop = nfeth_stop;
+-	dev->hard_start_xmit = nfeth_xmit;
+-	dev->tx_timeout = nfeth_tx_timeout;
+-	dev->get_stats = nfeth_get_stats;
++	dev->netdev_ops = &nfeth_netdev_ops;
++
+ 	dev->flags |= NETIF_F_NO_CSUM;
+ 	memcpy(dev->dev_addr, mac, ETH_ALEN);
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0049-ethernec-Convert-to-net_device_ops.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0049-ethernec-Convert-to-net_device_ops.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,61 @@
+From edd72a8e8bbc504071e561009cc6a536346df8c5 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Mon, 17 Aug 2009 22:05:03 +0200
+Subject: [PATCH] ethernec: Convert to net_device_ops
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/net/atari_ethernec.c |   23 +----------------------
+ 1 files changed, 1 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/net/atari_ethernec.c b/drivers/net/atari_ethernec.c
+index 05b5e2e..4fb22ce 100644
+--- a/drivers/net/atari_ethernec.c
++++ b/drivers/net/atari_ethernec.c
+@@ -199,9 +199,6 @@ bad_clone_list[] __initdata = {
+ static int ne_probe1(struct net_device *dev, int ioaddr);
+ static int ne_probe_isapnp(struct net_device *dev);
+ 
+-static int ne_open(struct net_device *dev);
+-static int ne_close(struct net_device *dev);
+-
+ static void ne_reset_8390(struct net_device *dev);
+ static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
+ 			    int ring_page);
+@@ -680,11 +677,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
+ 	ei_status.block_output = &ne_block_output;
+ 	ei_status.get_8390_hdr = &ne_get_8390_hdr;
+ 	ei_status.priv = 0;
+-	dev->open = &ne_open;
+-	dev->stop = &ne_close;
+-#ifdef CONFIG_NET_POLL_CONTROLLER
+-	dev->poll_controller = ei_poll;
+-#endif
++	dev->netdev_ops = &ei_netdev_ops;
+ 	NS8390_init(dev, 0);
+ 
+ 	ret = register_netdev(dev);
+@@ -699,20 +692,6 @@ err_out:
+ 	return ret;
+ }
+ 
+-static int ne_open(struct net_device *dev)
+-{
+-	ei_open(dev);
+-	return 0;
+-}
+-
+-static int ne_close(struct net_device *dev)
+-{
+-	if (ei_debug > 1)
+-		printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
+-	ei_close(dev);
+-	return 0;
+-}
+-
+ /* Hard reset the card.  This used to pause for the same period that a
+    8390 reset command required, but that shouldn't be necessary. */
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0050-rtc-Add-an-RTC-driver-for-the-Oki-MSM6242.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0050-rtc-Add-an-RTC-driver-for-the-Oki-MSM6242.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,324 @@
+From 8cfd7c59a2f3d0ef50082505b54ec918ab7648d2 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Wed, 18 Mar 2009 23:29:27 +0100
+Subject: [PATCH] rtc: Add an RTC driver for the Oki MSM6242
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+Acked-by: Alessandro Zummo <alessandro.zummo at towertech.it>
+---
+ drivers/rtc/Kconfig       |    9 ++
+ drivers/rtc/Makefile      |    1 +
+ drivers/rtc/rtc-msm6242.c |  269 +++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 279 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/rtc/rtc-msm6242.c
+
+diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
+index 3c20dae..16c8268 100644
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -509,6 +509,15 @@ config RTC_DRV_M48T59
+ 	  This driver can also be built as a module, if so, the module
+ 	  will be called "rtc-m48t59".
+ 
++config RTC_DRV_MSM6242
++	tristate "Oki MSM6242"
++	help
++	  If you say yes here you get support for the Oki MSM6242
++	  timekeeping chip. It is used in some Amiga models (e.g. A2000).
++
++	  This driver can also be built as a module. If so, the module
++	  will be called rtc-msm6242.
++
+ config RTC_MXC
+ 	tristate "Freescale MXC Real Time Clock"
+ 	depends on ARCH_MXC
+diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
+index aa3fbd5..7e704f6 100644
+--- a/drivers/rtc/Makefile
++++ b/drivers/rtc/Makefile
+@@ -52,6 +52,7 @@ obj-$(CONFIG_RTC_DRV_M48T86)	+= rtc-m48t86.o
+ obj-$(CONFIG_RTC_MXC)		+= rtc-mxc.o
+ obj-$(CONFIG_RTC_DRV_MAX6900)	+= rtc-max6900.o
+ obj-$(CONFIG_RTC_DRV_MAX6902)	+= rtc-max6902.o
++obj-$(CONFIG_RTC_DRV_MSM6242)	+= rtc-msm6242.o
+ obj-$(CONFIG_RTC_DRV_MV)	+= rtc-mv.o
+ obj-$(CONFIG_RTC_DRV_OMAP)	+= rtc-omap.o
+ obj-$(CONFIG_RTC_DRV_PCAP)	+= rtc-pcap.o
+diff --git a/drivers/rtc/rtc-msm6242.c b/drivers/rtc/rtc-msm6242.c
+new file mode 100644
+index 0000000..5f5968a
+--- /dev/null
++++ b/drivers/rtc/rtc-msm6242.c
+@@ -0,0 +1,269 @@
++/*
++ *  Oki MSM6242 RTC Driver
++ *
++ *  Copyright 2009 Geert Uytterhoeven
++ *
++ *  Based on the A2000 TOD code in arch/m68k/amiga/config.c
++ *  Copyright (C) 1993 Hamish Macdonald
++ */
++
++#include <linux/delay.h>
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/rtc.h>
++
++
++enum {
++	MSM6242_SECOND1		= 0x0,	/* 1-second digit register */
++	MSM6242_SECOND10	= 0x1,	/* 10-second digit register */
++	MSM6242_MINUTE1		= 0x2,	/* 1-minute digit register */
++	MSM6242_MINUTE10	= 0x3,	/* 10-minute digit register */
++	MSM6242_HOUR1		= 0x4,	/* 1-hour digit register */
++	MSM6242_HOUR10		= 0x5,	/* PM/AM, 10-hour digit register */
++	MSM6242_DAY1		= 0x6,	/* 1-day digit register */
++	MSM6242_DAY10		= 0x7,	/* 10-day digit register */
++	MSM6242_MONTH1		= 0x8,	/* 1-month digit register */
++	MSM6242_MONTH10		= 0x9,	/* 10-month digit register */
++	MSM6242_YEAR1		= 0xa,	/* 1-year digit register */
++	MSM6242_YEAR10		= 0xb,	/* 10-year digit register */
++	MSM6242_WEEK		= 0xc,	/* Week register */
++	MSM6242_CD		= 0xd,	/* Control Register D */
++	MSM6242_CE		= 0xe,	/* Control Register E */
++	MSM6242_CF		= 0xf,	/* Control Register F */
++};
++
++#define MSM6242_HOUR10_AM	(0 << 2)
++#define MSM6242_HOUR10_PM	(1 << 2)
++#define MSM6242_HOUR10_HR_MASK	(3 << 0)
++
++#define MSM6242_WEEK_SUNDAY	0
++#define MSM6242_WEEK_MONDAY	1
++#define MSM6242_WEEK_TUESDAY	2
++#define MSM6242_WEEK_WEDNESDAY	3
++#define MSM6242_WEEK_THURSDAY	4
++#define MSM6242_WEEK_FRIDAY	5
++#define MSM6242_WEEK_SATURDAY	6
++
++#define MSM6242_CD_30_S_ADJ	(1 << 3)	/* 30-second adjustment */
++#define MSM6242_CD_IRQ_FLAG	(1 << 2)
++#define MSM6242_CD_BUSY		(1 << 1)
++#define MSM6242_CD_HOLD		(1 << 0)
++
++#define MSM6242_CE_T_MASK	(3 << 2)
++#define MSM6242_CE_T_64HZ	(0 << 2)	/* period 1/64 second */
++#define MSM6242_CE_T_1HZ	(1 << 2)	/* period 1 second */
++#define MSM6242_CE_T_1MINUTE	(2 << 2)	/* period 1 minute */
++#define MSM6242_CE_T_1HOUR	(3 << 2)	/* period 1 hour */
++
++#define MSM6242_CE_ITRPT_STND	(1 << 1)
++#define MSM6242_CE_MASK		(1 << 0)	/* STD.P output control */
++
++#define MSM6242_CF_TEST		(1 << 3)
++#define MSM6242_CF_12H		(0 << 2)
++#define MSM6242_CF_24H		(1 << 2)
++#define MSM6242_CF_STOP		(1 << 1)
++#define MSM6242_CF_REST		(1 << 0)	/* reset */
++
++
++struct msm6242_priv {
++	u32 __iomem *regs;
++	struct rtc_device *rtc;
++};
++
++static inline unsigned int msm6242_read(struct msm6242_priv *priv,
++				       unsigned int reg)
++{
++	return __raw_readl(&priv->regs[reg]) & 0xf;
++}
++
++static inline void msm6242_write(struct msm6242_priv *priv, unsigned int val,
++				unsigned int reg)
++{
++	return __raw_writel(val, &priv->regs[reg]);
++}
++
++static inline void msm6242_set(struct msm6242_priv *priv, unsigned int val,
++			       unsigned int reg)
++{
++	msm6242_write(priv, msm6242_read(priv, reg) | val, reg);
++}
++
++static inline void msm6242_clear(struct msm6242_priv *priv, unsigned int val,
++				 unsigned int reg)
++{
++	msm6242_write(priv, msm6242_read(priv, reg) & ~val, reg);
++}
++
++static void msm6242_lock(struct msm6242_priv *priv)
++{
++	int cnt = 5;
++
++	msm6242_set(priv, MSM6242_CD_HOLD, MSM6242_CD);
++
++	while ((msm6242_read(priv, MSM6242_CD) & MSM6242_CD_BUSY) && cnt) {
++		msm6242_clear(priv, MSM6242_CD_HOLD, MSM6242_CD);
++		udelay(70);
++		msm6242_set(priv, MSM6242_CD_HOLD, MSM6242_CD);
++		cnt--;
++	}
++
++	if (!cnt)
++		pr_warning("msm6242: timed out waiting for RTC (0x%x)\n",
++			   msm6242_read(priv, MSM6242_CD));
++}
++
++static void msm6242_unlock(struct msm6242_priv *priv)
++{
++	msm6242_clear(priv, MSM6242_CD_HOLD, MSM6242_CD);
++}
++
++static int msm6242_read_time(struct device *dev, struct rtc_time *tm)
++{
++	struct msm6242_priv *priv = dev_get_drvdata(dev);
++
++	msm6242_lock(priv);
++
++	tm->tm_sec  = msm6242_read(priv, MSM6242_SECOND10) * 10 +
++		      msm6242_read(priv, MSM6242_SECOND1);
++	tm->tm_min  = msm6242_read(priv, MSM6242_MINUTE10) * 10 +
++		      msm6242_read(priv, MSM6242_MINUTE1);
++	tm->tm_hour = (msm6242_read(priv, MSM6242_HOUR10 & 3)) * 10 +
++		      msm6242_read(priv, MSM6242_HOUR1);
++	tm->tm_mday = msm6242_read(priv, MSM6242_DAY10) * 10 +
++		      msm6242_read(priv, MSM6242_DAY1);
++	tm->tm_wday = msm6242_read(priv, MSM6242_WEEK);
++	tm->tm_mon  = msm6242_read(priv, MSM6242_MONTH10) * 10 +
++		      msm6242_read(priv, MSM6242_MONTH1) - 1;
++	tm->tm_year = msm6242_read(priv, MSM6242_YEAR10) * 10 +
++		      msm6242_read(priv, MSM6242_YEAR1);
++	if (tm->tm_year <= 69)
++		tm->tm_year += 100;
++
++	if (!(msm6242_read(priv, MSM6242_CF) & MSM6242_CF_24H)) {
++		unsigned int pm = msm6242_read(priv, MSM6242_HOUR10) &
++				  MSM6242_HOUR10_PM;
++		if (!pm && tm->tm_hour == 12)
++			tm->tm_hour = 0;
++		else if (pm && tm->tm_hour != 12)
++			tm->tm_hour += 12;
++	}
++
++	msm6242_unlock(priv);
++
++	return rtc_valid_tm(tm);
++}
++
++static int msm6242_set_time(struct device *dev, struct rtc_time *tm)
++{
++	struct msm6242_priv *priv = dev_get_drvdata(dev);
++
++	msm6242_lock(priv);
++
++	msm6242_write(priv, tm->tm_sec / 10, MSM6242_SECOND10);
++	msm6242_write(priv, tm->tm_sec % 10, MSM6242_SECOND1);
++	msm6242_write(priv, tm->tm_min / 10, MSM6242_MINUTE10);
++	msm6242_write(priv, tm->tm_min % 10, MSM6242_MINUTE1);
++	if (msm6242_read(priv, MSM6242_CF) & MSM6242_CF_24H)
++		msm6242_write(priv, tm->tm_hour / 10, MSM6242_HOUR10);
++	else if (tm->tm_hour >= 12)
++		msm6242_write(priv, MSM6242_HOUR10_PM + (tm->tm_hour - 12) / 10,
++			      MSM6242_HOUR10);
++	else
++		msm6242_write(priv, tm->tm_hour / 10, MSM6242_HOUR10);
++	msm6242_write(priv, tm->tm_hour % 10, MSM6242_HOUR1);
++	msm6242_write(priv, tm->tm_mday / 10, MSM6242_DAY10);
++	msm6242_write(priv, tm->tm_mday % 10, MSM6242_DAY1);
++	if (tm->tm_wday != -1)
++		msm6242_write(priv, tm->tm_wday, MSM6242_WEEK);
++	msm6242_write(priv, (tm->tm_mon + 1) / 10, MSM6242_MONTH10);
++	msm6242_write(priv, (tm->tm_mon + 1) % 10, MSM6242_MONTH1);
++	if (tm->tm_year >= 100)
++		tm->tm_year -= 100;
++	msm6242_write(priv, tm->tm_year / 10, MSM6242_YEAR10);
++	msm6242_write(priv, tm->tm_year % 10, MSM6242_YEAR1);
++
++	msm6242_unlock(priv);
++	return 0;
++}
++
++static const struct rtc_class_ops msm6242_rtc_ops = {
++	.read_time	= msm6242_read_time,
++	.set_time	= msm6242_set_time,
++};
++
++static int __init msm6242_rtc_probe(struct platform_device *dev)
++{
++	struct resource *res;
++	struct msm6242_priv *priv;
++	struct rtc_device *rtc;
++	int error;
++
++	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
++	if (!res)
++		return -ENODEV;
++
++	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
++	if (!priv)
++		return -ENOMEM;
++
++	priv->regs = ioremap(res->start, resource_size(res));
++	if (!priv->regs) {
++		error = -ENOMEM;
++		goto out_free_priv;
++	}
++
++	rtc = rtc_device_register("rtc-msm6242", &dev->dev, &msm6242_rtc_ops,
++				  THIS_MODULE);
++	if (IS_ERR(rtc)) {
++		error = PTR_ERR(rtc);
++		goto out_unmap;
++	}
++
++	priv->rtc = rtc;
++	platform_set_drvdata(dev, priv);
++	return 0;
++
++out_unmap:
++	iounmap(priv->regs);
++out_free_priv:
++	kfree(priv);
++	return error;
++}
++
++static int __exit msm6242_rtc_remove(struct platform_device *dev)
++{
++	struct msm6242_priv *priv = platform_get_drvdata(dev);
++
++	rtc_device_unregister(priv->rtc);
++	iounmap(priv->regs);
++	kfree(priv);
++	return 0;
++}
++
++static struct platform_driver msm6242_rtc_driver = {
++	.driver	= {
++		.name	= "rtc-msm6242",
++		.owner	= THIS_MODULE,
++	},
++	.remove	= __exit_p(msm6242_rtc_remove),
++};
++
++static int __init msm6242_rtc_init(void)
++{
++	return platform_driver_probe(&msm6242_rtc_driver, msm6242_rtc_probe);
++}
++
++static void __exit msm6242_rtc_fini(void)
++{
++	platform_driver_unregister(&msm6242_rtc_driver);
++}
++
++module_init(msm6242_rtc_init);
++module_exit(msm6242_rtc_fini);
++
++MODULE_AUTHOR("Geert Uytterhoeven <geert at linux-m68k.org>");
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Oki MSM6242 RTC driver");
++MODULE_ALIAS("platform:rtc-msm6242");
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0051-rtc-Add-an-RTC-driver-for-the-Ricoh-RP5C01.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0051-rtc-Add-an-RTC-driver-for-the-Ricoh-RP5C01.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,278 @@
+From e575f96d03ae6f6d3e424156d9dd3ecceae81bac Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Wed, 18 Mar 2009 23:29:27 +0100
+Subject: [PATCH] rtc: Add an RTC driver for the Ricoh RP5C01
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+Acked-by: Alessandro Zummo <alessandro.zummo at towertech.it>
+---
+ drivers/rtc/Kconfig      |   10 ++
+ drivers/rtc/Makefile     |    1 +
+ drivers/rtc/rtc-rp5c01.c |  222 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 233 insertions(+), 0 deletions(-)
+ create mode 100644 drivers/rtc/rtc-rp5c01.c
+
+diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
+index 16c8268..4fcd36d 100644
+--- a/drivers/rtc/Kconfig
++++ b/drivers/rtc/Kconfig
+@@ -538,6 +538,16 @@ config RTC_DRV_BQ4802
+ 	  This driver can also be built as a module. If so, the module
+ 	  will be called rtc-bq4802.
+ 
++config RTC_DRV_RP5C01
++	tristate "Ricoh RP5C01"
++	help
++	  If you say yes here you get support for the Ricoh RP5C01
++	  timekeeping chip. It is used in some Amiga models (e.g. A3000
++	  and A4000).
++
++	  This driver can also be built as a module. If so, the module
++	  will be called rtc-rp5c01.
++
+ config RTC_DRV_V3020
+ 	tristate "EM Microelectronic V3020"
+ 	help
+diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
+index 7e704f6..af1ba7a 100644
+--- a/drivers/rtc/Makefile
++++ b/drivers/rtc/Makefile
+@@ -65,6 +65,7 @@ obj-$(CONFIG_RTC_DRV_PL031)	+= rtc-pl031.o
+ obj-$(CONFIG_RTC_DRV_PS3)	+= rtc-ps3.o
+ obj-$(CONFIG_RTC_DRV_PXA)	+= rtc-pxa.o
+ obj-$(CONFIG_RTC_DRV_R9701)	+= rtc-r9701.o
++obj-$(CONFIG_RTC_DRV_RP5C01)	+= rtc-rp5c01.o
+ obj-$(CONFIG_RTC_DRV_RS5C313)	+= rtc-rs5c313.o
+ obj-$(CONFIG_RTC_DRV_RS5C348)	+= rtc-rs5c348.o
+ obj-$(CONFIG_RTC_DRV_RS5C372)	+= rtc-rs5c372.o
+diff --git a/drivers/rtc/rtc-rp5c01.c b/drivers/rtc/rtc-rp5c01.c
+new file mode 100644
+index 0000000..e1313fe
+--- /dev/null
++++ b/drivers/rtc/rtc-rp5c01.c
+@@ -0,0 +1,222 @@
++/*
++ *  Ricoh RP5C01 RTC Driver
++ *
++ *  Copyright 2009 Geert Uytterhoeven
++ *
++ *  Based on the A3000 TOD code in arch/m68k/amiga/config.c
++ *  Copyright (C) 1993 Hamish Macdonald
++ */
++
++#include <linux/io.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/rtc.h>
++
++
++enum {
++	RP5C01_1_SECOND		= 0x0,	/* MODE 00 */
++	RP5C01_10_SECOND	= 0x1,	/* MODE 00 */
++	RP5C01_1_MINUTE		= 0x2,	/* MODE 00 and MODE 01 */
++	RP5C01_10_MINUTE	= 0x3,	/* MODE 00 and MODE 01 */
++	RP5C01_1_HOUR		= 0x4,	/* MODE 00 and MODE 01 */
++	RP5C01_10_HOUR		= 0x5,	/* MODE 00 and MODE 01 */
++	RP5C01_DAY_OF_WEEK	= 0x6,	/* MODE 00 and MODE 01 */
++	RP5C01_1_DAY		= 0x7,	/* MODE 00 and MODE 01 */
++	RP5C01_10_DAY		= 0x8,	/* MODE 00 and MODE 01 */
++	RP5C01_1_MONTH		= 0x9,	/* MODE 00 */
++	RP5C01_10_MONTH		= 0xa,	/* MODE 00 */
++	RP5C01_1_YEAR		= 0xb,	/* MODE 00 */
++	RP5C01_10_YEAR		= 0xc,	/* MODE 00 */
++
++	RP5C01_12_24_SELECT	= 0xa,	/* MODE 01 */
++	RP5C01_LEAP_YEAR	= 0xb,	/* MODE 01 */
++
++	RP5C01_MODE		= 0xd,	/* all modes */
++	RP5C01_TEST		= 0xe,	/* all modes */
++	RP5C01_RESET		= 0xf,	/* all modes */
++};
++
++#define RP5C01_12_24_SELECT_12	(0 << 0)
++#define RP5C01_12_24_SELECT_24	(1 << 0)
++
++#define RP5C01_10_HOUR_AM	(0 << 1)
++#define RP5C01_10_HOUR_PM	(1 << 1)
++
++#define RP5C01_MODE_TIMER_EN	(1 << 3)	/* timer enable */
++#define RP5C01_MODE_ALARM_EN	(1 << 2)	/* alarm enable */
++
++#define RP5C01_MODE_MODE_MASK	(3 << 0)
++#define RP5C01_MODE_MODE00	(0 << 0)	/* time */
++#define RP5C01_MODE_MODE01	(1 << 0)	/* alarm, 12h/24h, leap year */
++#define RP5C01_MODE_RAM_BLOCK10	(2 << 0)	/* RAM 4 bits x 13 */
++#define RP5C01_MODE_RAM_BLOCK11	(3 << 0)	/* RAM 4 bits x 13 */
++
++#define RP5C01_RESET_1HZ_PULSE	(1 << 3)
++#define RP5C01_RESET_16HZ_PULSE	(1 << 2)
++#define RP5C01_RESET_SECOND	(1 << 1)	/* reset divider stages for */
++						/* seconds or smaller units */
++#define RP5C01_RESET_ALARM	(1 << 0)	/* reset all alarm registers */
++
++
++struct rp5c01_priv {
++	u32 __iomem *regs;
++	struct rtc_device *rtc;
++};
++
++static inline unsigned int rp5c01_read(struct rp5c01_priv *priv,
++				       unsigned int reg)
++{
++	return __raw_readl(&priv->regs[reg]) & 0xf;
++}
++
++static inline void rp5c01_write(struct rp5c01_priv *priv, unsigned int val,
++				unsigned int reg)
++{
++	return __raw_writel(val, &priv->regs[reg]);
++}
++
++static void rp5c01_lock(struct rp5c01_priv *priv)
++{
++	rp5c01_write(priv, RP5C01_MODE_MODE00, RP5C01_MODE);
++}
++
++static void rp5c01_unlock(struct rp5c01_priv *priv)
++{
++	rp5c01_write(priv, RP5C01_MODE_TIMER_EN | RP5C01_MODE_MODE01,
++		     RP5C01_MODE);
++}
++
++static int rp5c01_read_time(struct device *dev, struct rtc_time *tm)
++{
++	struct rp5c01_priv *priv = dev_get_drvdata(dev);
++
++	rp5c01_lock(priv);
++
++	tm->tm_sec  = rp5c01_read(priv, RP5C01_10_SECOND) * 10 +
++		      rp5c01_read(priv, RP5C01_1_SECOND);
++	tm->tm_min  = rp5c01_read(priv, RP5C01_10_MINUTE) * 10 +
++		      rp5c01_read(priv, RP5C01_1_MINUTE);
++	tm->tm_hour = rp5c01_read(priv, RP5C01_10_HOUR) * 10 +
++		      rp5c01_read(priv, RP5C01_1_HOUR);
++	tm->tm_mday = rp5c01_read(priv, RP5C01_10_DAY) * 10 +
++		      rp5c01_read(priv, RP5C01_1_DAY);
++	tm->tm_wday = rp5c01_read(priv, RP5C01_DAY_OF_WEEK);
++	tm->tm_mon  = rp5c01_read(priv, RP5C01_10_MONTH) * 10 +
++		      rp5c01_read(priv, RP5C01_1_MONTH) - 1;
++	tm->tm_year = rp5c01_read(priv, RP5C01_10_YEAR) * 10 +
++		      rp5c01_read(priv, RP5C01_1_YEAR);
++	if (tm->tm_year <= 69)
++		tm->tm_year += 100;
++
++	rp5c01_unlock(priv);
++
++	return rtc_valid_tm(tm);
++}
++
++static int rp5c01_set_time(struct device *dev, struct rtc_time *tm)
++{
++	struct rp5c01_priv *priv = dev_get_drvdata(dev);
++
++	rp5c01_lock(priv);
++
++	rp5c01_write(priv, tm->tm_sec / 10, RP5C01_10_SECOND);
++	rp5c01_write(priv, tm->tm_sec % 10, RP5C01_1_SECOND);
++	rp5c01_write(priv, tm->tm_min / 10, RP5C01_10_MINUTE);
++	rp5c01_write(priv, tm->tm_min % 10, RP5C01_1_MINUTE);
++	rp5c01_write(priv, tm->tm_hour / 10, RP5C01_10_HOUR);
++	rp5c01_write(priv, tm->tm_hour % 10, RP5C01_1_HOUR);
++	rp5c01_write(priv, tm->tm_mday / 10, RP5C01_10_DAY);
++	rp5c01_write(priv, tm->tm_mday % 10, RP5C01_1_DAY);
++	if (tm->tm_wday != -1)
++		rp5c01_write(priv, tm->tm_wday, RP5C01_DAY_OF_WEEK);
++	rp5c01_write(priv, (tm->tm_mon + 1) / 10, RP5C01_10_MONTH);
++	rp5c01_write(priv, (tm->tm_mon + 1) % 10, RP5C01_1_MONTH);
++	if (tm->tm_year >= 100)
++		tm->tm_year -= 100;
++	rp5c01_write(priv, tm->tm_year / 10, RP5C01_10_YEAR);
++	rp5c01_write(priv, tm->tm_year % 10, RP5C01_1_YEAR);
++
++	rp5c01_unlock(priv);
++	return 0;
++}
++
++static const struct rtc_class_ops rp5c01_rtc_ops = {
++	.read_time	= rp5c01_read_time,
++	.set_time	= rp5c01_set_time,
++};
++
++static int __init rp5c01_rtc_probe(struct platform_device *dev)
++{
++	struct resource *res;
++	struct rp5c01_priv *priv;
++	struct rtc_device *rtc;
++	int error;
++
++	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
++	if (!res)
++		return -ENODEV;
++
++	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
++	if (!priv)
++		return -ENOMEM;
++
++	priv->regs = ioremap(res->start, resource_size(res));
++	if (!priv->regs) {
++		error = -ENOMEM;
++		goto out_free_priv;
++	}
++
++	rtc = rtc_device_register("rtc-rp5c01", &dev->dev, &rp5c01_rtc_ops,
++				  THIS_MODULE);
++	if (IS_ERR(rtc)) {
++		error = PTR_ERR(rtc);
++		goto out_unmap;
++	}
++
++	priv->rtc = rtc;
++	platform_set_drvdata(dev, priv);
++	return 0;
++
++out_unmap:
++	iounmap(priv->regs);
++out_free_priv:
++	kfree(priv);
++	return error;
++}
++
++static int __exit rp5c01_rtc_remove(struct platform_device *dev)
++{
++	struct rp5c01_priv *priv = platform_get_drvdata(dev);
++
++	rtc_device_unregister(priv->rtc);
++	iounmap(priv->regs);
++	kfree(priv);
++	return 0;
++}
++
++static struct platform_driver rp5c01_rtc_driver = {
++	.driver	= {
++		.name	= "rtc-rp5c01",
++		.owner	= THIS_MODULE,
++	},
++	.remove	= __exit_p(rp5c01_rtc_remove),
++};
++
++static int __init rp5c01_rtc_init(void)
++{
++	return platform_driver_probe(&rp5c01_rtc_driver, rp5c01_rtc_probe);
++}
++
++static void __exit rp5c01_rtc_fini(void)
++{
++	platform_driver_unregister(&rp5c01_rtc_driver);
++}
++
++module_init(rp5c01_rtc_init);
++module_exit(rp5c01_rtc_fini);
++
++MODULE_AUTHOR("Geert Uytterhoeven <geert at linux-m68k.org>");
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Ricoh RP5C01 RTC driver");
++MODULE_ALIAS("platform:rtc-rp5c01");
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0052-m68k-use-generic-code-for-ptrace-requests.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0052-m68k-use-generic-code-for-ptrace-requests.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,168 @@
+From f0df3c29d1684f0e1a745dc42940807f249875a2 Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <schwab at linux-m68k.org>
+Date: Sun, 10 May 2009 21:14:52 +0200
+Subject: [PATCH] m68k: use generic code for ptrace requests
+
+Remove all but PTRACE_{PEEK,POKE}USR and PTRACE_{GET,SET}{REGS,FPREGS}
+from arch_ptrace and let the rest be handled by generic code.  Define
+PTRACE_SINGLEBLOCK to enable singleblock tracing.
+[Geert] Not yet applicable for m68knommu
+
+Signed-off-by: Andreas Schwab <schwab at linux-m68k.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/include/asm/ptrace.h |   17 +++++++++
+ arch/m68k/kernel/ptrace.c      |   75 +++++++++++----------------------------
+ 2 files changed, 38 insertions(+), 54 deletions(-)
+
+diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h
+index 8c9194b..117adb1 100644
+--- a/arch/m68k/include/asm/ptrace.h
++++ b/arch/m68k/include/asm/ptrace.h
+@@ -71,6 +71,8 @@ struct switch_stack {
+ #define PTRACE_GETFPREGS          14
+ #define PTRACE_SETFPREGS          15
+ 
++#define PTRACE_SINGLEBLOCK	33	/* resume execution until next branch */
++
+ #ifdef __KERNEL__
+ 
+ #ifndef PS_S
+@@ -82,6 +84,21 @@ struct switch_stack {
+ #define instruction_pointer(regs) ((regs)->pc)
+ #define profile_pc(regs) instruction_pointer(regs)
+ extern void show_regs(struct pt_regs *);
++
++/*
++ * These are defined as per linux/ptrace.h, which see.
++ */
++struct task_struct;
++
++#ifdef CONFIG_MMU
++#define arch_has_single_step()	(1)
++extern void user_enable_single_step(struct task_struct *);
++extern void user_disable_single_step(struct task_struct *);
++
++#define arch_has_block_step()	(1)
++extern void user_enable_block_step(struct task_struct *);
++#endif
++
+ #endif /* __KERNEL__ */
+ #endif /* __ASSEMBLY__ */
+ #endif /* _M68K_PTRACE_H */
+diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
+index 2075543..bd08420 100644
+--- a/arch/m68k/kernel/ptrace.c
++++ b/arch/m68k/kernel/ptrace.c
+@@ -35,7 +35,9 @@
+ #define SR_MASK 0x001f
+ 
+ /* sets the trace bits. */
+-#define TRACE_BITS 0x8000
++#define TRACE_BITS 0xC000
++#define T1_BIT 0x8000
++#define T0_BIT 0x4000
+ 
+ /* Find the stack offset for a register, relative to thread.esp0. */
+ #define PT_REG(reg)	((long)&((struct pt_regs *)0)->reg)
+@@ -118,18 +120,30 @@ void ptrace_disable(struct task_struct *child)
+ 	singlestep_disable(child);
+ }
+ 
++void user_enable_single_step(struct task_struct *child)
++{
++	unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
++	put_reg(child, PT_SR, tmp | (T1_BIT << 16));
++	set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
++}
++
++void user_enable_block_step(struct task_struct *child)
++{
++	unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
++	put_reg(child, PT_SR, tmp | (T0_BIT << 16));
++}
++
++void user_disable_single_step(struct task_struct *child)
++{
++	singlestep_disable(child);
++}
++
+ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ {
+ 	unsigned long tmp;
+ 	int i, ret = 0;
+ 
+ 	switch (request) {
+-	/* when I and D space are separate, these will need to be fixed. */
+-	case PTRACE_PEEKTEXT:	/* read word at location addr. */
+-	case PTRACE_PEEKDATA:
+-		ret = generic_ptrace_peekdata(child, addr, data);
+-		break;
+-
+ 	/* read the word at location addr in the USER area. */
+ 	case PTRACE_PEEKUSR:
+ 		if (addr & 3)
+@@ -153,12 +167,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ 		ret = put_user(tmp, (unsigned long *)data);
+ 		break;
+ 
+-	/* when I and D space are separate, this will have to be fixed. */
+-	case PTRACE_POKETEXT:	/* write the word at location addr. */
+-	case PTRACE_POKEDATA:
+-		ret = generic_ptrace_pokedata(child, addr, data);
+-		break;
+-
+ 	case PTRACE_POKEUSR:	/* write the word at location addr in the USER area */
+ 		if (addr & 3)
+ 			goto out_eio;
+@@ -185,47 +193,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ 			goto out_eio;
+ 		break;
+ 
+-	case PTRACE_SYSCALL:	/* continue and stop at next (return from) syscall */
+-	case PTRACE_CONT:	/* restart after signal. */
+-		if (!valid_signal(data))
+-			goto out_eio;
+-
+-		if (request == PTRACE_SYSCALL)
+-			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+-		else
+-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+-		child->exit_code = data;
+-		singlestep_disable(child);
+-		wake_up_process(child);
+-		break;
+-
+-	/*
+-	 * make the child exit.  Best I can do is send it a sigkill.
+-	 * perhaps it should be put in the status that it wants to
+-	 * exit.
+-	 */
+-	case PTRACE_KILL:
+-		if (child->exit_state == EXIT_ZOMBIE) /* already dead */
+-			break;
+-		child->exit_code = SIGKILL;
+-		singlestep_disable(child);
+-		wake_up_process(child);
+-		break;
+-
+-	case PTRACE_SINGLESTEP:	/* set the trap flag. */
+-		if (!valid_signal(data))
+-			goto out_eio;
+-
+-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+-		tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
+-		put_reg(child, PT_SR, tmp);
+-		set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
+-
+-		child->exit_code = data;
+-		/* give it a chance to run. */
+-		wake_up_process(child);
+-		break;
+-
+ 	case PTRACE_GETREGS:	/* Get all gp regs from the child. */
+ 		for (i = 0; i < 19; i++) {
+ 			tmp = get_reg(child, i);
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0053-m68k-ptrace-fixes.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0053-m68k-ptrace-fixes.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,167 @@
+From f9150330da0f0e0bc89b8fc8699b0cb1ebedd6a0 Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <schwab at linux-m68k.org>
+Date: Tue, 19 May 2009 15:38:01 +0200
+Subject: [PATCH] m68k: ptrace fixes
+
+This fixes the following issues in ptrace:
+
+- when single stepping into the signal handler stop at the first insn of
+  the handler
+- handle non-zero stkadj when accessing pc and sr in ptregs
+- correctly handle PT_SR in PTRACE_POKEUSR
+- report -EIO when trying to read unknown offset in PTRACE_PEEKUSR
+
+Additionally, the handling of the special case that PT_SR accesses a 16
+bit word instead of a 32 bit word has been moved into get_reg/put_reg.
+
+Signed-off-by: Andreas Schwab <schwab at linux-m68k.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/kernel/entry.S  |    6 +++++-
+ arch/m68k/kernel/ptrace.c |   45 +++++++++++++++++++++++++++++----------------
+ 2 files changed, 34 insertions(+), 17 deletions(-)
+
+diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
+index c5b3363..77fc7c1 100644
+--- a/arch/m68k/kernel/entry.S
++++ b/arch/m68k/kernel/entry.S
+@@ -179,7 +179,11 @@ do_signal_return:
+ 	addql	#8,%sp
+ 	RESTORE_SWITCH_STACK
+ 	addql	#4,%sp
+-	jbra	resume_userspace
++	tstl	%d0
++	jeq	resume_userspace
++	| when single stepping into handler stop at the first insn
++	btst	#6,%curptr@(TASK_INFO+TINFO_FLAGS+2)
++	jeq	resume_userspace
+ 
+ do_delayed_trace:
+ 	bclr	#7,%sp@(PT_OFF_SR)	| clear trace bit in SR
+diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
+index bd08420..1fc217e 100644
+--- a/arch/m68k/kernel/ptrace.c
++++ b/arch/m68k/kernel/ptrace.c
+@@ -46,7 +46,7 @@
+ /* Mapping from PT_xxx to the stack offset at which the register is
+    saved.  Notice that usp has no stack-slot and needs to be treated
+    specially (see get_reg/put_reg below). */
+-static int regoff[] = {
++static const int regoff[] = {
+ 	[0]	= PT_REG(d1),
+ 	[1]	= PT_REG(d2),
+ 	[2]	= PT_REG(d3),
+@@ -81,6 +81,14 @@ static inline long get_reg(struct task_struct *task, int regno)
+ 		addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
+ 	else
+ 		return 0;
++	/* Need to take stkadj into account. */
++	if (regno == PT_SR || regno == PT_PC) {
++		long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
++		addr = (unsigned long *) ((unsigned long)addr + stkadj);
++		/* The sr is actually a 16 bit register.  */
++		if (regno == PT_SR)
++			return *(unsigned short *)addr;
++	}
+ 	return *addr;
+ }
+ 
+@@ -98,6 +106,16 @@ static inline int put_reg(struct task_struct *task, int regno,
+ 		addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
+ 	else
+ 		return -1;
++	/* Need to take stkadj into account. */
++	if (regno == PT_SR || regno == PT_PC) {
++		long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
++		addr = (unsigned long *) ((unsigned long)addr + stkadj);
++		/* The sr is actually a 16 bit register.  */
++		if (regno == PT_SR) {
++			*(unsigned short *)addr = data;
++			return 0;
++		}
++	}
+ 	*addr = data;
+ 	return 0;
+ }
+@@ -107,7 +125,7 @@ static inline int put_reg(struct task_struct *task, int regno,
+  */
+ static inline void singlestep_disable(struct task_struct *child)
+ {
+-	unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
++	unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
+ 	put_reg(child, PT_SR, tmp);
+ 	clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
+ }
+@@ -122,15 +140,15 @@ void ptrace_disable(struct task_struct *child)
+ 
+ void user_enable_single_step(struct task_struct *child)
+ {
+-	unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+-	put_reg(child, PT_SR, tmp | (T1_BIT << 16));
++	unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
++	put_reg(child, PT_SR, tmp | T1_BIT);
+ 	set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
+ }
+ 
+ void user_enable_block_step(struct task_struct *child)
+ {
+-	unsigned long tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+-	put_reg(child, PT_SR, tmp | (T0_BIT << 16));
++	unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
++	put_reg(child, PT_SR, tmp | T0_BIT);
+ }
+ 
+ void user_disable_single_step(struct task_struct *child)
+@@ -152,8 +170,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ 
+ 		if (addr >= 0 && addr < 19) {
+ 			tmp = get_reg(child, addr);
+-			if (addr == PT_SR)
+-				tmp >>= 16;
+ 		} else if (addr >= 21 && addr < 49) {
+ 			tmp = child->thread.fp[addr - 21];
+ 			/* Convert internal fpu reg representation
+@@ -163,7 +179,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ 				tmp = ((tmp & 0xffff0000) << 15) |
+ 				      ((tmp & 0x0000ffff) << 16);
+ 		} else
+-			break;
++			goto out_eio;
+ 		ret = put_user(tmp, (unsigned long *)data);
+ 		break;
+ 
+@@ -174,9 +190,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ 
+ 		if (addr == PT_SR) {
+ 			data &= SR_MASK;
+-			data <<= 16;
+-			data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
+-		} else if (addr >= 0 && addr < 19) {
++			data |= get_reg(child, PT_SR) & ~SR_MASK;
++		}
++		if (addr >= 0 && addr < 19) {
+ 			if (put_reg(child, addr, data))
+ 				goto out_eio;
+ 		} else if (addr >= 21 && addr < 48) {
+@@ -196,8 +212,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ 	case PTRACE_GETREGS:	/* Get all gp regs from the child. */
+ 		for (i = 0; i < 19; i++) {
+ 			tmp = get_reg(child, i);
+-			if (i == PT_SR)
+-				tmp >>= 16;
+ 			ret = put_user(tmp, (unsigned long *)data);
+ 			if (ret)
+ 				break;
+@@ -212,8 +226,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ 				break;
+ 			if (i == PT_SR) {
+ 				tmp &= SR_MASK;
+-				tmp <<= 16;
+-				tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
++				tmp |= get_reg(child, PT_SR) & ~SR_MASK;
+ 			}
+ 			put_reg(child, i, tmp);
+ 			data += sizeof(long);
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0054-m68knommu-define-arch_has_single_step-and-friends.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0054-m68knommu-define-arch_has_single_step-and-friends.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,74 @@
+From 27f9373849427a25bee01903e43667d6584a3887 Mon Sep 17 00:00:00 2001
+From: Greg Ungerer <gerg at uclinux.org>
+Date: Tue, 7 Jul 2009 15:54:54 +1000
+Subject: [PATCH] m68knommu: define arch_has_single_step() and friends
+
+Towards adding CONFIG_UTRACE support for non-mmu m68k add
+arch_has_single_step, and its support functions user_enable_single_step()
+and user_disable_single_step().
+[Geert] m68k conflict resolution from linux-next
+
+Signed-off-by: Greg Ungerer <gerg at uclinux.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/include/asm/ptrace.h |    2 +-
+ arch/m68knommu/kernel/ptrace.c |   18 +++++++++++++++---
+ 2 files changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h
+index 117adb1..a6ab663 100644
+--- a/arch/m68k/include/asm/ptrace.h
++++ b/arch/m68k/include/asm/ptrace.h
+@@ -90,11 +90,11 @@ extern void show_regs(struct pt_regs *);
+  */
+ struct task_struct;
+ 
+-#ifdef CONFIG_MMU
+ #define arch_has_single_step()	(1)
+ extern void user_enable_single_step(struct task_struct *);
+ extern void user_disable_single_step(struct task_struct *);
+ 
++#ifdef CONFIG_MMU
+ #define arch_has_block_step()	(1)
+ extern void user_enable_block_step(struct task_struct *);
+ #endif
+diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
+index ef70ca0..4d38289 100644
+--- a/arch/m68knommu/kernel/ptrace.c
++++ b/arch/m68knommu/kernel/ptrace.c
+@@ -86,6 +86,20 @@ static inline int put_reg(struct task_struct *task, int regno,
+ 	return 0;
+ }
+ 
++void user_enable_single_step(struct task_struct *task)
++{
++	unsigned long srflags;
++	srflags = get_reg(task, PT_SR) | (TRACE_BITS << 16);
++	put_reg(task, PT_SR, srflags);
++}
++
++void user_disable_single_step(struct task_struct *task)
++{
++	unsigned long srflags;
++	srflags = get_reg(task, PT_SR) & ~(TRACE_BITS << 16);
++	put_reg(task, PT_SR, srflags);
++}
++
+ /*
+  * Called by kernel/ptrace.c when detaching..
+  *
+@@ -93,10 +107,8 @@ static inline int put_reg(struct task_struct *task, int regno,
+  */
+ void ptrace_disable(struct task_struct *child)
+ {
+-	unsigned long tmp;
+ 	/* make sure the single step bit is not set. */
+-	tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+-	put_reg(child, PT_SR, tmp);
++	user_disable_single_step(child);
+ }
+ 
+ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0055-m68k-Make-thread_info.h-usable-from-assembly.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0055-m68k-Make-thread_info.h-usable-from-assembly.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,47 @@
+From 975070251427e454ffd96735d70d8c7e1bd1864f Mon Sep 17 00:00:00 2001
+From: Tim Abbott <tabbott at ksplice.com>
+Date: Wed, 16 Sep 2009 12:44:25 -0400
+Subject: [PATCH] m68k: Make thread_info.h usable from assembly.
+
+[Geert] <asm/thread_info_mm.h> pulls in <asm/current.h>, which contains C only.
+So the include must be moved inside #ifndef __ASSEMBLY__.
+
+Signed-off-by: Tim Abbott <tabbott at ksplice.com>
+Cc: Geert Uytterhoeven <geert at linux-m68k.org>
+Cc: Roman Zippel <zippel at linux-m68k.org>
+Cc: linux-m68k at lists.linux-m68k.org
+Cc: Sam Ravnborg <sam at ravnborg.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/include/asm/thread_info_mm.h |    5 ++++-
+ 1 files changed, 4 insertions(+), 1 deletions(-)
+
+diff --git a/arch/m68k/include/asm/thread_info_mm.h b/arch/m68k/include/asm/thread_info_mm.h
+index b6da388..167e518 100644
+--- a/arch/m68k/include/asm/thread_info_mm.h
++++ b/arch/m68k/include/asm/thread_info_mm.h
+@@ -4,10 +4,12 @@
+ #ifndef ASM_OFFSETS_C
+ #include <asm/asm-offsets.h>
+ #endif
+-#include <asm/current.h>
+ #include <asm/types.h>
+ #include <asm/page.h>
+ 
++#ifndef __ASSEMBLY__
++#include <asm/current.h>
++
+ struct thread_info {
+ 	struct task_struct	*task;		/* main task structure */
+ 	unsigned long		flags;
+@@ -16,6 +18,7 @@ struct thread_info {
+ 	__u32 cpu; /* should always be 0 on m68k */
+ 	struct restart_block    restart_block;
+ };
++#endif /* __ASSEMBLY__ */
+ 
+ #define PREEMPT_ACTIVE		0x4000000
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0056-m68k-Cleanup-linker-scripts-using-new-linker-script.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0056-m68k-Cleanup-linker-scripts-using-new-linker-script.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,206 @@
+From 31a0a2a65f9f906e5d6857d3edc9deb62327f083 Mon Sep 17 00:00:00 2001
+From: Tim Abbott <tabbott at ksplice.com>
+Date: Sun, 27 Sep 2009 13:57:55 -0400
+Subject: [PATCH] m68k: Cleanup linker scripts using new linker script macros.
+
+Signed-off-by: Tim Abbott <tabbott at ksplice.com>
+Tested-by: Andreas Schwab <schwab at linux-m68k.org>
+Cc: Roman Zippel <zippel at linux-m68k.org>
+Cc: Sam Ravnborg <sam at ravnborg.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/kernel/vmlinux-std.lds  |   61 ++++++++-----------------------------
+ arch/m68k/kernel/vmlinux-sun3.lds |   54 ++++----------------------------
+ 2 files changed, 20 insertions(+), 95 deletions(-)
+
+diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds
+index 47eac19..878be5f 100644
+--- a/arch/m68k/kernel/vmlinux-std.lds
++++ b/arch/m68k/kernel/vmlinux-std.lds
+@@ -2,6 +2,7 @@
+ 
+ #include <asm-generic/vmlinux.lds.h>
+ #include <asm/page.h>
++#include <asm/thread_info.h>
+ 
+ OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
+ OUTPUT_ARCH(m68k)
+@@ -22,73 +23,37 @@ SECTIONS
+ 
+   _etext = .;			/* End of text section */
+ 
+-  . = ALIGN(16);		/* Exception table */
+-  __start___ex_table = .;
+-  __ex_table : { *(__ex_table) }
+-  __stop___ex_table = .;
++  EXCEPTION_TABLE(16)
+ 
+   RODATA
+ 
+-  .data : {			/* Data */
+-	DATA_DATA
+-	CONSTRUCTORS
+-	}
++  RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
+ 
+-  . = ALIGN(16);
+-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+-
+-  .bss : { *(.bss) }		/* BSS */
++  BSS_SECTION(0, 0, 0)
+ 
+   _edata = .;			/* End of data section */
+ 
+   /* will be freed after init */
+   . = ALIGN(PAGE_SIZE);		/* Init code and data */
+   __init_begin = .;
+-  .init.text : {
+-	_sinittext = .;
+-	INIT_TEXT
+-	_einittext = .;
+-  } :data
+-  .init.data : { INIT_DATA }
+-  . = ALIGN(16);
+-  __setup_start = .;
+-  .init.setup : { *(.init.setup) }
+-  __setup_end = .;
+-  __initcall_start = .;
+-  .initcall.init : {
+-	INITCALLS
+-  }
+-  __initcall_end = .;
+-  __con_initcall_start = .;
+-  .con_initcall.init : { *(.con_initcall.init) }
+-  __con_initcall_end = .;
++  INIT_TEXT_SECTION(PAGE_SIZE) :data
++  INIT_DATA_SECTION(16)
+   .m68k_fixup : {
+ 	__start_fixup = .;
+ 	*(.m68k_fixup)
+ 	__stop_fixup = .;
+   }
+-  SECURITY_INIT
+-#ifdef CONFIG_BLK_DEV_INITRD
+-  . = ALIGN(8192);
+-  __initramfs_start = .;
+-  .init.ramfs : { *(.init.ramfs) }
+-  __initramfs_end = .;
+-#endif
+   NOTES
+-  . = ALIGN(8192);
+-  __init_end = .;
+-
+-  .data.init_task : { *(.data.init_task) }	/* The initial task and kernel stack */
++  .init_end : {
++	/* This ALIGN be in a section so that _end is at the end of the
++	   load segment. */
++	. = ALIGN(PAGE_SIZE);
++	__init_end = .;
++  }
+ 
+   _end = . ;
+ 
+-  /* Stabs debugging sections.  */
+-  .stab 0 : { *(.stab) }
+-  .stabstr 0 : { *(.stabstr) }
+-  .stab.excl 0 : { *(.stab.excl) }
+-  .stab.exclstr 0 : { *(.stab.exclstr) }
+-  .stab.index 0 : { *(.stab.index) }
+-  .stab.indexstr 0 : { *(.stab.indexstr) }
++  STABS_DEBUG
+   .comment 0 : { *(.comment) }
+ 
+   /* Sections to be discarded */
+diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
+index 03efaf0..1ad6b7a 100644
+--- a/arch/m68k/kernel/vmlinux-sun3.lds
++++ b/arch/m68k/kernel/vmlinux-sun3.lds
+@@ -2,6 +2,7 @@
+ 
+ #include <asm-generic/vmlinux.lds.h>
+ #include <asm/page.h>
++#include <asm/thread_info.h>
+ 
+ OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
+ OUTPUT_ARCH(m68k)
+@@ -23,14 +24,8 @@ SECTIONS
+ 
+   _etext = .;			/* End of text section */
+ 
+-  .data : {			/* Data */
+-	DATA_DATA
+-	CONSTRUCTORS
+-	. = ALIGN(16);		/* Exception table */
+-	__start___ex_table = .;
+-	*(__ex_table)
+-	__stop___ex_table = .;
+-	} :data
++  EXCEPTION_TABLE(16) :data
++  RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE) :data
+   /* End of data goes *here* so that freeing init code works properly. */
+   _edata = .;
+   NOTES
+@@ -38,56 +33,21 @@ SECTIONS
+   /* will be freed after init */
+   . = ALIGN(PAGE_SIZE);	/* Init code and data */
+ __init_begin = .;
+-	.init.text : {
+-		_sinittext = .;
+-		INIT_TEXT
+-		_einittext = .;
+-	}
+-	.init.data : { INIT_DATA }
+-	. = ALIGN(16);
+-	__setup_start = .;
+-	.init.setup : { *(.init.setup) }
+-	__setup_end = .;
+-	__initcall_start = .;
+-	.initcall.init : {
+-		INITCALLS
+-	}
+-	__initcall_end = .;
+-	__con_initcall_start = .;
+-	.con_initcall.init : { *(.con_initcall.init) }
+-	__con_initcall_end = .;
++	INIT_TEXT_SECTION(PAGE_SIZE)
++	INIT_DATA_SECTION(16)
+ 	.m68k_fixup : {
+ 		__start_fixup = .;
+ 		*(.m68k_fixup)
+ 		__stop_fixup = .;
+ 	}
+-	SECURITY_INIT
+-#ifdef CONFIG_BLK_DEV_INITRD
+-	. = ALIGN(PAGE_SIZE);
+-	__initramfs_start = .;
+-	.init.ramfs : { *(.init.ramfs) }
+-	__initramfs_end = .;
+-#endif
+ 	. = ALIGN(PAGE_SIZE);
+ 	__init_end = .;
+-	.data.init.task : { *(.data.init_task) }
+-
+ 
+-  .bss : { *(.bss) }		/* BSS */
++  BSS_SECTION(0, 0, 0)
+ 
+   _end = . ;
+ 
+-  .crap : {
+-	/* Stabs debugging sections.  */
+-	*(.stab)
+-	*(.stabstr)
+-	*(.stab.excl)
+-	*(.stab.exclstr)
+-	*(.stab.index)
+-	*(.stab.indexstr)
+-	*(.comment)
+-	*(.note)
+-  }
++  STABS_DEBUG
+ 
+   /* Sections to be discarded */
+   DISCARDS
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0057-m68k-Remove-the-BKL-from-sys_execve.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0057-m68k-Remove-the-BKL-from-sys_execve.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,39 @@
+From 64323f8e056b6b98f38046a5e0a6879cb71f1a90 Mon Sep 17 00:00:00 2001
+From: John Kacur <jkacur at redhat.com>
+Date: Mon, 12 Oct 2009 23:09:24 +0200
+Subject: [PATCH] m68k: Remove the BKL from sys_execve
+
+This seems like a copy-and-paste from code that no-longer needs the BKL
+Just remove it.
+
+Signed-off-by: John Kacur <jkacur at redhat.com>
+Reviewed-by: Frederic Weisbecker <fweisbec at gmail.com>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/kernel/process.c |    5 +----
+ 1 files changed, 1 insertions(+), 4 deletions(-)
+
+diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
+index 41230c5..0529659 100644
+--- a/arch/m68k/kernel/process.c
++++ b/arch/m68k/kernel/process.c
+@@ -317,15 +317,12 @@ asmlinkage int sys_execve(char __user *name, char __user * __user *argv, char __
+ 	char * filename;
+ 	struct pt_regs *regs = (struct pt_regs *) &name;
+ 
+-	lock_kernel();
+ 	filename = getname(name);
+ 	error = PTR_ERR(filename);
+ 	if (IS_ERR(filename))
+-		goto out;
++		return error;
+ 	error = do_execve(filename, argv, envp, regs);
+ 	putname(filename);
+-out:
+-	unlock_kernel();
+ 	return error;
+ }
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0058-fbdev-atafb-add-palette-register-check.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0058-fbdev-atafb-add-palette-register-check.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,32 @@
+From a79967b31ff32bd7f720221b00d7f70cf0d62b48 Mon Sep 17 00:00:00 2001
+From: Krzysztof Helt <krzysztof.h1 at wp.pl>
+Date: Sat, 24 Oct 2009 17:18:23 +0200
+Subject: [PATCH] fbdev: atafb - add palette register check
+
+Add check if palette register number is in correct range
+for few drivers which miss it. The regno value comes
+indirectly from user space.
+
+Signed-off-by: Krzysztof Helt <krzysztof.h1 at wp.pl>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/video/atafb.c |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
+index 37624f7..b7687c5 100644
+--- a/drivers/video/atafb.c
++++ b/drivers/video/atafb.c
+@@ -2242,6 +2242,9 @@ static int ext_setcolreg(unsigned int regno, unsigned int red,
+ 	if (!external_vgaiobase)
+ 		return 1;
+ 
++	if (regno > 255)
++		return 1;
++
+ 	switch (external_card_type) {
+ 	case IS_VGA:
+ 		OUTB(0x3c8, regno);
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0059-m68k-don-t-export-static-inline-functions.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0059-m68k-don-t-export-static-inline-functions.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,40 @@
+From 620dd5863c18774ce5620ee41ccda710e8f9cc51 Mon Sep 17 00:00:00 2001
+From: Stephen Rothwell <sfr at canb.auug.org.au>
+Date: Sat, 14 Nov 2009 18:20:28 +1100
+Subject: [PATCH] m68k: don't export static inline functions
+
+These now cause errors due to changes present in linux-next:
+
+(__ksymtab_sorted+0x1258): undefined reference to `dio_dev_driver'
+(__ksymtab_sorted+0x4d48): undefined reference to `zorro_dev_driver'
+
+Signed-off-by: Stephen Rothwell <sfr at canb.auug.org.au>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/dio/dio-driver.c     |    1 -
+ drivers/zorro/zorro-driver.c |    1 -
+ 2 files changed, 0 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/dio/dio-driver.c b/drivers/dio/dio-driver.c
+index 9c0c9af..a7b174e 100644
+--- a/drivers/dio/dio-driver.c
++++ b/drivers/dio/dio-driver.c
+@@ -140,5 +140,4 @@ postcore_initcall(dio_driver_init);
+ EXPORT_SYMBOL(dio_match_device);
+ EXPORT_SYMBOL(dio_register_driver);
+ EXPORT_SYMBOL(dio_unregister_driver);
+-EXPORT_SYMBOL(dio_dev_driver);
+ EXPORT_SYMBOL(dio_bus_type);
+diff --git a/drivers/zorro/zorro-driver.c b/drivers/zorro/zorro-driver.c
+index 409244b..7ee2b6e 100644
+--- a/drivers/zorro/zorro-driver.c
++++ b/drivers/zorro/zorro-driver.c
+@@ -180,5 +180,4 @@ postcore_initcall(zorro_driver_init);
+ EXPORT_SYMBOL(zorro_match_device);
+ EXPORT_SYMBOL(zorro_register_driver);
+ EXPORT_SYMBOL(zorro_unregister_driver);
+-EXPORT_SYMBOL(zorro_dev_driver);
+ EXPORT_SYMBOL(zorro_bus_type);
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0060-m68k-parport_mfc3-Not-makes-it-a-bool-before-the.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0060-m68k-parport_mfc3-Not-makes-it-a-bool-before-the.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,28 @@
+From f6c6ed4aee64396c0a710bd93d86fdfaf9b38915 Mon Sep 17 00:00:00 2001
+From: Roel Kluin <roel.kluin at gmail.com>
+Date: Wed, 18 Nov 2009 23:54:12 +0100
+Subject: [PATCH] m68k: parport_mfc3 - Not makes it a bool before the comparison.
+
+Signed-off-by: Roel Kluin <roel.kluin at gmail.com>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/parport/parport_mfc3.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c
+index 6dec9ba..362db31 100644
+--- a/drivers/parport/parport_mfc3.c
++++ b/drivers/parport/parport_mfc3.c
+@@ -386,7 +386,7 @@ static void __exit parport_mfc3_exit(void)
+ 		if (!this_port[i])
+ 			continue;
+ 		parport_remove_port(this_port[i]);
+-		if (!this_port[i]->irq != PARPORT_IRQ_NONE) {
++		if (this_port[i]->irq != PARPORT_IRQ_NONE) {
+ 			if (--use_cnt == 0) 
+ 				free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops);
+ 		}
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0061-Keys-KEYCTL_SESSION_TO_PARENT-needs-TIF_NOTIFY_RESU.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0061-Keys-KEYCTL_SESSION_TO_PARENT-needs-TIF_NOTIFY_RESU.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,55 @@
+From 71a3336af473be2c53a2a1e915b60673b4426e15 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert at linux-m68k.org>
+Date: Sun, 13 Dec 2009 20:21:34 +0100
+Subject: [PATCH] Keys: KEYCTL_SESSION_TO_PARENT needs TIF_NOTIFY_RESUME architecture support
+
+As of commit ee18d64c1f632043a02e6f5ba5e045bb26a5465f ("KEYS: Add a keyctl to
+install a process's session keyring on its parent [try #6]"), CONFIG_KEYS=y
+fails to build on architectures that haven't implemented TIF_NOTIFY_RESUME yet:
+
+security/keys/keyctl.c: In function 'keyctl_session_to_parent':
+security/keys/keyctl.c:1312: error: 'TIF_NOTIFY_RESUME' undeclared (first use in this function)
+security/keys/keyctl.c:1312: error: (Each undeclared identifier is reported only once
+security/keys/keyctl.c:1312: error: for each function it appears in.)
+
+Make KEYCTL_SESSION_TO_PARENT depend on TIF_NOTIFY_RESUME until
+m68k, and xtensa have implemented it.
+
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+Signed-off-by: James Morris <jmorris at namei.org>
+Acked-by: Mike Frysinger <vapier at gentoo.org>
+---
+ security/keys/keyctl.c |   10 ++++++++++
+ 1 files changed, 10 insertions(+), 0 deletions(-)
+
+diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
+index 06ec722..1cad4c7 100644
+--- a/security/keys/keyctl.c
++++ b/security/keys/keyctl.c
+@@ -1236,6 +1236,7 @@ long keyctl_get_security(key_serial_t keyid,
+  */
+ long keyctl_session_to_parent(void)
+ {
++#ifdef TIF_NOTIFY_RESUME
+ 	struct task_struct *me, *parent;
+ 	const struct cred *mycred, *pcred;
+ 	struct cred *cred, *oldcred;
+@@ -1326,6 +1327,15 @@ not_permitted:
+ error_keyring:
+ 	key_ref_put(keyring_r);
+ 	return ret;
++
++#else /* !TIF_NOTIFY_RESUME */
++	/*
++	 * To be removed when TIF_NOTIFY_RESUME has been implemented on
++	 * m68k/xtensa
++	 */
++#warning TIF_NOTIFY_RESUME not implemented
++	return -EOPNOTSUPP;
++#endif /* !TIF_NOTIFY_RESUME */
+ }
+ 
+ /*****************************************************************************/
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0062-m68k-Fix-asm-swab.h-for-ColdFire.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0062-m68k-Fix-asm-swab.h-for-ColdFire.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,30 @@
+From d48458907bb7fc109ac03f178e7b225ec5fc6d54 Mon Sep 17 00:00:00 2001
+From: Maxim Kuvyrkov <maxim at codesourcery.com>
+Date: Fri, 2 Oct 2009 12:32:18 +0400
+Subject: [PATCH] m68k: Fix asm/swab.h for ColdFire
+
+Make asm/swab.h compatible with ColdFire ISA_B CPUs.
+
+Signed-off-by: Maxim Kuvyrkov <maxim at codesourcery.com>
+Acked-by: Greg Ungerer <gerg at uclinux.org>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/include/asm/swab.h |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/m68k/include/asm/swab.h b/arch/m68k/include/asm/swab.h
+index 5b754aa..b7b37a4 100644
+--- a/arch/m68k/include/asm/swab.h
++++ b/arch/m68k/include/asm/swab.h
+@@ -14,7 +14,7 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
+ }
+ 
+ #define __arch_swab32 __arch_swab32
+-#elif !defined(__uClinux__)
++#elif !defined(__mcoldfire__)
+ 
+ static inline __attribute_const__ __u32 __arch_swab32(__u32 val)
+ {
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0063-m68k-Add-NPTL-support.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0063-m68k-Add-NPTL-support.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,215 @@
+From f0a7c50a9100ebe90f1cfd1d5bea2a9fcc1160de Mon Sep 17 00:00:00 2001
+From: Maxim Kuvyrkov <maxim at codesourcery.com>
+Date: Mon, 7 Dec 2009 00:24:27 -0800
+Subject: [PATCH] m68k: Add NPTL support
+
+This patch adds several syscalls, that provide necessary
+functionality to support NPTL on m68k/ColdFire.
+The syscalls are get_thread_area, set_thread_area, atomic_cmpxchg_32 and
+atomic_barrier.
+The cmpxchg syscall is required for ColdFire as it doesn't support 'cas'
+instruction.
+
+Also a ptrace call PTRACE_GET_THREAD_AREA is added to allow debugger to
+inspect the TLS storage.
+
+Signed-off-by: Maxim Kuvyrkov <maxim at codesourcery.com>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/include/asm/ptrace.h         |    2 +
+ arch/m68k/include/asm/thread_info_mm.h |    1 +
+ arch/m68k/include/asm/unistd.h         |    6 ++-
+ arch/m68k/kernel/entry.S               |    4 ++
+ arch/m68k/kernel/process.c             |    4 ++
+ arch/m68k/kernel/ptrace.c              |    5 ++
+ arch/m68k/kernel/sys_m68k.c            |   81 ++++++++++++++++++++++++++++++++
+ 7 files changed, 102 insertions(+), 1 deletions(-)
+
+diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h
+index a6ab663..43ab86a 100644
+--- a/arch/m68k/include/asm/ptrace.h
++++ b/arch/m68k/include/asm/ptrace.h
+@@ -71,6 +71,8 @@ struct switch_stack {
+ #define PTRACE_GETFPREGS          14
+ #define PTRACE_SETFPREGS          15
+ 
++#define PTRACE_GET_THREAD_AREA    25
++
+ #define PTRACE_SINGLEBLOCK	33	/* resume execution until next branch */
+ 
+ #ifdef __KERNEL__
+diff --git a/arch/m68k/include/asm/thread_info_mm.h b/arch/m68k/include/asm/thread_info_mm.h
+index 167e518..67266c6 100644
+--- a/arch/m68k/include/asm/thread_info_mm.h
++++ b/arch/m68k/include/asm/thread_info_mm.h
+@@ -16,6 +16,7 @@ struct thread_info {
+ 	struct exec_domain	*exec_domain;	/* execution domain */
+ 	int			preempt_count;	/* 0 => preemptable, <0 => BUG */
+ 	__u32 cpu; /* should always be 0 on m68k */
++	unsigned long		tp_value;	/* thread pointer */
+ 	struct restart_block    restart_block;
+ };
+ #endif /* __ASSEMBLY__ */
+diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
+index 48b87f5..d72a71d 100644
+--- a/arch/m68k/include/asm/unistd.h
++++ b/arch/m68k/include/asm/unistd.h
+@@ -336,10 +336,14 @@
+ #define __NR_pwritev		330
+ #define __NR_rt_tgsigqueueinfo	331
+ #define __NR_perf_event_open	332
++#define __NR_get_thread_area	333
++#define __NR_set_thread_area	334
++#define __NR_atomic_cmpxchg_32	335
++#define __NR_atomic_barrier	336
+ 
+ #ifdef __KERNEL__
+ 
+-#define NR_syscalls		333
++#define NR_syscalls		337
+ 
+ #define __ARCH_WANT_IPC_PARSE_VERSION
+ #define __ARCH_WANT_OLD_READDIR
+diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
+index 77fc7c1..e136b8c 100644
+--- a/arch/m68k/kernel/entry.S
++++ b/arch/m68k/kernel/entry.S
+@@ -761,4 +761,8 @@ sys_call_table:
+ 	.long sys_pwritev		/* 330 */
+ 	.long sys_rt_tgsigqueueinfo
+ 	.long sys_perf_event_open
++	.long sys_get_thread_area
++	.long sys_set_thread_area
++	.long sys_atomic_cmpxchg_32	/* 335 */
++	.long sys_atomic_barrier
+ 
+diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
+index 0529659..17c3f32 100644
+--- a/arch/m68k/kernel/process.c
++++ b/arch/m68k/kernel/process.c
+@@ -251,6 +251,10 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
+ 
+ 	p->thread.usp = usp;
+ 	p->thread.ksp = (unsigned long)childstack;
++
++	if (clone_flags & CLONE_SETTLS)
++		task_thread_info(p)->tp_value = regs->d5;
++
+ 	/*
+ 	 * Must save the current SFC/DFC value, NOT the value when
+ 	 * the parent was last descheduled - RGH  10-08-96
+diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
+index 1fc217e..616e597 100644
+--- a/arch/m68k/kernel/ptrace.c
++++ b/arch/m68k/kernel/ptrace.c
+@@ -245,6 +245,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ 			ret = -EFAULT;
+ 		break;
+ 
++	case PTRACE_GET_THREAD_AREA:
++		ret = put_user(task_thread_info(child)->tp_value,
++			       (unsigned long __user *)data);
++		break;
++
+ 	default:
+ 		ret = ptrace_request(child, request, addr, data);
+ 		break;
+diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
+index 7deb402..1f0db88 100644
+--- a/arch/m68k/kernel/sys_m68k.c
++++ b/arch/m68k/kernel/sys_m68k.c
+@@ -28,6 +28,11 @@
+ #include <asm/traps.h>
+ #include <asm/page.h>
+ #include <asm/unistd.h>
++#include <linux/elf.h>
++#include <asm/tlb.h>
++
++asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
++			     unsigned long error_code);
+ 
+ /* common code for old and new mmaps */
+ static inline long do_mmap2(
+@@ -662,3 +667,79 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+ 			: "d" (__a), "d" (__b), "d" (__c));
+ 	return __res;
+ }
++
++asmlinkage unsigned long sys_get_thread_area(void)
++{
++	return current_thread_info()->tp_value;
++}
++
++asmlinkage int sys_set_thread_area(unsigned long tp)
++{
++	current_thread_info()->tp_value = tp;
++	return 0;
++}
++
++/* This syscall gets its arguments in A0 (mem), D2 (oldval) and
++   D1 (newval).  */
++asmlinkage int
++sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
++		      unsigned long __user * mem)
++{
++	/* This was borrowed from ARM's implementation.  */
++	for (;;) {
++		struct mm_struct *mm = current->mm;
++		pgd_t *pgd;
++		pmd_t *pmd;
++		pte_t *pte;
++		spinlock_t *ptl;
++		unsigned long mem_value;
++
++		down_read(&mm->mmap_sem);
++		pgd = pgd_offset(mm, (unsigned long)mem);
++		if (!pgd_present(*pgd))
++			goto bad_access;
++		pmd = pmd_offset(pgd, (unsigned long)mem);
++		if (!pmd_present(*pmd))
++			goto bad_access;
++		pte = pte_offset_map_lock(mm, pmd, (unsigned long)mem, &ptl);
++		if (!pte_present(*pte) || !pte_dirty(*pte)
++		    || !pte_write(*pte)) {
++			pte_unmap_unlock(pte, ptl);
++			goto bad_access;
++		}
++
++		mem_value = *mem;
++		if (mem_value == oldval)
++			*mem = newval;
++
++		pte_unmap_unlock(pte, ptl);
++		up_read(&mm->mmap_sem);
++		return mem_value;
++
++	      bad_access:
++		up_read(&mm->mmap_sem);
++		/* This is not necessarily a bad access, we can get here if
++		   a memory we're trying to write to should be copied-on-write.
++		   Make the kernel do the necessary page stuff, then re-iterate.
++		   Simulate a write access fault to do that.  */
++		{
++			/* The first argument of the function corresponds to
++			   D1, which is the first field of struct pt_regs.  */
++			struct pt_regs *fp = (struct pt_regs *)&newval;
++
++			/* '3' is an RMW flag.  */
++			if (do_page_fault(fp, (unsigned long)mem, 3))
++				/* If the do_page_fault() failed, we don't
++				   have anything meaningful to return.
++				   There should be a SIGSEGV pending for
++				   the process.  */
++				return 0xdeadbeef;
++		}
++	}
++}
++
++asmlinkage int sys_atomic_barrier(void)
++{
++	/* no code needed for uniprocs */
++	return 0;
++}
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0064-m68knommu-NPTL-support-for-uClinux.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0064-m68knommu-NPTL-support-for-uClinux.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,122 @@
+From 07f00ec0c2fc14e1868782acf14ac26e89fc9d43 Mon Sep 17 00:00:00 2001
+From: Maxim Kuvyrkov <maxim at codesourcery.com>
+Date: Sun, 6 Dec 2009 10:08:14 -0800
+Subject: [PATCH] m68knommu: NPTL support for uClinux
+
+Port syscalls for NPTL support to m68knommu.
+
+Signed-off-by: Maxim Kuvyrkov <maxim at codesourcery.com>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/include/asm/thread_info_no.h |    1 +
+ arch/m68knommu/kernel/process.c        |    4 +++
+ arch/m68knommu/kernel/ptrace.c         |    5 ++++
+ arch/m68knommu/kernel/sys_m68k.c       |   36 ++++++++++++++++++++++++++++++++
+ arch/m68knommu/kernel/syscalltable.S   |    4 +++
+ 5 files changed, 50 insertions(+), 0 deletions(-)
+
+diff --git a/arch/m68k/include/asm/thread_info_no.h b/arch/m68k/include/asm/thread_info_no.h
+index c2bde5e..567d18d 100644
+--- a/arch/m68k/include/asm/thread_info_no.h
++++ b/arch/m68k/include/asm/thread_info_no.h
+@@ -37,6 +37,7 @@ struct thread_info {
+ 	unsigned long	   flags;		/* low level flags */
+ 	int		   cpu;			/* cpu we're on */
+ 	int		   preempt_count;	/* 0 => preemptable, <0 => BUG */
++	unsigned long	   tp_value;		/* thread pointer */
+ 	struct restart_block restart_block;
+ };
+ 
+diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
+index 8f8f4ab..e685200 100644
+--- a/arch/m68knommu/kernel/process.c
++++ b/arch/m68knommu/kernel/process.c
+@@ -221,6 +221,10 @@ int copy_thread(unsigned long clone_flags,
+ 
+ 	p->thread.usp = usp;
+ 	p->thread.ksp = (unsigned long)childstack;
++
++	if (clone_flags & CLONE_SETTLS)
++		task_thread_info(p)->tp_value = regs->d5;
++
+ 	/*
+ 	 * Must save the current SFC/DFC value, NOT the value when
+ 	 * the parent was last descheduled - RGH  10-08-96
+diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
+index 4d38289..85ed2f9 100644
+--- a/arch/m68knommu/kernel/ptrace.c
++++ b/arch/m68knommu/kernel/ptrace.c
+@@ -319,6 +319,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ 		}
+ #endif
+ 
++	case PTRACE_GET_THREAD_AREA:
++		ret = put_user(task_thread_info(child)->tp_value,
++			       (unsigned long __user *)data);
++		break;
++
+ 		default:
+ 			ret = -EIO;
+ 			break;
+diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
+index efdd090..1a6efa8 100644
+--- a/arch/m68knommu/kernel/sys_m68k.c
++++ b/arch/m68knommu/kernel/sys_m68k.c
+@@ -224,3 +224,39 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[])
+ 			: "d" (__a), "d" (__b), "d" (__c));
+ 	return __res;
+ }
++
++asmlinkage unsigned long sys_get_thread_area(void)
++{
++	return current_thread_info()->tp_value;
++}
++
++asmlinkage int sys_set_thread_area(unsigned long tp)
++{
++	current_thread_info()->tp_value = tp;
++	return 0;
++}
++
++/* This syscall gets its arguments in A0 (mem), D2 (oldval) and
++   D1 (newval).  */
++asmlinkage int
++sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
++		      unsigned long __user * mem)
++{
++	struct mm_struct *mm = current->mm;
++	unsigned long mem_value;
++
++	down_read(&mm->mmap_sem);
++
++	mem_value = *mem;
++	if (mem_value == oldval)
++		*mem = newval;
++
++	up_read(&mm->mmap_sem);
++	return mem_value;
++}
++
++asmlinkage int sys_atomic_barrier(void)
++{
++	/* no code needed for uniprocs */
++	return 0;
++}
+diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S
+index 23535cc..144823d 100644
+--- a/arch/m68knommu/kernel/syscalltable.S
++++ b/arch/m68knommu/kernel/syscalltable.S
+@@ -351,6 +351,10 @@ ENTRY(sys_call_table)
+ 	.long sys_pwritev		/* 330 */
+ 	.long sys_rt_tgsigqueueinfo
+ 	.long sys_perf_event_open
++	.long sys_get_thread_area
++	.long sys_set_thread_area
++	.long sys_atomic_cmpxchg_32	/* 335 */
++	.long sys_atomic_barrier
+ 
+ 	.rept NR_syscalls-(.-sys_call_table)/4
+ 		.long sys_ni_syscall
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0065-m68k-Allow-ioremapping-top-of-memory.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0065-m68k-Allow-ioremapping-top-of-memory.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,30 @@
+From d1da3984ce2164eddc5708b425e814b7c11b5fd9 Mon Sep 17 00:00:00 2001
+From: Philippe De Muyter <phdm at macqel.be>
+Date: Sun, 6 Dec 2009 20:28:41 +0100
+Subject: [PATCH] m68k: Allow ioremapping top of memory
+
+The test in __ioremap to reject memory ranges crossing the 0 boundary
+rejects also memory ranges ending at the end of the memory.  Fix that.
+
+Signed-off-by: Philippe De Muyter <phdm at macqel.be>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/mm/kmap.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
+index df620ac..cf93cdd 100644
+--- a/arch/m68k/mm/kmap.c
++++ b/arch/m68k/mm/kmap.c
+@@ -116,7 +116,7 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla
+ 	/*
+ 	 * Don't allow mappings that wrap..
+ 	 */
+-	if (!size || size > physaddr + size)
++	if (!size || physaddr > (unsigned long)(-size))
+ 		return NULL;
+ 
+ #ifdef CONFIG_AMIGA
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0066-m68k-nommu-h8300-Remove-obsolete-comment-about-ma.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0066-m68k-nommu-h8300-Remove-obsolete-comment-about-ma.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,59 @@
+From 380353123de875344110d1667ed8b032a4e9581b Mon Sep 17 00:00:00 2001
+From: Philippe De Muyter <phdm at macqel.be>
+Date: Thu, 22 Oct 2009 16:07:17 +0200
+Subject: [PATCH] m68k{,nommu}/h8300: Remove obsolete comment about map_chunk
+
+Remove the comments referring to a function map_chunk that no longer exists.
+
+Signed-off-by: Philippe De Muyter <phdm at macqel.be>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/h8300/mm/memory.c     |    4 ++--
+ arch/m68k/mm/kmap.c        |    3 +--
+ arch/m68knommu/mm/memory.c |    1 -
+ 3 files changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/arch/h8300/mm/memory.c b/arch/h8300/mm/memory.c
+index ccd6ade..40d8aa8 100644
+--- a/arch/h8300/mm/memory.c
++++ b/arch/h8300/mm/memory.c
+@@ -44,8 +44,8 @@ void cache_push_v (unsigned long vaddr, int len)
+ {
+ }
+ 
+-/* Map some physical address range into the kernel address space. The
+- * code is copied and adapted from map_chunk().
++/*
++ * Map some physical address range into the kernel address space.
+  */
+ 
+ unsigned long kernel_map(unsigned long paddr, unsigned long size,
+diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
+index cf93cdd..6934584 100644
+--- a/arch/m68k/mm/kmap.c
++++ b/arch/m68k/mm/kmap.c
+@@ -99,8 +99,7 @@ static inline void free_io_area(void *addr)
+ #endif
+ 
+ /*
+- * Map some physical address range into the kernel address space. The
+- * code is copied and adapted from map_chunk().
++ * Map some physical address range into the kernel address space.
+  */
+ /* Rewritten by Andreas Schwab to remove all races. */
+ 
+diff --git a/arch/m68knommu/mm/memory.c b/arch/m68knommu/mm/memory.c
+index f93b88b..d5b9e13 100644
+--- a/arch/m68knommu/mm/memory.c
++++ b/arch/m68knommu/mm/memory.c
+@@ -24,7 +24,6 @@
+ 
+ /*
+  * Map some physical address range into the kernel address space.
+- * The code is copied and adapted from map_chunk().
+  */
+ 
+ unsigned long kernel_map(unsigned long paddr, unsigned long size,
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0067-m68k-vme_scc-__init-annotations.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0067-m68k-vme_scc-__init-annotations.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,75 @@
+From b04866808ebd15f10c6bf7a88206451919619a19 Mon Sep 17 00:00:00 2001
+From: Peter Huewe <peterhuewe at gmx.de>
+Date: Thu, 20 Aug 2009 22:42:31 +0200
+Subject: [PATCH] m68k: vme_scc - __init annotations
+
+Trivial patch which adds the __init macro to the module_init
+function and all of its helper functions of drivers/char/vme_scc.c
+
+Signed-off-by: Peter Huewe <peterhuewe at gmx.de>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ drivers/char/vme_scc.c |   12 ++++++------
+ 1 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
+index 994e1a5..8b24729 100644
+--- a/drivers/char/vme_scc.c
++++ b/drivers/char/vme_scc.c
+@@ -136,7 +136,7 @@ static const struct tty_port_operations scc_port_ops = {
+  * vme_scc_init() and support functions
+  *---------------------------------------------------------------------------*/
+ 
+-static int scc_init_drivers(void)
++static int __init scc_init_drivers(void)
+ {
+ 	int error;
+ 
+@@ -172,7 +172,7 @@ static int scc_init_drivers(void)
+ /* ports[] array is indexed by line no (i.e. [0] for ttyS0, [1] for ttyS1).
+  */
+ 
+-static void scc_init_portstructs(void)
++static void __init scc_init_portstructs(void)
+ {
+ 	struct scc_port *port;
+ 	int i;
+@@ -195,7 +195,7 @@ static void scc_init_portstructs(void)
+ 
+ 
+ #ifdef CONFIG_MVME147_SCC
+-static int mvme147_scc_init(void)
++static int __init mvme147_scc_init(void)
+ {
+ 	struct scc_port *port;
+ 	int error;
+@@ -298,7 +298,7 @@ fail:
+ 
+ 
+ #ifdef CONFIG_MVME162_SCC
+-static int mvme162_scc_init(void)
++static int __init mvme162_scc_init(void)
+ {
+ 	struct scc_port *port;
+ 	int error;
+@@ -404,7 +404,7 @@ fail:
+ 
+ 
+ #ifdef CONFIG_BVME6000_SCC
+-static int bvme6000_scc_init(void)
++static int __init bvme6000_scc_init(void)
+ {
+ 	struct scc_port *port;
+ 	int error;
+@@ -503,7 +503,7 @@ fail_free_b_rx:
+ #endif
+ 
+ 
+-static int vme_scc_init(void)
++static int __init vme_scc_init(void)
+ {
+ 	int res = -ENODEV;
+ 
+-- 
+1.5.6.5
+

Added: dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0068-m68k-Use-DIV_ROUND_CLOSEST.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/bugfix/m68k/fp/0068-m68k-Use-DIV_ROUND_CLOSEST.patch	Thu Oct  7 02:04:46 2010	(r16408)
@@ -0,0 +1,45 @@
+From fc4231b37d4f73c77bd504a2912d4ed323bf1a30 Mon Sep 17 00:00:00 2001
+From: Julia Lawall <julia at diku.dk>
+Date: Sun, 2 Aug 2009 10:47:47 +0200
+Subject: [PATCH] m68k: Use DIV_ROUND_CLOSEST
+
+The kernel.h macro DIV_ROUND_CLOSEST performs the computation (x + d/2)/d
+but is perhaps more readable.
+
+The semantic patch that makes this change is as follows:
+(http://www.emn.fr/x-info/coccinelle/)
+
+// <smpl>
+ at haskernel@
+@@
+
+ at depends on haskernel@
+expression x,__divisor;
+@@
+
+- (((x) + ((__divisor) / 2)) / (__divisor))
++ DIV_ROUND_CLOSEST(x,__divisor)
+// </smpl>
+
+Signed-off-by: Julia Lawall <julia at diku.dk>
+Signed-off-by: Geert Uytterhoeven <geert at linux-m68k.org>
+---
+ arch/m68k/amiga/config.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
+index dd349a1..a50e8ab 100644
+--- a/arch/m68k/amiga/config.c
++++ b/arch/m68k/amiga/config.c
+@@ -486,7 +486,7 @@ static void __init amiga_sched_init(irq_handler_t timer_routine)
+ 	static struct resource sched_res = {
+ 		.name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff,
+ 	};
+-	jiffy_ticks = (amiga_eclock+HZ/2)/HZ;
++	jiffy_ticks = DIV_ROUND_CLOSEST(amiga_eclock, HZ);
+ 
+ 	if (request_resource(&mb_resources._ciab, &sched_res))
+ 		printk("Cannot allocate ciab.ta{lo,hi}\n");
+-- 
+1.5.6.5
+

Modified: dists/sid/linux-2.6/debian/patches/series/25
==============================================================================
--- dists/sid/linux-2.6/debian/patches/series/25	Thu Oct  7 01:58:53 2010	(r16407)
+++ dists/sid/linux-2.6/debian/patches/series/25	Thu Oct  7 02:04:46 2010	(r16408)
@@ -5,3 +5,70 @@
 + bugfix/m68k/m68k_add_missing_io_macros.patch
 + debian/isdn-i4l-mark-as-staging.patch
 + debian/hisax-Disable-device-aliases-that-conflict-with-mISDN.patch
++ bugfix/m68k/fp/0001-m68k-Atari-ARAnyM-support.patch
++ bugfix/m68k/fp/0002-m68k-Export-ARAnyM-native-feature-API.patch
++ bugfix/m68k/fp/0003-m68k-Add-support-for-ARAnyM-block-and-console-acces.patch
++ bugfix/m68k/fp/0004-m68k-ARAnyM-early_param-does-not-exist-in-the-mod.patch
++ bugfix/m68k/fp/0005-m68k-Wrap-nfblock-natfeat-calls.patch
++ bugfix/m68k/fp/0006-m68k-Atari-EtherNAT-SMC91C111-driver.patch
++ bugfix/m68k/fp/0007-m68k-Atari-EtherNAT-updates.patch
++ bugfix/m68k/fp/0008-m68k-Atari-EtherNAT-warning-fixes.patch
++ bugfix/m68k/fp/0009-m68k-section-mismatch-fixes-EtherNAT.patch
++ bugfix/m68k/fp/0010-m68k-Atari-ROM-port-ISA-adapter-support.patch
++ bugfix/m68k/fp/0011-m68k-Atari-io.h-fixes-for-EtherNAT-driver.patch
++ bugfix/m68k/fp/0012-m68k-Atari-EtherNEC-driver.patch
++ bugfix/m68k/fp/0013-atari-ethernec-fixes.diff.patch
++ bugfix/m68k/fp/0014-m68k-Atari-SCC-serial-driver-needs-atari_SCC_init_d.patch
++ bugfix/m68k/fp/0015-m68k-Atari-SCC-serial-driver-needs-CONFIG_ATARI_SCC.patch
++ bugfix/m68k/fp/0016-m68k-Atari-SCC-serial-driver.patch
++ bugfix/m68k/fp/0017-m68k-Atari-SCC-serial-driver-checkpatch-cleanups.patch
++ bugfix/m68k/fp/0018-m68k-Atari-SCC-serial-driver-gs-update.patch
++ bugfix/m68k/fp/0019-m68k-Atari-SCC-serial-driver-break_ctl-update.patch
++ bugfix/m68k/fp/0020-m68k-Disable-Atari-serial-console-support-if-modula.patch
++ bugfix/m68k/fp/0021-m68k-Atari-SCC-support-for-ST.patch
++ bugfix/m68k/fp/0022-m68k-atari_scc-kill-warn_unused_result-warnings.patch
++ bugfix/m68k/fp/0023-m68k-atari_scc-kill-fake-config-variables.patch
++ bugfix/m68k/fp/0024-Revert-msdos-fs-remove-unsettable-atari-option.patch
++ bugfix/m68k/fp/0025-Atari-FAT-updates.patch
++ bugfix/m68k/fp/0026-Add-Amiga-Zorro-bus-modalias-support.patch
++ bugfix/m68k/fp/0027-m68k-Fix-debug-mem-on-Amiga.patch
++ bugfix/m68k/fp/0028-m68k-allow-all-kernel-traps-to-be-handled-via-except.patch
++ bugfix/m68k/fp/0029-m68k-Add-support-for-EARLY_PRINTK-on-MVME16x.patch
++ bugfix/m68k/fp/0030-Update-for-m68k-Add-support-for-EARLY_PRINTK-on-MVM.patch
++ bugfix/m68k/fp/0031-m68k-atari_scc-Upstream-updates.patch
++ bugfix/m68k/fp/0032-m68k-atari-Rename-mfp-to-st_mfp.patch
++ bugfix/m68k/fp/0033-atari-Use-the-correct-mouse-interrupt-hook.patch
++ bugfix/m68k/fp/0034-m68k-Fix-atarimouse-init.patch
++ bugfix/m68k/fp/0035-ADB-raw-packets.patch
++ bugfix/m68k/fp/0036-m68k-Update-defconfigs-for-new-m68k-features.patch
++ bugfix/m68k/fp/0037-arch-m68k-emu-nfeth.c-doesn-t-need-obsolete-net-iee.patch
++ bugfix/m68k/fp/0038-m68k-z2ram-correct-printing-of-sector_t.patch
++ bugfix/m68k/fp/0039-m68k-Atari-SCC-verbosity-fix.patch
++ bugfix/m68k/fp/0040-m68k-Atari-EtherNAT-replace-bus_id-with-dev_name.patch
++ bugfix/m68k/fp/0041-m68k-Atari-EtherNAT-use-struct-net_device_ops.patch
++ bugfix/m68k/fp/0042-m68k-Hydra-Ethernet-correct-printing-of-resource_.patch
++ bugfix/m68k/fp/0043-scsi-Clean-up-mvme147.c.patch
++ bugfix/m68k/fp/0044-zorro-use-dev_name-instead-of-obsolete-device.bus.patch
++ bugfix/m68k/fp/0045-m68k-Atari-GEMDOS-FAT-option-fix-use-correct-logic.patch
++ bugfix/m68k/fp/0046-M68k-SERIAL_PORT_DFNS-only-if-CONFIG_ISA.patch
++ bugfix/m68k/fp/0047-aranym-Update-for-v2.6.31-block-layer-changes.patch
++ bugfix/m68k/fp/0048-aranym-Convert-to-net_device_ops.patch
++ bugfix/m68k/fp/0049-ethernec-Convert-to-net_device_ops.patch
++ bugfix/m68k/fp/0050-rtc-Add-an-RTC-driver-for-the-Oki-MSM6242.patch
++ bugfix/m68k/fp/0051-rtc-Add-an-RTC-driver-for-the-Ricoh-RP5C01.patch
++ bugfix/m68k/fp/0052-m68k-use-generic-code-for-ptrace-requests.patch
++ bugfix/m68k/fp/0053-m68k-ptrace-fixes.patch
++ bugfix/m68k/fp/0054-m68knommu-define-arch_has_single_step-and-friends.patch
++ bugfix/m68k/fp/0055-m68k-Make-thread_info.h-usable-from-assembly.patch
++ bugfix/m68k/fp/0056-m68k-Cleanup-linker-scripts-using-new-linker-script.patch
++ bugfix/m68k/fp/0057-m68k-Remove-the-BKL-from-sys_execve.patch
++ bugfix/m68k/fp/0058-fbdev-atafb-add-palette-register-check.patch
++ bugfix/m68k/fp/0059-m68k-don-t-export-static-inline-functions.patch
++ bugfix/m68k/fp/0060-m68k-parport_mfc3-Not-makes-it-a-bool-before-the.patch
++ bugfix/m68k/fp/0061-Keys-KEYCTL_SESSION_TO_PARENT-needs-TIF_NOTIFY_RESU.patch
++ bugfix/m68k/fp/0062-m68k-Fix-asm-swab.h-for-ColdFire.patch
++ bugfix/m68k/fp/0064-m68knommu-NPTL-support-for-uClinux.patch
++ bugfix/m68k/fp/0065-m68k-Allow-ioremapping-top-of-memory.patch
++ bugfix/m68k/fp/0066-m68k-nommu-h8300-Remove-obsolete-comment-about-ma.patch
++ bugfix/m68k/fp/0067-m68k-vme_scc-__init-annotations.patch
++ bugfix/m68k/fp/0068-m68k-Use-DIV_ROUND_CLOSEST.patch



More information about the Kernel-svn-changes mailing list