Skip to contentSkip to conversation

BUG in mtd/chips/cfi_cmdset_0002.c for 64bit width flashes (linuxppc_2_4_devel)

DISCUSSION Steffen Rumler 3 participants 3 messages Feb 6, 2004 Memory technology devices (MTD)

lore
Share & tools
lore
#0 lore raw

Hi,

We have found the following bug in mtd/chips/cfi_cmdset_0002.c for 64bit bus width.

The routine do_write_oneword() uses the DQ6 algorithm in order to detect the end of programming phase (see bitkeeper: linuxppc_2_4_devel)

oldstatus = cfi_read(map, adr);
status = cfi_read(map, adr);

while( (status & dq6) != (oldstatus & dq6) &&

        (status & dq5) != dq5 &&
        !time_after(jiffies, timeo) ) {

    if (need_resched()) {
        cfi_spin_unlock(chip->mutex);
        yield();
        cfi_spin_lock(chip->mutex);
    } else
        udelay(1);

    oldstatus = cfi_read( map, adr );
    status = cfi_read( map, adr );
}

There are two contiguous calls of cfi_read() to check for the DQ6 toggling.

But for 64bit one cfi_read() results in two flash accesses, one for the upper 32bit and the other for lower 32bit. In this way the DQ6 bits toggle for the two accesses related to one cfi_read(). The first access will be compared with the third and the second with the fourth.
The end detection is broken, the body of the while loop will never be executed.

I suggest to switch to the alternative DQ7 algorithm.

Steffen

--

--------------------------------------------------------------

Steffen Rumler
Siemens AG

Hofmannstr. 51                 Email: [email protected]
D-81359 Munich                 Phone: +49 89 722-44061
Germany                        Fax  : +49 89 722-36703

--------------------------------------------------------------

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

#1 lore raw
Quoted 29 lines · Steffen Rumler

Hi,

We have found the following bug in mtd/chips/cfi_cmdset_0002.c for 64bit bus width.

The routine do_write_oneword() uses the DQ6 algorithm in order to detect the end of programming phase (see bitkeeper: linuxppc_2_4_devel)

oldstatus = cfi_read(map, adr);
status = cfi_read(map, adr);

while( (status & dq6) != (oldstatus & dq6) &&

         (status & dq5) != dq5 &&
         !time_after(jiffies, timeo) ) {

     if (need_resched()) {
         cfi_spin_unlock(chip->mutex);
         yield();
         cfi_spin_lock(chip->mutex);
     } else
         udelay(1);

     oldstatus = cfi_read( map, adr );
     status = cfi_read( map, adr );
}

There are two contiguous calls of cfi_read() to check for the DQ6 toggling.

Quoted 7 lines

But for 64bit one cfi_read() results in two flash accesses, one for the upper 32bit and the other for lower 32bit. In this way the DQ6 bits toggle for the two accesses related to one cfi_read(). The first access will be compared with the third and the second with the fourth.
The end detection is broken, the body of the while loop will never be executed.

I suggest to switch to the alternative DQ7 algorithm.

You should probably discuss this with the folks that support the MTD layer (cc'd)

Signature · 2 lines
Gary Thomas <[email protected]>
MLB Associates
#2 lore raw
Quoted 24 lines · Gary Thomas
Quoted 23 lines · Steffen Rumler

Hi,

We have found the following bug in mtd/chips/cfi_cmdset_0002.c for 64bit bus width.

The routine do_write_oneword() uses the DQ6 algorithm in order to detect the end of programming phase (see bitkeeper: linuxppc_2_4_devel)

oldstatus = cfi_read(map, adr);
status = cfi_read(map, adr);

while( (status & dq6) != (oldstatus & dq6) &&

         (status & dq5) != dq5 &&
         !time_after(jiffies, timeo) ) {

     if (need_resched()) {
         cfi_spin_unlock(chip->mutex);
         yield();
         cfi_spin_lock(chip->mutex);
     } else
         udelay(1);
Quoted 8 lines
Quoted 8 lines
     oldstatus = cfi_read( map, adr );
     status = cfi_read( map, adr );
}

There are two contiguous calls of cfi_read() to check for the DQ6 toggling.

But for 64bit one cfi_read() results in two flash accesses, one for the upper 32bit and the other for lower 32bit.

Possibly there are 2 accesses on the bus but not to a single flash chip. If there is a problem it is with your map driver, not generating 64bit bus transactions.

My dimm memory says you need to use the FPU to generate a 64bit access on PPC.

Quoted 8 lines
Quoted 4 lines

In this way the DQ6 bits toggle
for the two accesses related to one cfi_read(). The first access will be compared with the third and the second with the fourth.
The end detection is broken, the body of the while loop will never be

executed.

Quoted 2 lines

I suggest to switch to the alternative DQ7 algorithm.

I suggest you use an uptodate version of cfi_cmdset_0002 before complaining. The logic that looks at dq5 in that loop was removed a long time ago. Of course the last merge with 2.4.x may have happened even longer ago.

Eric