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