From: Zhang Wei Get RapidIO space resource by catting /proc/riores. Signed-off-by: Zhang Wei Signed-off-by: Andrew Morton --- drivers/rapidio/Kconfig | 8 ++ drivers/rapidio/rio.c | 121 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff -puN drivers/rapidio/Kconfig~rapidio-add-rapidio-proc-fs-for-memory-mapping-debugging drivers/rapidio/Kconfig --- a/drivers/rapidio/Kconfig~rapidio-add-rapidio-proc-fs-for-memory-mapping-debugging +++ a/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 -puN drivers/rapidio/rio.c~rapidio-add-rapidio-proc-fs-for-memory-mapping-debugging drivers/rapidio/rio.c --- a/drivers/rapidio/rio.c~rapidio-add-rapidio-proc-fs-for-memory-mapping-debugging +++ a/drivers/rapidio/rio.c @@ -31,6 +31,9 @@ #include #include #include +#include +#include +#include #include #include @@ -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 : ""); + 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 _