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_vport.h" 47 #include "lpfc_debugfs.h" 48 49 #ifdef CONFIG_LPFC_DEBUG_FS 50 /* debugfs interface 51 * 52 * To access this interface the user should: 53 * # mkdir /debug 54 * # mount -t debugfs none /debug 55 * 56 * The lpfc debugfs directory hierachy is: 57 * lpfc/lpfcX/vportY 58 * where X is the lpfc hba unique_id 59 * where Y is the vport VPI on that hba 60 * 61 * Debugging services available per vport: 62 * discovery_trace 63 * This is an ACSII readable file that contains a trace of the last 64 * lpfc_debugfs_max_disc_trc events that happened on a specific vport. 65 * See lpfc_debugfs.h for different categories of 66 * discovery events. To enable the discovery trace, the following 67 * module parameters must be set: 68 * lpfc_debugfs_enable=1 Turns on lpfc debugfs filesystem support 69 * lpfc_debugfs_max_disc_trc=X Where X is the event trace depth for 70 * EACH vport. X MUST also be a power of 2. 71 * lpfc_debugfs_mask_disc_trc=Y Where Y is an event mask as defined in 72 * lpfc_debugfs.h . 73 */ 74 static int lpfc_debugfs_enable = 1; 75 module_param(lpfc_debugfs_enable, int, 0); 76 MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services"); 77 78 /* This MUST be a power of 2 */ 79 static int lpfc_debugfs_max_disc_trc = 0; 80 module_param(lpfc_debugfs_max_disc_trc, int, 0); 81 MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc, 82 "Set debugfs discovery trace depth"); 83 84 /* This MUST be a power of 2 */ 85 static int lpfc_debugfs_max_slow_ring_trc = 0; 86 module_param(lpfc_debugfs_max_slow_ring_trc, int, 0); 87 MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc, 88 "Set debugfs slow ring trace depth"); 89 90 static int lpfc_debugfs_mask_disc_trc = 0; 91 module_param(lpfc_debugfs_mask_disc_trc, int, 0); 92 MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc, 93 "Set debugfs discovery trace mask"); 94 95 #include <linux/debugfs.h> 96 97 /* size of output line, for discovery_trace and slow_ring_trace */ 98 #define LPFC_DEBUG_TRC_ENTRY_SIZE 100 99 100 /* nodelist output buffer size */ 101 #define LPFC_NODELIST_SIZE 8192 102 #define LPFC_NODELIST_ENTRY_SIZE 120 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 110 struct lpfc_debug { 111 char *buffer; 112 int len; 113 }; 114 115 static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0); 116 static unsigned long lpfc_debugfs_start_time = 0L; 117 118 static int 119 lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) 120 { 121 int i, index, len, enable; 122 uint32_t ms; 123 struct lpfc_debugfs_trc *dtp; 124 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE]; 125 126 127 enable = lpfc_debugfs_enable; 128 lpfc_debugfs_enable = 0; 129 130 len = 0; 131 index = (atomic_read(&vport->disc_trc_cnt) + 1) & 132 (lpfc_debugfs_max_disc_trc - 1); 133 for (i = index; i < lpfc_debugfs_max_disc_trc; i++) { 134 dtp = vport->disc_trc + i; 135 if (!dtp->fmt) 136 continue; 137 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 138 snprintf(buffer, 139 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 140 dtp->seq_cnt, ms, dtp->fmt); 141 len += snprintf(buf+len, size-len, buffer, 142 dtp->data1, dtp->data2, dtp->data3); 143 } 144 for (i = 0; i < index; i++) { 145 dtp = vport->disc_trc + i; 146 if (!dtp->fmt) 147 continue; 148 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 149 snprintf(buffer, 150 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 151 dtp->seq_cnt, ms, dtp->fmt); 152 len += snprintf(buf+len, size-len, buffer, 153 dtp->data1, dtp->data2, dtp->data3); 154 } 155 156 lpfc_debugfs_enable = enable; 157 return len; 158 } 159 160 static int 161 lpfc_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 202 static int lpfc_debugfs_last_hbq = -1; 203 204 static int 205 lpfc_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 } 292 skipit: 293 hbqe++; 294 if (len > LPFC_HBQINFO_SIZE - 54) 295 break; 296 } 297 spin_unlock_irq(&phba->hbalock); 298 return len; 299 } 300 301 static int 302 lpfc_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 390 static int 391 lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) 392 { 393 int len = 0; 394 int cnt; 395 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 396 struct lpfc_nodelist *ndlp; 397 unsigned char *statep, *name; 398 399 cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE); 400 401 spin_lock_irq(shost->host_lock); 402 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 403 if (!cnt) { 404 len += snprintf(buf+len, size-len, 405 "Missing Nodelist Entries\n"); 406 break; 407 } 408 cnt--; 409 switch (ndlp->nlp_state) { 410 case NLP_STE_UNUSED_NODE: 411 statep = "UNUSED"; 412 break; 413 case NLP_STE_PLOGI_ISSUE: 414 statep = "PLOGI "; 415 break; 416 case NLP_STE_ADISC_ISSUE: 417 statep = "ADISC "; 418 break; 419 case NLP_STE_REG_LOGIN_ISSUE: 420 statep = "REGLOG"; 421 break; 422 case NLP_STE_PRLI_ISSUE: 423 statep = "PRLI "; 424 break; 425 case NLP_STE_UNMAPPED_NODE: 426 statep = "UNMAP "; 427 break; 428 case NLP_STE_MAPPED_NODE: 429 statep = "MAPPED"; 430 break; 431 case NLP_STE_NPR_NODE: 432 statep = "NPR "; 433 break; 434 default: 435 statep = "UNKNOWN"; 436 } 437 len += snprintf(buf+len, size-len, "%s DID:x%06x ", 438 statep, ndlp->nlp_DID); 439 name = (unsigned char *)&ndlp->nlp_portname; 440 len += snprintf(buf+len, size-len, 441 "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", 442 *name, *(name+1), *(name+2), *(name+3), 443 *(name+4), *(name+5), *(name+6), *(name+7)); 444 name = (unsigned char *)&ndlp->nlp_nodename; 445 len += snprintf(buf+len, size-len, 446 "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", 447 *name, *(name+1), *(name+2), *(name+3), 448 *(name+4), *(name+5), *(name+6), *(name+7)); 449 len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ", 450 ndlp->nlp_rpi, ndlp->nlp_flag); 451 if (!ndlp->nlp_type) 452 len += snprintf(buf+len, size-len, "UNKNOWN_TYPE "); 453 if (ndlp->nlp_type & NLP_FC_NODE) 454 len += snprintf(buf+len, size-len, "FC_NODE "); 455 if (ndlp->nlp_type & NLP_FABRIC) 456 len += snprintf(buf+len, size-len, "FABRIC "); 457 if (ndlp->nlp_type & NLP_FCP_TARGET) 458 len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ", 459 ndlp->nlp_sid); 460 if (ndlp->nlp_type & NLP_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)); 464 len += snprintf(buf+len, size-len, "\n"); 465 } 466 spin_unlock_irq(shost->host_lock); 467 return len; 468 } 469 #endif 470 471 472 inline void 473 lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt, 474 uint32_t data1, uint32_t data2, uint32_t data3) 475 { 476 #ifdef CONFIG_LPFC_DEBUG_FS 477 struct lpfc_debugfs_trc *dtp; 478 int index; 479 480 if (!(lpfc_debugfs_mask_disc_trc & mask)) 481 return; 482 483 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc || 484 !vport || !vport->disc_trc) 485 return; 486 487 index = atomic_inc_return(&vport->disc_trc_cnt) & 488 (lpfc_debugfs_max_disc_trc - 1); 489 dtp = vport->disc_trc + index; 490 dtp->fmt = fmt; 491 dtp->data1 = data1; 492 dtp->data2 = data2; 493 dtp->data3 = data3; 494 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt); 495 dtp->jif = jiffies; 496 #endif 497 return; 498 } 499 500 inline void 501 lpfc_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); 520 dtp->jif = jiffies; 521 #endif 522 return; 523 } 524 525 #ifdef CONFIG_LPFC_DEBUG_FS 526 static int 527 lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file) 528 { 529 struct lpfc_vport *vport = inode->i_private; 530 struct lpfc_debug *debug; 531 int size; 532 int rc = -ENOMEM; 533 534 if (!lpfc_debugfs_max_disc_trc) { 535 rc = -ENOSPC; 536 goto out; 537 } 538 539 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 540 if (!debug) 541 goto out; 542 543 /* Round to page boundry */ 544 size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); 545 size = PAGE_ALIGN(size); 546 547 debug->buffer = kmalloc(size, GFP_KERNEL); 548 if (!debug->buffer) { 549 kfree(debug); 550 goto out; 551 } 552 553 debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size); 554 file->private_data = debug; 555 556 rc = 0; 557 out: 558 return rc; 559 } 560 561 static int 562 lpfc_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; 592 out: 593 return rc; 594 } 595 596 static int 597 lpfc_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; 619 out: 620 return rc; 621 } 622 623 static int 624 lpfc_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; 646 out: 647 return rc; 648 } 649 650 static int 651 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file) 652 { 653 struct lpfc_vport *vport = inode->i_private; 654 struct lpfc_debug *debug; 655 int rc = -ENOMEM; 656 657 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 658 if (!debug) 659 goto out; 660 661 /* Round to page boundry */ 662 debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL); 663 if (!debug->buffer) { 664 kfree(debug); 665 goto out; 666 } 667 668 debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer, 669 LPFC_NODELIST_SIZE); 670 file->private_data = debug; 671 672 rc = 0; 673 out: 674 return rc; 675 } 676 677 static loff_t 678 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence) 679 { 680 struct lpfc_debug *debug; 681 loff_t pos = -1; 682 683 debug = file->private_data; 684 685 switch (whence) { 686 case 0: 687 pos = off; 688 break; 689 case 1: 690 pos = file->f_pos + off; 691 break; 692 case 2: 693 pos = debug->len - off; 694 } 695 return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos); 696 } 697 698 static ssize_t 699 lpfc_debugfs_read(struct file *file, char __user *buf, 700 size_t nbytes, loff_t *ppos) 701 { 702 struct lpfc_debug *debug = file->private_data; 703 return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer, 704 debug->len); 705 } 706 707 static int 708 lpfc_debugfs_release(struct inode *inode, struct file *file) 709 { 710 struct lpfc_debug *debug = file->private_data; 711 712 kfree(debug->buffer); 713 kfree(debug); 714 715 return 0; 716 } 717 718 #undef lpfc_debugfs_op_disc_trc 719 static struct file_operations lpfc_debugfs_op_disc_trc = { 720 .owner = THIS_MODULE, 721 .open = lpfc_debugfs_disc_trc_open, 722 .llseek = lpfc_debugfs_lseek, 723 .read = lpfc_debugfs_read, 724 .release = lpfc_debugfs_release, 725 }; 726 727 #undef lpfc_debugfs_op_nodelist 728 static struct file_operations lpfc_debugfs_op_nodelist = { 729 .owner = THIS_MODULE, 730 .open = lpfc_debugfs_nodelist_open, 731 .llseek = lpfc_debugfs_lseek, 732 .read = lpfc_debugfs_read, 733 .release = lpfc_debugfs_release, 734 }; 735 736 #undef lpfc_debugfs_op_hbqinfo 737 static 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 746 static 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 755 static 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 763 static struct dentry *lpfc_debugfs_root = NULL; 764 static atomic_t lpfc_debugfs_hba_count; 765 #endif 766 767 inline void 768 lpfc_debugfs_initialize(struct lpfc_vport *vport) 769 { 770 #ifdef CONFIG_LPFC_DEBUG_FS 771 struct lpfc_hba *phba = vport->phba; 772 char name[64]; 773 uint32_t num, i; 774 775 if (!lpfc_debugfs_enable) 776 return; 777 778 /* Setup lpfc root directory */ 779 if (!lpfc_debugfs_root) { 780 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL); 781 atomic_set(&lpfc_debugfs_hba_count, 0); 782 if (!lpfc_debugfs_root) { 783 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 784 "0409 Cannot create debugfs root\n"); 785 goto debug_failed; 786 } 787 } 788 if (!lpfc_debugfs_start_time) 789 lpfc_debugfs_start_time = jiffies; 790 791 /* Setup lpfcX directory for specific HBA */ 792 snprintf(name, sizeof(name), "lpfc%d", phba->brd_no); 793 if (!phba->hba_debugfs_root) { 794 phba->hba_debugfs_root = 795 debugfs_create_dir(name, lpfc_debugfs_root); 796 if (!phba->hba_debugfs_root) { 797 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 798 "0409 Cannot create debugfs hba\n"); 799 goto debug_failed; 800 } 801 atomic_inc(&lpfc_debugfs_hba_count); 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 } 874 } 875 876 snprintf(name, sizeof(name), "vport%d", vport->vpi); 877 if (!vport->vport_debugfs_root) { 878 vport->vport_debugfs_root = 879 debugfs_create_dir(name, phba->hba_debugfs_root); 880 if (!vport->vport_debugfs_root) { 881 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 882 "0409 Cant create debugfs"); 883 goto debug_failed; 884 } 885 atomic_inc(&phba->debugfs_vport_count); 886 } 887 888 if (lpfc_debugfs_max_disc_trc) { 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 } 904 905 vport->disc_trc = kmalloc( 906 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc), 907 GFP_KERNEL); 908 909 if (!vport->disc_trc) { 910 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 911 "0409 Cannot create debugfs disc trace " 912 "buffer\n"); 913 goto debug_failed; 914 } 915 atomic_set(&vport->disc_trc_cnt, 0); 916 memset(vport->disc_trc, 0, 917 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc)); 918 919 snprintf(name, sizeof(name), "discovery_trace"); 920 vport->debug_disc_trc = 921 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 922 vport->vport_debugfs_root, 923 vport, &lpfc_debugfs_op_disc_trc); 924 if (!vport->debug_disc_trc) { 925 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 926 "0409 Cannot create debugfs " 927 "discovery_trace\n"); 928 goto debug_failed; 929 } 930 snprintf(name, sizeof(name), "nodelist"); 931 vport->debug_nodelist = 932 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 933 vport->vport_debugfs_root, 934 vport, &lpfc_debugfs_op_nodelist); 935 if (!vport->debug_nodelist) { 936 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 937 "0409 Cant create debugfs nodelist"); 938 goto debug_failed; 939 } 940 debug_failed: 941 return; 942 #endif 943 } 944 945 946 inline void 947 lpfc_debugfs_terminate(struct lpfc_vport *vport) 948 { 949 #ifdef CONFIG_LPFC_DEBUG_FS 950 struct lpfc_hba *phba = vport->phba; 951 952 if (vport->disc_trc) { 953 kfree(vport->disc_trc); 954 vport->disc_trc = NULL; 955 } 956 if (vport->debug_disc_trc) { 957 debugfs_remove(vport->debug_disc_trc); /* discovery_trace */ 958 vport->debug_disc_trc = NULL; 959 } 960 if (vport->debug_nodelist) { 961 debugfs_remove(vport->debug_nodelist); /* nodelist */ 962 vport->debug_nodelist = NULL; 963 } 964 965 if (vport->vport_debugfs_root) { 966 debugfs_remove(vport->vport_debugfs_root); /* vportX */ 967 vport->vport_debugfs_root = NULL; 968 atomic_dec(&phba->debugfs_vport_count); 969 } 970 if (atomic_read(&phba->debugfs_vport_count) == 0) { 971 972 if (phba->debug_hbqinfo) { 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 996 if (atomic_read(&lpfc_debugfs_hba_count) == 0) { 997 debugfs_remove(lpfc_debugfs_root); /* lpfc */ 998 lpfc_debugfs_root = NULL; 999 } 1000 } 1001 #endif 1002 return; 1003 } 1004 1005 1006