linux/drivers/atm/adummy.c
<<
>>
Prefs
   1/*
   2 * adummy.c: a dummy ATM driver
   3 */
   4
   5#include <linux/module.h>
   6#include <linux/kernel.h>
   7#include <linux/skbuff.h>
   8#include <linux/errno.h>
   9#include <linux/types.h>
  10#include <linux/string.h>
  11#include <linux/delay.h>
  12#include <linux/init.h>
  13#include <linux/mm.h>
  14#include <linux/timer.h>
  15#include <linux/interrupt.h>
  16#include <asm/io.h>
  17#include <asm/byteorder.h>
  18#include <asm/uaccess.h>
  19
  20#include <linux/atmdev.h>
  21#include <linux/atm.h>
  22#include <linux/sonet.h>
  23
  24/* version definition */
  25
  26#define DRV_VERSION "1.0"
  27
  28#define DEV_LABEL "adummy"
  29
  30#define ADUMMY_DEV(dev) ((struct adummy_dev *) (dev)->dev_data)
  31
  32struct adummy_dev {
  33        struct atm_dev *atm_dev;
  34
  35        struct list_head entry;
  36};
  37
  38/* globals */
  39
  40static LIST_HEAD(adummy_devs);
  41
  42static int __init
  43adummy_start(struct atm_dev *dev)
  44{
  45        dev->ci_range.vpi_bits = 4;
  46        dev->ci_range.vci_bits = 12;
  47
  48        return 0;
  49}
  50
  51static int
  52adummy_open(struct atm_vcc *vcc)
  53{
  54        short vpi = vcc->vpi;
  55        int vci = vcc->vci;
  56
  57        if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
  58                return 0;
  59
  60        set_bit(ATM_VF_ADDR, &vcc->flags);
  61        set_bit(ATM_VF_READY, &vcc->flags);
  62
  63        return 0;
  64}
  65
  66static void
  67adummy_close(struct atm_vcc *vcc)
  68{
  69        clear_bit(ATM_VF_READY, &vcc->flags);
  70        clear_bit(ATM_VF_ADDR, &vcc->flags);
  71}
  72
  73static int
  74adummy_send(struct atm_vcc *vcc, struct sk_buff *skb)
  75{
  76        if (vcc->pop)
  77                vcc->pop(vcc, skb);
  78        else
  79                dev_kfree_skb_any(skb);
  80        atomic_inc(&vcc->stats->tx);
  81
  82        return 0;
  83}
  84
  85static int
  86adummy_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
  87{
  88        int left = *pos;
  89
  90        if (!left--)
  91                return sprintf(page, "version %s\n", DRV_VERSION);
  92
  93        return 0;
  94}
  95
  96static struct atmdev_ops adummy_ops =
  97{
  98        .open =         adummy_open,
  99        .close =        adummy_close,   
 100        .send =         adummy_send,
 101        .proc_read =    adummy_proc_read,
 102        .owner =        THIS_MODULE
 103};
 104
 105static int __init adummy_init(void)
 106{
 107        struct atm_dev *atm_dev;
 108        struct adummy_dev *adummy_dev;
 109        int err = 0;
 110
 111        printk(KERN_ERR "adummy: version %s\n", DRV_VERSION);
 112
 113        adummy_dev = kzalloc(sizeof(struct adummy_dev),
 114                                                   GFP_KERNEL);
 115        if (!adummy_dev) {
 116                printk(KERN_ERR DEV_LABEL ": kzalloc() failed\n");
 117                err = -ENOMEM;
 118                goto out;
 119        }
 120        atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL);
 121        if (!atm_dev) {
 122                printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
 123                err = -ENODEV;
 124                goto out_kfree;
 125        }
 126
 127        adummy_dev->atm_dev = atm_dev;
 128        atm_dev->dev_data = adummy_dev;
 129
 130        if (adummy_start(atm_dev)) {
 131                printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n");
 132                err = -ENODEV;
 133                goto out_unregister;
 134        }
 135
 136        list_add(&adummy_dev->entry, &adummy_devs);
 137out:
 138        return err;
 139
 140out_unregister:
 141        atm_dev_deregister(atm_dev);
 142out_kfree:
 143        kfree(adummy_dev);
 144        goto out;
 145}
 146
 147static void __exit adummy_cleanup(void)
 148{
 149        struct adummy_dev *adummy_dev, *next;
 150
 151        list_for_each_entry_safe(adummy_dev, next, &adummy_devs, entry) {
 152                atm_dev_deregister(adummy_dev->atm_dev);
 153                kfree(adummy_dev);
 154        }
 155}
 156
 157module_init(adummy_init);
 158module_exit(adummy_cleanup);
 159
 160MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
 161MODULE_DESCRIPTION("dummy ATM driver");
 162MODULE_LICENSE("GPL");
 163