diff options
Diffstat (limited to 'drivers/mtd/chips/gen_probe.c')
-rw-r--r-- | drivers/mtd/chips/gen_probe.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c index 41bd59d20d85..cdb0f590b40c 100644 --- a/drivers/mtd/chips/gen_probe.c +++ b/drivers/mtd/chips/gen_probe.c | |||
@@ -37,8 +37,15 @@ struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp) | |||
37 | if (!mtd) | 37 | if (!mtd) |
38 | mtd = check_cmd_set(map, 0); /* Then the secondary */ | 38 | mtd = check_cmd_set(map, 0); /* Then the secondary */ |
39 | 39 | ||
40 | if (mtd) | 40 | if (mtd) { |
41 | if (mtd->size > map->size) { | ||
42 | printk(KERN_WARNING "Reducing visibility of %ldKiB chip to %ldKiB\n", | ||
43 | (unsigned long)mtd->size >> 10, | ||
44 | (unsigned long)map->size >> 10); | ||
45 | mtd->size = map->size; | ||
46 | } | ||
41 | return mtd; | 47 | return mtd; |
48 | } | ||
42 | 49 | ||
43 | printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n"); | 50 | printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n"); |
44 | 51 | ||
@@ -100,7 +107,12 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi | |||
100 | * Align bitmap storage size to full byte. | 107 | * Align bitmap storage size to full byte. |
101 | */ | 108 | */ |
102 | max_chips = map->size >> cfi.chipshift; | 109 | max_chips = map->size >> cfi.chipshift; |
103 | mapsize = (max_chips / 8) + ((max_chips % 8) ? 1 : 0); | 110 | if (!max_chips) { |
111 | printk(KERN_WARNING "NOR chip too large to fit in mapping. Attempting to cope...\n"); | ||
112 | max_chips = 1; | ||
113 | } | ||
114 | |||
115 | mapsize = (max_chips + BITS_PER_LONG-1) / BITS_PER_LONG; | ||
104 | chip_map = kmalloc(mapsize, GFP_KERNEL); | 116 | chip_map = kmalloc(mapsize, GFP_KERNEL); |
105 | if (!chip_map) { | 117 | if (!chip_map) { |
106 | printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name); | 118 | printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name); |
@@ -194,25 +206,28 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map, | |||
194 | { | 206 | { |
195 | struct cfi_private *cfi = map->fldrv_priv; | 207 | struct cfi_private *cfi = map->fldrv_priv; |
196 | __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; | 208 | __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; |
197 | #if defined(CONFIG_MODULES) && defined(HAVE_INTER_MODULE) | 209 | #ifdef CONFIG_MODULES |
198 | char probename[32]; | 210 | char probename[16+sizeof(MODULE_SYMBOL_PREFIX)]; |
199 | cfi_cmdset_fn_t *probe_function; | 211 | cfi_cmdset_fn_t *probe_function; |
200 | 212 | ||
201 | sprintf(probename, "cfi_cmdset_%4.4X", type); | 213 | sprintf(probename, MODULE_SYMBOL_PREFIX "cfi_cmdset_%4.4X", type); |
202 | 214 | ||
203 | probe_function = inter_module_get_request(probename, probename); | 215 | probe_function = __symbol_get(probename); |
216 | if (!probe_function) { | ||
217 | request_module(probename + sizeof(MODULE_SYMBOL_PREFIX) - 1); | ||
218 | probe_function = __symbol_get(probename); | ||
219 | } | ||
204 | 220 | ||
205 | if (probe_function) { | 221 | if (probe_function) { |
206 | struct mtd_info *mtd; | 222 | struct mtd_info *mtd; |
207 | 223 | ||
208 | mtd = (*probe_function)(map, primary); | 224 | mtd = (*probe_function)(map, primary); |
209 | /* If it was happy, it'll have increased its own use count */ | 225 | /* If it was happy, it'll have increased its own use count */ |
210 | inter_module_put(probename); | 226 | symbol_put_addr(probe_function); |
211 | return mtd; | 227 | return mtd; |
212 | } | 228 | } |
213 | #endif | 229 | #endif |
214 | printk(KERN_NOTICE "Support for command set %04X not present\n", | 230 | printk(KERN_NOTICE "Support for command set %04X not present\n", type); |
215 | type); | ||
216 | 231 | ||
217 | return NULL; | 232 | return NULL; |
218 | } | 233 | } |
@@ -226,12 +241,8 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary) | |||
226 | return NULL; | 241 | return NULL; |
227 | 242 | ||
228 | switch(type){ | 243 | switch(type){ |
229 | /* Urgh. Ifdefs. The version with weak symbols was | 244 | /* We need these for the !CONFIG_MODULES case, |
230 | * _much_ nicer. Shame it didn't seem to work on | 245 | because symbol_get() doesn't work there */ |
231 | * anything but x86, really. | ||
232 | * But we can't rely in inter_module_get() because | ||
233 | * that'd mean we depend on link order. | ||
234 | */ | ||
235 | #ifdef CONFIG_MTD_CFI_INTELEXT | 246 | #ifdef CONFIG_MTD_CFI_INTELEXT |
236 | case 0x0001: | 247 | case 0x0001: |
237 | case 0x0003: | 248 | case 0x0003: |
@@ -246,9 +257,9 @@ static struct mtd_info *check_cmd_set(struct map_info *map, int primary) | |||
246 | case 0x0020: | 257 | case 0x0020: |
247 | return cfi_cmdset_0020(map, primary); | 258 | return cfi_cmdset_0020(map, primary); |
248 | #endif | 259 | #endif |
260 | default: | ||
261 | return cfi_cmdset_unknown(map, primary); | ||
249 | } | 262 | } |
250 | |||
251 | return cfi_cmdset_unknown(map, primary); | ||
252 | } | 263 | } |
253 | 264 | ||
254 | MODULE_LICENSE("GPL"); | 265 | MODULE_LICENSE("GPL"); |