xref: /freebsd-12.1/sys/dev/cx/csigma.c (revision 453130d9)
1 /*-
2  * Low-level subroutines for Cronyx-Sigma adapter.
3  *
4  * Copyright (C) 1994-2000 Cronyx Engineering.
5  * Author: Serge Vakulenko, <[email protected]>
6  *
7  * This software is distributed with NO WARRANTIES, not even the implied
8  * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9  *
10  * Authors grant any other persons or organisations permission to use
11  * or modify this software as long as this message is kept with the software,
12  * all derivative works or modified versions.
13  *
14  * Cronyx Id: csigma.c,v 1.1.2.1 2003/11/12 17:13:41 rik Exp $
15  * $FreeBSD$
16  */
17 #include <dev/cx/machdep.h>
18 #include <dev/cx/cxddk.h>
19 #include <dev/cx/cxreg.h>
20 #include <dev/cx/cronyxfw.h>
21 
22 #define DMA_MASK	0xd4	/* DMA mask register */
23 #define DMA_MASK_CLEAR	0x04	/* DMA clear mask */
24 #define DMA_MODE	0xd6	/* DMA mode register */
25 #define DMA_MODE_MASTER	0xc0	/* DMA master mode */
26 
27 #define BYTE *(unsigned char*)&
28 
29 static unsigned char irqmask [] = {
30 	BCR0_IRQ_DIS,	BCR0_IRQ_DIS,	BCR0_IRQ_DIS,	BCR0_IRQ_3,
31 	BCR0_IRQ_DIS,	BCR0_IRQ_5,	BCR0_IRQ_DIS,	BCR0_IRQ_7,
32 	BCR0_IRQ_DIS,	BCR0_IRQ_DIS,	BCR0_IRQ_10,	BCR0_IRQ_11,
33 	BCR0_IRQ_12,	BCR0_IRQ_DIS,	BCR0_IRQ_DIS,	BCR0_IRQ_15,
34 };
35 
36 static unsigned char dmamask [] = {
37 	BCR0_DMA_DIS,	BCR0_DMA_DIS,	BCR0_DMA_DIS,	BCR0_DMA_DIS,
38 	BCR0_DMA_DIS,	BCR0_DMA_5,	BCR0_DMA_6,	BCR0_DMA_7,
39 };
40 
41 /* standard base port set */
42 static short porttab [] = {
43 	0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0,
44 	0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0x3c0, 0x3e0, 0
45 };
46 
47 /* valid IRQs and DRQs */
48 static short irqtab [] = { 3, 5, 7, 10, 11, 12, 15, 0 };
49 static short dmatab [] = { 5, 6, 7, 0 };
50 
valid(short value,short * list)51 static int valid (short value, short *list)
52 {
53 	while (*list)
54 		if (value == *list++)
55 			return 1;
56 	return 0;
57 }
58 
59 long cx_rxbaud = 9600;		/* receiver baud rate */
60 long cx_txbaud = 9600;		/* transmitter baud rate */
61 
62 int cx_univ_mode = M_HDLC;	/* univ. chan. mode: async or sync */
63 int cx_sync_mode = M_HDLC;	/* sync. chan. mode: HDLC, Bisync or X.21 */
64 int cx_iftype = 0;		/* univ. chan. interface: upper/lower */
65 
66 static int cx_probe_chip (port_t base);
67 static void cx_setup_chip (cx_chan_t *c);
68 
69 /*
70  * Wait for CCR to clear.
71  */
cx_cmd(port_t base,int cmd)72 void cx_cmd (port_t base, int cmd)
73 {
74 	port_t port = CCR(base);
75 	int count;
76 
77 	/* Wait 10 msec for the previous command to complete. */
78 	for (count=0; inb(port) && count<20000; ++count)
79 		continue;
80 
81 	/* Issue the command. */
82 	outb (port, cmd);
83 
84 	/* Wait 10 msec for the command to complete. */
85 	for (count=0; inb(port) && count<20000; ++count)
86 		continue;
87 }
88 
89 /*
90  * Reset the chip.
91  */
cx_reset(port_t port)92 static int cx_reset (port_t port)
93 {
94 	int count;
95 
96 	/* Wait up to 10 msec for revision code to appear after reset. */
97 	for (count=0; count<20000; ++count)
98 		if (inb(GFRCR(port)) != 0)
99 			break;
100 
101 	cx_cmd (port, CCR_RSTALL);
102 
103 	/* Firmware revision code should clear immediately. */
104 	/* Wait up to 10 msec for revision code to appear again. */
105 	for (count=0; count<20000; ++count)
106 		if (inb(GFRCR(port)) != 0)
107 			return (1);
108 
109 	/* Reset failed. */
110 	return (0);
111 }
112 
cx_download(port_t port,const unsigned char * firmware,long bits,const cr_dat_tst_t * tst)113 int cx_download (port_t port, const unsigned char *firmware, long bits,
114 	const cr_dat_tst_t *tst)
115 {
116 	unsigned char cr2, sr;
117 	long i, n, maxn = (bits + 7) / 8;
118 	int v, b;
119 
120 	inb (BDET(port));
121 	for (i=n=0; n<maxn; ++n) {
122 		v = ((firmware[n] ^ ' ') << 1) | (firmware[n] >> 7 & 1);
123 		for (b=0; b<7; b+=2, i+=2) {
124 			if (i >= bits)
125 				break;
126 			cr2 = 0;
127 			if (v >> b & 1) cr2 |= BCR2_TMS;
128 			if (v >> b & 2) cr2 |= BCR2_TDI;
129 			outb (BCR2(port), cr2);
130 			sr = inb (BSR(port));
131 			outb (BCR0(port), BCR0800_TCK);
132 			outb (BCR0(port), 0);
133 			if (i >= tst->end)
134 				++tst;
135 			if (i >= tst->start && (sr & BSR800_LERR))
136 				return (0);
137 		}
138 	}
139 	return (1);
140 }
141 
142 /*
143  * Check if the Sigma-XXX board is present at the given base port.
144  */
cx_probe_chained_board(port_t port,int * c0,int * c1)145 static int cx_probe_chained_board (port_t port, int *c0, int *c1)
146 {
147 	int rev, i;
148 
149 	/* Read and check the board revision code. */
150 	rev = inb (BSR(port));
151 	*c0 = *c1 = 0;
152 	switch (rev & BSR_VAR_MASK) {
153 	case CRONYX_100:	*c0 = 1;	break;
154 	case CRONYX_400:	*c1 = 1;	break;
155 	case CRONYX_500:	*c0 = *c1 = 1;	break;
156 	case CRONYX_410:	*c0 = 1;	break;
157 	case CRONYX_810:	*c0 = *c1 = 1;	break;
158 	case CRONYX_410s:	*c0 = 1;	break;
159 	case CRONYX_810s:	*c0 = *c1 = 1;	break;
160 	case CRONYX_440:	*c0 = 1;	break;
161 	case CRONYX_840:	*c0 = *c1 = 1;	break;
162 	case CRONYX_401:	*c0 = 1;	break;
163 	case CRONYX_801:	*c0 = *c1 = 1;	break;
164 	case CRONYX_401s:	*c0 = 1;	break;
165 	case CRONYX_801s:	*c0 = *c1 = 1;	break;
166 	case CRONYX_404:	*c0 = 1;	break;
167 	case CRONYX_703:	*c0 = *c1 = 1;	break;
168 	default:		return (0);	/* invalid variant code */
169 	}
170 
171 	switch (rev & BSR_OSC_MASK) {
172 	case BSR_OSC_20:	/* 20 MHz */
173 	case BSR_OSC_18432:	/* 18.432 MHz */
174 		break;
175 	default:
176 		return (0);	/* oscillator frequency does not match */
177 	}
178 
179 	for (i=2; i<0x10; i+=2)
180 		if ((inb (BSR(port)+i) & BSR_REV_MASK) != (rev & BSR_REV_MASK))
181 			return (0);	/* status changed? */
182 	return (1);
183 }
184 
185 /*
186  * Check if the Sigma-800 board is present at the given base port.
187  * Read board status register 1 and check identification bits
188  * which should invert every next read.
189  */
cx_probe_800_chained_board(port_t port)190 static int cx_probe_800_chained_board (port_t port)
191 {
192 	unsigned char det, odet;
193 	int i;
194 
195 	odet = inb (BDET(port));
196 	if ((odet & (BDET_IB | BDET_IB_NEG)) != BDET_IB &&
197 	    (odet & (BDET_IB | BDET_IB_NEG)) != BDET_IB_NEG)
198 		return (0);
199 	for (i=0; i<100; ++i) {
200 		det = inb (BDET(port));
201 		if (((det ^ odet) & (BDET_IB | BDET_IB_NEG)) !=
202 		    (BDET_IB | BDET_IB_NEG))
203 			return (0);
204 		odet = det;
205 	}
206 	/* Reset the controller. */
207 	outb (BCR0(port), 0);
208 	outb (BCR1(port), 0);
209 	outb (BCR2(port), 0);
210 	return (1);
211 }
212 
213 /*
214  * Check if the Sigma-2x board is present at the given base port.
215  */
cx_probe_2x_board(port_t port)216 static int cx_probe_2x_board (port_t port)
217 {
218 	int rev, i;
219 
220 	/* Read and check the board revision code. */
221 	rev = inb (BSR(port));
222 	if ((rev & BSR2X_VAR_MASK) != CRONYX_22 &&
223 	    (rev & BSR2X_VAR_MASK) != CRONYX_24)
224 		return (0);		/* invalid variant code */
225 
226 	for (i=2; i<0x10; i+=2)
227 		if ((inb (BSR(port)+i) & BSR2X_REV_MASK) !=
228 		    (rev & BSR2X_REV_MASK))
229 			return (0);	/* status changed? */
230 	return (1);
231 }
232 
233 /*
234  * Check if the Cronyx-Sigma board is present at the given base port.
235  */
cx_probe_board(port_t port,int irq,int dma)236 int cx_probe_board (port_t port, int irq, int dma)
237 {
238 	int c0, c1, c2=0, c3=0, result;
239 
240 	if (! valid (port, porttab))
241 		return 0;
242 
243 	if (irq > 0 && ! valid (irq, irqtab))
244 		return 0;
245 
246 	if (dma > 0 && ! valid (dma, dmatab))
247 		return 0;
248 
249 	if (cx_probe_800_chained_board (port)) {
250 		/* Sigma-800 detected. */
251 		if (! (inb (BSR(port)) & BSR_NOCHAIN)) {
252 			/* chained board attached */
253 			if (! cx_probe_800_chained_board (port+0x10))
254 				/* invalid chained board? */
255 				return (0);
256 			if (! (inb (BSR(port+0x10)) & BSR_NOCHAIN))
257 				/* invalid chained board flag? */
258 				return (0);
259 		}
260 		return 1;
261 	}
262 	if (cx_probe_chained_board (port, &c0, &c1)) {
263 		/* Sigma-XXX detected. */
264 		if (! (inb (BSR(port)) & BSR_NOCHAIN)) {
265 			/* chained board attached */
266 			if (! cx_probe_chained_board (port+0x10, &c2, &c3))
267 				/* invalid chained board? */
268 				return (0);
269 			if (! (inb (BSR(port+0x10)) & BSR_NOCHAIN))
270 				/* invalid chained board flag? */
271 				return (0);
272 		}
273 	} else if (cx_probe_2x_board (port)) {
274 		c0 = 1;		/* Sigma-2x detected. */
275 		c1 = 0;
276 	} else
277 		return (0);     /* no board detected */
278 
279 	/* Turn off the reset bit. */
280 	outb (BCR0(port), BCR0_NORESET);
281 	if (c2 || c3)
282 		outb (BCR0(port + 0x10), BCR0_NORESET);
283 
284 	result = 1;
285 	if (c0 && ! cx_probe_chip (CS0(port)))
286 		result = 0;	/* no CD2400 chip here */
287 	else if (c1 && ! cx_probe_chip (CS1A(port)) &&
288 	    ! cx_probe_chip (CS1(port)))
289 		result = 0;	/* no second CD2400 chip */
290 	else if (c2 && ! cx_probe_chip (CS0(port + 0x10)))
291 		result = 0;	/* no CD2400 chip on the slave board */
292 	else if (c3 && ! cx_probe_chip (CS1(port + 0x10)))
293 		result = 0;	/* no second CD2400 chip on the slave board */
294 
295 	/* Reset the controller. */
296 	outb (BCR0(port), 0);
297 	if (c2 || c3)
298 		outb (BCR0(port + 0x10), 0);
299 
300 	/* Yes, we really have valid Sigma board. */
301 	return (result);
302 }
303 
304 /*
305  * Check if the CD2400 chip is present at the given base port.
306  */
cx_probe_chip(port_t base)307 static int cx_probe_chip (port_t base)
308 {
309 	int rev, newrev, count;
310 
311 	/* Wait up to 10 msec for revision code to appear after reset. */
312 	rev = 0;
313 	for (count=0; rev==0; ++count) {
314 		if (count >= 20000)
315 			return (0); /* reset failed */
316 		rev = inb (GFRCR(base));
317 	}
318 
319 	/* Read and check the global firmware revision code. */
320 	if (! (rev>=REVCL_MIN && rev<=REVCL_MAX) &&
321 	    ! (rev>=REVCL31_MIN && rev<=REVCL31_MAX))
322 		return (0);	/* CD2400/2431 revision does not match */
323 
324 	/* Reset the chip. */
325 	if (! cx_reset (base))
326 		return (0);
327 
328 	/* Read and check the new global firmware revision code. */
329 	newrev = inb (GFRCR(base));
330 	if (newrev != rev)
331 		return (0);	/* revision changed */
332 
333 	/* Yes, we really have CD2400/2431 chip here. */
334 	return (1);
335 }
336 
337 /*
338  * Check that the irq is functional.
339  * irq>0  - activate the interrupt from the adapter (irq=on)
340  * irq<0  - deactivate the interrupt (irq=off)
341  * irq==0 - free the interrupt line (irq=tri-state)
342  * Return the interrupt mask _before_ activating irq.
343  */
cx_probe_irq(cx_board_t * b,int irq)344 int cx_probe_irq (cx_board_t *b, int irq)
345 {
346 	int mask, rev;
347         port_t port;
348 
349 	rev = inb (BSR(b->port));
350         port = ((rev & BSR_VAR_MASK) != CRONYX_400) ? CS0(b->port) : CS1(b->port);
351 
352 	outb (0x20, 0x0a);
353 	mask = inb (0x20);
354 	outb (0xa0, 0x0a);
355 	mask |= inb (0xa0) << 8;
356 
357 	if (irq > 0) {
358 		outb (BCR0(b->port), BCR0_NORESET | irqmask[irq]);
359 		outb (CAR(port), 0);
360 		cx_cmd (port, CCR_CLRCH);
361 		outb (CMR(port), CMR_HDLC);
362 		outb (TCOR(port), 0);
363 		outb (TBPR(port), 1);
364 		cx_cmd (port, CCR_INITCH | CCR_ENTX);
365 		outb (IER(port), IER_TXMPTY);
366 	} else if (irq < 0) {
367 		cx_reset (port);
368 		if (-irq > 7) {
369 			outb (0xa0, 0x60 | ((-irq) & 7));
370 			outb (0x20, 0x62);
371 		} else
372 			outb (0x20, 0x60 | (-irq));
373 	} else
374 		outb (BCR0(b->port), 0);
375 	return mask;
376 }
377 
cx_chip_revision(port_t port,int rev)378 static int cx_chip_revision (port_t port, int rev)
379 {
380 	int count;
381 
382 	/* Model 400 has no first chip. */
383 	port = ((rev & BSR_VAR_MASK) != CRONYX_400) ? CS0(port) : CS1(port);
384 
385 	/* Wait up to 10 msec for revision code to appear after reset. */
386 	for (count=0; inb(GFRCR(port))==0; ++count)
387 		if (count >= 20000)
388 			return (0); /* reset failed */
389 
390 	return inb (GFRCR (port));
391 }
392 
393 /*
394  * Probe and initialize the board structure.
395  */
cx_init(cx_board_t * b,int num,port_t port,int irq,int dma)396 void cx_init (cx_board_t *b, int num, port_t port, int irq, int dma)
397 {
398 	int gfrcr, rev, chain, mod = 0, rev2 = 0, mod2 = 0;
399 
400 	rev = inb (BSR(port));
401 	chain = ! (rev & BSR_NOCHAIN);
402 	if (cx_probe_800_chained_board (port)) {
403 		cx_init_800 (b, num, port, irq, dma, chain);
404 		return;
405 	}
406 	if ((rev & BSR2X_VAR_MASK) == CRONYX_22 ||
407 	    (rev & BSR2X_VAR_MASK) == CRONYX_24) {
408 		cx_init_2x (b, num, port, irq, dma,
409 			(rev & BSR2X_VAR_MASK), (rev & BSR2X_OSC_33));
410 		return;
411         }
412 
413 	outb (BCR0(port), BCR0_NORESET);
414 	if (chain)
415 		outb (BCR0(port+0x10), BCR0_NORESET);
416 	gfrcr = cx_chip_revision (port, rev);
417 	if (gfrcr >= REVCL31_MIN && gfrcr <= REVCL31_MAX)
418 		mod = 1;
419 	if (chain) {
420 		rev2 = inb (BSR(port+0x10));
421 		gfrcr = cx_chip_revision (port+0x10, rev2);
422 		if (gfrcr >= REVCL31_MIN && gfrcr <= REVCL31_MAX)
423 			mod2 = 1;
424 		outb (BCR0(port+0x10), 0);
425 	}
426 	outb (BCR0(port), 0);
427 
428 	cx_init_board (b, num, port, irq, dma, chain,
429 		(rev & BSR_VAR_MASK), (rev & BSR_OSC_MASK), mod,
430 		(rev2 & BSR_VAR_MASK), (rev2 & BSR_OSC_MASK), mod2);
431 }
432 
433 /*
434  * Initialize the board structure, given the type of the board.
435  */
cx_init_board(cx_board_t * b,int num,port_t port,int irq,int dma,int chain,int rev,int osc,int mod,int rev2,int osc2,int mod2)436 void cx_init_board (cx_board_t *b, int num, port_t port, int irq, int dma,
437 	int chain, int rev, int osc, int mod, int rev2, int osc2, int mod2)
438 {
439 	cx_chan_t *c;
440 	char *type;
441 	int i;
442 
443 	/* Initialize board structure. */
444 	b->port = port;
445 	b->num = num;
446 	b->irq = irq;
447 	b->dma = dma;
448 	b->opt = board_opt_dflt;
449 
450 	b->type = B_SIGMA_XXX;
451 	b->if0type = b->if8type = cx_iftype;
452 
453 	/* Set channels 0 and 8 mode, set DMA and IRQ. */
454 	b->bcr0 = b->bcr0b = BCR0_NORESET | dmamask[b->dma] | irqmask[b->irq];
455 
456 	/* Clear DTR[0..3] and DTR[8..12]. */
457 	b->bcr1 = b->bcr1b = 0;
458 
459 	/*------------------ Master board -------------------*/
460 
461 	/* Read and check the board revision code. */
462 	strcpy (b->name, mod ? "m" : "");
463 	switch (rev) {
464 	default:	  type = "";	 break;
465 	case CRONYX_100:  type = "100";  break;
466 	case CRONYX_400:  type = "400";  break;
467 	case CRONYX_500:  type = "500";  break;
468 	case CRONYX_410:  type = "410";  break;
469 	case CRONYX_810:  type = "810";  break;
470 	case CRONYX_410s: type = "410s"; break;
471 	case CRONYX_810s: type = "810s"; break;
472 	case CRONYX_440:  type = "440";  break;
473 	case CRONYX_840:  type = "840";  break;
474 	case CRONYX_401:  type = "401";  break;
475 	case CRONYX_801:  type = "801";  break;
476 	case CRONYX_401s: type = "401s"; break;
477 	case CRONYX_801s: type = "801s"; break;
478 	case CRONYX_404:  type = "404";  break;
479 	case CRONYX_703:  type = "703";  break;
480 	}
481 	strcat (b->name, type);
482 
483 	switch (osc) {
484 	default:
485 	case BSR_OSC_20: /* 20 MHz */
486 		b->chan[0].oscfreq = b->chan[1].oscfreq =
487 		b->chan[2].oscfreq = b->chan[3].oscfreq =
488 		b->chan[4].oscfreq = b->chan[5].oscfreq =
489 		b->chan[6].oscfreq = b->chan[7].oscfreq =
490 			mod ? 33000000L : 20000000L;
491 		strcat (b->name, "a");
492 		break;
493 	case BSR_OSC_18432: /* 18.432 MHz */
494 		b->chan[0].oscfreq = b->chan[1].oscfreq =
495 		b->chan[2].oscfreq = b->chan[3].oscfreq =
496 		b->chan[4].oscfreq = b->chan[5].oscfreq =
497 		b->chan[6].oscfreq = b->chan[7].oscfreq =
498 			mod ? 20000000L : 18432000L;
499 		strcat (b->name, "b");
500 		break;
501 	}
502 
503 	/*------------------ Slave board -------------------*/
504 
505 	if (chain) {
506 		/* Read and check the board revision code. */
507 		strcat (b->name, mod2 ? "/m" : "/");
508 		switch (rev2) {
509 		default:	  type = "";	 break;
510 		case CRONYX_100:  type = "100";  break;
511 		case CRONYX_400:  type = "400";  break;
512 		case CRONYX_500:  type = "500";  break;
513 		case CRONYX_410:  type = "410";  break;
514 		case CRONYX_810:  type = "810";  break;
515 		case CRONYX_410s: type = "410s"; break;
516 		case CRONYX_810s: type = "810s"; break;
517 		case CRONYX_440:  type = "440";  break;
518 		case CRONYX_840:  type = "840";  break;
519 		case CRONYX_401:  type = "401";  break;
520 		case CRONYX_801:  type = "801";  break;
521 		case CRONYX_401s: type = "401s"; break;
522 		case CRONYX_801s: type = "801s"; break;
523 		case CRONYX_404:  type = "404";  break;
524 		case CRONYX_703:  type = "703";  break;
525 		}
526 		strcat (b->name, type);
527 
528 		switch (osc2) {
529 		default:
530 		case BSR_OSC_20: /* 20 MHz */
531 			b->chan[8].oscfreq = b->chan[9].oscfreq =
532 			b->chan[10].oscfreq = b->chan[11].oscfreq =
533 			b->chan[12].oscfreq = b->chan[13].oscfreq =
534 			b->chan[14].oscfreq = b->chan[15].oscfreq =
535 				mod2 ? 33000000L : 20000000L;
536 			strcat (b->name, "a");
537 			break;
538 		case BSR_OSC_18432: /* 18.432 MHz */
539 			b->chan[8].oscfreq = b->chan[9].oscfreq =
540 			b->chan[10].oscfreq = b->chan[11].oscfreq =
541 			b->chan[12].oscfreq = b->chan[13].oscfreq =
542 			b->chan[14].oscfreq = b->chan[15].oscfreq =
543 				mod2 ? 20000000L : 18432000L;
544 			strcat (b->name, "b");
545 			break;
546 		}
547 	}
548 
549 	/* Initialize channel structures. */
550 	for (i=0; i<4; ++i) {
551 		b->chan[i+0].port  = CS0(port);
552 		b->chan[i+4].port  = cx_probe_chip (CS1A(port)) ?
553 			CS1A(port) : CS1(port);
554 		b->chan[i+8].port  = CS0(port+0x10);
555 		b->chan[i+12].port = CS1(port+0x10);
556 	}
557 	for (c=b->chan; c<b->chan+NCHAN; ++c) {
558 		c->board = b;
559 		c->num = c - b->chan;
560 		c->type = T_NONE;
561 	}
562 
563 	/*------------------ Master board -------------------*/
564 
565 	switch (rev) {
566 	case CRONYX_400:
567 		for (i=4; i<8; ++i)
568 			b->chan[i].type = T_UNIV_RS232;
569 		break;
570 	case CRONYX_100:
571 		b->chan[0].type = T_UNIV_RS232;
572 		break;
573 	case CRONYX_500:
574 		b->chan[0].type = T_UNIV_RS232;
575 		for (i=4; i<8; ++i)
576 			b->chan[i].type = T_UNIV_RS232;
577 		break;
578 	case CRONYX_410:
579 		b->chan[0].type = T_UNIV_V35;
580 		for (i=1; i<4; ++i)
581 			b->chan[i].type = T_UNIV_RS232;
582 		break;
583 	case CRONYX_810:
584 		b->chan[0].type = T_UNIV_V35;
585 		for (i=1; i<8; ++i)
586 			b->chan[i].type = T_UNIV_RS232;
587 		break;
588 	case CRONYX_410s:
589 		b->chan[0].type = T_UNIV_V35;
590 		for (i=1; i<4; ++i)
591 			b->chan[i].type = T_SYNC_RS232;
592 		break;
593 	case CRONYX_810s:
594 		b->chan[0].type = T_UNIV_V35;
595 		for (i=1; i<4; ++i)
596 			b->chan[i].type = T_SYNC_RS232;
597 		for (i=4; i<8; ++i)
598 			b->chan[i].type = T_UNIV_RS232;
599 		break;
600 	case CRONYX_440:
601 		b->chan[0].type = T_UNIV_V35;
602 		for (i=1; i<4; ++i)
603 			b->chan[i].type = T_SYNC_V35;
604 		break;
605 	case CRONYX_840:
606 		b->chan[0].type = T_UNIV_V35;
607 		for (i=1; i<4; ++i)
608 			b->chan[i].type = T_SYNC_V35;
609 		for (i=4; i<8; ++i)
610 			b->chan[i].type = T_UNIV_RS232;
611 		break;
612 	case CRONYX_401:
613 		b->chan[0].type = T_UNIV_RS449;
614 		for (i=1; i<4; ++i)
615 			b->chan[i].type = T_UNIV_RS232;
616 		break;
617 	case CRONYX_801:
618 		b->chan[0].type = T_UNIV_RS449;
619 		for (i=1; i<8; ++i)
620 			b->chan[i].type = T_UNIV_RS232;
621 		break;
622 	case CRONYX_401s:
623 		b->chan[0].type = T_UNIV_RS449;
624 		for (i=1; i<4; ++i)
625 			b->chan[i].type = T_SYNC_RS232;
626 		break;
627 	case CRONYX_801s:
628 		b->chan[0].type = T_UNIV_RS449;
629 		for (i=1; i<4; ++i)
630 			b->chan[i].type = T_SYNC_RS232;
631 		for (i=4; i<8; ++i)
632 			b->chan[i].type = T_UNIV_RS232;
633 		break;
634 	case CRONYX_404:
635 		b->chan[0].type = T_UNIV_RS449;
636 		for (i=1; i<4; ++i)
637 			b->chan[i].type = T_SYNC_RS449;
638 		break;
639 	case CRONYX_703:
640 		b->chan[0].type = T_UNIV_RS449;
641 		for (i=1; i<3; ++i)
642 			b->chan[i].type = T_SYNC_RS449;
643 		for (i=4; i<8; ++i)
644 			b->chan[i].type = T_UNIV_RS232;
645 		break;
646 	}
647 
648 	/*------------------ Slave board -------------------*/
649 
650 	if (chain) {
651 		switch (rev2) {
652 		case CRONYX_400:
653 			break;
654 		case CRONYX_100:
655 			b->chan[8].type = T_UNIV_RS232;
656 			break;
657 		case CRONYX_500:
658 			b->chan[8].type = T_UNIV_RS232;
659 			for (i=12; i<16; ++i)
660 				b->chan[i].type = T_UNIV_RS232;
661 			break;
662 		case CRONYX_410:
663 			b->chan[8].type = T_UNIV_V35;
664 			for (i=9; i<12; ++i)
665 				b->chan[i].type = T_UNIV_RS232;
666 			break;
667 		case CRONYX_810:
668 			b->chan[8].type = T_UNIV_V35;
669 			for (i=9; i<16; ++i)
670 				b->chan[i].type = T_UNIV_RS232;
671 			break;
672 		case CRONYX_410s:
673 			b->chan[8].type = T_UNIV_V35;
674 			for (i=9; i<12; ++i)
675 				b->chan[i].type = T_SYNC_RS232;
676 			break;
677 		case CRONYX_810s:
678 			b->chan[8].type = T_UNIV_V35;
679 			for (i=9; i<12; ++i)
680 				b->chan[i].type = T_SYNC_RS232;
681 			for (i=12; i<16; ++i)
682 				b->chan[i].type = T_UNIV_RS232;
683 			break;
684 		case CRONYX_440:
685 			b->chan[8].type = T_UNIV_V35;
686 			for (i=9; i<12; ++i)
687 				b->chan[i].type = T_SYNC_V35;
688 			break;
689 		case CRONYX_840:
690 			b->chan[8].type = T_UNIV_V35;
691 			for (i=9; i<12; ++i)
692 				b->chan[i].type = T_SYNC_V35;
693 			for (i=12; i<16; ++i)
694 				b->chan[i].type = T_UNIV_RS232;
695 			break;
696 		case CRONYX_401:
697 			b->chan[8].type = T_UNIV_RS449;
698 			for (i=9; i<12; ++i)
699 				b->chan[i].type = T_UNIV_RS232;
700 			break;
701 		case CRONYX_801:
702 			b->chan[8].type = T_UNIV_RS449;
703 			for (i=9; i<16; ++i)
704 				b->chan[i].type = T_UNIV_RS232;
705 			break;
706 		case CRONYX_401s:
707 			b->chan[8].type = T_UNIV_RS449;
708 			for (i=9; i<12; ++i)
709 				b->chan[i].type = T_UNIV_RS232;
710 			break;
711 		case CRONYX_801s:
712 			b->chan[8].type = T_UNIV_RS449;
713 			for (i=9; i<12; ++i)
714 				b->chan[i].type = T_SYNC_RS232;
715 			for (i=12; i<16; ++i)
716 				b->chan[i].type = T_UNIV_RS232;
717 			break;
718 		case CRONYX_404:
719 			b->chan[8].type = T_UNIV_RS449;
720 			for (i=9; i<12; ++i)
721 				b->chan[i].type = T_SYNC_RS449;
722 			break;
723 		case CRONYX_703:
724 			b->chan[8].type = T_UNIV_RS449;
725 			for (i=9; i<11; ++i)
726 				b->chan[i].type = T_SYNC_RS449;
727 			for (i=12; i<16; ++i)
728 				b->chan[i].type = T_UNIV_RS232;
729 			break;
730 		}
731 	}
732 
733 	b->nuniv = b->nsync = b->nasync = 0;
734 	for (c=b->chan; c<b->chan+NCHAN; ++c)
735 		switch (c->type) {
736 		case T_ASYNC:      ++b->nasync; break;
737 		case T_UNIV:
738 		case T_UNIV_RS232:
739 		case T_UNIV_RS449:
740 		case T_UNIV_V35:   ++b->nuniv;  break;
741 		case T_SYNC_RS232:
742 		case T_SYNC_V35:
743 		case T_SYNC_RS449: ++b->nsync;  break;
744 		}
745 
746 	cx_reinit_board (b);
747 }
748 
749 /*
750  * Initialize the Sigma-800 board structure.
751  */
cx_init_800(cx_board_t * b,int num,port_t port,int irq,int dma,int chain)752 void cx_init_800 (cx_board_t *b, int num, port_t port, int irq, int dma,
753 	int chain)
754 {
755 	cx_chan_t *c;
756 	int i;
757 
758 	/* Initialize board structure. */
759 	b->port = port;
760 	b->num = num;
761 	b->irq = irq;
762 	b->dma = dma;
763 	b->opt = board_opt_dflt;
764 	b->type = B_SIGMA_800;
765 
766 	/* Set channels 0 and 8 mode, set DMA and IRQ. */
767 	b->bcr0 = b->bcr0b = dmamask[b->dma] | irqmask[b->irq];
768 
769 	/* Clear DTR[0..7] and DTR[8..15]. */
770 	b->bcr1 = b->bcr1b = 0;
771 
772 	strcpy (b->name, "800");
773 	if (chain)
774 		strcat (b->name, "/800");
775 
776 	/* Initialize channel structures. */
777 	for (i=0; i<4; ++i) {
778 		b->chan[i+0].port  = CS0(port);
779 		b->chan[i+4].port  = cx_probe_chip (CS1A(port)) ?
780 			CS1A(port) : CS1(port);
781 		b->chan[i+8].port  = CS0(port+0x10);
782 		b->chan[i+12].port = CS1(port+0x10);
783 	}
784 	for (c=b->chan; c<b->chan+NCHAN; ++c) {
785 		c->board = b;
786 		c->num = c - b->chan;
787 		c->oscfreq = 33000000L;
788 		c->type = (c->num < 8 || chain) ? T_UNIV_RS232 : T_NONE;
789 	}
790 
791 	b->nuniv = b->nsync = b->nasync = 0;
792 	for (c=b->chan; c<b->chan+NCHAN; ++c)
793 		switch (c->type) {
794 		case T_ASYNC:      ++b->nasync; break;
795 		case T_UNIV:
796 		case T_UNIV_RS232:
797 		case T_UNIV_RS449:
798 		case T_UNIV_V35:   ++b->nuniv;  break;
799 		case T_SYNC_RS232:
800 		case T_SYNC_V35:
801 		case T_SYNC_RS449: ++b->nsync;  break;
802 		}
803 
804 	cx_reinit_board (b);
805 }
806 
807 /*
808  * Initialize the Sigma-2x board structure.
809  */
cx_init_2x(cx_board_t * b,int num,port_t port,int irq,int dma,int rev,int osc)810 void cx_init_2x (cx_board_t *b, int num, port_t port, int irq, int dma,
811 	int rev, int osc)
812 {
813 	cx_chan_t *c;
814 	int i;
815 
816 	/* Initialize board structure. */
817 	b->port = port;
818 	b->num = num;
819 	b->irq = irq;
820 	b->dma = dma;
821 	b->opt = board_opt_dflt;
822 
823 	b->type = B_SIGMA_2X;
824 
825 	/* Set channels 0 and 8 mode, set DMA and IRQ. */
826 	b->bcr0 = BCR0_NORESET | dmamask[b->dma] | irqmask[b->irq];
827 	if (b->type == B_SIGMA_2X && b->opt.fast)
828 		b->bcr0 |= BCR02X_FAST;
829 
830 	/* Clear DTR[0..3] and DTR[8..12]. */
831 	b->bcr1 = 0;
832 
833 	/* Initialize channel structures. */
834 	for (i=0; i<4; ++i) {
835 		b->chan[i+0].port  = CS0(port);
836 		b->chan[i+4].port  = CS1(port);
837 		b->chan[i+8].port  = CS0(port+0x10);
838 		b->chan[i+12].port = CS1(port+0x10);
839 	}
840 	for (c=b->chan; c<b->chan+NCHAN; ++c) {
841 		c->board = b;
842 		c->num = c - b->chan;
843 		c->type = T_NONE;
844 		c->oscfreq = (osc & BSR2X_OSC_33) ? 33000000L : 20000000L;
845 	}
846 
847 	/* Check the board revision code. */
848 	strcpy (b->name, "22");
849 	b->chan[0].type = T_UNIV;
850 	b->chan[1].type = T_UNIV;
851 	b->nsync = b->nasync = 0;
852 	b->nuniv = 2;
853 	if (rev == CRONYX_24) {
854 		strcpy (b->name, "24");
855 		b->chan[2].type = T_UNIV;
856 		b->chan[3].type = T_UNIV;
857 		b->nuniv += 2;
858 	}
859 	strcat (b->name, (osc & BSR2X_OSC_33) ? "c" : "a");
860 	cx_reinit_board (b);
861 }
862 
863 /*
864  * Reinitialize all channels, using new options and baud rate.
865  */
cx_reinit_board(cx_board_t * b)866 void cx_reinit_board (cx_board_t *b)
867 {
868 	cx_chan_t *c;
869 
870 	b->opt = board_opt_dflt;
871 	if (b->type == B_SIGMA_2X) {
872 		b->bcr0 &= ~BCR02X_FAST;
873 		if (b->opt.fast)
874 			b->bcr0 |= BCR02X_FAST;
875 	} else
876 		b->if0type = b->if8type = cx_iftype;
877 	for (c=b->chan; c<b->chan+NCHAN; ++c) {
878 		switch (c->type) {
879 		default:
880 		case T_NONE:
881 			continue;
882 		case T_UNIV:
883 		case T_UNIV_RS232:
884 		case T_UNIV_RS449:
885 		case T_UNIV_V35:
886 			c->mode = (cx_univ_mode == M_ASYNC) ?
887 				M_ASYNC : cx_sync_mode;
888 			break;
889 		case T_SYNC_RS232:
890 		case T_SYNC_V35:
891 		case T_SYNC_RS449:
892 			c->mode = cx_sync_mode;
893 			break;
894 		case T_ASYNC:
895 			c->mode = M_ASYNC;
896 			break;
897 		}
898 		c->rxbaud = cx_rxbaud;
899 		c->txbaud = cx_txbaud;
900 		c->opt = chan_opt_dflt;
901 		c->aopt = opt_async_dflt;
902 		c->hopt = opt_hdlc_dflt;
903 	}
904 }
905 
906 /*
907  * Set up the board.
908  */
cx_setup_board(cx_board_t * b,const unsigned char * firmware,long bits,const cr_dat_tst_t * tst)909 int cx_setup_board (cx_board_t *b, const unsigned char *firmware,
910 	long bits, const cr_dat_tst_t *tst)
911 {
912 	int i;
913 #ifndef NDIS_MINIPORT_DRIVER
914 	/* Disable DMA channel. */
915 	outb (DMA_MASK, (b->dma & 3) | DMA_MASK_CLEAR);
916 #endif
917 	/* Reset the controller. */
918 	outb (BCR0(b->port), 0);
919 	if (b->chan[8].type || b->chan[12].type)
920 		outb (BCR0(b->port+0x10), 0);
921 
922 	/* Load the firmware. */
923 	if (b->type == B_SIGMA_800) {
924 		/* Reset the controllers. */
925 		outb (BCR2(b->port), BCR2_TMS);
926 		if (b->chan[8].type || b->chan[12].type)
927 			outb (BCR2(b->port+0x10), BCR2_TMS);
928 		outb (BCR2(b->port), 0);
929 		if (b->chan[8].type || b->chan[12].type)
930 			outb (BCR2(b->port+0x10), 0);
931 
932 		if (firmware &&
933 		    (! cx_download (b->port, firmware, bits, tst) ||
934 		    ((b->chan[8].type || b->chan[12].type) &&
935 		    ! cx_download (b->port+0x10, firmware, bits, tst))))
936 			return (0);
937 	}
938 
939 	/*
940 	 * Set channels 0 and 8 to RS232 async. mode.
941 	 * Enable DMA and IRQ.
942 	 */
943 	outb (BCR0(b->port), b->bcr0);
944 	if (b->chan[8].type || b->chan[12].type)
945 		outb (BCR0(b->port+0x10), b->bcr0b);
946 
947 	/* Clear DTR[0..3] and DTR[8..12]. */
948 	outw (BCR1(b->port), b->bcr1);
949 	if (b->chan[8].type || b->chan[12].type)
950 		outw (BCR1(b->port+0x10), b->bcr1b);
951 
952 	if (b->type == B_SIGMA_800)
953 		outb (BCR2(b->port), b->opt.fast &
954 			(BCR2_BUS0 | BCR2_BUS1));
955 
956 	/* Initialize all controllers. */
957 	for (i=0; i<NCHAN; i+=4)
958 		if (b->chan[i].type != T_NONE)
959 			cx_setup_chip (b->chan + i);
960 #ifndef NDIS_MINIPORT_DRIVER
961 	/* Set up DMA channel to master mode. */
962 	outb (DMA_MODE, (b->dma & 3) | DMA_MODE_MASTER);
963 
964 	/* Enable DMA channel. */
965 	outb (DMA_MASK, b->dma & 3);
966 #endif
967 	/* Initialize all channels. */
968 	for (i=0; i<NCHAN; ++i)
969 		if (b->chan[i].type != T_NONE)
970 			cx_setup_chan (b->chan + i);
971 	return (1);
972 }
973 
974 /*
975  * Initialize the board.
976  */
cx_setup_chip(cx_chan_t * c)977 static void cx_setup_chip (cx_chan_t *c)
978 {
979 	/* Reset the chip. */
980 	cx_reset (c->port);
981 
982 	/*
983 	 * Set all interrupt level registers to the same value.
984 	 * This enables the internal CD2400 priority scheme.
985 	 */
986 	outb (RPILR(c->port), BRD_INTR_LEVEL);
987 	outb (TPILR(c->port), BRD_INTR_LEVEL);
988 	outb (MPILR(c->port), BRD_INTR_LEVEL);
989 
990 	/* Set bus error count to zero. */
991 	outb (BERCNT(c->port), 0);
992 
993 	/* Set 16-bit DMA mode. */
994 	outb (DMR(c->port), 0);
995 
996 	/* Set timer period register to 1 msec (approximately). */
997 	outb (TPR(c->port), 10);
998 }
999 
1000 /*
1001  * Initialize the CD2400 channel.
1002  */
cx_update_chan(cx_chan_t * c)1003 void cx_update_chan (cx_chan_t *c)
1004 {
1005 	int clock, period;
1006 
1007 	if (c->board->type == B_SIGMA_XXX)
1008 		switch (c->num) {
1009 		case 0:
1010 			c->board->bcr0 &= ~BCR0_UMASK;
1011 			if (c->mode != M_ASYNC)
1012 				c->board->bcr0 |= BCR0_UM_SYNC;
1013 			if (c->board->if0type &&
1014 			    (c->type==T_UNIV_RS449 || c->type==T_UNIV_V35))
1015 				c->board->bcr0 |= BCR0_UI_RS449;
1016 			outb (BCR0(c->board->port), c->board->bcr0);
1017 			break;
1018 		case 8:
1019 			c->board->bcr0b &= ~BCR0_UMASK;
1020 			if (c->mode != M_ASYNC)
1021 				c->board->bcr0b |= BCR0_UM_SYNC;
1022 			if (c->board->if8type &&
1023 			    (c->type==T_UNIV_RS449 || c->type==T_UNIV_V35))
1024 				c->board->bcr0b |= BCR0_UI_RS449;
1025 			outb (BCR0(c->board->port+0x10), c->board->bcr0b);
1026 			break;
1027 		}
1028 
1029 	/* set current channel number */
1030 	outb (CAR(c->port), c->num & 3);
1031 
1032 	switch (c->mode) {	/* initialize the channel mode */
1033 	case M_ASYNC:
1034 		/* set receiver timeout register */
1035 		outw (RTPR(c->port), 10);          /* 10 msec, see TPR */
1036 		c->opt.rcor.encod = ENCOD_NRZ;
1037 
1038 		outb (CMR(c->port), CMR_RXDMA | CMR_TXDMA | CMR_ASYNC);
1039 		outb (COR1(c->port), BYTE c->aopt.cor1);
1040 		outb (COR2(c->port), BYTE c->aopt.cor2);
1041 		outb (COR3(c->port), BYTE c->aopt.cor3);
1042 		outb (COR6(c->port), BYTE c->aopt.cor6);
1043 		outb (COR7(c->port), BYTE c->aopt.cor7);
1044 		outb (SCHR1(c->port), c->aopt.schr1);
1045 		outb (SCHR2(c->port), c->aopt.schr2);
1046 		outb (SCHR3(c->port), c->aopt.schr3);
1047 		outb (SCHR4(c->port), c->aopt.schr4);
1048 		outb (SCRL(c->port), c->aopt.scrl);
1049 		outb (SCRH(c->port), c->aopt.scrh);
1050 		outb (LNXT(c->port), c->aopt.lnxt);
1051 		break;
1052 	case M_HDLC:
1053 		outb (CMR(c->port), CMR_RXDMA | CMR_TXDMA | CMR_HDLC);
1054 		outb (COR1(c->port), BYTE c->hopt.cor1);
1055 		outb (COR2(c->port), BYTE c->hopt.cor2);
1056 		outb (COR3(c->port), BYTE c->hopt.cor3);
1057 		outb (RFAR1(c->port), c->hopt.rfar1);
1058 		outb (RFAR2(c->port), c->hopt.rfar2);
1059 		outb (RFAR3(c->port), c->hopt.rfar3);
1060 		outb (RFAR4(c->port), c->hopt.rfar4);
1061 		outb (CPSR(c->port), c->hopt.cpsr);
1062 		break;
1063 	}
1064 
1065 	/* set mode-independent options */
1066 	outb (COR4(c->port), BYTE c->opt.cor4);
1067 	outb (COR5(c->port), BYTE c->opt.cor5);
1068 
1069 	/* set up receiver clock values */
1070 	if (c->mode == M_ASYNC || c->opt.rcor.dpll || c->opt.tcor.llm) {
1071 		cx_clock (c->oscfreq, c->rxbaud, &clock, &period);
1072 		c->opt.rcor.clk = clock;
1073 	} else {
1074 		c->opt.rcor.clk = CLK_EXT;
1075 		period = 1;
1076 	}
1077 	outb (RCOR(c->port), BYTE c->opt.rcor);
1078 	outb (RBPR(c->port), period);
1079 
1080 	/* set up transmitter clock values */
1081 	if (c->mode == M_ASYNC || !c->opt.tcor.ext1x) {
1082 		unsigned ext1x = c->opt.tcor.ext1x;
1083 		c->opt.tcor.ext1x = 0;
1084 		cx_clock (c->oscfreq, c->txbaud, &clock, &period);
1085 		c->opt.tcor.clk = clock;
1086 		c->opt.tcor.ext1x = ext1x;
1087 	} else {
1088 		c->opt.tcor.clk = CLK_EXT;
1089 		period = 1;
1090 	}
1091 	outb (TCOR(c->port), BYTE c->opt.tcor);
1092 	outb (TBPR(c->port), period);
1093 }
1094 
1095 /*
1096  * Initialize the CD2400 channel.
1097  */
cx_setup_chan(cx_chan_t * c)1098 void cx_setup_chan (cx_chan_t *c)
1099 {
1100 	/* set current channel number */
1101 	outb (CAR(c->port), c->num & 3);
1102 
1103 	/* reset the channel */
1104 	cx_cmd (c->port, CCR_CLRCH);
1105 
1106 	/* set LIVR to contain the board and channel numbers */
1107 	outb (LIVR(c->port), c->board->num << 6 | c->num << 2);
1108 
1109 	/* clear DTR, RTS, set TXCout/DTR pin */
1110 	outb (MSVR_RTS(c->port), 0);
1111 	outb (MSVR_DTR(c->port), c->mode==M_ASYNC ? 0 : MSV_TXCOUT);
1112 
1113 	/* set receiver A buffer physical address */
1114 	outw (ARBADRU(c->port), (unsigned short) (c->arphys>>16));
1115 	outw (ARBADRL(c->port), (unsigned short) c->arphys);
1116 
1117 	/* set receiver B buffer physical address */
1118 	outw (BRBADRU(c->port), (unsigned short) (c->brphys>>16));
1119 	outw (BRBADRL(c->port), (unsigned short) c->brphys);
1120 
1121 	/* set transmitter A buffer physical address */
1122 	outw (ATBADRU(c->port), (unsigned short) (c->atphys>>16));
1123 	outw (ATBADRL(c->port), (unsigned short) c->atphys);
1124 
1125 	/* set transmitter B buffer physical address */
1126 	outw (BTBADRU(c->port), (unsigned short) (c->btphys>>16));
1127 	outw (BTBADRL(c->port), (unsigned short) c->btphys);
1128 
1129 	c->dtr = 0;
1130 	c->rts = 0;
1131 
1132 	cx_update_chan (c);
1133 }
1134 
1135 /*
1136  * Control DTR signal for the channel.
1137  * Turn it on/off.
1138  */
cx_set_dtr(cx_chan_t * c,int on)1139 void cx_set_dtr (cx_chan_t *c, int on)
1140 {
1141 	cx_board_t *b = c->board;
1142 
1143 	c->dtr = on ? 1 : 0;
1144 
1145 	if (b->type == B_SIGMA_2X) {
1146 		if (on) b->bcr1 |= BCR1_DTR(c->num);
1147 		else    b->bcr1 &= ~BCR1_DTR(c->num);
1148 		outw (BCR1(b->port), b->bcr1);
1149 		return;
1150 	}
1151 	if (b->type == B_SIGMA_800) {
1152 		if (c->num >= 8) {
1153 			if (on) b->bcr1b |= BCR1800_DTR(c->num);
1154 			else    b->bcr1b &= ~BCR1800_DTR(c->num);
1155 			outb (BCR1(b->port+0x10), b->bcr1b);
1156 		} else {
1157 			if (on) b->bcr1 |= BCR1800_DTR(c->num);
1158 			else    b->bcr1 &= ~BCR1800_DTR(c->num);
1159 			outb (BCR1(b->port), b->bcr1);
1160 		}
1161 		return;
1162 	}
1163 	if (c->mode == M_ASYNC) {
1164 		outb (CAR(c->port), c->num & 3);
1165 		outb (MSVR_DTR(c->port), on ? MSV_DTR : 0);
1166 		return;
1167 	}
1168 
1169 	switch (c->num) {
1170 	default:
1171 		/* Channels 4..7 and 12..15 in synchronous mode
1172 		 * have no DTR signal. */
1173 		break;
1174 
1175 	case 1: case 2:  case 3:
1176 		if (c->type == T_UNIV_RS232)
1177 			break;
1178 	case 0:
1179 		if (on) b->bcr1 |= BCR1_DTR(c->num);
1180 		else    b->bcr1 &= ~BCR1_DTR(c->num);
1181 		outw (BCR1(b->port), b->bcr1);
1182 		break;
1183 
1184 	case 9: case 10: case 11:
1185 		if (c->type == T_UNIV_RS232)
1186 			break;
1187 	case 8:
1188 		if (on) b->bcr1b |= BCR1_DTR(c->num & 3);
1189 		else    b->bcr1b &= ~BCR1_DTR(c->num & 3);
1190 		outw (BCR1(b->port+0x10), b->bcr1b);
1191 		break;
1192 	}
1193 }
1194 
1195 /*
1196  * Control RTS signal for the channel.
1197  * Turn it on/off.
1198  */
cx_set_rts(cx_chan_t * c,int on)1199 void cx_set_rts (cx_chan_t *c, int on)
1200 {
1201 	c->rts = on ? 1 : 0;
1202 	outb (CAR(c->port), c->num & 3);
1203 	outb (MSVR_RTS(c->port), on ? MSV_RTS : 0);
1204 }
1205 
1206 /*
1207  * Get the state of DSR signal of the channel.
1208  */
cx_get_dsr(cx_chan_t * c)1209 int cx_get_dsr (cx_chan_t *c)
1210 {
1211 	unsigned char sigval;
1212 
1213 	if (c->board->type == B_SIGMA_2X ||
1214 	    c->board->type == B_SIGMA_800 ||
1215 	    c->mode == M_ASYNC) {
1216 		outb (CAR(c->port), c->num & 3);
1217 		return (inb (MSVR(c->port)) & MSV_DSR ? 1 : 0);
1218 	}
1219 
1220 	/*
1221 	 * Channels 4..7 and 12..15 don't have DSR signal available.
1222 	 */
1223 	switch (c->num) {
1224 	default:
1225 		return (1);
1226 
1227 	case 1: case 2:  case 3:
1228 		if (c->type == T_UNIV_RS232)
1229 			return (1);
1230 	case 0:
1231 		sigval = inw (BSR(c->board->port)) >> 8;
1232 		break;
1233 
1234 	case 9: case 10: case 11:
1235 		if (c->type == T_UNIV_RS232)
1236 			return (1);
1237 	case 8:
1238 		sigval = inw (BSR(c->board->port+0x10)) >> 8;
1239 		break;
1240 	}
1241 	return (~sigval >> (c->num & 3) & 1);
1242 }
1243 
1244 /*
1245  * Get the state of CARRIER signal of the channel.
1246  */
cx_get_cd(cx_chan_t * c)1247 int cx_get_cd (cx_chan_t *c)
1248 {
1249 	unsigned char sigval;
1250 
1251 	if (c->board->type == B_SIGMA_2X ||
1252 	    c->board->type == B_SIGMA_800 ||
1253 	    c->mode == M_ASYNC) {
1254 		outb (CAR(c->port), c->num & 3);
1255 		return (inb (MSVR(c->port)) & MSV_CD ? 1 : 0);
1256 	}
1257 
1258 	/*
1259 	 * Channels 4..7 and 12..15 don't have CD signal available.
1260 	 */
1261 	switch (c->num) {
1262 	default:
1263 		return (1);
1264 
1265 	case 1: case 2:  case 3:
1266 		if (c->type == T_UNIV_RS232)
1267 			return (1);
1268 	case 0:
1269 		sigval = inw (BSR(c->board->port)) >> 8;
1270 		break;
1271 
1272 	case 9: case 10: case 11:
1273 		if (c->type == T_UNIV_RS232)
1274 			return (1);
1275 	case 8:
1276 		sigval = inw (BSR(c->board->port+0x10)) >> 8;
1277 		break;
1278 	}
1279 	return (~sigval >> 4 >> (c->num & 3) & 1);
1280 }
1281 
1282 /*
1283  * Get the state of CTS signal of the channel.
1284  */
cx_get_cts(cx_chan_t * c)1285 int cx_get_cts (cx_chan_t *c)
1286 {
1287 	outb (CAR(c->port), c->num & 3);
1288 	return (inb (MSVR(c->port)) & MSV_CTS ? 1 : 0);
1289 }
1290 
1291 /*
1292  * Compute CD2400 clock values.
1293  */
cx_clock(long hz,long ba,int * clk,int * div)1294 void cx_clock (long hz, long ba, int *clk, int *div)
1295 {
1296 	static short clocktab[] = { 8, 32, 128, 512, 2048, 0 };
1297 
1298 	for (*clk=0; clocktab[*clk]; ++*clk) {
1299 		long c = ba * clocktab[*clk];
1300 		if (hz <= c*256) {
1301 			*div = (2 * hz + c) / (2 * c) - 1;
1302 			return;
1303 		}
1304 	}
1305 	/* Incorrect baud rate.  Return some meaningful values. */
1306 	*clk = 0;
1307 	*div = 255;
1308 }
1309 
1310 /*
1311  * Turn LED on/off.
1312  */
cx_led(cx_board_t * b,int on)1313 void cx_led (cx_board_t *b, int on)
1314 {
1315 	switch (b->type) {
1316 	case B_SIGMA_2X:
1317 		if (on) b->bcr0 |= BCR02X_LED;
1318 		else    b->bcr0 &= ~BCR02X_LED;
1319 		outb (BCR0(b->port), b->bcr0);
1320 		break;
1321 	}
1322 }
1323 
cx_disable_dma(cx_board_t * b)1324 void cx_disable_dma (cx_board_t *b)
1325 {
1326 #ifndef NDIS_MINIPORT_DRIVER
1327 	/* Disable DMA channel. */
1328 	outb (DMA_MASK, (b->dma & 3) | DMA_MASK_CLEAR);
1329 #endif
1330 }
1331 
1332 cx_board_opt_t board_opt_dflt = { /* board options */
1333 	BUS_NORMAL,		/* normal bus master timing */
1334 };
1335 
1336 cx_chan_opt_t chan_opt_dflt = { /* mode-independent options */
1337 	{			/* cor4 */
1338 		7,		/* FIFO threshold, odd is better */
1339 		0,
1340 		0,              /* don't detect 1 to 0 on CTS */
1341 		1,		/* detect 1 to 0 on CD */
1342 		0,              /* detect 1 to 0 on DSR */
1343 	},
1344 	{			/* cor5 */
1345 		0,		/* receive flow control FIFO threshold */
1346 		0,
1347 		0,              /* don't detect 0 to 1 on CTS */
1348 		1,		/* detect 0 to 1 on CD */
1349 		0,              /* detect 0 to 1 on DSR */
1350 	},
1351 	{			/* rcor */
1352 		0,		/* dummy clock source */
1353 		ENCOD_NRZ,      /* NRZ mode */
1354 		0,              /* disable DPLL */
1355 		0,
1356 		0,		/* transmit line value */
1357 	},
1358 	{			/* tcor */
1359 		0,
1360 		0,		/* local loopback mode */
1361 		0,
1362 		1,		/* external 1x clock mode */
1363 		0,
1364 		0,		/* dummy transmit clock source */
1365 	},
1366 };
1367 
1368 cx_opt_async_t opt_async_dflt = { /* default async options */
1369 	{			/* cor1 */
1370 		8-1,		/* 8-bit char length */
1371 		0,		/* don't ignore parity */
1372 		PARM_NOPAR,	/* no parity */
1373 		PAR_EVEN,	/* even parity */
1374 	},
1375 	{			/* cor2 */
1376 		0,              /* disable automatic DSR */
1377 		1,              /* enable automatic CTS */
1378 		0,              /* disable automatic RTS */
1379 		0,		/* no remote loopback */
1380 		0,
1381 		0,              /* disable embedded cmds */
1382 		0,		/* disable XON/XOFF */
1383 		0,		/* disable XANY */
1384 	},
1385 	{			/* cor3 */
1386 		STOPB_1,	/* 1 stop bit */
1387 		0,
1388 		0,		/* disable special char detection */
1389 		FLOWCC_PASS,	/* pass flow ctl chars to the host */
1390 		0,		/* range detect disable */
1391 		0,		/* disable extended spec. char detect */
1392 	},
1393 	{			/* cor6 */
1394 		PERR_INTR,	/* generate exception on parity errors */
1395 		BRK_INTR,	/* generate exception on break condition */
1396 		0,		/* don't translate NL to CR on input */
1397 		0,		/* don't translate CR to NL on input */
1398 		0,		/* don't discard CR on input */
1399 	},
1400 	{			/* cor7 */
1401 		0,		/* don't translate CR to NL on output */
1402 		0,		/* don't translate NL to CR on output */
1403 		0,
1404 		0,		/* don't process flow ctl err chars */
1405 		0,		/* disable LNext option */
1406 		0,		/* don't strip 8 bit on input */
1407 	},
1408 	0, 0, 0, 0, 0, 0, 0,	/* clear schr1-4, scrl, scrh, lnxt */
1409 };
1410 
1411 cx_opt_hdlc_t opt_hdlc_dflt = { /* default hdlc options */
1412 	{			/* cor1 */
1413 		2,              /* 2 inter-frame flags */
1414 		0,		/* no-address mode */
1415 		CLRDET_DISABLE,	/* disable clear detect */
1416 		AFLO_1OCT,	/* 1-byte address field length */
1417 	},
1418 	{			/* cor2 */
1419 		0,		/* disable automatic DSR */
1420 		0,              /* disable automatic CTS */
1421 		0,              /* disable automatic RTS */
1422 		0,
1423 		CRC_INVERT,	/* use CRC V.41 */
1424 		0,
1425 		FCS_NOTPASS,	/* don't pass received CRC to the host */
1426 		0,
1427 	},
1428 	{			/* cor3 */
1429 		0,              /* 0 pad characters sent */
1430 		IDLE_FLAG,	/* idle in flag */
1431 		0,		/* enable FCS */
1432 		FCSP_ONES,	/* FCS preset to all ones (V.41) */
1433 		SYNC_AA,	/* use AAh as sync char */
1434 		0,              /* disable pad characters */
1435 	},
1436 	0, 0, 0, 0,		/* clear rfar1-4 */
1437 	POLY_V41,		/* use V.41 CRC polynomial */
1438 };
1439