From 3b6b74ee378564758fcebb2e96348fc132b20c02 Mon Sep 17 00:00:00 2001
From: Gabor Juhos <juhosg@openwrt.org>
Date: Sun, 14 Mar 2010 18:20:04 +0000
Subject: atheros: fix FIS directory parsing on Top Boot flash chips

SVN-Revision: 20213
---
 .../141-redboot_various_erase_size_fix.patch       | 72 ++++++++++++++++++++++
 .../141-redboot_various_erase_size_fix.patch       | 72 ++++++++++++++++++++++
 .../141-redboot_various_erase_size_fix.patch       | 72 ++++++++++++++++++++++
 .../141-redboot_various_erase_size_fix.patch       | 72 ++++++++++++++++++++++
 4 files changed, 288 insertions(+)
 create mode 100644 target/linux/atheros/patches-2.6.30/141-redboot_various_erase_size_fix.patch
 create mode 100644 target/linux/atheros/patches-2.6.31/141-redboot_various_erase_size_fix.patch
 create mode 100644 target/linux/atheros/patches-2.6.32/141-redboot_various_erase_size_fix.patch
 create mode 100644 target/linux/atheros/patches-2.6.33/141-redboot_various_erase_size_fix.patch

(limited to 'target')

diff --git a/target/linux/atheros/patches-2.6.30/141-redboot_various_erase_size_fix.patch b/target/linux/atheros/patches-2.6.30/141-redboot_various_erase_size_fix.patch
new file mode 100644
index 0000000000..b9cb0b4bcd
--- /dev/null
+++ b/target/linux/atheros/patches-2.6.30/141-redboot_various_erase_size_fix.patch
@@ -0,0 +1,72 @@
+--- a/drivers/mtd/redboot.c
++++ b/drivers/mtd/redboot.c
+@@ -39,6 +39,22 @@ static inline int redboot_checksum(struc
+ 	return 1;
+ }
+ 
++static uint32_t mtd_get_offset_erasesize(struct mtd_info *mtd, uint64_t offset)
++{
++	struct mtd_erase_region_info *regions = mtd->eraseregions;
++	int i;
++
++	for (i = 0; i < mtd->numeraseregions; i++) {
++		if (regions[i].offset +
++		    regions[i].numblocks * regions[i].erasesize <= offset)
++			continue;
++
++		return regions[i].erasesize;
++	}
++
++	return mtd->erasesize;
++}
++
+ static int parse_redboot_partitions(struct mtd_info *master,
+                              struct mtd_partition **pparts,
+                              unsigned long fis_origin)
+@@ -55,6 +71,7 @@ static int parse_redboot_partitions(stru
+ 	int namelen = 0;
+ 	int nulllen = 0;
+ 	int numslots;
++	int first_slot;
+ 	unsigned long offset;
+ #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
+ 	static char nullstring[] = "unallocated";
+@@ -168,7 +185,10 @@ static int parse_redboot_partitions(stru
+ 		goto out;
+ 	}
+ 
+-	for (i = 0; i < numslots; i++) {
++	first_slot = (buf[i].flash_base & (master->erasesize - 1)) /
++		     sizeof(struct fis_image_desc);
++
++	for (i = first_slot; i < first_slot + numslots; i++) {
+ 		struct fis_list *new_fl, **prev;
+ 
+ 		if (buf[i].name[0] == 0xff) {
+@@ -244,12 +264,13 @@ static int parse_redboot_partitions(stru
+ 	}
+ #endif
+ 	for ( ; i<nrparts; i++) {
+-		if(max_offset < buf[i].flash_base + buf[i].size)
+-			max_offset = buf[i].flash_base + buf[i].size;
+ 		parts[i].size = fl->img->size;
+ 		parts[i].offset = fl->img->flash_base;
+ 		parts[i].name = names;
+ 
++		if (max_offset < parts[i].offset + parts[i].size)
++			max_offset = parts[i].offset + parts[i].size;
++
+ 		strcpy(names, fl->img->name);
+ #ifdef CONFIG_MTD_REDBOOT_PARTS_READONLY
+ 		if (!memcmp(names, "RedBoot", 8) ||
+@@ -279,7 +300,9 @@ static int parse_redboot_partitions(stru
+ 		fl = fl->next;
+ 		kfree(tmp_fl);
+ 	}
+-	if(master->size - max_offset >= master->erasesize)
++
++	if (master->size - max_offset >=
++	    mtd_get_offset_erasesize(master, max_offset))
+ 	{
+ 		parts[nrparts].size = master->size - max_offset;
+ 		parts[nrparts].offset = max_offset;
diff --git a/target/linux/atheros/patches-2.6.31/141-redboot_various_erase_size_fix.patch b/target/linux/atheros/patches-2.6.31/141-redboot_various_erase_size_fix.patch
new file mode 100644
index 0000000000..b9cb0b4bcd
--- /dev/null
+++ b/target/linux/atheros/patches-2.6.31/141-redboot_various_erase_size_fix.patch
@@ -0,0 +1,72 @@
+--- a/drivers/mtd/redboot.c
++++ b/drivers/mtd/redboot.c
+@@ -39,6 +39,22 @@ static inline int redboot_checksum(struc
+ 	return 1;
+ }
+ 
++static uint32_t mtd_get_offset_erasesize(struct mtd_info *mtd, uint64_t offset)
++{
++	struct mtd_erase_region_info *regions = mtd->eraseregions;
++	int i;
++
++	for (i = 0; i < mtd->numeraseregions; i++) {
++		if (regions[i].offset +
++		    regions[i].numblocks * regions[i].erasesize <= offset)
++			continue;
++
++		return regions[i].erasesize;
++	}
++
++	return mtd->erasesize;
++}
++
+ static int parse_redboot_partitions(struct mtd_info *master,
+                              struct mtd_partition **pparts,
+                              unsigned long fis_origin)
+@@ -55,6 +71,7 @@ static int parse_redboot_partitions(stru
+ 	int namelen = 0;
+ 	int nulllen = 0;
+ 	int numslots;
++	int first_slot;
+ 	unsigned long offset;
+ #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
+ 	static char nullstring[] = "unallocated";
+@@ -168,7 +185,10 @@ static int parse_redboot_partitions(stru
+ 		goto out;
+ 	}
+ 
+-	for (i = 0; i < numslots; i++) {
++	first_slot = (buf[i].flash_base & (master->erasesize - 1)) /
++		     sizeof(struct fis_image_desc);
++
++	for (i = first_slot; i < first_slot + numslots; i++) {
+ 		struct fis_list *new_fl, **prev;
+ 
+ 		if (buf[i].name[0] == 0xff) {
+@@ -244,12 +264,13 @@ static int parse_redboot_partitions(stru
+ 	}
+ #endif
+ 	for ( ; i<nrparts; i++) {
+-		if(max_offset < buf[i].flash_base + buf[i].size)
+-			max_offset = buf[i].flash_base + buf[i].size;
+ 		parts[i].size = fl->img->size;
+ 		parts[i].offset = fl->img->flash_base;
+ 		parts[i].name = names;
+ 
++		if (max_offset < parts[i].offset + parts[i].size)
++			max_offset = parts[i].offset + parts[i].size;
++
+ 		strcpy(names, fl->img->name);
+ #ifdef CONFIG_MTD_REDBOOT_PARTS_READONLY
+ 		if (!memcmp(names, "RedBoot", 8) ||
+@@ -279,7 +300,9 @@ static int parse_redboot_partitions(stru
+ 		fl = fl->next;
+ 		kfree(tmp_fl);
+ 	}
+-	if(master->size - max_offset >= master->erasesize)
++
++	if (master->size - max_offset >=
++	    mtd_get_offset_erasesize(master, max_offset))
+ 	{
+ 		parts[nrparts].size = master->size - max_offset;
+ 		parts[nrparts].offset = max_offset;
diff --git a/target/linux/atheros/patches-2.6.32/141-redboot_various_erase_size_fix.patch b/target/linux/atheros/patches-2.6.32/141-redboot_various_erase_size_fix.patch
new file mode 100644
index 0000000000..b9cb0b4bcd
--- /dev/null
+++ b/target/linux/atheros/patches-2.6.32/141-redboot_various_erase_size_fix.patch
@@ -0,0 +1,72 @@
+--- a/drivers/mtd/redboot.c
++++ b/drivers/mtd/redboot.c
+@@ -39,6 +39,22 @@ static inline int redboot_checksum(struc
+ 	return 1;
+ }
+ 
++static uint32_t mtd_get_offset_erasesize(struct mtd_info *mtd, uint64_t offset)
++{
++	struct mtd_erase_region_info *regions = mtd->eraseregions;
++	int i;
++
++	for (i = 0; i < mtd->numeraseregions; i++) {
++		if (regions[i].offset +
++		    regions[i].numblocks * regions[i].erasesize <= offset)
++			continue;
++
++		return regions[i].erasesize;
++	}
++
++	return mtd->erasesize;
++}
++
+ static int parse_redboot_partitions(struct mtd_info *master,
+                              struct mtd_partition **pparts,
+                              unsigned long fis_origin)
+@@ -55,6 +71,7 @@ static int parse_redboot_partitions(stru
+ 	int namelen = 0;
+ 	int nulllen = 0;
+ 	int numslots;
++	int first_slot;
+ 	unsigned long offset;
+ #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
+ 	static char nullstring[] = "unallocated";
+@@ -168,7 +185,10 @@ static int parse_redboot_partitions(stru
+ 		goto out;
+ 	}
+ 
+-	for (i = 0; i < numslots; i++) {
++	first_slot = (buf[i].flash_base & (master->erasesize - 1)) /
++		     sizeof(struct fis_image_desc);
++
++	for (i = first_slot; i < first_slot + numslots; i++) {
+ 		struct fis_list *new_fl, **prev;
+ 
+ 		if (buf[i].name[0] == 0xff) {
+@@ -244,12 +264,13 @@ static int parse_redboot_partitions(stru
+ 	}
+ #endif
+ 	for ( ; i<nrparts; i++) {
+-		if(max_offset < buf[i].flash_base + buf[i].size)
+-			max_offset = buf[i].flash_base + buf[i].size;
+ 		parts[i].size = fl->img->size;
+ 		parts[i].offset = fl->img->flash_base;
+ 		parts[i].name = names;
+ 
++		if (max_offset < parts[i].offset + parts[i].size)
++			max_offset = parts[i].offset + parts[i].size;
++
+ 		strcpy(names, fl->img->name);
+ #ifdef CONFIG_MTD_REDBOOT_PARTS_READONLY
+ 		if (!memcmp(names, "RedBoot", 8) ||
+@@ -279,7 +300,9 @@ static int parse_redboot_partitions(stru
+ 		fl = fl->next;
+ 		kfree(tmp_fl);
+ 	}
+-	if(master->size - max_offset >= master->erasesize)
++
++	if (master->size - max_offset >=
++	    mtd_get_offset_erasesize(master, max_offset))
+ 	{
+ 		parts[nrparts].size = master->size - max_offset;
+ 		parts[nrparts].offset = max_offset;
diff --git a/target/linux/atheros/patches-2.6.33/141-redboot_various_erase_size_fix.patch b/target/linux/atheros/patches-2.6.33/141-redboot_various_erase_size_fix.patch
new file mode 100644
index 0000000000..b9cb0b4bcd
--- /dev/null
+++ b/target/linux/atheros/patches-2.6.33/141-redboot_various_erase_size_fix.patch
@@ -0,0 +1,72 @@
+--- a/drivers/mtd/redboot.c
++++ b/drivers/mtd/redboot.c
+@@ -39,6 +39,22 @@ static inline int redboot_checksum(struc
+ 	return 1;
+ }
+ 
++static uint32_t mtd_get_offset_erasesize(struct mtd_info *mtd, uint64_t offset)
++{
++	struct mtd_erase_region_info *regions = mtd->eraseregions;
++	int i;
++
++	for (i = 0; i < mtd->numeraseregions; i++) {
++		if (regions[i].offset +
++		    regions[i].numblocks * regions[i].erasesize <= offset)
++			continue;
++
++		return regions[i].erasesize;
++	}
++
++	return mtd->erasesize;
++}
++
+ static int parse_redboot_partitions(struct mtd_info *master,
+                              struct mtd_partition **pparts,
+                              unsigned long fis_origin)
+@@ -55,6 +71,7 @@ static int parse_redboot_partitions(stru
+ 	int namelen = 0;
+ 	int nulllen = 0;
+ 	int numslots;
++	int first_slot;
+ 	unsigned long offset;
+ #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
+ 	static char nullstring[] = "unallocated";
+@@ -168,7 +185,10 @@ static int parse_redboot_partitions(stru
+ 		goto out;
+ 	}
+ 
+-	for (i = 0; i < numslots; i++) {
++	first_slot = (buf[i].flash_base & (master->erasesize - 1)) /
++		     sizeof(struct fis_image_desc);
++
++	for (i = first_slot; i < first_slot + numslots; i++) {
+ 		struct fis_list *new_fl, **prev;
+ 
+ 		if (buf[i].name[0] == 0xff) {
+@@ -244,12 +264,13 @@ static int parse_redboot_partitions(stru
+ 	}
+ #endif
+ 	for ( ; i<nrparts; i++) {
+-		if(max_offset < buf[i].flash_base + buf[i].size)
+-			max_offset = buf[i].flash_base + buf[i].size;
+ 		parts[i].size = fl->img->size;
+ 		parts[i].offset = fl->img->flash_base;
+ 		parts[i].name = names;
+ 
++		if (max_offset < parts[i].offset + parts[i].size)
++			max_offset = parts[i].offset + parts[i].size;
++
+ 		strcpy(names, fl->img->name);
+ #ifdef CONFIG_MTD_REDBOOT_PARTS_READONLY
+ 		if (!memcmp(names, "RedBoot", 8) ||
+@@ -279,7 +300,9 @@ static int parse_redboot_partitions(stru
+ 		fl = fl->next;
+ 		kfree(tmp_fl);
+ 	}
+-	if(master->size - max_offset >= master->erasesize)
++
++	if (master->size - max_offset >=
++	    mtd_get_offset_erasesize(master, max_offset))
+ 	{
+ 		parts[nrparts].size = master->size - max_offset;
+ 		parts[nrparts].offset = max_offset;
-- 
cgit v1.2.3