xref: /openbsd-src/sys/dev/sbus/magma.c (revision 850e275390052b330d93020bf619a739a3c277ac)
1 /*	$OpenBSD: magma.c,v 1.15 2005/07/09 22:23:15 miod Exp $	*/
2 /*
3  * magma.c
4  *
5  * Copyright (c) 1998 Iain Hibbert
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  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by Iain Hibbert
19  * 4. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33 #define MAGMA_DEBUG
34  */
35 
36 /*
37  * Driver for Magma SBus Serial/Parallel cards using the Cirrus Logic
38  * CD1400 & CD1190 chips
39  */
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/proc.h>
44 #include <sys/device.h>
45 #include <sys/file.h>
46 #include <sys/ioctl.h>
47 #include <sys/malloc.h>
48 #include <sys/tty.h>
49 #include <sys/time.h>
50 #include <sys/kernel.h>
51 #include <sys/syslog.h>
52 #include <sys/conf.h>
53 #include <sys/errno.h>
54 
55 #include <machine/autoconf.h>
56 #include <machine/conf.h>
57 #include <machine/bus.h>
58 #include <machine/bppioctl.h>
59 
60 #include <dev/sbus/sbusvar.h>
61 #include <dev/ic/cd1400reg.h>
62 #include <dev/ic/cd1190reg.h>
63 
64 #include <dev/sbus/magmareg.h>
65 
66 /* supported cards
67  *
68  *  The table below lists the cards that this driver is likely to
69  *  be able to support.
70  *
71  *  Cards with parallel ports: except for the LC2+1Sp, they all use
72  *  the CD1190 chip which I know nothing about.  I've tried to leave
73  *  hooks for it so it shouldn't be too hard to add support later.
74  *  (I think somebody is working on this separately)
75  *
76  *  Thanks to Bruce at Magma for telling me the hardware offsets.
77  */
78 static const struct magma_board_info supported_cards[] = {
79 	{
80 		"MAGMA_Sp", "MAGMA,4_Sp", "Magma 4 Sp", 4, 0,
81 		1, 0xa000, 0xc000, 0xe000, { 0x8000, 0, 0, 0 },
82 		0, { 0, 0 }
83 	},
84 	{
85 		"MAGMA_Sp", "MAGMA,8_Sp", "Magma 8 Sp", 8, 0,
86 		2, 0xa000, 0xc000, 0xe000, { 0x4000, 0x6000, 0, 0 },
87 		0, { 0, 0 }
88 	},
89 	{
90 		"MAGMA_Sp", "MAGMA,_8HS_Sp", "Magma Fast 8 Sp", 8, 0,
91 		2, 0x2000, 0x4000, 0x6000, { 0x8000, 0xa000, 0, 0 },
92 		0, { 0, 0 }
93 	},
94 	{
95 		"MAGMA_Sp", "MAGMA,_8SP_422", "Magma 8 Sp - 422", 8, 0,
96 		2, 0x2000, 0x4000, 0x6000, { 0x8000, 0xa000, 0, 0 },
97 		0, { 0, 0 }
98 	},
99 	{
100 		"MAGMA_Sp", "MAGMA,12_Sp", "Magma 12 Sp", 12, 0,
101 		3, 0xa000, 0xc000, 0xe000, { 0x2000, 0x4000, 0x6000, 0 },
102 		0, { 0, 0 }
103 	},
104 	{
105 		"MAGMA_Sp", "MAGMA,16_Sp", "Magma 16 Sp", 16, 0,
106 		4, 0xd000, 0xe000, 0xf000, { 0x8000, 0x9000, 0xa000, 0xb000 },
107 		0, { 0, 0 }
108 	},
109 	{
110 		"MAGMA_Sp", "MAGMA,16_Sp_2", "Magma 16 Sp", 16, 0,
111 		4, 0x2000, 0x4000, 0x6000, { 0x8000, 0xa000, 0xc000, 0xe000 },
112 		0, { 0, 0 }
113 	},
114 	{
115 		"MAGMA_Sp", "MAGMA,16HS_Sp", "Magma Fast 16 Sp", 16, 0,
116 		4, 0x2000, 0x4000, 0x6000, { 0x8000, 0xa000, 0xc000, 0xe000 },
117 		0, { 0, 0 }
118 	},
119 	{
120 		"MAGMA_Sp", "MAGMA,21_Sp", "Magma LC 2+1 Sp", 2, 1,
121 		1, 0xa000, 0xc000, 0xe000, { 0x8000, 0, 0, 0 },
122 		0, { 0, 0 }
123 	},
124 	{
125 		"MAGMA_Sp", "MAGMA,21HS_Sp", "Magma 2+1 Sp", 2, 1,
126 		1, 0xa000, 0xc000, 0xe000, { 0x4000, 0, 0, 0 },
127 		1, { 0x6000, 0 }
128 	},
129 	{
130 		"MAGMA_Sp", "MAGMA,41_Sp", "Magma 4+1 Sp", 4, 1,
131 		1, 0xa000, 0xc000, 0xe000, { 0x4000, 0, 0, 0 },
132 		1, { 0x6000, 0 }
133 	},
134 	{
135 		"MAGMA_Sp", "MAGMA,82_Sp", "Magma 8+2 Sp", 8, 2,
136 		2, 0xd000, 0xe000, 0xf000, { 0x8000, 0x9000, 0, 0 },
137 		2, { 0xa000, 0xb000 }
138 	},
139 	{
140 		"MAGMA_Sp", "MAGMA,P1_Sp", "Magma P1 Sp", 0, 1,
141 		0, 0, 0, 0, { 0, 0, 0, 0 },
142 		1, { 0x8000, 0 }
143 	},
144 	{
145 		"MAGMA_Sp", "MAGMA,P2_Sp", "Magma P2 Sp", 0, 2,
146 		0, 0, 0, 0, { 0, 0, 0, 0 },
147 		2, { 0x4000, 0x8000 }
148 	},
149 	{
150 		"MAGMA 2+1HS Sp", "", "Magma 2+1HS Sp", 2, 0,
151 		1, 0xa000, 0xc000, 0xe000, { 0x4000, 0, 0, 0 },
152 		1, { 0x8000, 0 }
153 	},
154 	{
155 		NULL, NULL, NULL, 0, 0,
156 		0, 0, 0, 0, { 0, 0, 0, 0 },
157 		0, { 0, 0 }
158 	}
159 };
160 
161 /************************************************************************
162  *
163  *  Autoconfig Stuff
164  */
165 
166 struct cfattach magma_ca = {
167 	sizeof(struct magma_softc), magma_match, magma_attach
168 };
169 
170 struct cfdriver magma_cd = {
171 	NULL, "magma", DV_DULL
172 };
173 
174 struct cfattach mtty_ca = {
175 	sizeof(struct mtty_softc), mtty_match, mtty_attach
176 };
177 
178 struct cfdriver mtty_cd = {
179 	NULL, "mtty", DV_TTY
180 };
181 
182 struct cfattach mbpp_ca = {
183 	sizeof(struct mbpp_softc), mbpp_match, mbpp_attach
184 };
185 
186 struct cfdriver mbpp_cd = {
187 	NULL, "mbpp", DV_DULL
188 };
189 
190 /************************************************************************
191  *
192  *  CD1400 Routines
193  *
194  *	cd1400_compute_baud		calculate COR/BPR register values
195  *	cd1400_write_ccr		write a value to CD1400 ccr
196  *	cd1400_read_reg			read from a CD1400 register
197  *	cd1400_write_reg		write to a CD1400 register
198  *	cd1400_enable_transmitter	enable transmitting on CD1400 channel
199  */
200 
201 /*
202  * compute the bpr/cor pair for any baud rate
203  * returns 0 for success, 1 for failure
204  */
205 int
206 cd1400_compute_baud(speed_t speed, int clock, int *cor, int *bpr)
207 {
208 	int c, co, br;
209 
210 	if (speed < 50 || speed > 150000)
211 		return (1);
212 
213 	for (c = 0, co = 8 ; co <= 2048 ; co <<= 2, c++) {
214 		br = ((clock * 1000000) + (co * speed) / 2) / (co * speed);
215 		if (br < 0x100) {
216 			*bpr = br;
217 			*cor = c;
218 			return (0);
219 		}
220 	}
221 
222 	return (1);
223 }
224 
225 #define	CD1400_READ_REG(cd,reg) \
226     bus_space_read_1((cd)->cd_regt, (cd)->cd_regh, (reg))
227 #define	CD1400_WRITE_REG(cd,reg,value) \
228     bus_space_write_1((cd)->cd_regt, (cd)->cd_regh, (reg), (value))
229 
230 /*
231  * Write a CD1400 channel command, should have a timeout?
232  */
233 __inline void
234 cd1400_write_ccr(struct cd1400 *cd, u_char cmd)
235 {
236 	while (CD1400_READ_REG(cd, CD1400_CCR))
237 		/*EMPTY*/;
238 
239 	CD1400_WRITE_REG(cd, CD1400_CCR, cmd);
240 }
241 
242 /*
243  * enable transmit service requests for cd1400 channel
244  */
245 void
246 cd1400_enable_transmitter(struct cd1400 *cd, int channel)
247 {
248 	int s, srer;
249 
250 	s = spltty();
251 	CD1400_WRITE_REG(cd, CD1400_CAR, channel);
252 	srer = CD1400_READ_REG(cd, CD1400_SRER);
253 	SET(srer, CD1400_SRER_TXRDY);
254 	CD1400_WRITE_REG(cd, CD1400_SRER, srer);
255 	splx(s);
256 }
257 
258 /************************************************************************
259  *
260  *  CD1190 Routines
261  */
262 
263 /* well, there are none yet */
264 
265 /************************************************************************
266  *
267  *  Magma Routines
268  *
269  * magma_match		reports if we have a magma board available
270  * magma_attach		attaches magma boards to the sbus
271  * magma_hard		hardware level interrupt routine
272  * magma_soft		software level interrupt routine
273  */
274 
275 int
276 magma_match(struct device *parent, void *vcf, void *aux)
277 {
278 	struct sbus_attach_args *sa = aux;
279 	const struct magma_board_info *card;
280 
281 	/* See if we support this device */
282 	for (card = supported_cards; ; card++) {
283 		if (card->mb_sbusname == NULL)
284 			/* End of table: no match */
285 			return (0);
286 		if (strcmp(sa->sa_name, card->mb_sbusname) == 0)
287 			break;
288 	}
289 	return (1);
290 }
291 
292 void
293 magma_attach(struct device *parent, struct device *dev, void *aux)
294 {
295 	struct sbus_attach_args *sa = aux;
296 	struct magma_softc *sc = (struct magma_softc *)dev;
297 	const struct magma_board_info *card;
298 	char magma_prom[40], *clockstr;
299 	int chip, cd_clock;
300 
301 	getpropstringA(sa->sa_node, "magma_prom", magma_prom);
302 	for (card = supported_cards; card->mb_name != NULL; card++) {
303 		if (strcmp(sa->sa_name, card->mb_sbusname) != 0)
304 			continue;
305 		if (strcmp(magma_prom, card->mb_name) == 0)
306 			break;
307 	}
308 	if (card->mb_name == NULL) {
309 		printf(": %s (unsupported)\n", magma_prom);
310 		return;
311 	}
312 
313 	sc->sc_bustag = sa->sa_bustag;
314 
315 	clockstr = getpropstring(sa->sa_node, "clock");
316 	if (strlen(clockstr) == 0)
317 		cd_clock = 25;
318 	else {
319 		cd_clock = 0;
320 		while (*clockstr != '\0')
321 			cd_clock = cd_clock * 10 + *clockstr++ - '0';
322 	}
323 
324 	if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
325 	    sa->sa_reg[0].sbr_offset, sa->sa_reg[0].sbr_size,
326 	    0, 0, &sc->sc_iohandle) != 0) {
327 		printf(": can't map registers\n");
328 		return;
329 	}
330 
331 	if (sa->sa_nintr < 1) {
332 		printf(": can't find interrupt\n");
333 		return;
334 	}
335 	sc->sc_ih = bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_TTY, 0,
336 	    magma_hard, sc, dev->dv_xname);
337 	if (sc->sc_ih == NULL) {
338 		printf(": couldn't establish interrupt, pri %d\n",
339 		    INTLEV(sa->sa_pri));
340 		bus_space_unmap(sc->sc_bustag, sc->sc_iohandle,
341 		    sa->sa_reg[0].sbr_size);
342 		return;
343 	}
344 
345 	sc->sc_sih = softintr_establish(IPL_TTY, magma_soft, sc);
346 	if (sc->sc_sih == NULL) {
347 		printf(": can't get soft intr\n");
348 		bus_space_unmap(sc->sc_bustag, sc->sc_iohandle,
349 		    sa->sa_reg[0].sbr_size);
350 		return;
351 	}
352 
353 	printf(": %s\n", card->mb_realname);
354 
355 	sc->ms_board = card;
356 	sc->ms_ncd1400 = card->mb_ncd1400;
357 	sc->ms_ncd1190 = card->mb_ncd1190;
358 
359 	/* the SVCACK* lines are daisychained */
360 	if (bus_space_subregion(sc->sc_bustag, sc->sc_iohandle,
361 	    card->mb_svcackr, 1, &sc->sc_svcackrh)) {
362 		printf(": failed to map svcackr\n");
363 		return;
364 	}
365 	if (bus_space_subregion(sc->sc_bustag, sc->sc_iohandle,
366 	    card->mb_svcackt, 1, &sc->sc_svcackth)) {
367 		printf(": failed to map svcackt\n");
368 		return;
369 	}
370 	if (bus_space_subregion(sc->sc_bustag, sc->sc_iohandle,
371 	    card->mb_svcackm, 1, &sc->sc_svcackmh)) {
372 		printf(": failed to map svcackm\n");
373 		return;
374 	}
375 
376 	/* init the cd1400 chips */
377 	for (chip = 0 ; chip < card->mb_ncd1400 ; chip++) {
378 		struct cd1400 *cd = &sc->ms_cd1400[chip];
379 
380 		cd->cd_clock = cd_clock;
381 
382 		if (bus_space_subregion(sc->sc_bustag, sc->sc_iohandle,
383 		    card->mb_cd1400[chip], CD1400_REGMAPSIZE, &cd->cd_regh)) {
384 			printf(": failed to map cd1400 regs\n");
385 			return;
386 		}
387 		cd->cd_regt = sc->sc_bustag;
388 
389 		/* getpropstring(sa->sa_node, "chiprev"); */
390 		/* seemingly the Magma drivers just ignore the propstring */
391 		cd->cd_chiprev = CD1400_READ_REG(cd, CD1400_GFRCR);
392 
393 		dprintf(("%s attach CD1400 %d addr 0x%x rev %x clock %dMHz\n",
394 			    sc->ms_dev.dv_xname, chip, cd->cd_reg,
395 			    cd->cd_chiprev, cd->cd_clock));
396 
397 		/* clear GFRCR */
398 		CD1400_WRITE_REG(cd, CD1400_GFRCR, 0x00);
399 
400 		/* reset whole chip */
401 		cd1400_write_ccr(cd,
402 		    CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET);
403 
404 		/* wait for revision code to be restored */
405 		while (CD1400_READ_REG(cd, CD1400_GFRCR) != cd->cd_chiprev)
406 		        ;
407 
408 		/* set the Prescaler Period Register to tick at 1ms */
409 		CD1400_WRITE_REG(cd, CD1400_PPR,
410 		    ((cd->cd_clock * 1000000 / CD1400_PPR_PRESCALER + 500)
411 		    / 1000));
412 
413 		/*
414 		 * The LC2+1Sp card is the only card that doesn't have a
415 		 * CD1190 for the parallel port, but uses channel 0 of the
416 		 * CD1400, so we make a note of it for later and set up the
417 		 * CD1400 for parallel mode operation.
418 		 */
419 		if (card->mb_npar && card->mb_ncd1190 == 0) {
420 			CD1400_WRITE_REG(cd, CD1400_GCR, CD1400_GCR_PARALLEL);
421 			cd->cd_parmode = 1;
422 		}
423 	}
424 
425 	/* init the cd1190 chips */
426 	for (chip = 0 ; chip < card->mb_ncd1190 ; chip++) {
427 		struct cd1190 *cd = &sc->ms_cd1190[chip];
428 
429 		if (bus_space_subregion(sc->sc_bustag, sc->sc_iohandle,
430 		    card->mb_cd1190[chip], CD1190_REGMAPSIZE, &cd->cd_regh)) {
431 			printf(": failed to map cd1190 regs\n");
432 			return;
433 		}
434 		cd->cd_regt = sc->sc_bustag;
435 		dprintf(("%s attach CD1190 %d addr 0x%x (failed)\n",
436 		    sc->ms_dev.dv_xname, chip, cd->cd_reg));
437 		/* XXX don't know anything about these chips yet */
438 	}
439 
440 	/* configure the children */
441 	(void)config_found(dev, mtty_match, NULL);
442 	(void)config_found(dev, mbpp_match, NULL);
443 }
444 
445 /*
446  * hard interrupt routine
447  *
448  *  returns 1 if it handled it, otherwise 0
449  *
450  *  runs at interrupt priority
451  */
452 int
453 magma_hard(void *arg)
454 {
455 	struct magma_softc *sc = arg;
456 	struct cd1400 *cd;
457 	int chip, status = 0;
458 	int serviced = 0;
459 	int needsoftint = 0;
460 
461 	/*
462 	 * check status of all the CD1400 chips
463 	 */
464 	for (chip = 0 ; chip < sc->ms_ncd1400 ; chip++)
465 		status |= CD1400_READ_REG(&sc->ms_cd1400[chip], CD1400_SVRR);
466 
467 	if (ISSET(status, CD1400_SVRR_RXRDY)) {
468 		/* enter rx service context */
469 		u_int8_t rivr = bus_space_read_1(sc->sc_bustag, sc->sc_svcackrh, 0);
470 		int port = rivr >> 4;
471 
472 		if (rivr & (1<<3)) {			/* parallel port */
473 			struct mbpp_port *mbpp;
474 			int n_chars;
475 
476 			mbpp = &sc->ms_mbpp->ms_port[port];
477 			cd = mbpp->mp_cd1400;
478 
479 			/* don't think we have to handle exceptions */
480 			n_chars = CD1400_READ_REG(cd, CD1400_RDCR);
481 			while (n_chars--) {
482 				if (mbpp->mp_cnt == 0) {
483 					SET(mbpp->mp_flags, MBPPF_WAKEUP);
484 					needsoftint = 1;
485 					break;
486 				}
487 				*mbpp->mp_ptr = CD1400_READ_REG(cd, CD1400_RDSR);
488 				mbpp->mp_ptr++;
489 				mbpp->mp_cnt--;
490 			}
491 		} else {				/* serial port */
492 			struct mtty_port *mtty;
493 			u_char *ptr, n_chars, line_stat;
494 
495 			mtty = &sc->ms_mtty->ms_port[port];
496 			cd = mtty->mp_cd1400;
497 
498 			if (ISSET(rivr, CD1400_RIVR_EXCEPTION)) {
499 				line_stat = CD1400_READ_REG(cd, CD1400_RDSR);
500 				n_chars = 1;
501 			} else { /* no exception, received data OK */
502 				line_stat = 0;
503 				n_chars = CD1400_READ_REG(cd, CD1400_RDCR);
504 			}
505 
506 			ptr = mtty->mp_rput;
507 			while (n_chars--) {
508 				*ptr++ = line_stat;
509 				*ptr++ = CD1400_READ_REG(cd, CD1400_RDSR);
510 				if (ptr == mtty->mp_rend)
511 					ptr = mtty->mp_rbuf;
512 				if (ptr == mtty->mp_rget) {
513 					if (ptr == mtty->mp_rbuf)
514 						ptr = mtty->mp_rend;
515 					ptr -= 2;
516 					SET(mtty->mp_flags,
517 					    MTTYF_RING_OVERFLOW);
518 					break;
519 				}
520 			}
521 			mtty->mp_rput = ptr;
522 
523 			needsoftint = 1;
524 		}
525 
526 		CD1400_WRITE_REG(cd, CD1400_EOSRR, 0);	/* end service context */
527 		serviced = 1;
528 	} /* if(rx_service...) */
529 
530 	if (ISSET(status, CD1400_SVRR_MDMCH)) {
531 		u_int8_t mivr = bus_space_read_1(sc->sc_bustag, sc->sc_svcackmh, 0);
532 		int port = mivr >> 4;
533 		struct mtty_port *mtty;
534 		int carrier;
535 		u_char msvr;
536 
537 		/*
538 		 * Handle CD (LC2+1Sp = DSR) changes.
539 		 */
540 		mtty = &sc->ms_mtty->ms_port[port];
541 		cd = mtty->mp_cd1400;
542 		msvr = CD1400_READ_REG(cd, CD1400_MSVR2);
543 		carrier = ISSET(msvr, cd->cd_parmode ? CD1400_MSVR2_DSR : CD1400_MSVR2_CD);
544 
545 		if (mtty->mp_carrier != carrier) {
546 			SET(mtty->mp_flags, MTTYF_CARRIER_CHANGED);
547 			mtty->mp_carrier = carrier;
548 			needsoftint = 1;
549 		}
550 
551 		CD1400_WRITE_REG(cd, CD1400_EOSRR, 0);	/* end service context */
552 		serviced = 1;
553 	} /* if(mdm_service...) */
554 
555 	if (ISSET(status, CD1400_SVRR_TXRDY)) {
556 		/* enter tx service context */
557 		u_int8_t tivr = bus_space_read_1(sc->sc_bustag, sc->sc_svcackth, 0);
558 		int port = tivr >> 4;
559 
560 		if (tivr & (1<<3)) {	/* parallel port */
561 			struct mbpp_port *mbpp;
562 
563 			mbpp = &sc->ms_mbpp->ms_port[port];
564 			cd = mbpp->mp_cd1400;
565 
566 			if (mbpp->mp_cnt) {
567 				int count = 0;
568 
569 				/* fill the fifo */
570 				while (mbpp->mp_cnt && count++ < CD1400_PAR_FIFO_SIZE) {
571 					CD1400_WRITE_REG(cd, CD1400_TDR, *mbpp->mp_ptr);
572 					mbpp->mp_ptr++;
573 					mbpp->mp_cnt--;
574 				}
575 			} else {
576 				/* fifo is empty and we got no more data to send, so shut
577 				 * off interrupts and signal for a wakeup, which can't be
578 				 * done here in case we beat mbpp_send to the tsleep call
579 				 * (we are running at >spltty)
580 				 */
581 				CD1400_WRITE_REG(cd, CD1400_SRER, 0);
582 				SET(mbpp->mp_flags, MBPPF_WAKEUP);
583 				needsoftint = 1;
584 			}
585 		} else {		/* serial port */
586 			struct mtty_port *mtty;
587 			struct tty *tp;
588 
589 			mtty = &sc->ms_mtty->ms_port[port];
590 			cd = mtty->mp_cd1400;
591 			tp = mtty->mp_tty;
592 
593 			if (!ISSET(mtty->mp_flags, MTTYF_STOP)) {
594 				int count = 0;
595 
596 				/* check if we should start/stop a break */
597 				if (ISSET(mtty->mp_flags, MTTYF_SET_BREAK)) {
598 					CD1400_WRITE_REG(cd, CD1400_TDR, 0);
599 					CD1400_WRITE_REG(cd, CD1400_TDR, 0x81);
600 					/* should we delay too? */
601 					CLR(mtty->mp_flags, MTTYF_SET_BREAK);
602 					count += 2;
603 				}
604 
605 				if (ISSET(mtty->mp_flags, MTTYF_CLR_BREAK)) {
606 					CD1400_WRITE_REG(cd, CD1400_TDR, 0);
607 					CD1400_WRITE_REG(cd, CD1400_TDR, 0x83);
608 					CLR(mtty->mp_flags, MTTYF_CLR_BREAK);
609 					count += 2;
610 				}
611 
612 				/* I don't quite fill the fifo in case the last one is a
613 				 * NULL which I have to double up because its the escape
614 				 * code for embedded transmit characters.
615 				 */
616 				while (mtty->mp_txc > 0 && count < CD1400_TX_FIFO_SIZE - 1) {
617 					u_char ch;
618 
619 					ch = *mtty->mp_txp;
620 
621 					mtty->mp_txc--;
622 					mtty->mp_txp++;
623 
624 					if (ch == 0) {
625 						CD1400_WRITE_REG(cd, CD1400_TDR, ch);
626 						count++;
627 					}
628 
629 					CD1400_WRITE_REG(cd, CD1400_TDR, ch);
630 					count++;
631 				}
632 			}
633 
634 			/* if we ran out of work or are requested to STOP then
635 			 * shut off the txrdy interrupts and signal DONE to flush
636 			 * out the chars we have sent.
637 			 */
638 			if (mtty->mp_txc == 0 || ISSET(mtty->mp_flags, MTTYF_STOP)) {
639 				int srer;
640 
641 				srer = CD1400_READ_REG(cd, CD1400_SRER);
642 				CLR(srer, CD1400_SRER_TXRDY);
643 				CD1400_WRITE_REG(cd, CD1400_SRER, srer);
644 				CLR(mtty->mp_flags, MTTYF_STOP);
645 
646 				SET(mtty->mp_flags, MTTYF_DONE);
647 				needsoftint = 1;
648 			}
649 		}
650 
651 		CD1400_WRITE_REG(cd, CD1400_EOSRR, 0);	/* end service context */
652 		serviced = 1;
653 	} /* if(tx_service...) */
654 
655 	/* XXX service CD1190 interrupts too
656 	for (chip = 0 ; chip < sc->ms_ncd1190 ; chip++) {
657 	}
658 	*/
659 
660 	if (needsoftint)
661 		softintr_schedule(sc->sc_sih);
662 
663 	return (serviced);
664 }
665 
666 /*
667  * magma soft interrupt handler
668  *
669  *  returns 1 if it handled it, 0 otherwise
670  *
671  *  runs at spltty()
672  */
673 void
674 magma_soft(void *arg)
675 {
676 	struct magma_softc *sc = arg;
677 	struct mtty_softc *mtty = sc->ms_mtty;
678 	struct mbpp_softc *mbpp = sc->ms_mbpp;
679 	int port;
680 	int serviced = 0;
681 	int s, flags;
682 
683 	/*
684 	 * check the tty ports (if any) to see what needs doing
685 	 */
686 	if (mtty) {
687 		for (port = 0 ; port < mtty->ms_nports ; port++) {
688 			struct mtty_port *mp = &mtty->ms_port[port];
689 			struct tty *tp = mp->mp_tty;
690 
691 			if (!ISSET(tp->t_state, TS_ISOPEN))
692 				continue;
693 
694 			/*
695 			 * handle any received data
696 			 */
697 			while (mp->mp_rget != mp->mp_rput) {
698 				u_char stat;
699 				int data;
700 
701 				stat = mp->mp_rget[0];
702 				data = mp->mp_rget[1];
703 				mp->mp_rget = ((mp->mp_rget + 2) == mp->mp_rend) ? mp->mp_rbuf : (mp->mp_rget + 2);
704 
705 				if (stat & (CD1400_RDSR_BREAK | CD1400_RDSR_FE))
706 					data |= TTY_FE;
707 				if (stat & CD1400_RDSR_PE)
708 					data |= TTY_PE;
709 
710 				if (stat & CD1400_RDSR_OE)
711 					log(LOG_WARNING, "%s%x: fifo overflow\n", mtty->ms_dev.dv_xname, port);
712 
713 				(*linesw[tp->t_line].l_rint)(data, tp);
714 				serviced = 1;
715 			}
716 
717 			s = splhigh();	/* block out hard interrupt routine */
718 			flags = mp->mp_flags;
719 			CLR(mp->mp_flags, MTTYF_DONE | MTTYF_CARRIER_CHANGED | MTTYF_RING_OVERFLOW);
720 			splx(s);	/* ok */
721 
722 			if (ISSET(flags, MTTYF_CARRIER_CHANGED)) {
723 				dprintf(("%s%x: cd %s\n", mtty->ms_dev.dv_xname, port, mp->mp_carrier ? "on" : "off"));
724 				(*linesw[tp->t_line].l_modem)(tp, mp->mp_carrier);
725 				serviced = 1;
726 			}
727 
728 			if (ISSET(flags, MTTYF_RING_OVERFLOW)) {
729 				log(LOG_WARNING, "%s%x: ring buffer overflow\n", mtty->ms_dev.dv_xname, port);
730 				serviced = 1;
731 			}
732 
733 			if (ISSET(flags, MTTYF_DONE)) {
734 				ndflush(&tp->t_outq, mp->mp_txp - tp->t_outq.c_cf);
735 				CLR(tp->t_state, TS_BUSY);
736 				(*linesw[tp->t_line].l_start)(tp);	/* might be some more */
737 				serviced = 1;
738 			}
739 		} /* for (each mtty...) */
740 	}
741 
742 	/*
743 	 * check the bpp ports (if any) to see what needs doing
744 	 */
745 	if (mbpp) {
746 		for (port = 0 ; port < mbpp->ms_nports ; port++) {
747 			struct mbpp_port *mp = &mbpp->ms_port[port];
748 
749 			if (!ISSET(mp->mp_flags, MBPPF_OPEN))
750 				continue;
751 
752 			s = splhigh();	/* block out hard intr routine */
753 			flags = mp->mp_flags;
754 			CLR(mp->mp_flags, MBPPF_WAKEUP);
755 			splx(s);
756 
757 			if (ISSET(flags, MBPPF_WAKEUP)) {
758 				wakeup(mp);
759 				serviced = 1;
760 			}
761 		} /* for (each mbpp...) */
762 	}
763 }
764 
765 /************************************************************************
766  *
767  *  MTTY Routines
768  *
769  *	mtty_match		match one mtty device
770  *	mtty_attach		attach mtty devices
771  *	mttyopen		open mtty device
772  *	mttyclose		close mtty device
773  *	mttyread		read from mtty
774  *	mttywrite		write to mtty
775  *	mttyioctl		do ioctl on mtty
776  *	mttytty			return tty pointer for mtty
777  *	mttystop		stop mtty device
778  *	mtty_start		start mtty device
779  *	mtty_param		set mtty parameters
780  *	mtty_modem_control	set modem control lines
781  */
782 
783 int
784 mtty_match(struct device *parent, void *vcf, void *args)
785 {
786 	struct magma_softc *sc = (struct magma_softc *)parent;
787 
788 	return (args == mtty_match && sc->ms_board->mb_nser &&
789 	    sc->ms_mtty == NULL);
790 }
791 
792 void
793 mtty_attach(struct device *parent, struct device *dev, void *args)
794 {
795 	struct magma_softc *sc = (struct magma_softc *)parent;
796 	struct mtty_softc *ms = (struct mtty_softc *)dev;
797 	int port, chip, chan;
798 
799 	sc->ms_mtty = ms;
800 	dprintf((" addr 0x%x", ms));
801 
802 	for (port = 0, chip = 0, chan = 0;
803 	     port < sc->ms_board->mb_nser; port++) {
804 		struct mtty_port *mp = &ms->ms_port[port];
805 		struct tty *tp;
806 
807 		mp->mp_cd1400 = &sc->ms_cd1400[chip];
808 		if (mp->mp_cd1400->cd_parmode && chan == 0) {
809 			/* skip channel 0 if parmode */
810 			chan = 1;
811 		}
812 		mp->mp_channel = chan;
813 
814 		tp = ttymalloc();
815 		tp->t_oproc = mtty_start;
816 		tp->t_param = mtty_param;
817 
818 		mp->mp_tty = tp;
819 
820 		mp->mp_rbuf = malloc(MTTY_RBUF_SIZE, M_DEVBUF, M_NOWAIT);
821 		if (mp->mp_rbuf == NULL)
822 			break;
823 
824 		mp->mp_rend = mp->mp_rbuf + MTTY_RBUF_SIZE;
825 
826 		chan = (chan + 1) % CD1400_NO_OF_CHANNELS;
827 		if (chan == 0)
828 			chip++;
829 	}
830 
831 	ms->ms_nports = port;
832 	printf(": %d tty%s\n", port, port == 1 ? "" : "s");
833 }
834 
835 /*
836  * open routine. returns zero if successful, else error code
837  */
838 int
839 mttyopen(dev_t dev, int flags, int mode, struct proc *p)
840 {
841 	int card = MAGMA_CARD(dev);
842 	int port = MAGMA_PORT(dev);
843 	struct mtty_softc *ms;
844 	struct mtty_port *mp;
845 	struct tty *tp;
846 	struct cd1400 *cd;
847 	int s;
848 
849 	if (card >= mtty_cd.cd_ndevs || (ms = mtty_cd.cd_devs[card]) == NULL
850 	    || port >= ms->ms_nports)
851 		return (ENXIO);	/* device not configured */
852 
853 	mp = &ms->ms_port[port];
854 	tp = mp->mp_tty;
855 	tp->t_dev = dev;
856 
857 	if (!ISSET(tp->t_state, TS_ISOPEN)) {
858 		SET(tp->t_state, TS_WOPEN);
859 
860 		/* set defaults */
861 		ttychars(tp);
862 		tp->t_iflag = TTYDEF_IFLAG;
863 		tp->t_oflag = TTYDEF_OFLAG;
864 		tp->t_cflag = TTYDEF_CFLAG;
865 		if (ISSET(mp->mp_openflags, TIOCFLAG_CLOCAL))
866 			SET(tp->t_cflag, CLOCAL);
867 		if (ISSET(mp->mp_openflags, TIOCFLAG_CRTSCTS))
868 			SET(tp->t_cflag, CRTSCTS);
869 		if (ISSET(mp->mp_openflags, TIOCFLAG_MDMBUF))
870 			SET(tp->t_cflag, MDMBUF);
871 		tp->t_lflag = TTYDEF_LFLAG;
872 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
873 
874 		/* init ring buffer */
875 		mp->mp_rput = mp->mp_rget = mp->mp_rbuf;
876 
877 		s = spltty();
878 
879 		/* reset CD1400 channel */
880 		cd = mp->mp_cd1400;
881 		CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel);
882 		cd1400_write_ccr(cd, CD1400_CCR_CMDRESET);
883 
884 		/* encode the port number in top half of LIVR */
885 		CD1400_WRITE_REG(cd, CD1400_LIVR, port << 4);
886 
887 		/* sets parameters and raises DTR */
888 		(void)mtty_param(tp, &tp->t_termios);
889 
890 		/* set tty watermarks */
891 		ttsetwater(tp);
892 
893 		/* enable service requests */
894 		CD1400_WRITE_REG(cd, CD1400_SRER, CD1400_SRER_RXDATA | CD1400_SRER_MDMCH);
895 
896 		/* tell the tty about the carrier status */
897 		if (ISSET(mp->mp_openflags, TIOCFLAG_SOFTCAR) || mp->mp_carrier)
898 			SET(tp->t_state, TS_CARR_ON);
899 		else
900 			CLR(tp->t_state, TS_CARR_ON);
901 	} else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) {
902 		return (EBUSY);	/* superuser can break exclusive access */
903 	} else {
904 		s = spltty();
905 	}
906 
907 	/* wait for carrier if necessary */
908 	if (!ISSET(flags, O_NONBLOCK)) {
909 		while (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) {
910 			int error;
911 
912 			SET(tp->t_state, TS_WOPEN);
913 			error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, "mttydcd", 0);
914 			if (error != 0) {
915 				splx(s);
916 				CLR(tp->t_state, TS_WOPEN);
917 				return (error);
918 			}
919 		}
920 	}
921 
922 	splx(s);
923 
924 	return ((*linesw[tp->t_line].l_open)(dev, tp));
925 }
926 
927 /*
928  * close routine. returns zero if successful, else error code
929  */
930 int
931 mttyclose(dev_t dev, int flag, int mode, struct proc *p)
932 {
933 	struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)];
934 	struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)];
935 	struct tty *tp = mp->mp_tty;
936 	int s;
937 
938 	(*linesw[tp->t_line].l_close)(tp, flag);
939 	s = spltty();
940 
941 	/* if HUPCL is set, and the tty is no longer open
942 	 * shut down the port
943 	 */
944 	if (ISSET(tp->t_cflag, HUPCL) || !ISSET(tp->t_state, TS_ISOPEN)) {
945 	/* XXX wait until FIFO is empty before turning off the channel
946 		struct cd1400 *cd = mp->mp_cd1400;
947 	*/
948 
949 		/* drop DTR and RTS */
950 		(void)mtty_modem_control(mp, 0, DMSET);
951 
952 		/* turn off the channel
953 		CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel);
954 		cd1400_write_ccr(cd, CD1400_CCR_CMDRESET);
955 		*/
956 	}
957 
958 	splx(s);
959 	ttyclose(tp);
960 
961 	return (0);
962 }
963 
964 /*
965  * Read routine
966  */
967 int
968 mttyread(dev_t dev, struct uio *uio, int flags)
969 {
970 	struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)];
971 	struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)];
972 	struct tty *tp = mp->mp_tty;
973 
974 	return ((*linesw[tp->t_line].l_read)(tp, uio, flags));
975 }
976 
977 /*
978  * Write routine
979  */
980 int
981 mttywrite(dev_t dev, struct uio *uio, int flags)
982 {
983 	struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)];
984 	struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)];
985 	struct tty *tp = mp->mp_tty;
986 
987 	return ((*linesw[tp->t_line].l_write)(tp, uio, flags));
988 }
989 
990 /*
991  * return tty pointer
992  */
993 struct tty *
994 mttytty(dev_t dev)
995 {
996 	struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)];
997 	struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)];
998 
999 	return (mp->mp_tty);
1000 }
1001 
1002 /*
1003  * ioctl routine
1004  */
1005 int
1006 mttyioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
1007 {
1008 	struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)];
1009 	struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)];
1010 	struct tty *tp = mp->mp_tty;
1011 	int error;
1012 
1013 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, p);
1014 	if (error >= 0)
1015 		return (error);
1016 
1017 	error = ttioctl(tp, cmd, data, flags, p);
1018 	if (error >= 0)
1019 		return (error);
1020 
1021 	error = 0;
1022 
1023 	switch(cmd) {
1024 	case TIOCSBRK:	/* set break */
1025 		SET(mp->mp_flags, MTTYF_SET_BREAK);
1026 		cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel);
1027 		break;
1028 
1029 	case TIOCCBRK:	/* clear break */
1030 		SET(mp->mp_flags, MTTYF_CLR_BREAK);
1031 		cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel);
1032 		break;
1033 
1034 	case TIOCSDTR:	/* set DTR */
1035 		mtty_modem_control(mp, TIOCM_DTR, DMBIS);
1036 		break;
1037 
1038 	case TIOCCDTR:	/* clear DTR */
1039 		mtty_modem_control(mp, TIOCM_DTR, DMBIC);
1040 		break;
1041 
1042 	case TIOCMSET:	/* set modem lines */
1043 		mtty_modem_control(mp, *((int *)data), DMSET);
1044 		break;
1045 
1046 	case TIOCMBIS:	/* bit set modem lines */
1047 		mtty_modem_control(mp, *((int *)data), DMBIS);
1048 		break;
1049 
1050 	case TIOCMBIC:	/* bit clear modem lines */
1051 		mtty_modem_control(mp, *((int *)data), DMBIC);
1052 		break;
1053 
1054 	case TIOCMGET:	/* get modem lines */
1055 		*((int *)data) = mtty_modem_control(mp, 0, DMGET);
1056 		break;
1057 
1058 	case TIOCGFLAGS:
1059 		*((int *)data) = mp->mp_openflags;
1060 		break;
1061 
1062 	case TIOCSFLAGS:
1063 		if (suser(p, 0))
1064 			error = EPERM;
1065 		else
1066 			mp->mp_openflags = *((int *)data) &
1067 				(TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL |
1068 				TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF);
1069 		break;
1070 
1071 	default:
1072 		error = ENOTTY;
1073 	}
1074 
1075 	return (error);
1076 }
1077 
1078 /*
1079  * Stop output, e.g., for ^S or output flush.
1080  */
1081 int
1082 mttystop(struct tty *tp, int flags)
1083 {
1084 	struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(tp->t_dev)];
1085 	struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(tp->t_dev)];
1086 	int s;
1087 
1088 	s = spltty();
1089 
1090 	if (ISSET(tp->t_state, TS_BUSY)) {
1091 		if (!ISSET(tp->t_state, TS_TTSTOP))
1092 			SET(tp->t_state, TS_FLUSH);
1093 
1094 		/*
1095 		 * the transmit interrupt routine will disable transmit when it
1096 		 * notices that MTTYF_STOP has been set.
1097 		 */
1098 		SET(mp->mp_flags, MTTYF_STOP);
1099 	}
1100 
1101 	splx(s);
1102 	return (0);
1103 }
1104 
1105 /*
1106  * Start output, after a stop.
1107  */
1108 void
1109 mtty_start(struct tty *tp)
1110 {
1111 	struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(tp->t_dev)];
1112 	struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(tp->t_dev)];
1113 	int s;
1114 
1115 	s = spltty();
1116 
1117 	/* we only need to do something if we are not already busy
1118 	 * or delaying or stopped
1119 	 */
1120 	if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) {
1121 
1122 		/* if we are sleeping and output has drained below
1123 		 * low water mark, awaken
1124 		 */
1125 		if (tp->t_outq.c_cc <= tp->t_lowat) {
1126 			if (ISSET(tp->t_state, TS_ASLEEP)) {
1127 				CLR(tp->t_state, TS_ASLEEP);
1128 				wakeup(&tp->t_outq);
1129 			}
1130 
1131 			selwakeup(&tp->t_wsel);
1132 		}
1133 
1134 		/* if something to send, start transmitting
1135 		 */
1136 		if (tp->t_outq.c_cc) {
1137 			mp->mp_txc = ndqb(&tp->t_outq, 0);
1138 			mp->mp_txp = tp->t_outq.c_cf;
1139 			SET(tp->t_state, TS_BUSY);
1140 			cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel);
1141 		}
1142 	}
1143 
1144 	splx(s);
1145 }
1146 
1147 /*
1148  * set/get modem line status
1149  *
1150  * bits can be: TIOCM_DTR, TIOCM_RTS, TIOCM_CTS, TIOCM_CD, TIOCM_RI, TIOCM_DSR
1151  *
1152  * note that DTR and RTS lines are exchanged, and that DSR is
1153  * not available on the LC2+1Sp card (used as CD)
1154  *
1155  * only let them fiddle with RTS if CRTSCTS is not enabled
1156  */
1157 int
1158 mtty_modem_control(struct mtty_port *mp, int bits, int howto)
1159 {
1160 	struct cd1400 *cd = mp->mp_cd1400;
1161 	struct tty *tp = mp->mp_tty;
1162 	int s, msvr;
1163 
1164 	s = spltty();
1165 
1166 	CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel);
1167 
1168 	switch(howto) {
1169 	case DMGET:	/* get bits */
1170 		bits = 0;
1171 
1172 		bits |= TIOCM_LE;
1173 
1174 		msvr = CD1400_READ_REG(cd, CD1400_MSVR1);
1175 		if (msvr & CD1400_MSVR1_RTS)
1176 			bits |= TIOCM_DTR;
1177 
1178 		msvr = CD1400_READ_REG(cd, CD1400_MSVR2);
1179 		if (msvr & CD1400_MSVR2_DTR)
1180 			bits |= TIOCM_RTS;
1181 		if (msvr & CD1400_MSVR2_CTS)
1182 			bits |= TIOCM_CTS;
1183 		if (msvr & CD1400_MSVR2_RI)
1184 			bits |= TIOCM_RI;
1185 		if (msvr & CD1400_MSVR2_DSR)
1186 			bits |= (cd->cd_parmode ? TIOCM_CD : TIOCM_DSR);
1187 		if (msvr & CD1400_MSVR2_CD)
1188 			bits |= (cd->cd_parmode ? 0 : TIOCM_CD);
1189 
1190 		break;
1191 
1192 	case DMSET:	/* reset bits */
1193 		if (!ISSET(tp->t_cflag, CRTSCTS))
1194 			CD1400_WRITE_REG(cd, CD1400_MSVR2,
1195 			    ((bits & TIOCM_RTS) ? CD1400_MSVR2_DTR : 0));
1196 
1197 		CD1400_WRITE_REG(cd, CD1400_MSVR1,
1198 		    ((bits & TIOCM_DTR) ? CD1400_MSVR1_RTS : 0));
1199 
1200 		break;
1201 
1202 	case DMBIS:	/* set bits */
1203 		if ((bits & TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS))
1204 			CD1400_WRITE_REG(cd, CD1400_MSVR2, CD1400_MSVR2_DTR);
1205 
1206 		if (bits & TIOCM_DTR)
1207 			CD1400_WRITE_REG(cd, CD1400_MSVR1, CD1400_MSVR1_RTS);
1208 
1209 		break;
1210 
1211 	case DMBIC:	/* clear bits */
1212 		if ((bits & TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS))
1213 			CD1400_WRITE_REG(cd, CD1400_MSVR2, 0);
1214 
1215 		if (bits & TIOCM_DTR)
1216 			CD1400_WRITE_REG(cd, CD1400_MSVR1, 0);
1217 
1218 		break;
1219 	}
1220 
1221 	splx(s);
1222 	return (bits);
1223 }
1224 
1225 /*
1226  * Set tty parameters, returns error or 0 on success
1227  */
1228 int
1229 mtty_param(struct tty *tp, struct termios *t)
1230 {
1231 	struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(tp->t_dev)];
1232 	struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(tp->t_dev)];
1233 	struct cd1400 *cd = mp->mp_cd1400;
1234 	int rbpr, tbpr, rcor, tcor;
1235 	u_char mcor1 = 0, mcor2 = 0;
1236 	int s, opt;
1237 
1238 	if (t->c_ospeed &&
1239 	    cd1400_compute_baud(t->c_ospeed, cd->cd_clock, &tcor, &tbpr))
1240 		return (EINVAL);
1241 
1242 	if (t->c_ispeed &&
1243 	    cd1400_compute_baud(t->c_ispeed, cd->cd_clock, &rcor, &rbpr))
1244 		return (EINVAL);
1245 
1246 	s = spltty();
1247 
1248 	/* hang up the line if ospeed is zero, else raise DTR */
1249 	(void)mtty_modem_control(mp, TIOCM_DTR,
1250 	    (t->c_ospeed == 0 ? DMBIC : DMBIS));
1251 
1252 	/* select channel, done in mtty_modem_control() */
1253 	/* CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel); */
1254 
1255 	/* set transmit speed */
1256 	if (t->c_ospeed) {
1257 		CD1400_WRITE_REG(cd, CD1400_TCOR, tcor);
1258 		CD1400_WRITE_REG(cd, CD1400_TBPR, tbpr);
1259 	}
1260 
1261 	/* set receive speed */
1262 	if (t->c_ispeed) {
1263 		CD1400_WRITE_REG(cd, CD1400_RCOR, rcor);
1264 		CD1400_WRITE_REG(cd, CD1400_RBPR, rbpr);
1265 	}
1266 
1267 	/* enable transmitting and receiving on this channel */
1268 	opt = CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN | CD1400_CCR_RCVEN;
1269 	cd1400_write_ccr(cd, opt);
1270 
1271 	/* set parity, data and stop bits */
1272 	opt = 0;
1273 	if (ISSET(t->c_cflag, PARENB))
1274 		opt |= (ISSET(t->c_cflag, PARODD) ? CD1400_COR1_PARODD : CD1400_COR1_PARNORMAL);
1275 
1276 	if (!ISSET(t->c_iflag, INPCK))
1277 		opt |= CD1400_COR1_NOINPCK; /* no parity checking */
1278 
1279 	if (ISSET(t->c_cflag, CSTOPB))
1280 		opt |= CD1400_COR1_STOP2;
1281 
1282 	switch( t->c_cflag & CSIZE) {
1283 	case CS5:
1284 		opt |= CD1400_COR1_CS5;
1285 		break;
1286 
1287 	case CS6:
1288 		opt |= CD1400_COR1_CS6;
1289 		break;
1290 
1291 	case CS7:
1292 		opt |= CD1400_COR1_CS7;
1293 		break;
1294 
1295 	default:
1296 		opt |= CD1400_COR1_CS8;
1297 		break;
1298 	}
1299 
1300 	CD1400_WRITE_REG(cd, CD1400_COR1, opt);
1301 
1302 	/*
1303 	 * enable Embedded Transmit Commands (for breaks)
1304 	 * use the CD1400 automatic CTS flow control if CRTSCTS is set
1305 	 */
1306 	opt = CD1400_COR2_ETC;
1307 	if (ISSET(t->c_cflag, CRTSCTS))
1308 		opt |= CD1400_COR2_CCTS_OFLOW;
1309 	CD1400_WRITE_REG(cd, CD1400_COR2, opt);
1310 
1311 	CD1400_WRITE_REG(cd, CD1400_COR3, MTTY_RX_FIFO_THRESHOLD);
1312 
1313 	cd1400_write_ccr(cd, CD1400_CCR_CMDCORCHG | CD1400_CCR_COR1 | CD1400_CCR_COR2 | CD1400_CCR_COR3);
1314 
1315 	CD1400_WRITE_REG(cd, CD1400_COR4, CD1400_COR4_PFO_EXCEPTION);
1316 	CD1400_WRITE_REG(cd, CD1400_COR5, 0);
1317 
1318 	/*
1319 	 * if automatic RTS handshaking enabled, set DTR threshold
1320 	 * (RTS and DTR lines are switched, CD1400 thinks its DTR)
1321 	 */
1322 	if (ISSET(t->c_cflag, CRTSCTS))
1323 		mcor1 = MTTY_RX_DTR_THRESHOLD;
1324 
1325 	/* set up `carrier detect' interrupts */
1326 	if (cd->cd_parmode) {
1327 		SET(mcor1, CD1400_MCOR1_DSRzd);
1328 		SET(mcor2, CD1400_MCOR2_DSRod);
1329 	} else {
1330 		SET(mcor1, CD1400_MCOR1_CDzd);
1331 		SET(mcor2, CD1400_MCOR2_CDod);
1332 	}
1333 
1334 	CD1400_WRITE_REG(cd, CD1400_MCOR1, mcor1);
1335 	CD1400_WRITE_REG(cd, CD1400_MCOR2, mcor2);
1336 
1337 	/* receive timeout 2ms */
1338 	CD1400_WRITE_REG(cd, CD1400_RTPR, 2);
1339 
1340 	splx(s);
1341 	return (0);
1342 }
1343 
1344 /************************************************************************
1345  *
1346  *  MBPP Routines
1347  *
1348  *	mbpp_match	match one mbpp device
1349  *	mbpp_attach	attach mbpp devices
1350  *	mbppopen	open mbpp device
1351  *	mbppclose	close mbpp device
1352  *	mbppread	read from mbpp
1353  *	mbppwrite	write to mbpp
1354  *	mbppioctl	do ioctl on mbpp
1355  *	mbpppoll	do poll on mbpp
1356  *	mbpp_rw		general rw routine
1357  *	mbpp_timeout	rw timeout
1358  *	mbpp_start	rw start after delay
1359  *	mbpp_send	send data
1360  *	mbpp_recv	recv data
1361  */
1362 
1363 int
1364 mbpp_match(struct device *parent, void *vcf, void *args)
1365 {
1366 	struct magma_softc *sc = (struct magma_softc *)parent;
1367 
1368 	return (args == mbpp_match && sc->ms_board->mb_npar &&
1369 	    sc->ms_mbpp == NULL);
1370 }
1371 
1372 void
1373 mbpp_attach(struct device *parent, struct device *dev, void *args)
1374 {
1375 	struct magma_softc *sc = (struct magma_softc *)parent;
1376 	struct mbpp_softc *ms = (struct mbpp_softc *)dev;
1377 	struct mbpp_port *mp;
1378 	int port;
1379 
1380 	sc->ms_mbpp = ms;
1381 	dprintf((" addr 0x%x", ms));
1382 
1383 	for (port = 0 ; port < sc->ms_board->mb_npar ; port++) {
1384 		mp = &ms->ms_port[port];
1385 
1386 		if (sc->ms_ncd1190)
1387 			mp->mp_cd1190 = &sc->ms_cd1190[port];
1388 		else
1389 			mp->mp_cd1400 = &sc->ms_cd1400[0];
1390 
1391 		timeout_set(&mp->mp_timeout_tmo, mbpp_timeout, mp);
1392 		timeout_set(&mp->mp_start_tmo, mbpp_start, mp);
1393 	}
1394 
1395 	ms->ms_nports = port;
1396 	printf(": %d port%s\n", port, port == 1 ? "" : "s");
1397 }
1398 
1399 /*
1400  * open routine. returns zero if successful, else error code
1401  */
1402 int
1403 mbppopen(dev_t dev, int flags, int mode, struct proc *p)
1404 {
1405 	int card = MAGMA_CARD(dev);
1406 	int port = MAGMA_PORT(dev);
1407 	struct mbpp_softc *ms;
1408 	struct mbpp_port *mp;
1409 	int s;
1410 
1411 	if (card >= mbpp_cd.cd_ndevs || (ms = mbpp_cd.cd_devs[card]) == NULL || port >= ms->ms_nports)
1412 		return (ENXIO);
1413 
1414 	mp = &ms->ms_port[port];
1415 
1416 	s = spltty();
1417 	if (ISSET(mp->mp_flags, MBPPF_OPEN)) {
1418 		splx(s);
1419 		return (EBUSY);
1420 	}
1421 	SET(mp->mp_flags, MBPPF_OPEN);
1422 	splx(s);
1423 
1424 	/* set defaults */
1425 	mp->mp_burst = BPP_BURST;
1426 	mp->mp_timeout = mbpp_mstohz(BPP_TIMEOUT);
1427 	mp->mp_delay = mbpp_mstohz(BPP_DELAY);
1428 
1429 	/* init chips */
1430 	if (mp->mp_cd1400) {	/* CD1400 */
1431 		struct cd1400 *cd = mp->mp_cd1400;
1432 
1433 		/* set up CD1400 channel */
1434 		s = spltty();
1435 		CD1400_WRITE_REG(cd, CD1400_CAR, 0);
1436 		cd1400_write_ccr(cd, CD1400_CCR_CMDRESET);
1437 		CD1400_WRITE_REG(cd, CD1400_LIVR, (1<<3));
1438 		splx(s);
1439 	} else {		/* CD1190 */
1440 		mp->mp_flags = 0;
1441 		return (ENXIO);
1442 	}
1443 
1444 	return (0);
1445 }
1446 
1447 /*
1448  * close routine. returns zero if successful, else error code
1449  */
1450 int
1451 mbppclose(dev_t dev, int flag, int mode, struct proc *p)
1452 {
1453 	struct mbpp_softc *ms = mbpp_cd.cd_devs[MAGMA_CARD(dev)];
1454 	struct mbpp_port *mp = &ms->ms_port[MAGMA_PORT(dev)];
1455 
1456 	mp->mp_flags = 0;
1457 	return (0);
1458 }
1459 
1460 /*
1461  * Read routine
1462  */
1463 int
1464 mbppread(dev_t dev, struct uio *uio, int flags)
1465 {
1466 	return (mbpp_rw(dev, uio));
1467 }
1468 
1469 /*
1470  * Write routine
1471  */
1472 int
1473 mbppwrite(dev_t dev, struct uio *uio, int flags)
1474 {
1475 	return (mbpp_rw(dev, uio));
1476 }
1477 
1478 /*
1479  * ioctl routine
1480  */
1481 int
1482 mbppioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
1483 {
1484 	struct mbpp_softc *ms = mbpp_cd.cd_devs[MAGMA_CARD(dev)];
1485 	struct mbpp_port *mp = &ms->ms_port[MAGMA_PORT(dev)];
1486 	struct bpp_param *bp;
1487 	int error = 0;
1488 	int s;
1489 
1490 	switch(cmd) {
1491 	case BPPIOCSPARAM:
1492 		bp = (struct bpp_param *)data;
1493 		if (bp->bp_burst < BPP_BURST_MIN || bp->bp_burst > BPP_BURST_MAX ||
1494 		    bp->bp_delay < BPP_DELAY_MIN || bp->bp_delay > BPP_DELAY_MIN) {
1495 			error = EINVAL;
1496 		} else {
1497 			mp->mp_burst = bp->bp_burst;
1498 			mp->mp_timeout = mbpp_mstohz(bp->bp_timeout);
1499 			mp->mp_delay = mbpp_mstohz(bp->bp_delay);
1500 		}
1501 		break;
1502 	case BPPIOCGPARAM:
1503 		bp = (struct bpp_param *)data;
1504 		bp->bp_burst = mp->mp_burst;
1505 		bp->bp_timeout = mbpp_hztoms(mp->mp_timeout);
1506 		bp->bp_delay = mbpp_hztoms(mp->mp_delay);
1507 		break;
1508 	case BPPIOCGSTAT:
1509 		/* XXX make this more generic */
1510 		s = spltty();
1511 		CD1400_WRITE_REG(mp->mp_cd1400, CD1400_CAR, 0);
1512 		*(int *)data = CD1400_READ_REG(mp->mp_cd1400, CD1400_PSVR);
1513 		splx(s);
1514 		break;
1515 	default:
1516 		error = ENOTTY;
1517 	}
1518 
1519 	return (error);
1520 }
1521 
1522 /*
1523  * poll routine
1524  */
1525 int
1526 mbpppoll(dev_t dev, int events, struct proc *p)
1527 {
1528 	return (seltrue(dev, events, p));
1529 }
1530 
1531 int
1532 mbpp_rw(dev_t dev, struct uio *uio)
1533 {
1534 	int card = MAGMA_CARD(dev);
1535 	int port = MAGMA_PORT(dev);
1536 	struct mbpp_softc *ms = mbpp_cd.cd_devs[card];
1537 	struct mbpp_port *mp = &ms->ms_port[port];
1538 	caddr_t buffer, ptr;
1539 	int buflen, cnt, len;
1540 	int s, error = 0;
1541 	int gotdata = 0;
1542 
1543 	if (uio->uio_resid == 0)
1544 		return (0);
1545 
1546 	buflen = min(uio->uio_resid, mp->mp_burst);
1547 	buffer = malloc(buflen, M_DEVBUF, M_WAITOK);
1548 
1549 	SET(mp->mp_flags, MBPPF_UIO);
1550 
1551 	/*
1552 	 * start timeout, if needed
1553 	 */
1554 	if (mp->mp_timeout > 0) {
1555 		SET(mp->mp_flags, MBPPF_TIMEOUT);
1556 		timeout_add(&mp->mp_timeout_tmo, mp->mp_timeout);
1557 	}
1558 
1559 	len = cnt = 0;
1560 	while (uio->uio_resid > 0) {
1561 		len = min(buflen, uio->uio_resid);
1562 		ptr = buffer;
1563 
1564 		if (uio->uio_rw == UIO_WRITE) {
1565 			error = uiomove(ptr, len, uio);
1566 			if (error)
1567 				break;
1568 		}
1569 	again:		/* goto bad */
1570 		/* timed out?  */
1571 		if (!ISSET(mp->mp_flags, MBPPF_UIO))
1572 			break;
1573 
1574 		/*
1575 		 * perform the operation
1576 		 */
1577 		if (uio->uio_rw == UIO_WRITE) {
1578 			cnt = mbpp_send(mp, ptr, len);
1579 		} else {
1580 			cnt = mbpp_recv(mp, ptr, len);
1581 		}
1582 
1583 		if (uio->uio_rw == UIO_READ) {
1584 			if (cnt) {
1585 				error = uiomove(ptr, cnt, uio);
1586 				if (error)
1587 					break;
1588 				gotdata++;
1589 			}
1590 			else if (gotdata)	/* consider us done */
1591 				break;
1592 		}
1593 
1594 		/* timed out?  */
1595 		if (!ISSET(mp->mp_flags, MBPPF_UIO))
1596 			break;
1597 
1598 		/*
1599 		 * poll delay?
1600 		 */
1601 		if (mp->mp_delay > 0) {
1602 			s = spltty();	/* XXX */
1603 			SET(mp->mp_flags, MBPPF_DELAY);
1604 			timeout_add(&mp->mp_start_tmo, mp->mp_delay);
1605 			error = tsleep(mp, PCATCH | PZERO, "mbppdelay", 0);
1606 			splx(s);
1607 			if (error)
1608 				break;
1609 		}
1610 
1611 		/*
1612 		 * don't call uiomove again until we used all the data we grabbed
1613 		 */
1614 		if (uio->uio_rw == UIO_WRITE && cnt != len) {
1615 			ptr += cnt;
1616 			len -= cnt;
1617 			cnt = 0;
1618 			goto again;
1619 		}
1620 	}
1621 
1622 	/*
1623 	 * clear timeouts
1624 	 */
1625 	s = spltty();	/* XXX */
1626 	if (ISSET(mp->mp_flags, MBPPF_TIMEOUT)) {
1627 		timeout_del(&mp->mp_timeout_tmo);
1628 		CLR(mp->mp_flags, MBPPF_TIMEOUT);
1629 	}
1630 	if (ISSET(mp->mp_flags, MBPPF_DELAY)) {
1631 		timeout_del(&mp->mp_start_tmo);
1632 		CLR(mp->mp_flags, MBPPF_DELAY);
1633 	}
1634 	splx(s);
1635 
1636 	/*
1637 	 * adjust for those chars that we uiomoved but never actually wrote
1638 	 */
1639 	if (uio->uio_rw == UIO_WRITE && cnt != len) {
1640 		uio->uio_resid += (len - cnt);
1641 	}
1642 
1643 	free(buffer, M_DEVBUF);
1644 	return (error);
1645 }
1646 
1647 void
1648 mbpp_timeout(void *arg)
1649 {
1650 	struct mbpp_port *mp = arg;
1651 
1652 	CLR(mp->mp_flags, MBPPF_UIO | MBPPF_TIMEOUT);
1653 	wakeup(mp);
1654 }
1655 
1656 void
1657 mbpp_start(void *arg)
1658 {
1659 	struct mbpp_port *mp = arg;
1660 
1661 	CLR(mp->mp_flags, MBPPF_DELAY);
1662 	wakeup(mp);
1663 }
1664 
1665 int
1666 mbpp_send(struct mbpp_port *mp, caddr_t ptr, int len)
1667 {
1668 	int s;
1669 	struct cd1400 *cd = mp->mp_cd1400;
1670 
1671 	/* set up io information */
1672 	mp->mp_ptr = ptr;
1673 	mp->mp_cnt = len;
1674 
1675 	/* start transmitting */
1676 	s = spltty();
1677 	if (cd) {
1678 		CD1400_WRITE_REG(cd, CD1400_CAR, 0);
1679 
1680 		/* output strobe width ~1microsecond */
1681 		CD1400_WRITE_REG(cd, CD1400_TBPR, 10);
1682 
1683 		/* enable channel */
1684 		cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN);
1685 		CD1400_WRITE_REG(cd, CD1400_SRER, CD1400_SRER_TXRDY);
1686 	}
1687 
1688 	/* ZZzzz... */
1689 	tsleep(mp, PCATCH | PZERO, "mbpp_send", 0);
1690 
1691 	/* stop transmitting */
1692 	if (cd) {
1693 		CD1400_WRITE_REG(cd, CD1400_CAR, 0);
1694 
1695 		/* disable transmitter */
1696 		CD1400_WRITE_REG(cd, CD1400_SRER, 0);
1697 		cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTDIS);
1698 
1699 		/* flush fifo */
1700 		cd1400_write_ccr(cd, CD1400_CCR_CMDRESET | CD1400_CCR_FTF);
1701 	}
1702 	splx(s);
1703 
1704 	/* return number of chars sent */
1705 	return (len - mp->mp_cnt);
1706 }
1707 
1708 int
1709 mbpp_recv(struct mbpp_port *mp, caddr_t ptr, int len)
1710 {
1711 	int s;
1712 	struct cd1400 *cd = mp->mp_cd1400;
1713 
1714 	/* set up io information */
1715 	mp->mp_ptr = ptr;
1716 	mp->mp_cnt = len;
1717 
1718 	/* start receiving */
1719 	s = spltty();
1720 	if (cd) {
1721 		int rcor, rbpr;
1722 
1723 		CD1400_WRITE_REG(cd, CD1400_CAR, 0);
1724 
1725 		/* input strobe at 100kbaud (10microseconds) */
1726 		cd1400_compute_baud(100000, cd->cd_clock, &rcor, &rbpr);
1727 		CD1400_WRITE_REG(cd, CD1400_RCOR, rcor);
1728 		CD1400_WRITE_REG(cd, CD1400_RBPR, rbpr);
1729 
1730 		/* rx threshold */
1731 		CD1400_WRITE_REG(cd, CD1400_COR3, MBPP_RX_FIFO_THRESHOLD);
1732 		cd1400_write_ccr(cd, CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3);
1733 
1734 		/* enable channel */
1735 		cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_RCVEN);
1736 		CD1400_WRITE_REG(cd, CD1400_SRER, CD1400_SRER_RXDATA);
1737 	}
1738 
1739 	/* ZZzzz... */
1740 	tsleep(mp, PCATCH | PZERO, "mbpp_recv", 0);
1741 
1742 	/* stop receiving */
1743 	if (cd) {
1744 		CD1400_WRITE_REG(cd, CD1400_CAR, 0);
1745 
1746 		/* disable receiving */
1747 		CD1400_WRITE_REG(cd, CD1400_SRER, 0);
1748 		cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_RCVDIS);
1749 	}
1750 	splx(s);
1751 
1752 	/* return number of chars received */
1753 	return (len - mp->mp_cnt);
1754 }
1755 
1756 int
1757 mbpp_hztoms(int h)
1758 {
1759 	int m = h;
1760 
1761 	if (m > 0)
1762 		m = m * 1000 / hz;
1763 	return (m);
1764 }
1765 
1766 int
1767 mbpp_mstohz(int m)
1768 {
1769 	int h = m;
1770 
1771 	if (h > 0) {
1772 		h = h * hz / 1000;
1773 		if (h == 0)
1774 			h = 1000 / hz;
1775 	}
1776 	return (h);
1777 }
1778