2 * Intel MIC Platform Software Stack (MPSS)
4 * Copyright(c) 2016 Intel Corporation.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
18 * Intel Virtio Over PCIe (VOP) driver.
21 #include <linux/debugfs.h>
22 #include <linux/seq_file.h>
26 static int vop_dp_show(struct seq_file
*s
, void *pos
)
28 struct mic_device_desc
*d
;
29 struct mic_device_ctrl
*dc
;
30 struct mic_vqconfig
*vqconfig
;
33 struct vop_info
*vi
= s
->private;
34 struct vop_device
*vpdev
= vi
->vpdev
;
35 struct mic_bootparam
*bootparam
= vpdev
->hw_ops
->get_dp(vpdev
);
38 seq_printf(s
, "Bootparam: magic 0x%x\n",
40 seq_printf(s
, "Bootparam: h2c_config_db %d\n",
41 bootparam
->h2c_config_db
);
42 seq_printf(s
, "Bootparam: node_id %d\n",
44 seq_printf(s
, "Bootparam: c2h_scif_db %d\n",
45 bootparam
->c2h_scif_db
);
46 seq_printf(s
, "Bootparam: h2c_scif_db %d\n",
47 bootparam
->h2c_scif_db
);
48 seq_printf(s
, "Bootparam: scif_host_dma_addr 0x%llx\n",
49 bootparam
->scif_host_dma_addr
);
50 seq_printf(s
, "Bootparam: scif_card_dma_addr 0x%llx\n",
51 bootparam
->scif_card_dma_addr
);
53 for (j
= sizeof(*bootparam
);
54 j
< MIC_DP_SIZE
; j
+= mic_total_desc_size(d
)) {
55 d
= (void *)bootparam
+ j
;
56 dc
= (void *)d
+ mic_aligned_desc_size(d
);
65 seq_printf(s
, "Type %d ", d
->type
);
66 seq_printf(s
, "Num VQ %d ", d
->num_vq
);
67 seq_printf(s
, "Feature Len %d\n", d
->feature_len
);
68 seq_printf(s
, "Config Len %d ", d
->config_len
);
69 seq_printf(s
, "Shutdown Status %d\n", d
->status
);
71 for (k
= 0; k
< d
->num_vq
; k
++) {
72 vqconfig
= mic_vq_config(d
) + k
;
73 seq_printf(s
, "vqconfig[%d]: ", k
);
74 seq_printf(s
, "address 0x%llx ",
76 seq_printf(s
, "num %d ", vqconfig
->num
);
77 seq_printf(s
, "used address 0x%llx\n",
78 vqconfig
->used_address
);
81 features
= (__u32
*)mic_vq_features(d
);
82 seq_printf(s
, "Features: Host 0x%x ", features
[0]);
83 seq_printf(s
, "Guest 0x%x\n", features
[1]);
85 config
= mic_vq_configspace(d
);
86 for (k
= 0; k
< d
->config_len
; k
++)
87 seq_printf(s
, "config[%d]=%d\n", k
, config
[k
]);
89 seq_puts(s
, "Device control:\n");
90 seq_printf(s
, "Config Change %d ", dc
->config_change
);
91 seq_printf(s
, "Vdev reset %d\n", dc
->vdev_reset
);
92 seq_printf(s
, "Guest Ack %d ", dc
->guest_ack
);
93 seq_printf(s
, "Host ack %d\n", dc
->host_ack
);
94 seq_printf(s
, "Used address updated %d ",
95 dc
->used_address_updated
);
96 seq_printf(s
, "Vdev 0x%llx\n", dc
->vdev
);
97 seq_printf(s
, "c2h doorbell %d ", dc
->c2h_vdev_db
);
98 seq_printf(s
, "h2c doorbell %d\n", dc
->h2c_vdev_db
);
100 schedule_work(&vi
->hotplug_work
);
104 static int vop_dp_debug_open(struct inode
*inode
, struct file
*file
)
106 return single_open(file
, vop_dp_show
, inode
->i_private
);
109 static int vop_dp_debug_release(struct inode
*inode
, struct file
*file
)
111 return single_release(inode
, file
);
114 static const struct file_operations dp_ops
= {
115 .owner
= THIS_MODULE
,
116 .open
= vop_dp_debug_open
,
119 .release
= vop_dp_debug_release
122 static int vop_vdev_info_show(struct seq_file
*s
, void *unused
)
124 struct vop_info
*vi
= s
->private;
125 struct list_head
*pos
, *tmp
;
126 struct vop_vdev
*vdev
;
129 mutex_lock(&vi
->vop_mutex
);
130 list_for_each_safe(pos
, tmp
, &vi
->vdev_list
) {
131 vdev
= list_entry(pos
, struct vop_vdev
, list
);
132 seq_printf(s
, "VDEV type %d state %s in %ld out %ld in_dma %ld out_dma %ld\n",
134 vop_vdevup(vdev
) ? "UP" : "DOWN",
138 vdev
->out_bytes_dma
);
139 for (i
= 0; i
< MIC_MAX_VRINGS
; i
++) {
140 struct vring_desc
*desc
;
141 struct vring_avail
*avail
;
142 struct vring_used
*used
;
143 struct vop_vringh
*vvr
= &vdev
->vvr
[i
];
144 struct vringh
*vrh
= &vvr
->vrh
;
145 int num
= vrh
->vring
.num
;
149 desc
= vrh
->vring
.desc
;
150 seq_printf(s
, "vring i %d avail_idx %d",
151 i
, vvr
->vring
.info
->avail_idx
& (num
- 1));
152 seq_printf(s
, " vring i %d avail_idx %d\n",
153 i
, vvr
->vring
.info
->avail_idx
);
154 seq_printf(s
, "vrh i %d weak_barriers %d",
155 i
, vrh
->weak_barriers
);
156 seq_printf(s
, " last_avail_idx %d last_used_idx %d",
157 vrh
->last_avail_idx
, vrh
->last_used_idx
);
158 seq_printf(s
, " completed %d\n", vrh
->completed
);
159 for (j
= 0; j
< num
; j
++) {
160 seq_printf(s
, "desc[%d] addr 0x%llx len %d",
161 j
, desc
->addr
, desc
->len
);
162 seq_printf(s
, " flags 0x%x next %d\n",
163 desc
->flags
, desc
->next
);
166 avail
= vrh
->vring
.avail
;
167 seq_printf(s
, "avail flags 0x%x idx %d\n",
168 vringh16_to_cpu(vrh
, avail
->flags
),
170 avail
->idx
) & (num
- 1));
171 seq_printf(s
, "avail flags 0x%x idx %d\n",
172 vringh16_to_cpu(vrh
, avail
->flags
),
173 vringh16_to_cpu(vrh
, avail
->idx
));
174 for (j
= 0; j
< num
; j
++)
175 seq_printf(s
, "avail ring[%d] %d\n",
177 used
= vrh
->vring
.used
;
178 seq_printf(s
, "used flags 0x%x idx %d\n",
179 vringh16_to_cpu(vrh
, used
->flags
),
180 vringh16_to_cpu(vrh
, used
->idx
) & (num
- 1));
181 seq_printf(s
, "used flags 0x%x idx %d\n",
182 vringh16_to_cpu(vrh
, used
->flags
),
183 vringh16_to_cpu(vrh
, used
->idx
));
184 for (j
= 0; j
< num
; j
++)
185 seq_printf(s
, "used ring[%d] id %d len %d\n",
186 j
, vringh32_to_cpu(vrh
,
192 mutex_unlock(&vi
->vop_mutex
);
197 static int vop_vdev_info_debug_open(struct inode
*inode
, struct file
*file
)
199 return single_open(file
, vop_vdev_info_show
, inode
->i_private
);
202 static int vop_vdev_info_debug_release(struct inode
*inode
, struct file
*file
)
204 return single_release(inode
, file
);
207 static const struct file_operations vdev_info_ops
= {
208 .owner
= THIS_MODULE
,
209 .open
= vop_vdev_info_debug_open
,
212 .release
= vop_vdev_info_debug_release
215 void vop_init_debugfs(struct vop_info
*vi
)
219 snprintf(name
, sizeof(name
), "%s%d", KBUILD_MODNAME
, vi
->vpdev
->dnode
);
220 vi
->dbg
= debugfs_create_dir(name
, NULL
);
222 pr_err("can't create debugfs dir vop\n");
225 debugfs_create_file("dp", 0444, vi
->dbg
, vi
, &dp_ops
);
226 debugfs_create_file("vdev_info", 0444, vi
->dbg
, vi
, &vdev_info_ops
);
229 void vop_exit_debugfs(struct vop_info
*vi
)
231 debugfs_remove_recursive(vi
->dbg
);