Skip to contentSkip to conversation

cfi_cmdset_0002.c SST39VF3201B issue

DISCUSSION angelo 3 participants 5 messages Oct 6, 2011 – Oct 14, 2011 1 message not in the archive Memory technology devices (MTD)

lore
Share & tools
lore

angelo

author
#0 lore raw

Dear all,

like me some other users had issues with this chip and jffs2.

From time to time users asks why they get errors trying to use jffs2 with this chip.

This chip, from the datasheet, allows to erase 4KB "sectors" or 64KB "blocks", replying to cfi queries with a "setcor" erase size and a "block" erase size.

I can be wrong of course, but this is what i figured out:

1) fixup decision

Someone of you decided to fix up this SST39VF3201 in this way:

static void fixup_old_sst_eraseregion(struct mtd_info *mtd)

{
    struct map_info *map = mtd->priv;
    struct cfi_private *cfi = map->fldrv_priv;

    /*
     * These flashes report two seperate eraseblock regions based on the
     * sector_erase-size and block_erase-size, although they both 
operate on the
     * same memory. This is not allowed according to CFI, so we just 
pick the
     * sector_erase-size.
     */
    cfi->cfiq->NumEraseRegions = 1;
}

Of course, in this way, deciding 0x1000 (sector-size) is the one to use, jffs2 cannot be used safely, since minimal data block is 4Kb + some hdr bytes. Wasn't better fixup to "block" size (64K) ?

2) after fixup decision, when jffs2 asks to erase a block to cfi_cmdset_0002.c, cfi driver seems to erase wrongly a 64K block. This is what happen in detail:
jffs erase.c, to erase a block does: mtd->erase(), with a len
mtd->erasesize (4KB).
mtd->erase() is calls cfi_amdstd_erase_varsize ...
finally, do_erase_oneblock is called, where:

cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); map_write(map, CMD(0x30), adr);

but this chip uses 0x30 cmd to erase a 64 KB block, and 0x50 to erase a sector.

Please let me know if i am in the right direction, so i can think about a patch that allows jffs2 to be used with native hw 64KB block erasesize.

Regards
Angelo Dureghello

#1 lore raw

I would try to keep the 4kBi blocks.

regards

Il giorno gio, 06/10/2011 alle 14.29 +0200, angelo ha scritto:

Quoted 75 lines

Dear all,

like me some other users had issues with this chip and jffs2.

From time to time users asks why they get errors trying to use jffs2
with this chip.

This chip, from the datasheet, allows to erase 4KB "sectors" or 64KB "blocks", replying to cfi queries with a "setcor" erase size and a "block" erase size.

I can be wrong of course, but this is what i figured out:

1) fixup decision

Someone of you decided to fix up this SST39VF3201 in this way:

static void fixup_old_sst_eraseregion(struct mtd_info *mtd)

{
     struct map_info *map = mtd->priv;
     struct cfi_private *cfi = map->fldrv_priv;

     /*
      * These flashes report two seperate eraseblock regions based on the
      * sector_erase-size and block_erase-size, although they both 
operate on the
      * same memory. This is not allowed according to CFI, so we just 
pick the
      * sector_erase-size.
      */
     cfi->cfiq->NumEraseRegions = 1;
}

Of course, in this way, deciding 0x1000 (sector-size) is the one to use, jffs2 cannot be used safely, since
minimal data block is 4Kb + some hdr bytes. Wasn't better fixup to "block" size (64K) ?

2) after fixup decision, when jffs2 asks to erase a block to cfi_cmdset_0002.c, cfi driver seems to erase wrongly a 64K block. This is what happen in detail:

    jffs erase.c, to erase a block does:  mtd->erase(), with a len  

mtd->erasesize (4KB).
mtd->erase() is calls cfi_amdstd_erase_varsize ...
finally, do_erase_oneblock is called, where:

cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
map_write(map, CMD(0x30), adr);

but this chip uses 0x30 cmd to erase a 64 KB block, and 0x50 to erase a sector.

Please let me know if i am in the right direction, so i can think about a patch that allows
jffs2 to be used with native hw 64KB block erasesize.

Regards
Angelo Dureghello

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

Signature · 8 lines
Fabio Giovagnini

Aurion s.r.l.
P.iva 00885711200
cell. +39.335.8350919
Tel. +39.051.594.78.24
Fax. +39 051.082.14.49
skype: aurion.giovagnini
author
#2 lore raw

Hi,

i was working with main line kernel (2.6.36.2), and i have seen that the issue has been fixed for example in 2.6.38, to erase really a 4KB sector using flash cmd 0x50. This is probably why jffs2 "seems" to work, with the patch in mkfs.jffs2.

But, as already pointed out, jffs2 could have problems, due to the fact the minimal block size is 4KB + some bytes.

For who is interested, i patched the kernel 2.6.36.2 in my own way, using 64KB physical erasesize and JFFS2 works great:

in cfi_cmdset_0002.c

  static void fixup_old_sst_eraseregion(struct mtd_info *mtd)
  {
      struct map_info *map = mtd->priv;
      struct cfi_private *cfi = map->fldrv_priv;

/*
* These flashes report two seperate eraseblock regions based on the
* sector_erase-size and block_erase-size, although they both
operate on the
* same memory. This is not allowed according to CFI, so we just
pick the
* sector_erase-size.
*/
+ cfi->cfiq->EraseRegionInfo[0] = cfi->cfiq->EraseRegionInfo[1];
+

      cfi->cfiq->NumEraseRegions = 1;

}

Regards,
Angelo Dureghello

Quoted 86 lines · Fabio Giovagnini

I would try to keep the 4kBi blocks.

regards

Il giorno gio, 06/10/2011 alle 14.29 +0200, angelo ha scritto:

Quoted 76 lines

Dear all,

like me some other users had issues with this chip and jffs2.

From time to time users asks why they get errors trying to use jffs2
with this chip.

This chip, from the datasheet, allows to erase 4KB "sectors" or 64KB "blocks", replying to cfi queries with a "setcor" erase size and a "block" erase size.

I can be wrong of course, but this is what i figured out:

1) fixup decision

Someone of you decided to fix up this SST39VF3201 in this way:

static void fixup_old_sst_eraseregion(struct mtd_info *mtd)

{
      struct map_info *map = mtd->priv;
      struct cfi_private *cfi = map->fldrv_priv;

      /*
       * These flashes report two seperate eraseblock regions based on the
       * sector_erase-size and block_erase-size, although they both
operate on the
       * same memory. This is not allowed according to CFI, so we just
pick the
       * sector_erase-size.
       */
      cfi->cfiq->NumEraseRegions = 1;
}

Of course, in this way, deciding 0x1000 (sector-size) is the one to use, jffs2 cannot be used safely, since
minimal data block is 4Kb + some hdr bytes. Wasn't better fixup to "block" size (64K) ?

2) after fixup decision, when jffs2 asks to erase a block to cfi_cmdset_0002.c, cfi driver seems to erase wrongly a 64K block. This is what happen in detail:

     jffs erase.c, to erase a block does:  mtd->erase(), with a len

mtd->erasesize (4KB).
mtd->erase() is calls cfi_amdstd_erase_varsize ...
finally, do_erase_oneblock is called, where:

cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
map_write(map, CMD(0x30), adr);

but this chip uses 0x30 cmd to erase a 64 KB block, and 0x50 to erase a sector.

Please let me know if i am in the right direction, so i can think about a patch that allows
jffs2 to be used with native hw 64KB block erasesize.

Regards
Angelo Dureghello

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

A message that is not in the archive (sent off-list or not yet received): [email protected]

#4 lore raw

Hi Angelo,
I have worked with 2.6.38 and I have used 0x50 command and modification into mkfs.jffs2 utility in order to accomplish a 4k fs sector size. It is working and I think that in a not so huge memory support a 4k sector allows a better management rather than 64k sector.

Regards

Il giorno gio, 06/10/2011 alle 15.44 +0200, angelo ha scritto:

Quoted 118 lines

Hi Giovanni,

i can be wrong, but i think this is a bug of the cfi command set, and should be fixed in the best way from the maintainer.
This because mtd->regions[x].erasesize is set to 4KiB but everytime an mtd->erase is requested, a block of 64KB is erased.

Unfortunately, creating "virtual" 32 or 64KB" erasesizes to allows jffs2 to work is not convenient and also quite long job.

I will try the simplest patch for now (using native 64Kblocks as many other nor flash) and will post back shortly if the fix work, almost for jffs2.

Regards,
angelo

Quoted 85 lines · Fabio Giovagnini

I would try to keep the 4kBi blocks.

regards

Il giorno gio, 06/10/2011 alle 14.29 +0200, angelo ha scritto:

Quoted 76 lines

Dear all,

like me some other users had issues with this chip and jffs2.

From time to time users asks why they get errors trying to use jffs2
with this chip.

This chip, from the datasheet, allows to erase 4KB "sectors" or 64KB "blocks", replying to cfi queries with a "setcor" erase size and a "block" erase size.

I can be wrong of course, but this is what i figured out:

1) fixup decision

Someone of you decided to fix up this SST39VF3201 in this way:

static void fixup_old_sst_eraseregion(struct mtd_info *mtd)

{
     struct map_info *map = mtd->priv;
     struct cfi_private *cfi = map->fldrv_priv;

     /*
      * These flashes report two seperate eraseblock regions based on the
      * sector_erase-size and block_erase-size, although they both 
operate on the
      * same memory. This is not allowed according to CFI, so we just 
pick the
      * sector_erase-size.
      */
     cfi->cfiq->NumEraseRegions = 1;
}

Of course, in this way, deciding 0x1000 (sector-size) is the one to use, jffs2 cannot be used safely, since
minimal data block is 4Kb + some hdr bytes. Wasn't better fixup to "block" size (64K) ?

2) after fixup decision, when jffs2 asks to erase a block to cfi_cmdset_0002.c, cfi driver seems to erase wrongly a 64K block. This is what happen in detail:

    jffs erase.c, to erase a block does:  mtd->erase(), with a len  

mtd->erasesize (4KB).
mtd->erase() is calls cfi_amdstd_erase_varsize ...
finally, do_erase_oneblock is called, where:

cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
map_write(map, CMD(0x30), adr);

but this chip uses 0x30 cmd to erase a 64 KB block, and 0x50 to erase a sector.

Please let me know if i am in the right direction, so i can think about a patch that allows
jffs2 to be used with native hw 64KB block erasesize.

Regards
Angelo Dureghello

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

Signature · 7 lines
 .:.:.SYSAM.:.:.

  di Angelo Dureghello
    via San Nazario 149
      34151, Trieste, Italy
    ++39 340 7631990
  www.sysam.it
Signature · 8 lines
Fabio Giovagnini

Aurion s.r.l.
P.iva 00885711200
cell. +39.335.8350919
Tel. +39.051.594.78.24
Fax. +39 051.082.14.49
skype: aurion.giovagnini
#5 lore raw
Quoted 5 lines · Fabio Giovagnini

Hi Angelo,
I have worked with 2.6.38 and I have used 0x50 command and modification into mkfs.jffs2 utility in order to accomplish a 4k fs sector size. It is working and I think that in a not so huge memory support a 4k sector allows a better management rather than 64k sector.

4KiB is too small for JFFS2. If it works for you, it is only because you are lucky or you did not stress it well enough. Also, small eraseblocks just make JFFS2 much slower than it could be.

Signature · 2 lines
Best Regards,
Artem Bityutskiy