mtd/drivers/mtd rfd_ftl.c,1.1,1.2
sean at infradead.org
sean at infradead.org
Thu Jun 23 10:50:15 EDT 2005
Update of /home/cvs/mtd/drivers/mtd
In directory phoenix.infradead.org:/tmp/cvs-serv5598/drivers/mtd
Modified Files:
rfd_ftl.c
Log Message:
Proper cylinder/sectors and ignore writes of blank sectors
Signed-off-by: Sean Young <sean at mess.org>
Index: rfd_ftl.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/rfd_ftl.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- rfd_ftl.c 16 Jun 2005 08:49:29 -0000 1.1
+++ rfd_ftl.c 23 Jun 2005 14:50:11 -0000 1.2
@@ -8,7 +8,7 @@
* 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:
*
- * http://www.gensw.com/pages/prod/bios/rfd.htm
+ * http://www.gensw.com/pages/prod/bios/rfd.htm
*
* based on ftl.c
*/
@@ -31,7 +31,7 @@
/* A request for this major has been sent to device at lanana.org */
#ifndef RFD_FTL_MAJOR
-#define RFD_FTL_MAJOR 95
+#define RFD_FTL_MAJOR 95
#endif
/* Maximum number of partitions in an FTL region */
@@ -127,9 +127,8 @@
if (part->sector_map[entry] != -1) {
printk(KERN_NOTICE PREFIX
- "'%s': unit #%d: entry %d corrupt, "
- "sector %d linked twice\n",
- part->mbd.mtd->name, block_no, i, entry);
+ "'%s': more than one entry for sector %d\n",
+ part->mbd.mtd->name, entry);
continue;
}
@@ -155,6 +154,9 @@
sectors_per_block = part->block_size / SECTOR_SIZE;
part->total_blocks = part->mbd.mtd->size / part->block_size;
+ if (part->total_blocks < 2)
+ return -ENOENT;
+
/* each erase block has three bytes header, followed by the map */
part->header_sectors_per_block =
((HEADER_MAP_OFFSET + sectors_per_block) *
@@ -181,7 +183,7 @@
part->sector_map = vmalloc(part->sector_count * sizeof(u_long));
if (!part->sector_map) {
- printk (KERN_ERR PREFIX "'%s': unable to allocate memory for "
+ printk(KERN_ERR PREFIX "'%s': unable to allocate memory for "
"sector map", part->mbd.mtd->name);
goto err;
}
@@ -205,7 +207,7 @@
}
if (blocks_found == 0) {
- printk(KERN_NOTICE PREFIX "no FTL header found for '%s'.\n",
+ printk(KERN_NOTICE PREFIX "no RFD magic found in '%s'.\n",
part->mbd.mtd->name);
rc = -ENOENT;
goto err;
@@ -238,7 +240,7 @@
if (!rc && retlen != SECTOR_SIZE)
rc = -EIO;
- if (rc) {
+ if (rc) {
printk(KERN_WARNING PREFIX "error reading '%s' at "
"0x%lx\n", part->mbd.mtd->name, addr);
return rc;
@@ -591,29 +593,19 @@
return rc;
}
-static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf)
+static int do_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf, ulong *old_addr)
{
struct partition *part= (struct partition*)dev;
- u_long old_addr, addr;
+ u_long addr;
int i;
int rc;
size_t retlen;
u16 entry;
- pr_debug("rfd_ftl_writesect(sector=0x%lx)\n", sector);
-
- if (part->reserved_block == -1)
- return -EACCES;
-
- if (sector >= part->sector_count)
- return -EIO;
-
- old_addr = part->sector_map[sector];
-
if (part->current_block == -1 ||
!part->blocks[part->current_block].free_sectors) {
- rc = find_writeable_block(part, &old_addr);
+ rc = find_writeable_block(part, old_addr);
if (rc)
goto err;
}
@@ -663,6 +655,44 @@
part->blocks[part->current_block].used_sectors++;
part->blocks[part->current_block].free_sectors--;
+err:
+ return rc;
+}
+
+static int rfd_ftl_writesect(struct mtd_blktrans_dev *dev, u_long sector, char *buf)
+{
+ struct partition *part= (struct partition*)dev;
+ u_long old_addr;
+ int i;
+ int rc = 0;
+
+ pr_debug("rfd_ftl_writesect(sector=0x%lx)\n", sector);
+
+ if (part->reserved_block == -1) {
+ rc = -EACCES;
+ goto err;
+ }
+
+ if (sector >= part->sector_count) {
+ rc = -EIO;
+ goto err;
+ }
+
+ old_addr = part->sector_map[sector];
+
+ for (i=0; i<SECTOR_SIZE; i++) {
+ if (buf[i])
+ break;
+ }
+
+ if (i < SECTOR_SIZE) {
+ rc = do_writesect(dev, sector, buf, &old_addr);
+ if (rc)
+ goto err;
+ }
+ else
+ part->sector_map[sector] = -1;
+
if (old_addr != -1)
rc = mark_sector_removed(part, old_addr);
@@ -685,6 +715,9 @@
{
struct partition *part;
+ if(mtd->type != MTD_NORFLASH)
+ return;
+
part = kcalloc(1, sizeof(struct partition), GFP_KERNEL);
if (!part)
return;
More information about the linux-mtd-cvs
mailing list