Resent-Date: Mon, 16 Aug 1999 10:53:13 +0200 (MET DST)
Date: Mon, 16 Aug 1999 10:52:57 +0200 (MET DST)
From: Roman Zippel <zippel@fh-brandenburg.de>
X-Sender: zippel@zeus
To: Linux/m68k <linux-m68k@lists.linux-m68k.org>
Subject: partition table update and some misc patches
Resent-From: linux-m68k@phil.uni-sb.de

Hi,

2.3.13 doesn't work for me, does it work for anyone else on an Amiga
beside of Jes?
Anyway first some misc patches, e.g. it does reintroduce Andreas'
optimization of vmlinux.lds to save some space. The rest are more or less 
some minor cleanups.
Then I did rework the partitation table stuff a bit (I tested this with a
slightly older kernel and then dropped it into Jes' release). Now the scan
is always done in a fixed order, so one problem to integrate this into the
main kernel is gone :). Anyway, it's not yet the final version. First, I
get some warnings when I'm trying to include some other partition types,
that I currently don't how to resolve (I'm happy about any hint :) ).
Second, does anyone knows why get_ptable_blocksize() returns a blocksize
of at least 1024 bytes? I had some problems with this as I'm setting the
blocksize to a smaller value for partition table scan and then bread()
fails if used with get_ptable_blocksize(). I changed this function as it's
used only by the partition table code anyway.

bye, Roman


>>>>> misc stuff <<<<<

diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/arch/m68k/mm/init.c linux-test/arch/m68k/mm/init.c
--- linux-2.3.13/arch/m68k/mm/init.c	Tue Aug 10 20:14:46 1999
+++ linux-test/arch/m68k/mm/init.c	Sun Aug 15 23:15:19 1999
@@ -391,13 +391,10 @@
 			clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
 		if (PageReserved(mem_map+MAP_NR(tmp))) {
 			if (tmp >= (unsigned long)&_text
-			    && tmp < (unsigned long)&_edata) {
-				if (tmp < (unsigned long) &_etext)
-					codepages++;
-				else
-					datapages++;
-			} else if (tmp >= (unsigned long) &__init_begin
-				   && tmp < (unsigned long) &__init_end)
+			    && tmp < (unsigned long)&_etext)
+				codepages++;
+			else if (tmp >= (unsigned long) &__init_begin
+				 && tmp < (unsigned long) &__init_end)
 				initpages++;
 			else
 				datapages++;
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/arch/m68k/vmlinux.lds linux-test/arch/m68k/vmlinux.lds
--- linux-2.3.13/arch/m68k/vmlinux.lds	Tue Aug 10 20:14:27 1999
+++ linux-test/arch/m68k/vmlinux.lds	Sun Aug 15 23:15:19 1999
@@ -31,10 +31,12 @@
 	CONSTRUCTORS
 	}
 
-  _edata = .;			/* End of data section */
+  .bss : { *(.bss) }		/* BSS */
 
-  . = ALIGN(8192);
-  init_task : { *(init_task) }
+  . = ALIGN(16);
+  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+
+  _edata = .;			/* End of data section */
 
   . = ALIGN(4096);		/* Init code and data */
   __init_begin = .;
@@ -50,13 +52,8 @@
   . = ALIGN(8192);
   __init_end = .;
 
-  . = ALIGN(16);
-  .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+  init_task : { *(init_task) }	/* The initial task and kernel stack */
 
-  __bss_start = .;		/* BSS */
-  .bss : {
-	*(.bss)
-	}
   _end = . ;
 
   /* Stabs debugging sections.  */
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/drivers/block/Makefile linux-test/drivers/block/Makefile
--- linux-2.3.13/drivers/block/Makefile	Sat Aug 14 00:02:27 1999
+++ linux-test/drivers/block/Makefile	Sun Aug 15 23:15:19 1999
@@ -162,6 +162,8 @@
 # IDE-STUFF
 #
 
+IDE_OBJS :=
+
 ifeq ($(CONFIG_BLK_DEV_AEC6210),y)
 IDE_OBJS += aec6210.o
 endif
@@ -200,6 +202,10 @@
 
 ifeq ($(CONFIG_BLK_DEV_GAYLE),y)
 IDE_OBJS += gayle.o
+endif
+
+ifeq ($(CONFIG_BLK_DEV_Q40IDE),y)
+IDE_OBJS += q40ide.o
 endif
 
 ifeq ($(CONFIG_BLK_DEV_HD),y)
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/drivers/parport/parport_amiga.c linux-test/drivers/parport/parport_amiga.c
--- linux-2.3.13/drivers/parport/parport_amiga.c	Tue Aug 10 20:23:02 1999
+++ linux-test/drivers/parport/parport_amiga.c	Sun Aug 15 23:15:26 1999
@@ -64,8 +64,8 @@
 {
 	return PARPORT_CONTROL_SELECT |
 	      PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_STROBE;
-	/* fake value: interrupt enable, select in, no reset,
-	no autolf, no strobe - seems to be closest the wiring diagram */
+	/* fake value: select in, no reset, no autolf, no strobe - 
+	   seems to be closest the wiring diagram */
 }
 
 static void amiga_write_control(struct parport *p, unsigned char control)
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/drivers/video/clgenfb.c linux-test/drivers/video/clgenfb.c
--- linux-2.3.13/drivers/video/clgenfb.c	Fri Aug 13 22:44:06 1999
+++ linux-test/drivers/video/clgenfb.c	Sun Aug 15 23:15:26 1999
@@ -1657,9 +1657,11 @@
 /*****************************************************************/
 void __init clgenfb_setup(char *options)
 {
-//    char *this_opt;
+#if 0
+    char *this_opt;
 
-//    printk("clgenfb_setup(): options: %s\n", options);	
+    printk("clgenfb_setup(): options: %s\n", options);
+#endif
 }
 
 
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/include/asm-m68k/ide.h linux-test/include/asm-m68k/ide.h
--- linux-2.3.13/include/asm-m68k/ide.h	Tue May 18 16:10:57 1999
+++ linux-test/include/asm-m68k/ide.h	Sun Aug 15 23:49:06 1999
@@ -38,6 +38,7 @@
 #include <asm/irq.h>
 
 #ifdef CONFIG_ATARI
+#include <linux/interrupt.h>
 #include <asm/atari_stdma.h>
 #endif
 
@@ -63,7 +64,7 @@
 static __inline__ ide_ioreg_t ide_default_io_base(int index)
 {
 	if (MACH_IS_Q40)
-		return q40ide_default_io_base(index);
+		return (ide_ioreg_t)q40ide_default_io_base(index);
 	else return 0;
 }
 
@@ -82,7 +83,8 @@
 	if (MACH_IS_Q40)
 		return q40_ide_init_hwif_ports(hw, (q40ide_ioreg_t) data_port, (q40ide_ioreg_t) ctrl_port, irq);
 #endif
-	printk("ide_init_hwif_ports: must not be called\n");
+	if (data_port || ctrl_port)
+		printk("ide_init_hwif_ports: must not be called\n");
 }
 
 /*
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/include/asm-m68k/init.h linux-test/include/asm-m68k/init.h
--- linux-2.3.13/include/asm-m68k/init.h	Tue May 18 16:01:03 1999
+++ linux-test/include/asm-m68k/init.h	Sun Aug 15 23:15:27 1999
@@ -15,9 +15,6 @@
 #define __FINIT		.previous
 #define __INITDATA	.section	".data.init",#alloc,#write
 
-#define __cacheline_aligned __attribute__ \
-		((__aligned__(16), __section__ (".data.cacheline_aligned")))
-
 #else
 
 /* gdb doesn't like it all if the code for one source file isn't together in
@@ -30,7 +27,6 @@
 #define __INIT
 #define __FINIT
 #define __INITDATA
-#define __cacheline_aligned __attribute__ ((__aligned__(16)))
 
 #endif /* CONFIG_KGDB */
 
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/include/asm-m68k/mmu_context.h linux-test/include/asm-m68k/mmu_context.h
--- linux-2.3.13/include/asm-m68k/mmu_context.h	Tue Aug 10 20:24:44 1999
+++ linux-test/include/asm-m68k/mmu_context.h	Sun Aug 15 23:15:27 1999
@@ -23,7 +23,7 @@
 
 	/* flush MC68030/MC68020 caches (they are virtually addressed) */
 	asm volatile (
-		"movec %%cacr,%0;"
+		"movec %%cacr,%0; "
 		"orw %1,%0; "
 		"movec %0,%%cacr"
 		: "=d" (tmp) : "di" (FLUSH_I_AND_D));
@@ -69,7 +69,8 @@
 	asm volatile (".chip 68k");
 }
 
-static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
+extern inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+			     struct task_struct *tsk, unsigned cpu)
 {
 	if (prev != next) {
 		if (CPU_IS_020_OR_030)

>>>>> partition table diff <<<<<

diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/drivers/block/genhd.c linux-test/drivers/block/genhd.c
--- linux-2.3.13/drivers/block/genhd.c	Fri Aug 13 22:44:05 1999
+++ linux-test/drivers/block/genhd.c	Sun Aug 15 23:46:24 1999
@@ -51,7 +51,7 @@
 extern int net_dev_init(void);
 extern int i2o_init(void);
 
-struct partition_parser *partition_parsers = NULL;
+partbl_parser_t *partition_parsers = NULL;
 
 #ifdef CONFIG_PPC
 extern void note_bootable_part(kdev_t dev, int part);
@@ -187,12 +187,12 @@
       panic("Strange blocksize for partition table\n");
     }
 
-  return ret;
+  return blksize_size[MAJOR(dev)][MINOR(dev)];
 
 }
 
 
-#if CONFIG_KMOD && CONFIG_FOREIGN_PARTITIONS
+#ifdef CONFIG_KMOD
 
 #include <linux/kmod.h>
 
@@ -247,37 +247,39 @@
 
 /*
  * 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
+ * available 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
+static partbl_parser_t partbl_modules[] = {
 #ifdef CONFIG_OSF_PARTITION_MODULE
-	{ "osf",   LE32,  64, 0x82564557, NULL },
+	{ NULL, "osf", NULL, partbl_osf_prio,
+	  partbl_le32_probe,  (partbl_magic_t){ 64, 0x82564557 } },
 #endif
 #ifdef CONFIG_SUN_PARTITION_MODULE
-	{ "sun",   BE16, 508, 0xDABE, NULL },
+	{ NULL, "sun", NULL, partbl_sun_prio,
+	  partbl_be16_probe, (partbl_magic_t){ 508, 0xDABE } },
+#endif
+#ifdef CONFIG_SGI_PARTITION_MODULE
+	{ NULL, "sgi", NULL, partbl_sgi_prio,
+	  partbl_be32_probe, (partbl_magic_t){ 0, 0x0be5a941 } },
+#endif
+#ifdef CONFIG_MAC_PARTITION_MODULE
+	{ NULL, "mac", NULL, partbl_mac_prio,
+	  partbl_be16_probe, (partbl_magic_t){ 0, 0x4552 } },
 #endif
 #ifdef CONFIG_AMIGA_PARTITION_MODULE
-	{ "amiga", FUNC,   0,      0, probe_amiga_partition },
+	{ NULL, "amiga", NULL, partbl_amiga_prio,
+	  partbl_func_probe,  (partbl_magic_t)probe_amiga_partition },
 #endif
 #ifdef CONFIG_ATARI_PARTITION_MODULE
-	{ "atari", FUNC,   0,      0, probe_atari_partition },
+	{ NULL, "atari", NULL, partbl_atari_prio,
+	  partbl_func_probe,  (partbl_magic_t)probe_atari_partition },
 #endif
-#ifdef CONFIG_MAC_PARTITION_MODULE
-	{ "mac",   BE16,   0, 0x4552, NULL },
+#ifdef CONFIG_MSDOS_PARTITION_MODULE
+	{ NULL, "msdos", NULL, partbl_msdos_prio,
+	  partbl_le16_probe, (partbl_magic_t){ 510, 0xAA55 } },
 #endif
 };
 
@@ -286,66 +288,60 @@
 /*
  * Try to load all partition parsers that could apply to this device
  */
-static int try_to_load_parser(struct gendisk *hd, kdev_t dev)
+static inline void try_to_load_parser(struct gendisk *hd, kdev_t dev,
+				      partbl_parser_t *p, struct buffer_head *bh)
 {
-	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:
+	char modname[32];
+	char *data = bh->b_data + p->magic.m.offset;
+	u32 magic = p->magic.m.magic;
+
+	switch (p->type) {
+	case partbl_le16_probe:
+		if (le16_to_cpu(*(u16 *)data) != magic)
+			return;
+		break;
+	case partbl_le32_probe:
+		if (le32_to_cpu(*(u32 *)data) != magic)
+			return;
+		break;
+	case partbl_be16_probe:
+		if (be16_to_cpu(*(u16 *)data) != magic)
+			return;
+		break;
+	case partbl_be32_probe:
+		if (be32_to_cpu(*(u32 *)data) != magic)
+			return;
+		break;
+	case partbl_func_probe:
+		if (!p->magic.probe(hd, dev, bh))
+			return;
+		break;
+	default:
+		return;
 	}
-	brelse(bh);
-	return loaded;
+
+	strcpy(modname, "part-format-");
+	strcat(modname, p->name);
+	request_module(modname);
 }
 
-#endif /* CONFIG_KMOD && CONFIG_FOREIGN_PARTITIONS */
+#endif /* CONFIG_KMOD */
 
 
 static void check_partition(struct gendisk *hd, kdev_t dev)
 {
 	static int first_time = 1;
-	int tries = 0;
 	unsigned long first_sector;
 	char buf[40];
-	struct partition_parser *parser;
+	partbl_parser_t *parser;
+	int old_blocksize;
+#ifdef CONFIG_KMOD
+	struct buffer_head *bh = NULL;
+#endif
+
+	/* set 512 as fixed blocksize for partition table scan */
+	old_blocksize = get_ptable_blocksize(dev);
+	set_blocksize(dev, 512);
 
 	if (first_time)
 		printk(KERN_INFO "Partition check:\n");
@@ -361,56 +357,83 @@
 		return;
 	}
 
-#if CONFIG_KMOD && CONFIG_FOREIGN_PARTITIONS
-    retry:
-#endif
 	printk(KERN_INFO " %s:", disk_name(hd, MINOR(dev), buf));
-	for( parser = partition_parsers; parser; parser = parser->next ) {
-		if (parser->func(hd, dev, first_sector))
-			return;
+	for ( parser = partition_parsers; parser; parser = parser->next ) {
+#ifdef CONFIG_KMOD
+		if (!parser->pars && parser->type != partbl_none_probe) {
+			if (!bh) {
+				if (!(bh = bread(dev, 0, 512))) {
+					parser = NULL;
+					break;
+				}
+			}
+			try_to_load_parser(hd, dev, parser, bh);
+		}
+#endif
+		if (parser->pars && parser->pars(hd, dev, first_sector))
+			break;
 	}
-	++tries;
-#if CONFIG_KMOD && CONFIG_FOREIGN_PARTITIONS
-	if (tries == 1 && try_to_load_parser(hd, dev))
-		goto retry;
+
+	if (!parser)
+		printk(" unknown partition table\n");
+#ifdef CONFIG_KMOD
+	if (bh)
+		bforget(bh);
 #endif
-	printk(" unknown partition table\n");
+	set_blocksize(dev, old_blocksize);
 }
 
-int register_partbl( struct partition_parser *parser )
+int register_partbl(char *name, partbl_priority_t prio, partbl_parsfunc_t *pars)
 {
-	struct partition_parser **p;
-    
-	if (!parser)
-		return -EINVAL;
-	if (parser->next)
-		return -EBUSY;
-	for( p = &partition_parsers; *p; p = &(*p)->next )
-		if (*p == parser)
+	partbl_parser_t **prev, *new;
+
+	for (prev = &partition_parsers; *prev;  prev = &(*prev)->next) {
+		if (!strcmp((*prev)->name, name))
+			break;
+	}
+
+	if (*prev) {
+		new = *prev;
+		if (new->pars)
 			return -EBUSY;
+		*prev = new->next;
+	} else {
+		new = kmalloc(sizeof(partbl_parser_t) + strlen(name) + 1, GFP_KERNEL);
+		if (!new)
+			return -ENOMEM;
+		new->name = (char *)(new + 1);
+		strcpy(new->name, name);
+#ifdef CONFIG_MODULES
+		new->type = partbl_none_probe;
+#endif
+	}
+
+	for (prev = &partition_parsers; *prev;  prev = &(*prev)->next) {
+		if ((*prev)->prio >= prio)
+			break;
+	}
+
+	new->pars = pars;
+	new->prio = prio;
+
+	new->next = *prev;
+	*prev = new;
 
-	/* 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 )
+void unregister_partbl(char *name)
 {
-	struct partition_parser **p;
+	partbl_parser_t **prev;
     
-	for( p = &partition_parsers; *p; p = &(*p)->next ) {
-		if (*p == parser) {
-			*p = parser->next;
-			parser->next = NULL;
-			return 0;
-		}
+	for (prev = &partition_parsers; *prev; prev = &(*prev)->next) {
+		if (!strcmp((*prev)->name, name))
+			break;
 	}
-	return -EINVAL;
+
+	if (*prev)
+		(*prev)->pars = NULL;
 }
-#endif
 
 #ifdef CONFIG_PROC_FS
 static struct proc_dir_entry *proc_partbl;
@@ -418,43 +441,65 @@
 static int partbl_read_proc(char *buf, char **start, off_t offset,
 			    int len, int *eof, void *private)
 {
-	struct partition_parser *p;
+	partbl_parser_t *p;
 
 	len = 0;
-	for( p = partition_parsers; p && len < 4000; p = p->next )
-		len += sprintf(buf + len, "%s\n", p->name );
+	for( p = partition_parsers; p && len < 4000; p = p->next ) {
+		if (p->pars)
+			len += sprintf(buf + len, "%s\n", p->name );
+		else
+			len += sprintf(buf + len, "(%s)\n", p->name );
+	}
 	*start = buf + offset;
 	return len > offset ? len - offset : 0;
 }
 #endif
 
-__initfunc(static void partbl_init( void ))
+static __init void partbl_init(void)
 {
-	extern void msdos_partbl_init(void);
-	extern void osf_partbl_init(void);
-	extern void sun_partbl_init(void);
-	extern void sgi_partbl_init(void);
-	extern void ultrix_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_ULTRIX_PARTITION)
-		ultrix_partbl_init();
-	if (HAVE_SGI_PARTITION)
-		sgi_partbl_init();
-	if (HAVE_SUN_PARTITION)
-		sun_partbl_init();
-	if (HAVE_OSF_PARTITION)
-		osf_partbl_init();
-	if (HAVE_MSDOS_PARTITION)
-		msdos_partbl_init();
+	extern int osf_partbl_init(void);
+	extern int sun_partbl_init(void);
+	extern int sgi_partbl_init(void);
+	extern int ultrix_partbl_init(void);
+	extern int mac_partbl_init(void);
+	extern int amiga_partbl_init(void);
+	extern int atari_partbl_init(void);
+	extern int msdos_partbl_init(void);
+#ifdef CONFIG_KMOD
+	partbl_parser_t *p;
+	int i;
+
+	for (i = 0, p = partbl_modules; i < N_PARTBL_MODULES; i++, p++) {
+		p->next = partition_parsers;
+		partition_parsers = p;
+		register_partbl(p->name, p->prio, NULL);
+	}
+#endif
+
+#ifdef CONFIG_OSF_PARTITION
+	osf_partbl_init();
+#endif
+#ifdef CONFIG_SUN_PARTITION
+	sun_partbl_init();
+#endif
+#ifdef CONFIG_SGI_PARTITION
+	sgi_partbl_init();
+#endif
+#ifdef CONFIG_ULTRIX_PARTITION
+	ultrix_partbl_init();
+#endif
+#ifdef CONFIG_MAC_PARTITION
+	mac_partbl_init();
+#endif
+#ifdef CONFIG_AMIGA_PARTITION
+	amiga_partbl_init();
+#endif
+#ifdef CONFIG_ATARI_PARTITION
+	atari_partbl_init();
+#endif
+#ifdef CONFIG_MSDOS_PARTITION
+	msdos_partbl_init();
+#endif
 
 #ifdef CONFIG_PROC_FS
 	proc_partbl = create_proc_entry("partition-formats", 0, 0);
@@ -598,6 +643,7 @@
 /* symbols visible for partbl_* modules */
 EXPORT_SYMBOL(partbl_add_partition);
 EXPORT_SYMBOL(get_ptable_blocksize);
+EXPORT_SYMBOL(get_hardsect_size);
 EXPORT_SYMBOL(current_minor);
 EXPORT_SYMBOL(register_partbl);
 EXPORT_SYMBOL(unregister_partbl);
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/drivers/block/partbl_amiga.c linux-test/drivers/block/partbl_amiga.c
--- linux-2.3.13/drivers/block/partbl_amiga.c	Fri Aug 13 22:44:05 1999
+++ linux-test/drivers/block/partbl_amiga.c	Sun Aug 15 23:14:34 1999
@@ -38,24 +38,12 @@
 	int			 nr_sects;
 	int			 blk;
 	int			 part, res;
-	int			 old_blocksize;
-	int			 blocksize;
 
 	MOD_INC_USE_COUNT;
-	old_blocksize = get_ptable_blocksize(dev);
-	blocksize = get_hardsect_size(dev);
-
-	/*
-	 * Hack for disks with 256 byte hardware sectors
-	 */
-	if (blocksize < 512)
-		blocksize = 512;
-
-	set_blocksize(dev,blocksize);
 	res = 0;
 
 	for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
-		if(!(bh = bread(dev,blk,blocksize))) {
+		if (!(bh = bread(dev,blk,get_ptable_blocksize(dev)))) {
 			printk("Dev %s: unable to read RDB block %d\n",
 			       kdevname(dev),blk);
 			res = -1;
@@ -82,7 +70,7 @@
 			blk = be32_to_cpu(rdb->rdb_PartitionList);
 			brelse(bh);
 			for (part = 1; blk > 0 && part <= 16; part++) {
-				if (!(bh = bread(dev,blk,blocksize))) {
+				if (!(bh = bread(dev,blk,get_ptable_blocksize(dev)))) {
 					printk("Dev %s: unable to read partition block %d\n",
 						       kdevname(dev),blk);
 					res = -1;
@@ -119,27 +107,8 @@
 	}
 
 rdb_done:
-	set_blocksize(dev,old_blocksize);
 	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
+partbl_module(amiga)
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/drivers/block/partbl_atari.c linux-test/drivers/block/partbl_atari.c
--- linux-2.3.13/drivers/block/partbl_atari.c	Sat Aug 14 00:02:27 1999
+++ linux-test/drivers/block/partbl_atari.c	Sun Aug 15 23:15:26 1999
@@ -51,6 +51,7 @@
   bh = bread (dev, 0, get_ptable_blocksize(dev));
   if (!bh) {
       printk (" unable to read block 0 (partition table)\n");
+      MOD_DEC_USE_COUNT;
       return -1;
   }
 
@@ -61,6 +62,7 @@
   }
   if ((psum & 0xFFFF) != 0x1234) {
     brelse(bh);
+    MOD_DEC_USE_COUNT;
     return 0;
   }
 
@@ -191,22 +193,4 @@
   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
+partbl_module(atari)
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/drivers/block/partbl_mac.c linux-test/drivers/block/partbl_mac.c
--- linux-2.3.13/drivers/block/partbl_mac.c	Fri Aug 13 22:44:05 1999
+++ linux-test/drivers/block/partbl_mac.c	Sun Aug 15 23:14:34 1999
@@ -149,22 +149,4 @@
 	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
+partbl_module(mac)
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/drivers/block/partbl_msdos.c linux-test/drivers/block/partbl_msdos.c
--- linux-2.3.13/drivers/block/partbl_msdos.c	Fri Aug 13 22:44:05 1999
+++ linux-test/drivers/block/partbl_msdos.c	Sun Aug 15 23:14:34 1999
@@ -505,22 +505,4 @@
 	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
+partbl_module(msdos)
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/drivers/block/partbl_osf.c linux-test/drivers/block/partbl_osf.c
--- linux-2.3.13/drivers/block/partbl_osf.c	Fri Aug 13 22:44:05 1999
+++ linux-test/drivers/block/partbl_osf.c	Sun Aug 15 23:14:34 1999
@@ -90,22 +90,4 @@
 	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
+partbl_module(osf)
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/drivers/block/partbl_sgi.c linux-test/drivers/block/partbl_sgi.c
--- linux-2.3.13/drivers/block/partbl_sgi.c	Fri Aug 13 22:44:05 1999
+++ linux-test/drivers/block/partbl_sgi.c	Sun Aug 15 23:14:34 1999
@@ -92,22 +92,4 @@
 	return 1;
 }
 
-static struct partition_parser sgi_partition_parser =
-    { NULL, "sgi", sgi_partition };
-
-#ifndef MODULE
-__initfunc(void sgi_partbl_init( void ))
-{
-	(void)register_partbl( &sgi_partition_parser );
-}
-#else
-int init_module(void)
-{
-	return register_partbl( &sgi_partition_parser );
-}
-
-void cleanup_module(void)
-{
-	(void)unregister_partbl( &sgi_partition_parser );
-}
-#endif
+partbl_module(sgi)
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/drivers/block/partbl_sun.c linux-test/drivers/block/partbl_sun.c
--- linux-2.3.13/drivers/block/partbl_sun.c	Fri Aug 13 22:44:05 1999
+++ linux-test/drivers/block/partbl_sun.c	Sun Aug 15 23:14:34 1999
@@ -92,22 +92,4 @@
 	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
+partbl_module(sun)
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/drivers/block/partbl_ultrix.c linux-test/drivers/block/partbl_ultrix.c
--- linux-2.3.13/drivers/block/partbl_ultrix.c	Fri Aug 13 22:44:05 1999
+++ linux-test/drivers/block/partbl_ultrix.c	Sun Aug 15 23:14:34 1999
@@ -66,22 +66,4 @@
 	}
 }
 
-static struct partition_parser ultrix_partition_parser =
-    { NULL, "ultrix", ultrix_partition };
-
-#ifndef MODULE
-__initfunc(void ultrix_partbl_init( void ))
-{
-	(void)register_partbl( &ultrix_partition_parser );
-}
-#else
-int init_module(void)
-{
-	return register_partbl( &ultrix_partition_parser );
-}
-
-void cleanup_module(void)
-{
-	(void)unregister_partbl( &ultrix_partition_parser );
-}
-#endif
+partbl_module(ultrix)
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/fs/Config.in linux-test/fs/Config.in
--- linux-2.3.13/fs/Config.in	Fri Aug 13 22:44:07 1999
+++ linux-test/fs/Config.in	Sun Aug 15 23:14:34 1999
@@ -160,6 +160,10 @@
   if [ "$ARCH" != "sparc" -a "$ARCH" != "sparc64" ]; then
   	tristate 'Sun partition support' CONFIG_SUN_PARTITION
   fi
+  if [ "$ARCH" != "mips" -a "$CONFIG_SGI" != "y" ]; then
+	tristate 'SGI partition support' CONFIG_SGI_PARTITION
+  fi
+  tristate 'Ultrix partition support' CONFIG_ULTRIX_PARTITION
   if [ "$CONFIG_AMIGA" != "y" ]; then
   	tristate 'Amiga RDB partition support' CONFIG_AMIGA_PARTITION
   fi
diff -Nur -X /opt/home/roman/src/m68k_nodiff linux-2.3.13/include/linux/genhd.h linux-test/include/linux/genhd.h
--- linux-2.3.13/include/linux/genhd.h	Fri Aug 13 22:44:08 1999
+++ linux-test/include/linux/genhd.h	Sun Aug 15 23:14:34 1999
@@ -13,54 +13,6 @@
 #include <linux/types.h>
 #include <linux/kdev_t.h>
 
-#ifdef CONFIG_MSDOS_PARTITION
-# define HAVE_MSDOS_PARTITION 1
-#else
-# define HAVE_MSDOS_PARTITION 0
-#endif
-
-#ifdef CONFIG_OSF_PARTITION
-# define HAVE_OSF_PARTITION 1
-#else
-# define HAVE_OSF_PARTITION 0
-#endif
-
-#ifdef CONFIG_SUN_PARTITION
-# define HAVE_SUN_PARTITION 1
-#else
-# define HAVE_SUN_PARTITION 0
-#endif
-
-#ifdef CONFIG_AMIGA_PARTITION
-# define HAVE_AMIGA_PARTITION 1
-#else
-# define HAVE_AMIGA_PARTITION 0
-#endif
-
-#ifdef CONFIG_ATARI_PARTITION
-# define HAVE_ATARI_PARTITION 1
-#else
-# define HAVE_ATARI_PARTITION 0
-#endif
-
-#ifdef CONFIG_MAC_PARTITION
-# define HAVE_MAC_PARTITION 1
-#else
-# define HAVE_MAC_PARTITION 0
-#endif
-
-#ifdef CONFIG_SGI_PARTITION
-# define HAVE_SGI_PARTITION 1
-#else
-# define HAVE_SGI_PARTITION 0
-#endif
-
-#ifdef CONFIG_ULTRIX_PARTITION
-# define HAVE_ULTRIX_PARTITION 1
-#else
-# define HAVE_ULTRIX_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
@@ -262,25 +214,73 @@
 #endif /* CONFIG_UNIXWARE_DISKLABEL */
 
 #ifdef __KERNEL__
+
 extern struct gendisk *gendisk_head;	/* linked list of disks */
 
 char *disk_name (struct gendisk *hd, int minor, char *buf);
 
 int get_hardsect_size(kdev_t dev);
-#endif
 void partbl_add_partition (struct gendisk *hd, int minor, int start, int size);
-int get_hardsect_size(kdev_t dev);
 unsigned int get_ptable_blocksize(kdev_t dev);
 extern int current_minor;
 
-struct partition_parser {
-	struct partition_parser *next;
+typedef enum partbl_priority {
+	partbl_first_prio = 10,
+	partbl_osf_prio,
+	partbl_sun_prio,
+	partbl_sgi_prio,
+	partbl_ultrix_prio,
+	partbl_mac_prio,
+	partbl_amiga_prio,
+	partbl_atari_prio,
+	partbl_msdos_prio,
+	partbl_last_prio
+} partbl_priority_t;
+
+typedef enum partbl_probe_type {
+	partbl_none_probe,
+	partbl_be16_probe,
+	partbl_be32_probe,
+	partbl_le16_probe,
+	partbl_le32_probe,
+	partbl_func_probe
+} partbl_probe_t;
+
+typedef union partbl_magic {
+	struct {
+		u32 offset;
+	        u32 magic;
+	} m;
+	int (*probe)(struct gendisk *hd, kdev_t dev,
+		     struct buffer_head *bh_0);
+} partbl_magic_t;
+
+typedef int partbl_parsfunc_t(struct gendisk *hd, kdev_t dev, unsigned long first_sector);
+
+typedef struct partbl_parser {
+	struct partbl_parser *next;
 	char *name;
-	int (*func)(struct gendisk *hd, kdev_t dev,
-		    unsigned long first_sector);
-};
+	partbl_parsfunc_t *pars;
+	partbl_priority_t prio;
+#ifdef CONFIG_MODULES
+	partbl_probe_t type;
+	partbl_magic_t magic;
+#endif
+} partbl_parser_t;
+
+int register_partbl(char *name, partbl_priority_t prio, partbl_parsfunc_t *pars);
+void unregister_partbl(char *name);
+
+#define partbl_module(name)							\
+int name##_partbl_init(void) {							\
+	return register_partbl(#name, partbl_##name##_prio, name##_partition);	\
+}										\
+void  name##_partbl_exit(void) {						\
+	unregister_partbl(#name);						\
+}										\
+module_init(name##_partbl_init)							\
+module_exit(name##_partbl_exit)
 
-int register_partbl( struct partition_parser *parser );
-int unregister_partbl( struct partition_parser *parser );
+#endif /* __KERNEL__ */
 
-#endif
+#endif /* _LINUX_GENHD_H */

