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