int bcma_bus_scan()

in scan.c [456:524]


int bcma_bus_scan(struct bcma_bus *bus)
{
	u32 erombase;
	u32 __iomem *eromptr, *eromend;

	int err, core_num = 0;

	/* Skip if bus was already scanned (e.g. during early register) */
	if (bus->nr_cores)
		return 0;

	erombase = bcma_scan_read32(bus, BCMA_CC_EROM);
	if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
		eromptr = ioremap(erombase, BCMA_CORE_SIZE);
		if (!eromptr)
			return -ENOMEM;
	} else {
		eromptr = bus->mmio;
	}

	eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);

	bcma_scan_switch_core(bus, erombase);

	while (eromptr < eromend) {
		struct bcma_device *other_core;
		struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
		if (!core) {
			err = -ENOMEM;
			goto out;
		}
		INIT_LIST_HEAD(&core->list);
		core->bus = bus;

		err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
		if (err < 0) {
			kfree(core);
			if (err == -ENODEV) {
				core_num++;
				continue;
			} else if (err == -ENXIO) {
				continue;
			} else if (err == -ESPIPE) {
				break;
			}
			goto out;
		}

		core->core_index = core_num++;
		bus->nr_cores++;
		other_core = bcma_find_core_reverse(bus, core->id.id);
		core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
		bcma_prepare_core(bus, core);

		bcma_info(bus, "Core %d found: %s (manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
			  core->core_index, bcma_device_name(&core->id),
			  core->id.manuf, core->id.id, core->id.rev,
			  core->id.class);

		list_add_tail(&core->list, &bus->cores);
	}

	err = 0;
out:
	if (bus->hosttype == BCMA_HOSTTYPE_SOC)
		iounmap(eromptr);

	return err;
}