xref: /netbsd-src/sys/dev/sbus/spif.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1 /*	$NetBSD: spif.c,v 1.31 2014/07/25 08:10:38 dholland Exp $	*/
2 /*	$OpenBSD: spif.c,v 1.12 2003/10/03 16:44:51 miod Exp $	*/
3 
4 /*
5  * Copyright (c) 1999-2002 Jason L. Wright (jason@thought.net)
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
21  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * Effort sponsored in part by the Defense Advanced Research Projects
30  * Agency (DARPA) and Air Force Research Laboratory, Air Force
31  * Materiel Command, USAF, under agreement number F30602-01-2-0537.
32  *
33  */
34 
35 /*
36  * Driver for the SUNW,spif: 8 serial, 1 parallel sbus board
37  * based heavily on Iain Hibbert's driver for the MAGMA cards
38  */
39 
40 /* Ported to NetBSD 2.0 by Hauke Fath */
41 
42 
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: spif.c,v 1.31 2014/07/25 08:10:38 dholland Exp $");
45 
46 #include "spif.h"
47 #if NSPIF > 0
48 
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/proc.h>
52 #include <sys/device.h>
53 #include <sys/file.h>
54 #include <sys/ioctl.h>
55 #include <sys/malloc.h>
56 #include <sys/tty.h>
57 #include <sys/time.h>
58 #include <sys/kernel.h>
59 #include <sys/syslog.h>
60 #include <sys/conf.h>
61 #include <sys/errno.h>
62 #include <sys/kauth.h>
63 #include <sys/intr.h>
64 
65 #include <sys/bus.h>
66 #include <machine/autoconf.h>
67 #include <machine/promlib.h>
68 
69 #include <dev/sbus/sbusvar.h>
70 
71 #include <dev/sbus/spifvar.h>
72 #include <dev/sbus/spifreg.h>
73 
74 #include "ioconf.h"
75 
76 /* Autoconfig stuff */
77 
78 CFATTACH_DECL_NEW(spif, sizeof(struct spif_softc),
79     spif_match, spif_attach, NULL, NULL);
80 
81 CFATTACH_DECL_NEW(stty, sizeof(struct stty_softc),
82     stty_match, stty_attach, NULL, NULL);
83 
84 CFATTACH_DECL_NEW(sbpp, sizeof(struct sbpp_softc),
85     sbpp_match, sbpp_attach, NULL, NULL);
86 
87 dev_type_open(stty_open);
88 dev_type_close(stty_close);
89 dev_type_read(stty_read);
90 dev_type_write(stty_write);
91 dev_type_ioctl(stty_ioctl);
92 dev_type_stop(stty_stop);
93 dev_type_tty(stty_tty);
94 dev_type_poll(stty_poll);
95 
96 const struct cdevsw stty_cdevsw = {
97 	.d_open = stty_open,
98 	.d_close = stty_close,
99 	.d_read = stty_read,
100 	.d_write = stty_write,
101 	.d_ioctl = stty_ioctl,
102 	.d_stop = stty_stop,
103 	.d_tty = stty_tty,
104 	.d_poll = stty_poll,
105 	.d_mmap = nommap,
106 	.d_kqfilter = ttykqfilter,
107 	.d_discard = nodiscard,
108 	.d_flag = D_TTY
109 };
110 
111 dev_type_open(sbpp_open);
112 dev_type_close(sbpp_close);
113 dev_type_read(sbpp_read);
114 dev_type_write(sbpp_write);
115 dev_type_ioctl(sbpp_ioctl);
116 dev_type_poll(sbpp_poll);
117 
118 const struct cdevsw sbpp_cdevsw = {
119 	.d_open = sbpp_open,
120 	.d_close = sbpp_close,
121 	.d_read = sbpp_read,
122 	.d_write = sbpp_write,
123 	.d_ioctl = sbpp_ioctl,
124 	.d_stop = nostop,
125 	.d_tty = notty,
126 	.d_poll = sbpp_poll,
127 	.d_mmap = nommap,
128 	.d_kqfilter = nokqfilter,
129 	.d_discard = nodiscard,
130 	.d_flag = D_OTHER
131 };
132 
133 
134 /* normal STC access */
135 #define	STC_WRITE(sc,r,v)	\
136     bus_space_write_1((sc)->sc_bustag, (sc)->sc_stch, (r), (v))
137 #define	STC_READ(sc,r)		\
138     bus_space_read_1((sc)->sc_bustag, (sc)->sc_stch, (r))
139 
140 /* IACK STC access */
141 #define	ISTC_WRITE(sc,r,v)	\
142     bus_space_write_1((sc)->sc_bustag, (sc)->sc_istch, (r), (v))
143 #define	ISTC_READ(sc,r)		\
144     bus_space_read_1((sc)->sc_bustag, (sc)->sc_istch, (r))
145 
146 /* PPC access */
147 #define	PPC_WRITE(sc,r,v)	\
148     bus_space_write_1((sc)->sc_bustag, (sc)->sc_ppch, (r), (v))
149 #define	PPC_READ(sc,r)		\
150     bus_space_read_1((sc)->sc_bustag, (sc)->sc_ppch, (r))
151 
152 #define	DTR_WRITE(sc,port,v)						\
153     do {								\
154 	sc->sc_ttys->sc_port[(port)].sp_dtr = v;			\
155 	bus_space_write_1((sc)->sc_bustag,				\
156 	    sc->sc_dtrh, port, (v == 0) ? 1 : 0);			\
157     } while (0)
158 
159 #define	DTR_READ(sc,port)	((sc)->sc_ttys->sc_port[(port)].sp_dtr)
160 
161 
162 int
163 spif_match(device_t parent, cfdata_t vcf, void *aux)
164 {
165 	struct sbus_attach_args *sa = aux;
166 
167 	if (strcmp(vcf->cf_name, sa->sa_name) &&
168 	    strcmp("SUNW,spif", sa->sa_name))
169 		return (0);
170 	return (1);
171 }
172 
173 void
174 spif_attach(device_t parent, device_t self, void *aux)
175 {
176 	struct spif_softc *sc = device_private(self);
177 	struct sbus_attach_args *sa = aux;
178 
179 	sc->sc_dev = self;
180 
181 	if (sa->sa_nintr != 2) {
182 		printf(": expected %d interrupts, got %d\n", 2, sa->sa_nintr);
183 		return;
184 	}
185 
186 	if (sa->sa_nreg != 1) {
187 		printf(": expected %d registers, got %d\n", 1, sa->sa_nreg);
188 		return;
189 	}
190 
191 	sc->sc_bustag = sa->sa_bustag;
192 	if (sbus_bus_map(sa->sa_bustag, sa->sa_slot,
193 	    sa->sa_offset, sa->sa_size,
194 	    0, &sc->sc_regh) != 0) {
195 		printf(": can't map registers\n");
196 		return;
197 	}
198 
199 	if (bus_space_subregion(sc->sc_bustag, sc->sc_regh,
200 	    DTR_REG_OFFSET, DTR_REG_LEN, &sc->sc_dtrh) != 0) {
201 		printf(": can't map dtr regs\n");
202 		goto fail_unmapregs;
203 	}
204 
205 	if (bus_space_subregion(sc->sc_bustag, sc->sc_regh,
206 	    STC_REG_OFFSET, STC_REG_LEN, &sc->sc_stch) != 0) {
207 		printf(": can't map dtr regs\n");
208 		goto fail_unmapregs;
209 	}
210 
211 	if (bus_space_subregion(sc->sc_bustag, sc->sc_regh,
212 	    ISTC_REG_OFFSET, ISTC_REG_LEN, &sc->sc_istch) != 0) {
213 		printf(": can't map dtr regs\n");
214 		goto fail_unmapregs;
215 	}
216 
217 	if (bus_space_subregion(sc->sc_bustag, sc->sc_regh,
218 	    PPC_REG_OFFSET, PPC_REG_LEN, &sc->sc_ppch) != 0) {
219 		printf(": can't map dtr regs\n");
220 		goto fail_unmapregs;
221 	}
222 
223 	sc->sc_ppcih = bus_intr_establish(sa->sa_bustag,
224 	    sa->sa_intr[PARALLEL_INTR].oi_pri, IPL_SERIAL, spif_ppcintr, sc);
225 	if (sc->sc_ppcih == NULL) {
226 		printf(": failed to establish ppc interrupt\n");
227 		goto fail_unmapregs;
228 	}
229 
230 	sc->sc_stcih = bus_intr_establish(sa->sa_bustag,
231 	    sa->sa_intr[SERIAL_INTR].oi_pri, IPL_SERIAL, spif_stcintr, sc);
232 	if (sc->sc_stcih == NULL) {
233 		printf(": failed to establish stc interrupt\n");
234 		goto fail_unmapregs;
235 	}
236 
237 	sc->sc_softih = softint_establish(SOFTINT_SERIAL, spif_softintr, sc);
238 	if (sc->sc_softih == NULL) {
239 		printf(": can't get soft intr\n");
240 		goto fail_unmapregs;
241 	}
242 
243 	sc->sc_node = sa->sa_node;
244 
245 	sc->sc_rev = prom_getpropint(sc->sc_node, "revlev", 0);
246 
247 	sc->sc_osc = prom_getpropint(sc->sc_node, "verosc", 0);
248 	switch (sc->sc_osc) {
249 	case SPIF_OSC10:
250 		sc->sc_osc = 10000000;
251 		break;
252 	case SPIF_OSC9:
253 	default:
254 		sc->sc_osc = 9830400;
255 		break;
256 	}
257 
258 	sc->sc_nser = 8;
259 	sc->sc_npar = 1;
260 
261 	sc->sc_rev2 = STC_READ(sc, STC_GFRCR);
262 	STC_WRITE(sc, STC_GSVR, 0);
263 
264 	stty_write_ccr(sc, CD180_CCR_CMD_RESET | CD180_CCR_RESETALL);
265 	while (STC_READ(sc, STC_GSVR) != 0xff);
266 	while (STC_READ(sc, STC_GFRCR) != sc->sc_rev2);
267 
268 	STC_WRITE(sc, STC_PPRH, CD180_PPRH);
269 	STC_WRITE(sc, STC_PPRL, CD180_PPRL);
270 	STC_WRITE(sc, STC_MSMR, SPIF_MSMR);
271 	STC_WRITE(sc, STC_TSMR, SPIF_TSMR);
272 	STC_WRITE(sc, STC_RSMR, SPIF_RSMR);
273 	STC_WRITE(sc, STC_GSVR, 0);
274 	STC_WRITE(sc, STC_GSCR1, 0);
275 	STC_WRITE(sc, STC_GSCR2, 0);
276 	STC_WRITE(sc, STC_GSCR3, 0);
277 
278 	printf(": rev %x chiprev %x osc %sMHz\n",
279 	    sc->sc_rev, sc->sc_rev2, clockfreq(sc->sc_osc));
280 
281 	(void)config_found(self, stty_match, NULL);
282 	(void)config_found(self, sbpp_match, NULL);
283 
284 	return;
285 
286 fail_unmapregs:
287 	bus_space_unmap(sa->sa_bustag, sc->sc_regh, sa->sa_size);
288 }
289 
290 int
291 stty_match(device_t parent, cfdata_t vcf, void *aux)
292 {
293 	struct spif_softc *sc = device_private(parent);
294 
295 	return (aux == stty_match && sc->sc_ttys == NULL);
296 }
297 
298 void
299 stty_attach(device_t parent, device_t dev, void *aux)
300 {
301 	struct spif_softc *sc = device_private(parent);
302 	struct stty_softc *ssc = device_private(dev);
303 	int port;
304 
305 	sc->sc_dev = dev;
306 	sc->sc_ttys = ssc;
307 
308 	for (port = 0; port < sc->sc_nser; port++) {
309 		struct stty_port *sp = &ssc->sc_port[port];
310 		struct tty *tp;
311 
312 		DTR_WRITE(sc, port, 0);
313 
314 		tp = tty_alloc();
315 
316 		tp->t_oproc = stty_start;
317 		tp->t_param = stty_param;
318 
319 		sp->sp_tty = tp;
320 		sp->sp_sc = sc;
321 		sp->sp_channel = port;
322 
323 		sp->sp_rbuf = malloc(STTY_RBUF_SIZE, M_DEVBUF, M_NOWAIT);
324 		if(sp->sp_rbuf == NULL)
325 			break;
326 
327 		sp->sp_rend = sp->sp_rbuf + STTY_RBUF_SIZE;
328 	}
329 
330 	ssc->sc_nports = port;
331 
332 	printf(": %d tty%s\n", port, port == 1 ? "" : "s");
333 }
334 
335 int
336 stty_open(dev_t dev, int flags, int mode, struct lwp *l)
337 {
338 	struct spif_softc *csc;
339 	struct stty_softc *sc;
340 	struct stty_port *sp;
341 	struct tty *tp;
342 	int card = SPIF_CARD(dev);
343 	int port = SPIF_PORT(dev);
344 
345 	sc = device_lookup_private(&stty_cd, card);
346 	csc = device_lookup_private(&spif_cd, card);
347 	if (sc == NULL || csc == NULL)
348 		return (ENXIO);
349 
350 	if (port >= sc->sc_nports)
351 		return (ENXIO);
352 
353 	sp = &sc->sc_port[port];
354 	tp = sp->sp_tty;
355 	tp->t_dev = dev;
356 
357 	if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
358 		return (EBUSY);
359 
360 	mutex_spin_enter(&tty_lock);
361 	if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
362 		ttychars(tp);
363 		tp->t_iflag = TTYDEF_IFLAG;
364 		tp->t_oflag = TTYDEF_OFLAG;
365 		tp->t_cflag = TTYDEF_CFLAG;
366 		if (ISSET(sp->sp_openflags, TIOCFLAG_CLOCAL))
367 			SET(tp->t_cflag, CLOCAL);
368 		if (ISSET(sp->sp_openflags, TIOCFLAG_CRTSCTS))
369 			SET(tp->t_cflag, CRTSCTS);
370 		if (ISSET(sp->sp_openflags, TIOCFLAG_MDMBUF))
371 			SET(tp->t_cflag, MDMBUF);
372 		tp->t_lflag = TTYDEF_LFLAG;
373 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
374 
375 		sp->sp_rput = sp->sp_rget = sp->sp_rbuf;
376 
377 		STC_WRITE(csc, STC_CAR, sp->sp_channel);
378 		stty_write_ccr(csc, CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN);
379 		STC_WRITE(csc, STC_CAR, sp->sp_channel);
380 
381 		stty_param(tp, &tp->t_termios);
382 
383 		ttsetwater(tp);
384 
385 		STC_WRITE(csc, STC_SRER, CD180_SRER_CD | CD180_SRER_RXD);
386 
387 		if (ISSET(sp->sp_openflags, TIOCFLAG_SOFTCAR) || sp->sp_carrier)
388 			SET(tp->t_state, TS_CARR_ON);
389 		else
390 			CLR(tp->t_state, TS_CARR_ON);
391 	}
392 
393 	if (!ISSET(flags, O_NONBLOCK)) {
394 		while (!ISSET(tp->t_cflag, CLOCAL) &&
395 		    !ISSET(tp->t_state, TS_CARR_ON)) {
396 			int error;
397 			error = ttysleep(tp, &tp->t_rawcv, true, 0);
398 			if (error != 0) {
399 				mutex_spin_exit(&tty_lock);
400 				return (error);
401 			}
402 		}
403 	}
404 	mutex_spin_exit(&tty_lock);
405 
406 	return ((*tp->t_linesw->l_open)(dev, tp));
407 }
408 
409 int
410 stty_close(dev_t dev, int flags, int mode, struct lwp *l)
411 {
412 	struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev));
413 	struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
414 	struct spif_softc *csc = sp->sp_sc;
415 	struct tty *tp = sp->sp_tty;
416 	int port = SPIF_PORT(dev);
417 	int s;
418 
419 	(*tp->t_linesw->l_close)(tp, flags);
420 	s = spltty();
421 
422 	if (ISSET(tp->t_cflag, HUPCL) || !ISSET(tp->t_state, TS_ISOPEN)) {
423 		stty_modem_control(sp, 0, DMSET);
424 		STC_WRITE(csc, STC_CAR, port);
425 		STC_WRITE(csc, STC_CCR,
426 		    CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN);
427 	}
428 
429 	splx(s);
430 	ttyclose(tp);
431 	return (0);
432 }
433 
434 int
435 stty_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
436 {
437 	struct stty_softc *stc = device_lookup_private(&stty_cd,
438 						       SPIF_CARD(dev));
439 	struct stty_port *sp = &stc->sc_port[SPIF_PORT(dev)];
440 	struct spif_softc *sc = sp->sp_sc;
441 	struct tty *tp = sp->sp_tty;
442 	int error;
443 
444 	error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flags, l);
445 	if (error >= 0)
446 		return (error);
447 
448 	error = ttioctl(tp, cmd, data, flags, l);
449 	if (error >= 0)
450 		return (error);
451 
452 	error = 0;
453 
454 	switch (cmd) {
455 	case TIOCSBRK:
456 		SET(sp->sp_flags, STTYF_SET_BREAK);
457 		STC_WRITE(sc, STC_CAR, sp->sp_channel);
458 		STC_WRITE(sc, STC_SRER,
459 		    STC_READ(sc, STC_SRER) | CD180_SRER_TXD);
460 		break;
461 	case TIOCCBRK:
462 		SET(sp->sp_flags, STTYF_CLR_BREAK);
463 		STC_WRITE(sc, STC_CAR, sp->sp_channel);
464 		STC_WRITE(sc, STC_SRER,
465 		    STC_READ(sc, STC_SRER) | CD180_SRER_TXD);
466 		break;
467 	case TIOCSDTR:
468 		stty_modem_control(sp, TIOCM_DTR, DMBIS);
469 		break;
470 	case TIOCCDTR:
471 		stty_modem_control(sp, TIOCM_DTR, DMBIC);
472 		break;
473 	case TIOCMBIS:
474 		stty_modem_control(sp, *((int *)data), DMBIS);
475 		break;
476 	case TIOCMBIC:
477 		stty_modem_control(sp, *((int *)data), DMBIC);
478 		break;
479 	case TIOCMGET:
480 		*((int *)data) = stty_modem_control(sp, 0, DMGET);
481 		break;
482 	case TIOCMSET:
483 		stty_modem_control(sp, *((int *)data), DMSET);
484 		break;
485 	case TIOCGFLAGS:
486 		*((int *)data) = sp->sp_openflags;
487 		break;
488 	case TIOCSFLAGS:
489 		if (kauth_authorize_device_tty(l->l_cred,
490 		    KAUTH_DEVICE_TTY_PRIVSET, tp))
491 			error = EPERM;
492 		else
493 			sp->sp_openflags = *((int *)data) &
494 			    (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL |
495 			     TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF);
496 		break;
497 	default:
498 		error = ENOTTY;
499 	}
500 
501 	return (error);
502 }
503 
504 int
505 stty_modem_control(struct stty_port *sp, int bits, int how)
506 {
507 	struct spif_softc *csc = sp->sp_sc;
508 	struct tty *tp = sp->sp_tty;
509 	int s, msvr;
510 
511 	s = spltty();
512 	STC_WRITE(csc, STC_CAR, sp->sp_channel);
513 
514 	switch (how) {
515 	case DMGET:
516 		bits = TIOCM_LE;
517 		if (DTR_READ(csc, sp->sp_channel))
518 			bits |= TIOCM_DTR;
519 		msvr = STC_READ(csc, STC_MSVR);
520 		if (ISSET(msvr, CD180_MSVR_DSR))
521 			bits |= TIOCM_DSR;
522 		if (ISSET(msvr, CD180_MSVR_CD))
523 			bits |= TIOCM_CD;
524 		if (ISSET(msvr, CD180_MSVR_CTS))
525 			bits |= TIOCM_CTS;
526 		if (ISSET(msvr, CD180_MSVR_RTS))
527 			bits |= TIOCM_RTS;
528 		break;
529 	case DMSET:
530 		DTR_WRITE(csc, sp->sp_channel, ISSET(bits, TIOCM_DTR) ? 1 : 0);
531 		if (ISSET(bits, TIOCM_RTS))
532 			STC_WRITE(csc, STC_MSVR,
533 			    STC_READ(csc, STC_MSVR) & (~CD180_MSVR_RTS));
534 		else
535 			STC_WRITE(csc, STC_MSVR,
536 			    STC_READ(csc, STC_MSVR) | CD180_MSVR_RTS);
537 		break;
538 	case DMBIS:
539 		if (ISSET(bits, TIOCM_DTR))
540 			DTR_WRITE(csc, sp->sp_channel, 1);
541 		if (ISSET(bits, TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS))
542 			STC_WRITE(csc, STC_MSVR,
543 			    STC_READ(csc, STC_MSVR) & (~CD180_MSVR_RTS));
544 		break;
545 	case DMBIC:
546 		if (ISSET(bits, TIOCM_DTR))
547 			DTR_WRITE(csc, sp->sp_channel, 0);
548 		if (ISSET(bits, TIOCM_RTS))
549 			STC_WRITE(csc, STC_MSVR,
550 			    STC_READ(csc, STC_MSVR) | CD180_MSVR_RTS);
551 		break;
552 	}
553 
554 	splx(s);
555 	return (bits);
556 }
557 
558 int
559 stty_param(struct tty *tp, struct termios *t)
560 {
561 	struct stty_softc *st = device_lookup_private(&stty_cd,
562 						      SPIF_CARD(tp->t_dev));
563 	struct stty_port *sp = &st->sc_port[SPIF_PORT(tp->t_dev)];
564 	struct spif_softc *sc = sp->sp_sc;
565 	uint8_t rbprl = 0, rbprh = 0, tbprl = 0, tbprh = 0;
566 	int s, opt;
567 
568 	if (t->c_ospeed &&
569 	    stty_compute_baud(t->c_ospeed, sc->sc_osc, &tbprl, &tbprh))
570 		return (EINVAL);
571 
572 	if (t->c_ispeed &&
573 	    stty_compute_baud(t->c_ispeed, sc->sc_osc, &rbprl, &rbprh))
574 		return (EINVAL);
575 
576 	s = spltty();
577 
578 	/* hang up line if ospeed is zero, otherwise raise DTR */
579 	stty_modem_control(sp, TIOCM_DTR,
580 	    (t->c_ospeed == 0 ? DMBIC : DMBIS));
581 
582 	STC_WRITE(sc, STC_CAR, sp->sp_channel);
583 
584 	opt = 0;
585 	if (ISSET(t->c_cflag, PARENB)) {
586 		opt |= CD180_COR1_PARMODE_NORMAL;
587 		opt |= (ISSET(t->c_cflag, PARODD) ?
588 				CD180_COR1_ODDPAR :
589 				CD180_COR1_EVENPAR);
590 	}
591 	else
592 		opt |= CD180_COR1_PARMODE_NO;
593 
594 	if (!ISSET(t->c_iflag, INPCK))
595 		opt |= CD180_COR1_IGNPAR;
596 
597 	if (ISSET(t->c_cflag, CSTOPB))
598 		opt |= CD180_COR1_STOP2;
599 
600 	switch (t->c_cflag & CSIZE) {
601 	case CS5:
602 		opt |= CD180_COR1_CS5;
603 		break;
604 	case CS6:
605 		opt |= CD180_COR1_CS6;
606 		break;
607 	case CS7:
608 		opt |= CD180_COR1_CS7;
609 		break;
610 	default:
611 		opt |= CD180_COR1_CS8;
612 		break;
613 	}
614 	STC_WRITE(sc, STC_COR1, opt);
615 	stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG1);
616 
617 	opt = CD180_COR2_ETC;
618 	if (ISSET(t->c_cflag, CRTSCTS))
619 		opt |= CD180_COR2_CTSAE;
620 	STC_WRITE(sc, STC_COR2, opt);
621 	stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG2);
622 
623 	STC_WRITE(sc, STC_COR3, STTY_RX_FIFO_THRESHOLD);
624 	stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG3);
625 
626 	STC_WRITE(sc, STC_SCHR1, 0x11);
627 	STC_WRITE(sc, STC_SCHR2, 0x13);
628 	STC_WRITE(sc, STC_SCHR3, 0x11);
629 	STC_WRITE(sc, STC_SCHR4, 0x13);
630 	STC_WRITE(sc, STC_RTPR, 0x12);
631 
632 	STC_WRITE(sc, STC_MCOR1, CD180_MCOR1_CDZD | STTY_RX_DTR_THRESHOLD);
633 	STC_WRITE(sc, STC_MCOR2, CD180_MCOR2_CDOD);
634 	STC_WRITE(sc, STC_MCR, 0);
635 
636 	if (t->c_ospeed) {
637 		STC_WRITE(sc, STC_TBPRH, tbprh);
638 		STC_WRITE(sc, STC_TBPRL, tbprl);
639 	}
640 
641 	if (t->c_ispeed) {
642 		STC_WRITE(sc, STC_RBPRH, rbprh);
643 		STC_WRITE(sc, STC_RBPRL, rbprl);
644 	}
645 
646 	stty_write_ccr(sc, CD180_CCR_CMD_CHAN |
647 	    CD180_CCR_CHAN_TXEN | CD180_CCR_CHAN_RXEN);
648 
649 	sp->sp_carrier = STC_READ(sc, STC_MSVR) & CD180_MSVR_CD;
650 
651 	splx(s);
652 	return (0);
653 }
654 
655 int
656 stty_read(dev_t dev, struct uio *uio, int flags)
657 {
658 	struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev));
659 	struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
660 	struct tty *tp = sp->sp_tty;
661 
662 	return ((*tp->t_linesw->l_read)(tp, uio, flags));
663 }
664 
665 int
666 stty_write(dev_t dev, struct uio *uio, int flags)
667 {
668 	struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev));
669 	struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
670 	struct tty *tp = sp->sp_tty;
671 
672 	return ((*tp->t_linesw->l_write)(tp, uio, flags));
673 }
674 
675 int
676 stty_poll(dev_t dev, int events, struct lwp *l)
677 {
678 	struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev));
679 	struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
680 	struct tty *tp = sp->sp_tty;
681 
682 	return ((*tp->t_linesw->l_poll)(tp, events, l));
683 }
684 
685 struct tty *
686 stty_tty(dev_t dev)
687 {
688 	struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev));
689 	struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
690 
691 	return (sp->sp_tty);
692 }
693 
694 void
695 stty_stop(struct tty *tp, int flags)
696 {
697 	struct stty_softc *sc = device_lookup_private(&stty_cd,
698 						      SPIF_CARD(tp->t_dev));
699 	struct stty_port *sp = &sc->sc_port[SPIF_PORT(tp->t_dev)];
700 	int s;
701 
702 	s = spltty();
703 	if (ISSET(tp->t_state, TS_BUSY)) {
704 		if (!ISSET(tp->t_state, TS_TTSTOP))
705 			SET(tp->t_state, TS_FLUSH);
706 		SET(sp->sp_flags, STTYF_STOP);
707 	}
708 	splx(s);
709 }
710 
711 void
712 stty_start(struct tty *tp)
713 {
714 	struct stty_softc *stc = device_lookup_private(&stty_cd,
715 						       SPIF_CARD(tp->t_dev));
716 	struct stty_port *sp = &stc->sc_port[SPIF_PORT(tp->t_dev)];
717 	struct spif_softc *sc = sp->sp_sc;
718 	int s;
719 
720 	s = spltty();
721 
722 	if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) {
723 		if (ttypull(tp)) {
724 			sp->sp_txc = ndqb(&tp->t_outq, 0);
725 			sp->sp_txp = tp->t_outq.c_cf;
726 			SET(tp->t_state, TS_BUSY);
727 			STC_WRITE(sc, STC_CAR, sp->sp_channel);
728 			STC_WRITE(sc, STC_SRER,
729 			    STC_READ(sc, STC_SRER) | CD180_SRER_TXD);
730 		}
731 	}
732 
733 	splx(s);
734 }
735 
736 int
737 spif_stcintr_rxexception(struct spif_softc *sc, int *needsoftp)
738 {
739 	struct stty_port *sp;
740 	uint8_t channel, *ptr;
741 
742 	channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1));
743 	sp = &sc->sc_ttys->sc_port[channel];
744 	ptr = sp->sp_rput;
745 	*ptr++ = STC_READ(sc, STC_RCSR);
746 	*ptr++ = STC_READ(sc, STC_RDR);
747 	if (ptr == sp->sp_rend)
748 		ptr = sp->sp_rbuf;
749 	if (ptr == sp->sp_rget) {
750 		if (ptr == sp->sp_rbuf)
751 			ptr = sp->sp_rend;
752 		ptr -= 2;
753 		SET(sp->sp_flags, STTYF_RING_OVERFLOW);
754 	}
755 	STC_WRITE(sc, STC_EOSRR, 0);
756 	*needsoftp = 1;
757 	sp->sp_rput = ptr;
758 	return (1);
759 }
760 
761 int
762 spif_stcintr_rx(struct spif_softc *sc, int *needsoftp)
763 {
764 	struct stty_port *sp;
765 	uint8_t channel, *ptr, cnt;
766 	int i;
767 
768 	channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1));
769 	sp = &sc->sc_ttys->sc_port[channel];
770 	ptr = sp->sp_rput;
771 	cnt = STC_READ(sc, STC_RDCR);
772 	for (i = 0; i < cnt; i++) {
773 		*ptr++ = 0;
774 		(void)STC_READ(sc, STC_RCSR);
775 		*ptr++ = STC_READ(sc, STC_RDR);
776 		if (ptr == sp->sp_rend)
777 			ptr = sp->sp_rbuf;
778 		if (ptr == sp->sp_rget) {
779 			if (ptr == sp->sp_rbuf)
780 				ptr = sp->sp_rend;
781 			ptr -= 2;
782 			SET(sp->sp_flags, STTYF_RING_OVERFLOW);
783 			break;
784 		}
785 	}
786 	STC_WRITE(sc, STC_EOSRR, 0);
787 	if (cnt) {
788 		*needsoftp = 1;
789 		sp->sp_rput = ptr;
790 	}
791 	return (1);
792 }
793 
794 int
795 spif_stcintr_tx(struct spif_softc *sc, int *needsoftp)
796 {
797 	struct stty_port *sp;
798 	uint8_t channel, ch;
799 	int cnt = 0;
800 
801 	channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1));
802 	sp = &sc->sc_ttys->sc_port[channel];
803 	if (!ISSET(sp->sp_flags, STTYF_STOP)) {
804 		if (ISSET(sp->sp_flags, STTYF_SET_BREAK)) {
805 			STC_WRITE(sc, STC_TDR, 0);
806 			STC_WRITE(sc, STC_TDR, 0x81);
807 			CLR(sp->sp_flags, STTYF_SET_BREAK);
808 			cnt += 2;
809 		}
810 		if (ISSET(sp->sp_flags, STTYF_CLR_BREAK)) {
811 			STC_WRITE(sc, STC_TDR, 0);
812 			STC_WRITE(sc, STC_TDR, 0x83);
813 			CLR(sp->sp_flags, STTYF_CLR_BREAK);
814 			cnt += 2;
815 		}
816 
817 		while (sp->sp_txc > 0 && cnt < (CD180_TX_FIFO_SIZE-1)) {
818 			ch = *sp->sp_txp;
819 			sp->sp_txc--;
820 			sp->sp_txp++;
821 
822 			if (ch == 0) {
823 				STC_WRITE(sc, STC_TDR, ch);
824 				cnt++;
825 			}
826 			STC_WRITE(sc, STC_TDR, ch);
827 			cnt++;
828 		}
829 	}
830 
831 	if (sp->sp_txc == 0 ||
832 	    ISSET(sp->sp_flags, STTYF_STOP)) {
833 		STC_WRITE(sc, STC_SRER, STC_READ(sc, STC_SRER) &
834 		    (~CD180_SRER_TXD));
835 		CLR(sp->sp_flags, STTYF_STOP);
836 		SET(sp->sp_flags, STTYF_DONE);
837 		*needsoftp = 1;
838 	}
839 
840 	STC_WRITE(sc, STC_EOSRR, 0);
841 
842 	return (1);
843 }
844 
845 int
846 spif_stcintr_mx(struct spif_softc *sc, int *needsoftp)
847 {
848 	struct stty_port *sp;
849 	uint8_t channel, mcr;
850 
851 	channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1));
852 	sp = &sc->sc_ttys->sc_port[channel];
853 	mcr = STC_READ(sc, STC_MCR);
854 	if (mcr & CD180_MCR_CD) {
855 		SET(sp->sp_flags, STTYF_CDCHG);
856 		*needsoftp = 1;
857 	}
858 	STC_WRITE(sc, STC_MCR, 0);
859 	STC_WRITE(sc, STC_EOSRR, 0);
860 	return (1);
861 }
862 
863 int
864 spif_stcintr(void *vsc)
865 {
866 	struct spif_softc *sc = (struct spif_softc *)vsc;
867 	int needsoft = 0, r = 0, i;
868 	uint8_t ar;
869 
870 	for (i = 0; i < 8; i++) {
871 		ar = ISTC_READ(sc, STC_RRAR) & CD180_GSVR_IMASK;
872 		if (ar == CD180_GSVR_RXGOOD)
873 			r |= spif_stcintr_rx(sc, &needsoft);
874 		else if (ar == CD180_GSVR_RXEXCEPTION)
875 			r |= spif_stcintr_rxexception(sc, &needsoft);
876 	}
877 
878 	for (i = 0; i < 8; i++) {
879 		ar = ISTC_READ(sc, STC_TRAR) & CD180_GSVR_IMASK;
880 		if (ar == CD180_GSVR_TXDATA)
881 			r |= spif_stcintr_tx(sc, &needsoft);
882 	}
883 
884 	for (i = 0; i < 8; i++) {
885 		ar = ISTC_READ(sc, STC_MRAR) & CD180_GSVR_IMASK;
886 		if (ar == CD180_GSVR_STATCHG)
887 			r |= spif_stcintr_mx(sc, &needsoft);
888 	}
889 
890 	if (needsoft)
891 		softint_schedule(sc->sc_softih);
892 	return (r);
893 }
894 
895 void
896 spif_softintr(void *vsc)
897 {
898 	struct spif_softc *sc = (struct spif_softc *)vsc;
899 	struct stty_softc *stc = sc->sc_ttys;
900 	int i, data, s, flags;
901 	uint8_t stat, msvr;
902 	struct stty_port *sp;
903 	struct tty *tp;
904 
905 	if (stc != NULL) {
906 		for (i = 0; i < stc->sc_nports; i++) {
907 			sp = &stc->sc_port[i];
908 			tp = sp->sp_tty;
909 
910 			if (!ISSET(tp->t_state, TS_ISOPEN))
911 				continue;
912 
913 			while (sp->sp_rget != sp->sp_rput) {
914 				stat = sp->sp_rget[0];
915 				data = sp->sp_rget[1];
916 				sp->sp_rget += 2;
917 				if (sp->sp_rget == sp->sp_rend)
918 					sp->sp_rget = sp->sp_rbuf;
919 
920 				if (stat & (CD180_RCSR_BE | CD180_RCSR_FE))
921 					data |= TTY_FE;
922 
923 				if (stat & CD180_RCSR_PE)
924 					data |= TTY_PE;
925 
926 				(*tp->t_linesw->l_rint)(data, tp);
927 			}
928 
929 			s = splhigh();
930 			flags = sp->sp_flags;
931 			CLR(sp->sp_flags, STTYF_DONE | STTYF_CDCHG |
932 			    STTYF_RING_OVERFLOW);
933 			splx(s);
934 
935 			if (ISSET(flags, STTYF_CDCHG)) {
936 				s = spltty();
937 				STC_WRITE(sc, STC_CAR, i);
938 				msvr = STC_READ(sc, STC_MSVR);
939 				splx(s);
940 
941 				sp->sp_carrier = msvr & CD180_MSVR_CD;
942 				(*tp->t_linesw->l_modem)(tp,
943 				    sp->sp_carrier);
944 			}
945 
946 			if (ISSET(flags, STTYF_RING_OVERFLOW)) {
947 				log(LOG_WARNING, "%s-%x: ring overflow\n",
948 					device_xname(stc->sc_dev), i);
949 			}
950 
951 			if (ISSET(flags, STTYF_DONE)) {
952 				ndflush(&tp->t_outq,
953 				    sp->sp_txp - tp->t_outq.c_cf);
954 				CLR(tp->t_state, TS_BUSY);
955 				(*tp->t_linesw->l_start)(tp);
956 			}
957 		}
958 	}
959 }
960 
961 void
962 stty_write_ccr(struct spif_softc *sc, uint8_t val)
963 {
964 	int tries = 100000;
965 
966 	while (STC_READ(sc, STC_CCR) && tries--)
967 		/*EMPTY*/;
968 	if (tries == 0)
969 		aprint_error_dev(sc->sc_dev, "ccr timeout\n");
970 	STC_WRITE(sc, STC_CCR, val);
971 }
972 
973 int
974 stty_compute_baud(speed_t speed, int clock, uint8_t *bprlp, uint8_t *bprhp)
975 {
976 	uint32_t rate;
977 
978 	rate = (2 * clock) / (16 * speed);
979 	if (rate & 1)
980 		rate = (rate >> 1) + 1;
981 	else
982 		rate = rate >> 1;
983 
984 	if (rate > 0xffff || rate == 0)
985 		return (1);
986 
987 	*bprlp = rate & 0xff;
988 	*bprhp = (rate >> 8) & 0xff;
989 	return (0);
990 }
991 
992 int
993 sbpp_match(device_t parent, cfdata_t vcf, void *aux)
994 {
995 	struct spif_softc *sc = device_private(parent);
996 
997 	return (aux == sbpp_match && sc->sc_bpps == NULL);
998 }
999 
1000 void
1001 sbpp_attach(device_t parent, device_t dev, void *aux)
1002 {
1003 	struct spif_softc *sc = device_private(parent);
1004 	struct sbpp_softc *psc = device_private(dev);
1005 	int port;
1006 
1007 	sc->sc_bpps = psc;
1008 
1009 	for (port = 0; port < sc->sc_npar; port++) {
1010 	}
1011 
1012 	psc->sc_nports = port;
1013 	printf(": %d port%s\n", port, port == 1 ? "" : "s");
1014 }
1015 
1016 int
1017 sbpp_open(dev_t dev, int flags, int mode, struct lwp *l)
1018 {
1019 	return (ENXIO);
1020 }
1021 
1022 int
1023 sbpp_close(dev_t dev, int flags, int mode, struct lwp *l)
1024 {
1025 	return (ENXIO);
1026 }
1027 
1028 int
1029 spif_ppcintr(void *v)
1030 {
1031 	return (0);
1032 }
1033 
1034 int
1035 sbpp_read(dev_t dev, struct uio *uio, int flags)
1036 {
1037 	return (sbpp_rw(dev, uio));
1038 }
1039 
1040 int
1041 sbpp_write(dev_t dev, struct uio *uio, int flags)
1042 {
1043 	return (sbpp_rw(dev, uio));
1044 }
1045 
1046 int
1047 sbpp_rw(dev_t dev, struct uio *uio)
1048 {
1049 	return (ENXIO);
1050 }
1051 
1052 int
1053 sbpp_poll(dev_t dev, int events, struct lwp *l)
1054 {
1055 	return (seltrue(dev, events, l));
1056 }
1057 
1058 int
1059 sbpp_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
1060 {
1061 	int error;
1062 
1063 	error = ENOTTY;
1064 
1065 	return (error);
1066 }
1067 
1068 #endif /* NSPIF */
1069