in pci.c [857:925]
static int ssb_pci_sprom_get(struct ssb_bus *bus,
struct ssb_sprom *sprom)
{
int err;
u16 *buf;
if (!ssb_is_sprom_available(bus)) {
pr_err("No SPROM available!\n");
return -ENODEV;
}
if (bus->chipco.dev) { /* can be unavailable! */
/*
* get SPROM offset: SSB_SPROM_BASE1 except for
* chipcommon rev >= 31 or chip ID is 0x4312 and
* chipcommon status & 3 == 2
*/
if (bus->chipco.dev->id.revision >= 31)
bus->sprom_offset = SSB_SPROM_BASE31;
else if (bus->chip_id == 0x4312 &&
(bus->chipco.status & 0x03) == 2)
bus->sprom_offset = SSB_SPROM_BASE31;
else
bus->sprom_offset = SSB_SPROM_BASE1;
} else {
bus->sprom_offset = SSB_SPROM_BASE1;
}
pr_debug("SPROM offset is 0x%x\n", bus->sprom_offset);
buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
if (!buf)
return -ENOMEM;
bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
sprom_do_read(bus, buf);
err = sprom_check_crc(buf, bus->sprom_size);
if (err) {
/* try for a 440 byte SPROM - revision 4 and higher */
kfree(buf);
buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
GFP_KERNEL);
if (!buf)
return -ENOMEM;
bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
sprom_do_read(bus, buf);
err = sprom_check_crc(buf, bus->sprom_size);
if (err) {
/* All CRC attempts failed.
* Maybe there is no SPROM on the device?
* Now we ask the arch code if there is some sprom
* available for this device in some other storage */
err = ssb_fill_sprom_with_fallback(bus, sprom);
if (err) {
pr_warn("WARNING: Using fallback SPROM failed (err %d)\n",
err);
goto out_free;
} else {
pr_debug("Using SPROM revision %d provided by platform\n",
sprom->revision);
err = 0;
goto out_free;
}
pr_warn("WARNING: Invalid SPROM CRC (corrupt SPROM)\n");
}
}
err = sprom_extract(bus, sprom, buf, bus->sprom_size);
out_free:
kfree(buf);
return err;
}