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