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 ---