Deleted Added
full compact
cy.c (74810) cy.c (74903)
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 74810 2001-03-26 12:41:29Z phk $
30 * $FreeBSD: head/sys/dev/cy/cy.c 74903 2001-03-28 03:06:10Z jhb $
31 */
32
33#include "opt_compat.h"
34#include "cy.h"
35
36/*
37 * TODO:
38 * Atomic COR change.

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

345static int sioattach __P((struct isa_device *dev));
346static void cd1400_channel_cmd __P((struct com_s *com, int cmd));
347static void cd1400_channel_cmd_wait __P((struct com_s *com));
348static void cd_etc __P((struct com_s *com, int etc));
349static int cd_getreg __P((struct com_s *com, int reg));
350static void cd_setreg __P((struct com_s *com, int reg, int val));
351static timeout_t siodtrwakeup;
352static void comhardclose __P((struct com_s *com));
31 */
32
33#include "opt_compat.h"
34#include "cy.h"
35
36/*
37 * TODO:
38 * Atomic COR change.

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

345static int sioattach __P((struct isa_device *dev));
346static void cd1400_channel_cmd __P((struct com_s *com, int cmd));
347static void cd1400_channel_cmd_wait __P((struct com_s *com));
348static void cd_etc __P((struct com_s *com, int etc));
349static int cd_getreg __P((struct com_s *com, int reg));
350static void cd_setreg __P((struct com_s *com, int reg, int val));
351static timeout_t siodtrwakeup;
352static void comhardclose __P((struct com_s *com));
353static void sioinput __P((struct com_s *com));
353static void sioinput __P((struct com_s *com, critical_t *savecrit));
354#if 0
355static void siointr1 __P((struct com_s *com));
356#endif
357static int commctl __P((struct com_s *com, int bits, int how));
358static int comparam __P((struct tty *tp, struct termios *t));
359static void siopoll __P((void *arg));
360static int sioprobe __P((struct isa_device *dev));
361static void siosettimeout __P((void));

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

667 struct proc *p;
668{
669 struct com_s *com;
670 int error;
671 int mynor;
672 int s;
673 struct tty *tp;
674 int unit;
354#if 0
355static void siointr1 __P((struct com_s *com));
356#endif
357static int commctl __P((struct com_s *com, int bits, int how));
358static int comparam __P((struct tty *tp, struct termios *t));
359static void siopoll __P((void *arg));
360static int sioprobe __P((struct isa_device *dev));
361static void siosettimeout __P((void));

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

667 struct proc *p;
668{
669 struct com_s *com;
670 int error;
671 int mynor;
672 int s;
673 struct tty *tp;
674 int unit;
675 int intrsave;
675 critical_t savecrit;
676
677 mynor = minor(dev);
678 unit = MINOR_TO_UNIT(mynor);
679 if ((u_int) unit >= NSIO || (com = com_addr(unit)) == NULL)
680 return (ENXIO);
681 if (mynor & CONTROL_MASK)
682 return (0);
683#if 0 /* XXX */

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

774 if (!(inb(com->line_status_port) & LSR_RXRDY))
775 break;
776 outb(iobase + com_fifo, 0);
777 DELAY(100);
778 (void) inb(com->data_port);
779 }
780 }
781
676
677 mynor = minor(dev);
678 unit = MINOR_TO_UNIT(mynor);
679 if ((u_int) unit >= NSIO || (com = com_addr(unit)) == NULL)
680 return (ENXIO);
681 if (mynor & CONTROL_MASK)
682 return (0);
683#if 0 /* XXX */

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

774 if (!(inb(com->line_status_port) & LSR_RXRDY))
775 break;
776 outb(iobase + com_fifo, 0);
777 DELAY(100);
778 (void) inb(com->data_port);
779 }
780 }
781
782 intrsave = save_intr();
783 disable_intr();
782 savecrit = critical_enter();
784 COM_LOCK();
785 (void) inb(com->line_status_port);
786 (void) inb(com->data_port);
787 com->prev_modem_status = com->last_modem_status
788 = inb(com->modem_status_port);
789 outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS
790 | IER_EMSC);
791 COM_UNLOCK();
783 COM_LOCK();
784 (void) inb(com->line_status_port);
785 (void) inb(com->data_port);
786 com->prev_modem_status = com->last_modem_status
787 = inb(com->modem_status_port);
788 outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS
789 | IER_EMSC);
790 COM_UNLOCK();
792 restore_intr(intrsave);
791 critical_exit(savecrit);
793#else /* !0 */
794 /*
795 * Flush fifos. This requires a full channel reset which
796 * also disables the transmitter and receiver. Recover
797 * from this.
798 */
799 cd1400_channel_cmd(com,
800 CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET);
801 cd1400_channel_cmd(com, com->channel_control);
802
792#else /* !0 */
793 /*
794 * Flush fifos. This requires a full channel reset which
795 * also disables the transmitter and receiver. Recover
796 * from this.
797 */
798 cd1400_channel_cmd(com,
799 CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET);
800 cd1400_channel_cmd(com, com->channel_control);
801
803 intrsave = save_intr();
804 disable_intr();
802 savecrit = critical_enter();
805 COM_LOCK();
806 com->prev_modem_status = com->last_modem_status
807 = cd_getreg(com, CD1400_MSVR2);
808 cd_setreg(com, CD1400_SRER,
809 com->intr_enable
810 = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
811 COM_UNLOCK();
803 COM_LOCK();
804 com->prev_modem_status = com->last_modem_status
805 = cd_getreg(com, CD1400_MSVR2);
806 cd_setreg(com, CD1400_SRER,
807 com->intr_enable
808 = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
809 COM_UNLOCK();
812 restore_intr(intrsave);
810 critical_exit(savecrit);
813#endif /* 0 */
814 /*
815 * Handle initial DCD. Callout devices get a fake initial
816 * DCD (trapdoor DCD). If we are callout, then any sleeping
817 * callin opens get woken up and resume sleeping on "cybi"
818 * instead of "cydcd".
819 */
820 /*

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

887static void
888comhardclose(com)
889 struct com_s *com;
890{
891 cy_addr iobase;
892 int s;
893 struct tty *tp;
894 int unit;
811#endif /* 0 */
812 /*
813 * Handle initial DCD. Callout devices get a fake initial
814 * DCD (trapdoor DCD). If we are callout, then any sleeping
815 * callin opens get woken up and resume sleeping on "cybi"
816 * instead of "cydcd".
817 */
818 /*

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

885static void
886comhardclose(com)
887 struct com_s *com;
888{
889 cy_addr iobase;
890 int s;
891 struct tty *tp;
892 int unit;
895 int intrsave;
893 critical_t savecrit;
896
897 unit = com->unit;
898 iobase = com->iobase;
899 s = spltty();
900#if 0
901 com->poll = FALSE;
902 com->poll_output = FALSE;
903#endif
904 com->do_timestamp = 0;
905#if 0
906 outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
907#else
908 /* XXX */
894
895 unit = com->unit;
896 iobase = com->iobase;
897 s = spltty();
898#if 0
899 com->poll = FALSE;
900 com->poll_output = FALSE;
901#endif
902 com->do_timestamp = 0;
903#if 0
904 outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
905#else
906 /* XXX */
909 intrsave = save_intr();
910 disable_intr();
907 savecrit = critical_enter();
911 COM_LOCK();
912 com->etc = ETC_NONE;
913 cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC);
914 COM_UNLOCK();
908 COM_LOCK();
909 com->etc = ETC_NONE;
910 cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC);
911 COM_UNLOCK();
915 restore_intr(intrsave);
912 critical_exit(savecrit);
916 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
917#endif
918
919 {
920#if 0
921 outb(iobase + com_ier, 0);
922#else
913 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
914#endif
915
916 {
917#if 0
918 outb(iobase + com_ier, 0);
919#else
923 intrsave = save_intr();
924 disable_intr();
920 savecrit = critical_enter();
925 COM_LOCK();
926 cd_setreg(com, CD1400_SRER, com->intr_enable = 0);
927 COM_UNLOCK();
921 COM_LOCK();
922 cd_setreg(com, CD1400_SRER, com->intr_enable = 0);
923 COM_UNLOCK();
928 restore_intr(intrsave);
924 critical_exit(savecrit);
929#endif
930 tp = com->tp;
931 if ((tp->t_cflag & HUPCL)
932 /*
933 * XXX we will miss any carrier drop between here and the
934 * next open. Perhaps we should watch DCD even when the
935 * port is closed; it is not sufficient to check it at
936 * the next open because it might go up and down while

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

1016}
1017
1018/*
1019 * This function:
1020 * a) needs to be called with COM_LOCK() held, and
1021 * b) needs to return with COM_LOCK() held.
1022 */
1023static void
925#endif
926 tp = com->tp;
927 if ((tp->t_cflag & HUPCL)
928 /*
929 * XXX we will miss any carrier drop between here and the
930 * next open. Perhaps we should watch DCD even when the
931 * port is closed; it is not sufficient to check it at
932 * the next open because it might go up and down while

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

1012}
1013
1014/*
1015 * This function:
1016 * a) needs to be called with COM_LOCK() held, and
1017 * b) needs to return with COM_LOCK() held.
1018 */
1019static void
1024sioinput(com)
1020sioinput(com, savecrit)
1025 struct com_s *com;
1021 struct com_s *com;
1022 critical_t *savecrit;
1026{
1027 u_char *buf;
1028 int incc;
1029 u_char line_status;
1030 int recv_data;
1031 struct tty *tp;
1023{
1024 u_char *buf;
1025 int incc;
1026 u_char line_status;
1027 int recv_data;
1028 struct tty *tp;
1032 int intrsave;
1033
1034 buf = com->ibuf;
1035 tp = com->tp;
1036 if (!(tp->t_state & TS_ISOPEN)) {
1037 com_events -= (com->iptr - com->ibuf);
1038 com->iptr = com->ibuf;
1039 return;
1040 }

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

1048 */
1049
1050 do {
1051 /*
1052 * This may look odd, but it is using save-and-enable
1053 * semantics instead of the save-and-disable semantics
1054 * that are used everywhere else.
1055 */
1029
1030 buf = com->ibuf;
1031 tp = com->tp;
1032 if (!(tp->t_state & TS_ISOPEN)) {
1033 com_events -= (com->iptr - com->ibuf);
1034 com->iptr = com->ibuf;
1035 return;
1036 }

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

1044 */
1045
1046 do {
1047 /*
1048 * This may look odd, but it is using save-and-enable
1049 * semantics instead of the save-and-disable semantics
1050 * that are used everywhere else.
1051 */
1056 intrsave = save_intr();
1057 COM_UNLOCK();
1052 COM_UNLOCK();
1058 enable_intr();
1053 critical_exit(*savecrit);
1059 incc = com->iptr - buf;
1060 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat
1061 && (com->state & CS_RTS_IFLOW
1062 || tp->t_iflag & IXOFF)
1063 && !(tp->t_state & TS_TBLOCK))
1064 ttyblock(tp);
1065 com->delta_error_counts[CE_TTY_BUF_OVERFLOW]
1066 += b_to_q((char *)buf, incc, &tp->t_rawq);

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

1071 ttwakeup(tp);
1072 if (tp->t_state & TS_TTSTOP
1073 && (tp->t_iflag & IXANY
1074 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
1075 tp->t_state &= ~TS_TTSTOP;
1076 tp->t_lflag &= ~FLUSHO;
1077 comstart(tp);
1078 }
1054 incc = com->iptr - buf;
1055 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat
1056 && (com->state & CS_RTS_IFLOW
1057 || tp->t_iflag & IXOFF)
1058 && !(tp->t_state & TS_TBLOCK))
1059 ttyblock(tp);
1060 com->delta_error_counts[CE_TTY_BUF_OVERFLOW]
1061 += b_to_q((char *)buf, incc, &tp->t_rawq);

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

1066 ttwakeup(tp);
1067 if (tp->t_state & TS_TTSTOP
1068 && (tp->t_iflag & IXANY
1069 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
1070 tp->t_state &= ~TS_TTSTOP;
1071 tp->t_lflag &= ~FLUSHO;
1072 comstart(tp);
1073 }
1079 restore_intr(intrsave);
1074 *savecrit = critical_enter();
1080 COM_LOCK();
1081 } while (buf < com->iptr);
1082 } else {
1083 do {
1084 /*
1085 * This may look odd, but it is using save-and-enable
1086 * semantics instead of the save-and-disable semantics
1087 * that are used everywhere else.
1088 */
1075 COM_LOCK();
1076 } while (buf < com->iptr);
1077 } else {
1078 do {
1079 /*
1080 * This may look odd, but it is using save-and-enable
1081 * semantics instead of the save-and-disable semantics
1082 * that are used everywhere else.
1083 */
1089 intrsave = save_intr();
1090 COM_UNLOCK();
1084 COM_UNLOCK();
1091 enable_intr();
1085 critical_exit(*savecrit);
1092 line_status = buf[com->ierroff];
1093 recv_data = *buf++;
1094 if (line_status
1095 & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) {
1096 if (line_status & LSR_BI)
1097 recv_data |= TTY_BI;
1098 if (line_status & LSR_FE)
1099 recv_data |= TTY_FE;
1100 if (line_status & LSR_OE)
1101 recv_data |= TTY_OE;
1102 if (line_status & LSR_PE)
1103 recv_data |= TTY_PE;
1104 }
1105 (*linesw[tp->t_line].l_rint)(recv_data, tp);
1086 line_status = buf[com->ierroff];
1087 recv_data = *buf++;
1088 if (line_status
1089 & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) {
1090 if (line_status & LSR_BI)
1091 recv_data |= TTY_BI;
1092 if (line_status & LSR_FE)
1093 recv_data |= TTY_FE;
1094 if (line_status & LSR_OE)
1095 recv_data |= TTY_OE;
1096 if (line_status & LSR_PE)
1097 recv_data |= TTY_PE;
1098 }
1099 (*linesw[tp->t_line].l_rint)(recv_data, tp);
1106 restore_intr(intrsave);
1100 *savecrit = critical_enter();
1107 COM_LOCK();
1108 } while (buf < com->iptr);
1109 }
1110 com_events -= (com->iptr - com->ibuf);
1111 com->iptr = com->ibuf;
1112
1113 /*
1114 * There is now room for another low-level buffer full of input,

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

1772 splx(s);
1773 return (0);
1774}
1775
1776static void
1777siopoll(void *arg)
1778{
1779 int unit;
1101 COM_LOCK();
1102 } while (buf < com->iptr);
1103 }
1104 com_events -= (com->iptr - com->ibuf);
1105 com->iptr = com->ibuf;
1106
1107 /*
1108 * There is now room for another low-level buffer full of input,

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

1766 splx(s);
1767 return (0);
1768}
1769
1770static void
1771siopoll(void *arg)
1772{
1773 int unit;
1780 int intrsave;
1774 critical_t savecrit;
1781
1782#ifdef CyDebug
1783 ++cy_timeouts;
1784#endif
1785 if (com_events == 0)
1786 return;
1787repeat:
1788 for (unit = 0; unit < NSIO; ++unit) {

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

1795 continue;
1796 tp = com->tp;
1797 if (tp == NULL) {
1798 /*
1799 * XXX forget any events related to closed devices
1800 * (actually never opened devices) so that we don't
1801 * loop.
1802 */
1775
1776#ifdef CyDebug
1777 ++cy_timeouts;
1778#endif
1779 if (com_events == 0)
1780 return;
1781repeat:
1782 for (unit = 0; unit < NSIO; ++unit) {

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

1789 continue;
1790 tp = com->tp;
1791 if (tp == NULL) {
1792 /*
1793 * XXX forget any events related to closed devices
1794 * (actually never opened devices) so that we don't
1795 * loop.
1796 */
1803 intrsave = save_intr();
1804 disable_intr();
1797 savecrit = critical_enter();
1805 COM_LOCK();
1806 incc = com->iptr - com->ibuf;
1807 com->iptr = com->ibuf;
1808 if (com->state & CS_CHECKMSR) {
1809 incc += LOTS_OF_EVENTS;
1810 com->state &= ~CS_CHECKMSR;
1811 }
1812 com_events -= incc;
1813 COM_UNLOCK();
1798 COM_LOCK();
1799 incc = com->iptr - com->ibuf;
1800 com->iptr = com->ibuf;
1801 if (com->state & CS_CHECKMSR) {
1802 incc += LOTS_OF_EVENTS;
1803 com->state &= ~CS_CHECKMSR;
1804 }
1805 com_events -= incc;
1806 COM_UNLOCK();
1814 restore_intr(intrsave);
1807 critical_exit(savecrit);
1815 if (incc != 0)
1816 log(LOG_DEBUG,
1817 "sio%d: %d events for device with no tp\n",
1818 unit, incc);
1819 continue;
1820 }
1821 if (com->iptr != com->ibuf) {
1808 if (incc != 0)
1809 log(LOG_DEBUG,
1810 "sio%d: %d events for device with no tp\n",
1811 unit, incc);
1812 continue;
1813 }
1814 if (com->iptr != com->ibuf) {
1822 intrsave = save_intr();
1823 disable_intr();
1815 savecrit = critical_enter();
1824 COM_LOCK();
1816 COM_LOCK();
1825 sioinput(com);
1817 sioinput(com, &savecrit);
1826 COM_UNLOCK();
1818 COM_UNLOCK();
1827 restore_intr(intrsave);
1819 critical_exit(savecrit);
1828 }
1829 if (com->state & CS_CHECKMSR) {
1830 u_char delta_modem_status;
1831
1820 }
1821 if (com->state & CS_CHECKMSR) {
1822 u_char delta_modem_status;
1823
1832 intrsave = save_intr();
1833 disable_intr();
1824 savecrit = critical_enter();
1834 COM_LOCK();
1825 COM_LOCK();
1835 sioinput(com);
1826 sioinput(com, &savecrit);
1836 delta_modem_status = com->last_modem_status
1837 ^ com->prev_modem_status;
1838 com->prev_modem_status = com->last_modem_status;
1839 com_events -= LOTS_OF_EVENTS;
1840 com->state &= ~CS_CHECKMSR;
1841 COM_UNLOCK();
1827 delta_modem_status = com->last_modem_status
1828 ^ com->prev_modem_status;
1829 com->prev_modem_status = com->last_modem_status;
1830 com_events -= LOTS_OF_EVENTS;
1831 com->state &= ~CS_CHECKMSR;
1832 COM_UNLOCK();
1842 restore_intr(intrsave);
1833 critical_exit(savecrit);
1843 if (delta_modem_status & MSR_DCD)
1844 (*linesw[tp->t_line].l_modem)
1845 (tp, com->prev_modem_status & MSR_DCD);
1846 }
1847 if (com->extra_state & CSE_ODONE) {
1834 if (delta_modem_status & MSR_DCD)
1835 (*linesw[tp->t_line].l_modem)
1836 (tp, com->prev_modem_status & MSR_DCD);
1837 }
1838 if (com->extra_state & CSE_ODONE) {
1848 intrsave = save_intr();
1849 disable_intr();
1839 savecrit = critical_enter();
1850 COM_LOCK();
1851 com_events -= LOTS_OF_EVENTS;
1852 com->extra_state &= ~CSE_ODONE;
1853 COM_UNLOCK();
1840 COM_LOCK();
1841 com_events -= LOTS_OF_EVENTS;
1842 com->extra_state &= ~CSE_ODONE;
1843 COM_UNLOCK();
1854 restore_intr(intrsave);
1844 critical_exit(savecrit);
1855 if (!(com->state & CS_BUSY)) {
1856 tp->t_state &= ~TS_BUSY;
1857 ttwwakeup(com->tp);
1858 }
1859 if (com->etc != ETC_NONE) {
1860 if (com->etc == ETC_BREAK_ENDED)
1861 com->etc = ETC_NONE;
1862 wakeup(&com->etc);
1863 }
1864 }
1865 if (com->state & CS_ODONE) {
1845 if (!(com->state & CS_BUSY)) {
1846 tp->t_state &= ~TS_BUSY;
1847 ttwwakeup(com->tp);
1848 }
1849 if (com->etc != ETC_NONE) {
1850 if (com->etc == ETC_BREAK_ENDED)
1851 com->etc = ETC_NONE;
1852 wakeup(&com->etc);
1853 }
1854 }
1855 if (com->state & CS_ODONE) {
1866 intrsave = save_intr();
1867 disable_intr();
1856 savecrit = critical_enter();
1868 COM_LOCK();
1869 com_events -= LOTS_OF_EVENTS;
1870 com->state &= ~CS_ODONE;
1871 COM_UNLOCK();
1857 COM_LOCK();
1858 com_events -= LOTS_OF_EVENTS;
1859 com->state &= ~CS_ODONE;
1860 COM_UNLOCK();
1872 restore_intr(intrsave);
1861 critical_exit(savecrit);
1873 (*linesw[tp->t_line].l_start)(tp);
1874 }
1875 if (com_events == 0)
1876 break;
1877 }
1878 if (com_events >= LOTS_OF_EVENTS)
1879 goto repeat;
1880}

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

1893 int iflag;
1894 int iprescaler;
1895 int itimeout;
1896 int odivisor;
1897 int oprescaler;
1898 u_char opt;
1899 int s;
1900 int unit;
1862 (*linesw[tp->t_line].l_start)(tp);
1863 }
1864 if (com_events == 0)
1865 break;
1866 }
1867 if (com_events >= LOTS_OF_EVENTS)
1868 goto repeat;
1869}

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

1882 int iflag;
1883 int iprescaler;
1884 int itimeout;
1885 int odivisor;
1886 int oprescaler;
1887 u_char opt;
1888 int s;
1889 int unit;
1901 int intrsave;
1890 critical_t savecrit;
1902
1903 /* do historical conversions */
1904 if (t->c_ispeed == 0)
1905 t->c_ispeed = t->c_ospeed;
1906
1907 unit = DEV_TO_UNIT(tp->t_dev);
1908 com = com_addr(unit);
1909

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

2041 opt |= CD1400_COR2_IXANY;
2042 if (iflag & IXOFF)
2043 opt |= CD1400_COR2_IXOFF;
2044#endif
2045#ifndef SOFT_CTS_OFLOW
2046 if (cflag & CCTS_OFLOW)
2047 opt |= CD1400_COR2_CCTS_OFLOW;
2048#endif
1891
1892 /* do historical conversions */
1893 if (t->c_ispeed == 0)
1894 t->c_ispeed = t->c_ospeed;
1895
1896 unit = DEV_TO_UNIT(tp->t_dev);
1897 com = com_addr(unit);
1898

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

2030 opt |= CD1400_COR2_IXANY;
2031 if (iflag & IXOFF)
2032 opt |= CD1400_COR2_IXOFF;
2033#endif
2034#ifndef SOFT_CTS_OFLOW
2035 if (cflag & CCTS_OFLOW)
2036 opt |= CD1400_COR2_CCTS_OFLOW;
2037#endif
2049 intrsave = save_intr();
2050 disable_intr();
2038 savecrit = critical_enter();
2051 COM_LOCK();
2052 if (opt != com->cor[1]) {
2053 cor_change |= CD1400_CCR_COR2;
2054 cd_setreg(com, CD1400_COR2, com->cor[1] = opt);
2055 }
2056 COM_UNLOCK();
2039 COM_LOCK();
2040 if (opt != com->cor[1]) {
2041 cor_change |= CD1400_CCR_COR2;
2042 cd_setreg(com, CD1400_COR2, com->cor[1] = opt);
2043 }
2044 COM_UNLOCK();
2057 restore_intr(intrsave);
2045 critical_exit(savecrit);
2058
2059 /*
2060 * set channel option register 3 -
2061 * receiver FIFO interrupt threshold
2062 * flow control
2063 */
2064 opt = RxFifoThreshold;
2065#ifdef Smarts

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

2170 opt |= CD1400_MCOR2_CTSod;
2171#endif
2172 cd_setreg(com, CD1400_MCOR2, opt);
2173
2174 /*
2175 * XXX should have done this long ago, but there is too much state
2176 * to change all atomically.
2177 */
2046
2047 /*
2048 * set channel option register 3 -
2049 * receiver FIFO interrupt threshold
2050 * flow control
2051 */
2052 opt = RxFifoThreshold;
2053#ifdef Smarts

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

2158 opt |= CD1400_MCOR2_CTSod;
2159#endif
2160 cd_setreg(com, CD1400_MCOR2, opt);
2161
2162 /*
2163 * XXX should have done this long ago, but there is too much state
2164 * to change all atomically.
2165 */
2178 intrsave = save_intr();
2179 disable_intr();
2166 savecrit = critical_enter();
2180 COM_LOCK();
2181
2182 com->state &= ~CS_TTGO;
2183 if (!(tp->t_state & TS_TTSTOP))
2184 com->state |= CS_TTGO;
2185 if (cflag & CRTS_IFLOW) {
2186 com->state |= CS_RTS_IFLOW;
2187 /*

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

2239 if (com->intr_enable & CD1400_SRER_TXRDY)
2240 cd_setreg(com, CD1400_SRER,
2241 com->intr_enable
2242 = (com->intr_enable & ~CD1400_SRER_TXRDY)
2243 | CD1400_SRER_TXMPTY);
2244 }
2245
2246 COM_UNLOCK();
2167 COM_LOCK();
2168
2169 com->state &= ~CS_TTGO;
2170 if (!(tp->t_state & TS_TTSTOP))
2171 com->state |= CS_TTGO;
2172 if (cflag & CRTS_IFLOW) {
2173 com->state |= CS_RTS_IFLOW;
2174 /*

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

2226 if (com->intr_enable & CD1400_SRER_TXRDY)
2227 cd_setreg(com, CD1400_SRER,
2228 com->intr_enable
2229 = (com->intr_enable & ~CD1400_SRER_TXRDY)
2230 | CD1400_SRER_TXMPTY);
2231 }
2232
2233 COM_UNLOCK();
2247 restore_intr(intrsave);
2234 critical_exit(savecrit);
2248 splx(s);
2249 comstart(tp);
2250 if (com->ibufold != NULL) {
2251 free(com->ibufold, M_DEVBUF);
2252 com->ibufold = NULL;
2253 }
2254 return (0);
2255}
2256
2257static int
2258siosetwater(com, speed)
2259 struct com_s *com;
2260 speed_t speed;
2261{
2262 int cp4ticks;
2263 u_char *ibuf;
2264 int ibufsize;
2265 struct tty *tp;
2235 splx(s);
2236 comstart(tp);
2237 if (com->ibufold != NULL) {
2238 free(com->ibufold, M_DEVBUF);
2239 com->ibufold = NULL;
2240 }
2241 return (0);
2242}
2243
2244static int
2245siosetwater(com, speed)
2246 struct com_s *com;
2247 speed_t speed;
2248{
2249 int cp4ticks;
2250 u_char *ibuf;
2251 int ibufsize;
2252 struct tty *tp;
2266 int intrsave;
2253 critical_t savecrit;
2267
2268 /*
2269 * Make the buffer size large enough to handle a softtty interrupt
2270 * latency of about 2 ticks without loss of throughput or data
2271 * (about 3 ticks if input flow control is not used or not honoured,
2272 * but a bit less for CS5-CS7 modes).
2273 */
2274 cp4ticks = speed / 10 / hz * 4;

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

2296 tp->t_ispeedwat = (speed_t)-1;
2297 tp->t_ospeedwat = (speed_t)-1;
2298 }
2299
2300 /*
2301 * Read current input buffer, if any. Continue with interrupts
2302 * disabled.
2303 */
2254
2255 /*
2256 * Make the buffer size large enough to handle a softtty interrupt
2257 * latency of about 2 ticks without loss of throughput or data
2258 * (about 3 ticks if input flow control is not used or not honoured,
2259 * but a bit less for CS5-CS7 modes).
2260 */
2261 cp4ticks = speed / 10 / hz * 4;

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

2283 tp->t_ispeedwat = (speed_t)-1;
2284 tp->t_ospeedwat = (speed_t)-1;
2285 }
2286
2287 /*
2288 * Read current input buffer, if any. Continue with interrupts
2289 * disabled.
2290 */
2304 intrsave = save_intr();
2305 disable_intr();
2291 savecrit = critical_enter();
2306 COM_LOCK();
2307 if (com->iptr != com->ibuf)
2292 COM_LOCK();
2293 if (com->iptr != com->ibuf)
2308 sioinput(com);
2294 sioinput(com, &savecrit);
2309
2310 /*-
2311 * Initialize critical variables, including input buffer watermarks.
2312 * The external device is asked to stop sending when the buffer
2313 * exactly reaches high water, or when the high level requests it.
2314 * The high level is notified immediately (rather than at a later
2315 * clock tick) when this watermark is reached.
2316 * The buffer size is chosen so the watermark should almost never
2317 * be reached.
2318 * The low watermark is invisibly 0 since the buffer is always
2319 * emptied all at once.
2320 */
2321 com->iptr = com->ibuf = ibuf;
2322 com->ibufend = ibuf + ibufsize;
2323 com->ierroff = ibufsize;
2324 com->ihighwater = ibuf + 3 * ibufsize / 4;
2325
2326 COM_UNLOCK();
2295
2296 /*-
2297 * Initialize critical variables, including input buffer watermarks.
2298 * The external device is asked to stop sending when the buffer
2299 * exactly reaches high water, or when the high level requests it.
2300 * The high level is notified immediately (rather than at a later
2301 * clock tick) when this watermark is reached.
2302 * The buffer size is chosen so the watermark should almost never
2303 * be reached.
2304 * The low watermark is invisibly 0 since the buffer is always
2305 * emptied all at once.
2306 */
2307 com->iptr = com->ibuf = ibuf;
2308 com->ibufend = ibuf + ibufsize;
2309 com->ierroff = ibufsize;
2310 com->ihighwater = ibuf + 3 * ibufsize / 4;
2311
2312 COM_UNLOCK();
2327 restore_intr(intrsave);
2313 critical_exit(savecrit);
2328 return (0);
2329}
2330
2331static void
2332comstart(tp)
2333 struct tty *tp;
2334{
2335 struct com_s *com;
2336 int s;
2337#ifdef CyDebug
2338 bool_t started;
2339#endif
2340 int unit;
2314 return (0);
2315}
2316
2317static void
2318comstart(tp)
2319 struct tty *tp;
2320{
2321 struct com_s *com;
2322 int s;
2323#ifdef CyDebug
2324 bool_t started;
2325#endif
2326 int unit;
2341 int intrsave;
2327 critical_t savecrit;
2342
2343 unit = DEV_TO_UNIT(tp->t_dev);
2344 com = com_addr(unit);
2345 s = spltty();
2346
2347#ifdef CyDebug
2348 ++com->start_count;
2349 started = FALSE;
2350#endif
2351
2328
2329 unit = DEV_TO_UNIT(tp->t_dev);
2330 com = com_addr(unit);
2331 s = spltty();
2332
2333#ifdef CyDebug
2334 ++com->start_count;
2335 started = FALSE;
2336#endif
2337
2352 intrsave = save_intr();
2353 disable_intr();
2338 savecrit = critical_enter();
2354 COM_LOCK();
2355 if (tp->t_state & TS_TTSTOP) {
2356 com->state &= ~CS_TTGO;
2357 if (com->intr_enable & CD1400_SRER_TXRDY)
2358 cd_setreg(com, CD1400_SRER,
2359 com->intr_enable
2360 = (com->intr_enable & ~CD1400_SRER_TXRDY)
2361 | CD1400_SRER_TXMPTY);

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

2383#if 0
2384 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
2385#else
2386 cd_setreg(com, com->mcr_rts_reg,
2387 com->mcr_image |= com->mcr_rts);
2388#endif
2389 }
2390 COM_UNLOCK();
2339 COM_LOCK();
2340 if (tp->t_state & TS_TTSTOP) {
2341 com->state &= ~CS_TTGO;
2342 if (com->intr_enable & CD1400_SRER_TXRDY)
2343 cd_setreg(com, CD1400_SRER,
2344 com->intr_enable
2345 = (com->intr_enable & ~CD1400_SRER_TXRDY)
2346 | CD1400_SRER_TXMPTY);

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

2368#if 0
2369 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
2370#else
2371 cd_setreg(com, com->mcr_rts_reg,
2372 com->mcr_image |= com->mcr_rts);
2373#endif
2374 }
2375 COM_UNLOCK();
2391 restore_intr(intrsave);
2376 critical_exit(savecrit);
2392 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
2393 ttwwakeup(tp);
2394 splx(s);
2395 return;
2396 }
2397 if (tp->t_outq.c_cc != 0) {
2398 struct lbq *qp;
2399 struct lbq *next;
2400
2401 if (!com->obufs[0].l_queued) {
2402#ifdef CyDebug
2403 started = TRUE;
2404#endif
2405 com->obufs[0].l_tail
2406 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1,
2407 sizeof com->obuf1);
2408 com->obufs[0].l_next = NULL;
2409 com->obufs[0].l_queued = TRUE;
2377 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
2378 ttwwakeup(tp);
2379 splx(s);
2380 return;
2381 }
2382 if (tp->t_outq.c_cc != 0) {
2383 struct lbq *qp;
2384 struct lbq *next;
2385
2386 if (!com->obufs[0].l_queued) {
2387#ifdef CyDebug
2388 started = TRUE;
2389#endif
2390 com->obufs[0].l_tail
2391 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1,
2392 sizeof com->obuf1);
2393 com->obufs[0].l_next = NULL;
2394 com->obufs[0].l_queued = TRUE;
2410 intrsave = save_intr();
2411 disable_intr();
2395 savecrit = critical_enter();
2412 COM_LOCK();
2413 if (com->state & CS_BUSY) {
2414 qp = com->obufq.l_next;
2415 while ((next = qp->l_next) != NULL)
2416 qp = next;
2417 qp->l_next = &com->obufs[0];
2418 } else {
2419 com->obufq.l_head = com->obufs[0].l_head;

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

2424 | CS_ODEVREADY))
2425 cd_setreg(com, CD1400_SRER,
2426 com->intr_enable
2427 = (com->intr_enable
2428 & ~CD1400_SRER_TXMPTY)
2429 | CD1400_SRER_TXRDY);
2430 }
2431 COM_UNLOCK();
2396 COM_LOCK();
2397 if (com->state & CS_BUSY) {
2398 qp = com->obufq.l_next;
2399 while ((next = qp->l_next) != NULL)
2400 qp = next;
2401 qp->l_next = &com->obufs[0];
2402 } else {
2403 com->obufq.l_head = com->obufs[0].l_head;

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

2408 | CS_ODEVREADY))
2409 cd_setreg(com, CD1400_SRER,
2410 com->intr_enable
2411 = (com->intr_enable
2412 & ~CD1400_SRER_TXMPTY)
2413 | CD1400_SRER_TXRDY);
2414 }
2415 COM_UNLOCK();
2432 restore_intr(intrsave);
2416 critical_exit(savecrit);
2433 }
2434 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) {
2435#ifdef CyDebug
2436 started = TRUE;
2437#endif
2438 com->obufs[1].l_tail
2439 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2,
2440 sizeof com->obuf2);
2441 com->obufs[1].l_next = NULL;
2442 com->obufs[1].l_queued = TRUE;
2417 }
2418 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) {
2419#ifdef CyDebug
2420 started = TRUE;
2421#endif
2422 com->obufs[1].l_tail
2423 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2,
2424 sizeof com->obuf2);
2425 com->obufs[1].l_next = NULL;
2426 com->obufs[1].l_queued = TRUE;
2443 intrsave = save_intr();
2444 disable_intr();
2427 savecrit = critical_enter();
2445 COM_LOCK();
2446 if (com->state & CS_BUSY) {
2447 qp = com->obufq.l_next;
2448 while ((next = qp->l_next) != NULL)
2449 qp = next;
2450 qp->l_next = &com->obufs[1];
2451 } else {
2452 com->obufq.l_head = com->obufs[1].l_head;

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

2457 | CS_ODEVREADY))
2458 cd_setreg(com, CD1400_SRER,
2459 com->intr_enable
2460 = (com->intr_enable
2461 & ~CD1400_SRER_TXMPTY)
2462 | CD1400_SRER_TXRDY);
2463 }
2464 COM_UNLOCK();
2428 COM_LOCK();
2429 if (com->state & CS_BUSY) {
2430 qp = com->obufq.l_next;
2431 while ((next = qp->l_next) != NULL)
2432 qp = next;
2433 qp->l_next = &com->obufs[1];
2434 } else {
2435 com->obufq.l_head = com->obufs[1].l_head;

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

2440 | CS_ODEVREADY))
2441 cd_setreg(com, CD1400_SRER,
2442 com->intr_enable
2443 = (com->intr_enable
2444 & ~CD1400_SRER_TXMPTY)
2445 | CD1400_SRER_TXRDY);
2446 }
2447 COM_UNLOCK();
2465 restore_intr(intrsave);
2448 critical_exit(savecrit);
2466 }
2467 tp->t_state |= TS_BUSY;
2468 }
2469#ifdef CyDebug
2470 if (started)
2471 ++com->start_real;
2472#endif
2473#if 0
2449 }
2450 tp->t_state |= TS_BUSY;
2451 }
2452#ifdef CyDebug
2453 if (started)
2454 ++com->start_real;
2455#endif
2456#if 0
2474 intrsave = save_intr();
2475 disable_intr();
2457 savecrit = critical_enter();
2476 COM_LOCK();
2477 if (com->state >= (CS_BUSY | CS_TTGO))
2478 siointr1(com); /* fake interrupt to start output */
2479 COM_UNLOCK();
2458 COM_LOCK();
2459 if (com->state >= (CS_BUSY | CS_TTGO))
2460 siointr1(com); /* fake interrupt to start output */
2461 COM_UNLOCK();
2480 restore_intr(intrsave);
2462 critical_exit(savecrit);
2481#endif
2482 ttwwakeup(tp);
2483 splx(s);
2484}
2485
2486static void
2487comstop(tp, rw)
2488 struct tty *tp;
2489 int rw;
2490{
2491 struct com_s *com;
2492 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;
2493 int intrsave;
2475 critical_t savecrit;
2494
2495 com = com_addr(DEV_TO_UNIT(tp->t_dev));
2496 wakeup_etc = FALSE;
2476
2477 com = com_addr(DEV_TO_UNIT(tp->t_dev));
2478 wakeup_etc = FALSE;
2497 intrsave = save_intr();
2498 disable_intr();
2479 savecrit = critical_enter();
2499 COM_LOCK();
2500 if (rw & FWRITE) {
2501 com->obufs[0].l_queued = FALSE;
2502 com->obufs[1].l_queued = FALSE;
2503 if (com->extra_state & CSE_ODONE) {
2504 com_events -= LOTS_OF_EVENTS;
2505 com->extra_state &= ~CSE_ODONE;
2506 if (com->etc != ETC_NONE) {

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

2515 com->state &= ~(CS_ODONE | CS_BUSY);
2516 }
2517 if (rw & FREAD) {
2518 /* XXX no way to reset only input fifo. */
2519 com_events -= (com->iptr - com->ibuf);
2520 com->iptr = com->ibuf;
2521 }
2522 COM_UNLOCK();
2480 COM_LOCK();
2481 if (rw & FWRITE) {
2482 com->obufs[0].l_queued = FALSE;
2483 com->obufs[1].l_queued = FALSE;
2484 if (com->extra_state & CSE_ODONE) {
2485 com_events -= LOTS_OF_EVENTS;
2486 com->extra_state &= ~CSE_ODONE;
2487 if (com->etc != ETC_NONE) {

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

2496 com->state &= ~(CS_ODONE | CS_BUSY);
2497 }
2498 if (rw & FREAD) {
2499 /* XXX no way to reset only input fifo. */
2500 com_events -= (com->iptr - com->ibuf);
2501 com->iptr = com->ibuf;
2502 }
2503 COM_UNLOCK();
2523 restore_intr(intrsave);
2504 critical_exit(savecrit);
2524 if (wakeup_etc)
2525 wakeup(&com->etc);
2526 if (rw & FWRITE && com->etc == ETC_NONE)
2527 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
2528 comstart(tp);
2529}
2530
2531static int
2532commctl(com, bits, how)
2533 struct com_s *com;
2534 int bits;
2535 int how;
2536{
2537 int mcr;
2538 int msr;
2505 if (wakeup_etc)
2506 wakeup(&com->etc);
2507 if (rw & FWRITE && com->etc == ETC_NONE)
2508 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
2509 comstart(tp);
2510}
2511
2512static int
2513commctl(com, bits, how)
2514 struct com_s *com;
2515 int bits;
2516 int how;
2517{
2518 int mcr;
2519 int msr;
2539 int intrsave;
2520 critical_t savecrit;
2540
2541 if (how == DMGET) {
2542 if (com->channel_control & CD1400_CCR_RCVEN)
2543 bits |= TIOCM_LE;
2544 mcr = com->mcr_image;
2545 if (mcr & com->mcr_dtr)
2546 bits |= TIOCM_DTR;
2547 if (mcr & com->mcr_rts)

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

2569 bits |= TIOCM_RI;
2570 return (bits);
2571 }
2572 mcr = 0;
2573 if (bits & TIOCM_DTR)
2574 mcr |= com->mcr_dtr;
2575 if (bits & TIOCM_RTS)
2576 mcr |= com->mcr_rts;
2521
2522 if (how == DMGET) {
2523 if (com->channel_control & CD1400_CCR_RCVEN)
2524 bits |= TIOCM_LE;
2525 mcr = com->mcr_image;
2526 if (mcr & com->mcr_dtr)
2527 bits |= TIOCM_DTR;
2528 if (mcr & com->mcr_rts)

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

2550 bits |= TIOCM_RI;
2551 return (bits);
2552 }
2553 mcr = 0;
2554 if (bits & TIOCM_DTR)
2555 mcr |= com->mcr_dtr;
2556 if (bits & TIOCM_RTS)
2557 mcr |= com->mcr_rts;
2577 intrsave = save_intr();
2578 disable_intr();
2558 savecrit = critical_enter();
2579 COM_LOCK();
2580 switch (how) {
2581 case DMSET:
2582 com->mcr_image = mcr;
2583 cd_setreg(com, CD1400_MSVR1, mcr);
2584 cd_setreg(com, CD1400_MSVR2, mcr);
2585 break;
2586 case DMBIS:
2587 com->mcr_image = mcr = com->mcr_image | mcr;
2588 cd_setreg(com, CD1400_MSVR1, mcr);
2589 cd_setreg(com, CD1400_MSVR2, mcr);
2590 break;
2591 case DMBIC:
2592 com->mcr_image = mcr = com->mcr_image & ~mcr;
2593 cd_setreg(com, CD1400_MSVR1, mcr);
2594 cd_setreg(com, CD1400_MSVR2, mcr);
2595 break;
2596 }
2597 COM_UNLOCK();
2559 COM_LOCK();
2560 switch (how) {
2561 case DMSET:
2562 com->mcr_image = mcr;
2563 cd_setreg(com, CD1400_MSVR1, mcr);
2564 cd_setreg(com, CD1400_MSVR2, mcr);
2565 break;
2566 case DMBIS:
2567 com->mcr_image = mcr = com->mcr_image | mcr;
2568 cd_setreg(com, CD1400_MSVR1, mcr);
2569 cd_setreg(com, CD1400_MSVR2, mcr);
2570 break;
2571 case DMBIC:
2572 com->mcr_image = mcr = com->mcr_image & ~mcr;
2573 cd_setreg(com, CD1400_MSVR1, mcr);
2574 cd_setreg(com, CD1400_MSVR2, mcr);
2575 break;
2576 }
2577 COM_UNLOCK();
2598 restore_intr(intrsave);
2578 critical_exit(savecrit);
2599 return (0);
2600}
2601
2602static void
2603siosettimeout()
2604{
2605 struct com_s *com;
2606 bool_t someopen;

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

2652 /*
2653 * Recover from lost output interrupts.
2654 * Poll any lines that don't use interrupts.
2655 */
2656 for (unit = 0; unit < NSIO; ++unit) {
2657 com = com_addr(unit);
2658 if (com != NULL
2659 && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) {
2579 return (0);
2580}
2581
2582static void
2583siosettimeout()
2584{
2585 struct com_s *com;
2586 bool_t someopen;

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

2632 /*
2633 * Recover from lost output interrupts.
2634 * Poll any lines that don't use interrupts.
2635 */
2636 for (unit = 0; unit < NSIO; ++unit) {
2637 com = com_addr(unit);
2638 if (com != NULL
2639 && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) {
2660 int intrsave;
2640 critical_t savecrit;
2661
2641
2662 intrsave = save_intr();
2663 disable_intr();
2642 savecrit = critical_enter();
2664 COM_LOCK();
2665 siointr1(com);
2666 COM_UNLOCK();
2643 COM_LOCK();
2644 siointr1(com);
2645 COM_UNLOCK();
2667 restore_intr(intrsave);
2646 critical_exit(savecrit);
2668 }
2669 }
2670#endif
2671
2672 /*
2673 * Check for and log errors, but not too often.
2674 */
2675 if (--sio_timeouts_until_log > 0)
2676 return;
2677 sio_timeouts_until_log = hz / sio_timeout;
2678 for (unit = 0; unit < NSIO; ++unit) {
2679 int errnum;
2680
2681 com = com_addr(unit);
2682 if (com == NULL)
2683 continue;
2684 for (errnum = 0; errnum < CE_NTYPES; ++errnum) {
2685 u_int delta;
2686 u_long total;
2647 }
2648 }
2649#endif
2650
2651 /*
2652 * Check for and log errors, but not too often.
2653 */
2654 if (--sio_timeouts_until_log > 0)
2655 return;
2656 sio_timeouts_until_log = hz / sio_timeout;
2657 for (unit = 0; unit < NSIO; ++unit) {
2658 int errnum;
2659
2660 com = com_addr(unit);
2661 if (com == NULL)
2662 continue;
2663 for (errnum = 0; errnum < CE_NTYPES; ++errnum) {
2664 u_int delta;
2665 u_long total;
2687 int intrsave;
2666 critical_t savecrit;
2688
2667
2689 intrsave = save_intr();
2690 disable_intr();
2668 savecrit = critical_enter();
2691 COM_LOCK();
2692 delta = com->delta_error_counts[errnum];
2693 com->delta_error_counts[errnum] = 0;
2694 COM_UNLOCK();
2669 COM_LOCK();
2670 delta = com->delta_error_counts[errnum];
2671 com->delta_error_counts[errnum] = 0;
2672 COM_UNLOCK();
2695 restore_intr(intrsave);
2673 critical_exit(savecrit);
2696 if (delta == 0)
2697 continue;
2698 total = com->error_counts[errnum] += delta;
2699 log(LOG_ERR, "cy%d: %u more %s%s (total %lu)\n",
2700 unit, delta, error_desc[errnum],
2701 delta == 1 ? "" : "s", total);
2702 }
2703 }

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

2839 }
2840}
2841
2842static void
2843cd_etc(com, etc)
2844 struct com_s *com;
2845 int etc;
2846{
2674 if (delta == 0)
2675 continue;
2676 total = com->error_counts[errnum] += delta;
2677 log(LOG_ERR, "cy%d: %u more %s%s (total %lu)\n",
2678 unit, delta, error_desc[errnum],
2679 delta == 1 ? "" : "s", total);
2680 }
2681 }

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

2817 }
2818}
2819
2820static void
2821cd_etc(com, etc)
2822 struct com_s *com;
2823 int etc;
2824{
2847 int intrsave;
2825 critical_t savecrit;
2848
2849 /*
2850 * We can't change the hardware's ETC state while there are any
2851 * characters in the tx fifo, since those characters would be
2852 * interpreted as commands! Unputting characters from the fifo
2853 * is difficult, so we wait up to 12 character times for the fifo
2854 * to drain. The command will be delayed for up to 2 character
2855 * times for the tx to become empty. Unputting characters from
2856 * the tx holding and shift registers is impossible, so we wait
2857 * for the tx to become empty so that the command is sure to be
2858 * executed soon after we issue it.
2859 */
2826
2827 /*
2828 * We can't change the hardware's ETC state while there are any
2829 * characters in the tx fifo, since those characters would be
2830 * interpreted as commands! Unputting characters from the fifo
2831 * is difficult, so we wait up to 12 character times for the fifo
2832 * to drain. The command will be delayed for up to 2 character
2833 * times for the tx to become empty. Unputting characters from
2834 * the tx holding and shift registers is impossible, so we wait
2835 * for the tx to become empty so that the command is sure to be
2836 * executed soon after we issue it.
2837 */
2860 intrsave = save_intr();
2861 disable_intr();
2838 savecrit = critical_enter();
2862 COM_LOCK();
2863 if (com->etc == etc)
2864 goto wait;
2865 if ((etc == CD1400_ETC_SENDBREAK
2866 && (com->etc == ETC_BREAK_STARTING
2867 || com->etc == ETC_BREAK_STARTED))
2868 || (etc == CD1400_ETC_STOPBREAK
2869 && (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED
2870 || com->etc == ETC_NONE))) {
2871 COM_UNLOCK();
2839 COM_LOCK();
2840 if (com->etc == etc)
2841 goto wait;
2842 if ((etc == CD1400_ETC_SENDBREAK
2843 && (com->etc == ETC_BREAK_STARTING
2844 || com->etc == ETC_BREAK_STARTED))
2845 || (etc == CD1400_ETC_STOPBREAK
2846 && (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED
2847 || com->etc == ETC_NONE))) {
2848 COM_UNLOCK();
2872 restore_intr(intrsave);
2849 critical_exit(savecrit);
2873 return;
2874 }
2875 com->etc = etc;
2876 cd_setreg(com, CD1400_SRER,
2877 com->intr_enable
2878 = (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY);
2879wait:
2880 COM_UNLOCK();
2850 return;
2851 }
2852 com->etc = etc;
2853 cd_setreg(com, CD1400_SRER,
2854 com->intr_enable
2855 = (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY);
2856wait:
2857 COM_UNLOCK();
2881 restore_intr(intrsave);
2858 critical_exit(savecrit);
2882 while (com->etc == etc
2883 && tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0)
2884 continue;
2885}
2886
2887static int
2888cd_getreg(com, reg)
2889 struct com_s *com;
2890 int reg;
2891{
2892 struct com_s *basecom;
2893 u_char car;
2894 int cy_align;
2859 while (com->etc == etc
2860 && tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0)
2861 continue;
2862}
2863
2864static int
2865cd_getreg(com, reg)
2866 struct com_s *com;
2867 int reg;
2868{
2869 struct com_s *basecom;
2870 u_char car;
2871 int cy_align;
2895 int intrsave;
2872 criticale_t savecrit;
2873 register_t eflags;
2896 cy_addr iobase;
2897 int val;
2898
2899 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
2900 car = com->unit & CD1400_CAR_CHAN;
2901 cy_align = com->cy_align;
2902 iobase = com->iobase;
2874 cy_addr iobase;
2875 int val;
2876
2877 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
2878 car = com->unit & CD1400_CAR_CHAN;
2879 cy_align = com->cy_align;
2880 iobase = com->iobase;
2903 intrsave = save_intr();
2904 disable_intr();
2905 if (intrsave & PSL_I)
2881 eflags = read_eflags();
2882 savecrit = critical_enter();
2883 if (eflags & PSL_I)
2906 COM_LOCK();
2907 if (basecom->car != car)
2908 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
2909 val = cd_inb(iobase, reg, cy_align);
2884 COM_LOCK();
2885 if (basecom->car != car)
2886 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
2887 val = cd_inb(iobase, reg, cy_align);
2910 if (intrsave & PSL_I)
2888 if (eflags & PSL_I)
2911 COM_UNLOCK();
2889 COM_UNLOCK();
2912 restore_intr(intrsave);
2890 critical_exit(savecrit);
2913 return (val);
2914}
2915
2916static void
2917cd_setreg(com, reg, val)
2918 struct com_s *com;
2919 int reg;
2920 int val;
2921{
2922 struct com_s *basecom;
2923 u_char car;
2924 int cy_align;
2891 return (val);
2892}
2893
2894static void
2895cd_setreg(com, reg, val)
2896 struct com_s *com;
2897 int reg;
2898 int val;
2899{
2900 struct com_s *basecom;
2901 u_char car;
2902 int cy_align;
2925 int intrsave;
2903 critical_t savecrit;
2904 register_t eflags;
2926 cy_addr iobase;
2927
2928 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
2929 car = com->unit & CD1400_CAR_CHAN;
2930 cy_align = com->cy_align;
2931 iobase = com->iobase;
2905 cy_addr iobase;
2906
2907 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1));
2908 car = com->unit & CD1400_CAR_CHAN;
2909 cy_align = com->cy_align;
2910 iobase = com->iobase;
2932 intrsave = save_intr();
2933 disable_intr();
2934 if (intrsave & PSL_I)
2911 eflags = read_eflags();
2912 savecrit = critical_enter();
2913 if (eflags & PSL_I)
2935 COM_LOCK();
2936 if (basecom->car != car)
2937 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
2938 cd_outb(iobase, reg, cy_align, val);
2914 COM_LOCK();
2915 if (basecom->car != car)
2916 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car);
2917 cd_outb(iobase, reg, cy_align, val);
2939 if (intrsave & PSL_I)
2918 if (eflags & PSL_I)
2940 COM_UNLOCK();
2919 COM_UNLOCK();
2941 restore_intr(intrsave);
2920 critical_exit(savecrit);
2942}
2943
2944#ifdef CyDebug
2945/* useful in ddb */
2946void
2947cystatus(unit)
2948 int unit;
2949{

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

--- 54 unchanged lines hidden ---