[PATCH 15/17] Add RapidIO proc fs for memory mapping debugging.
Zhang Wei
wei.zhang at freescale.com
Tue Mar 11 20:07:56 EST 2008
Get RapidIO space resource by catting /proc/riores.
Signed-off-by: Zhang Wei <wei.zhang at freescale.com>
---
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
More information about the Linuxppc-dev
mailing list