/*
 * adummy.c: a dummy ATM driver
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <linux/uaccess.h>

#include <linux/atmdev.h>
#include <linux/atm.h>
#include <linux/sonet.h>

/* version definition */

#define DRV_VERSION "1.0"

#define DEV_LABEL "adummy"

#define ADUMMY_DEV(dev) ((struct adummy_dev *) (dev)->dev_data)

struct adummy_dev {
	struct atm_dev *atm_dev;

	struct list_head entry;
};

/* globals */

static LIST_HEAD(adummy_devs);

static ssize_t __set_signal(struct device *dev,
		struct device_attribute *attr,
		const char *buf, size_t len)
{
	struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev);
	int signal;

	if (sscanf(buf, "%d", &signal) == 1) {

		if (signal < ATM_PHY_SIG_LOST || signal > ATM_PHY_SIG_FOUND)
			signal = ATM_PHY_SIG_UNKNOWN;

		atm_dev_signal_change(atm_dev, signal);
		return 1;
	}
	return -EINVAL;
}

static ssize_t __show_signal(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev);
	return sprintf(buf, "%d\n", atm_dev->signal);
}
static DEVICE_ATTR(signal, 0644, __show_signal, __set_signal);

static struct attribute *adummy_attrs[] = {
	&dev_attr_signal.attr,
	NULL
};

static const struct attribute_group adummy_group_attrs = {
	.name = NULL, /* We want them in dev's root folder */
	.attrs = adummy_attrs
};

static int __init
adummy_start(struct atm_dev *dev)
{
	dev->ci_range.vpi_bits = 4;
	dev->ci_range.vci_bits = 12;

	return 0;
}

static int
adummy_open(struct atm_vcc *vcc)
{
	short vpi = vcc->vpi;
	int vci = vcc->vci;

	if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
		return 0;

	set_bit(ATM_VF_ADDR, &vcc->flags);
	set_bit(ATM_VF_READY, &vcc->flags);

	return 0;
}

static void
adummy_close(struct atm_vcc *vcc)
{
	clear_bit(ATM_VF_READY, &vcc->flags);
	clear_bit(ATM_VF_ADDR, &vcc->flags);
}

static int
adummy_send(struct atm_vcc *vcc, struct sk_buff *skb)
{
	if (vcc->pop)
		vcc->pop(vcc, skb);
	else
		dev_kfree_skb_any(skb);
	atomic_inc(&vcc->stats->tx);

	return 0;
}

static int
adummy_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
{
	int left = *pos;

	if (!left--)
		return sprintf(page, "version %s\n", DRV_VERSION);

	return 0;
}

static const struct atmdev_ops adummy_ops =
{
	.open =		adummy_open,
	.close =	adummy_close,	
	.send =		adummy_send,
	.proc_read =	adummy_proc_read,
	.owner =	THIS_MODULE
};

static int __init adummy_init(void)
{
	struct atm_dev *atm_dev;
	struct adummy_dev *adummy_dev;
	int err = 0;

	printk(KERN_ERR "adummy: version %s\n", DRV_VERSION);

	adummy_dev = kzalloc(sizeof(struct adummy_dev),
						   GFP_KERNEL);
	if (!adummy_dev) {
		printk(KERN_ERR DEV_LABEL ": kzalloc() failed\n");
		err = -ENOMEM;
		goto out;
	}
	atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL);
	if (!atm_dev) {
		printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
		err = -ENODEV;
		goto out_kfree;
	}

	adummy_dev->atm_dev = atm_dev;
	atm_dev->dev_data = adummy_dev;

	if (sysfs_create_group(&atm_dev->class_dev.kobj, &adummy_group_attrs))
		dev_err(&atm_dev->class_dev, "Could not register attrs for adummy\n");

	if (adummy_start(atm_dev)) {
		printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n");
		err = -ENODEV;
		goto out_unregister;
	}

	list_add(&adummy_dev->entry, &adummy_devs);
out:
	return err;

out_unregister:
	atm_dev_deregister(atm_dev);
out_kfree:
	kfree(adummy_dev);
	goto out;
}

static void __exit adummy_cleanup(void)
{
	struct adummy_dev *adummy_dev, *next;

	list_for_each_entry_safe(adummy_dev, next, &adummy_devs, entry) {
		atm_dev_deregister(adummy_dev->atm_dev);
		kfree(adummy_dev);
	}
}

module_init(adummy_init);
module_exit(adummy_cleanup);

MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
MODULE_DESCRIPTION("dummy ATM driver");
MODULE_LICENSE("GPL");
