/* * Read the platform configuration file from the EPROM. * * On success, an allocated buffer containing the data and its size are * returned. It is up to the caller to free this buffer. * * Return value: * 0 - success * -ENXIO - no EPROM is available * -EBUSY - not able to acquire access to the EPROM * -ENOENT - no recognizable file written * -ENOMEM - buffer could not be allocated */ int eprom_read_platform_config(struct hfi1_devdata *dd, void **data, u32 *size) { u32 directory[EP_PAGE_DWORDS]; /* aligned buffer */ int ret; if (!dd->eprom_available) return -ENXIO; ret = acquire_chip_resource(dd, CR_EPROM, EPROM_TIMEOUT); if (ret) return -EBUSY; /* read the last page of P0 for the EPROM format magic */ ret = read_length(dd, P1_START - EP_PAGE_SIZE, EP_PAGE_SIZE, directory); if (ret) goto done; /* last dword of P0 contains a magic indicator */ if (directory[EP_PAGE_DWORDS - 1] == 0) { /* partition format */ ret = read_partition_platform_config(dd, data, size); goto done; } /* nothing recognized */ ret = -ENOENT; done: release_chip_resource(dd, CR_EPROM); return ret; }
/* * Read the platform configuration file from the EPROM. * * On success, an allocated buffer containing the data and its size are * returned. It is up to the caller to free this buffer. * * Return value: * 0 - success * -ENXIO - no EPROM is available * -EBUSY - not able to acquire access to the EPROM * -ENOENT - no recognizable file written * -ENOMEM - buffer could not be allocated * -EINVAL - invalid EPROM contentents found */ int eprom_read_platform_config(struct hfi1_devdata *dd, void **data, u32 *size) { u32 directory[EP_PAGE_DWORDS]; /* aligned buffer */ int ret; if (!dd->eprom_available) return -ENXIO; ret = acquire_chip_resource(dd, CR_EPROM, EPROM_TIMEOUT); if (ret) return -EBUSY; /* read the last page of the segment for the EPROM format magic */ ret = read_length(dd, SEG_SIZE - EP_PAGE_SIZE, EP_PAGE_SIZE, directory); if (ret) goto done; /* last dword of the segment contains a magic value */ if (directory[EP_PAGE_DWORDS - 1] == FOOTER_MAGIC) { /* segment format */ ret = read_segment_platform_config(dd, directory, data, size); } else { /* partition format */ ret = read_partition_platform_config(dd, data, size); } done: release_chip_resource(dd, CR_EPROM); return ret; }
/* * Initialize the EPROM handler. */ int eprom_init(struct hfi1_devdata *dd) { int ret = 0; /* only the discrete chip has an EPROM */ if (dd->pcidev->device != PCI_DEVICE_ID_INTEL0) return 0; /* * It is OK if both HFIs reset the EPROM as long as they don't * do it at the same time. */ ret = acquire_chip_resource(dd, CR_EPROM, EPROM_TIMEOUT); if (ret) { dd_dev_err(dd, "%s: unable to acquire EPROM resource, no EPROM support\n", __func__); goto done_asic; } /* reset EPROM to be sure it is in a good state */ /* set reset */ write_csr(dd, ASIC_EEP_CTL_STAT, ASIC_EEP_CTL_STAT_EP_RESET_SMASK); /* clear reset, set speed */ write_csr(dd, ASIC_EEP_CTL_STAT, EP_SPEED_FULL << ASIC_EEP_CTL_STAT_RATE_SPI_SHIFT); /* wake the device with command "release powerdown NoID" */ write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_RELEASE_POWERDOWN_NOID); dd->eprom_available = true; release_chip_resource(dd, CR_EPROM); done_asic: return ret; }