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