xref: /openbmc/linux/drivers/isdn/capi/kcapi_proc.c (revision 88c896ef87fd0dd4dbf36e8e86e019c74b1f6649)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * Kernel CAPI 2.0 Module - /proc/capi handling
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * Copyright 1999 by Carsten Paeth <calle@calle.de>
51da177e4SLinus Torvalds  * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  * This software may be used and distributed according to the terms
81da177e4SLinus Torvalds  * of the GNU General Public License, incorporated herein by reference.
91da177e4SLinus Torvalds  *
101da177e4SLinus Torvalds  */
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds 
131da177e4SLinus Torvalds #include "kcapi.h"
141da177e4SLinus Torvalds #include <linux/proc_fs.h>
151da177e4SLinus Torvalds #include <linux/seq_file.h>
161da177e4SLinus Torvalds #include <linux/init.h>
171da177e4SLinus Torvalds 
1852253031SJan Kiszka static char *state2str(unsigned short state)
191da177e4SLinus Torvalds {
2052253031SJan Kiszka 	switch (state) {
2152253031SJan Kiszka 	case CAPI_CTR_DETECTED:	return "detected";
2252253031SJan Kiszka 	case CAPI_CTR_LOADING:	return "loading";
2352253031SJan Kiszka 	case CAPI_CTR_RUNNING:	return "running";
241da177e4SLinus Torvalds 	default:	        return "???";
251da177e4SLinus Torvalds 	}
261da177e4SLinus Torvalds }
271da177e4SLinus Torvalds 
281da177e4SLinus Torvalds // /proc/capi
291da177e4SLinus Torvalds // ===========================================================================
301da177e4SLinus Torvalds 
311da177e4SLinus Torvalds // /proc/capi/controller:
321da177e4SLinus Torvalds //      cnr driver cardstate name driverinfo
331da177e4SLinus Torvalds // /proc/capi/contrstats:
341da177e4SLinus Torvalds //      cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
351da177e4SLinus Torvalds // ---------------------------------------------------------------------------
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds static void *controller_start(struct seq_file *seq, loff_t *pos)
380ca3a017SJan Kiszka 	__acquires(capi_controller_lock)
391da177e4SLinus Torvalds {
400ca3a017SJan Kiszka 	mutex_lock(&capi_controller_lock);
410ca3a017SJan Kiszka 
421da177e4SLinus Torvalds 	if (*pos < CAPI_MAXCONTR)
4352253031SJan Kiszka 		return &capi_controller[*pos];
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds 	return NULL;
461da177e4SLinus Torvalds }
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds static void *controller_next(struct seq_file *seq, void *v, loff_t *pos)
491da177e4SLinus Torvalds {
501da177e4SLinus Torvalds 	++*pos;
511da177e4SLinus Torvalds 	if (*pos < CAPI_MAXCONTR)
5252253031SJan Kiszka 		return &capi_controller[*pos];
531da177e4SLinus Torvalds 
541da177e4SLinus Torvalds 	return NULL;
551da177e4SLinus Torvalds }
561da177e4SLinus Torvalds 
571da177e4SLinus Torvalds static void controller_stop(struct seq_file *seq, void *v)
580ca3a017SJan Kiszka 	__releases(capi_controller_lock)
591da177e4SLinus Torvalds {
600ca3a017SJan Kiszka 	mutex_unlock(&capi_controller_lock);
611da177e4SLinus Torvalds }
621da177e4SLinus Torvalds 
631da177e4SLinus Torvalds static int controller_show(struct seq_file *seq, void *v)
641da177e4SLinus Torvalds {
651da177e4SLinus Torvalds 	struct capi_ctr *ctr = *(struct capi_ctr **) v;
661da177e4SLinus Torvalds 
671da177e4SLinus Torvalds 	if (!ctr)
681da177e4SLinus Torvalds 		return 0;
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds 	seq_printf(seq, "%d %-10s %-8s %-16s %s\n",
711da177e4SLinus Torvalds 		   ctr->cnr, ctr->driver_name,
7252253031SJan Kiszka 		   state2str(ctr->state),
731da177e4SLinus Torvalds 		   ctr->name,
741da177e4SLinus Torvalds 		   ctr->procinfo ?  ctr->procinfo(ctr) : "");
751da177e4SLinus Torvalds 
761da177e4SLinus Torvalds 	return 0;
771da177e4SLinus Torvalds }
781da177e4SLinus Torvalds 
791da177e4SLinus Torvalds static int contrstats_show(struct seq_file *seq, void *v)
801da177e4SLinus Torvalds {
811da177e4SLinus Torvalds 	struct capi_ctr *ctr = *(struct capi_ctr **) v;
821da177e4SLinus Torvalds 
831da177e4SLinus Torvalds 	if (!ctr)
841da177e4SLinus Torvalds 		return 0;
851da177e4SLinus Torvalds 
861da177e4SLinus Torvalds 	seq_printf(seq, "%d %lu %lu %lu %lu\n",
871da177e4SLinus Torvalds 		   ctr->cnr,
881da177e4SLinus Torvalds 		   ctr->nrecvctlpkt,
891da177e4SLinus Torvalds 		   ctr->nrecvdatapkt,
901da177e4SLinus Torvalds 		   ctr->nsentctlpkt,
911da177e4SLinus Torvalds 		   ctr->nsentdatapkt);
921da177e4SLinus Torvalds 
931da177e4SLinus Torvalds 	return 0;
941da177e4SLinus Torvalds }
951da177e4SLinus Torvalds 
9688e9d34cSJames Morris static const struct seq_operations seq_controller_ops = {
971da177e4SLinus Torvalds 	.start	= controller_start,
981da177e4SLinus Torvalds 	.next	= controller_next,
991da177e4SLinus Torvalds 	.stop	= controller_stop,
1001da177e4SLinus Torvalds 	.show	= controller_show,
1011da177e4SLinus Torvalds };
1021da177e4SLinus Torvalds 
10388e9d34cSJames Morris static const struct seq_operations seq_contrstats_ops = {
1041da177e4SLinus Torvalds 	.start	= controller_start,
1051da177e4SLinus Torvalds 	.next	= controller_next,
1061da177e4SLinus Torvalds 	.stop	= controller_stop,
1071da177e4SLinus Torvalds 	.show	= contrstats_show,
1081da177e4SLinus Torvalds };
1091da177e4SLinus Torvalds 
1101da177e4SLinus Torvalds static int seq_controller_open(struct inode *inode, struct file *file)
1111da177e4SLinus Torvalds {
1121da177e4SLinus Torvalds 	return seq_open(file, &seq_controller_ops);
1131da177e4SLinus Torvalds }
1141da177e4SLinus Torvalds 
1151da177e4SLinus Torvalds static int seq_contrstats_open(struct inode *inode, struct file *file)
1161da177e4SLinus Torvalds {
1171da177e4SLinus Torvalds 	return seq_open(file, &seq_contrstats_ops);
1181da177e4SLinus Torvalds }
1191da177e4SLinus Torvalds 
1202b8693c0SArjan van de Ven static const struct file_operations proc_controller_ops = {
121ac41cfd1SDenis V. Lunev 	.owner		= THIS_MODULE,
1221da177e4SLinus Torvalds 	.open		= seq_controller_open,
1231da177e4SLinus Torvalds 	.read		= seq_read,
1241da177e4SLinus Torvalds 	.llseek		= seq_lseek,
1251da177e4SLinus Torvalds 	.release	= seq_release,
1261da177e4SLinus Torvalds };
1271da177e4SLinus Torvalds 
1282b8693c0SArjan van de Ven static const struct file_operations proc_contrstats_ops = {
129ac41cfd1SDenis V. Lunev 	.owner		= THIS_MODULE,
1301da177e4SLinus Torvalds 	.open		= seq_contrstats_open,
1311da177e4SLinus Torvalds 	.read		= seq_read,
1321da177e4SLinus Torvalds 	.llseek		= seq_lseek,
1331da177e4SLinus Torvalds 	.release	= seq_release,
1341da177e4SLinus Torvalds };
1351da177e4SLinus Torvalds 
1361da177e4SLinus Torvalds // /proc/capi/applications:
1371da177e4SLinus Torvalds //      applid l3cnt dblkcnt dblklen #ncci recvqueuelen
1381da177e4SLinus Torvalds // /proc/capi/applstats:
1391da177e4SLinus Torvalds //      applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
1401da177e4SLinus Torvalds // ---------------------------------------------------------------------------
1411da177e4SLinus Torvalds 
142*88c896efSJan Kiszka static void *applications_start(struct seq_file *seq, loff_t *pos)
143*88c896efSJan Kiszka 	__acquires(capi_controller_lock)
1441da177e4SLinus Torvalds {
145*88c896efSJan Kiszka 	mutex_lock(&capi_controller_lock);
146*88c896efSJan Kiszka 
1471da177e4SLinus Torvalds 	if (*pos < CAPI_MAXAPPL)
1481da177e4SLinus Torvalds 		return &capi_applications[*pos];
1491da177e4SLinus Torvalds 
1501da177e4SLinus Torvalds 	return NULL;
1511da177e4SLinus Torvalds }
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds static void *
1541da177e4SLinus Torvalds applications_next(struct seq_file *seq, void *v, loff_t *pos)
1551da177e4SLinus Torvalds {
1561da177e4SLinus Torvalds 	++*pos;
1571da177e4SLinus Torvalds 	if (*pos < CAPI_MAXAPPL)
1581da177e4SLinus Torvalds 		return &capi_applications[*pos];
1591da177e4SLinus Torvalds 
1601da177e4SLinus Torvalds 	return NULL;
1611da177e4SLinus Torvalds }
1621da177e4SLinus Torvalds 
163*88c896efSJan Kiszka static void applications_stop(struct seq_file *seq, void *v)
164*88c896efSJan Kiszka 	__releases(capi_controller_lock)
1651da177e4SLinus Torvalds {
166*88c896efSJan Kiszka 	mutex_unlock(&capi_controller_lock);
1671da177e4SLinus Torvalds }
1681da177e4SLinus Torvalds 
1691da177e4SLinus Torvalds static int
1701da177e4SLinus Torvalds applications_show(struct seq_file *seq, void *v)
1711da177e4SLinus Torvalds {
1721da177e4SLinus Torvalds 	struct capi20_appl *ap = *(struct capi20_appl **) v;
1731da177e4SLinus Torvalds 
1741da177e4SLinus Torvalds 	if (!ap)
1751da177e4SLinus Torvalds 		return 0;
1761da177e4SLinus Torvalds 
1771da177e4SLinus Torvalds 	seq_printf(seq, "%u %d %d %d\n",
1781da177e4SLinus Torvalds 		   ap->applid,
1791da177e4SLinus Torvalds 		   ap->rparam.level3cnt,
1801da177e4SLinus Torvalds 		   ap->rparam.datablkcnt,
1811da177e4SLinus Torvalds 		   ap->rparam.datablklen);
1821da177e4SLinus Torvalds 
1831da177e4SLinus Torvalds 	return 0;
1841da177e4SLinus Torvalds }
1851da177e4SLinus Torvalds 
1861da177e4SLinus Torvalds static int
1871da177e4SLinus Torvalds applstats_show(struct seq_file *seq, void *v)
1881da177e4SLinus Torvalds {
1891da177e4SLinus Torvalds 	struct capi20_appl *ap = *(struct capi20_appl **) v;
1901da177e4SLinus Torvalds 
1911da177e4SLinus Torvalds 	if (!ap)
1921da177e4SLinus Torvalds 		return 0;
1931da177e4SLinus Torvalds 
1941da177e4SLinus Torvalds 	seq_printf(seq, "%u %lu %lu %lu %lu\n",
1951da177e4SLinus Torvalds 		   ap->applid,
1961da177e4SLinus Torvalds 		   ap->nrecvctlpkt,
1971da177e4SLinus Torvalds 		   ap->nrecvdatapkt,
1981da177e4SLinus Torvalds 		   ap->nsentctlpkt,
1991da177e4SLinus Torvalds 		   ap->nsentdatapkt);
2001da177e4SLinus Torvalds 
2011da177e4SLinus Torvalds 	return 0;
2021da177e4SLinus Torvalds }
2031da177e4SLinus Torvalds 
20488e9d34cSJames Morris static const struct seq_operations seq_applications_ops = {
2051da177e4SLinus Torvalds 	.start	= applications_start,
2061da177e4SLinus Torvalds 	.next	= applications_next,
2071da177e4SLinus Torvalds 	.stop	= applications_stop,
2081da177e4SLinus Torvalds 	.show	= applications_show,
2091da177e4SLinus Torvalds };
2101da177e4SLinus Torvalds 
21188e9d34cSJames Morris static const struct seq_operations seq_applstats_ops = {
2121da177e4SLinus Torvalds 	.start	= applications_start,
2131da177e4SLinus Torvalds 	.next	= applications_next,
2141da177e4SLinus Torvalds 	.stop	= applications_stop,
2151da177e4SLinus Torvalds 	.show	= applstats_show,
2161da177e4SLinus Torvalds };
2171da177e4SLinus Torvalds 
2181da177e4SLinus Torvalds static int
2191da177e4SLinus Torvalds seq_applications_open(struct inode *inode, struct file *file)
2201da177e4SLinus Torvalds {
2211da177e4SLinus Torvalds 	return seq_open(file, &seq_applications_ops);
2221da177e4SLinus Torvalds }
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds static int
2251da177e4SLinus Torvalds seq_applstats_open(struct inode *inode, struct file *file)
2261da177e4SLinus Torvalds {
2271da177e4SLinus Torvalds 	return seq_open(file, &seq_applstats_ops);
2281da177e4SLinus Torvalds }
2291da177e4SLinus Torvalds 
2302b8693c0SArjan van de Ven static const struct file_operations proc_applications_ops = {
231ac41cfd1SDenis V. Lunev 	.owner		= THIS_MODULE,
2321da177e4SLinus Torvalds 	.open		= seq_applications_open,
2331da177e4SLinus Torvalds 	.read		= seq_read,
2341da177e4SLinus Torvalds 	.llseek		= seq_lseek,
2351da177e4SLinus Torvalds 	.release	= seq_release,
2361da177e4SLinus Torvalds };
2371da177e4SLinus Torvalds 
2382b8693c0SArjan van de Ven static const struct file_operations proc_applstats_ops = {
239ac41cfd1SDenis V. Lunev 	.owner		= THIS_MODULE,
2401da177e4SLinus Torvalds 	.open		= seq_applstats_open,
2411da177e4SLinus Torvalds 	.read		= seq_read,
2421da177e4SLinus Torvalds 	.llseek		= seq_lseek,
2431da177e4SLinus Torvalds 	.release	= seq_release,
2441da177e4SLinus Torvalds };
2451da177e4SLinus Torvalds 
2461da177e4SLinus Torvalds // ---------------------------------------------------------------------------
2471da177e4SLinus Torvalds 
2481da177e4SLinus Torvalds static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
2499717fb8bSJan Kiszka 	__acquires(&capi_drivers_lock)
2501da177e4SLinus Torvalds {
2519717fb8bSJan Kiszka 	mutex_lock(&capi_drivers_lock);
2522b7c3029SPavel Emelianov 	return seq_list_start(&capi_drivers, *pos);
2531da177e4SLinus Torvalds }
2541da177e4SLinus Torvalds 
2551da177e4SLinus Torvalds static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos)
2561da177e4SLinus Torvalds {
2572b7c3029SPavel Emelianov 	return seq_list_next(v, &capi_drivers, pos);
2581da177e4SLinus Torvalds }
2591da177e4SLinus Torvalds 
2601da177e4SLinus Torvalds static void capi_driver_stop(struct seq_file *seq, void *v)
2619717fb8bSJan Kiszka 	__releases(&capi_drivers_lock)
2621da177e4SLinus Torvalds {
2639717fb8bSJan Kiszka 	mutex_unlock(&capi_drivers_lock);
2641da177e4SLinus Torvalds }
2651da177e4SLinus Torvalds 
2661da177e4SLinus Torvalds static int capi_driver_show(struct seq_file *seq, void *v)
2671da177e4SLinus Torvalds {
2682b7c3029SPavel Emelianov 	struct capi_driver *drv = list_entry(v, struct capi_driver, list);
2692b7c3029SPavel Emelianov 
2701da177e4SLinus Torvalds 	seq_printf(seq, "%-32s %s\n", drv->name, drv->revision);
2711da177e4SLinus Torvalds 	return 0;
2721da177e4SLinus Torvalds }
2731da177e4SLinus Torvalds 
27488e9d34cSJames Morris static const struct seq_operations seq_capi_driver_ops = {
2751da177e4SLinus Torvalds 	.start	= capi_driver_start,
2761da177e4SLinus Torvalds 	.next	= capi_driver_next,
2771da177e4SLinus Torvalds 	.stop	= capi_driver_stop,
2781da177e4SLinus Torvalds 	.show	= capi_driver_show,
2791da177e4SLinus Torvalds };
2801da177e4SLinus Torvalds 
2811da177e4SLinus Torvalds static int
2821da177e4SLinus Torvalds seq_capi_driver_open(struct inode *inode, struct file *file)
2831da177e4SLinus Torvalds {
2841da177e4SLinus Torvalds 	int err;
2851da177e4SLinus Torvalds 	err = seq_open(file, &seq_capi_driver_ops);
2861da177e4SLinus Torvalds 	return err;
2871da177e4SLinus Torvalds }
2881da177e4SLinus Torvalds 
2892b8693c0SArjan van de Ven static const struct file_operations proc_driver_ops = {
290ac41cfd1SDenis V. Lunev 	.owner		= THIS_MODULE,
2911da177e4SLinus Torvalds 	.open		= seq_capi_driver_open,
2921da177e4SLinus Torvalds 	.read		= seq_read,
2931da177e4SLinus Torvalds 	.llseek		= seq_lseek,
2941da177e4SLinus Torvalds 	.release	= seq_release,
2951da177e4SLinus Torvalds };
2961da177e4SLinus Torvalds 
2971da177e4SLinus Torvalds // ---------------------------------------------------------------------------
2981da177e4SLinus Torvalds 
2991da177e4SLinus Torvalds void __init
3001da177e4SLinus Torvalds kcapi_proc_init(void)
3011da177e4SLinus Torvalds {
3021da177e4SLinus Torvalds 	proc_mkdir("capi",             NULL);
3031da177e4SLinus Torvalds 	proc_mkdir("capi/controllers", NULL);
304ac41cfd1SDenis V. Lunev 	proc_create("capi/controller",   0, NULL, &proc_controller_ops);
305ac41cfd1SDenis V. Lunev 	proc_create("capi/contrstats",   0, NULL, &proc_contrstats_ops);
306ac41cfd1SDenis V. Lunev 	proc_create("capi/applications", 0, NULL, &proc_applications_ops);
307ac41cfd1SDenis V. Lunev 	proc_create("capi/applstats",    0, NULL, &proc_applstats_ops);
308ac41cfd1SDenis V. Lunev 	proc_create("capi/driver",       0, NULL, &proc_driver_ops);
3091da177e4SLinus Torvalds }
3101da177e4SLinus Torvalds 
3111da177e4SLinus Torvalds void __exit
3121da177e4SLinus Torvalds kcapi_proc_exit(void)
3131da177e4SLinus Torvalds {
3141da177e4SLinus Torvalds 	remove_proc_entry("capi/driver",       NULL);
3151da177e4SLinus Torvalds 	remove_proc_entry("capi/controller",   NULL);
3161da177e4SLinus Torvalds 	remove_proc_entry("capi/contrstats",   NULL);
3171da177e4SLinus Torvalds 	remove_proc_entry("capi/applications", NULL);
3181da177e4SLinus Torvalds 	remove_proc_entry("capi/applstats",    NULL);
3191da177e4SLinus Torvalds 	remove_proc_entry("capi/controllers",  NULL);
3201da177e4SLinus Torvalds 	remove_proc_entry("capi",              NULL);
3211da177e4SLinus Torvalds }
322