kcapi_proc.c (5437B)
1/* 2 * Kernel CAPI 2.0 Module - /proc/capi handling 3 * 4 * Copyright 1999 by Carsten Paeth <calle@calle.de> 5 * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name> 6 * 7 * This software may be used and distributed according to the terms 8 * of the GNU General Public License, incorporated herein by reference. 9 * 10 */ 11 12 13#include "kcapi.h" 14#include <linux/proc_fs.h> 15#include <linux/seq_file.h> 16#include <linux/init.h> 17#include <linux/export.h> 18 19static char *state2str(unsigned short state) 20{ 21 switch (state) { 22 case CAPI_CTR_DETECTED: return "detected"; 23 case CAPI_CTR_LOADING: return "loading"; 24 case CAPI_CTR_RUNNING: return "running"; 25 default: return "???"; 26 } 27} 28 29// /proc/capi 30// =========================================================================== 31 32// /proc/capi/controller: 33// cnr driver cardstate name driverinfo 34// /proc/capi/contrstats: 35// cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt 36// --------------------------------------------------------------------------- 37 38static void *controller_start(struct seq_file *seq, loff_t *pos) 39 __acquires(capi_controller_lock) 40{ 41 mutex_lock(&capi_controller_lock); 42 43 if (*pos < CAPI_MAXCONTR) 44 return &capi_controller[*pos]; 45 46 return NULL; 47} 48 49static void *controller_next(struct seq_file *seq, void *v, loff_t *pos) 50{ 51 ++*pos; 52 if (*pos < CAPI_MAXCONTR) 53 return &capi_controller[*pos]; 54 55 return NULL; 56} 57 58static void controller_stop(struct seq_file *seq, void *v) 59 __releases(capi_controller_lock) 60{ 61 mutex_unlock(&capi_controller_lock); 62} 63 64static int controller_show(struct seq_file *seq, void *v) 65{ 66 struct capi_ctr *ctr = *(struct capi_ctr **) v; 67 68 if (!ctr) 69 return 0; 70 71 seq_printf(seq, "%d %-10s %-8s %-16s %s\n", 72 ctr->cnr, ctr->driver_name, 73 state2str(ctr->state), 74 ctr->name, 75 ctr->procinfo ? ctr->procinfo(ctr) : ""); 76 77 return 0; 78} 79 80static int contrstats_show(struct seq_file *seq, void *v) 81{ 82 struct capi_ctr *ctr = *(struct capi_ctr **) v; 83 84 if (!ctr) 85 return 0; 86 87 seq_printf(seq, "%d %lu %lu %lu %lu\n", 88 ctr->cnr, 89 ctr->nrecvctlpkt, 90 ctr->nrecvdatapkt, 91 ctr->nsentctlpkt, 92 ctr->nsentdatapkt); 93 94 return 0; 95} 96 97static const struct seq_operations seq_controller_ops = { 98 .start = controller_start, 99 .next = controller_next, 100 .stop = controller_stop, 101 .show = controller_show, 102}; 103 104static const struct seq_operations seq_contrstats_ops = { 105 .start = controller_start, 106 .next = controller_next, 107 .stop = controller_stop, 108 .show = contrstats_show, 109}; 110 111// /proc/capi/applications: 112// applid l3cnt dblkcnt dblklen #ncci recvqueuelen 113// /proc/capi/applstats: 114// applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt 115// --------------------------------------------------------------------------- 116 117static void *applications_start(struct seq_file *seq, loff_t *pos) 118 __acquires(capi_controller_lock) 119{ 120 mutex_lock(&capi_controller_lock); 121 122 if (*pos < CAPI_MAXAPPL) 123 return &capi_applications[*pos]; 124 125 return NULL; 126} 127 128static void * 129applications_next(struct seq_file *seq, void *v, loff_t *pos) 130{ 131 ++*pos; 132 if (*pos < CAPI_MAXAPPL) 133 return &capi_applications[*pos]; 134 135 return NULL; 136} 137 138static void applications_stop(struct seq_file *seq, void *v) 139 __releases(capi_controller_lock) 140{ 141 mutex_unlock(&capi_controller_lock); 142} 143 144static int 145applications_show(struct seq_file *seq, void *v) 146{ 147 struct capi20_appl *ap = *(struct capi20_appl **) v; 148 149 if (!ap) 150 return 0; 151 152 seq_printf(seq, "%u %d %d %d\n", 153 ap->applid, 154 ap->rparam.level3cnt, 155 ap->rparam.datablkcnt, 156 ap->rparam.datablklen); 157 158 return 0; 159} 160 161static int 162applstats_show(struct seq_file *seq, void *v) 163{ 164 struct capi20_appl *ap = *(struct capi20_appl **) v; 165 166 if (!ap) 167 return 0; 168 169 seq_printf(seq, "%u %lu %lu %lu %lu\n", 170 ap->applid, 171 ap->nrecvctlpkt, 172 ap->nrecvdatapkt, 173 ap->nsentctlpkt, 174 ap->nsentdatapkt); 175 176 return 0; 177} 178 179static const struct seq_operations seq_applications_ops = { 180 .start = applications_start, 181 .next = applications_next, 182 .stop = applications_stop, 183 .show = applications_show, 184}; 185 186static const struct seq_operations seq_applstats_ops = { 187 .start = applications_start, 188 .next = applications_next, 189 .stop = applications_stop, 190 .show = applstats_show, 191}; 192 193// --------------------------------------------------------------------------- 194 195/* /proc/capi/drivers is always empty */ 196static ssize_t empty_read(struct file *file, char __user *buf, 197 size_t size, loff_t *off) 198{ 199 return 0; 200} 201 202static const struct proc_ops empty_proc_ops = { 203 .proc_read = empty_read, 204 .proc_lseek = default_llseek, 205}; 206 207// --------------------------------------------------------------------------- 208 209void __init 210kcapi_proc_init(void) 211{ 212 proc_mkdir("capi", NULL); 213 proc_mkdir("capi/controllers", NULL); 214 proc_create_seq("capi/controller", 0, NULL, &seq_controller_ops); 215 proc_create_seq("capi/contrstats", 0, NULL, &seq_contrstats_ops); 216 proc_create_seq("capi/applications", 0, NULL, &seq_applications_ops); 217 proc_create_seq("capi/applstats", 0, NULL, &seq_applstats_ops); 218 proc_create("capi/driver", 0, NULL, &empty_proc_ops); 219} 220 221void 222kcapi_proc_exit(void) 223{ 224 remove_proc_entry("capi/driver", NULL); 225 remove_proc_entry("capi/controller", NULL); 226 remove_proc_entry("capi/contrstats", NULL); 227 remove_proc_entry("capi/applications", NULL); 228 remove_proc_entry("capi/applstats", NULL); 229 remove_proc_entry("capi/controllers", NULL); 230 remove_proc_entry("capi", NULL); 231}