mtd/drivers/mtd nftlmount.c,1.32,1.33 nftlcore.c,1.88,1.89

David Woodhouse dwmw2 at infradead.org
Sun May 18 18:29:51 EDT 2003


Update of /home/cvs/mtd/drivers/mtd
In directory phoenix.infradead.org:/tmp/cvs-serv15157

Modified Files:
	nftlmount.c nftlcore.c 
Log Message:
Convert NFTL to blktrans (untested)


Index: nftlmount.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nftlmount.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- nftlmount.c	9 May 2003 22:34:12 -0000	1.32
+++ nftlmount.c	18 May 2003 22:29:47 -0000	1.33
@@ -59,8 +59,8 @@
 
         /* Assume logical EraseSize == physical erasesize for starting the scan. 
 	   We'll sort it out later if we find a MediaHeader which says otherwise */
-	nftl->EraseSize = nftl->mtd->erasesize;
-        nftl->nb_blocks = nftl->mtd->size / nftl->EraseSize;
+	nftl->EraseSize = nftl->mbd.mtd->erasesize;
+        nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize;
 
 	nftl->MediaUnit = BLOCK_NIL;
 	nftl->SpareMediaUnit = BLOCK_NIL;
@@ -71,12 +71,12 @@
 
 		/* Check for ANAND header first. Then can whinge if it's found but later
 		   checks fail */
-		if ((ret = MTD_READ(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf))) {
+		if ((ret = MTD_READ(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf))) {
 			static int warncount = 5;
 
 			if (warncount) {
 				printk(KERN_WARNING "Block read at 0x%x of mtd%d failed: %d\n",
-				       block * nftl->EraseSize, nftl->mtd->index, ret);
+				       block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
 				if (!--warncount)
 					printk(KERN_WARNING "Further failures for this block will not be printed\n");
 			}
@@ -87,16 +87,16 @@
 			/* ANAND\0 not found. Continue */
 #if 0
 			printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n", 
-			       block * nftl->EraseSize, nftl->mtd->index);
+			       block * nftl->EraseSize, nftl->mbd.mtd->index);
 #endif			
 			continue;
 		}
 
 		/* To be safer with BIOS, also use erase mark as discriminant */
-		if ((ret = MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
+		if ((ret = MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8,
 				8, &retlen, (char *)&h1) < 0)) {
 			printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n",
-			       block * nftl->EraseSize, nftl->mtd->index, ret);
+			       block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
 			continue;
 		}
 
@@ -106,23 +106,23 @@
       */
 		if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) {
 			printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n",
-			       block * nftl->EraseSize, nftl->mtd->index, 
+			       block * nftl->EraseSize, nftl->mbd.mtd->index, 
 			       le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1));
 			continue;
 		}
 
 		/* Finally reread to check ECC */
-		if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize, SECTORSIZE,
+		if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE,
 				&retlen, buf, (char *)&oob, NAND_ECC_DISKONCHIP) < 0)) {
 			printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n",
-			       block * nftl->EraseSize, nftl->mtd->index, ret);
+			       block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
 			continue;
 		}
 
 		/* Paranoia. Check the ANAND header is still there after the ECC read */
 		if (memcmp(buf, "ANAND", 6)) {
 			printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but went away on reread!\n",
-			       block * nftl->EraseSize, nftl->mtd->index);
+			       block * nftl->EraseSize, nftl->mbd.mtd->index);
 			printk(KERN_NOTICE "New data are: %02x %02x %02x %02x %02x %02x\n",
 			       buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
 			continue;
@@ -167,8 +167,8 @@
 		} else if (mh->UnitSizeFactor != 0xff) {
 			printk(KERN_NOTICE "WARNING: Support for NFTL with UnitSizeFactor 0x%02x is experimental\n",
 			       mh->UnitSizeFactor);
-			nftl->EraseSize = nftl->mtd->erasesize << (0xff - mh->UnitSizeFactor);
-			nftl->nb_blocks = nftl->mtd->size / nftl->EraseSize;
+			nftl->EraseSize = nftl->mbd.mtd->erasesize << (0xff - mh->UnitSizeFactor);
+			nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize;
 		}
 		nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
 		if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
@@ -186,7 +186,7 @@
 			return -1;
 		}
 		
-		nftl->nr_sects  = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
+		nftl->mbd.size  = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
 
 		/* If we're not using the last sectors in the device for some reason,
 		   reduce nb_blocks accordingly so we forget they're there */
@@ -224,7 +224,7 @@
 		for (i = 0; i < nftl->nb_blocks; i++) {
 			if ((i & (SECTORSIZE - 1)) == 0) {
 				/* read one sector for every SECTORSIZE of blocks */
-				if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize +
+				if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize +
 						       i + SECTORSIZE, SECTORSIZE, &retlen, buf,
 						       (char *)&oob, NAND_ECC_DISKONCHIP)) < 0) {
 					printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n",
@@ -267,16 +267,16 @@
 	for (i = 0; i < len; i += SECTORSIZE) {
 		/* we want to read the sector without ECC check here since a free
 		   sector does not have ECC syndrome on it yet */
-		if (MTD_READ(nftl->mtd, address, SECTORSIZE, &retlen, buf) < 0)
+		if (MTD_READ(nftl->mbd.mtd, address, SECTORSIZE, &retlen, buf) < 0)
 			return -1;
 		if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
 			return -1;
 
 		if (check_oob) {
-			if (MTD_READOOB(nftl->mtd, address, nftl->mtd->oobsize,
+			if (MTD_READOOB(nftl->mbd.mtd, address, nftl->mbd.mtd->oobsize,
 					&retlen, buf) < 0)
 				return -1;
-			if (memcmpb(buf, 0xff, nftl->mtd->oobsize) != 0)
+			if (memcmpb(buf, 0xff, nftl->mbd.mtd->oobsize) != 0)
 				return -1;
 		}
 		address += SECTORSIZE;
@@ -301,7 +301,7 @@
 	struct erase_info *instr = &nftl->instr;
 
 	/* Read the Unit Control Information #1 for Wear-Leveling */
-	if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
+	if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8,
 			8, &retlen, (char *)&uci) < 0)
 		goto default_uci1;
 
@@ -318,7 +318,7 @@
 	/* XXX: use async erase interface, XXX: test return code */
 	instr->addr = block * nftl->EraseSize;
 	instr->len = nftl->EraseSize;
-	MTD_ERASE(nftl->mtd, instr);
+	MTD_ERASE(nftl->mbd.mtd, instr);
 
 	if (instr->state == MTD_ERASE_FAILED) {
 		/* could not format, FixMe: We should update the BadUnitTable 
@@ -341,7 +341,7 @@
 			return -1;
 
 		uci.WearInfo = le32_to_cpu(nb_erases);
-		if (MTD_WRITEOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
+		if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
 				 &retlen, (char *)&uci) < 0)
 			return -1;
 		return 0;
@@ -367,7 +367,7 @@
 	block = first_block;
 	for (;;) {
 		for (i = 0; i < sectors_per_block; i++) {
-			if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + i * SECTORSIZE,
+			if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i * SECTORSIZE,
 					8, &retlen, (char *)&bci) < 0)
 				status = SECTOR_IGNORE;
 			else
@@ -387,7 +387,7 @@
 					/* sector not free actually : mark it as SECTOR_IGNORE  */
 					bci.Status = SECTOR_IGNORE;
 					bci.Status1 = SECTOR_IGNORE;
-					MTD_WRITEOOB(nftl->mtd,
+					MTD_WRITEOOB(nftl->mbd.mtd,
 						     block * nftl->EraseSize + i * SECTORSIZE,
 						     8, &retlen, (char *)&bci);
 				}
@@ -480,7 +480,7 @@
 	size_t retlen;
 
 	/* check erase mark. */
-	if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 
+	if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 
 			&retlen, (char *)&h1) < 0)
 		return -1;
 
@@ -495,7 +495,7 @@
 		h1.EraseMark = cpu_to_le16(ERASE_MARK);
 		h1.EraseMark1 = cpu_to_le16(ERASE_MARK);
 		h1.WearInfo = cpu_to_le32(0);
-		if (MTD_WRITEOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 
+		if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8, 
 				 &retlen, (char *)&h1) < 0)
 			return -1;
 	} else {
@@ -507,7 +507,7 @@
 						SECTORSIZE, 0) != 0)
 				return -1;
 
-			if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + i,
+			if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i,
 					16, &retlen, buf) < 0)
 				return -1;
 			if (i == SECTORSIZE) {
@@ -537,7 +537,7 @@
 	struct nftl_uci2 uci;
 	size_t retlen;
 
-	if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8,
+	if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8,
 			8, &retlen, (char *)&uci) < 0)
 		return 0;
 
@@ -576,9 +576,9 @@
 
 			for (;;) {
 				/* read the block header. If error, we format the chain */
-				if (MTD_READOOB(s->mtd, block * s->EraseSize + 8, 8, 
+				if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8, 
 						&retlen, (char *)&h0) < 0 ||
-				    MTD_READOOB(s->mtd, block * s->EraseSize + SECTORSIZE + 8, 8, 
+				    MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8, 
 						&retlen, (char *)&h1) < 0) {
 					s->ReplUnitTable[block] = BLOCK_NIL;
 					do_format_chain = 1;

Index: nftlcore.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/nftlcore.c,v
retrieving revision 1.88
retrieving revision 1.89
diff -u -r1.88 -r1.89
--- nftlcore.c	2 Mar 2003 18:45:07 -0000	1.88
+++ nftlcore.c	18 May 2003 22:29:47 -0000	1.89
@@ -23,15 +23,13 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/init.h>
-#include <linux/blkpg.h>
+#include <linux/hdreg.h>
 
-#ifdef CONFIG_KMOD
 #include <linux/kmod.h>
-#endif
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nftl.h>
-#include <linux/mtd/compatmac.h>
+#include <linux/mtd/blktrans.h>
 
 /* maximum number of loops while examining next block, to have a
    chance to detect consistency problems (they should never happen
@@ -39,87 +37,29 @@
 
 #define MAX_LOOPS 10000
 
-/* NFTL block device stuff */
-#define MAJOR_NR NFTL_MAJOR
-#define DEVICE_REQUEST nftl_request
-#define DEVICE_OFF(device)
-
-
-#include <linux/blk.h>
-#include <linux/hdreg.h>
-
-/* Linux-specific block device functions */
-
-/* I _HATE_ the Linux block device setup more than anything else I've ever
- *  encountered, except ...
- */
-
-static int nftl_sizes[256];
-static int nftl_blocksizes[256];
-
-/* .. for the Linux partition table handling. */
-struct hd_struct part_table[256];
-
-#if LINUX_VERSION_CODE < 0x20328
-static void dummy_init (struct gendisk *crap)
-{}
-#endif
-
-static struct gendisk nftl_gendisk = {
-	major:		MAJOR_NR,
-	major_name:	"nftl",
-	minor_shift:	NFTL_PARTN_BITS,	/* Bits to shift to get real from partition */
-	max_p:		(1<<NFTL_PARTN_BITS)-1,	/* Number of partitions per real */
-#if LINUX_VERSION_CODE < 0x20328
-	max_nr:		MAX_NFTLS,      /* maximum number of real */
-	init:		dummy_init,     /* init function */
-#endif
-	part:		part_table,     /* hd struct */
-	sizes:		nftl_sizes,     /* block sizes */
-};
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
-#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
-#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
-#else
-#define BLK_INC_USE_COUNT do {} while(0)
-#define BLK_DEC_USE_COUNT do {} while(0)
-#endif
-
-struct NFTLrecord *NFTLs[MAX_NFTLS];
 
-static void NFTL_setup(struct mtd_info *mtd)
+static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
 {
-	int i;
 	struct NFTLrecord *nftl;
 	unsigned long temp;
-	int firstfree = -1;
-
-	DEBUG(MTD_DEBUG_LEVEL1,"NFTL_setup\n");
 
-	for (i = 0; i < MAX_NFTLS; i++) {
-		if (!NFTLs[i] && firstfree == -1)
-			firstfree = i;
-		else if (NFTLs[i] && NFTLs[i]->mtd == mtd) {
-			/* This is a Spare Media Header for an NFTL we've already found */
-			DEBUG(MTD_DEBUG_LEVEL1, "MTD already mounted as NFTL\n");
-			return;
-		}
-	}
-        if (firstfree == -1) {
-		printk(KERN_WARNING "No more NFTL slot available\n");
+	if (mtd->ecctype != MTD_ECC_RS_DiskOnChip)
 		return;
-        }
+
+	DEBUG(MTD_DEBUG_LEVEL1, "nftl_add_mtd for %s\n", mtd->name);
 
 	nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL);
+
 	if (!nftl) {
 		printk(KERN_WARNING "Out of memory for NFTL data structures\n");
 		return;
 	}
+	memset(nftl, 0, sizeof(*nftl));
 
-	init_MUTEX(&nftl->mutex);
-
-	nftl->mtd = mtd;
+	nftl->mbd.mtd = mtd;
+	nftl->mbd.devnum = -1;
+	nftl->mbd.blksize = 512;
+	nftl->mbd.tr = tr;
 
         if (NFTL_mount(nftl) < 0) {
 		printk(KERN_WARNING "Could not mount NFTL device\n");
@@ -128,100 +68,65 @@
         }
 
 	/* OK, it's a new one. Set up all the data structures. */
-#ifdef PSYCHO_DEBUG
-	printk("Found new NFTL nftl%c\n", firstfree + 'a');
-#endif
 
-        /* linux stuff */
-	nftl->usecount = 0;
+	/* Calculate geometry */
 	nftl->cylinders = 1024;
 	nftl->heads = 16;
 
 	temp = nftl->cylinders * nftl->heads;
-	nftl->sectors = nftl->nr_sects / temp;
-	if (nftl->nr_sects % temp) {
+	nftl->sectors = nftl->mbd.size / temp;
+	if (nftl->mbd.size % temp) {
 		nftl->sectors++;
 		temp = nftl->cylinders * nftl->sectors;
-		nftl->heads = nftl->nr_sects / temp;
+		nftl->heads = nftl->mbd.size / temp;
 
-		if (nftl->nr_sects % temp) {
+		if (nftl->mbd.size % temp) {
 			nftl->heads++;
 			temp = nftl->heads * nftl->sectors;
-			nftl->cylinders = nftl->nr_sects / temp;
+			nftl->cylinders = nftl->mbd.size / temp;
 		}
 	}
 
-	if (nftl->nr_sects != nftl->heads * nftl->cylinders * nftl->sectors) {
+	if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) {
+		/*
+		  Oh no we don't have 
+		   mbd.size == heads * cylinders * sectors
+		*/
 		printk(KERN_WARNING "Cannot calculate an NFTL geometry to "
-		       "match size of 0x%x.\n", nftl->nr_sects);
+		       "precisely match size of 0x%lx.\n", nftl->mbd.size);
 		printk(KERN_WARNING "Using C:%d H:%d S:%d (== 0x%lx sects)\n", 
 		       nftl->cylinders, nftl->heads , nftl->sectors, 
 		       (long)nftl->cylinders * (long)nftl->heads * (long)nftl->sectors );
+	}
 
-		/* Oh no we don't have nftl->nr_sects = nftl->heads * nftl->cylinders * nftl->sectors; */
+	if (add_mtd_blktrans_dev) {
+		if (nftl->ReplUnitTable)
+			kfree(nftl->ReplUnitTable);
+		if (nftl->EUNtable)
+			kfree(nftl->EUNtable);
+		kfree(nftl);
+		return;
 	}
-	NFTLs[firstfree] = nftl;
-	/* Finally, set up the block device sizes */
-	nftl_sizes[firstfree * 16] = nftl->nr_sects;
-	//nftl_blocksizes[firstfree*16] = 512;
-	part_table[firstfree * 16].nr_sects = nftl->nr_sects;
-
-	nftl_gendisk.nr_real++;
-
-	/* partition check ... */
-#if LINUX_VERSION_CODE < 0x20328
-	resetup_one_dev(&nftl_gendisk, firstfree);
-#else
-	grok_partitions(&nftl_gendisk, firstfree, 1<<NFTL_PARTN_BITS, nftl->nr_sects);
+#ifdef PSYCHO_DEBUG
+	printk("Found new NFTL nftl%c\n", nftl->mbd.devnum + 'a');
 #endif
+	return;
 }
 
-static void NFTL_unsetup(int i)
+static void nftl_remove_dev(struct mtd_blktrans_dev *dev)
 {
-	struct NFTLrecord *nftl = NFTLs[i];
+	struct NFTLrecord *nftl = (void *)dev;
 
-	DEBUG(MTD_DEBUG_LEVEL1, "NFTL_unsetup %d\n", i);
-	
-	NFTLs[i] = NULL;
-	
+	DEBUG(MTD_DEBUG_LEVEL1, "nftl_remove_dev %d\n", dev->devnum);
+
+	del_mtd_blktrans_dev(dev);
 	if (nftl->ReplUnitTable)
 		kfree(nftl->ReplUnitTable);
 	if (nftl->EUNtable)
 		kfree(nftl->EUNtable);
-		      
-	nftl_gendisk.nr_real--;
 	kfree(nftl);
 }
 
-/* Search the MTD device for NFTL partitions */
-static void NFTL_notify_add(struct mtd_info *mtd)
-{
-	DEBUG(MTD_DEBUG_LEVEL1, "NFTL_notify_add for %s\n", mtd->name);
-
-	if (mtd) {
-		if (!mtd->read_oob) {
-			/* If this MTD doesn't have out-of-band data,
-			   then there's no point continuing */
-			DEBUG(MTD_DEBUG_LEVEL1, "No OOB data, quitting\n");
-			return;
-		}
-		DEBUG(MTD_DEBUG_LEVEL3, "mtd->read = %p, size = %d, erasesize = %d\n", 
-		      mtd->read, mtd->size, mtd->erasesize);
-
-                NFTL_setup(mtd);
-	}
-}
-
-static void NFTL_notify_remove(struct mtd_info *mtd)
-{
-	int i;
-
-	for (i = 0; i < MAX_NFTLS; i++) {
-		if (NFTLs[i] && NFTLs[i]->mtd == mtd)
-			NFTL_unsetup(i);
-	}
-}
-
 #ifdef CONFIG_NFTL_RW
 
 /* Actual NFTL access routines */
@@ -303,7 +208,7 @@
 
 		targetEUN = thisEUN;
 		for (block = 0; block < nftl->EraseSize / 512; block ++) {
-			MTD_READOOB(nftl->mtd,
+			MTD_READOOB(nftl->mbd.mtd,
 				    (thisEUN * nftl->EraseSize) + (block * 512),
 				    16 , &retlen, (char *)&oob);
 			if (block == 2) {
@@ -420,7 +325,7 @@
                chain by selecting the longer one */
             oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS);
             oob.u.c.unused = 0xffffffff;
-            MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, 
+            MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8, 
                          8, &retlen, (char *)&oob.u);
         }
 
@@ -444,16 +349,16 @@
                 if (BlockMap[block] == BLOCK_NIL)
                         continue;
                 
-                ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
+                ret = MTD_READECC(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
 				  512, &retlen, movebuf, (char *)&oob, NAND_ECC_DISKONCHIP); 
                 if (ret < 0) {
-                    ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block])
+                    ret = MTD_READECC(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block])
                                       + (block * 512), 512, &retlen,
                                       movebuf, (char *)&oob, NAND_ECC_DISKONCHIP); 
                     if (ret != -EIO) 
                         printk("Error went away on retry.\n");
                 }
-                MTD_WRITEECC(nftl->mtd, (nftl->EraseSize * targetEUN) + (block * 512),
+                MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512),
                              512, &retlen, movebuf, (char *)&oob, NAND_ECC_DISKONCHIP);
 	}
         
@@ -462,7 +367,7 @@
                 = cpu_to_le16(thisVUC);
         oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;
         
-        MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 8, 
+        MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8, 
                      8, &retlen, (char *)&oob.u);
 
 	/* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */
@@ -582,7 +487,7 @@
 
 			lastEUN = writeEUN;
 
-			MTD_READOOB(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs,
+			MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
 				    8, &retlen, (char *)&bci);
 			
 			DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
@@ -670,12 +575,12 @@
 		nftl->ReplUnitTable[writeEUN] = BLOCK_NIL;
 
 		/* ... and on the flash itself */
-		MTD_READOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8,
+		MTD_READOOB(nftl->mbd.mtd, writeEUN * nftl->EraseSize + 8, 8,
 			    &retlen, (char *)&oob.u);
 
 		oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC);
 
-		MTD_WRITEOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8,
+		MTD_WRITEOOB(nftl->mbd.mtd, writeEUN * nftl->EraseSize + 8, 8,
                              &retlen, (char *)&oob.u);
 
                 /* we link the new block to the chain only after the
@@ -685,13 +590,13 @@
 			/* Both in our cache... */
 			nftl->ReplUnitTable[lastEUN] = writeEUN;
 			/* ... and on the flash itself */
-			MTD_READOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8,
+			MTD_READOOB(nftl->mbd.mtd, (lastEUN * nftl->EraseSize) + 8,
 				    8, &retlen, (char *)&oob.u);
 
 			oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum
 				= cpu_to_le16(writeEUN);
 
-			MTD_WRITEOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8,
+			MTD_WRITEOOB(nftl->mbd.mtd, (lastEUN * nftl->EraseSize) + 8,
 				     8, &retlen, (char *)&oob.u);
 		}
 
@@ -704,8 +609,10 @@
 	return 0xffff;
 }
 
-static int NFTL_writeblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
+static int nftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
+			   char *buffer)
 {
+	struct NFTLrecord *nftl = (void *)mbd;
 	u16 writeEUN;
 	unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
 	size_t retlen;
@@ -720,7 +627,7 @@
 		return 1;
 	}
 
-	MTD_WRITEECC(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs,
+	MTD_WRITEECC(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
 		     512, &retlen, (char *)buffer, (char *)eccbuf, NAND_ECC_DISKONCHIP);
         /* no need to write SECTOR_USED flags since they are written in mtd_writeecc */
 
@@ -728,8 +635,10 @@
 }
 #endif /* CONFIG_NFTL_RW */
 
-static int NFTL_readblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
+static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
+			  char *buffer)
 {
+	struct NFTLrecord *nftl = (void *)mbd;
 	u16 lastgoodEUN;
 	u16 thisEUN = nftl->EUNtable[block / (nftl->EraseSize / 512)];
 	unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
@@ -742,7 +651,7 @@
 
         if (thisEUN != BLOCK_NIL) {
 		while (thisEUN < nftl->nb_blocks) {
-			if (MTD_READOOB(nftl->mtd, (thisEUN * nftl->EraseSize) + blockofs,
+			if (MTD_READOOB(nftl->mbd.mtd, (thisEUN * nftl->EraseSize) + blockofs,
 					8, &retlen, (char *)&bci) < 0)
 				status = SECTOR_IGNORE;
 			else
@@ -761,13 +670,13 @@
 			case SECTOR_IGNORE:
 				break;
 			default:
-				printk("Unknown status for block %d in EUN %d: %x\n",
+				printk("Unknown status for block %ld in EUN %d: %x\n",
 				       block, thisEUN, status);
 				break;
 			}
 
 			if (!silly--) {
-				printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n",
+				printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%lx\n",
 				       block / (nftl->EraseSize / 512));
 				return 1;
 			}
@@ -783,20 +692,17 @@
 		loff_t ptr = (lastgoodEUN * nftl->EraseSize) + blockofs;
 		size_t retlen;
 		u_char eccbuf[6];
-		if (MTD_READECC(nftl->mtd, ptr, 512, &retlen, buffer, eccbuf, NAND_ECC_DISKONCHIP))
+		if (MTD_READECC(nftl->mbd.mtd, ptr, 512, &retlen, buffer, eccbuf, NAND_ECC_DISKONCHIP))
 			return -EIO;
 	}
 	return 0;
 }
 
-static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
+static int nftl_ioctl(struct mtd_blktrans_dev *dev,
+		     struct inode * inode, struct file * file, 
+		     unsigned int cmd, unsigned long arg)
 {
-	struct NFTLrecord *nftl;
-	int p;
-
-	nftl = NFTLs[MINOR(inode->i_rdev) >> NFTL_PARTN_BITS];
-
-	if (!nftl) return -EINVAL;
+	struct NFTLrecord *nftl = (void *)dev;
 
 	switch (cmd) {
 	case HDIO_GETGEO: {
@@ -805,242 +711,18 @@
 		g.heads = nftl->heads;
 		g.sectors = nftl->sectors;
 		g.cylinders = nftl->cylinders;
-		g.start = part_table[MINOR(inode->i_rdev)].start_sect;
+		g.start = 0;
 		return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
 	}
-	case BLKGETSIZE:   /* Return device size */
-		return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,
-                                (unsigned long *) arg);
-
-#ifdef BLKGETSIZE64
-	case BLKGETSIZE64:
-		return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9,
-                                (u64 *)arg);
-#endif
 
 	case BLKFLSBUF:
-		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-		fsync_dev(inode->i_rdev);
-		invalidate_buffers(inode->i_rdev);
-		if (nftl->mtd->sync)
-			nftl->mtd->sync(nftl->mtd);
 		return 0;
 
-	case BLKRRPART:
-		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-		if (nftl->usecount > 1) return -EBUSY;
-		/* 
-		 * We have to flush all buffers and invalidate caches,
-		 * or we won't be able to re-use the partitions,
-		 * if there was a change and we don't want to reboot
-		 */
-		p = (1<<NFTL_PARTN_BITS) - 1;
-		while (p-- > 0) {
-			kdev_t devp = MKDEV(MAJOR(inode->i_dev), MINOR(inode->i_dev)+p);
-			if (part_table[p].nr_sects > 0)
-				invalidate_device (devp, 1);
-
-			part_table[MINOR(inode->i_dev)+p].start_sect = 0;
-			part_table[MINOR(inode->i_dev)+p].nr_sects = 0;
-		}
-		
-#if LINUX_VERSION_CODE < 0x20328
-		resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS);
-#else
-		grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS,
-				1<<NFTL_PARTN_BITS, nftl->nr_sects);
-#endif
-		return 0;
-
-#if (LINUX_VERSION_CODE < 0x20303)		
-	RO_IOCTLS(inode->i_rdev, arg);  /* ref. linux/blk.h */
-#else
-	case BLKROSET:
-	case BLKROGET:
-	case BLKSSZGET:
-		return blk_ioctl(inode->i_rdev, cmd, arg);
-#endif
-
 	default:
-		return -EINVAL;
-	}
-}
-
-void nftl_request(RQFUNC_ARG)
-{
-	unsigned int dev, block, nsect;
-	struct NFTLrecord *nftl;
-	char *buffer;
-	struct request *req;
-	int res;
-
-	while (1) {
-		INIT_REQUEST;	/* blk.h */
-		req = CURRENT;
-		
-		/* We can do this because the generic code knows not to
-		   touch the request at the head of the queue */
-		spin_unlock_irq(&io_request_lock);
-
-		DEBUG(MTD_DEBUG_LEVEL2, "NFTL_request\n");
-		DEBUG(MTD_DEBUG_LEVEL3, "NFTL %s request, from sector 0x%04lx for 0x%04lx sectors\n",
-		      (req->cmd == READ) ? "Read " : "Write",
-		      req->sector, req->current_nr_sectors);
-
-		dev = MINOR(req->rq_dev);
-		block = req->sector;
-		nsect = req->current_nr_sectors;
-		buffer = req->buffer;
-		res = 1; /* succeed */
-
-		if (dev >= MAX_NFTLS * (1<<NFTL_PARTN_BITS)) {
-			/* there is no such partition */
-			printk("nftl: bad minor number: device = %s\n",
-			       kdevname(req->rq_dev));
-			res = 0; /* fail */
-			goto repeat;
-		}
-		
-		nftl = NFTLs[dev / (1<<NFTL_PARTN_BITS)];
-		DEBUG(MTD_DEBUG_LEVEL3, "Waiting for mutex\n");
-		down(&nftl->mutex);
-		DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n");
-
-		if (block + nsect > part_table[dev].nr_sects) {
-			/* access past the end of device */
-			printk("nftl%c%d: bad access: block = %d, count = %d\n",
-			       (MINOR(req->rq_dev)>>6)+'a', dev & 0xf, block, nsect);
-			up(&nftl->mutex);
-			res = 0; /* fail */
-			goto repeat;
-		}
-		
-		block += part_table[dev].start_sect;
-		
-		if (req->cmd == READ) {
-			DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request of 0x%x sectors @ %x "
-			      "(req->nr_sectors == %lx)\n", nsect, block, req->nr_sectors);
-	
-			for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
-				/* Read a single sector to req->buffer + (512 * i) */
-				if (NFTL_readblock(nftl, block, buffer)) {
-					DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request failed\n");
-					up(&nftl->mutex);
-					res = 0;
-					goto repeat;
-				}
-			}
-
-			DEBUG(MTD_DEBUG_LEVEL2,"NFTL read request completed OK\n");
-			up(&nftl->mutex);
-			goto repeat;
-		} else if (req->cmd == WRITE) {
-			DEBUG(MTD_DEBUG_LEVEL2, "NFTL write request of 0x%x sectors @ %x "
-			      "(req->nr_sectors == %lx)\n", nsect, block,
-			      req->nr_sectors);
-#ifdef CONFIG_NFTL_RW
-			for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
-				/* Read a single sector to req->buffer + (512 * i) */
-				if (NFTL_writeblock(nftl, block, buffer)) {
-					DEBUG(MTD_DEBUG_LEVEL1,"NFTL write request failed\n");
-					up(&nftl->mutex);
-					res = 0;
-					goto repeat;
-				}
-			}
-			DEBUG(MTD_DEBUG_LEVEL2,"NFTL write request completed OK\n");
-#else
-			res = 0; /* Writes always fail */
-#endif /* CONFIG_NFTL_RW */
-			up(&nftl->mutex);
-			goto repeat;
-		} else {
-			DEBUG(MTD_DEBUG_LEVEL0, "NFTL unknown request\n");
-			up(&nftl->mutex);
-			res = 0;
-			goto repeat;
-		}
-	repeat: 
-		DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res);
-		spin_lock_irq(&io_request_lock);
-		end_request(res);
+		return -ENOTTY;
 	}
 }
 
-static int nftl_open(struct inode *ip, struct file *fp)
-{
-	int nftlnum = MINOR(ip->i_rdev) >> NFTL_PARTN_BITS;
-	struct NFTLrecord *thisNFTL;
-	thisNFTL = NFTLs[nftlnum];
-
-	DEBUG(MTD_DEBUG_LEVEL2,"NFTL_open\n");
-
-#ifdef CONFIG_KMOD
-	if (!thisNFTL && nftlnum == 0) {
-		request_module("docprobe");
-		thisNFTL = NFTLs[nftlnum];
-	}
-#endif
-	if (!thisNFTL) {
-		DEBUG(MTD_DEBUG_LEVEL2,"ENODEV: thisNFTL = %d, minor = %d, ip = %p, fp = %p\n", 
-		      nftlnum, ip->i_rdev, ip, fp);
-		return -ENODEV;
-	}
-
-#ifndef CONFIG_NFTL_RW
-	if (fp->f_mode & FMODE_WRITE)
-		return -EROFS;
-#endif /* !CONFIG_NFTL_RW */
-
-	thisNFTL->usecount++;
-	BLK_INC_USE_COUNT;
-	if (!get_mtd_device(thisNFTL->mtd, -1)) {
-		BLK_DEC_USE_COUNT;
-		return -ENXIO;
-	}
-
-	return 0;
-}
-
-static int nftl_release(struct inode *inode, struct file *fp)
-{
-	struct NFTLrecord *thisNFTL;
-
-	thisNFTL = NFTLs[MINOR(inode->i_rdev) / 16];
-
-	DEBUG(MTD_DEBUG_LEVEL2, "NFTL_release\n");
-
-	if (thisNFTL->mtd->sync)
-		thisNFTL->mtd->sync(thisNFTL->mtd);
-	thisNFTL->usecount--;
-	BLK_DEC_USE_COUNT;
-
-	put_mtd_device(thisNFTL->mtd);
-
-	return 0;
-}
-#if LINUX_VERSION_CODE < 0x20326
-static struct file_operations nftl_fops = {
-	read:		block_read,
-	write:		block_write,
-	ioctl:		nftl_ioctl,
-	open:		nftl_open,
-	release:	nftl_release,
-	fsync:		block_fsync,
-};
-#else
-static struct block_device_operations nftl_fops = 
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
-	owner:		THIS_MODULE,
-#endif
-	open:		nftl_open,
-	release:	nftl_release,
-	ioctl: 		nftl_ioctl
-};
-#endif
-
-
 
 /****************************************************************************
  *
@@ -1048,49 +730,31 @@
  *
  ****************************************************************************/
 
-static struct mtd_notifier nftl_notifier = {
-	.add	= NFTL_notify_add,
-	.remove	= NFTL_notify_remove
+
+struct mtd_blktrans_ops nftl_tr = {
+	.name		= "nftl",
+	.major		= NFTL_MAJOR,
+	.part_bits	= NFTL_PARTN_BITS,
+	.ioctl		= nftl_ioctl,
+	.readsect	= nftl_readblock,
+	.writesect	= nftl_writeblock,
+	.add_mtd	= nftl_add_mtd,
+	.remove_dev	= nftl_remove_dev,
+	.owner		= THIS_MODULE,
 };
 
 extern char nftlmountrev[];
 
 int __init init_nftl(void)
 {
-	int i;
-
-#ifdef PRERELEASE 
 	printk(KERN_INFO "NFTL driver: nftlcore.c $Revision$, nftlmount.c %s\n", nftlmountrev);
-#endif
-
-	if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)){
-		printk("unable to register NFTL block device on major %d\n", MAJOR_NR);
-		return -EBUSY;
-	} else {
-		blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request);
 
-		/* set block size to 1kB each */
-		for (i = 0; i < 256; i++) {
-			nftl_blocksizes[i] = 1024;
-		}
-		blksize_size[MAJOR_NR] = nftl_blocksizes;
-
-		add_gendisk(&nftl_gendisk);
-	}
-	
-	register_mtd_user(&nftl_notifier);
-
-	return 0;
+	return register_mtd_blktrans(&nftl_tr);
 }
 
 static void __exit cleanup_nftl(void)
 {
-  	unregister_mtd_user(&nftl_notifier);
-  	unregister_blkdev(MAJOR_NR, "nftl");
-  	
-  	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-
-	del_gendisk(&nftl_gendisk);
+	deregister_mtd_blktrans(&nftl_tr);
 }
 
 module_init(init_nftl);




More information about the linux-mtd-cvs mailing list