0001
0002
0003
0004 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0005
0006 #include <linux/kernel.h>
0007 #include <linux/errno.h>
0008 #include <linux/tty.h>
0009 #include <linux/tty_driver.h>
0010 #include <linux/tty_flip.h>
0011 #include <linux/module.h>
0012 #include <linux/slab.h>
0013 #include <linux/usb/cdc.h>
0014 #include <linux/serial.h>
0015 #include "gdm_tty.h"
0016
0017 #define GDM_TTY_MAJOR 0
0018 #define GDM_TTY_MINOR 32
0019
0020 #define WRITE_SIZE 2048
0021
0022 #define MUX_TX_MAX_SIZE 2048
0023
0024 #define GDM_TTY_READY(gdm) (gdm && gdm->tty_dev && gdm->port.count)
0025
0026 static struct tty_driver *gdm_driver[TTY_MAX_COUNT];
0027 static struct gdm *gdm_table[TTY_MAX_COUNT][GDM_TTY_MINOR];
0028 static DEFINE_MUTEX(gdm_table_lock);
0029
0030 static const char *DRIVER_STRING[TTY_MAX_COUNT] = {"GCTATC", "GCTDM"};
0031 static char *DEVICE_STRING[TTY_MAX_COUNT] = {"GCT-ATC", "GCT-DM"};
0032
0033 static void gdm_port_destruct(struct tty_port *port)
0034 {
0035 struct gdm *gdm = container_of(port, struct gdm, port);
0036
0037 mutex_lock(&gdm_table_lock);
0038 gdm_table[gdm->index][gdm->minor] = NULL;
0039 mutex_unlock(&gdm_table_lock);
0040
0041 kfree(gdm);
0042 }
0043
0044 static const struct tty_port_operations gdm_port_ops = {
0045 .destruct = gdm_port_destruct,
0046 };
0047
0048 static int gdm_tty_install(struct tty_driver *driver, struct tty_struct *tty)
0049 {
0050 struct gdm *gdm = NULL;
0051 int ret;
0052
0053 ret = match_string(DRIVER_STRING, TTY_MAX_COUNT,
0054 tty->driver->driver_name);
0055 if (ret < 0)
0056 return -ENODEV;
0057
0058 mutex_lock(&gdm_table_lock);
0059 gdm = gdm_table[ret][tty->index];
0060 if (!gdm) {
0061 mutex_unlock(&gdm_table_lock);
0062 return -ENODEV;
0063 }
0064
0065 tty_port_get(&gdm->port);
0066
0067 ret = tty_standard_install(driver, tty);
0068 if (ret) {
0069 tty_port_put(&gdm->port);
0070 mutex_unlock(&gdm_table_lock);
0071 return ret;
0072 }
0073
0074 tty->driver_data = gdm;
0075 mutex_unlock(&gdm_table_lock);
0076
0077 return 0;
0078 }
0079
0080 static int gdm_tty_open(struct tty_struct *tty, struct file *filp)
0081 {
0082 struct gdm *gdm = tty->driver_data;
0083
0084 return tty_port_open(&gdm->port, tty, filp);
0085 }
0086
0087 static void gdm_tty_cleanup(struct tty_struct *tty)
0088 {
0089 struct gdm *gdm = tty->driver_data;
0090
0091 tty_port_put(&gdm->port);
0092 }
0093
0094 static void gdm_tty_hangup(struct tty_struct *tty)
0095 {
0096 struct gdm *gdm = tty->driver_data;
0097
0098 tty_port_hangup(&gdm->port);
0099 }
0100
0101 static void gdm_tty_close(struct tty_struct *tty, struct file *filp)
0102 {
0103 struct gdm *gdm = tty->driver_data;
0104
0105 tty_port_close(&gdm->port, tty, filp);
0106 }
0107
0108 static int gdm_tty_recv_complete(void *data,
0109 int len,
0110 int index,
0111 struct tty_dev *tty_dev,
0112 int complete)
0113 {
0114 struct gdm *gdm = tty_dev->gdm[index];
0115
0116 if (!GDM_TTY_READY(gdm)) {
0117 if (complete == RECV_PACKET_PROCESS_COMPLETE)
0118 gdm->tty_dev->recv_func(gdm->tty_dev->priv_dev,
0119 gdm_tty_recv_complete);
0120 return TO_HOST_PORT_CLOSE;
0121 }
0122
0123 if (data && len) {
0124 if (tty_buffer_request_room(&gdm->port, len) == len) {
0125 tty_insert_flip_string(&gdm->port, data, len);
0126 tty_flip_buffer_push(&gdm->port);
0127 } else {
0128 return TO_HOST_BUFFER_REQUEST_FAIL;
0129 }
0130 }
0131
0132 if (complete == RECV_PACKET_PROCESS_COMPLETE)
0133 gdm->tty_dev->recv_func(gdm->tty_dev->priv_dev,
0134 gdm_tty_recv_complete);
0135
0136 return 0;
0137 }
0138
0139 static void gdm_tty_send_complete(void *arg)
0140 {
0141 struct gdm *gdm = arg;
0142
0143 if (!GDM_TTY_READY(gdm))
0144 return;
0145
0146 tty_port_tty_wakeup(&gdm->port);
0147 }
0148
0149 static int gdm_tty_write(struct tty_struct *tty, const unsigned char *buf,
0150 int len)
0151 {
0152 struct gdm *gdm = tty->driver_data;
0153 int remain = len;
0154 int sent_len = 0;
0155 int sending_len = 0;
0156
0157 if (!GDM_TTY_READY(gdm))
0158 return -ENODEV;
0159
0160 if (!len)
0161 return 0;
0162
0163 while (1) {
0164 sending_len = min(MUX_TX_MAX_SIZE, remain);
0165 gdm->tty_dev->send_func(gdm->tty_dev->priv_dev,
0166 (void *)(buf + sent_len),
0167 sending_len,
0168 gdm->index,
0169 gdm_tty_send_complete,
0170 gdm);
0171 sent_len += sending_len;
0172 remain -= sending_len;
0173 if (remain <= 0)
0174 break;
0175 }
0176
0177 return len;
0178 }
0179
0180 static unsigned int gdm_tty_write_room(struct tty_struct *tty)
0181 {
0182 struct gdm *gdm = tty->driver_data;
0183
0184 if (!GDM_TTY_READY(gdm))
0185 return 0;
0186
0187 return WRITE_SIZE;
0188 }
0189
0190 int register_lte_tty_device(struct tty_dev *tty_dev, struct device *device)
0191 {
0192 struct gdm *gdm;
0193 int i;
0194 int j;
0195
0196 for (i = 0; i < TTY_MAX_COUNT; i++) {
0197 gdm = kmalloc(sizeof(*gdm), GFP_KERNEL);
0198 if (!gdm)
0199 return -ENOMEM;
0200
0201 mutex_lock(&gdm_table_lock);
0202 for (j = 0; j < GDM_TTY_MINOR; j++) {
0203 if (!gdm_table[i][j])
0204 break;
0205 }
0206
0207 if (j == GDM_TTY_MINOR) {
0208 kfree(gdm);
0209 mutex_unlock(&gdm_table_lock);
0210 return -EINVAL;
0211 }
0212
0213 gdm_table[i][j] = gdm;
0214 mutex_unlock(&gdm_table_lock);
0215
0216 tty_dev->gdm[i] = gdm;
0217 tty_port_init(&gdm->port);
0218
0219 gdm->port.ops = &gdm_port_ops;
0220 gdm->index = i;
0221 gdm->minor = j;
0222 gdm->tty_dev = tty_dev;
0223
0224 tty_port_register_device(&gdm->port, gdm_driver[i],
0225 gdm->minor, device);
0226 }
0227
0228 for (i = 0; i < MAX_ISSUE_NUM; i++)
0229 gdm->tty_dev->recv_func(gdm->tty_dev->priv_dev,
0230 gdm_tty_recv_complete);
0231
0232 return 0;
0233 }
0234
0235 void unregister_lte_tty_device(struct tty_dev *tty_dev)
0236 {
0237 struct gdm *gdm;
0238 struct tty_struct *tty;
0239 int i;
0240
0241 for (i = 0; i < TTY_MAX_COUNT; i++) {
0242 gdm = tty_dev->gdm[i];
0243 if (!gdm)
0244 continue;
0245
0246 mutex_lock(&gdm_table_lock);
0247 gdm_table[gdm->index][gdm->minor] = NULL;
0248 mutex_unlock(&gdm_table_lock);
0249
0250 tty = tty_port_tty_get(&gdm->port);
0251 if (tty) {
0252 tty_vhangup(tty);
0253 tty_kref_put(tty);
0254 }
0255
0256 tty_unregister_device(gdm_driver[i], gdm->minor);
0257 tty_port_put(&gdm->port);
0258 }
0259 }
0260
0261 static const struct tty_operations gdm_tty_ops = {
0262 .install = gdm_tty_install,
0263 .open = gdm_tty_open,
0264 .close = gdm_tty_close,
0265 .cleanup = gdm_tty_cleanup,
0266 .hangup = gdm_tty_hangup,
0267 .write = gdm_tty_write,
0268 .write_room = gdm_tty_write_room,
0269 };
0270
0271 int register_lte_tty_driver(void)
0272 {
0273 struct tty_driver *tty_driver;
0274 int i;
0275 int ret;
0276
0277 for (i = 0; i < TTY_MAX_COUNT; i++) {
0278 tty_driver = tty_alloc_driver(GDM_TTY_MINOR,
0279 TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV);
0280 if (IS_ERR(tty_driver))
0281 return PTR_ERR(tty_driver);
0282
0283 tty_driver->owner = THIS_MODULE;
0284 tty_driver->driver_name = DRIVER_STRING[i];
0285 tty_driver->name = DEVICE_STRING[i];
0286 tty_driver->major = GDM_TTY_MAJOR;
0287 tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
0288 tty_driver->subtype = SERIAL_TYPE_NORMAL;
0289 tty_driver->init_termios = tty_std_termios;
0290 tty_driver->init_termios.c_cflag = B9600 | CS8 | HUPCL | CLOCAL;
0291 tty_driver->init_termios.c_lflag = ISIG | ICANON | IEXTEN;
0292 tty_set_operations(tty_driver, &gdm_tty_ops);
0293
0294 ret = tty_register_driver(tty_driver);
0295 if (ret) {
0296 tty_driver_kref_put(tty_driver);
0297 return ret;
0298 }
0299
0300 gdm_driver[i] = tty_driver;
0301 }
0302
0303 return ret;
0304 }
0305
0306 void unregister_lte_tty_driver(void)
0307 {
0308 struct tty_driver *tty_driver;
0309 int i;
0310
0311 for (i = 0; i < TTY_MAX_COUNT; i++) {
0312 tty_driver = gdm_driver[i];
0313 if (tty_driver) {
0314 tty_unregister_driver(tty_driver);
0315 tty_driver_kref_put(tty_driver);
0316 }
0317 }
0318 }
0319