kernel: mtd: allow partial block erase
This fixes error erasing partial mtd partition which does not start on eraseblock boundary and allows using fconfig to configure redboot on devices such as the Gateworks Cambria. Signed-off-by: Maciej Skrzypek <maciej.skrzypek@flytronic.pl> SVN-Revision: 41733
This commit is contained in:
parent
51fbfde474
commit
1d232f354a
7 changed files with 28 additions and 21 deletions
|
@ -9,7 +9,7 @@
|
||||||
/* Our partition linked list */
|
/* Our partition linked list */
|
||||||
static LIST_HEAD(mtd_partitions);
|
static LIST_HEAD(mtd_partitions);
|
||||||
static DEFINE_MUTEX(mtd_partitions_mutex);
|
static DEFINE_MUTEX(mtd_partitions_mutex);
|
||||||
@@ -231,13 +233,60 @@ static int part_erase(struct mtd_info *m
|
@@ -231,13 +233,61 @@ static int part_erase(struct mtd_info *m
|
||||||
struct mtd_part *part = PART(mtd);
|
struct mtd_part *part = PART(mtd);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
+ part->master->erasesize,
|
+ part->master->erasesize,
|
||||||
+ &readlen, instr->erase_buf);
|
+ &readlen, instr->erase_buf);
|
||||||
+
|
+
|
||||||
|
+ instr->len += instr->erase_buf_ofs;
|
||||||
+ instr->partial_start = true;
|
+ instr->partial_start = true;
|
||||||
+ } else {
|
+ } else {
|
||||||
+ mtd_ofs = part->offset + part->mtd.size;
|
+ mtd_ofs = part->offset + part->mtd.size;
|
||||||
|
@ -70,7 +71,7 @@
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,7 +294,25 @@ void mtd_erase_callback(struct erase_inf
|
@@ -245,7 +295,25 @@ void mtd_erase_callback(struct erase_inf
|
||||||
{
|
{
|
||||||
if (instr->mtd->_erase == part_erase) {
|
if (instr->mtd->_erase == part_erase) {
|
||||||
struct mtd_part *part = PART(instr->mtd);
|
struct mtd_part *part = PART(instr->mtd);
|
||||||
|
@ -96,7 +97,7 @@
|
||||||
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
||||||
instr->fail_addr -= part->offset;
|
instr->fail_addr -= part->offset;
|
||||||
instr->addr -= part->offset;
|
instr->addr -= part->offset;
|
||||||
@@ -503,18 +570,24 @@ static struct mtd_part *allocate_partiti
|
@@ -503,18 +571,24 @@ static struct mtd_part *allocate_partiti
|
||||||
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||||
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
||||||
/* Doesn't start on a boundary of major erase size */
|
/* Doesn't start on a boundary of major erase size */
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
/* Our partition linked list */
|
/* Our partition linked list */
|
||||||
static LIST_HEAD(mtd_partitions);
|
static LIST_HEAD(mtd_partitions);
|
||||||
static DEFINE_MUTEX(mtd_partitions_mutex);
|
static DEFINE_MUTEX(mtd_partitions_mutex);
|
||||||
@@ -231,13 +233,60 @@ static int part_erase(struct mtd_info *m
|
@@ -231,13 +233,61 @@ static int part_erase(struct mtd_info *m
|
||||||
struct mtd_part *part = PART(mtd);
|
struct mtd_part *part = PART(mtd);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
+ part->master->erasesize,
|
+ part->master->erasesize,
|
||||||
+ &readlen, instr->erase_buf);
|
+ &readlen, instr->erase_buf);
|
||||||
+
|
+
|
||||||
|
+ instr->len += instr->erase_buf_ofs;
|
||||||
+ instr->partial_start = true;
|
+ instr->partial_start = true;
|
||||||
+ } else {
|
+ } else {
|
||||||
+ mtd_ofs = part->offset + part->mtd.size;
|
+ mtd_ofs = part->offset + part->mtd.size;
|
||||||
|
@ -70,7 +71,7 @@
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,7 +294,25 @@ void mtd_erase_callback(struct erase_inf
|
@@ -245,7 +295,25 @@ void mtd_erase_callback(struct erase_inf
|
||||||
{
|
{
|
||||||
if (instr->mtd->_erase == part_erase) {
|
if (instr->mtd->_erase == part_erase) {
|
||||||
struct mtd_part *part = PART(instr->mtd);
|
struct mtd_part *part = PART(instr->mtd);
|
||||||
|
@ -96,7 +97,7 @@
|
||||||
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
||||||
instr->fail_addr -= part->offset;
|
instr->fail_addr -= part->offset;
|
||||||
instr->addr -= part->offset;
|
instr->addr -= part->offset;
|
||||||
@@ -503,18 +570,24 @@ static struct mtd_part *allocate_partiti
|
@@ -503,18 +571,24 @@ static struct mtd_part *allocate_partiti
|
||||||
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||||
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
||||||
/* Doesn't start on a boundary of major erase size */
|
/* Doesn't start on a boundary of major erase size */
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
/* Our partition linked list */
|
/* Our partition linked list */
|
||||||
static LIST_HEAD(mtd_partitions);
|
static LIST_HEAD(mtd_partitions);
|
||||||
static DEFINE_MUTEX(mtd_partitions_mutex);
|
static DEFINE_MUTEX(mtd_partitions_mutex);
|
||||||
@@ -231,13 +233,60 @@ static int part_erase(struct mtd_info *m
|
@@ -231,13 +233,61 @@ static int part_erase(struct mtd_info *m
|
||||||
struct mtd_part *part = PART(mtd);
|
struct mtd_part *part = PART(mtd);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
+ part->master->erasesize,
|
+ part->master->erasesize,
|
||||||
+ &readlen, instr->erase_buf);
|
+ &readlen, instr->erase_buf);
|
||||||
+
|
+
|
||||||
|
+ instr->len += instr->erase_buf_ofs;
|
||||||
+ instr->partial_start = true;
|
+ instr->partial_start = true;
|
||||||
+ } else {
|
+ } else {
|
||||||
+ mtd_ofs = part->offset + part->mtd.size;
|
+ mtd_ofs = part->offset + part->mtd.size;
|
||||||
|
@ -70,7 +71,7 @@
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,7 +294,25 @@ void mtd_erase_callback(struct erase_inf
|
@@ -245,7 +295,25 @@ void mtd_erase_callback(struct erase_inf
|
||||||
{
|
{
|
||||||
if (instr->mtd->_erase == part_erase) {
|
if (instr->mtd->_erase == part_erase) {
|
||||||
struct mtd_part *part = PART(instr->mtd);
|
struct mtd_part *part = PART(instr->mtd);
|
||||||
|
@ -96,7 +97,7 @@
|
||||||
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
||||||
instr->fail_addr -= part->offset;
|
instr->fail_addr -= part->offset;
|
||||||
instr->addr -= part->offset;
|
instr->addr -= part->offset;
|
||||||
@@ -503,18 +570,24 @@ static struct mtd_part *allocate_partiti
|
@@ -503,18 +571,24 @@ static struct mtd_part *allocate_partiti
|
||||||
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||||
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
||||||
/* Doesn't start on a boundary of major erase size */
|
/* Doesn't start on a boundary of major erase size */
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
/* Our partition linked list */
|
/* Our partition linked list */
|
||||||
static LIST_HEAD(mtd_partitions);
|
static LIST_HEAD(mtd_partitions);
|
||||||
static DEFINE_MUTEX(mtd_partitions_mutex);
|
static DEFINE_MUTEX(mtd_partitions_mutex);
|
||||||
@@ -252,13 +254,60 @@ static int part_erase(struct mtd_info *m
|
@@ -252,13 +254,61 @@ static int part_erase(struct mtd_info *m
|
||||||
return -EROFS;
|
return -EROFS;
|
||||||
if (instr->addr >= mtd->size)
|
if (instr->addr >= mtd->size)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
+ part->master->erasesize,
|
+ part->master->erasesize,
|
||||||
+ &readlen, instr->erase_buf);
|
+ &readlen, instr->erase_buf);
|
||||||
+
|
+
|
||||||
|
+ instr->len += instr->erase_buf_ofs;
|
||||||
+ instr->partial_start = true;
|
+ instr->partial_start = true;
|
||||||
+ } else {
|
+ } else {
|
||||||
+ mtd_ofs = part->offset + part->mtd.size;
|
+ mtd_ofs = part->offset + part->mtd.size;
|
||||||
|
@ -70,7 +71,7 @@
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +315,25 @@ void mtd_erase_callback(struct erase_inf
|
@@ -266,7 +316,25 @@ void mtd_erase_callback(struct erase_inf
|
||||||
{
|
{
|
||||||
if (instr->mtd->erase == part_erase) {
|
if (instr->mtd->erase == part_erase) {
|
||||||
struct mtd_part *part = PART(instr->mtd);
|
struct mtd_part *part = PART(instr->mtd);
|
||||||
|
@ -96,7 +97,7 @@
|
||||||
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
||||||
instr->fail_addr -= part->offset;
|
instr->fail_addr -= part->offset;
|
||||||
instr->addr -= part->offset;
|
instr->addr -= part->offset;
|
||||||
@@ -537,18 +604,24 @@ static struct mtd_part *allocate_partiti
|
@@ -537,18 +605,24 @@ static struct mtd_part *allocate_partiti
|
||||||
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||||
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
||||||
/* Doesn't start on a boundary of major erase size */
|
/* Doesn't start on a boundary of major erase size */
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
/* Our partition linked list */
|
/* Our partition linked list */
|
||||||
static LIST_HEAD(mtd_partitions);
|
static LIST_HEAD(mtd_partitions);
|
||||||
static DEFINE_MUTEX(mtd_partitions_mutex);
|
static DEFINE_MUTEX(mtd_partitions_mutex);
|
||||||
@@ -230,13 +232,60 @@ static int part_erase(struct mtd_info *m
|
@@ -230,13 +232,61 @@ static int part_erase(struct mtd_info *m
|
||||||
struct mtd_part *part = PART(mtd);
|
struct mtd_part *part = PART(mtd);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
+ part->master->erasesize,
|
+ part->master->erasesize,
|
||||||
+ &readlen, instr->erase_buf);
|
+ &readlen, instr->erase_buf);
|
||||||
+
|
+
|
||||||
|
+ instr->len += instr->erase_buf_ofs;
|
||||||
+ instr->partial_start = true;
|
+ instr->partial_start = true;
|
||||||
+ } else {
|
+ } else {
|
||||||
+ mtd_ofs = part->offset + part->mtd.size;
|
+ mtd_ofs = part->offset + part->mtd.size;
|
||||||
|
@ -70,7 +71,7 @@
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,7 +293,25 @@ void mtd_erase_callback(struct erase_inf
|
@@ -244,7 +294,25 @@ void mtd_erase_callback(struct erase_inf
|
||||||
{
|
{
|
||||||
if (instr->mtd->_erase == part_erase) {
|
if (instr->mtd->_erase == part_erase) {
|
||||||
struct mtd_part *part = PART(instr->mtd);
|
struct mtd_part *part = PART(instr->mtd);
|
||||||
|
@ -96,7 +97,7 @@
|
||||||
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
||||||
instr->fail_addr -= part->offset;
|
instr->fail_addr -= part->offset;
|
||||||
instr->addr -= part->offset;
|
instr->addr -= part->offset;
|
||||||
@@ -504,18 +571,24 @@ static struct mtd_part *allocate_partiti
|
@@ -504,18 +572,24 @@ static struct mtd_part *allocate_partiti
|
||||||
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||||
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
||||||
/* Doesn't start on a boundary of major erase size */
|
/* Doesn't start on a boundary of major erase size */
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
/* Our partition linked list */
|
/* Our partition linked list */
|
||||||
static LIST_HEAD(mtd_partitions);
|
static LIST_HEAD(mtd_partitions);
|
||||||
static DEFINE_MUTEX(mtd_partitions_mutex);
|
static DEFINE_MUTEX(mtd_partitions_mutex);
|
||||||
@@ -230,13 +232,60 @@ static int part_erase(struct mtd_info *m
|
@@ -230,13 +232,61 @@ static int part_erase(struct mtd_info *m
|
||||||
struct mtd_part *part = PART(mtd);
|
struct mtd_part *part = PART(mtd);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
+ part->master->erasesize,
|
+ part->master->erasesize,
|
||||||
+ &readlen, instr->erase_buf);
|
+ &readlen, instr->erase_buf);
|
||||||
+
|
+
|
||||||
|
+ instr->len += instr->erase_buf_ofs;
|
||||||
+ instr->partial_start = true;
|
+ instr->partial_start = true;
|
||||||
+ } else {
|
+ } else {
|
||||||
+ mtd_ofs = part->offset + part->mtd.size;
|
+ mtd_ofs = part->offset + part->mtd.size;
|
||||||
|
@ -70,7 +71,7 @@
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,7 +293,25 @@ void mtd_erase_callback(struct erase_inf
|
@@ -244,7 +294,25 @@ void mtd_erase_callback(struct erase_inf
|
||||||
{
|
{
|
||||||
if (instr->mtd->_erase == part_erase) {
|
if (instr->mtd->_erase == part_erase) {
|
||||||
struct mtd_part *part = PART(instr->mtd);
|
struct mtd_part *part = PART(instr->mtd);
|
||||||
|
@ -96,7 +97,7 @@
|
||||||
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
||||||
instr->fail_addr -= part->offset;
|
instr->fail_addr -= part->offset;
|
||||||
instr->addr -= part->offset;
|
instr->addr -= part->offset;
|
||||||
@@ -504,18 +571,24 @@ static struct mtd_part *allocate_partiti
|
@@ -504,18 +572,24 @@ static struct mtd_part *allocate_partiti
|
||||||
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||||
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
||||||
/* Doesn't start on a boundary of major erase size */
|
/* Doesn't start on a boundary of major erase size */
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
/* Our partition linked list */
|
/* Our partition linked list */
|
||||||
static LIST_HEAD(mtd_partitions);
|
static LIST_HEAD(mtd_partitions);
|
||||||
static DEFINE_MUTEX(mtd_partitions_mutex);
|
static DEFINE_MUTEX(mtd_partitions_mutex);
|
||||||
@@ -230,13 +232,60 @@ static int part_erase(struct mtd_info *m
|
@@ -230,13 +232,61 @@ static int part_erase(struct mtd_info *m
|
||||||
struct mtd_part *part = PART(mtd);
|
struct mtd_part *part = PART(mtd);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
+ part->master->erasesize,
|
+ part->master->erasesize,
|
||||||
+ &readlen, instr->erase_buf);
|
+ &readlen, instr->erase_buf);
|
||||||
+
|
+
|
||||||
|
+ instr->len += instr->erase_buf_ofs;
|
||||||
+ instr->partial_start = true;
|
+ instr->partial_start = true;
|
||||||
+ } else {
|
+ } else {
|
||||||
+ mtd_ofs = part->offset + part->mtd.size;
|
+ mtd_ofs = part->offset + part->mtd.size;
|
||||||
|
@ -70,7 +71,7 @@
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,7 +293,25 @@ void mtd_erase_callback(struct erase_inf
|
@@ -244,7 +294,25 @@ void mtd_erase_callback(struct erase_inf
|
||||||
{
|
{
|
||||||
if (instr->mtd->_erase == part_erase) {
|
if (instr->mtd->_erase == part_erase) {
|
||||||
struct mtd_part *part = PART(instr->mtd);
|
struct mtd_part *part = PART(instr->mtd);
|
||||||
|
@ -96,7 +97,7 @@
|
||||||
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
||||||
instr->fail_addr -= part->offset;
|
instr->fail_addr -= part->offset;
|
||||||
instr->addr -= part->offset;
|
instr->addr -= part->offset;
|
||||||
@@ -504,18 +571,24 @@ static struct mtd_part *allocate_partiti
|
@@ -504,18 +572,24 @@ static struct mtd_part *allocate_partiti
|
||||||
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||||
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
||||||
/* Doesn't start on a boundary of major erase size */
|
/* Doesn't start on a boundary of major erase size */
|
||||||
|
|
Loading…
Reference in a new issue