Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5bd34c09 authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

[MTD] NAND Replace oobinfo by ecclayout



The nand_oobinfo structure is not fitting the newer error correction
demands anymore. Replace it by struct nand_ecclayout and fixup the users
all over the place. Keep the nand_oobinfo based ioctl for user space
compability reasons.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent ff268fb8
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -512,14 +512,36 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
		break;
	}

	/* Legacy interface */
	case MEMGETOOBSEL:
	{
		if (copy_to_user(argp, mtd->oobinfo,
				 sizeof(struct nand_oobinfo)))
		struct nand_oobinfo oi;

		if (!mtd->ecclayout)
			return -EOPNOTSUPP;
		if (mtd->ecclayout->eccbytes > ARRAY_SIZE(oi.eccpos))
			return -EINVAL;

		oi.useecc = MTD_NANDECC_AUTOPLACE;
		memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos));
		memcpy(&oi.oobfree, mtd->ecclayout->oobfree,
		       sizeof(oi.oobfree));

		if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo)))
			return -EFAULT;
		break;
	}

	case ECCGETLAYOUT:

		if (!mtd->ecclayout)
			return -EOPNOTSUPP;

		if (copy_to_user(argp, &mtd->ecclayout,
				 sizeof(struct nand_ecclayout)))
			return -EFAULT;
		break;

	case MEMGETBADBLOCK:
	{
		loff_t offs;
+1 −1
Original line number Diff line number Diff line
@@ -766,7 +766,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c

	}

	concat->mtd.oobinfo = subdev[0]->oobinfo;
	concat->mtd.ecclayout = subdev[0]->ecclayout;

	concat->num_subdev = num_devs;
	concat->mtd.name = name;
+1 −1
Original line number Diff line number Diff line
@@ -434,7 +434,7 @@ int add_mtd_partitions(struct mtd_info *master,
				parts[i].name);
		}

		slave->mtd.oobinfo = master->oobinfo;
		slave->mtd.ecclayout = master->ecclayout;

		if(parts[i].mtdp)
		{	/* store the object pointer (caller may or may not register it */
+2 −3
Original line number Diff line number Diff line
@@ -1058,8 +1058,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat,
 * safer.  The only problem with it is that any code that parses oobfree must
 * be able to handle out-of-order segments.
 */
static struct nand_oobinfo doc200x_oobinfo = {
	.useecc = MTD_NANDECC_AUTOPLACE,
static struct nand_ecclayout doc200x_oobinfo = {
	.eccbytes = 6,
	.eccpos = {0, 1, 2, 3, 4, 5},
	.oobfree = {{8, 8}, {6, 2}}
@@ -1662,7 +1661,7 @@ static int __init doc_probe(unsigned long physadr)
	nand->ecc.calculate	= doc200x_calculate_ecc;
	nand->ecc.correct	= doc200x_correct_data;

	nand->autooob		= &doc200x_oobinfo;
	nand->ecc.layout	= &doc200x_oobinfo;
	nand->ecc.mode		= NAND_ECC_HW_SYNDROME;
	nand->ecc.size		= 512;
	nand->ecc.bytes		= 6;
+33 −19
Original line number Diff line number Diff line
@@ -52,28 +52,33 @@
#endif

/* Define default oob placement schemes for large and small page devices */
static struct nand_oobinfo nand_oob_8 = {
	.useecc = MTD_NANDECC_AUTOPLACE,
static struct nand_ecclayout nand_oob_8 = {
	.eccbytes = 3,
	.eccpos = {0, 1, 2},
	.oobfree = {{3, 2}, {6, 2}}
	.oobfree = {
		{.offset = 3,
		 .length = 2},
		{.offset = 6,
		 .length = 2}}
};

static struct nand_oobinfo nand_oob_16 = {
	.useecc = MTD_NANDECC_AUTOPLACE,
static struct nand_ecclayout nand_oob_16 = {
	.eccbytes = 6,
	.eccpos = {0, 1, 2, 3, 6, 7},
	.oobfree = {{8, 8}}
	.oobfree = {
		{.offset = 8,
		 . length = 8}}
};

static struct nand_oobinfo nand_oob_64 = {
	.useecc = MTD_NANDECC_AUTOPLACE,
static struct nand_ecclayout nand_oob_64 = {
	.eccbytes = 24,
	.eccpos = {
		   40, 41, 42, 43, 44, 45, 46, 47,
		   48, 49, 50, 51, 52, 53, 54, 55,
		   56, 57, 58, 59, 60, 61, 62, 63},
	.oobfree = {{2, 38}}
	.oobfree = {
		{.offset = 2,
		 .length = 38}}
};

/* This is used for padding purposes in nand_write_oob */
@@ -749,7 +754,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
	uint8_t *p = buf;
	uint8_t *ecc_calc = chip->buffers.ecccalc;
	uint8_t *ecc_code = chip->buffers.ecccode;
	int *eccpos = chip->autooob->eccpos;
	int *eccpos = chip->ecc.layout->eccpos;

	chip->read_buf(mtd, buf, mtd->writesize);
	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -795,7 +800,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
	uint8_t *p = buf;
	uint8_t *ecc_calc = chip->buffers.ecccalc;
	uint8_t *ecc_code = chip->buffers.ecccode;
	int *eccpos = chip->autooob->eccpos;
	int *eccpos = chip->ecc.layout->eccpos;

	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
		chip->ecc.hwctl(mtd, NAND_ECC_READ);
@@ -1198,7 +1203,7 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
	int eccsteps = chip->ecc.steps;
	uint8_t *ecc_calc = chip->buffers.ecccalc;
	const uint8_t *p = buf;
	int *eccpos = chip->autooob->eccpos;
	int *eccpos = chip->ecc.layout->eccpos;

	if (chip->ecc.mode != NAND_ECC_NONE) {
		/* Software ecc calculation */
@@ -1227,7 +1232,7 @@ static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
	int eccsteps = chip->ecc.steps;
	uint8_t *ecc_calc = chip->buffers.ecccalc;
	const uint8_t *p = buf;
	int *eccpos = chip->autooob->eccpos;
	int *eccpos = chip->ecc.layout->eccpos;

	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
		chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
@@ -2124,16 +2129,16 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
	/*
	 * If no default placement scheme is given, select an appropriate one
	 */
	if (!chip->autooob) {
	if (!chip->ecc.layout) {
		switch (mtd->oobsize) {
		case 8:
			chip->autooob = &nand_oob_8;
			chip->ecc.layout = &nand_oob_8;
			break;
		case 16:
			chip->autooob = &nand_oob_16;
			chip->ecc.layout = &nand_oob_16;
			break;
		case 64:
			chip->autooob = &nand_oob_64;
			chip->ecc.layout = &nand_oob_64;
			break;
		default:
			printk(KERN_WARNING "No oob scheme defined for "
@@ -2197,6 +2202,15 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
		BUG();
	}

	/*
	 * The number of bytes available for a client to place data into
	 * the out of band area
	 */
	chip->ecc.layout->oobavail = 0;
	for (i = 0; chip->ecc.layout->oobfree[i].length; i++)
		chip->ecc.layout->oobavail +=
			chip->ecc.layout->oobfree[i].length;

	/*
	 * Set the number of read / write steps for one page depending on ECC
	 * mode
@@ -2236,8 +2250,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
	mtd->block_isbad = nand_block_isbad;
	mtd->block_markbad = nand_block_markbad;

	/* and make the autooob the default one */
	mtd->oobinfo = chip->autooob;
	/* propagate ecc.layout to mtd_info */
	mtd->ecclayout = chip->ecc.layout;

	/* Check, if we should skip the bad block table scan */
	if (chip->options & NAND_SKIP_BBTSCAN)
Loading