]> www.infradead.org Git - mtd-utils.git/commitdiff
UBI Utils: pfiflash did not erase block before writing to it
authorAlexander Schmidt <alexs@linux.vnet.ibm.com>
Wed, 21 Feb 2007 09:40:13 +0000 (10:40 +0100)
committerJosh Boyer <jwboyer@gmail.com>
Wed, 21 Feb 2007 13:23:50 +0000 (07:23 -0600)
Pfiflash should erase raw flash regions before overwriting them and check for
bad blocks in case of NAND flash.

Signed-off-by: Alexander Schmidt <alexs@linux.vnet.ibm.com>
Signed-off-by: Frank Haverkamp <haver@vnet.ibm.com>
Signed-off-by: Josh Boyer <jwboyer@gmail.com>
ubi-utils/src/libpfiflash.c
ubi-utils/src/pfiflash_error.h

index 0be1f2cbd20bcbd7acf1dacae83fa623da72356f..4dfafeae33a379caec48cd550a30dbfd260029e3 100644 (file)
 #define __USE_GNU
 #include <string.h>
 #include <stdlib.h>
+#include <sys/ioctl.h>
 
 #include <libubi.h>
 #include <pfiflash.h>
 
 #include <mtd/ubi-user.h>      /* FIXME Is this ok here? */
+#include <mtd/mtd-user.h>
 
 #include "pfiflash_error.h"
 #include "ubimirror.h"
@@ -554,6 +556,45 @@ write_normal_volume(int devno, uint32_t id, size_t update_size, FILE* fp_in,
        return rc;
 }
 
+static int
+erase_mtd_region(FILE* file_p, int start, int length)
+{
+       int rc, fd;
+       erase_info_t erase;
+       mtd_info_t mtdinfo;
+       loff_t offset = start;
+       loff_t end = offset + length;
+
+       fd = fileno(file_p);
+       if (fd < 0)
+               return -PFIFLASH_ERR_MTD_ERASE;
+
+       rc = ioctl(fd, MEMGETINFO, &mtdinfo);
+       if (rc)
+               return -PFIFLASH_ERR_MTD_ERASE;
+
+       /* check for bad blocks in case of NAND flash */
+       if (mtdinfo.type == MTD_NANDFLASH) {
+               while (offset < end) {
+                       rc = ioctl(fd, MEMGETBADBLOCK, &offset);
+                       if (rc > 0) {
+                               return -PFIFLASH_ERR_MTD_ERASE;
+                       }
+
+                       offset += mtdinfo.erasesize;
+               }
+       }
+
+       erase.start = start;
+       erase.length = length;
+
+       rc = ioctl(fd, MEMERASE, &erase);
+       if (rc) {
+               return -PFIFLASH_ERR_MTD_ERASE;
+       }
+
+       return rc;
+}
 
 /**
  * process_raw_volumes - writes the raw sections of the PFI data
@@ -582,7 +623,7 @@ process_raw_volumes(FILE* pfi, list_t pfi_raws, const char* rawdev,
        void *i;
        uint32_t crc, crc32_table[256];
        size_t j, k;
-       FILE* mtd;
+       FILE* mtd = NULL;
        list_t ptr;
 
        if (is_empty(pfi_raws))
@@ -639,6 +680,12 @@ process_raw_volumes(FILE* pfi, list_t pfi_raws, const char* rawdev,
                }
 
                for (j = 0; j < r->starts_size; j++) {
+                       rc = erase_mtd_region(mtd, r->starts[j], r->data_size);
+                       if (rc) {
+                               EBUF(PFIFLASH_ERRSTR[-rc]);
+                               goto err;
+                       }
+
                        fseek(mtd, r->starts[j], SEEK_SET);
                        for (k = 0; k < r->data_size; k++) {
                                int c = fputc((int)pfi_data[k], mtd);
@@ -656,6 +703,7 @@ process_raw_volumes(FILE* pfi, list_t pfi_raws, const char* rawdev,
                        }
                }
                rc = fclose(mtd);
+               mtd = NULL;
                if (rc != 0) {
                        rc = -PFIFLASH_ERR_MTD_CLOSE;
                        EBUF(PFIFLASH_ERRSTR[-rc], rawdev);
@@ -664,6 +712,8 @@ process_raw_volumes(FILE* pfi, list_t pfi_raws, const char* rawdev,
        }
 
  err:
+       if (mtd != NULL)
+               fclose(mtd);
        if (pfi_data != NULL)
                free(pfi_data);
        return rc;
index 34b705ed801eae45d2c333aec33b82b0e46ef085..c06232af8fb6a9be18542e3e074e9a4c614aba7c 100644 (file)
@@ -41,7 +41,8 @@ enum pfiflash_err {
        PFIFLASH_ERR_PDD_UNKNOWN,
        PFIFLASH_ERR_MTD_OPEN,
        PFIFLASH_ERR_MTD_CLOSE,
-       PFIFLASH_ERR_CRC_CHECK
+       PFIFLASH_ERR_CRC_CHECK,
+       PFIFLASH_ERR_MTD_ERASE
 };
 
 const char *const PFIFLASH_ERRSTR[] = {
@@ -63,7 +64,8 @@ const char *const PFIFLASH_ERRSTR[] = {
        "unknown PDD handling algorithm",
        "couldn't open MTD device %s",
        "couldn't close MTD device %s",
-       "CRC check failed: given=0x%08x, calculated=0x%08x"
+       "CRC check failed: given=0x%08x, calculated=0x%08x",
+       "couldn't erase raw mtd region"
 };
 
 #endif /* __PFIFLASH_ERROR_H__ */