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; 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 chan->fd = fd; 172 173 chan->opened = 1; 174 return 0; 175 } 176 177 int open_chan(struct list_head *chans) 178 { 179 struct list_head *ele; 180 struct chan *chan; 181 int ret, err = 0; 182 183 list_for_each(ele, chans){ 184 chan = list_entry(ele, struct chan, list); 185 ret = open_one_chan(chan); 186 if(chan->primary) 187 err = ret; 188 } 189 return err; 190 } 191 192 void chan_enable_winch(struct list_head *chans, struct tty_struct *tty) 193 { 194 struct list_head *ele; 195 struct chan *chan; 196 197 list_for_each(ele, chans){ 198 chan = list_entry(ele, struct chan, list); 199 if(chan->primary && chan->output && chan->ops->winch){ 200 register_winch(chan->fd, tty); 201 return; 202 } 203 } 204 } 205 206 int enable_chan(struct line *line) 207 { 208 struct list_head *ele; 209 struct chan *chan; 210 int err; 211 212 list_for_each(ele, &line->chan_list){ 213 chan = list_entry(ele, struct chan, list); 214 err = open_one_chan(chan); 215 if (err) { 216 if (chan->primary) 217 goto out_close; 218 219 continue; 220 } 221 222 if(chan->enabled) 223 continue; 224 err = line_setup_irq(chan->fd, chan->input, chan->output, line, 225 chan); 226 if (err) 227 goto out_close; 228 229 chan->enabled = 1; 230 } 231 232 return 0; 233 234 out_close: 235 close_chan(&line->chan_list, 0); 236 return err; 237 } 238 239 /* Items are added in IRQ context, when free_irq can't be called, and 240 * removed in process context, when it can. 241 * This handles interrupt sources which disappear, and which need to 242 * be permanently disabled. This is discovered in IRQ context, but 243 * the freeing of the IRQ must be done later. 244 */ 245 static DEFINE_SPINLOCK(irqs_to_free_lock); 246 static LIST_HEAD(irqs_to_free); 247 248 void free_irqs(void) 249 { 250 struct chan *chan; 251 LIST_HEAD(list); 252 struct list_head *ele; 253 unsigned long flags; 254 255 spin_lock_irqsave(&irqs_to_free_lock, flags); 256 list_splice_init(&irqs_to_free, &list); 257 spin_unlock_irqrestore(&irqs_to_free_lock, flags); 258 259 list_for_each(ele, &list){ 260 chan = list_entry(ele, struct chan, free_list); 261 262 if(chan->input) 263 free_irq(chan->line->driver->read_irq, chan); 264 if(chan->output) 265 free_irq(chan->line->driver->write_irq, chan); 266 chan->enabled = 0; 267 } 268 } 269 270 static void close_one_chan(struct chan *chan, int delay_free_irq) 271 { 272 unsigned long flags; 273 274 if(!chan->opened) 275 return; 276 277 if(delay_free_irq){ 278 spin_lock_irqsave(&irqs_to_free_lock, flags); 279 list_add(&chan->free_list, &irqs_to_free); 280 spin_unlock_irqrestore(&irqs_to_free_lock, flags); 281 } 282 else { 283 if(chan->input) 284 free_irq(chan->line->driver->read_irq, chan); 285 if(chan->output) 286 free_irq(chan->line->driver->write_irq, chan); 287 chan->enabled = 0; 288 } 289 if(chan->ops->close != NULL) 290 (*chan->ops->close)(chan->fd, chan->data); 291 292 chan->opened = 0; 293 chan->fd = -1; 294 } 295 296 void close_chan(struct list_head *chans, int delay_free_irq) 297 { 298 struct chan *chan; 299 300 /* Close in reverse order as open in case more than one of them 301 * refers to the same device and they save and restore that device's 302 * state. Then, the first one opened will have the original state, 303 * so it must be the last closed. 304 */ 305 list_for_each_entry_reverse(chan, chans, list) { 306 close_one_chan(chan, delay_free_irq); 307 } 308 } 309 310 void deactivate_chan(struct list_head *chans, int irq) 311 { 312 struct list_head *ele; 313 314 struct chan *chan; 315 list_for_each(ele, chans) { 316 chan = list_entry(ele, struct chan, list); 317 318 if(chan->enabled && chan->input) 319 deactivate_fd(chan->fd, irq); 320 } 321 } 322 323 void reactivate_chan(struct list_head *chans, int irq) 324 { 325 struct list_head *ele; 326 struct chan *chan; 327 328 list_for_each(ele, chans) { 329 chan = list_entry(ele, struct chan, list); 330 331 if(chan->enabled && chan->input) 332 reactivate_fd(chan->fd, irq); 333 } 334 } 335 336 int write_chan(struct list_head *chans, const char *buf, int len, 337 int write_irq) 338 { 339 struct list_head *ele; 340 struct chan *chan = NULL; 341 int n, ret = 0; 342 343 list_for_each(ele, chans) { 344 chan = list_entry(ele, struct chan, list); 345 if (!chan->output || (chan->ops->write == NULL)) 346 continue; 347 n = chan->ops->write(chan->fd, buf, len, chan->data); 348 if (chan->primary) { 349 ret = n; 350 if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len))) 351 reactivate_fd(chan->fd, write_irq); 352 } 353 } 354 return ret; 355 } 356 357 int console_write_chan(struct list_head *chans, const char *buf, int len) 358 { 359 struct list_head *ele; 360 struct chan *chan; 361 int n, ret = 0; 362 363 list_for_each(ele, chans){ 364 chan = list_entry(ele, struct chan, list); 365 if(!chan->output || (chan->ops->console_write == NULL)) 366 continue; 367 n = chan->ops->console_write(chan->fd, buf, len); 368 if(chan->primary) ret = n; 369 } 370 return ret; 371 } 372 373 int console_open_chan(struct line *line, struct console *co) 374 { 375 int err; 376 377 err = open_chan(&line->chan_list); 378 if(err) 379 return err; 380 381 printk("Console initialized on /dev/%s%d\n", co->name, co->index); 382 return 0; 383 } 384 385 int chan_window_size(struct list_head *chans, unsigned short *rows_out, 386 unsigned short *cols_out) 387 { 388 struct list_head *ele; 389 struct chan *chan; 390 391 list_for_each(ele, chans){ 392 chan = list_entry(ele, struct chan, list); 393 if(chan->primary){ 394 if(chan->ops->window_size == NULL) 395 return 0; 396 return chan->ops->window_size(chan->fd, chan->data, 397 rows_out, cols_out); 398 } 399 } 400 return 0; 401 } 402 403 static void free_one_chan(struct chan *chan, int delay_free_irq) 404 { 405 list_del(&chan->list); 406 407 close_one_chan(chan, delay_free_irq); 408 409 if(chan->ops->free != NULL) 410 (*chan->ops->free)(chan->data); 411 412 if(chan->primary && chan->output) ignore_sigio_fd(chan->fd); 413 kfree(chan); 414 } 415 416 static void free_chan(struct list_head *chans, int delay_free_irq) 417 { 418 struct list_head *ele, *next; 419 struct chan *chan; 420 421 list_for_each_safe(ele, next, chans){ 422 chan = list_entry(ele, struct chan, list); 423 free_one_chan(chan, delay_free_irq); 424 } 425 } 426 427 static int one_chan_config_string(struct chan *chan, char *str, int size, 428 char **error_out) 429 { 430 int n = 0; 431 432 if(chan == NULL){ 433 CONFIG_CHUNK(str, size, n, "none", 1); 434 return n; 435 } 436 437 CONFIG_CHUNK(str, size, n, chan->ops->type, 0); 438 439 if(chan->dev == NULL){ 440 CONFIG_CHUNK(str, size, n, "", 1); 441 return n; 442 } 443 444 CONFIG_CHUNK(str, size, n, ":", 0); 445 CONFIG_CHUNK(str, size, n, chan->dev, 0); 446 447 return n; 448 } 449 450 static int chan_pair_config_string(struct chan *in, struct chan *out, 451 char *str, int size, char **error_out) 452 { 453 int n; 454 455 n = one_chan_config_string(in, str, size, error_out); 456 str += n; 457 size -= n; 458 459 if(in == out){ 460 CONFIG_CHUNK(str, size, n, "", 1); 461 return n; 462 } 463 464 CONFIG_CHUNK(str, size, n, ",", 1); 465 n = one_chan_config_string(out, str, size, error_out); 466 str += n; 467 size -= n; 468 CONFIG_CHUNK(str, size, n, "", 1); 469 470 return n; 471 } 472 473 int chan_config_string(struct list_head *chans, char *str, int size, 474 char **error_out) 475 { 476 struct list_head *ele; 477 struct chan *chan, *in = NULL, *out = NULL; 478 479 list_for_each(ele, chans){ 480 chan = list_entry(ele, struct chan, list); 481 if(!chan->primary) 482 continue; 483 if(chan->input) 484 in = chan; 485 if(chan->output) 486 out = chan; 487 } 488 489 return chan_pair_config_string(in, out, str, size, error_out); 490 } 491 492 struct chan_type { 493 char *key; 494 const struct chan_ops *ops; 495 }; 496 497 static const struct chan_type chan_table[] = { 498 { "fd", &fd_ops }, 499 500 #ifdef CONFIG_NULL_CHAN 501 { "null", &null_ops }, 502 #else 503 { "null", ¬_configged_ops }, 504 #endif 505 506 #ifdef CONFIG_PORT_CHAN 507 { "port", &port_ops }, 508 #else 509 { "port", ¬_configged_ops }, 510 #endif 511 512 #ifdef CONFIG_PTY_CHAN 513 { "pty", &pty_ops }, 514 { "pts", &pts_ops }, 515 #else 516 { "pty", ¬_configged_ops }, 517 { "pts", ¬_configged_ops }, 518 #endif 519 520 #ifdef CONFIG_TTY_CHAN 521 { "tty", &tty_ops }, 522 #else 523 { "tty", ¬_configged_ops }, 524 #endif 525 526 #ifdef CONFIG_XTERM_CHAN 527 { "xterm", &xterm_ops }, 528 #else 529 { "xterm", ¬_configged_ops }, 530 #endif 531 }; 532 533 static struct chan *parse_chan(struct line *line, char *str, int device, 534 const struct chan_opts *opts, char **error_out) 535 { 536 const struct chan_type *entry; 537 const struct chan_ops *ops; 538 struct chan *chan; 539 void *data; 540 int i; 541 542 ops = NULL; 543 data = NULL; 544 for(i = 0; i < ARRAY_SIZE(chan_table); i++){ 545 entry = &chan_table[i]; 546 if(!strncmp(str, entry->key, strlen(entry->key))){ 547 ops = entry->ops; 548 str += strlen(entry->key); 549 break; 550 } 551 } 552 if(ops == NULL){ 553 *error_out = "No match for configured backends"; 554 return NULL; 555 } 556 557 data = (*ops->init)(str, device, opts); 558 if(data == NULL){ 559 *error_out = "Configuration failed"; 560 return NULL; 561 } 562 563 chan = kmalloc(sizeof(*chan), GFP_ATOMIC); 564 if(chan == NULL){ 565 *error_out = "Memory allocation failed"; 566 return NULL; 567 } 568 *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list), 569 .free_list = 570 LIST_HEAD_INIT(chan->free_list), 571 .line = line, 572 .primary = 1, 573 .input = 0, 574 .output = 0, 575 .opened = 0, 576 .enabled = 0, 577 .fd = -1, 578 .ops = ops, 579 .data = data }); 580 return chan; 581 } 582 583 int parse_chan_pair(char *str, struct line *line, int device, 584 const struct chan_opts *opts, char **error_out) 585 { 586 struct list_head *chans = &line->chan_list; 587 struct chan *new, *chan; 588 char *in, *out; 589 590 if(!list_empty(chans)){ 591 chan = list_entry(chans->next, struct chan, list); 592 free_chan(chans, 0); 593 INIT_LIST_HEAD(chans); 594 } 595 596 out = strchr(str, ','); 597 if(out != NULL){ 598 in = str; 599 *out = '\0'; 600 out++; 601 new = parse_chan(line, in, device, opts, error_out); 602 if(new == NULL) 603 return -1; 604 605 new->input = 1; 606 list_add(&new->list, chans); 607 608 new = parse_chan(line, out, device, opts, error_out); 609 if(new == NULL) 610 return -1; 611 612 list_add(&new->list, chans); 613 new->output = 1; 614 } 615 else { 616 new = parse_chan(line, str, device, opts, error_out); 617 if(new == NULL) 618 return -1; 619 620 list_add(&new->list, chans); 621 new->input = 1; 622 new->output = 1; 623 } 624 return 0; 625 } 626 627 int chan_out_fd(struct list_head *chans) 628 { 629 struct list_head *ele; 630 struct chan *chan; 631 632 list_for_each(ele, chans){ 633 chan = list_entry(ele, struct chan, list); 634 if(chan->primary && chan->output) 635 return chan->fd; 636 } 637 return -1; 638 } 639 640 void chan_interrupt(struct list_head *chans, struct delayed_work *task, 641 struct tty_struct *tty, int irq) 642 { 643 struct list_head *ele, *next; 644 struct chan *chan; 645 int err; 646 char c; 647 648 list_for_each_safe(ele, next, chans){ 649 chan = list_entry(ele, struct chan, list); 650 if(!chan->input || (chan->ops->read == NULL)) continue; 651 do { 652 if (tty && !tty_buffer_request_room(tty, 1)) { 653 schedule_delayed_work(task, 1); 654 goto out; 655 } 656 err = chan->ops->read(chan->fd, &c, chan->data); 657 if(err > 0) 658 tty_receive_char(tty, c); 659 } while(err > 0); 660 661 if(err == 0) reactivate_fd(chan->fd, irq); 662 if(err == -EIO){ 663 if(chan->primary){ 664 if(tty != NULL) 665 tty_hangup(tty); 666 close_chan(chans, 1); 667 return; 668 } 669 else close_one_chan(chan, 1); 670 } 671 } 672 out: 673 if(tty) tty_flip_buffer_push(tty); 674 } 675