// SPDX-License-Identifier: GPL-2.0
/*
 *  n_tracerouter.c - Trace data router through tty space
 *
 *  Copyright (C) Intel 2011
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * This trace router uses the Linux line discipline framework to route
 * trace data coming from a HW Modem to a PTI (Parallel Trace Module) port.
 * The solution is not specific to a HW modem and this line disciple can
 * be used to route any stream of data in kernel space.
 * This is part of a solution for the P1149.7, compact JTAG, standard.
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/tty.h>
#include <linux/tty_ldisc.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/bug.h>
#include "n_tracesink.h"

/*
 * Other ldisc drivers use 65536 which basically means,
 * 'I can always accept 64k' and flow control is off.
 * This number is deemed appropriate for this driver.
 */
#define RECEIVE_ROOM	65536
#define DRIVERNAME	"n_tracerouter"

/*
 * struct to hold private configuration data for this ldisc.
 * opencalled is used to hold if this ldisc has been opened.
 * kref_tty holds the tty reference the ldisc sits on top of.
 */
struct tracerouter_data {
	u8 opencalled;
	struct tty_struct *kref_tty;
};
static struct tracerouter_data *tr_data;

/* lock for when tty reference is being used */
static DEFINE_MUTEX(routelock);

/**
 * n_tracerouter_open() - Called when a tty is opened by a SW entity.
 * @tty: terminal device to the ldisc.
 *
 * Return:
 *      0 for success.
 *
 * Caveats: This should only be opened one time per SW entity.
 */
static int n_tracerouter_open(struct tty_struct *tty)
{
	int retval = -EEXIST;

	mutex_lock(&routelock);
	if (tr_data->opencalled == 0) {

		tr_data->kref_tty = tty_kref_get(tty);
		if (tr_data->kref_tty == NULL) {
			retval = -EFAULT;
		} else {
			tr_data->opencalled = 1;
			tty->disc_data      = tr_data;
			tty->receive_room   = RECEIVE_ROOM;
			tty_driver_flush_buffer(tty);
			retval = 0;
		}
	}
	mutex_unlock(&routelock);
	return retval;
}

/**
 * n_tracerouter_close() - close connection
 * @tty: terminal device to the ldisc.
 *
 * Called when a software entity wants to close a connection.
 */
static void n_tracerouter_close(struct tty_struct *tty)
{
	struct tracerouter_data *tptr = tty->disc_data;

	mutex_lock(&routelock);
	WARN_ON(tptr->kref_tty != tr_data->kref_tty);
	tty_driver_flush_buffer(tty);
	tty_kref_put(tr_data->kref_tty);
	tr_data->kref_tty = NULL;
	tr_data->opencalled = 0;
	tty->disc_data = NULL;
	mutex_unlock(&routelock);
}

/**
 * n_tracerouter_read() - read request from user space
 * @tty:  terminal device passed into the ldisc.
 * @file: pointer to open file object.
 * @buf:  pointer to the data buffer that gets eventually returned.
 * @nr:   number of bytes of the data buffer that is returned.
 *
 * function that allows read() functionality in userspace. By default if this
 * is not implemented it returns -EIO. This module is functioning like a
 * router via n_tracerouter_receivebuf(), and there is no real requirement
 * to implement this function. However, an error return value other than
 * -EIO should be used just to show that there was an intent not to have
 * this function implemented.  Return value based on read() man pages.
 *
 * Return:
 *	 -EINVAL
 */
static ssize_t n_tracerouter_read(struct tty_struct *tty, struct file *file,
				  unsigned char __user *buf, size_t nr) {
	return -EINVAL;
}

/**
 * n_tracerouter_write() - Function that allows write() in userspace.
 * @tty:  terminal device passed into the ldisc.
 * @file: pointer to open file object.
 * @buf:  pointer to the data buffer that gets eventually returned.
 * @nr:   number of bytes of the data buffer that is returned.
 *
 * By default if this is not implemented, it returns -EIO.
 * This should not be implemented, ever, because
 * 1. this driver is functioning like a router via
 *    n_tracerouter_receivebuf()
 * 2. No writes to HW will ever go through this line discpline driver.
 * However, an error return value other than -EIO should be used
 * just to show that there was an intent not to have this function
 * implemented.  Return value based on write() man pages.
 *
 * Return:
 *	-EINVAL
 */
static ssize_t n_tracerouter_write(struct tty_struct *tty, struct file *file,
				   const unsigned char *buf, size_t nr) {
	return -EINVAL;
}

/**
 * n_tracerouter_receivebuf() - Routing function for driver.
 * @tty: terminal device passed into the ldisc.  It's assumed
 *       tty will never be NULL.
 * @cp:  buffer, block of characters to be eventually read by
 *       someone, somewhere (user read() call or some kernel function).
 * @fp:  flag buffer.
 * @count: number of characters (aka, bytes) in cp.
 *
 * This function takes the input buffer, cp, and passes it to
 * an external API function for processing.
 */
static void n_tracerouter_receivebuf(struct tty_struct *tty,
					const unsigned char *cp,
					char *fp, int count)
{
	mutex_lock(&routelock);
	n_tracesink_datadrain((u8 *) cp, count);
	mutex_unlock(&routelock);
}

/*
 * Flush buffer is not impelemented as the ldisc has no internal buffering
 * so the tty_driver_flush_buffer() is sufficient for this driver's needs.
 */

static struct tty_ldisc_ops tty_ptirouter_ldisc = {
	.owner		= THIS_MODULE,
	.magic		= TTY_LDISC_MAGIC,
	.name		= DRIVERNAME,
	.open		= n_tracerouter_open,
	.close		= n_tracerouter_close,
	.read		= n_tracerouter_read,
	.write		= n_tracerouter_write,
	.receive_buf	= n_tracerouter_receivebuf
};

/**
 * n_tracerouter_init -	module initialisation
 *
 * Registers this module as a line discipline driver.
 *
 * Return:
 *	0 for success, any other value error.
 */
static int __init n_tracerouter_init(void)
{
	int retval;

	tr_data = kzalloc(sizeof(struct tracerouter_data), GFP_KERNEL);
	if (tr_data == NULL)
		return -ENOMEM;


	/* Note N_TRACEROUTER is defined in linux/tty.h */
	retval = tty_register_ldisc(N_TRACEROUTER, &tty_ptirouter_ldisc);
	if (retval < 0) {
		pr_err("%s: Registration failed: %d\n", __func__, retval);
		kfree(tr_data);
	}
	return retval;
}

/**
 * n_tracerouter_exit -	module unload
 *
 * Removes this module as a line discipline driver.
 */
static void __exit n_tracerouter_exit(void)
{
	int retval = tty_unregister_ldisc(N_TRACEROUTER);

	if (retval < 0)
		pr_err("%s: Unregistration failed: %d\n", __func__,  retval);
	else
		kfree(tr_data);
}

module_init(n_tracerouter_init);
module_exit(n_tracerouter_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jay Freyensee");
MODULE_ALIAS_LDISC(N_TRACEROUTER);
MODULE_DESCRIPTION("Trace router ldisc driver");
