aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/chips/gen_probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/chips/gen_probe.c')
-rw-r--r--drivers/mtd/chips/gen_probe.c45
1 files changed, 28 insertions, 17 deletions
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c
index 41bd59d20d8..cdb0f590b40 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
254MODULE_LICENSE("GPL"); 265MODULE_LICENSE("GPL");