mtd/drivers/mtd/chips cfi_cmdset_0001.c, 1.181, 1.182 gen_probe.c, 1.22, 1.23

Nicolas Pitre nico at infradead.org
Sat Aug 6 00:40:45 EDT 2005


Update of /home/cvs/mtd/drivers/mtd/chips
In directory phoenix.infradead.org:/tmp/cvs-serv14920/drivers/mtd/chips

Modified Files:
	cfi_cmdset_0001.c gen_probe.c 
Log Message:
{MTD] add support for Intel's "Sibley" flash

This updates the Primary Vendor-Specific Extended Query parsing to
version 1.4 in order to get the information about the Configurable
Programming Mode regions implemented in the Sibley flash, as well as
selecting the appropriate write command code.

This flash does not behave like traditional NOR flash when writing data.
While mtdblock should just work, further changes are needed for JFFS2 use.

Signed-off-by: Nicolas Pitre <nico at cam.org>


Index: cfi_cmdset_0001.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/cfi_cmdset_0001.c,v
retrieving revision 1.181
retrieving revision 1.182
diff -u -r1.181 -r1.182
--- cfi_cmdset_0001.c	6 Aug 2005 04:16:48 -0000	1.181
+++ cfi_cmdset_0001.c	6 Aug 2005 04:40:41 -0000	1.182
@@ -105,6 +105,7 @@
 static void cfi_tell_features(struct cfi_pri_intelext *extp)
 {
 	int i;
+	printk("  Extended Query version %c.%c\n", extp->MajorVersion, extp->MinorVersion);
 	printk("  Feature/Command Support:      %4.4X\n", extp->FeatureSupport);
 	printk("     - Chip Erase:              %s\n", extp->FeatureSupport&1?"supported":"unsupported");
 	printk("     - Suspend Erase:           %s\n", extp->FeatureSupport&2?"supported":"unsupported");
@@ -116,7 +117,8 @@
 	printk("     - Page-mode read:          %s\n", extp->FeatureSupport&128?"supported":"unsupported");
 	printk("     - Synchronous read:        %s\n", extp->FeatureSupport&256?"supported":"unsupported");
 	printk("     - Simultaneous operations: %s\n", extp->FeatureSupport&512?"supported":"unsupported");
-	for (i=10; i<32; i++) {
+	printk("     - Extended Flash Array:    %s\n", extp->FeatureSupport&1024?"supported":"unsupported");
+	for (i=11; i<32; i++) {
 		if (extp->FeatureSupport & (1<<i)) 
 			printk("     - Unknown Bit %X:      supported\n", i);
 	}
@@ -130,12 +132,18 @@
 	
 	printk("  Block Status Register Mask: %4.4X\n", extp->BlkStatusRegMask);
 	printk("     - Lock Bit Active:      %s\n", extp->BlkStatusRegMask&1?"yes":"no");
-	printk("     - Valid Bit Active:     %s\n", extp->BlkStatusRegMask&2?"yes":"no");
-	for (i=2; i<16; i++) {
+	printk("     - Lock-Down Bit Active: %s\n", extp->BlkStatusRegMask&2?"yes":"no");
+	for (i=2; i<3; i++) {
 		if (extp->BlkStatusRegMask & (1<<i))
 			printk("     - Unknown Bit %X Active: yes\n",i);
 	}
-	
+	printk("     - EFA Lock Bit:         %s\n", extp->BlkStatusRegMask&16?"yes":"no");
+	printk("     - EFA Lock-Down Bit:    %s\n", extp->BlkStatusRegMask&32?"yes":"no");
+	for (i=6; i<16; i++) {
+		if (extp->BlkStatusRegMask & (1<<i))
+			printk("     - Unknown Bit %X Active: yes\n",i);
+	}
+
 	printk("  Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n", 
 	       extp->VccOptimal >> 4, extp->VccOptimal & 0xf);
 	if (extp->VppOptimal)
@@ -253,7 +261,7 @@
 		return NULL;
 
 	if (extp->MajorVersion != '1' ||
-	    (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
+	    (extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
 		printk(KERN_ERR "  Unknown Intel/Sharp Extended Query "
 		       "version %c.%c.\n",  extp->MajorVersion,
 		       extp->MinorVersion);
@@ -266,7 +274,7 @@
 	extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask);
 	extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr);
 
-	if (extp->MajorVersion == '1' && extp->MinorVersion == '3') {
+	if (extp->MajorVersion == '1' && extp->MinorVersion >= '3') {
 		unsigned int extra_size = 0;
 		int nb_parts, i;
 
@@ -275,7 +283,7 @@
 			      sizeof(struct cfi_intelext_otpinfo);
 
 		/* Burst Read info */
-		extra_size += 6;
+		extra_size += (extp->MinorVersion < '4') ? 6 : 5;
 
 		/* Number of hardware-partitions */
 		extra_size += 1;
@@ -283,6 +291,10 @@
 			goto need_more;
 		nb_parts = extp->extra[extra_size - 1];
 
+		/* skip the sizeof(partregion) field in CFI 1.4 */
+		if (extp->MinorVersion >= '4')
+			extra_size += 2;
+
 		for (i = 0; i < nb_parts; i++) {
 			struct cfi_intelext_regioninfo *rinfo;
 			rinfo = (struct cfi_intelext_regioninfo *)&extp->extra[extra_size];
@@ -294,6 +306,9 @@
 				      * sizeof(struct cfi_intelext_blockinfo);
 		}
 
+		if (extp->MinorVersion >= '4')
+			extra_size += sizeof(struct cfi_intelext_programming_regioninfo);
+
 		if (extp_size < sizeof(*extp) + extra_size) {
 			need_more:
 			extp_size = sizeof(*extp) + extra_size;
@@ -490,7 +505,7 @@
 	 * arrangement at this point. This can be rearranged in the future
 	 * if someone feels motivated enough.  --nico
 	 */
-	if (extp && extp->MajorVersion == '1' && extp->MinorVersion == '3'
+	if (extp && extp->MajorVersion == '1' && extp->MinorVersion >= '3'
 	    && extp->FeatureSupport & (1 << 9)) {
 		struct cfi_private *newcfi;
 		struct flchip *chip;
@@ -502,12 +517,16 @@
 		       sizeof(struct cfi_intelext_otpinfo);
 
 		/* Burst Read info */
-		offs += 6;
+		offs += (extp->MinorVersion < '4') ? 6 : 5;
 
 		/* Number of partition regions */
 		numregions = extp->extra[offs];
 		offs += 1;
 
+		/* skip the sizeof(partregion) field in CFI 1.4 */
+		if (extp->MinorVersion >= '4')
+			offs += 2;
+
 		/* Number of hardware partitions */
 		numparts = 0;
 		for (i = 0; i < numregions; i++) {
@@ -519,6 +538,20 @@
 				  sizeof(struct cfi_intelext_blockinfo);
 		}
 
+		/* Programming Region info */
+		if (extp->MinorVersion >= '4') {
+			struct cfi_intelext_programming_regioninfo *prinfo;
+			prinfo = (struct cfi_intelext_programming_regioninfo *)&extp->extra[offs];
+			MTD_PROGREGION_SIZE(mtd) = cfi->interleave << prinfo->ProgRegShift;
+			MTD_PROGREGION_CTRLMODE_VALID(mtd) = cfi->interleave * prinfo->ControlValid;
+			MTD_PROGREGION_CTRLMODE_INVALID(mtd) = cfi->interleave * prinfo->ControlInvalid;
+			mtd->flags |= MTD_PROGRAM_REGIONS;
+			printk(KERN_DEBUG "%s: program region size/ctrl_valid/ctrl_inval = %d/%d/%d\n",
+			       map->name, MTD_PROGREGION_SIZE(mtd),
+			       MTD_PROGREGION_CTRLMODE_VALID(mtd),
+			       MTD_PROGREGION_CTRLMODE_INVALID(mtd));
+		}
+
 		/*
 		 * All functions below currently rely on all chips having
 		 * the same geometry so we'll just assume that all hardware
@@ -1222,12 +1255,17 @@
 
 	adr += chip->start;
 
-	/* Let's determine this according to the interleave only once */
+	/* Let's determine those according to the interleave only once */
 	status_OK = CMD(0x80);
 	switch (mode) {
-	case FL_WRITING:   write_cmd = CMD(0x40); break;
-	case FL_OTP_WRITE: write_cmd = CMD(0xc0); break;
-	default: return -EINVAL;
+	case FL_WRITING:
+		write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0x40) : CMD(0x41);
+		break;
+	case FL_OTP_WRITE:
+		write_cmd = CMD(0xc0);
+		break;
+	default:
+		return -EINVAL;
 	}
 
 	spin_lock(chip->mutex);
@@ -1410,16 +1448,17 @@
 				    unsigned long adr, const u_char *buf, int len)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
-	map_word status, status_OK;
+	map_word status, status_OK, write_cmd;
 	unsigned long cmd_adr, timeo;
 	int wbufsize, z, ret=0, bytes, words;
 
 	wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
 	adr += chip->start;
 	cmd_adr = adr & ~(wbufsize-1);
-	
+
 	/* Let's determine this according to the interleave only once */
 	status_OK = CMD(0x80);
+	write_cmd = (cfi->cfiq->P_ID != 0x0200) ? CMD(0xe8) : CMD(0xe9);
 
 	spin_lock(chip->mutex);
 	ret = get_chip(map, chip, cmd_adr, FL_WRITING);
@@ -1451,7 +1490,7 @@
 
 	z = 0;
 	for (;;) {
-		map_write(map, CMD(0xe8), cmd_adr);
+		map_write(map, write_cmd, cmd_adr);
 
 		status = map_read(map, cmd_adr);
 		if (map_word_andequal(map, status, status_OK, status_OK))
@@ -2380,20 +2419,23 @@
 	kfree(mtd->eraseregions);
 }
 
-static char im_name_1[]="cfi_cmdset_0001";
-static char im_name_3[]="cfi_cmdset_0003";
+static char im_name_0001[] = "cfi_cmdset_0001";
+static char im_name_0003[] = "cfi_cmdset_0003";
+static char im_name_0200[] = "cfi_cmdset_0200";
 
 static int __init 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);
+	inter_module_register(im_name_0001, THIS_MODULE, &cfi_cmdset_0001);
+	inter_module_register(im_name_0003, THIS_MODULE, &cfi_cmdset_0001);
+	inter_module_register(im_name_0200, THIS_MODULE, &cfi_cmdset_0001);
 	return 0;
 }
 
 static void __exit cfi_intelext_exit(void)
 {
-	inter_module_unregister(im_name_1);
-	inter_module_unregister(im_name_3);
+	inter_module_unregister(im_name_0001);
+	inter_module_unregister(im_name_0003);
+	inter_module_unregister(im_name_0200);
 }
 
 module_init(cfi_intelext_init);

Index: gen_probe.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/gen_probe.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- gen_probe.c	24 Jan 2005 23:49:50 -0000	1.22
+++ gen_probe.c	6 Aug 2005 04:40:41 -0000	1.23
@@ -235,6 +235,7 @@
 #ifdef CONFIG_MTD_CFI_INTELEXT
 	case 0x0001:
 	case 0x0003:
+	case 0x0200:
 		return cfi_cmdset_0001(map, primary);
 #endif
 #ifdef CONFIG_MTD_CFI_AMDSTD





More information about the linux-mtd-cvs mailing list