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