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 18static char *state2str(unsigned short state) 19{ 20 switch (state) { 21 case CAPI_CTR_DETECTED: return "detected"; 22 case CAPI_CTR_LOADING: return "loading"; 23 case CAPI_CTR_RUNNING: return "running"; 24 default: return "???"; 25 } 26} 27 28// /proc/capi 29// =========================================================================== 30 31// /proc/capi/controller: 32// cnr driver cardstate name driverinfo 33// /proc/capi/contrstats: 34// cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt 35// --------------------------------------------------------------------------- 36 37static void *controller_start(struct seq_file *seq, loff_t *pos) 38 __acquires(capi_controller_lock) 39{ 40 mutex_lock(&capi_controller_lock); 41 42 if (*pos < CAPI_MAXCONTR) 43 return &capi_controller[*pos]; 44 45 return NULL; 46} 47 48static void *controller_next(struct seq_file *seq, void *v, loff_t *pos) 49{ 50 ++*pos; 51 if (*pos < CAPI_MAXCONTR) 52 return &capi_controller[*pos]; 53 54 return NULL; 55} 56 57static void controller_stop(struct seq_file *seq, void *v) 58 __releases(capi_controller_lock) 59{ 60 mutex_unlock(&capi_controller_lock); 61} 62 63static int controller_show(struct seq_file *seq, void *v) 64{ 65 struct capi_ctr *ctr = *(struct capi_ctr **) v; 66 67 if (!ctr) 68 return 0; 69 70 seq_printf(seq, "%d %-10s %-8s %-16s %s\n", 71 ctr->cnr, ctr->driver_name, 72 state2str(ctr->state), 73 ctr->name, 74 ctr->procinfo ? ctr->procinfo(ctr) : ""); 75 76 return 0; 77} 78 79static int contrstats_show(struct seq_file *seq, void *v) 80{ 81 struct capi_ctr *ctr = *(struct capi_ctr **) v; 82 83 if (!ctr) 84 return 0; 85 86 seq_printf(seq, "%d %lu %lu %lu %lu\n", 87 ctr->cnr, 88 ctr->nrecvctlpkt, 89 ctr->nrecvdatapkt, 90 ctr->nsentctlpkt, 91 ctr->nsentdatapkt); 92 93 return 0; 94} 95 96static const struct seq_operations seq_controller_ops = { 97 .start = controller_start, 98 .next = controller_next, 99 .stop = controller_stop, 100 .show = controller_show, 101}; 102 103static const struct seq_operations seq_contrstats_ops = { 104 .start = controller_start, 105 .next = controller_next, 106 .stop = controller_stop, 107 .show = contrstats_show, 108}; 109 110static int seq_controller_open(struct inode *inode, struct file *file) 111{ 112 return seq_open(file, &seq_controller_ops); 113} 114 115static int seq_contrstats_open(struct inode *inode, struct file *file) 116{ 117 return seq_open(file, &seq_contrstats_ops); 118} 119 120static const struct file_operations proc_controller_ops = { 121 .owner = THIS_MODULE, 122 .open = seq_controller_open, 123 .read = seq_read, 124 .llseek = seq_lseek, 125 .release = seq_release, 126}; 127 128static const struct file_operations proc_contrstats_ops = { 129 .owner = THIS_MODULE, 130 .open = seq_contrstats_open, 131 .read = seq_read, 132 .llseek = seq_lseek, 133 .release = seq_release, 134}; 135 136// /proc/capi/applications: 137// applid l3cnt dblkcnt dblklen #ncci recvqueuelen 138// /proc/capi/applstats: 139// applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt 140// --------------------------------------------------------------------------- 141 142static void *applications_start(struct seq_file *seq, loff_t *pos) 143 __acquires(capi_controller_lock) 144{ 145 mutex_lock(&capi_controller_lock); 146 147 if (*pos < CAPI_MAXAPPL) 148 return &capi_applications[*pos]; 149 150 return NULL; 151} 152 153static void * 154applications_next(struct seq_file *seq, void *v, loff_t *pos) 155{ 156 ++*pos; 157 if (*pos < CAPI_MAXAPPL) 158 return &capi_applications[*pos]; 159 160 return NULL; 161} 162 163static void applications_stop(struct seq_file *seq, void *v) 164 __releases(capi_controller_lock) 165{ 166 mutex_unlock(&capi_controller_lock); 167} 168 169static int 170applications_show(struct seq_file *seq, void *v) 171{ 172 struct capi20_appl *ap = *(struct capi20_appl **) v; 173 174 if (!ap) 175 return 0; 176 177 seq_printf(seq, "%u %d %d %d\n", 178 ap->applid, 179 ap->rparam.level3cnt, 180 ap->rparam.datablkcnt, 181 ap->rparam.datablklen); 182 183 return 0; 184} 185 186static int 187applstats_show(struct seq_file *seq, void *v) 188{ 189 struct capi20_appl *ap = *(struct capi20_appl **) v; 190 191 if (!ap) 192 return 0; 193 194 seq_printf(seq, "%u %lu %lu %lu %lu\n", 195 ap->applid, 196 ap->nrecvctlpkt, 197 ap->nrecvdatapkt, 198 ap->nsentctlpkt, 199 ap->nsentdatapkt); 200 201 return 0; 202} 203 204static const struct seq_operations seq_applications_ops = { 205 .start = applications_start, 206 .next = applications_next, 207 .stop = applications_stop, 208 .show = applications_show, 209}; 210 211static const struct seq_operations seq_applstats_ops = { 212 .start = applications_start, 213 .next = applications_next, 214 .stop = applications_stop, 215 .show = applstats_show, 216}; 217 218static int 219seq_applications_open(struct inode *inode, struct file *file) 220{ 221 return seq_open(file, &seq_applications_ops); 222} 223 224static int 225seq_applstats_open(struct inode *inode, struct file *file) 226{ 227 return seq_open(file, &seq_applstats_ops); 228} 229 230static const struct file_operations proc_applications_ops = { 231 .owner = THIS_MODULE, 232 .open = seq_applications_open, 233 .read = seq_read, 234 .llseek = seq_lseek, 235 .release = seq_release, 236}; 237 238static const struct file_operations proc_applstats_ops = { 239 .owner = THIS_MODULE, 240 .open = seq_applstats_open, 241 .read = seq_read, 242 .llseek = seq_lseek, 243 .release = seq_release, 244}; 245 246// --------------------------------------------------------------------------- 247 248static void *capi_driver_start(struct seq_file *seq, loff_t *pos) 249 __acquires(&capi_drivers_lock) 250{ 251 mutex_lock(&capi_drivers_lock); 252 return seq_list_start(&capi_drivers, *pos); 253} 254 255static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos) 256{ 257 return seq_list_next(v, &capi_drivers, pos); 258} 259 260static void capi_driver_stop(struct seq_file *seq, void *v) 261 __releases(&capi_drivers_lock) 262{ 263 mutex_unlock(&capi_drivers_lock); 264} 265 266static int capi_driver_show(struct seq_file *seq, void *v) 267{ 268 struct capi_driver *drv = list_entry(v, struct capi_driver, list); 269 270 seq_printf(seq, "%-32s %s\n", drv->name, drv->revision); 271 return 0; 272} 273 274static const struct seq_operations seq_capi_driver_ops = { 275 .start = capi_driver_start, 276 .next = capi_driver_next, 277 .stop = capi_driver_stop, 278 .show = capi_driver_show, 279}; 280 281static int 282seq_capi_driver_open(struct inode *inode, struct file *file) 283{ 284 int err; 285 err = seq_open(file, &seq_capi_driver_ops); 286 return err; 287} 288 289static const struct file_operations proc_driver_ops = { 290 .owner = THIS_MODULE, 291 .open = seq_capi_driver_open, 292 .read = seq_read, 293 .llseek = seq_lseek, 294 .release = seq_release, 295}; 296 297// --------------------------------------------------------------------------- 298 299void __init 300kcapi_proc_init(void) 301{ 302 proc_mkdir("capi", NULL); 303 proc_mkdir("capi/controllers", NULL); 304 proc_create("capi/controller", 0, NULL, &proc_controller_ops); 305 proc_create("capi/contrstats", 0, NULL, &proc_contrstats_ops); 306 proc_create("capi/applications", 0, NULL, &proc_applications_ops); 307 proc_create("capi/applstats", 0, NULL, &proc_applstats_ops); 308 proc_create("capi/driver", 0, NULL, &proc_driver_ops); 309} 310 311void __exit 312kcapi_proc_exit(void) 313{ 314 remove_proc_entry("capi/driver", NULL); 315 remove_proc_entry("capi/controller", NULL); 316 remove_proc_entry("capi/contrstats", NULL); 317 remove_proc_entry("capi/applications", NULL); 318 remove_proc_entry("capi/applstats", NULL); 319 remove_proc_entry("capi/controllers", NULL); 320 remove_proc_entry("capi", NULL); 321} 322