diff -u --recursive --new-file v1.2.9/linux/Makefile linux/Makefile
--- v1.2.9/linux/Makefile	Thu Jun  1 13:16:23 1995
+++ linux/Makefile	Mon Jun 12 19:23:35 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 2
-SUBLEVEL = 9
+SUBLEVEL = 10
 
 ARCH = i386
 
diff -u --recursive --new-file v1.2.9/linux/drivers/block/Makefile linux/drivers/block/Makefile
--- v1.2.9/linux/drivers/block/Makefile	Wed Mar 29 06:52:57 1995
+++ linux/drivers/block/Makefile	Mon Jun 12 16:27:43 1995
@@ -100,6 +100,9 @@
 
 dep:
 	$(CPP) -M $(SRCS) > .depend
+ifdef BLOCK_MODULE_OBJS
+	$(CPP) -M -DMODULE $(BLOCK_MODULE_OBJS:.o=.c) >> .depend
+endif
 
 modules: $(BLOCK_MODULE_OBJS)
 	echo $(BLOCK_MODULE_OBJS) > ../../modules/BLOCK_MODULES
diff -u --recursive --new-file v1.2.9/linux/drivers/block/README.ide linux/drivers/block/README.ide
--- v1.2.9/linux/drivers/block/README.ide	Thu Jun  1 13:16:23 1995
+++ linux/drivers/block/README.ide	Fri Jun  2 13:46:26 1995
@@ -25,7 +25,7 @@
 		- use kernel command line option:   hda=serialize
 NEW!	- experimental support for DTC-2278D interfaces
 		- use kernel command line option:  hda=dtc2278
-NEW!	- run-time selectible 32bit interface support (using hdparm-2.3)
+NEW!	- run-time selectable 32bit interface support (using hdparm-2.3)
 
 Under construction:
 
diff -u --recursive --new-file v1.2.9/linux/drivers/block/README.sbpcd linux/drivers/block/README.sbpcd
--- v1.2.9/linux/drivers/block/README.sbpcd	Mon May 29 11:16:04 1995
+++ linux/drivers/block/README.sbpcd	Fri Jun  2 08:16:16 1995
@@ -1,9 +1,9 @@
-This README belongs to release 3.5 or newer of the SoundBlaster Pro
-(Matsushita, Kotobuki, Panasonic, CreativeLabs, Longshine and soon TEAC, too)
+This README belongs to release 3.7 or newer of the SoundBlaster Pro
+(Matsushita, Kotobuki, Panasonic, CreativeLabs, Longshine and TEAC)
 CD-ROM driver for Linux.
 
 The driver is able to drive the whole family of "traditional" IDE-style (that
-has nothing to do with the new "Enhanced IDE" drive standard) Matsushita,
+is NOT the new "Enhanced IDE" or "ATAPI" drive standard) Matsushita,
 Kotobuki, Panasonic drives, sometimes labelled as "CreativeLabs". The
 well-known drives are CR-521, CR-522, CR-523, CR-562, CR-563.
 
@@ -42,6 +42,10 @@
 The interface type has to get configured in /usr/include/linux/sbpcd.h, 
 because the behavior of some sound card interfaces is different.
 
+With some TEAC drives I have seen interface cards which seem to lack the
+"drive select" lines; always drive 0 gets addressed. To avoid "mirror drives"
+with such interface cards, set MAX_DRIVES to 1 and jumper your drive to ID 0.
+
 The driver respects all known drive firmware releases - my old drive is a 2.11,
 but it should work with CR-52x drives <2.01 ... >3.00 and with CR-56x drives
 <0.75 .. 5.00.
@@ -79,9 +83,8 @@
 CDplayer and WorkBone - tell me if it is not compatible with other software.
 
 With the CR-562 and CR-563 drives, the reading of audio frames is possible.
-This is implemented by an IOCTL function which per default reads only up to
-4 frames of 2352 bytes at once (configurable with the "READ_AUDIO" define,
-"55" is the maximum if you use sbpcd as a "module").
+This is implemented by an IOCTL function which reads READ_AUDIO frames of
+2352 bytes at once (configurable with the "READ_AUDIO" define, default is 0).
 Reading the same frame a second time gives different data; the frame data 
 start at a different position, but all read bytes are valid, and we always
 read 98 consecutive chunks (of 24 Bytes) as a frame. Reading more than 1 frame
@@ -89,8 +92,8 @@
 get corrected by external, "higher level" software which reads the same frame 
 again and tries to find and eliminate overlapping chunks (24-byte-pieces).
 
-The transfer rate with reading audio (1-frame-pieces) is as slow as 32 kB/sec.
-This could be better reading bigger chunks, but the "missing" chunks possibly
+The transfer rate with reading audio (1-frame-pieces) currently is very slow.
+This can be better reading bigger chunks, but the "missing" chunks possibly
 occur at the beginning of each single frame.
 The software interface possibly may change a bit the day the SCSI driver
 supports it too.
diff -u --recursive --new-file v1.2.9/linux/drivers/block/README.sonycd535 linux/drivers/block/README.sonycd535
--- v1.2.9/linux/drivers/block/README.sonycd535	Wed Feb 15 10:51:06 1995
+++ linux/drivers/block/README.sonycd535	Mon Jun 12 12:06:46 1995
@@ -58,13 +58,17 @@
 ======
 
 Many thanks to Ron Jeppesen (ronj.an@site007.saic.com) for getting
-this project off the ground.  He wrote the initial release and
-the first two patches to this driver (0.1, 0.2, and 0.3).
+this project off the ground.  He wrote the initial release
+and the first two patches to this driver (0.1, 0.2, and 0.3).
 Thanks also to Eberhard Moenkeberg (emoenke@gwdg.de) for prodding
-me to place this code into the mainstream Linux source tree (as
-of Linux version 1.1.91), as well as some patches to make it a
-better device citizen.  Further thanks to "S. Joel Katz"
-<stimpson@panix.com> for his MODULE patches (see details below).
+me to place this code into the mainstream Linux source tree
+(as of Linux version 1.1.91), as well as some patches to make
+it a better device citizen.  Further thanks to "S. Joel Katz"
+<stimpson@panix.com> for his MODULE patches (see details below),
+Porfiri Claudio <C.Porfiri@nisms.tei.ericsson.se> for patches
+to make the driver work with the older CDU-510/515 series, and
+Heiko Eissfeldt <heiko@colossus.escape.de> for pointing out that
+the verify_area() checks were ignoring the results of said checks.
 
 (Acknowledgments from Ron Jeppesen in the 0.3 release:)
 Thanks to Corey Minyard who wrote the original CDU-31A driver on which
diff -u --recursive --new-file v1.2.9/linux/drivers/block/sbpcd.c linux/drivers/block/sbpcd.c
--- v1.2.9/linux/drivers/block/sbpcd.c	Mon May 29 11:16:05 1995
+++ linux/drivers/block/sbpcd.c	Fri Jun  2 08:16:16 1995
@@ -11,7 +11,7 @@
  *            Also for the TEAC CD-55A drive.
  *            Not for Funai or Sanyo drives.
  *
- *  NOTE:     This is release 3.6.
+ *  NOTE:     This is release 3.7.
  *
  *  VERSION HISTORY
  *
@@ -207,6 +207,13 @@
  *       Initial size of the READ_AUDIO buffer is 0. Can get set to any size
  *       during runtime.
  *
+ *  3.7  Introduced MAX_DRIVES for some poor interface cards (seen with TEAC
+ *       drives) which allow only one drive (ID 0); this avoids repetitive
+ *       detection under IDs 1..3. 
+ *       Elongated cmd_out_T response waiting; necessary for photo CDs with
+ *       a lot of sessions.
+ *       Bettered the sbpcd_open() behavior with TEAC drives.
+ *
  *  TODO
  *
  *     disk change detection
@@ -288,13 +295,7 @@
 
 #include "blk.h"
 
-#define VERSION "v3.6-1 Eberhard Moenkeberg <emoenke@gwdg.de>"
-
-#if 0
-#define INLINE
-#else
-#define INLINE inline
-#endif
+#define VERSION "v3.7 Eberhard Moenkeberg <emoenke@gwdg.de>"
 
 /*==========================================================================*/
 /*
@@ -406,6 +407,9 @@
 #endif
 
 /*==========================================================================*/
+
+#define INLINE inline
+
 /*==========================================================================*/
 /*
  * the forward references:
@@ -533,8 +537,9 @@
 static u_char xa_head_buf[CD_XA_HEAD];
 static u_char xa_tail_buf[CD_XA_TAIL];
 
+static volatile u_char busy_data=0;
+static volatile u_char busy_audio=0; /* true semaphores would be safer */
 static u_long timeout;
-static u_char busy_data=0, busy_audio=0; /* true semaphores would be safer */
 static volatile u_char timed_out_delay=0;
 static volatile u_char timed_out_data=0;
 #if 0
@@ -1017,21 +1022,29 @@
 					st=inb(CDi_status);
 					if (!(st&s_not_result_ready)) break;
 				}
-				if (j != 0 || timeout <= jiffies) break;
-				sbp_sleep(0);
+				if ((j!=0)||(timeout<=jiffies)) break;
+				sbp_sleep(1);
 				j = 1;
 			}
-			if (timeout <= jiffies) break;
+			if (timeout<=jiffies) break;
 			infobuf[i]=inb(CDi_info);
 		}
 	}
+#if 000
+	while (!(inb(CDi_status)&s_not_result_ready))
+	{
+		infobuf[i++]=inb(CDi_info);
+	}
+	j=i-response_count;
+	if (j>0) msg(DBG_INF,"ResponseInfo: got %d trailing bytes.\n",j);
+#endif 000
 	for (j=0;j<i;j++)
 		sprintf(&msgbuf[j*3]," %02X",infobuf[j]);
 	msgbuf[j*3]=0;
 	msg(DBG_CMD,"ResponseInfo:%s (%d,%d)\n",msgbuf,response_count,i);
-	st=response_count-i;
-	if (st>0) st=-st;
-	return (st);
+	j=response_count-i;
+	if (j>0) return (-j);
+	else return (i);
 }
 /*==========================================================================*/
 static void EvaluateStatus(int st)
@@ -1253,7 +1266,7 @@
 static int cmd_out_T(void)
 {
 #undef CMDT_TRIES
-#define CMDT_TRIES 100
+#define CMDT_TRIES 1000
 	
 	static int cc_DriveReset(void);
 	int i, j, l, ntries;
@@ -1358,7 +1371,7 @@
 			return (-D_S[d].error_state-400);
 		}
 		if (drvcmd[0]==CMDT_READ) return (0); /* handled elsewhere */
-		sbp_sleep(1);
+		sbp_sleep(10);
 		if (ntries>(CMDT_TRIES-50)) continue;
 		msg(DBG_TEA,"cmd_out_T: next CMDT_TRIES (%02X): %d.\n", drvcmd[0], ntries-1);
 	}
@@ -1414,7 +1427,7 @@
 		if (D_S[d].in_SpinUp) msg(DBG_SPI,"in_SpinUp: to ResponseStatus.\n");
 		i=ResponseStatus();
 		/* builds status_bits, returns orig. status or p_busy_new */
-		if (i<0) return (-9);
+		if (i<0) return (i);
 		if (flags_cmd_out&(f_bit1|f_wait_if_busy))
 		{
 			if (!st_check)
@@ -2083,15 +2096,18 @@
 		sbp_sleep(1);
 	}
 	while ((i<0)&&(j));
-	if (j==0) cc_DriveReset();
-	j=20;
-	do
-	{
-		i=cc_LockDoor(1);
-		--j;
-		sbp_sleep(1);
+	if (j==0)
+	{		
+		cc_DriveReset();
+		j=20;
+		do
+		{
+			i=cc_LockDoor(1);
+			--j;
+			sbp_sleep(1);
+		}
+		while ((i<0)&&(j));
 	}
-	while ((i<0)&&(j));
 	return (i);
 }
 /*==========================================================================*/
@@ -2243,7 +2259,7 @@
 	else if (famT_drive)
 	{
 		D_S[d].sense_byte=0;
-		if (infobuf[4]==0x01) D_S[d].xa_byte=0x20;
+		if (infobuf[4]==0x01) D_S[d].xa_byte=0x20; /* wrong!!!! */
 		i=2;
 	}
 	D_S[d].frame_size=make16(infobuf[i],infobuf[i+1]);
@@ -3204,7 +3220,7 @@
 			if (D_S[d].firmware_version[j]!=lcs_firm_f4[j]) break;
 		if (j==4) D_S[d].drv_type=drv_f4;
 
-		if (!D_S[d].drv_type) ask_mail();
+		if (D_S[d].drv_type==drv_famL) ask_mail();
 	}
 	else if (famT_drive)
 	{
@@ -3382,7 +3398,7 @@
 	
 	msg(DBG_INI,"check_drives entered.\n");
 	ndrives=0;
-	for (j=0;j<NR_SBPCD;j++)
+	for (j=0;j<MAX_DRIVES;j++)
 	{
 		D_S[ndrives].drv_id=j;
 		if (sbpro_type==1) D_S[ndrives].drv_sel=(j&0x01)<<1|(j&0x02)>>1;
@@ -3624,7 +3640,7 @@
 		return (i);
 	}
 	if (D_S[d].f_multisession) D_S[d].sbp_bufsiz=1;  /* possibly a weird PhotoCD */
-	
+	else D_S[d].sbp_bufsiz=SBP_BUFFER_FRAMES;
 	i=cc_ReadTocEntry(D_S[d].n_first_track);
 	if (i<0)
 	{
@@ -4823,6 +4839,7 @@
 	{
 		cc_DriveReset();
 		i=ResponseStatus();
+		i=ResponseStatus();
 	}
 	if (i<0)
 	{
@@ -5065,12 +5082,12 @@
 		msg(DBG_INF,"Auto-Probing can cause a hang (f.e. touching an ethernet card).\n");
 		msg(DBG_INF,"If that happens, you have to reboot and use the\n");
 		msg(DBG_INF,"LILO (kernel) command line feature like:\n");
-		msg(DBG_INF,"\n   LILO boot: ... sbpcd=0x230,SoundBlaster\n");
+		msg(DBG_INF,"   LILO boot: ... sbpcd=0x230,SoundBlaster\n");
 		msg(DBG_INF,"or like:\n");
 		msg(DBG_INF,"   LILO boot: ... sbpcd=0x300,LaserMate\n");
 		msg(DBG_INF,"or like:\n");
 		msg(DBG_INF,"   LILO boot: ... sbpcd=0x330,SPEA\n");
-		msg(DBG_INF,"\nwith your REAL address.\n");
+		msg(DBG_INF,"with your REAL address.\n");
 		msg(DBG_INF,"= = = = = = = = = = END of WARNING = = = = = = = = = =\n\n");
 	}
 #endif DISTRIBUTION
@@ -5153,8 +5170,10 @@
 		
 		cc_ReadStatus();
 		i=ResponseStatus();  /* returns orig. status or p_busy_new */
+		if (famT_drive) i=ResponseStatus();  /* returns orig. status or p_busy_new */
 		if (i<0)
-			msg(DBG_INF,"init: ResponseStatus returns %02X\n",i);
+			if (i!=-402)
+				msg(DBG_INF,"init: ResponseStatus returns %d.\n",i);
 		else
 		{
 			if (st_check)
diff -u --recursive --new-file v1.2.9/linux/drivers/block/sonycd535.c linux/drivers/block/sonycd535.c
--- v1.2.9/linux/drivers/block/sonycd535.c	Thu Mar  9 20:37:33 1995
+++ linux/drivers/block/sonycd535.c	Mon Jun 12 12:06:47 1995
@@ -12,14 +12,24 @@
  * I tried polling without the sony_sleep during the data transfers but
  * it did not speed things up any.
  *
- *  5/23/93 (rgj) changed the major number to 21 to get rid of conflict
+ * 1993-05-23 (rgj) changed the major number to 21 to get rid of conflict
  * with CDU-31A driver.  This is the also the number from the Linux
  * Device Driver Registry for the Sony Drive.  Hope nobody else is using it.
  *
- *  8/29/93 (rgj) remove the configuring of the interface board address
+ * 1993-08-29 (rgj) remove the configuring of the interface board address
  * from the top level configuration, you have to modify it in this file.
  *
- * 1/26/95 Made module-capable (Joel Katz <Stimpson@Panix.COM>)
+ * 1995-01-26 Made module-capable (Joel Katz <Stimpson@Panix.COM>)
+ *
+ * 1995-05-20
+ *  Modified to support CDU-510/515 series
+ *      (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
+ *  Fixed to report verify_area() failures
+ *      (Heiko Eissfeldt <heiko@colossus.escape.de>)
+ *
+ * 1995-06-01
+ *  More chages to support CDU-510/515 series
+ *      (Claudio Porfiri<C.Porfiri@nisms.tei.ericsson.se>)
  *
  * Things to do:
  *  - handle errors and status better, put everything into a single word
@@ -131,7 +141,7 @@
 #define MAJOR_NR CDU535_CDROM_MAJOR
 
 #ifdef MODULE
-# include "/usr/src/linux/drivers/block/blk.h"
+# include "blk.h"
 #else
 # include "blk.h"
 # define MOD_INC_USE_COUNT
@@ -157,6 +167,13 @@
 # define CDU535_MESSAGE_NAME	"Sony CDU-535"
 #endif
 
+#ifndef MAX_SPINUP_RETRY
+# define MAX_SPINUP_RETRY		3	/* 1 is sufficient for most drives... */
+#endif
+#ifndef RETRY_FOR_BAD_STATUS
+# define RETRY_FOR_BAD_STATUS	100	/* in 10th of second */
+#endif
+
 #ifndef DEBUG
 # define DEBUG	1
 #endif
@@ -811,7 +828,6 @@
 	Byte status[2];
 	Byte cmd[2];
 
-
 	if (!sony_inuse) {
 		cdu_open(NULL, NULL);
 	}
@@ -870,36 +886,56 @@
 
 					/*
 					 * Read the data.  If the drive was not spinning,
-					 * spin it up and try once more.
+					 * spin it up and try some more.
 					 */
-					spin_up_retry = 0;
-					for (;;) {
-#if DEBUG > 1
-						if (check_drive_status() != 0) {
-							/* drive not ready */
-							sony_first_block = -1;
-							sony_last_block = -1;
-							end_request(0);
-							return;
-						}
-#endif
-						if (0 <= seek_and_read_N_blocks(params, read_size,
-									status, sony_buffer, (read_size * 2048)))
+					for (spin_up_retry=0 ;; ++spin_up_retry) {
+						/* This loop has been modified to support the Sony
+						 * CDU-510/515 series, thanks to Claudio Porfiri 
+						 * <C.Porfiri@nisms.tei.ericsson.se>.
+						 */
+						/*
+						 * This part is to deal with very slow hardware.  We
+						 * try at most MAX_SPINUP_RETRY times to read the same
+						 * block.  A check for seek_and_read_N_blocks' result is
+						 * performed; if the result is wrong, the CDROM's engine
+						 * is restarted and the operation is tried again.
+						 */
+						/*
+						 * 1995-06-01: The system got problems when downloading
+						 * from Slackware CDROM, the problem seems to be:
+						 * seek_and_read_N_blocks returns BAD_STATUS and we
+						 * should wait for a while before retrying, so a new
+						 * part was added to discriminate the return value from
+						 * seek_and_read_N_blocks for the various cases.
+						 */
+						int readStatus = seek_and_read_N_blocks(params, read_size,
+									status, sony_buffer, (read_size * 2048));
+						if (0 <= readStatus)	/* Good data; common case, placed first */
 							break;
-						if (!(status[0] & SONY535_STATUS1_NOT_SPINNING) ||
-															spin_up_retry) {
-							printk(CDU535_MESSAGE_NAME " Read error: 0x%.2x\n",
-									status[0]);
+						if (readStatus == NO_ROOM || spin_up_retry == MAX_SPINUP_RETRY) {
+							/* give up */
+							if (readStatus == NO_ROOM)
+								printk(CDU535_MESSAGE_NAME " No room to read from CD\n");
+							else
+								printk(CDU535_MESSAGE_NAME " Read error: 0x%.2x\n",
+										status[0]);
 							sony_first_block = -1;
 							sony_last_block = -1;
 							end_request(0);
 							return;
 						}
+						if (readStatus == BAD_STATUS) {
+							/* Sleep for a while, then retry */
+							current->state = TASK_INTERRUPTIBLE;
+							current->timeout = jiffies + RETRY_FOR_BAD_STATUS;
+							schedule();
+						}
+#if DEBUG > 0
 						printk(CDU535_MESSAGE_NAME
 							" debug: calling spin up when reading data!\n");
+#endif
 						cmd[0] = SONY535_SPIN_UP;
 						do_sony_cmd(cmd, 1, status, NULL, 0, 0);
-						spin_up_retry = 1;
 					}
 				}
 				/*
@@ -1008,7 +1044,7 @@
 sony_get_subchnl_info(long arg)
 {
 	struct cdrom_subchnl schi;
-
+	int err;
 
 	/* Get attention stuff */
 	if (check_drive_status() != 0)
@@ -1018,7 +1054,9 @@
 	if (!sony_toc_read) {
 		return -EIO;
 	}
-	verify_area(VERIFY_WRITE /* and read */ , (char *)arg, sizeof schi);
+	err = verify_area(VERIFY_WRITE /* and read */ , (char *)arg, sizeof schi);
+	if (err)
+		return err;
 
 	memcpy_fromfs(&schi, (char *)arg, sizeof schi);
 
@@ -1079,8 +1117,9 @@
 	unsigned int dev;
 	Byte status[2];
 	Byte cmd_buff[10], params[10];
-	int  i, dsc_status;
-
+	int  i;
+	int  dsc_status;
+	int  err;
 
 	if (!inode) {
 		return -EINVAL;
@@ -1170,7 +1209,9 @@
 		break;
 
 	case CDROMPLAYMSF:			/* Play starting at the given MSF address. */
-		verify_area(VERIFY_READ, (char *)arg, 6);
+		err = verify_area(VERIFY_READ, (char *)arg, 6);
+		if (err)
+			return err;
 		spin_up_drive(status);
 		set_drive_mode(SONY535_AUDIO_DRIVE_MODE, status);
 		memcpy_fromfs(params, (void *)arg, 6);
@@ -1209,7 +1250,9 @@
 			if (!sony_toc_read)
 				return -EIO;
 			hdr = (struct cdrom_tochdr *)arg;
-			verify_area(VERIFY_WRITE, hdr, sizeof *hdr);
+			err = verify_area(VERIFY_WRITE, hdr, sizeof *hdr);
+			if (err)
+				return err;
 			loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
 			loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
 			memcpy_tofs(hdr, &loc_hdr, sizeof *hdr);
@@ -1229,7 +1272,9 @@
 				return -EIO;
 			}
 			entry = (struct cdrom_tocentry *)arg;
-			verify_area(VERIFY_WRITE /* and read */ , entry, sizeof *entry);
+			err = verify_area(VERIFY_WRITE /* and read */ , entry, sizeof *entry);
+			if (err)
+				return err;
 
 			memcpy_fromfs(&loc_entry, entry, sizeof loc_entry);
 
@@ -1268,7 +1313,9 @@
 			sony_get_toc();
 			if (!sony_toc_read)
 				return -EIO;
-			verify_area(VERIFY_READ, (char *)arg, sizeof ti);
+			err = verify_area(VERIFY_READ, (char *)arg, sizeof ti);
+			if (err)
+				return err;
 
 			memcpy_fromfs(&ti, (char *)arg, sizeof ti);
 			if ((ti.cdti_trk0 < sony_toc->first_track_num)
@@ -1337,7 +1384,9 @@
 		{
 			struct cdrom_volctrl volctrl;
 
-			verify_area(VERIFY_READ, (char *)arg, sizeof volctrl);
+			err = verify_area(VERIFY_READ, (char *)arg, sizeof volctrl);
+			if (err)
+				return err;
 
 			memcpy_fromfs(&volctrl, (char *)arg, sizeof volctrl);
 			cmd_buff[0] = SONY535_SET_VOLUME;
diff -u --recursive --new-file v1.2.9/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
--- v1.2.9/linux/drivers/char/cyclades.c	Thu Jun  1 13:16:23 1995
+++ linux/drivers/char/cyclades.c	Fri Jun  2 13:46:26 1995
@@ -2643,7 +2643,7 @@
 
         /* The Cyclom-16Y does not decode address bit 9 and therefore
            cannot distinguish between references to chip 0 and a non-
-           existent chip 4.  If the preceeding clearing of the supposed
+           existent chip 4.  If the preceding clearing of the supposed
            chip 4 GFRCR register appears at chip 0, there is no chip 4
            and this must be a Cyclom-16Y, not a Cyclom-32Ye.
         */
diff -u --recursive --new-file v1.2.9/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
--- v1.2.9/linux/drivers/scsi/fdomain.c	Mon Jan 16 07:17:37 1995
+++ linux/drivers/scsi/fdomain.c	Fri Jun  9 08:03:10 1995
@@ -1,10 +1,10 @@
 /* fdomain.c -- Future Domain TMC-16x0 SCSI driver
  * Created: Sun May  3 18:53:19 1992 by faith@cs.unc.edu
- * Revised: Sat Jan 14 21:39:15 1995 by faith@cs.unc.edu
+ * Revised: Mon Jun  5 09:21:54 1995 by faith@cs.unc.edu
  * Author: Rickard E. Faith, faith@cs.unc.edu
  * Copyright 1992, 1993, 1994, 1995 Rickard E. Faith
  *
- * $Id: fdomain.c,v 5.26 1995/01/15 02:39:19 root Exp $
+ * $Id: fdomain.c,v 5.28 1995/06/05 13:21:57 faith Exp $
 
  * 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
@@ -41,7 +41,7 @@
  The following BIOS versions are supported: 2.0, 3.0, 3.2, 3.4, and 3.5.
  The following chips are supported: TMC-1800, TMC-18C50, TMC-18C30.
  Reports suggest that the driver will also work with the 36C70 chip and
- with the Quantum ISA-200S SCSI adapter.
+ with the Quantum ISA-200S and ISA-250MG SCSI adapters.
 
  Please note that the drive ordering that Future Domain implemented in BIOS
  versions 3.4 and 3.5 is the opposite of the order (currently) used by the
@@ -141,6 +141,10 @@
  and to Martin Andrews (andrewm@ccfadm.eeg.ccf.org) for the signature to
  some random TMC-1680 repackaged by IBM.
 
+ Thanks for Mark Singer (elf@netcom.com) and Richard Simpson
+ (rsimpson@ewrcsdra.demon.co.uk) for more Quantum signatures and detective
+ work on the Quantum RAM layout.
+
  All of the alpha testers deserve much thanks.
 
 
@@ -190,7 +194,7 @@
 #include <linux/string.h>
 #include <linux/ioport.h>
 
-#define VERSION          "$Revision: 5.26 $"
+#define VERSION          "$Revision: 5.28 $"
 
 /* START OF USER DEFINABLE OPTIONS */
 
@@ -281,7 +285,7 @@
 static int               bios_major        = 0;
 static int               bios_minor        = 0;
 static int               PCI_bus           = 0;
-static int               ISA_200S          = 0;	/* Quantum ISA-200S */
+static int               Quantum           = 0;	/* Quantum board variant */
 static int               interrupt_level   = 0;
 static volatile int      in_command        = 0;
 static Scsi_Cmnd         *current_SC       = NULL;
@@ -357,18 +361,22 @@
    int  sig_length;
    int  major_bios_version;
    int  minor_bios_version;
-   int  flag;			/* 1 == PCI_bus, 2 == ISA_200S */
+   int  flag; /* 1 == PCI_bus, 2 == ISA_200S, 3 == ISA_250MG, 4 == ISA_200S */
 } signatures[] = {
    /*          1         2         3         4         5         6 */
    /* 123456789012345678901234567890123456789012345678901234567890 */
    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89",  5, 50,  2,  0, 0 },
    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89",  5, 50,  2,  0, 0 },
    { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50,  2,  0, 2 },
+   { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0",        73, 43,  2,  0, 3 },
+   { "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.",            72, 39,  2,  0, 4 },
    { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92",        5, 44,  3,  0, 0 },
    { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93",        5, 44,  3,  2, 0 },
    { "IBM F1 P2 BIOS v1.0104/29/93",                        5, 28,  3, -1, 0 },
    { "Future Domain Corp. V1.0008/18/93",                   5, 33,  3,  4, 0 },
    { "Future Domain Corp. V1.0008/18/93",                  26, 33,  3,  4, 1 },
+				/* This next signature may not be a 3.5 bios */
+   { "Future Domain Corp. V2.0108/18/93",                   5, 33,  3,  5, 0 },
    { "FUTURE DOMAIN CORP.  V3.5008/18/93",                  5, 34,  3,  5, 0 },
    { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5",        5, 44,  3,  5, 0 },
    { "FUTURE DOMAIN TMC-18XX",                              5, 22, -1, -1, 0 },
@@ -558,7 +566,7 @@
 	    bios_major = signatures[j].major_bios_version;
 	    bios_minor = signatures[j].minor_bios_version;
 	    PCI_bus    = (signatures[j].flag == 1);
-	    ISA_200S   = (signatures[j].flag == 2);
+	    Quantum    = (signatures[j].flag > 1) ? signatures[j].flag : 0;
 	    bios_base  = addresses[i];
 	 }
       }
@@ -580,12 +588,20 @@
 	 DOS (this geometry has nothing to do with physical geometry).
        */
 
-      if (ISA_200S) {		/* The Quantum board is slightly different. */
+      switch (Quantum) {
+      case 2:			/* ISA_200S */
+      case 3:			/* ISA_250MG */
 	 port_base = *((char *)bios_base + 0x1fa2)
 	       + (*((char *)bios_base + 0x1fa3) << 8);
-      } else {
+	 break;
+      case 4:			/* ISA_200S (another one) */
+	 port_base = *((char *)bios_base + 0x1fa3)
+	       + (*((char *)bios_base + 0x1fa4) << 8);
+	 break;
+      default:
 	 port_base = *((char *)bios_base + 0x1fcc)
 	       + (*((char *)bios_base + 0x1fcd) << 8);
+	 break;
       }
    
 #if DEBUG_DETECT
@@ -648,7 +664,7 @@
 	    scan more addresses.  If you have to modify this section for
 	    your installation, please send mail to faith@cs.unc.edu. */
 
-	 for (i = 0xff00; !flag && i > 0xf000; i -= 8) {
+	 for (i = 0xfff8; !flag && i > 0xe000; i -= 8) {
 	    port_base = i;
 	    if (check_region( port_base, 0x10 )) {
 #if DEBUG_DETECT
@@ -1603,10 +1619,21 @@
    drive = MINOR(dev) / 16;
 
    if (bios_major == 2) {
-      if (ISA_200S) {
+      switch (Quantum) {
+      case 2:			/* ISA_200S */
+				/* The value of 25 has never been verified.
+				   It should probably be 15. */
 	 i = (struct drive_info *)( (char *)bios_base + 0x1f33 + drive * 25 );
-      } else {
+	 break;
+      case 3:			/* ISA_250MG */
+	 i = (struct drive_info *)( (char *)bios_base + 0x1f36 + drive * 15 );
+	 break;
+      case 4:			/* ISA_200S (another one) */
+	 i = (struct drive_info *)( (char *)bios_base + 0x1f34 + drive * 15 );
+	 break;
+      default:
 	 i = (struct drive_info *)( (char *)bios_base + 0x1f31 + drive * 25 );
+	 break;
       }
       info_array[0] = i->heads;
       info_array[1] = i->sectors;
diff -u --recursive --new-file v1.2.9/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v1.2.9/linux/drivers/scsi/st.c	Thu Jun  1 13:16:24 1995
+++ linux/drivers/scsi/st.c	Sun Jun 11 19:45:10 1995
@@ -119,8 +119,8 @@
 #ifdef DEBUG
   if (debugging) {
     printk("st%d: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n", dev, result,
-	   SCpnt->cmnd[0], SCpnt->cmnd[1], SCpnt->cmnd[2],
-	   SCpnt->cmnd[3], SCpnt->cmnd[4], SCpnt->cmnd[5],
+	   SCpnt->data_cmnd[0], SCpnt->data_cmnd[1], SCpnt->data_cmnd[2],
+	   SCpnt->data_cmnd[3], SCpnt->data_cmnd[4], SCpnt->data_cmnd[5],
 	   SCpnt->request_bufflen);
     if (driver_byte(result) & DRIVER_SENSE)
       print_sense("st", SCpnt);
@@ -144,15 +144,15 @@
   if ((sense[0] & 0x70) == 0x70 &&
       scode == RECOVERED_ERROR
 #ifdef ST_RECOVERED_WRITE_FATAL
-      && SCpnt->cmnd[0] != WRITE_6
-      && SCpnt->cmnd[0] != WRITE_FILEMARKS
+      && SCpnt->data_cmnd[0] != WRITE_6
+      && SCpnt->data_cmnd[0] != WRITE_FILEMARKS
 #endif
       ) {
     scsi_tapes[dev].recover_count++;
     scsi_tapes[dev].mt_status->mt_erreg += (1 << MT_ST_SOFTERR_SHIFT);
-    if (SCpnt->cmnd[0] == READ_6)
+    if (SCpnt->data_cmnd[0] == READ_6)
       stp = "read";
-    else if (SCpnt->cmnd[0] == WRITE_6)
+    else if (SCpnt->data_cmnd[0] == WRITE_6)
       stp = "write";
     else
       stp = "ioctl";
@@ -640,6 +640,12 @@
       if (debugging)
 	printk( "st%d: Write protected\n", dev);
 #endif
+      if ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR) {
+	(STp->buffer)->in_use = 0;
+	STp->buffer = 0;
+	STp->in_use = 0;
+	return (-EROFS);
+      }
     }
 
     if (scsi_tapes[dev].device->host->hostt->usage_count)
diff -u --recursive --new-file v1.2.9/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- v1.2.9/linux/fs/binfmt_elf.c	Wed Feb 15 10:51:06 1995
+++ linux/fs/binfmt_elf.c	Sun Jun 11 19:45:10 1995
@@ -208,10 +208,13 @@
 	eppnt = elf_phdata;
 	for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++)
 	  if(eppnt->p_type == PT_LOAD) {
+	    int elf_prot = (eppnt->p_flags & PF_R) ? PROT_READ : 0;
+	    if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
+	    if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
 	    error = do_mmap(file, 
 			    eppnt->p_vaddr & 0xfffff000,
 			    eppnt->p_filesz + (eppnt->p_vaddr & 0xfff),
-			    PROT_READ | PROT_WRITE | PROT_EXEC,
+			    elf_prot,
 			    MAP_PRIVATE | MAP_DENYWRITE | (interp_elf_ex->e_type == ET_EXEC ? MAP_FIXED : 0),
 			    eppnt->p_offset & 0xfffff000);
 	    
@@ -530,10 +533,13 @@
 		
 		
 		if(elf_ppnt->p_type == PT_LOAD) {
+			int elf_prot = (elf_ppnt->p_flags & PF_R) ? PROT_READ : 0;
+			if (elf_ppnt->p_flags & PF_W) elf_prot |= PROT_WRITE;
+			if (elf_ppnt->p_flags & PF_X) elf_prot |= PROT_EXEC;
 			error = do_mmap(file,
 					elf_ppnt->p_vaddr & 0xfffff000,
 					elf_ppnt->p_filesz + (elf_ppnt->p_vaddr & 0xfff),
-					PROT_READ | PROT_WRITE | PROT_EXEC,
+					elf_prot,
 					MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
 					elf_ppnt->p_offset & 0xfffff000);
 			
@@ -615,12 +621,15 @@
 	printk("(brk) %x\n" , current->mm->brk);
 #endif
 
-	/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
-	   and some applications "depend" upon this behavior.
-	   Since we do not have the power to recompile these, we
-	   emulate the SVr4 behavior.  Sigh.  */
-	error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
-			MAP_FIXED | MAP_PRIVATE, 0);
+	if( current->personality == PER_SVR4 )
+	{
+		/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
+		   and some applications "depend" upon this behavior.
+		   Since we do not have the power to recompile these, we
+		   emulate the SVr4 behavior.  Sigh.  */
+		error = do_mmap(NULL, 0, 4096, PROT_READ | PROT_EXEC,
+				MAP_FIXED | MAP_PRIVATE, 0);
+	}
 
 	start_thread(regs, elf_entry, bprm->p);
 	if (current->flags & PF_PTRACED)
diff -u --recursive --new-file v1.2.9/linux/include/linux/elf.h linux/include/linux/elf.h
--- v1.2.9/linux/include/linux/elf.h	Sat Mar 18 12:45:46 1995
+++ linux/include/linux/elf.h	Mon Jun  5 14:37:46 1995
@@ -148,6 +148,12 @@
   Elf32_Half	e_shstrndx;
 } Elf32_Ehdr;
 
+/* These constants define the permissions on sections in the program
+   header, p_flags. */
+#define PF_R		0x4
+#define PF_W		0x2
+#define PF_X		0x1
+
 typedef struct elf_phdr{
   Elf32_Word	p_type;
   Elf32_Off	p_offset;
@@ -234,6 +240,19 @@
 #define EV_NONE		0		/* e_version, EI_VERSION */
 #define EV_CURRENT	1
 #define EV_NUM		2
+
+/* Notes used in ET_CORE */
+#define NT_PRSTATUS	1
+#define NT_PRFPREG	2
+#define NT_PRPSINFO	3
+#define NT_TASKSTRUCT	4
+
+/* Note header in a PT_NOTE section */
+typedef struct elf_note {
+  Elf32_Word	n_namesz;	/* Name size */
+  Elf32_Word	n_descsz;	/* Content size */
+  Elf32_Word	n_type;		/* Content type */
+} Elf32_Nhdr;
 
 #define ELF_START_MMAP 0x80000000
 
diff -u --recursive --new-file v1.2.9/linux/include/linux/sbpcd.h linux/include/linux/sbpcd.h
--- v1.2.9/linux/include/linux/sbpcd.h	Mon May 29 11:16:09 1995
+++ linux/include/linux/sbpcd.h	Fri Jun  2 08:16:17 1995
@@ -70,21 +70,25 @@
 #if !(SBPCD_ISSUE-1)     /* first (or if you have only one) interface board: */
 #define CDROM_PORT 0x340 /* <-----------<< port address                      */
 #define SBPRO      0     /* <-----------<< interface type                    */
+#define MAX_DRIVES 4     /* set to 1 if the card does not use "drive select" */
 #define SOUND_BASE 0x220 /* <-----------<< sound address of this card or 0   */
 #endif
 #if !(SBPCD_ISSUE-2)     /* ==================== second interface board: === */
 #define CDROM_PORT 0x344 /* <-----------<< port address                      */
 #define SBPRO      0     /* <-----------<< interface type                    */
+#define MAX_DRIVES 4     /* set to 1 if the card does not use "drive select" */
 #define SOUND_BASE 0x000 /* <-----------<< sound address of this card or 0   */
 #endif
 #if !(SBPCD_ISSUE-3)     /* ===================== third interface board: === */
 #define CDROM_PORT 0x634 /* <-----------<< port address                      */
 #define SBPRO      1     /* <-----------<< interface type                    */
+#define MAX_DRIVES 4     /* set to 1 if the card does not use "drive select" */
 #define SOUND_BASE 0x240 /* <-----------<< sound address of this card or 0   */
 #endif
 #if !(SBPCD_ISSUE-4)     /* ==================== fourth interface board: === */
 #define CDROM_PORT 0x634 /* <-----------<< port address                      */
 #define SBPRO      0     /* <-----------<< interface type                    */
+#define MAX_DRIVES 4     /* set to 1 if the card does not use "drive select" */
 #define SOUND_BASE 0x000 /* <-----------<< sound address of this card or 0   */
 #endif
 
@@ -606,10 +610,11 @@
 #define CMD1_SUBCHANINF	0x11
 #define CMD2_SUBCHANINF	0x??
 
+#define CMD1_ABORT	0x08
+#define CMD2_ABORT	0x08
+#define CMDT_ABORT	0x08
+
 #define CMD2_x02	0x02
-#define CMD1_x08	0x08
-#define CMD2_x08	0x08
-#define CMDT_x08	0x08
 
 #define CMD2_SETSPEED	0xda
 
@@ -668,6 +673,7 @@
 #define CMDL_PLAY_MSF	0x???
 
 #define CMD0_PLAY_TI	0x0c
+#define CMD1_PLAY_TI	0x0f
 
 #define CMD0_STATUS	0x81
 #define CMD1_STATUS	0x05
diff -u --recursive --new-file v1.2.9/linux/include/linux/tcp.h linux/include/linux/tcp.h
--- v1.2.9/linux/include/linux/tcp.h	Fri Apr 28 11:10:56 1995
+++ linux/include/linux/tcp.h	Mon Jun 12 12:27:39 1995
@@ -37,15 +37,15 @@
 		urg:1,
 		res2:2;
 #elif defined(BIG_ENDIAN_BITFIELD)
-	__u16	res2:2,
+	__u16	doff:4,
+		res1:4,
+		res2:2,
 		urg:1,
 		ack:1,
 		psh:1,
 		rst:1,
 		syn:1,
-		fin:1,
-		doff:4,
-		res1:4;
+		fin:1;
 #else
 #error	"Adjust your <asm/byteorder.h> defines"
 #endif	
diff -u --recursive --new-file v1.2.9/linux/net/inet/af_inet.c linux/net/inet/af_inet.c
--- v1.2.9/linux/net/inet/af_inet.c	Thu Jun  1 13:16:25 1995
+++ linux/net/inet/af_inet.c	Mon Jun  5 12:25:55 1995
@@ -941,9 +941,12 @@
 
 	if (sock->state == SS_CONNECTING && sk->protocol == IPPROTO_TCP && (flags & O_NONBLOCK)) {
 		if (sk->err != 0)
-			return -sk->err;	/* Connection must have failed */
-		else
-			return -EALREADY;	/* Connecting is currently in progress */
+		{
+			err=sk->err;
+			sk->err=0;
+			return -err;
+		}
+		return -EALREADY;	/* Connecting is currently in progress */
 	}
   	
 	if (sock->state != SS_CONNECTING) 
diff -u --recursive --new-file v1.2.9/linux/net/inet/ip_fw.c linux/net/inet/ip_fw.c
--- v1.2.9/linux/net/inet/ip_fw.c	Sat Mar 18 12:45:46 1995
+++ linux/net/inet/ip_fw.c	Sun Jun 11 19:45:10 1995
@@ -961,7 +961,7 @@
 			ntohl(i->fw_src.s_addr),ntohl(i->fw_smsk.s_addr),
 			ntohl(i->fw_dst.s_addr),ntohl(i->fw_dmsk.s_addr),
 			ntohl(i->fw_via.s_addr),i->fw_flg);
-		len+=sprintf(buffer+len,"%u %u %lu %lu",
+		len+=sprintf(buffer+len,"%u %u %10lu %10lu",
 			i->fw_nsp,i->fw_ndp, i->fw_pcnt,i->fw_bcnt);
 		for (p = 0; p < IP_FW_MAX_PORTS; p++)
 			len+=sprintf(buffer+len, " %u", i->fw_pts[p]);
