Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "../port/error.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(uart == nil || ctlr == nil){
                iofree(io);
                free(uart);
                free(ctlr);
                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,
};