cy.c (61011) | cy.c (65557) |
---|---|
1/*- 2 * cyclades cyclom-y serial driver 3 * Andrew Herbert <andrew@werple.apana.org.au>, 17 August 1993 4 * 5 * Copyright (c) 1993 Andrew Herbert. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 13 unchanged lines hidden (view full) --- 22 * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * | 1/*- 2 * cyclades cyclom-y serial driver 3 * Andrew Herbert <andrew@werple.apana.org.au>, 17 August 1993 4 * 5 * Copyright (c) 1993 Andrew Herbert. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 13 unchanged lines hidden (view full) --- 22 * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * |
30 * $FreeBSD: head/sys/dev/cy/cy.c 61011 2000-05-28 13:40:48Z peter $ | 30 * $FreeBSD: head/sys/dev/cy/cy.c 65557 2000-09-07 01:33:02Z jasone $ |
31 */ 32 33#include "opt_compat.h" 34#include "cy.h" 35 36/* 37 * TODO: 38 * Atomic COR change. --- 50 unchanged lines hidden (view full) --- 89#include <i386/isa/isa_device.h> 90#include <i386/isa/cyreg.h> 91#include <i386/isa/ic/cd1400.h> 92 93#ifndef COMPAT_OLDISA 94#error "The cy device requires the old isa compatibility shims" 95#endif 96 | 31 */ 32 33#include "opt_compat.h" 34#include "cy.h" 35 36/* 37 * TODO: 38 * Atomic COR change. --- 50 unchanged lines hidden (view full) --- 89#include <i386/isa/isa_device.h> 90#include <i386/isa/cyreg.h> 91#include <i386/isa/ic/cd1400.h> 92 93#ifndef COMPAT_OLDISA 94#error "The cy device requires the old isa compatibility shims" 95#endif 96 |
97#ifdef SMP 98#define disable_intr() COM_DISABLE_INTR() 99#define enable_intr() COM_ENABLE_INTR() 100#endif /* SMP */ 101 | |
102/* 103 * Dictionary so that I can name everything *sio* or *com* to compare with 104 * sio.c. There is also lots of ugly formatting and unnecessary ifdefs to 105 * simplify the comparision. These will go away. 106 */ 107#define LSR_BI CD1400_RDSR_BREAK 108#define LSR_FE CD1400_RDSR_FE 109#define LSR_OE CD1400_RDSR_OE --- 251 unchanged lines hidden (view full) --- 361 362static char driver_name[] = "cy"; 363 364/* table and macro for fast conversion from a unit number to its com struct */ 365static struct com_s *p_com_addr[NSIO]; 366#define com_addr(unit) (p_com_addr[unit]) 367 368struct isa_driver siodriver = { | 97/* 98 * Dictionary so that I can name everything *sio* or *com* to compare with 99 * sio.c. There is also lots of ugly formatting and unnecessary ifdefs to 100 * simplify the comparision. These will go away. 101 */ 102#define LSR_BI CD1400_RDSR_BREAK 103#define LSR_FE CD1400_RDSR_FE 104#define LSR_OE CD1400_RDSR_OE --- 251 unchanged lines hidden (view full) --- 356 357static char driver_name[] = "cy"; 358 359/* table and macro for fast conversion from a unit number to its com struct */ 360static struct com_s *p_com_addr[NSIO]; 361#define com_addr(unit) (p_com_addr[unit]) 362 363struct isa_driver siodriver = { |
369 INTR_TYPE_TTY | INTR_TYPE_FAST, | 364 INTR_TYPE_TTY | INTR_FAST, |
370 sioprobe, 371 sioattach, 372 driver_name 373}; 374COMPAT_ISA_DRIVER(cy, cydriver); /* XXX */ 375 376static d_open_t sioopen; 377static d_close_t sioclose; --- 221 unchanged lines hidden (view full) --- 599 if (unit == comconsole) { 600 com->it_in.c_iflag = TTYDEF_IFLAG; 601 com->it_in.c_oflag = TTYDEF_OFLAG; 602 com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL; 603 com->it_in.c_lflag = TTYDEF_LFLAG; 604 com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL; 605 } 606 if (siosetwater(com, com->it_in.c_ispeed) != 0) { | 365 sioprobe, 366 sioattach, 367 driver_name 368}; 369COMPAT_ISA_DRIVER(cy, cydriver); /* XXX */ 370 371static d_open_t sioopen; 372static d_close_t sioclose; --- 221 unchanged lines hidden (view full) --- 594 if (unit == comconsole) { 595 com->it_in.c_iflag = TTYDEF_IFLAG; 596 com->it_in.c_oflag = TTYDEF_OFLAG; 597 com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL; 598 com->it_in.c_lflag = TTYDEF_LFLAG; 599 com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL; 600 } 601 if (siosetwater(com, com->it_in.c_ispeed) != 0) { |
607 enable_intr(); | |
608 free(com, M_DEVBUF); 609 return (0); 610 } | 602 free(com, M_DEVBUF); 603 return (0); 604 } |
611 enable_intr(); | |
612 termioschars(&com->it_in); 613 com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate; 614 com->it_out = com->it_in; 615 616 s = spltty(); 617 com_addr(unit) = com; 618 splx(s); 619 --- 37 unchanged lines hidden (view full) --- 657 struct proc *p; 658{ 659 struct com_s *com; 660 int error; 661 int mynor; 662 int s; 663 struct tty *tp; 664 int unit; | 605 termioschars(&com->it_in); 606 com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate; 607 com->it_out = com->it_in; 608 609 s = spltty(); 610 com_addr(unit) = com; 611 splx(s); 612 --- 37 unchanged lines hidden (view full) --- 650 struct proc *p; 651{ 652 struct com_s *com; 653 int error; 654 int mynor; 655 int s; 656 struct tty *tp; 657 int unit; |
658 int intrsave; |
|
665 666 mynor = minor(dev); 667 unit = MINOR_TO_UNIT(mynor); 668 if ((u_int) unit >= NSIO || (com = com_addr(unit)) == NULL) 669 return (ENXIO); 670 if (mynor & CONTROL_MASK) 671 return (0); 672#if 0 /* XXX */ --- 90 unchanged lines hidden (view full) --- 763 if (!(inb(com->line_status_port) & LSR_RXRDY)) 764 break; 765 outb(iobase + com_fifo, 0); 766 DELAY(100); 767 (void) inb(com->data_port); 768 } 769 } 770 | 659 660 mynor = minor(dev); 661 unit = MINOR_TO_UNIT(mynor); 662 if ((u_int) unit >= NSIO || (com = com_addr(unit)) == NULL) 663 return (ENXIO); 664 if (mynor & CONTROL_MASK) 665 return (0); 666#if 0 /* XXX */ --- 90 unchanged lines hidden (view full) --- 757 if (!(inb(com->line_status_port) & LSR_RXRDY)) 758 break; 759 outb(iobase + com_fifo, 0); 760 DELAY(100); 761 (void) inb(com->data_port); 762 } 763 } 764 |
765 intrsave = save_intr(); |
|
771 disable_intr(); | 766 disable_intr(); |
767 COM_LOCK(); |
|
772 (void) inb(com->line_status_port); 773 (void) inb(com->data_port); 774 com->prev_modem_status = com->last_modem_status 775 = inb(com->modem_status_port); 776 outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS 777 | IER_EMSC); | 768 (void) inb(com->line_status_port); 769 (void) inb(com->data_port); 770 com->prev_modem_status = com->last_modem_status 771 = inb(com->modem_status_port); 772 outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS 773 | IER_EMSC); |
778 enable_intr(); | 774 COM_UNLOCK(); 775 restore_intr(intrsave); |
779#else /* !0 */ 780 /* 781 * Flush fifos. This requires a full channel reset which 782 * also disables the transmitter and receiver. Recover 783 * from this. 784 */ 785 cd1400_channel_cmd(com, 786 CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET); 787 cd1400_channel_cmd(com, com->channel_control); 788 | 776#else /* !0 */ 777 /* 778 * Flush fifos. This requires a full channel reset which 779 * also disables the transmitter and receiver. Recover 780 * from this. 781 */ 782 cd1400_channel_cmd(com, 783 CD1400_CCR_CMDRESET | CD1400_CCR_CHANRESET); 784 cd1400_channel_cmd(com, com->channel_control); 785 |
786 intrsave = save_intr(); |
|
789 disable_intr(); | 787 disable_intr(); |
788 COM_LOCK(); |
|
790 com->prev_modem_status = com->last_modem_status 791 = cd_getreg(com, CD1400_MSVR2); 792 cd_setreg(com, CD1400_SRER, 793 com->intr_enable 794 = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA); | 789 com->prev_modem_status = com->last_modem_status 790 = cd_getreg(com, CD1400_MSVR2); 791 cd_setreg(com, CD1400_SRER, 792 com->intr_enable 793 = CD1400_SRER_MDMCH | CD1400_SRER_RXDATA); |
795 enable_intr(); | 794 COM_UNLOCK(); 795 restore_intr(intrsave); |
796#endif /* 0 */ 797 /* 798 * Handle initial DCD. Callout devices get a fake initial 799 * DCD (trapdoor DCD). If we are callout, then any sleeping 800 * callin opens get woken up and resume sleeping on "cybi" 801 * instead of "cydcd". 802 */ 803 /* --- 66 unchanged lines hidden (view full) --- 870static void 871comhardclose(com) 872 struct com_s *com; 873{ 874 cy_addr iobase; 875 int s; 876 struct tty *tp; 877 int unit; | 796#endif /* 0 */ 797 /* 798 * Handle initial DCD. Callout devices get a fake initial 799 * DCD (trapdoor DCD). If we are callout, then any sleeping 800 * callin opens get woken up and resume sleeping on "cybi" 801 * instead of "cydcd". 802 */ 803 /* --- 66 unchanged lines hidden (view full) --- 870static void 871comhardclose(com) 872 struct com_s *com; 873{ 874 cy_addr iobase; 875 int s; 876 struct tty *tp; 877 int unit; |
878 int intrsave; |
|
878 879 unit = com->unit; 880 iobase = com->iobase; 881 s = spltty(); 882#if 0 883 com->poll = FALSE; 884 com->poll_output = FALSE; 885#endif 886 com->do_timestamp = 0; 887#if 0 888 outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK); 889#else 890 /* XXX */ | 879 880 unit = com->unit; 881 iobase = com->iobase; 882 s = spltty(); 883#if 0 884 com->poll = FALSE; 885 com->poll_output = FALSE; 886#endif 887 com->do_timestamp = 0; 888#if 0 889 outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK); 890#else 891 /* XXX */ |
892 intrsave = save_intr(); |
|
891 disable_intr(); | 893 disable_intr(); |
894 COM_LOCK(); |
|
892 com->etc = ETC_NONE; 893 cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC); | 895 com->etc = ETC_NONE; 896 cd_setreg(com, CD1400_COR2, com->cor[1] &= ~CD1400_COR2_ETC); |
894 enable_intr(); | 897 COM_UNLOCK(); 898 restore_intr(intrsave); |
895 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 896#endif 897 898 { 899#if 0 900 outb(iobase + com_ier, 0); 901#else | 899 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 900#endif 901 902 { 903#if 0 904 outb(iobase + com_ier, 0); 905#else |
906 intrsave = save_intr(); |
|
902 disable_intr(); | 907 disable_intr(); |
908 COM_LOCK(); |
|
903 cd_setreg(com, CD1400_SRER, com->intr_enable = 0); | 909 cd_setreg(com, CD1400_SRER, com->intr_enable = 0); |
904 enable_intr(); | 910 COM_UNLOCK(); 911 restore_intr(intrsave); |
905#endif 906 tp = com->tp; 907 if ((tp->t_cflag & HUPCL) 908 /* 909 * XXX we will miss any carrier drop between here and the 910 * next open. Perhaps we should watch DCD even when the 911 * port is closed; it is not sufficient to check it at 912 * the next open because it might go up and down while --- 73 unchanged lines hidden (view full) --- 986{ 987 struct com_s *com; 988 989 com = (struct com_s *)chan; 990 com->state &= ~CS_DTR_OFF; 991 wakeup(&com->dtr_wait); 992} 993 | 912#endif 913 tp = com->tp; 914 if ((tp->t_cflag & HUPCL) 915 /* 916 * XXX we will miss any carrier drop between here and the 917 * next open. Perhaps we should watch DCD even when the 918 * port is closed; it is not sufficient to check it at 919 * the next open because it might go up and down while --- 73 unchanged lines hidden (view full) --- 993{ 994 struct com_s *com; 995 996 com = (struct com_s *)chan; 997 com->state &= ~CS_DTR_OFF; 998 wakeup(&com->dtr_wait); 999} 1000 |
1001/* 1002 * This function: 1003 * a) needs to be called with COM_LOCK() held, and 1004 * b) needs to return with COM_LOCK() held. 1005 */ |
|
994static void 995sioinput(com) 996 struct com_s *com; 997{ 998 u_char *buf; 999 int incc; 1000 u_char line_status; 1001 int recv_data; 1002 struct tty *tp; | 1006static void 1007sioinput(com) 1008 struct com_s *com; 1009{ 1010 u_char *buf; 1011 int incc; 1012 u_char line_status; 1013 int recv_data; 1014 struct tty *tp; |
1015 int intrsave; |
|
1003 1004 buf = com->ibuf; 1005 tp = com->tp; 1006 if (!(tp->t_state & TS_ISOPEN)) { 1007 com_events -= (com->iptr - com->ibuf); 1008 com->iptr = com->ibuf; 1009 return; 1010 } 1011 if (tp->t_state & TS_CAN_BYPASS_L_RINT) { 1012 /* 1013 * Avoid the grotesquely inefficient lineswitch routine 1014 * (ttyinput) in "raw" mode. It usually takes about 450 1015 * instructions (that's without canonical processing or echo!). 1016 * slinput is reasonably fast (usually 40 instructions plus 1017 * call overhead). 1018 */ | 1016 1017 buf = com->ibuf; 1018 tp = com->tp; 1019 if (!(tp->t_state & TS_ISOPEN)) { 1020 com_events -= (com->iptr - com->ibuf); 1021 com->iptr = com->ibuf; 1022 return; 1023 } 1024 if (tp->t_state & TS_CAN_BYPASS_L_RINT) { 1025 /* 1026 * Avoid the grotesquely inefficient lineswitch routine 1027 * (ttyinput) in "raw" mode. It usually takes about 450 1028 * instructions (that's without canonical processing or echo!). 1029 * slinput is reasonably fast (usually 40 instructions plus 1030 * call overhead). 1031 */ |
1032 |
|
1019 do { | 1033 do { |
1034 /* 1035 * This may look odd, but it is using save-and-enable 1036 * semantics instead of the save-and-disable semantics 1037 * that are used everywhere else. 1038 */ 1039 intrsave = save_intr(); 1040 COM_UNLOCK(); |
|
1020 enable_intr(); 1021 incc = com->iptr - buf; 1022 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat 1023 && (com->state & CS_RTS_IFLOW 1024 || tp->t_iflag & IXOFF) 1025 && !(tp->t_state & TS_TBLOCK)) 1026 ttyblock(tp); 1027 com->delta_error_counts[CE_TTY_BUF_OVERFLOW] --- 5 unchanged lines hidden (view full) --- 1033 ttwakeup(tp); 1034 if (tp->t_state & TS_TTSTOP 1035 && (tp->t_iflag & IXANY 1036 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { 1037 tp->t_state &= ~TS_TTSTOP; 1038 tp->t_lflag &= ~FLUSHO; 1039 comstart(tp); 1040 } | 1041 enable_intr(); 1042 incc = com->iptr - buf; 1043 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat 1044 && (com->state & CS_RTS_IFLOW 1045 || tp->t_iflag & IXOFF) 1046 && !(tp->t_state & TS_TBLOCK)) 1047 ttyblock(tp); 1048 com->delta_error_counts[CE_TTY_BUF_OVERFLOW] --- 5 unchanged lines hidden (view full) --- 1054 ttwakeup(tp); 1055 if (tp->t_state & TS_TTSTOP 1056 && (tp->t_iflag & IXANY 1057 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { 1058 tp->t_state &= ~TS_TTSTOP; 1059 tp->t_lflag &= ~FLUSHO; 1060 comstart(tp); 1061 } |
1041 disable_intr(); | 1062 restore_intr(intrsave); 1063 COM_LOCK(); |
1042 } while (buf < com->iptr); 1043 } else { 1044 do { | 1064 } while (buf < com->iptr); 1065 } else { 1066 do { |
1067 /* 1068 * This may look odd, but it is using save-and-enable 1069 * semantics instead of the save-and-disable semantics 1070 * that are used everywhere else. 1071 */ 1072 intrsave = save_intr(); 1073 COM_UNLOCK(); |
|
1045 enable_intr(); 1046 line_status = buf[com->ierroff]; 1047 recv_data = *buf++; 1048 if (line_status 1049 & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) { 1050 if (line_status & LSR_BI) 1051 recv_data |= TTY_BI; 1052 if (line_status & LSR_FE) 1053 recv_data |= TTY_FE; 1054 if (line_status & LSR_OE) 1055 recv_data |= TTY_OE; 1056 if (line_status & LSR_PE) 1057 recv_data |= TTY_PE; 1058 } 1059 (*linesw[tp->t_line].l_rint)(recv_data, tp); | 1074 enable_intr(); 1075 line_status = buf[com->ierroff]; 1076 recv_data = *buf++; 1077 if (line_status 1078 & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) { 1079 if (line_status & LSR_BI) 1080 recv_data |= TTY_BI; 1081 if (line_status & LSR_FE) 1082 recv_data |= TTY_FE; 1083 if (line_status & LSR_OE) 1084 recv_data |= TTY_OE; 1085 if (line_status & LSR_PE) 1086 recv_data |= TTY_PE; 1087 } 1088 (*linesw[tp->t_line].l_rint)(recv_data, tp); |
1060 disable_intr(); | 1089 restore_intr(intrsave); 1090 COM_LOCK(); |
1061 } while (buf < com->iptr); 1062 } 1063 com_events -= (com->iptr - com->ibuf); 1064 com->iptr = com->ibuf; 1065 1066 /* 1067 * There is now room for another low-level buffer full of input, 1068 * so enable RTS if it is now disabled and there is room in the --- 655 unchanged lines hidden (view full) --- 1724 splx(s); 1725 return (0); 1726} 1727 1728static void 1729siopoll() 1730{ 1731 int unit; | 1091 } while (buf < com->iptr); 1092 } 1093 com_events -= (com->iptr - com->ibuf); 1094 com->iptr = com->ibuf; 1095 1096 /* 1097 * There is now room for another low-level buffer full of input, 1098 * so enable RTS if it is now disabled and there is room in the --- 655 unchanged lines hidden (view full) --- 1754 splx(s); 1755 return (0); 1756} 1757 1758static void 1759siopoll() 1760{ 1761 int unit; |
1762 int intrsave; |
|
1732 1733#ifdef CyDebug 1734 ++cy_timeouts; 1735#endif 1736 if (com_events == 0) 1737 return; 1738repeat: 1739 for (unit = 0; unit < NSIO; ++unit) { --- 6 unchanged lines hidden (view full) --- 1746 continue; 1747 tp = com->tp; 1748 if (tp == NULL) { 1749 /* 1750 * XXX forget any events related to closed devices 1751 * (actually never opened devices) so that we don't 1752 * loop. 1753 */ | 1763 1764#ifdef CyDebug 1765 ++cy_timeouts; 1766#endif 1767 if (com_events == 0) 1768 return; 1769repeat: 1770 for (unit = 0; unit < NSIO; ++unit) { --- 6 unchanged lines hidden (view full) --- 1777 continue; 1778 tp = com->tp; 1779 if (tp == NULL) { 1780 /* 1781 * XXX forget any events related to closed devices 1782 * (actually never opened devices) so that we don't 1783 * loop. 1784 */ |
1785 intrsave = save_intr(); |
|
1754 disable_intr(); | 1786 disable_intr(); |
1787 COM_LOCK(); |
|
1755 incc = com->iptr - com->ibuf; 1756 com->iptr = com->ibuf; 1757 if (com->state & CS_CHECKMSR) { 1758 incc += LOTS_OF_EVENTS; 1759 com->state &= ~CS_CHECKMSR; 1760 } 1761 com_events -= incc; | 1788 incc = com->iptr - com->ibuf; 1789 com->iptr = com->ibuf; 1790 if (com->state & CS_CHECKMSR) { 1791 incc += LOTS_OF_EVENTS; 1792 com->state &= ~CS_CHECKMSR; 1793 } 1794 com_events -= incc; |
1762 enable_intr(); | 1795 COM_UNLOCK(); 1796 restore_intr(intrsave); |
1763 if (incc != 0) 1764 log(LOG_DEBUG, 1765 "sio%d: %d events for device with no tp\n", 1766 unit, incc); 1767 continue; 1768 } 1769 if (com->iptr != com->ibuf) { | 1797 if (incc != 0) 1798 log(LOG_DEBUG, 1799 "sio%d: %d events for device with no tp\n", 1800 unit, incc); 1801 continue; 1802 } 1803 if (com->iptr != com->ibuf) { |
1804 intrsave = save_intr(); |
|
1770 disable_intr(); | 1805 disable_intr(); |
1806 COM_LOCK(); |
|
1771 sioinput(com); | 1807 sioinput(com); |
1772 enable_intr(); | 1808 COM_UNLOCK(); 1809 restore_intr(intrsave); |
1773 } 1774 if (com->state & CS_CHECKMSR) { 1775 u_char delta_modem_status; 1776 | 1810 } 1811 if (com->state & CS_CHECKMSR) { 1812 u_char delta_modem_status; 1813 |
1814 intrsave = save_intr(); |
|
1777 disable_intr(); | 1815 disable_intr(); |
1816 COM_LOCK(); 1817 sioinput(com); |
|
1778 delta_modem_status = com->last_modem_status 1779 ^ com->prev_modem_status; 1780 com->prev_modem_status = com->last_modem_status; 1781 com_events -= LOTS_OF_EVENTS; 1782 com->state &= ~CS_CHECKMSR; | 1818 delta_modem_status = com->last_modem_status 1819 ^ com->prev_modem_status; 1820 com->prev_modem_status = com->last_modem_status; 1821 com_events -= LOTS_OF_EVENTS; 1822 com->state &= ~CS_CHECKMSR; |
1783 enable_intr(); | 1823 COM_UNLOCK(); 1824 restore_intr(intrsave); |
1784 if (delta_modem_status & MSR_DCD) 1785 (*linesw[tp->t_line].l_modem) 1786 (tp, com->prev_modem_status & MSR_DCD); 1787 } 1788 if (com->extra_state & CSE_ODONE) { | 1825 if (delta_modem_status & MSR_DCD) 1826 (*linesw[tp->t_line].l_modem) 1827 (tp, com->prev_modem_status & MSR_DCD); 1828 } 1829 if (com->extra_state & CSE_ODONE) { |
1830 intrsave = save_intr(); |
|
1789 disable_intr(); | 1831 disable_intr(); |
1832 COM_LOCK(); |
|
1790 com_events -= LOTS_OF_EVENTS; 1791 com->extra_state &= ~CSE_ODONE; | 1833 com_events -= LOTS_OF_EVENTS; 1834 com->extra_state &= ~CSE_ODONE; |
1792 enable_intr(); | 1835 COM_UNLOCK(); 1836 restore_intr(intrsave); |
1793 if (!(com->state & CS_BUSY)) { 1794 tp->t_state &= ~TS_BUSY; 1795 ttwwakeup(com->tp); 1796 } 1797 if (com->etc != ETC_NONE) { 1798 if (com->etc == ETC_BREAK_ENDED) 1799 com->etc = ETC_NONE; 1800 wakeup(&com->etc); 1801 } 1802 } 1803 if (com->state & CS_ODONE) { | 1837 if (!(com->state & CS_BUSY)) { 1838 tp->t_state &= ~TS_BUSY; 1839 ttwwakeup(com->tp); 1840 } 1841 if (com->etc != ETC_NONE) { 1842 if (com->etc == ETC_BREAK_ENDED) 1843 com->etc = ETC_NONE; 1844 wakeup(&com->etc); 1845 } 1846 } 1847 if (com->state & CS_ODONE) { |
1848 intrsave = save_intr(); |
|
1804 disable_intr(); | 1849 disable_intr(); |
1850 COM_LOCK(); |
|
1805 com_events -= LOTS_OF_EVENTS; 1806 com->state &= ~CS_ODONE; | 1851 com_events -= LOTS_OF_EVENTS; 1852 com->state &= ~CS_ODONE; |
1807 enable_intr(); | 1853 COM_UNLOCK(); 1854 restore_intr(intrsave); |
1808 (*linesw[tp->t_line].l_start)(tp); 1809 } 1810 if (com_events == 0) 1811 break; 1812 } 1813 if (com_events >= LOTS_OF_EVENTS) 1814 goto repeat; 1815} --- 12 unchanged lines hidden (view full) --- 1828 int iflag; 1829 int iprescaler; 1830 int itimeout; 1831 int odivisor; 1832 int oprescaler; 1833 u_char opt; 1834 int s; 1835 int unit; | 1855 (*linesw[tp->t_line].l_start)(tp); 1856 } 1857 if (com_events == 0) 1858 break; 1859 } 1860 if (com_events >= LOTS_OF_EVENTS) 1861 goto repeat; 1862} --- 12 unchanged lines hidden (view full) --- 1875 int iflag; 1876 int iprescaler; 1877 int itimeout; 1878 int odivisor; 1879 int oprescaler; 1880 u_char opt; 1881 int s; 1882 int unit; |
1883 int intrsave; |
|
1836 1837 /* do historical conversions */ 1838 if (t->c_ispeed == 0) 1839 t->c_ispeed = t->c_ospeed; 1840 1841 unit = DEV_TO_UNIT(tp->t_dev); 1842 com = com_addr(unit); 1843 --- 8 unchanged lines hidden (view full) --- 1852 1853 /* parameters are OK, convert them to the com struct and the device */ 1854 s = spltty(); 1855 if (odivisor == 0) 1856 (void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */ 1857 else 1858 (void)commctl(com, TIOCM_DTR, DMBIS); 1859 | 1884 1885 /* do historical conversions */ 1886 if (t->c_ispeed == 0) 1887 t->c_ispeed = t->c_ospeed; 1888 1889 unit = DEV_TO_UNIT(tp->t_dev); 1890 com = com_addr(unit); 1891 --- 8 unchanged lines hidden (view full) --- 1900 1901 /* parameters are OK, convert them to the com struct and the device */ 1902 s = spltty(); 1903 if (odivisor == 0) 1904 (void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */ 1905 else 1906 (void)commctl(com, TIOCM_DTR, DMBIS); 1907 |
1860 /* 1861 * This returns with interrupts disabled so that we can complete 1862 * the speed change atomically. 1863 */ | |
1864 (void) siosetwater(com, t->c_ispeed); 1865 1866 /* XXX we don't actually change the speed atomically. */ | 1908 (void) siosetwater(com, t->c_ispeed); 1909 1910 /* XXX we don't actually change the speed atomically. */ |
1867 enable_intr(); | |
1868 1869 if (idivisor != 0) { 1870 cd_setreg(com, CD1400_RBPR, idivisor); 1871 cd_setreg(com, CD1400_RCOR, iprescaler); 1872 } 1873 if (odivisor != 0) { 1874 cd_setreg(com, CD1400_TBPR, odivisor); 1875 cd_setreg(com, CD1400_TCOR, oprescaler); --- 104 unchanged lines hidden (view full) --- 1980 opt |= CD1400_COR2_IXANY; 1981 if (iflag & IXOFF) 1982 opt |= CD1400_COR2_IXOFF; 1983#endif 1984#ifndef SOFT_CTS_OFLOW 1985 if (cflag & CCTS_OFLOW) 1986 opt |= CD1400_COR2_CCTS_OFLOW; 1987#endif | 1911 1912 if (idivisor != 0) { 1913 cd_setreg(com, CD1400_RBPR, idivisor); 1914 cd_setreg(com, CD1400_RCOR, iprescaler); 1915 } 1916 if (odivisor != 0) { 1917 cd_setreg(com, CD1400_TBPR, odivisor); 1918 cd_setreg(com, CD1400_TCOR, oprescaler); --- 104 unchanged lines hidden (view full) --- 2023 opt |= CD1400_COR2_IXANY; 2024 if (iflag & IXOFF) 2025 opt |= CD1400_COR2_IXOFF; 2026#endif 2027#ifndef SOFT_CTS_OFLOW 2028 if (cflag & CCTS_OFLOW) 2029 opt |= CD1400_COR2_CCTS_OFLOW; 2030#endif |
2031 intrsave = save_intr(); |
|
1988 disable_intr(); | 2032 disable_intr(); |
2033 COM_LOCK(); |
|
1989 if (opt != com->cor[1]) { 1990 cor_change |= CD1400_CCR_COR2; 1991 cd_setreg(com, CD1400_COR2, com->cor[1] = opt); 1992 } | 2034 if (opt != com->cor[1]) { 2035 cor_change |= CD1400_CCR_COR2; 2036 cd_setreg(com, CD1400_COR2, com->cor[1] = opt); 2037 } |
1993 enable_intr(); | 2038 COM_UNLOCK(); 2039 restore_intr(intrsave); |
1994 1995 /* 1996 * set channel option register 3 - 1997 * receiver FIFO interrupt threshold 1998 * flow control 1999 */ 2000 opt = RxFifoThreshold; 2001#ifdef Smarts --- 104 unchanged lines hidden (view full) --- 2106 opt |= CD1400_MCOR2_CTSod; 2107#endif 2108 cd_setreg(com, CD1400_MCOR2, opt); 2109 2110 /* 2111 * XXX should have done this long ago, but there is too much state 2112 * to change all atomically. 2113 */ | 2040 2041 /* 2042 * set channel option register 3 - 2043 * receiver FIFO interrupt threshold 2044 * flow control 2045 */ 2046 opt = RxFifoThreshold; 2047#ifdef Smarts --- 104 unchanged lines hidden (view full) --- 2152 opt |= CD1400_MCOR2_CTSod; 2153#endif 2154 cd_setreg(com, CD1400_MCOR2, opt); 2155 2156 /* 2157 * XXX should have done this long ago, but there is too much state 2158 * to change all atomically. 2159 */ |
2160 intrsave = save_intr(); |
|
2114 disable_intr(); | 2161 disable_intr(); |
2162 COM_LOCK(); |
|
2115 2116 com->state &= ~CS_TTGO; 2117 if (!(tp->t_state & TS_TTSTOP)) 2118 com->state |= CS_TTGO; 2119 if (cflag & CRTS_IFLOW) { 2120 com->state |= CS_RTS_IFLOW; 2121 /* 2122 * If CS_RTS_IFLOW just changed from off to on, the change --- 49 unchanged lines hidden (view full) --- 2172 } else { 2173 if (com->intr_enable & CD1400_SRER_TXRDY) 2174 cd_setreg(com, CD1400_SRER, 2175 com->intr_enable 2176 = (com->intr_enable & ~CD1400_SRER_TXRDY) 2177 | CD1400_SRER_TXMPTY); 2178 } 2179 | 2163 2164 com->state &= ~CS_TTGO; 2165 if (!(tp->t_state & TS_TTSTOP)) 2166 com->state |= CS_TTGO; 2167 if (cflag & CRTS_IFLOW) { 2168 com->state |= CS_RTS_IFLOW; 2169 /* 2170 * If CS_RTS_IFLOW just changed from off to on, the change --- 49 unchanged lines hidden (view full) --- 2220 } else { 2221 if (com->intr_enable & CD1400_SRER_TXRDY) 2222 cd_setreg(com, CD1400_SRER, 2223 com->intr_enable 2224 = (com->intr_enable & ~CD1400_SRER_TXRDY) 2225 | CD1400_SRER_TXMPTY); 2226 } 2227 |
2180 enable_intr(); | 2228 COM_UNLOCK(); 2229 restore_intr(intrsave); |
2181 splx(s); 2182 comstart(tp); 2183 if (com->ibufold != NULL) { 2184 free(com->ibufold, M_DEVBUF); 2185 com->ibufold = NULL; 2186 } 2187 return (0); 2188} 2189 2190static int 2191siosetwater(com, speed) 2192 struct com_s *com; 2193 speed_t speed; 2194{ 2195 int cp4ticks; 2196 u_char *ibuf; 2197 int ibufsize; 2198 struct tty *tp; | 2230 splx(s); 2231 comstart(tp); 2232 if (com->ibufold != NULL) { 2233 free(com->ibufold, M_DEVBUF); 2234 com->ibufold = NULL; 2235 } 2236 return (0); 2237} 2238 2239static int 2240siosetwater(com, speed) 2241 struct com_s *com; 2242 speed_t speed; 2243{ 2244 int cp4ticks; 2245 u_char *ibuf; 2246 int ibufsize; 2247 struct tty *tp; |
2248 int intrsave; |
|
2199 2200 /* 2201 * Make the buffer size large enough to handle a softtty interrupt 2202 * latency of about 2 ticks without loss of throughput or data 2203 * (about 3 ticks if input flow control is not used or not honoured, 2204 * but a bit less for CS5-CS7 modes). 2205 */ 2206 cp4ticks = speed / 10 / hz * 4; 2207 for (ibufsize = 128; ibufsize < cp4ticks;) 2208 ibufsize <<= 1; 2209 if (ibufsize == com->ibufsize) { | 2249 2250 /* 2251 * Make the buffer size large enough to handle a softtty interrupt 2252 * latency of about 2 ticks without loss of throughput or data 2253 * (about 3 ticks if input flow control is not used or not honoured, 2254 * but a bit less for CS5-CS7 modes). 2255 */ 2256 cp4ticks = speed / 10 / hz * 4; 2257 for (ibufsize = 128; ibufsize < cp4ticks;) 2258 ibufsize <<= 1; 2259 if (ibufsize == com->ibufsize) { |
2210 disable_intr(); | |
2211 return (0); 2212 } 2213 2214 /* 2215 * Allocate input buffer. The extra factor of 2 in the size is 2216 * to allow for an error byte for each input byte. 2217 */ 2218 ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT); 2219 if (ibuf == NULL) { | 2260 return (0); 2261 } 2262 2263 /* 2264 * Allocate input buffer. The extra factor of 2 in the size is 2265 * to allow for an error byte for each input byte. 2266 */ 2267 ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT); 2268 if (ibuf == NULL) { |
2220 disable_intr(); | |
2221 return (ENOMEM); 2222 } 2223 2224 /* Initialize non-critical variables. */ 2225 com->ibufold = com->ibuf; 2226 com->ibufsize = ibufsize; 2227 tp = com->tp; 2228 if (tp != NULL) { 2229 tp->t_ififosize = 2 * ibufsize; 2230 tp->t_ispeedwat = (speed_t)-1; 2231 tp->t_ospeedwat = (speed_t)-1; 2232 } 2233 2234 /* 2235 * Read current input buffer, if any. Continue with interrupts 2236 * disabled. 2237 */ | 2269 return (ENOMEM); 2270 } 2271 2272 /* Initialize non-critical variables. */ 2273 com->ibufold = com->ibuf; 2274 com->ibufsize = ibufsize; 2275 tp = com->tp; 2276 if (tp != NULL) { 2277 tp->t_ififosize = 2 * ibufsize; 2278 tp->t_ispeedwat = (speed_t)-1; 2279 tp->t_ospeedwat = (speed_t)-1; 2280 } 2281 2282 /* 2283 * Read current input buffer, if any. Continue with interrupts 2284 * disabled. 2285 */ |
2286 intrsave = save_intr(); |
|
2238 disable_intr(); | 2287 disable_intr(); |
2288 COM_LOCK(); |
|
2239 if (com->iptr != com->ibuf) 2240 sioinput(com); 2241 2242 /*- 2243 * Initialize critical variables, including input buffer watermarks. 2244 * The external device is asked to stop sending when the buffer 2245 * exactly reaches high water, or when the high level requests it. 2246 * The high level is notified immediately (rather than at a later 2247 * clock tick) when this watermark is reached. 2248 * The buffer size is chosen so the watermark should almost never 2249 * be reached. 2250 * The low watermark is invisibly 0 since the buffer is always 2251 * emptied all at once. 2252 */ 2253 com->iptr = com->ibuf = ibuf; 2254 com->ibufend = ibuf + ibufsize; 2255 com->ierroff = ibufsize; 2256 com->ihighwater = ibuf + 3 * ibufsize / 4; | 2289 if (com->iptr != com->ibuf) 2290 sioinput(com); 2291 2292 /*- 2293 * Initialize critical variables, including input buffer watermarks. 2294 * The external device is asked to stop sending when the buffer 2295 * exactly reaches high water, or when the high level requests it. 2296 * The high level is notified immediately (rather than at a later 2297 * clock tick) when this watermark is reached. 2298 * The buffer size is chosen so the watermark should almost never 2299 * be reached. 2300 * The low watermark is invisibly 0 since the buffer is always 2301 * emptied all at once. 2302 */ 2303 com->iptr = com->ibuf = ibuf; 2304 com->ibufend = ibuf + ibufsize; 2305 com->ierroff = ibufsize; 2306 com->ihighwater = ibuf + 3 * ibufsize / 4; |
2307 2308 COM_UNLOCK(); 2309 restore_intr(intrsave); |
|
2257 return (0); 2258} 2259 2260static void 2261comstart(tp) 2262 struct tty *tp; 2263{ 2264 struct com_s *com; 2265 int s; 2266#ifdef CyDebug 2267 bool_t started; 2268#endif 2269 int unit; | 2310 return (0); 2311} 2312 2313static void 2314comstart(tp) 2315 struct tty *tp; 2316{ 2317 struct com_s *com; 2318 int s; 2319#ifdef CyDebug 2320 bool_t started; 2321#endif 2322 int unit; |
2323 int intrsave; |
|
2270 2271 unit = DEV_TO_UNIT(tp->t_dev); 2272 com = com_addr(unit); 2273 s = spltty(); 2274 2275#ifdef CyDebug 2276 ++com->start_count; 2277 started = FALSE; 2278#endif 2279 | 2324 2325 unit = DEV_TO_UNIT(tp->t_dev); 2326 com = com_addr(unit); 2327 s = spltty(); 2328 2329#ifdef CyDebug 2330 ++com->start_count; 2331 started = FALSE; 2332#endif 2333 |
2334 intrsave = save_intr(); |
|
2280 disable_intr(); | 2335 disable_intr(); |
2336 COM_LOCK(); |
|
2281 if (tp->t_state & TS_TTSTOP) { 2282 com->state &= ~CS_TTGO; 2283 if (com->intr_enable & CD1400_SRER_TXRDY) 2284 cd_setreg(com, CD1400_SRER, 2285 com->intr_enable 2286 = (com->intr_enable & ~CD1400_SRER_TXRDY) 2287 | CD1400_SRER_TXMPTY); 2288 } else { --- 19 unchanged lines hidden (view full) --- 2308 && com->state & CS_RTS_IFLOW) 2309#if 0 2310 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); 2311#else 2312 cd_setreg(com, com->mcr_rts_reg, 2313 com->mcr_image |= com->mcr_rts); 2314#endif 2315 } | 2337 if (tp->t_state & TS_TTSTOP) { 2338 com->state &= ~CS_TTGO; 2339 if (com->intr_enable & CD1400_SRER_TXRDY) 2340 cd_setreg(com, CD1400_SRER, 2341 com->intr_enable 2342 = (com->intr_enable & ~CD1400_SRER_TXRDY) 2343 | CD1400_SRER_TXMPTY); 2344 } else { --- 19 unchanged lines hidden (view full) --- 2364 && com->state & CS_RTS_IFLOW) 2365#if 0 2366 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); 2367#else 2368 cd_setreg(com, com->mcr_rts_reg, 2369 com->mcr_image |= com->mcr_rts); 2370#endif 2371 } |
2316 enable_intr(); | 2372 COM_UNLOCK(); 2373 restore_intr(intrsave); |
2317 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { 2318 ttwwakeup(tp); 2319 splx(s); 2320 return; 2321 } 2322 if (tp->t_outq.c_cc != 0) { 2323 struct lbq *qp; 2324 struct lbq *next; 2325 2326 if (!com->obufs[0].l_queued) { 2327#ifdef CyDebug 2328 started = TRUE; 2329#endif 2330 com->obufs[0].l_tail 2331 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1, 2332 sizeof com->obuf1); 2333 com->obufs[0].l_next = NULL; 2334 com->obufs[0].l_queued = TRUE; | 2374 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { 2375 ttwwakeup(tp); 2376 splx(s); 2377 return; 2378 } 2379 if (tp->t_outq.c_cc != 0) { 2380 struct lbq *qp; 2381 struct lbq *next; 2382 2383 if (!com->obufs[0].l_queued) { 2384#ifdef CyDebug 2385 started = TRUE; 2386#endif 2387 com->obufs[0].l_tail 2388 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1, 2389 sizeof com->obuf1); 2390 com->obufs[0].l_next = NULL; 2391 com->obufs[0].l_queued = TRUE; |
2392 intrsave = save_intr(); |
|
2335 disable_intr(); | 2393 disable_intr(); |
2394 COM_LOCK(); |
|
2336 if (com->state & CS_BUSY) { 2337 qp = com->obufq.l_next; 2338 while ((next = qp->l_next) != NULL) 2339 qp = next; 2340 qp->l_next = &com->obufs[0]; 2341 } else { 2342 com->obufq.l_head = com->obufs[0].l_head; 2343 com->obufq.l_tail = com->obufs[0].l_tail; 2344 com->obufq.l_next = &com->obufs[0]; 2345 com->state |= CS_BUSY; 2346 if (com->state >= (CS_BUSY | CS_TTGO 2347 | CS_ODEVREADY)) 2348 cd_setreg(com, CD1400_SRER, 2349 com->intr_enable 2350 = (com->intr_enable 2351 & ~CD1400_SRER_TXMPTY) 2352 | CD1400_SRER_TXRDY); 2353 } | 2395 if (com->state & CS_BUSY) { 2396 qp = com->obufq.l_next; 2397 while ((next = qp->l_next) != NULL) 2398 qp = next; 2399 qp->l_next = &com->obufs[0]; 2400 } else { 2401 com->obufq.l_head = com->obufs[0].l_head; 2402 com->obufq.l_tail = com->obufs[0].l_tail; 2403 com->obufq.l_next = &com->obufs[0]; 2404 com->state |= CS_BUSY; 2405 if (com->state >= (CS_BUSY | CS_TTGO 2406 | CS_ODEVREADY)) 2407 cd_setreg(com, CD1400_SRER, 2408 com->intr_enable 2409 = (com->intr_enable 2410 & ~CD1400_SRER_TXMPTY) 2411 | CD1400_SRER_TXRDY); 2412 } |
2354 enable_intr(); | 2413 COM_UNLOCK(); 2414 restore_intr(intrsave); |
2355 } 2356 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { 2357#ifdef CyDebug 2358 started = TRUE; 2359#endif 2360 com->obufs[1].l_tail 2361 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2, 2362 sizeof com->obuf2); 2363 com->obufs[1].l_next = NULL; 2364 com->obufs[1].l_queued = TRUE; | 2415 } 2416 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { 2417#ifdef CyDebug 2418 started = TRUE; 2419#endif 2420 com->obufs[1].l_tail 2421 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2, 2422 sizeof com->obuf2); 2423 com->obufs[1].l_next = NULL; 2424 com->obufs[1].l_queued = TRUE; |
2425 intrsave = save_intr(); |
|
2365 disable_intr(); | 2426 disable_intr(); |
2427 COM_LOCK(); |
|
2366 if (com->state & CS_BUSY) { 2367 qp = com->obufq.l_next; 2368 while ((next = qp->l_next) != NULL) 2369 qp = next; 2370 qp->l_next = &com->obufs[1]; 2371 } else { 2372 com->obufq.l_head = com->obufs[1].l_head; 2373 com->obufq.l_tail = com->obufs[1].l_tail; 2374 com->obufq.l_next = &com->obufs[1]; 2375 com->state |= CS_BUSY; 2376 if (com->state >= (CS_BUSY | CS_TTGO 2377 | CS_ODEVREADY)) 2378 cd_setreg(com, CD1400_SRER, 2379 com->intr_enable 2380 = (com->intr_enable 2381 & ~CD1400_SRER_TXMPTY) 2382 | CD1400_SRER_TXRDY); 2383 } | 2428 if (com->state & CS_BUSY) { 2429 qp = com->obufq.l_next; 2430 while ((next = qp->l_next) != NULL) 2431 qp = next; 2432 qp->l_next = &com->obufs[1]; 2433 } else { 2434 com->obufq.l_head = com->obufs[1].l_head; 2435 com->obufq.l_tail = com->obufs[1].l_tail; 2436 com->obufq.l_next = &com->obufs[1]; 2437 com->state |= CS_BUSY; 2438 if (com->state >= (CS_BUSY | CS_TTGO 2439 | CS_ODEVREADY)) 2440 cd_setreg(com, CD1400_SRER, 2441 com->intr_enable 2442 = (com->intr_enable 2443 & ~CD1400_SRER_TXMPTY) 2444 | CD1400_SRER_TXRDY); 2445 } |
2384 enable_intr(); | 2446 COM_UNLOCK(); 2447 restore_intr(intrsave); |
2385 } 2386 tp->t_state |= TS_BUSY; 2387 } 2388#ifdef CyDebug 2389 if (started) 2390 ++com->start_real; 2391#endif 2392#if 0 | 2448 } 2449 tp->t_state |= TS_BUSY; 2450 } 2451#ifdef CyDebug 2452 if (started) 2453 ++com->start_real; 2454#endif 2455#if 0 |
2456 intrsave = save_intr(); |
|
2393 disable_intr(); | 2457 disable_intr(); |
2458 COM_LOCK(); |
|
2394 if (com->state >= (CS_BUSY | CS_TTGO)) 2395 siointr1(com); /* fake interrupt to start output */ | 2459 if (com->state >= (CS_BUSY | CS_TTGO)) 2460 siointr1(com); /* fake interrupt to start output */ |
2396 enable_intr(); | 2461 COM_UNLOCK(); 2462 restore_intr(intrsave); |
2397#endif 2398 ttwwakeup(tp); 2399 splx(s); 2400} 2401 2402static void 2403comstop(tp, rw) 2404 struct tty *tp; 2405 int rw; 2406{ 2407 struct com_s *com; 2408 bool_t wakeup_etc; | 2463#endif 2464 ttwwakeup(tp); 2465 splx(s); 2466} 2467 2468static void 2469comstop(tp, rw) 2470 struct tty *tp; 2471 int rw; 2472{ 2473 struct com_s *com; 2474 bool_t wakeup_etc; |
2475 int intrsave; |
|
2409 2410 com = com_addr(DEV_TO_UNIT(tp->t_dev)); 2411 wakeup_etc = FALSE; | 2476 2477 com = com_addr(DEV_TO_UNIT(tp->t_dev)); 2478 wakeup_etc = FALSE; |
2479 intrsave = save_intr(); |
|
2412 disable_intr(); | 2480 disable_intr(); |
2481 COM_LOCK(); |
|
2413 if (rw & FWRITE) { 2414 com->obufs[0].l_queued = FALSE; 2415 com->obufs[1].l_queued = FALSE; 2416 if (com->extra_state & CSE_ODONE) { 2417 com_events -= LOTS_OF_EVENTS; 2418 com->extra_state &= ~CSE_ODONE; 2419 if (com->etc != ETC_NONE) { 2420 if (com->etc == ETC_BREAK_ENDED) --- 6 unchanged lines hidden (view full) --- 2427 com_events -= LOTS_OF_EVENTS; 2428 com->state &= ~(CS_ODONE | CS_BUSY); 2429 } 2430 if (rw & FREAD) { 2431 /* XXX no way to reset only input fifo. */ 2432 com_events -= (com->iptr - com->ibuf); 2433 com->iptr = com->ibuf; 2434 } | 2482 if (rw & FWRITE) { 2483 com->obufs[0].l_queued = FALSE; 2484 com->obufs[1].l_queued = FALSE; 2485 if (com->extra_state & CSE_ODONE) { 2486 com_events -= LOTS_OF_EVENTS; 2487 com->extra_state &= ~CSE_ODONE; 2488 if (com->etc != ETC_NONE) { 2489 if (com->etc == ETC_BREAK_ENDED) --- 6 unchanged lines hidden (view full) --- 2496 com_events -= LOTS_OF_EVENTS; 2497 com->state &= ~(CS_ODONE | CS_BUSY); 2498 } 2499 if (rw & FREAD) { 2500 /* XXX no way to reset only input fifo. */ 2501 com_events -= (com->iptr - com->ibuf); 2502 com->iptr = com->ibuf; 2503 } |
2435 enable_intr(); | 2504 COM_UNLOCK(); 2505 restore_intr(intrsave); |
2436 if (wakeup_etc) 2437 wakeup(&com->etc); 2438 if (rw & FWRITE && com->etc == ETC_NONE) 2439 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 2440 comstart(tp); 2441} 2442 2443static int 2444commctl(com, bits, how) 2445 struct com_s *com; 2446 int bits; 2447 int how; 2448{ 2449 int mcr; 2450 int msr; | 2506 if (wakeup_etc) 2507 wakeup(&com->etc); 2508 if (rw & FWRITE && com->etc == ETC_NONE) 2509 cd1400_channel_cmd(com, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 2510 comstart(tp); 2511} 2512 2513static int 2514commctl(com, bits, how) 2515 struct com_s *com; 2516 int bits; 2517 int how; 2518{ 2519 int mcr; 2520 int msr; |
2521 int intrsave; |
|
2451 2452 if (how == DMGET) { 2453 if (com->channel_control & CD1400_CCR_RCVEN) 2454 bits |= TIOCM_LE; 2455 mcr = com->mcr_image; 2456 if (mcr & com->mcr_dtr) 2457 bits |= TIOCM_DTR; 2458 if (mcr & com->mcr_rts) --- 21 unchanged lines hidden (view full) --- 2480 bits |= TIOCM_RI; 2481 return (bits); 2482 } 2483 mcr = 0; 2484 if (bits & TIOCM_DTR) 2485 mcr |= com->mcr_dtr; 2486 if (bits & TIOCM_RTS) 2487 mcr |= com->mcr_rts; | 2522 2523 if (how == DMGET) { 2524 if (com->channel_control & CD1400_CCR_RCVEN) 2525 bits |= TIOCM_LE; 2526 mcr = com->mcr_image; 2527 if (mcr & com->mcr_dtr) 2528 bits |= TIOCM_DTR; 2529 if (mcr & com->mcr_rts) --- 21 unchanged lines hidden (view full) --- 2551 bits |= TIOCM_RI; 2552 return (bits); 2553 } 2554 mcr = 0; 2555 if (bits & TIOCM_DTR) 2556 mcr |= com->mcr_dtr; 2557 if (bits & TIOCM_RTS) 2558 mcr |= com->mcr_rts; |
2559 intrsave = save_intr(); |
|
2488 disable_intr(); | 2560 disable_intr(); |
2561 COM_LOCK(); |
|
2489 switch (how) { 2490 case DMSET: 2491 com->mcr_image = mcr; 2492 cd_setreg(com, CD1400_MSVR1, mcr); 2493 cd_setreg(com, CD1400_MSVR2, mcr); 2494 break; 2495 case DMBIS: 2496 com->mcr_image = mcr = com->mcr_image | mcr; 2497 cd_setreg(com, CD1400_MSVR1, mcr); 2498 cd_setreg(com, CD1400_MSVR2, mcr); 2499 break; 2500 case DMBIC: 2501 com->mcr_image = mcr = com->mcr_image & ~mcr; 2502 cd_setreg(com, CD1400_MSVR1, mcr); 2503 cd_setreg(com, CD1400_MSVR2, mcr); 2504 break; 2505 } | 2562 switch (how) { 2563 case DMSET: 2564 com->mcr_image = mcr; 2565 cd_setreg(com, CD1400_MSVR1, mcr); 2566 cd_setreg(com, CD1400_MSVR2, mcr); 2567 break; 2568 case DMBIS: 2569 com->mcr_image = mcr = com->mcr_image | mcr; 2570 cd_setreg(com, CD1400_MSVR1, mcr); 2571 cd_setreg(com, CD1400_MSVR2, mcr); 2572 break; 2573 case DMBIC: 2574 com->mcr_image = mcr = com->mcr_image & ~mcr; 2575 cd_setreg(com, CD1400_MSVR1, mcr); 2576 cd_setreg(com, CD1400_MSVR2, mcr); 2577 break; 2578 } |
2506 enable_intr(); | 2579 COM_UNLOCK(); 2580 restore_intr(intrsave); |
2507 return (0); 2508} 2509 2510static void 2511siosettimeout() 2512{ 2513 struct com_s *com; 2514 bool_t someopen; --- 45 unchanged lines hidden (view full) --- 2560 /* 2561 * Recover from lost output interrupts. 2562 * Poll any lines that don't use interrupts. 2563 */ 2564 for (unit = 0; unit < NSIO; ++unit) { 2565 com = com_addr(unit); 2566 if (com != NULL 2567 && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { | 2581 return (0); 2582} 2583 2584static void 2585siosettimeout() 2586{ 2587 struct com_s *com; 2588 bool_t someopen; --- 45 unchanged lines hidden (view full) --- 2634 /* 2635 * Recover from lost output interrupts. 2636 * Poll any lines that don't use interrupts. 2637 */ 2638 for (unit = 0; unit < NSIO; ++unit) { 2639 com = com_addr(unit); 2640 if (com != NULL 2641 && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { |
2642 int intrsave; 2643 2644 intrsave = save_intr(); |
|
2568 disable_intr(); | 2645 disable_intr(); |
2646 COM_LOCK(); |
|
2569 siointr1(com); | 2647 siointr1(com); |
2570 enable_intr(); | 2648 COM_UNLOCK(); 2649 restore_intr(intrsave); |
2571 } 2572 } 2573#endif 2574 2575 /* 2576 * Check for and log errors, but not too often. 2577 */ 2578 if (--sio_timeouts_until_log > 0) 2579 return; 2580 sio_timeouts_until_log = hz / sio_timeout; 2581 for (unit = 0; unit < NSIO; ++unit) { 2582 int errnum; 2583 2584 com = com_addr(unit); 2585 if (com == NULL) 2586 continue; 2587 for (errnum = 0; errnum < CE_NTYPES; ++errnum) { 2588 u_int delta; 2589 u_long total; | 2650 } 2651 } 2652#endif 2653 2654 /* 2655 * Check for and log errors, but not too often. 2656 */ 2657 if (--sio_timeouts_until_log > 0) 2658 return; 2659 sio_timeouts_until_log = hz / sio_timeout; 2660 for (unit = 0; unit < NSIO; ++unit) { 2661 int errnum; 2662 2663 com = com_addr(unit); 2664 if (com == NULL) 2665 continue; 2666 for (errnum = 0; errnum < CE_NTYPES; ++errnum) { 2667 u_int delta; 2668 u_long total; |
2669 int intrsave; |
|
2590 | 2670 |
2671 intrsave = save_intr(); |
|
2591 disable_intr(); | 2672 disable_intr(); |
2673 COM_LOCK(); |
|
2592 delta = com->delta_error_counts[errnum]; 2593 com->delta_error_counts[errnum] = 0; | 2674 delta = com->delta_error_counts[errnum]; 2675 com->delta_error_counts[errnum] = 0; |
2594 enable_intr(); | 2676 COM_UNLOCK(); 2677 restore_intr(intrsave); |
2595 if (delta == 0) 2596 continue; 2597 total = com->error_counts[errnum] += delta; 2598 log(LOG_ERR, "cy%d: %u more %s%s (total %lu)\n", 2599 unit, delta, error_desc[errnum], 2600 delta == 1 ? "" : "s", total); 2601 } 2602 } --- 135 unchanged lines hidden (view full) --- 2738 } 2739} 2740 2741static void 2742cd_etc(com, etc) 2743 struct com_s *com; 2744 int etc; 2745{ | 2678 if (delta == 0) 2679 continue; 2680 total = com->error_counts[errnum] += delta; 2681 log(LOG_ERR, "cy%d: %u more %s%s (total %lu)\n", 2682 unit, delta, error_desc[errnum], 2683 delta == 1 ? "" : "s", total); 2684 } 2685 } --- 135 unchanged lines hidden (view full) --- 2821 } 2822} 2823 2824static void 2825cd_etc(com, etc) 2826 struct com_s *com; 2827 int etc; 2828{ |
2829 int intrsave; 2830 |
|
2746 /* 2747 * We can't change the hardware's ETC state while there are any 2748 * characters in the tx fifo, since those characters would be 2749 * interpreted as commands! Unputting characters from the fifo 2750 * is difficult, so we wait up to 12 character times for the fifo 2751 * to drain. The command will be delayed for up to 2 character 2752 * times for the tx to become empty. Unputting characters from 2753 * the tx holding and shift registers is impossible, so we wait 2754 * for the tx to become empty so that the command is sure to be 2755 * executed soon after we issue it. 2756 */ | 2831 /* 2832 * We can't change the hardware's ETC state while there are any 2833 * characters in the tx fifo, since those characters would be 2834 * interpreted as commands! Unputting characters from the fifo 2835 * is difficult, so we wait up to 12 character times for the fifo 2836 * to drain. The command will be delayed for up to 2 character 2837 * times for the tx to become empty. Unputting characters from 2838 * the tx holding and shift registers is impossible, so we wait 2839 * for the tx to become empty so that the command is sure to be 2840 * executed soon after we issue it. 2841 */ |
2842 intrsave = save_intr(); |
|
2757 disable_intr(); | 2843 disable_intr(); |
2758 if (com->etc == etc) { 2759 enable_intr(); | 2844 COM_LOCK(); 2845 if (com->etc == etc) |
2760 goto wait; | 2846 goto wait; |
2761 } | |
2762 if ((etc == CD1400_ETC_SENDBREAK 2763 && (com->etc == ETC_BREAK_STARTING 2764 || com->etc == ETC_BREAK_STARTED)) 2765 || (etc == CD1400_ETC_STOPBREAK 2766 && (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED 2767 || com->etc == ETC_NONE))) { | 2847 if ((etc == CD1400_ETC_SENDBREAK 2848 && (com->etc == ETC_BREAK_STARTING 2849 || com->etc == ETC_BREAK_STARTED)) 2850 || (etc == CD1400_ETC_STOPBREAK 2851 && (com->etc == ETC_BREAK_ENDING || com->etc == ETC_BREAK_ENDED 2852 || com->etc == ETC_NONE))) { |
2768 enable_intr(); | 2853 COM_UNLOCK(); 2854 restore_intr(intrsave); |
2769 return; 2770 } 2771 com->etc = etc; 2772 cd_setreg(com, CD1400_SRER, 2773 com->intr_enable 2774 = (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY); | 2855 return; 2856 } 2857 com->etc = etc; 2858 cd_setreg(com, CD1400_SRER, 2859 com->intr_enable 2860 = (com->intr_enable & ~CD1400_SRER_TXRDY) | CD1400_SRER_TXMPTY); |
2775 enable_intr(); | |
2776wait: | 2861wait: |
2862 COM_UNLOCK(); 2863 restore_intr(intrsave); |
|
2777 while (com->etc == etc 2778 && tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0) 2779 continue; 2780} 2781 2782static int 2783cd_getreg(com, reg) 2784 struct com_s *com; 2785 int reg; 2786{ 2787 struct com_s *basecom; 2788 u_char car; 2789 int cy_align; | 2864 while (com->etc == etc 2865 && tsleep(&com->etc, TTIPRI | PCATCH, "cyetc", 0) == 0) 2866 continue; 2867} 2868 2869static int 2870cd_getreg(com, reg) 2871 struct com_s *com; 2872 int reg; 2873{ 2874 struct com_s *basecom; 2875 u_char car; 2876 int cy_align; |
2790 u_long ef; | 2877 int intrsave; |
2791 cy_addr iobase; 2792 int val; 2793 2794 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1)); 2795 car = com->unit & CD1400_CAR_CHAN; 2796 cy_align = com->cy_align; 2797 iobase = com->iobase; | 2878 cy_addr iobase; 2879 int val; 2880 2881 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1)); 2882 car = com->unit & CD1400_CAR_CHAN; 2883 cy_align = com->cy_align; 2884 iobase = com->iobase; |
2798 ef = read_eflags(); 2799 if (ef & PSL_I) 2800 disable_intr(); | 2885 intrsave = save_intr(); 2886 disable_intr(); 2887 if (intrsave & PSL_I) 2888 COM_LOCK(); |
2801 if (basecom->car != car) 2802 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car); 2803 val = cd_inb(iobase, reg, cy_align); | 2889 if (basecom->car != car) 2890 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car); 2891 val = cd_inb(iobase, reg, cy_align); |
2804 if (ef & PSL_I) 2805 enable_intr(); | 2892 if (intrsave & PSL_I) 2893 COM_UNLOCK(); 2894 restore_intr(intrsave); |
2806 return (val); 2807} 2808 2809static void 2810cd_setreg(com, reg, val) 2811 struct com_s *com; 2812 int reg; 2813 int val; 2814{ 2815 struct com_s *basecom; 2816 u_char car; 2817 int cy_align; | 2895 return (val); 2896} 2897 2898static void 2899cd_setreg(com, reg, val) 2900 struct com_s *com; 2901 int reg; 2902 int val; 2903{ 2904 struct com_s *basecom; 2905 u_char car; 2906 int cy_align; |
2818 u_long ef; | 2907 int intrsave; |
2819 cy_addr iobase; 2820 2821 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1)); 2822 car = com->unit & CD1400_CAR_CHAN; 2823 cy_align = com->cy_align; 2824 iobase = com->iobase; | 2908 cy_addr iobase; 2909 2910 basecom = com_addr(com->unit & ~(CD1400_NO_OF_CHANNELS - 1)); 2911 car = com->unit & CD1400_CAR_CHAN; 2912 cy_align = com->cy_align; 2913 iobase = com->iobase; |
2825 ef = read_eflags(); 2826 if (ef & PSL_I) 2827 disable_intr(); | 2914 intrsave = save_intr(); 2915 disable_intr(); 2916 if (intrsave & PSL_I) 2917 COM_LOCK(); |
2828 if (basecom->car != car) 2829 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car); 2830 cd_outb(iobase, reg, cy_align, val); | 2918 if (basecom->car != car) 2919 cd_outb(iobase, CD1400_CAR, cy_align, basecom->car = car); 2920 cd_outb(iobase, reg, cy_align, val); |
2831 if (ef & PSL_I) 2832 enable_intr(); | 2921 if (intrsave & PSL_I) 2922 COM_UNLOCK(); 2923 restore_intr(intrsave); |
2833} 2834 2835#ifdef CyDebug 2836/* useful in ddb */ 2837void 2838cystatus(unit) 2839 int unit; 2840{ --- 54 unchanged lines hidden --- | 2924} 2925 2926#ifdef CyDebug 2927/* useful in ddb */ 2928void 2929cystatus(unit) 2930 int unit; 2931{ --- 54 unchanged lines hidden --- |