diff -u --recursive --new-file v2.4.9/linux/Documentation/00-INDEX linux/Documentation/00-INDEX
--- v2.4.9/linux/Documentation/00-INDEX	Thu Feb  8 16:32:44 2001
+++ linux/Documentation/00-INDEX	Mon Aug 27 07:44:15 2001
@@ -5,6 +5,11 @@
 Please try and keep the descriptions small enough to fit on one line.
 							 Thanks -- Paul G.
 
+Following translations are available on the WWW:
+
+   - Japanese, maintained by the JF Project (JF@linux.or.jp), at
+     http://www.linux.or.jp/JF/
+
 00-INDEX
 	- this file.
 BUG-HUNTING
diff -u --recursive --new-file v2.4.9/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.4.9/linux/Documentation/Configure.help	Mon Aug 27 12:41:37 2001
+++ linux/Documentation/Configure.help	Mon Aug 27 08:56:31 2001
@@ -1746,6 +1746,36 @@
   similar) CPU, R4xx0 might be a safe bet.
   If the resulting Kernel does not work try to recompile with R3000.
 
+CPU type
+CONFIG_CPU_VR41XX
+  The options selects support for the NEC VR41xx series of processors.
+  Only choose this option if you have one of these processors as a
+  kernel built with this option will not run on any other type of
+  processor or vice versa.
+
+CPU feature configuration
+CONFIG_CPU_ADVANCED
+  Saying yes here allows you to select support for various features your
+  CPU may or may not have.  Most people should say N here.
+
+ll and sc instructions
+CONFIG_CPU_HAS_LLSC
+  Say Y here if your CPU has the ll and sc instructions.  Say Y here for
+  better performance, N if you don't know.  You must say Y here for
+  multiprocessor machines.
+
+lld and scd instructions
+CONFIG_CPU_HAS_LLDSCD
+  Say Y here if your CPU has the lld and scd instructions, the 64-bit
+  equivalents of ll and sc.  Say Y here for better performance, N if
+  you don't know.  You must say Y here for multiprocessor machines.
+
+Support for writebuffer flushing
+CONFIG_CPU_HAS_WB
+  Say N here for slightly better performance.  You must say Y here for
+  machines which require flushing of write buffers in software.  Saying
+  Y is the safe option; N may result in kernel malfunction and crashes.
+
 Support for large 64-bit configurations
 CONFIG_MIPS_INSANE_LARGE
   MIPS R10000 does support a 44 bit / 16TB address space as opposed to
@@ -11478,6 +11508,45 @@
   The module will be called pegasus.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
+CONFIG_USB_KAWETH
+  Say Y here if you want to use one of the following 10Mbps only
+  USB Ethernet adapters based on the KLSI KL5KUSB101B chipset:
+       3Com 3C19250
+       ADS USB-10BT
+       ATEN USB Ethernet
+       ASANTE USB To Ethernet Adapter
+       AOX Endpoints USB Ethernet
+       Correga K.K.
+       D-Link DSB-650C and DU-E10
+       Entrega / Portgear E45
+       I-O DATA USB-ET/T
+       Jaton USB Ethernet Device Adapter
+       Kingston Technology USB Ethernet Adapter
+       Linksys USB10T
+       Mobility USB-Ethernet Adapter
+        NetGear EA-101
+       Peracom Enet and Enet2
+       Portsmith Express Ethernet Adapter
+       Shark Pocket Adapter
+       SMC 2202USB
+       Sony Vaio port extender
+
+  This driver is likely to work with most 10Mbps only USB Ethernet
+  adapters, including some "no brand" devices. It does NOT work on
+  SmartBridges smartNIC or on Belkin F5U111 devices - you should use
+  the CATC NetMate driver for those. If you are not sure which one
+  you need, select both, and the correct one should be selected for
+  you.
+
+  This driver makes the adapter appear as a normal Ethernet interface,
+  typically on eth0, if it is the only ethernet device, or perhaps on
+  eth1, if you have a PCI or ISA ethernet card installed.
+
+  This code 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 kaweth.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
 USB CATC NetMate-based Ethernet device support
 CONFIG_USB_CATC
   Say Y if you want to use one of the following 10Mbps USB Ethernet
@@ -15753,6 +15822,14 @@
   several megabytes and requires a machine with more than 16 MB,
   better 32 MB RAM to avoid excessive linking time. This is only
   useful for kernel hackers. If unsure, say N.
+
+Run uncached
+CONFIG_MIPS_UNCACHED
+  If you say Y here there kernel will disable all CPU caches.  This will
+  reduce the system's performance dramatically but can help finding
+  otherwise hard to track bugs.  It can also useful if you're doing
+  hardware debugging with a logic analyzer and need to see all traffic
+  on the bus.
 
 Magic System Request Key support
 CONFIG_MAGIC_SYSRQ
diff -u --recursive --new-file v2.4.9/linux/Documentation/mips/pci/pci.README linux/Documentation/mips/pci/pci.README
--- v2.4.9/linux/Documentation/mips/pci/pci.README	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/mips/pci/pci.README	Mon Aug 27 08:56:31 2001
@@ -0,0 +1,67 @@
+
+Pete Popov, ppopov@pacbell.net
+07/11/2001
+
+This README briefly explains how to use the pci and pci_auto
+code in arch/mips/kernel.  The code was ported from PowerPC and
+modified slightly. It has been tested pretty well on PPC on some
+rather complex systems with multiple bridges and devices behind
+each bridge. However, at the time this README was written, the
+mips port was tested only on boards with a single pci bus and
+no P2P bridges.  It's very possible that on boards with P2P
+bridges some modifications have to be made. The code will 
+evolve, no doubt, but currently every single mips board
+is doing its own pcibios thing and it has become a big
+mess.  This generic pci code is meant to clean up the mips
+pci mess and make it easier to add pci support to new boards.
+
+arch/mips/kernel/pci_auto.c has the pci bus enumeration code.
+This code scans the pci bus(es) and assigns all of the resources.
+Thus, you don't need the boot code to that, and many boot codes
+don't do it correctly anyway.  To enable the pci_auto code, add
+
+define_bool CONFIG_PCI_AUTO y 
+
+inside the define for your board in arch/mips/config.in. 
+For example, the Galileo EV96100 board  looks like this:
+
+if [ "$CONFIG_MIPS_EV96100" = "y" ]; then
+	define_bool CONFIG_PCI y
+	define_bool CONFIG_MIPS_GT96100 y
+	define_bool CONFIG_NEW_PCI y
+	define_bool CONFIG_PCI_AUTO y
+	define_bool CONFIG_SWAP_IO_SPACE y
+fi 
+
+
+Next, if you want to use the arch/mips/kernel/pci code, which has the
+pcibios_init() function, add
+
+define_bool CONFIG_NEW_PCI y
+ 
+inside the define for your board. Again, the EV96100 example above
+show NEW_PCI turned on.
+
+Note that you can enable CONFIG_NEW_PCI code without enabling 
+CONFIG_PCI_AUTO. But you can't do the opposite because the pci_auto
+routines are called from pcibios_init(), which is part of the 
+CONFIG_NEW_PCI code.
+
+
+Now you need to add your files to hook in your pci configuration
+cycles.  Usually you'll need only a couple of files named something
+like pci_fixups.c and pci_ops.c.  You can copy the templates
+provided and fill in the code.
+
+The file pci_ops.c should contain the pci configuration cycles routines.
+It also has the mips_pci_channels[] array which contains the descriptors
+of each pci controller.
+
+The file pci_fixups.c contains a few routines to do interrupt fixups,
+resources fixups, and, if needed, pci bios fixups.
+
+Usually you'll put your pci_fixups.c file in your board specific directory, 
+since the functions in that file are board specific.  The functions in
+pci_ops.c, on the other hand, are usually pci controller specific so that
+file could be shared among a few different boards using the same
+pci controller.
diff -u --recursive --new-file v2.4.9/linux/MAINTAINERS linux/MAINTAINERS
--- v2.4.9/linux/MAINTAINERS	Mon Aug 27 12:41:37 2001
+++ linux/MAINTAINERS	Mon Aug 27 08:56:31 2001
@@ -689,8 +689,8 @@
 S:	Orphan
 
 IEEE 1394 OHCI DRIVER
-P:	Sebastien Rougeaux
-M:	sebastien.rougeaux@anu.edu.au
+P:	Ben Collins
+M:	bcollins@debian.org
 L:	linux1394-devel@lists.sourceforge.net
 S:	Maintained
 
@@ -902,9 +902,9 @@
 
 MIPS
 P:	Ralf Baechle
-M:	ralf@gnu.ai.mit.edu
-W:	http://lena.fnet.fr/
-L:	linux-mips@fnet.fr
+M:	ralf@gnu.org
+W:	http://oss.sgi.com/mips/mips-howto.html
+L:	linux-mips@oss.sgi.com
 S:	Maintained
 
 MISCELLANEOUS MCA-SUPPORT
@@ -1452,6 +1452,13 @@
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
+
+USB KAWASAKI LSI DRIVER
+P:      Brad Hards
+M:      bradh@frogmouth.net
+L:      linux-usb-users@lists.sourceforge.net
+L:      linux-usb-devel@lists.sourceforge.net
+S:      Maintained
 
 USB OHCI DRIVER
 P:	Roman Weissgaerber
diff -u --recursive --new-file v2.4.9/linux/Makefile linux/Makefile
--- v2.4.9/linux/Makefile	Mon Aug 27 12:41:37 2001
+++ linux/Makefile	Mon Aug 27 09:07:37 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 9
-EXTRAVERSION =
+SUBLEVEL = 10
+EXTRAVERSION =-pre1
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -u --recursive --new-file v2.4.9/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- v2.4.9/linux/arch/alpha/kernel/alpha_ksyms.c	Mon Aug 27 12:41:37 2001
+++ linux/arch/alpha/kernel/alpha_ksyms.c	Mon Aug 27 07:56:48 2001
@@ -77,6 +77,14 @@
 EXPORT_SYMBOL(_writeb);
 EXPORT_SYMBOL(_writew);
 EXPORT_SYMBOL(_writel);
+EXPORT_SYMBOL(___raw_readb); 
+EXPORT_SYMBOL(___raw_readw); 
+EXPORT_SYMBOL(___raw_readl); 
+EXPORT_SYMBOL(___raw_readq); 
+EXPORT_SYMBOL(___raw_writeb); 
+EXPORT_SYMBOL(___raw_writew); 
+EXPORT_SYMBOL(___raw_writel); 
+EXPORT_SYMBOL(___raw_writeq); 
 EXPORT_SYMBOL(_memcpy_fromio);
 EXPORT_SYMBOL(_memcpy_toio);
 EXPORT_SYMBOL(_memset_c_io);
diff -u --recursive --new-file v2.4.9/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.4.9/linux/arch/i386/defconfig	Mon Aug 27 12:41:39 2001
+++ linux/arch/i386/defconfig	Mon Aug 27 09:16:06 2001
@@ -741,6 +741,7 @@
 # CONFIG_USB_PLUSB is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
 # CONFIG_USB_NET1080 is not set
 
 #
diff -u --recursive --new-file v2.4.9/linux/drivers/atm/Makefile linux/drivers/atm/Makefile
--- v2.4.9/linux/drivers/atm/Makefile	Mon Mar 26 15:36:30 2001
+++ linux/drivers/atm/Makefile	Mon Aug 27 09:01:33 2001
@@ -25,6 +25,7 @@
 obj-$(CONFIG_ATM_AMBASSADOR) += ambassador.o
 obj-$(CONFIG_ATM_TCP) += atmtcp.o
 obj-$(CONFIG_ATM_IA) += iphase.o suni.o
+obj-$(CONFIG_ATM_FIRESTREAM) += firestream.o
 
 ifeq ($(CONFIG_ATM_FORE200E_PCA),y)
   FORE200E_FW_OBJS += fore200e_pca_fw.o
diff -u --recursive --new-file v2.4.9/linux/drivers/atm/firestream.c linux/drivers/atm/firestream.c
--- v2.4.9/linux/drivers/atm/firestream.c	Wed Apr 11 19:02:30 2001
+++ linux/drivers/atm/firestream.c	Mon Aug 27 09:01:33 2001
@@ -295,6 +295,7 @@
 
 
 static int fs_keystream = 0;
+static int fs_maxphy = 1;
 
 #ifdef DEBUG
 /* I didn't forget to set this to zero before shipping. Hit me with a stick 
@@ -308,6 +309,7 @@
 #ifdef DEBUG 
 MODULE_PARM(fs_debug, "i");
 #endif
+MODULE_PARM(fs_maxphy, "i");
 MODULE_PARM(loopback, "i");
 MODULE_PARM(num, "i");
 MODULE_PARM(fs_keystream, "i");
@@ -866,6 +868,7 @@
 	int bfp;
 	int to;
 	unsigned short tmc0;
+	int uaddr;
 
 	func_enter ();
 
@@ -908,6 +911,9 @@
 	txtp = &atm_vcc->qos.txtp;
 	rxtp = &atm_vcc->qos.rxtp;
 
+	/* XXX Use VPI? How many bits? Which bits? */
+	uaddr = atm_vcc->dev->number - dev->start_number;
+
 	if (!test_bit(ATM_VF_PARTIAL, &atm_vcc->flags)) {
 		if (IS_FS50(dev)) {
 			/* Increment the channel numer: take a free one next time.  */
@@ -1012,7 +1018,7 @@
 		tc->TMC[2] = 0; /* Unused */
 		tc->TMC[3] = 0; /* Unused */
     
-		tc->spec = 0;    /* UTOPIA address, UDF, HEC: Unused -> 0 */
+		tc->spec = uaddr << 16;  /* UTOPIA address, UDF, HEC: Unused -> 0 */
 		tc->rtag[0] = 0; /* What should I do with routing tags??? 
 				    -- Not used -- AS -- Thanks -- REW*/
 		tc->rtag[1] = 0;
@@ -1081,7 +1087,7 @@
 			submit_command (dev, &dev->hp_txq, 
 					QE_CMD_REG_WR | QE_CMD_IMM_INQ,
 					0x80 + vcc->channo,
-					(vpi << 16) | vci, 0 ); /* XXX -- Use defines. */
+					(uaddr << 28) | (vpi << 16) | vci, 0 ); /* XXX -- Use defines. */
 		}
 		submit_command (dev, &dev->hp_txq, 
 				QE_CMD_RX_EN | QE_CMD_IMM_INQ | vcc->channo,
@@ -1772,8 +1778,10 @@
 
 	if (IS_FS50 (dev)) {
 		write_fs (dev, RAS0, RAS0_DCD_XHLT);
-		dev->atm_dev->ci_range.vpi_bits = 12;
-		dev->atm_dev->ci_range.vci_bits = 16;
+		for (i=0;i<fs_maxphy;i++) {
+			dev->atm_dev[i]->ci_range.vpi_bits = 12;
+			dev->atm_dev[i]->ci_range.vci_bits = 16;
+		}
 		dev->nchannels = FS50_NR_CHANNELS;
 	} else {
 		write_fs (dev, RAS0, RAS0_DCD_XHLT 
@@ -1781,8 +1789,10 @@
 			  | (((1 << FS155_VCI_BITS) - 1) * RAS0_VCSEL));
 		/* We can chose the split arbitarily. We might be able to 
 		   support more. Whatever. This should do for now. */
-		dev->atm_dev->ci_range.vpi_bits = FS155_VPI_BITS;
-		dev->atm_dev->ci_range.vci_bits = FS155_VCI_BITS;
+		for (i=0;i<fs_maxphy;i++) {
+			dev->atm_dev[i]->ci_range.vpi_bits = FS155_VPI_BITS;
+			dev->atm_dev[i]->ci_range.vci_bits = FS155_VCI_BITS;
+		}
     
 		/* Address bits we can't use should be compared to 0. */
 		write_fs (dev, RAC, 0);
@@ -1817,9 +1827,14 @@
 	}
 	memset (dev->tx_inuse, 0, dev->nchannels / 8);
 
-	/* -- RAS1 : FS155 and 50 differ. Default (0) should be OK for both */
-	/* -- RAS2 : FS50 only: Default is OK. */
+	if (IS_FS50 (dev)) {
+		/* -- RAS1 : FS155 and 50 differ. Default (0) should be OK for FS155, FS50/multiphy needs the maxPHY set... */
+		write_fs (dev, RAS1, (fs_maxphy - 1) * RAS1_UTREG);
 
+		/* -- RAS2 : FS50 only: Default is OK. */
+		/* Enable selecting for Utopia address for multiphy configs. */
+		write_fs (dev, RAS2, RAS2_USEL);
+	}
 	/* DMAMODE, default should be OK. -- REW */
 	write_fs (dev, DMAMR, DMAMR_TX_MODE_FULL);
 
@@ -1888,7 +1903,8 @@
 	add_timer (&dev->timer);
 #endif
 
-	dev->atm_dev->dev_data = dev;
+	for (i=0;i<fs_maxphy;i++)
+		dev->atm_dev[i]->dev_data = dev;
   
 	func_exit ();
 	return 0;
@@ -1897,9 +1913,9 @@
 static int __init firestream_init_one (struct pci_dev *pci_dev,
 				       const struct pci_device_id *ent) 
 {
-	struct atm_dev *atm_dev;
 	struct fs_dev *fs_dev;
-	
+	int i;
+
 	if (pci_enable_device(pci_dev)) 
 		goto err_out;
 
@@ -1910,13 +1926,17 @@
 		goto err_out;
 
 	memset (fs_dev, 0, sizeof (struct fs_dev));
-  
-	atm_dev = atm_dev_register("fs", &ops, -1, NULL);
-	if (!atm_dev)
-		goto err_out_free_fs_dev;
-  
+
+	for (i=0;i<fs_maxphy;i++) {
+		fs_dev->atm_dev[i] = atm_dev_register("fs", &ops, -1, NULL);
+		if (!fs_dev->atm_dev[i])
+			goto err_out_free_atm_dev;
+	}
+	/* XXX if another device is registering atm devices at the same time
+	   we get confusion.  */
+	fs_dev->start_number = fs_dev->atm_dev[0]->number;
+
 	fs_dev->pci_dev = pci_dev;
-	fs_dev->atm_dev = atm_dev;
 	fs_dev->flags = ent->driver_data;
 
 	if (fs_init(fs_dev))
@@ -1927,7 +1947,8 @@
 	return 0;
 
  err_out_free_atm_dev:
-	atm_dev_deregister(atm_dev);
+	for (i--;i >= 0;i--)
+		atm_dev_deregister(fs_dev->atm_dev[i]);
  err_out_free_fs_dev:
 	kfree(fs_dev);
  err_out:
@@ -2002,7 +2023,9 @@
 		free_irq (dev->irq, dev);
 		del_timer (&dev->timer);
 
-		atm_dev_deregister(dev->atm_dev);
+		for (i=0;i<fs_maxphy;i++)
+			atm_dev_deregister(dev->atm_dev[i]);
+
 		free_queue (dev, &dev->hp_txq);
 		free_queue (dev, &dev->lp_txq);
 		free_queue (dev, &dev->tx_relq);
diff -u --recursive --new-file v2.4.9/linux/drivers/atm/firestream.h linux/drivers/atm/firestream.h
--- v2.4.9/linux/drivers/atm/firestream.h	Wed Apr 11 19:02:30 2001
+++ linux/drivers/atm/firestream.h	Mon Aug 27 09:01:33 2001
@@ -345,13 +345,15 @@
 #define CELLOSCONF_COST   (0x1 <<  0)
 /* Bits? */
 
-
 #define RAS0 0x1bc
 #define RAS0_DCD_XHLT (0x1 << 31)
 
 #define RAS0_VPSEL    (0x1 << 16)
 #define RAS0_VCSEL    (0x1 <<  0)
 
+#define RAS1 0x1c0
+#define RAS1_UTREG    (0x1 << 5)
+
 
 #define DMAMR 0x1cc
 #define DMAMR_TX_MODE_FULL (0x0 << 0)
@@ -360,6 +362,14 @@
 
 
 
+#define RAS2 0x280
+
+#define RAS2_NNI  (0x1 << 0)
+#define RAS2_USEL (0x1 << 1)
+#define RAS2_UBS  (0x1 << 2)
+
+
+
 struct fs_transmit_config {
 	u32 flags;
 	u32 atm_hdr;
@@ -456,6 +466,7 @@
 	int n;
 };
 
+#define MAX_PHY 0x20
 
 struct fs_dev {
 	struct fs_dev *next;		/* other FS devices */
@@ -463,8 +474,9 @@
 
 	unsigned char irq;		/* IRQ */
 	struct pci_dev *pci_dev;	/* PCI stuff */
-	struct atm_dev *atm_dev;
+	struct atm_dev *atm_dev[MAX_PHY];
 	struct timer_list timer;
+	int start_number; 
 
 	unsigned long hw_base;		/* mem base address */
 	unsigned long base;             /* Mapping of base address */
diff -u --recursive --new-file v2.4.9/linux/drivers/char/agp/agp.h linux/drivers/char/agp/agp.h
--- v2.4.9/linux/drivers/char/agp/agp.h	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/agp/agp.h	Mon Aug 27 07:40:33 2001
@@ -101,6 +101,7 @@
 	int num_aperture_sizes;
 	int num_of_masks;
 	int capndx;
+	int cant_use_aperture;
 
 	/* Links to driver specific functions */
 
diff -u --recursive --new-file v2.4.9/linux/drivers/char/agp/agpgart_be.c linux/drivers/char/agp/agpgart_be.c
--- v2.4.9/linux/drivers/char/agp/agpgart_be.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/agp/agpgart_be.c	Mon Aug 27 07:40:33 2001
@@ -305,6 +305,9 @@
 
 void agp_copy_info(agp_kern_info * info)
 {
+	unsigned long page_mask = 0;
+	int i;
+
 	memset(info, 0, sizeof(agp_kern_info));
 	if (agp_bridge.type == NOT_SUPPORTED) {
 		info->chipset = agp_bridge.type;
@@ -319,6 +322,12 @@
 	info->aper_size = agp_return_size();
 	info->max_memory = agp_bridge.max_memory_agp;
 	info->current_memory = atomic_read(&agp_bridge.current_memory_agp);
+	info->cant_use_aperture = agp_bridge.cant_use_aperture;
+
+	for(i = 0; i < agp_bridge.num_of_masks; i++)
+		page_mask |= agp_bridge.mask_memory(page_mask, i);
+
+	info->page_mask = ~page_mask;
 }
 
 /* End - Routine to copy over information structure */
@@ -1083,6 +1092,7 @@
 	agp_bridge.free_by_type = intel_i810_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 }
@@ -1275,6 +1285,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 	
@@ -1305,6 +1316,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 	
@@ -1335,6 +1347,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 	
@@ -1452,6 +1465,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 	
@@ -1563,6 +1577,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 }
@@ -1938,6 +1953,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 	
@@ -2181,6 +2197,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = ali_alloc_page;
 	agp_bridge.agp_destroy_page = ali_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	return 0;
 	
@@ -2766,6 +2783,7 @@
 	agp_bridge.free_by_type = agp_generic_free_by_type;
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
+	agp_bridge.cant_use_aperture = 0;
 
 	pci_read_config_dword(agp_bridge.dev,
 			      SVWRKS_APSIZE,
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/ati_pcigart.h linux/drivers/char/drm/ati_pcigart.h
--- v2.4.9/linux/drivers/char/drm/ati_pcigart.h	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/drm/ati_pcigart.h	Mon Aug 27 09:18:29 2001
@@ -72,8 +72,6 @@
 	int i;
 	DRM_DEBUG( "%s\n", __FUNCTION__ );
 
-	if ( !address ) return;
-
 	page = virt_to_page( address );
 
 	for ( i = 0 ; i <= ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
@@ -84,23 +82,40 @@
 	free_pages( address, ATI_PCIGART_TABLE_ORDER );
 }
 
-unsigned long DRM(ati_pcigart_init)( drm_device_t *dev )
+int DRM(ati_pcigart_init)( drm_device_t *dev,
+			   unsigned long *addr,
+			   dma_addr_t *bus_addr)
 {
 	drm_sg_mem_t *entry = dev->sg;
-	unsigned long address;
+	unsigned long address = 0;
 	unsigned long pages;
-	u32 *pci_gart, page_base;
-	int i, j;
+	u32 *pci_gart, page_base, bus_address = 0;
+	int i, j, ret = 0;
 
 	if ( !entry ) {
 		DRM_ERROR( "no scatter/gather memory!\n" );
-		return 0;
+		goto done;
 	}
 
 	address = DRM(ati_alloc_pcigart_table)();
 	if ( !address ) {
 		DRM_ERROR( "cannot allocate PCI GART page!\n" );
-		return 0;
+		goto done;
+	}
+
+	if ( !dev->pdev ) {
+		DRM_ERROR( "PCI device unknown!\n" );
+		goto done;
+	}
+
+	bus_address = pci_map_single(dev->pdev, (void *)address,
+				  ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+				  PCI_DMA_TODEVICE);
+	if (bus_address == 0) {
+		DRM_ERROR( "unable to map PCIGART pages!\n" );
+		DRM(ati_free_pcigart_table)( address );
+		address = 0;
+		goto done;
 	}
 
 	pci_gart = (u32 *)address;
@@ -111,28 +126,72 @@
 	memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
 
 	for ( i = 0 ; i < pages ; i++ ) {
-		page_base = page_to_bus( entry->pagelist[i] );
+		/* we need to support large memory configurations */
+		entry->busaddr[i] = pci_map_single(dev->pdev,
+					   page_address( entry->pagelist[i] ),
+					   PAGE_SIZE,
+					   PCI_DMA_TODEVICE);
+		if (entry->busaddr[i] == 0) {
+			DRM_ERROR( "unable to map PCIGART pages!\n" );
+			DRM(ati_pcigart_cleanup)( dev, address, bus_address );
+			address = 0;
+			bus_address = 0;
+			goto done;
+		}
+		page_base = (u32) entry->busaddr[i];
+
 		for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
 			*pci_gart++ = cpu_to_le32( page_base );
 			page_base += ATI_PCIGART_PAGE_SIZE;
 		}
 	}
 
+	ret = 1;
+
 #if __i386__
 	asm volatile ( "wbinvd" ::: "memory" );
 #else
 	mb();
 #endif
 
-	return address;
+done:
+	*addr = address;
+	*bus_addr = bus_address;
+	return ret;
 }
 
-int DRM(ati_pcigart_cleanup)( unsigned long address )
+int DRM(ati_pcigart_cleanup)( drm_device_t *dev,
+			      unsigned long addr,
+			      dma_addr_t bus_addr)
 {
+	drm_sg_mem_t *entry = dev->sg;
+	unsigned long pages;
+	int i;
 
-	if ( address ) {
-		DRM(ati_free_pcigart_table)( address );
+	/* we need to support large memory configurations */
+	if ( !entry ) {
+		DRM_ERROR( "no scatter/gather memory!\n" );
+		return 0;
+	}
+
+	if ( bus_addr ) {
+		pci_unmap_single(dev->pdev, bus_addr,
+				 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
+				 PCI_DMA_TODEVICE);
+
+		pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
+		        ? entry->pages : ATI_MAX_PCIGART_PAGES;
+
+		for ( i = 0 ; i < pages ; i++ ) {
+			if ( !entry->busaddr[i] ) break;
+			pci_unmap_single(dev->pdev, entry->busaddr[i],
+					 PAGE_SIZE, PCI_DMA_TODEVICE);
+		}
+	}
+
+	if ( addr ) {
+		DRM(ati_free_pcigart_table)( addr );
 	}
 
-	return 0;
+	return 1;
 }
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/drmP.h linux/drivers/char/drm/drmP.h
--- v2.4.9/linux/drivers/char/drm/drmP.h	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/drmP.h	Mon Aug 27 09:18:29 2001
@@ -76,6 +76,17 @@
 #include <asm/pgalloc.h>
 #include "drm.h"
 
+/* page_to_bus for earlier kernels, not optimal in all cases */
+#ifndef page_to_bus
+#define page_to_bus(page)	((unsigned int)(virt_to_bus(page_address(page))))
+#endif
+
+/* We just use virt_to_bus for pci_map_single on older kernels */
+#if LINUX_VERSION_CODE < 0x020400
+#define pci_map_single(hwdev, ptr, size, direction)	virt_to_bus(ptr)
+#define pci_unmap_single(hwdev, dma_addr, size, direction)
+#endif
+
 /* DRM template customization defaults
  */
 #ifndef __HAVE_AGP
@@ -616,6 +627,8 @@
 	int                acquired;
 	unsigned long      base;
    	int 		   agp_mtrr;
+	int		   cant_use_aperture;
+	unsigned long	   page_mask;
 } drm_agp_head_t;
 #endif
 
@@ -624,6 +637,7 @@
 	void            *virtual;
 	int             pages;
 	struct page     **pagelist;
+	dma_addr_t	*busaddr;
 } drm_sg_mem_t;
 
 typedef struct drm_sigdata {
@@ -714,6 +728,7 @@
 #if __REALLY_HAVE_AGP
 	drm_agp_head_t    *agp;
 #endif
+	struct pci_dev *pdev;
 #ifdef __alpha__
 #if LINUX_VERSION_CODE < 0x020403
 	struct pci_controler *hose;
@@ -1018,8 +1033,12 @@
 #endif
 
                                /* ATI PCIGART support (ati_pcigart.h) */
-extern unsigned long  DRM(ati_pcigart_init)(drm_device_t *dev);
-extern int            DRM(ati_pcigart_cleanup)(unsigned long address);
+extern int            DRM(ati_pcigart_init)(drm_device_t *dev,
+					    unsigned long *addr,
+					    dma_addr_t *bus_addr);
+extern int            DRM(ati_pcigart_cleanup)(drm_device_t *dev,
+					       unsigned long addr,
+					       dma_addr_t bus_addr);
 
 #endif /* __KERNEL__ */
 #endif
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/drm_agpsupport.h linux/drivers/char/drm/drm_agpsupport.h
--- v2.4.9/linux/drivers/char/drm/drm_agpsupport.h	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/drm_agpsupport.h	Mon Aug 27 09:18:29 2001
@@ -316,6 +316,14 @@
 
 		default:		head->chipset = "Unknown";       break;
 		}
+#if LINUX_VERSION_CODE <= 0x020408
+		head->cant_use_aperture = 0;
+		head->page_mask = ~(0xfff);
+#else
+		head->cant_use_aperture = head->agp_info.cant_use_aperture;
+		head->page_mask = head->agp_info.page_mask;
+#endif
+
 		DRM_INFO("AGP %d.%d on %s @ 0x%08lx %ZuMB\n",
 			 head->agp_info.version.major,
 			 head->agp_info.version.minor,
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/drm_ioctl.h linux/drivers/char/drm/drm_ioctl.h
--- v2.4.9/linux/drivers/char/drm/drm_ioctl.h	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/drm_ioctl.h	Mon Aug 27 09:18:29 2001
@@ -98,7 +98,6 @@
 	}
 	sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
 
-#ifdef __alpha__
 	do {
 		struct pci_dev *pci_dev;
                 int b, d, f;
@@ -114,10 +113,13 @@
                 if (*p) break;
  
                 pci_dev = pci_find_slot(b, PCI_DEVFN(d,f));
-                if (pci_dev)
-                        dev->hose = pci_dev->sysdata;
-        } while(0);
+                if (pci_dev) {
+			dev->pdev = pci_dev;
+#ifdef __alpha__
+			dev->hose = pci_dev->sysdata;
 #endif
+		}
+        } while(0);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/drm_scatter.h linux/drivers/char/drm/drm_scatter.h
--- v2.4.9/linux/drivers/char/drm/drm_scatter.h	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/drm/drm_scatter.h	Mon Aug 27 09:18:29 2001
@@ -47,12 +47,15 @@
 
 	vfree( entry->virtual );
 
+	DRM(free)( entry->busaddr,
+		   entry->pages * sizeof(*entry->busaddr),
+		   DRM_MEM_PAGES );
 	DRM(free)( entry->pagelist,
-		  entry->pages * sizeof(*entry->pagelist),
-		  DRM_MEM_PAGES );
+		   entry->pages * sizeof(*entry->pagelist),
+		   DRM_MEM_PAGES );
 	DRM(free)( entry,
-		  sizeof(*entry),
-		  DRM_MEM_SGLISTS );
+		   sizeof(*entry),
+		   DRM_MEM_SGLISTS );
 }
 
 int DRM(sg_alloc)( struct inode *inode, struct file *filp,
@@ -93,16 +96,31 @@
 		DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS );
 		return -ENOMEM;
 	}
-	memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
+
+	entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
+				     DRM_MEM_PAGES );
+	if ( !entry->busaddr ) {
+		DRM(free)( entry->pagelist,
+			   entry->pages * sizeof(*entry->pagelist),
+			   DRM_MEM_PAGES );
+		DRM(free)( entry,
+			   sizeof(*entry),
+			   DRM_MEM_SGLISTS );
+		return -ENOMEM;
+	}
+	memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
 
 	entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
 	if ( !entry->virtual ) {
+		DRM(free)( entry->busaddr,
+			   entry->pages * sizeof(*entry->busaddr),
+			   DRM_MEM_PAGES );
 		DRM(free)( entry->pagelist,
-			  entry->pages * sizeof(*entry->pagelist),
-			  DRM_MEM_PAGES );
+			   entry->pages * sizeof(*entry->pagelist),
+			   DRM_MEM_PAGES );
 		DRM(free)( entry,
-			  sizeof(*entry),
-			  DRM_MEM_SGLISTS );
+			   sizeof(*entry),
+			   DRM_MEM_SGLISTS );
 		return -ENOMEM;
 	}
 
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/drm_vm.h linux/drivers/char/drm/drm_vm.h
--- v2.4.9/linux/drivers/char/drm/drm_vm.h	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/drm/drm_vm.h	Mon Aug 27 09:18:29 2001
@@ -67,6 +67,70 @@
 			    int write_access)
 #endif
 {
+#if __REALLY_HAVE_AGP
+	drm_file_t *priv  = vma->vm_file->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_map_t *map    = NULL;
+	drm_map_list_t  *r_list;
+	struct list_head *list;
+
+	/*
+         * Find the right map
+         */
+
+	if(!dev->agp->cant_use_aperture) goto vm_nopage_error;
+
+	list_for_each(list, &dev->maplist->head) {
+		r_list = (drm_map_list_t *)list;
+		map = r_list->map;
+		if (!map) continue;
+		if (map->offset == VM_OFFSET(vma)) break;
+	}
+
+	if (map && map->type == _DRM_AGP) {
+		unsigned long offset = address - vma->vm_start;
+		unsigned long baddr = VM_OFFSET(vma) + offset;
+		struct drm_agp_mem *agpmem;
+		struct page *page;
+
+#if __alpha__
+		/*
+                 * Adjust to a bus-relative address
+                 */
+		baddr -= dev->hose->mem_space->start;
+#endif
+
+		/*
+                 * It's AGP memory - find the real physical page to map
+                 */
+		for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
+			if (agpmem->bound <= baddr &&
+			    agpmem->bound + agpmem->pages * PAGE_SIZE > baddr) 
+				break;
+		}
+
+		if (!agpmem) goto vm_nopage_error;
+
+		/*
+                 * Get the page, inc the use count, and return it
+                 */
+		offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
+		agpmem->memory->memory[offset] &= dev->agp->page_mask;
+		page = virt_to_page(__va(agpmem->memory->memory[offset]));
+		get_page(page);
+
+		DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx\n",
+			  baddr, __va(agpmem->memory->memory[offset]), offset);
+
+#if LINUX_VERSION_CODE < 0x020317
+		return page_address(page);
+#else
+		return page;
+#endif
+        }
+vm_nopage_error:
+#endif /* __REALLY_HAVE_AGP */
+
 	return NOPAGE_SIGBUS;		/* Disallow mremap */
 }
 
@@ -220,24 +284,27 @@
 	drm_file_t	 *priv	 = vma->vm_file->private_data;
 	drm_device_t	 *dev	 = priv->dev;
 	drm_device_dma_t *dma	 = dev->dma;
-	unsigned long	 physical;
 	unsigned long	 offset;
-	unsigned long	 page;
+	unsigned long	 page_nr;
+	struct page	 *page;
 
 	if (!dma)		   return NOPAGE_SIGBUS; /* Error */
 	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
 	if (!dma->pagelist)	   return NOPAGE_OOM ; /* Nothing allocated */
 
 	offset	 = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
-	page	 = offset >> PAGE_SHIFT;
-	physical = dma->pagelist[page] + (offset & (~PAGE_MASK));
-	atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
+	page_nr  = offset >> PAGE_SHIFT;
+	page = virt_to_page((dma->pagelist[page_nr] + 
+			     (offset & (~PAGE_MASK))));
 
-	DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
+	get_page(page);
+
+	DRM_DEBUG("0x%08lx (page %lu) => 0x%08x\n", address, page_nr, 
+		  page_to_bus(page));
 #if LINUX_VERSION_CODE < 0x020317
-	return physical;
+	return page_address(page);
 #else
-	return virt_to_page(physical);
+	return page;
 #endif
 }
 
@@ -274,10 +341,10 @@
 	map_offset = map->offset - dev->sg->handle;
 	page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
 	page = entry->pagelist[page_offset];
-	atomic_inc(&page->count);                       /* Dec. by kernel */
+	get_page(page);
 
 #if LINUX_VERSION_CODE < 0x020317
-	return (unsigned long)virt_to_phys(page->virtual);
+	return page_address(page);
 #else
 	return page;
 #endif
@@ -435,9 +502,20 @@
 	}
 
 	switch (map->type) {
+        case _DRM_AGP:
+#if defined(__alpha__)
+                /*
+                 * On Alpha we can't talk to bus dma address from the
+                 * CPU, so for memory of type DRM_AGP, we'll deal with
+                 * sorting out the real physical pages and mappings
+                 * in nopage()
+                 */
+                vma->vm_ops = &DRM(vm_ops);
+                break;
+#endif
+                /* fall through to _DRM_FRAME_BUFFER... */        
 	case _DRM_FRAME_BUFFER:
 	case _DRM_REGISTERS:
-	case _DRM_AGP:
 		if (VM_OFFSET(vma) >= __pa(high_memory)) {
 #if defined(__i386__)
 			if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/mga_drv.h linux/drivers/char/drm/mga_drv.h
--- v2.4.9/linux/drivers/char/drm/mga_drv.h	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/mga_drv.h	Mon Aug 27 07:40:33 2001
@@ -145,14 +145,28 @@
 #define mga_flush_write_combine()	mb()
 
 
-#define MGA_BASE( reg )		((u32)(dev_priv->mmio->handle))
+#define MGA_BASE( reg )		((unsigned long)(dev_priv->mmio->handle))
 #define MGA_ADDR( reg )		(MGA_BASE(reg) + reg)
 
 #define MGA_DEREF( reg )	*(volatile u32 *)MGA_ADDR( reg )
+#define MGA_DEREF8( reg )	*(volatile u8 *)MGA_ADDR( reg )
+
+#ifdef __alpha__
+#define MGA_READ( reg )		(_MGA_READ((u32 *)MGA_ADDR(reg)))
+#define MGA_WRITE( reg, val )	do { wmb(); MGA_DEREF( reg ) = val; } while (0)
+#define MGA_WRITE8( reg, val )  do { wmb(); MGA_DEREF8( reg ) = val; } while (0)
+
+static inline u32 _MGA_READ(u32 *addr)
+{
+	mb();
+	return *(volatile u32 *)addr;
+}
+
+#else
 #define MGA_READ( reg )		MGA_DEREF( reg )
 #define MGA_WRITE( reg, val )	do { MGA_DEREF( reg ) = val; } while (0)
-#define MGA_DEREF8( reg )	*(volatile u8 *)MGA_ADDR( reg )
 #define MGA_WRITE8( reg, val )  do { MGA_DEREF8( reg ) = val; } while (0)
+#endif
 
 #define DWGREG0 	0x1c00
 #define DWGREG0_END 	0x1dff
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/r128_cce.c linux/drivers/char/drm/r128_cce.c
--- v2.4.9/linux/drivers/char/drm/r128_cce.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/drm/r128_cce.c	Mon Aug 27 07:40:33 2001
@@ -351,11 +351,10 @@
 		page_ofs = tmp_ofs >> PAGE_SHIFT;
 
 		R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
-			    page_to_bus(entry->pagelist[page_ofs]));
-
-		DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
-			   page_to_bus(entry->pagelist[page_ofs]),
-			   entry->handle + tmp_ofs );
+     			    entry->busaddr[page_ofs]);
+		DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n",
+			   entry->busaddr[page_ofs],
+     			   entry->handle + tmp_ofs );
 	}
 
 	/* Set watermark control */
@@ -599,15 +598,14 @@
 		    dev_priv->sarea_priv->last_dispatch );
 
 	if ( dev_priv->is_pci ) {
-		dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
-		if ( !dev_priv->phys_pci_gart ) {
+		if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
+     					    &dev_priv->bus_pci_gart) ) {
 			DRM_ERROR( "failed to init PCI GART!\n" );
 			dev->dev_private = (void *)dev_priv;
 			r128_do_cleanup_cce( dev );
 			return -ENOMEM;
 		}
-		R128_WRITE( R128_PCI_GART_PAGE,
-			    virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
+		R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart );
 	}
 
 	r128_cce_init_ring_buffer( dev, dev_priv );
@@ -629,6 +627,11 @@
 			DRM_IOREMAPFREE( dev_priv->cce_ring );
 			DRM_IOREMAPFREE( dev_priv->ring_rptr );
 			DRM_IOREMAPFREE( dev_priv->buffers );
+		} else {
+			if (!DRM(ati_pcigart_cleanup)( dev,
+						dev_priv->phys_pci_gart,
+						dev_priv->bus_pci_gart ))
+				DRM_ERROR( "failed to cleanup PCI GART!\n" );
 		}
 
 		DRM(free)( dev->dev_private, sizeof(drm_r128_private_t),
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/r128_drv.h linux/drivers/char/drm/r128_drv.h
--- v2.4.9/linux/drivers/char/drm/r128_drv.h	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/r128_drv.h	Mon Aug 27 07:40:33 2001
@@ -72,6 +72,7 @@
 	int usec_timeout;
 	int is_pci;
 	unsigned long phys_pci_gart;
+	dma_addr_t bus_pci_gart;
 	unsigned long cce_buffers_offset;
 
 	atomic_t idle_count;
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/radeon_cp.c linux/drivers/char/drm/radeon_cp.c
--- v2.4.9/linux/drivers/char/drm/radeon_cp.c	Mon Aug 27 12:41:40 2001
+++ linux/drivers/char/drm/radeon_cp.c	Mon Aug 27 07:40:33 2001
@@ -624,10 +624,9 @@
 		page_ofs = tmp_ofs >> PAGE_SHIFT;
 
 		RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
-			      page_to_bus(entry->pagelist[page_ofs]));
-
+			     entry->busaddr[page_ofs]);
 		DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n",
-			   page_to_bus(entry->pagelist[page_ofs]),
+			   entry->busaddr[page_ofs],
 			   entry->handle + tmp_ofs );
 	}
 
@@ -929,8 +928,8 @@
 		      dev_priv->sarea_priv->last_clear );
 
 	if ( dev_priv->is_pci ) {
-		dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
-		if ( !dev_priv->phys_pci_gart ) {
+		if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
+					    &dev_priv->bus_pci_gart)) {
 			DRM_ERROR( "failed to init PCI GART!\n" );
 			dev->dev_private = (void *)dev_priv;
 			radeon_do_cleanup_cp(dev);
@@ -944,8 +943,7 @@
 
 		/* set PCI GART page-table base address
 		 */
-		RADEON_WRITE( RADEON_AIC_PT_BASE,
-			      virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
+		RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart );
 
 		/* set address range for PCI address translate
 		 */
@@ -990,6 +988,11 @@
 			DRM_IOREMAPFREE( dev_priv->cp_ring );
 			DRM_IOREMAPFREE( dev_priv->ring_rptr );
 			DRM_IOREMAPFREE( dev_priv->buffers );
+		} else {
+			if (!DRM(ati_pcigart_cleanup)( dev,
+						dev_priv->phys_pci_gart,
+						dev_priv->bus_pci_gart ))
+				DRM_ERROR( "failed to cleanup PCI GART!\n" );
 		}
 
 		DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/radeon_drv.h linux/drivers/char/drm/radeon_drv.h
--- v2.4.9/linux/drivers/char/drm/radeon_drv.h	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/radeon_drv.h	Mon Aug 27 07:40:33 2001
@@ -84,6 +84,7 @@
 	int usec_timeout;
 	int is_pci;
 	unsigned long phys_pci_gart;
+	dma_addr_t bus_pci_gart;
 
 	atomic_t idle_count;
 
diff -u --recursive --new-file v2.4.9/linux/drivers/char/drm/tdfx_drv.c linux/drivers/char/drm/tdfx_drv.c
--- v2.4.9/linux/drivers/char/drm/tdfx_drv.c	Sun Aug 12 13:27:59 2001
+++ linux/drivers/char/drm/tdfx_drv.c	Mon Aug 27 07:40:33 2001
@@ -44,13 +44,30 @@
 #define DRIVER_MINOR		0
 #define DRIVER_PATCHLEVEL	0
 
+#ifndef PCI_VENDOR_ID_3DFX
+#define PCI_VENDOR_ID_3DFX 0x121A
+#endif
 #ifndef PCI_DEVICE_ID_3DFX_VOODOO5
 #define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009
 #endif
+#ifndef PCI_DEVICE_ID_3DFX_VOODOO4
+#define PCI_DEVICE_ID_3DFX_VOODOO4 0x0007
+#endif
+#ifndef PCI_DEVICE_ID_3DFX_VOODOO3_3000 /* Voodoo3 3000 */
+#define PCI_DEVICE_ID_3DFX_VOODOO3_3000 0x0005
+#endif
+#ifndef PCI_DEVICE_ID_3DFX_VOODOO3_2000 /* Voodoo3 3000 */
+#define PCI_DEVICE_ID_3DFX_VOODOO3_2000 0x0004
+#endif
+#ifndef PCI_DEVICE_ID_3DFX_BANSHEE
+#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003
+#endif
 
 static drm_pci_list_t DRM(idlist)[] = {
 	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE },
-	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3 },
+	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3_2000 },
+	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3_3000 },
+	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO4 },
 	{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO5 },
 	{ 0, 0 }
 };
diff -u --recursive --new-file v2.4.9/linux/drivers/ide/via82cxxx.c linux/drivers/ide/via82cxxx.c
--- v2.4.9/linux/drivers/ide/via82cxxx.c	Mon Aug 27 12:41:41 2001
+++ linux/drivers/ide/via82cxxx.c	Mon Aug 27 07:48:29 2001
@@ -1,5 +1,5 @@
 /*
- * $Id: via82cxxx.c,v 3.23 2001/03/09 09:30:00 vojtech Exp $
+ * $Id: via82cxxx.c,v 3.26 2001/08/17 12:03:00 vojtech Exp $
  *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
@@ -88,7 +88,6 @@
 #define VIA_BAD_CLK66		0x020	/* 66 MHz clock doesn't work correctly */
 #define VIA_SET_FIFO		0x040	/* Needs to have FIFO split set */
 #define VIA_SET_THRESH		0x080	/* Needs to have FIFO thresholds set */
-#define VIA_BAD_PIO		0x100	/* Always uses 26 PCICLK/xfer regardles of PIO mode */
 
 /*
  * VIA SouthBridge chips.
@@ -101,11 +100,9 @@
 	unsigned char rev_max;
 	unsigned short flags;
 } via_isa_bridges[] = {
-#ifdef VIA_NEW_BRIDGES_TESTED
 	{ "vt8233",	PCI_DEVICE_ID_VIA_8233_0,   0x00, 0x2f, VIA_UDMA_100 },
-	{ "vt8231",	PCI_DEVICE_ID_VIA_8231,     0x00, 0x2f, VIA_UDMA_66 },
-#endif
-	{ "vt82c686b",	PCI_DEVICE_ID_VIA_82C686,   0x40, 0x4f, VIA_UDMA_100 | VIA_BAD_PIO },
+	{ "vt8231",	PCI_DEVICE_ID_VIA_8231,     0x00, 0x2f, VIA_UDMA_100 },
+	{ "vt82c686b",	PCI_DEVICE_ID_VIA_82C686,   0x40, 0x4f, VIA_UDMA_100 },
 	{ "vt82c686a",	PCI_DEVICE_ID_VIA_82C686,   0x10, 0x2f, VIA_UDMA_66 },
 	{ "vt82c686",	PCI_DEVICE_ID_VIA_82C686,   0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
 	{ "vt82c596b",	PCI_DEVICE_ID_VIA_82C596,   0x10, 0x2f, VIA_UDMA_66 },
@@ -154,7 +151,7 @@
 
 	via_print("----------VIA BusMastering IDE Configuration----------------");
 
-	via_print("Driver Version:                     3.23");
+	via_print("Driver Version:                     3.26");
 	via_print("South Bridge:                       VIA %s", via_config->name);
 
 	pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t);
@@ -220,8 +217,8 @@
 		switch (via_config->flags & VIA_UDMA) {
 			
 			case VIA_UDMA_100:
-				speed[i] = 2000 / udma[i];
-				cycle[i] = 10 * udma[i];
+				speed[i] = 60 * via_clock / udma[i];
+				cycle[i] = 333 / via_clock * udma[i];
 				break;
 
 			case VIA_UDMA_66:
@@ -301,7 +298,7 @@
 	switch (via_config->flags & VIA_UDMA) {
 		case VIA_UDMA_33:   UT = T;   break;
 		case VIA_UDMA_66:   UT = T/2; break;
-		case VIA_UDMA_100:  UT = 10;  break;
+		case VIA_UDMA_100:  UT = T/3; break;
 		default:	    UT = T;   break;
 	}
 
diff -u --recursive --new-file v2.4.9/linux/drivers/net/wireless/airport.c linux/drivers/net/wireless/airport.c
--- v2.4.9/linux/drivers/net/wireless/airport.c	Mon Aug 27 12:41:43 2001
+++ linux/drivers/net/wireless/airport.c	Mon Aug 27 09:00:37 2001
@@ -5,6 +5,10 @@
  *
  * Copyright notice & release notes in file orinoco.c
  * 
+ * Note specific to airport stub:
+ * 
+ *  0.05 : first version of the new split driver
+ *  0.06 : fix possible hang on powerup, add sleep support
  */
 
 #include <linux/module.h>
@@ -25,9 +29,12 @@
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
 #include <linux/list.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
 
 #include <asm/prom.h>
 #include <asm/feature.h>
+#include <asm/irq.h>
 
 #include "hermes.h"
 #include "orinoco.h"
@@ -40,10 +47,18 @@
 	struct device_node* node;
 	int irq_requested;
 	int ndev_registered;
+	int open;
 	/* Common structure (fully included), see orinoco.h */
 	struct dldwd_priv priv;
 } dldwd_card_t;
 
+#ifdef CONFIG_PMAC_PBOOK
+static int airport_sleep_notify(struct pmu_sleep_notifier *self, int when);
+static struct pmu_sleep_notifier airport_sleep_notifier = {
+	airport_sleep_notify, SLEEP_LEVEL_NET,
+};
+#endif
+
 /*
  * Function prototypes
  */
@@ -69,24 +84,15 @@
 static int airport_init(struct net_device *dev)
 {
 	dldwd_priv_t *priv = dev->priv;
-	dldwd_card_t* card = (dldwd_card_t *)priv->card;
 	int rc;
 	
 	TRACE_ENTER(priv->ndev.name);
 
 	MOD_INC_USE_COUNT;
 
-	feature_set_airport_power(card->node, 1);
-	current->state = TASK_UNINTERRUPTIBLE;
-	schedule_timeout(HZ);
-
 	rc = dldwd_init(dev);
-	if (rc) {	
-		feature_set_airport_power(card->node, 0);
-		current->state = TASK_UNINTERRUPTIBLE;
-		schedule_timeout(HZ);
-	}
-	priv->hw_ready = 1;
+	if (!rc)
+		priv->hw_ready = 1;
 
 	MOD_DEC_USE_COUNT;
 
@@ -97,18 +103,20 @@
 airport_open(struct net_device *dev)
 {
 	dldwd_priv_t *priv = dev->priv;
+	dldwd_card_t* card = (dldwd_card_t *)priv->card;
 	int rc;
 
 	TRACE_ENTER(priv->ndev.name);
 
-	netif_device_attach(dev);
 	rc = dldwd_reset(priv);
 	if (rc)
 		airport_stop(dev);
-	else
-		netif_start_queue(dev);
+	else {
+		card->open = 1;
+		netif_device_attach(dev);
+	}
 
-	TRACE_EXIT(priv->ndev.name);
+//	TRACE_EXIT(priv->ndev.name);
 
 	return rc;
 }
@@ -117,18 +125,66 @@
 airport_stop(struct net_device *dev)
 {
 	dldwd_priv_t *priv = dev->priv;
+	dldwd_card_t* card = (dldwd_card_t *)priv->card;
 
 	TRACE_ENTER(priv->ndev.name);
 
 	netif_stop_queue(dev);
-
 	dldwd_shutdown(priv);
+	card->open = 0;
 
 	TRACE_EXIT(priv->ndev.name);
 
 	return 0;
 }
 
+#ifdef CONFIG_PMAC_PBOOK
+static int
+airport_sleep_notify(struct pmu_sleep_notifier *self, int when)
+{
+	dldwd_priv_t *priv;
+	struct net_device *ndev;
+	dldwd_card_t* card;
+	int rc;
+	
+	if (!airport_dev)
+		return PBOOK_SLEEP_OK;
+	priv = airport_dev;
+	ndev = &priv->ndev;
+	card = (dldwd_card_t *)priv->card;
+
+	switch (when) {
+	case PBOOK_SLEEP_REQUEST:
+		break;
+	case PBOOK_SLEEP_REJECT:
+		break;
+	case PBOOK_SLEEP_NOW:
+		printk(KERN_INFO "%s: Airport entering sleep mode\n", ndev->name);
+		netif_device_detach(ndev);
+		if (card->open)
+			dldwd_shutdown(priv);
+		disable_irq(ndev->irq);
+		feature_set_airport_power(card->node, 0);
+		priv->hw_ready = 0;
+		break;
+	case PBOOK_WAKE:
+		printk(KERN_INFO "%s: Airport waking up\n", ndev->name);
+		feature_set_airport_power(card->node, 1);
+		mdelay(200);
+		hermes_reset(&priv->hw);
+		priv->hw_ready = 1;		
+		rc = dldwd_reset(priv);
+		if (rc)
+			printk(KERN_ERR "airport: Error %d re-initing card !\n", rc);
+		else if (card->open)
+			netif_device_attach(ndev);
+		enable_irq(ndev->irq);
+		break;
+	}
+	return PBOOK_SLEEP_OK;
+}
+#endif /* CONFIG_PMAC_PBOOK */
+
 static dldwd_priv_t*
 airport_attach(struct device_node* of_node)
 {
@@ -175,6 +231,14 @@
 
 	hermes_struct_init(hw, ndev->base_addr);
 		
+	/* Power up card */
+	feature_set_airport_power(card->node, 1);
+	current->state = TASK_UNINTERRUPTIBLE;
+	schedule_timeout(HZ);
+
+	/* Reset it before we get the interrupt */
+	hermes_reset(hw);
+
 	if (request_irq(ndev->irq, dldwd_interrupt, 0, "Airport", (void *)priv)) {
 		printk(KERN_ERR "airport: Couldn't get IRQ %d\n", ndev->irq);
 		goto failed;
@@ -198,6 +262,9 @@
 		printk(KERN_ERR "airport: Failed to create /proc node for %s\n",
 		       ndev->name);
 
+#ifdef CONFIG_PMAC_PBOOK
+	pmu_register_sleep_notifier(&airport_sleep_notifier);
+#endif
 	return priv;
 	
 failed:
@@ -219,6 +286,9 @@
 	/* Unregister proc entry */
 	dldwd_proc_dev_cleanup(priv);
 
+#ifdef CONFIG_PMAC_PBOOK
+	pmu_unregister_sleep_notifier(&airport_sleep_notifier);
+#endif
 	if (card->ndev_registered)
 		unregister_netdev(&priv->ndev);
 	card->ndev_registered = 0;
@@ -265,8 +335,6 @@
 		airport_detach(airport_dev);
 	airport_dev = NULL;
 }
-
-MODULE_DESCRIPTION("Apple Airport driver");
 
 module_init(init_airport);
 module_exit(exit_airport);
diff -u --recursive --new-file v2.4.9/linux/drivers/pci/names.c linux/drivers/pci/names.c
--- v2.4.9/linux/drivers/pci/names.c	Mon Oct  2 12:00:16 2000
+++ linux/drivers/pci/names.c	Mon Aug 27 08:47:07 2001
@@ -32,9 +32,9 @@
  * real memory.. Parse the same file multiple times
  * to get all the info.
  */
-#define VENDOR( vendor, name )		static const char __vendorstr_##vendor[] __initdata = name;
+#define VENDOR( vendor, name )		static char __vendorstr_##vendor[] __initdata = name;
 #define ENDVENDOR()
-#define DEVICE( vendor, device, name ) 	static const char __devicestr_##vendor##device[] __initdata = name;
+#define DEVICE( vendor, device, name ) 	static char __devicestr_##vendor##device[] __initdata = name;
 #include "devlist.h"
 
 
@@ -43,7 +43,7 @@
 #define DEVICE( vendor, device, name )	{ 0x##device, 0, __devicestr_##vendor##device },
 #include "devlist.h"
 
-static const struct pci_vendor_info __initdata pci_vendor_list[] = {
+static struct pci_vendor_info __initdata pci_vendor_list[] = {
 #define VENDOR( vendor, name )		{ 0x##vendor, sizeof(__devices_##vendor) / sizeof(struct pci_device_info), __vendorstr_##vendor, __devices_##vendor },
 #define ENDVENDOR()
 #define DEVICE( vendor, device, name )
diff -u --recursive --new-file v2.4.9/linux/drivers/pcmcia/yenta.c linux/drivers/pcmcia/yenta.c
--- v2.4.9/linux/drivers/pcmcia/yenta.c	Wed Jul 25 17:10:22 2001
+++ linux/drivers/pcmcia/yenta.c	Mon Aug 27 08:05:50 2001
@@ -729,7 +729,7 @@
 	if (type & IORESOURCE_IO) {
 		align = 1024;
 		size = 256;
-		min = PCIBIOS_MIN_IO;
+		min = 0x4000;
 		max = 0xffff;
 	}
 		
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/ds1286.c linux/drivers/sgi/char/ds1286.c
--- v2.4.9/linux/drivers/sgi/char/ds1286.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/sgi/char/ds1286.c	Mon Aug 27 08:56:31 2001
@@ -1,32 +1,30 @@
-/* $Id: ds1286.c,v 1.6 1999/10/09 00:01:31 ralf Exp $
- *
- *	Real Time Clock interface for Linux	
+/*
+ * DS1286 Real Time Clock interface for Linux	
  *
- *	Copyright (C) 1998, 1999 Ralf Baechle
+ * Copyright (C) 1998, 1999, 2000 Ralf Baechle
  *	
- *	Based on code written by Paul Gortmaker.
+ * Based on code written by Paul Gortmaker.
  *
- *	This driver allows use of the real time clock (built into
- *	nearly all computers) from user space. It exports the /dev/rtc
- *	interface supporting various ioctl() and also the /proc/rtc
- *	pseudo-file for status information.
+ * This driver allows use of the real time clock (built into nearly all
+ * computers) from user space. It exports the /dev/rtc interface supporting
+ * various ioctl() and also the /proc/rtc pseudo-file for status
+ * information.
  *
- *	The ioctls can be used to set the interrupt behaviour and
- *	generation rate from the RTC via IRQ 8. Then the /dev/rtc
- *	interface can be used to make use of these timer interrupts,
- *	be they interval or alarm based.
+ * The ioctls can be used to set the interrupt behaviour and generation rate
+ * from the RTC via IRQ 8. Then the /dev/rtc interface can be used to make
+ * use of these timer interrupts, be they interval or alarm based.
  *
- *	The /dev/rtc interface will block on reads until an interrupt
- *	has been received. If a RTC interrupt has already happened,
- *	it will output an unsigned long and then block. The output value
- *	contains the interrupt status in the low byte and the number of
- *	interrupts since the last read in the remaining high bytes. The 
- *	/dev/rtc interface can also be used with the select(2) call.
+ * The /dev/rtc interface will block on reads until an interrupt has been
+ * received. If a RTC interrupt has already happened, it will output an
+ * unsigned long and then block. The output value contains the interrupt
+ * status in the low byte and the number of interrupts since the last read
+ * in the remaining high bytes. The /dev/rtc interface can also be used with
+ * the select(2) call.
  *
- *	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 free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
  */
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -38,7 +36,6 @@
 #include <linux/poll.h>
 #include <linux/rtc.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 
 #include <asm/ds1286.h>
 #include <asm/io.h>
@@ -81,58 +78,20 @@
 #define RTC_IS_OPEN		0x01	/* means /dev/rtc is in use	*/
 #define RTC_TIMER_ON		0x02	/* missed irq timer active	*/
 
-unsigned char ds1286_status = 0;	/* bitmapped status byte.	*/
-unsigned long ds1286_freq = 0;		/* Current periodic IRQ rate	*/
-unsigned long ds1286_irq_data = 0;	/* our output to the world	*/
+unsigned char ds1286_status;		/* bitmapped status byte.	*/
+unsigned long ds1286_freq;		/* Current periodic IRQ rate	*/
 
 unsigned char days_in_mo[] = 
 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 
 /*
- *	A very tiny interrupt handler. It runs with SA_INTERRUPT set,
- *	so that there is no possibility of conflicting with the
- *	set_rtc_mmss() call that happens during some timer interrupts.
- *	(See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.)
- */
-
-/*
  *	Now all the various file operations that we export.
  */
 
 static ssize_t ds1286_read(struct file *file, char *buf,
                            size_t count, loff_t *ppos)
 {
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long data;
-	ssize_t retval;
-	
-	if (count < sizeof(unsigned long))
-		return -EINVAL;
-
-	add_wait_queue(&ds1286_wait, &wait);
-
-	current->state = TASK_INTERRUPTIBLE;
-		
-	while ((data = xchg(&ds1286_irq_data, 0)) == 0) {
-		if (file->f_flags & O_NONBLOCK) {
-			retval = -EAGAIN;
-			goto out;
-		}
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			goto out;
-		}
-		schedule();
-	}
-
-	retval = put_user(data, (unsigned long *)buf); 
-	if (!retval)
-		retval = sizeof(unsigned long); 
- out:
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&ds1286_wait, &wait);
-
-	return retval;
+	return -EIO;
 }
 
 static int ds1286_ioctl(struct inode *inode, struct file *file,
@@ -338,27 +297,32 @@
 
 static int ds1286_open(struct inode *inode, struct file *file)
 {
-	if(ds1286_status & RTC_IS_OPEN)
-		return -EBUSY;
+	spin_lock_irq(&ds1286_lock);
+
+	if (ds1286_status & RTC_IS_OPEN)
+		goto out_busy;
 
 	ds1286_status |= RTC_IS_OPEN;
-	ds1286_irq_data = 0;
+
+	spin_lock_irq(&ds1286_lock);
 	return 0;
+
+out_busy:
+	spin_lock_irq(&ds1286_lock);
+	return -EBUSY;
 }
 
 static int ds1286_release(struct inode *inode, struct file *file)
 {
-	lock_kernel();
 	ds1286_status &= ~RTC_IS_OPEN;
-	unlock_kernel();
+
 	return 0;
 }
 
 static unsigned int ds1286_poll(struct file *file, poll_table *wait)
 {
 	poll_wait(file, &ds1286_wait, wait);
-	if (ds1286_irq_data != 0)
-		return POLLIN | POLLRDNORM;
+
 	return 0;
 }
 
@@ -407,7 +371,7 @@
 
 	get_rtc_time(&tm);
 	hundredth = CMOS_READ(RTC_HUNDREDTH_SECOND);
-	hundredth = BCD_TO_BIN(hundredth);
+	BCD_TO_BIN(hundredth);
 
 	p += sprintf(p,
 	             "rtc_time\t: %02d:%02d:%02d.%02d\n"
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/graphics.c linux/drivers/sgi/char/graphics.c
--- v2.4.9/linux/drivers/sgi/char/graphics.c	Mon Mar 19 12:35:09 2001
+++ linux/drivers/sgi/char/graphics.c	Mon Aug 27 08:56:31 2001
@@ -1,5 +1,4 @@
-/* $Id: graphics.c,v 1.22 2000/02/18 00:24:43 ralf Exp $
- *
+/*
  * gfx.c: support for SGI's /dev/graphics, /dev/opengl
  *
  * Author: Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -214,8 +213,7 @@
 /* 
  * This is the core of the direct rendering engine.
  */
-
-unsigned long
+struct page *
 sgi_graphics_nopage (struct vm_area_struct *vma, unsigned long address, int
 		     no_share)
 {
@@ -250,7 +248,6 @@
 	pgd = pgd_offset(current->mm, address);
 	pmd = pmd_offset(pgd, address);
 	pte = pte_offset(pmd, address);
-	printk("page: %08lx\n", pte_page(*pte));
 	return pte_page(*pte);
 }
 
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/graphics_syms.c linux/drivers/sgi/char/graphics_syms.c
--- v2.4.9/linux/drivers/sgi/char/graphics_syms.c	Mon Feb 28 07:18:20 2000
+++ linux/drivers/sgi/char/graphics_syms.c	Wed Dec 31 16:00:00 1969
@@ -1,35 +0,0 @@
-/*
- * graphics_syms.c: interfaces for SGI Indy newport graphics
- *
- * Copyright (C) 1999 Alex deVries <puffin@redhat.com>
- *
- * We should not even be trying to compile this if we are not doing
- * a module.
- */
-
-#define __NO_VERSION__
-#include <linux/module.h>
-
-/* extern int rrm_command (unsigned int cmd, void *arg);
-extern int rrm_close (struct inode *inode, struct file *file);
-EXPORT_SYMBOL(rrm_command);
-EXPORT_SYMBOL(rrm_close);
-
-
-*/
-extern void shmiq_init (void);
-extern void usema_init(void);
-
-EXPORT_SYMBOL(shmiq_init);
-EXPORT_SYMBOL(usema_init);
-
-extern void disable_gconsole(void);
-extern void enable_gconsole(void);
-extern void remove_mapping (struct task_struct *task, unsigned long start,
-      unsigned long end);
-
-EXPORT_SYMBOL(disable_gconsole);
-EXPORT_SYMBOL(enable_gconsole);
-EXPORT_SYMBOL(remove_mapping);
-
-EXPORT_SYMBOL(npregs);
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/newport.c linux/drivers/sgi/char/newport.c
--- v2.4.9/linux/drivers/sgi/char/newport.c	Mon Feb 28 07:18:20 2000
+++ linux/drivers/sgi/char/newport.c	Mon Aug 27 08:56:31 2001
@@ -16,6 +16,8 @@
 
 struct newport_regs *npregs;
 
+EXPORT_SYMBOL(npregs);
+
 /* Kernel routines for supporting graphics context switching */
 
 void newport_save (void *y)
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/rrm.c linux/drivers/sgi/char/rrm.c
--- v2.4.9/linux/drivers/sgi/char/rrm.c	Tue Aug 29 14:09:15 2000
+++ linux/drivers/sgi/char/rrm.c	Mon Aug 27 08:56:31 2001
@@ -9,12 +9,11 @@
  *
  * Fixes:
  */
+#include <linux/module.h>
+
 #include <asm/uaccess.h>
 #include <asm/rrm.h>
 
-#ifdef MODULE
-#include <linux/module.h>
-#endif
 
 int
 rrm_open_rn (int rnid, void *arg)
@@ -71,3 +70,6 @@
 	/* This routine is invoked when the device is closed */
 	return 0;
 }
+
+EXPORT_SYMBOL(rrm_command);
+EXPORT_SYMBOL(rrm_close);
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/sgicons.c linux/drivers/sgi/char/sgicons.c
--- v2.4.9/linux/drivers/sgi/char/sgicons.c	Sun Jul  9 22:32:58 2000
+++ linux/drivers/sgi/char/sgicons.c	Mon Aug 27 08:56:31 2001
@@ -1,5 +1,4 @@
-/* $Id: sgicons.c,v 1.10 1998/08/25 09:18:58 ralf Exp $
- *
+/*
  * sgicons.c: Setting up and registering console I/O on the SGI.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
@@ -10,12 +9,10 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
+#include <linux/module.h>
 #include <asm/uaccess.h>
 #include "gconsole.h"
 
-/* To make psaux code cleaner */
-unsigned char aux_device_present = 0xaa;
-
 /* This is the system graphics console (the first adapter found) */
 struct console_ops *gconsole = 0;
 struct console_ops *real_gconsole = 0;
@@ -35,6 +32,9 @@
 		gconsole = 0;
 	}
 }
+
+EXPORT_SYMBOL(disable_gconsole);
+EXPORT_SYMBOL(enable_gconsole);
 
 void
 register_gconsole (struct console_ops *gc)
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/sgiserial.c linux/drivers/sgi/char/sgiserial.c
--- v2.4.9/linux/drivers/sgi/char/sgiserial.c	Thu Oct 12 14:20:47 2000
+++ linux/drivers/sgi/char/sgiserial.c	Mon Aug 27 08:56:31 2001
@@ -13,6 +13,9 @@
  * thorough pass to merge in the rest of the updates.
  * Better still, someone really ought to make it a common
  * code module for both platforms.   kevink@mips.com
+ *
+ * 20010616 - Klaus Naumann <spock@mgnet.de> : Make serial console work with
+ *                                             any speed - not only 9600
  */
 
 #include <linux/config.h> /* for CONFIG_REMOTE_DEBUG */
@@ -58,9 +61,9 @@
 static int zilog_irq = SGI_SERIAL_IRQ;
 
 /* Console hooks... */
-static int zs_cons_chanout = 0;
-static int zs_cons_chanin = 0;
-struct sgi_serial *zs_consinfo = 0;
+static int zs_cons_chanout;
+static int zs_cons_chanin;
+struct sgi_serial *zs_consinfo;
 
 static unsigned char kgdb_regs[16] = {
 	0, 0, 0,                     /* write 0, 1, 2 */
@@ -97,6 +100,7 @@
 DECLARE_TASK_QUEUE(tq_serial);
 
 struct tty_driver serial_driver, callout_driver;
+struct console *sgisercon;
 static int serial_refcount;
 
 /* serial subtype definitions */
@@ -144,10 +148,10 @@
 					dev_t device, const char *routine)
 {
 #ifdef SERIAL_PARANOIA_CHECK
-	static const char *badmagic =
+	static const char *badmagic = KERN_WARNING
 		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
-	static const char *badinfo =
-		"Warning: null sun_serial for (%d, %d) in %s\n";
+	static const char *badinfo = KERN_WARNING
+		"Warning: null sgi_serial for (%d, %d) in %s\n";
 
 	if (!info) {
 		printk(badinfo, MAJOR(device), MINOR(device), routine);
@@ -178,7 +182,8 @@
  * interrupts are enabled. Therefore we have to check ioc_iocontrol before we
  * access it.
  */
-static inline unsigned char read_zsreg(struct sgi_zschannel *channel, unsigned char reg)
+static inline unsigned char read_zsreg(struct sgi_zschannel *channel,
+                                       unsigned char reg)
 {
 	unsigned char retval;
 	volatile unsigned char junk;
@@ -192,7 +197,8 @@
 	return retval;
 }
 
-static inline void write_zsreg(struct sgi_zschannel *channel, unsigned char reg, unsigned char value)
+static inline void write_zsreg(struct sgi_zschannel *channel,
+                               unsigned char reg, unsigned char value)
 {
 	volatile unsigned char junk;
 
@@ -323,7 +329,7 @@
  */
 static void batten_down_hatches(void)
 {
-	prom_imode();
+	ArcEnterInteractiveMode();
 #if 0
 	/* If we are doing kadb, we call the debugger
 	 * else we just drop into the boot monitor.
@@ -682,7 +688,7 @@
 	save_flags(flags); cli();
 
 #ifdef SERIAL_DEBUG_OPEN
-	printk("starting up ttys%d (irq %d)...", info->line, info->irq);
+	printk("starting up ttys%d (irq %d)...\n", info->line, info->irq);
 #endif
 
 	/*
@@ -1302,6 +1308,59 @@
 	junk = ioc_icontrol->istat0;
 	sti();
 	return put_user(status,value);
+} 
+
+static int get_modem_info(struct sgi_serial * info, unsigned int *value)
+{
+	unsigned char status;
+	unsigned int result;
+
+	cli();
+	status = info->zs_channel->control;
+	udelay(2);
+	sti();
+	result =  ((info->curregs[5] & RTS) ? TIOCM_RTS : 0)
+		| ((info->curregs[5] & DTR) ? TIOCM_DTR : 0)
+		| ((status  & DCD) ? TIOCM_CAR : 0)
+		| ((status  & SYNC) ? TIOCM_DSR : 0)
+		| ((status  & CTS) ? TIOCM_CTS : 0);
+	if (put_user(result, value))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_modem_info(struct sgi_serial * info, unsigned int cmd,
+			  unsigned int *value)
+{
+	unsigned int arg;
+
+	if (get_user(arg, value))
+		return -EFAULT;
+	switch (cmd) {
+	case TIOCMBIS: 
+		if (arg & TIOCM_RTS)
+			info->curregs[5] |= RTS;
+		if (arg & TIOCM_DTR)
+			info->curregs[5] |= DTR;
+		break;
+	case TIOCMBIC:
+		if (arg & TIOCM_RTS)
+			info->curregs[5] &= ~RTS;
+		if (arg & TIOCM_DTR)
+			info->curregs[5] &= ~DTR;
+		break;
+	case TIOCMSET:
+		info->curregs[5] = ((info->curregs[5] & ~(RTS | DTR))
+			     | ((arg & TIOCM_RTS) ? RTS : 0)
+			     | ((arg & TIOCM_DTR) ? DTR : 0));
+		break;
+	default:
+		return -EINVAL;
+	}
+	cli();
+	write_zsreg(info->zs_channel, 5, info->curregs[5]);
+	sti();
+	return 0;
 }
 
 /*
@@ -1322,11 +1381,10 @@
 static int rs_ioctl(struct tty_struct *tty, struct file * file,
 		    unsigned int cmd, unsigned long arg)
 {
-	int error;
-	struct sgi_serial * info = (struct sgi_serial *)tty->driver_data;
+	struct sgi_serial * info = (struct sgi_serial *) tty->driver_data;
 	int retval;
 
-	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
+	if (serial_paranoia_check(info, tty->device, "zs_ioctl"))
 		return -ENODEV;
 
 	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
@@ -1353,45 +1411,36 @@
 			send_break(info, arg ? arg*(HZ/10) : HZ/4);
 			return 0;
 		case TIOCGSOFTCAR:
-			error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
-			if (error)
-				return error;
-			put_user(C_CLOCAL(tty) ? 1 : 0,
-			         (unsigned long *) arg);
+			if (put_user(C_CLOCAL(tty) ? 1 : 0,
+				     (unsigned long *) arg))
+				return -EFAULT;
 			return 0;
 		case TIOCSSOFTCAR:
-			error = get_user(arg, (unsigned long *)arg);
-			if (error)
-				return error;
+			if (get_user(arg, (unsigned long *) arg))
+				return -EFAULT;
 			tty->termios->c_cflag =
 				((tty->termios->c_cflag & ~CLOCAL) |
 				 (arg ? CLOCAL : 0));
 			return 0;
+		case TIOCMGET:
+			return get_modem_info(info, (unsigned int *) arg);
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			return set_modem_info(info, cmd, (unsigned int *) arg);
 		case TIOCGSERIAL:
-			error = verify_area(VERIFY_WRITE, (void *) arg,
-						sizeof(struct serial_struct));
-			if (error)
-				return error;
 			return get_serial_info(info,
 					       (struct serial_struct *) arg);
 		case TIOCSSERIAL:
 			return set_serial_info(info,
 					       (struct serial_struct *) arg);
 		case TIOCSERGETLSR: /* Get line status register */
-			error = verify_area(VERIFY_WRITE, (void *) arg,
-				sizeof(unsigned int));
-			if (error)
-				return error;
-			else
-			    return get_lsr_info(info, (unsigned int *) arg);
+			return get_lsr_info(info, (unsigned int *) arg);
 
 		case TIOCSERGSTRUCT:
-			error = verify_area(VERIFY_WRITE, (void *) arg,
-						sizeof(struct sgi_serial));
-			if (error)
-				return error;
-			copy_to_user((struct sun_serial *) arg,
-				    info, sizeof(struct sgi_serial));
+			if (copy_to_user((struct sgi_serial *) arg,
+				    info, sizeof(struct sgi_serial)))
+				return -EFAULT;
 			return 0;
 			
 		default:
@@ -1727,11 +1776,19 @@
 		change_speed(info);
 	}
 
+	/* If this is the serial console change the speed to 
+	 * the right value
+	 */
+	if (info->is_cons) {
+		info->tty->termios->c_cflag = sgisercon->cflag;
+		change_speed(info);		
+	}
+
 	info->session = current->session;
 	info->pgrp = current->pgrp;
 
 #ifdef SERIAL_DEBUG_OPEN
-	printk("rs_open ttys%d successful...", info->line);
+	printk("rs_open ttys%d successful...\n", info->line);
 #endif
 	return 0;
 }
@@ -1748,13 +1805,10 @@
 {
 	extern struct hpc3_miscregs *hpc3mregs;
 
-	if(chip > 0) {
-		prom_printf("Wheee, bogus zs chip number requested.\n");
-		prom_getchar();
-		romvec->imode();
-	}
-	return (struct sgi_zslayout *) (&hpc3mregs->ser1cmd);
+	if (chip > 0)
+		panic("Wheee, bogus zs chip number requested.");
 
+	return (struct sgi_zslayout *) (&hpc3mregs->ser1cmd);
 }
 
 
@@ -1784,13 +1838,6 @@
 	}
 	if(o && i)
 		io = 1;
-	if(ss->zs_baud != 9562) { /* Don't ask... */
-		prom_printf("BAD console baud rate %d\n", ss->zs_baud);
-		prom_getchar();
-		prom_imode();
-		panic("Console baud rate weirdness");
-	}
-
 
 	/* Set flag variable for this port so that it cannot be
 	 * opened for other uses by accident.
@@ -1798,7 +1845,7 @@
 	ss->is_cons = 1;
 
 	if(io) {
-		if(!msg_printed) {
+		if (!msg_printed) {
 			printk("zs%d: console I/O\n", ((channel>>1)&1));
 			msg_printed = 1;
 		}
@@ -1806,7 +1853,6 @@
 	} else {
 		printk("zs%d: console %s\n", ((channel>>1)&1),
 		       (i==1 ? "input" : (o==1 ? "output" : "WEIRD")));
-
 	}
 }
 
@@ -2002,7 +2048,6 @@
 rs_cons_hook(int chip, int out, int line)
 {
 	int channel;
-
 	
 	if(chip)
 		panic("rs_cons_hook called with chip not zero");
@@ -2087,11 +2132,11 @@
 static int __init zs_console_setup(struct console *con, char *options)
 {
 	struct sgi_serial *info;
-	int	baud = 9600;
+	int	baud;
 	int	bits = 8;
 	int	parity = 'n';
 	int	cflag = CREAD | HUPCL | CLOCAL;
-	char	*s;
+	char	*s, *dbaud;
 	int     i, brg;
     
 	if (options) {
@@ -2102,6 +2147,21 @@
 		if (*s) parity = *s++;
 		if (*s) bits   = *s - '0';
 	}
+	else {
+		/* If the user doesn't set console=... try to read the
+		 * PROM variable - if this fails use 9600 baud and
+		 * inform the user about the problem
+		 */
+		dbaud = ArcGetEnvironmentVariable("dbaud");
+		if(dbaud) baud = simple_strtoul(dbaud, NULL, 10);
+		else {
+			/* Use prom_printf() to make sure that the user
+			 * is getting anything ...
+			 */
+			prom_printf("No dbaud set in PROM ?!? Using 9600.\n");
+			baud = 9600;
+		}
+	}
 
 	/*
 	 *	Now construct a cflag setting.
@@ -2156,7 +2216,8 @@
 	info = zs_soft + con->index;
 	info->is_cons = 1;
     
-	printk("Console: ttyS%d (Zilog8530)\n", info->line);
+	printk("Console: ttyS%d (Zilog8530), %d baud\n", 
+						info->line, baud);
 
 	i = con->cflag & CBAUD;
 	if (con->cflag & CBAUDEX) {
@@ -2195,6 +2256,8 @@
 		zscons_regs[4] |= SB2;
 	else
 		zscons_regs[4] |= SB1;
+	
+	sgisercon = con;
 
 	brg = BPS_TO_BRG(baud, ZS_CLOCK / info->clk_divisor);
 	zscons_regs[12] = brg & 0xff;
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/sgiserial.h linux/drivers/sgi/char/sgiserial.h
--- v2.4.9/linux/drivers/sgi/char/sgiserial.h	Fri Jun 25 17:39:34 1999
+++ linux/drivers/sgi/char/sgiserial.h	Mon Aug 27 08:56:31 2001
@@ -359,7 +359,7 @@
 #define	ZCOUNT		0x2	/* Zero count */
 #define	Tx_BUF_EMP	0x4	/* Tx Buffer empty */
 #define	DCD		0x8	/* DCD */
-#define	SYNC_HUNT	0x10	/* Sync/hunt */
+#define	SYNC		0x10	/* Sync/hunt */
 #define	CTS		0x20	/* CTS */
 #define	TxEOM		0x40	/* Tx underrun */
 #define	BRK_ABRT	0x80	/* Break/Abort */
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/shmiq.c linux/drivers/sgi/char/shmiq.c
--- v2.4.9/linux/drivers/sgi/char/shmiq.c	Mon Mar 19 12:35:09 2001
+++ linux/drivers/sgi/char/shmiq.c	Mon Aug 27 08:56:31 2001
@@ -1,5 +1,4 @@
-/* $Id: shmiq.c,v 1.19 2000/02/23 00:41:21 ralf Exp $
- *
+/*
  * shmiq.c: shared memory input queue driver
  * written 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
  *
@@ -42,7 +41,6 @@
  * Until then, I just allow for 1 qcntl device.
  *
  */
-
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/sched.h>
@@ -52,6 +50,7 @@
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
 #include <linux/major.h>
+#include <linux/module.h>
 #include <linux/smp_lock.h>
 #include <linux/devfs_fs_kernel.h>
 
@@ -470,3 +469,5 @@
 			       S_IFCHR | S_IRUSR | S_IWUSR,
 			       &shmiq_fops, NULL);
 }
+
+EXPORT_SYMBOL(shmiq_init);
diff -u --recursive --new-file v2.4.9/linux/drivers/sgi/char/usema.c linux/drivers/sgi/char/usema.c
--- v2.4.9/linux/drivers/sgi/char/usema.c	Wed Jul 12 21:58:43 2000
+++ linux/drivers/sgi/char/usema.c	Mon Aug 27 08:56:31 2001
@@ -20,8 +20,7 @@
  * usema(7m), usinit(3p), usnewsema(3p)
  * /usr/include/sys/usioctl.h 
  *
-*/
-
+ */
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/sched.h>
@@ -31,6 +30,7 @@
 #include <linux/string.h>
 #include <linux/dcache.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
 #include "usema.h"
@@ -180,3 +180,5 @@
 	       SGI_USEMACLONE);
 	misc_register(&dev_usemaclone);
 }
+
+EXPORT_SYMBOL(usema_init);
diff -u --recursive --new-file v2.4.9/linux/drivers/sound/awe_wave.c linux/drivers/sound/awe_wave.c
--- v2.4.9/linux/drivers/sound/awe_wave.c	Fri Mar  2 11:12:11 2001
+++ linux/drivers/sound/awe_wave.c	Mon Aug 27 08:11:43 2001
@@ -4873,7 +4873,7 @@
 /* any three numbers you like */
 #define UNIQUE_ID1	0x1234
 #define UNIQUE_ID2	0x4321
-#define UNIQUE_ID3	0xFFFF
+#define UNIQUE_ID3	0xABCD
 
 static void __init
 awe_check_dram(void)
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/lk201-map.map linux/drivers/tc/lk201-map.map
--- v2.4.9/linux/drivers/tc/lk201-map.map	Wed Dec 31 16:00:00 1969
+++ linux/drivers/tc/lk201-map.map	Mon Aug 27 08:56:31 2001
@@ -0,0 +1,356 @@
+# Default kernel keymap. This uses 7 modifier combinations.
+keymaps 0-2,4-5,8,12
+# Change the above line into
+#	keymaps 0-2,4-6,8,12
+# in case you want the entries
+#	altgr   control keycode  83 = Boot            
+#	altgr   control keycode 111 = Boot            
+# below.
+#
+# In fact AltGr is used very little, and one more keymap can
+# be saved by mapping AltGr to Alt (and adapting a few entries):
+# keycode 100 = Alt
+#
+keycode   0x15 = grave		tilde
+	alt     keycode   0x15 = Escape
+	control keycode   0x15 = Meta_Escape
+keycode   0x16 = one              exclam
+	alt     keycode   0x16 = Meta_one
+keycode   0x17 = two              at               at
+	control	keycode   0x17 = nul
+	shift	control	keycode   0x17 = nul
+	alt	keycode   0x17 = Meta_two
+keycode   0x18 = three            numbersign
+	control keycode   0x18 = Escape
+	alt     keycode   0x18 = Meta_three
+keycode   0x19 = four             dollar           dollar
+	control keycode   0x19 = Control_backslash
+	alt     keycode   0x19 = Meta_four
+keycode   0x1a = five             percent
+	control keycode   0x1a = Control_bracketright
+	alt     keycode   0x1a = Meta_five
+keycode   0x1b = six              asciicircum
+	control keycode   0x1b = Control_asciicircum
+	alt     keycode   0x1b = Meta_six
+keycode   0x1c = seven            ampersand        braceleft
+	control keycode   0x1c = Control_underscore
+	alt     keycode   0x1c = Meta_seven
+keycode   0x1d = eight            asterisk         bracketleft
+	control keycode   0x1d = Delete
+	alt     keycode   0x1d = Meta_eight
+keycode  0x1e = nine             parenleft        bracketright
+	alt     keycode  0x1e = Meta_nine
+keycode  0x1f = zero             parenright       braceright
+	alt     keycode  0x1f = Meta_zero
+keycode  0x20 = minus            underscore       backslash
+	control	keycode  0x20 = Control_underscore
+	shift	control	keycode  0x20 = Control_underscore
+	alt	keycode  0x20 = Meta_minus
+keycode  0x21 = equal            plus
+	alt     keycode  0x21 = Meta_equal
+keycode  0x22 = Delete           Delete
+	control keycode  0x22 = BackSpace
+	alt     keycode  0x22 = Meta_Delete
+keycode  0x2a = Tab              Tab
+	alt     keycode  0x2a = Meta_Tab
+keycode  0x2b = q
+keycode  0x2c = w
+keycode  0x2d = e
+	altgr   keycode  0x2d = Hex_E
+keycode  0x2e = r
+keycode  0x2f = t
+keycode  0x30 = y
+keycode  0x31 = u
+keycode  0x32 = i
+keycode  0x33 = o
+keycode  0x34 = p
+keycode  0x35 = bracketleft      braceleft
+	control keycode  0x35 = Escape
+	alt     keycode  0x35 = Meta_bracketleft
+keycode  0x36 = bracketright     braceright       asciitilde
+	control keycode  0x36 = Control_bracketright
+	alt     keycode  0x36 = Meta_bracketright
+keycode  0x37 = Return
+	alt     keycode  0x37 = Meta_Control_m
+keycode  0x3f = Control
+keycode  0x41 = a
+	altgr   keycode  0x41 = Hex_A
+keycode  0x42 = s
+keycode  0x43 = d
+	altgr   keycode  0x43 = Hex_D
+keycode  0x44 = f
+	altgr   keycode  0x44 = Hex_F
+keycode  0x45 = g
+keycode  0x46 = h
+keycode  0x47 = j
+keycode  0x48 = k
+keycode  0x49 = l
+keycode  0x4a = semicolon        colon
+	alt     keycode  0x4a = Meta_semicolon
+keycode  0x4b = apostrophe       quotedbl
+	control keycode  0x4b = Control_g
+	alt     keycode  0x4b = Meta_apostrophe
+# keycode  41 = grave            asciitilde
+#	control keycode  41 = nul
+#	alt     keycode  41 = Meta_grave
+keycode  0x52 = Shift
+keycode  0x4c = backslash        bar
+	control keycode  0x4c = Control_backslash
+	alt     keycode  0x4c = Meta_backslash
+keycode  0x53 = greater	less
+keycode  0x54 = z
+keycode  0x55 = x
+keycode  0x56 = c
+	altgr   keycode  0x56 = Hex_C
+keycode  0x57 = v
+keycode  0x58 = b
+	altgr   keycode  0x58 = Hex_B
+keycode  0x59 = n
+keycode  0x5a = m
+keycode  0x5b = comma            less
+	alt     keycode  0x5b = Meta_comma
+keycode  0x5c = period           greater
+	control keycode  0x5c = Compose
+	alt     keycode  0x5c = Meta_period
+keycode  0x5d = slash            question
+	control keycode  0x5d = Delete
+	alt     keycode  0x5d = Meta_slash
+
+keycode  0x67 = Alt
+keycode  0x68 = space            space
+	control keycode  0x68 = nul
+	alt     keycode  0x68 = Meta_space
+keycode  0x40 = Caps_Lock
+keycode  0x01 = F1
+	control keycode  0x01 = F1
+	alt     keycode  0x01 = Console_1
+	control alt     keycode  0x01 = Console_1
+keycode  0x02 = F2
+	control keycode  0x02 = F2
+	alt     keycode  0x02 = Console_2
+	control alt     keycode  0x02 = Console_2
+keycode  0x03 = F3
+	control keycode  0x03 = F3
+	alt     keycode  0x03 = Console_3
+	control alt     keycode  0x03 = Console_3
+keycode  0x04 = F4
+	control keycode  0x04 = F4
+	alt     keycode  0x04 = Console_4
+	control alt     keycode  0x04 = Console_4
+keycode  0x05 = F5
+	control keycode  0x05 = F5
+	alt     keycode  0x05 = Console_5
+	control alt     keycode  0x05 = Console_5
+keycode  0x06 = F6
+	control keycode  0x06 = F6
+	alt     keycode  0x06 = Console_6
+	control alt     keycode  0x06 = Console_6
+keycode  0x07 = F7
+	control keycode  0x07 = F7
+	alt     keycode  0x07 = Console_7
+	control alt     keycode  0x07 = Console_7
+keycode  0x08 = F8
+	control keycode  0x08 = F8
+	alt     keycode  0x08 = Console_8
+	control alt     keycode  0x08 = Console_8
+keycode  0x09 = F9
+	control keycode  0x09 = F9
+	alt     keycode  0x09 = Console_9
+	control alt     keycode  0x09 = Console_9
+keycode  0x0a = F10
+	control keycode  0x0a = F10
+	alt     keycode  0x0a = Console_10
+	control alt     keycode  0x0a = Console_10
+keycode  0x0b = F11
+	control keycode  0x0b = F11
+	alt     keycode  0x0b = Console_11
+	control alt     keycode  0x0b = Console_11
+keycode  0x0c = F12
+	control keycode  0x0c = F12
+	alt     keycode  0x0c = Console_12
+	control alt     keycode  0x0c = Console_12
+keycode  0x0d = F13
+	control keycode  0x0d = F13
+	alt     keycode  0x0d = Console_13
+	control alt     keycode  0x0d = Console_13
+keycode  0x0e = F14
+	control keycode  0x0e = F14
+	alt     keycode  0x0e = Console_14
+	control alt     keycode  0x0e = Console_14
+
+keycode  0x11 = F17
+	control keycode  0x11 = F17
+	alt     keycode  0x11 = Console_17
+	control alt     keycode  0x11 = Console_17
+keycode  0x12 = F18
+	control keycode  0x12 = F18
+	alt     keycode  0x12 = Console_18
+	control alt     keycode  0x12 = Console_18
+keycode  0x13 = F19
+	control keycode  0x13 = F19
+	alt     keycode  0x13 = Console_19
+	control alt     keycode  0x13 = Console_19
+keycode  0x14 = F20
+	control keycode  0x14 = F20
+	alt     keycode  0x14 = Console_20
+	control alt     keycode  0x14 = Console_20
+
+
+keycode  0x3b = KP_7
+	alt     keycode  0x3b = Ascii_7
+	altgr   keycode  0x3b = Hex_7
+keycode  0x3c = KP_8
+	alt     keycode  0x3c = Ascii_8
+	altgr   keycode  0x3c = Hex_8
+keycode  0x3d = KP_9
+	alt     keycode  0x3d = Ascii_9
+	altgr   keycode  0x3d = Hex_9
+keycode  0x3e = KP_Subtract
+keycode  0x4e = KP_4
+	alt     keycode  0x4e = Ascii_4
+	altgr   keycode  0x4e = Hex_4
+keycode  0x4f = KP_5
+	alt     keycode  0x4f = Ascii_5
+	altgr   keycode  0x4f = Hex_5
+keycode  0x50 = KP_6
+	alt     keycode  0x50 = Ascii_6
+	altgr   keycode  0x50 = Hex_6
+keycode  0x62 = KP_1
+	alt     keycode  0x62 = Ascii_1
+	altgr   keycode  0x62 = Hex_1
+keycode  0x63 = KP_2
+	alt     keycode  0x63 = Ascii_2
+	altgr   keycode  0x63 = Hex_2
+keycode  0x64 = KP_3
+	alt     keycode  0x64 = Ascii_3
+	altgr   keycode  0x64 = Hex_3
+keycode  0x6b = KP_0
+	alt     keycode  0x6b = Ascii_0
+	altgr   keycode  0x6b = Hex_0
+keycode  0x6c = KP_Period
+#	altgr   control keycode  0x6c = Boot
+	control alt     keycode  0x6c = Boot
+keycode  0x65 = KP_Enter
+
+keycode  0x3f = Control
+
+# keycode 100 = AltGr
+
+keycode 0x23 = Find
+keycode 0x4d = Up
+keycode 0x39 = Prior
+	shift   keycode 0x39 = Scroll_Backward
+keycode 0x5f = Left
+	alt     keycode 0x5f = Decr_Console
+keycode 0x61 = Right
+	alt     keycode 0x61 = Incr_Console
+keycode 0x38 = Select
+keycode 0x60 = Down
+keycode 0x3a = Next
+	shift   keycode 0x3a = Scroll_Forward
+keycode 0x24 = Insert
+keycode 0x25 = Remove
+#	altgr   control keycode 0x25 = Boot
+	control alt     keycode 0x25 = Boot
+
+keycode 0x0f = Help      Show_Memory      Show_Registers
+	control keycode  0x0f = Show_State
+
+keycode 0x10 = Do
+
+string F1 = "\033[[A"
+string F2 = "\033[[B"
+string F3 = "\033[[C"
+string F4 = "\033[[D"
+string F5 = "\033[[E"
+string F6 = "\033[17~"
+string F7 = "\033[18~"
+string F8 = "\033[19~"
+string F9 = "\033[20~"
+string F10 = "\033[21~"
+string F11 = "\033[23~"
+string F12 = "\033[24~"
+string F13 = "\033[25~"
+string F14 = "\033[26~"
+string F15 = "\033[28~"
+string F16 = "\033[29~"
+string F17 = "\033[31~"
+string F18 = "\033[32~"
+string F19 = "\033[33~"
+string F20 = "\033[34~"
+string Find = "\033[1~"
+string Insert = "\033[2~"
+string Remove = "\033[3~"
+string Select = "\033[4~"
+string Prior = "\033[5~"
+string Next = "\033[6~"
+string Macro = "\033[M"
+string Pause = "\033[P"
+compose '`' 'A' to 'À'
+compose '`' 'a' to 'à'
+compose '\'' 'A' to 'Á'
+compose '\'' 'a' to 'á'
+compose '^' 'A' to 'Â'
+compose '^' 'a' to 'â'
+compose '~' 'A' to 'Ã'
+compose '~' 'a' to 'ã'
+compose '"' 'A' to 'Ä'
+compose '"' 'a' to 'ä'
+compose 'O' 'A' to 'Å'
+compose 'o' 'a' to 'å'
+compose '0' 'A' to 'Å'
+compose '0' 'a' to 'å'
+compose 'A' 'A' to 'Å'
+compose 'a' 'a' to 'å'
+compose 'A' 'E' to 'Æ'
+compose 'a' 'e' to 'æ'
+compose ',' 'C' to 'Ç'
+compose ',' 'c' to 'ç'
+compose '`' 'E' to 'È'
+compose '`' 'e' to 'è'
+compose '\'' 'E' to 'É'
+compose '\'' 'e' to 'é'
+compose '^' 'E' to 'Ê'
+compose '^' 'e' to 'ê'
+compose '"' 'E' to 'Ë'
+compose '"' 'e' to 'ë'
+compose '`' 'I' to 'Ì'
+compose '`' 'i' to 'ì'
+compose '\'' 'I' to 'Í'
+compose '\'' 'i' to 'í'
+compose '^' 'I' to 'Î'
+compose '^' 'i' to 'î'
+compose '"' 'I' to 'Ï'
+compose '"' 'i' to 'ï'
+compose '-' 'D' to 'Ð'
+compose '-' 'd' to 'ð'
+compose '~' 'N' to 'Ñ'
+compose '~' 'n' to 'ñ'
+compose '`' 'O' to 'Ò'
+compose '`' 'o' to 'ò'
+compose '\'' 'O' to 'Ó'
+compose '\'' 'o' to 'ó'
+compose '^' 'O' to 'Ô'
+compose '^' 'o' to 'ô'
+compose '~' 'O' to 'Õ'
+compose '~' 'o' to 'õ'
+compose '"' 'O' to 'Ö'
+compose '"' 'o' to 'ö'
+compose '/' 'O' to 'Ø'
+compose '/' 'o' to 'ø'
+compose '`' 'U' to 'Ù'
+compose '`' 'u' to 'ù'
+compose '\'' 'U' to 'Ú'
+compose '\'' 'u' to 'ú'
+compose '^' 'U' to 'Û'
+compose '^' 'u' to 'û'
+compose '"' 'U' to 'Ü'
+compose '"' 'u' to 'ü'
+compose '\'' 'Y' to 'Ý'
+compose '\'' 'y' to 'ý'
+compose 'T' 'H' to 'Þ'
+compose 't' 'h' to 'þ'
+compose 's' 's' to 'ß'
+compose '"' 'y' to 'ÿ'
+compose 's' 'z' to 'ß'
+compose 'i' 'j' to 'ÿ'
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/lk201-remap.c linux/drivers/tc/lk201-remap.c
--- v2.4.9/linux/drivers/tc/lk201-remap.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/tc/lk201-remap.c	Mon Aug 27 08:56:31 2001
@@ -0,0 +1,172 @@
+/*
+ * Keyboard mappings for DEC LK201/401/501 keyboards
+ * 
+ * 17.05.99 Michael Engel (engel@unix-ag.org)
+ *
+ * DEC US keyboards generate keycodes in the range 0x55 - 0xfb
+ *
+ * This conflicts with Linux scancode conventions which define 
+ * 0x00-0x7f as "normal" and 0x80-0xff as "shifted" scancodes, so we
+ * have to remap the keycodes to 0x00-0x7f with the scancodeRemap
+ * array. The generated scancode is simply the number of the key counted
+ * from the left upper to the right lower corner of the keyboard ...
+ *
+ * These scancodes are then being remapped (I hope ;-)) with the 
+ * lk501*map[] arrays which define scancode -> Linux code mapping
+ *
+ * Oh man is this horrible ;-)
+ *
+ * Scancodes with dual labels exist for keyboards as follows:
+ *
+ * code:  left label          / right label
+ *
+ * 0x73:  LKx01, LK421        / LK443, LK444
+ * 0x74:  LKx01, LK421        / LK443, LK444
+ * 0x7c:  LKx01, LK421        / LK443, LK444
+ * 0x8a:  LKx01, LK421        / LK443, LK444
+ * 0x8b:  LKx01, LK421        / LK443, LK444
+ * 0x8c:  LKx01, LK421        / LK443, LK444
+ * 0x8d:  LKx01, LK421        / LK443, LK444
+ * 0x8e:  LKx01, LK421        / LK443, LK444
+ * 0x8f:  LKx01, LK421        / LK443, LK444
+ * 0x9c:  LKx01, LK421        / LK443, LK444
+ * 0xa1:  LKx01, LK421        / LK443, LK444
+ * 0xa2:  LKx01, LK421        / LK443, LK444
+ * 0xa3:  LKx01, LK421        / LK443, LK444
+ * 0xa4:  LKx01, LK421        / LK443, LK444
+ * 0xad:         LK421        / LK443, LK444
+ * 0xc9:  LKx01, LK421, LK443 /        LK444
+ * 0xf7:  LKx01,        LK443 /        LK444
+ */
+
+unsigned char scancodeRemap[256] = {
+/* ----- 								*/
+/*  0 */ 0,		0,		0,		0,
+/* ----- 								*/
+/*  4 */ 0,		0,		0,		0,
+/* ----- 								*/
+/*  8 */ 0,		0,		0,		0,
+/* ----- 								*/
+/*  c */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 10 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 14 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 18 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 1c */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 20 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 24 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 28 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 2c */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 30 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 34 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 38 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 3c */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 40 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 44 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 48 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 4c */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 50 */ 0,		0,		0,		0,
+/* ----- 	 	ESC		F1		F2 		*/
+/* 54 */ 0,		0,		0x01,  		0x02,
+/* ----- F3		F4		F5				*/
+/* 58 */ 0x03,  	0x04,		0x05,		0,
+/* ----- 								*/
+/* 5c */ 0,		0,		0,		0,
+/* ----- 								*/
+/* 60 */ 0,		0,		0,		0,
+/* ----- F6		F7		F8		F9		*/
+/* 64 */ 0x06,		0x07,		0x08,		0x09, 
+/* ----- F10								*/
+/* 68 */ 0x0a,		0,		0,		0,
+/* ----- 								*/
+/* 6c */ 0,		0,		0,		0,
+/* ----- 		F11   		F12		F13/PRNT SCRN	*/
+/* 70 */ 0,		0x0b,  		0x0c,		0x0d,
+/* ----- F14/SCRL LCK							*/
+/* 74 */ 0x0e,		0,		0,		0,
+/* ----- 								*/
+/* 78 */ 0,		0,		0,		0,
+/* ----- HELP/PAUSE	DO						*/
+/* 7c */ 0x0f,		0x10,		0,		0,
+/* ----- F17		F18		F19		F20		*/
+/* 80 */ 0x11,		0x12,		0x13,		0x14,
+/* ----- 								*/
+/* 84 */ 0,		0,		0,		0,
+/* ----- 				FIND/INSERT	INSERT/HOME	*/
+/* 88 */ 0,		0,		0x23,		0x24,
+/* ----- REMOVE/PG UP	SELECT/DELETE	PREVIOUS/END	NEXT/PG DN	*/
+/* 8c */ 0x25,		0x38,		0x39,		0x3a,
+/* ----- 				KP 0				*/
+/* 90 */ 0,		0,		0x6b,		0,
+/* ----- KP .		KP ENTER	KP 1		KP 2		*/
+/* 94 */ 0x6c,		0x65,		0x62,		0x63,
+/* ----- KP 3		KP 4		KP 5		KP 6		*/
+/* 98 */ 0x64,		0x4e,		0x4f,		0x50,
+/* ----- KP ,/KP +	KP 7		KP 8		KP 9		*/
+/* 9c */ 0x51,		0x3b,		0x3c,		0x3d,
+/* ----- KP -		KP F1/NUM LCK	KP F2/KP /	KP F3/KP *	*/
+/* a0 */ 0x3e,		0x26,		0x27,		0x28,
+/* ----- KP F4/KP -					LEFT		*/
+/* a4 */ 0x29,		0,		0,		0x5f,
+/* ----- RIGHT		DOWN		UP		SHIFT Rt	*/
+/* a8 */ 0x61,		0x60, 		0x4d,		0x5e,
+/* ----- ALT		COMP Rt/CTRL Rt	SHIFT		CONTROL		*/
+/* ac */ 0,		0,		0x52,		0x3f,
+/* ----- CAPS		COMPOSE		ALT Rt				*/
+/* b0 */ 0x40,		0x67,		0,		0,
+/* ----- 								*/
+/* b4 */ 0,		0,		0,		0,
+/* ----- 								*/
+/* b8 */ 0,		0,		0,		0,
+/* ----- BKSP		RET		TAB		`		*/
+/* bc */ 0x22,		0x37,		0x2a,		0x15,
+/* ----- 1		q		a		z		*/
+/* c0 */ 0x16,		0x2b,		0x41,		0x54,
+/* ----- 		2		w		s		*/
+/* c4 */ 0,		0x17,		0x2c,		0x42,
+/* ----- x		</\\				3		*/
+/* c8 */ 0x55,		0x53,		0,		0x18,
+/* ----- e		d		c				*/
+/* cc */ 0x2d,		0x43,		0x56,		0,
+/* ----- 4		r		f		v		*/
+/* d0 */ 0x19,		0x2e,		0x44,		0x57,
+/* ----- SPACE				5		t		*/
+/* d4 */ 0x68,		0,		0x1a,		0x2f,
+/* ----- g		b				6		*/
+/* d8 */ 0x45,		0x58,		0,		0x1b,
+/* ----- y		h		n				*/
+/* dc */ 0x30,		0x46,		0x59,		0,
+/* ----- 7		u		j		m		*/
+/* e0 */ 0x1c,		0x31,		0x47,		0x5a,
+/* ----- 		8		i		k		*/
+/* e4 */ 0,		0x1d,		0x32,		0x48,
+/* ----- ,				9		o		*/
+/* e8 */ 0x5b,		0,		0x1e,		0x33,
+/* ----- l		.				0		*/
+/* ec */ 0x49,		0x5c,		0,		0x1f,
+/* ----- p				;		/		*/
+/* f0 */ 0x34,		0,		0x4a,		0x5d,
+/* ----- 		=		]		\\/\'		*/
+/* f4 */ 0,		0x21,		0x36,		0x4c,
+/* ----- 		-		[		\'		*/
+/* f8 */ 0,		0x20,		0x35,		0x4b,
+/* ----- 								*/
+/* fc */ 0,		0,		0,		0,
+};
+
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/lk201.c linux/drivers/tc/lk201.c
--- v2.4.9/linux/drivers/tc/lk201.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/tc/lk201.c	Mon Aug 27 08:56:31 2001
@@ -0,0 +1,237 @@
+/*
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/kbd_ll.h>
+#include <asm/wbflush.h>
+#include <asm/dec/tc.h>
+#include <asm/dec/machtype.h>
+
+#include "zs.h"
+#include "lk201.h"
+
+/* Simple translation table for the SysRq keys */
+
+#ifdef CONFIG_MAGIC_SYSRQ
+/*
+ * Actually no translation at all, at least until we figure out
+ * how to define SysRq for LK201 and friends. --macro
+ */
+unsigned char lk201_sysrq_xlate[128];
+unsigned char *kbd_sysrq_xlate = lk201_sysrq_xlate;
+#endif
+
+#define KEYB_LINE	3
+
+static int __init lk201_init(struct dec_serial *);
+static void __init lk201_info(struct dec_serial *);
+static void lk201_kbd_rx_char(unsigned char, unsigned char);
+
+struct zs_hook lk201_kbdhook = {
+	init_channel:   lk201_init,
+	init_info:      lk201_info,
+	rx_char:        NULL,
+	poll_rx_char:   NULL,
+	poll_tx_char:   NULL,
+	cflags:         B4800 | CS8 | CSTOPB | CLOCAL
+};
+
+/*
+ * This is used during keyboard initialisation
+ */
+static unsigned char lk201_reset_string[] = {
+	LK_CMD_LEDS_ON, LK_PARAM_LED_MASK(0xf),	/* show we are resetting */
+	LK_CMD_SET_DEFAULTS,
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 1),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 2),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 3),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 4),
+	LK_CMD_MODE(LK_MODE_DOWN_UP, 5),
+	LK_CMD_MODE(LK_MODE_DOWN_UP, 6),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 7),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 8),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 9),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 10),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 11),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 12),
+	LK_CMD_MODE(LK_MODE_DOWN, 13),
+	LK_CMD_MODE(LK_MODE_RPT_DOWN, 14),
+	LK_CMD_ENB_RPT,
+	LK_CMD_DIS_KEYCLK,
+	LK_CMD_RESUME,
+	LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4),
+	LK_CMD_LEDS_OFF, LK_PARAM_LED_MASK(0xf)
+};
+
+static int __init lk201_reset(struct dec_serial *info)
+{
+	int i;
+
+	for (i = 0; i < sizeof(lk201_reset_string); i++)
+		if (info->hook->poll_tx_char(info, lk201_reset_string[i])) {
+			printk(__FUNCTION__" transmit timeout\n");
+			return -EIO;
+		}
+	return 0;
+}
+
+void kbd_leds(unsigned char leds)
+{
+	return;
+}
+
+int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
+{
+	return -EINVAL;
+}
+
+int kbd_getkeycode(unsigned int scancode)
+{
+	return -EINVAL;
+}
+
+int kbd_translate(unsigned char scancode, unsigned char *keycode,
+		  char raw_mode)
+{
+	*keycode = scancode;
+	return 1;
+}
+
+char kbd_unexpected_up(unsigned char keycode)
+{
+	return 0x80;
+}
+
+static void lk201_kbd_rx_char(unsigned char ch, unsigned char stat)
+{
+	static int shift_state = 0;
+	static int prev_scancode;
+	unsigned char c = scancodeRemap[ch];
+
+	if (!stat || stat == 4) {
+		switch (ch) {
+		case LK_KEY_ACK:
+			break;
+		case LK_KEY_LOCK:
+			shift_state ^= LK_LOCK;
+			handle_scancode(c, shift_state && LK_LOCK ? 1 : 0);
+			break;
+		case LK_KEY_SHIFT:
+			shift_state ^= LK_SHIFT;
+			handle_scancode(c, shift_state && LK_SHIFT ? 1 : 0);
+			break;
+		case LK_KEY_CTRL:
+			shift_state ^= LK_CTRL;
+			handle_scancode(c, shift_state && LK_CTRL ? 1 : 0);
+			break;
+		case LK_KEY_COMP:
+			shift_state ^= LK_COMP;
+			handle_scancode(c, shift_state && LK_COMP ? 1 : 0);
+			break;
+		case LK_KEY_RELEASE:
+			if (shift_state & LK_SHIFT)
+				handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
+			if (shift_state & LK_CTRL)
+				handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
+			if (shift_state & LK_COMP)
+				handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
+			if (shift_state & LK_LOCK)
+				handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
+			shift_state = 0;
+			break;
+		case LK_KEY_REPEAT:
+			handle_scancode(prev_scancode, 1);
+			break;
+		default:
+			prev_scancode = c;
+			handle_scancode(c, 1);
+			break;
+		}
+	} else
+		printk("Error reading LKx01 keyboard: 0x%02x\n", stat);
+}
+
+static void __init lk201_info(struct dec_serial *info)
+{
+}
+
+static int __init lk201_init(struct dec_serial *info)
+{
+	unsigned int ch, id = 0;
+	int result;
+
+	printk("DECstation LK keyboard driver v0.04... ");
+
+	result = lk201_reset(info);
+	if (result)
+		return result;
+	mdelay(10);
+
+	/*
+	 * Detect whether there is an LK201 or an LK401
+	 * The LK401 has ALT keys...
+	 */
+	info->hook->poll_tx_char(info, LK_CMD_REQ_ID);
+	while ((ch = info->hook->poll_rx_char(info)) > 0)
+		id = ch;
+
+	switch (id) {
+	case 1:
+		printk("LK201 detected\n");
+		break;
+	case 2:
+		printk("LK401 detected\n");
+		break;
+	default:
+		printk("unknown keyboard, ID %d,\n", id);
+		printk("... please report to <linux-mips@oss.sgi.com>\n");
+	}
+
+	/*
+	 * now we're ready
+	 */
+	info->hook->rx_char = lk201_kbd_rx_char;
+
+	return 0;
+}
+
+void __init kbd_init_hw(void)
+{
+	extern int register_zs_hook(unsigned int, struct zs_hook *);
+	extern int unregister_zs_hook(unsigned int);
+
+	if (TURBOCHANNEL) {
+		if (mips_machtype != MACH_DS5000_XX) {
+			/*
+			 * This is not a MAXINE, so:
+			 *
+			 * kbd_init_hw() is being called before
+			 * rs_init() so just register the kbd hook
+			 * and let zs_init do the rest :-)
+			 */
+			if (mips_machtype == MACH_DS5000_200)
+				printk("LK201 Support for DS5000/200 not yet ready ...\n");
+			else
+				if(!register_zs_hook(KEYB_LINE, &lk201_kbdhook))
+					unregister_zs_hook(KEYB_LINE);
+		}
+	} else {
+		/*
+		 * TODO: modify dz.c to allow similar hooks
+		 * for LK201 handling on DS2100, DS3100, and DS5000/200
+		 */
+		printk("LK201 Support for DS3100 not yet ready ...\n");
+	}
+}
+
+
+
+
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/lk201.h linux/drivers/tc/lk201.h
--- v2.4.9/linux/drivers/tc/lk201.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/tc/lk201.h	Mon Aug 27 08:56:31 2001
@@ -0,0 +1,53 @@
+/*
+ *	Commands to the keyboard processor
+ */
+
+#define	LK_PARAM		0x80	/* start/end parameter list */
+
+#define	LK_CMD_RESUME		0x8b
+#define	LK_CMD_INHIBIT		0xb9
+#define	LK_CMD_LEDS_ON		0x13	/* 1 param: led bitmask */
+#define	LK_CMD_LEDS_OFF		0x11	/* 1 param: led bitmask */
+#define	LK_CMD_DIS_KEYCLK	0x99
+#define	LK_CMD_ENB_KEYCLK	0x1b	/* 1 param: volume */
+#define	LK_CMD_DIS_CTLCLK	0xb9
+#define	LK_CMD_ENB_CTLCLK	0xbb
+#define	LK_CMD_SOUND_CLK	0x9f
+#define	LK_CMD_DIS_BELL		0xa1
+#define	LK_CMD_ENB_BELL		0x23	/* 1 param: volume */
+#define	LK_CMD_BELL		0xa7
+#define	LK_CMD_TMP_NORPT	0xc1
+#define	LK_CMD_ENB_RPT		0xe3
+#define	LK_CMD_DIS_RPT		0xe1
+#define	LK_CMD_RPT_TO_DOWN	0xd9
+#define	LK_CMD_REQ_ID		0xab
+#define	LK_CMD_POWER_UP		0xfd
+#define	LK_CMD_TEST_MODE	0xcb
+#define	LK_CMD_SET_DEFAULTS	0xd3
+
+/* there are 4 leds, represent them in the low 4 bits of a byte */
+#define	LK_PARAM_LED_MASK(ledbmap)	(LK_PARAM|(ledbmap))
+
+/* max volume is 0, lowest is 0x7 */
+#define	LK_PARAM_VOLUME(v)		(LK_PARAM|((v)&0x7))
+
+/* mode set command(s) details */
+#define	LK_MODE_DOWN		0x0
+#define	LK_MODE_RPT_DOWN	0x2
+#define	LK_MODE_DOWN_UP		0x6
+#define	LK_CMD_MODE(m,div)	(LK_PARAM|(div<<3)|m)
+
+#define LK_SHIFT 1<<0
+#define LK_CTRL 1<<1
+#define LK_LOCK 1<<2
+#define LK_COMP 1<<3
+
+#define LK_KEY_SHIFT 174
+#define LK_KEY_CTRL 175
+#define LK_KEY_LOCK 176
+#define LK_KEY_COMP 177
+#define LK_KEY_RELEASE 179
+#define LK_KEY_REPEAT 180
+#define LK_KEY_ACK 186
+
+extern unsigned char scancodeRemap[256];
\ No newline at end of file
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/tc.c linux/drivers/tc/tc.c
--- v2.4.9/linux/drivers/tc/tc.c	Sat May 13 08:31:25 2000
+++ linux/drivers/tc/tc.c	Mon Aug 27 08:56:31 2001
@@ -1,4 +1,4 @@
-/* $Id: tc.c,v 1.3 1999/10/09 00:01:32 ralf Exp $
+/*
  * tc-init: We assume the TURBOchannel to be up and running so
  * just probe for Modules and fill in the global data structure
  * tc_bus.
@@ -8,9 +8,7 @@
  * for more details.
  *
  * Copyright (c) Harald Koerfgen, 1998
- *
  */
-
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
@@ -23,14 +21,15 @@
 
 #include <asm/ptrace.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 
 #define TC_DEBUG
 
 slot_info tc_bus[MAX_SLOT];
-static int max_tcslot = 0;
-static tcinfo *info = (tcinfo *)0;
+static int max_tcslot;
+static tcinfo *info;
 
-unsigned long system_base = 0;
+unsigned long system_base;
 
 extern void (*dbe_board_handler)(struct pt_regs *regs);
 extern unsigned long *(*rex_slot_address)(int);
@@ -112,19 +111,19 @@
 	for (slot = 0; slot <= max_slot; slot++) {
 		module = (char *)(startaddr + slot * size);
 		offset = -1;
-		if (module[OLDCARD + PATTERN0] == 0x55 && module[OLDCARD + PATTERN1] == 0x00
-		  && module[OLDCARD + PATTERN2] == 0xaa && module[OLDCARD + PATTERN3] == 0xff)
+		if (module[OLDCARD + TC_PATTERN0] == 0x55 && module[OLDCARD + TC_PATTERN1] == 0x00
+		  && module[OLDCARD + TC_PATTERN2] == 0xaa && module[OLDCARD + TC_PATTERN3] == 0xff)
 			offset = OLDCARD;
-		if (module[PATTERN0] == 0x55 && module[PATTERN1] == 0x00
-		  && module[PATTERN2] == 0xaa && module[PATTERN3] == 0xff)
+		if (module[TC_PATTERN0] == 0x55 && module[TC_PATTERN1] == 0x00
+		  && module[TC_PATTERN2] == 0xaa && module[TC_PATTERN3] == 0xff)
 			offset = 0;
 
 		if (offset != -1) {
 			tc_bus[slot].base_addr = (unsigned long)module;
 			for(i = 0; i < 8; i++) {
-				tc_bus[slot].firmware[i] = module[FIRM_VER + offset + 4 * i];
-				tc_bus[slot].vendor[i] = module[VENDOR + offset + 4 * i];
-				tc_bus[slot].name[i] = module[MODULE + offset + 4 * i];
+				tc_bus[slot].firmware[i] = module[TC_FIRM_VER + offset + 4 * i];
+				tc_bus[slot].vendor[i] = module[TC_VENDOR + offset + 4 * i];
+				tc_bus[slot].name[i] = module[TC_MODULE + offset + 4 * i];
 			}
 			tc_bus[slot].firmware[8] = 0;
 			tc_bus[slot].vendor[8] = 0;
@@ -206,7 +205,7 @@
 	if (TURBOCHANNEL && info->slot_size && slot0addr) {
 		printk("TURBOchannel rev. %1d at %2d.%1d MHz ", info->revision,
 			tc_clock / 10, tc_clock % 10);
-		printk("(%sparity)\n", info->parity ? "" : "no ");
+		printk("(with%s parity)\n", info->parity ? "" : "out");
 
 		slot_size = info->slot_size << 20;
 
@@ -235,3 +234,11 @@
 		ioport_resource.end = KSEG2 - 1;
 	}
 }
+
+EXPORT_SYMBOL(search_tc_card);
+EXPORT_SYMBOL(claim_tc_card);
+EXPORT_SYMBOL(release_tc_card);
+EXPORT_SYMBOL(get_tc_base_addr);
+EXPORT_SYMBOL(get_tc_irq_nr);
+EXPORT_SYMBOL(get_tc_speed);
+
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/tcsyms.c linux/drivers/tc/tcsyms.c
--- v2.4.9/linux/drivers/tc/tcsyms.c	Sat May 13 08:31:25 2000
+++ linux/drivers/tc/tcsyms.c	Wed Dec 31 16:00:00 1969
@@ -1,14 +0,0 @@
-/*
- *	TURBOchannel Services -- Exported Symbols
- *
- */
-
-#include <linux/module.h>
-#include <asm/dec/tc.h>
-
-EXPORT_SYMBOL(search_tc_card);
-EXPORT_SYMBOL(claim_tc_card);
-EXPORT_SYMBOL(release_tc_card);
-EXPORT_SYMBOL(get_tc_base_addr);
-EXPORT_SYMBOL(get_tc_irq_nr);
-EXPORT_SYMBOL(get_tc_speed);
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/zs.c linux/drivers/tc/zs.c
--- v2.4.9/linux/drivers/tc/zs.c	Thu Oct 12 14:20:47 2000
+++ linux/drivers/tc/zs.c	Mon Aug 27 08:56:31 2001
@@ -1,22 +1,46 @@
 /*
- * decserial.c: Serial port driver for IOASIC DECsatations.
+ * decserial.c: Serial port driver for IOASIC DECstations.
  *
- * Derived from drivers/macintosh/macserial.c by Harald Koerfgen.
  * Derived from drivers/sbus/char/sunserial.c by Paul Mackerras.
+ * Derived from drivers/macintosh/macserial.c by Harald Koerfgen.
  *
  * DECstation changes
- * Copyright (C) 1998 Harald Koerfgen (Harald.Koerfgen@home.ivm.de)
+ * Copyright (C) 1998-2000 Harald Koerfgen
+ * Copyright (C) 2000,2001 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
  *
  * For the rest of the code the original Copyright applies:
  * Copyright (C) 1996 Paul Mackerras (Paul.Mackerras@cs.anu.edu.au)
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  *
- * Keyboard and mouse are not supported right now. If you want to change this,
- * you might want to have a look at drivers/sbus/char/sunserial.c to see
- * how this might be done. HK
+ *
+ * Note: for IOASIC systems the wiring is as follows:
+ *
+ * mouse/keyboard:
+ * DIN-7 MJ-4  signal        SCC
+ * 2     1     TxD       <-  A.TxD
+ * 3     4     RxD       ->  A.RxD
+ *
+ * EIA-232/EIA-423:
+ * DB-25 MMJ-6 signal        SCC
+ * 2     2     TxD       <-  B.TxD
+ * 3     5     RxD       ->  B.RxD
+ * 4           RTS       <- ~A.RTS
+ * 5           CTS       -> ~B.CTS
+ * 6     6     DSR       -> ~A.SYNC
+ * 8           CD        -> ~B.DCD
+ * 12          DSRS(DCE) -> ~A.CTS  (*)
+ * 15          TxC       ->  B.TxC
+ * 17          RxC       ->  B.RxC
+ * 20    1     DTR       <- ~A.DTR
+ * 22          RI        -> ~A.DCD
+ * 23          DSRS(DTE) <- ~B.RTS
+ *
+ * (*) EIA-232 defines the signal at this pin to be SCD, while DSRS(DCE)
+ *     is shared with DSRS(DTE) at pin 23.
  */
 
 #include <linux/config.h>
+#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
@@ -31,6 +55,7 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/ioport.h>
 #ifdef CONFIG_SERIAL_CONSOLE
 #include <linux/console.h>
 #endif
@@ -43,17 +68,26 @@
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
 #include <asm/wbflush.h>
+#include <asm/bootinfo.h>
+#ifdef CONFIG_DECSTATION
 #include <asm/dec/interrupts.h>
 #include <asm/dec/machtype.h>
 #include <asm/dec/tc.h>
 #include <asm/dec/ioasic_addrs.h>
+#endif
+#ifdef CONFIG_BAGET_MIPS
+#include <asm/baget/baget.h>
+unsigned long system_base;
+#endif
 #ifdef CONFIG_KGDB
 #include <asm/kgdb.h>
 #endif
+#ifdef CONFIG_MAGIC_SYSRQ
+#include <linux/sysrq.h>
+#endif
 
 #include "zs.h"
 
-
 /*
  * It would be nice to dynamically allocate everything that
  * depends on NUM_SERIAL, so we could support any number of
@@ -61,11 +95,60 @@
  */
 #define NUM_SERIAL	2		/* Max number of ZS chips supported */
 #define NUM_CHANNELS	(NUM_SERIAL * 2)	/* 2 channels per chip */
+#define CHANNEL_A_NR  (zs_parms->channel_a_offset > zs_parms->channel_b_offset)
+                                        /* Number of channel A in the chip */ 
+#define ZS_CHAN_IO_SIZE 8
+#define ZS_CLOCK        7372800 	/* Z8530 RTxC input clock rate */
 
 #define RECOVERY_DELAY  udelay(2)
 
-struct dec_zschannel zs_channels[NUM_CHANNELS];
+struct zs_parms {
+	unsigned long scc0;
+	unsigned long scc1;
+	int channel_a_offset;
+	int channel_b_offset;
+	int irq;
+	int clock;
+};
 
+static struct zs_parms *zs_parms;
+
+#ifdef CONFIG_DECSTATION
+static struct zs_parms ds_parms = {
+	scc0 : SCC0,
+	scc1 : SCC1,
+	channel_a_offset : 1,
+	channel_b_offset : 9,
+	irq : SERIAL,
+	clock : ZS_CLOCK
+};
+#endif
+#ifdef CONFIG_BAGET_MIPS
+static struct zs_parms baget_parms = {
+	scc0 : UNI_SCC0,
+	scc1 : UNI_SCC1,
+	channel_a_offset : 9,
+	channel_b_offset : 1,
+	irq : BAGET_SCC_IRQ,
+	clock : 14745000
+};
+#endif
+
+#ifdef CONFIG_DECSTATION
+#define DS_BUS_PRESENT (IOASIC)
+#else
+#define DS_BUS_PRESENT 0
+#endif
+
+#ifdef CONFIG_BAGET_MIPS
+#define BAGET_BUS_PRESENT (mips_machtype == MACH_BAGET202)
+#else
+#define BAGET_BUS_PRESENT 0
+#endif
+
+#define BUS_PRESENT (DS_BUS_PRESENT || BAGET_BUS_PRESENT)
+
+struct dec_zschannel zs_channels[NUM_CHANNELS];
 struct dec_serial zs_soft[NUM_CHANNELS];
 int zs_channels_found;
 struct dec_serial *zs_chain;	/* list of all channels */
@@ -75,19 +158,9 @@
 #ifdef CONFIG_SERIAL_CONSOLE
 static struct console sercons;
 #endif
-
-#ifdef CONFIG_KGDB
-struct dec_zschannel *zs_kgdbchan;
-static unsigned char scc_inittab[] = {
-	9,  0x80,	/* reset A side (CHRA) */
-	13, 0,		/* set baud rate divisor */
-	12, 1,
-	14, 1,		/* baud rate gen enable, src=rtxc (BRENABL) */
-	11, 0x50,	/* clocks = br gen (RCBR | TCBR) */
-	5,  0x6a,	/* tx 8 bits, assert RTS (Tx8 | TxENAB | RTS) */
-	4,  0x44,	/* x16 clock, 1 stop (SB1 | X16CLK)*/
-	3,  0xc1,	/* rx enable, 8 bits (RxENABLE | Rx8)*/
-};
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) \
+    && !defined(MODULE)
+static unsigned long break_pressed; /* break, really ... */
 #endif
 
 static unsigned char zs_init_regs[16] __initdata = {
@@ -106,8 +179,6 @@
 	0 			     /* write 15 */
 };
 
-#define ZS_CLOCK         7372800 	/* Z8530 RTxC input clock rate */
-
 DECLARE_TASK_QUEUE(tq_zs_serial);
 
 struct tty_driver serial_driver, callout_driver;
@@ -129,6 +200,12 @@
 #undef SERIAL_DEBUG_THROTTLE
 #undef SERIAL_PARANOIA_CHECK
 
+#undef ZS_DEBUG_REGS
+
+#ifdef SERIAL_DEBUG_THROTTLE
+#define _tty_name(tty,buf) tty_name(tty,buf)
+#endif
+
 #define RS_STROBE_TIME 10
 #define RS_ISR_PASS_LIMIT 256
 
@@ -184,7 +261,7 @@
  */
 static int baud_table[] = {
 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
-	9600, 19200, 38400, 57600, 0, 0 };
+	9600, 19200, 38400, 57600, 115200, 0 };
 
 /* 
  * Reading and writing Z8530 registers.
@@ -256,16 +333,21 @@
 }
 
 /* Sets or clears DTR/RTS on the requested line */
-static inline void zs_rtsdtr(struct dec_serial *ss, int set)
+static inline void zs_rtsdtr(struct dec_serial *info, int which, int set)
 {
-	if (ss->zs_channel != ss->zs_chan_a) {
-		if (set)
-			ss->zs_chan_a->curregs[5] |= (RTS | DTR);
-		else
-			ss->zs_chan_a->curregs[5] &= ~(RTS | DTR);
-		write_zsreg(ss->zs_chan_a, 5, ss->zs_chan_a->curregs[5]);
+        unsigned long flags;
+
+
+	save_flags(flags); cli();
+	if (info->zs_channel != info->zs_chan_a) {
+		if (set) {
+			info->zs_chan_a->curregs[5] |= (which & (RTS | DTR));
+		} else {
+			info->zs_chan_a->curregs[5] &= ~(which & (RTS | DTR));
+		}
+		write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]);
 	}
-	return;
+	restore_flags(flags);
 }
 
 /* Utility routines for the Zilog */
@@ -281,7 +363,7 @@
 	 */
 	brg = (read_zsreg(channel, 13) << 8);
 	brg |= read_zsreg(channel, 12);
-	return BRG_TO_BPS(brg, (ZS_CLOCK/(ss->clk_divisor)));
+	return BRG_TO_BPS(brg, (zs_parms->clock/(ss->clk_divisor)));
 }
 
 /* On receive, this clears errors and the receiver interrupts */
@@ -302,6 +384,8 @@
  * -----------------------------------------------------------------------
  */
 
+static int tty_break;	/* Set whenever BREAK condition is detected.  */
+
 /*
  * This routine is used by the interrupt handler to schedule
  * processing in the software interrupt portion of the driver.
@@ -320,23 +404,59 @@
 	struct tty_struct *tty = info->tty;
 	unsigned char ch, stat, flag;
 
-	while ((read_zsreg(info->zs_channel, 0) & Rx_CH_AV) != 0) {
+	while ((read_zsreg(info->zs_channel, R0) & Rx_CH_AV) != 0) {
 
 		stat = read_zsreg(info->zs_channel, R1);
 		ch = read_zsdata(info->zs_channel);
 
-#ifdef CONFIG_KGDB
-		if (info->kgdb_channel) {
-			if (ch == 0x03 || ch == '$')
-				breakpoint();
-			if (stat & (Rx_OVR|FRM_ERR|PAR_ERR))
-				write_zsreg(info->zs_channel, 0, ERR_RES);
-			return;
+		if (!tty && !info->hook && !info->hook->rx_char)
+			continue;
+
+		if (tty_break) {
+			tty_break = 0;
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
+			if (info->line == sercons.index) {
+				if (!break_pressed) {
+					break_pressed = jiffies;
+					goto ignore_char;
+				}
+				break_pressed = 0;
+			}
+#endif
+			flag = TTY_BREAK;
+			if (info->flags & ZILOG_SAK)
+				do_SAK(tty);
+		} else {
+			if (stat & Rx_OVR) {
+				flag = TTY_OVERRUN;
+			} else if (stat & FRM_ERR) {
+				flag = TTY_FRAME;
+			} else if (stat & PAR_ERR) {
+				flag = TTY_PARITY;
+			} else
+				flag = 0;
+			if (flag)
+				/* reset the error indication */
+				write_zsreg(info->zs_channel, R0, ERR_RES);
+		}
+
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) && !defined(MODULE)
+		if (break_pressed && info->line == sercons.index) {
+			if (ch != 0 &&
+			    time_before(jiffies, break_pressed + HZ*5)) {
+				handle_sysrq(ch, regs, NULL, NULL);
+				break_pressed = 0;
+				goto ignore_char;
+			}
+			break_pressed = 0;
 		}
 #endif
-		if (!tty)
-			continue;
 
+		if (info->hook && info->hook->rx_char) {
+			(*info->hook->rx_char)(ch, flag);
+			return;
+  		}
+		
 		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
 			static int flip_buf_ovf;
 			++flip_buf_ovf;
@@ -348,26 +468,18 @@
 			if (flip_max_cnt < tty->flip.count)
 				flip_max_cnt = tty->flip.count;
 		}
-		if (stat & Rx_OVR) {
-			flag = TTY_OVERRUN;
-		} else if (stat & FRM_ERR) {
-			flag = TTY_FRAME;
-		} else if (stat & PAR_ERR) {
-			flag = TTY_PARITY;
-		} else
-			flag = 0;
-		if (flag)
-			/* reset the error indication */
-			write_zsreg(info->zs_channel, 0, ERR_RES);
+
 		*tty->flip.flag_buf_ptr++ = flag;
 		*tty->flip.char_buf_ptr++ = ch;
+	ignore_char:
 	}
-	tty_flip_buffer_push(tty);
+	if (tty)
+		tty_flip_buffer_push(tty);
 }
 
 static void transmit_chars(struct dec_serial *info)
 {
-	if ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP) == 0)
+	if ((read_zsreg(info->zs_channel, R0) & Tx_BUF_EMP) == 0)
 		return;
 	info->tx_active = 0;
 
@@ -379,8 +491,9 @@
 		return;
 	}
 
-	if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tx_stopped) {
-		write_zsreg(info->zs_channel, 0, RES_Tx_P);
+	if ((info->xmit_cnt <= 0) || (info->tty && info->tty->stopped)
+	    || info->tx_stopped) {
+		write_zsreg(info->zs_channel, R0, RES_Tx_P);
 		return;
 	}
 	/* Send char */
@@ -395,45 +508,48 @@
 
 static _INLINE_ void status_handle(struct dec_serial *info)
 {
-	unsigned char status;
+	unsigned char stat;
 
 	/* Get status from Read Register 0 */
-	status = read_zsreg(info->zs_channel, 0);
+	stat = read_zsreg(info->zs_channel, R0);
+
+	if (stat & BRK_ABRT) {
+#ifdef SERIAL_DEBUG_INTR
+		printk("handling break....");
+#endif
+		tty_break = 1;
+	}
 
-	/* FIXEM: Check for DCD transitions */
-	if (((status ^ info->read_reg_zero) & DCD) != 0
-	    && info->tty && !C_CLOCAL(info->tty)) {
-		if (status & DCD) {
-			wake_up_interruptible(&info->open_wait);
-		} else if (!(info->flags & ZILOG_CALLOUT_ACTIVE)) {
-			if (info->tty)
+	if (info->zs_channel != info->zs_chan_a) {
+
+		/* FIXEM: Check for DCD transitions */
+		if (((stat ^ info->read_reg_zero) & DCD) != 0
+		    && info->tty && !C_CLOCAL(info->tty)) {
+			if (stat & DCD) {
+				wake_up_interruptible(&info->open_wait);
+			} else if (!(info->flags & ZILOG_CALLOUT_ACTIVE)) {
 				tty_hangup(info->tty);
+			}
 		}
-	}
 
-	/* Check for CTS transitions */
-	if (info->tty && C_CRTSCTS(info->tty)) {
-		/*
-		 * For some reason, on the Power Macintosh,
-		 * it seems that the CTS bit is 1 when CTS is
-		 * *negated* and 0 when it is asserted.
-		 * The DCD bit doesn't seem to be inverted
-		 * like this.
-		 */
-		if ((status & CTS) != 0) {
-			if (info->tx_stopped) {
-				info->tx_stopped = 0;
-				if (!info->tx_active)
-					transmit_chars(info);
+		/* Check for CTS transitions */
+		if (info->tty && C_CRTSCTS(info->tty)) {
+			if ((stat & CTS) != 0) {
+				if (info->tx_stopped) {
+					info->tx_stopped = 0;
+					if (!info->tx_active)
+						transmit_chars(info);
+				}
+			} else {
+				info->tx_stopped = 1;
 			}
-		} else {
-			info->tx_stopped = 1;
 		}
+
 	}
 
 	/* Clear status condition... */
-	write_zsreg(info->zs_channel, 0, RES_EXT_INT);
-	info->read_reg_zero = status;
+	write_zsreg(info->zs_channel, R0, RES_EXT_INT);
+	info->read_reg_zero = stat;
 }
 
 /*
@@ -459,7 +575,7 @@
 		shift = 0;	/* Channel B */
 
 	for (;;) {
-		zs_intreg = read_zsreg(info->zs_chan_a, 3) >> shift; 
+		zs_intreg = read_zsreg(info->zs_chan_a, R3) >> shift; 
 		if ((zs_intreg & CHAN_IRQMASK) == 0)
 			break;
 
@@ -473,8 +589,31 @@
 			status_handle(info);
 		}
 	}
+	
+	/* Why do we need this ? */
+	write_zsreg(info->zs_channel, 0, RES_H_IUS);
 }
 
+#ifdef ZS_DEBUG_REGS
+void zs_dump (void) {
+	int i, j;
+	for (i = 0; i < zs_channels_found; i++) {
+		struct dec_zschannel *ch = &zs_channels[i]; 
+		if ((long)ch->control == UNI_IO_BASE+UNI_SCC1A_CTRL) {
+			for (j = 0; j < 15; j++) {
+				printk("W%d = 0x%x\t", 
+				       j, (int)ch->curregs[j]);
+			}
+			for (j = 0; j < 15; j++) {
+				printk("R%d = 0x%x\t", 
+				       j, (int)read_zsreg(ch,j));
+			}
+			printk("\n\n");
+		}
+	}
+}
+#endif
+
 /*
  * -------------------------------------------------------------------
  * Here ends the serial interrupt routines.
@@ -559,7 +698,7 @@
 	}
 }
 
-static int startup(struct dec_serial * info)
+int zs_startup(struct dec_serial * info)
 {
 	unsigned long flags;
 
@@ -575,7 +714,7 @@
 	save_flags(flags); cli();
 
 #ifdef SERIAL_DEBUG_OPEN
-	printk("starting up ttyS%d (irq %d)...", info->line, info->irq);
+	printk("starting up ttyS%02d (irq %d)...", info->line, info->irq);
 #endif
 
 	/*
@@ -593,7 +732,7 @@
 	/*
 	 * Turn on RTS and DTR.
 	 */
-	zs_rtsdtr(info, 1);
+	zs_rtsdtr(info, RTS | DTR, 1);
 
 	/*
 	 * Finally, enable sequencing and interrupts
@@ -664,8 +803,7 @@
 	info->zs_channel->curregs[5] &= ~TxENAB;
 	write_zsreg(info->zs_channel, 5, info->zs_channel->curregs[5]);
 	if (!info->tty || C_HUPCL(info->tty)) {
-		info->zs_chan_a->curregs[5] &= ~(DTR | RTS);
-		write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]);
+		zs_rtsdtr(info, RTS | DTR, 0);
 	}
 
 	if (info->tty)
@@ -681,29 +819,45 @@
  */
 static void change_speed(struct dec_serial *info)
 {
-	unsigned short port;
 	unsigned cflag;
 	int	i;
-	int	brg;
+	int	brg, bits;
 	unsigned long flags;
 
-	if (!info->tty || !info->tty->termios)
-		return;
-	cflag = info->tty->termios->c_cflag;
-	if (!(port = info->port))
-		return;
+	if (!info->hook) {
+		if (!info->tty || !info->tty->termios)
+			return;
+		cflag = info->tty->termios->c_cflag;
+		if (!info->port)
+			return;
+	} else {
+		cflag = info->hook->cflags;
+	}
+
 	i = cflag & CBAUD;
+	if (i & CBAUDEX) {
+		i &= ~CBAUDEX;
+		if (i < 1 || i > 2) {
+			if (!info->hook)
+				info->tty->termios->c_cflag &= ~CBAUDEX;
+			else
+				info->hook->cflags &= ~CBAUDEX;
+		} else
+			i += 15;
+	}
 
 	save_flags(flags); cli();
 	info->zs_baud = baud_table[i];
 	info->clk_divisor = 16;
-
-	switch (info->zs_baud) {
-	default:
+	if (info->zs_baud) {
 		info->zs_channel->curregs[4] = X16CLK;
-		brg = BPS_TO_BRG(info->zs_baud, ZS_CLOCK/info->clk_divisor);
+		brg = BPS_TO_BRG(info->zs_baud, zs_parms->clock/info->clk_divisor);
 		info->zs_channel->curregs[12] = (brg & 255);
 		info->zs_channel->curregs[13] = ((brg >> 8) & 255);
+		zs_rtsdtr(info, DTR, 1); 
+	} else {
+		zs_rtsdtr(info, RTS | DTR, 0);
+		return;
 	}
 
 	/* byte size and parity */
@@ -711,24 +865,31 @@
 	info->zs_channel->curregs[5] &= ~TxNBITS_MASK;
 	switch (cflag & CSIZE) {
 	case CS5:
+		bits = 7;
 		info->zs_channel->curregs[3] |= Rx5;
 		info->zs_channel->curregs[5] |= Tx5;
 		break;
 	case CS6:
+		bits = 8;
 		info->zs_channel->curregs[3] |= Rx6;
 		info->zs_channel->curregs[5] |= Tx6;
 		break;
 	case CS7:
+		bits = 9;
 		info->zs_channel->curregs[3] |= Rx7;
 		info->zs_channel->curregs[5] |= Tx7;
 		break;
 	case CS8:
 	default: /* defaults to 8 bits */
+		bits = 10;
 		info->zs_channel->curregs[3] |= Rx8;
 		info->zs_channel->curregs[5] |= Tx8;
 		break;
 	}
 
+	info->timeout = ((info->xmit_fifo_size*HZ*bits) / info->zs_baud);
+        info->timeout += HZ/50;         /* Add .02 seconds of slop */
+
 	info->zs_channel->curregs[4] &= ~(SB_MASK | PAR_ENA | PAR_EVEN);
 	if (cflag & CSTOPB) {
 		info->zs_channel->curregs[4] |= SB2;
@@ -750,7 +911,7 @@
 		info->zs_channel->curregs[15] &= ~DCDIE;
 	if (cflag & CRTSCTS) {
 		info->zs_channel->curregs[15] |= CTSIE;
-		if ((read_zsreg(info->zs_channel, 0) & CTS) != 0)
+		if ((read_zsreg(info->zs_channel, 0) & CTS) == 0)
 			info->tx_stopped = 1;
 	} else {
 		info->zs_channel->curregs[15] &= ~CTSIE;
@@ -895,17 +1056,7 @@
 	}
 
 	if (C_CRTSCTS(tty)) {
-		/*
-		 * Here we want to turn off the RTS line.  On Macintoshes,
-		 * we only get the DTR line, which goes to both DTR and
-		 * RTS on the modem.  RTS doesn't go out to the serial
-		 * port socket.  So you should make sure your modem is
-		 * set to ignore DTR if you're using CRTSCTS.
-		 */
-		save_flags(flags); cli();
-		info->zs_chan_a->curregs[5] &= ~(DTR | RTS);
-		write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]);
-		restore_flags(flags);
+		zs_rtsdtr(info, RTS, 0);
 	}
 }
 
@@ -937,11 +1088,7 @@
 	}
 
 	if (C_CRTSCTS(tty)) {
-		/* Assert RTS and DTR lines */
-		save_flags(flags); cli();
-		info->zs_chan_a->curregs[5] |= DTR | RTS;
-		write_zsreg(info->zs_chan_a, 5, info->zs_chan_a->curregs[5]);
-		restore_flags(flags);
+		zs_rtsdtr(info, RTS, 1);
 	}
 }
 
@@ -983,7 +1130,7 @@
 	copy_from_user(&new_serial,new_info,sizeof(new_serial));
 	old_info = *info;
 
-	if (!suser()) {
+	if (!capable(CAP_SYS_ADMIN)) {
 		if ((new_serial.baud_base != info->baud_base) ||
 		    (new_serial.type != info->type) ||
 		    (new_serial.close_delay != info->close_delay) ||
@@ -1012,7 +1159,7 @@
 	info->closing_wait = new_serial.closing_wait;
 
 check_and_exit:
-	retval = startup(info);
+	retval = zs_startup(info);
 	return retval;
 }
 
@@ -1039,18 +1186,25 @@
 
 static int get_modem_info(struct dec_serial *info, unsigned int *value)
 {
-	unsigned char control, status;
+	unsigned char control, status_a, status_b;
 	unsigned int result;
 
-	cli();
-	control = info->zs_chan_a->curregs[5];
-	status = read_zsreg(info->zs_channel, 0);
-	sti();
-	result =  ((control & RTS) ? TIOCM_RTS: 0)
-		| ((control & DTR) ? TIOCM_DTR: 0)
-		| ((status  & DCD) ? TIOCM_CAR: 0)
-		| ((status  & CTS) ? 0: TIOCM_CTS);
-	put_user(result,value);
+	if (info->zs_channel == info->zs_chan_a)
+		result = 0;
+	else {
+		cli();
+		control = info->zs_chan_a->curregs[5];
+		status_a = read_zsreg(info->zs_chan_a, 0);
+		status_b = read_zsreg(info->zs_channel, 0);
+		sti();
+		result =  ((control  & RTS) ? TIOCM_RTS: 0)
+			| ((control  & DTR) ? TIOCM_DTR: 0)
+			| ((status_b & DCD) ? TIOCM_CAR: 0)
+			| ((status_a & DCD) ? TIOCM_RNG: 0)
+			| ((status_a & SYNC_HUNT) ? TIOCM_DSR: 0)
+			| ((status_b & CTS) ? TIOCM_CTS: 0);
+	}
+	put_user(result, value);
 	return 0;
 }
 
@@ -1063,6 +1217,10 @@
 	error = verify_area(VERIFY_READ, value, sizeof(int));
 	if (error)
 		return error;
+
+	if (info->zs_channel == info->zs_chan_a)
+		return 0;
+
 	get_user(arg, value);
 	bits = (arg & TIOCM_RTS? RTS: 0) + (arg & TIOCM_DTR? DTR: 0);
 	cli();
@@ -1074,7 +1232,8 @@
 		info->zs_chan_a->curregs[5] &= ~bits;
 		break;
 	case TIOCMSET:
-		info->zs_chan_a->curregs[5] = (info->zs_chan_a->curregs[5] & ~(DTR | RTS)) | bits;
+		info->zs_chan_a->curregs[5] = 
+			(info->zs_chan_a->curregs[5] & ~(DTR | RTS)) | bits;
 		break;
 	default:
 		sti();
@@ -1113,10 +1272,9 @@
 	int error;
 	struct dec_serial * info = (struct dec_serial *)tty->driver_data;
 
-#ifdef CONFIG_KGDB
-	if (info->kgdb_channel)
+	if (info->hook)
 		return -ENODEV;
-#endif
+
 	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
 		return -ENODEV;
 
@@ -1210,7 +1368,7 @@
 	}
 	
 #ifdef SERIAL_DEBUG_OPEN
-	printk("rs_close ttys%d, count = %d\n", info->line, info->count);
+	printk("rs_close ttyS%02d, count = %d\n", info->line, info->count);
 #endif
 	if ((tty->count == 1) && (info->count != 1)) {
 		/*
@@ -1225,7 +1383,7 @@
 		info->count = 1;
 	}
 	if (--info->count < 0) {
-		printk("rs_close: bad serial port count for ttys%d: %d\n",
+		printk("rs_close: bad serial port count for ttyS%02d: %d\n",
 		       info->line, info->count);
 		info->count = 0;
 	}
@@ -1415,7 +1573,7 @@
 	retval = 0;
 	add_wait_queue(&info->open_wait, &wait);
 #ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready before block: ttys%d, count = %d\n",
+	printk("block_til_ready before block: ttyS%02d, count = %d\n",
 	       info->line, info->count);
 #endif
 	cli();
@@ -1427,7 +1585,7 @@
 		cli();
 		if (!(info->flags & ZILOG_CALLOUT_ACTIVE) &&
 		    (tty->termios->c_cflag & CBAUD))
-			zs_rtsdtr(info, 1);
+			zs_rtsdtr(info, RTS | DTR, 1);
 		sti();
 		set_current_state(TASK_INTERRUPTIBLE);
 		if (tty_hung_up_p(filp) ||
@@ -1451,7 +1609,7 @@
 			break;
 		}
 #ifdef SERIAL_DEBUG_OPEN
-		printk("block_til_ready blocking: ttys%d, count = %d\n",
+		printk("block_til_ready blocking: ttyS%02d, count = %d\n",
 		       info->line, info->count);
 #endif
 		schedule();
@@ -1462,7 +1620,7 @@
 		info->count++;
 	info->blocked_open--;
 #ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready after blocking: ttys%d, count = %d\n",
+	printk("block_til_ready after blocking: ttyS%02d, count = %d\n",
 	       info->line, info->count);
 #endif
 	if (retval)
@@ -1487,10 +1645,9 @@
 		return -ENODEV;
 	info = zs_soft + line;
 
-#ifdef CONFIG_KGDB
-	if (info->kgdb_channel)
+	if (info->hook)
 		return -ENODEV;
-#endif
+
 	if (serial_paranoia_check(info, tty->device, "rs_open"))
 		return -ENODEV;
 #ifdef SERIAL_DEBUG_OPEN
@@ -1520,7 +1677,7 @@
 	/*
 	 * Start up serial port
 	 */
-	retval = startup(info);
+	retval = zs_startup(info);
 	if (retval)
 		return retval;
 
@@ -1552,7 +1709,7 @@
 	info->pgrp = current->pgrp;
 
 #ifdef SERIAL_DEBUG_OPEN
-	printk("rs_open ttys%d successful...", info->line);
+	printk("rs_open ttyS%02d successful...", info->line);
 #endif
 /* tty->low_latency = 1; */
 	return 0;
@@ -1562,7 +1719,7 @@
 
 static void __init show_serial_version(void)
 {
-	printk("DECstation Z8530 serial driver version 0.03\n");
+	printk("DECstation Z8530 serial driver version 0.05\n");
 }
 
 /*  Initialize Z8530s zs_channels
@@ -1576,7 +1733,7 @@
 	/*
 	 * did we get here by accident?
 	 */
-	if(!IOASIC) {
+	if(!BUS_PRESENT) {
 		printk("Not on JUNKIO machine, skipping probe_sccs\n");
 		return;
 	}
@@ -1587,19 +1744,36 @@
 	 * system_base for this case :-(. HK
 	 */
 	switch(mips_machtype) {
+#ifdef CONFIG_DECSTATION
 	case MACH_DS5000_2X0:
 		system_base = 0xbf800000;
 		n_chips = 2;
+		zs_parms = &ds_parms;
 		break;
 	case MACH_DS5000_1XX:
 		system_base = 0xbc000000;
 		n_chips = 2;
+		zs_parms = &ds_parms;
 		break;
 	case MACH_DS5000_XX:
 		system_base = 0xbc000000;
 		n_chips = 1;
+		zs_parms = &ds_parms;
+		break;
+#endif
+#ifdef CONFIG_BAGET_MIPS
+	case MACH_BAGET202:
+		system_base = UNI_IO_BASE;
+		n_chips = 2;
+		zs_parms = &baget_parms;
+		zs_init_regs[2] = 0x8;
 		break;
+#endif
+	default:
+		panic("zs: unsupported bus");
 	}
+	if (!zs_parms)
+		panic("zs: uninitialized parms");
 
 	pp = &zs_chain;
 
@@ -1610,16 +1784,44 @@
 			/*
 			 * The sccs reside on the high byte of the 16 bit IOBUS
 			 */
-			zs_channels[n_channels].control = (volatile unsigned char *)
-				system_base + (0 == chip ? SCC0 : SCC1) + (0 == channel ? 1 : 9);
-			zs_channels[n_channels].data = zs_channels[n_channels].control + 4;
+			zs_channels[n_channels].control = 
+				(volatile unsigned char *)system_base + 
+			  (0 == chip ? zs_parms->scc0 : zs_parms->scc1) + 
+			  (0 == channel ? zs_parms->channel_a_offset : 
+			                  zs_parms->channel_b_offset);
+			zs_channels[n_channels].data = 
+				zs_channels[n_channels].control + 4;
+
+#ifndef CONFIG_SERIAL_CONSOLE
+			/*
+			 * We're called early and memory managment isn't up, yet.
+			 * Thus check_region would fail.
+			 */
+			if (check_region((unsigned long)
+					 zs_channels[n_channels].control,
+					 ZS_CHAN_IO_SIZE) < 0) {
+				panic("SCC I/O region is not free");
+			}
+			request_region((unsigned long)
+				       zs_channels[n_channels].control,
+				       ZS_CHAN_IO_SIZE, "SCC");
+#endif
 			zs_soft[n_channels].zs_channel = &zs_channels[n_channels];
-			zs_soft[n_channels].irq = SERIAL;
+			zs_soft[n_channels].irq = zs_parms->irq;
 
-			if (0 == channel)
-				zs_soft[n_channels].zs_chan_a = &zs_channels[n_channels+1];
+			/* 
+			 *  Identification of channel A. Location of channel A
+                         *  inside chip depends on mapping of internal address
+			 *  the chip decodes channels by.
+			 *  CHANNEL_A_NR returns either 0 (in case of 
+			 *  DECstations) or 1 (in case of Baget).
+			 */
+			if (CHANNEL_A_NR == channel)
+				zs_soft[n_channels].zs_chan_a = 
+				    &zs_channels[n_channels+1-2*CHANNEL_A_NR];
 			else
-				zs_soft[n_channels].zs_chan_a = &zs_channels[n_channels];
+				zs_soft[n_channels].zs_chan_a = 
+				    &zs_channels[n_channels];
 
 			*pp = &zs_soft[n_channels];
 			pp = &zs_soft[n_channels].zs_next;
@@ -1639,9 +1841,9 @@
 /*	save_and_cli(flags);
 	for (n = 0; n < zs_channels_found; n++) {
 		if (((int)zs_channels[n].control & 0xf) == 1) {
-			write_zsreg(zs_soft[channel].zs_chan_a, R9, FHWRES);
-			udelay(10000);
-			write_zsreg(zs_soft[channel].zs_chan_a, R9, 0);
+			write_zsreg(zs_soft[n].zs_chan_a, R9, FHWRES);
+			mdelay(10);
+			write_zsreg(zs_soft[n].zs_chan_a, R9, 0);
 		}
 		load_zsregs(zs_soft[n].zs_channel, zs_soft[n].zs_channel->curregs);
 	} 
@@ -1655,7 +1857,7 @@
 	unsigned long flags;
 	struct dec_serial *info;
 
-	if(!IOASIC)
+	if(!BUS_PRESENT)
 		return -ENODEV;
 
 	/* Setup base handler, and timer table. */
@@ -1672,7 +1874,11 @@
 
 	memset(&serial_driver, 0, sizeof(struct tty_driver));
 	serial_driver.magic = TTY_DRIVER_MAGIC;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	serial_driver.name = "tts/%d";
+#else
 	serial_driver.name = "ttyS";
+#endif
 	serial_driver.major = TTY_MAJOR;
 	serial_driver.minor_start = 64;
 	serial_driver.num = zs_channels_found;
@@ -1682,7 +1888,7 @@
 
 	serial_driver.init_termios.c_cflag =
 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
 	serial_driver.refcount = &serial_refcount;
 	serial_driver.table = serial_table;
 	serial_driver.termios = serial_termios;
@@ -1710,7 +1916,11 @@
 	 * major number and the subtype code.
 	 */
 	callout_driver = serial_driver;
+#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
+	callout_driver.name = "cua/%d";
+#else
 	callout_driver.name = "cua";
+#endif
 	callout_driver.major = TTYAUX_MAJOR;
 	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
 
@@ -1722,36 +1932,26 @@
 	save_flags(flags); cli();
 
 	for (channel = 0; channel < zs_channels_found; ++channel) {
-#ifdef CONFIG_KGDB
-		if (zs_soft[channel].kgdb_channel) {
-			continue;
-		}
-#endif
+		if (zs_soft[channel].hook &&
+		    zs_soft[channel].hook->init_channel)
+			(*zs_soft[channel].hook->init_channel)
+				(&zs_soft[channel]);
+
 		zs_soft[channel].clk_divisor = 16;
 		zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);
 
-		if (request_irq(SERIAL, rs_interrupt, SA_SHIRQ,
+		if (request_irq(zs_parms->irq, rs_interrupt, SA_SHIRQ,
 				"SCC", &zs_soft[channel]))
 			printk(KERN_ERR "decserial: can't get irq %d\n",
-			       SERIAL);
-
-		/* If console serial line, then enable interrupts. */
-/*		if (zs_soft[channel].is_cons) {
-			write_zsreg(zs_soft[channel].zs_channel, R1,
-				    (EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB));
-			write_zsreg(zs_soft[channel].zs_channel, R9,
-				    (VIS | MIE));
-		}
-*/
+			       zs_parms->irq);
 	}
 
 	for (info = zs_chain, i = 0; info; info = info->zs_next, i++)
 	{
-#ifdef CONFIG_KGDB
-		if (info->kgdb_channel) {
+		if (info->hook && info->hook->init_info) {
+			(*info->hook->init_info)(info);
 			continue;
 		}
-#endif
 		info->magic = SERIAL_MAGIC;
 		info->port = (int) info->zs_channel->control;
 		info->line = i;
@@ -1765,13 +1965,18 @@
 		info->blocked_open = 0;
 		info->tqueue.routine = do_softint;
 		info->tqueue.data = info;
-		info->callout_termios =callout_driver.init_termios;
+		info->callout_termios = callout_driver.init_termios;
 		info->normal_termios = serial_driver.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
-		printk("tty%02d at 0x%08x (irq = %d)", info->line, 
+		printk("ttyS%02d at 0x%08x (irq = %d)", info->line, 
 		       info->port, info->irq);
 		printk(" is a Z85C30 SCC\n");
+		tty_register_devfs(&serial_driver, 0,
+				   serial_driver.minor_start + info->line);
+		tty_register_devfs(&callout_driver, 0,
+				   callout_driver.minor_start + info->line);
+
 	}
 
 	restore_flags(flags);
@@ -1795,38 +2000,116 @@
 }
 
 /*
- * ------------------------------------------------------------
- * Serial console driver
- * ------------------------------------------------------------
+ * polling I/O routines
  */
-#ifdef CONFIG_SERIAL_CONSOLE
+static int
+zs_poll_tx_char(struct dec_serial *info, unsigned char ch)
+{
+	struct dec_zschannel *chan = info->zs_channel;
+	int    ret;
 
+	if(chan) {
+		int loops = 10000;
+//		int nine = read_zsreg(chan, R9);
 
-/*
- *	Print a string to the serial port trying not to disturb
- *	any possible real use of the port...
- */
+		RECOVERY_DELAY;
+//        	write_zsreg(chan, R9, nine & ~MIE);
+               	wbflush();
+		RECOVERY_DELAY;
+
+        	while (!(*(chan->control) & Tx_BUF_EMP) && --loops)
+	        	RECOVERY_DELAY;
+
+                if (loops) {
+                        ret = 0;
+        	        *(chan->data) = ch;
+                	wbflush();
+			RECOVERY_DELAY;
+                } else
+                        ret = -EAGAIN;
+
+//        	write_zsreg(chan, R9, nine);
+               	wbflush();
+		RECOVERY_DELAY;
+
+                return ret;
+        }
 
-/* This is for console output */
-static void
-zs_console_putchar(struct dec_serial *info, char ch)
+	return -ENODEV;
+}
+
+static int
+zs_poll_rx_char(struct dec_serial *info)
 {
-	int loops = 10000;
-	unsigned long flags;
+        struct dec_zschannel *chan = info->zs_channel;
+        int    ret;
 
-	if(!info->zs_channel)
-		return;
+	if(chan) {
+                int loops = 10000;
 
-	save_flags(flags); cli();
+                while((read_zsreg(chan, 0) & Rx_CH_AV) == 0)
+		        loops--;
 
-	while (!(*(info->zs_channel->control) & Tx_BUF_EMP) && --loops)
-		RECOVERY_DELAY;
-	*(info->zs_channel->data) = ch;
-	wbflush(); RECOVERY_DELAY;
+                if (loops)
+                        ret = read_zsdata(chan);
+                else
+                        ret = -EAGAIN;
 
-	restore_flags(flags);
+                return ret;
+        } else
+                return -ENODEV;
+}
+
+unsigned int register_zs_hook(unsigned int channel, struct zs_hook *hook)
+{
+	struct dec_serial *info = &zs_soft[channel];
+
+	if (info->hook) {
+		printk(__FUNCTION__": line %d has already a hook registered\n", channel);
+
+		return 0;
+	} else {
+		info->hook = hook;
+
+		if (zs_chain == 0)
+			probe_sccs();
+
+		if (!(info->flags & ZILOG_INITIALIZED))
+			zs_startup(info);
+
+		hook->poll_rx_char = zs_poll_rx_char;
+		hook->poll_tx_char = zs_poll_tx_char;
+
+		return 1;
+	}
+}
+
+unsigned int unregister_zs_hook(unsigned int channel)
+{
+	struct dec_serial *info = &zs_soft[channel];
+
+        if (info->hook) {
+                info->hook = NULL;
+                return 1;
+        } else {
+                printk(__FUNCTION__": trying to unregister hook on line %d,"
+                       " but none is registered\n", channel);
+                return 0;
+        }
 }
 
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+#ifdef CONFIG_SERIAL_CONSOLE
+
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ */
 static void serial_console_write(struct console *co, const char *s,
 				 unsigned count)
 {
@@ -1835,28 +2118,11 @@
 
 	info = zs_soft + co->index;
 
-#if 0
-	/*
-	 * disable master interrupt if necessary
-	 */
-	nine = info->zs_channel->curregs[9];
-	if(nine & MIE)
-		write_zsreg(info->zs_channel, R9, nine & ~MIE);
-#endif
-	/*
-	 * do it
-	 */
 	for (i = 0; i < count; i++, s++) {
 		if(*s == '\n')
-			zs_console_putchar(info, '\r');
-		zs_console_putchar(info, *s);
+			zs_poll_tx_char(info, '\r');
+		zs_poll_tx_char(info, *s);
 	}
-	/*
-	 * restore master interrupt enable
-	 */
-#if 0
-	write_zsreg(info->zs_channel, R9, nine);
-#endif
 }
 
 /*
@@ -1864,7 +2130,11 @@
  */
 static int serial_console_wait_key(struct console *co)
 {
-	return 0;
+	struct dec_serial *info;
+
+        info = zs_soft + co->index;
+
+        return zs_poll_rx_char(info);
 }
 
 static kdev_t serial_console_device(struct console *c)
@@ -1888,7 +2158,7 @@
 	char	*s;
 	unsigned long flags;
 
-	if(!IOASIC)
+	if(!BUS_PRESENT)
 		return -ENODEV;
 
 	info = zs_soft + co->index;
@@ -1963,7 +2233,7 @@
 	/*
 	 * Turn on RTS and DTR.
 	 */
-	zs_rtsdtr(info, 1);
+	zs_rtsdtr(info, RTS | DTR, 1);
 
 	/*
 	 * Finally, enable sequencing
@@ -2017,6 +2287,18 @@
 #endif /* ifdef CONFIG_SERIAL_CONSOLE */
 
 #ifdef CONFIG_KGDB
+struct dec_zschannel *zs_kgdbchan;
+static unsigned char scc_inittab[] = {
+	9,  0x80,	/* reset A side (CHRA) */
+	13, 0,		/* set baud rate divisor */
+	12, 1,
+	14, 1,		/* baud rate gen enable, src=rtxc (BRENABL) */
+	11, 0x50,	/* clocks = br gen (RCBR | TCBR) */
+	5,  0x6a,	/* tx 8 bits, assert RTS (Tx8 | TxENAB | RTS) */
+	4,  0x44,	/* x16 clock, 1 stop (SB1 | X16CLK)*/
+	3,  0xc1,	/* rx enable, 8 bits (RxENABLE | Rx8)*/
+};
+
 /* These are for receiving and sending characters under the kgdb
  * source level kernel debugger.
  */
@@ -2051,6 +2333,25 @@
 	write_zsreg(chan, 1, one);
 	write_zsreg(chan, 9, nine);
 }
+
+static int kgdbhook_init_channel(struct dec_serial* info) 
+{
+	return 0;
+}
+
+static void kgdbhook_init_info(struct dec_serial* info)
+{
+}
+
+static void kgdbhook_rx_char(struct dec_serial* info, 
+			     unsigned char ch, unsigned char stat)
+{
+	if (ch == 0x03 || ch == '$')
+		breakpoint();
+	if (stat & (Rx_OVR|FRM_ERR|PAR_ERR))
+		write_zsreg(info->zs_channel, 0, ERR_RES);
+}
+
 /* This sets up the serial port we're using, and turns on
  * interrupts for that channel, so kgdb is usable once we're done.
  */
@@ -2059,7 +2360,7 @@
 	int brg;
 	int i, x;
 	volatile char *sccc = ms->control;
-	brg = BPS_TO_BRG(bps, ZS_CLOCK/16);
+	brg = BPS_TO_BRG(bps, zs_parms->clock/16);
 	printk("setting bps on kgdb line to %d [brg=%x]\n", bps, brg);
 	for (i = 20000; i != 0; --i) {
 		x = *sccc; eieio();
@@ -2074,6 +2375,13 @@
  * for /dev/ttyb which is determined in setup_arch() from the
  * boot command line flags.
  */
+struct zs_hook zs_kgdbhook = {
+	init_channel : kgdbhook_init_channel,
+	init_info    : kgdbhook_init_info,
+	cflags       : B38400|CS8|CLOCAL,
+	rx_char      : kgdbhook_rx_char,
+}
+
 void __init zs_kgdb_hook(int tty_num)
 {
 	/* Find out how many Z8530 SCCs we have */
@@ -2084,11 +2392,12 @@
 	zs_soft[tty_num].change_needed = 0;
 	zs_soft[tty_num].clk_divisor = 16;
 	zs_soft[tty_num].zs_baud = 38400;
-	zs_soft[tty_num].kgdb_channel = 1;     /* This runs kgdb */
-	zs_soft[tty_num ^ 1].kgdb_channel = 0; /* This does not */
+ 	zs_soft[tty_num].hook = &zs_kgdbhook; /* This runs kgdb */
 	/* Turn on transmitter/receiver at 8-bits/char */
         kgdb_chaninit(zs_soft[tty_num].zs_channel, 1, 38400);
 	printk("KGDB: on channel %d initialized\n", tty_num);
 	set_debug_traps(); /* init stub */
 }
 #endif /* ifdef CONFIG_KGDB */
+
+
diff -u --recursive --new-file v2.4.9/linux/drivers/tc/zs.h linux/drivers/tc/zs.h
--- v2.4.9/linux/drivers/tc/zs.h	Sat May 13 08:31:25 2000
+++ linux/drivers/tc/zs.h	Mon Aug 27 08:56:31 2001
@@ -89,6 +89,18 @@
 	unsigned char curregs[NUM_ZSREGS];
 };
 
+struct dec_serial;
+
+struct zs_hook {
+	int (*init_channel)(struct dec_serial* info);
+	void (*init_info)(struct dec_serial* info);
+	void (*rx_char)(unsigned char ch, unsigned char stat);
+	int  (*poll_rx_char)(struct dec_serial* info);
+	int  (*poll_tx_char)(struct dec_serial* info,
+			     unsigned char ch);
+	unsigned cflags;
+};
+
 struct dec_serial {
 	struct dec_serial *zs_next;	/* For IRQ servicing chain */
 	struct dec_zschannel *zs_channel; /* Channel registers */
@@ -97,7 +109,7 @@
 
 	char soft_carrier;  /* Use soft carrier on this channel */
 	char break_abort;   /* Is serial console in, so process brk/abrt */
-	char kgdb_channel;  /* Kgdb is running on this channel */
+	struct zs_hook *hook;  /* Hook on this channel */
 	char is_cons;       /* Is this our console. */
 	unsigned char tx_active; /* character is being xmitted */
 	unsigned char tx_stopped; /* output is suspended */
diff -u --recursive --new-file v2.4.9/linux/drivers/usb/Config.in linux/drivers/usb/Config.in
--- v2.4.9/linux/drivers/usb/Config.in	Tue Jul  3 17:08:21 2001
+++ linux/drivers/usb/Config.in	Mon Aug 27 08:45:43 2001
@@ -67,6 +67,7 @@
    dep_tristate '  PLUSB Prolific USB-Network driver (EXPERIMENTAL)' CONFIG_USB_PLUSB $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
    dep_tristate '  USB ADMtek Pegasus-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_PEGASUS $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
    dep_tristate '  USB CATC NetMate-based Ethernet driver (EXPERIMENTAL)' CONFIG_USB_CATC $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
+   dep_tristate '  USB KLSI KL5USB101-based ethernet device support (EXPERIMENTAL)' CONFIG_USB_KAWETH $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
    dep_tristate '  NetChip 1080-based USB Host-to-Host Link (EXPERIMENTAL)' CONFIG_USB_NET1080 $CONFIG_USB $CONFIG_NET $CONFIG_EXPERIMENTAL
 
    comment 'USB port drivers'
diff -u --recursive --new-file v2.4.9/linux/drivers/usb/Makefile linux/drivers/usb/Makefile
--- v2.4.9/linux/drivers/usb/Makefile	Tue Jul  3 17:08:21 2001
+++ linux/drivers/usb/Makefile	Mon Aug 27 08:45:43 2001
@@ -65,6 +65,7 @@
 obj-$(CONFIG_USB_SE401)		+= se401.o
 obj-$(CONFIG_USB_PEGASUS)	+= pegasus.o
 obj-$(CONFIG_USB_CATC)		+= catc.o
+obj-$(CONFIG_USB_KAWETH)        += kaweth.o
 obj-$(CONFIG_USB_RIO500)	+= rio500.o
 obj-$(CONFIG_USB_DSBR)		+= dsbr100.o
 obj-$(CONFIG_USB_MICROTEK)	+= microtek.o
diff -u --recursive --new-file v2.4.9/linux/drivers/usb/kaweth.c linux/drivers/usb/kaweth.c
--- v2.4.9/linux/drivers/usb/kaweth.c	Mon Aug 27 12:41:45 2001
+++ linux/drivers/usb/kaweth.c	Mon Aug 27 08:45:43 2001
@@ -248,9 +248,9 @@
 	
 	dr->requesttype = requesttype;
 	dr->request = request;
-	dr->value = value;
-	dr->index = index;
-	dr->length = size;
+	dr->value = cpu_to_le16p(&value);
+	dr->index = cpu_to_le16p(&index);
+	dr->length = cpu_to_le16p(&size);
 
 	return kaweth_internal_control_msg(kaweth->dev,
 					pipe,
@@ -370,6 +370,9 @@
 	kaweth->firmware_buf[4] = type;
 	kaweth->firmware_buf[5] = interrupt;
 
+	kaweth_dbg("High: %i, Low:%i", kaweth->firmware_buf[3],
+		   kaweth->firmware_buf[2]);
+
 	kaweth_dbg("Downloading firmware at %x to kaweth device at %x", 
 	    (int)data, 
 	    (int)kaweth);
@@ -476,7 +479,7 @@
 	int count = urb->actual_length;
 	int count2 = urb->transfer_buffer_length;
 			
-	__u16 pkt_len = *(__u16 *)kaweth->rx_buf;
+	__u16 pkt_len = le16_to_cpup(kaweth->rx_buf);
 
 	struct sk_buff *skb;
 
@@ -608,7 +611,7 @@
 	kaweth_async_set_rx_mode(kaweth);
 	netif_stop_queue(net);
 
-	*((__u16 *)kaweth->tx_buf) = skb->len;
+	*((__u16 *)kaweth->tx_buf) = cpu_to_le16(skb->len);
 
 	memcpy(kaweth->tx_buf + 2, skb->data, skb->len);
 
@@ -836,7 +839,7 @@
 
 	kaweth_info("Statistics collection: %x", kaweth->configuration.statistics_mask);
 	kaweth_info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
-	kaweth_info("MTU: %d", kaweth->configuration.segment_size);
+	kaweth_info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size));
 	kaweth_info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
 		 (int)kaweth->configuration.hw_addr[0],
 		 (int)kaweth->configuration.hw_addr[1],
@@ -896,7 +899,7 @@
 	kaweth->net->hard_start_xmit = kaweth_start_xmit;
 	kaweth->net->set_multicast_list = kaweth_set_rx_mode;
 	kaweth->net->get_stats = kaweth_netdev_stats;
-	kaweth->net->mtu = kaweth->configuration.segment_size;
+	kaweth->net->mtu = le16_to_cpu(kaweth->configuration.segment_size);
 
 	memset(&kaweth->stats, 0, sizeof(kaweth->stats));
 
@@ -1051,4 +1054,11 @@
 
 module_init(kaweth_init);
 module_exit(kaweth_exit);
+
+
+
+
+
+
+
 
diff -u --recursive --new-file v2.4.9/linux/fs/cramfs/inode.c linux/fs/cramfs/inode.c
--- v2.4.9/linux/fs/cramfs/inode.c	Wed Jul 25 17:10:24 2001
+++ linux/fs/cramfs/inode.c	Mon Aug 27 07:53:49 2001
@@ -374,6 +374,7 @@
 {
 	struct inode *inode = page->mapping->host;
 	u32 maxblock, bytes_filled;
+	void *pgdata;
 
 	maxblock = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 	bytes_filled = 0;
@@ -387,15 +388,18 @@
 			start_offset = *(u32 *) cramfs_read(sb, blkptr_offset-4, 4);
 		compr_len = (*(u32 *) cramfs_read(sb, blkptr_offset, 4)
 			     - start_offset);
+		pgdata = kmap(page);
 		if (compr_len == 0)
 			; /* hole */
 		else
-			bytes_filled = cramfs_uncompress_block(page_address(page),
+			bytes_filled = cramfs_uncompress_block(pgdata,
 				 PAGE_CACHE_SIZE,
 				 cramfs_read(sb, start_offset, compr_len),
 				 compr_len);
-	}
-	memset(page_address(page) + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled);
+	} else
+		pgdata = kmap(page);
+	memset(pgdata + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled);
+	kunmap(page);
 	flush_dcache_page(page);
 	SetPageUptodate(page);
 	UnlockPage(page);
diff -u --recursive --new-file v2.4.9/linux/fs/inode.c linux/fs/inode.c
--- v2.4.9/linux/fs/inode.c	Sun Aug 12 13:28:00 2001
+++ linux/fs/inode.c	Mon Aug 27 08:22:28 2001
@@ -1049,6 +1049,7 @@
 
 			if (op && op->delete_inode) {
 				void (*delete)(struct inode *) = op->delete_inode;
+				DQUOT_INIT(inode);
 				/* s_op->delete_inode internally recalls clear_inode() */
 				delete(inode);
 			} else
diff -u --recursive --new-file v2.4.9/linux/fs/ntfs/unistr.c linux/fs/ntfs/unistr.c
--- v2.4.9/linux/fs/ntfs/unistr.c	Mon Aug 27 12:41:46 2001
+++ linux/fs/ntfs/unistr.c	Mon Aug 27 07:47:16 2001
@@ -22,6 +22,7 @@
  */
 
 #include <linux/string.h>
+#include <linux/kernel.h>
 #include <asm/byteorder.h>
 
 #include "unistr.h"
diff -u --recursive --new-file v2.4.9/linux/fs/umsdos/emd.c linux/fs/umsdos/emd.c
--- v2.4.9/linux/fs/umsdos/emd.c	Tue Mar  6 19:44:37 2001
+++ linux/fs/umsdos/emd.c	Mon Aug 27 08:13:05 2001
@@ -259,10 +259,10 @@
 		p->ctime = cpu_to_le32(entry->ctime);
 		p->rdev = cpu_to_le16(entry->rdev);
 		p->mode = cpu_to_le16(entry->mode);
-		memcpy(p->name,entry->name,
+		memcpy(p->spare,entry->spare,
 			(char *)(page_address(page) + PAGE_CACHE_SIZE) - p->spare);
 		memcpy(page_address(page2),
-				entry->spare+PAGE_CACHE_SIZE-offs,
+				((char*)entry)+PAGE_CACHE_SIZE-offs,
 				offs+info->recsize-PAGE_CACHE_SIZE);
 		ret = mapping->a_ops->commit_write(NULL,page2,0,
 					offs+info->recsize-PAGE_CACHE_SIZE);
diff -u --recursive --new-file v2.4.9/linux/include/asm-alpha/keyboard.h linux/include/asm-alpha/keyboard.h
--- v2.4.9/linux/include/asm-alpha/keyboard.h	Mon Aug 27 12:41:47 2001
+++ linux/include/asm-alpha/keyboard.h	Mon Aug 27 07:53:23 2001
@@ -13,6 +13,8 @@
 
 #ifdef __KERNEL__
 
+#include <linux/kd.h>
+
 #define KEYBOARD_IRQ			1
 #define DISABLE_KBD_DURING_INTERRUPTS	0
 
@@ -31,7 +33,7 @@
 #define kbd_translate		pckbd_translate
 #define kbd_unexpected_up	pckbd_unexpected_up
 #define kbd_leds		pckbd_leds
-#define kbd_rate               pckbd_rate
+#define kbd_rate		pckbd_rate
 #define kbd_init_hw		pckbd_init_hw
 #define kbd_sysrq_xlate		pckbd_sysrq_xlate
 
diff -u --recursive --new-file v2.4.9/linux/include/asm-i386/kmap_types.h linux/include/asm-i386/kmap_types.h
--- v2.4.9/linux/include/asm-i386/kmap_types.h	Thu Apr 12 12:11:39 2001
+++ linux/include/asm-i386/kmap_types.h	Mon Aug 27 07:43:02 2001
@@ -6,6 +6,8 @@
 	KM_BOUNCE_WRITE,
 	KM_SKB_DATA,
 	KM_SKB_DATA_SOFTIRQ,
+	KM_USER0,
+	KM_USER1,
 	KM_TYPE_NR
 };
 
diff -u --recursive --new-file v2.4.9/linux/include/linux/agp_backend.h linux/include/linux/agp_backend.h
--- v2.4.9/linux/include/linux/agp_backend.h	Tue Jul  3 17:08:21 2001
+++ linux/include/linux/agp_backend.h	Mon Aug 27 07:40:33 2001
@@ -85,6 +85,8 @@
 	size_t aper_size;
 	int max_memory;		/* In pages */
 	int current_memory;
+	int cant_use_aperture;
+	unsigned long page_mask;
 } agp_kern_info;
 
 /* 
diff -u --recursive --new-file v2.4.9/linux/include/linux/highmem.h linux/include/linux/highmem.h
--- v2.4.9/linux/include/linux/highmem.h	Tue Aug  7 12:48:43 2001
+++ linux/include/linux/highmem.h	Mon Aug 27 09:17:26 2001
@@ -45,8 +45,9 @@
 /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */
 static inline void clear_user_highpage(struct page *page, unsigned long vaddr)
 {
-	clear_user_page(kmap(page), vaddr);
-	kunmap(page);
+	void *addr = kmap_atomic(page, KM_USER0);
+	clear_user_page(addr, vaddr);
+	kunmap_atomic(addr, KM_USER0);
 }
 
 static inline void clear_highpage(struct page *page)
@@ -85,11 +86,11 @@
 {
 	char *vfrom, *vto;
 
-	vfrom = kmap(from);
-	vto = kmap(to);
+	vfrom = kmap_atomic(from, KM_USER0);
+	vto = kmap_atomic(to, KM_USER1);
 	copy_user_page(vto, vfrom, vaddr);
-	kunmap(from);
-	kunmap(to);
+	kunmap_atomic(vfrom, KM_USER0);
+	kunmap_atomic(vto, KM_USER1);
 }
 
 static inline void copy_highpage(struct page *to, struct page *from)
diff -u --recursive --new-file v2.4.9/linux/include/linux/kernel.h linux/include/linux/kernel.h
--- v2.4.9/linux/include/linux/kernel.h	Mon Aug 27 12:41:48 2001
+++ linux/include/linux/kernel.h	Mon Aug 27 08:20:39 2001
@@ -113,9 +113,9 @@
 	((unsigned char *)&addr)[0]
 
 #define min(type,x,y) \
-	({ type __x = (x), __y = (y); __x < __y ? __x: __y; })
+	({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
 #define max(type,x,y) \
-	({ type __x = (x), __y = (y); __x > __y ? __x: __y; })
+	({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v2.4.9/linux/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- v2.4.9/linux/include/linux/pci_ids.h	Mon Aug 27 12:41:48 2001
+++ linux/include/linux/pci_ids.h	Mon Aug 27 08:56:31 2001
@@ -985,6 +985,7 @@
 #define PCI_VENDOR_ID_PHILIPS		0x1131
 #define PCI_DEVICE_ID_PHILIPS_SAA7145	0x7145
 #define PCI_DEVICE_ID_PHILIPS_SAA7146	0x7146
+#define PCI_DEVICE_ID_PHILIPS_SAA9730	0x9730
 
 #define PCI_VENDOR_ID_EICON		0x1133
 #define PCI_DEVICE_ID_EICON_DIVA20PRO	0xe001
@@ -1098,6 +1099,9 @@
 
 #define PCI_VENDOR_ID_GALILEO		0x11ab
 #define PCI_DEVICE_ID_GALILEO_GT64011	0x4146
+#define PCI_DEVICE_ID_GALILEO_GT64111	0x4146
+#define PCI_DEVICE_ID_GALILEO_GT96100	0x9652
+#define PCI_DEVICE_ID_GALILEO_GT96100A	0x9653
 
 #define PCI_VENDOR_ID_LITEON		0x11ad
 #define PCI_DEVICE_ID_LITEON_LNE100TX	0x0002
@@ -1227,6 +1231,10 @@
 #define PCI_DEVICE_ID_ENSONIQ_ES1371	0x1371
 
 #define PCI_VENDOR_ID_ROCKWELL		0x127A
+
+#define PCI_VENDOR_ID_ITE		0x1283
+#define PCI_DEVICE_ID_ITE_IT8172G	0x8172
+#define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801
 
 #define PCI_VENDOR_ID_ITE		0x1283
 #define PCI_DEVICE_ID_ITE_IT8172G	0x8172
diff -u --recursive --new-file v2.4.9/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.4.9/linux/kernel/ksyms.c	Mon Aug 27 12:41:49 2001
+++ linux/kernel/ksyms.c	Mon Aug 27 08:00:12 2001
@@ -434,6 +434,7 @@
 /* process management */
 EXPORT_SYMBOL(complete_and_exit);
 EXPORT_SYMBOL(__wake_up);
+EXPORT_SYMBOL(__wake_up_sync);
 EXPORT_SYMBOL(wake_up_process);
 EXPORT_SYMBOL(sleep_on);
 EXPORT_SYMBOL(sleep_on_timeout);
diff -u --recursive --new-file v2.4.9/linux/kernel/signal.c linux/kernel/signal.c
--- v2.4.9/linux/kernel/signal.c	Wed Jan  3 20:45:26 2001
+++ linux/kernel/signal.c	Mon Aug 27 08:58:52 2001
@@ -242,16 +242,16 @@
 #endif
 
 	sig = next_signal(current, mask);
-	if (current->notifier) {
-		if (sigismember(current->notifier_mask, sig)) {
-			if (!(current->notifier)(current->notifier_data)) {
-				current->sigpending = 0;
-				return 0;
+	if (sig) {
+		if (current->notifier) {
+			if (sigismember(current->notifier_mask, sig)) {
+				if (!(current->notifier)(current->notifier_data)) {
+					current->sigpending = 0;
+					return 0;
+				}
 			}
 		}
-	}
 
-	if (sig) {
 		if (!collect_signal(sig, &current->pending, info))
 			sig = 0;
 				
diff -u --recursive --new-file v2.4.9/linux/mm/memory.c linux/mm/memory.c
--- v2.4.9/linux/mm/memory.c	Mon Aug 27 12:41:49 2001
+++ linux/mm/memory.c	Sun Aug 26 20:32:18 2001
@@ -1119,6 +1119,7 @@
 			 */
 			return pte_same(*page_table, orig_pte) ? -1 : 1;
 		}
+		SetPageReferenced(page);
 	}
 
 	/*
