1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "../port/error.h"
8
9 extern PhysUart i8250physuart;
10 extern PhysUart isaphysuart;
11 extern void* i8250alloc(int, int, int);
12
13 static Uart*
uartisa(int ctlrno,ISAConf * isa)14 uartisa(int ctlrno, ISAConf* isa)
15 {
16 int io;
17 void *ctlr;
18 Uart *uart;
19 char buf[64];
20
21 io = isa->port;
22 snprint(buf, sizeof(buf), "%s%d", isaphysuart.name, ctlrno);
23 if(ioalloc(io, 8, 0, buf) < 0){
24 print("uartisa: I/O 0x%uX in use\n", io);
25 return nil;
26 }
27
28 uart = malloc(sizeof(Uart));
29 ctlr = i8250alloc(io, isa->irq, BUSUNKNOWN);
30 if(uart == nil || ctlr == nil){
31 iofree(io);
32 free(uart);
33 free(ctlr);
34 return nil;
35 }
36
37 uart->regs = ctlr;
38 snprint(buf, sizeof(buf), "COM%d", ctlrno+1);
39 kstrdup(&uart->name, buf);
40 uart->freq = isa->freq;
41 uart->phys = &i8250physuart;
42
43 return uart;
44 }
45
46 static Uart*
uartisapnp(void)47 uartisapnp(void)
48 {
49 int ctlrno;
50 ISAConf isa;
51 Uart *head, *tail, *uart;
52
53 /*
54 * Look for up to 4 discrete UARTs on the ISA bus.
55 * All suitable devices are configured to simply point
56 * to the generic i8250 driver.
57 */
58 head = tail = nil;
59 for(ctlrno = 2; ctlrno < 6; ctlrno++){
60 memset(&isa, 0, sizeof(isa));
61 if(!isaconfig("uart", ctlrno, &isa))
62 continue;
63 if(strcmp(isa.type, "isa") != 0)
64 continue;
65 if(isa.port == 0 || isa.irq == 0)
66 continue;
67 if(isa.freq == 0)
68 isa.freq = 1843200;
69 uart = uartisa(ctlrno, &isa);
70 if(uart == nil)
71 continue;
72 if(head != nil)
73 tail->next = uart;
74 else
75 head = uart;
76 tail = uart;
77 }
78
79 return head;
80 }
81
82 PhysUart isaphysuart = {
83 .name = "UartISA",
84 .pnp = uartisapnp,
85 .enable = nil,
86 .disable = nil,
87 .kick = nil,
88 .dobreak = nil,
89 .baud = nil,
90 .bits = nil,
91 .stop = nil,
92 .parity = nil,
93 .modemctl = nil,
94 .rts = nil,
95 .dtr = nil,
96 .status = nil,
97 .fifo = nil,
98 };
99