Skip to content

Commit

Permalink
IB/hfi1: Add ability to read platform config from the EPROM
Browse files Browse the repository at this point in the history
Add a function to read the platform configuration file from
the EPROM.

Reviewed-by: Easwar Hariharan <easwar.hariharan@intel.com>
Signed-off-by: Dean Luick <dean.luick@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
  • Loading branch information
Dean Luick authored and Doug Ledford committed Oct 2, 2016
1 parent e211375 commit 107ffbc
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
82 changes: 82 additions & 0 deletions drivers/infiniband/hw/hfi1/eprom.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 2 additions & 0 deletions drivers/infiniband/hw/hfi1/eprom.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

0 comments on commit 107ffbc

Please sign in to comment.