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