158 lines
3.7 KiB
C
158 lines
3.7 KiB
C
|
// SPDX-License-Identifier: GPL-2.0
|
||
|
/*
|
||
|
* Debugfs interface Support for MPT (Message Passing Technology) based
|
||
|
* controllers.
|
||
|
*
|
||
|
* Copyright (C) 2020 Broadcom Inc.
|
||
|
*
|
||
|
* Authors: Broadcom Inc.
|
||
|
* Sreekanth Reddy <sreekanth.reddy@broadcom.com>
|
||
|
* Suganath Prabu <suganath-prabu.subramani@broadcom.com>
|
||
|
*
|
||
|
* Send feedback to : MPT-FusionLinux.pdl@broadcom.com)
|
||
|
*
|
||
|
**/
|
||
|
|
||
|
#include <linux/kernel.h>
|
||
|
#include <linux/types.h>
|
||
|
#include <linux/pci.h>
|
||
|
#include <linux/interrupt.h>
|
||
|
#include <linux/compat.h>
|
||
|
#include <linux/uio.h>
|
||
|
|
||
|
#include <scsi/scsi.h>
|
||
|
#include <scsi/scsi_device.h>
|
||
|
#include <scsi/scsi_host.h>
|
||
|
#include "mpt3sas_base.h"
|
||
|
#include <linux/debugfs.h>
|
||
|
|
||
|
static struct dentry *mpt3sas_debugfs_root;
|
||
|
|
||
|
/*
|
||
|
* _debugfs_iocdump_read - copy ioc dump from debugfs buffer
|
||
|
* @filep: File Pointer
|
||
|
* @ubuf: Buffer to fill data
|
||
|
* @cnt: Length of the buffer
|
||
|
* @ppos: Offset in the file
|
||
|
*/
|
||
|
|
||
|
static ssize_t
|
||
|
_debugfs_iocdump_read(struct file *filp, char __user *ubuf, size_t cnt,
|
||
|
loff_t *ppos)
|
||
|
|
||
|
{
|
||
|
struct mpt3sas_debugfs_buffer *debug = filp->private_data;
|
||
|
|
||
|
if (!debug || !debug->buf)
|
||
|
return 0;
|
||
|
|
||
|
return simple_read_from_buffer(ubuf, cnt, ppos, debug->buf, debug->len);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* _debugfs_iocdump_open : open the ioc_dump debugfs attribute file
|
||
|
*/
|
||
|
static int
|
||
|
_debugfs_iocdump_open(struct inode *inode, struct file *file)
|
||
|
{
|
||
|
struct MPT3SAS_ADAPTER *ioc = inode->i_private;
|
||
|
struct mpt3sas_debugfs_buffer *debug;
|
||
|
|
||
|
debug = kzalloc(sizeof(struct mpt3sas_debugfs_buffer), GFP_KERNEL);
|
||
|
if (!debug)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
debug->buf = (void *)ioc;
|
||
|
debug->len = sizeof(struct MPT3SAS_ADAPTER);
|
||
|
file->private_data = debug;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* _debugfs_iocdump_release : release the ioc_dump debugfs attribute
|
||
|
* @inode: inode structure to the corresponds device
|
||
|
* @file: File pointer
|
||
|
*/
|
||
|
static int
|
||
|
_debugfs_iocdump_release(struct inode *inode, struct file *file)
|
||
|
{
|
||
|
struct mpt3sas_debugfs_buffer *debug = file->private_data;
|
||
|
|
||
|
if (!debug)
|
||
|
return 0;
|
||
|
|
||
|
file->private_data = NULL;
|
||
|
kfree(debug);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static const struct file_operations mpt3sas_debugfs_iocdump_fops = {
|
||
|
.owner = THIS_MODULE,
|
||
|
.open = _debugfs_iocdump_open,
|
||
|
.read = _debugfs_iocdump_read,
|
||
|
.release = _debugfs_iocdump_release,
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* mpt3sas_init_debugfs : Create debugfs root for mpt3sas driver
|
||
|
*/
|
||
|
void mpt3sas_init_debugfs(void)
|
||
|
{
|
||
|
mpt3sas_debugfs_root = debugfs_create_dir("mpt3sas", NULL);
|
||
|
if (!mpt3sas_debugfs_root)
|
||
|
pr_info("mpt3sas: Cannot create debugfs root\n");
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* mpt3sas_exit_debugfs : Remove debugfs root for mpt3sas driver
|
||
|
*/
|
||
|
void mpt3sas_exit_debugfs(void)
|
||
|
{
|
||
|
debugfs_remove_recursive(mpt3sas_debugfs_root);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* mpt3sas_setup_debugfs : Setup debugfs per HBA adapter
|
||
|
* ioc: MPT3SAS_ADAPTER object
|
||
|
*/
|
||
|
void
|
||
|
mpt3sas_setup_debugfs(struct MPT3SAS_ADAPTER *ioc)
|
||
|
{
|
||
|
char name[64];
|
||
|
|
||
|
snprintf(name, sizeof(name), "scsi_host%d", ioc->shost->host_no);
|
||
|
if (!ioc->debugfs_root) {
|
||
|
ioc->debugfs_root =
|
||
|
debugfs_create_dir(name, mpt3sas_debugfs_root);
|
||
|
if (!ioc->debugfs_root) {
|
||
|
dev_err(&ioc->pdev->dev,
|
||
|
"Cannot create per adapter debugfs directory\n");
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
snprintf(name, sizeof(name), "ioc_dump");
|
||
|
ioc->ioc_dump = debugfs_create_file(name, 0444,
|
||
|
ioc->debugfs_root, ioc, &mpt3sas_debugfs_iocdump_fops);
|
||
|
if (!ioc->ioc_dump) {
|
||
|
dev_err(&ioc->pdev->dev,
|
||
|
"Cannot create ioc_dump debugfs file\n");
|
||
|
debugfs_remove(ioc->debugfs_root);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
snprintf(name, sizeof(name), "host_recovery");
|
||
|
debugfs_create_u8(name, 0444, ioc->debugfs_root, &ioc->shost_recovery);
|
||
|
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* mpt3sas_destroy_debugfs : Destroy debugfs per HBA adapter
|
||
|
* @ioc: MPT3SAS_ADAPTER object
|
||
|
*/
|
||
|
void mpt3sas_destroy_debugfs(struct MPT3SAS_ADAPTER *ioc)
|
||
|
{
|
||
|
debugfs_remove_recursive(ioc->debugfs_root);
|
||
|
}
|
||
|
|