[PATCH 2/2] staging: unisys: added virtpci info entry

Erik Arfvidson erik.arfvidson at unisys.com
Wed Jul 9 20:22:43 UTC 2014


This patch adds the virtpci debugfs directory and the info entry
inside of it.

Signed-off-by: Erik Arfvidson <erik.arfvidson at unisys.com>
---
 drivers/staging/unisys/virtpci/virtpci.c | 123 ++++++++++++++++++++++++++++++-
 1 file changed, 119 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c
index 7d840b0..68fbe85 100644
--- a/drivers/staging/unisys/virtpci/virtpci.c
+++ b/drivers/staging/unisys/virtpci/virtpci.c
@@ -37,6 +37,7 @@
 #include <linux/if_ether.h>
 #include <linux/version.h>
 #include "version.h"
+ #include <linux/debugfs.h>
 #include "guestlinuxdebug.h"
 #include "timskmodutils.h"
 
@@ -100,6 +101,12 @@ static int virtpci_device_resume(struct device *dev);
 static int virtpci_device_probe(struct device *dev);
 static int virtpci_device_remove(struct device *dev);
 
+static ssize_t info_debugfs_read(struct file *file, char __user *buf,
+			      size_t len, loff_t *offset);
+
+static const struct file_operations debugfs_info_fops = {
+	.read = info_debugfs_read,
+};
 
 /*****************************************************/
 /* Globals                                           */
@@ -139,7 +146,19 @@ static DEFINE_RWLOCK(VpcidevListLock);
 
 /* filled in with info about this driver, wrt it servicing client busses */
 static ULTRA_VBUS_DEVICEINFO Bus_DriverInfo;
-
+/*****************************************************/
+/* DebugFS entries                                   */
+/*****************************************************/
+/* dentry is used to create the debugfs entry directory
+ * for virtpci
+ */
+static struct dentry *virtpci_debugfs_dir;
+static struct dentry *info_debugfs_entry;
+/* info_debugfs_entry is used to tell virtpci to display current info
+ * kept in the driver
+ */
+#define DIR_DEBUGFS_ENTRY "virtpci"
+#define INFO_DEBUGFS_ENTRY_FN "info"
 
 struct virtpci_busdev {
 	struct device virtpci_bus_device;
@@ -588,7 +607,8 @@ static void delete_all(void)
 /* deletes all vnics or vhbas
  * returns 0 failure, 1 success,
  */
-static int delete_all_virt(VIRTPCI_DEV_TYPE devtype, struct del_vbus_guestpart *delparams)
+static int delete_all_virt(VIRTPCI_DEV_TYPE devtype,
+			struct del_vbus_guestpart *delparams)
 {
 	int i;
 	unsigned char busid[BUS_ID_SIZE];
@@ -1375,6 +1395,97 @@ void virtpci_unregister_driver(struct virtpci_driver *drv)
 	DBGINF("Leaving\n");
 }
 EXPORT_SYMBOL_GPL(virtpci_unregister_driver);
+/*****************************************************/
+/* debugfs filesystem functions						*/
+/*****************************************************/
+struct print_vbus_info {
+	int *length;
+	char *buf;
+};
+
+static int print_vbus(struct device *vbus, void *data)
+{
+	struct print_vbus_info *p = (struct print_vbus_info *)data;
+
+	*p->length += sprintf(p->buf + *p->length, "bus_id:%s\n",
+			      dev_name(vbus));
+	return 0;		/* no error */
+}
+
+static ssize_t info_debugfs_read(struct file *file, char __user *buf,
+			      size_t len, loff_t *offset)
+{
+	int str_pos = 0;
+	struct virtpci_dev *tmpvpcidev;
+	unsigned long flags;
+	struct print_vbus_info printparam;
+	char *vbuf;
+	loff_t pos = *offset;
+
+	if (pos < 0)
+		return -EINVAL;
+
+	if (pos > 0 || !len)
+		return 0;
+
+	vbuf = kzalloc(len, GFP_KERNEL);
+	if (!vbuf)
+		return -ENOMEM;
+
+
+	str_pos += snprintf(vbuf + str_pos, len - str_pos,
+			"\n Virtual PCI Bus devices\n");
+	printparam.length = &str_pos;
+	printparam.buf = vbuf;
+	if (bus_for_each_dev(&virtpci_bus_type, NULL,
+			     (void *) &printparam, print_vbus))
+		LOGERR("Failed to find bus\n");
+
+	str_pos += snprintf(vbuf + str_pos, len - str_pos,
+			"\n Virtual PCI devices\n");
+	read_lock_irqsave(&VpcidevListLock, flags);
+	tmpvpcidev = VpcidevListHead;
+	while (tmpvpcidev) {
+		if (tmpvpcidev->devtype == VIRTHBA_TYPE) {
+			str_pos += snprintf(vbuf + str_pos, len - str_pos,
+					"[%d:%d] VHba:%08x:%08x max-config:%d-%d-%d-%d",
+				    tmpvpcidev->busNo, tmpvpcidev->deviceNo,
+				    tmpvpcidev->scsi.wwnn.wwnn1,
+				    tmpvpcidev->scsi.wwnn.wwnn2,
+				    tmpvpcidev->scsi.max.max_channel,
+				    tmpvpcidev->scsi.max.max_id,
+				    tmpvpcidev->scsi.max.max_lun,
+				    tmpvpcidev->scsi.max.cmd_per_lun);
+		} else {
+			str_pos += snprintf(vbuf + str_pos, len - str_pos,
+					"[%d:%d] VNic:%02x:%02x:%02x:%02x:%02x:%02x num_rcv_bufs:%d mtu:%d",
+				    tmpvpcidev->busNo, tmpvpcidev->deviceNo,
+				    tmpvpcidev->net.mac_addr[0],
+				    tmpvpcidev->net.mac_addr[1],
+				    tmpvpcidev->net.mac_addr[2],
+				    tmpvpcidev->net.mac_addr[3],
+				    tmpvpcidev->net.mac_addr[4],
+				    tmpvpcidev->net.mac_addr[5],
+				    tmpvpcidev->net.num_rcv_bufs,
+				    tmpvpcidev->net.mtu);
+		}
+		str_pos +=
+		    snprintf(vbuf + str_pos, len - str_pos, " chanptr:%p\n",
+			    tmpvpcidev->queueinfo.chan);
+		tmpvpcidev = tmpvpcidev->next;
+	}
+	read_unlock_irqrestore(&VpcidevListLock, flags);
+
+	str_pos += snprintf(vbuf + str_pos, len - str_pos, "\n");
+	if (copy_to_user(buf, vbuf, str_pos)) {
+		kfree(vbuf);
+		return -EFAULT;
+	}
+
+	kfree(vbuf);
+	*offset += str_pos;
+	return str_pos;
+}
 
 /*****************************************************/
 /* Module Init & Exit functions                      */
@@ -1426,7 +1537,10 @@ static int __init virtpci_mod_init(void)
 
 	LOGINF("successfully registered virtpci_ctrlchan_func (0x%p) as callback.\n",
 	     (void *) &virtpci_ctrlchan_func);
-
+	/*create debugfs directory*/
+	virtpci_debugfs_dir = debugfs_create_dir(DIR_DEBUGFS_ENTRY, NULL);
+	info_debugfs_entry = debugfs_create_file(INFO_DEBUGFS_ENTRY_FN, S_IRUSR,
+				virtpci_debugfs_dir, NULL, &debugfs_info_fops);
 	LOGINF("Leaving\n");
 	POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO);
 	return 0;
@@ -1442,7 +1556,8 @@ static void __exit virtpci_mod_exit(void)
 
 	device_unregister(&virtpci_rootbus_device);
 	bus_unregister(&virtpci_bus_type);
-
+	/*debug_fs file and directory removal*/
+	debugfs_remove(virtpci_debugfs_dir);
 	LOGINF("Leaving\n");
 
 }
-- 
1.9.1



More information about the devel mailing list