aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/epca.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2009-01-02 08:48:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:41 -0500
commit6ed1dbaeadd62a026a93aa3ac8680d2dfe9f96b3 (patch)
treeaf470015e92b5abbc510935b61f953015addb58a /drivers/char/epca.c
parent3969ffba71d39ced700d09d9cfde83174396299e (diff)
tty: Make epca use the port helpers
Now the locking is straight and the port kref usage is straight we can replace lots of chunks of code with the standard port helpers Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/epca.c')
-rw-r--r--drivers/char/epca.c172
1 files changed, 24 insertions, 148 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);