aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/devices/doc2000.c64
-rw-r--r--drivers/mtd/mtdconcat.c20
-rw-r--r--drivers/mtd/mtdpart.c23
-rw-r--r--drivers/mtd/nand/nand_base.c188
-rw-r--r--drivers/mtd/onenand/onenand_base.c140
5 files changed, 3 insertions, 432 deletions
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 423a34f4638c..6f32942fdf77 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -59,9 +59,6 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
59 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 59 size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
60static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, 60static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
61 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); 61 size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
62static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
63 unsigned long count, loff_t to, size_t *retlen,
64 u_char *eccbuf, struct nand_oobinfo *oobsel);
65static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 62static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
66 size_t *retlen, u_char *buf); 63 size_t *retlen, u_char *buf);
67static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 64static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
@@ -589,7 +586,6 @@ void DoC2k_init(struct mtd_info *mtd)
589 mtd->write = doc_write; 586 mtd->write = doc_write;
590 mtd->read_ecc = doc_read_ecc; 587 mtd->read_ecc = doc_read_ecc;
591 mtd->write_ecc = doc_write_ecc; 588 mtd->write_ecc = doc_write_ecc;
592 mtd->writev_ecc = doc_writev_ecc;
593 mtd->read_oob = doc_read_oob; 589 mtd->read_oob = doc_read_oob;
594 mtd->write_oob = doc_write_oob; 590 mtd->write_oob = doc_write_oob;
595 mtd->sync = NULL; 591 mtd->sync = NULL;
@@ -965,66 +961,6 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
965 return 0; 961 return 0;
966} 962}
967 963
968static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
969 unsigned long count, loff_t to, size_t *retlen,
970 u_char *eccbuf, struct nand_oobinfo *oobsel)
971{
972 static char static_buf[512];
973 static DEFINE_MUTEX(writev_buf_mutex);
974
975 size_t totretlen = 0;
976 size_t thisvecofs = 0;
977 int ret= 0;
978
979 mutex_lock(&writev_buf_mutex);
980
981 while(count) {
982 size_t thislen, thisretlen;
983 unsigned char *buf;
984
985 buf = vecs->iov_base + thisvecofs;
986 thislen = vecs->iov_len - thisvecofs;
987
988
989 if (thislen >= 512) {
990 thislen = thislen & ~(512-1);
991 thisvecofs += thislen;
992 } else {
993 /* Not enough to fill a page. Copy into buf */
994 memcpy(static_buf, buf, thislen);
995 buf = &static_buf[thislen];
996
997 while(count && thislen < 512) {
998 vecs++;
999 count--;
1000 thisvecofs = min((512-thislen), vecs->iov_len);
1001 memcpy(buf, vecs->iov_base, thisvecofs);
1002 thislen += thisvecofs;
1003 buf += thisvecofs;
1004 }
1005 buf = static_buf;
1006 }
1007 if (count && thisvecofs == vecs->iov_len) {
1008 thisvecofs = 0;
1009 vecs++;
1010 count--;
1011 }
1012 ret = doc_write_ecc(mtd, to, thislen, &thisretlen, buf, eccbuf, oobsel);
1013
1014 totretlen += thisretlen;
1015
1016 if (ret || thisretlen != thislen)
1017 break;
1018
1019 to += thislen;
1020 }
1021
1022 mutex_unlock(&writev_buf_mutex);
1023 *retlen = totretlen;
1024 return ret;
1025}
1026
1027
1028static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len, 964static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
1029 size_t * retlen, u_char * buf) 965 size_t * retlen, u_char * buf)
1030{ 966{
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index a5e8373349a5..a6fcee2713b0 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -253,9 +253,8 @@ concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
253} 253}
254 254
255static int 255static int
256concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, 256concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
257 unsigned long count, loff_t to, size_t * retlen, 257 unsigned long count, loff_t to, size_t * retlen)
258 u_char *eccbuf, struct nand_oobinfo *oobsel)
259{ 258{
260 struct mtd_concat *concat = CONCAT(mtd); 259 struct mtd_concat *concat = CONCAT(mtd);
261 struct kvec *vecs_copy; 260 struct kvec *vecs_copy;
@@ -315,10 +314,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
315 314
316 if (!(subdev->flags & MTD_WRITEABLE)) 315 if (!(subdev->flags & MTD_WRITEABLE))
317 err = -EROFS; 316 err = -EROFS;
318 else if (eccbuf)
319 err = subdev->writev_ecc(subdev, &vecs_copy[entry_low],
320 entry_high - entry_low + 1, to, &retsize,
321 eccbuf, oobsel);
322 else 317 else
323 err = subdev->writev(subdev, &vecs_copy[entry_low], 318 err = subdev->writev(subdev, &vecs_copy[entry_low],
324 entry_high - entry_low + 1, to, &retsize); 319 entry_high - entry_low + 1, to, &retsize);
@@ -333,8 +328,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
333 328
334 *retlen += retsize; 329 *retlen += retsize;
335 total_len -= wsize; 330 total_len -= wsize;
336 if (concat->mtd.type == MTD_NANDFLASH && eccbuf)
337 eccbuf += mtd->oobavail * (wsize / mtd->writesize);
338 331
339 if (total_len == 0) 332 if (total_len == 0)
340 break; 333 break;
@@ -348,13 +341,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
348} 341}
349 342
350static int 343static int
351concat_writev(struct mtd_info *mtd, const struct kvec *vecs,
352 unsigned long count, loff_t to, size_t * retlen)
353{
354 return concat_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
355}
356
357static int
358concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len, 344concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
359 size_t * retlen, u_char * buf) 345 size_t * retlen, u_char * buf)
360{ 346{
@@ -843,8 +829,6 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
843 concat->mtd.write_ecc = concat_write_ecc; 829 concat->mtd.write_ecc = concat_write_ecc;
844 if (subdev[0]->writev) 830 if (subdev[0]->writev)
845 concat->mtd.writev = concat_writev; 831 concat->mtd.writev = concat_writev;
846 if (subdev[0]->writev_ecc)
847 concat->mtd.writev_ecc = concat_writev_ecc;
848 if (subdev[0]->read_oob) 832 if (subdev[0]->read_oob)
849 concat->mtd.read_oob = concat_read_oob; 833 concat->mtd.read_oob = concat_read_oob;
850 if (subdev[0]->write_oob) 834 if (subdev[0]->write_oob)
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 082662f90481..ae675608fa91 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -208,13 +208,8 @@ static int part_writev (struct mtd_info *mtd, const struct kvec *vecs,
208 struct mtd_part *part = PART(mtd); 208 struct mtd_part *part = PART(mtd);
209 if (!(mtd->flags & MTD_WRITEABLE)) 209 if (!(mtd->flags & MTD_WRITEABLE))
210 return -EROFS; 210 return -EROFS;
211 if (part->master->writev_ecc == NULL) 211 return part->master->writev (part->master, vecs, count,
212 return part->master->writev (part->master, vecs, count,
213 to + part->offset, retlen); 212 to + part->offset, retlen);
214 else
215 return part->master->writev_ecc (part->master, vecs, count,
216 to + part->offset, retlen,
217 NULL, &mtd->oobinfo);
218} 213}
219 214
220static int part_readv (struct mtd_info *mtd, struct kvec *vecs, 215static int part_readv (struct mtd_info *mtd, struct kvec *vecs,
@@ -230,20 +225,6 @@ static int part_readv (struct mtd_info *mtd, struct kvec *vecs,
230 NULL, &mtd->oobinfo); 225 NULL, &mtd->oobinfo);
231} 226}
232 227
233static int part_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs,
234 unsigned long count, loff_t to, size_t *retlen,
235 u_char *eccbuf, struct nand_oobinfo *oobsel)
236{
237 struct mtd_part *part = PART(mtd);
238 if (!(mtd->flags & MTD_WRITEABLE))
239 return -EROFS;
240 if (oobsel == NULL)
241 oobsel = &mtd->oobinfo;
242 return part->master->writev_ecc (part->master, vecs, count,
243 to + part->offset, retlen,
244 eccbuf, oobsel);
245}
246
247static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs, 228static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs,
248 unsigned long count, loff_t from, size_t *retlen, 229 unsigned long count, loff_t from, size_t *retlen,
249 u_char *eccbuf, struct nand_oobinfo *oobsel) 230 u_char *eccbuf, struct nand_oobinfo *oobsel)
@@ -446,8 +427,6 @@ int add_mtd_partitions(struct mtd_info *master,
446 slave->mtd.writev = part_writev; 427 slave->mtd.writev = part_writev;
447 if (master->readv) 428 if (master->readv)
448 slave->mtd.readv = part_readv; 429 slave->mtd.readv = part_readv;
449 if (master->writev_ecc)
450 slave->mtd.writev_ecc = part_writev_ecc;
451 if (master->readv_ecc) 430 if (master->readv_ecc)
452 slave->mtd.readv_ecc = part_readv_ecc; 431 slave->mtd.readv_ecc = part_readv_ecc;
453 if (master->lock) 432 if (master->lock)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 778535006c83..9aaeb3aa9d4d 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -151,11 +151,6 @@ static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
151 struct nand_oobinfo *oobsel); 151 struct nand_oobinfo *oobsel);
152static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, 152static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
153 size_t *retlen, const uint8_t *buf); 153 size_t *retlen, const uint8_t *buf);
154static int nand_writev(struct mtd_info *mtd, const struct kvec *vecs,
155 unsigned long count, loff_t to, size_t *retlen);
156static int nand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
157 unsigned long count, loff_t to, size_t *retlen,
158 uint8_t *eccbuf, struct nand_oobinfo *oobsel);
159static int nand_erase(struct mtd_info *mtd, struct erase_info *instr); 154static int nand_erase(struct mtd_info *mtd, struct erase_info *instr);
160static void nand_sync(struct mtd_info *mtd); 155static void nand_sync(struct mtd_info *mtd);
161 156
@@ -1857,187 +1852,6 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, size_t *r
1857} 1852}
1858 1853
1859/** 1854/**
1860 * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc
1861 * @mtd: MTD device structure
1862 * @vecs: the iovectors to write
1863 * @count: number of vectors
1864 * @to: offset to write to
1865 * @retlen: pointer to variable to store the number of written bytes
1866 *
1867 * NAND write with kvec. This just calls the ecc function
1868 */
1869static int nand_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
1870 loff_t to, size_t *retlen)
1871{
1872 return (nand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL));
1873}
1874
1875/**
1876 * nand_writev_ecc - [MTD Interface] write with iovec with ecc
1877 * @mtd: MTD device structure
1878 * @vecs: the iovectors to write
1879 * @count: number of vectors
1880 * @to: offset to write to
1881 * @retlen: pointer to variable to store the number of written bytes
1882 * @eccbuf: filesystem supplied oob data buffer
1883 * @oobsel: oob selection structure
1884 *
1885 * NAND write with iovec with ecc
1886 */
1887static int nand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count,
1888 loff_t to, size_t *retlen, uint8_t *eccbuf, struct nand_oobinfo *oobsel)
1889{
1890 int i, page, len, total_len, ret = -EIO, written = 0, chipnr;
1891 int oob, numpages, autoplace = 0, startpage;
1892 struct nand_chip *this = mtd->priv;
1893 int ppblock = (1 << (this->phys_erase_shift - this->page_shift));
1894 uint8_t *oobbuf, *bufstart;
1895
1896 /* Preset written len for early exit */
1897 *retlen = 0;
1898
1899 /* Calculate total length of data */
1900 total_len = 0;
1901 for (i = 0; i < count; i++)
1902 total_len += (int)vecs[i].iov_len;
1903
1904 DEBUG(MTD_DEBUG_LEVEL3, "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int)to, (unsigned int)total_len, count);
1905
1906 /* Do not allow write past end of page */
1907 if ((to + total_len) > mtd->size) {
1908 DEBUG(MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n");
1909 return -EINVAL;
1910 }
1911
1912 /* reject writes, which are not page aligned */
1913 if (NOTALIGNED(to) || NOTALIGNED(total_len)) {
1914 printk(KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
1915 return -EINVAL;
1916 }
1917
1918 /* Grab the lock and see if the device is available */
1919 nand_get_device(this, mtd, FL_WRITING);
1920
1921 /* Get the current chip-nr */
1922 chipnr = (int)(to >> this->chip_shift);
1923 /* Select the NAND device */
1924 this->select_chip(mtd, chipnr);
1925
1926 /* Check, if it is write protected */
1927 if (nand_check_wp(mtd))
1928 goto out;
1929
1930 /* if oobsel is NULL, use chip defaults */
1931 if (oobsel == NULL)
1932 oobsel = &mtd->oobinfo;
1933
1934 /* Autoplace of oob data ? Use the default placement scheme */
1935 if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) {
1936 oobsel = this->autooob;
1937 autoplace = 1;
1938 }
1939 if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
1940 autoplace = 1;
1941
1942 /* Setup start page */
1943 page = (int)(to >> this->page_shift);
1944 /* Invalidate the page cache, if we write to the cached page */
1945 if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift))
1946 this->pagebuf = -1;
1947
1948 startpage = page & this->pagemask;
1949
1950 /* Loop until all kvec' data has been written */
1951 len = 0;
1952 while (count) {
1953 /* If the given tuple is >= pagesize then
1954 * write it out from the iov
1955 */
1956 if ((vecs->iov_len - len) >= mtd->writesize) {
1957 /* Calc number of pages we can write
1958 * out of this iov in one go */
1959 numpages = (vecs->iov_len - len) >> this->page_shift;
1960 /* Do not cross block boundaries */
1961 numpages = min(ppblock - (startpage & (ppblock - 1)), numpages);
1962 oobbuf = nand_prepare_oobbuf(mtd, NULL, oobsel, autoplace, numpages);
1963 bufstart = (uint8_t *) vecs->iov_base;
1964 bufstart += len;
1965 this->data_poi = bufstart;
1966 oob = 0;
1967 for (i = 1; i <= numpages; i++) {
1968 /* Write one page. If this is the last page to write
1969 * then use the real pageprogram command, else select
1970 * cached programming if supported by the chip.
1971 */
1972 ret = nand_write_page(mtd, this, page & this->pagemask,
1973 &oobbuf[oob], oobsel, i != numpages);
1974 if (ret)
1975 goto out;
1976 this->data_poi += mtd->writesize;
1977 len += mtd->writesize;
1978 oob += mtd->oobsize;
1979 page++;
1980 }
1981 /* Check, if we have to switch to the next tuple */
1982 if (len >= (int)vecs->iov_len) {
1983 vecs++;
1984 len = 0;
1985 count--;
1986 }
1987 } else {
1988 /* We must use the internal buffer, read data out of each
1989 * tuple until we have a full page to write
1990 */
1991 int cnt = 0;
1992 while (cnt < mtd->writesize) {
1993 if (vecs->iov_base != NULL && vecs->iov_len)
1994 this->data_buf[cnt++] = ((uint8_t *) vecs->iov_base)[len++];
1995 /* Check, if we have to switch to the next tuple */
1996 if (len >= (int)vecs->iov_len) {
1997 vecs++;
1998 len = 0;
1999 count--;
2000 }
2001 }
2002 this->pagebuf = page;
2003 this->data_poi = this->data_buf;
2004 bufstart = this->data_poi;
2005 numpages = 1;
2006 oobbuf = nand_prepare_oobbuf(mtd, NULL, oobsel, autoplace, numpages);
2007 ret = nand_write_page(mtd, this, page & this->pagemask, oobbuf, oobsel, 0);
2008 if (ret)
2009 goto out;
2010 page++;
2011 }
2012
2013 this->data_poi = bufstart;
2014 ret = nand_verify_pages(mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0);
2015 if (ret)
2016 goto out;
2017
2018 written += mtd->writesize * numpages;
2019 /* All done ? */
2020 if (!count)
2021 break;
2022
2023 startpage = page & this->pagemask;
2024 /* Check, if we cross a chip boundary */
2025 if (!startpage) {
2026 chipnr++;
2027 this->select_chip(mtd, -1);
2028 this->select_chip(mtd, chipnr);
2029 }
2030 }
2031 ret = 0;
2032 out:
2033 /* Deselect and wake up anyone waiting on the device */
2034 nand_release_device(mtd);
2035
2036 *retlen = written;
2037 return ret;
2038}
2039
2040/**
2041 * single_erease_cmd - [GENERIC] NAND standard block erase command function 1855 * single_erease_cmd - [GENERIC] NAND standard block erase command function
2042 * @mtd: MTD device structure 1856 * @mtd: MTD device structure
2043 * @page: the page address of the block which will be erased 1857 * @page: the page address of the block which will be erased
@@ -2718,8 +2532,6 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
2718 mtd->read_oob = nand_read_oob; 2532 mtd->read_oob = nand_read_oob;
2719 mtd->write_oob = nand_write_oob; 2533 mtd->write_oob = nand_write_oob;
2720 mtd->readv = NULL; 2534 mtd->readv = NULL;
2721 mtd->writev = nand_writev;
2722 mtd->writev_ecc = nand_writev_ecc;
2723 mtd->sync = nand_sync; 2535 mtd->sync = nand_sync;
2724 mtd->lock = NULL; 2536 mtd->lock = NULL;
2725 mtd->unlock = NULL; 2537 mtd->unlock = NULL;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 4c2c61d54b3a..8e875fa140a8 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1014,144 +1014,6 @@ out:
1014} 1014}
1015 1015
1016/** 1016/**
1017 * onenand_writev_ecc - [MTD Interface] write with iovec with ecc
1018 * @param mtd MTD device structure
1019 * @param vecs the iovectors to write
1020 * @param count number of vectors
1021 * @param to offset to write to
1022 * @param retlen pointer to variable to store the number of written bytes
1023 * @param eccbuf filesystem supplied oob data buffer
1024 * @param oobsel oob selection structure
1025 *
1026 * OneNAND write with iovec with ecc
1027 */
1028static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs,
1029 unsigned long count, loff_t to, size_t *retlen,
1030 u_char *eccbuf, struct nand_oobinfo *oobsel)
1031{
1032 struct onenand_chip *this = mtd->priv;
1033 unsigned char *pbuf;
1034 size_t total_len, len;
1035 int i, written = 0;
1036 int ret = 0;
1037
1038 /* Preset written len for early exit */
1039 *retlen = 0;
1040
1041 /* Calculate total length of data */
1042 total_len = 0;
1043 for (i = 0; i < count; i++)
1044 total_len += vecs[i].iov_len;
1045
1046 DEBUG(MTD_DEBUG_LEVEL3, "onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count);
1047
1048 /* Do not allow write past end of the device */
1049 if (unlikely((to + total_len) > mtd->size)) {
1050 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempted write past end of device\n");
1051 return -EINVAL;
1052 }
1053
1054 /* Reject writes, which are not page aligned */
1055 if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(total_len))) {
1056 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempt to write not page aligned data\n");
1057 return -EINVAL;
1058 }
1059
1060 /* Grab the lock and see if the device is available */
1061 onenand_get_device(mtd, FL_WRITING);
1062
1063 /* TODO handling oob */
1064
1065 /* Loop until all keve's data has been written */
1066 len = 0;
1067 while (count) {
1068 pbuf = this->page_buf;
1069 /*
1070 * If the given tuple is >= pagesize then
1071 * write it out from the iov
1072 */
1073 if ((vecs->iov_len - len) >= mtd->writesize) {
1074 pbuf = vecs->iov_base + len;
1075
1076 len += mtd->writesize;
1077
1078 /* Check, if we have to switch to the next tuple */
1079 if (len >= (int) vecs->iov_len) {
1080 vecs++;
1081 len = 0;
1082 count--;
1083 }
1084 } else {
1085 int cnt = 0, thislen;
1086 while (cnt < mtd->writesize) {
1087 thislen = min_t(int, mtd->writesize - cnt, vecs->iov_len - len);
1088 memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen);
1089 cnt += thislen;
1090 len += thislen;
1091
1092 /* Check, if we have to switch to the next tuple */
1093 if (len >= (int) vecs->iov_len) {
1094 vecs++;
1095 len = 0;
1096 count--;
1097 }
1098 }
1099 }
1100
1101 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize);
1102
1103 this->write_bufferram(mtd, ONENAND_DATARAM, pbuf, 0, mtd->writesize);
1104 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
1105
1106 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
1107
1108 onenand_update_bufferram(mtd, to, 1);
1109
1110 ret = this->wait(mtd, FL_WRITING);
1111 if (ret) {
1112 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: write failed %d\n", ret);
1113 goto out;
1114 }
1115
1116
1117 /* Only check verify write turn on */
1118 ret = onenand_verify_page(mtd, (u_char *) pbuf, to);
1119 if (ret) {
1120 DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: verify failed %d\n", ret);
1121 goto out;
1122 }
1123
1124 written += mtd->writesize;
1125
1126 to += mtd->writesize;
1127 }
1128
1129out:
1130 /* Deselect and wakt up anyone waiting on the device */
1131 onenand_release_device(mtd);
1132
1133 *retlen = written;
1134
1135 return 0;
1136}
1137
1138/**
1139 * onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc
1140 * @param mtd MTD device structure
1141 * @param vecs the iovectors to write
1142 * @param count number of vectors
1143 * @param to offset to write to
1144 * @param retlen pointer to variable to store the number of written bytes
1145 *
1146 * OneNAND write with kvec. This just calls the ecc function
1147 */
1148static int onenand_writev(struct mtd_info *mtd, const struct kvec *vecs,
1149 unsigned long count, loff_t to, size_t *retlen)
1150{
1151 return onenand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL);
1152}
1153
1154/**
1155 * onenand_block_checkbad - [GENERIC] Check if a block is marked bad 1017 * onenand_block_checkbad - [GENERIC] Check if a block is marked bad
1156 * @param mtd MTD device structure 1018 * @param mtd MTD device structure
1157 * @param ofs offset from device start 1019 * @param ofs offset from device start
@@ -1964,8 +1826,6 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
1964#endif 1826#endif
1965 mtd->readv = NULL; 1827 mtd->readv = NULL;
1966 mtd->readv_ecc = NULL; 1828 mtd->readv_ecc = NULL;
1967 mtd->writev = onenand_writev;
1968 mtd->writev_ecc = onenand_writev_ecc;
1969 mtd->sync = onenand_sync; 1829 mtd->sync = onenand_sync;
1970 mtd->lock = NULL; 1830 mtd->lock = NULL;
1971 mtd->unlock = onenand_unlock; 1831 mtd->unlock = onenand_unlock;