FreeBSD/Linux Kernel Cross Reference
sys/pc/uartaxp.c
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
223 axpccdone(void* ccb)
224 {
225 return !((Ccb*)ccb)->cc; /* hw sets ccb->cc to zero */
226 }
227
228 static void
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
257 axpstatus(Uart* uart, void* buf, long n, long offset)
258 {
259 char *p;
260 Ccb *ccb;
261 u16int bs, fstat, ms;
262
263 ccb = ((Cc*)(uart->regs))->ccb;
264
265 p = malloc(READSTR);
266 bs = ccb->bs;
267 fstat = ccb->df;
268 ms = ccb->ms;
269
270 snprint(p, READSTR,
271 "b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n"
272 "dev(%d) type(%d) framing(%d) overruns(%d) "
273 "berr(%d) serr(%d)%s%s%s%s\n",
274
275 uart->baud,
276 uart->hup_dcd,
277 ms & Sdsr,
278 uart->hup_dsr,
279 (fstat & DbMASK) + 5,
280 0,
281 (fstat & PMASK) ? ((fstat & Ep) == Ep? 'e': 'o'): 'n',
282 (bs & Rbrts) ? 1 : 0,
283 (fstat & Sb2) ? 2 : 1,
284 0,
285
286 uart->dev,
287 uart->type,
288 uart->ferr,
289 uart->oerr,
290 uart->berr,
291 uart->serr,
292 (ms & Scts) ? " cts" : "",
293 (ms & Sdsr) ? " dsr" : "",
294 (ms & Sdcd) ? " dcd" : "",
295 (ms & Sri) ? " ring" : ""
296 );
297 n = readstr(offset, buf, n, p);
298 free(p);
299
300 return n;
301 }
302
303 static void
304 axpfifo(Uart*, int)
305 {
306 }
307
308 static void
309 axpdtr(Uart* uart, int on)
310 {
311 Ccb *ccb;
312 u16int mc;
313
314 ccb = ((Cc*)(uart->regs))->ccb;
315
316 mc = ccb->mc;
317 if(on)
318 mc |= Adtr;
319 else
320 mc &= ~Adtr;
321 ccb->mc = mc;
322 }
323
324 /*
325 * can be called from uartstageinput() during an input interrupt,
326 * with uart->rlock ilocked or the uart qlocked, sometimes both.
327 */
328 static void
329 axprts(Uart* uart, int on)
330 {
331 Ccb *ccb;
332 u16int mc;
333
334 ccb = ((Cc*)(uart->regs))->ccb;
335
336 mc = ccb->mc;
337 if(on)
338 mc |= Arts;
339 else
340 mc &= ~Arts;
341 ccb->mc = mc;
342 }
343
344 static void
345 axpmodemctl(Uart* uart, int on)
346 {
347 Ccb *ccb;
348 u16int lp;
349
350 ccb = ((Cc*)(uart->regs))->ccb;
351
352 ilock(&uart->tlock);
353 lp = ccb->lp;
354 if(on){
355 lp |= Cts|Rts;
356 lp &= ~Emcs;
357 uart->cts = ccb->ms & Scts;
358 }
359 else{
360 lp &= ~(Cts|Rts);
361 lp |= Emcs;
362 uart->cts = 1;
363 }
364 uart->modem = on;
365 iunlock(&uart->tlock);
366
367 ccb->lp = lp;
368 axpcc(uart->regs, Ccu);
369 }
370
371 static int
372 axpparity(Uart* uart, int parity)
373 {
374 Ccb *ccb;
375 u16int df;
376
377 switch(parity){
378 default:
379 return -1;
380 case 'e':
381 parity = Ep;
382 break;
383 case 'o':
384 parity = Op;
385 break;
386 case 'n':
387 parity = Np;
388 break;
389 }
390
391 ccb = ((Cc*)(uart->regs))->ccb;
392
393 df = ccb->df & ~PMASK;
394 ccb->df = df|parity;
395 axpcc(uart->regs, Ccu);
396
397 return 0;
398 }
399
400 static int
401 axpstop(Uart* uart, int stop)
402 {
403 Ccb *ccb;
404 u16int df;
405
406 switch(stop){
407 default:
408 return -1;
409 case 1:
410 stop = Sb1;
411 break;
412 case 2:
413 stop = Sb2;
414 break;
415 }
416
417 ccb = ((Cc*)(uart->regs))->ccb;
418
419 df = ccb->df & ~SbMASK;
420 ccb->df = df|stop;
421 axpcc(uart->regs, Ccu);
422
423 return 0;
424 }
425
426 static int
427 axpbits(Uart* uart, int bits)
428 {
429 Ccb *ccb;
430 u16int df;
431
432 bits -= 5;
433 if(bits < 0 || bits > 3)
434 return -1;
435
436 ccb = ((Cc*)(uart->regs))->ccb;
437
438 df = ccb->df & ~DbMASK;
439 ccb->df = df|bits;
440 axpcc(uart->regs, Ccu);
441
442 return 0;
443 }
444
445 static int
446 axpbaud(Uart* uart, int baud)
447 {
448 Ccb *ccb;
449 int i, ibtr;
450
451 /*
452 * Set baud rate (high rates are special - only 16 bits).
453 */
454 if(baud <= 0)
455 return -1;
456 uart->baud = baud;
457
458 ccb = ((Cc*)(uart->regs))->ccb;
459
460 switch(baud){
461 default:
462 ccb->br = baud;
463 break;
464 case 76800:
465 ccb->br = Br76800;
466 break;
467 case 115200:
468 ccb->br = Br115200;
469 break;
470 }
471
472 /*
473 * Set trigger level to about 50 per second.
474 */
475 ibtr = baud/500;
476 i = (ccb->ibea - ccb->ibsa)/2;
477 if(ibtr > i)
478 ibtr = i;
479 ccb->ibtr = ibtr;
480 axpcc(uart->regs, Ccu);
481
482 return 0;
483 }
484
485 static void
486 axpbreak(Uart* uart, int ms)
487 {
488 Ccb *ccb;
489 u16int mc;
490
491 /*
492 * Send a break.
493 */
494 if(ms <= 0)
495 ms = 200;
496
497 ccb = ((Cc*)(uart->regs))->ccb;
498
499 mc = ccb->mc;
500 ccb->mc = Ab|mc;
501 tsleep(&up->sleep, return0, 0, ms);
502 ccb->mc = mc & ~Ab;
503 }
504
505 /* only called from interrupt service */
506 static void
507 axpmc(Cc* cc)
508 {
509 int old;
510 Ccb *ccb;
511 u16int ms;
512
513 ccb = cc->ccb;
514
515 ms = ccb->ms;
516
517 if(ms & Scts){
518 ilock(&cc->tlock);
519 old = cc->cts;
520 cc->cts = ms & Scts;
521 if(old == 0 && cc->cts)
522 cc->ctsbackoff = 2;
523 iunlock(&cc->tlock);
524 }
525 if(ms & Sdsr){
526 old = ms & Sdsr;
527 if(cc->hup_dsr && cc->dsr && !old)
528 cc->dohup = 1;
529 cc->dsr = old;
530 }
531 if(ms & Sdcd){
532 old = ms & Sdcd;
533 if(cc->hup_dcd && cc->dcd && !old)
534 cc->dohup = 1;
535 cc->dcd = old;
536 }
537 }
538
539 /* called from uartkick() with uart->tlock ilocked */
540 static void
541 axpkick(Uart* uart)
542 {
543 Cc *cc;
544 Ccb *ccb;
545 uchar *ep, *mem, *rp, *wp, *bp;
546
547 if(uart->cts == 0 || uart->blocked)
548 return;
549
550 cc = uart->regs;
551 ccb = cc->ccb;
552
553 mem = (uchar*)cc->ctlr->gcb;
554 bp = mem + ccb->obsa;
555 rp = mem + ccb->obrp;
556 wp = mem + ccb->obwp;
557 ep = mem + ccb->obea;
558 while(wp != rp-1 && (rp != bp || wp != ep)){
559 /*
560 * if we've exhausted the uart's output buffer,
561 * ask for more from the output queue, and quit if there
562 * isn't any.
563 */
564 if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
565 break;
566 *wp++ = *(uart->op++);
567 if(wp > ep)
568 wp = bp;
569 ccb->obwp = wp - mem;
570 }
571 }
572
573 /* only called from interrupt service */
574 static void
575 axprecv(Cc* cc)
576 {
577 Ccb *ccb;
578 uchar *ep, *mem, *rp, *wp;
579
580 ccb = cc->ccb;
581
582 mem = (uchar*)cc->ctlr->gcb;
583 rp = mem + ccb->ibrp;
584 wp = mem + ccb->ibwp;
585 ep = mem + ccb->ibea;
586
587 while(rp != wp){
588 uartrecv(cc, *rp++); /* ilocks cc->tlock */
589 if(rp > ep)
590 rp = mem + ccb->ibsa;
591 ccb->ibrp = rp - mem;
592 }
593 }
594
595 static void
596 axpinterrupt(Ureg*, void* arg)
597 {
598 int work;
599 Cc *cc;
600 Ctlr *ctlr;
601 u32int ics;
602 u16int r, sr;
603
604 work = 0;
605 ctlr = arg;
606 ics = csr32r(ctlr, Ics);
607 if(ics & 0x0810C000)
608 print("%s: unexpected interrupt %#ux\n", ctlr->name, ics);
609 if(!(ics & 0x00002000)) {
610 /* we get a steady stream of these on consoles */
611 // print("%s: non-doorbell interrupt\n", ctlr->name);
612 ctlr->gcb->gcw2 = 0x0001; /* set Gintack */
613 return;
614 }
615
616 // while(work to do){
617 cc = ctlr->cc;
618 for(sr = xchgw(&ctlr->gcb->isr, 0); sr != 0; sr >>= 1){
619 if(sr & 0x0001)
620 work++, axprecv(cc);
621 cc++;
622 }
623 cc = ctlr->cc;
624 for(sr = xchgw(&ctlr->gcb->osr, 0); sr != 0; sr >>= 1){
625 if(sr & 0x0001)
626 work++, uartkick(&cc->Uart);
627 cc++;
628 }
629 cc = ctlr->cc;
630 for(sr = xchgw(&ctlr->gcb->csr, 0); sr != 0; sr >>= 1){
631 if(sr & 0x0001)
632 work++, wakeup(cc);
633 cc++;
634 }
635 cc = ctlr->cc;
636 for(sr = xchgw(&ctlr->gcb->msr, 0); sr != 0; sr >>= 1){
637 if(sr & 0x0001)
638 work++, axpmc(cc);
639 cc++;
640 }
641 cc = ctlr->cc;
642 for(sr = xchgw(&ctlr->gcb->esr, 0); sr != 0; sr >>= 1){
643 if(sr & 0x0001){
644 r = cc->ccb->ms;
645 if(r & Oe)
646 cc->oerr++;
647 if(r & Pe)
648 cc->perr++;
649 if(r & Fe)
650 cc->ferr++;
651 if (r & (Oe|Pe|Fe))
652 work++;
653 }
654 cc++;
655 }
656 // }
657 /* only meaningful if we don't share the irq */
658 if (0 && !work)
659 print("%s: interrupt with no work\n", ctlr->name);
660 csr32w(ctlr, Pdb, 1); /* clear doorbell interrupt */
661 ctlr->gcb->gcw2 = 0x0001; /* set Gintack */
662 }
663
664 static void
665 axpdisable(Uart* uart)
666 {
667 Cc *cc;
668 u16int lp;
669 Ctlr *ctlr;
670
671 /*
672 * Turn off DTR and RTS, disable interrupts.
673 */
674 (*uart->phys->dtr)(uart, 0);
675 (*uart->phys->rts)(uart, 0);
676
677 cc = uart->regs;
678 lp = cc->ccb->lp;
679 cc->ccb->lp = Emcs|lp;
680 axpcc(cc, Dt|Dr|Fob|Fib|Ccu);
681
682 /*
683 * The Uart is qlocked.
684 */
685 ctlr = cc->ctlr;
686 ctlr->im &= ~(1<<cc->uartno);
687 if(ctlr->im == 0)
688 intrdisable(ctlr->pcidev->intl, axpinterrupt, ctlr,
689 ctlr->pcidev->tbdf, ctlr->name);
690 }
691
692 static void
693 axpenable(Uart* uart, int ie)
694 {
695 Cc *cc;
696 Ctlr *ctlr;
697 u16int lp;
698
699 cc = uart->regs;
700 ctlr = cc->ctlr;
701
702 /*
703 * Enable interrupts and turn on DTR and RTS.
704 * Be careful if this is called to set up a polled serial line
705 * early on not to try to enable interrupts as interrupt-
706 * -enabling mechanisms might not be set up yet.
707 */
708 if(ie){
709 /*
710 * The Uart is qlocked.
711 */
712 if(ctlr->im == 0){
713 intrenable(ctlr->pcidev->intl, axpinterrupt, ctlr,
714 ctlr->pcidev->tbdf, ctlr->name);
715 csr32w(ctlr, Ics, 0x00031F00);
716 csr32w(ctlr, Pdb, 1);
717 ctlr->gcb->gcw2 = 1;
718 }
719 ctlr->im |= 1<<cc->uartno;
720 }
721
722 (*uart->phys->dtr)(uart, 1);
723 (*uart->phys->rts)(uart, 1);
724
725 /*
726 * Make sure we control RTS, DTR and break.
727 */
728 lp = cc->ccb->lp;
729 cc->ccb->lp = Emcs|lp;
730 cc->ccb->oblw = 64;
731 axpcc(cc, Et|Er|Ccu);
732 }
733
734 static void*
735 axpdealloc(Ctlr* ctlr)
736 {
737 int i;
738
739 for(i = 0; i < 16; i++){
740 if(ctlr->cc[i].name != nil)
741 free(ctlr->cc[i].name);
742 }
743 if(ctlr->reg != nil)
744 vunmap(ctlr->reg, ctlr->pcidev->mem[0].size);
745 if(ctlr->mem != nil)
746 vunmap(ctlr->mem, ctlr->pcidev->mem[2].size);
747 if(ctlr->name != nil)
748 free(ctlr->name);
749 free(ctlr);
750
751 return nil;
752 }
753
754 static Uart*
755 axpalloc(int ctlrno, Pcidev* pcidev)
756 {
757 Cc *cc;
758 uchar *p;
759 Ctlr *ctlr;
760 void *addr;
761 char name[64];
762 u32int bar, r;
763 int i, n, timeo;
764
765 ctlr = malloc(sizeof(Ctlr));
766 seprint(name, name+sizeof(name), "uartaxp%d", ctlrno);
767 kstrdup(&ctlr->name, name);
768 ctlr->pcidev = pcidev;
769 ctlr->ctlrno = ctlrno;
770
771 /*
772 * Access to runtime registers.
773 */
774 bar = pcidev->mem[0].bar;
775 if((addr = vmap(bar & ~0x0F, pcidev->mem[0].size)) == 0){
776 print("%s: can't map registers at %#ux\n", ctlr->name, bar);
777 return axpdealloc(ctlr);
778 }
779 ctlr->reg = addr;
780 print("%s: port 0x%ux irq %d ", ctlr->name, bar, pcidev->intl);
781
782 /*
783 * Local address space 0.
784 */
785 bar = pcidev->mem[2].bar;
786 if((addr = vmap(bar & ~0x0F, pcidev->mem[2].size)) == 0){
787 print("%s: can't map memory at %#ux\n", ctlr->name, bar);
788 return axpdealloc(ctlr);
789 }
790 ctlr->mem = addr;
791 ctlr->gcb = (Gcb*)(ctlr->mem+0x10000);
792 print("mem 0x%ux size %d: ", bar, pcidev->mem[2].size);
793
794 /*
795 * Toggle the software reset and wait for
796 * the adapter local init status to indicate done.
797 *
798 * The two 'delay(100)'s below are important,
799 * without them the board seems to become confused
800 * (perhaps it needs some 'quiet time' because the
801 * timeout loops are not sufficient in themselves).
802 */
803 r = csr32r(ctlr, Mcc);
804 csr32w(ctlr, Mcc, r|Asr);
805 microdelay(1);
806 csr32w(ctlr, Mcc, r&~Asr);
807 delay(100);
808
809 for(timeo = 0; timeo < 100000; timeo++){
810 if(csr32r(ctlr, Mcc) & Lis)
811 break;
812 microdelay(1);
813 }
814 if(!(csr32r(ctlr, Mcc) & Lis)){
815 print("%s: couldn't reset\n", ctlr->name);
816 return axpdealloc(ctlr);
817 }
818 print("downloading...");
819 /*
820 * Copy the control programme to the card memory.
821 * The card's i960 control structures live at 0xD000.
822 */
823 if(sizeof(uartaxpcp) > 0xD000){
824 print("%s: control programme too big\n", ctlr->name);
825 return axpdealloc(ctlr);
826 }
827 /* TODO: is this right for more than 1 card? devastar does the same */
828 csr32w(ctlr, Remap, 0xA0000001);
829 for(i = 0; i < sizeof(uartaxpcp); i++)
830 ctlr->mem[i] = uartaxpcp[i];
831 /*
832 * Execute downloaded code and wait for it
833 * to signal ready.
834 */
835 csr32w(ctlr, Mb0, Edcc);
836 delay(100);
837 /* the manual says to wait for Cpr for 1 second */
838 for(timeo = 0; timeo < 10000; timeo++){
839 if(csr32r(ctlr, Mb0) & Cpr)
840 break;
841 microdelay(100);
842 }
843 if(!(csr32r(ctlr, Mb0) & Cpr)){
844 print("control programme not ready; Mb0 %#ux\n",
845 csr32r(ctlr, Mb0));
846 print("%s: distribution panel not connected or card not fully seated?\n",
847 ctlr->name);
848
849 return axpdealloc(ctlr);
850 }
851 print("\n");
852
853 n = ctlr->gcb->ccbn;
854 if(ctlr->gcb->bt != 0x12 || n > 16){
855 print("%s: wrong board type %#ux, %d channels\n",
856 ctlr->name, ctlr->gcb->bt, ctlr->gcb->ccbn);
857 return axpdealloc(ctlr);
858 }
859
860 p = ((uchar*)ctlr->gcb) + ctlr->gcb->ccboff;
861 for(i = 0; i < n; i++){
862 cc = &ctlr->cc[i];
863 cc->ccb = (Ccb*)p;
864 p += ctlr->gcb->ccbsz;
865 cc->uartno = i;
866 cc->ctlr = ctlr;
867
868 cc->regs = cc; /* actually Uart->regs */
869 seprint(name, name+sizeof(name), "uartaxp%d%2.2d", ctlrno, i);
870 kstrdup(&cc->name, name);
871 cc->freq = 0;
872 cc->bits = 8;
873 cc->stop = 1;
874 cc->parity = 'n';
875 cc->baud = 9600;
876 cc->phys = &axpphysuart;
877 cc->console = 0;
878 cc->special = 0;
879
880 cc->next = &ctlr->cc[i+1];
881 }
882 ctlr->cc[n-1].next = nil;
883
884 ctlr->next = nil;
885 if(axpctlrhead != nil)
886 axpctlrtail->next = ctlr;
887 else
888 axpctlrhead = ctlr;
889 axpctlrtail = ctlr;
890
891 return ctlr->cc;
892 }
893
894 static Uart*
895 axppnp(void)
896 {
897 Pcidev *p;
898 int ctlrno;
899 Uart *head, *tail, *uart;
900
901 /*
902 * Loop through all PCI devices looking for simple serial
903 * controllers (ccrb == 0x07) and configure the ones which
904 * are familiar.
905 */
906 head = tail = nil;
907 ctlrno = 0;
908 for(p = pcimatch(nil, 0, 0); p != nil; p = pcimatch(p, 0, 0)){
909 if(p->ccrb != 0x07)
910 continue;
911
912 switch((p->did<<16)|p->vid){
913 default:
914 continue;
915 case (0x6001<<16)|0x114F: /* AvanstarXp */
916 if((uart = axpalloc(ctlrno, p)) == nil)
917 continue;
918 break;
919 }
920
921 if(head != nil)
922 tail->next = uart;
923 else
924 head = uart;
925 for(tail = uart; tail->next != nil; tail = tail->next)
926 ;
927 ctlrno++;
928 }
929
930 return head;
931 }
932
933 PhysUart axpphysuart = {
934 .name = "AvanstarXp",
935 .pnp = axppnp,
936 .enable = axpenable,
937 .disable = axpdisable,
938 .kick = axpkick,
939 .dobreak = axpbreak,
940 .baud = axpbaud,
941 .bits = axpbits,
942 .stop = axpstop,
943 .parity = axpparity,
944 .modemctl = axpmodemctl,
945 .rts = axprts,
946 .dtr = axpdtr,
947 .status = axpstatus,
948 .fifo = axpfifo,
949 .getc = nil,
950 .putc = nil,
951 };
Cache object: fb892c42633101eaf67f5bb161d60253
|