diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/stallion.c | 116 |
1 files changed, 35 insertions, 81 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index b4ba5edea33d..0e511d61f544 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -702,6 +702,24 @@ static struct stlbrd *stl_allocbrd(void) | |||
702 | 702 | ||
703 | /*****************************************************************************/ | 703 | /*****************************************************************************/ |
704 | 704 | ||
705 | static int stl_activate(struct tty_port *port, struct tty_struct *tty) | ||
706 | { | ||
707 | struct stlport *portp = container_of(port, struct stlport, port); | ||
708 | if (!portp->tx.buf) { | ||
709 | portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); | ||
710 | if (!portp->tx.buf) | ||
711 | return -ENOMEM; | ||
712 | portp->tx.head = portp->tx.buf; | ||
713 | portp->tx.tail = portp->tx.buf; | ||
714 | } | ||
715 | stl_setport(portp, tty->termios); | ||
716 | portp->sigs = stl_getsignals(portp); | ||
717 | stl_setsignals(portp, 1, 1); | ||
718 | stl_enablerxtx(portp, 1, 1); | ||
719 | stl_startrxtx(portp, 1, 0); | ||
720 | return 0; | ||
721 | } | ||
722 | |||
705 | static int stl_open(struct tty_struct *tty, struct file *filp) | 723 | static int stl_open(struct tty_struct *tty, struct file *filp) |
706 | { | 724 | { |
707 | struct stlport *portp; | 725 | struct stlport *portp; |
@@ -737,32 +755,8 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
737 | if (portp == NULL) | 755 | if (portp == NULL) |
738 | return -ENODEV; | 756 | return -ENODEV; |
739 | port = &portp->port; | 757 | port = &portp->port; |
758 | return tty_port_open(&portp->port, tty, filp); | ||
740 | 759 | ||
741 | /* | ||
742 | * On the first open of the device setup the port hardware, and | ||
743 | * initialize the per port data structure. | ||
744 | */ | ||
745 | tty_port_tty_set(port, tty); | ||
746 | tty->driver_data = portp; | ||
747 | port->count++; | ||
748 | |||
749 | if ((port->flags & ASYNC_INITIALIZED) == 0) { | ||
750 | if (!portp->tx.buf) { | ||
751 | portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); | ||
752 | if (!portp->tx.buf) | ||
753 | return -ENOMEM; | ||
754 | portp->tx.head = portp->tx.buf; | ||
755 | portp->tx.tail = portp->tx.buf; | ||
756 | } | ||
757 | stl_setport(portp, tty->termios); | ||
758 | portp->sigs = stl_getsignals(portp); | ||
759 | stl_setsignals(portp, 1, 1); | ||
760 | stl_enablerxtx(portp, 1, 1); | ||
761 | stl_startrxtx(portp, 1, 0); | ||
762 | clear_bit(TTY_IO_ERROR, &tty->flags); | ||
763 | port->flags |= ASYNC_INITIALIZED; | ||
764 | } | ||
765 | return tty_port_block_til_ready(port, tty, filp); | ||
766 | } | 760 | } |
767 | 761 | ||
768 | /*****************************************************************************/ | 762 | /*****************************************************************************/ |
@@ -826,38 +820,12 @@ static void stl_waituntilsent(struct tty_struct *tty, int timeout) | |||
826 | 820 | ||
827 | /*****************************************************************************/ | 821 | /*****************************************************************************/ |
828 | 822 | ||
829 | static void stl_close(struct tty_struct *tty, struct file *filp) | 823 | static void stl_shutdown(struct tty_port *port) |
830 | { | 824 | { |
831 | struct stlport *portp; | 825 | struct stlport *portp = container_of(port, struct stlport, port); |
832 | struct tty_port *port; | ||
833 | unsigned long flags; | ||
834 | |||
835 | pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); | ||
836 | |||
837 | portp = tty->driver_data; | ||
838 | BUG_ON(portp == NULL); | ||
839 | |||
840 | port = &portp->port; | ||
841 | |||
842 | if (tty_port_close_start(port, tty, filp) == 0) | ||
843 | return; | ||
844 | /* | ||
845 | * May want to wait for any data to drain before closing. The BUSY | ||
846 | * flag keeps track of whether we are still sending or not - it is | ||
847 | * very accurate for the cd1400, not quite so for the sc26198. | ||
848 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) | ||
849 | */ | ||
850 | stl_waituntilsent(tty, (HZ / 2)); | ||
851 | |||
852 | spin_lock_irqsave(&port->lock, flags); | ||
853 | portp->port.flags &= ~ASYNC_INITIALIZED; | ||
854 | spin_unlock_irqrestore(&port->lock, flags); | ||
855 | |||
856 | stl_disableintrs(portp); | 826 | stl_disableintrs(portp); |
857 | if (tty->termios->c_cflag & HUPCL) | ||
858 | stl_setsignals(portp, 0, 0); | ||
859 | stl_enablerxtx(portp, 0, 0); | 827 | stl_enablerxtx(portp, 0, 0); |
860 | stl_flushbuffer(tty); | 828 | stl_flush(portp); |
861 | portp->istate = 0; | 829 | portp->istate = 0; |
862 | if (portp->tx.buf != NULL) { | 830 | if (portp->tx.buf != NULL) { |
863 | kfree(portp->tx.buf); | 831 | kfree(portp->tx.buf); |
@@ -865,9 +833,16 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
865 | portp->tx.head = NULL; | 833 | portp->tx.head = NULL; |
866 | portp->tx.tail = NULL; | 834 | portp->tx.tail = NULL; |
867 | } | 835 | } |
836 | } | ||
837 | |||
838 | static void stl_close(struct tty_struct *tty, struct file *filp) | ||
839 | { | ||
840 | struct stlport*portp; | ||
841 | pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); | ||
868 | 842 | ||
869 | tty_port_close_end(port, tty); | 843 | portp = tty->driver_data; |
870 | tty_port_tty_set(port, NULL); | 844 | BUG_ON(portp == NULL); |
845 | tty_port_close(&portp->port, tty, filp); | ||
871 | } | 846 | } |
872 | 847 | ||
873 | /*****************************************************************************/ | 848 | /*****************************************************************************/ |
@@ -1314,35 +1289,12 @@ static void stl_stop(struct tty_struct *tty) | |||
1314 | 1289 | ||
1315 | static void stl_hangup(struct tty_struct *tty) | 1290 | static void stl_hangup(struct tty_struct *tty) |
1316 | { | 1291 | { |
1317 | struct stlport *portp; | 1292 | struct stlport *portp = tty->driver_data; |
1318 | struct tty_port *port; | ||
1319 | unsigned long flags; | ||
1320 | |||
1321 | pr_debug("stl_hangup(tty=%p)\n", tty); | 1293 | pr_debug("stl_hangup(tty=%p)\n", tty); |
1322 | 1294 | ||
1323 | portp = tty->driver_data; | ||
1324 | if (portp == NULL) | 1295 | if (portp == NULL) |
1325 | return; | 1296 | return; |
1326 | port = &portp->port; | 1297 | tty_port_hangup(&portp->port); |
1327 | |||
1328 | spin_lock_irqsave(&port->lock, flags); | ||
1329 | port->flags &= ~ASYNC_INITIALIZED; | ||
1330 | spin_unlock_irqrestore(&port->lock, flags); | ||
1331 | |||
1332 | stl_disableintrs(portp); | ||
1333 | if (tty->termios->c_cflag & HUPCL) | ||
1334 | stl_setsignals(portp, 0, 0); | ||
1335 | stl_enablerxtx(portp, 0, 0); | ||
1336 | stl_flushbuffer(tty); | ||
1337 | portp->istate = 0; | ||
1338 | set_bit(TTY_IO_ERROR, &tty->flags); | ||
1339 | if (portp->tx.buf != NULL) { | ||
1340 | kfree(portp->tx.buf); | ||
1341 | portp->tx.buf = NULL; | ||
1342 | portp->tx.head = NULL; | ||
1343 | portp->tx.tail = NULL; | ||
1344 | } | ||
1345 | tty_port_hangup(port); | ||
1346 | } | 1298 | } |
1347 | 1299 | ||
1348 | /*****************************************************************************/ | 1300 | /*****************************************************************************/ |
@@ -2550,6 +2502,8 @@ static const struct tty_operations stl_ops = { | |||
2550 | static const struct tty_port_operations stl_port_ops = { | 2502 | static const struct tty_port_operations stl_port_ops = { |
2551 | .carrier_raised = stl_carrier_raised, | 2503 | .carrier_raised = stl_carrier_raised, |
2552 | .dtr_rts = stl_dtr_rts, | 2504 | .dtr_rts = stl_dtr_rts, |
2505 | .activate = stl_activate, | ||
2506 | .shutdown = stl_shutdown, | ||
2553 | }; | 2507 | }; |
2554 | 2508 | ||
2555 | /*****************************************************************************/ | 2509 | /*****************************************************************************/ |