Deleted Added
full compact
cy.c (61011) cy.c (65557)
1/*-
2 * cyclades cyclom-y serial driver
3 * Andrew Herbert <andrew@werple.apana.org.au>, 17 August 1993
4 *
5 * Copyright (c) 1993 Andrew Herbert.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 13 unchanged lines hidden (view full) ---

22 * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
1/*-
2 * cyclades cyclom-y serial driver
3 * Andrew Herbert <andrew@werple.apana.org.au>, 17 August 1993
4 *
5 * Copyright (c) 1993 Andrew Herbert.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 13 unchanged lines hidden (view full) ---

22 * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * $FreeBSD: head/sys/dev/cy/cy.c 61011 2000-05-28 13:40:48Z peter $
30 * $FreeBSD: head/sys/dev/cy/cy.c 65557 2000-09-07 01:33:02Z jasone $
31 */
32
33#include "opt_compat.h"
34#include "cy.h"
35
36/*
37 * TODO:
38 * Atomic COR change.

--- 50 unchanged lines hidden (view full) ---

89#include <i386/isa/isa_device.h>
90#include <i386/isa/cyreg.h>
91#include <i386/isa/ic/cd1400.h>
92
93#ifndef COMPAT_OLDISA
94#error "The cy device requires the old isa compatibility shims"
95#endif
96
31 */
32
33#include "opt_compat.h"
34#include "cy.h"
35
36/*
37 * TODO:
38 * Atomic COR change.

--- 50 unchanged lines hidden (view full) ---

89#include <i386/isa/isa_device.h>
90#include <i386/isa/cyreg.h>
91#include <i386/isa/ic/cd1400.h>
92
93#ifndef COMPAT_OLDISA
94#error "The cy device requires the old isa compatibility shims"
95#endif
96
97#ifdef SMP
98#define disable_intr() COM_DISABLE_INTR()
99#define enable_intr() COM_ENABLE_INTR()
100#endif /* SMP */
101
102/*
103 * Dictionary so that I can name everything *sio* or *com* to compare with
104 * sio.c. There is also lots of ugly formatting and unnecessary ifdefs to
105 * simplify the comparision. These will go away.
106 */
107#define LSR_BI CD1400_RDSR_BREAK
108#define LSR_FE CD1400_RDSR_FE
109#define LSR_OE CD1400_RDSR_OE

--- 251 unchanged lines hidden (view full) ---

361
362static char driver_name[] = "cy";
363
364/* table and macro for fast conversion from a unit number to its com struct */
365static struct com_s *p_com_addr[NSIO];
366#define com_addr(unit) (p_com_addr[unit])
367
368struct isa_driver siodriver = {
97/*
98 * Dictionary so that I can name everything *sio* or *com* to compare with
99 * sio.c. There is also lots of ugly formatting and unnecessary ifdefs to
100 * simplify the comparision. These will go away.
101 */
102#define LSR_BI CD1400_RDSR_BREAK
103#define LSR_FE CD1400_RDSR_FE
104#define LSR_OE CD1400_RDSR_OE

--- 251 unchanged lines hidden (view full) ---

356
357static char driver_name[] = "cy";
358
359/* table and macro for fast conversion from a unit number to its com struct */
360static struct com_s *p_com_addr[NSIO];
361#define com_addr(unit) (p_com_addr[unit])
362
363struct isa_driver siodriver = {
369 INTR_TYPE_TTY | INTR_TYPE_FAST,
364 INTR_TYPE_TTY | INTR_FAST,
370 sioprobe,
371 sioattach,
372 driver_name
373};
374COMPAT_ISA_DRIVER(cy, cydriver); /* XXX */
375
376static d_open_t sioopen;
377static d_close_t sioclose;

--- 221 unchanged lines hidden (view full) ---

599 if (unit == comconsole) {
600 com->it_in.c_iflag = TTYDEF_IFLAG;
601 com->it_in.c_oflag = TTYDEF_OFLAG;
602 com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL;
603 com->it_in.c_lflag = TTYDEF_LFLAG;
604 com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
605 }
606 if (siosetwater(com, com->it_in.c_ispeed) != 0) {
365 sioprobe,
366 sioattach,
367 driver_name
368};
369COMPAT_ISA_DRIVER(cy, cydriver); /* XXX */
370
371static d_open_t sioopen;
372static d_close_t sioclose;

--- 221 unchanged lines hidden (view full) ---

594 if (unit == comconsole) {
595 com->it_in.c_iflag = TTYDEF_IFLAG;
596 com->it_in.c_oflag = TTYDEF_OFLAG;
597 com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL;
598 com->it_in.c_lflag = TTYDEF_LFLAG;
599 com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
600 }
601 if (siosetwater(com, com->it_in.c_ispeed) != 0) {
607 enable_intr();
608 free(com, M_DEVBUF);
609 return (0);
610 }
602 free(com, M_DEVBUF);
603 return (0);
604 }
611 enable_intr();
612 termioschars(&com->it_in);
613 com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
614 com->it_out = com->it_in;
615
616 s = spltty();
617 com_addr(unit) = com;
618 splx(s);
619

--- 37 unchanged lines hidden (view full) ---

657 struct proc *p;
658{
659 struct com_s *com;
660 int error;
661 int mynor;
662 int s;
663 struct tty *tp;
664 int unit;
605 termioschars(&com->it_in);
606 com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
607 com->it_out = com->it_in;
608
609 s = spltty();
610 com_addr(unit) = com;
611 splx(s);
612

--- 37 unchanged lines hidden (view full) ---

650 struct proc *p;
651{
652 struct com_s *com;
653 int error;
654 int mynor;
655 int s;
656 struct tty *tp;
657 int unit;
658 int intrsave;
665
666 mynor = minor(dev);
667 unit = MINOR_TO_UNIT(mynor);
668 if ((u_int) unit >= NSIO || (com = com_addr(unit)) == NULL)
669 return (ENXIO);
670 if (mynor & CONTROL_MASK)
671 return (0);
672#if 0 /* XXX */

--- 90 unchanged lines hidden (view full) ---

763 if (!(inb(com->line_status_port) & LSR_RXRDY))
764 break;
765 outb(iobase + com_fifo, 0);
766 DELAY(100);
767 (void) inb(com->data_port);
768 }
769 }
770
659
660 mynor = minor(dev);
661 unit = MINOR_TO_UNIT(mynor);
662 if ((u_int) unit >= NSIO || (com = com_addr(unit)) == NULL)
663 return (ENXIO);
664 if (mynor & CONTROL_MASK)
665 return (0);
666#if 0 /* XXX */

--- 90 unchanged lines hidden (view full) ---

757 if (!(inb(com->line_status_port) & LSR_RXRDY))
758 break;
759 outb(iobase + com_fifo, 0);
760 DELAY(100);
761 (void) inb(com->data_port);
762 }
763 }
764
765 intrsave = save_intr();
771 disable_intr();
766 disable_intr();
767 COM_LOCK();
772 (void) inb(com->line_status_port);
773 (void) inb(com->data_port);
774 com->prev_modem_status = com->last_modem_status
775 = inb(com->modem_status_port);
776 outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS
777 | IER_EMSC);
768 (void) inb(com->line_status_port);
769 (void) inb(com->data_port);
770 com->prev_modem_status = com->last_modem_status
771 = inb(com->modem_status_port);
772 outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS
773 | IER_EMSC);
778 enable_intr();
774 COM_UNLOCK();
775 restore_intr(intrsave);
779#else /* !0 */
780 /*
781 * Flush fifos. This requires a full channel reset which
782 * also disables the transmitter and receiver. Recover
783 * from this.
784 */
785 cd1400_channel_cmd(com,
786 CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET);
787 cd1400_channel_cmd(com, com->channel_control);
788
776#else /* !0 */
777 /*
778 * Flush fifos. This requires a full channel reset which
779 * also disables the transmitter and receiver. Recover
780 * from this.
781 */
782 cd1400_channel_cmd(com,
783 CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET);
784 cd1400_channel_cmd(com, com->channel_control);
785
786 intrsave = save_intr();
789 disable_intr();
787 disable_intr();
788 COM_LOCK();
790 com->prev_modem_status = com->last_modem_status
791 = cd_getreg(com, CD1400_MSVR2);
792 cd_setreg(com, CD1400_SRER,
793 com->intr_enable
794 = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
789 com->prev_modem_status = com->last_modem_status
790 = cd_getreg(com, CD1400_MSVR2);
791 cd_setreg(com, CD1400_SRER,
792 com->intr_enable
793 = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
795 enable_intr();
794 COM_UNLOCK();
795 restore_intr(intrsave);
796#endif /* 0 */
797 /*
798 * Handle initial DCD. Callout devices get a fake initial
799 * DCD (trapdoor DCD). If we are callout, then any sleeping
800 * callin opens get woken up and resume sleeping on "cybi"
801 * instead of "cydcd".
802 */
803 /*

--- 66 unchanged lines hidden (view full) ---

870static void
871comhardclose(com)
872 struct com_s *com;
873{
874 cy_addr iobase;
875 int s;
876 struct tty *tp;
877 int unit;
796#endif /* 0 */
797 /*
798 * Handle initial DCD. Callout devices get a fake initial
799 * DCD (trapdoor DCD). If we are callout, then any sleeping
800 * callin opens get woken up and resume sleeping on "cybi"
801 * instead of "cydcd".
802 */
803 /*

--- 66 unchanged lines hidden (view full) ---

870static void
871comhardclose(com)
872 struct com_s *com;
873{
874 cy_addr iobase;
875 int s;
876 struct tty *tp;
877 int unit;
878 int intrsave;
878
879 unit = com->unit;
880 iobase = com->iobase;
881 s = spltty();
882#if 0
883 com->poll = FALSE;
884 com->poll_output = FALSE;
885#endif
886 com->do_timestamp = 0;
887#if 0
888 outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
889#else
890 /* XXX */
879
880 unit = com->unit;
881 iobase = com->iobase;
882 s = spltty();
883#if 0
884 com->poll = FALSE;
885 com->poll_output = FALSE;
886#endif
887 com->do_timestamp = 0;
888#if 0
889 outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
890#else
891 /* XXX */
892 intrsave = save_intr();
891 disable_intr();
893 disable_intr();
894 COM_LOCK();
892 com->etc = ETC_NONE;
893 cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC);
895 com->etc = ETC_NONE;
896 cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC);
894 enable_intr();
897 COM_UNLOCK();
898 restore_intr(intrsave);
895 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
896#endif
897
898 {
899#if 0
900 outb(iobase + com_ier, 0);
901#else
899 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
900#endif
901
902 {
903#if 0
904 outb(iobase + com_ier, 0);
905#else
906 intrsave = save_intr();
902 disable_intr();
907 disable_intr();
908 COM_LOCK();
903 cd_setreg(com, CD1400_SRER, com->intr_enable = 0);
909 cd_setreg(com, CD1400_SRER, com->intr_enable = 0);
904 enable_intr();
910 COM_UNLOCK();
911 restore_intr(intrsave);
905#endif
906 tp = com->tp;
907 if ((tp->t_cflag & HUPCL)
908 /*
909 * XXX we will miss any carrier drop between here and the
910 * next open. Perhaps we should watch DCD even when the
911 * port is closed; it is not sufficient to check it at
912 * the next open because it might go up and down while

--- 73 unchanged lines hidden (view full) ---

986{
987 struct com_s *com;
988
989 com = (struct com_s *)chan;
990 com->state &= ~CS_DTR_OFF;
991 wakeup(&com->dtr_wait);
992}
993
912#endif
913 tp = com->tp;
914 if ((tp->t_cflag & HUPCL)
915 /*
916 * XXX we will miss any carrier drop between here and the
917 * next open. Perhaps we should watch DCD even when the
918 * port is closed; it is not sufficient to check it at
919 * the next open because it might go up and down while

--- 73 unchanged lines hidden (view full) ---

993{
994 struct com_s *com;
995
996 com = (struct com_s *)chan;
997 com->state &= ~CS_DTR_OFF;
998 wakeup(&com->dtr_wait);
999}
1000
1001/*
1002 * This function:
1003 * a) needs to be called with COM_LOCK() held, and
1004 * b) needs to return with COM_LOCK() held.
1005 */
994static void
995sioinput(com)
996 struct com_s *com;
997{
998 u_char *buf;
999 int incc;
1000 u_char line_status;
1001 int recv_data;
1002 struct tty *tp;
1006static void
1007sioinput(com)
1008 struct com_s *com;
1009{
1010 u_char *buf;
1011 int incc;
1012 u_char line_status;
1013 int recv_data;
1014 struct tty *tp;
1015 int intrsave;
1003
1004 buf = com->ibuf;
1005 tp = com->tp;
1006 if (!(tp->t_state & TS_ISOPEN)) {
1007 com_events -= (com->iptr - com->ibuf);
1008 com->iptr = com->ibuf;
1009 return;
1010 }
1011 if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
1012 /*
1013 * Avoid the grotesquely inefficient lineswitch routine
1014 * (ttyinput) in "raw" mode. It usually takes about 450
1015 * instructions (that's without canonical processing or echo!).
1016 * slinput is reasonably fast (usually 40 instructions plus
1017 * call overhead).
1018 */
1016
1017 buf = com->ibuf;
1018 tp = com->tp;
1019 if (!(tp->t_state & TS_ISOPEN)) {
1020 com_events -= (com->iptr - com->ibuf);
1021 com->iptr = com->ibuf;
1022 return;
1023 }
1024 if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
1025 /*
1026 * Avoid the grotesquely inefficient lineswitch routine
1027 * (ttyinput) in "raw" mode. It usually takes about 450
1028 * instructions (that's without canonical processing or echo!).
1029 * slinput is reasonably fast (usually 40 instructions plus
1030 * call overhead).
1031 */
1032
1019 do {
1033 do {
1034 /*
1035 * This may look odd, but it is using save-and-enable
1036 * semantics instead of the save-and-disable semantics
1037 * that are used everywhere else.
1038 */
1039 intrsave = save_intr();
1040 COM_UNLOCK();
1020 enable_intr();
1021 incc = com->iptr - buf;
1022 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat
1023 && (com->state & CS_RTS_IFLOW
1024 || tp->t_iflag & IXOFF)
1025 && !(tp->t_state & TS_TBLOCK))
1026 ttyblock(tp);
1027 com->delta_error_counts[CE_TTY_BUF_OVERFLOW]

--- 5 unchanged lines hidden (view full) ---

1033 ttwakeup(tp);
1034 if (tp->t_state & TS_TTSTOP
1035 && (tp->t_iflag & IXANY
1036 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
1037 tp->t_state &= ~TS_TTSTOP;
1038 tp->t_lflag &= ~FLUSHO;
1039 comstart(tp);
1040 }
1041 enable_intr();
1042 incc = com->iptr - buf;
1043 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat
1044 && (com->state & CS_RTS_IFLOW
1045 || tp->t_iflag & IXOFF)
1046 && !(tp->t_state & TS_TBLOCK))
1047 ttyblock(tp);
1048 com->delta_error_counts[CE_TTY_BUF_OVERFLOW]

--- 5 unchanged lines hidden (view full) ---

1054 ttwakeup(tp);
1055 if (tp->t_state & TS_TTSTOP
1056 && (tp->t_iflag & IXANY
1057 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
1058 tp->t_state &= ~TS_TTSTOP;
1059 tp->t_lflag &= ~FLUSHO;
1060 comstart(tp);
1061 }
1041 disable_intr();
1062 restore_intr(intrsave);
1063 COM_LOCK();
1042 } while (buf < com->iptr);
1043 } else {
1044 do {
1064 } while (buf < com->iptr);
1065 } else {
1066 do {
1067 /*
1068 * This may look odd, but it is using save-and-enable
1069 * semantics instead of the save-and-disable semantics
1070 * that are used everywhere else.
1071 */
1072 intrsave = save_intr();
1073 COM_UNLOCK();
1045 enable_intr();
1046 line_status = buf[com->ierroff];
1047 recv_data = *buf++;
1048 if (line_status
1049 & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) {
1050 if (line_status & LSR_BI)
1051 recv_data |= TTY_BI;
1052 if (line_status & LSR_FE)
1053 recv_data |= TTY_FE;
1054 if (line_status & LSR_OE)
1055 recv_data |= TTY_OE;
1056 if (line_status & LSR_PE)
1057 recv_data |= TTY_PE;
1058 }
1059 (*linesw[tp->t_line].l_rint)(recv_data, tp);
1074 enable_intr();
1075 line_status = buf[com->ierroff];
1076 recv_data = *buf++;
1077 if (line_status
1078 & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) {
1079 if (line_status & LSR_BI)
1080 recv_data |= TTY_BI;
1081 if (line_status & LSR_FE)
1082 recv_data |= TTY_FE;
1083 if (line_status & LSR_OE)
1084 recv_data |= TTY_OE;
1085 if (line_status & LSR_PE)
1086 recv_data |= TTY_PE;
1087 }
1088 (*linesw[tp->t_line].l_rint)(recv_data, tp);
1060 disable_intr();
1089 restore_intr(intrsave);
1090 COM_LOCK();
1061 } while (buf < com->iptr);
1062 }
1063 com_events -= (com->iptr - com->ibuf);
1064 com->iptr = com->ibuf;
1065
1066 /*
1067 * There is now room for another low-level buffer full of input,
1068 * so enable RTS if it is now disabled and there is room in the

--- 655 unchanged lines hidden (view full) ---

1724 splx(s);
1725 return (0);
1726}
1727
1728static void
1729siopoll()
1730{
1731 int unit;
1091 } while (buf < com->iptr);
1092 }
1093 com_events -= (com->iptr - com->ibuf);
1094 com->iptr = com->ibuf;
1095
1096 /*
1097 * There is now room for another low-level buffer full of input,
1098 * so enable RTS if it is now disabled and there is room in the

--- 655 unchanged lines hidden (view full) ---

1754 splx(s);
1755 return (0);
1756}
1757
1758static void
1759siopoll()
1760{
1761 int unit;
1762 int intrsave;
1732
1733#ifdef CyDebug
1734 ++cy_timeouts;
1735#endif
1736 if (com_events == 0)
1737 return;
1738repeat:
1739 for (unit = 0; unit < NSIO; ++unit) {

--- 6 unchanged lines hidden (view full) ---

1746 continue;
1747 tp = com->tp;
1748 if (tp == NULL) {
1749 /*
1750 * XXX forget any events related to closed devices
1751 * (actually never opened devices) so that we don't
1752 * loop.
1753 */
1763
1764#ifdef CyDebug
1765 ++cy_timeouts;
1766#endif
1767 if (com_events == 0)
1768 return;
1769repeat:
1770 for (unit = 0; unit < NSIO; ++unit) {

--- 6 unchanged lines hidden (view full) ---

1777 continue;
1778 tp = com->tp;
1779 if (tp == NULL) {
1780 /*
1781 * XXX forget any events related to closed devices
1782 * (actually never opened devices) so that we don't
1783 * loop.
1784 */
1785 intrsave = save_intr();
1754 disable_intr();
1786 disable_intr();
1787 COM_LOCK();
1755 incc = com->iptr - com->ibuf;
1756 com->iptr = com->ibuf;
1757 if (com->state & CS_CHECKMSR) {
1758 incc += LOTS_OF_EVENTS;
1759 com->state &= ~CS_CHECKMSR;
1760 }
1761 com_events -= incc;
1788 incc = com->iptr - com->ibuf;
1789 com->iptr = com->ibuf;
1790 if (com->state & CS_CHECKMSR) {
1791 incc += LOTS_OF_EVENTS;
1792 com->state &= ~CS_CHECKMSR;
1793 }
1794 com_events -= incc;
1762 enable_intr();
1795 COM_UNLOCK();
1796 restore_intr(intrsave);
1763 if (incc != 0)
1764 log(LOG_DEBUG,
1765 "sio%d: %d events for device with no tp\n",
1766 unit, incc);
1767 continue;
1768 }
1769 if (com->iptr != com->ibuf) {
1797 if (incc != 0)
1798 log(LOG_DEBUG,
1799 "sio%d: %d events for device with no tp\n",
1800 unit, incc);
1801 continue;
1802 }
1803 if (com->iptr != com->ibuf) {
1804 intrsave = save_intr();
1770 disable_intr();
1805 disable_intr();
1806 COM_LOCK();
1771 sioinput(com);
1807 sioinput(com);
1772 enable_intr();
1808 COM_UNLOCK();
1809 restore_intr(intrsave);
1773 }
1774 if (com->state & CS_CHECKMSR) {
1775 u_char delta_modem_status;
1776
1810 }
1811 if (com->state & CS_CHECKMSR) {
1812 u_char delta_modem_status;
1813
1814 intrsave = save_intr();
1777 disable_intr();
1815 disable_intr();
1816 COM_LOCK();
1817 sioinput(com);
1778 delta_modem_status = com->last_modem_status
1779 ^ com->prev_modem_status;
1780 com->prev_modem_status = com->last_modem_status;
1781 com_events -= LOTS_OF_EVENTS;
1782 com->state &= ~CS_CHECKMSR;
1818 delta_modem_status = com->last_modem_status
1819 ^ com->prev_modem_status;
1820 com->prev_modem_status = com->last_modem_status;
1821 com_events -= LOTS_OF_EVENTS;
1822 com->state &= ~CS_CHECKMSR;
1783 enable_intr();
1823 COM_UNLOCK();
1824 restore_intr(intrsave);
1784 if (delta_modem_status & MSR_DCD)
1785 (*linesw[tp->t_line].l_modem)
1786 (tp, com->prev_modem_status & MSR_DCD);
1787 }
1788 if (com->extra_state & CSE_ODONE) {
1825 if (delta_modem_status & MSR_DCD)
1826 (*linesw[tp->t_line].l_modem)
1827 (tp, com->prev_modem_status & MSR_DCD);
1828 }
1829 if (com->extra_state & CSE_ODONE) {
1830 intrsave = save_intr();
1789 disable_intr();
1831 disable_intr();
1832 COM_LOCK();
1790 com_events -= LOTS_OF_EVENTS;
1791 com->extra_state &= ~CSE_ODONE;
1833 com_events -= LOTS_OF_EVENTS;
1834 com->extra_state &= ~CSE_ODONE;
1792 enable_intr();
1835 COM_UNLOCK();
1836 restore_intr(intrsave);
1793 if (!(com->state & CS_BUSY)) {
1794 tp->t_state &= ~TS_BUSY;
1795 ttwwakeup(com->tp);
1796 }
1797 if (com->etc != ETC_NONE) {
1798 if (com->etc == ETC_BREAK_ENDED)
1799 com->etc = ETC_NONE;
1800 wakeup(&com->etc);
1801 }
1802 }
1803 if (com->state & CS_ODONE) {
1837 if (!(com->state & CS_BUSY)) {
1838 tp->t_state &= ~TS_BUSY;
1839 ttwwakeup(com->tp);
1840 }
1841 if (com->etc != ETC_NONE) {
1842 if (com->etc == ETC_BREAK_ENDED)
1843 com->etc = ETC_NONE;
1844 wakeup(&com->etc);
1845 }
1846 }
1847 if (com->state & CS_ODONE) {
1848 intrsave = save_intr();
1804 disable_intr();
1849 disable_intr();
1850 COM_LOCK();
1805 com_events -= LOTS_OF_EVENTS;
1806 com->state &= ~CS_ODONE;
1851 com_events -= LOTS_OF_EVENTS;
1852 com->state &= ~CS_ODONE;
1807 enable_intr();
1853 COM_UNLOCK();
1854 restore_intr(intrsave);
1808 (*linesw[tp->t_line].l_start)(tp);
1809 }
1810 if (com_events == 0)
1811 break;
1812 }
1813 if (com_events >= LOTS_OF_EVENTS)
1814 goto repeat;
1815}

--- 12 unchanged lines hidden (view full) ---

1828 int iflag;
1829 int iprescaler;
1830 int itimeout;
1831 int odivisor;
1832 int oprescaler;
1833 u_char opt;
1834 int s;
1835 int unit;
1855 (*linesw[tp->t_line].l_start)(tp);
1856 }
1857 if (com_events == 0)
1858 break;
1859 }
1860 if (com_events >= LOTS_OF_EVENTS)
1861 goto repeat;
1862}

--- 12 unchanged lines hidden (view full) ---

1875 int iflag;
1876 int iprescaler;
1877 int itimeout;
1878 int odivisor;
1879 int oprescaler;
1880 u_char opt;
1881 int s;
1882 int unit;
1883 int intrsave;
1836
1837 /* do historical conversions */
1838 if (t->c_ispeed == 0)
1839 t->c_ispeed = t->c_ospeed;
1840
1841 unit = DEV_TO_UNIT(tp->t_dev);
1842 com = com_addr(unit);
1843

--- 8 unchanged lines hidden (view full) ---

1852
1853 /* parameters are OK, convert them to the com struct and the device */
1854 s = spltty();
1855 if (odivisor == 0)
1856 (void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */
1857 else
1858 (void)commctl(com, TIOCM_DTR, DMBIS);
1859
1884
1885 /* do historical conversions */
1886 if (t->c_ispeed == 0)
1887 t->c_ispeed = t->c_ospeed;
1888
1889 unit = DEV_TO_UNIT(tp->t_dev);
1890 com = com_addr(unit);
1891

--- 8 unchanged lines hidden (view full) ---

1900
1901 /* parameters are OK, convert them to the com struct and the device */
1902 s = spltty();
1903 if (odivisor == 0)
1904 (void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */
1905 else
1906 (void)commctl(com, TIOCM_DTR, DMBIS);
1907
1860 /*
1861 * This returns with interrupts disabled so that we can complete
1862 * the speed change atomically.
1863 */
1864 (void) siosetwater(com, t->c_ispeed);
1865
1866 /* XXX we don't actually change the speed atomically. */
1908 (void) siosetwater(com, t->c_ispeed);
1909
1910 /* XXX we don't actually change the speed atomically. */
1867 enable_intr();
1868
1869 if (idivisor != 0) {
1870 cd_setreg(com, CD1400_RBPR, idivisor);
1871 cd_setreg(com, CD1400_RCOR, iprescaler);
1872 }
1873 if (odivisor != 0) {
1874 cd_setreg(com, CD1400_TBPR, odivisor);
1875 cd_setreg(com, CD1400_TCOR, oprescaler);

--- 104 unchanged lines hidden (view full) ---

1980 opt |= CD1400_COR2_IXANY;
1981 if (iflag & IXOFF)
1982 opt |= CD1400_COR2_IXOFF;
1983#endif
1984#ifndef SOFT_CTS_OFLOW
1985 if (cflag & CCTS_OFLOW)
1986 opt |= CD1400_COR2_CCTS_OFLOW;
1987#endif
1911
1912 if (idivisor != 0) {
1913 cd_setreg(com, CD1400_RBPR, idivisor);
1914 cd_setreg(com, CD1400_RCOR, iprescaler);
1915 }
1916 if (odivisor != 0) {
1917 cd_setreg(com, CD1400_TBPR, odivisor);
1918 cd_setreg(com, CD1400_TCOR, oprescaler);

--- 104 unchanged lines hidden (view full) ---

2023 opt |= CD1400_COR2_IXANY;
2024 if (iflag & IXOFF)
2025 opt |= CD1400_COR2_IXOFF;
2026#endif
2027#ifndef SOFT_CTS_OFLOW
2028 if (cflag & CCTS_OFLOW)
2029 opt |= CD1400_COR2_CCTS_OFLOW;
2030#endif
2031 intrsave = save_intr();
1988 disable_intr();
2032 disable_intr();
2033 COM_LOCK();
1989 if (opt != com->cor[1]) {
1990 cor_change |= CD1400_CCR_COR2;
1991 cd_setreg(com, CD1400_COR2, com->cor[1] = opt);
1992 }
2034 if (opt != com->cor[1]) {
2035 cor_change |= CD1400_CCR_COR2;
2036 cd_setreg(com, CD1400_COR2, com->cor[1] = opt);
2037 }
1993 enable_intr();
2038 COM_UNLOCK();
2039 restore_intr(intrsave);
1994
1995 /*
1996 * set channel option register 3 -
1997 * receiver FIFO interrupt threshold
1998 * flow control
1999 */
2000 opt = RxFifoThreshold;
2001#ifdef Smarts

--- 104 unchanged lines hidden (view full) ---

2106 opt |= CD1400_MCOR2_CTSod;
2107#endif
2108 cd_setreg(com, CD1400_MCOR2, opt);
2109
2110 /*
2111 * XXX should have done this long ago, but there is too much state
2112 * to change all atomically.
2113 */
2040
2041 /*
2042 * set channel option register 3 -
2043 * receiver FIFO interrupt threshold
2044 * flow control
2045 */
2046 opt = RxFifoThreshold;
2047#ifdef Smarts

--- 104 unchanged lines hidden (view full) ---

2152 opt |= CD1400_MCOR2_CTSod;
2153#endif
2154 cd_setreg(com, CD1400_MCOR2, opt);
2155
2156 /*
2157 * XXX should have done this long ago, but there is too much state
2158 * to change all atomically.
2159 */
2160 intrsave = save_intr();
2114 disable_intr();
2161 disable_intr();
2162 COM_LOCK();
2115
2116 com->state &= ~CS_TTGO;
2117 if (!(tp->t_state & TS_TTSTOP))
2118 com->state |= CS_TTGO;
2119 if (cflag & CRTS_IFLOW) {
2120 com->state |= CS_RTS_IFLOW;
2121 /*
2122 * If CS_RTS_IFLOW just changed from off to on, the change

--- 49 unchanged lines hidden (view full) ---

2172 } else {
2173 if (com->intr_enable & CD1400_SRER_TXRDY)
2174 cd_setreg(com, CD1400_SRER,
2175 com->intr_enable
2176 = (com->intr_enable & ~CD1400_SRER_TXRDY)
2177 | CD1400_SRER_TXMPTY);
2178 }
2179
2163
2164 com->state &= ~CS_TTGO;
2165 if (!(tp->t_state & TS_TTSTOP))
2166 com->state |= CS_TTGO;
2167 if (cflag & CRTS_IFLOW) {
2168 com->state |= CS_RTS_IFLOW;
2169 /*
2170 * If CS_RTS_IFLOW just changed from off to on, the change

--- 49 unchanged lines hidden (view full) ---

2220 } else {
2221 if (com->intr_enable & CD1400_SRER_TXRDY)
2222 cd_setreg(com, CD1400_SRER,
2223 com->intr_enable
2224 = (com->intr_enable & ~CD1400_SRER_TXRDY)
2225 | CD1400_SRER_TXMPTY);
2226 }
2227
2180 enable_intr();
2228 COM_UNLOCK();
2229 restore_intr(intrsave);
2181 splx(s);
2182 comstart(tp);
2183 if (com->ibufold != NULL) {
2184 free(com->ibufold, M_DEVBUF);
2185 com->ibufold = NULL;
2186 }
2187 return (0);
2188}
2189
2190static int
2191siosetwater(com, speed)
2192 struct com_s *com;
2193 speed_t speed;
2194{
2195 int cp4ticks;
2196 u_char *ibuf;
2197 int ibufsize;
2198 struct tty *tp;
2230 splx(s);
2231 comstart(tp);
2232 if (com->ibufold != NULL) {
2233 free(com->ibufold, M_DEVBUF);
2234 com->ibufold = NULL;
2235 }
2236 return (0);
2237}
2238
2239static int
2240siosetwater(com, speed)
2241 struct com_s *com;
2242 speed_t speed;
2243{
2244 int cp4ticks;
2245 u_char *ibuf;
2246 int ibufsize;
2247 struct tty *tp;
2248 int intrsave;
2199
2200 /*
2201 * Make the buffer size large enough to handle a softtty interrupt
2202 * latency of about 2 ticks without loss of throughput or data
2203 * (about 3 ticks if input flow control is not used or not honoured,
2204 * but a bit less for CS5-CS7 modes).
2205 */
2206 cp4ticks = speed / 10 / hz * 4;
2207 for (ibufsize = 128; ibufsize < cp4ticks;)
2208 ibufsize <<= 1;
2209 if (ibufsize == com->ibufsize) {
2249
2250 /*
2251 * Make the buffer size large enough to handle a softtty interrupt
2252 * latency of about 2 ticks without loss of throughput or data
2253 * (about 3 ticks if input flow control is not used or not honoured,
2254 * but a bit less for CS5-CS7 modes).
2255 */
2256 cp4ticks = speed / 10 / hz * 4;
2257 for (ibufsize = 128; ibufsize < cp4ticks;)
2258 ibufsize <<= 1;
2259 if (ibufsize == com->ibufsize) {
2210 disable_intr();
2211 return (0);
2212 }
2213
2214 /*
2215 * Allocate input buffer. The extra factor of 2 in the size is
2216 * to allow for an error byte for each input byte.
2217 */
2218 ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT);
2219 if (ibuf == NULL) {
2260 return (0);
2261 }
2262
2263 /*
2264 * Allocate input buffer. The extra factor of 2 in the size is
2265 * to allow for an error byte for each input byte.
2266 */
2267 ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT);
2268 if (ibuf == NULL) {
2220 disable_intr();
2221 return (ENOMEM);
2222 }
2223
2224 /* Initialize non-critical variables. */
2225 com->ibufold = com->ibuf;
2226 com->ibufsize = ibufsize;
2227 tp = com->tp;
2228 if (tp != NULL) {
2229 tp->t_ififosize = 2 * ibufsize;
2230 tp->t_ispeedwat = (speed_t)-1;
2231 tp->t_ospeedwat = (speed_t)-1;
2232 }
2233
2234 /*
2235 * Read current input buffer, if any. Continue with interrupts
2236 * disabled.
2237 */
2269 return (ENOMEM);
2270 }
2271
2272 /* Initialize non-critical variables. */
2273 com->ibufold = com->ibuf;
2274 com->ibufsize = ibufsize;
2275 tp = com->tp;
2276 if (tp != NULL) {
2277 tp->t_ififosize = 2 * ibufsize;
2278 tp->t_ispeedwat = (speed_t)-1;
2279 tp->t_ospeedwat = (speed_t)-1;
2280 }
2281
2282 /*
2283 * Read current input buffer, if any. Continue with interrupts
2284 * disabled.
2285 */
2286 intrsave = save_intr();
2238 disable_intr();
2287 disable_intr();
2288 COM_LOCK();
2239 if (com->iptr != com->ibuf)
2240 sioinput(com);
2241
2242 /*-
2243 * Initialize critical variables, including input buffer watermarks.
2244 * The external device is asked to stop sending when the buffer
2245 * exactly reaches high water, or when the high level requests it.
2246 * The high level is notified immediately (rather than at a later
2247 * clock tick) when this watermark is reached.
2248 * The buffer size is chosen so the watermark should almost never
2249 * be reached.
2250 * The low watermark is invisibly 0 since the buffer is always
2251 * emptied all at once.
2252 */
2253 com->iptr = com->ibuf = ibuf;
2254 com->ibufend = ibuf + ibufsize;
2255 com->ierroff = ibufsize;
2256 com->ihighwater = ibuf + 3 * ibufsize / 4;
2289 if (com->iptr != com->ibuf)
2290 sioinput(com);
2291
2292 /*-
2293 * Initialize critical variables, including input buffer watermarks.
2294 * The external device is asked to stop sending when the buffer
2295 * exactly reaches high water, or when the high level requests it.
2296 * The high level is notified immediately (rather than at a later
2297 * clock tick) when this watermark is reached.
2298 * The buffer size is chosen so the watermark should almost never
2299 * be reached.
2300 * The low watermark is invisibly 0 since the buffer is always
2301 * emptied all at once.
2302 */
2303 com->iptr = com->ibuf = ibuf;
2304 com->ibufend = ibuf + ibufsize;
2305 com->ierroff = ibufsize;
2306 com->ihighwater = ibuf + 3 * ibufsize / 4;
2307
2308 COM_UNLOCK();
2309 restore_intr(intrsave);
2257 return (0);
2258}
2259
2260static void
2261comstart(tp)
2262 struct tty *tp;
2263{
2264 struct com_s *com;
2265 int s;
2266#ifdef CyDebug
2267 bool_t started;
2268#endif
2269 int unit;
2310 return (0);
2311}
2312
2313static void
2314comstart(tp)
2315 struct tty *tp;
2316{
2317 struct com_s *com;
2318 int s;
2319#ifdef CyDebug
2320 bool_t started;
2321#endif
2322 int unit;
2323 int intrsave;
2270
2271 unit = DEV_TO_UNIT(tp->t_dev);
2272 com = com_addr(unit);
2273 s = spltty();
2274
2275#ifdef CyDebug
2276 ++com->start_count;
2277 started = FALSE;
2278#endif
2279
2324
2325 unit = DEV_TO_UNIT(tp->t_dev);
2326 com = com_addr(unit);
2327 s = spltty();
2328
2329#ifdef CyDebug
2330 ++com->start_count;
2331 started = FALSE;
2332#endif
2333
2334 intrsave = save_intr();
2280 disable_intr();
2335 disable_intr();
2336 COM_LOCK();
2281 if (tp->t_state & TS_TTSTOP) {
2282 com->state &= ~CS_TTGO;
2283 if (com->intr_enable & CD1400_SRER_TXRDY)
2284 cd_setreg(com, CD1400_SRER,
2285 com->intr_enable
2286 = (com->intr_enable & ~CD1400_SRER_TXRDY)
2287 | CD1400_SRER_TXMPTY);
2288 } else {

--- 19 unchanged lines hidden (view full) ---

2308 && com->state & CS_RTS_IFLOW)
2309#if 0
2310 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
2311#else
2312 cd_setreg(com, com->mcr_rts_reg,
2313 com->mcr_image |= com->mcr_rts);
2314#endif
2315 }
2337 if (tp->t_state & TS_TTSTOP) {
2338 com->state &= ~CS_TTGO;
2339 if (com->intr_enable & CD1400_SRER_TXRDY)
2340 cd_setreg(com, CD1400_SRER,
2341 com->intr_enable
2342 = (com->intr_enable & ~CD1400_SRER_TXRDY)
2343 | CD1400_SRER_TXMPTY);
2344 } else {

--- 19 unchanged lines hidden (view full) ---

2364 && com->state & CS_RTS_IFLOW)
2365#if 0
2366 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
2367#else
2368 cd_setreg(com, com->mcr_rts_reg,
2369 com->mcr_image |= com->mcr_rts);
2370#endif
2371 }
2316 enable_intr();
2372 COM_UNLOCK();
2373 restore_intr(intrsave);
2317 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
2318 ttwwakeup(tp);
2319 splx(s);
2320 return;
2321 }
2322 if (tp->t_outq.c_cc != 0) {
2323 struct lbq *qp;
2324 struct lbq *next;
2325
2326 if (!com->obufs[0].l_queued) {
2327#ifdef CyDebug
2328 started = TRUE;
2329#endif
2330 com->obufs[0].l_tail
2331 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1,
2332 sizeof com->obuf1);
2333 com->obufs[0].l_next = NULL;
2334 com->obufs[0].l_queued = TRUE;
2374 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
2375 ttwwakeup(tp);
2376 splx(s);
2377 return;
2378 }
2379 if (tp->t_outq.c_cc != 0) {
2380 struct lbq *qp;
2381 struct lbq *next;
2382
2383 if (!com->obufs[0].l_queued) {
2384#ifdef CyDebug
2385 started = TRUE;
2386#endif
2387 com->obufs[0].l_tail
2388 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1,
2389 sizeof com->obuf1);
2390 com->obufs[0].l_next = NULL;
2391 com->obufs[0].l_queued = TRUE;
2392 intrsave = save_intr();
2335 disable_intr();
2393 disable_intr();
2394 COM_LOCK();
2336 if (com->state & CS_BUSY) {
2337 qp = com->obufq.l_next;
2338 while ((next = qp->l_next) != NULL)
2339 qp = next;
2340 qp->l_next = &com->obufs[0];
2341 } else {
2342 com->obufq.l_head = com->obufs[0].l_head;
2343 com->obufq.l_tail = com->obufs[0].l_tail;
2344 com->obufq.l_next = &com->obufs[0];
2345 com->state |= CS_BUSY;
2346 if (com->state >= (CS_BUSY | CS_TTGO
2347 | CS_ODEVREADY))
2348 cd_setreg(com, CD1400_SRER,
2349 com->intr_enable
2350 = (com->intr_enable
2351 & ~CD1400_SRER_TXMPTY)
2352 | CD1400_SRER_TXRDY);
2353 }
2395 if (com->state & CS_BUSY) {
2396 qp = com->obufq.l_next;
2397 while ((next = qp->l_next) != NULL)
2398 qp = next;
2399 qp->l_next = &com->obufs[0];
2400 } else {
2401 com->obufq.l_head = com->obufs[0].l_head;
2402 com->obufq.l_tail = com->obufs[0].l_tail;
2403 com->obufq.l_next = &com->obufs[0];
2404 com->state |= CS_BUSY;
2405 if (com->state >= (CS_BUSY | CS_TTGO
2406 | CS_ODEVREADY))
2407 cd_setreg(com, CD1400_SRER,
2408 com->intr_enable
2409 = (com->intr_enable
2410 & ~CD1400_SRER_TXMPTY)
2411 | CD1400_SRER_TXRDY);
2412 }
2354 enable_intr();
2413 COM_UNLOCK();
2414 restore_intr(intrsave);
2355 }
2356 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) {
2357#ifdef CyDebug
2358 started = TRUE;
2359#endif
2360 com->obufs[1].l_tail
2361 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2,
2362 sizeof com->obuf2);
2363 com->obufs[1].l_next = NULL;
2364 com->obufs[1].l_queued = TRUE;
2415 }
2416 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) {
2417#ifdef CyDebug
2418 started = TRUE;
2419#endif
2420 com->obufs[1].l_tail
2421 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2,
2422 sizeof com->obuf2);
2423 com->obufs[1].l_next = NULL;
2424 com->obufs[1].l_queued = TRUE;
2425 intrsave = save_intr();
2365 disable_intr();
2426 disable_intr();
2427 COM_LOCK();
2366 if (com->state & CS_BUSY) {
2367 qp = com->obufq.l_next;
2368 while ((next = qp->l_next) != NULL)
2369 qp = next;
2370 qp->l_next = &com->obufs[1];
2371 } else {
2372 com->obufq.l_head = com->obufs[1].l_head;
2373 com->obufq.l_tail = com->obufs[1].l_tail;
2374 com->obufq.l_next = &com->obufs[1];
2375 com->state |= CS_BUSY;
2376 if (com->state >= (CS_BUSY | CS_TTGO
2377 | CS_ODEVREADY))
2378 cd_setreg(com, CD1400_SRER,
2379 com->intr_enable
2380 = (com->intr_enable
2381 & ~CD1400_SRER_TXMPTY)
2382 | CD1400_SRER_TXRDY);
2383 }
2428 if (com->state & CS_BUSY) {
2429 qp = com->obufq.l_next;
2430 while ((next = qp->l_next) != NULL)
2431 qp = next;
2432 qp->l_next = &com->obufs[1];
2433 } else {
2434 com->obufq.l_head = com->obufs[1].l_head;
2435 com->obufq.l_tail = com->obufs[1].l_tail;
2436 com->obufq.l_next = &com->obufs[1];
2437 com->state |= CS_BUSY;
2438 if (com->state >= (CS_BUSY | CS_TTGO
2439 | CS_ODEVREADY))
2440 cd_setreg(com, CD1400_SRER,
2441 com->intr_enable
2442 = (com->intr_enable
2443 & ~CD1400_SRER_TXMPTY)
2444 | CD1400_SRER_TXRDY);
2445 }
2384 enable_intr();
2446 COM_UNLOCK();
2447 restore_intr(intrsave);
2385 }
2386 tp->t_state |= TS_BUSY;
2387 }
2388#ifdef CyDebug
2389 if (started)
2390 ++com->start_real;
2391#endif
2392#if 0
2448 }
2449 tp->t_state |= TS_BUSY;
2450 }
2451#ifdef CyDebug
2452 if (started)
2453 ++com->start_real;
2454#endif
2455#if 0
2456 intrsave = save_intr();
2393 disable_intr();
2457 disable_intr();
2458 COM_LOCK();
2394 if (com->state >= (CS_BUSY | CS_TTGO))
2395 siointr1(com); /* fake interrupt to start output */
2459 if (com->state >= (CS_BUSY | CS_TTGO))
2460 siointr1(com); /* fake interrupt to start output */
2396 enable_intr();
2461 COM_UNLOCK();
2462 restore_intr(intrsave);
2397#endif
2398 ttwwakeup(tp);
2399 splx(s);
2400}
2401
2402static void
2403comstop(tp, rw)
2404 struct tty *tp;
2405 int rw;
2406{
2407 struct com_s *com;
2408 bool_t wakeup_etc;
2463#endif
2464 ttwwakeup(tp);
2465 splx(s);
2466}
2467
2468static void
2469comstop(tp, rw)
2470 struct tty *tp;
2471 int rw;
2472{
2473 struct com_s *com;
2474 bool_t wakeup_etc;
2475 int intrsave;
2409
2410 com = com_addr(DEV_TO_UNIT(tp->t_dev));
2411 wakeup_etc = FALSE;
2476
2477 com = com_addr(DEV_TO_UNIT(tp->t_dev));
2478 wakeup_etc = FALSE;
2479 intrsave = save_intr();
2412 disable_intr();
2480 disable_intr();
2481 COM_LOCK();
2413 if (rw & FWRITE) {
2414 com->obufs[0].l_queued = FALSE;
2415 com->obufs[1].l_queued = FALSE;
2416 if (com->extra_state & CSE_ODONE) {
2417 com_events -= LOTS_OF_EVENTS;
2418 com->extra_state &= ~CSE_ODONE;
2419 if (com->etc != ETC_NONE) {
2420 if (com->etc == ETC_BREAK_ENDED)

--- 6 unchanged lines hidden (view full) ---

2427 com_events -= LOTS_OF_EVENTS;
2428 com->state &= ~(CS_ODONE | CS_BUSY);
2429 }
2430 if (rw & FREAD) {
2431 /* XXX no way to reset only input fifo. */
2432 com_events -= (com->iptr - com->ibuf);
2433 com->iptr = com->ibuf;
2434 }
2482 if (rw & FWRITE) {
2483 com->obufs[0].l_queued = FALSE;
2484 com->obufs[1].l_queued = FALSE;
2485 if (com->extra_state & CSE_ODONE) {
2486 com_events -= LOTS_OF_EVENTS;
2487 com->extra_state &= ~CSE_ODONE;
2488 if (com->etc != ETC_NONE) {
2489 if (com->etc == ETC_BREAK_ENDED)

--- 6 unchanged lines hidden (view full) ---

2496 com_events -= LOTS_OF_EVENTS;
2497 com->state &= ~(CS_ODONE | CS_BUSY);
2498 }
2499 if (rw & FREAD) {
2500 /* XXX no way to reset only input fifo. */
2501 com_events -= (com->iptr - com->ibuf);
2502 com->iptr = com->ibuf;
2503 }
2435 enable_intr();
2504 COM_UNLOCK();
2505 restore_intr(intrsave);
2436 if (wakeup_etc)
2437 wakeup(&com->etc);
2438 if (rw & FWRITE && com->etc == ETC_NONE)
2439 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
2440 comstart(tp);
2441}
2442
2443static int
2444commctl(com, bits, how)
2445 struct com_s *com;
2446 int bits;
2447 int how;
2448{
2449 int mcr;
2450 int msr;
2506 if (wakeup_etc)
2507 wakeup(&com->etc);
2508 if (rw & FWRITE && com->etc == ETC_NONE)
2509 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
2510 comstart(tp);
2511}
2512
2513static int
2514commctl(com, bits, how)
2515 struct com_s *com;
2516 int bits;
2517 int how;
2518{
2519 int mcr;
2520 int msr;
2521 int intrsave;
2451
2452 if (how == DMGET) {
2453 if (com->channel_control & CD1400_CCR_RCVEN)
2454 bits |= TIOCM_LE;
2455 mcr = com->mcr_image;
2456 if (mcr & com->mcr_dtr)
2457 bits |= TIOCM_DTR;
2458 if (mcr & com->mcr_rts)

--- 21 unchanged lines hidden (view full) ---

2480 bits |= TIOCM_RI;
2481 return (bits);
2482 }
2483 mcr = 0;
2484 if (bits & TIOCM_DTR)
2485 mcr |= com->mcr_dtr;
2486 if (bits & TIOCM_RTS)
2487 mcr |= com->mcr_rts;
2522
2523 if (how == DMGET) {
2524 if (com->channel_control & CD1400_CCR_RCVEN)
2525 bits |= TIOCM_LE;
2526 mcr = com->mcr_image;
2527 if (mcr & com->mcr_dtr)
2528 bits |= TIOCM_DTR;
2529 if (mcr & com->mcr_rts)

--- 21 unchanged lines hidden (view full) ---

2551 bits |= TIOCM_RI;
2552 return (bits);
2553 }
2554 mcr = 0;
2555 if (bits & TIOCM_DTR)
2556 mcr |= com->mcr_dtr;
2557 if (bits & TIOCM_RTS)
2558 mcr |= com->mcr_rts;
2559 intrsave = save_intr();
2488 disable_intr();
2560 disable_intr();
2561 COM_LOCK();
2489 switch (how) {
2490 case DMSET:
2491 com->mcr_image = mcr;
2492 cd_setreg(com, CD1400_MSVR1, mcr);
2493 cd_setreg(com, CD1400_MSVR2, mcr);
2494 break;
2495 case DMBIS:
2496 com->mcr_image = mcr = com->mcr_image | mcr;
2497 cd_setreg(com, CD1400_MSVR1, mcr);
2498 cd_setreg(com, CD1400_MSVR2, mcr);
2499 break;
2500 case DMBIC:
2501 com->mcr_image = mcr = com->mcr_image & ~mcr;
2502 cd_setreg(com, CD1400_MSVR1, mcr);
2503 cd_setreg(com, CD1400_MSVR2, mcr);
2504 break;
2505 }
2562 switch (how) {
2563 case DMSET:
2564 com->mcr_image = mcr;
2565 cd_setreg(com, CD1400_MSVR1, mcr);
2566 cd_setreg(com, CD1400_MSVR2, mcr);
2567 break;
2568 case DMBIS:
2569 com->mcr_image = mcr = com->mcr_image | mcr;
2570 cd_setreg(com, CD1400_MSVR1, mcr);
2571 cd_setreg(com, CD1400_MSVR2, mcr);
2572 break;
2573 case DMBIC:
2574 com->mcr_image = mcr = com->mcr_image & ~mcr;
2575 cd_setreg(com, CD1400_MSVR1, mcr);
2576 cd_setreg(com, CD1400_MSVR2, mcr);
2577 break;
2578 }
2506 enable_intr();
2579 COM_UNLOCK();
2580 restore_intr(intrsave);
2507 return (0);
2508}
2509
2510static void
2511siosettimeout()
2512{
2513 struct com_s *com;
2514 bool_t someopen;

--- 45 unchanged lines hidden (view full) ---

2560 /*
2561 * Recover from lost output interrupts.
2562 * Poll any lines that don't use interrupts.
2563 */
2564 for (unit = 0; unit < NSIO; ++unit) {
2565 com = com_addr(unit);
2566 if (com != NULL
2567 && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) {
2581 return (0);
2582}
2583
2584static void
2585siosettimeout()
2586{
2587 struct com_s *com;
2588 bool_t someopen;

--- 45 unchanged lines hidden (view full) ---

2634 /*
2635 * Recover from lost output interrupts.
2636 * Poll any lines that don't use interrupts.
2637 */
2638 for (unit = 0; unit < NSIO; ++unit) {
2639 com = com_addr(unit);
2640 if (com != NULL
2641 && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) {
2642 int intrsave;
2643
2644 intrsave = save_intr();
2568 disable_intr();
2645 disable_intr();
2646 COM_LOCK();
2569 siointr1(com);
2647 siointr1(com);
2570 enable_intr();
2648 COM_UNLOCK();
2649 restore_intr(intrsave);
2571 }
2572 }
2573#endif
2574
2575 /*
2576 * Check for and log errors, but not too often.
2577 */
2578 if (--sio_timeouts_until_log > 0)
2579 return;
2580 sio_timeouts_until_log = hz / sio_timeout;
2581 for (unit = 0; unit < NSIO; ++unit) {
2582 int errnum;
2583
2584 com = com_addr(unit);
2585 if (com == NULL)
2586 continue;
2587 for (errnum = 0; errnum < CE_NTYPES; ++errnum) {
2588 u_int delta;
2589 u_long total;
2650 }
2651 }
2652#endif
2653
2654 /*
2655 * Check for and log errors, but not too often.
2656 */
2657 if (--sio_timeouts_until_log > 0)
2658 return;
2659 sio_timeouts_until_log = hz / sio_timeout;
2660 for (unit = 0; unit < NSIO; ++unit) {
2661 int errnum;
2662
2663 com = com_addr(unit);
2664 if (com == NULL)
2665 continue;
2666 for (errnum = 0; errnum < CE_NTYPES; ++errnum) {
2667 u_int delta;
2668 u_long total;
2669 int intrsave;
2590
2670
2671 intrsave = save_intr();
2591 disable_intr();
2672 disable_intr();
2673 COM_LOCK();
2592 delta = com->delta_error_counts[errnum];
2593 com->delta_error_counts[errnum] = 0;
2674 delta = com->delta_error_counts[errnum];
2675 com->delta_error_counts[errnum] = 0;
2594 enable_intr();
2676 COM_UNLOCK();
2677 restore_intr(intrsave);
2595 if (delta == 0)
2596 continue;
2597 total = com->error_counts[errnum] += delta;
2598 log(LOG_ERR, "cy%d: %u more %s%s (total %lu)\n",
2599 unit, delta, error_desc[errnum],
2600 delta == 1 ? "" : "s", total);
2601 }
2602 }

--- 135 unchanged lines hidden (view full) ---

2738 }
2739}
2740
2741static void
2742cd_etc(com, etc)
2743 struct com_s *com;
2744 int etc;
2745{
2678 if (delta == 0)
2679 continue;
2680 total = com->error_counts[errnum] += delta;
2681 log(LOG_ERR, "cy%d: %u more %s%s (total %lu)\n",
2682 unit, delta, error_desc[errnum],
2683 delta == 1 ? "" : "s", total);
2684 }
2685 }

--- 135 unchanged lines hidden (view full) ---

2821 }
2822}
2823
2824static void
2825cd_etc(com, etc)
2826 struct com_s *com;
2827 int etc;
2828{
2829 int intrsave;
2830
2746 /*
2747 * We can't change the hardware's ETC state while there are any
2748 * characters in the tx fifo, since those characters would be
2749 * interpreted as commands! Unputting characters from the fifo
2750 * is difficult, so we wait up to 12 character times for the fifo
2751 * to drain. The command will be delayed for up to 2 character
2752 * times for the tx to become empty. Unputting characters from
2753 * the tx holding and shift registers is impossible, so we wait
2754 * for the tx to become empty so that the command is sure to be
2755 * executed soon after we issue it.
2756 */
2831 /*
2832 * We can't change the hardware's ETC state while there are any
2833 * characters in the tx fifo, since those characters would be
2834 * interpreted as commands! Unputting characters from the fifo
2835 * is difficult, so we wait up to 12 character times for the fifo
2836 * to drain. The command will be delayed for up to 2 character
2837 * times for the tx to become empty. Unputting characters from
2838 * the tx holding and shift registers is impossible, so we wait
2839 * for the tx to become empty so that the command is sure to be
2840 * executed soon after we issue it.
2841 */
2842 intrsave = save_intr();
2757 disable_intr();
2843 disable_intr();
2758 if (com->etc == etc) {
2759 enable_intr();
2844 COM_LOCK();
2845 if (com->etc == etc)
2760 goto wait;
2846 goto wait;
2761 }
2762 if ((etc == CD1400_ETC_SENDBREAK
2763 && (com->etc == ETC_BREAK_STARTING
2764 || com->etc == ETC_BREAK_STARTED))
2765 || (etc == CD1400_ETC_STOPBREAK
2766 && (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED
2767 || com->etc == ETC_NONE))) {
2847 if ((etc == CD1400_ETC_SENDBREAK
2848 && (com->etc == ETC_BREAK_STARTING
2849 || com->etc == ETC_BREAK_STARTED))
2850 || (etc == CD1400_ETC_STOPBREAK
2851 && (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED
2852 || com->etc == ETC_NONE))) {
2768 enable_intr();
2853 COM_UNLOCK();
2854 restore_intr(intrsave);
2769 return;
2770 }
2771 com->etc = etc;
2772 cd_setreg(com, CD1400_SRER,
2773 com->intr_enable
2774 = (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY);
2855 return;
2856 }
2857 com->etc = etc;
2858 cd_setreg(com, CD1400_SRER,
2859 com->intr_enable
2860 = (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY);
2775 enable_intr();
2776wait:
2861wait:
2862 COM_UNLOCK();
2863 restore_intr(intrsave);
2777 while (com->etc == etc
2778 && tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0)
2779 continue;
2780}
2781
2782static int
2783cd_getreg(com, reg)
2784 struct com_s *com;
2785 int reg;
2786{
2787 struct com_s *basecom;
2788 u_char car;
2789 int cy_align;
2864 while (com->etc == etc
2865 && tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0)
2866 continue;
2867}
2868
2869static int
2870cd_getreg(com, reg)
2871 struct com_s *com;
2872 int reg;
2873{
2874 struct com_s *basecom;
2875 u_char car;
2876 int cy_align;
2790 u_long ef;
2877 int intrsave;
2791 cy_addr iobase;
2792 int val;
2793
2794 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
2795 car = com->unit & CD1400_CAR_CHAN;
2796 cy_align = com->cy_align;
2797 iobase = com->iobase;
2878 cy_addr iobase;
2879 int val;
2880
2881 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
2882 car = com->unit & CD1400_CAR_CHAN;
2883 cy_align = com->cy_align;
2884 iobase = com->iobase;
2798 ef = read_eflags();
2799 if (ef & PSL_I)
2800 disable_intr();
2885 intrsave = save_intr();
2886 disable_intr();
2887 if (intrsave & PSL_I)
2888 COM_LOCK();
2801 if (basecom->car != car)
2802 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
2803 val = cd_inb(iobase, reg, cy_align);
2889 if (basecom->car != car)
2890 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
2891 val = cd_inb(iobase, reg, cy_align);
2804 if (ef & PSL_I)
2805 enable_intr();
2892 if (intrsave & PSL_I)
2893 COM_UNLOCK();
2894 restore_intr(intrsave);
2806 return (val);
2807}
2808
2809static void
2810cd_setreg(com, reg, val)
2811 struct com_s *com;
2812 int reg;
2813 int val;
2814{
2815 struct com_s *basecom;
2816 u_char car;
2817 int cy_align;
2895 return (val);
2896}
2897
2898static void
2899cd_setreg(com, reg, val)
2900 struct com_s *com;
2901 int reg;
2902 int val;
2903{
2904 struct com_s *basecom;
2905 u_char car;
2906 int cy_align;
2818 u_long ef;
2907 int intrsave;
2819 cy_addr iobase;
2820
2821 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
2822 car = com->unit & CD1400_CAR_CHAN;
2823 cy_align = com->cy_align;
2824 iobase = com->iobase;
2908 cy_addr iobase;
2909
2910 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
2911 car = com->unit & CD1400_CAR_CHAN;
2912 cy_align = com->cy_align;
2913 iobase = com->iobase;
2825 ef = read_eflags();
2826 if (ef & PSL_I)
2827 disable_intr();
2914 intrsave = save_intr();
2915 disable_intr();
2916 if (intrsave & PSL_I)
2917 COM_LOCK();
2828 if (basecom->car != car)
2829 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
2830 cd_outb(iobase, reg, cy_align, val);
2918 if (basecom->car != car)
2919 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
2920 cd_outb(iobase, reg, cy_align, val);
2831 if (ef & PSL_I)
2832 enable_intr();
2921 if (intrsave & PSL_I)
2922 COM_UNLOCK();
2923 restore_intr(intrsave);
2833}
2834
2835#ifdef CyDebug
2836/* useful in ddb */
2837void
2838cystatus(unit)
2839 int unit;
2840{

--- 54 unchanged lines hidden ---
2924}
2925
2926#ifdef CyDebug
2927/* useful in ddb */
2928void
2929cystatus(unit)
2930 int unit;
2931{

--- 54 unchanged lines hidden ---