summaryrefslogtreecommitdiff
path: root/os/pc/uartisa.c
diff options
context:
space:
mode:
Diffstat (limited to 'os/pc/uartisa.c')
-rw-r--r--os/pc/uartisa.c98
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,
+};