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