drivers/infiniband/hw/hfi1/eprom.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/hfi1/eprom.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/hfi1/eprom.c
Extension
.c
Size
11519 bytes
Lines
451
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct hfi1_eprom_footer {
	u32 oprom_size;		/* size of the oprom, in bytes */
	u16 num_table_entries;
	u16 version;		/* version of this footer */
	u32 magic;		/* must be last */
};

struct hfi1_eprom_table_entry {
	u32 type;		/* file type */
	u32 offset;		/* file offset from start of EPROM */
	u32 size;		/* file size, in bytes */
};

/*
 * Calculate the max number of table entries that will fit within a directory
 * buffer of size 'dir_size'.
 */
#define MAX_TABLE_ENTRIES(dir_size) \
	(((dir_size) - sizeof(struct hfi1_eprom_footer)) / \
		sizeof(struct hfi1_eprom_table_entry))

#define DIRECTORY_SIZE(n) (sizeof(struct hfi1_eprom_footer) + \
	(sizeof(struct hfi1_eprom_table_entry) * (n)))

#define MAGIC4(a, b, c, d) ((d) << 24 | (c) << 16 | (b) << 8 | (a))
#define FOOTER_MAGIC MAGIC4('e', 'p', 'r', 'm')
#define FOOTER_VERSION 1

/*
 * 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;
	}

	/* config partition is valid only if it starts with IMAGE_START_MAGIC */
	if (memcmp(buffer, IMAGE_START_MAGIC, strlen(IMAGE_START_MAGIC))) {
		kfree(buffer);
		return -ENOENT;
	}

	/* 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;
}

/*
 * The segment magic has been checked.  There is a footer and table of
 * contents present.
 *
 * directory is a u32 aligned buffer of size EP_PAGE_SIZE.
 */
static int read_segment_platform_config(struct hfi1_devdata *dd,
					void *directory, void **data, u32 *size)
{
	struct hfi1_eprom_footer *footer;
	struct hfi1_eprom_table_entry *table;
	struct hfi1_eprom_table_entry *entry;
	void *buffer = NULL;
	void *table_buffer = NULL;
	int ret, i;
	u32 directory_size;
	u32 seg_base, seg_offset;
	u32 bytes_available, ncopied, to_copy;

	/* the footer is at the end of the directory */
	footer = (struct hfi1_eprom_footer *)
			(directory + EP_PAGE_SIZE - sizeof(*footer));

Annotation

Implementation Notes