Пример #1
0
static ssize_t mtd_read_oob(struct cdev *cdev, void *buf, size_t count,
			     loff_t _offset, ulong flags)
{
	struct mtd_info *mtd = to_mtd(cdev);
	struct mtd_oob_ops ops;
	int ret;
	unsigned long offset = _offset;

	if (count < mtd->oobsize)
		return -EINVAL;

	ops.mode = MTD_OOB_RAW;
	ops.ooboffs = 0;
	ops.ooblen = mtd->oobsize;
	ops.oobbuf = buf;
	ops.datbuf = NULL;
	ops.len = mtd->oobsize;

	offset /= mtd->oobsize;
	ret = mtd->read_oob(mtd, offset * mtd->writesize, &ops);
	if (ret)
		return ret;

	return mtd->oobsize;
}
Пример #2
0
static ssize_t mtdraw_read(struct cdev *cdev, void *buf, size_t count,
			    loff_t _offset, ulong flags)
{
	struct mtd_info *mtd = to_mtd(cdev);
	ssize_t retlen = 0, ret = 1, toread;
	ulong numpage;
	int skip;
	unsigned long offset = _offset;

	numpage = offset / (mtd->writesize + mtd->oobsize);
	skip = offset % (mtd->writesize + mtd->oobsize);

	while (ret > 0 && count > 0) {
		toread = min_t(int, count,
				mtd->writesize + mtd->oobsize - skip);
		ret = mtdraw_read_unaligned(mtd, buf, toread,
					    skip, numpage++ * mtd->writesize);
		buf += ret;
		skip = 0;
		count -= ret;
		retlen += ret;
	}
	if (ret < 0)
		printf("err %zd\n", ret);
	else
		ret = retlen;
	return ret;
}
Пример #3
0
static int mtdraw_erase(struct cdev *cdev, size_t count, loff_t _offset)
{
	struct mtd_info *mtd = to_mtd(cdev);
	struct erase_info erase;
	unsigned long offset = _offset;
	int ret;

	offset = offset / (mtd->writesize + mtd->oobsize) * mtd->writesize;
	count = count / (mtd->writesize + mtd->oobsize) * mtd->writesize;

	memset(&erase, 0, sizeof(erase));
	erase.mtd = mtd;
	erase.addr = offset;
	erase.len = mtd->erasesize;

	while (count > 0) {
		debug("erase %d %d\n", erase.addr, erase.len);

		ret = mtd_block_isbad(mtd, erase.addr);
		if (ret > 0) {
			printf("Skipping bad block at 0x%08x\n", erase.addr);
		} else {
			ret = mtd->erase(mtd, &erase);
			if (ret)
				return ret;
		}

		erase.addr += mtd->erasesize;
		count -= count > mtd->erasesize ? mtd->erasesize : count;
	}

	return 0;
}
Пример #4
0
static ssize_t mtdraw_write(struct cdev *cdev, const void *buf, size_t count,
			    loff_t _offset, ulong flags)
{
	struct mtdraw *mtdraw = to_mtdraw(cdev);
	struct mtd_info *mtd = to_mtd(cdev);
	int bsz = mtd->writesize + mtd->oobsize;
	ulong numpage;
	size_t retlen = 0, tofill;
	unsigned long offset = _offset;
	int ret = 0;

	if (mtdraw->write_fill &&
	    mtdraw->write_ofs + mtdraw->write_fill != offset)
		return -EINVAL;
	if (mtdraw->write_fill == 0 && offset % bsz)
		return -EINVAL;

	if (mtdraw->write_fill) {
		tofill = min_t(size_t, count, bsz - mtdraw->write_fill);
		mtdraw_fillbuf(mtdraw, buf, tofill);
		offset += tofill;
		count -= tofill;
		retlen += tofill;
	}

	if (mtdraw->write_fill == bsz) {
		numpage = mtdraw->write_ofs / (mtd->writesize + mtd->oobsize);
		ret = mtdraw_blkwrite(mtd, mtdraw->writebuf,
				      mtd->writesize * numpage);
		mtdraw->write_fill = 0;
	}

	numpage = offset / (mtd->writesize + mtd->oobsize);
	while (ret >= 0 && count >= bsz) {
		ret = mtdraw_blkwrite(mtd, buf + retlen,
				   mtd->writesize * numpage++);
		count -= ret;
		retlen += ret;
		offset += ret;
	}

	if (ret >= 0 && count) {
		mtdraw->write_ofs = offset - mtdraw->write_fill;
		mtdraw_fillbuf(mtdraw, buf + retlen, count);
		retlen += count;
	}

	if (ret < 0) {
		printf("err %d\n", ret);
		return ret;
	} else {
		return retlen;
	}
}