Commit 7ee4c1b9 authored by Won Kang's avatar Won Kang Committed by Greg Kroah-Hartman
Browse files

staging: gdm7240: a TTY rewrite according to the latest TTY APIs



Removed the old style reference countings and termios.
Renamed variables to meaninful ones.

Signed-off-by: default avatarWon Kang <wonkang@gctsemi.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7d5b640d
Loading
Loading
Loading
Loading
+139 −155
Original line number Diff line number Diff line
@@ -45,141 +45,138 @@
#define gdm_tty_send_control(n, r, v, d, l) (\
	n->tty_dev->send_control(n->tty_dev->priv_dev, r, v, d, l))

#define acm_set_comm_feature(n, v)	\
	gdm_tty_send_control(n, 0x02, v, NULL, 0)
#define GDM_TTY_READY(gdm) (gdm && gdm->tty_dev && gdm->port.count)

#define GDM_TTY_READY(tty_str) (tty_str && tty_str->tty_dev && tty_str->port.count)

struct tty_driver *g_tty_drv[TTY_MAX_COUNT] = {NULL, };
struct tty_str *g_tty_str[TTY_MAX_COUNT][GDM_TTY_MINOR] = {{NULL, }, };
struct tty_driver *gdm_driver[TTY_MAX_COUNT];
struct gdm *gdm_table[TTY_MAX_COUNT][GDM_TTY_MINOR];
static DEFINE_MUTEX(gdm_table_lock);

static char *DRIVER_STRING[TTY_MAX_COUNT] = {"GCTATC", "GCTDM"};
static char *DEVICE_STRING[TTY_MAX_COUNT] = {"GCT-ATC", "GCT-DM"};

static DEFINE_MUTEX(open_mutex);
static void gdm_port_destruct(struct tty_port *port)
{
	struct gdm *gdm = container_of(port, struct gdm, port);

	mutex_lock(&gdm_table_lock);
	gdm_table[gdm->index][gdm->minor] = NULL;
	mutex_unlock(&gdm_table_lock);

	kfree(gdm);
}

static struct tty_port_operations gdm_tty_port_ops = {
static struct tty_port_operations gdm_port_ops = {
	.destruct = gdm_port_destruct,
};

static int gdm_tty_open(struct tty_struct *tty, struct file *filp)
static int gdm_tty_install(struct tty_driver *driver, struct tty_struct *tty)
{
	struct tty_str *tty_str = NULL;
	struct gdm *gdm = NULL;
	int ret;
	int i;
	int ret = 0;

	mutex_lock(&open_mutex);
	int j;

	j = GDM_TTY_MINOR;
	for (i = 0; i < TTY_MAX_COUNT; i++) {
		if (!strcmp(tty->driver->driver_name, DRIVER_STRING[i])) {
			tty_str = g_tty_str[i][tty->index];
			j = tty->index;
			break;
		}
	}

	if (!tty_str) {
		pr_info("no tty device\n");
		mutex_unlock(&open_mutex);
	if (j == GDM_TTY_MINOR)
		return -ENODEV;
	}

	set_bit(TTY_NO_WRITE_SPLIT, &tty->flags);

	tty->driver_data = tty_str;
	tty_port_tty_set(&tty_str->port, tty);
	tty_str->port.count++;
	set_bit(ASYNCB_INITIALIZED, &tty_str->port.flags);
	ret = tty_port_block_til_ready(&tty_str->port, tty, filp);
	mutex_lock(&gdm_table_lock);
	gdm = gdm_table[i][j];
	mutex_unlock(&gdm_table_lock);
	if (gdm == NULL)
		return -ENODEV;

	mutex_unlock(&open_mutex);
	tty_port_get(&gdm->port);

	ret = tty_standard_install(driver, tty);
	if (ret) {
		tty_port_put(&gdm->port);
		return ret;
	}

static void gdm_tty_close(struct tty_struct *tty, struct file *filp)
{
	struct tty_str *tty_str = tty->driver_data;
	int i;
	tty->driver_data = gdm;

	if (!tty_str) {
		pr_info("tty device already closed\n");
		return;
	return 0;
}

	if (tty_str->port.count != 0) {
		tty_port_close_start(&tty_str->port, tty, filp);
		tty_port_close_end(&tty_str->port, tty);

		if (tty_str->port.count == 0)
			tty_port_tty_set(&tty_str->port, NULL);
			tty_str->port.tty = NULL;
static int gdm_tty_open(struct tty_struct *tty, struct file *filp)
{
	struct gdm *gdm = tty->driver_data;
	return tty_port_open(&gdm->port, tty, filp);
}

	if (!tty_str->tty_dev) {
		for (i = 0; i < TTY_MAX_COUNT; i++) {
			if (!strcmp(tty->driver->driver_name, DRIVER_STRING[i]))
				break;
static void gdm_tty_cleanup(struct tty_struct *tty)
{
	struct gdm *gdm = tty->driver_data;
	tty_port_put(&gdm->port);
}

		if (i < TTY_MAX_COUNT) {
			tty_unregister_device(g_tty_drv[i], tty->index);
			tty_port_tty_set(&tty_str->port, NULL);
			kfree(tty_str);
			g_tty_str[i][tty->index] = NULL;
		}
static void gdm_tty_hangup(struct tty_struct *tty)
{
	struct gdm *gdm = tty->driver_data;
	tty_port_hangup(&gdm->port);
}

static void gdm_tty_close(struct tty_struct *tty, struct file *filp)
{
	struct gdm *gdm = tty->driver_data;
	tty_port_close(&gdm->port, tty, filp);
}

static int gdm_tty_recv_complete(void *data, int len, int index, int minor, int complete)
{
	struct tty_str *tty_str = g_tty_str[index][minor];
	struct tty_port *tty_port;
	struct gdm *gdm;

	mutex_lock(&gdm_table_lock);
	gdm = gdm_table[index][minor];
	mutex_unlock(&gdm_table_lock);

	if (!GDM_TTY_READY(tty_str)) {
	if (!GDM_TTY_READY(gdm)) {
		if (complete == RECV_PACKET_PROCESS_COMPLETE)
			gdm_tty_recv(tty_str, gdm_tty_recv_complete);
			gdm_tty_recv(gdm, gdm_tty_recv_complete);
		return TO_HOST_PORT_CLOSE;
	}

	if (!data || !len)
		goto complete_routine;

	tty_port = &tty_str->port;

	if (tty_buffer_request_room(tty_port, len) == len) {
		tty_insert_flip_string(tty_port, data, len);
		tty_flip_buffer_push(tty_port);
	if (data && len) {
		if (tty_buffer_request_room(&gdm->port, len) == len) {
			tty_insert_flip_string(&gdm->port, data, len);
			tty_flip_buffer_push(&gdm->port);
		} else {
			return TO_HOST_BUFFER_REQUEST_FAIL;
		}
	}

complete_routine:
	if (complete == RECV_PACKET_PROCESS_COMPLETE)
		gdm_tty_recv(tty_str, gdm_tty_recv_complete);
		gdm_tty_recv(gdm, gdm_tty_recv_complete);

	return 0;
}

static void gdm_tty_send_complete(void *arg)
{
	struct tty_str *tty_str = (struct tty_str *)arg;
	struct tty_struct *tty;
	struct gdm *gdm = (struct gdm *)arg;

	if (!GDM_TTY_READY(tty_str))
	if (!GDM_TTY_READY(gdm))
		return;

	tty = tty_port_tty_get(&tty_str->port);
	tty_wakeup(tty);
	tty_kref_put(tty);
	tty_port_tty_wakeup(&gdm->port);
}

static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf, int len)
{
	struct tty_str *tty_str = tty->driver_data;
	struct gdm *gdm = tty->driver_data;
	int remain = len;
	int sent_len = 0;
	int sending_len = 0;

	if (!GDM_TTY_READY(tty_str))
	if (!GDM_TTY_READY(gdm))
		return -ENODEV;

	if (!len)
@@ -187,12 +184,12 @@ static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf, int l

	while (1) {
		sending_len = remain > MUX_TX_MAX_SIZE ? MUX_TX_MAX_SIZE : remain;
		gdm_tty_send(tty_str,
		gdm_tty_send(gdm,
			     (void *)(buf+sent_len),
			     sending_len,
			     tty_str->tty_drv_index,
			     gdm->index,
			     gdm_tty_send_complete,
			     tty_str
			     gdm
			    );
		sent_len += sending_len;
		remain -= sending_len;
@@ -205,131 +202,113 @@ static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf, int l

static int gdm_tty_write_room(struct tty_struct *tty)
{
	struct tty_str *tty_str = tty->driver_data;
	struct gdm *gdm = tty->driver_data;

	if (!GDM_TTY_READY(tty_str))
	if (!GDM_TTY_READY(gdm))
		return -ENODEV;

	return WRITE_SIZE;
}

static int gdm_tty_tiocmget(struct tty_struct *tty)
{
	struct tty_str *tty_str = tty->driver_data;

	if (!GDM_TTY_READY(tty_str))
		return -ENODEV;

	return (0 & ACM_CTRL_DTR ? TIOCM_DTR : 0) |
	       (0 & ACM_CTRL_RTS ? TIOCM_RTS : 0) |
	       (0 & ACM_CTRL_DSR ? TIOCM_DSR : 0) |
	       (0 & ACM_CTRL_RI  ? TIOCM_RI  : 0) |
	       (0 & ACM_CTRL_DCD ? TIOCM_CD  : 0) |
	       TIOCM_CTS;
}

static int gdm_tty_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
int register_lte_tty_device(struct tty_dev *tty_dev, struct device *device)
{
	struct tty_str *tty_str = tty->driver_data;
	struct gdm *gdm;
	int i;
	int j;

	if (!GDM_TTY_READY(tty_str))
		return -ENODEV;
	for (i = 0; i < TTY_MAX_COUNT; i++) {

	return 1;
}
		gdm = kmalloc(sizeof(struct gdm), GFP_KERNEL);
		if (!gdm)
			return -ENOMEM;

int register_lte_tty_device(struct tty_dev *tty_dev, struct device *dev)
{
	struct tty_str *tty_str;
	int i, j;
		mutex_lock(&gdm_table_lock);

	for (i = 0; i < TTY_MAX_COUNT; i++) {
		for (j = 0; j < GDM_TTY_MINOR; j++) {
			if (!g_tty_str[i][j])
			if (!gdm_table[i][j])
				break;
		}

		if (j == GDM_TTY_MINOR) {
			tty_dev->minor[i] = j;
			return -1;
			tty_dev->minor[i] = GDM_TTY_MINOR;
			mutex_unlock(&gdm_table_lock);
			return -EINVAL;
		}

		tty_str = kmalloc(sizeof(struct tty_str), GFP_KERNEL);
		if (!tty_str)
			return -ENOMEM;
		gdm_table[i][j] = gdm;

		g_tty_str[i][j] = tty_str;
		mutex_unlock(&gdm_table_lock);

		tty_str->tty_dev = tty_dev;
		tty_str->tty_drv_index = i;
		tty_dev->minor[i] = j;
		tty_port_init(&tty_str->port);
		tty_str->port.ops = &gdm_tty_port_ops;

		if (strcmp(DEVICE_STRING[i], "GCT-ATC") != 0)
			dev = NULL;
		tty_register_device(g_tty_drv[i], j, dev);
	}
		tty_port_init(&gdm->port);
		gdm->port.ops = &gdm_port_ops;
		gdm->index = i;
		gdm->minor = j;
		gdm->tty_dev = tty_dev;

	acm_set_comm_feature(tty_str, 1);
		tty_port_register_device(&gdm->port, gdm_driver[i], j, device);
	}

	for (i = 0; i < MAX_ISSUE_NUM; i++)
		gdm_tty_recv(tty_str, gdm_tty_recv_complete);
		gdm_tty_recv(gdm, gdm_tty_recv_complete);

	return 0;
}

void unregister_lte_tty_device(struct tty_dev *tty_dev)
{
	struct tty_str *tty_str;
	struct gdm *gdm;
	struct tty_struct *tty;
	int i;
	int j;

	for (i = 0; i < TTY_MAX_COUNT; i++) {
		if (tty_dev->minor[i] >= GDM_TTY_MINOR)
			continue;

		tty_str = g_tty_str[i][tty_dev->minor[i]];
		if (!tty_str)
		j = tty_dev->minor[i];

		if (j >= GDM_TTY_MINOR)
			continue;

		tty_str->tty_dev = NULL;
		mutex_lock(&gdm_table_lock);
		gdm = gdm_table[i][j];
		mutex_unlock(&gdm_table_lock);

		if (!tty_str->port.count) {
			tty_unregister_device(g_tty_drv[i], tty_dev->minor[i]);
			tty_port_tty_set(&tty_str->port, NULL);
			kfree(tty_str);
			g_tty_str[i][tty_dev->minor[i]] = NULL;
		}
	}
		if (!gdm)
			continue;

		tty = tty_port_tty_get(&gdm->port);
		if (tty) {
			tty_vhangup(tty);
			tty_kref_put(tty);
		}

static void gdm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old)
{
	return;
		tty_unregister_device(gdm_driver[i], j);
		tty_port_put(&gdm->port);

	}
}

static const struct tty_operations gdm_tty_ops = {
	.install =	gdm_tty_install,
	.open =		gdm_tty_open,
	.close =	gdm_tty_close,
	.cleanup =	gdm_tty_cleanup,
	.hangup =	gdm_tty_hangup,
	.write =	gdm_tty_write,
	.write_room =	gdm_tty_write_room,
	.tiocmget = gdm_tty_tiocmget,
	.tiocmset = gdm_tty_tiocmset,
	.set_termios = gdm_tty_set_termios,
};

int register_lte_tty_driver(void)
{
	struct tty_driver *tty_driver = NULL;
	struct tty_driver *tty_driver;
	int i;
	int ret;

	for (i = 0; i < TTY_MAX_COUNT; i++) {
		tty_driver = alloc_tty_driver(GDM_TTY_MINOR);
		if (!tty_driver) {
			pr_err("alloc_tty_driver fail\n");
		if (!tty_driver)
			return -ENOMEM;
		}

		tty_driver->owner = THIS_MODULE;
		tty_driver->driver_name = DRIVER_STRING[i];
@@ -344,8 +323,12 @@ int register_lte_tty_driver(void)
		tty_set_operations(tty_driver, &gdm_tty_ops);

		ret = tty_register_driver(tty_driver);
		if (ret) {
			put_tty_driver(tty_driver);
			return ret;
		}

		g_tty_drv[i] = tty_driver;
		gdm_driver[i] = tty_driver;
	}

	return ret;
@@ -357,10 +340,11 @@ void unregister_lte_tty_driver(void)
	int i;

	for (i = 0; i < TTY_MAX_COUNT; i++) {
		tty_driver = g_tty_drv[i];
		tty_driver = gdm_driver[i];
		if (tty_driver) {
			tty_unregister_driver(tty_driver);
			put_tty_driver(tty_driver);
		}
	}
}
+3 −2
Original line number Diff line number Diff line
@@ -44,10 +44,11 @@ struct tty_dev {
	u8 minor[2];
};

struct tty_str {
struct gdm {
	struct tty_dev *tty_dev;
	int tty_drv_index;
	struct tty_port port;
	unsigned int index;
	unsigned int minor;
};

int register_lte_tty_driver(void);