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