cy.c (86008) | cy.c (88088) |
---|---|
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 86008 2001-11-04 08:49:51Z phk $ | 30 * $FreeBSD: head/sys/dev/cy/cy.c 88088 2001-12-18 00:27:18Z jhb $ |
31 */ 32 33#include "opt_compat.h" 34#include "cy.h" 35 36/* 37 * TODO: 38 * Atomic COR change. --- 312 unchanged lines hidden (view full) --- 351static int sioattach __P((struct isa_device *dev)); 352static void cd1400_channel_cmd __P((struct com_s *com, int cmd)); 353static void cd1400_channel_cmd_wait __P((struct com_s *com)); 354static void cd_etc __P((struct com_s *com, int etc)); 355static int cd_getreg __P((struct com_s *com, int reg)); 356static void cd_setreg __P((struct com_s *com, int reg, int val)); 357static timeout_t siodtrwakeup; 358static 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. --- 312 unchanged lines hidden (view full) --- 351static int sioattach __P((struct isa_device *dev)); 352static void cd1400_channel_cmd __P((struct com_s *com, int cmd)); 353static void cd1400_channel_cmd_wait __P((struct com_s *com)); 354static void cd_etc __P((struct com_s *com, int etc)); 355static int cd_getreg __P((struct com_s *com, int reg)); 356static void cd_setreg __P((struct com_s *com, int reg, int val)); 357static timeout_t siodtrwakeup; 358static void comhardclose __P((struct com_s *com)); |
359static void sioinput __P((struct com_s *com, critical_t *savecrit)); | 359static void sioinput __P((struct com_s *com)); |
360#if 0 361static void siointr1 __P((struct com_s *com)); 362#endif 363static int commctl __P((struct com_s *com, int bits, int how)); 364static int comparam __P((struct tty *tp, struct termios *t)); 365static void siopoll __P((void *arg)); 366static int sioprobe __P((struct isa_device *dev)); 367static void siosettimeout __P((void)); --- 300 unchanged lines hidden (view full) --- 668 struct thread *td; 669{ 670 struct com_s *com; 671 int error; 672 int mynor; 673 int s; 674 struct tty *tp; 675 int unit; | 360#if 0 361static void siointr1 __P((struct com_s *com)); 362#endif 363static int commctl __P((struct com_s *com, int bits, int how)); 364static int comparam __P((struct tty *tp, struct termios *t)); 365static void siopoll __P((void *arg)); 366static int sioprobe __P((struct isa_device *dev)); 367static void siosettimeout __P((void)); --- 300 unchanged lines hidden (view full) --- 668 struct thread *td; 669{ 670 struct com_s *com; 671 int error; 672 int mynor; 673 int s; 674 struct tty *tp; 675 int unit; |
676 critical_t savecrit; | |
677 678 mynor = minor(dev); 679 unit = MINOR_TO_UNIT(mynor); 680 if ((u_int) unit >= NSIO || (com = com_addr(unit)) == NULL) 681 return (ENXIO); 682 if (mynor & CONTROL_MASK) 683 return (0); 684 tp = dev->si_tty = com->tp = ttymalloc(com->tp); --- 85 unchanged lines hidden (view full) --- 770 if (!(inb(com->line_status_port) & LSR_RXRDY)) 771 break; 772 outb(iobase + com_fifo, 0); 773 DELAY(100); 774 (void) inb(com->data_port); 775 } 776 } 777 | 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 tp = dev->si_tty = com->tp = ttymalloc(com->tp); --- 85 unchanged lines hidden (view full) --- 769 if (!(inb(com->line_status_port) & LSR_RXRDY)) 770 break; 771 outb(iobase + com_fifo, 0); 772 DELAY(100); 773 (void) inb(com->data_port); 774 } 775 } 776 |
778 savecrit = critical_enter(); | 777 critical_enter(); |
779 COM_LOCK(); 780 (void) inb(com->line_status_port); 781 (void) inb(com->data_port); 782 com->prev_modem_status = com->last_modem_status 783 = inb(com->modem_status_port); 784 outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS 785 | IER_EMSC); 786 COM_UNLOCK(); | 778 COM_LOCK(); 779 (void) inb(com->line_status_port); 780 (void) inb(com->data_port); 781 com->prev_modem_status = com->last_modem_status 782 = inb(com->modem_status_port); 783 outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS 784 | IER_EMSC); 785 COM_UNLOCK(); |
787 critical_exit(savecrit); | 786 critical_exit(); |
788#else /* !0 */ 789 /* 790 * Flush fifos. This requires a full channel reset which 791 * also disables the transmitter and receiver. Recover 792 * from this. 793 */ 794 cd1400_channel_cmd(com, 795 CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET); 796 cd1400_channel_cmd(com, com->channel_control); 797 | 787#else /* !0 */ 788 /* 789 * Flush fifos. This requires a full channel reset which 790 * also disables the transmitter and receiver. Recover 791 * from this. 792 */ 793 cd1400_channel_cmd(com, 794 CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET); 795 cd1400_channel_cmd(com, com->channel_control); 796 |
798 savecrit = critical_enter(); | 797 critical_enter(); |
799 COM_LOCK(); 800 com->prev_modem_status = com->last_modem_status 801 = cd_getreg(com, CD1400_MSVR2); 802 cd_setreg(com, CD1400_SRER, 803 com->intr_enable 804 = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA); 805 COM_UNLOCK(); | 798 COM_LOCK(); 799 com->prev_modem_status = com->last_modem_status 800 = cd_getreg(com, CD1400_MSVR2); 801 cd_setreg(com, CD1400_SRER, 802 com->intr_enable 803 = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA); 804 COM_UNLOCK(); |
806 critical_exit(savecrit); | 805 critical_exit(); |
807#endif /* 0 */ 808 /* 809 * Handle initial DCD. Callout devices get a fake initial 810 * DCD (trapdoor DCD). If we are callout, then any sleeping 811 * callin opens get woken up and resume sleeping on "cybi" 812 * instead of "cydcd". 813 */ 814 /* --- 66 unchanged lines hidden (view full) --- 881static void 882comhardclose(com) 883 struct com_s *com; 884{ 885 cy_addr iobase; 886 int s; 887 struct tty *tp; 888 int unit; | 806#endif /* 0 */ 807 /* 808 * Handle initial DCD. Callout devices get a fake initial 809 * DCD (trapdoor DCD). If we are callout, then any sleeping 810 * callin opens get woken up and resume sleeping on "cybi" 811 * instead of "cydcd". 812 */ 813 /* --- 66 unchanged lines hidden (view full) --- 880static void 881comhardclose(com) 882 struct com_s *com; 883{ 884 cy_addr iobase; 885 int s; 886 struct tty *tp; 887 int unit; |
889 critical_t savecrit; | |
890 891 unit = com->unit; 892 iobase = com->iobase; 893 s = spltty(); 894#if 0 895 com->poll = FALSE; 896 com->poll_output = FALSE; 897#endif 898 com->do_timestamp = 0; 899#if 0 900 outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK); 901#else 902 /* XXX */ | 888 889 unit = com->unit; 890 iobase = com->iobase; 891 s = spltty(); 892#if 0 893 com->poll = FALSE; 894 com->poll_output = FALSE; 895#endif 896 com->do_timestamp = 0; 897#if 0 898 outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK); 899#else 900 /* XXX */ |
903 savecrit = critical_enter(); | 901 critical_enter(); |
904 COM_LOCK(); 905 com->etc = ETC_NONE; 906 cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC); 907 COM_UNLOCK(); | 902 COM_LOCK(); 903 com->etc = ETC_NONE; 904 cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC); 905 COM_UNLOCK(); |
908 critical_exit(savecrit); | 906 critical_exit(); |
909 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 910#endif 911 912 { 913#if 0 914 outb(iobase + com_ier, 0); 915#else | 907 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 908#endif 909 910 { 911#if 0 912 outb(iobase + com_ier, 0); 913#else |
916 savecrit = critical_enter(); | 914 critical_enter(); |
917 COM_LOCK(); 918 cd_setreg(com, CD1400_SRER, com->intr_enable = 0); 919 COM_UNLOCK(); | 915 COM_LOCK(); 916 cd_setreg(com, CD1400_SRER, com->intr_enable = 0); 917 COM_UNLOCK(); |
920 critical_exit(savecrit); | 918 critical_exit(); |
921#endif 922 tp = com->tp; 923 if ((tp->t_cflag & HUPCL) 924 /* 925 * XXX we will miss any carrier drop between here and the 926 * next open. Perhaps we should watch DCD even when the 927 * port is closed; it is not sufficient to check it at 928 * the next open because it might go up and down while --- 79 unchanged lines hidden (view full) --- 1008} 1009 1010/* 1011 * This function: 1012 * a) needs to be called with COM_LOCK() held, and 1013 * b) needs to return with COM_LOCK() held. 1014 */ 1015static void | 919#endif 920 tp = com->tp; 921 if ((tp->t_cflag & HUPCL) 922 /* 923 * XXX we will miss any carrier drop between here and the 924 * next open. Perhaps we should watch DCD even when the 925 * port is closed; it is not sufficient to check it at 926 * the next open because it might go up and down while --- 79 unchanged lines hidden (view full) --- 1006} 1007 1008/* 1009 * This function: 1010 * a) needs to be called with COM_LOCK() held, and 1011 * b) needs to return with COM_LOCK() held. 1012 */ 1013static void |
1016sioinput(com, savecrit) | 1014sioinput(com) |
1017 struct com_s *com; | 1015 struct com_s *com; |
1018 critical_t *savecrit; | |
1019{ 1020 u_char *buf; 1021 int incc; 1022 u_char line_status; 1023 int recv_data; 1024 struct tty *tp; 1025 1026 buf = com->ibuf; --- 14 unchanged lines hidden (view full) --- 1041 1042 do { 1043 /* 1044 * This may look odd, but it is using save-and-enable 1045 * semantics instead of the save-and-disable semantics 1046 * that are used everywhere else. 1047 */ 1048 COM_UNLOCK(); | 1016{ 1017 u_char *buf; 1018 int incc; 1019 u_char line_status; 1020 int recv_data; 1021 struct tty *tp; 1022 1023 buf = com->ibuf; --- 14 unchanged lines hidden (view full) --- 1038 1039 do { 1040 /* 1041 * This may look odd, but it is using save-and-enable 1042 * semantics instead of the save-and-disable semantics 1043 * that are used everywhere else. 1044 */ 1045 COM_UNLOCK(); |
1049 critical_exit(*savecrit); | 1046 critical_exit(); |
1050 incc = com->iptr - buf; 1051 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat 1052 && (com->state & CS_RTS_IFLOW 1053 || tp->t_iflag & IXOFF) 1054 && !(tp->t_state & TS_TBLOCK)) 1055 ttyblock(tp); 1056 com->delta_error_counts[CE_TTY_BUF_OVERFLOW] 1057 += b_to_q((char *)buf, incc, &tp->t_rawq); --- 4 unchanged lines hidden (view full) --- 1062 ttwakeup(tp); 1063 if (tp->t_state & TS_TTSTOP 1064 && (tp->t_iflag & IXANY 1065 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { 1066 tp->t_state &= ~TS_TTSTOP; 1067 tp->t_lflag &= ~FLUSHO; 1068 comstart(tp); 1069 } | 1047 incc = com->iptr - buf; 1048 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat 1049 && (com->state & CS_RTS_IFLOW 1050 || tp->t_iflag & IXOFF) 1051 && !(tp->t_state & TS_TBLOCK)) 1052 ttyblock(tp); 1053 com->delta_error_counts[CE_TTY_BUF_OVERFLOW] 1054 += b_to_q((char *)buf, incc, &tp->t_rawq); --- 4 unchanged lines hidden (view full) --- 1059 ttwakeup(tp); 1060 if (tp->t_state & TS_TTSTOP 1061 && (tp->t_iflag & IXANY 1062 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { 1063 tp->t_state &= ~TS_TTSTOP; 1064 tp->t_lflag &= ~FLUSHO; 1065 comstart(tp); 1066 } |
1070 *savecrit = critical_enter(); | 1067 critical_enter(); |
1071 COM_LOCK(); 1072 } while (buf < com->iptr); 1073 } else { 1074 do { 1075 /* 1076 * This may look odd, but it is using save-and-enable 1077 * semantics instead of the save-and-disable semantics 1078 * that are used everywhere else. 1079 */ 1080 COM_UNLOCK(); | 1068 COM_LOCK(); 1069 } while (buf < com->iptr); 1070 } else { 1071 do { 1072 /* 1073 * This may look odd, but it is using save-and-enable 1074 * semantics instead of the save-and-disable semantics 1075 * that are used everywhere else. 1076 */ 1077 COM_UNLOCK(); |
1081 critical_exit(*savecrit); | 1078 critical_exit(); |
1082 line_status = buf[com->ierroff]; 1083 recv_data = *buf++; 1084 if (line_status 1085 & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) { 1086 if (line_status & LSR_BI) 1087 recv_data |= TTY_BI; 1088 if (line_status & LSR_FE) 1089 recv_data |= TTY_FE; 1090 if (line_status & LSR_OE) 1091 recv_data |= TTY_OE; 1092 if (line_status & LSR_PE) 1093 recv_data |= TTY_PE; 1094 } 1095 (*linesw[tp->t_line].l_rint)(recv_data, tp); | 1079 line_status = buf[com->ierroff]; 1080 recv_data = *buf++; 1081 if (line_status 1082 & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) { 1083 if (line_status & LSR_BI) 1084 recv_data |= TTY_BI; 1085 if (line_status & LSR_FE) 1086 recv_data |= TTY_FE; 1087 if (line_status & LSR_OE) 1088 recv_data |= TTY_OE; 1089 if (line_status & LSR_PE) 1090 recv_data |= TTY_PE; 1091 } 1092 (*linesw[tp->t_line].l_rint)(recv_data, tp); |
1096 *savecrit = critical_enter(); | 1093 critical_enter(); |
1097 COM_LOCK(); 1098 } while (buf < com->iptr); 1099 } 1100 com_events -= (com->iptr - com->ibuf); 1101 com->iptr = com->ibuf; 1102 1103 /* 1104 * There is now room for another low-level buffer full of input, --- 657 unchanged lines hidden (view full) --- 1762 splx(s); 1763 return (0); 1764} 1765 1766static void 1767siopoll(void *arg) 1768{ 1769 int unit; | 1094 COM_LOCK(); 1095 } while (buf < com->iptr); 1096 } 1097 com_events -= (com->iptr - com->ibuf); 1098 com->iptr = com->ibuf; 1099 1100 /* 1101 * There is now room for another low-level buffer full of input, --- 657 unchanged lines hidden (view full) --- 1759 splx(s); 1760 return (0); 1761} 1762 1763static void 1764siopoll(void *arg) 1765{ 1766 int unit; |
1770 critical_t savecrit; | |
1771 1772#ifdef CyDebug 1773 ++cy_timeouts; 1774#endif 1775 if (com_events == 0) 1776 return; 1777repeat: 1778 for (unit = 0; unit < NSIO; ++unit) { --- 6 unchanged lines hidden (view full) --- 1785 continue; 1786 tp = com->tp; 1787 if (tp == NULL) { 1788 /* 1789 * XXX forget any events related to closed devices 1790 * (actually never opened devices) so that we don't 1791 * loop. 1792 */ | 1767 1768#ifdef CyDebug 1769 ++cy_timeouts; 1770#endif 1771 if (com_events == 0) 1772 return; 1773repeat: 1774 for (unit = 0; unit < NSIO; ++unit) { --- 6 unchanged lines hidden (view full) --- 1781 continue; 1782 tp = com->tp; 1783 if (tp == NULL) { 1784 /* 1785 * XXX forget any events related to closed devices 1786 * (actually never opened devices) so that we don't 1787 * loop. 1788 */ |
1793 savecrit = critical_enter(); | 1789 critical_enter(); |
1794 COM_LOCK(); 1795 incc = com->iptr - com->ibuf; 1796 com->iptr = com->ibuf; 1797 if (com->state & CS_CHECKMSR) { 1798 incc += LOTS_OF_EVENTS; 1799 com->state &= ~CS_CHECKMSR; 1800 } 1801 com_events -= incc; 1802 COM_UNLOCK(); | 1790 COM_LOCK(); 1791 incc = com->iptr - com->ibuf; 1792 com->iptr = com->ibuf; 1793 if (com->state & CS_CHECKMSR) { 1794 incc += LOTS_OF_EVENTS; 1795 com->state &= ~CS_CHECKMSR; 1796 } 1797 com_events -= incc; 1798 COM_UNLOCK(); |
1803 critical_exit(savecrit); | 1799 critical_exit(); |
1804 if (incc != 0) 1805 log(LOG_DEBUG, 1806 "sio%d: %d events for device with no tp\n", 1807 unit, incc); 1808 continue; 1809 } 1810 if (com->iptr != com->ibuf) { | 1800 if (incc != 0) 1801 log(LOG_DEBUG, 1802 "sio%d: %d events for device with no tp\n", 1803 unit, incc); 1804 continue; 1805 } 1806 if (com->iptr != com->ibuf) { |
1811 savecrit = critical_enter(); | 1807 critical_enter(); |
1812 COM_LOCK(); | 1808 COM_LOCK(); |
1813 sioinput(com, &savecrit); | 1809 sioinput(com); |
1814 COM_UNLOCK(); | 1810 COM_UNLOCK(); |
1815 critical_exit(savecrit); | 1811 critical_exit(); |
1816 } 1817 if (com->state & CS_CHECKMSR) { 1818 u_char delta_modem_status; 1819 | 1812 } 1813 if (com->state & CS_CHECKMSR) { 1814 u_char delta_modem_status; 1815 |
1820 savecrit = critical_enter(); | 1816 critical_enter(); |
1821 COM_LOCK(); | 1817 COM_LOCK(); |
1822 sioinput(com, &savecrit); | 1818 sioinput(com); |
1823 delta_modem_status = com->last_modem_status 1824 ^ com->prev_modem_status; 1825 com->prev_modem_status = com->last_modem_status; 1826 com_events -= LOTS_OF_EVENTS; 1827 com->state &= ~CS_CHECKMSR; 1828 COM_UNLOCK(); | 1819 delta_modem_status = com->last_modem_status 1820 ^ com->prev_modem_status; 1821 com->prev_modem_status = com->last_modem_status; 1822 com_events -= LOTS_OF_EVENTS; 1823 com->state &= ~CS_CHECKMSR; 1824 COM_UNLOCK(); |
1829 critical_exit(savecrit); | 1825 critical_exit(); |
1830 if (delta_modem_status & MSR_DCD) 1831 (*linesw[tp->t_line].l_modem) 1832 (tp, com->prev_modem_status & MSR_DCD); 1833 } 1834 if (com->extra_state & CSE_ODONE) { | 1826 if (delta_modem_status & MSR_DCD) 1827 (*linesw[tp->t_line].l_modem) 1828 (tp, com->prev_modem_status & MSR_DCD); 1829 } 1830 if (com->extra_state & CSE_ODONE) { |
1835 savecrit = critical_enter(); | 1831 critical_enter(); |
1836 COM_LOCK(); 1837 com_events -= LOTS_OF_EVENTS; 1838 com->extra_state &= ~CSE_ODONE; 1839 COM_UNLOCK(); | 1832 COM_LOCK(); 1833 com_events -= LOTS_OF_EVENTS; 1834 com->extra_state &= ~CSE_ODONE; 1835 COM_UNLOCK(); |
1840 critical_exit(savecrit); | 1836 critical_exit(); |
1841 if (!(com->state & CS_BUSY)) { 1842 tp->t_state &= ~TS_BUSY; 1843 ttwwakeup(com->tp); 1844 } 1845 if (com->etc != ETC_NONE) { 1846 if (com->etc == ETC_BREAK_ENDED) 1847 com->etc = ETC_NONE; 1848 wakeup(&com->etc); 1849 } 1850 } 1851 if (com->state & CS_ODONE) { | 1837 if (!(com->state & CS_BUSY)) { 1838 tp->t_state &= ~TS_BUSY; 1839 ttwwakeup(com->tp); 1840 } 1841 if (com->etc != ETC_NONE) { 1842 if (com->etc == ETC_BREAK_ENDED) 1843 com->etc = ETC_NONE; 1844 wakeup(&com->etc); 1845 } 1846 } 1847 if (com->state & CS_ODONE) { |
1852 savecrit = critical_enter(); | 1848 critical_enter(); |
1853 COM_LOCK(); 1854 com_events -= LOTS_OF_EVENTS; 1855 com->state &= ~CS_ODONE; 1856 COM_UNLOCK(); | 1849 COM_LOCK(); 1850 com_events -= LOTS_OF_EVENTS; 1851 com->state &= ~CS_ODONE; 1852 COM_UNLOCK(); |
1857 critical_exit(savecrit); | 1853 critical_exit(); |
1858 (*linesw[tp->t_line].l_start)(tp); 1859 } 1860 if (com_events == 0) 1861 break; 1862 } 1863 if (com_events >= LOTS_OF_EVENTS) 1864 goto repeat; 1865} --- 12 unchanged lines hidden (view full) --- 1878 int iflag; 1879 int iprescaler; 1880 int itimeout; 1881 int odivisor; 1882 int oprescaler; 1883 u_char opt; 1884 int s; 1885 int unit; | 1854 (*linesw[tp->t_line].l_start)(tp); 1855 } 1856 if (com_events == 0) 1857 break; 1858 } 1859 if (com_events >= LOTS_OF_EVENTS) 1860 goto repeat; 1861} --- 12 unchanged lines hidden (view full) --- 1874 int iflag; 1875 int iprescaler; 1876 int itimeout; 1877 int odivisor; 1878 int oprescaler; 1879 u_char opt; 1880 int s; 1881 int unit; |
1886 critical_t savecrit; | |
1887 1888 /* do historical conversions */ 1889 if (t->c_ispeed == 0) 1890 t->c_ispeed = t->c_ospeed; 1891 1892 unit = DEV_TO_UNIT(tp->t_dev); 1893 com = com_addr(unit); 1894 --- 131 unchanged lines hidden (view full) --- 2026 opt |= CD1400_COR2_IXANY; 2027 if (iflag & IXOFF) 2028 opt |= CD1400_COR2_IXOFF; 2029#endif 2030#ifndef SOFT_CTS_OFLOW 2031 if (cflag & CCTS_OFLOW) 2032 opt |= CD1400_COR2_CCTS_OFLOW; 2033#endif | 1882 1883 /* do historical conversions */ 1884 if (t->c_ispeed == 0) 1885 t->c_ispeed = t->c_ospeed; 1886 1887 unit = DEV_TO_UNIT(tp->t_dev); 1888 com = com_addr(unit); 1889 --- 131 unchanged lines hidden (view full) --- 2021 opt |= CD1400_COR2_IXANY; 2022 if (iflag & IXOFF) 2023 opt |= CD1400_COR2_IXOFF; 2024#endif 2025#ifndef SOFT_CTS_OFLOW 2026 if (cflag & CCTS_OFLOW) 2027 opt |= CD1400_COR2_CCTS_OFLOW; 2028#endif |
2034 savecrit = critical_enter(); | 2029 critical_enter(); |
2035 COM_LOCK(); 2036 if (opt != com->cor[1]) { 2037 cor_change |= CD1400_CCR_COR2; 2038 cd_setreg(com, CD1400_COR2, com->cor[1] = opt); 2039 } 2040 COM_UNLOCK(); | 2030 COM_LOCK(); 2031 if (opt != com->cor[1]) { 2032 cor_change |= CD1400_CCR_COR2; 2033 cd_setreg(com, CD1400_COR2, com->cor[1] = opt); 2034 } 2035 COM_UNLOCK(); |
2041 critical_exit(savecrit); | 2036 critical_exit(); |
2042 2043 /* 2044 * set channel option register 3 - 2045 * receiver FIFO interrupt threshold 2046 * flow control 2047 */ 2048 opt = RxFifoThreshold; 2049#ifdef Smarts --- 104 unchanged lines hidden (view full) --- 2154 opt |= CD1400_MCOR2_CTSod; 2155#endif 2156 cd_setreg(com, CD1400_MCOR2, opt); 2157 2158 /* 2159 * XXX should have done this long ago, but there is too much state 2160 * to change all atomically. 2161 */ | 2037 2038 /* 2039 * set channel option register 3 - 2040 * receiver FIFO interrupt threshold 2041 * flow control 2042 */ 2043 opt = RxFifoThreshold; 2044#ifdef Smarts --- 104 unchanged lines hidden (view full) --- 2149 opt |= CD1400_MCOR2_CTSod; 2150#endif 2151 cd_setreg(com, CD1400_MCOR2, opt); 2152 2153 /* 2154 * XXX should have done this long ago, but there is too much state 2155 * to change all atomically. 2156 */ |
2162 savecrit = critical_enter(); | 2157 critical_enter(); |
2163 COM_LOCK(); 2164 2165 com->state &= ~CS_TTGO; 2166 if (!(tp->t_state & TS_TTSTOP)) 2167 com->state |= CS_TTGO; 2168 if (cflag & CRTS_IFLOW) { 2169 com->state |= CS_RTS_IFLOW; 2170 /* --- 51 unchanged lines hidden (view full) --- 2222 if (com->intr_enable & CD1400_SRER_TXRDY) 2223 cd_setreg(com, CD1400_SRER, 2224 com->intr_enable 2225 = (com->intr_enable & ~CD1400_SRER_TXRDY) 2226 | CD1400_SRER_TXMPTY); 2227 } 2228 2229 COM_UNLOCK(); | 2158 COM_LOCK(); 2159 2160 com->state &= ~CS_TTGO; 2161 if (!(tp->t_state & TS_TTSTOP)) 2162 com->state |= CS_TTGO; 2163 if (cflag & CRTS_IFLOW) { 2164 com->state |= CS_RTS_IFLOW; 2165 /* --- 51 unchanged lines hidden (view full) --- 2217 if (com->intr_enable & CD1400_SRER_TXRDY) 2218 cd_setreg(com, CD1400_SRER, 2219 com->intr_enable 2220 = (com->intr_enable & ~CD1400_SRER_TXRDY) 2221 | CD1400_SRER_TXMPTY); 2222 } 2223 2224 COM_UNLOCK(); |
2230 critical_exit(savecrit); | 2225 critical_exit(); |
2231 splx(s); 2232 comstart(tp); 2233 if (com->ibufold != NULL) { 2234 free(com->ibufold, M_DEVBUF); 2235 com->ibufold = NULL; 2236 } 2237 return (0); 2238} 2239 2240static int 2241siosetwater(com, speed) 2242 struct com_s *com; 2243 speed_t speed; 2244{ 2245 int cp4ticks; 2246 u_char *ibuf; 2247 int ibufsize; 2248 struct tty *tp; | 2226 splx(s); 2227 comstart(tp); 2228 if (com->ibufold != NULL) { 2229 free(com->ibufold, M_DEVBUF); 2230 com->ibufold = NULL; 2231 } 2232 return (0); 2233} 2234 2235static int 2236siosetwater(com, speed) 2237 struct com_s *com; 2238 speed_t speed; 2239{ 2240 int cp4ticks; 2241 u_char *ibuf; 2242 int ibufsize; 2243 struct tty *tp; |
2249 critical_t savecrit; | |
2250 2251 /* 2252 * Make the buffer size large enough to handle a softtty interrupt 2253 * latency of about 2 ticks without loss of throughput or data 2254 * (about 3 ticks if input flow control is not used or not honoured, 2255 * but a bit less for CS5-CS7 modes). 2256 */ 2257 cp4ticks = speed / 10 / hz * 4; --- 21 unchanged lines hidden (view full) --- 2279 tp->t_ispeedwat = (speed_t)-1; 2280 tp->t_ospeedwat = (speed_t)-1; 2281 } 2282 2283 /* 2284 * Read current input buffer, if any. Continue with interrupts 2285 * disabled. 2286 */ | 2244 2245 /* 2246 * Make the buffer size large enough to handle a softtty interrupt 2247 * latency of about 2 ticks without loss of throughput or data 2248 * (about 3 ticks if input flow control is not used or not honoured, 2249 * but a bit less for CS5-CS7 modes). 2250 */ 2251 cp4ticks = speed / 10 / hz * 4; --- 21 unchanged lines hidden (view full) --- 2273 tp->t_ispeedwat = (speed_t)-1; 2274 tp->t_ospeedwat = (speed_t)-1; 2275 } 2276 2277 /* 2278 * Read current input buffer, if any. Continue with interrupts 2279 * disabled. 2280 */ |
2287 savecrit = critical_enter(); | 2281 critical_enter(); |
2288 COM_LOCK(); 2289 if (com->iptr != com->ibuf) | 2282 COM_LOCK(); 2283 if (com->iptr != com->ibuf) |
2290 sioinput(com, &savecrit); | 2284 sioinput(com); |
2291 2292 /*- 2293 * Initialize critical variables, including input buffer watermarks. 2294 * The external device is asked to stop sending when the buffer 2295 * exactly reaches high water, or when the high level requests it. 2296 * The high level is notified immediately (rather than at a later 2297 * clock tick) when this watermark is reached. 2298 * The buffer size is chosen so the watermark should almost never 2299 * be reached. 2300 * The low watermark is invisibly 0 since the buffer is always 2301 * emptied all at once. 2302 */ 2303 com->iptr = com->ibuf = ibuf; 2304 com->ibufend = ibuf + ibufsize; 2305 com->ierroff = ibufsize; 2306 com->ihighwater = ibuf + 3 * ibufsize / 4; 2307 2308 COM_UNLOCK(); | 2285 2286 /*- 2287 * Initialize critical variables, including input buffer watermarks. 2288 * The external device is asked to stop sending when the buffer 2289 * exactly reaches high water, or when the high level requests it. 2290 * The high level is notified immediately (rather than at a later 2291 * clock tick) when this watermark is reached. 2292 * The buffer size is chosen so the watermark should almost never 2293 * be reached. 2294 * The low watermark is invisibly 0 since the buffer is always 2295 * emptied all at once. 2296 */ 2297 com->iptr = com->ibuf = ibuf; 2298 com->ibufend = ibuf + ibufsize; 2299 com->ierroff = ibufsize; 2300 com->ihighwater = ibuf + 3 * ibufsize / 4; 2301 2302 COM_UNLOCK(); |
2309 critical_exit(savecrit); | 2303 critical_exit(); |
2310 return (0); 2311} 2312 2313static void 2314comstart(tp) 2315 struct tty *tp; 2316{ 2317 struct com_s *com; 2318 int s; 2319#ifdef CyDebug 2320 bool_t started; 2321#endif 2322 int unit; | 2304 return (0); 2305} 2306 2307static void 2308comstart(tp) 2309 struct tty *tp; 2310{ 2311 struct com_s *com; 2312 int s; 2313#ifdef CyDebug 2314 bool_t started; 2315#endif 2316 int unit; |
2323 critical_t savecrit; | |
2324 2325 unit = DEV_TO_UNIT(tp->t_dev); 2326 com = com_addr(unit); 2327 s = spltty(); 2328 2329#ifdef CyDebug 2330 ++com->start_count; 2331 started = FALSE; 2332#endif 2333 | 2317 2318 unit = DEV_TO_UNIT(tp->t_dev); 2319 com = com_addr(unit); 2320 s = spltty(); 2321 2322#ifdef CyDebug 2323 ++com->start_count; 2324 started = FALSE; 2325#endif 2326 |
2334 savecrit = critical_enter(); | 2327 critical_enter(); |
2335 COM_LOCK(); 2336 if (tp->t_state & TS_TTSTOP) { 2337 com->state &= ~CS_TTGO; 2338 if (com->intr_enable & CD1400_SRER_TXRDY) 2339 cd_setreg(com, CD1400_SRER, 2340 com->intr_enable 2341 = (com->intr_enable & ~CD1400_SRER_TXRDY) 2342 | CD1400_SRER_TXMPTY); --- 21 unchanged lines hidden (view full) --- 2364#if 0 2365 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); 2366#else 2367 cd_setreg(com, com->mcr_rts_reg, 2368 com->mcr_image |= com->mcr_rts); 2369#endif 2370 } 2371 COM_UNLOCK(); | 2328 COM_LOCK(); 2329 if (tp->t_state & TS_TTSTOP) { 2330 com->state &= ~CS_TTGO; 2331 if (com->intr_enable & CD1400_SRER_TXRDY) 2332 cd_setreg(com, CD1400_SRER, 2333 com->intr_enable 2334 = (com->intr_enable & ~CD1400_SRER_TXRDY) 2335 | CD1400_SRER_TXMPTY); --- 21 unchanged lines hidden (view full) --- 2357#if 0 2358 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); 2359#else 2360 cd_setreg(com, com->mcr_rts_reg, 2361 com->mcr_image |= com->mcr_rts); 2362#endif 2363 } 2364 COM_UNLOCK(); |
2372 critical_exit(savecrit); | 2365 critical_exit(); |
2373 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { 2374 ttwwakeup(tp); 2375 splx(s); 2376 return; 2377 } 2378 if (tp->t_outq.c_cc != 0) { 2379 struct lbq *qp; 2380 struct lbq *next; 2381 2382 if (!com->obufs[0].l_queued) { 2383#ifdef CyDebug 2384 started = TRUE; 2385#endif 2386 com->obufs[0].l_tail 2387 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1, 2388 sizeof com->obuf1); 2389 com->obufs[0].l_next = NULL; 2390 com->obufs[0].l_queued = TRUE; | 2366 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { 2367 ttwwakeup(tp); 2368 splx(s); 2369 return; 2370 } 2371 if (tp->t_outq.c_cc != 0) { 2372 struct lbq *qp; 2373 struct lbq *next; 2374 2375 if (!com->obufs[0].l_queued) { 2376#ifdef CyDebug 2377 started = TRUE; 2378#endif 2379 com->obufs[0].l_tail 2380 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1, 2381 sizeof com->obuf1); 2382 com->obufs[0].l_next = NULL; 2383 com->obufs[0].l_queued = TRUE; |
2391 savecrit = critical_enter(); | 2384 critical_enter(); |
2392 COM_LOCK(); 2393 if (com->state & CS_BUSY) { 2394 qp = com->obufq.l_next; 2395 while ((next = qp->l_next) != NULL) 2396 qp = next; 2397 qp->l_next = &com->obufs[0]; 2398 } else { 2399 com->obufq.l_head = com->obufs[0].l_head; --- 4 unchanged lines hidden (view full) --- 2404 | CS_ODEVREADY)) 2405 cd_setreg(com, CD1400_SRER, 2406 com->intr_enable 2407 = (com->intr_enable 2408 & ~CD1400_SRER_TXMPTY) 2409 | CD1400_SRER_TXRDY); 2410 } 2411 COM_UNLOCK(); | 2385 COM_LOCK(); 2386 if (com->state & CS_BUSY) { 2387 qp = com->obufq.l_next; 2388 while ((next = qp->l_next) != NULL) 2389 qp = next; 2390 qp->l_next = &com->obufs[0]; 2391 } else { 2392 com->obufq.l_head = com->obufs[0].l_head; --- 4 unchanged lines hidden (view full) --- 2397 | CS_ODEVREADY)) 2398 cd_setreg(com, CD1400_SRER, 2399 com->intr_enable 2400 = (com->intr_enable 2401 & ~CD1400_SRER_TXMPTY) 2402 | CD1400_SRER_TXRDY); 2403 } 2404 COM_UNLOCK(); |
2412 critical_exit(savecrit); | 2405 critical_exit(); |
2413 } 2414 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { 2415#ifdef CyDebug 2416 started = TRUE; 2417#endif 2418 com->obufs[1].l_tail 2419 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2, 2420 sizeof com->obuf2); 2421 com->obufs[1].l_next = NULL; 2422 com->obufs[1].l_queued = TRUE; | 2406 } 2407 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { 2408#ifdef CyDebug 2409 started = TRUE; 2410#endif 2411 com->obufs[1].l_tail 2412 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2, 2413 sizeof com->obuf2); 2414 com->obufs[1].l_next = NULL; 2415 com->obufs[1].l_queued = TRUE; |
2423 savecrit = critical_enter(); | 2416 critical_enter(); |
2424 COM_LOCK(); 2425 if (com->state & CS_BUSY) { 2426 qp = com->obufq.l_next; 2427 while ((next = qp->l_next) != NULL) 2428 qp = next; 2429 qp->l_next = &com->obufs[1]; 2430 } else { 2431 com->obufq.l_head = com->obufs[1].l_head; --- 4 unchanged lines hidden (view full) --- 2436 | CS_ODEVREADY)) 2437 cd_setreg(com, CD1400_SRER, 2438 com->intr_enable 2439 = (com->intr_enable 2440 & ~CD1400_SRER_TXMPTY) 2441 | CD1400_SRER_TXRDY); 2442 } 2443 COM_UNLOCK(); | 2417 COM_LOCK(); 2418 if (com->state & CS_BUSY) { 2419 qp = com->obufq.l_next; 2420 while ((next = qp->l_next) != NULL) 2421 qp = next; 2422 qp->l_next = &com->obufs[1]; 2423 } else { 2424 com->obufq.l_head = com->obufs[1].l_head; --- 4 unchanged lines hidden (view full) --- 2429 | CS_ODEVREADY)) 2430 cd_setreg(com, CD1400_SRER, 2431 com->intr_enable 2432 = (com->intr_enable 2433 & ~CD1400_SRER_TXMPTY) 2434 | CD1400_SRER_TXRDY); 2435 } 2436 COM_UNLOCK(); |
2444 critical_exit(savecrit); | 2437 critical_exit(); |
2445 } 2446 tp->t_state |= TS_BUSY; 2447 } 2448#ifdef CyDebug 2449 if (started) 2450 ++com->start_real; 2451#endif 2452#if 0 | 2438 } 2439 tp->t_state |= TS_BUSY; 2440 } 2441#ifdef CyDebug 2442 if (started) 2443 ++com->start_real; 2444#endif 2445#if 0 |
2453 savecrit = critical_enter(); | 2446 critical_enter(); |
2454 COM_LOCK(); 2455 if (com->state >= (CS_BUSY | CS_TTGO)) 2456 siointr1(com); /* fake interrupt to start output */ 2457 COM_UNLOCK(); | 2447 COM_LOCK(); 2448 if (com->state >= (CS_BUSY | CS_TTGO)) 2449 siointr1(com); /* fake interrupt to start output */ 2450 COM_UNLOCK(); |
2458 critical_exit(savecrit); | 2451 critical_exit(); |
2459#endif 2460 ttwwakeup(tp); 2461 splx(s); 2462} 2463 2464static void 2465comstop(tp, rw) 2466 struct tty *tp; 2467 int rw; 2468{ 2469 struct com_s *com; 2470 bool_t wakeup_etc; | 2452#endif 2453 ttwwakeup(tp); 2454 splx(s); 2455} 2456 2457static void 2458comstop(tp, rw) 2459 struct tty *tp; 2460 int rw; 2461{ 2462 struct com_s *com; 2463 bool_t wakeup_etc; |
2471 critical_t savecrit; | |
2472 2473 com = com_addr(DEV_TO_UNIT(tp->t_dev)); 2474 wakeup_etc = FALSE; | 2464 2465 com = com_addr(DEV_TO_UNIT(tp->t_dev)); 2466 wakeup_etc = FALSE; |
2475 savecrit = critical_enter(); | 2467 critical_enter(); |
2476 COM_LOCK(); 2477 if (rw & FWRITE) { 2478 com->obufs[0].l_queued = FALSE; 2479 com->obufs[1].l_queued = FALSE; 2480 if (com->extra_state & CSE_ODONE) { 2481 com_events -= LOTS_OF_EVENTS; 2482 com->extra_state &= ~CSE_ODONE; 2483 if (com->etc != ETC_NONE) { --- 8 unchanged lines hidden (view full) --- 2492 com->state &= ~(CS_ODONE | CS_BUSY); 2493 } 2494 if (rw & FREAD) { 2495 /* XXX no way to reset only input fifo. */ 2496 com_events -= (com->iptr - com->ibuf); 2497 com->iptr = com->ibuf; 2498 } 2499 COM_UNLOCK(); | 2468 COM_LOCK(); 2469 if (rw & FWRITE) { 2470 com->obufs[0].l_queued = FALSE; 2471 com->obufs[1].l_queued = FALSE; 2472 if (com->extra_state & CSE_ODONE) { 2473 com_events -= LOTS_OF_EVENTS; 2474 com->extra_state &= ~CSE_ODONE; 2475 if (com->etc != ETC_NONE) { --- 8 unchanged lines hidden (view full) --- 2484 com->state &= ~(CS_ODONE | CS_BUSY); 2485 } 2486 if (rw & FREAD) { 2487 /* XXX no way to reset only input fifo. */ 2488 com_events -= (com->iptr - com->ibuf); 2489 com->iptr = com->ibuf; 2490 } 2491 COM_UNLOCK(); |
2500 critical_exit(savecrit); | 2492 critical_exit(); |
2501 if (wakeup_etc) 2502 wakeup(&com->etc); 2503 if (rw & FWRITE && com->etc == ETC_NONE) 2504 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 2505 comstart(tp); 2506} 2507 2508static int 2509commctl(com, bits, how) 2510 struct com_s *com; 2511 int bits; 2512 int how; 2513{ 2514 int mcr; 2515 int msr; | 2493 if (wakeup_etc) 2494 wakeup(&com->etc); 2495 if (rw & FWRITE && com->etc == ETC_NONE) 2496 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 2497 comstart(tp); 2498} 2499 2500static int 2501commctl(com, bits, how) 2502 struct com_s *com; 2503 int bits; 2504 int how; 2505{ 2506 int mcr; 2507 int msr; |
2516 critical_t savecrit; | |
2517 2518 if (how == DMGET) { 2519 if (com->channel_control & CD1400_CCR_RCVEN) 2520 bits |= TIOCM_LE; 2521 mcr = com->mcr_image; 2522 if (mcr & com->mcr_dtr) 2523 bits |= TIOCM_DTR; 2524 if (mcr & com->mcr_rts) --- 21 unchanged lines hidden (view full) --- 2546 bits |= TIOCM_RI; 2547 return (bits); 2548 } 2549 mcr = 0; 2550 if (bits & TIOCM_DTR) 2551 mcr |= com->mcr_dtr; 2552 if (bits & TIOCM_RTS) 2553 mcr |= com->mcr_rts; | 2508 2509 if (how == DMGET) { 2510 if (com->channel_control & CD1400_CCR_RCVEN) 2511 bits |= TIOCM_LE; 2512 mcr = com->mcr_image; 2513 if (mcr & com->mcr_dtr) 2514 bits |= TIOCM_DTR; 2515 if (mcr & com->mcr_rts) --- 21 unchanged lines hidden (view full) --- 2537 bits |= TIOCM_RI; 2538 return (bits); 2539 } 2540 mcr = 0; 2541 if (bits & TIOCM_DTR) 2542 mcr |= com->mcr_dtr; 2543 if (bits & TIOCM_RTS) 2544 mcr |= com->mcr_rts; |
2554 savecrit = critical_enter(); | 2545 critical_enter(); |
2555 COM_LOCK(); 2556 switch (how) { 2557 case DMSET: 2558 com->mcr_image = mcr; 2559 cd_setreg(com, CD1400_MSVR1, mcr); 2560 cd_setreg(com, CD1400_MSVR2, mcr); 2561 break; 2562 case DMBIS: 2563 com->mcr_image = mcr = com->mcr_image | mcr; 2564 cd_setreg(com, CD1400_MSVR1, mcr); 2565 cd_setreg(com, CD1400_MSVR2, mcr); 2566 break; 2567 case DMBIC: 2568 com->mcr_image = mcr = com->mcr_image & ~mcr; 2569 cd_setreg(com, CD1400_MSVR1, mcr); 2570 cd_setreg(com, CD1400_MSVR2, mcr); 2571 break; 2572 } 2573 COM_UNLOCK(); | 2546 COM_LOCK(); 2547 switch (how) { 2548 case DMSET: 2549 com->mcr_image = mcr; 2550 cd_setreg(com, CD1400_MSVR1, mcr); 2551 cd_setreg(com, CD1400_MSVR2, mcr); 2552 break; 2553 case DMBIS: 2554 com->mcr_image = mcr = com->mcr_image | mcr; 2555 cd_setreg(com, CD1400_MSVR1, mcr); 2556 cd_setreg(com, CD1400_MSVR2, mcr); 2557 break; 2558 case DMBIC: 2559 com->mcr_image = mcr = com->mcr_image & ~mcr; 2560 cd_setreg(com, CD1400_MSVR1, mcr); 2561 cd_setreg(com, CD1400_MSVR2, mcr); 2562 break; 2563 } 2564 COM_UNLOCK(); |
2574 critical_exit(savecrit); | 2565 critical_exit(); |
2575 return (0); 2576} 2577 2578static void 2579siosettimeout() 2580{ 2581 struct com_s *com; 2582 bool_t someopen; --- 45 unchanged lines hidden (view full) --- 2628 /* 2629 * Recover from lost output interrupts. 2630 * Poll any lines that don't use interrupts. 2631 */ 2632 for (unit = 0; unit < NSIO; ++unit) { 2633 com = com_addr(unit); 2634 if (com != NULL 2635 && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { | 2566 return (0); 2567} 2568 2569static void 2570siosettimeout() 2571{ 2572 struct com_s *com; 2573 bool_t someopen; --- 45 unchanged lines hidden (view full) --- 2619 /* 2620 * Recover from lost output interrupts. 2621 * Poll any lines that don't use interrupts. 2622 */ 2623 for (unit = 0; unit < NSIO; ++unit) { 2624 com = com_addr(unit); 2625 if (com != NULL 2626 && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { |
2636 critical_t savecrit; 2637 2638 savecrit = critical_enter(); | 2627 critical_enter(); |
2639 COM_LOCK(); 2640 siointr1(com); 2641 COM_UNLOCK(); | 2628 COM_LOCK(); 2629 siointr1(com); 2630 COM_UNLOCK(); |
2642 critical_exit(savecrit); | 2631 critical_exit(); |
2643 } 2644 } 2645#endif 2646 2647 /* 2648 * Check for and log errors, but not too often. 2649 */ 2650 if (--sio_timeouts_until_log > 0) 2651 return; 2652 sio_timeouts_until_log = hz / sio_timeout; 2653 for (unit = 0; unit < NSIO; ++unit) { 2654 int errnum; 2655 2656 com = com_addr(unit); 2657 if (com == NULL) 2658 continue; 2659 for (errnum = 0; errnum < CE_NTYPES; ++errnum) { 2660 u_int delta; 2661 u_long total; | 2632 } 2633 } 2634#endif 2635 2636 /* 2637 * Check for and log errors, but not too often. 2638 */ 2639 if (--sio_timeouts_until_log > 0) 2640 return; 2641 sio_timeouts_until_log = hz / sio_timeout; 2642 for (unit = 0; unit < NSIO; ++unit) { 2643 int errnum; 2644 2645 com = com_addr(unit); 2646 if (com == NULL) 2647 continue; 2648 for (errnum = 0; errnum < CE_NTYPES; ++errnum) { 2649 u_int delta; 2650 u_long total; |
2662 critical_t savecrit; | |
2663 | 2651 |
2664 savecrit = critical_enter(); | 2652 critical_enter(); |
2665 COM_LOCK(); 2666 delta = com->delta_error_counts[errnum]; 2667 com->delta_error_counts[errnum] = 0; 2668 COM_UNLOCK(); | 2653 COM_LOCK(); 2654 delta = com->delta_error_counts[errnum]; 2655 com->delta_error_counts[errnum] = 0; 2656 COM_UNLOCK(); |
2669 critical_exit(savecrit); | 2657 critical_exit(); |
2670 if (delta == 0) 2671 continue; 2672 total = com->error_counts[errnum] += delta; 2673 log(LOG_ERR, "cy%d: %u more %s%s (total %lu)\n", 2674 unit, delta, error_desc[errnum], 2675 delta == 1 ? "" : "s", total); 2676 } 2677 } --- 135 unchanged lines hidden (view full) --- 2813 } 2814} 2815 2816static void 2817cd_etc(com, etc) 2818 struct com_s *com; 2819 int etc; 2820{ | 2658 if (delta == 0) 2659 continue; 2660 total = com->error_counts[errnum] += delta; 2661 log(LOG_ERR, "cy%d: %u more %s%s (total %lu)\n", 2662 unit, delta, error_desc[errnum], 2663 delta == 1 ? "" : "s", total); 2664 } 2665 } --- 135 unchanged lines hidden (view full) --- 2801 } 2802} 2803 2804static void 2805cd_etc(com, etc) 2806 struct com_s *com; 2807 int etc; 2808{ |
2821 critical_t savecrit; | |
2822 2823 /* 2824 * We can't change the hardware's ETC state while there are any 2825 * characters in the tx fifo, since those characters would be 2826 * interpreted as commands! Unputting characters from the fifo 2827 * is difficult, so we wait up to 12 character times for the fifo 2828 * to drain. The command will be delayed for up to 2 character 2829 * times for the tx to become empty. Unputting characters from 2830 * the tx holding and shift registers is impossible, so we wait 2831 * for the tx to become empty so that the command is sure to be 2832 * executed soon after we issue it. 2833 */ | 2809 2810 /* 2811 * We can't change the hardware's ETC state while there are any 2812 * characters in the tx fifo, since those characters would be 2813 * interpreted as commands! Unputting characters from the fifo 2814 * is difficult, so we wait up to 12 character times for the fifo 2815 * to drain. The command will be delayed for up to 2 character 2816 * times for the tx to become empty. Unputting characters from 2817 * the tx holding and shift registers is impossible, so we wait 2818 * for the tx to become empty so that the command is sure to be 2819 * executed soon after we issue it. 2820 */ |
2834 savecrit = critical_enter(); | 2821 critical_enter(); |
2835 COM_LOCK(); 2836 if (com->etc == etc) 2837 goto wait; 2838 if ((etc == CD1400_ETC_SENDBREAK 2839 && (com->etc == ETC_BREAK_STARTING 2840 || com->etc == ETC_BREAK_STARTED)) 2841 || (etc == CD1400_ETC_STOPBREAK 2842 && (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED 2843 || com->etc == ETC_NONE))) { 2844 COM_UNLOCK(); | 2822 COM_LOCK(); 2823 if (com->etc == etc) 2824 goto wait; 2825 if ((etc == CD1400_ETC_SENDBREAK 2826 && (com->etc == ETC_BREAK_STARTING 2827 || com->etc == ETC_BREAK_STARTED)) 2828 || (etc == CD1400_ETC_STOPBREAK 2829 && (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED 2830 || com->etc == ETC_NONE))) { 2831 COM_UNLOCK(); |
2845 critical_exit(savecrit); | 2832 critical_exit(); |
2846 return; 2847 } 2848 com->etc = etc; 2849 cd_setreg(com, CD1400_SRER, 2850 com->intr_enable 2851 = (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY); 2852wait: 2853 COM_UNLOCK(); | 2833 return; 2834 } 2835 com->etc = etc; 2836 cd_setreg(com, CD1400_SRER, 2837 com->intr_enable 2838 = (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY); 2839wait: 2840 COM_UNLOCK(); |
2854 critical_exit(savecrit); | 2841 critical_exit(); |
2855 while (com->etc == etc 2856 && tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0) 2857 continue; 2858} 2859 2860static int 2861cd_getreg(com, reg) 2862 struct com_s *com; 2863 int reg; 2864{ 2865 struct com_s *basecom; 2866 u_char car; 2867 int cy_align; | 2842 while (com->etc == etc 2843 && tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0) 2844 continue; 2845} 2846 2847static int 2848cd_getreg(com, reg) 2849 struct com_s *com; 2850 int reg; 2851{ 2852 struct com_s *basecom; 2853 u_char car; 2854 int cy_align; |
2868 critical_t savecrit; | |
2869 register_t eflags; 2870 cy_addr iobase; 2871 int val; 2872 2873 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1)); 2874 car = com->unit & CD1400_CAR_CHAN; 2875 cy_align = com->cy_align; 2876 iobase = com->iobase; 2877 eflags = read_eflags(); | 2855 register_t eflags; 2856 cy_addr iobase; 2857 int val; 2858 2859 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1)); 2860 car = com->unit & CD1400_CAR_CHAN; 2861 cy_align = com->cy_align; 2862 iobase = com->iobase; 2863 eflags = read_eflags(); |
2878 savecrit = critical_enter(); | 2864 critical_enter(); |
2879 if (eflags & PSL_I) 2880 COM_LOCK(); 2881 if (basecom->car != car) 2882 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car); 2883 val = cd_inb(iobase, reg, cy_align); 2884 if (eflags & PSL_I) 2885 COM_UNLOCK(); | 2865 if (eflags & PSL_I) 2866 COM_LOCK(); 2867 if (basecom->car != car) 2868 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car); 2869 val = cd_inb(iobase, reg, cy_align); 2870 if (eflags & PSL_I) 2871 COM_UNLOCK(); |
2886 critical_exit(savecrit); | 2872 critical_exit(); |
2887 return (val); 2888} 2889 2890static void 2891cd_setreg(com, reg, val) 2892 struct com_s *com; 2893 int reg; 2894 int val; 2895{ 2896 struct com_s *basecom; 2897 u_char car; 2898 int cy_align; | 2873 return (val); 2874} 2875 2876static void 2877cd_setreg(com, reg, val) 2878 struct com_s *com; 2879 int reg; 2880 int val; 2881{ 2882 struct com_s *basecom; 2883 u_char car; 2884 int cy_align; |
2899 critical_t savecrit; | |
2900 register_t eflags; 2901 cy_addr iobase; 2902 2903 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1)); 2904 car = com->unit & CD1400_CAR_CHAN; 2905 cy_align = com->cy_align; 2906 iobase = com->iobase; 2907 eflags = read_eflags(); | 2885 register_t eflags; 2886 cy_addr iobase; 2887 2888 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1)); 2889 car = com->unit & CD1400_CAR_CHAN; 2890 cy_align = com->cy_align; 2891 iobase = com->iobase; 2892 eflags = read_eflags(); |
2908 savecrit = critical_enter(); | 2893 critical_enter(); |
2909 if (eflags & PSL_I) 2910 COM_LOCK(); 2911 if (basecom->car != car) 2912 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car); 2913 cd_outb(iobase, reg, cy_align, val); 2914 if (eflags & PSL_I) 2915 COM_UNLOCK(); | 2894 if (eflags & PSL_I) 2895 COM_LOCK(); 2896 if (basecom->car != car) 2897 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car); 2898 cd_outb(iobase, reg, cy_align, val); 2899 if (eflags & PSL_I) 2900 COM_UNLOCK(); |
2916 critical_exit(savecrit); | 2901 critical_exit(); |
2917} 2918 2919#ifdef CyDebug 2920/* useful in ddb */ 2921void 2922cystatus(unit) 2923 int unit; 2924{ --- 54 unchanged lines hidden --- | 2902} 2903 2904#ifdef CyDebug 2905/* useful in ddb */ 2906void 2907cystatus(unit) 2908 int unit; 2909{ --- 54 unchanged lines hidden --- |