1 /******************************************************************* 2 * This file is part of the Emulex Linux Device Driver for * 3 * Fibre Channel Host Bus Adapters. * 4 * Copyright (C) 2007 Emulex. All rights reserved. * 5 * EMULEX and SLI are trademarks of Emulex. * 6 * www.emulex.com * 7 * * 8 * This program is free software; you can redistribute it and/or * 9 * modify it under the terms of version 2 of the GNU General * 10 * Public License as published by the Free Software Foundation. * 11 * This program is distributed in the hope that it will be useful. * 12 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * 13 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * 14 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * 15 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * 16 * TO BE LEGALLY INVALID. See the GNU General Public License for * 17 * more details, a copy of which can be found in the file COPYING * 18 * included with this package. * 19 *******************************************************************/ 20 21 #include <linux/blkdev.h> 22 #include <linux/delay.h> 23 #include <linux/dma-mapping.h> 24 #include <linux/idr.h> 25 #include <linux/interrupt.h> 26 #include <linux/kthread.h> 27 #include <linux/pci.h> 28 #include <linux/spinlock.h> 29 #include <linux/ctype.h> 30 #include <linux/version.h> 31 32 #include <scsi/scsi.h> 33 #include <scsi/scsi_device.h> 34 #include <scsi/scsi_host.h> 35 #include <scsi/scsi_transport_fc.h> 36 37 #include "lpfc_hw.h" 38 #include "lpfc_sli.h" 39 #include "lpfc_disc.h" 40 #include "lpfc_scsi.h" 41 #include "lpfc.h" 42 #include "lpfc_logmsg.h" 43 #include "lpfc_crtn.h" 44 #include "lpfc_vport.h" 45 #include "lpfc_version.h" 46 #include "lpfc_debugfs.h" 47 48 #ifdef CONFIG_LPFC_DEBUG_FS 49 /* debugfs interface 50 * 51 * To access this interface the user should: 52 * # mkdir /debug 53 * # mount -t debugfs none /debug 54 * 55 * The lpfc debugfs directory hierachy is: 56 * lpfc/lpfcX/vportY 57 * where X is the lpfc hba unique_id 58 * where Y is the vport VPI on that hba 59 * 60 * Debugging services available per vport: 61 * discovery_trace 62 * This is an ACSII readable file that contains a trace of the last 63 * lpfc_debugfs_max_disc_trc events that happened on a specific vport. 64 * See lpfc_debugfs.h for different categories of 65 * discovery events. To enable the discovery trace, the following 66 * module parameters must be set: 67 * lpfc_debugfs_enable=1 Turns on lpfc debugfs filesystem support 68 * lpfc_debugfs_max_disc_trc=X Where X is the event trace depth for 69 * EACH vport. X MUST also be a power of 2. 70 * lpfc_debugfs_mask_disc_trc=Y Where Y is an event mask as defined in 71 * lpfc_debugfs.h . 72 */ 73 static int lpfc_debugfs_enable = 1; 74 module_param(lpfc_debugfs_enable, int, 0); 75 MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services"); 76 77 /* This MUST be a power of 2 */ 78 static int lpfc_debugfs_max_disc_trc = 0; 79 module_param(lpfc_debugfs_max_disc_trc, int, 0); 80 MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc, 81 "Set debugfs discovery trace depth"); 82 83 /* This MUST be a power of 2 */ 84 static int lpfc_debugfs_max_slow_ring_trc = 0; 85 module_param(lpfc_debugfs_max_slow_ring_trc, int, 0); 86 MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc, 87 "Set debugfs slow ring trace depth"); 88 89 static int lpfc_debugfs_mask_disc_trc = 0; 90 module_param(lpfc_debugfs_mask_disc_trc, int, 0); 91 MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc, 92 "Set debugfs discovery trace mask"); 93 94 #include <linux/debugfs.h> 95 96 /* size of output line, for discovery_trace and slow_ring_trace */ 97 #define LPFC_DEBUG_TRC_ENTRY_SIZE 100 98 99 /* nodelist output buffer size */ 100 #define LPFC_NODELIST_SIZE 8192 101 #define LPFC_NODELIST_ENTRY_SIZE 120 102 103 /* dumpslim output buffer size */ 104 #define LPFC_DUMPSLIM_SIZE 4096 105 106 /* hbqinfo output buffer size */ 107 #define LPFC_HBQINFO_SIZE 8192 108 109 struct lpfc_debug { 110 char *buffer; 111 int len; 112 }; 113 114 static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0); 115 static unsigned long lpfc_debugfs_start_time = 0L; 116 117 static int 118 lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) 119 { 120 int i, index, len, enable; 121 uint32_t ms; 122 struct lpfc_debugfs_trc *dtp; 123 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE]; 124 125 126 enable = lpfc_debugfs_enable; 127 lpfc_debugfs_enable = 0; 128 129 len = 0; 130 index = (atomic_read(&vport->disc_trc_cnt) + 1) & 131 (lpfc_debugfs_max_disc_trc - 1); 132 for (i = index; i < lpfc_debugfs_max_disc_trc; i++) { 133 dtp = vport->disc_trc + i; 134 if (!dtp->fmt) 135 continue; 136 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 137 snprintf(buffer, 138 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 139 dtp->seq_cnt, ms, dtp->fmt); 140 len += snprintf(buf+len, size-len, buffer, 141 dtp->data1, dtp->data2, dtp->data3); 142 } 143 for (i = 0; i < index; i++) { 144 dtp = vport->disc_trc + i; 145 if (!dtp->fmt) 146 continue; 147 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 148 snprintf(buffer, 149 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 150 dtp->seq_cnt, ms, dtp->fmt); 151 len += snprintf(buf+len, size-len, buffer, 152 dtp->data1, dtp->data2, dtp->data3); 153 } 154 155 lpfc_debugfs_enable = enable; 156 return len; 157 } 158 159 static int 160 lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size) 161 { 162 int i, index, len, enable; 163 uint32_t ms; 164 struct lpfc_debugfs_trc *dtp; 165 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE]; 166 167 168 enable = lpfc_debugfs_enable; 169 lpfc_debugfs_enable = 0; 170 171 len = 0; 172 index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) & 173 (lpfc_debugfs_max_slow_ring_trc - 1); 174 for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) { 175 dtp = phba->slow_ring_trc + i; 176 if (!dtp->fmt) 177 continue; 178 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 179 snprintf(buffer, 180 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 181 dtp->seq_cnt, ms, dtp->fmt); 182 len += snprintf(buf+len, size-len, buffer, 183 dtp->data1, dtp->data2, dtp->data3); 184 } 185 for (i = 0; i < index; i++) { 186 dtp = phba->slow_ring_trc + i; 187 if (!dtp->fmt) 188 continue; 189 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 190 snprintf(buffer, 191 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 192 dtp->seq_cnt, ms, dtp->fmt); 193 len += snprintf(buf+len, size-len, buffer, 194 dtp->data1, dtp->data2, dtp->data3); 195 } 196 197 lpfc_debugfs_enable = enable; 198 return len; 199 } 200 201 static int lpfc_debugfs_last_hbq = -1; 202 203 static int 204 lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) 205 { 206 int len = 0; 207 int cnt, i, j, found, posted, low; 208 uint32_t phys, raw_index, getidx; 209 struct lpfc_hbq_init *hip; 210 struct hbq_s *hbqs; 211 struct lpfc_hbq_entry *hbqe; 212 struct lpfc_dmabuf *d_buf; 213 struct hbq_dmabuf *hbq_buf; 214 215 cnt = LPFC_HBQINFO_SIZE; 216 spin_lock_irq(&phba->hbalock); 217 218 /* toggle between multiple hbqs, if any */ 219 i = lpfc_sli_hbq_count(); 220 if (i > 1) { 221 lpfc_debugfs_last_hbq++; 222 if (lpfc_debugfs_last_hbq >= i) 223 lpfc_debugfs_last_hbq = 0; 224 } 225 else 226 lpfc_debugfs_last_hbq = 0; 227 228 i = lpfc_debugfs_last_hbq; 229 230 len += snprintf(buf+len, size-len, "HBQ %d Info\n", i); 231 232 hbqs = &phba->hbqs[i]; 233 posted = 0; 234 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) 235 posted++; 236 237 hip = lpfc_hbq_defs[i]; 238 len += snprintf(buf+len, size-len, 239 "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n", 240 hip->hbq_index, hip->profile, hip->rn, 241 hip->buffer_count, hip->init_count, hip->add_count, posted); 242 243 raw_index = phba->hbq_get[i]; 244 getidx = le32_to_cpu(raw_index); 245 len += snprintf(buf+len, size-len, 246 "entrys:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n", 247 hbqs->entry_count, hbqs->hbqPutIdx, hbqs->next_hbqPutIdx, 248 hbqs->local_hbqGetIdx, getidx); 249 250 hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt; 251 for (j=0; j<hbqs->entry_count; j++) { 252 len += snprintf(buf+len, size-len, 253 "%03d: %08x %04x %05x ", j, 254 hbqe->bde.addrLow, hbqe->bde.tus.w, hbqe->buffer_tag); 255 256 i = 0; 257 found = 0; 258 259 /* First calculate if slot has an associated posted buffer */ 260 low = hbqs->hbqPutIdx - posted; 261 if (low >= 0) { 262 if ((j >= hbqs->hbqPutIdx) || (j < low)) { 263 len += snprintf(buf+len, size-len, "Unused\n"); 264 goto skipit; 265 } 266 } 267 else { 268 if ((j >= hbqs->hbqPutIdx) && 269 (j < (hbqs->entry_count+low))) { 270 len += snprintf(buf+len, size-len, "Unused\n"); 271 goto skipit; 272 } 273 } 274 275 /* Get the Buffer info for the posted buffer */ 276 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) { 277 hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); 278 phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff); 279 if (phys == hbqe->bde.addrLow) { 280 len += snprintf(buf+len, size-len, 281 "Buf%d: %p %06x\n", i, 282 hbq_buf->dbuf.virt, hbq_buf->tag); 283 found = 1; 284 break; 285 } 286 i++; 287 } 288 if (!found) { 289 len += snprintf(buf+len, size-len, "No DMAinfo?\n"); 290 } 291 skipit: 292 hbqe++; 293 if (len > LPFC_HBQINFO_SIZE - 54) 294 break; 295 } 296 spin_unlock_irq(&phba->hbalock); 297 return len; 298 } 299 300 static int 301 lpfc_debugfs_dumpslim_data(struct lpfc_hba *phba, char *buf, int size) 302 { 303 int len = 0; 304 int cnt, i, off; 305 uint32_t word0, word1, word2, word3; 306 uint32_t *ptr; 307 struct lpfc_pgp *pgpp; 308 struct lpfc_sli *psli = &phba->sli; 309 struct lpfc_sli_ring *pring; 310 311 cnt = LPFC_DUMPSLIM_SIZE; 312 off = 0; 313 spin_lock_irq(&phba->hbalock); 314 315 len += snprintf(buf+len, size-len, "SLIM Mailbox\n"); 316 ptr = (uint32_t *)phba->slim2p; 317 i = sizeof(MAILBOX_t); 318 while (i > 0) { 319 len += snprintf(buf+len, size-len, 320 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", 321 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), 322 *(ptr+5), *(ptr+6), *(ptr+7)); 323 ptr += 8; 324 i -= (8 * sizeof(uint32_t)); 325 off += (8 * sizeof(uint32_t)); 326 } 327 328 len += snprintf(buf+len, size-len, "SLIM PCB\n"); 329 ptr = (uint32_t *)&phba->slim2p->pcb; 330 i = sizeof(PCB_t); 331 while (i > 0) { 332 len += snprintf(buf+len, size-len, 333 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", 334 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), 335 *(ptr+5), *(ptr+6), *(ptr+7)); 336 ptr += 8; 337 i -= (8 * sizeof(uint32_t)); 338 off += (8 * sizeof(uint32_t)); 339 } 340 341 pgpp = (struct lpfc_pgp *)&phba->slim2p->mbx.us.s3_pgp.port; 342 pring = &psli->ring[0]; 343 len += snprintf(buf+len, size-len, 344 "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " 345 "RSP PutInx:%d Max:%d\n", 346 pgpp->cmdGetInx, pring->numCiocb, 347 pring->next_cmdidx, pring->local_getidx, pring->flag, 348 pgpp->rspPutInx, pring->numRiocb); 349 pgpp++; 350 351 pring = &psli->ring[1]; 352 len += snprintf(buf+len, size-len, 353 "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " 354 "RSP PutInx:%d Max:%d\n", 355 pgpp->cmdGetInx, pring->numCiocb, 356 pring->next_cmdidx, pring->local_getidx, pring->flag, 357 pgpp->rspPutInx, pring->numRiocb); 358 pgpp++; 359 360 pring = &psli->ring[2]; 361 len += snprintf(buf+len, size-len, 362 "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " 363 "RSP PutInx:%d Max:%d\n", 364 pgpp->cmdGetInx, pring->numCiocb, 365 pring->next_cmdidx, pring->local_getidx, pring->flag, 366 pgpp->rspPutInx, pring->numRiocb); 367 pgpp++; 368 369 pring = &psli->ring[3]; 370 len += snprintf(buf+len, size-len, 371 "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " 372 "RSP PutInx:%d Max:%d\n", 373 pgpp->cmdGetInx, pring->numCiocb, 374 pring->next_cmdidx, pring->local_getidx, pring->flag, 375 pgpp->rspPutInx, pring->numRiocb); 376 377 378 ptr = (uint32_t *)&phba->slim2p->mbx.us.s3_pgp.hbq_get; 379 word0 = readl(phba->HAregaddr); 380 word1 = readl(phba->CAregaddr); 381 word2 = readl(phba->HSregaddr); 382 word3 = readl(phba->HCregaddr); 383 len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x HC:%08x\n", 384 word0, word1, word2, word3); 385 spin_unlock_irq(&phba->hbalock); 386 return len; 387 } 388 389 static int 390 lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) 391 { 392 int len = 0; 393 int cnt; 394 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 395 struct lpfc_nodelist *ndlp; 396 unsigned char *statep, *name; 397 398 cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE); 399 400 spin_lock_irq(shost->host_lock); 401 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 402 if (!cnt) { 403 len += snprintf(buf+len, size-len, 404 "Missing Nodelist Entries\n"); 405 break; 406 } 407 cnt--; 408 switch (ndlp->nlp_state) { 409 case NLP_STE_UNUSED_NODE: 410 statep = "UNUSED"; 411 break; 412 case NLP_STE_PLOGI_ISSUE: 413 statep = "PLOGI "; 414 break; 415 case NLP_STE_ADISC_ISSUE: 416 statep = "ADISC "; 417 break; 418 case NLP_STE_REG_LOGIN_ISSUE: 419 statep = "REGLOG"; 420 break; 421 case NLP_STE_PRLI_ISSUE: 422 statep = "PRLI "; 423 break; 424 case NLP_STE_UNMAPPED_NODE: 425 statep = "UNMAP "; 426 break; 427 case NLP_STE_MAPPED_NODE: 428 statep = "MAPPED"; 429 break; 430 case NLP_STE_NPR_NODE: 431 statep = "NPR "; 432 break; 433 default: 434 statep = "UNKNOWN"; 435 } 436 len += snprintf(buf+len, size-len, "%s DID:x%06x ", 437 statep, ndlp->nlp_DID); 438 name = (unsigned char *)&ndlp->nlp_portname; 439 len += snprintf(buf+len, size-len, 440 "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", 441 *name, *(name+1), *(name+2), *(name+3), 442 *(name+4), *(name+5), *(name+6), *(name+7)); 443 name = (unsigned char *)&ndlp->nlp_nodename; 444 len += snprintf(buf+len, size-len, 445 "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", 446 *name, *(name+1), *(name+2), *(name+3), 447 *(name+4), *(name+5), *(name+6), *(name+7)); 448 len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ", 449 ndlp->nlp_rpi, ndlp->nlp_flag); 450 if (!ndlp->nlp_type) 451 len += snprintf(buf+len, size-len, "UNKNOWN_TYPE "); 452 if (ndlp->nlp_type & NLP_FC_NODE) 453 len += snprintf(buf+len, size-len, "FC_NODE "); 454 if (ndlp->nlp_type & NLP_FABRIC) 455 len += snprintf(buf+len, size-len, "FABRIC "); 456 if (ndlp->nlp_type & NLP_FCP_TARGET) 457 len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ", 458 ndlp->nlp_sid); 459 if (ndlp->nlp_type & NLP_FCP_INITIATOR) 460 len += snprintf(buf+len, size-len, "FCP_INITIATOR "); 461 len += snprintf(buf+len, size-len, "refcnt:%x", 462 atomic_read(&ndlp->kref.refcount)); 463 len += snprintf(buf+len, size-len, "\n"); 464 } 465 spin_unlock_irq(shost->host_lock); 466 return len; 467 } 468 #endif 469 470 471 inline void 472 lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt, 473 uint32_t data1, uint32_t data2, uint32_t data3) 474 { 475 #ifdef CONFIG_LPFC_DEBUG_FS 476 struct lpfc_debugfs_trc *dtp; 477 int index; 478 479 if (!(lpfc_debugfs_mask_disc_trc & mask)) 480 return; 481 482 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc || 483 !vport || !vport->disc_trc) 484 return; 485 486 index = atomic_inc_return(&vport->disc_trc_cnt) & 487 (lpfc_debugfs_max_disc_trc - 1); 488 dtp = vport->disc_trc + index; 489 dtp->fmt = fmt; 490 dtp->data1 = data1; 491 dtp->data2 = data2; 492 dtp->data3 = data3; 493 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt); 494 dtp->jif = jiffies; 495 #endif 496 return; 497 } 498 499 inline void 500 lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt, 501 uint32_t data1, uint32_t data2, uint32_t data3) 502 { 503 #ifdef CONFIG_LPFC_DEBUG_FS 504 struct lpfc_debugfs_trc *dtp; 505 int index; 506 507 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc || 508 !phba || !phba->slow_ring_trc) 509 return; 510 511 index = atomic_inc_return(&phba->slow_ring_trc_cnt) & 512 (lpfc_debugfs_max_slow_ring_trc - 1); 513 dtp = phba->slow_ring_trc + index; 514 dtp->fmt = fmt; 515 dtp->data1 = data1; 516 dtp->data2 = data2; 517 dtp->data3 = data3; 518 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt); 519 dtp->jif = jiffies; 520 #endif 521 return; 522 } 523 524 #ifdef CONFIG_LPFC_DEBUG_FS 525 static int 526 lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file) 527 { 528 struct lpfc_vport *vport = inode->i_private; 529 struct lpfc_debug *debug; 530 int size; 531 int rc = -ENOMEM; 532 533 if (!lpfc_debugfs_max_disc_trc) { 534 rc = -ENOSPC; 535 goto out; 536 } 537 538 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 539 if (!debug) 540 goto out; 541 542 /* Round to page boundry */ 543 size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); 544 size = PAGE_ALIGN(size); 545 546 debug->buffer = kmalloc(size, GFP_KERNEL); 547 if (!debug->buffer) { 548 kfree(debug); 549 goto out; 550 } 551 552 debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size); 553 file->private_data = debug; 554 555 rc = 0; 556 out: 557 return rc; 558 } 559 560 static int 561 lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file) 562 { 563 struct lpfc_hba *phba = inode->i_private; 564 struct lpfc_debug *debug; 565 int size; 566 int rc = -ENOMEM; 567 568 if (!lpfc_debugfs_max_slow_ring_trc) { 569 rc = -ENOSPC; 570 goto out; 571 } 572 573 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 574 if (!debug) 575 goto out; 576 577 /* Round to page boundry */ 578 size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); 579 size = PAGE_ALIGN(size); 580 581 debug->buffer = kmalloc(size, GFP_KERNEL); 582 if (!debug->buffer) { 583 kfree(debug); 584 goto out; 585 } 586 587 debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size); 588 file->private_data = debug; 589 590 rc = 0; 591 out: 592 return rc; 593 } 594 595 static int 596 lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file) 597 { 598 struct lpfc_hba *phba = inode->i_private; 599 struct lpfc_debug *debug; 600 int rc = -ENOMEM; 601 602 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 603 if (!debug) 604 goto out; 605 606 /* Round to page boundry */ 607 debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL); 608 if (!debug->buffer) { 609 kfree(debug); 610 goto out; 611 } 612 613 debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer, 614 LPFC_HBQINFO_SIZE); 615 file->private_data = debug; 616 617 rc = 0; 618 out: 619 return rc; 620 } 621 622 static int 623 lpfc_debugfs_dumpslim_open(struct inode *inode, struct file *file) 624 { 625 struct lpfc_hba *phba = inode->i_private; 626 struct lpfc_debug *debug; 627 int rc = -ENOMEM; 628 629 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 630 if (!debug) 631 goto out; 632 633 /* Round to page boundry */ 634 debug->buffer = kmalloc(LPFC_DUMPSLIM_SIZE, GFP_KERNEL); 635 if (!debug->buffer) { 636 kfree(debug); 637 goto out; 638 } 639 640 debug->len = lpfc_debugfs_dumpslim_data(phba, debug->buffer, 641 LPFC_DUMPSLIM_SIZE); 642 file->private_data = debug; 643 644 rc = 0; 645 out: 646 return rc; 647 } 648 649 static int 650 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file) 651 { 652 struct lpfc_vport *vport = inode->i_private; 653 struct lpfc_debug *debug; 654 int rc = -ENOMEM; 655 656 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 657 if (!debug) 658 goto out; 659 660 /* Round to page boundry */ 661 debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL); 662 if (!debug->buffer) { 663 kfree(debug); 664 goto out; 665 } 666 667 debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer, 668 LPFC_NODELIST_SIZE); 669 file->private_data = debug; 670 671 rc = 0; 672 out: 673 return rc; 674 } 675 676 static loff_t 677 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence) 678 { 679 struct lpfc_debug *debug; 680 loff_t pos = -1; 681 682 debug = file->private_data; 683 684 switch (whence) { 685 case 0: 686 pos = off; 687 break; 688 case 1: 689 pos = file->f_pos + off; 690 break; 691 case 2: 692 pos = debug->len - off; 693 } 694 return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos); 695 } 696 697 static ssize_t 698 lpfc_debugfs_read(struct file *file, char __user *buf, 699 size_t nbytes, loff_t *ppos) 700 { 701 struct lpfc_debug *debug = file->private_data; 702 return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer, 703 debug->len); 704 } 705 706 static int 707 lpfc_debugfs_release(struct inode *inode, struct file *file) 708 { 709 struct lpfc_debug *debug = file->private_data; 710 711 kfree(debug->buffer); 712 kfree(debug); 713 714 return 0; 715 } 716 717 #undef lpfc_debugfs_op_disc_trc 718 static struct file_operations lpfc_debugfs_op_disc_trc = { 719 .owner = THIS_MODULE, 720 .open = lpfc_debugfs_disc_trc_open, 721 .llseek = lpfc_debugfs_lseek, 722 .read = lpfc_debugfs_read, 723 .release = lpfc_debugfs_release, 724 }; 725 726 #undef lpfc_debugfs_op_nodelist 727 static struct file_operations lpfc_debugfs_op_nodelist = { 728 .owner = THIS_MODULE, 729 .open = lpfc_debugfs_nodelist_open, 730 .llseek = lpfc_debugfs_lseek, 731 .read = lpfc_debugfs_read, 732 .release = lpfc_debugfs_release, 733 }; 734 735 #undef lpfc_debugfs_op_hbqinfo 736 static struct file_operations lpfc_debugfs_op_hbqinfo = { 737 .owner = THIS_MODULE, 738 .open = lpfc_debugfs_hbqinfo_open, 739 .llseek = lpfc_debugfs_lseek, 740 .read = lpfc_debugfs_read, 741 .release = lpfc_debugfs_release, 742 }; 743 744 #undef lpfc_debugfs_op_dumpslim 745 static struct file_operations lpfc_debugfs_op_dumpslim = { 746 .owner = THIS_MODULE, 747 .open = lpfc_debugfs_dumpslim_open, 748 .llseek = lpfc_debugfs_lseek, 749 .read = lpfc_debugfs_read, 750 .release = lpfc_debugfs_release, 751 }; 752 753 #undef lpfc_debugfs_op_slow_ring_trc 754 static struct file_operations lpfc_debugfs_op_slow_ring_trc = { 755 .owner = THIS_MODULE, 756 .open = lpfc_debugfs_slow_ring_trc_open, 757 .llseek = lpfc_debugfs_lseek, 758 .read = lpfc_debugfs_read, 759 .release = lpfc_debugfs_release, 760 }; 761 762 static struct dentry *lpfc_debugfs_root = NULL; 763 static atomic_t lpfc_debugfs_hba_count; 764 #endif 765 766 inline void 767 lpfc_debugfs_initialize(struct lpfc_vport *vport) 768 { 769 #ifdef CONFIG_LPFC_DEBUG_FS 770 struct lpfc_hba *phba = vport->phba; 771 char name[64]; 772 uint32_t num, i; 773 774 if (!lpfc_debugfs_enable) 775 return; 776 777 /* Setup lpfc root directory */ 778 if (!lpfc_debugfs_root) { 779 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL); 780 atomic_set(&lpfc_debugfs_hba_count, 0); 781 if (!lpfc_debugfs_root) { 782 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 783 "0409 Cannot create debugfs root\n"); 784 goto debug_failed; 785 } 786 } 787 if (!lpfc_debugfs_start_time) 788 lpfc_debugfs_start_time = jiffies; 789 790 /* Setup lpfcX directory for specific HBA */ 791 snprintf(name, sizeof(name), "lpfc%d", phba->brd_no); 792 if (!phba->hba_debugfs_root) { 793 phba->hba_debugfs_root = 794 debugfs_create_dir(name, lpfc_debugfs_root); 795 if (!phba->hba_debugfs_root) { 796 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 797 "0409 Cannot create debugfs hba\n"); 798 goto debug_failed; 799 } 800 atomic_inc(&lpfc_debugfs_hba_count); 801 atomic_set(&phba->debugfs_vport_count, 0); 802 803 /* Setup hbqinfo */ 804 snprintf(name, sizeof(name), "hbqinfo"); 805 phba->debug_hbqinfo = 806 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 807 phba->hba_debugfs_root, 808 phba, &lpfc_debugfs_op_hbqinfo); 809 if (!phba->debug_hbqinfo) { 810 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 811 "0409 Cannot create debugfs hbqinfo\n"); 812 goto debug_failed; 813 } 814 815 /* Setup dumpslim */ 816 snprintf(name, sizeof(name), "dumpslim"); 817 phba->debug_dumpslim = 818 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 819 phba->hba_debugfs_root, 820 phba, &lpfc_debugfs_op_dumpslim); 821 if (!phba->debug_dumpslim) { 822 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 823 "0409 Cannot create debugfs dumpslim\n"); 824 goto debug_failed; 825 } 826 827 /* Setup slow ring trace */ 828 if (lpfc_debugfs_max_slow_ring_trc) { 829 num = lpfc_debugfs_max_slow_ring_trc - 1; 830 if (num & lpfc_debugfs_max_slow_ring_trc) { 831 /* Change to be a power of 2 */ 832 num = lpfc_debugfs_max_slow_ring_trc; 833 i = 0; 834 while (num > 1) { 835 num = num >> 1; 836 i++; 837 } 838 lpfc_debugfs_max_slow_ring_trc = (1 << i); 839 printk(KERN_ERR 840 "lpfc_debugfs_max_disc_trc changed to " 841 "%d\n", lpfc_debugfs_max_disc_trc); 842 } 843 } 844 845 846 snprintf(name, sizeof(name), "slow_ring_trace"); 847 phba->debug_slow_ring_trc = 848 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 849 phba->hba_debugfs_root, 850 phba, &lpfc_debugfs_op_slow_ring_trc); 851 if (!phba->debug_slow_ring_trc) { 852 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 853 "0409 Cannot create debugfs " 854 "slow_ring_trace\n"); 855 goto debug_failed; 856 } 857 if (!phba->slow_ring_trc) { 858 phba->slow_ring_trc = kmalloc( 859 (sizeof(struct lpfc_debugfs_trc) * 860 lpfc_debugfs_max_slow_ring_trc), 861 GFP_KERNEL); 862 if (!phba->slow_ring_trc) { 863 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 864 "0409 Cannot create debugfs " 865 "slow_ring buffer\n"); 866 goto debug_failed; 867 } 868 atomic_set(&phba->slow_ring_trc_cnt, 0); 869 memset(phba->slow_ring_trc, 0, 870 (sizeof(struct lpfc_debugfs_trc) * 871 lpfc_debugfs_max_slow_ring_trc)); 872 } 873 } 874 875 snprintf(name, sizeof(name), "vport%d", vport->vpi); 876 if (!vport->vport_debugfs_root) { 877 vport->vport_debugfs_root = 878 debugfs_create_dir(name, phba->hba_debugfs_root); 879 if (!vport->vport_debugfs_root) { 880 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 881 "0409 Cant create debugfs"); 882 goto debug_failed; 883 } 884 atomic_inc(&phba->debugfs_vport_count); 885 } 886 887 if (lpfc_debugfs_max_disc_trc) { 888 num = lpfc_debugfs_max_disc_trc - 1; 889 if (num & lpfc_debugfs_max_disc_trc) { 890 /* Change to be a power of 2 */ 891 num = lpfc_debugfs_max_disc_trc; 892 i = 0; 893 while (num > 1) { 894 num = num >> 1; 895 i++; 896 } 897 lpfc_debugfs_max_disc_trc = (1 << i); 898 printk(KERN_ERR 899 "lpfc_debugfs_max_disc_trc changed to %d\n", 900 lpfc_debugfs_max_disc_trc); 901 } 902 } 903 904 vport->disc_trc = kmzlloc( 905 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc), 906 GFP_KERNEL); 907 908 if (!vport->disc_trc) { 909 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 910 "0409 Cannot create debugfs disc trace " 911 "buffer\n"); 912 goto debug_failed; 913 } 914 atomic_set(&vport->disc_trc_cnt, 0); 915 916 snprintf(name, sizeof(name), "discovery_trace"); 917 vport->debug_disc_trc = 918 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 919 vport->vport_debugfs_root, 920 vport, &lpfc_debugfs_op_disc_trc); 921 if (!vport->debug_disc_trc) { 922 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 923 "0409 Cannot create debugfs " 924 "discovery_trace\n"); 925 goto debug_failed; 926 } 927 snprintf(name, sizeof(name), "nodelist"); 928 vport->debug_nodelist = 929 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 930 vport->vport_debugfs_root, 931 vport, &lpfc_debugfs_op_nodelist); 932 if (!vport->debug_nodelist) { 933 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 934 "0409 Cant create debugfs nodelist"); 935 goto debug_failed; 936 } 937 debug_failed: 938 return; 939 #endif 940 } 941 942 943 inline void 944 lpfc_debugfs_terminate(struct lpfc_vport *vport) 945 { 946 #ifdef CONFIG_LPFC_DEBUG_FS 947 struct lpfc_hba *phba = vport->phba; 948 949 if (vport->disc_trc) { 950 kfree(vport->disc_trc); 951 vport->disc_trc = NULL; 952 } 953 if (vport->debug_disc_trc) { 954 debugfs_remove(vport->debug_disc_trc); /* discovery_trace */ 955 vport->debug_disc_trc = NULL; 956 } 957 if (vport->debug_nodelist) { 958 debugfs_remove(vport->debug_nodelist); /* nodelist */ 959 vport->debug_nodelist = NULL; 960 } 961 962 if (vport->vport_debugfs_root) { 963 debugfs_remove(vport->vport_debugfs_root); /* vportX */ 964 vport->vport_debugfs_root = NULL; 965 atomic_dec(&phba->debugfs_vport_count); 966 } 967 if (atomic_read(&phba->debugfs_vport_count) == 0) { 968 969 if (phba->debug_hbqinfo) { 970 debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */ 971 phba->debug_hbqinfo = NULL; 972 } 973 if (phba->debug_dumpslim) { 974 debugfs_remove(phba->debug_dumpslim); /* dumpslim */ 975 phba->debug_dumpslim = NULL; 976 } 977 if (phba->slow_ring_trc) { 978 kfree(phba->slow_ring_trc); 979 phba->slow_ring_trc = NULL; 980 } 981 if (phba->debug_slow_ring_trc) { 982 /* slow_ring_trace */ 983 debugfs_remove(phba->debug_slow_ring_trc); 984 phba->debug_slow_ring_trc = NULL; 985 } 986 987 if (phba->hba_debugfs_root) { 988 debugfs_remove(phba->hba_debugfs_root); /* lpfcX */ 989 phba->hba_debugfs_root = NULL; 990 atomic_dec(&lpfc_debugfs_hba_count); 991 } 992 993 if (atomic_read(&lpfc_debugfs_hba_count) == 0) { 994 debugfs_remove(lpfc_debugfs_root); /* lpfc */ 995 lpfc_debugfs_root = NULL; 996 } 997 } 998 #endif 999 return; 1000 } 1001 1002 1003