File Index
Files and directories
Sign in
FILE

lpfc_debugfs.c

File preview with syntax highlighting.

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