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 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 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 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 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 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 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 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 * 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 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 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 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 */ 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 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 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