public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* New Intel chip with CFIext version 1.3 not working.
@ 2001-11-14  9:53 Jarkko Lavinen
       [not found] ` <2478.1005732188@redhat.com>
  2001-11-22 15:15 ` Jarkko Lavinen
  0 siblings, 2 replies; 5+ messages in thread
From: Jarkko Lavinen @ 2001-11-14  9:53 UTC (permalink / raw)
  To: MTD List

Is anybody using Intel chips with extended CFI query version 1.3?

Current version of the cfi_cmdset_0001.c rejects the chip and accepts
only the extended CFI versions 1.0, 1.1, and 1.2. The chip I am trying
to get working is Intel's 28F640W18 and its datasheet is available
from http://www.intel.com/design/flash/datashts/index.htm. The
extended query is specified at the page 71 of the datasheet.

I tried to modify the driver by allowing also the extemded CFI version
1.3. After that the chip was accepted but sectors were locked and
writes failed The unlock function unlocked only the first sector, not 
the whole region requested.

I modified the function cfi_intelext_unlock() to unlock the whole
region requested. After that it was possible to unlock the chip and 
also erase it with erase_all. Mounting JFFS2, however, fails.

JFFS2 mount seems to fail because the chip has 4mbit partitions and
each of them has their own status. When the mount scans flash chip
contents and proceeds past the partition boundary, the status is not
anymore the same as in the previous boundary.

What happens is that cfi_cmdset_0001.c keeps the chip at state
FL_STATUS and when the mount proceeds to address 0x80000 it fails
because the chip is at read array mode and returns flash contents, not
the partition status.

I have attached the changes I made in cfi_cmdset_0001.c to get to this
point.

Could anyone help me on solving this problem? Suggestions, please?

Jarkko Lavinen

----
Changes in function cfi_cmdset_0001():

                if (extp->MajorVersion != '1' ||
+#if 0
                    (extp->MinorVersion < '0' || extp->MinorVersion > '2')) {
+#else
+                   (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
+#endif
                        printk(KERN_WARNING "  Unknown IntelExt Extended Query "
                               "version %c.%c.\n",  extp->MajorVersion,
                               extp->MinorVersion);

The function cfi_intelext_unlock() after my changes:

static int cfi_intelext_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
{
	struct map_info *map = mtd->priv;
	struct cfi_private *cfi = map->fldrv_priv;
	int eraseoffset, erasesize, eraseblocks;
	unsigned long adr;
	int chipnum, ernum, ret = 0;
#ifdef DEBUG_LOCK_BITS
	int ofs_factor = cfi->interleave * cfi->device_type;
	unsigned long temp_adr = adr;
	unsigned long temp_len = len;
#endif

	/* Pass the whole chip through sector by sector and check for each
	   sector if the sector and the given interval overlap */
	for(ernum = 0; ernum < mtd->numeraseregions; ernum++) {
		struct mtd_erase_region_info *erp = &mtd->eraseregions[ernum];

		eraseoffset = erp->offset;
		erasesize = erp->erasesize;
		eraseblocks = erp->numblocks;

#ifdef DEBUG_LOCK_BITS
		printk("Erase offset %08x size %06x blocks %d\n",
		       eraseoffset, erasesize, eraseblocks);
#endif

		if (ofs > eraseoffset + erasesize)
			continue;

		while (eraseblocks > 0) {
			if (ofs < eraseoffset + erasesize &&
			    ofs + len > eraseoffset) {

				chipnum = eraseoffset >> cfi->chipshift;
				adr = eraseoffset -
					(chipnum << cfi->chipshift);

#ifdef DEBUG_LOCK_BITS
				temp_adr = adr;
				temp_len = len;

				cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi,
						 cfi->device_type, NULL);
				while (temp_len) {
					printk("before unlock %x: block "
					       "status register is %x\n",
					       temp_adr, cfi_read_query(map, temp_adr+(2*ofs_factor)));
					temp_adr += mtd->erasesize;
					temp_len -= mtd->erasesize;
				}

				cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi,
						 cfi->device_type, NULL);

#endif
				ret = do_unlock_oneblock(map,
							 &cfi->chips[chipnum],
							 adr);

#ifdef DEBUG_LOCK_BITS
				cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi,
						 cfi->device_type, NULL);
				printk("after unlock: block status register "
				       "is %x\n",
				       cfi_read_query(map, adr+(2*ofs_factor)));
				cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi,
						 cfi->device_type, NULL);
#endif
			}
			eraseoffset += erasesize;
			eraseblocks --;
		}
	}

	return ret;
}

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

* Re: New Intel chip with CFIext version 1.3 not working.
       [not found] ` <2478.1005732188@redhat.com>
@ 2001-11-14 11:27   ` Jarkko Lavinen
  0 siblings, 0 replies; 5+ messages in thread
From: Jarkko Lavinen @ 2001-11-14 11:27 UTC (permalink / raw)
  To: MTD List; +Cc: David Woodhouse

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

> Please could you send the changes in 'diff -u' form so that I can see what's 
> changed?

OK, here comes.

Jarkko

[-- Attachment #2: cfi_cmdset_0001.c.diff --]
[-- Type: text/plain, Size: 4576 bytes --]

--- cfi_cmdset_0001.c.old	Wed Nov 14 12:06:22 2001
+++ cfi_cmdset_0001.c	Wed Nov 14 12:09:08 2001
@@ -4,7 +4,7 @@
  *
  * (C) 2000 Red Hat. GPL'd
  *
- * $Id: cfi_cmdset_0001.c,v 1.87 2001/10/02 15:05:11 dwmw2 Exp $
+ * $Id: cfi_cmdset_0001.c,v 1.85 2001/07/19 14:11:47 rmk Exp $
  *
  * 
  * 10/10/2000	Nicolas Pitre <nico@cam.org>
@@ -140,7 +140,11 @@
 		}
 		
 		if (extp->MajorVersion != '1' || 
+#if 0
 		    (extp->MinorVersion < '0' || extp->MinorVersion > '2')) {
+#else
+		    (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
+#endif
 			printk(KERN_WARNING "  Unknown IntelExt Extended Query "
 			       "version %c.%c.\n",  extp->MajorVersion,
 			       extp->MinorVersion);
@@ -1478,37 +1482,76 @@
 {
 	struct map_info *map = mtd->priv;
 	struct cfi_private *cfi = map->fldrv_priv;
+	int eraseoffset, erasesize, eraseblocks;
 	unsigned long adr;
-	int chipnum, ret = 0;
+	int chipnum, ernum, ret = 0;
 #ifdef DEBUG_LOCK_BITS
 	int ofs_factor = cfi->interleave * cfi->device_type;
+	unsigned long temp_adr = adr;
+	unsigned long temp_len = len;
 #endif
 
-	chipnum = ofs >> cfi->chipshift;
-	adr = ofs - (chipnum << cfi->chipshift);
+	/* Pass the whole chip through sector by sector and check for each
+	   sector if the sector and the given interval overlap */
+	for(ernum = 0; ernum < mtd->numeraseregions; ernum++) {
+		struct mtd_erase_region_info *erp = &mtd->eraseregions[ernum];
+
+		eraseoffset = erp->offset;
+		erasesize = erp->erasesize;
+		eraseblocks = erp->numblocks;
 
 #ifdef DEBUG_LOCK_BITS
-	{
-		unsigned long temp_adr = adr;
-		unsigned long temp_len = len;
-                 
-		cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
-                while (temp_len) {
-			printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor)));
-			temp_adr += mtd->erasesize;
-			temp_len -= mtd->erasesize;
-		}
-		cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
-	}
+		printk("Erase offset %08x size %06x blocks %d\n",
+		       eraseoffset, erasesize, eraseblocks);
 #endif
 
-	ret = do_unlock_oneblock(map, &cfi->chips[chipnum], adr);
+		if (ofs > eraseoffset + erasesize)
+			continue;
+
+		while (eraseblocks > 0) {
+			if (ofs < eraseoffset + erasesize && 
+			    ofs + len > eraseoffset) {
+			       
+				chipnum = eraseoffset >> cfi->chipshift;
+				adr = eraseoffset - 
+					(chipnum << cfi->chipshift);
 
 #ifdef DEBUG_LOCK_BITS
-	cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
-	printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
-	cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
+				temp_adr = adr;
+				temp_len = len;
+				
+				cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, 
+						 cfi->device_type, NULL);
+				while (temp_len) {
+					printk("before unlock %x: block "
+					       "status register is %x\n",
+					       temp_adr, cfi_read_query(map, temp_adr+(2*ofs_factor)));
+					temp_adr += mtd->erasesize;
+					temp_len -= mtd->erasesize;
+				}
+					
+				cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, 
+						 cfi->device_type, NULL);
+
+#endif
+				ret = do_unlock_oneblock(map, 
+							 &cfi->chips[chipnum],
+							 adr);
+
+#ifdef DEBUG_LOCK_BITS
+				cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, 
+						 cfi->device_type, NULL);
+				printk("after unlock: block status register "
+				       "is %x\n", 
+				       cfi_read_query(map, adr+(2*ofs_factor)));
+				cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, 
+						 cfi->device_type, NULL);
 #endif
+			}
+			eraseoffset += erasesize;
+			eraseblocks --;
+		}
+	}
 	
 	return ret;
 }
@@ -1601,17 +1644,23 @@
 	kfree(cfi);
 }
 
+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
+#define cfi_intelext_init init_module
+#define cfi_intelext_exit cleanup_module
+#endif
+
 static char im_name_1[]="cfi_cmdset_0001";
 static char im_name_3[]="cfi_cmdset_0003";
 
-int __init cfi_intelext_init(void)
+
+mod_init_t cfi_intelext_init(void)
 {
 	inter_module_register(im_name_1, THIS_MODULE, &cfi_cmdset_0001);
 	inter_module_register(im_name_3, THIS_MODULE, &cfi_cmdset_0001);
 	return 0;
 }
 
-static void __exit cfi_intelext_exit(void)
+mod_exit_t cfi_intelext_exit(void)
 {
 	inter_module_unregister(im_name_1);
 	inter_module_unregister(im_name_3);
@@ -1619,7 +1668,3 @@
 
 module_init(cfi_intelext_init);
 module_exit(cfi_intelext_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
-MODULE_DESCRIPTION("MTD chip driver for Intel/Sharp flash chips");

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

* Re: New Intel chip with CFIext version 1.3 not working
  2001-11-14  9:53 Jarkko Lavinen
       [not found] ` <2478.1005732188@redhat.com>
@ 2001-11-22 15:15 ` Jarkko Lavinen
  1 sibling, 0 replies; 5+ messages in thread
From: Jarkko Lavinen @ 2001-11-22 15:15 UTC (permalink / raw)
  To: MTD List

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

Could anybody give suggestions how to add the concept of multiple
planes into MTD? Or is it there somewhere already? 

The problem is that currently there is flchip_t structure that has single 
field for flash state, but this state is shared among all planes. This is
not good since each plane has its own independent state.

Is see two possibilites. Either each partition region or plane has its
own flchip_t or flchip_t is expanded to understand multiple planes.

Another problem is to how to find out the existence of these planes
from the flash. For this end I have modified the cfi_cmdset_0001
driver to tell in cleartext the data it sees about partition regions.
Below follows a sample from boot messages. 

I have also attached a hex dump of the flash memory contents. Attaches 
is also the patch containing my modifications.

The chip is top boot with 16 planes. Each of the plane is 512 KB. The
first 15 planes have 8 64 KB sectors each. The last plane has 7 64 kB
sectors and 8 8KB sectors.

Jarkko Lavinen


Kernel boot messages follow:

Number of Erase Block Regions: 2
  Erase Region #0: BlockSize 0x10000 bytes, 127 blocks
  Erase Region #1: BlockSize 0x2000 bytes, 8 blocks
Map Flash0, base 0, number of device hardware partition regions: 2
Partition Region 0 Information:
  Number of identical partitions within partition region 15
  Number of simultaneous program operations: 1
  Number of simultaneous erase operations: 1
  Number of programming or erase ops allowed in other partitions while programmming: 0
  Number of programming or erase ops allowed in other partitions while erasing: 0
  Number of erase block regions w/ contiguous same-size erase blocks: 1
  Erase Block Type 0
    Number of identical sized erase block: 8
    Number of bytes in erase block region: 65536
    Minimum block erase cycles: 100000
    Internal ECC, bits per cell: 1
    Internal ECC, inernal ECC used: 1
    Page mode host reads permitted: 0
    Synchronous host reads permitted: 1
    Synchronous host writes permitted: 0
Partition Region 1 Information:
  Number of identical partitions within partition region 1
  Number of simultaneous program operations: 1
  Number of simultaneous erase operations: 1
  Number of programming or erase ops allowed in other partitions while programmming: 0
  Number of programming or erase ops allowed in other partitions while erasing: 0
  Number of erase block regions w/ contiguous same-size erase blocks: 2
  Erase Block Type 0
    Number of identical sized erase block: 7
    Number of bytes in erase block region: 65536
    Minimum block erase cycles: 100000
    Internal ECC, bits per cell: 1
    Internal ECC, inernal ECC used: 1
    Page mode host reads permitted: 0
    Synchronous host reads permitted: 1
    Synchronous host writes permitted: 0
  Erase Block Type 1
    Number of identical sized erase block: 8
    Number of bytes in erase block region: 8192
    Minimum block erase cycles: 100000
    Internal ECC, bits per cell: 1
    Internal ECC, inernal ECC used: 1
    Page mode host reads permitted: 0
    Synchronous host reads permitted: 1
    Synchronous host writes permitted: 0
mtd: Giving out device 0 to Flash0

Hex dump of flash chip in read query mode follows:

address__0__1__2__3__4__5__6__7__8__9__A__B__C__D__E__F__0123456789ABCDEF
F0000000|89 00 74 88 01 00 01 00 89 00 CF FF 01 00 01 00 ..t.............
F0000010|89 00 74 88 01 00 01 00 89 00 CF FF 01 00 01 00 ..t.............
F0000020|51 00 52 00 59 00 03 00 00 00 39 00 00 00 00 00 Q.R.Y.....9.....
F0000030|00 00 00 00 00 00 17 00 19 00 B4 00 C6 00 04 00 ................
F0000040|00 00 0A 00 00 00 04 00 00 00 03 00 00 00 17 00 ................
F0000050|01 00 00 00 00 00 00 00 02 00 7E 00 00 00 00 00 ..........~.....
F0000060|01 00 07 00 00 00 20 00 00 00 00 00 00 00 00 00 ...... .........
F0000070|00 00 50 00 52 00 49 00 31 00 33 00 66 00 0B 00 ..P.R.I.1.3.f...
F0000080|00 00 00 00 01 00 03 00 00 00 18 00 C0 00 01 00 ................
F0000090|80 00 00 00 03 00 03 00 00 00 03 00 01 00 02 00 ................
F00000A0|07 00 02 00 0F 00 00 00 11 00 00 00 00 00 01 00 ................
F00000B0|07 00 00 00 00 00 01 00 64 00 00 00 01 00 02 00 ........d.......
F00000C0|01 00 00 00 11 00 00 00 00 00 02 00 06 00 00 00 ................
F00000D0|00 00 01 00 64 00 00 00 01 00 02 00 07 00 00 00 ....d...........
F00000E0|20 00 00 00 64 00 00 00 01 00 02 00 01 00 FF FF  ...d...........
F00000F0|FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
F0000100|FE FF 03 80 16 00 69 3A 4D A6 FF FF FF FF FF FF ......i:M.......

[-- Attachment #2: partregs-patch --]
[-- Type: text/plain, Size: 8486 bytes --]

diff -u -r linux-2.4.14/drivers/mtd/chips/cfi_cmdset_0001.c linux-2.4.14-jlavi/drivers/mtd/chips/cfi_cmdset_0001.c
--- linux-2.4.14/drivers/mtd/chips/cfi_cmdset_0001.c	Fri Oct  5 01:14:59 2001
+++ linux-2.4.14-jlavi/drivers/mtd/chips/cfi_cmdset_0001.c	Thu Nov 22 16:18:27 2001
@@ -4,7 +4,7 @@
  *
  * (C) 2000 Red Hat. GPL'd
  *
- * $Id: cfi_cmdset_0001.c,v 1.87 2001/10/02 15:05:11 dwmw2 Exp $
+ * $Id: cfi_cmdset_0001.c,v 1.85 2001/07/19 14:11:47 rmk Exp $
  *
  * 
  * 10/10/2000	Nicolas Pitre <nico@cam.org>
@@ -97,6 +97,95 @@
 }
 #endif
 
+void cfi_intel_specific_partitions(struct map_info *map, __u16 adr)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	__u32 base = cfi->chips[0].start;
+	int ofs_factor = cfi->interleave * cfi->device_type;
+	int i, j, k, nparts, nfields, ofs;
+
+	/*printk("adr: %x\n", adr);*/
+
+	ofs = 0;
+	/* Skip Primary Vendor Specific Entended Query Table */
+	ofs = sizeof(struct cfi_pri_intelext);
+	
+	/* Skip Protected Register Informantion */
+	nfields = cfi_read_query(map, (base+((adr + ofs)*ofs_factor)));
+	
+	ofs += sizeof(__u8) + nfields*sizeof(__u32);
+	
+	/* Skip Burst Read Informatin */
+	nfields = cfi_read_query(map, (base+((adr + ofs + 1)*ofs_factor)));
+	
+	ofs += 2*sizeof(__u8) + nfields*sizeof(__u8);
+
+	/*printk("ofs: %x\n", ofs); */
+	
+	/* Read Partition and Erase Block Region Information */
+	
+	nparts = cfi_read_query(map, (base+((adr + ofs)*ofs_factor)));
+	printk("Map %s, base %x, number of device hardware partition regions: %d\n",
+	       map->name, base, nparts);
+				  		       			
+	ofs += 1;
+	for(i = 0; i < nparts; i++) {
+		struct cfi_vsi_pri_query pri;
+		struct cfi_vsi_ebr_query ebr;
+		
+		for(j=0; j < sizeof(struct cfi_vsi_pri_query); j++)
+			((unsigned char *)&pri)[j] = 
+				cfi_read_query(map, (base+((adr + ofs + j)*
+							   ofs_factor)));
+		pri.NumOfIdPartitions = le16_to_cpu(pri.NumOfIdPartitions);
+		
+		printk("Partition Region %d Information:\n"
+		       "  Number of identical partitions within partition region %d\n"
+		       "  Number of simultaneous program operations: %d\n"
+		       "  Number of simultaneous erase operations: %d\n"
+		       "  Number of programming or erase ops allowed in other partitions while programmming: %d\n"
+		       "  Number of programming or erase ops allowed in other partitions while erasing: %d\n"
+		       "  Number of erase block regions w/ contiguous same-size erase blocks: %d\n",
+		       i, 
+		       pri.NumOfIdPartitions,
+		       pri.NumOfOps & 0xf, pri.NumOfOps >> 4,
+		       pri.NunOfOtherPEOpsWhileProgramming,
+		       pri.NunOfOtherPEOpsWhileErasing,
+		       pri.NumOfEBRsInProgRegion);
+
+		ofs += sizeof(struct cfi_vsi_pri_query);
+		for(j = 0; j < pri.NumOfEBRsInProgRegion; j++) {
+			for(k = 0; k < sizeof(struct cfi_vsi_ebr_query); k++)
+				((unsigned char *)&ebr)[k] = 
+					cfi_read_query(map, (base+((adr + ofs + k)* ofs_factor)));
+
+			ebr.NumOfEQSizedEBRs = le16_to_cpu(ebr.NumOfEQSizedEBRs);
+			ebr.NumOfEBRBytes = le16_to_cpu(ebr.NumOfEBRBytes);
+			ebr.MaxBEraseCnt = le16_to_cpu(ebr.MaxBEraseCnt);
+			
+			printk("  Erase Block Type %d\n"
+			       "    Number of identical sized erase block: %d\n"
+			       "    Number of bytes in erase block region: %d\n"
+			       "    Minimum block erase cycles: %d\n"
+			       "    Internal ECC, bits per cell: %d\n"
+			       "    Internal ECC, inernal ECC used: %d\n"
+			       "    Page mode host reads permitted: %d\n"
+			       "    Synchronous host reads permitted: %d\n"
+			       "    Synchronous host writes permitted: %d\n",
+			       j,
+			       ebr.NumOfEQSizedEBRs + 1,
+			       ebr.NumOfEBRBytes * 256,
+			       ebr.MaxBEraseCnt * 1000,
+			       ebr.EccBits & 0xf, (ebr.EccBits & 0x10) != 0,
+			       (ebr.PgSynModeCap & 0x1) != 0,
+			       (ebr.PgSynModeCap & 0x2) != 0,
+			       (ebr.PgSynModeCap & 0x4) != 0);
+
+			ofs += sizeof(struct cfi_vsi_ebr_query);
+		}			
+	}
+}
+
 /* This routine is made available to other mtd code via
  * inter_module_register.  It must only be accessed through
  * inter_module_get which will bump the use count of this module.  The
@@ -138,9 +227,18 @@
 			((unsigned char *)extp)[i] = 
 				cfi_read_query(map, (base+((adr+i)*ofs_factor)));
 		}
-		
+
+#if defined(DEBUG_CFI_FEATURES)
+		if (extp->MajorVersion == '1' &&  extp->MinorVersion == '3') 
+			cfi_intel_specific_partitions(map, adr);
+#endif
+
 		if (extp->MajorVersion != '1' || 
+#if 0
 		    (extp->MinorVersion < '0' || extp->MinorVersion > '2')) {
+#else
+		    (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
+#endif
 			printk(KERN_WARNING "  Unknown IntelExt Extended Query "
 			       "version %c.%c.\n",  extp->MajorVersion,
 			       extp->MinorVersion);
@@ -1478,37 +1576,76 @@
 {
 	struct map_info *map = mtd->priv;
 	struct cfi_private *cfi = map->fldrv_priv;
+	int eraseoffset, erasesize, eraseblocks;
 	unsigned long adr;
-	int chipnum, ret = 0;
+	int chipnum, ernum, ret = 0;
 #ifdef DEBUG_LOCK_BITS
 	int ofs_factor = cfi->interleave * cfi->device_type;
+	unsigned long temp_adr = adr;
+	unsigned long temp_len = len;
 #endif
 
-	chipnum = ofs >> cfi->chipshift;
-	adr = ofs - (chipnum << cfi->chipshift);
+	/* Pass the whole chip through sector by sector and check for each
+	   sector if the sector and the given interval overlap */
+	for(ernum = 0; ernum < mtd->numeraseregions; ernum++) {
+		struct mtd_erase_region_info *erp = &mtd->eraseregions[ernum];
+
+		eraseoffset = erp->offset;
+		erasesize = erp->erasesize;
+		eraseblocks = erp->numblocks;
 
 #ifdef DEBUG_LOCK_BITS
-	{
-		unsigned long temp_adr = adr;
-		unsigned long temp_len = len;
-                 
-		cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
-                while (temp_len) {
-			printk("before unlock %x: block status register is %x\n",temp_adr,cfi_read_query(map, temp_adr+(2*ofs_factor)));
-			temp_adr += mtd->erasesize;
-			temp_len -= mtd->erasesize;
-		}
-		cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
-	}
+		printk("Erase offset %08x size %06x blocks %d\n",
+		       eraseoffset, erasesize, eraseblocks);
 #endif
 
-	ret = do_unlock_oneblock(map, &cfi->chips[chipnum], adr);
+		if (ofs > eraseoffset + erasesize)
+			continue;
+
+		while (eraseblocks > 0) {
+			if (ofs < eraseoffset + erasesize && 
+			    ofs + len > eraseoffset) {
+			       
+				chipnum = eraseoffset >> cfi->chipshift;
+				adr = eraseoffset - 
+					(chipnum << cfi->chipshift);
 
 #ifdef DEBUG_LOCK_BITS
-	cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
-	printk("after unlock: block status register is %x\n",cfi_read_query(map, adr+(2*ofs_factor)));
-	cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
+				temp_adr = adr;
+				temp_len = len;
+				
+				cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, 
+						 cfi->device_type, NULL);
+				while (temp_len) {
+					printk("before unlock %x: block "
+					       "status register is %x\n",
+					       temp_adr, cfi_read_query(map, temp_adr+(2*ofs_factor)));
+					temp_adr += mtd->erasesize;
+					temp_len -= mtd->erasesize;
+				}
+					
+				cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, 
+						 cfi->device_type, NULL);
+
+#endif
+				ret = do_unlock_oneblock(map, 
+							 &cfi->chips[chipnum],
+							 adr);
+
+#ifdef DEBUG_LOCK_BITS
+				cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, 
+						 cfi->device_type, NULL);
+				printk("after unlock: block status register "
+				       "is %x\n", 
+				       cfi_read_query(map, adr+(2*ofs_factor)));
+				cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, 
+						 cfi->device_type, NULL);
 #endif
+			}
+			eraseoffset += erasesize;
+			eraseblocks --;
+		}
+	}
 	
 	return ret;
 }
diff -u -r linux-2.4.14/include/linux/mtd/cfi.h linux-2.4.14-jlavi/include/linux/mtd/cfi.h
--- linux-2.4.14/include/linux/mtd/cfi.h	Fri Oct  5 01:13:18 2001
+++ linux-2.4.14-jlavi/include/linux/mtd/cfi.h	Thu Nov 22 14:15:40 2001
@@ -219,6 +219,22 @@
   __u32 ConfField[1]; /* Not host ordered */
 } __attribute__((packed));
 
+struct cfi_vsi_pri_query {
+	__u16 NumOfIdPartitions;
+	__u8  NumOfOps;
+	__u8  NunOfOtherPEOpsWhileProgramming;
+	__u8  NunOfOtherPEOpsWhileErasing;	
+	__u8  NumOfEBRsInProgRegion;
+} __attribute__((packed));
+
+struct cfi_vsi_ebr_query {
+	__u16 NumOfEQSizedEBRs;
+	__u16 NumOfEBRBytes;
+	__u16 MaxBEraseCnt;
+	__u8  EccBits;
+	__u8  PgSynModeCap;
+} __attribute__((packed));
+
 #define P_ID_NONE 0
 #define P_ID_INTEL_EXT 1
 #define P_ID_AMD_STD 2

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

* New Intel chip with CFIext version 1.3 not working.
@ 2005-01-25  1:59 Unnamalai Kanchi Bashyam
  2005-01-26 16:10 ` Jared Hulbert
  0 siblings, 1 reply; 5+ messages in thread
From: Unnamalai Kanchi Bashyam @ 2005-01-25  1:59 UTC (permalink / raw)
  To: linux-mtd

Dear Mr. Jarkko Lavinen,

 I am encountering the same problem that which you faced - "Unknown
IntelExt Extended Query". I am using Intel Strata Flash chip and its CFI
version is 1.3.  Linux version 2.4.18-rmk4-mx2bsp, Architecture -
Motorola MX2ADS. 
 Is a patch available for this problem?

Regards,
Unnamalai

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

* Re: New Intel chip with CFIext version 1.3 not working.
  2005-01-25  1:59 New Intel chip with CFIext version 1.3 not working Unnamalai Kanchi Bashyam
@ 2005-01-26 16:10 ` Jared Hulbert
  0 siblings, 0 replies; 5+ messages in thread
From: Jared Hulbert @ 2005-01-26 16:10 UTC (permalink / raw)
  To: Unnamalai Kanchi Bashyam; +Cc: linux-mtd

Newer versions of the MTD fix this.  I'm not aware of a patch that
would directly apply to that kernel.  I had good luck with backporting
current MTD's to older kernels.  the patchin.sh script found in the
CVS snapshots is useful in doing this.

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

end of thread, other threads:[~2005-01-26 16:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-01-25  1:59 New Intel chip with CFIext version 1.3 not working Unnamalai Kanchi Bashyam
2005-01-26 16:10 ` Jared Hulbert
  -- strict thread matches above, loose matches on Subject: below --
2001-11-14  9:53 Jarkko Lavinen
     [not found] ` <2478.1005732188@redhat.com>
2001-11-14 11:27   ` Jarkko Lavinen
2001-11-22 15:15 ` Jarkko Lavinen

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