Loading drivers/mtd/devices/doc2000.c +0 −64 Original line number Diff line number Diff line Loading @@ -59,9 +59,6 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *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, struct nand_oobinfo *oobsel); static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *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, Loading Loading @@ -589,7 +586,6 @@ void DoC2k_init(struct mtd_info *mtd) 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; Loading Loading @@ -965,66 +961,6 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, return 0; } static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) { static char static_buf[512]; static DEFINE_MUTEX(writev_buf_mutex); size_t totretlen = 0; size_t thisvecofs = 0; int ret= 0; mutex_lock(&writev_buf_mutex); 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; } mutex_unlock(&writev_buf_mutex); *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) { Loading drivers/mtd/mtdconcat.c +2 −18 Original line number Diff line number Diff line Loading @@ -253,9 +253,8 @@ concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, } static int concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) concat_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t * retlen) { struct mtd_concat *concat = CONCAT(mtd); struct kvec *vecs_copy; Loading Loading @@ -315,10 +314,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, if (!(subdev->flags & MTD_WRITEABLE)) err = -EROFS; else if (eccbuf) err = subdev->writev_ecc(subdev, &vecs_copy[entry_low], entry_high - entry_low + 1, to, &retsize, eccbuf, oobsel); else err = subdev->writev(subdev, &vecs_copy[entry_low], entry_high - entry_low + 1, to, &retsize); Loading @@ -333,8 +328,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, *retlen += retsize; total_len -= wsize; if (concat->mtd.type == MTD_NANDFLASH && eccbuf) eccbuf += mtd->oobavail * (wsize / mtd->writesize); if (total_len == 0) break; Loading @@ -347,13 +340,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, return err; } static int concat_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t * retlen) { return concat_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL); } static int concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) Loading Loading @@ -843,8 +829,6 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->mtd.write_ecc = concat_write_ecc; if (subdev[0]->writev) concat->mtd.writev = concat_writev; if (subdev[0]->writev_ecc) concat->mtd.writev_ecc = concat_writev_ecc; if (subdev[0]->read_oob) concat->mtd.read_oob = concat_read_oob; if (subdev[0]->write_oob) Loading drivers/mtd/mtdpart.c +1 −22 Original line number Diff line number Diff line Loading @@ -208,13 +208,8 @@ static int part_writev (struct mtd_info *mtd, const struct kvec *vecs, struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (part->master->writev_ecc == NULL) return part->master->writev (part->master, vecs, count, to + part->offset, retlen); else return part->master->writev_ecc (part->master, vecs, count, to + part->offset, retlen, NULL, &mtd->oobinfo); } static int part_readv (struct mtd_info *mtd, struct kvec *vecs, Loading @@ -230,20 +225,6 @@ static int part_readv (struct mtd_info *mtd, struct kvec *vecs, NULL, &mtd->oobinfo); } static int part_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) { struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (oobsel == NULL) oobsel = &mtd->oobinfo; return part->master->writev_ecc (part->master, vecs, count, to + part->offset, retlen, eccbuf, oobsel); } static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) Loading Loading @@ -446,8 +427,6 @@ int add_mtd_partitions(struct mtd_info *master, slave->mtd.writev = part_writev; if (master->readv) slave->mtd.readv = part_readv; if (master->writev_ecc) slave->mtd.writev_ecc = part_writev_ecc; if (master->readv_ecc) slave->mtd.readv_ecc = part_readv_ecc; if (master->lock) Loading drivers/mtd/nand/nand_base.c +0 −188 Original line number Diff line number Diff line Loading @@ -151,11 +151,6 @@ static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, struct nand_oobinfo *oobsel); static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const uint8_t *buf); static int nand_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); static int nand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, uint8_t *eccbuf, struct nand_oobinfo *oobsel); static int nand_erase(struct mtd_info *mtd, struct erase_info *instr); static void nand_sync(struct mtd_info *mtd); Loading Loading @@ -1856,187 +1851,6 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, size_t *r return ret; } /** * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc * @mtd: MTD device structure * @vecs: the iovectors to write * @count: number of vectors * @to: offset to write to * @retlen: pointer to variable to store the number of written bytes * * NAND write with kvec. This just calls the ecc function */ static int nand_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { return (nand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL)); } /** * nand_writev_ecc - [MTD Interface] write with iovec with ecc * @mtd: MTD device structure * @vecs: the iovectors to write * @count: number of vectors * @to: offset to write to * @retlen: pointer to variable to store the number of written bytes * @eccbuf: filesystem supplied oob data buffer * @oobsel: oob selection structure * * NAND write with iovec with ecc */ static int nand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, uint8_t *eccbuf, struct nand_oobinfo *oobsel) { int i, page, len, total_len, ret = -EIO, written = 0, chipnr; int oob, numpages, autoplace = 0, startpage; struct nand_chip *this = mtd->priv; int ppblock = (1 << (this->phys_erase_shift - this->page_shift)); uint8_t *oobbuf, *bufstart; /* Preset written len for early exit */ *retlen = 0; /* Calculate total length of data */ total_len = 0; for (i = 0; i < count; i++) total_len += (int)vecs[i].iov_len; DEBUG(MTD_DEBUG_LEVEL3, "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int)to, (unsigned int)total_len, count); /* Do not allow write past end of page */ if ((to + total_len) > mtd->size) { DEBUG(MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n"); return -EINVAL; } /* reject writes, which are not page aligned */ if (NOTALIGNED(to) || NOTALIGNED(total_len)) { printk(KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); return -EINVAL; } /* Grab the lock and see if the device is available */ nand_get_device(this, mtd, FL_WRITING); /* Get the current chip-nr */ chipnr = (int)(to >> this->chip_shift); /* Select the NAND device */ this->select_chip(mtd, chipnr); /* Check, if it is write protected */ if (nand_check_wp(mtd)) goto out; /* if oobsel is NULL, use chip defaults */ if (oobsel == NULL) oobsel = &mtd->oobinfo; /* Autoplace of oob data ? Use the default placement scheme */ if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { oobsel = this->autooob; autoplace = 1; } if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) autoplace = 1; /* Setup start page */ page = (int)(to >> this->page_shift); /* Invalidate the page cache, if we write to the cached page */ if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift)) this->pagebuf = -1; startpage = page & this->pagemask; /* Loop until all kvec' data has been written */ len = 0; while (count) { /* If the given tuple is >= pagesize then * write it out from the iov */ if ((vecs->iov_len - len) >= mtd->writesize) { /* Calc number of pages we can write * out of this iov in one go */ numpages = (vecs->iov_len - len) >> this->page_shift; /* Do not cross block boundaries */ numpages = min(ppblock - (startpage & (ppblock - 1)), numpages); oobbuf = nand_prepare_oobbuf(mtd, NULL, oobsel, autoplace, numpages); bufstart = (uint8_t *) vecs->iov_base; bufstart += len; this->data_poi = bufstart; oob = 0; for (i = 1; i <= numpages; i++) { /* Write one page. If this is the last page to write * then use the real pageprogram command, else select * cached programming if supported by the chip. */ ret = nand_write_page(mtd, this, page & this->pagemask, &oobbuf[oob], oobsel, i != numpages); if (ret) goto out; this->data_poi += mtd->writesize; len += mtd->writesize; oob += mtd->oobsize; page++; } /* Check, if we have to switch to the next tuple */ if (len >= (int)vecs->iov_len) { vecs++; len = 0; count--; } } else { /* We must use the internal buffer, read data out of each * tuple until we have a full page to write */ int cnt = 0; while (cnt < mtd->writesize) { if (vecs->iov_base != NULL && vecs->iov_len) this->data_buf[cnt++] = ((uint8_t *) vecs->iov_base)[len++]; /* Check, if we have to switch to the next tuple */ if (len >= (int)vecs->iov_len) { vecs++; len = 0; count--; } } this->pagebuf = page; this->data_poi = this->data_buf; bufstart = this->data_poi; numpages = 1; oobbuf = nand_prepare_oobbuf(mtd, NULL, oobsel, autoplace, numpages); ret = nand_write_page(mtd, this, page & this->pagemask, oobbuf, oobsel, 0); if (ret) goto out; page++; } this->data_poi = bufstart; ret = nand_verify_pages(mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0); if (ret) goto out; written += mtd->writesize * numpages; /* All done ? */ if (!count) break; startpage = page & this->pagemask; /* Check, if we cross a chip boundary */ if (!startpage) { chipnr++; this->select_chip(mtd, -1); this->select_chip(mtd, chipnr); } } ret = 0; out: /* Deselect and wake up anyone waiting on the device */ nand_release_device(mtd); *retlen = written; return ret; } /** * single_erease_cmd - [GENERIC] NAND standard block erase command function * @mtd: MTD device structure Loading Loading @@ -2718,8 +2532,6 @@ int nand_scan(struct mtd_info *mtd, int maxchips) mtd->read_oob = nand_read_oob; mtd->write_oob = nand_write_oob; mtd->readv = NULL; mtd->writev = nand_writev; mtd->writev_ecc = nand_writev_ecc; mtd->sync = nand_sync; mtd->lock = NULL; mtd->unlock = NULL; Loading drivers/mtd/onenand/onenand_base.c +0 −140 Original line number Diff line number Diff line Loading @@ -1013,144 +1013,6 @@ static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, return ret; } /** * onenand_writev_ecc - [MTD Interface] write with iovec with ecc * @param mtd MTD device structure * @param vecs the iovectors to write * @param count number of vectors * @param to offset to write to * @param retlen pointer to variable to store the number of written bytes * @param eccbuf filesystem supplied oob data buffer * @param oobsel oob selection structure * * OneNAND write with iovec with ecc */ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) { struct onenand_chip *this = mtd->priv; unsigned char *pbuf; size_t total_len, len; int i, written = 0; int ret = 0; /* Preset written len for early exit */ *retlen = 0; /* Calculate total length of data */ total_len = 0; for (i = 0; i < count; i++) total_len += vecs[i].iov_len; DEBUG(MTD_DEBUG_LEVEL3, "onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count); /* Do not allow write past end of the device */ if (unlikely((to + total_len) > mtd->size)) { DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempted write past end of device\n"); return -EINVAL; } /* Reject writes, which are not page aligned */ if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(total_len))) { DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempt to write not page aligned data\n"); return -EINVAL; } /* Grab the lock and see if the device is available */ onenand_get_device(mtd, FL_WRITING); /* TODO handling oob */ /* Loop until all keve's data has been written */ len = 0; while (count) { pbuf = this->page_buf; /* * If the given tuple is >= pagesize then * write it out from the iov */ if ((vecs->iov_len - len) >= mtd->writesize) { pbuf = vecs->iov_base + len; len += mtd->writesize; /* Check, if we have to switch to the next tuple */ if (len >= (int) vecs->iov_len) { vecs++; len = 0; count--; } } else { int cnt = 0, thislen; while (cnt < mtd->writesize) { thislen = min_t(int, mtd->writesize - cnt, vecs->iov_len - len); memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen); cnt += thislen; len += thislen; /* Check, if we have to switch to the next tuple */ if (len >= (int) vecs->iov_len) { vecs++; len = 0; count--; } } } this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize); this->write_bufferram(mtd, ONENAND_DATARAM, pbuf, 0, mtd->writesize); this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); onenand_update_bufferram(mtd, to, 1); ret = this->wait(mtd, FL_WRITING); if (ret) { DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: write failed %d\n", ret); goto out; } /* Only check verify write turn on */ ret = onenand_verify_page(mtd, (u_char *) pbuf, to); if (ret) { DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: verify failed %d\n", ret); goto out; } written += mtd->writesize; to += mtd->writesize; } out: /* Deselect and wakt up anyone waiting on the device */ onenand_release_device(mtd); *retlen = written; return 0; } /** * onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc * @param mtd MTD device structure * @param vecs the iovectors to write * @param count number of vectors * @param to offset to write to * @param retlen pointer to variable to store the number of written bytes * * OneNAND write with kvec. This just calls the ecc function */ static int onenand_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { return onenand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL); } /** * onenand_block_checkbad - [GENERIC] Check if a block is marked bad * @param mtd MTD device structure Loading Loading @@ -1964,8 +1826,6 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) #endif mtd->readv = NULL; mtd->readv_ecc = NULL; mtd->writev = onenand_writev; mtd->writev_ecc = onenand_writev_ecc; mtd->sync = onenand_sync; mtd->lock = NULL; mtd->unlock = onenand_unlock; Loading Loading
drivers/mtd/devices/doc2000.c +0 −64 Original line number Diff line number Diff line Loading @@ -59,9 +59,6 @@ static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *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, struct nand_oobinfo *oobsel); static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *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, Loading Loading @@ -589,7 +586,6 @@ void DoC2k_init(struct mtd_info *mtd) 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; Loading Loading @@ -965,66 +961,6 @@ static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, return 0; } static int doc_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) { static char static_buf[512]; static DEFINE_MUTEX(writev_buf_mutex); size_t totretlen = 0; size_t thisvecofs = 0; int ret= 0; mutex_lock(&writev_buf_mutex); 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; } mutex_unlock(&writev_buf_mutex); *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) { Loading
drivers/mtd/mtdconcat.c +2 −18 Original line number Diff line number Diff line Loading @@ -253,9 +253,8 @@ concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, } static int concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) concat_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t * retlen) { struct mtd_concat *concat = CONCAT(mtd); struct kvec *vecs_copy; Loading Loading @@ -315,10 +314,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, if (!(subdev->flags & MTD_WRITEABLE)) err = -EROFS; else if (eccbuf) err = subdev->writev_ecc(subdev, &vecs_copy[entry_low], entry_high - entry_low + 1, to, &retsize, eccbuf, oobsel); else err = subdev->writev(subdev, &vecs_copy[entry_low], entry_high - entry_low + 1, to, &retsize); Loading @@ -333,8 +328,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, *retlen += retsize; total_len -= wsize; if (concat->mtd.type == MTD_NANDFLASH && eccbuf) eccbuf += mtd->oobavail * (wsize / mtd->writesize); if (total_len == 0) break; Loading @@ -347,13 +340,6 @@ concat_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, return err; } static int concat_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t * retlen) { return concat_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL); } static int concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf) Loading Loading @@ -843,8 +829,6 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->mtd.write_ecc = concat_write_ecc; if (subdev[0]->writev) concat->mtd.writev = concat_writev; if (subdev[0]->writev_ecc) concat->mtd.writev_ecc = concat_writev_ecc; if (subdev[0]->read_oob) concat->mtd.read_oob = concat_read_oob; if (subdev[0]->write_oob) Loading
drivers/mtd/mtdpart.c +1 −22 Original line number Diff line number Diff line Loading @@ -208,13 +208,8 @@ static int part_writev (struct mtd_info *mtd, const struct kvec *vecs, struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (part->master->writev_ecc == NULL) return part->master->writev (part->master, vecs, count, to + part->offset, retlen); else return part->master->writev_ecc (part->master, vecs, count, to + part->offset, retlen, NULL, &mtd->oobinfo); } static int part_readv (struct mtd_info *mtd, struct kvec *vecs, Loading @@ -230,20 +225,6 @@ static int part_readv (struct mtd_info *mtd, struct kvec *vecs, NULL, &mtd->oobinfo); } static int part_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) { struct mtd_part *part = PART(mtd); if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; if (oobsel == NULL) oobsel = &mtd->oobinfo; return part->master->writev_ecc (part->master, vecs, count, to + part->offset, retlen, eccbuf, oobsel); } static int part_readv_ecc (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) Loading Loading @@ -446,8 +427,6 @@ int add_mtd_partitions(struct mtd_info *master, slave->mtd.writev = part_writev; if (master->readv) slave->mtd.readv = part_readv; if (master->writev_ecc) slave->mtd.writev_ecc = part_writev_ecc; if (master->readv_ecc) slave->mtd.readv_ecc = part_readv_ecc; if (master->lock) Loading
drivers/mtd/nand/nand_base.c +0 −188 Original line number Diff line number Diff line Loading @@ -151,11 +151,6 @@ static int nand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len, struct nand_oobinfo *oobsel); static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const uint8_t *buf); static int nand_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); static int nand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, uint8_t *eccbuf, struct nand_oobinfo *oobsel); static int nand_erase(struct mtd_info *mtd, struct erase_info *instr); static void nand_sync(struct mtd_info *mtd); Loading Loading @@ -1856,187 +1851,6 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, size_t *r return ret; } /** * nand_writev - [MTD Interface] compabilty function for nand_writev_ecc * @mtd: MTD device structure * @vecs: the iovectors to write * @count: number of vectors * @to: offset to write to * @retlen: pointer to variable to store the number of written bytes * * NAND write with kvec. This just calls the ecc function */ static int nand_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { return (nand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL)); } /** * nand_writev_ecc - [MTD Interface] write with iovec with ecc * @mtd: MTD device structure * @vecs: the iovectors to write * @count: number of vectors * @to: offset to write to * @retlen: pointer to variable to store the number of written bytes * @eccbuf: filesystem supplied oob data buffer * @oobsel: oob selection structure * * NAND write with iovec with ecc */ static int nand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, uint8_t *eccbuf, struct nand_oobinfo *oobsel) { int i, page, len, total_len, ret = -EIO, written = 0, chipnr; int oob, numpages, autoplace = 0, startpage; struct nand_chip *this = mtd->priv; int ppblock = (1 << (this->phys_erase_shift - this->page_shift)); uint8_t *oobbuf, *bufstart; /* Preset written len for early exit */ *retlen = 0; /* Calculate total length of data */ total_len = 0; for (i = 0; i < count; i++) total_len += (int)vecs[i].iov_len; DEBUG(MTD_DEBUG_LEVEL3, "nand_writev: to = 0x%08x, len = %i, count = %ld\n", (unsigned int)to, (unsigned int)total_len, count); /* Do not allow write past end of page */ if ((to + total_len) > mtd->size) { DEBUG(MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of device\n"); return -EINVAL; } /* reject writes, which are not page aligned */ if (NOTALIGNED(to) || NOTALIGNED(total_len)) { printk(KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n"); return -EINVAL; } /* Grab the lock and see if the device is available */ nand_get_device(this, mtd, FL_WRITING); /* Get the current chip-nr */ chipnr = (int)(to >> this->chip_shift); /* Select the NAND device */ this->select_chip(mtd, chipnr); /* Check, if it is write protected */ if (nand_check_wp(mtd)) goto out; /* if oobsel is NULL, use chip defaults */ if (oobsel == NULL) oobsel = &mtd->oobinfo; /* Autoplace of oob data ? Use the default placement scheme */ if (oobsel->useecc == MTD_NANDECC_AUTOPLACE) { oobsel = this->autooob; autoplace = 1; } if (oobsel->useecc == MTD_NANDECC_AUTOPL_USR) autoplace = 1; /* Setup start page */ page = (int)(to >> this->page_shift); /* Invalidate the page cache, if we write to the cached page */ if (page <= this->pagebuf && this->pagebuf < ((to + total_len) >> this->page_shift)) this->pagebuf = -1; startpage = page & this->pagemask; /* Loop until all kvec' data has been written */ len = 0; while (count) { /* If the given tuple is >= pagesize then * write it out from the iov */ if ((vecs->iov_len - len) >= mtd->writesize) { /* Calc number of pages we can write * out of this iov in one go */ numpages = (vecs->iov_len - len) >> this->page_shift; /* Do not cross block boundaries */ numpages = min(ppblock - (startpage & (ppblock - 1)), numpages); oobbuf = nand_prepare_oobbuf(mtd, NULL, oobsel, autoplace, numpages); bufstart = (uint8_t *) vecs->iov_base; bufstart += len; this->data_poi = bufstart; oob = 0; for (i = 1; i <= numpages; i++) { /* Write one page. If this is the last page to write * then use the real pageprogram command, else select * cached programming if supported by the chip. */ ret = nand_write_page(mtd, this, page & this->pagemask, &oobbuf[oob], oobsel, i != numpages); if (ret) goto out; this->data_poi += mtd->writesize; len += mtd->writesize; oob += mtd->oobsize; page++; } /* Check, if we have to switch to the next tuple */ if (len >= (int)vecs->iov_len) { vecs++; len = 0; count--; } } else { /* We must use the internal buffer, read data out of each * tuple until we have a full page to write */ int cnt = 0; while (cnt < mtd->writesize) { if (vecs->iov_base != NULL && vecs->iov_len) this->data_buf[cnt++] = ((uint8_t *) vecs->iov_base)[len++]; /* Check, if we have to switch to the next tuple */ if (len >= (int)vecs->iov_len) { vecs++; len = 0; count--; } } this->pagebuf = page; this->data_poi = this->data_buf; bufstart = this->data_poi; numpages = 1; oobbuf = nand_prepare_oobbuf(mtd, NULL, oobsel, autoplace, numpages); ret = nand_write_page(mtd, this, page & this->pagemask, oobbuf, oobsel, 0); if (ret) goto out; page++; } this->data_poi = bufstart; ret = nand_verify_pages(mtd, this, startpage, numpages, oobbuf, oobsel, chipnr, 0); if (ret) goto out; written += mtd->writesize * numpages; /* All done ? */ if (!count) break; startpage = page & this->pagemask; /* Check, if we cross a chip boundary */ if (!startpage) { chipnr++; this->select_chip(mtd, -1); this->select_chip(mtd, chipnr); } } ret = 0; out: /* Deselect and wake up anyone waiting on the device */ nand_release_device(mtd); *retlen = written; return ret; } /** * single_erease_cmd - [GENERIC] NAND standard block erase command function * @mtd: MTD device structure Loading Loading @@ -2718,8 +2532,6 @@ int nand_scan(struct mtd_info *mtd, int maxchips) mtd->read_oob = nand_read_oob; mtd->write_oob = nand_write_oob; mtd->readv = NULL; mtd->writev = nand_writev; mtd->writev_ecc = nand_writev_ecc; mtd->sync = nand_sync; mtd->lock = NULL; mtd->unlock = NULL; Loading
drivers/mtd/onenand/onenand_base.c +0 −140 Original line number Diff line number Diff line Loading @@ -1013,144 +1013,6 @@ static int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, return ret; } /** * onenand_writev_ecc - [MTD Interface] write with iovec with ecc * @param mtd MTD device structure * @param vecs the iovectors to write * @param count number of vectors * @param to offset to write to * @param retlen pointer to variable to store the number of written bytes * @param eccbuf filesystem supplied oob data buffer * @param oobsel oob selection structure * * OneNAND write with iovec with ecc */ static int onenand_writev_ecc(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel) { struct onenand_chip *this = mtd->priv; unsigned char *pbuf; size_t total_len, len; int i, written = 0; int ret = 0; /* Preset written len for early exit */ *retlen = 0; /* Calculate total length of data */ total_len = 0; for (i = 0; i < count; i++) total_len += vecs[i].iov_len; DEBUG(MTD_DEBUG_LEVEL3, "onenand_writev_ecc: to = 0x%08x, len = %i, count = %ld\n", (unsigned int) to, (unsigned int) total_len, count); /* Do not allow write past end of the device */ if (unlikely((to + total_len) > mtd->size)) { DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempted write past end of device\n"); return -EINVAL; } /* Reject writes, which are not page aligned */ if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(total_len))) { DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: Attempt to write not page aligned data\n"); return -EINVAL; } /* Grab the lock and see if the device is available */ onenand_get_device(mtd, FL_WRITING); /* TODO handling oob */ /* Loop until all keve's data has been written */ len = 0; while (count) { pbuf = this->page_buf; /* * If the given tuple is >= pagesize then * write it out from the iov */ if ((vecs->iov_len - len) >= mtd->writesize) { pbuf = vecs->iov_base + len; len += mtd->writesize; /* Check, if we have to switch to the next tuple */ if (len >= (int) vecs->iov_len) { vecs++; len = 0; count--; } } else { int cnt = 0, thislen; while (cnt < mtd->writesize) { thislen = min_t(int, mtd->writesize - cnt, vecs->iov_len - len); memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen); cnt += thislen; len += thislen; /* Check, if we have to switch to the next tuple */ if (len >= (int) vecs->iov_len) { vecs++; len = 0; count--; } } } this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize); this->write_bufferram(mtd, ONENAND_DATARAM, pbuf, 0, mtd->writesize); this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); onenand_update_bufferram(mtd, to, 1); ret = this->wait(mtd, FL_WRITING); if (ret) { DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: write failed %d\n", ret); goto out; } /* Only check verify write turn on */ ret = onenand_verify_page(mtd, (u_char *) pbuf, to); if (ret) { DEBUG(MTD_DEBUG_LEVEL0, "onenand_writev_ecc: verify failed %d\n", ret); goto out; } written += mtd->writesize; to += mtd->writesize; } out: /* Deselect and wakt up anyone waiting on the device */ onenand_release_device(mtd); *retlen = written; return 0; } /** * onenand_writev - [MTD Interface] compabilty function for onenand_writev_ecc * @param mtd MTD device structure * @param vecs the iovectors to write * @param count number of vectors * @param to offset to write to * @param retlen pointer to variable to store the number of written bytes * * OneNAND write with kvec. This just calls the ecc function */ static int onenand_writev(struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen) { return onenand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NULL); } /** * onenand_block_checkbad - [GENERIC] Check if a block is marked bad * @param mtd MTD device structure Loading Loading @@ -1964,8 +1826,6 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) #endif mtd->readv = NULL; mtd->readv_ecc = NULL; mtd->writev = onenand_writev; mtd->writev_ecc = onenand_writev_ecc; mtd->sync = onenand_sync; mtd->lock = NULL; mtd->unlock = onenand_unlock; Loading