sio.c (62573) | sio.c (65568) |
---|---|
1/*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * | 1/*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * |
33 * $FreeBSD: head/sys/pc98/cbus/sio.c 62573 2000-07-04 11:25:35Z phk $ | 33 * $FreeBSD: head/sys/pc98/cbus/sio.c 65568 2000-09-07 13:34:45Z kato $ |
34 * from: @(#)com.c 7.5 (Berkeley) 5/16/91 35 * from: i386/isa sio.c,v 1.234 36 */ 37 38#include "opt_comconsole.h" 39#include "opt_compat.h" 40#include "opt_ddb.h" 41#include "opt_sio.h" --- 143 unchanged lines hidden (view full) --- 185#ifdef COM_ESP 186#include <i386/isa/ic/esp.h> 187#endif 188#include <i386/isa/ic/ns16550.h> 189#ifdef PC98 190#include <i386/isa/ic/rsa.h> 191#endif 192 | 34 * from: @(#)com.c 7.5 (Berkeley) 5/16/91 35 * from: i386/isa sio.c,v 1.234 36 */ 37 38#include "opt_comconsole.h" 39#include "opt_compat.h" 40#include "opt_ddb.h" 41#include "opt_sio.h" --- 143 unchanged lines hidden (view full) --- 185#ifdef COM_ESP 186#include <i386/isa/ic/esp.h> 187#endif 188#include <i386/isa/ic/ns16550.h> 189#ifdef PC98 190#include <i386/isa/ic/rsa.h> 191#endif 192 |
193/* XXX - this is ok because we only do sio fast interrupts on i386 */ |
|
193#ifndef __i386__ 194#define disable_intr() 195#define enable_intr() 196#endif 197 | 194#ifndef __i386__ 195#define disable_intr() 196#define enable_intr() 197#endif 198 |
198#ifdef SMP 199#define disable_intr() COM_DISABLE_INTR() 200#define enable_intr() COM_ENABLE_INTR() 201#endif /* SMP */ 202 | |
203#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */ 204 205#define CALLOUT_MASK 0x80 206#define CONTROL_MASK 0x60 207#define CONTROL_INIT_STATE 0x20 208#define CONTROL_LOCK_STATE 0x40 209#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev))) 210#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK) --- 867 unchanged lines hidden (view full) --- 1078 {0x7602a904, NULL}, /* AEI0276 - 56K v.90 Fax Modem (LKT) */ 1079 {0x00007905, NULL}, /* AKY0000 - 56K Plug&Play Modem */ 1080 {0x01405407, NULL}, /* AZT4001 - AZT3000 PnP SOUND DEVICE, MODEM */ 1081 {0x56039008, NULL}, /* BDP0356 - Best Data 56x2 */ 1082 {0x36339008, NULL}, /* BDP3336 - Best Data Prods. 336F */ 1083 {0x0014490a, NULL}, /* BRI1400 - Boca 33.6 PnP */ 1084 {0x0015490a, NULL}, /* BRI1500 - Internal Fax Data */ 1085 {0x0034490a, NULL}, /* BRI3400 - Internal ACF Modem */ | 199#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */ 200 201#define CALLOUT_MASK 0x80 202#define CONTROL_MASK 0x60 203#define CONTROL_INIT_STATE 0x20 204#define CONTROL_LOCK_STATE 0x40 205#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev))) 206#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK) --- 867 unchanged lines hidden (view full) --- 1074 {0x7602a904, NULL}, /* AEI0276 - 56K v.90 Fax Modem (LKT) */ 1075 {0x00007905, NULL}, /* AKY0000 - 56K Plug&Play Modem */ 1076 {0x01405407, NULL}, /* AZT4001 - AZT3000 PnP SOUND DEVICE, MODEM */ 1077 {0x56039008, NULL}, /* BDP0356 - Best Data 56x2 */ 1078 {0x36339008, NULL}, /* BDP3336 - Best Data Prods. 336F */ 1079 {0x0014490a, NULL}, /* BRI1400 - Boca 33.6 PnP */ 1080 {0x0015490a, NULL}, /* BRI1500 - Internal Fax Data */ 1081 {0x0034490a, NULL}, /* BRI3400 - Internal ACF Modem */ |
1082 {0x0094490a, NULL}, /* BRI9400 - Boca K56Flex PnP */ |
|
1086 {0x00b4490a, NULL}, /* BRIB400 - Boca 56k PnP */ 1087 {0x0030320d, NULL}, /* CIR3000 - Cirrus Logic V43 */ 1088 {0x0100440e, NULL}, /* CRD0001 - Cardinal MVP288IV ? */ 1089 {0x1200c31e, NULL}, /* GVC0012 - VF1128HV-R9 (win modem?) */ 1090 {0x0303c31e, NULL}, /* GVC0303 - MaxTech 33.6 PnP D/F/V */ 1091 {0x0505c31e, NULL}, /* GVC0505 - GVC 56k Faxmodem */ 1092 {0x0050c31e, NULL}, /* GVC5000 - some GVC modem */ 1093 {0x3800f91e, NULL}, /* GWY0038 - Telepath with v.90 */ --- 29 unchanged lines hidden (view full) --- 1123 {0x70207256, NULL}, /* USR2070 - U.S.Robotics Inc. Sportster 560 */ 1124 {0x30307256, NULL}, /* USR3030 - U.S. Robotics 56K FAX INT */ 1125 {0x31307256, NULL}, /* USR3031 - U.S. Robotics 56K FAX INT */ 1126 {0x50307256, NULL}, /* USR3050 - U.S. Robotics 56K FAX INT */ 1127 {0x70307256, NULL}, /* USR3070 - U.S. Robotics 56K Voice INT */ 1128 {0x90307256, NULL}, /* USR3090 - USR ? */ 1129 {0x90917256, NULL}, /* USR9190 - USR 56k Voice INT */ 1130 {0x0300695c, NULL}, /* WCI0003 - Fax/Voice/Modem/Speakphone/Asvd */ | 1083 {0x00b4490a, NULL}, /* BRIB400 - Boca 56k PnP */ 1084 {0x0030320d, NULL}, /* CIR3000 - Cirrus Logic V43 */ 1085 {0x0100440e, NULL}, /* CRD0001 - Cardinal MVP288IV ? */ 1086 {0x1200c31e, NULL}, /* GVC0012 - VF1128HV-R9 (win modem?) */ 1087 {0x0303c31e, NULL}, /* GVC0303 - MaxTech 33.6 PnP D/F/V */ 1088 {0x0505c31e, NULL}, /* GVC0505 - GVC 56k Faxmodem */ 1089 {0x0050c31e, NULL}, /* GVC5000 - some GVC modem */ 1090 {0x3800f91e, NULL}, /* GWY0038 - Telepath with v.90 */ --- 29 unchanged lines hidden (view full) --- 1120 {0x70207256, NULL}, /* USR2070 - U.S.Robotics Inc. Sportster 560 */ 1121 {0x30307256, NULL}, /* USR3030 - U.S. Robotics 56K FAX INT */ 1122 {0x31307256, NULL}, /* USR3031 - U.S. Robotics 56K FAX INT */ 1123 {0x50307256, NULL}, /* USR3050 - U.S. Robotics 56K FAX INT */ 1124 {0x70307256, NULL}, /* USR3070 - U.S. Robotics 56K Voice INT */ 1125 {0x90307256, NULL}, /* USR3090 - USR ? */ 1126 {0x90917256, NULL}, /* USR9190 - USR 56k Voice INT */ 1127 {0x0300695c, NULL}, /* WCI0003 - Fax/Voice/Modem/Speakphone/Asvd */ |
1128 {0x01a0896a, NULL}, /* ZTIA001 - Zoom Internal V90 Faxmodem */ |
|
1131 {0x61f7896a, NULL}, /* ZTIF761 - Zoom ComStar 33.6 */ 1132#ifdef PC98 1133 {0x0100e4a5, "RSA-98III"}, 1134#endif 1135 {0} 1136}; 1137 1138 --- 33 unchanged lines hidden (view full) --- 1172 intrmask_t irqmap[4]; 1173 intrmask_t irqs; 1174 u_char mcr_image; 1175 int result; 1176 u_long xirq; 1177 u_int flags = device_get_flags(dev); 1178 int rid; 1179 struct resource *port; | 1129 {0x61f7896a, NULL}, /* ZTIF761 - Zoom ComStar 33.6 */ 1130#ifdef PC98 1131 {0x0100e4a5, "RSA-98III"}, 1132#endif 1133 {0} 1134}; 1135 1136 --- 33 unchanged lines hidden (view full) --- 1170 intrmask_t irqmap[4]; 1171 intrmask_t irqs; 1172 u_char mcr_image; 1173 int result; 1174 u_long xirq; 1175 u_int flags = device_get_flags(dev); 1176 int rid; 1177 struct resource *port; |
1178 int intrsave; |
|
1180#ifdef PC98 1181 int tmp; 1182 struct siodev iod; 1183#endif 1184 1185#ifdef PC98 1186 iod.if_type = GET_IFTYPE(flags); 1187 if ((iod.if_type < 0 || iod.if_type > COM_IF_END1) && --- 222 unchanged lines hidden (view full) --- 1410#endif 1411 1412 /* 1413 * We don't want to get actual interrupts, just masked ones. 1414 * Interrupts from this line should already be masked in the ICU, 1415 * but mask them in the processor as well in case there are some 1416 * (misconfigured) shared interrupts. 1417 */ | 1179#ifdef PC98 1180 int tmp; 1181 struct siodev iod; 1182#endif 1183 1184#ifdef PC98 1185 iod.if_type = GET_IFTYPE(flags); 1186 if ((iod.if_type < 0 || iod.if_type > COM_IF_END1) && --- 222 unchanged lines hidden (view full) --- 1409#endif 1410 1411 /* 1412 * We don't want to get actual interrupts, just masked ones. 1413 * Interrupts from this line should already be masked in the ICU, 1414 * but mask them in the processor as well in case there are some 1415 * (misconfigured) shared interrupts. 1416 */ |
1417 intrsave = save_intr(); |
|
1418 disable_intr(); | 1418 disable_intr(); |
1419 COM_LOCK(); |
|
1419/* EXTRA DELAY? */ 1420 1421 /* 1422 * Initialize the speed and the word size and wait long enough to 1423 * drain the maximum of 16 bytes of junk in device output queues. 1424 * The speed is undefined after a master reset and must be set 1425 * before relying on anything related to output. There may be 1426 * junk after a (very fast) soft reboot and (apparently) after --- 93 unchanged lines hidden (view full) --- 1520 /* Unknown, Just omit this chip.. XXX */ 1521 result = ENXIO; 1522 } 1523 } else { 1524 /* OK. this is well-known guys */ 1525 CLR_FLAG(dev, COM_C_IIR_TXRDYBUG); 1526 } 1527 sio_setreg(com, com_cfcr, CFCR_8BITS); | 1420/* EXTRA DELAY? */ 1421 1422 /* 1423 * Initialize the speed and the word size and wait long enough to 1424 * drain the maximum of 16 bytes of junk in device output queues. 1425 * The speed is undefined after a master reset and must be set 1426 * before relying on anything related to output. There may be 1427 * junk after a (very fast) soft reboot and (apparently) after --- 93 unchanged lines hidden (view full) --- 1521 /* Unknown, Just omit this chip.. XXX */ 1522 result = ENXIO; 1523 } 1524 } else { 1525 /* OK. this is well-known guys */ 1526 CLR_FLAG(dev, COM_C_IIR_TXRDYBUG); 1527 } 1528 sio_setreg(com, com_cfcr, CFCR_8BITS); |
1528 enable_intr(); | 1529 COM_UNLOCK(); 1530 restore_intr(intrsave); |
1529 bus_release_resource(dev, SYS_RES_IOPORT, rid, port); 1530 return (iobase == siocniobase ? 0 : result); 1531 } 1532 1533 /* 1534 * Check that 1535 * o the CFCR, IER and MCR in UART hold the values written to them 1536 * (the values happen to be all distinct - this is good for --- 41 unchanged lines hidden (view full) --- 1578 failures[9] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND; 1579#ifdef PC98 1580 if (iod.if_type == COM_IF_RSA98III) { 1581 inb(iobase + rsa_srr); 1582 outb(iobase + rsa_frr, 0x00); 1583 } 1584#endif 1585 | 1531 bus_release_resource(dev, SYS_RES_IOPORT, rid, port); 1532 return (iobase == siocniobase ? 0 : result); 1533 } 1534 1535 /* 1536 * Check that 1537 * o the CFCR, IER and MCR in UART hold the values written to them 1538 * (the values happen to be all distinct - this is good for --- 41 unchanged lines hidden (view full) --- 1580 failures[9] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND; 1581#ifdef PC98 1582 if (iod.if_type == COM_IF_RSA98III) { 1583 inb(iobase + rsa_srr); 1584 outb(iobase + rsa_frr, 0x00); 1585 } 1586#endif 1587 |
1586 enable_intr(); | 1588 COM_UNLOCK(); 1589 restore_intr(intrsave); |
1587 1588 irqs = irqmap[1] & ~irqmap[0]; 1589 if (bus_get_resource(idev, SYS_RES_IRQ, 0, &xirq, NULL) == 0 && 1590 ((1 << xirq) & irqs) == 0) 1591 printf( 1592 "sio%d: configured irq %ld not in bitmap of probed irqs %#x\n", 1593 device_get_unit(dev), xirq, irqs); 1594 if (bootverbose) --- 261 unchanged lines hidden (view full) --- 1856 com->it_in.c_lflag = TTYDEF_LFLAG; 1857 com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL; 1858 com->lt_out.c_ispeed = com->lt_out.c_ospeed = 1859 com->lt_in.c_ispeed = com->lt_in.c_ospeed = 1860 com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate; 1861 } else 1862 com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED; 1863 if (siosetwater(com, com->it_in.c_ispeed) != 0) { | 1590 1591 irqs = irqmap[1] & ~irqmap[0]; 1592 if (bus_get_resource(idev, SYS_RES_IRQ, 0, &xirq, NULL) == 0 && 1593 ((1 << xirq) & irqs) == 0) 1594 printf( 1595 "sio%d: configured irq %ld not in bitmap of probed irqs %#x\n", 1596 device_get_unit(dev), xirq, irqs); 1597 if (bootverbose) --- 261 unchanged lines hidden (view full) --- 1859 com->it_in.c_lflag = TTYDEF_LFLAG; 1860 com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL; 1861 com->lt_out.c_ispeed = com->lt_out.c_ospeed = 1862 com->lt_in.c_ispeed = com->lt_in.c_ospeed = 1863 com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate; 1864 } else 1865 com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED; 1866 if (siosetwater(com, com->it_in.c_ispeed) != 0) { |
1864 enable_intr(); | |
1865 /* 1866 * Leave i/o resources allocated if this is a `cn'-level 1867 * console, so that other devices can't snarf them. 1868 */ 1869 if (iobase != siocniobase) 1870 bus_release_resource(dev, SYS_RES_IOPORT, rid, port); 1871 return (ENOMEM); 1872 } | 1867 /* 1868 * Leave i/o resources allocated if this is a `cn'-level 1869 * console, so that other devices can't snarf them. 1870 */ 1871 if (iobase != siocniobase) 1872 bus_release_resource(dev, SYS_RES_IOPORT, rid, port); 1873 return (ENOMEM); 1874 } |
1873 enable_intr(); | |
1874 termioschars(&com->it_in); 1875 com->it_out = com->it_in; 1876 1877 /* attempt to determine UART type */ 1878 printf("sio%d: type", unit); 1879 1880 1881#ifndef PC98 --- 212 unchanged lines hidden (view full) --- 2094 com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; 2095 pps_init(&com->pps); 2096 2097 rid = 0; 2098 com->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, 2099 RF_ACTIVE); 2100 if (com->irqres) { 2101 ret = BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres, | 1875 termioschars(&com->it_in); 1876 com->it_out = com->it_in; 1877 1878 /* attempt to determine UART type */ 1879 printf("sio%d: type", unit); 1880 1881 1882#ifndef PC98 --- 212 unchanged lines hidden (view full) --- 2095 com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; 2096 pps_init(&com->pps); 2097 2098 rid = 0; 2099 com->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, 2100 RF_ACTIVE); 2101 if (com->irqres) { 2102 ret = BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres, |
2102 INTR_TYPE_TTY | INTR_TYPE_FAST, | 2103 INTR_TYPE_TTY | INTR_FAST, |
2103 siointr, com, &com->cookie); 2104 if (ret) { 2105 ret = BUS_SETUP_INTR(device_get_parent(dev), dev, 2106 com->irqres, INTR_TYPE_TTY, 2107 siointr, com, &com->cookie); 2108 if (ret == 0) 2109 device_printf(dev, "unable to activate interrupt in fast mode - using normal mode"); 2110 } --- 67 unchanged lines hidden (view full) --- 2178 } 2179 } 2180 if (tp->t_state & TS_XCLUDE && 2181 suser(p)) { 2182 error = EBUSY; 2183 goto out; 2184 } 2185 } else { | 2104 siointr, com, &com->cookie); 2105 if (ret) { 2106 ret = BUS_SETUP_INTR(device_get_parent(dev), dev, 2107 com->irqres, INTR_TYPE_TTY, 2108 siointr, com, &com->cookie); 2109 if (ret == 0) 2110 device_printf(dev, "unable to activate interrupt in fast mode - using normal mode"); 2111 } --- 67 unchanged lines hidden (view full) --- 2179 } 2180 } 2181 if (tp->t_state & TS_XCLUDE && 2182 suser(p)) { 2183 error = EBUSY; 2184 goto out; 2185 } 2186 } else { |
2187 int intrsave; 2188 |
|
2186 /* 2187 * The device isn't open, so there are no conflicts. 2188 * Initialize it. Initialization is done twice in many 2189 * cases: to preempt sleeping callin opens if we are 2190 * callout, and to complete a callin open after DCD rises. 2191 */ 2192 tp->t_oproc = comstart; 2193 tp->t_param = comparam; --- 68 unchanged lines hidden (view full) --- 2262 break; 2263#endif 2264 sio_setreg(com, com_fifo, 0); 2265 DELAY(50); 2266 (void) inb(com->data_port); 2267 } 2268 } 2269 | 2189 /* 2190 * The device isn't open, so there are no conflicts. 2191 * Initialize it. Initialization is done twice in many 2192 * cases: to preempt sleeping callin opens if we are 2193 * callout, and to complete a callin open after DCD rises. 2194 */ 2195 tp->t_oproc = comstart; 2196 tp->t_param = comparam; --- 68 unchanged lines hidden (view full) --- 2265 break; 2266#endif 2267 sio_setreg(com, com_fifo, 0); 2268 DELAY(50); 2269 (void) inb(com->data_port); 2270 } 2271 } 2272 |
2273 intrsave = save_intr(); |
|
2270 disable_intr(); | 2274 disable_intr(); |
2275 COM_LOCK(); |
|
2271#ifdef PC98 2272 if (IS_8251(com->pc98_if_type)) { 2273 com_tiocm_bis(com, TIOCM_LE); 2274 com->pc98_prev_modem_status = pc98_get_modem_status(com); 2275 com_int_Rx_enable(com); 2276 } else { 2277#endif 2278 (void) inb(com->line_status_port); --- 11 unchanged lines hidden (view full) --- 2290 if (com->pc98_if_type == COM_IF_RSA98III) { 2291 outb(com->rsabase + rsa_ier, 0x1d); 2292 outb(com->intr_ctl_port, IER_ERLS | IER_EMSC); 2293 } 2294#endif 2295#ifdef PC98 2296 } 2297#endif | 2276#ifdef PC98 2277 if (IS_8251(com->pc98_if_type)) { 2278 com_tiocm_bis(com, TIOCM_LE); 2279 com->pc98_prev_modem_status = pc98_get_modem_status(com); 2280 com_int_Rx_enable(com); 2281 } else { 2282#endif 2283 (void) inb(com->line_status_port); --- 11 unchanged lines hidden (view full) --- 2295 if (com->pc98_if_type == COM_IF_RSA98III) { 2296 outb(com->rsabase + rsa_ier, 0x1d); 2297 outb(com->intr_ctl_port, IER_ERLS | IER_EMSC); 2298 } 2299#endif 2300#ifdef PC98 2301 } 2302#endif |
2298 enable_intr(); | 2303 COM_UNLOCK(); 2304 restore_intr(intrsave); |
2299 /* 2300 * Handle initial DCD. Callout devices get a fake initial 2301 * DCD (trapdoor DCD). If we are callout, then any sleeping 2302 * callin opens get woken up and resume sleeping on "siobi" 2303 * instead of "siodcd". 2304 */ 2305 /* 2306 * XXX `mynor & CALLOUT_MASK' should be --- 271 unchanged lines hidden (view full) --- 2578{ 2579 struct com_s *com; 2580 2581 com = (struct com_s *)chan; 2582 com->state &= ~CS_DTR_OFF; 2583 wakeup(&com->dtr_wait); 2584} 2585 | 2305 /* 2306 * Handle initial DCD. Callout devices get a fake initial 2307 * DCD (trapdoor DCD). If we are callout, then any sleeping 2308 * callin opens get woken up and resume sleeping on "siobi" 2309 * instead of "siodcd". 2310 */ 2311 /* 2312 * XXX `mynor & CALLOUT_MASK' should be --- 271 unchanged lines hidden (view full) --- 2584{ 2585 struct com_s *com; 2586 2587 com = (struct com_s *)chan; 2588 com->state &= ~CS_DTR_OFF; 2589 wakeup(&com->dtr_wait); 2590} 2591 |
2592/* 2593 * Call this function with COM_LOCK. It will return with the lock still held. 2594 */ |
|
2586static void 2587sioinput(com) 2588 struct com_s *com; 2589{ 2590 u_char *buf; 2591 int incc; 2592 u_char line_status; 2593 int recv_data; 2594 struct tty *tp; | 2595static void 2596sioinput(com) 2597 struct com_s *com; 2598{ 2599 u_char *buf; 2600 int incc; 2601 u_char line_status; 2602 int recv_data; 2603 struct tty *tp; |
2604 int intrsave; |
|
2595 2596 buf = com->ibuf; 2597 tp = com->tp; 2598 if (!(tp->t_state & TS_ISOPEN) || !(tp->t_cflag & CREAD)) { 2599 com_events -= (com->iptr - com->ibuf); 2600 com->iptr = com->ibuf; 2601 return; 2602 } 2603 if (tp->t_state & TS_CAN_BYPASS_L_RINT) { 2604 /* 2605 * Avoid the grotesquely inefficient lineswitch routine 2606 * (ttyinput) in "raw" mode. It usually takes about 450 2607 * instructions (that's without canonical processing or echo!). 2608 * slinput is reasonably fast (usually 40 instructions plus 2609 * call overhead). 2610 */ 2611 do { | 2605 2606 buf = com->ibuf; 2607 tp = com->tp; 2608 if (!(tp->t_state & TS_ISOPEN) || !(tp->t_cflag & CREAD)) { 2609 com_events -= (com->iptr - com->ibuf); 2610 com->iptr = com->ibuf; 2611 return; 2612 } 2613 if (tp->t_state & TS_CAN_BYPASS_L_RINT) { 2614 /* 2615 * Avoid the grotesquely inefficient lineswitch routine 2616 * (ttyinput) in "raw" mode. It usually takes about 450 2617 * instructions (that's without canonical processing or echo!). 2618 * slinput is reasonably fast (usually 40 instructions plus 2619 * call overhead). 2620 */ 2621 do { |
2622 /* 2623 * This may look odd, but it is using save-and-enable 2624 * semantics instead of the save-and-disable semantics 2625 * that are used everywhere else. 2626 */ 2627 intrsave = save_intr(); 2628 COM_UNLOCK(); |
|
2612 enable_intr(); 2613 incc = com->iptr - buf; 2614 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat 2615 && (com->state & CS_RTS_IFLOW 2616 || tp->t_iflag & IXOFF) 2617 && !(tp->t_state & TS_TBLOCK)) 2618 ttyblock(tp); 2619 com->delta_error_counts[CE_TTY_BUF_OVERFLOW] --- 5 unchanged lines hidden (view full) --- 2625 ttwakeup(tp); 2626 if (tp->t_state & TS_TTSTOP 2627 && (tp->t_iflag & IXANY 2628 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { 2629 tp->t_state &= ~TS_TTSTOP; 2630 tp->t_lflag &= ~FLUSHO; 2631 comstart(tp); 2632 } | 2629 enable_intr(); 2630 incc = com->iptr - buf; 2631 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat 2632 && (com->state & CS_RTS_IFLOW 2633 || tp->t_iflag & IXOFF) 2634 && !(tp->t_state & TS_TBLOCK)) 2635 ttyblock(tp); 2636 com->delta_error_counts[CE_TTY_BUF_OVERFLOW] --- 5 unchanged lines hidden (view full) --- 2642 ttwakeup(tp); 2643 if (tp->t_state & TS_TTSTOP 2644 && (tp->t_iflag & IXANY 2645 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { 2646 tp->t_state &= ~TS_TTSTOP; 2647 tp->t_lflag &= ~FLUSHO; 2648 comstart(tp); 2649 } |
2633 disable_intr(); | 2650 restore_intr(intrsave); 2651 COM_LOCK(); |
2634 } while (buf < com->iptr); 2635 } else { 2636 do { | 2652 } while (buf < com->iptr); 2653 } else { 2654 do { |
2655 /* 2656 * This may look odd, but it is using save-and-enable 2657 * semantics instead of the save-and-disable semantics 2658 * that are used everywhere else. 2659 */ 2660 intrsave = save_intr(); 2661 COM_UNLOCK(); |
|
2637 enable_intr(); 2638 line_status = buf[com->ierroff]; 2639 recv_data = *buf++; 2640 if (line_status 2641 & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) { 2642 if (line_status & LSR_BI) 2643 recv_data |= TTY_BI; 2644 if (line_status & LSR_FE) 2645 recv_data |= TTY_FE; 2646 if (line_status & LSR_OE) 2647 recv_data |= TTY_OE; 2648 if (line_status & LSR_PE) 2649 recv_data |= TTY_PE; 2650 } 2651 (*linesw[tp->t_line].l_rint)(recv_data, tp); | 2662 enable_intr(); 2663 line_status = buf[com->ierroff]; 2664 recv_data = *buf++; 2665 if (line_status 2666 & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) { 2667 if (line_status & LSR_BI) 2668 recv_data |= TTY_BI; 2669 if (line_status & LSR_FE) 2670 recv_data |= TTY_FE; 2671 if (line_status & LSR_OE) 2672 recv_data |= TTY_OE; 2673 if (line_status & LSR_PE) 2674 recv_data |= TTY_PE; 2675 } 2676 (*linesw[tp->t_line].l_rint)(recv_data, tp); |
2652 disable_intr(); | 2677 restore_intr(intrsave); 2678 COM_LOCK(); |
2653 } while (buf < com->iptr); 2654 } 2655 com_events -= (com->iptr - com->ibuf); 2656 com->iptr = com->ibuf; 2657 2658 /* 2659 * There is now room for another low-level buffer full of input, 2660 * so enable RTS if it is now disabled and there is room in the --- 225 unchanged lines hidden (view full) --- 2886 setsofttty(); 2887 ioptr = com->iptr; 2888 if (ioptr >= com->ibufend) 2889 CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW); 2890 else { 2891 if (com->do_timestamp) 2892 microtime(&com->timestamp); 2893 ++com_events; | 2679 } while (buf < com->iptr); 2680 } 2681 com_events -= (com->iptr - com->ibuf); 2682 com->iptr = com->ibuf; 2683 2684 /* 2685 * There is now room for another low-level buffer full of input, 2686 * so enable RTS if it is now disabled and there is room in the --- 225 unchanged lines hidden (view full) --- 2912 setsofttty(); 2913 ioptr = com->iptr; 2914 if (ioptr >= com->ibufend) 2915 CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW); 2916 else { 2917 if (com->do_timestamp) 2918 microtime(&com->timestamp); 2919 ++com_events; |
2920/* XXX - needs to go away when alpha gets ithreads */ 2921#ifdef __alpha__ |
|
2894 schedsofttty(); | 2922 schedsofttty(); |
2923#endif |
|
2895#if 0 /* for testing input latency vs efficiency */ 2896if (com->iptr - com->ibuf == 8) 2897 setsofttty(); 2898#endif 2899 ioptr[0] = recv_data; 2900 ioptr[com->ierroff] = line_status; 2901 com->iptr = ++ioptr; 2902 if (ioptr == com->ihighwater --- 405 unchanged lines hidden (view full) --- 3308 } 3309#ifdef PC98 3310 } 3311#endif 3312 splx(s); 3313 return (0); 3314} 3315 | 2924#if 0 /* for testing input latency vs efficiency */ 2925if (com->iptr - com->ibuf == 8) 2926 setsofttty(); 2927#endif 2928 ioptr[0] = recv_data; 2929 ioptr[com->ierroff] = line_status; 2930 com->iptr = ++ioptr; 2931 if (ioptr == com->ihighwater --- 405 unchanged lines hidden (view full) --- 3337 } 3338#ifdef PC98 3339 } 3340#endif 3341 splx(s); 3342 return (0); 3343} 3344 |
3345/* software interrupt handler for SWI_TTY */ |
|
3316static void 3317siopoll() 3318{ 3319 int unit; | 3346static void 3347siopoll() 3348{ 3349 int unit; |
3350 int intrsave; |
|
3320 3321 if (com_events == 0) 3322 return; 3323repeat: 3324 for (unit = 0; unit < sio_numunits; ++unit) { 3325 struct com_s *com; 3326 int incc; 3327 struct tty *tp; 3328 3329 com = com_addr(unit); 3330 if (com == NULL) 3331 continue; 3332 tp = com->tp; 3333 if (tp == NULL || com->gone) { 3334 /* 3335 * Discard any events related to never-opened or 3336 * going-away devices. 3337 */ | 3351 3352 if (com_events == 0) 3353 return; 3354repeat: 3355 for (unit = 0; unit < sio_numunits; ++unit) { 3356 struct com_s *com; 3357 int incc; 3358 struct tty *tp; 3359 3360 com = com_addr(unit); 3361 if (com == NULL) 3362 continue; 3363 tp = com->tp; 3364 if (tp == NULL || com->gone) { 3365 /* 3366 * Discard any events related to never-opened or 3367 * going-away devices. 3368 */ |
3369 intrsave = save_intr(); |
|
3338 disable_intr(); | 3370 disable_intr(); |
3371 COM_LOCK(); |
|
3339 incc = com->iptr - com->ibuf; 3340 com->iptr = com->ibuf; 3341 if (com->state & CS_CHECKMSR) { 3342 incc += LOTS_OF_EVENTS; 3343 com->state &= ~CS_CHECKMSR; 3344 } 3345 com_events -= incc; | 3372 incc = com->iptr - com->ibuf; 3373 com->iptr = com->ibuf; 3374 if (com->state & CS_CHECKMSR) { 3375 incc += LOTS_OF_EVENTS; 3376 com->state &= ~CS_CHECKMSR; 3377 } 3378 com_events -= incc; |
3346 enable_intr(); | 3379 COM_UNLOCK(); 3380 restore_intr(intrsave); |
3347 continue; 3348 } 3349 if (com->iptr != com->ibuf) { | 3381 continue; 3382 } 3383 if (com->iptr != com->ibuf) { |
3384 intrsave = save_intr(); |
|
3350 disable_intr(); | 3385 disable_intr(); |
3386 COM_LOCK(); |
|
3351 sioinput(com); | 3387 sioinput(com); |
3352 enable_intr(); | 3388 COM_UNLOCK(); 3389 restore_intr(intrsave); |
3353 } 3354 if (com->state & CS_CHECKMSR) { 3355 u_char delta_modem_status; 3356 3357#ifdef PC98 3358 if (!IS_8251(com->pc98_if_type)) { 3359#endif | 3390 } 3391 if (com->state & CS_CHECKMSR) { 3392 u_char delta_modem_status; 3393 3394#ifdef PC98 3395 if (!IS_8251(com->pc98_if_type)) { 3396#endif |
3397 intrsave = save_intr(); |
|
3360 disable_intr(); | 3398 disable_intr(); |
3399 COM_LOCK(); |
|
3361 delta_modem_status = com->last_modem_status 3362 ^ com->prev_modem_status; 3363 com->prev_modem_status = com->last_modem_status; 3364 com_events -= LOTS_OF_EVENTS; 3365 com->state &= ~CS_CHECKMSR; | 3400 delta_modem_status = com->last_modem_status 3401 ^ com->prev_modem_status; 3402 com->prev_modem_status = com->last_modem_status; 3403 com_events -= LOTS_OF_EVENTS; 3404 com->state &= ~CS_CHECKMSR; |
3366 enable_intr(); | 3405 COM_UNLOCK(); 3406 restore_intr(intrsave); |
3367 if (delta_modem_status & MSR_DCD) 3368 (*linesw[tp->t_line].l_modem) 3369 (tp, com->prev_modem_status & MSR_DCD); 3370#ifdef PC98 3371 } 3372#endif 3373 } 3374 if (com->state & CS_ODONE) { | 3407 if (delta_modem_status & MSR_DCD) 3408 (*linesw[tp->t_line].l_modem) 3409 (tp, com->prev_modem_status & MSR_DCD); 3410#ifdef PC98 3411 } 3412#endif 3413 } 3414 if (com->state & CS_ODONE) { |
3415 intrsave = save_intr(); |
|
3375 disable_intr(); | 3416 disable_intr(); |
3417 COM_LOCK(); |
|
3376 com_events -= LOTS_OF_EVENTS; 3377 com->state &= ~CS_ODONE; | 3418 com_events -= LOTS_OF_EVENTS; 3419 com->state &= ~CS_ODONE; |
3378 enable_intr(); | 3420 COM_UNLOCK(); 3421 restore_intr(intrsave); |
3379 if (!(com->state & CS_BUSY) 3380 && !(com->extra_state & CSE_BUSYCHECK)) { 3381 timeout(siobusycheck, com, hz / 100); 3382 com->extra_state |= CSE_BUSYCHECK; 3383 } 3384 (*linesw[tp->t_line].l_start)(tp); 3385 } 3386 if (com_events == 0) --- 11 unchanged lines hidden (view full) --- 3398 u_int cfcr; 3399 int cflag; 3400 struct com_s *com; 3401 int divisor; 3402 u_char dlbh; 3403 u_char dlbl; 3404 int s; 3405 int unit; | 3422 if (!(com->state & CS_BUSY) 3423 && !(com->extra_state & CSE_BUSYCHECK)) { 3424 timeout(siobusycheck, com, hz / 100); 3425 com->extra_state |= CSE_BUSYCHECK; 3426 } 3427 (*linesw[tp->t_line].l_start)(tp); 3428 } 3429 if (com_events == 0) --- 11 unchanged lines hidden (view full) --- 3441 u_int cfcr; 3442 int cflag; 3443 struct com_s *com; 3444 int divisor; 3445 u_char dlbh; 3446 u_char dlbl; 3447 int s; 3448 int unit; |
3449 int intrsave; |
|
3406#ifdef PC98 3407 u_char param = 0; 3408#endif 3409 3410#ifdef PC98 3411 unit = DEV_TO_UNIT(tp->t_dev); 3412 com = com_addr(unit); 3413 --- 87 unchanged lines hidden (view full) --- 3501 com->fifo_image |= FIFO_DMA_MODE; 3502#endif 3503 sio_setreg(com, com_fifo, com->fifo_image); 3504 } 3505#ifdef PC98 3506 } 3507#endif 3508 | 3450#ifdef PC98 3451 u_char param = 0; 3452#endif 3453 3454#ifdef PC98 3455 unit = DEV_TO_UNIT(tp->t_dev); 3456 com = com_addr(unit); 3457 --- 87 unchanged lines hidden (view full) --- 3545 com->fifo_image |= FIFO_DMA_MODE; 3546#endif 3547 sio_setreg(com, com_fifo, com->fifo_image); 3548 } 3549#ifdef PC98 3550 } 3551#endif 3552 |
3509 /* 3510 * This returns with interrupts disabled so that we can complete 3511 * the speed change atomically. Keeping interrupts disabled is 3512 * especially important while com_data is hidden. 3513 */ | 3553 intrsave = save_intr(); 3554 disable_intr(); 3555 COM_LOCK(); 3556 |
3514 (void) siosetwater(com, t->c_ispeed); 3515 3516#ifdef PC98 3517 if (IS_8251(com->pc98_if_type)) 3518 com_cflag_and_speed_set(com, cflag, t->c_ospeed); 3519 else { 3520#endif 3521 if (divisor != 0) { --- 111 unchanged lines hidden (view full) --- 3633 /* 3634 * Recover from fiddling with CS_TTGO. We used to call siointr1() 3635 * unconditionally, but that defeated the careful discarding of 3636 * stale input in sioopen(). 3637 */ 3638 if (com->state >= (CS_BUSY | CS_TTGO)) 3639 siointr1(com); 3640 | 3557 (void) siosetwater(com, t->c_ispeed); 3558 3559#ifdef PC98 3560 if (IS_8251(com->pc98_if_type)) 3561 com_cflag_and_speed_set(com, cflag, t->c_ospeed); 3562 else { 3563#endif 3564 if (divisor != 0) { --- 111 unchanged lines hidden (view full) --- 3676 /* 3677 * Recover from fiddling with CS_TTGO. We used to call siointr1() 3678 * unconditionally, but that defeated the careful discarding of 3679 * stale input in sioopen(). 3680 */ 3681 if (com->state >= (CS_BUSY | CS_TTGO)) 3682 siointr1(com); 3683 |
3641 enable_intr(); | 3684 COM_UNLOCK(); 3685 restore_intr(intrsave); |
3642 splx(s); 3643 comstart(tp); 3644 if (com->ibufold != NULL) { 3645 free(com->ibufold, M_DEVBUF); 3646 com->ibufold = NULL; 3647 } 3648 return (0); 3649} 3650 3651static int 3652siosetwater(com, speed) 3653 struct com_s *com; 3654 speed_t speed; 3655{ 3656 int cp4ticks; 3657 u_char *ibuf; 3658 int ibufsize; 3659 struct tty *tp; | 3686 splx(s); 3687 comstart(tp); 3688 if (com->ibufold != NULL) { 3689 free(com->ibufold, M_DEVBUF); 3690 com->ibufold = NULL; 3691 } 3692 return (0); 3693} 3694 3695static int 3696siosetwater(com, speed) 3697 struct com_s *com; 3698 speed_t speed; 3699{ 3700 int cp4ticks; 3701 u_char *ibuf; 3702 int ibufsize; 3703 struct tty *tp; |
3704 int intrsave; |
|
3660 3661 /* 3662 * Make the buffer size large enough to handle a softtty interrupt 3663 * latency of about 2 ticks without loss of throughput or data 3664 * (about 3 ticks if input flow control is not used or not honoured, 3665 * but a bit less for CS5-CS7 modes). 3666 */ 3667 cp4ticks = speed / 10 / hz * 4; 3668 for (ibufsize = 128; ibufsize < cp4ticks;) 3669 ibufsize <<= 1; 3670#ifdef PC98 3671 if (com->pc98_if_type == COM_IF_RSA98III) 3672 ibufsize = 2048; 3673#endif | 3705 3706 /* 3707 * Make the buffer size large enough to handle a softtty interrupt 3708 * latency of about 2 ticks without loss of throughput or data 3709 * (about 3 ticks if input flow control is not used or not honoured, 3710 * but a bit less for CS5-CS7 modes). 3711 */ 3712 cp4ticks = speed / 10 / hz * 4; 3713 for (ibufsize = 128; ibufsize < cp4ticks;) 3714 ibufsize <<= 1; 3715#ifdef PC98 3716 if (com->pc98_if_type == COM_IF_RSA98III) 3717 ibufsize = 2048; 3718#endif |
3674 if (ibufsize == com->ibufsize) { 3675 disable_intr(); | 3719 if (ibufsize == com->ibufsize) |
3676 return (0); | 3720 return (0); |
3677 } | |
3678 3679 /* 3680 * Allocate input buffer. The extra factor of 2 in the size is 3681 * to allow for an error byte for each input byte. 3682 */ 3683 ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT); | 3721 3722 /* 3723 * Allocate input buffer. The extra factor of 2 in the size is 3724 * to allow for an error byte for each input byte. 3725 */ 3726 ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT); |
3684 if (ibuf == NULL) { 3685 disable_intr(); | 3727 if (ibuf == NULL) |
3686 return (ENOMEM); | 3728 return (ENOMEM); |
3687 } | |
3688 3689 /* Initialize non-critical variables. */ 3690 com->ibufold = com->ibuf; 3691 com->ibufsize = ibufsize; 3692 tp = com->tp; 3693 if (tp != NULL) { 3694 tp->t_ififosize = 2 * ibufsize; 3695 tp->t_ispeedwat = (speed_t)-1; 3696 tp->t_ospeedwat = (speed_t)-1; 3697 } 3698 3699 /* 3700 * Read current input buffer, if any. Continue with interrupts 3701 * disabled. 3702 */ | 3729 3730 /* Initialize non-critical variables. */ 3731 com->ibufold = com->ibuf; 3732 com->ibufsize = ibufsize; 3733 tp = com->tp; 3734 if (tp != NULL) { 3735 tp->t_ififosize = 2 * ibufsize; 3736 tp->t_ispeedwat = (speed_t)-1; 3737 tp->t_ospeedwat = (speed_t)-1; 3738 } 3739 3740 /* 3741 * Read current input buffer, if any. Continue with interrupts 3742 * disabled. 3743 */ |
3744 intrsave = save_intr(); |
|
3703 disable_intr(); | 3745 disable_intr(); |
3746 COM_LOCK(); |
|
3704 if (com->iptr != com->ibuf) 3705 sioinput(com); 3706 3707 /*- 3708 * Initialize critical variables, including input buffer watermarks. 3709 * The external device is asked to stop sending when the buffer 3710 * exactly reaches high water, or when the high level requests it. 3711 * The high level is notified immediately (rather than at a later 3712 * clock tick) when this watermark is reached. 3713 * The buffer size is chosen so the watermark should almost never 3714 * be reached. 3715 * The low watermark is invisibly 0 since the buffer is always 3716 * emptied all at once. 3717 */ 3718 com->iptr = com->ibuf = ibuf; 3719 com->ibufend = ibuf + ibufsize; 3720 com->ierroff = ibufsize; 3721 com->ihighwater = ibuf + 3 * ibufsize / 4; | 3747 if (com->iptr != com->ibuf) 3748 sioinput(com); 3749 3750 /*- 3751 * Initialize critical variables, including input buffer watermarks. 3752 * The external device is asked to stop sending when the buffer 3753 * exactly reaches high water, or when the high level requests it. 3754 * The high level is notified immediately (rather than at a later 3755 * clock tick) when this watermark is reached. 3756 * The buffer size is chosen so the watermark should almost never 3757 * be reached. 3758 * The low watermark is invisibly 0 since the buffer is always 3759 * emptied all at once. 3760 */ 3761 com->iptr = com->ibuf = ibuf; 3762 com->ibufend = ibuf + ibufsize; 3763 com->ierroff = ibufsize; 3764 com->ihighwater = ibuf + 3 * ibufsize / 4; |
3765 COM_UNLOCK(); 3766 restore_intr(intrsave); |
|
3722 return (0); 3723} 3724 3725static void 3726comstart(tp) 3727 struct tty *tp; 3728{ 3729 struct com_s *com; 3730 int s; 3731 int unit; | 3767 return (0); 3768} 3769 3770static void 3771comstart(tp) 3772 struct tty *tp; 3773{ 3774 struct com_s *com; 3775 int s; 3776 int unit; |
3777 int intrsave; |
|
3732 3733 unit = DEV_TO_UNIT(tp->t_dev); 3734 com = com_addr(unit); 3735 if (com == NULL) 3736 return; 3737 s = spltty(); | 3778 3779 unit = DEV_TO_UNIT(tp->t_dev); 3780 com = com_addr(unit); 3781 if (com == NULL) 3782 return; 3783 s = spltty(); |
3784 intrsave = save_intr(); |
|
3738 disable_intr(); | 3785 disable_intr(); |
3786 COM_LOCK(); |
|
3739 if (tp->t_state & TS_TTSTOP) 3740 com->state &= ~CS_TTGO; 3741 else 3742 com->state |= CS_TTGO; 3743 if (tp->t_state & TS_TBLOCK) { 3744#ifdef PC98 3745 if (IS_8251(com->pc98_if_type)) { 3746 if ((com_tiocm_get(com) & TIOCM_RTS) && --- 22 unchanged lines hidden (view full) --- 3769 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); 3770 } 3771#else 3772 if (!(com->mcr_image & MCR_RTS) && com->iptr < com->ihighwater 3773 && com->state & CS_RTS_IFLOW) 3774 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); 3775#endif 3776 } | 3787 if (tp->t_state & TS_TTSTOP) 3788 com->state &= ~CS_TTGO; 3789 else 3790 com->state |= CS_TTGO; 3791 if (tp->t_state & TS_TBLOCK) { 3792#ifdef PC98 3793 if (IS_8251(com->pc98_if_type)) { 3794 if ((com_tiocm_get(com) & TIOCM_RTS) && --- 22 unchanged lines hidden (view full) --- 3817 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); 3818 } 3819#else 3820 if (!(com->mcr_image & MCR_RTS) && com->iptr < com->ihighwater 3821 && com->state & CS_RTS_IFLOW) 3822 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); 3823#endif 3824 } |
3777 enable_intr(); | 3825 COM_UNLOCK(); 3826 restore_intr(intrsave); |
3778 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { 3779 ttwwakeup(tp); 3780 splx(s); 3781 return; 3782 } 3783 if (tp->t_outq.c_cc != 0) { 3784 struct lbq *qp; 3785 struct lbq *next; 3786 3787 if (!com->obufs[0].l_queued) { 3788 com->obufs[0].l_tail 3789 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1, 3790#ifdef PC98 3791 com->obufsize); 3792#else 3793 sizeof com->obuf1); 3794#endif 3795 com->obufs[0].l_next = NULL; 3796 com->obufs[0].l_queued = TRUE; | 3827 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { 3828 ttwwakeup(tp); 3829 splx(s); 3830 return; 3831 } 3832 if (tp->t_outq.c_cc != 0) { 3833 struct lbq *qp; 3834 struct lbq *next; 3835 3836 if (!com->obufs[0].l_queued) { 3837 com->obufs[0].l_tail 3838 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1, 3839#ifdef PC98 3840 com->obufsize); 3841#else 3842 sizeof com->obuf1); 3843#endif 3844 com->obufs[0].l_next = NULL; 3845 com->obufs[0].l_queued = TRUE; |
3846 intrsave = save_intr(); |
|
3797 disable_intr(); | 3847 disable_intr(); |
3848 COM_LOCK(); |
|
3798 if (com->state & CS_BUSY) { 3799 qp = com->obufq.l_next; 3800 while ((next = qp->l_next) != NULL) 3801 qp = next; 3802 qp->l_next = &com->obufs[0]; 3803 } else { 3804 com->obufq.l_head = com->obufs[0].l_head; 3805 com->obufq.l_tail = com->obufs[0].l_tail; 3806 com->obufq.l_next = &com->obufs[0]; 3807 com->state |= CS_BUSY; 3808 } | 3849 if (com->state & CS_BUSY) { 3850 qp = com->obufq.l_next; 3851 while ((next = qp->l_next) != NULL) 3852 qp = next; 3853 qp->l_next = &com->obufs[0]; 3854 } else { 3855 com->obufq.l_head = com->obufs[0].l_head; 3856 com->obufq.l_tail = com->obufs[0].l_tail; 3857 com->obufq.l_next = &com->obufs[0]; 3858 com->state |= CS_BUSY; 3859 } |
3809 enable_intr(); | 3860 COM_UNLOCK(); 3861 restore_intr(intrsave); |
3810 } 3811 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { 3812 com->obufs[1].l_tail 3813 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2, 3814#ifdef PC98 3815 com->obufsize); 3816#else 3817 sizeof com->obuf2); 3818#endif 3819 com->obufs[1].l_next = NULL; 3820 com->obufs[1].l_queued = TRUE; | 3862 } 3863 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) { 3864 com->obufs[1].l_tail 3865 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2, 3866#ifdef PC98 3867 com->obufsize); 3868#else 3869 sizeof com->obuf2); 3870#endif 3871 com->obufs[1].l_next = NULL; 3872 com->obufs[1].l_queued = TRUE; |
3873 intrsave = save_intr(); |
|
3821 disable_intr(); | 3874 disable_intr(); |
3875 COM_LOCK(); |
|
3822 if (com->state & CS_BUSY) { 3823 qp = com->obufq.l_next; 3824 while ((next = qp->l_next) != NULL) 3825 qp = next; 3826 qp->l_next = &com->obufs[1]; 3827 } else { 3828 com->obufq.l_head = com->obufs[1].l_head; 3829 com->obufq.l_tail = com->obufs[1].l_tail; 3830 com->obufq.l_next = &com->obufs[1]; 3831 com->state |= CS_BUSY; 3832 } | 3876 if (com->state & CS_BUSY) { 3877 qp = com->obufq.l_next; 3878 while ((next = qp->l_next) != NULL) 3879 qp = next; 3880 qp->l_next = &com->obufs[1]; 3881 } else { 3882 com->obufq.l_head = com->obufs[1].l_head; 3883 com->obufq.l_tail = com->obufs[1].l_tail; 3884 com->obufq.l_next = &com->obufs[1]; 3885 com->state |= CS_BUSY; 3886 } |
3833 enable_intr(); | 3887 COM_UNLOCK(); 3888 restore_intr(intrsave); |
3834 } 3835 tp->t_state |= TS_BUSY; 3836 } | 3889 } 3890 tp->t_state |= TS_BUSY; 3891 } |
3892 intrsave = save_intr(); |
|
3837 disable_intr(); | 3893 disable_intr(); |
3894 COM_LOCK(); |
|
3838 if (com->state >= (CS_BUSY | CS_TTGO)) 3839 siointr1(com); /* fake interrupt to start output */ | 3895 if (com->state >= (CS_BUSY | CS_TTGO)) 3896 siointr1(com); /* fake interrupt to start output */ |
3840 enable_intr(); | 3897 COM_UNLOCK(); 3898 restore_intr(intrsave); |
3841 ttwwakeup(tp); 3842 splx(s); 3843} 3844 3845static void 3846comstop(tp, rw) 3847 struct tty *tp; 3848 int rw; 3849{ 3850 struct com_s *com; | 3899 ttwwakeup(tp); 3900 splx(s); 3901} 3902 3903static void 3904comstop(tp, rw) 3905 struct tty *tp; 3906 int rw; 3907{ 3908 struct com_s *com; |
3909 int intrsave; |
|
3851#ifdef PC98 3852 int rsa98_tmp = 0; 3853#endif 3854 3855 com = com_addr(DEV_TO_UNIT(tp->t_dev)); 3856 if (com == NULL || com->gone) 3857 return; | 3910#ifdef PC98 3911 int rsa98_tmp = 0; 3912#endif 3913 3914 com = com_addr(DEV_TO_UNIT(tp->t_dev)); 3915 if (com == NULL || com->gone) 3916 return; |
3917 intrsave = save_intr(); |
|
3858 disable_intr(); | 3918 disable_intr(); |
3919 COM_LOCK(); |
|
3859 if (rw & FWRITE) { 3860#ifdef PC98 3861 if (!IS_8251(com->pc98_if_type)) { 3862#endif 3863 if (com->hasfifo) 3864#ifdef COM_ESP 3865 /* XXX avoid h/w bug. */ 3866 if (!com->esp) --- 29 unchanged lines hidden (view full) --- 3896 sio_setreg(com, com_fifo, 3897 FIFO_RCV_RST | com->fifo_image); 3898#ifdef PC98 3899 } 3900#endif 3901 com_events -= (com->iptr - com->ibuf); 3902 com->iptr = com->ibuf; 3903 } | 3920 if (rw & FWRITE) { 3921#ifdef PC98 3922 if (!IS_8251(com->pc98_if_type)) { 3923#endif 3924 if (com->hasfifo) 3925#ifdef COM_ESP 3926 /* XXX avoid h/w bug. */ 3927 if (!com->esp) --- 29 unchanged lines hidden (view full) --- 3957 sio_setreg(com, com_fifo, 3958 FIFO_RCV_RST | com->fifo_image); 3959#ifdef PC98 3960 } 3961#endif 3962 com_events -= (com->iptr - com->ibuf); 3963 com->iptr = com->ibuf; 3964 } |
3904 enable_intr(); | 3965 COM_UNLOCK(); 3966 restore_intr(intrsave); |
3905 comstart(tp); 3906} 3907 3908static int 3909commctl(com, bits, how) 3910 struct com_s *com; 3911 int bits; 3912 int how; 3913{ 3914 int mcr; 3915 int msr; | 3967 comstart(tp); 3968} 3969 3970static int 3971commctl(com, bits, how) 3972 struct com_s *com; 3973 int bits; 3974 int how; 3975{ 3976 int mcr; 3977 int msr; |
3978 int intrsave; |
|
3916 3917 if (how == DMGET) { 3918 bits = TIOCM_LE; /* XXX - always enabled while open */ 3919 mcr = com->mcr_image; 3920 if (mcr & MCR_DTR) 3921 bits |= TIOCM_DTR; 3922 if (mcr & MCR_RTS) 3923 bits |= TIOCM_RTS; --- 15 unchanged lines hidden (view full) --- 3939 } 3940 mcr = 0; 3941 if (bits & TIOCM_DTR) 3942 mcr |= MCR_DTR; 3943 if (bits & TIOCM_RTS) 3944 mcr |= MCR_RTS; 3945 if (com->gone) 3946 return(0); | 3979 3980 if (how == DMGET) { 3981 bits = TIOCM_LE; /* XXX - always enabled while open */ 3982 mcr = com->mcr_image; 3983 if (mcr & MCR_DTR) 3984 bits |= TIOCM_DTR; 3985 if (mcr & MCR_RTS) 3986 bits |= TIOCM_RTS; --- 15 unchanged lines hidden (view full) --- 4002 } 4003 mcr = 0; 4004 if (bits & TIOCM_DTR) 4005 mcr |= MCR_DTR; 4006 if (bits & TIOCM_RTS) 4007 mcr |= MCR_RTS; 4008 if (com->gone) 4009 return(0); |
4010 intrsave = save_intr(); |
|
3947 disable_intr(); | 4011 disable_intr(); |
4012 COM_LOCK(); |
|
3948 switch (how) { 3949 case DMSET: 3950 outb(com->modem_ctl_port, 3951 com->mcr_image = mcr | (com->mcr_image & MCR_IENABLE)); 3952 break; 3953 case DMBIS: 3954 outb(com->modem_ctl_port, com->mcr_image |= mcr); 3955 break; 3956 case DMBIC: 3957 outb(com->modem_ctl_port, com->mcr_image &= ~mcr); 3958 break; 3959 } | 4013 switch (how) { 4014 case DMSET: 4015 outb(com->modem_ctl_port, 4016 com->mcr_image = mcr | (com->mcr_image & MCR_IENABLE)); 4017 break; 4018 case DMBIS: 4019 outb(com->modem_ctl_port, com->mcr_image |= mcr); 4020 break; 4021 case DMBIC: 4022 outb(com->modem_ctl_port, com->mcr_image &= ~mcr); 4023 break; 4024 } |
3960 enable_intr(); | 4025 COM_UNLOCK(); 4026 restore_intr(intrsave); |
3961 return (0); 3962} 3963 3964static void 3965siosettimeout() 3966{ 3967 struct com_s *com; 3968 bool_t someopen; --- 31 unchanged lines hidden (view full) --- 4000} 4001 4002static void 4003comwakeup(chan) 4004 void *chan; 4005{ 4006 struct com_s *com; 4007 int unit; | 4027 return (0); 4028} 4029 4030static void 4031siosettimeout() 4032{ 4033 struct com_s *com; 4034 bool_t someopen; --- 31 unchanged lines hidden (view full) --- 4066} 4067 4068static void 4069comwakeup(chan) 4070 void *chan; 4071{ 4072 struct com_s *com; 4073 int unit; |
4074 int intrsave; |
|
4008 4009 sio_timeout_handle = timeout(comwakeup, (void *)NULL, sio_timeout); 4010 4011 /* 4012 * Recover from lost output interrupts. 4013 * Poll any lines that don't use interrupts. 4014 */ 4015 for (unit = 0; unit < sio_numunits; ++unit) { 4016 com = com_addr(unit); 4017 if (com != NULL && !com->gone 4018 && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { | 4075 4076 sio_timeout_handle = timeout(comwakeup, (void *)NULL, sio_timeout); 4077 4078 /* 4079 * Recover from lost output interrupts. 4080 * Poll any lines that don't use interrupts. 4081 */ 4082 for (unit = 0; unit < sio_numunits; ++unit) { 4083 com = com_addr(unit); 4084 if (com != NULL && !com->gone 4085 && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { |
4086 intrsave = save_intr(); |
|
4019 disable_intr(); | 4087 disable_intr(); |
4088 COM_LOCK(); |
|
4020 siointr1(com); | 4089 siointr1(com); |
4021 enable_intr(); | 4090 COM_UNLOCK(); 4091 restore_intr(intrsave); |
4022 } 4023 } 4024 4025 /* 4026 * Check for and log errors, but not too often. 4027 */ 4028 if (--sio_timeouts_until_log > 0) 4029 return; --- 5 unchanged lines hidden (view full) --- 4035 if (com == NULL) 4036 continue; 4037 if (com->gone) 4038 continue; 4039 for (errnum = 0; errnum < CE_NTYPES; ++errnum) { 4040 u_int delta; 4041 u_long total; 4042 | 4092 } 4093 } 4094 4095 /* 4096 * Check for and log errors, but not too often. 4097 */ 4098 if (--sio_timeouts_until_log > 0) 4099 return; --- 5 unchanged lines hidden (view full) --- 4105 if (com == NULL) 4106 continue; 4107 if (com->gone) 4108 continue; 4109 for (errnum = 0; errnum < CE_NTYPES; ++errnum) { 4110 u_int delta; 4111 u_long total; 4112 |
4113 intrsave = save_intr(); |
|
4043 disable_intr(); | 4114 disable_intr(); |
4115 COM_LOCK(); |
|
4044 delta = com->delta_error_counts[errnum]; 4045 com->delta_error_counts[errnum] = 0; | 4116 delta = com->delta_error_counts[errnum]; 4117 com->delta_error_counts[errnum] = 0; |
4046 enable_intr(); | 4118 COM_UNLOCK(); 4119 restore_intr(intrsave); |
4047 if (delta == 0) 4048 continue; 4049 total = com->error_counts[errnum] += delta; 4050 log(LOG_ERR, "sio%d: %u more %s%s (total %lu)\n", 4051 unit, delta, error_desc[errnum], 4052 delta == 1 ? "" : "s", total); 4053 } 4054 } --- 1131 unchanged lines hidden --- | 4120 if (delta == 0) 4121 continue; 4122 total = com->error_counts[errnum] += delta; 4123 log(LOG_ERR, "sio%d: %u more %s%s (total %lu)\n", 4124 unit, delta, error_desc[errnum], 4125 delta == 1 ? "" : "s", total); 4126 } 4127 } --- 1131 unchanged lines hidden --- |