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#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
 111static int seq_controller_open(struct inode *inode, struct file *file)
 112{
 113        return seq_open(file, &seq_controller_ops);
 114}
 115
 116static int seq_contrstats_open(struct inode *inode, struct file *file)
 117{
 118        return seq_open(file, &seq_contrstats_ops);
 119}
 120
 121static const struct file_operations proc_controller_ops = {
 122        .owner          = THIS_MODULE,
 123        .open           = seq_controller_open,
 124        .read           = seq_read,
 125        .llseek         = seq_lseek,
 126        .release        = seq_release,
 127};
 128
 129static const struct file_operations proc_contrstats_ops = {
 130        .owner          = THIS_MODULE,
 131        .open           = seq_contrstats_open,
 132        .read           = seq_read,
 133        .llseek         = seq_lseek,
 134        .release        = seq_release,
 135};
 136
 137// /proc/capi/applications:
 138//      applid l3cnt dblkcnt dblklen #ncci recvqueuelen
 139// /proc/capi/applstats:
 140//      applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
 141// ---------------------------------------------------------------------------
 142
 143static void *applications_start(struct seq_file *seq, loff_t *pos)
 144        __acquires(capi_controller_lock)
 145{
 146        mutex_lock(&capi_controller_lock);
 147
 148        if (*pos < CAPI_MAXAPPL)
 149                return &capi_applications[*pos];
 150
 151        return NULL;
 152}
 153
 154static void *
 155applications_next(struct seq_file *seq, void *v, loff_t *pos)
 156{
 157        ++*pos;
 158        if (*pos < CAPI_MAXAPPL)
 159                return &capi_applications[*pos];
 160
 161        return NULL;
 162}
 163
 164static void applications_stop(struct seq_file *seq, void *v)
 165        __releases(capi_controller_lock)
 166{
 167        mutex_unlock(&capi_controller_lock);
 168}
 169
 170static int
 171applications_show(struct seq_file *seq, void *v)
 172{
 173        struct capi20_appl *ap = *(struct capi20_appl **) v;
 174
 175        if (!ap)
 176                return 0;
 177
 178        seq_printf(seq, "%u %d %d %d\n",
 179                   ap->applid,
 180                   ap->rparam.level3cnt,
 181                   ap->rparam.datablkcnt,
 182                   ap->rparam.datablklen);
 183
 184        return 0;
 185}
 186
 187static int
 188applstats_show(struct seq_file *seq, void *v)
 189{
 190        struct capi20_appl *ap = *(struct capi20_appl **) v;
 191
 192        if (!ap)
 193                return 0;
 194
 195        seq_printf(seq, "%u %lu %lu %lu %lu\n",
 196                   ap->applid,
 197                   ap->nrecvctlpkt,
 198                   ap->nrecvdatapkt,
 199                   ap->nsentctlpkt,
 200                   ap->nsentdatapkt);
 201
 202        return 0;
 203}
 204
 205static const struct seq_operations seq_applications_ops = {
 206        .start  = applications_start,
 207        .next   = applications_next,
 208        .stop   = applications_stop,
 209        .show   = applications_show,
 210};
 211
 212static const struct seq_operations seq_applstats_ops = {
 213        .start  = applications_start,
 214        .next   = applications_next,
 215        .stop   = applications_stop,
 216        .show   = applstats_show,
 217};
 218
 219static int
 220seq_applications_open(struct inode *inode, struct file *file)
 221{
 222        return seq_open(file, &seq_applications_ops);
 223}
 224
 225static int
 226seq_applstats_open(struct inode *inode, struct file *file)
 227{
 228        return seq_open(file, &seq_applstats_ops);
 229}
 230
 231static const struct file_operations proc_applications_ops = {
 232        .owner          = THIS_MODULE,
 233        .open           = seq_applications_open,
 234        .read           = seq_read,
 235        .llseek         = seq_lseek,
 236        .release        = seq_release,
 237};
 238
 239static const struct file_operations proc_applstats_ops = {
 240        .owner          = THIS_MODULE,
 241        .open           = seq_applstats_open,
 242        .read           = seq_read,
 243        .llseek         = seq_lseek,
 244        .release        = seq_release,
 245};
 246
 247// ---------------------------------------------------------------------------
 248
 249static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
 250        __acquires(&capi_drivers_lock)
 251{
 252        mutex_lock(&capi_drivers_lock);
 253        return seq_list_start(&capi_drivers, *pos);
 254}
 255
 256static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos)
 257{
 258        return seq_list_next(v, &capi_drivers, pos);
 259}
 260
 261static void capi_driver_stop(struct seq_file *seq, void *v)
 262        __releases(&capi_drivers_lock)
 263{
 264        mutex_unlock(&capi_drivers_lock);
 265}
 266
 267static int capi_driver_show(struct seq_file *seq, void *v)
 268{
 269        struct capi_driver *drv = list_entry(v, struct capi_driver, list);
 270
 271        seq_printf(seq, "%-32s %s\n", drv->name, drv->revision);
 272        return 0;
 273}
 274
 275static const struct seq_operations seq_capi_driver_ops = {
 276        .start  = capi_driver_start,
 277        .next   = capi_driver_next,
 278        .stop   = capi_driver_stop,
 279        .show   = capi_driver_show,
 280};
 281
 282static int
 283seq_capi_driver_open(struct inode *inode, struct file *file)
 284{
 285        int err;
 286        err = seq_open(file, &seq_capi_driver_ops);
 287        return err;
 288}
 289
 290static const struct file_operations proc_driver_ops = {
 291        .owner          = THIS_MODULE,
 292        .open           = seq_capi_driver_open,
 293        .read           = seq_read,
 294        .llseek         = seq_lseek,
 295        .release        = seq_release,
 296};
 297
 298// ---------------------------------------------------------------------------
 299
 300void __init
 301kcapi_proc_init(void)
 302{
 303        proc_mkdir("capi",             NULL);
 304        proc_mkdir("capi/controllers", NULL);
 305        proc_create("capi/controller",   0, NULL, &proc_controller_ops);
 306        proc_create("capi/contrstats",   0, NULL, &proc_contrstats_ops);
 307        proc_create("capi/applications", 0, NULL, &proc_applications_ops);
 308        proc_create("capi/applstats",    0, NULL, &proc_applstats_ops);
 309        proc_create("capi/driver",       0, NULL, &proc_driver_ops);
 310}
 311
 312void __exit
 313kcapi_proc_exit(void)
 314{
 315        remove_proc_entry("capi/driver",       NULL);
 316        remove_proc_entry("capi/controller",   NULL);
 317        remove_proc_entry("capi/contrstats",   NULL);
 318        remove_proc_entry("capi/applications", NULL);
 319        remove_proc_entry("capi/applstats",    NULL);
 320        remove_proc_entry("capi/controllers",  NULL);
 321        remove_proc_entry("capi",              NULL);
 322}
 323