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