1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) 4 */ 5 6 #include <linux/slab.h> 7 #include <linux/tty.h> 8 #include <linux/tty_flip.h> 9 #include "chan.h" 10 #include <os.h> 11 #include <irq_kern.h> 12 13 #ifdef CONFIG_NOCONFIG_CHAN 14 static void *not_configged_init(char *str, int device, 15 const struct chan_opts *opts) 16 { 17 printk(KERN_ERR "Using a channel type which is configured out of " 18 "UML\n"); 19 return NULL; 20 } 21 22 static int not_configged_open(int input, int output, int primary, void *data, 23 char **dev_out) 24 { 25 printk(KERN_ERR "Using a channel type which is configured out of " 26 "UML\n"); 27 return -ENODEV; 28 } 29 30 static void not_configged_close(int fd, void *data) 31 { 32 printk(KERN_ERR "Using a channel type which is configured out of " 33 "UML\n"); 34 } 35 36 static int not_configged_read(int fd, u8 *c_out, void *data) 37 { 38 printk(KERN_ERR "Using a channel type which is configured out of " 39 "UML\n"); 40 return -EIO; 41 } 42 43 static int not_configged_write(int fd, const u8 *buf, size_t len, void *data) 44 { 45 printk(KERN_ERR "Using a channel type which is configured out of " 46 "UML\n"); 47 return -EIO; 48 } 49 50 static int not_configged_console_write(int fd, const char *buf, int len) 51 { 52 printk(KERN_ERR "Using a channel type which is configured out of " 53 "UML\n"); 54 return -EIO; 55 } 56 57 static int not_configged_window_size(int fd, void *data, unsigned short *rows, 58 unsigned short *cols) 59 { 60 printk(KERN_ERR "Using a channel type which is configured out of " 61 "UML\n"); 62 return -ENODEV; 63 } 64 65 static void not_configged_free(void *data) 66 { 67 printk(KERN_ERR "Using a channel type which is configured out of " 68 "UML\n"); 69 } 70 71 static const struct chan_ops not_configged_ops = { 72 .init = not_configged_init, 73 .open = not_configged_open, 74 .close = not_configged_close, 75 .read = not_configged_read, 76 .write = not_configged_write, 77 .console_write = not_configged_console_write, 78 .window_size = not_configged_window_size, 79 .free = not_configged_free, 80 .winch = 0, 81 }; 82 #endif /* CONFIG_NOCONFIG_CHAN */ 83 84 static int open_one_chan(struct chan *chan) 85 { 86 int fd, err; 87 88 if (chan->opened) 89 return 0; 90 91 if (chan->ops->open == NULL) 92 fd = 0; 93 else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary, 94 chan->data, &chan->dev); 95 if (fd < 0) 96 return fd; 97 98 err = os_set_fd_block(fd, 0); 99 if (err) { 100 (*chan->ops->close)(fd, chan->data); 101 return err; 102 } 103 104 chan->fd = fd; 105 106 chan->opened = 1; 107 return 0; 108 } 109 110 static int open_chan(struct list_head *chans) 111 { 112 struct list_head *ele; 113 struct chan *chan; 114 int ret, err = 0; 115 116 list_for_each(ele, chans) { 117 chan = list_entry(ele, struct chan, list); 118 ret = open_one_chan(chan); 119 if (chan->primary) 120 err = ret; 121 } 122 return err; 123 } 124 125 void chan_enable_winch(struct chan *chan, struct tty_port *port) 126 { 127 if (chan && chan->primary && chan->ops->winch) 128 register_winch(chan->fd, port); 129 } 130 131 static void line_timer_cb(struct work_struct *work) 132 { 133 struct line *line = container_of(work, struct line, task.work); 134 135 if (!line->throttled) 136 chan_interrupt(line, line->read_irq); 137 } 138 139 int enable_chan(struct line *line) 140 { 141 struct list_head *ele; 142 struct chan *chan; 143 int err; 144 145 INIT_DELAYED_WORK(&line->task, line_timer_cb); 146 147 list_for_each(ele, &line->chan_list) { 148 chan = list_entry(ele, struct chan, list); 149 err = open_one_chan(chan); 150 if (err) { 151 if (chan->primary) 152 goto out_close; 153 154 continue; 155 } 156 157 if (chan->enabled) 158 continue; 159 err = line_setup_irq(chan->fd, chan->input, chan->output, line, 160 chan); 161 if (err) 162 goto out_close; 163 164 chan->enabled = 1; 165 } 166 167 return 0; 168 169 out_close: 170 close_chan(line); 171 return err; 172 } 173 174 /* Items are added in IRQ context, when free_irq can't be called, and 175 * removed in process context, when it can. 176 * This handles interrupt sources which disappear, and which need to 177 * be permanently disabled. This is discovered in IRQ context, but 178 * the freeing of the IRQ must be done later. 179 */ 180 static DEFINE_SPINLOCK(irqs_to_free_lock); 181 static LIST_HEAD(irqs_to_free); 182 183 void free_irqs(void) 184 { 185 struct chan *chan; 186 LIST_HEAD(list); 187 struct list_head *ele; 188 unsigned long flags; 189 190 spin_lock_irqsave(&irqs_to_free_lock, flags); 191 list_splice_init(&irqs_to_free, &list); 192 spin_unlock_irqrestore(&irqs_to_free_lock, flags); 193 194 list_for_each(ele, &list) { 195 chan = list_entry(ele, struct chan, free_list); 196 197 if (chan->input && chan->enabled) 198 um_free_irq(chan->line->read_irq, chan); 199 if (chan->output && chan->enabled) 200 um_free_irq(chan->line->write_irq, chan); 201 chan->enabled = 0; 202 } 203 } 204 205 static void close_one_chan(struct chan *chan, int delay_free_irq) 206 { 207 unsigned long flags; 208 209 if (!chan->opened) 210 return; 211 212 if (delay_free_irq) { 213 spin_lock_irqsave(&irqs_to_free_lock, flags); 214 list_add(&chan->free_list, &irqs_to_free); 215 spin_unlock_irqrestore(&irqs_to_free_lock, flags); 216 } else { 217 if (chan->input && chan->enabled) 218 um_free_irq(chan->line->read_irq, chan); 219 if (chan->output && chan->enabled) 220 um_free_irq(chan->line->write_irq, chan); 221 chan->enabled = 0; 222 } 223 if (chan->ops->close != NULL) 224 (*chan->ops->close)(chan->fd, chan->data); 225 226 chan->opened = 0; 227 chan->fd = -1; 228 } 229 230 void close_chan(struct line *line) 231 { 232 struct chan *chan; 233 234 /* Close in reverse order as open in case more than one of them 235 * refers to the same device and they save and restore that device's 236 * state. Then, the first one opened will have the original state, 237 * so it must be the last closed. 238 */ 239 list_for_each_entry_reverse(chan, &line->chan_list, list) { 240 close_one_chan(chan, 0); 241 } 242 } 243 244 void deactivate_chan(struct chan *chan, int irq) 245 { 246 if (chan && chan->enabled) 247 deactivate_fd(chan->fd, irq); 248 } 249 250 int write_chan(struct chan *chan, const u8 *buf, size_t len, int write_irq) 251 { 252 int n, ret = 0; 253 254 if (len == 0 || !chan || !chan->ops->write) 255 return 0; 256 257 n = chan->ops->write(chan->fd, buf, len, chan->data); 258 if (chan->primary) { 259 ret = n; 260 } 261 return ret; 262 } 263 264 int console_write_chan(struct chan *chan, const char *buf, int len) 265 { 266 int n, ret = 0; 267 268 if (!chan || !chan->ops->console_write) 269 return 0; 270 271 n = chan->ops->console_write(chan->fd, buf, len); 272 if (chan->primary) 273 ret = n; 274 return ret; 275 } 276 277 int console_open_chan(struct line *line, struct console *co) 278 { 279 int err; 280 281 err = open_chan(&line->chan_list); 282 if (err) 283 return err; 284 285 printk(KERN_INFO "Console initialized on /dev/%s%d\n", co->name, 286 co->index); 287 return 0; 288 } 289 290 int chan_window_size(struct line *line, unsigned short *rows_out, 291 unsigned short *cols_out) 292 { 293 struct chan *chan; 294 295 chan = line->chan_in; 296 if (chan && chan->primary) { 297 if (chan->ops->window_size == NULL) 298 return 0; 299 return chan->ops->window_size(chan->fd, chan->data, 300 rows_out, cols_out); 301 } 302 chan = line->chan_out; 303 if (chan && chan->primary) { 304 if (chan->ops->window_size == NULL) 305 return 0; 306 return chan->ops->window_size(chan->fd, chan->data, 307 rows_out, cols_out); 308 } 309 return 0; 310 } 311 312 static void free_one_chan(struct chan *chan) 313 { 314 list_del(&chan->list); 315 316 close_one_chan(chan, 0); 317 318 if (chan->ops->free != NULL) 319 (*chan->ops->free)(chan->data); 320 321 if (chan->primary && chan->output) 322 ignore_sigio_fd(chan->fd); 323 kfree(chan); 324 } 325 326 static void free_chan(struct list_head *chans) 327 { 328 struct list_head *ele, *next; 329 struct chan *chan; 330 331 list_for_each_safe(ele, next, chans) { 332 chan = list_entry(ele, struct chan, list); 333 free_one_chan(chan); 334 } 335 } 336 337 static int one_chan_config_string(struct chan *chan, char *str, int size, 338 char **error_out) 339 { 340 int n = 0; 341 342 if (chan == NULL) { 343 CONFIG_CHUNK(str, size, n, "none", 1); 344 return n; 345 } 346 347 CONFIG_CHUNK(str, size, n, chan->ops->type, 0); 348 349 if (chan->dev == NULL) { 350 CONFIG_CHUNK(str, size, n, "", 1); 351 return n; 352 } 353 354 CONFIG_CHUNK(str, size, n, ":", 0); 355 CONFIG_CHUNK(str, size, n, chan->dev, 0); 356 357 return n; 358 } 359 360 static int chan_pair_config_string(struct chan *in, struct chan *out, 361 char *str, int size, char **error_out) 362 { 363 int n; 364 365 n = one_chan_config_string(in, str, size, error_out); 366 str += n; 367 size -= n; 368 369 if (in == out) { 370 CONFIG_CHUNK(str, size, n, "", 1); 371 return n; 372 } 373 374 CONFIG_CHUNK(str, size, n, ",", 1); 375 n = one_chan_config_string(out, str, size, error_out); 376 str += n; 377 size -= n; 378 CONFIG_CHUNK(str, size, n, "", 1); 379 380 return n; 381 } 382 383 int chan_config_string(struct line *line, char *str, int size, 384 char **error_out) 385 { 386 struct chan *in = line->chan_in, *out = line->chan_out; 387 388 if (in && !in->primary) 389 in = NULL; 390 if (out && !out->primary) 391 out = NULL; 392 393 return chan_pair_config_string(in, out, str, size, error_out); 394 } 395 396 struct chan_type { 397 char *key; 398 const struct chan_ops *ops; 399 }; 400 401 static const struct chan_type chan_table[] = { 402 { "fd", &fd_ops }, 403 404 #ifdef CONFIG_NULL_CHAN 405 { "null", &null_ops }, 406 #else 407 { "null", ¬_configged_ops }, 408 #endif 409 410 #ifdef CONFIG_PORT_CHAN 411 { "port", &port_ops }, 412 #else 413 { "port", ¬_configged_ops }, 414 #endif 415 416 #ifdef CONFIG_PTY_CHAN 417 { "pty", &pty_ops }, 418 { "pts", &pts_ops }, 419 #else 420 { "pty", ¬_configged_ops }, 421 { "pts", ¬_configged_ops }, 422 #endif 423 424 #ifdef CONFIG_TTY_CHAN 425 { "tty", &tty_ops }, 426 #else 427 { "tty", ¬_configged_ops }, 428 #endif 429 430 #ifdef CONFIG_XTERM_CHAN 431 { "xterm", &xterm_ops }, 432 #else 433 { "xterm", ¬_configged_ops }, 434 #endif 435 }; 436 437 static struct chan *parse_chan(struct line *line, char *str, int device, 438 const struct chan_opts *opts, char **error_out) 439 { 440 const struct chan_type *entry; 441 const struct chan_ops *ops; 442 struct chan *chan; 443 void *data; 444 int i; 445 446 ops = NULL; 447 data = NULL; 448 for(i = 0; i < ARRAY_SIZE(chan_table); i++) { 449 entry = &chan_table[i]; 450 if (!strncmp(str, entry->key, strlen(entry->key))) { 451 ops = entry->ops; 452 str += strlen(entry->key); 453 break; 454 } 455 } 456 if (ops == NULL) { 457 *error_out = "No match for configured backends"; 458 return NULL; 459 } 460 461 data = (*ops->init)(str, device, opts); 462 if (data == NULL) { 463 *error_out = "Configuration failed"; 464 return NULL; 465 } 466 467 chan = kmalloc(sizeof(*chan), GFP_ATOMIC); 468 if (chan == NULL) { 469 *error_out = "Memory allocation failed"; 470 return NULL; 471 } 472 *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list), 473 .free_list = 474 LIST_HEAD_INIT(chan->free_list), 475 .line = line, 476 .primary = 1, 477 .input = 0, 478 .output = 0, 479 .opened = 0, 480 .enabled = 0, 481 .fd = -1, 482 .ops = ops, 483 .data = data }); 484 return chan; 485 } 486 487 int parse_chan_pair(char *str, struct line *line, int device, 488 const struct chan_opts *opts, char **error_out) 489 { 490 struct list_head *chans = &line->chan_list; 491 struct chan *new; 492 char *in, *out; 493 494 if (!list_empty(chans)) { 495 line->chan_in = line->chan_out = NULL; 496 free_chan(chans); 497 INIT_LIST_HEAD(chans); 498 } 499 500 if (!str) 501 return 0; 502 503 out = strchr(str, ','); 504 if (out != NULL) { 505 in = str; 506 *out = '\0'; 507 out++; 508 new = parse_chan(line, in, device, opts, error_out); 509 if (new == NULL) 510 return -1; 511 512 new->input = 1; 513 list_add(&new->list, chans); 514 line->chan_in = new; 515 516 new = parse_chan(line, out, device, opts, error_out); 517 if (new == NULL) 518 return -1; 519 520 list_add(&new->list, chans); 521 new->output = 1; 522 line->chan_out = new; 523 } 524 else { 525 new = parse_chan(line, str, device, opts, error_out); 526 if (new == NULL) 527 return -1; 528 529 list_add(&new->list, chans); 530 new->input = 1; 531 new->output = 1; 532 line->chan_in = line->chan_out = new; 533 } 534 return 0; 535 } 536 537 void chan_interrupt(struct line *line, int irq) 538 { 539 struct tty_port *port = &line->port; 540 struct chan *chan = line->chan_in; 541 int err; 542 u8 c; 543 544 if (!chan || !chan->ops->read) 545 goto out; 546 547 do { 548 if (!tty_buffer_request_room(port, 1)) { 549 schedule_delayed_work(&line->task, 1); 550 goto out; 551 } 552 err = chan->ops->read(chan->fd, &c, chan->data); 553 if (err > 0) 554 tty_insert_flip_char(port, c, TTY_NORMAL); 555 } while (err > 0); 556 557 if (err == -EIO) { 558 if (chan->primary) { 559 tty_port_tty_hangup(&line->port, false); 560 if (line->chan_out != chan) 561 close_one_chan(line->chan_out, 1); 562 } 563 close_one_chan(chan, 1); 564 if (chan->primary) 565 return; 566 } 567 out: 568 tty_flip_buffer_push(port); 569 } 570