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