Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 107ffbc5 authored by Dean Luick's avatar Dean Luick Committed by Doug Ledford
Browse files

IB/hfi1: Add ability to read platform config from the EPROM



Add a function to read the platform configuration file from
the EPROM.

Reviewed-by: default avatarEaswar Hariharan <easwar.hariharan@intel.com>
Signed-off-by: default avatarDean Luick <dean.luick@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent e2113752
Loading
Loading
Loading
Loading
+82 −0
Original line number Diff line number Diff line
@@ -203,3 +203,85 @@ int eprom_init(struct hfi1_devdata *dd)
done_asic:
	return ret;
}

/* magic character sequence that trails an image */
#define IMAGE_TRAIL_MAGIC "egamiAPO"

/*
 * Read all of partition 1.  The actual file is at the front.  Adjust
 * the returned size if a trailing image magic is found.
 */
static int read_partition_platform_config(struct hfi1_devdata *dd, void **data,
					  u32 *size)
{
	void *buffer;
	void *p;
	u32 length;
	int ret;

	buffer = kmalloc(P1_SIZE, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;

	ret = read_length(dd, P1_START, P1_SIZE, buffer);
	if (ret) {
		kfree(buffer);
		return ret;
	}

	/* scan for image magic that may trail the actual data */
	p = strnstr(buffer, IMAGE_TRAIL_MAGIC, P1_SIZE);
	if (p)
		length = p - buffer;
	else
		length = P1_SIZE;

	*data = buffer;
	*size = length;
	return 0;
}

/*
 * 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
Original line number Diff line number Diff line
@@ -48,3 +48,5 @@
struct hfi1_devdata;

int eprom_init(struct hfi1_devdata *dd);
int eprom_read_platform_config(struct hfi1_devdata *dd, void **buf_ret,
			       u32 *size_ret);