/* ATM driver model support. */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/kobject.h>
#include <linux/atmdev.h>
#include "common.h"
#include "resources.h"

#define to_atm_dev(cldev) container_of(cldev, struct atm_dev, class_dev)

static ssize_t show_type(struct device *cdev,
			 struct device_attribute *attr, char *buf)
{
	struct atm_dev *adev = to_atm_dev(cdev);
	return sprintf(buf, "%s\n", adev->type);
}

static ssize_t show_address(struct device *cdev,
			    struct device_attribute *attr, char *buf)
{
	char *pos = buf;
	struct atm_dev *adev = to_atm_dev(cdev);
	int i;

	for (i = 0; i < (ESI_LEN - 1); i++)
		pos += sprintf(pos, "%02x:", adev->esi[i]);
	pos += sprintf(pos, "%02x\n", adev->esi[i]);

	return pos - buf;
}

static ssize_t show_atmaddress(struct device *cdev,
			       struct device_attribute *attr, char *buf)
{
	unsigned long flags;
	char *pos = buf;
	struct atm_dev *adev = to_atm_dev(cdev);
	struct atm_dev_addr *aaddr;
	int bin[] = { 1, 2, 10, 6, 1 }, *fmt = bin;
	int i, j;

	spin_lock_irqsave(&adev->lock, flags);
	list_for_each_entry(aaddr, &adev->local, entry) {
		for(i = 0, j = 0; i < ATM_ESA_LEN; ++i, ++j) {
			if (j == *fmt) {
				pos += sprintf(pos, ".");
				++fmt;
				j = 0;
			}
			pos += sprintf(pos, "%02x", aaddr->addr.sas_addr.prv[i]);
		}
		pos += sprintf(pos, "\n");
	}
	spin_unlock_irqrestore(&adev->lock, flags);

	return pos - buf;
}

static ssize_t show_carrier(struct device *cdev,
			    struct device_attribute *attr, char *buf)
{
	char *pos = buf;
	struct atm_dev *adev = to_atm_dev(cdev);

	pos += sprintf(pos, "%d\n",
		       adev->signal == ATM_PHY_SIG_LOST ? 0 : 1);

	return pos - buf;
}

static ssize_t show_link_rate(struct device *cdev,
			      struct device_attribute *attr, char *buf)
{
	char *pos = buf;
	struct atm_dev *adev = to_atm_dev(cdev);
	int link_rate;

	/* show the link rate, not the data rate */
	switch (adev->link_rate) {
		case ATM_OC3_PCR:
			link_rate = 155520000;
			break;
		case ATM_OC12_PCR:
			link_rate = 622080000;
			break;
		case ATM_25_PCR:
			link_rate = 25600000;
			break;
		default:
			link_rate = adev->link_rate * 8 * 53;
	}
	pos += sprintf(pos, "%d\n", link_rate);

	return pos - buf;
}

static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
static DEVICE_ATTR(atmaddress, S_IRUGO, show_atmaddress, NULL);
static DEVICE_ATTR(carrier, S_IRUGO, show_carrier, NULL);
static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
static DEVICE_ATTR(link_rate, S_IRUGO, show_link_rate, NULL);

static struct device_attribute *atm_attrs[] = {
	&dev_attr_atmaddress,
	&dev_attr_address,
	&dev_attr_carrier,
	&dev_attr_type,
	&dev_attr_link_rate,
	NULL
};


static int atm_uevent(struct device *cdev, struct kobj_uevent_env *env)
{
	struct atm_dev *adev;

	if (!cdev)
		return -ENODEV;

	adev = to_atm_dev(cdev);
	if (!adev)
		return -ENODEV;

	if (add_uevent_var(env, "NAME=%s%d", adev->type, adev->number))
		return -ENOMEM;

	return 0;
}

static void atm_release(struct device *cdev)
{
	struct atm_dev *adev = to_atm_dev(cdev);

	kfree(adev);
}

static struct class atm_class = {
	.name		= "atm",
	.dev_release	= atm_release,
	.dev_uevent		= atm_uevent,
};

int atm_register_sysfs(struct atm_dev *adev)
{
	struct device *cdev = &adev->class_dev;
	int i, j, err;

	cdev->class = &atm_class;
	dev_set_drvdata(cdev, adev);

	dev_set_name(cdev, "%s%d", adev->type, adev->number);
	err = device_register(cdev);
	if (err < 0)
		return err;

	for (i = 0; atm_attrs[i]; i++) {
		err = device_create_file(cdev, atm_attrs[i]);
		if (err)
			goto err_out;
	}

	return 0;

err_out:
	for (j = 0; j < i; j++)
		device_remove_file(cdev, atm_attrs[j]);
	device_del(cdev);
	return err;
}

void atm_unregister_sysfs(struct atm_dev *adev)
{
	struct device *cdev = &adev->class_dev;

	device_del(cdev);
}

int __init atm_sysfs_init(void)
{
	return class_register(&atm_class);
}

void __exit atm_sysfs_exit(void)
{
	class_unregister(&atm_class);
}
