xref: /plan9/sys/src/9/pc/uartaxp.c (revision aa72973a2891ccbd3fb042462446761159389e19)
1 /*
2  * Avanstar Xp pci uart driver
3  */
4 #include "u.h"
5 #include "../port/lib.h"
6 #include "mem.h"
7 #include "dat.h"
8 #include "fns.h"
9 #include "io.h"
10 #include "../port/error.h"
11 
12 #include "uartaxp.i"
13 
14 typedef struct Cc Cc;
15 typedef struct Ccb Ccb;
16 typedef struct Ctlr Ctlr;
17 typedef struct Gcb Gcb;
18 
19 /*
20  * Global Control Block.
21  * Service Request fields must be accessed using XCHG.
22  */
23 struct Gcb {
24 	u16int	gcw;				/* Global Command Word */
25 	u16int	gsw;				/* Global Status Word */
26 	u16int	gsr;				/* Global Service Request */
27 	u16int	abs;				/* Available Buffer Space */
28 	u16int	bt;				/* Board Type */
29 	u16int	cpv;				/* Control Program Version */
30 	u16int	ccbn;				/* Ccb count */
31 	u16int	ccboff;				/* Ccb offset */
32 	u16int	ccbsz;				/* Ccb size */
33 	u16int	gcw2;				/* Global Command Word 2 */
34 	u16int	gsw2;				/* Global Status Word 2 */
35 	u16int	esr;				/* Error Service Request */
36 	u16int	isr;				/* Input Service Request */
37 	u16int	osr;				/* Output Service Request */
38 	u16int	msr;				/* Modem Service Request */
39 	u16int	csr;				/* Command Service Request */
40 };
41 
42 /*
43  * Channel Control Block.
44  */
45 struct Ccb {
46 	u16int	br;				/* Baud Rate */
47 	u16int	df;				/* Data Format */
48 	u16int	lp;				/* Line Protocol */
49 	u16int	ibs;				/* Input Buffer Size */
50 	u16int	obs;				/* Output Buffer Size */
51 	u16int 	ibtr;				/* Ib Trigger Rate */
52 	u16int	oblw;				/* Ob Low Watermark */
53 	u8int	ixon[2];			/* IXON characters */
54 	u16int	ibhw;				/* Ib High Watermark */
55 	u16int	iblw;				/* Ib Low Watermark */
56 	u16int	cc;				/* Channel Command */
57 	u16int	cs;				/* Channel Status */
58 	u16int	ibsa;				/* Ib Start Addr */
59 	u16int 	ibea;				/* Ib Ending Addr */
60 	u16int	obsa;				/* Ob Start Addr */
61 	u16int 	obea;				/* Ob Ending Addr */
62 	u16int	ibwp;				/* Ib write pointer (RO) */
63 	u16int	ibrp;				/* Ib read pointer (R/W) */
64 	u16int	obwp;				/* Ob write pointer (R/W) */
65 	u16int	obrp;				/* Ob read pointer (RO) */
66 	u16int	ces;				/* Communication Error Status */
67 	u16int	bcp;				/* Bad Character Pointer */
68 	u16int	mc;				/* Modem Control */
69 	u16int	ms;				/* Modem Status */
70 	u16int	bs;				/* Blocking Status */
71 	u16int	crf;				/* Character Received Flag */
72 	u8int	ixoff[2];			/* IXOFF characters */
73 	u16int	cs2;				/* Channel Status 2 */
74 	u8int	sec[2];				/* Strip/Error Characters */
75 };
76 
77 enum {						/* br */
78 	Br76800		= 0xFF00,
79 	Br115200	= 0xFF01,
80 };
81 
82 enum {						/* df */
83 	Db5		= 0x0000,		/* Data Bits - 5 bits/byte */
84 	Db6		= 0x0001,		/*	6 bits/byte */
85 	Db7		= 0x0002,		/*	7 bits/byte */
86 	Db8		= 0x0003,		/*	8 bits/byte */
87 	DbMASK		= 0x0003,
88 	Sb1		= 0x0000,		/* 1 Stop Bit */
89 	Sb2		= 0x0004,		/* 2 Stop Bit */
90 	SbMASK		= 0x0004,
91 	Np		= 0x0000,		/* No Parity */
92 	Op		= 0x0008,		/* Odd Parity */
93 	Ep		= 0x0010,		/* Even Parity */
94 	Mp		= 0x0020,		/* Mark Parity */
95 	Sp		= 0x0030,		/* Space Parity */
96 	PMASK		= 0x0038,
97 	Cmn		= 0x0000,		/* Channel Mode Normal */
98 	Cme		= 0x0040,		/* CM Echo */
99 	Cmll		= 0x0080,		/* CM Local Loopback */
100 	Cmrl		= 0x00C0,		/* CM Remote Loopback */
101 };
102 
103 enum {						/* lp */
104 	Ixon		= 0x0001,		/* Obey IXON/IXOFF */
105 	Ixany		= 0x0002,		/* Any character retarts Tx */
106 	Ixgen		= 0x0004,		/* Generate IXON/IXOFF  */
107 	Cts		= 0x0008,		/* CTS controls Tx */
108 	Dtr		= 0x0010,		/* Rx controls DTR */
109 	½d		= 0x0020,		/* RTS off during Tx */
110 	Rts		= 0x0040,		/* generate RTS */
111 	Emcs		= 0x0080,		/* Enable Modem Control */
112 	Ecs		= 0x1000,		/* Enable Character Stripping */
113 	Eia422		= 0x2000,		/* EIA422 */
114 };
115 
116 enum {						/* cc */
117 	Ccu		= 0x0001,		/* Configure Channel and UART */
118 	Cco		= 0x0002,		/* Configure Channel Only */
119 	Fib		= 0x0004,		/* Flush Input Buffer */
120 	Fob		= 0x0008,		/* Flush Output Buffer */
121 	Er		= 0x0010,		/* Enable Receiver */
122 	Dr		= 0x0020,		/* Disable Receiver */
123 	Et		= 0x0040,		/* Enable Transmitter */
124 	Dt		= 0x0080,		/* Disable Transmitter */
125 };
126 
127 enum {						/* ces */
128 	Oe		= 0x0001,		/* Overrun Error */
129 	Pe		= 0x0002,		/* Parity Error */
130 	Fe		= 0x0004,		/* Framing Error */
131 	Br		= 0x0008,		/* Break Received */
132 };
133 
134 enum {						/* mc */
135 	Adtr		= 0x0001,		/* Assert DTR */
136 	Arts		= 0x0002,		/* Assert RTS */
137 	Ab		= 0x0010,		/* Assert BREAK */
138 };
139 
140 enum {						/* ms */
141 	Scts		= 0x0001,		/* Status od CTS */
142 	Sdsr		= 0x0002,		/* Status of DSR */
143 	Sri		= 0x0004,		/* Status of RI */
144 	Sdcd		= 0x0008,		/* Status of DCD */
145 };
146 
147 enum {						/* bs */
148 	Rd		= 0x0001,		/* Receiver Disabled */
149 	Td		= 0x0002,		/* Transmitter Disabled */
150 	Tbxoff		= 0x0004,		/* Tx Blocked by XOFF */
151 	Tbcts		= 0x0008,		/* Tx Blocked by CTS */
152 	Rbxoff		= 0x0010,		/* Rx Blocked by XOFF */
153 	Rbrts		= 0x0020,		/* Rx Blocked by RTS */
154 };
155 
156 enum {						/* Local Configuration */
157 	Range		= 0x00,
158 	Remap		= 0x04,
159 	Region		= 0x18,
160 	Mb0		= 0x40,			/* Mailbox 0 */
161 	Ldb		= 0x60,			/* PCI to Local Doorbell */
162 	Pdb		= 0x64,			/* Local to PCI Doorbell */
163 	Ics		= 0x68,			/* Interrupt Control/Status */
164 	Mcc		= 0x6C,			/* Misc. Command and Control */
165 };
166 
167 enum {						/* Mb0 */
168 	Edcc		= 1,			/* exec. downloaded code cmd */
169 	Aic		= 0x10,			/* adapter init'zed correctly */
170 	Cpr		= 1ul << 31,		/* control program ready */
171 };
172 
173 enum {						/* Mcc */
174 	Rcr		= 1ul << 29,		/* reload config. reg.s */
175 	Asr		= 1ul << 30,		/* pci adapter sw reset */
176 	Lis		= 1ul << 31,		/* local init status */
177 };
178 
179 typedef struct Cc Cc;
180 typedef struct Ccb Ccb;
181 typedef struct Ctlr Ctlr;
182 
183 /*
184  * Channel Control, one per uart.
185  * Devuart communicates via the PhysUart functions with
186  * a Uart* argument. Uart.regs is filled in by this driver
187  * to point to a Cc, and Cc.ctlr points to the Axp board
188  * controller.
189  */
190 struct Cc {
191 	int	uartno;
192 	Ccb*	ccb;
193 	Ctlr*	ctlr;
194 
195 	Rendez;
196 
197 	Uart;
198 };
199 
200 typedef struct Ctlr {
201 	char*	name;
202 	Pcidev*	pcidev;
203 	int	ctlrno;
204 	Ctlr*	next;
205 
206 	u32int*	reg;
207 	uchar*	mem;
208 	Gcb*	gcb;
209 
210 	int	im;		/* interrupt mask */
211 	Cc	cc[16];
212 } Ctlr;
213 
214 #define csr32r(c, r)	(*((c)->reg+((r)/4)))
215 #define csr32w(c, r, v)	(*((c)->reg+((r)/4)) = (v))
216 
217 static Ctlr* axpctlrhead;
218 static Ctlr* axpctlrtail;
219 
220 extern PhysUart axpphysuart;
221 
222 static int
axpccdone(void * ccb)223 axpccdone(void* ccb)
224 {
225 	return !((Ccb*)ccb)->cc;	/* hw sets ccb->cc to zero */
226 }
227 
228 static void
axpcc(Cc * cc,int cmd)229 axpcc(Cc* cc, int cmd)
230 {
231 	Ccb *ccb;
232 	int timeo;
233 	u16int cs;
234 
235 	ccb = cc->ccb;
236 	ccb->cc = cmd;
237 
238 	if(!cc->ctlr->im)
239 		for(timeo = 0; timeo < 1000000; timeo++){
240 			if(!ccb->cc)
241 				break;
242 			microdelay(1);
243 		}
244 	else
245 		tsleep(cc, axpccdone, ccb, 1000);
246 
247 	cs = ccb->cs;
248 	if(ccb->cc || cs){
249 		print("%s: cmd %#ux didn't terminate: %#ux %#ux\n",
250 			cc->name, cmd, ccb->cc, cs);
251 		if(cc->ctlr->im)
252 			error(Eio);
253 	}
254 }
255 
256 static long
axpstatus(Uart * uart,void * buf,long n,long offset)257 axpstatus(Uart* uart, void* buf, long n, long offset)
258 {
259 	char *p;
260 	Ccb *ccb;
261 	u16int bs, fstat, ms;
262 
263 	p = malloc(READSTR);
264 	if(p == nil)
265 		error(Enomem);
266 	ccb = ((Cc*)(uart->regs))->ccb;
267 	bs = ccb->bs;
268 	fstat = ccb->df;
269 	ms = ccb->ms;
270 
271 	snprint(p, READSTR,
272 		"b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n"
273 		"dev(%d) type(%d) framing(%d) overruns(%d) "
274 		"berr(%d) serr(%d)%s%s%s%s\n",
275 
276 		uart->baud,
277 		uart->hup_dcd,
278 		ms & Sdsr,
279 		uart->hup_dsr,
280 		(fstat & DbMASK) + 5,
281 		0,
282 		(fstat & PMASK) ? ((fstat & Ep) == Ep? 'e': 'o'): 'n',
283 		(bs & Rbrts) ? 1 : 0,
284 		(fstat & Sb2) ? 2 : 1,
285 		0,
286 
287 		uart->dev,
288 		uart->type,
289 		uart->ferr,
290 		uart->oerr,
291 		uart->berr,
292 		uart->serr,
293 		(ms & Scts) ? " cts"  : "",
294 		(ms & Sdsr) ? " dsr"  : "",
295 		(ms & Sdcd) ? " dcd"  : "",
296 		(ms & Sri) ? " ring" : ""
297 	);
298 	n = readstr(offset, buf, n, p);
299 	free(p);
300 
301 	return n;
302 }
303 
304 static void
axpfifo(Uart *,int)305 axpfifo(Uart*, int)
306 {
307 }
308 
309 static void
axpdtr(Uart * uart,int on)310 axpdtr(Uart* uart, int on)
311 {
312 	Ccb *ccb;
313 	u16int mc;
314 
315 	ccb = ((Cc*)(uart->regs))->ccb;
316 
317 	mc = ccb->mc;
318 	if(on)
319 		mc |= Adtr;
320 	else
321 		mc &= ~Adtr;
322 	ccb->mc = mc;
323 }
324 
325 /*
326  * can be called from uartstageinput() during an input interrupt,
327  * with uart->rlock ilocked or the uart qlocked, sometimes both.
328  */
329 static void
axprts(Uart * uart,int on)330 axprts(Uart* uart, int on)
331 {
332 	Ccb *ccb;
333 	u16int mc;
334 
335 	ccb = ((Cc*)(uart->regs))->ccb;
336 
337 	mc = ccb->mc;
338 	if(on)
339 		mc |= Arts;
340 	else
341 		mc &= ~Arts;
342 	ccb->mc = mc;
343 }
344 
345 static void
axpmodemctl(Uart * uart,int on)346 axpmodemctl(Uart* uart, int on)
347 {
348 	Ccb *ccb;
349 	u16int lp;
350 
351 	ccb = ((Cc*)(uart->regs))->ccb;
352 
353 	ilock(&uart->tlock);
354 	lp = ccb->lp;
355 	if(on){
356 		lp |= Cts|Rts;
357 		lp &= ~Emcs;
358 		uart->cts = ccb->ms & Scts;
359 	}
360 	else{
361 		lp &= ~(Cts|Rts);
362 		lp |= Emcs;
363 		uart->cts = 1;
364 	}
365 	uart->modem = on;
366 	iunlock(&uart->tlock);
367 
368 	ccb->lp = lp;
369 	axpcc(uart->regs, Ccu);
370 }
371 
372 static int
axpparity(Uart * uart,int parity)373 axpparity(Uart* uart, int parity)
374 {
375 	Ccb *ccb;
376 	u16int df;
377 
378 	switch(parity){
379 	default:
380 		return -1;
381 	case 'e':
382 		parity = Ep;
383 		break;
384 	case 'o':
385 		parity = Op;
386 		break;
387 	case 'n':
388 		parity = Np;
389 		break;
390 	}
391 
392 	ccb = ((Cc*)(uart->regs))->ccb;
393 
394 	df = ccb->df & ~PMASK;
395 	ccb->df = df|parity;
396 	axpcc(uart->regs, Ccu);
397 
398 	return 0;
399 }
400 
401 static int
axpstop(Uart * uart,int stop)402 axpstop(Uart* uart, int stop)
403 {
404 	Ccb *ccb;
405 	u16int df;
406 
407 	switch(stop){
408 	default:
409 		return -1;
410 	case 1:
411 		stop = Sb1;
412 		break;
413 	case 2:
414 		stop = Sb2;
415 		break;
416 	}
417 
418 	ccb = ((Cc*)(uart->regs))->ccb;
419 
420 	df = ccb->df & ~SbMASK;
421 	ccb->df = df|stop;
422 	axpcc(uart->regs, Ccu);
423 
424 	return 0;
425 }
426 
427 static int
axpbits(Uart * uart,int bits)428 axpbits(Uart* uart, int bits)
429 {
430 	Ccb *ccb;
431 	u16int df;
432 
433 	bits -= 5;
434 	if(bits < 0 || bits > 3)
435 		return -1;
436 
437 	ccb = ((Cc*)(uart->regs))->ccb;
438 
439 	df = ccb->df & ~DbMASK;
440 	ccb->df = df|bits;
441 	axpcc(uart->regs, Ccu);
442 
443 	return 0;
444 }
445 
446 static int
axpbaud(Uart * uart,int baud)447 axpbaud(Uart* uart, int baud)
448 {
449 	Ccb *ccb;
450 	int i, ibtr;
451 
452 	/*
453 	 * Set baud rate (high rates are special - only 16 bits).
454 	 */
455 	if(baud <= 0)
456 		return -1;
457 	uart->baud = baud;
458 
459 	ccb = ((Cc*)(uart->regs))->ccb;
460 
461 	switch(baud){
462 	default:
463 		ccb->br = baud;
464 		break;
465 	case 76800:
466 		ccb->br = Br76800;
467 		break;
468 	case 115200:
469 		ccb->br = Br115200;
470 		break;
471 	}
472 
473 	/*
474 	 * Set trigger level to about 50 per second.
475 	 */
476 	ibtr = baud/500;
477 	i = (ccb->ibea - ccb->ibsa)/2;
478 	if(ibtr > i)
479 		ibtr = i;
480 	ccb->ibtr = ibtr;
481 	axpcc(uart->regs, Ccu);
482 
483 	return 0;
484 }
485 
486 static void
axpbreak(Uart * uart,int ms)487 axpbreak(Uart* uart, int ms)
488 {
489 	Ccb *ccb;
490 	u16int mc;
491 
492 	/*
493 	 * Send a break.
494 	 */
495 	if(ms <= 0)
496 		ms = 200;
497 
498 	ccb = ((Cc*)(uart->regs))->ccb;
499 
500 	mc = ccb->mc;
501 	ccb->mc = Ab|mc;
502 	tsleep(&up->sleep, return0, 0, ms);
503 	ccb->mc = mc & ~Ab;
504 }
505 
506 /* only called from interrupt service */
507 static void
axpmc(Cc * cc)508 axpmc(Cc* cc)
509 {
510 	int old;
511 	Ccb *ccb;
512 	u16int ms;
513 
514 	ccb = cc->ccb;
515 
516 	ms = ccb->ms;
517 
518 	if(ms & Scts){
519 		ilock(&cc->tlock);
520 		old = cc->cts;
521 		cc->cts = ms & Scts;
522 		if(old == 0 && cc->cts)
523 			cc->ctsbackoff = 2;
524 		iunlock(&cc->tlock);
525 	}
526 	if(ms & Sdsr){
527 		old = ms & Sdsr;
528 		if(cc->hup_dsr && cc->dsr && !old)
529 			cc->dohup = 1;
530 		cc->dsr = old;
531 	}
532 	if(ms & Sdcd){
533 		old = ms & Sdcd;
534 		if(cc->hup_dcd && cc->dcd && !old)
535 			cc->dohup = 1;
536 		cc->dcd = old;
537 	}
538 }
539 
540 /* called from uartkick() with uart->tlock ilocked */
541 static void
axpkick(Uart * uart)542 axpkick(Uart* uart)
543 {
544 	Cc *cc;
545 	Ccb *ccb;
546 	uchar *ep, *mem, *rp, *wp, *bp;
547 
548 	if(uart->cts == 0 || uart->blocked)
549 		return;
550 
551 	cc = uart->regs;
552 	ccb = cc->ccb;
553 
554 	mem = (uchar*)cc->ctlr->gcb;
555 	bp = mem + ccb->obsa;
556 	rp = mem + ccb->obrp;
557 	wp = mem + ccb->obwp;
558 	ep = mem + ccb->obea;
559 	while(wp != rp-1 && (rp != bp || wp != ep)){
560 		/*
561 		 * if we've exhausted the uart's output buffer,
562 		 * ask for more from the output queue, and quit if there
563 		 * isn't any.
564 		 */
565 		if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
566 			break;
567 		*wp++ = *(uart->op++);
568 		if(wp > ep)
569 			wp = bp;
570 		ccb->obwp = wp - mem;
571 	}
572 }
573 
574 /* only called from interrupt service */
575 static void
axprecv(Cc * cc)576 axprecv(Cc* cc)
577 {
578 	Ccb *ccb;
579 	uchar *ep, *mem, *rp, *wp;
580 
581 	ccb = cc->ccb;
582 
583 	mem = (uchar*)cc->ctlr->gcb;
584 	rp = mem + ccb->ibrp;
585 	wp = mem + ccb->ibwp;
586 	ep = mem + ccb->ibea;
587 
588 	while(rp != wp){
589 		uartrecv(cc, *rp++);		/* ilocks cc->tlock */
590 		if(rp > ep)
591 			rp = mem + ccb->ibsa;
592 		ccb->ibrp = rp - mem;
593 	}
594 }
595 
596 static void
axpinterrupt(Ureg *,void * arg)597 axpinterrupt(Ureg*, void* arg)
598 {
599 	int work;
600 	Cc *cc;
601 	Ctlr *ctlr;
602 	u32int ics;
603 	u16int r, sr;
604 
605 	work = 0;
606 	ctlr = arg;
607 	ics = csr32r(ctlr, Ics);
608 	if(ics & 0x0810C000)
609 		print("%s: unexpected interrupt %#ux\n", ctlr->name, ics);
610 	if(!(ics & 0x00002000)) {
611 		/* we get a steady stream of these on consoles */
612 		// print("%s: non-doorbell interrupt\n", ctlr->name);
613 		ctlr->gcb->gcw2 = 0x0001;	/* set Gintack */
614 		return;
615 	}
616 
617 //	while(work to do){
618 		cc = ctlr->cc;
619 		for(sr = xchgw(&ctlr->gcb->isr, 0); sr != 0; sr >>= 1){
620 			if(sr & 0x0001)
621 				work++, axprecv(cc);
622 			cc++;
623 		}
624 		cc = ctlr->cc;
625 		for(sr = xchgw(&ctlr->gcb->osr, 0); sr != 0; sr >>= 1){
626 			if(sr & 0x0001)
627 				work++, uartkick(&cc->Uart);
628 			cc++;
629 		}
630 		cc = ctlr->cc;
631 		for(sr = xchgw(&ctlr->gcb->csr, 0); sr != 0; sr >>= 1){
632 			if(sr & 0x0001)
633 				work++, wakeup(cc);
634 			cc++;
635 		}
636 		cc = ctlr->cc;
637 		for(sr = xchgw(&ctlr->gcb->msr, 0); sr != 0; sr >>= 1){
638 			if(sr & 0x0001)
639 				work++, axpmc(cc);
640 			cc++;
641 		}
642 		cc = ctlr->cc;
643 		for(sr = xchgw(&ctlr->gcb->esr, 0); sr != 0; sr >>= 1){
644 			if(sr & 0x0001){
645 				r = cc->ccb->ms;
646 				if(r & Oe)
647 					cc->oerr++;
648 				if(r & Pe)
649 					cc->perr++;
650 				if(r & Fe)
651 					cc->ferr++;
652 				if (r & (Oe|Pe|Fe))
653 					work++;
654 			}
655 			cc++;
656 		}
657 //	}
658 	/* only meaningful if we don't share the irq */
659 	if (0 && !work)
660 		print("%s: interrupt with no work\n", ctlr->name);
661 	csr32w(ctlr, Pdb, 1);		/* clear doorbell interrupt */
662 	ctlr->gcb->gcw2 = 0x0001;	/* set Gintack */
663 }
664 
665 static void
axpdisable(Uart * uart)666 axpdisable(Uart* uart)
667 {
668 	Cc *cc;
669 	u16int lp;
670 	Ctlr *ctlr;
671 
672 	/*
673  	 * Turn off DTR and RTS, disable interrupts.
674 	 */
675 	(*uart->phys->dtr)(uart, 0);
676 	(*uart->phys->rts)(uart, 0);
677 
678 	cc = uart->regs;
679 	lp = cc->ccb->lp;
680 	cc->ccb->lp = Emcs|lp;
681 	axpcc(cc, Dt|Dr|Fob|Fib|Ccu);
682 
683 	/*
684 	 * The Uart is qlocked.
685 	 */
686 	ctlr = cc->ctlr;
687 	ctlr->im &= ~(1<<cc->uartno);
688 	if(ctlr->im == 0)
689 		intrdisable(ctlr->pcidev->intl, axpinterrupt, ctlr,
690 			ctlr->pcidev->tbdf, ctlr->name);
691 }
692 
693 static void
axpenable(Uart * uart,int ie)694 axpenable(Uart* uart, int ie)
695 {
696 	Cc *cc;
697 	Ctlr *ctlr;
698 	u16int lp;
699 
700 	cc = uart->regs;
701 	ctlr = cc->ctlr;
702 
703 	/*
704  	 * Enable interrupts and turn on DTR and RTS.
705 	 * Be careful if this is called to set up a polled serial line
706 	 * early on not to try to enable interrupts as interrupt-
707 	 * -enabling mechanisms might not be set up yet.
708 	 */
709 	if(ie){
710 		/*
711 		 * The Uart is qlocked.
712 		 */
713 		if(ctlr->im == 0){
714 			intrenable(ctlr->pcidev->intl, axpinterrupt, ctlr,
715 				ctlr->pcidev->tbdf, ctlr->name);
716 			csr32w(ctlr, Ics, 0x00031F00);
717 			csr32w(ctlr, Pdb, 1);
718 			ctlr->gcb->gcw2 = 1;
719 		}
720 		ctlr->im |= 1<<cc->uartno;
721 	}
722 
723 	(*uart->phys->dtr)(uart, 1);
724 	(*uart->phys->rts)(uart, 1);
725 
726 	/*
727 	 * Make sure we control RTS, DTR and break.
728 	 */
729 	lp = cc->ccb->lp;
730 	cc->ccb->lp = Emcs|lp;
731 	cc->ccb->oblw = 64;
732 	axpcc(cc, Et|Er|Ccu);
733 }
734 
735 static void*
axpdealloc(Ctlr * ctlr)736 axpdealloc(Ctlr* ctlr)
737 {
738 	int i;
739 
740 	for(i = 0; i < 16; i++){
741 		if(ctlr->cc[i].name != nil)
742 			free(ctlr->cc[i].name);
743 	}
744 	if(ctlr->reg != nil)
745 		vunmap(ctlr->reg, ctlr->pcidev->mem[0].size);
746 	if(ctlr->mem != nil)
747 		vunmap(ctlr->mem, ctlr->pcidev->mem[2].size);
748 	if(ctlr->name != nil)
749 		free(ctlr->name);
750 	free(ctlr);
751 
752 	return nil;
753 }
754 
755 static Uart*
axpalloc(int ctlrno,Pcidev * pcidev)756 axpalloc(int ctlrno, Pcidev* pcidev)
757 {
758 	Cc *cc;
759 	uchar *p;
760 	Ctlr *ctlr;
761 	void *addr;
762 	char name[64];
763 	u32int bar, r;
764 	int i, n, timeo;
765 
766 	ctlr = malloc(sizeof(Ctlr));
767 	if(ctlr == nil)
768 		error(Enomem);
769 	seprint(name, name+sizeof(name), "uartaxp%d", ctlrno);
770 	kstrdup(&ctlr->name, name);
771 	ctlr->pcidev = pcidev;
772 	ctlr->ctlrno = ctlrno;
773 
774 	/*
775 	 * Access to runtime registers.
776 	 */
777 	bar = pcidev->mem[0].bar;
778 	if((addr = vmap(bar & ~0x0F, pcidev->mem[0].size)) == 0){
779 		print("%s: can't map registers at %#ux\n", ctlr->name, bar);
780 		return axpdealloc(ctlr);
781 	}
782 	ctlr->reg = addr;
783 	print("%s: port 0x%ux irq %d ", ctlr->name, bar, pcidev->intl);
784 
785 	/*
786 	 * Local address space 0.
787 	 */
788 	bar = pcidev->mem[2].bar;
789 	if((addr = vmap(bar & ~0x0F, pcidev->mem[2].size)) == 0){
790 		print("%s: can't map memory at %#ux\n", ctlr->name, bar);
791 		return axpdealloc(ctlr);
792 	}
793 	ctlr->mem = addr;
794 	ctlr->gcb = (Gcb*)(ctlr->mem+0x10000);
795 	print("mem 0x%ux size %d: ", bar, pcidev->mem[2].size);
796 
797 	/*
798 	 * Toggle the software reset and wait for
799 	 * the adapter local init status to indicate done.
800 	 *
801 	 * The two 'delay(100)'s below are important,
802 	 * without them the board seems to become confused
803 	 * (perhaps it needs some 'quiet time' because the
804 	 * timeout loops are not sufficient in themselves).
805 	 */
806 	r = csr32r(ctlr, Mcc);
807 	csr32w(ctlr, Mcc, r|Asr);
808 	microdelay(1);
809 	csr32w(ctlr, Mcc, r&~Asr);
810 	delay(100);
811 
812 	for(timeo = 0; timeo < 100000; timeo++){
813 		if(csr32r(ctlr, Mcc) & Lis)
814 			break;
815 		microdelay(1);
816 	}
817 	if(!(csr32r(ctlr, Mcc) & Lis)){
818 		print("%s: couldn't reset\n", ctlr->name);
819 		return axpdealloc(ctlr);
820 	}
821 	print("downloading...");
822 	/*
823 	 * Copy the control programme to the card memory.
824 	 * The card's i960 control structures live at 0xD000.
825 	 */
826 	if(sizeof(uartaxpcp) > 0xD000){
827 		print("%s: control programme too big\n", ctlr->name);
828 		return axpdealloc(ctlr);
829 	}
830 	/* TODO: is this right for more than 1 card? devastar does the same */
831 	csr32w(ctlr, Remap, 0xA0000001);
832 	for(i = 0; i < sizeof(uartaxpcp); i++)
833 		ctlr->mem[i] = uartaxpcp[i];
834 	/*
835 	 * Execute downloaded code and wait for it
836 	 * to signal ready.
837 	 */
838 	csr32w(ctlr, Mb0, Edcc);
839 	delay(100);
840 	/* the manual says to wait for Cpr for 1 second */
841 	for(timeo = 0; timeo < 10000; timeo++){
842 		if(csr32r(ctlr, Mb0) & Cpr)
843 			break;
844 		microdelay(100);
845 	}
846 	if(!(csr32r(ctlr, Mb0) & Cpr)){
847 		print("control programme not ready; Mb0 %#ux\n",
848 			csr32r(ctlr, Mb0));
849 		print("%s: distribution panel not connected or card not fully seated?\n",
850 			ctlr->name);
851 
852 		return axpdealloc(ctlr);
853 	}
854 	print("\n");
855 
856 	n = ctlr->gcb->ccbn;
857 	if(ctlr->gcb->bt != 0x12 || n > 16){
858 		print("%s: wrong board type %#ux, %d channels\n",
859 			ctlr->name, ctlr->gcb->bt, ctlr->gcb->ccbn);
860 		return axpdealloc(ctlr);
861 	}
862 
863 	p = ((uchar*)ctlr->gcb) + ctlr->gcb->ccboff;
864 	for(i = 0; i < n; i++){
865 		cc = &ctlr->cc[i];
866 		cc->ccb = (Ccb*)p;
867 		p += ctlr->gcb->ccbsz;
868 		cc->uartno = i;
869 		cc->ctlr = ctlr;
870 
871 		cc->regs = cc;		/* actually Uart->regs */
872 		seprint(name, name+sizeof(name), "uartaxp%d%2.2d", ctlrno, i);
873 		kstrdup(&cc->name, name);
874 		cc->freq = 0;
875 		cc->bits = 8;
876 		cc->stop = 1;
877 		cc->parity = 'n';
878 		cc->baud = 9600;
879 		cc->phys = &axpphysuart;
880 		cc->console = 0;
881 		cc->special = 0;
882 
883 		cc->next = &ctlr->cc[i+1];
884 	}
885 	ctlr->cc[n-1].next = nil;
886 
887 	ctlr->next = nil;
888 	if(axpctlrhead != nil)
889 		axpctlrtail->next = ctlr;
890 	else
891 		axpctlrhead = ctlr;
892 	axpctlrtail = ctlr;
893 
894 	return ctlr->cc;
895 }
896 
897 static Uart*
axppnp(void)898 axppnp(void)
899 {
900 	Pcidev *p;
901 	int ctlrno;
902 	Uart *head, *tail, *uart;
903 
904 	/*
905 	 * Loop through all PCI devices looking for simple serial
906 	 * controllers (ccrb == 0x07) and configure the ones which
907 	 * are familiar.
908 	 */
909 	head = tail = nil;
910 	ctlrno = 0;
911 	for(p = pcimatch(nil, 0, 0); p != nil; p = pcimatch(p, 0, 0)){
912 		if(p->ccrb != 0x07)
913 			continue;
914 
915 		switch((p->did<<16)|p->vid){
916 		default:
917 			continue;
918 		case (0x6001<<16)|0x114F:	/* AvanstarXp */
919 			if((uart = axpalloc(ctlrno, p)) == nil)
920 				continue;
921 			break;
922 		}
923 
924 		if(head != nil)
925 			tail->next = uart;
926 		else
927 			head = uart;
928 		for(tail = uart; tail->next != nil; tail = tail->next)
929 			;
930 		ctlrno++;
931 	}
932 
933 	return head;
934 }
935 
936 PhysUart axpphysuart = {
937 	.name		= "AvanstarXp",
938 	.pnp		= axppnp,
939 	.enable		= axpenable,
940 	.disable	= axpdisable,
941 	.kick		= axpkick,
942 	.dobreak	= axpbreak,
943 	.baud		= axpbaud,
944 	.bits		= axpbits,
945 	.stop		= axpstop,
946 	.parity		= axpparity,
947 	.modemctl	= axpmodemctl,
948 	.rts		= axprts,
949 	.dtr		= axpdtr,
950 	.status		= axpstatus,
951 	.fifo		= axpfifo,
952 	.getc		= nil,
953 	.putc		= nil,
954 };
955