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_compat.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; 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; 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 int lpfc_debugfs_mask_disc_trc; 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 /* dumpHBASlim output buffer size */ 105 #define LPFC_DUMPHBASLIM_SIZE 4096 106 107 /* dumpHostSlim output buffer size */ 108 #define LPFC_DUMPHOSTSLIM_SIZE 4096 109 110 /* hbqinfo output buffer size */ 111 #define LPFC_HBQINFO_SIZE 8192 112 113 struct lpfc_debug { 114 char *buffer; 115 int len; 116 }; 117 118 static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0); 119 static unsigned long lpfc_debugfs_start_time = 0L; 120 121 static int 122 lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) 123 { 124 int i, index, len, enable; 125 uint32_t ms; 126 struct lpfc_debugfs_trc *dtp; 127 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE]; 128 129 130 enable = lpfc_debugfs_enable; 131 lpfc_debugfs_enable = 0; 132 133 len = 0; 134 index = (atomic_read(&vport->disc_trc_cnt) + 1) & 135 (lpfc_debugfs_max_disc_trc - 1); 136 for (i = index; i < lpfc_debugfs_max_disc_trc; i++) { 137 dtp = vport->disc_trc + i; 138 if (!dtp->fmt) 139 continue; 140 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 141 snprintf(buffer, 142 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 143 dtp->seq_cnt, ms, dtp->fmt); 144 len += snprintf(buf+len, size-len, buffer, 145 dtp->data1, dtp->data2, dtp->data3); 146 } 147 for (i = 0; i < index; i++) { 148 dtp = vport->disc_trc + i; 149 if (!dtp->fmt) 150 continue; 151 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 152 snprintf(buffer, 153 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 154 dtp->seq_cnt, ms, dtp->fmt); 155 len += snprintf(buf+len, size-len, buffer, 156 dtp->data1, dtp->data2, dtp->data3); 157 } 158 159 lpfc_debugfs_enable = enable; 160 return len; 161 } 162 163 static int 164 lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size) 165 { 166 int i, index, len, enable; 167 uint32_t ms; 168 struct lpfc_debugfs_trc *dtp; 169 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE]; 170 171 172 enable = lpfc_debugfs_enable; 173 lpfc_debugfs_enable = 0; 174 175 len = 0; 176 index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) & 177 (lpfc_debugfs_max_slow_ring_trc - 1); 178 for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) { 179 dtp = phba->slow_ring_trc + i; 180 if (!dtp->fmt) 181 continue; 182 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 183 snprintf(buffer, 184 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 185 dtp->seq_cnt, ms, dtp->fmt); 186 len += snprintf(buf+len, size-len, buffer, 187 dtp->data1, dtp->data2, dtp->data3); 188 } 189 for (i = 0; i < index; i++) { 190 dtp = phba->slow_ring_trc + i; 191 if (!dtp->fmt) 192 continue; 193 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 194 snprintf(buffer, 195 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 196 dtp->seq_cnt, ms, dtp->fmt); 197 len += snprintf(buf+len, size-len, buffer, 198 dtp->data1, dtp->data2, dtp->data3); 199 } 200 201 lpfc_debugfs_enable = enable; 202 return len; 203 } 204 205 static int lpfc_debugfs_last_hbq = -1; 206 207 static int 208 lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) 209 { 210 int len = 0; 211 int cnt, i, j, found, posted, low; 212 uint32_t phys, raw_index, getidx; 213 struct lpfc_hbq_init *hip; 214 struct hbq_s *hbqs; 215 struct lpfc_hbq_entry *hbqe; 216 struct lpfc_dmabuf *d_buf; 217 struct hbq_dmabuf *hbq_buf; 218 219 cnt = LPFC_HBQINFO_SIZE; 220 spin_lock_irq(&phba->hbalock); 221 222 /* toggle between multiple hbqs, if any */ 223 i = lpfc_sli_hbq_count(); 224 if (i > 1) { 225 lpfc_debugfs_last_hbq++; 226 if (lpfc_debugfs_last_hbq >= i) 227 lpfc_debugfs_last_hbq = 0; 228 } 229 else 230 lpfc_debugfs_last_hbq = 0; 231 232 i = lpfc_debugfs_last_hbq; 233 234 len += snprintf(buf+len, size-len, "HBQ %d Info\n", i); 235 236 hbqs = &phba->hbqs[i]; 237 posted = 0; 238 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) 239 posted++; 240 241 hip = lpfc_hbq_defs[i]; 242 len += snprintf(buf+len, size-len, 243 "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n", 244 hip->hbq_index, hip->profile, hip->rn, 245 hip->buffer_count, hip->init_count, hip->add_count, posted); 246 247 raw_index = phba->hbq_get[i]; 248 getidx = le32_to_cpu(raw_index); 249 len += snprintf(buf+len, size-len, 250 "entrys:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n", 251 hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx, 252 hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx); 253 254 hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt; 255 for (j=0; j<hbqs->entry_count; j++) { 256 len += snprintf(buf+len, size-len, 257 "%03d: %08x %04x %05x ", j, 258 le32_to_cpu(hbqe->bde.addrLow), 259 le32_to_cpu(hbqe->bde.tus.w), 260 le32_to_cpu(hbqe->buffer_tag)); 261 i = 0; 262 found = 0; 263 264 /* First calculate if slot has an associated posted buffer */ 265 low = hbqs->hbqPutIdx - posted; 266 if (low >= 0) { 267 if ((j >= hbqs->hbqPutIdx) || (j < low)) { 268 len += snprintf(buf+len, size-len, "Unused\n"); 269 goto skipit; 270 } 271 } 272 else { 273 if ((j >= hbqs->hbqPutIdx) && 274 (j < (hbqs->entry_count+low))) { 275 len += snprintf(buf+len, size-len, "Unused\n"); 276 goto skipit; 277 } 278 } 279 280 /* Get the Buffer info for the posted buffer */ 281 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) { 282 hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); 283 phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff); 284 if (phys == le32_to_cpu(hbqe->bde.addrLow)) { 285 len += snprintf(buf+len, size-len, 286 "Buf%d: %p %06x\n", i, 287 hbq_buf->dbuf.virt, hbq_buf->tag); 288 found = 1; 289 break; 290 } 291 i++; 292 } 293 if (!found) { 294 len += snprintf(buf+len, size-len, "No DMAinfo?\n"); 295 } 296 skipit: 297 hbqe++; 298 if (len > LPFC_HBQINFO_SIZE - 54) 299 break; 300 } 301 spin_unlock_irq(&phba->hbalock); 302 return len; 303 } 304 305 static int lpfc_debugfs_last_hba_slim_off; 306 307 static int 308 lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size) 309 { 310 int len = 0; 311 int i, off; 312 uint32_t *ptr; 313 char buffer[1024]; 314 315 off = 0; 316 spin_lock_irq(&phba->hbalock); 317 318 len += snprintf(buf+len, size-len, "HBA SLIM\n"); 319 lpfc_memcpy_from_slim(buffer, 320 ((uint8_t *)phba->MBslimaddr) + lpfc_debugfs_last_hba_slim_off, 321 1024); 322 323 ptr = (uint32_t *)&buffer[0]; 324 off = lpfc_debugfs_last_hba_slim_off; 325 326 /* Set it up for the next time */ 327 lpfc_debugfs_last_hba_slim_off += 1024; 328 if (lpfc_debugfs_last_hba_slim_off >= 4096) 329 lpfc_debugfs_last_hba_slim_off = 0; 330 331 i = 1024; 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 spin_unlock_irq(&phba->hbalock); 343 return len; 344 } 345 346 static int 347 lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size) 348 { 349 int len = 0; 350 int i, off; 351 uint32_t word0, word1, word2, word3; 352 uint32_t *ptr; 353 struct lpfc_pgp *pgpp; 354 struct lpfc_sli *psli = &phba->sli; 355 struct lpfc_sli_ring *pring; 356 357 off = 0; 358 spin_lock_irq(&phba->hbalock); 359 360 len += snprintf(buf+len, size-len, "SLIM Mailbox\n"); 361 ptr = (uint32_t *)phba->slim2p; 362 i = sizeof(MAILBOX_t); 363 while (i > 0) { 364 len += snprintf(buf+len, size-len, 365 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", 366 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), 367 *(ptr+5), *(ptr+6), *(ptr+7)); 368 ptr += 8; 369 i -= (8 * sizeof(uint32_t)); 370 off += (8 * sizeof(uint32_t)); 371 } 372 373 len += snprintf(buf+len, size-len, "SLIM PCB\n"); 374 ptr = (uint32_t *)&phba->slim2p->pcb; 375 i = sizeof(PCB_t); 376 while (i > 0) { 377 len += snprintf(buf+len, size-len, 378 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", 379 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), 380 *(ptr+5), *(ptr+6), *(ptr+7)); 381 ptr += 8; 382 i -= (8 * sizeof(uint32_t)); 383 off += (8 * sizeof(uint32_t)); 384 } 385 386 pgpp = (struct lpfc_pgp *)&phba->slim2p->mbx.us.s3_pgp.port; 387 pring = &psli->ring[0]; 388 len += snprintf(buf+len, size-len, 389 "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " 390 "RSP PutInx:%d Max:%d\n", 391 pgpp->cmdGetInx, pring->numCiocb, 392 pring->next_cmdidx, pring->local_getidx, pring->flag, 393 pgpp->rspPutInx, pring->numRiocb); 394 pgpp++; 395 396 pring = &psli->ring[1]; 397 len += snprintf(buf+len, size-len, 398 "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " 399 "RSP PutInx:%d Max:%d\n", 400 pgpp->cmdGetInx, pring->numCiocb, 401 pring->next_cmdidx, pring->local_getidx, pring->flag, 402 pgpp->rspPutInx, pring->numRiocb); 403 pgpp++; 404 405 pring = &psli->ring[2]; 406 len += snprintf(buf+len, size-len, 407 "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " 408 "RSP PutInx:%d Max:%d\n", 409 pgpp->cmdGetInx, pring->numCiocb, 410 pring->next_cmdidx, pring->local_getidx, pring->flag, 411 pgpp->rspPutInx, pring->numRiocb); 412 pgpp++; 413 414 pring = &psli->ring[3]; 415 len += snprintf(buf+len, size-len, 416 "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) " 417 "RSP PutInx:%d Max:%d\n", 418 pgpp->cmdGetInx, pring->numCiocb, 419 pring->next_cmdidx, pring->local_getidx, pring->flag, 420 pgpp->rspPutInx, pring->numRiocb); 421 422 423 ptr = (uint32_t *)&phba->slim2p->mbx.us.s3_pgp.hbq_get; 424 word0 = readl(phba->HAregaddr); 425 word1 = readl(phba->CAregaddr); 426 word2 = readl(phba->HSregaddr); 427 word3 = readl(phba->HCregaddr); 428 len += snprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x HC:%08x\n", 429 word0, word1, word2, word3); 430 spin_unlock_irq(&phba->hbalock); 431 return len; 432 } 433 434 static int 435 lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) 436 { 437 int len = 0; 438 int cnt; 439 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 440 struct lpfc_nodelist *ndlp; 441 unsigned char *statep, *name; 442 443 cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE); 444 445 spin_lock_irq(shost->host_lock); 446 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 447 if (!cnt) { 448 len += snprintf(buf+len, size-len, 449 "Missing Nodelist Entries\n"); 450 break; 451 } 452 cnt--; 453 switch (ndlp->nlp_state) { 454 case NLP_STE_UNUSED_NODE: 455 statep = "UNUSED"; 456 break; 457 case NLP_STE_PLOGI_ISSUE: 458 statep = "PLOGI "; 459 break; 460 case NLP_STE_ADISC_ISSUE: 461 statep = "ADISC "; 462 break; 463 case NLP_STE_REG_LOGIN_ISSUE: 464 statep = "REGLOG"; 465 break; 466 case NLP_STE_PRLI_ISSUE: 467 statep = "PRLI "; 468 break; 469 case NLP_STE_UNMAPPED_NODE: 470 statep = "UNMAP "; 471 break; 472 case NLP_STE_MAPPED_NODE: 473 statep = "MAPPED"; 474 break; 475 case NLP_STE_NPR_NODE: 476 statep = "NPR "; 477 break; 478 default: 479 statep = "UNKNOWN"; 480 } 481 len += snprintf(buf+len, size-len, "%s DID:x%06x ", 482 statep, ndlp->nlp_DID); 483 name = (unsigned char *)&ndlp->nlp_portname; 484 len += snprintf(buf+len, size-len, 485 "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", 486 *name, *(name+1), *(name+2), *(name+3), 487 *(name+4), *(name+5), *(name+6), *(name+7)); 488 name = (unsigned char *)&ndlp->nlp_nodename; 489 len += snprintf(buf+len, size-len, 490 "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", 491 *name, *(name+1), *(name+2), *(name+3), 492 *(name+4), *(name+5), *(name+6), *(name+7)); 493 len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ", 494 ndlp->nlp_rpi, ndlp->nlp_flag); 495 if (!ndlp->nlp_type) 496 len += snprintf(buf+len, size-len, "UNKNOWN_TYPE "); 497 if (ndlp->nlp_type & NLP_FC_NODE) 498 len += snprintf(buf+len, size-len, "FC_NODE "); 499 if (ndlp->nlp_type & NLP_FABRIC) 500 len += snprintf(buf+len, size-len, "FABRIC "); 501 if (ndlp->nlp_type & NLP_FCP_TARGET) 502 len += snprintf(buf+len, size-len, "FCP_TGT sid:%d ", 503 ndlp->nlp_sid); 504 if (ndlp->nlp_type & NLP_FCP_INITIATOR) 505 len += snprintf(buf+len, size-len, "FCP_INITIATOR "); 506 len += snprintf(buf+len, size-len, "usgmap:%x ", 507 ndlp->nlp_usg_map); 508 len += snprintf(buf+len, size-len, "refcnt:%x", 509 atomic_read(&ndlp->kref.refcount)); 510 len += snprintf(buf+len, size-len, "\n"); 511 } 512 spin_unlock_irq(shost->host_lock); 513 return len; 514 } 515 #endif 516 517 518 inline void 519 lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt, 520 uint32_t data1, uint32_t data2, uint32_t data3) 521 { 522 #ifdef CONFIG_LPFC_DEBUG_FS 523 struct lpfc_debugfs_trc *dtp; 524 int index; 525 526 if (!(lpfc_debugfs_mask_disc_trc & mask)) 527 return; 528 529 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc || 530 !vport || !vport->disc_trc) 531 return; 532 533 index = atomic_inc_return(&vport->disc_trc_cnt) & 534 (lpfc_debugfs_max_disc_trc - 1); 535 dtp = vport->disc_trc + index; 536 dtp->fmt = fmt; 537 dtp->data1 = data1; 538 dtp->data2 = data2; 539 dtp->data3 = data3; 540 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt); 541 dtp->jif = jiffies; 542 #endif 543 return; 544 } 545 546 inline void 547 lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt, 548 uint32_t data1, uint32_t data2, uint32_t data3) 549 { 550 #ifdef CONFIG_LPFC_DEBUG_FS 551 struct lpfc_debugfs_trc *dtp; 552 int index; 553 554 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc || 555 !phba || !phba->slow_ring_trc) 556 return; 557 558 index = atomic_inc_return(&phba->slow_ring_trc_cnt) & 559 (lpfc_debugfs_max_slow_ring_trc - 1); 560 dtp = phba->slow_ring_trc + index; 561 dtp->fmt = fmt; 562 dtp->data1 = data1; 563 dtp->data2 = data2; 564 dtp->data3 = data3; 565 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt); 566 dtp->jif = jiffies; 567 #endif 568 return; 569 } 570 571 #ifdef CONFIG_LPFC_DEBUG_FS 572 static int 573 lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file) 574 { 575 struct lpfc_vport *vport = inode->i_private; 576 struct lpfc_debug *debug; 577 int size; 578 int rc = -ENOMEM; 579 580 if (!lpfc_debugfs_max_disc_trc) { 581 rc = -ENOSPC; 582 goto out; 583 } 584 585 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 586 if (!debug) 587 goto out; 588 589 /* Round to page boundry */ 590 size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); 591 size = PAGE_ALIGN(size); 592 593 debug->buffer = kmalloc(size, GFP_KERNEL); 594 if (!debug->buffer) { 595 kfree(debug); 596 goto out; 597 } 598 599 debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size); 600 file->private_data = debug; 601 602 rc = 0; 603 out: 604 return rc; 605 } 606 607 static int 608 lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file) 609 { 610 struct lpfc_hba *phba = inode->i_private; 611 struct lpfc_debug *debug; 612 int size; 613 int rc = -ENOMEM; 614 615 if (!lpfc_debugfs_max_slow_ring_trc) { 616 rc = -ENOSPC; 617 goto out; 618 } 619 620 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 621 if (!debug) 622 goto out; 623 624 /* Round to page boundry */ 625 size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); 626 size = PAGE_ALIGN(size); 627 628 debug->buffer = kmalloc(size, GFP_KERNEL); 629 if (!debug->buffer) { 630 kfree(debug); 631 goto out; 632 } 633 634 debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size); 635 file->private_data = debug; 636 637 rc = 0; 638 out: 639 return rc; 640 } 641 642 static int 643 lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file) 644 { 645 struct lpfc_hba *phba = inode->i_private; 646 struct lpfc_debug *debug; 647 int rc = -ENOMEM; 648 649 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 650 if (!debug) 651 goto out; 652 653 /* Round to page boundry */ 654 debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL); 655 if (!debug->buffer) { 656 kfree(debug); 657 goto out; 658 } 659 660 debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer, 661 LPFC_HBQINFO_SIZE); 662 file->private_data = debug; 663 664 rc = 0; 665 out: 666 return rc; 667 } 668 669 static int 670 lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file) 671 { 672 struct lpfc_hba *phba = inode->i_private; 673 struct lpfc_debug *debug; 674 int rc = -ENOMEM; 675 676 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 677 if (!debug) 678 goto out; 679 680 /* Round to page boundry */ 681 debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL); 682 if (!debug->buffer) { 683 kfree(debug); 684 goto out; 685 } 686 687 debug->len = lpfc_debugfs_dumpHBASlim_data(phba, debug->buffer, 688 LPFC_DUMPHBASLIM_SIZE); 689 file->private_data = debug; 690 691 rc = 0; 692 out: 693 return rc; 694 } 695 696 static int 697 lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file) 698 { 699 struct lpfc_hba *phba = inode->i_private; 700 struct lpfc_debug *debug; 701 int rc = -ENOMEM; 702 703 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 704 if (!debug) 705 goto out; 706 707 /* Round to page boundry */ 708 debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL); 709 if (!debug->buffer) { 710 kfree(debug); 711 goto out; 712 } 713 714 debug->len = lpfc_debugfs_dumpHostSlim_data(phba, debug->buffer, 715 LPFC_DUMPHOSTSLIM_SIZE); 716 file->private_data = debug; 717 718 rc = 0; 719 out: 720 return rc; 721 } 722 723 static int 724 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file) 725 { 726 struct lpfc_vport *vport = inode->i_private; 727 struct lpfc_debug *debug; 728 int rc = -ENOMEM; 729 730 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 731 if (!debug) 732 goto out; 733 734 /* Round to page boundry */ 735 debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL); 736 if (!debug->buffer) { 737 kfree(debug); 738 goto out; 739 } 740 741 debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer, 742 LPFC_NODELIST_SIZE); 743 file->private_data = debug; 744 745 rc = 0; 746 out: 747 return rc; 748 } 749 750 static loff_t 751 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence) 752 { 753 struct lpfc_debug *debug; 754 loff_t pos = -1; 755 756 debug = file->private_data; 757 758 switch (whence) { 759 case 0: 760 pos = off; 761 break; 762 case 1: 763 pos = file->f_pos + off; 764 break; 765 case 2: 766 pos = debug->len - off; 767 } 768 return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos); 769 } 770 771 static ssize_t 772 lpfc_debugfs_read(struct file *file, char __user *buf, 773 size_t nbytes, loff_t *ppos) 774 { 775 struct lpfc_debug *debug = file->private_data; 776 return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer, 777 debug->len); 778 } 779 780 static int 781 lpfc_debugfs_release(struct inode *inode, struct file *file) 782 { 783 struct lpfc_debug *debug = file->private_data; 784 785 kfree(debug->buffer); 786 kfree(debug); 787 788 return 0; 789 } 790 791 #undef lpfc_debugfs_op_disc_trc 792 static struct file_operations lpfc_debugfs_op_disc_trc = { 793 .owner = THIS_MODULE, 794 .open = lpfc_debugfs_disc_trc_open, 795 .llseek = lpfc_debugfs_lseek, 796 .read = lpfc_debugfs_read, 797 .release = lpfc_debugfs_release, 798 }; 799 800 #undef lpfc_debugfs_op_nodelist 801 static struct file_operations lpfc_debugfs_op_nodelist = { 802 .owner = THIS_MODULE, 803 .open = lpfc_debugfs_nodelist_open, 804 .llseek = lpfc_debugfs_lseek, 805 .read = lpfc_debugfs_read, 806 .release = lpfc_debugfs_release, 807 }; 808 809 #undef lpfc_debugfs_op_hbqinfo 810 static struct file_operations lpfc_debugfs_op_hbqinfo = { 811 .owner = THIS_MODULE, 812 .open = lpfc_debugfs_hbqinfo_open, 813 .llseek = lpfc_debugfs_lseek, 814 .read = lpfc_debugfs_read, 815 .release = lpfc_debugfs_release, 816 }; 817 818 #undef lpfc_debugfs_op_dumpHBASlim 819 static struct file_operations lpfc_debugfs_op_dumpHBASlim = { 820 .owner = THIS_MODULE, 821 .open = lpfc_debugfs_dumpHBASlim_open, 822 .llseek = lpfc_debugfs_lseek, 823 .read = lpfc_debugfs_read, 824 .release = lpfc_debugfs_release, 825 }; 826 827 #undef lpfc_debugfs_op_dumpHostSlim 828 static struct file_operations lpfc_debugfs_op_dumpHostSlim = { 829 .owner = THIS_MODULE, 830 .open = lpfc_debugfs_dumpHostSlim_open, 831 .llseek = lpfc_debugfs_lseek, 832 .read = lpfc_debugfs_read, 833 .release = lpfc_debugfs_release, 834 }; 835 836 #undef lpfc_debugfs_op_slow_ring_trc 837 static struct file_operations lpfc_debugfs_op_slow_ring_trc = { 838 .owner = THIS_MODULE, 839 .open = lpfc_debugfs_slow_ring_trc_open, 840 .llseek = lpfc_debugfs_lseek, 841 .read = lpfc_debugfs_read, 842 .release = lpfc_debugfs_release, 843 }; 844 845 static struct dentry *lpfc_debugfs_root = NULL; 846 static atomic_t lpfc_debugfs_hba_count; 847 #endif 848 849 inline void 850 lpfc_debugfs_initialize(struct lpfc_vport *vport) 851 { 852 #ifdef CONFIG_LPFC_DEBUG_FS 853 struct lpfc_hba *phba = vport->phba; 854 char name[64]; 855 uint32_t num, i; 856 857 if (!lpfc_debugfs_enable) 858 return; 859 860 /* Setup lpfc root directory */ 861 if (!lpfc_debugfs_root) { 862 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL); 863 atomic_set(&lpfc_debugfs_hba_count, 0); 864 if (!lpfc_debugfs_root) { 865 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 866 "0409 Cannot create debugfs root\n"); 867 goto debug_failed; 868 } 869 } 870 if (!lpfc_debugfs_start_time) 871 lpfc_debugfs_start_time = jiffies; 872 873 /* Setup lpfcX directory for specific HBA */ 874 snprintf(name, sizeof(name), "lpfc%d", phba->brd_no); 875 if (!phba->hba_debugfs_root) { 876 phba->hba_debugfs_root = 877 debugfs_create_dir(name, lpfc_debugfs_root); 878 if (!phba->hba_debugfs_root) { 879 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 880 "0409 Cannot create debugfs hba\n"); 881 goto debug_failed; 882 } 883 atomic_inc(&lpfc_debugfs_hba_count); 884 atomic_set(&phba->debugfs_vport_count, 0); 885 886 /* Setup hbqinfo */ 887 snprintf(name, sizeof(name), "hbqinfo"); 888 phba->debug_hbqinfo = 889 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 890 phba->hba_debugfs_root, 891 phba, &lpfc_debugfs_op_hbqinfo); 892 if (!phba->debug_hbqinfo) { 893 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 894 "0409 Cannot create debugfs hbqinfo\n"); 895 goto debug_failed; 896 } 897 898 /* Setup dumpHBASlim */ 899 snprintf(name, sizeof(name), "dumpHBASlim"); 900 phba->debug_dumpHBASlim = 901 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 902 phba->hba_debugfs_root, 903 phba, &lpfc_debugfs_op_dumpHBASlim); 904 if (!phba->debug_dumpHBASlim) { 905 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 906 "0409 Cannot create debugfs dumpHBASlim\n"); 907 goto debug_failed; 908 } 909 910 /* Setup dumpHostSlim */ 911 snprintf(name, sizeof(name), "dumpHostSlim"); 912 phba->debug_dumpHostSlim = 913 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 914 phba->hba_debugfs_root, 915 phba, &lpfc_debugfs_op_dumpHostSlim); 916 if (!phba->debug_dumpHostSlim) { 917 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 918 "0409 Cannot create debugfs dumpHostSlim\n"); 919 goto debug_failed; 920 } 921 922 /* Setup slow ring trace */ 923 if (lpfc_debugfs_max_slow_ring_trc) { 924 num = lpfc_debugfs_max_slow_ring_trc - 1; 925 if (num & lpfc_debugfs_max_slow_ring_trc) { 926 /* Change to be a power of 2 */ 927 num = lpfc_debugfs_max_slow_ring_trc; 928 i = 0; 929 while (num > 1) { 930 num = num >> 1; 931 i++; 932 } 933 lpfc_debugfs_max_slow_ring_trc = (1 << i); 934 printk(KERN_ERR 935 "lpfc_debugfs_max_disc_trc changed to " 936 "%d\n", lpfc_debugfs_max_disc_trc); 937 } 938 } 939 940 941 snprintf(name, sizeof(name), "slow_ring_trace"); 942 phba->debug_slow_ring_trc = 943 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 944 phba->hba_debugfs_root, 945 phba, &lpfc_debugfs_op_slow_ring_trc); 946 if (!phba->debug_slow_ring_trc) { 947 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 948 "0409 Cannot create debugfs " 949 "slow_ring_trace\n"); 950 goto debug_failed; 951 } 952 if (!phba->slow_ring_trc) { 953 phba->slow_ring_trc = kmalloc( 954 (sizeof(struct lpfc_debugfs_trc) * 955 lpfc_debugfs_max_slow_ring_trc), 956 GFP_KERNEL); 957 if (!phba->slow_ring_trc) { 958 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 959 "0409 Cannot create debugfs " 960 "slow_ring buffer\n"); 961 goto debug_failed; 962 } 963 atomic_set(&phba->slow_ring_trc_cnt, 0); 964 memset(phba->slow_ring_trc, 0, 965 (sizeof(struct lpfc_debugfs_trc) * 966 lpfc_debugfs_max_slow_ring_trc)); 967 } 968 } 969 970 snprintf(name, sizeof(name), "vport%d", vport->vpi); 971 if (!vport->vport_debugfs_root) { 972 vport->vport_debugfs_root = 973 debugfs_create_dir(name, phba->hba_debugfs_root); 974 if (!vport->vport_debugfs_root) { 975 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 976 "0409 Cant create debugfs"); 977 goto debug_failed; 978 } 979 atomic_inc(&phba->debugfs_vport_count); 980 } 981 982 if (lpfc_debugfs_max_disc_trc) { 983 num = lpfc_debugfs_max_disc_trc - 1; 984 if (num & lpfc_debugfs_max_disc_trc) { 985 /* Change to be a power of 2 */ 986 num = lpfc_debugfs_max_disc_trc; 987 i = 0; 988 while (num > 1) { 989 num = num >> 1; 990 i++; 991 } 992 lpfc_debugfs_max_disc_trc = (1 << i); 993 printk(KERN_ERR 994 "lpfc_debugfs_max_disc_trc changed to %d\n", 995 lpfc_debugfs_max_disc_trc); 996 } 997 } 998 999 vport->disc_trc = kzalloc( 1000 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc), 1001 GFP_KERNEL); 1002 1003 if (!vport->disc_trc) { 1004 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 1005 "0409 Cannot create debugfs disc trace " 1006 "buffer\n"); 1007 goto debug_failed; 1008 } 1009 atomic_set(&vport->disc_trc_cnt, 0); 1010 1011 snprintf(name, sizeof(name), "discovery_trace"); 1012 vport->debug_disc_trc = 1013 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 1014 vport->vport_debugfs_root, 1015 vport, &lpfc_debugfs_op_disc_trc); 1016 if (!vport->debug_disc_trc) { 1017 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 1018 "0409 Cannot create debugfs " 1019 "discovery_trace\n"); 1020 goto debug_failed; 1021 } 1022 snprintf(name, sizeof(name), "nodelist"); 1023 vport->debug_nodelist = 1024 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 1025 vport->vport_debugfs_root, 1026 vport, &lpfc_debugfs_op_nodelist); 1027 if (!vport->debug_nodelist) { 1028 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 1029 "0409 Cant create debugfs nodelist"); 1030 goto debug_failed; 1031 } 1032 debug_failed: 1033 return; 1034 #endif 1035 } 1036 1037 1038 inline void 1039 lpfc_debugfs_terminate(struct lpfc_vport *vport) 1040 { 1041 #ifdef CONFIG_LPFC_DEBUG_FS 1042 struct lpfc_hba *phba = vport->phba; 1043 1044 if (vport->disc_trc) { 1045 kfree(vport->disc_trc); 1046 vport->disc_trc = NULL; 1047 } 1048 if (vport->debug_disc_trc) { 1049 debugfs_remove(vport->debug_disc_trc); /* discovery_trace */ 1050 vport->debug_disc_trc = NULL; 1051 } 1052 if (vport->debug_nodelist) { 1053 debugfs_remove(vport->debug_nodelist); /* nodelist */ 1054 vport->debug_nodelist = NULL; 1055 } 1056 1057 if (vport->vport_debugfs_root) { 1058 debugfs_remove(vport->vport_debugfs_root); /* vportX */ 1059 vport->vport_debugfs_root = NULL; 1060 atomic_dec(&phba->debugfs_vport_count); 1061 } 1062 if (atomic_read(&phba->debugfs_vport_count) == 0) { 1063 1064 if (phba->debug_hbqinfo) { 1065 debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */ 1066 phba->debug_hbqinfo = NULL; 1067 } 1068 if (phba->debug_dumpHBASlim) { 1069 debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */ 1070 phba->debug_dumpHBASlim = NULL; 1071 } 1072 if (phba->debug_dumpHostSlim) { 1073 debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */ 1074 phba->debug_dumpHostSlim = NULL; 1075 } 1076 if (phba->slow_ring_trc) { 1077 kfree(phba->slow_ring_trc); 1078 phba->slow_ring_trc = NULL; 1079 } 1080 if (phba->debug_slow_ring_trc) { 1081 /* slow_ring_trace */ 1082 debugfs_remove(phba->debug_slow_ring_trc); 1083 phba->debug_slow_ring_trc = NULL; 1084 } 1085 1086 if (phba->hba_debugfs_root) { 1087 debugfs_remove(phba->hba_debugfs_root); /* lpfcX */ 1088 phba->hba_debugfs_root = NULL; 1089 atomic_dec(&lpfc_debugfs_hba_count); 1090 } 1091 1092 if (atomic_read(&lpfc_debugfs_hba_count) == 0) { 1093 debugfs_remove(lpfc_debugfs_root); /* lpfc */ 1094 lpfc_debugfs_root = NULL; 1095 } 1096 } 1097 #endif 1098 return; 1099 } 1100 1101 1102