eprom.c (e2113752b783e387f9cb0d8b9d928c6f9fce08b3) eprom.c (107ffbc521b07f22c2e8d1c5fce39766c265c02c)
1/*
2 * Copyright(c) 2015, 2016 Intel Corporation.
3 *
4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license.
6 *
7 * GPL LICENSE SUMMARY
8 *

--- 189 unchanged lines hidden (view full) ---

198 /* wake the device with command "release powerdown NoID" */
199 write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_RELEASE_POWERDOWN_NOID);
200
201 dd->eprom_available = true;
202 release_chip_resource(dd, CR_EPROM);
203done_asic:
204 return ret;
205}
1/*
2 * Copyright(c) 2015, 2016 Intel Corporation.
3 *
4 * This file is provided under a dual BSD/GPLv2 license. When using or
5 * redistributing this file, you may do so under either license.
6 *
7 * GPL LICENSE SUMMARY
8 *

--- 189 unchanged lines hidden (view full) ---

198 /* wake the device with command "release powerdown NoID" */
199 write_csr(dd, ASIC_EEP_ADDR_CMD, CMD_RELEASE_POWERDOWN_NOID);
200
201 dd->eprom_available = true;
202 release_chip_resource(dd, CR_EPROM);
203done_asic:
204 return ret;
205}
206
207/* magic character sequence that trails an image */
208#define IMAGE_TRAIL_MAGIC "egamiAPO"
209
210/*
211 * Read all of partition 1. The actual file is at the front. Adjust
212 * the returned size if a trailing image magic is found.
213 */
214static int read_partition_platform_config(struct hfi1_devdata *dd, void **data,
215 u32 *size)
216{
217 void *buffer;
218 void *p;
219 u32 length;
220 int ret;
221
222 buffer = kmalloc(P1_SIZE, GFP_KERNEL);
223 if (!buffer)
224 return -ENOMEM;
225
226 ret = read_length(dd, P1_START, P1_SIZE, buffer);
227 if (ret) {
228 kfree(buffer);
229 return ret;
230 }
231
232 /* scan for image magic that may trail the actual data */
233 p = strnstr(buffer, IMAGE_TRAIL_MAGIC, P1_SIZE);
234 if (p)
235 length = p - buffer;
236 else
237 length = P1_SIZE;
238
239 *data = buffer;
240 *size = length;
241 return 0;
242}
243
244/*
245 * Read the platform configuration file from the EPROM.
246 *
247 * On success, an allocated buffer containing the data and its size are
248 * returned. It is up to the caller to free this buffer.
249 *
250 * Return value:
251 * 0 - success
252 * -ENXIO - no EPROM is available
253 * -EBUSY - not able to acquire access to the EPROM
254 * -ENOENT - no recognizable file written
255 * -ENOMEM - buffer could not be allocated
256 */
257int eprom_read_platform_config(struct hfi1_devdata *dd, void **data, u32 *size)
258{
259 u32 directory[EP_PAGE_DWORDS]; /* aligned buffer */
260 int ret;
261
262 if (!dd->eprom_available)
263 return -ENXIO;
264
265 ret = acquire_chip_resource(dd, CR_EPROM, EPROM_TIMEOUT);
266 if (ret)
267 return -EBUSY;
268
269 /* read the last page of P0 for the EPROM format magic */
270 ret = read_length(dd, P1_START - EP_PAGE_SIZE, EP_PAGE_SIZE, directory);
271 if (ret)
272 goto done;
273
274 /* last dword of P0 contains a magic indicator */
275 if (directory[EP_PAGE_DWORDS - 1] == 0) {
276 /* partition format */
277 ret = read_partition_platform_config(dd, data, size);
278 goto done;
279 }
280
281 /* nothing recognized */
282 ret = -ENOENT;
283
284done:
285 release_chip_resource(dd, CR_EPROM);
286 return ret;
287}