Commit 5e1073d3 authored by Tim Sell's avatar Tim Sell Committed by Greg Kroah-Hartman

staging: unisys: visorhba: simplify and enhance debugfs interface

debugfs info for each visorhba device is now presented by a file named of
the following form within the debugfs tree:

    visorhba/vbus<x>:dev<y>/info

where <x> is the vbus number, and <y> is the relative device number.

Also, the debugfs presentation function was converted to use the seq_file
interface, so that it could access the device context without resorting to
a global array.  This also simplified the function.
Signed-off-by: default avatarTim Sell <Timothy.Sell@unisys.com>
Signed-off-by: default avatarDavid Kershner <david.kershner@unisys.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bf817f2f
......@@ -17,6 +17,7 @@
#include <linux/skbuff.h>
#include <linux/kthread.h>
#include <linux/idr.h>
#include <linux/seq_file.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
......@@ -51,14 +52,7 @@ static int visorhba_pause(struct visor_device *dev,
static int visorhba_resume(struct visor_device *dev,
visorbus_state_complete_func complete_func);
static ssize_t info_debugfs_read(struct file *file, char __user *buf,
size_t len, loff_t *offset);
static int set_no_disk_inquiry_result(unsigned char *buf,
size_t len, bool is_lun0);
static struct dentry *visorhba_debugfs_dir;
static const struct file_operations debugfs_info_fops = {
.read = info_debugfs_read,
};
/* GUIDS for HBA channel type supported by this driver */
static struct visor_channeltype_descriptor visorhba_channel_types[] = {
......@@ -132,6 +126,9 @@ struct visorhba_devdata {
* iovm, instead of raw pointers
*/
struct idr idr;
struct dentry *debugfs_dir;
struct dentry *debugfs_info;
};
struct visorhba_devices_open {
......@@ -667,66 +664,49 @@ static struct scsi_host_template visorhba_driver_template = {
};
/**
* info_debugfs_read - debugfs interface to dump visorhba states
* @file: Debug file
* @buf: buffer to send back to user
* @len: len that can be written to buf
* @offset: offset into buf
* info_debugfs_show - debugfs interface to dump visorhba states
*
* Dumps information about the visorhba driver and devices
* TODO: Make this per vhba
* Returns bytes_read
* This presents a file in the debugfs tree named:
* /visorhba/vbus<x>:dev<y>/info
*/
static ssize_t info_debugfs_read(struct file *file, char __user *buf,
size_t len, loff_t *offset)
static int info_debugfs_show(struct seq_file *seq, void *v)
{
ssize_t bytes_read = 0;
int str_pos = 0;
u64 phys_flags_addr;
int i;
struct visorhba_devdata *devdata;
char *vbuf;
if (len > MAX_BUF)
len = MAX_BUF;
vbuf = kzalloc(len, GFP_KERNEL);
if (!vbuf)
return -ENOMEM;
for (i = 0; i < VISORHBA_OPEN_MAX; i++) {
if (!visorhbas_open[i].devdata)
continue;
devdata = visorhbas_open[i].devdata;
str_pos += scnprintf(vbuf + str_pos,
len - str_pos, "max_buff_len:%u\n",
devdata->max_buff_len);
str_pos += scnprintf(vbuf + str_pos, len - str_pos,
"\ninterrupts_rcvd = %llu, interrupts_disabled = %llu\n",
devdata->interrupts_rcvd,
devdata->interrupts_disabled);
str_pos += scnprintf(vbuf + str_pos,
len - str_pos, "\ninterrupts_notme = %llu,\n",
devdata->interrupts_notme);
phys_flags_addr = virt_to_phys((__force void *)
devdata->flags_addr);
str_pos += scnprintf(vbuf + str_pos, len - str_pos,
"flags_addr = %p, phys_flags_addr=0x%016llx, FeatureFlags=%llu\n",
devdata->flags_addr, phys_flags_addr,
(__le64)readq(devdata->flags_addr));
str_pos += scnprintf(vbuf + str_pos,
len - str_pos, "acquire_failed_cnt:%llu\n",
devdata->acquire_failed_cnt);
str_pos += scnprintf(vbuf + str_pos, len - str_pos, "\n");
struct visorhba_devdata *devdata = seq->private;
seq_printf(seq, "max_buff_len = %u\n", devdata->max_buff_len);
seq_printf(seq, "interrupts_rcvd = %llu\n", devdata->interrupts_rcvd);
seq_printf(seq, "interrupts_disabled = %llu\n",
devdata->interrupts_disabled);
seq_printf(seq, "interrupts_notme = %llu\n",
devdata->interrupts_notme);
seq_printf(seq, "flags_addr = %p\n", devdata->flags_addr);
if (devdata->flags_addr) {
u64 phys_flags_addr =
virt_to_phys((__force void *)devdata->flags_addr);
seq_printf(seq, "phys_flags_addr = 0x%016llx\n",
phys_flags_addr);
seq_printf(seq, "FeatureFlags = %llu\n",
(__le64)readq(devdata->flags_addr));
}
seq_printf(seq, "acquire_failed_cnt = %llu\n",
devdata->acquire_failed_cnt);
bytes_read = simple_read_from_buffer(buf, len, offset, vbuf, str_pos);
kfree(vbuf);
return bytes_read;
return 0;
}
static int info_debugfs_open(struct inode *inode, struct file *file)
{
return single_open(file, info_debugfs_show, inode->i_private);
}
static const struct file_operations info_debugfs_fops = {
.owner = THIS_MODULE,
.open = info_debugfs_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
/**
* complete_taskmgmt_command - complete task management
* @cmdrsp: Response from the IOVM
......@@ -1134,6 +1114,21 @@ static int visorhba_probe(struct visor_device *dev)
devdata->dev = dev;
dev_set_drvdata(&dev->device, devdata);
devdata->debugfs_dir = debugfs_create_dir(dev_name(&dev->device),
visorhba_debugfs_dir);
if (!devdata->debugfs_dir) {
err = -ENOMEM;
goto err_scsi_remove_host;
}
devdata->debugfs_info =
debugfs_create_file("info", S_IRUSR | S_IRGRP,
devdata->debugfs_dir, devdata,
&info_debugfs_fops);
if (!devdata->debugfs_info) {
err = -ENOMEM;
goto err_debugfs_dir;
}
init_waitqueue_head(&devdata->rsp_queue);
spin_lock_init(&devdata->privlock);
devdata->serverdown = false;
......@@ -1144,11 +1139,11 @@ static int visorhba_probe(struct visor_device *dev)
channel_header.features);
err = visorbus_read_channel(dev, channel_offset, &features, 8);
if (err)
goto err_scsi_remove_host;
goto err_debugfs_info;
features |= ULTRA_IO_CHANNEL_IS_POLLING;
err = visorbus_write_channel(dev, channel_offset, &features, 8);
if (err)
goto err_scsi_remove_host;
goto err_debugfs_info;
idr_init(&devdata->idr);
......@@ -1160,6 +1155,12 @@ static int visorhba_probe(struct visor_device *dev)
return 0;
err_debugfs_info:
debugfs_remove(devdata->debugfs_info);
err_debugfs_dir:
debugfs_remove_recursive(devdata->debugfs_dir);
err_scsi_remove_host:
scsi_remove_host(scsihost);
......@@ -1191,6 +1192,8 @@ static void visorhba_remove(struct visor_device *dev)
idr_destroy(&devdata->idr);
dev_set_drvdata(&dev->device, NULL);
debugfs_remove(devdata->debugfs_info);
debugfs_remove_recursive(devdata->debugfs_dir);
}
/**
......@@ -1201,21 +1204,12 @@ static void visorhba_remove(struct visor_device *dev)
*/
static int visorhba_init(void)
{
struct dentry *ret;
int rc = -ENOMEM;
visorhba_debugfs_dir = debugfs_create_dir("visorhba", NULL);
if (!visorhba_debugfs_dir)
return -ENOMEM;
ret = debugfs_create_file("info", S_IRUSR, visorhba_debugfs_dir, NULL,
&debugfs_info_fops);
if (!ret) {
rc = -EIO;
goto cleanup_debugfs;
}
rc = visorbus_register_visor_driver(&visorhba_driver);
if (rc)
goto cleanup_debugfs;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment