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