aboutsummaryrefslogtreecommitdiffstats
path: root/device_info_procfs.c
blob: 5fc417f1e3a3aedb8e1ebfa75cf54566faa4a49a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
generated by cgit v1.2.2 (git 2.25.0) at 2026-11-02 18:53:31 -0500
 


"hl opt">;
	struct nvdebug_state *g = &g_nvdebug_state[file2parentgpuidx(f)];
	if (size < 16 || *off != 0)
		return 0;
	// 32 bit register will always take less than 16 characters to print
	chars_written = scnprintf(out, 16, "%#0x\n", nvdebug_readl(g, (uintptr_t)PDE_DATA(file_inode(f))));
	if (copy_to_user(buf, out, chars_written))
		printk(KERN_WARNING "Unable to copy all data for %s\n", file_dentry(f)->d_name.name);
	*off += chars_written;
	return chars_written;
}
struct file_operations nvdebug_read_reg32_file_ops = {
	.read = nvdebug_reg32_read,
	.llseek = default_llseek,
};

//// ==v== PTOP_DEVICE_INFO ==v== ////

// Called to start or resume a sequence. Prior to 4.19, *pos is unreliable.
// Initializes iterator `idx` state and returns it. Ends sequence on NULL.
static void* device_info_file_seq_start(struct seq_file *s, loff_t *pos) {
	static int idx;
	// If start of sequence, reset `idx`
	if (*pos == 0)
		idx = 0;
	// Number of possible info entries is fixed, and list is sparse
	if (idx >= NV_PTOP_DEVICE_INFO__SIZE_1)
		return NULL;
	return &idx;
}

// Steps to next record. Returns new value of `idx`.
// Calls show() on non-NULL return
static void* device_info_file_seq_next(struct seq_file *s, void *idx,
				       loff_t *pos) {
	(*pos)++; // Required by seq interface
	// Number of possible info entries is fixed, and list is sparse
	if ((*(int*)idx)++ >= NV_PTOP_DEVICE_INFO__SIZE_1)
		return NULL;
	return idx;
}

// Print info at index *idx. Returns non-zero on error.
static int device_info_file_seq_show(struct seq_file *s, void *idx) {
	ptop_device_info_t curr_info;
	struct nvdebug_state *g = &g_nvdebug_state[seq2gpuidx(s)];

	curr_info.raw = nvdebug_readl(g, NV_PTOP_DEVICE_INFO(*(int*)idx));
	// Check for read errors
	if (curr_info.raw == -1)
		return -EIO;

	// Parse and print the data
	switch(curr_info.info_type) {
	case INFO_TYPE_DATA:
		// As of early 2022, only the ENUM2 format of this entry exists
		if (curr_info.is_not_enum2)
			break;
		seq_printf(s, "| BAR0 Base %#.8x\n"
			      "|           instance %d\n",
			curr_info.pri_base << 12, curr_info.inst_id);
		if (curr_info.fault_id_is_valid)