aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/epca.c172
-rw-r--r--drivers/char/tty_port.c3
2 files changed, 26 insertions, 149 deletions
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 7a697055e4f6..71225d1af9ee 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -432,58 +432,15 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
432 return; 432 return;
433 port = &ch->port; 433 port = &ch->port;
434 434
435 spin_lock_irqsave(&port->lock, flags); 435 if (tty_port_close_start(port, tty, filp) == 0)
436 if (tty_hung_up_p(filp)) {
437 spin_unlock_irqrestore(&port->lock, flags);
438 return;
439 }
440 if (port->count-- > 1) {
441 /* Begin channel is open more than once */
442 /*
443 * Return without doing anything. Someone might still
444 * be using the channel.
445 */
446 spin_unlock_irqrestore(&port->lock, flags);
447 return; 436 return;
448 }
449 /* Port open only once go ahead with shutdown & reset */
450 WARN_ON(port->count < 0);
451 437
452 /*
453 * Let the rest of the driver know the channel is being closed.
454 * This becomes important if an open is attempted before close
455 * is finished.
456 */
457 port->flags |= ASYNC_CLOSING;
458 tty->closing = 1;
459
460 spin_unlock_irqrestore(&port->lock, flags);
461
462 if (port->flags & ASYNC_INITIALIZED) {
463 /* Setup an event to indicate when the
464 transmit buffer empties */
465 setup_empty_event(tty, ch);
466 /* 30 seconds timeout */
467 tty_wait_until_sent(tty, 3000);
468 }
469 pc_flush_buffer(tty); 438 pc_flush_buffer(tty);
470 tty_ldisc_flush(tty);
471 shutdown(ch, tty); 439 shutdown(ch, tty);
472 440
473 spin_lock_irqsave(&port->lock, flags); 441 tty_port_close_end(port, tty);
474 tty->closing = 0; 442 ch->event = 0; /* FIXME: review ch->event locking */
475 ch->event = 0;
476 tty_port_tty_set(port, NULL); 443 tty_port_tty_set(port, NULL);
477 spin_unlock_irqrestore(&port->lock, flags);
478
479 if (port->blocked_open) {
480 if (ch->close_delay)
481 msleep_interruptible(jiffies_to_msecs(ch->close_delay));
482 wake_up_interruptible(&port->open_wait);
483 }
484 port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED |
485 ASYNC_CLOSING);
486 wake_up_interruptible(&port->close_wait);
487} 444}
488 445
489static void shutdown(struct channel *ch, struct tty_struct *tty) 446static void shutdown(struct channel *ch, struct tty_struct *tty)
@@ -527,7 +484,6 @@ static void shutdown(struct channel *ch, struct tty_struct *tty)
527static void pc_hangup(struct tty_struct *tty) 484static void pc_hangup(struct tty_struct *tty)
528{ 485{
529 struct channel *ch; 486 struct channel *ch;
530 struct tty_port *port;
531 487
532 /* 488 /*
533 * verifyChannel returns the channel from the tty struct if it is 489 * verifyChannel returns the channel from the tty struct if it is
@@ -536,19 +492,13 @@ static void pc_hangup(struct tty_struct *tty)
536 ch = verifyChannel(tty); 492 ch = verifyChannel(tty);
537 if (ch != NULL) { 493 if (ch != NULL) {
538 unsigned long flags; 494 unsigned long flags;
539 port = &ch->port;
540 495
541 pc_flush_buffer(tty); 496 pc_flush_buffer(tty);
542 tty_ldisc_flush(tty); 497 tty_ldisc_flush(tty);
543 shutdown(ch, tty); 498 shutdown(ch, tty);
544 499
545 spin_lock_irqsave(&port->lock, flags);
546 port->tty = NULL;
547 ch->event = 0; /* FIXME: review locking of ch->event */ 500 ch->event = 0; /* FIXME: review locking of ch->event */
548 port->count = 0; 501 tty_port_hangup(&ch->port);
549 port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED);
550 spin_unlock_irqrestore(&port->lock, flags);
551 wake_up_interruptible(&port->open_wait);
552 } 502 }
553} 503}
554 504
@@ -792,98 +742,18 @@ static void pc_flush_chars(struct tty_struct *tty)
792 } 742 }
793} 743}
794 744
795static int block_til_ready(struct tty_struct *tty, 745static int epca_carrier_raised(struct tty_port *port)
796 struct file *filp, struct channel *ch)
797{ 746{
798 DECLARE_WAITQUEUE(wait, current); 747 struct channel *ch = container_of(port, struct channel, port);
799 int retval, do_clocal = 0; 748 if (ch->imodem & ch->dcd)
800 unsigned long flags; 749 return 1;
801 struct tty_port *port = &ch->port;
802
803 if (tty_hung_up_p(filp)) {
804 if (port->flags & ASYNC_HUP_NOTIFY)
805 retval = -EAGAIN;
806 else
807 retval = -ERESTARTSYS;
808 return retval;
809 }
810
811 /*
812 * If the device is in the middle of being closed, then block until
813 * it's done, and then try again.
814 */
815 if (port->flags & ASYNC_CLOSING) {
816 interruptible_sleep_on(&port->close_wait);
817
818 if (port->flags & ASYNC_HUP_NOTIFY)
819 return -EAGAIN;
820 else
821 return -ERESTARTSYS;
822 }
823
824 if (filp->f_flags & O_NONBLOCK) {
825 /*
826 * If non-blocking mode is set, then make the check up front
827 * and then exit.
828 */
829 port->flags |= ASYNC_NORMAL_ACTIVE;
830 return 0;
831 }
832 if (tty->termios->c_cflag & CLOCAL)
833 do_clocal = 1;
834 /* Block waiting for the carrier detect and the line to become free */
835
836 retval = 0;
837 add_wait_queue(&port->open_wait, &wait);
838
839 spin_lock_irqsave(&port->lock, flags);
840 /* We dec count so that pc_close will know when to free things */
841 if (!tty_hung_up_p(filp))
842 port->count--;
843 port->blocked_open++;
844 while (1) {
845 set_current_state(TASK_INTERRUPTIBLE);
846 if (tty_hung_up_p(filp) ||
847 !(port->flags & ASYNC_INITIALIZED)) {
848 if (port->flags & ASYNC_HUP_NOTIFY)
849 retval = -EAGAIN;
850 else
851 retval = -ERESTARTSYS;
852 break;
853 }
854 if (!(port->flags & ASYNC_CLOSING) &&
855 (do_clocal || (ch->imodem & ch->dcd)))
856 break;
857 if (signal_pending(current)) {
858 retval = -ERESTARTSYS;
859 break;
860 }
861 spin_unlock_irqrestore(&port->lock, flags);
862 /*
863 * Allow someone else to be scheduled. We will occasionally go
864 * through this loop until one of the above conditions change.
865 * The below schedule call will allow other processes to enter
866 * and prevent this loop from hogging the cpu.
867 */
868 schedule();
869 spin_lock_irqsave(&port->lock, flags);
870 }
871
872 __set_current_state(TASK_RUNNING);
873 remove_wait_queue(&port->open_wait, &wait);
874 if (!tty_hung_up_p(filp))
875 port->count++;
876 port->blocked_open--;
877
878 spin_unlock_irqrestore(&port->lock, flags);
879
880 if (retval)
881 return retval;
882
883 port->flags |= ASYNC_NORMAL_ACTIVE;
884 return 0; 750 return 0;
885} 751}
886 752
753static void epca_raise_dtr_rts(struct tty_port *port0
754{
755}
756
887static int pc_open(struct tty_struct *tty, struct file *filp) 757static int pc_open(struct tty_struct *tty, struct file *filp)
888{ 758{
889 struct channel *ch; 759 struct channel *ch;
@@ -978,7 +848,7 @@ static int pc_open(struct tty_struct *tty, struct file *filp)
978 port->flags |= ASYNC_INITIALIZED; 848 port->flags |= ASYNC_INITIALIZED;
979 spin_unlock_irqrestore(&port->lock, flags); 849 spin_unlock_irqrestore(&port->lock, flags);
980 850
981 retval = block_til_ready(tty, filp, ch); 851 retval = tty_port_block_til_ready(port, tty, filp);
982 if (retval) 852 if (retval)
983 return retval; 853 return retval;
984 /* 854 /*
@@ -1058,6 +928,11 @@ static const struct tty_operations pc_ops = {
1058 .break_ctl = pc_send_break 928 .break_ctl = pc_send_break
1059}; 929};
1060 930
931static const struct tty_port_operations epca_port_ops = {
932 .carrier_raised = epca_carrier_raised,
933 .raise_dtr_rts = epca_raise_dtr_rts,
934};
935
1061static int info_open(struct tty_struct *tty, struct file *filp) 936static int info_open(struct tty_struct *tty, struct file *filp)
1062{ 937{
1063 return 0; 938 return 0;
@@ -1393,6 +1268,7 @@ static void post_fep_init(unsigned int crd)
1393 u16 tseg, rseg; 1268 u16 tseg, rseg;
1394 1269
1395 tty_port_init(&ch->port); 1270 tty_port_init(&ch->port);
1271 ch->port.ops - &epca_port_ops;
1396 ch->brdchan = bc; 1272 ch->brdchan = bc;
1397 ch->mailbox = gd; 1273 ch->mailbox = gd;
1398 INIT_WORK(&ch->tqueue, do_softint); 1274 INIT_WORK(&ch->tqueue, do_softint);
@@ -1526,7 +1402,7 @@ static void post_fep_init(unsigned int crd)
1526 ch->fepstartca = 0; 1402 ch->fepstartca = 0;
1527 ch->fepstopca = 0; 1403 ch->fepstopca = 0;
1528 1404
1529 ch->close_delay = 50; 1405 ch->port.close_delay = 50;
1530 1406
1531 spin_unlock_irqrestore(&epca_lock, flags); 1407 spin_unlock_irqrestore(&epca_lock, flags);
1532 } 1408 }
@@ -1647,7 +1523,7 @@ static void doevent(int crd)
1647 if (event & MODEMCHG_IND) { 1523 if (event & MODEMCHG_IND) {
1648 /* A modem signal change has been indicated */ 1524 /* A modem signal change has been indicated */
1649 ch->imodem = mstat; 1525 ch->imodem = mstat;
1650 if (ch->port.flags & ASYNC_CHECK_CD) { 1526 if (test_bit(ASYNC_CHECK_CD, &ch->port.flags)) {
1651 /* We are now receiving dcd */ 1527 /* We are now receiving dcd */
1652 if (mstat & ch->dcd) 1528 if (mstat & ch->dcd)
1653 wake_up_interruptible(&ch->port.open_wait); 1529 wake_up_interruptible(&ch->port.open_wait);
@@ -1894,9 +1770,9 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
1894 * that the driver will wait on carrier detect. 1770 * that the driver will wait on carrier detect.
1895 */ 1771 */
1896 if (ts->c_cflag & CLOCAL) 1772 if (ts->c_cflag & CLOCAL)
1897 ch->port.flags &= ~ASYNC_CHECK_CD; 1773 clear_bit(ASYNC_CHECK_CD, &ch->port.flags);
1898 else 1774 else
1899 ch->port.flags |= ASYNC_CHECK_CD; 1775 set_bit(ASYNC_CHECK_CD, &ch->port.flags);
1900 mval = ch->m_dtr | ch->m_rts; 1776 mval = ch->m_dtr | ch->m_rts;
1901 } /* End CBAUD not detected */ 1777 } /* End CBAUD not detected */
1902 iflag = termios2digi_i(ch, ts->c_iflag); 1778 iflag = termios2digi_i(ch, ts->c_iflag);
@@ -2373,7 +2249,7 @@ static void do_softint(struct work_struct *work)
2373 if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) { 2249 if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
2374 tty_hangup(tty); 2250 tty_hangup(tty);
2375 wake_up_interruptible(&ch->port.open_wait); 2251 wake_up_interruptible(&ch->port.open_wait);
2376 ch->port.flags &= ~ASYNC_NORMAL_ACTIVE; 2252 clear_bit(ASYNC_NORMAL_ACTIVE, &ch->port.flags);
2377 } 2253 }
2378 } 2254 }
2379 tty_kref_put(tty); 2255 tty_kref_put(tty);
diff --git a/drivers/char/tty_port.c b/drivers/char/tty_port.c
index b3175f54fe05..b580fcf629f8 100644
--- a/drivers/char/tty_port.c
+++ b/drivers/char/tty_port.c
@@ -286,7 +286,8 @@ int tty_port_close_start(struct tty_port *port, struct tty_struct *tty, struct f
286 port->flags |= ASYNC_CLOSING; 286 port->flags |= ASYNC_CLOSING;
287 tty->closing = 1; 287 tty->closing = 1;
288 spin_unlock_irqrestore(&port->lock, flags); 288 spin_unlock_irqrestore(&port->lock, flags);
289 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) 289 if (port->flags & ASYNC_INITIALIZED &&
290 port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
290 tty_wait_until_sent(tty, port->closing_wait); 291 tty_wait_until_sent(tty, port->closing_wait);
291 return 1; 292 return 1;
292} 293}