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