|
@@ -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;
|
|
|
+}
|