]>
Commit | Line | Data |
---|---|---|
ace7f46b MR |
1 | /* |
2 | * QLogic iSCSI Offload Driver | |
3 | * Copyright (c) 2016 Cavium Inc. | |
4 | * | |
5 | * This software is available under the terms of the GNU General Public License | |
6 | * (GPL) Version 2, available from the file COPYING in the main directory of | |
7 | * this source tree. | |
8 | */ | |
9 | ||
10 | #include "qedi.h" | |
11 | #include "qedi_dbg.h" | |
12 | ||
13 | #include <linux/uaccess.h> | |
14 | #include <linux/debugfs.h> | |
15 | #include <linux/module.h> | |
16 | ||
bd571195 | 17 | int qedi_do_not_recover; |
ace7f46b MR |
18 | static struct dentry *qedi_dbg_root; |
19 | ||
20 | void | |
21 | qedi_dbg_host_init(struct qedi_dbg_ctx *qedi, | |
22 | struct qedi_debugfs_ops *dops, | |
23 | const struct file_operations *fops) | |
24 | { | |
25 | char host_dirname[32]; | |
26 | struct dentry *file_dentry = NULL; | |
27 | ||
28 | sprintf(host_dirname, "host%u", qedi->host_no); | |
29 | qedi->bdf_dentry = debugfs_create_dir(host_dirname, qedi_dbg_root); | |
30 | if (!qedi->bdf_dentry) | |
31 | return; | |
32 | ||
33 | while (dops) { | |
34 | if (!(dops->name)) | |
35 | break; | |
36 | ||
37 | file_dentry = debugfs_create_file(dops->name, 0600, | |
38 | qedi->bdf_dentry, qedi, | |
39 | fops); | |
40 | if (!file_dentry) { | |
41 | QEDI_INFO(qedi, QEDI_LOG_DEBUGFS, | |
42 | "Debugfs entry %s creation failed\n", | |
43 | dops->name); | |
44 | debugfs_remove_recursive(qedi->bdf_dentry); | |
45 | return; | |
46 | } | |
47 | dops++; | |
48 | fops++; | |
49 | } | |
50 | } | |
51 | ||
52 | void | |
53 | qedi_dbg_host_exit(struct qedi_dbg_ctx *qedi) | |
54 | { | |
55 | debugfs_remove_recursive(qedi->bdf_dentry); | |
56 | qedi->bdf_dentry = NULL; | |
57 | } | |
58 | ||
59 | void | |
60 | qedi_dbg_init(char *drv_name) | |
61 | { | |
62 | qedi_dbg_root = debugfs_create_dir(drv_name, NULL); | |
63 | if (!qedi_dbg_root) | |
64 | QEDI_INFO(NULL, QEDI_LOG_DEBUGFS, "Init of debugfs failed\n"); | |
65 | } | |
66 | ||
67 | void | |
68 | qedi_dbg_exit(void) | |
69 | { | |
70 | debugfs_remove_recursive(qedi_dbg_root); | |
71 | qedi_dbg_root = NULL; | |
72 | } | |
73 | ||
74 | static ssize_t | |
75 | qedi_dbg_do_not_recover_enable(struct qedi_dbg_ctx *qedi_dbg) | |
76 | { | |
bd571195 AB |
77 | if (!qedi_do_not_recover) |
78 | qedi_do_not_recover = 1; | |
ace7f46b MR |
79 | |
80 | QEDI_INFO(qedi_dbg, QEDI_LOG_DEBUGFS, "do_not_recover=%d\n", | |
bd571195 | 81 | qedi_do_not_recover); |
ace7f46b MR |
82 | return 0; |
83 | } | |
84 | ||
85 | static ssize_t | |
86 | qedi_dbg_do_not_recover_disable(struct qedi_dbg_ctx *qedi_dbg) | |
87 | { | |
bd571195 AB |
88 | if (qedi_do_not_recover) |
89 | qedi_do_not_recover = 0; | |
ace7f46b MR |
90 | |
91 | QEDI_INFO(qedi_dbg, QEDI_LOG_DEBUGFS, "do_not_recover=%d\n", | |
bd571195 | 92 | qedi_do_not_recover); |
ace7f46b MR |
93 | return 0; |
94 | } | |
95 | ||
96 | static struct qedi_list_of_funcs qedi_dbg_do_not_recover_ops[] = { | |
97 | { "enable", qedi_dbg_do_not_recover_enable }, | |
98 | { "disable", qedi_dbg_do_not_recover_disable }, | |
99 | { NULL, NULL } | |
100 | }; | |
101 | ||
102 | struct qedi_debugfs_ops qedi_debugfs_ops[] = { | |
103 | { "gbl_ctx", NULL }, | |
104 | { "do_not_recover", qedi_dbg_do_not_recover_ops}, | |
105 | { "io_trace", NULL }, | |
106 | { NULL, NULL } | |
107 | }; | |
108 | ||
109 | static ssize_t | |
110 | qedi_dbg_do_not_recover_cmd_write(struct file *filp, const char __user *buffer, | |
111 | size_t count, loff_t *ppos) | |
112 | { | |
113 | size_t cnt = 0; | |
114 | struct qedi_dbg_ctx *qedi_dbg = | |
115 | (struct qedi_dbg_ctx *)filp->private_data; | |
116 | struct qedi_list_of_funcs *lof = qedi_dbg_do_not_recover_ops; | |
117 | ||
118 | if (*ppos) | |
119 | return 0; | |
120 | ||
121 | while (lof) { | |
122 | if (!(lof->oper_str)) | |
123 | break; | |
124 | ||
125 | if (!strncmp(lof->oper_str, buffer, strlen(lof->oper_str))) { | |
126 | cnt = lof->oper_func(qedi_dbg); | |
127 | break; | |
128 | } | |
129 | ||
130 | lof++; | |
131 | } | |
132 | return (count - cnt); | |
133 | } | |
134 | ||
135 | static ssize_t | |
136 | qedi_dbg_do_not_recover_cmd_read(struct file *filp, char __user *buffer, | |
137 | size_t count, loff_t *ppos) | |
138 | { | |
139 | size_t cnt = 0; | |
140 | ||
141 | if (*ppos) | |
142 | return 0; | |
143 | ||
bd571195 | 144 | cnt = sprintf(buffer, "do_not_recover=%d\n", qedi_do_not_recover); |
ace7f46b MR |
145 | cnt = min_t(int, count, cnt - *ppos); |
146 | *ppos += cnt; | |
147 | return cnt; | |
148 | } | |
149 | ||
150 | static int | |
151 | qedi_gbl_ctx_show(struct seq_file *s, void *unused) | |
152 | { | |
153 | struct qedi_fastpath *fp = NULL; | |
154 | struct qed_sb_info *sb_info = NULL; | |
155 | struct status_block *sb = NULL; | |
156 | struct global_queue *que = NULL; | |
157 | int id; | |
158 | u16 prod_idx; | |
159 | struct qedi_ctx *qedi = s->private; | |
160 | unsigned long flags; | |
161 | ||
162 | seq_puts(s, " DUMP CQ CONTEXT:\n"); | |
163 | ||
164 | for (id = 0; id < MIN_NUM_CPUS_MSIX(qedi); id++) { | |
165 | spin_lock_irqsave(&qedi->hba_lock, flags); | |
166 | seq_printf(s, "=========FAST CQ PATH [%d] ==========\n", id); | |
167 | fp = &qedi->fp_array[id]; | |
168 | sb_info = fp->sb_info; | |
169 | sb = sb_info->sb_virt; | |
170 | prod_idx = (sb->pi_array[QEDI_PROTO_CQ_PROD_IDX] & | |
171 | STATUS_BLOCK_PROD_INDEX_MASK); | |
172 | seq_printf(s, "SB PROD IDX: %d\n", prod_idx); | |
173 | que = qedi->global_queues[fp->sb_id]; | |
174 | seq_printf(s, "DRV CONS IDX: %d\n", que->cq_cons_idx); | |
175 | seq_printf(s, "CQ complete host memory: %d\n", fp->sb_id); | |
176 | seq_puts(s, "=========== END ==================\n\n\n"); | |
177 | spin_unlock_irqrestore(&qedi->hba_lock, flags); | |
178 | } | |
179 | return 0; | |
180 | } | |
181 | ||
182 | static int | |
183 | qedi_dbg_gbl_ctx_open(struct inode *inode, struct file *file) | |
184 | { | |
185 | struct qedi_dbg_ctx *qedi_dbg = inode->i_private; | |
186 | struct qedi_ctx *qedi = container_of(qedi_dbg, struct qedi_ctx, | |
187 | dbg_ctx); | |
188 | ||
189 | return single_open(file, qedi_gbl_ctx_show, qedi); | |
190 | } | |
191 | ||
192 | static int | |
193 | qedi_io_trace_show(struct seq_file *s, void *unused) | |
194 | { | |
195 | int id, idx = 0; | |
196 | struct qedi_ctx *qedi = s->private; | |
197 | struct qedi_io_log *io_log; | |
198 | unsigned long flags; | |
199 | ||
200 | seq_puts(s, " DUMP IO LOGS:\n"); | |
201 | spin_lock_irqsave(&qedi->io_trace_lock, flags); | |
202 | idx = qedi->io_trace_idx; | |
203 | for (id = 0; id < QEDI_IO_TRACE_SIZE; id++) { | |
204 | io_log = &qedi->io_trace_buf[idx]; | |
205 | seq_printf(s, "iodir-%d:", io_log->direction); | |
206 | seq_printf(s, "tid-0x%x:", io_log->task_id); | |
207 | seq_printf(s, "cid-0x%x:", io_log->cid); | |
208 | seq_printf(s, "lun-%d:", io_log->lun); | |
209 | seq_printf(s, "op-0x%02x:", io_log->op); | |
210 | seq_printf(s, "0x%02x%02x%02x%02x:", io_log->lba[0], | |
211 | io_log->lba[1], io_log->lba[2], io_log->lba[3]); | |
212 | seq_printf(s, "buflen-%d:", io_log->bufflen); | |
213 | seq_printf(s, "sgcnt-%d:", io_log->sg_count); | |
214 | seq_printf(s, "res-0x%08x:", io_log->result); | |
215 | seq_printf(s, "jif-%lu:", io_log->jiffies); | |
216 | seq_printf(s, "blk_req_cpu-%d:", io_log->blk_req_cpu); | |
217 | seq_printf(s, "req_cpu-%d:", io_log->req_cpu); | |
218 | seq_printf(s, "intr_cpu-%d:", io_log->intr_cpu); | |
219 | seq_printf(s, "blk_rsp_cpu-%d\n", io_log->blk_rsp_cpu); | |
220 | ||
221 | idx++; | |
222 | if (idx == QEDI_IO_TRACE_SIZE) | |
223 | idx = 0; | |
224 | } | |
225 | spin_unlock_irqrestore(&qedi->io_trace_lock, flags); | |
226 | return 0; | |
227 | } | |
228 | ||
229 | static int | |
230 | qedi_dbg_io_trace_open(struct inode *inode, struct file *file) | |
231 | { | |
232 | struct qedi_dbg_ctx *qedi_dbg = inode->i_private; | |
233 | struct qedi_ctx *qedi = container_of(qedi_dbg, struct qedi_ctx, | |
234 | dbg_ctx); | |
235 | ||
236 | return single_open(file, qedi_io_trace_show, qedi); | |
237 | } | |
238 | ||
239 | const struct file_operations qedi_dbg_fops[] = { | |
240 | qedi_dbg_fileops_seq(qedi, gbl_ctx), | |
241 | qedi_dbg_fileops(qedi, do_not_recover), | |
242 | qedi_dbg_fileops_seq(qedi, io_trace), | |
243 | { NULL, NULL }, | |
244 | }; |