Get RapidIO space resource by catting /proc/riores.

Signed-off-by: Zhang Wei <[EMAIL PROTECTED]>
---
 drivers/rapidio/Kconfig |    8 +++
 drivers/rapidio/rio.c   |  121 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 129 insertions(+), 0 deletions(-)

diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index fde2bb3..f669108 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -9,4 +9,12 @@ config RAPIDIO_DISC_TIMEOUT
          Amount of time a discovery node waits for a host to complete
          enumeration before giving up.
 
+config RAPIDIO_PROC_FS
+       bool "I/O and Memory resource debug"
+       depends on RAPIDIO && PROC_FS
+       default y
+       ---help---
+         Enable this option, it will create a /proc/riores node for
+         monitoring the RapidIO I/O and Memory resource.
+
 source "drivers/rapidio/sallocator/Kconfig"
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index cda8fce..9bae341 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -31,6 +31,9 @@
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
+#include <linux/seq_file.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
 #include <linux/dma-mapping.h>
 #include <linux/hardirq.h>
 
@@ -872,3 +875,121 @@ EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
 EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
 EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
 EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
+
+#ifdef CONFIG_RAPIDIO_PROC_FS
+enum { MAX_IORES_LEVEL = 5 };
+
+struct riors {
+       struct rio_mport *mp;
+       int res;
+       struct resource *p;
+} riomres;
+
+static void *r_next(struct seq_file *m, void *v, loff_t *pos)
+{
+       struct resource *p = v;
+       struct riors *rs = m->private;
+
+       (*pos)++;
+       if (p->child)
+               return p->child;
+       while (!p->sibling && p->parent)
+               p = p->parent;
+       if (p->sibling)
+               return p->sibling;
+       else {
+               rs->res++;
+               if (rs->res >= RIO_MAX_MPORT_RESOURCES) {
+                       rs->mp = list_entry(rs->mp->node.next, struct rio_mport,
+                                       node);
+                       rs->res = 0;
+                       if (&rs->mp->node == &rio_mports)
+                               return NULL;
+               }
+               seq_printf(m, "%2d: ", rs->res);
+               rs->p = &rs->mp->riores[rs->res];
+               p = rs->p;
+
+               return p;
+       }
+}
+
+static void *r_start(struct seq_file *m, loff_t *pos)
+{
+       struct riors *rs = m->private;
+       struct resource *p;
+
+       if (*pos) {
+               *pos = 0;
+               return NULL;
+       }
+
+       rs->mp = list_entry(rio_mports.next, struct rio_mport, node);
+       rs->res = -1;
+       rs->p = &rs->mp->iores;
+       p = rs->p;
+
+       seq_printf(m, "IO: ");
+
+       return p;
+}
+
+static void r_stop(struct seq_file *m, void *v)
+{
+}
+
+static int r_show(struct seq_file *m, void *v)
+{
+       struct riors *rs = m->private;
+       struct resource *root = rs->p;
+       struct resource *r = v, *p;
+       int width = root->end < 0x10000 ? 4 : 8;
+       int depth;
+
+       for (depth = 0, p = r; p->parent && depth < MAX_IORES_LEVEL; depth++,
+                                       p = p->parent)
+               if (p == root)
+                       break;
+       seq_printf(m, "%*s%0*llx-%0*llx : %s\n",
+                       depth * 2, "",
+                       width, (unsigned long long) r->start,
+                       width, (unsigned long long) r->end,
+                       r->name ? r->name : "<BAD>");
+       return 0;
+}
+
+static const struct seq_operations resource_op = {
+       .start  = r_start,
+       .next   = r_next,
+       .stop   = r_stop,
+       .show   = r_show,
+};
+
+static int riores_open(struct inode *inode, struct file *file)
+{
+       int res = seq_open(file, &resource_op);
+       if (!res) {
+               struct seq_file *m = file->private_data;
+               m->private = &riomres;
+       }
+       return res;
+}
+
+static const struct file_operations proc_riores_operations = {
+       .open           = riores_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
+
+static int __init rioresources_init(void)
+{
+       struct proc_dir_entry *entry;
+
+       entry = create_proc_entry("riores", 0, NULL);
+       if (entry)
+               entry->proc_fops = &proc_riores_operations;
+       return 0;
+}
+__initcall(rioresources_init);
+#endif
-- 
1.5.4

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to