aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/cmdlinepart.c2
-rw-r--r--drivers/mtd/ftl.c3
-rw-r--r--drivers/mtd/inftlcore.c9
-rw-r--r--drivers/mtd/maps/Kconfig9
-rw-r--r--drivers/mtd/maps/Makefile1
-rw-r--r--drivers/mtd/maps/ck804xrom.c356
-rw-r--r--drivers/mtd/mtd_blkdevs.c15
-rw-r--r--drivers/mtd/mtdblock.c3
-rw-r--r--drivers/mtd/mtdblock_ro.c3
-rw-r--r--drivers/mtd/mtdchar.c12
-rw-r--r--drivers/mtd/mtdconcat.c39
-rw-r--r--drivers/mtd/mtdpart.c4
-rw-r--r--drivers/mtd/nand/Kconfig1
-rw-r--r--drivers/mtd/nand/nand_base.c53
-rw-r--r--drivers/mtd/nand/nand_bbt.c5
-rw-r--r--drivers/mtd/nand/ndfc.c2
-rw-r--r--drivers/mtd/nand/rtc_from4.c44
-rw-r--r--drivers/mtd/nftlcore.c9
-rw-r--r--drivers/mtd/rfd_ftl.c3
-rw-r--r--drivers/mtd/ssfdc.c5
20 files changed, 467 insertions, 111 deletions
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index a7a7bfe33879..3402ce448702 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -346,7 +346,7 @@ static int parse_cmdline_partitions(struct mtd_info *master,
346 * 346 *
347 * This function needs to be visible for bootloaders. 347 * This function needs to be visible for bootloaders.
348 */ 348 */
349int mtdpart_setup(char *s) 349static int mtdpart_setup(char *s)
350{ 350{
351 cmdline = s; 351 cmdline = s;
352 return 1; 352 return 1;
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index 8a878b34eca0..da39355132d8 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1054,7 +1054,7 @@ static void ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
1054 le32_to_cpu(partition->header.FormattedSize) >> 10); 1054 le32_to_cpu(partition->header.FormattedSize) >> 10);
1055#endif 1055#endif
1056 partition->mbd.size = le32_to_cpu(partition->header.FormattedSize) >> 9; 1056 partition->mbd.size = le32_to_cpu(partition->header.FormattedSize) >> 9;
1057 partition->mbd.blksize = SECTOR_SIZE; 1057
1058 partition->mbd.tr = tr; 1058 partition->mbd.tr = tr;
1059 partition->mbd.devnum = -1; 1059 partition->mbd.devnum = -1;
1060 if (!add_mtd_blktrans_dev((void *)partition)) 1060 if (!add_mtd_blktrans_dev((void *)partition))
@@ -1076,6 +1076,7 @@ struct mtd_blktrans_ops ftl_tr = {
1076 .name = "ftl", 1076 .name = "ftl",
1077 .major = FTL_MAJOR, 1077 .major = FTL_MAJOR,
1078 .part_bits = PART_BITS, 1078 .part_bits = PART_BITS,
1079 .blksize = SECTOR_SIZE,
1079 .readsect = ftl_readsect, 1080 .readsect = ftl_readsect,
1080 .writesect = ftl_writesect, 1081 .writesect = ftl_writesect,
1081 .getgeo = ftl_getgeo, 1082 .getgeo = ftl_getgeo,
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index 4116535805f1..d2f54c037e0f 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -77,7 +77,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
77 77
78 inftl->mbd.mtd = mtd; 78 inftl->mbd.mtd = mtd;
79 inftl->mbd.devnum = -1; 79 inftl->mbd.devnum = -1;
80 inftl->mbd.blksize = 512; 80
81 inftl->mbd.tr = tr; 81 inftl->mbd.tr = tr;
82 82
83 if (INFTL_mount(inftl) < 0) { 83 if (INFTL_mount(inftl) < 0) {
@@ -163,10 +163,9 @@ int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
163 ops.ooblen = len; 163 ops.ooblen = len;
164 ops.oobbuf = buf; 164 ops.oobbuf = buf;
165 ops.datbuf = NULL; 165 ops.datbuf = NULL;
166 ops.len = len;
167 166
168 res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops); 167 res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
169 *retlen = ops.retlen; 168 *retlen = ops.oobretlen;
170 return res; 169 return res;
171} 170}
172 171
@@ -184,10 +183,9 @@ int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
184 ops.ooblen = len; 183 ops.ooblen = len;
185 ops.oobbuf = buf; 184 ops.oobbuf = buf;
186 ops.datbuf = NULL; 185 ops.datbuf = NULL;
187 ops.len = len;
188 186
189 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops); 187 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
190 *retlen = ops.retlen; 188 *retlen = ops.oobretlen;
191 return res; 189 return res;
192} 190}
193 191
@@ -945,6 +943,7 @@ static struct mtd_blktrans_ops inftl_tr = {
945 .name = "inftl", 943 .name = "inftl",
946 .major = INFTL_MAJOR, 944 .major = INFTL_MAJOR,
947 .part_bits = INFTL_PARTN_BITS, 945 .part_bits = INFTL_PARTN_BITS,
946 .blksize = 512,
948 .getgeo = inftl_getgeo, 947 .getgeo = inftl_getgeo,
949 .readsect = inftl_readblock, 948 .readsect = inftl_readblock,
950 .writesect = inftl_writeblock, 949 .writesect = inftl_writeblock,
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 7514a9bee015..fa7466886fd6 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -193,6 +193,15 @@ config MTD_ESB2ROM
193 193
194 BE VERY CAREFUL. 194 BE VERY CAREFUL.
195 195
196config MTD_CK804XROM
197 tristate "BIOS flash chip on Nvidia CK804"
198 depends on X86 && MTD_JEDECPROBE
199 help
200 Support for treating the BIOS flash chip on nvidia motherboards
201 as an MTD device - with this you can reprogram your BIOS.
202
203 BE VERY CAREFUL.
204
196config MTD_SCB2_FLASH 205config MTD_SCB2_FLASH
197 tristate "BIOS flash chip on Intel SCB2 boards" 206 tristate "BIOS flash chip on Intel SCB2 boards"
198 depends on X86 && MTD_JEDECPROBE 207 depends on X86 && MTD_JEDECPROBE
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 9061432c5e1a..34505216d403 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_MTD_L440GX) += l440gx.o
19obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o 19obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o
20obj-$(CONFIG_MTD_ESB2ROM) += esb2rom.o 20obj-$(CONFIG_MTD_ESB2ROM) += esb2rom.o
21obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o 21obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o
22obj-$(CONFIG_MTD_CK804XROM) += ck804xrom.o
22obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o 23obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o
23obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o 24obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o
24obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o 25obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c
new file mode 100644
index 000000000000..c222b88c3c3a
--- /dev/null
+++ b/drivers/mtd/maps/ck804xrom.c
@@ -0,0 +1,356 @@
1/*
2 * ck804xrom.c
3 *
4 * Normal mappings of chips in physical memory
5 *
6 * Dave Olsen <dolsen@lnxi.com>
7 * Ryan Jackson <rjackson@lnxi.com>
8 */
9
10#include <linux/module.h>
11#include <linux/types.h>
12#include <linux/version.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <asm/io.h>
16#include <linux/mtd/mtd.h>
17#include <linux/mtd/map.h>
18#include <linux/mtd/cfi.h>
19#include <linux/mtd/flashchip.h>
20#include <linux/pci.h>
21#include <linux/pci_ids.h>
22#include <linux/list.h>
23
24
25#define MOD_NAME KBUILD_BASENAME
26
27#define ADDRESS_NAME_LEN 18
28
29#define ROM_PROBE_STEP_SIZE (64*1024)
30
31struct ck804xrom_window {
32 void __iomem *virt;
33 unsigned long phys;
34 unsigned long size;
35 struct list_head maps;
36 struct resource rsrc;
37 struct pci_dev *pdev;
38};
39
40struct ck804xrom_map_info {
41 struct list_head list;
42 struct map_info map;
43 struct mtd_info *mtd;
44 struct resource rsrc;
45 char map_name[sizeof(MOD_NAME) + 2 + ADDRESS_NAME_LEN];
46};
47
48
49/* The 2 bits controlling the window size are often set to allow reading
50 * the BIOS, but too small to allow writing, since the lock registers are
51 * 4MiB lower in the address space than the data.
52 *
53 * This is intended to prevent flashing the bios, perhaps accidentally.
54 *
55 * This parameter allows the normal driver to override the BIOS settings.
56 *
57 * The bits are 6 and 7. If both bits are set, it is a 5MiB window.
58 * If only the 7 Bit is set, it is a 4MiB window. Otherwise, a
59 * 64KiB window.
60 *
61 */
62static uint win_size_bits = 0;
63module_param(win_size_bits, uint, 0);
64MODULE_PARM_DESC(win_size_bits, "ROM window size bits override for 0x88 byte, normally set by BIOS.");
65
66static struct ck804xrom_window ck804xrom_window = {
67 .maps = LIST_HEAD_INIT(ck804xrom_window.maps),
68};
69
70static void ck804xrom_cleanup(struct ck804xrom_window *window)
71{
72 struct ck804xrom_map_info *map, *scratch;
73 u8 byte;
74
75 if (window->pdev) {
76 /* Disable writes through the rom window */
77 pci_read_config_byte(window->pdev, 0x6d, &byte);
78 pci_write_config_byte(window->pdev, 0x6d, byte & ~1);
79 }
80
81 /* Free all of the mtd devices */
82 list_for_each_entry_safe(map, scratch, &window->maps, list) {
83 if (map->rsrc.parent)
84 release_resource(&map->rsrc);
85
86 del_mtd_device(map->mtd);
87 map_destroy(map->mtd);
88 list_del(&map->list);
89 kfree(map);
90 }
91 if (window->rsrc.parent)
92 release_resource(&window->rsrc);
93
94 if (window->virt) {
95 iounmap(window->virt);
96 window->virt = NULL;
97 window->phys = 0;
98 window->size = 0;
99 }
100 pci_dev_put(window->pdev);
101}
102
103
104static int __devinit ck804xrom_init_one (struct pci_dev *pdev,
105 const struct pci_device_id *ent)
106{
107 static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
108 u8 byte;
109 struct ck804xrom_window *window = &ck804xrom_window;
110 struct ck804xrom_map_info *map = NULL;
111 unsigned long map_top;
112
113 /* Remember the pci dev I find the window in */
114 window->pdev = pci_dev_get(pdev);
115
116 /* Enable the selected rom window. This is often incorrectly
117 * set up by the BIOS, and the 4MiB offset for the lock registers
118 * requires the full 5MiB of window space.
119 *
120 * This 'write, then read' approach leaves the bits for
121 * other uses of the hardware info.
122 */
123 pci_read_config_byte(pdev, 0x88, &byte);
124 pci_write_config_byte(pdev, 0x88, byte | win_size_bits );
125
126
127 /* Assume the rom window is properly setup, and find it's size */
128 pci_read_config_byte(pdev, 0x88, &byte);
129
130 if ((byte & ((1<<7)|(1<<6))) == ((1<<7)|(1<<6)))
131 window->phys = 0xffb00000; /* 5MiB */
132 else if ((byte & (1<<7)) == (1<<7))
133 window->phys = 0xffc00000; /* 4MiB */
134 else
135 window->phys = 0xffff0000; /* 64KiB */
136
137 window->size = 0xffffffffUL - window->phys + 1UL;
138
139 /*
140 * Try to reserve the window mem region. If this fails then
141 * it is likely due to a fragment of the window being
142 * "reserved" by the BIOS. In the case that the
143 * request_mem_region() fails then once the rom size is
144 * discovered we will try to reserve the unreserved fragment.
145 */
146 window->rsrc.name = MOD_NAME;
147 window->rsrc.start = window->phys;
148 window->rsrc.end = window->phys + window->size - 1;
149 window->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
150 if (request_resource(&iomem_resource, &window->rsrc)) {
151 window->rsrc.parent = NULL;
152 printk(KERN_ERR MOD_NAME
153 " %s(): Unable to register resource"
154 " 0x%.016llx-0x%.016llx - kernel bug?\n",
155 __func__,
156 (unsigned long long)window->rsrc.start,
157 (unsigned long long)window->rsrc.end);
158 }
159
160
161 /* Enable writes through the rom window */
162 pci_read_config_byte(pdev, 0x6d, &byte);
163 pci_write_config_byte(pdev, 0x6d, byte | 1);
164
165 /* FIXME handle registers 0x80 - 0x8C the bios region locks */
166
167 /* For write accesses caches are useless */
168 window->virt = ioremap_nocache(window->phys, window->size);
169 if (!window->virt) {
170 printk(KERN_ERR MOD_NAME ": ioremap(%08lx, %08lx) failed\n",
171 window->phys, window->size);
172 goto out;
173 }
174
175 /* Get the first address to look for a rom chip at */
176 map_top = window->phys;
177#if 1
178 /* The probe sequence run over the firmware hub lock
179 * registers sets them to 0x7 (no access).
180 * Probe at most the last 4MiB of the address space.
181 */
182 if (map_top < 0xffc00000)
183 map_top = 0xffc00000;
184#endif
185 /* Loop through and look for rom chips. Since we don't know the
186 * starting address for each chip, probe every ROM_PROBE_STEP_SIZE
187 * bytes from the starting address of the window.
188 */
189 while((map_top - 1) < 0xffffffffUL) {
190 struct cfi_private *cfi;
191 unsigned long offset;
192 int i;
193
194 if (!map)
195 map = kmalloc(sizeof(*map), GFP_KERNEL);
196
197 if (!map) {
198 printk(KERN_ERR MOD_NAME ": kmalloc failed");
199 goto out;
200 }
201 memset(map, 0, sizeof(*map));
202 INIT_LIST_HEAD(&map->list);
203 map->map.name = map->map_name;
204 map->map.phys = map_top;
205 offset = map_top - window->phys;
206 map->map.virt = (void __iomem *)
207 (((unsigned long)(window->virt)) + offset);
208 map->map.size = 0xffffffffUL - map_top + 1UL;
209 /* Set the name of the map to the address I am trying */
210 sprintf(map->map_name, "%s @%08lx",
211 MOD_NAME, map->map.phys);
212
213 /* There is no generic VPP support */
214 for(map->map.bankwidth = 32; map->map.bankwidth;
215 map->map.bankwidth >>= 1)
216 {
217 char **probe_type;
218 /* Skip bankwidths that are not supported */
219 if (!map_bankwidth_supported(map->map.bankwidth))
220 continue;
221
222 /* Setup the map methods */
223 simple_map_init(&map->map);
224
225 /* Try all of the probe methods */
226 probe_type = rom_probe_types;
227 for(; *probe_type; probe_type++) {
228 map->mtd = do_map_probe(*probe_type, &map->map);
229 if (map->mtd)
230 goto found;
231 }
232 }
233 map_top += ROM_PROBE_STEP_SIZE;
234 continue;
235 found:
236 /* Trim the size if we are larger than the map */
237 if (map->mtd->size > map->map.size) {
238 printk(KERN_WARNING MOD_NAME
239 " rom(%u) larger than window(%lu). fixing...\n",
240 map->mtd->size, map->map.size);
241 map->mtd->size = map->map.size;
242 }
243 if (window->rsrc.parent) {
244 /*
245 * Registering the MTD device in iomem may not be possible
246 * if there is a BIOS "reserved" and BUSY range. If this
247 * fails then continue anyway.
248 */
249 map->rsrc.name = map->map_name;
250 map->rsrc.start = map->map.phys;
251 map->rsrc.end = map->map.phys + map->mtd->size - 1;
252 map->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
253 if (request_resource(&window->rsrc, &map->rsrc)) {
254 printk(KERN_ERR MOD_NAME
255 ": cannot reserve MTD resource\n");
256 map->rsrc.parent = NULL;
257 }
258 }
259
260 /* Make the whole region visible in the map */
261 map->map.virt = window->virt;
262 map->map.phys = window->phys;
263 cfi = map->map.fldrv_priv;
264 for(i = 0; i < cfi->numchips; i++)
265 cfi->chips[i].start += offset;
266
267 /* Now that the mtd devices is complete claim and export it */
268 map->mtd->owner = THIS_MODULE;
269 if (add_mtd_device(map->mtd)) {
270 map_destroy(map->mtd);
271 map->mtd = NULL;
272 goto out;
273 }
274
275
276 /* Calculate the new value of map_top */
277 map_top += map->mtd->size;
278
279 /* File away the map structure */
280 list_add(&map->list, &window->maps);
281 map = NULL;
282 }
283
284 out:
285 /* Free any left over map structures */
286 if (map)
287 kfree(map);
288
289 /* See if I have any map structures */
290 if (list_empty(&window->maps)) {
291 ck804xrom_cleanup(window);
292 return -ENODEV;
293 }
294 return 0;
295}
296
297
298static void __devexit ck804xrom_remove_one (struct pci_dev *pdev)
299{
300 struct ck804xrom_window *window = &ck804xrom_window;
301
302 ck804xrom_cleanup(window);
303}
304
305static struct pci_device_id ck804xrom_pci_tbl[] = {
306 { PCI_VENDOR_ID_NVIDIA, 0x0051,
307 PCI_ANY_ID, PCI_ANY_ID, }, /* nvidia ck804 */
308 { 0, }
309};
310
311MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl);
312
313#if 0
314static struct pci_driver ck804xrom_driver = {
315 .name = MOD_NAME,
316 .id_table = ck804xrom_pci_tbl,
317 .probe = ck804xrom_init_one,
318 .remove = ck804xrom_remove_one,
319};
320#endif
321
322static int __init init_ck804xrom(void)
323{
324 struct pci_dev *pdev;
325 struct pci_device_id *id;
326 int retVal;
327 pdev = NULL;
328
329 for(id = ck804xrom_pci_tbl; id->vendor; id++) {
330 pdev = pci_find_device(id->vendor, id->device, NULL);
331 if (pdev)
332 break;
333 }
334 if (pdev) {
335 retVal = ck804xrom_init_one(pdev, &ck804xrom_pci_tbl[0]);
336 pci_dev_put(pdev);
337 return retVal;
338 }
339 return -ENXIO;
340#if 0
341 return pci_module_init(&ck804xrom_driver);
342#endif
343}
344
345static void __exit cleanup_ck804xrom(void)
346{
347 ck804xrom_remove_one(ck804xrom_window.pdev);
348}
349
350module_init(init_ck804xrom);
351module_exit(cleanup_ck804xrom);
352
353MODULE_LICENSE("GPL");
354MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>, Dave Olsen <dolsen@lnxi.com>");
355MODULE_DESCRIPTION("MTD map driver for BIOS chips on the Nvidia ck804 southbridge");
356
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 178b53b56be9..b5d62cb357da 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -42,19 +42,20 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
42 unsigned long block, nsect; 42 unsigned long block, nsect;
43 char *buf; 43 char *buf;
44 44
45 block = req->sector; 45 block = req->sector << 9 >> tr->blkshift;
46 nsect = req->current_nr_sectors; 46 nsect = req->current_nr_sectors << 9 >> tr->blkshift;
47
47 buf = req->buffer; 48 buf = req->buffer;
48 49
49 if (!blk_fs_request(req)) 50 if (!blk_fs_request(req))
50 return 0; 51 return 0;
51 52
52 if (block + nsect > get_capacity(req->rq_disk)) 53 if (req->sector + req->current_nr_sectors > get_capacity(req->rq_disk))
53 return 0; 54 return 0;
54 55
55 switch(rq_data_dir(req)) { 56 switch(rq_data_dir(req)) {
56 case READ: 57 case READ:
57 for (; nsect > 0; nsect--, block++, buf += 512) 58 for (; nsect > 0; nsect--, block++, buf += tr->blksize)
58 if (tr->readsect(dev, block, buf)) 59 if (tr->readsect(dev, block, buf))
59 return 0; 60 return 0;
60 return 1; 61 return 1;
@@ -63,7 +64,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
63 if (!tr->writesect) 64 if (!tr->writesect)
64 return 0; 65 return 0;
65 66
66 for (; nsect > 0; nsect--, block++, buf += 512) 67 for (; nsect > 0; nsect--, block++, buf += tr->blksize)
67 if (tr->writesect(dev, block, buf)) 68 if (tr->writesect(dev, block, buf))
68 return 0; 69 return 0;
69 return 1; 70 return 1;
@@ -297,7 +298,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
297 298
298 /* 2.5 has capacity in units of 512 bytes while still 299 /* 2.5 has capacity in units of 512 bytes while still
299 having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */ 300 having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
300 set_capacity(gd, (new->size * new->blksize) >> 9); 301 set_capacity(gd, (new->size * tr->blksize) >> 9);
301 302
302 gd->private_data = new; 303 gd->private_data = new;
303 new->blkcore_priv = gd; 304 new->blkcore_priv = gd;
@@ -401,6 +402,8 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
401 } 402 }
402 403
403 tr->blkcore_priv->rq->queuedata = tr; 404 tr->blkcore_priv->rq->queuedata = tr;
405 blk_queue_hardsect_size(tr->blkcore_priv->rq, tr->blksize);
406 tr->blkshift = ffs(tr->blksize) - 1;
404 407
405 ret = kernel_thread(mtd_blktrans_thread, tr, CLONE_KERNEL); 408 ret = kernel_thread(mtd_blktrans_thread, tr, CLONE_KERNEL);
406 if (ret < 0) { 409 if (ret < 0) {
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index 04ed34694b14..a052648f6e31 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -348,7 +348,7 @@ static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
348 348
349 dev->mtd = mtd; 349 dev->mtd = mtd;
350 dev->devnum = mtd->index; 350 dev->devnum = mtd->index;
351 dev->blksize = 512; 351
352 dev->size = mtd->size >> 9; 352 dev->size = mtd->size >> 9;
353 dev->tr = tr; 353 dev->tr = tr;
354 354
@@ -368,6 +368,7 @@ static struct mtd_blktrans_ops mtdblock_tr = {
368 .name = "mtdblock", 368 .name = "mtdblock",
369 .major = 31, 369 .major = 31,
370 .part_bits = 0, 370 .part_bits = 0,
371 .blksize = 512,
371 .open = mtdblock_open, 372 .open = mtdblock_open,
372 .flush = mtdblock_flush, 373 .flush = mtdblock_flush,
373 .release = mtdblock_release, 374 .release = mtdblock_release,
diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c
index 29563ed258a4..642ccc66f283 100644
--- a/drivers/mtd/mtdblock_ro.c
+++ b/drivers/mtd/mtdblock_ro.c
@@ -42,7 +42,7 @@ static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
42 42
43 dev->mtd = mtd; 43 dev->mtd = mtd;
44 dev->devnum = mtd->index; 44 dev->devnum = mtd->index;
45 dev->blksize = 512; 45
46 dev->size = mtd->size >> 9; 46 dev->size = mtd->size >> 9;
47 dev->tr = tr; 47 dev->tr = tr;
48 dev->readonly = 1; 48 dev->readonly = 1;
@@ -60,6 +60,7 @@ static struct mtd_blktrans_ops mtdblock_tr = {
60 .name = "mtdblock", 60 .name = "mtdblock",
61 .major = 31, 61 .major = 31,
62 .part_bits = 0, 62 .part_bits = 0,
63 .blksize = 512,
63 .readsect = mtdblock_readsect, 64 .readsect = mtdblock_readsect,
64 .writesect = mtdblock_writesect, 65 .writesect = mtdblock_writesect,
65 .add_mtd = mtdblock_add_mtd, 66 .add_mtd = mtdblock_add_mtd,
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 866c8e0d57e4..07618f51d969 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -499,13 +499,12 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
499 if (ret) 499 if (ret)
500 return ret; 500 return ret;
501 501
502 ops.len = buf.length;
503 ops.ooblen = buf.length; 502 ops.ooblen = buf.length;
504 ops.ooboffs = buf.start & (mtd->oobsize - 1); 503 ops.ooboffs = buf.start & (mtd->oobsize - 1);
505 ops.datbuf = NULL; 504 ops.datbuf = NULL;
506 ops.mode = MTD_OOB_PLACE; 505 ops.mode = MTD_OOB_PLACE;
507 506
508 if (ops.ooboffs && ops.len > (mtd->oobsize - ops.ooboffs)) 507 if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))
509 return -EINVAL; 508 return -EINVAL;
510 509
511 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL); 510 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL);
@@ -520,7 +519,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
520 buf.start &= ~(mtd->oobsize - 1); 519 buf.start &= ~(mtd->oobsize - 1);
521 ret = mtd->write_oob(mtd, buf.start, &ops); 520 ret = mtd->write_oob(mtd, buf.start, &ops);
522 521
523 if (copy_to_user(argp + sizeof(uint32_t), &ops.retlen, 522 if (copy_to_user(argp + sizeof(uint32_t), &ops.oobretlen,
524 sizeof(uint32_t))) 523 sizeof(uint32_t)))
525 ret = -EFAULT; 524 ret = -EFAULT;
526 525
@@ -548,7 +547,6 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
548 if (ret) 547 if (ret)
549 return ret; 548 return ret;
550 549
551 ops.len = buf.length;
552 ops.ooblen = buf.length; 550 ops.ooblen = buf.length;
553 ops.ooboffs = buf.start & (mtd->oobsize - 1); 551 ops.ooboffs = buf.start & (mtd->oobsize - 1);
554 ops.datbuf = NULL; 552 ops.datbuf = NULL;
@@ -564,10 +562,10 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
564 buf.start &= ~(mtd->oobsize - 1); 562 buf.start &= ~(mtd->oobsize - 1);
565 ret = mtd->read_oob(mtd, buf.start, &ops); 563 ret = mtd->read_oob(mtd, buf.start, &ops);
566 564
567 if (put_user(ops.retlen, (uint32_t __user *)argp)) 565 if (put_user(ops.oobretlen, (uint32_t __user *)argp))
568 ret = -EFAULT; 566 ret = -EFAULT;
569 else if (ops.retlen && copy_to_user(buf.ptr, ops.oobbuf, 567 else if (ops.oobretlen && copy_to_user(buf.ptr, ops.oobbuf,
570 ops.retlen)) 568 ops.oobretlen))
571 ret = -EFAULT; 569 ret = -EFAULT;
572 570
573 kfree(ops.oobbuf); 571 kfree(ops.oobbuf);
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 1fea631b5852..cf927a8803e7 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -247,7 +247,7 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
247 struct mtd_oob_ops devops = *ops; 247 struct mtd_oob_ops devops = *ops;
248 int i, err, ret = 0; 248 int i, err, ret = 0;
249 249
250 ops->retlen = 0; 250 ops->retlen = ops->oobretlen = 0;
251 251
252 for (i = 0; i < concat->num_subdev; i++) { 252 for (i = 0; i < concat->num_subdev; i++) {
253 struct mtd_info *subdev = concat->subdev[i]; 253 struct mtd_info *subdev = concat->subdev[i];
@@ -263,6 +263,7 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
263 263
264 err = subdev->read_oob(subdev, from, &devops); 264 err = subdev->read_oob(subdev, from, &devops);
265 ops->retlen += devops.retlen; 265 ops->retlen += devops.retlen;
266 ops->oobretlen += devops.oobretlen;
266 267
267 /* Save information about bitflips! */ 268 /* Save information about bitflips! */
268 if (unlikely(err)) { 269 if (unlikely(err)) {
@@ -278,14 +279,18 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
278 return err; 279 return err;
279 } 280 }
280 281
281 devops.len = ops->len - ops->retlen; 282 if (devops.datbuf) {
282 if (!devops.len) 283 devops.len = ops->len - ops->retlen;
283 return ret; 284 if (!devops.len)
284 285 return ret;
285 if (devops.datbuf)
286 devops.datbuf += devops.retlen; 286 devops.datbuf += devops.retlen;
287 if (devops.oobbuf) 287 }
288 devops.oobbuf += devops.ooblen; 288 if (devops.oobbuf) {
289 devops.ooblen = ops->ooblen - ops->oobretlen;
290 if (!devops.ooblen)
291 return ret;
292 devops.oobbuf += ops->oobretlen;
293 }
289 294
290 from = 0; 295 from = 0;
291 } 296 }
@@ -321,14 +326,18 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
321 if (err) 326 if (err)
322 return err; 327 return err;
323 328
324 devops.len = ops->len - ops->retlen; 329 if (devops.datbuf) {
325 if (!devops.len) 330 devops.len = ops->len - ops->retlen;
326 return 0; 331 if (!devops.len)
327 332 return 0;
328 if (devops.datbuf)
329 devops.datbuf += devops.retlen; 333 devops.datbuf += devops.retlen;
330 if (devops.oobbuf) 334 }
331 devops.oobbuf += devops.ooblen; 335 if (devops.oobbuf) {
336 devops.ooblen = ops->ooblen - ops->oobretlen;
337 if (!devops.ooblen)
338 return 0;
339 devops.oobbuf += devops.oobretlen;
340 }
332 to = 0; 341 to = 0;
333 } 342 }
334 return -EINVAL; 343 return -EINVAL;
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 06a930372b7a..a20f75fd8d61 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -94,7 +94,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from,
94 94
95 if (from >= mtd->size) 95 if (from >= mtd->size)
96 return -EINVAL; 96 return -EINVAL;
97 if (from + ops->len > mtd->size) 97 if (ops->datbuf && from + ops->len > mtd->size)
98 return -EINVAL; 98 return -EINVAL;
99 res = part->master->read_oob(part->master, from + part->offset, ops); 99 res = part->master->read_oob(part->master, from + part->offset, ops);
100 100
@@ -161,7 +161,7 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to,
161 161
162 if (to >= mtd->size) 162 if (to >= mtd->size)
163 return -EINVAL; 163 return -EINVAL;
164 if (to + ops->len > mtd->size) 164 if (ops->datbuf && to + ops->len > mtd->size)
165 return -EINVAL; 165 return -EINVAL;
166 return part->master->write_oob(part->master, to + part->offset, ops); 166 return part->master->write_oob(part->master, to + part->offset, ops);
167} 167}
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 564f79d16656..06627757f500 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -90,6 +90,7 @@ config MTD_NAND_RTC_FROM4
90 depends on MTD_NAND && SH_SOLUTION_ENGINE 90 depends on MTD_NAND && SH_SOLUTION_ENGINE
91 select REED_SOLOMON 91 select REED_SOLOMON
92 select REED_SOLOMON_DEC8 92 select REED_SOLOMON_DEC8
93 select BITREVERSE
93 help 94 help
94 This enables the driver for the Renesas Technology AG-AND 95 This enables the driver for the Renesas Technology AG-AND
95 flash interface board (FROM_BOARD4) 96 flash interface board (FROM_BOARD4)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index f23ab2c70433..5dcb2e066ce7 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -362,7 +362,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
362 * access 362 * access
363 */ 363 */
364 ofs += mtd->oobsize; 364 ofs += mtd->oobsize;
365 chip->ops.len = 2; 365 chip->ops.len = chip->ops.ooblen = 2;
366 chip->ops.datbuf = NULL; 366 chip->ops.datbuf = NULL;
367 chip->ops.oobbuf = buf; 367 chip->ops.oobbuf = buf;
368 chip->ops.ooboffs = chip->badblockpos & ~0x01; 368 chip->ops.ooboffs = chip->badblockpos & ~0x01;
@@ -897,12 +897,11 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
897 * @chip: nand chip structure 897 * @chip: nand chip structure
898 * @oob: oob destination address 898 * @oob: oob destination address
899 * @ops: oob ops structure 899 * @ops: oob ops structure
900 * @len: size of oob to transfer
900 */ 901 */
901static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, 902static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
902 struct mtd_oob_ops *ops) 903 struct mtd_oob_ops *ops, size_t len)
903{ 904{
904 size_t len = ops->ooblen;
905
906 switch(ops->mode) { 905 switch(ops->mode) {
907 906
908 case MTD_OOB_PLACE: 907 case MTD_OOB_PLACE:
@@ -960,6 +959,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
960 int sndcmd = 1; 959 int sndcmd = 1;
961 int ret = 0; 960 int ret = 0;
962 uint32_t readlen = ops->len; 961 uint32_t readlen = ops->len;
962 uint32_t oobreadlen = ops->ooblen;
963 uint8_t *bufpoi, *oob, *buf; 963 uint8_t *bufpoi, *oob, *buf;
964 964
965 stats = mtd->ecc_stats; 965 stats = mtd->ecc_stats;
@@ -1006,10 +1006,17 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1006 1006
1007 if (unlikely(oob)) { 1007 if (unlikely(oob)) {
1008 /* Raw mode does data:oob:data:oob */ 1008 /* Raw mode does data:oob:data:oob */
1009 if (ops->mode != MTD_OOB_RAW) 1009 if (ops->mode != MTD_OOB_RAW) {
1010 oob = nand_transfer_oob(chip, oob, ops); 1010 int toread = min(oobreadlen,
1011 else 1011 chip->ecc.layout->oobavail);
1012 buf = nand_transfer_oob(chip, buf, ops); 1012 if (toread) {
1013 oob = nand_transfer_oob(chip,
1014 oob, ops, toread);
1015 oobreadlen -= toread;
1016 }
1017 } else
1018 buf = nand_transfer_oob(chip,
1019 buf, ops, mtd->oobsize);
1013 } 1020 }
1014 1021
1015 if (!(chip->options & NAND_NO_READRDY)) { 1022 if (!(chip->options & NAND_NO_READRDY)) {
@@ -1056,6 +1063,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
1056 } 1063 }
1057 1064
1058 ops->retlen = ops->len - (size_t) readlen; 1065 ops->retlen = ops->len - (size_t) readlen;
1066 if (oob)
1067 ops->oobretlen = ops->ooblen - oobreadlen;
1059 1068
1060 if (ret) 1069 if (ret)
1061 return ret; 1070 return ret;
@@ -1256,12 +1265,18 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1256 int page, realpage, chipnr, sndcmd = 1; 1265 int page, realpage, chipnr, sndcmd = 1;
1257 struct nand_chip *chip = mtd->priv; 1266 struct nand_chip *chip = mtd->priv;
1258 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; 1267 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
1259 int readlen = ops->len; 1268 int readlen = ops->ooblen;
1269 int len;
1260 uint8_t *buf = ops->oobbuf; 1270 uint8_t *buf = ops->oobbuf;
1261 1271
1262 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n", 1272 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08Lx, len = %i\n",
1263 (unsigned long long)from, readlen); 1273 (unsigned long long)from, readlen);
1264 1274
1275 if (ops->mode == MTD_OOB_RAW)
1276 len = mtd->oobsize;
1277 else
1278 len = chip->ecc.layout->oobavail;
1279
1265 chipnr = (int)(from >> chip->chip_shift); 1280 chipnr = (int)(from >> chip->chip_shift);
1266 chip->select_chip(mtd, chipnr); 1281 chip->select_chip(mtd, chipnr);
1267 1282
@@ -1271,7 +1286,9 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1271 1286
1272 while(1) { 1287 while(1) {
1273 sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); 1288 sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd);
1274 buf = nand_transfer_oob(chip, buf, ops); 1289
1290 len = min(len, readlen);
1291 buf = nand_transfer_oob(chip, buf, ops, len);
1275 1292
1276 if (!(chip->options & NAND_NO_READRDY)) { 1293 if (!(chip->options & NAND_NO_READRDY)) {
1277 /* 1294 /*
@@ -1286,7 +1303,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1286 nand_wait_ready(mtd); 1303 nand_wait_ready(mtd);
1287 } 1304 }
1288 1305
1289 readlen -= ops->ooblen; 1306 readlen -= len;
1290 if (!readlen) 1307 if (!readlen)
1291 break; 1308 break;
1292 1309
@@ -1308,7 +1325,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1308 sndcmd = 1; 1325 sndcmd = 1;
1309 } 1326 }
1310 1327
1311 ops->retlen = ops->len; 1328 ops->oobretlen = ops->ooblen;
1312 return 0; 1329 return 0;
1313} 1330}
1314 1331
@@ -1329,7 +1346,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1329 ops->retlen = 0; 1346 ops->retlen = 0;
1330 1347
1331 /* Do not allow reads past end of device */ 1348 /* Do not allow reads past end of device */
1332 if ((from + ops->len) > mtd->size) { 1349 if (ops->datbuf && (from + ops->len) > mtd->size) {
1333 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " 1350 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1334 "Attempt read beyond end of device\n"); 1351 "Attempt read beyond end of device\n");
1335 return -EINVAL; 1352 return -EINVAL;
@@ -1654,6 +1671,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
1654 } 1671 }
1655 1672
1656 ops->retlen = ops->len - writelen; 1673 ops->retlen = ops->len - writelen;
1674 if (unlikely(oob))
1675 ops->oobretlen = ops->ooblen;
1657 return ret; 1676 return ret;
1658} 1677}
1659 1678
@@ -1709,10 +1728,10 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1709 struct nand_chip *chip = mtd->priv; 1728 struct nand_chip *chip = mtd->priv;
1710 1729
1711 DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", 1730 DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n",
1712 (unsigned int)to, (int)ops->len); 1731 (unsigned int)to, (int)ops->ooblen);
1713 1732
1714 /* Do not allow write past end of page */ 1733 /* Do not allow write past end of page */
1715 if ((ops->ooboffs + ops->len) > mtd->oobsize) { 1734 if ((ops->ooboffs + ops->ooblen) > mtd->oobsize) {
1716 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " 1735 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
1717 "Attempt to write past end of page\n"); 1736 "Attempt to write past end of page\n");
1718 return -EINVAL; 1737 return -EINVAL;
@@ -1748,7 +1767,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1748 if (status) 1767 if (status)
1749 return status; 1768 return status;
1750 1769
1751 ops->retlen = ops->len; 1770 ops->oobretlen = ops->ooblen;
1752 1771
1753 return 0; 1772 return 0;
1754} 1773}
@@ -1768,7 +1787,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
1768 ops->retlen = 0; 1787 ops->retlen = 0;
1769 1788
1770 /* Do not allow writes past end of device */ 1789 /* Do not allow writes past end of device */
1771 if ((to + ops->len) > mtd->size) { 1790 if (ops->datbuf && (to + ops->len) > mtd->size) {
1772 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: " 1791 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1773 "Attempt read beyond end of device\n"); 1792 "Attempt read beyond end of device\n");
1774 return -EINVAL; 1793 return -EINVAL;
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 9402653eb09b..4e74fe9af29e 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -333,7 +333,6 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
333 struct mtd_oob_ops ops; 333 struct mtd_oob_ops ops;
334 int j, ret; 334 int j, ret;
335 335
336 ops.len = mtd->oobsize;
337 ops.ooblen = mtd->oobsize; 336 ops.ooblen = mtd->oobsize;
338 ops.oobbuf = buf; 337 ops.oobbuf = buf;
339 ops.ooboffs = 0; 338 ops.ooboffs = 0;
@@ -676,10 +675,10 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
676 "bad block table\n"); 675 "bad block table\n");
677 } 676 }
678 /* Read oob data */ 677 /* Read oob data */
679 ops.len = (len >> this->page_shift) * mtd->oobsize; 678 ops.ooblen = (len >> this->page_shift) * mtd->oobsize;
680 ops.oobbuf = &buf[len]; 679 ops.oobbuf = &buf[len];
681 res = mtd->read_oob(mtd, to + mtd->writesize, &ops); 680 res = mtd->read_oob(mtd, to + mtd->writesize, &ops);
682 if (res < 0 || ops.retlen != ops.len) 681 if (res < 0 || ops.oobretlen != ops.ooblen)
683 goto outerr; 682 goto outerr;
684 683
685 /* Calc the byte offset in the buffer */ 684 /* Calc the byte offset in the buffer */
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index 039c759cfbfc..fd7a8d5ba29a 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -56,7 +56,7 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip)
56 ccr |= NDFC_CCR_BS(chip + pchip->chip_offset); 56 ccr |= NDFC_CCR_BS(chip + pchip->chip_offset);
57 } else 57 } else
58 ccr |= NDFC_CCR_RESET_CE; 58 ccr |= NDFC_CCR_RESET_CE;
59 writel(ccr, ndfc->ndfcbase + NDFC_CCR); 59 __raw_writel(ccr, ndfc->ndfcbase + NDFC_CCR);
60} 60}
61 61
62static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) 62static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c
index f8c49645324d..4a83a7dd58da 100644
--- a/drivers/mtd/nand/rtc_from4.c
+++ b/drivers/mtd/nand/rtc_from4.c
@@ -24,6 +24,7 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/rslib.h> 26#include <linux/rslib.h>
27#include <linux/bitrev.h>
27#include <linux/module.h> 28#include <linux/module.h>
28#include <linux/mtd/compatmac.h> 29#include <linux/mtd/compatmac.h>
29#include <linux/mtd/mtd.h> 30#include <linux/mtd/mtd.h>
@@ -152,47 +153,6 @@ static struct nand_ecclayout rtc_from4_nand_oobinfo = {
152 .oobfree = {{32, 32}} 153 .oobfree = {{32, 32}}
153}; 154};
154 155
155/* Aargh. I missed the reversed bit order, when I
156 * was talking to Renesas about the FPGA.
157 *
158 * The table is used for bit reordering and inversion
159 * of the ecc byte which we get from the FPGA
160 */
161static uint8_t revbits[256] = {
162 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
163 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
164 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
165 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
166 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
167 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
168 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
169 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
170 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
171 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
172 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
173 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
174 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
175 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
176 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
177 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
178 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
179 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
180 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
181 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
182 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
183 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
184 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
185 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
186 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
187 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
188 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
189 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
190 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
191 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
192 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
193 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
194};
195
196#endif 156#endif
197 157
198/* 158/*
@@ -397,7 +357,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
397 /* Read the syndrom pattern from the FPGA and correct the bitorder */ 357 /* Read the syndrom pattern from the FPGA and correct the bitorder */
398 rs_ecc = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC); 358 rs_ecc = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC);
399 for (i = 0; i < 8; i++) { 359 for (i = 0; i < 8; i++) {
400 ecc[i] = revbits[(*rs_ecc) & 0xFF]; 360 ecc[i] = byte_rev_table[(*rs_ecc) & 0xFF];
401 rs_ecc++; 361 rs_ecc++;
402 } 362 }
403 363
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index b5a5f8da4722..f4d38546068f 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -67,7 +67,7 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
67 67
68 nftl->mbd.mtd = mtd; 68 nftl->mbd.mtd = mtd;
69 nftl->mbd.devnum = -1; 69 nftl->mbd.devnum = -1;
70 nftl->mbd.blksize = 512; 70
71 nftl->mbd.tr = tr; 71 nftl->mbd.tr = tr;
72 72
73 if (NFTL_mount(nftl) < 0) { 73 if (NFTL_mount(nftl) < 0) {
@@ -147,10 +147,9 @@ int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
147 ops.ooblen = len; 147 ops.ooblen = len;
148 ops.oobbuf = buf; 148 ops.oobbuf = buf;
149 ops.datbuf = NULL; 149 ops.datbuf = NULL;
150 ops.len = len;
151 150
152 res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops); 151 res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
153 *retlen = ops.retlen; 152 *retlen = ops.oobretlen;
154 return res; 153 return res;
155} 154}
156 155
@@ -168,10 +167,9 @@ int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
168 ops.ooblen = len; 167 ops.ooblen = len;
169 ops.oobbuf = buf; 168 ops.oobbuf = buf;
170 ops.datbuf = NULL; 169 ops.datbuf = NULL;
171 ops.len = len;
172 170
173 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops); 171 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
174 *retlen = ops.retlen; 172 *retlen = ops.oobretlen;
175 return res; 173 return res;
176} 174}
177 175
@@ -797,6 +795,7 @@ static struct mtd_blktrans_ops nftl_tr = {
797 .name = "nftl", 795 .name = "nftl",
798 .major = NFTL_MAJOR, 796 .major = NFTL_MAJOR,
799 .part_bits = NFTL_PARTN_BITS, 797 .part_bits = NFTL_PARTN_BITS,
798 .blksize = 512,
800 .getgeo = nftl_getgeo, 799 .getgeo = nftl_getgeo,
801 .readsect = nftl_readblock, 800 .readsect = nftl_readblock,
802#ifdef CONFIG_NFTL_RW 801#ifdef CONFIG_NFTL_RW
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index fa4362fb4dd8..d60cc6696cbd 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -787,7 +787,6 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
787 787
788 if (scan_header(part) == 0) { 788 if (scan_header(part) == 0) {
789 part->mbd.size = part->sector_count; 789 part->mbd.size = part->sector_count;
790 part->mbd.blksize = SECTOR_SIZE;
791 part->mbd.tr = tr; 790 part->mbd.tr = tr;
792 part->mbd.devnum = -1; 791 part->mbd.devnum = -1;
793 if (!(mtd->flags & MTD_WRITEABLE)) 792 if (!(mtd->flags & MTD_WRITEABLE))
@@ -829,6 +828,8 @@ struct mtd_blktrans_ops rfd_ftl_tr = {
829 .name = "rfd", 828 .name = "rfd",
830 .major = RFD_FTL_MAJOR, 829 .major = RFD_FTL_MAJOR,
831 .part_bits = PART_BITS, 830 .part_bits = PART_BITS,
831 .blksize = SECTOR_SIZE,
832
832 .readsect = rfd_ftl_readsect, 833 .readsect = rfd_ftl_readsect,
833 .writesect = rfd_ftl_writesect, 834 .writesect = rfd_ftl_writesect,
834 .getgeo = rfd_ftl_getgeo, 835 .getgeo = rfd_ftl_getgeo,
diff --git a/drivers/mtd/ssfdc.c b/drivers/mtd/ssfdc.c
index 79d3bb659bfe..e834cc16c9f9 100644
--- a/drivers/mtd/ssfdc.c
+++ b/drivers/mtd/ssfdc.c
@@ -172,13 +172,12 @@ static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf)
172 172
173 ops.mode = MTD_OOB_RAW; 173 ops.mode = MTD_OOB_RAW;
174 ops.ooboffs = 0; 174 ops.ooboffs = 0;
175 ops.ooblen = mtd->oobsize; 175 ops.ooblen = OOB_SIZE;
176 ops.len = OOB_SIZE;
177 ops.oobbuf = buf; 176 ops.oobbuf = buf;
178 ops.datbuf = NULL; 177 ops.datbuf = NULL;
179 178
180 ret = mtd->read_oob(mtd, offs, &ops); 179 ret = mtd->read_oob(mtd, offs, &ops);
181 if (ret < 0 || ops.retlen != OOB_SIZE) 180 if (ret < 0 || ops.oobretlen != OOB_SIZE)
182 return -1; 181 return -1;
183 182
184 return 0; 183 return 0;