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 --- |