diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/cmdlinepart.c | 2 | ||||
-rw-r--r-- | drivers/mtd/ftl.c | 3 | ||||
-rw-r--r-- | drivers/mtd/inftlcore.c | 9 | ||||
-rw-r--r-- | drivers/mtd/maps/Kconfig | 9 | ||||
-rw-r--r-- | drivers/mtd/maps/Makefile | 1 | ||||
-rw-r--r-- | drivers/mtd/maps/ck804xrom.c | 356 | ||||
-rw-r--r-- | drivers/mtd/mtd_blkdevs.c | 15 | ||||
-rw-r--r-- | drivers/mtd/mtdblock.c | 3 | ||||
-rw-r--r-- | drivers/mtd/mtdblock_ro.c | 3 | ||||
-rw-r--r-- | drivers/mtd/mtdchar.c | 12 | ||||
-rw-r--r-- | drivers/mtd/mtdconcat.c | 39 | ||||
-rw-r--r-- | drivers/mtd/mtdpart.c | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/Kconfig | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 53 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_bbt.c | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/ndfc.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/rtc_from4.c | 44 | ||||
-rw-r--r-- | drivers/mtd/nftlcore.c | 9 | ||||
-rw-r--r-- | drivers/mtd/rfd_ftl.c | 3 | ||||
-rw-r--r-- | drivers/mtd/ssfdc.c | 5 |
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 | */ |
349 | int mtdpart_setup(char *s) | 349 | static 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 | ||
196 | config 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 | |||
196 | config MTD_SCB2_FLASH | 205 | config 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 | |||
19 | obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o | 19 | obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o |
20 | obj-$(CONFIG_MTD_ESB2ROM) += esb2rom.o | 20 | obj-$(CONFIG_MTD_ESB2ROM) += esb2rom.o |
21 | obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o | 21 | obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o |
22 | obj-$(CONFIG_MTD_CK804XROM) += ck804xrom.o | ||
22 | obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o | 23 | obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o |
23 | obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o | 24 | obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o |
24 | obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o | 25 | obj-$(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 | |||
31 | struct 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 | |||
40 | struct 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 | */ | ||
62 | static uint win_size_bits = 0; | ||
63 | module_param(win_size_bits, uint, 0); | ||
64 | MODULE_PARM_DESC(win_size_bits, "ROM window size bits override for 0x88 byte, normally set by BIOS."); | ||
65 | |||
66 | static struct ck804xrom_window ck804xrom_window = { | ||
67 | .maps = LIST_HEAD_INIT(ck804xrom_window.maps), | ||
68 | }; | ||
69 | |||
70 | static 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 | |||
104 | static 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 | |||
298 | static void __devexit ck804xrom_remove_one (struct pci_dev *pdev) | ||
299 | { | ||
300 | struct ck804xrom_window *window = &ck804xrom_window; | ||
301 | |||
302 | ck804xrom_cleanup(window); | ||
303 | } | ||
304 | |||
305 | static 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 | |||
311 | MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl); | ||
312 | |||
313 | #if 0 | ||
314 | static 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 | |||
322 | static 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 | |||
345 | static void __exit cleanup_ck804xrom(void) | ||
346 | { | ||
347 | ck804xrom_remove_one(ck804xrom_window.pdev); | ||
348 | } | ||
349 | |||
350 | module_init(init_ck804xrom); | ||
351 | module_exit(cleanup_ck804xrom); | ||
352 | |||
353 | MODULE_LICENSE("GPL"); | ||
354 | MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>, Dave Olsen <dolsen@lnxi.com>"); | ||
355 | MODULE_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 | */ |
901 | static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, | 902 | static 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 | ||
62 | static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 62 | static 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 | */ | ||
161 | static 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; |