diff -u --recursive --new-file v2.0.28/linux/MAINTAINERS linux/MAINTAINERS
--- v2.0.28/linux/MAINTAINERS	Fri Nov 22 16:25:54 1996
+++ linux/MAINTAINERS	Wed Jan 15 13:58:28 1997
@@ -195,6 +195,12 @@
 L:	linux-kernel@vger.rutgers.edu
 S:	Maintained
 
+IDE/ATAPI CDROM DRIVER 
+P:	Erik Andersen
+M:	andersee@debian.org
+L:	linux-kernel@vger.rutgers.edu
+S:	Maintained
+
 ISDN SUBSYSTEM
 P:	Fritz Elfert
 M:	fritz@wuemaus.franken.de
diff -u --recursive --new-file v2.0.28/linux/Makefile linux/Makefile
--- v2.0.28/linux/Makefile	Thu Feb  6 17:16:22 1997
+++ linux/Makefile	Wed Jan 15 01:13:12 1997
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 0
-SUBLEVEL = 28
+SUBLEVEL = 29
 
 ARCH = i386
 
diff -u --recursive --new-file v2.0.28/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c
--- v2.0.28/linux/arch/alpha/kernel/bios32.c	Mon Dec 30 16:01:46 1996
+++ linux/arch/alpha/kernel/bios32.c	Sun Feb  2 14:59:20 1997
@@ -24,6 +24,7 @@
  * within the United States, $35 abroad.
  */
 #include <linux/config.h>
+#include <linux/kernel.h>
 
 #if 0
 # define DBG_DEVS(args)		printk args
@@ -48,7 +49,6 @@
 
 #else /* CONFIG_PCI */
 
-#include <linux/kernel.h>
 #include <linux/bios32.h>
 #include <linux/pci.h>
 #include <linux/malloc.h>
diff -u --recursive --new-file v2.0.28/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v2.0.28/linux/arch/alpha/kernel/traps.c	Sun May 19 17:02:31 1996
+++ linux/arch/alpha/kernel/traps.c	Sun Feb  2 15:00:20 1997
@@ -236,13 +236,13 @@
 	exp = (exp_msb << 10) | exp_low;	/* common case */
 	if (exp_msb) {
 		if (exp_low == 0x7f) {
-			exp = 0x3ff;
+			exp = 0x7ff;
 		}
 	} else {
 		if (exp_low == 0x00) {
 			exp = 0x000;
 		} else {
-			exp |= (0x7 << 8);
+			exp |= (0x7 << 7);
 		}
 	}
 	return (sign << 63) | (exp << 52) | (frac << 29);
diff -u --recursive --new-file v2.0.28/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.0.28/linux/arch/i386/kernel/irq.c	Wed Nov 13 11:26:21 1996
+++ linux/arch/i386/kernel/irq.c	Thu Jan 16 04:33:22 1997
@@ -285,7 +285,7 @@
 		for (j=0;j<smp_num_cpus;j++)
 			len+=sprintf(buf+len, "%10d ",
 				int_count[cpu_logical_map[j]][i]);
-		len += sprintf(buf+len, "%c %s\n",
+		len += sprintf(buf+len, "%c %s",
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
 		for (action=action->next; action; action = action->next) {
@@ -293,6 +293,7 @@
 				(action->flags & SA_INTERRUPT) ? " +" : "",
 				action->name);
 		}
+		len += sprintf(buf+len, "\n");
 	}
 	len+=sprintf(buf+len, "LCK: %10lu",
 		sum_spins);
diff -u --recursive --new-file v2.0.28/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
--- v2.0.28/linux/drivers/block/ide-cd.c	Fri Sep 20 17:00:34 1996
+++ linux/drivers/block/ide-cd.c	Wed Jan 15 13:58:28 1997
@@ -1,5 +1,14 @@
+/* #define VERBOSE_IDE_CD_ERRORS 1 */
 /*
  * linux/drivers/block/ide-cd.c
+ * ATAPI cd-rom driver.  To be used with ide.c.
+ * See Documentation/cdrom/ide-cd for usage information.
+ *
+ * Copyright (C) 1994, 1995, 1996  scott snyder  <snyder@fnald0.fnal.gov>
+ * Copyright (C) 1996, 1997  Erik Andersen <andersee@debian.org>
+ *
+ * May be copied or modified under the terms of the GNU General Public License
+ * see linux/COPYING for more information.
  *
  * 1.00  Oct 31, 1994 -- Initial version.
  * 1.01  Nov  2, 1994 -- Fixed problem with starting request in
@@ -109,15 +118,30 @@
  * 3.17  Sep 17, 1996 -- Tweak audio reads for some drives.
  *                       Start changing CDROMLOADFROMSLOT to CDROM_SELECT_DISC.
  *
+ * 3.19  Nov 5, 1996  -- New ide-cd maintainer:
+ *                                 Erik B. Andersen <andersee@debian.org>
+ * 3.20  Jan 13,1997  -- Bug Fixes:
+ *                        Fix errors on CDROMSTOP (If you have a "Dolphin",
+ *                          you must define IHAVEADOLPHIN)
+ *                        Added identifier so new Sanyo CD-changer works
+ *                        Better detection if door locking isn't supported 
+ *                         
  * NOTE: Direct audio reads will only work on some types of drive.
  * So far, i've received reports of success for Sony and Toshiba drives.
  *
- * ATAPI cd-rom driver.  To be used with ide.c.
- * See Documentation/cdrom/ide-cd for usage information.
+ * ALSO NOTE:
+ *
+ *  The ide cdrom driver has undergone extensive changes for the
+ *       latest development kernel.  If you wish to add new features to
+ *       this driver, make your changes to the latest version in the
+ *       development kernel.  Only Bug fixes will be accepted for this
+ *       version.
+ *
+ *       For those wishing to work on this driver, please be sure you download
+ *       and comply with the latest ATAPI standard.  This document can be
+ *       obtained by anonymous ftp from fission.dt.wdc.com in directory:
+ *       /pub/standards/atapi/spec/SFF8020-r2.6/PDF/8020r26.pdf
  *
- * Copyright (C) 1994, 1995, 1996  scott snyder  <snyder@fnald0.fnal.gov>
- * May be copied or modified under the terms of the GNU General Public License
- * (../../COPYING).
  */
 
 
@@ -1555,7 +1579,7 @@
 		/* If we got an illegal field error, the drive
 		   probably cannot lock the door. */
 		if (reqbuf->sense_key == ILLEGAL_REQUEST &&
-		    reqbuf->asc == 0x24) {
+		    (reqbuf->asc == 0x24 || reqbuf->asc == 0x20)) {
 			printk ("%s: door locking not supported\n",
 				drive->name);
 			CDROM_CONFIG_FLAGS (drive)->no_doorlock = 1;
@@ -2065,13 +2089,18 @@
 		return cdrom_startstop (drive, 1, NULL);
 
 	case CDROMSTOP: {
+#ifdef IHAVEADOLPHIN
+		/*  Certain Drives require this.  Most don't
+		    and will produce errors upon CDROMSTOP
+		    pit says the Dolphin needs this.  If you
+		    own a dolphin, just define IHAVEADOLPHIN somewhere */
 		int stat;
-
 		stat = cdrom_startstop (drive, 0, NULL);
 		if (stat) return stat;
-		/* pit says the Dolphin needs this. */
 		return cdrom_eject (drive, 1, NULL);
-      }
+#endif /* end of IHAVEADOLPHIN  */
+		return cdrom_startstop (drive, 0, NULL);
+	}
 
 	case CDROMPLAYMSF: {
 		struct cdrom_msf msf;
@@ -2694,14 +2723,15 @@
 			CDROM_CONFIG_FLAGS (drive)->subchan_as_bcd = 1;
 		}
 
-		/* Sanyo 3 CD changer uses a non-standard command 
-                   for CD changing */
-                else if ((strcmp(drive->id->model, "CD-ROM CDR-C3 G") == 0) ||
-                         (strcmp(drive->id->model, "CD-ROM CDR-C3G") == 0)) {
-			/* uses CD in slot 0 when value is set to 3 */
-			CDROM_STATE_FLAGS (drive)->sanyo_slot = 3;
-		}
-
+                /* Sanyo 3 CD changer uses a non-standard command
+                    for CD changing */
+                 else if ((strcmp(drive->id->model, "CD-ROM CDR-C3 G") == 0) ||
+                         (strcmp(drive->id->model, "CD-ROM CDR-C3G") == 0) ||
+                         (strcmp(drive->id->model, "CD-ROM CDR_C36") == 0)) {
+                        /* uses CD in slot 0 when value is set to 3 */
+                        CDROM_STATE_FLAGS (drive)->sanyo_slot = 3;
+                }
+                
 	}
 #endif /* not STANDARD_ATAPI */
 
diff -u --recursive --new-file v2.0.28/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.0.28/linux/drivers/pci/pci.c	Thu Feb  6 17:16:26 1997
+++ linux/drivers/pci/pci.c	Fri Jan 24 20:56:58 1997
@@ -91,6 +91,7 @@
 	DEVICE( MATROX,		MATROX_MGA_IMP,	"MGA Impression"),
 	DEVICE( CT,		CT_65545,	"65545"),
 	DEVICE( CT,		CT_65548,	"65548"),
+	DEVICE(	CT,		CT_65550,	"65550"),
 	DEVICE( MIRO,		MIRO_36050,	"ZR36050"),
 	DEVICE( FD,		FD_36C70,	"TMC-18C30"),
 	DEVICE( SI,		SI_6201,	"6201"),
diff -u --recursive --new-file v2.0.28/linux/drivers/scsi/AM53C974.c linux/drivers/scsi/AM53C974.c
--- v2.0.28/linux/drivers/scsi/AM53C974.c	Thu Oct 31 12:08:52 1996
+++ linux/drivers/scsi/AM53C974.c	Mon Feb  3 14:06:20 1997
@@ -158,6 +158,11 @@
 static int commandline_current = 0;
 override_t overrides[7] = { {-1, 0, 0, 0}, };   /* LILO overrides */
 
+struct proc_dir_entry proc_scsi_am53c974 = {
+	PROC_SCSI_AM53C974, 8, "am53c974",
+	S_IFDIR | S_IRUGO | S_IXUGO, 2
+};
+
 #ifdef AM53C974_DEBUG
 static int deb_stop = 1;
 
@@ -566,6 +571,8 @@
 {
 int count;        /* number of boards detected */
 
+tpnt->proc_dir = &proc_scsi_am53c974;
+
 #if defined (CONFIG_PCI)
 if (pcibios_present())
    count = AM53C974_bios_detect(tpnt);
@@ -598,7 +605,7 @@
 
 #ifdef AM53C974_OPTION_DEBUG_PROBE_ONLY
    printk ("AM53C974: probe only enabled, aborting initialization\n");
-   return -1;
+   return 0;
 #endif
 
 instance = scsi_register(tpnt, sizeof(struct AM53C974_hostdata));
@@ -661,7 +668,7 @@
    if (request_irq(instance->irq, AM53C974_intr, SA_INTERRUPT, "AM53C974", NULL)) {
       printk("scsi%d: IRQ%d not free, detaching\n", instance->host_no, instance->irq);
       scsi_unregister(instance);
-      return -1; } 
+      return 0; } 
    }
   else {
    printk("scsi%d: using interrupt handler previously installed for scsi%d\n",
@@ -679,8 +686,7 @@
 AM53C974_write_8(CMDREG, CMDREG_RBUS);     /* reset SCSI bus */
 udelay(10);
 AM53C974_config_after_reset(instance);
-
-return(0);
+return(1);
 }
 
 /*********************************************************************
@@ -2007,7 +2013,7 @@
 AM53C974_write_8(STCMREG, (unsigned char)((length & 0xff00) >> 8));
 AM53C974_write_8(STCHREG, (unsigned char)((length & 0xff0000) >> 16));
 AM53C974_write_32(DMASTC, length & 0xffffff);
-AM53C974_write_32(DMASPA, (unsigned long)data);
+AM53C974_write_32(DMASPA, virt_to_bus(data));
 AM53C974_write_8(CMDREG, CMDREG_IT | CMDREG_DMA);
 AM53C974_write_8(DMACMD, (dir << 7) | DMACMD_INTE_D | DMACMD_START);
 }
@@ -2243,6 +2249,21 @@
 cmd->scsi_done(cmd);
 return SCSI_ABORT_SUCCESS;
 }
+
+
+/*
+ * AM53C974_release()
+ *
+ * Release resources allocated for a single AM53C974 adapter.
+ */
+int
+AM53C974_release(struct Scsi_Host *shp)
+{
+	free_irq(shp->irq, NULL);
+	scsi_unregister(shp);
+	return 0;
+}
+
 
 #ifdef MODULE
 /* Eventually this will go into an include file, but this will be later */
diff -u --recursive --new-file v2.0.28/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- v2.0.28/linux/drivers/scsi/scsi_ioctl.c	Thu Feb  6 17:16:27 1997
+++ linux/drivers/scsi/scsi_ioctl.c	Fri Feb  7 14:34:42 1997
@@ -247,6 +247,7 @@
 	retries = 1;
 	break;
       case START_STOP:
+      case MOVE_MEDIUM:
 	timeout =  60 * HZ;	/* 60 seconds */
 	retries = 1;
 	break;
diff -u --recursive --new-file v2.0.28/linux/fs/nfs/bio.c linux/fs/nfs/bio.c
--- v2.0.28/linux/fs/nfs/bio.c	Sat Jun 29 12:00:46 1996
+++ linux/fs/nfs/bio.c	Wed Jan 15 01:16:19 1997
@@ -210,6 +210,9 @@
 	unsigned long	address;
 	int		error = -1;
 
+	/* In case we're called from a page fault we want to */
+	/* make sure we're runnable before we schedule.. */
+	current->state = TASK_RUNNING;
 	dprintk("NFS: nfs_readpage %08lx\n", page_address(page));
 	address = page_address(page);
 	page->count++;
diff -u --recursive --new-file v2.0.28/linux/fs/nfs/rpcsock.c linux/fs/nfs/rpcsock.c
--- v2.0.28/linux/fs/nfs/rpcsock.c	Sun Sep  8 19:50:21 1996
+++ linux/fs/nfs/rpcsock.c	Thu Feb  6 17:32:41 1997
@@ -357,6 +357,9 @@
 	if (result < 4) {
 		printk(KERN_WARNING "RPC: impossible RPC reply size %d\n",
 						result);
+		iov[0].iov_base=(void*)&xid;	/* xid=32bits, which is large enough */
+		iov[0].iov_len=result;
+		rpc_recvmsg(rsock, iov, 1, result, 0);
 		return 0;
 	}
 
diff -u --recursive --new-file v2.0.28/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.0.28/linux/include/linux/pci.h	Fri Nov 22 16:26:05 1996
+++ linux/include/linux/pci.h	Fri Jan 24 20:56:58 1997
@@ -302,6 +302,7 @@
 #define PCI_VENDOR_ID_CT		0x102c
 #define PCI_DEVICE_ID_CT_65545		0x00d8
 #define PCI_DEVICE_ID_CT_65548		0x00dc
+#define PCI_DEVICE_ID_CT_65550		0x00e0
 
 #define PCI_VENDOR_ID_MIRO		0x1031
 #define PCI_DEVICE_ID_MIRO_36050	0x5601
diff -u --recursive --new-file v2.0.28/linux/include/scsi/scsi.h linux/include/scsi/scsi.h
--- v2.0.28/linux/include/scsi/scsi.h	Mon Jul  8 13:09:16 1996
+++ linux/include/scsi/scsi.h	Fri Feb  7 14:34:42 1997
@@ -74,12 +74,14 @@
 #define LOG_SENSE             0x4d
 #define MODE_SELECT_10        0x55
 #define MODE_SENSE_10         0x5a
+#define MOVE_MEDIUM           0xa5
 #define READ_12               0xa8
 #define WRITE_12              0xaa
 #define WRITE_VERIFY_12       0xae
 #define SEARCH_HIGH_12        0xb0
 #define SEARCH_EQUAL_12       0xb1
 #define SEARCH_LOW_12         0xb2
+#define READ_ELEMENT_STATUS   0xb8
 #define SEND_VOLUME_TAG       0xb6
 #define WRITE_LONG_2          0xea
 
diff -u --recursive --new-file v2.0.28/linux/net/ipv4/arp.c linux/net/ipv4/arp.c
--- v2.0.28/linux/net/ipv4/arp.c	Thu Oct 31 12:08:55 1996
+++ linux/net/ipv4/arp.c	Tue Feb  4 16:29:49 1997
@@ -1907,12 +1907,14 @@
 		/*
 		 *	net_alias_dev_rcv_sel32 returns main dev if it fails to found other.
 		 */
-		dev = net_alias_dev_rcv_sel32(dev, AF_INET, sip, tip);
+		if (ip_chk_addr(tip) == IS_MYADDR) {
+			dev = net_alias_dev_rcv_sel32(dev, AF_INET, sip, tip);
 
-		if (dev->type != ntohs(arp->ar_hrd) || dev->flags & IFF_NOARP)
-		{
-			kfree_skb(skb, FREE_READ);
-			return 0;
+			if (dev->type != ntohs(arp->ar_hrd) || dev->flags & IFF_NOARP)
+			{
+				kfree_skb(skb, FREE_READ);
+				return 0;
+			}
 		}
 	}
 #endif
diff -u --recursive --new-file v2.0.28/linux/net/ipv4/ip_input.c linux/net/ipv4/ip_input.c
--- v2.0.28/linux/net/ipv4/ip_input.c	Thu Jun  6 21:22:24 1996
+++ linux/net/ipv4/ip_input.c	Tue Feb  4 16:30:48 1997
@@ -302,8 +302,10 @@
 	 */
 
 #ifdef CONFIG_NET_ALIAS
-	if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev)) 
-		skb->dev = dev = net_alias_dev_rcv_sel32(skb->dev, AF_INET, iph->saddr, iph->daddr);
+	if (iph->daddr != skb->dev->pa_addr && net_alias_has(skb->dev)) {
+		if (ip_chk_addr(iph->daddr) == IS_MYADDR)
+			skb->dev = dev = net_alias_dev_rcv_sel32(skb->dev, AF_INET, iph->saddr, iph->daddr);
+	}
 #endif
 
 	if (iph->ihl > 5) 
