drivers/net/wireless/mediatek/mt76/mt7915/coredump.c

Source file repositories/reference/linux-study-clean/drivers/net/wireless/mediatek/mt76/mt7915/coredump.c

File Facts

System
Linux kernel
Corpus path
drivers/net/wireless/mediatek/mt76/mt7915/coredump.c
Extension
.c
Size
10233 bytes
Lines
412
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

if (!id && idx == 3) {
			strscpy(dump->fw_context, "(context) idle",
				sizeof(dump->fw_context));
		} else if (id && idx != 3) {
			strscpy(dump->fw_context, "(context) task",
				sizeof(dump->fw_context));

			dump->context.idx = idx;
			dump->context.handler = id;
		}
	}
}

static struct mt7915_coredump *mt7915_coredump_build(struct mt7915_dev *dev)
{
	struct mt7915_crash_data *crash_data = dev->coredump.crash_data;
	struct mt7915_coredump *dump;
	struct mt7915_coredump_mem *dump_mem;
	size_t len, sofar = 0, hdr_len = sizeof(*dump);
	unsigned char *buf;
	bool exception;

	len = hdr_len;

	if (coredump_memdump && crash_data->memdump_buf_len)
		len += sizeof(*dump_mem) + crash_data->memdump_buf_len;

	sofar += hdr_len;

	/* this is going to get big when we start dumping memory and such,
	 * so go ahead and use vmalloc.
	 */
	buf = vzalloc(len);
	if (!buf)
		return NULL;

	mutex_lock(&dev->dump_mutex);

	dump = (struct mt7915_coredump *)(buf);
	dump->len = len;

	/* plain text */
	strscpy(dump->magic, "mt76-crash-dump", sizeof(dump->magic));
	strscpy(dump->kernel, init_utsname()->release, sizeof(dump->kernel));
	strscpy(dump->fw_ver, dev->mt76.hw->wiphy->fw_version,
		sizeof(dump->fw_ver));

	guid_copy(&dump->guid, &crash_data->guid);
	dump->tv_sec = crash_data->timestamp.tv_sec;
	dump->tv_nsec = crash_data->timestamp.tv_nsec;
	dump->device_id = mt76_chip(&dev->mt76);

	mt7915_coredump_fw_state(dev, dump, &exception);
	mt7915_coredump_fw_trace(dev, dump, exception);
	mt7915_coredump_fw_task(dev, dump);
	mt7915_coredump_fw_context(dev, dump);
	mt7915_coredump_fw_stack(dev, dump, exception);

	/* gather memory content */
	dump_mem = (struct mt7915_coredump_mem *)(buf + sofar);
	dump_mem->len = crash_data->memdump_buf_len;
	if (coredump_memdump && crash_data->memdump_buf_len)
		memcpy(dump_mem->data, crash_data->memdump_buf,
		       crash_data->memdump_buf_len);

	mutex_unlock(&dev->dump_mutex);

	return dump;
}

int mt7915_coredump_submit(struct mt7915_dev *dev)
{
	struct mt7915_coredump *dump;

	dump = mt7915_coredump_build(dev);
	if (!dump) {
		dev_warn(dev->mt76.dev, "no crash dump data found\n");
		return -ENODATA;
	}

	dev_coredumpv(dev->mt76.dev, dump, dump->len, GFP_KERNEL);

	return 0;
}

int mt7915_coredump_register(struct mt7915_dev *dev)
{
	struct mt7915_crash_data *crash_data;

	crash_data = vzalloc(sizeof(*dev->coredump.crash_data));

Annotation

Implementation Notes