drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c

Source file repositories/reference/linux-study-clean/drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c

File Facts

System
Linux kernel
Corpus path
drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c
Extension
.c
Size
7398 bytes
Lines
286
Domain
Driver Families
Bucket
drivers/net
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 mcp251xfd_dump_iter {
	void *start;
	struct mcp251xfd_dump_object_header *hdr;
	void *data;
};

struct mcp251xfd_dump_reg_space {
	u16 base;
	u16 size;
};

struct mcp251xfd_dump_ring {
	enum mcp251xfd_dump_object_ring_key key;
	u32 val;
};

static const struct mcp251xfd_dump_reg_space mcp251xfd_dump_reg_space[] = {
	{
		.base = MCP251XFD_REG_CON,
		.size = MCP251XFD_REG_FLTOBJ(32) - MCP251XFD_REG_CON,
	}, {
		.base = MCP251XFD_RAM_START,
		.size = MCP251XFD_RAM_SIZE,
	}, {
		.base = MCP251XFD_REG_OSC,
		.size = MCP251XFD_REG_DEVID - MCP251XFD_REG_OSC,
	},
};

static void mcp251xfd_dump_header(struct mcp251xfd_dump_iter *iter,
				  enum mcp251xfd_dump_object_type object_type,
				  const void *data_end)
{
	struct mcp251xfd_dump_object_header *hdr = iter->hdr;
	unsigned int len;

	len = data_end - iter->data;
	if (!len)
		return;

	hdr->magic = cpu_to_le32(MCP251XFD_DUMP_MAGIC);
	hdr->type = cpu_to_le32(object_type);
	hdr->offset = cpu_to_le32(iter->data - iter->start);
	hdr->len = cpu_to_le32(len);

	iter->hdr++;
	iter->data += len;
}

static void mcp251xfd_dump_registers(const struct mcp251xfd_priv *priv,
				     struct mcp251xfd_dump_iter *iter)
{
	const int val_bytes = regmap_get_val_bytes(priv->map_rx);
	struct mcp251xfd_dump_object_reg *reg = iter->data;
	unsigned int i, j;
	int err;

	for (i = 0; i < ARRAY_SIZE(mcp251xfd_dump_reg_space); i++) {
		const struct mcp251xfd_dump_reg_space *reg_space;
		void *buf;

		reg_space = &mcp251xfd_dump_reg_space[i];

		buf = kmalloc(reg_space->size, GFP_KERNEL);
		if (!buf)
			goto out;

		err = regmap_bulk_read(priv->map_reg, reg_space->base,
				       buf, reg_space->size / val_bytes);
		if (err) {
			kfree(buf);
			continue;
		}

		for (j = 0; j < reg_space->size; j += sizeof(u32), reg++) {
			reg->reg = cpu_to_le32(reg_space->base + j);
			reg->val = cpu_to_le32p(buf + j);
		}

		kfree(buf);
	}

out:
	mcp251xfd_dump_header(iter, MCP251XFD_DUMP_OBJECT_TYPE_REG, reg);
}

static void mcp251xfd_dump_ring(struct mcp251xfd_dump_iter *iter,
				enum mcp251xfd_dump_object_type object_type,
				const struct mcp251xfd_dump_ring *dump_ring,
				unsigned int len)

Annotation

Implementation Notes