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