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