line.c (c45bb8cb72136bf23d18926113bff04c8cc90813) | line.c (6aad04f21374633bd8cecf25024553d1e11a9522) |
---|---|
1/* 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 * Licensed under the GPL 4 */ 5 6#include <linux/irqreturn.h> 7#include <linux/kd.h> 8#include <linux/sched.h> --- 234 unchanged lines hidden (view full) --- 243 if (!line->throttled) 244 reactivate_chan(line->chan_in, line->driver->read_irq); 245} 246 247static irqreturn_t line_write_interrupt(int irq, void *data) 248{ 249 struct chan *chan = data; 250 struct line *line = chan->line; | 1/* 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 * Licensed under the GPL 4 */ 5 6#include <linux/irqreturn.h> 7#include <linux/kd.h> 8#include <linux/sched.h> --- 234 unchanged lines hidden (view full) --- 243 if (!line->throttled) 244 reactivate_chan(line->chan_in, line->driver->read_irq); 245} 246 247static irqreturn_t line_write_interrupt(int irq, void *data) 248{ 249 struct chan *chan = data; 250 struct line *line = chan->line; |
251 struct tty_struct *tty; | |
252 int err; 253 254 /* 255 * Interrupts are disabled here because genirq keep irqs disabled when 256 * calling the action handler. 257 */ 258 259 spin_lock(&line->lock); 260 err = flush_buffer(line); 261 if (err == 0) { 262 spin_unlock(&line->lock); 263 return IRQ_NONE; 264 } else if (err < 0) { 265 line->head = line->buffer; 266 line->tail = line->buffer; 267 } 268 spin_unlock(&line->lock); 269 | 251 int err; 252 253 /* 254 * Interrupts are disabled here because genirq keep irqs disabled when 255 * calling the action handler. 256 */ 257 258 spin_lock(&line->lock); 259 err = flush_buffer(line); 260 if (err == 0) { 261 spin_unlock(&line->lock); 262 return IRQ_NONE; 263 } else if (err < 0) { 264 line->head = line->buffer; 265 line->tail = line->buffer; 266 } 267 spin_unlock(&line->lock); 268 |
270 tty = tty_port_tty_get(&line->port); 271 if (tty == NULL) 272 return IRQ_NONE; | 269 tty_port_tty_wakeup(&line->port); |
273 | 270 |
274 tty_wakeup(tty); 275 tty_kref_put(tty); 276 | |
277 return IRQ_HANDLED; 278} 279 280int line_setup_irq(int fd, int input, int output, struct line *line, void *data) 281{ 282 const struct line_driver *driver = line->driver; 283 int err = 0; 284 --- 15 unchanged lines hidden (view full) --- 300 int ret; 301 struct line *line = tty->driver_data; 302 303 ret = enable_chan(line); 304 if (ret) 305 return ret; 306 307 if (!line->sigio) { | 271 return IRQ_HANDLED; 272} 273 274int line_setup_irq(int fd, int input, int output, struct line *line, void *data) 275{ 276 const struct line_driver *driver = line->driver; 277 int err = 0; 278 --- 15 unchanged lines hidden (view full) --- 294 int ret; 295 struct line *line = tty->driver_data; 296 297 ret = enable_chan(line); 298 if (ret) 299 return ret; 300 301 if (!line->sigio) { |
308 chan_enable_winch(line->chan_out, port); | 302 chan_enable_winch(line->chan_out, tty); |
309 line->sigio = 1; 310 } 311 312 chan_window_size(line, &tty->winsize.ws_row, 313 &tty->winsize.ws_col); 314 315 return 0; 316} 317 | 303 line->sigio = 1; 304 } 305 306 chan_window_size(line, &tty->winsize.ws_row, 307 &tty->winsize.ws_col); 308 309 return 0; 310} 311 |
318static void unregister_winch(struct tty_struct *tty); 319 320static void line_destruct(struct tty_port *port) 321{ 322 struct tty_struct *tty = tty_port_tty_get(port); 323 struct line *line = tty->driver_data; 324 325 if (line->sigio) { 326 unregister_winch(tty); 327 line->sigio = 0; 328 } 329} 330 | |
331static const struct tty_port_operations line_port_ops = { 332 .activate = line_activate, | 312static const struct tty_port_operations line_port_ops = { 313 .activate = line_activate, |
333 .destruct = line_destruct, | |
334}; 335 336int line_open(struct tty_struct *tty, struct file *filp) 337{ 338 struct line *line = tty->driver_data; 339 340 return tty_port_open(&line->port, tty, filp); 341} --- 7 unchanged lines hidden (view full) --- 349 if (ret) 350 return ret; 351 352 tty->driver_data = line; 353 354 return 0; 355} 356 | 314}; 315 316int line_open(struct tty_struct *tty, struct file *filp) 317{ 318 struct line *line = tty->driver_data; 319 320 return tty_port_open(&line->port, tty, filp); 321} --- 7 unchanged lines hidden (view full) --- 329 if (ret) 330 return ret; 331 332 tty->driver_data = line; 333 334 return 0; 335} 336 |
337static void unregister_winch(struct tty_struct *tty); 338 339void line_cleanup(struct tty_struct *tty) 340{ 341 struct line *line = tty->driver_data; 342 343 if (line->sigio) { 344 unregister_winch(tty); 345 line->sigio = 0; 346 } 347} 348 |
|
357void line_close(struct tty_struct *tty, struct file * filp) 358{ 359 struct line *line = tty->driver_data; 360 361 tty_port_close(&line->port, tty, filp); 362} 363 364void line_hangup(struct tty_struct *tty) --- 233 unchanged lines hidden (view full) --- 598static DEFINE_SPINLOCK(winch_handler_lock); 599static LIST_HEAD(winch_handlers); 600 601struct winch { 602 struct list_head list; 603 int fd; 604 int tty_fd; 605 int pid; | 349void line_close(struct tty_struct *tty, struct file * filp) 350{ 351 struct line *line = tty->driver_data; 352 353 tty_port_close(&line->port, tty, filp); 354} 355 356void line_hangup(struct tty_struct *tty) --- 233 unchanged lines hidden (view full) --- 590static DEFINE_SPINLOCK(winch_handler_lock); 591static LIST_HEAD(winch_handlers); 592 593struct winch { 594 struct list_head list; 595 int fd; 596 int tty_fd; 597 int pid; |
606 struct tty_port *port; | 598 struct tty_struct *tty; |
607 unsigned long stack; 608 struct work_struct work; 609}; 610 611static void __free_winch(struct work_struct *work) 612{ 613 struct winch *winch = container_of(work, struct winch, work); 614 um_free_irq(WINCH_IRQ, winch); --- 37 unchanged lines hidden (view full) --- 652 "support\n", winch->tty_fd); 653 INIT_WORK(&winch->work, __free_winch); 654 schedule_work(&winch->work); 655 return IRQ_HANDLED; 656 } 657 goto out; 658 } 659 } | 599 unsigned long stack; 600 struct work_struct work; 601}; 602 603static void __free_winch(struct work_struct *work) 604{ 605 struct winch *winch = container_of(work, struct winch, work); 606 um_free_irq(WINCH_IRQ, winch); --- 37 unchanged lines hidden (view full) --- 644 "support\n", winch->tty_fd); 645 INIT_WORK(&winch->work, __free_winch); 646 schedule_work(&winch->work); 647 return IRQ_HANDLED; 648 } 649 goto out; 650 } 651 } |
660 tty = tty_port_tty_get(winch->port); | 652 tty = winch->tty; |
661 if (tty != NULL) { 662 line = tty->driver_data; 663 if (line != NULL) { 664 chan_window_size(line, &tty->winsize.ws_row, 665 &tty->winsize.ws_col); 666 kill_pgrp(tty->pgrp, SIGWINCH, 1); 667 } | 653 if (tty != NULL) { 654 line = tty->driver_data; 655 if (line != NULL) { 656 chan_window_size(line, &tty->winsize.ws_row, 657 &tty->winsize.ws_col); 658 kill_pgrp(tty->pgrp, SIGWINCH, 1); 659 } |
668 tty_kref_put(tty); | |
669 } 670 out: 671 if (winch->fd != -1) 672 reactivate_fd(winch->fd, WINCH_IRQ); 673 return IRQ_HANDLED; 674} 675 | 660 } 661 out: 662 if (winch->fd != -1) 663 reactivate_fd(winch->fd, WINCH_IRQ); 664 return IRQ_HANDLED; 665} 666 |
676void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port, | 667void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, |
677 unsigned long stack) 678{ 679 struct winch *winch; 680 681 winch = kmalloc(sizeof(*winch), GFP_KERNEL); 682 if (winch == NULL) { 683 printk(KERN_ERR "register_winch_irq - kmalloc failed\n"); 684 goto cleanup; 685 } 686 687 *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list), 688 .fd = fd, 689 .tty_fd = tty_fd, 690 .pid = pid, | 668 unsigned long stack) 669{ 670 struct winch *winch; 671 672 winch = kmalloc(sizeof(*winch), GFP_KERNEL); 673 if (winch == NULL) { 674 printk(KERN_ERR "register_winch_irq - kmalloc failed\n"); 675 goto cleanup; 676 } 677 678 *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list), 679 .fd = fd, 680 .tty_fd = tty_fd, 681 .pid = pid, |
691 .port = port, | 682 .tty = tty, |
692 .stack = stack }); 693 694 if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 695 IRQF_SHARED, "winch", winch) < 0) { 696 printk(KERN_ERR "register_winch_irq - failed to register " 697 "IRQ\n"); 698 goto out_free; 699 } --- 12 unchanged lines hidden (view full) --- 712 if (stack != 0) 713 free_stack(stack, 0); 714} 715 716static void unregister_winch(struct tty_struct *tty) 717{ 718 struct list_head *ele, *next; 719 struct winch *winch; | 683 .stack = stack }); 684 685 if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 686 IRQF_SHARED, "winch", winch) < 0) { 687 printk(KERN_ERR "register_winch_irq - failed to register " 688 "IRQ\n"); 689 goto out_free; 690 } --- 12 unchanged lines hidden (view full) --- 703 if (stack != 0) 704 free_stack(stack, 0); 705} 706 707static void unregister_winch(struct tty_struct *tty) 708{ 709 struct list_head *ele, *next; 710 struct winch *winch; |
720 struct tty_struct *wtty; | |
721 722 spin_lock(&winch_handler_lock); 723 724 list_for_each_safe(ele, next, &winch_handlers) { 725 winch = list_entry(ele, struct winch, list); | 711 712 spin_lock(&winch_handler_lock); 713 714 list_for_each_safe(ele, next, &winch_handlers) { 715 winch = list_entry(ele, struct winch, list); |
726 wtty = tty_port_tty_get(winch->port); 727 if (wtty == tty) { | 716 if (winch->tty == tty) { |
728 free_winch(winch); 729 break; 730 } | 717 free_winch(winch); 718 break; 719 } |
731 tty_kref_put(wtty); | |
732 } 733 spin_unlock(&winch_handler_lock); 734} 735 736static void winch_cleanup(void) 737{ 738 struct list_head *ele, *next; 739 struct winch *winch; --- 31 unchanged lines hidden --- | 720 } 721 spin_unlock(&winch_handler_lock); 722} 723 724static void winch_cleanup(void) 725{ 726 struct list_head *ele, *next; 727 struct winch *winch; --- 31 unchanged lines hidden --- |