|
@@ -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
|
|
@@ -202,8 +202,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 +285,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 +377,25 @@ 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;
|
|
|
-
|
|
|
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 +404,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);
|
|
@@ -430,6 +426,7 @@ static int torture_peb(const struct ubi_device *ubi, int pnum)
|
|
|
err = patt_count;
|
|
|
|
|
|
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 +437,6 @@ out:
|
|
|
pnum);
|
|
|
err = -EIO;
|
|
|
}
|
|
|
- vfree(buf);
|
|
|
return err;
|
|
|
}
|
|
|
|
|
@@ -460,7 +456,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 +613,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;
|
|
@@ -723,7 +719,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 +885,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;
|
|
@@ -996,7 +992,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 +1215,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);
|
|
|
+ print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4,
|
|
|
+ ubi->dbg_peb_buf, len, 1);
|
|
|
err = 1;
|
|
|
error:
|
|
|
ubi_dbg_dump_stack();
|
|
|
- vfree(buf);
|
|
|
+ mutex_unlock(&ubi->dbg_buf_mutex);
|
|
|
return err;
|
|
|
}
|
|
|
|