[1763] in linux-scsi channel archive

home help back first fref pref prev next nref lref last post

Re: fujitsu scsi m2513 mo 2048 sector size

daemon@ATHENA.MIT.EDU (Oliver Schaertel)
Sat Apr 26 12:18:14 1997

Date: 	Sat, 26 Apr 1997 17:14:50 +0000
From: Oliver Schaertel <orschaer@cip.informatik.uni-erlangen.de>
To: Jacek Zapala <jacek@cs.unipos.com.pl>
CC: linux-kernel@vger.rutgers.edu, linux-scsi@vger.rutgers.edu

This is a multi-part message in MIME format.

--------------B210502028B3D614C31872
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Jacek Zapala wrote:
> 
> Is there any patch for linux 2.0.xx for supporting 2048 sector size on
> SCSI (for the device from subject) ?
> 
>         Jacek Zapala
Hi
Look at http://wwwcip.informatik.uni-erlangen.de/user/orschaer/mo 
I also attached the patch!

Oliver

--------------B210502028B3D614C31872
Content-Type: text/plain; charset=us-ascii; name="fujitsu2513a.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="fujitsu2513a.diff"

diff -ru linux2.0.30.unpatched/drivers/block/genhd.c linux2.0.30.mopatched/drivers/block/genhd.c
--- linux2.0.30.unpatched/drivers/block/genhd.c	Wed Aug 21 06:18:07 1996
+++ linux2.0.30.mopatched/drivers/block/genhd.c	Mon Apr 14 22:17:12 1997
@@ -24,9 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/string.h>
-#ifdef CONFIG_BLK_DEV_INITRD
 #include <linux/blk.h>
-#endif
 
 #include <asm/system.h>
 
@@ -105,7 +103,60 @@
 		SYS_IND(p) == LINUX_EXTENDED_PARTITION);
 }
 
+static int sec_fac(kdev_t dev)
+{
+  return (hardsect_size[MAJOR(dev)][MINOR(dev)]/512);
+}
+
+static unsigned int get_ptable_blocksize(kdev_t dev)
+{
+  int ret = 1024;
+
+  /*
+   * See whether the low-level driver has given us a minumum blocksize.
+   * If so, check to see whether it is larger than the default of 1024.
+   */
+  if (!blksize_size[MAJOR(dev)])
+    {
+      return ret;
+    }
+
+  /*
+   * Check for certain special power of two sizes that we allow.
+   * With anything larger than 1024, we must force the blocksize up to
+   * the natural blocksize for the device so that we don't have to try
+   * and read partial sectors.  Anything smaller should be just fine.
+   */
+  switch( blksize_size[MAJOR(dev)][MINOR(dev)] )
+    {
+    case 2048:
+      ret = 2048;
+      break;
+    case 4096:
+      ret = 4096;
+      break;
+    case 8192:
+      ret = 8192;
+      break;
+    case 1024:
+    case 512:
+    case 256:
+    case 0:
+      /*
+       * These are all OK.
+       */
+      break;
+    default:
+      panic("Strange blocksize for partition table\n");
+    }
+
+  return ret;
+
+}
+
+
 #ifdef CONFIG_MSDOS_PARTITION
+
 /*
  * Create devices for each logical partition in an extended partition.
  * The logical partitions form a linked list, with each entry being
@@ -124,7 +175,7 @@
 	unsigned long first_sector, first_size, this_sector, this_size;
 	int mask = (1 << hd->minor_shift) - 1;
 	int i;
-
+        int sf=sec_fac(dev);
 	first_sector = hd->part[MINOR(dev)].start_sect;
 	first_size = hd->part[MINOR(dev)].nr_sects;
 	this_sector = first_sector;
@@ -132,7 +183,7 @@
 	while (1) {
 		if ((current_minor & mask) == 0)
 			return;
-		if (!(bh = bread(dev,0,1024)))
+		if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
 			return;
 	  /*
 	   * This block is from a device that we're about to stomp on.
@@ -165,14 +216,14 @@
 
 		    /* Check the 3rd and 4th entries -
 		       these sometimes contain random garbage */
-		    if (i >= 2
+       		    if (i >= 2
 			&& START_SECT(p) + NR_SECTS(p) > this_size
 			&& (this_sector + START_SECT(p) < first_sector ||
 			    this_sector + START_SECT(p) + NR_SECTS(p) >
 			     first_sector + first_size))
 		      continue;
 
-		    add_partition(hd, current_minor, this_sector+START_SECT(p), NR_SECTS(p));
+		    add_partition(hd, current_minor, this_sector+START_SECT(p) *sf , NR_SECTS(p) *sf );
 		    current_minor++;
 		    if ((current_minor & mask) == 0)
 		      goto done;
@@ -194,9 +245,9 @@
 		if (i == 4)
 		  goto done;	 /* nothing left to do */
 
-		hd->part[current_minor].nr_sects = NR_SECTS(p);
-		hd->part[current_minor].start_sect = first_sector + START_SECT(p);
-		this_sector = first_sector + START_SECT(p);
+		hd->part[current_minor].nr_sects = NR_SECTS(p)*sf ;
+		hd->part[current_minor].start_sect = first_sector + START_SECT(p) *sf;
+		this_sector = first_sector + START_SECT(p)*sf;
 		dev = MKDEV(hd->major, current_minor);
 		brelse(bh);
 	}
@@ -216,7 +267,7 @@
 	struct bsd_partition *p;
 	int mask = (1 << hd->minor_shift) - 1;
 
-	if (!(bh = bread(dev,0,1024)))
+	if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
 		return;
 	bh->b_state = 0;
 	l = (struct bsd_disklabel *) (bh->b_data+512);
@@ -248,12 +299,13 @@
 	struct partition *p;
 	unsigned char *data;
 	int mask = (1 << hd->minor_shift) - 1;
+        int sf=sec_fac(dev);
 #ifdef CONFIG_BLK_DEV_IDE
 	int tested_for_xlate = 0;
 
 read_mbr:
 #endif
-	if (!(bh = bread(dev,0,1024))) {
+	if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
 		printk(" unable to read partition table\n");
 		return -1;
 	}
@@ -343,10 +395,11 @@
 #endif	/* CONFIG_BLK_DEV_IDE */
 
 	current_minor += 4;  /* first "extra" minor (for extended partitions) */
+        
 	for (i=1 ; i<=4 ; minor++,i++,p++) {
 		if (!NR_SECTS(p))
 			continue;
-		add_partition(hd, minor, first_sector+START_SECT(p), NR_SECTS(p));
+		add_partition(hd, minor, first_sector+START_SECT(p)*sf , NR_SECTS(p)*sf );
 		if (is_extended_partition(p)) {
 			printk(" <");
 			/*
@@ -371,6 +424,7 @@
 			printk(" >");
 		}
 #endif
+		
 	}
 	/*
 	 *  Check for old-style Disk Manager partition table
@@ -434,7 +488,7 @@
 	struct d_partition * partition;
 #define DISKLABELMAGIC (0x82564557UL)
 
-	if (!(bh = bread(dev,0,1024))) {
+	if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
 		printk("unable to read partition table\n");
 		return -1;
 	}
@@ -509,7 +563,7 @@
 				 | (((__u32)(x) & 0xFF000000) >> 24) \
 				 : (__u32)(x))
 
-	if(!(bh = bread(dev, 0, 1024))) {
+	if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
 		printk("Dev %s: unable to read partition table\n",
 		       kdevname(dev));
 		return -1;
diff -ru linux2.0.30.unpatched/drivers/block/hd.c linux2.0.30.mopatched/drivers/block/hd.c
--- linux2.0.30.unpatched/drivers/block/hd.c	Fri Mar  1 05:50:39 1996
+++ linux2.0.30.mopatched/drivers/block/hd.c	Mon Apr 14 22:15:44 1997
@@ -801,6 +801,8 @@
 				(short *) &loc->cylinders);
 			put_user(hd[MINOR(inode->i_rdev)].start_sect,
 				(long *) &loc->start);
+			put_user(hardsect_size[MAJOR(dev)][MINOR(dev)],
+				(long *) &loc->sector_size);
 			return 0;
 		case BLKRASET:
 			if(!suser())  return -EACCES;
diff -ru linux2.0.30.unpatched/drivers/block/ide.c linux2.0.30.mopatched/drivers/block/ide.c
--- linux2.0.30.unpatched/drivers/block/ide.c	Tue Nov 19 14:21:06 1996
+++ linux2.0.30.mopatched/drivers/block/ide.c	Mon Apr 14 22:18:55 1997
@@ -2037,6 +2037,8 @@
 			put_user(drive->bios_cyl, (unsigned short *) &loc->cylinders);
 			put_user((unsigned)drive->part[MINOR(inode->i_rdev)&PARTN_MASK].start_sect,
 				(unsigned long *) &loc->start);
+			put_user(hardsect_size[MAJOR(inode->i_rdev)][MINOR(inode->i_rdev)],
+                                (long *) &loc->sector_size);
 			return 0;
 		}
 		case BLKFLSBUF:
diff -ru linux2.0.30.unpatched/drivers/block/md.c linux2.0.30.mopatched/drivers/block/md.c
--- linux2.0.30.unpatched/drivers/block/md.c	Sat Jun 29 21:04:00 1996
+++ linux2.0.30.mopatched/drivers/block/md.c	Mon Apr 14 22:15:44 1997
@@ -336,6 +336,8 @@
     put_user (md_hd_struct[minor].nr_sects/8, (short *) &loc->cylinders);
     put_user (md_hd_struct[MINOR(inode->i_rdev)].start_sect,
 		(long *) &loc->start);
+    put_user(hardsect_size[MAJOR(dev)][MINOR(dev)],
+                (long *) &loc->sector_size);
     break;
     
     RO_IOCTLS(inode->i_rdev,arg);
diff -ru linux2.0.30.unpatched/drivers/block/xd.c linux2.0.30.mopatched/drivers/block/xd.c
--- linux2.0.30.unpatched/drivers/block/xd.c	Sun Sep  8 16:50:20 1996
+++ linux2.0.30.mopatched/drivers/block/xd.c	Mon Apr 14 22:27:33 1997
@@ -260,6 +260,8 @@
 					put_user(xd_info[dev].sectors, &geometry->sectors);
 					put_user(xd_info[dev].cylinders, &geometry->cylinders);
 					put_user(xd[MINOR(inode->i_rdev)].start_sect,&geometry->start);
+					put_user(hardsect_size[MAJOR(dev)][MINOR(dev)],
+		                                (long *) &geometry->sector_size);
 
 					return (0);
 				}
diff -ru linux2.0.30.unpatched/drivers/scsi/sd.c linux2.0.30.mopatched/drivers/scsi/sd.c
--- linux2.0.30.unpatched/drivers/scsi/sd.c	Mon Apr 14 22:10:47 1997
+++ linux2.0.30.mopatched/drivers/scsi/sd.c	Mon Apr 14 22:15:45 1997
@@ -59,7 +59,7 @@
  */
 
 #define SD_TIMEOUT (15 * HZ)
-#define SD_MOD_TIMEOUT (15 * HZ)
+#define SD_MOD_TIMEOUT (75 * HZ)
 
 #define CLUSTERABLE_DEVICE(SC) (SC->host->use_clustering && \
 				SC->device->type != TYPE_MOD)
@@ -249,6 +249,11 @@
 	    error_sector <<= 1;
 	    if (block_sectors < 2) block_sectors = 2;
 	  }
+        else if (sector_size == 2048)
+	  {
+	    error_sector <<= 2;
+	    if (block_sectors < 4) block_sectors = 4;
+	  }
 	else if (sector_size == 256)
 	  error_sector >>= 1;
 	error_sector -= sd[MINOR(SCpnt->request.rq_dev)].start_sect;
@@ -629,6 +634,13 @@
 	    goto repeat;
 	}
     
+    if (rscsi_disks[dev].sector_size == 2048)
+	if((block & 3) || (SCpnt->request.nr_sectors & 3)) {
+	    printk("sd.c:Bad block number requested");
+	    SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
+	    goto repeat;
+	}
+    
     switch (SCpnt->request.cmd)
     {
     case WRITE :
@@ -895,6 +907,13 @@
     
     cmd[1] = (SCpnt->lun << 5) & 0xe0;
     
+    if (rscsi_disks[dev].sector_size == 2048){
+	if(block & 3) panic("sd.c:Bad block number requested");
+	if(this_count & 3) panic("sd.c:Bad block number requested");
+	block = block >> 2;
+	this_count = this_count >> 2;
+    }
+    
     if (rscsi_disks[dev].sector_size == 1024){
 	if(block & 1) panic("sd.c:Bad block number requested");
 	if(this_count & 1) panic("sd.c:Bad block number requested");
@@ -1196,6 +1215,7 @@
 	
 	if (rscsi_disks[i].sector_size != 512 &&
 	    rscsi_disks[i].sector_size != 1024 &&
+	    rscsi_disks[i].sector_size != 2048 &&
 	    rscsi_disks[i].sector_size != 256)
 	{
 	    printk ("sd%c : unsupported sector size %d.\n",
@@ -1210,6 +1230,22 @@
 		return i;
 	    }
 	}
+
+        if( rscsi_disks[i].sector_size == 2048 )
+          {
+            int m;
+
+            /*
+             * We must fix the sd_blocksizes and sd_hardsizes
+             * to allow us to read the partition tables.
+             * The disk reading code does not allow for reading
+             * of partial sectors.
+             */
+            for (m=i<<4; m<((i+1)<<4); m++)
+              {
+                sd_blocksizes[m] = 2048;
+              }
+          }
     {
 	/*
 	 * The msdos fs needs to know the hardware sector size
@@ -1233,6 +1269,8 @@
 		i+'a', hard_sector, rscsi_disks[i].capacity, 
                 mb, sz_quot, sz_rem);
     }
+	if(rscsi_disks[i].sector_size == 2048)
+	    rscsi_disks[i].capacity <<= 2;  /* Change into 512 byte sectors */
 	if(rscsi_disks[i].sector_size == 1024)
 	    rscsi_disks[i].capacity <<= 1;  /* Change into 512 byte sectors */
 	if(rscsi_disks[i].sector_size == 256)
@@ -1336,10 +1374,12 @@
     sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) * 
 					    sizeof(int), GFP_ATOMIC);
     
-    for(i=0;i<(sd_template.dev_max << 4);i++){
-	sd_blocksizes[i] = 1024;
-	sd_hardsizes[i] = 512;
-    }
+    for(i=0;i<(sd_template.dev_max << 4);i++)
+      {
+        sd_blocksizes[i] = 1024;
+        sd_hardsizes[i] = 512;
+      }
+
     blksize_size[MAJOR_NR] = sd_blocksizes;
     hardsect_size[MAJOR_NR] = sd_hardsizes;
     sd = (struct hd_struct *) scsi_init_malloc((sd_template.dev_max << 4) *
@@ -1472,9 +1512,15 @@
 	gdev->part[minor].nr_sects = 0;
         /*
          * Reset the blocksize for everything so that we can read
-         * the partition table.
+         * the partition table.  Technically we will determine the
+         * correct block size when we revalidate, but we do this just
+         * to make sure that everything remains consistent.
          */
         blksize_size[MAJOR_NR][minor] = 1024;
+        if( rscsi_disks[target].sector_size == 2048 )
+          blksize_size[MAJOR_NR][minor] = 2048;
+        else
+          blksize_size[MAJOR_NR][minor] = 1024;
     }
     
 #ifdef MAYBE_REINIT
diff -ru linux2.0.30.unpatched/drivers/scsi/sd_ioctl.c linux2.0.30.mopatched/drivers/scsi/sd_ioctl.c
--- linux2.0.30.unpatched/drivers/scsi/sd_ioctl.c	Thu May  2 04:48:54 1996
+++ linux2.0.30.mopatched/drivers/scsi/sd_ioctl.c	Mon Apr 14 22:15:45 1997
@@ -55,6 +55,7 @@
 	put_user(diskinfo[1], &loc->sectors);
 	put_user(diskinfo[2], &loc->cylinders);
 	put_user(sd[MINOR(inode->i_rdev)].start_sect, &loc->start);
+	put_user(hardsect_size[MAJOR(dev)][MINOR(dev)], &loc->sector_size);
 	return 0;
     case BLKGETSIZE:   /* Return device size */
 	if (!arg)  return -EINVAL;
diff -ru linux2.0.30.unpatched/drivers/scsi/sr.c linux2.0.30.mopatched/drivers/scsi/sr.c
--- linux2.0.30.unpatched/drivers/scsi/sr.c	Mon Apr 14 22:10:47 1997
+++ linux2.0.30.mopatched/drivers/scsi/sr.c	Mon Apr 14 22:15:45 1997
@@ -54,9 +54,10 @@
 					       sr_finish, sr_attach, sr_detach};
 
 Scsi_CD * scsi_CDs = NULL;
-static int * sr_sizes;
+static int * sr_sizes = NULL;
 
-static int * sr_blocksizes;
+static int * sr_blocksizes = NULL;
+static int * sr_hardsizes = NULL;              /* Hardware sector size */
 
 static int sr_open(struct inode *, struct file *);
 void get_sectorsize(int);
@@ -123,24 +124,37 @@
 	inode.i_rdev = full_dev;  /* This is all we really need here */
 	retval = sr_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
     
-	if(retval){ /* Unable to test, unit probably not ready.  This usually
+	if(retval)
+        {
+                /* Unable to test, unit probably not ready.  This usually
 		 * means there is no disc in the drive.  Mark as changed,
 		 * and we will figure it out later once the drive is
 		 * available again.  */
 	
-	scsi_CDs[target].device->changed = 1;
-	return 1; /* This will force a flush, if called from
-		   * check_disk_change */
-	};
+                scsi_CDs[target].device->changed = 1;
+                return 1; /* This will force a flush, if called from
+                           * check_disk_change */
+	}
     
 	retval = scsi_CDs[target].device->changed;
-	if(!flag) {
-	scsi_CDs[target].device->changed = 0;
-	/* If the disk changed, the capacity will now be different,
-	 * so we force a re-read of this information */
-	if (retval) scsi_CDs[target].needs_sector_size = 1;
-	};
-	return retval;
+	if(!flag) 
+        {
+                scsi_CDs[target].device->changed = 0;
+                /* 
+                 * If the disk changed, the capacity will now be different,
+                 * so we force a re-read of this information 
+                 * Force 2048 for the sector size so that filesystems won't
+                 * be trying to use something that is too small if the disc
+                 * has changed.
+                 */
+                if (retval) 
+                {
+                        scsi_CDs[target].needs_sector_size = 1;
+                        scsi_CDs[target].sector_size = 
+                                sr_hardsizes[target] = 2048;
+                }
+        }
+        return retval;
 }
 
 /*
@@ -1120,6 +1134,12 @@
 			scsi_CDs[i].capacity = 0;
 			scsi_CDs[i].needs_sector_size = 1;
 	}
+
+        /*
+         * Add this so that we have the ability to correctly gauge
+         * what the device is capable of.
+         */
+        sr_hardsizes[i] = scsi_CDs[i].sector_size;
 	scsi_CDs[i].needs_sector_size = 0;
 	sr_sizes[i] = scsi_CDs[i].capacity >> (BLOCK_SIZE_BITS - 9);
     };
@@ -1153,8 +1173,16 @@
 
     sr_blocksizes = (int *) scsi_init_malloc(sr_template.dev_max * 
 					 sizeof(int), GFP_ATOMIC);
+    sr_hardsizes =  (int *) scsi_init_malloc(sr_template.dev_max * 
+                                         sizeof(int), GFP_ATOMIC);
+
+    /*
+     * These are good guesses for the time being.
+     */
     for(i=0;i<sr_template.dev_max;i++) sr_blocksizes[i] = 2048;
+    for(i=0;i<sr_template.dev_max;i++) sr_hardsizes[i] = 2048;
     blksize_size[MAJOR_NR] = sr_blocksizes;
+    hardsect_size[MAJOR_NR] = sr_hardsizes;
     return 0;
 }
 
@@ -1247,7 +1275,13 @@
 		       * sizeof(Scsi_CD));
 	
 	scsi_init_free((char *) sr_sizes, sr_template.dev_max * sizeof(int));
+        sr_sizes = NULL;
+
 	scsi_init_free((char *) sr_blocksizes, sr_template.dev_max * sizeof(int));
+        sr_blocksizes = NULL;
+
+	scsi_init_free((char *) sr_hardsizes,  sr_template.dev_max * sizeof(int));
+        sr_hardsizes = NULL;
     }
     
     blksize_size[MAJOR_NR] = NULL;
diff -ru linux2.0.30.unpatched/drivers/sound/Config.in linux2.0.30.mopatched/drivers/sound/Config.in
--- linux2.0.30.unpatched/drivers/sound/Config.in	Wed Jul 10 11:34:03 1996
+++ linux2.0.30.mopatched/drivers/sound/Config.in	Mon Apr 14 22:19:47 1997
@@ -1,15 +1,251 @@
-#
-# Sound driver configuration
-#
-#--------
-# There is another confic script which is compatible with rest of
-# the kernel. It can be activated by running 'make mkscript' in this
-# directory. Please note that this is an _experimental_ feature which
-# doesn't work with all cards (PSS, SM Wave, AudioTriX Pro, Maui).
-#--------
-#
-$MAKE -C drivers/sound config || exit 1
+bool 'ProAudioSpectrum 16 support' CONFIG_PAS
+bool 'Sound Blaster (SB, SBPro, SB16, clones) support' CONFIG_SB
+bool 'Generic OPL2/OPL3 FM synthesizer support' CONFIG_ADLIB
+bool 'Gravis Ultrasound support' CONFIG_GUS
+bool 'MPU-401 support (NOT for SB16)' CONFIG_MPU401
+bool '6850 UART Midi support' CONFIG_UART6850
+bool 'PSS (ECHO-ADI2111) support' CONFIG_PSS
+bool '16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16
+bool 'GUS MAX support' CONFIG_GUSMAX
+bool 'Microsoft Sound System support' CONFIG_MSS
+bool 'Ensoniq SoundScape support' CONFIG_SSCAPE
+bool 'MediaTrix AudioTrix Pro support' CONFIG_TRIX
+bool 'Support for MAD16 and/or Mozart based cards' CONFIG_MAD16
+bool 'Support for Crystal CS4232 based (PnP) cards' CONFIG_CS4232
+bool 'Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_MAUI
+bool '/dev/dsp and /dev/audio support' CONFIG_AUDIO
+bool 'MIDI interface support' CONFIG_MIDI
+bool 'FM synthesizer (YM3812/OPL-3) support' CONFIG_YM3812
+
+if [ "$CONFIG_SB" = "y" ]; then
+hex 'I/O base for SB Check from manual of the card' SBC_BASE 220
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+int 'Sound Blaster IRQ Check from manual of the card' SBC_IRQ 7
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+int 'Sound Blaster DMA 0, 1 or 3' SBC_DMA 1
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+int 'Sound Blaster 16 bit DMA (_REQUIRED_for SB16, Jazz16, SMW) 5, 6 or 7 (use 1 for 8 bit cards)' SB_DMA2 5
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+hex 'MPU401 I/O base of SB16, Jazz16 and ES1688 Check from manual of the card' SB_MPU_BASE 0
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+int 'SB MPU401 IRQ (Jazz16, SM Wave and ES1688) Use -1 with SB16' SB_MPU_IRQ -1
+fi
+
+if [ "$CONFIG_PAS" = "y" ]; then
+int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' PAS_IRQ 10
+fi
+
+if [ "$CONFIG_PAS" = "y" ]; then
+int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' PAS_DMA 3
+fi
+
+if [ "$CONFIG_GUS" = "y" ]; then
+hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' GUS_BASE 220
+fi
+
+if [ "$CONFIG_GUS" = "y" ]; then
+int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' GUS_IRQ 15
+fi
+
+if [ "$CONFIG_GUS" = "y" ]; then
+int 'GUS DMA 1, 3, 5, 6 or 7' GUS_DMA 6
+fi
+
+if [ "$CONFIG_GUS" = "y" ]; then
+int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' GUS_DMA2 -1
+fi
+
+if [ "$CONFIG_GUS16" = "y" ]; then
+hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' GUS16_BASE 530
+fi
+
+if [ "$CONFIG_GUS16" = "y" ]; then
+int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' GUS16_IRQ 7
+fi
+
+if [ "$CONFIG_GUS16" = "y" ]; then
+int 'GUS DMA 0, 1 or 3' GUS16_DMA 3
+fi
+
+if [ "$CONFIG_MPU401" = "y" ]; then
+hex 'I/O base for MPU401 Check from manual of the card' MPU_BASE 330
+fi
+
+if [ "$CONFIG_MPU401" = "y" ]; then
+int 'MPU401 IRQ Check from manual of the card' MPU_IRQ 9
+fi
+
+if [ "$CONFIG_MAUI" = "y" ]; then
+hex 'I/O base for Maui 210, 230, 260, 290, 300, 320, 338 or 330' MAUI_BASE 330
+fi
+
+if [ "$CONFIG_MAUI" = "y" ]; then
+int 'Maui IRQ 5, 9, 12 or 15' MAUI_IRQ 9
+fi
+
+if [ "$CONFIG_UART6850" = "y" ]; then
+hex 'I/O base for UART 6850 MIDI port (Unknown)' U6850_BASE 0
+fi
+
+if [ "$CONFIG_UART6850" = "y" ]; then
+int 'UART6850 IRQ (Unknown)' U6850_IRQ -1
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+hex 'PSS I/O base 220 or 240' PSS_BASE 220
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+hex 'PSS audio I/O base 530, 604, E80 or F40' PSS_MSS_BASE 530
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+int 'PSS audio IRQ 7, 9, 10 or 11' PSS_MSS_IRQ 11
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+int 'PSS audio DMA 0, 1 or 3' PSS_MSS_DMA 3
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+hex 'PSS MIDI I/O base ' PSS_MPU_BASE 330
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+int 'PSS MIDI IRQ 3, 4, 5, 7 or 9' PSS_MPU_IRQ 9
+fi
 
+if [ "$CONFIG_MSS" = "y" ]; then
+hex 'MSS/WSS I/O base 530, 604, E80 or F40' MSS_BASE 530
+fi
+
+if [ "$CONFIG_MSS" = "y" ]; then
+int 'MSS/WSS IRQ 7, 9, 10 or 11' MSS_IRQ 11
+fi
+
+if [ "$CONFIG_MSS" = "y" ]; then
+int 'MSS/WSS DMA 0, 1 or 3' MSS_DMA 3
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+hex 'SoundScape MIDI I/O base 320, 330, 340 or 350' SSCAPE_BASE 330
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+int 'SoundScape MIDI IRQ ' SSCAPE_IRQ 9
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+int 'SoundScape initialization DMA 0, 1 or 3' SSCAPE_DMA 3
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+hex 'SoundScape audio I/O base 534, 608, E84 or F44' SSCAPE_MSS_BASE 534
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+int 'SoundScape audio IRQ 7, 9, 10 or 11' SSCAPE_MSS_IRQ 11
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+hex 'AudioTrix audio I/O base 530, 604, E80 or F40' TRIX_BASE 530
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'AudioTrix audio IRQ 7, 9, 10 or 11' TRIX_IRQ 11
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'AudioTrix audio DMA 0, 1 or 3' TRIX_DMA 0
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'AudioTrix second (duplex) DMA 0, 1 or 3' TRIX_DMA2 3
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+hex 'AudioTrix MIDI I/O base 330, 370, 3B0 or 3F0' TRIX_MPU_BASE 330
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'AudioTrix MIDI IRQ 3, 4, 5, 7 or 9' TRIX_MPU_IRQ 9
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+hex 'AudioTrix SB I/O base 220, 210, 230, 240, 250, 260 or 270' TRIX_SB_BASE 220
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'AudioTrix SB IRQ 3, 4, 5 or 7' TRIX_SB_IRQ 7
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'AudioTrix SB DMA 1 or 3' TRIX_SB_DMA 1
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+hex 'CS4232 audio I/O base 530, 604, E80 or F40' CS4232_BASE 530
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CS4232_IRQ 11
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+int 'CS4232 audio DMA 0, 1 or 3' CS4232_DMA 0
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+int 'CS4232 second (duplex) DMA 0, 1 or 3' CS4232_DMA2 3
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CS4232_MPU_BASE 330
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CS4232_MPU_IRQ 9
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+hex 'MAD16 audio I/O base 530, 604, E80 or F40' MAD16_BASE 530
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+int 'MAD16 audio IRQ 7, 9, 10 or 11' MAD16_IRQ 11
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+int 'MAD16 audio DMA 0, 1 or 3' MAD16_DMA 3
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+int 'MAD16 second (duplex) DMA 0, 1 or 3' MAD16_DMA2 0
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+hex 'MAD16 MIDI I/O base 300, 310, 320 or 330 (0 disables)' MAD16_MPU_BASE 330
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+int 'MAD16 MIDI IRQ 5, 7, 9 or 10' MAD16_MPU_IRQ 9
+fi
+
+if [ "$CONFIG_AUDIO" = "y" ]; then
+int 'Audio DMA buffer size 4096, 16384, 32768 or 65536' DSP_BUFFSIZE 65536
+fi
+#
+$MAKE -C drivers/sound kernelconfig || exit 1
 bool 'Additional low level drivers' CONFIG_LOWLEVEL_SOUND
 
 if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
diff -ru linux2.0.30.unpatched/fs/buffer.c linux2.0.30.mopatched/fs/buffer.c
--- linux2.0.30.unpatched/fs/buffer.c	Mon Apr 14 22:10:47 1997
+++ linux2.0.30.mopatched/fs/buffer.c	Mon Apr 14 22:15:45 1997
@@ -28,7 +28,7 @@
 #include <linux/swapctl.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
-
+#include <linux/blkdev.h>
 #include <asm/system.h>
 #include <asm/segment.h>
 #include <asm/io.h>
@@ -483,6 +483,31 @@
 			return bh;
 		bh->b_count--;
 	}
+}
+
+unsigned int get_hardblocksize(kdev_t dev)
+{
+  int blksize = 0;
+
+  /*
+   * Get the hard sector size for the given device.  If we don't know
+   * what it is, return 0.
+   */
+
+  if (hardsect_size[MAJOR(dev)] != NULL)
+    {
+      blksize = hardsect_size[MAJOR(dev)][MINOR(dev)];
+      if (blksize != 0)
+	{
+	  return blksize;
+	}
+  }
+
+  /*
+   * We don't know what the hardware sector size for this device is.
+   * Return 0 indicating that we don't know.
+   */
+  return 0;
 }
 
 void set_blocksize(kdev_t dev, int size)
diff -ru linux2.0.30.unpatched/fs/ext2/super.c linux2.0.30.mopatched/fs/ext2/super.c
--- linux2.0.30.unpatched/fs/ext2/super.c	Sun Jul  7 08:06:53 1996
+++ linux2.0.30.mopatched/fs/ext2/super.c	Mon Apr 14 22:15:45 1997
@@ -29,6 +29,7 @@
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/locks.h>
+#include <linux/blkdev.h>
 
 static char error_buf[1024];
 
@@ -371,10 +372,24 @@
 	unsigned short resuid = EXT2_DEF_RESUID;
 	unsigned short resgid = EXT2_DEF_RESGID;
 	unsigned long logic_sb_block = 1;
+	unsigned long offset = 0;
 	kdev_t dev = sb->s_dev;
+	int blocksize = BLOCK_SIZE;
+	int hblock;
 	int db_count;
 	int i, j;
 
+	/*
+	 * See what the current blocksize for the device is, and
+	 * use that as the blocksize.  Otherwise (or if the blocksize
+	 * is smaller than the default) use the default.
+	 */
+	blocksize = get_hardblocksize(dev);
+	if( blocksize <= 1024)
+	  {
+	    blocksize = BLOCK_SIZE;
+	  }
+
 	sb->u.ext2_sb.s_mount_opt = 0;
 	set_opt (sb->u.ext2_sb.s_mount_opt, CHECK_NORMAL);
 	if (!parse_options ((char *) data, &sb_block, &resuid, &resgid,
@@ -385,8 +400,19 @@
 
 	MOD_INC_USE_COUNT;
 	lock_super (sb);
-	set_blocksize (dev, BLOCK_SIZE);
-	if (!(bh = bread (dev, sb_block, BLOCK_SIZE))) {
+	set_blocksize (dev, blocksize);
+
+	/*
+	 * If the superblock doesn't start on a sector boundary,
+	 * calculate the offset.  FIXME(eric) this doesn't make sense
+	 * that we would have to do this.
+	 */
+	if (blocksize != BLOCK_SIZE) {
+		logic_sb_block = (sb_block*BLOCK_SIZE) / blocksize;
+		offset = (sb_block*BLOCK_SIZE) % blocksize;
+	}
+
+	if (!(bh = bread (dev, logic_sb_block, blocksize))) {
 		sb->s_dev = 0;
 		unlock_super (sb);
 		printk ("EXT2-fs: unable to read superblock\n");
@@ -397,7 +423,7 @@
 	 * Note: s_es must be initialized s_es as soon as possible because
 	 * some ext2 macro-instructions depend on its value
 	 */
-	es = (struct ext2_super_block *) bh->b_data;
+	es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
 	sb->u.ext2_sb.s_es = es;
 	sb->s_magic = es->s_magic;
 	if (sb->s_magic != EXT2_SUPER_MAGIC) {
@@ -432,7 +458,17 @@
 	if (sb->s_blocksize != BLOCK_SIZE && 
 	    (sb->s_blocksize == 1024 || sb->s_blocksize == 2048 ||  
 	     sb->s_blocksize == 4096)) {
-		unsigned long offset;
+		/*
+		 * Make sure the blocksize for the filesystem is larger
+		 * than the hardware sectorsize for the machine.
+		 */
+		hblock = get_hardblocksize(dev);
+		if(    (hblock != 0)
+		    && (sb->s_blocksize < hblock) )
+		{
+			printk("EXT2-fs: blocksize too small for device.\n");
+			goto failed_mount;
+		}
 
 		brelse (bh);
 		set_blocksize (dev, sb->s_blocksize);
diff -ru linux2.0.30.unpatched/fs/fat/buffer.c linux2.0.30.mopatched/fs/fat/buffer.c
--- linux2.0.30.unpatched/fs/fat/buffer.c	Fri May 10 04:54:52 1996
+++ linux2.0.30.mopatched/fs/fat/buffer.c	Mon Apr 14 22:15:45 1997
@@ -16,13 +16,18 @@
 {
 	struct buffer_head *ret = NULL;
 
-	/* Note that the blocksize is 512 or 1024, but the first read
-	   is always of size 1024. Doing readahead may be counterproductive
+	/* Note that the blocksize is 512, 1024 or 2048, but the first read
+	   is always of size 1024 (or 2048). Doing readahead may be counterproductive
 	   or just plain wrong. */
 	if (sb->s_blocksize == 512) {
 		ret = bread (sb->s_dev,block,512);
 	} else {
-		struct buffer_head *real = bread (sb->s_dev,block>>1,1024);
+		struct buffer_head *real;
+		if (sb->s_blocksize == 1024){
+			real = bread (sb->s_dev,block>>1,1024);
+		}else{
+			real = bread (sb->s_dev,block>>2,2048);
+		}
 
 		if (real != NULL){
 			ret = (struct buffer_head *)
@@ -59,7 +64,11 @@
 				*/
 				memset (ret,0,sizeof(*ret));
 				ret->b_data = real->b_data;
-				if (block & 1) ret->b_data += 512;
+				if (sb->s_blocksize == 2048) {
+					if (block & 3) ret->b_data += (block & 3) << 9;
+				}else{
+					if (block & 1) ret->b_data += 512;
+				}
 				ret->b_next = real;
 			}else{
 				brelse (real);
diff -ru linux2.0.30.unpatched/fs/fat/inode.c linux2.0.30.mopatched/fs/fat/inode.c
--- linux2.0.30.unpatched/fs/fat/inode.c	Sat Nov 30 10:27:38 1996
+++ linux2.0.30.mopatched/fs/fat/inode.c	Mon Apr 14 22:15:45 1997
@@ -172,8 +172,8 @@
 			*blksize = simple_strtoul(value,&value,0);
 			if (*value)
 				return 0;
-			if (*blksize != 512 && *blksize != 1024){
-				printk ("MSDOS FS: Invalid blocksize (512 or 1024)\n");
+			if (*blksize != 512 && *blksize != 1024 && *blksize != 2048){
+				printk ("MSDOS FS: Invalid blocksize (512, 1024 or 2048)\n");
 			}
 		}
 		else if (!strcmp(this_char,"sys_immutable")) {
@@ -205,16 +205,25 @@
 		}
 	}
 	if (!parse_options((char *) data, &fat, &blksize, &debug, &opts)
-		|| (blksize != 512 && blksize != 1024)) {
+		|| (blksize != 512 && blksize != 1024 && blksize != 2048)) {
 		sb->s_dev = 0;
 		MOD_DEC_USE_COUNT;
 		return NULL;
 	}
 	cache_init();
 	lock_super(sb);
-	/* The first read is always 1024 bytes */
-	sb->s_blocksize = 1024;
-	set_blocksize(sb->s_dev, 1024);
+	if( blksize > 1024 )
+	  {
+	    /* Force the superblock to a larger size here. */
+	    sb->s_blocksize = blksize;
+	    set_blocksize(sb->s_dev, blksize);
+	  }
+	else
+	  {
+	    /* The first read is always 1024 bytes */
+	    sb->s_blocksize = 1024;
+	    set_blocksize(sb->s_dev, 1024);
+	  }
 	bh = fat_bread(sb, 0);
 	unlock_super(sb);
 	if (bh == NULL || !fat_is_uptodate(sb,bh)) {
@@ -285,7 +294,7 @@
 				/* the misfit with buffer cache and cluster */
 				/* because clusters (DOS) are often aligned */
 				/* on odd sectors. */
-	sb->s_blocksize_bits = blksize == 512 ? 9 : 10;
+	sb->s_blocksize_bits = blksize == 512 ? 9 : (blksize == 1024 ? 10 : 11);
 	if (error || debug) {
 		/* The MSDOS_CAN_BMAP is obsolete, but left just to remember */
 		printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,"
@@ -451,7 +460,7 @@
 		       !is_exec(raw_entry->ext)))
 		    	? S_IRUGO|S_IWUGO : S_IRWXUGO)
 		    & ~MSDOS_SB(sb)->options.fs_umask) | S_IFREG;
-		inode->i_op = (sb->s_blocksize == 1024)
+		inode->i_op = (sb->s_blocksize == 1024 || sb->s_blocksize == 2048)
 			? &fat_file_inode_operations_1024
 			: &fat_file_inode_operations;
 		MSDOS_I(inode)->i_start = CF_LE_W(raw_entry->start);
diff -ru linux2.0.30.unpatched/fs/isofs/dir.c linux2.0.30.mopatched/fs/isofs/dir.c
--- linux2.0.30.unpatched/fs/isofs/dir.c	Tue Jul 23 07:26:40 1996
+++ linux2.0.30.mopatched/fs/isofs/dir.c	Mon Apr 14 22:15:45 1997
@@ -131,28 +131,12 @@
 		return 0;
 
 	while (filp->f_pos < inode->i_size) {
-		int de_len, next_offset;
+		int de_len;
 #ifdef DEBUG
 		printk("Block, offset, f_pos: %x %x %x\n",
 		       block, offset, filp->f_pos);
 	        printk("inode->i_size = %x\n",inode->i_size);
 #endif
-		/* Next directory_record on next CDROM sector */
-		if (offset >= bufsize) {
-#ifdef DEBUG
-		        printk("offset >= bufsize\n");
-#endif
-			brelse(bh);
-			offset = 0;
-			block = isofs_bmap(inode, (filp->f_pos) >> bufbits);
-			if (!block)
-				return 0;
-			bh = breada(inode->i_dev, block, bufsize, filp->f_pos, inode->i_size);
-			if (!bh)
-				return 0;
-			continue;
-		}
-
 		de = (struct iso_directory_record *) (bh->b_data + offset);
 		inode_number = (block << bufbits) + (offset & (bufsize - 1));
 
@@ -166,7 +150,7 @@
 		   CDROM sector.  If we are at the end of the directory, we
 		   kick out of the while loop. */
 
-		if (de_len == 0) {
+		if ((de_len == 0) || (offset == bufsize) ) {
 			brelse(bh);
 			filp->f_pos = ((filp->f_pos & ~(ISOFS_BLOCK_SIZE - 1))
 				       + ISOFS_BLOCK_SIZE);
@@ -180,40 +164,18 @@
 			continue;
 		}
 
-		/* Make sure that the entire directory record is in the
-		   current bh block.
-		   If not, put the two halves together in "tmpde" */
-		next_offset = offset + de_len;
-		if (next_offset > bufsize) {
-#ifdef DEBUG
-		        printk("next_offset (%x) > bufsize (%x)\n",next_offset,bufsize);
-#endif
-			next_offset &= (bufsize - 1);
-		        memcpy(tmpde, de, bufsize - offset);
-			brelse(bh);
-			block = isofs_bmap(inode, (filp->f_pos + de_len) >> bufbits);
-			if (!block)
-		        {
-				return 0;
-			}
-		  
-			bh = breada(inode->i_dev, block, bufsize, 
-				    filp->f_pos, 
-				    inode->i_size);
-			if (!bh)
-		        {
-#ifdef DEBUG
-                 		printk("!bh block=%ld, bufsize=%ld\n",block,bufsize); 
- 				printk("filp->f_pos = %ld\n",filp->f_pos);
-				printk("inode->i_size = %ld\n", inode->i_size);
-#endif
-				return 0;
-			}
-		  
-			memcpy(bufsize - offset + (char *) tmpde, bh->b_data, next_offset);
-			de = tmpde;
+		offset +=  de_len;
+		if (offset > bufsize) {
+			/*
+			 * This would only normally happen if we had
+			 * a buggy cdrom image.  All directory
+			 * entries should terminate with a null size
+			 * or end exactly at the end of the sector.
+			 */
+		        printk("next_offset (%x) > bufsize (%x)\n",
+			       offset,bufsize);
+			break;
 		}
-		offset = next_offset;
 
 		/* Handle the case of the '.' directory */
 		if (de->name_len[0] == 1 && de->name[0] == 0) {
diff -ru linux2.0.30.unpatched/fs/isofs/inode.c linux2.0.30.mopatched/fs/isofs/inode.c
--- linux2.0.30.unpatched/fs/isofs/inode.c	Sat Aug 17 18:19:28 1996
+++ linux2.0.30.mopatched/fs/isofs/inode.c	Mon Apr 14 22:15:45 1997
@@ -85,8 +85,11 @@
 	popt->check = 's';		/* default: strict */
 	popt->conversion = 'b';		/* default: no conversion */
 	popt->blocksize = 1024;
-	popt->mode = S_IRUGO;
-	popt->gid = 0;
+	popt->mode = S_IRUGO | S_IXUGO; /* r-x for all.  The disc could
+					   be shared with DOS machines so
+					   virtually anything could be
+					   a valid executable. */
+ 	popt->gid = 0;
 	popt->uid = 0;
 	if (!options) return 1;
 	for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
@@ -221,23 +224,22 @@
 struct super_block *isofs_read_super(struct super_block *s,void *data,
 				     int silent)
 {
-	struct buffer_head *bh=NULL;
-	int iso_blknum;
-	unsigned int blocksize_bits;
-	int high_sierra;
-	kdev_t dev = s->s_dev;
-	unsigned int vol_desc_start;
-	int orig_zonesize;
-
-	struct iso_volume_descriptor *vdp;
-	struct hs_volume_descriptor *hdp;
-
-	struct iso_primary_descriptor *pri = NULL;
-	struct hs_primary_descriptor *h_pri = NULL;
+	struct buffer_head	      * bh = NULL;
+	unsigned int			blocksize;
+	unsigned int			blocksize_bits;
+	kdev_t				dev = s->s_dev;
+	struct hs_volume_descriptor   * hdp;
+	struct hs_primary_descriptor  * h_pri = NULL;
+	int				high_sierra;
+	int				iso_blknum;
+	struct iso9660_options		opt;
+	int				orig_zonesize;
+	struct iso_primary_descriptor * pri = NULL;
+	struct iso_directory_record   * rootp;
+	struct iso_volume_descriptor  * vdp;
+	unsigned int			vol_desc_start;
 
-	struct iso_directory_record *rootp;
 
-	struct iso9660_options opt;
 
 	MOD_INC_USE_COUNT;
 
@@ -259,6 +261,23 @@
 	printk("uid = %d\n", opt.uid);
 #endif
 	
+	/*
+	 * First of all, get the hardware blocksize for this device.
+	 * If we don't know what it is, or the hardware blocksize is
+	 * larger than the blocksize the user specified, then use
+	 * that value.
+	 */
+	blocksize = get_hardblocksize(dev);
+	if(    (blocksize != 0)
+	    && (blocksize > opt.blocksize) )
+	  {
+	    /*
+	     * Force the blocksize we are going to use to be the
+	     * hardware blocksize.
+	     */
+	    opt.blocksize = blocksize;
+	  }
+
 	blocksize_bits = 0;
 	{
 	  int i = opt.blocksize;
@@ -267,6 +286,7 @@
 	    i >>=1;
 	  }
 	}
+
 	set_blocksize(dev, opt.blocksize);
 
 	lock_super(s);
@@ -356,6 +376,24 @@
 	/* RDE: convert log zone size to bit shift */
 
 	orig_zonesize = s -> u.isofs_sb.s_log_zone_size;
+
+	/*
+	 * If the zone size is smaller than the hardware sector size,
+	 * this is a fatal error.  This would occur if the
+	 * disc drive had sectors that were 2048 bytes, but the filesystem
+	 * had blocks that were 512 bytes (which should only very rarely
+	 * happen.
+	 */
+	if(    (blocksize != 0)
+	    && (orig_zonesize < blocksize) )
+	  {
+	      printk("Logical zone size(%ld) < hardware blocksize(%ld)\n", 
+		     orig_zonesize, blocksize);
+	      goto out;
+
+	  }
+
+
 	switch (s -> u.isofs_sb.s_log_zone_size)
 	  { case  512: s -> u.isofs_sb.s_log_zone_size =  9; break;
 	    case 1024: s -> u.isofs_sb.s_log_zone_size = 10; break;
@@ -397,8 +435,20 @@
 	 * Force the blocksize to 512 for 512 byte sectors.  The file
 	 * read primitives really get it wrong in a bad way if we don't
 	 * do this.
+	 *
+	 * Note - we should never be setting the blocksize to something
+	 * less than the hardware sector size for the device.  If we
+	 * do, we would end up having to read larger buffers and split
+	 * out portions to satisfy requests.
+	 *
+	 * Note2- the idea here is that we want to deal with the optimal
+	 * zonesize in the filesystem.  If we have it set to something less,
+	 * then we have horrible problems with trying to piece together
+	 * bits of adjacent blocks in order to properly read directory
+	 * entries.  By forcing the blocksize in this way, we ensure
+	 * that we will never be required to do this.
 	 */
-	if( orig_zonesize < opt.blocksize )
+	if( orig_zonesize != opt.blocksize )
 	  {
 	    opt.blocksize = orig_zonesize;
 	    blocksize_bits = 0;
@@ -496,7 +546,6 @@
 	struct buffer_head * bh;
 	struct iso_directory_record * raw_inode;
 	unsigned char *pnt = NULL;
-	void *cpnt = NULL;
 	int high_sierra;
 	int block;
 	int volume_seq_no ;
@@ -513,30 +562,6 @@
 	raw_inode = ((struct iso_directory_record *) pnt);
 	high_sierra = inode->i_sb->u.isofs_sb.s_high_sierra;
 
-	if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize){
-	        int frag1, offset;
-
-		offset = (inode->i_ino & (bufsize - 1));
-		frag1 = bufsize - offset;
-	        cpnt = kmalloc(*pnt,GFP_KERNEL);
-		if (cpnt == NULL) {
-			printk(KERN_INFO "NoMem ISO inode %lu\n",inode->i_ino);
-			brelse(bh);
-			goto fail;
-		}
-		memcpy(cpnt, bh->b_data + offset, frag1);
-		brelse(bh);
-		if (!(bh = bread(inode->i_dev,++block, bufsize))) {
-			kfree(cpnt);
-			printk("unable to read i-node block");
-			goto fail;
-		}
-		offset += *pnt - bufsize;
-		memcpy((char *)cpnt+frag1, bh->b_data, offset);
-		pnt = ((unsigned char *) cpnt);
-		raw_inode = ((struct iso_directory_record *) pnt);
-	}
-
 	if (raw_inode->flags[-high_sierra] & 2) {
 		inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
 		inode->i_nlink = 1; /* Set to 1.  We know there are 2, but
@@ -676,10 +701,6 @@
 	  else if (S_ISFIFO(inode->i_mode))
 	    init_fifo(inode);
 	}
-	if (cpnt) {
-		kfree (cpnt);
-		cpnt = NULL;
-	}
 	return;
       fail:
 	/* With a data error we return this information */
@@ -719,8 +740,6 @@
 	unsigned char bufbits = ISOFS_BUFFER_BITS(parent);
 	unsigned int block,offset;
 	int parent_dir, inode_number;
-	int old_offset;
-	void * cpnt = NULL;
 	int result;
 	int directory_size;
 	struct buffer_head * bh;
@@ -780,7 +799,7 @@
 		   CDROM sector.  If we are at the end of the directory, we
 		   kick out of the while loop. */
 		
-		if (*((unsigned char *) de) == 0) 
+		if ((*((unsigned char *) de) == 0) || (offset == bufsize) )
 		{
 			brelse(bh);
 			offset = 0;
@@ -807,52 +826,24 @@
 		   bh block.  If not, we malloc a buffer, and put the two
 		   halves together, so that we can cleanly read the block.  */
 
-		old_offset = offset;
 		offset += *((unsigned char *) de);
 
-		if (offset >= bufsize)
+		if (offset > bufsize)
 		{
- 		        unsigned int frag1;
- 			frag1 = bufsize - old_offset;
- 			cpnt = kmalloc(*((unsigned char *) de),GFP_KERNEL);
-			if (!cpnt) return -1;
- 			memcpy(cpnt, bh->b_data + old_offset, frag1);
- 			de = (struct iso_directory_record *) ((char *)cpnt);
-			brelse(bh);
-			offset -= bufsize;
- 			directory_size -= bufsize;
-			if(directory_size < 0) 
-			{
-				printk("Directory size < 0\n");
-				return -1;
-			}
-			block++;
-			if(!(bh = bread(parent->i_dev,block,bufsize))) {
- 			        kfree(cpnt);
-				return -1;
-			}
- 			memcpy((char *)cpnt+frag1, bh->b_data, offset);
+			printk("Directory overrun\n");
+			goto out;
 		}
 		
 		if (find_rock_ridge_relocation(de, parent) == extent){
 			result = inode_number;
 			goto out;
 		}
-		
-		if (cpnt) {
-			kfree(cpnt);
-			cpnt = NULL;
-		}
 	}
 
 	/* We go here for any condition we cannot handle.
 	   We also drop through to here at the end of the directory. */
 
  out:
-	if (cpnt) {
-	        kfree(cpnt);
-		cpnt = NULL;
-	}
 	brelse(bh);
 #ifdef DEBUG
 	printk("Resultant Inode %d\n",result);
diff -ru linux2.0.30.unpatched/fs/isofs/rock.c linux2.0.30.mopatched/fs/isofs/rock.c
--- linux2.0.30.unpatched/fs/isofs/rock.c	Sat May 18 08:15:09 1996
+++ linux2.0.30.mopatched/fs/isofs/rock.c	Mon Apr 14 22:15:45 1997
@@ -203,6 +203,16 @@
 	break;
       case SIG('N','M'):
 	if (truncate) break;
+        /*
+	 * If the flags are 2 or 4, this indicates '.' or '..'.
+	 * We don't want to do anything with this, because it
+	 * screws up the code that calls us.  We don't really
+	 * care anyways, since we can just use the non-RR
+	 * name.
+	 */
+	if (rr->u.NM.flags & 6) {
+	  break;
+	}
 	if (rr->u.NM.flags & ~1) {
 	  printk("Unsupported NM flag settings (%d)\n",rr->u.NM.flags);
 	  break;
diff -ru linux2.0.30.unpatched/include/linux/fs.h linux2.0.30.mopatched/include/linux/fs.h
--- linux2.0.30.unpatched/include/linux/fs.h	Mon Apr 14 22:10:48 1997
+++ linux2.0.30.mopatched/include/linux/fs.h	Mon Apr 14 22:22:46 1997
@@ -644,6 +644,7 @@
 		__bforget(buf);
 }
 extern void set_blocksize(kdev_t dev, int size);
+extern unsigned int get_hardblocksize(kdev_t dev);
 extern struct buffer_head * bread(kdev_t dev, int block, int size);
 extern struct buffer_head * breada(kdev_t dev,int block, int size, 
 				   unsigned int pos, unsigned int filesize);
diff -ru linux2.0.30.unpatched/include/linux/hdreg.h linux2.0.30.mopatched/include/linux/hdreg.h
--- linux2.0.30.unpatched/include/linux/hdreg.h	Sun Dec  1 17:59:18 1996
+++ linux2.0.30.mopatched/include/linux/hdreg.h	Mon Apr 14 22:22:46 1997
@@ -80,6 +80,7 @@
       unsigned char sectors;
       unsigned short cylinders;
       unsigned long start;
+      unsigned short sector_size;
 };
 
 /* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */
diff -ru linux2.0.30.unpatched/include/linux/xd.h linux2.0.30.mopatched/include/linux/xd.h
--- linux2.0.30.unpatched/include/linux/xd.h	Fri Mar  1 05:50:56 1996
+++ linux2.0.30.mopatched/include/linux/xd.h	Mon Apr 14 22:30:02 1997
@@ -93,6 +93,7 @@
 	u_char sectors;
 	u_short cylinders;
 	u_long start;
+	u_long sector_size;
 } XD_GEOMETRY;
 
 /* this structure defines a ROM BIOS signature */
diff -ru linux2.0.30.unpatched/kernel/ksyms.c linux2.0.30.mopatched/kernel/ksyms.c
--- linux2.0.30.unpatched/kernel/ksyms.c	Mon Apr 14 22:10:49 1997
+++ linux2.0.30.mopatched/kernel/ksyms.c	Mon Apr 14 22:15:45 1997
@@ -154,6 +154,7 @@
 	X(permission),
 	X(inode_setattr),
 	X(inode_change_ok),
+	X(get_hardblocksize),
 	X(set_blocksize),
 	X(getblk),
 	X(bread),

--------------B210502028B3D614C31872--


home help back first fref pref prev next nref lref last post