From b2e3a83da4f91c040da62e6ca1ef3c8f8ab15553 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 12 Feb 2009 10:40:05 +0000 Subject: [PATCH] --- yaml --- r: 142319 b: refs/heads/master c: 6e232cfce35a20a8702d9ac7709d35030c1b3271 h: refs/heads/master i: 142317: 045c472f5521da49f0d616cc88100d8e84c76ded 142315: 6ec693fbd7c5240ab7841d8c09c7807c08f4550b 142311: 0ba8eebc0d7d30d99c274c681817c9a166e27e1b 142303: ee8de63b68eb25cd4af9272a0cc99a162036e38e v: v3 --- [refs] | 2 +- trunk/drivers/mtd/mtdconcat.c | 47 +++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index a8e766fa736b..0267b84fe75f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 402d326519c1a4859c527702383f4e60f606ef52 +refs/heads/master: 6e232cfce35a20a8702d9ac7709d35030c1b3271 diff --git a/trunk/drivers/mtd/mtdconcat.c b/trunk/drivers/mtd/mtdconcat.c index 3dbb1b38db66..792b547786b8 100644 --- a/trunk/drivers/mtd/mtdconcat.c +++ b/trunk/drivers/mtd/mtdconcat.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -683,6 +684,40 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs) return err; } +/* + * try to support NOMMU mmaps on concatenated devices + * - we don't support subdev spanning as we can't guarantee it'll work + */ +static unsigned long concat_get_unmapped_area(struct mtd_info *mtd, + unsigned long len, + unsigned long offset, + unsigned long flags) +{ + struct mtd_concat *concat = CONCAT(mtd); + int i; + + for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; + + if (offset >= subdev->size) { + offset -= subdev->size; + continue; + } + + /* we've found the subdev over which the mapping will reside */ + if (offset + len > subdev->size) + return (unsigned long) -EINVAL; + + if (subdev->get_unmapped_area) + return subdev->get_unmapped_area(subdev, len, offset, + flags); + + break; + } + + return (unsigned long) -ENOSYS; +} + /* * This function constructs a virtual MTD device by concatenating * num_devs MTD devices. A pointer to the new device object is @@ -740,6 +775,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks; + concat->mtd.backing_dev_info = subdev[0]->backing_dev_info; + concat->subdev[0] = subdev[0]; for (i = 1; i < num_devs; i++) { @@ -766,6 +803,15 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->mtd.flags |= subdev[i]->flags & MTD_WRITEABLE; } + + /* only permit direct mapping if the BDIs are all the same + * - copy-mapping is still permitted + */ + if (concat->mtd.backing_dev_info != + subdev[i]->backing_dev_info) + concat->mtd.backing_dev_info = + &default_backing_dev_info; + concat->mtd.size += subdev[i]->size; concat->mtd.ecc_stats.badblocks += subdev[i]->ecc_stats.badblocks; @@ -796,6 +842,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->mtd.unlock = concat_unlock; concat->mtd.suspend = concat_suspend; concat->mtd.resume = concat_resume; + concat->mtd.get_unmapped_area = concat_get_unmapped_area; /* * Combine the erase block size info of the subdevices: