UBI: fix checkpatch.pl errors and warnings
[safe/jmp/linux-2.6] / drivers / mtd / ubi / io.c
index ba5bc4a..a84f0db 100644 (file)
  */
 
 /*
- * UBI input/output unit.
+ * UBI input/output sub-system.
  *
- * This unit provides a uniform way to work with all kinds of the underlying
- * MTD devices. It also implements handy functions for reading and writing UBI
- * headers.
+ * This sub-system provides a uniform way to work with all kinds of the
+ * underlying MTD devices. It also implements handy functions for reading and
+ * writing UBI headers.
  *
  * We are trying to have a paranoid mindset and not to trust to what we read
- * from the flash media in order to be more secure and robust. So this unit
- * validates every single header it reads from the flash media.
+ * from the flash media in order to be more secure and robust. So this
+ * sub-system validates every single header it reads from the flash media.
  *
  * Some words about how the eraseblock headers are stored.
  *
  * 512-byte chunks, we have to allocate one more buffer and copy our VID header
  * to offset 448 of this buffer.
  *
- * The I/O unit does the following trick in order to avoid this extra copy.
- * It always allocates a @ubi->vid_hdr_alsize bytes buffer for the VID header
- * and returns a pointer to offset @ubi->vid_hdr_shift of this buffer. When the
- * VID header is being written out, it shifts the VID header pointer back and
- * writes the whole sub-page.
+ * The I/O sub-system does the following trick in order to avoid this extra
+ * copy. It always allocates a @ubi->vid_hdr_alsize bytes buffer for the VID
+ * header and returns a pointer to offset @ubi->vid_hdr_shift of this buffer.
+ * When the VID header is being written out, it shifts the VID header pointer
+ * back and writes the whole sub-page.
  */
 
 #include <linux/crc32.h>
@@ -98,8 +98,8 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum,
 static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum);
 static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum,
                                  const struct ubi_vid_hdr *vid_hdr);
-static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum,
-                                int offset, int len);
+static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset,
+                                int len);
 #else
 #define paranoid_check_not_bad(ubi, pnum) 0
 #define paranoid_check_peb_ec_hdr(ubi, pnum)  0
@@ -156,15 +156,19 @@ retry:
                        /*
                         * -EUCLEAN is reported if there was a bit-flip which
                         * was corrected, so this is harmless.
+                        *
+                        * We do not report about it here unless debugging is
+                        * enabled. A corresponding message will be printed
+                        * later, when it is has been scrubbed.
                         */
-                       ubi_msg("fixable bit-flip detected at PEB %d", pnum);
+                       dbg_msg("fixable bit-flip detected at PEB %d", pnum);
                        ubi_assert(len == read);
                        return UBI_IO_BITFLIPS;
                }
 
                if (read != len && retries++ < UBI_IO_RETRIES) {
-                       dbg_io("error %d while reading %d bytes from PEB %d:%d, "
-                              "read only %zd bytes, retry",
+                       dbg_io("error %d while reading %d bytes from PEB %d:%d,"
+                              " read only %zd bytes, retry",
                               err, len, pnum, offset, read);
                        yield();
                        goto retry;
@@ -173,11 +177,21 @@ retry:
                ubi_err("error %d while reading %d bytes from PEB %d:%d, "
                        "read %zd bytes", err, len, pnum, offset, read);
                ubi_dbg_dump_stack();
+
+               /*
+                * The driver should never return -EBADMSG if it failed to read
+                * all the requested data. But some buggy drivers might do
+                * this, so we change it to -EIO.
+                */
+               if (read != len && err == -EBADMSG) {
+                       ubi_assert(0);
+                       err = -EIO;
+               }
        } else {
                ubi_assert(len == read);
 
                if (ubi_dbg_is_bitflip()) {
-                       dbg_msg("bit-flip (emulated)");
+                       dbg_gen("bit-flip (emulated)");
                        err = UBI_IO_BITFLIPS;
                }
        }
@@ -202,8 +216,8 @@ retry:
  * Note, in case of an error, it is possible that something was still written
  * to the flash media, but may be some garbage.
  */
-int ubi_io_write(const struct ubi_device *ubi, const void *buf, int pnum,
-                int offset, int len)
+int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
+                int len)
 {
        int err;
        size_t written;
@@ -285,7 +299,7 @@ static void erase_callback(struct erase_info *ei)
  * zero in case of success and a negative error code in case of failure. If
  * %-EIO is returned, the physical eraseblock most probably went bad.
  */
-static int do_sync_erase(const struct ubi_device *ubi, int pnum)
+static int do_sync_erase(struct ubi_device *ubi, int pnum)
 {
        int err, retries = 0;
        struct erase_info ei;
@@ -377,29 +391,26 @@ static uint8_t patterns[] = {0xa5, 0x5a, 0x0};
  * test, a positive number of erase operations done if the test was
  * successfully passed, and other negative error codes in case of other errors.
  */
-static int torture_peb(const struct ubi_device *ubi, int pnum)
+static int torture_peb(struct ubi_device *ubi, int pnum)
 {
-       void *buf;
        int err, i, patt_count;
 
-       buf = vmalloc(ubi->peb_size);
-       if (!buf)
-               return -ENOMEM;
-
+       ubi_msg("run torture test for PEB %d", pnum);
        patt_count = ARRAY_SIZE(patterns);
        ubi_assert(patt_count > 0);
 
+       mutex_lock(&ubi->buf_mutex);
        for (i = 0; i < patt_count; i++) {
                err = do_sync_erase(ubi, pnum);
                if (err)
                        goto out;
 
                /* Make sure the PEB contains only 0xFF bytes */
-               err = ubi_io_read(ubi, buf, pnum, 0, ubi->peb_size);
+               err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size);
                if (err)
                        goto out;
 
-               err = check_pattern(buf, 0xFF, ubi->peb_size);
+               err = check_pattern(ubi->peb_buf1, 0xFF, ubi->peb_size);
                if (err == 0) {
                        ubi_err("erased PEB %d, but a non-0xFF byte found",
                                pnum);
@@ -408,17 +419,17 @@ static int torture_peb(const struct ubi_device *ubi, int pnum)
                }
 
                /* Write a pattern and check it */
-               memset(buf, patterns[i], ubi->peb_size);
-               err = ubi_io_write(ubi, buf, pnum, 0, ubi->peb_size);
+               memset(ubi->peb_buf1, patterns[i], ubi->peb_size);
+               err = ubi_io_write(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size);
                if (err)
                        goto out;
 
-               memset(buf, ~patterns[i], ubi->peb_size);
-               err = ubi_io_read(ubi, buf, pnum, 0, ubi->peb_size);
+               memset(ubi->peb_buf1, ~patterns[i], ubi->peb_size);
+               err = ubi_io_read(ubi, ubi->peb_buf1, pnum, 0, ubi->peb_size);
                if (err)
                        goto out;
 
-               err = check_pattern(buf, patterns[i], ubi->peb_size);
+               err = check_pattern(ubi->peb_buf1, patterns[i], ubi->peb_size);
                if (err == 0) {
                        ubi_err("pattern %x checking failed for PEB %d",
                                patterns[i], pnum);
@@ -428,8 +439,10 @@ static int torture_peb(const struct ubi_device *ubi, int pnum)
        }
 
        err = patt_count;
+       ubi_msg("PEB %d passed torture test, do not mark it a bad", pnum);
 
 out:
+       mutex_unlock(&ubi->buf_mutex);
        if (err == UBI_IO_BITFLIPS || err == -EBADMSG) {
                /*
                 * If a bit-flip or data integrity error was detected, the test
@@ -440,7 +453,6 @@ out:
                        pnum);
                err = -EIO;
        }
-       vfree(buf);
        return err;
 }
 
@@ -460,7 +472,7 @@ out:
  * codes in case of other errors. Note, %-EIO means that the physical
  * eraseblock is bad.
  */
-int ubi_io_sync_erase(const struct ubi_device *ubi, int pnum, int torture)
+int ubi_io_sync_erase(struct ubi_device *ubi, int pnum, int torture)
 {
        int err, ret = 0;
 
@@ -617,7 +629,7 @@ bad:
  * o %UBI_IO_PEB_EMPTY if the physical eraseblock is empty;
  * o a negative error code in case of failure.
  */
-int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum,
+int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
                       struct ubi_ec_hdr *ec_hdr, int verbose)
 {
        int err, read_err = 0;
@@ -625,6 +637,8 @@ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum,
 
        dbg_io("read EC header from PEB %d", pnum);
        ubi_assert(pnum >= 0 && pnum < ubi->peb_count);
+       if (UBI_IO_DEBUG)
+               verbose = 1;
 
        err = ubi_io_read(ubi, ec_hdr, pnum, 0, UBI_EC_HDR_SIZE);
        if (err) {
@@ -691,8 +705,8 @@ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum,
 
        if (hdr_crc != crc) {
                if (verbose) {
-                       ubi_warn("bad EC header CRC at PEB %d, calculated %#08x,"
-                                " read %#08x", pnum, crc, hdr_crc);
+                       ubi_warn("bad EC header CRC at PEB %d, calculated "
+                                "%#08x, read %#08x", pnum, crc, hdr_crc);
                        ubi_dbg_dump_ec_hdr(ec_hdr);
                }
                return UBI_IO_BAD_EC_HDR;
@@ -723,7 +737,7 @@ int ubi_io_read_ec_hdr(const struct ubi_device *ubi, int pnum,
  * case of failure. If %-EIO is returned, the physical eraseblock most probably
  * went bad.
  */
-int ubi_io_write_ec_hdr(const struct ubi_device *ubi, int pnum,
+int ubi_io_write_ec_hdr(struct ubi_device *ubi, int pnum,
                        struct ubi_ec_hdr *ec_hdr)
 {
        int err;
@@ -889,7 +903,7 @@ bad:
  *   header there);
  * o a negative error code in case of failure.
  */
-int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum,
+int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
                        struct ubi_vid_hdr *vid_hdr, int verbose)
 {
        int err, read_err = 0;
@@ -898,6 +912,8 @@ int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum,
 
        dbg_io("read VID header from PEB %d", pnum);
        ubi_assert(pnum >= 0 &&  pnum < ubi->peb_count);
+       if (UBI_IO_DEBUG)
+               verbose = 1;
 
        p = (char *)vid_hdr - ubi->vid_hdr_shift;
        err = ubi_io_read(ubi, p, pnum, ubi->vid_hdr_aloffset,
@@ -996,7 +1012,7 @@ int ubi_io_read_vid_hdr(const struct ubi_device *ubi, int pnum,
  * case of failure. If %-EIO is returned, the physical eraseblock probably went
  * bad.
  */
-int ubi_io_write_vid_hdr(const struct ubi_device *ubi, int pnum,
+int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum,
                         struct ubi_vid_hdr *vid_hdr)
 {
        int err;
@@ -1219,44 +1235,40 @@ exit:
  * @offset of the physical eraseblock @pnum, %1 if not, and a negative error
  * code if an error occurred.
  */
-static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum,
-                                int offset, int len)
+static int paranoid_check_all_ff(struct ubi_device *ubi, int pnum, int offset,
+                                int len)
 {
        size_t read;
        int err;
-       void *buf;
        loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
 
-       buf = vmalloc(len);
-       if (!buf)
-               return -ENOMEM;
-       memset(buf, 0, len);
-
-       err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
+       mutex_lock(&ubi->dbg_buf_mutex);
+       err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf);
        if (err && err != -EUCLEAN) {
                ubi_err("error %d while reading %d bytes from PEB %d:%d, "
                        "read %zd bytes", err, len, pnum, offset, read);
                goto error;
        }
 
-       err = check_pattern(buf, 0xFF, len);
+       err = check_pattern(ubi->dbg_peb_buf, 0xFF, len);
        if (err == 0) {
                ubi_err("flash region at PEB %d:%d, length %d does not "
                        "contain all 0xFF bytes", pnum, offset, len);
                goto fail;
        }
+       mutex_unlock(&ubi->dbg_buf_mutex);
 
-       vfree(buf);
        return 0;
 
 fail:
        ubi_err("paranoid check failed for PEB %d", pnum);
-       dbg_msg("hex dump of the %d-%d region", offset, offset + len);
-       print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1);
+       ubi_msg("hex dump of the %d-%d region", offset, offset + len);
+       print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1,
+                      ubi->dbg_peb_buf, len, 1);
        err = 1;
 error:
        ubi_dbg_dump_stack();
-       vfree(buf);
+       mutex_unlock(&ubi->dbg_buf_mutex);
        return err;
 }