diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-06 14:56:26 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-06 14:56:26 -0700 |
commit | 22ae77bc7ac115b9d518d5cbc13d39317079b2b0 (patch) | |
tree | 574b7af678c0b1ad2c891ac5066292746788ece8 /drivers/mtd/mtdconcat.c | |
parent | e379ec7c42343c6b6ef06a98de7c94db41c1423e (diff) | |
parent | 30bbf1406714cf464c56e96e4ad6a291907f5023 (diff) |
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (53 commits)
[MTD] struct device - replace bus_id with dev_name(), dev_set_name()
[MTD] [NOR] Fixup for Numonyx M29W128 chips
[MTD] mtdpart: Make ecc_stats more realistic.
powerpc/85xx: TQM8548: Update DTS file for multi-chip support
powerpc: NAND: FSL UPM: document new bindings
[MTD] [NAND] FSL-UPM: Add wait flags to support board/chip specific delays
[MTD] [NAND] FSL-UPM: add multi chip support
[MTD] [NOR] Add device parent info to physmap_of
[MTD] [NAND] Add support for NAND on the Socrates board
[MTD] [NAND] Add support for 4KiB pages.
[MTD] sysfs support should not depend on CONFIG_PROC_FS
[MTD] [NAND] Add parent info for CAFÉ controller
[MTD] support driver model updates
[MTD] driver model updates (part 2)
[MTD] driver model updates
[MTD] [NAND] move gen_nand's probe function to .devinit.text
[MTD] [MAPS] move sa1100 flash's probe function to .devinit.text
[MTD] fix use after free in register_mtd_blktrans
[MTD] [MAPS] Drop now unused sharpsl-flash map
[MTD] ofpart: Check name property to determine partition nodes.
...
Manually fix trivial conflict in drivers/mtd/maps/Makefile
Diffstat (limited to 'drivers/mtd/mtdconcat.c')
-rw-r--r-- | drivers/mtd/mtdconcat.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index 3dbb1b38db6..792b547786b 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c @@ -13,6 +13,7 @@ #include <linux/slab.h> #include <linux/sched.h> #include <linux/types.h> +#include <linux/backing-dev.h> #include <linux/mtd/mtd.h> #include <linux/mtd/concat.h> @@ -684,6 +685,40 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs) } /* + * 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 * stored to *new_dev upon success. This function does _not_ @@ -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: |