Commit 683b30c8 authored by Sean Young's avatar Sean Young Committed by David Woodhouse

[MTD] RFD FTL: Be noisier, and don't assume block without RFD magic are erased

Signed-off-by: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent ae282d49
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (C) 2005 Sean Young <sean@mess.org> * Copyright (C) 2005 Sean Young <sean@mess.org>
* *
* $Id: rfd_ftl.c,v 1.5 2005/11/07 11:14:21 gleixner Exp $ * $Id: rfd_ftl.c,v 1.8 2006/01/15 12:51:44 sean Exp $
* *
* This type of flash translation layer (FTL) is used by the Embedded BIOS * This type of flash translation layer (FTL) is used by the Embedded BIOS
* by General Software. It is known as the Resident Flash Disk (RFD), see: * by General Software. It is known as the Resident Flash Disk (RFD), see:
...@@ -61,6 +61,7 @@ struct block { ...@@ -61,6 +61,7 @@ struct block {
BLOCK_OK, BLOCK_OK,
BLOCK_ERASING, BLOCK_ERASING,
BLOCK_ERASED, BLOCK_ERASED,
BLOCK_UNUSED,
BLOCK_FAILED BLOCK_FAILED
} state; } state;
int free_sectors; int free_sectors;
...@@ -99,10 +100,8 @@ static int build_block_map(struct partition *part, int block_no) ...@@ -99,10 +100,8 @@ static int build_block_map(struct partition *part, int block_no)
block->offset = part->block_size * block_no; block->offset = part->block_size * block_no;
if (le16_to_cpu(part->header_cache[0]) != RFD_MAGIC) { if (le16_to_cpu(part->header_cache[0]) != RFD_MAGIC) {
block->state = BLOCK_ERASED; /* assumption */ block->state = BLOCK_UNUSED;
block->free_sectors = part->data_sectors_per_block; return -ENOENT;
part->reserved_block = block_no;
return 1;
} }
block->state = BLOCK_OK; block->state = BLOCK_OK;
...@@ -124,7 +123,7 @@ static int build_block_map(struct partition *part, int block_no) ...@@ -124,7 +123,7 @@ static int build_block_map(struct partition *part, int block_no)
entry = 0; entry = 0;
if (entry >= part->sector_count) { if (entry >= part->sector_count) {
printk(KERN_NOTICE PREFIX printk(KERN_WARNING PREFIX
"'%s': unit #%d: entry %d corrupt, " "'%s': unit #%d: entry %d corrupt, "
"sector %d out of range\n", "sector %d out of range\n",
part->mbd.mtd->name, block_no, i, entry); part->mbd.mtd->name, block_no, i, entry);
...@@ -132,7 +131,7 @@ static int build_block_map(struct partition *part, int block_no) ...@@ -132,7 +131,7 @@ static int build_block_map(struct partition *part, int block_no)
} }
if (part->sector_map[entry] != -1) { if (part->sector_map[entry] != -1) {
printk(KERN_NOTICE PREFIX printk(KERN_WARNING PREFIX
"'%s': more than one entry for sector %d\n", "'%s': more than one entry for sector %d\n",
part->mbd.mtd->name, entry); part->mbd.mtd->name, entry);
part->errors = 1; part->errors = 1;
...@@ -226,7 +225,7 @@ static int scan_header(struct partition *part) ...@@ -226,7 +225,7 @@ static int scan_header(struct partition *part)
} }
if (part->reserved_block == -1) { if (part->reserved_block == -1) {
printk(KERN_NOTICE PREFIX "'%s': no empty erase unit found\n", printk(KERN_WARNING PREFIX "'%s': no empty erase unit found\n",
part->mbd.mtd->name); part->mbd.mtd->name);
part->errors = 1; part->errors = 1;
...@@ -315,7 +314,7 @@ static void erase_callback(struct erase_info *erase) ...@@ -315,7 +314,7 @@ static void erase_callback(struct erase_info *erase)
rc = -EIO; rc = -EIO;
if (rc) { if (rc) {
printk(KERN_NOTICE PREFIX "'%s': unable to write RFD " printk(KERN_ERR PREFIX "'%s': unable to write RFD "
"header at 0x%lx\n", "header at 0x%lx\n",
part->mbd.mtd->name, part->mbd.mtd->name,
part->blocks[i].offset); part->blocks[i].offset);
...@@ -348,7 +347,7 @@ static int erase_block(struct partition *part, int block) ...@@ -348,7 +347,7 @@ static int erase_block(struct partition *part, int block)
rc = part->mbd.mtd->erase(part->mbd.mtd, erase); rc = part->mbd.mtd->erase(part->mbd.mtd, erase);
if (rc) { if (rc) {
printk(KERN_WARNING PREFIX "erase of region %x,%x on '%s' " printk(KERN_ERR PREFIX "erase of region %x,%x on '%s' "
"failed\n", erase->addr, erase->len, "failed\n", erase->addr, erase->len,
part->mbd.mtd->name); part->mbd.mtd->name);
kfree(erase); kfree(erase);
...@@ -383,7 +382,7 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old ...@@ -383,7 +382,7 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
rc = -EIO; rc = -EIO;
if (rc) { if (rc) {
printk(KERN_NOTICE PREFIX "error reading '%s' at " printk(KERN_ERR PREFIX "error reading '%s' at "
"0x%lx\n", part->mbd.mtd->name, "0x%lx\n", part->mbd.mtd->name,
part->blocks[block_no].offset); part->blocks[block_no].offset);
...@@ -423,7 +422,7 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old ...@@ -423,7 +422,7 @@ static int move_block_contents(struct partition *part, int block_no, u_long *old
rc = -EIO; rc = -EIO;
if (rc) { if (rc) {
printk(KERN_NOTICE PREFIX "'%s': Unable to " printk(KERN_ERR PREFIX "'%s': Unable to "
"read sector for relocation\n", "read sector for relocation\n",
part->mbd.mtd->name); part->mbd.mtd->name);
...@@ -520,7 +519,7 @@ static int reclaim_block(struct partition *part, u_long *old_sector) ...@@ -520,7 +519,7 @@ static int reclaim_block(struct partition *part, u_long *old_sector)
* because if we fill that one up first it'll have the most chance of having * because if we fill that one up first it'll have the most chance of having
* the least live sectors at reclaim. * the least live sectors at reclaim.
*/ */
static int find_free_block(const struct partition *part) static int find_free_block(struct partition *part)
{ {
int block, stop; int block, stop;
...@@ -533,6 +532,9 @@ static int find_free_block(const struct partition *part) ...@@ -533,6 +532,9 @@ static int find_free_block(const struct partition *part)
block != part->reserved_block) block != part->reserved_block)
return block; return block;
if (part->blocks[block].state == BLOCK_UNUSED)
erase_block(part, block);
if (++block >= part->total_blocks) if (++block >= part->total_blocks)
block = 0; block = 0;
...@@ -541,7 +543,7 @@ static int find_free_block(const struct partition *part) ...@@ -541,7 +543,7 @@ static int find_free_block(const struct partition *part)
return -1; return -1;
} }
static int find_writeable_block(struct partition *part, u_long *old_sector) static int find_writable_block(struct partition *part, u_long *old_sector)
{ {
int rc, block; int rc, block;
size_t retlen; size_t retlen;
...@@ -570,7 +572,7 @@ static int find_writeable_block(struct partition *part, u_long *old_sector) ...@@ -570,7 +572,7 @@ static int find_writeable_block(struct partition *part, u_long *old_sector)
rc = -EIO; rc = -EIO;
if (rc) { if (rc) {
printk(KERN_NOTICE PREFIX "'%s': unable to read header at " printk(KERN_ERR PREFIX "'%s': unable to read header at "
"0x%lx\n", part->mbd.mtd->name, "0x%lx\n", part->mbd.mtd->name,
part->blocks[block].offset); part->blocks[block].offset);
goto err; goto err;
...@@ -602,7 +604,7 @@ static int mark_sector_deleted(struct partition *part, u_long old_addr) ...@@ -602,7 +604,7 @@ static int mark_sector_deleted(struct partition *part, u_long old_addr)
rc = -EIO; rc = -EIO;
if (rc) { if (rc) {
printk(KERN_WARNING PREFIX "error writing '%s' at " printk(KERN_ERR PREFIX "error writing '%s' at "
"0x%lx\n", part->mbd.mtd->name, addr); "0x%lx\n", part->mbd.mtd->name, addr);
if (rc) if (rc)
goto err; goto err;
...@@ -652,7 +654,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf, ...@@ -652,7 +654,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
if (part->current_block == -1 || if (part->current_block == -1 ||
!part->blocks[part->current_block].free_sectors) { !part->blocks[part->current_block].free_sectors) {
rc = find_writeable_block(part, old_addr); rc = find_writable_block(part, old_addr);
if (rc) if (rc)
goto err; goto err;
} }
...@@ -675,7 +677,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf, ...@@ -675,7 +677,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
rc = -EIO; rc = -EIO;
if (rc) { if (rc) {
printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n", printk(KERN_ERR PREFIX "error writing '%s' at 0x%lx\n",
part->mbd.mtd->name, addr); part->mbd.mtd->name, addr);
if (rc) if (rc)
goto err; goto err;
...@@ -695,7 +697,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf, ...@@ -695,7 +697,7 @@ static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf,
rc = -EIO; rc = -EIO;
if (rc) { if (rc) {
printk(KERN_WARNING PREFIX "error writing '%s' at 0x%lx\n", printk(KERN_ERR PREFIX "error writing '%s' at 0x%lx\n",
part->mbd.mtd->name, addr); part->mbd.mtd->name, addr);
if (rc) if (rc)
goto err; goto err;
...@@ -776,7 +778,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) ...@@ -776,7 +778,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
part->block_size = block_size; part->block_size = block_size;
else { else {
if (!mtd->erasesize) { if (!mtd->erasesize) {
printk(KERN_NOTICE PREFIX "please provide block_size"); printk(KERN_WARNING PREFIX "please provide block_size");
return; return;
} }
else else
...@@ -791,8 +793,8 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) ...@@ -791,8 +793,8 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
if (!(mtd->flags & MTD_WRITEABLE)) if (!(mtd->flags & MTD_WRITEABLE))
part->mbd.readonly = 1; part->mbd.readonly = 1;
else if (part->errors) { else if (part->errors) {
printk(KERN_NOTICE PREFIX "'%s': errors found, " printk(KERN_WARNING PREFIX "'%s': errors found, "
"setting read-only", mtd->name); "setting read-only\n", mtd->name);
part->mbd.readonly = 1; part->mbd.readonly = 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment