Date: Fri, 12 Jun 1998 11:50:27 +0200 (MET DST)
From: Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
To: Jes.Sorensen@cern.ch,
        Russell King - ARM Linux Admin <linux@arm.uk.linux.org>
Cc: linux-m68k@lists.linux-m68k.org
Subject: L68K: Merge of partition checking code
Sender: owner-linux-m68k@phil.uni-sb.de


Below is a patch for Linux/68k 2.1.105 which merges Russell's and my
variants of how to do it. All the partition checkers are moved to
fs/partitions/*.c, and fs/partcheck.c is the coordinator of them. The
parsers can be modules and can be loaded by kmod.

To Russell: I've integrated the latest version of your sources that
you sent me and just added some le32_to_cpu calls to make the parser
endianess independent. I hope the version I took is still current...
Otherwise, could you please integrate any updates?

Roman

diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/Makefile linux-2.1.105/Makefile
--- linux-2.1.105.orig/Makefile	Mon Jun  8 16:44:20 1998
+++ linux-2.1.105/Makefile	Thu Jun 11 23:29:10 1998
@@ -325,17 +325,18 @@
 		echo Installing modules under $$MODLIB/$$2; \
 	}; \
 	\
-	if [ -f BLOCK_MODULES ]; then inst_mod BLOCK_MODULES block; fi; \
-	if [ -f NET_MODULES   ]; then inst_mod NET_MODULES   net;   fi; \
-	if [ -f IPV4_MODULES  ]; then inst_mod IPV4_MODULES  ipv4;  fi; \
-	if [ -f IPV6_MODULES  ]; then inst_mod IPV6_MODULES  ipv6;  fi; \
-	if [ -f SCSI_MODULES  ]; then inst_mod SCSI_MODULES  scsi;  fi; \
-	if [ -f FS_MODULES    ]; then inst_mod FS_MODULES    fs;    fi; \
-	if [ -f NLS_MODULES   ]; then inst_mod NLS_MODULES   fs;    fi; \
-	if [ -f CDROM_MODULES ]; then inst_mod CDROM_MODULES cdrom; fi; \
-	if [ -f VIDEO_MODULES ]; then inst_mod VIDEO_MODULES video; fi; \
-	if [ -f HAM_MODULES   ]; then inst_mod HAM_MODULES   net;   fi; \
-	if [ -f SOUND_MODULES ]; then inst_mod SOUND_MODULES sound; fi; \
+	if [ -f BLOCK_MODULES  ]; then inst_mod BLOCK_MODULES  block;  fi; \
+	if [ -f NET_MODULES    ]; then inst_mod NET_MODULES    net;    fi; \
+	if [ -f IPV4_MODULES   ]; then inst_mod IPV4_MODULES   ipv4;   fi; \
+	if [ -f IPV6_MODULES   ]; then inst_mod IPV6_MODULES   ipv6;   fi; \
+	if [ -f SCSI_MODULES   ]; then inst_mod SCSI_MODULES   scsi;   fi; \
+	if [ -f FS_MODULES     ]; then inst_mod FS_MODULES     fs;     fi; \
+	if [ -f NLS_MODULES    ]; then inst_mod NLS_MODULES    fs;     fi; \
+	if [ -f PARTBL_MODULES ]; then inst_mod PARTBL_MODULES partbl; fi; \
+	if [ -f CDROM_MODULES  ]; then inst_mod CDROM_MODULES  cdrom;  fi; \
+	if [ -f VIDEO_MODULES  ]; then inst_mod VIDEO_MODULES  video;  fi; \
+	if [ -f HAM_MODULES    ]; then inst_mod HAM_MODULES    net;    fi; \
+	if [ -f SOUND_MODULES  ]; then inst_mod SOUND_MODULES  sound;  fi; \
 	\
 	ls *.o > .allmods; \
 	echo $$MODULES | tr ' ' '\n' | sort | comm -23 .allmods - > .misc; \
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/drivers/block/Makefile linux-2.1.105/drivers/block/Makefile
--- linux-2.1.105.orig/drivers/block/Makefile	Mon Jun  8 16:44:30 1998
+++ linux-2.1.105/drivers/block/Makefile	Thu Jun 11 20:41:57 1998
@@ -28,54 +28,6 @@
 
 IDE_OBJS :=
 
-ifeq ($(CONFIG_MSDOS_PARTITION),y)
-  L_OBJS += partbl_msdos.o
-else
-  ifeq ($(CONFIG_MSDOS_PARTITION),m)
-    M_OBJS += partbl_msdos.o
-  endif
-endif
-
-ifeq ($(CONFIG_OSF_PARTITION),y)
-  L_OBJS += partbl_osf.o
-else
-  ifeq ($(CONFIG_OSF_PARTITION),m)
-    M_OBJS += partbl_osf.o
-  endif
-endif
-
-ifeq ($(CONFIG_SUN_PARTITION),y)
-  L_OBJS += partbl_sun.o
-else
-  ifeq ($(CONFIG_SUN_PARTITION),m)
-    M_OBJS += partbl_sun.o
-  endif
-endif
-
-ifeq ($(CONFIG_AMIGA_PARTITION),y)
-  L_OBJS += partbl_amiga.o
-else
-  ifeq ($(CONFIG_AMIGA_PARTITION),m)
-    M_OBJS += partbl_amiga.o
-  endif
-endif
-
-ifeq ($(CONFIG_ATARI_PARTITION),y)
-  L_OBJS += partbl_atari.o
-else
-  ifeq ($(CONFIG_ATARI_PARTITION),m)
-    M_OBJS += partbl_atari.o
-  endif
-endif
-
-ifeq ($(CONFIG_MAC_PARTITION),y)
-  L_OBJS += partbl_mac.o
-else
-  ifeq ($(CONFIG_MAC_PARTITION),m)
-    M_OBJS += partbl_mac.o
-  endif
-endif
-
 ifeq ($(CONFIG_MAC_FLOPPY),y)
 L_OBJS += swim3.o
 endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/drivers/block/genhd.c linux-2.1.105/drivers/block/genhd.c
--- linux-2.1.105.orig/drivers/block/genhd.c	Mon Feb  9 19:19:25 1998
+++ linux-2.1.105/drivers/block/genhd.c	Thu Jun 11 20:27:04 1998
@@ -17,8 +17,8 @@
  *
  *  Check partition table on IDE disks for common CHS translations
  *
- *  Moved partition table parsers into separate files and modularized them
- *  (10/08/97 Roman Hodek)
+ *  Moved partition table parsers to fs/partitions and modularized them
+ *  (10/08/97 Roman Hodek, Russell King)
  */
 
 #include <linux/config.h>
@@ -30,15 +30,16 @@
 #include <linux/string.h>
 #include <linux/blk.h>
 #include <linux/init.h>
-#ifdef CONFIG_PROC_FS
-#include <linux/proc_fs.h>
-#endif
 
 #include <asm/system.h>
 
+/* defined in fs/partitions/check.c */
+extern void partbl_init( void );
+extern void check_partition(struct gendisk *hd, kdev_t dev, int first_minor);
+
+
 struct gendisk *gendisk_head = NULL;
 
-int current_minor = 0;
 extern int *blk_size[];
 extern void rd_load(void);
 extern void initrd_load(void);
@@ -48,362 +49,6 @@
 extern int scsi_dev_init(void);
 extern int net_dev_init(void);
 
-struct partition_parser *partition_parsers = NULL;
-
-/*
- * disk_name() is used by genhd.c and md.c.
- * It formats the devicename of the indicated disk
- * into the supplied buffer, and returns a pointer
- * to that same buffer (for convenience).
- */
-char *disk_name (struct gendisk *hd, int minor, char *buf)
-{
-	unsigned int part;
-	const char *maj = hd->major_name;
-	char unit = (minor >> hd->minor_shift) + 'a';
-
-	/*
-	 * IDE devices use multiple major numbers, but the drives
-	 * are named as:  {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}..
-	 * This requires special handling here.
-	 */
-	switch (hd->major) {
-		case IDE3_MAJOR:
-			unit += 2;
-		case IDE2_MAJOR:
-			unit += 2;
-		case IDE1_MAJOR:
-			unit += 2;
-		case IDE0_MAJOR:
-			maj = "hd";
-	}
-	part = minor & ((1 << hd->minor_shift) - 1);
-	if (part)
-		sprintf(buf, "%s%c%d", maj, unit, part);
-	else
-		sprintf(buf, "%s%c", maj, unit);
-	return buf;
-}
-
-void add_partition (struct gendisk *hd, int minor, int start, int size)
-{
-	char buf[8];
-	hd->part[minor].start_sect = start;
-	hd->part[minor].nr_sects   = size;
-	printk(" %s", disk_name(hd, minor, buf));
-}
-
-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;
-
-}
-
-
-#if CONFIG_KERNELD && CONFIG_FOREIGN_PARTITIONS
-
-#include <linux/kerneld.h>
-
-#ifdef CONFIG_AMIGA_PARTITION_MODULE
-#include <linux/affs_hardblocks.h>
-static int probe_amiga_partition(struct gendisk *hd, kdev_t dev,
-				 struct buffer_head *bh_0)
-{
-	struct buffer_head *bh;
-	int blk, res;
-
-	if (*(u32 *)bh_0->b_data == cpu_to_be32(IDNAME_RIGIDDISK))
-		return 1;
-
-	/* also need to check other possible RDB blocks */
-	for (blk = 1; blk < RDB_ALLOCATION_LIMIT; blk++) {
-		if (!(bh = bread(dev,blk,512)))
-			return -1;
-		res = *(u32 *)bh->b_data == cpu_to_be32(IDNAME_RIGIDDISK);
-		brelse(bh);
-		if (res)
-			return 1;
-	}
-	return 0;
-}
-#endif
-
-#ifdef CONFIG_ATARI_PARTITION_MODULE
-#include <linux/atari_rootsec.h>
-#include <linux/ctype.h>
-#define	VALID_PARTITION(pi,hdsiz)					     \
-    (((pi)->flg & 1) &&							     \
-     isalnum((pi)->id[0]) && isalnum((pi)->id[1]) && isalnum((pi)->id[2]) && \
-     be32_to_cpu((pi)->st) <= (hdsiz) &&				     \
-     be32_to_cpu((pi)->st) + be32_to_cpu((pi)->siz) <= (hdsiz))
-static int probe_atari_partition(struct gendisk *hd, kdev_t dev,
-				 struct buffer_head *bh_0)
-{
-	struct rootsector *rs;
-	u32 hd_size;
-	int res;
-
-	rs = (struct rootsector *)bh_0->b_data;
-	hd_size = hd->part[0].nr_sects;
-	res = VALID_PARTITION( &rs->part[0], hd_size ) ||
-	      VALID_PARTITION( &rs->part[1], hd_size ) ||
-	      VALID_PARTITION( &rs->part[2], hd_size ) ||
-	      VALID_PARTITION( &rs->part[3], hd_size );
-	return res;
-}
-#endif
-
-/*
- * This table lists the magics to recognize the partition formats that are
- * availble as modules. The magics can be stored as 16 or 32 bit little-endian
- * or big-endian numbers. For the more complicated cases (Amiga and Atari), a
- * function doing the real work is called.
- */
-
-enum partbl_probe_type { BE16, BE32, LE16, LE32, FUNC };
-
-static struct partbl_probe {
-	char *name;
-	enum partbl_probe_type type;
-	u32 offset;
-	u32 magic;
-	int (*func)(struct gendisk *hd, kdev_t dev, struct buffer_head *bh_0);
-} partbl_modules[] = {
-#ifdef CONFIG_MSDOS_PARTITION_MODULE
-	{ "msdos", LE16, 510, 0xAA55, NULL },
-#endif
-#ifdef CONFIG_OSF_PARTITION_MODULE
-	{ "osf",   LE32,  64, 0x82564557, NULL },
-#endif
-#ifdef CONFIG_SUN_PARTITION_MODULE
-	{ "sun",   BE16, 508, 0xDABE, NULL },
-#endif
-#ifdef CONFIG_AMIGA_PARTITION_MODULE
-	{ "amiga", FUNC,   0,      0, probe_amiga_partition },
-#endif
-#ifdef CONFIG_ATARI_PARTITION_MODULE
-	{ "atari", FUNC,   0,      0, probe_atari_partition },
-#endif
-#ifdef CONFIG_MAC_PARTITION_MODULE
-	{ "mac",   BE16,   0, 0x4552, NULL },
-#endif
-};
-
-#define N_PARTBL_MODULES sizeof(partbl_modules)/sizeof(*partbl_modules)
-
-/*
- * Try to load all partition parsers that could apply to this device
- */
-static int try_to_load_parser(struct gendisk *hd, kdev_t dev)
-{
-	int i, hit = 0, loaded = 0;
-	char modname[24];
-	struct partbl_probe *mod;
-	struct partition_parser *p;
-	struct buffer_head *bh;
-
-	if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
-		return -1;
-
-	for( i = 0, mod = partbl_modules; i < N_PARTBL_MODULES; ++i, ++mod ) {
-		/* don't probe already loaded formats again */
-		for( p = partition_parsers; p; p = p->next )
-			if (!strcmp( mod->name, p->name))
-				goto skip;
-		
-		switch( mod->type ) {
-		    case LE16:
-			hit = le16_to_cpu(*(u16 *)(bh->b_data+mod->offset)) ==
-			      mod->magic;
-			break;
-		    case LE32:
-			hit = le32_to_cpu(*(u32 *)(bh->b_data+mod->offset)) ==
-			      mod->magic;
-			break;
-		    case BE16:
-			hit = be16_to_cpu(*(u16 *)(bh->b_data+mod->offset)) ==
-			      mod->magic;
-			break;
-		    case BE32:
-			hit = be32_to_cpu(*(u32 *)(bh->b_data+mod->offset)) ==
-			      mod->magic;
-			break;
-		    case FUNC:
-			hit = mod->func(hd, dev, bh) > 0;
-			break;
-		}
-		if (hit) {
-			strcpy(modname, "part-format-");
-			strcat(modname, mod->name);
-			request_module(modname);
-			++loaded;
-		}
-	    skip:
-	}
-	brelse(bh);
-	return loaded;
-}
-
-#endif /* CONFIG_KERNELD && CONFIG_FOREIGN_PARTITIONS */
-
-
-static void check_partition(struct gendisk *hd, kdev_t dev)
-{
-	static int first_time = 1;
-	int tries = 0;
-	unsigned long first_sector;
-	char buf[8];
-	struct partition_parser *parser;
-
-	if (first_time)
-		printk("Partition check:\n");
-	first_time = 0;
-	first_sector = hd->part[MINOR(dev)].start_sect;
-
-	/*
-	 * This is a kludge to allow the partition check to be
-	 * skipped for specific drives (e.g. IDE cd-rom drives)
-	 */
-	if ((int)first_sector == -1) {
-		hd->part[MINOR(dev)].start_sect = 0;
-		return;
-	}
-
-#if CONFIG_KERNELD && CONFIG_FOREIGN_PARTITIONS
-    retry:
-#endif
-	printk(" %s:", disk_name(hd, MINOR(dev), buf));
-	for( parser = partition_parsers; parser; parser = parser->next ) {
-		if (parser->func(hd, dev, first_sector))
-			return;
-	}
-	++tries;
-#if CONFIG_KERNELD && CONFIG_FOREIGN_PARTITIONS
-	if (tries == 1 && try_to_load_parser(hd, dev))
-		goto retry;
-#endif
-	printk(" unknown partition table\n");
-}
-
-int register_partbl( struct partition_parser *parser )
-{
-	struct partition_parser **p;
-    
-	if (!parser)
-		return -EINVAL;
-	if (parser->next)
-		return -EBUSY;
-	for( p = &partition_parsers; *p; p = &(*p)->next )
-		if (*p == parser)
-			return -EBUSY;
-
-	/* Insert new parser at front of list, so that a user-loaded module can
-	 * (in case of some misdetection) override other parsers */
-	parser->next = partition_parsers;
-	partition_parsers = parser;
-	return 0;
-}
-
-#ifdef CONFIG_MODULES
-int unregister_partbl( struct partition_parser *parser )
-{
-	struct partition_parser **p;
-    
-	for( p = &partition_parsers; *p; p = &(*p)->next ) {
-		if (*p == parser) {
-			*p = parser->next;
-			parser->next = NULL;
-			return 0;
-		}
-	}
-	return -EINVAL;
-}
-#endif
-
-#ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *proc_partbl;
-
-static int partbl_read_proc(char *buf, char **start, off_t offset,
-			    int len, int *eof, void *private)
-{
-	struct partition_parser *p;
-
-	len = 0;
-	for( p = partition_parsers; p && len < 4000; p = p->next )
-		len += sprintf(buf + len, "%s\n", p->name );
-	*start = buf + offset;
-	return len > offset ? len - offset : 0;
-}
-#endif
-
-__initfunc(static void partbl_init( void ))
-{
-	extern void msdos_partbl_init(void);
-	extern void osf_partbl_init(void);
-	extern void sun_partbl_init(void);
-	extern void amiga_partbl_init(void);
-	extern void atari_partbl_init(void);
-	extern void mac_partbl_init(void);
-    
-	if (HAVE_MAC_PARTITION)
-		mac_partbl_init();
-	if (HAVE_ATARI_PARTITION)
-		atari_partbl_init();
-	if (HAVE_AMIGA_PARTITION)
-		amiga_partbl_init();
-	if (HAVE_SUN_PARTITION)
-		sun_partbl_init();
-	if (HAVE_OSF_PARTITION)
-		osf_partbl_init();
-	if (HAVE_MSDOS_PARTITION)
-		msdos_partbl_init();
-
-#ifdef CONFIG_PROC_FS
-	proc_partbl = create_proc_entry("partition-formats", 0, 0);
-	if (proc_partbl)
-		proc_partbl->read_proc = partbl_read_proc;
-#endif
-}
 
 /* This function is used to re-read partition tables for removable disks.
    Much of the cleanup from the old partition tables should have already been
@@ -421,8 +66,7 @@
 	int end_minor	= first_minor + dev->max_p;
 
 	blk_size[dev->major] = NULL;
-	current_minor = 1 + first_minor;
-	check_partition(dev, MKDEV(dev->major, first_minor));
+	check_partition(dev, MKDEV(dev->major, first_minor), 1 + first_minor);
 
  	/*
  	 * We need to set the sizes array before we will be able to access
@@ -448,8 +92,7 @@
 	dev->init(dev);	
 	for (drive = 0 ; drive < dev->nr_real ; drive++) {
 		int first_minor	= drive << dev->minor_shift;
-		current_minor = 1 + first_minor;
-		check_partition(dev, MKDEV(dev->major, first_minor));
+		check_partition(dev, MKDEV(dev->major, first_minor), 1 + first_minor);
 	}
 	if (dev->sizes != NULL) {	/* optional safeguard in ll_rw_blk.c */
 		for (i = 0; i < end_minor; i++)
@@ -502,10 +145,3 @@
         md_setup_drive();
 #endif
 }
-
-/* symbols visible for partbl_* modules */
-EXPORT_SYMBOL(add_partition);
-EXPORT_SYMBOL(get_ptable_blocksize);
-EXPORT_SYMBOL(current_minor);
-EXPORT_SYMBOL(register_partbl);
-EXPORT_SYMBOL(unregister_partbl);
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/drivers/block/partbl_amiga.c linux-2.1.105/drivers/block/partbl_amiga.c
--- linux-2.1.105.orig/drivers/block/partbl_amiga.c	Fri Oct 31 18:49:11 1997
+++ linux-2.1.105/drivers/block/partbl_amiga.c	Thu Jan  1 01:00:00 1970
@@ -1,121 +0,0 @@
-/*
- *  partbl_amiga.c -- Amiga RDSK partition table parser
- *
- *  Code extracted from
- *  linux/drivers/block/genhd.c
- *
- */
-
-#include <linux/module.h>
-
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/affs_hardblocks.h>
-#include <asm/byteorder.h>
-
-static __inline__ u32
-checksum_block(u32 *m, int size)
-{
-	u32 sum = 0;
-
-	while (size--)
-		sum += be32_to_cpu(*m++);
-	return sum;
-}
-
-static int
-amiga_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
-{
-	struct buffer_head	*bh;
-	struct RigidDiskBlock	*rdb;
-	struct PartitionBlock	*pb;
-	int			 start_sect;
-	int			 nr_sects;
-	int			 blk;
-	int			 part, res;
-
-	MOD_INC_USE_COUNT;
-	set_blocksize(dev,512);
-	res = 0;
-
-	for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
-		if(!(bh = bread(dev,blk,512))) {
-			printk("Dev %s: unable to read RDB block %d\n",
-			       kdevname(dev),blk);
-			res = -1;
-			goto rdb_done;
-		}
-		if (*(u32 *)bh->b_data == cpu_to_be32(IDNAME_RIGIDDISK)) {
-			rdb = (struct RigidDiskBlock *)bh->b_data;
-			if (checksum_block((u32 *)bh->b_data,be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)) {
-				printk("Dev %s: RDB in block %d has bad checksum\n",
-				       kdevname(dev),blk);
-				brelse(bh);
-				continue;
-			}
-			printk(" RDSK");
-			blk = be32_to_cpu(rdb->rdb_PartitionList);
-			brelse(bh);
-			for (part = 1; blk > 0 && part <= 16; part++) {
-				if (!(bh = bread(dev,blk,512))) {
-					printk("Dev %s: unable to read partition block %d\n",
-						       kdevname(dev),blk);
-					res = -1;
-					goto rdb_done;
-				}
-				pb  = (struct PartitionBlock *)bh->b_data;
-				blk = be32_to_cpu(pb->pb_Next);
-				if (pb->pb_ID == cpu_to_be32(IDNAME_PARTITION) && checksum_block(
-				    (u32 *)pb,be32_to_cpu(pb->pb_SummedLongs) & 0x7F) == 0 ) {
-					
-					/* Tell Kernel about it */
-
-					if (!(nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
-							  be32_to_cpu(pb->pb_Environment[9])) *
-							 be32_to_cpu(pb->pb_Environment[3]) *
-							 be32_to_cpu(pb->pb_Environment[5]))) {
-						continue;
-					}
-					start_sect = be32_to_cpu(pb->pb_Environment[9]) *
-						     be32_to_cpu(pb->pb_Environment[3]) *
-						     be32_to_cpu(pb->pb_Environment[5]);
-					add_partition(hd,current_minor,start_sect,nr_sects);
-					current_minor++;
-					res = 1;
-				}
-				brelse(bh);
-			}
-			printk("\n");
-			break;
-		}
-	}
-
-rdb_done:
-	set_blocksize(dev,BLOCK_SIZE);
-	MOD_DEC_USE_COUNT;
-	return res;
-}
-
-static struct partition_parser amiga_partition_parser =
-    { NULL, "amiga", amiga_partition };
-
-#ifndef MODULE
-__initfunc(void amiga_partbl_init( void ))
-{
-	(void)register_partbl( &amiga_partition_parser );
-}
-#else
-int init_module(void)
-{
-	return register_partbl( &amiga_partition_parser );
-}
-
-void cleanup_module(void)
-{
-	(void)unregister_partbl( &amiga_partition_parser );
-}
-#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/drivers/block/partbl_atari.c linux-2.1.105/drivers/block/partbl_atari.c
--- linux-2.1.105.orig/drivers/block/partbl_atari.c	Tue Jan  6 18:33:03 1998
+++ linux-2.1.105/drivers/block/partbl_atari.c	Thu Jan  1 01:00:00 1970
@@ -1,203 +0,0 @@
-/*
- *  partbl_atari.c -- Atari partition table parser
- *
- *  Code extracted from
- *  linux/drivers/block/genhd.c
- *
- */
-
-#include <linux/module.h>
-
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/init.h>
-#include <linux/atari_rootsec.h>
-#include <asm/byteorder.h>
-
-
-/* ++guenther: this should be settable by the user ("make config")?.
- * roman: doesn't use much code, better always include it :-)
- */
-#define ICD_PARTS
-
-/* check if a partition entry looks valid -- Atari format is assumed if at
- * least one of the primary entries is ok this way */
-#define	VALID_PARTITION(pi,hdsiz)					     \
-    (((pi)->flg & 1) &&							     \
-     isalnum((pi)->id[0]) && isalnum((pi)->id[1]) && isalnum((pi)->id[2]) && \
-     be32_to_cpu((pi)->st) <= (hdsiz) &&				     \
-     be32_to_cpu((pi)->st) + be32_to_cpu((pi)->siz) <= (hdsiz))
-
-static int atari_partition (struct gendisk *hd, kdev_t dev,
-			    unsigned long first_sector)
-{
-  int minor = current_minor, m_lim = current_minor + hd->max_p;
-  int i;
-  struct buffer_head *bh;
-  struct rootsector *rs;
-  struct partition_info *pi;
-  u32 extensect;
-  u32 hd_size;
-#ifdef ICD_PARTS
-  int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
-#endif
-
-  MOD_INC_USE_COUNT;
-  bh = bread (dev, 0, get_ptable_blocksize(dev));
-  if (!bh)
-    {
-      printk (" unable to read block 0\n");
-      MOD_DEC_USE_COUNT;
-      return -1;
-    }
-
-  rs = (struct rootsector *) bh->b_data;
-  hd_size = hd->part[current_minor-1].nr_sects;
-  if (!VALID_PARTITION( &rs->part[0], hd_size ) &&
-      !VALID_PARTITION( &rs->part[1], hd_size ) &&
-      !VALID_PARTITION( &rs->part[2], hd_size ) &&
-      !VALID_PARTITION( &rs->part[3], hd_size )) {
-      /* if there's no valid primary partition, assume that no Atari format
-       * partition table (there's no reliable magic or the like :-() */
-      MOD_DEC_USE_COUNT;
-      return 0;
-  }
-
-  printk (" AHDI");
-  pi = &rs->part[0];
-  for (; pi < &rs->part[4] && minor < m_lim; minor++, pi++)
-    {
-      if (pi->flg & 1)
-	/* active partition */
-	{
-	  if (memcmp (pi->id, "XGM", 3) == 0)
-	    /* extension partition */
-	    {
-	      struct rootsector *xrs;
-	      struct buffer_head *xbh;
-	      u32 partsect;
-
-#ifdef ICD_PARTS
-	      part_fmt = 1;
-#endif
-	      printk(" XGM<");
-	      partsect = extensect = be32_to_cpu(pi->st);
-	      while (1)
-		{
-		  xbh = bread (dev, partsect / 2, 1024);
-		  if (!xbh)
-		    {
-		      printk (" block %u read failed\n", partsect);
-		      brelse(bh);
-		      MOD_DEC_USE_COUNT;
-		      return -1;
-		    }
-		  if (partsect & 1)
-		    xrs = (struct rootsector *) &xbh->b_data[512];
-		  else
-		    xrs = (struct rootsector *) &xbh->b_data[0];
-
-		  /* ++roman: valid bit must be set in one of the first 3
-		   * slots */
-		  for( i = 0; i < 3; ++i )
-		      if (xrs->part[0].flg & 1)
-			  break;
-		  if (i == 3) {
-		    printk( "\nNo valid subpartition in extended "
-			    "partition!\n" );
-		    break;
-		  }
-		  
-		  add_partition(hd, minor,
-				partsect + be32_to_cpu(xrs->part[i].st),
-				be32_to_cpu(xrs->part[i].siz));
-
-		  /* the slot following must be either invalid (end of list)
-		   * or another XGM entry */
-		  if (!(xrs->part[i+1].flg & 1)) {
-		    brelse( xbh );
-		    break;
-		  }
-		  if (memcmp( xrs->part[i+1].id, "XGM", 3 ) != 0) {
-		    printk( "\nLink ID in extended partition is not XGM!\n" );
-		    brelse( xbh );
-		    break;
-		  }
-
-		  partsect = be32_to_cpu(xrs->part[i+1].st) + extensect;
-		  brelse (xbh);
-		  minor++;
-		  if (minor >= m_lim) {
-		    printk( "\nMaximum number of partitions reached!\n" );
-		    break;
-		  }
-		}
-	      printk(" >");
-	    }
-	  else
-	    {
-	      /* we don't care about other id's */
-	      add_partition (hd, minor, be32_to_cpu(pi->st),
-			     be32_to_cpu(pi->siz));
-	    }
-	}
-    }
-#ifdef ICD_PARTS
-  if ( part_fmt!=1 ) /* no extended partitions -> test ICD-format */
-  {
-    pi = &rs->icdpart[0];
-    /* sanity check: no ICD format if first partition invalid */
-    if (memcmp (pi->id, "GEM", 3) == 0 ||
-        memcmp (pi->id, "BGM", 3) == 0 ||
-        memcmp (pi->id, "LNX", 3) == 0 ||
-        memcmp (pi->id, "SWP", 3) == 0 ||
-        memcmp (pi->id, "RAW", 3) == 0 )
-    {
-      printk(" ICD<");
-      for (; pi < &rs->icdpart[8] && minor < m_lim; minor++, pi++)
-      {
-        /* accept only GEM,BGM,RAW,LNX,SWP partitions */
-        if (pi->flg & 1 && 
-            (memcmp (pi->id, "GEM", 3) == 0 ||
-             memcmp (pi->id, "BGM", 3) == 0 ||
-             memcmp (pi->id, "LNX", 3) == 0 ||
-             memcmp (pi->id, "SWP", 3) == 0 ||
-             memcmp (pi->id, "RAW", 3) == 0) )
-        {
-          part_fmt = 2;
-	  add_partition (hd, minor, be32_to_cpu(pi->st), be32_to_cpu(pi->siz));
-        }
-      }
-      printk(" >");
-    }
-  }
-#endif
-  brelse (bh);
-  printk ("\n");
-  MOD_DEC_USE_COUNT;
-  return 1;
-}
-
-static struct partition_parser atari_partition_parser =
-    { NULL, "atari", atari_partition };
-
-#ifndef MODULE
-__initfunc(void atari_partbl_init( void ))
-{
-	(void)register_partbl( &atari_partition_parser );
-}
-#else
-int init_module(void)
-{
-	return register_partbl( &atari_partition_parser );
-}
-
-void cleanup_module(void)
-{
-	(void)unregister_partbl( &atari_partition_parser );
-}
-#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/drivers/block/partbl_mac.c linux-2.1.105/drivers/block/partbl_mac.c
--- linux-2.1.105.orig/drivers/block/partbl_mac.c	Fri Oct 31 18:49:11 1997
+++ linux-2.1.105/drivers/block/partbl_mac.c	Thu Jan  1 01:00:00 1970
@@ -1,170 +0,0 @@
-/*
- *  partbl_mac.c -- Mac partition table parser
- *
- *  Code extracted from
- *  linux/drivers/block/genhd.c
- *
- */
-
-#include <linux/module.h>
-
-#include <linux/config.h>
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/init.h>
-
-
-/*
- * Code to understand MacOS partition tables.
- */
-
-#define MAC_PARTITION_MAGIC	0x504d
-
-/* type field value for A/UX or other Unix partitions */
-#define APPLE_AUX_TYPE	"Apple_UNIX_SVR2"
-
-struct mac_partition {
-	__u16	signature;	/* expected to be MAC_PARTITION_MAGIC */
-	__u16	res1;
-	__u32	map_count;	/* # blocks in partition map */
-	__u32	start_block;	/* absolute starting block # of partition */
-	__u32	block_count;	/* number of blocks in partition */
-	char	name[32];	/* partition name */
-	char	type[32];	/* string type description */
-	__u32	data_start;	/* rel block # of first data block */
-	__u32	data_count;	/* number of data blocks */
-	__u32	status;		/* partition status bits */
-	__u32	boot_start;
-	__u32	boot_size;
-	__u32	boot_load;
-	__u32	boot_load2;
-	__u32	boot_entry;
-	__u32	boot_entry2;
-	__u32	boot_cksum;
-	char	processor[16];	/* identifies ISA of boot */
-	/* there is more stuff after this that we don't need */
-};
-
-#define MAC_STATUS_BOOTABLE	8	/* partition is bootable */
-
-#define MAC_DRIVER_MAGIC	0x4552
-
-/* Driver descriptor structure, in block 0 */
-struct mac_driver_desc {
-	__u16	signature;	/* expected to be MAC_DRIVER_MAGIC */
-	__u16	block_size;
-	__u32	block_count;
-    /* ... more stuff */
-};
-
-static int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec)
-{
-	struct buffer_head *bh;
-	int blk, blocks_in_map;
-	int dev_bsize, dev_pos, pos;
-	unsigned secsize;
-#ifdef CONFIG_PMAC
-	int first_bootable = 1;
-#endif
-	struct mac_partition *part;
-	struct mac_driver_desc *md;
-
-	MOD_INC_USE_COUNT;
-	dev_bsize = get_ptable_blocksize(dev);
-	dev_pos = 0;
-	/* Get 0th block and look at the first partition map entry. */
-	if ((bh = bread(dev, 0, dev_bsize)) == 0) {
-	    printk("%s: error reading partition table\n",
-		   kdevname(dev));
-	    MOD_DEC_USE_COUNT;
-	    return -1;
-	}
-	md = (struct mac_driver_desc *) bh->b_data;
-	if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) {
-		brelse(bh);
-		MOD_DEC_USE_COUNT;
-		return 0;
-	}
-	secsize = be16_to_cpu(md->block_size);
-	if (secsize >= dev_bsize) {
-		brelse(bh);
-		dev_pos = secsize;
-		if ((bh = bread(dev, secsize/dev_bsize, dev_bsize)) == 0) {
-			printk("%s: error reading partition table\n",
-			       kdevname(dev));
-			MOD_DEC_USE_COUNT;
-			return -1;
-		}
-	}
-	part = (struct mac_partition *) (bh->b_data + secsize - dev_pos);
-	if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
-		brelse(bh);
-		MOD_DEC_USE_COUNT;
-		return 0;		/* not a MacOS disk */
-	}
-	printk(" MAC");
-	blocks_in_map = be32_to_cpu(part->map_count);
-	for (blk = 1; blk <= blocks_in_map; ++blk) {
-		pos = blk * secsize;
-		if (pos >= dev_pos + dev_bsize) {
-			brelse(bh);
-			dev_pos = pos;
-			if ((bh = bread(dev, pos/dev_bsize, dev_bsize)) == 0) {
-				printk("%s: error reading partition table\n",
-				       kdevname(dev));
-				MOD_DEC_USE_COUNT;
-				return -1;
-			}
-		}
-		part = (struct mac_partition *) (bh->b_data + pos - dev_pos);
-		if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
-			break;
-		blocks_in_map = be32_to_cpu(part->map_count);
-		add_partition(hd, current_minor,
-			fsec + be32_to_cpu(part->start_block) * (secsize/512),
-			be32_to_cpu(part->block_count) * (secsize/512));
-
-#ifdef CONFIG_PMAC
-		/*
-		 * If this is the first bootable partition, tell the
-		 * setup code, in case it wants to make this the root.
-		 */
-		if (first_bootable
-		    && (be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
-		    && strcasecmp(part->processor, "powerpc") == 0) {
-			note_bootable_part(dev, blk);
-			first_bootable = 0;
-		}
-#endif /* CONFIG_PMAC */
-
-		++current_minor;
-	}
-	brelse(bh);
-	printk("\n");
-	MOD_DEC_USE_COUNT;
-	return 1;
-}
-
-static struct partition_parser mac_partition_parser =
-    { NULL, "mac", mac_partition };
-
-#ifndef MODULE
-__initfunc(void mac_partbl_init( void ))
-{
-	(void)register_partbl( &mac_partition_parser );
-}
-#else
-int init_module(void)
-{
-	return register_partbl( &mac_partition_parser );
-}
-
-void cleanup_module(void)
-{
-	(void)unregister_partbl( &mac_partition_parser );
-}
-#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/drivers/block/partbl_msdos.c linux-2.1.105/drivers/block/partbl_msdos.c
--- linux-2.1.105.orig/drivers/block/partbl_msdos.c	Tue Feb 17 14:57:04 1998
+++ linux-2.1.105/drivers/block/partbl_msdos.c	Thu Jan  1 01:00:00 1970
@@ -1,423 +0,0 @@
-/*
- *  partbl_msdos.c -- MSDOS partition table parser
- *
- *  Code extracted from
- *  linux/drivers/block/genhd.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- *
- *  Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
- *  in the early extended-partition checks and added DM partitions
- *
- *  Support for DiskManager v6.0x added by Mark Lord,
- *  with information provided by OnTrack.  This now works for linux fdisk
- *  and LILO, as well as loadlin and bootln.  Note that disks other than
- *  /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1).
- *
- *  More flexible handling of extended partitions - aeb, 950831
- *
- *  Check partition table on IDE disks for common CHS translations
- */
-
-#include <linux/module.h>
-
-#include <linux/config.h>
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/blk.h>
-#include <linux/init.h>
-
-#include <asm/system.h>
-
-/*
- * Many architectures don't like unaligned accesses, which is
- * frequently the case with the nr_sects and start_sect partition
- * table entries.
- */
-#include <asm/unaligned.h>
-
-#define SYS_IND(p)	(get_unaligned(&p->sys_ind))
-#define NR_SECTS(p)	({ __typeof__(p->nr_sects) __a =	\
-				get_unaligned(&p->nr_sects);	\
-				le32_to_cpu(__a); \
-			})
-
-#define START_SECT(p)	({ __typeof__(p->start_sect) __a =	\
-				get_unaligned(&p->start_sect);	\
-				le32_to_cpu(__a); \
-			})
-
-
-static inline int is_extended_partition(struct partition *p)
-{
-	return (SYS_IND(p) == DOS_EXTENDED_PARTITION ||
-		SYS_IND(p) == WIN98_EXTENDED_PARTITION ||
-		SYS_IND(p) == LINUX_EXTENDED_PARTITION);
-}
-
-/*
- * Create devices for each logical partition in an extended partition.
- * The logical partitions form a linked list, with each entry being
- * a partition table with two entries.  The first entry
- * is the real data partition (with a start relative to the partition
- * table start).  The second is a pointer to the next logical partition
- * (with a start relative to the entire extended partition).
- * We do not create a Linux partition for the partition tables, but
- * only for the actual data partitions.
- */
-
-#define MSDOS_LABEL_MAGIC		0xAA55
-
-static void extended_partition(struct gendisk *hd, kdev_t dev)
-{
-	struct buffer_head *bh;
-	struct partition *p;
-	unsigned long first_sector, first_size, this_sector, this_size;
-	int mask = (1 << hd->minor_shift) - 1;
-	int i;
-
-	first_sector = hd->part[MINOR(dev)].start_sect;
-	first_size = hd->part[MINOR(dev)].nr_sects;
-	this_sector = first_sector;
-
-	while (1) {
-		if ((current_minor & mask) == 0)
-			return;
-		if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
-			return;
-	  /*
-	   * This block is from a device that we're about to stomp on.
-	   * So make sure nobody thinks this block is usable.
-	   */
-		bh->b_state = 0;
-
-		if ((*(unsigned short *) (bh->b_data+510)) != cpu_to_le16(MSDOS_LABEL_MAGIC))
-			goto done;
-
-		p = (struct partition *) (0x1BE + bh->b_data);
-
-		this_size = hd->part[MINOR(dev)].nr_sects;
-
-		/*
-		 * Usually, the first entry is the real data partition,
-		 * the 2nd entry is the next extended partition, or empty,
-		 * and the 3rd and 4th entries are unused.
-		 * However, DRDOS sometimes has the extended partition as
-		 * the first entry (when the data partition is empty),
-		 * and OS/2 seems to use all four entries.
-		 */
-
-		/* 
-		 * First process the data partition(s)
-		 */
-		for (i=0; i<4; i++, p++) {
-		    if (!NR_SECTS(p) || is_extended_partition(p))
-		      continue;
-
-		    /* Check the 3rd and 4th entries -
-		       these sometimes contain random garbage */
-		    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));
-		    current_minor++;
-		    if ((current_minor & mask) == 0)
-		      goto done;
-		}
-		/*
-		 * Next, process the (first) extended partition, if present.
-		 * (So far, there seems to be no reason to make
-		 *  extended_partition()  recursive and allow a tree
-		 *  of extended partitions.)
-		 * It should be a link to the next logical partition.
-		 * Create a minor for this just long enough to get the next
-		 * partition table.  The minor will be reused for the next
-		 * data partition.
-		 */
-		p -= 4;
-		for (i=0; i<4; i++, p++)
-		  if(NR_SECTS(p) && is_extended_partition(p))
-		    break;
-		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);
-		dev = MKDEV(hd->major, current_minor);
-		brelse(bh);
-	}
-done:
-	brelse(bh);
-}
-
-#ifdef CONFIG_SOLARIS_X86_PARTITION
-static void
-solaris_x86_partition(struct gendisk *hd, kdev_t dev, long offset) {
-
-	struct buffer_head *bh;
-	struct solaris_x86_vtoc *v;
-	struct solaris_x86_slice *s;
-	int i;
-
-	if(!(bh = bread(dev, 0, get_ptable_blocksize(dev))))
-		return;
-	v = (struct solaris_x86_vtoc *)(bh->b_data + 512);
-	if(v->v_sanity != cpu_to_le32(SOLARIS_X86_VTOC_SANE)) {
-		brelse(bh);
-		return;
-	}
-	printk(" <solaris:");
-	if(v->v_version != cpu_to_le32(1)) {
-		printk("  cannot handle version %ld vtoc>", le32_to_cpu(v->v_version));
-		brelse(bh);
-		return;
-	}
-	for(i=0; i<SOLARIS_X86_NUMSLICE; i++) {
-		s = &v->v_slice[i];
-
-		if (s->s_tag == 0)
-			continue;
-		printk(" [s%d]", i);
-		/* solaris partitions are relative to current MS-DOS
-		 * one but add_partition starts relative to sector
-		 * zero of the disk.  Therefore, must add the offset
-		 * of the current partition */
-		add_partition(hd, current_minor, le32_to_cpu(s->s_start)+offset,
-					  le32_to_cpu(s->s_size));
-		current_minor++;
-	}
-	brelse(bh);
-	printk(" >");
-}
-#endif
-
-#ifdef CONFIG_BSD_DISKLABEL
-/* 
- * Create devices for BSD partitions listed in a disklabel, under a
- * dos-like partition. See extended_partition() for more information.
- */
-static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev)
-{
-	struct buffer_head *bh;
-	struct bsd_disklabel *l;
-	struct bsd_partition *p;
-	int mask = (1 << hd->minor_shift) - 1;
-
-	if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
-		return;
-	bh->b_state = 0;
-	l = (struct bsd_disklabel *) (bh->b_data+512);
-	if (l->d_magic != cpu_to_le32(BSD_DISKMAGIC)) {
-		brelse(bh);
-		return;
-	}
-
-	p = &l->d_partitions[0];
-	while (p - &l->d_partitions[0] <= BSD_MAXPARTITIONS) {
-		if ((current_minor & mask) >= (4 + hd->max_p))
-			break;
-
-		if (p->p_fstype != BSD_FS_UNUSED) {
-			add_partition(hd, current_minor, le32_to_cpu(p->p_offset),
-						  le32_to_cpu(p->p_size));
-			current_minor++;
-		}
-		p++;
-	}
-	brelse(bh);
-
-}
-#endif
-
-static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
-{
-	int i, minor = current_minor;
-	struct buffer_head *bh;
-	struct partition *p;
-	unsigned char *data;
-	int mask = (1 << hd->minor_shift) - 1;
-#ifdef CONFIG_BLK_DEV_IDE
-	int tested_for_xlate = 0;
-
-	MOD_INC_USE_COUNT;
-read_mbr:
-#endif
-	if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
-		printk(" unable to read partition table\n");
-	    MOD_DEC_USE_COUNT;
-		return -1;
-	}
-	data = bh->b_data;
-	/* In some cases we modify the geometry    */
-	/*  of the drive (below), so ensure that   */
-	/*  nobody else tries to re-use this data. */
-	bh->b_state = 0;
-#ifdef CONFIG_BLK_DEV_IDE
-check_table:
-#endif
-	if (*(unsigned short *)  (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) {
-		brelse(bh);
-	    MOD_DEC_USE_COUNT;
-		return 0;
-	}
-	p = (struct partition *) (0x1be + data);
-
-#ifdef CONFIG_BLK_DEV_IDE
-	if (!tested_for_xlate++) {	/* Do this only once per disk */
-		/*
-		 * Look for various forms of IDE disk geometry translation
-		 */
-		extern int ide_xlate_1024(kdev_t, int, const char *);
-		unsigned int sig = le16_to_cpu(*(unsigned short *)(data + 2));
-		if (SYS_IND(p) == EZD_PARTITION) {
-			/*
-			 * The remainder of the disk must be accessed using
-			 * a translated geometry that reduces the number of 
-			 * apparent cylinders to less than 1024 if possible.
-			 *
-			 * ide_xlate_1024() will take care of the necessary
-			 * adjustments to fool fdisk/LILO and partition check.
-			 */
-			if (ide_xlate_1024(dev, -1, " [EZD]")) {
-				data += 512;
-				goto check_table;
-			}
-		} else if (SYS_IND(p) == DM6_PARTITION) {
-
-			/*
-			 * Everything on the disk is offset by 63 sectors,
-			 * including a "new" MBR with its own partition table,
-			 * and the remainder of the disk must be accessed using
-			 * a translated geometry that reduces the number of 
-			 * apparent cylinders to less than 1024 if possible.
-			 *
-			 * ide_xlate_1024() will take care of the necessary
-			 * adjustments to fool fdisk/LILO and partition check.
-			 */
-			if (ide_xlate_1024(dev, 1, " [DM6:DDO]")) {
-				brelse(bh);
-				goto read_mbr;	/* start over with new MBR */
-			}
-		} else if (sig <= 0x1ae &&
-			   *(unsigned short *)(data + sig) == cpu_to_le16(0x55AA) &&
-			   (1 & *(unsigned char *)(data + sig + 2))) {
-			/* DM6 signature in MBR, courtesy of OnTrack */
-			(void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");
-		} else if (SYS_IND(p) == DM6_AUX1PARTITION || SYS_IND(p) == DM6_AUX3PARTITION) {
-			/*
-			 * DM6 on other than the first (boot) drive
-			 */
-			(void) ide_xlate_1024(dev, 0, " [DM6:AUX]");
-		} else {
-			/*
-			 * Examine the partition table for common translations.
-			 * This is necessary for drives for situations where
-			 * the translated geometry is unavailable from the BIOS.
-			 */
-			for (i = 0; i < 4 ; i++) {
-				struct partition *q = &p[i];
-				if (NR_SECTS(q)
-				   && (q->sector & 63) == 1
-				   && (q->end_sector & 63) == 63) {
-					unsigned int heads = q->end_head + 1;
-					if (heads == 32 || heads == 64 || heads == 128 || heads == 255) {
-
-						(void) ide_xlate_1024(dev, heads, " [PTBL]");
-						break;
-					}
-				}
-			}
-		}
-	}
-#endif	/* CONFIG_BLK_DEV_IDE */
-
-	printk(" DOS");	/* show partition type */
-	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));
-		if (is_extended_partition(p)) {
-			printk(" <");
-			/*
-			 * If we are rereading the partition table, we need
-			 * to set the size of the partition so that we will
-			 * be able to bread the block containing the extended
-			 * partition info.
-			 */
-			hd->sizes[minor] = hd->part[minor].nr_sects 
-			  	>> (BLOCK_SIZE_BITS - 9);
-			extended_partition(hd, MKDEV(hd->major, minor));
-			printk(" >");
-			/* prevent someone doing mkfs or mkswap on an
-			   extended partition, but leave room for LILO */
-			if (hd->part[minor].nr_sects > 2)
-				hd->part[minor].nr_sects = 2;
-		}
-#ifdef CONFIG_BSD_DISKLABEL
-		if (SYS_IND(p) == BSD_PARTITION) {
-			printk(" BSD<");
-			bsd_disklabel_partition(hd, MKDEV(hd->major, minor));
-			printk(" >");
-		}
-#endif
-#ifdef CONFIG_SOLARIS_X86_PARTITION
-
-		/* james@bpgc.com: Solaris has a nasty indicator: 0x82
-		 * which also means linux swap.  For that reason, all
-		 * of the prints are done inside the
-		 * solaris_x86_partition routine */
-
-		if(SYS_IND(p) == SOLARIS_X86_PARTITION) {
-			solaris_x86_partition(hd, MKDEV(hd->major, minor),
-					      first_sector+START_SECT(p));
-		}
-#endif
-	}
-	/*
-	 *  Check for old-style Disk Manager partition table
-	 */
-	if (*(unsigned short *) (data+0xfc) == cpu_to_le16(MSDOS_LABEL_MAGIC)) {
-		p = (struct partition *) (0x1be + data);
-		for (i = 4 ; i < 16 ; i++, current_minor++) {
-			p--;
-			if ((current_minor & mask) == 0)
-				break;
-			if (!(START_SECT(p) && NR_SECTS(p)))
-				continue;
-			add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
-		}
-	}
-	printk("\n");
-	brelse(bh);
-	MOD_DEC_USE_COUNT;
-	return 1;
-}
-
-static struct partition_parser msdos_partition_parser =
-    { NULL, "msdos", msdos_partition };
-
-#ifndef MODULE
-__initfunc(void msdos_partbl_init( void ))
-{
-	(void)register_partbl( &msdos_partition_parser );
-}
-#else
-int init_module(void)
-{
-	return register_partbl( &msdos_partition_parser );
-}
-
-void cleanup_module(void)
-{
-	(void)unregister_partbl( &msdos_partition_parser );
-}
-#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/drivers/block/partbl_osf.c linux-2.1.105/drivers/block/partbl_osf.c
--- linux-2.1.105.orig/drivers/block/partbl_osf.c	Fri Oct 31 18:49:12 1997
+++ linux-2.1.105/drivers/block/partbl_osf.c	Thu Jan  1 01:00:00 1970
@@ -1,117 +0,0 @@
-/*
- *  partbl_osf.c -- partition table parser for OSF partitions (alpha)
- *
- *  Code extracted from
- *  linux/drivers/block/genhd.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-#include <linux/module.h>
-
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/init.h>
-
-
-static int osf_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
-{
-	int i;
-	int mask = (1 << hd->minor_shift) - 1;
-	struct buffer_head *bh;
-	struct disklabel {
-		u32 d_magic;
-		u16 d_type,d_subtype;
-		u8 d_typename[16];
-		u8 d_packname[16];
-		u32 d_secsize;
-		u32 d_nsectors;
-		u32 d_ntracks;
-		u32 d_ncylinders;
-		u32 d_secpercyl;
-		u32 d_secprtunit;
-		u16 d_sparespertrack;
-		u16 d_sparespercyl;
-		u32 d_acylinders;
-		u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
-		u32 d_headswitch, d_trkseek, d_flags;
-		u32 d_drivedata[5];
-		u32 d_spare[5];
-		u32 d_magic2;
-		u16 d_checksum;
-		u16 d_npartitions;
-		u32 d_bbsize, d_sbsize;
-		struct d_partition {
-			u32 p_size;
-			u32 p_offset;
-			u32 p_fsize;
-			u8  p_fstype;
-			u8  p_frag;
-			u16 p_cpg;
-		} d_partitions[8];
-	} * label;
-	struct d_partition * partition;
-#define DISKLABELMAGIC (0x82564557UL)
-
-	MOD_INC_USE_COUNT;
-	if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
-		printk("unable to read partition table\n");
-	    MOD_DEC_USE_COUNT;
-		return -1;
-	}
-	label = (struct disklabel *) (bh->b_data+64);
-	partition = label->d_partitions;
-	if (label->d_magic != cpu_to_le32(DISKLABELMAGIC)) {
-#if 0
-		printk("magic: %08x\n", label->d_magic);
-#endif
-		brelse(bh);
-	    MOD_DEC_USE_COUNT;
-		return 0;
-	}
-	if (label->d_magic2 != cpu_to_le32(DISKLABELMAGIC)) {
-#if 0
-		printk("magic2: %08x\n", label->d_magic2);
-#endif
-		brelse(bh);
-	    MOD_DEC_USE_COUNT;
-		return 0;
-	}
-	printk(" OSF");
-	for (i = 0 ; i < le16_to_cpu(label->d_npartitions); i++, partition++) {
-		if ((current_minor & mask) == 0)
-		        break;
-		if (partition->p_size)
-			add_partition(hd, current_minor,
-				first_sector+le32_to_cpu(partition->p_offset),
-				le32_to_cpu(partition->p_size));
-		current_minor++;
-	}
-	printk("\n");
-	brelse(bh);
-	MOD_DEC_USE_COUNT;
-	return 1;
-}
-
-static struct partition_parser osf_partition_parser =
-    { NULL, "osf",  osf_partition };
-
-#ifndef MODULE
-__initfunc(void osf_partbl_init( void ))
-{
-	(void)register_partbl( &osf_partition_parser );
-}
-#else
-int init_module(void)
-{
-	return register_partbl( &osf_partition_parser );
-}
-
-void cleanup_module(void)
-{
-	(void)unregister_partbl( &osf_partition_parser );
-}
-#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/drivers/block/partbl_sun.c linux-2.1.105/drivers/block/partbl_sun.c
--- linux-2.1.105.orig/drivers/block/partbl_sun.c	Mon Feb  9 19:19:27 1998
+++ linux-2.1.105/drivers/block/partbl_sun.c	Thu Jan  1 01:00:00 1970
@@ -1,113 +0,0 @@
-/*
- *  partbl_sun.c -- Sun partition table parser
- *
- *  Code extracted from
- *  linux/drivers/block/genhd.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-#include <linux/module.h>
-
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/init.h>
-
-
-static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
-{
-	int i, csum;
-	unsigned short *ush;
-	struct buffer_head *bh;
-	struct sun_disklabel {
-		unsigned char info[128];   /* Informative text string */
-		unsigned char spare[292];  /* Boot information etc. */
-		unsigned short rspeed;     /* Disk rotational speed */
-		unsigned short pcylcount;  /* Physical cylinder count */
-		unsigned short sparecyl;   /* extra sects per cylinder */
-		unsigned char spare2[4];   /* More magic... */
-		unsigned short ilfact;     /* Interleave factor */
-		unsigned short ncyl;       /* Data cylinder count */
-		unsigned short nacyl;      /* Alt. cylinder count */
-		unsigned short ntrks;      /* Tracks per cylinder */
-		unsigned short nsect;      /* Sectors per track */
-		unsigned char spare3[4];   /* Even more magic... */
-		struct sun_partition {
-			__u32 start_cylinder;
-			__u32 num_sectors;
-		} partitions[8];
-		unsigned short magic;      /* Magic number */
-		unsigned short csum;       /* Label xor'd checksum */
-	} * label;		
-	struct sun_partition *p;
-	unsigned long spc;
-#define SUN_LABEL_MAGIC          0xDABE
-
-	MOD_INC_USE_COUNT;
-	if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
-		printk("Dev %s: unable to read partition table\n",
-		       kdevname(dev));
-	    MOD_DEC_USE_COUNT;
-		return -1;
-	}
-	label = (struct sun_disklabel *) bh->b_data;
-	p = label->partitions;
-	if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
-		printk("Dev %s Sun disklabel: bad magic %04x\n",
-		       kdevname(dev), be16_to_cpu(label->magic));
-		brelse(bh);
-	    MOD_DEC_USE_COUNT;
-		return 0;
-	}
-	/* Look at the checksum */
-	ush = ((unsigned short *) (label+1)) - 1;
-	for(csum = 0; ush >= ((unsigned short *) label);)
-		csum ^= *ush--;
-	if(csum) {
-		printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
-		       kdevname(dev));
-		brelse(bh);
-	    MOD_DEC_USE_COUNT;
-		return 0;
-	}
-	printk(" UFS");
-	/* All Sun disks have 8 partition entries */
-	spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);
-	for(i=0; i < 8; i++, p++) {
-		unsigned long st_sector;
-		int num_sectors;
-
-		st_sector = first_sector + be32_to_cpu(p->start_cylinder) * spc;
-		num_sectors = be32_to_cpu(p->num_sectors);
-		if (num_sectors)
-			add_partition(hd, current_minor, st_sector, num_sectors);
-		current_minor++;
-	}
-	printk("\n");
-	brelse(bh);
-	MOD_DEC_USE_COUNT;
-	return 1;
-}
-
-static struct partition_parser sun_partition_parser =
-    { NULL, "sun", sun_partition };
-
-#ifndef MODULE
-__initfunc(void sun_partbl_init( void ))
-{
-	(void)register_partbl( &sun_partition_parser );
-}
-#else
-int init_module(void)
-{
-	return register_partbl( &sun_partition_parser );
-}
-
-void cleanup_module(void)
-{
-	(void)unregister_partbl( &sun_partition_parser );
-}
-#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/Config.in linux-2.1.105/fs/Config.in
--- linux-2.1.105.orig/fs/Config.in	Tue Apr  7 12:26:29 1998
+++ linux-2.1.105/fs/Config.in	Thu Jun 11 20:27:04 1998
@@ -65,72 +65,6 @@
 tristate 'Kernel automounter support' CONFIG_AUTOFS_FS
 tristate 'UFS filesystem support (read only)' CONFIG_UFS_FS
 
-comment 'Partition Tables'
-if [ "$ARCH" = "i386" ]; then
-  define_bool CONFIG_MSDOS_PARTITION y
-fi
-if [ "$ARCH" = "alpha" ]; then
-  define_bool CONFIG_OSF_PARTITION y
-fi
-if [ "$ARCH" = "m68k" ]; then
-  if [ "$CONFIG_AMIGA" = "y" ]; then
-    define_bool CONFIG_AMIGA_PARTITION y
-  fi
-  if [ "$CONFIG_ATARI" = "y" ]; then
-    define_bool CONFIG_ATARI_PARTITION y
-  fi
-  if [ "$CONFIG_MAC" = "y" ]; then
-    define_bool CONFIG_MAC_PARTITION y
-  fi
-fi
-if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
-  define_bool CONFIG_SUN_PARTITION y
-fi
-if [ "$ARCH" = "ppc" ]; then
-  if [ "$CONFIG_MACH_SPECIFIC" = "y" ]; then
-    if [ "$CONFIG_PMAC" = "y" -o "$CONFIG_CHRP" = "y" ]; then
-      define_bool CONFIG_MAC_PARTITION y
-    fi
-    if [ "$CONFIG_PREP" = "y" -o "$CONFIG_CHRP" = "y" ]; then
-      define_bool CONFIG_MSDOS_PARTITION y
-    fi
-  else
-    define_bool CONFIG_MAC_PARTITION y
-    define_bool CONFIG_MSDOS_PARTITION y
-  fi
-fi
-
-bool 'Support for foreign partition tables' CONFIG_FOREIGN_PARTITIONS
-if [ "$CONFIG_FOREIGN_PARTITIONS" = "y" ]; then
-  if [ ! \( "$ARCH" = "i386" -o \
-            \( "$ARCH" = "ppc" -a \
-               \( "$CONFIG_MACH_SPECIFIC" = "n" -o "$CONFIG_PREP" = "y" -o \
-                  "$CONFIG_CHRP" = "y" \) \) \) ]; then
-  	tristate 'MS-DOS partition support' CONFIG_MSDOS_PARTITION
-  fi
-  if [ "$ARCH" != "alpha" ]; then
-  	tristate 'OSF partition support' CONFIG_OSF_PARTITION
-  fi
-  if [ "$ARCH" != "sparc" -a "$ARCH" != "sparc64" ]; then
-  	tristate 'Sun partition support' CONFIG_SUN_PARTITION
-  fi
-  if [ "$CONFIG_AMIGA" != "y" ]; then
-  	tristate 'Amiga RDB partition support' CONFIG_AMIGA_PARTITION
-  fi
-  if [ "$CONFIG_ATARI" != "y" ]; then
-  	tristate 'Atari partition support' CONFIG_ATARI_PARTITION
-  fi
-  if [ ! \( \( "$ARCH" = "m68k" -a "$CONFIG_MAC" = "y" \) -o \
-            \( "$ARCH" = "ppc" -a \
-               \( "$CONFIG_MACH_SPECIFIC" = "n" -o "$CONFIG_PMAC" = "y" -o \
-                  "$CONFIG_CHRP" = "y" \) \) \) ]; then
-  	tristate 'Mac partition support' CONFIG_MAC_PARTITION
-  fi
-fi
-if [ "$CONFIG_MSDOS_PARTITION" != "n" ]; then
-  bool 'BSD disklabel (FreeBSD partition tables) support' CONFIG_BSD_DISKLABEL
-  bool 'Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION
-fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
   tristate 'ADFS filesystem support (read only) (EXPERIMENTAL)' CONFIG_ADFS_FS
   tristate '/dev/pts filesystem support (EXPERIMENTAL)' CONFIG_DEVPTS_FS
@@ -138,3 +72,4 @@
 
 endmenu
 
+source fs/partitions/Config.in
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/Makefile linux-2.1.105/fs/Makefile
--- linux-2.1.105.orig/fs/Makefile	Mon May 11 11:42:02 1998
+++ linux-2.1.105/fs/Makefile	Thu Jun 11 21:59:34 1998
@@ -14,11 +14,15 @@
 		super.o  block_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
 		ioctl.o readdir.o select.o fifo.o locks.o filesystems.o \
 		dcache.o inode.o attr.o bad_inode.o $(BINFMTS) 
+OX_OBJS  := partcheck.o
 
 MOD_LIST_NAME := FS_MODULES
 ALL_SUB_DIRS = coda minix ext2 fat msdos vfat proc isofs nfs umsdos ntfs \
 		hpfs sysv smbfs ncpfs ufs affs romfs autofs hfs lockd nfsd \
-		nls devpts adfs
+		nls devpts adfs partitions
+
+SUB_DIRS := partitions
+MOD_IN_SUB_DIRS := partitions
 
 ifeq ($(CONFIG_QUOTA),y)
 O_OBJS += dquot.o
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/partcheck.c linux-2.1.105/fs/partcheck.c
--- linux-2.1.105.orig/fs/partcheck.c	Thu Jan  1 01:00:00 1970
+++ linux-2.1.105/fs/partcheck.c	Fri Jun 12 01:01:35 1998
@@ -0,0 +1,431 @@
+/*
+ *  Code extracted from drivers/block/genhd.c
+ *  Copyright (C) 1991-1998  Linus Torvalds
+ *  Re-organised May 1998 Roman Hodek and Russell King
+ *
+ *  We now have independent partition support from the
+ *  block drivers, which allows all the partition code to
+ *  be grouped in one location, and it to be mostly self
+ *  contained.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/blk.h>
+#include <linux/init.h>
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#endif
+
+#include <asm/system.h>
+#include "partcheck.h"
+
+static struct partition_parser *partition_parsers = NULL;
+
+/*
+ * disk_name() is used by genhd.c and md.c.
+ * It formats the devicename of the indicated disk
+ * into the supplied buffer, and returns a pointer
+ * to that same buffer (for convenience).
+ */
+char *disk_name (struct gendisk *hd, int minor, char *buf)
+{
+	unsigned int part;
+	const char *maj = hd->major_name;
+	char unit = (minor >> hd->minor_shift) + 'a';
+
+	/*
+	 * IDE devices use multiple major numbers, but the drives
+	 * are named as:  {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}..
+	 * This requires special handling here.
+	 */
+	switch (hd->major) {
+		case IDE3_MAJOR:
+			unit += 2;
+		case IDE2_MAJOR:
+			unit += 2;
+		case IDE1_MAJOR:
+			unit += 2;
+		case IDE0_MAJOR:
+			maj = "hd";
+	}
+	part = minor & ((1 << hd->minor_shift) - 1);
+	if (part)
+		sprintf(buf, "%s%c%d", maj, unit, part);
+	else
+		sprintf(buf, "%s%c", maj, unit);
+	return buf;
+}
+
+void add_partition (struct gendisk *hd, int minor, int start, int size)
+{
+	char buf[8];
+	hd->part[minor].start_sect = start;
+	hd->part[minor].nr_sects   = size;
+	printk(" %s", disk_name(hd, minor, buf));
+}
+
+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;
+
+}
+
+
+#if CONFIG_KMOD && CONFIG_FOREIGN_PARTITIONS
+
+#include <linux/kmod.h>
+
+#ifdef CONFIG_AMIGA_PARTITION_MODULE
+#include <linux/affs_hardblocks.h>
+static int probe_amiga_partition(struct gendisk *hd, kdev_t dev,
+				 struct buffer_head *bh_0)
+{
+	struct buffer_head *bh;
+	int blk, res;
+
+	if (*(u32 *)bh_0->b_data == cpu_to_be32(IDNAME_RIGIDDISK))
+		return 1;
+
+	/* also need to check other possible RDB blocks */
+	for (blk = 1; blk < RDB_ALLOCATION_LIMIT; blk++) {
+		if (!(bh = bread(dev,blk,512)))
+			return -1;
+		res = *(u32 *)bh->b_data == cpu_to_be32(IDNAME_RIGIDDISK);
+		brelse(bh);
+		if (res)
+			return 1;
+	}
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_ATARI_PARTITION_MODULE
+#include <linux/atari_rootsec.h>
+#include <linux/ctype.h>
+#define	VALID_PARTITION(pi,hdsiz)					     \
+    (((pi)->flg & 1) &&							     \
+     isalnum((pi)->id[0]) && isalnum((pi)->id[1]) && isalnum((pi)->id[2]) && \
+     be32_to_cpu((pi)->st) <= (hdsiz) &&				     \
+     be32_to_cpu((pi)->st) + be32_to_cpu((pi)->siz) <= (hdsiz))
+static int probe_atari_partition(struct gendisk *hd, kdev_t dev,
+				 struct buffer_head *bh_0)
+{
+	struct rootsector *rs;
+	u32 hd_size;
+	int res;
+
+	rs = (struct rootsector *)bh_0->b_data;
+	hd_size = hd->part[0].nr_sects;
+	res = VALID_PARTITION( &rs->part[0], hd_size ) ||
+	      VALID_PARTITION( &rs->part[1], hd_size ) ||
+	      VALID_PARTITION( &rs->part[2], hd_size ) ||
+	      VALID_PARTITION( &rs->part[3], hd_size );
+	return res;
+}
+#endif
+
+#ifdef CONFIG_ACORN_PARTITION_MODULE
+# ifdef CONFIG_ACORN_PARTITION_ICS
+static int probe_acorn_ICS_partition(struct gendisk *hd, kdev_t dev,
+				     struct buffer_head *bh_0)
+{
+	unsigned long sum;
+	unsigned int i;
+
+	for (i = 0, sum = 0x50617274; i < 508; i++)
+	    sum += bh_0->b_data[i];
+	return sum == le32_to_cpu(*(unsigned long *)(&bh_0->b_data[508]));
+}
+# endif
+# ifdef CONFIG_ACORN_PARTITION_ADFS
+#include <linux/adfs_fs.h>
+static int probe_acorn_ADFS_partition(struct gendisk *hd, kdev_t dev,
+				      struct buffer_head *bh_0)
+{
+	struct buffer_head *bh;
+	int res;
+
+	if (!(bh = bread(dev, 3, 1024)))
+		return -1;
+	res = adfs_checkbblk(bh->b_data) == 0;
+	brelse(bh);
+	return res;
+}
+# endif
+#endif
+
+
+/*
+ * This table lists the magics to recognize the partition formats that are
+ * availble as modules. The magics can be stored as 16 or 32 bit little-endian
+ * or big-endian numbers. For the more complicated cases (Amiga and Atari), a
+ * function doing the real work is called.
+ */
+
+enum partbl_probe_type { BE16, BE32, LE16, LE32, FUNC };
+
+static struct partbl_probe {
+	char *name;
+	enum partbl_probe_type type;
+	u32 offset;
+	u32 magic;
+	int (*func)(struct gendisk *hd, kdev_t dev, struct buffer_head *bh_0);
+} partbl_modules[] = {
+#ifdef CONFIG_MSDOS_PARTITION_MODULE
+	{ "pc", LE16, 510, 0xAA55, NULL },
+#endif
+#ifdef CONFIG_OSF_PARTITION_MODULE
+	{ "osf",   LE32,  64, 0x82564557, NULL },
+#endif
+#ifdef CONFIG_SUN_PARTITION_MODULE
+	{ "sun",   BE16, 508, 0xDABE, NULL },
+#endif
+#ifdef CONFIG_AMIGA_PARTITION_MODULE
+	{ "amiga", FUNC,   0,      0, probe_amiga_partition },
+#endif
+#ifdef CONFIG_ATARI_PARTITION_MODULE
+	{ "atari", FUNC,   0,      0, probe_atari_partition },
+#endif
+#ifdef CONFIG_MAC_PARTITION_MODULE
+	{ "mac",   BE16,   0, 0x4552, NULL },
+#endif
+#ifdef CONFIG_ACORN_PARTITION_MODULE
+# ifdef CONFIG_ACORN_PARTITION_ICS
+	{ "acorn", FUNC,   0,      0, probe_acorn_ICS_partition },
+# endif
+# ifdef CONFIG_ACORN_PARTITION_ADFS
+	{ "acorn", FUNC,   0,      0, probe_acorn_ADFS_partition },
+# endif
+#endif
+};
+
+#define N_PARTBL_MODULES sizeof(partbl_modules)/sizeof(*partbl_modules)
+
+/*
+ * Try to load all partition parsers that could apply to this device
+ */
+static int try_to_load_parser(struct gendisk *hd, kdev_t dev)
+{
+	int i, hit = 0, loaded = 0;
+	char modname[24];
+	struct partbl_probe *mod;
+	struct partition_parser *p;
+	struct buffer_head *bh;
+
+	if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
+		return -1;
+
+	for( i = 0, mod = partbl_modules; i < N_PARTBL_MODULES; ++i, ++mod ) {
+		/* don't probe already loaded formats again */
+		for( p = partition_parsers; p; p = p->next )
+			if (!strcmp( mod->name, p->name))
+				goto skip;
+		
+		switch( mod->type ) {
+		    case LE16:
+			hit = le16_to_cpu(*(u16 *)(bh->b_data+mod->offset)) ==
+			      mod->magic;
+			break;
+		    case LE32:
+			hit = le32_to_cpu(*(u32 *)(bh->b_data+mod->offset)) ==
+			      mod->magic;
+			break;
+		    case BE16:
+			hit = be16_to_cpu(*(u16 *)(bh->b_data+mod->offset)) ==
+			      mod->magic;
+			break;
+		    case BE32:
+			hit = be32_to_cpu(*(u32 *)(bh->b_data+mod->offset)) ==
+			      mod->magic;
+			break;
+		    case FUNC:
+			hit = mod->func(hd, dev, bh) > 0;
+			break;
+		}
+		if (hit) {
+			strcpy(modname, "part-format-");
+			strcat(modname, mod->name);
+			request_module(modname);
+			++loaded;
+		}
+	    skip:
+	}
+	brelse(bh);
+	return loaded;
+}
+
+#endif /* CONFIG_KMOD && CONFIG_FOREIGN_PARTITIONS */
+
+
+void check_partition(struct gendisk *hd, kdev_t dev, int first_minor)
+{
+	static int first_time = 1;
+	int tries = 0;
+	unsigned long first_sector;
+	char buf[8];
+	struct partition_parser *parser;
+
+	if (first_time)
+		printk("Partition check:\n");
+	first_time = 0;
+	first_sector = hd->part[MINOR(dev)].start_sect;
+
+	/*
+	 * This is a kludge to allow the partition check to be
+	 * skipped for specific drives (e.g. IDE cd-rom drives)
+	 */
+	if ((int)first_sector == -1) {
+		hd->part[MINOR(dev)].start_sect = 0;
+		return;
+	}
+
+#if CONFIG_KMOD && CONFIG_FOREIGN_PARTITIONS
+    retry:
+#endif
+	printk(" %s:", disk_name(hd, MINOR(dev), buf));
+	for( parser = partition_parsers; parser; parser = parser->next ) {
+		if (parser->func(hd, dev, first_sector, first_minor))
+			return;
+	}
+	++tries;
+#if CONFIG_KMOD && CONFIG_FOREIGN_PARTITIONS
+	if (tries == 1 && try_to_load_parser(hd, dev))
+		goto retry;
+#endif
+	printk(" unknown partition table\n");
+}
+
+int register_partbl( struct partition_parser *parser )
+{
+	struct partition_parser **p;
+    
+	if (!parser)
+		return -EINVAL;
+	if (parser->next)
+		return -EBUSY;
+	for( p = &partition_parsers; *p; p = &(*p)->next )
+		if (*p == parser)
+			return -EBUSY;
+
+	/* Insert new parser at front of list, so that a user-loaded module can
+	 * (in case of some misdetection) override other parsers */
+	parser->next = partition_parsers;
+	partition_parsers = parser;
+	return 0;
+}
+
+#ifdef CONFIG_MODULES
+int unregister_partbl( struct partition_parser *parser )
+{
+	struct partition_parser **p;
+    
+	for( p = &partition_parsers; *p; p = &(*p)->next ) {
+		if (*p == parser) {
+			*p = parser->next;
+			parser->next = NULL;
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+#endif
+
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry *proc_partbl;
+
+static int partbl_read_proc(char *buf, char **start, off_t offset,
+			    int len, int *eof, void *private)
+{
+	struct partition_parser *p;
+
+	len = 0;
+	for( p = partition_parsers; p && len < 4000; p = p->next )
+		len += sprintf(buf + len, "%s\n", p->name );
+	*start = buf + offset;
+	return len > offset ? len - offset : 0;
+}
+#endif
+
+__initfunc(void partbl_init( void ))
+{
+	extern void msdos_partbl_init(void);
+	extern void osf_partbl_init(void);
+	extern void sun_partbl_init(void);
+	extern void amiga_partbl_init(void);
+	extern void atari_partbl_init(void);
+	extern void mac_partbl_init(void);
+	extern void acorn_partbl_init(void);
+    
+	if (HAVE_ACORN_PARTITION)
+		acorn_partbl_init();
+	if (HAVE_MAC_PARTITION)
+		mac_partbl_init();
+	if (HAVE_ATARI_PARTITION)
+		atari_partbl_init();
+	if (HAVE_AMIGA_PARTITION)
+		amiga_partbl_init();
+	if (HAVE_SUN_PARTITION)
+		sun_partbl_init();
+	if (HAVE_OSF_PARTITION)
+		osf_partbl_init();
+	if (HAVE_MSDOS_PARTITION)
+		msdos_partbl_init();
+
+#ifdef CONFIG_PROC_FS
+	proc_partbl = create_proc_entry("partition-formats", 0, 0);
+	if (proc_partbl)
+		proc_partbl->read_proc = partbl_read_proc;
+#endif
+}
+
+/* symbols visible for modules */
+EXPORT_SYMBOL(add_partition);
+EXPORT_SYMBOL(get_ptable_blocksize);
+EXPORT_SYMBOL(register_partbl);
+EXPORT_SYMBOL(unregister_partbl);
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/partcheck.h linux-2.1.105/fs/partcheck.h
--- linux-2.1.105.orig/fs/partcheck.h	Thu Jan  1 01:00:00 1970
+++ linux-2.1.105/fs/partcheck.h	Thu Jun 11 20:54:59 1998
@@ -0,0 +1,26 @@
+#ifndef _FS_PARTCHECK_H
+#define _FS_PARTCHECK_H
+
+#include <linux/genhd.h>
+
+/*
+ * disk_name() is used by genhd.c and md.c.
+ * It formats the devicename of the indicated disk
+ * into the supplied buffer, and returns a pointer
+ * to that same buffer (for convenience).
+ */
+char *disk_name (struct gendisk *hd, int minor, char *buf);
+void add_partition (struct gendisk *hd, int minor, int start, int size);
+unsigned int get_ptable_blocksize(kdev_t dev);
+
+struct partition_parser {
+	struct partition_parser *next;
+	char *name;
+	int (*func)(struct gendisk *hd, kdev_t dev,
+		    unsigned long first_sector, int first_minor);
+};
+
+int register_partbl( struct partition_parser *parser );
+int unregister_partbl( struct partition_parser *parser );
+
+#endif /* _FS_PARTCHECK_H */
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/partitions/Config.in linux-2.1.105/fs/partitions/Config.in
--- linux-2.1.105.orig/fs/partitions/Config.in	Thu Jan  1 01:00:00 1970
+++ linux-2.1.105/fs/partitions/Config.in	Thu Jun 11 22:35:23 1998
@@ -0,0 +1,88 @@
+#
+# Partition configuration
+#
+mainmenu_option next_comment
+comment 'Partition Tables'
+
+if [ "$ARCH" = "i386" ]; then
+  define_bool CONFIG_MSDOS_PARTITION y
+fi
+if [ "$ARCH" = "alpha" ]; then
+  define_bool CONFIG_OSF_PARTITION y
+fi
+if [ "$ARCH" = "m68k" ]; then
+  if [ "$CONFIG_AMIGA" = "y" ]; then
+    define_bool CONFIG_AMIGA_PARTITION y
+  fi
+  if [ "$CONFIG_ATARI" = "y" ]; then
+    define_bool CONFIG_ATARI_PARTITION y
+  fi
+  if [ "$CONFIG_MAC" = "y" ]; then
+    define_bool CONFIG_MAC_PARTITION y
+  fi
+fi
+if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
+  define_bool CONFIG_SUN_PARTITION y
+fi
+if [ "$ARCH" = "ppc" ]; then
+  if [ "$CONFIG_MACH_SPECIFIC" = "y" ]; then
+    if [ "$CONFIG_PMAC" = "y" -o "$CONFIG_CHRP" = "y" ]; then
+      define_bool CONFIG_MAC_PARTITION y
+    fi
+    if [ "$CONFIG_PREP" = "y" -o "$CONFIG_CHRP" = "y" ]; then
+      define_bool CONFIG_MSDOS_PARTITION y
+    fi
+  else
+    define_bool CONFIG_MAC_PARTITION y
+    define_bool CONFIG_MSDOS_PARTITION y
+  fi
+fi
+if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
+  define_bool CONFIG_ACORN_PARTITION y
+fi
+
+bool 'Support for foreign partition tables' CONFIG_FOREIGN_PARTITIONS
+if [ "$CONFIG_FOREIGN_PARTITIONS" = "y" ]; then
+  if [ ! \( "$ARCH" = "i386" -o \
+            \( "$ARCH" = "ppc" -a \
+               \( "$CONFIG_MACH_SPECIFIC" = "n" -o "$CONFIG_PREP" = "y" -o \
+                  "$CONFIG_CHRP" = "y" \) \) \) ]; then
+  	tristate 'MS-DOS partition support' CONFIG_MSDOS_PARTITION
+  fi
+  if [ "$ARCH" != "alpha" ]; then
+  	tristate 'OSF partition support' CONFIG_OSF_PARTITION
+  fi
+  if [ "$ARCH" != "sparc" -a "$ARCH" != "sparc64" ]; then
+  	tristate 'Sun partition support' CONFIG_SUN_PARTITION
+  fi
+  if [ "$CONFIG_AMIGA" != "y" ]; then
+  	tristate 'Amiga RDB partition support' CONFIG_AMIGA_PARTITION
+  fi
+  if [ "$CONFIG_ATARI" != "y" ]; then
+  	tristate 'Atari partition support' CONFIG_ATARI_PARTITION
+  fi
+  if [ ! \( \( "$ARCH" = "m68k" -a "$CONFIG_MAC" = "y" \) -o \
+            \( "$ARCH" = "ppc" -a \
+               \( "$CONFIG_MACH_SPECIFIC" = "n" -o "$CONFIG_PMAC" = "y" -o \
+                  "$CONFIG_CHRP" = "y" \) \) \) ]; then
+  	tristate 'Mac partition support' CONFIG_MAC_PARTITION
+  fi
+  if [ "$CONFIG_ARCH_ACORN" != "y" ]; then
+    tristate 'Acorn partition support' CONFIG_ACORN_PARTITION
+  fi
+fi
+
+if [ "$CONFIG_MSDOS_PARTITION" != "n" ]; then
+  bool 'BSD disklabel (FreeBSD partition tables) support' CONFIG_BSD_DISKLABEL
+  bool 'Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION
+fi
+
+if [ "$CONFIG_ACORN_PARTITION" != "n" ]; then
+  bool 'Acorn native filecore partition support' CONFIG_ACORN_PARTITION_ADFS
+#  bool 'Acorn Cumana partition support' CONFIG_ACORN_PARTITION_CUMANA
+  bool 'Acorn ICS partition support' CONFIG_ACORN_PARTITION_ICS
+#  bool 'Acorn PowerTec partition support' CONFIG_ACORN_PARTITION_POWERTEC
+  bool 'Acorn RISCiX partition support' CONFIG_ACORN_PARTITION_RISCIX
+fi
+
+endmenu
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/partitions/Makefile linux-2.1.105/fs/partitions/Makefile
--- linux-2.1.105.orig/fs/partitions/Makefile	Thu Jan  1 01:00:00 1970
+++ linux-2.1.105/fs/partitions/Makefile	Thu Jun 11 22:49:41 1998
@@ -0,0 +1,72 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+O_TARGET := partitions.o
+O_OBJS   := 
+M_OBJS   := 
+
+MOD_LIST_NAME := PARTBL_MODULES
+
+ifeq ($(CONFIG_MSDOS_PARTITION),y)
+  O_OBJS += pc.o
+else
+  ifeq ($(CONFIG_MSDOS_PARTITION),m)
+    M_OBJS += pc.o
+  endif
+endif
+
+ifeq ($(CONFIG_OSF_PARTITION),y)
+  O_OBJS += osf.o
+else
+  ifeq ($(CONFIG_OSF_PARTITION),m)
+    M_OBJS += osf.o
+  endif
+endif
+
+ifeq ($(CONFIG_SUN_PARTITION),y)
+  O_OBJS += sun.o
+else
+  ifeq ($(CONFIG_SUN_PARTITION),m)
+    M_OBJS += sun.o
+  endif
+endif
+
+ifeq ($(CONFIG_AMIGA_PARTITION),y)
+  O_OBJS += amiga.o
+else
+  ifeq ($(CONFIG_AMIGA_PARTITION),m)
+    M_OBJS += amiga.o
+  endif
+endif
+
+ifeq ($(CONFIG_ATARI_PARTITION),y)
+  O_OBJS += atari.o
+else
+  ifeq ($(CONFIG_ATARI_PARTITION),m)
+    M_OBJS += atari.o
+  endif
+endif
+
+ifeq ($(CONFIG_MAC_PARTITION),y)
+  O_OBJS += mac.o
+else
+  ifeq ($(CONFIG_MAC_PARTITION),m)
+    M_OBJS += mac.o
+  endif
+endif
+
+ifeq ($(CONFIG_ACORN_PARTITION),y)
+  O_OBJS += acorn.o
+else
+  ifeq ($(CONFIG_ACORN_PARTITION),m)
+    M_OBJS += acorn.o
+  endif
+endif
+
+include $(TOPDIR)/Rules.make
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/partitions/acorn.c linux-2.1.105/fs/partitions/acorn.c
--- linux-2.1.105.orig/fs/partitions/acorn.c	Thu Jan  1 01:00:00 1970
+++ linux-2.1.105/fs/partitions/acorn.c	Fri Jun 12 01:10:42 1998
@@ -0,0 +1,447 @@
+/*
+ * fs/partitions/acorn.c
+ *
+ * Copyright (c) 1996,1997 Russell King.
+ *
+ * Scan ADFS partitions on hard disk drives.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+
+#include "acorn.h"
+#include "../partcheck.h"
+
+static void adfspart_setgeometry (kdev_t dev, unsigned int secspertrack, unsigned int heads, unsigned long totalblocks)
+{
+	extern void hd_set_geometry (kdev_t dev, unsigned char, unsigned char, unsigned long, unsigned int);
+	extern void xd_set_geometry (kdev_t dev, unsigned char, unsigned char, unsigned long, unsigned int);
+
+	switch (MAJOR(dev)) {
+#ifdef CONFIG_BLK_DEV_HD
+	/*
+	 * It would actually look like the HD driver doesn't actually need this,
+	 * since it asks the drive about its the geometry...  However, the 'BIOS'
+	 * information is not updated...
+	 */
+	case HD_MAJOR:
+		hd_set_geometry (dev, secspertrack, heads, totalblocks, 1);
+		break;
+#endif
+#ifdef CONFIG_BLK_DEV_IDE
+#ifndef CONFIG_BLK_DEV_HD
+	case IDE0_MAJOR:
+#endif
+	case IDE1_MAJOR:
+	case IDE2_MAJOR:
+	case IDE3_MAJOR:
+		break;
+#endif
+#ifdef CONFIG_BLK_DEV_XD
+	case XT_DISK_MAJOR:
+		xd_set_geometry (dev, secspertrack, heads, totalblocks, 1);
+		break;
+#endif
+	case SCSI_DISK_MAJOR:
+		/* we don't need to set geometry for SCSI disks */
+		break;
+
+	default:
+		printk ("%s: don't know how to set geometry\n", kdevname (dev));
+		break;
+    }
+}
+
+#define LINUX_NATIVE_MAGIC 0xdeafa1de
+#define LINUX_SWAP_MAGIC   0xdeafab1e
+
+struct linux_part {
+	unsigned long magic;
+	unsigned long start_sect;
+	unsigned long nr_sects;
+};
+
+static struct disc_record *adfs_partition (struct gendisk *hd, char *name, char *data,
+					   unsigned long first_sector, unsigned int minor)
+{
+	struct disc_record *dr;
+	unsigned int nr_sects;
+
+	if (adfs_checkbblk (data))
+		return NULL;
+
+	dr = (struct disc_record *)(data + 0x1c0);
+
+	if (dr->disc_size == 0 && dr->disc_size_high == 0)
+		return NULL;
+
+	nr_sects = (le32_to_cpu(dr->disc_size_high) << 23) |
+		   (le32_to_cpu(dr->disc_size) >> 9);
+
+	if (name)
+		printk (" [%s]", name);
+	add_partition (hd, minor, first_sector, nr_sects);
+	return dr;
+}
+
+#ifdef CONFIG_ACORN_PARTITION_RISCIX
+static int riscix_partition (struct gendisk *hd, kdev_t dev, unsigned long first_sect,
+			     unsigned int minor, unsigned long nr_sects)
+{
+	struct buffer_head *bh;
+	struct riscix_record *rr;
+	unsigned int riscix_minor;
+
+	printk (" [RISCiX]");
+
+	add_partition (hd, riscix_minor = minor++, first_sect, nr_sects);
+	hd->sizes[riscix_minor] = hd->part[riscix_minor].nr_sects >> (BLOCK_SIZE_BITS - 9);
+	dev = MKDEV(hd->major, riscix_minor);
+
+	if (!(bh = bread (dev, 0, 1024)))
+		return -1;
+
+	rr = (struct riscix_record *)bh->b_data;
+	if (rr->magic == cpu_to_le32(RISCIX_MAGIC)) {
+		int part;
+
+		printk (" <");
+
+		for (part = 0; part < 8; part++) {
+			if (rr->part[part].one &&
+			    memcmp (rr->part[part].name, "All\0", 4)) {
+				add_partition (hd, minor++,
+						le32_to_cpu(rr->part[part].start),
+						le32_to_cpu(rr->part[part].length));
+				printk ("(%s)", rr->part[part].name);
+			}
+		}
+
+		printk (" >");
+
+		if (hd->part[riscix_minor].nr_sects > 2)
+			hd->part[riscix_minor].nr_sects = 2;
+	}
+
+	brelse (bh);
+	return minor;
+}
+#endif
+
+static int linux_partition (struct gendisk *hd, kdev_t dev, unsigned long first_sect,
+			    unsigned int minor, unsigned long nr_sects)
+{
+	struct buffer_head *bh;
+	struct linux_part *linuxp;
+	unsigned int linux_minor, mask = (1 << hd->minor_shift) - 1;
+
+	printk (" [Linux]");
+
+	add_partition (hd, linux_minor = minor++, first_sect, nr_sects);
+	hd->sizes[linux_minor] = hd->part[linux_minor].nr_sects >> (BLOCK_SIZE_BITS - 9);
+	dev = MKDEV(hd->major, linux_minor);
+
+	if (!(bh = bread (dev, 0, 1024)))
+		return -1;
+
+	linuxp = (struct linux_part *)bh->b_data;
+	printk (" <");
+	while (linuxp->magic == cpu_to_le32(LINUX_NATIVE_MAGIC) ||
+	       linuxp->magic == cpu_to_le32(LINUX_SWAP_MAGIC)) {
+		if (!(minor & mask))
+			break;
+		add_partition (hd, minor++,
+			       first_sect + le32_to_cpu(linuxp->start_sect),
+			       le32_to_cpu(linuxp->nr_sects));
+		linuxp ++;
+	}
+	printk (" >");
+	/*
+	 * Prevent someone doing a mkswap or mkfs on this partition
+	 */
+	if(hd->part[linux_minor].nr_sects > 2)
+		hd->part[linux_minor].nr_sects = 2;
+
+	brelse(bh);
+	return minor;
+}
+
+#ifdef CONFIG_ACORN_PARTITION_CUMANA
+static int adfspart_check_CUMANA (struct gendisk *hd, kdev_t dev, unsigned long first_sector,
+				  unsigned int minor)
+{
+	unsigned int start_blk = 0, mask = (1 << hd->minor_shift) - 1;
+	struct buffer_head *bh = NULL;
+	char *name = "CUMANA/ADFS";
+	int first = 1;
+
+	/*
+	 * Try Cumana style partitions - sector 3 contains ADFS boot block with pointer
+	 * to next 'drive'.
+	 *
+	 * There are unknowns in this code - is the 'cylinder number' of the next
+	 * partition relative to the start of this one - I'm assuming it is.
+	 *
+	 * Also, which ID did Cumana use?
+	 *
+	 * This is totally unfinished, and will require more work to get it going.
+	 * Hence it is totally untested.
+	 */
+	do {
+		struct disc_record *dr;
+		unsigned int nr_sects;
+
+		if (!(minor & mask))
+			break;
+
+		if (!(bh = bread (dev, start_blk + 3, 1024)))
+			return -1;
+
+		dr = adfs_partition (hd, name, bh->b_data, first_sector, minor++);
+		if (!dr)
+			break;
+		name = NULL;
+
+		nr_sects = (bh->b_data[0x1fd] + (bh->b_data[0x1fe] << 8)) *
+			 (dr->heads + (dr->lowsector & 0x40 ? 1 : 0)) * dr->secspertrack;
+
+		if (!nr_sects)
+			break;
+
+		first = 0;
+		first_sector += nr_sects;
+		start_blk += nr_sects >> (BLOCK_SIZE_BITS - 9);
+		nr_sects = 0; /* hmm - should be partition size */
+
+		switch (bh->b_data[0x1fc] & 15) {
+		case 0: /* No partition / ADFS? */
+			break;
+
+#ifdef CONFIG_ACORN_PARTITION_RISCIX
+		case PARTITION_RISCIX_SCSI: /* RiscIX - we don't know how to find the next one. */
+			minor = riscix_partition (hd, dev, first_sector, minor, nr_sects);
+			break;
+#endif
+
+		case PARTITION_LINUX:
+			minor = linux_partition (hd, dev, first_sector, minor, nr_sects);
+			break;
+		}
+		brelse (bh);
+		bh = NULL;
+		if (minor == -1)
+			return minor;
+	} while (1);
+	if (bh)
+		brelse (bh);
+	return first ? 0 : 1;
+}
+#endif
+
+#ifdef CONFIG_ACORN_PARTITION_ADFS
+/*
+ * Purpose: allocate ADFS partitions.
+ *
+ * Params : hd		- pointer to gendisk structure to store partition info.
+ *	    dev		- device number to access.
+ *	    first_sector- first readable sector on the device.
+ *	    minor	- first available minor on device.
+ *
+ * Returns: -1 on error, 0 for no ADFS boot sector, 1 for ok.
+ *
+ * Alloc  : hda  = whole drive
+ *	    hda1 = ADFS partition on first drive.
+ *	    hda2 = non-ADFS partition.
+ */
+static int adfspart_check_ADFS (struct gendisk *hd, kdev_t dev, unsigned long first_sector,
+				unsigned int minor)
+{
+	unsigned long start_sect, nr_sects, sectscyl, heads;
+	struct buffer_head *bh;
+	struct disc_record *dr;
+
+	if (!(bh = bread (dev, 3, 1024)))
+		return -1;
+
+	dr = adfs_partition (hd, "ADFS", bh->b_data, first_sector, minor++);
+	if (!dr) {
+	    	brelse (bh);
+    		return 0;
+	}
+
+	heads = dr->heads + ((dr->lowsector >> 6) & 1);
+	adfspart_setgeometry (dev, dr->secspertrack, heads, hd->part[MINOR(dev)].nr_sects);
+	sectscyl = dr->secspertrack * heads;
+
+	/*
+	 * Work out start of non-adfs partition.
+	 */
+	start_sect = ((bh->b_data[0x1fe] << 8) + bh->b_data[0x1fd]) * sectscyl;
+	nr_sects = hd->part[MINOR(dev)].nr_sects - start_sect;
+
+	if (start_sect) {
+		first_sector += start_sect;
+		/*
+		 * we now have a problem - how to set the origional disk size if the
+		 * disk doesn't report it, since there is no standard way of getting
+		 * that info.
+		 */
+		switch (bh->b_data[0x1fc] & 15) {
+#ifdef CONFIG_ACORN_PARTITION_RISCIX
+		case PARTITION_RISCIX_SCSI:
+		case PARTITION_RISCIX_MFM:
+			minor = riscix_partition (hd, dev, first_sector, minor, nr_sects);
+			break;
+#endif
+
+		case PARTITION_LINUX:
+			minor = linux_partition (hd, dev, first_sector, minor, nr_sects);
+			break;
+		}
+	}
+	brelse(bh);
+	return 1;
+}
+#endif
+
+#ifdef CONFIG_ACORN_PARTITION_ICS
+static int adfspart_check_ICSLinux (kdev_t dev, unsigned long block)
+{
+	struct buffer_head *bh;
+	int result = 0;
+
+	if ((bh = bread (dev, block >> 1, 1024)) != NULL) {
+		if (memcmp (bh->b_data + ((block & 1) ? 512 : 0),
+			    "LinuxPart", 9) == 0)
+			result = 1;
+
+		brelse (bh);
+	}
+
+	return result;
+}
+
+/*
+ * Purpose: allocate ICS partitions.
+ * Params : hd		- pointer to gendisk structure to store partition info.
+ *	    dev		- device number to access.
+ *	    first_sector- first readable sector on the device.
+ *	    minor	- first available minor on device.
+ * Returns: -1 on error, 0 for no ICS table, 1 for partitions ok.
+ * Alloc  : hda  = whole drive
+ *	    hda1 = ADFS partition 0 on first drive.
+ *	    hda2 = ADFS partition 1 on first drive.
+ *		..etc..
+ */
+static int adfspart_check_ICS (struct gendisk *hd, kdev_t dev, unsigned long first_sector,
+			       unsigned int minor)
+{
+	struct buffer_head *bh;
+	unsigned long sum;
+	unsigned int i, mask = (1 << hd->minor_shift) - 1;
+	struct ics_part { unsigned long start; unsigned long size; } *p;
+
+	/*
+	 * Try ICS style partitions - sector 0 contains partition info.
+	 */
+	if (!(bh = bread (dev, 0, 1024)))
+	    	return -1;
+
+	/*
+	 * check for a valid checksum
+	 */
+	for (i = 0, sum = 0x50617274; i < 508; i++)
+		sum += bh->b_data[i];
+
+	if (sum != le32_to_cpu(*(unsigned long *)(&bh->b_data[508]))) {
+	    	brelse (bh);
+		return 0; /* not ICS partition table */
+	}
+
+	printk (" [ICS]");
+
+	for (p = (struct ics_part *)bh->b_data; p->size; p++) {
+		if ((minor & mask) == 0)
+			break;
+
+		if (p->size < 0 && adfspart_check_ICSLinux (dev, p->start)) {
+			/*
+			 * We use the first sector to identify what type
+			 * this partition is...
+			 */
+			if (p->size > 1)
+				add_partition (hd, minor, first_sector + p->start + 1, p->size - 1);
+		} else
+			add_partition (hd, minor, first_sector + p->start, p->size);
+		minor++;
+	}
+	brelse (bh);
+
+	return 1;
+}
+#endif
+
+/*
+ * Purpose: initialise all the partitions on an ADFS drive.
+ *          These may be other ADFS partitions or a Linux/RiscBSD/RiscIX
+ *	    partition.
+ *
+ * Params : hd		 - pointer to gendisk structure to store devices partitions.
+ *          dev		 - device number to access
+ *	    first_sector - first available sector on the disk.
+ *	    minor	 - first available minor on this device.
+ *
+ * Returns: -1 on error, 0 if not ADFS format, 1 if ok.
+ */
+int acorn_partition(struct gendisk *hd, kdev_t dev,
+		    unsigned long first_sector, int first_part_minor)
+{
+	int r = 0;
+
+	MOD_INC_USE_COUNT;
+#ifdef CONFIG_ACORN_PARTITION_ICS
+	if (r == 0)
+		r = adfspart_check_ICS (hd, dev, first_sector, first_part_minor);
+#endif
+#if 0
+#ifdef CONFIG_ACORN_PARTITION_CUMANA
+	if (r == 0)    
+		r = adfspart_check_CUMANA (hd, dev, first_sector, first_part_minor);
+#endif
+#endif
+#ifdef CONFIG_ACORN_PARTITION_ADFS
+	if (r == 0)
+		r = adfspart_check_ADFS (hd, dev, first_sector, first_part_minor);
+#endif
+	if (r < 0)
+		printk (" unable to read boot sectors / partition sectors\n");
+	else if (r)
+		printk ("\n");
+	MOD_DEC_USE_COUNT;
+	return r;
+}
+
+static struct partition_parser acorn_partition_parser =
+    { NULL, "acorn", acorn_partition };
+
+#ifndef MODULE
+__initfunc(void acorn_partbl_init( void ))
+{
+	(void)register_partbl( &acorn_partition_parser );
+}
+#else
+int init_module(void)
+{
+	return register_partbl( &acorn_partition_parser );
+}
+
+void cleanup_module(void)
+{
+	(void)unregister_partbl( &acorn_partition_parser );
+}
+#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/partitions/acorn.h linux-2.1.105/fs/partitions/acorn.h
--- linux-2.1.105.orig/fs/partitions/acorn.h	Thu Jan  1 01:00:00 1970
+++ linux-2.1.105/fs/partitions/acorn.h	Thu Jun 11 22:00:10 1998
@@ -0,0 +1,68 @@
+/*
+ * fs/partitions/acorn.h
+ *
+ * Copyright (C) 1996-1998 Russell King
+ */
+#include <linux/adfs_fs.h>
+
+/*
+ * Offset in bytes of the boot block on the disk.
+ */
+#define BOOT_SECTOR_ADDRESS 0xc00
+
+/*
+ * Disc record size
+ */
+#define RECSIZE 60
+
+/*
+ * Disc record
+ */
+struct disc_record {
+	unsigned char  log2secsize;
+	unsigned char  secspertrack;
+	unsigned char  heads;
+	unsigned char  density;
+	unsigned char  idlen;
+	unsigned char  log2bpmb;
+	unsigned char  skew;
+	unsigned char  bootoption;
+	unsigned char  lowsector;
+	unsigned char  nzones;
+	unsigned short zone_spare;
+	unsigned long  root;
+	unsigned long  disc_size;
+	unsigned short disc_id;
+	unsigned char  disc_name[10];
+	unsigned long  disc_type;
+	unsigned long  disc_size_high;
+	unsigned char  log2sharesize:4;
+	unsigned char  unused:4;
+	unsigned char  big_flag:1;
+};
+
+/*
+ * Partition types. (Oh for reusability)
+ */
+#define PARTITION_RISCIX_MFM	1
+#define PARTITION_RISCIX_SCSI	2
+#define PARTITION_LINUX		9
+
+struct riscix_part {
+	unsigned long  start;
+	unsigned long  length;
+	unsigned long  one;
+	char name[16];
+};
+
+struct riscix_record {
+	unsigned long  magic;
+#define RISCIX_MAGIC	(0x4a657320)
+	unsigned long  date;
+	struct riscix_part part[8];
+};
+
+int
+acorn_partition(struct gendisk *hd, kdev_t dev,
+		unsigned long first_sector, int first_part_minor);
+
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/partitions/amiga.c linux-2.1.105/fs/partitions/amiga.c
--- linux-2.1.105.orig/fs/partitions/amiga.c	Thu Jan  1 01:00:00 1970
+++ linux-2.1.105/fs/partitions/amiga.c	Fri Jun 12 01:07:09 1998
@@ -0,0 +1,122 @@
+/*
+ *  fs/partitions/amiga.c -- Amiga RDSK partition table parser
+ *
+ *  Code extracted from
+ *  linux/drivers/block/genhd.c
+ *
+ */
+
+#include <linux/module.h>
+
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/affs_hardblocks.h>
+#include <asm/byteorder.h>
+#include "../partcheck.h"
+
+static __inline__ u32
+checksum_block(u32 *m, int size)
+{
+	u32 sum = 0;
+
+	while (size--)
+		sum += be32_to_cpu(*m++);
+	return sum;
+}
+
+static int
+amiga_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector,
+		int current_minor)
+{
+	struct buffer_head	*bh;
+	struct RigidDiskBlock	*rdb;
+	struct PartitionBlock	*pb;
+	int			 start_sect;
+	int			 nr_sects;
+	int			 blk;
+	int			 part, res;
+
+	MOD_INC_USE_COUNT;
+	set_blocksize(dev,512);
+	res = 0;
+
+	for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
+		if(!(bh = bread(dev,blk,512))) {
+			printk("Dev %s: unable to read RDB block %d\n",
+			       kdevname(dev),blk);
+			res = -1;
+			goto rdb_done;
+		}
+		if (*(u32 *)bh->b_data == cpu_to_be32(IDNAME_RIGIDDISK)) {
+			rdb = (struct RigidDiskBlock *)bh->b_data;
+			if (checksum_block((u32 *)bh->b_data,be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)) {
+				printk("Dev %s: RDB in block %d has bad checksum\n",
+				       kdevname(dev),blk);
+				brelse(bh);
+				continue;
+			}
+			printk(" RDSK");
+			blk = be32_to_cpu(rdb->rdb_PartitionList);
+			brelse(bh);
+			for (part = 1; blk > 0 && part <= 16; part++) {
+				if (!(bh = bread(dev,blk,512))) {
+					printk("Dev %s: unable to read partition block %d\n",
+						       kdevname(dev),blk);
+					res = -1;
+					goto rdb_done;
+				}
+				pb  = (struct PartitionBlock *)bh->b_data;
+				blk = be32_to_cpu(pb->pb_Next);
+				if (pb->pb_ID == cpu_to_be32(IDNAME_PARTITION) && checksum_block(
+				    (u32 *)pb,be32_to_cpu(pb->pb_SummedLongs) & 0x7F) == 0 ) {
+					
+					/* Tell Kernel about it */
+
+					if (!(nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
+							  be32_to_cpu(pb->pb_Environment[9])) *
+							 be32_to_cpu(pb->pb_Environment[3]) *
+							 be32_to_cpu(pb->pb_Environment[5]))) {
+						continue;
+					}
+					start_sect = be32_to_cpu(pb->pb_Environment[9]) *
+						     be32_to_cpu(pb->pb_Environment[3]) *
+						     be32_to_cpu(pb->pb_Environment[5]);
+					add_partition(hd,current_minor,start_sect,nr_sects);
+					current_minor++;
+					res = 1;
+				}
+				brelse(bh);
+			}
+			printk("\n");
+			break;
+		}
+	}
+
+rdb_done:
+	set_blocksize(dev,BLOCK_SIZE);
+	MOD_DEC_USE_COUNT;
+	return res;
+}
+
+static struct partition_parser amiga_partition_parser =
+    { NULL, "amiga", amiga_partition };
+
+#ifndef MODULE
+__initfunc(void amiga_partbl_init( void ))
+{
+	(void)register_partbl( &amiga_partition_parser );
+}
+#else
+int init_module(void)
+{
+	return register_partbl( &amiga_partition_parser );
+}
+
+void cleanup_module(void)
+{
+	(void)unregister_partbl( &amiga_partition_parser );
+}
+#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/partitions/atari.c linux-2.1.105/fs/partitions/atari.c
--- linux-2.1.105.orig/fs/partitions/atari.c	Thu Jan  1 01:00:00 1970
+++ linux-2.1.105/fs/partitions/atari.c	Fri Jun 12 01:21:54 1998
@@ -0,0 +1,192 @@
+/*
+ *  fs/partitions/atari.c -- Atari partition table parser
+ *
+ *  Code extracted from
+ *  linux/drivers/block/genhd.c
+ *
+ */
+
+#include <linux/module.h>
+
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/atari_rootsec.h>
+#include <asm/byteorder.h>
+#include "../partcheck.h"
+
+
+/* check if a partition entry looks valid -- Atari format is assumed if at
+ * least one of the primary entries is ok this way */
+#define	VALID_PARTITION(pi,hdsiz)					     \
+    (((pi)->flg & 1) &&							     \
+     isalnum((pi)->id[0]) && isalnum((pi)->id[1]) && isalnum((pi)->id[2]) && \
+     be32_to_cpu((pi)->st) <= (hdsiz) &&				     \
+     be32_to_cpu((pi)->st) + be32_to_cpu((pi)->siz) <= (hdsiz))
+
+static int atari_partition (struct gendisk *hd, kdev_t dev,
+			    unsigned long first_sector, int current_minor)
+{
+  int minor = current_minor, m_lim = current_minor + hd->max_p;
+  int i;
+  struct buffer_head *bh;
+  struct rootsector *rs;
+  struct partition_info *pi;
+  u32 extensect;
+  u32 hd_size;
+  int bsize, bdiv;
+  int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
+
+  MOD_INC_USE_COUNT;
+  bsize = get_ptable_blocksize(dev);
+  bdiv  = bsize / 512;
+  bh = bread (dev, 0, bsize);
+  if (!bh)
+    {
+      printk (" unable to read block 0\n");
+      MOD_DEC_USE_COUNT;
+      return -1;
+    }
+
+  rs = (struct rootsector *) bh->b_data;
+  hd_size = hd->part[current_minor-1].nr_sects;
+  if (!VALID_PARTITION( &rs->part[0], hd_size ) &&
+      !VALID_PARTITION( &rs->part[1], hd_size ) &&
+      !VALID_PARTITION( &rs->part[2], hd_size ) &&
+      !VALID_PARTITION( &rs->part[3], hd_size )) {
+      /* if there's no valid primary partition, assume that no Atari format
+       * partition table (there's no reliable magic or the like :-() */
+      MOD_DEC_USE_COUNT;
+      return 0;
+  }
+
+  printk (" AHDI");
+  pi = &rs->part[0];
+  for (; pi < &rs->part[4] && minor < m_lim; minor++, pi++)
+    {
+      if (pi->flg & 1)
+	/* active partition */
+	{
+	  if (memcmp (pi->id, "XGM", 3) == 0)
+	    /* extension partition */
+	    {
+	      struct rootsector *xrs;
+	      struct buffer_head *xbh;
+	      u32 partsect;
+
+	      part_fmt = 1;
+	      printk(" XGM<");
+	      partsect = extensect = be32_to_cpu(pi->st);
+	      while (1)
+		{
+		  xbh = bread (dev, partsect / bdiv, bsize);
+		  if (!xbh)
+		    {
+		      printk (" block %u read failed\n", partsect);
+		      brelse(bh);
+		      MOD_DEC_USE_COUNT;
+		      return -1;
+		    }
+		  xrs = (struct rootsector *) &xbh->b_data[(partsect%bdiv)*512];
+
+		  /* ++roman: valid bit must be set in one of the first 3
+		   * slots */
+		  for( i = 0; i < 3; ++i )
+		      if (xrs->part[0].flg & 1)
+			  break;
+		  if (i == 3) {
+		    printk( "\nNo valid subpartition in extended "
+			    "partition!\n" );
+		    break;
+		  }
+		  
+		  add_partition(hd, minor,
+				partsect + be32_to_cpu(xrs->part[i].st),
+				be32_to_cpu(xrs->part[i].siz));
+
+		  /* the slot following must be either invalid (end of list)
+		   * or another XGM entry */
+		  if (!(xrs->part[i+1].flg & 1)) {
+		    brelse( xbh );
+		    break;
+		  }
+		  if (memcmp( xrs->part[i+1].id, "XGM", 3 ) != 0) {
+		    printk( "\nLink ID in extended partition is not XGM!\n" );
+		    brelse( xbh );
+		    break;
+		  }
+
+		  partsect = be32_to_cpu(xrs->part[i+1].st) + extensect;
+		  brelse (xbh);
+		  minor++;
+		  if (minor >= m_lim) {
+		    printk( "\nMaximum number of partitions reached!\n" );
+		    break;
+		  }
+		}
+	      printk(" >");
+	    }
+	  else
+	    {
+	      /* we don't care about other id's */
+	      add_partition (hd, minor, be32_to_cpu(pi->st),
+			     be32_to_cpu(pi->siz));
+	    }
+	}
+    }
+  if ( part_fmt!=1 ) /* no extended partitions -> test ICD-format */
+  {
+    pi = &rs->icdpart[0];
+    /* sanity check: no ICD format if first partition invalid */
+    if (memcmp (pi->id, "GEM", 3) == 0 ||
+        memcmp (pi->id, "BGM", 3) == 0 ||
+        memcmp (pi->id, "LNX", 3) == 0 ||
+        memcmp (pi->id, "SWP", 3) == 0 ||
+        memcmp (pi->id, "RAW", 3) == 0 )
+    {
+      printk(" ICD<");
+      for (; pi < &rs->icdpart[8] && minor < m_lim; minor++, pi++)
+      {
+        /* accept only GEM,BGM,RAW,LNX,SWP partitions */
+        if (pi->flg & 1 && 
+            (memcmp (pi->id, "GEM", 3) == 0 ||
+             memcmp (pi->id, "BGM", 3) == 0 ||
+             memcmp (pi->id, "LNX", 3) == 0 ||
+             memcmp (pi->id, "SWP", 3) == 0 ||
+             memcmp (pi->id, "RAW", 3) == 0) )
+        {
+          part_fmt = 2;
+	  add_partition (hd, minor, be32_to_cpu(pi->st), be32_to_cpu(pi->siz));
+        }
+      }
+      printk(" >");
+    }
+  }
+  brelse (bh);
+  printk ("\n");
+  MOD_DEC_USE_COUNT;
+  return 1;
+}
+
+static struct partition_parser atari_partition_parser =
+    { NULL, "atari", atari_partition };
+
+#ifndef MODULE
+__initfunc(void atari_partbl_init( void ))
+{
+	(void)register_partbl( &atari_partition_parser );
+}
+#else
+int init_module(void)
+{
+	return register_partbl( &atari_partition_parser );
+}
+
+void cleanup_module(void)
+{
+	(void)unregister_partbl( &atari_partition_parser );
+}
+#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/partitions/mac.c linux-2.1.105/fs/partitions/mac.c
--- linux-2.1.105.orig/fs/partitions/mac.c	Thu Jan  1 01:00:00 1970
+++ linux-2.1.105/fs/partitions/mac.c	Fri Jun 12 01:07:35 1998
@@ -0,0 +1,171 @@
+/*
+ *  fs/partitions/mac.c -- Mac partition table parser
+ *
+ *  Code extracted from
+ *  linux/drivers/block/genhd.c
+ *
+ */
+
+#include <linux/module.h>
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include "../partcheck.h"
+
+
+/*
+ * Code to understand MacOS partition tables.
+ */
+
+#define MAC_PARTITION_MAGIC	0x504d
+
+/* type field value for A/UX or other Unix partitions */
+#define APPLE_AUX_TYPE	"Apple_UNIX_SVR2"
+
+struct mac_partition {
+	__u16	signature;	/* expected to be MAC_PARTITION_MAGIC */
+	__u16	res1;
+	__u32	map_count;	/* # blocks in partition map */
+	__u32	start_block;	/* absolute starting block # of partition */
+	__u32	block_count;	/* number of blocks in partition */
+	char	name[32];	/* partition name */
+	char	type[32];	/* string type description */
+	__u32	data_start;	/* rel block # of first data block */
+	__u32	data_count;	/* number of data blocks */
+	__u32	status;		/* partition status bits */
+	__u32	boot_start;
+	__u32	boot_size;
+	__u32	boot_load;
+	__u32	boot_load2;
+	__u32	boot_entry;
+	__u32	boot_entry2;
+	__u32	boot_cksum;
+	char	processor[16];	/* identifies ISA of boot */
+	/* there is more stuff after this that we don't need */
+};
+
+#define MAC_STATUS_BOOTABLE	8	/* partition is bootable */
+
+#define MAC_DRIVER_MAGIC	0x4552
+
+/* Driver descriptor structure, in block 0 */
+struct mac_driver_desc {
+	__u16	signature;	/* expected to be MAC_DRIVER_MAGIC */
+	__u16	block_size;
+	__u32	block_count;
+    /* ... more stuff */
+};
+
+static int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec,
+						 int current_minor)
+{
+	struct buffer_head *bh;
+	int blk, blocks_in_map;
+	int dev_bsize, dev_pos, pos;
+	unsigned secsize;
+#ifdef CONFIG_PMAC
+	int first_bootable = 1;
+#endif
+	struct mac_partition *part;
+	struct mac_driver_desc *md;
+
+	MOD_INC_USE_COUNT;
+	dev_bsize = get_ptable_blocksize(dev);
+	dev_pos = 0;
+	/* Get 0th block and look at the first partition map entry. */
+	if ((bh = bread(dev, 0, dev_bsize)) == 0) {
+	    printk("%s: error reading partition table\n",
+		   kdevname(dev));
+	    MOD_DEC_USE_COUNT;
+	    return -1;
+	}
+	md = (struct mac_driver_desc *) bh->b_data;
+	if (be16_to_cpu(md->signature) != MAC_DRIVER_MAGIC) {
+		brelse(bh);
+		MOD_DEC_USE_COUNT;
+		return 0;
+	}
+	secsize = be16_to_cpu(md->block_size);
+	if (secsize >= dev_bsize) {
+		brelse(bh);
+		dev_pos = secsize;
+		if ((bh = bread(dev, secsize/dev_bsize, dev_bsize)) == 0) {
+			printk("%s: error reading partition table\n",
+			       kdevname(dev));
+			MOD_DEC_USE_COUNT;
+			return -1;
+		}
+	}
+	part = (struct mac_partition *) (bh->b_data + secsize - dev_pos);
+	if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
+		brelse(bh);
+		MOD_DEC_USE_COUNT;
+		return 0;		/* not a MacOS disk */
+	}
+	printk(" MAC");
+	blocks_in_map = be32_to_cpu(part->map_count);
+	for (blk = 1; blk <= blocks_in_map; ++blk) {
+		pos = blk * secsize;
+		if (pos >= dev_pos + dev_bsize) {
+			brelse(bh);
+			dev_pos = pos;
+			if ((bh = bread(dev, pos/dev_bsize, dev_bsize)) == 0) {
+				printk("%s: error reading partition table\n",
+				       kdevname(dev));
+				MOD_DEC_USE_COUNT;
+				return -1;
+			}
+		}
+		part = (struct mac_partition *) (bh->b_data + pos - dev_pos);
+		if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC)
+			break;
+		blocks_in_map = be32_to_cpu(part->map_count);
+		add_partition(hd, current_minor,
+			fsec + be32_to_cpu(part->start_block) * (secsize/512),
+			be32_to_cpu(part->block_count) * (secsize/512));
+
+#ifdef CONFIG_PMAC
+		/*
+		 * If this is the first bootable partition, tell the
+		 * setup code, in case it wants to make this the root.
+		 */
+		if (first_bootable
+		    && (be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
+		    && strcasecmp(part->processor, "powerpc") == 0) {
+			note_bootable_part(dev, blk);
+			first_bootable = 0;
+		}
+#endif /* CONFIG_PMAC */
+
+		++current_minor;
+	}
+	brelse(bh);
+	printk("\n");
+	MOD_DEC_USE_COUNT;
+	return 1;
+}
+
+static struct partition_parser mac_partition_parser =
+    { NULL, "mac", mac_partition };
+
+#ifndef MODULE
+__initfunc(void mac_partbl_init( void ))
+{
+	(void)register_partbl( &mac_partition_parser );
+}
+#else
+int init_module(void)
+{
+	return register_partbl( &mac_partition_parser );
+}
+
+void cleanup_module(void)
+{
+	(void)unregister_partbl( &mac_partition_parser );
+}
+#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/partitions/osf.c linux-2.1.105/fs/partitions/osf.c
--- linux-2.1.105.orig/fs/partitions/osf.c	Thu Jan  1 01:00:00 1970
+++ linux-2.1.105/fs/partitions/osf.c	Fri Jun 12 01:12:15 1998
@@ -0,0 +1,117 @@
+/*
+ *  fs/partitions/osf.c -- partition table parser for OSF partitions (alpha)
+ *
+ *  Code extracted from
+ *  linux/drivers/block/genhd.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#include <linux/module.h>
+
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include "../partcheck.h"
+
+
+static int osf_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int current_minor)
+{
+	int i;
+	int mask = (1 << hd->minor_shift) - 1;
+	struct buffer_head *bh;
+	struct disklabel {
+		u32 d_magic;
+		u16 d_type,d_subtype;
+		u8 d_typename[16];
+		u8 d_packname[16];
+		u32 d_secsize;
+		u32 d_nsectors;
+		u32 d_ntracks;
+		u32 d_ncylinders;
+		u32 d_secpercyl;
+		u32 d_secprtunit;
+		u16 d_sparespertrack;
+		u16 d_sparespercyl;
+		u32 d_acylinders;
+		u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
+		u32 d_headswitch, d_trkseek, d_flags;
+		u32 d_drivedata[5];
+		u32 d_spare[5];
+		u32 d_magic2;
+		u16 d_checksum;
+		u16 d_npartitions;
+		u32 d_bbsize, d_sbsize;
+		struct d_partition {
+			u32 p_size;
+			u32 p_offset;
+			u32 p_fsize;
+			u8  p_fstype;
+			u8  p_frag;
+			u16 p_cpg;
+		} d_partitions[8];
+	} * label;
+	struct d_partition * partition;
+#define DISKLABELMAGIC (0x82564557UL)
+
+	MOD_INC_USE_COUNT;
+	if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
+		printk("unable to read partition table\n");
+	    MOD_DEC_USE_COUNT;
+		return -1;
+	}
+	label = (struct disklabel *) (bh->b_data+64);
+	partition = label->d_partitions;
+	if (label->d_magic != cpu_to_le32(DISKLABELMAGIC)) {
+#if 0
+		printk("magic: %08x\n", label->d_magic);
+#endif
+		brelse(bh);
+	    MOD_DEC_USE_COUNT;
+		return 0;
+	}
+	if (label->d_magic2 != cpu_to_le32(DISKLABELMAGIC)) {
+#if 0
+		printk("magic2: %08x\n", label->d_magic2);
+#endif
+		brelse(bh);
+	    MOD_DEC_USE_COUNT;
+		return 0;
+	}
+	printk(" OSF");
+	for (i = 0 ; i < le16_to_cpu(label->d_npartitions); i++, partition++) {
+		if ((current_minor & mask) == 0)
+		        break;
+		if (partition->p_size)
+			add_partition(hd, current_minor,
+				first_sector+le32_to_cpu(partition->p_offset),
+				le32_to_cpu(partition->p_size));
+		current_minor++;
+	}
+	printk("\n");
+	brelse(bh);
+	MOD_DEC_USE_COUNT;
+	return 1;
+}
+
+static struct partition_parser osf_partition_parser =
+    { NULL, "osf",  osf_partition };
+
+#ifndef MODULE
+__initfunc(void osf_partbl_init( void ))
+{
+	(void)register_partbl( &osf_partition_parser );
+}
+#else
+int init_module(void)
+{
+	return register_partbl( &osf_partition_parser );
+}
+
+void cleanup_module(void)
+{
+	(void)unregister_partbl( &osf_partition_parser );
+}
+#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/partitions/pc.c linux-2.1.105/fs/partitions/pc.c
--- linux-2.1.105.orig/fs/partitions/pc.c	Thu Jan  1 01:00:00 1970
+++ linux-2.1.105/fs/partitions/pc.c	Fri Jun 12 01:12:31 1998
@@ -0,0 +1,425 @@
+/*
+ *  fs/partitions/pc.c -- PC (= MSDOS) partition table parser
+ *
+ *  Code extracted from
+ *  linux/drivers/block/genhd.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
+ *  in the early extended-partition checks and added DM partitions
+ *
+ *  Support for DiskManager v6.0x added by Mark Lord,
+ *  with information provided by OnTrack.  This now works for linux fdisk
+ *  and LILO, as well as loadlin and bootln.  Note that disks other than
+ *  /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1).
+ *
+ *  More flexible handling of extended partitions - aeb, 950831
+ *
+ *  Check partition table on IDE disks for common CHS translations
+ */
+
+#include <linux/module.h>
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/blk.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include "../partcheck.h"
+
+static int current_minor;
+
+/*
+ * Many architectures don't like unaligned accesses, which is
+ * frequently the case with the nr_sects and start_sect partition
+ * table entries.
+ */
+#include <asm/unaligned.h>
+
+#define SYS_IND(p)	(get_unaligned(&p->sys_ind))
+#define NR_SECTS(p)	({ __typeof__(p->nr_sects) __a =	\
+				get_unaligned(&p->nr_sects);	\
+				le32_to_cpu(__a); \
+			})
+
+#define START_SECT(p)	({ __typeof__(p->start_sect) __a =	\
+				get_unaligned(&p->start_sect);	\
+				le32_to_cpu(__a); \
+			})
+
+
+static inline int is_extended_partition(struct partition *p)
+{
+	return (SYS_IND(p) == DOS_EXTENDED_PARTITION ||
+		SYS_IND(p) == WIN98_EXTENDED_PARTITION ||
+		SYS_IND(p) == LINUX_EXTENDED_PARTITION);
+}
+
+/*
+ * Create devices for each logical partition in an extended partition.
+ * The logical partitions form a linked list, with each entry being
+ * a partition table with two entries.  The first entry
+ * is the real data partition (with a start relative to the partition
+ * table start).  The second is a pointer to the next logical partition
+ * (with a start relative to the entire extended partition).
+ * We do not create a Linux partition for the partition tables, but
+ * only for the actual data partitions.
+ */
+
+#define MSDOS_LABEL_MAGIC		0xAA55
+
+static void extended_partition(struct gendisk *hd, kdev_t dev)
+{
+	struct buffer_head *bh;
+	struct partition *p;
+	unsigned long first_sector, first_size, this_sector, this_size;
+	int mask = (1 << hd->minor_shift) - 1;
+	int i;
+
+	first_sector = hd->part[MINOR(dev)].start_sect;
+	first_size = hd->part[MINOR(dev)].nr_sects;
+	this_sector = first_sector;
+
+	while (1) {
+		if ((current_minor & mask) == 0)
+			return;
+		if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
+			return;
+	  /*
+	   * This block is from a device that we're about to stomp on.
+	   * So make sure nobody thinks this block is usable.
+	   */
+		bh->b_state = 0;
+
+		if ((*(unsigned short *) (bh->b_data+510)) != cpu_to_le16(MSDOS_LABEL_MAGIC))
+			goto done;
+
+		p = (struct partition *) (0x1BE + bh->b_data);
+
+		this_size = hd->part[MINOR(dev)].nr_sects;
+
+		/*
+		 * Usually, the first entry is the real data partition,
+		 * the 2nd entry is the next extended partition, or empty,
+		 * and the 3rd and 4th entries are unused.
+		 * However, DRDOS sometimes has the extended partition as
+		 * the first entry (when the data partition is empty),
+		 * and OS/2 seems to use all four entries.
+		 */
+
+		/* 
+		 * First process the data partition(s)
+		 */
+		for (i=0; i<4; i++, p++) {
+		    if (!NR_SECTS(p) || is_extended_partition(p))
+		      continue;
+
+		    /* Check the 3rd and 4th entries -
+		       these sometimes contain random garbage */
+		    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));
+		    current_minor++;
+		    if ((current_minor & mask) == 0)
+		      goto done;
+		}
+		/*
+		 * Next, process the (first) extended partition, if present.
+		 * (So far, there seems to be no reason to make
+		 *  extended_partition()  recursive and allow a tree
+		 *  of extended partitions.)
+		 * It should be a link to the next logical partition.
+		 * Create a minor for this just long enough to get the next
+		 * partition table.  The minor will be reused for the next
+		 * data partition.
+		 */
+		p -= 4;
+		for (i=0; i<4; i++, p++)
+		  if(NR_SECTS(p) && is_extended_partition(p))
+		    break;
+		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);
+		dev = MKDEV(hd->major, current_minor);
+		brelse(bh);
+	}
+done:
+	brelse(bh);
+}
+
+#ifdef CONFIG_SOLARIS_X86_PARTITION
+static void
+solaris_x86_partition(struct gendisk *hd, kdev_t dev, long offset) {
+
+	struct buffer_head *bh;
+	struct solaris_x86_vtoc *v;
+	struct solaris_x86_slice *s;
+	int i;
+
+	if(!(bh = bread(dev, 0, get_ptable_blocksize(dev))))
+		return;
+	v = (struct solaris_x86_vtoc *)(bh->b_data + 512);
+	if(v->v_sanity != cpu_to_le32(SOLARIS_X86_VTOC_SANE)) {
+		brelse(bh);
+		return;
+	}
+	printk(" <solaris:");
+	if(v->v_version != cpu_to_le32(1)) {
+		printk("  cannot handle version %d vtoc>", le32_to_cpu(v->v_version));
+		brelse(bh);
+		return;
+	}
+	for(i=0; i<SOLARIS_X86_NUMSLICE; i++) {
+		s = &v->v_slice[i];
+
+		if (s->s_tag == 0)
+			continue;
+		printk(" [s%d]", i);
+		/* solaris partitions are relative to current MS-DOS
+		 * one but add_partition starts relative to sector
+		 * zero of the disk.  Therefore, must add the offset
+		 * of the current partition */
+		add_partition(hd, current_minor, le32_to_cpu(s->s_start)+offset,
+					  le32_to_cpu(s->s_size));
+		current_minor++;
+	}
+	brelse(bh);
+	printk(" >");
+}
+#endif
+
+#ifdef CONFIG_BSD_DISKLABEL
+/* 
+ * Create devices for BSD partitions listed in a disklabel, under a
+ * dos-like partition. See extended_partition() for more information.
+ */
+static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev)
+{
+	struct buffer_head *bh;
+	struct bsd_disklabel *l;
+	struct bsd_partition *p;
+	int mask = (1 << hd->minor_shift) - 1;
+
+	if (!(bh = bread(dev,0,get_ptable_blocksize(dev))))
+		return;
+	bh->b_state = 0;
+	l = (struct bsd_disklabel *) (bh->b_data+512);
+	if (l->d_magic != cpu_to_le32(BSD_DISKMAGIC)) {
+		brelse(bh);
+		return;
+	}
+
+	p = &l->d_partitions[0];
+	while (p - &l->d_partitions[0] <= BSD_MAXPARTITIONS) {
+		if ((current_minor & mask) >= (4 + hd->max_p))
+			break;
+
+		if (p->p_fstype != BSD_FS_UNUSED) {
+			add_partition(hd, current_minor, le32_to_cpu(p->p_offset),
+						  le32_to_cpu(p->p_size));
+			current_minor++;
+		}
+		p++;
+	}
+	brelse(bh);
+
+}
+#endif
+
+static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int first_minor)
+{
+	int i, minor = current_minor = first_minor;
+	struct buffer_head *bh;
+	struct partition *p;
+	unsigned char *data;
+	int mask = (1 << hd->minor_shift) - 1;
+#ifdef CONFIG_BLK_DEV_IDE
+	int tested_for_xlate = 0;
+
+	MOD_INC_USE_COUNT;
+read_mbr:
+#endif
+	if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
+		printk(" unable to read partition table\n");
+	    MOD_DEC_USE_COUNT;
+		return -1;
+	}
+	data = bh->b_data;
+	/* In some cases we modify the geometry    */
+	/*  of the drive (below), so ensure that   */
+	/*  nobody else tries to re-use this data. */
+	bh->b_state = 0;
+#ifdef CONFIG_BLK_DEV_IDE
+check_table:
+#endif
+	if (*(unsigned short *)  (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) {
+		brelse(bh);
+	    MOD_DEC_USE_COUNT;
+		return 0;
+	}
+	p = (struct partition *) (0x1be + data);
+
+#ifdef CONFIG_BLK_DEV_IDE
+	if (!tested_for_xlate++) {	/* Do this only once per disk */
+		/*
+		 * Look for various forms of IDE disk geometry translation
+		 */
+		extern int ide_xlate_1024(kdev_t, int, const char *);
+		unsigned int sig = le16_to_cpu(*(unsigned short *)(data + 2));
+		if (SYS_IND(p) == EZD_PARTITION) {
+			/*
+			 * The remainder of the disk must be accessed using
+			 * a translated geometry that reduces the number of 
+			 * apparent cylinders to less than 1024 if possible.
+			 *
+			 * ide_xlate_1024() will take care of the necessary
+			 * adjustments to fool fdisk/LILO and partition check.
+			 */
+			if (ide_xlate_1024(dev, -1, " [EZD]")) {
+				data += 512;
+				goto check_table;
+			}
+		} else if (SYS_IND(p) == DM6_PARTITION) {
+
+			/*
+			 * Everything on the disk is offset by 63 sectors,
+			 * including a "new" MBR with its own partition table,
+			 * and the remainder of the disk must be accessed using
+			 * a translated geometry that reduces the number of 
+			 * apparent cylinders to less than 1024 if possible.
+			 *
+			 * ide_xlate_1024() will take care of the necessary
+			 * adjustments to fool fdisk/LILO and partition check.
+			 */
+			if (ide_xlate_1024(dev, 1, " [DM6:DDO]")) {
+				brelse(bh);
+				goto read_mbr;	/* start over with new MBR */
+			}
+		} else if (sig <= 0x1ae &&
+			   *(unsigned short *)(data + sig) == cpu_to_le16(0x55AA) &&
+			   (1 & *(unsigned char *)(data + sig + 2))) {
+			/* DM6 signature in MBR, courtesy of OnTrack */
+			(void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");
+		} else if (SYS_IND(p) == DM6_AUX1PARTITION || SYS_IND(p) == DM6_AUX3PARTITION) {
+			/*
+			 * DM6 on other than the first (boot) drive
+			 */
+			(void) ide_xlate_1024(dev, 0, " [DM6:AUX]");
+		} else {
+			/*
+			 * Examine the partition table for common translations.
+			 * This is necessary for drives for situations where
+			 * the translated geometry is unavailable from the BIOS.
+			 */
+			for (i = 0; i < 4 ; i++) {
+				struct partition *q = &p[i];
+				if (NR_SECTS(q)
+				   && (q->sector & 63) == 1
+				   && (q->end_sector & 63) == 63) {
+					unsigned int heads = q->end_head + 1;
+					if (heads == 32 || heads == 64 || heads == 128 || heads == 255) {
+
+						(void) ide_xlate_1024(dev, heads, " [PTBL]");
+						break;
+					}
+				}
+			}
+		}
+	}
+#endif	/* CONFIG_BLK_DEV_IDE */
+
+	printk(" PC");	/* show partition type */
+	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));
+		if (is_extended_partition(p)) {
+			printk(" <");
+			/*
+			 * If we are rereading the partition table, we need
+			 * to set the size of the partition so that we will
+			 * be able to bread the block containing the extended
+			 * partition info.
+			 */
+			hd->sizes[minor] = hd->part[minor].nr_sects 
+			  	>> (BLOCK_SIZE_BITS - 9);
+			extended_partition(hd, MKDEV(hd->major, minor));
+			printk(" >");
+			/* prevent someone doing mkfs or mkswap on an
+			   extended partition, but leave room for LILO */
+			if (hd->part[minor].nr_sects > 2)
+				hd->part[minor].nr_sects = 2;
+		}
+#ifdef CONFIG_BSD_DISKLABEL
+		if (SYS_IND(p) == BSD_PARTITION) {
+			printk(" BSD<");
+			bsd_disklabel_partition(hd, MKDEV(hd->major, minor));
+			printk(" >");
+		}
+#endif
+#ifdef CONFIG_SOLARIS_X86_PARTITION
+
+		/* james@bpgc.com: Solaris has a nasty indicator: 0x82
+		 * which also means linux swap.  For that reason, all
+		 * of the prints are done inside the
+		 * solaris_x86_partition routine */
+
+		if(SYS_IND(p) == SOLARIS_X86_PARTITION) {
+			solaris_x86_partition(hd, MKDEV(hd->major, minor),
+					      first_sector+START_SECT(p));
+		}
+#endif
+	}
+	/*
+	 *  Check for old-style Disk Manager partition table
+	 */
+	if (*(unsigned short *) (data+0xfc) == cpu_to_le16(MSDOS_LABEL_MAGIC)) {
+		p = (struct partition *) (0x1be + data);
+		for (i = 4 ; i < 16 ; i++, current_minor++) {
+			p--;
+			if ((current_minor & mask) == 0)
+				break;
+			if (!(START_SECT(p) && NR_SECTS(p)))
+				continue;
+			add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
+		}
+	}
+	printk("\n");
+	brelse(bh);
+	MOD_DEC_USE_COUNT;
+	return 1;
+}
+
+static struct partition_parser msdos_partition_parser =
+    { NULL, "msdos", msdos_partition };
+
+#ifndef MODULE
+__initfunc(void msdos_partbl_init( void ))
+{
+	(void)register_partbl( &msdos_partition_parser );
+}
+#else
+int init_module(void)
+{
+	return register_partbl( &msdos_partition_parser );
+}
+
+void cleanup_module(void)
+{
+	(void)unregister_partbl( &msdos_partition_parser );
+}
+#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/fs/partitions/sun.c linux-2.1.105/fs/partitions/sun.c
--- linux-2.1.105.orig/fs/partitions/sun.c	Thu Jan  1 01:00:00 1970
+++ linux-2.1.105/fs/partitions/sun.c	Fri Jun 12 01:12:20 1998
@@ -0,0 +1,113 @@
+/*
+ *  fs/partitions/sun.c -- Sun partition table parser
+ *
+ *  Code extracted from
+ *  linux/drivers/block/genhd.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#include <linux/module.h>
+
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include "../partcheck.h"
+
+
+static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int current_minor)
+{
+	int i, csum;
+	unsigned short *ush;
+	struct buffer_head *bh;
+	struct sun_disklabel {
+		unsigned char info[128];   /* Informative text string */
+		unsigned char spare[292];  /* Boot information etc. */
+		unsigned short rspeed;     /* Disk rotational speed */
+		unsigned short pcylcount;  /* Physical cylinder count */
+		unsigned short sparecyl;   /* extra sects per cylinder */
+		unsigned char spare2[4];   /* More magic... */
+		unsigned short ilfact;     /* Interleave factor */
+		unsigned short ncyl;       /* Data cylinder count */
+		unsigned short nacyl;      /* Alt. cylinder count */
+		unsigned short ntrks;      /* Tracks per cylinder */
+		unsigned short nsect;      /* Sectors per track */
+		unsigned char spare3[4];   /* Even more magic... */
+		struct sun_partition {
+			__u32 start_cylinder;
+			__u32 num_sectors;
+		} partitions[8];
+		unsigned short magic;      /* Magic number */
+		unsigned short csum;       /* Label xor'd checksum */
+	} * label;		
+	struct sun_partition *p;
+	unsigned long spc;
+#define SUN_LABEL_MAGIC          0xDABE
+
+	MOD_INC_USE_COUNT;
+	if(!(bh = bread(dev, 0, get_ptable_blocksize(dev)))) {
+		printk("Dev %s: unable to read partition table\n",
+		       kdevname(dev));
+	    MOD_DEC_USE_COUNT;
+		return -1;
+	}
+	label = (struct sun_disklabel *) bh->b_data;
+	p = label->partitions;
+	if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
+		printk("Dev %s Sun disklabel: bad magic %04x\n",
+		       kdevname(dev), be16_to_cpu(label->magic));
+		brelse(bh);
+	    MOD_DEC_USE_COUNT;
+		return 0;
+	}
+	/* Look at the checksum */
+	ush = ((unsigned short *) (label+1)) - 1;
+	for(csum = 0; ush >= ((unsigned short *) label);)
+		csum ^= *ush--;
+	if(csum) {
+		printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
+		       kdevname(dev));
+		brelse(bh);
+	    MOD_DEC_USE_COUNT;
+		return 0;
+	}
+	printk(" UFS");
+	/* All Sun disks have 8 partition entries */
+	spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);
+	for(i=0; i < 8; i++, p++) {
+		unsigned long st_sector;
+		int num_sectors;
+
+		st_sector = first_sector + be32_to_cpu(p->start_cylinder) * spc;
+		num_sectors = be32_to_cpu(p->num_sectors);
+		if (num_sectors)
+			add_partition(hd, current_minor, st_sector, num_sectors);
+		current_minor++;
+	}
+	printk("\n");
+	brelse(bh);
+	MOD_DEC_USE_COUNT;
+	return 1;
+}
+
+static struct partition_parser sun_partition_parser =
+    { NULL, "sun", sun_partition };
+
+#ifndef MODULE
+__initfunc(void sun_partbl_init( void ))
+{
+	(void)register_partbl( &sun_partition_parser );
+}
+#else
+int init_module(void)
+{
+	return register_partbl( &sun_partition_parser );
+}
+
+void cleanup_module(void)
+{
+	(void)unregister_partbl( &sun_partition_parser );
+}
+#endif
diff -u --recursive --exclude-from=diff-excludes --new-file linux-2.1.105.orig/include/linux/genhd.h linux-2.1.105/include/linux/genhd.h
--- linux-2.1.105.orig/include/linux/genhd.h	Mon Jan 12 10:05:16 1998
+++ linux-2.1.105/include/linux/genhd.h	Thu Jun 11 20:38:13 1998
@@ -48,6 +48,12 @@
 # define HAVE_MAC_PARTITION 0
 #endif
 
+#ifdef CONFIG_ACORN_PARTITION
+# define HAVE_ACORN_PARTITION 1
+#else
+# define HAVE_ACORN_PARTITION 0
+#endif
+
 /* These three have identical behaviour; use the second one if DOS fdisk gets
    confused about extended/logical partitions starting past cylinder 1023. */
 #define DOS_EXTENDED_PARTITION 5
@@ -183,26 +189,5 @@
 #endif	/* CONFIG_BSD_DISKLABEL */
 
 extern struct gendisk *gendisk_head;	/* linked list of disks */
-
-/*
- * disk_name() is used by genhd.c and md.c.
- * It formats the devicename of the indicated disk
- * into the supplied buffer, and returns a pointer
- * to that same buffer (for convenience).
- */
-char *disk_name (struct gendisk *hd, int minor, char *buf);
-void add_partition (struct gendisk *hd, int minor, int start, int size);
-unsigned int get_ptable_blocksize(kdev_t dev);
-extern int current_minor;
-
-struct partition_parser {
-	struct partition_parser *next;
-	char *name;
-	int (*func)(struct gendisk *hd, kdev_t dev,
-		    unsigned long first_sector);
-};
-
-int register_partbl( struct partition_parser *parser );
-int unregister_partbl( struct partition_parser *parser );
 
 #endif
