aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r--drivers/mtd/nand/nand_base.c188
1 files changed, 0 insertions, 188 deletions
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;