diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-03-08 19:30:55 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2009-03-08 19:30:55 -0400 |
commit | d15c22e78674f9a5bc0de0932a43abe1aafae303 (patch) | |
tree | 3e4198c44bd2d9184e91647346c66aa95e28f843 /drivers/mtd | |
parent | 0f4954819fb6f840d46076f0dbd313ef5da48f5d (diff) | |
parent | fec6c6fec3e20637bee5d276fb61dd8b49a3f9cc (diff) |
Merge commit 'v2.6.29-rc7' into next
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/chips/map_rom.c | 8 | ||||
-rw-r--r-- | drivers/mtd/devices/slram.c | 14 | ||||
-rw-r--r-- | drivers/mtd/lpddr/Kconfig | 1 | ||||
-rw-r--r-- | drivers/mtd/maps/Kconfig | 2 | ||||
-rw-r--r-- | drivers/mtd/maps/bfin-async-flash.c | 6 | ||||
-rw-r--r-- | drivers/mtd/maps/ck804xrom.c | 2 | ||||
-rw-r--r-- | drivers/mtd/maps/physmap.c | 38 | ||||
-rw-r--r-- | drivers/mtd/maps/sa1100-flash.c | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 3 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_elbc_nand.c | 8 | ||||
-rw-r--r-- | drivers/mtd/nand/orion_nand.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/pasemi_nand.c | 4 | ||||
-rw-r--r-- | drivers/mtd/onenand/omap2.c | 6 | ||||
-rw-r--r-- | drivers/mtd/ubi/Kconfig.debug | 10 | ||||
-rw-r--r-- | drivers/mtd/ubi/build.c | 21 | ||||
-rw-r--r-- | drivers/mtd/ubi/cdev.c | 184 | ||||
-rw-r--r-- | drivers/mtd/ubi/gluebi.c | 11 | ||||
-rw-r--r-- | drivers/mtd/ubi/scan.c | 8 | ||||
-rw-r--r-- | drivers/mtd/ubi/ubi.h | 11 | ||||
-rw-r--r-- | drivers/mtd/ubi/upd.c | 21 | ||||
-rw-r--r-- | drivers/mtd/ubi/vmt.c | 17 |
21 files changed, 233 insertions, 148 deletions
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c index 821d0ed6bae3..c76d6e5f47ee 100644 --- a/drivers/mtd/chips/map_rom.c +++ b/drivers/mtd/chips/map_rom.c | |||
@@ -19,6 +19,7 @@ static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | |||
19 | static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | 19 | static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *); |
20 | static void maprom_nop (struct mtd_info *); | 20 | static void maprom_nop (struct mtd_info *); |
21 | static struct mtd_info *map_rom_probe(struct map_info *map); | 21 | static struct mtd_info *map_rom_probe(struct map_info *map); |
22 | static int maprom_erase (struct mtd_info *mtd, struct erase_info *info); | ||
22 | 23 | ||
23 | static struct mtd_chip_driver maprom_chipdrv = { | 24 | static struct mtd_chip_driver maprom_chipdrv = { |
24 | .probe = map_rom_probe, | 25 | .probe = map_rom_probe, |
@@ -42,6 +43,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map) | |||
42 | mtd->read = maprom_read; | 43 | mtd->read = maprom_read; |
43 | mtd->write = maprom_write; | 44 | mtd->write = maprom_write; |
44 | mtd->sync = maprom_nop; | 45 | mtd->sync = maprom_nop; |
46 | mtd->erase = maprom_erase; | ||
45 | mtd->flags = MTD_CAP_ROM; | 47 | mtd->flags = MTD_CAP_ROM; |
46 | mtd->erasesize = map->size; | 48 | mtd->erasesize = map->size; |
47 | mtd->writesize = 1; | 49 | mtd->writesize = 1; |
@@ -71,6 +73,12 @@ static int maprom_write (struct mtd_info *mtd, loff_t to, size_t len, size_t *re | |||
71 | return -EIO; | 73 | return -EIO; |
72 | } | 74 | } |
73 | 75 | ||
76 | static int maprom_erase (struct mtd_info *mtd, struct erase_info *info) | ||
77 | { | ||
78 | /* We do our best 8) */ | ||
79 | return -EROFS; | ||
80 | } | ||
81 | |||
74 | static int __init map_rom_init(void) | 82 | static int __init map_rom_init(void) |
75 | { | 83 | { |
76 | register_mtd_chip_driver(&maprom_chipdrv); | 84 | register_mtd_chip_driver(&maprom_chipdrv); |
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index a425d09f35a0..00248e81ecd5 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c | |||
@@ -267,22 +267,28 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength) | |||
267 | if (*(szlength) != '+') { | 267 | if (*(szlength) != '+') { |
268 | devlength = simple_strtoul(szlength, &buffer, 0); | 268 | devlength = simple_strtoul(szlength, &buffer, 0); |
269 | devlength = handle_unit(devlength, buffer) - devstart; | 269 | devlength = handle_unit(devlength, buffer) - devstart; |
270 | if (devlength < devstart) | ||
271 | goto err_out; | ||
272 | |||
273 | devlength -= devstart; | ||
270 | } else { | 274 | } else { |
271 | devlength = simple_strtoul(szlength + 1, &buffer, 0); | 275 | devlength = simple_strtoul(szlength + 1, &buffer, 0); |
272 | devlength = handle_unit(devlength, buffer); | 276 | devlength = handle_unit(devlength, buffer); |
273 | } | 277 | } |
274 | T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", | 278 | T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", |
275 | devname, devstart, devlength); | 279 | devname, devstart, devlength); |
276 | if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) { | 280 | if (devlength % SLRAM_BLK_SZ != 0) |
277 | E("slram: Illegal start / length parameter.\n"); | 281 | goto err_out; |
278 | return(-EINVAL); | ||
279 | } | ||
280 | 282 | ||
281 | if ((devstart = register_device(devname, devstart, devlength))){ | 283 | if ((devstart = register_device(devname, devstart, devlength))){ |
282 | unregister_devices(); | 284 | unregister_devices(); |
283 | return((int)devstart); | 285 | return((int)devstart); |
284 | } | 286 | } |
285 | return(0); | 287 | return(0); |
288 | |||
289 | err_out: | ||
290 | E("slram: Illegal length parameter.\n"); | ||
291 | return(-EINVAL); | ||
286 | } | 292 | } |
287 | 293 | ||
288 | #ifndef MODULE | 294 | #ifndef MODULE |
diff --git a/drivers/mtd/lpddr/Kconfig b/drivers/mtd/lpddr/Kconfig index acd4ea9b2278..5a401d8047ab 100644 --- a/drivers/mtd/lpddr/Kconfig +++ b/drivers/mtd/lpddr/Kconfig | |||
@@ -12,6 +12,7 @@ config MTD_LPDDR | |||
12 | DDR memories, intended for battery-operated systems. | 12 | DDR memories, intended for battery-operated systems. |
13 | 13 | ||
14 | config MTD_QINFO_PROBE | 14 | config MTD_QINFO_PROBE |
15 | depends on MTD_LPDDR | ||
15 | tristate "Detect flash chips by QINFO probe" | 16 | tristate "Detect flash chips by QINFO probe" |
16 | help | 17 | help |
17 | Device Information for LPDDR chips is offered through the Overlay | 18 | Device Information for LPDDR chips is offered through the Overlay |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 0225cbbf22de..043d50fb6ef6 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -491,7 +491,7 @@ config MTD_PCMCIA_ANONYMOUS | |||
491 | 491 | ||
492 | config MTD_BFIN_ASYNC | 492 | config MTD_BFIN_ASYNC |
493 | tristate "Blackfin BF533-STAMP Flash Chip Support" | 493 | tristate "Blackfin BF533-STAMP Flash Chip Support" |
494 | depends on BFIN533_STAMP && MTD_CFI | 494 | depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS |
495 | select MTD_PARTITIONS | 495 | select MTD_PARTITIONS |
496 | default y | 496 | default y |
497 | help | 497 | help |
diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c index 6fec86aaed7e..576611f605db 100644 --- a/drivers/mtd/maps/bfin-async-flash.c +++ b/drivers/mtd/maps/bfin-async-flash.c | |||
@@ -152,14 +152,18 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev) | |||
152 | 152 | ||
153 | if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) { | 153 | if (gpio_request(state->enet_flash_pin, DRIVER_NAME)) { |
154 | pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin); | 154 | pr_devinit(KERN_ERR DRIVER_NAME ": Failed to request gpio %d\n", state->enet_flash_pin); |
155 | kfree(state); | ||
155 | return -EBUSY; | 156 | return -EBUSY; |
156 | } | 157 | } |
157 | gpio_direction_output(state->enet_flash_pin, 1); | 158 | gpio_direction_output(state->enet_flash_pin, 1); |
158 | 159 | ||
159 | pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8); | 160 | pr_devinit(KERN_NOTICE DRIVER_NAME ": probing %d-bit flash bus\n", state->map.bankwidth * 8); |
160 | state->mtd = do_map_probe(memory->name, &state->map); | 161 | state->mtd = do_map_probe(memory->name, &state->map); |
161 | if (!state->mtd) | 162 | if (!state->mtd) { |
163 | gpio_free(state->enet_flash_pin); | ||
164 | kfree(state); | ||
162 | return -ENXIO; | 165 | return -ENXIO; |
166 | } | ||
163 | 167 | ||
164 | #ifdef CONFIG_MTD_PARTITIONS | 168 | #ifdef CONFIG_MTD_PARTITIONS |
165 | ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); | 169 | ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0); |
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index 5f7a245ed132..424f17d6ffd1 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c | |||
@@ -342,9 +342,9 @@ static struct pci_device_id ck804xrom_pci_tbl[] = { | |||
342 | { 0, } | 342 | { 0, } |
343 | }; | 343 | }; |
344 | 344 | ||
345 | #if 0 | ||
345 | MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl); | 346 | MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl); |
346 | 347 | ||
347 | #if 0 | ||
348 | static struct pci_driver ck804xrom_driver = { | 348 | static struct pci_driver ck804xrom_driver = { |
349 | .name = MOD_NAME, | 349 | .name = MOD_NAME, |
350 | .id_table = ck804xrom_pci_tbl, | 350 | .id_table = ck804xrom_pci_tbl, |
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 87743661d48e..4b122e7ab4b3 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c | |||
@@ -29,6 +29,7 @@ struct physmap_flash_info { | |||
29 | struct map_info map[MAX_RESOURCES]; | 29 | struct map_info map[MAX_RESOURCES]; |
30 | #ifdef CONFIG_MTD_PARTITIONS | 30 | #ifdef CONFIG_MTD_PARTITIONS |
31 | int nr_parts; | 31 | int nr_parts; |
32 | struct mtd_partition *parts; | ||
32 | #endif | 33 | #endif |
33 | }; | 34 | }; |
34 | 35 | ||
@@ -45,25 +46,26 @@ static int physmap_flash_remove(struct platform_device *dev) | |||
45 | 46 | ||
46 | physmap_data = dev->dev.platform_data; | 47 | physmap_data = dev->dev.platform_data; |
47 | 48 | ||
48 | #ifdef CONFIG_MTD_CONCAT | 49 | #ifdef CONFIG_MTD_PARTITIONS |
49 | if (info->cmtd != info->mtd[0]) { | 50 | if (info->nr_parts) { |
51 | del_mtd_partitions(info->cmtd); | ||
52 | kfree(info->parts); | ||
53 | } else if (physmap_data->nr_parts) | ||
54 | del_mtd_partitions(info->cmtd); | ||
55 | else | ||
50 | del_mtd_device(info->cmtd); | 56 | del_mtd_device(info->cmtd); |
57 | #else | ||
58 | del_mtd_device(info->cmtd); | ||
59 | #endif | ||
60 | |||
61 | #ifdef CONFIG_MTD_CONCAT | ||
62 | if (info->cmtd != info->mtd[0]) | ||
51 | mtd_concat_destroy(info->cmtd); | 63 | mtd_concat_destroy(info->cmtd); |
52 | } | ||
53 | #endif | 64 | #endif |
54 | 65 | ||
55 | for (i = 0; i < MAX_RESOURCES; i++) { | 66 | for (i = 0; i < MAX_RESOURCES; i++) { |
56 | if (info->mtd[i] != NULL) { | 67 | if (info->mtd[i] != NULL) |
57 | #ifdef CONFIG_MTD_PARTITIONS | ||
58 | if (info->nr_parts || physmap_data->nr_parts) | ||
59 | del_mtd_partitions(info->mtd[i]); | ||
60 | else | ||
61 | del_mtd_device(info->mtd[i]); | ||
62 | #else | ||
63 | del_mtd_device(info->mtd[i]); | ||
64 | #endif | ||
65 | map_destroy(info->mtd[i]); | 68 | map_destroy(info->mtd[i]); |
66 | } | ||
67 | } | 69 | } |
68 | return 0; | 70 | return 0; |
69 | } | 71 | } |
@@ -86,9 +88,6 @@ static int physmap_flash_probe(struct platform_device *dev) | |||
86 | int err = 0; | 88 | int err = 0; |
87 | int i; | 89 | int i; |
88 | int devices_found = 0; | 90 | int devices_found = 0; |
89 | #ifdef CONFIG_MTD_PARTITIONS | ||
90 | struct mtd_partition *parts; | ||
91 | #endif | ||
92 | 91 | ||
93 | physmap_data = dev->dev.platform_data; | 92 | physmap_data = dev->dev.platform_data; |
94 | if (physmap_data == NULL) | 93 | if (physmap_data == NULL) |
@@ -167,10 +166,11 @@ static int physmap_flash_probe(struct platform_device *dev) | |||
167 | goto err_out; | 166 | goto err_out; |
168 | 167 | ||
169 | #ifdef CONFIG_MTD_PARTITIONS | 168 | #ifdef CONFIG_MTD_PARTITIONS |
170 | err = parse_mtd_partitions(info->cmtd, part_probe_types, &parts, 0); | 169 | err = parse_mtd_partitions(info->cmtd, part_probe_types, |
170 | &info->parts, 0); | ||
171 | if (err > 0) { | 171 | if (err > 0) { |
172 | add_mtd_partitions(info->cmtd, parts, err); | 172 | add_mtd_partitions(info->cmtd, info->parts, err); |
173 | kfree(parts); | 173 | info->nr_parts = err; |
174 | return 0; | 174 | return 0; |
175 | } | 175 | } |
176 | 176 | ||
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 7df6bbf0e4d9..6f6a0f6dafd6 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c | |||
@@ -453,7 +453,7 @@ static struct platform_driver sa1100_mtd_driver = { | |||
453 | .resume = sa1100_mtd_resume, | 453 | .resume = sa1100_mtd_resume, |
454 | .shutdown = sa1100_mtd_shutdown, | 454 | .shutdown = sa1100_mtd_shutdown, |
455 | .driver = { | 455 | .driver = { |
456 | .name = "flash", | 456 | .name = "sa1100-mtd", |
457 | .owner = THIS_MODULE, | 457 | .owner = THIS_MODULE, |
458 | }, | 458 | }, |
459 | }; | 459 | }; |
@@ -474,4 +474,4 @@ module_exit(sa1100_mtd_exit); | |||
474 | MODULE_AUTHOR("Nicolas Pitre"); | 474 | MODULE_AUTHOR("Nicolas Pitre"); |
475 | MODULE_DESCRIPTION("SA1100 CFI map driver"); | 475 | MODULE_DESCRIPTION("SA1100 CFI map driver"); |
476 | MODULE_LICENSE("GPL"); | 476 | MODULE_LICENSE("GPL"); |
477 | MODULE_ALIAS("platform:flash"); | 477 | MODULE_ALIAS("platform:sa1100-mtd"); |
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index c98c1570a40b..47a33cec3793 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -139,7 +139,8 @@ static int atmel_nand_device_ready(struct mtd_info *mtd) | |||
139 | struct nand_chip *nand_chip = mtd->priv; | 139 | struct nand_chip *nand_chip = mtd->priv; |
140 | struct atmel_nand_host *host = nand_chip->priv; | 140 | struct atmel_nand_host *host = nand_chip->priv; |
141 | 141 | ||
142 | return gpio_get_value(host->board->rdy_pin); | 142 | return gpio_get_value(host->board->rdy_pin) ^ |
143 | !!host->board->rdy_pin_active_low; | ||
143 | } | 144 | } |
144 | 145 | ||
145 | /* | 146 | /* |
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 65929db29446..1f6eb2578717 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c | |||
@@ -676,7 +676,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) | |||
676 | 676 | ||
677 | dev_dbg(ctrl->dev, "fsl_elbc_init: nand->numchips = %d\n", | 677 | dev_dbg(ctrl->dev, "fsl_elbc_init: nand->numchips = %d\n", |
678 | chip->numchips); | 678 | chip->numchips); |
679 | dev_dbg(ctrl->dev, "fsl_elbc_init: nand->chipsize = %ld\n", | 679 | dev_dbg(ctrl->dev, "fsl_elbc_init: nand->chipsize = %lld\n", |
680 | chip->chipsize); | 680 | chip->chipsize); |
681 | dev_dbg(ctrl->dev, "fsl_elbc_init: nand->pagemask = %8x\n", | 681 | dev_dbg(ctrl->dev, "fsl_elbc_init: nand->pagemask = %8x\n", |
682 | chip->pagemask); | 682 | chip->pagemask); |
@@ -703,7 +703,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) | |||
703 | dev_dbg(ctrl->dev, "fsl_elbc_init: nand->ecc.layout = %p\n", | 703 | dev_dbg(ctrl->dev, "fsl_elbc_init: nand->ecc.layout = %p\n", |
704 | chip->ecc.layout); | 704 | chip->ecc.layout); |
705 | dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags); | 705 | dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags); |
706 | dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->size = %d\n", mtd->size); | 706 | dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->size = %lld\n", mtd->size); |
707 | dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->erasesize = %d\n", | 707 | dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->erasesize = %d\n", |
708 | mtd->erasesize); | 708 | mtd->erasesize); |
709 | dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->writesize = %d\n", | 709 | dev_dbg(ctrl->dev, "fsl_elbc_init: mtd->writesize = %d\n", |
@@ -932,8 +932,8 @@ static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl, | |||
932 | #endif | 932 | #endif |
933 | add_mtd_device(&priv->mtd); | 933 | add_mtd_device(&priv->mtd); |
934 | 934 | ||
935 | printk(KERN_INFO "eLBC NAND device at 0x%zx, bank %d\n", | 935 | printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n", |
936 | res.start, priv->bank); | 936 | (unsigned long long)res.start, priv->bank); |
937 | return 0; | 937 | return 0; |
938 | 938 | ||
939 | err: | 939 | err: |
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 917cf8d3ae95..c2dfd3ea353d 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c | |||
@@ -149,7 +149,7 @@ static int __devexit orion_nand_remove(struct platform_device *pdev) | |||
149 | 149 | ||
150 | static struct platform_driver orion_nand_driver = { | 150 | static struct platform_driver orion_nand_driver = { |
151 | .probe = orion_nand_probe, | 151 | .probe = orion_nand_probe, |
152 | .remove = orion_nand_remove, | 152 | .remove = __devexit_p(orion_nand_remove), |
153 | .driver = { | 153 | .driver = { |
154 | .name = "orion_nand", | 154 | .name = "orion_nand", |
155 | .owner = THIS_MODULE, | 155 | .owner = THIS_MODULE, |
diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 9bd6c9ac8443..a8b9376cf324 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c | |||
@@ -107,7 +107,7 @@ static int __devinit pasemi_nand_probe(struct of_device *ofdev, | |||
107 | if (pasemi_nand_mtd) | 107 | if (pasemi_nand_mtd) |
108 | return -ENODEV; | 108 | return -ENODEV; |
109 | 109 | ||
110 | pr_debug("pasemi_nand at %lx-%lx\n", res.start, res.end); | 110 | pr_debug("pasemi_nand at %llx-%llx\n", res.start, res.end); |
111 | 111 | ||
112 | /* Allocate memory for MTD device structure and private data */ | 112 | /* Allocate memory for MTD device structure and private data */ |
113 | pasemi_nand_mtd = kzalloc(sizeof(struct mtd_info) + | 113 | pasemi_nand_mtd = kzalloc(sizeof(struct mtd_info) + |
@@ -170,7 +170,7 @@ static int __devinit pasemi_nand_probe(struct of_device *ofdev, | |||
170 | goto out_lpc; | 170 | goto out_lpc; |
171 | } | 171 | } |
172 | 172 | ||
173 | printk(KERN_INFO "PA Semi NAND flash at %08lx, control at I/O %x\n", | 173 | printk(KERN_INFO "PA Semi NAND flash at %08llx, control at I/O %x\n", |
174 | res.start, lpcctl); | 174 | res.start, lpcctl); |
175 | 175 | ||
176 | return 0; | 176 | return 0; |
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 96ecc1766fa8..77a4f1446156 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c | |||
@@ -629,7 +629,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev) | |||
629 | } | 629 | } |
630 | 630 | ||
631 | if (c->gpio_irq) { | 631 | if (c->gpio_irq) { |
632 | if ((r = omap_request_gpio(c->gpio_irq)) < 0) { | 632 | if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) { |
633 | dev_err(&pdev->dev, "Failed to request GPIO%d for " | 633 | dev_err(&pdev->dev, "Failed to request GPIO%d for " |
634 | "OneNAND\n", c->gpio_irq); | 634 | "OneNAND\n", c->gpio_irq); |
635 | goto err_iounmap; | 635 | goto err_iounmap; |
@@ -726,7 +726,7 @@ err_release_dma: | |||
726 | free_irq(gpio_to_irq(c->gpio_irq), c); | 726 | free_irq(gpio_to_irq(c->gpio_irq), c); |
727 | err_release_gpio: | 727 | err_release_gpio: |
728 | if (c->gpio_irq) | 728 | if (c->gpio_irq) |
729 | omap_free_gpio(c->gpio_irq); | 729 | gpio_free(c->gpio_irq); |
730 | err_iounmap: | 730 | err_iounmap: |
731 | iounmap(c->onenand.base); | 731 | iounmap(c->onenand.base); |
732 | err_release_mem_region: | 732 | err_release_mem_region: |
@@ -761,7 +761,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev) | |||
761 | platform_set_drvdata(pdev, NULL); | 761 | platform_set_drvdata(pdev, NULL); |
762 | if (c->gpio_irq) { | 762 | if (c->gpio_irq) { |
763 | free_irq(gpio_to_irq(c->gpio_irq), c); | 763 | free_irq(gpio_to_irq(c->gpio_irq), c); |
764 | omap_free_gpio(c->gpio_irq); | 764 | gpio_free(c->gpio_irq); |
765 | } | 765 | } |
766 | iounmap(c->onenand.base); | 766 | iounmap(c->onenand.base); |
767 | release_mem_region(c->phys_base, ONENAND_IO_SIZE); | 767 | release_mem_region(c->phys_base, ONENAND_IO_SIZE); |
diff --git a/drivers/mtd/ubi/Kconfig.debug b/drivers/mtd/ubi/Kconfig.debug index 1e2ee22edeff..2246f154e2f7 100644 --- a/drivers/mtd/ubi/Kconfig.debug +++ b/drivers/mtd/ubi/Kconfig.debug | |||
@@ -33,16 +33,6 @@ config MTD_UBI_DEBUG_DISABLE_BGT | |||
33 | This option switches the background thread off by default. The thread | 33 | This option switches the background thread off by default. The thread |
34 | may be also be enabled/disabled via UBI sysfs. | 34 | may be also be enabled/disabled via UBI sysfs. |
35 | 35 | ||
36 | config MTD_UBI_DEBUG_USERSPACE_IO | ||
37 | bool "Direct user-space write/erase support" | ||
38 | default n | ||
39 | depends on MTD_UBI_DEBUG | ||
40 | help | ||
41 | By default, users cannot directly write and erase individual | ||
42 | eraseblocks of dynamic volumes, and have to use update operation | ||
43 | instead. This option enables this capability - it is very useful for | ||
44 | debugging and testing. | ||
45 | |||
46 | config MTD_UBI_DEBUG_EMULATE_BITFLIPS | 36 | config MTD_UBI_DEBUG_EMULATE_BITFLIPS |
47 | bool "Emulate flash bit-flips" | 37 | bool "Emulate flash bit-flips" |
48 | depends on MTD_UBI_DEBUG | 38 | depends on MTD_UBI_DEBUG |
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 9082768cc6c3..4048db83aef6 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -263,8 +263,12 @@ static ssize_t dev_attribute_show(struct device *dev, | |||
263 | return ret; | 263 | return ret; |
264 | } | 264 | } |
265 | 265 | ||
266 | /* Fake "release" method for UBI devices */ | 266 | static void dev_release(struct device *dev) |
267 | static void dev_release(struct device *dev) { } | 267 | { |
268 | struct ubi_device *ubi = container_of(dev, struct ubi_device, dev); | ||
269 | |||
270 | kfree(ubi); | ||
271 | } | ||
268 | 272 | ||
269 | /** | 273 | /** |
270 | * ubi_sysfs_init - initialize sysfs for an UBI device. | 274 | * ubi_sysfs_init - initialize sysfs for an UBI device. |
@@ -380,7 +384,7 @@ static void free_user_volumes(struct ubi_device *ubi) | |||
380 | */ | 384 | */ |
381 | static int uif_init(struct ubi_device *ubi) | 385 | static int uif_init(struct ubi_device *ubi) |
382 | { | 386 | { |
383 | int i, err, do_free = 0; | 387 | int i, err; |
384 | dev_t dev; | 388 | dev_t dev; |
385 | 389 | ||
386 | sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); | 390 | sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); |
@@ -427,13 +431,10 @@ static int uif_init(struct ubi_device *ubi) | |||
427 | 431 | ||
428 | out_volumes: | 432 | out_volumes: |
429 | kill_volumes(ubi); | 433 | kill_volumes(ubi); |
430 | do_free = 0; | ||
431 | out_sysfs: | 434 | out_sysfs: |
432 | ubi_sysfs_close(ubi); | 435 | ubi_sysfs_close(ubi); |
433 | cdev_del(&ubi->cdev); | 436 | cdev_del(&ubi->cdev); |
434 | out_unreg: | 437 | out_unreg: |
435 | if (do_free) | ||
436 | free_user_volumes(ubi); | ||
437 | unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); | 438 | unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); |
438 | ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err); | 439 | ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err); |
439 | return err; | 440 | return err; |
@@ -947,6 +948,12 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) | |||
947 | if (ubi->bgt_thread) | 948 | if (ubi->bgt_thread) |
948 | kthread_stop(ubi->bgt_thread); | 949 | kthread_stop(ubi->bgt_thread); |
949 | 950 | ||
951 | /* | ||
952 | * Get a reference to the device in order to prevent 'dev_release()' | ||
953 | * from freeing @ubi object. | ||
954 | */ | ||
955 | get_device(&ubi->dev); | ||
956 | |||
950 | uif_close(ubi); | 957 | uif_close(ubi); |
951 | ubi_wl_close(ubi); | 958 | ubi_wl_close(ubi); |
952 | free_internal_volumes(ubi); | 959 | free_internal_volumes(ubi); |
@@ -958,7 +965,7 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) | |||
958 | vfree(ubi->dbg_peb_buf); | 965 | vfree(ubi->dbg_peb_buf); |
959 | #endif | 966 | #endif |
960 | ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); | 967 | ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num); |
961 | kfree(ubi); | 968 | put_device(&ubi->dev); |
962 | return 0; | 969 | return 0; |
963 | } | 970 | } |
964 | 971 | ||
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index 98cf31ed0814..e63c8fc3df3a 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
@@ -40,9 +40,9 @@ | |||
40 | #include <linux/ioctl.h> | 40 | #include <linux/ioctl.h> |
41 | #include <linux/capability.h> | 41 | #include <linux/capability.h> |
42 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
43 | #include <linux/smp_lock.h> | 43 | #include <linux/compat.h> |
44 | #include <linux/math64.h> | ||
44 | #include <mtd/ubi-user.h> | 45 | #include <mtd/ubi-user.h> |
45 | #include <asm/div64.h> | ||
46 | #include "ubi.h" | 46 | #include "ubi.h" |
47 | 47 | ||
48 | /** | 48 | /** |
@@ -195,7 +195,6 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, | |||
195 | int err, lnum, off, len, tbuf_size; | 195 | int err, lnum, off, len, tbuf_size; |
196 | size_t count_save = count; | 196 | size_t count_save = count; |
197 | void *tbuf; | 197 | void *tbuf; |
198 | uint64_t tmp; | ||
199 | 198 | ||
200 | dbg_gen("read %zd bytes from offset %lld of volume %d", | 199 | dbg_gen("read %zd bytes from offset %lld of volume %d", |
201 | count, *offp, vol->vol_id); | 200 | count, *offp, vol->vol_id); |
@@ -225,10 +224,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, | |||
225 | return -ENOMEM; | 224 | return -ENOMEM; |
226 | 225 | ||
227 | len = count > tbuf_size ? tbuf_size : count; | 226 | len = count > tbuf_size ? tbuf_size : count; |
228 | 227 | lnum = div_u64_rem(*offp, vol->usable_leb_size, &off); | |
229 | tmp = *offp; | ||
230 | off = do_div(tmp, vol->usable_leb_size); | ||
231 | lnum = tmp; | ||
232 | 228 | ||
233 | do { | 229 | do { |
234 | cond_resched(); | 230 | cond_resched(); |
@@ -263,12 +259,9 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, | |||
263 | return err ? err : count_save - count; | 259 | return err ? err : count_save - count; |
264 | } | 260 | } |
265 | 261 | ||
266 | #ifdef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO | ||
267 | |||
268 | /* | 262 | /* |
269 | * This function allows to directly write to dynamic UBI volumes, without | 263 | * This function allows to directly write to dynamic UBI volumes, without |
270 | * issuing the volume update operation. Available only as a debugging feature. | 264 | * issuing the volume update operation. |
271 | * Very useful for testing UBI. | ||
272 | */ | 265 | */ |
273 | static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, | 266 | static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, |
274 | size_t count, loff_t *offp) | 267 | size_t count, loff_t *offp) |
@@ -279,7 +272,9 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, | |||
279 | int lnum, off, len, tbuf_size, err = 0; | 272 | int lnum, off, len, tbuf_size, err = 0; |
280 | size_t count_save = count; | 273 | size_t count_save = count; |
281 | char *tbuf; | 274 | char *tbuf; |
282 | uint64_t tmp; | 275 | |
276 | if (!vol->direct_writes) | ||
277 | return -EPERM; | ||
283 | 278 | ||
284 | dbg_gen("requested: write %zd bytes to offset %lld of volume %u", | 279 | dbg_gen("requested: write %zd bytes to offset %lld of volume %u", |
285 | count, *offp, vol->vol_id); | 280 | count, *offp, vol->vol_id); |
@@ -287,10 +282,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, | |||
287 | if (vol->vol_type == UBI_STATIC_VOLUME) | 282 | if (vol->vol_type == UBI_STATIC_VOLUME) |
288 | return -EROFS; | 283 | return -EROFS; |
289 | 284 | ||
290 | tmp = *offp; | 285 | lnum = div_u64_rem(*offp, vol->usable_leb_size, &off); |
291 | off = do_div(tmp, vol->usable_leb_size); | ||
292 | lnum = tmp; | ||
293 | |||
294 | if (off & (ubi->min_io_size - 1)) { | 286 | if (off & (ubi->min_io_size - 1)) { |
295 | dbg_err("unaligned position"); | 287 | dbg_err("unaligned position"); |
296 | return -EINVAL; | 288 | return -EINVAL; |
@@ -347,10 +339,6 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, | |||
347 | return err ? err : count_save - count; | 339 | return err ? err : count_save - count; |
348 | } | 340 | } |
349 | 341 | ||
350 | #else | ||
351 | #define vol_cdev_direct_write(file, buf, count, offp) (-EPERM) | ||
352 | #endif /* CONFIG_MTD_UBI_DEBUG_USERSPACE_IO */ | ||
353 | |||
354 | static ssize_t vol_cdev_write(struct file *file, const char __user *buf, | 342 | static ssize_t vol_cdev_write(struct file *file, const char __user *buf, |
355 | size_t count, loff_t *offp) | 343 | size_t count, loff_t *offp) |
356 | { | 344 | { |
@@ -402,8 +390,8 @@ static ssize_t vol_cdev_write(struct file *file, const char __user *buf, | |||
402 | return count; | 390 | return count; |
403 | } | 391 | } |
404 | 392 | ||
405 | static int vol_cdev_ioctl(struct inode *inode, struct file *file, | 393 | static long vol_cdev_ioctl(struct file *file, unsigned int cmd, |
406 | unsigned int cmd, unsigned long arg) | 394 | unsigned long arg) |
407 | { | 395 | { |
408 | int err = 0; | 396 | int err = 0; |
409 | struct ubi_volume_desc *desc = file->private_data; | 397 | struct ubi_volume_desc *desc = file->private_data; |
@@ -487,7 +475,6 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, | |||
487 | break; | 475 | break; |
488 | } | 476 | } |
489 | 477 | ||
490 | #ifdef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO | ||
491 | /* Logical eraseblock erasure command */ | 478 | /* Logical eraseblock erasure command */ |
492 | case UBI_IOCEBER: | 479 | case UBI_IOCEBER: |
493 | { | 480 | { |
@@ -518,13 +505,77 @@ static int vol_cdev_ioctl(struct inode *inode, struct file *file, | |||
518 | err = ubi_wl_flush(ubi); | 505 | err = ubi_wl_flush(ubi); |
519 | break; | 506 | break; |
520 | } | 507 | } |
521 | #endif | 508 | |
509 | /* Logical eraseblock map command */ | ||
510 | case UBI_IOCEBMAP: | ||
511 | { | ||
512 | struct ubi_map_req req; | ||
513 | |||
514 | err = copy_from_user(&req, argp, sizeof(struct ubi_map_req)); | ||
515 | if (err) { | ||
516 | err = -EFAULT; | ||
517 | break; | ||
518 | } | ||
519 | err = ubi_leb_map(desc, req.lnum, req.dtype); | ||
520 | break; | ||
521 | } | ||
522 | |||
523 | /* Logical eraseblock un-map command */ | ||
524 | case UBI_IOCEBUNMAP: | ||
525 | { | ||
526 | int32_t lnum; | ||
527 | |||
528 | err = get_user(lnum, (__user int32_t *)argp); | ||
529 | if (err) { | ||
530 | err = -EFAULT; | ||
531 | break; | ||
532 | } | ||
533 | err = ubi_leb_unmap(desc, lnum); | ||
534 | break; | ||
535 | } | ||
536 | |||
537 | /* Check if logical eraseblock is mapped command */ | ||
538 | case UBI_IOCEBISMAP: | ||
539 | { | ||
540 | int32_t lnum; | ||
541 | |||
542 | err = get_user(lnum, (__user int32_t *)argp); | ||
543 | if (err) { | ||
544 | err = -EFAULT; | ||
545 | break; | ||
546 | } | ||
547 | err = ubi_is_mapped(desc, lnum); | ||
548 | break; | ||
549 | } | ||
550 | |||
551 | /* Set volume property command*/ | ||
552 | case UBI_IOCSETPROP: | ||
553 | { | ||
554 | struct ubi_set_prop_req req; | ||
555 | |||
556 | err = copy_from_user(&req, argp, | ||
557 | sizeof(struct ubi_set_prop_req)); | ||
558 | if (err) { | ||
559 | err = -EFAULT; | ||
560 | break; | ||
561 | } | ||
562 | switch (req.property) { | ||
563 | case UBI_PROP_DIRECT_WRITE: | ||
564 | mutex_lock(&ubi->volumes_mutex); | ||
565 | desc->vol->direct_writes = !!req.value; | ||
566 | mutex_unlock(&ubi->volumes_mutex); | ||
567 | break; | ||
568 | default: | ||
569 | err = -EINVAL; | ||
570 | break; | ||
571 | } | ||
572 | break; | ||
573 | } | ||
522 | 574 | ||
523 | default: | 575 | default: |
524 | err = -ENOTTY; | 576 | err = -ENOTTY; |
525 | break; | 577 | break; |
526 | } | 578 | } |
527 | |||
528 | return err; | 579 | return err; |
529 | } | 580 | } |
530 | 581 | ||
@@ -762,8 +813,8 @@ out_free: | |||
762 | return err; | 813 | return err; |
763 | } | 814 | } |
764 | 815 | ||
765 | static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | 816 | static long ubi_cdev_ioctl(struct file *file, unsigned int cmd, |
766 | unsigned int cmd, unsigned long arg) | 817 | unsigned long arg) |
767 | { | 818 | { |
768 | int err = 0; | 819 | int err = 0; |
769 | struct ubi_device *ubi; | 820 | struct ubi_device *ubi; |
@@ -773,7 +824,7 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
773 | if (!capable(CAP_SYS_RESOURCE)) | 824 | if (!capable(CAP_SYS_RESOURCE)) |
774 | return -EPERM; | 825 | return -EPERM; |
775 | 826 | ||
776 | ubi = ubi_get_by_major(imajor(inode)); | 827 | ubi = ubi_get_by_major(imajor(file->f_mapping->host)); |
777 | if (!ubi) | 828 | if (!ubi) |
778 | return -ENODEV; | 829 | return -ENODEV; |
779 | 830 | ||
@@ -843,7 +894,6 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
843 | case UBI_IOCRSVOL: | 894 | case UBI_IOCRSVOL: |
844 | { | 895 | { |
845 | int pebs; | 896 | int pebs; |
846 | uint64_t tmp; | ||
847 | struct ubi_rsvol_req req; | 897 | struct ubi_rsvol_req req; |
848 | 898 | ||
849 | dbg_gen("re-size volume"); | 899 | dbg_gen("re-size volume"); |
@@ -863,9 +913,8 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
863 | break; | 913 | break; |
864 | } | 914 | } |
865 | 915 | ||
866 | tmp = req.bytes; | 916 | pebs = div_u64(req.bytes + desc->vol->usable_leb_size - 1, |
867 | pebs = !!do_div(tmp, desc->vol->usable_leb_size); | 917 | desc->vol->usable_leb_size); |
868 | pebs += tmp; | ||
869 | 918 | ||
870 | mutex_lock(&ubi->volumes_mutex); | 919 | mutex_lock(&ubi->volumes_mutex); |
871 | err = ubi_resize_volume(desc, pebs); | 920 | err = ubi_resize_volume(desc, pebs); |
@@ -909,8 +958,8 @@ static int ubi_cdev_ioctl(struct inode *inode, struct file *file, | |||
909 | return err; | 958 | return err; |
910 | } | 959 | } |
911 | 960 | ||
912 | static int ctrl_cdev_ioctl(struct inode *inode, struct file *file, | 961 | static long ctrl_cdev_ioctl(struct file *file, unsigned int cmd, |
913 | unsigned int cmd, unsigned long arg) | 962 | unsigned long arg) |
914 | { | 963 | { |
915 | int err = 0; | 964 | int err = 0; |
916 | void __user *argp = (void __user *)arg; | 965 | void __user *argp = (void __user *)arg; |
@@ -986,26 +1035,59 @@ static int ctrl_cdev_ioctl(struct inode *inode, struct file *file, | |||
986 | return err; | 1035 | return err; |
987 | } | 1036 | } |
988 | 1037 | ||
989 | /* UBI control character device operations */ | 1038 | #ifdef CONFIG_COMPAT |
990 | struct file_operations ubi_ctrl_cdev_operations = { | 1039 | static long vol_cdev_compat_ioctl(struct file *file, unsigned int cmd, |
991 | .ioctl = ctrl_cdev_ioctl, | 1040 | unsigned long arg) |
992 | .owner = THIS_MODULE, | 1041 | { |
1042 | unsigned long translated_arg = (unsigned long)compat_ptr(arg); | ||
1043 | |||
1044 | return vol_cdev_ioctl(file, cmd, translated_arg); | ||
1045 | } | ||
1046 | |||
1047 | static long ubi_cdev_compat_ioctl(struct file *file, unsigned int cmd, | ||
1048 | unsigned long arg) | ||
1049 | { | ||
1050 | unsigned long translated_arg = (unsigned long)compat_ptr(arg); | ||
1051 | |||
1052 | return ubi_cdev_ioctl(file, cmd, translated_arg); | ||
1053 | } | ||
1054 | |||
1055 | static long ctrl_cdev_compat_ioctl(struct file *file, unsigned int cmd, | ||
1056 | unsigned long arg) | ||
1057 | { | ||
1058 | unsigned long translated_arg = (unsigned long)compat_ptr(arg); | ||
1059 | |||
1060 | return ctrl_cdev_ioctl(file, cmd, translated_arg); | ||
1061 | } | ||
1062 | #else | ||
1063 | #define vol_cdev_compat_ioctl NULL | ||
1064 | #define ubi_cdev_compat_ioctl NULL | ||
1065 | #define ctrl_cdev_compat_ioctl NULL | ||
1066 | #endif | ||
1067 | |||
1068 | /* UBI volume character device operations */ | ||
1069 | const struct file_operations ubi_vol_cdev_operations = { | ||
1070 | .owner = THIS_MODULE, | ||
1071 | .open = vol_cdev_open, | ||
1072 | .release = vol_cdev_release, | ||
1073 | .llseek = vol_cdev_llseek, | ||
1074 | .read = vol_cdev_read, | ||
1075 | .write = vol_cdev_write, | ||
1076 | .unlocked_ioctl = vol_cdev_ioctl, | ||
1077 | .compat_ioctl = vol_cdev_compat_ioctl, | ||
993 | }; | 1078 | }; |
994 | 1079 | ||
995 | /* UBI character device operations */ | 1080 | /* UBI character device operations */ |
996 | struct file_operations ubi_cdev_operations = { | 1081 | const struct file_operations ubi_cdev_operations = { |
997 | .owner = THIS_MODULE, | 1082 | .owner = THIS_MODULE, |
998 | .ioctl = ubi_cdev_ioctl, | 1083 | .llseek = no_llseek, |
999 | .llseek = no_llseek, | 1084 | .unlocked_ioctl = ubi_cdev_ioctl, |
1085 | .compat_ioctl = ubi_cdev_compat_ioctl, | ||
1000 | }; | 1086 | }; |
1001 | 1087 | ||
1002 | /* UBI volume character device operations */ | 1088 | /* UBI control character device operations */ |
1003 | struct file_operations ubi_vol_cdev_operations = { | 1089 | const struct file_operations ubi_ctrl_cdev_operations = { |
1004 | .owner = THIS_MODULE, | 1090 | .owner = THIS_MODULE, |
1005 | .open = vol_cdev_open, | 1091 | .unlocked_ioctl = ctrl_cdev_ioctl, |
1006 | .release = vol_cdev_release, | 1092 | .compat_ioctl = ctrl_cdev_compat_ioctl, |
1007 | .llseek = vol_cdev_llseek, | ||
1008 | .read = vol_cdev_read, | ||
1009 | .write = vol_cdev_write, | ||
1010 | .ioctl = vol_cdev_ioctl, | ||
1011 | }; | 1093 | }; |
diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 6dd4f5e77f82..49cd55ade9c8 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c | |||
@@ -28,7 +28,7 @@ | |||
28 | * eraseblock size is equivalent to the logical eraseblock size of the volume. | 28 | * eraseblock size is equivalent to the logical eraseblock size of the volume. |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <asm/div64.h> | 31 | #include <linux/math64.h> |
32 | #include "ubi.h" | 32 | #include "ubi.h" |
33 | 33 | ||
34 | /** | 34 | /** |
@@ -109,7 +109,6 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
109 | int err = 0, lnum, offs, total_read; | 109 | int err = 0, lnum, offs, total_read; |
110 | struct ubi_volume *vol; | 110 | struct ubi_volume *vol; |
111 | struct ubi_device *ubi; | 111 | struct ubi_device *ubi; |
112 | uint64_t tmp = from; | ||
113 | 112 | ||
114 | dbg_gen("read %zd bytes from offset %lld", len, from); | 113 | dbg_gen("read %zd bytes from offset %lld", len, from); |
115 | 114 | ||
@@ -119,9 +118,7 @@ static int gluebi_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
119 | vol = container_of(mtd, struct ubi_volume, gluebi_mtd); | 118 | vol = container_of(mtd, struct ubi_volume, gluebi_mtd); |
120 | ubi = vol->ubi; | 119 | ubi = vol->ubi; |
121 | 120 | ||
122 | offs = do_div(tmp, mtd->erasesize); | 121 | lnum = div_u64_rem(from, mtd->erasesize, &offs); |
123 | lnum = tmp; | ||
124 | |||
125 | total_read = len; | 122 | total_read = len; |
126 | while (total_read) { | 123 | while (total_read) { |
127 | size_t to_read = mtd->erasesize - offs; | 124 | size_t to_read = mtd->erasesize - offs; |
@@ -160,7 +157,6 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
160 | int err = 0, lnum, offs, total_written; | 157 | int err = 0, lnum, offs, total_written; |
161 | struct ubi_volume *vol; | 158 | struct ubi_volume *vol; |
162 | struct ubi_device *ubi; | 159 | struct ubi_device *ubi; |
163 | uint64_t tmp = to; | ||
164 | 160 | ||
165 | dbg_gen("write %zd bytes to offset %lld", len, to); | 161 | dbg_gen("write %zd bytes to offset %lld", len, to); |
166 | 162 | ||
@@ -173,8 +169,7 @@ static int gluebi_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
173 | if (ubi->ro_mode) | 169 | if (ubi->ro_mode) |
174 | return -EROFS; | 170 | return -EROFS; |
175 | 171 | ||
176 | offs = do_div(tmp, mtd->erasesize); | 172 | lnum = div_u64_rem(to, mtd->erasesize, &offs); |
177 | lnum = tmp; | ||
178 | 173 | ||
179 | if (len % mtd->writesize || offs % mtd->writesize) | 174 | if (len % mtd->writesize || offs % mtd->writesize) |
180 | return -EINVAL; | 175 | return -EINVAL; |
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c index ecde202a5a12..c3d653ba5ca0 100644 --- a/drivers/mtd/ubi/scan.c +++ b/drivers/mtd/ubi/scan.c | |||
@@ -42,7 +42,7 @@ | |||
42 | 42 | ||
43 | #include <linux/err.h> | 43 | #include <linux/err.h> |
44 | #include <linux/crc32.h> | 44 | #include <linux/crc32.h> |
45 | #include <asm/div64.h> | 45 | #include <linux/math64.h> |
46 | #include "ubi.h" | 46 | #include "ubi.h" |
47 | 47 | ||
48 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 48 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID |
@@ -904,10 +904,8 @@ struct ubi_scan_info *ubi_scan(struct ubi_device *ubi) | |||
904 | dbg_msg("scanning is finished"); | 904 | dbg_msg("scanning is finished"); |
905 | 905 | ||
906 | /* Calculate mean erase counter */ | 906 | /* Calculate mean erase counter */ |
907 | if (si->ec_count) { | 907 | if (si->ec_count) |
908 | do_div(si->ec_sum, si->ec_count); | 908 | si->mean_ec = div_u64(si->ec_sum, si->ec_count); |
909 | si->mean_ec = si->ec_sum; | ||
910 | } | ||
911 | 909 | ||
912 | if (si->is_empty) | 910 | if (si->is_empty) |
913 | ubi_msg("empty MTD device detected"); | 911 | ubi_msg("empty MTD device detected"); |
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 4a8ec485c91d..c055511bb1b2 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
@@ -206,6 +206,7 @@ struct ubi_volume_desc; | |||
206 | * @upd_marker: %1 if the update marker is set for this volume | 206 | * @upd_marker: %1 if the update marker is set for this volume |
207 | * @updating: %1 if the volume is being updated | 207 | * @updating: %1 if the volume is being updated |
208 | * @changing_leb: %1 if the atomic LEB change ioctl command is in progress | 208 | * @changing_leb: %1 if the atomic LEB change ioctl command is in progress |
209 | * @direct_writes: %1 if direct writes are enabled for this volume | ||
209 | * | 210 | * |
210 | * @gluebi_desc: gluebi UBI volume descriptor | 211 | * @gluebi_desc: gluebi UBI volume descriptor |
211 | * @gluebi_refcount: reference count of the gluebi MTD device | 212 | * @gluebi_refcount: reference count of the gluebi MTD device |
@@ -253,6 +254,7 @@ struct ubi_volume { | |||
253 | unsigned int upd_marker:1; | 254 | unsigned int upd_marker:1; |
254 | unsigned int updating:1; | 255 | unsigned int updating:1; |
255 | unsigned int changing_leb:1; | 256 | unsigned int changing_leb:1; |
257 | unsigned int direct_writes:1; | ||
256 | 258 | ||
257 | #ifdef CONFIG_MTD_UBI_GLUEBI | 259 | #ifdef CONFIG_MTD_UBI_GLUEBI |
258 | /* | 260 | /* |
@@ -304,7 +306,8 @@ struct ubi_wl_entry; | |||
304 | * @vtbl_size: size of the volume table in bytes | 306 | * @vtbl_size: size of the volume table in bytes |
305 | * @vtbl: in-RAM volume table copy | 307 | * @vtbl: in-RAM volume table copy |
306 | * @volumes_mutex: protects on-flash volume table and serializes volume | 308 | * @volumes_mutex: protects on-flash volume table and serializes volume |
307 | * changes, like creation, deletion, update, re-size and re-name | 309 | * changes, like creation, deletion, update, re-size, |
310 | * re-name and set property | ||
308 | * | 311 | * |
309 | * @max_ec: current highest erase counter value | 312 | * @max_ec: current highest erase counter value |
310 | * @mean_ec: current mean erase counter value | 313 | * @mean_ec: current mean erase counter value |
@@ -449,9 +452,9 @@ struct ubi_device { | |||
449 | }; | 452 | }; |
450 | 453 | ||
451 | extern struct kmem_cache *ubi_wl_entry_slab; | 454 | extern struct kmem_cache *ubi_wl_entry_slab; |
452 | extern struct file_operations ubi_ctrl_cdev_operations; | 455 | extern const struct file_operations ubi_ctrl_cdev_operations; |
453 | extern struct file_operations ubi_cdev_operations; | 456 | extern const struct file_operations ubi_cdev_operations; |
454 | extern struct file_operations ubi_vol_cdev_operations; | 457 | extern const struct file_operations ubi_vol_cdev_operations; |
455 | extern struct class *ubi_class; | 458 | extern struct class *ubi_class; |
456 | extern struct mutex ubi_devices_mutex; | 459 | extern struct mutex ubi_devices_mutex; |
457 | 460 | ||
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c index 8b89cc18ff0b..6b4d1ae891ae 100644 --- a/drivers/mtd/ubi/upd.c +++ b/drivers/mtd/ubi/upd.c | |||
@@ -40,7 +40,7 @@ | |||
40 | 40 | ||
41 | #include <linux/err.h> | 41 | #include <linux/err.h> |
42 | #include <linux/uaccess.h> | 42 | #include <linux/uaccess.h> |
43 | #include <asm/div64.h> | 43 | #include <linux/math64.h> |
44 | #include "ubi.h" | 44 | #include "ubi.h" |
45 | 45 | ||
46 | /** | 46 | /** |
@@ -89,7 +89,6 @@ static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol, | |||
89 | long long bytes) | 89 | long long bytes) |
90 | { | 90 | { |
91 | int err; | 91 | int err; |
92 | uint64_t tmp; | ||
93 | struct ubi_vtbl_record vtbl_rec; | 92 | struct ubi_vtbl_record vtbl_rec; |
94 | 93 | ||
95 | dbg_gen("clear update marker for volume %d", vol->vol_id); | 94 | dbg_gen("clear update marker for volume %d", vol->vol_id); |
@@ -101,9 +100,9 @@ static int clear_update_marker(struct ubi_device *ubi, struct ubi_volume *vol, | |||
101 | 100 | ||
102 | if (vol->vol_type == UBI_STATIC_VOLUME) { | 101 | if (vol->vol_type == UBI_STATIC_VOLUME) { |
103 | vol->corrupted = 0; | 102 | vol->corrupted = 0; |
104 | vol->used_bytes = tmp = bytes; | 103 | vol->used_bytes = bytes; |
105 | vol->last_eb_bytes = do_div(tmp, vol->usable_leb_size); | 104 | vol->used_ebs = div_u64_rem(bytes, vol->usable_leb_size, |
106 | vol->used_ebs = tmp; | 105 | &vol->last_eb_bytes); |
107 | if (vol->last_eb_bytes) | 106 | if (vol->last_eb_bytes) |
108 | vol->used_ebs += 1; | 107 | vol->used_ebs += 1; |
109 | else | 108 | else |
@@ -131,7 +130,6 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, | |||
131 | long long bytes) | 130 | long long bytes) |
132 | { | 131 | { |
133 | int i, err; | 132 | int i, err; |
134 | uint64_t tmp; | ||
135 | 133 | ||
136 | dbg_gen("start update of volume %d, %llu bytes", vol->vol_id, bytes); | 134 | dbg_gen("start update of volume %d, %llu bytes", vol->vol_id, bytes); |
137 | ubi_assert(!vol->updating && !vol->changing_leb); | 135 | ubi_assert(!vol->updating && !vol->changing_leb); |
@@ -161,9 +159,8 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, | |||
161 | if (!vol->upd_buf) | 159 | if (!vol->upd_buf) |
162 | return -ENOMEM; | 160 | return -ENOMEM; |
163 | 161 | ||
164 | tmp = bytes; | 162 | vol->upd_ebs = div_u64(bytes + vol->usable_leb_size - 1, |
165 | vol->upd_ebs = !!do_div(tmp, vol->usable_leb_size); | 163 | vol->usable_leb_size); |
166 | vol->upd_ebs += tmp; | ||
167 | vol->upd_bytes = bytes; | 164 | vol->upd_bytes = bytes; |
168 | vol->upd_received = 0; | 165 | vol->upd_received = 0; |
169 | return 0; | 166 | return 0; |
@@ -282,7 +279,6 @@ static int write_leb(struct ubi_device *ubi, struct ubi_volume *vol, int lnum, | |||
282 | int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, | 279 | int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, |
283 | const void __user *buf, int count) | 280 | const void __user *buf, int count) |
284 | { | 281 | { |
285 | uint64_t tmp; | ||
286 | int lnum, offs, err = 0, len, to_write = count; | 282 | int lnum, offs, err = 0, len, to_write = count; |
287 | 283 | ||
288 | dbg_gen("write %d of %lld bytes, %lld already passed", | 284 | dbg_gen("write %d of %lld bytes, %lld already passed", |
@@ -291,10 +287,7 @@ int ubi_more_update_data(struct ubi_device *ubi, struct ubi_volume *vol, | |||
291 | if (ubi->ro_mode) | 287 | if (ubi->ro_mode) |
292 | return -EROFS; | 288 | return -EROFS; |
293 | 289 | ||
294 | tmp = vol->upd_received; | 290 | lnum = div_u64_rem(vol->upd_received, vol->usable_leb_size, &offs); |
295 | offs = do_div(tmp, vol->usable_leb_size); | ||
296 | lnum = tmp; | ||
297 | |||
298 | if (vol->upd_received + count > vol->upd_bytes) | 291 | if (vol->upd_received + count > vol->upd_bytes) |
299 | to_write = count = vol->upd_bytes - vol->upd_received; | 292 | to_write = count = vol->upd_bytes - vol->upd_received; |
300 | 293 | ||
diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 22e1d7398fce..df5483562b7a 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c | |||
@@ -24,7 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <asm/div64.h> | 27 | #include <linux/math64.h> |
28 | #include "ubi.h" | 28 | #include "ubi.h" |
29 | 29 | ||
30 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 30 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID |
@@ -205,7 +205,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) | |||
205 | int i, err, vol_id = req->vol_id, do_free = 1; | 205 | int i, err, vol_id = req->vol_id, do_free = 1; |
206 | struct ubi_volume *vol; | 206 | struct ubi_volume *vol; |
207 | struct ubi_vtbl_record vtbl_rec; | 207 | struct ubi_vtbl_record vtbl_rec; |
208 | uint64_t bytes; | ||
209 | dev_t dev; | 208 | dev_t dev; |
210 | 209 | ||
211 | if (ubi->ro_mode) | 210 | if (ubi->ro_mode) |
@@ -255,10 +254,8 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) | |||
255 | 254 | ||
256 | /* Calculate how many eraseblocks are requested */ | 255 | /* Calculate how many eraseblocks are requested */ |
257 | vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment; | 256 | vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment; |
258 | bytes = req->bytes; | 257 | vol->reserved_pebs += div_u64(req->bytes + vol->usable_leb_size - 1, |
259 | if (do_div(bytes, vol->usable_leb_size)) | 258 | vol->usable_leb_size); |
260 | vol->reserved_pebs = 1; | ||
261 | vol->reserved_pebs += bytes; | ||
262 | 259 | ||
263 | /* Reserve physical eraseblocks */ | 260 | /* Reserve physical eraseblocks */ |
264 | if (vol->reserved_pebs > ubi->avail_pebs) { | 261 | if (vol->reserved_pebs > ubi->avail_pebs) { |
@@ -301,10 +298,10 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) | |||
301 | vol->used_bytes = | 298 | vol->used_bytes = |
302 | (long long)vol->used_ebs * vol->usable_leb_size; | 299 | (long long)vol->used_ebs * vol->usable_leb_size; |
303 | } else { | 300 | } else { |
304 | bytes = vol->used_bytes; | 301 | vol->used_ebs = div_u64_rem(vol->used_bytes, |
305 | vol->last_eb_bytes = do_div(bytes, vol->usable_leb_size); | 302 | vol->usable_leb_size, |
306 | vol->used_ebs = bytes; | 303 | &vol->last_eb_bytes); |
307 | if (vol->last_eb_bytes) | 304 | if (vol->last_eb_bytes != 0) |
308 | vol->used_ebs += 1; | 305 | vol->used_ebs += 1; |
309 | else | 306 | else |
310 | vol->last_eb_bytes = vol->usable_leb_size; | 307 | vol->last_eb_bytes = vol->usable_leb_size; |