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