예제 #1
0
파일: eprom.c 프로젝트: acton393/linux
/*
 * 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;
}
예제 #2
0
파일: eprom.c 프로젝트: AshishNamdev/linux
/*
 * 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;
}
예제 #3
0
파일: eprom.c 프로젝트: acton393/linux
/*
 * 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;
}