mtd/drivers/mtd/devices doc2000.c,1.54,1.55

David Woodhouse dwmw2 at infradead.org
Tue Jul 1 18:23:23 EDT 2003


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

Modified Files:
	doc2000.c 
Log Message:
Add writev to make JFFS2 work

Index: doc2000.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/devices/doc2000.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- doc2000.c	30 Jun 2003 13:06:01 -0000	1.54
+++ doc2000.c	1 Jul 2003 22:23:21 -0000	1.55
@@ -56,6 +56,9 @@
 			size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel);
 static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
 			 size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel);
+static int doc_writev_ecc(struct mtd_info *mtd, const struct iovec *vecs, 
+			  unsigned long count, loff_t to, size_t *retlen,
+			  u_char *eccbuf, struct nand_oobinfo *oobsel);
 static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
 			size_t *retlen, u_char *buf);
 static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
@@ -566,6 +569,7 @@
 	mtd->write = doc_write;
 	mtd->read_ecc = doc_read_ecc;
 	mtd->write_ecc = doc_write_ecc;
+	mtd->writev_ecc = doc_writev_ecc;
 	mtd->read_oob = doc_read_oob;
 	mtd->write_oob = doc_write_oob;
 	mtd->sync = NULL;
@@ -933,6 +937,66 @@
 	up(&this->lock);
 	return 0;
 }
+
+static int doc_writev_ecc(struct mtd_info *mtd, const struct iovec *vecs, 
+			  unsigned long count, loff_t to, size_t *retlen,
+			  u_char *eccbuf, struct nand_oobinfo *oobsel)
+{
+	static char static_buf[512];
+	static DECLARE_MUTEX(writev_buf_sem);
+
+	size_t totretlen = 0;
+	size_t thisvecofs = 0;
+	int ret= 0;
+
+	down(&writev_buf_sem);
+
+	while(count) {
+		size_t thislen, thisretlen;
+		unsigned char *buf;
+
+		buf = vecs->iov_base + thisvecofs;
+		thislen = vecs->iov_len - thisvecofs;
+
+
+		if (thislen >= 512) {
+			thislen = thislen & ~(512-1);
+			thisvecofs += thislen;
+		} else {
+			/* Not enough to fill a page. Copy into buf */
+			memcpy(static_buf, buf, thislen);
+			buf = &static_buf[thislen];
+
+			while(count && thislen < 512) {
+				vecs++;
+				count--;
+				thisvecofs = min((512-thislen), vecs->iov_len);
+				memcpy(buf, vecs->iov_base, thisvecofs);
+				thislen += thisvecofs;
+				buf += thisvecofs;
+			}
+			buf = static_buf;
+		}
+		if (count && thisvecofs == vecs->iov_len) {
+			thisvecofs = 0;
+			vecs++;
+			count--;
+		}
+		ret = doc_write_ecc(mtd, to, thislen, &thisretlen, buf, eccbuf, oobsel);
+
+		totretlen += thisretlen;
+
+		if (ret || thisretlen != thislen)
+			break;
+
+		to += thislen;
+	}		
+
+	up(&writev_buf_sem);
+	*retlen = totretlen;
+	return ret;
+}
+
 
 static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
 			size_t * retlen, u_char * buf)




More information about the linux-mtd-cvs mailing list