/*
 * Copyright 2004 Digi International (www.digi.com)
 *      Scott H Kilau <Scott_Kilau at digi dot com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 */

#include "dgrp_common.h"

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/serial_reg.h>
#include <linux/pci.h>
#include <linux/kdev_t.h>


#define PORTSERVER_DIVIDEND 1843200
#define SERIAL_TYPE_NORMAL      1
#define SERIAL_TYPE_CALLOUT     2
#define SERIAL_TYPE_XPRINT      3


static struct class *dgrp_class;
static struct device *dgrp_class_nodes_dev;
static struct device *dgrp_class_global_settings_dev;


static ssize_t dgrp_class_version_show(struct class *class,
				       struct class_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%s\n", DIGI_VERSION);
}
static CLASS_ATTR(driver_version, 0400, dgrp_class_version_show, NULL);


static ssize_t dgrp_class_register_with_sysfs_show(struct device *c,
						   struct device_attribute *attr,
						   char *buf)
{
	return snprintf(buf, PAGE_SIZE, "1\n");
}
static DEVICE_ATTR(register_with_sysfs, 0400,
		   dgrp_class_register_with_sysfs_show, NULL);


static ssize_t dgrp_class_pollrate_show(struct device *c,
					struct device_attribute *attr,
					char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", dgrp_poll_tick);
}

static ssize_t dgrp_class_pollrate_store(struct device *c,
					 struct device_attribute *attr,
					 const char *buf, size_t count)
{
	sscanf(buf, "0x%x\n", &dgrp_poll_tick);
	return count;
}
static DEVICE_ATTR(pollrate, 0600, dgrp_class_pollrate_show,
		   dgrp_class_pollrate_store);

static struct attribute *dgrp_sysfs_global_settings_entries[] = {
	&dev_attr_pollrate.attr,
	&dev_attr_register_with_sysfs.attr,
	NULL
};


static struct attribute_group dgrp_global_settings_attribute_group = {
	.name = NULL,
	.attrs = dgrp_sysfs_global_settings_entries,
};



int dgrp_create_class_sysfs_files(void)
{
	int ret = 0;
	int max_majors = 1U << (32 - MINORBITS);

	dgrp_class = class_create(THIS_MODULE, "digi_realport");
	if (IS_ERR(dgrp_class))
		return PTR_ERR(dgrp_class);
	ret = class_create_file(dgrp_class, &class_attr_driver_version);
	if (ret)
		goto err_class;

	dgrp_class_global_settings_dev = device_create(dgrp_class, NULL,
		MKDEV(0, max_majors + 1), NULL, "driver_settings");
	if (IS_ERR(dgrp_class_global_settings_dev)) {
		ret = PTR_ERR(dgrp_class_global_settings_dev);
		goto err_file;
	}
	ret = sysfs_create_group(&dgrp_class_global_settings_dev->kobj,
		&dgrp_global_settings_attribute_group);
	if (ret) {
		pr_alert("%s: failed to create sysfs global settings device attributes.\n",
			__func__);
		goto err_dev1;
	}

	dgrp_class_nodes_dev = device_create(dgrp_class, NULL,
		MKDEV(0, max_majors + 2), NULL, "nodes");
	if (IS_ERR(dgrp_class_nodes_dev)) {
		ret = PTR_ERR(dgrp_class_nodes_dev);
		goto err_group;
	}

	return 0;
err_group:
	sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
		&dgrp_global_settings_attribute_group);
err_dev1:
	device_destroy(dgrp_class, MKDEV(0, max_majors + 1));
err_file:
	class_remove_file(dgrp_class, &class_attr_driver_version);
err_class:
	class_destroy(dgrp_class);
	return ret;
}


void dgrp_remove_class_sysfs_files(void)
{
	struct nd_struct *nd;
	int max_majors = 1U << (32 - MINORBITS);

	list_for_each_entry(nd, &nd_struct_list, list)
		dgrp_remove_node_class_sysfs_files(nd);

	sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
		&dgrp_global_settings_attribute_group);

	class_remove_file(dgrp_class, &class_attr_driver_version);

	device_destroy(dgrp_class, MKDEV(0, max_majors + 1));
	device_destroy(dgrp_class, MKDEV(0, max_majors + 2));
	class_destroy(dgrp_class);
}

static ssize_t dgrp_node_state_show(struct device *c,
				    struct device_attribute *attr, char *buf)
{
	struct nd_struct *nd;

	if (!c)
		return 0;
	nd = (struct nd_struct *) dev_get_drvdata(c);
	if (!nd)
		return 0;

	return snprintf(buf, PAGE_SIZE, "%s\n", ND_STATE_STR(nd->nd_state));
}

static DEVICE_ATTR(state, 0600, dgrp_node_state_show, NULL);

static ssize_t dgrp_node_description_show(struct device *c,
					  struct device_attribute *attr,
					  char *buf)
{
	struct nd_struct *nd;

	if (!c)
		return 0;
	nd = (struct nd_struct *) dev_get_drvdata(c);
	if (!nd)
		return 0;

	if (nd->nd_state == NS_READY)
		return snprintf(buf, PAGE_SIZE, "%s\n", nd->nd_ps_desc);
	return 0;
}
static DEVICE_ATTR(description_info, 0600, dgrp_node_description_show, NULL);

static ssize_t dgrp_node_hw_version_show(struct device *c,
					 struct device_attribute *attr,
					 char *buf)
{
	struct nd_struct *nd;

	if (!c)
		return 0;
	nd = (struct nd_struct *) dev_get_drvdata(c);
	if (!nd)
		return 0;

	if (nd->nd_state == NS_READY)
		return snprintf(buf, PAGE_SIZE, "%d.%d\n",
				(nd->nd_hw_ver >> 8) & 0xff,
				nd->nd_hw_ver & 0xff);

	return 0;
}
static DEVICE_ATTR(hw_version_info, 0600, dgrp_node_hw_version_show, NULL);

static ssize_t dgrp_node_hw_id_show(struct device *c,
				    struct device_attribute *attr, char *buf)
{
	struct nd_struct *nd;

	if (!c)
		return 0;
	nd = (struct nd_struct *) dev_get_drvdata(c);
	if (!nd)
		return 0;


	if (nd->nd_state == NS_READY)
		return snprintf(buf, PAGE_SIZE, "%d\n", nd->nd_hw_id);
	return 0;
}
static DEVICE_ATTR(hw_id_info, 0600, dgrp_node_hw_id_show, NULL);

static ssize_t dgrp_node_sw_version_show(struct device *c,
					 struct device_attribute *attr,
					 char *buf)
{
	struct nd_struct *nd;

	if (!c)
		return 0;

	nd = (struct nd_struct *) dev_get_drvdata(c);
	if (!nd)
		return 0;

	if (nd->nd_state == NS_READY)
		return snprintf(buf, PAGE_SIZE, "%d.%d\n",
				(nd->nd_sw_ver >> 8) & 0xff,
				nd->nd_sw_ver & 0xff);

	return 0;
}
static DEVICE_ATTR(sw_version_info, 0600, dgrp_node_sw_version_show, NULL);


static struct attribute *dgrp_sysfs_node_entries[] = {
	&dev_attr_state.attr,
	&dev_attr_description_info.attr,
	&dev_attr_hw_version_info.attr,
	&dev_attr_hw_id_info.attr,
	&dev_attr_sw_version_info.attr,
	NULL
};


static struct attribute_group dgrp_node_attribute_group = {
	.name = NULL,
	.attrs = dgrp_sysfs_node_entries,
};


void dgrp_create_node_class_sysfs_files(struct nd_struct *nd)
{
	int ret;
	char name[10];

	if (nd->nd_ID)
		ID_TO_CHAR(nd->nd_ID, name);
	else
		sprintf(name, "node%ld", nd->nd_major);

	nd->nd_class_dev = device_create(dgrp_class, dgrp_class_nodes_dev,
		MKDEV(0, nd->nd_major), NULL, name);

	ret = sysfs_create_group(&nd->nd_class_dev->kobj,
				 &dgrp_node_attribute_group);

	if (ret) {
		pr_alert("%s: failed to create sysfs node device attributes.\n",
			__func__);
		sysfs_remove_group(&nd->nd_class_dev->kobj,
				   &dgrp_node_attribute_group);
		return;
	}

	dev_set_drvdata(nd->nd_class_dev, nd);

}


void dgrp_remove_node_class_sysfs_files(struct nd_struct *nd)
{
	if (nd->nd_class_dev) {
		sysfs_remove_group(&nd->nd_class_dev->kobj,
				   &dgrp_node_attribute_group);

		device_destroy(dgrp_class, MKDEV(0, nd->nd_major));
		nd->nd_class_dev = NULL;
	}
}



static ssize_t dgrp_tty_state_show(struct device *d,
				   struct device_attribute *attr, char *buf)
{
	struct un_struct *un;

	if (!d)
		return 0;
	un = (struct un_struct *) dev_get_drvdata(d);
	if (!un)
		return 0;

	return snprintf(buf, PAGE_SIZE, "%s\n",
			un->un_open_count ? "Open" : "Closed");
}
static DEVICE_ATTR(state_info, 0600, dgrp_tty_state_show, NULL);

static ssize_t dgrp_tty_baud_show(struct device *d,
				  struct device_attribute *attr, char *buf)
{
	struct ch_struct *ch;
	struct un_struct *un;

	if (!d)
		return 0;
	un = (struct un_struct *) dev_get_drvdata(d);
	if (!un)
		return 0;
	ch = un->un_ch;
	if (!ch)
		return 0;
	return snprintf(buf, PAGE_SIZE, "%d\n",
		un->un_open_count ? (PORTSERVER_DIVIDEND / ch->ch_s_brate) : 0);
}
static DEVICE_ATTR(baud_info, 0400, dgrp_tty_baud_show, NULL);


static ssize_t dgrp_tty_msignals_show(struct device *d,
				      struct device_attribute *attr, char *buf)
{
	struct ch_struct *ch;
	struct un_struct *un;

	if (!d)
		return 0;
	un = (struct un_struct *) dev_get_drvdata(d);
	if (!un)
		return 0;
	ch = un->un_ch;
	if (!ch)
		return 0;

	if (ch->ch_open_count) {
		return snprintf(buf, PAGE_SIZE, "%s %s %s %s %s %s\n",
			(ch->ch_s_mlast & DM_RTS) ? "RTS" : "",
			(ch->ch_s_mlast & DM_CTS) ? "CTS" : "",
			(ch->ch_s_mlast & DM_DTR) ? "DTR" : "",
			(ch->ch_s_mlast & DM_DSR) ? "DSR" : "",
			(ch->ch_s_mlast & DM_CD) ? "DCD" : "",
			(ch->ch_s_mlast & DM_RI)  ? "RI"  : "");
	}
	return 0;
}
static DEVICE_ATTR(msignals_info, 0400, dgrp_tty_msignals_show, NULL);


static ssize_t dgrp_tty_iflag_show(struct device *d,
				   struct device_attribute *attr, char *buf)
{
	struct ch_struct *ch;
	struct un_struct *un;

	if (!d)
		return 0;
	un = (struct un_struct *) dev_get_drvdata(d);
	if (!un)
		return 0;
	ch = un->un_ch;
	if (!ch)
		return 0;
	return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_iflag);
}
static DEVICE_ATTR(iflag_info, 0600, dgrp_tty_iflag_show, NULL);


static ssize_t dgrp_tty_cflag_show(struct device *d,
				   struct device_attribute *attr, char *buf)
{
	struct ch_struct *ch;
	struct un_struct *un;

	if (!d)
		return 0;
	un = (struct un_struct *) dev_get_drvdata(d);
	if (!un)
		return 0;
	ch = un->un_ch;
	if (!ch)
		return 0;
	return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_cflag);
}
static DEVICE_ATTR(cflag_info, 0600, dgrp_tty_cflag_show, NULL);


static ssize_t dgrp_tty_oflag_show(struct device *d,
				   struct device_attribute *attr, char *buf)
{
	struct ch_struct *ch;
	struct un_struct *un;

	if (!d)
		return 0;
	un = (struct un_struct *) dev_get_drvdata(d);
	if (!un)
		return 0;
	ch = un->un_ch;
	if (!ch)
		return 0;
	return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_s_oflag);
}
static DEVICE_ATTR(oflag_info, 0600, dgrp_tty_oflag_show, NULL);


static ssize_t dgrp_tty_digi_flag_show(struct device *d,
				       struct device_attribute *attr, char *buf)
{
	struct ch_struct *ch;
	struct un_struct *un;

	if (!d)
		return 0;
	un = (struct un_struct *) dev_get_drvdata(d);
	if (!un)
		return 0;
	ch = un->un_ch;
	if (!ch)
		return 0;
	return snprintf(buf, PAGE_SIZE, "%x\n", ch->ch_digi.digi_flags);
}
static DEVICE_ATTR(digi_flag_info, 0600, dgrp_tty_digi_flag_show, NULL);


static ssize_t dgrp_tty_rxcount_show(struct device *d,
				     struct device_attribute *attr, char *buf)
{
	struct ch_struct *ch;
	struct un_struct *un;

	if (!d)
		return 0;
	un = (struct un_struct *) dev_get_drvdata(d);
	if (!un)
		return 0;
	ch = un->un_ch;
	if (!ch)
		return 0;
	return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_rxcount);
}
static DEVICE_ATTR(rxcount_info, 0600, dgrp_tty_rxcount_show, NULL);


static ssize_t dgrp_tty_txcount_show(struct device *d,
				     struct device_attribute *attr, char *buf)
{
	struct ch_struct *ch;
	struct un_struct *un;

	if (!d)
		return 0;
	un = (struct un_struct *) dev_get_drvdata(d);
	if (!un)
		return 0;
	ch = un->un_ch;
	if (!ch)
		return 0;
	return snprintf(buf, PAGE_SIZE, "%d\n", ch->ch_txcount);
}
static DEVICE_ATTR(txcount_info, 0600, dgrp_tty_txcount_show, NULL);


static ssize_t dgrp_tty_name_show(struct device *d,
				  struct device_attribute *attr, char *buf)
{
	struct nd_struct *nd;
	struct ch_struct *ch;
	struct un_struct *un;
	char name[10];

	if (!d)
		return 0;
	un = (struct un_struct *) dev_get_drvdata(d);
	if (!un)
		return 0;
	ch = un->un_ch;
	if (!ch)
		return 0;
	nd = ch->ch_nd;
	if (!nd)
		return 0;

	ID_TO_CHAR(nd->nd_ID, name);

	return snprintf(buf, PAGE_SIZE, "%s%s%02d\n",
		un->un_type == SERIAL_TYPE_XPRINT ? "pr" : "tty",
		name, ch->ch_portnum);
}
static DEVICE_ATTR(custom_name, 0600, dgrp_tty_name_show, NULL);


static struct attribute *dgrp_sysfs_tty_entries[] = {
	&dev_attr_state_info.attr,
	&dev_attr_baud_info.attr,
	&dev_attr_msignals_info.attr,
	&dev_attr_iflag_info.attr,
	&dev_attr_cflag_info.attr,
	&dev_attr_oflag_info.attr,
	&dev_attr_digi_flag_info.attr,
	&dev_attr_rxcount_info.attr,
	&dev_attr_txcount_info.attr,
	&dev_attr_custom_name.attr,
	NULL
};


static struct attribute_group dgrp_tty_attribute_group = {
	.name = NULL,
	.attrs = dgrp_sysfs_tty_entries,
};


void dgrp_create_tty_sysfs(struct un_struct *un, struct device *c)
{
	int ret;

	ret = sysfs_create_group(&c->kobj, &dgrp_tty_attribute_group);
	if (ret) {
		pr_alert("%s: failed to create sysfs tty device attributes.\n",
			__func__);
		sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
		return;
	}

	dev_set_drvdata(c, un);

}


void dgrp_remove_tty_sysfs(struct device *c)
{
	sysfs_remove_group(&c->kobj, &dgrp_tty_attribute_group);
}
