diff options
author | Won Kang <wkang77@gmail.com> | 2013-08-16 13:13:43 +0900 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-19 15:30:59 -0700 |
commit | 7ee4c1b94958837015f8b8a1db6101810c211a8c (patch) | |
tree | 115926900d7158c59c8bd54aefe9eb159fd4d8a4 /drivers | |
parent | 7d5b640dfa19a9d55bb5c9dd34f607200cb199c3 (diff) |
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: Won Kang <wonkang@gctsemi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/gdm724x/gdm_tty.c | 294 | ||||
-rw-r--r-- | drivers/staging/gdm724x/gdm_tty.h | 5 |
2 files changed, 142 insertions, 157 deletions
diff --git a/drivers/staging/gdm724x/gdm_tty.c b/drivers/staging/gdm724x/gdm_tty.c index 912022b84c03..5bcf88224e90 100644 --- a/drivers/staging/gdm724x/gdm_tty.c +++ b/drivers/staging/gdm724x/gdm_tty.c @@ -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); + mutex_lock(&gdm_table_lock); + gdm = gdm_table[i][j]; + mutex_unlock(&gdm_table_lock); + if (gdm == NULL) + return -ENODEV; - 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); + tty_port_get(&gdm->port); - mutex_unlock(&open_mutex); + ret = tty_standard_install(driver, tty); + if (ret) { + tty_port_put(&gdm->port); + return ret; + } - return ret; + tty->driver_data = gdm; + + return 0; } -static void gdm_tty_close(struct tty_struct *tty, struct file *filp) +static int gdm_tty_open(struct tty_struct *tty, struct file *filp) { - struct tty_str *tty_str = tty->driver_data; - int i; - - if (!tty_str) { - pr_info("tty device already closed\n"); - return; - } - - if (tty_str->port.count != 0) { - tty_port_close_start(&tty_str->port, tty, filp); - tty_port_close_end(&tty_str->port, tty); + struct gdm *gdm = tty->driver_data; + return tty_port_open(&gdm->port, tty, filp); +} - if (tty_str->port.count == 0) - tty_port_tty_set(&tty_str->port, NULL); - tty_str->port.tty = NULL; - } +static void gdm_tty_cleanup(struct tty_struct *tty) +{ + struct gdm *gdm = tty->driver_data; + tty_port_put(&gdm->port); +} - 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_hangup(struct tty_struct *tty) +{ + struct gdm *gdm = tty->driver_data; + tty_port_hangup(&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_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; - if (!GDM_TTY_READY(tty_str)) { + mutex_lock(&gdm_table_lock); + gdm = gdm_table[index][minor]; + mutex_unlock(&gdm_table_lock); + + 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); - } else { - return TO_HOST_BUFFER_REQUEST_FAIL; + 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 = { - .open = gdm_tty_open, - .close = gdm_tty_close, - .write = gdm_tty_write, - .write_room = gdm_tty_write_room, - .tiocmget = gdm_tty_tiocmget, - .tiocmset = gdm_tty_tiocmset, - .set_termios = gdm_tty_set_termios, + .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, }; 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); } } } + diff --git a/drivers/staging/gdm724x/gdm_tty.h b/drivers/staging/gdm724x/gdm_tty.h index a75be1df0100..64db5e63e389 100644 --- a/drivers/staging/gdm724x/gdm_tty.h +++ b/drivers/staging/gdm724x/gdm_tty.h @@ -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); |