94 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From 36bcc0c9c2bc8f56569cd735ba531a51358d7c2b Mon Sep 17 00:00:00 2001
 | 
						|
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
 | 
						|
Date: Sun, 6 Dec 2015 11:31:38 +0100
 | 
						|
Subject: [PATCH] mtd: bcm47xxpart: don't fail because of bit-flips
 | 
						|
MIME-Version: 1.0
 | 
						|
Content-Type: text/plain; charset=UTF-8
 | 
						|
Content-Transfer-Encoding: 8bit
 | 
						|
 | 
						|
Bit-flip errors may occur on NAND flashes and are harmless. Handle them
 | 
						|
gracefully as read content is still reliable and can be parsed.
 | 
						|
 | 
						|
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | 
						|
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
 | 
						|
---
 | 
						|
 drivers/mtd/bcm47xxpart.c | 38 ++++++++++++++++++++++----------------
 | 
						|
 1 file changed, 22 insertions(+), 16 deletions(-)
 | 
						|
 | 
						|
--- a/drivers/mtd/bcm47xxpart.c
 | 
						|
+++ b/drivers/mtd/bcm47xxpart.c
 | 
						|
@@ -66,11 +66,13 @@ static const char *bcm47xxpart_trx_data_
 | 
						|
 {
 | 
						|
 	uint32_t buf;
 | 
						|
 	size_t bytes_read;
 | 
						|
+	int err;
 | 
						|
 
 | 
						|
-	if (mtd_read(master, offset, sizeof(buf), &bytes_read,
 | 
						|
-		     (uint8_t *)&buf) < 0) {
 | 
						|
-		pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
 | 
						|
-			offset);
 | 
						|
+	err  = mtd_read(master, offset, sizeof(buf), &bytes_read,
 | 
						|
+			(uint8_t *)&buf);
 | 
						|
+	if (err && !mtd_is_bitflip(err)) {
 | 
						|
+		pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
 | 
						|
+			offset, err);
 | 
						|
 		goto out_default;
 | 
						|
 	}
 | 
						|
 
 | 
						|
@@ -95,6 +97,7 @@ static int bcm47xxpart_parse(struct mtd_
 | 
						|
 	int trx_part = -1;
 | 
						|
 	int last_trx_part = -1;
 | 
						|
 	int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, };
 | 
						|
+	int err;
 | 
						|
 
 | 
						|
 	/*
 | 
						|
 	 * Some really old flashes (like AT45DB*) had smaller erasesize-s, but
 | 
						|
@@ -128,10 +131,11 @@ static int bcm47xxpart_parse(struct mtd_
 | 
						|
 		}
 | 
						|
 
 | 
						|
 		/* Read beginning of the block */
 | 
						|
-		if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ,
 | 
						|
-			     &bytes_read, (uint8_t *)buf) < 0) {
 | 
						|
-			pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
 | 
						|
-			       offset);
 | 
						|
+		err = mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ,
 | 
						|
+			       &bytes_read, (uint8_t *)buf);
 | 
						|
+		if (err && !mtd_is_bitflip(err)) {
 | 
						|
+			pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
 | 
						|
+			       offset, err);
 | 
						|
 			continue;
 | 
						|
 		}
 | 
						|
 
 | 
						|
@@ -254,10 +258,11 @@ static int bcm47xxpart_parse(struct mtd_
 | 
						|
 		}
 | 
						|
 
 | 
						|
 		/* Read middle of the block */
 | 
						|
-		if (mtd_read(master, offset + 0x8000, 0x4,
 | 
						|
-			     &bytes_read, (uint8_t *)buf) < 0) {
 | 
						|
-			pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
 | 
						|
-			       offset);
 | 
						|
+		err = mtd_read(master, offset + 0x8000, 0x4, &bytes_read,
 | 
						|
+			       (uint8_t *)buf);
 | 
						|
+		if (err && !mtd_is_bitflip(err)) {
 | 
						|
+			pr_err("mtd_read error while parsing (offset: 0x%X): %d\n",
 | 
						|
+			       offset, err);
 | 
						|
 			continue;
 | 
						|
 		}
 | 
						|
 
 | 
						|
@@ -277,10 +282,11 @@ static int bcm47xxpart_parse(struct mtd_
 | 
						|
 		}
 | 
						|
 
 | 
						|
 		offset = master->size - possible_nvram_sizes[i];
 | 
						|
-		if (mtd_read(master, offset, 0x4, &bytes_read,
 | 
						|
-			     (uint8_t *)buf) < 0) {
 | 
						|
-			pr_err("mtd_read error while reading at offset 0x%X!\n",
 | 
						|
-			       offset);
 | 
						|
+		err = mtd_read(master, offset, 0x4, &bytes_read,
 | 
						|
+			       (uint8_t *)buf);
 | 
						|
+		if (err && !mtd_is_bitflip(err)) {
 | 
						|
+			pr_err("mtd_read error while reading (offset 0x%X): %d\n",
 | 
						|
+			       offset, err);
 | 
						|
 			continue;
 | 
						|
 		}
 | 
						|
 
 |