aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_debugfs.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-30 14:36:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-30 14:36:02 -0400
commit6c6e3b828b2a13b923b9465fc4316c5bdc92291f (patch)
treeca027f7d7645c577ed76fcc8358163eb1689d8ae /drivers/scsi/lpfc/lpfc_debugfs.c
parentc11abbbaa3252875c5740a6880b9a1a6f1e2a870 (diff)
parentd272281c390eb6c3f1e70ed0337c9e619d99cd9c (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (71 commits) [SCSI] fcoe: cleanup cpu selection for incoming requests [SCSI] fcoe: add fip retry to avoid missing critical keep alive [SCSI] libfc: fix warn on in lport retry [SCSI] libfc: Remove the reference to FCP packet from scsi_cmnd in case of error [SCSI] libfc: cleanup sending SRR request [SCSI] libfc: two minor changes in comments [SCSI] libfc, fcoe: ignore rx frame with wrong xid info [SCSI] libfc: release exchg cache [SCSI] libfc: use FC_MAX_ERROR_CNT [SCSI] fcoe: remove unused ptype field in fcoe_rcv_info [SCSI] bnx2fc: Update copyright and bump version to 1.0.4 [SCSI] bnx2fc: Tx BDs cache in write tasks [SCSI] bnx2fc: Do not arm CQ when there are no CQEs [SCSI] bnx2fc: hold tgt lock when calling cmd_release [SCSI] bnx2fc: Enable support for sequence level error recovery [SCSI] bnx2fc: HSI changes for tape [SCSI] bnx2fc: Handle REC_TOV error code from firmware [SCSI] bnx2fc: REC/SRR link service request and response handling [SCSI] bnx2fc: Support 'sequence cleanup' task [SCSI] dh_rdac: Associate HBA and storage in rdac_controller to support partitions in storage ...
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_debugfs.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c1354
1 files changed, 1326 insertions, 28 deletions
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 30b25c5fdd7e..a0424dd90e40 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -48,6 +48,7 @@
48#include "lpfc_version.h" 48#include "lpfc_version.h"
49#include "lpfc_compat.h" 49#include "lpfc_compat.h"
50#include "lpfc_debugfs.h" 50#include "lpfc_debugfs.h"
51#include "lpfc_bsg.h"
51 52
52#ifdef CONFIG_SCSI_LPFC_DEBUG_FS 53#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
53/* 54/*
@@ -135,7 +136,11 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
135 int i, index, len, enable; 136 int i, index, len, enable;
136 uint32_t ms; 137 uint32_t ms;
137 struct lpfc_debugfs_trc *dtp; 138 struct lpfc_debugfs_trc *dtp;
138 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE]; 139 char *buffer;
140
141 buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
142 if (!buffer)
143 return 0;
139 144
140 enable = lpfc_debugfs_enable; 145 enable = lpfc_debugfs_enable;
141 lpfc_debugfs_enable = 0; 146 lpfc_debugfs_enable = 0;
@@ -167,6 +172,8 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
167 } 172 }
168 173
169 lpfc_debugfs_enable = enable; 174 lpfc_debugfs_enable = enable;
175 kfree(buffer);
176
170 return len; 177 return len;
171} 178}
172 179
@@ -195,8 +202,11 @@ lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
195 int i, index, len, enable; 202 int i, index, len, enable;
196 uint32_t ms; 203 uint32_t ms;
197 struct lpfc_debugfs_trc *dtp; 204 struct lpfc_debugfs_trc *dtp;
198 char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE]; 205 char *buffer;
199 206
207 buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
208 if (!buffer)
209 return 0;
200 210
201 enable = lpfc_debugfs_enable; 211 enable = lpfc_debugfs_enable;
202 lpfc_debugfs_enable = 0; 212 lpfc_debugfs_enable = 0;
@@ -228,6 +238,8 @@ lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
228 } 238 }
229 239
230 lpfc_debugfs_enable = enable; 240 lpfc_debugfs_enable = enable;
241 kfree(buffer);
242
231 return len; 243 return len;
232} 244}
233 245
@@ -378,7 +390,11 @@ lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
378 int len = 0; 390 int len = 0;
379 int i, off; 391 int i, off;
380 uint32_t *ptr; 392 uint32_t *ptr;
381 char buffer[1024]; 393 char *buffer;
394
395 buffer = kmalloc(1024, GFP_KERNEL);
396 if (!buffer)
397 return 0;
382 398
383 off = 0; 399 off = 0;
384 spin_lock_irq(&phba->hbalock); 400 spin_lock_irq(&phba->hbalock);
@@ -407,6 +423,8 @@ lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
407 } 423 }
408 424
409 spin_unlock_irq(&phba->hbalock); 425 spin_unlock_irq(&phba->hbalock);
426 kfree(buffer);
427
410 return len; 428 return len;
411} 429}
412 430
@@ -1327,8 +1345,8 @@ lpfc_idiag_pcicfg_read(struct file *file, char __user *buf, size_t nbytes,
1327 return 0; 1345 return 0;
1328 1346
1329 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) { 1347 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
1330 where = idiag.cmd.data[0]; 1348 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
1331 count = idiag.cmd.data[1]; 1349 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
1332 } else 1350 } else
1333 return 0; 1351 return 0;
1334 1352
@@ -1373,6 +1391,11 @@ pcicfg_browse:
1373 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, 1391 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1374 "%08x ", u32val); 1392 "%08x ", u32val);
1375 offset += sizeof(uint32_t); 1393 offset += sizeof(uint32_t);
1394 if (offset >= LPFC_PCI_CFG_SIZE) {
1395 len += snprintf(pbuffer+len,
1396 LPFC_PCI_CFG_SIZE-len, "\n");
1397 break;
1398 }
1376 index -= sizeof(uint32_t); 1399 index -= sizeof(uint32_t);
1377 if (!index) 1400 if (!index)
1378 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len, 1401 len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
@@ -1385,8 +1408,11 @@ pcicfg_browse:
1385 } 1408 }
1386 1409
1387 /* Set up the offset for next portion of pci cfg read */ 1410 /* Set up the offset for next portion of pci cfg read */
1388 idiag.offset.last_rd += LPFC_PCI_CFG_RD_SIZE; 1411 if (index == 0) {
1389 if (idiag.offset.last_rd >= LPFC_PCI_CFG_SIZE) 1412 idiag.offset.last_rd += LPFC_PCI_CFG_RD_SIZE;
1413 if (idiag.offset.last_rd >= LPFC_PCI_CFG_SIZE)
1414 idiag.offset.last_rd = 0;
1415 } else
1390 idiag.offset.last_rd = 0; 1416 idiag.offset.last_rd = 0;
1391 1417
1392 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len); 1418 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
@@ -1439,8 +1465,8 @@ lpfc_idiag_pcicfg_write(struct file *file, const char __user *buf,
1439 if (rc != LPFC_PCI_CFG_RD_CMD_ARG) 1465 if (rc != LPFC_PCI_CFG_RD_CMD_ARG)
1440 goto error_out; 1466 goto error_out;
1441 /* Read command from PCI config space, set up command fields */ 1467 /* Read command from PCI config space, set up command fields */
1442 where = idiag.cmd.data[0]; 1468 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
1443 count = idiag.cmd.data[1]; 1469 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
1444 if (count == LPFC_PCI_CFG_BROWSE) { 1470 if (count == LPFC_PCI_CFG_BROWSE) {
1445 if (where % sizeof(uint32_t)) 1471 if (where % sizeof(uint32_t))
1446 goto error_out; 1472 goto error_out;
@@ -1475,9 +1501,9 @@ lpfc_idiag_pcicfg_write(struct file *file, const char __user *buf,
1475 if (rc != LPFC_PCI_CFG_WR_CMD_ARG) 1501 if (rc != LPFC_PCI_CFG_WR_CMD_ARG)
1476 goto error_out; 1502 goto error_out;
1477 /* Write command to PCI config space, read-modify-write */ 1503 /* Write command to PCI config space, read-modify-write */
1478 where = idiag.cmd.data[0]; 1504 where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
1479 count = idiag.cmd.data[1]; 1505 count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
1480 value = idiag.cmd.data[2]; 1506 value = idiag.cmd.data[IDIAG_PCICFG_VALUE_INDX];
1481 /* Sanity checks */ 1507 /* Sanity checks */
1482 if ((count != sizeof(uint8_t)) && 1508 if ((count != sizeof(uint8_t)) &&
1483 (count != sizeof(uint16_t)) && 1509 (count != sizeof(uint16_t)) &&
@@ -1570,6 +1596,292 @@ error_out:
1570} 1596}
1571 1597
1572/** 1598/**
1599 * lpfc_idiag_baracc_read - idiag debugfs pci bar access read
1600 * @file: The file pointer to read from.
1601 * @buf: The buffer to copy the data to.
1602 * @nbytes: The number of bytes to read.
1603 * @ppos: The position in the file to start reading from.
1604 *
1605 * Description:
1606 * This routine reads data from the @phba pci bar memory mapped space
1607 * according to the idiag command, and copies to user @buf.
1608 *
1609 * Returns:
1610 * This function returns the amount of data that was read (this could be less
1611 * than @nbytes if the end of the file was reached) or a negative error value.
1612 **/
1613static ssize_t
1614lpfc_idiag_baracc_read(struct file *file, char __user *buf, size_t nbytes,
1615 loff_t *ppos)
1616{
1617 struct lpfc_debug *debug = file->private_data;
1618 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1619 int offset_label, offset, offset_run, len = 0, index;
1620 int bar_num, acc_range, bar_size;
1621 char *pbuffer;
1622 void __iomem *mem_mapped_bar;
1623 uint32_t if_type;
1624 struct pci_dev *pdev;
1625 uint32_t u32val;
1626
1627 pdev = phba->pcidev;
1628 if (!pdev)
1629 return 0;
1630
1631 /* This is a user read operation */
1632 debug->op = LPFC_IDIAG_OP_RD;
1633
1634 if (!debug->buffer)
1635 debug->buffer = kmalloc(LPFC_PCI_BAR_RD_BUF_SIZE, GFP_KERNEL);
1636 if (!debug->buffer)
1637 return 0;
1638 pbuffer = debug->buffer;
1639
1640 if (*ppos)
1641 return 0;
1642
1643 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
1644 bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
1645 offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
1646 acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
1647 bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
1648 } else
1649 return 0;
1650
1651 if (acc_range == 0)
1652 return 0;
1653
1654 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
1655 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
1656 if (bar_num == IDIAG_BARACC_BAR_0)
1657 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
1658 else if (bar_num == IDIAG_BARACC_BAR_1)
1659 mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
1660 else if (bar_num == IDIAG_BARACC_BAR_2)
1661 mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
1662 else
1663 return 0;
1664 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
1665 if (bar_num == IDIAG_BARACC_BAR_0)
1666 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
1667 else
1668 return 0;
1669 } else
1670 return 0;
1671
1672 /* Read single PCI bar space register */
1673 if (acc_range == SINGLE_WORD) {
1674 offset_run = offset;
1675 u32val = readl(mem_mapped_bar + offset_run);
1676 len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
1677 "%05x: %08x\n", offset_run, u32val);
1678 } else
1679 goto baracc_browse;
1680
1681 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1682
1683baracc_browse:
1684
1685 /* Browse all PCI bar space registers */
1686 offset_label = idiag.offset.last_rd;
1687 offset_run = offset_label;
1688
1689 /* Read PCI bar memory mapped space */
1690 len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
1691 "%05x: ", offset_label);
1692 index = LPFC_PCI_BAR_RD_SIZE;
1693 while (index > 0) {
1694 u32val = readl(mem_mapped_bar + offset_run);
1695 len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
1696 "%08x ", u32val);
1697 offset_run += sizeof(uint32_t);
1698 if (acc_range == LPFC_PCI_BAR_BROWSE) {
1699 if (offset_run >= bar_size) {
1700 len += snprintf(pbuffer+len,
1701 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
1702 break;
1703 }
1704 } else {
1705 if (offset_run >= offset +
1706 (acc_range * sizeof(uint32_t))) {
1707 len += snprintf(pbuffer+len,
1708 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
1709 break;
1710 }
1711 }
1712 index -= sizeof(uint32_t);
1713 if (!index)
1714 len += snprintf(pbuffer+len,
1715 LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
1716 else if (!(index % (8 * sizeof(uint32_t)))) {
1717 offset_label += (8 * sizeof(uint32_t));
1718 len += snprintf(pbuffer+len,
1719 LPFC_PCI_BAR_RD_BUF_SIZE-len,
1720 "\n%05x: ", offset_label);
1721 }
1722 }
1723
1724 /* Set up the offset for next portion of pci bar read */
1725 if (index == 0) {
1726 idiag.offset.last_rd += LPFC_PCI_BAR_RD_SIZE;
1727 if (acc_range == LPFC_PCI_BAR_BROWSE) {
1728 if (idiag.offset.last_rd >= bar_size)
1729 idiag.offset.last_rd = 0;
1730 } else {
1731 if (offset_run >= offset +
1732 (acc_range * sizeof(uint32_t)))
1733 idiag.offset.last_rd = offset;
1734 }
1735 } else {
1736 if (acc_range == LPFC_PCI_BAR_BROWSE)
1737 idiag.offset.last_rd = 0;
1738 else
1739 idiag.offset.last_rd = offset;
1740 }
1741
1742 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1743}
1744
1745/**
1746 * lpfc_idiag_baracc_write - Syntax check and set up idiag bar access commands
1747 * @file: The file pointer to read from.
1748 * @buf: The buffer to copy the user data from.
1749 * @nbytes: The number of bytes to get.
1750 * @ppos: The position in the file to start reading from.
1751 *
1752 * This routine get the debugfs idiag command struct from user space and
1753 * then perform the syntax check for PCI bar memory mapped space read or
1754 * write command accordingly. In the case of PCI bar memory mapped space
1755 * read command, it sets up the command in the idiag command struct for
1756 * the debugfs read operation. In the case of PCI bar memorpy mapped space
1757 * write operation, it executes the write operation into the PCI bar memory
1758 * mapped space accordingly.
1759 *
1760 * It returns the @nbytges passing in from debugfs user space when successful.
1761 * In case of error conditions, it returns proper error code back to the user
1762 * space.
1763 */
1764static ssize_t
1765lpfc_idiag_baracc_write(struct file *file, const char __user *buf,
1766 size_t nbytes, loff_t *ppos)
1767{
1768 struct lpfc_debug *debug = file->private_data;
1769 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
1770 uint32_t bar_num, bar_size, offset, value, acc_range;
1771 struct pci_dev *pdev;
1772 void __iomem *mem_mapped_bar;
1773 uint32_t if_type;
1774 uint32_t u32val;
1775 int rc;
1776
1777 pdev = phba->pcidev;
1778 if (!pdev)
1779 return -EFAULT;
1780
1781 /* This is a user write operation */
1782 debug->op = LPFC_IDIAG_OP_WR;
1783
1784 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
1785 if (rc < 0)
1786 return rc;
1787
1788 if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
1789 bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
1790
1791 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
1792 if ((bar_num != IDIAG_BARACC_BAR_0) &&
1793 (bar_num != IDIAG_BARACC_BAR_1) &&
1794 (bar_num != IDIAG_BARACC_BAR_2))
1795 goto error_out;
1796 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
1797 if (bar_num != IDIAG_BARACC_BAR_0)
1798 goto error_out;
1799 } else
1800 goto error_out;
1801
1802 if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
1803 if (bar_num == IDIAG_BARACC_BAR_0) {
1804 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
1805 LPFC_PCI_IF0_BAR0_SIZE;
1806 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
1807 } else if (bar_num == IDIAG_BARACC_BAR_1) {
1808 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
1809 LPFC_PCI_IF0_BAR1_SIZE;
1810 mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
1811 } else if (bar_num == IDIAG_BARACC_BAR_2) {
1812 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
1813 LPFC_PCI_IF0_BAR2_SIZE;
1814 mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
1815 } else
1816 goto error_out;
1817 } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
1818 if (bar_num == IDIAG_BARACC_BAR_0) {
1819 idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
1820 LPFC_PCI_IF2_BAR0_SIZE;
1821 mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
1822 } else
1823 goto error_out;
1824 } else
1825 goto error_out;
1826
1827 offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
1828 if (offset % sizeof(uint32_t))
1829 goto error_out;
1830
1831 bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
1832 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
1833 /* Sanity check on PCI config read command line arguments */
1834 if (rc != LPFC_PCI_BAR_RD_CMD_ARG)
1835 goto error_out;
1836 acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
1837 if (acc_range == LPFC_PCI_BAR_BROWSE) {
1838 if (offset > bar_size - sizeof(uint32_t))
1839 goto error_out;
1840 /* Starting offset to browse */
1841 idiag.offset.last_rd = offset;
1842 } else if (acc_range > SINGLE_WORD) {
1843 if (offset + acc_range * sizeof(uint32_t) > bar_size)
1844 goto error_out;
1845 /* Starting offset to browse */
1846 idiag.offset.last_rd = offset;
1847 } else if (acc_range != SINGLE_WORD)
1848 goto error_out;
1849 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR ||
1850 idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST ||
1851 idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
1852 /* Sanity check on PCI bar write command line arguments */
1853 if (rc != LPFC_PCI_BAR_WR_CMD_ARG)
1854 goto error_out;
1855 /* Write command to PCI bar space, read-modify-write */
1856 acc_range = SINGLE_WORD;
1857 value = idiag.cmd.data[IDIAG_BARACC_REG_VAL_INDX];
1858 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR) {
1859 writel(value, mem_mapped_bar + offset);
1860 readl(mem_mapped_bar + offset);
1861 }
1862 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST) {
1863 u32val = readl(mem_mapped_bar + offset);
1864 u32val |= value;
1865 writel(u32val, mem_mapped_bar + offset);
1866 readl(mem_mapped_bar + offset);
1867 }
1868 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
1869 u32val = readl(mem_mapped_bar + offset);
1870 u32val &= ~value;
1871 writel(u32val, mem_mapped_bar + offset);
1872 readl(mem_mapped_bar + offset);
1873 }
1874 } else
1875 /* All other opecodes are illegal for now */
1876 goto error_out;
1877
1878 return nbytes;
1879error_out:
1880 memset(&idiag, 0, sizeof(idiag));
1881 return -EINVAL;
1882}
1883
1884/**
1573 * lpfc_idiag_queinfo_read - idiag debugfs read queue information 1885 * lpfc_idiag_queinfo_read - idiag debugfs read queue information
1574 * @file: The file pointer to read from. 1886 * @file: The file pointer to read from.
1575 * @buf: The buffer to copy the data to. 1887 * @buf: The buffer to copy the data to.
@@ -1871,8 +2183,8 @@ lpfc_idiag_queacc_read(struct file *file, char __user *buf, size_t nbytes,
1871 return 0; 2183 return 0;
1872 2184
1873 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) { 2185 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
1874 index = idiag.cmd.data[2]; 2186 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
1875 count = idiag.cmd.data[3]; 2187 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
1876 pque = (struct lpfc_queue *)idiag.ptr_private; 2188 pque = (struct lpfc_queue *)idiag.ptr_private;
1877 } else 2189 } else
1878 return 0; 2190 return 0;
@@ -1944,12 +2256,12 @@ lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
1944 return rc; 2256 return rc;
1945 2257
1946 /* Get and sanity check on command feilds */ 2258 /* Get and sanity check on command feilds */
1947 quetp = idiag.cmd.data[0]; 2259 quetp = idiag.cmd.data[IDIAG_QUEACC_QUETP_INDX];
1948 queid = idiag.cmd.data[1]; 2260 queid = idiag.cmd.data[IDIAG_QUEACC_QUEID_INDX];
1949 index = idiag.cmd.data[2]; 2261 index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
1950 count = idiag.cmd.data[3]; 2262 count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
1951 offset = idiag.cmd.data[4]; 2263 offset = idiag.cmd.data[IDIAG_QUEACC_OFFST_INDX];
1952 value = idiag.cmd.data[5]; 2264 value = idiag.cmd.data[IDIAG_QUEACC_VALUE_INDX];
1953 2265
1954 /* Sanity check on command line arguments */ 2266 /* Sanity check on command line arguments */
1955 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR || 2267 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
@@ -2218,7 +2530,7 @@ lpfc_idiag_drbacc_read(struct file *file, char __user *buf, size_t nbytes,
2218 return 0; 2530 return 0;
2219 2531
2220 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD) 2532 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD)
2221 drb_reg_id = idiag.cmd.data[0]; 2533 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
2222 else 2534 else
2223 return 0; 2535 return 0;
2224 2536
@@ -2257,7 +2569,7 @@ lpfc_idiag_drbacc_write(struct file *file, const char __user *buf,
2257{ 2569{
2258 struct lpfc_debug *debug = file->private_data; 2570 struct lpfc_debug *debug = file->private_data;
2259 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private; 2571 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2260 uint32_t drb_reg_id, value, reg_val; 2572 uint32_t drb_reg_id, value, reg_val = 0;
2261 void __iomem *drb_reg; 2573 void __iomem *drb_reg;
2262 int rc; 2574 int rc;
2263 2575
@@ -2269,8 +2581,8 @@ lpfc_idiag_drbacc_write(struct file *file, const char __user *buf,
2269 return rc; 2581 return rc;
2270 2582
2271 /* Sanity check on command line arguments */ 2583 /* Sanity check on command line arguments */
2272 drb_reg_id = idiag.cmd.data[0]; 2584 drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
2273 value = idiag.cmd.data[1]; 2585 value = idiag.cmd.data[IDIAG_DRBACC_VALUE_INDX];
2274 2586
2275 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR || 2587 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
2276 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST || 2588 idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
@@ -2330,6 +2642,679 @@ error_out:
2330 return -EINVAL; 2642 return -EINVAL;
2331} 2643}
2332 2644
2645/**
2646 * lpfc_idiag_ctlacc_read_reg - idiag debugfs read a control registers
2647 * @phba: The pointer to hba structure.
2648 * @pbuffer: The pointer to the buffer to copy the data to.
2649 * @len: The lenght of bytes to copied.
2650 * @drbregid: The id to doorbell registers.
2651 *
2652 * Description:
2653 * This routine reads a control register and copies its content to the
2654 * user buffer pointed to by @pbuffer.
2655 *
2656 * Returns:
2657 * This function returns the amount of data that was copied into @pbuffer.
2658 **/
2659static int
2660lpfc_idiag_ctlacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
2661 int len, uint32_t ctlregid)
2662{
2663
2664 if (!pbuffer)
2665 return 0;
2666
2667 switch (ctlregid) {
2668 case LPFC_CTL_PORT_SEM:
2669 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2670 "Port SemReg: 0x%08x\n",
2671 readl(phba->sli4_hba.conf_regs_memmap_p +
2672 LPFC_CTL_PORT_SEM_OFFSET));
2673 break;
2674 case LPFC_CTL_PORT_STA:
2675 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2676 "Port StaReg: 0x%08x\n",
2677 readl(phba->sli4_hba.conf_regs_memmap_p +
2678 LPFC_CTL_PORT_STA_OFFSET));
2679 break;
2680 case LPFC_CTL_PORT_CTL:
2681 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2682 "Port CtlReg: 0x%08x\n",
2683 readl(phba->sli4_hba.conf_regs_memmap_p +
2684 LPFC_CTL_PORT_CTL_OFFSET));
2685 break;
2686 case LPFC_CTL_PORT_ER1:
2687 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2688 "Port Er1Reg: 0x%08x\n",
2689 readl(phba->sli4_hba.conf_regs_memmap_p +
2690 LPFC_CTL_PORT_ER1_OFFSET));
2691 break;
2692 case LPFC_CTL_PORT_ER2:
2693 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2694 "Port Er2Reg: 0x%08x\n",
2695 readl(phba->sli4_hba.conf_regs_memmap_p +
2696 LPFC_CTL_PORT_ER2_OFFSET));
2697 break;
2698 case LPFC_CTL_PDEV_CTL:
2699 len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
2700 "PDev CtlReg: 0x%08x\n",
2701 readl(phba->sli4_hba.conf_regs_memmap_p +
2702 LPFC_CTL_PDEV_CTL_OFFSET));
2703 break;
2704 default:
2705 break;
2706 }
2707 return len;
2708}
2709
2710/**
2711 * lpfc_idiag_ctlacc_read - idiag debugfs read port and device control register
2712 * @file: The file pointer to read from.
2713 * @buf: The buffer to copy the data to.
2714 * @nbytes: The number of bytes to read.
2715 * @ppos: The position in the file to start reading from.
2716 *
2717 * Description:
2718 * This routine reads data from the @phba port and device registers according
2719 * to the idiag command, and copies to user @buf.
2720 *
2721 * Returns:
2722 * This function returns the amount of data that was read (this could be less
2723 * than @nbytes if the end of the file was reached) or a negative error value.
2724 **/
2725static ssize_t
2726lpfc_idiag_ctlacc_read(struct file *file, char __user *buf, size_t nbytes,
2727 loff_t *ppos)
2728{
2729 struct lpfc_debug *debug = file->private_data;
2730 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2731 uint32_t ctl_reg_id, i;
2732 char *pbuffer;
2733 int len = 0;
2734
2735 /* This is a user read operation */
2736 debug->op = LPFC_IDIAG_OP_RD;
2737
2738 if (!debug->buffer)
2739 debug->buffer = kmalloc(LPFC_CTL_ACC_BUF_SIZE, GFP_KERNEL);
2740 if (!debug->buffer)
2741 return 0;
2742 pbuffer = debug->buffer;
2743
2744 if (*ppos)
2745 return 0;
2746
2747 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD)
2748 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
2749 else
2750 return 0;
2751
2752 if (ctl_reg_id == LPFC_CTL_ACC_ALL)
2753 for (i = 1; i <= LPFC_CTL_MAX; i++)
2754 len = lpfc_idiag_ctlacc_read_reg(phba,
2755 pbuffer, len, i);
2756 else
2757 len = lpfc_idiag_ctlacc_read_reg(phba,
2758 pbuffer, len, ctl_reg_id);
2759
2760 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2761}
2762
2763/**
2764 * lpfc_idiag_ctlacc_write - Syntax check and set up idiag ctlacc commands
2765 * @file: The file pointer to read from.
2766 * @buf: The buffer to copy the user data from.
2767 * @nbytes: The number of bytes to get.
2768 * @ppos: The position in the file to start reading from.
2769 *
2770 * This routine get the debugfs idiag command struct from user space and then
2771 * perform the syntax check for port and device control register read (dump)
2772 * or write (set) command accordingly.
2773 *
2774 * It returns the @nbytges passing in from debugfs user space when successful.
2775 * In case of error conditions, it returns proper error code back to the user
2776 * space.
2777 **/
2778static ssize_t
2779lpfc_idiag_ctlacc_write(struct file *file, const char __user *buf,
2780 size_t nbytes, loff_t *ppos)
2781{
2782 struct lpfc_debug *debug = file->private_data;
2783 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2784 uint32_t ctl_reg_id, value, reg_val = 0;
2785 void __iomem *ctl_reg;
2786 int rc;
2787
2788 /* This is a user write operation */
2789 debug->op = LPFC_IDIAG_OP_WR;
2790
2791 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
2792 if (rc < 0)
2793 return rc;
2794
2795 /* Sanity check on command line arguments */
2796 ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
2797 value = idiag.cmd.data[IDIAG_CTLACC_VALUE_INDX];
2798
2799 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
2800 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
2801 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
2802 if (rc != LPFC_CTL_ACC_WR_CMD_ARG)
2803 goto error_out;
2804 if (ctl_reg_id > LPFC_CTL_MAX)
2805 goto error_out;
2806 } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD) {
2807 if (rc != LPFC_CTL_ACC_RD_CMD_ARG)
2808 goto error_out;
2809 if ((ctl_reg_id > LPFC_CTL_MAX) &&
2810 (ctl_reg_id != LPFC_CTL_ACC_ALL))
2811 goto error_out;
2812 } else
2813 goto error_out;
2814
2815 /* Perform the write access operation */
2816 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
2817 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
2818 idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
2819 switch (ctl_reg_id) {
2820 case LPFC_CTL_PORT_SEM:
2821 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
2822 LPFC_CTL_PORT_SEM_OFFSET;
2823 break;
2824 case LPFC_CTL_PORT_STA:
2825 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
2826 LPFC_CTL_PORT_STA_OFFSET;
2827 break;
2828 case LPFC_CTL_PORT_CTL:
2829 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
2830 LPFC_CTL_PORT_CTL_OFFSET;
2831 break;
2832 case LPFC_CTL_PORT_ER1:
2833 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
2834 LPFC_CTL_PORT_ER1_OFFSET;
2835 break;
2836 case LPFC_CTL_PORT_ER2:
2837 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
2838 LPFC_CTL_PORT_ER2_OFFSET;
2839 break;
2840 case LPFC_CTL_PDEV_CTL:
2841 ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
2842 LPFC_CTL_PDEV_CTL_OFFSET;
2843 break;
2844 default:
2845 goto error_out;
2846 }
2847
2848 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR)
2849 reg_val = value;
2850 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST) {
2851 reg_val = readl(ctl_reg);
2852 reg_val |= value;
2853 }
2854 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
2855 reg_val = readl(ctl_reg);
2856 reg_val &= ~value;
2857 }
2858 writel(reg_val, ctl_reg);
2859 readl(ctl_reg); /* flush */
2860 }
2861 return nbytes;
2862
2863error_out:
2864 /* Clean out command structure on command error out */
2865 memset(&idiag, 0, sizeof(idiag));
2866 return -EINVAL;
2867}
2868
2869/**
2870 * lpfc_idiag_mbxacc_get_setup - idiag debugfs get mailbox access setup
2871 * @phba: Pointer to HBA context object.
2872 * @pbuffer: Pointer to data buffer.
2873 *
2874 * Description:
2875 * This routine gets the driver mailbox access debugfs setup information.
2876 *
2877 * Returns:
2878 * This function returns the amount of data that was read (this could be less
2879 * than @nbytes if the end of the file was reached) or a negative error value.
2880 **/
2881static int
2882lpfc_idiag_mbxacc_get_setup(struct lpfc_hba *phba, char *pbuffer)
2883{
2884 uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
2885 int len = 0;
2886
2887 mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
2888 mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
2889 mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
2890 mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
2891
2892 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
2893 "mbx_dump_map: 0x%08x\n", mbx_dump_map);
2894 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
2895 "mbx_dump_cnt: %04d\n", mbx_dump_cnt);
2896 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
2897 "mbx_word_cnt: %04d\n", mbx_word_cnt);
2898 len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
2899 "mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd);
2900
2901 return len;
2902}
2903
2904/**
2905 * lpfc_idiag_mbxacc_read - idiag debugfs read on mailbox access
2906 * @file: The file pointer to read from.
2907 * @buf: The buffer to copy the data to.
2908 * @nbytes: The number of bytes to read.
2909 * @ppos: The position in the file to start reading from.
2910 *
2911 * Description:
2912 * This routine reads data from the @phba driver mailbox access debugfs setup
2913 * information.
2914 *
2915 * Returns:
2916 * This function returns the amount of data that was read (this could be less
2917 * than @nbytes if the end of the file was reached) or a negative error value.
2918 **/
2919static ssize_t
2920lpfc_idiag_mbxacc_read(struct file *file, char __user *buf, size_t nbytes,
2921 loff_t *ppos)
2922{
2923 struct lpfc_debug *debug = file->private_data;
2924 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2925 char *pbuffer;
2926 int len = 0;
2927
2928 /* This is a user read operation */
2929 debug->op = LPFC_IDIAG_OP_RD;
2930
2931 if (!debug->buffer)
2932 debug->buffer = kmalloc(LPFC_MBX_ACC_BUF_SIZE, GFP_KERNEL);
2933 if (!debug->buffer)
2934 return 0;
2935 pbuffer = debug->buffer;
2936
2937 if (*ppos)
2938 return 0;
2939
2940 if ((idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP) &&
2941 (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP))
2942 return 0;
2943
2944 len = lpfc_idiag_mbxacc_get_setup(phba, pbuffer);
2945
2946 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
2947}
2948
2949/**
2950 * lpfc_idiag_mbxacc_write - Syntax check and set up idiag mbxacc commands
2951 * @file: The file pointer to read from.
2952 * @buf: The buffer to copy the user data from.
2953 * @nbytes: The number of bytes to get.
2954 * @ppos: The position in the file to start reading from.
2955 *
2956 * This routine get the debugfs idiag command struct from user space and then
2957 * perform the syntax check for driver mailbox command (dump) and sets up the
2958 * necessary states in the idiag command struct accordingly.
2959 *
2960 * It returns the @nbytges passing in from debugfs user space when successful.
2961 * In case of error conditions, it returns proper error code back to the user
2962 * space.
2963 **/
2964static ssize_t
2965lpfc_idiag_mbxacc_write(struct file *file, const char __user *buf,
2966 size_t nbytes, loff_t *ppos)
2967{
2968 struct lpfc_debug *debug = file->private_data;
2969 uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
2970 int rc;
2971
2972 /* This is a user write operation */
2973 debug->op = LPFC_IDIAG_OP_WR;
2974
2975 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
2976 if (rc < 0)
2977 return rc;
2978
2979 /* Sanity check on command line arguments */
2980 mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
2981 mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
2982 mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
2983 mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
2984
2985 if (idiag.cmd.opcode == LPFC_IDIAG_CMD_MBXACC_DP) {
2986 if (!(mbx_dump_map & LPFC_MBX_DMP_MBX_ALL))
2987 goto error_out;
2988 if ((mbx_dump_map & ~LPFC_MBX_DMP_MBX_ALL) &&
2989 (mbx_dump_map != LPFC_MBX_DMP_ALL))
2990 goto error_out;
2991 if (mbx_word_cnt > sizeof(MAILBOX_t))
2992 goto error_out;
2993 } else if (idiag.cmd.opcode == LPFC_IDIAG_BSG_MBXACC_DP) {
2994 if (!(mbx_dump_map & LPFC_BSG_DMP_MBX_ALL))
2995 goto error_out;
2996 if ((mbx_dump_map & ~LPFC_BSG_DMP_MBX_ALL) &&
2997 (mbx_dump_map != LPFC_MBX_DMP_ALL))
2998 goto error_out;
2999 if (mbx_word_cnt > (BSG_MBOX_SIZE)/4)
3000 goto error_out;
3001 if (mbx_mbox_cmd != 0x9b)
3002 goto error_out;
3003 } else
3004 goto error_out;
3005
3006 if (mbx_word_cnt == 0)
3007 goto error_out;
3008 if (rc != LPFC_MBX_DMP_ARG)
3009 goto error_out;
3010 if (mbx_mbox_cmd & ~0xff)
3011 goto error_out;
3012
3013 /* condition for stop mailbox dump */
3014 if (mbx_dump_cnt == 0)
3015 goto reset_out;
3016
3017 return nbytes;
3018
3019reset_out:
3020 /* Clean out command structure on command error out */
3021 memset(&idiag, 0, sizeof(idiag));
3022 return nbytes;
3023
3024error_out:
3025 /* Clean out command structure on command error out */
3026 memset(&idiag, 0, sizeof(idiag));
3027 return -EINVAL;
3028}
3029
3030/**
3031 * lpfc_idiag_extacc_avail_get - get the available extents information
3032 * @phba: pointer to lpfc hba data structure.
3033 * @pbuffer: pointer to internal buffer.
3034 * @len: length into the internal buffer data has been copied.
3035 *
3036 * Description:
3037 * This routine is to get the available extent information.
3038 *
3039 * Returns:
3040 * overall lenth of the data read into the internal buffer.
3041 **/
3042static int
3043lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len)
3044{
3045 uint16_t ext_cnt, ext_size;
3046
3047 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3048 "\nAvailable Extents Information:\n");
3049
3050 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3051 "\tPort Available VPI extents: ");
3052 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VPI,
3053 &ext_cnt, &ext_size);
3054 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3055 "Count %3d, Size %3d\n", ext_cnt, ext_size);
3056
3057 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3058 "\tPort Available VFI extents: ");
3059 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VFI,
3060 &ext_cnt, &ext_size);
3061 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3062 "Count %3d, Size %3d\n", ext_cnt, ext_size);
3063
3064 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3065 "\tPort Available RPI extents: ");
3066 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_RPI,
3067 &ext_cnt, &ext_size);
3068 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3069 "Count %3d, Size %3d\n", ext_cnt, ext_size);
3070
3071 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3072 "\tPort Available XRI extents: ");
3073 lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_XRI,
3074 &ext_cnt, &ext_size);
3075 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3076 "Count %3d, Size %3d\n", ext_cnt, ext_size);
3077
3078 return len;
3079}
3080
3081/**
3082 * lpfc_idiag_extacc_alloc_get - get the allocated extents information
3083 * @phba: pointer to lpfc hba data structure.
3084 * @pbuffer: pointer to internal buffer.
3085 * @len: length into the internal buffer data has been copied.
3086 *
3087 * Description:
3088 * This routine is to get the allocated extent information.
3089 *
3090 * Returns:
3091 * overall lenth of the data read into the internal buffer.
3092 **/
3093static int
3094lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len)
3095{
3096 uint16_t ext_cnt, ext_size;
3097 int rc;
3098
3099 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3100 "\nAllocated Extents Information:\n");
3101
3102 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3103 "\tHost Allocated VPI extents: ");
3104 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VPI,
3105 &ext_cnt, &ext_size);
3106 if (!rc)
3107 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3108 "Port %d Extent %3d, Size %3d\n",
3109 phba->brd_no, ext_cnt, ext_size);
3110 else
3111 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3112 "N/A\n");
3113
3114 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3115 "\tHost Allocated VFI extents: ");
3116 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VFI,
3117 &ext_cnt, &ext_size);
3118 if (!rc)
3119 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3120 "Port %d Extent %3d, Size %3d\n",
3121 phba->brd_no, ext_cnt, ext_size);
3122 else
3123 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3124 "N/A\n");
3125
3126 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3127 "\tHost Allocated RPI extents: ");
3128 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_RPI,
3129 &ext_cnt, &ext_size);
3130 if (!rc)
3131 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3132 "Port %d Extent %3d, Size %3d\n",
3133 phba->brd_no, ext_cnt, ext_size);
3134 else
3135 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3136 "N/A\n");
3137
3138 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3139 "\tHost Allocated XRI extents: ");
3140 rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_XRI,
3141 &ext_cnt, &ext_size);
3142 if (!rc)
3143 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3144 "Port %d Extent %3d, Size %3d\n",
3145 phba->brd_no, ext_cnt, ext_size);
3146 else
3147 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3148 "N/A\n");
3149
3150 return len;
3151}
3152
3153/**
3154 * lpfc_idiag_extacc_drivr_get - get driver extent information
3155 * @phba: pointer to lpfc hba data structure.
3156 * @pbuffer: pointer to internal buffer.
3157 * @len: length into the internal buffer data has been copied.
3158 *
3159 * Description:
3160 * This routine is to get the driver extent information.
3161 *
3162 * Returns:
3163 * overall lenth of the data read into the internal buffer.
3164 **/
3165static int
3166lpfc_idiag_extacc_drivr_get(struct lpfc_hba *phba, char *pbuffer, int len)
3167{
3168 struct lpfc_rsrc_blks *rsrc_blks;
3169 int index;
3170
3171 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3172 "\nDriver Extents Information:\n");
3173
3174 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3175 "\tVPI extents:\n");
3176 index = 0;
3177 list_for_each_entry(rsrc_blks, &phba->lpfc_vpi_blk_list, list) {
3178 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3179 "\t\tBlock %3d: Start %4d, Count %4d\n",
3180 index, rsrc_blks->rsrc_start,
3181 rsrc_blks->rsrc_size);
3182 index++;
3183 }
3184 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3185 "\tVFI extents:\n");
3186 index = 0;
3187 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_vfi_blk_list,
3188 list) {
3189 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3190 "\t\tBlock %3d: Start %4d, Count %4d\n",
3191 index, rsrc_blks->rsrc_start,
3192 rsrc_blks->rsrc_size);
3193 index++;
3194 }
3195
3196 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3197 "\tRPI extents:\n");
3198 index = 0;
3199 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_rpi_blk_list,
3200 list) {
3201 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3202 "\t\tBlock %3d: Start %4d, Count %4d\n",
3203 index, rsrc_blks->rsrc_start,
3204 rsrc_blks->rsrc_size);
3205 index++;
3206 }
3207
3208 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3209 "\tXRI extents:\n");
3210 index = 0;
3211 list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_xri_blk_list,
3212 list) {
3213 len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
3214 "\t\tBlock %3d: Start %4d, Count %4d\n",
3215 index, rsrc_blks->rsrc_start,
3216 rsrc_blks->rsrc_size);
3217 index++;
3218 }
3219
3220 return len;
3221}
3222
3223/**
3224 * lpfc_idiag_extacc_write - Syntax check and set up idiag extacc commands
3225 * @file: The file pointer to read from.
3226 * @buf: The buffer to copy the user data from.
3227 * @nbytes: The number of bytes to get.
3228 * @ppos: The position in the file to start reading from.
3229 *
3230 * This routine get the debugfs idiag command struct from user space and then
3231 * perform the syntax check for extent information access commands and sets
3232 * up the necessary states in the idiag command struct accordingly.
3233 *
3234 * It returns the @nbytges passing in from debugfs user space when successful.
3235 * In case of error conditions, it returns proper error code back to the user
3236 * space.
3237 **/
3238static ssize_t
3239lpfc_idiag_extacc_write(struct file *file, const char __user *buf,
3240 size_t nbytes, loff_t *ppos)
3241{
3242 struct lpfc_debug *debug = file->private_data;
3243 uint32_t ext_map;
3244 int rc;
3245
3246 /* This is a user write operation */
3247 debug->op = LPFC_IDIAG_OP_WR;
3248
3249 rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
3250 if (rc < 0)
3251 return rc;
3252
3253 ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
3254
3255 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
3256 goto error_out;
3257 if (rc != LPFC_EXT_ACC_CMD_ARG)
3258 goto error_out;
3259 if (!(ext_map & LPFC_EXT_ACC_ALL))
3260 goto error_out;
3261
3262 return nbytes;
3263error_out:
3264 /* Clean out command structure on command error out */
3265 memset(&idiag, 0, sizeof(idiag));
3266 return -EINVAL;
3267}
3268
3269/**
3270 * lpfc_idiag_extacc_read - idiag debugfs read access to extent information
3271 * @file: The file pointer to read from.
3272 * @buf: The buffer to copy the data to.
3273 * @nbytes: The number of bytes to read.
3274 * @ppos: The position in the file to start reading from.
3275 *
3276 * Description:
3277 * This routine reads data from the proper extent information according to
3278 * the idiag command, and copies to user @buf.
3279 *
3280 * Returns:
3281 * This function returns the amount of data that was read (this could be less
3282 * than @nbytes if the end of the file was reached) or a negative error value.
3283 **/
3284static ssize_t
3285lpfc_idiag_extacc_read(struct file *file, char __user *buf, size_t nbytes,
3286 loff_t *ppos)
3287{
3288 struct lpfc_debug *debug = file->private_data;
3289 struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
3290 char *pbuffer;
3291 uint32_t ext_map;
3292 int len = 0;
3293
3294 /* This is a user read operation */
3295 debug->op = LPFC_IDIAG_OP_RD;
3296
3297 if (!debug->buffer)
3298 debug->buffer = kmalloc(LPFC_EXT_ACC_BUF_SIZE, GFP_KERNEL);
3299 if (!debug->buffer)
3300 return 0;
3301 pbuffer = debug->buffer;
3302 if (*ppos)
3303 return 0;
3304 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
3305 return 0;
3306
3307 ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
3308 if (ext_map & LPFC_EXT_ACC_AVAIL)
3309 len = lpfc_idiag_extacc_avail_get(phba, pbuffer, len);
3310 if (ext_map & LPFC_EXT_ACC_ALLOC)
3311 len = lpfc_idiag_extacc_alloc_get(phba, pbuffer, len);
3312 if (ext_map & LPFC_EXT_ACC_DRIVR)
3313 len = lpfc_idiag_extacc_drivr_get(phba, pbuffer, len);
3314
3315 return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
3316}
3317
2333#undef lpfc_debugfs_op_disc_trc 3318#undef lpfc_debugfs_op_disc_trc
2334static const struct file_operations lpfc_debugfs_op_disc_trc = { 3319static const struct file_operations lpfc_debugfs_op_disc_trc = {
2335 .owner = THIS_MODULE, 3320 .owner = THIS_MODULE,
@@ -2420,6 +3405,16 @@ static const struct file_operations lpfc_idiag_op_pciCfg = {
2420 .release = lpfc_idiag_cmd_release, 3405 .release = lpfc_idiag_cmd_release,
2421}; 3406};
2422 3407
3408#undef lpfc_idiag_op_barAcc
3409static const struct file_operations lpfc_idiag_op_barAcc = {
3410 .owner = THIS_MODULE,
3411 .open = lpfc_idiag_open,
3412 .llseek = lpfc_debugfs_lseek,
3413 .read = lpfc_idiag_baracc_read,
3414 .write = lpfc_idiag_baracc_write,
3415 .release = lpfc_idiag_cmd_release,
3416};
3417
2423#undef lpfc_idiag_op_queInfo 3418#undef lpfc_idiag_op_queInfo
2424static const struct file_operations lpfc_idiag_op_queInfo = { 3419static const struct file_operations lpfc_idiag_op_queInfo = {
2425 .owner = THIS_MODULE, 3420 .owner = THIS_MODULE,
@@ -2428,7 +3423,7 @@ static const struct file_operations lpfc_idiag_op_queInfo = {
2428 .release = lpfc_idiag_release, 3423 .release = lpfc_idiag_release,
2429}; 3424};
2430 3425
2431#undef lpfc_idiag_op_queacc 3426#undef lpfc_idiag_op_queAcc
2432static const struct file_operations lpfc_idiag_op_queAcc = { 3427static const struct file_operations lpfc_idiag_op_queAcc = {
2433 .owner = THIS_MODULE, 3428 .owner = THIS_MODULE,
2434 .open = lpfc_idiag_open, 3429 .open = lpfc_idiag_open,
@@ -2438,7 +3433,7 @@ static const struct file_operations lpfc_idiag_op_queAcc = {
2438 .release = lpfc_idiag_cmd_release, 3433 .release = lpfc_idiag_cmd_release,
2439}; 3434};
2440 3435
2441#undef lpfc_idiag_op_drbacc 3436#undef lpfc_idiag_op_drbAcc
2442static const struct file_operations lpfc_idiag_op_drbAcc = { 3437static const struct file_operations lpfc_idiag_op_drbAcc = {
2443 .owner = THIS_MODULE, 3438 .owner = THIS_MODULE,
2444 .open = lpfc_idiag_open, 3439 .open = lpfc_idiag_open,
@@ -2448,8 +3443,234 @@ static const struct file_operations lpfc_idiag_op_drbAcc = {
2448 .release = lpfc_idiag_cmd_release, 3443 .release = lpfc_idiag_cmd_release,
2449}; 3444};
2450 3445
3446#undef lpfc_idiag_op_ctlAcc
3447static const struct file_operations lpfc_idiag_op_ctlAcc = {
3448 .owner = THIS_MODULE,
3449 .open = lpfc_idiag_open,
3450 .llseek = lpfc_debugfs_lseek,
3451 .read = lpfc_idiag_ctlacc_read,
3452 .write = lpfc_idiag_ctlacc_write,
3453 .release = lpfc_idiag_cmd_release,
3454};
3455
3456#undef lpfc_idiag_op_mbxAcc
3457static const struct file_operations lpfc_idiag_op_mbxAcc = {
3458 .owner = THIS_MODULE,
3459 .open = lpfc_idiag_open,
3460 .llseek = lpfc_debugfs_lseek,
3461 .read = lpfc_idiag_mbxacc_read,
3462 .write = lpfc_idiag_mbxacc_write,
3463 .release = lpfc_idiag_cmd_release,
3464};
3465
3466#undef lpfc_idiag_op_extAcc
3467static const struct file_operations lpfc_idiag_op_extAcc = {
3468 .owner = THIS_MODULE,
3469 .open = lpfc_idiag_open,
3470 .llseek = lpfc_debugfs_lseek,
3471 .read = lpfc_idiag_extacc_read,
3472 .write = lpfc_idiag_extacc_write,
3473 .release = lpfc_idiag_cmd_release,
3474};
3475
2451#endif 3476#endif
2452 3477
3478/* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command
3479 * @phba: Pointer to HBA context object.
3480 * @dmabuf: Pointer to a DMA buffer descriptor.
3481 *
3482 * Description:
3483 * This routine dump a bsg pass-through non-embedded mailbox command with
3484 * external buffer.
3485 **/
3486void
3487lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba *phba, enum nemb_type nemb_tp,
3488 enum mbox_type mbox_tp, enum dma_type dma_tp,
3489 enum sta_type sta_tp,
3490 struct lpfc_dmabuf *dmabuf, uint32_t ext_buf)
3491{
3492#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
3493 uint32_t *mbx_mbox_cmd, *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt;
3494 char line_buf[LPFC_MBX_ACC_LBUF_SZ];
3495 int len = 0;
3496 uint32_t do_dump = 0;
3497 uint32_t *pword;
3498 uint32_t i;
3499
3500 if (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP)
3501 return;
3502
3503 mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3504 mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3505 mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3506 mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3507
3508 if (!(*mbx_dump_map & LPFC_MBX_DMP_ALL) ||
3509 (*mbx_dump_cnt == 0) ||
3510 (*mbx_word_cnt == 0))
3511 return;
3512
3513 if (*mbx_mbox_cmd != 0x9B)
3514 return;
3515
3516 if ((mbox_tp == mbox_rd) && (dma_tp == dma_mbox)) {
3517 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_MBX) {
3518 do_dump |= LPFC_BSG_DMP_MBX_RD_MBX;
3519 printk(KERN_ERR "\nRead mbox command (x%x), "
3520 "nemb:0x%x, extbuf_cnt:%d:\n",
3521 sta_tp, nemb_tp, ext_buf);
3522 }
3523 }
3524 if ((mbox_tp == mbox_rd) && (dma_tp == dma_ebuf)) {
3525 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_BUF) {
3526 do_dump |= LPFC_BSG_DMP_MBX_RD_BUF;
3527 printk(KERN_ERR "\nRead mbox buffer (x%x), "
3528 "nemb:0x%x, extbuf_seq:%d:\n",
3529 sta_tp, nemb_tp, ext_buf);
3530 }
3531 }
3532 if ((mbox_tp == mbox_wr) && (dma_tp == dma_mbox)) {
3533 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_MBX) {
3534 do_dump |= LPFC_BSG_DMP_MBX_WR_MBX;
3535 printk(KERN_ERR "\nWrite mbox command (x%x), "
3536 "nemb:0x%x, extbuf_cnt:%d:\n",
3537 sta_tp, nemb_tp, ext_buf);
3538 }
3539 }
3540 if ((mbox_tp == mbox_wr) && (dma_tp == dma_ebuf)) {
3541 if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_BUF) {
3542 do_dump |= LPFC_BSG_DMP_MBX_WR_BUF;
3543 printk(KERN_ERR "\nWrite mbox buffer (x%x), "
3544 "nemb:0x%x, extbuf_seq:%d:\n",
3545 sta_tp, nemb_tp, ext_buf);
3546 }
3547 }
3548
3549 /* dump buffer content */
3550 if (do_dump) {
3551 pword = (uint32_t *)dmabuf->virt;
3552 for (i = 0; i < *mbx_word_cnt; i++) {
3553 if (!(i % 8)) {
3554 if (i != 0)
3555 printk(KERN_ERR "%s\n", line_buf);
3556 len = 0;
3557 len += snprintf(line_buf+len,
3558 LPFC_MBX_ACC_LBUF_SZ-len,
3559 "%03d: ", i);
3560 }
3561 len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
3562 "%08x ", (uint32_t)*pword);
3563 pword++;
3564 }
3565 if ((i - 1) % 8)
3566 printk(KERN_ERR "%s\n", line_buf);
3567 (*mbx_dump_cnt)--;
3568 }
3569
3570 /* Clean out command structure on reaching dump count */
3571 if (*mbx_dump_cnt == 0)
3572 memset(&idiag, 0, sizeof(idiag));
3573 return;
3574#endif
3575}
3576
3577/* lpfc_idiag_mbxacc_dump_issue_mbox - idiag debugfs dump issue mailbox command
3578 * @phba: Pointer to HBA context object.
3579 * @dmabuf: Pointer to a DMA buffer descriptor.
3580 *
3581 * Description:
3582 * This routine dump a pass-through non-embedded mailbox command from issue
3583 * mailbox command.
3584 **/
3585void
3586lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *phba, MAILBOX_t *pmbox)
3587{
3588#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
3589 uint32_t *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt, *mbx_mbox_cmd;
3590 char line_buf[LPFC_MBX_ACC_LBUF_SZ];
3591 int len = 0;
3592 uint32_t *pword;
3593 uint8_t *pbyte;
3594 uint32_t i, j;
3595
3596 if (idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP)
3597 return;
3598
3599 mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
3600 mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
3601 mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
3602 mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
3603
3604 if (!(*mbx_dump_map & LPFC_MBX_DMP_MBX_ALL) ||
3605 (*mbx_dump_cnt == 0) ||
3606 (*mbx_word_cnt == 0))
3607 return;
3608
3609 if ((*mbx_mbox_cmd != LPFC_MBX_ALL_CMD) &&
3610 (*mbx_mbox_cmd != pmbox->mbxCommand))
3611 return;
3612
3613 /* dump buffer content */
3614 if (*mbx_dump_map & LPFC_MBX_DMP_MBX_WORD) {
3615 printk(KERN_ERR "Mailbox command:0x%x dump by word:\n",
3616 pmbox->mbxCommand);
3617 pword = (uint32_t *)pmbox;
3618 for (i = 0; i < *mbx_word_cnt; i++) {
3619 if (!(i % 8)) {
3620 if (i != 0)
3621 printk(KERN_ERR "%s\n", line_buf);
3622 len = 0;
3623 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
3624 len += snprintf(line_buf+len,
3625 LPFC_MBX_ACC_LBUF_SZ-len,
3626 "%03d: ", i);
3627 }
3628 len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
3629 "%08x ",
3630 ((uint32_t)*pword) & 0xffffffff);
3631 pword++;
3632 }
3633 if ((i - 1) % 8)
3634 printk(KERN_ERR "%s\n", line_buf);
3635 printk(KERN_ERR "\n");
3636 }
3637 if (*mbx_dump_map & LPFC_MBX_DMP_MBX_BYTE) {
3638 printk(KERN_ERR "Mailbox command:0x%x dump by byte:\n",
3639 pmbox->mbxCommand);
3640 pbyte = (uint8_t *)pmbox;
3641 for (i = 0; i < *mbx_word_cnt; i++) {
3642 if (!(i % 8)) {
3643 if (i != 0)
3644 printk(KERN_ERR "%s\n", line_buf);
3645 len = 0;
3646 memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
3647 len += snprintf(line_buf+len,
3648 LPFC_MBX_ACC_LBUF_SZ-len,
3649 "%03d: ", i);
3650 }
3651 for (j = 0; j < 4; j++) {
3652 len += snprintf(line_buf+len,
3653 LPFC_MBX_ACC_LBUF_SZ-len,
3654 "%02x",
3655 ((uint8_t)*pbyte) & 0xff);
3656 pbyte++;
3657 }
3658 len += snprintf(line_buf+len,
3659 LPFC_MBX_ACC_LBUF_SZ-len, " ");
3660 }
3661 if ((i - 1) % 8)
3662 printk(KERN_ERR "%s\n", line_buf);
3663 printk(KERN_ERR "\n");
3664 }
3665 (*mbx_dump_cnt)--;
3666
3667 /* Clean out command structure on reaching dump count */
3668 if (*mbx_dump_cnt == 0)
3669 memset(&idiag, 0, sizeof(idiag));
3670 return;
3671#endif
3672}
3673
2453/** 3674/**
2454 * lpfc_debugfs_initialize - Initialize debugfs for a vport 3675 * lpfc_debugfs_initialize - Initialize debugfs for a vport
2455 * @vport: The vport pointer to initialize. 3676 * @vport: The vport pointer to initialize.
@@ -2673,7 +3894,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
2673 vport, &lpfc_debugfs_op_nodelist); 3894 vport, &lpfc_debugfs_op_nodelist);
2674 if (!vport->debug_nodelist) { 3895 if (!vport->debug_nodelist) {
2675 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, 3896 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
2676 "0409 Can't create debugfs nodelist\n"); 3897 "2985 Can't create debugfs nodelist\n");
2677 goto debug_failed; 3898 goto debug_failed;
2678 } 3899 }
2679 3900
@@ -2710,6 +3931,20 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
2710 idiag.offset.last_rd = 0; 3931 idiag.offset.last_rd = 0;
2711 } 3932 }
2712 3933
3934 /* iDiag PCI BAR access */
3935 snprintf(name, sizeof(name), "barAcc");
3936 if (!phba->idiag_bar_acc) {
3937 phba->idiag_bar_acc =
3938 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
3939 phba->idiag_root, phba, &lpfc_idiag_op_barAcc);
3940 if (!phba->idiag_bar_acc) {
3941 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3942 "3056 Can't create idiag debugfs\n");
3943 goto debug_failed;
3944 }
3945 idiag.offset.last_rd = 0;
3946 }
3947
2713 /* iDiag get PCI function queue information */ 3948 /* iDiag get PCI function queue information */
2714 snprintf(name, sizeof(name), "queInfo"); 3949 snprintf(name, sizeof(name), "queInfo");
2715 if (!phba->idiag_que_info) { 3950 if (!phba->idiag_que_info) {
@@ -2749,6 +3984,50 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
2749 } 3984 }
2750 } 3985 }
2751 3986
3987 /* iDiag access PCI function control registers */
3988 snprintf(name, sizeof(name), "ctlAcc");
3989 if (!phba->idiag_ctl_acc) {
3990 phba->idiag_ctl_acc =
3991 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
3992 phba->idiag_root, phba, &lpfc_idiag_op_ctlAcc);
3993 if (!phba->idiag_ctl_acc) {
3994 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
3995 "2981 Can't create idiag debugfs\n");
3996 goto debug_failed;
3997 }
3998 }
3999
4000 /* iDiag access mbox commands */
4001 snprintf(name, sizeof(name), "mbxAcc");
4002 if (!phba->idiag_mbx_acc) {
4003 phba->idiag_mbx_acc =
4004 debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
4005 phba->idiag_root, phba, &lpfc_idiag_op_mbxAcc);
4006 if (!phba->idiag_mbx_acc) {
4007 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4008 "2980 Can't create idiag debugfs\n");
4009 goto debug_failed;
4010 }
4011 }
4012
4013 /* iDiag extents access commands */
4014 if (phba->sli4_hba.extents_in_use) {
4015 snprintf(name, sizeof(name), "extAcc");
4016 if (!phba->idiag_ext_acc) {
4017 phba->idiag_ext_acc =
4018 debugfs_create_file(name,
4019 S_IFREG|S_IRUGO|S_IWUSR,
4020 phba->idiag_root, phba,
4021 &lpfc_idiag_op_extAcc);
4022 if (!phba->idiag_ext_acc) {
4023 lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
4024 "2986 Cant create "
4025 "idiag debugfs\n");
4026 goto debug_failed;
4027 }
4028 }
4029 }
4030
2752debug_failed: 4031debug_failed:
2753 return; 4032 return;
2754#endif 4033#endif
@@ -2783,7 +4062,6 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
2783 debugfs_remove(vport->debug_nodelist); /* nodelist */ 4062 debugfs_remove(vport->debug_nodelist); /* nodelist */
2784 vport->debug_nodelist = NULL; 4063 vport->debug_nodelist = NULL;
2785 } 4064 }
2786
2787 if (vport->vport_debugfs_root) { 4065 if (vport->vport_debugfs_root) {
2788 debugfs_remove(vport->vport_debugfs_root); /* vportX */ 4066 debugfs_remove(vport->vport_debugfs_root); /* vportX */
2789 vport->vport_debugfs_root = NULL; 4067 vport->vport_debugfs_root = NULL;
@@ -2827,6 +4105,21 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
2827 * iDiag release 4105 * iDiag release
2828 */ 4106 */
2829 if (phba->sli_rev == LPFC_SLI_REV4) { 4107 if (phba->sli_rev == LPFC_SLI_REV4) {
4108 if (phba->idiag_ext_acc) {
4109 /* iDiag extAcc */
4110 debugfs_remove(phba->idiag_ext_acc);
4111 phba->idiag_ext_acc = NULL;
4112 }
4113 if (phba->idiag_mbx_acc) {
4114 /* iDiag mbxAcc */
4115 debugfs_remove(phba->idiag_mbx_acc);
4116 phba->idiag_mbx_acc = NULL;
4117 }
4118 if (phba->idiag_ctl_acc) {
4119 /* iDiag ctlAcc */
4120 debugfs_remove(phba->idiag_ctl_acc);
4121 phba->idiag_ctl_acc = NULL;
4122 }
2830 if (phba->idiag_drb_acc) { 4123 if (phba->idiag_drb_acc) {
2831 /* iDiag drbAcc */ 4124 /* iDiag drbAcc */
2832 debugfs_remove(phba->idiag_drb_acc); 4125 debugfs_remove(phba->idiag_drb_acc);
@@ -2842,6 +4135,11 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
2842 debugfs_remove(phba->idiag_que_info); 4135 debugfs_remove(phba->idiag_que_info);
2843 phba->idiag_que_info = NULL; 4136 phba->idiag_que_info = NULL;
2844 } 4137 }
4138 if (phba->idiag_bar_acc) {
4139 /* iDiag barAcc */
4140 debugfs_remove(phba->idiag_bar_acc);
4141 phba->idiag_bar_acc = NULL;
4142 }
2845 if (phba->idiag_pci_cfg) { 4143 if (phba->idiag_pci_cfg) {
2846 /* iDiag pciCfg */ 4144 /* iDiag pciCfg */
2847 debugfs_remove(phba->idiag_pci_cfg); 4145 debugfs_remove(phba->idiag_pci_cfg);