diff -u --recursive --new-file v1.1.86/linux/CREDITS linux/CREDITS
--- v1.1.86/linux/CREDITS	Mon Jan 30 06:41:55 1995
+++ linux/CREDITS	Sun Jan 29 12:30:17 1995
@@ -505,7 +505,7 @@
 S: Finland
 
 N: Kai M"akisara
-E: Kai.Makisara@vtt.fi
+E: Kai.Makisara@metla.fi
 D: SCSI Tape Driver
 
 N: Hamish Macdonald
diff -u --recursive --new-file v1.1.86/linux/Makefile linux/Makefile
--- v1.1.86/linux/Makefile	Mon Jan 30 06:41:55 1995
+++ linux/Makefile	Mon Jan 30 06:40:25 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 1
-SUBLEVEL = 86
+SUBLEVEL = 87
 
 ARCH = i386
 
diff -u --recursive --new-file v1.1.86/linux/arch/alpha/boot/main.c linux/arch/alpha/boot/main.c
--- v1.1.86/linux/arch/alpha/boot/main.c	Thu Jan 26 07:49:02 1995
+++ linux/arch/alpha/boot/main.c	Mon Jan 30 06:39:28 1995
@@ -162,42 +162,17 @@
 }
 
 /*
- * Start the kernel:
- * - switch to the proper PCB structure
- * - switch to the proper ptbr
- * - switch to the new kernel stack
+ * Start the kernel.
  */
 static void runkernel(void)
 {
-	struct pcb_struct * init_pcb = (struct pcb_struct *) INIT_PCB;
-	unsigned long oldptbr, *oldL1;
-	unsigned long newptbr, *newL1;
-
-	oldptbr = pcb_va->ptbr;
-	oldL1 = (unsigned long *) (PAGE_OFFSET + (oldptbr << PAGE_SHIFT));
-
-	newptbr = (SWAPPER_PGD - PAGE_OFFSET) >> PAGE_SHIFT;
-	newL1 = (unsigned long *) SWAPPER_PGD;
-
-	memcpy(newL1, oldL1, PAGE_SIZE);
-	newL1[1023] = (newptbr << 32) | pgprot_val(PAGE_KERNEL);
-
-	*init_pcb = *pcb_va;
-	init_pcb->ksp = PAGE_SIZE + INIT_STACK;
-	init_pcb->ptbr = newptbr;
-	
 	__asm__ __volatile__(
+		"bis %1,%1,$30\n\t"
 		"bis %0,%0,$26\n\t"
-		"bis %1,%1,$16\n\t"
-		".long %2\n\t"
-		"lda $16,-2($31)\n\t"
-		".long 51\n\t"
 		"ret ($26)"
 		: /* no outputs: it doesn't even return */
 		: "r" (START_ADDR),
-		  "r" (init_pcb),
-		  "i" (PAL_swpctx)
-		: "$16","$26");
+		  "r" (PAGE_SIZE + INIT_STACK));
 }
 
 void start_kernel(void)
diff -u --recursive --new-file v1.1.86/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v1.1.86/linux/arch/alpha/kernel/traps.c	Sun Jan 22 21:39:37 1995
+++ linux/arch/alpha/kernel/traps.c	Mon Jan 30 06:39:28 1995
@@ -47,6 +47,9 @@
 {
 	unsigned long gptr;
 
+	/*
+	 * Tell PAL-code what global pointer we want in the kernel..
+	 */
 	__asm__("br %0,___tmp\n"
 		"___tmp:\tldgp %0,0(%0)"
 		: "=r" (gptr));
diff -u --recursive --new-file v1.1.86/linux/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile
--- v1.1.86/linux/arch/alpha/lib/Makefile	Wed Jan 11 21:14:25 1995
+++ linux/arch/alpha/lib/Makefile	Mon Jan 30 06:39:28 1995
@@ -9,7 +9,7 @@
 .c.o:
 	$(CC) $(CFLAGS) -c $<
 
-OBJS  = __divqu.o __remqu.o __divlu.o __remlu.o
+OBJS  = __divqu.o __remqu.o __divlu.o __remlu.o memset.o
 
 lib.a: $(OBJS)
 	$(AR) rcs lib.a $(OBJS)
diff -u --recursive --new-file v1.1.86/linux/arch/alpha/lib/memset.c linux/arch/alpha/lib/memset.c
--- v1.1.86/linux/arch/alpha/lib/memset.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/alpha/lib/memset.c	Mon Jan 30 06:39:28 1995
@@ -0,0 +1,44 @@
+/*
+ *  linux/arch/alpha/lib/memset.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ */
+
+/*
+ * These are only slightly optimized so far..
+ */
+
+#include <linux/types.h>
+
+void * __constant_c_memset(void * s, unsigned long c, long count)
+{
+	unsigned long xs = (unsigned long) s;
+
+	/*
+	 * the first and last parts could be done with just one
+	 * unaligned load/store, but I don't want to think about it
+	 */
+	while (count > 0 && (xs & 7)) {
+		*(char *) xs = c;
+		count--; xs++;
+	}
+	while (count > 7) {
+		*(unsigned long *) xs = c;
+		count -=8; xs += 8;
+	}
+	while (count > 0) {
+		*(char *) xs = c;
+		count--; xs++;
+	}
+	return s;
+}
+
+void * __memset(void * s,char c,size_t count)
+{
+	char *xs = (char *) s;
+
+	while (count--)
+		*xs++ = c;
+
+	return s;
+}
diff -u --recursive --new-file v1.1.86/linux/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c
--- v1.1.86/linux/arch/alpha/mm/init.c	Thu Jan 26 07:49:02 1995
+++ linux/arch/alpha/mm/init.c	Mon Jan 30 06:39:29 1995
@@ -86,17 +86,25 @@
 
 extern unsigned long free_area_init(unsigned long, unsigned long);
 
+static void load_PCB(struct thread_struct * pcb)
+{
+	__asm__ __volatile__(
+		"stq $30,0(%0)\n\t"
+		"bis %0,%0,$16\n\t"
+		".long %1"
+		: /* no outputs */
+		: "r" (pcb), "i" (PAL_swpctx)
+		: "$0", "$1", "$16", "$22", "$23", "$24", "$25");
+}
+
 /*
  * paging_init() sets up the page tables: in the alpha version this actually
  * unmaps the bootup page table (as we're now in KSEG, so we don't need it).
- *
- * The bootup sequence put the virtual page table into high memory: that
- * means that we can change the L1 page table by just using VL1p below.
  */
-#define VL1p ((unsigned long *) 0xffffffffffffe000)
 unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
 {
 	int i;
+	unsigned long newptbr;
 	struct memclust_struct * cluster;
 	struct memdesc_struct * memdesc;
 
@@ -122,8 +130,14 @@
 	}
 
 	/* unmap the console stuff: we don't need it, and we don't want it */
-	for (i = 0; i < 1023; i++)
-		VL1p[i] = 0;
+	/* Also set up the real kernel PCB while we're at it.. */
+	memset((void *) ZERO_PGE, 0, PAGE_SIZE);
+	memset(swapper_pg_dir, 0, PAGE_SIZE);
+	newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT;
+	pgd_val(swapper_pg_dir[1023]) = (newptbr << 32) | pgprot_val(PAGE_KERNEL);
+	init_task.tss.ptbr = newptbr;
+	load_PCB(&init_task.tss);
+
 	invalidate_all();
 	return start_mem;
 }
diff -u --recursive --new-file v1.1.86/linux/arch/i386/boot/compressed/Makefile linux/arch/i386/boot/compressed/Makefile
--- v1.1.86/linux/arch/i386/boot/compressed/Makefile	Mon Jan  9 07:21:55 1995
+++ linux/arch/i386/boot/compressed/Makefile	Mon Jan 30 06:39:29 1995
@@ -31,5 +31,11 @@
 piggy.o:	$(SYSTEM) xtract piggyback
 		./xtract $(SYSTEM) | gzip -9 | ./piggyback > piggy.o
 
+xtract: xtract.c
+	$(HOSTCC) $(CFLAGS) -o xtract xtract.c
+
+piggyback: xtract.c
+	$(HOSTCC) $(CFLAGS) -o piggyback piggyback.c
+
 clean:
 	rm -f xtract piggyback vmlinux
diff -u --recursive --new-file v1.1.86/linux/arch/i386/config.in linux/arch/i386/config.in
--- v1.1.86/linux/arch/i386/config.in	Mon Jan 30 06:41:55 1995
+++ linux/arch/i386/config.in	Sun Jan 29 12:40:51 1995
@@ -41,7 +41,7 @@
 if [ "$CONFIG_NET" = "y" ]; then
 comment 'Networking options'
 bool 'TCP/IP networking' CONFIG_INET y
-if [ "$CONFIG_INET" "=" "y" ]; then
+if [ "$CONFIG_INET" = "y" ]; then
 bool 'IP forwarding/gatewaying' CONFIG_IP_FORWARD n
 bool 'IP multicasting (ALPHA)' CONFIG_IP_MULTICAST n
 bool 'IP firewalling' CONFIG_IP_FIREWALL n
diff -u --recursive --new-file v1.1.86/linux/drivers/block/Makefile linux/drivers/block/Makefile
--- v1.1.86/linux/drivers/block/Makefile	Sun Jan 22 21:39:38 1995
+++ linux/drivers/block/Makefile	Mon Jan 30 06:48:46 1995
@@ -21,8 +21,13 @@
 # In the future, some of these should be built conditionally.
 #
 
-OBJS := ll_rw_blk.o floppy.o ramdisk.o genhd.o 
-SRCS := ll_rw_blk.c floppy.c ramdisk.c genhd.c 
+OBJS := ll_rw_blk.o ramdisk.o genhd.o 
+SRCS := ll_rw_blk.c ramdisk.c genhd.c 
+
+ifdef CONFIG_BLK_DEV_FD
+OBJS := $(OBJS) floppy.o
+SRCS := $(SRCS) floppy.c
+endif
 
 ifdef CONFIG_CDU31A
 OBJS := $(OBJS) cdu31a.o
diff -u --recursive --new-file v1.1.86/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v1.1.86/linux/drivers/block/floppy.c	Sun Jan 22 23:03:58 1995
+++ linux/drivers/block/floppy.c	Mon Jan 30 06:48:46 1995
@@ -92,8 +92,6 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_BLK_DEV_FD
-
 #ifndef FD_MODULE
 /* the following is the mask of allowed drives. By default units 2 and
  * 3 of both floppy controllers are disabled, because switching on the
@@ -3393,4 +3391,3 @@
 #endif
 }
 
-#endif
diff -u --recursive --new-file v1.1.86/linux/drivers/block/sbpcd.c linux/drivers/block/sbpcd.c
--- v1.1.86/linux/drivers/block/sbpcd.c	Thu Jan 26 07:49:04 1995
+++ linux/drivers/block/sbpcd.c	Sun Jan 29 20:28:43 1995
@@ -7,11 +7,11 @@
  *            Also for the Longshine LCS-7260 drive.
  *            Also for the IBM "External ISA CD-Rom" drive.
  *            Not for the TEAC CD-55A drive (yet).
- *            Not for the CreativeLabs CD200 drive (yet).
+ *            Not for the CreativeLabs CD200 drive (who knows?).
  *
- *  NOTE:     This is release 3.2.
+ *  NOTE:     This is release 3.3.
  *            It works with my SbPro & drive CR-521 V2.11 from 2/92
- *            and with the new CR-562-B V0.75 on a "naked" Panasonic
+ *            and with the CR-562-B V0.75 on a "naked" Panasonic
  *            CI-101P interface. And vice versa. 
  *  
  *
@@ -178,6 +178,8 @@
  *     
  *  3.2  Still testing with CD200 and CD-55A drives.
  *
+ *  3.3  Working with CD200 support. Maybe a simple read is already possible.
+ *
  *  TODO
  *
  *     disk change detection
@@ -193,11 +195,8 @@
  *     thread which brought additional hints and bug fixes.
  * 
  *
- *   Copyright (C) 1993, 1994  Eberhard Moenkeberg <emoenke@gwdg.de>
- *                         or <eberhard_moenkeberg@rollo.central.de>
- *
- *                  The FTP-home of this driver is 
- *                  ftp.gwdg.de:/pub/linux/cdrom/drivers/sbpcd/.
+ *   Copyright (C) 1993, 1994, 1995  Eberhard Moenkeberg <emoenke@gwdg.de>
+ *                               or <eberhard_moenkeberg@rollo.central.de>
  *
  *                  If you change this software, you should mail a .diff
  *                  file with some description lines to emoenke@gwdg.de.
@@ -256,11 +255,13 @@
 
 #include "blk.h"
 
-#define VERSION "3.2 Eberhard Moenkeberg <emoenke@gwdg.de>"
+#define VERSION "3.3 Eberhard Moenkeberg <emoenke@gwdg.de>"
 
 /*
  * still testing around...
  */
+#define TEAC 0 /* set to 1 for TEAC CD-55A detection test (not more) */
+
 #define MULTISESSION_BY_DRIVER 0 /* if set to 0 here, we need the counterpart
                                   * in linux/fs/isofs/inode.c
                                   */
@@ -282,7 +283,7 @@
 #define PRINTK_BUG 0
 #define TEST_STI 0
 
-#define DISTRIBUTION 1
+#define DISTRIBUTION 1 /* I use it with a 0 here */
 
 #if 0
 #define INLINE
@@ -290,9 +291,6 @@
 #define INLINE inline
 #endif
 
-#define TEAC 0
-#define CD200 0
-
 /*==========================================================================*/
 /*
  * provisions for more than 1 driver issues
@@ -348,6 +346,7 @@
 static int sbpcd_probe[] = 
 {
   CDROM_PORT, SBPRO, /* probe with user's setup first */
+#if DISTRIBUTION
   0x230, 1, /* Soundblaster Pro and 16 (default) */
   0x300, 0, /* CI-101P (default), WDH-7001C (default),
 	       Galaxy (default), Reveal (one default) */
@@ -381,6 +380,7 @@
   0x290, 1, /* Soundblaster 16 */
   0x310, 0, /* Lasermate, CI-101P, WDH-7001C */
 #endif
+#endif DISTRIBUTION
 };
 #else
 static int sbpcd_probe[] = {CDROM_PORT, SBPRO}; /* probe with user's setup only */
@@ -460,12 +460,9 @@
 static int sbpcd_debug =  (1<<DBG_INF) |
                           (1<<DBG_TOC) |
                           (1<<DBG_MUL) |
-                          (1<<DBG_LCS) |
-                          (1<<DBG_TEA) |
-                          (1<<DBG_CD2) |
-                          (1<<DBG_ID)  |
                           (1<<DBG_UPC);
-#endif
+#endif DISTRIBUTION
+
 static int sbpcd_ioaddr = CDROM_PORT;	/* default I/O base address */
 static int sbpro_type = SBPRO;
 static unsigned char setup_done = 0;
@@ -559,7 +556,7 @@
   char drv_sel; /* drive select lines bits */
 
   char drive_model[9];
-  char firmware_version[4];
+  u_char firmware_version[4];
   char f_eject; /* auto-eject flag: 0 or 1 */
   u_char *sbp_buf; /* Pointer to internal data buffer,
                            space allocated during sbpcd_init() */
@@ -583,7 +580,11 @@
   
   u_char f_multisession;
   u_int lba_multi;
+#if MULTISESSION_BY_DRIVER
   u_int last_redirect;
+#endif MULTISESSION_BY_DRIVER
+  int first_session;
+  int last_session;
   
   u_char audio_state;
   u_int pos_audio_start;
@@ -881,7 +882,7 @@
   return (-1);
 }
 /*==========================================================================*/
-#if TEAC
+#if TEAC-X
 /*==========================================================================*/
 static int tst_DataReady(void)
 {
@@ -910,7 +911,7 @@
   return (0);
 }
 /*==========================================================================*/
-#endif TEAC
+#endif TEAC-X
 /*==========================================================================*/
 static int ResponseInfo(void)
 {
@@ -1048,7 +1049,7 @@
   else /* CD200, CD-55A */
     {
     }
-  if (!fam0_drive) for (i=0;i<6;i++) OUT(CDo_command,0);
+  if (!fam0L_drive) for (i=0;i<6;i++) OUT(CDo_command,0);
   SBPCD_STI;
 }
 /*==========================================================================*/
@@ -1073,18 +1074,25 @@
       else
 	flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus;
     }
-  else /* CD200, CD-55A */
+  else if (fam2_drive)
+    {
+      drvcmd[0]=CMD2_READ_ERR;
+      response_count=6;
+      flags_cmd_out=f_putcmd;
+    }
+  else /* CD-55A */
     {
+      return (-1);
+      drvcmd[0]=CMDT_READ_ERR;
+      response_count=5;
+      flags_cmd_out=f_putcmd;
     }
   i=cmd_out(7);
   DriveStruct[d].error_byte=0;
   DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: cmd_out(82) returns %d (%02X)\n",i,i));
   if (i<0) return (i);
   if (fam0_drive) i=1;
-  else if (fam1L_drive) i=2;
-  else /* CD200, CD-55A */
-    {
-    }
+  else i=2;
   DriveStruct[d].error_byte=infobuf[i];
   DPRINTF((DBG_ERR,"SBPCD: xx_ReadError: infobuf[%d] is %d (%02X)\n",i,DriveStruct[d].error_byte,DriveStruct[d].error_byte));
   i=sta2err(infobuf[i]);
@@ -1163,7 +1171,7 @@
   if (f_blk_msf>1) return (-3);
   if (fam0_drive)
     {
-      drvcmd[0]=CMD0_SEEK; /* same as CMD1_ and CMDL_ */
+      drvcmd[0]=CMD0_SEEK;
       if (f_blk_msf==1) pos=msf2blk(pos);
       drvcmd[2]=(pos>>16)&0x00FF;
       drvcmd[3]=(pos>>8)&0x00FF;
@@ -1183,8 +1191,19 @@
       else
 	flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
     }
-  else /* CD200, CD-55A */
+  else if (fam2_drive)
+    {
+      drvcmd[0]=CMD2_SEEK;
+      if (f_blk_msf==0) pos=blk2msf(pos);
+      drvcmd[2]=(pos>>16)&0x00FF;
+      drvcmd[3]=(pos>>16)&0x00FF;
+      drvcmd[4]=(pos>>8)&0x00FF;
+      drvcmd[5]=pos&0x00FF;
+      flags_cmd_out=f_putcmd|f_ResponseStatus;
+    }
+  else /* CD-55A */
     {
+      return (-1);
     }
   response_count=0;
   i=cmd_out(7);
@@ -1209,8 +1228,15 @@
       drvcmd[0]=CMD1_SPINUP;
       flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
     }
-  else /* CD200, CD-55A */
+  else if (fam2_drive)
+    {
+      drvcmd[0]=CMD2_TRAY_CTL;
+      drvcmd[4]=0x01;
+      flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
+    }
+  else /* CD-55A */
     {
+      return (-1);
     }
   response_count=0;
   i=cmd_out(7);
@@ -1224,21 +1250,27 @@
 
   if (fam0_drive) return (-3);
   clr_cmdbuf();
+  response_count=0;
   if (fam1_drive)
     {
       drvcmd[0]=CMD1_SPINDOWN;
       flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
-      response_count=0;
+    }
+  else if (fam2_drive)
+    {
+      drvcmd[0]=CMD2_TRAY_CTL;
+      drvcmd[4]=0x02; /* "eject" */
+      flags_cmd_out=f_putcmd|f_ResponseStatus;
     }
   else if (famL_drive)
     {
       drvcmd[0]=CMDL_SPINDOWN;
       drvcmd[1]=1;
       flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
-      response_count=0;
     }
-  else /* CD200, CD-55A */
+  else /* CD-55A */
     {
+      return (-1);
     }
   i=cmd_out(7);
   return (i);
@@ -1250,13 +1282,35 @@
 
   if (fam0L_drive) return (-3);
   clr_cmdbuf();
-  drvcmd[0]=CMD1_SETMODE;
-  drvcmd[1]=0x03;
-  drvcmd[2]=speed;
-  drvcmd[3]=x1;
-  drvcmd[4]=x2;
-  flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
   response_count=0;
+  if (fam1_drive)
+    {
+      drvcmd[0]=CMD1_SETMODE;
+      drvcmd[1]=0x03;
+      drvcmd[2]=speed;
+      drvcmd[3]=x1;
+      drvcmd[4]=x2;
+      flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
+    }
+  else if (fam2_drive)
+    {
+      drvcmd[0]=CMD2_SETSPEED;
+      if (speed&speed_auto)
+	{
+	  drvcmd[2]=0xFF;
+	  drvcmd[3]=0xFF;
+	}
+      else
+	{
+	  drvcmd[2]=0;
+	  drvcmd[3]=150;
+	}
+      flags_cmd_out=f_putcmd|f_ResponseStatus;
+    }
+  else /* CD-55A */
+    {
+      return (-1);
+    }
   i=cmd_out(7);
   return (i);
 }
@@ -1315,6 +1369,22 @@
       drvcmd[6]=value1;
       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
     }
+  else if (fam2_drive)
+    {
+      control0=channel0+1;
+      control1=channel1+1;
+      value0=(volume0>volume1)?volume0:volume1;
+      value1=value0;
+      if (volume0==0) control0=0;
+      if (volume1==0) control1=0;
+      drvcmd[0]=CMD2_SETMODE;
+      drvcmd[1]=0x0E;
+      drvcmd[3]=control0;
+      drvcmd[4]=value0;
+      drvcmd[5]=control1;
+      drvcmd[6]=value1;
+      flags_cmd_out=f_putcmd|f_ResponseStatus;
+    }
   else if (famL_drive)
     {
       if ((volume0==0)||(channel0!=0)) control0 |= 0x80;
@@ -1392,8 +1462,9 @@
       drvcmd[5]=value0;
       flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
     }
-  else /* CD200, CD-55A */
+  else /* CD-55A */
     {
+      return (-1);
     }
   response_count=0;
   i=cmd_out(7);
@@ -1418,17 +1489,25 @@
   int i;
 
   DPRINTF((DBG_RES,"SBPCD: xy_DriveReset called.\n"));
+  clr_cmdbuf();
+  response_count=0;
   if (fam0L_drive) OUT(CDo_reset,0x00);
   else if (fam1_drive)
     {
-      clr_cmdbuf();
       drvcmd[0]=CMD1_RESET;
       flags_cmd_out=f_putcmd;
-      response_count=0;
       i=cmd_out(7);
     }
-  else /* CD200, CD-55A */
+  else if (fam2_drive)
     {
+      drvcmd[0]=CMD2_RESET;
+      flags_cmd_out=f_putcmd;
+      i=cmd_out(7);
+      OUT(CDo_reset,0x00);
+    }
+  else /* CD-55A */
+    {
+      return (-1);
     }
   if (famL_drive) sbp_sleep(500); /* wait 5 seconds */
   else sbp_sleep(100); /* wait a second */
@@ -1483,14 +1562,23 @@
   int i;
 
   clr_cmdbuf();
+  response_count=0;
   if (fam1_drive)
     {
       drvcmd[0]=CMD1_PAU_RES;
+      if (pau_res!=1) drvcmd[1]=0x80;
       flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
     }
+  else if (fam2_drive)
+    {
+      drvcmd[0]=CMD2_PAU_RES;
+      if (pau_res!=1) drvcmd[2]=0x01;
+      flags_cmd_out=f_putcmd|f_ResponseStatus;
+    }
   else if (fam0L_drive)
     {
       drvcmd[0]=CMD0_PAU_RES;
+      if (pau_res!=1) drvcmd[1]=0x80;
       if (famL_drive)
 	flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
 	  f_obey_p_check|f_bit1;
@@ -1498,11 +1586,10 @@
 	flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|
 	  f_obey_p_check;
     }
-  else /* CD200, CD-55A */
+  else /* CD-55A */
     {
+      return (-1);
     }
-  if (pau_res!=1) drvcmd[1]=0x80;
-  response_count=0;
   i=cmd_out(7);
   return (i);
 }
@@ -1515,22 +1602,28 @@
   DPRINTF((DBG_LCK,"SBPCD: yy_LockDoor: %d (drive %d)\n", lock, d));
   DPRINTF((DBG_LCS,"SBPCD: p_door_locked bit %d before\n", st_door_locked));
   clr_cmdbuf();
+  response_count=0;
   if (fam1_drive)
     {
       drvcmd[0]=CMD1_LOCK_CTL;
       if (lock==1) drvcmd[1]=0x01;
       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
-      response_count=0;
+    }
+  else if (fam2_drive)
+    {
+      drvcmd[0]=CMD2_LOCK_CTL;
+      if (lock==1) drvcmd[4]=0x01;
+      flags_cmd_out=f_putcmd|f_ResponseStatus;
     }
   else if (famL_drive)
     {
       drvcmd[0]=CMDL_LOCK_CTL;
       if (lock==1) drvcmd[1]=0x01;
       flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|f_ResponseStatus|f_obey_p_check|f_bit1;
-      response_count=0;
     }
-  else /* CD200, CD-55A */
+  else /* CD-55A */
     {
+      return (-1);
     }
   i=cmd_out(7);
   DPRINTF((DBG_LCS,"SBPCD: p_door_locked bit %d after\n", st_door_locked));
@@ -1546,21 +1639,29 @@
   DPRINTF((DBG_LCS,"SBPCD: p_door_closed bit %d before\n", st_door_closed));
 
   clr_cmdbuf();
+  response_count=0;
   if (fam1_drive)
     {
       drvcmd[0]=CMD1_TRAY_CTL;
       flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
     }
+  else if (fam2_drive)
+    {
+      drvcmd[0]=CMD2_TRAY_CTL;
+      drvcmd[1]=0x01;
+      drvcmd[4]=0x03; /* "insert" */
+      flags_cmd_out=f_putcmd|f_ResponseStatus;
+    }
   else if (famL_drive)
     {
       drvcmd[0]=CMDL_TRAY_CTL;
       flags_cmd_out=f_putcmd|f_respo2|f_lopsta|f_getsta|
  	f_ResponseStatus|f_obey_p_check|f_bit1;
     }
-  else /* CD200, CD-55A */
+  else /* CD-55A */
     {
+      return (-1);
     }
-  response_count=0;
   i=cmd_out(7);
   DPRINTF((DBG_LCS,"SBPCD: p_door_closed bit %d after\n", st_door_closed));
   return (i);
@@ -1580,6 +1681,14 @@
 	  flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
 	  response_count=11;
 	}
+      else if (fam2_drive)
+	{
+	  drvcmd[0]=CMD2_READSUBQ;
+	  drvcmd[1]=0x02;
+	  drvcmd[3]=0x01;
+	  flags_cmd_out=f_putcmd;
+	  response_count=10;
+	}
       else if (fam0L_drive)
 	{
 	  drvcmd[0]=CMD0_READSUBQ;
@@ -1590,13 +1699,14 @@
  	    flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
 	  response_count=13;
 	}
-      else /* CD200, CD-55A */
+      else /* CD-55A */
 	{
+	  return (-1);
 	}
       i=cmd_out(7);
       if (i<0) return (i);
       DPRINTF((DBG_SQ,"SBPCD: xx_ReadSubQ:"));
-      for (i=0;i<(fam1_drive?11:13);i++)
+      for (i=0;i<response_count;i++)
 	{
 	  DPRINTF((DBG_SQ," %02X", infobuf[i]));
 	}
@@ -1627,34 +1737,34 @@
 {
   int i;
 
+  if (fam2_drive) return (0);
   DriveStruct[d].diskstate_flags &= ~frame_size_bit;
   clr_cmdbuf();
   if (fam1_drive)
     {
       drvcmd[0]=CMD1_GETMODE;
-      drvcmd[1]=0x00;
       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
       response_count=5;
     }
   else if (fam0L_drive)
     {
       drvcmd[0]=CMD0_GETMODE;
-      drvcmd[1]=0x00;
       if (famL_drive)
 	flags_cmd_out=f_putcmd;
       else
 	flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
       response_count=2;
     }
-  else /* CD200, CD-55A */
+  else /* CD-55A */
     {
+      return (-1);
     }
   i=cmd_out(7);
   if (i<0) return (i);
   i=0;
-  if (fam0L_drive) DriveStruct[d].sense_byte=0;
   if (fam1_drive) DriveStruct[d].sense_byte=infobuf[i++];
-  else /* CD200, CD-55A */
+  else if (fam0L_drive) DriveStruct[d].sense_byte=0;
+  else /* CD-55A */
     {
     }
   DriveStruct[d].frame_size=make16(infobuf[i],infobuf[i+1]);
@@ -1675,6 +1785,7 @@
 {
   int i;
 
+  if (fam2_drive) return (0);
   DriveStruct[d].diskstate_flags &= ~frame_size_bit;
   clr_cmdbuf();
   DriveStruct[d].frame_size=framesize;
@@ -1705,8 +1816,9 @@
       else
 	flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
     }
-  else /* CD200, CD-55A */
+  else /* CD-55A */
     {
+      return (-1);
     }
   response_count=0;
   i=cmd_out(7);
@@ -1731,6 +1843,13 @@
       response_count=5;
       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
     }
+  else if (fam2_drive)
+    {
+      drvcmd[0]=CMD2_GETMODE;
+      drvcmd[1]=0x0E;
+      response_count=5;
+      flags_cmd_out=f_putcmd;
+    }
   else if (fam0L_drive)
     {
       drvcmd[0]=CMD0_GETMODE;
@@ -1741,8 +1860,9 @@
       else
 	flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
     }
-  else /* CD200, CD-55A */
+  else /* CD-55A */
     {
+      return (-1);
     }
   i=cmd_out(7);
   if (i<0) return (i);
@@ -1765,6 +1885,13 @@
       chan0 >>= 1;
       chan1 >>= 1;
     }
+  else if (fam2_drive)
+    {
+      chan0=infobuf[1];
+      vol0=infobuf[2];
+      chan1=infobuf[3];
+      vol1=infobuf[4];
+    }
   else if (famL_drive)
     {
       chan0=0;
@@ -1804,26 +1931,18 @@
             }
         }
     }
-  else /* CD200, CD-55A */
+  else /* CD-55A */
     {
+      return (-1);
     }
   DriveStruct[d].vol_chan0=chan0;
   DriveStruct[d].vol_ctrl0=vol0;
   DriveStruct[d].vol_chan1=chan1;
   DriveStruct[d].vol_ctrl1=vol1;
-  if (fam01_drive)
-    {
-      DriveStruct[d].vol_chan2=2;
-      DriveStruct[d].vol_ctrl2=0xFF;
-      DriveStruct[d].vol_chan3=3;
-      DriveStruct[d].vol_ctrl3=0xFF;
-    }
-  else if (famL_drive)
-    {
-    }
-  else /* CD200, CD-55A */
-    {
-    }
+  DriveStruct[d].vol_chan2=2;
+  DriveStruct[d].vol_ctrl2=0xFF;
+  DriveStruct[d].vol_chan3=3;
+  DriveStruct[d].vol_ctrl3=0xFF;
   DriveStruct[d].diskstate_flags |= volume_bit;
   return (0);
 }
@@ -1833,31 +1952,39 @@
 {
   int i;
 
+  if (famL_drive) return (0);
   DriveStruct[d].diskstate_flags &= ~cd_size_bit;
   clr_cmdbuf();
   if (fam1_drive)
     {
       drvcmd[0]=CMD1_CAPACITY;
+      response_count=5;
       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
     }
-  else if (fam0L_drive)
+  else if (fam2_drive)
+    {
+      drvcmd[0]=CMD2_CAPACITY;
+      response_count=8;
+      flags_cmd_out=f_putcmd;
+    }
+  else if (fam0_drive)
     {
       drvcmd[0]=CMD0_CAPACITY;
+      response_count=5;
       if(famL_drive)
 	flags_cmd_out=f_putcmd;
       else
 	flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
     }
-  else /* CD200, CD-55A */
+  else /* CD-55A */
     {
+      return (-1);
     }
-  response_count=5;
   i=cmd_out(7);
   if (i<0) return (i);
-  DriveStruct[d].CDsize_blk=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
-  if (fam1_drive) DriveStruct[d].CDsize_blk=msf2blk(DriveStruct[d].CDsize_blk);
-  DriveStruct[d].CDsize_frm = (DriveStruct[d].CDsize_blk * make16(infobuf[3],infobuf[4])) / CD_FRAMESIZE;
-  DriveStruct[d].CDsize_blk += 151;
+  if (fam1_drive) DriveStruct[d].CDsize_frm=msf2blk(make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2])))+CD_BLOCK_OFFSET;
+  else if (fam0_drive) DriveStruct[d].CDsize_frm=make32(make16(0,infobuf[0]),make16(infobuf[1],infobuf[2]));
+  else if (fam2_drive) DriveStruct[d].CDsize_frm=make32(make16(infobuf[0],infobuf[1]),make16(infobuf[2],infobuf[3]));
   DriveStruct[d].diskstate_flags |= cd_size_bit;
   return (0);
 }
@@ -1871,30 +1998,93 @@
   if (fam1_drive)
     {
       drvcmd[0]=CMD1_DISKINFO;
+      response_count=6;
       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
     }
   else if (fam0L_drive)
     {
       drvcmd[0]=CMD0_DISKINFO;
+      response_count=6;
       if(famL_drive)
 	flags_cmd_out=f_putcmd;
       else
 	flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
     }
-  else /* CD200, CD-55A */
+  else if (fam2_drive)
     {
+      /* possibly longer timeout periods necessary */
+      DriveStruct[d].f_multisession=0;
+      drvcmd[0]=CMD2_DISKINFO;
+      drvcmd[1]=0x02;
+      drvcmd[2]=0xAB;
+      drvcmd[3]=0xFF; /* session */
+      response_count=8;
+      flags_cmd_out=f_putcmd;
+    }
+  else /* CD-55A */
+    {
+      return (-1);
     }
-  response_count=6;
   i=cmd_out(7);
   if (i<0) return (i);
   DriveStruct[d].xa_byte=infobuf[0];
-  DriveStruct[d].n_first_track=infobuf[1];
-  DriveStruct[d].n_last_track=infobuf[2];
-  DriveStruct[d].size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
-  DriveStruct[d].size_blk=msf2blk(DriveStruct[d].size_msf);
+  if (fam2_drive)
+    {
+      DriveStruct[d].first_session=infobuf[1];
+      DriveStruct[d].last_session=infobuf[2];
+      DriveStruct[d].n_first_track=infobuf[3];
+      DriveStruct[d].n_last_track=infobuf[4];
+      if (DriveStruct[d].first_session!=DriveStruct[d].last_session)
+	{
+	  DriveStruct[d].f_multisession=1;
+	  DriveStruct[d].lba_multi=msf2blk(make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7])));
+	}
+#if 0
+      if (DriveStruct[d].first_session!=DriveStruct[d].last_session)
+	{
+	  if (DriveStruct[d].last_session<=20)
+	    zwanzig=DriveStruct[d].last_session+1;
+	  else zwanzig=20;
+	  for (count=DriveStruct[d].first_session;count<zwanzig;count++)
+	    {
+	      drvcmd[0]=CMD2_DISKINFO;
+	      drvcmd[1]=0x02;
+	      drvcmd[2]=0xAB;
+	      drvcmd[3]=count;
+	      response_count=8;
+	      flags_cmd_out=f_putcmd;
+	      i=cmd_out(7);
+	      if (i<0) return (i);
+	      DriveStruct[d].msf_multi_n[count]=make32(make16(0,infobuf[5]),make16(infobuf[6],infobuf[7]));
+	    }
+	  DriveStruct[d].diskstate_flags |= multisession_bit;
+	}
+#endif
+      drvcmd[0]=CMD2_DISKINFO;
+      drvcmd[1]=0x02;
+      drvcmd[2]=0xAA;
+      drvcmd[3]=0xFF;
+      response_count=5;
+      flags_cmd_out=f_putcmd;
+      i=cmd_out(7);
+      if (i<0) return (i);
+      DriveStruct[d].size_msf=make32(make16(0,infobuf[2]),make16(infobuf[3],infobuf[4]));
+      DriveStruct[d].size_blk=msf2blk(DriveStruct[d].size_msf);
+    }
+  else
+    {
+      DriveStruct[d].n_first_track=infobuf[1];
+      DriveStruct[d].n_last_track=infobuf[2];
+      DriveStruct[d].size_msf=make32(make16(0,infobuf[3]),make16(infobuf[4],infobuf[5]));
+      DriveStruct[d].size_blk=msf2blk(DriveStruct[d].size_msf);
+      if (famL_drive) DriveStruct[d].CDsize_frm=DriveStruct[d].size_blk+1;
+    }
   DriveStruct[d].diskstate_flags |= toc_bit;
   DPRINTF((DBG_TOC,"SBPCD: TocDesc: %02X %02X %02X %08X\n",
-	 DriveStruct[d].xa_byte,DriveStruct[d].n_first_track,DriveStruct[d].n_last_track,DriveStruct[d].size_msf));
+	   DriveStruct[d].xa_byte,
+	   DriveStruct[d].n_first_track,
+	   DriveStruct[d].n_last_track,
+	   DriveStruct[d].size_msf));
   return (0);
 }
 /*==========================================================================*/
@@ -1906,30 +2096,49 @@
   if (fam1_drive)
     {
       drvcmd[0]=CMD1_READTOC;
+      response_count=8;
       flags_cmd_out=f_putcmd|f_ResponseStatus|f_obey_p_check;
     }
+  else if (fam2_drive)
+    {
+      /* possibly longer timeout periods necessary */
+      drvcmd[0]=CMD2_DISKINFO;
+      drvcmd[1]=0x02;
+      response_count=5;
+      flags_cmd_out=f_putcmd;
+    }
   else if (fam0L_drive)
     {
       drvcmd[0]=CMD0_READTOC;
       drvcmd[1]=0x02;
+      response_count=8;
       if(famL_drive)
 	flags_cmd_out=f_putcmd;
       else
 	flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
     }
-  else /* CD200, CD-55A */
+  else /* CD-55A */
     {
+      return (-1);
     }
   drvcmd[2]=num;
-  response_count=8;
   i=cmd_out(7);
   if (i<0) return (i);
-  DriveStruct[d].TocEnt_nixbyte=infobuf[0];
-  DriveStruct[d].TocEnt_ctl_adr=swap_nibbles(infobuf[1]);
-  DriveStruct[d].TocEnt_number=infobuf[2];
-  DriveStruct[d].TocEnt_format=infobuf[3];
+  if (fam2_drive) i=0;
+  else
+    {
+      DriveStruct[d].TocEnt_nixbyte=infobuf[0];
+      i=1;
+    }
+  DriveStruct[d].TocEnt_ctl_adr=swap_nibbles(infobuf[i++]);
+  if (!(fam2_drive))
+    {
+      DriveStruct[d].TocEnt_number=infobuf[i++];
+      DriveStruct[d].TocEnt_format=infobuf[i];
+    }
   if (fam1_drive) i=4;
-  else i=5;
+  else if (fam0L_drive) i=5;
+  else if (fam2_drive) i=2;
   DriveStruct[d].TocEnt_address=make32(make16(0,infobuf[i]),
 				       make16(infobuf[i+1],infobuf[i+2]));
   DPRINTF((DBG_TOC,"SBPCD: TocEntry: %02X %02X %02X %02X %08X\n",
@@ -1952,6 +2161,7 @@
     flags_cmd_out=f_putcmd|f_getsta|f_ResponseStatus|f_obey_p_check;
   else /* CD200, CD-55A */
     {
+      return (-1);
     }
   i=cmd_out(7);
   return (i);
@@ -1973,6 +2183,7 @@
 	}
       else /* CD200, CD-55A */
 	{
+	  return (-1);
 	}
     }
   DriveStruct[d].UPC_buf[6] &= 0xF0;
@@ -2016,6 +2227,7 @@
 	}
       else /* CD200, CD-55A */
 	{
+	  return (-1);
 	}
       i=cmd_out(7);
       if (i<0) return (i);
@@ -2067,10 +2279,11 @@
 {
   int i;
 
+  if (fam2_drive) return (0);
   DriveStruct[d].f_multisession=0;
-  clr_cmdbuf();
   DriveStruct[d].lba_multi=0;
   if (fam0_drive) return (0);
+  clr_cmdbuf();
   if (fam1_drive)
     {
       drvcmd[0]=CMD1_MULTISESS;
@@ -2083,11 +2296,9 @@
 	  DriveStruct[d].f_multisession=1;
 	  DriveStruct[d].lba_multi=msf2blk(make32(make16(0,infobuf[1]),
 						  make16(infobuf[2],infobuf[3])));
+#if MULTISESSION_BY_DRIVER
 	  DriveStruct[d].last_redirect=19;
-	  /* preliminary - has to get adjusted the following way:
-           *   look at the first byte of frames 17 ff. until 0xFF is seen
-           *   the frame before this one is the last continuation frame
-           */
+#endif MULTISESSION_BY_DRIVER
 	  DPRINTF((DBG_MUL,"SBPCD: MultiSession CD detected: %02X %02X %02X %02X %02X %02X (%d)\n",
 		   infobuf[0], infobuf[1], infobuf[2],
 		   infobuf[3], infobuf[4], infobuf[5],
@@ -2113,15 +2324,14 @@
 	{
 	  DPRINTF((DBG_MUL,"SBPCD: MultiSession base: %06X\n", DriveStruct[d].lba_multi));
 	  DriveStruct[d].f_multisession=1;
+#if MULTISESSION_BY_DRIVER
 	  DriveStruct[d].last_redirect=19;
-	  /* preliminary - has to get adjusted the following way:
-	   *   look at the first byte of frames 17 ff. until 0xFF is seen;
-	   *   the frame before this one is the last repetition frame.
-	   */
+#endif MULTISESSION_BY_DRIVER
 	}
     }
-  else /* CD200, CD-55A */
+  else /* CD-55A */
     {
+      return (-1);
     }
   return (0);
 }
@@ -2198,7 +2408,7 @@
 #endif CDMKE
 }
 /*==========================================================================*/
-#if TEAC
+#if TEAC-X
 /*==========================================================================*/
 static void teac_reset(int drv_id)
 {
@@ -2242,7 +2452,7 @@
   return (found);
 }
 /*==========================================================================*/
-#endif TEAC
+#endif TEAC-X
 /*==========================================================================*/
 /*==========================================================================*/
 #ifdef CD200
@@ -2310,11 +2520,31 @@
 static int check_version(void)
 {
   int i, j;
+  u_char lcs_firm[][4]={"A4F4","A E1"};
 
   DPRINTF((DBG_INI,"SBPCD: check_version entered.\n"));
   DriveStruct[d].drv_type=0;
 
-  /* check for CD200 first */
+#if TEAC
+  /* check for CD-55A */
+  clr_cmdbuf();
+  drvcmd[0]=CMDT_READ_ERR;
+  response_count=5;
+  flags_cmd_out=f_putcmd;
+  i=cmd_out(7);
+  if (i<0) DPRINTF((DBG_INI,"SBPCD: CMDT_READERR returns %d (ok anyway).\n",i));
+  /* read drive version */
+  clr_cmdbuf();
+  for (i=0;i<12;i++) infobuf[i]=0;
+  if (sbpro_type==1) OUT(CDo_sel_i_d,0);
+  response_count=12; /* may be too much */
+  drvcmd[0]=CMDT_READ_VER;
+  drvcmd[4]=response_count;
+  flags_cmd_out=f_putcmd;
+  i=cmd_out(10); /* possibly only 6 */
+  if (i<0) DPRINTF((DBG_INI,"SBPCD: CMDT_READ_VER returns %d\n",i));
+#else
+  /* check for CD200 */
   clr_cmdbuf();
   drvcmd[0]=CMD2_READ_ERR;
   response_count=9;
@@ -2335,27 +2565,7 @@
   flags_cmd_out=f_putcmd;
   i=cmd_out(7);
   if (i<0) DPRINTF((DBG_INI,"SBPCD: CMD2_READ_VER returns %d\n",i));
-
-  if (i<0)
-    {
-      /* check for CD-55A */
-      clr_cmdbuf();
-      drvcmd[0]=CMDT_READ_ERR;
-      response_count=5;
-      flags_cmd_out=f_putcmd;
-      i=cmd_out(7);
-      if (i<0) DPRINTF((DBG_INI,"SBPCD: CMDT_READERR returns %d (ok anyway).\n",i));
-      /* read drive version */
-      clr_cmdbuf();
-      for (i=0;i<12;i++) infobuf[i]=0;
-      if (sbpro_type==1) OUT(CDo_sel_i_d,0);
-      response_count=12; /* may be too much */
-      drvcmd[0]=CMDT_READ_VER;
-      drvcmd[4]=response_count;
-      flags_cmd_out=f_putcmd;
-      i=cmd_out(10); /* possibly only 6 */
-      if (i<0) DPRINTF((DBG_INI,"SBPCD: CMDT_READ_VER returns %d\n",i));
-    }
+#endif TEAC
   if (i>=0) /* either from CD200 or CD-55A */
     {
       for (i=0, j=0;i<12;i++) j+=infobuf[i];
@@ -2473,12 +2683,14 @@
   for (j=0;j<4;j++) DriveStruct[d].firmware_version[j]=infobuf[i+j];
   if (famL_drive)
     {
+      for (i=0;i<2;i++)
+	{
+	  for (j=0;j<4;j++)
+	    if (DriveStruct[d].firmware_version[j]!=lcs_firm[i][j]) break;
+	  if (j==4) break;
+	}
+      if (j!=4) ask_mail();
       DriveStruct[d].drv_type=drv_260;
-      if ((DriveStruct[d].firmware_version[0]!='A') ||
-	  (DriveStruct[d].firmware_version[1]!='4') ||
-	  (DriveStruct[d].firmware_version[2]!='F') ||
-	  (DriveStruct[d].firmware_version[3]!='4'))
-	ask_mail();
     }
   else if (famT_drive)
     {
@@ -2511,13 +2723,9 @@
 	{
 	  printk("\n\nSBPCD: new drive CD200 (%s)detected.\n",
 		 DriveStruct[d].firmware_version);
-	  printk("SBPCD: support is not fulfilled yet - drive gets ignored.\n");
+	  printk("SBPCD: support is not fulfilled yet.\n");
 	  if (j!=101) /* only 1.01 known at time */
 	    ask_mail();
-	  else
-	    printk("SBPCD: just wait some days...\n\n");
-	  DriveStruct[d].drv_type=0;
-	  return (-1);
 	}
     }
   DPRINTF((DBG_LCS,"SBPCD: drive type %02X\n",DriveStruct[d].drv_type));
@@ -3284,9 +3492,10 @@
 	int error_flag;
 
 	DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADAUDIO requested.\n"));
-#if 0
-	if (fam0L_drive) return (-EINVAL);
-#endif
+	if (fam0_drive) return (-EINVAL);
+	if (famL_drive) return (-EINVAL);
+	if (fam2_drive) return (-EINVAL);
+	if (famT_drive) return (-EINVAL);
 	if (DriveStruct[d].aud_buf==NULL) return (-EINVAL);
 	i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_read_audio));
 	if (i) return (i);
@@ -3717,13 +3926,21 @@
     }
   else if (fam1_drive)
     {
-      drvcmd[0]=CMD1_READ; /* "read frames", new drives */
+      drvcmd[0]=CMD1_READ;
       lba2msf(block,&drvcmd[1]); /* msf-bin format required */
       drvcmd[4]=0;
       drvcmd[5]=0;
       drvcmd[6]=DriveStruct[d].sbp_read_frames;
     }
-  else /* CD200, CD-55A */
+  else if (fam2_drive)
+    {
+      drvcmd[0]=CMD2_READ;
+      lba2msf(block,&drvcmd[1]); /* msf-bin format required */
+      drvcmd[4]=0;
+      drvcmd[5]=DriveStruct[d].sbp_read_frames;
+      drvcmd[6]=0x02;
+    }
+  else /* CD-55A */
     {
     }
   SBPCD_CLI;
@@ -4004,7 +4221,7 @@
   sbpcd_release,          /* release */
   NULL,                   /* fsync */
   NULL,                   /* fasync */
-  sbpcd_chk_disk_change,     /* media_change */
+  sbpcd_chk_disk_change,  /* media_change */
   NULL                    /* revalidate */
 };
 /*==========================================================================*/
diff -u --recursive --new-file v1.1.86/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v1.1.86/linux/drivers/char/Makefile	Mon Jan 30 06:41:56 1995
+++ linux/drivers/char/Makefile	Fri Jan 27 16:54:02 1995
@@ -94,9 +94,9 @@
 
 dep:
 	$(CPP) -M $(SRCS) > .depend
-#ifdef MODULES
+ifdef MODULES
 	$(CPP) -M -DMODULE $(MODULES:.o=.c) >> .depend
-#endif
+endif
 
 dummy:
 
diff -u --recursive --new-file v1.1.86/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- v1.1.86/linux/drivers/scsi/sr.c	Mon Jan 30 06:41:57 1995
+++ linux/drivers/scsi/sr.c	Mon Jan 30 06:51:02 1995
@@ -304,11 +304,16 @@
  *   kraxel@cs.tu-berlin.de (Gerd Knorr)
  */
 
+#define DEBUG
+
 static void sr_photocd(struct inode *inode)
 {
   unsigned long   sector,min,sec,frame;
-  unsigned char   buf[40];
-  int             rc;
+  unsigned char   buf[40];    /* the buffer for the ioctl */
+  unsigned char   *cmd;       /* the scsi-command */
+  unsigned char   *send;      /* the data we send to the drive ... */
+  unsigned char   *rec;       /* ... and get back */
+  int             rc,is_xa;
 
   if (!suser()) {
     /* I'm not the superuser, so SCSI_IOCTL_SEND_COMMAND isn't allowed for me.
@@ -321,7 +326,8 @@
       scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = 0;
     return;
   }
-  
+
+  cmd = rec = &buf[8];
   switch(scsi_CDs[MINOR(inode->i_rdev)].device->manufacturer) {
 
   case SCSI_MAN_NEC:
@@ -329,22 +335,24 @@
     printk("sr_photocd: use NEC code\n");
 #endif
     memset(buf,0,40);
-    *((unsigned long*)buf)   = 0;
-    *((unsigned long*)buf+1) = 0x16;
-    buf[8+0] = 0xde;
-    buf[8+1] = 0x03;
-    buf[8+2] = 0xb0;
+    *((unsigned long*)buf)   = 0x0;   /* we send nothing...     */
+    *((unsigned long*)buf+1) = 0x16;  /* and receive 0x16 bytes */
+    cmd[0] = 0xde;
+    cmd[1] = 0x03;
+    cmd[2] = 0xb0;
     rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
 			   SCSI_IOCTL_SEND_COMMAND, buf);
     if (rc != 0) {
       printk("sr_photocd: ioctl error (NEC): 0x%x\n",rc);
       sector = 0;
     } else {
-      min   = (unsigned long)buf[8+15]/16*10 + (unsigned long)buf[8+15]%16;
-      sec   = (unsigned long)buf[8+16]/16*10 + (unsigned long)buf[8+16]%16;
-      frame = (unsigned long)buf[8+17]/16*10 + (unsigned long)buf[8+17]%16;
-      sector = min*60*75 + sec*75 + frame;
+      min   = (unsigned long) rec[15]/16*10 + (unsigned long) rec[15]%16;
+      sec   = (unsigned long) rec[16]/16*10 + (unsigned long) rec[16]%16;
+      frame = (unsigned long) rec[17]/16*10 + (unsigned long) rec[17]%16;
+      /* if rec[14] is'nt 0xb0, the drive does not support multisession CD's, use zero */
+      sector = (0xb0 == rec[14]) ? min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame : 0;
 #ifdef DEBUG
+      printk("NEC: (%2x) %2li:%02li:%02li = %li\n",buf[8+14],min,sec,frame,sector);
       if (sector) {
 	printk("sr_photocd: multisession CD detected. start: %lu\n",sector);
       }
@@ -357,43 +365,71 @@
     printk("sr_photocd: use TOSHIBA code\n");
 #endif
     
-    /* first I do a set_density-call (for reading XA-sectors) ... */
+    /* we request some disc information (is it a XA-CD ?,
+       where starts the last session ?) */
     memset(buf,0,40);
-    *((unsigned long*)buf)   = 12;
-    *((unsigned long*)buf+1) = 12;
-    buf[8+0] = 0x15;
-    buf[8+1] = (1 << 4);
-    buf[8+4] = 12;
-    buf[14+ 3] = 0x08;
-    buf[14+ 4] = 0x83;
-    buf[14+10] = 0x08;
+    *((unsigned long*)buf)   = 0;
+    *((unsigned long*)buf+1) = 4;  /* we receive 4 bytes from the drive */
+    cmd[0] = 0xc7;
+    cmd[1] = 3;
     rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
 			   SCSI_IOCTL_SEND_COMMAND, buf);
     if (rc != 0) {
       printk("sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc);
+      sector = 0;
+      break; /* if the first ioctl fails, we don't call the secound one */
+    }
+    is_xa  = (rec[0] == 0x20);
+#ifdef DEBUG
+    printk("sr_photocd: TOSHIBA %x\n",rec[0]);
+#endif
+    min    = (unsigned long) rec[1]/16*10 + (unsigned long) rec[1]%16;
+    sec    = (unsigned long) rec[2]/16*10 + (unsigned long) rec[2]%16;
+    frame  = (unsigned long) rec[3]/16*10 + (unsigned long) rec[3]%16;
+    sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
+    if (sector) {
+      sector -= CD_BLOCK_OFFSET;
+#ifdef DEBUG
+      printk("sr_photocd: multisession CD detected: start: %lu\n",sector);
+#endif
     }
 
-    /* ... and then I ask, if there is a multisession-Disk */
+    /* now we do a get_density... */
     memset(buf,0,40);
     *((unsigned long*)buf)   = 0;
-    *((unsigned long*)buf+1) = 4;
-    buf[8+0] = 0xc7;
-    buf[8+1] = 3;
+    *((unsigned long*)buf+1) = 12;
+    cmd[0] = 0x1a;
+    cmd[2] = 1;
+    cmd[4] = 12;
     rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
 			   SCSI_IOCTL_SEND_COMMAND, buf);
     if (rc != 0) {
       printk("sr_photocd: ioctl error (TOSHIBA #2): 0x%x\n",rc);
-      sector = 0;
-    } else {
-      min   = (unsigned long)buf[8+1]/16*10 + (unsigned long)buf[8+1]%16;
-      sec   = (unsigned long)buf[8+2]/16*10 + (unsigned long)buf[8+2]%16;
-      frame = (unsigned long)buf[8+3]/16*10 + (unsigned long)buf[8+3]%16;
-      sector = min*60*75 + sec*75 + frame;
-      if (sector) {
-        sector -= CD_BLOCK_OFFSET;
+      break;
+    }
 #ifdef DEBUG
-        printk("sr_photocd: multisession CD detected: start: %lu\n",sector);
+    printk("sr_photocd: get_density: 0x%x\n",rec[4]);
 #endif
+    
+    /* ...and only if nessesary a set_density */
+    if ((rec[4] != 0x81 && is_xa) || (rec[4] != 0 && !is_xa)) {
+#ifdef DEBUG
+      printk("sr_photocd: doing set_density\n");
+#endif
+      memset(buf,0,40);
+      *((unsigned long*)buf)   = 12;  /* sending 12 bytes... */
+      *((unsigned long*)buf+1) = 0;
+      cmd[0] = 0x15;
+      cmd[1] = (1 << 4);
+      cmd[4] = 12;
+      send = &cmd[6];                 /* this is a 6-Byte command          */
+      send[ 3] = 0x08;                /* the data for the command          */
+      send[ 4] = (is_xa) ? 0x81 : 0;  /* density 0x81 for XA-CD's, 0 else  */
+      send[10] = 0x08;
+      rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
+			     SCSI_IOCTL_SEND_COMMAND, buf);
+      if (rc != 0) {
+	printk("sr_photocd: ioctl error (TOSHIBA #3): 0x%x\n",rc);
       }
     }
     break;
@@ -412,6 +448,8 @@
   return;
 }
 
+#undef DEBUG
+
 static int sr_open(struct inode * inode, struct file * filp)
 {
 	if(MINOR(inode->i_rdev) >= sr_template.nr_dev || 
@@ -427,9 +465,7 @@
 	if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
 	  (*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)++;
 
-#if 1	/* don't use for now - it doesn't seem to work for everybody */
 	sr_photocd(inode);
-#endif
 
 	/* If this device did not have media in the drive at boot time, then
 	   we would have been unable to get the sector size.  Check to see if
@@ -587,15 +623,6 @@
 and we have 2048 byte sectors.  This code should work for buffers that
 are any multiple of 512 bytes long.  */
 
-#if 1
-	/* Here we redirect the volume descriptor block of the CD-ROM.
-	 * Necessary for multisession CD's, until the isofs-routines
-	 * handle this via the CDROMMULTISESSION_SYS call
-	 */
-	if (block >= 64 && block < 68) {
-	  block += scsi_CDs[dev].mpcd_sector*4; }
-#endif
-	
 	SCpnt->use_sg = 0;
 
 	if (SCpnt->host->sg_tablesize > 0 &&
diff -u --recursive --new-file v1.1.86/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v1.1.86/linux/drivers/scsi/st.c	Thu Jan 26 07:49:07 1995
+++ linux/drivers/scsi/st.c	Sun Jan 29 12:30:36 1995
@@ -11,7 +11,7 @@
   Copyright 1992, 1993, 1994, 1995 Kai Makisara
 		 email Kai.Makisara@metla.fi
 
-  Last modified: Wed Jan 11 22:02:20 1995 by root@kai.home
+  Last modified: Thu Jan 19 23:28:05 1995 by makisara@kai.home
 */
 
 #include <linux/fs.h>
@@ -1546,7 +1546,7 @@
      STp->moves_after_eof = 0;
    else
      STp->moves_after_eof = 1;
-   if (!ioctl_result) {
+   if (!ioctl_result) {  /* SCSI command successful */
      if (cmd_in != MTSEEK) {
        STp->drv_block = blkno;
        (STp->mt_status)->mt_fileno = fileno;
@@ -1587,9 +1587,11 @@
        STp->eof = ST_NOEOF;
        STp->eof_hit = 0;
      }
-   } else {
+   } else {  /* SCSI command was not completely successful */
      if (SCpnt->sense_buffer[2] & 0x40) {
-       STp->eof = ST_EOM_OK;
+       if (cmd_in != MTBSF && cmd_in != MTBSFM &&
+	   cmd_in != MTBSR && cmd_in != MTBSS)
+	 STp->eof = ST_EOM_OK;
        STp->eof_hit = 0;
        STp->drv_block = 0;
      }
@@ -1884,7 +1886,6 @@
 {
   int i;
   Scsi_Tape * STp;
-  Scsi_Device * SDp;
   static int st_registered = 0;
 
   if (st_template.dev_noticed == 0) return;
diff -u --recursive --new-file v1.1.86/linux/fs/nfs/proc.c linux/fs/nfs/proc.c
--- v1.1.86/linux/fs/nfs/proc.c	Thu Jan 26 07:49:08 1995
+++ linux/fs/nfs/proc.c	Mon Jan 30 06:51:02 1995
@@ -901,6 +901,7 @@
 	{ NFSERR_NOENT,		ENOENT		},
 	{ NFSERR_IO,		errno_NFSERR_IO	},
 	{ NFSERR_NXIO,		ENXIO		},
+	{ NFSERR_EAGAIN,	EAGAIN		},
 	{ NFSERR_ACCES,		EACCES		},
 	{ NFSERR_EXIST,		EEXIST		},
 	{ NFSERR_NODEV,		ENODEV		},
diff -u --recursive --new-file v1.1.86/linux/include/asm-alpha/page.h linux/include/asm-alpha/page.h
--- v1.1.86/linux/include/asm-alpha/page.h	Thu Jan 26 07:49:14 1995
+++ linux/include/asm-alpha/page.h	Mon Jan 30 06:39:29 1995
@@ -16,15 +16,22 @@
 	: : :"$1", "$16", "$17", "$22","$23","$24","$25")
 
 /* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT			13
-#define PGDIR_SHIFT			23
-#define PAGE_SIZE			(1UL << PAGE_SHIFT)
-#define PGDIR_SIZE			(1UL << PGDIR_SHIFT)
+#define PAGE_SHIFT	13
+#define PMD_SHIFT	23
+#define PGDIR_SHIFT	33
+
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+#define PMD_MASK	(~(PMD_SIZE-1))
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
 #ifdef __KERNEL__
 
 #define PAGE_OFFSET 0xFFFFFC0000000000
-#define MAP_NR(addr) (((addr) - PAGE_OFFSET) >> PAGE_SHIFT)
+#define MAP_NR(addr) ((((unsigned long) (addr)) - PAGE_OFFSET) >> PAGE_SHIFT)
 #define MAP_PAGE_RESERVED (1<<31)
 
 typedef unsigned int mem_map_t;
@@ -37,10 +44,12 @@
  * These are used to make use of C type-checking..
  */
 typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pgd; } pgd_t;
 typedef struct { unsigned long pgprot; } pgprot_t;
 
 #define pte_val(x)	((x).pte)
+#define pmd_val(x)	((x).pmd)
 #define pgd_val(x)	((x).pgd)
 #define pgprot_val(x)	((x).pgprot)
 
@@ -53,10 +62,12 @@
  * .. while these make it easier on the compiler
  */
 typedef unsigned long pte_t;
+typedef unsigned long pmd_t;
 typedef unsigned long pgd_t;
 typedef unsigned long pgprot_t;
 
 #define pte_val(x)	(x)
+#define pmd_val(x)	(x)
 #define pgd_val(x)	(x)
 #define pgprot_val(x)	(x)
 
@@ -141,7 +152,7 @@
  * for zero-mapped memory areas etc..
  */
 extern pte_t __bad_page(void);
-extern pte_t * __bad_pagetable(void);
+extern pmd_t * __bad_pagetable(void);
 
 extern unsigned long __zero_page(void);
 
@@ -152,12 +163,6 @@
 /* number of bits that fit into a memory pointer */
 #define BITS_PER_PTR			(8*sizeof(unsigned long))
 
-/* to mask away the intra-page address bits */
-#define PAGE_MASK			(~(PAGE_SIZE-1))
-
-/* to mask away the intra-page address bits */
-#define PGDIR_MASK			(~(PGDIR_SIZE-1))
-
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)		(((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
@@ -171,23 +176,12 @@
 #define PAGE_PTR(address)		\
   ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
 
-/* the no. of pointers that fit on a page */
-#define PTRS_PER_PAGE			(PAGE_SIZE/sizeof(void*))
-
-/* to set the page-dir */
-extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir)
-{
-	tsk->tss.ptbr = ((unsigned long) pgdir - PAGE_OFFSET) >> PAGE_SHIFT;
-	if (tsk == current)
-		invalidate();
-}
+/* This one will go away */
+#define PTRS_PER_PAGE	1024
 
-/* to find an entry in a page-table-directory */
-extern inline pgd_t * PAGE_DIR_OFFSET(struct task_struct * tsk, unsigned long address)
-{
-	return (pgd_t *) ((tsk->tss.ptbr << PAGE_SHIFT) + PAGE_OFFSET) +
-		((address >> 33) & PTR_MASK);
-}
+#define PTRS_PER_PTE	1024
+#define PTRS_PER_PMD	1024
+#define PTRS_PER_PGD	1024
 
 extern unsigned long high_memory;
 
@@ -196,23 +190,37 @@
  * and a page entry and page directory to the page they refer to.
  */
 extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
-{ pte_t pte; pte_val(pte) = (page << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; }
+{ pte_t pte; pte_val(pte) = ((page-PAGE_OFFSET) << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; }
 
 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
 
-extern inline void pgd_set(pgd_t * pgdp, pte_t * ptep)
-{ pgd_val(*pgdp) = _PAGE_TABLE | (((unsigned long) ptep) << (32-PAGE_SHIFT)); }
+extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
+{ pmd_val(*pmdp) = _PAGE_TABLE | ((((unsigned long) ptep) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
+
+extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
+{ pgd_val(*pgdp) = _PAGE_TABLE | ((((unsigned long) pmdp) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
+
+extern inline unsigned long pte_page(pte_t pte)
+{ return PAGE_OFFSET + ((pte_val(pte) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
+
+extern inline pte_t * pmd_page(pmd_t pmd)
+{ return (pte_t *) (PAGE_OFFSET + ((pmd_val(pmd) & _PFN_MASK) >> (32-PAGE_SHIFT))); }
 
-extern inline unsigned long pte_page(pte_t pte)	{ return (pte_val(pte) & _PFN_MASK) >> (32-PAGE_SHIFT); }
-extern inline unsigned long pgd_page(pgd_t pgd)	{ return (pgd_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT); }
+extern inline pmd_t * pgd_page(pgd_t pgd)
+{ return (pmd_t *) (PAGE_OFFSET + ((pgd_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT))); }
 
 extern inline int pte_none(pte_t pte)		{ return !pte_val(pte); }
 extern inline int pte_present(pte_t pte)	{ return pte_val(pte) & _PAGE_VALID; }
 extern inline void pte_clear(pte_t *ptep)	{ pte_val(*ptep) = 0; }
 
+extern inline int pmd_none(pmd_t pmd)		{ return !pmd_val(pmd); }
+extern inline int pmd_bad(pmd_t pmd)		{ return (pmd_val(pmd) & ~_PFN_MASK) != _PAGE_TABLE || (unsigned long) pmd_page(pmd) > high_memory; }
+extern inline int pmd_present(pmd_t pmd)	{ return pmd_val(pmd) & _PAGE_VALID; }
+extern inline void pmd_clear(pmd_t * pmdp)	{ pmd_val(*pmdp) = 0; }
+
 extern inline int pgd_none(pgd_t pgd)		{ return !pgd_val(pgd); }
-extern inline int pgd_bad(pgd_t pgd)		{ return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE || pgd_page(pgd) > high_memory; }
+extern inline int pgd_bad(pgd_t pgd)		{ return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE || (unsigned long) pgd_page(pgd) > high_memory; }
 extern inline int pgd_present(pgd_t pgd)	{ return pgd_val(pgd) & _PAGE_VALID; }
 extern inline void pgd_clear(pgd_t * pgdp)	{ pgd_val(*pgdp) = 0; }
 
@@ -239,6 +247,83 @@
 extern inline pte_t pte_mkdirty(pte_t pte)	{ pte_val(pte) |= __DIRTY_BITS; return pte; }
 extern inline pte_t pte_mkyoung(pte_t pte)	{ pte_val(pte) |= __ACCESS_BITS; return pte; }
 extern inline pte_t pte_mkcow(pte_t pte)	{ pte_val(pte) |= _PAGE_COW; return pte; }
+
+/* to set the page-dir */
+extern inline void SET_PAGE_DIR(struct task_struct * tsk, pgd_t * pgdir)
+{
+	tsk->tss.ptbr = ((unsigned long) pgdir - PAGE_OFFSET) >> PAGE_SHIFT;
+	if (tsk == current)
+		invalidate();
+}
+
+/* to find an entry in a page-table-directory */
+extern inline pgd_t * PAGE_DIR_OFFSET(struct task_struct * tsk, unsigned long address)
+{
+	return (pgd_t *) ((tsk->tss.ptbr << PAGE_SHIFT) + PAGE_OFFSET) +
+		((address >> 33) & (PTRS_PER_PGD - 1));
+}
+
+/* to find an entry in the second-level page-table-directory */
+extern inline pmd_t * PAGE_MIDDLE_OFFSET(pgd_t * dir, unsigned long address)
+{
+	return pgd_page(*dir) + ((address >> 23) & (PTRS_PER_PMD - 1));
+}
+
+/* to find an entry in the third-level page-table-directory */
+extern inline pte_t * PAGE_ENTRY_OFFSET(pmd_t * dir, unsigned long address)
+{
+	return pmd_page(*dir) + ((address >> 13) & (PTRS_PER_PTE - 1));
+}
+
+extern inline pte_t * pte_alloc(pmd_t *pmd, unsigned long address)
+{
+	unsigned long page;
+
+	address = (address >> 13) & (PTRS_PER_PTE - 1);
+	if (pmd_none(*pmd)) {
+		pte_t *page = (pte_t *) get_free_page(GFP_KERNEL);
+		if (pmd_none(*pmd)) {
+			if (page) {
+				pmd_set(pmd, page);
+				return page + address;
+			}
+			pmd_set(pmd, BAD_PAGETABLE);
+			return NULL;
+		}
+		free_page((unsigned long) page);
+	}
+	if (pmd_bad(*pmd)) {
+		printk("pte_alloc: bad pmd\n");
+		pmd_set(pmd, BAD_PAGETABLE);
+		return NULL;
+	}
+	return pmd_page(*pmd) + address;
+}
+
+extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address)
+{
+	unsigned long page;
+
+	address = (address >> 23) & (PTRS_PER_PMD - 1);
+	if (pgd_none(*pgd)) {
+		pmd_t *page = (pmd_t *) get_free_page(GFP_KERNEL);
+		if (pgd_none(*pgd)) {
+			if (page) {
+				pgd_set(pgd, page);
+				return page + address;
+			}
+			pgd_set(pgd, BAD_PAGETABLE);
+			return NULL;
+		}
+		free_page((unsigned long) page);
+	}
+	if (pgd_bad(*pgd)) {
+		printk("pmd_alloc: bad pgd\n");
+		pgd_set(pgd, BAD_PAGETABLE);
+		return NULL;
+	}
+	return pgd_page(*pgd) + address;
+}
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v1.1.86/linux/include/asm-alpha/string.h linux/include/asm-alpha/string.h
--- v1.1.86/linux/include/asm-alpha/string.h	Mon Jan  9 07:22:09 1995
+++ linux/include/asm-alpha/string.h	Mon Jan 30 06:39:29 1995
@@ -1,4 +1,12 @@
 #ifndef __ALPHA_STRING_H
 #define __ALPHA_STRING_H
 
+extern void * __constant_c_memset(void *, unsigned long, long);
+extern void * __memset(void *, char, size_t);
+
+#define memset(s, c, count) \
+(__builtin_constant_p(c) ? \
+ __constant_c_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \
+ __memset((s),(c),(count)))
+
 #endif
diff -u --recursive --new-file v1.1.86/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h
--- v1.1.86/linux/include/asm-alpha/system.h	Mon Jan 16 14:18:24 1995
+++ linux/include/asm-alpha/system.h	Mon Jan 30 06:39:29 1995
@@ -18,12 +18,11 @@
 #define BOOT_SIZE	(16*1024)
 
 #define KERNEL_START	0xfffffc0000300000
-#define INIT_PCB	0xfffffc0000300000
+#define SWAPPER_PGD	0xfffffc0000300000
 #define INIT_STACK	0xfffffc0000302000
 #define EMPTY_PGT	0xfffffc0000304000
 #define EMPTY_PGE	0xfffffc0000308000
 #define ZERO_PGE	0xfffffc000030A000
-#define SWAPPER_PGD	0xfffffc000030C000
 
 #define START_ADDR	0xfffffc0000310000
 #define START_SIZE	(1024*1024)
diff -u --recursive --new-file v1.1.86/linux/include/linux/nfs.h linux/include/linux/nfs.h
--- v1.1.86/linux/include/linux/nfs.h	Fri Dec 31 09:44:46 1993
+++ linux/include/linux/nfs.h	Mon Jan 30 06:51:02 1995
@@ -67,6 +67,7 @@
 	NFSERR_NOENT = 2,
 	NFSERR_IO = 5,
 	NFSERR_NXIO = 6,
+	NFSERR_EAGAIN = 11,
 	NFSERR_ACCES = 13,
 	NFSERR_EXIST = 17,
 	NFSERR_NODEV = 19,
diff -u --recursive --new-file v1.1.86/linux/include/linux/personality.h linux/include/linux/personality.h
--- v1.1.86/linux/include/linux/personality.h	Thu Jun 16 10:30:25 1994
+++ linux/include/linux/personality.h	Sun Jan 29 12:58:46 1995
@@ -20,7 +20,7 @@
 #define PER_WYSEV386		(0x0004 | STICKY_TIMEOUTS)
 #define PER_ISCR4		(0x0005 | STICKY_TIMEOUTS)
 #define PER_BSD			(0x0006)
-
+#define PER_XENIX		(0x0007 | STICKY_TIMEOUTS)
 
 /* Prototype for an lcall7 syscall handler. */
 typedef asmlinkage void (*lcall7_func)(struct pt_regs *);
diff -u --recursive --new-file v1.1.86/linux/include/linux/sbpcd.h linux/include/linux/sbpcd.h
--- v1.1.86/linux/include/linux/sbpcd.h	Fri Jan 13 16:57:06 1995
+++ linux/include/linux/sbpcd.h	Sun Jan 29 20:28:43 1995
@@ -526,7 +526,6 @@
  */
 #define CMD1_RESET	0x0a
 #define CMD2_RESET	0x01
-#define CMDL_RESET	0x0a
 #define CMDT_RESET	0xc0
 #define CMD1_LOCK_CTL	0x0c
 #define CMD2_LOCK_CTL	0x1e
@@ -537,7 +536,6 @@
 #define CMDL_TRAY_CTL	0x0d
 #define CMDT_TRAY_CTL	0x1b
 #define CMD1_MULTISESS	0x8d
-#define CMD2_MULTISESS	0x43
 #define CMDL_MULTISESS	0x8c
 #define CMD1_SUBCHANINF	0x11
 #define CMD2_SUBCHANINF	0x
@@ -628,7 +626,7 @@
 #define CMD0_DISKCODE	0x8a
 #define CMD0_DISKINFO	0x8b
 #define CMD1_DISKINFO	0x8b
-#define CMD2_DISKINFO	0x
+#define CMD2_DISKINFO	0x43
 #define CMDL_DISKINFO	0x8b
 #define CMDT_DISKINFO	0x43
 #define CMD0_READTOC	0x8c
diff -u --recursive --new-file v1.1.86/linux/lib/vsprintf.c linux/lib/vsprintf.c
--- v1.1.86/linux/lib/vsprintf.c	Mon Jan 16 14:18:33 1995
+++ linux/lib/vsprintf.c	Mon Jan 30 06:39:29 1995
@@ -68,7 +68,7 @@
 static char * number(char * str, long num, int base, int size, int precision
 	,int type)
 {
-	char c,sign,tmp[36];
+	char c,sign,tmp[66];
 	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
 	int i;
 
diff -u --recursive --new-file v1.1.86/linux/net/inet/icmp.c linux/net/inet/icmp.c
--- v1.1.86/linux/net/inet/icmp.c	Mon Jan 30 06:41:59 1995
+++ linux/net/inet/icmp.c	Sun Jan 29 19:44:30 1995
@@ -162,9 +162,6 @@
 				icmph->type == ICMP_PARAMETERPROB)
 				return;
 		}
-  
-		return;
-
 	}
 	icmp_statistics.IcmpOutMsgs++;
 	
diff -u --recursive --new-file v1.1.86/linux/net/inet/igmp.c linux/net/inet/igmp.c
--- v1.1.86/linux/net/inet/igmp.c	Mon Jan 30 06:41:59 1995
+++ linux/net/inet/igmp.c	Fri Jan 27 17:00:37 1995
@@ -63,6 +63,7 @@
 		return;
 	tv=random()%(10*HZ);		/* Pick a number any number 8) */
 	im->timer.expires=tv;
+	im->tm_running=1;
 	add_timer(&im->timer);
 }
  
diff -u --recursive --new-file v1.1.86/linux/net/inet/tcp.c linux/net/inet/tcp.c
--- v1.1.86/linux/net/inet/tcp.c	Mon Jan 30 06:42:00 1995
+++ linux/net/inet/tcp.c	Sun Jan 29 19:44:59 1995
@@ -606,6 +606,7 @@
 	if (sk->retransmits > TCP_RETR2) 
 	{
 		sk->err = ETIMEDOUT;
+		sk->error_report(sk);
 		/*
 		 *	Time wait the socket 
 		 */
