Commit | Line | Data |
---|---|---|
2b01b293 SP |
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 | ||
2b01b293 SP |
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 | ||
29 | static 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 | ||
39 | static 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 | */ | |
55 | static 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 | */ | |
76 | static 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 | ||
89 | static 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 | */ | |
99 | void 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 | */ | |
109 | void 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 | */ | |
118 | void | |
119 | mpt3sas_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 | */ | |
153 | void mpt3sas_destroy_debugfs(struct MPT3SAS_ADAPTER *ioc) | |
154 | { | |
155 | debugfs_remove_recursive(ioc->debugfs_root); | |
156 | } | |
157 |