diff options
Diffstat (limited to 'nuttx/drivers/mtd/ftl.c')
-rw-r--r-- | nuttx/drivers/mtd/ftl.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/nuttx/drivers/mtd/ftl.c b/nuttx/drivers/mtd/ftl.c index cdb35aa5c..6cf8f0317 100644 --- a/nuttx/drivers/mtd/ftl.c +++ b/nuttx/drivers/mtd/ftl.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/mtd/ftl.c * - * Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011-2012 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -229,6 +229,10 @@ static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer, remaining = nblocks; if (alignedblock > startblock) { + /* Check if the write is shorter than to the end of the erase block */ + + bool short_write = (remaining < (alignedblock - startblock)); + /* Read the full erase block into the buffer */ rwblock = startblock & ~mask; @@ -252,9 +256,19 @@ static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer, /* Copy the user data at the end of the buffered erase block */ offset = (startblock & mask) * dev->geo.blocksize; - nbytes = dev->geo.erasesize - offset; + + if (short_write) + { + nbytes = remaining * dev->geo.blocksize; + } + else + { + nbytes = dev->geo.erasesize - offset; + } + fvdbg("Copy %d bytes into erase block=%d at offset=%d\n", nbytes, eraseblock, offset); + memcpy(dev->eblock + offset, buffer, nbytes); /* And write the erase back to flash */ @@ -268,8 +282,16 @@ static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer, /* Then update for amount written */ - remaining -= dev->blkper - (startblock & mask); - buffer += nbytes; + if (short_write) + { + remaining = 0; + } + else + { + remaining -= dev->blkper - (startblock & mask); + } + + buffer += nbytes; } /* How handle full erase pages in the middle */ @@ -290,6 +312,7 @@ static ssize_t ftl_flush(FAR void *priv, FAR const uint8_t *buffer, fvdbg("Write %d bytes into erase block=%d at offset=0\n", dev->geo.erasesize, alignedblock); + nxfrd = MTD_BWRITE(dev->mtd, alignedblock, dev->blkper, buffer); if (nxfrd != dev->blkper) { |