aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_debugfs.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c595
1 files changed, 546 insertions, 49 deletions
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 673cfe11cc2b..2e3c01bebed6 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -71,15 +71,22 @@
71 * lpfc_debugfs_mask_disc_trc=Y Where Y is an event mask as defined in 71 * lpfc_debugfs_mask_disc_trc=Y Where Y is an event mask as defined in
72 * lpfc_debugfs.h . 72 * lpfc_debugfs.h .
73 */ 73 */
74static int lpfc_debugfs_enable = 0; 74static int lpfc_debugfs_enable = 1;
75module_param(lpfc_debugfs_enable, int, 0); 75module_param(lpfc_debugfs_enable, int, 0);
76MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services"); 76MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services");
77 77
78static int lpfc_debugfs_max_disc_trc = 0; /* This MUST be a power of 2 */ 78/* This MUST be a power of 2 */
79static int lpfc_debugfs_max_disc_trc = 0;
79module_param(lpfc_debugfs_max_disc_trc, int, 0); 80module_param(lpfc_debugfs_max_disc_trc, int, 0);
80MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc, 81MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc,
81 "Set debugfs discovery trace depth"); 82 "Set debugfs discovery trace depth");
82 83
84/* This MUST be a power of 2 */
85static int lpfc_debugfs_max_slow_ring_trc = 0;
86module_param(lpfc_debugfs_max_slow_ring_trc, int, 0);
87MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc,
88 "Set debugfs slow ring trace depth");
89
83static int lpfc_debugfs_mask_disc_trc = 0; 90static int lpfc_debugfs_mask_disc_trc = 0;
84module_param(lpfc_debugfs_mask_disc_trc, int, 0); 91module_param(lpfc_debugfs_mask_disc_trc, int, 0);
85MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc, 92MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
@@ -87,28 +94,34 @@ MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
87 94
88#include <linux/debugfs.h> 95#include <linux/debugfs.h>
89 96
90/* size of discovery_trace output line */ 97/* size of output line, for discovery_trace and slow_ring_trace */
91#define LPFC_DISC_TRC_ENTRY_SIZE 80 98#define LPFC_DEBUG_TRC_ENTRY_SIZE 100
92 99
93/* nodelist output buffer size */ 100/* nodelist output buffer size */
94#define LPFC_NODELIST_SIZE 8192 101#define LPFC_NODELIST_SIZE 8192
95#define LPFC_NODELIST_ENTRY_SIZE 120 102#define LPFC_NODELIST_ENTRY_SIZE 120
96 103
104/* dumpslim output buffer size */
105#define LPFC_DUMPSLIM_SIZE 4096
106
107/* hbqinfo output buffer size */
108#define LPFC_HBQINFO_SIZE 8192
109
97struct lpfc_debug { 110struct lpfc_debug {
98 char *buffer; 111 char *buffer;
99 int len; 112 int len;
100}; 113};
101 114
102atomic_t lpfc_debugfs_disc_trc_cnt = ATOMIC_INIT(0); 115static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
103unsigned long lpfc_debugfs_start_time = 0L; 116static unsigned long lpfc_debugfs_start_time = 0L;
104 117
105static int 118static int
106lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) 119lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
107{ 120{
108 int i, index, len, enable; 121 int i, index, len, enable;
109 uint32_t ms; 122 uint32_t ms;
110 struct lpfc_disc_trc *dtp; 123 struct lpfc_debugfs_trc *dtp;
111 char buffer[80]; 124 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
112 125
113 126
114 enable = lpfc_debugfs_enable; 127 enable = lpfc_debugfs_enable;
@@ -122,7 +135,8 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
122 if (!dtp->fmt) 135 if (!dtp->fmt)
123 continue; 136 continue;
124 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 137 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
125 snprintf(buffer, 80, "%010d:%010d ms:%s\n", 138 snprintf(buffer,
139 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
126 dtp->seq_cnt, ms, dtp->fmt); 140 dtp->seq_cnt, ms, dtp->fmt);
127 len += snprintf(buf+len, size-len, buffer, 141 len += snprintf(buf+len, size-len, buffer,
128 dtp->data1, dtp->data2, dtp->data3); 142 dtp->data1, dtp->data2, dtp->data3);
@@ -132,7 +146,8 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
132 if (!dtp->fmt) 146 if (!dtp->fmt)
133 continue; 147 continue;
134 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 148 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
135 snprintf(buffer, 80, "%010d:%010d ms:%s\n", 149 snprintf(buffer,
150 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
136 dtp->seq_cnt, ms, dtp->fmt); 151 dtp->seq_cnt, ms, dtp->fmt);
137 len += snprintf(buf+len, size-len, buffer, 152 len += snprintf(buf+len, size-len, buffer,
138 dtp->data1, dtp->data2, dtp->data3); 153 dtp->data1, dtp->data2, dtp->data3);
@@ -143,6 +158,236 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
143} 158}
144 159
145static int 160static int
161lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
162{
163 int i, index, len, enable;
164 uint32_t ms;
165 struct lpfc_debugfs_trc *dtp;
166 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
167
168
169 enable = lpfc_debugfs_enable;
170 lpfc_debugfs_enable = 0;
171
172 len = 0;
173 index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) &
174 (lpfc_debugfs_max_slow_ring_trc - 1);
175 for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) {
176 dtp = phba->slow_ring_trc + i;
177 if (!dtp->fmt)
178 continue;
179 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
180 snprintf(buffer,
181 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
182 dtp->seq_cnt, ms, dtp->fmt);
183 len += snprintf(buf+len, size-len, buffer,
184 dtp->data1, dtp->data2, dtp->data3);
185 }
186 for (i = 0; i < index; i++) {
187 dtp = phba->slow_ring_trc + i;
188 if (!dtp->fmt)
189 continue;
190 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time);
191 snprintf(buffer,
192 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n",
193 dtp->seq_cnt, ms, dtp->fmt);
194 len += snprintf(buf+len, size-len, buffer,
195 dtp->data1, dtp->data2, dtp->data3);
196 }
197
198 lpfc_debugfs_enable = enable;
199 return len;
200}
201
202static int lpfc_debugfs_last_hbq = -1;
203
204static int
205lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
206{
207 int len = 0;
208 int cnt, i, j, found, posted, low;
209 uint32_t phys, raw_index, getidx;
210 struct lpfc_hbq_init *hip;
211 struct hbq_s *hbqs;
212 struct lpfc_hbq_entry *hbqe;
213 struct lpfc_dmabuf *d_buf;
214 struct hbq_dmabuf *hbq_buf;
215
216 cnt = LPFC_HBQINFO_SIZE;
217 spin_lock_irq(&phba->hbalock);
218
219 /* toggle between multiple hbqs, if any */
220 i = lpfc_sli_hbq_count();
221 if (i > 1) {
222 lpfc_debugfs_last_hbq++;
223 if (lpfc_debugfs_last_hbq >= i)
224 lpfc_debugfs_last_hbq = 0;
225 }
226 else
227 lpfc_debugfs_last_hbq = 0;
228
229 i = lpfc_debugfs_last_hbq;
230
231 len += snprintf(buf+len, size-len, "HBQ %d Info\n", i);
232
233 hbqs = &phba->hbqs[i];
234 posted = 0;
235 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list)
236 posted++;
237
238 hip = lpfc_hbq_defs[i];
239 len += snprintf(buf+len, size-len,
240 "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n",
241 hip->hbq_index, hip->profile, hip->rn,
242 hip->buffer_count, hip->init_count, hip->add_count, posted);
243
244 raw_index = phba->hbq_get[i];
245 getidx = le32_to_cpu(raw_index);
246 len += snprintf(buf+len, size-len,
247 "entrys:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n",
248 hbqs->entry_count, hbqs->hbqPutIdx, hbqs->next_hbqPutIdx,
249 hbqs->local_hbqGetIdx, getidx);
250
251 hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt;
252 for (j=0; j<hbqs->entry_count; j++) {
253 len += snprintf(buf+len, size-len,
254 "%03d: %08x %04x %05x ", j,
255 hbqe->bde.addrLow, hbqe->bde.tus.w, hbqe->buffer_tag);
256
257 i = 0;
258 found = 0;
259
260 /* First calculate if slot has an associated posted buffer */
261 low = hbqs->hbqPutIdx - posted;
262 if (low >= 0) {
263 if ((j >= hbqs->hbqPutIdx) || (j < low)) {
264 len += snprintf(buf+len, size-len, "Unused\n");
265 goto skipit;
266 }
267 }
268 else {
269 if ((j >= hbqs->hbqPutIdx) &&
270 (j < (hbqs->entry_count+low))) {
271 len += snprintf(buf+len, size-len, "Unused\n");
272 goto skipit;
273 }
274 }
275
276 /* Get the Buffer info for the posted buffer */
277 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) {
278 hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf);
279 phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff);
280 if (phys == hbqe->bde.addrLow) {
281 len += snprintf(buf+len, size-len,
282 "Buf%d: %p %06x\n", i,
283 hbq_buf->dbuf.virt, hbq_buf->tag);
284 found = 1;
285 break;
286 }
287 i++;
288 }
289 if (!found) {
290 len += snprintf(buf+len, size-len, "No DMAinfo?\n");
291 }
292skipit:
293 hbqe++;
294 if (len > LPFC_HBQINFO_SIZE - 54)
295 break;
296 }
297 spin_unlock_irq(&phba->hbalock);
298 return len;
299}
300
301static int
302lpfc_debugfs_dumpslim_data(struct lpfc_hba *phba, char *buf, int size)
303{
304 int len = 0;
305 int cnt, i, off;
306 uint32_t word0, word1, word2, word3;
307 uint32_t *ptr;
308 struct lpfc_pgp *pgpp;
309 struct lpfc_sli *psli = &phba->sli;
310 struct lpfc_sli_ring *pring;
311
312 cnt = LPFC_DUMPSLIM_SIZE;
313 off = 0;
314 spin_lock_irq(&phba->hbalock);
315
316 len += snprintf(buf+len, size-len, "SLIM Mailbox\n");
317 ptr = (uint32_t *)phba->slim2p;
318 i = sizeof(MAILBOX_t);
319 while (i > 0) {
320 len += snprintf(buf+len, size-len,
321 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
322 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
323 *(ptr+5), *(ptr+6), *(ptr+7));
324 ptr += 8;
325 i -= (8 * sizeof(uint32_t));
326 off += (8 * sizeof(uint32_t));
327 }
328
329 len += snprintf(buf+len, size-len, "SLIM PCB\n");
330 ptr = (uint32_t *)&phba->slim2p->pcb;
331 i = sizeof(PCB_t);
332 while (i > 0) {
333 len += snprintf(buf+len, size-len,
334 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
335 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4),
336 *(ptr+5), *(ptr+6), *(ptr+7));
337 ptr += 8;
338 i -= (8 * sizeof(uint32_t));
339 off += (8 * sizeof(uint32_t));
340 }
341
342 pgpp = (struct lpfc_pgp *)&phba->slim2p->mbx.us.s3_pgp.port;
343 pring = &psli->ring[0];
344 len += snprintf(buf+len, size-len,
345 "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
346 "RSP PutInx:%d Max:%d\n",
347 pgpp->cmdGetInx, pring->numCiocb,
348 pring->next_cmdidx, pring->local_getidx, pring->flag,
349 pgpp->rspPutInx, pring->numRiocb);
350 pgpp++;
351
352 pring = &psli->ring[1];
353 len += snprintf(buf+len, size-len,
354 "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
355 "RSP PutInx:%d Max:%d\n",
356 pgpp->cmdGetInx, pring->numCiocb,
357 pring->next_cmdidx, pring->local_getidx, pring->flag,
358 pgpp->rspPutInx, pring->numRiocb);
359 pgpp++;
360
361 pring = &psli->ring[2];
362 len += snprintf(buf+len, size-len,
363 "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
364 "RSP PutInx:%d Max:%d\n",
365 pgpp->cmdGetInx, pring->numCiocb,
366 pring->next_cmdidx, pring->local_getidx, pring->flag,
367 pgpp->rspPutInx, pring->numRiocb);
368 pgpp++;
369
370 pring = &psli->ring[3];
371 len += snprintf(buf+len, size-len,
372 "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
373 "RSP PutInx:%d Max:%d\n",
374 pgpp->cmdGetInx, pring->numCiocb,
375 pring->next_cmdidx, pring->local_getidx, pring->flag,
376 pgpp->rspPutInx, pring->numRiocb);
377
378
379 ptr = (uint32_t *)&phba->slim2p->mbx.us.s3_pgp.hbq_get;
380 word0 = readl(phba->HAregaddr);
381 word1 = readl(phba->CAregaddr);
382 word2 = readl(phba->HSregaddr);
383 word3 = readl(phba->HCregaddr);
384 len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x HC:%08x\n",
385 word0, word1, word2, word3);
386 spin_unlock_irq(&phba->hbalock);
387 return len;
388}
389
390static int
146lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) 391lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
147{ 392{
148 int len = 0; 393 int len = 0;
@@ -204,7 +449,7 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
204 len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ", 449 len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ",
205 ndlp->nlp_rpi, ndlp->nlp_flag); 450 ndlp->nlp_rpi, ndlp->nlp_flag);
206 if (!ndlp->nlp_type) 451 if (!ndlp->nlp_type)
207 len += snprintf(buf+len, size-len, "UNKNOWN_TYPE"); 452 len += snprintf(buf+len, size-len, "UNKNOWN_TYPE ");
208 if (ndlp->nlp_type & NLP_FC_NODE) 453 if (ndlp->nlp_type & NLP_FC_NODE)
209 len += snprintf(buf+len, size-len, "FC_NODE "); 454 len += snprintf(buf+len, size-len, "FC_NODE ");
210 if (ndlp->nlp_type & NLP_FABRIC) 455 if (ndlp->nlp_type & NLP_FABRIC)
@@ -213,7 +458,9 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
213 len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ", 458 len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ",
214 ndlp->nlp_sid); 459 ndlp->nlp_sid);
215 if (ndlp->nlp_type & NLP_FCP_INITIATOR) 460 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
216 len += snprintf(buf+len, size-len, "FCP_INITIATOR"); 461 len += snprintf(buf+len, size-len, "FCP_INITIATOR ");
462 len += snprintf(buf+len, size-len, "refcnt:%x",
463 atomic_read(&ndlp->kref.refcount));
217 len += snprintf(buf+len, size-len, "\n"); 464 len += snprintf(buf+len, size-len, "\n");
218 } 465 }
219 spin_unlock_irq(shost->host_lock); 466 spin_unlock_irq(shost->host_lock);
@@ -227,7 +474,7 @@ lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
227 uint32_t data1, uint32_t data2, uint32_t data3) 474 uint32_t data1, uint32_t data2, uint32_t data3)
228{ 475{
229#ifdef CONFIG_LPFC_DEBUG_FS 476#ifdef CONFIG_LPFC_DEBUG_FS
230 struct lpfc_disc_trc *dtp; 477 struct lpfc_debugfs_trc *dtp;
231 int index; 478 int index;
232 479
233 if (!(lpfc_debugfs_mask_disc_trc & mask)) 480 if (!(lpfc_debugfs_mask_disc_trc & mask))
@@ -244,7 +491,32 @@ lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
244 dtp->data1 = data1; 491 dtp->data1 = data1;
245 dtp->data2 = data2; 492 dtp->data2 = data2;
246 dtp->data3 = data3; 493 dtp->data3 = data3;
247 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_disc_trc_cnt); 494 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
495 dtp->jif = jiffies;
496#endif
497 return;
498}
499
500inline void
501lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
502 uint32_t data1, uint32_t data2, uint32_t data3)
503{
504#ifdef CONFIG_LPFC_DEBUG_FS
505 struct lpfc_debugfs_trc *dtp;
506 int index;
507
508 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc ||
509 !phba || !phba->slow_ring_trc)
510 return;
511
512 index = atomic_inc_return(&phba->slow_ring_trc_cnt) &
513 (lpfc_debugfs_max_slow_ring_trc - 1);
514 dtp = phba->slow_ring_trc + index;
515 dtp->fmt = fmt;
516 dtp->data1 = data1;
517 dtp->data2 = data2;
518 dtp->data3 = data3;
519 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt);
248 dtp->jif = jiffies; 520 dtp->jif = jiffies;
249#endif 521#endif
250 return; 522 return;
@@ -269,7 +541,7 @@ lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
269 goto out; 541 goto out;
270 542
271 /* Round to page boundry */ 543 /* Round to page boundry */
272 size = (lpfc_debugfs_max_disc_trc * LPFC_DISC_TRC_ENTRY_SIZE); 544 size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
273 size = PAGE_ALIGN(size); 545 size = PAGE_ALIGN(size);
274 546
275 debug->buffer = kmalloc(size, GFP_KERNEL); 547 debug->buffer = kmalloc(size, GFP_KERNEL);
@@ -287,6 +559,95 @@ out:
287} 559}
288 560
289static int 561static int
562lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
563{
564 struct lpfc_hba *phba = inode->i_private;
565 struct lpfc_debug *debug;
566 int size;
567 int rc = -ENOMEM;
568
569 if (!lpfc_debugfs_max_slow_ring_trc) {
570 rc = -ENOSPC;
571 goto out;
572 }
573
574 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
575 if (!debug)
576 goto out;
577
578 /* Round to page boundry */
579 size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
580 size = PAGE_ALIGN(size);
581
582 debug->buffer = kmalloc(size, GFP_KERNEL);
583 if (!debug->buffer) {
584 kfree(debug);
585 goto out;
586 }
587
588 debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size);
589 file->private_data = debug;
590
591 rc = 0;
592out:
593 return rc;
594}
595
596static int
597lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
598{
599 struct lpfc_hba *phba = inode->i_private;
600 struct lpfc_debug *debug;
601 int rc = -ENOMEM;
602
603 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
604 if (!debug)
605 goto out;
606
607 /* Round to page boundry */
608 debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
609 if (!debug->buffer) {
610 kfree(debug);
611 goto out;
612 }
613
614 debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer,
615 LPFC_HBQINFO_SIZE);
616 file->private_data = debug;
617
618 rc = 0;
619out:
620 return rc;
621}
622
623static int
624lpfc_debugfs_dumpslim_open(struct inode *inode, struct file *file)
625{
626 struct lpfc_hba *phba = inode->i_private;
627 struct lpfc_debug *debug;
628 int rc = -ENOMEM;
629
630 debug = kmalloc(sizeof(*debug), GFP_KERNEL);
631 if (!debug)
632 goto out;
633
634 /* Round to page boundry */
635 debug->buffer = kmalloc(LPFC_DUMPSLIM_SIZE, GFP_KERNEL);
636 if (!debug->buffer) {
637 kfree(debug);
638 goto out;
639 }
640
641 debug->len = lpfc_debugfs_dumpslim_data(phba, debug->buffer,
642 LPFC_DUMPSLIM_SIZE);
643 file->private_data = debug;
644
645 rc = 0;
646out:
647 return rc;
648}
649
650static int
290lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file) 651lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
291{ 652{
292 struct lpfc_vport *vport = inode->i_private; 653 struct lpfc_vport *vport = inode->i_private;
@@ -372,6 +733,33 @@ static struct file_operations lpfc_debugfs_op_nodelist = {
372 .release = lpfc_debugfs_release, 733 .release = lpfc_debugfs_release,
373}; 734};
374 735
736#undef lpfc_debugfs_op_hbqinfo
737static struct file_operations lpfc_debugfs_op_hbqinfo = {
738 .owner = THIS_MODULE,
739 .open = lpfc_debugfs_hbqinfo_open,
740 .llseek = lpfc_debugfs_lseek,
741 .read = lpfc_debugfs_read,
742 .release = lpfc_debugfs_release,
743};
744
745#undef lpfc_debugfs_op_dumpslim
746static struct file_operations lpfc_debugfs_op_dumpslim = {
747 .owner = THIS_MODULE,
748 .open = lpfc_debugfs_dumpslim_open,
749 .llseek = lpfc_debugfs_lseek,
750 .read = lpfc_debugfs_read,
751 .release = lpfc_debugfs_release,
752};
753
754#undef lpfc_debugfs_op_slow_ring_trc
755static struct file_operations lpfc_debugfs_op_slow_ring_trc = {
756 .owner = THIS_MODULE,
757 .open = lpfc_debugfs_slow_ring_trc_open,
758 .llseek = lpfc_debugfs_lseek,
759 .read = lpfc_debugfs_read,
760 .release = lpfc_debugfs_release,
761};
762
375static struct dentry *lpfc_debugfs_root = NULL; 763static struct dentry *lpfc_debugfs_root = NULL;
376static atomic_t lpfc_debugfs_hba_count; 764static atomic_t lpfc_debugfs_hba_count;
377#endif 765#endif
@@ -387,60 +775,146 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
387 if (!lpfc_debugfs_enable) 775 if (!lpfc_debugfs_enable)
388 return; 776 return;
389 777
390 if (lpfc_debugfs_max_disc_trc) { 778 /* Setup lpfc root directory */
391 num = lpfc_debugfs_max_disc_trc - 1;
392 if (num & lpfc_debugfs_max_disc_trc) {
393 /* Change to be a power of 2 */
394 num = lpfc_debugfs_max_disc_trc;
395 i = 0;
396 while (num > 1) {
397 num = num >> 1;
398 i++;
399 }
400 lpfc_debugfs_max_disc_trc = (1 << i);
401 printk(KERN_ERR
402 "lpfc_debugfs_max_disc_trc changed to %d\n",
403 lpfc_debugfs_max_disc_trc);
404 }
405 }
406
407 if (!lpfc_debugfs_root) { 779 if (!lpfc_debugfs_root) {
408 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL); 780 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL);
409 atomic_set(&lpfc_debugfs_hba_count, 0); 781 atomic_set(&lpfc_debugfs_hba_count, 0);
410 if (!lpfc_debugfs_root) 782 if (!lpfc_debugfs_root) {
783 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
784 "0409 Cannot create debugfs root\n");
411 goto debug_failed; 785 goto debug_failed;
786 }
412 } 787 }
788 if (!lpfc_debugfs_start_time)
789 lpfc_debugfs_start_time = jiffies;
413 790
791 /* Setup lpfcX directory for specific HBA */
414 snprintf(name, sizeof(name), "lpfc%d", phba->brd_no); 792 snprintf(name, sizeof(name), "lpfc%d", phba->brd_no);
415 if (!phba->hba_debugfs_root) { 793 if (!phba->hba_debugfs_root) {
416 phba->hba_debugfs_root = 794 phba->hba_debugfs_root =
417 debugfs_create_dir(name, lpfc_debugfs_root); 795 debugfs_create_dir(name, lpfc_debugfs_root);
418 if (!phba->hba_debugfs_root) 796 if (!phba->hba_debugfs_root) {
797 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
798 "0409 Cannot create debugfs hba\n");
419 goto debug_failed; 799 goto debug_failed;
800 }
420 atomic_inc(&lpfc_debugfs_hba_count); 801 atomic_inc(&lpfc_debugfs_hba_count);
421 atomic_set(&phba->debugfs_vport_count, 0); 802 atomic_set(&phba->debugfs_vport_count, 0);
803
804 /* Setup hbqinfo */
805 snprintf(name, sizeof(name), "hbqinfo");
806 phba->debug_hbqinfo =
807 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
808 phba->hba_debugfs_root,
809 phba, &lpfc_debugfs_op_hbqinfo);
810 if (!phba->debug_hbqinfo) {
811 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
812 "0409 Cannot create debugfs hbqinfo\n");
813 goto debug_failed;
814 }
815
816 /* Setup dumpslim */
817 snprintf(name, sizeof(name), "dumpslim");
818 phba->debug_dumpslim =
819 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
820 phba->hba_debugfs_root,
821 phba, &lpfc_debugfs_op_dumpslim);
822 if (!phba->debug_dumpslim) {
823 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
824 "0409 Cannot create debugfs dumpslim\n");
825 goto debug_failed;
826 }
827
828 /* Setup slow ring trace */
829 if (lpfc_debugfs_max_slow_ring_trc) {
830 num = lpfc_debugfs_max_slow_ring_trc - 1;
831 if (num & lpfc_debugfs_max_slow_ring_trc) {
832 /* Change to be a power of 2 */
833 num = lpfc_debugfs_max_slow_ring_trc;
834 i = 0;
835 while (num > 1) {
836 num = num >> 1;
837 i++;
838 }
839 lpfc_debugfs_max_slow_ring_trc = (1 << i);
840 printk(KERN_ERR
841 "lpfc_debugfs_max_disc_trc changed to "
842 "%d\n", lpfc_debugfs_max_disc_trc);
843 }
844 }
845
846
847 snprintf(name, sizeof(name), "slow_ring_trace");
848 phba->debug_slow_ring_trc =
849 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
850 phba->hba_debugfs_root,
851 phba, &lpfc_debugfs_op_slow_ring_trc);
852 if (!phba->debug_slow_ring_trc) {
853 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
854 "0409 Cannot create debugfs "
855 "slow_ring_trace\n");
856 goto debug_failed;
857 }
858 if (!phba->slow_ring_trc) {
859 phba->slow_ring_trc = kmalloc(
860 (sizeof(struct lpfc_debugfs_trc) *
861 lpfc_debugfs_max_slow_ring_trc),
862 GFP_KERNEL);
863 if (!phba->slow_ring_trc) {
864 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
865 "0409 Cannot create debugfs "
866 "slow_ring buffer\n");
867 goto debug_failed;
868 }
869 atomic_set(&phba->slow_ring_trc_cnt, 0);
870 memset(phba->slow_ring_trc, 0,
871 (sizeof(struct lpfc_debugfs_trc) *
872 lpfc_debugfs_max_slow_ring_trc));
873 }
422 } 874 }
423 875
424 snprintf(name, sizeof(name), "vport%d", vport->vpi); 876 snprintf(name, sizeof(name), "vport%d", vport->vpi);
425 if (!vport->vport_debugfs_root) { 877 if (!vport->vport_debugfs_root) {
426 vport->vport_debugfs_root = 878 vport->vport_debugfs_root =
427 debugfs_create_dir(name, phba->hba_debugfs_root); 879 debugfs_create_dir(name, phba->hba_debugfs_root);
428 if (!vport->vport_debugfs_root) 880 if (!vport->vport_debugfs_root) {
881 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
882 "0409 Cant create debugfs");
429 goto debug_failed; 883 goto debug_failed;
884 }
430 atomic_inc(&phba->debugfs_vport_count); 885 atomic_inc(&phba->debugfs_vport_count);
431 } 886 }
432 887
433 if (!lpfc_debugfs_start_time) 888 if (lpfc_debugfs_max_disc_trc) {
434 lpfc_debugfs_start_time = jiffies; 889 num = lpfc_debugfs_max_disc_trc - 1;
890 if (num & lpfc_debugfs_max_disc_trc) {
891 /* Change to be a power of 2 */
892 num = lpfc_debugfs_max_disc_trc;
893 i = 0;
894 while (num > 1) {
895 num = num >> 1;
896 i++;
897 }
898 lpfc_debugfs_max_disc_trc = (1 << i);
899 printk(KERN_ERR
900 "lpfc_debugfs_max_disc_trc changed to %d\n",
901 lpfc_debugfs_max_disc_trc);
902 }
903 }
435 904
436 vport->disc_trc = kmalloc( 905 vport->disc_trc = kmalloc(
437 (sizeof(struct lpfc_disc_trc) * lpfc_debugfs_max_disc_trc), 906 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc),
438 GFP_KERNEL); 907 GFP_KERNEL);
439 908
440 if (!vport->disc_trc) 909 if (!vport->disc_trc) {
910 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
911 "0409 Cannot create debugfs disc trace "
912 "buffer\n");
441 goto debug_failed; 913 goto debug_failed;
914 }
915 atomic_set(&vport->disc_trc_cnt, 0);
442 memset(vport->disc_trc, 0, 916 memset(vport->disc_trc, 0,
443 (sizeof(struct lpfc_disc_trc) * lpfc_debugfs_max_disc_trc)); 917 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc));
444 918
445 snprintf(name, sizeof(name), "discovery_trace"); 919 snprintf(name, sizeof(name), "discovery_trace");
446 vport->debug_disc_trc = 920 vport->debug_disc_trc =
@@ -448,9 +922,9 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
448 vport->vport_debugfs_root, 922 vport->vport_debugfs_root,
449 vport, &lpfc_debugfs_op_disc_trc); 923 vport, &lpfc_debugfs_op_disc_trc);
450 if (!vport->debug_disc_trc) { 924 if (!vport->debug_disc_trc) {
451 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 925 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
452 "%d:0409 Cannot create debugfs", 926 "0409 Cannot create debugfs "
453 phba->brd_no); 927 "discovery_trace\n");
454 goto debug_failed; 928 goto debug_failed;
455 } 929 }
456 snprintf(name, sizeof(name), "nodelist"); 930 snprintf(name, sizeof(name), "nodelist");
@@ -459,9 +933,8 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
459 vport->vport_debugfs_root, 933 vport->vport_debugfs_root,
460 vport, &lpfc_debugfs_op_nodelist); 934 vport, &lpfc_debugfs_op_nodelist);
461 if (!vport->debug_nodelist) { 935 if (!vport->debug_nodelist) {
462 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 936 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
463 "%d:0409 Cannot create debugfs", 937 "0409 Cant create debugfs nodelist");
464 phba->brd_no);
465 goto debug_failed; 938 goto debug_failed;
466 } 939 }
467debug_failed: 940debug_failed:
@@ -488,21 +961,45 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
488 debugfs_remove(vport->debug_nodelist); /* nodelist */ 961 debugfs_remove(vport->debug_nodelist); /* nodelist */
489 vport->debug_nodelist = NULL; 962 vport->debug_nodelist = NULL;
490 } 963 }
964
491 if (vport->vport_debugfs_root) { 965 if (vport->vport_debugfs_root) {
492 debugfs_remove(vport->vport_debugfs_root); /* vportX */ 966 debugfs_remove(vport->vport_debugfs_root); /* vportX */
493 vport->vport_debugfs_root = NULL; 967 vport->vport_debugfs_root = NULL;
494 atomic_dec(&phba->debugfs_vport_count); 968 atomic_dec(&phba->debugfs_vport_count);
495 } 969 }
496 if (atomic_read(&phba->debugfs_vport_count) == 0) { 970 if (atomic_read(&phba->debugfs_vport_count) == 0) {
497 debugfs_remove(vport->phba->hba_debugfs_root); /* lpfcX */ 971
498 vport->phba->hba_debugfs_root = NULL; 972 if (phba->debug_hbqinfo) {
499 atomic_dec(&lpfc_debugfs_hba_count); 973 debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */
974 phba->debug_hbqinfo = NULL;
975 }
976 if (phba->debug_dumpslim) {
977 debugfs_remove(phba->debug_dumpslim); /* dumpslim */
978 phba->debug_dumpslim = NULL;
979 }
980 if (phba->slow_ring_trc) {
981 kfree(phba->slow_ring_trc);
982 phba->slow_ring_trc = NULL;
983 }
984 if (phba->debug_slow_ring_trc) {
985 /* slow_ring_trace */
986 debugfs_remove(phba->debug_slow_ring_trc);
987 phba->debug_slow_ring_trc = NULL;
988 }
989
990 if (phba->hba_debugfs_root) {
991 debugfs_remove(phba->hba_debugfs_root); /* lpfcX */
992 phba->hba_debugfs_root = NULL;
993 atomic_dec(&lpfc_debugfs_hba_count);
994 }
995
500 if (atomic_read(&lpfc_debugfs_hba_count) == 0) { 996 if (atomic_read(&lpfc_debugfs_hba_count) == 0) {
501 debugfs_remove(lpfc_debugfs_root); /* lpfc */ 997 debugfs_remove(lpfc_debugfs_root); /* lpfc */
502 lpfc_debugfs_root = NULL; 998 lpfc_debugfs_root = NULL;
503 } 999 }
504 } 1000 }
505#endif 1001#endif
1002 return;
506} 1003}
507 1004
508 1005