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