/*
 * Kernel CAPI 2.0 Module - /proc/capi handling
 *
 * Copyright 1999 by Carsten Paeth <calle@calle.de>
 * Copyright 2002 by Kai Germaschewski <kai@germaschewski.name>
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 */


#include "kcapi.h"
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/init.h>
#include <linux/export.h>

static char *state2str(unsigned short state)
{
	switch (state) {
	case CAPI_CTR_DETECTED:	return "detected";
	case CAPI_CTR_LOADING:	return "loading";
	case CAPI_CTR_RUNNING:	return "running";
	default:	        return "???";
	}
}

// /proc/capi
// ===========================================================================

// /proc/capi/controller:
//      cnr driver cardstate name driverinfo
// /proc/capi/contrstats:
//      cnr nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
// ---------------------------------------------------------------------------

static void *controller_start(struct seq_file *seq, loff_t *pos)
	__acquires(capi_controller_lock)
{
	mutex_lock(&capi_controller_lock);

	if (*pos < CAPI_MAXCONTR)
		return &capi_controller[*pos];

	return NULL;
}

static void *controller_next(struct seq_file *seq, void *v, loff_t *pos)
{
	++*pos;
	if (*pos < CAPI_MAXCONTR)
		return &capi_controller[*pos];

	return NULL;
}

static void controller_stop(struct seq_file *seq, void *v)
	__releases(capi_controller_lock)
{
	mutex_unlock(&capi_controller_lock);
}

static int controller_show(struct seq_file *seq, void *v)
{
	struct capi_ctr *ctr = *(struct capi_ctr **) v;

	if (!ctr)
		return 0;

	seq_printf(seq, "%d %-10s %-8s %-16s %s\n",
		   ctr->cnr, ctr->driver_name,
		   state2str(ctr->state),
		   ctr->name,
		   ctr->procinfo ?  ctr->procinfo(ctr) : "");

	return 0;
}

static int contrstats_show(struct seq_file *seq, void *v)
{
	struct capi_ctr *ctr = *(struct capi_ctr **) v;

	if (!ctr)
		return 0;

	seq_printf(seq, "%d %lu %lu %lu %lu\n",
		   ctr->cnr,
		   ctr->nrecvctlpkt,
		   ctr->nrecvdatapkt,
		   ctr->nsentctlpkt,
		   ctr->nsentdatapkt);

	return 0;
}

static const struct seq_operations seq_controller_ops = {
	.start	= controller_start,
	.next	= controller_next,
	.stop	= controller_stop,
	.show	= controller_show,
};

static const struct seq_operations seq_contrstats_ops = {
	.start	= controller_start,
	.next	= controller_next,
	.stop	= controller_stop,
	.show	= contrstats_show,
};

static int seq_controller_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &seq_controller_ops);
}

static int seq_contrstats_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &seq_contrstats_ops);
}

static const struct file_operations proc_controller_ops = {
	.owner		= THIS_MODULE,
	.open		= seq_controller_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

static const struct file_operations proc_contrstats_ops = {
	.owner		= THIS_MODULE,
	.open		= seq_contrstats_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

// /proc/capi/applications:
//      applid l3cnt dblkcnt dblklen #ncci recvqueuelen
// /proc/capi/applstats:
//      applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
// ---------------------------------------------------------------------------

static void *applications_start(struct seq_file *seq, loff_t *pos)
	__acquires(capi_controller_lock)
{
	mutex_lock(&capi_controller_lock);

	if (*pos < CAPI_MAXAPPL)
		return &capi_applications[*pos];

	return NULL;
}

static void *
applications_next(struct seq_file *seq, void *v, loff_t *pos)
{
	++*pos;
	if (*pos < CAPI_MAXAPPL)
		return &capi_applications[*pos];

	return NULL;
}

static void applications_stop(struct seq_file *seq, void *v)
	__releases(capi_controller_lock)
{
	mutex_unlock(&capi_controller_lock);
}

static int
applications_show(struct seq_file *seq, void *v)
{
	struct capi20_appl *ap = *(struct capi20_appl **) v;

	if (!ap)
		return 0;

	seq_printf(seq, "%u %d %d %d\n",
		   ap->applid,
		   ap->rparam.level3cnt,
		   ap->rparam.datablkcnt,
		   ap->rparam.datablklen);

	return 0;
}

static int
applstats_show(struct seq_file *seq, void *v)
{
	struct capi20_appl *ap = *(struct capi20_appl **) v;

	if (!ap)
		return 0;

	seq_printf(seq, "%u %lu %lu %lu %lu\n",
		   ap->applid,
		   ap->nrecvctlpkt,
		   ap->nrecvdatapkt,
		   ap->nsentctlpkt,
		   ap->nsentdatapkt);

	return 0;
}

static const struct seq_operations seq_applications_ops = {
	.start	= applications_start,
	.next	= applications_next,
	.stop	= applications_stop,
	.show	= applications_show,
};

static const struct seq_operations seq_applstats_ops = {
	.start	= applications_start,
	.next	= applications_next,
	.stop	= applications_stop,
	.show	= applstats_show,
};

static int
seq_applications_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &seq_applications_ops);
}

static int
seq_applstats_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &seq_applstats_ops);
}

static const struct file_operations proc_applications_ops = {
	.owner		= THIS_MODULE,
	.open		= seq_applications_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

static const struct file_operations proc_applstats_ops = {
	.owner		= THIS_MODULE,
	.open		= seq_applstats_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

// ---------------------------------------------------------------------------

static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
	__acquires(&capi_drivers_lock)
{
	mutex_lock(&capi_drivers_lock);
	return seq_list_start(&capi_drivers, *pos);
}

static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos)
{
	return seq_list_next(v, &capi_drivers, pos);
}

static void capi_driver_stop(struct seq_file *seq, void *v)
	__releases(&capi_drivers_lock)
{
	mutex_unlock(&capi_drivers_lock);
}

static int capi_driver_show(struct seq_file *seq, void *v)
{
	struct capi_driver *drv = list_entry(v, struct capi_driver, list);

	seq_printf(seq, "%-32s %s\n", drv->name, drv->revision);
	return 0;
}

static const struct seq_operations seq_capi_driver_ops = {
	.start	= capi_driver_start,
	.next	= capi_driver_next,
	.stop	= capi_driver_stop,
	.show	= capi_driver_show,
};

static int
seq_capi_driver_open(struct inode *inode, struct file *file)
{
	int err;
	err = seq_open(file, &seq_capi_driver_ops);
	return err;
}

static const struct file_operations proc_driver_ops = {
	.owner		= THIS_MODULE,
	.open		= seq_capi_driver_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

// ---------------------------------------------------------------------------

void __init
kcapi_proc_init(void)
{
	proc_mkdir("capi",             NULL);
	proc_mkdir("capi/controllers", NULL);
	proc_create("capi/controller",   0, NULL, &proc_controller_ops);
	proc_create("capi/contrstats",   0, NULL, &proc_contrstats_ops);
	proc_create("capi/applications", 0, NULL, &proc_applications_ops);
	proc_create("capi/applstats",    0, NULL, &proc_applstats_ops);
	proc_create("capi/driver",       0, NULL, &proc_driver_ops);
}

void __exit
kcapi_proc_exit(void)
{
	remove_proc_entry("capi/driver",       NULL);
	remove_proc_entry("capi/controller",   NULL);
	remove_proc_entry("capi/contrstats",   NULL);
	remove_proc_entry("capi/applications", NULL);
	remove_proc_entry("capi/applstats",    NULL);
	remove_proc_entry("capi/controllers",  NULL);
	remove_proc_entry("capi",              NULL);
}
