diff options
Diffstat (limited to 'os/pc/uartisa.c')
| -rw-r--r-- | os/pc/uartisa.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/os/pc/uartisa.c b/os/pc/uartisa.c new file mode 100644 index 00000000..de4a8dcc --- /dev/null +++ b/os/pc/uartisa.c @@ -0,0 +1,98 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/error.h" +#include "../port/uart.h" + +extern PhysUart i8250physuart; +extern PhysUart isaphysuart; +extern void* i8250alloc(int, int, int); + +static Uart* +uartisa(int ctlrno, ISAConf* isa) +{ + int io; + void *ctlr; + Uart *uart; + char buf[64]; + + io = isa->port; + snprint(buf, sizeof(buf), "%s%d", isaphysuart.name, ctlrno); + if(ioalloc(io, 8, 0, buf) < 0){ + print("uartisa: I/O 0x%uX in use\n", io); + return nil; + } + + uart = malloc(sizeof(Uart)); + ctlr = i8250alloc(io, isa->irq, BUSUNKNOWN); + if(ctlr == nil){ + iofree(io); + free(uart); + return nil; + } + + uart->regs = ctlr; + snprint(buf, sizeof(buf), "COM%d", ctlrno+1); + kstrdup(&uart->name, buf); + uart->freq = isa->freq; + uart->phys = &i8250physuart; + + return uart; +} + +static Uart* +uartisapnp(void) +{ + int ctlrno; + ISAConf isa; + Uart *head, *tail, *uart; + + /* + * Look for up to 4 discrete UARTs on the ISA bus. + * All suitable devices are configured to simply point + * to the generic i8250 driver. + */ + head = tail = nil; + for(ctlrno = 2; ctlrno < 6; ctlrno++){ + memset(&isa, 0, sizeof(isa)); + if(!isaconfig("uart", ctlrno, &isa)) + continue; + if(strcmp(isa.type, "isa") != 0) + continue; + if(isa.port == 0 || isa.irq == 0) + continue; + if(isa.freq == 0) + isa.freq = 1843200; + uart = uartisa(ctlrno, &isa); + if(uart == nil) + continue; + if(head != nil) + tail->next = uart; + else + head = uart; + tail = uart; + } + + return head; +} + +PhysUart isaphysuart = { + .name = "UartISA", + .pnp = uartisapnp, + .enable = nil, + .disable = nil, + .kick = nil, + .dobreak = nil, + .baud = nil, + .bits = nil, + .stop = nil, + .parity = nil, + .modemctl = nil, + .rts = nil, + .dtr = nil, + .status = nil, + .fifo = nil, +}; |
