Deleted Added
full compact
sio.c (111616) sio.c (111815)
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
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
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
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
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/dev/sio/sio.c 111616 2003-02-27 12:53:21Z phk $
33 * $FreeBSD: head/sys/dev/sio/sio.c 111815 2003-03-03 12:15:54Z phk $
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"
42
43/*
44 * Serial driver, based on 386BSD-0.1 com driver.
45 * Mostly rewritten to use pseudo-DMA.
46 * Works for National Semiconductor NS8250-NS16550AF UARTs.
47 * COM driver, based on HP dca driver.
48 *
49 * Changes for PC-Card integration:
50 * - Added PC-Card driver table and handlers
51 */
52#include <sys/param.h>
53#include <sys/systm.h>
54#include <sys/bus.h>
55#include <sys/conf.h>
56#include <sys/fcntl.h>
57#include <sys/interrupt.h>
58#include <sys/kernel.h>
59#include <sys/lock.h>
60#include <sys/malloc.h>
61#include <sys/module.h>
62#include <sys/mutex.h>
63#include <sys/proc.h>
64#include <sys/reboot.h>
65#include <sys/sysctl.h>
66#include <sys/syslog.h>
67#include <sys/tty.h>
68#include <machine/bus_pio.h>
69#include <machine/bus.h>
70#include <sys/rman.h>
71#include <sys/timepps.h>
72#include <sys/uio.h>
73
74#include <isa/isavar.h>
75
76#include <machine/limits.h>
77#include <machine/resource.h>
78
79#include <dev/sio/sioreg.h>
80#include <dev/sio/siovar.h>
81
82#ifdef COM_ESP
83#include <dev/ic/esp.h>
84#endif
85#include <dev/ic/ns16550.h>
86
87#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
88
89#define CALLOUT_MASK 0x80
90#define CONTROL_MASK 0x60
91#define CONTROL_INIT_STATE 0x20
92#define CONTROL_LOCK_STATE 0x40
93#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev)))
94#define MINOR_TO_UNIT(mynor) ((((mynor) & ~0xffffU) >> (8 + 3)) \
95 | ((mynor) & 0x1f))
96#define UNIT_TO_MINOR(unit) ((((unit) & ~0x1fU) << (8 + 3)) \
97 | ((unit) & 0x1f))
98
99#ifdef COM_MULTIPORT
100/* checks in flags for multiport and which is multiport "master chip"
101 * for a given card
102 */
103#define COM_ISMULTIPORT(flags) ((flags) & 0x01)
104#define COM_MPMASTER(flags) (((flags) >> 8) & 0x0ff)
105#define COM_NOTAST4(flags) ((flags) & 0x04)
106#else
107#define COM_ISMULTIPORT(flags) (0)
108#endif /* COM_MULTIPORT */
109
110#define COM_CONSOLE(flags) ((flags) & 0x10)
111#define COM_FORCECONSOLE(flags) ((flags) & 0x20)
112#define COM_LLCONSOLE(flags) ((flags) & 0x40)
113#define COM_DEBUGGER(flags) ((flags) & 0x80)
114#define COM_LOSESOUTINTS(flags) ((flags) & 0x08)
115#define COM_NOFIFO(flags) ((flags) & 0x02)
116#define COM_PPSCTS(flags) ((flags) & 0x10000)
117#define COM_ST16650A(flags) ((flags) & 0x20000)
118#define COM_C_NOPROBE (0x40000)
119#define COM_NOPROBE(flags) ((flags) & COM_C_NOPROBE)
120#define COM_C_IIR_TXRDYBUG (0x80000)
121#define COM_IIR_TXRDYBUG(flags) ((flags) & COM_C_IIR_TXRDYBUG)
122#define COM_NOSCR(flags) ((flags) & 0x100000)
123#define COM_FIFOSIZE(flags) (((flags) & 0xff000000) >> 24)
124
125#define sio_getreg(com, off) \
126 (bus_space_read_1((com)->bst, (com)->bsh, (off)))
127#define sio_setreg(com, off, value) \
128 (bus_space_write_1((com)->bst, (com)->bsh, (off), (value)))
129
130/*
131 * com state bits.
132 * (CS_BUSY | CS_TTGO) and (CS_BUSY | CS_TTGO | CS_ODEVREADY) must be higher
133 * than the other bits so that they can be tested as a group without masking
134 * off the low bits.
135 *
136 * The following com and tty flags correspond closely:
137 * CS_BUSY = TS_BUSY (maintained by comstart(), siopoll() and
138 * comstop())
139 * CS_TTGO = ~TS_TTSTOP (maintained by comparam() and comstart())
140 * CS_CTS_OFLOW = CCTS_OFLOW (maintained by comparam())
141 * CS_RTS_IFLOW = CRTS_IFLOW (maintained by comparam())
142 * TS_FLUSH is not used.
143 * XXX I think TIOCSETA doesn't clear TS_TTSTOP when it clears IXON.
144 * XXX CS_*FLOW should be CF_*FLOW in com->flags (control flags not state).
145 */
146#define CS_BUSY 0x80 /* output in progress */
147#define CS_TTGO 0x40 /* output not stopped by XOFF */
148#define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */
149#define CS_CHECKMSR 1 /* check of MSR scheduled */
150#define CS_CTS_OFLOW 2 /* use CTS output flow control */
151#define CS_DTR_OFF 0x10 /* DTR held off */
152#define CS_ODONE 4 /* output completed */
153#define CS_RTS_IFLOW 8 /* use RTS input flow control */
154#define CSE_BUSYCHECK 1 /* siobusycheck() scheduled */
155
156static char const * const error_desc[] = {
157#define CE_OVERRUN 0
158 "silo overflow",
159#define CE_INTERRUPT_BUF_OVERFLOW 1
160 "interrupt-level buffer overflow",
161#define CE_TTY_BUF_OVERFLOW 2
162 "tty-level buffer overflow",
163};
164
165#define CE_NTYPES 3
166#define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum])
167
168/* types. XXX - should be elsewhere */
169typedef u_int Port_t; /* hardware port */
170typedef u_char bool_t; /* boolean */
171
172/* queue of linear buffers */
173struct lbq {
174 u_char *l_head; /* next char to process */
175 u_char *l_tail; /* one past the last char to process */
176 struct lbq *l_next; /* next in queue */
177 bool_t l_queued; /* nonzero if queued */
178};
179
180/* com device structure */
181struct com_s {
182 u_int flags; /* Copy isa device flags */
183 u_char state; /* miscellaneous flag bits */
184 bool_t active_out; /* nonzero if the callout device is open */
185 u_char cfcr_image; /* copy of value written to CFCR */
186#ifdef COM_ESP
187 bool_t esp; /* is this unit a hayes esp board? */
188#endif
189 u_char extra_state; /* more flag bits, separate for order trick */
190 u_char fifo_image; /* copy of value written to FIFO */
191 bool_t hasfifo; /* nonzero for 16550 UARTs */
192 bool_t st16650a; /* Is a Startech 16650A or RTS/CTS compat */
193 bool_t loses_outints; /* nonzero if device loses output interrupts */
194 u_char mcr_image; /* copy of value written to MCR */
195#ifdef COM_MULTIPORT
196 bool_t multiport; /* is this unit part of a multiport device? */
197#endif /* COM_MULTIPORT */
198 bool_t no_irq; /* nonzero if irq is not attached */
199 bool_t gone; /* hardware disappeared */
200 bool_t poll; /* nonzero if polling is required */
201 bool_t poll_output; /* nonzero if polling for output is required */
202 int unit; /* unit number */
203 int dtr_wait; /* time to hold DTR down on close (* 1/hz) */
204 u_int tx_fifo_size;
205 u_int wopeners; /* # processes waiting for DCD in open() */
206
207 /*
208 * The high level of the driver never reads status registers directly
209 * because there would be too many side effects to handle conveniently.
210 * Instead, it reads copies of the registers stored here by the
211 * interrupt handler.
212 */
213 u_char last_modem_status; /* last MSR read by intr handler */
214 u_char prev_modem_status; /* last MSR handled by high level */
215
216 u_char hotchar; /* ldisc-specific char to be handled ASAP */
217 u_char *ibuf; /* start of input buffer */
218 u_char *ibufend; /* end of input buffer */
219 u_char *ibufold; /* old input buffer, to be freed */
220 u_char *ihighwater; /* threshold in input buffer */
221 u_char *iptr; /* next free spot in input buffer */
222 int ibufsize; /* size of ibuf (not include error bytes) */
223 int ierroff; /* offset of error bytes in ibuf */
224
225 struct lbq obufq; /* head of queue of output buffers */
226 struct lbq obufs[2]; /* output buffers */
227
228 bus_space_tag_t bst;
229 bus_space_handle_t bsh;
230
231 Port_t data_port; /* i/o ports */
232#ifdef COM_ESP
233 Port_t esp_port;
234#endif
235 Port_t int_id_port;
236 Port_t modem_ctl_port;
237 Port_t line_status_port;
238 Port_t modem_status_port;
239 Port_t intr_ctl_port; /* Ports of IIR register */
240
241 struct tty *tp; /* cross reference */
242
243 /* Initial state. */
244 struct termios it_in; /* should be in struct tty */
245 struct termios it_out;
246
247 /* Lock state. */
248 struct termios lt_in; /* should be in struct tty */
249 struct termios lt_out;
250
251 bool_t do_timestamp;
252 bool_t do_dcd_timestamp;
253 struct timeval timestamp;
254 struct timeval dcd_timestamp;
255 struct pps_state pps;
256 int pps_bit;
257
258 u_long bytes_in; /* statistics */
259 u_long bytes_out;
260 u_int delta_error_counts[CE_NTYPES];
261 u_long error_counts[CE_NTYPES];
262
263 u_long rclk;
264
265 struct resource *irqres;
266 struct resource *ioportres;
267 void *cookie;
268 dev_t devs[6];
269
270 /*
271 * Data area for output buffers. Someday we should build the output
272 * buffer queue without copying data.
273 */
274 u_char obuf1[256];
275 u_char obuf2[256];
276};
277
278#ifdef COM_ESP
279static int espattach(struct com_s *com, Port_t esp_port);
280#endif
281
282static timeout_t siobusycheck;
283static u_int siodivisor(u_long rclk, speed_t speed);
284static timeout_t siodtrwakeup;
285static void comhardclose(struct com_s *com);
286static void sioinput(struct com_s *com);
287static void siointr1(struct com_s *com);
288static void siointr(void *arg);
289static int commctl(struct com_s *com, int bits, int how);
290static int comparam(struct tty *tp, struct termios *t);
291static void siopoll(void *);
292static void siosettimeout(void);
293static int siosetwater(struct com_s *com, speed_t speed);
294static void comstart(struct tty *tp);
295static void comstop(struct tty *tp, int rw);
296static timeout_t comwakeup;
297static void disc_optim(struct tty *tp, struct termios *t,
298 struct com_s *com);
299
300char sio_driver_name[] = "sio";
301static struct mtx sio_lock;
302static int sio_inited;
303
304/* table and macro for fast conversion from a unit number to its com struct */
305devclass_t sio_devclass;
306#define com_addr(unit) ((struct com_s *) \
307 devclass_get_softc(sio_devclass, unit)) /* XXX */
308
309static d_open_t sioopen;
310static d_close_t sioclose;
311static d_read_t sioread;
312static d_write_t siowrite;
313static d_ioctl_t sioioctl;
314
315#define CDEV_MAJOR 28
316static struct cdevsw sio_cdevsw = {
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"
42
43/*
44 * Serial driver, based on 386BSD-0.1 com driver.
45 * Mostly rewritten to use pseudo-DMA.
46 * Works for National Semiconductor NS8250-NS16550AF UARTs.
47 * COM driver, based on HP dca driver.
48 *
49 * Changes for PC-Card integration:
50 * - Added PC-Card driver table and handlers
51 */
52#include <sys/param.h>
53#include <sys/systm.h>
54#include <sys/bus.h>
55#include <sys/conf.h>
56#include <sys/fcntl.h>
57#include <sys/interrupt.h>
58#include <sys/kernel.h>
59#include <sys/lock.h>
60#include <sys/malloc.h>
61#include <sys/module.h>
62#include <sys/mutex.h>
63#include <sys/proc.h>
64#include <sys/reboot.h>
65#include <sys/sysctl.h>
66#include <sys/syslog.h>
67#include <sys/tty.h>
68#include <machine/bus_pio.h>
69#include <machine/bus.h>
70#include <sys/rman.h>
71#include <sys/timepps.h>
72#include <sys/uio.h>
73
74#include <isa/isavar.h>
75
76#include <machine/limits.h>
77#include <machine/resource.h>
78
79#include <dev/sio/sioreg.h>
80#include <dev/sio/siovar.h>
81
82#ifdef COM_ESP
83#include <dev/ic/esp.h>
84#endif
85#include <dev/ic/ns16550.h>
86
87#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
88
89#define CALLOUT_MASK 0x80
90#define CONTROL_MASK 0x60
91#define CONTROL_INIT_STATE 0x20
92#define CONTROL_LOCK_STATE 0x40
93#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev)))
94#define MINOR_TO_UNIT(mynor) ((((mynor) & ~0xffffU) >> (8 + 3)) \
95 | ((mynor) & 0x1f))
96#define UNIT_TO_MINOR(unit) ((((unit) & ~0x1fU) << (8 + 3)) \
97 | ((unit) & 0x1f))
98
99#ifdef COM_MULTIPORT
100/* checks in flags for multiport and which is multiport "master chip"
101 * for a given card
102 */
103#define COM_ISMULTIPORT(flags) ((flags) & 0x01)
104#define COM_MPMASTER(flags) (((flags) >> 8) & 0x0ff)
105#define COM_NOTAST4(flags) ((flags) & 0x04)
106#else
107#define COM_ISMULTIPORT(flags) (0)
108#endif /* COM_MULTIPORT */
109
110#define COM_CONSOLE(flags) ((flags) & 0x10)
111#define COM_FORCECONSOLE(flags) ((flags) & 0x20)
112#define COM_LLCONSOLE(flags) ((flags) & 0x40)
113#define COM_DEBUGGER(flags) ((flags) & 0x80)
114#define COM_LOSESOUTINTS(flags) ((flags) & 0x08)
115#define COM_NOFIFO(flags) ((flags) & 0x02)
116#define COM_PPSCTS(flags) ((flags) & 0x10000)
117#define COM_ST16650A(flags) ((flags) & 0x20000)
118#define COM_C_NOPROBE (0x40000)
119#define COM_NOPROBE(flags) ((flags) & COM_C_NOPROBE)
120#define COM_C_IIR_TXRDYBUG (0x80000)
121#define COM_IIR_TXRDYBUG(flags) ((flags) & COM_C_IIR_TXRDYBUG)
122#define COM_NOSCR(flags) ((flags) & 0x100000)
123#define COM_FIFOSIZE(flags) (((flags) & 0xff000000) >> 24)
124
125#define sio_getreg(com, off) \
126 (bus_space_read_1((com)->bst, (com)->bsh, (off)))
127#define sio_setreg(com, off, value) \
128 (bus_space_write_1((com)->bst, (com)->bsh, (off), (value)))
129
130/*
131 * com state bits.
132 * (CS_BUSY | CS_TTGO) and (CS_BUSY | CS_TTGO | CS_ODEVREADY) must be higher
133 * than the other bits so that they can be tested as a group without masking
134 * off the low bits.
135 *
136 * The following com and tty flags correspond closely:
137 * CS_BUSY = TS_BUSY (maintained by comstart(), siopoll() and
138 * comstop())
139 * CS_TTGO = ~TS_TTSTOP (maintained by comparam() and comstart())
140 * CS_CTS_OFLOW = CCTS_OFLOW (maintained by comparam())
141 * CS_RTS_IFLOW = CRTS_IFLOW (maintained by comparam())
142 * TS_FLUSH is not used.
143 * XXX I think TIOCSETA doesn't clear TS_TTSTOP when it clears IXON.
144 * XXX CS_*FLOW should be CF_*FLOW in com->flags (control flags not state).
145 */
146#define CS_BUSY 0x80 /* output in progress */
147#define CS_TTGO 0x40 /* output not stopped by XOFF */
148#define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */
149#define CS_CHECKMSR 1 /* check of MSR scheduled */
150#define CS_CTS_OFLOW 2 /* use CTS output flow control */
151#define CS_DTR_OFF 0x10 /* DTR held off */
152#define CS_ODONE 4 /* output completed */
153#define CS_RTS_IFLOW 8 /* use RTS input flow control */
154#define CSE_BUSYCHECK 1 /* siobusycheck() scheduled */
155
156static char const * const error_desc[] = {
157#define CE_OVERRUN 0
158 "silo overflow",
159#define CE_INTERRUPT_BUF_OVERFLOW 1
160 "interrupt-level buffer overflow",
161#define CE_TTY_BUF_OVERFLOW 2
162 "tty-level buffer overflow",
163};
164
165#define CE_NTYPES 3
166#define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum])
167
168/* types. XXX - should be elsewhere */
169typedef u_int Port_t; /* hardware port */
170typedef u_char bool_t; /* boolean */
171
172/* queue of linear buffers */
173struct lbq {
174 u_char *l_head; /* next char to process */
175 u_char *l_tail; /* one past the last char to process */
176 struct lbq *l_next; /* next in queue */
177 bool_t l_queued; /* nonzero if queued */
178};
179
180/* com device structure */
181struct com_s {
182 u_int flags; /* Copy isa device flags */
183 u_char state; /* miscellaneous flag bits */
184 bool_t active_out; /* nonzero if the callout device is open */
185 u_char cfcr_image; /* copy of value written to CFCR */
186#ifdef COM_ESP
187 bool_t esp; /* is this unit a hayes esp board? */
188#endif
189 u_char extra_state; /* more flag bits, separate for order trick */
190 u_char fifo_image; /* copy of value written to FIFO */
191 bool_t hasfifo; /* nonzero for 16550 UARTs */
192 bool_t st16650a; /* Is a Startech 16650A or RTS/CTS compat */
193 bool_t loses_outints; /* nonzero if device loses output interrupts */
194 u_char mcr_image; /* copy of value written to MCR */
195#ifdef COM_MULTIPORT
196 bool_t multiport; /* is this unit part of a multiport device? */
197#endif /* COM_MULTIPORT */
198 bool_t no_irq; /* nonzero if irq is not attached */
199 bool_t gone; /* hardware disappeared */
200 bool_t poll; /* nonzero if polling is required */
201 bool_t poll_output; /* nonzero if polling for output is required */
202 int unit; /* unit number */
203 int dtr_wait; /* time to hold DTR down on close (* 1/hz) */
204 u_int tx_fifo_size;
205 u_int wopeners; /* # processes waiting for DCD in open() */
206
207 /*
208 * The high level of the driver never reads status registers directly
209 * because there would be too many side effects to handle conveniently.
210 * Instead, it reads copies of the registers stored here by the
211 * interrupt handler.
212 */
213 u_char last_modem_status; /* last MSR read by intr handler */
214 u_char prev_modem_status; /* last MSR handled by high level */
215
216 u_char hotchar; /* ldisc-specific char to be handled ASAP */
217 u_char *ibuf; /* start of input buffer */
218 u_char *ibufend; /* end of input buffer */
219 u_char *ibufold; /* old input buffer, to be freed */
220 u_char *ihighwater; /* threshold in input buffer */
221 u_char *iptr; /* next free spot in input buffer */
222 int ibufsize; /* size of ibuf (not include error bytes) */
223 int ierroff; /* offset of error bytes in ibuf */
224
225 struct lbq obufq; /* head of queue of output buffers */
226 struct lbq obufs[2]; /* output buffers */
227
228 bus_space_tag_t bst;
229 bus_space_handle_t bsh;
230
231 Port_t data_port; /* i/o ports */
232#ifdef COM_ESP
233 Port_t esp_port;
234#endif
235 Port_t int_id_port;
236 Port_t modem_ctl_port;
237 Port_t line_status_port;
238 Port_t modem_status_port;
239 Port_t intr_ctl_port; /* Ports of IIR register */
240
241 struct tty *tp; /* cross reference */
242
243 /* Initial state. */
244 struct termios it_in; /* should be in struct tty */
245 struct termios it_out;
246
247 /* Lock state. */
248 struct termios lt_in; /* should be in struct tty */
249 struct termios lt_out;
250
251 bool_t do_timestamp;
252 bool_t do_dcd_timestamp;
253 struct timeval timestamp;
254 struct timeval dcd_timestamp;
255 struct pps_state pps;
256 int pps_bit;
257
258 u_long bytes_in; /* statistics */
259 u_long bytes_out;
260 u_int delta_error_counts[CE_NTYPES];
261 u_long error_counts[CE_NTYPES];
262
263 u_long rclk;
264
265 struct resource *irqres;
266 struct resource *ioportres;
267 void *cookie;
268 dev_t devs[6];
269
270 /*
271 * Data area for output buffers. Someday we should build the output
272 * buffer queue without copying data.
273 */
274 u_char obuf1[256];
275 u_char obuf2[256];
276};
277
278#ifdef COM_ESP
279static int espattach(struct com_s *com, Port_t esp_port);
280#endif
281
282static timeout_t siobusycheck;
283static u_int siodivisor(u_long rclk, speed_t speed);
284static timeout_t siodtrwakeup;
285static void comhardclose(struct com_s *com);
286static void sioinput(struct com_s *com);
287static void siointr1(struct com_s *com);
288static void siointr(void *arg);
289static int commctl(struct com_s *com, int bits, int how);
290static int comparam(struct tty *tp, struct termios *t);
291static void siopoll(void *);
292static void siosettimeout(void);
293static int siosetwater(struct com_s *com, speed_t speed);
294static void comstart(struct tty *tp);
295static void comstop(struct tty *tp, int rw);
296static timeout_t comwakeup;
297static void disc_optim(struct tty *tp, struct termios *t,
298 struct com_s *com);
299
300char sio_driver_name[] = "sio";
301static struct mtx sio_lock;
302static int sio_inited;
303
304/* table and macro for fast conversion from a unit number to its com struct */
305devclass_t sio_devclass;
306#define com_addr(unit) ((struct com_s *) \
307 devclass_get_softc(sio_devclass, unit)) /* XXX */
308
309static d_open_t sioopen;
310static d_close_t sioclose;
311static d_read_t sioread;
312static d_write_t siowrite;
313static d_ioctl_t sioioctl;
314
315#define CDEV_MAJOR 28
316static struct cdevsw sio_cdevsw = {
317 /* open */ sioopen,
318 /* close */ sioclose,
319 /* read */ sioread,
320 /* write */ siowrite,
321 /* ioctl */ sioioctl,
322 /* poll */ ttypoll,
323 /* mmap */ nommap,
324 /* strategy */ nostrategy,
325 /* name */ sio_driver_name,
326 /* maj */ CDEV_MAJOR,
327 /* dump */ nodump,
328 /* psize */ nopsize,
329 /* flags */ D_TTY | D_KQFILTER,
330 /* kqfilter */ ttykqfilter,
317 .d_open = sioopen,
318 .d_close = sioclose,
319 .d_read = sioread,
320 .d_write = siowrite,
321 .d_ioctl = sioioctl,
322 .d_poll = ttypoll,
323 .d_name = sio_driver_name,
324 .d_maj = CDEV_MAJOR,
325 .d_flags = D_TTY | D_KQFILTER,
326 .d_kqfilter = ttykqfilter,
331};
332
333int comconsole = -1;
334static volatile speed_t comdefaultrate = CONSPEED;
335static u_long comdefaultrclk = DEFAULT_RCLK;
336SYSCTL_ULONG(_machdep, OID_AUTO, conrclk, CTLFLAG_RW, &comdefaultrclk, 0, "");
337static speed_t gdbdefaultrate = GDBSPEED;
338SYSCTL_UINT(_machdep, OID_AUTO, gdbspeed, CTLFLAG_RW,
339 &gdbdefaultrate, GDBSPEED, "");
340static u_int com_events; /* input chars + weighted output completions */
341static Port_t siocniobase;
342static int siocnunit = -1;
343static Port_t siogdbiobase;
344static int siogdbunit = -1;
345static void *sio_slow_ih;
346static void *sio_fast_ih;
347static int sio_timeout;
348static int sio_timeouts_until_log;
349static struct callout_handle sio_timeout_handle
350 = CALLOUT_HANDLE_INITIALIZER(&sio_timeout_handle);
351static int sio_numunits;
352
353#ifdef COM_ESP
354/* XXX configure this properly. */
355/* XXX quite broken for new-bus. */
356static Port_t likely_com_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, };
357static Port_t likely_esp_ports[] = { 0x140, 0x180, 0x280, 0 };
358#endif
359
360/*
361 * handle sysctl read/write requests for console speed
362 *
363 * In addition to setting comdefaultrate for I/O through /dev/console,
364 * also set the initial and lock values for the /dev/ttyXX device
365 * if there is one associated with the console. Finally, if the /dev/tty
366 * device has already been open, change the speed on the open running port
367 * itself.
368 */
369
370static int
371sysctl_machdep_comdefaultrate(SYSCTL_HANDLER_ARGS)
372{
373 int error, s;
374 speed_t newspeed;
375 struct com_s *com;
376 struct tty *tp;
377
378 newspeed = comdefaultrate;
379
380 error = sysctl_handle_opaque(oidp, &newspeed, sizeof newspeed, req);
381 if (error || !req->newptr)
382 return (error);
383
384 comdefaultrate = newspeed;
385
386 if (comconsole < 0) /* serial console not selected? */
387 return (0);
388
389 com = com_addr(comconsole);
390 if (com == NULL)
391 return (ENXIO);
392
393 /*
394 * set the initial and lock rates for /dev/ttydXX and /dev/cuaXX
395 * (note, the lock rates really are boolean -- if non-zero, disallow
396 * speed changes)
397 */
398 com->it_in.c_ispeed = com->it_in.c_ospeed =
399 com->lt_in.c_ispeed = com->lt_in.c_ospeed =
400 com->it_out.c_ispeed = com->it_out.c_ospeed =
401 com->lt_out.c_ispeed = com->lt_out.c_ospeed = comdefaultrate;
402
403 /*
404 * if we're open, change the running rate too
405 */
406 tp = com->tp;
407 if (tp && (tp->t_state & TS_ISOPEN)) {
408 tp->t_termios.c_ispeed =
409 tp->t_termios.c_ospeed = comdefaultrate;
410 s = spltty();
411 error = comparam(tp, &tp->t_termios);
412 splx(s);
413 }
414 return error;
415}
416
417SYSCTL_PROC(_machdep, OID_AUTO, conspeed, CTLTYPE_INT | CTLFLAG_RW,
418 0, 0, sysctl_machdep_comdefaultrate, "I", "");
419/* TUNABLE_INT("machdep.conspeed", &comdefaultrate); */
420
421#define SET_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) | (bit))
422#define CLR_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) & ~(bit))
423
424/*
425 * Unload the driver and clear the table.
426 * XXX this is mostly wrong.
427 * XXX TODO:
428 * This is usually called when the card is ejected, but
429 * can be caused by a kldunload of a controller driver.
430 * The idea is to reset the driver's view of the device
431 * and ensure that any driver entry points such as
432 * read and write do not hang.
433 */
434int
435siodetach(dev)
436 device_t dev;
437{
438 struct com_s *com;
439 int i;
440
441 com = (struct com_s *) device_get_softc(dev);
442 if (com == NULL) {
443 device_printf(dev, "NULL com in siounload\n");
444 return (0);
445 }
446 com->gone = 1;
447 for (i = 0 ; i < 6; i++)
448 destroy_dev(com->devs[i]);
449 if (com->irqres) {
450 bus_teardown_intr(dev, com->irqres, com->cookie);
451 bus_release_resource(dev, SYS_RES_IRQ, 0, com->irqres);
452 }
453 if (com->ioportres)
454 bus_release_resource(dev, SYS_RES_IOPORT, 0, com->ioportres);
455 if (com->tp && (com->tp->t_state & TS_ISOPEN)) {
456 device_printf(dev, "still open, forcing close\n");
457 (*linesw[com->tp->t_line].l_close)(com->tp, 0);
458 com->tp->t_gen++;
459 ttyclose(com->tp);
460 ttwakeup(com->tp);
461 ttwwakeup(com->tp);
462 } else {
463 if (com->ibuf != NULL)
464 free(com->ibuf, M_DEVBUF);
465 device_set_softc(dev, NULL);
466 free(com, M_DEVBUF);
467 }
468 return (0);
469}
470
471int
472sioprobe(dev, xrid, rclk, noprobe)
473 device_t dev;
474 int xrid;
475 u_long rclk;
476 int noprobe;
477{
478#if 0
479 static bool_t already_init;
480 device_t xdev;
481#endif
482 struct com_s *com;
483 u_int divisor;
484 bool_t failures[10];
485 int fn;
486 device_t idev;
487 Port_t iobase;
488 intrmask_t irqmap[4];
489 intrmask_t irqs;
490 u_char mcr_image;
491 int result;
492 u_long xirq;
493 u_int flags = device_get_flags(dev);
494 int rid;
495 struct resource *port;
496
497 rid = xrid;
498 port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
499 0, ~0, IO_COMSIZE, RF_ACTIVE);
500 if (!port)
501 return (ENXIO);
502
503 com = malloc(sizeof(*com), M_DEVBUF, M_NOWAIT | M_ZERO);
504 if (com == NULL)
505 return (ENOMEM);
506 device_set_softc(dev, com);
507 com->bst = rman_get_bustag(port);
508 com->bsh = rman_get_bushandle(port);
509 if (rclk == 0)
510 rclk = DEFAULT_RCLK;
511 com->rclk = rclk;
512
513 while (sio_inited != 2)
514 if (atomic_cmpset_int(&sio_inited, 0, 1)) {
515 mtx_init(&sio_lock, sio_driver_name, NULL,
516 (comconsole != -1) ?
517 MTX_SPIN | MTX_QUIET : MTX_SPIN);
518 atomic_store_rel_int(&sio_inited, 2);
519 }
520
521#if 0
522 /*
523 * XXX this is broken - when we are first called, there are no
524 * previously configured IO ports. We could hard code
525 * 0x3f8, 0x2f8, 0x3e8, 0x2e8 etc but that's probably worse.
526 * This code has been doing nothing since the conversion since
527 * "count" is zero the first time around.
528 */
529 if (!already_init) {
530 /*
531 * Turn off MCR_IENABLE for all likely serial ports. An unused
532 * port with its MCR_IENABLE gate open will inhibit interrupts
533 * from any used port that shares the interrupt vector.
534 * XXX the gate enable is elsewhere for some multiports.
535 */
536 device_t *devs;
537 int count, i, xioport;
538
539 devclass_get_devices(sio_devclass, &devs, &count);
540 for (i = 0; i < count; i++) {
541 xdev = devs[i];
542 if (device_is_enabled(xdev) &&
543 bus_get_resource(xdev, SYS_RES_IOPORT, 0, &xioport,
544 NULL) == 0)
545 outb(xioport + com_mcr, 0);
546 }
547 free(devs, M_TEMP);
548 already_init = TRUE;
549 }
550#endif
551
552 if (COM_LLCONSOLE(flags)) {
553 printf("sio%d: reserved for low-level i/o\n",
554 device_get_unit(dev));
555 bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
556 device_set_softc(dev, NULL);
557 free(com, M_DEVBUF);
558 return (ENXIO);
559 }
560
561 /*
562 * If the device is on a multiport card and has an AST/4
563 * compatible interrupt control register, initialize this
564 * register and prepare to leave MCR_IENABLE clear in the mcr.
565 * Otherwise, prepare to set MCR_IENABLE in the mcr.
566 * Point idev to the device struct giving the correct id_irq.
567 * This is the struct for the master device if there is one.
568 */
569 idev = dev;
570 mcr_image = MCR_IENABLE;
571#ifdef COM_MULTIPORT
572 if (COM_ISMULTIPORT(flags)) {
573 Port_t xiobase;
574 u_long io;
575
576 idev = devclass_get_device(sio_devclass, COM_MPMASTER(flags));
577 if (idev == NULL) {
578 printf("sio%d: master device %d not configured\n",
579 device_get_unit(dev), COM_MPMASTER(flags));
580 idev = dev;
581 }
582 if (!COM_NOTAST4(flags)) {
583 if (bus_get_resource(idev, SYS_RES_IOPORT, 0, &io,
584 NULL) == 0) {
585 xiobase = io;
586 if (bus_get_resource(idev, SYS_RES_IRQ, 0,
587 NULL, NULL) == 0)
588 outb(xiobase + com_scr, 0x80);
589 else
590 outb(xiobase + com_scr, 0);
591 }
592 mcr_image = 0;
593 }
594 }
595#endif /* COM_MULTIPORT */
596 if (bus_get_resource(idev, SYS_RES_IRQ, 0, NULL, NULL) != 0)
597 mcr_image = 0;
598
599 bzero(failures, sizeof failures);
600 iobase = rman_get_start(port);
601
602 /*
603 * We don't want to get actual interrupts, just masked ones.
604 * Interrupts from this line should already be masked in the ICU,
605 * but mask them in the processor as well in case there are some
606 * (misconfigured) shared interrupts.
607 */
608 mtx_lock_spin(&sio_lock);
609/* EXTRA DELAY? */
610
611 /*
612 * Initialize the speed and the word size and wait long enough to
613 * drain the maximum of 16 bytes of junk in device output queues.
614 * The speed is undefined after a master reset and must be set
615 * before relying on anything related to output. There may be
616 * junk after a (very fast) soft reboot and (apparently) after
617 * master reset.
618 * XXX what about the UART bug avoided by waiting in comparam()?
619 * We don't want to to wait long enough to drain at 2 bps.
620 */
621 if (iobase == siocniobase)
622 DELAY((16 + 1) * 1000000 / (comdefaultrate / 10));
623 else {
624 sio_setreg(com, com_cfcr, CFCR_DLAB | CFCR_8BITS);
625 divisor = siodivisor(rclk, SIO_TEST_SPEED);
626 sio_setreg(com, com_dlbl, divisor & 0xff);
627 sio_setreg(com, com_dlbh, divisor >> 8);
628 sio_setreg(com, com_cfcr, CFCR_8BITS);
629 DELAY((16 + 1) * 1000000 / (SIO_TEST_SPEED / 10));
630 }
631
632 /*
633 * Enable the interrupt gate and disable device interupts. This
634 * should leave the device driving the interrupt line low and
635 * guarantee an edge trigger if an interrupt can be generated.
636 */
637/* EXTRA DELAY? */
638 sio_setreg(com, com_mcr, mcr_image);
639 sio_setreg(com, com_ier, 0);
640 DELAY(1000); /* XXX */
641 irqmap[0] = isa_irq_pending();
642
643 /*
644 * Attempt to set loopback mode so that we can send a null byte
645 * without annoying any external device.
646 */
647/* EXTRA DELAY? */
648 sio_setreg(com, com_mcr, mcr_image | MCR_LOOPBACK);
649
650 /*
651 * Attempt to generate an output interrupt. On 8250's, setting
652 * IER_ETXRDY generates an interrupt independent of the current
653 * setting and independent of whether the THR is empty. On 16450's,
654 * setting IER_ETXRDY generates an interrupt independent of the
655 * current setting. On 16550A's, setting IER_ETXRDY only
656 * generates an interrupt when IER_ETXRDY is not already set.
657 */
658 sio_setreg(com, com_ier, IER_ETXRDY);
659
660 /*
661 * On some 16x50 incompatibles, setting IER_ETXRDY doesn't generate
662 * an interrupt. They'd better generate one for actually doing
663 * output. Loopback may be broken on the same incompatibles but
664 * it's unlikely to do more than allow the null byte out.
665 */
666 sio_setreg(com, com_data, 0);
667 DELAY((1 + 2) * 1000000 / (SIO_TEST_SPEED / 10));
668
669 /*
670 * Turn off loopback mode so that the interrupt gate works again
671 * (MCR_IENABLE was hidden). This should leave the device driving
672 * an interrupt line high. It doesn't matter if the interrupt
673 * line oscillates while we are not looking at it, since interrupts
674 * are disabled.
675 */
676/* EXTRA DELAY? */
677 sio_setreg(com, com_mcr, mcr_image);
678
679 /*
680 * It seems my Xircom CBEM56G Cardbus modem wants to be reset
681 * to 8 bits *again*, or else probe test 0 will fail.
682 * gwk@sgi.com, 4/19/2001
683 */
684 sio_setreg(com, com_cfcr, CFCR_8BITS);
685
686 /*
687 * Some pcmcia cards have the "TXRDY bug", so we check everyone
688 * for IIR_TXRDY implementation ( Palido 321s, DC-1S... )
689 */
690 if (noprobe) {
691 /* Reading IIR register twice */
692 for (fn = 0; fn < 2; fn ++) {
693 DELAY(10000);
694 failures[6] = sio_getreg(com, com_iir);
695 }
696 /* Check IIR_TXRDY clear ? */
697 result = 0;
698 if (failures[6] & IIR_TXRDY) {
699 /* No, Double check with clearing IER */
700 sio_setreg(com, com_ier, 0);
701 if (sio_getreg(com, com_iir) & IIR_NOPEND) {
702 /* Ok. We discovered TXRDY bug! */
703 SET_FLAG(dev, COM_C_IIR_TXRDYBUG);
704 } else {
705 /* Unknown, Just omit this chip.. XXX */
706 result = ENXIO;
707 sio_setreg(com, com_mcr, 0);
708 }
709 } else {
710 /* OK. this is well-known guys */
711 CLR_FLAG(dev, COM_C_IIR_TXRDYBUG);
712 }
713 sio_setreg(com, com_ier, 0);
714 sio_setreg(com, com_cfcr, CFCR_8BITS);
715 mtx_unlock_spin(&sio_lock);
716 bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
717 if (iobase == siocniobase)
718 result = 0;
719 if (result != 0) {
720 device_set_softc(dev, NULL);
721 free(com, M_DEVBUF);
722 }
723 return (result);
724 }
725
726 /*
727 * Check that
728 * o the CFCR, IER and MCR in UART hold the values written to them
729 * (the values happen to be all distinct - this is good for
730 * avoiding false positive tests from bus echoes).
731 * o an output interrupt is generated and its vector is correct.
732 * o the interrupt goes away when the IIR in the UART is read.
733 */
734/* EXTRA DELAY? */
735 failures[0] = sio_getreg(com, com_cfcr) - CFCR_8BITS;
736 failures[1] = sio_getreg(com, com_ier) - IER_ETXRDY;
737 failures[2] = sio_getreg(com, com_mcr) - mcr_image;
738 DELAY(10000); /* Some internal modems need this time */
739 irqmap[1] = isa_irq_pending();
740 failures[4] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_TXRDY;
741 DELAY(1000); /* XXX */
742 irqmap[2] = isa_irq_pending();
743 failures[6] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND;
744
745 /*
746 * Turn off all device interrupts and check that they go off properly.
747 * Leave MCR_IENABLE alone. For ports without a master port, it gates
748 * the OUT2 output of the UART to
749 * the ICU input. Closing the gate would give a floating ICU input
750 * (unless there is another device driving it) and spurious interrupts.
751 * (On the system that this was first tested on, the input floats high
752 * and gives a (masked) interrupt as soon as the gate is closed.)
753 */
754 sio_setreg(com, com_ier, 0);
755 sio_setreg(com, com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */
756 failures[7] = sio_getreg(com, com_ier);
757 DELAY(1000); /* XXX */
758 irqmap[3] = isa_irq_pending();
759 failures[9] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND;
760
761 mtx_unlock_spin(&sio_lock);
762
763 irqs = irqmap[1] & ~irqmap[0];
764 if (bus_get_resource(idev, SYS_RES_IRQ, 0, &xirq, NULL) == 0 &&
765 ((1 << xirq) & irqs) == 0) {
766 printf(
767 "sio%d: configured irq %ld not in bitmap of probed irqs %#x\n",
768 device_get_unit(dev), xirq, irqs);
769 printf(
770 "sio%d: port may not be enabled\n",
771 device_get_unit(dev));
772 }
773 if (bootverbose)
774 printf("sio%d: irq maps: %#x %#x %#x %#x\n",
775 device_get_unit(dev),
776 irqmap[0], irqmap[1], irqmap[2], irqmap[3]);
777
778 result = 0;
779 for (fn = 0; fn < sizeof failures; ++fn)
780 if (failures[fn]) {
781 sio_setreg(com, com_mcr, 0);
782 result = ENXIO;
783 if (bootverbose) {
784 printf("sio%d: probe failed test(s):",
785 device_get_unit(dev));
786 for (fn = 0; fn < sizeof failures; ++fn)
787 if (failures[fn])
788 printf(" %d", fn);
789 printf("\n");
790 }
791 break;
792 }
793 bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
794 if (iobase == siocniobase)
795 result = 0;
796 if (result != 0) {
797 device_set_softc(dev, NULL);
798 free(com, M_DEVBUF);
799 }
800 return (result);
801}
802
803#ifdef COM_ESP
804static int
805espattach(com, esp_port)
806 struct com_s *com;
807 Port_t esp_port;
808{
809 u_char dips;
810 u_char val;
811
812 /*
813 * Check the ESP-specific I/O port to see if we're an ESP
814 * card. If not, return failure immediately.
815 */
816 if ((inb(esp_port) & 0xf3) == 0) {
817 printf(" port 0x%x is not an ESP board?\n", esp_port);
818 return (0);
819 }
820
821 /*
822 * We've got something that claims to be a Hayes ESP card.
823 * Let's hope so.
824 */
825
826 /* Get the dip-switch configuration */
827 outb(esp_port + ESP_CMD1, ESP_GETDIPS);
828 dips = inb(esp_port + ESP_STATUS1);
829
830 /*
831 * Bits 0,1 of dips say which COM port we are.
832 */
833 if (rman_get_start(com->ioportres) == likely_com_ports[dips & 0x03])
834 printf(" : ESP");
835 else {
836 printf(" esp_port has com %d\n", dips & 0x03);
837 return (0);
838 }
839
840 /*
841 * Check for ESP version 2.0 or later: bits 4,5,6 = 010.
842 */
843 outb(esp_port + ESP_CMD1, ESP_GETTEST);
844 val = inb(esp_port + ESP_STATUS1); /* clear reg 1 */
845 val = inb(esp_port + ESP_STATUS2);
846 if ((val & 0x70) < 0x20) {
847 printf("-old (%o)", val & 0x70);
848 return (0);
849 }
850
851 /*
852 * Check for ability to emulate 16550: bit 7 == 1
853 */
854 if ((dips & 0x80) == 0) {
855 printf(" slave");
856 return (0);
857 }
858
859 /*
860 * Okay, we seem to be a Hayes ESP card. Whee.
861 */
862 com->esp = TRUE;
863 com->esp_port = esp_port;
864 return (1);
865}
866#endif /* COM_ESP */
867
868int
869sioattach(dev, xrid, rclk)
870 device_t dev;
871 int xrid;
872 u_long rclk;
873{
874 struct com_s *com;
875#ifdef COM_ESP
876 Port_t *espp;
877#endif
878 Port_t iobase;
879 int minorbase;
880 int unit;
881 u_int flags;
882 int rid;
883 struct resource *port;
884 int ret;
885
886 rid = xrid;
887 port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
888 0, ~0, IO_COMSIZE, RF_ACTIVE);
889 if (!port)
890 return (ENXIO);
891
892 iobase = rman_get_start(port);
893 unit = device_get_unit(dev);
894 com = device_get_softc(dev);
895 flags = device_get_flags(dev);
896
897 if (unit >= sio_numunits)
898 sio_numunits = unit + 1;
899 /*
900 * sioprobe() has initialized the device registers as follows:
901 * o cfcr = CFCR_8BITS.
902 * It is most important that CFCR_DLAB is off, so that the
903 * data port is not hidden when we enable interrupts.
904 * o ier = 0.
905 * Interrupts are only enabled when the line is open.
906 * o mcr = MCR_IENABLE, or 0 if the port has AST/4 compatible
907 * interrupt control register or the config specifies no irq.
908 * Keeping MCR_DTR and MCR_RTS off might stop the external
909 * device from sending before we are ready.
910 */
911 bzero(com, sizeof *com);
912 com->unit = unit;
913 com->ioportres = port;
914 com->bst = rman_get_bustag(port);
915 com->bsh = rman_get_bushandle(port);
916 com->cfcr_image = CFCR_8BITS;
917 com->dtr_wait = 3 * hz;
918 com->loses_outints = COM_LOSESOUTINTS(flags) != 0;
919 com->no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0;
920 com->tx_fifo_size = 1;
921 com->obufs[0].l_head = com->obuf1;
922 com->obufs[1].l_head = com->obuf2;
923
924 com->data_port = iobase + com_data;
925 com->int_id_port = iobase + com_iir;
926 com->modem_ctl_port = iobase + com_mcr;
927 com->mcr_image = inb(com->modem_ctl_port);
928 com->line_status_port = iobase + com_lsr;
929 com->modem_status_port = iobase + com_msr;
930 com->intr_ctl_port = iobase + com_ier;
931
932 if (rclk == 0)
933 rclk = DEFAULT_RCLK;
934 com->rclk = rclk;
935
936 /*
937 * We don't use all the flags from <sys/ttydefaults.h> since they
938 * are only relevant for logins. It's important to have echo off
939 * initially so that the line doesn't start blathering before the
940 * echo flag can be turned off.
941 */
942 com->it_in.c_iflag = 0;
943 com->it_in.c_oflag = 0;
944 com->it_in.c_cflag = TTYDEF_CFLAG;
945 com->it_in.c_lflag = 0;
946 if (unit == comconsole) {
947 com->it_in.c_iflag = TTYDEF_IFLAG;
948 com->it_in.c_oflag = TTYDEF_OFLAG;
949 com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL;
950 com->it_in.c_lflag = TTYDEF_LFLAG;
951 com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
952 com->lt_out.c_ispeed = com->lt_out.c_ospeed =
953 com->lt_in.c_ispeed = com->lt_in.c_ospeed =
954 com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
955 } else
956 com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED;
957 if (siosetwater(com, com->it_in.c_ispeed) != 0) {
958 mtx_unlock_spin(&sio_lock);
959 /*
960 * Leave i/o resources allocated if this is a `cn'-level
961 * console, so that other devices can't snarf them.
962 */
963 if (iobase != siocniobase)
964 bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
965 return (ENOMEM);
966 }
967 mtx_unlock_spin(&sio_lock);
968 termioschars(&com->it_in);
969 com->it_out = com->it_in;
970
971 /* attempt to determine UART type */
972 printf("sio%d: type", unit);
973
974
975 if (!COM_ISMULTIPORT(flags) &&
976 !COM_IIR_TXRDYBUG(flags) && !COM_NOSCR(flags)) {
977 u_char scr;
978 u_char scr1;
979 u_char scr2;
980
981 scr = sio_getreg(com, com_scr);
982 sio_setreg(com, com_scr, 0xa5);
983 scr1 = sio_getreg(com, com_scr);
984 sio_setreg(com, com_scr, 0x5a);
985 scr2 = sio_getreg(com, com_scr);
986 sio_setreg(com, com_scr, scr);
987 if (scr1 != 0xa5 || scr2 != 0x5a) {
988 printf(" 8250 or not responding");
989 goto determined_type;
990 }
991 }
992 sio_setreg(com, com_fifo, FIFO_ENABLE | FIFO_RX_HIGH);
993 DELAY(100);
994 com->st16650a = 0;
995 switch (inb(com->int_id_port) & IIR_FIFO_MASK) {
996 case FIFO_RX_LOW:
997 printf(" 16450");
998 break;
999 case FIFO_RX_MEDL:
1000 printf(" 16450?");
1001 break;
1002 case FIFO_RX_MEDH:
1003 printf(" 16550?");
1004 break;
1005 case FIFO_RX_HIGH:
1006 if (COM_NOFIFO(flags)) {
1007 printf(" 16550A fifo disabled");
1008 } else {
1009 com->hasfifo = TRUE;
1010 if (COM_ST16650A(flags)) {
1011 com->st16650a = 1;
1012 com->tx_fifo_size = 32;
1013 printf(" ST16650A");
1014 } else {
1015 com->tx_fifo_size = COM_FIFOSIZE(flags);
1016 printf(" 16550A");
1017 }
1018 }
1019#ifdef COM_ESP
1020 for (espp = likely_esp_ports; *espp != 0; espp++)
1021 if (espattach(com, *espp)) {
1022 com->tx_fifo_size = 1024;
1023 break;
1024 }
1025#endif
1026 if (!com->st16650a) {
1027 if (!com->tx_fifo_size)
1028 com->tx_fifo_size = 16;
1029 else
1030 printf(" lookalike with %d bytes FIFO",
1031 com->tx_fifo_size);
1032 }
1033
1034 break;
1035 }
1036
1037#ifdef COM_ESP
1038 if (com->esp) {
1039 /*
1040 * Set 16550 compatibility mode.
1041 * We don't use the ESP_MODE_SCALE bit to increase the
1042 * fifo trigger levels because we can't handle large
1043 * bursts of input.
1044 * XXX flow control should be set in comparam(), not here.
1045 */
1046 outb(com->esp_port + ESP_CMD1, ESP_SETMODE);
1047 outb(com->esp_port + ESP_CMD2, ESP_MODE_RTS | ESP_MODE_FIFO);
1048
1049 /* Set RTS/CTS flow control. */
1050 outb(com->esp_port + ESP_CMD1, ESP_SETFLOWTYPE);
1051 outb(com->esp_port + ESP_CMD2, ESP_FLOW_RTS);
1052 outb(com->esp_port + ESP_CMD2, ESP_FLOW_CTS);
1053
1054 /* Set flow-control levels. */
1055 outb(com->esp_port + ESP_CMD1, ESP_SETRXFLOW);
1056 outb(com->esp_port + ESP_CMD2, HIBYTE(768));
1057 outb(com->esp_port + ESP_CMD2, LOBYTE(768));
1058 outb(com->esp_port + ESP_CMD2, HIBYTE(512));
1059 outb(com->esp_port + ESP_CMD2, LOBYTE(512));
1060 }
1061#endif /* COM_ESP */
1062 sio_setreg(com, com_fifo, 0);
1063determined_type: ;
1064
1065#ifdef COM_MULTIPORT
1066 if (COM_ISMULTIPORT(flags)) {
1067 device_t masterdev;
1068
1069 com->multiport = TRUE;
1070 printf(" (multiport");
1071 if (unit == COM_MPMASTER(flags))
1072 printf(" master");
1073 printf(")");
1074 masterdev = devclass_get_device(sio_devclass,
1075 COM_MPMASTER(flags));
1076 com->no_irq = (masterdev == NULL || bus_get_resource(masterdev,
1077 SYS_RES_IRQ, 0, NULL, NULL) != 0);
1078 }
1079#endif /* COM_MULTIPORT */
1080 if (unit == comconsole)
1081 printf(", console");
1082 if (COM_IIR_TXRDYBUG(flags))
1083 printf(" with a bogus IIR_TXRDY register");
1084 printf("\n");
1085
1086 if (sio_fast_ih == NULL) {
1087 swi_add(&tty_ithd, "tty:sio", siopoll, NULL, SWI_TTY, 0,
1088 &sio_fast_ih);
1089 swi_add(&clk_ithd, "tty:sio", siopoll, NULL, SWI_TTY, 0,
1090 &sio_slow_ih);
1091 }
1092 minorbase = UNIT_TO_MINOR(unit);
1093 com->devs[0] = make_dev(&sio_cdevsw, minorbase,
1094 UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit);
1095 com->devs[1] = make_dev(&sio_cdevsw, minorbase | CONTROL_INIT_STATE,
1096 UID_ROOT, GID_WHEEL, 0600, "ttyid%r", unit);
1097 com->devs[2] = make_dev(&sio_cdevsw, minorbase | CONTROL_LOCK_STATE,
1098 UID_ROOT, GID_WHEEL, 0600, "ttyld%r", unit);
1099 com->devs[3] = make_dev(&sio_cdevsw, minorbase | CALLOUT_MASK,
1100 UID_UUCP, GID_DIALER, 0660, "cuaa%r", unit);
1101 com->devs[4] = make_dev(&sio_cdevsw,
1102 minorbase | CALLOUT_MASK | CONTROL_INIT_STATE,
1103 UID_UUCP, GID_DIALER, 0660, "cuaia%r", unit);
1104 com->devs[5] = make_dev(&sio_cdevsw,
1105 minorbase | CALLOUT_MASK | CONTROL_LOCK_STATE,
1106 UID_UUCP, GID_DIALER, 0660, "cuala%r", unit);
1107 for (rid = 0; rid < 6; rid++)
1108 com->devs[rid]->si_drv1 = com;
1109 com->flags = flags;
1110 com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;
1111
1112 if (COM_PPSCTS(flags))
1113 com->pps_bit = MSR_CTS;
1114 else
1115 com->pps_bit = MSR_DCD;
1116 pps_init(&com->pps);
1117
1118 rid = 0;
1119 com->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1,
1120 RF_ACTIVE);
1121 if (com->irqres) {
1122 ret = BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres,
1123 INTR_TYPE_TTY | INTR_FAST,
1124 siointr, com, &com->cookie);
1125 if (ret) {
1126 ret = BUS_SETUP_INTR(device_get_parent(dev), dev,
1127 com->irqres, INTR_TYPE_TTY,
1128 siointr, com, &com->cookie);
1129 if (ret == 0)
1130 device_printf(dev, "unable to activate interrupt in fast mode - using normal mode\n");
1131 }
1132 if (ret)
1133 device_printf(dev, "could not activate interrupt\n");
1134#if defined(DDB) && (defined(BREAK_TO_DEBUGGER) || \
1135 defined(ALT_BREAK_TO_DEBUGGER))
1136 /*
1137 * Enable interrupts for early break-to-debugger support
1138 * on the console.
1139 */
1140 if (ret == 0 && unit == comconsole)
1141 outb(siocniobase + com_ier, IER_ERXRDY | IER_ERLS |
1142 IER_EMSC);
1143#endif
1144 }
1145
1146 return (0);
1147}
1148
1149static int
1150sioopen(dev, flag, mode, td)
1151 dev_t dev;
1152 int flag;
1153 int mode;
1154 struct thread *td;
1155{
1156 struct com_s *com;
1157 int error;
1158 int mynor;
1159 int s;
1160 struct tty *tp;
1161 int unit;
1162
1163 mynor = minor(dev);
1164 unit = MINOR_TO_UNIT(mynor);
1165 com = com_addr(unit);
1166 if (com == NULL)
1167 return (ENXIO);
1168 if (com->gone)
1169 return (ENXIO);
1170 if (mynor & CONTROL_MASK)
1171 return (0);
1172 tp = dev->si_tty = com->tp = ttymalloc(com->tp);
1173 s = spltty();
1174 /*
1175 * We jump to this label after all non-interrupted sleeps to pick
1176 * up any changes of the device state.
1177 */
1178open_top:
1179 while (com->state & CS_DTR_OFF) {
1180 error = tsleep(&com->dtr_wait, TTIPRI | PCATCH, "siodtr", 0);
1181 if (com_addr(unit) == NULL)
1182 return (ENXIO);
1183 if (error != 0 || com->gone)
1184 goto out;
1185 }
1186 if (tp->t_state & TS_ISOPEN) {
1187 /*
1188 * The device is open, so everything has been initialized.
1189 * Handle conflicts.
1190 */
1191 if (mynor & CALLOUT_MASK) {
1192 if (!com->active_out) {
1193 error = EBUSY;
1194 goto out;
1195 }
1196 } else {
1197 if (com->active_out) {
1198 if (flag & O_NONBLOCK) {
1199 error = EBUSY;
1200 goto out;
1201 }
1202 error = tsleep(&com->active_out,
1203 TTIPRI | PCATCH, "siobi", 0);
1204 if (com_addr(unit) == NULL)
1205 return (ENXIO);
1206 if (error != 0 || com->gone)
1207 goto out;
1208 goto open_top;
1209 }
1210 }
1211 if (tp->t_state & TS_XCLUDE &&
1212 suser(td)) {
1213 error = EBUSY;
1214 goto out;
1215 }
1216 } else {
1217 /*
1218 * The device isn't open, so there are no conflicts.
1219 * Initialize it. Initialization is done twice in many
1220 * cases: to preempt sleeping callin opens if we are
1221 * callout, and to complete a callin open after DCD rises.
1222 */
1223 tp->t_oproc = comstart;
1224 tp->t_param = comparam;
1225 tp->t_stop = comstop;
1226 tp->t_dev = dev;
1227 tp->t_termios = mynor & CALLOUT_MASK
1228 ? com->it_out : com->it_in;
1229 (void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET);
1230 com->poll = com->no_irq;
1231 com->poll_output = com->loses_outints;
1232 ++com->wopeners;
1233 error = comparam(tp, &tp->t_termios);
1234 --com->wopeners;
1235 if (error != 0)
1236 goto out;
1237 /*
1238 * XXX we should goto open_top if comparam() slept.
1239 */
1240 if (com->hasfifo) {
1241 int i;
1242 /*
1243 * (Re)enable and drain fifos.
1244 *
1245 * Certain SMC chips cause problems if the fifos
1246 * are enabled while input is ready. Turn off the
1247 * fifo if necessary to clear the input. We test
1248 * the input ready bit after enabling the fifos
1249 * since we've already enabled them in comparam()
1250 * and to handle races between enabling and fresh
1251 * input.
1252 */
1253 for (i = 0; i < 500; i++) {
1254 sio_setreg(com, com_fifo,
1255 FIFO_RCV_RST | FIFO_XMT_RST
1256 | com->fifo_image);
1257 /*
1258 * XXX the delays are for superstitious
1259 * historical reasons. It must be less than
1260 * the character time at the maximum
1261 * supported speed (87 usec at 115200 bps
1262 * 8N1). Otherwise we might loop endlessly
1263 * if data is streaming in. We used to use
1264 * delays of 100. That usually worked
1265 * because DELAY(100) used to usually delay
1266 * for about 85 usec instead of 100.
1267 */
1268 DELAY(50);
1269 if (!(inb(com->line_status_port) & LSR_RXRDY))
1270 break;
1271 sio_setreg(com, com_fifo, 0);
1272 DELAY(50);
1273 (void) inb(com->data_port);
1274 }
1275 if (i == 500) {
1276 error = EIO;
1277 goto out;
1278 }
1279 }
1280
1281 mtx_lock_spin(&sio_lock);
1282 (void) inb(com->line_status_port);
1283 (void) inb(com->data_port);
1284 com->prev_modem_status = com->last_modem_status
1285 = inb(com->modem_status_port);
1286 if (COM_IIR_TXRDYBUG(com->flags)) {
1287 outb(com->intr_ctl_port, IER_ERXRDY | IER_ERLS
1288 | IER_EMSC);
1289 } else {
1290 outb(com->intr_ctl_port, IER_ERXRDY | IER_ETXRDY
1291 | IER_ERLS | IER_EMSC);
1292 }
1293 mtx_unlock_spin(&sio_lock);
1294 /*
1295 * Handle initial DCD. Callout devices get a fake initial
1296 * DCD (trapdoor DCD). If we are callout, then any sleeping
1297 * callin opens get woken up and resume sleeping on "siobi"
1298 * instead of "siodcd".
1299 */
1300 /*
1301 * XXX `mynor & CALLOUT_MASK' should be
1302 * `tp->t_cflag & (SOFT_CARRIER | TRAPDOOR_CARRIER) where
1303 * TRAPDOOR_CARRIER is the default initial state for callout
1304 * devices and SOFT_CARRIER is like CLOCAL except it hides
1305 * the true carrier.
1306 */
1307 if (com->prev_modem_status & MSR_DCD || mynor & CALLOUT_MASK)
1308 (*linesw[tp->t_line].l_modem)(tp, 1);
1309 }
1310 /*
1311 * Wait for DCD if necessary.
1312 */
1313 if (!(tp->t_state & TS_CARR_ON) && !(mynor & CALLOUT_MASK)
1314 && !(tp->t_cflag & CLOCAL) && !(flag & O_NONBLOCK)) {
1315 ++com->wopeners;
1316 error = tsleep(TSA_CARR_ON(tp), TTIPRI | PCATCH, "siodcd", 0);
1317 if (com_addr(unit) == NULL)
1318 return (ENXIO);
1319 --com->wopeners;
1320 if (error != 0 || com->gone)
1321 goto out;
1322 goto open_top;
1323 }
1324 error = (*linesw[tp->t_line].l_open)(dev, tp);
1325 disc_optim(tp, &tp->t_termios, com);
1326 if (tp->t_state & TS_ISOPEN && mynor & CALLOUT_MASK)
1327 com->active_out = TRUE;
1328 siosettimeout();
1329out:
1330 splx(s);
1331 if (!(tp->t_state & TS_ISOPEN) && com->wopeners == 0)
1332 comhardclose(com);
1333 return (error);
1334}
1335
1336static int
1337sioclose(dev, flag, mode, td)
1338 dev_t dev;
1339 int flag;
1340 int mode;
1341 struct thread *td;
1342{
1343 struct com_s *com;
1344 int mynor;
1345 int s;
1346 struct tty *tp;
1347
1348 mynor = minor(dev);
1349 if (mynor & CONTROL_MASK)
1350 return (0);
1351 com = com_addr(MINOR_TO_UNIT(mynor));
1352 if (com == NULL)
1353 return (ENODEV);
1354 tp = com->tp;
1355 s = spltty();
1356 (*linesw[tp->t_line].l_close)(tp, flag);
1357 disc_optim(tp, &tp->t_termios, com);
1358 comstop(tp, FREAD | FWRITE);
1359 comhardclose(com);
1360 ttyclose(tp);
1361 siosettimeout();
1362 splx(s);
1363 if (com->gone) {
1364 printf("sio%d: gone\n", com->unit);
1365 s = spltty();
1366 if (com->ibuf != NULL)
1367 free(com->ibuf, M_DEVBUF);
1368 bzero(tp, sizeof *tp);
1369 splx(s);
1370 }
1371 return (0);
1372}
1373
1374static void
1375comhardclose(com)
1376 struct com_s *com;
1377{
1378 int s;
1379 struct tty *tp;
1380 int unit;
1381
1382 unit = com->unit;
1383 s = spltty();
1384 com->poll = FALSE;
1385 com->poll_output = FALSE;
1386 com->do_timestamp = FALSE;
1387 com->do_dcd_timestamp = FALSE;
1388 com->pps.ppsparam.mode = 0;
1389 sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
1390 tp = com->tp;
1391
1392#if defined(DDB) && (defined(BREAK_TO_DEBUGGER) || \
1393 defined(ALT_BREAK_TO_DEBUGGER))
1394 /*
1395 * Leave interrupts enabled and don't clear DTR if this is the
1396 * console. This allows us to detect break-to-debugger events
1397 * while the console device is closed.
1398 */
1399 if (com->unit != comconsole)
1400#endif
1401 {
1402 sio_setreg(com, com_ier, 0);
1403 if (tp->t_cflag & HUPCL
1404 /*
1405 * XXX we will miss any carrier drop between here and the
1406 * next open. Perhaps we should watch DCD even when the
1407 * port is closed; it is not sufficient to check it at
1408 * the next open because it might go up and down while
1409 * we're not watching.
1410 */
1411 || (!com->active_out
1412 && !(com->prev_modem_status & MSR_DCD)
1413 && !(com->it_in.c_cflag & CLOCAL))
1414 || !(tp->t_state & TS_ISOPEN)) {
1415 (void)commctl(com, TIOCM_DTR, DMBIC);
1416 if (com->dtr_wait != 0 && !(com->state & CS_DTR_OFF)) {
1417 timeout(siodtrwakeup, com, com->dtr_wait);
1418 com->state |= CS_DTR_OFF;
1419 }
1420 }
1421 }
1422 if (com->hasfifo) {
1423 /*
1424 * Disable fifos so that they are off after controlled
1425 * reboots. Some BIOSes fail to detect 16550s when the
1426 * fifos are enabled.
1427 */
1428 sio_setreg(com, com_fifo, 0);
1429 }
1430 com->active_out = FALSE;
1431 wakeup(&com->active_out);
1432 wakeup(TSA_CARR_ON(tp)); /* restart any wopeners */
1433 splx(s);
1434}
1435
1436static int
1437sioread(dev, uio, flag)
1438 dev_t dev;
1439 struct uio *uio;
1440 int flag;
1441{
1442 int mynor;
1443 struct com_s *com;
1444
1445 mynor = minor(dev);
1446 if (mynor & CONTROL_MASK)
1447 return (ENODEV);
1448 com = com_addr(MINOR_TO_UNIT(mynor));
1449 if (com == NULL || com->gone)
1450 return (ENODEV);
1451 return ((*linesw[com->tp->t_line].l_read)(com->tp, uio, flag));
1452}
1453
1454static int
1455siowrite(dev, uio, flag)
1456 dev_t dev;
1457 struct uio *uio;
1458 int flag;
1459{
1460 int mynor;
1461 struct com_s *com;
1462 int unit;
1463
1464 mynor = minor(dev);
1465 if (mynor & CONTROL_MASK)
1466 return (ENODEV);
1467
1468 unit = MINOR_TO_UNIT(mynor);
1469 com = com_addr(unit);
1470 if (com == NULL || com->gone)
1471 return (ENODEV);
1472 /*
1473 * (XXX) We disallow virtual consoles if the physical console is
1474 * a serial port. This is in case there is a display attached that
1475 * is not the console. In that situation we don't need/want the X
1476 * server taking over the console.
1477 */
1478 if (constty != NULL && unit == comconsole)
1479 constty = NULL;
1480 return ((*linesw[com->tp->t_line].l_write)(com->tp, uio, flag));
1481}
1482
1483static void
1484siobusycheck(chan)
1485 void *chan;
1486{
1487 struct com_s *com;
1488 int s;
1489
1490 com = (struct com_s *)chan;
1491
1492 /*
1493 * Clear TS_BUSY if low-level output is complete.
1494 * spl locking is sufficient because siointr1() does not set CS_BUSY.
1495 * If siointr1() clears CS_BUSY after we look at it, then we'll get
1496 * called again. Reading the line status port outside of siointr1()
1497 * is safe because CS_BUSY is clear so there are no output interrupts
1498 * to lose.
1499 */
1500 s = spltty();
1501 if (com->state & CS_BUSY)
1502 com->extra_state &= ~CSE_BUSYCHECK; /* False alarm. */
1503 else if ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY))
1504 == (LSR_TSRE | LSR_TXRDY)) {
1505 com->tp->t_state &= ~TS_BUSY;
1506 ttwwakeup(com->tp);
1507 com->extra_state &= ~CSE_BUSYCHECK;
1508 } else
1509 timeout(siobusycheck, com, hz / 100);
1510 splx(s);
1511}
1512
1513static u_int
1514siodivisor(rclk, speed)
1515 u_long rclk;
1516 speed_t speed;
1517{
1518 long actual_speed;
1519 u_int divisor;
1520 int error;
1521
1522 if (speed == 0 || speed > (ULONG_MAX - 1) / 8)
1523 return (0);
1524 divisor = (rclk / (8UL * speed) + 1) / 2;
1525 if (divisor == 0 || divisor >= 65536)
1526 return (0);
1527 actual_speed = rclk / (16UL * divisor);
1528
1529 /* 10 times error in percent: */
1530 error = ((actual_speed - (long)speed) * 2000 / (long)speed + 1) / 2;
1531
1532 /* 3.0% maximum error tolerance: */
1533 if (error < -30 || error > 30)
1534 return (0);
1535
1536 return (divisor);
1537}
1538
1539static void
1540siodtrwakeup(chan)
1541 void *chan;
1542{
1543 struct com_s *com;
1544
1545 com = (struct com_s *)chan;
1546 com->state &= ~CS_DTR_OFF;
1547 wakeup(&com->dtr_wait);
1548}
1549
1550/*
1551 * Call this function with the sio_lock mutex held. It will return with the
1552 * lock still held.
1553 */
1554static void
1555sioinput(com)
1556 struct com_s *com;
1557{
1558 u_char *buf;
1559 int incc;
1560 u_char line_status;
1561 int recv_data;
1562 struct tty *tp;
1563
1564 buf = com->ibuf;
1565 tp = com->tp;
1566 if (!(tp->t_state & TS_ISOPEN) || !(tp->t_cflag & CREAD)) {
1567 com_events -= (com->iptr - com->ibuf);
1568 com->iptr = com->ibuf;
1569 return;
1570 }
1571 if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
1572 /*
1573 * Avoid the grotesquely inefficient lineswitch routine
1574 * (ttyinput) in "raw" mode. It usually takes about 450
1575 * instructions (that's without canonical processing or echo!).
1576 * slinput is reasonably fast (usually 40 instructions plus
1577 * call overhead).
1578 */
1579 do {
1580 /*
1581 * This may look odd, but it is using save-and-enable
1582 * semantics instead of the save-and-disable semantics
1583 * that are used everywhere else.
1584 */
1585 mtx_unlock_spin(&sio_lock);
1586 incc = com->iptr - buf;
1587 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat
1588 && (com->state & CS_RTS_IFLOW
1589 || tp->t_iflag & IXOFF)
1590 && !(tp->t_state & TS_TBLOCK))
1591 ttyblock(tp);
1592 com->delta_error_counts[CE_TTY_BUF_OVERFLOW]
1593 += b_to_q((char *)buf, incc, &tp->t_rawq);
1594 buf += incc;
1595 tk_nin += incc;
1596 tk_rawcc += incc;
1597 tp->t_rawcc += incc;
1598 ttwakeup(tp);
1599 if (tp->t_state & TS_TTSTOP
1600 && (tp->t_iflag & IXANY
1601 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
1602 tp->t_state &= ~TS_TTSTOP;
1603 tp->t_lflag &= ~FLUSHO;
1604 comstart(tp);
1605 }
1606 mtx_lock_spin(&sio_lock);
1607 } while (buf < com->iptr);
1608 } else {
1609 do {
1610 /*
1611 * This may look odd, but it is using save-and-enable
1612 * semantics instead of the save-and-disable semantics
1613 * that are used everywhere else.
1614 */
1615 mtx_unlock_spin(&sio_lock);
1616 line_status = buf[com->ierroff];
1617 recv_data = *buf++;
1618 if (line_status
1619 & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) {
1620 if (line_status & LSR_BI)
1621 recv_data |= TTY_BI;
1622 if (line_status & LSR_FE)
1623 recv_data |= TTY_FE;
1624 if (line_status & LSR_OE)
1625 recv_data |= TTY_OE;
1626 if (line_status & LSR_PE)
1627 recv_data |= TTY_PE;
1628 }
1629 (*linesw[tp->t_line].l_rint)(recv_data, tp);
1630 mtx_lock_spin(&sio_lock);
1631 } while (buf < com->iptr);
1632 }
1633 com_events -= (com->iptr - com->ibuf);
1634 com->iptr = com->ibuf;
1635
1636 /*
1637 * There is now room for another low-level buffer full of input,
1638 * so enable RTS if it is now disabled and there is room in the
1639 * high-level buffer.
1640 */
1641 if ((com->state & CS_RTS_IFLOW) && !(com->mcr_image & MCR_RTS) &&
1642 !(tp->t_state & TS_TBLOCK))
1643 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
1644}
1645
1646static void
1647siointr(arg)
1648 void *arg;
1649{
1650 struct com_s *com;
1651
1652#ifndef COM_MULTIPORT
1653 com = (struct com_s *)arg;
1654
1655 mtx_lock_spin(&sio_lock);
1656 siointr1(com);
1657 mtx_unlock_spin(&sio_lock);
1658#else /* COM_MULTIPORT */
1659 bool_t possibly_more_intrs;
1660 int unit;
1661
1662 /*
1663 * Loop until there is no activity on any port. This is necessary
1664 * to get an interrupt edge more than to avoid another interrupt.
1665 * If the IRQ signal is just an OR of the IRQ signals from several
1666 * devices, then the edge from one may be lost because another is
1667 * on.
1668 */
1669 mtx_lock_spin(&sio_lock);
1670 do {
1671 possibly_more_intrs = FALSE;
1672 for (unit = 0; unit < sio_numunits; ++unit) {
1673 com = com_addr(unit);
1674 /*
1675 * XXX COM_LOCK();
1676 * would it work here, or be counter-productive?
1677 */
1678 if (com != NULL
1679 && !com->gone
1680 && (inb(com->int_id_port) & IIR_IMASK)
1681 != IIR_NOPEND) {
1682 siointr1(com);
1683 possibly_more_intrs = TRUE;
1684 }
1685 /* XXX COM_UNLOCK(); */
1686 }
1687 } while (possibly_more_intrs);
1688 mtx_unlock_spin(&sio_lock);
1689#endif /* COM_MULTIPORT */
1690}
1691
1692static struct timespec siots[8192];
1693static int siotso;
1694static int volatile siotsunit = -1;
1695
1696static int
1697sysctl_siots(SYSCTL_HANDLER_ARGS)
1698{
1699 char buf[128];
1700 long long delta;
1701 size_t len;
1702 int error, i;
1703
1704 for (i = 1; i < siotso; i++) {
1705 delta = (long long)(siots[i].tv_sec - siots[i - 1].tv_sec) *
1706 1000000000 +
1707 (siots[i].tv_nsec - siots[i - 1].tv_nsec);
1708 len = sprintf(buf, "%lld\n", delta);
1709 if (delta >= 110000)
1710 len += sprintf(buf + len - 1, ": *** %ld.%09ld\n",
1711 (long)siots[i].tv_sec, siots[i].tv_nsec);
1712 if (i == siotso - 1)
1713 buf[len - 1] = '\0';
1714 error = SYSCTL_OUT(req, buf, len);
1715 if (error != 0)
1716 return (error);
1717 uio_yield();
1718 }
1719 return (0);
1720}
1721
1722SYSCTL_PROC(_machdep, OID_AUTO, siots, CTLTYPE_STRING | CTLFLAG_RD,
1723 0, 0, sysctl_siots, "A", "sio timestamps");
1724
1725static void
1726siointr1(com)
1727 struct com_s *com;
1728{
1729 u_char line_status;
1730 u_char modem_status;
1731 u_char *ioptr;
1732 u_char recv_data;
1733 u_char int_ctl;
1734 u_char int_ctl_new;
1735
1736 int_ctl = inb(com->intr_ctl_port);
1737 int_ctl_new = int_ctl;
1738
1739 while (!com->gone) {
1740 if (com->pps.ppsparam.mode & PPS_CAPTUREBOTH) {
1741 modem_status = inb(com->modem_status_port);
1742 if ((modem_status ^ com->last_modem_status) &
1743 com->pps_bit) {
1744 pps_capture(&com->pps);
1745 pps_event(&com->pps,
1746 (modem_status & com->pps_bit) ?
1747 PPS_CAPTUREASSERT : PPS_CAPTURECLEAR);
1748 }
1749 }
1750 line_status = inb(com->line_status_port);
1751
1752 /* input event? (check first to help avoid overruns) */
1753 while (line_status & LSR_RCV_MASK) {
1754 /* break/unnattached error bits or real input? */
1755 if (!(line_status & LSR_RXRDY))
1756 recv_data = 0;
1757 else
1758 recv_data = inb(com->data_port);
1759#if defined(DDB) && defined(ALT_BREAK_TO_DEBUGGER)
1760 /*
1761 * Solaris implements a new BREAK which is initiated
1762 * by a character sequence CR ~ ^b which is similar
1763 * to a familiar pattern used on Sun servers by the
1764 * Remote Console.
1765 */
1766#define KEY_CRTLB 2 /* ^B */
1767#define KEY_CR 13 /* CR '\r' */
1768#define KEY_TILDE 126 /* ~ */
1769
1770 if (com->unit == comconsole) {
1771 static int brk_state1 = 0, brk_state2 = 0;
1772 if (recv_data == KEY_CR) {
1773 brk_state1 = recv_data;
1774 brk_state2 = 0;
1775 } else if (brk_state1 == KEY_CR
1776 && (recv_data == KEY_TILDE
1777 || recv_data == KEY_CRTLB)) {
1778 if (recv_data == KEY_TILDE)
1779 brk_state2 = recv_data;
1780 else if (brk_state2 == KEY_TILDE
1781 && recv_data == KEY_CRTLB) {
1782 breakpoint();
1783 brk_state1 = 0;
1784 brk_state2 = 0;
1785 goto cont;
1786 } else
1787 brk_state2 = 0;
1788 } else
1789 brk_state1 = 0;
1790 }
1791#endif
1792 if (line_status & (LSR_BI | LSR_FE | LSR_PE)) {
1793 /*
1794 * Don't store BI if IGNBRK or FE/PE if IGNPAR.
1795 * Otherwise, push the work to a higher level
1796 * (to handle PARMRK) if we're bypassing.
1797 * Otherwise, convert BI/FE and PE+INPCK to 0.
1798 *
1799 * This makes bypassing work right in the
1800 * usual "raw" case (IGNBRK set, and IGNPAR
1801 * and INPCK clear).
1802 *
1803 * Note: BI together with FE/PE means just BI.
1804 */
1805 if (line_status & LSR_BI) {
1806#if defined(DDB) && defined(BREAK_TO_DEBUGGER)
1807 if (com->unit == comconsole) {
1808 breakpoint();
1809 goto cont;
1810 }
1811#endif
1812 if (com->tp == NULL
1813 || com->tp->t_iflag & IGNBRK)
1814 goto cont;
1815 } else {
1816 if (com->tp == NULL
1817 || com->tp->t_iflag & IGNPAR)
1818 goto cont;
1819 }
1820 if (com->tp->t_state & TS_CAN_BYPASS_L_RINT
1821 && (line_status & (LSR_BI | LSR_FE)
1822 || com->tp->t_iflag & INPCK))
1823 recv_data = 0;
1824 }
1825 ++com->bytes_in;
1826 if (com->hotchar != 0 && recv_data == com->hotchar)
1827 swi_sched(sio_fast_ih, 0);
1828 ioptr = com->iptr;
1829 if (ioptr >= com->ibufend)
1830 CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
1831 else {
1832 if (com->do_timestamp)
1833 microtime(&com->timestamp);
1834 ++com_events;
1835 swi_sched(sio_slow_ih, SWI_DELAY);
1836#if 0 /* for testing input latency vs efficiency */
1837if (com->iptr - com->ibuf == 8)
1838 swi_sched(sio_fast_ih, 0);
1839#endif
1840 ioptr[0] = recv_data;
1841 ioptr[com->ierroff] = line_status;
1842 com->iptr = ++ioptr;
1843 if (ioptr == com->ihighwater
1844 && com->state & CS_RTS_IFLOW)
1845 outb(com->modem_ctl_port,
1846 com->mcr_image &= ~MCR_RTS);
1847 if (line_status & LSR_OE)
1848 CE_RECORD(com, CE_OVERRUN);
1849 }
1850cont:
1851 /*
1852 * "& 0x7F" is to avoid the gcc-1.40 generating a slow
1853 * jump from the top of the loop to here
1854 */
1855 line_status = inb(com->line_status_port) & 0x7F;
1856 }
1857
1858 /* modem status change? (always check before doing output) */
1859 modem_status = inb(com->modem_status_port);
1860 if (modem_status != com->last_modem_status) {
1861 if (com->do_dcd_timestamp
1862 && !(com->last_modem_status & MSR_DCD)
1863 && modem_status & MSR_DCD)
1864 microtime(&com->dcd_timestamp);
1865
1866 /*
1867 * Schedule high level to handle DCD changes. Note
1868 * that we don't use the delta bits anywhere. Some
1869 * UARTs mess them up, and it's easy to remember the
1870 * previous bits and calculate the delta.
1871 */
1872 com->last_modem_status = modem_status;
1873 if (!(com->state & CS_CHECKMSR)) {
1874 com_events += LOTS_OF_EVENTS;
1875 com->state |= CS_CHECKMSR;
1876 swi_sched(sio_fast_ih, 0);
1877 }
1878
1879 /* handle CTS change immediately for crisp flow ctl */
1880 if (com->state & CS_CTS_OFLOW) {
1881 if (modem_status & MSR_CTS)
1882 com->state |= CS_ODEVREADY;
1883 else
1884 com->state &= ~CS_ODEVREADY;
1885 }
1886 }
1887
1888 /* output queued and everything ready? */
1889 if (line_status & LSR_TXRDY
1890 && com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
1891 ioptr = com->obufq.l_head;
1892 if (com->tx_fifo_size > 1 && com->unit != siotsunit) {
1893 u_int ocount;
1894
1895 ocount = com->obufq.l_tail - ioptr;
1896 if (ocount > com->tx_fifo_size)
1897 ocount = com->tx_fifo_size;
1898 com->bytes_out += ocount;
1899 do
1900 outb(com->data_port, *ioptr++);
1901 while (--ocount != 0);
1902 } else {
1903 outb(com->data_port, *ioptr++);
1904 ++com->bytes_out;
1905 if (com->unit == siotsunit) {
1906 nanouptime(&siots[siotso]);
1907 siotso = (siotso + 1) %
1908 (sizeof siots / sizeof siots[0]);
1909 }
1910 }
1911 com->obufq.l_head = ioptr;
1912 if (COM_IIR_TXRDYBUG(com->flags)) {
1913 int_ctl_new = int_ctl | IER_ETXRDY;
1914 }
1915 if (ioptr >= com->obufq.l_tail) {
1916 struct lbq *qp;
1917
1918 qp = com->obufq.l_next;
1919 qp->l_queued = FALSE;
1920 qp = qp->l_next;
1921 if (qp != NULL) {
1922 com->obufq.l_head = qp->l_head;
1923 com->obufq.l_tail = qp->l_tail;
1924 com->obufq.l_next = qp;
1925 } else {
1926 /* output just completed */
1927 if (COM_IIR_TXRDYBUG(com->flags)) {
1928 int_ctl_new = int_ctl & ~IER_ETXRDY;
1929 }
1930 com->state &= ~CS_BUSY;
1931 }
1932 if (!(com->state & CS_ODONE)) {
1933 com_events += LOTS_OF_EVENTS;
1934 com->state |= CS_ODONE;
1935 /* handle at high level ASAP */
1936 swi_sched(sio_fast_ih, 0);
1937 }
1938 }
1939 if (COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) {
1940 outb(com->intr_ctl_port, int_ctl_new);
1941 }
1942 }
1943
1944 /* finished? */
1945#ifndef COM_MULTIPORT
1946 if ((inb(com->int_id_port) & IIR_IMASK) == IIR_NOPEND)
1947#endif /* COM_MULTIPORT */
1948 return;
1949 }
1950}
1951
1952static int
1953sioioctl(dev, cmd, data, flag, td)
1954 dev_t dev;
1955 u_long cmd;
1956 caddr_t data;
1957 int flag;
1958 struct thread *td;
1959{
1960 struct com_s *com;
1961 int error;
1962 int mynor;
1963 int s;
1964 struct tty *tp;
1965#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1966 u_long oldcmd;
1967 struct termios term;
1968#endif
1969
1970 mynor = minor(dev);
1971 com = com_addr(MINOR_TO_UNIT(mynor));
1972 if (com == NULL || com->gone)
1973 return (ENODEV);
1974 if (mynor & CONTROL_MASK) {
1975 struct termios *ct;
1976
1977 switch (mynor & CONTROL_MASK) {
1978 case CONTROL_INIT_STATE:
1979 ct = mynor & CALLOUT_MASK ? &com->it_out : &com->it_in;
1980 break;
1981 case CONTROL_LOCK_STATE:
1982 ct = mynor & CALLOUT_MASK ? &com->lt_out : &com->lt_in;
1983 break;
1984 default:
1985 return (ENODEV); /* /dev/nodev */
1986 }
1987 switch (cmd) {
1988 case TIOCSETA:
1989 error = suser(td);
1990 if (error != 0)
1991 return (error);
1992 *ct = *(struct termios *)data;
1993 return (0);
1994 case TIOCGETA:
1995 *(struct termios *)data = *ct;
1996 return (0);
1997 case TIOCGETD:
1998 *(int *)data = TTYDISC;
1999 return (0);
2000 case TIOCGWINSZ:
2001 bzero(data, sizeof(struct winsize));
2002 return (0);
2003 default:
2004 return (ENOTTY);
2005 }
2006 }
2007 tp = com->tp;
2008#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
2009 term = tp->t_termios;
2010 oldcmd = cmd;
2011 error = ttsetcompat(tp, &cmd, data, &term);
2012 if (error != 0)
2013 return (error);
2014 if (cmd != oldcmd)
2015 data = (caddr_t)&term;
2016#endif
2017 if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) {
2018 int cc;
2019 struct termios *dt = (struct termios *)data;
2020 struct termios *lt = mynor & CALLOUT_MASK
2021 ? &com->lt_out : &com->lt_in;
2022
2023 dt->c_iflag = (tp->t_iflag & lt->c_iflag)
2024 | (dt->c_iflag & ~lt->c_iflag);
2025 dt->c_oflag = (tp->t_oflag & lt->c_oflag)
2026 | (dt->c_oflag & ~lt->c_oflag);
2027 dt->c_cflag = (tp->t_cflag & lt->c_cflag)
2028 | (dt->c_cflag & ~lt->c_cflag);
2029 dt->c_lflag = (tp->t_lflag & lt->c_lflag)
2030 | (dt->c_lflag & ~lt->c_lflag);
2031 for (cc = 0; cc < NCCS; ++cc)
2032 if (lt->c_cc[cc] != 0)
2033 dt->c_cc[cc] = tp->t_cc[cc];
2034 if (lt->c_ispeed != 0)
2035 dt->c_ispeed = tp->t_ispeed;
2036 if (lt->c_ospeed != 0)
2037 dt->c_ospeed = tp->t_ospeed;
2038 }
2039 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, td);
2040 if (error != ENOIOCTL)
2041 return (error);
2042 s = spltty();
2043 error = ttioctl(tp, cmd, data, flag);
2044 disc_optim(tp, &tp->t_termios, com);
2045 if (error != ENOIOCTL) {
2046 splx(s);
2047 return (error);
2048 }
2049 switch (cmd) {
2050 case TIOCSBRK:
2051 sio_setreg(com, com_cfcr, com->cfcr_image |= CFCR_SBREAK);
2052 break;
2053 case TIOCCBRK:
2054 sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
2055 break;
2056 case TIOCSDTR:
2057 (void)commctl(com, TIOCM_DTR, DMBIS);
2058 break;
2059 case TIOCCDTR:
2060 (void)commctl(com, TIOCM_DTR, DMBIC);
2061 break;
2062 /*
2063 * XXX should disallow changing MCR_RTS if CS_RTS_IFLOW is set. The
2064 * changes get undone on the next call to comparam().
2065 */
2066 case TIOCMSET:
2067 (void)commctl(com, *(int *)data, DMSET);
2068 break;
2069 case TIOCMBIS:
2070 (void)commctl(com, *(int *)data, DMBIS);
2071 break;
2072 case TIOCMBIC:
2073 (void)commctl(com, *(int *)data, DMBIC);
2074 break;
2075 case TIOCMGET:
2076 *(int *)data = commctl(com, 0, DMGET);
2077 break;
2078 case TIOCMSDTRWAIT:
2079 /* must be root since the wait applies to following logins */
2080 error = suser(td);
2081 if (error != 0) {
2082 splx(s);
2083 return (error);
2084 }
2085 com->dtr_wait = *(int *)data * hz / 100;
2086 break;
2087 case TIOCMGDTRWAIT:
2088 *(int *)data = com->dtr_wait * 100 / hz;
2089 break;
2090 case TIOCTIMESTAMP:
2091 com->do_timestamp = TRUE;
2092 *(struct timeval *)data = com->timestamp;
2093 break;
2094 case TIOCDCDTIMESTAMP:
2095 com->do_dcd_timestamp = TRUE;
2096 *(struct timeval *)data = com->dcd_timestamp;
2097 break;
2098 default:
2099 splx(s);
2100 error = pps_ioctl(cmd, data, &com->pps);
2101 if (error == ENODEV)
2102 error = ENOTTY;
2103 return (error);
2104 }
2105 splx(s);
2106 return (0);
2107}
2108
2109/* software interrupt handler for SWI_TTY */
2110static void
2111siopoll(void *dummy)
2112{
2113 int unit;
2114
2115 if (com_events == 0)
2116 return;
2117repeat:
2118 for (unit = 0; unit < sio_numunits; ++unit) {
2119 struct com_s *com;
2120 int incc;
2121 struct tty *tp;
2122
2123 com = com_addr(unit);
2124 if (com == NULL)
2125 continue;
2126 tp = com->tp;
2127 if (tp == NULL || com->gone) {
2128 /*
2129 * Discard any events related to never-opened or
2130 * going-away devices.
2131 */
2132 mtx_lock_spin(&sio_lock);
2133 incc = com->iptr - com->ibuf;
2134 com->iptr = com->ibuf;
2135 if (com->state & CS_CHECKMSR) {
2136 incc += LOTS_OF_EVENTS;
2137 com->state &= ~CS_CHECKMSR;
2138 }
2139 com_events -= incc;
2140 mtx_unlock_spin(&sio_lock);
2141 continue;
2142 }
2143 if (com->iptr != com->ibuf) {
2144 mtx_lock_spin(&sio_lock);
2145 sioinput(com);
2146 mtx_unlock_spin(&sio_lock);
2147 }
2148 if (com->state & CS_CHECKMSR) {
2149 u_char delta_modem_status;
2150
2151 mtx_lock_spin(&sio_lock);
2152 delta_modem_status = com->last_modem_status
2153 ^ com->prev_modem_status;
2154 com->prev_modem_status = com->last_modem_status;
2155 com_events -= LOTS_OF_EVENTS;
2156 com->state &= ~CS_CHECKMSR;
2157 mtx_unlock_spin(&sio_lock);
2158 if (delta_modem_status & MSR_DCD)
2159 (*linesw[tp->t_line].l_modem)
2160 (tp, com->prev_modem_status & MSR_DCD);
2161 }
2162 if (com->state & CS_ODONE) {
2163 mtx_lock_spin(&sio_lock);
2164 com_events -= LOTS_OF_EVENTS;
2165 com->state &= ~CS_ODONE;
2166 mtx_unlock_spin(&sio_lock);
2167 if (!(com->state & CS_BUSY)
2168 && !(com->extra_state & CSE_BUSYCHECK)) {
2169 timeout(siobusycheck, com, hz / 100);
2170 com->extra_state |= CSE_BUSYCHECK;
2171 }
2172 (*linesw[tp->t_line].l_start)(tp);
2173 }
2174 if (com_events == 0)
2175 break;
2176 }
2177 if (com_events >= LOTS_OF_EVENTS)
2178 goto repeat;
2179}
2180
2181static int
2182comparam(tp, t)
2183 struct tty *tp;
2184 struct termios *t;
2185{
2186 u_int cfcr;
2187 int cflag;
2188 struct com_s *com;
2189 u_int divisor;
2190 u_char dlbh;
2191 u_char dlbl;
2192 int s;
2193 int unit;
2194
2195 unit = DEV_TO_UNIT(tp->t_dev);
2196 com = com_addr(unit);
2197 if (com == NULL)
2198 return (ENODEV);
2199
2200 /* do historical conversions */
2201 if (t->c_ispeed == 0)
2202 t->c_ispeed = t->c_ospeed;
2203
2204 /* check requested parameters */
2205 if (t->c_ospeed == 0)
2206 divisor = 0;
2207 else {
2208 if (t->c_ispeed != t->c_ospeed)
2209 return (EINVAL);
2210 divisor = siodivisor(com->rclk, t->c_ispeed);
2211 if (divisor == 0)
2212 return (EINVAL);
2213 }
2214
2215 /* parameters are OK, convert them to the com struct and the device */
2216 s = spltty();
2217 if (divisor == 0)
2218 (void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */
2219 else
2220 (void)commctl(com, TIOCM_DTR, DMBIS);
2221 cflag = t->c_cflag;
2222 switch (cflag & CSIZE) {
2223 case CS5:
2224 cfcr = CFCR_5BITS;
2225 break;
2226 case CS6:
2227 cfcr = CFCR_6BITS;
2228 break;
2229 case CS7:
2230 cfcr = CFCR_7BITS;
2231 break;
2232 default:
2233 cfcr = CFCR_8BITS;
2234 break;
2235 }
2236 if (cflag & PARENB) {
2237 cfcr |= CFCR_PENAB;
2238 if (!(cflag & PARODD))
2239 cfcr |= CFCR_PEVEN;
2240 }
2241 if (cflag & CSTOPB)
2242 cfcr |= CFCR_STOPB;
2243
2244 if (com->hasfifo && divisor != 0) {
2245 /*
2246 * Use a fifo trigger level low enough so that the input
2247 * latency from the fifo is less than about 16 msec and
2248 * the total latency is less than about 30 msec. These
2249 * latencies are reasonable for humans. Serial comms
2250 * protocols shouldn't expect anything better since modem
2251 * latencies are larger.
2252 *
2253 * The fifo trigger level cannot be set at RX_HIGH for high
2254 * speed connections without further work on reducing
2255 * interrupt disablement times in other parts of the system,
2256 * without producing silo overflow errors.
2257 */
2258 com->fifo_image = com->unit == siotsunit ? 0
2259 : t->c_ospeed <= 4800
2260 ? FIFO_ENABLE : FIFO_ENABLE | FIFO_RX_MEDH;
2261#ifdef COM_ESP
2262 /*
2263 * The Hayes ESP card needs the fifo DMA mode bit set
2264 * in compatibility mode. If not, it will interrupt
2265 * for each character received.
2266 */
2267 if (com->esp)
2268 com->fifo_image |= FIFO_DMA_MODE;
2269#endif
2270 sio_setreg(com, com_fifo, com->fifo_image);
2271 }
2272
2273 /*
2274 * This returns with interrupts disabled so that we can complete
2275 * the speed change atomically. Keeping interrupts disabled is
2276 * especially important while com_data is hidden.
2277 */
2278 (void) siosetwater(com, t->c_ispeed);
2279
2280 if (divisor != 0) {
2281 sio_setreg(com, com_cfcr, cfcr | CFCR_DLAB);
2282 /*
2283 * Only set the divisor registers if they would change,
2284 * since on some 16550 incompatibles (UMC8669F), setting
2285 * them while input is arriving them loses sync until
2286 * data stops arriving.
2287 */
2288 dlbl = divisor & 0xFF;
2289 if (sio_getreg(com, com_dlbl) != dlbl)
2290 sio_setreg(com, com_dlbl, dlbl);
2291 dlbh = divisor >> 8;
2292 if (sio_getreg(com, com_dlbh) != dlbh)
2293 sio_setreg(com, com_dlbh, dlbh);
2294 }
2295
2296 sio_setreg(com, com_cfcr, com->cfcr_image = cfcr);
2297
2298 if (!(tp->t_state & TS_TTSTOP))
2299 com->state |= CS_TTGO;
2300
2301 if (cflag & CRTS_IFLOW) {
2302 if (com->st16650a) {
2303 sio_setreg(com, com_cfcr, 0xbf);
2304 sio_setreg(com, com_fifo,
2305 sio_getreg(com, com_fifo) | 0x40);
2306 }
2307 com->state |= CS_RTS_IFLOW;
2308 /*
2309 * If CS_RTS_IFLOW just changed from off to on, the change
2310 * needs to be propagated to MCR_RTS. This isn't urgent,
2311 * so do it later by calling comstart() instead of repeating
2312 * a lot of code from comstart() here.
2313 */
2314 } else if (com->state & CS_RTS_IFLOW) {
2315 com->state &= ~CS_RTS_IFLOW;
2316 /*
2317 * CS_RTS_IFLOW just changed from on to off. Force MCR_RTS
2318 * on here, since comstart() won't do it later.
2319 */
2320 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
2321 if (com->st16650a) {
2322 sio_setreg(com, com_cfcr, 0xbf);
2323 sio_setreg(com, com_fifo,
2324 sio_getreg(com, com_fifo) & ~0x40);
2325 }
2326 }
2327
2328
2329 /*
2330 * Set up state to handle output flow control.
2331 * XXX - worth handling MDMBUF (DCD) flow control at the lowest level?
2332 * Now has 10+ msec latency, while CTS flow has 50- usec latency.
2333 */
2334 com->state |= CS_ODEVREADY;
2335 com->state &= ~CS_CTS_OFLOW;
2336 if (cflag & CCTS_OFLOW) {
2337 com->state |= CS_CTS_OFLOW;
2338 if (!(com->last_modem_status & MSR_CTS))
2339 com->state &= ~CS_ODEVREADY;
2340 if (com->st16650a) {
2341 sio_setreg(com, com_cfcr, 0xbf);
2342 sio_setreg(com, com_fifo,
2343 sio_getreg(com, com_fifo) | 0x80);
2344 }
2345 } else {
2346 if (com->st16650a) {
2347 sio_setreg(com, com_cfcr, 0xbf);
2348 sio_setreg(com, com_fifo,
2349 sio_getreg(com, com_fifo) & ~0x80);
2350 }
2351 }
2352
2353 sio_setreg(com, com_cfcr, com->cfcr_image);
2354
2355 /* XXX shouldn't call functions while intrs are disabled. */
2356 disc_optim(tp, t, com);
2357 /*
2358 * Recover from fiddling with CS_TTGO. We used to call siointr1()
2359 * unconditionally, but that defeated the careful discarding of
2360 * stale input in sioopen().
2361 */
2362 if (com->state >= (CS_BUSY | CS_TTGO))
2363 siointr1(com);
2364
2365 mtx_unlock_spin(&sio_lock);
2366 splx(s);
2367 comstart(tp);
2368 if (com->ibufold != NULL) {
2369 free(com->ibufold, M_DEVBUF);
2370 com->ibufold = NULL;
2371 }
2372 return (0);
2373}
2374
2375/*
2376 * This function must be called with the sio_lock mutex released and will
2377 * return with it obtained.
2378 */
2379static int
2380siosetwater(com, speed)
2381 struct com_s *com;
2382 speed_t speed;
2383{
2384 int cp4ticks;
2385 u_char *ibuf;
2386 int ibufsize;
2387 struct tty *tp;
2388
2389 /*
2390 * Make the buffer size large enough to handle a softtty interrupt
2391 * latency of about 2 ticks without loss of throughput or data
2392 * (about 3 ticks if input flow control is not used or not honoured,
2393 * but a bit less for CS5-CS7 modes).
2394 */
2395 cp4ticks = speed / 10 / hz * 4;
2396 for (ibufsize = 128; ibufsize < cp4ticks;)
2397 ibufsize <<= 1;
2398 if (ibufsize == com->ibufsize) {
2399 mtx_lock_spin(&sio_lock);
2400 return (0);
2401 }
2402
2403 /*
2404 * Allocate input buffer. The extra factor of 2 in the size is
2405 * to allow for an error byte for each input byte.
2406 */
2407 ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT);
2408 if (ibuf == NULL) {
2409 mtx_lock_spin(&sio_lock);
2410 return (ENOMEM);
2411 }
2412
2413 /* Initialize non-critical variables. */
2414 com->ibufold = com->ibuf;
2415 com->ibufsize = ibufsize;
2416 tp = com->tp;
2417 if (tp != NULL) {
2418 tp->t_ififosize = 2 * ibufsize;
2419 tp->t_ispeedwat = (speed_t)-1;
2420 tp->t_ospeedwat = (speed_t)-1;
2421 }
2422
2423 /*
2424 * Read current input buffer, if any. Continue with interrupts
2425 * disabled.
2426 */
2427 mtx_lock_spin(&sio_lock);
2428 if (com->iptr != com->ibuf)
2429 sioinput(com);
2430
2431 /*-
2432 * Initialize critical variables, including input buffer watermarks.
2433 * The external device is asked to stop sending when the buffer
2434 * exactly reaches high water, or when the high level requests it.
2435 * The high level is notified immediately (rather than at a later
2436 * clock tick) when this watermark is reached.
2437 * The buffer size is chosen so the watermark should almost never
2438 * be reached.
2439 * The low watermark is invisibly 0 since the buffer is always
2440 * emptied all at once.
2441 */
2442 com->iptr = com->ibuf = ibuf;
2443 com->ibufend = ibuf + ibufsize;
2444 com->ierroff = ibufsize;
2445 com->ihighwater = ibuf + 3 * ibufsize / 4;
2446 return (0);
2447}
2448
2449static void
2450comstart(tp)
2451 struct tty *tp;
2452{
2453 struct com_s *com;
2454 int s;
2455 int unit;
2456
2457 unit = DEV_TO_UNIT(tp->t_dev);
2458 com = com_addr(unit);
2459 if (com == NULL)
2460 return;
2461 s = spltty();
2462 mtx_lock_spin(&sio_lock);
2463 if (tp->t_state & TS_TTSTOP)
2464 com->state &= ~CS_TTGO;
2465 else
2466 com->state |= CS_TTGO;
2467 if (tp->t_state & TS_TBLOCK) {
2468 if (com->mcr_image & MCR_RTS && com->state & CS_RTS_IFLOW)
2469 outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS);
2470 } else {
2471 if (!(com->mcr_image & MCR_RTS) && com->iptr < com->ihighwater
2472 && com->state & CS_RTS_IFLOW)
2473 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
2474 }
2475 mtx_unlock_spin(&sio_lock);
2476 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
2477 ttwwakeup(tp);
2478 splx(s);
2479 return;
2480 }
2481 if (tp->t_outq.c_cc != 0) {
2482 struct lbq *qp;
2483 struct lbq *next;
2484
2485 if (!com->obufs[0].l_queued) {
2486 com->obufs[0].l_tail
2487 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1,
2488 sizeof com->obuf1);
2489 com->obufs[0].l_next = NULL;
2490 com->obufs[0].l_queued = TRUE;
2491 mtx_lock_spin(&sio_lock);
2492 if (com->state & CS_BUSY) {
2493 qp = com->obufq.l_next;
2494 while ((next = qp->l_next) != NULL)
2495 qp = next;
2496 qp->l_next = &com->obufs[0];
2497 } else {
2498 com->obufq.l_head = com->obufs[0].l_head;
2499 com->obufq.l_tail = com->obufs[0].l_tail;
2500 com->obufq.l_next = &com->obufs[0];
2501 com->state |= CS_BUSY;
2502 }
2503 mtx_unlock_spin(&sio_lock);
2504 }
2505 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) {
2506 com->obufs[1].l_tail
2507 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2,
2508 sizeof com->obuf2);
2509 com->obufs[1].l_next = NULL;
2510 com->obufs[1].l_queued = TRUE;
2511 mtx_lock_spin(&sio_lock);
2512 if (com->state & CS_BUSY) {
2513 qp = com->obufq.l_next;
2514 while ((next = qp->l_next) != NULL)
2515 qp = next;
2516 qp->l_next = &com->obufs[1];
2517 } else {
2518 com->obufq.l_head = com->obufs[1].l_head;
2519 com->obufq.l_tail = com->obufs[1].l_tail;
2520 com->obufq.l_next = &com->obufs[1];
2521 com->state |= CS_BUSY;
2522 }
2523 mtx_unlock_spin(&sio_lock);
2524 }
2525 tp->t_state |= TS_BUSY;
2526 }
2527 mtx_lock_spin(&sio_lock);
2528 if (com->state >= (CS_BUSY | CS_TTGO))
2529 siointr1(com); /* fake interrupt to start output */
2530 mtx_unlock_spin(&sio_lock);
2531 ttwwakeup(tp);
2532 splx(s);
2533}
2534
2535static void
2536comstop(tp, rw)
2537 struct tty *tp;
2538 int rw;
2539{
2540 struct com_s *com;
2541
2542 com = com_addr(DEV_TO_UNIT(tp->t_dev));
2543 if (com == NULL || com->gone)
2544 return;
2545 mtx_lock_spin(&sio_lock);
2546 if (rw & FWRITE) {
2547 if (com->hasfifo)
2548#ifdef COM_ESP
2549 /* XXX avoid h/w bug. */
2550 if (!com->esp)
2551#endif
2552 sio_setreg(com, com_fifo,
2553 FIFO_XMT_RST | com->fifo_image);
2554 com->obufs[0].l_queued = FALSE;
2555 com->obufs[1].l_queued = FALSE;
2556 if (com->state & CS_ODONE)
2557 com_events -= LOTS_OF_EVENTS;
2558 com->state &= ~(CS_ODONE | CS_BUSY);
2559 com->tp->t_state &= ~TS_BUSY;
2560 }
2561 if (rw & FREAD) {
2562 if (com->hasfifo)
2563#ifdef COM_ESP
2564 /* XXX avoid h/w bug. */
2565 if (!com->esp)
2566#endif
2567 sio_setreg(com, com_fifo,
2568 FIFO_RCV_RST | com->fifo_image);
2569 com_events -= (com->iptr - com->ibuf);
2570 com->iptr = com->ibuf;
2571 }
2572 mtx_unlock_spin(&sio_lock);
2573 comstart(tp);
2574}
2575
2576static int
2577commctl(com, bits, how)
2578 struct com_s *com;
2579 int bits;
2580 int how;
2581{
2582 int mcr;
2583 int msr;
2584
2585 if (how == DMGET) {
2586 bits = TIOCM_LE; /* XXX - always enabled while open */
2587 mcr = com->mcr_image;
2588 if (mcr & MCR_DTR)
2589 bits |= TIOCM_DTR;
2590 if (mcr & MCR_RTS)
2591 bits |= TIOCM_RTS;
2592 msr = com->prev_modem_status;
2593 if (msr & MSR_CTS)
2594 bits |= TIOCM_CTS;
2595 if (msr & MSR_DCD)
2596 bits |= TIOCM_CD;
2597 if (msr & MSR_DSR)
2598 bits |= TIOCM_DSR;
2599 /*
2600 * XXX - MSR_RI is naturally volatile, and we make MSR_TERI
2601 * more volatile by reading the modem status a lot. Perhaps
2602 * we should latch both bits until the status is read here.
2603 */
2604 if (msr & (MSR_RI | MSR_TERI))
2605 bits |= TIOCM_RI;
2606 return (bits);
2607 }
2608 mcr = 0;
2609 if (bits & TIOCM_DTR)
2610 mcr |= MCR_DTR;
2611 if (bits & TIOCM_RTS)
2612 mcr |= MCR_RTS;
2613 if (com->gone)
2614 return(0);
2615 mtx_lock_spin(&sio_lock);
2616 switch (how) {
2617 case DMSET:
2618 outb(com->modem_ctl_port,
2619 com->mcr_image = mcr | (com->mcr_image & MCR_IENABLE));
2620 break;
2621 case DMBIS:
2622 outb(com->modem_ctl_port, com->mcr_image |= mcr);
2623 break;
2624 case DMBIC:
2625 outb(com->modem_ctl_port, com->mcr_image &= ~mcr);
2626 break;
2627 }
2628 mtx_unlock_spin(&sio_lock);
2629 return (0);
2630}
2631
2632static void
2633siosettimeout()
2634{
2635 struct com_s *com;
2636 bool_t someopen;
2637 int unit;
2638
2639 /*
2640 * Set our timeout period to 1 second if no polled devices are open.
2641 * Otherwise set it to max(1/200, 1/hz).
2642 * Enable timeouts iff some device is open.
2643 */
2644 untimeout(comwakeup, (void *)NULL, sio_timeout_handle);
2645 sio_timeout = hz;
2646 someopen = FALSE;
2647 for (unit = 0; unit < sio_numunits; ++unit) {
2648 com = com_addr(unit);
2649 if (com != NULL && com->tp != NULL
2650 && com->tp->t_state & TS_ISOPEN && !com->gone) {
2651 someopen = TRUE;
2652 if (com->poll || com->poll_output) {
2653 sio_timeout = hz > 200 ? hz / 200 : 1;
2654 break;
2655 }
2656 }
2657 }
2658 if (someopen) {
2659 sio_timeouts_until_log = hz / sio_timeout;
2660 sio_timeout_handle = timeout(comwakeup, (void *)NULL,
2661 sio_timeout);
2662 } else {
2663 /* Flush error messages, if any. */
2664 sio_timeouts_until_log = 1;
2665 comwakeup((void *)NULL);
2666 untimeout(comwakeup, (void *)NULL, sio_timeout_handle);
2667 }
2668}
2669
2670static void
2671comwakeup(chan)
2672 void *chan;
2673{
2674 struct com_s *com;
2675 int unit;
2676
2677 sio_timeout_handle = timeout(comwakeup, (void *)NULL, sio_timeout);
2678
2679 /*
2680 * Recover from lost output interrupts.
2681 * Poll any lines that don't use interrupts.
2682 */
2683 for (unit = 0; unit < sio_numunits; ++unit) {
2684 com = com_addr(unit);
2685 if (com != NULL && !com->gone
2686 && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) {
2687 mtx_lock_spin(&sio_lock);
2688 siointr1(com);
2689 mtx_unlock_spin(&sio_lock);
2690 }
2691 }
2692
2693 /*
2694 * Check for and log errors, but not too often.
2695 */
2696 if (--sio_timeouts_until_log > 0)
2697 return;
2698 sio_timeouts_until_log = hz / sio_timeout;
2699 for (unit = 0; unit < sio_numunits; ++unit) {
2700 int errnum;
2701
2702 com = com_addr(unit);
2703 if (com == NULL)
2704 continue;
2705 if (com->gone)
2706 continue;
2707 for (errnum = 0; errnum < CE_NTYPES; ++errnum) {
2708 u_int delta;
2709 u_long total;
2710
2711 mtx_lock_spin(&sio_lock);
2712 delta = com->delta_error_counts[errnum];
2713 com->delta_error_counts[errnum] = 0;
2714 mtx_unlock_spin(&sio_lock);
2715 if (delta == 0)
2716 continue;
2717 total = com->error_counts[errnum] += delta;
2718 log(LOG_ERR, "sio%d: %u more %s%s (total %lu)\n",
2719 unit, delta, error_desc[errnum],
2720 delta == 1 ? "" : "s", total);
2721 }
2722 }
2723}
2724
2725static void
2726disc_optim(tp, t, com)
2727 struct tty *tp;
2728 struct termios *t;
2729 struct com_s *com;
2730{
2731 if (!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON))
2732 && (!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK))
2733 && (!(t->c_iflag & PARMRK)
2734 || (t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))
2735 && !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN))
2736 && linesw[tp->t_line].l_rint == ttyinput)
2737 tp->t_state |= TS_CAN_BYPASS_L_RINT;
2738 else
2739 tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
2740 com->hotchar = linesw[tp->t_line].l_hotchar;
2741}
2742
2743/*
2744 * Following are all routines needed for SIO to act as console
2745 */
2746#include <sys/cons.h>
2747
2748struct siocnstate {
2749 u_char dlbl;
2750 u_char dlbh;
2751 u_char ier;
2752 u_char cfcr;
2753 u_char mcr;
2754};
2755
2756#ifndef __alpha__
2757static speed_t siocngetspeed(Port_t, u_long rclk);
2758#endif
2759static void siocnclose(struct siocnstate *sp, Port_t iobase);
2760static void siocnopen(struct siocnstate *sp, Port_t iobase, int speed);
2761static void siocntxwait(Port_t iobase);
2762
2763#ifdef __alpha__
2764int siocnattach(int port, int speed);
2765int siogdbattach(int port, int speed);
2766int siogdbgetc(void);
2767void siogdbputc(int c);
2768#else
2769static cn_probe_t siocnprobe;
2770static cn_init_t siocninit;
2771static cn_term_t siocnterm;
2772#endif
2773static cn_checkc_t siocncheckc;
2774static cn_getc_t siocngetc;
2775static cn_putc_t siocnputc;
2776
2777#ifndef __alpha__
2778CONS_DRIVER(sio, siocnprobe, siocninit, siocnterm, siocngetc, siocncheckc,
2779 siocnputc, NULL);
2780#endif
2781
2782/* To get the GDB related variables */
2783#if DDB > 0
2784#include <ddb/ddb.h>
2785static struct consdev gdbconsdev;
2786
2787#endif
2788
2789static void
2790siocntxwait(iobase)
2791 Port_t iobase;
2792{
2793 int timo;
2794
2795 /*
2796 * Wait for any pending transmission to finish. Required to avoid
2797 * the UART lockup bug when the speed is changed, and for normal
2798 * transmits.
2799 */
2800 timo = 100000;
2801 while ((inb(iobase + com_lsr) & (LSR_TSRE | LSR_TXRDY))
2802 != (LSR_TSRE | LSR_TXRDY) && --timo != 0)
2803 ;
2804}
2805
2806#ifndef __alpha__
2807
2808/*
2809 * Read the serial port specified and try to figure out what speed
2810 * it's currently running at. We're assuming the serial port has
2811 * been initialized and is basicly idle. This routine is only intended
2812 * to be run at system startup.
2813 *
2814 * If the value read from the serial port doesn't make sense, return 0.
2815 */
2816
2817static speed_t
2818siocngetspeed(iobase, rclk)
2819 Port_t iobase;
2820 u_long rclk;
2821{
2822 u_int divisor;
2823 u_char dlbh;
2824 u_char dlbl;
2825 u_char cfcr;
2826
2827 cfcr = inb(iobase + com_cfcr);
2828 outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
2829
2830 dlbl = inb(iobase + com_dlbl);
2831 dlbh = inb(iobase + com_dlbh);
2832
2833 outb(iobase + com_cfcr, cfcr);
2834
2835 divisor = dlbh << 8 | dlbl;
2836
2837 /* XXX there should be more sanity checking. */
2838 if (divisor == 0)
2839 return (CONSPEED);
2840 return (rclk / (16UL * divisor));
2841}
2842
2843#endif
2844
2845static void
2846siocnopen(sp, iobase, speed)
2847 struct siocnstate *sp;
2848 Port_t iobase;
2849 int speed;
2850{
2851 u_int divisor;
2852 u_char dlbh;
2853 u_char dlbl;
2854
2855 /*
2856 * Save all the device control registers except the fifo register
2857 * and set our default ones (cs8 -parenb speed=comdefaultrate).
2858 * We can't save the fifo register since it is read-only.
2859 */
2860 sp->ier = inb(iobase + com_ier);
2861 outb(iobase + com_ier, 0); /* spltty() doesn't stop siointr() */
2862 siocntxwait(iobase);
2863 sp->cfcr = inb(iobase + com_cfcr);
2864 outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
2865 sp->dlbl = inb(iobase + com_dlbl);
2866 sp->dlbh = inb(iobase + com_dlbh);
2867 /*
2868 * Only set the divisor registers if they would change, since on
2869 * some 16550 incompatibles (Startech), setting them clears the
2870 * data input register. This also reduces the effects of the
2871 * UMC8669F bug.
2872 */
2873 divisor = siodivisor(comdefaultrclk, speed);
2874 dlbl = divisor & 0xFF;
2875 if (sp->dlbl != dlbl)
2876 outb(iobase + com_dlbl, dlbl);
2877 dlbh = divisor >> 8;
2878 if (sp->dlbh != dlbh)
2879 outb(iobase + com_dlbh, dlbh);
2880 outb(iobase + com_cfcr, CFCR_8BITS);
2881 sp->mcr = inb(iobase + com_mcr);
2882 /*
2883 * We don't want interrupts, but must be careful not to "disable"
2884 * them by clearing the MCR_IENABLE bit, since that might cause
2885 * an interrupt by floating the IRQ line.
2886 */
2887 outb(iobase + com_mcr, (sp->mcr & MCR_IENABLE) | MCR_DTR | MCR_RTS);
2888}
2889
2890static void
2891siocnclose(sp, iobase)
2892 struct siocnstate *sp;
2893 Port_t iobase;
2894{
2895 /*
2896 * Restore the device control registers.
2897 */
2898 siocntxwait(iobase);
2899 outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
2900 if (sp->dlbl != inb(iobase + com_dlbl))
2901 outb(iobase + com_dlbl, sp->dlbl);
2902 if (sp->dlbh != inb(iobase + com_dlbh))
2903 outb(iobase + com_dlbh, sp->dlbh);
2904 outb(iobase + com_cfcr, sp->cfcr);
2905 /*
2906 * XXX damp oscillations of MCR_DTR and MCR_RTS by not restoring them.
2907 */
2908 outb(iobase + com_mcr, sp->mcr | MCR_DTR | MCR_RTS);
2909 outb(iobase + com_ier, sp->ier);
2910}
2911
2912#ifndef __alpha__
2913
2914static void
2915siocnprobe(cp)
2916 struct consdev *cp;
2917{
2918 speed_t boot_speed;
2919 u_char cfcr;
2920 u_int divisor;
2921 int s, unit;
2922 struct siocnstate sp;
2923
2924 /*
2925 * Find our first enabled console, if any. If it is a high-level
2926 * console device, then initialize it and return successfully.
2927 * If it is a low-level console device, then initialize it and
2928 * return unsuccessfully. It must be initialized in both cases
2929 * for early use by console drivers and debuggers. Initializing
2930 * the hardware is not necessary in all cases, since the i/o
2931 * routines initialize it on the fly, but it is necessary if
2932 * input might arrive while the hardware is switched back to an
2933 * uninitialized state. We can't handle multiple console devices
2934 * yet because our low-level routines don't take a device arg.
2935 * We trust the user to set the console flags properly so that we
2936 * don't need to probe.
2937 */
2938 cp->cn_pri = CN_DEAD;
2939
2940 for (unit = 0; unit < 16; unit++) { /* XXX need to know how many */
2941 int flags;
2942 int disabled;
2943 if (resource_int_value("sio", unit, "disabled", &disabled) == 0) {
2944 if (disabled)
2945 continue;
2946 }
2947 if (resource_int_value("sio", unit, "flags", &flags))
2948 continue;
2949 if (COM_CONSOLE(flags) || COM_DEBUGGER(flags)) {
2950 int port;
2951 Port_t iobase;
2952
2953 if (resource_int_value("sio", unit, "port", &port))
2954 continue;
2955 iobase = port;
2956 s = spltty();
2957 if (boothowto & RB_SERIAL) {
2958 boot_speed =
2959 siocngetspeed(iobase, comdefaultrclk);
2960 if (boot_speed)
2961 comdefaultrate = boot_speed;
2962 }
2963
2964 /*
2965 * Initialize the divisor latch. We can't rely on
2966 * siocnopen() to do this the first time, since it
2967 * avoids writing to the latch if the latch appears
2968 * to have the correct value. Also, if we didn't
2969 * just read the speed from the hardware, then we
2970 * need to set the speed in hardware so that
2971 * switching it later is null.
2972 */
2973 cfcr = inb(iobase + com_cfcr);
2974 outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
2975 divisor = siodivisor(comdefaultrclk, comdefaultrate);
2976 outb(iobase + com_dlbl, divisor & 0xff);
2977 outb(iobase + com_dlbh, divisor >> 8);
2978 outb(iobase + com_cfcr, cfcr);
2979
2980 siocnopen(&sp, iobase, comdefaultrate);
2981
2982 splx(s);
2983 if (COM_CONSOLE(flags) && !COM_LLCONSOLE(flags)) {
2984 cp->cn_dev = makedev(CDEV_MAJOR, unit);
2985 cp->cn_pri = COM_FORCECONSOLE(flags)
2986 || boothowto & RB_SERIAL
2987 ? CN_REMOTE : CN_NORMAL;
2988 siocniobase = iobase;
2989 siocnunit = unit;
2990 }
2991 if (COM_DEBUGGER(flags)) {
2992 printf("sio%d: gdb debugging port\n", unit);
2993 siogdbiobase = iobase;
2994 siogdbunit = unit;
2995#if DDB > 0
2996 gdbconsdev.cn_dev = makedev(CDEV_MAJOR, unit);
2997 gdb_arg = &gdbconsdev;
2998 gdb_getc = siocngetc;
2999 gdb_putc = siocnputc;
3000#endif
3001 }
3002 }
3003 }
3004#ifdef __i386__
3005#if DDB > 0
3006 /*
3007 * XXX Ugly Compatability.
3008 * If no gdb port has been specified, set it to be the console
3009 * as some configuration files don't specify the gdb port.
3010 */
3011 if (gdb_arg == NULL && (boothowto & RB_GDB)) {
3012 printf("Warning: no GDB port specified. Defaulting to sio%d.\n",
3013 siocnunit);
3014 printf("Set flag 0x80 on desired GDB port in your\n");
3015 printf("configuration file (currently sio only).\n");
3016 siogdbiobase = siocniobase;
3017 siogdbunit = siocnunit;
3018 gdbconsdev.cn_dev = makedev(CDEV_MAJOR, siocnunit);
3019 gdb_arg = &gdbconsdev;
3020 gdb_getc = siocngetc;
3021 gdb_putc = siocnputc;
3022 }
3023#endif
3024#endif
3025}
3026
3027static void
3028siocninit(cp)
3029 struct consdev *cp;
3030{
3031 comconsole = DEV_TO_UNIT(cp->cn_dev);
3032}
3033
3034static void
3035siocnterm(cp)
3036 struct consdev *cp;
3037{
3038 comconsole = -1;
3039}
3040
3041#endif
3042
3043#ifdef __alpha__
3044
3045CONS_DRIVER(sio, NULL, NULL, NULL, siocngetc, siocncheckc, siocnputc, NULL);
3046
3047int
3048siocnattach(port, speed)
3049 int port;
3050 int speed;
3051{
3052 int s;
3053 u_char cfcr;
3054 u_int divisor;
3055 struct siocnstate sp;
3056 int unit = 0; /* XXX random value! */
3057
3058 siocniobase = port;
3059 siocnunit = unit;
3060 comdefaultrate = speed;
3061 sio_consdev.cn_pri = CN_NORMAL;
3062 sio_consdev.cn_dev = makedev(CDEV_MAJOR, unit);
3063
3064 s = spltty();
3065
3066 /*
3067 * Initialize the divisor latch. We can't rely on
3068 * siocnopen() to do this the first time, since it
3069 * avoids writing to the latch if the latch appears
3070 * to have the correct value. Also, if we didn't
3071 * just read the speed from the hardware, then we
3072 * need to set the speed in hardware so that
3073 * switching it later is null.
3074 */
3075 cfcr = inb(siocniobase + com_cfcr);
3076 outb(siocniobase + com_cfcr, CFCR_DLAB | cfcr);
3077 divisor = siodivisor(comdefaultrclk, comdefaultrate);
3078 outb(siocniobase + com_dlbl, divisor & 0xff);
3079 outb(siocniobase + com_dlbh, divisor >> 8);
3080 outb(siocniobase + com_cfcr, cfcr);
3081
3082 siocnopen(&sp, siocniobase, comdefaultrate);
3083 splx(s);
3084
3085 cnadd(&sio_consdev);
3086 return (0);
3087}
3088
3089int
3090siogdbattach(port, speed)
3091 int port;
3092 int speed;
3093{
3094 int s;
3095 u_char cfcr;
3096 u_int divisor;
3097 struct siocnstate sp;
3098 int unit = 1; /* XXX random value! */
3099
3100 siogdbiobase = port;
3101 gdbdefaultrate = speed;
3102
3103 printf("sio%d: gdb debugging port\n", unit);
3104 siogdbunit = unit;
3105#if DDB > 0
3106 gdbconsdev.cn_dev = makedev(CDEV_MAJOR, unit);
3107 gdb_arg = &gdbconsdev;
3108 gdb_getc = siocngetc;
3109 gdb_putc = siocnputc;
3110#endif
3111
3112 s = spltty();
3113
3114 /*
3115 * Initialize the divisor latch. We can't rely on
3116 * siocnopen() to do this the first time, since it
3117 * avoids writing to the latch if the latch appears
3118 * to have the correct value. Also, if we didn't
3119 * just read the speed from the hardware, then we
3120 * need to set the speed in hardware so that
3121 * switching it later is null.
3122 */
3123 cfcr = inb(siogdbiobase + com_cfcr);
3124 outb(siogdbiobase + com_cfcr, CFCR_DLAB | cfcr);
3125 divisor = siodivisor(comdefaultrclk, gdbdefaultrate);
3126 outb(siogdbiobase + com_dlbl, divisor & 0xff);
3127 outb(siogdbiobase + com_dlbh, divisor >> 8);
3128 outb(siogdbiobase + com_cfcr, cfcr);
3129
3130 siocnopen(&sp, siogdbiobase, gdbdefaultrate);
3131 splx(s);
3132
3133 return (0);
3134}
3135
3136#endif
3137
3138static int
3139siocncheckc(struct consdev *cd)
3140{
3141 int c;
3142 dev_t dev;
3143 Port_t iobase;
3144 int s;
3145 struct siocnstate sp;
3146 speed_t speed;
3147
3148 dev = cd->cn_dev;
3149 if (minor(dev) == siocnunit) {
3150 iobase = siocniobase;
3151 speed = comdefaultrate;
3152 } else {
3153 iobase = siogdbiobase;
3154 speed = gdbdefaultrate;
3155 }
3156 s = spltty();
3157 siocnopen(&sp, iobase, speed);
3158 if (inb(iobase + com_lsr) & LSR_RXRDY)
3159 c = inb(iobase + com_data);
3160 else
3161 c = -1;
3162 siocnclose(&sp, iobase);
3163 splx(s);
3164 return (c);
3165}
3166
3167
3168static int
3169siocngetc(struct consdev *cd)
3170{
3171 int c;
3172 dev_t dev;
3173 Port_t iobase;
3174 int s;
3175 struct siocnstate sp;
3176 speed_t speed;
3177
3178 dev = cd->cn_dev;
3179 if (minor(dev) == siocnunit) {
3180 iobase = siocniobase;
3181 speed = comdefaultrate;
3182 } else {
3183 iobase = siogdbiobase;
3184 speed = gdbdefaultrate;
3185 }
3186 s = spltty();
3187 siocnopen(&sp, iobase, speed);
3188 while (!(inb(iobase + com_lsr) & LSR_RXRDY))
3189 ;
3190 c = inb(iobase + com_data);
3191 siocnclose(&sp, iobase);
3192 splx(s);
3193 return (c);
3194}
3195
3196static void
3197siocnputc(struct consdev *cd, int c)
3198{
3199 int need_unlock;
3200 int s;
3201 dev_t dev;
3202 struct siocnstate sp;
3203 Port_t iobase;
3204 speed_t speed;
3205
3206 dev = cd->cn_dev;
3207 if (minor(dev) == siocnunit) {
3208 iobase = siocniobase;
3209 speed = comdefaultrate;
3210 } else {
3211 iobase = siogdbiobase;
3212 speed = gdbdefaultrate;
3213 }
3214 s = spltty();
3215 need_unlock = 0;
3216 if (sio_inited == 2 && !mtx_owned(&sio_lock)) {
3217 mtx_lock_spin(&sio_lock);
3218 need_unlock = 1;
3219 }
3220 siocnopen(&sp, iobase, speed);
3221 siocntxwait(iobase);
3222 outb(iobase + com_data, c);
3223 siocnclose(&sp, iobase);
3224 if (need_unlock)
3225 mtx_unlock_spin(&sio_lock);
3226 splx(s);
3227}
3228
3229#ifdef __alpha__
3230int
3231siogdbgetc()
3232{
3233 int c;
3234 Port_t iobase;
3235 speed_t speed;
3236 int s;
3237 struct siocnstate sp;
3238
3239 if (siogdbunit == siocnunit) {
3240 iobase = siocniobase;
3241 speed = comdefaultrate;
3242 } else {
3243 iobase = siogdbiobase;
3244 speed = gdbdefaultrate;
3245 }
3246
3247 s = spltty();
3248 siocnopen(&sp, iobase, speed);
3249 while (!(inb(iobase + com_lsr) & LSR_RXRDY))
3250 ;
3251 c = inb(iobase + com_data);
3252 siocnclose(&sp, iobase);
3253 splx(s);
3254 return (c);
3255}
3256
3257void
3258siogdbputc(c)
3259 int c;
3260{
3261 Port_t iobase;
3262 speed_t speed;
3263 int s;
3264 struct siocnstate sp;
3265
3266 if (siogdbunit == siocnunit) {
3267 iobase = siocniobase;
3268 speed = comdefaultrate;
3269 } else {
3270 iobase = siogdbiobase;
3271 speed = gdbdefaultrate;
3272 }
3273
3274 s = spltty();
3275 siocnopen(&sp, iobase, speed);
3276 siocntxwait(siogdbiobase);
3277 outb(siogdbiobase + com_data, c);
3278 siocnclose(&sp, siogdbiobase);
3279 splx(s);
3280}
3281#endif
327};
328
329int comconsole = -1;
330static volatile speed_t comdefaultrate = CONSPEED;
331static u_long comdefaultrclk = DEFAULT_RCLK;
332SYSCTL_ULONG(_machdep, OID_AUTO, conrclk, CTLFLAG_RW, &comdefaultrclk, 0, "");
333static speed_t gdbdefaultrate = GDBSPEED;
334SYSCTL_UINT(_machdep, OID_AUTO, gdbspeed, CTLFLAG_RW,
335 &gdbdefaultrate, GDBSPEED, "");
336static u_int com_events; /* input chars + weighted output completions */
337static Port_t siocniobase;
338static int siocnunit = -1;
339static Port_t siogdbiobase;
340static int siogdbunit = -1;
341static void *sio_slow_ih;
342static void *sio_fast_ih;
343static int sio_timeout;
344static int sio_timeouts_until_log;
345static struct callout_handle sio_timeout_handle
346 = CALLOUT_HANDLE_INITIALIZER(&sio_timeout_handle);
347static int sio_numunits;
348
349#ifdef COM_ESP
350/* XXX configure this properly. */
351/* XXX quite broken for new-bus. */
352static Port_t likely_com_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, };
353static Port_t likely_esp_ports[] = { 0x140, 0x180, 0x280, 0 };
354#endif
355
356/*
357 * handle sysctl read/write requests for console speed
358 *
359 * In addition to setting comdefaultrate for I/O through /dev/console,
360 * also set the initial and lock values for the /dev/ttyXX device
361 * if there is one associated with the console. Finally, if the /dev/tty
362 * device has already been open, change the speed on the open running port
363 * itself.
364 */
365
366static int
367sysctl_machdep_comdefaultrate(SYSCTL_HANDLER_ARGS)
368{
369 int error, s;
370 speed_t newspeed;
371 struct com_s *com;
372 struct tty *tp;
373
374 newspeed = comdefaultrate;
375
376 error = sysctl_handle_opaque(oidp, &newspeed, sizeof newspeed, req);
377 if (error || !req->newptr)
378 return (error);
379
380 comdefaultrate = newspeed;
381
382 if (comconsole < 0) /* serial console not selected? */
383 return (0);
384
385 com = com_addr(comconsole);
386 if (com == NULL)
387 return (ENXIO);
388
389 /*
390 * set the initial and lock rates for /dev/ttydXX and /dev/cuaXX
391 * (note, the lock rates really are boolean -- if non-zero, disallow
392 * speed changes)
393 */
394 com->it_in.c_ispeed = com->it_in.c_ospeed =
395 com->lt_in.c_ispeed = com->lt_in.c_ospeed =
396 com->it_out.c_ispeed = com->it_out.c_ospeed =
397 com->lt_out.c_ispeed = com->lt_out.c_ospeed = comdefaultrate;
398
399 /*
400 * if we're open, change the running rate too
401 */
402 tp = com->tp;
403 if (tp && (tp->t_state & TS_ISOPEN)) {
404 tp->t_termios.c_ispeed =
405 tp->t_termios.c_ospeed = comdefaultrate;
406 s = spltty();
407 error = comparam(tp, &tp->t_termios);
408 splx(s);
409 }
410 return error;
411}
412
413SYSCTL_PROC(_machdep, OID_AUTO, conspeed, CTLTYPE_INT | CTLFLAG_RW,
414 0, 0, sysctl_machdep_comdefaultrate, "I", "");
415/* TUNABLE_INT("machdep.conspeed", &comdefaultrate); */
416
417#define SET_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) | (bit))
418#define CLR_FLAG(dev, bit) device_set_flags(dev, device_get_flags(dev) & ~(bit))
419
420/*
421 * Unload the driver and clear the table.
422 * XXX this is mostly wrong.
423 * XXX TODO:
424 * This is usually called when the card is ejected, but
425 * can be caused by a kldunload of a controller driver.
426 * The idea is to reset the driver's view of the device
427 * and ensure that any driver entry points such as
428 * read and write do not hang.
429 */
430int
431siodetach(dev)
432 device_t dev;
433{
434 struct com_s *com;
435 int i;
436
437 com = (struct com_s *) device_get_softc(dev);
438 if (com == NULL) {
439 device_printf(dev, "NULL com in siounload\n");
440 return (0);
441 }
442 com->gone = 1;
443 for (i = 0 ; i < 6; i++)
444 destroy_dev(com->devs[i]);
445 if (com->irqres) {
446 bus_teardown_intr(dev, com->irqres, com->cookie);
447 bus_release_resource(dev, SYS_RES_IRQ, 0, com->irqres);
448 }
449 if (com->ioportres)
450 bus_release_resource(dev, SYS_RES_IOPORT, 0, com->ioportres);
451 if (com->tp && (com->tp->t_state & TS_ISOPEN)) {
452 device_printf(dev, "still open, forcing close\n");
453 (*linesw[com->tp->t_line].l_close)(com->tp, 0);
454 com->tp->t_gen++;
455 ttyclose(com->tp);
456 ttwakeup(com->tp);
457 ttwwakeup(com->tp);
458 } else {
459 if (com->ibuf != NULL)
460 free(com->ibuf, M_DEVBUF);
461 device_set_softc(dev, NULL);
462 free(com, M_DEVBUF);
463 }
464 return (0);
465}
466
467int
468sioprobe(dev, xrid, rclk, noprobe)
469 device_t dev;
470 int xrid;
471 u_long rclk;
472 int noprobe;
473{
474#if 0
475 static bool_t already_init;
476 device_t xdev;
477#endif
478 struct com_s *com;
479 u_int divisor;
480 bool_t failures[10];
481 int fn;
482 device_t idev;
483 Port_t iobase;
484 intrmask_t irqmap[4];
485 intrmask_t irqs;
486 u_char mcr_image;
487 int result;
488 u_long xirq;
489 u_int flags = device_get_flags(dev);
490 int rid;
491 struct resource *port;
492
493 rid = xrid;
494 port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
495 0, ~0, IO_COMSIZE, RF_ACTIVE);
496 if (!port)
497 return (ENXIO);
498
499 com = malloc(sizeof(*com), M_DEVBUF, M_NOWAIT | M_ZERO);
500 if (com == NULL)
501 return (ENOMEM);
502 device_set_softc(dev, com);
503 com->bst = rman_get_bustag(port);
504 com->bsh = rman_get_bushandle(port);
505 if (rclk == 0)
506 rclk = DEFAULT_RCLK;
507 com->rclk = rclk;
508
509 while (sio_inited != 2)
510 if (atomic_cmpset_int(&sio_inited, 0, 1)) {
511 mtx_init(&sio_lock, sio_driver_name, NULL,
512 (comconsole != -1) ?
513 MTX_SPIN | MTX_QUIET : MTX_SPIN);
514 atomic_store_rel_int(&sio_inited, 2);
515 }
516
517#if 0
518 /*
519 * XXX this is broken - when we are first called, there are no
520 * previously configured IO ports. We could hard code
521 * 0x3f8, 0x2f8, 0x3e8, 0x2e8 etc but that's probably worse.
522 * This code has been doing nothing since the conversion since
523 * "count" is zero the first time around.
524 */
525 if (!already_init) {
526 /*
527 * Turn off MCR_IENABLE for all likely serial ports. An unused
528 * port with its MCR_IENABLE gate open will inhibit interrupts
529 * from any used port that shares the interrupt vector.
530 * XXX the gate enable is elsewhere for some multiports.
531 */
532 device_t *devs;
533 int count, i, xioport;
534
535 devclass_get_devices(sio_devclass, &devs, &count);
536 for (i = 0; i < count; i++) {
537 xdev = devs[i];
538 if (device_is_enabled(xdev) &&
539 bus_get_resource(xdev, SYS_RES_IOPORT, 0, &xioport,
540 NULL) == 0)
541 outb(xioport + com_mcr, 0);
542 }
543 free(devs, M_TEMP);
544 already_init = TRUE;
545 }
546#endif
547
548 if (COM_LLCONSOLE(flags)) {
549 printf("sio%d: reserved for low-level i/o\n",
550 device_get_unit(dev));
551 bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
552 device_set_softc(dev, NULL);
553 free(com, M_DEVBUF);
554 return (ENXIO);
555 }
556
557 /*
558 * If the device is on a multiport card and has an AST/4
559 * compatible interrupt control register, initialize this
560 * register and prepare to leave MCR_IENABLE clear in the mcr.
561 * Otherwise, prepare to set MCR_IENABLE in the mcr.
562 * Point idev to the device struct giving the correct id_irq.
563 * This is the struct for the master device if there is one.
564 */
565 idev = dev;
566 mcr_image = MCR_IENABLE;
567#ifdef COM_MULTIPORT
568 if (COM_ISMULTIPORT(flags)) {
569 Port_t xiobase;
570 u_long io;
571
572 idev = devclass_get_device(sio_devclass, COM_MPMASTER(flags));
573 if (idev == NULL) {
574 printf("sio%d: master device %d not configured\n",
575 device_get_unit(dev), COM_MPMASTER(flags));
576 idev = dev;
577 }
578 if (!COM_NOTAST4(flags)) {
579 if (bus_get_resource(idev, SYS_RES_IOPORT, 0, &io,
580 NULL) == 0) {
581 xiobase = io;
582 if (bus_get_resource(idev, SYS_RES_IRQ, 0,
583 NULL, NULL) == 0)
584 outb(xiobase + com_scr, 0x80);
585 else
586 outb(xiobase + com_scr, 0);
587 }
588 mcr_image = 0;
589 }
590 }
591#endif /* COM_MULTIPORT */
592 if (bus_get_resource(idev, SYS_RES_IRQ, 0, NULL, NULL) != 0)
593 mcr_image = 0;
594
595 bzero(failures, sizeof failures);
596 iobase = rman_get_start(port);
597
598 /*
599 * We don't want to get actual interrupts, just masked ones.
600 * Interrupts from this line should already be masked in the ICU,
601 * but mask them in the processor as well in case there are some
602 * (misconfigured) shared interrupts.
603 */
604 mtx_lock_spin(&sio_lock);
605/* EXTRA DELAY? */
606
607 /*
608 * Initialize the speed and the word size and wait long enough to
609 * drain the maximum of 16 bytes of junk in device output queues.
610 * The speed is undefined after a master reset and must be set
611 * before relying on anything related to output. There may be
612 * junk after a (very fast) soft reboot and (apparently) after
613 * master reset.
614 * XXX what about the UART bug avoided by waiting in comparam()?
615 * We don't want to to wait long enough to drain at 2 bps.
616 */
617 if (iobase == siocniobase)
618 DELAY((16 + 1) * 1000000 / (comdefaultrate / 10));
619 else {
620 sio_setreg(com, com_cfcr, CFCR_DLAB | CFCR_8BITS);
621 divisor = siodivisor(rclk, SIO_TEST_SPEED);
622 sio_setreg(com, com_dlbl, divisor & 0xff);
623 sio_setreg(com, com_dlbh, divisor >> 8);
624 sio_setreg(com, com_cfcr, CFCR_8BITS);
625 DELAY((16 + 1) * 1000000 / (SIO_TEST_SPEED / 10));
626 }
627
628 /*
629 * Enable the interrupt gate and disable device interupts. This
630 * should leave the device driving the interrupt line low and
631 * guarantee an edge trigger if an interrupt can be generated.
632 */
633/* EXTRA DELAY? */
634 sio_setreg(com, com_mcr, mcr_image);
635 sio_setreg(com, com_ier, 0);
636 DELAY(1000); /* XXX */
637 irqmap[0] = isa_irq_pending();
638
639 /*
640 * Attempt to set loopback mode so that we can send a null byte
641 * without annoying any external device.
642 */
643/* EXTRA DELAY? */
644 sio_setreg(com, com_mcr, mcr_image | MCR_LOOPBACK);
645
646 /*
647 * Attempt to generate an output interrupt. On 8250's, setting
648 * IER_ETXRDY generates an interrupt independent of the current
649 * setting and independent of whether the THR is empty. On 16450's,
650 * setting IER_ETXRDY generates an interrupt independent of the
651 * current setting. On 16550A's, setting IER_ETXRDY only
652 * generates an interrupt when IER_ETXRDY is not already set.
653 */
654 sio_setreg(com, com_ier, IER_ETXRDY);
655
656 /*
657 * On some 16x50 incompatibles, setting IER_ETXRDY doesn't generate
658 * an interrupt. They'd better generate one for actually doing
659 * output. Loopback may be broken on the same incompatibles but
660 * it's unlikely to do more than allow the null byte out.
661 */
662 sio_setreg(com, com_data, 0);
663 DELAY((1 + 2) * 1000000 / (SIO_TEST_SPEED / 10));
664
665 /*
666 * Turn off loopback mode so that the interrupt gate works again
667 * (MCR_IENABLE was hidden). This should leave the device driving
668 * an interrupt line high. It doesn't matter if the interrupt
669 * line oscillates while we are not looking at it, since interrupts
670 * are disabled.
671 */
672/* EXTRA DELAY? */
673 sio_setreg(com, com_mcr, mcr_image);
674
675 /*
676 * It seems my Xircom CBEM56G Cardbus modem wants to be reset
677 * to 8 bits *again*, or else probe test 0 will fail.
678 * gwk@sgi.com, 4/19/2001
679 */
680 sio_setreg(com, com_cfcr, CFCR_8BITS);
681
682 /*
683 * Some pcmcia cards have the "TXRDY bug", so we check everyone
684 * for IIR_TXRDY implementation ( Palido 321s, DC-1S... )
685 */
686 if (noprobe) {
687 /* Reading IIR register twice */
688 for (fn = 0; fn < 2; fn ++) {
689 DELAY(10000);
690 failures[6] = sio_getreg(com, com_iir);
691 }
692 /* Check IIR_TXRDY clear ? */
693 result = 0;
694 if (failures[6] & IIR_TXRDY) {
695 /* No, Double check with clearing IER */
696 sio_setreg(com, com_ier, 0);
697 if (sio_getreg(com, com_iir) & IIR_NOPEND) {
698 /* Ok. We discovered TXRDY bug! */
699 SET_FLAG(dev, COM_C_IIR_TXRDYBUG);
700 } else {
701 /* Unknown, Just omit this chip.. XXX */
702 result = ENXIO;
703 sio_setreg(com, com_mcr, 0);
704 }
705 } else {
706 /* OK. this is well-known guys */
707 CLR_FLAG(dev, COM_C_IIR_TXRDYBUG);
708 }
709 sio_setreg(com, com_ier, 0);
710 sio_setreg(com, com_cfcr, CFCR_8BITS);
711 mtx_unlock_spin(&sio_lock);
712 bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
713 if (iobase == siocniobase)
714 result = 0;
715 if (result != 0) {
716 device_set_softc(dev, NULL);
717 free(com, M_DEVBUF);
718 }
719 return (result);
720 }
721
722 /*
723 * Check that
724 * o the CFCR, IER and MCR in UART hold the values written to them
725 * (the values happen to be all distinct - this is good for
726 * avoiding false positive tests from bus echoes).
727 * o an output interrupt is generated and its vector is correct.
728 * o the interrupt goes away when the IIR in the UART is read.
729 */
730/* EXTRA DELAY? */
731 failures[0] = sio_getreg(com, com_cfcr) - CFCR_8BITS;
732 failures[1] = sio_getreg(com, com_ier) - IER_ETXRDY;
733 failures[2] = sio_getreg(com, com_mcr) - mcr_image;
734 DELAY(10000); /* Some internal modems need this time */
735 irqmap[1] = isa_irq_pending();
736 failures[4] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_TXRDY;
737 DELAY(1000); /* XXX */
738 irqmap[2] = isa_irq_pending();
739 failures[6] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND;
740
741 /*
742 * Turn off all device interrupts and check that they go off properly.
743 * Leave MCR_IENABLE alone. For ports without a master port, it gates
744 * the OUT2 output of the UART to
745 * the ICU input. Closing the gate would give a floating ICU input
746 * (unless there is another device driving it) and spurious interrupts.
747 * (On the system that this was first tested on, the input floats high
748 * and gives a (masked) interrupt as soon as the gate is closed.)
749 */
750 sio_setreg(com, com_ier, 0);
751 sio_setreg(com, com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */
752 failures[7] = sio_getreg(com, com_ier);
753 DELAY(1000); /* XXX */
754 irqmap[3] = isa_irq_pending();
755 failures[9] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND;
756
757 mtx_unlock_spin(&sio_lock);
758
759 irqs = irqmap[1] & ~irqmap[0];
760 if (bus_get_resource(idev, SYS_RES_IRQ, 0, &xirq, NULL) == 0 &&
761 ((1 << xirq) & irqs) == 0) {
762 printf(
763 "sio%d: configured irq %ld not in bitmap of probed irqs %#x\n",
764 device_get_unit(dev), xirq, irqs);
765 printf(
766 "sio%d: port may not be enabled\n",
767 device_get_unit(dev));
768 }
769 if (bootverbose)
770 printf("sio%d: irq maps: %#x %#x %#x %#x\n",
771 device_get_unit(dev),
772 irqmap[0], irqmap[1], irqmap[2], irqmap[3]);
773
774 result = 0;
775 for (fn = 0; fn < sizeof failures; ++fn)
776 if (failures[fn]) {
777 sio_setreg(com, com_mcr, 0);
778 result = ENXIO;
779 if (bootverbose) {
780 printf("sio%d: probe failed test(s):",
781 device_get_unit(dev));
782 for (fn = 0; fn < sizeof failures; ++fn)
783 if (failures[fn])
784 printf(" %d", fn);
785 printf("\n");
786 }
787 break;
788 }
789 bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
790 if (iobase == siocniobase)
791 result = 0;
792 if (result != 0) {
793 device_set_softc(dev, NULL);
794 free(com, M_DEVBUF);
795 }
796 return (result);
797}
798
799#ifdef COM_ESP
800static int
801espattach(com, esp_port)
802 struct com_s *com;
803 Port_t esp_port;
804{
805 u_char dips;
806 u_char val;
807
808 /*
809 * Check the ESP-specific I/O port to see if we're an ESP
810 * card. If not, return failure immediately.
811 */
812 if ((inb(esp_port) & 0xf3) == 0) {
813 printf(" port 0x%x is not an ESP board?\n", esp_port);
814 return (0);
815 }
816
817 /*
818 * We've got something that claims to be a Hayes ESP card.
819 * Let's hope so.
820 */
821
822 /* Get the dip-switch configuration */
823 outb(esp_port + ESP_CMD1, ESP_GETDIPS);
824 dips = inb(esp_port + ESP_STATUS1);
825
826 /*
827 * Bits 0,1 of dips say which COM port we are.
828 */
829 if (rman_get_start(com->ioportres) == likely_com_ports[dips & 0x03])
830 printf(" : ESP");
831 else {
832 printf(" esp_port has com %d\n", dips & 0x03);
833 return (0);
834 }
835
836 /*
837 * Check for ESP version 2.0 or later: bits 4,5,6 = 010.
838 */
839 outb(esp_port + ESP_CMD1, ESP_GETTEST);
840 val = inb(esp_port + ESP_STATUS1); /* clear reg 1 */
841 val = inb(esp_port + ESP_STATUS2);
842 if ((val & 0x70) < 0x20) {
843 printf("-old (%o)", val & 0x70);
844 return (0);
845 }
846
847 /*
848 * Check for ability to emulate 16550: bit 7 == 1
849 */
850 if ((dips & 0x80) == 0) {
851 printf(" slave");
852 return (0);
853 }
854
855 /*
856 * Okay, we seem to be a Hayes ESP card. Whee.
857 */
858 com->esp = TRUE;
859 com->esp_port = esp_port;
860 return (1);
861}
862#endif /* COM_ESP */
863
864int
865sioattach(dev, xrid, rclk)
866 device_t dev;
867 int xrid;
868 u_long rclk;
869{
870 struct com_s *com;
871#ifdef COM_ESP
872 Port_t *espp;
873#endif
874 Port_t iobase;
875 int minorbase;
876 int unit;
877 u_int flags;
878 int rid;
879 struct resource *port;
880 int ret;
881
882 rid = xrid;
883 port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
884 0, ~0, IO_COMSIZE, RF_ACTIVE);
885 if (!port)
886 return (ENXIO);
887
888 iobase = rman_get_start(port);
889 unit = device_get_unit(dev);
890 com = device_get_softc(dev);
891 flags = device_get_flags(dev);
892
893 if (unit >= sio_numunits)
894 sio_numunits = unit + 1;
895 /*
896 * sioprobe() has initialized the device registers as follows:
897 * o cfcr = CFCR_8BITS.
898 * It is most important that CFCR_DLAB is off, so that the
899 * data port is not hidden when we enable interrupts.
900 * o ier = 0.
901 * Interrupts are only enabled when the line is open.
902 * o mcr = MCR_IENABLE, or 0 if the port has AST/4 compatible
903 * interrupt control register or the config specifies no irq.
904 * Keeping MCR_DTR and MCR_RTS off might stop the external
905 * device from sending before we are ready.
906 */
907 bzero(com, sizeof *com);
908 com->unit = unit;
909 com->ioportres = port;
910 com->bst = rman_get_bustag(port);
911 com->bsh = rman_get_bushandle(port);
912 com->cfcr_image = CFCR_8BITS;
913 com->dtr_wait = 3 * hz;
914 com->loses_outints = COM_LOSESOUTINTS(flags) != 0;
915 com->no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0;
916 com->tx_fifo_size = 1;
917 com->obufs[0].l_head = com->obuf1;
918 com->obufs[1].l_head = com->obuf2;
919
920 com->data_port = iobase + com_data;
921 com->int_id_port = iobase + com_iir;
922 com->modem_ctl_port = iobase + com_mcr;
923 com->mcr_image = inb(com->modem_ctl_port);
924 com->line_status_port = iobase + com_lsr;
925 com->modem_status_port = iobase + com_msr;
926 com->intr_ctl_port = iobase + com_ier;
927
928 if (rclk == 0)
929 rclk = DEFAULT_RCLK;
930 com->rclk = rclk;
931
932 /*
933 * We don't use all the flags from <sys/ttydefaults.h> since they
934 * are only relevant for logins. It's important to have echo off
935 * initially so that the line doesn't start blathering before the
936 * echo flag can be turned off.
937 */
938 com->it_in.c_iflag = 0;
939 com->it_in.c_oflag = 0;
940 com->it_in.c_cflag = TTYDEF_CFLAG;
941 com->it_in.c_lflag = 0;
942 if (unit == comconsole) {
943 com->it_in.c_iflag = TTYDEF_IFLAG;
944 com->it_in.c_oflag = TTYDEF_OFLAG;
945 com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL;
946 com->it_in.c_lflag = TTYDEF_LFLAG;
947 com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
948 com->lt_out.c_ispeed = com->lt_out.c_ospeed =
949 com->lt_in.c_ispeed = com->lt_in.c_ospeed =
950 com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
951 } else
952 com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED;
953 if (siosetwater(com, com->it_in.c_ispeed) != 0) {
954 mtx_unlock_spin(&sio_lock);
955 /*
956 * Leave i/o resources allocated if this is a `cn'-level
957 * console, so that other devices can't snarf them.
958 */
959 if (iobase != siocniobase)
960 bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
961 return (ENOMEM);
962 }
963 mtx_unlock_spin(&sio_lock);
964 termioschars(&com->it_in);
965 com->it_out = com->it_in;
966
967 /* attempt to determine UART type */
968 printf("sio%d: type", unit);
969
970
971 if (!COM_ISMULTIPORT(flags) &&
972 !COM_IIR_TXRDYBUG(flags) && !COM_NOSCR(flags)) {
973 u_char scr;
974 u_char scr1;
975 u_char scr2;
976
977 scr = sio_getreg(com, com_scr);
978 sio_setreg(com, com_scr, 0xa5);
979 scr1 = sio_getreg(com, com_scr);
980 sio_setreg(com, com_scr, 0x5a);
981 scr2 = sio_getreg(com, com_scr);
982 sio_setreg(com, com_scr, scr);
983 if (scr1 != 0xa5 || scr2 != 0x5a) {
984 printf(" 8250 or not responding");
985 goto determined_type;
986 }
987 }
988 sio_setreg(com, com_fifo, FIFO_ENABLE | FIFO_RX_HIGH);
989 DELAY(100);
990 com->st16650a = 0;
991 switch (inb(com->int_id_port) & IIR_FIFO_MASK) {
992 case FIFO_RX_LOW:
993 printf(" 16450");
994 break;
995 case FIFO_RX_MEDL:
996 printf(" 16450?");
997 break;
998 case FIFO_RX_MEDH:
999 printf(" 16550?");
1000 break;
1001 case FIFO_RX_HIGH:
1002 if (COM_NOFIFO(flags)) {
1003 printf(" 16550A fifo disabled");
1004 } else {
1005 com->hasfifo = TRUE;
1006 if (COM_ST16650A(flags)) {
1007 com->st16650a = 1;
1008 com->tx_fifo_size = 32;
1009 printf(" ST16650A");
1010 } else {
1011 com->tx_fifo_size = COM_FIFOSIZE(flags);
1012 printf(" 16550A");
1013 }
1014 }
1015#ifdef COM_ESP
1016 for (espp = likely_esp_ports; *espp != 0; espp++)
1017 if (espattach(com, *espp)) {
1018 com->tx_fifo_size = 1024;
1019 break;
1020 }
1021#endif
1022 if (!com->st16650a) {
1023 if (!com->tx_fifo_size)
1024 com->tx_fifo_size = 16;
1025 else
1026 printf(" lookalike with %d bytes FIFO",
1027 com->tx_fifo_size);
1028 }
1029
1030 break;
1031 }
1032
1033#ifdef COM_ESP
1034 if (com->esp) {
1035 /*
1036 * Set 16550 compatibility mode.
1037 * We don't use the ESP_MODE_SCALE bit to increase the
1038 * fifo trigger levels because we can't handle large
1039 * bursts of input.
1040 * XXX flow control should be set in comparam(), not here.
1041 */
1042 outb(com->esp_port + ESP_CMD1, ESP_SETMODE);
1043 outb(com->esp_port + ESP_CMD2, ESP_MODE_RTS | ESP_MODE_FIFO);
1044
1045 /* Set RTS/CTS flow control. */
1046 outb(com->esp_port + ESP_CMD1, ESP_SETFLOWTYPE);
1047 outb(com->esp_port + ESP_CMD2, ESP_FLOW_RTS);
1048 outb(com->esp_port + ESP_CMD2, ESP_FLOW_CTS);
1049
1050 /* Set flow-control levels. */
1051 outb(com->esp_port + ESP_CMD1, ESP_SETRXFLOW);
1052 outb(com->esp_port + ESP_CMD2, HIBYTE(768));
1053 outb(com->esp_port + ESP_CMD2, LOBYTE(768));
1054 outb(com->esp_port + ESP_CMD2, HIBYTE(512));
1055 outb(com->esp_port + ESP_CMD2, LOBYTE(512));
1056 }
1057#endif /* COM_ESP */
1058 sio_setreg(com, com_fifo, 0);
1059determined_type: ;
1060
1061#ifdef COM_MULTIPORT
1062 if (COM_ISMULTIPORT(flags)) {
1063 device_t masterdev;
1064
1065 com->multiport = TRUE;
1066 printf(" (multiport");
1067 if (unit == COM_MPMASTER(flags))
1068 printf(" master");
1069 printf(")");
1070 masterdev = devclass_get_device(sio_devclass,
1071 COM_MPMASTER(flags));
1072 com->no_irq = (masterdev == NULL || bus_get_resource(masterdev,
1073 SYS_RES_IRQ, 0, NULL, NULL) != 0);
1074 }
1075#endif /* COM_MULTIPORT */
1076 if (unit == comconsole)
1077 printf(", console");
1078 if (COM_IIR_TXRDYBUG(flags))
1079 printf(" with a bogus IIR_TXRDY register");
1080 printf("\n");
1081
1082 if (sio_fast_ih == NULL) {
1083 swi_add(&tty_ithd, "tty:sio", siopoll, NULL, SWI_TTY, 0,
1084 &sio_fast_ih);
1085 swi_add(&clk_ithd, "tty:sio", siopoll, NULL, SWI_TTY, 0,
1086 &sio_slow_ih);
1087 }
1088 minorbase = UNIT_TO_MINOR(unit);
1089 com->devs[0] = make_dev(&sio_cdevsw, minorbase,
1090 UID_ROOT, GID_WHEEL, 0600, "ttyd%r", unit);
1091 com->devs[1] = make_dev(&sio_cdevsw, minorbase | CONTROL_INIT_STATE,
1092 UID_ROOT, GID_WHEEL, 0600, "ttyid%r", unit);
1093 com->devs[2] = make_dev(&sio_cdevsw, minorbase | CONTROL_LOCK_STATE,
1094 UID_ROOT, GID_WHEEL, 0600, "ttyld%r", unit);
1095 com->devs[3] = make_dev(&sio_cdevsw, minorbase | CALLOUT_MASK,
1096 UID_UUCP, GID_DIALER, 0660, "cuaa%r", unit);
1097 com->devs[4] = make_dev(&sio_cdevsw,
1098 minorbase | CALLOUT_MASK | CONTROL_INIT_STATE,
1099 UID_UUCP, GID_DIALER, 0660, "cuaia%r", unit);
1100 com->devs[5] = make_dev(&sio_cdevsw,
1101 minorbase | CALLOUT_MASK | CONTROL_LOCK_STATE,
1102 UID_UUCP, GID_DIALER, 0660, "cuala%r", unit);
1103 for (rid = 0; rid < 6; rid++)
1104 com->devs[rid]->si_drv1 = com;
1105 com->flags = flags;
1106 com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;
1107
1108 if (COM_PPSCTS(flags))
1109 com->pps_bit = MSR_CTS;
1110 else
1111 com->pps_bit = MSR_DCD;
1112 pps_init(&com->pps);
1113
1114 rid = 0;
1115 com->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1,
1116 RF_ACTIVE);
1117 if (com->irqres) {
1118 ret = BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres,
1119 INTR_TYPE_TTY | INTR_FAST,
1120 siointr, com, &com->cookie);
1121 if (ret) {
1122 ret = BUS_SETUP_INTR(device_get_parent(dev), dev,
1123 com->irqres, INTR_TYPE_TTY,
1124 siointr, com, &com->cookie);
1125 if (ret == 0)
1126 device_printf(dev, "unable to activate interrupt in fast mode - using normal mode\n");
1127 }
1128 if (ret)
1129 device_printf(dev, "could not activate interrupt\n");
1130#if defined(DDB) && (defined(BREAK_TO_DEBUGGER) || \
1131 defined(ALT_BREAK_TO_DEBUGGER))
1132 /*
1133 * Enable interrupts for early break-to-debugger support
1134 * on the console.
1135 */
1136 if (ret == 0 && unit == comconsole)
1137 outb(siocniobase + com_ier, IER_ERXRDY | IER_ERLS |
1138 IER_EMSC);
1139#endif
1140 }
1141
1142 return (0);
1143}
1144
1145static int
1146sioopen(dev, flag, mode, td)
1147 dev_t dev;
1148 int flag;
1149 int mode;
1150 struct thread *td;
1151{
1152 struct com_s *com;
1153 int error;
1154 int mynor;
1155 int s;
1156 struct tty *tp;
1157 int unit;
1158
1159 mynor = minor(dev);
1160 unit = MINOR_TO_UNIT(mynor);
1161 com = com_addr(unit);
1162 if (com == NULL)
1163 return (ENXIO);
1164 if (com->gone)
1165 return (ENXIO);
1166 if (mynor & CONTROL_MASK)
1167 return (0);
1168 tp = dev->si_tty = com->tp = ttymalloc(com->tp);
1169 s = spltty();
1170 /*
1171 * We jump to this label after all non-interrupted sleeps to pick
1172 * up any changes of the device state.
1173 */
1174open_top:
1175 while (com->state & CS_DTR_OFF) {
1176 error = tsleep(&com->dtr_wait, TTIPRI | PCATCH, "siodtr", 0);
1177 if (com_addr(unit) == NULL)
1178 return (ENXIO);
1179 if (error != 0 || com->gone)
1180 goto out;
1181 }
1182 if (tp->t_state & TS_ISOPEN) {
1183 /*
1184 * The device is open, so everything has been initialized.
1185 * Handle conflicts.
1186 */
1187 if (mynor & CALLOUT_MASK) {
1188 if (!com->active_out) {
1189 error = EBUSY;
1190 goto out;
1191 }
1192 } else {
1193 if (com->active_out) {
1194 if (flag & O_NONBLOCK) {
1195 error = EBUSY;
1196 goto out;
1197 }
1198 error = tsleep(&com->active_out,
1199 TTIPRI | PCATCH, "siobi", 0);
1200 if (com_addr(unit) == NULL)
1201 return (ENXIO);
1202 if (error != 0 || com->gone)
1203 goto out;
1204 goto open_top;
1205 }
1206 }
1207 if (tp->t_state & TS_XCLUDE &&
1208 suser(td)) {
1209 error = EBUSY;
1210 goto out;
1211 }
1212 } else {
1213 /*
1214 * The device isn't open, so there are no conflicts.
1215 * Initialize it. Initialization is done twice in many
1216 * cases: to preempt sleeping callin opens if we are
1217 * callout, and to complete a callin open after DCD rises.
1218 */
1219 tp->t_oproc = comstart;
1220 tp->t_param = comparam;
1221 tp->t_stop = comstop;
1222 tp->t_dev = dev;
1223 tp->t_termios = mynor & CALLOUT_MASK
1224 ? com->it_out : com->it_in;
1225 (void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET);
1226 com->poll = com->no_irq;
1227 com->poll_output = com->loses_outints;
1228 ++com->wopeners;
1229 error = comparam(tp, &tp->t_termios);
1230 --com->wopeners;
1231 if (error != 0)
1232 goto out;
1233 /*
1234 * XXX we should goto open_top if comparam() slept.
1235 */
1236 if (com->hasfifo) {
1237 int i;
1238 /*
1239 * (Re)enable and drain fifos.
1240 *
1241 * Certain SMC chips cause problems if the fifos
1242 * are enabled while input is ready. Turn off the
1243 * fifo if necessary to clear the input. We test
1244 * the input ready bit after enabling the fifos
1245 * since we've already enabled them in comparam()
1246 * and to handle races between enabling and fresh
1247 * input.
1248 */
1249 for (i = 0; i < 500; i++) {
1250 sio_setreg(com, com_fifo,
1251 FIFO_RCV_RST | FIFO_XMT_RST
1252 | com->fifo_image);
1253 /*
1254 * XXX the delays are for superstitious
1255 * historical reasons. It must be less than
1256 * the character time at the maximum
1257 * supported speed (87 usec at 115200 bps
1258 * 8N1). Otherwise we might loop endlessly
1259 * if data is streaming in. We used to use
1260 * delays of 100. That usually worked
1261 * because DELAY(100) used to usually delay
1262 * for about 85 usec instead of 100.
1263 */
1264 DELAY(50);
1265 if (!(inb(com->line_status_port) & LSR_RXRDY))
1266 break;
1267 sio_setreg(com, com_fifo, 0);
1268 DELAY(50);
1269 (void) inb(com->data_port);
1270 }
1271 if (i == 500) {
1272 error = EIO;
1273 goto out;
1274 }
1275 }
1276
1277 mtx_lock_spin(&sio_lock);
1278 (void) inb(com->line_status_port);
1279 (void) inb(com->data_port);
1280 com->prev_modem_status = com->last_modem_status
1281 = inb(com->modem_status_port);
1282 if (COM_IIR_TXRDYBUG(com->flags)) {
1283 outb(com->intr_ctl_port, IER_ERXRDY | IER_ERLS
1284 | IER_EMSC);
1285 } else {
1286 outb(com->intr_ctl_port, IER_ERXRDY | IER_ETXRDY
1287 | IER_ERLS | IER_EMSC);
1288 }
1289 mtx_unlock_spin(&sio_lock);
1290 /*
1291 * Handle initial DCD. Callout devices get a fake initial
1292 * DCD (trapdoor DCD). If we are callout, then any sleeping
1293 * callin opens get woken up and resume sleeping on "siobi"
1294 * instead of "siodcd".
1295 */
1296 /*
1297 * XXX `mynor & CALLOUT_MASK' should be
1298 * `tp->t_cflag & (SOFT_CARRIER | TRAPDOOR_CARRIER) where
1299 * TRAPDOOR_CARRIER is the default initial state for callout
1300 * devices and SOFT_CARRIER is like CLOCAL except it hides
1301 * the true carrier.
1302 */
1303 if (com->prev_modem_status & MSR_DCD || mynor & CALLOUT_MASK)
1304 (*linesw[tp->t_line].l_modem)(tp, 1);
1305 }
1306 /*
1307 * Wait for DCD if necessary.
1308 */
1309 if (!(tp->t_state & TS_CARR_ON) && !(mynor & CALLOUT_MASK)
1310 && !(tp->t_cflag & CLOCAL) && !(flag & O_NONBLOCK)) {
1311 ++com->wopeners;
1312 error = tsleep(TSA_CARR_ON(tp), TTIPRI | PCATCH, "siodcd", 0);
1313 if (com_addr(unit) == NULL)
1314 return (ENXIO);
1315 --com->wopeners;
1316 if (error != 0 || com->gone)
1317 goto out;
1318 goto open_top;
1319 }
1320 error = (*linesw[tp->t_line].l_open)(dev, tp);
1321 disc_optim(tp, &tp->t_termios, com);
1322 if (tp->t_state & TS_ISOPEN && mynor & CALLOUT_MASK)
1323 com->active_out = TRUE;
1324 siosettimeout();
1325out:
1326 splx(s);
1327 if (!(tp->t_state & TS_ISOPEN) && com->wopeners == 0)
1328 comhardclose(com);
1329 return (error);
1330}
1331
1332static int
1333sioclose(dev, flag, mode, td)
1334 dev_t dev;
1335 int flag;
1336 int mode;
1337 struct thread *td;
1338{
1339 struct com_s *com;
1340 int mynor;
1341 int s;
1342 struct tty *tp;
1343
1344 mynor = minor(dev);
1345 if (mynor & CONTROL_MASK)
1346 return (0);
1347 com = com_addr(MINOR_TO_UNIT(mynor));
1348 if (com == NULL)
1349 return (ENODEV);
1350 tp = com->tp;
1351 s = spltty();
1352 (*linesw[tp->t_line].l_close)(tp, flag);
1353 disc_optim(tp, &tp->t_termios, com);
1354 comstop(tp, FREAD | FWRITE);
1355 comhardclose(com);
1356 ttyclose(tp);
1357 siosettimeout();
1358 splx(s);
1359 if (com->gone) {
1360 printf("sio%d: gone\n", com->unit);
1361 s = spltty();
1362 if (com->ibuf != NULL)
1363 free(com->ibuf, M_DEVBUF);
1364 bzero(tp, sizeof *tp);
1365 splx(s);
1366 }
1367 return (0);
1368}
1369
1370static void
1371comhardclose(com)
1372 struct com_s *com;
1373{
1374 int s;
1375 struct tty *tp;
1376 int unit;
1377
1378 unit = com->unit;
1379 s = spltty();
1380 com->poll = FALSE;
1381 com->poll_output = FALSE;
1382 com->do_timestamp = FALSE;
1383 com->do_dcd_timestamp = FALSE;
1384 com->pps.ppsparam.mode = 0;
1385 sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
1386 tp = com->tp;
1387
1388#if defined(DDB) && (defined(BREAK_TO_DEBUGGER) || \
1389 defined(ALT_BREAK_TO_DEBUGGER))
1390 /*
1391 * Leave interrupts enabled and don't clear DTR if this is the
1392 * console. This allows us to detect break-to-debugger events
1393 * while the console device is closed.
1394 */
1395 if (com->unit != comconsole)
1396#endif
1397 {
1398 sio_setreg(com, com_ier, 0);
1399 if (tp->t_cflag & HUPCL
1400 /*
1401 * XXX we will miss any carrier drop between here and the
1402 * next open. Perhaps we should watch DCD even when the
1403 * port is closed; it is not sufficient to check it at
1404 * the next open because it might go up and down while
1405 * we're not watching.
1406 */
1407 || (!com->active_out
1408 && !(com->prev_modem_status & MSR_DCD)
1409 && !(com->it_in.c_cflag & CLOCAL))
1410 || !(tp->t_state & TS_ISOPEN)) {
1411 (void)commctl(com, TIOCM_DTR, DMBIC);
1412 if (com->dtr_wait != 0 && !(com->state & CS_DTR_OFF)) {
1413 timeout(siodtrwakeup, com, com->dtr_wait);
1414 com->state |= CS_DTR_OFF;
1415 }
1416 }
1417 }
1418 if (com->hasfifo) {
1419 /*
1420 * Disable fifos so that they are off after controlled
1421 * reboots. Some BIOSes fail to detect 16550s when the
1422 * fifos are enabled.
1423 */
1424 sio_setreg(com, com_fifo, 0);
1425 }
1426 com->active_out = FALSE;
1427 wakeup(&com->active_out);
1428 wakeup(TSA_CARR_ON(tp)); /* restart any wopeners */
1429 splx(s);
1430}
1431
1432static int
1433sioread(dev, uio, flag)
1434 dev_t dev;
1435 struct uio *uio;
1436 int flag;
1437{
1438 int mynor;
1439 struct com_s *com;
1440
1441 mynor = minor(dev);
1442 if (mynor & CONTROL_MASK)
1443 return (ENODEV);
1444 com = com_addr(MINOR_TO_UNIT(mynor));
1445 if (com == NULL || com->gone)
1446 return (ENODEV);
1447 return ((*linesw[com->tp->t_line].l_read)(com->tp, uio, flag));
1448}
1449
1450static int
1451siowrite(dev, uio, flag)
1452 dev_t dev;
1453 struct uio *uio;
1454 int flag;
1455{
1456 int mynor;
1457 struct com_s *com;
1458 int unit;
1459
1460 mynor = minor(dev);
1461 if (mynor & CONTROL_MASK)
1462 return (ENODEV);
1463
1464 unit = MINOR_TO_UNIT(mynor);
1465 com = com_addr(unit);
1466 if (com == NULL || com->gone)
1467 return (ENODEV);
1468 /*
1469 * (XXX) We disallow virtual consoles if the physical console is
1470 * a serial port. This is in case there is a display attached that
1471 * is not the console. In that situation we don't need/want the X
1472 * server taking over the console.
1473 */
1474 if (constty != NULL && unit == comconsole)
1475 constty = NULL;
1476 return ((*linesw[com->tp->t_line].l_write)(com->tp, uio, flag));
1477}
1478
1479static void
1480siobusycheck(chan)
1481 void *chan;
1482{
1483 struct com_s *com;
1484 int s;
1485
1486 com = (struct com_s *)chan;
1487
1488 /*
1489 * Clear TS_BUSY if low-level output is complete.
1490 * spl locking is sufficient because siointr1() does not set CS_BUSY.
1491 * If siointr1() clears CS_BUSY after we look at it, then we'll get
1492 * called again. Reading the line status port outside of siointr1()
1493 * is safe because CS_BUSY is clear so there are no output interrupts
1494 * to lose.
1495 */
1496 s = spltty();
1497 if (com->state & CS_BUSY)
1498 com->extra_state &= ~CSE_BUSYCHECK; /* False alarm. */
1499 else if ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY))
1500 == (LSR_TSRE | LSR_TXRDY)) {
1501 com->tp->t_state &= ~TS_BUSY;
1502 ttwwakeup(com->tp);
1503 com->extra_state &= ~CSE_BUSYCHECK;
1504 } else
1505 timeout(siobusycheck, com, hz / 100);
1506 splx(s);
1507}
1508
1509static u_int
1510siodivisor(rclk, speed)
1511 u_long rclk;
1512 speed_t speed;
1513{
1514 long actual_speed;
1515 u_int divisor;
1516 int error;
1517
1518 if (speed == 0 || speed > (ULONG_MAX - 1) / 8)
1519 return (0);
1520 divisor = (rclk / (8UL * speed) + 1) / 2;
1521 if (divisor == 0 || divisor >= 65536)
1522 return (0);
1523 actual_speed = rclk / (16UL * divisor);
1524
1525 /* 10 times error in percent: */
1526 error = ((actual_speed - (long)speed) * 2000 / (long)speed + 1) / 2;
1527
1528 /* 3.0% maximum error tolerance: */
1529 if (error < -30 || error > 30)
1530 return (0);
1531
1532 return (divisor);
1533}
1534
1535static void
1536siodtrwakeup(chan)
1537 void *chan;
1538{
1539 struct com_s *com;
1540
1541 com = (struct com_s *)chan;
1542 com->state &= ~CS_DTR_OFF;
1543 wakeup(&com->dtr_wait);
1544}
1545
1546/*
1547 * Call this function with the sio_lock mutex held. It will return with the
1548 * lock still held.
1549 */
1550static void
1551sioinput(com)
1552 struct com_s *com;
1553{
1554 u_char *buf;
1555 int incc;
1556 u_char line_status;
1557 int recv_data;
1558 struct tty *tp;
1559
1560 buf = com->ibuf;
1561 tp = com->tp;
1562 if (!(tp->t_state & TS_ISOPEN) || !(tp->t_cflag & CREAD)) {
1563 com_events -= (com->iptr - com->ibuf);
1564 com->iptr = com->ibuf;
1565 return;
1566 }
1567 if (tp->t_state & TS_CAN_BYPASS_L_RINT) {
1568 /*
1569 * Avoid the grotesquely inefficient lineswitch routine
1570 * (ttyinput) in "raw" mode. It usually takes about 450
1571 * instructions (that's without canonical processing or echo!).
1572 * slinput is reasonably fast (usually 40 instructions plus
1573 * call overhead).
1574 */
1575 do {
1576 /*
1577 * This may look odd, but it is using save-and-enable
1578 * semantics instead of the save-and-disable semantics
1579 * that are used everywhere else.
1580 */
1581 mtx_unlock_spin(&sio_lock);
1582 incc = com->iptr - buf;
1583 if (tp->t_rawq.c_cc + incc > tp->t_ihiwat
1584 && (com->state & CS_RTS_IFLOW
1585 || tp->t_iflag & IXOFF)
1586 && !(tp->t_state & TS_TBLOCK))
1587 ttyblock(tp);
1588 com->delta_error_counts[CE_TTY_BUF_OVERFLOW]
1589 += b_to_q((char *)buf, incc, &tp->t_rawq);
1590 buf += incc;
1591 tk_nin += incc;
1592 tk_rawcc += incc;
1593 tp->t_rawcc += incc;
1594 ttwakeup(tp);
1595 if (tp->t_state & TS_TTSTOP
1596 && (tp->t_iflag & IXANY
1597 || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) {
1598 tp->t_state &= ~TS_TTSTOP;
1599 tp->t_lflag &= ~FLUSHO;
1600 comstart(tp);
1601 }
1602 mtx_lock_spin(&sio_lock);
1603 } while (buf < com->iptr);
1604 } else {
1605 do {
1606 /*
1607 * This may look odd, but it is using save-and-enable
1608 * semantics instead of the save-and-disable semantics
1609 * that are used everywhere else.
1610 */
1611 mtx_unlock_spin(&sio_lock);
1612 line_status = buf[com->ierroff];
1613 recv_data = *buf++;
1614 if (line_status
1615 & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) {
1616 if (line_status & LSR_BI)
1617 recv_data |= TTY_BI;
1618 if (line_status & LSR_FE)
1619 recv_data |= TTY_FE;
1620 if (line_status & LSR_OE)
1621 recv_data |= TTY_OE;
1622 if (line_status & LSR_PE)
1623 recv_data |= TTY_PE;
1624 }
1625 (*linesw[tp->t_line].l_rint)(recv_data, tp);
1626 mtx_lock_spin(&sio_lock);
1627 } while (buf < com->iptr);
1628 }
1629 com_events -= (com->iptr - com->ibuf);
1630 com->iptr = com->ibuf;
1631
1632 /*
1633 * There is now room for another low-level buffer full of input,
1634 * so enable RTS if it is now disabled and there is room in the
1635 * high-level buffer.
1636 */
1637 if ((com->state & CS_RTS_IFLOW) && !(com->mcr_image & MCR_RTS) &&
1638 !(tp->t_state & TS_TBLOCK))
1639 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
1640}
1641
1642static void
1643siointr(arg)
1644 void *arg;
1645{
1646 struct com_s *com;
1647
1648#ifndef COM_MULTIPORT
1649 com = (struct com_s *)arg;
1650
1651 mtx_lock_spin(&sio_lock);
1652 siointr1(com);
1653 mtx_unlock_spin(&sio_lock);
1654#else /* COM_MULTIPORT */
1655 bool_t possibly_more_intrs;
1656 int unit;
1657
1658 /*
1659 * Loop until there is no activity on any port. This is necessary
1660 * to get an interrupt edge more than to avoid another interrupt.
1661 * If the IRQ signal is just an OR of the IRQ signals from several
1662 * devices, then the edge from one may be lost because another is
1663 * on.
1664 */
1665 mtx_lock_spin(&sio_lock);
1666 do {
1667 possibly_more_intrs = FALSE;
1668 for (unit = 0; unit < sio_numunits; ++unit) {
1669 com = com_addr(unit);
1670 /*
1671 * XXX COM_LOCK();
1672 * would it work here, or be counter-productive?
1673 */
1674 if (com != NULL
1675 && !com->gone
1676 && (inb(com->int_id_port) & IIR_IMASK)
1677 != IIR_NOPEND) {
1678 siointr1(com);
1679 possibly_more_intrs = TRUE;
1680 }
1681 /* XXX COM_UNLOCK(); */
1682 }
1683 } while (possibly_more_intrs);
1684 mtx_unlock_spin(&sio_lock);
1685#endif /* COM_MULTIPORT */
1686}
1687
1688static struct timespec siots[8192];
1689static int siotso;
1690static int volatile siotsunit = -1;
1691
1692static int
1693sysctl_siots(SYSCTL_HANDLER_ARGS)
1694{
1695 char buf[128];
1696 long long delta;
1697 size_t len;
1698 int error, i;
1699
1700 for (i = 1; i < siotso; i++) {
1701 delta = (long long)(siots[i].tv_sec - siots[i - 1].tv_sec) *
1702 1000000000 +
1703 (siots[i].tv_nsec - siots[i - 1].tv_nsec);
1704 len = sprintf(buf, "%lld\n", delta);
1705 if (delta >= 110000)
1706 len += sprintf(buf + len - 1, ": *** %ld.%09ld\n",
1707 (long)siots[i].tv_sec, siots[i].tv_nsec);
1708 if (i == siotso - 1)
1709 buf[len - 1] = '\0';
1710 error = SYSCTL_OUT(req, buf, len);
1711 if (error != 0)
1712 return (error);
1713 uio_yield();
1714 }
1715 return (0);
1716}
1717
1718SYSCTL_PROC(_machdep, OID_AUTO, siots, CTLTYPE_STRING | CTLFLAG_RD,
1719 0, 0, sysctl_siots, "A", "sio timestamps");
1720
1721static void
1722siointr1(com)
1723 struct com_s *com;
1724{
1725 u_char line_status;
1726 u_char modem_status;
1727 u_char *ioptr;
1728 u_char recv_data;
1729 u_char int_ctl;
1730 u_char int_ctl_new;
1731
1732 int_ctl = inb(com->intr_ctl_port);
1733 int_ctl_new = int_ctl;
1734
1735 while (!com->gone) {
1736 if (com->pps.ppsparam.mode & PPS_CAPTUREBOTH) {
1737 modem_status = inb(com->modem_status_port);
1738 if ((modem_status ^ com->last_modem_status) &
1739 com->pps_bit) {
1740 pps_capture(&com->pps);
1741 pps_event(&com->pps,
1742 (modem_status & com->pps_bit) ?
1743 PPS_CAPTUREASSERT : PPS_CAPTURECLEAR);
1744 }
1745 }
1746 line_status = inb(com->line_status_port);
1747
1748 /* input event? (check first to help avoid overruns) */
1749 while (line_status & LSR_RCV_MASK) {
1750 /* break/unnattached error bits or real input? */
1751 if (!(line_status & LSR_RXRDY))
1752 recv_data = 0;
1753 else
1754 recv_data = inb(com->data_port);
1755#if defined(DDB) && defined(ALT_BREAK_TO_DEBUGGER)
1756 /*
1757 * Solaris implements a new BREAK which is initiated
1758 * by a character sequence CR ~ ^b which is similar
1759 * to a familiar pattern used on Sun servers by the
1760 * Remote Console.
1761 */
1762#define KEY_CRTLB 2 /* ^B */
1763#define KEY_CR 13 /* CR '\r' */
1764#define KEY_TILDE 126 /* ~ */
1765
1766 if (com->unit == comconsole) {
1767 static int brk_state1 = 0, brk_state2 = 0;
1768 if (recv_data == KEY_CR) {
1769 brk_state1 = recv_data;
1770 brk_state2 = 0;
1771 } else if (brk_state1 == KEY_CR
1772 && (recv_data == KEY_TILDE
1773 || recv_data == KEY_CRTLB)) {
1774 if (recv_data == KEY_TILDE)
1775 brk_state2 = recv_data;
1776 else if (brk_state2 == KEY_TILDE
1777 && recv_data == KEY_CRTLB) {
1778 breakpoint();
1779 brk_state1 = 0;
1780 brk_state2 = 0;
1781 goto cont;
1782 } else
1783 brk_state2 = 0;
1784 } else
1785 brk_state1 = 0;
1786 }
1787#endif
1788 if (line_status & (LSR_BI | LSR_FE | LSR_PE)) {
1789 /*
1790 * Don't store BI if IGNBRK or FE/PE if IGNPAR.
1791 * Otherwise, push the work to a higher level
1792 * (to handle PARMRK) if we're bypassing.
1793 * Otherwise, convert BI/FE and PE+INPCK to 0.
1794 *
1795 * This makes bypassing work right in the
1796 * usual "raw" case (IGNBRK set, and IGNPAR
1797 * and INPCK clear).
1798 *
1799 * Note: BI together with FE/PE means just BI.
1800 */
1801 if (line_status & LSR_BI) {
1802#if defined(DDB) && defined(BREAK_TO_DEBUGGER)
1803 if (com->unit == comconsole) {
1804 breakpoint();
1805 goto cont;
1806 }
1807#endif
1808 if (com->tp == NULL
1809 || com->tp->t_iflag & IGNBRK)
1810 goto cont;
1811 } else {
1812 if (com->tp == NULL
1813 || com->tp->t_iflag & IGNPAR)
1814 goto cont;
1815 }
1816 if (com->tp->t_state & TS_CAN_BYPASS_L_RINT
1817 && (line_status & (LSR_BI | LSR_FE)
1818 || com->tp->t_iflag & INPCK))
1819 recv_data = 0;
1820 }
1821 ++com->bytes_in;
1822 if (com->hotchar != 0 && recv_data == com->hotchar)
1823 swi_sched(sio_fast_ih, 0);
1824 ioptr = com->iptr;
1825 if (ioptr >= com->ibufend)
1826 CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW);
1827 else {
1828 if (com->do_timestamp)
1829 microtime(&com->timestamp);
1830 ++com_events;
1831 swi_sched(sio_slow_ih, SWI_DELAY);
1832#if 0 /* for testing input latency vs efficiency */
1833if (com->iptr - com->ibuf == 8)
1834 swi_sched(sio_fast_ih, 0);
1835#endif
1836 ioptr[0] = recv_data;
1837 ioptr[com->ierroff] = line_status;
1838 com->iptr = ++ioptr;
1839 if (ioptr == com->ihighwater
1840 && com->state & CS_RTS_IFLOW)
1841 outb(com->modem_ctl_port,
1842 com->mcr_image &= ~MCR_RTS);
1843 if (line_status & LSR_OE)
1844 CE_RECORD(com, CE_OVERRUN);
1845 }
1846cont:
1847 /*
1848 * "& 0x7F" is to avoid the gcc-1.40 generating a slow
1849 * jump from the top of the loop to here
1850 */
1851 line_status = inb(com->line_status_port) & 0x7F;
1852 }
1853
1854 /* modem status change? (always check before doing output) */
1855 modem_status = inb(com->modem_status_port);
1856 if (modem_status != com->last_modem_status) {
1857 if (com->do_dcd_timestamp
1858 && !(com->last_modem_status & MSR_DCD)
1859 && modem_status & MSR_DCD)
1860 microtime(&com->dcd_timestamp);
1861
1862 /*
1863 * Schedule high level to handle DCD changes. Note
1864 * that we don't use the delta bits anywhere. Some
1865 * UARTs mess them up, and it's easy to remember the
1866 * previous bits and calculate the delta.
1867 */
1868 com->last_modem_status = modem_status;
1869 if (!(com->state & CS_CHECKMSR)) {
1870 com_events += LOTS_OF_EVENTS;
1871 com->state |= CS_CHECKMSR;
1872 swi_sched(sio_fast_ih, 0);
1873 }
1874
1875 /* handle CTS change immediately for crisp flow ctl */
1876 if (com->state & CS_CTS_OFLOW) {
1877 if (modem_status & MSR_CTS)
1878 com->state |= CS_ODEVREADY;
1879 else
1880 com->state &= ~CS_ODEVREADY;
1881 }
1882 }
1883
1884 /* output queued and everything ready? */
1885 if (line_status & LSR_TXRDY
1886 && com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
1887 ioptr = com->obufq.l_head;
1888 if (com->tx_fifo_size > 1 && com->unit != siotsunit) {
1889 u_int ocount;
1890
1891 ocount = com->obufq.l_tail - ioptr;
1892 if (ocount > com->tx_fifo_size)
1893 ocount = com->tx_fifo_size;
1894 com->bytes_out += ocount;
1895 do
1896 outb(com->data_port, *ioptr++);
1897 while (--ocount != 0);
1898 } else {
1899 outb(com->data_port, *ioptr++);
1900 ++com->bytes_out;
1901 if (com->unit == siotsunit) {
1902 nanouptime(&siots[siotso]);
1903 siotso = (siotso + 1) %
1904 (sizeof siots / sizeof siots[0]);
1905 }
1906 }
1907 com->obufq.l_head = ioptr;
1908 if (COM_IIR_TXRDYBUG(com->flags)) {
1909 int_ctl_new = int_ctl | IER_ETXRDY;
1910 }
1911 if (ioptr >= com->obufq.l_tail) {
1912 struct lbq *qp;
1913
1914 qp = com->obufq.l_next;
1915 qp->l_queued = FALSE;
1916 qp = qp->l_next;
1917 if (qp != NULL) {
1918 com->obufq.l_head = qp->l_head;
1919 com->obufq.l_tail = qp->l_tail;
1920 com->obufq.l_next = qp;
1921 } else {
1922 /* output just completed */
1923 if (COM_IIR_TXRDYBUG(com->flags)) {
1924 int_ctl_new = int_ctl & ~IER_ETXRDY;
1925 }
1926 com->state &= ~CS_BUSY;
1927 }
1928 if (!(com->state & CS_ODONE)) {
1929 com_events += LOTS_OF_EVENTS;
1930 com->state |= CS_ODONE;
1931 /* handle at high level ASAP */
1932 swi_sched(sio_fast_ih, 0);
1933 }
1934 }
1935 if (COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) {
1936 outb(com->intr_ctl_port, int_ctl_new);
1937 }
1938 }
1939
1940 /* finished? */
1941#ifndef COM_MULTIPORT
1942 if ((inb(com->int_id_port) & IIR_IMASK) == IIR_NOPEND)
1943#endif /* COM_MULTIPORT */
1944 return;
1945 }
1946}
1947
1948static int
1949sioioctl(dev, cmd, data, flag, td)
1950 dev_t dev;
1951 u_long cmd;
1952 caddr_t data;
1953 int flag;
1954 struct thread *td;
1955{
1956 struct com_s *com;
1957 int error;
1958 int mynor;
1959 int s;
1960 struct tty *tp;
1961#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1962 u_long oldcmd;
1963 struct termios term;
1964#endif
1965
1966 mynor = minor(dev);
1967 com = com_addr(MINOR_TO_UNIT(mynor));
1968 if (com == NULL || com->gone)
1969 return (ENODEV);
1970 if (mynor & CONTROL_MASK) {
1971 struct termios *ct;
1972
1973 switch (mynor & CONTROL_MASK) {
1974 case CONTROL_INIT_STATE:
1975 ct = mynor & CALLOUT_MASK ? &com->it_out : &com->it_in;
1976 break;
1977 case CONTROL_LOCK_STATE:
1978 ct = mynor & CALLOUT_MASK ? &com->lt_out : &com->lt_in;
1979 break;
1980 default:
1981 return (ENODEV); /* /dev/nodev */
1982 }
1983 switch (cmd) {
1984 case TIOCSETA:
1985 error = suser(td);
1986 if (error != 0)
1987 return (error);
1988 *ct = *(struct termios *)data;
1989 return (0);
1990 case TIOCGETA:
1991 *(struct termios *)data = *ct;
1992 return (0);
1993 case TIOCGETD:
1994 *(int *)data = TTYDISC;
1995 return (0);
1996 case TIOCGWINSZ:
1997 bzero(data, sizeof(struct winsize));
1998 return (0);
1999 default:
2000 return (ENOTTY);
2001 }
2002 }
2003 tp = com->tp;
2004#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
2005 term = tp->t_termios;
2006 oldcmd = cmd;
2007 error = ttsetcompat(tp, &cmd, data, &term);
2008 if (error != 0)
2009 return (error);
2010 if (cmd != oldcmd)
2011 data = (caddr_t)&term;
2012#endif
2013 if (cmd == TIOCSETA || cmd == TIOCSETAW || cmd == TIOCSETAF) {
2014 int cc;
2015 struct termios *dt = (struct termios *)data;
2016 struct termios *lt = mynor & CALLOUT_MASK
2017 ? &com->lt_out : &com->lt_in;
2018
2019 dt->c_iflag = (tp->t_iflag & lt->c_iflag)
2020 | (dt->c_iflag & ~lt->c_iflag);
2021 dt->c_oflag = (tp->t_oflag & lt->c_oflag)
2022 | (dt->c_oflag & ~lt->c_oflag);
2023 dt->c_cflag = (tp->t_cflag & lt->c_cflag)
2024 | (dt->c_cflag & ~lt->c_cflag);
2025 dt->c_lflag = (tp->t_lflag & lt->c_lflag)
2026 | (dt->c_lflag & ~lt->c_lflag);
2027 for (cc = 0; cc < NCCS; ++cc)
2028 if (lt->c_cc[cc] != 0)
2029 dt->c_cc[cc] = tp->t_cc[cc];
2030 if (lt->c_ispeed != 0)
2031 dt->c_ispeed = tp->t_ispeed;
2032 if (lt->c_ospeed != 0)
2033 dt->c_ospeed = tp->t_ospeed;
2034 }
2035 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, td);
2036 if (error != ENOIOCTL)
2037 return (error);
2038 s = spltty();
2039 error = ttioctl(tp, cmd, data, flag);
2040 disc_optim(tp, &tp->t_termios, com);
2041 if (error != ENOIOCTL) {
2042 splx(s);
2043 return (error);
2044 }
2045 switch (cmd) {
2046 case TIOCSBRK:
2047 sio_setreg(com, com_cfcr, com->cfcr_image |= CFCR_SBREAK);
2048 break;
2049 case TIOCCBRK:
2050 sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
2051 break;
2052 case TIOCSDTR:
2053 (void)commctl(com, TIOCM_DTR, DMBIS);
2054 break;
2055 case TIOCCDTR:
2056 (void)commctl(com, TIOCM_DTR, DMBIC);
2057 break;
2058 /*
2059 * XXX should disallow changing MCR_RTS if CS_RTS_IFLOW is set. The
2060 * changes get undone on the next call to comparam().
2061 */
2062 case TIOCMSET:
2063 (void)commctl(com, *(int *)data, DMSET);
2064 break;
2065 case TIOCMBIS:
2066 (void)commctl(com, *(int *)data, DMBIS);
2067 break;
2068 case TIOCMBIC:
2069 (void)commctl(com, *(int *)data, DMBIC);
2070 break;
2071 case TIOCMGET:
2072 *(int *)data = commctl(com, 0, DMGET);
2073 break;
2074 case TIOCMSDTRWAIT:
2075 /* must be root since the wait applies to following logins */
2076 error = suser(td);
2077 if (error != 0) {
2078 splx(s);
2079 return (error);
2080 }
2081 com->dtr_wait = *(int *)data * hz / 100;
2082 break;
2083 case TIOCMGDTRWAIT:
2084 *(int *)data = com->dtr_wait * 100 / hz;
2085 break;
2086 case TIOCTIMESTAMP:
2087 com->do_timestamp = TRUE;
2088 *(struct timeval *)data = com->timestamp;
2089 break;
2090 case TIOCDCDTIMESTAMP:
2091 com->do_dcd_timestamp = TRUE;
2092 *(struct timeval *)data = com->dcd_timestamp;
2093 break;
2094 default:
2095 splx(s);
2096 error = pps_ioctl(cmd, data, &com->pps);
2097 if (error == ENODEV)
2098 error = ENOTTY;
2099 return (error);
2100 }
2101 splx(s);
2102 return (0);
2103}
2104
2105/* software interrupt handler for SWI_TTY */
2106static void
2107siopoll(void *dummy)
2108{
2109 int unit;
2110
2111 if (com_events == 0)
2112 return;
2113repeat:
2114 for (unit = 0; unit < sio_numunits; ++unit) {
2115 struct com_s *com;
2116 int incc;
2117 struct tty *tp;
2118
2119 com = com_addr(unit);
2120 if (com == NULL)
2121 continue;
2122 tp = com->tp;
2123 if (tp == NULL || com->gone) {
2124 /*
2125 * Discard any events related to never-opened or
2126 * going-away devices.
2127 */
2128 mtx_lock_spin(&sio_lock);
2129 incc = com->iptr - com->ibuf;
2130 com->iptr = com->ibuf;
2131 if (com->state & CS_CHECKMSR) {
2132 incc += LOTS_OF_EVENTS;
2133 com->state &= ~CS_CHECKMSR;
2134 }
2135 com_events -= incc;
2136 mtx_unlock_spin(&sio_lock);
2137 continue;
2138 }
2139 if (com->iptr != com->ibuf) {
2140 mtx_lock_spin(&sio_lock);
2141 sioinput(com);
2142 mtx_unlock_spin(&sio_lock);
2143 }
2144 if (com->state & CS_CHECKMSR) {
2145 u_char delta_modem_status;
2146
2147 mtx_lock_spin(&sio_lock);
2148 delta_modem_status = com->last_modem_status
2149 ^ com->prev_modem_status;
2150 com->prev_modem_status = com->last_modem_status;
2151 com_events -= LOTS_OF_EVENTS;
2152 com->state &= ~CS_CHECKMSR;
2153 mtx_unlock_spin(&sio_lock);
2154 if (delta_modem_status & MSR_DCD)
2155 (*linesw[tp->t_line].l_modem)
2156 (tp, com->prev_modem_status & MSR_DCD);
2157 }
2158 if (com->state & CS_ODONE) {
2159 mtx_lock_spin(&sio_lock);
2160 com_events -= LOTS_OF_EVENTS;
2161 com->state &= ~CS_ODONE;
2162 mtx_unlock_spin(&sio_lock);
2163 if (!(com->state & CS_BUSY)
2164 && !(com->extra_state & CSE_BUSYCHECK)) {
2165 timeout(siobusycheck, com, hz / 100);
2166 com->extra_state |= CSE_BUSYCHECK;
2167 }
2168 (*linesw[tp->t_line].l_start)(tp);
2169 }
2170 if (com_events == 0)
2171 break;
2172 }
2173 if (com_events >= LOTS_OF_EVENTS)
2174 goto repeat;
2175}
2176
2177static int
2178comparam(tp, t)
2179 struct tty *tp;
2180 struct termios *t;
2181{
2182 u_int cfcr;
2183 int cflag;
2184 struct com_s *com;
2185 u_int divisor;
2186 u_char dlbh;
2187 u_char dlbl;
2188 int s;
2189 int unit;
2190
2191 unit = DEV_TO_UNIT(tp->t_dev);
2192 com = com_addr(unit);
2193 if (com == NULL)
2194 return (ENODEV);
2195
2196 /* do historical conversions */
2197 if (t->c_ispeed == 0)
2198 t->c_ispeed = t->c_ospeed;
2199
2200 /* check requested parameters */
2201 if (t->c_ospeed == 0)
2202 divisor = 0;
2203 else {
2204 if (t->c_ispeed != t->c_ospeed)
2205 return (EINVAL);
2206 divisor = siodivisor(com->rclk, t->c_ispeed);
2207 if (divisor == 0)
2208 return (EINVAL);
2209 }
2210
2211 /* parameters are OK, convert them to the com struct and the device */
2212 s = spltty();
2213 if (divisor == 0)
2214 (void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */
2215 else
2216 (void)commctl(com, TIOCM_DTR, DMBIS);
2217 cflag = t->c_cflag;
2218 switch (cflag & CSIZE) {
2219 case CS5:
2220 cfcr = CFCR_5BITS;
2221 break;
2222 case CS6:
2223 cfcr = CFCR_6BITS;
2224 break;
2225 case CS7:
2226 cfcr = CFCR_7BITS;
2227 break;
2228 default:
2229 cfcr = CFCR_8BITS;
2230 break;
2231 }
2232 if (cflag & PARENB) {
2233 cfcr |= CFCR_PENAB;
2234 if (!(cflag & PARODD))
2235 cfcr |= CFCR_PEVEN;
2236 }
2237 if (cflag & CSTOPB)
2238 cfcr |= CFCR_STOPB;
2239
2240 if (com->hasfifo && divisor != 0) {
2241 /*
2242 * Use a fifo trigger level low enough so that the input
2243 * latency from the fifo is less than about 16 msec and
2244 * the total latency is less than about 30 msec. These
2245 * latencies are reasonable for humans. Serial comms
2246 * protocols shouldn't expect anything better since modem
2247 * latencies are larger.
2248 *
2249 * The fifo trigger level cannot be set at RX_HIGH for high
2250 * speed connections without further work on reducing
2251 * interrupt disablement times in other parts of the system,
2252 * without producing silo overflow errors.
2253 */
2254 com->fifo_image = com->unit == siotsunit ? 0
2255 : t->c_ospeed <= 4800
2256 ? FIFO_ENABLE : FIFO_ENABLE | FIFO_RX_MEDH;
2257#ifdef COM_ESP
2258 /*
2259 * The Hayes ESP card needs the fifo DMA mode bit set
2260 * in compatibility mode. If not, it will interrupt
2261 * for each character received.
2262 */
2263 if (com->esp)
2264 com->fifo_image |= FIFO_DMA_MODE;
2265#endif
2266 sio_setreg(com, com_fifo, com->fifo_image);
2267 }
2268
2269 /*
2270 * This returns with interrupts disabled so that we can complete
2271 * the speed change atomically. Keeping interrupts disabled is
2272 * especially important while com_data is hidden.
2273 */
2274 (void) siosetwater(com, t->c_ispeed);
2275
2276 if (divisor != 0) {
2277 sio_setreg(com, com_cfcr, cfcr | CFCR_DLAB);
2278 /*
2279 * Only set the divisor registers if they would change,
2280 * since on some 16550 incompatibles (UMC8669F), setting
2281 * them while input is arriving them loses sync until
2282 * data stops arriving.
2283 */
2284 dlbl = divisor & 0xFF;
2285 if (sio_getreg(com, com_dlbl) != dlbl)
2286 sio_setreg(com, com_dlbl, dlbl);
2287 dlbh = divisor >> 8;
2288 if (sio_getreg(com, com_dlbh) != dlbh)
2289 sio_setreg(com, com_dlbh, dlbh);
2290 }
2291
2292 sio_setreg(com, com_cfcr, com->cfcr_image = cfcr);
2293
2294 if (!(tp->t_state & TS_TTSTOP))
2295 com->state |= CS_TTGO;
2296
2297 if (cflag & CRTS_IFLOW) {
2298 if (com->st16650a) {
2299 sio_setreg(com, com_cfcr, 0xbf);
2300 sio_setreg(com, com_fifo,
2301 sio_getreg(com, com_fifo) | 0x40);
2302 }
2303 com->state |= CS_RTS_IFLOW;
2304 /*
2305 * If CS_RTS_IFLOW just changed from off to on, the change
2306 * needs to be propagated to MCR_RTS. This isn't urgent,
2307 * so do it later by calling comstart() instead of repeating
2308 * a lot of code from comstart() here.
2309 */
2310 } else if (com->state & CS_RTS_IFLOW) {
2311 com->state &= ~CS_RTS_IFLOW;
2312 /*
2313 * CS_RTS_IFLOW just changed from on to off. Force MCR_RTS
2314 * on here, since comstart() won't do it later.
2315 */
2316 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
2317 if (com->st16650a) {
2318 sio_setreg(com, com_cfcr, 0xbf);
2319 sio_setreg(com, com_fifo,
2320 sio_getreg(com, com_fifo) & ~0x40);
2321 }
2322 }
2323
2324
2325 /*
2326 * Set up state to handle output flow control.
2327 * XXX - worth handling MDMBUF (DCD) flow control at the lowest level?
2328 * Now has 10+ msec latency, while CTS flow has 50- usec latency.
2329 */
2330 com->state |= CS_ODEVREADY;
2331 com->state &= ~CS_CTS_OFLOW;
2332 if (cflag & CCTS_OFLOW) {
2333 com->state |= CS_CTS_OFLOW;
2334 if (!(com->last_modem_status & MSR_CTS))
2335 com->state &= ~CS_ODEVREADY;
2336 if (com->st16650a) {
2337 sio_setreg(com, com_cfcr, 0xbf);
2338 sio_setreg(com, com_fifo,
2339 sio_getreg(com, com_fifo) | 0x80);
2340 }
2341 } else {
2342 if (com->st16650a) {
2343 sio_setreg(com, com_cfcr, 0xbf);
2344 sio_setreg(com, com_fifo,
2345 sio_getreg(com, com_fifo) & ~0x80);
2346 }
2347 }
2348
2349 sio_setreg(com, com_cfcr, com->cfcr_image);
2350
2351 /* XXX shouldn't call functions while intrs are disabled. */
2352 disc_optim(tp, t, com);
2353 /*
2354 * Recover from fiddling with CS_TTGO. We used to call siointr1()
2355 * unconditionally, but that defeated the careful discarding of
2356 * stale input in sioopen().
2357 */
2358 if (com->state >= (CS_BUSY | CS_TTGO))
2359 siointr1(com);
2360
2361 mtx_unlock_spin(&sio_lock);
2362 splx(s);
2363 comstart(tp);
2364 if (com->ibufold != NULL) {
2365 free(com->ibufold, M_DEVBUF);
2366 com->ibufold = NULL;
2367 }
2368 return (0);
2369}
2370
2371/*
2372 * This function must be called with the sio_lock mutex released and will
2373 * return with it obtained.
2374 */
2375static int
2376siosetwater(com, speed)
2377 struct com_s *com;
2378 speed_t speed;
2379{
2380 int cp4ticks;
2381 u_char *ibuf;
2382 int ibufsize;
2383 struct tty *tp;
2384
2385 /*
2386 * Make the buffer size large enough to handle a softtty interrupt
2387 * latency of about 2 ticks without loss of throughput or data
2388 * (about 3 ticks if input flow control is not used or not honoured,
2389 * but a bit less for CS5-CS7 modes).
2390 */
2391 cp4ticks = speed / 10 / hz * 4;
2392 for (ibufsize = 128; ibufsize < cp4ticks;)
2393 ibufsize <<= 1;
2394 if (ibufsize == com->ibufsize) {
2395 mtx_lock_spin(&sio_lock);
2396 return (0);
2397 }
2398
2399 /*
2400 * Allocate input buffer. The extra factor of 2 in the size is
2401 * to allow for an error byte for each input byte.
2402 */
2403 ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT);
2404 if (ibuf == NULL) {
2405 mtx_lock_spin(&sio_lock);
2406 return (ENOMEM);
2407 }
2408
2409 /* Initialize non-critical variables. */
2410 com->ibufold = com->ibuf;
2411 com->ibufsize = ibufsize;
2412 tp = com->tp;
2413 if (tp != NULL) {
2414 tp->t_ififosize = 2 * ibufsize;
2415 tp->t_ispeedwat = (speed_t)-1;
2416 tp->t_ospeedwat = (speed_t)-1;
2417 }
2418
2419 /*
2420 * Read current input buffer, if any. Continue with interrupts
2421 * disabled.
2422 */
2423 mtx_lock_spin(&sio_lock);
2424 if (com->iptr != com->ibuf)
2425 sioinput(com);
2426
2427 /*-
2428 * Initialize critical variables, including input buffer watermarks.
2429 * The external device is asked to stop sending when the buffer
2430 * exactly reaches high water, or when the high level requests it.
2431 * The high level is notified immediately (rather than at a later
2432 * clock tick) when this watermark is reached.
2433 * The buffer size is chosen so the watermark should almost never
2434 * be reached.
2435 * The low watermark is invisibly 0 since the buffer is always
2436 * emptied all at once.
2437 */
2438 com->iptr = com->ibuf = ibuf;
2439 com->ibufend = ibuf + ibufsize;
2440 com->ierroff = ibufsize;
2441 com->ihighwater = ibuf + 3 * ibufsize / 4;
2442 return (0);
2443}
2444
2445static void
2446comstart(tp)
2447 struct tty *tp;
2448{
2449 struct com_s *com;
2450 int s;
2451 int unit;
2452
2453 unit = DEV_TO_UNIT(tp->t_dev);
2454 com = com_addr(unit);
2455 if (com == NULL)
2456 return;
2457 s = spltty();
2458 mtx_lock_spin(&sio_lock);
2459 if (tp->t_state & TS_TTSTOP)
2460 com->state &= ~CS_TTGO;
2461 else
2462 com->state |= CS_TTGO;
2463 if (tp->t_state & TS_TBLOCK) {
2464 if (com->mcr_image & MCR_RTS && com->state & CS_RTS_IFLOW)
2465 outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS);
2466 } else {
2467 if (!(com->mcr_image & MCR_RTS) && com->iptr < com->ihighwater
2468 && com->state & CS_RTS_IFLOW)
2469 outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
2470 }
2471 mtx_unlock_spin(&sio_lock);
2472 if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) {
2473 ttwwakeup(tp);
2474 splx(s);
2475 return;
2476 }
2477 if (tp->t_outq.c_cc != 0) {
2478 struct lbq *qp;
2479 struct lbq *next;
2480
2481 if (!com->obufs[0].l_queued) {
2482 com->obufs[0].l_tail
2483 = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1,
2484 sizeof com->obuf1);
2485 com->obufs[0].l_next = NULL;
2486 com->obufs[0].l_queued = TRUE;
2487 mtx_lock_spin(&sio_lock);
2488 if (com->state & CS_BUSY) {
2489 qp = com->obufq.l_next;
2490 while ((next = qp->l_next) != NULL)
2491 qp = next;
2492 qp->l_next = &com->obufs[0];
2493 } else {
2494 com->obufq.l_head = com->obufs[0].l_head;
2495 com->obufq.l_tail = com->obufs[0].l_tail;
2496 com->obufq.l_next = &com->obufs[0];
2497 com->state |= CS_BUSY;
2498 }
2499 mtx_unlock_spin(&sio_lock);
2500 }
2501 if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) {
2502 com->obufs[1].l_tail
2503 = com->obuf2 + q_to_b(&tp->t_outq, com->obuf2,
2504 sizeof com->obuf2);
2505 com->obufs[1].l_next = NULL;
2506 com->obufs[1].l_queued = TRUE;
2507 mtx_lock_spin(&sio_lock);
2508 if (com->state & CS_BUSY) {
2509 qp = com->obufq.l_next;
2510 while ((next = qp->l_next) != NULL)
2511 qp = next;
2512 qp->l_next = &com->obufs[1];
2513 } else {
2514 com->obufq.l_head = com->obufs[1].l_head;
2515 com->obufq.l_tail = com->obufs[1].l_tail;
2516 com->obufq.l_next = &com->obufs[1];
2517 com->state |= CS_BUSY;
2518 }
2519 mtx_unlock_spin(&sio_lock);
2520 }
2521 tp->t_state |= TS_BUSY;
2522 }
2523 mtx_lock_spin(&sio_lock);
2524 if (com->state >= (CS_BUSY | CS_TTGO))
2525 siointr1(com); /* fake interrupt to start output */
2526 mtx_unlock_spin(&sio_lock);
2527 ttwwakeup(tp);
2528 splx(s);
2529}
2530
2531static void
2532comstop(tp, rw)
2533 struct tty *tp;
2534 int rw;
2535{
2536 struct com_s *com;
2537
2538 com = com_addr(DEV_TO_UNIT(tp->t_dev));
2539 if (com == NULL || com->gone)
2540 return;
2541 mtx_lock_spin(&sio_lock);
2542 if (rw & FWRITE) {
2543 if (com->hasfifo)
2544#ifdef COM_ESP
2545 /* XXX avoid h/w bug. */
2546 if (!com->esp)
2547#endif
2548 sio_setreg(com, com_fifo,
2549 FIFO_XMT_RST | com->fifo_image);
2550 com->obufs[0].l_queued = FALSE;
2551 com->obufs[1].l_queued = FALSE;
2552 if (com->state & CS_ODONE)
2553 com_events -= LOTS_OF_EVENTS;
2554 com->state &= ~(CS_ODONE | CS_BUSY);
2555 com->tp->t_state &= ~TS_BUSY;
2556 }
2557 if (rw & FREAD) {
2558 if (com->hasfifo)
2559#ifdef COM_ESP
2560 /* XXX avoid h/w bug. */
2561 if (!com->esp)
2562#endif
2563 sio_setreg(com, com_fifo,
2564 FIFO_RCV_RST | com->fifo_image);
2565 com_events -= (com->iptr - com->ibuf);
2566 com->iptr = com->ibuf;
2567 }
2568 mtx_unlock_spin(&sio_lock);
2569 comstart(tp);
2570}
2571
2572static int
2573commctl(com, bits, how)
2574 struct com_s *com;
2575 int bits;
2576 int how;
2577{
2578 int mcr;
2579 int msr;
2580
2581 if (how == DMGET) {
2582 bits = TIOCM_LE; /* XXX - always enabled while open */
2583 mcr = com->mcr_image;
2584 if (mcr & MCR_DTR)
2585 bits |= TIOCM_DTR;
2586 if (mcr & MCR_RTS)
2587 bits |= TIOCM_RTS;
2588 msr = com->prev_modem_status;
2589 if (msr & MSR_CTS)
2590 bits |= TIOCM_CTS;
2591 if (msr & MSR_DCD)
2592 bits |= TIOCM_CD;
2593 if (msr & MSR_DSR)
2594 bits |= TIOCM_DSR;
2595 /*
2596 * XXX - MSR_RI is naturally volatile, and we make MSR_TERI
2597 * more volatile by reading the modem status a lot. Perhaps
2598 * we should latch both bits until the status is read here.
2599 */
2600 if (msr & (MSR_RI | MSR_TERI))
2601 bits |= TIOCM_RI;
2602 return (bits);
2603 }
2604 mcr = 0;
2605 if (bits & TIOCM_DTR)
2606 mcr |= MCR_DTR;
2607 if (bits & TIOCM_RTS)
2608 mcr |= MCR_RTS;
2609 if (com->gone)
2610 return(0);
2611 mtx_lock_spin(&sio_lock);
2612 switch (how) {
2613 case DMSET:
2614 outb(com->modem_ctl_port,
2615 com->mcr_image = mcr | (com->mcr_image & MCR_IENABLE));
2616 break;
2617 case DMBIS:
2618 outb(com->modem_ctl_port, com->mcr_image |= mcr);
2619 break;
2620 case DMBIC:
2621 outb(com->modem_ctl_port, com->mcr_image &= ~mcr);
2622 break;
2623 }
2624 mtx_unlock_spin(&sio_lock);
2625 return (0);
2626}
2627
2628static void
2629siosettimeout()
2630{
2631 struct com_s *com;
2632 bool_t someopen;
2633 int unit;
2634
2635 /*
2636 * Set our timeout period to 1 second if no polled devices are open.
2637 * Otherwise set it to max(1/200, 1/hz).
2638 * Enable timeouts iff some device is open.
2639 */
2640 untimeout(comwakeup, (void *)NULL, sio_timeout_handle);
2641 sio_timeout = hz;
2642 someopen = FALSE;
2643 for (unit = 0; unit < sio_numunits; ++unit) {
2644 com = com_addr(unit);
2645 if (com != NULL && com->tp != NULL
2646 && com->tp->t_state & TS_ISOPEN && !com->gone) {
2647 someopen = TRUE;
2648 if (com->poll || com->poll_output) {
2649 sio_timeout = hz > 200 ? hz / 200 : 1;
2650 break;
2651 }
2652 }
2653 }
2654 if (someopen) {
2655 sio_timeouts_until_log = hz / sio_timeout;
2656 sio_timeout_handle = timeout(comwakeup, (void *)NULL,
2657 sio_timeout);
2658 } else {
2659 /* Flush error messages, if any. */
2660 sio_timeouts_until_log = 1;
2661 comwakeup((void *)NULL);
2662 untimeout(comwakeup, (void *)NULL, sio_timeout_handle);
2663 }
2664}
2665
2666static void
2667comwakeup(chan)
2668 void *chan;
2669{
2670 struct com_s *com;
2671 int unit;
2672
2673 sio_timeout_handle = timeout(comwakeup, (void *)NULL, sio_timeout);
2674
2675 /*
2676 * Recover from lost output interrupts.
2677 * Poll any lines that don't use interrupts.
2678 */
2679 for (unit = 0; unit < sio_numunits; ++unit) {
2680 com = com_addr(unit);
2681 if (com != NULL && !com->gone
2682 && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) {
2683 mtx_lock_spin(&sio_lock);
2684 siointr1(com);
2685 mtx_unlock_spin(&sio_lock);
2686 }
2687 }
2688
2689 /*
2690 * Check for and log errors, but not too often.
2691 */
2692 if (--sio_timeouts_until_log > 0)
2693 return;
2694 sio_timeouts_until_log = hz / sio_timeout;
2695 for (unit = 0; unit < sio_numunits; ++unit) {
2696 int errnum;
2697
2698 com = com_addr(unit);
2699 if (com == NULL)
2700 continue;
2701 if (com->gone)
2702 continue;
2703 for (errnum = 0; errnum < CE_NTYPES; ++errnum) {
2704 u_int delta;
2705 u_long total;
2706
2707 mtx_lock_spin(&sio_lock);
2708 delta = com->delta_error_counts[errnum];
2709 com->delta_error_counts[errnum] = 0;
2710 mtx_unlock_spin(&sio_lock);
2711 if (delta == 0)
2712 continue;
2713 total = com->error_counts[errnum] += delta;
2714 log(LOG_ERR, "sio%d: %u more %s%s (total %lu)\n",
2715 unit, delta, error_desc[errnum],
2716 delta == 1 ? "" : "s", total);
2717 }
2718 }
2719}
2720
2721static void
2722disc_optim(tp, t, com)
2723 struct tty *tp;
2724 struct termios *t;
2725 struct com_s *com;
2726{
2727 if (!(t->c_iflag & (ICRNL | IGNCR | IMAXBEL | INLCR | ISTRIP | IXON))
2728 && (!(t->c_iflag & BRKINT) || (t->c_iflag & IGNBRK))
2729 && (!(t->c_iflag & PARMRK)
2730 || (t->c_iflag & (IGNPAR | IGNBRK)) == (IGNPAR | IGNBRK))
2731 && !(t->c_lflag & (ECHO | ICANON | IEXTEN | ISIG | PENDIN))
2732 && linesw[tp->t_line].l_rint == ttyinput)
2733 tp->t_state |= TS_CAN_BYPASS_L_RINT;
2734 else
2735 tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
2736 com->hotchar = linesw[tp->t_line].l_hotchar;
2737}
2738
2739/*
2740 * Following are all routines needed for SIO to act as console
2741 */
2742#include <sys/cons.h>
2743
2744struct siocnstate {
2745 u_char dlbl;
2746 u_char dlbh;
2747 u_char ier;
2748 u_char cfcr;
2749 u_char mcr;
2750};
2751
2752#ifndef __alpha__
2753static speed_t siocngetspeed(Port_t, u_long rclk);
2754#endif
2755static void siocnclose(struct siocnstate *sp, Port_t iobase);
2756static void siocnopen(struct siocnstate *sp, Port_t iobase, int speed);
2757static void siocntxwait(Port_t iobase);
2758
2759#ifdef __alpha__
2760int siocnattach(int port, int speed);
2761int siogdbattach(int port, int speed);
2762int siogdbgetc(void);
2763void siogdbputc(int c);
2764#else
2765static cn_probe_t siocnprobe;
2766static cn_init_t siocninit;
2767static cn_term_t siocnterm;
2768#endif
2769static cn_checkc_t siocncheckc;
2770static cn_getc_t siocngetc;
2771static cn_putc_t siocnputc;
2772
2773#ifndef __alpha__
2774CONS_DRIVER(sio, siocnprobe, siocninit, siocnterm, siocngetc, siocncheckc,
2775 siocnputc, NULL);
2776#endif
2777
2778/* To get the GDB related variables */
2779#if DDB > 0
2780#include <ddb/ddb.h>
2781static struct consdev gdbconsdev;
2782
2783#endif
2784
2785static void
2786siocntxwait(iobase)
2787 Port_t iobase;
2788{
2789 int timo;
2790
2791 /*
2792 * Wait for any pending transmission to finish. Required to avoid
2793 * the UART lockup bug when the speed is changed, and for normal
2794 * transmits.
2795 */
2796 timo = 100000;
2797 while ((inb(iobase + com_lsr) & (LSR_TSRE | LSR_TXRDY))
2798 != (LSR_TSRE | LSR_TXRDY) && --timo != 0)
2799 ;
2800}
2801
2802#ifndef __alpha__
2803
2804/*
2805 * Read the serial port specified and try to figure out what speed
2806 * it's currently running at. We're assuming the serial port has
2807 * been initialized and is basicly idle. This routine is only intended
2808 * to be run at system startup.
2809 *
2810 * If the value read from the serial port doesn't make sense, return 0.
2811 */
2812
2813static speed_t
2814siocngetspeed(iobase, rclk)
2815 Port_t iobase;
2816 u_long rclk;
2817{
2818 u_int divisor;
2819 u_char dlbh;
2820 u_char dlbl;
2821 u_char cfcr;
2822
2823 cfcr = inb(iobase + com_cfcr);
2824 outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
2825
2826 dlbl = inb(iobase + com_dlbl);
2827 dlbh = inb(iobase + com_dlbh);
2828
2829 outb(iobase + com_cfcr, cfcr);
2830
2831 divisor = dlbh << 8 | dlbl;
2832
2833 /* XXX there should be more sanity checking. */
2834 if (divisor == 0)
2835 return (CONSPEED);
2836 return (rclk / (16UL * divisor));
2837}
2838
2839#endif
2840
2841static void
2842siocnopen(sp, iobase, speed)
2843 struct siocnstate *sp;
2844 Port_t iobase;
2845 int speed;
2846{
2847 u_int divisor;
2848 u_char dlbh;
2849 u_char dlbl;
2850
2851 /*
2852 * Save all the device control registers except the fifo register
2853 * and set our default ones (cs8 -parenb speed=comdefaultrate).
2854 * We can't save the fifo register since it is read-only.
2855 */
2856 sp->ier = inb(iobase + com_ier);
2857 outb(iobase + com_ier, 0); /* spltty() doesn't stop siointr() */
2858 siocntxwait(iobase);
2859 sp->cfcr = inb(iobase + com_cfcr);
2860 outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
2861 sp->dlbl = inb(iobase + com_dlbl);
2862 sp->dlbh = inb(iobase + com_dlbh);
2863 /*
2864 * Only set the divisor registers if they would change, since on
2865 * some 16550 incompatibles (Startech), setting them clears the
2866 * data input register. This also reduces the effects of the
2867 * UMC8669F bug.
2868 */
2869 divisor = siodivisor(comdefaultrclk, speed);
2870 dlbl = divisor & 0xFF;
2871 if (sp->dlbl != dlbl)
2872 outb(iobase + com_dlbl, dlbl);
2873 dlbh = divisor >> 8;
2874 if (sp->dlbh != dlbh)
2875 outb(iobase + com_dlbh, dlbh);
2876 outb(iobase + com_cfcr, CFCR_8BITS);
2877 sp->mcr = inb(iobase + com_mcr);
2878 /*
2879 * We don't want interrupts, but must be careful not to "disable"
2880 * them by clearing the MCR_IENABLE bit, since that might cause
2881 * an interrupt by floating the IRQ line.
2882 */
2883 outb(iobase + com_mcr, (sp->mcr & MCR_IENABLE) | MCR_DTR | MCR_RTS);
2884}
2885
2886static void
2887siocnclose(sp, iobase)
2888 struct siocnstate *sp;
2889 Port_t iobase;
2890{
2891 /*
2892 * Restore the device control registers.
2893 */
2894 siocntxwait(iobase);
2895 outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
2896 if (sp->dlbl != inb(iobase + com_dlbl))
2897 outb(iobase + com_dlbl, sp->dlbl);
2898 if (sp->dlbh != inb(iobase + com_dlbh))
2899 outb(iobase + com_dlbh, sp->dlbh);
2900 outb(iobase + com_cfcr, sp->cfcr);
2901 /*
2902 * XXX damp oscillations of MCR_DTR and MCR_RTS by not restoring them.
2903 */
2904 outb(iobase + com_mcr, sp->mcr | MCR_DTR | MCR_RTS);
2905 outb(iobase + com_ier, sp->ier);
2906}
2907
2908#ifndef __alpha__
2909
2910static void
2911siocnprobe(cp)
2912 struct consdev *cp;
2913{
2914 speed_t boot_speed;
2915 u_char cfcr;
2916 u_int divisor;
2917 int s, unit;
2918 struct siocnstate sp;
2919
2920 /*
2921 * Find our first enabled console, if any. If it is a high-level
2922 * console device, then initialize it and return successfully.
2923 * If it is a low-level console device, then initialize it and
2924 * return unsuccessfully. It must be initialized in both cases
2925 * for early use by console drivers and debuggers. Initializing
2926 * the hardware is not necessary in all cases, since the i/o
2927 * routines initialize it on the fly, but it is necessary if
2928 * input might arrive while the hardware is switched back to an
2929 * uninitialized state. We can't handle multiple console devices
2930 * yet because our low-level routines don't take a device arg.
2931 * We trust the user to set the console flags properly so that we
2932 * don't need to probe.
2933 */
2934 cp->cn_pri = CN_DEAD;
2935
2936 for (unit = 0; unit < 16; unit++) { /* XXX need to know how many */
2937 int flags;
2938 int disabled;
2939 if (resource_int_value("sio", unit, "disabled", &disabled) == 0) {
2940 if (disabled)
2941 continue;
2942 }
2943 if (resource_int_value("sio", unit, "flags", &flags))
2944 continue;
2945 if (COM_CONSOLE(flags) || COM_DEBUGGER(flags)) {
2946 int port;
2947 Port_t iobase;
2948
2949 if (resource_int_value("sio", unit, "port", &port))
2950 continue;
2951 iobase = port;
2952 s = spltty();
2953 if (boothowto & RB_SERIAL) {
2954 boot_speed =
2955 siocngetspeed(iobase, comdefaultrclk);
2956 if (boot_speed)
2957 comdefaultrate = boot_speed;
2958 }
2959
2960 /*
2961 * Initialize the divisor latch. We can't rely on
2962 * siocnopen() to do this the first time, since it
2963 * avoids writing to the latch if the latch appears
2964 * to have the correct value. Also, if we didn't
2965 * just read the speed from the hardware, then we
2966 * need to set the speed in hardware so that
2967 * switching it later is null.
2968 */
2969 cfcr = inb(iobase + com_cfcr);
2970 outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
2971 divisor = siodivisor(comdefaultrclk, comdefaultrate);
2972 outb(iobase + com_dlbl, divisor & 0xff);
2973 outb(iobase + com_dlbh, divisor >> 8);
2974 outb(iobase + com_cfcr, cfcr);
2975
2976 siocnopen(&sp, iobase, comdefaultrate);
2977
2978 splx(s);
2979 if (COM_CONSOLE(flags) && !COM_LLCONSOLE(flags)) {
2980 cp->cn_dev = makedev(CDEV_MAJOR, unit);
2981 cp->cn_pri = COM_FORCECONSOLE(flags)
2982 || boothowto & RB_SERIAL
2983 ? CN_REMOTE : CN_NORMAL;
2984 siocniobase = iobase;
2985 siocnunit = unit;
2986 }
2987 if (COM_DEBUGGER(flags)) {
2988 printf("sio%d: gdb debugging port\n", unit);
2989 siogdbiobase = iobase;
2990 siogdbunit = unit;
2991#if DDB > 0
2992 gdbconsdev.cn_dev = makedev(CDEV_MAJOR, unit);
2993 gdb_arg = &gdbconsdev;
2994 gdb_getc = siocngetc;
2995 gdb_putc = siocnputc;
2996#endif
2997 }
2998 }
2999 }
3000#ifdef __i386__
3001#if DDB > 0
3002 /*
3003 * XXX Ugly Compatability.
3004 * If no gdb port has been specified, set it to be the console
3005 * as some configuration files don't specify the gdb port.
3006 */
3007 if (gdb_arg == NULL && (boothowto & RB_GDB)) {
3008 printf("Warning: no GDB port specified. Defaulting to sio%d.\n",
3009 siocnunit);
3010 printf("Set flag 0x80 on desired GDB port in your\n");
3011 printf("configuration file (currently sio only).\n");
3012 siogdbiobase = siocniobase;
3013 siogdbunit = siocnunit;
3014 gdbconsdev.cn_dev = makedev(CDEV_MAJOR, siocnunit);
3015 gdb_arg = &gdbconsdev;
3016 gdb_getc = siocngetc;
3017 gdb_putc = siocnputc;
3018 }
3019#endif
3020#endif
3021}
3022
3023static void
3024siocninit(cp)
3025 struct consdev *cp;
3026{
3027 comconsole = DEV_TO_UNIT(cp->cn_dev);
3028}
3029
3030static void
3031siocnterm(cp)
3032 struct consdev *cp;
3033{
3034 comconsole = -1;
3035}
3036
3037#endif
3038
3039#ifdef __alpha__
3040
3041CONS_DRIVER(sio, NULL, NULL, NULL, siocngetc, siocncheckc, siocnputc, NULL);
3042
3043int
3044siocnattach(port, speed)
3045 int port;
3046 int speed;
3047{
3048 int s;
3049 u_char cfcr;
3050 u_int divisor;
3051 struct siocnstate sp;
3052 int unit = 0; /* XXX random value! */
3053
3054 siocniobase = port;
3055 siocnunit = unit;
3056 comdefaultrate = speed;
3057 sio_consdev.cn_pri = CN_NORMAL;
3058 sio_consdev.cn_dev = makedev(CDEV_MAJOR, unit);
3059
3060 s = spltty();
3061
3062 /*
3063 * Initialize the divisor latch. We can't rely on
3064 * siocnopen() to do this the first time, since it
3065 * avoids writing to the latch if the latch appears
3066 * to have the correct value. Also, if we didn't
3067 * just read the speed from the hardware, then we
3068 * need to set the speed in hardware so that
3069 * switching it later is null.
3070 */
3071 cfcr = inb(siocniobase + com_cfcr);
3072 outb(siocniobase + com_cfcr, CFCR_DLAB | cfcr);
3073 divisor = siodivisor(comdefaultrclk, comdefaultrate);
3074 outb(siocniobase + com_dlbl, divisor & 0xff);
3075 outb(siocniobase + com_dlbh, divisor >> 8);
3076 outb(siocniobase + com_cfcr, cfcr);
3077
3078 siocnopen(&sp, siocniobase, comdefaultrate);
3079 splx(s);
3080
3081 cnadd(&sio_consdev);
3082 return (0);
3083}
3084
3085int
3086siogdbattach(port, speed)
3087 int port;
3088 int speed;
3089{
3090 int s;
3091 u_char cfcr;
3092 u_int divisor;
3093 struct siocnstate sp;
3094 int unit = 1; /* XXX random value! */
3095
3096 siogdbiobase = port;
3097 gdbdefaultrate = speed;
3098
3099 printf("sio%d: gdb debugging port\n", unit);
3100 siogdbunit = unit;
3101#if DDB > 0
3102 gdbconsdev.cn_dev = makedev(CDEV_MAJOR, unit);
3103 gdb_arg = &gdbconsdev;
3104 gdb_getc = siocngetc;
3105 gdb_putc = siocnputc;
3106#endif
3107
3108 s = spltty();
3109
3110 /*
3111 * Initialize the divisor latch. We can't rely on
3112 * siocnopen() to do this the first time, since it
3113 * avoids writing to the latch if the latch appears
3114 * to have the correct value. Also, if we didn't
3115 * just read the speed from the hardware, then we
3116 * need to set the speed in hardware so that
3117 * switching it later is null.
3118 */
3119 cfcr = inb(siogdbiobase + com_cfcr);
3120 outb(siogdbiobase + com_cfcr, CFCR_DLAB | cfcr);
3121 divisor = siodivisor(comdefaultrclk, gdbdefaultrate);
3122 outb(siogdbiobase + com_dlbl, divisor & 0xff);
3123 outb(siogdbiobase + com_dlbh, divisor >> 8);
3124 outb(siogdbiobase + com_cfcr, cfcr);
3125
3126 siocnopen(&sp, siogdbiobase, gdbdefaultrate);
3127 splx(s);
3128
3129 return (0);
3130}
3131
3132#endif
3133
3134static int
3135siocncheckc(struct consdev *cd)
3136{
3137 int c;
3138 dev_t dev;
3139 Port_t iobase;
3140 int s;
3141 struct siocnstate sp;
3142 speed_t speed;
3143
3144 dev = cd->cn_dev;
3145 if (minor(dev) == siocnunit) {
3146 iobase = siocniobase;
3147 speed = comdefaultrate;
3148 } else {
3149 iobase = siogdbiobase;
3150 speed = gdbdefaultrate;
3151 }
3152 s = spltty();
3153 siocnopen(&sp, iobase, speed);
3154 if (inb(iobase + com_lsr) & LSR_RXRDY)
3155 c = inb(iobase + com_data);
3156 else
3157 c = -1;
3158 siocnclose(&sp, iobase);
3159 splx(s);
3160 return (c);
3161}
3162
3163
3164static int
3165siocngetc(struct consdev *cd)
3166{
3167 int c;
3168 dev_t dev;
3169 Port_t iobase;
3170 int s;
3171 struct siocnstate sp;
3172 speed_t speed;
3173
3174 dev = cd->cn_dev;
3175 if (minor(dev) == siocnunit) {
3176 iobase = siocniobase;
3177 speed = comdefaultrate;
3178 } else {
3179 iobase = siogdbiobase;
3180 speed = gdbdefaultrate;
3181 }
3182 s = spltty();
3183 siocnopen(&sp, iobase, speed);
3184 while (!(inb(iobase + com_lsr) & LSR_RXRDY))
3185 ;
3186 c = inb(iobase + com_data);
3187 siocnclose(&sp, iobase);
3188 splx(s);
3189 return (c);
3190}
3191
3192static void
3193siocnputc(struct consdev *cd, int c)
3194{
3195 int need_unlock;
3196 int s;
3197 dev_t dev;
3198 struct siocnstate sp;
3199 Port_t iobase;
3200 speed_t speed;
3201
3202 dev = cd->cn_dev;
3203 if (minor(dev) == siocnunit) {
3204 iobase = siocniobase;
3205 speed = comdefaultrate;
3206 } else {
3207 iobase = siogdbiobase;
3208 speed = gdbdefaultrate;
3209 }
3210 s = spltty();
3211 need_unlock = 0;
3212 if (sio_inited == 2 && !mtx_owned(&sio_lock)) {
3213 mtx_lock_spin(&sio_lock);
3214 need_unlock = 1;
3215 }
3216 siocnopen(&sp, iobase, speed);
3217 siocntxwait(iobase);
3218 outb(iobase + com_data, c);
3219 siocnclose(&sp, iobase);
3220 if (need_unlock)
3221 mtx_unlock_spin(&sio_lock);
3222 splx(s);
3223}
3224
3225#ifdef __alpha__
3226int
3227siogdbgetc()
3228{
3229 int c;
3230 Port_t iobase;
3231 speed_t speed;
3232 int s;
3233 struct siocnstate sp;
3234
3235 if (siogdbunit == siocnunit) {
3236 iobase = siocniobase;
3237 speed = comdefaultrate;
3238 } else {
3239 iobase = siogdbiobase;
3240 speed = gdbdefaultrate;
3241 }
3242
3243 s = spltty();
3244 siocnopen(&sp, iobase, speed);
3245 while (!(inb(iobase + com_lsr) & LSR_RXRDY))
3246 ;
3247 c = inb(iobase + com_data);
3248 siocnclose(&sp, iobase);
3249 splx(s);
3250 return (c);
3251}
3252
3253void
3254siogdbputc(c)
3255 int c;
3256{
3257 Port_t iobase;
3258 speed_t speed;
3259 int s;
3260 struct siocnstate sp;
3261
3262 if (siogdbunit == siocnunit) {
3263 iobase = siocniobase;
3264 speed = comdefaultrate;
3265 } else {
3266 iobase = siogdbiobase;
3267 speed = gdbdefaultrate;
3268 }
3269
3270 s = spltty();
3271 siocnopen(&sp, iobase, speed);
3272 siocntxwait(siogdbiobase);
3273 outb(siogdbiobase + com_data, c);
3274 siocnclose(&sp, siogdbiobase);
3275 splx(s);
3276}
3277#endif