~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

Viewing changes to drivers/scsi/lpfc/lpfc_debugfs.c

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
#include <linux/blkdev.h>
22
22
#include <linux/delay.h>
 
23
#include <linux/module.h>
23
24
#include <linux/dma-mapping.h>
24
25
#include <linux/idr.h>
25
26
#include <linux/interrupt.h>
48
49
#include "lpfc_version.h"
49
50
#include "lpfc_compat.h"
50
51
#include "lpfc_debugfs.h"
 
52
#include "lpfc_bsg.h"
51
53
 
52
54
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
53
55
/*
135
137
        int i, index, len, enable;
136
138
        uint32_t ms;
137
139
        struct lpfc_debugfs_trc *dtp;
138
 
        char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
 
140
        char *buffer;
 
141
 
 
142
        buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
 
143
        if (!buffer)
 
144
                return 0;
139
145
 
140
146
        enable = lpfc_debugfs_enable;
141
147
        lpfc_debugfs_enable = 0;
167
173
        }
168
174
 
169
175
        lpfc_debugfs_enable = enable;
 
176
        kfree(buffer);
 
177
 
170
178
        return len;
171
179
}
172
180
 
195
203
        int i, index, len, enable;
196
204
        uint32_t ms;
197
205
        struct lpfc_debugfs_trc *dtp;
198
 
        char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
 
206
        char *buffer;
199
207
 
 
208
        buffer = kmalloc(LPFC_DEBUG_TRC_ENTRY_SIZE, GFP_KERNEL);
 
209
        if (!buffer)
 
210
                return 0;
200
211
 
201
212
        enable = lpfc_debugfs_enable;
202
213
        lpfc_debugfs_enable = 0;
228
239
        }
229
240
 
230
241
        lpfc_debugfs_enable = enable;
 
242
        kfree(buffer);
 
243
 
231
244
        return len;
232
245
}
233
246
 
378
391
        int len = 0;
379
392
        int i, off;
380
393
        uint32_t *ptr;
381
 
        char buffer[1024];
 
394
        char *buffer;
 
395
 
 
396
        buffer = kmalloc(1024, GFP_KERNEL);
 
397
        if (!buffer)
 
398
                return 0;
382
399
 
383
400
        off = 0;
384
401
        spin_lock_irq(&phba->hbalock);
407
424
        }
408
425
 
409
426
        spin_unlock_irq(&phba->hbalock);
 
427
        kfree(buffer);
 
428
 
410
429
        return len;
411
430
}
412
431
 
978
997
        return nbytes;
979
998
}
980
999
 
 
1000
static int
 
1001
lpfc_debugfs_dif_err_open(struct inode *inode, struct file *file)
 
1002
{
 
1003
        file->private_data = inode->i_private;
 
1004
        return 0;
 
1005
}
 
1006
 
 
1007
static ssize_t
 
1008
lpfc_debugfs_dif_err_read(struct file *file, char __user *buf,
 
1009
        size_t nbytes, loff_t *ppos)
 
1010
{
 
1011
        struct dentry *dent = file->f_dentry;
 
1012
        struct lpfc_hba *phba = file->private_data;
 
1013
        char cbuf[16];
 
1014
        int cnt = 0;
 
1015
 
 
1016
        if (dent == phba->debug_writeGuard)
 
1017
                cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wgrd_cnt);
 
1018
        else if (dent == phba->debug_writeApp)
 
1019
                cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wapp_cnt);
 
1020
        else if (dent == phba->debug_writeRef)
 
1021
                cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_wref_cnt);
 
1022
        else if (dent == phba->debug_readApp)
 
1023
                cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rapp_cnt);
 
1024
        else if (dent == phba->debug_readRef)
 
1025
                cnt = snprintf(cbuf, 16, "%u\n", phba->lpfc_injerr_rref_cnt);
 
1026
        else if (dent == phba->debug_InjErrLBA)
 
1027
                cnt = snprintf(cbuf, 16, "0x%lx\n",
 
1028
                                 (unsigned long) phba->lpfc_injerr_lba);
 
1029
        else
 
1030
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 
1031
                         "0547 Unknown debugfs error injection entry\n");
 
1032
 
 
1033
        return simple_read_from_buffer(buf, nbytes, ppos, &cbuf, cnt);
 
1034
}
 
1035
 
 
1036
static ssize_t
 
1037
lpfc_debugfs_dif_err_write(struct file *file, const char __user *buf,
 
1038
        size_t nbytes, loff_t *ppos)
 
1039
{
 
1040
        struct dentry *dent = file->f_dentry;
 
1041
        struct lpfc_hba *phba = file->private_data;
 
1042
        char dstbuf[32];
 
1043
        unsigned long tmp;
 
1044
        int size;
 
1045
 
 
1046
        memset(dstbuf, 0, 32);
 
1047
        size = (nbytes < 32) ? nbytes : 32;
 
1048
        if (copy_from_user(dstbuf, buf, size))
 
1049
                return 0;
 
1050
 
 
1051
        if (strict_strtoul(dstbuf, 0, &tmp))
 
1052
                return 0;
 
1053
 
 
1054
        if (dent == phba->debug_writeGuard)
 
1055
                phba->lpfc_injerr_wgrd_cnt = (uint32_t)tmp;
 
1056
        else if (dent == phba->debug_writeApp)
 
1057
                phba->lpfc_injerr_wapp_cnt = (uint32_t)tmp;
 
1058
        else if (dent == phba->debug_writeRef)
 
1059
                phba->lpfc_injerr_wref_cnt = (uint32_t)tmp;
 
1060
        else if (dent == phba->debug_readApp)
 
1061
                phba->lpfc_injerr_rapp_cnt = (uint32_t)tmp;
 
1062
        else if (dent == phba->debug_readRef)
 
1063
                phba->lpfc_injerr_rref_cnt = (uint32_t)tmp;
 
1064
        else if (dent == phba->debug_InjErrLBA)
 
1065
                phba->lpfc_injerr_lba = (sector_t)tmp;
 
1066
        else
 
1067
                lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 
1068
                         "0548 Unknown debugfs error injection entry\n");
 
1069
 
 
1070
        return nbytes;
 
1071
}
 
1072
 
 
1073
static int
 
1074
lpfc_debugfs_dif_err_release(struct inode *inode, struct file *file)
 
1075
{
 
1076
        return 0;
 
1077
}
 
1078
 
981
1079
/**
982
1080
 * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file
983
1081
 * @inode: The inode pointer that contains a vport pointer.
1147
1245
{
1148
1246
        char mybuf[64];
1149
1247
        char *pbuf, *step_str;
1150
 
        int bsize, i;
 
1248
        int i;
 
1249
        size_t bsize;
1151
1250
 
1152
1251
        /* Protect copy from user */
1153
1252
        if (!access_ok(VERIFY_READ, buf, nbytes))
1326
1425
                return 0;
1327
1426
 
1328
1427
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
1329
 
                where = idiag.cmd.data[0];
1330
 
                count = idiag.cmd.data[1];
 
1428
                where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
 
1429
                count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
1331
1430
        } else
1332
1431
                return 0;
1333
1432
 
1372
1471
                len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1373
1472
                                "%08x ", u32val);
1374
1473
                offset += sizeof(uint32_t);
 
1474
                if (offset >= LPFC_PCI_CFG_SIZE) {
 
1475
                        len += snprintf(pbuffer+len,
 
1476
                                        LPFC_PCI_CFG_SIZE-len, "\n");
 
1477
                        break;
 
1478
                }
1375
1479
                index -= sizeof(uint32_t);
1376
1480
                if (!index)
1377
1481
                        len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
1384
1488
        }
1385
1489
 
1386
1490
        /* Set up the offset for next portion of pci cfg read */
1387
 
        idiag.offset.last_rd += LPFC_PCI_CFG_RD_SIZE;
1388
 
        if (idiag.offset.last_rd >= LPFC_PCI_CFG_SIZE)
 
1491
        if (index == 0) {
 
1492
                idiag.offset.last_rd += LPFC_PCI_CFG_RD_SIZE;
 
1493
                if (idiag.offset.last_rd >= LPFC_PCI_CFG_SIZE)
 
1494
                        idiag.offset.last_rd = 0;
 
1495
        } else
1389
1496
                idiag.offset.last_rd = 0;
1390
1497
 
1391
1498
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
1438
1545
                if (rc != LPFC_PCI_CFG_RD_CMD_ARG)
1439
1546
                        goto error_out;
1440
1547
                /* Read command from PCI config space, set up command fields */
1441
 
                where = idiag.cmd.data[0];
1442
 
                count = idiag.cmd.data[1];
 
1548
                where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
 
1549
                count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
1443
1550
                if (count == LPFC_PCI_CFG_BROWSE) {
1444
1551
                        if (where % sizeof(uint32_t))
1445
1552
                                goto error_out;
1474
1581
                if (rc != LPFC_PCI_CFG_WR_CMD_ARG)
1475
1582
                        goto error_out;
1476
1583
                /* Write command to PCI config space, read-modify-write */
1477
 
                where = idiag.cmd.data[0];
1478
 
                count = idiag.cmd.data[1];
1479
 
                value = idiag.cmd.data[2];
 
1584
                where = idiag.cmd.data[IDIAG_PCICFG_WHERE_INDX];
 
1585
                count = idiag.cmd.data[IDIAG_PCICFG_COUNT_INDX];
 
1586
                value = idiag.cmd.data[IDIAG_PCICFG_VALUE_INDX];
1480
1587
                /* Sanity checks */
1481
1588
                if ((count != sizeof(uint8_t)) &&
1482
1589
                    (count != sizeof(uint16_t)) &&
1569
1676
}
1570
1677
 
1571
1678
/**
 
1679
 * lpfc_idiag_baracc_read - idiag debugfs pci bar access read
 
1680
 * @file: The file pointer to read from.
 
1681
 * @buf: The buffer to copy the data to.
 
1682
 * @nbytes: The number of bytes to read.
 
1683
 * @ppos: The position in the file to start reading from.
 
1684
 *
 
1685
 * Description:
 
1686
 * This routine reads data from the @phba pci bar memory mapped space
 
1687
 * according to the idiag command, and copies to user @buf.
 
1688
 *
 
1689
 * Returns:
 
1690
 * This function returns the amount of data that was read (this could be less
 
1691
 * than @nbytes if the end of the file was reached) or a negative error value.
 
1692
 **/
 
1693
static ssize_t
 
1694
lpfc_idiag_baracc_read(struct file *file, char __user *buf, size_t nbytes,
 
1695
                       loff_t *ppos)
 
1696
{
 
1697
        struct lpfc_debug *debug = file->private_data;
 
1698
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
1699
        int offset_label, offset, offset_run, len = 0, index;
 
1700
        int bar_num, acc_range, bar_size;
 
1701
        char *pbuffer;
 
1702
        void __iomem *mem_mapped_bar;
 
1703
        uint32_t if_type;
 
1704
        struct pci_dev *pdev;
 
1705
        uint32_t u32val;
 
1706
 
 
1707
        pdev = phba->pcidev;
 
1708
        if (!pdev)
 
1709
                return 0;
 
1710
 
 
1711
        /* This is a user read operation */
 
1712
        debug->op = LPFC_IDIAG_OP_RD;
 
1713
 
 
1714
        if (!debug->buffer)
 
1715
                debug->buffer = kmalloc(LPFC_PCI_BAR_RD_BUF_SIZE, GFP_KERNEL);
 
1716
        if (!debug->buffer)
 
1717
                return 0;
 
1718
        pbuffer = debug->buffer;
 
1719
 
 
1720
        if (*ppos)
 
1721
                return 0;
 
1722
 
 
1723
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
 
1724
                bar_num   = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
 
1725
                offset    = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
 
1726
                acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
 
1727
                bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
 
1728
        } else
 
1729
                return 0;
 
1730
 
 
1731
        if (acc_range == 0)
 
1732
                return 0;
 
1733
 
 
1734
        if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
 
1735
        if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
 
1736
                if (bar_num == IDIAG_BARACC_BAR_0)
 
1737
                        mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
 
1738
                else if (bar_num == IDIAG_BARACC_BAR_1)
 
1739
                        mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
 
1740
                else if (bar_num == IDIAG_BARACC_BAR_2)
 
1741
                        mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
 
1742
                else
 
1743
                        return 0;
 
1744
        } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
 
1745
                if (bar_num == IDIAG_BARACC_BAR_0)
 
1746
                        mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
 
1747
                else
 
1748
                        return 0;
 
1749
        } else
 
1750
                return 0;
 
1751
 
 
1752
        /* Read single PCI bar space register */
 
1753
        if (acc_range == SINGLE_WORD) {
 
1754
                offset_run = offset;
 
1755
                u32val = readl(mem_mapped_bar + offset_run);
 
1756
                len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
 
1757
                                "%05x: %08x\n", offset_run, u32val);
 
1758
        } else
 
1759
                goto baracc_browse;
 
1760
 
 
1761
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
1762
 
 
1763
baracc_browse:
 
1764
 
 
1765
        /* Browse all PCI bar space registers */
 
1766
        offset_label = idiag.offset.last_rd;
 
1767
        offset_run = offset_label;
 
1768
 
 
1769
        /* Read PCI bar memory mapped space */
 
1770
        len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
 
1771
                        "%05x: ", offset_label);
 
1772
        index = LPFC_PCI_BAR_RD_SIZE;
 
1773
        while (index > 0) {
 
1774
                u32val = readl(mem_mapped_bar + offset_run);
 
1775
                len += snprintf(pbuffer+len, LPFC_PCI_BAR_RD_BUF_SIZE-len,
 
1776
                                "%08x ", u32val);
 
1777
                offset_run += sizeof(uint32_t);
 
1778
                if (acc_range == LPFC_PCI_BAR_BROWSE) {
 
1779
                        if (offset_run >= bar_size) {
 
1780
                                len += snprintf(pbuffer+len,
 
1781
                                        LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
 
1782
                                break;
 
1783
                        }
 
1784
                } else {
 
1785
                        if (offset_run >= offset +
 
1786
                            (acc_range * sizeof(uint32_t))) {
 
1787
                                len += snprintf(pbuffer+len,
 
1788
                                        LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
 
1789
                                break;
 
1790
                        }
 
1791
                }
 
1792
                index -= sizeof(uint32_t);
 
1793
                if (!index)
 
1794
                        len += snprintf(pbuffer+len,
 
1795
                                        LPFC_PCI_BAR_RD_BUF_SIZE-len, "\n");
 
1796
                else if (!(index % (8 * sizeof(uint32_t)))) {
 
1797
                        offset_label += (8 * sizeof(uint32_t));
 
1798
                        len += snprintf(pbuffer+len,
 
1799
                                        LPFC_PCI_BAR_RD_BUF_SIZE-len,
 
1800
                                        "\n%05x: ", offset_label);
 
1801
                }
 
1802
        }
 
1803
 
 
1804
        /* Set up the offset for next portion of pci bar read */
 
1805
        if (index == 0) {
 
1806
                idiag.offset.last_rd += LPFC_PCI_BAR_RD_SIZE;
 
1807
                if (acc_range == LPFC_PCI_BAR_BROWSE) {
 
1808
                        if (idiag.offset.last_rd >= bar_size)
 
1809
                                idiag.offset.last_rd = 0;
 
1810
                } else {
 
1811
                        if (offset_run >= offset +
 
1812
                            (acc_range * sizeof(uint32_t)))
 
1813
                                idiag.offset.last_rd = offset;
 
1814
                }
 
1815
        } else {
 
1816
                if (acc_range == LPFC_PCI_BAR_BROWSE)
 
1817
                        idiag.offset.last_rd = 0;
 
1818
                else
 
1819
                        idiag.offset.last_rd = offset;
 
1820
        }
 
1821
 
 
1822
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
1823
}
 
1824
 
 
1825
/**
 
1826
 * lpfc_idiag_baracc_write - Syntax check and set up idiag bar access commands
 
1827
 * @file: The file pointer to read from.
 
1828
 * @buf: The buffer to copy the user data from.
 
1829
 * @nbytes: The number of bytes to get.
 
1830
 * @ppos: The position in the file to start reading from.
 
1831
 *
 
1832
 * This routine get the debugfs idiag command struct from user space and
 
1833
 * then perform the syntax check for PCI bar memory mapped space read or
 
1834
 * write command accordingly. In the case of PCI bar memory mapped space
 
1835
 * read command, it sets up the command in the idiag command struct for
 
1836
 * the debugfs read operation. In the case of PCI bar memorpy mapped space
 
1837
 * write operation, it executes the write operation into the PCI bar memory
 
1838
 * mapped space accordingly.
 
1839
 *
 
1840
 * It returns the @nbytges passing in from debugfs user space when successful.
 
1841
 * In case of error conditions, it returns proper error code back to the user
 
1842
 * space.
 
1843
 */
 
1844
static ssize_t
 
1845
lpfc_idiag_baracc_write(struct file *file, const char __user *buf,
 
1846
                        size_t nbytes, loff_t *ppos)
 
1847
{
 
1848
        struct lpfc_debug *debug = file->private_data;
 
1849
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
1850
        uint32_t bar_num, bar_size, offset, value, acc_range;
 
1851
        struct pci_dev *pdev;
 
1852
        void __iomem *mem_mapped_bar;
 
1853
        uint32_t if_type;
 
1854
        uint32_t u32val;
 
1855
        int rc;
 
1856
 
 
1857
        pdev = phba->pcidev;
 
1858
        if (!pdev)
 
1859
                return -EFAULT;
 
1860
 
 
1861
        /* This is a user write operation */
 
1862
        debug->op = LPFC_IDIAG_OP_WR;
 
1863
 
 
1864
        rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
 
1865
        if (rc < 0)
 
1866
                return rc;
 
1867
 
 
1868
        if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf);
 
1869
        bar_num = idiag.cmd.data[IDIAG_BARACC_BAR_NUM_INDX];
 
1870
 
 
1871
        if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
 
1872
                if ((bar_num != IDIAG_BARACC_BAR_0) &&
 
1873
                    (bar_num != IDIAG_BARACC_BAR_1) &&
 
1874
                    (bar_num != IDIAG_BARACC_BAR_2))
 
1875
                        goto error_out;
 
1876
        } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
 
1877
                if (bar_num != IDIAG_BARACC_BAR_0)
 
1878
                        goto error_out;
 
1879
        } else
 
1880
                goto error_out;
 
1881
 
 
1882
        if (if_type == LPFC_SLI_INTF_IF_TYPE_0) {
 
1883
                if (bar_num == IDIAG_BARACC_BAR_0) {
 
1884
                        idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
 
1885
                                LPFC_PCI_IF0_BAR0_SIZE;
 
1886
                        mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
 
1887
                } else if (bar_num == IDIAG_BARACC_BAR_1) {
 
1888
                        idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
 
1889
                                LPFC_PCI_IF0_BAR1_SIZE;
 
1890
                        mem_mapped_bar = phba->sli4_hba.ctrl_regs_memmap_p;
 
1891
                } else if (bar_num == IDIAG_BARACC_BAR_2) {
 
1892
                        idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
 
1893
                                LPFC_PCI_IF0_BAR2_SIZE;
 
1894
                        mem_mapped_bar = phba->sli4_hba.drbl_regs_memmap_p;
 
1895
                } else
 
1896
                        goto error_out;
 
1897
        } else if (if_type == LPFC_SLI_INTF_IF_TYPE_2) {
 
1898
                if (bar_num == IDIAG_BARACC_BAR_0) {
 
1899
                        idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX] =
 
1900
                                LPFC_PCI_IF2_BAR0_SIZE;
 
1901
                        mem_mapped_bar = phba->sli4_hba.conf_regs_memmap_p;
 
1902
                } else
 
1903
                        goto error_out;
 
1904
        } else
 
1905
                goto error_out;
 
1906
 
 
1907
        offset = idiag.cmd.data[IDIAG_BARACC_OFF_SET_INDX];
 
1908
        if (offset % sizeof(uint32_t))
 
1909
                goto error_out;
 
1910
 
 
1911
        bar_size = idiag.cmd.data[IDIAG_BARACC_BAR_SZE_INDX];
 
1912
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_RD) {
 
1913
                /* Sanity check on PCI config read command line arguments */
 
1914
                if (rc != LPFC_PCI_BAR_RD_CMD_ARG)
 
1915
                        goto error_out;
 
1916
                acc_range = idiag.cmd.data[IDIAG_BARACC_ACC_MOD_INDX];
 
1917
                if (acc_range == LPFC_PCI_BAR_BROWSE) {
 
1918
                        if (offset > bar_size - sizeof(uint32_t))
 
1919
                                goto error_out;
 
1920
                        /* Starting offset to browse */
 
1921
                        idiag.offset.last_rd = offset;
 
1922
                } else if (acc_range > SINGLE_WORD) {
 
1923
                        if (offset + acc_range * sizeof(uint32_t) > bar_size)
 
1924
                                goto error_out;
 
1925
                        /* Starting offset to browse */
 
1926
                        idiag.offset.last_rd = offset;
 
1927
                } else if (acc_range != SINGLE_WORD)
 
1928
                        goto error_out;
 
1929
        } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR ||
 
1930
                   idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST ||
 
1931
                   idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
 
1932
                /* Sanity check on PCI bar write command line arguments */
 
1933
                if (rc != LPFC_PCI_BAR_WR_CMD_ARG)
 
1934
                        goto error_out;
 
1935
                /* Write command to PCI bar space, read-modify-write */
 
1936
                acc_range = SINGLE_WORD;
 
1937
                value = idiag.cmd.data[IDIAG_BARACC_REG_VAL_INDX];
 
1938
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_WR) {
 
1939
                        writel(value, mem_mapped_bar + offset);
 
1940
                        readl(mem_mapped_bar + offset);
 
1941
                }
 
1942
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_ST) {
 
1943
                        u32val = readl(mem_mapped_bar + offset);
 
1944
                        u32val |= value;
 
1945
                        writel(u32val, mem_mapped_bar + offset);
 
1946
                        readl(mem_mapped_bar + offset);
 
1947
                }
 
1948
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_BARACC_CL) {
 
1949
                        u32val = readl(mem_mapped_bar + offset);
 
1950
                        u32val &= ~value;
 
1951
                        writel(u32val, mem_mapped_bar + offset);
 
1952
                        readl(mem_mapped_bar + offset);
 
1953
                }
 
1954
        } else
 
1955
                /* All other opecodes are illegal for now */
 
1956
                goto error_out;
 
1957
 
 
1958
        return nbytes;
 
1959
error_out:
 
1960
        memset(&idiag, 0, sizeof(idiag));
 
1961
        return -EINVAL;
 
1962
}
 
1963
 
 
1964
/**
1572
1965
 * lpfc_idiag_queinfo_read - idiag debugfs read queue information
1573
1966
 * @file: The file pointer to read from.
1574
1967
 * @buf: The buffer to copy the data to.
1870
2263
                return 0;
1871
2264
 
1872
2265
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
1873
 
                index = idiag.cmd.data[2];
1874
 
                count = idiag.cmd.data[3];
 
2266
                index = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
 
2267
                count = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
1875
2268
                pque = (struct lpfc_queue *)idiag.ptr_private;
1876
2269
        } else
1877
2270
                return 0;
1943
2336
                return rc;
1944
2337
 
1945
2338
        /* Get and sanity check on command feilds */
1946
 
        quetp  = idiag.cmd.data[0];
1947
 
        queid  = idiag.cmd.data[1];
1948
 
        index  = idiag.cmd.data[2];
1949
 
        count  = idiag.cmd.data[3];
1950
 
        offset = idiag.cmd.data[4];
1951
 
        value  = idiag.cmd.data[5];
 
2339
        quetp  = idiag.cmd.data[IDIAG_QUEACC_QUETP_INDX];
 
2340
        queid  = idiag.cmd.data[IDIAG_QUEACC_QUEID_INDX];
 
2341
        index  = idiag.cmd.data[IDIAG_QUEACC_INDEX_INDX];
 
2342
        count  = idiag.cmd.data[IDIAG_QUEACC_COUNT_INDX];
 
2343
        offset = idiag.cmd.data[IDIAG_QUEACC_OFFST_INDX];
 
2344
        value  = idiag.cmd.data[IDIAG_QUEACC_VALUE_INDX];
1952
2345
 
1953
2346
        /* Sanity check on command line arguments */
1954
2347
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
2217
2610
                return 0;
2218
2611
 
2219
2612
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD)
2220
 
                drb_reg_id = idiag.cmd.data[0];
 
2613
                drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
2221
2614
        else
2222
2615
                return 0;
2223
2616
 
2256
2649
{
2257
2650
        struct lpfc_debug *debug = file->private_data;
2258
2651
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
2259
 
        uint32_t drb_reg_id, value, reg_val;
 
2652
        uint32_t drb_reg_id, value, reg_val = 0;
2260
2653
        void __iomem *drb_reg;
2261
2654
        int rc;
2262
2655
 
2268
2661
                return rc;
2269
2662
 
2270
2663
        /* Sanity check on command line arguments */
2271
 
        drb_reg_id = idiag.cmd.data[0];
2272
 
        value = idiag.cmd.data[1];
 
2664
        drb_reg_id = idiag.cmd.data[IDIAG_DRBACC_REGID_INDX];
 
2665
        value = idiag.cmd.data[IDIAG_DRBACC_VALUE_INDX];
2273
2666
 
2274
2667
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
2275
2668
            idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
2329
2722
        return -EINVAL;
2330
2723
}
2331
2724
 
 
2725
/**
 
2726
 * lpfc_idiag_ctlacc_read_reg - idiag debugfs read a control registers
 
2727
 * @phba: The pointer to hba structure.
 
2728
 * @pbuffer: The pointer to the buffer to copy the data to.
 
2729
 * @len: The lenght of bytes to copied.
 
2730
 * @drbregid: The id to doorbell registers.
 
2731
 *
 
2732
 * Description:
 
2733
 * This routine reads a control register and copies its content to the
 
2734
 * user buffer pointed to by @pbuffer.
 
2735
 *
 
2736
 * Returns:
 
2737
 * This function returns the amount of data that was copied into @pbuffer.
 
2738
 **/
 
2739
static int
 
2740
lpfc_idiag_ctlacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
 
2741
                           int len, uint32_t ctlregid)
 
2742
{
 
2743
 
 
2744
        if (!pbuffer)
 
2745
                return 0;
 
2746
 
 
2747
        switch (ctlregid) {
 
2748
        case LPFC_CTL_PORT_SEM:
 
2749
                len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
 
2750
                                "Port SemReg:   0x%08x\n",
 
2751
                                readl(phba->sli4_hba.conf_regs_memmap_p +
 
2752
                                      LPFC_CTL_PORT_SEM_OFFSET));
 
2753
                break;
 
2754
        case LPFC_CTL_PORT_STA:
 
2755
                len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
 
2756
                                "Port StaReg:   0x%08x\n",
 
2757
                                readl(phba->sli4_hba.conf_regs_memmap_p +
 
2758
                                      LPFC_CTL_PORT_STA_OFFSET));
 
2759
                break;
 
2760
        case LPFC_CTL_PORT_CTL:
 
2761
                len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
 
2762
                                "Port CtlReg:   0x%08x\n",
 
2763
                                readl(phba->sli4_hba.conf_regs_memmap_p +
 
2764
                                      LPFC_CTL_PORT_CTL_OFFSET));
 
2765
                break;
 
2766
        case LPFC_CTL_PORT_ER1:
 
2767
                len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
 
2768
                                "Port Er1Reg:   0x%08x\n",
 
2769
                                readl(phba->sli4_hba.conf_regs_memmap_p +
 
2770
                                      LPFC_CTL_PORT_ER1_OFFSET));
 
2771
                break;
 
2772
        case LPFC_CTL_PORT_ER2:
 
2773
                len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
 
2774
                                "Port Er2Reg:   0x%08x\n",
 
2775
                                readl(phba->sli4_hba.conf_regs_memmap_p +
 
2776
                                      LPFC_CTL_PORT_ER2_OFFSET));
 
2777
                break;
 
2778
        case LPFC_CTL_PDEV_CTL:
 
2779
                len += snprintf(pbuffer+len, LPFC_CTL_ACC_BUF_SIZE-len,
 
2780
                                "PDev CtlReg:   0x%08x\n",
 
2781
                                readl(phba->sli4_hba.conf_regs_memmap_p +
 
2782
                                      LPFC_CTL_PDEV_CTL_OFFSET));
 
2783
                break;
 
2784
        default:
 
2785
                break;
 
2786
        }
 
2787
        return len;
 
2788
}
 
2789
 
 
2790
/**
 
2791
 * lpfc_idiag_ctlacc_read - idiag debugfs read port and device control register
 
2792
 * @file: The file pointer to read from.
 
2793
 * @buf: The buffer to copy the data to.
 
2794
 * @nbytes: The number of bytes to read.
 
2795
 * @ppos: The position in the file to start reading from.
 
2796
 *
 
2797
 * Description:
 
2798
 * This routine reads data from the @phba port and device registers according
 
2799
 * to the idiag command, and copies to user @buf.
 
2800
 *
 
2801
 * Returns:
 
2802
 * This function returns the amount of data that was read (this could be less
 
2803
 * than @nbytes if the end of the file was reached) or a negative error value.
 
2804
 **/
 
2805
static ssize_t
 
2806
lpfc_idiag_ctlacc_read(struct file *file, char __user *buf, size_t nbytes,
 
2807
                       loff_t *ppos)
 
2808
{
 
2809
        struct lpfc_debug *debug = file->private_data;
 
2810
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
2811
        uint32_t ctl_reg_id, i;
 
2812
        char *pbuffer;
 
2813
        int len = 0;
 
2814
 
 
2815
        /* This is a user read operation */
 
2816
        debug->op = LPFC_IDIAG_OP_RD;
 
2817
 
 
2818
        if (!debug->buffer)
 
2819
                debug->buffer = kmalloc(LPFC_CTL_ACC_BUF_SIZE, GFP_KERNEL);
 
2820
        if (!debug->buffer)
 
2821
                return 0;
 
2822
        pbuffer = debug->buffer;
 
2823
 
 
2824
        if (*ppos)
 
2825
                return 0;
 
2826
 
 
2827
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD)
 
2828
                ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
 
2829
        else
 
2830
                return 0;
 
2831
 
 
2832
        if (ctl_reg_id == LPFC_CTL_ACC_ALL)
 
2833
                for (i = 1; i <= LPFC_CTL_MAX; i++)
 
2834
                        len = lpfc_idiag_ctlacc_read_reg(phba,
 
2835
                                                         pbuffer, len, i);
 
2836
        else
 
2837
                len = lpfc_idiag_ctlacc_read_reg(phba,
 
2838
                                                 pbuffer, len, ctl_reg_id);
 
2839
 
 
2840
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
2841
}
 
2842
 
 
2843
/**
 
2844
 * lpfc_idiag_ctlacc_write - Syntax check and set up idiag ctlacc commands
 
2845
 * @file: The file pointer to read from.
 
2846
 * @buf: The buffer to copy the user data from.
 
2847
 * @nbytes: The number of bytes to get.
 
2848
 * @ppos: The position in the file to start reading from.
 
2849
 *
 
2850
 * This routine get the debugfs idiag command struct from user space and then
 
2851
 * perform the syntax check for port and device control register read (dump)
 
2852
 * or write (set) command accordingly.
 
2853
 *
 
2854
 * It returns the @nbytges passing in from debugfs user space when successful.
 
2855
 * In case of error conditions, it returns proper error code back to the user
 
2856
 * space.
 
2857
 **/
 
2858
static ssize_t
 
2859
lpfc_idiag_ctlacc_write(struct file *file, const char __user *buf,
 
2860
                        size_t nbytes, loff_t *ppos)
 
2861
{
 
2862
        struct lpfc_debug *debug = file->private_data;
 
2863
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
2864
        uint32_t ctl_reg_id, value, reg_val = 0;
 
2865
        void __iomem *ctl_reg;
 
2866
        int rc;
 
2867
 
 
2868
        /* This is a user write operation */
 
2869
        debug->op = LPFC_IDIAG_OP_WR;
 
2870
 
 
2871
        rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
 
2872
        if (rc < 0)
 
2873
                return rc;
 
2874
 
 
2875
        /* Sanity check on command line arguments */
 
2876
        ctl_reg_id = idiag.cmd.data[IDIAG_CTLACC_REGID_INDX];
 
2877
        value = idiag.cmd.data[IDIAG_CTLACC_VALUE_INDX];
 
2878
 
 
2879
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
 
2880
            idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
 
2881
            idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
 
2882
                if (rc != LPFC_CTL_ACC_WR_CMD_ARG)
 
2883
                        goto error_out;
 
2884
                if (ctl_reg_id > LPFC_CTL_MAX)
 
2885
                        goto error_out;
 
2886
        } else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_RD) {
 
2887
                if (rc != LPFC_CTL_ACC_RD_CMD_ARG)
 
2888
                        goto error_out;
 
2889
                if ((ctl_reg_id > LPFC_CTL_MAX) &&
 
2890
                    (ctl_reg_id != LPFC_CTL_ACC_ALL))
 
2891
                        goto error_out;
 
2892
        } else
 
2893
                goto error_out;
 
2894
 
 
2895
        /* Perform the write access operation */
 
2896
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR ||
 
2897
            idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST ||
 
2898
            idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
 
2899
                switch (ctl_reg_id) {
 
2900
                case LPFC_CTL_PORT_SEM:
 
2901
                        ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
 
2902
                                        LPFC_CTL_PORT_SEM_OFFSET;
 
2903
                        break;
 
2904
                case LPFC_CTL_PORT_STA:
 
2905
                        ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
 
2906
                                        LPFC_CTL_PORT_STA_OFFSET;
 
2907
                        break;
 
2908
                case LPFC_CTL_PORT_CTL:
 
2909
                        ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
 
2910
                                        LPFC_CTL_PORT_CTL_OFFSET;
 
2911
                        break;
 
2912
                case LPFC_CTL_PORT_ER1:
 
2913
                        ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
 
2914
                                        LPFC_CTL_PORT_ER1_OFFSET;
 
2915
                        break;
 
2916
                case LPFC_CTL_PORT_ER2:
 
2917
                        ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
 
2918
                                        LPFC_CTL_PORT_ER2_OFFSET;
 
2919
                        break;
 
2920
                case LPFC_CTL_PDEV_CTL:
 
2921
                        ctl_reg = phba->sli4_hba.conf_regs_memmap_p +
 
2922
                                        LPFC_CTL_PDEV_CTL_OFFSET;
 
2923
                        break;
 
2924
                default:
 
2925
                        goto error_out;
 
2926
                }
 
2927
 
 
2928
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_WR)
 
2929
                        reg_val = value;
 
2930
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_ST) {
 
2931
                        reg_val = readl(ctl_reg);
 
2932
                        reg_val |= value;
 
2933
                }
 
2934
                if (idiag.cmd.opcode == LPFC_IDIAG_CMD_CTLACC_CL) {
 
2935
                        reg_val = readl(ctl_reg);
 
2936
                        reg_val &= ~value;
 
2937
                }
 
2938
                writel(reg_val, ctl_reg);
 
2939
                readl(ctl_reg); /* flush */
 
2940
        }
 
2941
        return nbytes;
 
2942
 
 
2943
error_out:
 
2944
        /* Clean out command structure on command error out */
 
2945
        memset(&idiag, 0, sizeof(idiag));
 
2946
        return -EINVAL;
 
2947
}
 
2948
 
 
2949
/**
 
2950
 * lpfc_idiag_mbxacc_get_setup - idiag debugfs get mailbox access setup
 
2951
 * @phba: Pointer to HBA context object.
 
2952
 * @pbuffer: Pointer to data buffer.
 
2953
 *
 
2954
 * Description:
 
2955
 * This routine gets the driver mailbox access debugfs setup information.
 
2956
 *
 
2957
 * Returns:
 
2958
 * This function returns the amount of data that was read (this could be less
 
2959
 * than @nbytes if the end of the file was reached) or a negative error value.
 
2960
 **/
 
2961
static int
 
2962
lpfc_idiag_mbxacc_get_setup(struct lpfc_hba *phba, char *pbuffer)
 
2963
{
 
2964
        uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
 
2965
        int len = 0;
 
2966
 
 
2967
        mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
 
2968
        mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
 
2969
        mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
 
2970
        mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
 
2971
 
 
2972
        len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
 
2973
                        "mbx_dump_map: 0x%08x\n", mbx_dump_map);
 
2974
        len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
 
2975
                        "mbx_dump_cnt: %04d\n", mbx_dump_cnt);
 
2976
        len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
 
2977
                        "mbx_word_cnt: %04d\n", mbx_word_cnt);
 
2978
        len += snprintf(pbuffer+len, LPFC_MBX_ACC_BUF_SIZE-len,
 
2979
                        "mbx_mbox_cmd: 0x%02x\n", mbx_mbox_cmd);
 
2980
 
 
2981
        return len;
 
2982
}
 
2983
 
 
2984
/**
 
2985
 * lpfc_idiag_mbxacc_read - idiag debugfs read on mailbox access
 
2986
 * @file: The file pointer to read from.
 
2987
 * @buf: The buffer to copy the data to.
 
2988
 * @nbytes: The number of bytes to read.
 
2989
 * @ppos: The position in the file to start reading from.
 
2990
 *
 
2991
 * Description:
 
2992
 * This routine reads data from the @phba driver mailbox access debugfs setup
 
2993
 * information.
 
2994
 *
 
2995
 * Returns:
 
2996
 * This function returns the amount of data that was read (this could be less
 
2997
 * than @nbytes if the end of the file was reached) or a negative error value.
 
2998
 **/
 
2999
static ssize_t
 
3000
lpfc_idiag_mbxacc_read(struct file *file, char __user *buf, size_t nbytes,
 
3001
                       loff_t *ppos)
 
3002
{
 
3003
        struct lpfc_debug *debug = file->private_data;
 
3004
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
3005
        char *pbuffer;
 
3006
        int len = 0;
 
3007
 
 
3008
        /* This is a user read operation */
 
3009
        debug->op = LPFC_IDIAG_OP_RD;
 
3010
 
 
3011
        if (!debug->buffer)
 
3012
                debug->buffer = kmalloc(LPFC_MBX_ACC_BUF_SIZE, GFP_KERNEL);
 
3013
        if (!debug->buffer)
 
3014
                return 0;
 
3015
        pbuffer = debug->buffer;
 
3016
 
 
3017
        if (*ppos)
 
3018
                return 0;
 
3019
 
 
3020
        if ((idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP) &&
 
3021
            (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP))
 
3022
                return 0;
 
3023
 
 
3024
        len = lpfc_idiag_mbxacc_get_setup(phba, pbuffer);
 
3025
 
 
3026
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
3027
}
 
3028
 
 
3029
/**
 
3030
 * lpfc_idiag_mbxacc_write - Syntax check and set up idiag mbxacc commands
 
3031
 * @file: The file pointer to read from.
 
3032
 * @buf: The buffer to copy the user data from.
 
3033
 * @nbytes: The number of bytes to get.
 
3034
 * @ppos: The position in the file to start reading from.
 
3035
 *
 
3036
 * This routine get the debugfs idiag command struct from user space and then
 
3037
 * perform the syntax check for driver mailbox command (dump) and sets up the
 
3038
 * necessary states in the idiag command struct accordingly.
 
3039
 *
 
3040
 * It returns the @nbytges passing in from debugfs user space when successful.
 
3041
 * In case of error conditions, it returns proper error code back to the user
 
3042
 * space.
 
3043
 **/
 
3044
static ssize_t
 
3045
lpfc_idiag_mbxacc_write(struct file *file, const char __user *buf,
 
3046
                        size_t nbytes, loff_t *ppos)
 
3047
{
 
3048
        struct lpfc_debug *debug = file->private_data;
 
3049
        uint32_t mbx_dump_map, mbx_dump_cnt, mbx_word_cnt, mbx_mbox_cmd;
 
3050
        int rc;
 
3051
 
 
3052
        /* This is a user write operation */
 
3053
        debug->op = LPFC_IDIAG_OP_WR;
 
3054
 
 
3055
        rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
 
3056
        if (rc < 0)
 
3057
                return rc;
 
3058
 
 
3059
        /* Sanity check on command line arguments */
 
3060
        mbx_mbox_cmd = idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
 
3061
        mbx_dump_map = idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
 
3062
        mbx_dump_cnt = idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
 
3063
        mbx_word_cnt = idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
 
3064
 
 
3065
        if (idiag.cmd.opcode == LPFC_IDIAG_CMD_MBXACC_DP) {
 
3066
                if (!(mbx_dump_map & LPFC_MBX_DMP_MBX_ALL))
 
3067
                        goto error_out;
 
3068
                if ((mbx_dump_map & ~LPFC_MBX_DMP_MBX_ALL) &&
 
3069
                    (mbx_dump_map != LPFC_MBX_DMP_ALL))
 
3070
                        goto error_out;
 
3071
                if (mbx_word_cnt > sizeof(MAILBOX_t))
 
3072
                        goto error_out;
 
3073
        } else if (idiag.cmd.opcode == LPFC_IDIAG_BSG_MBXACC_DP) {
 
3074
                if (!(mbx_dump_map & LPFC_BSG_DMP_MBX_ALL))
 
3075
                        goto error_out;
 
3076
                if ((mbx_dump_map & ~LPFC_BSG_DMP_MBX_ALL) &&
 
3077
                    (mbx_dump_map != LPFC_MBX_DMP_ALL))
 
3078
                        goto error_out;
 
3079
                if (mbx_word_cnt > (BSG_MBOX_SIZE)/4)
 
3080
                        goto error_out;
 
3081
                if (mbx_mbox_cmd != 0x9b)
 
3082
                        goto error_out;
 
3083
        } else
 
3084
                goto error_out;
 
3085
 
 
3086
        if (mbx_word_cnt == 0)
 
3087
                goto error_out;
 
3088
        if (rc != LPFC_MBX_DMP_ARG)
 
3089
                goto error_out;
 
3090
        if (mbx_mbox_cmd & ~0xff)
 
3091
                goto error_out;
 
3092
 
 
3093
        /* condition for stop mailbox dump */
 
3094
        if (mbx_dump_cnt == 0)
 
3095
                goto reset_out;
 
3096
 
 
3097
        return nbytes;
 
3098
 
 
3099
reset_out:
 
3100
        /* Clean out command structure on command error out */
 
3101
        memset(&idiag, 0, sizeof(idiag));
 
3102
        return nbytes;
 
3103
 
 
3104
error_out:
 
3105
        /* Clean out command structure on command error out */
 
3106
        memset(&idiag, 0, sizeof(idiag));
 
3107
        return -EINVAL;
 
3108
}
 
3109
 
 
3110
/**
 
3111
 * lpfc_idiag_extacc_avail_get - get the available extents information
 
3112
 * @phba: pointer to lpfc hba data structure.
 
3113
 * @pbuffer: pointer to internal buffer.
 
3114
 * @len: length into the internal buffer data has been copied.
 
3115
 *
 
3116
 * Description:
 
3117
 * This routine is to get the available extent information.
 
3118
 *
 
3119
 * Returns:
 
3120
 * overall lenth of the data read into the internal buffer.
 
3121
 **/
 
3122
static int
 
3123
lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len)
 
3124
{
 
3125
        uint16_t ext_cnt, ext_size;
 
3126
 
 
3127
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3128
                        "\nAvailable Extents Information:\n");
 
3129
 
 
3130
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3131
                        "\tPort Available VPI extents: ");
 
3132
        lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VPI,
 
3133
                                       &ext_cnt, &ext_size);
 
3134
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3135
                        "Count %3d, Size %3d\n", ext_cnt, ext_size);
 
3136
 
 
3137
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3138
                        "\tPort Available VFI extents: ");
 
3139
        lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_VFI,
 
3140
                                       &ext_cnt, &ext_size);
 
3141
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3142
                        "Count %3d, Size %3d\n", ext_cnt, ext_size);
 
3143
 
 
3144
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3145
                        "\tPort Available RPI extents: ");
 
3146
        lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_RPI,
 
3147
                                       &ext_cnt, &ext_size);
 
3148
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3149
                        "Count %3d, Size %3d\n", ext_cnt, ext_size);
 
3150
 
 
3151
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3152
                        "\tPort Available XRI extents: ");
 
3153
        lpfc_sli4_get_avail_extnt_rsrc(phba, LPFC_RSC_TYPE_FCOE_XRI,
 
3154
                                       &ext_cnt, &ext_size);
 
3155
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3156
                        "Count %3d, Size %3d\n", ext_cnt, ext_size);
 
3157
 
 
3158
        return len;
 
3159
}
 
3160
 
 
3161
/**
 
3162
 * lpfc_idiag_extacc_alloc_get - get the allocated extents information
 
3163
 * @phba: pointer to lpfc hba data structure.
 
3164
 * @pbuffer: pointer to internal buffer.
 
3165
 * @len: length into the internal buffer data has been copied.
 
3166
 *
 
3167
 * Description:
 
3168
 * This routine is to get the allocated extent information.
 
3169
 *
 
3170
 * Returns:
 
3171
 * overall lenth of the data read into the internal buffer.
 
3172
 **/
 
3173
static int
 
3174
lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len)
 
3175
{
 
3176
        uint16_t ext_cnt, ext_size;
 
3177
        int rc;
 
3178
 
 
3179
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3180
                        "\nAllocated Extents Information:\n");
 
3181
 
 
3182
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3183
                        "\tHost Allocated VPI extents: ");
 
3184
        rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VPI,
 
3185
                                            &ext_cnt, &ext_size);
 
3186
        if (!rc)
 
3187
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3188
                                "Port %d Extent %3d, Size %3d\n",
 
3189
                                phba->brd_no, ext_cnt, ext_size);
 
3190
        else
 
3191
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3192
                                "N/A\n");
 
3193
 
 
3194
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3195
                        "\tHost Allocated VFI extents: ");
 
3196
        rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_VFI,
 
3197
                                            &ext_cnt, &ext_size);
 
3198
        if (!rc)
 
3199
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3200
                                "Port %d Extent %3d, Size %3d\n",
 
3201
                                phba->brd_no, ext_cnt, ext_size);
 
3202
        else
 
3203
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3204
                                "N/A\n");
 
3205
 
 
3206
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3207
                        "\tHost Allocated RPI extents: ");
 
3208
        rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_RPI,
 
3209
                                            &ext_cnt, &ext_size);
 
3210
        if (!rc)
 
3211
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3212
                                "Port %d Extent %3d, Size %3d\n",
 
3213
                                phba->brd_no, ext_cnt, ext_size);
 
3214
        else
 
3215
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3216
                                "N/A\n");
 
3217
 
 
3218
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3219
                        "\tHost Allocated XRI extents: ");
 
3220
        rc = lpfc_sli4_get_allocated_extnts(phba, LPFC_RSC_TYPE_FCOE_XRI,
 
3221
                                            &ext_cnt, &ext_size);
 
3222
        if (!rc)
 
3223
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3224
                                "Port %d Extent %3d, Size %3d\n",
 
3225
                                phba->brd_no, ext_cnt, ext_size);
 
3226
        else
 
3227
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3228
                                "N/A\n");
 
3229
 
 
3230
        return len;
 
3231
}
 
3232
 
 
3233
/**
 
3234
 * lpfc_idiag_extacc_drivr_get - get driver extent information
 
3235
 * @phba: pointer to lpfc hba data structure.
 
3236
 * @pbuffer: pointer to internal buffer.
 
3237
 * @len: length into the internal buffer data has been copied.
 
3238
 *
 
3239
 * Description:
 
3240
 * This routine is to get the driver extent information.
 
3241
 *
 
3242
 * Returns:
 
3243
 * overall lenth of the data read into the internal buffer.
 
3244
 **/
 
3245
static int
 
3246
lpfc_idiag_extacc_drivr_get(struct lpfc_hba *phba, char *pbuffer, int len)
 
3247
{
 
3248
        struct lpfc_rsrc_blks *rsrc_blks;
 
3249
        int index;
 
3250
 
 
3251
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3252
                        "\nDriver Extents Information:\n");
 
3253
 
 
3254
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3255
                        "\tVPI extents:\n");
 
3256
        index = 0;
 
3257
        list_for_each_entry(rsrc_blks, &phba->lpfc_vpi_blk_list, list) {
 
3258
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3259
                                "\t\tBlock %3d: Start %4d, Count %4d\n",
 
3260
                                index, rsrc_blks->rsrc_start,
 
3261
                                rsrc_blks->rsrc_size);
 
3262
                index++;
 
3263
        }
 
3264
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3265
                        "\tVFI extents:\n");
 
3266
        index = 0;
 
3267
        list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_vfi_blk_list,
 
3268
                            list) {
 
3269
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3270
                                "\t\tBlock %3d: Start %4d, Count %4d\n",
 
3271
                                index, rsrc_blks->rsrc_start,
 
3272
                                rsrc_blks->rsrc_size);
 
3273
                index++;
 
3274
        }
 
3275
 
 
3276
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3277
                        "\tRPI extents:\n");
 
3278
        index = 0;
 
3279
        list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_rpi_blk_list,
 
3280
                            list) {
 
3281
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3282
                                "\t\tBlock %3d: Start %4d, Count %4d\n",
 
3283
                                index, rsrc_blks->rsrc_start,
 
3284
                                rsrc_blks->rsrc_size);
 
3285
                index++;
 
3286
        }
 
3287
 
 
3288
        len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3289
                        "\tXRI extents:\n");
 
3290
        index = 0;
 
3291
        list_for_each_entry(rsrc_blks, &phba->sli4_hba.lpfc_xri_blk_list,
 
3292
                            list) {
 
3293
                len += snprintf(pbuffer+len, LPFC_EXT_ACC_BUF_SIZE-len,
 
3294
                                "\t\tBlock %3d: Start %4d, Count %4d\n",
 
3295
                                index, rsrc_blks->rsrc_start,
 
3296
                                rsrc_blks->rsrc_size);
 
3297
                index++;
 
3298
        }
 
3299
 
 
3300
        return len;
 
3301
}
 
3302
 
 
3303
/**
 
3304
 * lpfc_idiag_extacc_write - Syntax check and set up idiag extacc commands
 
3305
 * @file: The file pointer to read from.
 
3306
 * @buf: The buffer to copy the user data from.
 
3307
 * @nbytes: The number of bytes to get.
 
3308
 * @ppos: The position in the file to start reading from.
 
3309
 *
 
3310
 * This routine get the debugfs idiag command struct from user space and then
 
3311
 * perform the syntax check for extent information access commands and sets
 
3312
 * up the necessary states in the idiag command struct accordingly.
 
3313
 *
 
3314
 * It returns the @nbytges passing in from debugfs user space when successful.
 
3315
 * In case of error conditions, it returns proper error code back to the user
 
3316
 * space.
 
3317
 **/
 
3318
static ssize_t
 
3319
lpfc_idiag_extacc_write(struct file *file, const char __user *buf,
 
3320
                        size_t nbytes, loff_t *ppos)
 
3321
{
 
3322
        struct lpfc_debug *debug = file->private_data;
 
3323
        uint32_t ext_map;
 
3324
        int rc;
 
3325
 
 
3326
        /* This is a user write operation */
 
3327
        debug->op = LPFC_IDIAG_OP_WR;
 
3328
 
 
3329
        rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
 
3330
        if (rc < 0)
 
3331
                return rc;
 
3332
 
 
3333
        ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
 
3334
 
 
3335
        if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
 
3336
                goto error_out;
 
3337
        if (rc != LPFC_EXT_ACC_CMD_ARG)
 
3338
                goto error_out;
 
3339
        if (!(ext_map & LPFC_EXT_ACC_ALL))
 
3340
                goto error_out;
 
3341
 
 
3342
        return nbytes;
 
3343
error_out:
 
3344
        /* Clean out command structure on command error out */
 
3345
        memset(&idiag, 0, sizeof(idiag));
 
3346
        return -EINVAL;
 
3347
}
 
3348
 
 
3349
/**
 
3350
 * lpfc_idiag_extacc_read - idiag debugfs read access to extent information
 
3351
 * @file: The file pointer to read from.
 
3352
 * @buf: The buffer to copy the data to.
 
3353
 * @nbytes: The number of bytes to read.
 
3354
 * @ppos: The position in the file to start reading from.
 
3355
 *
 
3356
 * Description:
 
3357
 * This routine reads data from the proper extent information according to
 
3358
 * the idiag command, and copies to user @buf.
 
3359
 *
 
3360
 * Returns:
 
3361
 * This function returns the amount of data that was read (this could be less
 
3362
 * than @nbytes if the end of the file was reached) or a negative error value.
 
3363
 **/
 
3364
static ssize_t
 
3365
lpfc_idiag_extacc_read(struct file *file, char __user *buf, size_t nbytes,
 
3366
                       loff_t *ppos)
 
3367
{
 
3368
        struct lpfc_debug *debug = file->private_data;
 
3369
        struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
 
3370
        char *pbuffer;
 
3371
        uint32_t ext_map;
 
3372
        int len = 0;
 
3373
 
 
3374
        /* This is a user read operation */
 
3375
        debug->op = LPFC_IDIAG_OP_RD;
 
3376
 
 
3377
        if (!debug->buffer)
 
3378
                debug->buffer = kmalloc(LPFC_EXT_ACC_BUF_SIZE, GFP_KERNEL);
 
3379
        if (!debug->buffer)
 
3380
                return 0;
 
3381
        pbuffer = debug->buffer;
 
3382
        if (*ppos)
 
3383
                return 0;
 
3384
        if (idiag.cmd.opcode != LPFC_IDIAG_CMD_EXTACC_RD)
 
3385
                return 0;
 
3386
 
 
3387
        ext_map = idiag.cmd.data[IDIAG_EXTACC_EXMAP_INDX];
 
3388
        if (ext_map & LPFC_EXT_ACC_AVAIL)
 
3389
                len = lpfc_idiag_extacc_avail_get(phba, pbuffer, len);
 
3390
        if (ext_map & LPFC_EXT_ACC_ALLOC)
 
3391
                len = lpfc_idiag_extacc_alloc_get(phba, pbuffer, len);
 
3392
        if (ext_map & LPFC_EXT_ACC_DRIVR)
 
3393
                len = lpfc_idiag_extacc_drivr_get(phba, pbuffer, len);
 
3394
 
 
3395
        return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 
3396
}
 
3397
 
2332
3398
#undef lpfc_debugfs_op_disc_trc
2333
3399
static const struct file_operations lpfc_debugfs_op_disc_trc = {
2334
3400
        .owner =        THIS_MODULE,
2394
3460
        .release =      lpfc_debugfs_dumpDataDif_release,
2395
3461
};
2396
3462
 
 
3463
#undef lpfc_debugfs_op_dif_err
 
3464
static const struct file_operations lpfc_debugfs_op_dif_err = {
 
3465
        .owner =        THIS_MODULE,
 
3466
        .open =         lpfc_debugfs_dif_err_open,
 
3467
        .llseek =       lpfc_debugfs_lseek,
 
3468
        .read =         lpfc_debugfs_dif_err_read,
 
3469
        .write =        lpfc_debugfs_dif_err_write,
 
3470
        .release =      lpfc_debugfs_dif_err_release,
 
3471
};
 
3472
 
2397
3473
#undef lpfc_debugfs_op_slow_ring_trc
2398
3474
static const struct file_operations lpfc_debugfs_op_slow_ring_trc = {
2399
3475
        .owner =        THIS_MODULE,
2419
3495
        .release =      lpfc_idiag_cmd_release,
2420
3496
};
2421
3497
 
 
3498
#undef lpfc_idiag_op_barAcc
 
3499
static const struct file_operations lpfc_idiag_op_barAcc = {
 
3500
        .owner =        THIS_MODULE,
 
3501
        .open =         lpfc_idiag_open,
 
3502
        .llseek =       lpfc_debugfs_lseek,
 
3503
        .read =         lpfc_idiag_baracc_read,
 
3504
        .write =        lpfc_idiag_baracc_write,
 
3505
        .release =      lpfc_idiag_cmd_release,
 
3506
};
 
3507
 
2422
3508
#undef lpfc_idiag_op_queInfo
2423
3509
static const struct file_operations lpfc_idiag_op_queInfo = {
2424
3510
        .owner =        THIS_MODULE,
2427
3513
        .release =      lpfc_idiag_release,
2428
3514
};
2429
3515
 
2430
 
#undef lpfc_idiag_op_queacc
 
3516
#undef lpfc_idiag_op_queAcc
2431
3517
static const struct file_operations lpfc_idiag_op_queAcc = {
2432
3518
        .owner =        THIS_MODULE,
2433
3519
        .open =         lpfc_idiag_open,
2437
3523
        .release =      lpfc_idiag_cmd_release,
2438
3524
};
2439
3525
 
2440
 
#undef lpfc_idiag_op_drbacc
 
3526
#undef lpfc_idiag_op_drbAcc
2441
3527
static const struct file_operations lpfc_idiag_op_drbAcc = {
2442
3528
        .owner =        THIS_MODULE,
2443
3529
        .open =         lpfc_idiag_open,
2447
3533
        .release =      lpfc_idiag_cmd_release,
2448
3534
};
2449
3535
 
2450
 
#endif
 
3536
#undef lpfc_idiag_op_ctlAcc
 
3537
static const struct file_operations lpfc_idiag_op_ctlAcc = {
 
3538
        .owner =        THIS_MODULE,
 
3539
        .open =         lpfc_idiag_open,
 
3540
        .llseek =       lpfc_debugfs_lseek,
 
3541
        .read =         lpfc_idiag_ctlacc_read,
 
3542
        .write =        lpfc_idiag_ctlacc_write,
 
3543
        .release =      lpfc_idiag_cmd_release,
 
3544
};
 
3545
 
 
3546
#undef lpfc_idiag_op_mbxAcc
 
3547
static const struct file_operations lpfc_idiag_op_mbxAcc = {
 
3548
        .owner =        THIS_MODULE,
 
3549
        .open =         lpfc_idiag_open,
 
3550
        .llseek =       lpfc_debugfs_lseek,
 
3551
        .read =         lpfc_idiag_mbxacc_read,
 
3552
        .write =        lpfc_idiag_mbxacc_write,
 
3553
        .release =      lpfc_idiag_cmd_release,
 
3554
};
 
3555
 
 
3556
#undef lpfc_idiag_op_extAcc
 
3557
static const struct file_operations lpfc_idiag_op_extAcc = {
 
3558
        .owner =        THIS_MODULE,
 
3559
        .open =         lpfc_idiag_open,
 
3560
        .llseek =       lpfc_debugfs_lseek,
 
3561
        .read =         lpfc_idiag_extacc_read,
 
3562
        .write =        lpfc_idiag_extacc_write,
 
3563
        .release =      lpfc_idiag_cmd_release,
 
3564
};
 
3565
 
 
3566
#endif
 
3567
 
 
3568
/* lpfc_idiag_mbxacc_dump_bsg_mbox - idiag debugfs dump bsg mailbox command
 
3569
 * @phba: Pointer to HBA context object.
 
3570
 * @dmabuf: Pointer to a DMA buffer descriptor.
 
3571
 *
 
3572
 * Description:
 
3573
 * This routine dump a bsg pass-through non-embedded mailbox command with
 
3574
 * external buffer.
 
3575
 **/
 
3576
void
 
3577
lpfc_idiag_mbxacc_dump_bsg_mbox(struct lpfc_hba *phba, enum nemb_type nemb_tp,
 
3578
                                enum mbox_type mbox_tp, enum dma_type dma_tp,
 
3579
                                enum sta_type sta_tp,
 
3580
                                struct lpfc_dmabuf *dmabuf, uint32_t ext_buf)
 
3581
{
 
3582
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
 
3583
        uint32_t *mbx_mbox_cmd, *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt;
 
3584
        char line_buf[LPFC_MBX_ACC_LBUF_SZ];
 
3585
        int len = 0;
 
3586
        uint32_t do_dump = 0;
 
3587
        uint32_t *pword;
 
3588
        uint32_t i;
 
3589
 
 
3590
        if (idiag.cmd.opcode != LPFC_IDIAG_BSG_MBXACC_DP)
 
3591
                return;
 
3592
 
 
3593
        mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
 
3594
        mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
 
3595
        mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
 
3596
        mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
 
3597
 
 
3598
        if (!(*mbx_dump_map & LPFC_MBX_DMP_ALL) ||
 
3599
            (*mbx_dump_cnt == 0) ||
 
3600
            (*mbx_word_cnt == 0))
 
3601
                return;
 
3602
 
 
3603
        if (*mbx_mbox_cmd != 0x9B)
 
3604
                return;
 
3605
 
 
3606
        if ((mbox_tp == mbox_rd) && (dma_tp == dma_mbox)) {
 
3607
                if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_MBX) {
 
3608
                        do_dump |= LPFC_BSG_DMP_MBX_RD_MBX;
 
3609
                        printk(KERN_ERR "\nRead mbox command (x%x), "
 
3610
                               "nemb:0x%x, extbuf_cnt:%d:\n",
 
3611
                               sta_tp, nemb_tp, ext_buf);
 
3612
                }
 
3613
        }
 
3614
        if ((mbox_tp == mbox_rd) && (dma_tp == dma_ebuf)) {
 
3615
                if (*mbx_dump_map & LPFC_BSG_DMP_MBX_RD_BUF) {
 
3616
                        do_dump |= LPFC_BSG_DMP_MBX_RD_BUF;
 
3617
                        printk(KERN_ERR "\nRead mbox buffer (x%x), "
 
3618
                               "nemb:0x%x, extbuf_seq:%d:\n",
 
3619
                               sta_tp, nemb_tp, ext_buf);
 
3620
                }
 
3621
        }
 
3622
        if ((mbox_tp == mbox_wr) && (dma_tp == dma_mbox)) {
 
3623
                if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_MBX) {
 
3624
                        do_dump |= LPFC_BSG_DMP_MBX_WR_MBX;
 
3625
                        printk(KERN_ERR "\nWrite mbox command (x%x), "
 
3626
                               "nemb:0x%x, extbuf_cnt:%d:\n",
 
3627
                               sta_tp, nemb_tp, ext_buf);
 
3628
                }
 
3629
        }
 
3630
        if ((mbox_tp == mbox_wr) && (dma_tp == dma_ebuf)) {
 
3631
                if (*mbx_dump_map & LPFC_BSG_DMP_MBX_WR_BUF) {
 
3632
                        do_dump |= LPFC_BSG_DMP_MBX_WR_BUF;
 
3633
                        printk(KERN_ERR "\nWrite mbox buffer (x%x), "
 
3634
                               "nemb:0x%x, extbuf_seq:%d:\n",
 
3635
                               sta_tp, nemb_tp, ext_buf);
 
3636
                }
 
3637
        }
 
3638
 
 
3639
        /* dump buffer content */
 
3640
        if (do_dump) {
 
3641
                pword = (uint32_t *)dmabuf->virt;
 
3642
                for (i = 0; i < *mbx_word_cnt; i++) {
 
3643
                        if (!(i % 8)) {
 
3644
                                if (i != 0)
 
3645
                                        printk(KERN_ERR "%s\n", line_buf);
 
3646
                                len = 0;
 
3647
                                len += snprintf(line_buf+len,
 
3648
                                                LPFC_MBX_ACC_LBUF_SZ-len,
 
3649
                                                "%03d: ", i);
 
3650
                        }
 
3651
                        len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
 
3652
                                        "%08x ", (uint32_t)*pword);
 
3653
                        pword++;
 
3654
                }
 
3655
                if ((i - 1) % 8)
 
3656
                        printk(KERN_ERR "%s\n", line_buf);
 
3657
                (*mbx_dump_cnt)--;
 
3658
        }
 
3659
 
 
3660
        /* Clean out command structure on reaching dump count */
 
3661
        if (*mbx_dump_cnt == 0)
 
3662
                memset(&idiag, 0, sizeof(idiag));
 
3663
        return;
 
3664
#endif
 
3665
}
 
3666
 
 
3667
/* lpfc_idiag_mbxacc_dump_issue_mbox - idiag debugfs dump issue mailbox command
 
3668
 * @phba: Pointer to HBA context object.
 
3669
 * @dmabuf: Pointer to a DMA buffer descriptor.
 
3670
 *
 
3671
 * Description:
 
3672
 * This routine dump a pass-through non-embedded mailbox command from issue
 
3673
 * mailbox command.
 
3674
 **/
 
3675
void
 
3676
lpfc_idiag_mbxacc_dump_issue_mbox(struct lpfc_hba *phba, MAILBOX_t *pmbox)
 
3677
{
 
3678
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
 
3679
        uint32_t *mbx_dump_map, *mbx_dump_cnt, *mbx_word_cnt, *mbx_mbox_cmd;
 
3680
        char line_buf[LPFC_MBX_ACC_LBUF_SZ];
 
3681
        int len = 0;
 
3682
        uint32_t *pword;
 
3683
        uint8_t *pbyte;
 
3684
        uint32_t i, j;
 
3685
 
 
3686
        if (idiag.cmd.opcode != LPFC_IDIAG_CMD_MBXACC_DP)
 
3687
                return;
 
3688
 
 
3689
        mbx_mbox_cmd = &idiag.cmd.data[IDIAG_MBXACC_MBCMD_INDX];
 
3690
        mbx_dump_map = &idiag.cmd.data[IDIAG_MBXACC_DPMAP_INDX];
 
3691
        mbx_dump_cnt = &idiag.cmd.data[IDIAG_MBXACC_DPCNT_INDX];
 
3692
        mbx_word_cnt = &idiag.cmd.data[IDIAG_MBXACC_WDCNT_INDX];
 
3693
 
 
3694
        if (!(*mbx_dump_map & LPFC_MBX_DMP_MBX_ALL) ||
 
3695
            (*mbx_dump_cnt == 0) ||
 
3696
            (*mbx_word_cnt == 0))
 
3697
                return;
 
3698
 
 
3699
        if ((*mbx_mbox_cmd != LPFC_MBX_ALL_CMD) &&
 
3700
            (*mbx_mbox_cmd != pmbox->mbxCommand))
 
3701
                return;
 
3702
 
 
3703
        /* dump buffer content */
 
3704
        if (*mbx_dump_map & LPFC_MBX_DMP_MBX_WORD) {
 
3705
                printk(KERN_ERR "Mailbox command:0x%x dump by word:\n",
 
3706
                       pmbox->mbxCommand);
 
3707
                pword = (uint32_t *)pmbox;
 
3708
                for (i = 0; i < *mbx_word_cnt; i++) {
 
3709
                        if (!(i % 8)) {
 
3710
                                if (i != 0)
 
3711
                                        printk(KERN_ERR "%s\n", line_buf);
 
3712
                                len = 0;
 
3713
                                memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
 
3714
                                len += snprintf(line_buf+len,
 
3715
                                                LPFC_MBX_ACC_LBUF_SZ-len,
 
3716
                                                "%03d: ", i);
 
3717
                        }
 
3718
                        len += snprintf(line_buf+len, LPFC_MBX_ACC_LBUF_SZ-len,
 
3719
                                        "%08x ",
 
3720
                                        ((uint32_t)*pword) & 0xffffffff);
 
3721
                        pword++;
 
3722
                }
 
3723
                if ((i - 1) % 8)
 
3724
                        printk(KERN_ERR "%s\n", line_buf);
 
3725
                printk(KERN_ERR "\n");
 
3726
        }
 
3727
        if (*mbx_dump_map & LPFC_MBX_DMP_MBX_BYTE) {
 
3728
                printk(KERN_ERR "Mailbox command:0x%x dump by byte:\n",
 
3729
                       pmbox->mbxCommand);
 
3730
                pbyte = (uint8_t *)pmbox;
 
3731
                for (i = 0; i < *mbx_word_cnt; i++) {
 
3732
                        if (!(i % 8)) {
 
3733
                                if (i != 0)
 
3734
                                        printk(KERN_ERR "%s\n", line_buf);
 
3735
                                len = 0;
 
3736
                                memset(line_buf, 0, LPFC_MBX_ACC_LBUF_SZ);
 
3737
                                len += snprintf(line_buf+len,
 
3738
                                                LPFC_MBX_ACC_LBUF_SZ-len,
 
3739
                                                "%03d: ", i);
 
3740
                        }
 
3741
                        for (j = 0; j < 4; j++) {
 
3742
                                len += snprintf(line_buf+len,
 
3743
                                                LPFC_MBX_ACC_LBUF_SZ-len,
 
3744
                                                "%02x",
 
3745
                                                ((uint8_t)*pbyte) & 0xff);
 
3746
                                pbyte++;
 
3747
                        }
 
3748
                        len += snprintf(line_buf+len,
 
3749
                                        LPFC_MBX_ACC_LBUF_SZ-len, " ");
 
3750
                }
 
3751
                if ((i - 1) % 8)
 
3752
                        printk(KERN_ERR "%s\n", line_buf);
 
3753
                printk(KERN_ERR "\n");
 
3754
        }
 
3755
        (*mbx_dump_cnt)--;
 
3756
 
 
3757
        /* Clean out command structure on reaching dump count */
 
3758
        if (*mbx_dump_cnt == 0)
 
3759
                memset(&idiag, 0, sizeof(idiag));
 
3760
        return;
 
3761
#endif
 
3762
}
2451
3763
 
2452
3764
/**
2453
3765
 * lpfc_debugfs_initialize - Initialize debugfs for a vport
2566
3878
                        goto debug_failed;
2567
3879
                }
2568
3880
 
 
3881
                /* Setup DIF Error Injections */
 
3882
                snprintf(name, sizeof(name), "InjErrLBA");
 
3883
                phba->debug_InjErrLBA =
 
3884
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3885
                        phba->hba_debugfs_root,
 
3886
                        phba, &lpfc_debugfs_op_dif_err);
 
3887
                if (!phba->debug_InjErrLBA) {
 
3888
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3889
                                "0807 Cannot create debugfs InjErrLBA\n");
 
3890
                        goto debug_failed;
 
3891
                }
 
3892
                phba->lpfc_injerr_lba = LPFC_INJERR_LBA_OFF;
 
3893
 
 
3894
                snprintf(name, sizeof(name), "writeGuardInjErr");
 
3895
                phba->debug_writeGuard =
 
3896
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3897
                        phba->hba_debugfs_root,
 
3898
                        phba, &lpfc_debugfs_op_dif_err);
 
3899
                if (!phba->debug_writeGuard) {
 
3900
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3901
                                "0802 Cannot create debugfs writeGuard\n");
 
3902
                        goto debug_failed;
 
3903
                }
 
3904
 
 
3905
                snprintf(name, sizeof(name), "writeAppInjErr");
 
3906
                phba->debug_writeApp =
 
3907
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3908
                        phba->hba_debugfs_root,
 
3909
                        phba, &lpfc_debugfs_op_dif_err);
 
3910
                if (!phba->debug_writeApp) {
 
3911
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3912
                                "0803 Cannot create debugfs writeApp\n");
 
3913
                        goto debug_failed;
 
3914
                }
 
3915
 
 
3916
                snprintf(name, sizeof(name), "writeRefInjErr");
 
3917
                phba->debug_writeRef =
 
3918
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3919
                        phba->hba_debugfs_root,
 
3920
                        phba, &lpfc_debugfs_op_dif_err);
 
3921
                if (!phba->debug_writeRef) {
 
3922
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3923
                                "0804 Cannot create debugfs writeRef\n");
 
3924
                        goto debug_failed;
 
3925
                }
 
3926
 
 
3927
                snprintf(name, sizeof(name), "readAppInjErr");
 
3928
                phba->debug_readApp =
 
3929
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3930
                        phba->hba_debugfs_root,
 
3931
                        phba, &lpfc_debugfs_op_dif_err);
 
3932
                if (!phba->debug_readApp) {
 
3933
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3934
                                "0805 Cannot create debugfs readApp\n");
 
3935
                        goto debug_failed;
 
3936
                }
 
3937
 
 
3938
                snprintf(name, sizeof(name), "readRefInjErr");
 
3939
                phba->debug_readRef =
 
3940
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
3941
                        phba->hba_debugfs_root,
 
3942
                        phba, &lpfc_debugfs_op_dif_err);
 
3943
                if (!phba->debug_readRef) {
 
3944
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
3945
                                "0806 Cannot create debugfs readApp\n");
 
3946
                        goto debug_failed;
 
3947
                }
 
3948
 
2569
3949
                /* Setup slow ring trace */
2570
3950
                if (lpfc_debugfs_max_slow_ring_trc) {
2571
3951
                        num = lpfc_debugfs_max_slow_ring_trc - 1;
2672
4052
                                 vport, &lpfc_debugfs_op_nodelist);
2673
4053
        if (!vport->debug_nodelist) {
2674
4054
                lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
2675
 
                                 "0409 Can't create debugfs nodelist\n");
 
4055
                                 "2985 Can't create debugfs nodelist\n");
2676
4056
                goto debug_failed;
2677
4057
        }
2678
4058
 
2709
4089
                idiag.offset.last_rd = 0;
2710
4090
        }
2711
4091
 
 
4092
        /* iDiag PCI BAR access */
 
4093
        snprintf(name, sizeof(name), "barAcc");
 
4094
        if (!phba->idiag_bar_acc) {
 
4095
                phba->idiag_bar_acc =
 
4096
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
4097
                                phba->idiag_root, phba, &lpfc_idiag_op_barAcc);
 
4098
                if (!phba->idiag_bar_acc) {
 
4099
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4100
                                        "3056 Can't create idiag debugfs\n");
 
4101
                        goto debug_failed;
 
4102
                }
 
4103
                idiag.offset.last_rd = 0;
 
4104
        }
 
4105
 
2712
4106
        /* iDiag get PCI function queue information */
2713
4107
        snprintf(name, sizeof(name), "queInfo");
2714
4108
        if (!phba->idiag_que_info) {
2748
4142
                }
2749
4143
        }
2750
4144
 
 
4145
        /* iDiag access PCI function control registers */
 
4146
        snprintf(name, sizeof(name), "ctlAcc");
 
4147
        if (!phba->idiag_ctl_acc) {
 
4148
                phba->idiag_ctl_acc =
 
4149
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
4150
                                phba->idiag_root, phba, &lpfc_idiag_op_ctlAcc);
 
4151
                if (!phba->idiag_ctl_acc) {
 
4152
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4153
                                         "2981 Can't create idiag debugfs\n");
 
4154
                        goto debug_failed;
 
4155
                }
 
4156
        }
 
4157
 
 
4158
        /* iDiag access mbox commands */
 
4159
        snprintf(name, sizeof(name), "mbxAcc");
 
4160
        if (!phba->idiag_mbx_acc) {
 
4161
                phba->idiag_mbx_acc =
 
4162
                        debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
 
4163
                                phba->idiag_root, phba, &lpfc_idiag_op_mbxAcc);
 
4164
                if (!phba->idiag_mbx_acc) {
 
4165
                        lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4166
                                        "2980 Can't create idiag debugfs\n");
 
4167
                        goto debug_failed;
 
4168
                }
 
4169
        }
 
4170
 
 
4171
        /* iDiag extents access commands */
 
4172
        if (phba->sli4_hba.extents_in_use) {
 
4173
                snprintf(name, sizeof(name), "extAcc");
 
4174
                if (!phba->idiag_ext_acc) {
 
4175
                        phba->idiag_ext_acc =
 
4176
                                debugfs_create_file(name,
 
4177
                                                    S_IFREG|S_IRUGO|S_IWUSR,
 
4178
                                                    phba->idiag_root, phba,
 
4179
                                                    &lpfc_idiag_op_extAcc);
 
4180
                        if (!phba->idiag_ext_acc) {
 
4181
                                lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
 
4182
                                                "2986 Cant create "
 
4183
                                                "idiag debugfs\n");
 
4184
                                goto debug_failed;
 
4185
                        }
 
4186
                }
 
4187
        }
 
4188
 
2751
4189
debug_failed:
2752
4190
        return;
2753
4191
#endif
2782
4220
                debugfs_remove(vport->debug_nodelist); /* nodelist */
2783
4221
                vport->debug_nodelist = NULL;
2784
4222
        }
2785
 
 
2786
4223
        if (vport->vport_debugfs_root) {
2787
4224
                debugfs_remove(vport->vport_debugfs_root); /* vportX */
2788
4225
                vport->vport_debugfs_root = NULL;
2811
4248
                        debugfs_remove(phba->debug_dumpDif); /* dumpDif */
2812
4249
                        phba->debug_dumpDif = NULL;
2813
4250
                }
 
4251
                if (phba->debug_InjErrLBA) {
 
4252
                        debugfs_remove(phba->debug_InjErrLBA); /* InjErrLBA */
 
4253
                        phba->debug_InjErrLBA = NULL;
 
4254
                }
 
4255
                if (phba->debug_writeGuard) {
 
4256
                        debugfs_remove(phba->debug_writeGuard); /* writeGuard */
 
4257
                        phba->debug_writeGuard = NULL;
 
4258
                }
 
4259
                if (phba->debug_writeApp) {
 
4260
                        debugfs_remove(phba->debug_writeApp); /* writeApp */
 
4261
                        phba->debug_writeApp = NULL;
 
4262
                }
 
4263
                if (phba->debug_writeRef) {
 
4264
                        debugfs_remove(phba->debug_writeRef); /* writeRef */
 
4265
                        phba->debug_writeRef = NULL;
 
4266
                }
 
4267
                if (phba->debug_readApp) {
 
4268
                        debugfs_remove(phba->debug_readApp); /* readApp */
 
4269
                        phba->debug_readApp = NULL;
 
4270
                }
 
4271
                if (phba->debug_readRef) {
 
4272
                        debugfs_remove(phba->debug_readRef); /* readRef */
 
4273
                        phba->debug_readRef = NULL;
 
4274
                }
2814
4275
 
2815
4276
                if (phba->slow_ring_trc) {
2816
4277
                        kfree(phba->slow_ring_trc);
2826
4287
                 * iDiag release
2827
4288
                 */
2828
4289
                if (phba->sli_rev == LPFC_SLI_REV4) {
 
4290
                        if (phba->idiag_ext_acc) {
 
4291
                                /* iDiag extAcc */
 
4292
                                debugfs_remove(phba->idiag_ext_acc);
 
4293
                                phba->idiag_ext_acc = NULL;
 
4294
                        }
 
4295
                        if (phba->idiag_mbx_acc) {
 
4296
                                /* iDiag mbxAcc */
 
4297
                                debugfs_remove(phba->idiag_mbx_acc);
 
4298
                                phba->idiag_mbx_acc = NULL;
 
4299
                        }
 
4300
                        if (phba->idiag_ctl_acc) {
 
4301
                                /* iDiag ctlAcc */
 
4302
                                debugfs_remove(phba->idiag_ctl_acc);
 
4303
                                phba->idiag_ctl_acc = NULL;
 
4304
                        }
2829
4305
                        if (phba->idiag_drb_acc) {
2830
4306
                                /* iDiag drbAcc */
2831
4307
                                debugfs_remove(phba->idiag_drb_acc);
2841
4317
                                debugfs_remove(phba->idiag_que_info);
2842
4318
                                phba->idiag_que_info = NULL;
2843
4319
                        }
 
4320
                        if (phba->idiag_bar_acc) {
 
4321
                                /* iDiag barAcc */
 
4322
                                debugfs_remove(phba->idiag_bar_acc);
 
4323
                                phba->idiag_bar_acc = NULL;
 
4324
                        }
2844
4325
                        if (phba->idiag_pci_cfg) {
2845
4326
                                /* iDiag pciCfg */
2846
4327
                                debugfs_remove(phba->idiag_pci_cfg);