public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* Re: Erase Sector Size
  2001-08-21 11:44 Erase Sector Size Ashok M Padmanaban
@ 2001-08-21  6:33 ` David Woodhouse
  0 siblings, 0 replies; 6+ messages in thread
From: David Woodhouse @ 2001-08-21  6:33 UTC (permalink / raw)
  To: Ashok M Padmanaban; +Cc: MTD for Linux, JFFS mailing list

ashokmp@sasken.com said:
>  Iam using intels 28F128 Strata flash, According to its data sheet its
> erase sector size is 128KB. But with 2.4.2 kernel + rmk2 (patch,diff)
> + mtd patch , the erase sector size is 256KB.

It's not configurable. You probably have two 16-bit devices arranged in a 
pair to give a 32-bit data path - which doubles the effective erase size 
because it doesn't make sense to erase one half at a time.

We just need to fix JFFS2 so it isn't so greedy.

--
dwmw2

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: Erase Sector Size
@ 2001-08-21 11:37 Kremer, Alex
  0 siblings, 0 replies; 6+ messages in thread
From: Kremer, Alex @ 2001-08-21 11:37 UTC (permalink / raw)
  To: MTD for Linux, JFFS mailing list

[-- Attachment #1: Type: text/plain, Size: 2992 bytes --]


Hi all,

I have a design question for the code I'm attaching 
that adds support for the old Intel's TE28F*B Fast Boot Block series.
The patch is to cvs from Aug, 19. Note that it modifies
the maps/dc21285.c code and Config.in, to which my question below is
related.

As opposed to Intel's 28F*J Strata Flash series the 
old Fast Boot Block series is not CFI compliant.
I couldn't even coerce it to work as a jedec.

The Lart (devices/lart.c) uses a chip from this series, but the data bus has

a totally crazy mapping.
So I wrote a module for this series somewhat based on the chips/amd_flash.c
code.
Since I have it mapped via dc21285 I modified maps/dc21285.c to probe using
my module
instead of using cfi_probe. (I also had to modify the write16, since the
code there uses,
IMO,  a wrong addr. mask).

I see two problems (not counting the possible bug in dc21285_write*() code)
with what I did:

1. The dc21285.c use of cfi compliant chips is hardcoded (there should maybe
be a
	way to try and probe all registered modules for the first one that
reports success,
	or something like that) or should I use CONFIG_ and #ifdef
2. A minor one - the use of a certain chipset for mapping doesn't
necessarily mean that the
	address and data lanes are always the same. In addition is there
some framework in plan 
      that captures the mapping/interleaving and bus width issues separated
for the specific chip support?

Should I maybe write a device specific modules without the maps/chips
separation, since it seems only
to complicate things?

BTW: For some reason for Intel's 28F* chips the most important is the letter
that follows the
      size code, so the 28F128J means that it belongs to a Strata Flash line
which is CFI comliant,
 	while 28F128B belongs to the Fast Boot Block Flash line, which is
really a pre-CFI,
	and the CFI code wont work.

A totally unrelated issue: 
 I need to edit the redboot partition table from linux.
 How should I reread it? Removing and loading the modules, doesn't seem like
a nice solution,
 especially since the root fs is on flash.
 Should I try and add ioctl to the mtdchar/block code, so it would work like
when you use fdisk?

Kreso

-----Original Message-----
From: David Woodhouse [mailto:dwmw2@infradead.org]
Sent: Tue, August 21, 2001 9:33 AM
To: Ashok M Padmanaban
Cc: MTD for Linux; JFFS mailing list
Subject: Re: Erase Sector Size 



ashokmp@sasken.com said:
>  Iam using intels 28F128 Strata flash, According to its data sheet its
> erase sector size is 128KB. But with 2.4.2 kernel + rmk2 (patch,diff)
> + mtd patch , the erase sector size is 256KB.

It's not configurable. You probably have two 16-bit devices arranged in a 
pair to give a 32-bit data path - which doubles the effective erase size 
because it doesn't make sense to erase one half at a time.

We just need to fix JFFS2 so it isn't so greedy.

--
dwmw2



To unsubscribe from this list: send the line "unsubscribe jffs-dev" in
the body of a message to majordomo@axis.com


[-- Attachment #2: mtd-cvs-2001-08-19-intel_bb.patch --]
[-- Type: application/octet-stream, Size: 35342 bytes --]

diff -urN mtd-cvs-2001-08-19/drivers/mtd/chips/Config.in mtd/drivers/mtd/chips/Config.in
--- mtd-cvs-2001-08-19/drivers/mtd/chips/Config.in	Sun Aug 19 08:28:51 2001
+++ mtd/drivers/mtd/chips/Config.in	Sun Aug 19 18:47:32 2001
@@ -32,6 +32,7 @@
 dep_tristate '    CFI support for Intel/Sharp Basic/Extended Commands' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_CFI
 dep_tristate '    CFI support for AMD/Fujitsu Standard Commands' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_CFI
 dep_tristate '  AMD compatible flash chip support (non-CFI)' CONFIG_MTD_AMDSTD $CONFIG_MTD
+dep_tristate '  Intel Fast Boot Block chip support (non-CFI)' CONFIG_MTD_INTELBB $CONFIG_MTD
 dep_tristate '  pre-CFI Sharp chip support' CONFIG_MTD_SHARP $CONFIG_MTD
 dep_tristate '  Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD
 dep_tristate '  Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD
diff -urN mtd-cvs-2001-08-19/drivers/mtd/chips/Makefile mtd/drivers/mtd/chips/Makefile
--- mtd-cvs-2001-08-19/drivers/mtd/chips/Makefile	Sun Aug 19 08:28:51 2001
+++ mtd/drivers/mtd/chips/Makefile	Sun Aug 19 18:47:06 2001
@@ -15,6 +15,7 @@
 # the CFI command set drivers are linked before cfi_probe.o
 
 obj-$(CONFIG_MTD)		+= chipreg.o
+obj-$(CONFIG_MTD_INTELBB)	+= intel_bb.o 
 obj-$(CONFIG_MTD_AMDSTD)	+= amd_flash.o 
 obj-$(CONFIG_MTD_CFI)		+= cfi_probe.o cfi_jedec.o
 obj-$(CONFIG_MTD_CFI_AMDSTD)	+= cfi_cmdset_0002.o
diff -urN mtd-cvs-2001-08-19/drivers/mtd/chips/intel_bb.c mtd/drivers/mtd/chips/intel_bb.c
--- mtd-cvs-2001-08-19/drivers/mtd/chips/intel_bb.c	Thu Jan  1 02:00:00 1970
+++ mtd/drivers/mtd/chips/intel_bb.c	Sun Aug 19 18:42:47 2001
@@ -0,0 +1,1201 @@
+/*
+ * MTD map driver for the old Intel Advanced BootBlock TE28F*B3 pre-CFI series
+ *
+ * Author: Alex Kremer <alex.kremer@intel.com>
+ *
+ * Code based on Jonas Holmberg's AMD code
+ *
+ * $Id$
+ *
+ * Copyright (c) 2001 Intel Co.
+ *
+ * This file is under GPL.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/flashchip.h>
+
+/* There's no limit. It exists only to avoid realloc. */
+#define MAX_BB_CHIPS 4
+
+/* flash addressing type */
+#define DEVICE_ADDRTYPE_x8	 (8 / 8)
+#define DEVICE_ADDRTYPE_x16	(16 / 8)
+#define DEVICE_ADDRTYPE_x32	(32 / 8)
+
+/* Addresses */
+#define ADDR_DEVICE_MFR		0x0000
+#define ADDR_DEVICE_ID		0x0001
+
+#define ADDR_DEVICE_GEN_CMD	0x0000  /* for general commands,
+					   any addr would do,
+					   for erase, erase-confirm
+					   use any addr within the block */
+
+
+/* Commands */
+#define CMD_READ_ARRAY		0xFF /* to any address */
+#define CMD_PROGRAM_SETUP	0x40 /* followed by addr/data */
+#define CMD_ERASE_SETUP		0x20 /* to the address within the block */
+#define CMD_RESUME		0xD0
+#define CMD_ERASE_CONFIRM	0xD0 /* to the address within the block */
+#define CMD_SUSPEND		0xB0 /* suspends both program and erase ops */
+#define CMD_READ_STATUS		0x70 /* automatically after program or erase */
+#define CMD_CLEAR_STATUS	0x50 
+#define CMD_READ_ID		0x90 
+
+/* status register bits */
+#define SR_READY		(1<<7)  /* write state machine status: 1-ready 0-busy */
+#define SR_ERASE_SUSPENDED	(1<<6)	/* erase was suspended, can resume */
+#define SR_ERASE_FAILED   	(1<<5)	/* erase op failed */
+#define SR_PROGRAM_FAILED	(1<<4)	/* program has failed */
+#define SR_VPP			(1<<3)	/* Vpp state  */
+#define SR_PROGRAM_SUSPENDED	(1<<2)	/* program was suspended, can resume */
+#define SR_BLOCK_LOCKED		(1<<1)	/* program/erase on locked block attempted */
+#define SR_RESERVED		(1<<0)	/* bah! */
+
+
+
+
+/* all the in the advanced boot block series */
+#define MFR_INTEL	0x0089
+
+#define TE28F004B3_TOP		0x00D4
+#define TE28F004B3_BOTTOM	0x00D5
+
+#define TE28F400B3_TOP		0x8894
+#define TE28F400B3_BOTTOM	0x8895
+
+#define TE28F008B3_TOP		0x00D2
+#define TE28F008B3_BOTTOM	0x00D3
+
+#define TE28F016B3_TOP		0x00D0
+#define TE28F016B3_BOTTOM	0x00D1
+
+#define TE28F160B3_TOP		0x8890
+#define TE28F160B3_BOTTOM	0x8891
+
+#define TE28F320B3_TOP		0x8896
+#define TE28F320B3_BOTTOM	0x8897
+
+#define TE28F640B3_TOP		0x8898
+#define TE28F640B3_BOTTOM	0x8899
+
+
+struct bb_flash_chip_info {
+      const __u16 mfr_id;
+      const __u16 dev_id;
+      const int  device_addrtype;
+      const char *name;
+      const u_long size; /* in bytes */
+
+#define MAX_ERASEREGIONS 4     
+      const int numeraseregions;
+      const struct mtd_erase_region_info regions[MAX_ERASEREGIONS];
+};
+
+
+
+struct bb_flash_private {
+
+      int interleave;
+      unsigned long chipshift;
+      int device_addrtype;
+      
+      int numchips;
+      struct flchip chips[0];
+};
+
+
+static int bb_flash_read(struct mtd_info *, loff_t, size_t, size_t *,
+			 u_char *);
+static int bb_flash_write(struct mtd_info *, loff_t, size_t, size_t *,
+			  const u_char *);
+static int bb_flash_erase(struct mtd_info *, struct erase_info *);
+static void bb_flash_sync(struct mtd_info *);
+static int bb_flash_suspend(struct mtd_info *);
+static void bb_flash_resume(struct mtd_info *);
+static void bb_flash_destroy(struct mtd_info *);
+static struct mtd_info *bb_flash_probe(struct map_info *map);
+
+
+static struct mtd_chip_driver bb_flash_chipdrv = {
+      probe: bb_flash_probe,
+      destroy: bb_flash_destroy,
+      name: "intel_bb_flash",
+      module: THIS_MODULE
+};
+
+static const char im_name[] = "bb_flash";
+
+static inline void dump_bits(__u32 w, int bn) {
+      int i;
+      for (i=0; i<bn; i++)
+	    printk(" %02d=%d ", i, ((w>>i)&1));
+      printk("\n");
+}
+
+
+static inline __u32 wide_read(struct map_info *map, __u32 addr)
+{
+      if (map->buswidth == 1) {
+	    return map->read8(map, addr);
+      } else if (map->buswidth == 2) {
+	    return map->read16(map, addr);
+      } else if (map->buswidth == 4) {
+	    return map->read32(map, addr);
+      }
+
+      return 0;
+}
+
+static inline void wide_write(struct map_info *map, __u32 val, __u32 addr)
+{
+      if (map->buswidth == 1) {
+	    map->write8(map, val, addr);
+      } else if (map->buswidth == 2) {
+	    map->write16(map, val, addr);
+      } else if (map->buswidth == 4) {
+	    map->write32(map, val, addr);
+      }
+}
+
+static inline __u32 make_cmd(struct map_info *map, __u32 cmd)
+{
+      const struct bb_flash_private *private = map->fldrv_priv;
+      if ((private->interleave == 2) &&
+	  (private->device_addrtype == DEVICE_ADDRTYPE_x16)) {
+	    cmd |= (cmd << 16);
+      }
+
+      return cmd;
+}
+
+#if 0
+static inline void send_unlock(struct map_info *map, unsigned long base)
+{
+      wide_write(map, (CMD_UNLOCK_DATA_1 << 16) | CMD_UNLOCK_DATA_1,
+		 base + (map->buswidth * ADDR_UNLOCK_1));
+      wide_write(map, (CMD_UNLOCK_DATA_2 << 16) | CMD_UNLOCK_DATA_2,
+		 base + (map->buswidth * ADDR_UNLOCK_2));
+}
+#endif
+
+static inline void send_cmd(struct map_info *map, unsigned long base, __u32 cmd)
+{
+      //send_unlock(map, base);
+      wide_write(map, make_cmd(map, cmd), base);
+}
+
+static inline void send_cmd_to_addr(struct map_info *map, unsigned long base,
+				    __u32 cmd, unsigned long addr)
+{
+      //send_unlock(map, base);
+      wide_write(map, make_cmd(map, cmd), base + addr);
+}
+
+static inline int check_SR(struct map_info *map, unsigned long base, __u32 bits)
+{
+      return (wide_read(map, base) & bits);
+}
+
+static inline int flash_is_busy(struct map_info *map, unsigned long base,
+				int interleave)
+{
+      return !check_SR(map, base, SR_READY);
+}
+
+
+/*
+ * Reads JEDEC manufacturer ID and device ID and returns the index of the first
+ * matching table = table entry (-1 if not found or alias for already found chip).
+ */ 
+static int probe_new_chip(struct mtd_info *mtd, __u32 base,
+			  struct flchip *chips,
+			  struct bb_flash_private *private,
+			  struct bb_flash_chip_info *table)
+{
+      __u32 mfr_id;
+      __u32 dev_id;
+      struct map_info *map = mtd->priv;
+      struct bb_flash_private temp;
+      int i;
+
+      printk("probing a new chip at 0x%ux\n", base);
+      
+      temp.interleave = 2;
+      map->fldrv_priv = &temp;
+
+      /* Enter autoselect mode. */
+      send_cmd(map, base, CMD_CLEAR_STATUS);
+      send_cmd(map, base, CMD_READ_ID);
+
+      printk("after command\n");
+      
+      mfr_id = wide_read(map, base + (map->buswidth * ADDR_DEVICE_MFR));
+      dev_id = wide_read(map, base + (map->buswidth * ADDR_DEVICE_ID));
+
+      if ((map->buswidth == 4) && ((mfr_id >> 16) == (mfr_id & 0xffff)) &&
+	  ((dev_id >> 16) == (dev_id & 0xffff))) {
+	    mfr_id &= 0xffff;
+	    dev_id &= 0xffff;
+      } else {
+	    temp.interleave = 1;
+      }
+
+      printk("after determining interleave\n");
+
+      
+      for (i = 0; table[i].name; i++) {
+	    printk("testing chips: is it [%d] %s?\n", i, table[i].name);
+	    if ((mfr_id == table[i].mfr_id) &&
+		(dev_id == table[i].dev_id)) {
+		  if (private->numchips) {
+#if 0
+			int j;
+
+				/* Is this an alias for an already found chip?
+				 * In that case that chip should be in
+				 * autoselect mode now.
+				 */
+
+			for (j = 0; j < private->numchips; j++) {
+			      __u32 mfr_id_other;
+			      __u32 dev_id_other;
+
+			      mfr_id_other =
+				    wide_read(map, private->chips[j].start +
+					      (map->buswidth *
+					       ADDR_DEVICE_MFR
+					       ));
+			      dev_id_other =
+				    wide_read(map, private->chips[j].start +
+					      (map->buswidth *
+					       ADDR_DEVICE_ID));
+			      if (temp.interleave == 2) {
+				    mfr_id_other &= 0xffff;
+				    dev_id_other &= 0xffff;
+			      }
+			      if ((mfr_id_other == mfr_id) &&
+				  (dev_id_other == dev_id)) {
+
+				    /* Exit autoselect mode. */
+				    send_cmd(map, base,
+					     CMD_READ_ARRAY);
+
+				    return -1;
+			      }
+			}
+#endif
+			
+			if (private->numchips == MAX_BB_CHIPS) {
+			      printk(KERN_WARNING
+				     "%s: Too many flash chips "
+				     "detected. Increase "
+				     "MAX_BB_CHIPS from %d.\n",
+				     map->name, MAX_BB_CHIPS);
+
+			      return -1;
+			}
+
+			chips[private->numchips].start = base;
+			chips[private->numchips].state = FL_READY;
+			chips[private->numchips].mutex = &chips[private->numchips]._spinlock;
+			private->numchips++;
+		  }
+
+		  printk("%s: Found %d x %ldMiB %s at 0x%x -- %d chips found so far\n",
+			 map->name,
+			 temp.interleave, (table[i].size)/(1024*1024),
+			 table[i].name, base,
+			 private->numchips);
+
+		  mtd->size += table[i].size * temp.interleave;
+		  mtd->numeraseregions += table[i].numeraseregions;
+
+		  printk("that's it\n");
+		  
+		  break;
+	    }
+      }
+
+      printk("finished scanning for chip type\n");
+      
+      /* Exit autoselect mode. */
+      send_cmd(map, base, CMD_READ_ARRAY);
+
+      if (!(table[i].name)) {
+	    printk(KERN_DEBUG "%s: unknown flash device at 0x%x, "
+		   "mfr id 0x%x, dev id 0x%x\n", map->name,
+		   base, mfr_id, dev_id);
+	    map->fldrv_priv = NULL;
+
+	    return -1;
+      }
+
+      printk("ok my job is finished\n");
+      
+      private->device_addrtype = table[i].device_addrtype;
+      private->interleave = temp.interleave;
+
+      return i;
+}
+
+
+
+static struct mtd_info *bb_flash_probe(struct map_info *map)
+{
+      /* Keep this table on the stack so that it gets deallocated after the
+       * probe is done.
+	 */
+
+
+      struct bb_flash_chip_info table[] = {
+	    /* need to fill in the others */
+	    
+	    
+#define expandID(id) mfr_id: MFR_INTEL, dev_id: id, name: "Intel " #id
+#define expandADDRTYPE(t) device_addrtype: DEVICE_ADDRTYPE_ ## t
+	    
+	    
+	    { expandID(TE28F320B3_TOP),
+	      expandADDRTYPE(x16),
+	      size: 0x0400000, /* 4MB in bytes */
+	      numeraseregions: 2,
+	      regions: {
+		    [0] = { offset: 0x000000, erasesize: 0x10000, numblocks: 63 },
+		    [1] = { offset: 0x1F8000, erasesize: 0x02000, numblocks:  8 },
+	      }
+	    },
+	    
+	    { expandID(TE28F320B3_BOTTOM),
+	      expandADDRTYPE(x16),
+	      size: 0x0400000, /* 4MB in bytes */
+	      numeraseregions: 2,
+	      regions: {
+		    [0] = { offset: 0x000000, erasesize: 0x02000, numblocks:  8 },
+		    [1] = { offset: 0x008000, erasesize: 0x10000, numblocks: 63 },
+	      }
+	    },
+	    
+	    { 0 },
+      };	    
+      
+      struct mtd_info *mtd;
+
+      struct bb_flash_private temp;
+      struct bb_flash_private *private;
+      
+      u_long size;
+      unsigned long base;
+      int i, table_pos[MAX_BB_CHIPS];
+      struct flchip chips[MAX_BB_CHIPS];
+      int reg_idx;
+      int offset;
+
+      printk("Probing flash\n");
+      
+      mtd = (struct mtd_info*)kmalloc(sizeof(*mtd), GFP_KERNEL);
+      if (!mtd) {
+	    printk(KERN_WARNING
+		   "%s: kmalloc failed for info structure\n", map->name);
+	    return NULL;
+      }
+      memset(mtd, 0, sizeof(*mtd));
+      mtd->priv = map;
+
+      memset(&temp, 0, sizeof(temp));
+      printk("%s: Probing for BB compatible flash...\n", map->name);
+
+      if ((table_pos[0] = probe_new_chip(mtd, 0, NULL, &temp, table))
+	  == -1) {
+	    printk(KERN_WARNING
+	     "%s: Found no BB compatible device at location zero\n",
+	     map->name);
+	    kfree(mtd);
+	    
+	    return NULL;
+      }
+
+      printk("one chip found at base 0\n");
+      
+      chips[0].start = 0;
+      chips[0].state = FL_READY;
+      chips[0].mutex = &chips[0]._spinlock;
+      temp.numchips = 1;
+
+      
+      for (size = mtd->size; size > 1; size >>= 1) {
+	    temp.chipshift++;
+      }
+      switch (temp.interleave) {
+	 case 2:
+	       temp.chipshift += 1;
+	       break;
+	 case 4:
+	       temp.chipshift += 2;
+	       break;
+      }
+
+
+      printk("before scanning the rest of the ROM space for chips\n");
+      /* Find out if there are any more chips in the map. */
+      for (base = (1 << temp.chipshift);
+	   base < map->size;
+	   base += (1 << temp.chipshift)) {
+	    int numchips = temp.numchips;
+	    printk("scanning at %lux, numchip so far is %d\n", base, numchips);
+	    table_pos[numchips] = probe_new_chip(mtd, base, chips, &temp, table);
+      }
+
+
+      printk("finished scanning\n");
+      mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) *
+				  mtd->numeraseregions, GFP_KERNEL);
+      if (!mtd->eraseregions) { 
+	    printk(KERN_WARNING "%s: Failed to allocate "
+		   "memory for MTD erase region info\n", map->name);
+	    kfree(mtd);
+	    map->fldrv_priv = NULL;
+	    return 0;
+      }
+
+      printk("updating erase regions for chips mtd->numeraseregions = %d\n", mtd->numeraseregions);
+      
+      reg_idx = 0;
+      offset = 0;
+      for (i = 0; i < temp.numchips; i++) {
+	    int dev_size;
+	    int j;
+
+	    printk("dealing with chip number %d, offset = %d\n", i, offset);
+	    
+	    dev_size = 0;
+	    for (j = 0; j < table[table_pos[i]].numeraseregions; j++) {
+		  printk("reg_idx = %d, dealing with eraseregion %d of chip %d\n", reg_idx, j, i);
+		  
+		  mtd->eraseregions[reg_idx].offset = offset +
+			(table[table_pos[i]].regions[j].offset *
+			 temp.interleave);
+		  mtd->eraseregions[reg_idx].erasesize =
+			table[table_pos[i]].regions[j].erasesize *
+			temp.interleave;
+		  mtd->eraseregions[reg_idx].numblocks =
+			table[table_pos[i]].regions[j].numblocks;
+		  if (mtd->erasesize <
+		      mtd->eraseregions[reg_idx].erasesize) {
+			mtd->erasesize =
+			      mtd->eraseregions[reg_idx].erasesize;
+		  }
+		  dev_size += mtd->eraseregions[reg_idx].erasesize *
+			mtd->eraseregions[reg_idx].numblocks;
+		  reg_idx++;
+	    }
+	    offset += dev_size;
+      }
+
+      printk("finished with eraseregion bits\n");
+      
+      mtd->type = MTD_NORFLASH;
+      mtd->flags = MTD_CAP_NORFLASH;
+      mtd->name = map->name;
+      mtd->erase = bb_flash_erase;	
+      mtd->read = bb_flash_read;	
+      mtd->write = bb_flash_write;	
+      mtd->sync = bb_flash_sync;	
+      mtd->suspend = bb_flash_suspend;	
+      mtd->resume = bb_flash_resume;	
+
+      private = kmalloc(sizeof(*private) + (sizeof(struct flchip) * temp.numchips), GFP_KERNEL);
+      if (!private) {
+	    printk(KERN_WARNING
+		   "%s: kmalloc failed for private structure\n", map->name);
+	    kfree(mtd->eraseregions);
+	    kfree(mtd);
+	    map->fldrv_priv = NULL;
+	    return NULL;
+      }
+      memcpy(private, &temp, sizeof(temp));
+      memcpy(private->chips, chips, sizeof(struct flchip) * private->numchips);
+
+      for (i = 0; i < private->numchips; i++) {
+	    init_waitqueue_head(&private->chips[i].wq);
+	    spin_lock_init(&private->chips[i]._spinlock);
+      }
+
+      map->fldrv_priv = private;
+
+      map->fldrv = &bb_flash_chipdrv;
+
+      MOD_INC_USE_COUNT;
+
+      printk("FLASH: found %d chips, interleave = %d,"
+	     "chipshift = %lu, device_addrtype = %u\n, erasesize=%d",
+	     private->numchips, private->interleave,
+	     private->chipshift, private->device_addrtype*8, mtd->erasesize);
+	     
+
+      return mtd;
+}
+
+
+
+static inline int read_one_chip(struct map_info *map, struct flchip *chip,
+				loff_t adr, size_t len, u_char *buf)
+{
+      DECLARE_WAITQUEUE(wait, current);
+      unsigned long timeo = jiffies + HZ;
+
+      send_cmd(map, chip->start, CMD_READ_ARRAY);
+      
+ retry:
+      spin_lock_bh(chip->mutex);
+
+      if (chip->state != FL_READY){
+	    printk(KERN_INFO "%s: waiting for chip to read, state = %d\n",
+		   map->name, chip->state);
+	    set_current_state(TASK_UNINTERRUPTIBLE);
+	    add_wait_queue(&chip->wq, &wait);
+                
+	    spin_unlock_bh(chip->mutex);
+
+	    schedule();
+	    remove_wait_queue(&chip->wq, &wait);
+
+	    if(signal_pending(current)) {
+		  return -EINTR;
+	    }
+
+	    timeo = jiffies + HZ;
+
+	    goto retry;
+      }	
+
+      adr += chip->start;
+
+      chip->state = FL_READY;
+
+      map->copy_from(map, buf, adr, len);
+
+      wake_up(&chip->wq);
+      spin_unlock_bh(chip->mutex);
+
+      return 0;
+}
+
+
+
+static int bb_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
+			 size_t *retlen, u_char *buf)
+{
+      struct map_info *map = mtd->priv;
+      struct bb_flash_private *private = map->fldrv_priv;
+      unsigned long ofs;
+      int chipnum;
+      int ret = 0;
+
+      if ((from + len) > mtd->size) {
+	    printk(KERN_WARNING "%s: read request past end of device "
+		   "(0x%lx)\n", map->name, (unsigned long)from + len);
+
+	    return -EINVAL;
+      }
+
+      /* Offset within the first chip that the first read should start. */
+      chipnum = (from >> private->chipshift);
+      ofs = from - (chipnum <<  private->chipshift);
+
+      *retlen = 0;
+
+      while (len) {
+	    unsigned long this_len;
+
+	    if (chipnum >= private->numchips) {
+		  break;
+	    }
+
+	    if ((len + ofs - 1) >> private->chipshift) {
+		  this_len = (1 << private->chipshift) - ofs;
+	    } else {
+		  this_len = len;
+	    }
+
+	    ret = read_one_chip(map, &private->chips[chipnum], ofs,
+				this_len, buf);
+	    if (ret) {
+		  break;
+	    }
+
+	    *retlen += this_len;
+	    len -= this_len;
+	    buf += this_len;
+
+	    ofs = 0;
+	    chipnum++;
+      }
+
+      return ret;
+}
+
+
+
+static int write_one_word(struct map_info *map, struct flchip *chip,
+			  unsigned long adr, __u32 datum)
+{
+      unsigned long timeo = jiffies + HZ;
+      struct bb_flash_private *private = map->fldrv_priv;
+      DECLARE_WAITQUEUE(wait, current);
+      int ret = 0;
+      int times_left;
+
+#if 0      
+      if (((adr + chip->start ) % 1024) < 4)
+	    printk("attempt to write 0x%x at 0x%lx\n", datum, adr + chip->start);
+      return 0;
+#endif      
+      
+ retry:
+      spin_lock_bh(chip->mutex);
+
+      if (chip->state != FL_READY){
+	    printk("%s: waiting for chip to write, state = %d\n",
+		   map->name, chip->state);
+	    set_current_state(TASK_UNINTERRUPTIBLE);
+	    add_wait_queue(&chip->wq, &wait);
+                
+	    spin_unlock_bh(chip->mutex);
+
+	    schedule();
+	    remove_wait_queue(&chip->wq, &wait);
+	    printk(KERN_INFO "%s: woke up to write\n", map->name);
+	    if(signal_pending(current))
+		  return -EINTR;
+
+	    timeo = jiffies + HZ;
+
+	    goto retry;
+      }	
+
+      chip->state = FL_WRITING;
+
+      adr += chip->start;
+      ENABLE_VPP(map);
+      send_cmd(map, chip->start, CMD_PROGRAM_SETUP);
+      wide_write(map, datum, adr);
+
+      times_left = 500000;
+      while (times_left-- && flash_is_busy(map, chip->start,
+					   private->interleave)) {
+	    if (current->need_resched) {
+		  spin_unlock_bh(chip->mutex);
+		  schedule();
+		  spin_lock_bh(chip->mutex);
+	    }
+      }
+      
+      DISABLE_VPP(map);
+      
+      if (!times_left) {
+	    printk(KERN_WARNING "%s: write to 0x%lx timed out!\n",
+		   map->name, adr);
+	    ret = -EIO;
+      } else {
+#if 0	    
+	    __u32 verify;
+
+	    send_cmd(map, chip->start, CMD_READ_ARRAY);
+	    if ((verify = wide_read(map, adr)) != datum) {
+		  printk(KERN_WARNING "%s: write to 0x%lx failed. "
+			 "datum = %x, verify = %x\n",
+			 map->name, adr, datum, verify);
+		  ret = -EIO;
+	    } else {
+		  printk("wrote %d at 0x%lx: success\n", datum, adr);
+	    }
+#endif	    
+      }
+
+
+      chip->state = FL_READY;
+      wake_up(&chip->wq);
+      spin_unlock_bh(chip->mutex);
+
+      return ret;
+}
+
+
+
+static int bb_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
+			  size_t *retlen, const u_char *buf)
+{
+      struct map_info *map = mtd->priv;
+      struct bb_flash_private *private = map->fldrv_priv;
+      int ret = 0;
+      int chipnum;
+      unsigned long ofs;
+      unsigned long chipstart;
+
+      *retlen = 0;
+      if (!len) {
+	    return 0;
+      }
+
+      chipnum = to >> private->chipshift;
+      ofs = to  - (chipnum << private->chipshift);
+      chipstart = private->chips[chipnum].start;
+
+      /* If it's not bus-aligned, do the first byte write. */
+      if (ofs & (map->buswidth - 1)) {
+	    unsigned long bus_ofs = ofs & ~(map->buswidth - 1);
+	    int i = ofs - bus_ofs;
+	    int n = 0;
+	    u_char tmp_buf[4];
+	    __u32 datum;
+
+	    map->copy_from(map, tmp_buf,
+			   bus_ofs + private->chips[chipnum].start,
+			   map->buswidth);
+	    while (len && i < map->buswidth)
+		  tmp_buf[i++] = buf[n++], len--;
+
+	    if (map->buswidth == 2) {
+		  datum = *(__u16*)tmp_buf;
+	    } else if (map->buswidth == 4) {
+		  datum = *(__u32*)tmp_buf;
+	    } else {
+		  return -EINVAL;  /* should never happen, but be safe */
+	    }
+
+	    ret = write_one_word(map, &private->chips[chipnum], bus_ofs,
+				 datum);
+	    if (ret) {
+		  return ret;
+	    }
+		
+	    ofs += n;
+	    buf += n;
+	    (*retlen) += n;
+
+	    if (ofs >> private->chipshift) {
+		  chipnum++;
+		  ofs = 0;
+		  if (chipnum == private->numchips) {
+			return 0;
+		  }
+	    }
+      }
+	
+      /* We are now aligned, write as much as possible. */
+      while(len >= map->buswidth) {
+	    __u32 datum;
+
+	    if (map->buswidth == 1) {
+		  datum = *(__u8*)buf;
+	    } else if (map->buswidth == 2) {
+		  datum = *(__u16*)buf;
+	    } else if (map->buswidth == 4) {
+		  datum = *(__u32*)buf;
+	    } else {
+		  return -EINVAL;
+	    }
+
+	    ret = write_one_word(map, &private->chips[chipnum], ofs, datum);
+
+	    if (ret) {
+		  return ret;
+	    }
+
+	    ofs += map->buswidth;
+	    buf += map->buswidth;
+	    (*retlen) += map->buswidth;
+	    len -= map->buswidth;
+
+	    if (ofs >> private->chipshift) {
+		  chipnum++;
+		  ofs = 0;
+		  if (chipnum == private->numchips) {
+			return 0;
+		  }
+		  chipstart = private->chips[chipnum].start;
+	    }
+      }
+
+      if (len & (map->buswidth - 1)) {
+	    int i = 0, n = 0;
+	    u_char tmp_buf[2];
+	    __u32 datum;
+
+	    map->copy_from(map, tmp_buf,
+			   ofs + private->chips[chipnum].start,
+			   map->buswidth);
+	    while (len--) {
+		  tmp_buf[i++] = buf[n++];
+	    }
+
+	    if (map->buswidth == 2) {
+		  datum = *(__u16*)tmp_buf;
+	    } else if (map->buswidth == 4) {
+		  datum = *(__u32*)tmp_buf;
+	    } else {
+		  return -EINVAL;  /* should never happen, but be safe */
+	    }
+
+	    ret = write_one_word(map, &private->chips[chipnum], ofs, datum);
+
+	    if (ret) {
+		  return ret;
+	    }
+		
+	    (*retlen) += n;
+      }
+
+      return 0;
+}
+
+
+
+static inline int erase_one_block(struct map_info *map, struct flchip *chip,
+				  unsigned long adr, u_long size)
+{
+      unsigned long timeo = jiffies + HZ;
+      struct bb_flash_private *private = map->fldrv_priv;
+      DECLARE_WAITQUEUE(wait, current);
+
+      //printk("attempt to erase block at 0x%lx (size = %ld)\n", adr + chip->start, size);
+      //return 0;
+      
+ retry:
+      spin_lock_bh(chip->mutex);
+
+      if (chip->state != FL_READY){
+	    set_current_state(TASK_UNINTERRUPTIBLE);
+	    add_wait_queue(&chip->wq, &wait);
+                
+	    spin_unlock_bh(chip->mutex);
+
+	    schedule();
+	    remove_wait_queue(&chip->wq, &wait);
+
+	    if (signal_pending(current)) {
+		  return -EINTR;
+	    }
+
+	    timeo = jiffies + HZ;
+
+	    goto retry;
+      }	
+
+      chip->state = FL_ERASING;
+
+      adr += chip->start;
+      ENABLE_VPP(map);
+      send_cmd(map, chip->start, CMD_ERASE_SETUP);
+      send_cmd_to_addr(map, chip->start, CMD_ERASE_CONFIRM, adr);
+	
+      timeo = jiffies + (HZ * 5);
+
+      spin_unlock_bh(chip->mutex);
+      schedule_timeout(HZ);
+      spin_lock_bh(chip->mutex);
+	
+      while (flash_is_busy(map, chip->start, private->interleave)) {
+
+	    if (chip->state != FL_ERASING) {
+		  /* Someone's suspended the erase. Sleep */
+		  set_current_state(TASK_UNINTERRUPTIBLE);
+		  add_wait_queue(&chip->wq, &wait);
+			
+		  spin_unlock_bh(chip->mutex);
+		  printk(KERN_INFO "%s: erase suspended. Sleeping\n",
+			 map->name);
+		  schedule();
+		  remove_wait_queue(&chip->wq, &wait);
+			
+		  if (signal_pending(current)) {
+			return -EINTR;
+		  }
+			
+		  timeo = jiffies + (HZ*2); /* FIXME */
+		  spin_lock_bh(chip->mutex);
+		  continue;
+	    }
+
+	    /* OK Still waiting */
+	    if (time_after(jiffies, timeo)) {
+		  chip->state = FL_READY;
+		  spin_unlock_bh(chip->mutex);
+		  printk(KERN_WARNING "%s: waiting for erase to complete "
+			 "timed out.\n", map->name);
+		  DISABLE_VPP(map);
+
+		  return -EIO;
+	    }
+		
+	    /* Latency issues. Drop the lock, wait a while and retry */
+	    spin_unlock_bh(chip->mutex);
+
+	    if (current->need_resched)
+		  schedule();
+	    else
+		  udelay(1);
+		
+	    spin_lock_bh(chip->mutex);
+      }
+
+      DISABLE_VPP(map);
+
+      send_cmd(map, chip->start, CMD_READ_ARRAY);
+      
+      /* Verify every single word */
+      {
+	    int address;
+	    int error = 0;
+	    __u16 verify;
+
+	    for (address = adr; address < (adr + size); address++) {
+		  if ((verify = map->read16(map, address)) != 0xFFFF) {
+			error = 1;
+			break;
+		  }
+	    }
+	    if (error) {
+		  chip->state = FL_READY;
+		  spin_unlock_bh(chip->mutex);
+		  printk(KERN_WARNING
+			 "%s: verify error at 0x%x, size %ld.\n",
+			 map->name, address, size);
+		  DISABLE_VPP(map);
+
+		  return -EIO;
+	    } else {
+		  //printk("erased block at 0x%lx\n", adr);
+	    }
+      }
+	
+      chip->state = FL_READY;
+      wake_up(&chip->wq);
+      spin_unlock_bh(chip->mutex);
+
+      return 0;
+}
+
+
+
+static int bb_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+      struct map_info *map = mtd->priv;
+      struct bb_flash_private *private = map->fldrv_priv;
+      unsigned long adr, len;
+      int chipnum;
+      int ret = 0;
+      int i;
+      int first;
+      struct mtd_erase_region_info *regions = mtd->eraseregions;
+
+      if (instr->addr > mtd->size) {
+	    return -EINVAL;
+      }
+
+      if ((instr->len + instr->addr) > mtd->size) {
+	    return -EINVAL;
+      }
+
+      /* Check that both start and end of the requested erase are
+       * aligned with the erasesize at the appropriate addresses.
+       */
+
+      i = 0;
+
+      /* Skip all erase regions which are ended before the start of
+	 the requested erase. Actually, to save on the calculations,
+	 we skip to the first erase region which starts after the
+	 start of the requested erase, and then go back one.
+      */
+
+      while ((i < mtd->numeraseregions) &&
+	     (instr->addr >= regions[i].offset)) {
+	    i++;
+      }
+      i--;
+
+      /* OK, now i is pointing at the erase region in which this
+       * erase request starts. Check the start of the requested
+       * erase range is aligned with the erase size which is in
+       * effect here.
+       */
+
+      if (instr->addr & (regions[i].erasesize-1)) {
+	    return -EINVAL;
+      }
+
+      /* Remember the erase region we start on. */
+
+      first = i;
+
+      /* Next, check that the end of the requested erase is aligned
+       * with the erase region at that address.
+       */
+
+      while ((i < mtd->numeraseregions) && 
+	     ((instr->addr + instr->len) >= regions[i].offset)) {
+	    i++;
+      }
+
+      /* As before, drop back one to point at the region in which
+       * the address actually falls.
+       */
+
+      i--;
+
+      if ((instr->addr + instr->len) & (regions[i].erasesize-1)) {
+	    return -EINVAL;
+      }
+
+      chipnum = instr->addr >> private->chipshift;
+      adr = instr->addr - (chipnum << private->chipshift);
+      len = instr->len;
+
+      i = first;
+
+      while (len) {
+	    ret = erase_one_block(map, &private->chips[chipnum], adr,
+				  regions[i].erasesize);
+
+	    if (ret) {
+		  return ret;
+	    }
+
+	    adr += regions[i].erasesize;
+	    len -= regions[i].erasesize;
+
+	    if ((adr % (1 << private->chipshift)) ==
+		((regions[i].offset + (regions[i].erasesize *
+				       regions[i].numblocks))
+		 % (1 << private->chipshift))) {
+		  i++;
+	    }
+
+	    if (adr >> private->chipshift) {
+		  adr = 0;
+		  chipnum++;
+		  if (chipnum >= private->numchips) {
+			break;
+		  }
+	    }
+      }
+		
+      instr->state = MTD_ERASE_DONE;
+      if (instr->callback) {
+	    instr->callback(instr);
+      }
+	
+      return 0;
+}
+
+
+
+static void bb_flash_sync(struct mtd_info *mtd)
+{
+      struct map_info *map = mtd->priv;
+      struct bb_flash_private *private = map->fldrv_priv;
+      int i;
+      struct flchip *chip;
+      int ret = 0;
+      DECLARE_WAITQUEUE(wait, current);
+
+      for (i = 0; !ret && (i < private->numchips); i++) {
+	    chip = &private->chips[i];
+
+       retry:
+	    spin_lock_bh(chip->mutex);
+
+	    switch(chip->state) {
+	       case FL_READY:
+	       case FL_STATUS:
+	       case FL_CFI_QUERY:
+	       case FL_JEDEC_QUERY:
+		     chip->oldstate = chip->state;
+		     chip->state = FL_SYNCING;
+		     /* No need to wake_up() on this state change - 
+		      * as the whole point is that nobody can do anything
+		      * with the chip now anyway.
+		      */
+	       case FL_SYNCING:
+		     spin_unlock_bh(chip->mutex);
+		     break;
+
+	       default:
+		     /* Not an idle state */
+		     add_wait_queue(&chip->wq, &wait);
+			
+		     spin_unlock_bh(chip->mutex);
+
+		     schedule();
+
+		     remove_wait_queue(&chip->wq, &wait);
+			
+		     goto retry;
+	    }
+      }
+
+      /* Unlock the chips again */
+      for (i--; i >= 0; i--) {
+	    chip = &private->chips[i];
+
+	    spin_lock_bh(chip->mutex);
+		
+	    if (chip->state == FL_SYNCING) {
+		  chip->state = chip->oldstate;
+		  wake_up(&chip->wq);
+	    }
+	    spin_unlock_bh(chip->mutex);
+      }
+}
+
+
+
+static int bb_flash_suspend(struct mtd_info *mtd)
+{
+      printk("bb_flash_suspend(): not implemented!\n");
+      return -EINVAL;
+}
+
+
+
+static void bb_flash_resume(struct mtd_info *mtd)
+{
+      printk("bb_flash_resume(): not implemented!\n");
+}
+
+
+
+static void bb_flash_destroy(struct mtd_info *mtd)
+{
+      struct map_info *map = mtd->priv;
+      struct bb_flash_private *private = map->fldrv_priv;
+      kfree(private);
+}
+
+int __init bb_flash_init(void)
+{
+      register_mtd_chip_driver(&bb_flash_chipdrv);
+      return 0;
+}
+
+void __exit bb_flash_exit(void)
+{
+      unregister_mtd_chip_driver(&bb_flash_chipdrv);
+}
+
+module_init(bb_flash_init);
+module_exit(bb_flash_exit);
diff -urN mtd-cvs-2001-08-19/drivers/mtd/maps/Config.in mtd/drivers/mtd/maps/Config.in
--- mtd-cvs-2001-08-19/drivers/mtd/maps/Config.in	Sun Aug 19 08:28:51 2001
+++ mtd/drivers/mtd/maps/Config.in	Sun Aug 19 18:55:23 2001
@@ -41,7 +41,7 @@
   dep_tristate '  CFI Flash device mapped on ARM Integrator/P720T' CONFIG_MTD_ARM_INTEGRATOR $CONFIG_MTD_CFI $CONFIG_ARM
   dep_tristate '  Cirrus CDB89712 evaluation board mappings' CONFIG_MTD_CDB89712 $CONFIG_MTD_CFI $CONFIG_ARCH_CDB89712
   dep_tristate '  CFI Flash device mapped on StrongARM SA11x0' CONFIG_MTD_SA1100 $CONFIG_MTD_CFI $CONFIG_ARCH_SA1100 $CONFIG_MTD_PARTITIONS
-  dep_tristate '  CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE $CONFIG_MTD_PARTITIONS
+  dep_tristate '  CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_INTELBB $CONFIG_ARCH_FOOTBRIDGE $CONFIG_MTD_PARTITIONS
   dep_tristate '  CFI Flash device mapped on the XScale IQ80310 board' CONFIG_MTD_IQ80310 $CONFIG_MTD_CFI $CONFIG_XSCALE_IQ80310
 fi
 endmenu
diff -urN mtd-cvs-2001-08-19/drivers/mtd/maps/dc21285.c mtd/drivers/mtd/maps/dc21285.c
--- mtd-cvs-2001-08-19/drivers/mtd/maps/dc21285.c	Sat Jul 14 03:59:17 2001
+++ mtd/drivers/mtd/maps/dc21285.c	Sun Aug 19 18:41:12 2001
@@ -52,7 +52,10 @@
 void dc21285_write16(struct map_info *map, __u16 d, unsigned long adr)
 {
 	*CSR_ROMWRITEREG = adr;
-	adr &= ~1;
+	/*Original:
+	  adr &= ~1;
+	*/
+	adr &= ~3;
 	*(__u16*)(map->map_priv_1 + adr) = d;
 }
 
@@ -137,7 +140,7 @@
 		return -EIO;
 	}
 
-	mymtd = do_map_probe("cfi_probe", &dc21285_map);
+	mymtd = do_map_probe("intel_bb_flash", &dc21285_map);
 	if (mymtd) {
 		int nrparts;
 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Erase Sector Size
@ 2001-08-21 11:44 Ashok M Padmanaban
  2001-08-21  6:33 ` David Woodhouse
  0 siblings, 1 reply; 6+ messages in thread
From: Ashok M Padmanaban @ 2001-08-21 11:44 UTC (permalink / raw)
  To: MTD for Linux, JFFS mailing list

[-- Attachment #1: Type: text/plain, Size: 464 bytes --]

Hi,
 Iam using intels 28F128 Strata flash, According to its data sheet
its erase sector size is 128KB.
But with 2.4.2 kernel + rmk2 (patch,diff) + mtd patch , the erase sector
size
is 256KB.
As 5 sectors have to be reserved for garbage collection in jffs2. When i
make a
1MB partition iam left with no space on the jffs2 partition.
How can i make the erase sector size to 128KB, is this configurable and
if so
what should i do change it.

thanks and regards
ashok

[-- Attachment #2: Card for Ashok M Padmanaban --]
[-- Type: text/x-vcard, Size: 356 bytes --]

begin:vcard 
n:.m.padmanabhan;ashok
tel;work:5281461/5281229 ext 3096
x-mozilla-html:FALSE
org:sasken communication technologies ltd;internt access solutions
version:2.1
email;internet:ashokmp@sasken.com
title:software engineer
adr;quoted-printable:;;3008,12 th B cross,=0D=0Aindranagar	;banglore;;;india
x-mozilla-cpt:;0
fn:ashok .m.padmanabhan
end:vcard

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Erase Sector Size
       [not found] <20010831124235.27912.qmail@mailweb26.rediffmail.com>
@ 2001-08-31 12:50 ` Abraham vd Merwe
  0 siblings, 0 replies; 6+ messages in thread
From: Abraham vd Merwe @ 2001-08-31 12:50 UTC (permalink / raw)
  To: ashok mp; +Cc: MTD for Linux

[-- Attachment #1: Type: text/plain, Size: 1040 bytes --]

Hi ashok!

> iam using 2.4.2 rmk2 np1 kernel
> while make menuconfig under
> *MTD
> *RAM/ROM(Flash Chip Driver)
>  () Flash cmd/Qurey data swapping
> 
> what should i select here (iam using assabet board)
> ()NO
> ()BIG_ENDIAN_BYTE
> ()LITTLE_ENDIAN_BYTE.

Have you read Vipin's mtd-jffs HOWTO yet? It covers these kind of questions.
You can also ask around on the MTD mailinglist.

I don't have a Assabet board myself, but iirc it uses Intel StrataFlash, so
you want CFI support, it's corresponding mapping driver, etc. etc.

-- 

Regards
 Abraham

Tuesday After Lunch is the cosmic time of the week.

__________________________________________________________
 Abraham vd Merwe - 2d3D, Inc.

 Device Driver Development, Outsourcing, Embedded Systems

  Cell: +27 82 565 4451         Snailmail:
   Tel: +27 21 761 7549            Block C, Antree Park
   Fax: +27 21 761 7648            Doncaster Road
 Email: abraham@2d3d.co.za         Kenilworth, 7700
  Http: http://www.2d3d.com        South Africa


[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Erase sector size
@ 2002-12-23 18:19 Rekha Nagananda
  0 siblings, 0 replies; 6+ messages in thread
From: Rekha Nagananda @ 2002-12-23 18:19 UTC (permalink / raw)
  To: linux-mtd, jffs-dev; +Cc: rekhanaga

Hi,

I am using prpmc815 Motorola's PMC board, it has two 16MB 28F128 Intel 
flash. According to Intel's data sheet sector size is 128KB. Does anybody 
know - when we erase a sector does it erase 128KB or 256KB? (since prpmc815 
has 2 flash chips).

Thanks,
Rekha




_________________________________________________________________
MSN 8 with e-mail virus protection service: 3 months FREE*. 
http://join.msn.com/?page=features/virus&xAPID=42&PS=47575&PI=7324&DI=7474&SU= 
http://www.hotmail.msn.com/cgi-bin/getmsg&HL=1216hotmailtaglines_eliminateviruses_3mf

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: Erase sector size
@ 2002-12-30 12:47 Paul Nash
  0 siblings, 0 replies; 6+ messages in thread
From: Paul Nash @ 2002-12-30 12:47 UTC (permalink / raw)
  To: 'Rekha Nagananda', linux-mtd

(un-cross-posting...)

I think that would depend on how the chips are connected.  Assuming they're
16 bits wide, if they're configured as two banks of 16bit wide memory, then
you would erase a 128KB block.  If they're configured in parallel as a
composite 32-bit wide device, then you would erase 256KB blocks.

-----Original Message-----
From: Rekha Nagananda [mailto:rekhanaga@hotmail.com] 
Sent: Monday, December 23, 2002 10:19 AM
To: linux-mtd@lists.infradead.org; jffs-dev@axis.com
Cc: rekhanaga@hotmail.com
Subject: Erase sector size


Hi,

I am using prpmc815 Motorola's PMC board, it has two 16MB 28F128 Intel 
flash. According to Intel's data sheet sector size is 128KB. Does anybody 
know - when we erase a sector does it erase 128KB or 256KB? (since prpmc815 
has 2 flash chips).

Thanks,
Rekha




_________________________________________________________________
MSN 8 with e-mail virus protection service: 3 months FREE*. 
http://join.msn.com/?page=features/virus&xAPID=42&PS=47575&PI=7324&DI=7474&S
U= 
http://www.hotmail.msn.com/cgi-bin/getmsg&HL=1216hotmailtaglines_eliminatevi
ruses_3mf


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2002-12-30 12:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-08-21 11:44 Erase Sector Size Ashok M Padmanaban
2001-08-21  6:33 ` David Woodhouse
  -- strict thread matches above, loose matches on Subject: below --
2002-12-30 12:47 Erase sector size Paul Nash
2002-12-23 18:19 Rekha Nagananda
     [not found] <20010831124235.27912.qmail@mailweb26.rediffmail.com>
2001-08-31 12:50 ` Erase Sector Size Abraham vd Merwe
2001-08-21 11:37 Kremer, Alex

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox