xref: /plan9/sys/src/9/pc/uartisa.c (revision aa72973a2891ccbd3fb042462446761159389e19)
123655ee0SDavid du Colombier #include "u.h"
223655ee0SDavid du Colombier #include "../port/lib.h"
323655ee0SDavid du Colombier #include "mem.h"
423655ee0SDavid du Colombier #include "dat.h"
523655ee0SDavid du Colombier #include "fns.h"
623655ee0SDavid du Colombier #include "io.h"
723655ee0SDavid du Colombier #include "../port/error.h"
823655ee0SDavid du Colombier 
923655ee0SDavid du Colombier extern PhysUart i8250physuart;
1023655ee0SDavid du Colombier extern PhysUart isaphysuart;
1123655ee0SDavid du Colombier extern void* i8250alloc(int, int, int);
1223655ee0SDavid du Colombier 
1323655ee0SDavid du Colombier static Uart*
uartisa(int ctlrno,ISAConf * isa)1423655ee0SDavid du Colombier uartisa(int ctlrno, ISAConf* isa)
1523655ee0SDavid du Colombier {
1623655ee0SDavid du Colombier 	int io;
1723655ee0SDavid du Colombier 	void *ctlr;
1823655ee0SDavid du Colombier 	Uart *uart;
1923655ee0SDavid du Colombier 	char buf[64];
2023655ee0SDavid du Colombier 
2123655ee0SDavid du Colombier 	io = isa->port;
2223655ee0SDavid du Colombier 	snprint(buf, sizeof(buf), "%s%d", isaphysuart.name, ctlrno);
2323655ee0SDavid du Colombier 	if(ioalloc(io, 8, 0, buf) < 0){
2423655ee0SDavid du Colombier 		print("uartisa: I/O 0x%uX in use\n", io);
2523655ee0SDavid du Colombier 		return nil;
2623655ee0SDavid du Colombier 	}
2723655ee0SDavid du Colombier 
2823655ee0SDavid du Colombier 	uart = malloc(sizeof(Uart));
2923655ee0SDavid du Colombier 	ctlr = i8250alloc(io, isa->irq, BUSUNKNOWN);
30*aa72973aSDavid du Colombier 	if(uart == nil || ctlr == nil){
3123655ee0SDavid du Colombier 		iofree(io);
3223655ee0SDavid du Colombier 		free(uart);
33*aa72973aSDavid du Colombier 		free(ctlr);
3423655ee0SDavid du Colombier 		return nil;
3523655ee0SDavid du Colombier 	}
3623655ee0SDavid du Colombier 
3723655ee0SDavid du Colombier 	uart->regs = ctlr;
389027b8f7SDavid du Colombier 	snprint(buf, sizeof(buf), "COM%d", ctlrno+1);
3923655ee0SDavid du Colombier 	kstrdup(&uart->name, buf);
4023655ee0SDavid du Colombier 	uart->freq = isa->freq;
4123655ee0SDavid du Colombier 	uart->phys = &i8250physuart;
4223655ee0SDavid du Colombier 
4323655ee0SDavid du Colombier 	return uart;
4423655ee0SDavid du Colombier }
4523655ee0SDavid du Colombier 
4623655ee0SDavid du Colombier static Uart*
uartisapnp(void)4723655ee0SDavid du Colombier uartisapnp(void)
4823655ee0SDavid du Colombier {
4923655ee0SDavid du Colombier 	int ctlrno;
5023655ee0SDavid du Colombier 	ISAConf isa;
5123655ee0SDavid du Colombier 	Uart *head, *tail, *uart;
5223655ee0SDavid du Colombier 
5323655ee0SDavid du Colombier 	/*
5423655ee0SDavid du Colombier 	 * Look for up to 4 discrete UARTs on the ISA bus.
5523655ee0SDavid du Colombier 	 * All suitable devices are configured to simply point
5623655ee0SDavid du Colombier 	 * to the generic i8250 driver.
5723655ee0SDavid du Colombier 	 */
5823655ee0SDavid du Colombier 	head = tail = nil;
5923655ee0SDavid du Colombier 	for(ctlrno = 2; ctlrno < 6; ctlrno++){
6023655ee0SDavid du Colombier 		memset(&isa, 0, sizeof(isa));
6123655ee0SDavid du Colombier 		if(!isaconfig("uart", ctlrno, &isa))
6223655ee0SDavid du Colombier 			continue;
6323655ee0SDavid du Colombier 		if(strcmp(isa.type, "isa") != 0)
6423655ee0SDavid du Colombier 			continue;
6523655ee0SDavid du Colombier 		if(isa.port == 0 || isa.irq == 0)
6623655ee0SDavid du Colombier 			continue;
6723655ee0SDavid du Colombier 		if(isa.freq == 0)
6823655ee0SDavid du Colombier 			isa.freq = 1843200;
6923655ee0SDavid du Colombier 		uart = uartisa(ctlrno, &isa);
7023655ee0SDavid du Colombier 		if(uart == nil)
7123655ee0SDavid du Colombier 			continue;
7223655ee0SDavid du Colombier 		if(head != nil)
7323655ee0SDavid du Colombier 			tail->next = uart;
7423655ee0SDavid du Colombier 		else
7523655ee0SDavid du Colombier 			head = uart;
7623655ee0SDavid du Colombier 		tail = uart;
7723655ee0SDavid du Colombier 	}
7823655ee0SDavid du Colombier 
7923655ee0SDavid du Colombier 	return head;
8023655ee0SDavid du Colombier }
8123655ee0SDavid du Colombier 
8223655ee0SDavid du Colombier PhysUart isaphysuart = {
8323655ee0SDavid du Colombier 	.name		= "UartISA",
8423655ee0SDavid du Colombier 	.pnp		= uartisapnp,
8523655ee0SDavid du Colombier 	.enable		= nil,
8623655ee0SDavid du Colombier 	.disable	= nil,
8723655ee0SDavid du Colombier 	.kick		= nil,
8823655ee0SDavid du Colombier 	.dobreak	= nil,
8923655ee0SDavid du Colombier 	.baud		= nil,
9023655ee0SDavid du Colombier 	.bits		= nil,
9123655ee0SDavid du Colombier 	.stop		= nil,
9223655ee0SDavid du Colombier 	.parity		= nil,
9323655ee0SDavid du Colombier 	.modemctl	= nil,
9423655ee0SDavid du Colombier 	.rts		= nil,
9523655ee0SDavid du Colombier 	.dtr		= nil,
9623655ee0SDavid du Colombier 	.status		= nil,
9723655ee0SDavid du Colombier 	.fifo		= nil,
9823655ee0SDavid du Colombier };
99