Skip to contentSkip to conversation

P30 flash left in read status mode after a write

DISCUSSION Jon Ringle 5 participants 11 messages Feb 14, 2007 – Feb 20, 2007 Memory technology devices (MTD)

lore
Share & tools
lore

Jon Ringle

author
#0 lore raw

Hi,

We have a hardware architecture with a IXP455 processor that allows read access to a P30 flash attached to the IXP's expansion bus from a Pentium M that does it's access via the PCI bus. The flash has 4 partitions: Redboot, jffs2, fconfig, fis. I am running Linux 2.6.16.29 and I've found that whenever a write is done to the jffs2 filesystem that flash is left in read status mode and anything trying to do a read of flash directly reads only 0x0080. Reading from an mtd device seems to fix the problem. I modified the mapper utility from LDD3 so I could read flash directly from linux which illustrates the problem:

[root@rsc4 ~]# mapper /dev/mem 0x51fa0000 0x100 1|hexdump -C mapped "/dev/mem" from 1375338496 (0x51fa0000) to 1375338752 (0x51fa0100)

00000000  00 00 10 00 0b ad fa ce  01 0c 01 00 62 6f 6f 74  |............boot|
00000010  5f 73 63 72 69 70 74 00  00 00 00 01 04 11 01 0c  |_script.........|
00000020  62 6f 6f 74 5f 73 63 72  69 70 74 5f 64 61 74 61  |boot_script_data|
00000030  00 62 6f 6f 74 5f 73 63  72 69 70 74 00 25 7b 73  |.boot_script.%{s|
00000040  6e 69 66 66 7d 0a 25 7b  67 6f 7d 0a 25 7b 66 69  |niff}.%{go}.%{fi|
00000050  78 5f 7a 49 6d 61 67 65  7d 0a 00 00 00 00 00 00  |x_zImage}.......|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

*
00000100
[root@rsc4 ~]# touch xyz
[root@rsc4 ~]# mapper /dev/mem 0x51fa0000 0x100 1|hexdump -C mapped "/dev/mem" from 1375338496 (0x51fa0000) to 1375338752 (0x51fa0100) 00000000 00 80 00 80 00 80 00 80 00 80 00 80 00 80 00 80 |................| *
00000100
[root@rsc4 ~]# cat /dev/mtd2 > /dev/null
[root@rsc4 ~]# mapper /dev/mem 0x51fa0000 0x100 1|hexdump -C mapped "/dev/mem" from 1375338496 (0x51fa0000) to 1375338752 (0x51fa0100)

00000000  00 00 10 00 0b ad fa ce  01 0c 01 00 62 6f 6f 74  |............boot|
00000010  5f 73 63 72 69 70 74 00  00 00 00 01 04 11 01 0c  |_script.........|
00000020  62 6f 6f 74 5f 73 63 72  69 70 74 5f 64 61 74 61  |boot_script_data|
00000030  00 62 6f 6f 74 5f 73 63  72 69 70 74 00 25 7b 73  |.boot_script.%{s|
00000040  6e 69 66 66 7d 0a 25 7b  67 6f 7d 0a 25 7b 66 69  |niff}.%{go}.%{fi|
00000050  78 5f 7a 49 6d 61 67 65  7d 0a 00 00 00 00 00 00  |x_zImage}.......|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

*
00000100

It appears that the MTD_XIP code has what I need to get flash out of read status mode after a write, however, since I'm not actually doing execute in place, it's overkill for my purposes. It seems that writing a xip_enable() function that puts flash in ready mode and leaving the other xip_* functions defined as nothing was a quick way to fix the problem in my case:

static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
unsigned long adr)
{
struct cfi_private *cfi = map->fldrv_priv;

   if (chip->state != FL_POINT && chip->state != FL_READY) {
       map_write(map, CMD(0xff), adr);
       chip->state = FL_READY;

}
(void) map_read(map, adr);
}

This did indeed seem to fix the problem, but I'm not sure if I might inadvertently be causing some side effect. I believe that I might be taking a slight performance hit to consecutive jffs2 write operations because now each write operation will need to spend more cycles putting the flash in to a write mode.

Any advice would be appreciated.

Thanks,

Jon

#1 lore raw
Quoted 9 lines · Jon Ringle

Hi,

We have a hardware architecture with a IXP455 processor that allows read access to a P30 flash attached to the IXP's expansion bus from a Pentium M that does it's access via the PCI bus. The flash has 4 partitions:
Redboot, jffs2, fconfig, fis. I am running Linux 2.6.16.29 and I've found that whenever a write is done to the jffs2 filesystem that flash is left in read status mode and anything trying to do a read of flash directly reads only 0x0080. Reading from an mtd device seems to fix the

Yes.

Quoted 5 lines

This did indeed seem to fix the problem, but I'm not sure if I might inadvertently be causing some side effect. I believe that I might be taking a slight performance hit to consecutive jffs2 write operations because now each write operation will need to spend more cycles putting the flash in to a write mode.

You're probably better off changing the driver to put the chip back in read mode after directly from the write function. You will, as you correctly pointed out, incur a performance hit to consecutive JFFS2 writes.

Of course, I don't really see a problem here to being with though. Doing the reads and writes through the MTD layer (which JFFS2 does) should all work just fine. Unless you're trying to access the flash via something other than MTD. If so, that is likely going to be racy.

josh

#2 lore raw
In reply to Jon Ringle
Quoted 5 lines · Jon Ringle

I am running Linux 2.6.16.29 and I've
found that whenever a write is done to the jffs2 filesystem that flash is left in read status mode and anything trying to do a read of flash directly reads only 0x0080. Reading from an mtd device seems to fix the problem.

This is done on purpose. And as you deduced yourself this is so to avoid ...

Quoted 5 lines

taking a slight performance hit to consecutive jffs2 write operations because now each write operation will need to spend more cycles putting the flash in to a write mode.

Any advice would be appreciated.

First, why is this a problem for you?

Nicolas

author
#3 lore raw
Quoted 9 lines · Nicolas Pitre
Quoted 2 lines · Jon Ringle

I am running Linux 2.6.16.29 and I've found that whenever a write is done to the jffs2 filesystem that flash is left in read status mode and anything trying to do a read of flash directly reads only 0x0080. Reading from an mtd device seems to fix the problem.

This is done on purpose. And as you deduced yourself this is so to avoid ...

Quoted 8 lines
Quoted 4 lines

taking a slight performance hit to consecutive jffs2 write operations because now each write operation will need to spend more cycles putting the flash in to a write mode.

Any advice would be appreciated.

First, why is this a problem for you?

This is a problem on our (unusual) hardware because we have a Pentium M processor (not running Linux) that reads fconfig partition outside the context of the IXP processor that is running Linux. It does so via data path: Pentium -> PCI -> IXP Expansion bus -> Flash. This data path allows the Pentium to directly access the fconfig partition without needing any active code on the IXP's arm core processor to do anything to facilitate such access by the Pentium. However, when the mtd driver leaves the flash in read status mode, the Pentium just reads 0x0080 when trying to read the fconfig partition. With a change to have the mtd driver put the flash back into ready mode after a write, then I think that the Pentium only needs to deal with a temporary read failure if it happens to do a read at the same time that a write is occurring on the jffs2. In which case, the Pentium code simply spins retrying to do the read until it is successful.

Jon

#4 lore raw
Quoted 4 lines · Jon Ringle
Quoted 3 lines · Nicolas Pitre

First, why is this a problem for you?

Quoted 13 lines

This is a problem on our (unusual) hardware because we have a Pentium M processor (not running Linux) that reads fconfig partition outside the context of the IXP processor that is running Linux. It does so via data path: Pentium -> PCI -> IXP Expansion bus -> Flash. This data path allows the Pentium to directly access the fconfig partition without needing any active code on the IXP's arm core processor to do anything to facilitate such access by the Pentium. However, when the mtd driver leaves the flash in read status mode, the Pentium just reads 0x0080 when trying to read the fconfig partition. With a change to have the mtd driver put the flash back into ready mode after a write, then I think that the Pentium only needs to deal with a temporary read failure if it happens to do a read at the same time that a write is occurring on the jffs2. In which case, the Pentium code simply spins retrying to do the read until it is successful.

And how do you determine that you have a read failure?

Because the flash doesn't necessarily always have 0x00800080 to show when outside of the read mode.

Of course, since you have an unusual setup you can have an unusual patch in your own kernel tree for this issue. But this isn't entirely safe since the Pentium code might be fooled by some other flash status output that doesn,t look like a read failure.

Nicolas

author
#5 lore raw
Quoted 24 lines · Nicolas Pitre
Quoted 6 lines · Jon Ringle
Quoted 4 lines · Nicolas Pitre

First, why is this a problem for you?

Quoted 14 lines

This is a problem on our (unusual) hardware because we have a Pentium M processor (not running Linux) that reads fconfig partition outside the context of the IXP processor that is running Linux. It does so via data path: Pentium -> PCI -> IXP Expansion bus -> Flash. This data path allows the Pentium to directly access the fconfig partition without needing any active code on the IXP's arm core processor to do anything to facilitate such access by the Pentium. However, when the mtd driver leaves the flash in read status mode, the Pentium just reads 0x0080 when trying to read the fconfig partition. With a change to have the mtd driver put the flash back into ready mode after a write, then I think that the Pentium only needs to deal with a temporary read failure if it happens to do a read at the same time that a write is occurring on the jffs2. In which case, the Pentium code simply spins retrying to do the read until it is successful.

Quoted 4 lines

And how do you determine that you have a read failure?

Because the flash doesn't necessarily always have 0x00800080 to show when outside of the read mode.

True. However, the data that is being read has magic values and a checksum for validity, so the likelihood of a false positive on passing these tests is extremely unlikely.

Quoted 2 lines

Of course, since you have an unusual setup you can have an unusual patch in your own kernel tree for this issue. But this isn't entirely safe since the Pentium code might be fooled by some other flash status output that doesn,t look like a read failure.

I was intending for just patching my own kernel tree for this issue, since this issue is unlikely to be of wider audience appeal. I just wanted to present my problem to people that are more knowledgeable with the mtd code as a sanity check for my solution.

Jon

#6 lore raw
Quoted 13 lines · Jon Ringle
Quoted 5 lines

And how do you determine that you have a read failure?

Because the flash doesn't necessarily always have 0x00800080 to show when outside of the read mode.

True. However, the data that is being read has magic values and a checksum for validity, so the likelihood of a false positive on passing these tests is extremely unlikely.

Quoted 5 lines

Of course, since you have an unusual setup you can have an unusual patch in your own kernel tree for this issue. But this isn't entirely safe since the Pentium code might be fooled by some other flash status output that doesn,t look like a read failure.

Quoted 4 lines

I was intending for just patching my own kernel tree for this issue, since this issue is unlikely to be of wider audience appeal. I just wanted to present my problem to people that are more knowledgeable with the mtd code as a sanity check for my solution.

Your solution looked sane.

Nicolas

#7 lore raw
In reply to Jon Ringle
Quoted 6 lines · Jon Ringle

This did indeed seem to fix the problem, but I'm not sure if I might inadvertently be causing some side effect. I believe that I might be taking a slight performance hit to consecutive jffs2 write operations because now each write operation will need to spend more cycles putting the flash in to a write mode.

If the performance hit concerns you, you could set a timer instead of changing the chip state. Only if the timer expires - which means that consecutive writes are a non-issue - do you change the chip state.

Jörn

Signature · 2 lines
"Error protection by error detection and correction."
-- from a university class
author
#8 lore raw
Quoted 10 lines · Jörn Engel
Quoted 2 lines · Jon Ringle

This did indeed seem to fix the problem, but I'm not sure if I might inadvertently be causing some side effect. I believe that I might be taking a slight performance hit to consecutive jffs2 write operations because now each write operation will need to spend more cycles putting the flash in to a write mode.

If the performance hit concerns you, you could set a timer instead of changing the chip state. Only if the timer expires - which means that consecutive writes are a non-issue - do you change the chip state.

Using a timer sounds like a good idea. I'll keep it in mind. I'm not sure yet whether I'm concerned about the performance hit as I haven't profiled the impact yet. Has anyone got any data that shows what kind of improvement jffs2 write operations get with this optimization in place to leave flash in read status mode?

Jon

#9 lore raw
Quoted 15 lines · Jon Ringle
Quoted 9 lines · Jörn Engel
Quoted 6 lines · Jon Ringle

This did indeed seem to fix the problem, but I'm not sure if I might inadvertently be causing some side effect. I believe that I might be taking a slight performance hit to consecutive jffs2 write operations because now each write operation will need to spend more cycles putting the flash in to a write mode.

Quoted 5 lines

If the performance hit concerns you, you could set a timer instead of changing the chip state. Only if the timer expires - which means that consecutive writes are a non-issue - do you change the chip state.

Quoted 5 lines

Using a timer sounds like a good idea. I'll keep it in mind. I'm not sure yet whether I'm concerned about the performance hit as I haven't profiled the impact yet. Has anyone got any data that shows what kind of improvement jffs2 write operations get with this optimization in place to leave flash in read status mode?

It should be fairly minimal. Probably less than 5% difference.

Nicolas

#10 lore raw

HI ALL.

I'm not sure if it could help but it remind me one bug I faced over a year ago. Could you please try this fixup. It fixes improper CFI parsing in CFI drivers.

drivers/mtd/chips/cfi_cmdset_0001.c (revision 10) renamed from drivers/mtd/chips/cfi_cmdset_0001.c (revision 8) +2 -3
@@ -285,7 +285,7 @@
                            sizeof(struct cfi_intelext_otpinfo);
 
              /* Burst Read info */
-             extra_size += (extp->MinorVersion < '4') ? 6 : 5;
+             extra_size += (unsigned int)extp->extra[extra_size+1]+2;
 
              /* Number of hardware-partitions */
              extra_size += 1;
@@ -519,7 +519,7 @@
                     sizeof(struct cfi_intelext_otpinfo);
 
              /* Burst Read info */
-             offs += (extp->MinorVersion < '4') ? 6 : 5;
+             offs += (int)extp->extra[offs+1]+2;
-------------------------------------
 

Original fix message is here:http://lists.infradead.org/pipermail/linux-mtd/2005-October/014144.html

Thanks
Alexey