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, "refcnt:%x", 507 atomic_read(&ndlp->kref.refcount)); 508 len += snprintf(buf+len, size-len, "\n"); 509 } 510 spin_unlock_irq(shost->host_lock); 511 return len; 512 } 513 #endif 514 515 516 inline void 517 lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt, 518 uint32_t data1, uint32_t data2, uint32_t data3) 519 { 520 #ifdef CONFIG_LPFC_DEBUG_FS 521 struct lpfc_debugfs_trc *dtp; 522 int index; 523 524 if (!(lpfc_debugfs_mask_disc_trc & mask)) 525 return; 526 527 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc || 528 !vport || !vport->disc_trc) 529 return; 530 531 index = atomic_inc_return(&vport->disc_trc_cnt) & 532 (lpfc_debugfs_max_disc_trc - 1); 533 dtp = vport->disc_trc + index; 534 dtp->fmt = fmt; 535 dtp->data1 = data1; 536 dtp->data2 = data2; 537 dtp->data3 = data3; 538 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt); 539 dtp->jif = jiffies; 540 #endif 541 return; 542 } 543 544 inline void 545 lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt, 546 uint32_t data1, uint32_t data2, uint32_t data3) 547 { 548 #ifdef CONFIG_LPFC_DEBUG_FS 549 struct lpfc_debugfs_trc *dtp; 550 int index; 551 552 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc || 553 !phba || !phba->slow_ring_trc) 554 return; 555 556 index = atomic_inc_return(&phba->slow_ring_trc_cnt) & 557 (lpfc_debugfs_max_slow_ring_trc - 1); 558 dtp = phba->slow_ring_trc + index; 559 dtp->fmt = fmt; 560 dtp->data1 = data1; 561 dtp->data2 = data2; 562 dtp->data3 = data3; 563 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt); 564 dtp->jif = jiffies; 565 #endif 566 return; 567 } 568 569 #ifdef CONFIG_LPFC_DEBUG_FS 570 static int 571 lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file) 572 { 573 struct lpfc_vport *vport = inode->i_private; 574 struct lpfc_debug *debug; 575 int size; 576 int rc = -ENOMEM; 577 578 if (!lpfc_debugfs_max_disc_trc) { 579 rc = -ENOSPC; 580 goto out; 581 } 582 583 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 584 if (!debug) 585 goto out; 586 587 /* Round to page boundry */ 588 size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); 589 size = PAGE_ALIGN(size); 590 591 debug->buffer = kmalloc(size, GFP_KERNEL); 592 if (!debug->buffer) { 593 kfree(debug); 594 goto out; 595 } 596 597 debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size); 598 file->private_data = debug; 599 600 rc = 0; 601 out: 602 return rc; 603 } 604 605 static int 606 lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file) 607 { 608 struct lpfc_hba *phba = inode->i_private; 609 struct lpfc_debug *debug; 610 int size; 611 int rc = -ENOMEM; 612 613 if (!lpfc_debugfs_max_slow_ring_trc) { 614 rc = -ENOSPC; 615 goto out; 616 } 617 618 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 619 if (!debug) 620 goto out; 621 622 /* Round to page boundry */ 623 size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); 624 size = PAGE_ALIGN(size); 625 626 debug->buffer = kmalloc(size, GFP_KERNEL); 627 if (!debug->buffer) { 628 kfree(debug); 629 goto out; 630 } 631 632 debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size); 633 file->private_data = debug; 634 635 rc = 0; 636 out: 637 return rc; 638 } 639 640 static int 641 lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file) 642 { 643 struct lpfc_hba *phba = inode->i_private; 644 struct lpfc_debug *debug; 645 int rc = -ENOMEM; 646 647 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 648 if (!debug) 649 goto out; 650 651 /* Round to page boundry */ 652 debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL); 653 if (!debug->buffer) { 654 kfree(debug); 655 goto out; 656 } 657 658 debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer, 659 LPFC_HBQINFO_SIZE); 660 file->private_data = debug; 661 662 rc = 0; 663 out: 664 return rc; 665 } 666 667 static int 668 lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file) 669 { 670 struct lpfc_hba *phba = inode->i_private; 671 struct lpfc_debug *debug; 672 int rc = -ENOMEM; 673 674 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 675 if (!debug) 676 goto out; 677 678 /* Round to page boundry */ 679 debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL); 680 if (!debug->buffer) { 681 kfree(debug); 682 goto out; 683 } 684 685 debug->len = lpfc_debugfs_dumpHBASlim_data(phba, debug->buffer, 686 LPFC_DUMPHBASLIM_SIZE); 687 file->private_data = debug; 688 689 rc = 0; 690 out: 691 return rc; 692 } 693 694 static int 695 lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file) 696 { 697 struct lpfc_hba *phba = inode->i_private; 698 struct lpfc_debug *debug; 699 int rc = -ENOMEM; 700 701 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 702 if (!debug) 703 goto out; 704 705 /* Round to page boundry */ 706 debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL); 707 if (!debug->buffer) { 708 kfree(debug); 709 goto out; 710 } 711 712 debug->len = lpfc_debugfs_dumpHostSlim_data(phba, debug->buffer, 713 LPFC_DUMPHOSTSLIM_SIZE); 714 file->private_data = debug; 715 716 rc = 0; 717 out: 718 return rc; 719 } 720 721 static int 722 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file) 723 { 724 struct lpfc_vport *vport = inode->i_private; 725 struct lpfc_debug *debug; 726 int rc = -ENOMEM; 727 728 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 729 if (!debug) 730 goto out; 731 732 /* Round to page boundry */ 733 debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL); 734 if (!debug->buffer) { 735 kfree(debug); 736 goto out; 737 } 738 739 debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer, 740 LPFC_NODELIST_SIZE); 741 file->private_data = debug; 742 743 rc = 0; 744 out: 745 return rc; 746 } 747 748 static loff_t 749 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence) 750 { 751 struct lpfc_debug *debug; 752 loff_t pos = -1; 753 754 debug = file->private_data; 755 756 switch (whence) { 757 case 0: 758 pos = off; 759 break; 760 case 1: 761 pos = file->f_pos + off; 762 break; 763 case 2: 764 pos = debug->len - off; 765 } 766 return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos); 767 } 768 769 static ssize_t 770 lpfc_debugfs_read(struct file *file, char __user *buf, 771 size_t nbytes, loff_t *ppos) 772 { 773 struct lpfc_debug *debug = file->private_data; 774 return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer, 775 debug->len); 776 } 777 778 static int 779 lpfc_debugfs_release(struct inode *inode, struct file *file) 780 { 781 struct lpfc_debug *debug = file->private_data; 782 783 kfree(debug->buffer); 784 kfree(debug); 785 786 return 0; 787 } 788 789 #undef lpfc_debugfs_op_disc_trc 790 static struct file_operations lpfc_debugfs_op_disc_trc = { 791 .owner = THIS_MODULE, 792 .open = lpfc_debugfs_disc_trc_open, 793 .llseek = lpfc_debugfs_lseek, 794 .read = lpfc_debugfs_read, 795 .release = lpfc_debugfs_release, 796 }; 797 798 #undef lpfc_debugfs_op_nodelist 799 static struct file_operations lpfc_debugfs_op_nodelist = { 800 .owner = THIS_MODULE, 801 .open = lpfc_debugfs_nodelist_open, 802 .llseek = lpfc_debugfs_lseek, 803 .read = lpfc_debugfs_read, 804 .release = lpfc_debugfs_release, 805 }; 806 807 #undef lpfc_debugfs_op_hbqinfo 808 static struct file_operations lpfc_debugfs_op_hbqinfo = { 809 .owner = THIS_MODULE, 810 .open = lpfc_debugfs_hbqinfo_open, 811 .llseek = lpfc_debugfs_lseek, 812 .read = lpfc_debugfs_read, 813 .release = lpfc_debugfs_release, 814 }; 815 816 #undef lpfc_debugfs_op_dumpHBASlim 817 static struct file_operations lpfc_debugfs_op_dumpHBASlim = { 818 .owner = THIS_MODULE, 819 .open = lpfc_debugfs_dumpHBASlim_open, 820 .llseek = lpfc_debugfs_lseek, 821 .read = lpfc_debugfs_read, 822 .release = lpfc_debugfs_release, 823 }; 824 825 #undef lpfc_debugfs_op_dumpHostSlim 826 static struct file_operations lpfc_debugfs_op_dumpHostSlim = { 827 .owner = THIS_MODULE, 828 .open = lpfc_debugfs_dumpHostSlim_open, 829 .llseek = lpfc_debugfs_lseek, 830 .read = lpfc_debugfs_read, 831 .release = lpfc_debugfs_release, 832 }; 833 834 #undef lpfc_debugfs_op_slow_ring_trc 835 static struct file_operations lpfc_debugfs_op_slow_ring_trc = { 836 .owner = THIS_MODULE, 837 .open = lpfc_debugfs_slow_ring_trc_open, 838 .llseek = lpfc_debugfs_lseek, 839 .read = lpfc_debugfs_read, 840 .release = lpfc_debugfs_release, 841 }; 842 843 static struct dentry *lpfc_debugfs_root = NULL; 844 static atomic_t lpfc_debugfs_hba_count; 845 #endif 846 847 inline void 848 lpfc_debugfs_initialize(struct lpfc_vport *vport) 849 { 850 #ifdef CONFIG_LPFC_DEBUG_FS 851 struct lpfc_hba *phba = vport->phba; 852 char name[64]; 853 uint32_t num, i; 854 855 if (!lpfc_debugfs_enable) 856 return; 857 858 /* Setup lpfc root directory */ 859 if (!lpfc_debugfs_root) { 860 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL); 861 atomic_set(&lpfc_debugfs_hba_count, 0); 862 if (!lpfc_debugfs_root) { 863 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 864 "0409 Cannot create debugfs root\n"); 865 goto debug_failed; 866 } 867 } 868 if (!lpfc_debugfs_start_time) 869 lpfc_debugfs_start_time = jiffies; 870 871 /* Setup lpfcX directory for specific HBA */ 872 snprintf(name, sizeof(name), "lpfc%d", phba->brd_no); 873 if (!phba->hba_debugfs_root) { 874 phba->hba_debugfs_root = 875 debugfs_create_dir(name, lpfc_debugfs_root); 876 if (!phba->hba_debugfs_root) { 877 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 878 "0409 Cannot create debugfs hba\n"); 879 goto debug_failed; 880 } 881 atomic_inc(&lpfc_debugfs_hba_count); 882 atomic_set(&phba->debugfs_vport_count, 0); 883 884 /* Setup hbqinfo */ 885 snprintf(name, sizeof(name), "hbqinfo"); 886 phba->debug_hbqinfo = 887 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 888 phba->hba_debugfs_root, 889 phba, &lpfc_debugfs_op_hbqinfo); 890 if (!phba->debug_hbqinfo) { 891 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 892 "0409 Cannot create debugfs hbqinfo\n"); 893 goto debug_failed; 894 } 895 896 /* Setup dumpHBASlim */ 897 snprintf(name, sizeof(name), "dumpHBASlim"); 898 phba->debug_dumpHBASlim = 899 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 900 phba->hba_debugfs_root, 901 phba, &lpfc_debugfs_op_dumpHBASlim); 902 if (!phba->debug_dumpHBASlim) { 903 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 904 "0409 Cannot create debugfs dumpHBASlim\n"); 905 goto debug_failed; 906 } 907 908 /* Setup dumpHostSlim */ 909 snprintf(name, sizeof(name), "dumpHostSlim"); 910 phba->debug_dumpHostSlim = 911 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 912 phba->hba_debugfs_root, 913 phba, &lpfc_debugfs_op_dumpHostSlim); 914 if (!phba->debug_dumpHostSlim) { 915 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 916 "0409 Cannot create debugfs dumpHostSlim\n"); 917 goto debug_failed; 918 } 919 920 /* Setup slow ring trace */ 921 if (lpfc_debugfs_max_slow_ring_trc) { 922 num = lpfc_debugfs_max_slow_ring_trc - 1; 923 if (num & lpfc_debugfs_max_slow_ring_trc) { 924 /* Change to be a power of 2 */ 925 num = lpfc_debugfs_max_slow_ring_trc; 926 i = 0; 927 while (num > 1) { 928 num = num >> 1; 929 i++; 930 } 931 lpfc_debugfs_max_slow_ring_trc = (1 << i); 932 printk(KERN_ERR 933 "lpfc_debugfs_max_disc_trc changed to " 934 "%d\n", lpfc_debugfs_max_disc_trc); 935 } 936 } 937 938 939 snprintf(name, sizeof(name), "slow_ring_trace"); 940 phba->debug_slow_ring_trc = 941 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 942 phba->hba_debugfs_root, 943 phba, &lpfc_debugfs_op_slow_ring_trc); 944 if (!phba->debug_slow_ring_trc) { 945 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 946 "0409 Cannot create debugfs " 947 "slow_ring_trace\n"); 948 goto debug_failed; 949 } 950 if (!phba->slow_ring_trc) { 951 phba->slow_ring_trc = kmalloc( 952 (sizeof(struct lpfc_debugfs_trc) * 953 lpfc_debugfs_max_slow_ring_trc), 954 GFP_KERNEL); 955 if (!phba->slow_ring_trc) { 956 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 957 "0409 Cannot create debugfs " 958 "slow_ring buffer\n"); 959 goto debug_failed; 960 } 961 atomic_set(&phba->slow_ring_trc_cnt, 0); 962 memset(phba->slow_ring_trc, 0, 963 (sizeof(struct lpfc_debugfs_trc) * 964 lpfc_debugfs_max_slow_ring_trc)); 965 } 966 } 967 968 snprintf(name, sizeof(name), "vport%d", vport->vpi); 969 if (!vport->vport_debugfs_root) { 970 vport->vport_debugfs_root = 971 debugfs_create_dir(name, phba->hba_debugfs_root); 972 if (!vport->vport_debugfs_root) { 973 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 974 "0409 Cant create debugfs"); 975 goto debug_failed; 976 } 977 atomic_inc(&phba->debugfs_vport_count); 978 } 979 980 if (lpfc_debugfs_max_disc_trc) { 981 num = lpfc_debugfs_max_disc_trc - 1; 982 if (num & lpfc_debugfs_max_disc_trc) { 983 /* Change to be a power of 2 */ 984 num = lpfc_debugfs_max_disc_trc; 985 i = 0; 986 while (num > 1) { 987 num = num >> 1; 988 i++; 989 } 990 lpfc_debugfs_max_disc_trc = (1 << i); 991 printk(KERN_ERR 992 "lpfc_debugfs_max_disc_trc changed to %d\n", 993 lpfc_debugfs_max_disc_trc); 994 } 995 } 996 997 vport->disc_trc = kzalloc( 998 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc), 999 GFP_KERNEL); 1000 1001 if (!vport->disc_trc) { 1002 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 1003 "0409 Cannot create debugfs disc trace " 1004 "buffer\n"); 1005 goto debug_failed; 1006 } 1007 atomic_set(&vport->disc_trc_cnt, 0); 1008 1009 snprintf(name, sizeof(name), "discovery_trace"); 1010 vport->debug_disc_trc = 1011 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 1012 vport->vport_debugfs_root, 1013 vport, &lpfc_debugfs_op_disc_trc); 1014 if (!vport->debug_disc_trc) { 1015 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 1016 "0409 Cannot create debugfs " 1017 "discovery_trace\n"); 1018 goto debug_failed; 1019 } 1020 snprintf(name, sizeof(name), "nodelist"); 1021 vport->debug_nodelist = 1022 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR, 1023 vport->vport_debugfs_root, 1024 vport, &lpfc_debugfs_op_nodelist); 1025 if (!vport->debug_nodelist) { 1026 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 1027 "0409 Cant create debugfs nodelist"); 1028 goto debug_failed; 1029 } 1030 debug_failed: 1031 return; 1032 #endif 1033 } 1034 1035 1036 inline void 1037 lpfc_debugfs_terminate(struct lpfc_vport *vport) 1038 { 1039 #ifdef CONFIG_LPFC_DEBUG_FS 1040 struct lpfc_hba *phba = vport->phba; 1041 1042 if (vport->disc_trc) { 1043 kfree(vport->disc_trc); 1044 vport->disc_trc = NULL; 1045 } 1046 if (vport->debug_disc_trc) { 1047 debugfs_remove(vport->debug_disc_trc); /* discovery_trace */ 1048 vport->debug_disc_trc = NULL; 1049 } 1050 if (vport->debug_nodelist) { 1051 debugfs_remove(vport->debug_nodelist); /* nodelist */ 1052 vport->debug_nodelist = NULL; 1053 } 1054 1055 if (vport->vport_debugfs_root) { 1056 debugfs_remove(vport->vport_debugfs_root); /* vportX */ 1057 vport->vport_debugfs_root = NULL; 1058 atomic_dec(&phba->debugfs_vport_count); 1059 } 1060 if (atomic_read(&phba->debugfs_vport_count) == 0) { 1061 1062 if (phba->debug_hbqinfo) { 1063 debugfs_remove(phba->debug_hbqinfo); /* hbqinfo */ 1064 phba->debug_hbqinfo = NULL; 1065 } 1066 if (phba->debug_dumpHBASlim) { 1067 debugfs_remove(phba->debug_dumpHBASlim); /* HBASlim */ 1068 phba->debug_dumpHBASlim = NULL; 1069 } 1070 if (phba->debug_dumpHostSlim) { 1071 debugfs_remove(phba->debug_dumpHostSlim); /* HostSlim */ 1072 phba->debug_dumpHostSlim = NULL; 1073 } 1074 if (phba->slow_ring_trc) { 1075 kfree(phba->slow_ring_trc); 1076 phba->slow_ring_trc = NULL; 1077 } 1078 if (phba->debug_slow_ring_trc) { 1079 /* slow_ring_trace */ 1080 debugfs_remove(phba->debug_slow_ring_trc); 1081 phba->debug_slow_ring_trc = NULL; 1082 } 1083 1084 if (phba->hba_debugfs_root) { 1085 debugfs_remove(phba->hba_debugfs_root); /* lpfcX */ 1086 phba->hba_debugfs_root = NULL; 1087 atomic_dec(&lpfc_debugfs_hba_count); 1088 } 1089 1090 if (atomic_read(&lpfc_debugfs_hba_count) == 0) { 1091 debugfs_remove(lpfc_debugfs_root); /* lpfc */ 1092 lpfc_debugfs_root = NULL; 1093 } 1094 } 1095 #endif 1096 return; 1097 } 1098 1099 1100