linux/drivers/scsi/mpt3sas/mpt3sas_debugfs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Debugfs interface Support for MPT (Message Passing Technology) based
   4 * controllers.
   5 *
   6 * Copyright (C) 2020  Broadcom Inc.
   7 *
   8 * Authors: Broadcom Inc.
   9 * Sreekanth Reddy  <sreekanth.reddy@broadcom.com>
  10 * Suganath Prabu <suganath-prabu.subramani@broadcom.com>
  11 *
  12 * Send feedback to : MPT-FusionLinux.pdl@broadcom.com)
  13 *
  14 **/
  15
  16#include <linux/kernel.h>
  17#include <linux/types.h>
  18#include <linux/pci.h>
  19#include <linux/interrupt.h>
  20#include <linux/compat.h>
  21#include <linux/uio.h>
  22
  23#include <scsi/scsi.h>
  24#include <scsi/scsi_device.h>
  25#include <scsi/scsi_host.h>
  26#include "mpt3sas_base.h"
  27#include <linux/debugfs.h>
  28
  29static struct dentry *mpt3sas_debugfs_root;
  30
  31/*
  32 * _debugfs_iocdump_read - copy ioc dump from debugfs buffer
  33 * @filep:      File Pointer
  34 * @ubuf:       Buffer to fill data
  35 * @cnt:        Length of the buffer
  36 * @ppos:       Offset in the file
  37 */
  38
  39static ssize_t
  40_debugfs_iocdump_read(struct file *filp, char __user *ubuf, size_t cnt,
  41        loff_t *ppos)
  42
  43{
  44        struct mpt3sas_debugfs_buffer *debug = filp->private_data;
  45
  46        if (!debug || !debug->buf)
  47                return 0;
  48
  49        return simple_read_from_buffer(ubuf, cnt, ppos, debug->buf, debug->len);
  50}
  51
  52/*
  53 * _debugfs_iocdump_open :      open the ioc_dump debugfs attribute file
  54 */
  55static int
  56_debugfs_iocdump_open(struct inode *inode, struct file *file)
  57{
  58        struct MPT3SAS_ADAPTER *ioc = inode->i_private;
  59        struct mpt3sas_debugfs_buffer *debug;
  60
  61        debug = kzalloc(sizeof(struct mpt3sas_debugfs_buffer), GFP_KERNEL);
  62        if (!debug)
  63                return -ENOMEM;
  64
  65        debug->buf = (void *)ioc;
  66        debug->len = sizeof(struct MPT3SAS_ADAPTER);
  67        file->private_data = debug;
  68        return 0;
  69}
  70
  71/*
  72 * _debugfs_iocdump_release :   release the ioc_dump debugfs attribute
  73 * @inode: inode structure to the corresponds device
  74 * @file: File pointer
  75 */
  76static int
  77_debugfs_iocdump_release(struct inode *inode, struct file *file)
  78{
  79        struct mpt3sas_debugfs_buffer *debug = file->private_data;
  80
  81        if (!debug)
  82                return 0;
  83
  84        file->private_data = NULL;
  85        kfree(debug);
  86        return 0;
  87}
  88
  89static const struct file_operations mpt3sas_debugfs_iocdump_fops = {
  90        .owner          = THIS_MODULE,
  91        .open           = _debugfs_iocdump_open,
  92        .read           = _debugfs_iocdump_read,
  93        .release        = _debugfs_iocdump_release,
  94};
  95
  96/*
  97 * mpt3sas_init_debugfs :       Create debugfs root for mpt3sas driver
  98 */
  99void mpt3sas_init_debugfs(void)
 100{
 101        mpt3sas_debugfs_root = debugfs_create_dir("mpt3sas", NULL);
 102        if (!mpt3sas_debugfs_root)
 103                pr_info("mpt3sas: Cannot create debugfs root\n");
 104}
 105
 106/*
 107 * mpt3sas_exit_debugfs :       Remove debugfs root for mpt3sas driver
 108 */
 109void mpt3sas_exit_debugfs(void)
 110{
 111        debugfs_remove_recursive(mpt3sas_debugfs_root);
 112}
 113
 114/*
 115 * mpt3sas_setup_debugfs :      Setup debugfs per HBA adapter
 116 * ioc:                         MPT3SAS_ADAPTER object
 117 */
 118void
 119mpt3sas_setup_debugfs(struct MPT3SAS_ADAPTER *ioc)
 120{
 121        char name[64];
 122
 123        snprintf(name, sizeof(name), "scsi_host%d", ioc->shost->host_no);
 124        if (!ioc->debugfs_root) {
 125                ioc->debugfs_root =
 126                    debugfs_create_dir(name, mpt3sas_debugfs_root);
 127                if (!ioc->debugfs_root) {
 128                        dev_err(&ioc->pdev->dev,
 129                            "Cannot create per adapter debugfs directory\n");
 130                        return;
 131                }
 132        }
 133
 134        snprintf(name, sizeof(name), "ioc_dump");
 135        ioc->ioc_dump = debugfs_create_file(name, 0444,
 136            ioc->debugfs_root, ioc, &mpt3sas_debugfs_iocdump_fops);
 137        if (!ioc->ioc_dump) {
 138                dev_err(&ioc->pdev->dev,
 139                    "Cannot create ioc_dump debugfs file\n");
 140                debugfs_remove(ioc->debugfs_root);
 141                return;
 142        }
 143
 144        snprintf(name, sizeof(name), "host_recovery");
 145        debugfs_create_u8(name, 0444, ioc->debugfs_root, &ioc->shost_recovery);
 146
 147}
 148
 149/*
 150 * mpt3sas_destroy_debugfs :    Destroy debugfs per HBA adapter
 151 * @ioc:        MPT3SAS_ADAPTER object
 152 */
 153void mpt3sas_destroy_debugfs(struct MPT3SAS_ADAPTER *ioc)
 154{
 155        debugfs_remove_recursive(ioc->debugfs_root);
 156}
 157
 158