1 /******************************************************************* 2 * This file is part of the Emulex Linux Device Driver for * 3 * Fibre Channel Host Bus Adapters. * 4 * Copyright (C) 2017-2025 Broadcom. All Rights Reserved. The term * 5 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * 6 * Copyright (C) 2007-2015 Emulex. All rights reserved. * 7 * EMULEX and SLI are trademarks of Emulex. * 8 * www.broadcom.com * 9 * * 10 * This program is free software; you can redistribute it and/or * 11 * modify it under the terms of version 2 of the GNU General * 12 * Public License as published by the Free Software Foundation. * 13 * This program is distributed in the hope that it will be useful. * 14 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * 15 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * 16 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * 17 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * 18 * TO BE LEGALLY INVALID. See the GNU General Public License for * 19 * more details, a copy of which can be found in the file COPYING * 20 * included with this package. * 21 *******************************************************************/ 22 23 #include <linux/blkdev.h> 24 #include <linux/delay.h> 25 #include <linux/module.h> 26 #include <linux/dma-mapping.h> 27 #include <linux/idr.h> 28 #include <linux/interrupt.h> 29 #include <linux/kthread.h> 30 #include <linux/slab.h> 31 #include <linux/pci.h> 32 #include <linux/spinlock.h> 33 #include <linux/ctype.h> 34 #include <linux/vmalloc.h> 35 36 #include <scsi/scsi.h> 37 #include <scsi/scsi_device.h> 38 #include <scsi/scsi_host.h> 39 #include <scsi/scsi_transport_fc.h> 40 #include <scsi/fc/fc_fs.h> 41 42 #include "lpfc_hw4.h" 43 #include "lpfc_hw.h" 44 #include "lpfc_sli.h" 45 #include "lpfc_sli4.h" 46 #include "lpfc_nl.h" 47 #include "lpfc_disc.h" 48 #include "lpfc.h" 49 #include "lpfc_scsi.h" 50 #include "lpfc_nvme.h" 51 #include "lpfc_logmsg.h" 52 #include "lpfc_crtn.h" 53 #include "lpfc_vport.h" 54 #include "lpfc_version.h" 55 #include "lpfc_compat.h" 56 #include "lpfc_debugfs.h" 57 #include "lpfc_bsg.h" 58 59 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS 60 /* 61 * debugfs interface 62 * 63 * To access this interface the user should: 64 * # mount -t debugfs none /sys/kernel/debug 65 * 66 * The lpfc debugfs directory hierarchy is: 67 * /sys/kernel/debug/lpfc/fnX/vportY 68 * where X is the lpfc hba function unique_id 69 * where Y is the vport VPI on that hba 70 * 71 * Debugging services available per vport: 72 * discovery_trace 73 * This is an ACSII readable file that contains a trace of the last 74 * lpfc_debugfs_max_disc_trc events that happened on a specific vport. 75 * See lpfc_debugfs.h for different categories of discovery events. 76 * To enable the discovery trace, the following module parameters must be set: 77 * lpfc_debugfs_enable=1 Turns on lpfc debugfs filesystem support 78 * lpfc_debugfs_max_disc_trc=X Where X is the event trace depth for 79 * EACH vport. X MUST also be a power of 2. 80 * lpfc_debugfs_mask_disc_trc=Y Where Y is an event mask as defined in 81 * lpfc_debugfs.h . 82 * 83 * slow_ring_trace 84 * This is an ACSII readable file that contains a trace of the last 85 * lpfc_debugfs_max_slow_ring_trc events that happened on a specific HBA. 86 * To enable the slow ring trace, the following module parameters must be set: 87 * lpfc_debugfs_enable=1 Turns on lpfc debugfs filesystem support 88 * lpfc_debugfs_max_slow_ring_trc=X Where X is the event trace depth for 89 * the HBA. X MUST also be a power of 2. 90 */ 91 static int lpfc_debugfs_enable = 1; 92 module_param(lpfc_debugfs_enable, int, S_IRUGO); 93 MODULE_PARM_DESC(lpfc_debugfs_enable, "Enable debugfs services"); 94 95 /* This MUST be a power of 2 */ 96 static int lpfc_debugfs_max_disc_trc; 97 module_param(lpfc_debugfs_max_disc_trc, int, S_IRUGO); 98 MODULE_PARM_DESC(lpfc_debugfs_max_disc_trc, 99 "Set debugfs discovery trace depth"); 100 101 /* This MUST be a power of 2 */ 102 static int lpfc_debugfs_max_slow_ring_trc; 103 module_param(lpfc_debugfs_max_slow_ring_trc, int, S_IRUGO); 104 MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc, 105 "Set debugfs slow ring trace depth"); 106 107 /* This MUST be a power of 2 */ 108 static int lpfc_debugfs_max_nvmeio_trc; 109 module_param(lpfc_debugfs_max_nvmeio_trc, int, 0444); 110 MODULE_PARM_DESC(lpfc_debugfs_max_nvmeio_trc, 111 "Set debugfs NVME IO trace depth"); 112 113 static int lpfc_debugfs_mask_disc_trc; 114 module_param(lpfc_debugfs_mask_disc_trc, int, S_IRUGO); 115 MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc, 116 "Set debugfs discovery trace mask"); 117 118 #include <linux/debugfs.h> 119 120 static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0); 121 static unsigned long lpfc_debugfs_start_time = 0L; 122 123 /* iDiag */ 124 static struct lpfc_idiag idiag; 125 126 /** 127 * lpfc_debugfs_disc_trc_data - Dump discovery logging to a buffer 128 * @vport: The vport to gather the log info from. 129 * @buf: The buffer to dump log into. 130 * @size: The maximum amount of data to process. 131 * 132 * Description: 133 * This routine gathers the lpfc discovery debugfs data from the @vport and 134 * dumps it to @buf up to @size number of bytes. It will start at the next entry 135 * in the log and process the log until the end of the buffer. Then it will 136 * gather from the beginning of the log and process until the current entry. 137 * 138 * Notes: 139 * Discovery logging will be disabled while while this routine dumps the log. 140 * 141 * Return Value: 142 * This routine returns the amount of bytes that were dumped into @buf and will 143 * not exceed @size. 144 **/ 145 static int 146 lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size) 147 { 148 int i, index, len, enable; 149 uint32_t ms; 150 struct lpfc_debugfs_trc *dtp; 151 char *buffer; 152 153 buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL); 154 if (!buffer) 155 return 0; 156 157 enable = lpfc_debugfs_enable; 158 lpfc_debugfs_enable = 0; 159 160 len = 0; 161 index = (atomic_read(&vport->disc_trc_cnt) + 1) & 162 (lpfc_debugfs_max_disc_trc - 1); 163 for (i = index; i < lpfc_debugfs_max_disc_trc; i++) { 164 dtp = vport->disc_trc + i; 165 if (!dtp->fmt) 166 continue; 167 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 168 snprintf(buffer, 169 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 170 dtp->seq_cnt, ms, dtp->fmt); 171 len += scnprintf(buf+len, size-len, buffer, 172 dtp->data1, dtp->data2, dtp->data3); 173 } 174 for (i = 0; i < index; i++) { 175 dtp = vport->disc_trc + i; 176 if (!dtp->fmt) 177 continue; 178 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 179 snprintf(buffer, 180 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 181 dtp->seq_cnt, ms, dtp->fmt); 182 len += scnprintf(buf+len, size-len, buffer, 183 dtp->data1, dtp->data2, dtp->data3); 184 } 185 186 lpfc_debugfs_enable = enable; 187 kfree(buffer); 188 189 return len; 190 } 191 192 /** 193 * lpfc_debugfs_slow_ring_trc_data - Dump slow ring logging to a buffer 194 * @phba: The HBA to gather the log info from. 195 * @buf: The buffer to dump log into. 196 * @size: The maximum amount of data to process. 197 * 198 * Description: 199 * This routine gathers the lpfc slow ring debugfs data from the @phba and 200 * dumps it to @buf up to @size number of bytes. It will start at the next entry 201 * in the log and process the log until the end of the buffer. Then it will 202 * gather from the beginning of the log and process until the current entry. 203 * 204 * Notes: 205 * Slow ring logging will be disabled while while this routine dumps the log. 206 * 207 * Return Value: 208 * This routine returns the amount of bytes that were dumped into @buf and will 209 * not exceed @size. 210 **/ 211 static int 212 lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size) 213 { 214 int i, index, len, enable; 215 uint32_t ms; 216 struct lpfc_debugfs_trc *dtp; 217 char *buffer; 218 219 buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL); 220 if (!buffer) 221 return 0; 222 223 enable = lpfc_debugfs_enable; 224 lpfc_debugfs_enable = 0; 225 226 len = 0; 227 index = (atomic_read(&phba->slow_ring_trc_cnt) + 1) & 228 (lpfc_debugfs_max_slow_ring_trc - 1); 229 for (i = index; i < lpfc_debugfs_max_slow_ring_trc; i++) { 230 dtp = phba->slow_ring_trc + i; 231 if (!dtp->fmt) 232 continue; 233 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 234 snprintf(buffer, 235 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 236 dtp->seq_cnt, ms, dtp->fmt); 237 len += scnprintf(buf+len, size-len, buffer, 238 dtp->data1, dtp->data2, dtp->data3); 239 } 240 for (i = 0; i < index; i++) { 241 dtp = phba->slow_ring_trc + i; 242 if (!dtp->fmt) 243 continue; 244 ms = jiffies_to_msecs(dtp->jif - lpfc_debugfs_start_time); 245 snprintf(buffer, 246 LPFC_DEBUG_TRC_ENTRY_SIZE, "%010d:%010d ms:%s\n", 247 dtp->seq_cnt, ms, dtp->fmt); 248 len += scnprintf(buf+len, size-len, buffer, 249 dtp->data1, dtp->data2, dtp->data3); 250 } 251 252 lpfc_debugfs_enable = enable; 253 kfree(buffer); 254 255 return len; 256 } 257 258 static int lpfc_debugfs_last_hbq = -1; 259 260 /** 261 * lpfc_debugfs_hbqinfo_data - Dump host buffer queue info to a buffer 262 * @phba: The HBA to gather host buffer info from. 263 * @buf: The buffer to dump log into. 264 * @size: The maximum amount of data to process. 265 * 266 * Description: 267 * This routine dumps the host buffer queue info from the @phba to @buf up to 268 * @size number of bytes. A header that describes the current hbq state will be 269 * dumped to @buf first and then info on each hbq entry will be dumped to @buf 270 * until @size bytes have been dumped or all the hbq info has been dumped. 271 * 272 * Notes: 273 * This routine will rotate through each configured HBQ each time called. 274 * 275 * Return Value: 276 * This routine returns the amount of bytes that were dumped into @buf and will 277 * not exceed @size. 278 **/ 279 static int 280 lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size) 281 { 282 int len = 0; 283 int i, j, found, posted, low; 284 uint32_t phys, raw_index, getidx; 285 struct lpfc_hbq_init *hip; 286 struct hbq_s *hbqs; 287 struct lpfc_hbq_entry *hbqe; 288 struct lpfc_dmabuf *d_buf; 289 struct hbq_dmabuf *hbq_buf; 290 291 if (phba->sli_rev != 3) 292 return 0; 293 294 spin_lock_irq(&phba->hbalock); 295 296 /* toggle between multiple hbqs, if any */ 297 i = lpfc_sli_hbq_count(); 298 if (i > 1) { 299 lpfc_debugfs_last_hbq++; 300 if (lpfc_debugfs_last_hbq >= i) 301 lpfc_debugfs_last_hbq = 0; 302 } 303 else 304 lpfc_debugfs_last_hbq = 0; 305 306 i = lpfc_debugfs_last_hbq; 307 308 len += scnprintf(buf+len, size-len, "HBQ %d Info\n", i); 309 310 hbqs = &phba->hbqs[i]; 311 posted = 0; 312 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) 313 posted++; 314 315 hip = lpfc_hbq_defs[i]; 316 len += scnprintf(buf+len, size-len, 317 "idx:%d prof:%d rn:%d bufcnt:%d icnt:%d acnt:%d posted %d\n", 318 hip->hbq_index, hip->profile, hip->rn, 319 hip->buffer_count, hip->init_count, hip->add_count, posted); 320 321 raw_index = phba->hbq_get[i]; 322 getidx = le32_to_cpu(raw_index); 323 len += scnprintf(buf+len, size-len, 324 "entries:%d bufcnt:%d Put:%d nPut:%d localGet:%d hbaGet:%d\n", 325 hbqs->entry_count, hbqs->buffer_count, hbqs->hbqPutIdx, 326 hbqs->next_hbqPutIdx, hbqs->local_hbqGetIdx, getidx); 327 328 hbqe = (struct lpfc_hbq_entry *) phba->hbqs[i].hbq_virt; 329 for (j=0; j<hbqs->entry_count; j++) { 330 len += scnprintf(buf+len, size-len, 331 "%03d: %08x %04x %05x ", j, 332 le32_to_cpu(hbqe->bde.addrLow), 333 le32_to_cpu(hbqe->bde.tus.w), 334 le32_to_cpu(hbqe->buffer_tag)); 335 i = 0; 336 found = 0; 337 338 /* First calculate if slot has an associated posted buffer */ 339 low = hbqs->hbqPutIdx - posted; 340 if (low >= 0) { 341 if ((j >= hbqs->hbqPutIdx) || (j < low)) { 342 len += scnprintf(buf + len, size - len, 343 "Unused\n"); 344 goto skipit; 345 } 346 } 347 else { 348 if ((j >= hbqs->hbqPutIdx) && 349 (j < (hbqs->entry_count+low))) { 350 len += scnprintf(buf + len, size - len, 351 "Unused\n"); 352 goto skipit; 353 } 354 } 355 356 /* Get the Buffer info for the posted buffer */ 357 list_for_each_entry(d_buf, &hbqs->hbq_buffer_list, list) { 358 hbq_buf = container_of(d_buf, struct hbq_dmabuf, dbuf); 359 phys = ((uint64_t)hbq_buf->dbuf.phys & 0xffffffff); 360 if (phys == le32_to_cpu(hbqe->bde.addrLow)) { 361 len += scnprintf(buf+len, size-len, 362 "Buf%d: x%px %06x\n", i, 363 hbq_buf->dbuf.virt, hbq_buf->tag); 364 found = 1; 365 break; 366 } 367 i++; 368 } 369 if (!found) { 370 len += scnprintf(buf+len, size-len, "No DMAinfo?\n"); 371 } 372 skipit: 373 hbqe++; 374 if (len > LPFC_HBQINFO_SIZE - 54) 375 break; 376 } 377 spin_unlock_irq(&phba->hbalock); 378 return len; 379 } 380 381 static int lpfc_debugfs_last_xripool; 382 383 /** 384 * lpfc_debugfs_commonxripools_data - Dump Hardware Queue info to a buffer 385 * @phba: The HBA to gather host buffer info from. 386 * @buf: The buffer to dump log into. 387 * @size: The maximum amount of data to process. 388 * 389 * Description: 390 * This routine dumps the Hardware Queue info from the @phba to @buf up to 391 * @size number of bytes. A header that describes the current hdwq state will be 392 * dumped to @buf first and then info on each hdwq entry will be dumped to @buf 393 * until @size bytes have been dumped or all the hdwq info has been dumped. 394 * 395 * Notes: 396 * This routine will rotate through each configured Hardware Queue each 397 * time called. 398 * 399 * Return Value: 400 * This routine returns the amount of bytes that were dumped into @buf and will 401 * not exceed @size. 402 **/ 403 static int 404 lpfc_debugfs_commonxripools_data(struct lpfc_hba *phba, char *buf, int size) 405 { 406 struct lpfc_sli4_hdw_queue *qp; 407 int len = 0; 408 int i, out; 409 unsigned long iflag; 410 411 for (i = 0; i < phba->cfg_hdw_queue; i++) { 412 if (len > (LPFC_DUMP_MULTIXRIPOOL_SIZE - 80)) 413 break; 414 qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_xripool]; 415 416 len += scnprintf(buf + len, size - len, "HdwQ %d Info ", i); 417 spin_lock_irqsave(&qp->abts_io_buf_list_lock, iflag); 418 spin_lock(&qp->io_buf_list_get_lock); 419 spin_lock(&qp->io_buf_list_put_lock); 420 out = qp->total_io_bufs - (qp->get_io_bufs + qp->put_io_bufs + 421 qp->abts_scsi_io_bufs + qp->abts_nvme_io_bufs); 422 len += scnprintf(buf + len, size - len, 423 "tot:%d get:%d put:%d mt:%d " 424 "ABTS scsi:%d nvme:%d Out:%d\n", 425 qp->total_io_bufs, qp->get_io_bufs, qp->put_io_bufs, 426 qp->empty_io_bufs, qp->abts_scsi_io_bufs, 427 qp->abts_nvme_io_bufs, out); 428 spin_unlock(&qp->io_buf_list_put_lock); 429 spin_unlock(&qp->io_buf_list_get_lock); 430 spin_unlock_irqrestore(&qp->abts_io_buf_list_lock, iflag); 431 432 lpfc_debugfs_last_xripool++; 433 if (lpfc_debugfs_last_xripool >= phba->cfg_hdw_queue) 434 lpfc_debugfs_last_xripool = 0; 435 } 436 437 return len; 438 } 439 440 /** 441 * lpfc_debugfs_multixripools_data - Display multi-XRI pools information 442 * @phba: The HBA to gather host buffer info from. 443 * @buf: The buffer to dump log into. 444 * @size: The maximum amount of data to process. 445 * 446 * Description: 447 * This routine displays current multi-XRI pools information including XRI 448 * count in public, private and txcmplq. It also displays current high and 449 * low watermark. 450 * 451 * Return Value: 452 * This routine returns the amount of bytes that were dumped into @buf and will 453 * not exceed @size. 454 **/ 455 static int 456 lpfc_debugfs_multixripools_data(struct lpfc_hba *phba, char *buf, int size) 457 { 458 u32 i; 459 u32 hwq_count; 460 struct lpfc_sli4_hdw_queue *qp; 461 struct lpfc_multixri_pool *multixri_pool; 462 struct lpfc_pvt_pool *pvt_pool; 463 struct lpfc_pbl_pool *pbl_pool; 464 u32 txcmplq_cnt; 465 char tmp[LPFC_DEBUG_OUT_LINE_SZ] = {0}; 466 467 if (phba->sli_rev != LPFC_SLI_REV4) 468 return 0; 469 470 if (!phba->sli4_hba.hdwq) 471 return 0; 472 473 if (!phba->cfg_xri_rebalancing) { 474 i = lpfc_debugfs_commonxripools_data(phba, buf, size); 475 return i; 476 } 477 478 /* 479 * Pbl: Current number of free XRIs in public pool 480 * Pvt: Current number of free XRIs in private pool 481 * Busy: Current number of outstanding XRIs 482 * HWM: Current high watermark 483 * pvt_empty: Incremented by 1 when IO submission fails (no xri) 484 * pbl_empty: Incremented by 1 when all pbl_pool are empty during 485 * IO submission 486 */ 487 scnprintf(tmp, sizeof(tmp), 488 "HWQ: Pbl Pvt Busy HWM | pvt_empty pbl_empty "); 489 if (strlcat(buf, tmp, size) >= size) 490 return strnlen(buf, size); 491 492 #ifdef LPFC_MXP_STAT 493 /* 494 * MAXH: Max high watermark seen so far 495 * above_lmt: Incremented by 1 if xri_owned > xri_limit during 496 * IO submission 497 * below_lmt: Incremented by 1 if xri_owned <= xri_limit during 498 * IO submission 499 * locPbl_hit: Incremented by 1 if successfully get a batch of XRI from 500 * local pbl_pool 501 * othPbl_hit: Incremented by 1 if successfully get a batch of XRI from 502 * other pbl_pool 503 */ 504 scnprintf(tmp, sizeof(tmp), 505 "MAXH above_lmt below_lmt locPbl_hit othPbl_hit"); 506 if (strlcat(buf, tmp, size) >= size) 507 return strnlen(buf, size); 508 509 /* 510 * sPbl: snapshot of Pbl 15 sec after stat gets cleared 511 * sPvt: snapshot of Pvt 15 sec after stat gets cleared 512 * sBusy: snapshot of Busy 15 sec after stat gets cleared 513 */ 514 scnprintf(tmp, sizeof(tmp), 515 " | sPbl sPvt sBusy"); 516 if (strlcat(buf, tmp, size) >= size) 517 return strnlen(buf, size); 518 #endif 519 520 scnprintf(tmp, sizeof(tmp), "\n"); 521 if (strlcat(buf, tmp, size) >= size) 522 return strnlen(buf, size); 523 524 hwq_count = phba->cfg_hdw_queue; 525 for (i = 0; i < hwq_count; i++) { 526 qp = &phba->sli4_hba.hdwq[i]; 527 multixri_pool = qp->p_multixri_pool; 528 if (!multixri_pool) 529 continue; 530 pbl_pool = &multixri_pool->pbl_pool; 531 pvt_pool = &multixri_pool->pvt_pool; 532 txcmplq_cnt = qp->io_wq->pring->txcmplq_cnt; 533 534 scnprintf(tmp, sizeof(tmp), 535 "%03d: %4d %4d %4d %4d | %10d %10d ", 536 i, pbl_pool->count, pvt_pool->count, 537 txcmplq_cnt, pvt_pool->high_watermark, 538 qp->empty_io_bufs, multixri_pool->pbl_empty_count); 539 if (strlcat(buf, tmp, size) >= size) 540 break; 541 542 #ifdef LPFC_MXP_STAT 543 scnprintf(tmp, sizeof(tmp), 544 "%4d %10d %10d %10d %10d", 545 multixri_pool->stat_max_hwm, 546 multixri_pool->above_limit_count, 547 multixri_pool->below_limit_count, 548 multixri_pool->local_pbl_hit_count, 549 multixri_pool->other_pbl_hit_count); 550 if (strlcat(buf, tmp, size) >= size) 551 break; 552 553 scnprintf(tmp, sizeof(tmp), 554 " | %4d %4d %5d", 555 multixri_pool->stat_pbl_count, 556 multixri_pool->stat_pvt_count, 557 multixri_pool->stat_busy_count); 558 if (strlcat(buf, tmp, size) >= size) 559 break; 560 #endif 561 562 scnprintf(tmp, sizeof(tmp), "\n"); 563 if (strlcat(buf, tmp, size) >= size) 564 break; 565 } 566 return strnlen(buf, size); 567 } 568 569 570 #ifdef LPFC_HDWQ_LOCK_STAT 571 static int lpfc_debugfs_last_lock; 572 573 /** 574 * lpfc_debugfs_lockstat_data - Dump Hardware Queue info to a buffer 575 * @phba: The HBA to gather host buffer info from. 576 * @buf: The buffer to dump log into. 577 * @size: The maximum amount of data to process. 578 * 579 * Description: 580 * This routine dumps the Hardware Queue info from the @phba to @buf up to 581 * @size number of bytes. A header that describes the current hdwq state will be 582 * dumped to @buf first and then info on each hdwq entry will be dumped to @buf 583 * until @size bytes have been dumped or all the hdwq info has been dumped. 584 * 585 * Notes: 586 * This routine will rotate through each configured Hardware Queue each 587 * time called. 588 * 589 * Return Value: 590 * This routine returns the amount of bytes that were dumped into @buf and will 591 * not exceed @size. 592 **/ 593 static int 594 lpfc_debugfs_lockstat_data(struct lpfc_hba *phba, char *buf, int size) 595 { 596 struct lpfc_sli4_hdw_queue *qp; 597 int len = 0; 598 int i; 599 600 if (phba->sli_rev != LPFC_SLI_REV4) 601 return 0; 602 603 if (!phba->sli4_hba.hdwq) 604 return 0; 605 606 for (i = 0; i < phba->cfg_hdw_queue; i++) { 607 if (len > (LPFC_HDWQINFO_SIZE - 100)) 608 break; 609 qp = &phba->sli4_hba.hdwq[lpfc_debugfs_last_lock]; 610 611 len += scnprintf(buf + len, size - len, "HdwQ %03d Lock ", i); 612 if (phba->cfg_xri_rebalancing) { 613 len += scnprintf(buf + len, size - len, 614 "get_pvt:%d mv_pvt:%d " 615 "mv2pub:%d mv2pvt:%d " 616 "put_pvt:%d put_pub:%d wq:%d\n", 617 qp->lock_conflict.alloc_pvt_pool, 618 qp->lock_conflict.mv_from_pvt_pool, 619 qp->lock_conflict.mv_to_pub_pool, 620 qp->lock_conflict.mv_to_pvt_pool, 621 qp->lock_conflict.free_pvt_pool, 622 qp->lock_conflict.free_pub_pool, 623 qp->lock_conflict.wq_access); 624 } else { 625 len += scnprintf(buf + len, size - len, 626 "get:%d put:%d free:%d wq:%d\n", 627 qp->lock_conflict.alloc_xri_get, 628 qp->lock_conflict.alloc_xri_put, 629 qp->lock_conflict.free_xri, 630 qp->lock_conflict.wq_access); 631 } 632 633 lpfc_debugfs_last_lock++; 634 if (lpfc_debugfs_last_lock >= phba->cfg_hdw_queue) 635 lpfc_debugfs_last_lock = 0; 636 } 637 638 return len; 639 } 640 #endif 641 642 static int lpfc_debugfs_last_hba_slim_off; 643 644 /** 645 * lpfc_debugfs_dumpHBASlim_data - Dump HBA SLIM info to a buffer 646 * @phba: The HBA to gather SLIM info from. 647 * @buf: The buffer to dump log into. 648 * @size: The maximum amount of data to process. 649 * 650 * Description: 651 * This routine dumps the current contents of HBA SLIM for the HBA associated 652 * with @phba to @buf up to @size bytes of data. This is the raw HBA SLIM data. 653 * 654 * Notes: 655 * This routine will only dump up to 1024 bytes of data each time called and 656 * should be called multiple times to dump the entire HBA SLIM. 657 * 658 * Return Value: 659 * This routine returns the amount of bytes that were dumped into @buf and will 660 * not exceed @size. 661 **/ 662 static int 663 lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size) 664 { 665 int len = 0; 666 int i, off; 667 uint32_t *ptr; 668 char *buffer; 669 670 buffer = kmalloc(1024, GFP_KERNEL); 671 if (!buffer) 672 return 0; 673 674 off = 0; 675 spin_lock_irq(&phba->hbalock); 676 677 len += scnprintf(buf+len, size-len, "HBA SLIM\n"); 678 lpfc_memcpy_from_slim(buffer, 679 phba->MBslimaddr + lpfc_debugfs_last_hba_slim_off, 1024); 680 681 ptr = (uint32_t *)&buffer[0]; 682 off = lpfc_debugfs_last_hba_slim_off; 683 684 /* Set it up for the next time */ 685 lpfc_debugfs_last_hba_slim_off += 1024; 686 if (lpfc_debugfs_last_hba_slim_off >= 4096) 687 lpfc_debugfs_last_hba_slim_off = 0; 688 689 i = 1024; 690 while (i > 0) { 691 len += scnprintf(buf+len, size-len, 692 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", 693 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), 694 *(ptr+5), *(ptr+6), *(ptr+7)); 695 ptr += 8; 696 i -= (8 * sizeof(uint32_t)); 697 off += (8 * sizeof(uint32_t)); 698 } 699 700 spin_unlock_irq(&phba->hbalock); 701 kfree(buffer); 702 703 return len; 704 } 705 706 /** 707 * lpfc_debugfs_dumpHostSlim_data - Dump host SLIM info to a buffer 708 * @phba: The HBA to gather Host SLIM info from. 709 * @buf: The buffer to dump log into. 710 * @size: The maximum amount of data to process. 711 * 712 * Description: 713 * This routine dumps the current contents of host SLIM for the host associated 714 * with @phba to @buf up to @size bytes of data. The dump will contain the 715 * Mailbox, PCB, Rings, and Registers that are located in host memory. 716 * 717 * Return Value: 718 * This routine returns the amount of bytes that were dumped into @buf and will 719 * not exceed @size. 720 **/ 721 static int 722 lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size) 723 { 724 int len = 0; 725 int i, off; 726 uint32_t word0, word1, word2, word3; 727 uint32_t *ptr; 728 struct lpfc_pgp *pgpp; 729 struct lpfc_sli *psli = &phba->sli; 730 struct lpfc_sli_ring *pring; 731 732 off = 0; 733 spin_lock_irq(&phba->hbalock); 734 735 len += scnprintf(buf+len, size-len, "SLIM Mailbox\n"); 736 ptr = (uint32_t *)phba->slim2p.virt; 737 i = sizeof(MAILBOX_t); 738 while (i > 0) { 739 len += scnprintf(buf+len, size-len, 740 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", 741 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), 742 *(ptr+5), *(ptr+6), *(ptr+7)); 743 ptr += 8; 744 i -= (8 * sizeof(uint32_t)); 745 off += (8 * sizeof(uint32_t)); 746 } 747 748 len += scnprintf(buf+len, size-len, "SLIM PCB\n"); 749 ptr = (uint32_t *)phba->pcb; 750 i = sizeof(PCB_t); 751 while (i > 0) { 752 len += scnprintf(buf+len, size-len, 753 "%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", 754 off, *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), 755 *(ptr+5), *(ptr+6), *(ptr+7)); 756 ptr += 8; 757 i -= (8 * sizeof(uint32_t)); 758 off += (8 * sizeof(uint32_t)); 759 } 760 761 if (phba->sli_rev <= LPFC_SLI_REV3) { 762 for (i = 0; i < 4; i++) { 763 pgpp = &phba->port_gp[i]; 764 pring = &psli->sli3_ring[i]; 765 len += scnprintf(buf+len, size-len, 766 "Ring %d: CMD GetInx:%d " 767 "(Max:%d Next:%d " 768 "Local:%d flg:x%x) " 769 "RSP PutInx:%d Max:%d\n", 770 i, pgpp->cmdGetInx, 771 pring->sli.sli3.numCiocb, 772 pring->sli.sli3.next_cmdidx, 773 pring->sli.sli3.local_getidx, 774 pring->flag, pgpp->rspPutInx, 775 pring->sli.sli3.numRiocb); 776 } 777 778 word0 = readl(phba->HAregaddr); 779 word1 = readl(phba->CAregaddr); 780 word2 = readl(phba->HSregaddr); 781 word3 = readl(phba->HCregaddr); 782 len += scnprintf(buf+len, size-len, "HA:%08x CA:%08x HS:%08x " 783 "HC:%08x\n", word0, word1, word2, word3); 784 } 785 spin_unlock_irq(&phba->hbalock); 786 return len; 787 } 788 789 /** 790 * lpfc_debugfs_nodelist_data - Dump target node list to a buffer 791 * @vport: The vport to gather target node info from. 792 * @buf: The buffer to dump log into. 793 * @size: The maximum amount of data to process. 794 * 795 * Description: 796 * This routine dumps the current target node list associated with @vport to 797 * @buf up to @size bytes of data. Each node entry in the dump will contain a 798 * node state, DID, WWPN, WWNN, RPI, flags, type, and other useful fields. 799 * 800 * Return Value: 801 * This routine returns the amount of bytes that were dumped into @buf and will 802 * not exceed @size. 803 **/ 804 static int 805 lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) 806 { 807 int len = 0; 808 int i, iocnt, outio, cnt; 809 struct lpfc_hba *phba = vport->phba; 810 struct lpfc_nodelist *ndlp; 811 unsigned char *statep; 812 unsigned long iflags; 813 struct nvme_fc_local_port *localport; 814 struct nvme_fc_remote_port *nrport = NULL; 815 struct lpfc_nvme_rport *rport; 816 817 cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE); 818 outio = 0; 819 820 len += scnprintf(buf+len, size-len, "\nFCP Nodelist Entries ...\n"); 821 spin_lock_irqsave(&vport->fc_nodes_list_lock, iflags); 822 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 823 iocnt = 0; 824 if (!cnt) { 825 len += scnprintf(buf+len, size-len, 826 "Missing Nodelist Entries\n"); 827 break; 828 } 829 cnt--; 830 switch (ndlp->nlp_state) { 831 case NLP_STE_UNUSED_NODE: 832 statep = "UNUSED"; 833 break; 834 case NLP_STE_PLOGI_ISSUE: 835 statep = "PLOGI "; 836 break; 837 case NLP_STE_ADISC_ISSUE: 838 statep = "ADISC "; 839 break; 840 case NLP_STE_REG_LOGIN_ISSUE: 841 statep = "REGLOG"; 842 break; 843 case NLP_STE_PRLI_ISSUE: 844 statep = "PRLI "; 845 break; 846 case NLP_STE_LOGO_ISSUE: 847 statep = "LOGO "; 848 break; 849 case NLP_STE_UNMAPPED_NODE: 850 statep = "UNMAP "; 851 iocnt = 1; 852 break; 853 case NLP_STE_MAPPED_NODE: 854 statep = "MAPPED"; 855 iocnt = 1; 856 break; 857 case NLP_STE_NPR_NODE: 858 statep = "NPR "; 859 break; 860 default: 861 statep = "UNKNOWN"; 862 } 863 len += scnprintf(buf+len, size-len, "%s DID:x%06x ", 864 statep, ndlp->nlp_DID); 865 len += scnprintf(buf+len, size-len, 866 "WWPN x%016llx ", 867 wwn_to_u64(ndlp->nlp_portname.u.wwn)); 868 len += scnprintf(buf+len, size-len, 869 "WWNN x%016llx ", 870 wwn_to_u64(ndlp->nlp_nodename.u.wwn)); 871 len += scnprintf(buf+len, size-len, "RPI:x%04x ", 872 ndlp->nlp_rpi); 873 len += scnprintf(buf+len, size-len, "flag:x%08lx ", 874 ndlp->nlp_flag); 875 if (ndlp->nlp_enc_info.status) { 876 len += scnprintf(buf + len, 877 size - len, "ENCRYPTED"); 878 len += scnprintf(buf + len, size - len, 879 ndlp->nlp_enc_info.level 880 ? "(CNSA2.0) " : "(CNSA1.0) "); 881 } 882 if (!ndlp->nlp_type) 883 len += scnprintf(buf+len, size-len, "UNKNOWN_TYPE "); 884 if (ndlp->nlp_type & NLP_FC_NODE) 885 len += scnprintf(buf+len, size-len, "FC_NODE "); 886 if (ndlp->nlp_type & NLP_FABRIC) { 887 len += scnprintf(buf+len, size-len, "FABRIC "); 888 iocnt = 0; 889 } 890 if (ndlp->nlp_type & NLP_FCP_TARGET) 891 len += scnprintf(buf+len, size-len, "FCP_TGT sid:%d ", 892 ndlp->nlp_sid); 893 if (ndlp->nlp_type & NLP_FCP_INITIATOR) 894 len += scnprintf(buf+len, size-len, "FCP_INITIATOR "); 895 if (ndlp->nlp_type & NLP_NVME_TARGET) 896 len += scnprintf(buf + len, 897 size - len, "NVME_TGT sid:%d ", 898 NLP_NO_SID); 899 if (ndlp->nlp_type & NLP_NVME_INITIATOR) 900 len += scnprintf(buf + len, 901 size - len, "NVME_INITIATOR "); 902 len += scnprintf(buf+len, size-len, "refcnt:%d", 903 kref_read(&ndlp->kref)); 904 if (iocnt) { 905 i = atomic_read(&ndlp->cmd_pending); 906 len += scnprintf(buf + len, size - len, 907 " OutIO:x%x Qdepth x%x", 908 i, ndlp->cmd_qdepth); 909 outio += i; 910 } 911 len += scnprintf(buf+len, size-len, " xpt:x%x", 912 ndlp->fc4_xpt_flags); 913 if (ndlp->nlp_defer_did != NLP_EVT_NOTHING_PENDING) 914 len += scnprintf(buf+len, size-len, " defer:%x", 915 ndlp->nlp_defer_did); 916 len += scnprintf(buf+len, size-len, "\n"); 917 } 918 spin_unlock_irqrestore(&vport->fc_nodes_list_lock, iflags); 919 920 len += scnprintf(buf + len, size - len, 921 "\nOutstanding IO x%x\n", outio); 922 923 if (phba->nvmet_support && phba->targetport && (vport == phba->pport)) { 924 len += scnprintf(buf + len, size - len, 925 "\nNVME Targetport Entry ...\n"); 926 927 /* Port state is only one of two values for now. */ 928 if (phba->targetport->port_id) 929 statep = "REGISTERED"; 930 else 931 statep = "INIT"; 932 len += scnprintf(buf + len, size - len, 933 "TGT WWNN x%llx WWPN x%llx State %s\n", 934 wwn_to_u64(vport->fc_nodename.u.wwn), 935 wwn_to_u64(vport->fc_portname.u.wwn), 936 statep); 937 len += scnprintf(buf + len, size - len, 938 " Targetport DID x%06x\n", 939 phba->targetport->port_id); 940 goto out_exit; 941 } 942 943 len += scnprintf(buf + len, size - len, 944 "\nNVME Lport/Rport Entries ...\n"); 945 946 localport = vport->localport; 947 if (!localport) 948 goto out_exit; 949 950 /* Port state is only one of two values for now. */ 951 if (localport->port_id) 952 statep = "ONLINE"; 953 else 954 statep = "UNKNOWN "; 955 956 len += scnprintf(buf + len, size - len, 957 "Lport DID x%06x PortState %s\n", 958 localport->port_id, statep); 959 960 len += scnprintf(buf + len, size - len, "\tRport List:\n"); 961 spin_lock_irqsave(&vport->fc_nodes_list_lock, iflags); 962 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 963 /* local short-hand pointer. */ 964 spin_lock(&ndlp->lock); 965 rport = lpfc_ndlp_get_nrport(ndlp); 966 if (rport) 967 nrport = rport->remoteport; 968 else 969 nrport = NULL; 970 spin_unlock(&ndlp->lock); 971 if (!nrport) 972 continue; 973 974 /* Port state is only one of two values for now. */ 975 switch (nrport->port_state) { 976 case FC_OBJSTATE_ONLINE: 977 statep = "ONLINE"; 978 break; 979 case FC_OBJSTATE_UNKNOWN: 980 statep = "UNKNOWN "; 981 break; 982 default: 983 statep = "UNSUPPORTED"; 984 break; 985 } 986 987 /* Tab in to show lport ownership. */ 988 len += scnprintf(buf + len, size - len, 989 "\t%s Port ID:x%06x ", 990 statep, nrport->port_id); 991 len += scnprintf(buf + len, size - len, "WWPN x%llx ", 992 nrport->port_name); 993 len += scnprintf(buf + len, size - len, "WWNN x%llx ", 994 nrport->node_name); 995 996 /* An NVME rport can have multiple roles. */ 997 if (nrport->port_role & FC_PORT_ROLE_NVME_INITIATOR) 998 len += scnprintf(buf + len, size - len, 999 "INITIATOR "); 1000 if (nrport->port_role & FC_PORT_ROLE_NVME_TARGET) 1001 len += scnprintf(buf + len, size - len, 1002 "TARGET "); 1003 if (nrport->port_role & FC_PORT_ROLE_NVME_DISCOVERY) 1004 len += scnprintf(buf + len, size - len, 1005 "DISCSRVC "); 1006 if (nrport->port_role & ~(FC_PORT_ROLE_NVME_INITIATOR | 1007 FC_PORT_ROLE_NVME_TARGET | 1008 FC_PORT_ROLE_NVME_DISCOVERY)) 1009 len += scnprintf(buf + len, size - len, 1010 "UNKNOWN ROLE x%x", 1011 nrport->port_role); 1012 /* Terminate the string. */ 1013 len += scnprintf(buf + len, size - len, "\n"); 1014 } 1015 spin_unlock_irqrestore(&vport->fc_nodes_list_lock, iflags); 1016 out_exit: 1017 return len; 1018 } 1019 1020 /** 1021 * lpfc_debugfs_nvmestat_data - Dump target node list to a buffer 1022 * @vport: The vport to gather target node info from. 1023 * @buf: The buffer to dump log into. 1024 * @size: The maximum amount of data to process. 1025 * 1026 * Description: 1027 * This routine dumps the NVME statistics associated with @vport 1028 * 1029 * Return Value: 1030 * This routine returns the amount of bytes that were dumped into @buf and will 1031 * not exceed @size. 1032 **/ 1033 static int 1034 lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) 1035 { 1036 struct lpfc_hba *phba = vport->phba; 1037 struct lpfc_nvmet_tgtport *tgtp; 1038 struct lpfc_async_xchg_ctx *ctxp, *next_ctxp; 1039 struct nvme_fc_local_port *localport; 1040 struct lpfc_fc4_ctrl_stat *cstat; 1041 struct lpfc_nvme_lport *lport; 1042 uint64_t data1, data2, data3; 1043 uint64_t tot, totin, totout; 1044 int cnt, i; 1045 int len = 0; 1046 1047 if (phba->nvmet_support) { 1048 if (!phba->targetport) 1049 return len; 1050 tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; 1051 len += scnprintf(buf + len, size - len, 1052 "\nNVME Targetport Statistics\n"); 1053 1054 len += scnprintf(buf + len, size - len, 1055 "LS: Rcv %08x Drop %08x Abort %08x\n", 1056 atomic_read(&tgtp->rcv_ls_req_in), 1057 atomic_read(&tgtp->rcv_ls_req_drop), 1058 atomic_read(&tgtp->xmt_ls_abort)); 1059 if (atomic_read(&tgtp->rcv_ls_req_in) != 1060 atomic_read(&tgtp->rcv_ls_req_out)) { 1061 len += scnprintf(buf + len, size - len, 1062 "Rcv LS: in %08x != out %08x\n", 1063 atomic_read(&tgtp->rcv_ls_req_in), 1064 atomic_read(&tgtp->rcv_ls_req_out)); 1065 } 1066 1067 len += scnprintf(buf + len, size - len, 1068 "LS: Xmt %08x Drop %08x Cmpl %08x\n", 1069 atomic_read(&tgtp->xmt_ls_rsp), 1070 atomic_read(&tgtp->xmt_ls_drop), 1071 atomic_read(&tgtp->xmt_ls_rsp_cmpl)); 1072 1073 len += scnprintf(buf + len, size - len, 1074 "LS: RSP Abort %08x xb %08x Err %08x\n", 1075 atomic_read(&tgtp->xmt_ls_rsp_aborted), 1076 atomic_read(&tgtp->xmt_ls_rsp_xb_set), 1077 atomic_read(&tgtp->xmt_ls_rsp_error)); 1078 1079 len += scnprintf(buf + len, size - len, 1080 "FCP: Rcv %08x Defer %08x Release %08x " 1081 "Drop %08x\n", 1082 atomic_read(&tgtp->rcv_fcp_cmd_in), 1083 atomic_read(&tgtp->rcv_fcp_cmd_defer), 1084 atomic_read(&tgtp->xmt_fcp_release), 1085 atomic_read(&tgtp->rcv_fcp_cmd_drop)); 1086 1087 if (atomic_read(&tgtp->rcv_fcp_cmd_in) != 1088 atomic_read(&tgtp->rcv_fcp_cmd_out)) { 1089 len += scnprintf(buf + len, size - len, 1090 "Rcv FCP: in %08x != out %08x\n", 1091 atomic_read(&tgtp->rcv_fcp_cmd_in), 1092 atomic_read(&tgtp->rcv_fcp_cmd_out)); 1093 } 1094 1095 len += scnprintf(buf + len, size - len, 1096 "FCP Rsp: read %08x readrsp %08x " 1097 "write %08x rsp %08x\n", 1098 atomic_read(&tgtp->xmt_fcp_read), 1099 atomic_read(&tgtp->xmt_fcp_read_rsp), 1100 atomic_read(&tgtp->xmt_fcp_write), 1101 atomic_read(&tgtp->xmt_fcp_rsp)); 1102 1103 len += scnprintf(buf + len, size - len, 1104 "FCP Rsp Cmpl: %08x err %08x drop %08x\n", 1105 atomic_read(&tgtp->xmt_fcp_rsp_cmpl), 1106 atomic_read(&tgtp->xmt_fcp_rsp_error), 1107 atomic_read(&tgtp->xmt_fcp_rsp_drop)); 1108 1109 len += scnprintf(buf + len, size - len, 1110 "FCP Rsp Abort: %08x xb %08x xricqe %08x\n", 1111 atomic_read(&tgtp->xmt_fcp_rsp_aborted), 1112 atomic_read(&tgtp->xmt_fcp_rsp_xb_set), 1113 atomic_read(&tgtp->xmt_fcp_xri_abort_cqe)); 1114 1115 len += scnprintf(buf + len, size - len, 1116 "ABORT: Xmt %08x Cmpl %08x\n", 1117 atomic_read(&tgtp->xmt_fcp_abort), 1118 atomic_read(&tgtp->xmt_fcp_abort_cmpl)); 1119 1120 len += scnprintf(buf + len, size - len, 1121 "ABORT: Sol %08x Usol %08x Err %08x Cmpl %08x", 1122 atomic_read(&tgtp->xmt_abort_sol), 1123 atomic_read(&tgtp->xmt_abort_unsol), 1124 atomic_read(&tgtp->xmt_abort_rsp), 1125 atomic_read(&tgtp->xmt_abort_rsp_error)); 1126 1127 len += scnprintf(buf + len, size - len, "\n"); 1128 1129 cnt = 0; 1130 spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock); 1131 list_for_each_entry_safe(ctxp, next_ctxp, 1132 &phba->sli4_hba.lpfc_abts_nvmet_ctx_list, 1133 list) { 1134 cnt++; 1135 } 1136 spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock); 1137 if (cnt) { 1138 len += scnprintf(buf + len, size - len, 1139 "ABORT: %d ctx entries\n", cnt); 1140 spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock); 1141 list_for_each_entry_safe(ctxp, next_ctxp, 1142 &phba->sli4_hba.lpfc_abts_nvmet_ctx_list, 1143 list) { 1144 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) 1145 break; 1146 len += scnprintf(buf + len, size - len, 1147 "Entry: oxid %x state %x " 1148 "flag %x\n", 1149 ctxp->oxid, ctxp->state, 1150 ctxp->flag); 1151 } 1152 spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock); 1153 } 1154 1155 /* Calculate outstanding IOs */ 1156 tot = atomic_read(&tgtp->rcv_fcp_cmd_drop); 1157 tot += atomic_read(&tgtp->xmt_fcp_release); 1158 tot = atomic_read(&tgtp->rcv_fcp_cmd_in) - tot; 1159 1160 len += scnprintf(buf + len, size - len, 1161 "IO_CTX: %08x WAIT: cur %08x tot %08x\n" 1162 "CTX Outstanding %08llx\n", 1163 phba->sli4_hba.nvmet_xri_cnt, 1164 phba->sli4_hba.nvmet_io_wait_cnt, 1165 phba->sli4_hba.nvmet_io_wait_total, 1166 tot); 1167 } else { 1168 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) 1169 return len; 1170 1171 localport = vport->localport; 1172 if (!localport) 1173 return len; 1174 lport = (struct lpfc_nvme_lport *)localport->private; 1175 if (!lport) 1176 return len; 1177 1178 len += scnprintf(buf + len, size - len, 1179 "\nNVME HDWQ Statistics\n"); 1180 1181 len += scnprintf(buf + len, size - len, 1182 "LS: Xmt %016x Cmpl %016x\n", 1183 atomic_read(&lport->fc4NvmeLsRequests), 1184 atomic_read(&lport->fc4NvmeLsCmpls)); 1185 1186 totin = 0; 1187 totout = 0; 1188 for (i = 0; i < phba->cfg_hdw_queue; i++) { 1189 cstat = &phba->sli4_hba.hdwq[i].nvme_cstat; 1190 tot = cstat->io_cmpls; 1191 totin += tot; 1192 data1 = cstat->input_requests; 1193 data2 = cstat->output_requests; 1194 data3 = cstat->control_requests; 1195 totout += (data1 + data2 + data3); 1196 1197 /* Limit to 32, debugfs display buffer limitation */ 1198 if (i >= 32) 1199 continue; 1200 1201 len += scnprintf(buf + len, PAGE_SIZE - len, 1202 "HDWQ (%d): Rd %016llx Wr %016llx " 1203 "IO %016llx ", 1204 i, data1, data2, data3); 1205 len += scnprintf(buf + len, PAGE_SIZE - len, 1206 "Cmpl %016llx OutIO %016llx\n", 1207 tot, ((data1 + data2 + data3) - tot)); 1208 } 1209 len += scnprintf(buf + len, PAGE_SIZE - len, 1210 "Total FCP Cmpl %016llx Issue %016llx " 1211 "OutIO %016llx\n", 1212 totin, totout, totout - totin); 1213 1214 len += scnprintf(buf + len, size - len, 1215 "LS Xmt Err: Abrt %08x Err %08x " 1216 "Cmpl Err: xb %08x Err %08x\n", 1217 atomic_read(&lport->xmt_ls_abort), 1218 atomic_read(&lport->xmt_ls_err), 1219 atomic_read(&lport->cmpl_ls_xb), 1220 atomic_read(&lport->cmpl_ls_err)); 1221 1222 len += scnprintf(buf + len, size - len, 1223 "FCP Xmt Err: noxri %06x nondlp %06x " 1224 "qdepth %06x wqerr %06x err %06x Abrt %06x\n", 1225 atomic_read(&lport->xmt_fcp_noxri), 1226 atomic_read(&lport->xmt_fcp_bad_ndlp), 1227 atomic_read(&lport->xmt_fcp_qdepth), 1228 atomic_read(&lport->xmt_fcp_wqerr), 1229 atomic_read(&lport->xmt_fcp_err), 1230 atomic_read(&lport->xmt_fcp_abort)); 1231 1232 len += scnprintf(buf + len, size - len, 1233 "FCP Cmpl Err: xb %08x Err %08x\n", 1234 atomic_read(&lport->cmpl_fcp_xb), 1235 atomic_read(&lport->cmpl_fcp_err)); 1236 1237 } 1238 1239 return len; 1240 } 1241 1242 /** 1243 * lpfc_debugfs_scsistat_data - Dump target node list to a buffer 1244 * @vport: The vport to gather target node info from. 1245 * @buf: The buffer to dump log into. 1246 * @size: The maximum amount of data to process. 1247 * 1248 * Description: 1249 * This routine dumps the SCSI statistics associated with @vport 1250 * 1251 * Return Value: 1252 * This routine returns the amount of bytes that were dumped into @buf and will 1253 * not exceed @size. 1254 **/ 1255 static int 1256 lpfc_debugfs_scsistat_data(struct lpfc_vport *vport, char *buf, int size) 1257 { 1258 int len; 1259 struct lpfc_hba *phba = vport->phba; 1260 struct lpfc_fc4_ctrl_stat *cstat; 1261 u64 data1, data2, data3; 1262 u64 tot, totin, totout; 1263 int i; 1264 char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0}; 1265 1266 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_FCP) || 1267 (phba->sli_rev != LPFC_SLI_REV4)) 1268 return 0; 1269 1270 scnprintf(buf, size, "SCSI HDWQ Statistics\n"); 1271 1272 totin = 0; 1273 totout = 0; 1274 for (i = 0; i < phba->cfg_hdw_queue; i++) { 1275 cstat = &phba->sli4_hba.hdwq[i].scsi_cstat; 1276 tot = cstat->io_cmpls; 1277 totin += tot; 1278 data1 = cstat->input_requests; 1279 data2 = cstat->output_requests; 1280 data3 = cstat->control_requests; 1281 totout += (data1 + data2 + data3); 1282 1283 scnprintf(tmp, sizeof(tmp), "HDWQ (%d): Rd %016llx Wr %016llx " 1284 "IO %016llx ", i, data1, data2, data3); 1285 if (strlcat(buf, tmp, size) >= size) 1286 goto buffer_done; 1287 1288 scnprintf(tmp, sizeof(tmp), "Cmpl %016llx OutIO %016llx\n", 1289 tot, ((data1 + data2 + data3) - tot)); 1290 if (strlcat(buf, tmp, size) >= size) 1291 goto buffer_done; 1292 } 1293 scnprintf(tmp, sizeof(tmp), "Total FCP Cmpl %016llx Issue %016llx " 1294 "OutIO %016llx\n", totin, totout, totout - totin); 1295 strlcat(buf, tmp, size); 1296 1297 buffer_done: 1298 len = strnlen(buf, size); 1299 1300 return len; 1301 } 1302 1303 void 1304 lpfc_io_ktime(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) 1305 { 1306 uint64_t seg1, seg2, seg3, seg4; 1307 uint64_t segsum; 1308 1309 if (!lpfc_cmd->ts_last_cmd || 1310 !lpfc_cmd->ts_cmd_start || 1311 !lpfc_cmd->ts_cmd_wqput || 1312 !lpfc_cmd->ts_isr_cmpl || 1313 !lpfc_cmd->ts_data_io) 1314 return; 1315 1316 if (lpfc_cmd->ts_data_io < lpfc_cmd->ts_cmd_start) 1317 return; 1318 if (lpfc_cmd->ts_cmd_start < lpfc_cmd->ts_last_cmd) 1319 return; 1320 if (lpfc_cmd->ts_cmd_wqput < lpfc_cmd->ts_cmd_start) 1321 return; 1322 if (lpfc_cmd->ts_isr_cmpl < lpfc_cmd->ts_cmd_wqput) 1323 return; 1324 if (lpfc_cmd->ts_data_io < lpfc_cmd->ts_isr_cmpl) 1325 return; 1326 /* 1327 * Segment 1 - Time from Last FCP command cmpl is handed 1328 * off to NVME Layer to start of next command. 1329 * Segment 2 - Time from Driver receives a IO cmd start 1330 * from NVME Layer to WQ put is done on IO cmd. 1331 * Segment 3 - Time from Driver WQ put is done on IO cmd 1332 * to MSI-X ISR for IO cmpl. 1333 * Segment 4 - Time from MSI-X ISR for IO cmpl to when 1334 * cmpl is handled off to the NVME Layer. 1335 */ 1336 seg1 = lpfc_cmd->ts_cmd_start - lpfc_cmd->ts_last_cmd; 1337 if (seg1 > 5000000) /* 5 ms - for sequential IOs only */ 1338 seg1 = 0; 1339 1340 /* Calculate times relative to start of IO */ 1341 seg2 = (lpfc_cmd->ts_cmd_wqput - lpfc_cmd->ts_cmd_start); 1342 segsum = seg2; 1343 seg3 = lpfc_cmd->ts_isr_cmpl - lpfc_cmd->ts_cmd_start; 1344 if (segsum > seg3) 1345 return; 1346 seg3 -= segsum; 1347 segsum += seg3; 1348 1349 seg4 = lpfc_cmd->ts_data_io - lpfc_cmd->ts_cmd_start; 1350 if (segsum > seg4) 1351 return; 1352 seg4 -= segsum; 1353 1354 phba->ktime_data_samples++; 1355 phba->ktime_seg1_total += seg1; 1356 if (seg1 < phba->ktime_seg1_min) 1357 phba->ktime_seg1_min = seg1; 1358 else if (seg1 > phba->ktime_seg1_max) 1359 phba->ktime_seg1_max = seg1; 1360 phba->ktime_seg2_total += seg2; 1361 if (seg2 < phba->ktime_seg2_min) 1362 phba->ktime_seg2_min = seg2; 1363 else if (seg2 > phba->ktime_seg2_max) 1364 phba->ktime_seg2_max = seg2; 1365 phba->ktime_seg3_total += seg3; 1366 if (seg3 < phba->ktime_seg3_min) 1367 phba->ktime_seg3_min = seg3; 1368 else if (seg3 > phba->ktime_seg3_max) 1369 phba->ktime_seg3_max = seg3; 1370 phba->ktime_seg4_total += seg4; 1371 if (seg4 < phba->ktime_seg4_min) 1372 phba->ktime_seg4_min = seg4; 1373 else if (seg4 > phba->ktime_seg4_max) 1374 phba->ktime_seg4_max = seg4; 1375 1376 lpfc_cmd->ts_last_cmd = 0; 1377 lpfc_cmd->ts_cmd_start = 0; 1378 lpfc_cmd->ts_cmd_wqput = 0; 1379 lpfc_cmd->ts_isr_cmpl = 0; 1380 lpfc_cmd->ts_data_io = 0; 1381 } 1382 1383 /** 1384 * lpfc_debugfs_ioktime_data - Dump target node list to a buffer 1385 * @vport: The vport to gather target node info from. 1386 * @buf: The buffer to dump log into. 1387 * @size: The maximum amount of data to process. 1388 * 1389 * Description: 1390 * This routine dumps the NVME statistics associated with @vport 1391 * 1392 * Return Value: 1393 * This routine returns the amount of bytes that were dumped into @buf and will 1394 * not exceed @size. 1395 **/ 1396 static int 1397 lpfc_debugfs_ioktime_data(struct lpfc_vport *vport, char *buf, int size) 1398 { 1399 struct lpfc_hba *phba = vport->phba; 1400 int len = 0; 1401 1402 if (phba->nvmet_support == 0) { 1403 /* Initiator */ 1404 len += scnprintf(buf + len, PAGE_SIZE - len, 1405 "ktime %s: Total Samples: %lld\n", 1406 (phba->ktime_on ? "Enabled" : "Disabled"), 1407 phba->ktime_data_samples); 1408 if (phba->ktime_data_samples == 0) 1409 return len; 1410 1411 len += scnprintf( 1412 buf + len, PAGE_SIZE - len, 1413 "Segment 1: Last Cmd cmpl " 1414 "done -to- Start of next Cmd (in driver)\n"); 1415 len += scnprintf( 1416 buf + len, PAGE_SIZE - len, 1417 "avg:%08lld min:%08lld max %08lld\n", 1418 div_u64(phba->ktime_seg1_total, 1419 phba->ktime_data_samples), 1420 phba->ktime_seg1_min, 1421 phba->ktime_seg1_max); 1422 len += scnprintf( 1423 buf + len, PAGE_SIZE - len, 1424 "Segment 2: Driver start of Cmd " 1425 "-to- Firmware WQ doorbell\n"); 1426 len += scnprintf( 1427 buf + len, PAGE_SIZE - len, 1428 "avg:%08lld min:%08lld max %08lld\n", 1429 div_u64(phba->ktime_seg2_total, 1430 phba->ktime_data_samples), 1431 phba->ktime_seg2_min, 1432 phba->ktime_seg2_max); 1433 len += scnprintf( 1434 buf + len, PAGE_SIZE - len, 1435 "Segment 3: Firmware WQ doorbell -to- " 1436 "MSI-X ISR cmpl\n"); 1437 len += scnprintf( 1438 buf + len, PAGE_SIZE - len, 1439 "avg:%08lld min:%08lld max %08lld\n", 1440 div_u64(phba->ktime_seg3_total, 1441 phba->ktime_data_samples), 1442 phba->ktime_seg3_min, 1443 phba->ktime_seg3_max); 1444 len += scnprintf( 1445 buf + len, PAGE_SIZE - len, 1446 "Segment 4: MSI-X ISR cmpl -to- " 1447 "Cmd cmpl done\n"); 1448 len += scnprintf( 1449 buf + len, PAGE_SIZE - len, 1450 "avg:%08lld min:%08lld max %08lld\n", 1451 div_u64(phba->ktime_seg4_total, 1452 phba->ktime_data_samples), 1453 phba->ktime_seg4_min, 1454 phba->ktime_seg4_max); 1455 len += scnprintf( 1456 buf + len, PAGE_SIZE - len, 1457 "Total IO avg time: %08lld\n", 1458 div_u64(phba->ktime_seg1_total + 1459 phba->ktime_seg2_total + 1460 phba->ktime_seg3_total + 1461 phba->ktime_seg4_total, 1462 phba->ktime_data_samples)); 1463 return len; 1464 } 1465 1466 /* NVME Target */ 1467 len += scnprintf(buf + len, PAGE_SIZE-len, 1468 "ktime %s: Total Samples: %lld %lld\n", 1469 (phba->ktime_on ? "Enabled" : "Disabled"), 1470 phba->ktime_data_samples, 1471 phba->ktime_status_samples); 1472 if (phba->ktime_data_samples == 0) 1473 return len; 1474 1475 len += scnprintf(buf + len, PAGE_SIZE-len, 1476 "Segment 1: MSI-X ISR Rcv cmd -to- " 1477 "cmd pass to NVME Layer\n"); 1478 len += scnprintf(buf + len, PAGE_SIZE-len, 1479 "avg:%08lld min:%08lld max %08lld\n", 1480 div_u64(phba->ktime_seg1_total, 1481 phba->ktime_data_samples), 1482 phba->ktime_seg1_min, 1483 phba->ktime_seg1_max); 1484 len += scnprintf(buf + len, PAGE_SIZE-len, 1485 "Segment 2: cmd pass to NVME Layer- " 1486 "-to- Driver rcv cmd OP (action)\n"); 1487 len += scnprintf(buf + len, PAGE_SIZE-len, 1488 "avg:%08lld min:%08lld max %08lld\n", 1489 div_u64(phba->ktime_seg2_total, 1490 phba->ktime_data_samples), 1491 phba->ktime_seg2_min, 1492 phba->ktime_seg2_max); 1493 len += scnprintf(buf + len, PAGE_SIZE-len, 1494 "Segment 3: Driver rcv cmd OP -to- " 1495 "Firmware WQ doorbell: cmd\n"); 1496 len += scnprintf(buf + len, PAGE_SIZE-len, 1497 "avg:%08lld min:%08lld max %08lld\n", 1498 div_u64(phba->ktime_seg3_total, 1499 phba->ktime_data_samples), 1500 phba->ktime_seg3_min, 1501 phba->ktime_seg3_max); 1502 len += scnprintf(buf + len, PAGE_SIZE-len, 1503 "Segment 4: Firmware WQ doorbell: cmd " 1504 "-to- MSI-X ISR for cmd cmpl\n"); 1505 len += scnprintf(buf + len, PAGE_SIZE-len, 1506 "avg:%08lld min:%08lld max %08lld\n", 1507 div_u64(phba->ktime_seg4_total, 1508 phba->ktime_data_samples), 1509 phba->ktime_seg4_min, 1510 phba->ktime_seg4_max); 1511 len += scnprintf(buf + len, PAGE_SIZE-len, 1512 "Segment 5: MSI-X ISR for cmd cmpl " 1513 "-to- NVME layer passed cmd done\n"); 1514 len += scnprintf(buf + len, PAGE_SIZE-len, 1515 "avg:%08lld min:%08lld max %08lld\n", 1516 div_u64(phba->ktime_seg5_total, 1517 phba->ktime_data_samples), 1518 phba->ktime_seg5_min, 1519 phba->ktime_seg5_max); 1520 1521 if (phba->ktime_status_samples == 0) { 1522 len += scnprintf(buf + len, PAGE_SIZE-len, 1523 "Total: cmd received by MSI-X ISR " 1524 "-to- cmd completed on wire\n"); 1525 len += scnprintf(buf + len, PAGE_SIZE-len, 1526 "avg:%08lld min:%08lld " 1527 "max %08lld\n", 1528 div_u64(phba->ktime_seg10_total, 1529 phba->ktime_data_samples), 1530 phba->ktime_seg10_min, 1531 phba->ktime_seg10_max); 1532 return len; 1533 } 1534 1535 len += scnprintf(buf + len, PAGE_SIZE-len, 1536 "Segment 6: NVME layer passed cmd done " 1537 "-to- Driver rcv rsp status OP\n"); 1538 len += scnprintf(buf + len, PAGE_SIZE-len, 1539 "avg:%08lld min:%08lld max %08lld\n", 1540 div_u64(phba->ktime_seg6_total, 1541 phba->ktime_status_samples), 1542 phba->ktime_seg6_min, 1543 phba->ktime_seg6_max); 1544 len += scnprintf(buf + len, PAGE_SIZE-len, 1545 "Segment 7: Driver rcv rsp status OP " 1546 "-to- Firmware WQ doorbell: status\n"); 1547 len += scnprintf(buf + len, PAGE_SIZE-len, 1548 "avg:%08lld min:%08lld max %08lld\n", 1549 div_u64(phba->ktime_seg7_total, 1550 phba->ktime_status_samples), 1551 phba->ktime_seg7_min, 1552 phba->ktime_seg7_max); 1553 len += scnprintf(buf + len, PAGE_SIZE-len, 1554 "Segment 8: Firmware WQ doorbell: status" 1555 " -to- MSI-X ISR for status cmpl\n"); 1556 len += scnprintf(buf + len, PAGE_SIZE-len, 1557 "avg:%08lld min:%08lld max %08lld\n", 1558 div_u64(phba->ktime_seg8_total, 1559 phba->ktime_status_samples), 1560 phba->ktime_seg8_min, 1561 phba->ktime_seg8_max); 1562 len += scnprintf(buf + len, PAGE_SIZE-len, 1563 "Segment 9: MSI-X ISR for status cmpl " 1564 "-to- NVME layer passed status done\n"); 1565 len += scnprintf(buf + len, PAGE_SIZE-len, 1566 "avg:%08lld min:%08lld max %08lld\n", 1567 div_u64(phba->ktime_seg9_total, 1568 phba->ktime_status_samples), 1569 phba->ktime_seg9_min, 1570 phba->ktime_seg9_max); 1571 len += scnprintf(buf + len, PAGE_SIZE-len, 1572 "Total: cmd received by MSI-X ISR -to- " 1573 "cmd completed on wire\n"); 1574 len += scnprintf(buf + len, PAGE_SIZE-len, 1575 "avg:%08lld min:%08lld max %08lld\n", 1576 div_u64(phba->ktime_seg10_total, 1577 phba->ktime_status_samples), 1578 phba->ktime_seg10_min, 1579 phba->ktime_seg10_max); 1580 return len; 1581 } 1582 1583 /** 1584 * lpfc_debugfs_nvmeio_trc_data - Dump NVME IO trace list to a buffer 1585 * @phba: The phba to gather target node info from. 1586 * @buf: The buffer to dump log into. 1587 * @size: The maximum amount of data to process. 1588 * 1589 * Description: 1590 * This routine dumps the NVME IO trace associated with @phba 1591 * 1592 * Return Value: 1593 * This routine returns the amount of bytes that were dumped into @buf and will 1594 * not exceed @size. 1595 **/ 1596 static int 1597 lpfc_debugfs_nvmeio_trc_data(struct lpfc_hba *phba, char *buf, int size) 1598 { 1599 struct lpfc_debugfs_nvmeio_trc *dtp; 1600 int i, state, index, skip; 1601 int len = 0; 1602 1603 state = phba->nvmeio_trc_on; 1604 1605 index = (atomic_read(&phba->nvmeio_trc_cnt) + 1) & 1606 (phba->nvmeio_trc_size - 1); 1607 skip = phba->nvmeio_trc_output_idx; 1608 1609 len += scnprintf(buf + len, size - len, 1610 "%s IO Trace %s: next_idx %d skip %d size %d\n", 1611 (phba->nvmet_support ? "NVME" : "NVMET"), 1612 (state ? "Enabled" : "Disabled"), 1613 index, skip, phba->nvmeio_trc_size); 1614 1615 if (!phba->nvmeio_trc || state) 1616 return len; 1617 1618 /* trace MUST bhe off to continue */ 1619 1620 for (i = index; i < phba->nvmeio_trc_size; i++) { 1621 if (skip) { 1622 skip--; 1623 continue; 1624 } 1625 dtp = phba->nvmeio_trc + i; 1626 phba->nvmeio_trc_output_idx++; 1627 1628 if (!dtp->fmt) 1629 continue; 1630 1631 len += scnprintf(buf + len, size - len, dtp->fmt, 1632 dtp->data1, dtp->data2, dtp->data3); 1633 1634 if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) { 1635 phba->nvmeio_trc_output_idx = 0; 1636 len += scnprintf(buf + len, size - len, 1637 "Trace Complete\n"); 1638 goto out; 1639 } 1640 1641 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) { 1642 len += scnprintf(buf + len, size - len, 1643 "Trace Continue (%d of %d)\n", 1644 phba->nvmeio_trc_output_idx, 1645 phba->nvmeio_trc_size); 1646 goto out; 1647 } 1648 } 1649 for (i = 0; i < index; i++) { 1650 if (skip) { 1651 skip--; 1652 continue; 1653 } 1654 dtp = phba->nvmeio_trc + i; 1655 phba->nvmeio_trc_output_idx++; 1656 1657 if (!dtp->fmt) 1658 continue; 1659 1660 len += scnprintf(buf + len, size - len, dtp->fmt, 1661 dtp->data1, dtp->data2, dtp->data3); 1662 1663 if (phba->nvmeio_trc_output_idx >= phba->nvmeio_trc_size) { 1664 phba->nvmeio_trc_output_idx = 0; 1665 len += scnprintf(buf + len, size - len, 1666 "Trace Complete\n"); 1667 goto out; 1668 } 1669 1670 if (len >= (size - LPFC_DEBUG_OUT_LINE_SZ)) { 1671 len += scnprintf(buf + len, size - len, 1672 "Trace Continue (%d of %d)\n", 1673 phba->nvmeio_trc_output_idx, 1674 phba->nvmeio_trc_size); 1675 goto out; 1676 } 1677 } 1678 1679 len += scnprintf(buf + len, size - len, 1680 "Trace Done\n"); 1681 out: 1682 return len; 1683 } 1684 1685 /** 1686 * lpfc_debugfs_hdwqstat_data - Dump I/O stats to a buffer 1687 * @vport: The vport to gather target node info from. 1688 * @buf: The buffer to dump log into. 1689 * @size: The maximum amount of data to process. 1690 * 1691 * Description: 1692 * This routine dumps the NVME + SCSI statistics associated with @vport 1693 * 1694 * Return Value: 1695 * This routine returns the amount of bytes that were dumped into @buf and will 1696 * not exceed @size. 1697 **/ 1698 static int 1699 lpfc_debugfs_hdwqstat_data(struct lpfc_vport *vport, char *buf, int size) 1700 { 1701 struct lpfc_hba *phba = vport->phba; 1702 struct lpfc_hdwq_stat *c_stat; 1703 int i, j, len; 1704 uint32_t tot_xmt; 1705 uint32_t tot_rcv; 1706 uint32_t tot_cmpl; 1707 char tmp[LPFC_MAX_SCSI_INFO_TMP_LEN] = {0}; 1708 1709 scnprintf(tmp, sizeof(tmp), "HDWQ Stats:\n\n"); 1710 if (strlcat(buf, tmp, size) >= size) 1711 goto buffer_done; 1712 1713 scnprintf(tmp, sizeof(tmp), "(NVME Accounting: %s) ", 1714 (phba->hdwqstat_on & 1715 (LPFC_CHECK_NVME_IO | LPFC_CHECK_NVMET_IO) ? 1716 "Enabled" : "Disabled")); 1717 if (strlcat(buf, tmp, size) >= size) 1718 goto buffer_done; 1719 1720 scnprintf(tmp, sizeof(tmp), "(SCSI Accounting: %s) ", 1721 (phba->hdwqstat_on & LPFC_CHECK_SCSI_IO ? 1722 "Enabled" : "Disabled")); 1723 if (strlcat(buf, tmp, size) >= size) 1724 goto buffer_done; 1725 1726 scnprintf(tmp, sizeof(tmp), "\n\n"); 1727 if (strlcat(buf, tmp, size) >= size) 1728 goto buffer_done; 1729 1730 for (i = 0; i < phba->cfg_hdw_queue; i++) { 1731 tot_rcv = 0; 1732 tot_xmt = 0; 1733 tot_cmpl = 0; 1734 1735 for_each_present_cpu(j) { 1736 c_stat = per_cpu_ptr(phba->sli4_hba.c_stat, j); 1737 1738 /* Only display for this HDWQ */ 1739 if (i != c_stat->hdwq_no) 1740 continue; 1741 1742 /* Only display non-zero counters */ 1743 if (!c_stat->xmt_io && !c_stat->cmpl_io && 1744 !c_stat->rcv_io) 1745 continue; 1746 1747 if (!tot_xmt && !tot_cmpl && !tot_rcv) { 1748 /* Print HDWQ string only the first time */ 1749 scnprintf(tmp, sizeof(tmp), "[HDWQ %d]:\t", i); 1750 if (strlcat(buf, tmp, size) >= size) 1751 goto buffer_done; 1752 } 1753 1754 tot_xmt += c_stat->xmt_io; 1755 tot_cmpl += c_stat->cmpl_io; 1756 if (phba->nvmet_support) 1757 tot_rcv += c_stat->rcv_io; 1758 1759 scnprintf(tmp, sizeof(tmp), "| [CPU %d]: ", j); 1760 if (strlcat(buf, tmp, size) >= size) 1761 goto buffer_done; 1762 1763 if (phba->nvmet_support) { 1764 scnprintf(tmp, sizeof(tmp), 1765 "XMT 0x%x CMPL 0x%x RCV 0x%x |", 1766 c_stat->xmt_io, c_stat->cmpl_io, 1767 c_stat->rcv_io); 1768 if (strlcat(buf, tmp, size) >= size) 1769 goto buffer_done; 1770 } else { 1771 scnprintf(tmp, sizeof(tmp), 1772 "XMT 0x%x CMPL 0x%x |", 1773 c_stat->xmt_io, c_stat->cmpl_io); 1774 if (strlcat(buf, tmp, size) >= size) 1775 goto buffer_done; 1776 } 1777 } 1778 1779 /* Check if nothing to display */ 1780 if (!tot_xmt && !tot_cmpl && !tot_rcv) 1781 continue; 1782 1783 scnprintf(tmp, sizeof(tmp), "\t->\t[HDWQ Total: "); 1784 if (strlcat(buf, tmp, size) >= size) 1785 goto buffer_done; 1786 1787 if (phba->nvmet_support) { 1788 scnprintf(tmp, sizeof(tmp), 1789 "XMT 0x%x CMPL 0x%x RCV 0x%x]\n\n", 1790 tot_xmt, tot_cmpl, tot_rcv); 1791 if (strlcat(buf, tmp, size) >= size) 1792 goto buffer_done; 1793 } else { 1794 scnprintf(tmp, sizeof(tmp), 1795 "XMT 0x%x CMPL 0x%x]\n\n", 1796 tot_xmt, tot_cmpl); 1797 if (strlcat(buf, tmp, size) >= size) 1798 goto buffer_done; 1799 } 1800 } 1801 1802 buffer_done: 1803 len = strnlen(buf, size); 1804 return len; 1805 } 1806 1807 #endif 1808 1809 /** 1810 * lpfc_debugfs_disc_trc - Store discovery trace log 1811 * @vport: The vport to associate this trace string with for retrieval. 1812 * @mask: Log entry classification. 1813 * @fmt: Format string to be displayed when dumping the log. 1814 * @data1: 1st data parameter to be applied to @fmt. 1815 * @data2: 2nd data parameter to be applied to @fmt. 1816 * @data3: 3rd data parameter to be applied to @fmt. 1817 * 1818 * Description: 1819 * This routine is used by the driver code to add a debugfs log entry to the 1820 * discovery trace buffer associated with @vport. Only entries with a @mask that 1821 * match the current debugfs discovery mask will be saved. Entries that do not 1822 * match will be thrown away. @fmt, @data1, @data2, and @data3 are used like 1823 * printf when displaying the log. 1824 **/ 1825 inline void 1826 lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt, 1827 uint32_t data1, uint32_t data2, uint32_t data3) 1828 { 1829 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS 1830 struct lpfc_debugfs_trc *dtp; 1831 int index; 1832 1833 if (!(lpfc_debugfs_mask_disc_trc & mask)) 1834 return; 1835 1836 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_disc_trc || 1837 !vport || !vport->disc_trc) 1838 return; 1839 1840 index = atomic_inc_return(&vport->disc_trc_cnt) & 1841 (lpfc_debugfs_max_disc_trc - 1); 1842 dtp = vport->disc_trc + index; 1843 dtp->fmt = fmt; 1844 dtp->data1 = data1; 1845 dtp->data2 = data2; 1846 dtp->data3 = data3; 1847 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt); 1848 dtp->jif = jiffies; 1849 #endif 1850 return; 1851 } 1852 1853 /** 1854 * lpfc_debugfs_slow_ring_trc - Store slow ring trace log 1855 * @phba: The phba to associate this trace string with for retrieval. 1856 * @fmt: Format string to be displayed when dumping the log. 1857 * @data1: 1st data parameter to be applied to @fmt. 1858 * @data2: 2nd data parameter to be applied to @fmt. 1859 * @data3: 3rd data parameter to be applied to @fmt. 1860 * 1861 * Description: 1862 * This routine is used by the driver code to add a debugfs log entry to the 1863 * discovery trace buffer associated with @vport. @fmt, @data1, @data2, and 1864 * @data3 are used like printf when displaying the log. 1865 **/ 1866 inline void 1867 lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt, 1868 uint32_t data1, uint32_t data2, uint32_t data3) 1869 { 1870 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS 1871 struct lpfc_debugfs_trc *dtp; 1872 int index; 1873 1874 if (!lpfc_debugfs_enable || !lpfc_debugfs_max_slow_ring_trc || 1875 !phba || !phba->slow_ring_trc) 1876 return; 1877 1878 index = atomic_inc_return(&phba->slow_ring_trc_cnt) & 1879 (lpfc_debugfs_max_slow_ring_trc - 1); 1880 dtp = phba->slow_ring_trc + index; 1881 dtp->fmt = fmt; 1882 dtp->data1 = data1; 1883 dtp->data2 = data2; 1884 dtp->data3 = data3; 1885 dtp->seq_cnt = atomic_inc_return(&lpfc_debugfs_seq_trc_cnt); 1886 dtp->jif = jiffies; 1887 #endif 1888 return; 1889 } 1890 1891 /** 1892 * lpfc_debugfs_nvme_trc - Store NVME/NVMET trace log 1893 * @phba: The phba to associate this trace string with for retrieval. 1894 * @fmt: Format string to be displayed when dumping the log. 1895 * @data1: 1st data parameter to be applied to @fmt. 1896 * @data2: 2nd data parameter to be applied to @fmt. 1897 * @data3: 3rd data parameter to be applied to @fmt. 1898 * 1899 * Description: 1900 * This routine is used by the driver code to add a debugfs log entry to the 1901 * nvme trace buffer associated with @phba. @fmt, @data1, @data2, and 1902 * @data3 are used like printf when displaying the log. 1903 **/ 1904 inline void 1905 lpfc_debugfs_nvme_trc(struct lpfc_hba *phba, char *fmt, 1906 uint16_t data1, uint16_t data2, uint32_t data3) 1907 { 1908 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS 1909 struct lpfc_debugfs_nvmeio_trc *dtp; 1910 int index; 1911 1912 if (!phba->nvmeio_trc_on || !phba->nvmeio_trc) 1913 return; 1914 1915 index = atomic_inc_return(&phba->nvmeio_trc_cnt) & 1916 (phba->nvmeio_trc_size - 1); 1917 dtp = phba->nvmeio_trc + index; 1918 dtp->fmt = fmt; 1919 dtp->data1 = data1; 1920 dtp->data2 = data2; 1921 dtp->data3 = data3; 1922 #endif 1923 } 1924 1925 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS 1926 /** 1927 * lpfc_debugfs_disc_trc_open - Open the discovery trace log 1928 * @inode: The inode pointer that contains a vport pointer. 1929 * @file: The file pointer to attach the log output. 1930 * 1931 * Description: 1932 * This routine is the entry point for the debugfs open file operation. It gets 1933 * the vport from the i_private field in @inode, allocates the necessary buffer 1934 * for the log, fills the buffer from the in-memory log for this vport, and then 1935 * returns a pointer to that log in the private_data field in @file. 1936 * 1937 * Returns: 1938 * This function returns zero if successful. On error it will return a negative 1939 * error value. 1940 **/ 1941 static int 1942 lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file) 1943 { 1944 struct lpfc_vport *vport = inode->i_private; 1945 struct lpfc_debug *debug; 1946 int size; 1947 int rc = -ENOMEM; 1948 1949 if (!lpfc_debugfs_max_disc_trc) { 1950 rc = -ENOSPC; 1951 goto out; 1952 } 1953 1954 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 1955 if (!debug) 1956 goto out; 1957 1958 /* Round to page boundary */ 1959 size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); 1960 size = PAGE_ALIGN(size); 1961 1962 debug->buffer = kmalloc(size, GFP_KERNEL); 1963 if (!debug->buffer) { 1964 kfree(debug); 1965 goto out; 1966 } 1967 1968 debug->len = lpfc_debugfs_disc_trc_data(vport, debug->buffer, size); 1969 file->private_data = debug; 1970 1971 rc = 0; 1972 out: 1973 return rc; 1974 } 1975 1976 /** 1977 * lpfc_debugfs_slow_ring_trc_open - Open the Slow Ring trace log 1978 * @inode: The inode pointer that contains a vport pointer. 1979 * @file: The file pointer to attach the log output. 1980 * 1981 * Description: 1982 * This routine is the entry point for the debugfs open file operation. It gets 1983 * the vport from the i_private field in @inode, allocates the necessary buffer 1984 * for the log, fills the buffer from the in-memory log for this vport, and then 1985 * returns a pointer to that log in the private_data field in @file. 1986 * 1987 * Returns: 1988 * This function returns zero if successful. On error it will return a negative 1989 * error value. 1990 **/ 1991 static int 1992 lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file) 1993 { 1994 struct lpfc_hba *phba = inode->i_private; 1995 struct lpfc_debug *debug; 1996 int size; 1997 int rc = -ENOMEM; 1998 1999 if (!lpfc_debugfs_max_slow_ring_trc) { 2000 rc = -ENOSPC; 2001 goto out; 2002 } 2003 2004 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 2005 if (!debug) 2006 goto out; 2007 2008 /* Round to page boundary */ 2009 size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE); 2010 size = PAGE_ALIGN(size); 2011 2012 debug->buffer = kmalloc(size, GFP_KERNEL); 2013 if (!debug->buffer) { 2014 kfree(debug); 2015 goto out; 2016 } 2017 2018 debug->len = lpfc_debugfs_slow_ring_trc_data(phba, debug->buffer, size); 2019 file->private_data = debug; 2020 2021 rc = 0; 2022 out: 2023 return rc; 2024 } 2025 2026 /** 2027 * lpfc_debugfs_hbqinfo_open - Open the hbqinfo debugfs buffer 2028 * @inode: The inode pointer that contains a vport pointer. 2029 * @file: The file pointer to attach the log output. 2030 * 2031 * Description: 2032 * This routine is the entry point for the debugfs open file operation. It gets 2033 * the vport from the i_private field in @inode, allocates the necessary buffer 2034 * for the log, fills the buffer from the in-memory log for this vport, and then 2035 * returns a pointer to that log in the private_data field in @file. 2036 * 2037 * Returns: 2038 * This function returns zero if successful. On error it will return a negative 2039 * error value. 2040 **/ 2041 static int 2042 lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file) 2043 { 2044 struct lpfc_hba *phba = inode->i_private; 2045 struct lpfc_debug *debug; 2046 int rc = -ENOMEM; 2047 2048 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 2049 if (!debug) 2050 goto out; 2051 2052 /* Round to page boundary */ 2053 debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL); 2054 if (!debug->buffer) { 2055 kfree(debug); 2056 goto out; 2057 } 2058 2059 debug->len = lpfc_debugfs_hbqinfo_data(phba, debug->buffer, 2060 LPFC_HBQINFO_SIZE); 2061 file->private_data = debug; 2062 2063 rc = 0; 2064 out: 2065 return rc; 2066 } 2067 2068 /** 2069 * lpfc_debugfs_multixripools_open - Open the multixripool debugfs buffer 2070 * @inode: The inode pointer that contains a hba pointer. 2071 * @file: The file pointer to attach the log output. 2072 * 2073 * Description: 2074 * This routine is the entry point for the debugfs open file operation. It gets 2075 * the hba from the i_private field in @inode, allocates the necessary buffer 2076 * for the log, fills the buffer from the in-memory log for this hba, and then 2077 * returns a pointer to that log in the private_data field in @file. 2078 * 2079 * Returns: 2080 * This function returns zero if successful. On error it will return a negative 2081 * error value. 2082 **/ 2083 static int 2084 lpfc_debugfs_multixripools_open(struct inode *inode, struct file *file) 2085 { 2086 struct lpfc_hba *phba = inode->i_private; 2087 struct lpfc_debug *debug; 2088 int rc = -ENOMEM; 2089 2090 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 2091 if (!debug) 2092 goto out; 2093 2094 /* Round to page boundary */ 2095 debug->buffer = kzalloc(LPFC_DUMP_MULTIXRIPOOL_SIZE, GFP_KERNEL); 2096 if (!debug->buffer) { 2097 kfree(debug); 2098 goto out; 2099 } 2100 2101 debug->len = lpfc_debugfs_multixripools_data( 2102 phba, debug->buffer, LPFC_DUMP_MULTIXRIPOOL_SIZE); 2103 2104 debug->i_private = inode->i_private; 2105 file->private_data = debug; 2106 2107 rc = 0; 2108 out: 2109 return rc; 2110 } 2111 2112 #ifdef LPFC_HDWQ_LOCK_STAT 2113 /** 2114 * lpfc_debugfs_lockstat_open - Open the lockstat debugfs buffer 2115 * @inode: The inode pointer that contains a vport pointer. 2116 * @file: The file pointer to attach the log output. 2117 * 2118 * Description: 2119 * This routine is the entry point for the debugfs open file operation. It gets 2120 * the vport from the i_private field in @inode, allocates the necessary buffer 2121 * for the log, fills the buffer from the in-memory log for this vport, and then 2122 * returns a pointer to that log in the private_data field in @file. 2123 * 2124 * Returns: 2125 * This function returns zero if successful. On error it will return a negative 2126 * error value. 2127 **/ 2128 static int 2129 lpfc_debugfs_lockstat_open(struct inode *inode, struct file *file) 2130 { 2131 struct lpfc_hba *phba = inode->i_private; 2132 struct lpfc_debug *debug; 2133 int rc = -ENOMEM; 2134 2135 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 2136 if (!debug) 2137 goto out; 2138 2139 /* Round to page boundary */ 2140 debug->buffer = kmalloc(LPFC_HDWQINFO_SIZE, GFP_KERNEL); 2141 if (!debug->buffer) { 2142 kfree(debug); 2143 goto out; 2144 } 2145 2146 debug->len = lpfc_debugfs_lockstat_data(phba, debug->buffer, 2147 LPFC_HBQINFO_SIZE); 2148 file->private_data = debug; 2149 2150 rc = 0; 2151 out: 2152 return rc; 2153 } 2154 2155 static ssize_t 2156 lpfc_debugfs_lockstat_write(struct file *file, const char __user *buf, 2157 size_t nbytes, loff_t *ppos) 2158 { 2159 struct lpfc_debug *debug = file->private_data; 2160 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 2161 struct lpfc_sli4_hdw_queue *qp; 2162 char mybuf[64]; 2163 char *pbuf; 2164 int i; 2165 size_t bsize; 2166 2167 memset(mybuf, 0, sizeof(mybuf)); 2168 2169 bsize = min(nbytes, (sizeof(mybuf) - 1)); 2170 2171 if (copy_from_user(mybuf, buf, bsize)) 2172 return -EFAULT; 2173 pbuf = &mybuf[0]; 2174 2175 if ((strncmp(pbuf, "reset", strlen("reset")) == 0) || 2176 (strncmp(pbuf, "zero", strlen("zero")) == 0)) { 2177 for (i = 0; i < phba->cfg_hdw_queue; i++) { 2178 qp = &phba->sli4_hba.hdwq[i]; 2179 qp->lock_conflict.alloc_xri_get = 0; 2180 qp->lock_conflict.alloc_xri_put = 0; 2181 qp->lock_conflict.free_xri = 0; 2182 qp->lock_conflict.wq_access = 0; 2183 qp->lock_conflict.alloc_pvt_pool = 0; 2184 qp->lock_conflict.mv_from_pvt_pool = 0; 2185 qp->lock_conflict.mv_to_pub_pool = 0; 2186 qp->lock_conflict.mv_to_pvt_pool = 0; 2187 qp->lock_conflict.free_pvt_pool = 0; 2188 qp->lock_conflict.free_pub_pool = 0; 2189 qp->lock_conflict.wq_access = 0; 2190 } 2191 } 2192 return bsize; 2193 } 2194 #endif 2195 2196 static int lpfc_debugfs_ras_log_data(struct lpfc_hba *phba, 2197 char *buffer, int size) 2198 { 2199 int copied = 0; 2200 struct lpfc_dmabuf *dmabuf, *next; 2201 2202 memset(buffer, 0, size); 2203 2204 spin_lock_irq(&phba->ras_fwlog_lock); 2205 if (phba->ras_fwlog.state != ACTIVE) { 2206 spin_unlock_irq(&phba->ras_fwlog_lock); 2207 return -EINVAL; 2208 } 2209 spin_unlock_irq(&phba->ras_fwlog_lock); 2210 2211 list_for_each_entry_safe(dmabuf, next, 2212 &phba->ras_fwlog.fwlog_buff_list, list) { 2213 /* Check if copying will go over size and a '\0' char */ 2214 if ((copied + LPFC_RAS_MAX_ENTRY_SIZE) >= (size - 1)) { 2215 memcpy(buffer + copied, dmabuf->virt, 2216 size - copied - 1); 2217 copied += size - copied - 1; 2218 break; 2219 } 2220 memcpy(buffer + copied, dmabuf->virt, LPFC_RAS_MAX_ENTRY_SIZE); 2221 copied += LPFC_RAS_MAX_ENTRY_SIZE; 2222 } 2223 return copied; 2224 } 2225 2226 static int 2227 lpfc_debugfs_ras_log_release(struct inode *inode, struct file *file) 2228 { 2229 struct lpfc_debug *debug = file->private_data; 2230 2231 vfree(debug->buffer); 2232 kfree(debug); 2233 2234 return 0; 2235 } 2236 2237 /** 2238 * lpfc_debugfs_ras_log_open - Open the RAS log debugfs buffer 2239 * @inode: The inode pointer that contains a vport pointer. 2240 * @file: The file pointer to attach the log output. 2241 * 2242 * Description: 2243 * This routine is the entry point for the debugfs open file operation. It gets 2244 * the vport from the i_private field in @inode, allocates the necessary buffer 2245 * for the log, fills the buffer from the in-memory log for this vport, and then 2246 * returns a pointer to that log in the private_data field in @file. 2247 * 2248 * Returns: 2249 * This function returns zero if successful. On error it will return a negative 2250 * error value. 2251 **/ 2252 static int 2253 lpfc_debugfs_ras_log_open(struct inode *inode, struct file *file) 2254 { 2255 struct lpfc_hba *phba = inode->i_private; 2256 struct lpfc_debug *debug; 2257 int size; 2258 int rc = -ENOMEM; 2259 2260 spin_lock_irq(&phba->ras_fwlog_lock); 2261 if (phba->ras_fwlog.state != ACTIVE) { 2262 spin_unlock_irq(&phba->ras_fwlog_lock); 2263 rc = -EINVAL; 2264 goto out; 2265 } 2266 spin_unlock_irq(&phba->ras_fwlog_lock); 2267 2268 if (check_mul_overflow(LPFC_RAS_MIN_BUFF_POST_SIZE, 2269 phba->cfg_ras_fwlog_buffsize, &size)) 2270 goto out; 2271 2272 debug = kzalloc(sizeof(*debug), GFP_KERNEL); 2273 if (!debug) 2274 goto out; 2275 2276 debug->buffer = vmalloc(size); 2277 if (!debug->buffer) 2278 goto free_debug; 2279 2280 debug->len = lpfc_debugfs_ras_log_data(phba, debug->buffer, size); 2281 if (debug->len < 0) { 2282 rc = -EINVAL; 2283 goto free_buffer; 2284 } 2285 file->private_data = debug; 2286 2287 return 0; 2288 2289 free_buffer: 2290 vfree(debug->buffer); 2291 free_debug: 2292 kfree(debug); 2293 out: 2294 return rc; 2295 } 2296 2297 /** 2298 * lpfc_debugfs_dumpHBASlim_open - Open the Dump HBA SLIM debugfs buffer 2299 * @inode: The inode pointer that contains a vport pointer. 2300 * @file: The file pointer to attach the log output. 2301 * 2302 * Description: 2303 * This routine is the entry point for the debugfs open file operation. It gets 2304 * the vport from the i_private field in @inode, allocates the necessary buffer 2305 * for the log, fills the buffer from the in-memory log for this vport, and then 2306 * returns a pointer to that log in the private_data field in @file. 2307 * 2308 * Returns: 2309 * This function returns zero if successful. On error it will return a negative 2310 * error value. 2311 **/ 2312 static int 2313 lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file) 2314 { 2315 struct lpfc_hba *phba = inode->i_private; 2316 struct lpfc_debug *debug; 2317 int rc = -ENOMEM; 2318 2319 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 2320 if (!debug) 2321 goto out; 2322 2323 /* Round to page boundary */ 2324 debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL); 2325 if (!debug->buffer) { 2326 kfree(debug); 2327 goto out; 2328 } 2329 2330 debug->len = lpfc_debugfs_dumpHBASlim_data(phba, debug->buffer, 2331 LPFC_DUMPHBASLIM_SIZE); 2332 file->private_data = debug; 2333 2334 rc = 0; 2335 out: 2336 return rc; 2337 } 2338 2339 /** 2340 * lpfc_debugfs_dumpHostSlim_open - Open the Dump Host SLIM debugfs buffer 2341 * @inode: The inode pointer that contains a vport pointer. 2342 * @file: The file pointer to attach the log output. 2343 * 2344 * Description: 2345 * This routine is the entry point for the debugfs open file operation. It gets 2346 * the vport from the i_private field in @inode, allocates the necessary buffer 2347 * for the log, fills the buffer from the in-memory log for this vport, and then 2348 * returns a pointer to that log in the private_data field in @file. 2349 * 2350 * Returns: 2351 * This function returns zero if successful. On error it will return a negative 2352 * error value. 2353 **/ 2354 static int 2355 lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file) 2356 { 2357 struct lpfc_hba *phba = inode->i_private; 2358 struct lpfc_debug *debug; 2359 int rc = -ENOMEM; 2360 2361 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 2362 if (!debug) 2363 goto out; 2364 2365 /* Round to page boundary */ 2366 debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL); 2367 if (!debug->buffer) { 2368 kfree(debug); 2369 goto out; 2370 } 2371 2372 debug->len = lpfc_debugfs_dumpHostSlim_data(phba, debug->buffer, 2373 LPFC_DUMPHOSTSLIM_SIZE); 2374 file->private_data = debug; 2375 2376 rc = 0; 2377 out: 2378 return rc; 2379 } 2380 2381 static ssize_t 2382 lpfc_debugfs_dif_err_read(struct file *file, char __user *buf, 2383 size_t nbytes, loff_t *ppos) 2384 { 2385 struct lpfc_hba *phba = file->private_data; 2386 int kind = debugfs_get_aux_num(file); 2387 char cbuf[32] = {0}; 2388 int cnt = 0; 2389 2390 switch (kind) { 2391 case writeGuard: 2392 cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n", 2393 phba->lpfc_injerr_wgrd_cnt); 2394 break; 2395 case writeApp: 2396 cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n", 2397 phba->lpfc_injerr_wapp_cnt); 2398 break; 2399 case writeRef: 2400 cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n", 2401 phba->lpfc_injerr_wref_cnt); 2402 break; 2403 case readGuard: 2404 cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n", 2405 phba->lpfc_injerr_rgrd_cnt); 2406 break; 2407 case readApp: 2408 cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n", 2409 phba->lpfc_injerr_rapp_cnt); 2410 break; 2411 case readRef: 2412 cnt = scnprintf(cbuf, sizeof(cbuf), "%u\n", 2413 phba->lpfc_injerr_rref_cnt); 2414 break; 2415 case InjErrNPortID: 2416 cnt = scnprintf(cbuf, sizeof(cbuf), "0x%06x\n", 2417 phba->lpfc_injerr_nportid); 2418 break; 2419 case InjErrWWPN: 2420 cnt = scnprintf(cbuf, sizeof(cbuf), "0x%016llx\n", 2421 be64_to_cpu(phba->lpfc_injerr_wwpn.u.wwn_be)); 2422 break; 2423 case InjErrLBA: 2424 if (phba->lpfc_injerr_lba == LPFC_INJERR_LBA_OFF) 2425 cnt = scnprintf(cbuf, sizeof(cbuf), "off\n"); 2426 else 2427 cnt = scnprintf(cbuf, sizeof(cbuf), "0x%llx\n", 2428 (uint64_t)phba->lpfc_injerr_lba); 2429 break; 2430 default: 2431 lpfc_log_msg(phba, KERN_WARNING, LOG_INIT, 2432 "0547 Unknown debugfs error injection entry\n"); 2433 break; 2434 } 2435 2436 return simple_read_from_buffer(buf, nbytes, ppos, &cbuf, cnt); 2437 } 2438 2439 static ssize_t 2440 lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf, 2441 size_t nbytes, loff_t *ppos) 2442 { 2443 struct lpfc_hba *phba = file->private_data; 2444 int kind = debugfs_get_aux_num(file); 2445 char dstbuf[33] = {0}; 2446 unsigned long long tmp; 2447 unsigned long size; 2448 2449 size = (nbytes < (sizeof(dstbuf) - 1)) ? nbytes : (sizeof(dstbuf) - 1); 2450 if (copy_from_user(dstbuf, buf, size)) 2451 return -EFAULT; 2452 2453 if (kstrtoull(dstbuf, 0, &tmp)) { 2454 if (kind != InjErrLBA || !strstr(dstbuf, "off")) 2455 return -EINVAL; 2456 } 2457 2458 switch (kind) { 2459 case writeGuard: 2460 phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp; 2461 break; 2462 case writeApp: 2463 phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp; 2464 break; 2465 case writeRef: 2466 phba->lpfc_injerr_wref_cnt = (uint32_t)tmp; 2467 break; 2468 case readGuard: 2469 phba->lpfc_injerr_rgrd_cnt = (uint32_t)tmp; 2470 break; 2471 case readApp: 2472 phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp; 2473 break; 2474 case readRef: 2475 phba->lpfc_injerr_rref_cnt = (uint32_t)tmp; 2476 break; 2477 case InjErrLBA: 2478 if (strstr(dstbuf, "off")) 2479 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; 2480 else 2481 phba->lpfc_injerr_lba = (sector_t)tmp; 2482 break; 2483 case InjErrNPortID: 2484 phba->lpfc_injerr_nportid = (uint32_t)(tmp & Mask_DID); 2485 break; 2486 case InjErrWWPN: 2487 phba->lpfc_injerr_wwpn.u.wwn_be = cpu_to_be64(tmp); 2488 break; 2489 default: 2490 lpfc_log_msg(phba, KERN_WARNING, LOG_INIT, 2491 "0548 Unknown debugfs error injection entry\n"); 2492 break; 2493 } 2494 return nbytes; 2495 } 2496 2497 static int 2498 lpfc_debugfs_dif_err_release(struct inode *inode, struct file *file) 2499 { 2500 return 0; 2501 } 2502 2503 /** 2504 * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file 2505 * @inode: The inode pointer that contains a vport pointer. 2506 * @file: The file pointer to attach the log output. 2507 * 2508 * Description: 2509 * This routine is the entry point for the debugfs open file operation. It gets 2510 * the vport from the i_private field in @inode, allocates the necessary buffer 2511 * for the log, fills the buffer from the in-memory log for this vport, and then 2512 * returns a pointer to that log in the private_data field in @file. 2513 * 2514 * Returns: 2515 * This function returns zero if successful. On error it will return a negative 2516 * error value. 2517 **/ 2518 static int 2519 lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file) 2520 { 2521 struct lpfc_vport *vport = inode->i_private; 2522 struct lpfc_debug *debug; 2523 int rc = -ENOMEM; 2524 2525 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 2526 if (!debug) 2527 goto out; 2528 2529 /* Round to page boundary */ 2530 debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL); 2531 if (!debug->buffer) { 2532 kfree(debug); 2533 goto out; 2534 } 2535 2536 debug->len = lpfc_debugfs_nodelist_data(vport, debug->buffer, 2537 LPFC_NODELIST_SIZE); 2538 file->private_data = debug; 2539 2540 rc = 0; 2541 out: 2542 return rc; 2543 } 2544 2545 /** 2546 * lpfc_debugfs_lseek - Seek through a debugfs file 2547 * @file: The file pointer to seek through. 2548 * @off: The offset to seek to or the amount to seek by. 2549 * @whence: Indicates how to seek. 2550 * 2551 * Description: 2552 * This routine is the entry point for the debugfs lseek file operation. The 2553 * @whence parameter indicates whether @off is the offset to directly seek to, 2554 * or if it is a value to seek forward or reverse by. This function figures out 2555 * what the new offset of the debugfs file will be and assigns that value to the 2556 * f_pos field of @file. 2557 * 2558 * Returns: 2559 * This function returns the new offset if successful and returns a negative 2560 * error if unable to process the seek. 2561 **/ 2562 static loff_t 2563 lpfc_debugfs_lseek(struct file *file, loff_t off, int whence) 2564 { 2565 struct lpfc_debug *debug = file->private_data; 2566 return fixed_size_llseek(file, off, whence, debug->len); 2567 } 2568 2569 /** 2570 * lpfc_debugfs_read - Read a debugfs file 2571 * @file: The file pointer to read from. 2572 * @buf: The buffer to copy the data to. 2573 * @nbytes: The number of bytes to read. 2574 * @ppos: The position in the file to start reading from. 2575 * 2576 * Description: 2577 * This routine reads data from from the buffer indicated in the private_data 2578 * field of @file. It will start reading at @ppos and copy up to @nbytes of 2579 * data to @buf. 2580 * 2581 * Returns: 2582 * This function returns the amount of data that was read (this could be less 2583 * than @nbytes if the end of the file was reached) or a negative error value. 2584 **/ 2585 static ssize_t 2586 lpfc_debugfs_read(struct file *file, char __user *buf, 2587 size_t nbytes, loff_t *ppos) 2588 { 2589 struct lpfc_debug *debug = file->private_data; 2590 2591 return simple_read_from_buffer(buf, nbytes, ppos, debug->buffer, 2592 debug->len); 2593 } 2594 2595 /** 2596 * lpfc_debugfs_release - Release the buffer used to store debugfs file data 2597 * @inode: The inode pointer that contains a vport pointer. (unused) 2598 * @file: The file pointer that contains the buffer to release. 2599 * 2600 * Description: 2601 * This routine frees the buffer that was allocated when the debugfs file was 2602 * opened. 2603 * 2604 * Returns: 2605 * This function returns zero. 2606 **/ 2607 static int 2608 lpfc_debugfs_release(struct inode *inode, struct file *file) 2609 { 2610 struct lpfc_debug *debug = file->private_data; 2611 2612 kfree(debug->buffer); 2613 kfree(debug); 2614 2615 return 0; 2616 } 2617 2618 /** 2619 * lpfc_debugfs_multixripools_write - Clear multi-XRI pools statistics 2620 * @file: The file pointer to read from. 2621 * @buf: The buffer to copy the user data from. 2622 * @nbytes: The number of bytes to get. 2623 * @ppos: The position in the file to start reading from. 2624 * 2625 * Description: 2626 * This routine clears multi-XRI pools statistics when buf contains "clear". 2627 * 2628 * Return Value: 2629 * It returns the @nbytges passing in from debugfs user space when successful. 2630 * In case of error conditions, it returns proper error code back to the user 2631 * space. 2632 **/ 2633 static ssize_t 2634 lpfc_debugfs_multixripools_write(struct file *file, const char __user *buf, 2635 size_t nbytes, loff_t *ppos) 2636 { 2637 struct lpfc_debug *debug = file->private_data; 2638 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 2639 char mybuf[64]; 2640 char *pbuf; 2641 u32 i; 2642 u32 hwq_count; 2643 struct lpfc_sli4_hdw_queue *qp; 2644 struct lpfc_multixri_pool *multixri_pool; 2645 2646 if (nbytes > sizeof(mybuf) - 1) 2647 nbytes = sizeof(mybuf) - 1; 2648 2649 memset(mybuf, 0, sizeof(mybuf)); 2650 2651 if (copy_from_user(mybuf, buf, nbytes)) 2652 return -EFAULT; 2653 pbuf = &mybuf[0]; 2654 2655 if ((strncmp(pbuf, "clear", strlen("clear"))) == 0) { 2656 hwq_count = phba->cfg_hdw_queue; 2657 for (i = 0; i < hwq_count; i++) { 2658 qp = &phba->sli4_hba.hdwq[i]; 2659 multixri_pool = qp->p_multixri_pool; 2660 if (!multixri_pool) 2661 continue; 2662 2663 qp->empty_io_bufs = 0; 2664 multixri_pool->pbl_empty_count = 0; 2665 #ifdef LPFC_MXP_STAT 2666 multixri_pool->above_limit_count = 0; 2667 multixri_pool->below_limit_count = 0; 2668 multixri_pool->stat_max_hwm = 0; 2669 multixri_pool->local_pbl_hit_count = 0; 2670 multixri_pool->other_pbl_hit_count = 0; 2671 2672 multixri_pool->stat_pbl_count = 0; 2673 multixri_pool->stat_pvt_count = 0; 2674 multixri_pool->stat_busy_count = 0; 2675 multixri_pool->stat_snapshot_taken = 0; 2676 #endif 2677 } 2678 return strlen(pbuf); 2679 } 2680 2681 return -EINVAL; 2682 } 2683 2684 static int 2685 lpfc_debugfs_nvmestat_open(struct inode *inode, struct file *file) 2686 { 2687 struct lpfc_vport *vport = inode->i_private; 2688 struct lpfc_debug *debug; 2689 int rc = -ENOMEM; 2690 2691 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 2692 if (!debug) 2693 goto out; 2694 2695 /* Round to page boundary */ 2696 debug->buffer = kmalloc(LPFC_NVMESTAT_SIZE, GFP_KERNEL); 2697 if (!debug->buffer) { 2698 kfree(debug); 2699 goto out; 2700 } 2701 2702 debug->len = lpfc_debugfs_nvmestat_data(vport, debug->buffer, 2703 LPFC_NVMESTAT_SIZE); 2704 2705 debug->i_private = inode->i_private; 2706 file->private_data = debug; 2707 2708 rc = 0; 2709 out: 2710 return rc; 2711 } 2712 2713 static ssize_t 2714 lpfc_debugfs_nvmestat_write(struct file *file, const char __user *buf, 2715 size_t nbytes, loff_t *ppos) 2716 { 2717 struct lpfc_debug *debug = file->private_data; 2718 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private; 2719 struct lpfc_hba *phba = vport->phba; 2720 struct lpfc_nvmet_tgtport *tgtp; 2721 char mybuf[64]; 2722 char *pbuf; 2723 2724 if (!phba->targetport) 2725 return -ENXIO; 2726 2727 if (nbytes > sizeof(mybuf) - 1) 2728 nbytes = sizeof(mybuf) - 1; 2729 2730 memset(mybuf, 0, sizeof(mybuf)); 2731 2732 if (copy_from_user(mybuf, buf, nbytes)) 2733 return -EFAULT; 2734 pbuf = &mybuf[0]; 2735 2736 tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; 2737 if ((strncmp(pbuf, "reset", strlen("reset")) == 0) || 2738 (strncmp(pbuf, "zero", strlen("zero")) == 0)) { 2739 atomic_set(&tgtp->rcv_ls_req_in, 0); 2740 atomic_set(&tgtp->rcv_ls_req_out, 0); 2741 atomic_set(&tgtp->rcv_ls_req_drop, 0); 2742 atomic_set(&tgtp->xmt_ls_abort, 0); 2743 atomic_set(&tgtp->xmt_ls_abort_cmpl, 0); 2744 atomic_set(&tgtp->xmt_ls_rsp, 0); 2745 atomic_set(&tgtp->xmt_ls_drop, 0); 2746 atomic_set(&tgtp->xmt_ls_rsp_error, 0); 2747 atomic_set(&tgtp->xmt_ls_rsp_cmpl, 0); 2748 2749 atomic_set(&tgtp->rcv_fcp_cmd_in, 0); 2750 atomic_set(&tgtp->rcv_fcp_cmd_out, 0); 2751 atomic_set(&tgtp->rcv_fcp_cmd_drop, 0); 2752 atomic_set(&tgtp->xmt_fcp_drop, 0); 2753 atomic_set(&tgtp->xmt_fcp_read_rsp, 0); 2754 atomic_set(&tgtp->xmt_fcp_read, 0); 2755 atomic_set(&tgtp->xmt_fcp_write, 0); 2756 atomic_set(&tgtp->xmt_fcp_rsp, 0); 2757 atomic_set(&tgtp->xmt_fcp_release, 0); 2758 atomic_set(&tgtp->xmt_fcp_rsp_cmpl, 0); 2759 atomic_set(&tgtp->xmt_fcp_rsp_error, 0); 2760 atomic_set(&tgtp->xmt_fcp_rsp_drop, 0); 2761 2762 atomic_set(&tgtp->xmt_fcp_abort, 0); 2763 atomic_set(&tgtp->xmt_fcp_abort_cmpl, 0); 2764 atomic_set(&tgtp->xmt_abort_sol, 0); 2765 atomic_set(&tgtp->xmt_abort_unsol, 0); 2766 atomic_set(&tgtp->xmt_abort_rsp, 0); 2767 atomic_set(&tgtp->xmt_abort_rsp_error, 0); 2768 } 2769 return nbytes; 2770 } 2771 2772 static int 2773 lpfc_debugfs_scsistat_open(struct inode *inode, struct file *file) 2774 { 2775 struct lpfc_vport *vport = inode->i_private; 2776 struct lpfc_debug *debug; 2777 int rc = -ENOMEM; 2778 2779 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 2780 if (!debug) 2781 goto out; 2782 2783 /* Round to page boundary */ 2784 debug->buffer = kzalloc(LPFC_SCSISTAT_SIZE, GFP_KERNEL); 2785 if (!debug->buffer) { 2786 kfree(debug); 2787 goto out; 2788 } 2789 2790 debug->len = lpfc_debugfs_scsistat_data(vport, debug->buffer, 2791 LPFC_SCSISTAT_SIZE); 2792 2793 debug->i_private = inode->i_private; 2794 file->private_data = debug; 2795 2796 rc = 0; 2797 out: 2798 return rc; 2799 } 2800 2801 static ssize_t 2802 lpfc_debugfs_scsistat_write(struct file *file, const char __user *buf, 2803 size_t nbytes, loff_t *ppos) 2804 { 2805 struct lpfc_debug *debug = file->private_data; 2806 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private; 2807 struct lpfc_hba *phba = vport->phba; 2808 char mybuf[6] = {0}; 2809 int i; 2810 2811 if (copy_from_user(mybuf, buf, (nbytes >= sizeof(mybuf)) ? 2812 (sizeof(mybuf) - 1) : nbytes)) 2813 return -EFAULT; 2814 2815 if ((strncmp(&mybuf[0], "reset", strlen("reset")) == 0) || 2816 (strncmp(&mybuf[0], "zero", strlen("zero")) == 0)) { 2817 for (i = 0; i < phba->cfg_hdw_queue; i++) { 2818 memset(&phba->sli4_hba.hdwq[i].scsi_cstat, 0, 2819 sizeof(phba->sli4_hba.hdwq[i].scsi_cstat)); 2820 } 2821 } 2822 2823 return nbytes; 2824 } 2825 2826 static int 2827 lpfc_debugfs_ioktime_open(struct inode *inode, struct file *file) 2828 { 2829 struct lpfc_vport *vport = inode->i_private; 2830 struct lpfc_debug *debug; 2831 int rc = -ENOMEM; 2832 2833 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 2834 if (!debug) 2835 goto out; 2836 2837 /* Round to page boundary */ 2838 debug->buffer = kmalloc(LPFC_IOKTIME_SIZE, GFP_KERNEL); 2839 if (!debug->buffer) { 2840 kfree(debug); 2841 goto out; 2842 } 2843 2844 debug->len = lpfc_debugfs_ioktime_data(vport, debug->buffer, 2845 LPFC_IOKTIME_SIZE); 2846 2847 debug->i_private = inode->i_private; 2848 file->private_data = debug; 2849 2850 rc = 0; 2851 out: 2852 return rc; 2853 } 2854 2855 static ssize_t 2856 lpfc_debugfs_ioktime_write(struct file *file, const char __user *buf, 2857 size_t nbytes, loff_t *ppos) 2858 { 2859 struct lpfc_debug *debug = file->private_data; 2860 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private; 2861 struct lpfc_hba *phba = vport->phba; 2862 char mybuf[64]; 2863 char *pbuf; 2864 2865 if (nbytes > sizeof(mybuf) - 1) 2866 nbytes = sizeof(mybuf) - 1; 2867 2868 memset(mybuf, 0, sizeof(mybuf)); 2869 2870 if (copy_from_user(mybuf, buf, nbytes)) 2871 return -EFAULT; 2872 pbuf = &mybuf[0]; 2873 2874 if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) { 2875 phba->ktime_data_samples = 0; 2876 phba->ktime_status_samples = 0; 2877 phba->ktime_seg1_total = 0; 2878 phba->ktime_seg1_max = 0; 2879 phba->ktime_seg1_min = 0xffffffff; 2880 phba->ktime_seg2_total = 0; 2881 phba->ktime_seg2_max = 0; 2882 phba->ktime_seg2_min = 0xffffffff; 2883 phba->ktime_seg3_total = 0; 2884 phba->ktime_seg3_max = 0; 2885 phba->ktime_seg3_min = 0xffffffff; 2886 phba->ktime_seg4_total = 0; 2887 phba->ktime_seg4_max = 0; 2888 phba->ktime_seg4_min = 0xffffffff; 2889 phba->ktime_seg5_total = 0; 2890 phba->ktime_seg5_max = 0; 2891 phba->ktime_seg5_min = 0xffffffff; 2892 phba->ktime_seg6_total = 0; 2893 phba->ktime_seg6_max = 0; 2894 phba->ktime_seg6_min = 0xffffffff; 2895 phba->ktime_seg7_total = 0; 2896 phba->ktime_seg7_max = 0; 2897 phba->ktime_seg7_min = 0xffffffff; 2898 phba->ktime_seg8_total = 0; 2899 phba->ktime_seg8_max = 0; 2900 phba->ktime_seg8_min = 0xffffffff; 2901 phba->ktime_seg9_total = 0; 2902 phba->ktime_seg9_max = 0; 2903 phba->ktime_seg9_min = 0xffffffff; 2904 phba->ktime_seg10_total = 0; 2905 phba->ktime_seg10_max = 0; 2906 phba->ktime_seg10_min = 0xffffffff; 2907 2908 phba->ktime_on = 1; 2909 return strlen(pbuf); 2910 } else if ((strncmp(pbuf, "off", 2911 sizeof("off") - 1) == 0)) { 2912 phba->ktime_on = 0; 2913 return strlen(pbuf); 2914 } else if ((strncmp(pbuf, "zero", 2915 sizeof("zero") - 1) == 0)) { 2916 phba->ktime_data_samples = 0; 2917 phba->ktime_status_samples = 0; 2918 phba->ktime_seg1_total = 0; 2919 phba->ktime_seg1_max = 0; 2920 phba->ktime_seg1_min = 0xffffffff; 2921 phba->ktime_seg2_total = 0; 2922 phba->ktime_seg2_max = 0; 2923 phba->ktime_seg2_min = 0xffffffff; 2924 phba->ktime_seg3_total = 0; 2925 phba->ktime_seg3_max = 0; 2926 phba->ktime_seg3_min = 0xffffffff; 2927 phba->ktime_seg4_total = 0; 2928 phba->ktime_seg4_max = 0; 2929 phba->ktime_seg4_min = 0xffffffff; 2930 phba->ktime_seg5_total = 0; 2931 phba->ktime_seg5_max = 0; 2932 phba->ktime_seg5_min = 0xffffffff; 2933 phba->ktime_seg6_total = 0; 2934 phba->ktime_seg6_max = 0; 2935 phba->ktime_seg6_min = 0xffffffff; 2936 phba->ktime_seg7_total = 0; 2937 phba->ktime_seg7_max = 0; 2938 phba->ktime_seg7_min = 0xffffffff; 2939 phba->ktime_seg8_total = 0; 2940 phba->ktime_seg8_max = 0; 2941 phba->ktime_seg8_min = 0xffffffff; 2942 phba->ktime_seg9_total = 0; 2943 phba->ktime_seg9_max = 0; 2944 phba->ktime_seg9_min = 0xffffffff; 2945 phba->ktime_seg10_total = 0; 2946 phba->ktime_seg10_max = 0; 2947 phba->ktime_seg10_min = 0xffffffff; 2948 return strlen(pbuf); 2949 } 2950 return -EINVAL; 2951 } 2952 2953 static int 2954 lpfc_debugfs_nvmeio_trc_open(struct inode *inode, struct file *file) 2955 { 2956 struct lpfc_hba *phba = inode->i_private; 2957 struct lpfc_debug *debug; 2958 int rc = -ENOMEM; 2959 2960 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 2961 if (!debug) 2962 goto out; 2963 2964 /* Round to page boundary */ 2965 debug->buffer = kmalloc(LPFC_NVMEIO_TRC_SIZE, GFP_KERNEL); 2966 if (!debug->buffer) { 2967 kfree(debug); 2968 goto out; 2969 } 2970 2971 debug->len = lpfc_debugfs_nvmeio_trc_data(phba, debug->buffer, 2972 LPFC_NVMEIO_TRC_SIZE); 2973 2974 debug->i_private = inode->i_private; 2975 file->private_data = debug; 2976 2977 rc = 0; 2978 out: 2979 return rc; 2980 } 2981 2982 static ssize_t 2983 lpfc_debugfs_nvmeio_trc_write(struct file *file, const char __user *buf, 2984 size_t nbytes, loff_t *ppos) 2985 { 2986 struct lpfc_debug *debug = file->private_data; 2987 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 2988 int i; 2989 unsigned long sz; 2990 char mybuf[64]; 2991 char *pbuf; 2992 2993 if (nbytes > sizeof(mybuf) - 1) 2994 nbytes = sizeof(mybuf) - 1; 2995 2996 memset(mybuf, 0, sizeof(mybuf)); 2997 2998 if (copy_from_user(mybuf, buf, nbytes)) 2999 return -EFAULT; 3000 pbuf = &mybuf[0]; 3001 3002 if ((strncmp(pbuf, "off", sizeof("off") - 1) == 0)) { 3003 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 3004 "0570 nvmeio_trc_off\n"); 3005 phba->nvmeio_trc_output_idx = 0; 3006 phba->nvmeio_trc_on = 0; 3007 return strlen(pbuf); 3008 } else if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) { 3009 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 3010 "0571 nvmeio_trc_on\n"); 3011 phba->nvmeio_trc_output_idx = 0; 3012 phba->nvmeio_trc_on = 1; 3013 return strlen(pbuf); 3014 } 3015 3016 /* We must be off to allocate the trace buffer */ 3017 if (phba->nvmeio_trc_on != 0) 3018 return -EINVAL; 3019 3020 /* If not on or off, the parameter is the trace buffer size */ 3021 i = kstrtoul(pbuf, 0, &sz); 3022 if (i) 3023 return -EINVAL; 3024 phba->nvmeio_trc_size = (uint32_t)sz; 3025 3026 /* It must be a power of 2 - round down */ 3027 i = 0; 3028 while (sz > 1) { 3029 sz = sz >> 1; 3030 i++; 3031 } 3032 sz = (1 << i); 3033 if (phba->nvmeio_trc_size != sz) 3034 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 3035 "0572 nvmeio_trc_size changed to %ld\n", 3036 sz); 3037 phba->nvmeio_trc_size = (uint32_t)sz; 3038 3039 /* If one previously exists, free it */ 3040 kfree(phba->nvmeio_trc); 3041 3042 /* Allocate new trace buffer and initialize */ 3043 phba->nvmeio_trc = kzalloc((sizeof(struct lpfc_debugfs_nvmeio_trc) * 3044 sz), GFP_KERNEL); 3045 if (!phba->nvmeio_trc) { 3046 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 3047 "0573 Cannot create debugfs " 3048 "nvmeio_trc buffer\n"); 3049 return -ENOMEM; 3050 } 3051 atomic_set(&phba->nvmeio_trc_cnt, 0); 3052 phba->nvmeio_trc_on = 0; 3053 phba->nvmeio_trc_output_idx = 0; 3054 3055 return strlen(pbuf); 3056 } 3057 3058 static int 3059 lpfc_debugfs_hdwqstat_open(struct inode *inode, struct file *file) 3060 { 3061 struct lpfc_vport *vport = inode->i_private; 3062 struct lpfc_debug *debug; 3063 int rc = -ENOMEM; 3064 3065 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 3066 if (!debug) 3067 goto out; 3068 3069 /* Round to page boundary */ 3070 debug->buffer = kcalloc(1, LPFC_SCSISTAT_SIZE, GFP_KERNEL); 3071 if (!debug->buffer) { 3072 kfree(debug); 3073 goto out; 3074 } 3075 3076 debug->len = lpfc_debugfs_hdwqstat_data(vport, debug->buffer, 3077 LPFC_SCSISTAT_SIZE); 3078 3079 debug->i_private = inode->i_private; 3080 file->private_data = debug; 3081 3082 rc = 0; 3083 out: 3084 return rc; 3085 } 3086 3087 static ssize_t 3088 lpfc_debugfs_hdwqstat_write(struct file *file, const char __user *buf, 3089 size_t nbytes, loff_t *ppos) 3090 { 3091 struct lpfc_debug *debug = file->private_data; 3092 struct lpfc_vport *vport = (struct lpfc_vport *)debug->i_private; 3093 struct lpfc_hba *phba = vport->phba; 3094 struct lpfc_hdwq_stat *c_stat; 3095 char mybuf[64]; 3096 char *pbuf; 3097 int i; 3098 3099 if (nbytes > sizeof(mybuf) - 1) 3100 nbytes = sizeof(mybuf) - 1; 3101 3102 memset(mybuf, 0, sizeof(mybuf)); 3103 3104 if (copy_from_user(mybuf, buf, nbytes)) 3105 return -EFAULT; 3106 pbuf = &mybuf[0]; 3107 3108 if ((strncmp(pbuf, "on", sizeof("on") - 1) == 0)) { 3109 if (phba->nvmet_support) 3110 phba->hdwqstat_on |= LPFC_CHECK_NVMET_IO; 3111 else 3112 phba->hdwqstat_on |= (LPFC_CHECK_NVME_IO | 3113 LPFC_CHECK_SCSI_IO); 3114 return strlen(pbuf); 3115 } else if ((strncmp(pbuf, "nvme_on", sizeof("nvme_on") - 1) == 0)) { 3116 if (phba->nvmet_support) 3117 phba->hdwqstat_on |= LPFC_CHECK_NVMET_IO; 3118 else 3119 phba->hdwqstat_on |= LPFC_CHECK_NVME_IO; 3120 return strlen(pbuf); 3121 } else if ((strncmp(pbuf, "scsi_on", sizeof("scsi_on") - 1) == 0)) { 3122 if (!phba->nvmet_support) 3123 phba->hdwqstat_on |= LPFC_CHECK_SCSI_IO; 3124 return strlen(pbuf); 3125 } else if ((strncmp(pbuf, "nvme_off", sizeof("nvme_off") - 1) == 0)) { 3126 phba->hdwqstat_on &= ~(LPFC_CHECK_NVME_IO | 3127 LPFC_CHECK_NVMET_IO); 3128 return strlen(pbuf); 3129 } else if ((strncmp(pbuf, "scsi_off", sizeof("scsi_off") - 1) == 0)) { 3130 phba->hdwqstat_on &= ~LPFC_CHECK_SCSI_IO; 3131 return strlen(pbuf); 3132 } else if ((strncmp(pbuf, "off", 3133 sizeof("off") - 1) == 0)) { 3134 phba->hdwqstat_on = LPFC_CHECK_OFF; 3135 return strlen(pbuf); 3136 } else if ((strncmp(pbuf, "zero", 3137 sizeof("zero") - 1) == 0)) { 3138 for_each_present_cpu(i) { 3139 c_stat = per_cpu_ptr(phba->sli4_hba.c_stat, i); 3140 c_stat->xmt_io = 0; 3141 c_stat->cmpl_io = 0; 3142 c_stat->rcv_io = 0; 3143 } 3144 return strlen(pbuf); 3145 } 3146 return -EINVAL; 3147 } 3148 3149 /* 3150 * --------------------------------- 3151 * iDiag debugfs file access methods 3152 * --------------------------------- 3153 * 3154 * All access methods are through the proper SLI4 PCI function's debugfs 3155 * iDiag directory: 3156 * 3157 * /sys/kernel/debug/lpfc/fn<#>/iDiag 3158 */ 3159 3160 /** 3161 * lpfc_idiag_cmd_get - Get and parse idiag debugfs comands from user space 3162 * @buf: The pointer to the user space buffer. 3163 * @nbytes: The number of bytes in the user space buffer. 3164 * @idiag_cmd: pointer to the idiag command struct. 3165 * 3166 * This routine reads data from debugfs user space buffer and parses the 3167 * buffer for getting the idiag command and arguments. The while space in 3168 * between the set of data is used as the parsing separator. 3169 * 3170 * This routine returns 0 when successful, it returns proper error code 3171 * back to the user space in error conditions. 3172 */ 3173 static int lpfc_idiag_cmd_get(const char __user *buf, size_t nbytes, 3174 struct lpfc_idiag_cmd *idiag_cmd) 3175 { 3176 char mybuf[64]; 3177 char *pbuf, *step_str; 3178 int i; 3179 size_t bsize; 3180 3181 memset(mybuf, 0, sizeof(mybuf)); 3182 memset(idiag_cmd, 0, sizeof(*idiag_cmd)); 3183 bsize = min(nbytes, (sizeof(mybuf)-1)); 3184 3185 if (copy_from_user(mybuf, buf, bsize)) 3186 return -EFAULT; 3187 pbuf = &mybuf[0]; 3188 step_str = strsep(&pbuf, "\t "); 3189 3190 /* The opcode must present */ 3191 if (!step_str) 3192 return -EINVAL; 3193 3194 idiag_cmd->opcode = simple_strtol(step_str, NULL, 0); 3195 if (idiag_cmd->opcode == 0) 3196 return -EINVAL; 3197 3198 for (i = 0; i < LPFC_IDIAG_CMD_DATA_SIZE; i++) { 3199 step_str = strsep(&pbuf, "\t "); 3200 if (!step_str) 3201 return i; 3202 idiag_cmd->data[i] = simple_strtol(step_str, NULL, 0); 3203 } 3204 return i; 3205 } 3206 3207 /** 3208 * lpfc_idiag_open - idiag open debugfs 3209 * @inode: The inode pointer that contains a pointer to phba. 3210 * @file: The file pointer to attach the file operation. 3211 * 3212 * Description: 3213 * This routine is the entry point for the debugfs open file operation. It 3214 * gets the reference to phba from the i_private field in @inode, it then 3215 * allocates buffer for the file operation, performs the necessary PCI config 3216 * space read into the allocated buffer according to the idiag user command 3217 * setup, and then returns a pointer to buffer in the private_data field in 3218 * @file. 3219 * 3220 * Returns: 3221 * This function returns zero if successful. On error it will return an 3222 * negative error value. 3223 **/ 3224 static int 3225 lpfc_idiag_open(struct inode *inode, struct file *file) 3226 { 3227 struct lpfc_debug *debug; 3228 3229 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 3230 if (!debug) 3231 return -ENOMEM; 3232 3233 debug->i_private = inode->i_private; 3234 debug->buffer = NULL; 3235 file->private_data = debug; 3236 3237 return 0; 3238 } 3239 3240 /** 3241 * lpfc_idiag_release - Release idiag access file operation 3242 * @inode: The inode pointer that contains a vport pointer. (unused) 3243 * @file: The file pointer that contains the buffer to release. 3244 * 3245 * Description: 3246 * This routine is the generic release routine for the idiag access file 3247 * operation, it frees the buffer that was allocated when the debugfs file 3248 * was opened. 3249 * 3250 * Returns: 3251 * This function returns zero. 3252 **/ 3253 static int 3254 lpfc_idiag_release(struct inode *inode, struct file *file) 3255 { 3256 struct lpfc_debug *debug = file->private_data; 3257 3258 /* Free the buffers to the file operation */ 3259 kfree(debug->buffer); 3260 kfree(debug); 3261 3262 return 0; 3263 } 3264 3265 /** 3266 * lpfc_idiag_cmd_release - Release idiag cmd access file operation 3267 * @inode: The inode pointer that contains a vport pointer. (unused) 3268 * @file: The file pointer that contains the buffer to release. 3269 * 3270 * Description: 3271 * This routine frees the buffer that was allocated when the debugfs file 3272 * was opened. It also reset the fields in the idiag command struct in the 3273 * case of command for write operation. 3274 * 3275 * Returns: 3276 * This function returns zero. 3277 **/ 3278 static int 3279 lpfc_idiag_cmd_release(struct inode *inode, struct file *file) 3280 { 3281 struct lpfc_debug *debug = file->private_data; 3282 3283 if (debug->op == LPFC_IDIAG_OP_WR) { 3284 switch (idiag.cmd.opcode) { 3285 case LPFC_IDIAG_CMD_PCICFG_WR: 3286 case LPFC_IDIAG_CMD_PCICFG_ST: 3287 case LPFC_IDIAG_CMD_PCICFG_CL: 3288 case LPFC_IDIAG_CMD_QUEACC_WR: 3289 case LPFC_IDIAG_CMD_QUEACC_ST: 3290 case LPFC_IDIAG_CMD_QUEACC_CL: 3291 memset(&idiag, 0, sizeof(idiag)); 3292 break; 3293 default: 3294 break; 3295 } 3296 } 3297 3298 /* Free the buffers to the file operation */ 3299 kfree(debug->buffer); 3300 kfree(debug); 3301 3302 return 0; 3303 } 3304 3305 /** 3306 * lpfc_idiag_pcicfg_read - idiag debugfs read pcicfg 3307 * @file: The file pointer to read from. 3308 * @buf: The buffer to copy the data to. 3309 * @nbytes: The number of bytes to read. 3310 * @ppos: The position in the file to start reading from. 3311 * 3312 * Description: 3313 * This routine reads data from the @phba pci config space according to the 3314 * idiag command, and copies to user @buf. Depending on the PCI config space 3315 * read command setup, it does either a single register read of a byte 3316 * (8 bits), a word (16 bits), or a dword (32 bits) or browsing through all 3317 * registers from the 4K extended PCI config space. 3318 * 3319 * Returns: 3320 * This function returns the amount of data that was read (this could be less 3321 * than @nbytes if the end of the file was reached) or a negative error value. 3322 **/ 3323 static ssize_t 3324 lpfc_idiag_pcicfg_read(struct file *file, char __user *buf, size_t nbytes, 3325 loff_t *ppos) 3326 { 3327 struct lpfc_debug *debug = file->private_data; 3328 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 3329 int offset_label, offset, len = 0, index = LPFC_PCI_CFG_RD_SIZE; 3330 int where, count; 3331 char *pbuffer; 3332 struct pci_dev *pdev; 3333 uint32_t u32val; 3334 uint16_t u16val; 3335 uint8_t u8val; 3336 3337 pdev = phba->pcidev; 3338 if (!pdev) 3339 return 0; 3340 3341 /* This is a user read operation */ 3342 debug->op = LPFC_IDIAG_OP_RD; 3343 3344 if (!debug->buffer) 3345 debug->buffer = kmalloc(LPFC_PCI_CFG_SIZE, GFP_KERNEL); 3346 if (!debug->buffer) 3347 return 0; 3348 pbuffer = debug->buffer; 3349 3350 if (*ppos) 3351 return 0; 3352 3353 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) { 3354 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX]; 3355 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX]; 3356 } else 3357 return 0; 3358 3359 /* Read single PCI config space register */ 3360 switch (count) { 3361 case SIZE_U8: /* byte (8 bits) */ 3362 pci_read_config_byte(pdev, where, &u8val); 3363 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, 3364 "%03x: %02x\n", where, u8val); 3365 break; 3366 case SIZE_U16: /* word (16 bits) */ 3367 pci_read_config_word(pdev, where, &u16val); 3368 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, 3369 "%03x: %04x\n", where, u16val); 3370 break; 3371 case SIZE_U32: /* double word (32 bits) */ 3372 pci_read_config_dword(pdev, where, &u32val); 3373 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, 3374 "%03x: %08x\n", where, u32val); 3375 break; 3376 case LPFC_PCI_CFG_BROWSE: /* browse all */ 3377 goto pcicfg_browse; 3378 default: 3379 /* illegal count */ 3380 len = 0; 3381 break; 3382 } 3383 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 3384 3385 pcicfg_browse: 3386 3387 /* Browse all PCI config space registers */ 3388 offset_label = idiag.offset.last_rd; 3389 offset = offset_label; 3390 3391 /* Read PCI config space */ 3392 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, 3393 "%03x: ", offset_label); 3394 while (index > 0) { 3395 pci_read_config_dword(pdev, offset, &u32val); 3396 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, 3397 "%08x ", u32val); 3398 offset += sizeof(uint32_t); 3399 if (offset >= LPFC_PCI_CFG_SIZE) { 3400 len += scnprintf(pbuffer+len, 3401 LPFC_PCI_CFG_SIZE-len, "\n"); 3402 break; 3403 } 3404 index -= sizeof(uint32_t); 3405 if (!index) 3406 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, 3407 "\n"); 3408 else if (!(index % (8 * sizeof(uint32_t)))) { 3409 offset_label += (8 * sizeof(uint32_t)); 3410 len += scnprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, 3411 "\n%03x: ", offset_label); 3412 } 3413 } 3414 3415 /* Set up the offset for next portion of pci cfg read */ 3416 if (index == 0) { 3417 idiag.offset.last_rd += LPFC_PCI_CFG_RD_SIZE; 3418 if (idiag.offset.last_rd >= LPFC_PCI_CFG_SIZE) 3419 idiag.offset.last_rd = 0; 3420 } else 3421 idiag.offset.last_rd = 0; 3422 3423 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 3424 } 3425 3426 /** 3427 * lpfc_idiag_pcicfg_write - Syntax check and set up idiag pcicfg commands 3428 * @file: The file pointer to read from. 3429 * @buf: The buffer to copy the user data from. 3430 * @nbytes: The number of bytes to get. 3431 * @ppos: The position in the file to start reading from. 3432 * 3433 * This routine get the debugfs idiag command struct from user space and 3434 * then perform the syntax check for PCI config space read or write command 3435 * accordingly. In the case of PCI config space read command, it sets up 3436 * the command in the idiag command struct for the debugfs read operation. 3437 * In the case of PCI config space write operation, it executes the write 3438 * operation into the PCI config space accordingly. 3439 * 3440 * It returns the @nbytges passing in from debugfs user space when successful. 3441 * In case of error conditions, it returns proper error code back to the user 3442 * space. 3443 */ 3444 static ssize_t 3445 lpfc_idiag_pcicfg_write(struct file *file, const char __user *buf, 3446 size_t nbytes, loff_t *ppos) 3447 { 3448 struct lpfc_debug *debug = file->private_data; 3449 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 3450 uint32_t where, value, count; 3451 uint32_t u32val; 3452 uint16_t u16val; 3453 uint8_t u8val; 3454 struct pci_dev *pdev; 3455 int rc; 3456 3457 pdev = phba->pcidev; 3458 if (!pdev) 3459 return -EFAULT; 3460 3461 /* This is a user write operation */ 3462 debug->op = LPFC_IDIAG_OP_WR; 3463 3464 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd); 3465 if (rc < 0) 3466 return rc; 3467 3468 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) { 3469 /* Sanity check on PCI config read command line arguments */ 3470 if (rc != LPFC_PCI_CFG_RD_CMD_ARG) 3471 goto error_out; 3472 /* Read command from PCI config space, set up command fields */ 3473 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX]; 3474 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX]; 3475 if (count == LPFC_PCI_CFG_BROWSE) { 3476 if (where % sizeof(uint32_t)) 3477 goto error_out; 3478 /* Starting offset to browse */ 3479 idiag.offset.last_rd = where; 3480 } else if ((count != sizeof(uint8_t)) && 3481 (count != sizeof(uint16_t)) && 3482 (count != sizeof(uint32_t))) 3483 goto error_out; 3484 if (count == sizeof(uint8_t)) { 3485 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t)) 3486 goto error_out; 3487 if (where % sizeof(uint8_t)) 3488 goto error_out; 3489 } 3490 if (count == sizeof(uint16_t)) { 3491 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t)) 3492 goto error_out; 3493 if (where % sizeof(uint16_t)) 3494 goto error_out; 3495 } 3496 if (count == sizeof(uint32_t)) { 3497 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t)) 3498 goto error_out; 3499 if (where % sizeof(uint32_t)) 3500 goto error_out; 3501 } 3502 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR || 3503 idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST || 3504 idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) { 3505 /* Sanity check on PCI config write command line arguments */ 3506 if (rc != LPFC_PCI_CFG_WR_CMD_ARG) 3507 goto error_out; 3508 /* Write command to PCI config space, read-modify-write */ 3509 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX]; 3510 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX]; 3511 value = idiag.cmd.data[IDIAG_PCICFG_VALUE_INDX]; 3512 /* Sanity checks */ 3513 if ((count != sizeof(uint8_t)) && 3514 (count != sizeof(uint16_t)) && 3515 (count != sizeof(uint32_t))) 3516 goto error_out; 3517 if (count == sizeof(uint8_t)) { 3518 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint8_t)) 3519 goto error_out; 3520 if (where % sizeof(uint8_t)) 3521 goto error_out; 3522 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR) 3523 pci_write_config_byte(pdev, where, 3524 (uint8_t)value); 3525 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) { 3526 rc = pci_read_config_byte(pdev, where, &u8val); 3527 if (!rc) { 3528 u8val |= (uint8_t)value; 3529 pci_write_config_byte(pdev, where, 3530 u8val); 3531 } 3532 } 3533 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) { 3534 rc = pci_read_config_byte(pdev, where, &u8val); 3535 if (!rc) { 3536 u8val &= (uint8_t)(~value); 3537 pci_write_config_byte(pdev, where, 3538 u8val); 3539 } 3540 } 3541 } 3542 if (count == sizeof(uint16_t)) { 3543 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint16_t)) 3544 goto error_out; 3545 if (where % sizeof(uint16_t)) 3546 goto error_out; 3547 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR) 3548 pci_write_config_word(pdev, where, 3549 (uint16_t)value); 3550 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) { 3551 rc = pci_read_config_word(pdev, where, &u16val); 3552 if (!rc) { 3553 u16val |= (uint16_t)value; 3554 pci_write_config_word(pdev, where, 3555 u16val); 3556 } 3557 } 3558 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) { 3559 rc = pci_read_config_word(pdev, where, &u16val); 3560 if (!rc) { 3561 u16val &= (uint16_t)(~value); 3562 pci_write_config_word(pdev, where, 3563 u16val); 3564 } 3565 } 3566 } 3567 if (count == sizeof(uint32_t)) { 3568 if (where > LPFC_PCI_CFG_SIZE - sizeof(uint32_t)) 3569 goto error_out; 3570 if (where % sizeof(uint32_t)) 3571 goto error_out; 3572 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR) 3573 pci_write_config_dword(pdev, where, value); 3574 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST) { 3575 rc = pci_read_config_dword(pdev, where, 3576 &u32val); 3577 if (!rc) { 3578 u32val |= value; 3579 pci_write_config_dword(pdev, where, 3580 u32val); 3581 } 3582 } 3583 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) { 3584 rc = pci_read_config_dword(pdev, where, 3585 &u32val); 3586 if (!rc) { 3587 u32val &= ~value; 3588 pci_write_config_dword(pdev, where, 3589 u32val); 3590 } 3591 } 3592 } 3593 } else 3594 /* All other opecodes are illegal for now */ 3595 goto error_out; 3596 3597 return nbytes; 3598 error_out: 3599 memset(&idiag, 0, sizeof(idiag)); 3600 return -EINVAL; 3601 } 3602 3603 /** 3604 * lpfc_idiag_baracc_read - idiag debugfs pci bar access read 3605 * @file: The file pointer to read from. 3606 * @buf: The buffer to copy the data to. 3607 * @nbytes: The number of bytes to read. 3608 * @ppos: The position in the file to start reading from. 3609 * 3610 * Description: 3611 * This routine reads data from the @phba pci bar memory mapped space 3612 * according to the idiag command, and copies to user @buf. 3613 * 3614 * Returns: 3615 * This function returns the amount of data that was read (this could be less 3616 * than @nbytes if the end of the file was reached) or a negative error value. 3617 **/ 3618 static ssize_t 3619 lpfc_idiag_baracc_read(struct file *file, char __user *buf, size_t nbytes, 3620 loff_t *ppos) 3621 { 3622 struct lpfc_debug *debug = file->private_data; 3623 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 3624 int offset_label, offset, offset_run, len = 0, index; 3625 int bar_num, acc_range, bar_size; 3626 char *pbuffer; 3627 void __iomem *mem_mapped_bar; 3628 uint32_t if_type; 3629 struct pci_dev *pdev; 3630 uint32_t u32val; 3631 3632 pdev = phba->pcidev; 3633 if (!pdev) 3634 return 0; 3635 3636 /* This is a user read operation */ 3637 debug->op = LPFC_IDIAG_OP_RD; 3638 3639 if (!debug->buffer) 3640 debug->buffer = kmalloc(LPFC_PCI_BAR_RD_BUF_SIZE, GFP_KERNEL); 3641 if (!debug->buffer) 3642 return 0; 3643 pbuffer = debug->buffer; 3644 3645 if (*ppos) 3646 return 0; 3647 3648 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) { 3649 bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX]; 3650 offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX]; 3651 acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX]; 3652 bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX]; 3653 } else 3654 return 0; 3655 3656 if (acc_range == 0) 3657 return 0; 3658 3659 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); 3660 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) { 3661 if (bar_num == IDIAG_BARACC_BAR_0) 3662 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p; 3663 else if (bar_num == IDIAG_BARACC_BAR_1) 3664 mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p; 3665 else if (bar_num == IDIAG_BARACC_BAR_2) 3666 mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p; 3667 else 3668 return 0; 3669 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) { 3670 if (bar_num == IDIAG_BARACC_BAR_0) 3671 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p; 3672 else 3673 return 0; 3674 } else 3675 return 0; 3676 3677 /* Read single PCI bar space register */ 3678 if (acc_range == SINGLE_WORD) { 3679 offset_run = offset; 3680 u32val = readl(mem_mapped_bar + offset_run); 3681 len += scnprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len, 3682 "%05x: %08x\n", offset_run, u32val); 3683 } else 3684 goto baracc_browse; 3685 3686 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 3687 3688 baracc_browse: 3689 3690 /* Browse all PCI bar space registers */ 3691 offset_label = idiag.offset.last_rd; 3692 offset_run = offset_label; 3693 3694 /* Read PCI bar memory mapped space */ 3695 len += scnprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len, 3696 "%05x: ", offset_label); 3697 index = LPFC_PCI_BAR_RD_SIZE; 3698 while (index > 0) { 3699 u32val = readl(mem_mapped_bar + offset_run); 3700 len += scnprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len, 3701 "%08x ", u32val); 3702 offset_run += sizeof(uint32_t); 3703 if (acc_range == LPFC_PCI_BAR_BROWSE) { 3704 if (offset_run >= bar_size) { 3705 len += scnprintf(pbuffer+len, 3706 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n"); 3707 break; 3708 } 3709 } else { 3710 if (offset_run >= offset + 3711 (acc_range * sizeof(uint32_t))) { 3712 len += scnprintf(pbuffer+len, 3713 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n"); 3714 break; 3715 } 3716 } 3717 index -= sizeof(uint32_t); 3718 if (!index) 3719 len += scnprintf(pbuffer+len, 3720 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n"); 3721 else if (!(index % (8 * sizeof(uint32_t)))) { 3722 offset_label += (8 * sizeof(uint32_t)); 3723 len += scnprintf(pbuffer+len, 3724 LPFC_PCI_BAR_RD_BUF_SIZE-len, 3725 "\n%05x: ", offset_label); 3726 } 3727 } 3728 3729 /* Set up the offset for next portion of pci bar read */ 3730 if (index == 0) { 3731 idiag.offset.last_rd += LPFC_PCI_BAR_RD_SIZE; 3732 if (acc_range == LPFC_PCI_BAR_BROWSE) { 3733 if (idiag.offset.last_rd >= bar_size) 3734 idiag.offset.last_rd = 0; 3735 } else { 3736 if (offset_run >= offset + 3737 (acc_range * sizeof(uint32_t))) 3738 idiag.offset.last_rd = offset; 3739 } 3740 } else { 3741 if (acc_range == LPFC_PCI_BAR_BROWSE) 3742 idiag.offset.last_rd = 0; 3743 else 3744 idiag.offset.last_rd = offset; 3745 } 3746 3747 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 3748 } 3749 3750 /** 3751 * lpfc_idiag_baracc_write - Syntax check and set up idiag bar access commands 3752 * @file: The file pointer to read from. 3753 * @buf: The buffer to copy the user data from. 3754 * @nbytes: The number of bytes to get. 3755 * @ppos: The position in the file to start reading from. 3756 * 3757 * This routine get the debugfs idiag command struct from user space and 3758 * then perform the syntax check for PCI bar memory mapped space read or 3759 * write command accordingly. In the case of PCI bar memory mapped space 3760 * read command, it sets up the command in the idiag command struct for 3761 * the debugfs read operation. In the case of PCI bar memorpy mapped space 3762 * write operation, it executes the write operation into the PCI bar memory 3763 * mapped space accordingly. 3764 * 3765 * It returns the @nbytges passing in from debugfs user space when successful. 3766 * In case of error conditions, it returns proper error code back to the user 3767 * space. 3768 */ 3769 static ssize_t 3770 lpfc_idiag_baracc_write(struct file *file, const char __user *buf, 3771 size_t nbytes, loff_t *ppos) 3772 { 3773 struct lpfc_debug *debug = file->private_data; 3774 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 3775 uint32_t bar_num, bar_size, offset, value, acc_range; 3776 struct pci_dev *pdev; 3777 void __iomem *mem_mapped_bar; 3778 uint32_t if_type; 3779 uint32_t u32val; 3780 int rc; 3781 3782 pdev = phba->pcidev; 3783 if (!pdev) 3784 return -EFAULT; 3785 3786 /* This is a user write operation */ 3787 debug->op = LPFC_IDIAG_OP_WR; 3788 3789 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd); 3790 if (rc < 0) 3791 return rc; 3792 3793 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); 3794 bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX]; 3795 3796 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) { 3797 if ((bar_num != IDIAG_BARACC_BAR_0) && 3798 (bar_num != IDIAG_BARACC_BAR_1) && 3799 (bar_num != IDIAG_BARACC_BAR_2)) 3800 goto error_out; 3801 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) { 3802 if (bar_num != IDIAG_BARACC_BAR_0) 3803 goto error_out; 3804 } else 3805 goto error_out; 3806 3807 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) { 3808 if (bar_num == IDIAG_BARACC_BAR_0) { 3809 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] = 3810 LPFC_PCI_IF0_BAR0_SIZE; 3811 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p; 3812 } else if (bar_num == IDIAG_BARACC_BAR_1) { 3813 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] = 3814 LPFC_PCI_IF0_BAR1_SIZE; 3815 mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p; 3816 } else if (bar_num == IDIAG_BARACC_BAR_2) { 3817 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] = 3818 LPFC_PCI_IF0_BAR2_SIZE; 3819 mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p; 3820 } else 3821 goto error_out; 3822 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) { 3823 if (bar_num == IDIAG_BARACC_BAR_0) { 3824 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] = 3825 LPFC_PCI_IF2_BAR0_SIZE; 3826 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p; 3827 } else 3828 goto error_out; 3829 } else 3830 goto error_out; 3831 3832 offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX]; 3833 if (offset % sizeof(uint32_t)) 3834 goto error_out; 3835 3836 bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX]; 3837 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) { 3838 /* Sanity check on PCI config read command line arguments */ 3839 if (rc != LPFC_PCI_BAR_RD_CMD_ARG) 3840 goto error_out; 3841 acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX]; 3842 if (acc_range == LPFC_PCI_BAR_BROWSE) { 3843 if (offset > bar_size - sizeof(uint32_t)) 3844 goto error_out; 3845 /* Starting offset to browse */ 3846 idiag.offset.last_rd = offset; 3847 } else if (acc_range > SINGLE_WORD) { 3848 if (offset + acc_range * sizeof(uint32_t) > bar_size) 3849 goto error_out; 3850 /* Starting offset to browse */ 3851 idiag.offset.last_rd = offset; 3852 } else if (acc_range != SINGLE_WORD) 3853 goto error_out; 3854 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR || 3855 idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST || 3856 idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) { 3857 /* Sanity check on PCI bar write command line arguments */ 3858 if (rc != LPFC_PCI_BAR_WR_CMD_ARG) 3859 goto error_out; 3860 /* Write command to PCI bar space, read-modify-write */ 3861 acc_range = SINGLE_WORD; 3862 value = idiag.cmd.data[IDIAG_BARACC_REG_VAL_INDX]; 3863 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR) { 3864 writel(value, mem_mapped_bar + offset); 3865 readl(mem_mapped_bar + offset); 3866 } 3867 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST) { 3868 u32val = readl(mem_mapped_bar + offset); 3869 u32val |= value; 3870 writel(u32val, mem_mapped_bar + offset); 3871 readl(mem_mapped_bar + offset); 3872 } 3873 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) { 3874 u32val = readl(mem_mapped_bar + offset); 3875 u32val &= ~value; 3876 writel(u32val, mem_mapped_bar + offset); 3877 readl(mem_mapped_bar + offset); 3878 } 3879 } else 3880 /* All other opecodes are illegal for now */ 3881 goto error_out; 3882 3883 return nbytes; 3884 error_out: 3885 memset(&idiag, 0, sizeof(idiag)); 3886 return -EINVAL; 3887 } 3888 3889 static int 3890 __lpfc_idiag_print_wq(struct lpfc_queue *qp, char *wqtype, 3891 char *pbuffer, int len) 3892 { 3893 if (!qp) 3894 return len; 3895 3896 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 3897 "\t\t%s WQ info: ", wqtype); 3898 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 3899 "AssocCQID[%04d]: WQ-STAT[oflow:x%x posted:x%llx]\n", 3900 qp->assoc_qid, qp->q_cnt_1, 3901 (unsigned long long)qp->q_cnt_4); 3902 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 3903 "\t\tWQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " 3904 "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]", 3905 qp->queue_id, qp->entry_count, 3906 qp->entry_size, qp->host_index, 3907 qp->hba_index, qp->notify_interval); 3908 len += scnprintf(pbuffer + len, 3909 LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n"); 3910 return len; 3911 } 3912 3913 static int 3914 lpfc_idiag_wqs_for_cq(struct lpfc_hba *phba, char *wqtype, char *pbuffer, 3915 int *len, int max_cnt, int cq_id) 3916 { 3917 struct lpfc_queue *qp; 3918 int qidx; 3919 3920 for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { 3921 qp = phba->sli4_hba.hdwq[qidx].io_wq; 3922 if (qp->assoc_qid != cq_id) 3923 continue; 3924 *len = __lpfc_idiag_print_wq(qp, wqtype, pbuffer, *len); 3925 if (*len >= max_cnt) 3926 return 1; 3927 } 3928 return 0; 3929 } 3930 3931 static int 3932 __lpfc_idiag_print_cq(struct lpfc_queue *qp, char *cqtype, 3933 char *pbuffer, int len) 3934 { 3935 if (!qp) 3936 return len; 3937 3938 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 3939 "\t%s CQ info: ", cqtype); 3940 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 3941 "AssocEQID[%02d]: CQ STAT[max:x%x relw:x%x " 3942 "xabt:x%x wq:x%llx]\n", 3943 qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2, 3944 qp->q_cnt_3, (unsigned long long)qp->q_cnt_4); 3945 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 3946 "\tCQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " 3947 "HST-IDX[%04d], NTFI[%03d], PLMT[%03d]", 3948 qp->queue_id, qp->entry_count, 3949 qp->entry_size, qp->host_index, 3950 qp->notify_interval, qp->max_proc_limit); 3951 3952 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 3953 "\n"); 3954 3955 return len; 3956 } 3957 3958 static int 3959 __lpfc_idiag_print_rqpair(struct lpfc_queue *qp, struct lpfc_queue *datqp, 3960 char *rqtype, char *pbuffer, int len) 3961 { 3962 if (!qp || !datqp) 3963 return len; 3964 3965 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 3966 "\t\t%s RQ info: ", rqtype); 3967 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 3968 "AssocCQID[%02d]: RQ-STAT[nopost:x%x nobuf:x%x " 3969 "posted:x%x rcv:x%llx]\n", 3970 qp->assoc_qid, qp->q_cnt_1, qp->q_cnt_2, 3971 qp->q_cnt_3, (unsigned long long)qp->q_cnt_4); 3972 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 3973 "\t\tHQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " 3974 "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n", 3975 qp->queue_id, qp->entry_count, qp->entry_size, 3976 qp->host_index, qp->hba_index, qp->notify_interval); 3977 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 3978 "\t\tDQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " 3979 "HST-IDX[%04d], PRT-IDX[%04d], NTFI[%03d]\n", 3980 datqp->queue_id, datqp->entry_count, 3981 datqp->entry_size, datqp->host_index, 3982 datqp->hba_index, datqp->notify_interval); 3983 return len; 3984 } 3985 3986 static int 3987 lpfc_idiag_cqs_for_eq(struct lpfc_hba *phba, char *pbuffer, 3988 int *len, int max_cnt, int eqidx, int eq_id) 3989 { 3990 struct lpfc_queue *qp; 3991 int rc; 3992 3993 qp = phba->sli4_hba.hdwq[eqidx].io_cq; 3994 3995 *len = __lpfc_idiag_print_cq(qp, "IO", pbuffer, *len); 3996 3997 /* Reset max counter */ 3998 qp->CQ_max_cqe = 0; 3999 4000 if (*len >= max_cnt) 4001 return 1; 4002 4003 rc = lpfc_idiag_wqs_for_cq(phba, "IO", pbuffer, len, 4004 max_cnt, qp->queue_id); 4005 if (rc) 4006 return 1; 4007 4008 if ((eqidx < phba->cfg_nvmet_mrq) && phba->nvmet_support) { 4009 /* NVMET CQset */ 4010 qp = phba->sli4_hba.nvmet_cqset[eqidx]; 4011 *len = __lpfc_idiag_print_cq(qp, "NVMET CQset", pbuffer, *len); 4012 4013 /* Reset max counter */ 4014 qp->CQ_max_cqe = 0; 4015 4016 if (*len >= max_cnt) 4017 return 1; 4018 4019 /* RQ header */ 4020 qp = phba->sli4_hba.nvmet_mrq_hdr[eqidx]; 4021 *len = __lpfc_idiag_print_rqpair(qp, 4022 phba->sli4_hba.nvmet_mrq_data[eqidx], 4023 "NVMET MRQ", pbuffer, *len); 4024 4025 if (*len >= max_cnt) 4026 return 1; 4027 } 4028 4029 return 0; 4030 } 4031 4032 static int 4033 __lpfc_idiag_print_eq(struct lpfc_queue *qp, char *eqtype, 4034 char *pbuffer, int len) 4035 { 4036 if (!qp) 4037 return len; 4038 4039 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 4040 "\n%s EQ info: EQ-STAT[max:x%x noE:x%x " 4041 "cqe_proc:x%x eqe_proc:x%llx eqd %d]\n", 4042 eqtype, qp->q_cnt_1, qp->q_cnt_2, qp->q_cnt_3, 4043 (unsigned long long)qp->q_cnt_4, qp->q_mode); 4044 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 4045 "EQID[%02d], QE-CNT[%04d], QE-SZ[%04d], " 4046 "HST-IDX[%04d], NTFI[%03d], PLMT[%03d], AFFIN[%03d]", 4047 qp->queue_id, qp->entry_count, qp->entry_size, 4048 qp->host_index, qp->notify_interval, 4049 qp->max_proc_limit, qp->chann); 4050 len += scnprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, 4051 "\n"); 4052 4053 return len; 4054 } 4055 4056 /** 4057 * lpfc_idiag_queinfo_read - idiag debugfs read queue information 4058 * @file: The file pointer to read from. 4059 * @buf: The buffer to copy the data to. 4060 * @nbytes: The number of bytes to read. 4061 * @ppos: The position in the file to start reading from. 4062 * 4063 * Description: 4064 * This routine reads data from the @phba SLI4 PCI function queue information, 4065 * and copies to user @buf. 4066 * This routine only returns 1 EQs worth of information. It remembers the last 4067 * EQ read and jumps to the next EQ. Thus subsequent calls to queInfo will 4068 * retrieve all EQs allocated for the phba. 4069 * 4070 * Returns: 4071 * This function returns the amount of data that was read (this could be less 4072 * than @nbytes if the end of the file was reached) or a negative error value. 4073 **/ 4074 static ssize_t 4075 lpfc_idiag_queinfo_read(struct file *file, char __user *buf, size_t nbytes, 4076 loff_t *ppos) 4077 { 4078 struct lpfc_debug *debug = file->private_data; 4079 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 4080 char *pbuffer; 4081 int max_cnt, rc, x, len = 0; 4082 struct lpfc_queue *qp = NULL; 4083 4084 if (!debug->buffer) 4085 debug->buffer = kmalloc(LPFC_QUE_INFO_GET_BUF_SIZE, GFP_KERNEL); 4086 if (!debug->buffer) 4087 return 0; 4088 pbuffer = debug->buffer; 4089 max_cnt = LPFC_QUE_INFO_GET_BUF_SIZE - 256; 4090 4091 if (*ppos) 4092 return 0; 4093 4094 spin_lock_irq(&phba->hbalock); 4095 4096 /* Fast-path event queue */ 4097 if (phba->sli4_hba.hdwq && phba->cfg_hdw_queue) { 4098 4099 x = phba->lpfc_idiag_last_eq; 4100 phba->lpfc_idiag_last_eq++; 4101 if (phba->lpfc_idiag_last_eq >= phba->cfg_hdw_queue) 4102 phba->lpfc_idiag_last_eq = 0; 4103 4104 len += scnprintf(pbuffer + len, 4105 LPFC_QUE_INFO_GET_BUF_SIZE - len, 4106 "HDWQ %d out of %d HBA HDWQs\n", 4107 x, phba->cfg_hdw_queue); 4108 4109 /* Fast-path EQ */ 4110 qp = phba->sli4_hba.hdwq[x].hba_eq; 4111 if (!qp) 4112 goto out; 4113 4114 len = __lpfc_idiag_print_eq(qp, "HBA", pbuffer, len); 4115 4116 /* Reset max counter */ 4117 qp->EQ_max_eqe = 0; 4118 4119 if (len >= max_cnt) 4120 goto too_big; 4121 4122 /* will dump both fcp and nvme cqs/wqs for the eq */ 4123 rc = lpfc_idiag_cqs_for_eq(phba, pbuffer, &len, 4124 max_cnt, x, qp->queue_id); 4125 if (rc) 4126 goto too_big; 4127 4128 /* Only EQ 0 has slow path CQs configured */ 4129 if (x) 4130 goto out; 4131 4132 /* Slow-path mailbox CQ */ 4133 qp = phba->sli4_hba.mbx_cq; 4134 len = __lpfc_idiag_print_cq(qp, "MBX", pbuffer, len); 4135 if (len >= max_cnt) 4136 goto too_big; 4137 4138 /* Slow-path MBOX MQ */ 4139 qp = phba->sli4_hba.mbx_wq; 4140 len = __lpfc_idiag_print_wq(qp, "MBX", pbuffer, len); 4141 if (len >= max_cnt) 4142 goto too_big; 4143 4144 /* Slow-path ELS response CQ */ 4145 qp = phba->sli4_hba.els_cq; 4146 len = __lpfc_idiag_print_cq(qp, "ELS", pbuffer, len); 4147 /* Reset max counter */ 4148 if (qp) 4149 qp->CQ_max_cqe = 0; 4150 if (len >= max_cnt) 4151 goto too_big; 4152 4153 /* Slow-path ELS WQ */ 4154 qp = phba->sli4_hba.els_wq; 4155 len = __lpfc_idiag_print_wq(qp, "ELS", pbuffer, len); 4156 if (len >= max_cnt) 4157 goto too_big; 4158 4159 qp = phba->sli4_hba.hdr_rq; 4160 len = __lpfc_idiag_print_rqpair(qp, phba->sli4_hba.dat_rq, 4161 "ELS RQpair", pbuffer, len); 4162 if (len >= max_cnt) 4163 goto too_big; 4164 4165 /* Slow-path NVME LS response CQ */ 4166 qp = phba->sli4_hba.nvmels_cq; 4167 len = __lpfc_idiag_print_cq(qp, "NVME LS", 4168 pbuffer, len); 4169 /* Reset max counter */ 4170 if (qp) 4171 qp->CQ_max_cqe = 0; 4172 if (len >= max_cnt) 4173 goto too_big; 4174 4175 /* Slow-path NVME LS WQ */ 4176 qp = phba->sli4_hba.nvmels_wq; 4177 len = __lpfc_idiag_print_wq(qp, "NVME LS", 4178 pbuffer, len); 4179 if (len >= max_cnt) 4180 goto too_big; 4181 4182 goto out; 4183 } 4184 4185 spin_unlock_irq(&phba->hbalock); 4186 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 4187 4188 too_big: 4189 len += scnprintf(pbuffer + len, 4190 LPFC_QUE_INFO_GET_BUF_SIZE - len, "Truncated ...\n"); 4191 out: 4192 spin_unlock_irq(&phba->hbalock); 4193 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 4194 } 4195 4196 /** 4197 * lpfc_idiag_que_param_check - queue access command parameter sanity check 4198 * @q: The pointer to queue structure. 4199 * @index: The index into a queue entry. 4200 * @count: The number of queue entries to access. 4201 * 4202 * Description: 4203 * The routine performs sanity check on device queue access method commands. 4204 * 4205 * Returns: 4206 * This function returns -EINVAL when fails the sanity check, otherwise, it 4207 * returns 0. 4208 **/ 4209 static int 4210 lpfc_idiag_que_param_check(struct lpfc_queue *q, int index, int count) 4211 { 4212 /* Only support single entry read or browsing */ 4213 if ((count != 1) && (count != LPFC_QUE_ACC_BROWSE)) 4214 return -EINVAL; 4215 if (index > q->entry_count - 1) 4216 return -EINVAL; 4217 return 0; 4218 } 4219 4220 /** 4221 * lpfc_idiag_queacc_read_qe - read a single entry from the given queue index 4222 * @pbuffer: The pointer to buffer to copy the read data into. 4223 * @len: Length of the buffer. 4224 * @pque: The pointer to the queue to be read. 4225 * @index: The index into the queue entry. 4226 * 4227 * Description: 4228 * This routine reads out a single entry from the given queue's index location 4229 * and copies it into the buffer provided. 4230 * 4231 * Returns: 4232 * This function returns 0 when it fails, otherwise, it returns the length of 4233 * the data read into the buffer provided. 4234 **/ 4235 static int 4236 lpfc_idiag_queacc_read_qe(char *pbuffer, int len, struct lpfc_queue *pque, 4237 uint32_t index) 4238 { 4239 int offset, esize; 4240 uint32_t *pentry; 4241 4242 if (!pbuffer || !pque) 4243 return 0; 4244 4245 esize = pque->entry_size; 4246 len += scnprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, 4247 "QE-INDEX[%04d]:\n", index); 4248 4249 offset = 0; 4250 pentry = lpfc_sli4_qe(pque, index); 4251 while (esize > 0) { 4252 len += scnprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, 4253 "%08x ", *pentry); 4254 pentry++; 4255 offset += sizeof(uint32_t); 4256 esize -= sizeof(uint32_t); 4257 if (esize > 0 && !(offset % (4 * sizeof(uint32_t)))) 4258 len += scnprintf(pbuffer+len, 4259 LPFC_QUE_ACC_BUF_SIZE-len, "\n"); 4260 } 4261 len += scnprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, "\n"); 4262 4263 return len; 4264 } 4265 4266 /** 4267 * lpfc_idiag_queacc_read - idiag debugfs read port queue 4268 * @file: The file pointer to read from. 4269 * @buf: The buffer to copy the data to. 4270 * @nbytes: The number of bytes to read. 4271 * @ppos: The position in the file to start reading from. 4272 * 4273 * Description: 4274 * This routine reads data from the @phba device queue memory according to the 4275 * idiag command, and copies to user @buf. Depending on the queue dump read 4276 * command setup, it does either a single queue entry read or browing through 4277 * all entries of the queue. 4278 * 4279 * Returns: 4280 * This function returns the amount of data that was read (this could be less 4281 * than @nbytes if the end of the file was reached) or a negative error value. 4282 **/ 4283 static ssize_t 4284 lpfc_idiag_queacc_read(struct file *file, char __user *buf, size_t nbytes, 4285 loff_t *ppos) 4286 { 4287 struct lpfc_debug *debug = file->private_data; 4288 uint32_t last_index, index, count; 4289 struct lpfc_queue *pque = NULL; 4290 char *pbuffer; 4291 int len = 0; 4292 4293 /* This is a user read operation */ 4294 debug->op = LPFC_IDIAG_OP_RD; 4295 4296 if (!debug->buffer) 4297 debug->buffer = kmalloc(LPFC_QUE_ACC_BUF_SIZE, GFP_KERNEL); 4298 if (!debug->buffer) 4299 return 0; 4300 pbuffer = debug->buffer; 4301 4302 if (*ppos) 4303 return 0; 4304 4305 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) { 4306 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX]; 4307 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX]; 4308 pque = (struct lpfc_queue *)idiag.ptr_private; 4309 } else 4310 return 0; 4311 4312 /* Browse the queue starting from index */ 4313 if (count == LPFC_QUE_ACC_BROWSE) 4314 goto que_browse; 4315 4316 /* Read a single entry from the queue */ 4317 len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index); 4318 4319 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 4320 4321 que_browse: 4322 4323 /* Browse all entries from the queue */ 4324 last_index = idiag.offset.last_rd; 4325 index = last_index; 4326 4327 while (len < LPFC_QUE_ACC_SIZE - pque->entry_size) { 4328 len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index); 4329 index++; 4330 if (index > pque->entry_count - 1) 4331 break; 4332 } 4333 4334 /* Set up the offset for next portion of pci cfg read */ 4335 if (index > pque->entry_count - 1) 4336 index = 0; 4337 idiag.offset.last_rd = index; 4338 4339 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 4340 } 4341 4342 /** 4343 * lpfc_idiag_queacc_write - Syntax check and set up idiag queacc commands 4344 * @file: The file pointer to read from. 4345 * @buf: The buffer to copy the user data from. 4346 * @nbytes: The number of bytes to get. 4347 * @ppos: The position in the file to start reading from. 4348 * 4349 * This routine get the debugfs idiag command struct from user space and then 4350 * perform the syntax check for port queue read (dump) or write (set) command 4351 * accordingly. In the case of port queue read command, it sets up the command 4352 * in the idiag command struct for the following debugfs read operation. In 4353 * the case of port queue write operation, it executes the write operation 4354 * into the port queue entry accordingly. 4355 * 4356 * It returns the @nbytges passing in from debugfs user space when successful. 4357 * In case of error conditions, it returns proper error code back to the user 4358 * space. 4359 **/ 4360 static ssize_t 4361 lpfc_idiag_queacc_write(struct file *file, const char __user *buf, 4362 size_t nbytes, loff_t *ppos) 4363 { 4364 struct lpfc_debug *debug = file->private_data; 4365 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 4366 uint32_t qidx, quetp, queid, index, count, offset, value; 4367 uint32_t *pentry; 4368 struct lpfc_queue *pque, *qp; 4369 int rc; 4370 4371 /* This is a user write operation */ 4372 debug->op = LPFC_IDIAG_OP_WR; 4373 4374 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd); 4375 if (rc < 0) 4376 return rc; 4377 4378 /* Get and sanity check on command feilds */ 4379 quetp = idiag.cmd.data[IDIAG_QUEACC_QUETP_INDX]; 4380 queid = idiag.cmd.data[IDIAG_QUEACC_QUEID_INDX]; 4381 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX]; 4382 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX]; 4383 offset = idiag.cmd.data[IDIAG_QUEACC_OFFST_INDX]; 4384 value = idiag.cmd.data[IDIAG_QUEACC_VALUE_INDX]; 4385 4386 /* Sanity check on command line arguments */ 4387 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR || 4388 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST || 4389 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) { 4390 if (rc != LPFC_QUE_ACC_WR_CMD_ARG) 4391 goto error_out; 4392 if (count != 1) 4393 goto error_out; 4394 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) { 4395 if (rc != LPFC_QUE_ACC_RD_CMD_ARG) 4396 goto error_out; 4397 } else 4398 goto error_out; 4399 4400 switch (quetp) { 4401 case LPFC_IDIAG_EQ: 4402 /* HBA event queue */ 4403 if (phba->sli4_hba.hdwq) { 4404 for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { 4405 qp = phba->sli4_hba.hdwq[qidx].hba_eq; 4406 if (qp && qp->queue_id == queid) { 4407 /* Sanity check */ 4408 rc = lpfc_idiag_que_param_check(qp, 4409 index, count); 4410 if (rc) 4411 goto error_out; 4412 idiag.ptr_private = qp; 4413 goto pass_check; 4414 } 4415 } 4416 } 4417 goto error_out; 4418 4419 case LPFC_IDIAG_CQ: 4420 /* MBX complete queue */ 4421 if (phba->sli4_hba.mbx_cq && 4422 phba->sli4_hba.mbx_cq->queue_id == queid) { 4423 /* Sanity check */ 4424 rc = lpfc_idiag_que_param_check( 4425 phba->sli4_hba.mbx_cq, index, count); 4426 if (rc) 4427 goto error_out; 4428 idiag.ptr_private = phba->sli4_hba.mbx_cq; 4429 goto pass_check; 4430 } 4431 /* ELS complete queue */ 4432 if (phba->sli4_hba.els_cq && 4433 phba->sli4_hba.els_cq->queue_id == queid) { 4434 /* Sanity check */ 4435 rc = lpfc_idiag_que_param_check( 4436 phba->sli4_hba.els_cq, index, count); 4437 if (rc) 4438 goto error_out; 4439 idiag.ptr_private = phba->sli4_hba.els_cq; 4440 goto pass_check; 4441 } 4442 /* NVME LS complete queue */ 4443 if (phba->sli4_hba.nvmels_cq && 4444 phba->sli4_hba.nvmels_cq->queue_id == queid) { 4445 /* Sanity check */ 4446 rc = lpfc_idiag_que_param_check( 4447 phba->sli4_hba.nvmels_cq, index, count); 4448 if (rc) 4449 goto error_out; 4450 idiag.ptr_private = phba->sli4_hba.nvmels_cq; 4451 goto pass_check; 4452 } 4453 /* FCP complete queue */ 4454 if (phba->sli4_hba.hdwq) { 4455 for (qidx = 0; qidx < phba->cfg_hdw_queue; 4456 qidx++) { 4457 qp = phba->sli4_hba.hdwq[qidx].io_cq; 4458 if (qp && qp->queue_id == queid) { 4459 /* Sanity check */ 4460 rc = lpfc_idiag_que_param_check( 4461 qp, index, count); 4462 if (rc) 4463 goto error_out; 4464 idiag.ptr_private = qp; 4465 goto pass_check; 4466 } 4467 } 4468 } 4469 goto error_out; 4470 4471 case LPFC_IDIAG_MQ: 4472 /* MBX work queue */ 4473 if (phba->sli4_hba.mbx_wq && 4474 phba->sli4_hba.mbx_wq->queue_id == queid) { 4475 /* Sanity check */ 4476 rc = lpfc_idiag_que_param_check( 4477 phba->sli4_hba.mbx_wq, index, count); 4478 if (rc) 4479 goto error_out; 4480 idiag.ptr_private = phba->sli4_hba.mbx_wq; 4481 goto pass_check; 4482 } 4483 goto error_out; 4484 4485 case LPFC_IDIAG_WQ: 4486 /* ELS work queue */ 4487 if (phba->sli4_hba.els_wq && 4488 phba->sli4_hba.els_wq->queue_id == queid) { 4489 /* Sanity check */ 4490 rc = lpfc_idiag_que_param_check( 4491 phba->sli4_hba.els_wq, index, count); 4492 if (rc) 4493 goto error_out; 4494 idiag.ptr_private = phba->sli4_hba.els_wq; 4495 goto pass_check; 4496 } 4497 /* NVME LS work queue */ 4498 if (phba->sli4_hba.nvmels_wq && 4499 phba->sli4_hba.nvmels_wq->queue_id == queid) { 4500 /* Sanity check */ 4501 rc = lpfc_idiag_que_param_check( 4502 phba->sli4_hba.nvmels_wq, index, count); 4503 if (rc) 4504 goto error_out; 4505 idiag.ptr_private = phba->sli4_hba.nvmels_wq; 4506 goto pass_check; 4507 } 4508 4509 if (phba->sli4_hba.hdwq) { 4510 /* FCP/SCSI work queue */ 4511 for (qidx = 0; qidx < phba->cfg_hdw_queue; qidx++) { 4512 qp = phba->sli4_hba.hdwq[qidx].io_wq; 4513 if (qp && qp->queue_id == queid) { 4514 /* Sanity check */ 4515 rc = lpfc_idiag_que_param_check( 4516 qp, index, count); 4517 if (rc) 4518 goto error_out; 4519 idiag.ptr_private = qp; 4520 goto pass_check; 4521 } 4522 } 4523 } 4524 goto error_out; 4525 4526 case LPFC_IDIAG_RQ: 4527 /* HDR queue */ 4528 if (phba->sli4_hba.hdr_rq && 4529 phba->sli4_hba.hdr_rq->queue_id == queid) { 4530 /* Sanity check */ 4531 rc = lpfc_idiag_que_param_check( 4532 phba->sli4_hba.hdr_rq, index, count); 4533 if (rc) 4534 goto error_out; 4535 idiag.ptr_private = phba->sli4_hba.hdr_rq; 4536 goto pass_check; 4537 } 4538 /* DAT queue */ 4539 if (phba->sli4_hba.dat_rq && 4540 phba->sli4_hba.dat_rq->queue_id == queid) { 4541 /* Sanity check */ 4542 rc = lpfc_idiag_que_param_check( 4543 phba->sli4_hba.dat_rq, index, count); 4544 if (rc) 4545 goto error_out; 4546 idiag.ptr_private = phba->sli4_hba.dat_rq; 4547 goto pass_check; 4548 } 4549 goto error_out; 4550 default: 4551 goto error_out; 4552 } 4553 4554 pass_check: 4555 4556 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) { 4557 if (count == LPFC_QUE_ACC_BROWSE) 4558 idiag.offset.last_rd = index; 4559 } 4560 4561 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR || 4562 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST || 4563 idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) { 4564 /* Additional sanity checks on write operation */ 4565 pque = (struct lpfc_queue *)idiag.ptr_private; 4566 if (offset > pque->entry_size/sizeof(uint32_t) - 1) 4567 goto error_out; 4568 pentry = lpfc_sli4_qe(pque, index); 4569 pentry += offset; 4570 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR) 4571 *pentry = value; 4572 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST) 4573 *pentry |= value; 4574 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) 4575 *pentry &= ~value; 4576 } 4577 return nbytes; 4578 4579 error_out: 4580 /* Clean out command structure on command error out */ 4581 memset(&idiag, 0, sizeof(idiag)); 4582 return -EINVAL; 4583 } 4584 4585 /** 4586 * lpfc_idiag_drbacc_read_reg - idiag debugfs read a doorbell register 4587 * @phba: The pointer to hba structure. 4588 * @pbuffer: The pointer to the buffer to copy the data to. 4589 * @len: The length of bytes to copied. 4590 * @drbregid: The id to doorbell registers. 4591 * 4592 * Description: 4593 * This routine reads a doorbell register and copies its content to the 4594 * user buffer pointed to by @pbuffer. 4595 * 4596 * Returns: 4597 * This function returns the amount of data that was copied into @pbuffer. 4598 **/ 4599 static int 4600 lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char *pbuffer, 4601 int len, uint32_t drbregid) 4602 { 4603 4604 if (!pbuffer) 4605 return 0; 4606 4607 switch (drbregid) { 4608 case LPFC_DRB_EQ: 4609 len += scnprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE-len, 4610 "EQ-DRB-REG: 0x%08x\n", 4611 readl(phba->sli4_hba.EQDBregaddr)); 4612 break; 4613 case LPFC_DRB_CQ: 4614 len += scnprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE - len, 4615 "CQ-DRB-REG: 0x%08x\n", 4616 readl(phba->sli4_hba.CQDBregaddr)); 4617 break; 4618 case LPFC_DRB_MQ: 4619 len += scnprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len, 4620 "MQ-DRB-REG: 0x%08x\n", 4621 readl(phba->sli4_hba.MQDBregaddr)); 4622 break; 4623 case LPFC_DRB_WQ: 4624 len += scnprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len, 4625 "WQ-DRB-REG: 0x%08x\n", 4626 readl(phba->sli4_hba.WQDBregaddr)); 4627 break; 4628 case LPFC_DRB_RQ: 4629 len += scnprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len, 4630 "RQ-DRB-REG: 0x%08x\n", 4631 readl(phba->sli4_hba.RQDBregaddr)); 4632 break; 4633 default: 4634 break; 4635 } 4636 4637 return len; 4638 } 4639 4640 /** 4641 * lpfc_idiag_drbacc_read - idiag debugfs read port doorbell 4642 * @file: The file pointer to read from. 4643 * @buf: The buffer to copy the data to. 4644 * @nbytes: The number of bytes to read. 4645 * @ppos: The position in the file to start reading from. 4646 * 4647 * Description: 4648 * This routine reads data from the @phba device doorbell register according 4649 * to the idiag command, and copies to user @buf. Depending on the doorbell 4650 * register read command setup, it does either a single doorbell register 4651 * read or dump all doorbell registers. 4652 * 4653 * Returns: 4654 * This function returns the amount of data that was read (this could be less 4655 * than @nbytes if the end of the file was reached) or a negative error value. 4656 **/ 4657 static ssize_t 4658 lpfc_idiag_drbacc_read(struct file *file, char __user *buf, size_t nbytes, 4659 loff_t *ppos) 4660 { 4661 struct lpfc_debug *debug = file->private_data; 4662 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 4663 uint32_t drb_reg_id, i; 4664 char *pbuffer; 4665 int len = 0; 4666 4667 /* This is a user read operation */ 4668 debug->op = LPFC_IDIAG_OP_RD; 4669 4670 if (!debug->buffer) 4671 debug->buffer = kmalloc(LPFC_DRB_ACC_BUF_SIZE, GFP_KERNEL); 4672 if (!debug->buffer) 4673 return 0; 4674 pbuffer = debug->buffer; 4675 4676 if (*ppos) 4677 return 0; 4678 4679 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD) 4680 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX]; 4681 else 4682 return 0; 4683 4684 if (drb_reg_id == LPFC_DRB_ACC_ALL) 4685 for (i = 1; i <= LPFC_DRB_MAX; i++) 4686 len = lpfc_idiag_drbacc_read_reg(phba, 4687 pbuffer, len, i); 4688 else 4689 len = lpfc_idiag_drbacc_read_reg(phba, 4690 pbuffer, len, drb_reg_id); 4691 4692 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 4693 } 4694 4695 /** 4696 * lpfc_idiag_drbacc_write - Syntax check and set up idiag drbacc commands 4697 * @file: The file pointer to read from. 4698 * @buf: The buffer to copy the user data from. 4699 * @nbytes: The number of bytes to get. 4700 * @ppos: The position in the file to start reading from. 4701 * 4702 * This routine get the debugfs idiag command struct from user space and then 4703 * perform the syntax check for port doorbell register read (dump) or write 4704 * (set) command accordingly. In the case of port queue read command, it sets 4705 * up the command in the idiag command struct for the following debugfs read 4706 * operation. In the case of port doorbell register write operation, it 4707 * executes the write operation into the port doorbell register accordingly. 4708 * 4709 * It returns the @nbytges passing in from debugfs user space when successful. 4710 * In case of error conditions, it returns proper error code back to the user 4711 * space. 4712 **/ 4713 static ssize_t 4714 lpfc_idiag_drbacc_write(struct file *file, const char __user *buf, 4715 size_t nbytes, loff_t *ppos) 4716 { 4717 struct lpfc_debug *debug = file->private_data; 4718 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 4719 uint32_t drb_reg_id, value, reg_val = 0; 4720 void __iomem *drb_reg; 4721 int rc; 4722 4723 /* This is a user write operation */ 4724 debug->op = LPFC_IDIAG_OP_WR; 4725 4726 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd); 4727 if (rc < 0) 4728 return rc; 4729 4730 /* Sanity check on command line arguments */ 4731 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX]; 4732 value = idiag.cmd.data[IDIAG_DRBACC_VALUE_INDX]; 4733 4734 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR || 4735 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST || 4736 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) { 4737 if (rc != LPFC_DRB_ACC_WR_CMD_ARG) 4738 goto error_out; 4739 if (drb_reg_id > LPFC_DRB_MAX) 4740 goto error_out; 4741 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD) { 4742 if (rc != LPFC_DRB_ACC_RD_CMD_ARG) 4743 goto error_out; 4744 if ((drb_reg_id > LPFC_DRB_MAX) && 4745 (drb_reg_id != LPFC_DRB_ACC_ALL)) 4746 goto error_out; 4747 } else 4748 goto error_out; 4749 4750 /* Perform the write access operation */ 4751 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR || 4752 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST || 4753 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) { 4754 switch (drb_reg_id) { 4755 case LPFC_DRB_EQ: 4756 drb_reg = phba->sli4_hba.EQDBregaddr; 4757 break; 4758 case LPFC_DRB_CQ: 4759 drb_reg = phba->sli4_hba.CQDBregaddr; 4760 break; 4761 case LPFC_DRB_MQ: 4762 drb_reg = phba->sli4_hba.MQDBregaddr; 4763 break; 4764 case LPFC_DRB_WQ: 4765 drb_reg = phba->sli4_hba.WQDBregaddr; 4766 break; 4767 case LPFC_DRB_RQ: 4768 drb_reg = phba->sli4_hba.RQDBregaddr; 4769 break; 4770 default: 4771 goto error_out; 4772 } 4773 4774 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR) 4775 reg_val = value; 4776 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST) { 4777 reg_val = readl(drb_reg); 4778 reg_val |= value; 4779 } 4780 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) { 4781 reg_val = readl(drb_reg); 4782 reg_val &= ~value; 4783 } 4784 writel(reg_val, drb_reg); 4785 readl(drb_reg); /* flush */ 4786 } 4787 return nbytes; 4788 4789 error_out: 4790 /* Clean out command structure on command error out */ 4791 memset(&idiag, 0, sizeof(idiag)); 4792 return -EINVAL; 4793 } 4794 4795 /** 4796 * lpfc_idiag_ctlacc_read_reg - idiag debugfs read a control registers 4797 * @phba: The pointer to hba structure. 4798 * @pbuffer: The pointer to the buffer to copy the data to. 4799 * @len: The length of bytes to copied. 4800 * @ctlregid: The id to doorbell registers. 4801 * 4802 * Description: 4803 * This routine reads a control register and copies its content to the 4804 * user buffer pointed to by @pbuffer. 4805 * 4806 * Returns: 4807 * This function returns the amount of data that was copied into @pbuffer. 4808 **/ 4809 static int 4810 lpfc_idiag_ctlacc_read_reg(struct lpfc_hba *phba, char *pbuffer, 4811 int len, uint32_t ctlregid) 4812 { 4813 4814 if (!pbuffer) 4815 return 0; 4816 4817 switch (ctlregid) { 4818 case LPFC_CTL_PORT_SEM: 4819 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, 4820 "Port SemReg: 0x%08x\n", 4821 readl(phba->sli4_hba.conf_regs_memmap_p + 4822 LPFC_CTL_PORT_SEM_OFFSET)); 4823 break; 4824 case LPFC_CTL_PORT_STA: 4825 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, 4826 "Port StaReg: 0x%08x\n", 4827 readl(phba->sli4_hba.conf_regs_memmap_p + 4828 LPFC_CTL_PORT_STA_OFFSET)); 4829 break; 4830 case LPFC_CTL_PORT_CTL: 4831 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, 4832 "Port CtlReg: 0x%08x\n", 4833 readl(phba->sli4_hba.conf_regs_memmap_p + 4834 LPFC_CTL_PORT_CTL_OFFSET)); 4835 break; 4836 case LPFC_CTL_PORT_ER1: 4837 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, 4838 "Port Er1Reg: 0x%08x\n", 4839 readl(phba->sli4_hba.conf_regs_memmap_p + 4840 LPFC_CTL_PORT_ER1_OFFSET)); 4841 break; 4842 case LPFC_CTL_PORT_ER2: 4843 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, 4844 "Port Er2Reg: 0x%08x\n", 4845 readl(phba->sli4_hba.conf_regs_memmap_p + 4846 LPFC_CTL_PORT_ER2_OFFSET)); 4847 break; 4848 case LPFC_CTL_PDEV_CTL: 4849 len += scnprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len, 4850 "PDev CtlReg: 0x%08x\n", 4851 readl(phba->sli4_hba.conf_regs_memmap_p + 4852 LPFC_CTL_PDEV_CTL_OFFSET)); 4853 break; 4854 default: 4855 break; 4856 } 4857 return len; 4858 } 4859 4860 /** 4861 * lpfc_idiag_ctlacc_read - idiag debugfs read port and device control register 4862 * @file: The file pointer to read from. 4863 * @buf: The buffer to copy the data to. 4864 * @nbytes: The number of bytes to read. 4865 * @ppos: The position in the file to start reading from. 4866 * 4867 * Description: 4868 * This routine reads data from the @phba port and device registers according 4869 * to the idiag command, and copies to user @buf. 4870 * 4871 * Returns: 4872 * This function returns the amount of data that was read (this could be less 4873 * than @nbytes if the end of the file was reached) or a negative error value. 4874 **/ 4875 static ssize_t 4876 lpfc_idiag_ctlacc_read(struct file *file, char __user *buf, size_t nbytes, 4877 loff_t *ppos) 4878 { 4879 struct lpfc_debug *debug = file->private_data; 4880 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 4881 uint32_t ctl_reg_id, i; 4882 char *pbuffer; 4883 int len = 0; 4884 4885 /* This is a user read operation */ 4886 debug->op = LPFC_IDIAG_OP_RD; 4887 4888 if (!debug->buffer) 4889 debug->buffer = kmalloc(LPFC_CTL_ACC_BUF_SIZE, GFP_KERNEL); 4890 if (!debug->buffer) 4891 return 0; 4892 pbuffer = debug->buffer; 4893 4894 if (*ppos) 4895 return 0; 4896 4897 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD) 4898 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX]; 4899 else 4900 return 0; 4901 4902 if (ctl_reg_id == LPFC_CTL_ACC_ALL) 4903 for (i = 1; i <= LPFC_CTL_MAX; i++) 4904 len = lpfc_idiag_ctlacc_read_reg(phba, 4905 pbuffer, len, i); 4906 else 4907 len = lpfc_idiag_ctlacc_read_reg(phba, 4908 pbuffer, len, ctl_reg_id); 4909 4910 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 4911 } 4912 4913 /** 4914 * lpfc_idiag_ctlacc_write - Syntax check and set up idiag ctlacc commands 4915 * @file: The file pointer to read from. 4916 * @buf: The buffer to copy the user data from. 4917 * @nbytes: The number of bytes to get. 4918 * @ppos: The position in the file to start reading from. 4919 * 4920 * This routine get the debugfs idiag command struct from user space and then 4921 * perform the syntax check for port and device control register read (dump) 4922 * or write (set) command accordingly. 4923 * 4924 * It returns the @nbytges passing in from debugfs user space when successful. 4925 * In case of error conditions, it returns proper error code back to the user 4926 * space. 4927 **/ 4928 static ssize_t 4929 lpfc_idiag_ctlacc_write(struct file *file, const char __user *buf, 4930 size_t nbytes, loff_t *ppos) 4931 { 4932 struct lpfc_debug *debug = file->private_data; 4933 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 4934 uint32_t ctl_reg_id, value, reg_val = 0; 4935 void __iomem *ctl_reg; 4936 int rc; 4937 4938 /* This is a user write operation */ 4939 debug->op = LPFC_IDIAG_OP_WR; 4940 4941 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd); 4942 if (rc < 0) 4943 return rc; 4944 4945 /* Sanity check on command line arguments */ 4946 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX]; 4947 value = idiag.cmd.data[IDIAG_CTLACC_VALUE_INDX]; 4948 4949 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR || 4950 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST || 4951 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) { 4952 if (rc != LPFC_CTL_ACC_WR_CMD_ARG) 4953 goto error_out; 4954 if (ctl_reg_id > LPFC_CTL_MAX) 4955 goto error_out; 4956 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD) { 4957 if (rc != LPFC_CTL_ACC_RD_CMD_ARG) 4958 goto error_out; 4959 if ((ctl_reg_id > LPFC_CTL_MAX) && 4960 (ctl_reg_id != LPFC_CTL_ACC_ALL)) 4961 goto error_out; 4962 } else 4963 goto error_out; 4964 4965 /* Perform the write access operation */ 4966 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR || 4967 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST || 4968 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) { 4969 switch (ctl_reg_id) { 4970 case LPFC_CTL_PORT_SEM: 4971 ctl_reg = phba->sli4_hba.conf_regs_memmap_p + 4972 LPFC_CTL_PORT_SEM_OFFSET; 4973 break; 4974 case LPFC_CTL_PORT_STA: 4975 ctl_reg = phba->sli4_hba.conf_regs_memmap_p + 4976 LPFC_CTL_PORT_STA_OFFSET; 4977 break; 4978 case LPFC_CTL_PORT_CTL: 4979 ctl_reg = phba->sli4_hba.conf_regs_memmap_p + 4980 LPFC_CTL_PORT_CTL_OFFSET; 4981 break; 4982 case LPFC_CTL_PORT_ER1: 4983 ctl_reg = phba->sli4_hba.conf_regs_memmap_p + 4984 LPFC_CTL_PORT_ER1_OFFSET; 4985 break; 4986 case LPFC_CTL_PORT_ER2: 4987 ctl_reg = phba->sli4_hba.conf_regs_memmap_p + 4988 LPFC_CTL_PORT_ER2_OFFSET; 4989 break; 4990 case LPFC_CTL_PDEV_CTL: 4991 ctl_reg = phba->sli4_hba.conf_regs_memmap_p + 4992 LPFC_CTL_PDEV_CTL_OFFSET; 4993 break; 4994 default: 4995 goto error_out; 4996 } 4997 4998 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR) 4999 reg_val = value; 5000 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST) { 5001 reg_val = readl(ctl_reg); 5002 reg_val |= value; 5003 } 5004 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) { 5005 reg_val = readl(ctl_reg); 5006 reg_val &= ~value; 5007 } 5008 writel(reg_val, ctl_reg); 5009 readl(ctl_reg); /* flush */ 5010 } 5011 return nbytes; 5012 5013 error_out: 5014 /* Clean out command structure on command error out */ 5015 memset(&idiag, 0, sizeof(idiag)); 5016 return -EINVAL; 5017 } 5018 5019 /** 5020 * lpfc_idiag_mbxacc_get_setup - idiag debugfs get mailbox access setup 5021 * @phba: Pointer to HBA context object. 5022 * @pbuffer: Pointer to data buffer. 5023 * 5024 * Description: 5025 * This routine gets the driver mailbox access debugfs setup information. 5026 * 5027 * Returns: 5028 * This function returns the amount of data that was read (this could be less 5029 * than @nbytes if the end of the file was reached) or a negative error value. 5030 **/ 5031 static int 5032 lpfc_idiag_mbxacc_get_setup(struct lpfc_hba *phba, char *pbuffer) 5033 { 5034 uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd; 5035 int len = 0; 5036 5037 mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX]; 5038 mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX]; 5039 mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX]; 5040 mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX]; 5041 5042 len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len, 5043 "mbx_dump_map: 0x%08x\n", mbx_dump_map); 5044 len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len, 5045 "mbx_dump_cnt: %04d\n", mbx_dump_cnt); 5046 len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len, 5047 "mbx_word_cnt: %04d\n", mbx_word_cnt); 5048 len += scnprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len, 5049 "mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd); 5050 5051 return len; 5052 } 5053 5054 /** 5055 * lpfc_idiag_mbxacc_read - idiag debugfs read on mailbox access 5056 * @file: The file pointer to read from. 5057 * @buf: The buffer to copy the data to. 5058 * @nbytes: The number of bytes to read. 5059 * @ppos: The position in the file to start reading from. 5060 * 5061 * Description: 5062 * This routine reads data from the @phba driver mailbox access debugfs setup 5063 * information. 5064 * 5065 * Returns: 5066 * This function returns the amount of data that was read (this could be less 5067 * than @nbytes if the end of the file was reached) or a negative error value. 5068 **/ 5069 static ssize_t 5070 lpfc_idiag_mbxacc_read(struct file *file, char __user *buf, size_t nbytes, 5071 loff_t *ppos) 5072 { 5073 struct lpfc_debug *debug = file->private_data; 5074 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 5075 char *pbuffer; 5076 int len = 0; 5077 5078 /* This is a user read operation */ 5079 debug->op = LPFC_IDIAG_OP_RD; 5080 5081 if (!debug->buffer) 5082 debug->buffer = kmalloc(LPFC_MBX_ACC_BUF_SIZE, GFP_KERNEL); 5083 if (!debug->buffer) 5084 return 0; 5085 pbuffer = debug->buffer; 5086 5087 if (*ppos) 5088 return 0; 5089 5090 if ((idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP) && 5091 (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP)) 5092 return 0; 5093 5094 len = lpfc_idiag_mbxacc_get_setup(phba, pbuffer); 5095 5096 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 5097 } 5098 5099 /** 5100 * lpfc_idiag_mbxacc_write - Syntax check and set up idiag mbxacc commands 5101 * @file: The file pointer to read from. 5102 * @buf: The buffer to copy the user data from. 5103 * @nbytes: The number of bytes to get. 5104 * @ppos: The position in the file to start reading from. 5105 * 5106 * This routine get the debugfs idiag command struct from user space and then 5107 * perform the syntax check for driver mailbox command (dump) and sets up the 5108 * necessary states in the idiag command struct accordingly. 5109 * 5110 * It returns the @nbytges passing in from debugfs user space when successful. 5111 * In case of error conditions, it returns proper error code back to the user 5112 * space. 5113 **/ 5114 static ssize_t 5115 lpfc_idiag_mbxacc_write(struct file *file, const char __user *buf, 5116 size_t nbytes, loff_t *ppos) 5117 { 5118 struct lpfc_debug *debug = file->private_data; 5119 uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd; 5120 int rc; 5121 5122 /* This is a user write operation */ 5123 debug->op = LPFC_IDIAG_OP_WR; 5124 5125 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd); 5126 if (rc < 0) 5127 return rc; 5128 5129 /* Sanity check on command line arguments */ 5130 mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX]; 5131 mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX]; 5132 mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX]; 5133 mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX]; 5134 5135 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_MBXACC_DP) { 5136 if (!(mbx_dump_map & LPFC_MBX_DMP_MBX_ALL)) 5137 goto error_out; 5138 if ((mbx_dump_map & ~LPFC_MBX_DMP_MBX_ALL) && 5139 (mbx_dump_map != LPFC_MBX_DMP_ALL)) 5140 goto error_out; 5141 if (mbx_word_cnt > sizeof(MAILBOX_t)) 5142 goto error_out; 5143 } else if (idiag.cmd.opcode == LPFC_IDIAG_BSG_MBXACC_DP) { 5144 if (!(mbx_dump_map & LPFC_BSG_DMP_MBX_ALL)) 5145 goto error_out; 5146 if ((mbx_dump_map & ~LPFC_BSG_DMP_MBX_ALL) && 5147 (mbx_dump_map != LPFC_MBX_DMP_ALL)) 5148 goto error_out; 5149 if (mbx_word_cnt > (BSG_MBOX_SIZE)/4) 5150 goto error_out; 5151 if (mbx_mbox_cmd != 0x9b) 5152 goto error_out; 5153 } else 5154 goto error_out; 5155 5156 if (mbx_word_cnt == 0) 5157 goto error_out; 5158 if (rc != LPFC_MBX_DMP_ARG) 5159 goto error_out; 5160 if (mbx_mbox_cmd & ~0xff) 5161 goto error_out; 5162 5163 /* condition for stop mailbox dump */ 5164 if (mbx_dump_cnt == 0) 5165 goto reset_out; 5166 5167 return nbytes; 5168 5169 reset_out: 5170 /* Clean out command structure on command error out */ 5171 memset(&idiag, 0, sizeof(idiag)); 5172 return nbytes; 5173 5174 error_out: 5175 /* Clean out command structure on command error out */ 5176 memset(&idiag, 0, sizeof(idiag)); 5177 return -EINVAL; 5178 } 5179 5180 /** 5181 * lpfc_idiag_extacc_avail_get - get the available extents information 5182 * @phba: pointer to lpfc hba data structure. 5183 * @pbuffer: pointer to internal buffer. 5184 * @len: length into the internal buffer data has been copied. 5185 * 5186 * Description: 5187 * This routine is to get the available extent information. 5188 * 5189 * Returns: 5190 * overall length of the data read into the internal buffer. 5191 **/ 5192 static int 5193 lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len) 5194 { 5195 uint16_t ext_cnt = 0, ext_size = 0; 5196 5197 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5198 "\nAvailable Extents Information:\n"); 5199 5200 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5201 "\tPort Available VPI extents: "); 5202 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VPI, 5203 &ext_cnt, &ext_size); 5204 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5205 "Count %3d, Size %3d\n", ext_cnt, ext_size); 5206 5207 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5208 "\tPort Available VFI extents: "); 5209 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VFI, 5210 &ext_cnt, &ext_size); 5211 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5212 "Count %3d, Size %3d\n", ext_cnt, ext_size); 5213 5214 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5215 "\tPort Available RPI extents: "); 5216 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_RPI, 5217 &ext_cnt, &ext_size); 5218 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5219 "Count %3d, Size %3d\n", ext_cnt, ext_size); 5220 5221 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5222 "\tPort Available XRI extents: "); 5223 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_XRI, 5224 &ext_cnt, &ext_size); 5225 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5226 "Count %3d, Size %3d\n", ext_cnt, ext_size); 5227 5228 return len; 5229 } 5230 5231 /** 5232 * lpfc_idiag_extacc_alloc_get - get the allocated extents information 5233 * @phba: pointer to lpfc hba data structure. 5234 * @pbuffer: pointer to internal buffer. 5235 * @len: length into the internal buffer data has been copied. 5236 * 5237 * Description: 5238 * This routine is to get the allocated extent information. 5239 * 5240 * Returns: 5241 * overall length of the data read into the internal buffer. 5242 **/ 5243 static int 5244 lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len) 5245 { 5246 uint16_t ext_cnt, ext_size; 5247 int rc; 5248 5249 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5250 "\nAllocated Extents Information:\n"); 5251 5252 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5253 "\tHost Allocated VPI extents: "); 5254 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VPI, 5255 &ext_cnt, &ext_size); 5256 if (!rc) 5257 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5258 "Port %d Extent %3d, Size %3d\n", 5259 phba->brd_no, ext_cnt, ext_size); 5260 else 5261 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5262 "N/A\n"); 5263 5264 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5265 "\tHost Allocated VFI extents: "); 5266 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VFI, 5267 &ext_cnt, &ext_size); 5268 if (!rc) 5269 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5270 "Port %d Extent %3d, Size %3d\n", 5271 phba->brd_no, ext_cnt, ext_size); 5272 else 5273 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5274 "N/A\n"); 5275 5276 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5277 "\tHost Allocated RPI extents: "); 5278 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_RPI, 5279 &ext_cnt, &ext_size); 5280 if (!rc) 5281 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5282 "Port %d Extent %3d, Size %3d\n", 5283 phba->brd_no, ext_cnt, ext_size); 5284 else 5285 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5286 "N/A\n"); 5287 5288 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5289 "\tHost Allocated XRI extents: "); 5290 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_XRI, 5291 &ext_cnt, &ext_size); 5292 if (!rc) 5293 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5294 "Port %d Extent %3d, Size %3d\n", 5295 phba->brd_no, ext_cnt, ext_size); 5296 else 5297 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5298 "N/A\n"); 5299 5300 return len; 5301 } 5302 5303 /** 5304 * lpfc_idiag_extacc_drivr_get - get driver extent information 5305 * @phba: pointer to lpfc hba data structure. 5306 * @pbuffer: pointer to internal buffer. 5307 * @len: length into the internal buffer data has been copied. 5308 * 5309 * Description: 5310 * This routine is to get the driver extent information. 5311 * 5312 * Returns: 5313 * overall length of the data read into the internal buffer. 5314 **/ 5315 static int 5316 lpfc_idiag_extacc_drivr_get(struct lpfc_hba *phba, char *pbuffer, int len) 5317 { 5318 struct lpfc_rsrc_blks *rsrc_blks; 5319 int index; 5320 5321 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5322 "\nDriver Extents Information:\n"); 5323 5324 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5325 "\tVPI extents:\n"); 5326 index = 0; 5327 list_for_each_entry(rsrc_blks, &phba->lpfc_vpi_blk_list, list) { 5328 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5329 "\t\tBlock %3d: Start %4d, Count %4d\n", 5330 index, rsrc_blks->rsrc_start, 5331 rsrc_blks->rsrc_size); 5332 index++; 5333 } 5334 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5335 "\tVFI extents:\n"); 5336 index = 0; 5337 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_vfi_blk_list, 5338 list) { 5339 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5340 "\t\tBlock %3d: Start %4d, Count %4d\n", 5341 index, rsrc_blks->rsrc_start, 5342 rsrc_blks->rsrc_size); 5343 index++; 5344 } 5345 5346 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5347 "\tRPI extents:\n"); 5348 index = 0; 5349 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_rpi_blk_list, 5350 list) { 5351 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5352 "\t\tBlock %3d: Start %4d, Count %4d\n", 5353 index, rsrc_blks->rsrc_start, 5354 rsrc_blks->rsrc_size); 5355 index++; 5356 } 5357 5358 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5359 "\tXRI extents:\n"); 5360 index = 0; 5361 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_xri_blk_list, 5362 list) { 5363 len += scnprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len, 5364 "\t\tBlock %3d: Start %4d, Count %4d\n", 5365 index, rsrc_blks->rsrc_start, 5366 rsrc_blks->rsrc_size); 5367 index++; 5368 } 5369 5370 return len; 5371 } 5372 5373 /** 5374 * lpfc_idiag_extacc_write - Syntax check and set up idiag extacc commands 5375 * @file: The file pointer to read from. 5376 * @buf: The buffer to copy the user data from. 5377 * @nbytes: The number of bytes to get. 5378 * @ppos: The position in the file to start reading from. 5379 * 5380 * This routine get the debugfs idiag command struct from user space and then 5381 * perform the syntax check for extent information access commands and sets 5382 * up the necessary states in the idiag command struct accordingly. 5383 * 5384 * It returns the @nbytges passing in from debugfs user space when successful. 5385 * In case of error conditions, it returns proper error code back to the user 5386 * space. 5387 **/ 5388 static ssize_t 5389 lpfc_idiag_extacc_write(struct file *file, const char __user *buf, 5390 size_t nbytes, loff_t *ppos) 5391 { 5392 struct lpfc_debug *debug = file->private_data; 5393 uint32_t ext_map; 5394 int rc; 5395 5396 /* This is a user write operation */ 5397 debug->op = LPFC_IDIAG_OP_WR; 5398 5399 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd); 5400 if (rc < 0) 5401 return rc; 5402 5403 ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX]; 5404 5405 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD) 5406 goto error_out; 5407 if (rc != LPFC_EXT_ACC_CMD_ARG) 5408 goto error_out; 5409 if (!(ext_map & LPFC_EXT_ACC_ALL)) 5410 goto error_out; 5411 5412 return nbytes; 5413 error_out: 5414 /* Clean out command structure on command error out */ 5415 memset(&idiag, 0, sizeof(idiag)); 5416 return -EINVAL; 5417 } 5418 5419 /** 5420 * lpfc_idiag_extacc_read - idiag debugfs read access to extent information 5421 * @file: The file pointer to read from. 5422 * @buf: The buffer to copy the data to. 5423 * @nbytes: The number of bytes to read. 5424 * @ppos: The position in the file to start reading from. 5425 * 5426 * Description: 5427 * This routine reads data from the proper extent information according to 5428 * the idiag command, and copies to user @buf. 5429 * 5430 * Returns: 5431 * This function returns the amount of data that was read (this could be less 5432 * than @nbytes if the end of the file was reached) or a negative error value. 5433 **/ 5434 static ssize_t 5435 lpfc_idiag_extacc_read(struct file *file, char __user *buf, size_t nbytes, 5436 loff_t *ppos) 5437 { 5438 struct lpfc_debug *debug = file->private_data; 5439 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 5440 char *pbuffer; 5441 uint32_t ext_map; 5442 int len = 0; 5443 5444 /* This is a user read operation */ 5445 debug->op = LPFC_IDIAG_OP_RD; 5446 5447 if (!debug->buffer) 5448 debug->buffer = kmalloc(LPFC_EXT_ACC_BUF_SIZE, GFP_KERNEL); 5449 if (!debug->buffer) 5450 return 0; 5451 pbuffer = debug->buffer; 5452 if (*ppos) 5453 return 0; 5454 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD) 5455 return 0; 5456 5457 ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX]; 5458 if (ext_map & LPFC_EXT_ACC_AVAIL) 5459 len = lpfc_idiag_extacc_avail_get(phba, pbuffer, len); 5460 if (ext_map & LPFC_EXT_ACC_ALLOC) 5461 len = lpfc_idiag_extacc_alloc_get(phba, pbuffer, len); 5462 if (ext_map & LPFC_EXT_ACC_DRIVR) 5463 len = lpfc_idiag_extacc_drivr_get(phba, pbuffer, len); 5464 5465 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 5466 } 5467 5468 static int 5469 lpfc_cgn_buffer_open(struct inode *inode, struct file *file) 5470 { 5471 struct lpfc_debug *debug; 5472 int rc = -ENOMEM; 5473 5474 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 5475 if (!debug) 5476 goto out; 5477 5478 debug->buffer = vmalloc(LPFC_CGN_BUF_SIZE); 5479 if (!debug->buffer) { 5480 kfree(debug); 5481 goto out; 5482 } 5483 5484 debug->i_private = inode->i_private; 5485 file->private_data = debug; 5486 5487 rc = 0; 5488 out: 5489 return rc; 5490 } 5491 5492 static ssize_t 5493 lpfc_cgn_buffer_read(struct file *file, char __user *buf, size_t nbytes, 5494 loff_t *ppos) 5495 { 5496 struct lpfc_debug *debug = file->private_data; 5497 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 5498 char *buffer = debug->buffer; 5499 uint32_t *ptr; 5500 int cnt, len = 0; 5501 5502 if (!phba->sli4_hba.pc_sli4_params.mi_ver || !phba->cgn_i) { 5503 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len, 5504 "Congestion Mgmt is not supported\n"); 5505 goto out; 5506 } 5507 ptr = (uint32_t *)phba->cgn_i->virt; 5508 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len, 5509 "Congestion Buffer Header\n"); 5510 /* Dump the first 32 bytes */ 5511 cnt = 32; 5512 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len, 5513 "000: %08x %08x %08x %08x %08x %08x %08x %08x\n", 5514 *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3), 5515 *(ptr + 4), *(ptr + 5), *(ptr + 6), *(ptr + 7)); 5516 ptr += 8; 5517 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len, 5518 "Congestion Buffer Data\n"); 5519 while (cnt < sizeof(struct lpfc_cgn_info)) { 5520 if (len > (LPFC_CGN_BUF_SIZE - LPFC_DEBUG_OUT_LINE_SZ)) { 5521 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len, 5522 "Truncated . . .\n"); 5523 goto out; 5524 } 5525 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len, 5526 "%03x: %08x %08x %08x %08x " 5527 "%08x %08x %08x %08x\n", 5528 cnt, *ptr, *(ptr + 1), *(ptr + 2), 5529 *(ptr + 3), *(ptr + 4), *(ptr + 5), 5530 *(ptr + 6), *(ptr + 7)); 5531 cnt += 32; 5532 ptr += 8; 5533 } 5534 if (len > (LPFC_CGN_BUF_SIZE - LPFC_DEBUG_OUT_LINE_SZ)) { 5535 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len, 5536 "Truncated . . .\n"); 5537 goto out; 5538 } 5539 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len, 5540 "Parameter Data\n"); 5541 ptr = (uint32_t *)&phba->cgn_p; 5542 len += scnprintf(buffer + len, LPFC_CGN_BUF_SIZE - len, 5543 "%08x %08x %08x %08x\n", 5544 *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3)); 5545 out: 5546 return simple_read_from_buffer(buf, nbytes, ppos, buffer, len); 5547 } 5548 5549 static int 5550 lpfc_cgn_buffer_release(struct inode *inode, struct file *file) 5551 { 5552 struct lpfc_debug *debug = file->private_data; 5553 5554 vfree(debug->buffer); 5555 kfree(debug); 5556 5557 return 0; 5558 } 5559 5560 static int 5561 lpfc_rx_monitor_open(struct inode *inode, struct file *file) 5562 { 5563 struct lpfc_rx_monitor_debug *debug; 5564 int rc = -ENOMEM; 5565 5566 debug = kmalloc(sizeof(*debug), GFP_KERNEL); 5567 if (!debug) 5568 goto out; 5569 5570 debug->buffer = vmalloc(MAX_DEBUGFS_RX_INFO_SIZE); 5571 if (!debug->buffer) { 5572 kfree(debug); 5573 goto out; 5574 } 5575 5576 debug->i_private = inode->i_private; 5577 file->private_data = debug; 5578 5579 rc = 0; 5580 out: 5581 return rc; 5582 } 5583 5584 static ssize_t 5585 lpfc_rx_monitor_read(struct file *file, char __user *buf, size_t nbytes, 5586 loff_t *ppos) 5587 { 5588 struct lpfc_rx_monitor_debug *debug = file->private_data; 5589 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 5590 char *buffer = debug->buffer; 5591 5592 if (!phba->rx_monitor) { 5593 scnprintf(buffer, MAX_DEBUGFS_RX_INFO_SIZE, 5594 "Rx Monitor Info is empty.\n"); 5595 } else { 5596 lpfc_rx_monitor_report(phba, phba->rx_monitor, buffer, 5597 MAX_DEBUGFS_RX_INFO_SIZE, 5598 LPFC_MAX_RXMONITOR_ENTRY); 5599 } 5600 5601 return simple_read_from_buffer(buf, nbytes, ppos, buffer, 5602 strlen(buffer)); 5603 } 5604 5605 static int 5606 lpfc_rx_monitor_release(struct inode *inode, struct file *file) 5607 { 5608 struct lpfc_rx_monitor_debug *debug = file->private_data; 5609 5610 vfree(debug->buffer); 5611 kfree(debug); 5612 5613 return 0; 5614 } 5615 5616 #undef lpfc_debugfs_op_disc_trc 5617 static const struct file_operations lpfc_debugfs_op_disc_trc = { 5618 .owner = THIS_MODULE, 5619 .open = lpfc_debugfs_disc_trc_open, 5620 .llseek = lpfc_debugfs_lseek, 5621 .read = lpfc_debugfs_read, 5622 .release = lpfc_debugfs_release, 5623 }; 5624 5625 #undef lpfc_debugfs_op_nodelist 5626 static const struct file_operations lpfc_debugfs_op_nodelist = { 5627 .owner = THIS_MODULE, 5628 .open = lpfc_debugfs_nodelist_open, 5629 .llseek = lpfc_debugfs_lseek, 5630 .read = lpfc_debugfs_read, 5631 .release = lpfc_debugfs_release, 5632 }; 5633 5634 #undef lpfc_debugfs_op_multixripools 5635 static const struct file_operations lpfc_debugfs_op_multixripools = { 5636 .owner = THIS_MODULE, 5637 .open = lpfc_debugfs_multixripools_open, 5638 .llseek = lpfc_debugfs_lseek, 5639 .read = lpfc_debugfs_read, 5640 .write = lpfc_debugfs_multixripools_write, 5641 .release = lpfc_debugfs_release, 5642 }; 5643 5644 #undef lpfc_debugfs_op_hbqinfo 5645 static const struct file_operations lpfc_debugfs_op_hbqinfo = { 5646 .owner = THIS_MODULE, 5647 .open = lpfc_debugfs_hbqinfo_open, 5648 .llseek = lpfc_debugfs_lseek, 5649 .read = lpfc_debugfs_read, 5650 .release = lpfc_debugfs_release, 5651 }; 5652 5653 #ifdef LPFC_HDWQ_LOCK_STAT 5654 #undef lpfc_debugfs_op_lockstat 5655 static const struct file_operations lpfc_debugfs_op_lockstat = { 5656 .owner = THIS_MODULE, 5657 .open = lpfc_debugfs_lockstat_open, 5658 .llseek = lpfc_debugfs_lseek, 5659 .read = lpfc_debugfs_read, 5660 .write = lpfc_debugfs_lockstat_write, 5661 .release = lpfc_debugfs_release, 5662 }; 5663 #endif 5664 5665 #undef lpfc_debugfs_ras_log 5666 static const struct file_operations lpfc_debugfs_ras_log = { 5667 .owner = THIS_MODULE, 5668 .open = lpfc_debugfs_ras_log_open, 5669 .llseek = lpfc_debugfs_lseek, 5670 .read = lpfc_debugfs_read, 5671 .release = lpfc_debugfs_ras_log_release, 5672 }; 5673 5674 #undef lpfc_debugfs_op_dumpHBASlim 5675 static const struct file_operations lpfc_debugfs_op_dumpHBASlim = { 5676 .owner = THIS_MODULE, 5677 .open = lpfc_debugfs_dumpHBASlim_open, 5678 .llseek = lpfc_debugfs_lseek, 5679 .read = lpfc_debugfs_read, 5680 .release = lpfc_debugfs_release, 5681 }; 5682 5683 #undef lpfc_debugfs_op_dumpHostSlim 5684 static const struct file_operations lpfc_debugfs_op_dumpHostSlim = { 5685 .owner = THIS_MODULE, 5686 .open = lpfc_debugfs_dumpHostSlim_open, 5687 .llseek = lpfc_debugfs_lseek, 5688 .read = lpfc_debugfs_read, 5689 .release = lpfc_debugfs_release, 5690 }; 5691 5692 #undef lpfc_debugfs_op_nvmestat 5693 static const struct file_operations lpfc_debugfs_op_nvmestat = { 5694 .owner = THIS_MODULE, 5695 .open = lpfc_debugfs_nvmestat_open, 5696 .llseek = lpfc_debugfs_lseek, 5697 .read = lpfc_debugfs_read, 5698 .write = lpfc_debugfs_nvmestat_write, 5699 .release = lpfc_debugfs_release, 5700 }; 5701 5702 #undef lpfc_debugfs_op_scsistat 5703 static const struct file_operations lpfc_debugfs_op_scsistat = { 5704 .owner = THIS_MODULE, 5705 .open = lpfc_debugfs_scsistat_open, 5706 .llseek = lpfc_debugfs_lseek, 5707 .read = lpfc_debugfs_read, 5708 .write = lpfc_debugfs_scsistat_write, 5709 .release = lpfc_debugfs_release, 5710 }; 5711 5712 #undef lpfc_debugfs_op_ioktime 5713 static const struct file_operations lpfc_debugfs_op_ioktime = { 5714 .owner = THIS_MODULE, 5715 .open = lpfc_debugfs_ioktime_open, 5716 .llseek = lpfc_debugfs_lseek, 5717 .read = lpfc_debugfs_read, 5718 .write = lpfc_debugfs_ioktime_write, 5719 .release = lpfc_debugfs_release, 5720 }; 5721 5722 #undef lpfc_debugfs_op_nvmeio_trc 5723 static const struct file_operations lpfc_debugfs_op_nvmeio_trc = { 5724 .owner = THIS_MODULE, 5725 .open = lpfc_debugfs_nvmeio_trc_open, 5726 .llseek = lpfc_debugfs_lseek, 5727 .read = lpfc_debugfs_read, 5728 .write = lpfc_debugfs_nvmeio_trc_write, 5729 .release = lpfc_debugfs_release, 5730 }; 5731 5732 #undef lpfc_debugfs_op_hdwqstat 5733 static const struct file_operations lpfc_debugfs_op_hdwqstat = { 5734 .owner = THIS_MODULE, 5735 .open = lpfc_debugfs_hdwqstat_open, 5736 .llseek = lpfc_debugfs_lseek, 5737 .read = lpfc_debugfs_read, 5738 .write = lpfc_debugfs_hdwqstat_write, 5739 .release = lpfc_debugfs_release, 5740 }; 5741 5742 #undef lpfc_debugfs_op_dif_err 5743 static const struct file_operations lpfc_debugfs_op_dif_err = { 5744 .owner = THIS_MODULE, 5745 .open = simple_open, 5746 .llseek = lpfc_debugfs_lseek, 5747 .read = lpfc_debugfs_dif_err_read, 5748 .write = lpfc_debugfs_dif_err_write, 5749 .release = lpfc_debugfs_dif_err_release, 5750 }; 5751 5752 #undef lpfc_debugfs_op_slow_ring_trc 5753 static const struct file_operations lpfc_debugfs_op_slow_ring_trc = { 5754 .owner = THIS_MODULE, 5755 .open = lpfc_debugfs_slow_ring_trc_open, 5756 .llseek = lpfc_debugfs_lseek, 5757 .read = lpfc_debugfs_read, 5758 .release = lpfc_debugfs_release, 5759 }; 5760 5761 static struct dentry *lpfc_debugfs_root = NULL; 5762 static unsigned int lpfc_debugfs_hba_count; 5763 5764 /* 5765 * File operations for the iDiag debugfs 5766 */ 5767 #undef lpfc_idiag_op_pciCfg 5768 static const struct file_operations lpfc_idiag_op_pciCfg = { 5769 .owner = THIS_MODULE, 5770 .open = lpfc_idiag_open, 5771 .llseek = lpfc_debugfs_lseek, 5772 .read = lpfc_idiag_pcicfg_read, 5773 .write = lpfc_idiag_pcicfg_write, 5774 .release = lpfc_idiag_cmd_release, 5775 }; 5776 5777 #undef lpfc_idiag_op_barAcc 5778 static const struct file_operations lpfc_idiag_op_barAcc = { 5779 .owner = THIS_MODULE, 5780 .open = lpfc_idiag_open, 5781 .llseek = lpfc_debugfs_lseek, 5782 .read = lpfc_idiag_baracc_read, 5783 .write = lpfc_idiag_baracc_write, 5784 .release = lpfc_idiag_cmd_release, 5785 }; 5786 5787 #undef lpfc_idiag_op_queInfo 5788 static const struct file_operations lpfc_idiag_op_queInfo = { 5789 .owner = THIS_MODULE, 5790 .open = lpfc_idiag_open, 5791 .read = lpfc_idiag_queinfo_read, 5792 .release = lpfc_idiag_release, 5793 }; 5794 5795 #undef lpfc_idiag_op_queAcc 5796 static const struct file_operations lpfc_idiag_op_queAcc = { 5797 .owner = THIS_MODULE, 5798 .open = lpfc_idiag_open, 5799 .llseek = lpfc_debugfs_lseek, 5800 .read = lpfc_idiag_queacc_read, 5801 .write = lpfc_idiag_queacc_write, 5802 .release = lpfc_idiag_cmd_release, 5803 }; 5804 5805 #undef lpfc_idiag_op_drbAcc 5806 static const struct file_operations lpfc_idiag_op_drbAcc = { 5807 .owner = THIS_MODULE, 5808 .open = lpfc_idiag_open, 5809 .llseek = lpfc_debugfs_lseek, 5810 .read = lpfc_idiag_drbacc_read, 5811 .write = lpfc_idiag_drbacc_write, 5812 .release = lpfc_idiag_cmd_release, 5813 }; 5814 5815 #undef lpfc_idiag_op_ctlAcc 5816 static const struct file_operations lpfc_idiag_op_ctlAcc = { 5817 .owner = THIS_MODULE, 5818 .open = lpfc_idiag_open, 5819 .llseek = lpfc_debugfs_lseek, 5820 .read = lpfc_idiag_ctlacc_read, 5821 .write = lpfc_idiag_ctlacc_write, 5822 .release = lpfc_idiag_cmd_release, 5823 }; 5824 5825 #undef lpfc_idiag_op_mbxAcc 5826 static const struct file_operations lpfc_idiag_op_mbxAcc = { 5827 .owner = THIS_MODULE, 5828 .open = lpfc_idiag_open, 5829 .llseek = lpfc_debugfs_lseek, 5830 .read = lpfc_idiag_mbxacc_read, 5831 .write = lpfc_idiag_mbxacc_write, 5832 .release = lpfc_idiag_cmd_release, 5833 }; 5834 5835 #undef lpfc_idiag_op_extAcc 5836 static const struct file_operations lpfc_idiag_op_extAcc = { 5837 .owner = THIS_MODULE, 5838 .open = lpfc_idiag_open, 5839 .llseek = lpfc_debugfs_lseek, 5840 .read = lpfc_idiag_extacc_read, 5841 .write = lpfc_idiag_extacc_write, 5842 .release = lpfc_idiag_cmd_release, 5843 }; 5844 #undef lpfc_cgn_buffer_op 5845 static const struct file_operations lpfc_cgn_buffer_op = { 5846 .owner = THIS_MODULE, 5847 .open = lpfc_cgn_buffer_open, 5848 .llseek = lpfc_debugfs_lseek, 5849 .read = lpfc_cgn_buffer_read, 5850 .release = lpfc_cgn_buffer_release, 5851 }; 5852 5853 #undef lpfc_rx_monitor_op 5854 static const struct file_operations lpfc_rx_monitor_op = { 5855 .owner = THIS_MODULE, 5856 .open = lpfc_rx_monitor_open, 5857 .llseek = lpfc_debugfs_lseek, 5858 .read = lpfc_rx_monitor_read, 5859 .release = lpfc_rx_monitor_release, 5860 }; 5861 #endif 5862 5863 /* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command 5864 * @phba: Pointer to HBA context object. 5865 * @dmabuf: Pointer to a DMA buffer descriptor. 5866 * 5867 * Description: 5868 * This routine dump a bsg pass-through non-embedded mailbox command with 5869 * external buffer. 5870 **/ 5871 void 5872 lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba *phba, enum nemb_type nemb_tp, 5873 enum mbox_type mbox_tp, enum dma_type dma_tp, 5874 enum sta_type sta_tp, 5875 struct lpfc_dmabuf *dmabuf, uint32_t ext_buf) 5876 { 5877 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS 5878 uint32_t *mbx_mbox_cmd, *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt; 5879 char line_buf[LPFC_MBX_ACC_LBUF_SZ]; 5880 int len = 0; 5881 uint32_t do_dump = 0; 5882 uint32_t *pword; 5883 uint32_t i; 5884 5885 if (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP) 5886 return; 5887 5888 mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX]; 5889 mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX]; 5890 mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX]; 5891 mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX]; 5892 5893 if (!(*mbx_dump_map & LPFC_MBX_DMP_ALL) || 5894 (*mbx_dump_cnt == 0) || 5895 (*mbx_word_cnt == 0)) 5896 return; 5897 5898 if (*mbx_mbox_cmd != 0x9B) 5899 return; 5900 5901 if ((mbox_tp == mbox_rd) && (dma_tp == dma_mbox)) { 5902 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_MBX) { 5903 do_dump |= LPFC_BSG_DMP_MBX_RD_MBX; 5904 pr_err("\nRead mbox command (x%x), " 5905 "nemb:0x%x, extbuf_cnt:%d:\n", 5906 sta_tp, nemb_tp, ext_buf); 5907 } 5908 } 5909 if ((mbox_tp == mbox_rd) && (dma_tp == dma_ebuf)) { 5910 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_BUF) { 5911 do_dump |= LPFC_BSG_DMP_MBX_RD_BUF; 5912 pr_err("\nRead mbox buffer (x%x), " 5913 "nemb:0x%x, extbuf_seq:%d:\n", 5914 sta_tp, nemb_tp, ext_buf); 5915 } 5916 } 5917 if ((mbox_tp == mbox_wr) && (dma_tp == dma_mbox)) { 5918 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_MBX) { 5919 do_dump |= LPFC_BSG_DMP_MBX_WR_MBX; 5920 pr_err("\nWrite mbox command (x%x), " 5921 "nemb:0x%x, extbuf_cnt:%d:\n", 5922 sta_tp, nemb_tp, ext_buf); 5923 } 5924 } 5925 if ((mbox_tp == mbox_wr) && (dma_tp == dma_ebuf)) { 5926 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_BUF) { 5927 do_dump |= LPFC_BSG_DMP_MBX_WR_BUF; 5928 pr_err("\nWrite mbox buffer (x%x), " 5929 "nemb:0x%x, extbuf_seq:%d:\n", 5930 sta_tp, nemb_tp, ext_buf); 5931 } 5932 } 5933 5934 /* dump buffer content */ 5935 if (do_dump) { 5936 pword = (uint32_t *)dmabuf->virt; 5937 for (i = 0; i < *mbx_word_cnt; i++) { 5938 if (!(i % 8)) { 5939 if (i != 0) 5940 pr_err("%s\n", line_buf); 5941 len = 0; 5942 len += scnprintf(line_buf+len, 5943 LPFC_MBX_ACC_LBUF_SZ-len, 5944 "%03d: ", i); 5945 } 5946 len += scnprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len, 5947 "%08x ", (uint32_t)*pword); 5948 pword++; 5949 } 5950 if ((i - 1) % 8) 5951 pr_err("%s\n", line_buf); 5952 (*mbx_dump_cnt)--; 5953 } 5954 5955 /* Clean out command structure on reaching dump count */ 5956 if (*mbx_dump_cnt == 0) 5957 memset(&idiag, 0, sizeof(idiag)); 5958 return; 5959 #endif 5960 } 5961 5962 /* lpfc_idiag_mbxacc_dump_issue_mbox - idiag debugfs dump issue mailbox command 5963 * @phba: Pointer to HBA context object. 5964 * @dmabuf: Pointer to a DMA buffer descriptor. 5965 * 5966 * Description: 5967 * This routine dump a pass-through non-embedded mailbox command from issue 5968 * mailbox command. 5969 **/ 5970 void 5971 lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *phba, MAILBOX_t *pmbox) 5972 { 5973 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS 5974 uint32_t *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt, *mbx_mbox_cmd; 5975 char line_buf[LPFC_MBX_ACC_LBUF_SZ]; 5976 int len = 0; 5977 uint32_t *pword; 5978 uint8_t *pbyte; 5979 uint32_t i, j; 5980 5981 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP) 5982 return; 5983 5984 mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX]; 5985 mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX]; 5986 mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX]; 5987 mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX]; 5988 5989 if (!(*mbx_dump_map & LPFC_MBX_DMP_MBX_ALL) || 5990 (*mbx_dump_cnt == 0) || 5991 (*mbx_word_cnt == 0)) 5992 return; 5993 5994 if ((*mbx_mbox_cmd != LPFC_MBX_ALL_CMD) && 5995 (*mbx_mbox_cmd != pmbox->mbxCommand)) 5996 return; 5997 5998 /* dump buffer content */ 5999 if (*mbx_dump_map & LPFC_MBX_DMP_MBX_WORD) { 6000 pr_err("Mailbox command:0x%x dump by word:\n", 6001 pmbox->mbxCommand); 6002 pword = (uint32_t *)pmbox; 6003 for (i = 0; i < *mbx_word_cnt; i++) { 6004 if (!(i % 8)) { 6005 if (i != 0) 6006 pr_err("%s\n", line_buf); 6007 len = 0; 6008 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ); 6009 len += scnprintf(line_buf+len, 6010 LPFC_MBX_ACC_LBUF_SZ-len, 6011 "%03d: ", i); 6012 } 6013 len += scnprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len, 6014 "%08x ", 6015 ((uint32_t)*pword) & 0xffffffff); 6016 pword++; 6017 } 6018 if ((i - 1) % 8) 6019 pr_err("%s\n", line_buf); 6020 pr_err("\n"); 6021 } 6022 if (*mbx_dump_map & LPFC_MBX_DMP_MBX_BYTE) { 6023 pr_err("Mailbox command:0x%x dump by byte:\n", 6024 pmbox->mbxCommand); 6025 pbyte = (uint8_t *)pmbox; 6026 for (i = 0; i < *mbx_word_cnt; i++) { 6027 if (!(i % 8)) { 6028 if (i != 0) 6029 pr_err("%s\n", line_buf); 6030 len = 0; 6031 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ); 6032 len += scnprintf(line_buf+len, 6033 LPFC_MBX_ACC_LBUF_SZ-len, 6034 "%03d: ", i); 6035 } 6036 for (j = 0; j < 4; j++) { 6037 len += scnprintf(line_buf+len, 6038 LPFC_MBX_ACC_LBUF_SZ-len, 6039 "%02x", 6040 ((uint8_t)*pbyte) & 0xff); 6041 pbyte++; 6042 } 6043 len += scnprintf(line_buf+len, 6044 LPFC_MBX_ACC_LBUF_SZ-len, " "); 6045 } 6046 if ((i - 1) % 8) 6047 pr_err("%s\n", line_buf); 6048 pr_err("\n"); 6049 } 6050 (*mbx_dump_cnt)--; 6051 6052 /* Clean out command structure on reaching dump count */ 6053 if (*mbx_dump_cnt == 0) 6054 memset(&idiag, 0, sizeof(idiag)); 6055 return; 6056 #endif 6057 } 6058 6059 /** 6060 * lpfc_debugfs_initialize - Initialize debugfs for a vport 6061 * @vport: The vport pointer to initialize. 6062 * 6063 * Description: 6064 * When Debugfs is configured this routine sets up the lpfc debugfs file system. 6065 * If not already created, this routine will create the lpfc directory, and 6066 * lpfcX directory (for this HBA), and vportX directory for this vport. It will 6067 * also create each file used to access lpfc specific debugfs information. 6068 **/ 6069 inline void 6070 lpfc_debugfs_initialize(struct lpfc_vport *vport) 6071 { 6072 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS 6073 struct lpfc_hba *phba = vport->phba; 6074 char name[64]; 6075 uint32_t num, i; 6076 bool pport_setup = false; 6077 6078 if (!lpfc_debugfs_enable) 6079 return; 6080 6081 /* Setup lpfc root directory */ 6082 if (!lpfc_debugfs_root) { 6083 lpfc_debugfs_root = debugfs_create_dir("lpfc", NULL); 6084 lpfc_debugfs_hba_count = 0; 6085 if (IS_ERR(lpfc_debugfs_root)) { 6086 lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT, 6087 "0527 Cannot create debugfs lpfc\n"); 6088 return; 6089 } 6090 } 6091 if (!lpfc_debugfs_start_time) 6092 lpfc_debugfs_start_time = jiffies; 6093 6094 /* Setup funcX directory for specific HBA PCI function */ 6095 snprintf(name, sizeof(name), "fn%d", phba->brd_no); 6096 if (!phba->hba_debugfs_root) { 6097 pport_setup = true; 6098 phba->hba_debugfs_root = 6099 debugfs_create_dir(name, lpfc_debugfs_root); 6100 phba->debugfs_vport_count = 0; 6101 if (IS_ERR(phba->hba_debugfs_root)) { 6102 lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT, 6103 "0528 Cannot create debugfs %s\n", name); 6104 return; 6105 } 6106 lpfc_debugfs_hba_count++; 6107 6108 /* Multi-XRI pools */ 6109 debugfs_create_file("multixripools", 0644, 6110 phba->hba_debugfs_root, phba, 6111 &lpfc_debugfs_op_multixripools); 6112 6113 /* Congestion Info Buffer */ 6114 debugfs_create_file("cgn_buffer", 0644, phba->hba_debugfs_root, 6115 phba, &lpfc_cgn_buffer_op); 6116 6117 /* RX Monitor */ 6118 debugfs_create_file("rx_monitor", 0644, phba->hba_debugfs_root, 6119 phba, &lpfc_rx_monitor_op); 6120 6121 /* RAS log */ 6122 debugfs_create_file("ras_log", 0644, phba->hba_debugfs_root, 6123 phba, &lpfc_debugfs_ras_log); 6124 6125 /* Setup hbqinfo */ 6126 debugfs_create_file("hbqinfo", 0644, phba->hba_debugfs_root, 6127 phba, &lpfc_debugfs_op_hbqinfo); 6128 6129 #ifdef LPFC_HDWQ_LOCK_STAT 6130 /* Setup lockstat */ 6131 debugfs_create_file("lockstat", 0644, phba->hba_debugfs_root, 6132 phba, &lpfc_debugfs_op_lockstat); 6133 #endif 6134 if (phba->sli_rev < LPFC_SLI_REV4) { 6135 /* Setup dumpHBASlim */ 6136 debugfs_create_file("dumpHBASlim", 0644, 6137 phba->hba_debugfs_root, phba, 6138 &lpfc_debugfs_op_dumpHBASlim); 6139 } 6140 6141 if (phba->sli_rev < LPFC_SLI_REV4) { 6142 /* Setup dumpHostSlim */ 6143 debugfs_create_file("dumpHostSlim", 0644, 6144 phba->hba_debugfs_root, phba, 6145 &lpfc_debugfs_op_dumpHostSlim); 6146 } 6147 6148 /* Setup DIF Error Injections */ 6149 debugfs_create_file_aux_num("InjErrLBA", 0644, 6150 phba->hba_debugfs_root, phba, 6151 InjErrLBA, 6152 &lpfc_debugfs_op_dif_err); 6153 phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF; 6154 6155 debugfs_create_file_aux_num("InjErrNPortID", 0644, 6156 phba->hba_debugfs_root, phba, 6157 InjErrNPortID, 6158 &lpfc_debugfs_op_dif_err); 6159 6160 debugfs_create_file_aux_num("InjErrWWPN", 0644, 6161 phba->hba_debugfs_root, phba, 6162 InjErrWWPN, 6163 &lpfc_debugfs_op_dif_err); 6164 6165 debugfs_create_file_aux_num("writeGuardInjErr", 0644, 6166 phba->hba_debugfs_root, phba, 6167 writeGuard, 6168 &lpfc_debugfs_op_dif_err); 6169 6170 debugfs_create_file_aux_num("writeAppInjErr", 0644, 6171 phba->hba_debugfs_root, phba, 6172 writeApp, &lpfc_debugfs_op_dif_err); 6173 6174 debugfs_create_file_aux_num("writeRefInjErr", 0644, 6175 phba->hba_debugfs_root, phba, 6176 writeRef, &lpfc_debugfs_op_dif_err); 6177 6178 debugfs_create_file_aux_num("readGuardInjErr", 0644, 6179 phba->hba_debugfs_root, phba, 6180 readGuard, 6181 &lpfc_debugfs_op_dif_err); 6182 6183 debugfs_create_file_aux_num("readAppInjErr", 0644, 6184 phba->hba_debugfs_root, phba, 6185 readApp, &lpfc_debugfs_op_dif_err); 6186 6187 debugfs_create_file_aux_num("readRefInjErr", 0644, 6188 phba->hba_debugfs_root, phba, 6189 readRef, &lpfc_debugfs_op_dif_err); 6190 6191 /* Setup slow ring trace */ 6192 if (lpfc_debugfs_max_slow_ring_trc) { 6193 num = lpfc_debugfs_max_slow_ring_trc - 1; 6194 if (num & lpfc_debugfs_max_slow_ring_trc) { 6195 /* Change to be a power of 2 */ 6196 num = lpfc_debugfs_max_slow_ring_trc; 6197 i = 0; 6198 while (num > 1) { 6199 num = num >> 1; 6200 i++; 6201 } 6202 lpfc_debugfs_max_slow_ring_trc = (1 << i); 6203 pr_info("lpfc_debugfs_max_slow_ring_trc " 6204 "changed to %d\n", 6205 lpfc_debugfs_max_slow_ring_trc); 6206 } 6207 } 6208 6209 debugfs_create_file("slow_ring_trace", 0644, 6210 phba->hba_debugfs_root, phba, 6211 &lpfc_debugfs_op_slow_ring_trc); 6212 if (!phba->slow_ring_trc) { 6213 phba->slow_ring_trc = kcalloc( 6214 lpfc_debugfs_max_slow_ring_trc, 6215 sizeof(struct lpfc_debugfs_trc), 6216 GFP_KERNEL); 6217 if (!phba->slow_ring_trc) { 6218 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 6219 "0416 Cannot create debugfs " 6220 "slow_ring buffer\n"); 6221 goto out; 6222 } 6223 atomic_set(&phba->slow_ring_trc_cnt, 0); 6224 } 6225 6226 debugfs_create_file("nvmeio_trc", 0644, phba->hba_debugfs_root, 6227 phba, &lpfc_debugfs_op_nvmeio_trc); 6228 6229 atomic_set(&phba->nvmeio_trc_cnt, 0); 6230 if (lpfc_debugfs_max_nvmeio_trc) { 6231 num = lpfc_debugfs_max_nvmeio_trc - 1; 6232 if (num & lpfc_debugfs_max_nvmeio_trc) { 6233 /* Change to be a power of 2 */ 6234 num = lpfc_debugfs_max_nvmeio_trc; 6235 i = 0; 6236 while (num > 1) { 6237 num = num >> 1; 6238 i++; 6239 } 6240 lpfc_debugfs_max_nvmeio_trc = (1 << i); 6241 pr_info("lpfc_debugfs_max_nvmeio_trc changed " 6242 "to %d\n", 6243 lpfc_debugfs_max_nvmeio_trc); 6244 } 6245 phba->nvmeio_trc_size = lpfc_debugfs_max_nvmeio_trc; 6246 6247 /* Allocate trace buffer and initialize */ 6248 phba->nvmeio_trc = kzalloc( 6249 (sizeof(struct lpfc_debugfs_nvmeio_trc) * 6250 phba->nvmeio_trc_size), GFP_KERNEL); 6251 6252 if (!phba->nvmeio_trc) { 6253 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 6254 "0576 Cannot create debugfs " 6255 "nvmeio_trc buffer\n"); 6256 goto nvmeio_off; 6257 } 6258 phba->nvmeio_trc_on = 1; 6259 phba->nvmeio_trc_output_idx = 0; 6260 } else { 6261 nvmeio_off: 6262 phba->nvmeio_trc_size = 0; 6263 phba->nvmeio_trc_on = 0; 6264 phba->nvmeio_trc_output_idx = 0; 6265 phba->nvmeio_trc = NULL; 6266 } 6267 } 6268 6269 snprintf(name, sizeof(name), "vport%d", vport->vpi); 6270 if (!vport->vport_debugfs_root) { 6271 vport->vport_debugfs_root = 6272 debugfs_create_dir(name, phba->hba_debugfs_root); 6273 if (IS_ERR(vport->vport_debugfs_root)) { 6274 lpfc_vlog_msg(vport, KERN_WARNING, LOG_INIT, 6275 "0529 Cannot create debugfs %s\n", name); 6276 return; 6277 } 6278 phba->debugfs_vport_count++; 6279 } 6280 6281 if (lpfc_debugfs_max_disc_trc) { 6282 num = lpfc_debugfs_max_disc_trc - 1; 6283 if (num & lpfc_debugfs_max_disc_trc) { 6284 /* Change to be a power of 2 */ 6285 num = lpfc_debugfs_max_disc_trc; 6286 i = 0; 6287 while (num > 1) { 6288 num = num >> 1; 6289 i++; 6290 } 6291 lpfc_debugfs_max_disc_trc = (1 << i); 6292 pr_info("lpfc_debugfs_max_disc_trc changed to %d\n", 6293 lpfc_debugfs_max_disc_trc); 6294 } 6295 } 6296 6297 vport->disc_trc = kzalloc( 6298 (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc), 6299 GFP_KERNEL); 6300 6301 if (!vport->disc_trc) { 6302 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 6303 "0418 Cannot create debugfs disc trace " 6304 "buffer\n"); 6305 goto out; 6306 } 6307 atomic_set(&vport->disc_trc_cnt, 0); 6308 6309 debugfs_create_file("discovery_trace", 0644, vport->vport_debugfs_root, 6310 vport, &lpfc_debugfs_op_disc_trc); 6311 6312 debugfs_create_file("nodelist", 0644, vport->vport_debugfs_root, vport, 6313 &lpfc_debugfs_op_nodelist); 6314 6315 debugfs_create_file("nvmestat", 0644, vport->vport_debugfs_root, vport, 6316 &lpfc_debugfs_op_nvmestat); 6317 6318 debugfs_create_file("scsistat", 0644, vport->vport_debugfs_root, vport, 6319 &lpfc_debugfs_op_scsistat); 6320 6321 debugfs_create_file("ioktime", 0644, vport->vport_debugfs_root, vport, 6322 &lpfc_debugfs_op_ioktime); 6323 6324 debugfs_create_file("hdwqstat", 0644, vport->vport_debugfs_root, vport, 6325 &lpfc_debugfs_op_hdwqstat); 6326 6327 /* 6328 * The following section is for additional directories/files for the 6329 * physical port. 6330 */ 6331 6332 if (!pport_setup) 6333 return; 6334 6335 /* 6336 * iDiag debugfs root entry points for SLI4 device only 6337 */ 6338 if (phba->sli_rev < LPFC_SLI_REV4) 6339 return; 6340 6341 if (!phba->idiag_root) { 6342 phba->idiag_root = 6343 debugfs_create_dir("iDiag", phba->hba_debugfs_root); 6344 /* Initialize iDiag data structure */ 6345 memset(&idiag, 0, sizeof(idiag)); 6346 } 6347 6348 /* iDiag read PCI config space */ 6349 debugfs_create_file("pciCfg", 0644, phba->idiag_root, phba, 6350 &lpfc_idiag_op_pciCfg); 6351 idiag.offset.last_rd = 0; 6352 6353 /* iDiag PCI BAR access */ 6354 debugfs_create_file("barAcc", 0644, phba->idiag_root, phba, 6355 &lpfc_idiag_op_barAcc); 6356 idiag.offset.last_rd = 0; 6357 6358 /* iDiag get PCI function queue information */ 6359 debugfs_create_file("queInfo", 0444, phba->idiag_root, phba, 6360 &lpfc_idiag_op_queInfo); 6361 6362 /* iDiag access PCI function queue */ 6363 debugfs_create_file("queAcc", 0644, phba->idiag_root, phba, 6364 &lpfc_idiag_op_queAcc); 6365 6366 /* iDiag access PCI function doorbell registers */ 6367 debugfs_create_file("drbAcc", 0644, phba->idiag_root, phba, 6368 &lpfc_idiag_op_drbAcc); 6369 6370 /* iDiag access PCI function control registers */ 6371 debugfs_create_file("ctlAcc", 0644, phba->idiag_root, phba, 6372 &lpfc_idiag_op_ctlAcc); 6373 6374 /* iDiag access mbox commands */ 6375 debugfs_create_file("mbxAcc", 0644, phba->idiag_root, phba, 6376 &lpfc_idiag_op_mbxAcc); 6377 6378 /* iDiag extents access commands */ 6379 if (phba->sli4_hba.extents_in_use) { 6380 debugfs_create_file("extAcc", 0644, phba->idiag_root, phba, 6381 &lpfc_idiag_op_extAcc); 6382 } 6383 out: 6384 /* alloc'ed items are kfree'd in lpfc_debugfs_terminate */ 6385 return; 6386 #endif 6387 } 6388 6389 /** 6390 * lpfc_debugfs_terminate - Tear down debugfs infrastructure for this vport 6391 * @vport: The vport pointer to remove from debugfs. 6392 * 6393 * Description: 6394 * When Debugfs is configured this routine removes debugfs file system elements 6395 * that are specific to this vport. It also checks to see if there are any 6396 * users left for the debugfs directories associated with the HBA and driver. If 6397 * this is the last user of the HBA directory or driver directory then it will 6398 * remove those from the debugfs infrastructure as well. 6399 **/ 6400 inline void 6401 lpfc_debugfs_terminate(struct lpfc_vport *vport) 6402 { 6403 #ifdef CONFIG_SCSI_LPFC_DEBUG_FS 6404 struct lpfc_hba *phba = vport->phba; 6405 6406 kfree(vport->disc_trc); 6407 vport->disc_trc = NULL; 6408 6409 if (vport->vport_debugfs_root) { 6410 debugfs_remove(vport->vport_debugfs_root); /* vportX */ 6411 vport->vport_debugfs_root = NULL; 6412 phba->debugfs_vport_count--; 6413 } 6414 6415 if (!phba->debugfs_vport_count) { 6416 kfree(phba->slow_ring_trc); 6417 phba->slow_ring_trc = NULL; 6418 6419 kfree(phba->nvmeio_trc); 6420 phba->nvmeio_trc = NULL; 6421 6422 if (phba->hba_debugfs_root) { 6423 debugfs_remove(phba->hba_debugfs_root); /* fnX */ 6424 phba->hba_debugfs_root = NULL; 6425 lpfc_debugfs_hba_count--; 6426 } 6427 6428 if (!lpfc_debugfs_hba_count) { 6429 debugfs_remove(lpfc_debugfs_root); /* lpfc */ 6430 lpfc_debugfs_root = NULL; 6431 } 6432 } 6433 #endif 6434 return; 6435 } 6436 6437 /* 6438 * Driver debug utility routines outside of debugfs. The debug utility 6439 * routines implemented here is intended to be used in the instrumented 6440 * debug driver for debugging host or port issues. 6441 */ 6442 6443 /** 6444 * lpfc_debug_dump_all_queues - dump all the queues with a hba 6445 * @phba: Pointer to HBA context object. 6446 * 6447 * This function dumps entries of all the queues asociated with the @phba. 6448 **/ 6449 void 6450 lpfc_debug_dump_all_queues(struct lpfc_hba *phba) 6451 { 6452 int idx; 6453 6454 /* 6455 * Dump Work Queues (WQs) 6456 */ 6457 lpfc_debug_dump_wq(phba, DUMP_MBX, 0); 6458 lpfc_debug_dump_wq(phba, DUMP_ELS, 0); 6459 lpfc_debug_dump_wq(phba, DUMP_NVMELS, 0); 6460 6461 for (idx = 0; idx < phba->cfg_hdw_queue; idx++) 6462 lpfc_debug_dump_wq(phba, DUMP_IO, idx); 6463 6464 lpfc_debug_dump_hdr_rq(phba); 6465 lpfc_debug_dump_dat_rq(phba); 6466 /* 6467 * Dump Complete Queues (CQs) 6468 */ 6469 lpfc_debug_dump_cq(phba, DUMP_MBX, 0); 6470 lpfc_debug_dump_cq(phba, DUMP_ELS, 0); 6471 lpfc_debug_dump_cq(phba, DUMP_NVMELS, 0); 6472 6473 for (idx = 0; idx < phba->cfg_hdw_queue; idx++) 6474 lpfc_debug_dump_cq(phba, DUMP_IO, idx); 6475 6476 /* 6477 * Dump Event Queues (EQs) 6478 */ 6479 for (idx = 0; idx < phba->cfg_hdw_queue; idx++) 6480 lpfc_debug_dump_hba_eq(phba, idx); 6481 } 6482