drivers/mtd/chips/gen_probe.c

Source file repositories/reference/linux-study-clean/drivers/mtd/chips/gen_probe.c

File Facts

System
Linux kernel
Corpus path
drivers/mtd/chips/gen_probe.c
Extension
.c
Size
6729 bytes
Lines
267
Domain
Driver Families
Bucket
drivers/mtd
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (mtd->size > map->size) {
			printk(KERN_WARNING "Reducing visibility of %ldKiB chip to %ldKiB\n",
			       (unsigned long)mtd->size >> 10,
			       (unsigned long)map->size >> 10);
			mtd->size = map->size;
		}
		return mtd;
	}

	printk(KERN_WARNING"gen_probe: No supported Vendor Command Set found\n");

	kfree(cfi->cfiq);
	kfree(cfi);
	map->fldrv_priv = NULL;
	return NULL;
}
EXPORT_SYMBOL(mtd_do_chip_probe);


static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe *cp)
{
	struct cfi_private cfi;
	struct cfi_private *retcfi;
	unsigned long *chip_map;
	int max_chips;
	int i, j;

	memset(&cfi, 0, sizeof(cfi));

	/* Call the probetype-specific code with all permutations of
	   interleave and device type, etc. */
	if (!genprobe_new_chip(map, cp, &cfi)) {
		/* The probe didn't like it */
		pr_debug("%s: Found no %s device at location zero\n",
			 cp->name, map->name);
		return NULL;
	}

#if 0 /* Let the CFI probe routine do this sanity check. The Intel and AMD
	 probe routines won't ever return a broken CFI structure anyway,
	 because they make them up themselves.
      */
	if (cfi.cfiq->NumEraseRegions == 0) {
		printk(KERN_WARNING "Number of erase regions is zero\n");
		kfree(cfi.cfiq);
		return NULL;
	}
#endif
	cfi.chipshift = cfi.cfiq->DevSize;

	if (cfi_interleave_is_1(&cfi)) {
		;
	} else if (cfi_interleave_is_2(&cfi)) {
		cfi.chipshift++;
	} else if (cfi_interleave_is_4((&cfi))) {
		cfi.chipshift += 2;
	} else if (cfi_interleave_is_8(&cfi)) {
		cfi.chipshift += 3;
	} else {
		BUG();
	}

	cfi.numchips = 1;

	/*
	 * Allocate memory for bitmap of valid chips.
	 * Align bitmap storage size to full byte.
	 */
	max_chips = map->size >> cfi.chipshift;
	if (!max_chips) {
		printk(KERN_WARNING "NOR chip too large to fit in mapping. Attempting to cope...\n");
		max_chips = 1;
	}

	chip_map = bitmap_zalloc(max_chips, GFP_KERNEL);
	if (!chip_map) {
		kfree(cfi.cfiq);
		return NULL;
	}

	set_bit(0, chip_map); /* Mark first chip valid */

	/*
	 * Now probe for other chips, checking sensibly for aliases while
	 * we're at it. The new_chip probe above should have let the first
	 * chip in read mode.
	 */

	for (i = 1; i < max_chips; i++) {
		cp->probe_chip(map, i << cfi.chipshift, chip_map, &cfi);

Annotation

Implementation Notes