diff options
Diffstat (limited to 'drivers/ssb/pci.c')
-rw-r--r-- | drivers/ssb/pci.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index c958ac16423c..40ea41762247 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -564,6 +564,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, | |||
564 | static int ssb_pci_sprom_get(struct ssb_bus *bus, | 564 | static int ssb_pci_sprom_get(struct ssb_bus *bus, |
565 | struct ssb_sprom *sprom) | 565 | struct ssb_sprom *sprom) |
566 | { | 566 | { |
567 | const struct ssb_sprom *fallback; | ||
567 | int err = -ENOMEM; | 568 | int err = -ENOMEM; |
568 | u16 *buf; | 569 | u16 *buf; |
569 | 570 | ||
@@ -583,12 +584,23 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, | |||
583 | bus->sprom_size = SSB_SPROMSIZE_WORDS_R4; | 584 | bus->sprom_size = SSB_SPROMSIZE_WORDS_R4; |
584 | sprom_do_read(bus, buf); | 585 | sprom_do_read(bus, buf); |
585 | err = sprom_check_crc(buf, bus->sprom_size); | 586 | err = sprom_check_crc(buf, bus->sprom_size); |
586 | if (err) | 587 | if (err) { |
588 | /* All CRC attempts failed. | ||
589 | * Maybe there is no SPROM on the device? | ||
590 | * If we have a fallback, use that. */ | ||
591 | fallback = ssb_get_fallback_sprom(); | ||
592 | if (fallback) { | ||
593 | memcpy(sprom, fallback, sizeof(*sprom)); | ||
594 | err = 0; | ||
595 | goto out_free; | ||
596 | } | ||
587 | ssb_printk(KERN_WARNING PFX "WARNING: Invalid" | 597 | ssb_printk(KERN_WARNING PFX "WARNING: Invalid" |
588 | " SPROM CRC (corrupt SPROM)\n"); | 598 | " SPROM CRC (corrupt SPROM)\n"); |
599 | } | ||
589 | } | 600 | } |
590 | err = sprom_extract(bus, sprom, buf, bus->sprom_size); | 601 | err = sprom_extract(bus, sprom, buf, bus->sprom_size); |
591 | 602 | ||
603 | out_free: | ||
592 | kfree(buf); | 604 | kfree(buf); |
593 | out: | 605 | out: |
594 | return err; | 606 | return err; |