muti-page-rw.diff

Rogelio M. Serrano Jr. rogelio at evoserve.com
Tue Jul 25 20:08:43 EDT 2000


I modified the doc2000 read and write functions to allow multipage read
and write to any offest. I am behind a firewall so I cant do cvs. I am
working on jffs_file_write to fix the max_chunk_size problem.
-------------- next part --------------
diff -r -u mtd/kernel/doc2000.c mtd-snapshot-20000725/kernel/doc2000.c
--- mtd/kernel/doc2000.c	Wed Jul 26 06:00:03 2000
+++ mtd-snapshot-20000725/kernel/doc2000.c	Wed Jul 26 07:27:47 2000
@@ -496,18 +496,37 @@
 	unsigned long docptr;
 	struct Nand *mychip;
 
+        loff_t subfrom;
+        size_t sublen;
+        u_char *pos;
+        int multipage = 0;
+        loff_t end = from + len;
+
 	docptr = this->virtadr;
 
+        *retlen = 0;
+        sublen = len;
+        subfrom = from;
+        pos = buf;
+        
 	/* Don't allow read past end of device */
 	if (from >= this->totlen)
 		return -EINVAL;
-	
-	/* Don't allow a single read to cross a 512-byte block boundary */
-	if (from + len > ( (from | 0x1ff) + 1)) 
-		len = ((from | 0x1ff) + 1) - from;
 
+        if ((subfrom + sublen) > ((subfrom | 0x1ff) + 1)) {
+              multipage = 1;
+              sublen = ((subfrom | 0x1ff) + 1) - subfrom;
+        }
+do {
+        if ((subfrom + 512) > end) {
+             multipage = 0;
+             sublen = end - subfrom;
+             if (!sublen) break;
+        }
+
+	
 	/* Find the chip which is to be used and select it */
-	mychip = &this->chips[from >> (this->chipshift)];
+	mychip = &this->chips[subfrom >> (this->chipshift)];
 	
 	if (this->curfloor != mychip->floor) {
 		DoC_SelectFloor(docptr, mychip->floor);
@@ -527,15 +546,15 @@
 		WriteDOC ( DOC_ECC_EN, docptr, ECCConf);
 	}
 
-	DoC_Command(docptr, (from >> 8) & 1, CDSN_CTRL_WP);
-	DoC_Address(docptr, 3, from, CDSN_CTRL_WP , CDSN_CTRL_ECC_IO);
+	DoC_Command(docptr, (subfrom >> 8) & 1, CDSN_CTRL_WP);
+	DoC_Address(docptr, 3, subfrom, CDSN_CTRL_WP , CDSN_CTRL_ECC_IO);
 
-	for (di=0; di < len ; di++) {
-		buf[di] = ReadDOC(docptr, 2k_CDSN_IO);
+	for (di=0; di < sublen ; di++) {
+		pos[di] = ReadDOC(docptr, 2k_CDSN_IO);
 	}
 
 	/* Let the caller know we completed it */
-	*retlen = len;
+	*retlen += sublen;
 
 	if (eccbuf) {
 		/* Read the ECC data through the DiskOnChip ECC logic */
@@ -571,6 +590,14 @@
 		
 	}
 
+        if (multipage){
+             subfrom += sublen;
+             pos += sublen;
+             sublen = 512;
+        }
+
+} while (multipage);
+
 	return 0;
 }
 
@@ -587,24 +614,36 @@
 	unsigned long docptr;
 	struct Nand *mychip;
 
+        loff_t subto;
+        size_t sublen;
+        u_char *pos;
+        int multipage = 0;
+        loff_t end = to + len;
+        
 	docptr = this->virtadr;
 
+        *retlen = 0;
+        sublen = len;
+        subto = to;
+        pos = buf;
+        
 	/* Don't allow write past end of device */
 	if (to >= this->totlen)
 		return -EINVAL;
-#if 0	
-	/* Don't allow a single write to cross a 512-byte block boundary */
-	if (to + len > ( (to | 0x1ff) + 1)) 
-		len = ((to | 0x1ff) + 1) - to;
-
-#else
-	/* Don't allow writes which aren't exactly one block */
-	if (to & 0x1ff || len != 0x200)
-		return -EINVAL;
-#endif
 
+        if ((subto + sublen) > ((subto | 0x1ff) + 1)) {
+              multipage = 1;
+              sublen = ((subto | 0x1ff) + 1) - subto;
+        }
+do {
+        if ((subto + 512) > end) {
+             multipage = 0;
+             sublen = end - subto;
+             if (!sublen) break;
+        }
+        
 	/* Find the chip which is to be used and select it */
-	mychip = &this->chips[to >> (this->chipshift)];
+	mychip = &this->chips[subto >> (this->chipshift)];
 	
 	if (this->curfloor != mychip->floor) {
 		DoC_SelectFloor(docptr, mychip->floor);
@@ -628,10 +667,10 @@
 	}
 
 	DoC_Command(docptr, NAND_CMD_SEQIN, 0);
-	DoC_Address(docptr, 3, to, 0, CDSN_CTRL_ECC_IO);
+	DoC_Address(docptr, 3, subto, 0, CDSN_CTRL_ECC_IO);
 
-	for (di=0; di < len ; di++) {
-		WriteDOC(buf[di], docptr, 2k_CDSN_IO);
+	for (di=0; di < sublen ; di++) {
+		WriteDOC(pos[di], docptr, 2k_CDSN_IO);
 	}
 
 
@@ -675,8 +714,14 @@
 	}
 
 	/* Let the caller know we completed it */
-	*retlen = len;
+	*retlen += sublen;
 
+        if (multipage){
+             subto += sublen;
+             pos += sublen;
+             sublen = 512;
+        }
+} while (multipage); 
 	return 0;
 }
 


More information about the linux-mtd mailing list