aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/mtdoops.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 20eaf294f620..723ca76d6b55 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -103,7 +103,7 @@ static int mtdoops_inc_counter(struct mtdoops_context *cxt)
103 103
104 ret = mtd->read(mtd, cxt->nextpage * OOPS_PAGE_SIZE, 4, 104 ret = mtd->read(mtd, cxt->nextpage * OOPS_PAGE_SIZE, 4,
105 &retlen, (u_char *) &count); 105 &retlen, (u_char *) &count);
106 if ((retlen != 4) || (ret < 0)) { 106 if ((retlen != 4) || ((ret < 0) && (ret != -EUCLEAN))) {
107 printk(KERN_ERR "mtdoops: Read failure at %d (%td of 4 read)" 107 printk(KERN_ERR "mtdoops: Read failure at %d (%td of 4 read)"
108 ", err %d.\n", cxt->nextpage * OOPS_PAGE_SIZE, 108 ", err %d.\n", cxt->nextpage * OOPS_PAGE_SIZE,
109 retlen, ret); 109 retlen, ret);
@@ -136,8 +136,14 @@ static void mtdoops_prepare(struct mtdoops_context *cxt)
136 cxt->nextpage = 0; 136 cxt->nextpage = 0;
137 } 137 }
138 138
139 while (mtd->block_isbad && 139 while (mtd->block_isbad) {
140 mtd->block_isbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE)) { 140 ret = mtd->block_isbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE);
141 if (!ret)
142 break;
143 if (ret < 0) {
144 printk(KERN_ERR "mtdoops: block_isbad failed, aborting.\n");
145 return;
146 }
141badblock: 147badblock:
142 printk(KERN_WARNING "mtdoops: Bad block at %08x\n", 148 printk(KERN_WARNING "mtdoops: Bad block at %08x\n",
143 cxt->nextpage * OOPS_PAGE_SIZE); 149 cxt->nextpage * OOPS_PAGE_SIZE);
@@ -154,15 +160,20 @@ badblock:
154 for (j = 0, ret = -1; (j < 3) && (ret < 0); j++) 160 for (j = 0, ret = -1; (j < 3) && (ret < 0); j++)
155 ret = mtdoops_erase_block(mtd, cxt->nextpage * OOPS_PAGE_SIZE); 161 ret = mtdoops_erase_block(mtd, cxt->nextpage * OOPS_PAGE_SIZE);
156 162
157 if (ret < 0) { 163 if (ret >= 0) {
158 if (mtd->block_markbad) 164 printk(KERN_DEBUG "mtdoops: Ready %d, %d \n", cxt->nextpage, cxt->nextcount);
159 mtd->block_markbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE); 165 cxt->ready = 1;
160 goto badblock; 166 return;
161 } 167 }
162 168
163 printk(KERN_DEBUG "mtdoops: Ready %d, %d \n", cxt->nextpage, cxt->nextcount); 169 if (mtd->block_markbad && (ret == -EIO)) {
164 170 ret = mtd->block_markbad(mtd, cxt->nextpage * OOPS_PAGE_SIZE);
165 cxt->ready = 1; 171 if (ret < 0) {
172 printk(KERN_ERR "mtdoops: block_markbad failed, aborting.\n");
173 return;
174 }
175 }
176 goto badblock;
166} 177}
167 178
168static void mtdoops_workfunc(struct work_struct *work) 179static void mtdoops_workfunc(struct work_struct *work)
@@ -176,12 +187,18 @@ static void mtdoops_workfunc(struct work_struct *work)
176static int find_next_position(struct mtdoops_context *cxt) 187static int find_next_position(struct mtdoops_context *cxt)
177{ 188{
178 struct mtd_info *mtd = cxt->mtd; 189 struct mtd_info *mtd = cxt->mtd;
179 int page, maxpos = 0; 190 int ret, page, maxpos = 0;
180 u32 count, maxcount = 0xffffffff; 191 u32 count, maxcount = 0xffffffff;
181 size_t retlen; 192 size_t retlen;
182 193
183 for (page = 0; page < cxt->oops_pages; page++) { 194 for (page = 0; page < cxt->oops_pages; page++) {
184 mtd->read(mtd, page * OOPS_PAGE_SIZE, 4, &retlen, (u_char *) &count); 195 ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 4, &retlen, (u_char *) &count);
196 if ((retlen != 4) || ((ret < 0) && (ret != -EUCLEAN))) {
197 printk(KERN_ERR "mtdoops: Read failure at %d (%td of 4 read)"
198 ", err %d.\n", page * OOPS_PAGE_SIZE, retlen, ret);
199 continue;
200 }
201
185 if (count == 0xffffffff) 202 if (count == 0xffffffff)
186 continue; 203 continue;
187 if (maxcount == 0xffffffff) { 204 if (maxcount == 0xffffffff) {