qdio_debug.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. * drivers/s390/cio/qdio_debug.c
  3. *
  4. * Copyright IBM Corp. 2008,2009
  5. *
  6. * Author: Jan Glauber (jang@linux.vnet.ibm.com)
  7. */
  8. #include <linux/seq_file.h>
  9. #include <linux/debugfs.h>
  10. #include <asm/debug.h>
  11. #include "qdio_debug.h"
  12. #include "qdio.h"
  13. debug_info_t *qdio_dbf_setup;
  14. debug_info_t *qdio_dbf_error;
  15. static struct dentry *debugfs_root;
  16. #define QDIO_DEBUGFS_NAME_LEN 10
  17. void qdio_allocate_dbf(struct qdio_initialize *init_data,
  18. struct qdio_irq *irq_ptr)
  19. {
  20. char text[20];
  21. DBF_EVENT("qfmt:%1d", init_data->q_format);
  22. DBF_HEX(init_data->adapter_name, 8);
  23. DBF_EVENT("qpff%4x", init_data->qib_param_field_format);
  24. DBF_HEX(&init_data->qib_param_field, sizeof(void *));
  25. DBF_HEX(&init_data->input_slib_elements, sizeof(void *));
  26. DBF_HEX(&init_data->output_slib_elements, sizeof(void *));
  27. DBF_EVENT("niq:%1d noq:%1d", init_data->no_input_qs,
  28. init_data->no_output_qs);
  29. DBF_HEX(&init_data->input_handler, sizeof(void *));
  30. DBF_HEX(&init_data->output_handler, sizeof(void *));
  31. DBF_HEX(&init_data->int_parm, sizeof(long));
  32. DBF_HEX(&init_data->flags, sizeof(long));
  33. DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *));
  34. DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *));
  35. DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
  36. /* allocate trace view for the interface */
  37. snprintf(text, 20, "qdio_%s", dev_name(&init_data->cdev->dev));
  38. irq_ptr->debug_area = debug_register(text, 2, 1, 16);
  39. debug_register_view(irq_ptr->debug_area, &debug_hex_ascii_view);
  40. debug_set_level(irq_ptr->debug_area, DBF_WARN);
  41. DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created");
  42. }
  43. static int qstat_show(struct seq_file *m, void *v)
  44. {
  45. unsigned char state;
  46. struct qdio_q *q = m->private;
  47. int i;
  48. if (!q)
  49. return 0;
  50. seq_printf(m, "device state indicator: %d\n", *(u32 *)q->irq_ptr->dsci);
  51. seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used));
  52. seq_printf(m, "ftc: %d\n", q->first_to_check);
  53. seq_printf(m, "last_move: %d\n", q->last_move);
  54. seq_printf(m, "polling: %d\n", q->u.in.polling);
  55. seq_printf(m, "ack start: %d\n", q->u.in.ack_start);
  56. seq_printf(m, "ack count: %d\n", q->u.in.ack_count);
  57. seq_printf(m, "slsb buffer states:\n");
  58. seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
  59. for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
  60. debug_get_buf_state(q, i, &state);
  61. switch (state) {
  62. case SLSB_P_INPUT_NOT_INIT:
  63. case SLSB_P_OUTPUT_NOT_INIT:
  64. seq_printf(m, "N");
  65. break;
  66. case SLSB_P_INPUT_PRIMED:
  67. case SLSB_CU_OUTPUT_PRIMED:
  68. seq_printf(m, "+");
  69. break;
  70. case SLSB_P_INPUT_ACK:
  71. seq_printf(m, "A");
  72. break;
  73. case SLSB_P_INPUT_ERROR:
  74. case SLSB_P_OUTPUT_ERROR:
  75. seq_printf(m, "x");
  76. break;
  77. case SLSB_CU_INPUT_EMPTY:
  78. case SLSB_P_OUTPUT_EMPTY:
  79. seq_printf(m, "-");
  80. break;
  81. case SLSB_P_INPUT_HALTED:
  82. case SLSB_P_OUTPUT_HALTED:
  83. seq_printf(m, ".");
  84. break;
  85. default:
  86. seq_printf(m, "?");
  87. }
  88. if (i == 63)
  89. seq_printf(m, "\n");
  90. }
  91. seq_printf(m, "\n");
  92. seq_printf(m, "|64 |72 |80 |88 |96 |104 |112 | 127|\n");
  93. return 0;
  94. }
  95. static ssize_t qstat_seq_write(struct file *file, const char __user *buf,
  96. size_t count, loff_t *off)
  97. {
  98. struct seq_file *seq = file->private_data;
  99. struct qdio_q *q = seq->private;
  100. if (!q)
  101. return 0;
  102. if (q->is_input_q)
  103. xchg(q->irq_ptr->dsci, 1);
  104. local_bh_disable();
  105. tasklet_schedule(&q->tasklet);
  106. local_bh_enable();
  107. return count;
  108. }
  109. static int qstat_seq_open(struct inode *inode, struct file *filp)
  110. {
  111. return single_open(filp, qstat_show,
  112. filp->f_path.dentry->d_inode->i_private);
  113. }
  114. static const struct file_operations debugfs_fops = {
  115. .owner = THIS_MODULE,
  116. .open = qstat_seq_open,
  117. .read = seq_read,
  118. .write = qstat_seq_write,
  119. .llseek = seq_lseek,
  120. .release = single_release,
  121. };
  122. static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev)
  123. {
  124. char name[QDIO_DEBUGFS_NAME_LEN];
  125. snprintf(name, QDIO_DEBUGFS_NAME_LEN, "%s_%d",
  126. q->is_input_q ? "input" : "output",
  127. q->nr);
  128. q->debugfs_q = debugfs_create_file(name, S_IFREG | S_IRUGO | S_IWUSR,
  129. q->irq_ptr->debugfs_dev, q, &debugfs_fops);
  130. if (IS_ERR(q->debugfs_q))
  131. q->debugfs_q = NULL;
  132. }
  133. void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev)
  134. {
  135. struct qdio_q *q;
  136. int i;
  137. irq_ptr->debugfs_dev = debugfs_create_dir(dev_name(&cdev->dev),
  138. debugfs_root);
  139. if (IS_ERR(irq_ptr->debugfs_dev))
  140. irq_ptr->debugfs_dev = NULL;
  141. for_each_input_queue(irq_ptr, q, i)
  142. setup_debugfs_entry(q, cdev);
  143. for_each_output_queue(irq_ptr, q, i)
  144. setup_debugfs_entry(q, cdev);
  145. }
  146. void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev)
  147. {
  148. struct qdio_q *q;
  149. int i;
  150. for_each_input_queue(irq_ptr, q, i)
  151. debugfs_remove(q->debugfs_q);
  152. for_each_output_queue(irq_ptr, q, i)
  153. debugfs_remove(q->debugfs_q);
  154. debugfs_remove(irq_ptr->debugfs_dev);
  155. }
  156. int __init qdio_debug_init(void)
  157. {
  158. debugfs_root = debugfs_create_dir("qdio", NULL);
  159. qdio_dbf_setup = debug_register("qdio_setup", 16, 1, 16);
  160. debug_register_view(qdio_dbf_setup, &debug_hex_ascii_view);
  161. debug_set_level(qdio_dbf_setup, DBF_INFO);
  162. DBF_EVENT("dbf created\n");
  163. qdio_dbf_error = debug_register("qdio_error", 4, 1, 16);
  164. debug_register_view(qdio_dbf_error, &debug_hex_ascii_view);
  165. debug_set_level(qdio_dbf_error, DBF_INFO);
  166. DBF_ERROR("dbf created\n");
  167. return 0;
  168. }
  169. void qdio_debug_exit(void)
  170. {
  171. debugfs_remove(debugfs_root);
  172. if (qdio_dbf_setup)
  173. debug_unregister(qdio_dbf_setup);
  174. if (qdio_dbf_error)
  175. debug_unregister(qdio_dbf_error);
  176. }