root/drivers/mtd/chips/gen_probe.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mtd_do_chip_probe
  2. genprobe_ident_chips
  3. genprobe_new_chip
  4. cfi_cmdset_unknown
  5. check_cmd_set

   1 /*
   2  * Routines common to all CFI-type probes.
   3  * (C) 2001-2003 Red Hat, Inc.
   4  * GPL'd
   5  */
   6 
   7 #include <linux/kernel.h>
   8 #include <linux/slab.h>
   9 #include <linux/module.h>
  10 #include <linux/mtd/mtd.h>
  11 #include <linux/mtd/map.h>
  12 #include <linux/mtd/cfi.h>
  13 #include <linux/mtd/gen_probe.h>
  14 
  15 static struct mtd_info *check_cmd_set(struct map_info *, int);
  16 static struct cfi_private *genprobe_ident_chips(struct map_info *map,
  17                                                 struct chip_probe *cp);
  18 static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,
  19                              struct cfi_private *cfi);
  20 
  21 struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp)
  22 {
  23         struct mtd_info *mtd;
  24         struct cfi_private *cfi;
  25 
  26         /* First probe the map to see if we have CFI stuff there. */
  27         cfi = genprobe_ident_chips(map, cp);
  28 
  29         if (!cfi)
  30                 return NULL;
  31 
  32         map->fldrv_priv = cfi;
  33         /* OK we liked it. Now find a driver for the command set it talks */
  34 
  35         mtd = check_cmd_set(map, 1); /* First the primary cmdset */
  36         if (!mtd)
  37                 mtd = check_cmd_set(map, 0); /* Then the secondary */
  38 
  39         if (mtd) {
  40                 if (mtd->size > map->size) {
  41                         printk(KERN_WARNING "Reducing visibility of %ldKiB chip to %ldKiB\n",
  42                                (unsigned long)mtd->size >> 10,
  43                                (unsigned long)map->size >> 10);
  44                         mtd->size = map->size;
  45                 }
  46                 return mtd;
  47         }
  48 
  49         printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n");
  50 
  51         kfree(cfi->cfiq);
  52         kfree(cfi);
  53         map->fldrv_priv = NULL;
  54         return NULL;
  55 }
  56 EXPORT_SYMBOL(mtd_do_chip_probe);
  57 
  58 
  59 static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe *cp)
  60 {
  61         struct cfi_private cfi;
  62         struct cfi_private *retcfi;
  63         unsigned long *chip_map;
  64         int i, j, mapsize;
  65         int max_chips;
  66 
  67         memset(&cfi, 0, sizeof(cfi));
  68 
  69         /* Call the probetype-specific code with all permutations of
  70            interleave and device type, etc. */
  71         if (!genprobe_new_chip(map, cp, &cfi)) {
  72                 /* The probe didn't like it */
  73                 pr_debug("%s: Found no %s device at location zero\n",
  74                          cp->name, map->name);
  75                 return NULL;
  76         }
  77 
  78 #if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD
  79          probe routines won't ever return a broken CFI structure anyway,
  80          because they make them up themselves.
  81       */
  82         if (cfi.cfiq->NumEraseRegions == 0) {
  83                 printk(KERN_WARNING "Number of erase regions is zero\n");
  84                 kfree(cfi.cfiq);
  85                 return NULL;
  86         }
  87 #endif
  88         cfi.chipshift = cfi.cfiq->DevSize;
  89 
  90         if (cfi_interleave_is_1(&cfi)) {
  91                 ;
  92         } else if (cfi_interleave_is_2(&cfi)) {
  93                 cfi.chipshift++;
  94         } else if (cfi_interleave_is_4((&cfi))) {
  95                 cfi.chipshift += 2;
  96         } else if (cfi_interleave_is_8(&cfi)) {
  97                 cfi.chipshift += 3;
  98         } else {
  99                 BUG();
 100         }
 101 
 102         cfi.numchips = 1;
 103 
 104         /*
 105          * Allocate memory for bitmap of valid chips.
 106          * Align bitmap storage size to full byte.
 107          */
 108         max_chips = map->size >> cfi.chipshift;
 109         if (!max_chips) {
 110                 printk(KERN_WARNING "NOR chip too large to fit in mapping. Attempting to cope...\n");
 111                 max_chips = 1;
 112         }
 113 
 114         mapsize = sizeof(long) * DIV_ROUND_UP(max_chips, BITS_PER_LONG);
 115         chip_map = kzalloc(mapsize, GFP_KERNEL);
 116         if (!chip_map) {
 117                 kfree(cfi.cfiq);
 118                 return NULL;
 119         }
 120 
 121         set_bit(0, chip_map); /* Mark first chip valid */
 122 
 123         /*
 124          * Now probe for other chips, checking sensibly for aliases while
 125          * we're at it. The new_chip probe above should have let the first
 126          * chip in read mode.
 127          */
 128 
 129         for (i = 1; i < max_chips; i++) {
 130                 cp->probe_chip(map, i << cfi.chipshift, chip_map, &cfi);
 131         }
 132 
 133         /*
 134          * Now allocate the space for the structures we need to return to
 135          * our caller, and copy the appropriate data into them.
 136          */
 137 
 138         retcfi = kmalloc(struct_size(retcfi, chips, cfi.numchips), GFP_KERNEL);
 139 
 140         if (!retcfi) {
 141                 kfree(cfi.cfiq);
 142                 kfree(chip_map);
 143                 return NULL;
 144         }
 145 
 146         memcpy(retcfi, &cfi, sizeof(cfi));
 147         memset(&retcfi->chips[0], 0, sizeof(struct flchip) * cfi.numchips);
 148 
 149         for (i = 0, j = 0; (j < cfi.numchips) && (i < max_chips); i++) {
 150                 if(test_bit(i, chip_map)) {
 151                         struct flchip *pchip = &retcfi->chips[j++];
 152 
 153                         pchip->start = (i << cfi.chipshift);
 154                         pchip->state = FL_READY;
 155                         init_waitqueue_head(&pchip->wq);
 156                         mutex_init(&pchip->mutex);
 157                 }
 158         }
 159 
 160         kfree(chip_map);
 161         return retcfi;
 162 }
 163 
 164 
 165 static int genprobe_new_chip(struct map_info *map, struct chip_probe *cp,
 166                              struct cfi_private *cfi)
 167 {
 168         int min_chips = (map_bankwidth(map)/4?:1); /* At most 4-bytes wide. */
 169         int max_chips = map_bankwidth(map); /* And minimum 1 */
 170         int nr_chips, type;
 171 
 172         for (nr_chips = max_chips; nr_chips >= min_chips; nr_chips >>= 1) {
 173 
 174                 if (!cfi_interleave_supported(nr_chips))
 175                     continue;
 176 
 177                 cfi->interleave = nr_chips;
 178 
 179                 /* Minimum device size. Don't look for one 8-bit device
 180                    in a 16-bit bus, etc. */
 181                 type = map_bankwidth(map) / nr_chips;
 182 
 183                 for (; type <= CFI_DEVICETYPE_X32; type<<=1) {
 184                         cfi->device_type = type;
 185 
 186                         if (cp->probe_chip(map, 0, NULL, cfi))
 187                                 return 1;
 188                 }
 189         }
 190         return 0;
 191 }
 192 
 193 typedef struct mtd_info *cfi_cmdset_fn_t(struct map_info *, int);
 194 
 195 extern cfi_cmdset_fn_t cfi_cmdset_0001;
 196 extern cfi_cmdset_fn_t cfi_cmdset_0002;
 197 extern cfi_cmdset_fn_t cfi_cmdset_0020;
 198 
 199 static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
 200                                                   int primary)
 201 {
 202         struct cfi_private *cfi = map->fldrv_priv;
 203         __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
 204 #ifdef CONFIG_MODULES
 205         cfi_cmdset_fn_t *probe_function;
 206         char *probename;
 207 
 208         probename = kasprintf(GFP_KERNEL, "cfi_cmdset_%4.4X", type);
 209         if (!probename)
 210                 return NULL;
 211 
 212         probe_function = __symbol_get(probename);
 213         if (!probe_function) {
 214                 request_module("cfi_cmdset_%4.4X", type);
 215                 probe_function = __symbol_get(probename);
 216         }
 217         kfree(probename);
 218 
 219         if (probe_function) {
 220                 struct mtd_info *mtd;
 221 
 222                 mtd = (*probe_function)(map, primary);
 223                 /* If it was happy, it'll have increased its own use count */
 224                 symbol_put_addr(probe_function);
 225                 return mtd;
 226         }
 227 #endif
 228         printk(KERN_NOTICE "Support for command set %04X not present\n", type);
 229 
 230         return NULL;
 231 }
 232 
 233 static struct mtd_info *check_cmd_set(struct map_info *map, int primary)
 234 {
 235         struct cfi_private *cfi = map->fldrv_priv;
 236         __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
 237 
 238         if (type == P_ID_NONE || type == P_ID_RESERVED)
 239                 return NULL;
 240 
 241         switch(type){
 242                 /* We need these for the !CONFIG_MODULES case,
 243                    because symbol_get() doesn't work there */
 244 #ifdef CONFIG_MTD_CFI_INTELEXT
 245         case P_ID_INTEL_EXT:
 246         case P_ID_INTEL_STD:
 247         case P_ID_INTEL_PERFORMANCE:
 248                 return cfi_cmdset_0001(map, primary);
 249 #endif
 250 #ifdef CONFIG_MTD_CFI_AMDSTD
 251         case P_ID_AMD_STD:
 252         case P_ID_SST_OLD:
 253         case P_ID_WINBOND:
 254                 return cfi_cmdset_0002(map, primary);
 255 #endif
 256 #ifdef CONFIG_MTD_CFI_STAA
 257         case P_ID_ST_ADV:
 258                 return cfi_cmdset_0020(map, primary);
 259 #endif
 260         default:
 261                 return cfi_cmdset_unknown(map, primary);
 262         }
 263 }
 264 
 265 MODULE_LICENSE("GPL");
 266 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
 267 MODULE_DESCRIPTION("Helper routines for flash chip probe code");

/* [<][>][^][v][top][bottom][index][help] */