vop_debugfs.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Intel MIC Platform Software Stack (MPSS)
  3. *
  4. * Copyright(c) 2016 Intel Corporation.
  5. *
  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.
  9. *
  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.
  14. *
  15. * The full GNU General Public License is included in this distribution in
  16. * the file called "COPYING".
  17. *
  18. * Intel Virtio Over PCIe (VOP) driver.
  19. *
  20. */
  21. #include <linux/debugfs.h>
  22. #include <linux/seq_file.h>
  23. #include "vop_main.h"
  24. static int vop_dp_show(struct seq_file *s, void *pos)
  25. {
  26. struct mic_device_desc *d;
  27. struct mic_device_ctrl *dc;
  28. struct mic_vqconfig *vqconfig;
  29. __u32 *features;
  30. __u8 *config;
  31. struct vop_info *vi = s->private;
  32. struct vop_device *vpdev = vi->vpdev;
  33. struct mic_bootparam *bootparam = vpdev->hw_ops->get_dp(vpdev);
  34. int j, k;
  35. seq_printf(s, "Bootparam: magic 0x%x\n",
  36. bootparam->magic);
  37. seq_printf(s, "Bootparam: h2c_config_db %d\n",
  38. bootparam->h2c_config_db);
  39. seq_printf(s, "Bootparam: node_id %d\n",
  40. bootparam->node_id);
  41. seq_printf(s, "Bootparam: c2h_scif_db %d\n",
  42. bootparam->c2h_scif_db);
  43. seq_printf(s, "Bootparam: h2c_scif_db %d\n",
  44. bootparam->h2c_scif_db);
  45. seq_printf(s, "Bootparam: scif_host_dma_addr 0x%llx\n",
  46. bootparam->scif_host_dma_addr);
  47. seq_printf(s, "Bootparam: scif_card_dma_addr 0x%llx\n",
  48. bootparam->scif_card_dma_addr);
  49. for (j = sizeof(*bootparam);
  50. j < MIC_DP_SIZE; j += mic_total_desc_size(d)) {
  51. d = (void *)bootparam + j;
  52. dc = (void *)d + mic_aligned_desc_size(d);
  53. /* end of list */
  54. if (d->type == 0)
  55. break;
  56. if (d->type == -1)
  57. continue;
  58. seq_printf(s, "Type %d ", d->type);
  59. seq_printf(s, "Num VQ %d ", d->num_vq);
  60. seq_printf(s, "Feature Len %d\n", d->feature_len);
  61. seq_printf(s, "Config Len %d ", d->config_len);
  62. seq_printf(s, "Shutdown Status %d\n", d->status);
  63. for (k = 0; k < d->num_vq; k++) {
  64. vqconfig = mic_vq_config(d) + k;
  65. seq_printf(s, "vqconfig[%d]: ", k);
  66. seq_printf(s, "address 0x%llx ",
  67. vqconfig->address);
  68. seq_printf(s, "num %d ", vqconfig->num);
  69. seq_printf(s, "used address 0x%llx\n",
  70. vqconfig->used_address);
  71. }
  72. features = (__u32 *)mic_vq_features(d);
  73. seq_printf(s, "Features: Host 0x%x ", features[0]);
  74. seq_printf(s, "Guest 0x%x\n", features[1]);
  75. config = mic_vq_configspace(d);
  76. for (k = 0; k < d->config_len; k++)
  77. seq_printf(s, "config[%d]=%d\n", k, config[k]);
  78. seq_puts(s, "Device control:\n");
  79. seq_printf(s, "Config Change %d ", dc->config_change);
  80. seq_printf(s, "Vdev reset %d\n", dc->vdev_reset);
  81. seq_printf(s, "Guest Ack %d ", dc->guest_ack);
  82. seq_printf(s, "Host ack %d\n", dc->host_ack);
  83. seq_printf(s, "Used address updated %d ",
  84. dc->used_address_updated);
  85. seq_printf(s, "Vdev 0x%llx\n", dc->vdev);
  86. seq_printf(s, "c2h doorbell %d ", dc->c2h_vdev_db);
  87. seq_printf(s, "h2c doorbell %d\n", dc->h2c_vdev_db);
  88. }
  89. schedule_work(&vi->hotplug_work);
  90. return 0;
  91. }
  92. static int vop_dp_debug_open(struct inode *inode, struct file *file)
  93. {
  94. return single_open(file, vop_dp_show, inode->i_private);
  95. }
  96. static int vop_dp_debug_release(struct inode *inode, struct file *file)
  97. {
  98. return single_release(inode, file);
  99. }
  100. static const struct file_operations dp_ops = {
  101. .owner = THIS_MODULE,
  102. .open = vop_dp_debug_open,
  103. .read = seq_read,
  104. .llseek = seq_lseek,
  105. .release = vop_dp_debug_release
  106. };
  107. static int vop_vdev_info_show(struct seq_file *s, void *unused)
  108. {
  109. struct vop_info *vi = s->private;
  110. struct list_head *pos, *tmp;
  111. struct vop_vdev *vdev;
  112. int i, j;
  113. mutex_lock(&vi->vop_mutex);
  114. list_for_each_safe(pos, tmp, &vi->vdev_list) {
  115. vdev = list_entry(pos, struct vop_vdev, list);
  116. seq_printf(s, "VDEV type %d state %s in %ld out %ld in_dma %ld out_dma %ld\n",
  117. vdev->virtio_id,
  118. vop_vdevup(vdev) ? "UP" : "DOWN",
  119. vdev->in_bytes,
  120. vdev->out_bytes,
  121. vdev->in_bytes_dma,
  122. vdev->out_bytes_dma);
  123. for (i = 0; i < MIC_MAX_VRINGS; i++) {
  124. struct vring_desc *desc;
  125. struct vring_avail *avail;
  126. struct vring_used *used;
  127. struct vop_vringh *vvr = &vdev->vvr[i];
  128. struct vringh *vrh = &vvr->vrh;
  129. int num = vrh->vring.num;
  130. if (!num)
  131. continue;
  132. desc = vrh->vring.desc;
  133. seq_printf(s, "vring i %d avail_idx %d",
  134. i, vvr->vring.info->avail_idx & (num - 1));
  135. seq_printf(s, " vring i %d avail_idx %d\n",
  136. i, vvr->vring.info->avail_idx);
  137. seq_printf(s, "vrh i %d weak_barriers %d",
  138. i, vrh->weak_barriers);
  139. seq_printf(s, " last_avail_idx %d last_used_idx %d",
  140. vrh->last_avail_idx, vrh->last_used_idx);
  141. seq_printf(s, " completed %d\n", vrh->completed);
  142. for (j = 0; j < num; j++) {
  143. seq_printf(s, "desc[%d] addr 0x%llx len %d",
  144. j, desc->addr, desc->len);
  145. seq_printf(s, " flags 0x%x next %d\n",
  146. desc->flags, desc->next);
  147. desc++;
  148. }
  149. avail = vrh->vring.avail;
  150. seq_printf(s, "avail flags 0x%x idx %d\n",
  151. vringh16_to_cpu(vrh, avail->flags),
  152. vringh16_to_cpu(vrh,
  153. avail->idx) & (num - 1));
  154. seq_printf(s, "avail flags 0x%x idx %d\n",
  155. vringh16_to_cpu(vrh, avail->flags),
  156. vringh16_to_cpu(vrh, avail->idx));
  157. for (j = 0; j < num; j++)
  158. seq_printf(s, "avail ring[%d] %d\n",
  159. j, avail->ring[j]);
  160. used = vrh->vring.used;
  161. seq_printf(s, "used flags 0x%x idx %d\n",
  162. vringh16_to_cpu(vrh, used->flags),
  163. vringh16_to_cpu(vrh, used->idx) & (num - 1));
  164. seq_printf(s, "used flags 0x%x idx %d\n",
  165. vringh16_to_cpu(vrh, used->flags),
  166. vringh16_to_cpu(vrh, used->idx));
  167. for (j = 0; j < num; j++)
  168. seq_printf(s, "used ring[%d] id %d len %d\n",
  169. j, vringh32_to_cpu(vrh,
  170. used->ring[j].id),
  171. vringh32_to_cpu(vrh,
  172. used->ring[j].len));
  173. }
  174. }
  175. mutex_unlock(&vi->vop_mutex);
  176. return 0;
  177. }
  178. static int vop_vdev_info_debug_open(struct inode *inode, struct file *file)
  179. {
  180. return single_open(file, vop_vdev_info_show, inode->i_private);
  181. }
  182. static int vop_vdev_info_debug_release(struct inode *inode, struct file *file)
  183. {
  184. return single_release(inode, file);
  185. }
  186. static const struct file_operations vdev_info_ops = {
  187. .owner = THIS_MODULE,
  188. .open = vop_vdev_info_debug_open,
  189. .read = seq_read,
  190. .llseek = seq_lseek,
  191. .release = vop_vdev_info_debug_release
  192. };
  193. void vop_init_debugfs(struct vop_info *vi)
  194. {
  195. char name[16];
  196. snprintf(name, sizeof(name), "%s%d", KBUILD_MODNAME, vi->vpdev->dnode);
  197. vi->dbg = debugfs_create_dir(name, NULL);
  198. if (!vi->dbg) {
  199. pr_err("can't create debugfs dir vop\n");
  200. return;
  201. }
  202. debugfs_create_file("dp", 0444, vi->dbg, vi, &dp_ops);
  203. debugfs_create_file("vdev_info", 0444, vi->dbg, vi, &vdev_info_ops);
  204. }
  205. void vop_exit_debugfs(struct vop_info *vi)
  206. {
  207. debugfs_remove_recursive(vi->dbg);
  208. }