diff mbox

[U-Boot,v1,6/7] dfu, nand, ubi: fix erasing after write finish

Message ID 1464152832-11200-7-git-send-email-hs@denx.de
State Superseded
Delegated to: Tom Rini
Headers show

Commit Message

Heiko Schocher May 25, 2016, 5:07 a.m. UTC
writting to ubi nand partitions need after write ends an erase
of the remaining sectors. This fail, if dfu write size was not
a multiple of erasesize, example log:

Failure erase: -1

Fix this error.

Signed-off-by: Heiko Schocher <hs@denx.de>
---

 drivers/dfu/dfu_nand.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Comments

Scott Wood May 25, 2016, 5:33 a.m. UTC | #1
On 05/25/2016 12:07 AM, Heiko Schocher wrote:
> writting to ubi nand partitions need after write ends an erase
> of the remaining sectors. This fail, if dfu write size was not
> a multiple of erasesize, example log:
> 
> Failure erase: -1
> 
> Fix this error.
> 
> Signed-off-by: Heiko Schocher <hs@denx.de>

Why don't you just erase the whole partition up front?

-Scott
Heiko Schocher May 25, 2016, 6:21 a.m. UTC | #2
Hello Scott,

Am 25.05.2016 um 07:33 schrieb Scott Wood:
> On 05/25/2016 12:07 AM, Heiko Schocher wrote:
>> writting to ubi nand partitions need after write ends an erase
>> of the remaining sectors. This fail, if dfu write size was not
>> a multiple of erasesize, example log:
>>
>> Failure erase: -1
>>
>> Fix this error.
>>
>> Signed-off-by: Heiko Schocher <hs@denx.de>
>
> Why don't you just erase the whole partition up front?

Good question ... I think the reason is that if we erase a big partition
at once on dfu start, dfu-util rans into timeout ... but may I am wrong ...

IIRC at the end of a DFU transfer DFU protocol sends a "flush" to the
device ... where we currently erase the remaining sectors ... we need
this on an ubi partition, else there may remain old used UBI sectors ...
(BTW: we need an "ubi format" command ...)

@Lukasz? Am I correct? Or could we simple erase before writting?

bye,
Heiko
Łukasz Majewski May 30, 2016, 9:51 a.m. UTC | #3
Hi Heiko,

> Hello Scott,
> 
> Am 25.05.2016 um 07:33 schrieb Scott Wood:
> > On 05/25/2016 12:07 AM, Heiko Schocher wrote:
> >> writting to ubi nand partitions need after write ends an erase
> >> of the remaining sectors. This fail, if dfu write size was not
> >> a multiple of erasesize, example log:
> >>
> >> Failure erase: -1

Is this a new bug? Or is this a regression?

> >>
> >> Fix this error.
> >>
> >> Signed-off-by: Heiko Schocher <hs@denx.de>
> >
> > Why don't you just erase the whole partition up front?
> 
> Good question ... I think the reason is that if we erase a big
> partition at once on dfu start, dfu-util rans into timeout ... but
> may I am wrong ...

This is interesting, since we had similar problem with eMMC, but on the
end of writing large files to FS.

To fix this issue, the deferred write has been introduced [1]:
SHA1: fc18f8d170ecc7e15269ad5312ec643addb42491

> 
> IIRC at the end of a DFU transfer DFU protocol sends a "flush" to the
> device ... 

Yes, correct, we do that.

> where we currently erase the remaining sectors 

I'm not the "regular" user of NAND part of DFU framework. However,
AFAIK each sector is erased just before writing (dfu_nand.c @ line 62).

The same scheme should be performed just before writing last chunk of
data to NAND.

> ... we need
> this on an ubi partition, else there may remain old used UBI
> sectors ... (BTW: we need an "ubi format" command ...)
> 
> @Lukasz? Am I correct? Or could we simple erase before writting?

I'm just wondering if have you tried erasing the whole NAND area before
starting DFU operation?
How long does it take to erase large NAND area for e.g. rootfs?

If I remember correctly, the timeout in dfu-util is 5 seconds sharp. 


Generally, I'm fine with erasing NAND sectors just before writing (as
we do it up till now in the NAND part of DFU).

> 
> bye,
> Heiko
Heiko Schocher May 30, 2016, 10:15 a.m. UTC | #4
Hello Lukasz,

Am 30.05.2016 um 11:51 schrieb Lukasz Majewski:
> Hi Heiko,
>
>> Hello Scott,
>>
>> Am 25.05.2016 um 07:33 schrieb Scott Wood:
>>> On 05/25/2016 12:07 AM, Heiko Schocher wrote:
>>>> writting to ubi nand partitions need after write ends an erase
>>>> of the remaining sectors. This fail, if dfu write size was not
>>>> a multiple of erasesize, example log:
>>>>
>>>> Failure erase: -1
>
> Is this a new bug? Or is this a regression?

This is a fix of a current Bug.

>>>> Fix this error.
>>>>
>>>> Signed-off-by: Heiko Schocher <hs@denx.de>
>>>
>>> Why don't you just erase the whole partition up front?
>>
>> Good question ... I think the reason is that if we erase a big
>> partition at once on dfu start, dfu-util rans into timeout ... but
>> may I am wrong ...
>
> This is interesting, since we had similar problem with eMMC, but on the
> end of writing large files to FS.
>
> To fix this issue, the deferred write has been introduced [1]:
> SHA1: fc18f8d170ecc7e15269ad5312ec643addb42491

I had downloaded files > 300MiB IIRC without problems on NAND.

>> IIRC at the end of a DFU transfer DFU protocol sends a "flush" to the
>> device ...
>
> Yes, correct, we do that.
>
>> where we currently erase the remaining sectors
>
> I'm not the "regular" user of NAND part of DFU framework. However,
> AFAIK each sector is erased just before writing (dfu_nand.c @ line 62).

Yep, and this is currrent state and works fine (on the siemens boards)
And so we need at the end in the flush state of the dfu protcol
to erase the sectors on the end of the partition, if it is an ubi partition.

> The same scheme should be performed just before writing last chunk of
> data to NAND.
>
>> ... we need
>> this on an ubi partition, else there may remain old used UBI
>> sectors ... (BTW: we need an "ubi format" command ...)
>>
>> @Lukasz? Am I correct? Or could we simple erase before writting?
>
> I'm just wondering if have you tried erasing the whole NAND area before
> starting DFU operation?
> How long does it take to erase large NAND area for e.g. rootfs?

I must measure this value ... but just posted the etamin module support,
and there is a DDP Nand with 4GiB ... and there is a big fat (UBI) partition
at the end:

device nand2 <omap2-nand_concat>, # parts = 9
  #: name                size            offset          mask_flags
[...]
  8: rootfs              0xff080000      0x00f80000      0

> If I remember correctly, the timeout in dfu-util is 5 seconds sharp.

Yes, this is may too small, right, just erased the DDP nand on the
etamin module:

U-Boot# nand device 0
Device 0: nand0... is now current device
U-Boot# time nand erase f80000 7f080000

NAND erase: device 0 offset 0xf80000, size 0x7f080000
[...]
Erasing at 0x7ff80000 -- 100% complete.
OK

time: 3.999 seconds
U-Boot# nand device 1
Device 1: nand1... is now current device
U-Boot# time nand erase.chip

NAND erase.chip: device 1 whole chip
[...]
Erasing at 0x7ff80000 -- 100% complete.
OK

time: 4.019 seconds
U-Boot#

~8seconds for erasing the hole partition ...

> Generally, I'm fine with erasing NAND sectors just before writing (as
> we do it up till now in the NAND part of DFU).

Thanks for clarification!

bye,
Heiko
Łukasz Majewski May 30, 2016, 1:13 p.m. UTC | #5
Hi Heiko,

> Hello Lukasz,
> 
> Am 30.05.2016 um 11:51 schrieb Lukasz Majewski:
> > Hi Heiko,
> >
> >> Hello Scott,
> >>
> >> Am 25.05.2016 um 07:33 schrieb Scott Wood:
> >>> On 05/25/2016 12:07 AM, Heiko Schocher wrote:
> >>>> writting to ubi nand partitions need after write ends an erase
> >>>> of the remaining sectors. This fail, if dfu write size was not
> >>>> a multiple of erasesize, example log:
> >>>>
> >>>> Failure erase: -1
> >
> > Is this a new bug? Or is this a regression?
> 
> This is a fix of a current Bug.

Ok.

> 
> >>>> Fix this error.
> >>>>
> >>>> Signed-off-by: Heiko Schocher <hs@denx.de>
> >>>
> >>> Why don't you just erase the whole partition up front?
> >>
> >> Good question ... I think the reason is that if we erase a big
> >> partition at once on dfu start, dfu-util rans into timeout ... but
> >> may I am wrong ...
> >
> > This is interesting, since we had similar problem with eMMC, but on
> > the end of writing large files to FS.
> >
> > To fix this issue, the deferred write has been introduced [1]:
> > SHA1: fc18f8d170ecc7e15269ad5312ec643addb42491
> 
> I had downloaded files > 300MiB IIRC without problems on NAND.
> 
> >> IIRC at the end of a DFU transfer DFU protocol sends a "flush" to
> >> the device ...
> >
> > Yes, correct, we do that.
> >
> >> where we currently erase the remaining sectors
> >
> > I'm not the "regular" user of NAND part of DFU framework. However,
> > AFAIK each sector is erased just before writing (dfu_nand.c @ line
> > 62).
> 
> Yep, and this is currrent state and works fine (on the siemens boards)
> And so we need at the end in the flush state of the dfu protcol
> to erase the sectors on the end of the partition, if it is an ubi
> partition.

Then we should stick with this scheme.

> 
> > The same scheme should be performed just before writing last chunk
> > of data to NAND.
> >
> >> ... we need
> >> this on an ubi partition, else there may remain old used UBI
> >> sectors ... (BTW: we need an "ubi format" command ...)
> >>
> >> @Lukasz? Am I correct? Or could we simple erase before writting?
> >
> > I'm just wondering if have you tried erasing the whole NAND area
> > before starting DFU operation?
> > How long does it take to erase large NAND area for e.g. rootfs?
> 
> I must measure this value ... but just posted the etamin module
> support, and there is a DDP Nand with 4GiB ... and there is a big fat
> (UBI) partition at the end:
> 
> device nand2 <omap2-nand_concat>, # parts = 9
>   #: name                size            offset          mask_flags
> [...]
>   8: rootfs              0xff080000      0x00f80000      0
> 
> > If I remember correctly, the timeout in dfu-util is 5 seconds sharp.
> 
> Yes, this is may too small, right, just erased the DDP nand on the
> etamin module:
> 
> U-Boot# nand device 0
> Device 0: nand0... is now current device
> U-Boot# time nand erase f80000 7f080000
> 
> NAND erase: device 0 offset 0xf80000, size 0x7f080000
> [...]
> Erasing at 0x7ff80000 -- 100% complete.
> OK
> 
> time: 3.999 seconds
> U-Boot# nand device 1
> Device 1: nand1... is now current device
> U-Boot# time nand erase.chip
> 
> NAND erase.chip: device 1 whole chip
> [...]
> Erasing at 0x7ff80000 -- 100% complete.
> OK
> 
> time: 4.019 seconds
> U-Boot#
> 
> ~8seconds for erasing the hole partition ...

So, then we would need to add some extra code to support erasing the
whole partition before flashing. 

However, I think that we should use the current scheme and erase the
last sector just before writing.

> 
> > Generally, I'm fine with erasing NAND sectors just before writing
> > (as we do it up till now in the NAND part of DFU).
> 
> Thanks for clarification!

No problem.

> 
> bye,
> Heiko
diff mbox

Patch

diff --git a/drivers/dfu/dfu_nand.c b/drivers/dfu/dfu_nand.c
index da2278e..f60d032 100644
--- a/drivers/dfu/dfu_nand.c
+++ b/drivers/dfu/dfu_nand.c
@@ -143,6 +143,7 @@  static int dfu_read_medium_nand(struct dfu_entity *dfu, u64 offset, void *buf,
 static int dfu_flush_medium_nand(struct dfu_entity *dfu)
 {
 	int ret = 0;
+	u64 off;
 
 	/* in case of ubi partition, erase rest of the partition */
 	if (dfu->data.nand.ubi) {
@@ -159,7 +160,16 @@  static int dfu_flush_medium_nand(struct dfu_entity *dfu)
 		nand = &nand_info[nand_curr_device];
 
 		memset(&opts, 0, sizeof(opts));
-		opts.offset = dfu->data.nand.start + dfu->offset +
+		off = dfu->offset;
+		if ((off & (nand->erasesize - 1)) != 0) {
+			/*
+			 * last write ended with unaligned length
+			 * sector is erased, jump to next
+			 */
+			off = off & ~((nand->erasesize - 1));
+			off += nand->erasesize;
+		}
+		opts.offset = dfu->data.nand.start + off +
 				dfu->bad_skip;
 		opts.length = dfu->data.nand.start +
 				dfu->data.nand.size - opts.offset;