|
@@ -266,91 +266,55 @@ static int rfd_ftl_readsect(struct mtd_blktrans_dev *dev, u_long sector, char *b
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static void erase_callback(struct erase_info *erase)
|
|
|
-{
|
|
|
- struct partition *part;
|
|
|
- u16 magic;
|
|
|
- int i, rc;
|
|
|
- size_t retlen;
|
|
|
-
|
|
|
- part = (struct partition*)erase->priv;
|
|
|
-
|
|
|
- i = (u32)erase->addr / part->block_size;
|
|
|
- if (i >= part->total_blocks || part->blocks[i].offset != erase->addr ||
|
|
|
- erase->addr > UINT_MAX) {
|
|
|
- printk(KERN_ERR PREFIX "erase callback for unknown offset %llx "
|
|
|
- "on '%s'\n", (unsigned long long)erase->addr, part->mbd.mtd->name);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (erase->state != MTD_ERASE_DONE) {
|
|
|
- printk(KERN_WARNING PREFIX "erase failed at 0x%llx on '%s', "
|
|
|
- "state %d\n", (unsigned long long)erase->addr,
|
|
|
- part->mbd.mtd->name, erase->state);
|
|
|
-
|
|
|
- part->blocks[i].state = BLOCK_FAILED;
|
|
|
- part->blocks[i].free_sectors = 0;
|
|
|
- part->blocks[i].used_sectors = 0;
|
|
|
-
|
|
|
- kfree(erase);
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- magic = cpu_to_le16(RFD_MAGIC);
|
|
|
-
|
|
|
- part->blocks[i].state = BLOCK_ERASED;
|
|
|
- part->blocks[i].free_sectors = part->data_sectors_per_block;
|
|
|
- part->blocks[i].used_sectors = 0;
|
|
|
- part->blocks[i].erases++;
|
|
|
-
|
|
|
- rc = mtd_write(part->mbd.mtd, part->blocks[i].offset, sizeof(magic),
|
|
|
- &retlen, (u_char *)&magic);
|
|
|
-
|
|
|
- if (!rc && retlen != sizeof(magic))
|
|
|
- rc = -EIO;
|
|
|
-
|
|
|
- if (rc) {
|
|
|
- printk(KERN_ERR PREFIX "'%s': unable to write RFD "
|
|
|
- "header at 0x%lx\n",
|
|
|
- part->mbd.mtd->name,
|
|
|
- part->blocks[i].offset);
|
|
|
- part->blocks[i].state = BLOCK_FAILED;
|
|
|
- }
|
|
|
- else
|
|
|
- part->blocks[i].state = BLOCK_OK;
|
|
|
-
|
|
|
- kfree(erase);
|
|
|
-}
|
|
|
-
|
|
|
static int erase_block(struct partition *part, int block)
|
|
|
{
|
|
|
struct erase_info *erase;
|
|
|
- int rc = -ENOMEM;
|
|
|
+ int rc;
|
|
|
|
|
|
erase = kmalloc(sizeof(struct erase_info), GFP_KERNEL);
|
|
|
if (!erase)
|
|
|
- goto err;
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
erase->mtd = part->mbd.mtd;
|
|
|
- erase->callback = erase_callback;
|
|
|
erase->addr = part->blocks[block].offset;
|
|
|
erase->len = part->block_size;
|
|
|
- erase->priv = (u_long)part;
|
|
|
|
|
|
part->blocks[block].state = BLOCK_ERASING;
|
|
|
part->blocks[block].free_sectors = 0;
|
|
|
|
|
|
rc = mtd_erase(part->mbd.mtd, erase);
|
|
|
-
|
|
|
if (rc) {
|
|
|
printk(KERN_ERR PREFIX "erase of region %llx,%llx on '%s' "
|
|
|
"failed\n", (unsigned long long)erase->addr,
|
|
|
(unsigned long long)erase->len, part->mbd.mtd->name);
|
|
|
- kfree(erase);
|
|
|
+ part->blocks[block].state = BLOCK_FAILED;
|
|
|
+ part->blocks[block].free_sectors = 0;
|
|
|
+ part->blocks[block].used_sectors = 0;
|
|
|
+ } else {
|
|
|
+ u16 magic = cpu_to_le16(RFD_MAGIC);
|
|
|
+ size_t retlen;
|
|
|
+
|
|
|
+ part->blocks[block].state = BLOCK_ERASED;
|
|
|
+ part->blocks[block].free_sectors = part->data_sectors_per_block;
|
|
|
+ part->blocks[block].used_sectors = 0;
|
|
|
+ part->blocks[block].erases++;
|
|
|
+
|
|
|
+ rc = mtd_write(part->mbd.mtd, part->blocks[block].offset,
|
|
|
+ sizeof(magic), &retlen, (u_char *)&magic);
|
|
|
+ if (!rc && retlen != sizeof(magic))
|
|
|
+ rc = -EIO;
|
|
|
+
|
|
|
+ if (rc) {
|
|
|
+ pr_err(PREFIX "'%s': unable to write RFD header at 0x%lx\n",
|
|
|
+ part->mbd.mtd->name, part->blocks[block].offset);
|
|
|
+ part->blocks[block].state = BLOCK_FAILED;
|
|
|
+ } else {
|
|
|
+ part->blocks[block].state = BLOCK_OK;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-err:
|
|
|
+ kfree(erase);
|
|
|
+
|
|
|
return rc;
|
|
|
}
|
|
|
|