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