FreeBSD/Linux Kernel Cross Reference
sys/pc/uartisa.c
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*
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(ctlr == nil){
31 iofree(io);
32 free(uart);
33 return nil;
34 }
35
36 uart->regs = ctlr;
37 snprint(buf, sizeof(buf), "COM%d", ctlrno+1);
38 kstrdup(&uart->name, buf);
39 uart->freq = isa->freq;
40 uart->phys = &i8250physuart;
41
42 return uart;
43 }
44
45 static Uart*
46 uartisapnp(void)
47 {
48 int ctlrno;
49 ISAConf isa;
50 Uart *head, *tail, *uart;
51
52 /*
53 * Look for up to 4 discrete UARTs on the ISA bus.
54 * All suitable devices are configured to simply point
55 * to the generic i8250 driver.
56 */
57 head = tail = nil;
58 for(ctlrno = 2; ctlrno < 6; ctlrno++){
59 memset(&isa, 0, sizeof(isa));
60 if(!isaconfig("uart", ctlrno, &isa))
61 continue;
62 if(strcmp(isa.type, "isa") != 0)
63 continue;
64 if(isa.port == 0 || isa.irq == 0)
65 continue;
66 if(isa.freq == 0)
67 isa.freq = 1843200;
68 uart = uartisa(ctlrno, &isa);
69 if(uart == nil)
70 continue;
71 if(head != nil)
72 tail->next = uart;
73 else
74 head = uart;
75 tail = uart;
76 }
77
78 return head;
79 }
80
81 PhysUart isaphysuart = {
82 .name = "UartISA",
83 .pnp = uartisapnp,
84 .enable = nil,
85 .disable = nil,
86 .kick = nil,
87 .dobreak = nil,
88 .baud = nil,
89 .bits = nil,
90 .stop = nil,
91 .parity = nil,
92 .modemctl = nil,
93 .rts = nil,
94 .dtr = nil,
95 .status = nil,
96 .fifo = nil,
97 };
Cache object: 1907c28526e9076041928865eb419de6
|