2 * QLogic iSCSI Offload Driver
3 * Copyright (c) 2016 Cavium Inc.
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
13 #include <linux/uaccess.h>
14 #include <linux/debugfs.h>
15 #include <linux/module.h>
17 int qedi_do_not_recover
;
18 static struct dentry
*qedi_dbg_root
;
21 qedi_dbg_host_init(struct qedi_dbg_ctx
*qedi
,
22 const struct qedi_debugfs_ops
*dops
,
23 const struct file_operations
*fops
)
25 char host_dirname
[32];
26 struct dentry
*file_dentry
= NULL
;
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
)
37 file_dentry
= debugfs_create_file(dops
->name
, 0600,
38 qedi
->bdf_dentry
, qedi
,
41 QEDI_INFO(qedi
, QEDI_LOG_DEBUGFS
,
42 "Debugfs entry %s creation failed\n",
44 debugfs_remove_recursive(qedi
->bdf_dentry
);
53 qedi_dbg_host_exit(struct qedi_dbg_ctx
*qedi
)
55 debugfs_remove_recursive(qedi
->bdf_dentry
);
56 qedi
->bdf_dentry
= NULL
;
60 qedi_dbg_init(char *drv_name
)
62 qedi_dbg_root
= debugfs_create_dir(drv_name
, NULL
);
64 QEDI_INFO(NULL
, QEDI_LOG_DEBUGFS
, "Init of debugfs failed\n");
70 debugfs_remove_recursive(qedi_dbg_root
);
75 qedi_dbg_do_not_recover_enable(struct qedi_dbg_ctx
*qedi_dbg
)
77 if (!qedi_do_not_recover
)
78 qedi_do_not_recover
= 1;
80 QEDI_INFO(qedi_dbg
, QEDI_LOG_DEBUGFS
, "do_not_recover=%d\n",
86 qedi_dbg_do_not_recover_disable(struct qedi_dbg_ctx
*qedi_dbg
)
88 if (qedi_do_not_recover
)
89 qedi_do_not_recover
= 0;
91 QEDI_INFO(qedi_dbg
, QEDI_LOG_DEBUGFS
, "do_not_recover=%d\n",
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
},
102 const struct qedi_debugfs_ops qedi_debugfs_ops
[] = {
104 { "do_not_recover", qedi_dbg_do_not_recover_ops
},
105 { "io_trace", NULL
},
110 qedi_dbg_do_not_recover_cmd_write(struct file
*filp
, const char __user
*buffer
,
111 size_t count
, loff_t
*ppos
)
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
;
122 if (!(lof
->oper_str
))
125 if (!strncmp(lof
->oper_str
, buffer
, strlen(lof
->oper_str
))) {
126 cnt
= lof
->oper_func(qedi_dbg
);
132 return (count
- cnt
);
136 qedi_dbg_do_not_recover_cmd_read(struct file
*filp
, char __user
*buffer
,
137 size_t count
, loff_t
*ppos
)
144 cnt
= sprintf(buffer
, "do_not_recover=%d\n", qedi_do_not_recover
);
145 cnt
= min_t(int, count
, cnt
- *ppos
);
151 qedi_gbl_ctx_show(struct seq_file
*s
, void *unused
)
153 struct qedi_fastpath
*fp
= NULL
;
154 struct qed_sb_info
*sb_info
= NULL
;
155 struct status_block_e4
*sb
= NULL
;
156 struct global_queue
*que
= NULL
;
159 struct qedi_ctx
*qedi
= s
->private;
162 seq_puts(s
, " DUMP CQ CONTEXT:\n");
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_E4_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
);
183 qedi_dbg_gbl_ctx_open(struct inode
*inode
, struct file
*file
)
185 struct qedi_dbg_ctx
*qedi_dbg
= inode
->i_private
;
186 struct qedi_ctx
*qedi
= container_of(qedi_dbg
, struct qedi_ctx
,
189 return single_open(file
, qedi_gbl_ctx_show
, qedi
);
193 qedi_io_trace_show(struct seq_file
*s
, void *unused
)
196 struct qedi_ctx
*qedi
= s
->private;
197 struct qedi_io_log
*io_log
;
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
);
222 if (idx
== QEDI_IO_TRACE_SIZE
)
225 spin_unlock_irqrestore(&qedi
->io_trace_lock
, flags
);
230 qedi_dbg_io_trace_open(struct inode
*inode
, struct file
*file
)
232 struct qedi_dbg_ctx
*qedi_dbg
= inode
->i_private
;
233 struct qedi_ctx
*qedi
= container_of(qedi_dbg
, struct qedi_ctx
,
236 return single_open(file
, qedi_io_trace_show
, qedi
);
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
),