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