Deleted Added
full compact
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 ---