diff options
| -rw-r--r-- | target/linux/aruba-2.6/config/default | 2 | ||||
| -rw-r--r-- | target/linux/aruba-2.6/files/drivers/char/watchdog/wdt_merlot.c | 2 | ||||
| -rw-r--r-- | target/linux/aruba-2.6/patches/000-aruba.patch | 9159 | ||||
| -rw-r--r-- | target/linux/generic-2.6/config-template | 3 | 
4 files changed, 9119 insertions, 47 deletions
| diff --git a/target/linux/aruba-2.6/config/default b/target/linux/aruba-2.6/config/default index a15c7340f..2b14b56ae 100644 --- a/target/linux/aruba-2.6/config/default +++ b/target/linux/aruba-2.6/config/default @@ -167,7 +167,7 @@ CONFIG_PAGE_SIZE_4KB=y  # CONFIG_PCMCIA_ATMEL is not set  # CONFIG_PMC_YOSEMITE is not set  # CONFIG_PNX8550_JBS is not set -# CONFIG_PNX8550_V2PCI is not set +# CONFIG_PNX8550_STB810 is not set  # CONFIG_RTC is not set  CONFIG_RWSEM_GENERIC_SPINLOCK=y  CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y diff --git a/target/linux/aruba-2.6/files/drivers/char/watchdog/wdt_merlot.c b/target/linux/aruba-2.6/files/drivers/char/watchdog/wdt_merlot.c index de966c869..ef5e52aa0 100644 --- a/target/linux/aruba-2.6/files/drivers/char/watchdog/wdt_merlot.c +++ b/target/linux/aruba-2.6/files/drivers/char/watchdog/wdt_merlot.c @@ -4,6 +4,8 @@  #include <linux/miscdevice.h>  #include <linux/watchdog.h>  #include <linux/fs.h> +#include <linux/jiffies.h> +#include <linux/timer.h>  #include <asm/io.h>  #include <asm/uaccess.h> diff --git a/target/linux/aruba-2.6/patches/000-aruba.patch b/target/linux/aruba-2.6/patches/000-aruba.patch index 7317685c5..804bf2f22 100644 --- a/target/linux/aruba-2.6/patches/000-aruba.patch +++ b/target/linux/aruba-2.6/patches/000-aruba.patch @@ -1,9 +1,9 @@ -diff -Nur linux-2.6.17/arch/mips/Kconfig linux-2.6.17-owrt/arch/mips/Kconfig ---- linux-2.6.17/arch/mips/Kconfig	2006-06-18 03:49:35.000000000 +0200 -+++ linux-2.6.17-owrt/arch/mips/Kconfig	2006-06-18 12:44:28.000000000 +0200 -@@ -227,6 +227,17 @@ - 	  either a NEC Vr5432 or QED RM5231. Say Y here if you wish to build - 	  a kernel for this platform. +diff -Nur linux-2.6.21.1/arch/mips/Kconfig linux-2.6.21.1-owrt/arch/mips/Kconfig +--- linux-2.6.21.1/arch/mips/Kconfig	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/arch/mips/Kconfig	2007-05-23 23:34:01.000000000 +0200 +@@ -220,6 +220,17 @@ + 	  <http://www.marvell.com/>.  Say Y here if you wish to build a + 	  kernel for this platform.  +config MACH_ARUBA  +	bool "Support for the ARUBA product line" @@ -19,10 +19,10 @@ diff -Nur linux-2.6.17/arch/mips/Kconfig linux-2.6.17-owrt/arch/mips/Kconfig   config MACH_JAZZ   	bool "Jazz family of machines"   	select ARC -diff -Nur linux-2.6.17/arch/mips/Makefile linux-2.6.17-owrt/arch/mips/Makefile ---- linux-2.6.17/arch/mips/Makefile	2006-06-18 03:49:35.000000000 +0200 -+++ linux-2.6.17-owrt/arch/mips/Makefile	2006-06-18 12:44:28.000000000 +0200 -@@ -145,6 +145,14 @@ +diff -Nur linux-2.6.21.1/arch/mips/Makefile linux-2.6.21.1-owrt/arch/mips/Makefile +--- linux-2.6.21.1/arch/mips/Makefile	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/arch/mips/Makefile	2007-05-23 23:34:01.000000000 +0200 +@@ -158,6 +158,14 @@   #   # @@ -37,13 +37,666 @@ diff -Nur linux-2.6.17/arch/mips/Makefile linux-2.6.17-owrt/arch/mips/Makefile   # Acer PICA 61, Mips Magnum 4000 and Olivetti M700.   #   core-$(CONFIG_MACH_JAZZ)	+= arch/mips/jazz/ -diff -Nur linux-2.6.17/drivers/net/Kconfig linux-2.6.17-owrt/drivers/net/Kconfig ---- linux-2.6.17/drivers/net/Kconfig	2006-06-18 03:49:35.000000000 +0200 -+++ linux-2.6.17-owrt/drivers/net/Kconfig	2006-06-18 12:44:28.000000000 +0200 -@@ -187,6 +187,13 @@ +diff -Nur linux-2.6.21.1/arch/mips/pci/Makefile linux-2.6.21.1-owrt/arch/mips/pci/Makefile +--- linux-2.6.21.1/arch/mips/pci/Makefile	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/arch/mips/pci/Makefile	2007-05-23 23:36:48.000000000 +0200 +@@ -53,3 +53,4 @@ + obj-$(CONFIG_VICTOR_MPC30X)	+= fixup-mpc30x.o + obj-$(CONFIG_ZAO_CAPCELLA)	+= fixup-capcella.o + obj-$(CONFIG_WR_PPMC)		+= fixup-wrppmc.o ++obj-$(CONFIG_MACH_ARUBA)        += fixup-aruba.o ops-aruba.o pci-aruba.o +diff -Nur linux-2.6.21.1/drivers/char/watchdog/Makefile linux-2.6.21.1-owrt/drivers/char/watchdog/Makefile +--- linux-2.6.21.1/drivers/char/watchdog/Makefile	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/drivers/char/watchdog/Makefile	2007-05-23 23:36:53.000000000 +0200 +@@ -82,5 +82,8 @@ +  + # SPARC64 Architecture +  ++# Aruba Architecture ++obj-$(CONFIG_MACH_ARUBA) += wdt_merlot.o ++ + # Architecture Independant + obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o +diff -Nur linux-2.6.21.1/drivers/char/watchdog/Makefile.orig linux-2.6.21.1-owrt/drivers/char/watchdog/Makefile.orig +--- linux-2.6.21.1/drivers/char/watchdog/Makefile.orig	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.1-owrt/drivers/char/watchdog/Makefile.orig	2007-04-27 23:49:26.000000000 +0200 +@@ -0,0 +1,86 @@ ++# ++# Makefile for the WatchDog device drivers. ++# ++ ++# Only one watchdog can succeed. We probe the ISA/PCI/USB based ++# watchdog-cards first, then the architecture specific watchdog ++# drivers and then the architecture independant "softdog" driver. ++# This means that if your ISA/PCI/USB card isn't detected that ++# you can fall back to an architecture specific driver and if ++# that also fails then you can fall back to the software watchdog ++# to give you some cover. ++ ++# ISA-based Watchdog Cards ++obj-$(CONFIG_PCWATCHDOG) += pcwd.o ++obj-$(CONFIG_MIXCOMWD) += mixcomwd.o ++obj-$(CONFIG_WDT) += wdt.o ++ ++# PCI-based Watchdog Cards ++obj-$(CONFIG_PCIPCWATCHDOG) += pcwd_pci.o ++obj-$(CONFIG_WDTPCI) += wdt_pci.o ++ ++# USB-based Watchdog Cards ++obj-$(CONFIG_USBPCWATCHDOG) += pcwd_usb.o ++ ++# ARM Architecture ++obj-$(CONFIG_AT91RM9200_WATCHDOG) += at91rm9200_wdt.o ++obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o ++obj-$(CONFIG_21285_WATCHDOG) += wdt285.o ++obj-$(CONFIG_977_WATCHDOG) += wdt977.o ++obj-$(CONFIG_IXP2000_WATCHDOG) += ixp2000_wdt.o ++obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o ++obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o ++obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o ++obj-$(CONFIG_MPCORE_WATCHDOG) += mpcore_wdt.o ++obj-$(CONFIG_EP93XX_WATCHDOG) += ep93xx_wdt.o ++obj-$(CONFIG_PNX4008_WATCHDOG) += pnx4008_wdt.o ++ ++# X86 (i386 + ia64 + x86_64) Architecture ++obj-$(CONFIG_ACQUIRE_WDT) += acquirewdt.o ++obj-$(CONFIG_ADVANTECH_WDT) += advantechwdt.o ++obj-$(CONFIG_ALIM1535_WDT) += alim1535_wdt.o ++obj-$(CONFIG_ALIM7101_WDT) += alim7101_wdt.o ++obj-$(CONFIG_SC520_WDT) += sc520_wdt.o ++obj-$(CONFIG_EUROTECH_WDT) += eurotechwdt.o ++obj-$(CONFIG_IB700_WDT) += ib700wdt.o ++obj-$(CONFIG_IBMASR) += ibmasr.o ++obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o ++obj-$(CONFIG_I6300ESB_WDT) += i6300esb.o ++obj-$(CONFIG_I8XX_TCO) += i8xx_tco.o ++obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o iTCO_vendor_support.o ++obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o ++obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o ++obj-$(CONFIG_PC87413_WDT) += pc87413_wdt.o ++obj-$(CONFIG_60XX_WDT) += sbc60xxwdt.o ++obj-$(CONFIG_SBC8360_WDT) += sbc8360.o ++obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o ++obj-$(CONFIG_SMSC37B787_WDT) += smsc37b787_wdt.o ++obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o ++obj-$(CONFIG_W83697HF_WDT) += w83697hf_wdt.o ++obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o ++obj-$(CONFIG_W83977F_WDT) += w83977f_wdt.o ++obj-$(CONFIG_MACHZ_WDT) += machzwd.o ++obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o ++ ++# PowerPC Architecture ++obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o ++obj-$(CONFIG_83xx_WDT) += mpc83xx_wdt.o ++obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o ++obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o ++ ++# PPC64 Architecture ++obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o ++ ++# MIPS Architecture ++obj-$(CONFIG_INDYDOG) += indydog.o ++obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o ++ ++# S390 Architecture ++ ++# SUPERH Architecture ++obj-$(CONFIG_SH_WDT) += shwdt.o ++ ++# SPARC64 Architecture ++ ++# Architecture Independant ++obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o +diff -Nur linux-2.6.21.1/drivers/mtd/chips/cfi_probe.c linux-2.6.21.1-owrt/drivers/mtd/chips/cfi_probe.c +--- linux-2.6.21.1/drivers/mtd/chips/cfi_probe.c	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/drivers/mtd/chips/cfi_probe.c	2007-05-23 23:36:42.000000000 +0200 +@@ -25,6 +25,74 @@ + static void print_cfi_ident(struct cfi_ident *); + #endif +  ++#if 1 ++ ++#define AMD_AUTOSEL_OFF1	0xAAA ++#define AMD_AUTOSEL_OFF2	0x555 ++#define AMD_MANUF_ID		0x1 ++#define AMD_DEVICE_ID1		0xF6 /* T */ ++#define AMD_DEVICE_ID2		0xF9 /* B */ ++/* Foll. are definitions for Macronix Flash Part */ ++#define MCX_MANUF_ID		0xC2 ++#define MCX_DEVICE_ID1		0xA7 ++#define MCX_DEVICE_ID2		0xA8 ++/* Foll. common to both AMD and Macronix */ ++#define FACTORY_LOCKED		0x99 ++#define USER_LOCKED		0x19 ++ ++/* NOTE: AP-70/6x use BYTE mode flash access. Therefore the ++ * lowest Addr. pin in the flash is not A0 but A-1 (A minus 1). ++ * CPU's A0 is tied to Flash's A-1, A1 to A0 and so on. This ++ * gives 4MB of byte-addressable mem. In byte mode, all addr ++ * need to be multiplied by 2 (i.e compared to word mode). ++ * NOTE: AMD_AUTOSEL_OFF1 and OFF2 are already mult. by 2 ++ * Just blindly use the addr offsets suggested in the manual ++ * for byte mode and you'll be OK. Offs. in Table 6 need to ++ * be mult by 2 (for getting autosel params) ++ */ ++void ++flash_detect(struct map_info *map, __u32 base, struct cfi_private *cfi) ++{ ++	map_word val[3]; ++	int osf = cfi->interleave * cfi->device_type; // =2 for AP70/6x ++	char *manuf, *part, *lock ; ++ ++	if (osf != 1) return ; ++ ++	cfi_send_gen_cmd(0xAA, AMD_AUTOSEL_OFF1, base, map, cfi, cfi->device_type, NULL); ++	cfi_send_gen_cmd(0x55, AMD_AUTOSEL_OFF2, base, map, cfi, cfi->device_type, NULL); ++	cfi_send_gen_cmd(0x90, AMD_AUTOSEL_OFF1, base, map, cfi, cfi->device_type, NULL); ++	val[0] = map_read(map, base) ; // manuf ID ++	val[1] = map_read(map, base+2) ; // device ID ++	val[2] = map_read(map, base+6) ; // lock indicator ++#if 0 ++printk("v1=0x%x v2=0x%x v3=0x%x\n", val[0], val[1], val[2]) ; ++#endif ++	if (val[0].x[0] == AMD_MANUF_ID) { ++		manuf = "AMD Flash" ; ++		if (val[1].x[0] == AMD_DEVICE_ID1) ++			part = "AM29LV320D (Top)" ; ++		else if (val[1].x[0] == AMD_DEVICE_ID2) ++			part = "AM29LV320D (Bot)" ; ++		else part = "Unknown" ; ++	} else if (val[0].x[0] == MCX_MANUF_ID) { ++		manuf = "Macronix Flash" ; ++		if (val[1].x[0] == MCX_DEVICE_ID1) ++			part = "MX29LV320A (Top)" ; ++		else if (val[1].x[0] == MCX_DEVICE_ID2) ++			part = "MX29LV320A (Bot)" ; ++		else part = "Unknown" ; ++	} else ++		return ; ++	if (val[2].x[0] == FACTORY_LOCKED) ++		lock = "Factory Locked" ; ++	else if (val[2].x[0] == USER_LOCKED) ++		lock = "User Locked" ; ++	else lock = "Unknown locking" ; ++	printk("%s %s (%s)\n", manuf, part, lock) ; ++} ++#endif ++ + static int cfi_probe_chip(struct map_info *map, __u32 base, + 			  unsigned long *chip_map, struct cfi_private *cfi); + static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi); +@@ -117,6 +185,10 @@ + 	} +  + 	xip_disable(); ++#if 1 ++	//cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); ++	flash_detect(map, base, cfi) ; ++#endif + 	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); + 	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); + 	cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); +diff -Nur linux-2.6.21.1/drivers/mtd/chips/cfi_probe.c.orig linux-2.6.21.1-owrt/drivers/mtd/chips/cfi_probe.c.orig +--- linux-2.6.21.1/drivers/mtd/chips/cfi_probe.c.orig	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.1-owrt/drivers/mtd/chips/cfi_probe.c.orig	2007-04-27 23:49:26.000000000 +0200 +@@ -0,0 +1,444 @@ ++/* ++   Common Flash Interface probe code. ++   (C) 2000 Red Hat. GPL'd. ++   $Id: cfi_probe.c,v 1.86 2005/11/29 14:48:31 gleixner Exp $ ++*/ ++ ++#include <linux/module.h> ++#include <linux/types.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <asm/io.h> ++#include <asm/byteorder.h> ++#include <linux/errno.h> ++#include <linux/slab.h> ++#include <linux/interrupt.h> ++ ++#include <linux/mtd/xip.h> ++#include <linux/mtd/map.h> ++#include <linux/mtd/cfi.h> ++#include <linux/mtd/gen_probe.h> ++ ++//#define DEBUG_CFI ++ ++#ifdef DEBUG_CFI ++static void print_cfi_ident(struct cfi_ident *); ++#endif ++ ++static int cfi_probe_chip(struct map_info *map, __u32 base, ++			  unsigned long *chip_map, struct cfi_private *cfi); ++static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi); ++ ++struct mtd_info *cfi_probe(struct map_info *map); ++ ++#ifdef CONFIG_MTD_XIP ++ ++/* only needed for short periods, so this is rather simple */ ++#define xip_disable()	local_irq_disable() ++ ++#define xip_allowed(base, map) \ ++do { \ ++	(void) map_read(map, base); \ ++	asm volatile (".rep 8; nop; .endr"); \ ++	local_irq_enable(); \ ++} while (0) ++ ++#define xip_enable(base, map, cfi) \ ++do { \ ++	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); \ ++	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); \ ++	xip_allowed(base, map); \ ++} while (0) ++ ++#define xip_disable_qry(base, map, cfi) \ ++do { \ ++	xip_disable(); \ ++	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); \ ++	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); \ ++	cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); \ ++} while (0) ++ ++#else ++ ++#define xip_disable()			do { } while (0) ++#define xip_allowed(base, map)		do { } while (0) ++#define xip_enable(base, map, cfi)	do { } while (0) ++#define xip_disable_qry(base, map, cfi) do { } while (0) ++ ++#endif ++ ++/* check for QRY. ++   in: interleave,type,mode ++   ret: table index, <0 for error ++ */ ++static int __xipram qry_present(struct map_info *map, __u32 base, ++				struct cfi_private *cfi) ++{ ++	int osf = cfi->interleave * cfi->device_type;	// scale factor ++	map_word val[3]; ++	map_word qry[3]; ++ ++	qry[0] = cfi_build_cmd('Q', map, cfi); ++	qry[1] = cfi_build_cmd('R', map, cfi); ++	qry[2] = cfi_build_cmd('Y', map, cfi); ++ ++	val[0] = map_read(map, base + osf*0x10); ++	val[1] = map_read(map, base + osf*0x11); ++	val[2] = map_read(map, base + osf*0x12); ++ ++	if (!map_word_equal(map, qry[0], val[0])) ++		return 0; ++ ++	if (!map_word_equal(map, qry[1], val[1])) ++		return 0; ++ ++	if (!map_word_equal(map, qry[2], val[2])) ++		return 0; ++ ++	return 1; 	// "QRY" found ++} ++ ++static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, ++				   unsigned long *chip_map, struct cfi_private *cfi) ++{ ++	int i; ++ ++	if ((base + 0) >= map->size) { ++		printk(KERN_NOTICE ++			"Probe at base[0x00](0x%08lx) past the end of the map(0x%08lx)\n", ++			(unsigned long)base, map->size -1); ++		return 0; ++	} ++	if ((base + 0xff) >= map->size) { ++		printk(KERN_NOTICE ++			"Probe at base[0x55](0x%08lx) past the end of the map(0x%08lx)\n", ++			(unsigned long)base + 0x55, map->size -1); ++		return 0; ++	} ++ ++	xip_disable(); ++	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); ++	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); ++	cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); ++ ++	if (!qry_present(map,base,cfi)) { ++		xip_enable(base, map, cfi); ++		return 0; ++	} ++ ++	if (!cfi->numchips) { ++		/* This is the first time we're called. Set up the CFI ++		   stuff accordingly and return */ ++		return cfi_chip_setup(map, cfi); ++	} ++ ++	/* Check each previous chip to see if it's an alias */ ++ 	for (i=0; i < (base >> cfi->chipshift); i++) { ++ 		unsigned long start; ++ 		if(!test_bit(i, chip_map)) { ++			/* Skip location; no valid chip at this address */ ++ 			continue; ++ 		} ++ 		start = i << cfi->chipshift; ++		/* This chip should be in read mode if it's one ++		   we've already touched. */ ++		if (qry_present(map, start, cfi)) { ++			/* Eep. This chip also had the QRY marker. ++			 * Is it an alias for the new one? */ ++			cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL); ++			cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); ++ ++			/* If the QRY marker goes away, it's an alias */ ++			if (!qry_present(map, start, cfi)) { ++				xip_allowed(base, map); ++				printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", ++				       map->name, base, start); ++				return 0; ++			} ++			/* Yes, it's actually got QRY for data. Most ++			 * unfortunate. Stick the new chip in read mode ++			 * too and if it's the same, assume it's an alias. */ ++			/* FIXME: Use other modes to do a proper check */ ++			cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); ++			cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL); ++ ++			if (qry_present(map, base, cfi)) { ++				xip_allowed(base, map); ++				printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n", ++				       map->name, base, start); ++				return 0; ++			} ++		} ++	} ++ ++	/* OK, if we got to here, then none of the previous chips appear to ++	   be aliases for the current one. */ ++	set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */ ++	cfi->numchips++; ++ ++	/* Put it back into Read Mode */ ++	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); ++	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); ++	xip_allowed(base, map); ++ ++	printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", ++	       map->name, cfi->interleave, cfi->device_type*8, base, ++	       map->bankwidth*8); ++ ++	return 1; ++} ++ ++static int __xipram cfi_chip_setup(struct map_info *map, ++				   struct cfi_private *cfi) ++{ ++	int ofs_factor = cfi->interleave*cfi->device_type; ++	__u32 base = 0; ++	int num_erase_regions = cfi_read_query(map, base + (0x10 + 28)*ofs_factor); ++	int i; ++ ++	xip_enable(base, map, cfi); ++#ifdef DEBUG_CFI ++	printk("Number of erase regions: %d\n", num_erase_regions); ++#endif ++	if (!num_erase_regions) ++		return 0; ++ ++	cfi->cfiq = kmalloc(sizeof(struct cfi_ident) + num_erase_regions * 4, GFP_KERNEL); ++	if (!cfi->cfiq) { ++		printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); ++		return 0; ++	} ++ ++	memset(cfi->cfiq,0,sizeof(struct cfi_ident)); ++ ++	cfi->cfi_mode = CFI_MODE_CFI; ++ ++	/* Read the CFI info structure */ ++	xip_disable_qry(base, map, cfi); ++	for (i=0; i<(sizeof(struct cfi_ident) + num_erase_regions * 4); i++) ++		((unsigned char *)cfi->cfiq)[i] = cfi_read_query(map,base + (0x10 + i)*ofs_factor); ++ ++	/* Note we put the device back into Read Mode BEFORE going into Auto ++	 * Select Mode, as some devices support nesting of modes, others ++	 * don't. This way should always work. ++	 * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and ++	 * so should be treated as nops or illegal (and so put the device ++	 * back into Read Mode, which is a nop in this case). ++	 */ ++	cfi_send_gen_cmd(0xf0,     0, base, map, cfi, cfi->device_type, NULL); ++	cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL); ++	cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); ++	cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); ++	cfi->mfr = cfi_read_query16(map, base); ++	cfi->id = cfi_read_query16(map, base + ofs_factor); ++ ++	/* Put it back into Read Mode */ ++	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); ++	/* ... even if it's an Intel chip */ ++	cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); ++	xip_allowed(base, map); ++ ++	/* Do any necessary byteswapping */ ++	cfi->cfiq->P_ID = le16_to_cpu(cfi->cfiq->P_ID); ++ ++	cfi->cfiq->P_ADR = le16_to_cpu(cfi->cfiq->P_ADR); ++	cfi->cfiq->A_ID = le16_to_cpu(cfi->cfiq->A_ID); ++	cfi->cfiq->A_ADR = le16_to_cpu(cfi->cfiq->A_ADR); ++	cfi->cfiq->InterfaceDesc = le16_to_cpu(cfi->cfiq->InterfaceDesc); ++	cfi->cfiq->MaxBufWriteSize = le16_to_cpu(cfi->cfiq->MaxBufWriteSize); ++ ++#ifdef DEBUG_CFI ++	/* Dump the information therein */ ++	print_cfi_ident(cfi->cfiq); ++#endif ++ ++	for (i=0; i<cfi->cfiq->NumEraseRegions; i++) { ++		cfi->cfiq->EraseRegionInfo[i] = le32_to_cpu(cfi->cfiq->EraseRegionInfo[i]); ++ ++#ifdef DEBUG_CFI ++		printk("  Erase Region #%d: BlockSize 0x%4.4X bytes, %d blocks\n", ++		       i, (cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff, ++		       (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1); ++#endif ++	} ++ ++	printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n", ++	       map->name, cfi->interleave, cfi->device_type*8, base, ++	       map->bankwidth*8); ++ ++	return 1; ++} ++ ++#ifdef DEBUG_CFI ++static char *vendorname(__u16 vendor) ++{ ++	switch (vendor) { ++	case P_ID_NONE: ++		return "None"; ++ ++	case P_ID_INTEL_EXT: ++		return "Intel/Sharp Extended"; ++ ++	case P_ID_AMD_STD: ++		return "AMD/Fujitsu Standard"; ++ ++	case P_ID_INTEL_STD: ++		return "Intel/Sharp Standard"; ++ ++	case P_ID_AMD_EXT: ++		return "AMD/Fujitsu Extended"; ++ ++	case P_ID_WINBOND: ++		return "Winbond Standard"; ++ ++	case P_ID_ST_ADV: ++		return "ST Advanced"; ++ ++	case P_ID_MITSUBISHI_STD: ++		return "Mitsubishi Standard"; ++ ++	case P_ID_MITSUBISHI_EXT: ++		return "Mitsubishi Extended"; ++ ++	case P_ID_SST_PAGE: ++		return "SST Page Write"; ++ ++	case P_ID_INTEL_PERFORMANCE: ++		return "Intel Performance Code"; ++ ++	case P_ID_INTEL_DATA: ++		return "Intel Data"; ++ ++	case P_ID_RESERVED: ++		return "Not Allowed / Reserved for Future Use"; ++ ++	default: ++		return "Unknown"; ++	} ++} ++ ++ ++static void print_cfi_ident(struct cfi_ident *cfip) ++{ ++#if 0 ++	if (cfip->qry[0] != 'Q' || cfip->qry[1] != 'R' || cfip->qry[2] != 'Y') { ++		printk("Invalid CFI ident structure.\n"); ++		return; ++	} ++#endif ++	printk("Primary Vendor Command Set: %4.4X (%s)\n", cfip->P_ID, vendorname(cfip->P_ID)); ++	if (cfip->P_ADR) ++		printk("Primary Algorithm Table at %4.4X\n", cfip->P_ADR); ++	else ++		printk("No Primary Algorithm Table\n"); ++ ++	printk("Alternative Vendor Command Set: %4.4X (%s)\n", cfip->A_ID, vendorname(cfip->A_ID)); ++	if (cfip->A_ADR) ++		printk("Alternate Algorithm Table at %4.4X\n", cfip->A_ADR); ++	else ++		printk("No Alternate Algorithm Table\n"); ++ ++ ++	printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf); ++	printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf); ++	if (cfip->VppMin) { ++		printk("Vpp Minimum: %2d.%d V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf); ++		printk("Vpp Maximum: %2d.%d V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf); ++	} ++	else ++		printk("No Vpp line\n"); ++ ++	printk("Typical byte/word write timeout: %d µs\n", 1<<cfip->WordWriteTimeoutTyp); ++	printk("Maximum byte/word write timeout: %d µs\n", (1<<cfip->WordWriteTimeoutMax) * (1<<cfip->WordWriteTimeoutTyp)); ++ ++	if (cfip->BufWriteTimeoutTyp || cfip->BufWriteTimeoutMax) { ++		printk("Typical full buffer write timeout: %d µs\n", 1<<cfip->BufWriteTimeoutTyp); ++		printk("Maximum full buffer write timeout: %d µs\n", (1<<cfip->BufWriteTimeoutMax) * (1<<cfip->BufWriteTimeoutTyp)); ++	} ++	else ++		printk("Full buffer write not supported\n"); ++ ++	printk("Typical block erase timeout: %d ms\n", 1<<cfip->BlockEraseTimeoutTyp); ++	printk("Maximum block erase timeout: %d ms\n", (1<<cfip->BlockEraseTimeoutMax) * (1<<cfip->BlockEraseTimeoutTyp)); ++	if (cfip->ChipEraseTimeoutTyp || cfip->ChipEraseTimeoutMax) { ++		printk("Typical chip erase timeout: %d ms\n", 1<<cfip->ChipEraseTimeoutTyp); ++		printk("Maximum chip erase timeout: %d ms\n", (1<<cfip->ChipEraseTimeoutMax) * (1<<cfip->ChipEraseTimeoutTyp)); ++	} ++	else ++		printk("Chip erase not supported\n"); ++ ++	printk("Device size: 0x%X bytes (%d MiB)\n", 1 << cfip->DevSize, 1<< (cfip->DevSize - 20)); ++	printk("Flash Device Interface description: 0x%4.4X\n", cfip->InterfaceDesc); ++	switch(cfip->InterfaceDesc) { ++	case 0: ++		printk("  - x8-only asynchronous interface\n"); ++		break; ++ ++	case 1: ++		printk("  - x16-only asynchronous interface\n"); ++		break; ++ ++	case 2: ++		printk("  - supports x8 and x16 via BYTE# with asynchronous interface\n"); ++		break; ++ ++	case 3: ++		printk("  - x32-only asynchronous interface\n"); ++		break; ++ ++	case 4: ++		printk("  - supports x16 and x32 via Word# with asynchronous interface\n"); ++		break; ++ ++	case 65535: ++		printk("  - Not Allowed / Reserved\n"); ++		break; ++ ++	default: ++		printk("  - Unknown\n"); ++		break; ++	} ++ ++	printk("Max. bytes in buffer write: 0x%x\n", 1<< cfip->MaxBufWriteSize); ++	printk("Number of Erase Block Regions: %d\n", cfip->NumEraseRegions); ++ ++} ++#endif /* DEBUG_CFI */ ++ ++static struct chip_probe cfi_chip_probe = { ++	.name		= "CFI", ++	.probe_chip	= cfi_probe_chip ++}; ++ ++struct mtd_info *cfi_probe(struct map_info *map) ++{ ++	/* ++	 * Just use the generic probe stuff to call our CFI-specific ++	 * chip_probe routine in all the possible permutations, etc. ++	 */ ++	return mtd_do_chip_probe(map, &cfi_chip_probe); ++} ++ ++static struct mtd_chip_driver cfi_chipdrv = { ++	.probe		= cfi_probe, ++	.name		= "cfi_probe", ++	.module		= THIS_MODULE ++}; ++ ++static int __init cfi_probe_init(void) ++{ ++	register_mtd_chip_driver(&cfi_chipdrv); ++	return 0; ++} ++ ++static void __exit cfi_probe_exit(void) ++{ ++	unregister_mtd_chip_driver(&cfi_chipdrv); ++} ++ ++module_init(cfi_probe_init); ++module_exit(cfi_probe_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al."); ++MODULE_DESCRIPTION("Probe code for CFI-compliant flash chips"); +diff -Nur linux-2.6.21.1/drivers/net/Kconfig linux-2.6.21.1-owrt/drivers/net/Kconfig +--- linux-2.6.21.1/drivers/net/Kconfig	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/drivers/net/Kconfig	2007-05-23 23:37:01.000000000 +0200 +@@ -201,6 +201,19 @@   source "drivers/net/arm/Kconfig" ++config AR2313 ++	tristate "AR2313 Ethernet support" ++	depends on NET_ETHERNET && MACH_ARUBA ++	help ++	  Support for the AR2313 Ethernet part on Aruba AP60/61 ++  +config IDT_RC32434_ETH  +        tristate "IDT RC32434 Local Ethernet support"  +        depends on NET_ETHERNET @@ -54,23 +707,3212 @@ diff -Nur linux-2.6.17/drivers/net/Kconfig linux-2.6.17-owrt/drivers/net/Kconfig   config MACE   	tristate "MACE (Power Mac ethernet) support"   	depends on NET_ETHERNET && PPC_PMAC && PPC32 -diff -Nur linux-2.6.17/drivers/net/Makefile linux-2.6.17-owrt/drivers/net/Makefile ---- linux-2.6.17/drivers/net/Makefile	2006-06-18 03:49:35.000000000 +0200 -+++ linux-2.6.17-owrt/drivers/net/Makefile	2006-06-18 12:44:28.000000000 +0200 -@@ -38,6 +38,7 @@ +diff -Nur linux-2.6.21.1/drivers/net/Kconfig.orig linux-2.6.21.1-owrt/drivers/net/Kconfig.orig +--- linux-2.6.21.1/drivers/net/Kconfig.orig	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.1-owrt/drivers/net/Kconfig.orig	2007-05-23 23:34:01.000000000 +0200 +@@ -0,0 +1,2952 @@ ++ ++# ++# Network device configuration ++# ++ ++menu "Network device support" ++	depends on NET ++ ++config NETDEVICES ++	default y if UML ++	bool "Network device support" ++	---help--- ++	  You can say N here if you don't intend to connect your Linux box to ++	  any other computer at all. ++ ++	  You'll have to say Y if your computer contains a network card that ++	  you want to use under Linux. If you are going to run SLIP or PPP over ++	  telephone line or null modem cable you need say Y here. Connecting ++	  two machines with parallel ports using PLIP needs this, as well as ++	  AX.25/KISS for sending Internet traffic over amateur radio links. ++ ++	  See also "The Linux Network Administrator's Guide" by Olaf Kirch and ++	  Terry Dawson. Available at <http://www.tldp.org/guides.html>. ++ ++	  If unsure, say Y. ++ ++# All the following symbols are dependent on NETDEVICES - do not repeat ++# that for each of the symbols. ++if NETDEVICES ++ ++config IFB ++	tristate "Intermediate Functional Block support" ++	depends on NET_CLS_ACT ++	---help--- ++	  This is an intermediate driver that allows sharing of ++	  resources. ++	  To compile this driver as a module, choose M here: the module ++	  will be called ifb.  If you want to use more than one ifb ++	  device at a time, you need to compile this driver as a module. ++	  Instead of 'ifb', the devices will then be called 'ifb0', ++	  'ifb1' etc. ++	  Look at the iproute2 documentation directory for usage etc ++ ++config DUMMY ++	tristate "Dummy net driver support" ++	---help--- ++	  This is essentially a bit-bucket device (i.e. traffic you send to ++	  this device is consigned into oblivion) with a configurable IP ++	  address. It is most commonly used in order to make your currently ++	  inactive SLIP address seem like a real address for local programs. ++	  If you use SLIP or PPP, you might want to say Y here. Since this ++	  thing often comes in handy, the default is Y. It won't enlarge your ++	  kernel either. What a deal. Read about it in the Network ++	  Administrator's Guide, available from ++	  <http://www.tldp.org/docs.html#guide>. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called dummy.  If you want to use more than one dummy ++	  device at a time, you need to compile this driver as a module. ++	  Instead of 'dummy', the devices will then be called 'dummy0', ++	  'dummy1' etc. ++ ++config BONDING ++	tristate "Bonding driver support" ++	depends on INET ++	---help--- ++	  Say 'Y' or 'M' if you wish to be able to 'bond' multiple Ethernet ++	  Channels together. This is called 'Etherchannel' by Cisco, ++	  'Trunking' by Sun, 802.3ad by the IEEE, and 'Bonding' in Linux. ++ ++	  The driver supports multiple bonding modes to allow for both high ++	  performance and high availability operation. ++ ++	  Refer to <file:Documentation/networking/bonding.txt> for more ++	  information. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called bonding. ++ ++config EQUALIZER ++	tristate "EQL (serial line load balancing) support" ++	---help--- ++	  If you have two serial connections to some other computer (this ++	  usually requires two modems and two telephone lines) and you use ++	  SLIP (the protocol for sending Internet traffic over telephone ++	  lines) or PPP (a better SLIP) on them, you can make them behave like ++	  one double speed connection using this driver.  Naturally, this has ++	  to be supported at the other end as well, either with a similar EQL ++	  Linux driver or with a Livingston Portmaster 2e. ++ ++	  Say Y if you want this and read ++	  <file:Documentation/networking/eql.txt>.  You may also want to read ++	  section 6.2 of the NET-3-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called eql.  If unsure, say N. ++ ++config TUN ++	tristate "Universal TUN/TAP device driver support" ++	select CRC32 ++	---help--- ++	  TUN/TAP provides packet reception and transmission for user space ++	  programs.  It can be viewed as a simple Point-to-Point or Ethernet ++	  device, which instead of receiving packets from a physical media, ++	  receives them from user space program and instead of sending packets ++	  via physical media writes them to the user space program. ++ ++	  When a program opens /dev/net/tun, driver creates and registers ++	  corresponding net device tunX or tapX.  After a program closed above ++	  devices, driver will automatically delete tunXX or tapXX device and ++	  all routes corresponding to it. ++ ++	  Please read <file:Documentation/networking/tuntap.txt> for more ++	  information. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called tun. ++ ++	  If you don't know what to use this for, you don't need it. ++ ++config NET_SB1000 ++	tristate "General Instruments Surfboard 1000" ++	depends on PNP ++	---help--- ++	  This is a driver for the General Instrument (also known as ++	  NextLevel) SURFboard 1000 internal ++	  cable modem. This is an ISA card which is used by a number of cable ++	  TV companies to provide cable modem access. It's a one-way ++	  downstream-only cable modem, meaning that your upstream net link is ++	  provided by your regular phone modem. ++ ++	  At present this driver only compiles as a module, so say M here if ++	  you have this card. The module will be called sb1000. Then read ++	  <file:Documentation/networking/README.sb1000> for information on how ++	  to use this module, as it needs special ppp scripts for establishing ++	  a connection. Further documentation and the necessary scripts can be ++	  found at: ++ ++	  <http://www.jacksonville.net/~fventuri/> ++	  <http://home.adelphia.net/~siglercm/sb1000.html> ++	  <http://linuxpower.cx/~cable/> ++ ++	  If you don't have this card, of course say N. ++ ++source "drivers/net/arcnet/Kconfig" ++ ++source "drivers/net/phy/Kconfig" ++ ++# ++#	Ethernet ++# ++ ++menu "Ethernet (10 or 100Mbit)" ++	depends on !UML ++ ++config NET_ETHERNET ++	bool "Ethernet (10 or 100Mbit)" ++	---help--- ++	  Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common ++	  type of Local Area Network (LAN) in universities and companies. ++ ++	  Common varieties of Ethernet are: 10BASE-2 or Thinnet (10 Mbps over ++	  coaxial cable, linking computers in a chain), 10BASE-T or twisted ++	  pair (10 Mbps over twisted pair cable, linking computers to central ++	  hubs), 10BASE-F (10 Mbps over optical fiber links, using hubs), ++	  100BASE-TX (100 Mbps over two twisted pair cables, using hubs), ++	  100BASE-T4 (100 Mbps over 4 standard voice-grade twisted pair ++	  cables, using hubs), 100BASE-FX (100 Mbps over optical fiber links) ++	  [the 100BASE varieties are also known as Fast Ethernet], and Gigabit ++	  Ethernet (1 Gbps over optical fiber or short copper links). ++ ++	  If your Linux machine will be connected to an Ethernet and you have ++	  an Ethernet network interface card (NIC) installed in your computer, ++	  say Y here and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. You will then also have ++	  to say Y to the driver for your particular NIC. ++ ++	  Note that the answer to this question won't directly affect the ++	  kernel: saying N will just cause the configurator to skip all ++	  the questions about Ethernet network cards. If unsure, say N. ++ ++config MII ++	tristate "Generic Media Independent Interface device support" ++	depends on NET_ETHERNET ++	help ++	  Most ethernet controllers have MII transceiver either as an external ++	  or internal device.  It is safe to say Y or M here even if your ++	  ethernet card lack MII. ++ ++config MACB ++	tristate "Atmel MACB support" ++	depends on NET_ETHERNET && (AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263) ++	select MII ++	help ++	  The Atmel MACB ethernet interface is found on many AT32 and AT91 ++	  parts. Say Y to include support for the MACB chip. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called macb. ++ ++source "drivers/net/arm/Kconfig" ++ ++config IDT_RC32434_ETH ++        tristate "IDT RC32434 Local Ethernet support" ++        depends on NET_ETHERNET ++        help ++        IDT RC32434 has one local ethernet port. Say Y here to enable it. ++        To compile this driver as a module, choose M here. ++ ++config MACE ++	tristate "MACE (Power Mac ethernet) support" ++	depends on NET_ETHERNET && PPC_PMAC && PPC32 ++	select CRC32 ++	help ++	  Power Macintoshes and clones with Ethernet built-in on the ++	  motherboard will usually use a MACE (Medium Access Control for ++	  Ethernet) interface. Say Y to include support for the MACE chip. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called mace. ++ ++config MACE_AAUI_PORT ++	bool "Use AAUI port instead of TP by default" ++	depends on MACE ++	help ++	  Some Apple machines (notably the Apple Network Server) which use the ++	  MACE ethernet chip have an Apple AUI port (small 15-pin connector), ++	  instead of an 8-pin RJ45 connector for twisted-pair ethernet.  Say ++	  Y here if you have such a machine.  If unsure, say N. ++	  The driver will default to AAUI on ANS anyway, and if you use it as ++	  a module, you can provide the port_aaui=0|1 to force the driver. ++ ++config BMAC ++	tristate "BMAC (G3 ethernet) support" ++	depends on NET_ETHERNET && PPC_PMAC && PPC32 ++	select CRC32 ++	help ++	  Say Y for support of BMAC Ethernet interfaces. These are used on G3 ++	  computers. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called bmac. ++ ++config ARIADNE ++	tristate "Ariadne support" ++	depends on NET_ETHERNET && ZORRO ++	help ++	  If you have a Village Tronic Ariadne Ethernet adapter, say Y. ++	  Otherwise, say N. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called ariadne. ++ ++config A2065 ++	tristate "A2065 support" ++	depends on NET_ETHERNET && ZORRO ++	select CRC32 ++	help ++	  If you have a Commodore A2065 Ethernet adapter, say Y. Otherwise, ++	  say N. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called a2065. ++ ++config HYDRA ++	tristate "Hydra support" ++	depends on NET_ETHERNET && ZORRO ++	select CRC32 ++	help ++	  If you have a Hydra Ethernet adapter, say Y. Otherwise, say N. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called hydra. ++ ++config ZORRO8390 ++	tristate "Zorro NS8390-based Ethernet support" ++	depends on NET_ETHERNET && ZORRO ++	select CRC32 ++	help ++	  This driver is for Zorro Ethernet cards using an NS8390-compatible ++	  chipset, like the Village Tronic Ariadne II and the Individual ++	  Computers X-Surf Ethernet cards. If you have such a card, say Y. ++	  Otherwise, say N. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called zorro8390. ++ ++config APNE ++	tristate "PCMCIA NE2000 support" ++	depends on NET_ETHERNET && AMIGA_PCMCIA ++	select CRC32 ++	help ++	  If you have a PCMCIA NE2000 compatible adapter, say Y.  Otherwise, ++	  say N. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called apne. ++ ++config APOLLO_ELPLUS ++	tristate "Apollo 3c505 support" ++	depends on NET_ETHERNET && APOLLO ++	help ++	  Say Y or M here if your Apollo has a 3Com 3c505 ISA Ethernet card. ++	  If you don't have one made for Apollos, you can use one from a PC, ++	  except that your Apollo won't be able to boot from it (because the ++	  code in the ROM will be for a PC). ++ ++config MAC8390 ++	bool "Macintosh NS 8390 based ethernet cards" ++	depends on NET_ETHERNET && MAC ++	select CRC32 ++	help ++	  If you want to include a driver to support Nubus or LC-PDS ++	  Ethernet cards using an NS8390 chipset or its equivalent, say Y ++	  and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++config MAC89x0 ++	tristate "Macintosh CS89x0 based ethernet cards" ++	depends on NET_ETHERNET && MAC && BROKEN ++	---help--- ++	  Support for CS89x0 chipset based Ethernet cards.  If you have a ++	  Nubus or LC-PDS network (Ethernet) card of this type, say Y and ++	  read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  This module will ++	  be called mac89x0. ++ ++config MACSONIC ++	tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)" ++	depends on NET_ETHERNET && MAC ++	---help--- ++	  Support for NatSemi SONIC based Ethernet devices.  This includes ++	  the onboard Ethernet in many Quadras as well as some LC-PDS, ++	  a few Nubus and all known Comm Slot Ethernet cards.  If you have ++	  one of these say Y and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  This module will ++	  be called macsonic. ++ ++config MACMACE ++	bool "Macintosh (AV) onboard MACE ethernet (EXPERIMENTAL)" ++	depends on NET_ETHERNET && MAC && EXPERIMENTAL ++	select CRC32 ++	help ++	  Support for the onboard AMD 79C940 MACE Ethernet controller used in ++	  the 660AV and 840AV Macintosh.  If you have one of these Macintoshes ++	  say Y and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++config MVME147_NET ++	tristate "MVME147 (Lance) Ethernet support" ++	depends on NET_ETHERNET && MVME147 ++	select CRC32 ++	help ++	  Support for the on-board Ethernet interface on the Motorola MVME147 ++	  single-board computer.  Say Y here to include the ++	  driver for this chip in your kernel. ++	  To compile this driver as a module, choose M here. ++ ++config MVME16x_NET ++	tristate "MVME16x Ethernet support" ++	depends on NET_ETHERNET && MVME16x ++	help ++	  This is the driver for the Ethernet interface on the Motorola ++	  MVME162, 166, 167, 172 and 177 boards.  Say Y here to include the ++	  driver for this chip in your kernel. ++	  To compile this driver as a module, choose M here. ++ ++config BVME6000_NET ++	tristate "BVME6000 Ethernet support" ++	depends on NET_ETHERNET && BVME6000 ++	help ++	  This is the driver for the Ethernet interface on BVME4000 and ++	  BVME6000 VME boards.  Say Y here to include the driver for this chip ++	  in your kernel. ++	  To compile this driver as a module, choose M here. ++ ++config ATARILANCE ++	tristate "Atari Lance support" ++	depends on NET_ETHERNET && ATARI ++	help ++	  Say Y to include support for several Atari Ethernet adapters based ++	  on the AMD Lance chipset: RieblCard (with or without battery), or ++	  PAMCard VME (also the version by Rhotron, with different addresses). ++ ++config ATARI_BIONET ++	tristate "BioNet-100 support" ++	depends on NET_ETHERNET && ATARI && ATARI_ACSI && BROKEN ++	help ++	  Say Y to include support for BioData's BioNet-100 Ethernet adapter ++	  for the ACSI port. The driver works (has to work...) with a polled ++	  I/O scheme, so it's rather slow :-( ++ ++config ATARI_PAMSNET ++	tristate "PAMsNet support" ++	depends on NET_ETHERNET && ATARI && ATARI_ACSI && BROKEN ++	help ++	  Say Y to include support for the PAMsNet Ethernet adapter for the ++	  ACSI port ("ACSI node"). The driver works (has to work...) with a ++	  polled I/O scheme, so it's rather slow :-( ++ ++config SUN3LANCE ++	tristate "Sun3/Sun3x on-board LANCE support" ++	depends on NET_ETHERNET && (SUN3 || SUN3X) ++	help ++	  Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80) ++	  featured an AMD Lance 10Mbit Ethernet controller on board; say Y ++	  here to compile in the Linux driver for this and enable Ethernet. ++	  General Linux information on the Sun 3 and 3x series (now ++	  discontinued) is at ++	  <http://www.angelfire.com/ca2/tech68k/sun3.html>. ++ ++	  If you're not building a kernel for a Sun 3, say N. ++ ++config SUN3_82586 ++	bool "Sun3 on-board Intel 82586 support" ++	depends on NET_ETHERNET && SUN3 ++	help ++	  This driver enables support for the on-board Intel 82586 based ++	  Ethernet adapter found on Sun 3/1xx and 3/2xx motherboards.  Note ++	  that this driver does not support 82586-based adapters on additional ++	  VME boards. ++ ++config HPLANCE ++	bool "HP on-board LANCE support" ++	depends on NET_ETHERNET && DIO ++	select CRC32 ++	help ++	  If you want to use the builtin "LANCE" Ethernet controller on an ++	  HP300 machine, say Y here. ++ ++config LASI_82596 ++	tristate "Lasi ethernet" ++	depends on NET_ETHERNET && GSC ++	help ++	  Say Y here to support the builtin Intel 82596 ethernet controller ++	  found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet. ++ ++config MIPS_JAZZ_SONIC ++	tristate "MIPS JAZZ onboard SONIC Ethernet support" ++	depends on NET_ETHERNET && MACH_JAZZ ++	help ++	  This is the driver for the onboard card of MIPS Magnum 4000, ++	  Acer PICA, Olivetti M700-10 and a few other identical OEM systems. ++ ++config MIPS_AU1X00_ENET ++	bool "MIPS AU1000 Ethernet support" ++	depends on NET_ETHERNET && SOC_AU1X00 ++	select PHYLIB ++	select CRC32 ++	help ++	  If you have an Alchemy Semi AU1X00 based system ++	  say Y.  Otherwise, say N. ++ ++config NET_SB1250_MAC ++	tristate "SB1250 Ethernet support" ++	depends on NET_ETHERNET && SIBYTE_SB1xxx_SOC ++ ++config SGI_IOC3_ETH ++	bool "SGI IOC3 Ethernet" ++	depends on NET_ETHERNET && PCI && SGI_IP27 ++	select CRC32 ++	select MII ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++config SGI_IOC3_ETH_HW_RX_CSUM ++	bool "Receive hardware checksums" ++	depends on SGI_IOC3_ETH && INET ++	default y ++	help ++	  The SGI IOC3 network adapter supports TCP and UDP checksums in ++	  hardware to offload processing of these checksums from the CPU.  At ++	  the moment only acceleration of IPv4 is supported.  This option ++	  enables offloading for checksums on receive.  If unsure, say Y. ++ ++config SGI_IOC3_ETH_HW_TX_CSUM ++	bool "Transmit hardware checksums" ++	depends on SGI_IOC3_ETH && INET ++	default y ++	help ++	  The SGI IOC3 network adapter supports TCP and UDP checksums in ++	  hardware to offload processing of these checksums from the CPU.  At ++	  the moment only acceleration of IPv4 is supported.  This option ++	  enables offloading for checksums on transmit.  If unsure, say Y. ++ ++config MIPS_SIM_NET ++	tristate "MIPS simulator Network device (EXPERIMENTAL)" ++	depends on MIPS_SIM && EXPERIMENTAL ++	help ++	  The MIPSNET device is a simple Ethernet network device which is ++	  emulated by the MIPS Simulator. ++	  If you are not using a MIPSsim or are unsure, say N. ++ ++config SGI_O2MACE_ETH ++	tristate "SGI O2 MACE Fast Ethernet support" ++	depends on NET_ETHERNET && SGI_IP32=y ++ ++config STNIC ++	tristate "National DP83902AV  support" ++	depends on NET_ETHERNET && SUPERH ++	select CRC32 ++	help ++	  Support for cards based on the National Semiconductor DP83902AV ++	  ST-NIC Serial Network Interface Controller for Twisted Pair.  This ++	  is a 10Mbit/sec Ethernet controller.  Product overview and specs at ++	  <http://www.national.com/pf/DP/DP83902A.html>. ++ ++	  If unsure, say N. ++ ++config SUNLANCE ++	tristate "Sun LANCE support" ++	depends on NET_ETHERNET && SBUS ++	select CRC32 ++	help ++	  This driver supports the "le" interface present on all 32-bit Sparc ++	  systems, on some older Ultra systems and as an Sbus option.  These ++	  cards are based on the AMD Lance chipset, which is better known ++	  via the NE2100 cards. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called sunlance. ++ ++config HAPPYMEAL ++	tristate "Sun Happy Meal 10/100baseT support" ++	depends on NET_ETHERNET && (SBUS || PCI) ++	select CRC32 ++	help ++	  This driver supports the "hme" interface present on most Ultra ++	  systems and as an option on older Sbus systems. This driver supports ++	  both PCI and Sbus devices. This driver also supports the "qfe" quad ++	  100baseT device available in both PCI and Sbus configurations. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called sunhme. ++ ++config SUNBMAC ++	tristate "Sun BigMAC 10/100baseT support (EXPERIMENTAL)" ++	depends on NET_ETHERNET && SBUS && EXPERIMENTAL ++	select CRC32 ++	help ++	  This driver supports the "be" interface available as an Sbus option. ++	  This is Sun's older 100baseT Ethernet device. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called sunbmac. ++ ++config SUNQE ++	tristate "Sun QuadEthernet support" ++	depends on NET_ETHERNET && SBUS ++	select CRC32 ++	help ++	  This driver supports the "qe" 10baseT Ethernet device, available as ++	  an Sbus option. Note that this is not the same as Quad FastEthernet ++	  "qfe" which is supported by the Happy Meal driver instead. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called sunqe. ++ ++config SUNGEM ++	tristate "Sun GEM support" ++	depends on NET_ETHERNET && PCI ++	select CRC32 ++	help ++	  Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0.  See also ++	  <http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>. ++ ++config CASSINI ++	tristate "Sun Cassini support" ++	depends on NET_ETHERNET && PCI ++	select CRC32 ++	help ++	  Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also ++	  <http://www.sun.com/products-n-solutions/hardware/docs/pdf/817-4341-10.pdf> ++ ++config NET_VENDOR_3COM ++	bool "3COM cards" ++	depends on NET_ETHERNET && (ISA || EISA || MCA || PCI) ++	help ++	  If you have a network (Ethernet) card belonging to this class, say Y ++	  and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  Note that the answer to this question doesn't directly affect the ++	  kernel: saying N will just cause the configurator to skip all ++	  the questions about 3COM cards. If you say Y, you will be asked for ++	  your specific card in the following questions. ++ ++config EL1 ++	tristate "3c501 \"EtherLink\" support" ++	depends on NET_VENDOR_3COM && ISA ++	---help--- ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>.  Also, consider buying a ++	  new card, since the 3c501 is slow, broken, and obsolete: you will ++	  have problems.  Some people suggest to ping ("man ping") a nearby ++	  machine every minute ("man cron") when using this card. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called 3c501. ++ ++config EL2 ++	tristate "3c503 \"EtherLink II\" support" ++	depends on NET_VENDOR_3COM && ISA ++	select CRC32 ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called 3c503. ++ ++config ELPLUS ++	tristate "3c505 \"EtherLink Plus\" support" ++	depends on NET_VENDOR_3COM && ISA && ISA_DMA_API ++	---help--- ++	  Information about this network (Ethernet) card can be found in ++	  <file:Documentation/networking/3c505.txt>.  If you have a card of ++	  this type, say Y and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called 3c505. ++ ++config EL16 ++	tristate "3c507 \"EtherLink 16\" support (EXPERIMENTAL)" ++	depends on NET_VENDOR_3COM && ISA && EXPERIMENTAL ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called 3c507. ++ ++config EL3 ++	tristate "3c509/3c529 (MCA)/3c579 \"EtherLink III\" support" ++	depends on NET_VENDOR_3COM && (ISA || EISA || MCA) ++	---help--- ++	  If you have a network (Ethernet) card belonging to the 3Com ++	  EtherLinkIII series, say Y and read the Ethernet-HOWTO, available ++	  from <http://www.tldp.org/docs.html#howto>. ++ ++	  If your card is not working you may need to use the DOS ++	  setup disk to disable Plug & Play mode, and to select the default ++	  media type. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called 3c509. ++ ++config 3C515 ++	tristate "3c515 ISA \"Fast EtherLink\"" ++	depends on NET_VENDOR_3COM && (ISA || EISA) && ISA_DMA_API ++	help ++	  If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet ++	  network card, say Y and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called 3c515. ++ ++config ELMC ++	tristate "3c523 \"EtherLink/MC\" support" ++	depends on NET_VENDOR_3COM && MCA_LEGACY ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called 3c523. ++ ++config ELMC_II ++	tristate "3c527 \"EtherLink/MC 32\" support (EXPERIMENTAL)" ++	depends on NET_VENDOR_3COM && MCA && MCA_LEGACY ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called 3c527. ++ ++config VORTEX ++	tristate "3c590/3c900 series (592/595/597) \"Vortex/Boomerang\" support" ++	depends on NET_VENDOR_3COM && (PCI || EISA) ++	select MII ++	---help--- ++	  This option enables driver support for a large number of 10Mbps and ++	  10/100Mbps EISA, PCI and PCMCIA 3Com network cards: ++ ++	  "Vortex"    (Fast EtherLink 3c590/3c592/3c595/3c597) EISA and PCI ++	  "Boomerang" (EtherLink XL 3c900 or 3c905)            PCI ++	  "Cyclone"   (3c540/3c900/3c905/3c980/3c575/3c656)    PCI and Cardbus ++	  "Tornado"   (3c905)                                  PCI ++	  "Hurricane" (3c555/3cSOHO)                           PCI ++ ++	  If you have such a card, say Y and read the Ethernet-HOWTO, ++	  available from <http://www.tldp.org/docs.html#howto>. More ++	  specific information is in ++	  <file:Documentation/networking/vortex.txt> and in the comments at ++	  the beginning of <file:drivers/net/3c59x.c>. ++ ++	  To compile this support as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. ++ ++config TYPHOON ++	tristate "3cr990 series \"Typhoon\" support" ++	depends on NET_VENDOR_3COM && PCI ++	select CRC32 ++	---help--- ++	  This option enables driver support for the 3cr990 series of cards: ++ ++	  3C990-TX, 3CR990-TX-95, 3CR990-TX-97, 3CR990-FX-95, 3CR990-FX-97, ++	  3CR990SVR, 3CR990SVR95, 3CR990SVR97, 3CR990-FX-95 Server, ++	  3CR990-FX-97 Server, 3C990B-TX-M, 3C990BSVR ++ ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called typhoon. ++ ++config LANCE ++	tristate "AMD LANCE and PCnet (AT1500 and NE2100) support" ++	depends on NET_ETHERNET && ISA && ISA_DMA_API ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. Some LinkSys cards are ++	  of this type. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called lance.  This is recommended. ++ ++config NET_VENDOR_SMC ++	bool "Western Digital/SMC cards" ++	depends on NET_ETHERNET && (ISA || MCA || EISA || MAC) ++	help ++	  If you have a network (Ethernet) card belonging to this class, say Y ++	  and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  Note that the answer to this question doesn't directly affect the ++	  kernel: saying N will just cause the configurator to skip all ++	  the questions about Western Digital cards. If you say Y, you will be ++	  asked for your specific card in the following questions. ++ ++config WD80x3 ++	tristate "WD80*3 support" ++	depends on NET_VENDOR_SMC && ISA ++	select CRC32 ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called wd. ++ ++config ULTRAMCA ++	tristate "SMC Ultra MCA support" ++	depends on NET_VENDOR_SMC && MCA ++	select CRC32 ++	help ++	  If you have a network (Ethernet) card of this type and are running ++	  an MCA based system (PS/2), say Y and read the Ethernet-HOWTO, ++	  available from <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called smc-mca. ++ ++config ULTRA ++	tristate "SMC Ultra support" ++	depends on NET_VENDOR_SMC && ISA ++	select CRC32 ++	---help--- ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  Important: There have been many reports that, with some motherboards ++	  mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible, ++	  such as some BusLogic models) causes corruption problems with many ++	  operating systems. The Linux smc-ultra driver has a work-around for ++	  this but keep it in mind if you have such a SCSI card and have ++	  problems. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called smc-ultra. ++ ++config ULTRA32 ++	tristate "SMC Ultra32 EISA support" ++	depends on NET_VENDOR_SMC && EISA ++	select CRC32 ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called smc-ultra32. ++ ++config SMC91X ++	tristate "SMC 91C9x/91C1xxx support" ++	select CRC32 ++	select MII ++	depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00) ++	help ++	  This is a driver for SMC's 91x series of Ethernet chipsets, ++	  including the SMC91C94 and the SMC91C111. Say Y if you want it ++	  compiled into the kernel, and read the file ++	  <file:Documentation/networking/smc9.txt>  and the Ethernet-HOWTO, ++	  available from  <http://www.linuxdoc.org/docs.html#howto>. ++ ++	  This driver is also available as a module ( = code which can be ++	  inserted in and removed from the running kernel whenever you want). ++	  The module will be called smc91x.  If you want to compile it as a ++	  module, say M here and read <file:Documentation/modules.txt> as well ++	  as <file:Documentation/networking/net-modules.txt>. ++ ++config SMC9194 ++	tristate "SMC 9194 support" ++	depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN) ++	select CRC32 ++	---help--- ++	  This is support for the SMC9xxx based Ethernet cards. Choose this ++	  option if you have a DELL laptop with the docking station, or ++	  another SMC9192/9194 based chipset.  Say Y if you want it compiled ++	  into the kernel, and read the file ++	  <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO, ++	  available from <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called smc9194. ++ ++config NET_NETX ++	tristate "NetX Ethernet support" ++	select MII ++	depends on NET_ETHERNET && ARCH_NETX ++	help ++	  This is support for the Hilscher netX builtin Ethernet ports ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called netx-eth. ++ ++config DM9000 ++	tristate "DM9000 support" ++	depends on (ARM || MIPS) && NET_ETHERNET ++	select CRC32 ++	select MII ++	---help--- ++	  Support for DM9000 chipset. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module will be ++	  called dm9000. ++ ++config SMC911X ++	tristate "SMSC LAN911[5678] support" ++	select CRC32 ++	select MII ++	depends on NET_ETHERNET && ARCH_PXA ++	help ++	  This is a driver for SMSC's LAN911x series of Ethernet chipsets ++	  including the new LAN9115, LAN9116, LAN9117, and LAN9118. ++	  Say Y if you want it compiled into the kernel,  ++	  and read the Ethernet-HOWTO, available from ++	  <http://www.linuxdoc.org/docs.html#howto>. ++ ++	  This driver is also available as a module. The module will be  ++	  called smc911x.  If you want to compile it as a module, say M  ++	  here and read <file:Documentation/modules.txt> ++ ++config NET_VENDOR_RACAL ++	bool "Racal-Interlan (Micom) NI cards" ++	depends on NET_ETHERNET && ISA ++	help ++	  If you have a network (Ethernet) card belonging to this class, such ++	  as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO, ++	  available from <http://www.tldp.org/docs.html#howto>. ++ ++	  Note that the answer to this question doesn't directly affect the ++	  kernel: saying N will just cause the configurator to skip all ++	  the questions about NI cards. If you say Y, you will be asked for ++	  your specific card in the following questions. ++ ++config NI5010 ++	tristate "NI5010 support (EXPERIMENTAL)" ++	depends on NET_VENDOR_RACAL && ISA && EXPERIMENTAL && BROKEN_ON_SMP ++	---help--- ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. Note that this is still ++	  experimental code. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called ni5010. ++ ++config NI52 ++	tristate "NI5210 support" ++	depends on NET_VENDOR_RACAL && ISA ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called ni52. ++ ++config NI65 ++	tristate "NI6510 support" ++	depends on NET_VENDOR_RACAL && ISA && ISA_DMA_API ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called ni65. ++ ++source "drivers/net/tulip/Kconfig" ++ ++config AT1700 ++	tristate "AT1700/1720 support (EXPERIMENTAL)" ++	depends on NET_ETHERNET && (ISA || MCA_LEGACY) && EXPERIMENTAL ++	select CRC32 ++	---help--- ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called at1700. ++ ++config DEPCA ++	tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support" ++	depends on NET_ETHERNET && (ISA || EISA || MCA) ++	select CRC32 ++	---help--- ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto> as well as ++	  <file:drivers/net/depca.c>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called depca. ++ ++config HP100 ++	tristate "HP 10/100VG PCLAN (ISA, EISA, PCI) support" ++	depends on NET_ETHERNET && (ISA || EISA || PCI) ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called hp100. ++ ++config NET_ISA ++	bool "Other ISA cards" ++	depends on NET_ETHERNET && ISA ++	---help--- ++	  If your network (Ethernet) card hasn't been mentioned yet and its ++	  bus system (that's the way the cards talks to the other components ++	  of your computer) is ISA (as opposed to EISA, VLB or PCI), say Y. ++	  Make sure you know the name of your card. Read the Ethernet-HOWTO, ++	  available from <http://www.tldp.org/docs.html#howto>. ++ ++	  If unsure, say Y. ++ ++	  Note that the answer to this question doesn't directly affect the ++	  kernel: saying N will just cause the configurator to skip all ++	  the remaining ISA network card questions. If you say Y, you will be ++	  asked for your specific card in the following questions. ++ ++config E2100 ++	tristate "Cabletron E21xx support" ++	depends on NET_ISA ++	select CRC32 ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called e2100. ++ ++config EWRK3 ++	tristate "EtherWORKS 3 (DE203, DE204, DE205) support" ++	depends on NET_ISA ++	select CRC32 ++	---help--- ++	  This driver supports the DE203, DE204 and DE205 network (Ethernet) ++	  cards. If this is for you, say Y and read ++	  <file:Documentation/networking/ewrk3.txt> in the kernel source as ++	  well as the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called ewrk3. ++ ++config EEXPRESS ++	tristate "EtherExpress 16 support" ++	depends on NET_ISA ++	---help--- ++	  If you have an EtherExpress16 network (Ethernet) card, say Y and ++	  read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>.  Note that the Intel ++	  EtherExpress16 card used to be regarded as a very poor choice ++	  because the driver was very unreliable. We now have a new driver ++	  that should do better. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called eexpress. ++ ++config EEXPRESS_PRO ++	tristate "EtherExpressPro support/EtherExpress 10 (i82595) support" ++	depends on NET_ISA ++	---help--- ++	  If you have a network (Ethernet) card of this type, say Y. This ++	  driver supports Intel i82595{FX,TX} based boards. Note however ++	  that the EtherExpress PRO/100 Ethernet card has its own separate ++	  driver.  Please read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called eepro. ++ ++config HPLAN_PLUS ++	tristate "HP PCLAN+ (27247B and 27252A) support" ++	depends on NET_ISA ++	select CRC32 ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called hp-plus. ++ ++config HPLAN ++	tristate "HP PCLAN (27245 and other 27xxx series) support" ++	depends on NET_ISA ++	select CRC32 ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called hp. ++ ++config LP486E ++	tristate "LP486E on board Ethernet" ++	depends on NET_ISA ++	help ++	  Say Y here to support the 82596-based on-board Ethernet controller ++	  for the Panther motherboard, which is one of the two shipped in the ++	  Intel Professional Workstation. ++ ++config ETH16I ++	tristate "ICL EtherTeam 16i/32 support" ++	depends on NET_ISA ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called eth16i. ++ ++config NE2000 ++	tristate "NE2000/NE1000 support" ++	depends on NET_ISA || (Q40 && m) || M32R ++	select CRC32 ++	---help--- ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>.  Many Ethernet cards ++	  without a specific driver are compatible with NE2000. ++ ++	  If you have a PCI NE2000 card however, say N here and Y to "PCI ++	  NE2000 and clone support" under "EISA, VLB, PCI and on board ++	  controllers" below. If you have a NE2000 card and are running on ++	  an MCA system (a bus system used on some IBM PS/2 computers and ++	  laptops), say N here and Y to "NE/2 (ne2000 MCA version) support", ++	  below. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called ne. ++ ++config ZNET ++	tristate "Zenith Z-Note support (EXPERIMENTAL)" ++	depends on NET_ISA && EXPERIMENTAL && ISA_DMA_API ++	help ++	  The Zenith Z-Note notebook computer has a built-in network ++	  (Ethernet) card, and this is the Linux driver for it. Note that the ++	  IBM Thinkpad 300 is compatible with the Z-Note and is also supported ++	  by this driver. Read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++config SEEQ8005 ++	tristate "SEEQ8005 support (EXPERIMENTAL)" ++	depends on NET_ISA && EXPERIMENTAL ++	help ++	  This is a driver for the SEEQ 8005 network (Ethernet) card.  If this ++	  is for you, read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called seeq8005. ++ ++config NE2_MCA ++	tristate "NE/2 (ne2000 MCA version) support" ++	depends on NET_ETHERNET && MCA_LEGACY ++	select CRC32 ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called ne2. ++ ++config IBMLANA ++	tristate "IBM LAN Adapter/A support" ++	depends on NET_ETHERNET && MCA && MCA_LEGACY ++	---help--- ++	  This is a Micro Channel Ethernet adapter.  You need to set ++	  CONFIG_MCA to use this driver.  It is both available as an in-kernel ++	  driver and as a module. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The only ++	  currently supported card is the IBM LAN Adapter/A for Ethernet.  It ++	  will both support 16K and 32K memory windows, however a 32K window ++	  gives a better security against packet losses.  Usage of multiple ++	  boards with this driver should be possible, but has not been tested ++	  up to now due to lack of hardware. ++ ++config IBMVETH ++	tristate "IBM LAN Virtual Ethernet support" ++	depends on NET_ETHERNET && PPC_PSERIES ++	---help--- ++	  This driver supports virtual ethernet adapters on newer IBM iSeries ++	  and pSeries systems. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module will ++	  be called ibmveth. ++ ++config IBM_EMAC ++	tristate "PowerPC 4xx on-chip Ethernet support" ++	depends on 4xx ++	help ++	  This driver supports the PowerPC 4xx EMAC family of on-chip ++          Ethernet controllers. ++ ++config IBM_EMAC_RXB ++	int "Number of receive buffers" ++	depends on IBM_EMAC ++	default "128" ++ ++config IBM_EMAC_TXB ++	int "Number of transmit buffers" ++	depends on IBM_EMAC ++	default "64" ++ ++config IBM_EMAC_POLL_WEIGHT ++	int "MAL NAPI polling weight" ++	depends on IBM_EMAC ++	default "32" ++ ++config IBM_EMAC_RX_COPY_THRESHOLD ++	int "RX skb copy threshold (bytes)" ++	depends on IBM_EMAC ++	default "256" ++ ++config IBM_EMAC_RX_SKB_HEADROOM ++	int "Additional RX skb headroom (bytes)" ++	depends on IBM_EMAC ++	default "0" ++	help ++	  Additional receive skb headroom. Note, that driver ++	  will always reserve at least 2 bytes to make IP header ++	  aligned, so usually there is no need to add any additional ++	  headroom. ++	   ++	  If unsure, set to 0. ++ ++config IBM_EMAC_PHY_RX_CLK_FIX ++	bool "PHY Rx clock workaround" ++	depends on IBM_EMAC && (405EP || 440GX || 440EP || 440GR) ++	help ++	  Enable this if EMAC attached to a PHY which doesn't generate ++	  RX clock if there is no link, if this is the case, you will  ++	  see "TX disable timeout" or "RX disable timeout" in the system ++	  log. ++	   ++	  If unsure, say N. ++ ++config IBM_EMAC_DEBUG ++	bool "Debugging" ++	depends on IBM_EMAC ++	default n ++ ++config IBM_EMAC_ZMII ++	bool ++	depends on IBM_EMAC && (NP405H || NP405L || 44x) ++	default y ++ ++config IBM_EMAC_RGMII ++	bool ++	depends on IBM_EMAC && 440GX ++	default y ++		 ++config IBM_EMAC_TAH ++	bool ++	depends on IBM_EMAC && 440GX ++	default y ++ ++config NET_PCI ++	bool "EISA, VLB, PCI and on board controllers" ++	depends on NET_ETHERNET && (ISA || EISA || PCI) ++	help ++	  This is another class of network cards which attach directly to the ++	  bus. If you have one of those, say Y and read the Ethernet-HOWTO, ++	  available from <http://www.tldp.org/docs.html#howto>. ++ ++	  Note that the answer to this question doesn't directly affect the ++	  kernel: saying N will just cause the configurator to skip all ++	  the questions about this class of network cards. If you say Y, you ++	  will be asked for your specific card in the following questions. If ++	  you are unsure, say Y. ++ ++config PCNET32 ++	tristate "AMD PCnet32 PCI support" ++	depends on NET_PCI && PCI ++	select CRC32 ++	select MII ++	help ++	  If you have a PCnet32 or PCnetPCI based network (Ethernet) card, ++	  answer Y here and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called pcnet32. ++ ++config PCNET32_NAPI ++	bool "Use RX polling (NAPI)" ++	depends on PCNET32 ++	help ++	  NAPI is a new driver API designed to reduce CPU and interrupt load ++	  when the driver is receiving lots of packets from the card. It is ++	  still somewhat experimental and thus not yet enabled by default. ++ ++	  If your estimated Rx load is 10kpps or more, or if the card will be ++	  deployed on potentially unfriendly networks (e.g. in a firewall), ++	  then say Y here. ++ ++	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more ++	  information. ++ ++	  If in doubt, say N. ++ ++config AMD8111_ETH ++	tristate "AMD 8111 (new PCI lance) support" ++	depends on NET_PCI && PCI ++	select CRC32 ++	select MII ++	help ++	  If you have an AMD 8111-based PCI lance ethernet card, ++	  answer Y here and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called amd8111e. ++config AMD8111E_NAPI ++	bool "Enable NAPI support" ++	depends on AMD8111_ETH ++	help ++	  NAPI is a new driver API designed to reduce CPU and interrupt load ++	  when the driver is receiving lots of packets from the card. It is ++	  still somewhat experimental and thus not yet enabled by default. ++ ++	  If your estimated Rx load is 10kpps or more, or if the card will be ++	  deployed on potentially unfriendly networks (e.g. in a firewall), ++	  then say Y here. ++ ++	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more ++	  information. ++ ++	  If in doubt, say N. ++ ++config ADAPTEC_STARFIRE ++	tristate "Adaptec Starfire/DuraLAN support" ++	depends on NET_PCI && PCI ++	select CRC32 ++	select MII ++	help ++	  Say Y here if you have an Adaptec Starfire (or DuraLAN) PCI network ++	  adapter. The DuraLAN chip is used on the 64 bit PCI boards from ++	  Adaptec e.g. the ANA-6922A. The older 32 bit boards use the tulip ++	  driver. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called starfire.  This is recommended. ++ ++config ADAPTEC_STARFIRE_NAPI ++	bool "Use Rx Polling (NAPI) (EXPERIMENTAL)" ++	depends on ADAPTEC_STARFIRE && EXPERIMENTAL ++	help ++	  NAPI is a new driver API designed to reduce CPU and interrupt load ++	  when the driver is receiving lots of packets from the card. It is ++	  still somewhat experimental and thus not yet enabled by default. ++ ++	  If your estimated Rx load is 10kpps or more, or if the card will be ++	  deployed on potentially unfriendly networks (e.g. in a firewall), ++	  then say Y here. ++ ++	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more ++	  information. ++ ++	  If in doubt, say N. ++ ++config AC3200 ++	tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)" ++	depends on NET_PCI && (ISA || EISA) && EXPERIMENTAL ++	select CRC32 ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called ac3200. ++ ++config APRICOT ++	tristate "Apricot Xen-II on board Ethernet" ++	depends on NET_PCI && ISA ++	help ++	  If you have a network (Ethernet) controller of this type, say Y and ++	  read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module will be ++	  called apricot. ++ ++config B44 ++	tristate "Broadcom 4400 ethernet support" ++	depends on NET_PCI && PCI ++	select MII ++	help ++	  If you have a network (Ethernet) controller of this type, say Y and ++	  read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module will be ++	  called b44. ++ ++config FORCEDETH ++	tristate "nForce Ethernet support" ++	depends on NET_PCI && PCI ++	help ++	  If you have a network (Ethernet) controller of this type, say Y and ++	  read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module will be ++	  called forcedeth. ++ ++config FORCEDETH_NAPI ++	bool "Use Rx and Tx Polling (NAPI) (EXPERIMENTAL)" ++	depends on FORCEDETH && EXPERIMENTAL ++	help ++	  NAPI is a new driver API designed to reduce CPU and interrupt load ++	  when the driver is receiving lots of packets from the card. It is ++	  still somewhat experimental and thus not yet enabled by default. ++ ++	  If your estimated Rx load is 10kpps or more, or if the card will be ++	  deployed on potentially unfriendly networks (e.g. in a firewall), ++	  then say Y here. ++ ++	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more ++	  information. ++ ++	  If in doubt, say N. ++ ++config CS89x0 ++	tristate "CS89x0 support" ++	depends on NET_PCI && (ISA || MACH_IXDP2351 || ARCH_IXDP2X01 || ARCH_PNX010X) ++	---help--- ++	  Support for CS89x0 chipset based Ethernet cards. If you have a ++	  network (Ethernet) card of this type, say Y and read the ++	  Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto> as well as ++	  <file:Documentation/networking/cs89x0.txt>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module will be ++	  called cs89x0. ++ ++config TC35815 ++	tristate "TOSHIBA TC35815 Ethernet support" ++	depends on NET_PCI && PCI && TOSHIBA_JMR3927 ++ ++config DGRS ++	tristate "Digi Intl. RightSwitch SE-X support" ++	depends on NET_PCI && (PCI || EISA) ++	---help--- ++	  This is support for the Digi International RightSwitch series of ++	  PCI/EISA Ethernet switch cards. These include the SE-4 and the SE-6 ++	  models.  If you have a network card of this type, say Y and read the ++	  Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>.  More specific ++	  information is contained in <file:Documentation/networking/dgrs.txt>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module ++	  will be called dgrs. ++ ++config EEPRO100 ++	tristate "EtherExpressPro/100 support (eepro100, original Becker driver)" ++	depends on NET_PCI && PCI ++	select MII ++	help ++	  If you have an Intel EtherExpress PRO/100 PCI network (Ethernet) ++	  card, say Y and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module ++	  will be called eepro100. ++ ++ ++config E100 ++	tristate "Intel(R) PRO/100+ support" ++	depends on NET_PCI && PCI ++	select MII ++	---help--- ++	  This driver supports Intel(R) PRO/100 family of adapters. ++	  To verify that your adapter is supported, find the board ID number  ++	  on the adapter. Look for a label that has a barcode and a number  ++	  in the format 123456-001 (six digits hyphen three digits).  ++ ++	  Use the above information and the Adapter & Driver ID Guide at: ++ ++	  <http://support.intel.com/support/network/adapter/pro100/21397.htm> ++ ++          to identify the adapter. ++ ++	  For the latest Intel PRO/100 network driver for Linux, see: ++ ++	  <http://appsr.intel.com/scripts-df/support_intel.asp> ++ ++	  More specific information on configuring the driver is in  ++	  <file:Documentation/networking/e100.txt>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module ++	  will be called e100. ++ ++config LNE390 ++	tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)" ++	depends on NET_PCI && EISA && EXPERIMENTAL ++	select CRC32 ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module ++	  will be called lne390. ++ ++config FEALNX ++	tristate "Myson MTD-8xx PCI Ethernet support" ++	depends on NET_PCI && PCI ++	select CRC32 ++	select MII ++	help ++	  Say Y here to support the Mysom MTD-800 family of PCI-based Ethernet ++	  cards. Specifications and data at ++	  <http://www.myson.com.hk/mtd/datasheet/>. ++ ++config NATSEMI ++	tristate "National Semiconductor DP8381x series PCI Ethernet support" ++	depends on NET_PCI && PCI ++	select CRC32 ++	help ++	  This driver is for the National Semiconductor DP83810 series, ++	  which is used in cards from PureData, NetGear, Linksys ++	  and others, including the 83815 chip. ++	  More specific information and updates are available from ++	  <http://www.scyld.com/network/natsemi.html>. ++ ++config NE2K_PCI ++	tristate "PCI NE2000 and clones support (see help)" ++	depends on NET_PCI && PCI ++	select CRC32 ++	---help--- ++	  This driver is for NE2000 compatible PCI cards. It will not work ++	  with ISA NE2000 cards (they have their own driver, "NE2000/NE1000 ++	  support" below). If you have a PCI NE2000 network (Ethernet) card, ++	  say Y and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  This driver also works for the following NE2000 clone cards: ++	  RealTek RTL-8029  Winbond 89C940  Compex RL2000  KTI ET32P2 ++	  NetVin NV5000SC   Via 86C926      SureCom NE34   Winbond ++	  Holtek HT80232    Holtek HT80229 ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module ++	  will be called ne2k-pci. ++ ++config NE3210 ++	tristate "Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)" ++	depends on NET_PCI && EISA && EXPERIMENTAL ++	select CRC32 ++	---help--- ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>.  Note that this driver ++	  will NOT WORK for NE3200 cards as they are completely different. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module ++	  will be called ne3210. ++ ++config ES3210 ++	tristate "Racal-Interlan EISA ES3210 support (EXPERIMENTAL)" ++	depends on NET_PCI && EISA && EXPERIMENTAL ++	select CRC32 ++	help ++	  If you have a network (Ethernet) card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module ++	  will be called es3210. ++ ++config 8139CP ++	tristate "RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support (EXPERIMENTAL)" ++	depends on NET_PCI && PCI && EXPERIMENTAL ++	select CRC32 ++	select MII ++	help ++	  This is a driver for the Fast Ethernet PCI network cards based on ++	  the RTL8139C+ chips. If you have one of those, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called 8139cp.  This is recommended. ++ ++config 8139TOO ++	tristate "RealTek RTL-8129/8130/8139 PCI Fast Ethernet Adapter support" ++	depends on NET_PCI && PCI ++	select CRC32 ++	select MII ++	---help--- ++	  This is a driver for the Fast Ethernet PCI network cards based on ++	  the RTL 8129/8130/8139 chips. If you have one of those, say Y and ++	  read the Ethernet-HOWTO <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called 8139too.  This is recommended. ++ ++config 8139TOO_PIO ++	bool "Use PIO instead of MMIO" ++	default y ++	depends on 8139TOO ++	help ++	  This instructs the driver to use programmed I/O ports (PIO) instead ++	  of PCI shared memory (MMIO).  This can possibly solve some problems ++	  in case your mainboard has memory consistency issues.  If unsure, ++	  say N. ++ ++config 8139TOO_TUNE_TWISTER ++	bool "Support for uncommon RTL-8139 rev. K (automatic channel equalization)" ++	depends on 8139TOO ++	help ++	  This implements a function which might come in handy in case you ++	  are using low quality on long cabling. It is required for RealTek ++	  RTL-8139 revision K boards, and totally unused otherwise.  It tries ++	  to match the transceiver to the cable characteristics. This is ++	  experimental since hardly documented by the manufacturer. ++	  If unsure, say Y. ++ ++config 8139TOO_8129 ++	bool "Support for older RTL-8129/8130 boards" ++	depends on 8139TOO ++	help ++	  This enables support for the older and uncommon RTL-8129 and ++	  RTL-8130 chips, which support MII via an external transceiver, ++	  instead of an internal one.  Disabling this option will save some ++	  memory by making the code size smaller.  If unsure, say Y. ++ ++config 8139_OLD_RX_RESET ++	bool "Use older RX-reset method" ++	depends on 8139TOO ++	help ++	  The 8139too driver was recently updated to contain a more rapid ++	  reset sequence, in the face of severe receive errors.  This "new" ++	  RX-reset method should be adequate for all boards.  But if you ++	  experience problems, you can enable this option to restore the ++	  old RX-reset behavior.  If unsure, say N. ++ ++config SIS900 ++	tristate "SiS 900/7016 PCI Fast Ethernet Adapter support" ++	depends on NET_PCI && PCI ++	select CRC32 ++	select MII ++	---help--- ++	  This is a driver for the Fast Ethernet PCI network cards based on ++	  the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in ++	  SiS 630 and SiS 540 chipsets. ++ ++	  This driver also supports AMD 79C901 HomePNA so that you can use ++	  your phone line as a network cable. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called sis900.  This is recommended. ++ ++config EPIC100 ++	tristate "SMC EtherPower II" ++	depends on NET_PCI && PCI ++	select CRC32 ++	select MII ++	help ++	  This driver is for the SMC EtherPower II 9432 PCI Ethernet NIC, ++	  which is based on the SMC83c17x (EPIC/100). ++	  More specific information and updates are available from ++	  <http://www.scyld.com/network/epic100.html>. ++ ++config SUNDANCE ++	tristate "Sundance Alta support" ++	depends on NET_PCI && PCI ++	select CRC32 ++	select MII ++	help ++	  This driver is for the Sundance "Alta" chip. ++	  More specific information and updates are available from ++	  <http://www.scyld.com/network/sundance.html>. ++ ++config SUNDANCE_MMIO ++	bool "Use MMIO instead of PIO" ++	depends on SUNDANCE ++	help ++	  Enable memory-mapped I/O for interaction with Sundance NIC registers. ++	  Do NOT enable this by default, PIO (enabled when MMIO is disabled) ++	  is known to solve bugs on certain chips. ++ ++	  If unsure, say N. ++ ++config TLAN ++	tristate "TI ThunderLAN support" ++	depends on NET_PCI && (PCI || EISA) && !64BIT ++	---help--- ++	  If you have a PCI Ethernet network card based on the ThunderLAN chip ++	  which is supported by this driver, say Y and read the ++	  Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  Devices currently supported by this driver are Compaq Netelligent, ++	  Compaq NetFlex and Olicom cards.  Please read the file ++	  <file:Documentation/networking/tlan.txt> for more details. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module ++	  will be called tlan. ++ ++	  Please email feedback to <torben.mathiasen@compaq.com>. ++ ++config VIA_RHINE ++	tristate "VIA Rhine support" ++	depends on NET_PCI && PCI ++	select CRC32 ++	select MII ++	help ++	  If you have a VIA "Rhine" based network card (Rhine-I (VT86C100A), ++	  Rhine-II (VT6102), or Rhine-III (VT6105)), say Y here. Rhine-type ++	  Ethernet functions can also be found integrated on South Bridges ++	  (e.g. VT8235). ++ ++	  To compile this driver as a module, choose M here. The module ++	  will be called via-rhine. ++ ++config VIA_RHINE_MMIO ++	bool "Use MMIO instead of PIO" ++	depends on VIA_RHINE ++	help ++	  This instructs the driver to use PCI shared memory (MMIO) instead of ++	  programmed I/O ports (PIO). Enabling this gives an improvement in ++	  processing time in parts of the driver. ++ ++	  If unsure, say Y. ++ ++config VIA_RHINE_NAPI ++	bool "Use Rx Polling (NAPI)" ++	depends on VIA_RHINE ++	help ++	  NAPI is a new driver API designed to reduce CPU and interrupt load ++	  when the driver is receiving lots of packets from the card. ++ ++	  If your estimated Rx load is 10kpps or more, or if the card will be ++	  deployed on potentially unfriendly networks (e.g. in a firewall), ++	  then say Y here. ++ ++	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more ++	  information. ++ ++config LAN_SAA9730 ++	bool "Philips SAA9730 Ethernet support" ++	depends on NET_PCI && PCI && MIPS_ATLAS ++	help ++	  The SAA9730 is a combined multimedia and peripheral controller used ++	  in thin clients, Internet access terminals, and diskless ++	  workstations. ++	  See <http://www.semiconductors.philips.com/pip/SAA9730_flyer_1>. ++ ++config SC92031 ++	tristate "Silan SC92031 PCI Fast Ethernet Adapter driver (EXPERIMENTAL)" ++	depends on NET_PCI && PCI && EXPERIMENTAL ++	select CRC32 ++	---help--- ++	  This is a driver for the Fast Ethernet PCI network cards based on ++	  the Silan SC92031 chip (sometimes also called Rsltek 8139D). If you ++	  have one of these, say Y here. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called sc92031.  This is recommended. ++ ++config NET_POCKET ++	bool "Pocket and portable adapters" ++	depends on NET_ETHERNET && PARPORT ++	---help--- ++	  Cute little network (Ethernet) devices which attach to the parallel ++	  port ("pocket adapters"), commonly used with laptops. If you have ++	  one of those, say Y and read the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  If you want to plug a network (or some other) card into the PCMCIA ++	  (or PC-card) slot of your laptop instead (PCMCIA is the standard for ++	  credit card size extension cards used by all modern laptops), you ++	  need the pcmcia-cs package (location contained in the file ++	  <file:Documentation/Changes>) and you can say N here. ++ ++	  Laptop users should read the Linux Laptop home page at ++	  <http://www.linux-on-laptops.com/> or ++	  Tuxmobil - Linux on Mobile Computers at <http://www.tuxmobil.org/>. ++ ++	  Note that the answer to this question doesn't directly affect the ++	  kernel: saying N will just cause the configurator to skip all ++	  the questions about this class of network devices. If you say Y, you ++	  will be asked for your specific device in the following questions. ++ ++config ATP ++	tristate "AT-LAN-TEC/RealTek pocket adapter support" ++	depends on NET_POCKET && PARPORT && X86 ++	select CRC32 ++	---help--- ++	  This is a network (Ethernet) device which attaches to your parallel ++	  port. Read <file:drivers/net/atp.c> as well as the Ethernet-HOWTO, ++	  available from <http://www.tldp.org/docs.html#howto>, if you ++	  want to use this.  If you intend to use this driver, you should have ++	  said N to the "Parallel printer support", because the two drivers ++	  don't like each other. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called atp. ++ ++config DE600 ++	tristate "D-Link DE600 pocket adapter support" ++	depends on NET_POCKET && PARPORT ++	---help--- ++	  This is a network (Ethernet) device which attaches to your parallel ++	  port. Read <file:Documentation/networking/DLINK.txt> as well as the ++	  Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>, if you want to use ++	  this. It is possible to have several devices share a single parallel ++	  port and it is safe to compile the corresponding drivers into the ++	  kernel. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called de600. ++ ++config DE620 ++	tristate "D-Link DE620 pocket adapter support" ++	depends on NET_POCKET && PARPORT ++	---help--- ++	  This is a network (Ethernet) device which attaches to your parallel ++	  port. Read <file:Documentation/networking/DLINK.txt> as well as the ++	  Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>, if you want to use ++	  this. It is possible to have several devices share a single parallel ++	  port and it is safe to compile the corresponding drivers into the ++	  kernel. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called de620. ++ ++config SGISEEQ ++	tristate "SGI Seeq ethernet controller support" ++	depends on NET_ETHERNET && SGI_IP22 ++	help ++	  Say Y here if you have an Seeq based Ethernet network card. This is ++	  used in many Silicon Graphics machines. ++ ++config DECLANCE ++	tristate "DEC LANCE ethernet controller support" ++	depends on NET_ETHERNET && MACH_DECSTATION ++	select CRC32 ++	help ++	  This driver is for the series of Ethernet controllers produced by ++	  DEC (now Compaq) based on the AMD Lance chipset, including the ++	  DEPCA series.  (This chipset is better known via the NE2100 cards.) ++ ++config 68360_ENET ++	bool "Motorola 68360 ethernet controller" ++	depends on M68360 ++	help ++	  Say Y here if you want to use the built-in ethernet controller of ++	  the Motorola 68360 processor. ++ ++config FEC ++	bool "FEC ethernet controller (of ColdFire CPUs)" ++	depends on M523x || M527x || M5272 || M528x || M520x ++	help ++	  Say Y here if you want to use the built-in 10/100 Fast ethernet ++	  controller on some Motorola ColdFire processors. ++ ++config FEC2 ++	bool "Second FEC ethernet controller (on some ColdFire CPUs)" ++	depends on FEC ++	help ++	  Say Y here if you want to use the second built-in 10/100 Fast ++	  ethernet controller on some Motorola ColdFire processors. ++ ++config NE_H8300 ++	tristate "NE2000 compatible support for H8/300" ++	depends on H8300 && NET_ETHERNET ++	help ++	  Say Y here if you want to use the NE2000 compatible ++	  controller on the Renesas H8/300 processor. ++ ++source "drivers/net/fec_8xx/Kconfig" ++source "drivers/net/fs_enet/Kconfig" ++ ++endmenu ++ ++# ++#	Gigabit Ethernet ++# ++ ++menu "Ethernet (1000 Mbit)" ++	depends on !UML ++ ++config ACENIC ++	tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support" ++	depends on PCI ++	---help--- ++	  Say Y here if you have an Alteon AceNIC, 3Com 3C985(B), NetGear ++	  GA620, SGI Gigabit or Farallon PN9000-SX PCI Gigabit Ethernet ++	  adapter. The driver allows for using the Jumbo Frame option (9000 ++	  bytes/frame) however it requires that your switches can handle this ++	  as well. To enable Jumbo Frames, add `mtu 9000' to your ifconfig ++	  line. ++ ++	  To compile this driver as a module, choose M here: the ++	  module will be called acenic. ++ ++config ACENIC_OMIT_TIGON_I ++	bool "Omit support for old Tigon I based AceNICs" ++	depends on ACENIC ++	help ++	  Say Y here if you only have Tigon II based AceNICs and want to leave ++	  out support for the older Tigon I based cards which are no longer ++	  being sold (ie. the original Alteon AceNIC and 3Com 3C985 (non B ++	  version)).  This will reduce the size of the driver object by ++	  app. 100KB.  If you are not sure whether your card is a Tigon I or a ++	  Tigon II, say N here. ++ ++	  The safe and default value for this is N. ++ ++config DL2K ++	tristate "D-Link DL2000-based Gigabit Ethernet support" ++	depends on PCI ++	select CRC32 ++	help ++	  This driver supports D-Link 2000-based gigabit ethernet cards, which ++	  includes ++	  D-Link DGE-550T Gigabit Ethernet Adapter. ++	  D-Link DL2000-based Gigabit Ethernet Adapter. ++ ++	  To compile this driver as a module, choose M here: the ++	  module will be called dl2k. ++ ++config E1000 ++	tristate "Intel(R) PRO/1000 Gigabit Ethernet support" ++	depends on PCI ++	---help--- ++	  This driver supports Intel(R) PRO/1000 gigabit ethernet family of ++	  adapters.  For more information on how to identify your adapter, go  ++	  to the Adapter & Driver ID Guide at: ++ ++	  <http://support.intel.com/support/network/adapter/pro100/21397.htm> ++ ++	  For general information and support, go to the Intel support ++	  website at: ++ ++	  <http://support.intel.com> ++ ++	  More specific information on configuring the driver is in  ++	  <file:Documentation/networking/e1000.txt>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module ++	  will be called e1000. ++ ++config E1000_NAPI ++	bool "Use Rx Polling (NAPI)" ++	depends on E1000 ++	help ++	  NAPI is a new driver API designed to reduce CPU and interrupt load ++	  when the driver is receiving lots of packets from the card. It is ++	  still somewhat experimental and thus not yet enabled by default. ++ ++	  If your estimated Rx load is 10kpps or more, or if the card will be ++	  deployed on potentially unfriendly networks (e.g. in a firewall), ++	  then say Y here. ++ ++	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more ++	  information. ++ ++	  If in doubt, say N. ++ ++config E1000_DISABLE_PACKET_SPLIT ++	bool "Disable Packet Split for PCI express adapters" ++	depends on E1000 ++	help ++	  Say Y here if you want to use the legacy receive path for PCI express ++	  hardware. ++ ++	  If in doubt, say N. ++ ++source "drivers/net/ixp2000/Kconfig" ++ ++config MYRI_SBUS ++	tristate "MyriCOM Gigabit Ethernet support" ++	depends on SBUS ++	help ++	  This driver supports MyriCOM Sbus gigabit Ethernet cards. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called myri_sbus.  This is recommended. ++ ++config NS83820 ++	tristate "National Semiconductor DP83820 support" ++	depends on PCI ++	help ++	  This is a driver for the National Semiconductor DP83820 series ++	  of gigabit ethernet MACs.  Cards using this chipset include ++	  the D-Link DGE-500T, PureData's PDP8023Z-TG, SMC's SMC9462TX, ++	  SOHO-GA2000T, SOHO-GA2500T.  The driver supports the use of ++	  zero copy. ++ ++config HAMACHI ++	tristate "Packet Engines Hamachi GNIC-II support" ++	depends on PCI ++	select MII ++	help ++	  If you have a Gigabit Ethernet card of this type, say Y and read ++	  the Ethernet-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module will be ++	  called hamachi. ++ ++config YELLOWFIN ++	tristate "Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)" ++	depends on PCI && EXPERIMENTAL ++	select CRC32 ++	---help--- ++	  Say Y here if you have a Packet Engines G-NIC PCI Gigabit Ethernet ++	  adapter or the SYM53C885 Ethernet controller. The Gigabit adapter is ++	  used by the Beowulf Linux cluster project.  See ++	  <http://cesdis.gsfc.nasa.gov/linux/drivers/yellowfin.html> for more ++	  information about this driver in particular and Beowulf in general. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called yellowfin.  This is recommended. ++ ++config R8169 ++	tristate "Realtek 8169 gigabit ethernet support" ++	depends on PCI ++	select CRC32 ++	---help--- ++	  Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called r8169.  This is recommended. ++ ++config R8169_NAPI ++	bool "Use Rx and Tx Polling (NAPI) (EXPERIMENTAL)" ++	depends on R8169 && EXPERIMENTAL ++	help ++	  NAPI is a new driver API designed to reduce CPU and interrupt load ++	  when the driver is receiving lots of packets from the card. It is ++	  still somewhat experimental and thus not yet enabled by default. ++ ++	  If your estimated Rx load is 10kpps or more, or if the card will be ++	  deployed on potentially unfriendly networks (e.g. in a firewall), ++	  then say Y here. ++ ++	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more ++	  information. ++ ++	  If in doubt, say N. ++ ++config R8169_VLAN ++	bool "VLAN support" ++	depends on R8169 && VLAN_8021Q ++	---help--- ++	  Say Y here for the r8169 driver to support the functions required ++	  by the kernel 802.1Q code. ++	   ++	  If in doubt, say Y. ++ ++config SIS190 ++	tristate "SiS190/SiS191 gigabit ethernet support" ++	depends on PCI ++	select CRC32 ++	select MII ++	---help--- ++	  Say Y here if you have a SiS 190 PCI Fast Ethernet adapter or ++	  a SiS 191 PCI Gigabit Ethernet adapter. Both are expected to ++	  appear in lan on motherboard designs which are based on SiS 965 ++	  and SiS 966 south bridge. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called sis190.  This is recommended. ++ ++config SKGE ++	tristate "New SysKonnect GigaEthernet support" ++	depends on PCI ++	select CRC32 ++	---help--- ++	  This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx ++	  and related Gigabit Ethernet adapters. It is a new smaller driver ++	  with better performance and more complete ethtool support. ++ ++	  It does not support the link failover and network management  ++	  features that "portable" vendor supplied sk98lin driver does. ++ ++	  This driver supports adapters based on the original Yukon chipset: ++	  Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T, ++	  Linksys EG1032/EG1064, 3Com 3C940/3C940B, SysKonnect SK-9871/9872. ++ ++	  It does not support the newer Yukon2 chipset: a separate driver, ++	  sky2, is provided for Yukon2-based adapters. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called skge.  This is recommended. ++ ++config SKY2 ++	tristate "SysKonnect Yukon2 support (EXPERIMENTAL)" ++	depends on PCI ++	select CRC32 ++	---help--- ++	  This driver supports Gigabit Ethernet adapters based on the ++	  Marvell Yukon 2 chipset: ++	  Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/ ++	  88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21 ++ ++	  There is companion driver for the older Marvell Yukon and ++	  Genesis based adapters: skge. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called sky2.  This is recommended. ++ ++config SK98LIN ++	tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)" ++	depends on PCI ++	---help--- ++	  Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx ++	  compliant Gigabit Ethernet Adapter. ++ ++	  This driver supports the original Yukon chipset. This driver is ++	  deprecated and will be removed from the kernel in the near future, ++	  it has been replaced by the skge driver. skge is cleaner and ++	  seems to work better. ++ ++	  This driver does not support the newer Yukon2 chipset. A separate ++	  driver, sky2, is provided to support Yukon2-based adapters. ++ ++	  The following adapters are supported by this driver: ++	    - 3Com 3C940 Gigabit LOM Ethernet Adapter ++	    - 3Com 3C941 Gigabit LOM Ethernet Adapter ++	    - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter ++	    - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter ++	    - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter ++	    - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter ++	    - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter ++	    - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter ++	    - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter ++	    - Allied Telesyn AT-2971T Gigabit Ethernet Adapter ++	    - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45 ++	    - EG1032 v2 Instant Gigabit Network Adapter ++	    - EG1064 v2 Instant Gigabit Network Adapter ++	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) ++	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron) ++	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus) ++	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS) ++	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox) ++	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn) ++	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte) ++	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill) ++	    - Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel) ++	    - Marvell RDK-8001 Adapter ++	    - Marvell RDK-8002 Adapter ++	    - Marvell RDK-8003 Adapter ++	    - Marvell RDK-8004 Adapter ++	    - Marvell RDK-8006 Adapter ++	    - Marvell RDK-8007 Adapter ++	    - Marvell RDK-8008 Adapter ++	    - Marvell RDK-8009 Adapter ++	    - Marvell RDK-8010 Adapter ++	    - Marvell RDK-8011 Adapter ++	    - Marvell RDK-8012 Adapter ++	    - Marvell RDK-8052 Adapter ++	    - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit) ++	    - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit) ++	    - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L) ++	    - SK-9521 10/100/1000Base-T Adapter ++	    - SK-9521 V2.0 10/100/1000Base-T Adapter ++	    - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T) ++	    - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter ++	    - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link) ++	    - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX) ++	    - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter ++	    - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link) ++	    - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX) ++	    - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter ++	    - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link) ++	    - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter ++	    - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition) ++	    - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter ++	    - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link) ++	    - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX) ++	    - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter ++	    - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) ++	    - SMC EZ Card 1000 (SMC9452TXV.2) ++	   ++	  The adapters support Jumbo Frames. ++	  The dual link adapters support link-failover and dual port features. ++	  Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support  ++	  the scatter-gather functionality with sendfile(). Please refer to  ++	  <file:Documentation/networking/sk98lin.txt> for more information about ++	  optional driver parameters. ++	  Questions concerning this driver may be addressed to: ++	      <linux@syskonnect.de> ++	   ++	  If you want to compile this driver as a module ( = code which can be ++	  inserted in and removed from the running kernel whenever you want), ++	  say M here and read <file:Documentation/kbuild/modules.txt>. The module will ++	  be called sk98lin. This is recommended. ++ ++config VIA_VELOCITY ++	tristate "VIA Velocity support" ++	depends on NET_PCI && PCI ++	select CRC32 ++	select CRC_CCITT ++	select MII ++	help ++	  If you have a VIA "Velocity" based network card say Y here. ++ ++	  To compile this driver as a module, choose M here. The module ++	  will be called via-velocity. ++ ++config TIGON3 ++	tristate "Broadcom Tigon3 support" ++	depends on PCI ++	help ++	  This driver supports Broadcom Tigon3 based gigabit Ethernet cards. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called tg3.  This is recommended. ++ ++config BNX2 ++	tristate "Broadcom NetXtremeII support" ++	depends on PCI ++	select CRC32 ++	select ZLIB_INFLATE ++	help ++	  This driver supports Broadcom NetXtremeII gigabit Ethernet cards. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called bnx2.  This is recommended. ++ ++config SPIDER_NET ++	tristate "Spider Gigabit Ethernet driver" ++	depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB) ++	select FW_LOADER ++	help ++	  This driver supports the Gigabit Ethernet chips present on the ++	  Cell Processor-Based Blades from IBM. ++ ++config TSI108_ETH ++	   tristate "Tundra TSI108 gigabit Ethernet support" ++	   depends on TSI108_BRIDGE ++	   help ++	     This driver supports Tundra TSI108 gigabit Ethernet ports. ++	     To compile this driver as a module, choose M here: the module ++	     will be called tsi108_eth. ++ ++config GIANFAR ++	tristate "Gianfar Ethernet" ++	depends on 85xx || 83xx || PPC_86xx ++	select PHYLIB ++	select CRC32 ++	help ++	  This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx, ++	  and MPC86xx family of chips, and the FEC on the 8540. ++ ++config GFAR_NAPI ++	bool "NAPI Support" ++	depends on GIANFAR ++ ++config UCC_GETH ++	tristate "Freescale QE UCC GETH" ++	depends on QUICC_ENGINE && UCC_FAST ++	help ++	  This driver supports the Gigabit Ethernet mode of QE UCC. ++	  QE can be found on MPC836x CPUs. ++ ++config UGETH_NAPI ++	bool "NAPI Support" ++	depends on UCC_GETH ++ ++config UGETH_MAGIC_PACKET ++	bool "Magic Packet detection support" ++	depends on UCC_GETH ++ ++config UGETH_FILTERING ++	bool "Mac address filtering support" ++	depends on UCC_GETH ++ ++config UGETH_TX_ON_DEMOND ++	bool "Transmit on Demond support" ++	depends on UCC_GETH ++ ++config UGETH_HAS_GIGA ++	bool ++	depends on UCC_GETH && PPC_MPC836x ++ ++config MV643XX_ETH ++	tristate "MV-643XX Ethernet support" ++	depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MOMENCO_OCELOT_3 || (PPC_MULTIPLATFORM && PPC32) ++	select MII ++	help ++	  This driver supports the gigabit Ethernet on the Marvell MV643XX ++	  chipset which is used in the Momenco Ocelot C and Jaguar ATX and ++	  Pegasos II, amongst other PPC and MIPS boards. ++ ++config QLA3XXX ++	tristate "QLogic QLA3XXX Network Driver Support" ++	depends on PCI ++	help ++	  This driver supports QLogic ISP3XXX gigabit Ethernet cards. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called qla3xxx. ++ ++config ATL1 ++	tristate "Attansic L1 Gigabit Ethernet support (EXPERIMENTAL)" ++	depends on PCI && EXPERIMENTAL ++	select CRC32 ++	select MII ++	help ++	  This driver supports the Attansic L1 gigabit ethernet adapter. ++ ++	  To compile this driver as a module, choose M here.  The module ++	  will be called atl1. ++ ++endmenu ++ ++# ++#	10 Gigabit Ethernet ++# ++ ++menu "Ethernet (10000 Mbit)" ++	depends on !UML ++ ++config CHELSIO_T1 ++        tristate "Chelsio 10Gb Ethernet support" ++        depends on PCI ++	select CRC32 ++        help ++          This driver supports Chelsio gigabit and 10-gigabit ++          Ethernet cards. More information about adapter features and ++	  performance tuning is in <file:Documentation/networking/cxgb.txt>. ++ ++          For general information about Chelsio and our products, visit ++          our website at <http://www.chelsio.com>. ++ ++          For customer support, please visit our customer support page at ++          <http://www.chelsio.com/support.htm>. ++ ++          Please send feedback to <linux-bugs@chelsio.com>. ++ ++          To compile this driver as a module, choose M here: the module ++          will be called cxgb. ++ ++config CHELSIO_T1_1G ++        bool "Chelsio gigabit Ethernet support" ++        depends on CHELSIO_T1 ++        help ++          Enables support for Chelsio's gigabit Ethernet PCI cards.  If you ++          are using only 10G cards say 'N' here. ++ ++config CHELSIO_T1_NAPI ++	bool "Use Rx Polling (NAPI)" ++	depends on CHELSIO_T1 ++	default y ++	help ++	  NAPI is a driver API designed to reduce CPU and interrupt load ++	  when the driver is receiving lots of packets from the card. ++ ++config CHELSIO_T3 ++	tristate "Chelsio Communications T3 10Gb Ethernet support" ++	depends on PCI ++	select FW_LOADER ++	help ++	  This driver supports Chelsio T3-based gigabit and 10Gb Ethernet ++	  adapters. ++ ++	  For general information about Chelsio and our products, visit ++	  our website at <http://www.chelsio.com>. ++ ++	  For customer support, please visit our customer support page at ++	  <http://www.chelsio.com/support.htm>. ++ ++	  Please send feedback to <linux-bugs@chelsio.com>. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called cxgb3. ++ ++config EHEA ++	tristate "eHEA Ethernet support" ++	depends on IBMEBUS ++	---help--- ++	  This driver supports the IBM pSeries eHEA ethernet adapter. ++ ++	  To compile the driver as a module, choose M here. The module ++	  will be called ehea. ++ ++config IXGB ++	tristate "Intel(R) PRO/10GbE support" ++	depends on PCI ++	---help--- ++	  This driver supports Intel(R) PRO/10GbE family of ++	  adapters.  For more information on how to identify your adapter, go ++	  to the Adapter & Driver ID Guide at: ++ ++	  <http://support.intel.com/support/network/adapter/pro100/21397.htm> ++ ++	  For general information and support, go to the Intel support ++	  website at: ++ ++	  <http://support.intel.com> ++ ++	  More specific information on configuring the driver is in  ++	  <file:Documentation/networking/ixgb.txt>. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module ++	  will be called ixgb. ++ ++config IXGB_NAPI ++	bool "Use Rx Polling (NAPI) (EXPERIMENTAL)" ++	depends on IXGB && EXPERIMENTAL ++	help ++	  NAPI is a new driver API designed to reduce CPU and interrupt load ++	  when the driver is receiving lots of packets from the card. It is ++	  still somewhat experimental and thus not yet enabled by default. ++ ++	  If your estimated Rx load is 10kpps or more, or if the card will be ++	  deployed on potentially unfriendly networks (e.g. in a firewall), ++	  then say Y here. ++ ++	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more ++	  information. ++ ++	  If in doubt, say N. ++ ++config S2IO ++	tristate "S2IO 10Gbe XFrame NIC" ++	depends on PCI ++	---help--- ++	  This driver supports the 10Gbe XFrame NIC of S2IO.  ++	  More specific information on configuring the driver is in  ++	  <file:Documentation/networking/s2io.txt>. ++ ++config S2IO_NAPI ++	bool "Use Rx Polling (NAPI) (EXPERIMENTAL)" ++	depends on S2IO && EXPERIMENTAL ++	help ++	  NAPI is a new driver API designed to reduce CPU and interrupt load ++	  when the driver is receiving lots of packets from the card. It is ++	  still somewhat experimental and thus not yet enabled by default. ++ ++	  If your estimated Rx load is 10kpps or more, or if the card will be ++	  deployed on potentially unfriendly networks (e.g. in a firewall), ++	  then say Y here. ++ ++	  See <file:Documentation/networking/NAPI_HOWTO.txt> for more ++	  information. ++ ++	  If in doubt, say N. ++ ++config MYRI10GE ++	tristate "Myricom Myri-10G Ethernet support" ++	depends on PCI ++	select FW_LOADER ++	select CRC32 ++	---help--- ++	  This driver supports Myricom Myri-10G Dual Protocol interface in ++	  Ethernet mode. If the eeprom on your board is not recent enough, ++	  you will need a newer firmware image. ++	  You may get this image or more information, at: ++ ++	  <http://www.myri.com/scs/download-Myri10GE.html> ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module ++	  will be called myri10ge. ++ ++config NETXEN_NIC ++	tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC" ++	depends on PCI ++	help ++	  This enables the support for NetXen's Gigabit Ethernet card. ++ ++config PASEMI_MAC ++	tristate "PA Semi 1/10Gbit MAC" ++	depends on PPC64 && PCI ++	help ++	  This driver supports the on-chip 1/10Gbit Ethernet controller on ++	  PA Semi's PWRficient line of chips. ++ ++endmenu ++ ++source "drivers/net/tokenring/Kconfig" ++ ++source "drivers/net/wireless/Kconfig" ++ ++source "drivers/net/pcmcia/Kconfig" ++ ++source "drivers/net/wan/Kconfig" ++ ++source "drivers/atm/Kconfig" ++ ++source "drivers/s390/net/Kconfig" ++ ++config ISERIES_VETH ++	tristate "iSeries Virtual Ethernet driver support" ++	depends on PPC_ISERIES ++ ++config RIONET ++	tristate "RapidIO Ethernet over messaging driver support" ++	depends on RAPIDIO ++ ++config RIONET_TX_SIZE ++	int "Number of outbound queue entries" ++	depends on RIONET ++	default "128" ++ ++config RIONET_RX_SIZE ++	int "Number of inbound queue entries" ++	depends on RIONET ++	default "128" ++ ++config FDDI ++	bool "FDDI driver support" ++	depends on (PCI || EISA || TC) ++	help ++	  Fiber Distributed Data Interface is a high speed local area network ++	  design; essentially a replacement for high speed Ethernet. FDDI can ++	  run over copper or fiber. If you are connected to such a network and ++	  want a driver for the FDDI card in your computer, say Y here (and ++	  then also Y to the driver for your FDDI card, below). Most people ++	  will say N. ++ ++config DEFXX ++	tristate "Digital DEFTA/DEFEA/DEFPA adapter support" ++	depends on FDDI && (PCI || EISA || TC) ++	---help--- ++	  This is support for the DIGITAL series of TURBOchannel (DEFTA), ++	  EISA (DEFEA) and PCI (DEFPA) controllers which can connect you ++	  to a local FDDI network. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called defxx.  If unsure, say N. ++ ++config DEFXX_MMIO ++	bool ++	prompt "Use MMIO instead of PIO" if PCI || EISA ++	depends on DEFXX ++	default n if PCI || EISA ++	default y ++	---help--- ++	  This instructs the driver to use EISA or PCI memory-mapped I/O ++	  (MMIO) as appropriate instead of programmed I/O ports (PIO). ++	  Enabling this gives an improvement in processing time in parts ++	  of the driver, but it may cause problems with EISA (DEFEA) ++	  adapters.  TURBOchannel does not have the concept of I/O ports, ++	  so MMIO is always used for these (DEFTA) adapters. ++ ++	  If unsure, say N. ++ ++config SKFP ++	tristate "SysKonnect FDDI PCI support" ++	depends on FDDI && PCI ++	select BITREVERSE ++	---help--- ++	  Say Y here if you have a SysKonnect FDDI PCI adapter. ++	  The following adapters are supported by this driver: ++	  - SK-5521 (SK-NET FDDI-UP) ++	  - SK-5522 (SK-NET FDDI-UP DAS) ++	  - SK-5541 (SK-NET FDDI-FP) ++	  - SK-5543 (SK-NET FDDI-LP) ++	  - SK-5544 (SK-NET FDDI-LP DAS) ++	  - SK-5821 (SK-NET FDDI-UP64) ++	  - SK-5822 (SK-NET FDDI-UP64 DAS) ++	  - SK-5841 (SK-NET FDDI-FP64) ++	  - SK-5843 (SK-NET FDDI-LP64) ++	  - SK-5844 (SK-NET FDDI-LP64 DAS) ++	  - Netelligent 100 FDDI DAS Fibre SC ++	  - Netelligent 100 FDDI SAS Fibre SC ++	  - Netelligent 100 FDDI DAS UTP ++	  - Netelligent 100 FDDI SAS UTP ++	  - Netelligent 100 FDDI SAS Fibre MIC ++ ++	  Read <file:Documentation/networking/skfp.txt> for information about ++	  the driver. ++ ++	  Questions concerning this driver can be addressed to: ++	  <linux@syskonnect.de> ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called skfp.  This is recommended. ++ ++config HIPPI ++	bool "HIPPI driver support (EXPERIMENTAL)" ++	depends on EXPERIMENTAL && INET && PCI ++	help ++	  HIgh Performance Parallel Interface (HIPPI) is a 800Mbit/sec and ++	  1600Mbit/sec dual-simplex switched or point-to-point network. HIPPI ++	  can run over copper (25m) or fiber (300m on multi-mode or 10km on ++	  single-mode). HIPPI networks are commonly used for clusters and to ++	  connect to super computers. If you are connected to a HIPPI network ++	  and have a HIPPI network card in your computer that you want to use ++	  under Linux, say Y here (you must also remember to enable the driver ++	  for your HIPPI card below). Most people will say N here. ++ ++config ROADRUNNER ++	tristate "Essential RoadRunner HIPPI PCI adapter support (EXPERIMENTAL)" ++	depends on HIPPI && PCI ++	help ++	  Say Y here if this is your PCI HIPPI network card. ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called rrunner.  If unsure, say N. ++ ++config ROADRUNNER_LARGE_RINGS ++	bool "Use large TX/RX rings (EXPERIMENTAL)" ++	depends on ROADRUNNER ++	help ++	  If you say Y here, the RoadRunner driver will preallocate up to 2 MB ++	  of additional memory to allow for fastest operation, both for ++	  transmitting and receiving. This memory cannot be used by any other ++	  kernel code or by user space programs. Say Y here only if you have ++	  the memory. ++ ++config PLIP ++	tristate "PLIP (parallel port) support" ++	depends on PARPORT ++	---help--- ++	  PLIP (Parallel Line Internet Protocol) is used to create a ++	  reasonably fast mini network consisting of two (or, rarely, more) ++	  local machines.  A PLIP link from a Linux box is a popular means to ++	  install a Linux distribution on a machine which doesn't have a ++	  CD-ROM drive (a minimal system has to be transferred with floppies ++	  first). The kernels on both machines need to have this PLIP option ++	  enabled for this to work. ++ ++	  The PLIP driver has two modes, mode 0 and mode 1.  The parallel ++	  ports (the connectors at the computers with 25 holes) are connected ++	  with "null printer" or "Turbo Laplink" cables which can transmit 4 ++	  bits at a time (mode 0) or with special PLIP cables, to be used on ++	  bidirectional parallel ports only, which can transmit 8 bits at a ++	  time (mode 1); you can find the wiring of these cables in ++	  <file:Documentation/networking/PLIP.txt>.  The cables can be up to ++	  15m long.  Mode 0 works also if one of the machines runs DOS/Windows ++	  and has some PLIP software installed, e.g. the Crynwr PLIP packet ++	  driver (<http://oak.oakland.edu/simtel.net/msdos/pktdrvr-pre.html>) ++	  and winsock or NCSA's telnet. ++ ++	  If you want to use PLIP, say Y and read the PLIP mini-HOWTO as well ++	  as the NET-3-HOWTO, both available from ++	  <http://www.tldp.org/docs.html#howto>.  Note that the PLIP ++	  protocol has been changed and this PLIP driver won't work together ++	  with the PLIP support in Linux versions 1.0.x.  This option enlarges ++	  your kernel by about 8 KB. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>.  The module will be ++	  called plip.  If unsure, say Y or M, in case you buy a laptop ++	  later. ++ ++config PPP ++	tristate "PPP (point-to-point protocol) support" ++	select SLHC ++	---help--- ++	  PPP (Point to Point Protocol) is a newer and better SLIP.  It serves ++	  the same purpose: sending Internet traffic over telephone (and other ++	  serial) lines.  Ask your access provider if they support it, because ++	  otherwise you can't use it; most Internet access providers these ++	  days support PPP rather than SLIP. ++ ++	  To use PPP, you need an additional program called pppd as described ++	  in the PPP-HOWTO, available at ++	  <http://www.tldp.org/docs.html#howto>.  Make sure that you have ++	  the version of pppd recommended in <file:Documentation/Changes>. ++	  The PPP option enlarges your kernel by about 16 KB. ++ ++	  There are actually two versions of PPP: the traditional PPP for ++	  asynchronous lines, such as regular analog phone lines, and ++	  synchronous PPP which can be used over digital ISDN lines for ++	  example.  If you want to use PPP over phone lines or other ++	  asynchronous serial lines, you need to say Y (or M) here and also to ++	  the next option, "PPP support for async serial ports".  For PPP over ++	  synchronous lines, you should say Y (or M) here and to "Support ++	  synchronous PPP", below. ++ ++	  If you said Y to "Version information on all symbols" above, then ++	  you cannot compile the PPP driver into the kernel; you can then only ++	  compile it as a module. To compile this driver as a module, choose M ++	  here and read <file:Documentation/networking/net-modules.txt>. ++	  The module will be called ppp_generic. ++ ++config PPP_MULTILINK ++	bool "PPP multilink support (EXPERIMENTAL)" ++	depends on PPP && EXPERIMENTAL ++	help ++	  PPP multilink is a protocol (defined in RFC 1990) which allows you ++	  to combine several (logical or physical) lines into one logical PPP ++	  connection, so that you can utilize your full bandwidth. ++ ++	  This has to be supported at the other end as well and you need a ++	  version of the pppd daemon which understands the multilink protocol. ++ ++	  If unsure, say N. ++ ++config PPP_FILTER ++	bool "PPP filtering" ++	depends on PPP ++	help ++	  Say Y here if you want to be able to filter the packets passing over ++	  PPP interfaces.  This allows you to control which packets count as ++	  activity (i.e. which packets will reset the idle timer or bring up ++	  a demand-dialed link) and which packets are to be dropped entirely. ++	  You need to say Y here if you wish to use the pass-filter and ++	  active-filter options to pppd. ++ ++	  If unsure, say N. ++ ++config PPP_ASYNC ++	tristate "PPP support for async serial ports" ++	depends on PPP ++	select CRC_CCITT ++	---help--- ++	  Say Y (or M) here if you want to be able to use PPP over standard ++	  asynchronous serial ports, such as COM1 or COM2 on a PC.  If you use ++	  a modem (not a synchronous or ISDN modem) to contact your ISP, you ++	  need this option. ++ ++	  To compile this driver as a module, choose M here. ++ ++	  If unsure, say Y. ++ ++config PPP_SYNC_TTY ++	tristate "PPP support for sync tty ports" ++	depends on PPP ++	help ++	  Say Y (or M) here if you want to be able to use PPP over synchronous ++	  (HDLC) tty devices, such as the SyncLink adapter. These devices ++	  are often used for high-speed leased lines like T1/E1. ++ ++	  To compile this driver as a module, choose M here. ++ ++config PPP_DEFLATE ++	tristate "PPP Deflate compression" ++	depends on PPP ++	select ZLIB_INFLATE ++	select ZLIB_DEFLATE ++	---help--- ++	  Support for the Deflate compression method for PPP, which uses the ++	  Deflate algorithm (the same algorithm that gzip uses) to compress ++	  each PPP packet before it is sent over the wire.  The machine at the ++	  other end of the PPP link (usually your ISP) has to support the ++	  Deflate compression method as well for this to be useful.  Even if ++	  they don't support it, it is safe to say Y here. ++ ++	  To compile this driver as a module, choose M here. ++ ++config PPP_BSDCOMP ++	tristate "PPP BSD-Compress compression" ++	depends on PPP ++	---help--- ++	  Support for the BSD-Compress compression method for PPP, which uses ++	  the LZW compression method to compress each PPP packet before it is ++	  sent over the wire. The machine at the other end of the PPP link ++	  (usually your ISP) has to support the BSD-Compress compression ++	  method as well for this to be useful. Even if they don't support it, ++	  it is safe to say Y here. ++ ++	  The PPP Deflate compression method ("PPP Deflate compression", ++	  above) is preferable to BSD-Compress, because it compresses better ++	  and is patent-free. ++ ++	  Note that the BSD compression code will always be compiled as a ++	  module; it is called bsd_comp and will show up in the directory ++	  modules once you have said "make modules". If unsure, say N. ++ ++config PPP_MPPE ++       tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)" ++       depends on PPP && EXPERIMENTAL ++       select CRYPTO ++       select CRYPTO_SHA1 ++       select CRYPTO_ARC4 ++       select CRYPTO_ECB ++       ---help--- ++         Support for the MPPE Encryption protocol, as employed by the ++	 Microsoft Point-to-Point Tunneling Protocol. ++ ++	 See http://pptpclient.sourceforge.net/ for information on ++	 configuring PPTP clients and servers to utilize this method. ++ ++config PPPOE ++	tristate "PPP over Ethernet (EXPERIMENTAL)" ++	depends on EXPERIMENTAL && PPP ++	help ++	  Support for PPP over Ethernet. ++ ++	  This driver requires the latest version of pppd from the CVS ++	  repository at cvs.samba.org.  Alternatively, see the  ++	  RoaringPenguin package (<http://www.roaringpenguin.com/pppoe>) ++	  which contains instruction on how to use this driver (under  ++	  the heading "Kernel mode PPPoE"). ++ ++config PPPOATM ++	tristate "PPP over ATM" ++	depends on ATM && PPP ++	help ++	  Support PPP (Point to Point Protocol) encapsulated in ATM frames. ++	  This implementation does not yet comply with section 8 of RFC2364, ++	  which can lead to bad results if the ATM peer loses state and ++	  changes its encapsulation unilaterally. ++ ++config SLIP ++	tristate "SLIP (serial line) support" ++	---help--- ++	  Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to ++	  connect to your Internet service provider or to connect to some ++	  other local Unix box or if you want to configure your Linux box as a ++	  Slip/CSlip server for other people to dial in. SLIP (Serial Line ++	  Internet Protocol) is a protocol used to send Internet traffic over ++	  serial connections such as telephone lines or null modem cables; ++	  nowadays, the protocol PPP is more commonly used for this same ++	  purpose. ++ ++	  Normally, your access provider has to support SLIP in order for you ++	  to be able to use it, but there is now a SLIP emulator called SLiRP ++	  around (available from ++	  <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which ++	  allows you to use SLIP over a regular dial up shell connection. If ++	  you plan to use SLiRP, make sure to say Y to CSLIP, below. The ++	  NET-3-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>, explains how to ++	  configure SLIP. Note that you don't need this option if you just ++	  want to run term (term is a program which gives you almost full ++	  Internet connectivity if you have a regular dial up shell account on ++	  some Internet connected Unix computer. Read ++	  <http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html>). SLIP ++	  support will enlarge your kernel by about 4 KB. If unsure, say N. ++ ++	  To compile this driver as a module, choose M here and read ++	  <file:Documentation/networking/net-modules.txt>. The module will be ++	  called slip. ++ ++config SLIP_COMPRESSED ++	bool "CSLIP compressed headers" ++	depends on SLIP ++	select SLHC ++	---help--- ++	  This protocol is faster than SLIP because it uses compression on the ++	  TCP/IP headers (not on the data itself), but it has to be supported ++	  on both ends. Ask your access provider if you are not sure and ++	  answer Y, just in case. You will still be able to use plain SLIP. If ++	  you plan to use SLiRP, the SLIP emulator (available from ++	  <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which ++	  allows you to use SLIP over a regular dial up shell connection, you ++	  definitely want to say Y here. The NET-3-HOWTO, available from ++	  <http://www.tldp.org/docs.html#howto>, explains how to configure ++	  CSLIP. This won't enlarge your kernel. ++ ++config SLHC ++	tristate ++	help ++	  This option enables Van Jacobsen serial line header compression ++	  routines. ++ ++config SLIP_SMART ++	bool "Keepalive and linefill" ++	depends on SLIP ++	help ++	  Adds additional capabilities to the SLIP driver to support the ++	  RELCOM line fill and keepalive monitoring. Ideal on poor quality ++	  analogue lines. ++ ++config SLIP_MODE_SLIP6 ++	bool "Six bit SLIP encapsulation" ++	depends on SLIP ++	help ++	  Just occasionally you may need to run IP over hostile serial ++	  networks that don't pass all control characters or are only seven ++	  bit. Saying Y here adds an extra mode you can use with SLIP: ++	  "slip6". In this mode, SLIP will only send normal ASCII symbols over ++	  the serial device. Naturally, this has to be supported at the other ++	  end of the link as well. It's good enough, for example, to run IP ++	  over the async ports of a Camtec JNT Pad. If unsure, say N. ++ ++config NET_FC ++	bool "Fibre Channel driver support" ++	depends on SCSI && PCI ++	help ++	  Fibre Channel is a high speed serial protocol mainly used to connect ++	  large storage devices to the computer; it is compatible with and ++	  intended to replace SCSI. ++ ++	  If you intend to use Fibre Channel, you need to have a Fibre channel ++	  adaptor card in your computer; say Y here and to the driver for your ++	  adaptor below. You also should have said Y to "SCSI support" and ++	  "SCSI generic support". ++ ++config SHAPER ++	tristate "Traffic Shaper (OBSOLETE)" ++	depends on EXPERIMENTAL ++	---help--- ++	  The traffic shaper is a virtual network device that allows you to ++	  limit the rate of outgoing data flow over some other network device. ++	  The traffic that you want to slow down can then be routed through ++	  these virtual devices. See ++	  <file:Documentation/networking/shaper.txt> for more information. ++ ++	  An alternative to this traffic shaper are traffic schedulers which ++	  you'll get if you say Y to "QoS and/or fair queuing" in ++	  "Networking options". ++ ++	  To compile this driver as a module, choose M here: the module ++	  will be called shaper.  If unsure, say N. ++ ++config NETCONSOLE ++	tristate "Network console logging support (EXPERIMENTAL)" ++	depends on EXPERIMENTAL ++	---help--- ++	If you want to log kernel messages over the network, enable this. ++	See <file:Documentation/networking/netconsole.txt> for details. ++ ++endif #NETDEVICES ++ ++config NETPOLL ++	def_bool NETCONSOLE ++ ++config NETPOLL_RX ++	bool "Netpoll support for trapping incoming packets" ++	default n ++	depends on NETPOLL ++ ++config NETPOLL_TRAP ++	bool "Netpoll traffic trapping" ++	default n ++	depends on NETPOLL ++ ++config NET_POLL_CONTROLLER ++	def_bool NETPOLL ++ ++endmenu +diff -Nur linux-2.6.21.1/drivers/net/Makefile linux-2.6.21.1-owrt/drivers/net/Makefile +--- linux-2.6.21.1/drivers/net/Makefile	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/drivers/net/Makefile	2007-05-23 23:37:01.000000000 +0200 +@@ -11,6 +11,7 @@ + obj-$(CONFIG_BONDING) += bonding/ + obj-$(CONFIG_ATL1) += atl1/ + obj-$(CONFIG_GIANFAR) += gianfar_driver.o ++obj-$(CONFIG_AR2313) += ar2313/ - obj-$(CONFIG_OAKNET) += oaknet.o 8390.o + gianfar_driver-objs := gianfar.o \ + 		gianfar_ethtool.o \ +@@ -38,6 +39,7 @@ + obj-$(CONFIG_MACE) += mace.o + obj-$(CONFIG_BMAC) += bmac.o  +obj-$(CONFIG_IDT_RC32434_ETH) += rc32434_eth.o   obj-$(CONFIG_DGRS) += dgrs.o   obj-$(CONFIG_VORTEX) += 3c59x.o   obj-$(CONFIG_TYPHOON) += typhoon.o -diff -Nur linux-2.6.17/drivers/net/natsemi.c linux-2.6.17-owrt/drivers/net/natsemi.c ---- linux-2.6.17/drivers/net/natsemi.c	2006-06-18 03:49:35.000000000 +0200 -+++ linux-2.6.17-owrt/drivers/net/natsemi.c	2006-06-18 12:44:28.000000000 +0200 -@@ -771,6 +771,49 @@ +diff -Nur linux-2.6.21.1/drivers/net/Makefile.orig linux-2.6.21.1-owrt/drivers/net/Makefile.orig +--- linux-2.6.21.1/drivers/net/Makefile.orig	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.1-owrt/drivers/net/Makefile.orig	2007-05-23 23:34:01.000000000 +0200 +@@ -0,0 +1,221 @@ ++# ++# Makefile for the Linux network (ethercard) device drivers. ++# ++ ++obj-$(CONFIG_E1000) += e1000/ ++obj-$(CONFIG_IBM_EMAC) += ibm_emac/ ++obj-$(CONFIG_IXGB) += ixgb/ ++obj-$(CONFIG_CHELSIO_T1) += chelsio/ ++obj-$(CONFIG_CHELSIO_T3) += cxgb3/ ++obj-$(CONFIG_EHEA) += ehea/ ++obj-$(CONFIG_BONDING) += bonding/ ++obj-$(CONFIG_ATL1) += atl1/ ++obj-$(CONFIG_GIANFAR) += gianfar_driver.o ++ ++gianfar_driver-objs := gianfar.o \ ++		gianfar_ethtool.o \ ++		gianfar_mii.o \ ++		gianfar_sysfs.o ++ ++obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o ++ucc_geth_driver-objs := ucc_geth.o ucc_geth_phy.o ++ ++# ++# link order important here ++# ++obj-$(CONFIG_PLIP) += plip.o ++ ++obj-$(CONFIG_ROADRUNNER) += rrunner.o ++ ++obj-$(CONFIG_HAPPYMEAL) += sunhme.o ++obj-$(CONFIG_SUNLANCE) += sunlance.o ++obj-$(CONFIG_SUNQE) += sunqe.o ++obj-$(CONFIG_SUNBMAC) += sunbmac.o ++obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o ++obj-$(CONFIG_SUNGEM) += sungem.o sungem_phy.o ++obj-$(CONFIG_CASSINI) += cassini.o ++ ++obj-$(CONFIG_MACE) += mace.o ++obj-$(CONFIG_BMAC) += bmac.o ++ ++obj-$(CONFIG_IDT_RC32434_ETH) += rc32434_eth.o ++obj-$(CONFIG_DGRS) += dgrs.o ++obj-$(CONFIG_VORTEX) += 3c59x.o ++obj-$(CONFIG_TYPHOON) += typhoon.o ++obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o ++obj-$(CONFIG_PCNET32) += pcnet32.o ++obj-$(CONFIG_EEPRO100) += eepro100.o ++obj-$(CONFIG_E100) += e100.o ++obj-$(CONFIG_TLAN) += tlan.o ++obj-$(CONFIG_EPIC100) += epic100.o ++obj-$(CONFIG_SIS190) += sis190.o ++obj-$(CONFIG_SIS900) += sis900.o ++obj-$(CONFIG_YELLOWFIN) += yellowfin.o ++obj-$(CONFIG_ACENIC) += acenic.o ++obj-$(CONFIG_ISERIES_VETH) += iseries_veth.o ++obj-$(CONFIG_NATSEMI) += natsemi.o ++obj-$(CONFIG_NS83820) += ns83820.o ++obj-$(CONFIG_STNIC) += stnic.o 8390.o ++obj-$(CONFIG_FEALNX) += fealnx.o ++obj-$(CONFIG_TIGON3) += tg3.o ++obj-$(CONFIG_BNX2) += bnx2.o ++spidernet-y += spider_net.o spider_net_ethtool.o ++obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o ++obj-$(CONFIG_TC35815) += tc35815.o ++obj-$(CONFIG_SKGE) += skge.o ++obj-$(CONFIG_SKY2) += sky2.o ++obj-$(CONFIG_SK98LIN) += sk98lin/ ++obj-$(CONFIG_SKFP) += skfp/ ++obj-$(CONFIG_VIA_RHINE) += via-rhine.o ++obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o ++obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o ++obj-$(CONFIG_RIONET) += rionet.o ++ ++# ++# end link order section ++# ++ ++obj-$(CONFIG_MII) += mii.o ++obj-$(CONFIG_PHYLIB) += phy/ ++ ++obj-$(CONFIG_SUNDANCE) += sundance.o ++obj-$(CONFIG_HAMACHI) += hamachi.o ++obj-$(CONFIG_NET) += Space.o loopback.o ++obj-$(CONFIG_SEEQ8005) += seeq8005.o ++obj-$(CONFIG_NET_SB1000) += sb1000.o ++obj-$(CONFIG_MAC8390) += mac8390.o ++obj-$(CONFIG_APNE) += apne.o 8390.o ++obj-$(CONFIG_PCMCIA_PCNET) += 8390.o ++obj-$(CONFIG_SHAPER) += shaper.o ++obj-$(CONFIG_HP100) += hp100.o ++obj-$(CONFIG_SMC9194) += smc9194.o ++obj-$(CONFIG_FEC) += fec.o ++obj-$(CONFIG_68360_ENET) += 68360enet.o ++obj-$(CONFIG_WD80x3) += wd.o 8390.o ++obj-$(CONFIG_EL2) += 3c503.o 8390.o ++obj-$(CONFIG_NE2000) += ne.o 8390.o ++obj-$(CONFIG_NE2_MCA) += ne2.o 8390.o ++obj-$(CONFIG_HPLAN) += hp.o 8390.o ++obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390.o ++obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o ++obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o ++obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o ++obj-$(CONFIG_E2100) += e2100.o 8390.o ++obj-$(CONFIG_ES3210) += es3210.o 8390.o ++obj-$(CONFIG_LNE390) += lne390.o 8390.o ++obj-$(CONFIG_NE3210) += ne3210.o 8390.o ++obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o ++obj-$(CONFIG_B44) += b44.o ++obj-$(CONFIG_FORCEDETH) += forcedeth.o ++obj-$(CONFIG_NE_H8300) += ne-h8300.o ++ ++obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o ++obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o ++obj-$(CONFIG_QLA3XXX) += qla3xxx.o ++ ++obj-$(CONFIG_PPP) += ppp_generic.o ++obj-$(CONFIG_PPP_ASYNC) += ppp_async.o ++obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o ++obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o ++obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o ++obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o ++obj-$(CONFIG_PPPOE) += pppox.o pppoe.o ++ ++obj-$(CONFIG_SLIP) += slip.o ++obj-$(CONFIG_SLHC) += slhc.o ++ ++obj-$(CONFIG_DUMMY) += dummy.o ++obj-$(CONFIG_IFB) += ifb.o ++obj-$(CONFIG_DE600) += de600.o ++obj-$(CONFIG_DE620) += de620.o ++obj-$(CONFIG_LANCE) += lance.o ++obj-$(CONFIG_SUN3_82586) += sun3_82586.o ++obj-$(CONFIG_SUN3LANCE) += sun3lance.o ++obj-$(CONFIG_DEFXX) += defxx.o ++obj-$(CONFIG_SGISEEQ) += sgiseeq.o ++obj-$(CONFIG_SGI_O2MACE_ETH) += meth.o ++obj-$(CONFIG_AT1700) += at1700.o ++obj-$(CONFIG_EL1) += 3c501.o ++obj-$(CONFIG_EL16) += 3c507.o ++obj-$(CONFIG_ELMC) += 3c523.o ++obj-$(CONFIG_IBMLANA) += ibmlana.o ++obj-$(CONFIG_ELMC_II) += 3c527.o ++obj-$(CONFIG_EL3) += 3c509.o ++obj-$(CONFIG_3C515) += 3c515.o ++obj-$(CONFIG_EEXPRESS) += eexpress.o ++obj-$(CONFIG_EEXPRESS_PRO) += eepro.o ++obj-$(CONFIG_8139CP) += 8139cp.o ++obj-$(CONFIG_8139TOO) += 8139too.o ++obj-$(CONFIG_ZNET) += znet.o ++obj-$(CONFIG_LAN_SAA9730) += saa9730.o ++obj-$(CONFIG_DEPCA) += depca.o ++obj-$(CONFIG_EWRK3) += ewrk3.o ++obj-$(CONFIG_ATP) += atp.o ++obj-$(CONFIG_NI5010) += ni5010.o ++obj-$(CONFIG_NI52) += ni52.o ++obj-$(CONFIG_NI65) += ni65.o ++obj-$(CONFIG_ELPLUS) += 3c505.o ++obj-$(CONFIG_AC3200) += ac3200.o 8390.o ++obj-$(CONFIG_APRICOT) += 82596.o ++obj-$(CONFIG_LASI_82596) += lasi_82596.o ++obj-$(CONFIG_MVME16x_NET) += 82596.o ++obj-$(CONFIG_BVME6000_NET) += 82596.o ++obj-$(CONFIG_SC92031) += sc92031.o ++ ++# This is also a 82596 and should probably be merged ++obj-$(CONFIG_LP486E) += lp486e.o ++ ++obj-$(CONFIG_ETH16I) += eth16i.o ++obj-$(CONFIG_ZORRO8390) += zorro8390.o ++obj-$(CONFIG_HPLANCE) += hplance.o 7990.o ++obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o ++obj-$(CONFIG_EQUALIZER) += eql.o ++obj-$(CONFIG_MIPS_JAZZ_SONIC) += jazzsonic.o ++obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o ++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_BIONET) += atari_bionet.o ++obj-$(CONFIG_ATARI_PAMSNET) += atari_pamsnet.o ++obj-$(CONFIG_A2065) += a2065.o ++obj-$(CONFIG_HYDRA) += hydra.o ++obj-$(CONFIG_ARIADNE) += ariadne.o ++obj-$(CONFIG_CS89x0) += cs89x0.o ++obj-$(CONFIG_MACSONIC) += macsonic.o ++obj-$(CONFIG_MACMACE) += macmace.o ++obj-$(CONFIG_MAC89x0) += mac89x0.o ++obj-$(CONFIG_TUN) += tun.o ++obj-$(CONFIG_NET_NETX) += netx-eth.o ++obj-$(CONFIG_DL2K) += dl2k.o ++obj-$(CONFIG_R8169) += r8169.o ++obj-$(CONFIG_AMD8111_ETH) += amd8111e.o ++obj-$(CONFIG_IBMVETH) += ibmveth.o ++obj-$(CONFIG_S2IO) += s2io.o ++obj-$(CONFIG_MYRI10GE) += myri10ge/ ++obj-$(CONFIG_SMC91X) += smc91x.o ++obj-$(CONFIG_SMC911X) += smc911x.o ++obj-$(CONFIG_DM9000) += dm9000.o ++obj-$(CONFIG_FEC_8XX) += fec_8xx/ ++obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o ++ ++obj-$(CONFIG_MACB) += macb.o ++ ++obj-$(CONFIG_ARM) += arm/ ++obj-$(CONFIG_DEV_APPLETALK) += appletalk/ ++obj-$(CONFIG_TR) += tokenring/ ++obj-$(CONFIG_WAN) += wan/ ++obj-$(CONFIG_ARCNET) += arcnet/ ++obj-$(CONFIG_NET_PCMCIA) += pcmcia/ ++obj-$(CONFIG_NET_RADIO) += wireless/ ++obj-$(CONFIG_NET_TULIP) += tulip/ ++obj-$(CONFIG_HAMRADIO) += hamradio/ ++obj-$(CONFIG_IRDA) += irda/ ++obj-$(CONFIG_ETRAX_ETHERNET) += cris/ ++obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/ ++ ++obj-$(CONFIG_NETCONSOLE) += netconsole.o ++ ++obj-$(CONFIG_FS_ENET) += fs_enet/ ++ ++obj-$(CONFIG_NETXEN_NIC) += netxen/ +diff -Nur linux-2.6.21.1/drivers/net/natsemi.c linux-2.6.21.1-owrt/drivers/net/natsemi.c +--- linux-2.6.21.1/drivers/net/natsemi.c	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/drivers/net/natsemi.c	2007-05-23 23:34:01.000000000 +0200 +@@ -656,6 +656,49 @@   static int netdev_get_eeprom(struct net_device *dev, u8 *buf); - static struct ethtool_ops ethtool_ops; + static const struct ethtool_ops ethtool_ops;  +#ifdef CONFIG_MACH_ARUBA  + @@ -118,7 +3960,7 @@ diff -Nur linux-2.6.17/drivers/net/natsemi.c linux-2.6.17-owrt/drivers/net/natse   static inline void __iomem *ns_ioaddr(struct net_device *dev)   {   	return (void __iomem *) dev->base_addr; -@@ -871,6 +914,7 @@ +@@ -794,6 +837,7 @@   		goto err_ioremap;   	} @@ -126,7 +3968,7 @@ diff -Nur linux-2.6.17/drivers/net/natsemi.c linux-2.6.17-owrt/drivers/net/natse   	/* Work around the dropped serial bit. */   	prev_eedata = eeprom_read(ioaddr, 6);   	for (i = 0; i < 3; i++) { -@@ -879,6 +923,19 @@ +@@ -802,6 +846,19 @@   		dev->dev_addr[i*2+1] = eedata >> 7;   		prev_eedata = eedata;   	} @@ -146,12 +3988,4877 @@ diff -Nur linux-2.6.17/drivers/net/natsemi.c linux-2.6.17-owrt/drivers/net/natse   	dev->base_addr = (unsigned long __force) ioaddr;   	dev->irq = irq; -diff -Nur linux-2.6.17/include/asm-mips/bootinfo.h linux-2.6.17-owrt/include/asm-mips/bootinfo.h ---- linux-2.6.17/include/asm-mips/bootinfo.h	2006-06-18 03:49:35.000000000 +0200 -+++ linux-2.6.17-owrt/include/asm-mips/bootinfo.h	2006-06-18 12:44:28.000000000 +0200 -@@ -218,6 +218,17 @@ - #define MACH_GROUP_TITAN       22	/* PMC-Sierra Titan		*/ - #define  MACH_TITAN_YOSEMITE	1	/* PMC-Sierra Yosemite		*/ +diff -Nur linux-2.6.21.1/drivers/pci/access.c linux-2.6.21.1-owrt/drivers/pci/access.c +--- linux-2.6.21.1/drivers/pci/access.c	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/drivers/pci/access.c	2007-05-23 23:36:48.000000000 +0200 +@@ -23,6 +23,7 @@ + #define PCI_word_BAD (pos & 1) + #define PCI_dword_BAD (pos & 3) +  ++#ifdef __MIPSEB__ + #define PCI_OP_READ(size,type,len) \ + int pci_bus_read_config_##size \ + 	(struct pci_bus *bus, unsigned int devfn, int pos, type *value)	\ +@@ -33,11 +34,32 @@ + 	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\ + 	spin_lock_irqsave(&pci_lock, flags);				\ + 	res = bus->ops->read(bus, devfn, pos, len, &data);		\ ++	if (len == 1)							\ ++	 *value = (type)((data >> 24) & 0xff);				\ ++	 else if (len == 2)						\ ++	 *value = (type)((data >> 16) & 0xffff);			\ ++	else								\ + 	*value = (type)data;						\ + 	spin_unlock_irqrestore(&pci_lock, flags);			\ + 	return res;							\ + } ++#else +  ++#define PCI_OP_READ(size,type,len) \ ++int pci_bus_read_config_##size \ ++	(struct pci_bus *bus, unsigned int devfn, int pos, type *value) \ ++{									\ ++	int res;							\ ++	unsigned long flags;						\ ++	u32 data = 0;							\ ++	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\ ++	spin_lock_irqsave(&pci_lock, flags);				\ ++	res = bus->ops->read(bus, devfn, pos, len, &data);		\ ++	*value = (type)data;						\ ++	spin_unlock_irqrestore(&pci_lock, flags);			\ ++	return res;							\ ++} ++#endif + #define PCI_OP_WRITE(size,type,len) \ + int pci_bus_write_config_##size \ + 	(struct pci_bus *bus, unsigned int devfn, int pos, type value)	\ +diff -Nur linux-2.6.21.1/drivers/pci/access.c.orig linux-2.6.21.1-owrt/drivers/pci/access.c.orig +--- linux-2.6.21.1/drivers/pci/access.c.orig	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.1-owrt/drivers/pci/access.c.orig	2007-04-27 23:49:26.000000000 +0200 +@@ -0,0 +1,173 @@ ++#include <linux/pci.h> ++#include <linux/module.h> ++#include <linux/sched.h> ++#include <linux/ioport.h> ++#include <linux/wait.h> ++ ++#include "pci.h" ++ ++/* ++ * This interrupt-safe spinlock protects all accesses to PCI ++ * configuration space. ++ */ ++ ++static DEFINE_SPINLOCK(pci_lock); ++ ++/* ++ *  Wrappers for all PCI configuration access functions.  They just check ++ *  alignment, do locking and call the low-level functions pointed to ++ *  by pci_dev->ops. ++ */ ++ ++#define PCI_byte_BAD 0 ++#define PCI_word_BAD (pos & 1) ++#define PCI_dword_BAD (pos & 3) ++ ++#define PCI_OP_READ(size,type,len) \ ++int pci_bus_read_config_##size \ ++	(struct pci_bus *bus, unsigned int devfn, int pos, type *value)	\ ++{									\ ++	int res;							\ ++	unsigned long flags;						\ ++	u32 data = 0;							\ ++	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\ ++	spin_lock_irqsave(&pci_lock, flags);				\ ++	res = bus->ops->read(bus, devfn, pos, len, &data);		\ ++	*value = (type)data;						\ ++	spin_unlock_irqrestore(&pci_lock, flags);			\ ++	return res;							\ ++} ++ ++#define PCI_OP_WRITE(size,type,len) \ ++int pci_bus_write_config_##size \ ++	(struct pci_bus *bus, unsigned int devfn, int pos, type value)	\ ++{									\ ++	int res;							\ ++	unsigned long flags;						\ ++	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\ ++	spin_lock_irqsave(&pci_lock, flags);				\ ++	res = bus->ops->write(bus, devfn, pos, len, value);		\ ++	spin_unlock_irqrestore(&pci_lock, flags);			\ ++	return res;							\ ++} ++ ++PCI_OP_READ(byte, u8, 1) ++PCI_OP_READ(word, u16, 2) ++PCI_OP_READ(dword, u32, 4) ++PCI_OP_WRITE(byte, u8, 1) ++PCI_OP_WRITE(word, u16, 2) ++PCI_OP_WRITE(dword, u32, 4) ++ ++EXPORT_SYMBOL(pci_bus_read_config_byte); ++EXPORT_SYMBOL(pci_bus_read_config_word); ++EXPORT_SYMBOL(pci_bus_read_config_dword); ++EXPORT_SYMBOL(pci_bus_write_config_byte); ++EXPORT_SYMBOL(pci_bus_write_config_word); ++EXPORT_SYMBOL(pci_bus_write_config_dword); ++ ++/* ++ * The following routines are to prevent the user from accessing PCI config ++ * space when it's unsafe to do so.  Some devices require this during BIST and ++ * we're required to prevent it during D-state transitions. ++ * ++ * We have a bit per device to indicate it's blocked and a global wait queue ++ * for callers to sleep on until devices are unblocked. ++ */ ++static DECLARE_WAIT_QUEUE_HEAD(pci_ucfg_wait); ++ ++static noinline void pci_wait_ucfg(struct pci_dev *dev) ++{ ++	DECLARE_WAITQUEUE(wait, current); ++ ++	__add_wait_queue(&pci_ucfg_wait, &wait); ++	do { ++		set_current_state(TASK_UNINTERRUPTIBLE); ++		spin_unlock_irq(&pci_lock); ++		schedule(); ++		spin_lock_irq(&pci_lock); ++	} while (dev->block_ucfg_access); ++	__remove_wait_queue(&pci_ucfg_wait, &wait); ++} ++ ++#define PCI_USER_READ_CONFIG(size,type)					\ ++int pci_user_read_config_##size						\ ++	(struct pci_dev *dev, int pos, type *val)			\ ++{									\ ++	int ret = 0;							\ ++	u32 data = -1;							\ ++	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\ ++	spin_lock_irq(&pci_lock);					\ ++	if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev);	\ ++	ret = dev->bus->ops->read(dev->bus, dev->devfn,			\ ++					pos, sizeof(type), &data);	\ ++	spin_unlock_irq(&pci_lock);					\ ++	*val = (type)data;						\ ++	return ret;							\ ++} ++ ++#define PCI_USER_WRITE_CONFIG(size,type)				\ ++int pci_user_write_config_##size					\ ++	(struct pci_dev *dev, int pos, type val)			\ ++{									\ ++	int ret = -EIO;							\ ++	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\ ++	spin_lock_irq(&pci_lock);					\ ++	if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev);	\ ++	ret = dev->bus->ops->write(dev->bus, dev->devfn,		\ ++					pos, sizeof(type), val);	\ ++	spin_unlock_irq(&pci_lock);					\ ++	return ret;							\ ++} ++ ++PCI_USER_READ_CONFIG(byte, u8) ++PCI_USER_READ_CONFIG(word, u16) ++PCI_USER_READ_CONFIG(dword, u32) ++PCI_USER_WRITE_CONFIG(byte, u8) ++PCI_USER_WRITE_CONFIG(word, u16) ++PCI_USER_WRITE_CONFIG(dword, u32) ++ ++/** ++ * pci_block_user_cfg_access - Block userspace PCI config reads/writes ++ * @dev:	pci device struct ++ * ++ * When user access is blocked, any reads or writes to config space will ++ * sleep until access is unblocked again.  We don't allow nesting of ++ * block/unblock calls. ++ */ ++void pci_block_user_cfg_access(struct pci_dev *dev) ++{ ++	unsigned long flags; ++	int was_blocked; ++ ++	spin_lock_irqsave(&pci_lock, flags); ++	was_blocked = dev->block_ucfg_access; ++	dev->block_ucfg_access = 1; ++	spin_unlock_irqrestore(&pci_lock, flags); ++ ++	/* If we BUG() inside the pci_lock, we're guaranteed to hose ++	 * the machine */ ++	BUG_ON(was_blocked); ++} ++EXPORT_SYMBOL_GPL(pci_block_user_cfg_access); ++ ++/** ++ * pci_unblock_user_cfg_access - Unblock userspace PCI config reads/writes ++ * @dev:	pci device struct ++ * ++ * This function allows userspace PCI config accesses to resume. ++ */ ++void pci_unblock_user_cfg_access(struct pci_dev *dev) ++{ ++	unsigned long flags; ++ ++	spin_lock_irqsave(&pci_lock, flags); ++ ++	/* This indicates a problem in the caller, but we don't need ++	 * to kill them, unlike a double-block above. */ ++	WARN_ON(!dev->block_ucfg_access); ++ ++	dev->block_ucfg_access = 0; ++	wake_up_all(&pci_ucfg_wait); ++	spin_unlock_irqrestore(&pci_lock, flags); ++} ++EXPORT_SYMBOL_GPL(pci_unblock_user_cfg_access); +diff -Nur linux-2.6.21.1/drivers/serial/8250.c linux-2.6.21.1-owrt/drivers/serial/8250.c +--- linux-2.6.21.1/drivers/serial/8250.c	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/drivers/serial/8250.c	2007-05-23 23:37:11.000000000 +0200 +@@ -1635,7 +1635,7 @@ + { + 	struct uart_8250_port *up = (struct uart_8250_port *)port; + 	unsigned long flags; +-	unsigned char lsr, iir; ++//	unsigned char lsr, iir; + 	int retval; +  + 	up->capabilities = uart_config[up->port.type].flags; +@@ -1772,6 +1772,8 @@ +  + 	serial8250_set_mctrl(&up->port, up->port.mctrl); +  ++// For some reason this test causes problems on the AP6x serial console ++#if 0 + 	/* + 	 * Do a quick test to see if we receive an + 	 * interrupt when we enable the TX irq. +@@ -1790,7 +1792,8 @@ + 	} else { + 		up->bugs &= ~UART_BUG_TXEN; + 	} +- ++#endif ++	 + 	spin_unlock_irqrestore(&up->port.lock, flags); +  + 	/* +diff -Nur linux-2.6.21.1/drivers/serial/8250.c.orig linux-2.6.21.1-owrt/drivers/serial/8250.c.orig +--- linux-2.6.21.1/drivers/serial/8250.c.orig	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.1-owrt/drivers/serial/8250.c.orig	2007-04-27 23:49:26.000000000 +0200 +@@ -0,0 +1,2817 @@ ++/* ++ *  linux/drivers/char/8250.c ++ * ++ *  Driver for 8250/16550-type serial ports ++ * ++ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. ++ * ++ *  Copyright (C) 2001 Russell King. ++ * ++ * 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. ++ * ++ *  $Id: 8250.c,v 1.90 2002/07/28 10:03:27 rmk Exp $ ++ * ++ * A note about mapbase / membase ++ * ++ *  mapbase is the physical address of the IO port. ++ *  membase is an 'ioremapped' cookie. ++ */ ++ ++#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) ++#define SUPPORT_SYSRQ ++#endif ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/ioport.h> ++#include <linux/init.h> ++#include <linux/console.h> ++#include <linux/sysrq.h> ++#include <linux/delay.h> ++#include <linux/platform_device.h> ++#include <linux/tty.h> ++#include <linux/tty_flip.h> ++#include <linux/serial_reg.h> ++#include <linux/serial_core.h> ++#include <linux/serial.h> ++#include <linux/serial_8250.h> ++#include <linux/nmi.h> ++#include <linux/mutex.h> ++ ++#include <asm/io.h> ++#include <asm/irq.h> ++ ++#include "8250.h" ++ ++/* ++ * Configuration: ++ *   share_irqs - whether we pass IRQF_SHARED to request_irq().  This option ++ *                is unsafe when used on edge-triggered interrupts. ++ */ ++static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; ++ ++static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; ++ ++/* ++ * Debugging. ++ */ ++#if 0 ++#define DEBUG_AUTOCONF(fmt...)	printk(fmt) ++#else ++#define DEBUG_AUTOCONF(fmt...)	do { } while (0) ++#endif ++ ++#if 0 ++#define DEBUG_INTR(fmt...)	printk(fmt) ++#else ++#define DEBUG_INTR(fmt...)	do { } while (0) ++#endif ++ ++#define PASS_LIMIT	256 ++ ++/* ++ * We default to IRQ0 for the "no irq" hack.   Some ++ * machine types want others as well - they're free ++ * to redefine this in their header file. ++ */ ++#define is_real_interrupt(irq)	((irq) != 0) ++ ++#ifdef CONFIG_SERIAL_8250_DETECT_IRQ ++#define CONFIG_SERIAL_DETECT_IRQ 1 ++#endif ++#ifdef CONFIG_SERIAL_8250_MANY_PORTS ++#define CONFIG_SERIAL_MANY_PORTS 1 ++#endif ++ ++/* ++ * HUB6 is always on.  This will be removed once the header ++ * files have been cleaned. ++ */ ++#define CONFIG_HUB6 1 ++ ++#include <asm/serial.h> ++ ++/* ++ * SERIAL_PORT_DFNS tells us about built-in ports that have no ++ * standard enumeration mechanism.   Platforms that can find all ++ * serial ports via mechanisms like ACPI or PCI need not supply it. ++ */ ++#ifndef SERIAL_PORT_DFNS ++#define SERIAL_PORT_DFNS ++#endif ++ ++static const struct old_serial_port old_serial_port[] = { ++	SERIAL_PORT_DFNS /* defined in asm/serial.h */ ++}; ++ ++#define UART_NR	CONFIG_SERIAL_8250_NR_UARTS ++ ++#ifdef CONFIG_SERIAL_8250_RSA ++ ++#define PORT_RSA_MAX 4 ++static unsigned long probe_rsa[PORT_RSA_MAX]; ++static unsigned int probe_rsa_count; ++#endif /* CONFIG_SERIAL_8250_RSA  */ ++ ++struct uart_8250_port { ++	struct uart_port	port; ++	struct timer_list	timer;		/* "no irq" timer */ ++	struct list_head	list;		/* ports on this IRQ */ ++	unsigned short		capabilities;	/* port capabilities */ ++	unsigned short		bugs;		/* port bugs */ ++	unsigned int		tx_loadsz;	/* transmit fifo load size */ ++	unsigned char		acr; ++	unsigned char		ier; ++	unsigned char		lcr; ++	unsigned char		mcr; ++	unsigned char		mcr_mask;	/* mask of user bits */ ++	unsigned char		mcr_force;	/* mask of forced bits */ ++	unsigned char		lsr_break_flag; ++ ++	/* ++	 * We provide a per-port pm hook. ++	 */ ++	void			(*pm)(struct uart_port *port, ++				      unsigned int state, unsigned int old); ++}; ++ ++struct irq_info { ++	spinlock_t		lock; ++	struct list_head	*head; ++}; ++ ++static struct irq_info irq_lists[NR_IRQS]; ++ ++/* ++ * Here we define the default xmit fifo size used for each type of UART. ++ */ ++static const struct serial8250_config uart_config[] = { ++	[PORT_UNKNOWN] = { ++		.name		= "unknown", ++		.fifo_size	= 1, ++		.tx_loadsz	= 1, ++	}, ++	[PORT_8250] = { ++		.name		= "8250", ++		.fifo_size	= 1, ++		.tx_loadsz	= 1, ++	}, ++	[PORT_16450] = { ++		.name		= "16450", ++		.fifo_size	= 1, ++		.tx_loadsz	= 1, ++	}, ++	[PORT_16550] = { ++		.name		= "16550", ++		.fifo_size	= 1, ++		.tx_loadsz	= 1, ++	}, ++	[PORT_16550A] = { ++		.name		= "16550A", ++		.fifo_size	= 16, ++		.tx_loadsz	= 16, ++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, ++		.flags		= UART_CAP_FIFO, ++	}, ++	[PORT_CIRRUS] = { ++		.name		= "Cirrus", ++		.fifo_size	= 1, ++		.tx_loadsz	= 1, ++	}, ++	[PORT_16650] = { ++		.name		= "ST16650", ++		.fifo_size	= 1, ++		.tx_loadsz	= 1, ++		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, ++	}, ++	[PORT_16650V2] = { ++		.name		= "ST16650V2", ++		.fifo_size	= 32, ++		.tx_loadsz	= 16, ++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | ++				  UART_FCR_T_TRIG_00, ++		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, ++	}, ++	[PORT_16750] = { ++		.name		= "TI16750", ++		.fifo_size	= 64, ++		.tx_loadsz	= 64, ++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 | ++				  UART_FCR7_64BYTE, ++		.flags		= UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE, ++	}, ++	[PORT_STARTECH] = { ++		.name		= "Startech", ++		.fifo_size	= 1, ++		.tx_loadsz	= 1, ++	}, ++	[PORT_16C950] = { ++		.name		= "16C950/954", ++		.fifo_size	= 128, ++		.tx_loadsz	= 128, ++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, ++		.flags		= UART_CAP_FIFO, ++	}, ++	[PORT_16654] = { ++		.name		= "ST16654", ++		.fifo_size	= 64, ++		.tx_loadsz	= 32, ++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | ++				  UART_FCR_T_TRIG_10, ++		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, ++	}, ++	[PORT_16850] = { ++		.name		= "XR16850", ++		.fifo_size	= 128, ++		.tx_loadsz	= 128, ++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, ++		.flags		= UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, ++	}, ++	[PORT_RSA] = { ++		.name		= "RSA", ++		.fifo_size	= 2048, ++		.tx_loadsz	= 2048, ++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11, ++		.flags		= UART_CAP_FIFO, ++	}, ++	[PORT_NS16550A] = { ++		.name		= "NS16550A", ++		.fifo_size	= 16, ++		.tx_loadsz	= 16, ++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, ++		.flags		= UART_CAP_FIFO | UART_NATSEMI, ++	}, ++	[PORT_XSCALE] = { ++		.name		= "XScale", ++		.fifo_size	= 32, ++		.tx_loadsz	= 32, ++		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, ++		.flags		= UART_CAP_FIFO | UART_CAP_UUE, ++	}, ++}; ++ ++#ifdef CONFIG_SERIAL_8250_AU1X00 ++ ++/* Au1x00 UART hardware has a weird register layout */ ++static const u8 au_io_in_map[] = { ++	[UART_RX]  = 0, ++	[UART_IER] = 2, ++	[UART_IIR] = 3, ++	[UART_LCR] = 5, ++	[UART_MCR] = 6, ++	[UART_LSR] = 7, ++	[UART_MSR] = 8, ++}; ++ ++static const u8 au_io_out_map[] = { ++	[UART_TX]  = 1, ++	[UART_IER] = 2, ++	[UART_FCR] = 4, ++	[UART_LCR] = 5, ++	[UART_MCR] = 6, ++}; ++ ++/* sane hardware needs no mapping */ ++static inline int map_8250_in_reg(struct uart_8250_port *up, int offset) ++{ ++	if (up->port.iotype != UPIO_AU) ++		return offset; ++	return au_io_in_map[offset]; ++} ++ ++static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) ++{ ++	if (up->port.iotype != UPIO_AU) ++		return offset; ++	return au_io_out_map[offset]; ++} ++ ++#else ++ ++/* sane hardware needs no mapping */ ++#define map_8250_in_reg(up, offset) (offset) ++#define map_8250_out_reg(up, offset) (offset) ++ ++#endif ++ ++static unsigned int serial_in(struct uart_8250_port *up, int offset) ++{ ++	unsigned int tmp; ++	offset = map_8250_in_reg(up, offset) << up->port.regshift; ++ ++	switch (up->port.iotype) { ++	case UPIO_HUB6: ++		outb(up->port.hub6 - 1 + offset, up->port.iobase); ++		return inb(up->port.iobase + 1); ++ ++	case UPIO_MEM: ++		return readb(up->port.membase + offset); ++ ++	case UPIO_MEM32: ++		return readl(up->port.membase + offset); ++ ++#ifdef CONFIG_SERIAL_8250_AU1X00 ++	case UPIO_AU: ++		return __raw_readl(up->port.membase + offset); ++#endif ++ ++	case UPIO_TSI: ++		if (offset == UART_IIR) { ++			tmp = readl(up->port.membase + (UART_IIR & ~3)); ++			return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */ ++		} else ++			return readb(up->port.membase + offset); ++ ++	default: ++		return inb(up->port.iobase + offset); ++	} ++} ++ ++static void ++serial_out(struct uart_8250_port *up, int offset, int value) ++{ ++	offset = map_8250_out_reg(up, offset) << up->port.regshift; ++ ++	switch (up->port.iotype) { ++	case UPIO_HUB6: ++		outb(up->port.hub6 - 1 + offset, up->port.iobase); ++		outb(value, up->port.iobase + 1); ++		break; ++ ++	case UPIO_MEM: ++		writeb(value, up->port.membase + offset); ++		break; ++ ++	case UPIO_MEM32: ++		writel(value, up->port.membase + offset); ++		break; ++ ++#ifdef CONFIG_SERIAL_8250_AU1X00 ++	case UPIO_AU: ++		__raw_writel(value, up->port.membase + offset); ++		break; ++#endif ++	case UPIO_TSI: ++		if (!((offset == UART_IER) && (value & UART_IER_UUE))) ++			writeb(value, up->port.membase + offset); ++		break; ++ ++	default: ++		outb(value, up->port.iobase + offset); ++	} ++} ++ ++static void ++serial_out_sync(struct uart_8250_port *up, int offset, int value) ++{ ++	switch (up->port.iotype) { ++	case UPIO_MEM: ++	case UPIO_MEM32: ++#ifdef CONFIG_SERIAL_8250_AU1X00 ++	case UPIO_AU: ++#endif ++		serial_out(up, offset, value); ++		serial_in(up, UART_LCR);	/* safe, no side-effects */ ++		break; ++	default: ++		serial_out(up, offset, value); ++	} ++} ++ ++/* ++ * We used to support using pause I/O for certain machines.  We ++ * haven't supported this for a while, but just in case it's badly ++ * needed for certain old 386 machines, I've left these #define's ++ * in.... ++ */ ++#define serial_inp(up, offset)		serial_in(up, offset) ++#define serial_outp(up, offset, value)	serial_out(up, offset, value) ++ ++/* Uart divisor latch read */ ++static inline int _serial_dl_read(struct uart_8250_port *up) ++{ ++	return serial_inp(up, UART_DLL) | serial_inp(up, UART_DLM) << 8; ++} ++ ++/* Uart divisor latch write */ ++static inline void _serial_dl_write(struct uart_8250_port *up, int value) ++{ ++	serial_outp(up, UART_DLL, value & 0xff); ++	serial_outp(up, UART_DLM, value >> 8 & 0xff); ++} ++ ++#ifdef CONFIG_SERIAL_8250_AU1X00 ++/* Au1x00 haven't got a standard divisor latch */ ++static int serial_dl_read(struct uart_8250_port *up) ++{ ++	if (up->port.iotype == UPIO_AU) ++		return __raw_readl(up->port.membase + 0x28); ++	else ++		return _serial_dl_read(up); ++} ++ ++static void serial_dl_write(struct uart_8250_port *up, int value) ++{ ++	if (up->port.iotype == UPIO_AU) ++		__raw_writel(value, up->port.membase + 0x28); ++	else ++		_serial_dl_write(up, value); ++} ++#else ++#define serial_dl_read(up) _serial_dl_read(up) ++#define serial_dl_write(up, value) _serial_dl_write(up, value) ++#endif ++ ++/* ++ * For the 16C950 ++ */ ++static void serial_icr_write(struct uart_8250_port *up, int offset, int value) ++{ ++	serial_out(up, UART_SCR, offset); ++	serial_out(up, UART_ICR, value); ++} ++ ++static unsigned int serial_icr_read(struct uart_8250_port *up, int offset) ++{ ++	unsigned int value; ++ ++	serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD); ++	serial_out(up, UART_SCR, offset); ++	value = serial_in(up, UART_ICR); ++	serial_icr_write(up, UART_ACR, up->acr); ++ ++	return value; ++} ++ ++/* ++ * FIFO support. ++ */ ++static inline void serial8250_clear_fifos(struct uart_8250_port *p) ++{ ++	if (p->capabilities & UART_CAP_FIFO) { ++		serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO); ++		serial_outp(p, UART_FCR, UART_FCR_ENABLE_FIFO | ++			       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); ++		serial_outp(p, UART_FCR, 0); ++	} ++} ++ ++/* ++ * IER sleep support.  UARTs which have EFRs need the "extended ++ * capability" bit enabled.  Note that on XR16C850s, we need to ++ * reset LCR to write to IER. ++ */ ++static inline void serial8250_set_sleep(struct uart_8250_port *p, int sleep) ++{ ++	if (p->capabilities & UART_CAP_SLEEP) { ++		if (p->capabilities & UART_CAP_EFR) { ++			serial_outp(p, UART_LCR, 0xBF); ++			serial_outp(p, UART_EFR, UART_EFR_ECB); ++			serial_outp(p, UART_LCR, 0); ++		} ++		serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0); ++		if (p->capabilities & UART_CAP_EFR) { ++			serial_outp(p, UART_LCR, 0xBF); ++			serial_outp(p, UART_EFR, 0); ++			serial_outp(p, UART_LCR, 0); ++		} ++	} ++} ++ ++#ifdef CONFIG_SERIAL_8250_RSA ++/* ++ * Attempts to turn on the RSA FIFO.  Returns zero on failure. ++ * We set the port uart clock rate if we succeed. ++ */ ++static int __enable_rsa(struct uart_8250_port *up) ++{ ++	unsigned char mode; ++	int result; ++ ++	mode = serial_inp(up, UART_RSA_MSR); ++	result = mode & UART_RSA_MSR_FIFO; ++ ++	if (!result) { ++		serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO); ++		mode = serial_inp(up, UART_RSA_MSR); ++		result = mode & UART_RSA_MSR_FIFO; ++	} ++ ++	if (result) ++		up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16; ++ ++	return result; ++} ++ ++static void enable_rsa(struct uart_8250_port *up) ++{ ++	if (up->port.type == PORT_RSA) { ++		if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) { ++			spin_lock_irq(&up->port.lock); ++			__enable_rsa(up); ++			spin_unlock_irq(&up->port.lock); ++		} ++		if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) ++			serial_outp(up, UART_RSA_FRR, 0); ++	} ++} ++ ++/* ++ * Attempts to turn off the RSA FIFO.  Returns zero on failure. ++ * It is unknown why interrupts were disabled in here.  However, ++ * the caller is expected to preserve this behaviour by grabbing ++ * the spinlock before calling this function. ++ */ ++static void disable_rsa(struct uart_8250_port *up) ++{ ++	unsigned char mode; ++	int result; ++ ++	if (up->port.type == PORT_RSA && ++	    up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) { ++		spin_lock_irq(&up->port.lock); ++ ++		mode = serial_inp(up, UART_RSA_MSR); ++		result = !(mode & UART_RSA_MSR_FIFO); ++ ++		if (!result) { ++			serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO); ++			mode = serial_inp(up, UART_RSA_MSR); ++			result = !(mode & UART_RSA_MSR_FIFO); ++		} ++ ++		if (result) ++			up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16; ++		spin_unlock_irq(&up->port.lock); ++	} ++} ++#endif /* CONFIG_SERIAL_8250_RSA */ ++ ++/* ++ * This is a quickie test to see how big the FIFO is. ++ * It doesn't work at all the time, more's the pity. ++ */ ++static int size_fifo(struct uart_8250_port *up) ++{ ++	unsigned char old_fcr, old_mcr, old_lcr; ++	unsigned short old_dl; ++	int count; ++ ++	old_lcr = serial_inp(up, UART_LCR); ++	serial_outp(up, UART_LCR, 0); ++	old_fcr = serial_inp(up, UART_FCR); ++	old_mcr = serial_inp(up, UART_MCR); ++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | ++		    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); ++	serial_outp(up, UART_MCR, UART_MCR_LOOP); ++	serial_outp(up, UART_LCR, UART_LCR_DLAB); ++	old_dl = serial_dl_read(up); ++	serial_dl_write(up, 0x0001); ++	serial_outp(up, UART_LCR, 0x03); ++	for (count = 0; count < 256; count++) ++		serial_outp(up, UART_TX, count); ++	mdelay(20);/* FIXME - schedule_timeout */ ++	for (count = 0; (serial_inp(up, UART_LSR) & UART_LSR_DR) && ++	     (count < 256); count++) ++		serial_inp(up, UART_RX); ++	serial_outp(up, UART_FCR, old_fcr); ++	serial_outp(up, UART_MCR, old_mcr); ++	serial_outp(up, UART_LCR, UART_LCR_DLAB); ++	serial_dl_write(up, old_dl); ++	serial_outp(up, UART_LCR, old_lcr); ++ ++	return count; ++} ++ ++/* ++ * Read UART ID using the divisor method - set DLL and DLM to zero ++ * and the revision will be in DLL and device type in DLM.  We ++ * preserve the device state across this. ++ */ ++static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) ++{ ++	unsigned char old_dll, old_dlm, old_lcr; ++	unsigned int id; ++ ++	old_lcr = serial_inp(p, UART_LCR); ++	serial_outp(p, UART_LCR, UART_LCR_DLAB); ++ ++	old_dll = serial_inp(p, UART_DLL); ++	old_dlm = serial_inp(p, UART_DLM); ++ ++	serial_outp(p, UART_DLL, 0); ++	serial_outp(p, UART_DLM, 0); ++ ++	id = serial_inp(p, UART_DLL) | serial_inp(p, UART_DLM) << 8; ++ ++	serial_outp(p, UART_DLL, old_dll); ++	serial_outp(p, UART_DLM, old_dlm); ++	serial_outp(p, UART_LCR, old_lcr); ++ ++	return id; ++} ++ ++/* ++ * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's. ++ * When this function is called we know it is at least a StarTech ++ * 16650 V2, but it might be one of several StarTech UARTs, or one of ++ * its clones.  (We treat the broken original StarTech 16650 V1 as a ++ * 16550, and why not?  Startech doesn't seem to even acknowledge its ++ * existence.) ++ *  ++ * What evil have men's minds wrought... ++ */ ++static void autoconfig_has_efr(struct uart_8250_port *up) ++{ ++	unsigned int id1, id2, id3, rev; ++ ++	/* ++	 * Everything with an EFR has SLEEP ++	 */ ++	up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; ++ ++	/* ++	 * First we check to see if it's an Oxford Semiconductor UART. ++	 * ++	 * If we have to do this here because some non-National ++	 * Semiconductor clone chips lock up if you try writing to the ++	 * LSR register (which serial_icr_read does) ++	 */ ++ ++	/* ++	 * Check for Oxford Semiconductor 16C950. ++	 * ++	 * EFR [4] must be set else this test fails. ++	 * ++	 * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca) ++	 * claims that it's needed for 952 dual UART's (which are not ++	 * recommended for new designs). ++	 */ ++	up->acr = 0; ++	serial_out(up, UART_LCR, 0xBF); ++	serial_out(up, UART_EFR, UART_EFR_ECB); ++	serial_out(up, UART_LCR, 0x00); ++	id1 = serial_icr_read(up, UART_ID1); ++	id2 = serial_icr_read(up, UART_ID2); ++	id3 = serial_icr_read(up, UART_ID3); ++	rev = serial_icr_read(up, UART_REV); ++ ++	DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev); ++ ++	if (id1 == 0x16 && id2 == 0xC9 && ++	    (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) { ++		up->port.type = PORT_16C950; ++ ++		/* ++		 * Enable work around for the Oxford Semiconductor 952 rev B ++		 * chip which causes it to seriously miscalculate baud rates ++		 * when DLL is 0. ++		 */ ++		if (id3 == 0x52 && rev == 0x01) ++			up->bugs |= UART_BUG_QUOT; ++		return; ++	} ++	 ++	/* ++	 * We check for a XR16C850 by setting DLL and DLM to 0, and then ++	 * reading back DLL and DLM.  The chip type depends on the DLM ++	 * value read back: ++	 *  0x10 - XR16C850 and the DLL contains the chip revision. ++	 *  0x12 - XR16C2850. ++	 *  0x14 - XR16C854. ++	 */ ++	id1 = autoconfig_read_divisor_id(up); ++	DEBUG_AUTOCONF("850id=%04x ", id1); ++ ++	id2 = id1 >> 8; ++	if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) { ++		up->port.type = PORT_16850; ++		return; ++	} ++ ++	/* ++	 * It wasn't an XR16C850. ++	 * ++	 * We distinguish between the '654 and the '650 by counting ++	 * how many bytes are in the FIFO.  I'm using this for now, ++	 * since that's the technique that was sent to me in the ++	 * serial driver update, but I'm not convinced this works. ++	 * I've had problems doing this in the past.  -TYT ++	 */ ++	if (size_fifo(up) == 64) ++		up->port.type = PORT_16654; ++	else ++		up->port.type = PORT_16650V2; ++} ++ ++/* ++ * We detected a chip without a FIFO.  Only two fall into ++ * this category - the original 8250 and the 16450.  The ++ * 16450 has a scratch register (accessible with LCR=0) ++ */ ++static void autoconfig_8250(struct uart_8250_port *up) ++{ ++	unsigned char scratch, status1, status2; ++ ++	up->port.type = PORT_8250; ++ ++	scratch = serial_in(up, UART_SCR); ++	serial_outp(up, UART_SCR, 0xa5); ++	status1 = serial_in(up, UART_SCR); ++	serial_outp(up, UART_SCR, 0x5a); ++	status2 = serial_in(up, UART_SCR); ++	serial_outp(up, UART_SCR, scratch); ++ ++	if (status1 == 0xa5 && status2 == 0x5a) ++		up->port.type = PORT_16450; ++} ++ ++static int broken_efr(struct uart_8250_port *up) ++{ ++	/* ++	 * Exar ST16C2550 "A2" devices incorrectly detect as ++	 * having an EFR, and report an ID of 0x0201.  See ++	 * http://www.exar.com/info.php?pdf=dan180_oct2004.pdf ++	 */ ++	if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16) ++		return 1; ++ ++	return 0; ++} ++ ++/* ++ * We know that the chip has FIFOs.  Does it have an EFR?  The ++ * EFR is located in the same register position as the IIR and ++ * we know the top two bits of the IIR are currently set.  The ++ * EFR should contain zero.  Try to read the EFR. ++ */ ++static void autoconfig_16550a(struct uart_8250_port *up) ++{ ++	unsigned char status1, status2; ++	unsigned int iersave; ++ ++	up->port.type = PORT_16550A; ++	up->capabilities |= UART_CAP_FIFO; ++ ++	/* ++	 * Check for presence of the EFR when DLAB is set. ++	 * Only ST16C650V1 UARTs pass this test. ++	 */ ++	serial_outp(up, UART_LCR, UART_LCR_DLAB); ++	if (serial_in(up, UART_EFR) == 0) { ++		serial_outp(up, UART_EFR, 0xA8); ++		if (serial_in(up, UART_EFR) != 0) { ++			DEBUG_AUTOCONF("EFRv1 "); ++			up->port.type = PORT_16650; ++			up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP; ++		} else { ++			DEBUG_AUTOCONF("Motorola 8xxx DUART "); ++		} ++		serial_outp(up, UART_EFR, 0); ++		return; ++	} ++ ++	/* ++	 * Maybe it requires 0xbf to be written to the LCR. ++	 * (other ST16C650V2 UARTs, TI16C752A, etc) ++	 */ ++	serial_outp(up, UART_LCR, 0xBF); ++	if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) { ++		DEBUG_AUTOCONF("EFRv2 "); ++		autoconfig_has_efr(up); ++		return; ++	} ++ ++	/* ++	 * Check for a National Semiconductor SuperIO chip. ++	 * Attempt to switch to bank 2, read the value of the LOOP bit ++	 * from EXCR1. Switch back to bank 0, change it in MCR. Then ++	 * switch back to bank 2, read it from EXCR1 again and check ++	 * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 ++	 */ ++	serial_outp(up, UART_LCR, 0); ++	status1 = serial_in(up, UART_MCR); ++	serial_outp(up, UART_LCR, 0xE0); ++	status2 = serial_in(up, 0x02); /* EXCR1 */ ++ ++	if (!((status2 ^ status1) & UART_MCR_LOOP)) { ++		serial_outp(up, UART_LCR, 0); ++		serial_outp(up, UART_MCR, status1 ^ UART_MCR_LOOP); ++		serial_outp(up, UART_LCR, 0xE0); ++		status2 = serial_in(up, 0x02); /* EXCR1 */ ++		serial_outp(up, UART_LCR, 0); ++		serial_outp(up, UART_MCR, status1); ++ ++		if ((status2 ^ status1) & UART_MCR_LOOP) { ++			unsigned short quot; ++ ++			serial_outp(up, UART_LCR, 0xE0); ++ ++			quot = serial_dl_read(up); ++			quot <<= 3; ++ ++			status1 = serial_in(up, 0x04); /* EXCR1 */ ++			status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ ++			status1 |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */ ++			serial_outp(up, 0x04, status1); ++			 ++			serial_dl_write(up, quot); ++ ++			serial_outp(up, UART_LCR, 0); ++ ++			up->port.uartclk = 921600*16; ++			up->port.type = PORT_NS16550A; ++			up->capabilities |= UART_NATSEMI; ++			return; ++		} ++	} ++ ++	/* ++	 * No EFR.  Try to detect a TI16750, which only sets bit 5 of ++	 * the IIR when 64 byte FIFO mode is enabled when DLAB is set. ++	 * Try setting it with and without DLAB set.  Cheap clones ++	 * set bit 5 without DLAB set. ++	 */ ++	serial_outp(up, UART_LCR, 0); ++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); ++	status1 = serial_in(up, UART_IIR) >> 5; ++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); ++	serial_outp(up, UART_LCR, UART_LCR_DLAB); ++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE); ++	status2 = serial_in(up, UART_IIR) >> 5; ++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); ++	serial_outp(up, UART_LCR, 0); ++ ++	DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2); ++ ++	if (status1 == 6 && status2 == 7) { ++		up->port.type = PORT_16750; ++		up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP; ++		return; ++	} ++ ++	/* ++	 * Try writing and reading the UART_IER_UUE bit (b6). ++	 * If it works, this is probably one of the Xscale platform's ++	 * internal UARTs. ++	 * We're going to explicitly set the UUE bit to 0 before ++	 * trying to write and read a 1 just to make sure it's not ++	 * already a 1 and maybe locked there before we even start start. ++	 */ ++	iersave = serial_in(up, UART_IER); ++	serial_outp(up, UART_IER, iersave & ~UART_IER_UUE); ++	if (!(serial_in(up, UART_IER) & UART_IER_UUE)) { ++		/* ++		 * OK it's in a known zero state, try writing and reading ++		 * without disturbing the current state of the other bits. ++		 */ ++		serial_outp(up, UART_IER, iersave | UART_IER_UUE); ++		if (serial_in(up, UART_IER) & UART_IER_UUE) { ++			/* ++			 * It's an Xscale. ++			 * We'll leave the UART_IER_UUE bit set to 1 (enabled). ++			 */ ++			DEBUG_AUTOCONF("Xscale "); ++			up->port.type = PORT_XSCALE; ++			up->capabilities |= UART_CAP_UUE; ++			return; ++		} ++	} else { ++		/* ++		 * If we got here we couldn't force the IER_UUE bit to 0. ++		 * Log it and continue. ++		 */ ++		DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 "); ++	} ++	serial_outp(up, UART_IER, iersave); ++} ++ ++/* ++ * This routine is called by rs_init() to initialize a specific serial ++ * port.  It determines what type of UART chip this serial port is ++ * using: 8250, 16450, 16550, 16550A.  The important question is ++ * whether or not this UART is a 16550A or not, since this will ++ * determine whether or not we can use its FIFO features or not. ++ */ ++static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) ++{ ++	unsigned char status1, scratch, scratch2, scratch3; ++	unsigned char save_lcr, save_mcr; ++	unsigned long flags; ++ ++	if (!up->port.iobase && !up->port.mapbase && !up->port.membase) ++		return; ++ ++	DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ", ++			up->port.line, up->port.iobase, up->port.membase); ++ ++	/* ++	 * We really do need global IRQs disabled here - we're going to ++	 * be frobbing the chips IRQ enable register to see if it exists. ++	 */ ++	spin_lock_irqsave(&up->port.lock, flags); ++//	save_flags(flags); cli(); ++ ++	up->capabilities = 0; ++	up->bugs = 0; ++ ++	if (!(up->port.flags & UPF_BUGGY_UART)) { ++		/* ++		 * Do a simple existence test first; if we fail this, ++		 * there's no point trying anything else. ++		 *  ++		 * 0x80 is used as a nonsense port to prevent against ++		 * false positives due to ISA bus float.  The ++		 * assumption is that 0x80 is a non-existent port; ++		 * which should be safe since include/asm/io.h also ++		 * makes this assumption. ++		 * ++		 * Note: this is safe as long as MCR bit 4 is clear ++		 * and the device is in "PC" mode. ++		 */ ++		scratch = serial_inp(up, UART_IER); ++		serial_outp(up, UART_IER, 0); ++#ifdef __i386__ ++		outb(0xff, 0x080); ++#endif ++		/* ++		 * Mask out IER[7:4] bits for test as some UARTs (e.g. TL ++		 * 16C754B) allow only to modify them if an EFR bit is set. ++		 */ ++		scratch2 = serial_inp(up, UART_IER) & 0x0f; ++		serial_outp(up, UART_IER, 0x0F); ++#ifdef __i386__ ++		outb(0, 0x080); ++#endif ++		scratch3 = serial_inp(up, UART_IER) & 0x0f; ++		serial_outp(up, UART_IER, scratch); ++		if (scratch2 != 0 || scratch3 != 0x0F) { ++			/* ++			 * We failed; there's nothing here ++			 */ ++			DEBUG_AUTOCONF("IER test failed (%02x, %02x) ", ++				       scratch2, scratch3); ++			goto out; ++		} ++	} ++ ++	save_mcr = serial_in(up, UART_MCR); ++	save_lcr = serial_in(up, UART_LCR); ++ ++	/*  ++	 * Check to see if a UART is really there.  Certain broken ++	 * internal modems based on the Rockwell chipset fail this ++	 * test, because they apparently don't implement the loopback ++	 * test mode.  So this test is skipped on the COM 1 through ++	 * COM 4 ports.  This *should* be safe, since no board ++	 * manufacturer would be stupid enough to design a board ++	 * that conflicts with COM 1-4 --- we hope! ++	 */ ++	if (!(up->port.flags & UPF_SKIP_TEST)) { ++		serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A); ++		status1 = serial_inp(up, UART_MSR) & 0xF0; ++		serial_outp(up, UART_MCR, save_mcr); ++		if (status1 != 0x90) { ++			DEBUG_AUTOCONF("LOOP test failed (%02x) ", ++				       status1); ++			goto out; ++		} ++	} ++ ++	/* ++	 * We're pretty sure there's a port here.  Lets find out what ++	 * type of port it is.  The IIR top two bits allows us to find ++	 * out if it's 8250 or 16450, 16550, 16550A or later.  This ++	 * determines what we test for next. ++	 * ++	 * We also initialise the EFR (if any) to zero for later.  The ++	 * EFR occupies the same register location as the FCR and IIR. ++	 */ ++	serial_outp(up, UART_LCR, 0xBF); ++	serial_outp(up, UART_EFR, 0); ++	serial_outp(up, UART_LCR, 0); ++ ++	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); ++	scratch = serial_in(up, UART_IIR) >> 6; ++ ++	DEBUG_AUTOCONF("iir=%d ", scratch); ++ ++	switch (scratch) { ++	case 0: ++		autoconfig_8250(up); ++		break; ++	case 1: ++		up->port.type = PORT_UNKNOWN; ++		break; ++	case 2: ++		up->port.type = PORT_16550; ++		break; ++	case 3: ++		autoconfig_16550a(up); ++		break; ++	} ++ ++#ifdef CONFIG_SERIAL_8250_RSA ++	/* ++	 * Only probe for RSA ports if we got the region. ++	 */ ++	if (up->port.type == PORT_16550A && probeflags & PROBE_RSA) { ++		int i; ++ ++		for (i = 0 ; i < probe_rsa_count; ++i) { ++			if (probe_rsa[i] == up->port.iobase && ++			    __enable_rsa(up)) { ++				up->port.type = PORT_RSA; ++				break; ++			} ++		} ++	} ++#endif ++ ++#ifdef CONFIG_SERIAL_8250_AU1X00 ++	/* if access method is AU, it is a 16550 with a quirk */ ++	if (up->port.type == PORT_16550A && up->port.iotype == UPIO_AU) ++		up->bugs |= UART_BUG_NOMSR; ++#endif ++ ++	serial_outp(up, UART_LCR, save_lcr); ++ ++	if (up->capabilities != uart_config[up->port.type].flags) { ++		printk(KERN_WARNING ++		       "ttyS%d: detected caps %08x should be %08x\n", ++			up->port.line, up->capabilities, ++			uart_config[up->port.type].flags); ++	} ++ ++	up->port.fifosize = uart_config[up->port.type].fifo_size; ++	up->capabilities = uart_config[up->port.type].flags; ++	up->tx_loadsz = uart_config[up->port.type].tx_loadsz; ++ ++	if (up->port.type == PORT_UNKNOWN) ++		goto out; ++ ++	/* ++	 * Reset the UART. ++	 */ ++#ifdef CONFIG_SERIAL_8250_RSA ++	if (up->port.type == PORT_RSA) ++		serial_outp(up, UART_RSA_FRR, 0); ++#endif ++	serial_outp(up, UART_MCR, save_mcr); ++	serial8250_clear_fifos(up); ++	serial_in(up, UART_RX); ++	if (up->capabilities & UART_CAP_UUE) ++		serial_outp(up, UART_IER, UART_IER_UUE); ++	else ++		serial_outp(up, UART_IER, 0); ++ ++ out:	 ++	spin_unlock_irqrestore(&up->port.lock, flags); ++//	restore_flags(flags); ++	DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name); ++} ++ ++static void autoconfig_irq(struct uart_8250_port *up) ++{ ++	unsigned char save_mcr, save_ier; ++	unsigned char save_ICP = 0; ++	unsigned int ICP = 0; ++	unsigned long irqs; ++	int irq; ++ ++	if (up->port.flags & UPF_FOURPORT) { ++		ICP = (up->port.iobase & 0xfe0) | 0x1f; ++		save_ICP = inb_p(ICP); ++		outb_p(0x80, ICP); ++		(void) inb_p(ICP); ++	} ++ ++	/* forget possible initially masked and pending IRQ */ ++	probe_irq_off(probe_irq_on()); ++	save_mcr = serial_inp(up, UART_MCR); ++	save_ier = serial_inp(up, UART_IER); ++	serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); ++	 ++	irqs = probe_irq_on(); ++	serial_outp(up, UART_MCR, 0); ++	udelay (10); ++	if (up->port.flags & UPF_FOURPORT)  { ++		serial_outp(up, UART_MCR, ++			    UART_MCR_DTR | UART_MCR_RTS); ++	} else { ++		serial_outp(up, UART_MCR, ++			    UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2); ++	} ++	serial_outp(up, UART_IER, 0x0f);	/* enable all intrs */ ++	(void)serial_inp(up, UART_LSR); ++	(void)serial_inp(up, UART_RX); ++	(void)serial_inp(up, UART_IIR); ++	(void)serial_inp(up, UART_MSR); ++	serial_outp(up, UART_TX, 0xFF); ++	udelay (20); ++	irq = probe_irq_off(irqs); ++ ++	serial_outp(up, UART_MCR, save_mcr); ++	serial_outp(up, UART_IER, save_ier); ++ ++	if (up->port.flags & UPF_FOURPORT) ++		outb_p(save_ICP, ICP); ++ ++	up->port.irq = (irq > 0) ? irq : 0; ++} ++ ++static inline void __stop_tx(struct uart_8250_port *p) ++{ ++	if (p->ier & UART_IER_THRI) { ++		p->ier &= ~UART_IER_THRI; ++		serial_out(p, UART_IER, p->ier); ++	} ++} ++ ++static void serial8250_stop_tx(struct uart_port *port) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++ ++	__stop_tx(up); ++ ++	/* ++	 * We really want to stop the transmitter from sending. ++	 */ ++	if (up->port.type == PORT_16C950) { ++		up->acr |= UART_ACR_TXDIS; ++		serial_icr_write(up, UART_ACR, up->acr); ++	} ++} ++ ++static void transmit_chars(struct uart_8250_port *up); ++ ++static void serial8250_start_tx(struct uart_port *port) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++ ++	if (!(up->ier & UART_IER_THRI)) { ++		up->ier |= UART_IER_THRI; ++		serial_out(up, UART_IER, up->ier); ++ ++		if (up->bugs & UART_BUG_TXEN) { ++			unsigned char lsr, iir; ++			lsr = serial_in(up, UART_LSR); ++			iir = serial_in(up, UART_IIR); ++			if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) ++				transmit_chars(up); ++		} ++	} ++ ++	/* ++	 * Re-enable the transmitter if we disabled it. ++	 */ ++	if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { ++		up->acr &= ~UART_ACR_TXDIS; ++		serial_icr_write(up, UART_ACR, up->acr); ++	} ++} ++ ++static void serial8250_stop_rx(struct uart_port *port) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++ ++	up->ier &= ~UART_IER_RLSI; ++	up->port.read_status_mask &= ~UART_LSR_DR; ++	serial_out(up, UART_IER, up->ier); ++} ++ ++static void serial8250_enable_ms(struct uart_port *port) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++ ++	/* no MSR capabilities */ ++	if (up->bugs & UART_BUG_NOMSR) ++		return; ++ ++	up->ier |= UART_IER_MSI; ++	serial_out(up, UART_IER, up->ier); ++} ++ ++static void ++receive_chars(struct uart_8250_port *up, unsigned int *status) ++{ ++	struct tty_struct *tty = up->port.info->tty; ++	unsigned char ch, lsr = *status; ++	int max_count = 256; ++	char flag; ++ ++	do { ++		ch = serial_inp(up, UART_RX); ++		flag = TTY_NORMAL; ++		up->port.icount.rx++; ++ ++#ifdef CONFIG_SERIAL_8250_CONSOLE ++		/* ++		 * Recover the break flag from console xmit ++		 */ ++		if (up->port.line == up->port.cons->index) { ++			lsr |= up->lsr_break_flag; ++			up->lsr_break_flag = 0; ++		} ++#endif ++ ++		if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE | ++				    UART_LSR_FE | UART_LSR_OE))) { ++			/* ++			 * For statistics only ++			 */ ++			if (lsr & UART_LSR_BI) { ++				lsr &= ~(UART_LSR_FE | UART_LSR_PE); ++				up->port.icount.brk++; ++				/* ++				 * We do the SysRQ and SAK checking ++				 * here because otherwise the break ++				 * may get masked by ignore_status_mask ++				 * or read_status_mask. ++				 */ ++				if (uart_handle_break(&up->port)) ++					goto ignore_char; ++			} else if (lsr & UART_LSR_PE) ++				up->port.icount.parity++; ++			else if (lsr & UART_LSR_FE) ++				up->port.icount.frame++; ++			if (lsr & UART_LSR_OE) ++				up->port.icount.overrun++; ++ ++			/* ++			 * Mask off conditions which should be ignored. ++			 */ ++			lsr &= up->port.read_status_mask; ++ ++			if (lsr & UART_LSR_BI) { ++				DEBUG_INTR("handling break...."); ++				flag = TTY_BREAK; ++			} else if (lsr & UART_LSR_PE) ++				flag = TTY_PARITY; ++			else if (lsr & UART_LSR_FE) ++				flag = TTY_FRAME; ++		} ++		if (uart_handle_sysrq_char(&up->port, ch)) ++			goto ignore_char; ++ ++		uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); ++ ++	ignore_char: ++		lsr = serial_inp(up, UART_LSR); ++	} while ((lsr & UART_LSR_DR) && (max_count-- > 0)); ++	spin_unlock(&up->port.lock); ++	tty_flip_buffer_push(tty); ++	spin_lock(&up->port.lock); ++	*status = lsr; ++} ++ ++static void transmit_chars(struct uart_8250_port *up) ++{ ++	struct circ_buf *xmit = &up->port.info->xmit; ++	int count; ++ ++	if (up->port.x_char) { ++		serial_outp(up, UART_TX, up->port.x_char); ++		up->port.icount.tx++; ++		up->port.x_char = 0; ++		return; ++	} ++	if (uart_tx_stopped(&up->port)) { ++		serial8250_stop_tx(&up->port); ++		return; ++	} ++	if (uart_circ_empty(xmit)) { ++		__stop_tx(up); ++		return; ++	} ++ ++	count = up->tx_loadsz; ++	do { ++		serial_out(up, UART_TX, xmit->buf[xmit->tail]); ++		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); ++		up->port.icount.tx++; ++		if (uart_circ_empty(xmit)) ++			break; ++	} while (--count > 0); ++ ++	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) ++		uart_write_wakeup(&up->port); ++ ++	DEBUG_INTR("THRE..."); ++ ++	if (uart_circ_empty(xmit)) ++		__stop_tx(up); ++} ++ ++static unsigned int check_modem_status(struct uart_8250_port *up) ++{ ++	unsigned int status = serial_in(up, UART_MSR); ++ ++	if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && ++	    up->port.info != NULL) { ++		if (status & UART_MSR_TERI) ++			up->port.icount.rng++; ++		if (status & UART_MSR_DDSR) ++			up->port.icount.dsr++; ++		if (status & UART_MSR_DDCD) ++			uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); ++		if (status & UART_MSR_DCTS) ++			uart_handle_cts_change(&up->port, status & UART_MSR_CTS); ++ ++		wake_up_interruptible(&up->port.info->delta_msr_wait); ++	} ++ ++	return status; ++} ++ ++/* ++ * This handles the interrupt from one port. ++ */ ++static inline void ++serial8250_handle_port(struct uart_8250_port *up) ++{ ++	unsigned int status; ++	unsigned long flags; ++ ++	spin_lock_irqsave(&up->port.lock, flags); ++ ++	status = serial_inp(up, UART_LSR); ++ ++	DEBUG_INTR("status = %x...", status); ++ ++	if (status & UART_LSR_DR) ++		receive_chars(up, &status); ++	check_modem_status(up); ++	if (status & UART_LSR_THRE) ++		transmit_chars(up); ++ ++	spin_unlock_irqrestore(&up->port.lock, flags); ++} ++ ++/* ++ * This is the serial driver's interrupt routine. ++ * ++ * Arjan thinks the old way was overly complex, so it got simplified. ++ * Alan disagrees, saying that need the complexity to handle the weird ++ * nature of ISA shared interrupts.  (This is a special exception.) ++ * ++ * In order to handle ISA shared interrupts properly, we need to check ++ * that all ports have been serviced, and therefore the ISA interrupt ++ * line has been de-asserted. ++ * ++ * This means we need to loop through all ports. checking that they ++ * don't have an interrupt pending. ++ */ ++static irqreturn_t serial8250_interrupt(int irq, void *dev_id) ++{ ++	struct irq_info *i = dev_id; ++	struct list_head *l, *end = NULL; ++	int pass_counter = 0, handled = 0; ++ ++	DEBUG_INTR("serial8250_interrupt(%d)...", irq); ++ ++	spin_lock(&i->lock); ++ ++	l = i->head; ++	do { ++		struct uart_8250_port *up; ++		unsigned int iir; ++ ++		up = list_entry(l, struct uart_8250_port, list); ++ ++		iir = serial_in(up, UART_IIR); ++		if (!(iir & UART_IIR_NO_INT)) { ++			serial8250_handle_port(up); ++ ++			handled = 1; ++ ++			end = NULL; ++		} else if (end == NULL) ++			end = l; ++ ++		l = l->next; ++ ++		if (l == i->head && pass_counter++ > PASS_LIMIT) { ++			/* If we hit this, we're dead. */ ++			printk(KERN_ERR "serial8250: too much work for " ++				"irq%d\n", irq); ++			break; ++		} ++	} while (l != end); ++ ++	spin_unlock(&i->lock); ++ ++	DEBUG_INTR("end.\n"); ++ ++	return IRQ_RETVAL(handled); ++} ++ ++/* ++ * To support ISA shared interrupts, we need to have one interrupt ++ * handler that ensures that the IRQ line has been deasserted ++ * before returning.  Failing to do this will result in the IRQ ++ * line being stuck active, and, since ISA irqs are edge triggered, ++ * no more IRQs will be seen. ++ */ ++static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up) ++{ ++	spin_lock_irq(&i->lock); ++ ++	if (!list_empty(i->head)) { ++		if (i->head == &up->list) ++			i->head = i->head->next; ++		list_del(&up->list); ++	} else { ++		BUG_ON(i->head != &up->list); ++		i->head = NULL; ++	} ++ ++	spin_unlock_irq(&i->lock); ++} ++ ++static int serial_link_irq_chain(struct uart_8250_port *up) ++{ ++	struct irq_info *i = irq_lists + up->port.irq; ++	int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; ++ ++	spin_lock_irq(&i->lock); ++ ++	if (i->head) { ++		list_add(&up->list, i->head); ++		spin_unlock_irq(&i->lock); ++ ++		ret = 0; ++	} else { ++		INIT_LIST_HEAD(&up->list); ++		i->head = &up->list; ++		spin_unlock_irq(&i->lock); ++ ++		ret = request_irq(up->port.irq, serial8250_interrupt, ++				  irq_flags, "serial", i); ++		if (ret < 0) ++			serial_do_unlink(i, up); ++	} ++ ++	return ret; ++} ++ ++static void serial_unlink_irq_chain(struct uart_8250_port *up) ++{ ++	struct irq_info *i = irq_lists + up->port.irq; ++ ++	BUG_ON(i->head == NULL); ++ ++	if (list_empty(i->head)) ++		free_irq(up->port.irq, i); ++ ++	serial_do_unlink(i, up); ++} ++ ++/* Base timer interval for polling */ ++static inline int poll_timeout(int timeout) ++{ ++	return timeout > 6 ? (timeout / 2 - 2) : 1; ++} ++ ++/* ++ * This function is used to handle ports that do not have an ++ * interrupt.  This doesn't work very well for 16450's, but gives ++ * barely passable results for a 16550A.  (Although at the expense ++ * of much CPU overhead). ++ */ ++static void serial8250_timeout(unsigned long data) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)data; ++	unsigned int iir; ++ ++	iir = serial_in(up, UART_IIR); ++	if (!(iir & UART_IIR_NO_INT)) ++		serial8250_handle_port(up); ++	mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout)); ++} ++ ++static void serial8250_backup_timeout(unsigned long data) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)data; ++	unsigned int iir, ier = 0; ++ ++	/* ++	 * Must disable interrupts or else we risk racing with the interrupt ++	 * based handler. ++	 */ ++	if (is_real_interrupt(up->port.irq)) { ++		ier = serial_in(up, UART_IER); ++		serial_out(up, UART_IER, 0); ++	} ++ ++	iir = serial_in(up, UART_IIR); ++ ++	/* ++	 * This should be a safe test for anyone who doesn't trust the ++	 * IIR bits on their UART, but it's specifically designed for ++	 * the "Diva" UART used on the management processor on many HP ++	 * ia64 and parisc boxes. ++	 */ ++	if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && ++	    (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) && ++	    (serial_in(up, UART_LSR) & UART_LSR_THRE)) { ++		iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); ++		iir |= UART_IIR_THRI; ++	} ++ ++	if (!(iir & UART_IIR_NO_INT)) ++		serial8250_handle_port(up); ++ ++	if (is_real_interrupt(up->port.irq)) ++		serial_out(up, UART_IER, ier); ++ ++	/* Standard timer interval plus 0.2s to keep the port running */ ++	mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout) + HZ/5); ++} ++ ++static unsigned int serial8250_tx_empty(struct uart_port *port) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++	unsigned long flags; ++	unsigned int ret; ++ ++	spin_lock_irqsave(&up->port.lock, flags); ++	ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; ++	spin_unlock_irqrestore(&up->port.lock, flags); ++ ++	return ret; ++} ++ ++static unsigned int serial8250_get_mctrl(struct uart_port *port) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++	unsigned int status; ++	unsigned int ret; ++ ++	status = check_modem_status(up); ++ ++	ret = 0; ++	if (status & UART_MSR_DCD) ++		ret |= TIOCM_CAR; ++	if (status & UART_MSR_RI) ++		ret |= TIOCM_RNG; ++	if (status & UART_MSR_DSR) ++		ret |= TIOCM_DSR; ++	if (status & UART_MSR_CTS) ++		ret |= TIOCM_CTS; ++	return ret; ++} ++ ++static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++	unsigned char mcr = 0; ++ ++	if (mctrl & TIOCM_RTS) ++		mcr |= UART_MCR_RTS; ++	if (mctrl & TIOCM_DTR) ++		mcr |= UART_MCR_DTR; ++	if (mctrl & TIOCM_OUT1) ++		mcr |= UART_MCR_OUT1; ++	if (mctrl & TIOCM_OUT2) ++		mcr |= UART_MCR_OUT2; ++	if (mctrl & TIOCM_LOOP) ++		mcr |= UART_MCR_LOOP; ++ ++	mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr; ++ ++	serial_out(up, UART_MCR, mcr); ++} ++ ++static void serial8250_break_ctl(struct uart_port *port, int break_state) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++	unsigned long flags; ++ ++	spin_lock_irqsave(&up->port.lock, flags); ++	if (break_state == -1) ++		up->lcr |= UART_LCR_SBC; ++	else ++		up->lcr &= ~UART_LCR_SBC; ++	serial_out(up, UART_LCR, up->lcr); ++	spin_unlock_irqrestore(&up->port.lock, flags); ++} ++ ++#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) ++ ++/* ++ *	Wait for transmitter & holding register to empty ++ */ ++static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) ++{ ++	unsigned int status, tmout = 10000; ++ ++	/* Wait up to 10ms for the character(s) to be sent. */ ++	do { ++		status = serial_in(up, UART_LSR); ++ ++		if (status & UART_LSR_BI) ++			up->lsr_break_flag = UART_LSR_BI; ++ ++		if (--tmout == 0) ++			break; ++		udelay(1); ++	} while ((status & bits) != bits); ++ ++	/* Wait up to 1s for flow control if necessary */ ++	if (up->port.flags & UPF_CONS_FLOW) { ++		tmout = 1000000; ++		while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) { ++			udelay(1); ++			touch_nmi_watchdog(); ++		} ++	} ++} ++ ++static int serial8250_startup(struct uart_port *port) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++	unsigned long flags; ++	unsigned char lsr, iir; ++	int retval; ++ ++	up->capabilities = uart_config[up->port.type].flags; ++	up->mcr = 0; ++ ++	if (up->port.type == PORT_16C950) { ++		/* Wake up and initialize UART */ ++		up->acr = 0; ++		serial_outp(up, UART_LCR, 0xBF); ++		serial_outp(up, UART_EFR, UART_EFR_ECB); ++		serial_outp(up, UART_IER, 0); ++		serial_outp(up, UART_LCR, 0); ++		serial_icr_write(up, UART_CSR, 0); /* Reset the UART */ ++		serial_outp(up, UART_LCR, 0xBF); ++		serial_outp(up, UART_EFR, UART_EFR_ECB); ++		serial_outp(up, UART_LCR, 0); ++	} ++ ++#ifdef CONFIG_SERIAL_8250_RSA ++	/* ++	 * If this is an RSA port, see if we can kick it up to the ++	 * higher speed clock. ++	 */ ++	enable_rsa(up); ++#endif ++ ++	/* ++	 * Clear the FIFO buffers and disable them. ++	 * (they will be reenabled in set_termios()) ++	 */ ++	serial8250_clear_fifos(up); ++ ++	/* ++	 * Clear the interrupt registers. ++	 */ ++	(void) serial_inp(up, UART_LSR); ++	(void) serial_inp(up, UART_RX); ++	(void) serial_inp(up, UART_IIR); ++	(void) serial_inp(up, UART_MSR); ++ ++	/* ++	 * At this point, there's no way the LSR could still be 0xff; ++	 * if it is, then bail out, because there's likely no UART ++	 * here. ++	 */ ++	if (!(up->port.flags & UPF_BUGGY_UART) && ++	    (serial_inp(up, UART_LSR) == 0xff)) { ++		printk("ttyS%d: LSR safety check engaged!\n", up->port.line); ++		return -ENODEV; ++	} ++ ++	/* ++	 * For a XR16C850, we need to set the trigger levels ++	 */ ++	if (up->port.type == PORT_16850) { ++		unsigned char fctr; ++ ++		serial_outp(up, UART_LCR, 0xbf); ++ ++		fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX); ++		serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX); ++		serial_outp(up, UART_TRG, UART_TRG_96); ++		serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_TX); ++		serial_outp(up, UART_TRG, UART_TRG_96); ++ ++		serial_outp(up, UART_LCR, 0); ++	} ++ ++	if (is_real_interrupt(up->port.irq)) { ++		/* ++		 * Test for UARTs that do not reassert THRE when the ++		 * transmitter is idle and the interrupt has already ++		 * been cleared.  Real 16550s should always reassert ++		 * this interrupt whenever the transmitter is idle and ++		 * the interrupt is enabled.  Delays are necessary to ++		 * allow register changes to become visible. ++		 */ ++		spin_lock_irqsave(&up->port.lock, flags); ++ ++		wait_for_xmitr(up, UART_LSR_THRE); ++		serial_out_sync(up, UART_IER, UART_IER_THRI); ++		udelay(1); /* allow THRE to set */ ++		serial_in(up, UART_IIR); ++		serial_out(up, UART_IER, 0); ++		serial_out_sync(up, UART_IER, UART_IER_THRI); ++		udelay(1); /* allow a working UART time to re-assert THRE */ ++		iir = serial_in(up, UART_IIR); ++		serial_out(up, UART_IER, 0); ++ ++		spin_unlock_irqrestore(&up->port.lock, flags); ++ ++		/* ++		 * If the interrupt is not reasserted, setup a timer to ++		 * kick the UART on a regular basis. ++		 */ ++		if (iir & UART_IIR_NO_INT) { ++			pr_debug("ttyS%d - using backup timer\n", port->line); ++			up->timer.function = serial8250_backup_timeout; ++			up->timer.data = (unsigned long)up; ++			mod_timer(&up->timer, jiffies + ++			          poll_timeout(up->port.timeout) + HZ/5); ++		} ++	} ++ ++	/* ++	 * If the "interrupt" for this port doesn't correspond with any ++	 * hardware interrupt, we use a timer-based system.  The original ++	 * driver used to do this with IRQ0. ++	 */ ++	if (!is_real_interrupt(up->port.irq)) { ++		up->timer.data = (unsigned long)up; ++		mod_timer(&up->timer, jiffies + poll_timeout(up->port.timeout)); ++	} else { ++		retval = serial_link_irq_chain(up); ++		if (retval) ++			return retval; ++	} ++ ++	/* ++	 * Now, initialize the UART ++	 */ ++	serial_outp(up, UART_LCR, UART_LCR_WLEN8); ++ ++	spin_lock_irqsave(&up->port.lock, flags); ++	if (up->port.flags & UPF_FOURPORT) { ++		if (!is_real_interrupt(up->port.irq)) ++			up->port.mctrl |= TIOCM_OUT1; ++	} else ++		/* ++		 * Most PC uarts need OUT2 raised to enable interrupts. ++		 */ ++		if (is_real_interrupt(up->port.irq)) ++			up->port.mctrl |= TIOCM_OUT2; ++ ++	serial8250_set_mctrl(&up->port, up->port.mctrl); ++ ++	/* ++	 * Do a quick test to see if we receive an ++	 * interrupt when we enable the TX irq. ++	 */ ++	serial_outp(up, UART_IER, UART_IER_THRI); ++	lsr = serial_in(up, UART_LSR); ++	iir = serial_in(up, UART_IIR); ++	serial_outp(up, UART_IER, 0); ++ ++	if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) { ++		if (!(up->bugs & UART_BUG_TXEN)) { ++			up->bugs |= UART_BUG_TXEN; ++			pr_debug("ttyS%d - enabling bad tx status workarounds\n", ++				 port->line); ++		} ++	} else { ++		up->bugs &= ~UART_BUG_TXEN; ++	} ++ ++	spin_unlock_irqrestore(&up->port.lock, flags); ++ ++	/* ++	 * Finally, enable interrupts.  Note: Modem status interrupts ++	 * are set via set_termios(), which will be occurring imminently ++	 * anyway, so we don't enable them here. ++	 */ ++	up->ier = UART_IER_RLSI | UART_IER_RDI; ++	serial_outp(up, UART_IER, up->ier); ++ ++	if (up->port.flags & UPF_FOURPORT) { ++		unsigned int icp; ++		/* ++		 * Enable interrupts on the AST Fourport board ++		 */ ++		icp = (up->port.iobase & 0xfe0) | 0x01f; ++		outb_p(0x80, icp); ++		(void) inb_p(icp); ++	} ++ ++	/* ++	 * And clear the interrupt registers again for luck. ++	 */ ++	(void) serial_inp(up, UART_LSR); ++	(void) serial_inp(up, UART_RX); ++	(void) serial_inp(up, UART_IIR); ++	(void) serial_inp(up, UART_MSR); ++ ++	return 0; ++} ++ ++static void serial8250_shutdown(struct uart_port *port) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++	unsigned long flags; ++ ++	/* ++	 * Disable interrupts from this port ++	 */ ++	up->ier = 0; ++	serial_outp(up, UART_IER, 0); ++ ++	spin_lock_irqsave(&up->port.lock, flags); ++	if (up->port.flags & UPF_FOURPORT) { ++		/* reset interrupts on the AST Fourport board */ ++		inb((up->port.iobase & 0xfe0) | 0x1f); ++		up->port.mctrl |= TIOCM_OUT1; ++	} else ++		up->port.mctrl &= ~TIOCM_OUT2; ++ ++	serial8250_set_mctrl(&up->port, up->port.mctrl); ++	spin_unlock_irqrestore(&up->port.lock, flags); ++ ++	/* ++	 * Disable break condition and FIFOs ++	 */ ++	serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC); ++	serial8250_clear_fifos(up); ++ ++#ifdef CONFIG_SERIAL_8250_RSA ++	/* ++	 * Reset the RSA board back to 115kbps compat mode. ++	 */ ++	disable_rsa(up); ++#endif ++ ++	/* ++	 * Read data port to reset things, and then unlink from ++	 * the IRQ chain. ++	 */ ++	(void) serial_in(up, UART_RX); ++ ++	del_timer_sync(&up->timer); ++	up->timer.function = serial8250_timeout; ++	if (is_real_interrupt(up->port.irq)) ++		serial_unlink_irq_chain(up); ++} ++ ++static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud) ++{ ++	unsigned int quot; ++ ++	/* ++	 * Handle magic divisors for baud rates above baud_base on ++	 * SMSC SuperIO chips. ++	 */ ++	if ((port->flags & UPF_MAGIC_MULTIPLIER) && ++	    baud == (port->uartclk/4)) ++		quot = 0x8001; ++	else if ((port->flags & UPF_MAGIC_MULTIPLIER) && ++		 baud == (port->uartclk/8)) ++		quot = 0x8002; ++	else ++		quot = uart_get_divisor(port, baud); ++ ++	return quot; ++} ++ ++static void ++serial8250_set_termios(struct uart_port *port, struct ktermios *termios, ++		       struct ktermios *old) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++	unsigned char cval, fcr = 0; ++	unsigned long flags; ++	unsigned int baud, quot; ++ ++	switch (termios->c_cflag & CSIZE) { ++	case CS5: ++		cval = UART_LCR_WLEN5; ++		break; ++	case CS6: ++		cval = UART_LCR_WLEN6; ++		break; ++	case CS7: ++		cval = UART_LCR_WLEN7; ++		break; ++	default: ++	case CS8: ++		cval = UART_LCR_WLEN8; ++		break; ++	} ++ ++	if (termios->c_cflag & CSTOPB) ++		cval |= UART_LCR_STOP; ++	if (termios->c_cflag & PARENB) ++		cval |= UART_LCR_PARITY; ++	if (!(termios->c_cflag & PARODD)) ++		cval |= UART_LCR_EPAR; ++#ifdef CMSPAR ++	if (termios->c_cflag & CMSPAR) ++		cval |= UART_LCR_SPAR; ++#endif ++ ++	/* ++	 * Ask the core to calculate the divisor for us. ++	 */ ++	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);  ++	quot = serial8250_get_divisor(port, baud); ++ ++	/* ++	 * Oxford Semi 952 rev B workaround ++	 */ ++	if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0) ++		quot ++; ++ ++	if (up->capabilities & UART_CAP_FIFO && up->port.fifosize > 1) { ++		if (baud < 2400) ++			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1; ++		else ++			fcr = uart_config[up->port.type].fcr; ++	} ++ ++	/* ++	 * MCR-based auto flow control.  When AFE is enabled, RTS will be ++	 * deasserted when the receive FIFO contains more characters than ++	 * the trigger, or the MCR RTS bit is cleared.  In the case where ++	 * the remote UART is not using CTS auto flow control, we must ++	 * have sufficient FIFO entries for the latency of the remote ++	 * UART to respond.  IOW, at least 32 bytes of FIFO. ++	 */ ++	if (up->capabilities & UART_CAP_AFE && up->port.fifosize >= 32) { ++		up->mcr &= ~UART_MCR_AFE; ++		if (termios->c_cflag & CRTSCTS) ++			up->mcr |= UART_MCR_AFE; ++	} ++ ++	/* ++	 * Ok, we're now changing the port state.  Do it with ++	 * interrupts disabled. ++	 */ ++	spin_lock_irqsave(&up->port.lock, flags); ++ ++	/* ++	 * Update the per-port timeout. ++	 */ ++	uart_update_timeout(port, termios->c_cflag, baud); ++ ++	up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; ++	if (termios->c_iflag & INPCK) ++		up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; ++	if (termios->c_iflag & (BRKINT | PARMRK)) ++		up->port.read_status_mask |= UART_LSR_BI; ++ ++	/* ++	 * Characteres to ignore ++	 */ ++	up->port.ignore_status_mask = 0; ++	if (termios->c_iflag & IGNPAR) ++		up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; ++	if (termios->c_iflag & IGNBRK) { ++		up->port.ignore_status_mask |= UART_LSR_BI; ++		/* ++		 * If we're ignoring parity and break indicators, ++		 * ignore overruns too (for real raw support). ++		 */ ++		if (termios->c_iflag & IGNPAR) ++			up->port.ignore_status_mask |= UART_LSR_OE; ++	} ++ ++	/* ++	 * ignore all characters if CREAD is not set ++	 */ ++	if ((termios->c_cflag & CREAD) == 0) ++		up->port.ignore_status_mask |= UART_LSR_DR; ++ ++	/* ++	 * CTS flow control flag and modem status interrupts ++	 */ ++	up->ier &= ~UART_IER_MSI; ++	if (!(up->bugs & UART_BUG_NOMSR) && ++			UART_ENABLE_MS(&up->port, termios->c_cflag)) ++		up->ier |= UART_IER_MSI; ++	if (up->capabilities & UART_CAP_UUE) ++		up->ier |= UART_IER_UUE | UART_IER_RTOIE; ++ ++	serial_out(up, UART_IER, up->ier); ++ ++	if (up->capabilities & UART_CAP_EFR) { ++		unsigned char efr = 0; ++		/* ++		 * TI16C752/Startech hardware flow control.  FIXME: ++		 * - TI16C752 requires control thresholds to be set. ++		 * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled. ++		 */ ++		if (termios->c_cflag & CRTSCTS) ++			efr |= UART_EFR_CTS; ++ ++		serial_outp(up, UART_LCR, 0xBF); ++		serial_outp(up, UART_EFR, efr); ++	} ++ ++#ifdef CONFIG_ARCH_OMAP15XX ++	/* Workaround to enable 115200 baud on OMAP1510 internal ports */ ++	if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) { ++		if (baud == 115200) { ++			quot = 1; ++			serial_out(up, UART_OMAP_OSC_12M_SEL, 1); ++		} else ++			serial_out(up, UART_OMAP_OSC_12M_SEL, 0); ++	} ++#endif ++ ++	if (up->capabilities & UART_NATSEMI) { ++		/* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */ ++		serial_outp(up, UART_LCR, 0xe0); ++	} else { ++		serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ ++	} ++ ++	serial_dl_write(up, quot); ++ ++	/* ++	 * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR ++	 * is written without DLAB set, this mode will be disabled. ++	 */ ++	if (up->port.type == PORT_16750) ++		serial_outp(up, UART_FCR, fcr); ++ ++	serial_outp(up, UART_LCR, cval);		/* reset DLAB */ ++	up->lcr = cval;					/* Save LCR */ ++	if (up->port.type != PORT_16750) { ++		if (fcr & UART_FCR_ENABLE_FIFO) { ++			/* emulated UARTs (Lucent Venus 167x) need two steps */ ++			serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); ++		} ++		serial_outp(up, UART_FCR, fcr);		/* set fcr */ ++	} ++	serial8250_set_mctrl(&up->port, up->port.mctrl); ++	spin_unlock_irqrestore(&up->port.lock, flags); ++} ++ ++static void ++serial8250_pm(struct uart_port *port, unsigned int state, ++	      unsigned int oldstate) ++{ ++	struct uart_8250_port *p = (struct uart_8250_port *)port; ++ ++	serial8250_set_sleep(p, state != 0); ++ ++	if (p->pm) ++		p->pm(port, state, oldstate); ++} ++ ++/* ++ * Resource handling. ++ */ ++static int serial8250_request_std_resource(struct uart_8250_port *up) ++{ ++	unsigned int size = 8 << up->port.regshift; ++	int ret = 0; ++ ++	switch (up->port.iotype) { ++	case UPIO_AU: ++		size = 0x100000; ++		/* fall thru */ ++	case UPIO_TSI: ++	case UPIO_MEM32: ++	case UPIO_MEM: ++		if (!up->port.mapbase) ++			break; ++ ++		if (!request_mem_region(up->port.mapbase, size, "serial")) { ++			ret = -EBUSY; ++			break; ++		} ++ ++		if (up->port.flags & UPF_IOREMAP) { ++			up->port.membase = ioremap(up->port.mapbase, size); ++			if (!up->port.membase) { ++				release_mem_region(up->port.mapbase, size); ++				ret = -ENOMEM; ++			} ++		} ++		break; ++ ++	case UPIO_HUB6: ++	case UPIO_PORT: ++		if (!request_region(up->port.iobase, size, "serial")) ++			ret = -EBUSY; ++		break; ++	} ++	return ret; ++} ++ ++static void serial8250_release_std_resource(struct uart_8250_port *up) ++{ ++	unsigned int size = 8 << up->port.regshift; ++ ++	switch (up->port.iotype) { ++	case UPIO_AU: ++		size = 0x100000; ++		/* fall thru */ ++	case UPIO_TSI: ++	case UPIO_MEM32: ++	case UPIO_MEM: ++		if (!up->port.mapbase) ++			break; ++ ++		if (up->port.flags & UPF_IOREMAP) { ++			iounmap(up->port.membase); ++			up->port.membase = NULL; ++		} ++ ++		release_mem_region(up->port.mapbase, size); ++		break; ++ ++	case UPIO_HUB6: ++	case UPIO_PORT: ++		release_region(up->port.iobase, size); ++		break; ++	} ++} ++ ++static int serial8250_request_rsa_resource(struct uart_8250_port *up) ++{ ++	unsigned long start = UART_RSA_BASE << up->port.regshift; ++	unsigned int size = 8 << up->port.regshift; ++	int ret = -EINVAL; ++ ++	switch (up->port.iotype) { ++	case UPIO_HUB6: ++	case UPIO_PORT: ++		start += up->port.iobase; ++		if (request_region(start, size, "serial-rsa")) ++			ret = 0; ++		else ++			ret = -EBUSY; ++		break; ++	} ++ ++	return ret; ++} ++ ++static void serial8250_release_rsa_resource(struct uart_8250_port *up) ++{ ++	unsigned long offset = UART_RSA_BASE << up->port.regshift; ++	unsigned int size = 8 << up->port.regshift; ++ ++	switch (up->port.iotype) { ++	case UPIO_HUB6: ++	case UPIO_PORT: ++		release_region(up->port.iobase + offset, size); ++		break; ++	} ++} ++ ++static void serial8250_release_port(struct uart_port *port) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++ ++	serial8250_release_std_resource(up); ++	if (up->port.type == PORT_RSA) ++		serial8250_release_rsa_resource(up); ++} ++ ++static int serial8250_request_port(struct uart_port *port) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++	int ret = 0; ++ ++	ret = serial8250_request_std_resource(up); ++	if (ret == 0 && up->port.type == PORT_RSA) { ++		ret = serial8250_request_rsa_resource(up); ++		if (ret < 0) ++			serial8250_release_std_resource(up); ++	} ++ ++	return ret; ++} ++ ++static void serial8250_config_port(struct uart_port *port, int flags) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++	int probeflags = PROBE_ANY; ++	int ret; ++ ++	/* ++	 * Find the region that we can probe for.  This in turn ++	 * tells us whether we can probe for the type of port. ++	 */ ++	ret = serial8250_request_std_resource(up); ++	if (ret < 0) ++		return; ++ ++	ret = serial8250_request_rsa_resource(up); ++	if (ret < 0) ++		probeflags &= ~PROBE_RSA; ++ ++	if (flags & UART_CONFIG_TYPE) ++		autoconfig(up, probeflags); ++	if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) ++		autoconfig_irq(up); ++ ++	if (up->port.type != PORT_RSA && probeflags & PROBE_RSA) ++		serial8250_release_rsa_resource(up); ++	if (up->port.type == PORT_UNKNOWN) ++		serial8250_release_std_resource(up); ++} ++ ++static int ++serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) ++{ ++	if (ser->irq >= NR_IRQS || ser->irq < 0 || ++	    ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || ++	    ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS || ++	    ser->type == PORT_STARTECH) ++		return -EINVAL; ++	return 0; ++} ++ ++static const char * ++serial8250_type(struct uart_port *port) ++{ ++	int type = port->type; ++ ++	if (type >= ARRAY_SIZE(uart_config)) ++		type = 0; ++	return uart_config[type].name; ++} ++ ++static struct uart_ops serial8250_pops = { ++	.tx_empty	= serial8250_tx_empty, ++	.set_mctrl	= serial8250_set_mctrl, ++	.get_mctrl	= serial8250_get_mctrl, ++	.stop_tx	= serial8250_stop_tx, ++	.start_tx	= serial8250_start_tx, ++	.stop_rx	= serial8250_stop_rx, ++	.enable_ms	= serial8250_enable_ms, ++	.break_ctl	= serial8250_break_ctl, ++	.startup	= serial8250_startup, ++	.shutdown	= serial8250_shutdown, ++	.set_termios	= serial8250_set_termios, ++	.pm		= serial8250_pm, ++	.type		= serial8250_type, ++	.release_port	= serial8250_release_port, ++	.request_port	= serial8250_request_port, ++	.config_port	= serial8250_config_port, ++	.verify_port	= serial8250_verify_port, ++}; ++ ++static struct uart_8250_port serial8250_ports[UART_NR]; ++ ++static void __init serial8250_isa_init_ports(void) ++{ ++	struct uart_8250_port *up; ++	static int first = 1; ++	int i; ++ ++	if (!first) ++		return; ++	first = 0; ++ ++	for (i = 0; i < nr_uarts; i++) { ++		struct uart_8250_port *up = &serial8250_ports[i]; ++ ++		up->port.line = i; ++		spin_lock_init(&up->port.lock); ++ ++		init_timer(&up->timer); ++		up->timer.function = serial8250_timeout; ++ ++		/* ++		 * ALPHA_KLUDGE_MCR needs to be killed. ++		 */ ++		up->mcr_mask = ~ALPHA_KLUDGE_MCR; ++		up->mcr_force = ALPHA_KLUDGE_MCR; ++ ++		up->port.ops = &serial8250_pops; ++	} ++ ++	for (i = 0, up = serial8250_ports; ++	     i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; ++	     i++, up++) { ++		up->port.iobase   = old_serial_port[i].port; ++		up->port.irq      = irq_canonicalize(old_serial_port[i].irq); ++		up->port.uartclk  = old_serial_port[i].baud_base * 16; ++		up->port.flags    = old_serial_port[i].flags; ++		up->port.hub6     = old_serial_port[i].hub6; ++		up->port.membase  = old_serial_port[i].iomem_base; ++		up->port.iotype   = old_serial_port[i].io_type; ++		up->port.regshift = old_serial_port[i].iomem_reg_shift; ++		if (share_irqs) ++			up->port.flags |= UPF_SHARE_IRQ; ++	} ++} ++ ++static void __init ++serial8250_register_ports(struct uart_driver *drv, struct device *dev) ++{ ++	int i; ++ ++	serial8250_isa_init_ports(); ++ ++	for (i = 0; i < nr_uarts; i++) { ++		struct uart_8250_port *up = &serial8250_ports[i]; ++ ++		up->port.dev = dev; ++		uart_add_one_port(drv, &up->port); ++	} ++} ++ ++#ifdef CONFIG_SERIAL_8250_CONSOLE ++ ++static void serial8250_console_putchar(struct uart_port *port, int ch) ++{ ++	struct uart_8250_port *up = (struct uart_8250_port *)port; ++ ++	wait_for_xmitr(up, UART_LSR_THRE); ++	serial_out(up, UART_TX, ch); ++} ++ ++/* ++ *	Print a string to the serial port trying not to disturb ++ *	any possible real use of the port... ++ * ++ *	The console_lock must be held when we get here. ++ */ ++static void ++serial8250_console_write(struct console *co, const char *s, unsigned int count) ++{ ++	struct uart_8250_port *up = &serial8250_ports[co->index]; ++	unsigned long flags; ++	unsigned int ier; ++	int locked = 1; ++ ++	touch_nmi_watchdog(); ++ ++	local_irq_save(flags); ++	if (up->port.sysrq) { ++		/* serial8250_handle_port() already took the lock */ ++		locked = 0; ++	} else if (oops_in_progress) { ++		locked = spin_trylock(&up->port.lock); ++	} else ++		spin_lock(&up->port.lock); ++ ++	/* ++	 *	First save the IER then disable the interrupts ++	 */ ++	ier = serial_in(up, UART_IER); ++ ++	if (up->capabilities & UART_CAP_UUE) ++		serial_out(up, UART_IER, UART_IER_UUE); ++	else ++		serial_out(up, UART_IER, 0); ++ ++	uart_console_write(&up->port, s, count, serial8250_console_putchar); ++ ++	/* ++	 *	Finally, wait for transmitter to become empty ++	 *	and restore the IER ++	 */ ++	wait_for_xmitr(up, BOTH_EMPTY); ++	serial_out(up, UART_IER, ier); ++ ++	if (locked) ++		spin_unlock(&up->port.lock); ++	local_irq_restore(flags); ++} ++ ++static int __init serial8250_console_setup(struct console *co, char *options) ++{ ++	struct uart_port *port; ++	int baud = 9600; ++	int bits = 8; ++	int parity = 'n'; ++	int flow = 'n'; ++ ++	/* ++	 * Check whether an invalid uart number has been specified, and ++	 * if so, search for the first available port that does have ++	 * console support. ++	 */ ++	if (co->index >= nr_uarts) ++		co->index = 0; ++	port = &serial8250_ports[co->index].port; ++	if (!port->iobase && !port->membase) ++		return -ENODEV; ++ ++	if (options) ++		uart_parse_options(options, &baud, &parity, &bits, &flow); ++ ++	return uart_set_options(port, co, baud, parity, bits, flow); ++} ++ ++static struct uart_driver serial8250_reg; ++static struct console serial8250_console = { ++	.name		= "ttyS", ++	.write		= serial8250_console_write, ++	.device		= uart_console_device, ++	.setup		= serial8250_console_setup, ++	.flags		= CON_PRINTBUFFER, ++	.index		= -1, ++	.data		= &serial8250_reg, ++}; ++ ++static int __init serial8250_console_init(void) ++{ ++	serial8250_isa_init_ports(); ++	register_console(&serial8250_console); ++	return 0; ++} ++console_initcall(serial8250_console_init); ++ ++static int __init find_port(struct uart_port *p) ++{ ++	int line; ++	struct uart_port *port; ++ ++	for (line = 0; line < nr_uarts; line++) { ++		port = &serial8250_ports[line].port; ++		if (uart_match_port(p, port)) ++			return line; ++	} ++	return -ENODEV; ++} ++ ++int __init serial8250_start_console(struct uart_port *port, char *options) ++{ ++	int line; ++ ++	line = find_port(port); ++	if (line < 0) ++		return -ENODEV; ++ ++	add_preferred_console("ttyS", line, options); ++	printk("Adding console on ttyS%d at %s 0x%lx (options '%s')\n", ++		line, port->iotype == UPIO_MEM ? "MMIO" : "I/O port", ++		port->iotype == UPIO_MEM ? (unsigned long) port->mapbase : ++		    (unsigned long) port->iobase, options); ++	if (!(serial8250_console.flags & CON_ENABLED)) { ++		serial8250_console.flags &= ~CON_PRINTBUFFER; ++		register_console(&serial8250_console); ++	} ++	return line; ++} ++ ++#define SERIAL8250_CONSOLE	&serial8250_console ++#else ++#define SERIAL8250_CONSOLE	NULL ++#endif ++ ++static struct uart_driver serial8250_reg = { ++	.owner			= THIS_MODULE, ++	.driver_name		= "serial", ++	.dev_name		= "ttyS", ++	.major			= TTY_MAJOR, ++	.minor			= 64, ++	.nr			= UART_NR, ++	.cons			= SERIAL8250_CONSOLE, ++}; ++ ++/* ++ * early_serial_setup - early registration for 8250 ports ++ * ++ * Setup an 8250 port structure prior to console initialisation.  Use ++ * after console initialisation will cause undefined behaviour. ++ */ ++int __init early_serial_setup(struct uart_port *port) ++{ ++	if (port->line >= ARRAY_SIZE(serial8250_ports)) ++		return -ENODEV; ++ ++	serial8250_isa_init_ports(); ++	serial8250_ports[port->line].port	= *port; ++	serial8250_ports[port->line].port.ops	= &serial8250_pops; ++	return 0; ++} ++ ++/** ++ *	serial8250_suspend_port - suspend one serial port ++ *	@line:  serial line number ++ * ++ *	Suspend one serial port. ++ */ ++void serial8250_suspend_port(int line) ++{ ++	uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port); ++} ++ ++/** ++ *	serial8250_resume_port - resume one serial port ++ *	@line:  serial line number ++ * ++ *	Resume one serial port. ++ */ ++void serial8250_resume_port(int line) ++{ ++	uart_resume_port(&serial8250_reg, &serial8250_ports[line].port); ++} ++ ++/* ++ * Register a set of serial devices attached to a platform device.  The ++ * list is terminated with a zero flags entry, which means we expect ++ * all entries to have at least UPF_BOOT_AUTOCONF set. ++ */ ++static int __devinit serial8250_probe(struct platform_device *dev) ++{ ++	struct plat_serial8250_port *p = dev->dev.platform_data; ++	struct uart_port port; ++	int ret, i; ++ ++	memset(&port, 0, sizeof(struct uart_port)); ++ ++	for (i = 0; p && p->flags != 0; p++, i++) { ++		port.iobase	= p->iobase; ++		port.membase	= p->membase; ++		port.irq	= p->irq; ++		port.uartclk	= p->uartclk; ++		port.regshift	= p->regshift; ++		port.iotype	= p->iotype; ++		port.flags	= p->flags; ++		port.mapbase	= p->mapbase; ++		port.hub6	= p->hub6; ++		port.dev	= &dev->dev; ++		if (share_irqs) ++			port.flags |= UPF_SHARE_IRQ; ++		ret = serial8250_register_port(&port); ++		if (ret < 0) { ++			dev_err(&dev->dev, "unable to register port at index %d " ++				"(IO%lx MEM%lx IRQ%d): %d\n", i, ++				p->iobase, p->mapbase, p->irq, ret); ++		} ++	} ++	return 0; ++} ++ ++/* ++ * Remove serial ports registered against a platform device. ++ */ ++static int __devexit serial8250_remove(struct platform_device *dev) ++{ ++	int i; ++ ++	for (i = 0; i < nr_uarts; i++) { ++		struct uart_8250_port *up = &serial8250_ports[i]; ++ ++		if (up->port.dev == &dev->dev) ++			serial8250_unregister_port(i); ++	} ++	return 0; ++} ++ ++static int serial8250_suspend(struct platform_device *dev, pm_message_t state) ++{ ++	int i; ++ ++	for (i = 0; i < UART_NR; i++) { ++		struct uart_8250_port *up = &serial8250_ports[i]; ++ ++		if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev) ++			uart_suspend_port(&serial8250_reg, &up->port); ++	} ++ ++	return 0; ++} ++ ++static int serial8250_resume(struct platform_device *dev) ++{ ++	int i; ++ ++	for (i = 0; i < UART_NR; i++) { ++		struct uart_8250_port *up = &serial8250_ports[i]; ++ ++		if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev) ++			uart_resume_port(&serial8250_reg, &up->port); ++	} ++ ++	return 0; ++} ++ ++static struct platform_driver serial8250_isa_driver = { ++	.probe		= serial8250_probe, ++	.remove		= __devexit_p(serial8250_remove), ++	.suspend	= serial8250_suspend, ++	.resume		= serial8250_resume, ++	.driver		= { ++		.name	= "serial8250", ++		.owner	= THIS_MODULE, ++	}, ++}; ++ ++/* ++ * This "device" covers _all_ ISA 8250-compatible serial devices listed ++ * in the table in include/asm/serial.h ++ */ ++static struct platform_device *serial8250_isa_devs; ++ ++/* ++ * serial8250_register_port and serial8250_unregister_port allows for ++ * 16x50 serial ports to be configured at run-time, to support PCMCIA ++ * modems and PCI multiport cards. ++ */ ++static DEFINE_MUTEX(serial_mutex); ++ ++static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port) ++{ ++	int i; ++ ++	/* ++	 * First, find a port entry which matches. ++	 */ ++	for (i = 0; i < nr_uarts; i++) ++		if (uart_match_port(&serial8250_ports[i].port, port)) ++			return &serial8250_ports[i]; ++ ++	/* ++	 * We didn't find a matching entry, so look for the first ++	 * free entry.  We look for one which hasn't been previously ++	 * used (indicated by zero iobase). ++	 */ ++	for (i = 0; i < nr_uarts; i++) ++		if (serial8250_ports[i].port.type == PORT_UNKNOWN && ++		    serial8250_ports[i].port.iobase == 0) ++			return &serial8250_ports[i]; ++ ++	/* ++	 * That also failed.  Last resort is to find any entry which ++	 * doesn't have a real port associated with it. ++	 */ ++	for (i = 0; i < nr_uarts; i++) ++		if (serial8250_ports[i].port.type == PORT_UNKNOWN) ++			return &serial8250_ports[i]; ++ ++	return NULL; ++} ++ ++/** ++ *	serial8250_register_port - register a serial port ++ *	@port: serial port template ++ * ++ *	Configure the serial port specified by the request. If the ++ *	port exists and is in use, it is hung up and unregistered ++ *	first. ++ * ++ *	The port is then probed and if necessary the IRQ is autodetected ++ *	If this fails an error is returned. ++ * ++ *	On success the port is ready to use and the line number is returned. ++ */ ++int serial8250_register_port(struct uart_port *port) ++{ ++	struct uart_8250_port *uart; ++	int ret = -ENOSPC; ++ ++	if (port->uartclk == 0) ++		return -EINVAL; ++ ++	mutex_lock(&serial_mutex); ++ ++	uart = serial8250_find_match_or_unused(port); ++	if (uart) { ++		uart_remove_one_port(&serial8250_reg, &uart->port); ++ ++		uart->port.iobase   = port->iobase; ++		uart->port.membase  = port->membase; ++		uart->port.irq      = port->irq; ++		uart->port.uartclk  = port->uartclk; ++		uart->port.fifosize = port->fifosize; ++		uart->port.regshift = port->regshift; ++		uart->port.iotype   = port->iotype; ++		uart->port.flags    = port->flags | UPF_BOOT_AUTOCONF; ++		uart->port.mapbase  = port->mapbase; ++		if (port->dev) ++			uart->port.dev = port->dev; ++ ++		ret = uart_add_one_port(&serial8250_reg, &uart->port); ++		if (ret == 0) ++			ret = uart->port.line; ++	} ++	mutex_unlock(&serial_mutex); ++ ++	return ret; ++} ++EXPORT_SYMBOL(serial8250_register_port); ++ ++/** ++ *	serial8250_unregister_port - remove a 16x50 serial port at runtime ++ *	@line: serial line number ++ * ++ *	Remove one serial port.  This may not be called from interrupt ++ *	context.  We hand the port back to the our control. ++ */ ++void serial8250_unregister_port(int line) ++{ ++	struct uart_8250_port *uart = &serial8250_ports[line]; ++ ++	mutex_lock(&serial_mutex); ++	uart_remove_one_port(&serial8250_reg, &uart->port); ++	if (serial8250_isa_devs) { ++		uart->port.flags &= ~UPF_BOOT_AUTOCONF; ++		uart->port.type = PORT_UNKNOWN; ++		uart->port.dev = &serial8250_isa_devs->dev; ++		uart_add_one_port(&serial8250_reg, &uart->port); ++	} else { ++		uart->port.dev = NULL; ++	} ++	mutex_unlock(&serial_mutex); ++} ++EXPORT_SYMBOL(serial8250_unregister_port); ++ ++static int __init serial8250_init(void) ++{ ++	int ret, i; ++ ++	if (nr_uarts > UART_NR) ++		nr_uarts = UART_NR; ++ ++	printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ " ++		"%d ports, IRQ sharing %sabled\n", nr_uarts, ++		share_irqs ? "en" : "dis"); ++ ++	for (i = 0; i < NR_IRQS; i++) ++		spin_lock_init(&irq_lists[i].lock); ++ ++	ret = uart_register_driver(&serial8250_reg); ++	if (ret) ++		goto out; ++ ++	serial8250_isa_devs = platform_device_alloc("serial8250", ++						    PLAT8250_DEV_LEGACY); ++	if (!serial8250_isa_devs) { ++		ret = -ENOMEM; ++		goto unreg_uart_drv; ++	} ++ ++	ret = platform_device_add(serial8250_isa_devs); ++	if (ret) ++		goto put_dev; ++ ++	serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev); ++ ++	ret = platform_driver_register(&serial8250_isa_driver); ++	if (ret == 0) ++		goto out; ++ ++	platform_device_del(serial8250_isa_devs); ++ put_dev: ++	platform_device_put(serial8250_isa_devs); ++ unreg_uart_drv: ++	uart_unregister_driver(&serial8250_reg); ++ out: ++	return ret; ++} ++ ++static void __exit serial8250_exit(void) ++{ ++	struct platform_device *isa_dev = serial8250_isa_devs; ++ ++	/* ++	 * This tells serial8250_unregister_port() not to re-register ++	 * the ports (thereby making serial8250_isa_driver permanently ++	 * in use.) ++	 */ ++	serial8250_isa_devs = NULL; ++ ++	platform_driver_unregister(&serial8250_isa_driver); ++	platform_device_unregister(isa_dev); ++ ++	uart_unregister_driver(&serial8250_reg); ++} ++ ++module_init(serial8250_init); ++module_exit(serial8250_exit); ++ ++EXPORT_SYMBOL(serial8250_suspend_port); ++EXPORT_SYMBOL(serial8250_resume_port); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Generic 8250/16x50 serial driver $Revision: 1.90 $"); ++ ++module_param(share_irqs, uint, 0644); ++MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices" ++	" (unsafe)"); ++ ++module_param(nr_uarts, uint, 0644); ++MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); ++ ++#ifdef CONFIG_SERIAL_8250_RSA ++module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); ++MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); ++#endif ++MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR); +diff -Nur linux-2.6.21.1/drivers/usb/host/ehci.h linux-2.6.21.1-owrt/drivers/usb/host/ehci.h +--- linux-2.6.21.1/drivers/usb/host/ehci.h	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/drivers/usb/host/ehci.h	2007-05-23 23:37:18.000000000 +0200 +@@ -87,6 +87,7 @@ + 	struct dma_pool		*sitd_pool;	/* sitd per split iso urb */ +  + 	struct timer_list	watchdog; ++	struct timer_list	softirq; + 	unsigned long		actions; + 	unsigned		stamp; + 	unsigned long		next_statechange; +diff -Nur linux-2.6.21.1/drivers/usb/host/ehci-hcd.c linux-2.6.21.1-owrt/drivers/usb/host/ehci-hcd.c +--- linux-2.6.21.1/drivers/usb/host/ehci-hcd.c	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/drivers/usb/host/ehci-hcd.c	2007-05-23 23:37:18.000000000 +0200 +@@ -118,6 +118,7 @@ + #define EHCI_IO_JIFFIES		(HZ/10)		/* io watchdog > irq_thresh */ + #define EHCI_ASYNC_JIFFIES	(HZ/20)		/* async idle timeout */ + #define EHCI_SHRINK_JIFFIES	(HZ/200)	/* async qh unlink delay */ ++#define EHCI_SOFTIRQ		(HZ/400) +  + /* Initial IRQ latency:  faster than hw default */ + static int log2_irq_thresh = 0;		// 0 to 6 +@@ -273,6 +274,16 @@ + #include "ehci-sched.c" +  + /*-------------------------------------------------------------------------*/ ++static irqreturn_t ehci_irq (struct usb_hcd *hcd); ++ ++static void ehci_softirq (unsigned long param) ++{ ++	struct ehci_hcd         *ehci = (struct ehci_hcd *) param; ++ ++	if (ehci_irq(ehci_to_hcd(ehci)) != IRQ_NONE) ++		set_bit(HCD_FLAG_SAW_IRQ, &(ehci_to_hcd(ehci))->flags); ++	mod_timer (&ehci->softirq, jiffies + EHCI_SOFTIRQ); ++} +  + static void ehci_watchdog (unsigned long param) + { +@@ -289,6 +300,10 @@ + 			COUNT (ehci->stats.lost_iaa); + 			ehci_writel(ehci, STS_IAA, &ehci->regs->status); + 			ehci->reclaim_ready = 1; ++			if (!timer_pending(&ehci->softirq)) { ++				ehci_info(ehci, "switching to softirq\n"); ++				mod_timer (&ehci->softirq, jiffies + EHCI_SOFTIRQ); ++			} + 		} + 	} +  +@@ -396,6 +411,7 @@ +  + 	/* no more interrupts ... */ + 	del_timer_sync (&ehci->watchdog); ++	del_timer_sync (&ehci->softirq); +  + 	spin_lock_irq(&ehci->lock); + 	if (HC_IS_RUNNING (hcd->state)) +@@ -444,6 +460,10 @@ + 	ehci->watchdog.function = ehci_watchdog; + 	ehci->watchdog.data = (unsigned long) ehci; +  ++	init_timer(&ehci->softirq); ++	ehci->softirq.function = ehci_softirq; ++	ehci->softirq.data = (unsigned long) ehci; ++ + 	/* + 	 * hw default: 1K periodic list heads, one per frame. + 	 * periodic_size can shrink by USBCMD update if hcc_params allows. +diff -Nur linux-2.6.21.1/drivers/usb/host/ehci-hcd.c.orig linux-2.6.21.1-owrt/drivers/usb/host/ehci-hcd.c.orig +--- linux-2.6.21.1/drivers/usb/host/ehci-hcd.c.orig	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.1-owrt/drivers/usb/host/ehci-hcd.c.orig	2007-04-27 23:49:26.000000000 +0200 +@@ -0,0 +1,1008 @@ ++/* ++ * Copyright (c) 2000-2004 by David Brownell ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License ++ * for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include <linux/module.h> ++#include <linux/pci.h> ++#include <linux/dmapool.h> ++#include <linux/kernel.h> ++#include <linux/delay.h> ++#include <linux/ioport.h> ++#include <linux/sched.h> ++#include <linux/slab.h> ++#include <linux/smp_lock.h> ++#include <linux/errno.h> ++#include <linux/init.h> ++#include <linux/timer.h> ++#include <linux/list.h> ++#include <linux/interrupt.h> ++#include <linux/reboot.h> ++#include <linux/usb.h> ++#include <linux/moduleparam.h> ++#include <linux/dma-mapping.h> ++ ++#include "../core/hcd.h" ++ ++#include <asm/byteorder.h> ++#include <asm/io.h> ++#include <asm/irq.h> ++#include <asm/system.h> ++#include <asm/unaligned.h> ++#ifdef CONFIG_PPC_PS3 ++#include <asm/firmware.h> ++#endif ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * EHCI hc_driver implementation ... experimental, incomplete. ++ * Based on the final 1.0 register interface specification. ++ * ++ * USB 2.0 shows up in upcoming www.pcmcia.org technology. ++ * First was PCMCIA, like ISA; then CardBus, which is PCI. ++ * Next comes "CardBay", using USB 2.0 signals. ++ * ++ * Contains additional contributions by Brad Hards, Rory Bolt, and others. ++ * Special thanks to Intel and VIA for providing host controllers to ++ * test this driver on, and Cypress (including In-System Design) for ++ * providing early devices for those host controllers to talk to! ++ * ++ * HISTORY: ++ * ++ * 2004-05-10 Root hub and PCI suspend/resume support; remote wakeup. (db) ++ * 2004-02-24 Replace pci_* with generic dma_* API calls (dsaxena@plexity.net) ++ * 2003-12-29 Rewritten high speed iso transfer support (by Michal Sojka, ++ *	<sojkam@centrum.cz>, updates by DB). ++ * ++ * 2002-11-29	Correct handling for hw async_next register. ++ * 2002-08-06	Handling for bulk and interrupt transfers is mostly shared; ++ *	only scheduling is different, no arbitrary limitations. ++ * 2002-07-25	Sanity check PCI reads, mostly for better cardbus support, ++ *	clean up HC run state handshaking. ++ * 2002-05-24	Preliminary FS/LS interrupts, using scheduling shortcuts ++ * 2002-05-11	Clear TT errors for FS/LS ctrl/bulk.  Fill in some other ++ *	missing pieces:  enabling 64bit dma, handoff from BIOS/SMM. ++ * 2002-05-07	Some error path cleanups to report better errors; wmb(); ++ *	use non-CVS version id; better iso bandwidth claim. ++ * 2002-04-19	Control/bulk/interrupt submit no longer uses giveback() on ++ *	errors in submit path.  Bugfixes to interrupt scheduling/processing. ++ * 2002-03-05	Initial high-speed ISO support; reduce ITD memory; shift ++ *	more checking to generic hcd framework (db).  Make it work with ++ *	Philips EHCI; reduce PCI traffic; shorten IRQ path (Rory Bolt). ++ * 2002-01-14	Minor cleanup; version synch. ++ * 2002-01-08	Fix roothub handoff of FS/LS to companion controllers. ++ * 2002-01-04	Control/Bulk queuing behaves. ++ * ++ * 2001-12-12	Initial patch version for Linux 2.5.1 kernel. ++ * 2001-June	Works with usb-storage and NEC EHCI on 2.4 ++ */ ++ ++#define DRIVER_VERSION "10 Dec 2004" ++#define DRIVER_AUTHOR "David Brownell" ++#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver" ++ ++static const char	hcd_name [] = "ehci_hcd"; ++ ++ ++#undef EHCI_VERBOSE_DEBUG ++#undef EHCI_URB_TRACE ++ ++#ifdef DEBUG ++#define EHCI_STATS ++#endif ++ ++/* magic numbers that can affect system performance */ ++#define	EHCI_TUNE_CERR		3	/* 0-3 qtd retries; 0 == don't stop */ ++#define	EHCI_TUNE_RL_HS		4	/* nak throttle; see 4.9 */ ++#define	EHCI_TUNE_RL_TT		0 ++#define	EHCI_TUNE_MULT_HS	1	/* 1-3 transactions/uframe; 4.10.3 */ ++#define	EHCI_TUNE_MULT_TT	1 ++#define	EHCI_TUNE_FLS		2	/* (small) 256 frame schedule */ ++ ++#define EHCI_IAA_JIFFIES	(HZ/100)	/* arbitrary; ~10 msec */ ++#define EHCI_IO_JIFFIES		(HZ/10)		/* io watchdog > irq_thresh */ ++#define EHCI_ASYNC_JIFFIES	(HZ/20)		/* async idle timeout */ ++#define EHCI_SHRINK_JIFFIES	(HZ/200)	/* async qh unlink delay */ ++ ++/* Initial IRQ latency:  faster than hw default */ ++static int log2_irq_thresh = 0;		// 0 to 6 ++module_param (log2_irq_thresh, int, S_IRUGO); ++MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes"); ++ ++/* initial park setting:  slower than hw default */ ++static unsigned park = 0; ++module_param (park, uint, S_IRUGO); ++MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets"); ++ ++/* for flakey hardware, ignore overcurrent indicators */ ++static int ignore_oc = 0; ++module_param (ignore_oc, bool, S_IRUGO); ++MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); ++ ++#define	INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) ++ ++/*-------------------------------------------------------------------------*/ ++ ++#include "ehci.h" ++#include "ehci-dbg.c" ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * handshake - spin reading hc until handshake completes or fails ++ * @ptr: address of hc register to be read ++ * @mask: bits to look at in result of read ++ * @done: value of those bits when handshake succeeds ++ * @usec: timeout in microseconds ++ * ++ * Returns negative errno, or zero on success ++ * ++ * Success happens when the "mask" bits have the specified value (hardware ++ * handshake done).  There are two failure modes:  "usec" have passed (major ++ * hardware flakeout), or the register reads as all-ones (hardware removed). ++ * ++ * That last failure should_only happen in cases like physical cardbus eject ++ * before driver shutdown. But it also seems to be caused by bugs in cardbus ++ * bridge shutdown:  shutting down the bridge before the devices using it. ++ */ ++static int handshake (struct ehci_hcd *ehci, void __iomem *ptr, ++		      u32 mask, u32 done, int usec) ++{ ++	u32	result; ++ ++	do { ++		result = ehci_readl(ehci, ptr); ++		if (result == ~(u32)0)		/* card removed */ ++			return -ENODEV; ++		result &= mask; ++		if (result == done) ++			return 0; ++		udelay (1); ++		usec--; ++	} while (usec > 0); ++	return -ETIMEDOUT; ++} ++ ++/* force HC to halt state from unknown (EHCI spec section 2.3) */ ++static int ehci_halt (struct ehci_hcd *ehci) ++{ ++	u32	temp = ehci_readl(ehci, &ehci->regs->status); ++ ++	/* disable any irqs left enabled by previous code */ ++	ehci_writel(ehci, 0, &ehci->regs->intr_enable); ++ ++	if ((temp & STS_HALT) != 0) ++		return 0; ++ ++	temp = ehci_readl(ehci, &ehci->regs->command); ++	temp &= ~CMD_RUN; ++	ehci_writel(ehci, temp, &ehci->regs->command); ++	return handshake (ehci, &ehci->regs->status, ++			  STS_HALT, STS_HALT, 16 * 125); ++} ++ ++/* put TDI/ARC silicon into EHCI mode */ ++static void tdi_reset (struct ehci_hcd *ehci) ++{ ++	u32 __iomem	*reg_ptr; ++	u32		tmp; ++ ++	reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + 0x68); ++	tmp = ehci_readl(ehci, reg_ptr); ++	tmp |= 0x3; ++	ehci_writel(ehci, tmp, reg_ptr); ++} ++ ++/* reset a non-running (STS_HALT == 1) controller */ ++static int ehci_reset (struct ehci_hcd *ehci) ++{ ++	int	retval; ++	u32	command = ehci_readl(ehci, &ehci->regs->command); ++ ++	command |= CMD_RESET; ++	dbg_cmd (ehci, "reset", command); ++	ehci_writel(ehci, command, &ehci->regs->command); ++	ehci_to_hcd(ehci)->state = HC_STATE_HALT; ++	ehci->next_statechange = jiffies; ++	retval = handshake (ehci, &ehci->regs->command, ++			    CMD_RESET, 0, 250 * 1000); ++ ++	if (retval) ++		return retval; ++ ++	if (ehci_is_TDI(ehci)) ++		tdi_reset (ehci); ++ ++	return retval; ++} ++ ++/* idle the controller (from running) */ ++static void ehci_quiesce (struct ehci_hcd *ehci) ++{ ++	u32	temp; ++ ++#ifdef DEBUG ++	if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) ++		BUG (); ++#endif ++ ++	/* wait for any schedule enables/disables to take effect */ ++	temp = ehci_readl(ehci, &ehci->regs->command) << 10; ++	temp &= STS_ASS | STS_PSS; ++	if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS, ++				temp, 16 * 125) != 0) { ++		ehci_to_hcd(ehci)->state = HC_STATE_HALT; ++		return; ++	} ++ ++	/* then disable anything that's still active */ ++	temp = ehci_readl(ehci, &ehci->regs->command); ++	temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE); ++	ehci_writel(ehci, temp, &ehci->regs->command); ++ ++	/* hardware can take 16 microframes to turn off ... */ ++	if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS, ++				0, 16 * 125) != 0) { ++		ehci_to_hcd(ehci)->state = HC_STATE_HALT; ++		return; ++	} ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void ehci_work(struct ehci_hcd *ehci); ++ ++#include "ehci-hub.c" ++#include "ehci-mem.c" ++#include "ehci-q.c" ++#include "ehci-sched.c" ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void ehci_watchdog (unsigned long param) ++{ ++	struct ehci_hcd		*ehci = (struct ehci_hcd *) param; ++	unsigned long		flags; ++ ++	spin_lock_irqsave (&ehci->lock, flags); ++ ++	/* lost IAA irqs wedge things badly; seen with a vt8235 */ ++	if (ehci->reclaim) { ++		u32		status = ehci_readl(ehci, &ehci->regs->status); ++		if (status & STS_IAA) { ++			ehci_vdbg (ehci, "lost IAA\n"); ++			COUNT (ehci->stats.lost_iaa); ++			ehci_writel(ehci, STS_IAA, &ehci->regs->status); ++			ehci->reclaim_ready = 1; ++		} ++	} ++ ++ 	/* stop async processing after it's idled a bit */ ++	if (test_bit (TIMER_ASYNC_OFF, &ehci->actions)) ++		start_unlink_async (ehci, ehci->async); ++ ++	/* ehci could run by timer, without IRQs ... */ ++	ehci_work (ehci); ++ ++	spin_unlock_irqrestore (&ehci->lock, flags); ++} ++ ++/* On some systems, leaving remote wakeup enabled prevents system shutdown. ++ * The firmware seems to think that powering off is a wakeup event! ++ * This routine turns off remote wakeup and everything else, on all ports. ++ */ ++static void ehci_turn_off_all_ports(struct ehci_hcd *ehci) ++{ ++	int	port = HCS_N_PORTS(ehci->hcs_params); ++ ++	while (port--) ++		ehci_writel(ehci, PORT_RWC_BITS, ++				&ehci->regs->port_status[port]); ++} ++ ++/* ehci_shutdown kick in for silicon on any bus (not just pci, etc). ++ * This forcibly disables dma and IRQs, helping kexec and other cases ++ * where the next system software may expect clean state. ++ */ ++static void ++ehci_shutdown (struct usb_hcd *hcd) ++{ ++	struct ehci_hcd	*ehci; ++ ++	ehci = hcd_to_ehci (hcd); ++	(void) ehci_halt (ehci); ++	ehci_turn_off_all_ports(ehci); ++ ++	/* make BIOS/etc use companion controller during reboot */ ++	ehci_writel(ehci, 0, &ehci->regs->configured_flag); ++ ++	/* unblock posted writes */ ++	ehci_readl(ehci, &ehci->regs->configured_flag); ++} ++ ++static void ehci_port_power (struct ehci_hcd *ehci, int is_on) ++{ ++	unsigned port; ++ ++	if (!HCS_PPC (ehci->hcs_params)) ++		return; ++ ++	ehci_dbg (ehci, "...power%s ports...\n", is_on ? "up" : "down"); ++	for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) ++		(void) ehci_hub_control(ehci_to_hcd(ehci), ++				is_on ? SetPortFeature : ClearPortFeature, ++				USB_PORT_FEAT_POWER, ++				port--, NULL, 0); ++	msleep(20); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * ehci_work is called from some interrupts, timers, and so on. ++ * it calls driver completion functions, after dropping ehci->lock. ++ */ ++static void ehci_work (struct ehci_hcd *ehci) ++{ ++	timer_action_done (ehci, TIMER_IO_WATCHDOG); ++	if (ehci->reclaim_ready) ++		end_unlink_async (ehci); ++ ++	/* another CPU may drop ehci->lock during a schedule scan while ++	 * it reports urb completions.  this flag guards against bogus ++	 * attempts at re-entrant schedule scanning. ++	 */ ++	if (ehci->scanning) ++		return; ++	ehci->scanning = 1; ++	scan_async (ehci); ++	if (ehci->next_uframe != -1) ++		scan_periodic (ehci); ++	ehci->scanning = 0; ++ ++	/* the IO watchdog guards against hardware or driver bugs that ++	 * misplace IRQs, and should let us run completely without IRQs. ++	 * such lossage has been observed on both VT6202 and VT8235. ++	 */ ++	if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && ++			(ehci->async->qh_next.ptr != NULL || ++			 ehci->periodic_sched != 0)) ++		timer_action (ehci, TIMER_IO_WATCHDOG); ++} ++ ++static void ehci_stop (struct usb_hcd *hcd) ++{ ++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd); ++ ++	ehci_dbg (ehci, "stop\n"); ++ ++	/* Turn off port power on all root hub ports. */ ++	ehci_port_power (ehci, 0); ++ ++	/* no more interrupts ... */ ++	del_timer_sync (&ehci->watchdog); ++ ++	spin_lock_irq(&ehci->lock); ++	if (HC_IS_RUNNING (hcd->state)) ++		ehci_quiesce (ehci); ++ ++	ehci_reset (ehci); ++	ehci_writel(ehci, 0, &ehci->regs->intr_enable); ++	spin_unlock_irq(&ehci->lock); ++ ++	/* let companion controllers work when we aren't */ ++	ehci_writel(ehci, 0, &ehci->regs->configured_flag); ++ ++	remove_companion_file(ehci); ++	remove_debug_files (ehci); ++ ++	/* root hub is shut down separately (first, when possible) */ ++	spin_lock_irq (&ehci->lock); ++	if (ehci->async) ++		ehci_work (ehci); ++	spin_unlock_irq (&ehci->lock); ++	ehci_mem_cleanup (ehci); ++ ++#ifdef	EHCI_STATS ++	ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", ++		ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, ++		ehci->stats.lost_iaa); ++	ehci_dbg (ehci, "complete %ld unlink %ld\n", ++		ehci->stats.complete, ehci->stats.unlink); ++#endif ++ ++	dbg_status (ehci, "ehci_stop completed", ++		    ehci_readl(ehci, &ehci->regs->status)); ++} ++ ++/* one-time init, only for memory state */ ++static int ehci_init(struct usb_hcd *hcd) ++{ ++	struct ehci_hcd		*ehci = hcd_to_ehci(hcd); ++	u32			temp; ++	int			retval; ++	u32			hcc_params; ++ ++	spin_lock_init(&ehci->lock); ++ ++	init_timer(&ehci->watchdog); ++	ehci->watchdog.function = ehci_watchdog; ++	ehci->watchdog.data = (unsigned long) ehci; ++ ++	/* ++	 * hw default: 1K periodic list heads, one per frame. ++	 * periodic_size can shrink by USBCMD update if hcc_params allows. ++	 */ ++	ehci->periodic_size = DEFAULT_I_TDPS; ++	if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) ++		return retval; ++ ++	/* controllers may cache some of the periodic schedule ... */ ++	hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); ++	if (HCC_ISOC_CACHE(hcc_params))		// full frame cache ++		ehci->i_thresh = 8; ++	else					// N microframes cached ++		ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); ++ ++	ehci->reclaim = NULL; ++	ehci->reclaim_ready = 0; ++	ehci->next_uframe = -1; ++ ++	/* ++	 * dedicate a qh for the async ring head, since we couldn't unlink ++	 * a 'real' qh without stopping the async schedule [4.8].  use it ++	 * as the 'reclamation list head' too. ++	 * its dummy is used in hw_alt_next of many tds, to prevent the qh ++	 * from automatically advancing to the next td after short reads. ++	 */ ++	ehci->async->qh_next.qh = NULL; ++	ehci->async->hw_next = QH_NEXT(ehci->async->qh_dma); ++	ehci->async->hw_info1 = cpu_to_le32(QH_HEAD); ++	ehci->async->hw_token = cpu_to_le32(QTD_STS_HALT); ++	ehci->async->hw_qtd_next = EHCI_LIST_END; ++	ehci->async->qh_state = QH_STATE_LINKED; ++	ehci->async->hw_alt_next = QTD_NEXT(ehci->async->dummy->qtd_dma); ++ ++	/* clear interrupt enables, set irq latency */ ++	if (log2_irq_thresh < 0 || log2_irq_thresh > 6) ++		log2_irq_thresh = 0; ++	temp = 1 << (16 + log2_irq_thresh); ++	if (HCC_CANPARK(hcc_params)) { ++		/* HW default park == 3, on hardware that supports it (like ++		 * NVidia and ALI silicon), maximizes throughput on the async ++		 * schedule by avoiding QH fetches between transfers. ++		 * ++		 * With fast usb storage devices and NForce2, "park" seems to ++		 * make problems:  throughput reduction (!), data errors... ++		 */ ++		if (park) { ++			park = min(park, (unsigned) 3); ++			temp |= CMD_PARK; ++			temp |= park << 8; ++		} ++		ehci_dbg(ehci, "park %d\n", park); ++	} ++	if (HCC_PGM_FRAMELISTLEN(hcc_params)) { ++		/* periodic schedule size can be smaller than default */ ++		temp &= ~(3 << 2); ++		temp |= (EHCI_TUNE_FLS << 2); ++		switch (EHCI_TUNE_FLS) { ++		case 0: ehci->periodic_size = 1024; break; ++		case 1: ehci->periodic_size = 512; break; ++		case 2: ehci->periodic_size = 256; break; ++		default:	BUG(); ++		} ++	} ++	ehci->command = temp; ++ ++	return 0; ++} ++ ++/* start HC running; it's halted, ehci_init() has been run (once) */ ++static int ehci_run (struct usb_hcd *hcd) ++{ ++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd); ++	int			retval; ++	u32			temp; ++	u32			hcc_params; ++ ++	hcd->uses_new_polling = 1; ++	hcd->poll_rh = 0; ++ ++	/* EHCI spec section 4.1 */ ++	if ((retval = ehci_reset(ehci)) != 0) { ++		ehci_mem_cleanup(ehci); ++		return retval; ++	} ++	ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); ++	ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); ++ ++	/* ++	 * hcc_params controls whether ehci->regs->segment must (!!!) ++	 * be used; it constrains QH/ITD/SITD and QTD locations. ++	 * pci_pool consistent memory always uses segment zero. ++	 * streaming mappings for I/O buffers, like pci_map_single(), ++	 * can return segments above 4GB, if the device allows. ++	 * ++	 * NOTE:  the dma mask is visible through dma_supported(), so ++	 * drivers can pass this info along ... like NETIF_F_HIGHDMA, ++	 * Scsi_Host.highmem_io, and so forth.  It's readonly to all ++	 * host side drivers though. ++	 */ ++	hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); ++	if (HCC_64BIT_ADDR(hcc_params)) { ++		ehci_writel(ehci, 0, &ehci->regs->segment); ++#if 0 ++// this is deeply broken on almost all architectures ++		if (!dma_set_mask(hcd->self.controller, DMA_64BIT_MASK)) ++			ehci_info(ehci, "enabled 64bit DMA\n"); ++#endif ++	} ++ ++ ++	// Philips, Intel, and maybe others need CMD_RUN before the ++	// root hub will detect new devices (why?); NEC doesn't ++	ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); ++	ehci->command |= CMD_RUN; ++	ehci_writel(ehci, ehci->command, &ehci->regs->command); ++	dbg_cmd (ehci, "init", ehci->command); ++ ++	/* ++	 * Start, enabling full USB 2.0 functionality ... usb 1.1 devices ++	 * are explicitly handed to companion controller(s), so no TT is ++	 * involved with the root hub.  (Except where one is integrated, ++	 * and there's no companion controller unless maybe for USB OTG.) ++	 */ ++	hcd->state = HC_STATE_RUNNING; ++	ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ++	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */ ++ ++	temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); ++	ehci_info (ehci, ++		"USB %x.%x started, EHCI %x.%02x, driver %s%s\n", ++		((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), ++		temp >> 8, temp & 0xff, DRIVER_VERSION, ++		ignore_oc ? ", overcurrent ignored" : ""); ++ ++	ehci_writel(ehci, INTR_MASK, ++		    &ehci->regs->intr_enable); /* Turn On Interrupts */ ++ ++	/* GRR this is run-once init(), being done every time the HC starts. ++	 * So long as they're part of class devices, we can't do it init() ++	 * since the class device isn't created that early. ++	 */ ++	create_debug_files(ehci); ++	create_companion_file(ehci); ++ ++	return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static irqreturn_t ehci_irq (struct usb_hcd *hcd) ++{ ++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd); ++	u32			status, pcd_status = 0; ++	int			bh; ++ ++	spin_lock (&ehci->lock); ++ ++	status = ehci_readl(ehci, &ehci->regs->status); ++ ++	/* e.g. cardbus physical eject */ ++	if (status == ~(u32) 0) { ++		ehci_dbg (ehci, "device removed\n"); ++		goto dead; ++	} ++ ++	status &= INTR_MASK; ++	if (!status) {			/* irq sharing? */ ++		spin_unlock(&ehci->lock); ++		return IRQ_NONE; ++	} ++ ++	/* clear (just) interrupts */ ++	ehci_writel(ehci, status, &ehci->regs->status); ++	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted write */ ++	bh = 0; ++ ++#ifdef	EHCI_VERBOSE_DEBUG ++	/* unrequested/ignored: Frame List Rollover */ ++	dbg_status (ehci, "irq", status); ++#endif ++ ++	/* INT, ERR, and IAA interrupt rates can be throttled */ ++ ++	/* normal [4.15.1.2] or error [4.15.1.1] completion */ ++	if (likely ((status & (STS_INT|STS_ERR)) != 0)) { ++		if (likely ((status & STS_ERR) == 0)) ++			COUNT (ehci->stats.normal); ++		else ++			COUNT (ehci->stats.error); ++		bh = 1; ++	} ++ ++	/* complete the unlinking of some qh [4.15.2.3] */ ++	if (status & STS_IAA) { ++		COUNT (ehci->stats.reclaim); ++		ehci->reclaim_ready = 1; ++		bh = 1; ++	} ++ ++	/* remote wakeup [4.3.1] */ ++	if (status & STS_PCD) { ++		unsigned	i = HCS_N_PORTS (ehci->hcs_params); ++		pcd_status = status; ++ ++		/* resume root hub? */ ++		if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN)) ++			usb_hcd_resume_root_hub(hcd); ++ ++		while (i--) { ++			int pstatus = ehci_readl(ehci, ++						 &ehci->regs->port_status [i]); ++ ++			if (pstatus & PORT_OWNER) ++				continue; ++			if (!(pstatus & PORT_RESUME) ++					|| ehci->reset_done [i] != 0) ++				continue; ++ ++			/* start 20 msec resume signaling from this port, ++			 * and make khubd collect PORT_STAT_C_SUSPEND to ++			 * stop that signaling. ++			 */ ++			ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); ++			ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); ++			mod_timer(&hcd->rh_timer, ehci->reset_done[i]); ++		} ++	} ++ ++	/* PCI errors [4.15.2.4] */ ++	if (unlikely ((status & STS_FATAL) != 0)) { ++		/* bogus "fatal" IRQs appear on some chips... why?  */ ++		status = ehci_readl(ehci, &ehci->regs->status); ++		dbg_cmd (ehci, "fatal", ehci_readl(ehci, ++						   &ehci->regs->command)); ++		dbg_status (ehci, "fatal", status); ++		if (status & STS_HALT) { ++			ehci_err (ehci, "fatal error\n"); ++dead: ++			ehci_reset (ehci); ++			ehci_writel(ehci, 0, &ehci->regs->configured_flag); ++			/* generic layer kills/unlinks all urbs, then ++			 * uses ehci_stop to clean up the rest ++			 */ ++			bh = 1; ++		} ++	} ++ ++	if (bh) ++		ehci_work (ehci); ++	spin_unlock (&ehci->lock); ++	if (pcd_status & STS_PCD) ++		usb_hcd_poll_rh_status(hcd); ++	return IRQ_HANDLED; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * non-error returns are a promise to giveback() the urb later ++ * we drop ownership so next owner (or urb unlink) can get it ++ * ++ * urb + dev is in hcd.self.controller.urb_list ++ * we're queueing TDs onto software and hardware lists ++ * ++ * hcd-specific init for hcpriv hasn't been done yet ++ * ++ * NOTE:  control, bulk, and interrupt share the same code to append TDs ++ * to a (possibly active) QH, and the same QH scanning code. ++ */ ++static int ehci_urb_enqueue ( ++	struct usb_hcd	*hcd, ++	struct usb_host_endpoint *ep, ++	struct urb	*urb, ++	gfp_t		mem_flags ++) { ++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd); ++	struct list_head	qtd_list; ++ ++	INIT_LIST_HEAD (&qtd_list); ++ ++	switch (usb_pipetype (urb->pipe)) { ++	// case PIPE_CONTROL: ++	// case PIPE_BULK: ++	default: ++		if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) ++			return -ENOMEM; ++		return submit_async (ehci, ep, urb, &qtd_list, mem_flags); ++ ++	case PIPE_INTERRUPT: ++		if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) ++			return -ENOMEM; ++		return intr_submit (ehci, ep, urb, &qtd_list, mem_flags); ++ ++	case PIPE_ISOCHRONOUS: ++		if (urb->dev->speed == USB_SPEED_HIGH) ++			return itd_submit (ehci, urb, mem_flags); ++		else ++			return sitd_submit (ehci, urb, mem_flags); ++	} ++} ++ ++static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) ++{ ++	/* if we need to use IAA and it's busy, defer */ ++	if (qh->qh_state == QH_STATE_LINKED ++			&& ehci->reclaim ++			&& HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) { ++		struct ehci_qh		*last; ++ ++		for (last = ehci->reclaim; ++				last->reclaim; ++				last = last->reclaim) ++			continue; ++		qh->qh_state = QH_STATE_UNLINK_WAIT; ++		last->reclaim = qh; ++ ++	/* bypass IAA if the hc can't care */ ++	} else if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && ehci->reclaim) ++		end_unlink_async (ehci); ++ ++	/* something else might have unlinked the qh by now */ ++	if (qh->qh_state == QH_STATE_LINKED) ++		start_unlink_async (ehci, qh); ++} ++ ++/* remove from hardware lists ++ * completions normally happen asynchronously ++ */ ++ ++static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) ++{ ++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd); ++	struct ehci_qh		*qh; ++	unsigned long		flags; ++ ++	spin_lock_irqsave (&ehci->lock, flags); ++	switch (usb_pipetype (urb->pipe)) { ++	// case PIPE_CONTROL: ++	// case PIPE_BULK: ++	default: ++		qh = (struct ehci_qh *) urb->hcpriv; ++		if (!qh) ++			break; ++		unlink_async (ehci, qh); ++		break; ++ ++	case PIPE_INTERRUPT: ++		qh = (struct ehci_qh *) urb->hcpriv; ++		if (!qh) ++			break; ++		switch (qh->qh_state) { ++		case QH_STATE_LINKED: ++			intr_deschedule (ehci, qh); ++			/* FALL THROUGH */ ++		case QH_STATE_IDLE: ++			qh_completions (ehci, qh); ++			break; ++		default: ++			ehci_dbg (ehci, "bogus qh %p state %d\n", ++					qh, qh->qh_state); ++			goto done; ++		} ++ ++		/* reschedule QH iff another request is queued */ ++		if (!list_empty (&qh->qtd_list) ++				&& HC_IS_RUNNING (hcd->state)) { ++			int status; ++ ++			status = qh_schedule (ehci, qh); ++			spin_unlock_irqrestore (&ehci->lock, flags); ++ ++			if (status != 0) { ++				// shouldn't happen often, but ... ++				// FIXME kill those tds' urbs ++				err ("can't reschedule qh %p, err %d", ++					qh, status); ++			} ++			return status; ++		} ++		break; ++ ++	case PIPE_ISOCHRONOUS: ++		// itd or sitd ... ++ ++		// wait till next completion, do it then. ++		// completion irqs can wait up to 1024 msec, ++		break; ++	} ++done: ++	spin_unlock_irqrestore (&ehci->lock, flags); ++	return 0; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++// bulk qh holds the data toggle ++ ++static void ++ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) ++{ ++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd); ++	unsigned long		flags; ++	struct ehci_qh		*qh, *tmp; ++ ++	/* ASSERT:  any requests/urbs are being unlinked */ ++	/* ASSERT:  nobody can be submitting urbs for this any more */ ++ ++rescan: ++	spin_lock_irqsave (&ehci->lock, flags); ++	qh = ep->hcpriv; ++	if (!qh) ++		goto done; ++ ++	/* endpoints can be iso streams.  for now, we don't ++	 * accelerate iso completions ... so spin a while. ++	 */ ++	if (qh->hw_info1 == 0) { ++		ehci_vdbg (ehci, "iso delay\n"); ++		goto idle_timeout; ++	} ++ ++	if (!HC_IS_RUNNING (hcd->state)) ++		qh->qh_state = QH_STATE_IDLE; ++	switch (qh->qh_state) { ++	case QH_STATE_LINKED: ++		for (tmp = ehci->async->qh_next.qh; ++				tmp && tmp != qh; ++				tmp = tmp->qh_next.qh) ++			continue; ++		/* periodic qh self-unlinks on empty */ ++		if (!tmp) ++			goto nogood; ++		unlink_async (ehci, qh); ++		/* FALL THROUGH */ ++	case QH_STATE_UNLINK:		/* wait for hw to finish? */ ++idle_timeout: ++		spin_unlock_irqrestore (&ehci->lock, flags); ++		schedule_timeout_uninterruptible(1); ++		goto rescan; ++	case QH_STATE_IDLE:		/* fully unlinked */ ++		if (list_empty (&qh->qtd_list)) { ++			qh_put (qh); ++			break; ++		} ++		/* else FALL THROUGH */ ++	default: ++nogood: ++		/* caller was supposed to have unlinked any requests; ++		 * that's not our job.  just leak this memory. ++		 */ ++		ehci_err (ehci, "qh %p (#%02x) state %d%s\n", ++			qh, ep->desc.bEndpointAddress, qh->qh_state, ++			list_empty (&qh->qtd_list) ? "" : "(has tds)"); ++		break; ++	} ++	ep->hcpriv = NULL; ++done: ++	spin_unlock_irqrestore (&ehci->lock, flags); ++	return; ++} ++ ++static int ehci_get_frame (struct usb_hcd *hcd) ++{ ++	struct ehci_hcd		*ehci = hcd_to_ehci (hcd); ++	return (ehci_readl(ehci, &ehci->regs->frame_index) >> 3) % ++		ehci->periodic_size; ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC ++ ++MODULE_DESCRIPTION (DRIVER_INFO); ++MODULE_AUTHOR (DRIVER_AUTHOR); ++MODULE_LICENSE ("GPL"); ++ ++#ifdef CONFIG_PCI ++#include "ehci-pci.c" ++#define	PCI_DRIVER		ehci_pci_driver ++#endif ++ ++#ifdef CONFIG_MPC834x ++#include "ehci-fsl.c" ++#define	PLATFORM_DRIVER		ehci_fsl_driver ++#endif ++ ++#ifdef CONFIG_SOC_AU1200 ++#include "ehci-au1xxx.c" ++#define	PLATFORM_DRIVER		ehci_hcd_au1xxx_driver ++#endif ++ ++#ifdef CONFIG_PPC_PS3 ++#include "ehci-ps3.c" ++#define	PS3_SYSTEM_BUS_DRIVER	ps3_ehci_sb_driver ++#endif ++ ++#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ ++    !defined(PS3_SYSTEM_BUS_DRIVER) ++#error "missing bus glue for ehci-hcd" ++#endif ++ ++static int __init ehci_hcd_init(void) ++{ ++	int retval = 0; ++ ++	pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", ++		 hcd_name, ++		 sizeof(struct ehci_qh), sizeof(struct ehci_qtd), ++		 sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); ++ ++#ifdef PLATFORM_DRIVER ++	retval = platform_driver_register(&PLATFORM_DRIVER); ++	if (retval < 0) ++		return retval; ++#endif ++ ++#ifdef PCI_DRIVER ++	retval = pci_register_driver(&PCI_DRIVER); ++	if (retval < 0) { ++#ifdef PLATFORM_DRIVER ++		platform_driver_unregister(&PLATFORM_DRIVER); ++#endif ++		return retval; ++	} ++#endif ++ ++#ifdef PS3_SYSTEM_BUS_DRIVER ++	if (firmware_has_feature(FW_FEATURE_PS3_LV1)) { ++		retval = ps3_system_bus_driver_register( ++				&PS3_SYSTEM_BUS_DRIVER); ++		if (retval < 0) { ++#ifdef PLATFORM_DRIVER ++			platform_driver_unregister(&PLATFORM_DRIVER); ++#endif ++#ifdef PCI_DRIVER ++			pci_unregister_driver(&PCI_DRIVER); ++#endif ++			return retval; ++		} ++	} ++#endif ++ ++	return retval; ++} ++module_init(ehci_hcd_init); ++ ++static void __exit ehci_hcd_cleanup(void) ++{ ++#ifdef PLATFORM_DRIVER ++	platform_driver_unregister(&PLATFORM_DRIVER); ++#endif ++#ifdef PCI_DRIVER ++	pci_unregister_driver(&PCI_DRIVER); ++#endif ++#ifdef PS3_SYSTEM_BUS_DRIVER ++	if (firmware_has_feature(FW_FEATURE_PS3_LV1)) ++		ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); ++#endif ++} ++module_exit(ehci_hcd_cleanup); ++ +diff -Nur linux-2.6.21.1/drivers/usb/host/ehci.h.orig linux-2.6.21.1-owrt/drivers/usb/host/ehci.h.orig +--- linux-2.6.21.1/drivers/usb/host/ehci.h.orig	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.1-owrt/drivers/usb/host/ehci.h.orig	2007-04-27 23:49:26.000000000 +0200 +@@ -0,0 +1,707 @@ ++/* ++ * Copyright (c) 2001-2002 by David Brownell ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License ++ * for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software Foundation, ++ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifndef __LINUX_EHCI_HCD_H ++#define __LINUX_EHCI_HCD_H ++ ++/* definitions used for the EHCI driver */ ++ ++/* statistics can be kept for for tuning/monitoring */ ++struct ehci_stats { ++	/* irq usage */ ++	unsigned long		normal; ++	unsigned long		error; ++	unsigned long		reclaim; ++	unsigned long		lost_iaa; ++ ++	/* termination of urbs from core */ ++	unsigned long		complete; ++	unsigned long		unlink; ++}; ++ ++/* ehci_hcd->lock guards shared data against other CPUs: ++ *   ehci_hcd:	async, reclaim, periodic (and shadow), ... ++ *   usb_host_endpoint: hcpriv ++ *   ehci_qh:	qh_next, qtd_list ++ *   ehci_qtd:	qtd_list ++ * ++ * Also, hold this lock when talking to HC registers or ++ * when updating hw_* fields in shared qh/qtd/... structures. ++ */ ++ ++#define	EHCI_MAX_ROOT_PORTS	15		/* see HCS_N_PORTS */ ++ ++struct ehci_hcd {			/* one per controller */ ++	/* glue to PCI and HCD framework */ ++	struct ehci_caps __iomem *caps; ++	struct ehci_regs __iomem *regs; ++	struct ehci_dbg_port __iomem *debug; ++ ++	__u32			hcs_params;	/* cached register copy */ ++	spinlock_t		lock; ++ ++	/* async schedule support */ ++	struct ehci_qh		*async; ++	struct ehci_qh		*reclaim; ++	unsigned		reclaim_ready : 1; ++	unsigned		scanning : 1; ++ ++	/* periodic schedule support */ ++#define	DEFAULT_I_TDPS		1024		/* some HCs can do less */ ++	unsigned		periodic_size; ++	__le32			*periodic;	/* hw periodic table */ ++	dma_addr_t		periodic_dma; ++	unsigned		i_thresh;	/* uframes HC might cache */ ++ ++	union ehci_shadow	*pshadow;	/* mirror hw periodic table */ ++	int			next_uframe;	/* scan periodic, start here */ ++	unsigned		periodic_sched;	/* periodic activity count */ ++ ++	/* per root hub port */ ++	unsigned long		reset_done [EHCI_MAX_ROOT_PORTS]; ++	/* bit vectors (one bit per port) */ ++	unsigned long		bus_suspended;		/* which ports were ++			already suspended at the start of a bus suspend */ ++	unsigned long		companion_ports;	/* which ports are ++			dedicated to the companion controller */ ++ ++	/* per-HC memory pools (could be per-bus, but ...) */ ++	struct dma_pool		*qh_pool;	/* qh per active urb */ ++	struct dma_pool		*qtd_pool;	/* one or more per qh */ ++	struct dma_pool		*itd_pool;	/* itd per iso urb */ ++	struct dma_pool		*sitd_pool;	/* sitd per split iso urb */ ++ ++	struct timer_list	watchdog; ++	unsigned long		actions; ++	unsigned		stamp; ++	unsigned long		next_statechange; ++	u32			command; ++ ++	/* SILICON QUIRKS */ ++	unsigned		is_tdi_rh_tt:1;	/* TDI roothub with TT */ ++	unsigned		no_selective_suspend:1; ++	unsigned		has_fsl_port_bug:1; /* FreeScale */ ++	unsigned		big_endian_mmio:1; ++ ++	u8			sbrn;		/* packed release number */ ++ ++	/* irq statistics */ ++#ifdef EHCI_STATS ++	struct ehci_stats	stats; ++#	define COUNT(x) do { (x)++; } while (0) ++#else ++#	define COUNT(x) do {} while (0) ++#endif ++}; ++ ++/* convert between an HCD pointer and the corresponding EHCI_HCD */ ++static inline struct ehci_hcd *hcd_to_ehci (struct usb_hcd *hcd) ++{ ++	return (struct ehci_hcd *) (hcd->hcd_priv); ++} ++static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci) ++{ ++	return container_of ((void *) ehci, struct usb_hcd, hcd_priv); ++} ++ ++ ++enum ehci_timer_action { ++	TIMER_IO_WATCHDOG, ++	TIMER_IAA_WATCHDOG, ++	TIMER_ASYNC_SHRINK, ++	TIMER_ASYNC_OFF, ++}; ++ ++static inline void ++timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action) ++{ ++	clear_bit (action, &ehci->actions); ++} ++ ++static inline void ++timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) ++{ ++	if (!test_and_set_bit (action, &ehci->actions)) { ++		unsigned long t; ++ ++		switch (action) { ++		case TIMER_IAA_WATCHDOG: ++			t = EHCI_IAA_JIFFIES; ++			break; ++		case TIMER_IO_WATCHDOG: ++			t = EHCI_IO_JIFFIES; ++			break; ++		case TIMER_ASYNC_OFF: ++			t = EHCI_ASYNC_JIFFIES; ++			break; ++		// case TIMER_ASYNC_SHRINK: ++		default: ++			t = EHCI_SHRINK_JIFFIES; ++			break; ++		} ++		t += jiffies; ++		// all timings except IAA watchdog can be overridden. ++		// async queue SHRINK often precedes IAA.  while it's ready ++		// to go OFF neither can matter, and afterwards the IO ++		// watchdog stops unless there's still periodic traffic. ++		if (action != TIMER_IAA_WATCHDOG ++				&& t > ehci->watchdog.expires ++				&& timer_pending (&ehci->watchdog)) ++			return; ++		mod_timer (&ehci->watchdog, t); ++	} ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */ ++ ++/* Section 2.2 Host Controller Capability Registers */ ++struct ehci_caps { ++	/* these fields are specified as 8 and 16 bit registers, ++	 * but some hosts can't perform 8 or 16 bit PCI accesses. ++	 */ ++	u32		hc_capbase; ++#define HC_LENGTH(p)		(((p)>>00)&0x00ff)	/* bits 7:0 */ ++#define HC_VERSION(p)		(((p)>>16)&0xffff)	/* bits 31:16 */ ++	u32		hcs_params;     /* HCSPARAMS - offset 0x4 */ ++#define HCS_DEBUG_PORT(p)	(((p)>>20)&0xf)	/* bits 23:20, debug port? */ ++#define HCS_INDICATOR(p)	((p)&(1 << 16))	/* true: has port indicators */ ++#define HCS_N_CC(p)		(((p)>>12)&0xf)	/* bits 15:12, #companion HCs */ ++#define HCS_N_PCC(p)		(((p)>>8)&0xf)	/* bits 11:8, ports per CC */ ++#define HCS_PORTROUTED(p)	((p)&(1 << 7))	/* true: port routing */ ++#define HCS_PPC(p)		((p)&(1 << 4))	/* true: port power control */ ++#define HCS_N_PORTS(p)		(((p)>>0)&0xf)	/* bits 3:0, ports on HC */ ++ ++	u32		hcc_params;      /* HCCPARAMS - offset 0x8 */ ++#define HCC_EXT_CAPS(p)		(((p)>>8)&0xff)	/* for pci extended caps */ ++#define HCC_ISOC_CACHE(p)       ((p)&(1 << 7))  /* true: can cache isoc frame */ ++#define HCC_ISOC_THRES(p)       (((p)>>4)&0x7)  /* bits 6:4, uframes cached */ ++#define HCC_CANPARK(p)		((p)&(1 << 2))  /* true: can park on async qh */ ++#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1))  /* true: periodic_size changes*/ ++#define HCC_64BIT_ADDR(p)       ((p)&(1))       /* true: can use 64-bit addr */ ++	u8		portroute [8];	 /* nibbles for routing - offset 0xC */ ++} __attribute__ ((packed)); ++ ++ ++/* Section 2.3 Host Controller Operational Registers */ ++struct ehci_regs { ++ ++	/* USBCMD: offset 0x00 */ ++	u32		command; ++/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */ ++#define CMD_PARK	(1<<11)		/* enable "park" on async qh */ ++#define CMD_PARK_CNT(c)	(((c)>>8)&3)	/* how many transfers to park for */ ++#define CMD_LRESET	(1<<7)		/* partial reset (no ports, etc) */ ++#define CMD_IAAD	(1<<6)		/* "doorbell" interrupt async advance */ ++#define CMD_ASE		(1<<5)		/* async schedule enable */ ++#define CMD_PSE		(1<<4)		/* periodic schedule enable */ ++/* 3:2 is periodic frame list size */ ++#define CMD_RESET	(1<<1)		/* reset HC not bus */ ++#define CMD_RUN		(1<<0)		/* start/stop HC */ ++ ++	/* USBSTS: offset 0x04 */ ++	u32		status; ++#define STS_ASS		(1<<15)		/* Async Schedule Status */ ++#define STS_PSS		(1<<14)		/* Periodic Schedule Status */ ++#define STS_RECL	(1<<13)		/* Reclamation */ ++#define STS_HALT	(1<<12)		/* Not running (any reason) */ ++/* some bits reserved */ ++	/* these STS_* flags are also intr_enable bits (USBINTR) */ ++#define STS_IAA		(1<<5)		/* Interrupted on async advance */ ++#define STS_FATAL	(1<<4)		/* such as some PCI access errors */ ++#define STS_FLR		(1<<3)		/* frame list rolled over */ ++#define STS_PCD		(1<<2)		/* port change detect */ ++#define STS_ERR		(1<<1)		/* "error" completion (overflow, ...) */ ++#define STS_INT		(1<<0)		/* "normal" completion (short, ...) */ ++ ++	/* USBINTR: offset 0x08 */ ++	u32		intr_enable; ++ ++	/* FRINDEX: offset 0x0C */ ++	u32		frame_index;	/* current microframe number */ ++	/* CTRLDSSEGMENT: offset 0x10 */ ++	u32		segment;	/* address bits 63:32 if needed */ ++	/* PERIODICLISTBASE: offset 0x14 */ ++	u32		frame_list;	/* points to periodic list */ ++	/* ASYNCLISTADDR: offset 0x18 */ ++	u32		async_next;	/* address of next async queue head */ ++ ++	u32		reserved [9]; ++ ++	/* CONFIGFLAG: offset 0x40 */ ++	u32		configured_flag; ++#define FLAG_CF		(1<<0)		/* true: we'll support "high speed" */ ++ ++	/* PORTSC: offset 0x44 */ ++	u32		port_status [0];	/* up to N_PORTS */ ++/* 31:23 reserved */ ++#define PORT_WKOC_E	(1<<22)		/* wake on overcurrent (enable) */ ++#define PORT_WKDISC_E	(1<<21)		/* wake on disconnect (enable) */ ++#define PORT_WKCONN_E	(1<<20)		/* wake on connect (enable) */ ++/* 19:16 for port testing */ ++#define PORT_LED_OFF	(0<<14) ++#define PORT_LED_AMBER	(1<<14) ++#define PORT_LED_GREEN	(2<<14) ++#define PORT_LED_MASK	(3<<14) ++#define PORT_OWNER	(1<<13)		/* true: companion hc owns this port */ ++#define PORT_POWER	(1<<12)		/* true: has power (see PPC) */ ++#define PORT_USB11(x) (((x)&(3<<10))==(1<<10))	/* USB 1.1 device */ ++/* 11:10 for detecting lowspeed devices (reset vs release ownership) */ ++/* 9 reserved */ ++#define PORT_RESET	(1<<8)		/* reset port */ ++#define PORT_SUSPEND	(1<<7)		/* suspend port */ ++#define PORT_RESUME	(1<<6)		/* resume it */ ++#define PORT_OCC	(1<<5)		/* over current change */ ++#define PORT_OC		(1<<4)		/* over current active */ ++#define PORT_PEC	(1<<3)		/* port enable change */ ++#define PORT_PE		(1<<2)		/* port enable */ ++#define PORT_CSC	(1<<1)		/* connect status change */ ++#define PORT_CONNECT	(1<<0)		/* device connected */ ++#define PORT_RWC_BITS   (PORT_CSC | PORT_PEC | PORT_OCC) ++} __attribute__ ((packed)); ++ ++/* Appendix C, Debug port ... intended for use with special "debug devices" ++ * that can help if there's no serial console.  (nonstandard enumeration.) ++ */ ++struct ehci_dbg_port { ++	u32	control; ++#define DBGP_OWNER	(1<<30) ++#define DBGP_ENABLED	(1<<28) ++#define DBGP_DONE	(1<<16) ++#define DBGP_INUSE	(1<<10) ++#define DBGP_ERRCODE(x)	(((x)>>7)&0x07) ++#	define DBGP_ERR_BAD	1 ++#	define DBGP_ERR_SIGNAL	2 ++#define DBGP_ERROR	(1<<6) ++#define DBGP_GO		(1<<5) ++#define DBGP_OUT	(1<<4) ++#define DBGP_LEN(x)	(((x)>>0)&0x0f) ++	u32	pids; ++#define DBGP_PID_GET(x)		(((x)>>16)&0xff) ++#define DBGP_PID_SET(data,tok)	(((data)<<8)|(tok)) ++	u32	data03; ++	u32	data47; ++	u32	address; ++#define DBGP_EPADDR(dev,ep)	(((dev)<<8)|(ep)) ++} __attribute__ ((packed)); ++ ++/*-------------------------------------------------------------------------*/ ++ ++#define	QTD_NEXT(dma)	cpu_to_le32((u32)dma) ++ ++/* ++ * EHCI Specification 0.95 Section 3.5 ++ * QTD: describe data transfer components (buffer, direction, ...) ++ * See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram". ++ * ++ * These are associated only with "QH" (Queue Head) structures, ++ * used with control, bulk, and interrupt transfers. ++ */ ++struct ehci_qtd { ++	/* first part defined by EHCI spec */ ++	__le32			hw_next;	  /* see EHCI 3.5.1 */ ++	__le32			hw_alt_next;      /* see EHCI 3.5.2 */ ++	__le32			hw_token;         /* see EHCI 3.5.3 */ ++#define	QTD_TOGGLE	(1 << 31)	/* data toggle */ ++#define	QTD_LENGTH(tok)	(((tok)>>16) & 0x7fff) ++#define	QTD_IOC		(1 << 15)	/* interrupt on complete */ ++#define	QTD_CERR(tok)	(((tok)>>10) & 0x3) ++#define	QTD_PID(tok)	(((tok)>>8) & 0x3) ++#define	QTD_STS_ACTIVE	(1 << 7)	/* HC may execute this */ ++#define	QTD_STS_HALT	(1 << 6)	/* halted on error */ ++#define	QTD_STS_DBE	(1 << 5)	/* data buffer error (in HC) */ ++#define	QTD_STS_BABBLE	(1 << 4)	/* device was babbling (qtd halted) */ ++#define	QTD_STS_XACT	(1 << 3)	/* device gave illegal response */ ++#define	QTD_STS_MMF	(1 << 2)	/* incomplete split transaction */ ++#define	QTD_STS_STS	(1 << 1)	/* split transaction state */ ++#define	QTD_STS_PING	(1 << 0)	/* issue PING? */ ++	__le32			hw_buf [5];        /* see EHCI 3.5.4 */ ++	__le32			hw_buf_hi [5];        /* Appendix B */ ++ ++	/* the rest is HCD-private */ ++	dma_addr_t		qtd_dma;		/* qtd address */ ++	struct list_head	qtd_list;		/* sw qtd list */ ++	struct urb		*urb;			/* qtd's urb */ ++	size_t			length;			/* length of buffer */ ++} __attribute__ ((aligned (32))); ++ ++/* mask NakCnt+T in qh->hw_alt_next */ ++#define QTD_MASK __constant_cpu_to_le32 (~0x1f) ++ ++#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1) ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* type tag from {qh,itd,sitd,fstn}->hw_next */ ++#define Q_NEXT_TYPE(dma) ((dma) & __constant_cpu_to_le32 (3 << 1)) ++ ++/* values for that type tag */ ++#define Q_TYPE_ITD	__constant_cpu_to_le32 (0 << 1) ++#define Q_TYPE_QH	__constant_cpu_to_le32 (1 << 1) ++#define Q_TYPE_SITD	__constant_cpu_to_le32 (2 << 1) ++#define Q_TYPE_FSTN	__constant_cpu_to_le32 (3 << 1) ++ ++/* next async queue entry, or pointer to interrupt/periodic QH */ ++#define	QH_NEXT(dma)	(cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH) ++ ++/* for periodic/async schedules and qtd lists, mark end of list */ ++#define	EHCI_LIST_END	__constant_cpu_to_le32(1) /* "null pointer" to hw */ ++ ++/* ++ * Entries in periodic shadow table are pointers to one of four kinds ++ * of data structure.  That's dictated by the hardware; a type tag is ++ * encoded in the low bits of the hardware's periodic schedule.  Use ++ * Q_NEXT_TYPE to get the tag. ++ * ++ * For entries in the async schedule, the type tag always says "qh". ++ */ ++union ehci_shadow { ++	struct ehci_qh		*qh;		/* Q_TYPE_QH */ ++	struct ehci_itd		*itd;		/* Q_TYPE_ITD */ ++	struct ehci_sitd	*sitd;		/* Q_TYPE_SITD */ ++	struct ehci_fstn	*fstn;		/* Q_TYPE_FSTN */ ++	__le32			*hw_next;	/* (all types) */ ++	void			*ptr; ++}; ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * EHCI Specification 0.95 Section 3.6 ++ * QH: describes control/bulk/interrupt endpoints ++ * See Fig 3-7 "Queue Head Structure Layout". ++ * ++ * These appear in both the async and (for interrupt) periodic schedules. ++ */ ++ ++struct ehci_qh { ++	/* first part defined by EHCI spec */ ++	__le32			hw_next;	 /* see EHCI 3.6.1 */ ++	__le32			hw_info1;        /* see EHCI 3.6.2 */ ++#define	QH_HEAD		0x00008000 ++	__le32			hw_info2;        /* see EHCI 3.6.2 */ ++#define	QH_SMASK	0x000000ff ++#define	QH_CMASK	0x0000ff00 ++#define	QH_HUBADDR	0x007f0000 ++#define	QH_HUBPORT	0x3f800000 ++#define	QH_MULT		0xc0000000 ++	__le32			hw_current;	 /* qtd list - see EHCI 3.6.4 */ ++ ++	/* qtd overlay (hardware parts of a struct ehci_qtd) */ ++	__le32			hw_qtd_next; ++	__le32			hw_alt_next; ++	__le32			hw_token; ++	__le32			hw_buf [5]; ++	__le32			hw_buf_hi [5]; ++ ++	/* the rest is HCD-private */ ++	dma_addr_t		qh_dma;		/* address of qh */ ++	union ehci_shadow	qh_next;	/* ptr to qh; or periodic */ ++	struct list_head	qtd_list;	/* sw qtd list */ ++	struct ehci_qtd		*dummy; ++	struct ehci_qh		*reclaim;	/* next to reclaim */ ++ ++	struct ehci_hcd		*ehci; ++	struct kref		kref; ++	unsigned		stamp; ++ ++	u8			qh_state; ++#define	QH_STATE_LINKED		1		/* HC sees this */ ++#define	QH_STATE_UNLINK		2		/* HC may still see this */ ++#define	QH_STATE_IDLE		3		/* HC doesn't see this */ ++#define	QH_STATE_UNLINK_WAIT	4		/* LINKED and on reclaim q */ ++#define	QH_STATE_COMPLETING	5		/* don't touch token.HALT */ ++ ++	/* periodic schedule info */ ++	u8			usecs;		/* intr bandwidth */ ++	u8			gap_uf;		/* uframes split/csplit gap */ ++	u8			c_usecs;	/* ... split completion bw */ ++	u16			tt_usecs;	/* tt downstream bandwidth */ ++	unsigned short		period;		/* polling interval */ ++	unsigned short		start;		/* where polling starts */ ++#define NO_FRAME ((unsigned short)~0)			/* pick new start */ ++	struct usb_device	*dev;		/* access to TT */ ++} __attribute__ ((aligned (32))); ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* description of one iso transaction (up to 3 KB data if highspeed) */ ++struct ehci_iso_packet { ++	/* These will be copied to iTD when scheduling */ ++	u64			bufp;		/* itd->hw_bufp{,_hi}[pg] |= */ ++	__le32			transaction;	/* itd->hw_transaction[i] |= */ ++	u8			cross;		/* buf crosses pages */ ++	/* for full speed OUT splits */ ++	u32			buf1; ++}; ++ ++/* temporary schedule data for packets from iso urbs (both speeds) ++ * each packet is one logical usb transaction to the device (not TT), ++ * beginning at stream->next_uframe ++ */ ++struct ehci_iso_sched { ++	struct list_head	td_list; ++	unsigned		span; ++	struct ehci_iso_packet	packet [0]; ++}; ++ ++/* ++ * ehci_iso_stream - groups all (s)itds for this endpoint. ++ * acts like a qh would, if EHCI had them for ISO. ++ */ ++struct ehci_iso_stream { ++	/* first two fields match QH, but info1 == 0 */ ++	__le32			hw_next; ++	__le32			hw_info1; ++ ++	u32			refcount; ++	u8			bEndpointAddress; ++	u8			highspeed; ++	u16			depth;		/* depth in uframes */ ++	struct list_head	td_list;	/* queued itds/sitds */ ++	struct list_head	free_list;	/* list of unused itds/sitds */ ++	struct usb_device	*udev; ++	struct usb_host_endpoint *ep; ++ ++	/* output of (re)scheduling */ ++	unsigned long		start;		/* jiffies */ ++	unsigned long		rescheduled; ++	int			next_uframe; ++	__le32			splits; ++ ++	/* the rest is derived from the endpoint descriptor, ++	 * trusting urb->interval == f(epdesc->bInterval) and ++	 * including the extra info for hw_bufp[0..2] ++	 */ ++	u8			interval; ++	u8			usecs, c_usecs; ++	u16			tt_usecs; ++	u16			maxp; ++	u16			raw_mask; ++	unsigned		bandwidth; ++ ++	/* This is used to initialize iTD's hw_bufp fields */ ++	__le32			buf0; ++	__le32			buf1; ++	__le32			buf2; ++ ++	/* this is used to initialize sITD's tt info */ ++	__le32			address; ++}; ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * EHCI Specification 0.95 Section 3.3 ++ * Fig 3-4 "Isochronous Transaction Descriptor (iTD)" ++ * ++ * Schedule records for high speed iso xfers ++ */ ++struct ehci_itd { ++	/* first part defined by EHCI spec */ ++	__le32			hw_next;           /* see EHCI 3.3.1 */ ++	__le32			hw_transaction [8]; /* see EHCI 3.3.2 */ ++#define EHCI_ISOC_ACTIVE        (1<<31)        /* activate transfer this slot */ ++#define EHCI_ISOC_BUF_ERR       (1<<30)        /* Data buffer error */ ++#define EHCI_ISOC_BABBLE        (1<<29)        /* babble detected */ ++#define EHCI_ISOC_XACTERR       (1<<28)        /* XactErr - transaction error */ ++#define	EHCI_ITD_LENGTH(tok)	(((tok)>>16) & 0x0fff) ++#define	EHCI_ITD_IOC		(1 << 15)	/* interrupt on complete */ ++ ++#define ITD_ACTIVE	__constant_cpu_to_le32(EHCI_ISOC_ACTIVE) ++ ++	__le32			hw_bufp [7];	/* see EHCI 3.3.3 */ ++	__le32			hw_bufp_hi [7];	/* Appendix B */ ++ ++	/* the rest is HCD-private */ ++	dma_addr_t		itd_dma;	/* for this itd */ ++	union ehci_shadow	itd_next;	/* ptr to periodic q entry */ ++ ++	struct urb		*urb; ++	struct ehci_iso_stream	*stream;	/* endpoint's queue */ ++	struct list_head	itd_list;	/* list of stream's itds */ ++ ++	/* any/all hw_transactions here may be used by that urb */ ++	unsigned		frame;		/* where scheduled */ ++	unsigned		pg; ++	unsigned		index[8];	/* in urb->iso_frame_desc */ ++	u8			usecs[8]; ++} __attribute__ ((aligned (32))); ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * EHCI Specification 0.95 Section 3.4 ++ * siTD, aka split-transaction isochronous Transfer Descriptor ++ *       ... describe full speed iso xfers through TT in hubs ++ * see Figure 3-5 "Split-transaction Isochronous Transaction Descriptor (siTD) ++ */ ++struct ehci_sitd { ++	/* first part defined by EHCI spec */ ++	__le32			hw_next; ++/* uses bit field macros above - see EHCI 0.95 Table 3-8 */ ++	__le32			hw_fullspeed_ep;	/* EHCI table 3-9 */ ++	__le32			hw_uframe;		/* EHCI table 3-10 */ ++	__le32			hw_results;		/* EHCI table 3-11 */ ++#define	SITD_IOC	(1 << 31)	/* interrupt on completion */ ++#define	SITD_PAGE	(1 << 30)	/* buffer 0/1 */ ++#define	SITD_LENGTH(x)	(0x3ff & ((x)>>16)) ++#define	SITD_STS_ACTIVE	(1 << 7)	/* HC may execute this */ ++#define	SITD_STS_ERR	(1 << 6)	/* error from TT */ ++#define	SITD_STS_DBE	(1 << 5)	/* data buffer error (in HC) */ ++#define	SITD_STS_BABBLE	(1 << 4)	/* device was babbling */ ++#define	SITD_STS_XACT	(1 << 3)	/* illegal IN response */ ++#define	SITD_STS_MMF	(1 << 2)	/* incomplete split transaction */ ++#define	SITD_STS_STS	(1 << 1)	/* split transaction state */ ++ ++#define SITD_ACTIVE	__constant_cpu_to_le32(SITD_STS_ACTIVE) ++ ++	__le32			hw_buf [2];		/* EHCI table 3-12 */ ++	__le32			hw_backpointer;		/* EHCI table 3-13 */ ++	__le32			hw_buf_hi [2];		/* Appendix B */ ++ ++	/* the rest is HCD-private */ ++	dma_addr_t		sitd_dma; ++	union ehci_shadow	sitd_next;	/* ptr to periodic q entry */ ++ ++	struct urb		*urb; ++	struct ehci_iso_stream	*stream;	/* endpoint's queue */ ++	struct list_head	sitd_list;	/* list of stream's sitds */ ++	unsigned		frame; ++	unsigned		index; ++} __attribute__ ((aligned (32))); ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* ++ * EHCI Specification 0.96 Section 3.7 ++ * Periodic Frame Span Traversal Node (FSTN) ++ * ++ * Manages split interrupt transactions (using TT) that span frame boundaries ++ * into uframes 0/1; see 4.12.2.2.  In those uframes, a "save place" FSTN ++ * makes the HC jump (back) to a QH to scan for fs/ls QH completions until ++ * it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work. ++ */ ++struct ehci_fstn { ++	__le32			hw_next;	/* any periodic q entry */ ++	__le32			hw_prev;	/* qh or EHCI_LIST_END */ ++ ++	/* the rest is HCD-private */ ++	dma_addr_t		fstn_dma; ++	union ehci_shadow	fstn_next;	/* ptr to periodic q entry */ ++} __attribute__ ((aligned (32))); ++ ++/*-------------------------------------------------------------------------*/ ++ ++#ifdef CONFIG_USB_EHCI_ROOT_HUB_TT ++ ++/* ++ * Some EHCI controllers have a Transaction Translator built into the ++ * root hub. This is a non-standard feature.  Each controller will need ++ * to add code to the following inline functions, and call them as ++ * needed (mostly in root hub code). ++ */ ++ ++#define	ehci_is_TDI(e)			((e)->is_tdi_rh_tt) ++ ++/* Returns the speed of a device attached to a port on the root hub. */ ++static inline unsigned int ++ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) ++{ ++	if (ehci_is_TDI(ehci)) { ++		switch ((portsc>>26)&3) { ++		case 0: ++			return 0; ++		case 1: ++			return (1<<USB_PORT_FEAT_LOWSPEED); ++		case 2: ++		default: ++			return (1<<USB_PORT_FEAT_HIGHSPEED); ++		} ++	} ++	return (1<<USB_PORT_FEAT_HIGHSPEED); ++} ++ ++#else ++ ++#define	ehci_is_TDI(e)			(0) ++ ++#define	ehci_port_speed(ehci, portsc)	(1<<USB_PORT_FEAT_HIGHSPEED) ++#endif ++ ++/*-------------------------------------------------------------------------*/ ++ ++#ifdef CONFIG_PPC_83xx ++/* Some Freescale processors have an erratum in which the TT ++ * port number in the queue head was 0..N-1 instead of 1..N. ++ */ ++#define	ehci_has_fsl_portno_bug(e)		((e)->has_fsl_port_bug) ++#else ++#define	ehci_has_fsl_portno_bug(e)		(0) ++#endif ++ ++/* ++ * While most USB host controllers implement their registers in ++ * little-endian format, a minority (celleb companion chip) implement ++ * them in big endian format. ++ * ++ * This attempts to support either format at compile time without a ++ * runtime penalty, or both formats with the additional overhead ++ * of checking a flag bit. ++ */ ++ ++#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO ++#define ehci_big_endian_mmio(e)		((e)->big_endian_mmio) ++#else ++#define ehci_big_endian_mmio(e)		0 ++#endif ++ ++static inline unsigned int ehci_readl (const struct ehci_hcd *ehci, ++				       __u32 __iomem * regs) ++{ ++#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO ++	return ehci_big_endian_mmio(ehci) ? ++		readl_be(regs) : ++		readl(regs); ++#else ++	return readl(regs); ++#endif ++} ++ ++static inline void ehci_writel (const struct ehci_hcd *ehci, ++				const unsigned int val, __u32 __iomem *regs) ++{ ++#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO ++	ehci_big_endian_mmio(ehci) ? ++		writel_be(val, regs) : ++		writel(val, regs); ++#else ++	writel(val, regs); ++#endif ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++#ifndef DEBUG ++#define STUB_DEBUG_FILES ++#endif	/* DEBUG */ ++ ++/*-------------------------------------------------------------------------*/ ++ ++#endif /* __LINUX_EHCI_HCD_H */ +diff -Nur linux-2.6.21.1/include/asm-mips/bootinfo.h linux-2.6.21.1-owrt/include/asm-mips/bootinfo.h +--- linux-2.6.21.1/include/asm-mips/bootinfo.h	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/include/asm-mips/bootinfo.h	2007-05-23 23:34:01.000000000 +0200 +@@ -213,6 +213,17 @@ + #define MACH_GROUP_NEC_EMMA2RH 25	/* NEC EMMA2RH (was 23)		*/ + #define  MACH_NEC_MARKEINS	0	/* NEC EMMA2RH Mark-eins	*/  +  +/* @@ -167,9 +8874,9 @@ diff -Nur linux-2.6.17/include/asm-mips/bootinfo.h linux-2.6.17-owrt/include/asm   #define CL_SIZE			COMMAND_LINE_SIZE   const char *get_system_type(void); -diff -Nur linux-2.6.17/include/asm-mips/cpu.h linux-2.6.17-owrt/include/asm-mips/cpu.h ---- linux-2.6.17/include/asm-mips/cpu.h	2006-06-18 03:49:35.000000000 +0200 -+++ linux-2.6.17-owrt/include/asm-mips/cpu.h	2006-06-18 12:45:56.000000000 +0200 +diff -Nur linux-2.6.21.1/include/asm-mips/cpu.h linux-2.6.21.1-owrt/include/asm-mips/cpu.h +--- linux-2.6.21.1/include/asm-mips/cpu.h	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/include/asm-mips/cpu.h	2007-05-23 23:34:01.000000000 +0200  @@ -54,6 +54,9 @@   #define PRID_IMP_R14000		0x0f00   #define PRID_IMP_R8000		0x1000 @@ -190,25 +8897,385 @@ diff -Nur linux-2.6.17/include/asm-mips/cpu.h linux-2.6.17-owrt/include/asm-mips   /*    * ISA Level encodings -diff -Nur linux-2.6.17/include/asm-mips/mach-generic/irq.h linux-2.6.17-owrt/include/asm-mips/mach-generic/irq.h ---- linux-2.6.17/include/asm-mips/mach-generic/irq.h	2006-06-18 03:49:35.000000000 +0200 -+++ linux-2.6.17-owrt/include/asm-mips/mach-generic/irq.h	2006-06-18 12:44:28.000000000 +0200 -@@ -8,6 +8,6 @@ - #ifndef __ASM_MACH_GENERIC_IRQ_H +diff -Nur linux-2.6.21.1/include/asm-mips/mach-generic/irq.h linux-2.6.21.1-owrt/include/asm-mips/mach-generic/irq.h +--- linux-2.6.21.1/include/asm-mips/mach-generic/irq.h	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/include/asm-mips/mach-generic/irq.h	2007-05-23 23:35:55.000000000 +0200 +@@ -9,7 +9,7 @@   #define __ASM_MACH_GENERIC_IRQ_H + #ifndef NR_IRQS  -#define NR_IRQS	128  +#define NR_IRQS	256 + #endif - #endif /* __ASM_MACH_GENERIC_IRQ_H */ -diff -Nur linux-2.6.17/include/linux/kernel.h linux-2.6.17-owrt/include/linux/kernel.h ---- linux-2.6.17/include/linux/kernel.h	2006-06-18 03:49:35.000000000 +0200 -+++ linux-2.6.17-owrt/include/linux/kernel.h	2006-06-18 12:44:28.000000000 +0200 -@@ -329,6 +329,7 @@ + #ifdef CONFIG_I8259 +diff -Nur linux-2.6.21.1/include/linux/kernel.h linux-2.6.21.1-owrt/include/linux/kernel.h +--- linux-2.6.21.1/include/linux/kernel.h	2007-04-27 23:49:26.000000000 +0200 ++++ linux-2.6.21.1-owrt/include/linux/kernel.h	2007-05-23 23:34:01.000000000 +0200 +@@ -334,6 +334,7 @@   };   /* Force a compilation error if condition is true */  +extern void BUILD_BUG(void);   #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) - /* Trap pasters of __FUNCTION__ at compile-time */ + /* Force a compilation error if condition is true, but also produce a +diff -Nur linux-2.6.21.1/include/linux/kernel.h.orig linux-2.6.21.1-owrt/include/linux/kernel.h.orig +--- linux-2.6.21.1/include/linux/kernel.h.orig	1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.1-owrt/include/linux/kernel.h.orig	2007-04-27 23:49:26.000000000 +0200 +@@ -0,0 +1,355 @@ ++#ifndef _LINUX_KERNEL_H ++#define _LINUX_KERNEL_H ++ ++/* ++ * 'kernel.h' contains some often-used function prototypes etc ++ */ ++ ++#ifdef __KERNEL__ ++ ++#include <stdarg.h> ++#include <linux/linkage.h> ++#include <linux/stddef.h> ++#include <linux/types.h> ++#include <linux/compiler.h> ++#include <linux/bitops.h> ++#include <linux/log2.h> ++#include <asm/byteorder.h> ++#include <asm/bug.h> ++ ++extern const char linux_banner[]; ++extern const char linux_proc_banner[]; ++ ++#define INT_MAX		((int)(~0U>>1)) ++#define INT_MIN		(-INT_MAX - 1) ++#define UINT_MAX	(~0U) ++#define LONG_MAX	((long)(~0UL>>1)) ++#define LONG_MIN	(-LONG_MAX - 1) ++#define ULONG_MAX	(~0UL) ++#define LLONG_MAX	((long long)(~0ULL>>1)) ++#define LLONG_MIN	(-LLONG_MAX - 1) ++#define ULLONG_MAX	(~0ULL) ++ ++#define STACK_MAGIC	0xdeadbeef ++ ++#define ALIGN(x,a)		__ALIGN_MASK(x,(typeof(x))(a)-1) ++#define __ALIGN_MASK(x,mask)	(((x)+(mask))&~(mask)) ++ ++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) ++#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) ++#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) ++#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) ++ ++#define	KERN_EMERG	"<0>"	/* system is unusable			*/ ++#define	KERN_ALERT	"<1>"	/* action must be taken immediately	*/ ++#define	KERN_CRIT	"<2>"	/* critical conditions			*/ ++#define	KERN_ERR	"<3>"	/* error conditions			*/ ++#define	KERN_WARNING	"<4>"	/* warning conditions			*/ ++#define	KERN_NOTICE	"<5>"	/* normal but significant condition	*/ ++#define	KERN_INFO	"<6>"	/* informational			*/ ++#define	KERN_DEBUG	"<7>"	/* debug-level messages			*/ ++ ++extern int console_printk[]; ++ ++#define console_loglevel (console_printk[0]) ++#define default_message_loglevel (console_printk[1]) ++#define minimum_console_loglevel (console_printk[2]) ++#define default_console_loglevel (console_printk[3]) ++ ++struct completion; ++struct pt_regs; ++struct user; ++ ++/** ++ * might_sleep - annotation for functions that can sleep ++ * ++ * this macro will print a stack trace if it is executed in an atomic ++ * context (spinlock, irq-handler, ...). ++ * ++ * This is a useful debugging help to be able to catch problems early and not ++ * be bitten later when the calling function happens to sleep when it is not ++ * supposed to. ++ */ ++#ifdef CONFIG_PREEMPT_VOLUNTARY ++extern int cond_resched(void); ++# define might_resched() cond_resched() ++#else ++# define might_resched() do { } while (0) ++#endif ++ ++#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP ++  void __might_sleep(char *file, int line); ++# define might_sleep() \ ++	do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0) ++#else ++# define might_sleep() do { might_resched(); } while (0) ++#endif ++ ++#define might_sleep_if(cond) do { if (cond) might_sleep(); } while (0) ++ ++#define abs(x) ({				\ ++		int __x = (x);			\ ++		(__x < 0) ? -__x : __x;		\ ++	}) ++ ++extern struct atomic_notifier_head panic_notifier_list; ++extern long (*panic_blink)(long time); ++NORET_TYPE void panic(const char * fmt, ...) ++	__attribute__ ((NORET_AND format (printf, 1, 2))); ++extern void oops_enter(void); ++extern void oops_exit(void); ++extern int oops_may_print(void); ++fastcall NORET_TYPE void do_exit(long error_code) ++	ATTRIB_NORET; ++NORET_TYPE void complete_and_exit(struct completion *, long) ++	ATTRIB_NORET; ++extern unsigned long simple_strtoul(const char *,char **,unsigned int); ++extern long simple_strtol(const char *,char **,unsigned int); ++extern unsigned long long simple_strtoull(const char *,char **,unsigned int); ++extern long long simple_strtoll(const char *,char **,unsigned int); ++extern int sprintf(char * buf, const char * fmt, ...) ++	__attribute__ ((format (printf, 2, 3))); ++extern int vsprintf(char *buf, const char *, va_list) ++	__attribute__ ((format (printf, 2, 0))); ++extern int snprintf(char * buf, size_t size, const char * fmt, ...) ++	__attribute__ ((format (printf, 3, 4))); ++extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) ++	__attribute__ ((format (printf, 3, 0))); ++extern int scnprintf(char * buf, size_t size, const char * fmt, ...) ++	__attribute__ ((format (printf, 3, 4))); ++extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) ++	__attribute__ ((format (printf, 3, 0))); ++extern char *kasprintf(gfp_t gfp, const char *fmt, ...) ++	__attribute__ ((format (printf, 2, 3))); ++ ++extern int sscanf(const char *, const char *, ...) ++	__attribute__ ((format (scanf, 2, 3))); ++extern int vsscanf(const char *, const char *, va_list) ++	__attribute__ ((format (scanf, 2, 0))); ++ ++extern int get_option(char **str, int *pint); ++extern char *get_options(const char *str, int nints, int *ints); ++extern unsigned long long memparse(char *ptr, char **retptr); ++ ++extern int core_kernel_text(unsigned long addr); ++extern int __kernel_text_address(unsigned long addr); ++extern int kernel_text_address(unsigned long addr); ++struct pid; ++extern struct pid *session_of_pgrp(struct pid *pgrp); ++ ++extern void dump_thread(struct pt_regs *regs, struct user *dump); ++ ++#ifdef CONFIG_PRINTK ++asmlinkage int vprintk(const char *fmt, va_list args) ++	__attribute__ ((format (printf, 1, 0))); ++asmlinkage int printk(const char * fmt, ...) ++	__attribute__ ((format (printf, 1, 2))); ++#else ++static inline int vprintk(const char *s, va_list args) ++	__attribute__ ((format (printf, 1, 0))); ++static inline int vprintk(const char *s, va_list args) { return 0; } ++static inline int printk(const char *s, ...) ++	__attribute__ ((format (printf, 1, 2))); ++static inline int printk(const char *s, ...) { return 0; } ++#endif ++ ++unsigned long int_sqrt(unsigned long); ++ ++extern int printk_ratelimit(void); ++extern int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst); ++extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, ++				unsigned int interval_msec); ++ ++static inline void console_silent(void) ++{ ++	console_loglevel = 0; ++} ++ ++static inline void console_verbose(void) ++{ ++	if (console_loglevel) ++		console_loglevel = 15; ++} ++ ++extern void bust_spinlocks(int yes); ++extern void wake_up_klogd(void); ++extern int oops_in_progress;		/* If set, an oops, panic(), BUG() or die() is in progress */ ++extern int panic_timeout; ++extern int panic_on_oops; ++extern int panic_on_unrecovered_nmi; ++extern int tainted; ++extern const char *print_tainted(void); ++extern void add_taint(unsigned); ++ ++/* Values used for system_state */ ++extern enum system_states { ++	SYSTEM_BOOTING, ++	SYSTEM_RUNNING, ++	SYSTEM_HALT, ++	SYSTEM_POWER_OFF, ++	SYSTEM_RESTART, ++	SYSTEM_SUSPEND_DISK, ++} system_state; ++ ++#define TAINT_PROPRIETARY_MODULE	(1<<0) ++#define TAINT_FORCED_MODULE		(1<<1) ++#define TAINT_UNSAFE_SMP		(1<<2) ++#define TAINT_FORCED_RMMOD		(1<<3) ++#define TAINT_MACHINE_CHECK		(1<<4) ++#define TAINT_BAD_PAGE			(1<<5) ++#define TAINT_USER			(1<<6) ++ ++extern void dump_stack(void); ++ ++#ifdef DEBUG ++/* If you are writing a driver, please use dev_dbg instead */ ++#define pr_debug(fmt,arg...) \ ++	printk(KERN_DEBUG fmt,##arg) ++#else ++static inline int __attribute__ ((format (printf, 1, 2))) pr_debug(const char * fmt, ...) ++{ ++	return 0; ++} ++#endif ++ ++#define pr_info(fmt,arg...) \ ++	printk(KERN_INFO fmt,##arg) ++ ++/* ++ *      Display an IP address in readable format. ++ */ ++ ++#define NIPQUAD(addr) \ ++	((unsigned char *)&addr)[0], \ ++	((unsigned char *)&addr)[1], \ ++	((unsigned char *)&addr)[2], \ ++	((unsigned char *)&addr)[3] ++#define NIPQUAD_FMT "%u.%u.%u.%u" ++ ++#define NIP6(addr) \ ++	ntohs((addr).s6_addr16[0]), \ ++	ntohs((addr).s6_addr16[1]), \ ++	ntohs((addr).s6_addr16[2]), \ ++	ntohs((addr).s6_addr16[3]), \ ++	ntohs((addr).s6_addr16[4]), \ ++	ntohs((addr).s6_addr16[5]), \ ++	ntohs((addr).s6_addr16[6]), \ ++	ntohs((addr).s6_addr16[7]) ++#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" ++#define NIP6_SEQFMT "%04x%04x%04x%04x%04x%04x%04x%04x" ++ ++#if defined(__LITTLE_ENDIAN) ++#define HIPQUAD(addr) \ ++	((unsigned char *)&addr)[3], \ ++	((unsigned char *)&addr)[2], \ ++	((unsigned char *)&addr)[1], \ ++	((unsigned char *)&addr)[0] ++#elif defined(__BIG_ENDIAN) ++#define HIPQUAD	NIPQUAD ++#else ++#error "Please fix asm/byteorder.h" ++#endif /* __LITTLE_ENDIAN */ ++ ++/* ++ * min()/max() macros that also do ++ * strict type-checking.. See the ++ * "unnecessary" pointer comparison. ++ */ ++#define min(x,y) ({ \ ++	typeof(x) _x = (x);	\ ++	typeof(y) _y = (y);	\ ++	(void) (&_x == &_y);		\ ++	_x < _y ? _x : _y; }) ++ ++#define max(x,y) ({ \ ++	typeof(x) _x = (x);	\ ++	typeof(y) _y = (y);	\ ++	(void) (&_x == &_y);		\ ++	_x > _y ? _x : _y; }) ++ ++/* ++ * ..and if you can't take the strict ++ * types, you can specify one yourself. ++ * ++ * Or not use min/max at all, of course. ++ */ ++#define min_t(type,x,y) \ ++	({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) ++#define max_t(type,x,y) \ ++	({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) ++ ++ ++/** ++ * container_of - cast a member of a structure out to the containing structure ++ * @ptr:	the pointer to the member. ++ * @type:	the type of the container struct this is embedded in. ++ * @member:	the name of the member within the struct. ++ * ++ */ ++#define container_of(ptr, type, member) ({			\ ++        const typeof( ((type *)0)->member ) *__mptr = (ptr);	\ ++        (type *)( (char *)__mptr - offsetof(type,member) );}) ++ ++/* ++ * Check at compile time that something is of a particular type. ++ * Always evaluates to 1 so you may use it easily in comparisons. ++ */ ++#define typecheck(type,x) \ ++({	type __dummy; \ ++	typeof(x) __dummy2; \ ++	(void)(&__dummy == &__dummy2); \ ++	1; \ ++}) ++ ++/* ++ * Check at compile time that 'function' is a certain type, or is a pointer ++ * to that type (needs to use typedef for the function type.) ++ */ ++#define typecheck_fn(type,function) \ ++({	typeof(type) __tmp = function; \ ++	(void)__tmp; \ ++}) ++ ++struct sysinfo; ++extern int do_sysinfo(struct sysinfo *info); ++ ++#endif /* __KERNEL__ */ ++ ++#define SI_LOAD_SHIFT	16 ++struct sysinfo { ++	long uptime;			/* Seconds since boot */ ++	unsigned long loads[3];		/* 1, 5, and 15 minute load averages */ ++	unsigned long totalram;		/* Total usable main memory size */ ++	unsigned long freeram;		/* Available memory size */ ++	unsigned long sharedram;	/* Amount of shared memory */ ++	unsigned long bufferram;	/* Memory used by buffers */ ++	unsigned long totalswap;	/* Total swap space size */ ++	unsigned long freeswap;		/* swap space still available */ ++	unsigned short procs;		/* Number of current processes */ ++	unsigned short pad;		/* explicit padding for m68k */ ++	unsigned long totalhigh;	/* Total high memory size */ ++	unsigned long freehigh;		/* Available high memory size */ ++	unsigned int mem_unit;		/* Memory unit size in bytes */ ++	char _f[20-2*sizeof(long)-sizeof(int)];	/* Padding: libc5 uses this.. */ ++}; ++ ++/* Force a compilation error if condition is true */ ++#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) ++ ++/* Force a compilation error if condition is true, but also produce a ++   result (of value 0 and type size_t), so the expression can be used ++   e.g. in a structure initializer (or where-ever else comma expressions ++   aren't permitted). */ ++#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1) ++ ++/* Trap pasters of __FUNCTION__ at compile-time */ ++#define __FUNCTION__ (__func__) ++ ++/* This helps us to avoid #ifdef CONFIG_NUMA */ ++#ifdef CONFIG_NUMA ++#define NUMA_BUILD 1 ++#else ++#define NUMA_BUILD 0 ++#endif ++ ++#endif diff --git a/target/linux/generic-2.6/config-template b/target/linux/generic-2.6/config-template index 164048a8d..1c1d57077 100644 --- a/target/linux/generic-2.6/config-template +++ b/target/linux/generic-2.6/config-template @@ -1343,6 +1343,7 @@ CONFIG_USB_EZUSB=y  CONFIG_USB_KAWETH=m  # CONFIG_USB_KBD is not set  # CONFIG_USB_KBTAB is not set +# CONFIG_USB_KC2190 is not set  # CONFIG_USB_KEYSPAN_REMOTE is not set  # CONFIG_USB_LCD is not set  # CONFIG_USB_LD is not set @@ -1356,6 +1357,7 @@ CONFIG_USB_KAWETH=m  CONFIG_USB_NET_AX8817X=m  CONFIG_USB_NET_CDCETHER=m  CONFIG_USB_NET_CDC_SUBSET=m +CONFIG_USB_NET_DM9601=m  CONFIG_USB_NET_GL620A=m  CONFIG_USB_NET_MCS7830=m  CONFIG_USB_NET_NET1080=m @@ -1380,6 +1382,7 @@ CONFIG_USB_SERIAL_BELKIN=m  CONFIG_USB_SERIAL_CP2101=m  CONFIG_USB_SERIAL_CYBERJACK=m  CONFIG_USB_SERIAL_CYPRESS_M8=m +# CONFIG_USB_SERIAL_DEBUG is not set  CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m  CONFIG_USB_SERIAL_EDGEPORT=m  CONFIG_USB_SERIAL_EDGEPORT_TI=m | 
