On Mon, Jul 21, 2014 at 02:47:43PM -0400, Erik Arfvidson wrote: > This patch adds virthba debugfs directory and info entry > > Signed-off-by: Erik Arfvidson <erik.arfvidson@xxxxxxxxxx> > Signed-off-by: Benjamin Romer <benjamin.romer@xxxxxxxxxx> > --- > drivers/staging/unisys/virthba/virthba.c | 79 ++++++++++++++++++++++++++++++++ > 1 file changed, 79 insertions(+) > > diff --git a/drivers/staging/unisys/virthba/virthba.c b/drivers/staging/unisys/virthba/virthba.c > index b9cbcf2..121cc05 100644 > --- a/drivers/staging/unisys/virthba/virthba.c > +++ b/drivers/staging/unisys/virthba/virthba.c > @@ -50,6 +50,7 @@ > #include <scsi/scsi_cmnd.h> > #include <scsi/scsi_device.h> > #include <asm/param.h> > +#include <linux/debugfs.h> > #include <linux/types.h> > > #include "virthba.h" > @@ -66,6 +67,11 @@ > /* NOTE: L1_CACHE_BYTES >=128 */ > #define DEVICE_ATTRIBUTE struct device_attribute > > + /* MAX_BUF = 6 lines x 10 MAXVHBA x 80 characters > + * = 4800 bytes ~ 2^13 = 8192 bytes > + */ > +#define MAX_BUF 8192 > + > /*****************************************************/ > /* Forward declarations */ > /*****************************************************/ > @@ -104,6 +110,8 @@ static int virthba_serverup(struct virtpci_dev *virtpcidev); > static int virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state); > static void doDiskAddRemove(struct work_struct *work); > static void virthba_serverdown_complete(struct work_struct *work); > +static ssize_t info_debugfs_read(struct file *file, char __user *buf, > + size_t len, loff_t *offset); > > /*****************************************************/ > /* Globals */ > @@ -221,9 +229,18 @@ struct virthba_devices_open { > struct virthba_info *virthbainfo; > }; > > +static const struct file_operations debugfs_info_fops = { > + .read = info_debugfs_read, > +}; > + > +/*****************************************************/ > +/* Structs */ > +/*****************************************************/ > + > #define VIRTHBASOPENMAX 1 > /* array of open devices maintained by open() and close(); */ > static struct virthba_devices_open VirtHbasOpen[VIRTHBASOPENMAX]; > +static struct dentry *virthba_debugfs_dir; > > /*****************************************************/ > /* Local Functions */ > @@ -1342,6 +1359,62 @@ process_incoming_rsps(void *v) > complete_and_exit(&dc->threadinfo.has_stopped, 0); > } > > +/*****************************************************/ > +/* Debugfs filesystem functions */ > +/*****************************************************/ > + > +static ssize_t info_debugfs_read(struct file *file, > + char __user *buf, size_t len, loff_t *offset) > +{ > + ssize_t bytes_read = 0; > + int str_pos = 0; > + U64 phys_flags_addr; > + int i; > + struct virthba_info *virthbainfo; > + char *vbuf; > + > + if (len > MAX_BUF) > + len = MAX_BUF; > + vbuf = kzalloc(len, GFP_KERNEL); > + if (!vbuf) > + return -ENOMEM; > + > + for (i = 0; i < VIRTHBASOPENMAX; i++) { > + if (VirtHbasOpen[i].virthbainfo == NULL) > + continue; > + > + virthbainfo = VirtHbasOpen[i].virthbainfo; > + > + str_pos += scnprintf(vbuf + str_pos, > + len - str_pos, "MaxBuffLen:%u\n", MaxBuffLen); > + > + str_pos += scnprintf(vbuf + str_pos, len - str_pos, > + "\nvirthba result queue poll wait:%d usecs.\n", > + rsltq_wait_usecs); > + str_pos += scnprintf(vbuf + str_pos, len - str_pos, > + "\ninterrupts_rcvd = %llu, interrupts_disabled = %llu\n", > + virthbainfo->interrupts_rcvd, > + virthbainfo->interrupts_disabled); > + str_pos += scnprintf(vbuf + str_pos, > + len - str_pos, "\ninterrupts_notme = %llu,\n", > + virthbainfo->interrupts_notme); > + phys_flags_addr = virt_to_phys((__force void *) > + virthbainfo->flags_addr); > + str_pos += scnprintf(vbuf + str_pos, len - str_pos, > + "flags_addr = %p, phys_flags_addr=0x%016llx, FeatureFlags=%llu\n", > + virthbainfo->flags_addr, phys_flags_addr, > + (__le64)readq(virthbainfo->flags_addr)); > + str_pos += scnprintf(vbuf + str_pos, > + len - str_pos, "acquire_failed_cnt:%llu\n", > + virthbainfo->acquire_failed_cnt); > + str_pos += scnprintf(vbuf + str_pos, len - str_pos, "\n"); > + } > + > + bytes_read = simple_read_from_buffer(buf, len, offset, vbuf, str_pos); > + kfree(vbuf); > + return bytes_read; > +} > + > /* As per VirtpciFunc returns 1 for success and 0 for failure */ > static int > virthba_serverup(struct virtpci_dev *virtpcidev) > @@ -1526,6 +1599,10 @@ virthba_mod_init(void) > POSTCODE_SEVERITY_ERR); > } else { > > + /* create the debugfs directories and entries */ > + virthba_debugfs_dir = debugfs_create_dir("virthba", NULL); > + debugfs_create_file("info", S_IRUSR, virthba_debugfs_dir, > + NULL, &debugfs_info_fops); Shouldn't you have one unisys-named debugfs top-level directory that you can put your "virtpci" and "virthba" subdirs into? Seems odd for a single driver to be creating multiple top-level debugfs subdirs. I'll take this for now, but please fix this up in the future. > + /* remove debugfs directory and files. */ > + debugfs_remove_recursive(virthba_debugfs_dir); Again, the function name is self-descriptive, this comment is a waste... _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel