New Intel chip with CFIext version 1.3 not working.
Jarkko Lavinen
jlavi at iki.fi
Wed Nov 14 06:27:34 EST 2001
> Please could you send the changes in 'diff -u' form so that I can see what's
> changed?
OK, here comes.
Jarkko
-------------- next part --------------
--- 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 at 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 at infradead.org> et al.");
-MODULE_DESCRIPTION("MTD chip driver for Intel/Sharp flash chips");
More information about the linux-mtd
mailing list