summaryrefslogtreecommitdiff
path: root/drivers/mtd/mtdconcat.c
diff options
context:
space:
mode:
authorSergey Lapin <slapin@ossfans.org>2013-01-14 03:46:50 +0000
committerScott Wood <scottwood@freescale.com>2013-05-31 17:12:03 -0500
commitdfe64e2c89731a3f9950d7acd8681b68df2bae03 (patch)
tree880eae93d5f4bd3e9747960eea71502c67e49d8e /drivers/mtd/mtdconcat.c
parenta1b81ab26fbbdcbaa6e2a096397c75415181c298 (diff)
downloadu-boot-imx-dfe64e2c89731a3f9950d7acd8681b68df2bae03.zip
u-boot-imx-dfe64e2c89731a3f9950d7acd8681b68df2bae03.tar.gz
u-boot-imx-dfe64e2c89731a3f9950d7acd8681b68df2bae03.tar.bz2
mtd: resync with Linux-3.7.1
This patch is essentially an update of u-boot MTD subsystem to the state of Linux-3.7.1 with exclusion of some bits: - the update is concentrated on NAND, no onenand or CFI/NOR/SPI flashes interfaces are updated EXCEPT for API changes. - new large NAND chips support is there, though some updates have got in Linux-3.8.-rc1, (which will follow on top of this patch). To produce this update I used tag v3.7.1 of linux-stable repository. The update was made using application of relevant patches, with changes relevant to U-Boot-only stuff sticked together to keep bisectability. Then all changes were grouped together to this patch. Signed-off-by: Sergey Lapin <slapin@ossfans.org> [scottwood@freescale.com: some eccstrength and build fixes] Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'drivers/mtd/mtdconcat.c')
-rw-r--r--drivers/mtd/mtdconcat.c98
1 files changed, 32 insertions, 66 deletions
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index e6d9384..31e4289 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -70,14 +70,14 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len,
/* Entire transaction goes into this subdev */
size = len;
- err = subdev->read(subdev, from, size, &retsize, buf);
+ err = mtd_read(subdev, from, size, &retsize, buf);
/* Save information about bitflips! */
if (unlikely(err)) {
- if (err == -EBADMSG) {
+ if (mtd_is_eccerr(err)) {
mtd->ecc_stats.failed++;
ret = err;
- } else if (err == -EUCLEAN) {
+ } else if (mtd_is_bitflip(err)) {
mtd->ecc_stats.corrected++;
/* Do not overwrite -EBADMSG !! */
if (!ret)
@@ -105,9 +105,6 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len,
int err = -EINVAL;
int i;
- if (!(mtd->flags & MTD_WRITEABLE))
- return -EROFS;
-
*retlen = 0;
for (i = 0; i < concat->num_subdev; i++) {
@@ -124,11 +121,7 @@ concat_write(struct mtd_info *mtd, loff_t to, size_t len,
else
size = len;
- if (!(subdev->flags & MTD_WRITEABLE))
- err = -EROFS;
- else
- err = subdev->write(subdev, to, size, &retsize, buf);
-
+ err = mtd_write(subdev, to, size, &retsize, buf);
if (err)
break;
@@ -165,16 +158,16 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
if (from + devops.len > subdev->size)
devops.len = subdev->size - from;
- err = subdev->read_oob(subdev, from, &devops);
+ err = mtd_read_oob(subdev, from, &devops);
ops->retlen += devops.retlen;
ops->oobretlen += devops.oobretlen;
/* Save information about bitflips! */
if (unlikely(err)) {
- if (err == -EBADMSG) {
+ if (mtd_is_eccerr(err)) {
mtd->ecc_stats.failed++;
ret = err;
- } else if (err == -EUCLEAN) {
+ } else if (mtd_is_bitflip(err)) {
mtd->ecc_stats.corrected++;
/* Do not overwrite -EBADMSG !! */
if (!ret)
@@ -225,7 +218,7 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
if (to + devops.len > subdev->size)
devops.len = subdev->size - to;
- err = subdev->write_oob(subdev, to, &devops);
+ err = mtd_write_oob(subdev, to, &devops);
ops->retlen += devops.retlen;
if (err)
return err;
@@ -271,7 +264,7 @@ static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
* FIXME: Allow INTERRUPTIBLE. Which means
* not having the wait_queue head on the stack.
*/
- err = mtd->erase(mtd, erase);
+ err = mtd_erase(mtd, erase);
if (!err) {
set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&waitq, &wait);
@@ -294,15 +287,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
uint64_t length, offset = 0;
struct erase_info *erase;
- if (!(mtd->flags & MTD_WRITEABLE))
- return -EROFS;
-
- if (instr->addr > concat->mtd.size)
- return -EINVAL;
-
- if (instr->len + instr->addr > concat->mtd.size)
- return -EINVAL;
-
/*
* Check for proper erase block alignment of the to-be-erased area.
* It is easier to do this based on the super device's erase
@@ -350,8 +334,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
return -EINVAL;
}
- instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
-
/* make a local copy of instr to avoid modifying the caller's struct */
erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL);
@@ -390,10 +372,6 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
else
erase->len = length;
- if (!(subdev->flags & MTD_WRITEABLE)) {
- err = -EROFS;
- break;
- }
length -= erase->len;
if ((err = concat_dev_erase(subdev, erase))) {
/* sanity check: should never happen since
@@ -429,9 +407,6 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
struct mtd_concat *concat = CONCAT(mtd);
int i, err = -EINVAL;
- if ((len + ofs) > mtd->size)
- return -EINVAL;
-
for (i = 0; i < concat->num_subdev; i++) {
struct mtd_info *subdev = concat->subdev[i];
uint64_t size;
@@ -446,7 +421,7 @@ static int concat_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
else
size = len;
- err = subdev->lock(subdev, ofs, size);
+ err = mtd_lock(subdev, ofs, size);
if (err)
break;
@@ -467,9 +442,6 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
struct mtd_concat *concat = CONCAT(mtd);
int i, err = 0;
- if ((len + ofs) > mtd->size)
- return -EINVAL;
-
for (i = 0; i < concat->num_subdev; i++) {
struct mtd_info *subdev = concat->subdev[i];
uint64_t size;
@@ -484,7 +456,7 @@ static int concat_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
else
size = len;
- err = subdev->unlock(subdev, ofs, size);
+ err = mtd_unlock(subdev, ofs, size);
if (err)
break;
@@ -507,7 +479,7 @@ static void concat_sync(struct mtd_info *mtd)
for (i = 0; i < concat->num_subdev; i++) {
struct mtd_info *subdev = concat->subdev[i];
- subdev->sync(subdev);
+ mtd_sync(subdev);
}
}
@@ -516,12 +488,9 @@ static int concat_block_isbad(struct mtd_info *mtd, loff_t ofs)
struct mtd_concat *concat = CONCAT(mtd);
int i, res = 0;
- if (!concat->subdev[0]->block_isbad)
+ if (!mtd_can_have_bb(concat->subdev[0]))
return res;
- if (ofs > mtd->size)
- return -EINVAL;
-
for (i = 0; i < concat->num_subdev; i++) {
struct mtd_info *subdev = concat->subdev[i];
@@ -530,7 +499,7 @@ static int concat_block_isbad(struct mtd_info *mtd, loff_t ofs)
continue;
}
- res = subdev->block_isbad(subdev, ofs);
+ res = mtd_block_isbad(subdev, ofs);
break;
}
@@ -542,12 +511,9 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
struct mtd_concat *concat = CONCAT(mtd);
int i, err = -EINVAL;
- if (!concat->subdev[0]->block_markbad)
+ if (!mtd_can_have_bb(concat->subdev[0]))
return 0;
- if (ofs > mtd->size)
- return -EINVAL;
-
for (i = 0; i < concat->num_subdev; i++) {
struct mtd_info *subdev = concat->subdev[i];
@@ -556,7 +522,7 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
continue;
}
- err = subdev->block_markbad(subdev, ofs);
+ err = mtd_block_markbad(subdev, ofs);
if (!err)
mtd->ecc_stats.badblocks++;
break;
@@ -609,14 +575,14 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat->mtd.subpage_sft = subdev[0]->subpage_sft;
concat->mtd.oobsize = subdev[0]->oobsize;
concat->mtd.oobavail = subdev[0]->oobavail;
- if (subdev[0]->read_oob)
- concat->mtd.read_oob = concat_read_oob;
- if (subdev[0]->write_oob)
- concat->mtd.write_oob = concat_write_oob;
- if (subdev[0]->block_isbad)
- concat->mtd.block_isbad = concat_block_isbad;
- if (subdev[0]->block_markbad)
- concat->mtd.block_markbad = concat_block_markbad;
+ if (subdev[0]->_read_oob)
+ concat->mtd._read_oob = concat_read_oob;
+ if (subdev[0]->_write_oob)
+ concat->mtd._write_oob = concat_write_oob;
+ if (subdev[0]->_block_isbad)
+ concat->mtd._block_isbad = concat_block_isbad;
+ if (subdev[0]->_block_markbad)
+ concat->mtd._block_markbad = concat_block_markbad;
concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks;
@@ -653,8 +619,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
if (concat->mtd.writesize != subdev[i]->writesize ||
concat->mtd.subpage_sft != subdev[i]->subpage_sft ||
concat->mtd.oobsize != subdev[i]->oobsize ||
- !concat->mtd.read_oob != !subdev[i]->read_oob ||
- !concat->mtd.write_oob != !subdev[i]->write_oob) {
+ !concat->mtd._read_oob != !subdev[i]->_read_oob ||
+ !concat->mtd._write_oob != !subdev[i]->_write_oob) {
kfree(concat);
printk("Incompatible OOB or ECC data on \"%s\"\n",
subdev[i]->name);
@@ -669,12 +635,12 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat->num_subdev = num_devs;
concat->mtd.name = name;
- concat->mtd.erase = concat_erase;
- concat->mtd.read = concat_read;
- concat->mtd.write = concat_write;
- concat->mtd.sync = concat_sync;
- concat->mtd.lock = concat_lock;
- concat->mtd.unlock = concat_unlock;
+ concat->mtd._erase = concat_erase;
+ concat->mtd._read = concat_read;
+ concat->mtd._write = concat_write;
+ concat->mtd._sync = concat_sync;
+ concat->mtd._lock = concat_lock;
+ concat->mtd._unlock = concat_unlock;
/*
* Combine the erase block size info of the subdevices: