xref: /openbmc/linux/drivers/isdn/capi/kcapi_proc.c (revision 8be98d2f2a0a262f8bf8a0bc1fdf522b3c7aab17)
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>
175d76fc21SPaul Gortmaker #include <linux/export.h>
181da177e4SLinus Torvalds 
state2str(unsigned short state)1952253031SJan Kiszka static char *state2str(unsigned short state)
201da177e4SLinus Torvalds {
2152253031SJan Kiszka 	switch (state) {
2252253031SJan Kiszka 	case CAPI_CTR_DETECTED:	return "detected";
2352253031SJan Kiszka 	case CAPI_CTR_LOADING:	return "loading";
2452253031SJan Kiszka 	case CAPI_CTR_RUNNING:	return "running";
251da177e4SLinus Torvalds 	default:	        return "???";
261da177e4SLinus Torvalds 	}
271da177e4SLinus Torvalds }
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds // /proc/capi
301da177e4SLinus Torvalds // ===========================================================================
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds // /proc/capi/controller:
331da177e4SLinus Torvalds //      cnr driver cardstate name driverinfo
341da177e4SLinus Torvalds // /proc/capi/contrstats:
351da177e4SLinus Torvalds //      cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
361da177e4SLinus Torvalds // ---------------------------------------------------------------------------
371da177e4SLinus Torvalds 
controller_start(struct seq_file * seq,loff_t * pos)381da177e4SLinus Torvalds static void *controller_start(struct seq_file *seq, loff_t *pos)
390ca3a017SJan Kiszka 	__acquires(capi_controller_lock)
401da177e4SLinus Torvalds {
410ca3a017SJan Kiszka 	mutex_lock(&capi_controller_lock);
420ca3a017SJan Kiszka 
431da177e4SLinus Torvalds 	if (*pos < CAPI_MAXCONTR)
4452253031SJan Kiszka 		return &capi_controller[*pos];
451da177e4SLinus Torvalds 
461da177e4SLinus Torvalds 	return NULL;
471da177e4SLinus Torvalds }
481da177e4SLinus Torvalds 
controller_next(struct seq_file * seq,void * v,loff_t * pos)491da177e4SLinus Torvalds static void *controller_next(struct seq_file *seq, void *v, loff_t *pos)
501da177e4SLinus Torvalds {
511da177e4SLinus Torvalds 	++*pos;
521da177e4SLinus Torvalds 	if (*pos < CAPI_MAXCONTR)
5352253031SJan Kiszka 		return &capi_controller[*pos];
541da177e4SLinus Torvalds 
551da177e4SLinus Torvalds 	return NULL;
561da177e4SLinus Torvalds }
571da177e4SLinus Torvalds 
controller_stop(struct seq_file * seq,void * v)581da177e4SLinus Torvalds static void controller_stop(struct seq_file *seq, void *v)
590ca3a017SJan Kiszka 	__releases(capi_controller_lock)
601da177e4SLinus Torvalds {
610ca3a017SJan Kiszka 	mutex_unlock(&capi_controller_lock);
621da177e4SLinus Torvalds }
631da177e4SLinus Torvalds 
controller_show(struct seq_file * seq,void * v)641da177e4SLinus Torvalds static int controller_show(struct seq_file *seq, void *v)
651da177e4SLinus Torvalds {
661da177e4SLinus Torvalds 	struct capi_ctr *ctr = *(struct capi_ctr **) v;
671da177e4SLinus Torvalds 
681da177e4SLinus Torvalds 	if (!ctr)
691da177e4SLinus Torvalds 		return 0;
701da177e4SLinus Torvalds 
711da177e4SLinus Torvalds 	seq_printf(seq, "%d %-10s %-8s %-16s %s\n",
721da177e4SLinus Torvalds 		   ctr->cnr, ctr->driver_name,
7352253031SJan Kiszka 		   state2str(ctr->state),
741da177e4SLinus Torvalds 		   ctr->name,
751da177e4SLinus Torvalds 		   ctr->procinfo ?  ctr->procinfo(ctr) : "");
761da177e4SLinus Torvalds 
771da177e4SLinus Torvalds 	return 0;
781da177e4SLinus Torvalds }
791da177e4SLinus Torvalds 
contrstats_show(struct seq_file * seq,void * v)801da177e4SLinus Torvalds static int contrstats_show(struct seq_file *seq, void *v)
811da177e4SLinus Torvalds {
821da177e4SLinus Torvalds 	struct capi_ctr *ctr = *(struct capi_ctr **) v;
831da177e4SLinus Torvalds 
841da177e4SLinus Torvalds 	if (!ctr)
851da177e4SLinus Torvalds 		return 0;
861da177e4SLinus Torvalds 
871da177e4SLinus Torvalds 	seq_printf(seq, "%d %lu %lu %lu %lu\n",
881da177e4SLinus Torvalds 		   ctr->cnr,
891da177e4SLinus Torvalds 		   ctr->nrecvctlpkt,
901da177e4SLinus Torvalds 		   ctr->nrecvdatapkt,
911da177e4SLinus Torvalds 		   ctr->nsentctlpkt,
921da177e4SLinus Torvalds 		   ctr->nsentdatapkt);
931da177e4SLinus Torvalds 
941da177e4SLinus Torvalds 	return 0;
951da177e4SLinus Torvalds }
961da177e4SLinus Torvalds 
9788e9d34cSJames Morris static const struct seq_operations seq_controller_ops = {
981da177e4SLinus Torvalds 	.start	= controller_start,
991da177e4SLinus Torvalds 	.next	= controller_next,
1001da177e4SLinus Torvalds 	.stop	= controller_stop,
1011da177e4SLinus Torvalds 	.show	= controller_show,
1021da177e4SLinus Torvalds };
1031da177e4SLinus Torvalds 
10488e9d34cSJames Morris static const struct seq_operations seq_contrstats_ops = {
1051da177e4SLinus Torvalds 	.start	= controller_start,
1061da177e4SLinus Torvalds 	.next	= controller_next,
1071da177e4SLinus Torvalds 	.stop	= controller_stop,
1081da177e4SLinus Torvalds 	.show	= contrstats_show,
1091da177e4SLinus Torvalds };
1101da177e4SLinus Torvalds 
1111da177e4SLinus Torvalds // /proc/capi/applications:
1121da177e4SLinus Torvalds //      applid l3cnt dblkcnt dblklen #ncci recvqueuelen
1131da177e4SLinus Torvalds // /proc/capi/applstats:
1141da177e4SLinus Torvalds //      applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
1151da177e4SLinus Torvalds // ---------------------------------------------------------------------------
1161da177e4SLinus Torvalds 
applications_start(struct seq_file * seq,loff_t * pos)11788c896efSJan Kiszka static void *applications_start(struct seq_file *seq, loff_t *pos)
11888c896efSJan Kiszka 	__acquires(capi_controller_lock)
1191da177e4SLinus Torvalds {
12088c896efSJan Kiszka 	mutex_lock(&capi_controller_lock);
12188c896efSJan Kiszka 
1221da177e4SLinus Torvalds 	if (*pos < CAPI_MAXAPPL)
1231da177e4SLinus Torvalds 		return &capi_applications[*pos];
1241da177e4SLinus Torvalds 
1251da177e4SLinus Torvalds 	return NULL;
1261da177e4SLinus Torvalds }
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds static void *
applications_next(struct seq_file * seq,void * v,loff_t * pos)1291da177e4SLinus Torvalds applications_next(struct seq_file *seq, void *v, loff_t *pos)
1301da177e4SLinus Torvalds {
1311da177e4SLinus Torvalds 	++*pos;
1321da177e4SLinus Torvalds 	if (*pos < CAPI_MAXAPPL)
1331da177e4SLinus Torvalds 		return &capi_applications[*pos];
1341da177e4SLinus Torvalds 
1351da177e4SLinus Torvalds 	return NULL;
1361da177e4SLinus Torvalds }
1371da177e4SLinus Torvalds 
applications_stop(struct seq_file * seq,void * v)13888c896efSJan Kiszka static void applications_stop(struct seq_file *seq, void *v)
13988c896efSJan Kiszka 	__releases(capi_controller_lock)
1401da177e4SLinus Torvalds {
14188c896efSJan Kiszka 	mutex_unlock(&capi_controller_lock);
1421da177e4SLinus Torvalds }
1431da177e4SLinus Torvalds 
1441da177e4SLinus Torvalds static int
applications_show(struct seq_file * seq,void * v)1451da177e4SLinus Torvalds applications_show(struct seq_file *seq, void *v)
1461da177e4SLinus Torvalds {
1471da177e4SLinus Torvalds 	struct capi20_appl *ap = *(struct capi20_appl **) v;
1481da177e4SLinus Torvalds 
1491da177e4SLinus Torvalds 	if (!ap)
1501da177e4SLinus Torvalds 		return 0;
1511da177e4SLinus Torvalds 
1521da177e4SLinus Torvalds 	seq_printf(seq, "%u %d %d %d\n",
1531da177e4SLinus Torvalds 		   ap->applid,
1541da177e4SLinus Torvalds 		   ap->rparam.level3cnt,
1551da177e4SLinus Torvalds 		   ap->rparam.datablkcnt,
1561da177e4SLinus Torvalds 		   ap->rparam.datablklen);
1571da177e4SLinus Torvalds 
1581da177e4SLinus Torvalds 	return 0;
1591da177e4SLinus Torvalds }
1601da177e4SLinus Torvalds 
1611da177e4SLinus Torvalds static int
applstats_show(struct seq_file * seq,void * v)1621da177e4SLinus Torvalds applstats_show(struct seq_file *seq, void *v)
1631da177e4SLinus Torvalds {
1641da177e4SLinus Torvalds 	struct capi20_appl *ap = *(struct capi20_appl **) v;
1651da177e4SLinus Torvalds 
1661da177e4SLinus Torvalds 	if (!ap)
1671da177e4SLinus Torvalds 		return 0;
1681da177e4SLinus Torvalds 
1691da177e4SLinus Torvalds 	seq_printf(seq, "%u %lu %lu %lu %lu\n",
1701da177e4SLinus Torvalds 		   ap->applid,
1711da177e4SLinus Torvalds 		   ap->nrecvctlpkt,
1721da177e4SLinus Torvalds 		   ap->nrecvdatapkt,
1731da177e4SLinus Torvalds 		   ap->nsentctlpkt,
1741da177e4SLinus Torvalds 		   ap->nsentdatapkt);
1751da177e4SLinus Torvalds 
1761da177e4SLinus Torvalds 	return 0;
1771da177e4SLinus Torvalds }
1781da177e4SLinus Torvalds 
17988e9d34cSJames Morris static const struct seq_operations seq_applications_ops = {
1801da177e4SLinus Torvalds 	.start	= applications_start,
1811da177e4SLinus Torvalds 	.next	= applications_next,
1821da177e4SLinus Torvalds 	.stop	= applications_stop,
1831da177e4SLinus Torvalds 	.show	= applications_show,
1841da177e4SLinus Torvalds };
1851da177e4SLinus Torvalds 
18688e9d34cSJames Morris static const struct seq_operations seq_applstats_ops = {
1871da177e4SLinus Torvalds 	.start	= applications_start,
1881da177e4SLinus Torvalds 	.next	= applications_next,
1891da177e4SLinus Torvalds 	.stop	= applications_stop,
1901da177e4SLinus Torvalds 	.show	= applstats_show,
1911da177e4SLinus Torvalds };
1921da177e4SLinus Torvalds 
1931da177e4SLinus Torvalds // ---------------------------------------------------------------------------
1941da177e4SLinus Torvalds 
195f59aba2fSArnd Bergmann /* /proc/capi/drivers is always empty */
empty_read(struct file * file,char __user * buf,size_t size,loff_t * off)196f59aba2fSArnd Bergmann static ssize_t empty_read(struct file *file, char __user *buf,
197f59aba2fSArnd Bergmann 			  size_t size, loff_t *off)
1981da177e4SLinus Torvalds {
1991da177e4SLinus Torvalds 	return 0;
2001da177e4SLinus Torvalds }
2011da177e4SLinus Torvalds 
20297a32539SAlexey Dobriyan static const struct proc_ops empty_proc_ops = {
20397a32539SAlexey Dobriyan 	.proc_read	= empty_read,
204*d4455facSAlexey Dobriyan 	.proc_lseek	= default_llseek,
2051da177e4SLinus Torvalds };
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds // ---------------------------------------------------------------------------
2081da177e4SLinus Torvalds 
2091da177e4SLinus Torvalds void __init
kcapi_proc_init(void)2101da177e4SLinus Torvalds kcapi_proc_init(void)
2111da177e4SLinus Torvalds {
2121da177e4SLinus Torvalds 	proc_mkdir("capi",             NULL);
2131da177e4SLinus Torvalds 	proc_mkdir("capi/controllers", NULL);
214fddda2b7SChristoph Hellwig 	proc_create_seq("capi/controller",   0, NULL, &seq_controller_ops);
215fddda2b7SChristoph Hellwig 	proc_create_seq("capi/contrstats",   0, NULL, &seq_contrstats_ops);
216fddda2b7SChristoph Hellwig 	proc_create_seq("capi/applications", 0, NULL, &seq_applications_ops);
217fddda2b7SChristoph Hellwig 	proc_create_seq("capi/applstats",    0, NULL, &seq_applstats_ops);
21897a32539SAlexey Dobriyan 	proc_create("capi/driver",           0, NULL, &empty_proc_ops);
2191da177e4SLinus Torvalds }
2201da177e4SLinus Torvalds 
221b33bdf80SArnd Bergmann void
kcapi_proc_exit(void)2221da177e4SLinus Torvalds kcapi_proc_exit(void)
2231da177e4SLinus Torvalds {
2241da177e4SLinus Torvalds 	remove_proc_entry("capi/driver",       NULL);
2251da177e4SLinus Torvalds 	remove_proc_entry("capi/controller",   NULL);
2261da177e4SLinus Torvalds 	remove_proc_entry("capi/contrstats",   NULL);
2271da177e4SLinus Torvalds 	remove_proc_entry("capi/applications", NULL);
2281da177e4SLinus Torvalds 	remove_proc_entry("capi/applstats",    NULL);
2291da177e4SLinus Torvalds 	remove_proc_entry("capi/controllers",  NULL);
2301da177e4SLinus Torvalds 	remove_proc_entry("capi",              NULL);
2311da177e4SLinus Torvalds }
232