diff -urN -X dontdiff linux-2.4.20/drivers/mtd/chips/jedec_probe.c 
linux-2.4.20-modified/drivers/mtd/chips/jedec_probe.c
--- linux-2.4.20/drivers/mtd/chips/jedec_probe.c	2001-11-10 00:29:40.000000000 
+0200
+++ linux-2.4.20-modified/drivers/mtd/chips/jedec_probe.c	2003-04-03 
11:35:25.000000000 +0300
@@ -1,4 +1,4 @@
-/* 
+/*
    Common Flash Interface probe code.
    (C) 2000 Red Hat. GPL'd.
    $Id: jedec_probe.c,v 1.3 2001/10/02 15:05:12 dwmw2 Exp $
@@ -34,6 +34,8 @@
 #define AM29LV800BT	0x22DA
 #define AM29LV160DT	0x22C4
 #define AM29LV160DB	0x2249
+#define AM29LV081	0x38
+#define AM29LV017	0xC8
 
 /* Atmel */
 #define AT49BV16X4	0x00c0
@@ -247,12 +249,26 @@
                 regions: {ERASEINFO(0x10000,30),
                           ERASEINFO(0x08000,2),
 			  ERASEINFO(0x02000,8)
-                }
-	} 
+        	}
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV081,
+		name: "AMD AM29LV081",
+		DevSize: SIZE_1MiB,
+		NumEraseRegions: 1,
+		regions: { ERASEINFO(0x10000,16) }
+	}, {
+		mfr_id: MANUFACTURER_AMD,
+		dev_id: AM29LV017,
+		name: "AMD AM29LV017",
+		DevSize: SIZE_2MiB,
+		NumEraseRegions: 1,
+		regions: { ERASEINFO(0x10000,32) }
+	}
 };
 
 
-static int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
+static int cfi_jedec_setup(struct map_info *map, struct cfi_private *p_cfi, int index);
 
 static int jedec_probe_chip(struct map_info *map, __u32 base,
 			    struct flchip *chips, struct cfi_private *cfi);
@@ -261,11 +277,15 @@
 #define jedec_read_mfr(map, base, osf) cfi_read(map, base)
 #define jedec_read_id(map, base, osf) cfi_read(map, (base)+(osf))
 
-static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
+static int cfi_jedec_setup(struct map_info *map, struct cfi_private *p_cfi, int index)
 {
 	int i,num_erase_regions;
 
-	printk("Found: %s\n",jedec_table[index].name);
+	printk("%s: Found %s\n", map->name, jedec_table[index].name);
+
+	printk(KERN_INFO "%s: Found %d x%d devices at 0x0 in %d-bit mode\n",
+	       map->name, p_cfi->interleave, p_cfi->device_type * 8,
+	       map->buswidth * 8);
 
 	num_erase_regions = jedec_table[index].NumEraseRegions;
 	
@@ -283,10 +303,45 @@
 
 	for (i=0; i<num_erase_regions; i++){
 		p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
-	}	
+	}
+			
 	return 1; 	/* ok */
 }
 
+#define JEDEC_MATCH(val) jedec_match_pattern(map, cfi, (val))
+
+static int jedec_match_pattern(struct map_info *map, struct cfi_private *cfi, __u16 value) {
+
+	int i = 0, tmp = 0, bw_il = 0, mask_val = 0;
+
+	bw_il = map->buswidth/cfi->interleave;
+	mask_val = value & ((1 << (bw_il << 3)) - 1);
+
+	/* Create pattern for given configuration */
+	for (i = 0; i < cfi->interleave; i += bw_il) {
+		tmp |= mask_val << (i * bw_il << 3);
+	}
+
+	return tmp;
+}
+
+#define JEDEC_FIND(mfr, id) jedec_find_chip(map, cfi, (mfr), (id))
+
+static int jedec_find_chip(struct map_info *map, struct cfi_private *cfi, 
+	int mfr, int id) {
+
+	int i;
+
+	for (i=0; i < sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
+
+		if (mfr == JEDEC_MATCH(jedec_table[i].mfr_id) &&
+		    id == JEDEC_MATCH(jedec_table[i].dev_id))
+			return i;
+	}
+
+	return -1;
+}
+
 static int jedec_probe_chip(struct map_info *map, __u32 base,
 			      struct flchip *chips, struct cfi_private *cfi)
 {
@@ -329,43 +384,55 @@
 	cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
 
 	if (!cfi->numchips) {
-		/* This is the first time we're called. Set up the CFI 
+
+	        int chip_ind = 0;
+
+		/* This is the first time we're called. Set up the CFI
 		   stuff accordingly and return */
 		
 		cfi->mfr = jedec_read_mfr(map, base, osf);
 		cfi->id = jedec_read_id(map, base, osf);
-		
-		for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
-			if (cfi->mfr == jedec_table[i].mfr_id &&
-			    cfi->id == jedec_table[i].dev_id)
-				return cfi_jedec_setup(cfi, i);
-		}
+
+		/* See if the chip is supported */
+		if (-1 < (chip_ind = JEDEC_FIND(cfi->mfr, cfi->id)))
+			return cfi_jedec_setup(map, cfi, chip_ind);
+
 		if (!retried++) {
 			/* Deal with whichever strange chips these were */
 			cfi->addr_unlock1 |= cfi->addr_unlock1 << 8;
 			cfi->addr_unlock2 |= cfi->addr_unlock2 << 8;
 			goto retry;
 		}
+
+		return 0;
+	}
+
+	/* Check if chip type remains the same. If not then pass... */
+	else if (jedec_read_mfr(map, base, osf) != cfi->mfr ||
+		 jedec_read_id(map, base, osf) != cfi->id) {
 		return 0;
 	}
 	
 	/* Check each previous chip to see if it's an alias */
 	for (i=0; i<cfi->numchips; i++) {
+	
 		/* This chip should be in read mode if it's one
 		   we've already touched. */
-		if (jedec_read_mfr(map, base, osf) == cfi->mfr &&
-		    jedec_read_id(map, base, osf) == cfi->id) {
+		if (jedec_read_mfr(map, chips[i].start, osf) == cfi->mfr &&
+		    jedec_read_id(map, chips[i].start, osf) == cfi->id) {
+			
 			/* Eep. This chip also looks like it's in autoselect mode.
 			   Is it an alias for the new one? */
 			
 			cfi_send_gen_cmd(0xF0, 0, chips[i].start, map, cfi, cfi->device_type, NULL);
+			
 			/* If the device IDs go away, it's an alias */
 			if (jedec_read_mfr(map, base, osf) != cfi->mfr ||
 			    jedec_read_id(map, base, osf) != cfi->id) {
 				printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
 				       map->name, base, chips[i].start);
 				return 0;
-			}
+			} 
 			
 			/* Yes, it's actually got the device IDs as data. Most
 			 * unfortunate. Stick the new chip in read mode
@@ -396,7 +463,7 @@
 	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
 
 	printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n",
-	       map->name, cfi->interleave, cfi->device_type*8, base, 
+	       map->name, cfi->interleave, cfi->device_type*8, base,
 	       map->buswidth*8);
 	
 	return 1;
diff -urN -X dontdiff linux-2.4.20/drivers/mtd/maps/Config.in 
linux-2.4.20-modified/drivers/mtd/maps/Config.in
--- linux-2.4.20/drivers/mtd/maps/Config.in	2002-11-29 01:53:13.000000000 
+0200
+++ linux-2.4.20-modified/drivers/mtd/maps/Config.in	2003-03-20 
15:42:32.000000000 +0200
@@ -17,6 +17,10 @@
    dep_tristate '  Sun Microsystems userflash support' CONFIG_MTD_SUN_UFLASH $CONFIG_MTD_CFI
 fi
 
+if [ "$CONFIG_SPARC" = "y" -o "$CONFIG_SPARC32" = "y" ]; then
+   dep_tristate '  Sun Microsystems Javastation OS-flash support' CONFIG_MTD_SUN_JSFLASH $CONFIG_MTD_CFI
+fi
+
 if [ "$CONFIG_X86" = "y" ]; then
    dep_tristate '  CFI Flash device mapped on Photron PNC-2000' CONFIG_MTD_PNC2000 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
    dep_tristate '  CFI Flash device mapped on AMD SC520 CDP' CONFIG_MTD_SC520CDP $CONFIG_MTD_CFI
diff -urN -X dontdiff linux-2.4.20/drivers/mtd/maps/jsflash.c 
linux-2.4.20-modified/drivers/mtd/maps/jsflash.c
--- linux-2.4.20/drivers/mtd/maps/jsflash.c	1970-01-01 02:00:00.000000000 
+0200
+++ linux-2.4.20-modified/drivers/mtd/maps/jsflash.c	2003-03-21 
15:33:41.000000000 +0200
@@ -0,0 +1,175 @@
+/* $Id: sun_uflash.c,v 1.4 2001/10/02 15:05:14 dwmw2 Exp $
+ *
+ *  drivers/mtd/maps/jsflash.c
+ *
+ *  Copyright (C) 1999-2000 Pete Zaitcev (Old jsflash.c)
+ *  Copyright (C) 2003 Jarno Manninen
+ *
+ *  This module provides acces to a flash memory window 
+ *  on microsparc machines.
+ *
+ *  The window is located at 0x20400000, size 16Mb. 
+ *  
+ *  Devices used on Javastation should be JEDEC compliant
+ *  so we just probe for them, which should detect chips.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/ebus.h>
+#include <asm/oplib.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#define JSFLASH_OBPNAME	"flash-memory"
+#define JSFLASH_DEVNAME "OS-flash"
+
+#define JSFLASH_ADDRESS         0x20400000
+#define JSFLASH_WINDOW_SIZE	0x01000000           /* 16Mb window */
+#define JSFLASH_BUSWIDTH	         4           /* Native width */
+
+MODULE_AUTHOR
+	("Jarno Manninen <jarno.manninen@tut.fi>");
+MODULE_DESCRIPTION
+	("User-programmable flash device on Sun Javastations");
+MODULE_SUPPORTED_DEVICE
+	("OS-flash");
+MODULE_LICENSE
+	("GPL");
+
+static __u32 jsflash_read32(struct map_info *map, unsigned long ofs)
+{
+	unsigned long retval, addr;
+
+	/* Non 4-byte aligned accesses kill the system,
+	   but MTD takes care of this after probing. */
+	if (ofs & 0x3)
+	  	return 0;
+
+        addr = JSFLASH_ADDRESS + ofs;
+
+	__asm__ __volatile__("lda [%1] %2, %0\n\t" :
+				"=r" (retval) :
+				"r" (addr), "i" (ASI_M_BYPASS));
+
+	return retval;
+}
+
+static void jsflash_copy_from(struct map_info *map, void *to,
+	unsigned long from, ssize_t len)
+{
+	union byte4 {
+		char s[4];
+		unsigned int n;
+	} b;
+
+	while (len >= 4) {
+		len -= 4;
+		b.n = jsflash_read32(map, from);
+		memcpy(to, b.s, 4);
+		from += 4;
+		to += 4;
+	}
+	if (len > 0) {
+		b.n = jsflash_read32(map, from);
+		memcpy(to, b.s, len);
+	}
+}
+
+static void jsflash_write32(struct map_info *map, __u32 data,
+	unsigned long ofs)
+{
+
+	unsigned long addr;
+
+	if (ofs & 0x3)
+		return;
+
+	addr = JSFLASH_ADDRESS + ofs;
+
+	__asm__ __volatile__("sta %0, [%1] %2\n\t" : :
+				"r" (data), "r" (addr), "i" (ASI_M_BYPASS) :
+				"memory");
+}
+
+static struct mtd_info *jsflash_mtd = 0;
+
+static struct map_info jsflash_map = {
+
+		name:		JSFLASH_DEVNAME,
+		size:		JSFLASH_WINDOW_SIZE,
+		buswidth:	JSFLASH_BUSWIDTH,
+
+		read32:		jsflash_read32,
+		copy_from:	jsflash_copy_from,
+		write32:	jsflash_write32,
+};
+
+/*
+   TODO! Create simple partitioning, with correct values
+   this is just for testing.
+*/
+
+static struct mtd_partition javastation_partitions[] = {
+	{
+		name:		"Bootstrap",	/* For proll??? */
+		size:		0x80000,
+		offset:		0,
+	}, {
+		name:		"Filesystem",
+		size:		0,		/* Let the MTD fill it */
+		offset:		MTDPART_OFS_APPEND,
+	}
+};
+
+static int __init jsflash_init(void)
+{
+	int node;
+	struct linux_prom_registers reg0;
+
+	node = prom_getchild(prom_root_node);
+	node = prom_searchsiblings(node, "flash-memory");
+
+	if (node == 0 || node == -1 || sparc_cpu_model != sun4m) {
+		return -ENXIO;
+	}
+
+	/* Now we must be on sun4m. And supposedly on Javastation */
+
+	/* Try to probe around in the flash window */
+	jsflash_mtd = do_map_probe("jedec_probe", &jsflash_map);
+
+	if (0 == jsflash_mtd) {
+		return(-ENXIO);
+	}
+
+	jsflash_mtd->module = THIS_MODULE;
+	add_mtd_device(jsflash_mtd);
+	add_mtd_partitions(jsflash_mtd, javastation_partitions, 
+		(sizeof(javastation_partitions)/sizeof(struct mtd_partition)));
+
+	return(0);
+}
+
+static void __exit jsflash_cleanup(void)
+{
+        if (0 != jsflash_mtd) {
+	  	del_mtd_partitions(jsflash_mtd);
+	  	del_mtd_device(jsflash_mtd);
+	  	map_destroy(jsflash_mtd);
+	}
+}
+
+module_init(jsflash_init);
+module_exit(jsflash_cleanup);
diff -urN -X dontdiff linux-2.4.20/drivers/mtd/maps/Makefile 
linux-2.4.20-modified/drivers/mtd/maps/Makefile
--- linux-2.4.20/drivers/mtd/maps/Makefile	2002-11-29 01:53:13.000000000 +0200
+++ linux-2.4.20-modified/drivers/mtd/maps/Makefile	2003-03-20 
15:43:08.000000000 +0200
@@ -40,5 +40,6 @@
 obj-$(CONFIG_MTD_PB1100)        += pb1xxx-flash.o
 obj-$(CONFIG_MTD_PB1500)        += pb1xxx-flash.o
 obj-$(CONFIG_MTD_AUTCPU12)	+= autcpu12-nvram.o
+obj-$(CONFIG_MTD_SUN_JSFLASH)   += jsflash.o

 include $(TOPDIR)/Rules.make

