From 85286bff2f3760a27fcb53fe36432fa35ad0b07b Mon Sep 17 00:00:00 2001 From: cgd Date: Sun, 10 Mar 1996 09:01:20 +0000 Subject: [PATCH] convert these to use new interfaces. This involved substantial reworking of the multi-port drivers, as they need to frob bits in the io-port spaces of their children. As a result, the commulti->com attachment interface is substantially more complex. (This may be fixable in the future by making some of the code common, but as long as io-port allocation checking is planned, it's necessary.) --- sys/dev/ic/com.c | 407 ++++++++++++++++++++++++++++--------------- sys/dev/ic/comvar.h | 14 +- sys/dev/isa/ast.c | 123 ++++++++----- sys/dev/isa/boca.c | 121 ++++++++----- sys/dev/isa/com.c | 407 ++++++++++++++++++++++++++++--------------- sys/dev/isa/comvar.h | 14 +- sys/dev/isa/rtfps.c | 125 ++++++++----- 7 files changed, 797 insertions(+), 414 deletions(-) diff --git a/sys/dev/ic/com.c b/sys/dev/ic/com.c index cfc971e4b517..f0361fae4541 100644 --- a/sys/dev/ic/com.c +++ b/sys/dev/ic/com.c @@ -1,4 +1,4 @@ -/* $NetBSD: com.c,v 1.74 1996/03/09 01:02:08 cgd Exp $ */ +/* $NetBSD: com.c,v 1.75 1996/03/10 09:01:24 cgd Exp $ */ /*- * Copyright (c) 1993, 1994, 1995, 1996 @@ -57,7 +57,7 @@ #include #include -#include +#include #include #include @@ -86,6 +86,11 @@ struct com_softc { #ifdef COM_HAYESP int sc_hayespbase; #endif + + bus_chipset_tag_t sc_bc; + bus_io_handle_t sc_ioh; + bus_io_handle_t sc_hayespioh; + u_char sc_hwflags; #define COM_HW_NOIEN 0x01 #define COM_HW_FIFO 0x02 @@ -104,6 +109,9 @@ struct com_softc { }; int comprobe __P((struct device *, void *, void *)); +#ifdef COM_HAYESP +int comprobeHAYESP __P((bus_io_handle_t hayespioh, struct com_softc *sc)); +#endif void comattach __P((struct device *, struct device *, void *)); int comopen __P((dev_t, int, int, struct proc *)); int comclose __P((dev_t, int, int, struct proc *)); @@ -113,18 +121,23 @@ void compoll __P((void *)); int comparam __P((struct tty *, struct termios *)); void comstart __P((struct tty *)); +int cominit __P((bus_chipset_tag_t, bus_io_handle_t, int)); + struct cfdriver comcd = { NULL, "com", comprobe, comattach, DV_TTY, sizeof(struct com_softc) }; #ifdef COMCONSOLE -int comdefaultrate = CONSPEED; -int comconsole = COMCONSOLE; +int comdefaultrate = CONSPEED; /* XXX why set default? */ #else int comdefaultrate = TTYDEF_SPEED; -int comconsole = -1; #endif +int comconsaddr; int comconsinit; +int comconsattached; +bus_chipset_tag_t comconsbc; +bus_io_handle_t comconsioh; + int commajor; int comsopen = 0; int comevents = 0; @@ -169,14 +182,16 @@ comspeed(speed) } int -comprobe1(iobase) +comprobe1(bc, ioh, iobase) + bus_chipset_tag_t bc; + bus_io_handle_t ioh; int iobase; { /* force access to id reg */ - outb(iobase + com_lcr, 0); - outb(iobase + com_iir, 0); - if (inb(iobase + com_iir) & 0x38) + bus_io_write_1(bc, ioh, com_lcr, 0); + bus_io_write_1(bc, ioh, com_iir, 0); + if (bus_io_read_1(bc, ioh, com_iir) & 0x38) return 0; return 1; @@ -184,12 +199,13 @@ comprobe1(iobase) #ifdef COM_HAYESP int -comprobeHAYESP(iobase, sc) - int iobase; +comprobeHAYESP(hayespioh, sc) + bus_io_handle_t hayespioh; struct com_softc *sc; { char val, dips; int combaselist[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; + bus_chipset_tag_t bc = sc->sc_bc; /* * Hayes ESP cards have two iobases. One is for compatibility with @@ -199,7 +215,7 @@ comprobeHAYESP(iobase, sc) */ /* Test for ESP signature */ - if ((inb(iobase) & 0xf3) == 0) + if ((bus_io_read_1(bc, hayespioh, 0) & 0xf3) == 0) return 0; /* @@ -207,8 +223,8 @@ comprobeHAYESP(iobase, sc) */ /* Get the dip-switch configurations */ - outb(iobase + HAYESP_CMD1, HAYESP_GETDIPS); - dips = inb(iobase + HAYESP_STATUS1); + bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_GETDIPS); + dips = bus_io_read_1(bc, hayespioh, HAYESP_STATUS1); /* Determine which com port this ESP card services: bits 0,1 of */ /* dips is the port # (0-3); combaselist[val] is the com_iobase */ @@ -219,9 +235,9 @@ comprobeHAYESP(iobase, sc) /* Check ESP Self Test bits. */ /* Check for ESP version 2.0: bits 4,5,6 == 010 */ - outb(iobase + HAYESP_CMD1, HAYESP_GETTEST); - val = inb(iobase + HAYESP_STATUS1); /* Clear reg 1 */ - val = inb(iobase + HAYESP_STATUS2); + bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_GETTEST); + val = bus_io_read_1(bc, hayespioh, HAYESP_STATUS1); /* Clear reg 1 */ + val = bus_io_read_1(bc, hayespioh, HAYESP_STATUS2); if ((val & 0x70) < 0x20) { printf("-old (%o)", val & 0x70); /* we do not support the necessary features */ @@ -251,15 +267,50 @@ comprobe(parent, match, aux) struct device *parent; void *match, *aux; { - struct isa_attach_args *ia = aux; - int iobase = ia->ia_iobase; + struct cfdata *cf = match; + bus_chipset_tag_t bc; + bus_io_handle_t ioh; + int iobase, needioh; + int rv = 1; - if (!comprobe1(iobase)) - return 0; + if (!strcmp(parent->dv_cfdata->cf_driver->cd_name, "isa")) { + struct isa_attach_args *ia = aux; - ia->ia_iosize = COM_NPORTS; - ia->ia_msize = 0; - return 1; + bc = ia->ia_bc; + iobase = ia->ia_iobase; + needioh = 1; + } else { + struct commulti_attach_args *ca = aux; + + if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ca->ca_slave) + return (0); + + bc = ca->ca_bc; + iobase = ca->ca_iobase; + ioh = ca->ca_ioh; + needioh = 0; + } + + /* if it's in use as console, it's there. */ + if (iobase == comconsaddr && !comconsattached) + goto out; + + if (needioh && bus_io_map(bc, iobase, COM_NPORTS, &ioh)) { + rv = 0; + goto out; + } + rv = comprobe1(bc, ioh, iobase); + if (needioh) + bus_io_unmap(bc, ioh, COM_NPORTS); + +out: + if (rv && !strcmp(parent->dv_cfdata->cf_driver->cd_name, "isa")) { + struct isa_attach_args *ia = aux; + + ia->ia_iosize = COM_NPORTS; + ia->ia_msize = 0; + } + return (rv); } void @@ -268,64 +319,114 @@ comattach(parent, self, aux) void *aux; { struct com_softc *sc = (void *)self; - struct isa_attach_args *ia = aux; struct cfdata *cf = sc->sc_dev.dv_cfdata; - int iobase = ia->ia_iobase; + int iobase, irq; + bus_chipset_tag_t bc; + bus_io_handle_t ioh; struct tty *tp; #ifdef COM_HAYESP int hayesp_ports[] = { 0x140, 0x180, 0x280, 0x300, 0 }; int *hayespp; #endif - sc->sc_iobase = iobase; - sc->sc_hwflags = ISSET(cf->cf_flags, COM_HW_NOIEN); + sc->sc_hwflags = 0; sc->sc_swflags = 0; + if (!strcmp(parent->dv_cfdata->cf_driver->cd_name, "isa")) { + struct isa_attach_args *ia = aux; - if (sc->sc_dev.dv_unit == comconsole) - delay(1000); + /* + * We're living on an isa. + */ + iobase = ia->ia_iobase; + bc = ia->ia_bc; + if (iobase != comconsaddr) { + if (bus_io_map(bc, iobase, COM_NPORTS, &ioh)) + panic("comattach: io mapping failed"); + } else + ioh = comconsioh; + irq = ia->ia_irq; + } else { + struct commulti_attach_args *ca = aux; + + /* + * We're living on a commulti. + */ + iobase = ca->ca_iobase; + bc = ca->ca_bc; + ioh = ca->ca_ioh; + irq = IRQUNK; + + if (ca->ca_noien) + sc->sc_hwflags |= COM_HW_NOIEN; + } + + sc->sc_bc = bc; + sc->sc_ioh = ioh; + sc->sc_iobase = iobase; + + if (iobase == comconsaddr) { + comconsattached = 1; + + /* + * Need to reset baud rate, etc. of next print so reset + * comconsinit. Also make sure console is always "hardwired". + */ + delay(1000); /* wait for output to finish */ + comconsinit = 0; + SET(sc->sc_hwflags, COM_HW_CONSOLE); + SET(sc->sc_swflags, COM_SW_SOFTCAR); + } #ifdef COM_HAYESP /* Look for a Hayes ESP board. */ - for (hayespp = hayesp_ports; *hayespp != 0; hayespp++) - if (comprobeHAYESP(*hayespp, sc)) { + for (hayespp = hayesp_ports; *hayespp != 0; hayespp++) { + bus_io_handle_t hayespioh; + +#define HAYESP_NPORTS 8 /* XXX XXX XXX ??? ??? ??? */ + if (bus_io_map(bc, *hayespp, HAYESP_NPORTS, &hayespioh)) + continue; + if (comprobeHAYESP(hayespioh, sc)) { sc->sc_hayespbase = *hayespp; + sc->sc_hayespioh = hayespioh; break; } + bus_io_unmap(bc, hayespioh, HAYESP_NPORTS); + } /* No ESP; look for other things. */ if (*hayespp == 0) { #endif /* look for a NS 16550AF UART with FIFOs */ - outb(iobase + com_fifo, + bus_io_write_1(bc, ioh, com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14); delay(100); - if (ISSET(inb(iobase + com_iir), IIR_FIFO_MASK) == IIR_FIFO_MASK) - if (ISSET(inb(iobase + com_fifo), FIFO_TRIGGER_14) == FIFO_TRIGGER_14) { + if (ISSET(bus_io_read_1(bc, ioh, com_iir), IIR_FIFO_MASK) == IIR_FIFO_MASK) + if (ISSET(bus_io_read_1(bc, ioh, com_fifo), FIFO_TRIGGER_14) == FIFO_TRIGGER_14) { SET(sc->sc_hwflags, COM_HW_FIFO); printf(": ns16550a, working fifo\n"); } else printf(": ns16550, broken fifo\n"); else printf(": ns8250 or ns16450, no fifo\n"); - outb(iobase + com_fifo, 0); + bus_io_write_1(bc, ioh, com_fifo, 0); #ifdef COM_HAYESP } #endif /* disable interrupts */ - outb(iobase + com_ier, 0); - outb(iobase + com_mcr, 0); + bus_io_write_1(bc, ioh, com_ier, 0); + bus_io_write_1(bc, ioh, com_mcr, 0); - if (ia->ia_irq != IRQUNK) - sc->sc_ih = isa_intr_establish(ia->ia_irq, IST_EDGE, IPL_TTY, + if (irq != IRQUNK) + sc->sc_ih = isa_intr_establish(irq, IST_EDGE, IPL_TTY, comintr, sc); #ifdef KGDB if (kgdb_dev == makedev(commajor, unit)) { - if (comconsole == unit) + if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) kgdb_dev = -1; /* can't debug over console port */ else { - (void) cominit(unit, kgdb_rate); + (void) cominit(bc, ioh, kgdb_rate); if (kgdb_debug_init) { /* * Print prefix of device name, @@ -340,15 +441,9 @@ comattach(parent, self, aux) } #endif - if (sc->sc_dev.dv_unit == comconsole) { - /* - * Need to reset baud rate, etc. of next print so reset - * comconsinit. Also make sure console is always "hardwired". - */ - comconsinit = 0; - SET(sc->sc_hwflags, COM_HW_CONSOLE); - SET(sc->sc_swflags, COM_SW_SOFTCAR); - } + /* XXX maybe move up some? */ + if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) + printf("%s: console\n", sc->sc_dev.dv_xname); } int @@ -359,7 +454,8 @@ comopen(dev, flag, mode, p) { int unit = COMUNIT(dev); struct com_softc *sc; - int iobase; + bus_chipset_tag_t bc; + bus_io_handle_t ioh; struct tty *tp; int s; int error = 0; @@ -405,56 +501,57 @@ comopen(dev, flag, mode, p) sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER; sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE; - iobase = sc->sc_iobase; + bc = sc->sc_bc; + ioh = sc->sc_ioh; #ifdef COM_HAYESP /* Setup the ESP board */ if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) { - int hayespbase = sc->sc_hayespbase; + bus_io_handle_t hayespioh = sc->sc_hayespioh; - outb(iobase + com_fifo, + bus_io_write_1(bc, ioh, com_fifo, FIFO_DMA_MODE|FIFO_ENABLE| FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_8); /* Set 16550 compatibility mode */ - outb(hayespbase + HAYESP_CMD1, HAYESP_SETMODE); - outb(hayespbase + HAYESP_CMD2, + bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_SETMODE); + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_MODE_FIFO|HAYESP_MODE_RTS| HAYESP_MODE_SCALE); /* Set RTS/CTS flow control */ - outb(hayespbase + HAYESP_CMD1, HAYESP_SETFLOWTYPE); - outb(hayespbase + HAYESP_CMD2, HAYESP_FLOW_RTS); - outb(hayespbase + HAYESP_CMD2, HAYESP_FLOW_CTS); + bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_SETFLOWTYPE); + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_FLOW_RTS); + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_FLOW_CTS); /* Set flow control levels */ - outb(hayespbase + HAYESP_CMD1, HAYESP_SETRXFLOW); - outb(hayespbase + HAYESP_CMD2, + bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_SETRXFLOW); + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_HIBYTE(HAYESP_RXHIWMARK)); - outb(hayespbase + HAYESP_CMD2, + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_LOBYTE(HAYESP_RXHIWMARK)); - outb(hayespbase + HAYESP_CMD2, + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_HIBYTE(HAYESP_RXLOWMARK)); - outb(hayespbase + HAYESP_CMD2, + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_LOBYTE(HAYESP_RXLOWMARK)); } else #endif if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) /* Set the FIFO threshold based on the receive speed. */ - outb(iobase + com_fifo, + bus_io_write_1(bc, ioh, com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | (tp->t_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8)); /* flush any pending I/O */ - while (ISSET(inb(iobase + com_lsr), LSR_RXRDY)) - (void) inb(iobase + com_data); + while (ISSET(bus_io_read_1(bc, ioh, com_lsr), LSR_RXRDY)) + (void) bus_io_read_1(bc, ioh, com_data); /* you turn me on, baby */ sc->sc_mcr = MCR_DTR | MCR_RTS; if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN)) SET(sc->sc_mcr, MCR_IENABLE); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC; - outb(iobase + com_ier, sc->sc_ier); + bus_io_write_1(bc, ioh, com_ier, sc->sc_ier); - sc->sc_msr = inb(iobase + com_msr); + sc->sc_msr = bus_io_read_1(bc, ioh, com_msr); if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) || ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF)) SET(tp->t_state, TS_CARR_ON); @@ -493,7 +590,8 @@ comclose(dev, flag, mode, p) int unit = COMUNIT(dev); struct com_softc *sc = comcd.cd_devs[unit]; struct tty *tp = sc->sc_tty; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; + bus_io_handle_t ioh = sc->sc_ioh; int s; /* XXX This is for cons.c. */ @@ -503,12 +601,12 @@ comclose(dev, flag, mode, p) (*linesw[tp->t_line].l_close)(tp, flag); s = spltty(); CLR(sc->sc_lcr, LCR_SBREAK); - outb(iobase + com_lcr, sc->sc_lcr); - outb(iobase + com_ier, 0); + bus_io_write_1(bc, ioh, com_lcr, sc->sc_lcr); + bus_io_write_1(bc, ioh, com_ier, 0); if (ISSET(tp->t_cflag, HUPCL) && !ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) { /* XXX perhaps only clear DTR */ - outb(iobase + com_mcr, 0); + bus_io_write_1(bc, ioh, com_mcr, 0); } CLR(tp->t_state, TS_BUSY | TS_FLUSH); if (--comsopen == 0) @@ -516,7 +614,7 @@ comclose(dev, flag, mode, p) splx(s); ttyclose(tp); #ifdef notyet /* XXXX */ - if (unit != comconsole) { + if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { ttyfree(tp); sc->sc_tty = 0; } @@ -582,7 +680,8 @@ comioctl(dev, cmd, data, flag, p) int unit = COMUNIT(dev); struct com_softc *sc = comcd.cd_devs[unit]; struct tty *tp = sc->sc_tty; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; + bus_io_handle_t ioh = sc->sc_ioh; int error; error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); @@ -595,29 +694,29 @@ comioctl(dev, cmd, data, flag, p) switch (cmd) { case TIOCSBRK: SET(sc->sc_lcr, LCR_SBREAK); - outb(iobase + com_lcr, sc->sc_lcr); + bus_io_write_1(bc, ioh, com_lcr, sc->sc_lcr); break; case TIOCCBRK: CLR(sc->sc_lcr, LCR_SBREAK); - outb(iobase + com_lcr, sc->sc_lcr); + bus_io_write_1(bc, ioh, com_lcr, sc->sc_lcr); break; case TIOCSDTR: SET(sc->sc_mcr, sc->sc_dtr); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); break; case TIOCCDTR: CLR(sc->sc_mcr, sc->sc_dtr); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); break; case TIOCMSET: CLR(sc->sc_mcr, MCR_DTR | MCR_RTS); case TIOCMBIS: SET(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data)); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); break; case TIOCMBIC: CLR(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data)); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); break; case TIOCMGET: { u_char m; @@ -637,7 +736,7 @@ comioctl(dev, cmd, data, flag, p) SET(bits, TIOCM_DSR); if (ISSET(m, MSR_RI | MSR_TERI)) SET(bits, TIOCM_RI); - if (inb(iobase + com_ier)) + if (bus_io_read_1(bc, ioh, com_ier)) SET(bits, TIOCM_LE); *(int *)data = bits; break; @@ -692,7 +791,8 @@ comparam(tp, t) struct termios *t; { struct com_softc *sc = comcd.cd_devs[COMUNIT(tp->t_dev)]; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; + bus_io_handle_t ioh = sc->sc_ioh; int ospeed = comspeed(t->c_ospeed); u_char lcr; tcflag_t oldcflag; @@ -732,7 +832,7 @@ comparam(tp, t) if (ospeed == 0) { CLR(sc->sc_mcr, MCR_DTR); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); } /* @@ -767,34 +867,34 @@ comparam(tp, t) } } - outb(iobase + com_lcr, lcr | LCR_DLAB); - outb(iobase + com_dlbl, ospeed); - outb(iobase + com_dlbh, ospeed >> 8); - outb(iobase + com_lcr, lcr); + bus_io_write_1(bc, ioh, com_lcr, lcr | LCR_DLAB); + bus_io_write_1(bc, ioh, com_dlbl, ospeed); + bus_io_write_1(bc, ioh, com_dlbh, ospeed >> 8); + bus_io_write_1(bc, ioh, com_lcr, lcr); SET(sc->sc_mcr, MCR_DTR); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); } else - outb(iobase + com_lcr, lcr); + bus_io_write_1(bc, ioh, com_lcr, lcr); if (!ISSET(sc->sc_hwflags, COM_HW_HAYESP) && ISSET(sc->sc_hwflags, COM_HW_FIFO)) - outb(iobase + com_fifo, + bus_io_write_1(bc, ioh, com_fifo, FIFO_ENABLE | (t->c_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8)); } else - outb(iobase + com_lcr, lcr); + bus_io_write_1(bc, ioh, com_lcr, lcr); /* When not using CRTSCTS, RTS follows DTR. */ if (!ISSET(t->c_cflag, CRTSCTS)) { if (ISSET(sc->sc_mcr, MCR_DTR)) { if (!ISSET(sc->sc_mcr, MCR_RTS)) { SET(sc->sc_mcr, MCR_RTS); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); } } else { if (ISSET(sc->sc_mcr, MCR_RTS)) { CLR(sc->sc_mcr, MCR_RTS); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); } } sc->sc_dtr = MCR_DTR | MCR_RTS; @@ -816,7 +916,7 @@ comparam(tp, t) ISSET(oldcflag, MDMBUF) != ISSET(tp->t_cflag, MDMBUF) && (*linesw[tp->t_line].l_modem)(tp, 0) == 0) { CLR(sc->sc_mcr, sc->sc_dtr); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); } /* Just to be sure... */ @@ -830,7 +930,8 @@ comstart(tp) struct tty *tp; { struct com_softc *sc = comcd.cd_devs[COMUNIT(tp->t_dev)]; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; + bus_io_handle_t ioh = sc->sc_ioh; int s; s = spltty(); @@ -854,14 +955,14 @@ comstart(tp) if (!ISSET(sc->sc_ier, IER_ETXRDY)) { SET(sc->sc_ier, IER_ETXRDY); - outb(iobase + com_ier, sc->sc_ier); + bus_io_write_1(bc, ioh, com_ier, sc->sc_ier); } #ifdef COM_HAYESP if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) { u_char buffer[1024], *cp = buffer; int n = q_to_b(&tp->t_outq, cp, sizeof buffer); do - outb(iobase + com_data, *cp++); + bus_io_write_1(bc, ioh, com_data, *cp++); while (--n); } else @@ -870,17 +971,17 @@ comstart(tp) u_char buffer[16], *cp = buffer; int n = q_to_b(&tp->t_outq, cp, sizeof buffer); do { - outb(iobase + com_data, *cp++); + bus_io_write_1(bc, ioh, com_data, *cp++); } while (--n); } else - outb(iobase + com_data, getc(&tp->t_outq)); + bus_io_write_1(bc, ioh, com_data, getc(&tp->t_outq)); out: splx(s); return; stopped: if (ISSET(sc->sc_ier, IER_ETXRDY)) { CLR(sc->sc_ier, IER_ETXRDY); - outb(iobase + com_ier, sc->sc_ier); + bus_io_write_1(bc, ioh, com_ier, sc->sc_ier); } splx(s); } @@ -980,7 +1081,8 @@ compoll(arg) !ISSET(sc->sc_mcr, MCR_RTS)) { /* XXX */ SET(sc->sc_mcr, MCR_RTS); - outb(sc->sc_iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(sc->sc_bc, sc->sc_ioh, com_mcr, + sc->sc_mcr); } splx(s); @@ -1007,7 +1109,8 @@ comintr(arg) void *arg; { struct com_softc *sc = arg; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; + bus_io_handle_t ioh = sc->sc_ioh; struct tty *tp; u_char lsr, data, msr, delta; #ifdef COM_DEBUG @@ -1019,10 +1122,10 @@ comintr(arg) #ifdef COM_DEBUG n = 0; - if (ISSET(iter[n].iir = inb(iobase + com_iir), IIR_NOPEND)) + if (ISSET(iter[n].iir = bus_io_read_1(bc, ioh, com_iir), IIR_NOPEND)) return (0); #else - if (ISSET(inb(iobase + com_iir), IIR_NOPEND)) + if (ISSET(bus_io_read_1(bc, ioh, com_iir), IIR_NOPEND)) return (0); #endif @@ -1032,14 +1135,14 @@ comintr(arg) #ifdef COM_DEBUG iter[n].lsr = #endif - lsr = inb(iobase + com_lsr); + lsr = bus_io_read_1(bc, ioh, com_lsr); if (ISSET(lsr, LSR_RXRDY)) { register u_char *p = sc->sc_ibufp; comevents = 1; do { - data = inb(iobase + com_data); + data = bus_io_read_1(bc, ioh, com_data); if (ISSET(lsr, LSR_BI)) { #ifdef notdef printf("break %02x %02x %02x %02x\n", @@ -1047,7 +1150,8 @@ comintr(arg) sc->sc_dtr); #endif #ifdef DDB - if (sc->sc_dev.dv_unit == comconsole) { + if (ISSET(sc->sc_hwflags, + COM_HW_CONSOLE)) { Debugger(); goto next; } @@ -1064,8 +1168,8 @@ comintr(arg) ISSET(tp->t_cflag, CRTSCTS)) { /* XXX */ CLR(sc->sc_mcr, MCR_RTS); - outb(iobase + com_mcr, - sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, + sc->sc_mcr); } } next: @@ -1074,7 +1178,7 @@ comintr(arg) goto ohfudge; iter[n].lsr = #endif - lsr = inb(iobase + com_lsr); + lsr = bus_io_read_1(bc, ioh, com_lsr); } while (ISSET(lsr, LSR_RXRDY)); sc->sc_ibufp = p; @@ -1087,7 +1191,7 @@ comintr(arg) #ifdef COM_DEBUG iter[n].msr = #endif - msr = inb(iobase + com_msr); + msr = bus_io_read_1(bc, ioh, com_msr); if (msr != sc->sc_msr) { delta = msr ^ sc->sc_msr; @@ -1096,7 +1200,7 @@ comintr(arg) !ISSET(sc->sc_swflags, COM_SW_SOFTCAR) && (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD)) == 0) { CLR(sc->sc_mcr, sc->sc_dtr); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); } if (ISSET(delta & msr, MSR_CTS) && ISSET(tp->t_cflag, CRTSCTS)) { @@ -1115,10 +1219,10 @@ comintr(arg) #ifdef COM_DEBUG if (++n >= 32) goto ohfudge; - if (ISSET(iter[n].iir = inb(iobase + com_iir), IIR_NOPEND)) + if (ISSET(iter[n].iir = bus_io_read_1(bc, ioh, com_iir), IIR_NOPEND)) return (1); #else - if (ISSET(inb(iobase + com_iir), IIR_NOPEND)) + if (ISSET(bus_io_read_1(bc, ioh, com_iir), IIR_NOPEND)) return (1); #endif } @@ -1147,8 +1251,21 @@ void comcnprobe(cp) struct consdev *cp; { + bus_chipset_tag_t bc; + bus_io_handle_t ioh; + int found; - if (!comprobe1(CONADDR)) { +#if 0 + XXX NEEDS TO BE FIXED XXX + bc = ???; +#endif + if (bus_io_map(bc, CONADDR, COM_NPORTS, &ioh)) { + cp->cn_pri = CN_DEAD; + return; + } + found = comprobe1(bc, ioh, CONADDR); + bus_io_unmap(bc, ioh, COM_NPORTS); + if (!found) { cp->cn_pri = CN_DEAD; return; } @@ -1172,26 +1289,34 @@ comcninit(cp) struct consdev *cp; { - cominit(CONUNIT, comdefaultrate); - comconsole = CONUNIT; +#if 0 + XXX NEEDS TO BE FIXED XXX + comconsbc = ???; +#endif + if (bus_io_map(comconsbc, CONADDR, COM_NPORTS, &comconsioh)) + panic("comcninit: mapping failed"); + + cominit(comconsbc, comconsioh, comdefaultrate); + comconsaddr = CONADDR; comconsinit = 0; } -cominit(unit, rate) - int unit, rate; +cominit(bc, ioh, rate) + bus_chipset_tag_t bc; + bus_io_handle_t ioh; + int rate; { int s = splhigh(); - int iobase = CONADDR; u_char stat; - outb(iobase + com_lcr, LCR_DLAB); + bus_io_write_1(bc, ioh, com_lcr, LCR_DLAB); rate = comspeed(comdefaultrate); - outb(iobase + com_dlbl, rate); - outb(iobase + com_dlbh, rate >> 8); - outb(iobase + com_lcr, LCR_8BITS); - outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY); - outb(iobase + com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_4); - stat = inb(iobase + com_iir); + bus_io_write_1(bc, ioh, com_dlbl, rate); + bus_io_write_1(bc, ioh, com_dlbh, rate >> 8); + bus_io_write_1(bc, ioh, com_lcr, LCR_8BITS); + bus_io_write_1(bc, ioh, com_ier, IER_ERXRDY | IER_ETXRDY); + bus_io_write_1(bc, ioh, com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_4); + stat = bus_io_read_1(bc, ioh, com_iir); splx(s); } @@ -1199,13 +1324,14 @@ comcngetc(dev) dev_t dev; { int s = splhigh(); - int iobase = CONADDR; + bus_chipset_tag_t bc = comconsbc; + bus_io_handle_t ioh = comconsioh; u_char stat, c; - while (!ISSET(stat = inb(iobase + com_lsr), LSR_RXRDY)) + while (!ISSET(stat = bus_io_read_1(bc, ioh, com_lsr), LSR_RXRDY)) ; - c = inb(iobase + com_data); - stat = inb(iobase + com_iir); + c = bus_io_read_1(bc, ioh, com_data); + stat = bus_io_read_1(bc, ioh, com_iir); splx(s); return c; } @@ -1219,7 +1345,8 @@ comcnputc(dev, c) int c; { int s = splhigh(); - int iobase = CONADDR; + bus_chipset_tag_t bc = comconsbc; + bus_io_handle_t ioh = comconsioh; u_char stat; register int timo; @@ -1227,20 +1354,20 @@ comcnputc(dev, c) if (dev != kgdb_dev) #endif if (comconsinit == 0) { - (void) cominit(COMUNIT(dev), comdefaultrate); + (void) cominit(bc, ioh, comdefaultrate); comconsinit = 1; } /* wait for any pending transmission to finish */ timo = 50000; - while (!ISSET(stat = inb(iobase + com_lsr), LSR_TXRDY) && --timo) + while (!ISSET(stat = bus_io_read_1(bc, ioh, com_lsr), LSR_TXRDY) && --timo) ; - outb(iobase + com_data, c); + bus_io_write_1(bc, ioh, com_data, c); /* wait for this transmission to complete */ timo = 1500000; - while (!ISSET(stat = inb(iobase + com_lsr), LSR_TXRDY) && --timo) + while (!ISSET(stat = bus_io_read_1(bc, ioh, com_lsr), LSR_TXRDY) && --timo) ; /* clear any interrupts generated by this transmission */ - stat = inb(iobase + com_iir); + stat = bus_io_read_1(bc, ioh, com_iir); splx(s); } diff --git a/sys/dev/ic/comvar.h b/sys/dev/ic/comvar.h index 7871165eba55..b86f7af1861f 100644 --- a/sys/dev/ic/comvar.h +++ b/sys/dev/ic/comvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: comvar.h,v 1.2 1996/03/09 23:37:14 cgd Exp $ */ +/* $NetBSD: comvar.h,v 1.3 1996/03/10 09:01:26 cgd Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. @@ -32,6 +32,16 @@ struct commulti_attach_args { int ca_slave; /* slave number */ + + bus_chipset_tag_t ca_bc; + bus_io_handle_t ca_ioh; + int ca_iobase; + int ca_noien; }; -int comprobe1 __P((int)); +int comprobe1 __P((bus_chipset_tag_t, bus_io_handle_t, int)); + +extern int comconsaddr; +extern int comconsattached; +extern bus_chipset_tag_t comconsbc; +extern bus_io_handle_t comconsioh; diff --git a/sys/dev/isa/ast.c b/sys/dev/isa/ast.c index 2873923fe5a8..1f0464346b15 100644 --- a/sys/dev/isa/ast.c +++ b/sys/dev/isa/ast.c @@ -1,6 +1,7 @@ -/* $NetBSD: ast.c,v 1.21 1996/03/09 01:03:59 cgd Exp $ */ +/* $NetBSD: ast.c,v 1.22 1996/03/10 09:01:20 cgd Exp $ */ /* + * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. * Copyright (c) 1995 Charles Hannum. All rights reserved. * * This code is derived from public-domain software written by @@ -35,7 +36,7 @@ #include #include -#include +#include #include #include @@ -47,9 +48,12 @@ struct ast_softc { struct device sc_dev; void *sc_ih; + bus_chipset_tag_t sc_bc; int sc_iobase; + int sc_alive; /* mask of slave units attached */ void *sc_slaves[NSLAVES]; /* com device unit numbers */ + bus_io_handle_t sc_slaveioh[NSLAVES]; }; int astprobe(); @@ -66,40 +70,62 @@ astprobe(parent, self, aux) void *aux; { struct isa_attach_args *ia = aux; + int iobase = ia->ia_iobase; + bus_chipset_tag_t bc = ia->ia_bc; + bus_io_handle_t ioh; + int i, rv = 1; /* * Do the normal com probe for the first UART and assume - * its presence means there is a multiport board there. + * its presence, and the ability to map the other UARTS, + * means there is a multiport board there. * XXX Needs more robustness. */ - ia->ia_iosize = NSLAVES * COM_NPORTS; - return (comprobe1(ia->ia_iobase)); + + /* if the first port is in use as console, then it. */ + if (iobase == comconsaddr && !comconsattached) + goto checkmappings; + + if (bus_io_map(bc, iobase, COM_NPORTS, &ioh)) { + rv = 0; + goto out; + } + rv = comprobe1(bc, ioh, iobase); + bus_io_unmap(bc, ioh, COM_NPORTS); + if (rv == 0) + goto out; + +checkmappings: + for (i = 1; i < NSLAVES; i++) { + iobase += COM_NPORTS; + + if (iobase == comconsaddr && !comconsattached) + continue; + + if (bus_io_map(bc, iobase, COM_NPORTS, &ioh)) { + rv = 0; + goto out; + } + bus_io_unmap(bc, ioh, COM_NPORTS); + } + +out: + if (rv) + ia->ia_iosize = NSLAVES * COM_NPORTS; + return (rv); } int -astsubmatch(parent, match, aux) - struct device *parent; - void *match, *aux; -{ - struct ast_softc *sc = (void *)parent; - struct cfdata *cf = match; - struct isa_attach_args *ia = aux; - struct commulti_attach_args *ca = ia->ia_aux; - - if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ca->ca_slave) - return (0); - return ((*cf->cf_driver->cd_match)(parent, match, ia)); -} - -int -astprint(aux, ast) +astprint(aux, pnp) void *aux; - char *ast; + char *pnp; { - struct isa_attach_args *ia = aux; - struct commulti_attach_args *ca = ia->ia_aux; + struct commulti_attach_args *ca = aux; + if (pnp) + printf("com at %s", pnp); printf(" slave %d", ca->ca_slave); + return (UNCONF); } void @@ -110,32 +136,41 @@ astattach(parent, self, aux) struct ast_softc *sc = (void *)self; struct isa_attach_args *ia = aux; struct commulti_attach_args ca; - struct isa_attach_args isa; - int subunit; + int i, subunit; + sc->sc_bc = ia->ia_bc; sc->sc_iobase = ia->ia_iobase; + for (i = 0; i < NSLAVES; i++) + if (bus_io_map(bc, sc->sc_iobase + i * COM_NPORTS, COM_NPORTS, + &sc->sc_slaveioh[i])) + panic("astattach: couldn't map slave %d", i); + /* * Enable the master interrupt. */ - outb(sc->sc_iobase | 0x1f, 0x80); + bus_io_write_1(bc, sc->sc_slaveioh[3], 7, 0x80); printf("\n"); - isa.ia_aux = &ca; - for (ca.ca_slave = 0; ca.ca_slave < NSLAVES; ca.ca_slave++) { - struct cfdata *cf; - isa.ia_iobase = sc->sc_iobase + COM_NPORTS * ca.ca_slave; - isa.ia_iosize = 0x666; - isa.ia_irq = IRQUNK; - isa.ia_drq = DRQUNK; - isa.ia_msize = 0; - if ((cf = config_search(astsubmatch, self, &isa)) != 0) { - subunit = cf->cf_unit; /* can change if unit == * */ - config_attach(self, cf, &isa, astprint); - sc->sc_slaves[ca.ca_slave] = - cf->cf_driver->cd_devs[subunit]; - sc->sc_alive |= 1 << ca.ca_slave; + for (i = 0; i < NSLAVES; i++) { + struct cfdata *match; + + ca.ca_slave = i; + ca.ca_bc = sc->sc_bc; + ca.ca_ioh = sc->sc_slaveioh[i]; + ca.ca_iobase = sc->sc_iobase + i * COM_NPORTS; + ca.ca_noien = 1; + + /* mimic config_found(), but with special functionality */ + if ((match = config_search(NULL, self, &ca)) != NULL) { + subunit = match->cf_unit; /* can change if unit == * */ + config_attach(self, match, &ca, astprint); + sc->sc_slaves[i] = match->cf_driver->cd_devs[subunit]; + sc->sc_alive |= 1 << i; + } else { + astprint(&ca, self->dv_xname); + printf(" not configured\n"); } } @@ -148,11 +183,11 @@ astintr(arg) void *arg; { struct ast_softc *sc = arg; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; int alive = sc->sc_alive; int bits; - bits = ~inb(iobase | 0x1f) & alive; + bits = ~bus_io_read_1(bc, sc->sc_slaveioh[3], 7) & alive; if (bits == 0) return (0); @@ -165,7 +200,7 @@ astintr(arg) TRY(2); TRY(3); #undef TRY - bits = ~inb(iobase | 0x1f) & alive; + bits = ~bus_io_read_1(bc, sc->sc_slaveioh[3], 7) & alive; if (bits == 0) return (1); } diff --git a/sys/dev/isa/boca.c b/sys/dev/isa/boca.c index f9a98ac9376f..eb7ddc4f9807 100644 --- a/sys/dev/isa/boca.c +++ b/sys/dev/isa/boca.c @@ -1,6 +1,7 @@ -/* $NetBSD: boca.c,v 1.8 1996/03/09 01:04:00 cgd Exp $ */ +/* $NetBSD: boca.c,v 1.9 1996/03/10 09:01:22 cgd Exp $ */ /* + * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. * Copyright (c) 1995 Charles Hannum. All rights reserved. * * This code is derived from public-domain software written by @@ -35,7 +36,7 @@ #include #include -#include +#include #include #include @@ -47,9 +48,12 @@ struct boca_softc { struct device sc_dev; void *sc_ih; + bus_chipset_tag_t sc_bc; int sc_iobase; + int sc_alive; /* mask of slave units attached */ void *sc_slaves[NSLAVES]; /* com device unit numbers */ + bus_io_handle_t sc_slaveioh[NSLAVES]; }; int bocaprobe(); @@ -66,40 +70,62 @@ bocaprobe(parent, self, aux) void *aux; { struct isa_attach_args *ia = aux; + int iobase = ia->ia_iobase; + bus_chipset_tag_t bc = ia->ia_bc; + bus_io_handle_t ioh; + int i, rv = 1; /* * Do the normal com probe for the first UART and assume - * its presence means there is a multiport board there. + * its presence, and the ability to map the other UARTS, + * means there is a multiport board there. * XXX Needs more robustness. */ - ia->ia_iosize = NSLAVES * COM_NPORTS; - return (comprobe1(ia->ia_iobase)); + + /* if the first port is in use as console, then it. */ + if (iobase == comconsaddr && !comconsattached) + goto checkmappings; + + if (bus_io_map(bc, iobase, COM_NPORTS, &ioh)) { + rv = 0; + goto out; + } + rv = comprobe1(bc, ioh, iobase); + bus_io_unmap(bc, ioh, COM_NPORTS); + if (rv == 0) + goto out; + +checkmappings: + for (i = 1; i < NSLAVES; i++) { + iobase += COM_NPORTS; + + if (iobase == comconsaddr && !comconsattached) + continue; + + if (bus_io_map(bc, iobase, COM_NPORTS, &ioh)) { + rv = 0; + goto out; + } + bus_io_unmap(bc, ioh, COM_NPORTS); + } + +out: + if (rv) + ia->ia_iosize = NSLAVES * COM_NPORTS; + return (rv); } int -bocasubmatch(parent, match, aux) - struct device *parent; - void *match, *aux; -{ - struct boca_softc *sc = (void *)parent; - struct cfdata *cf = match; - struct isa_attach_args *ia = aux; - struct commulti_attach_args *ca = ia->ia_aux; - - if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ca->ca_slave) - return (0); - return ((*cf->cf_driver->cd_match)(parent, match, ia)); -} - -int -bocaprint(aux, boca) +bocaprint(aux, pnp) void *aux; - char *boca; + char *pnp; { - struct isa_attach_args *ia = aux; - struct commulti_attach_args *ca = ia->ia_aux; + struct commulti_attach_args *ca = aux; + if (pnp) + printf("com at %s", pnp); printf(" slave %d", ca->ca_slave); + return (UNCONF); } void @@ -110,27 +136,36 @@ bocaattach(parent, self, aux) struct boca_softc *sc = (void *)self; struct isa_attach_args *ia = aux; struct commulti_attach_args ca; - struct isa_attach_args isa; - int subunit; + int i, subunit; + sc->sc_bc = ia->ia_bc; sc->sc_iobase = ia->ia_iobase; + for (i = 0; i < NSLAVES; i++) + if (bus_io_map(bc, sc->sc_iobase + i * COM_NPORTS, COM_NPORTS, + &sc->sc_slaveioh[i])) + panic("bocaattach: couldn't map slave %d", i); + printf("\n"); - isa.ia_aux = &ca; - for (ca.ca_slave = 0; ca.ca_slave < NSLAVES; ca.ca_slave++) { - struct cfdata *cf; - isa.ia_iobase = sc->sc_iobase + COM_NPORTS * ca.ca_slave; - isa.ia_iosize = 0x666; - isa.ia_irq = IRQUNK; - isa.ia_drq = DRQUNK; - isa.ia_msize = 0; - if ((cf = config_search(bocasubmatch, self, &isa)) != 0) { - subunit = cf->cf_unit; /* can change if unit == * */ - config_attach(self, cf, &isa, bocaprint); - sc->sc_slaves[ca.ca_slave] = - cf->cf_driver->cd_devs[subunit]; - sc->sc_alive |= 1 << ca.ca_slave; + for (i = 0; i < NSLAVES; i++) { + struct cfdata *match; + + ca.ca_slave = i; + ca.ca_bc = sc->sc_bc; + ca.ca_ioh = sc->sc_slaveioh[i]; + ca.ca_iobase = sc->sc_iobase + i * COM_NPORTS; + ca.ca_noien = 0; + + /* mimic config_found(), but with special functionality */ + if ((match = config_search(NULL, self, &ca)) != NULL) { + subunit = match->cf_unit; /* can change if unit == * */ + config_attach(self, match, &ca, bocaprint); + sc->sc_slaves[i] = match->cf_driver->cd_devs[subunit]; + sc->sc_alive |= 1 << i; + } else { + bocaprint(&ca, self->dv_xname); + printf(" not configured\n"); } } @@ -143,11 +178,11 @@ bocaintr(arg) void *arg; { struct boca_softc *sc = arg; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; int alive = sc->sc_alive; int bits; - bits = inb(iobase | 0x07) & alive; + bits = bus_io_read_1(bc, sc->sc_slaveioh[0], 7) & alive; if (bits == 0) return (0); @@ -164,7 +199,7 @@ bocaintr(arg) TRY(6); TRY(7); #undef TRY - bits = inb(iobase | 0x07) & alive; + bits = bus_io_read_1(bc, sc->sc_slaveioh[0], 7) & alive; if (bits == 0) return (1); } diff --git a/sys/dev/isa/com.c b/sys/dev/isa/com.c index cfc971e4b517..f0361fae4541 100644 --- a/sys/dev/isa/com.c +++ b/sys/dev/isa/com.c @@ -1,4 +1,4 @@ -/* $NetBSD: com.c,v 1.74 1996/03/09 01:02:08 cgd Exp $ */ +/* $NetBSD: com.c,v 1.75 1996/03/10 09:01:24 cgd Exp $ */ /*- * Copyright (c) 1993, 1994, 1995, 1996 @@ -57,7 +57,7 @@ #include #include -#include +#include #include #include @@ -86,6 +86,11 @@ struct com_softc { #ifdef COM_HAYESP int sc_hayespbase; #endif + + bus_chipset_tag_t sc_bc; + bus_io_handle_t sc_ioh; + bus_io_handle_t sc_hayespioh; + u_char sc_hwflags; #define COM_HW_NOIEN 0x01 #define COM_HW_FIFO 0x02 @@ -104,6 +109,9 @@ struct com_softc { }; int comprobe __P((struct device *, void *, void *)); +#ifdef COM_HAYESP +int comprobeHAYESP __P((bus_io_handle_t hayespioh, struct com_softc *sc)); +#endif void comattach __P((struct device *, struct device *, void *)); int comopen __P((dev_t, int, int, struct proc *)); int comclose __P((dev_t, int, int, struct proc *)); @@ -113,18 +121,23 @@ void compoll __P((void *)); int comparam __P((struct tty *, struct termios *)); void comstart __P((struct tty *)); +int cominit __P((bus_chipset_tag_t, bus_io_handle_t, int)); + struct cfdriver comcd = { NULL, "com", comprobe, comattach, DV_TTY, sizeof(struct com_softc) }; #ifdef COMCONSOLE -int comdefaultrate = CONSPEED; -int comconsole = COMCONSOLE; +int comdefaultrate = CONSPEED; /* XXX why set default? */ #else int comdefaultrate = TTYDEF_SPEED; -int comconsole = -1; #endif +int comconsaddr; int comconsinit; +int comconsattached; +bus_chipset_tag_t comconsbc; +bus_io_handle_t comconsioh; + int commajor; int comsopen = 0; int comevents = 0; @@ -169,14 +182,16 @@ comspeed(speed) } int -comprobe1(iobase) +comprobe1(bc, ioh, iobase) + bus_chipset_tag_t bc; + bus_io_handle_t ioh; int iobase; { /* force access to id reg */ - outb(iobase + com_lcr, 0); - outb(iobase + com_iir, 0); - if (inb(iobase + com_iir) & 0x38) + bus_io_write_1(bc, ioh, com_lcr, 0); + bus_io_write_1(bc, ioh, com_iir, 0); + if (bus_io_read_1(bc, ioh, com_iir) & 0x38) return 0; return 1; @@ -184,12 +199,13 @@ comprobe1(iobase) #ifdef COM_HAYESP int -comprobeHAYESP(iobase, sc) - int iobase; +comprobeHAYESP(hayespioh, sc) + bus_io_handle_t hayespioh; struct com_softc *sc; { char val, dips; int combaselist[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; + bus_chipset_tag_t bc = sc->sc_bc; /* * Hayes ESP cards have two iobases. One is for compatibility with @@ -199,7 +215,7 @@ comprobeHAYESP(iobase, sc) */ /* Test for ESP signature */ - if ((inb(iobase) & 0xf3) == 0) + if ((bus_io_read_1(bc, hayespioh, 0) & 0xf3) == 0) return 0; /* @@ -207,8 +223,8 @@ comprobeHAYESP(iobase, sc) */ /* Get the dip-switch configurations */ - outb(iobase + HAYESP_CMD1, HAYESP_GETDIPS); - dips = inb(iobase + HAYESP_STATUS1); + bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_GETDIPS); + dips = bus_io_read_1(bc, hayespioh, HAYESP_STATUS1); /* Determine which com port this ESP card services: bits 0,1 of */ /* dips is the port # (0-3); combaselist[val] is the com_iobase */ @@ -219,9 +235,9 @@ comprobeHAYESP(iobase, sc) /* Check ESP Self Test bits. */ /* Check for ESP version 2.0: bits 4,5,6 == 010 */ - outb(iobase + HAYESP_CMD1, HAYESP_GETTEST); - val = inb(iobase + HAYESP_STATUS1); /* Clear reg 1 */ - val = inb(iobase + HAYESP_STATUS2); + bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_GETTEST); + val = bus_io_read_1(bc, hayespioh, HAYESP_STATUS1); /* Clear reg 1 */ + val = bus_io_read_1(bc, hayespioh, HAYESP_STATUS2); if ((val & 0x70) < 0x20) { printf("-old (%o)", val & 0x70); /* we do not support the necessary features */ @@ -251,15 +267,50 @@ comprobe(parent, match, aux) struct device *parent; void *match, *aux; { - struct isa_attach_args *ia = aux; - int iobase = ia->ia_iobase; + struct cfdata *cf = match; + bus_chipset_tag_t bc; + bus_io_handle_t ioh; + int iobase, needioh; + int rv = 1; - if (!comprobe1(iobase)) - return 0; + if (!strcmp(parent->dv_cfdata->cf_driver->cd_name, "isa")) { + struct isa_attach_args *ia = aux; - ia->ia_iosize = COM_NPORTS; - ia->ia_msize = 0; - return 1; + bc = ia->ia_bc; + iobase = ia->ia_iobase; + needioh = 1; + } else { + struct commulti_attach_args *ca = aux; + + if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ca->ca_slave) + return (0); + + bc = ca->ca_bc; + iobase = ca->ca_iobase; + ioh = ca->ca_ioh; + needioh = 0; + } + + /* if it's in use as console, it's there. */ + if (iobase == comconsaddr && !comconsattached) + goto out; + + if (needioh && bus_io_map(bc, iobase, COM_NPORTS, &ioh)) { + rv = 0; + goto out; + } + rv = comprobe1(bc, ioh, iobase); + if (needioh) + bus_io_unmap(bc, ioh, COM_NPORTS); + +out: + if (rv && !strcmp(parent->dv_cfdata->cf_driver->cd_name, "isa")) { + struct isa_attach_args *ia = aux; + + ia->ia_iosize = COM_NPORTS; + ia->ia_msize = 0; + } + return (rv); } void @@ -268,64 +319,114 @@ comattach(parent, self, aux) void *aux; { struct com_softc *sc = (void *)self; - struct isa_attach_args *ia = aux; struct cfdata *cf = sc->sc_dev.dv_cfdata; - int iobase = ia->ia_iobase; + int iobase, irq; + bus_chipset_tag_t bc; + bus_io_handle_t ioh; struct tty *tp; #ifdef COM_HAYESP int hayesp_ports[] = { 0x140, 0x180, 0x280, 0x300, 0 }; int *hayespp; #endif - sc->sc_iobase = iobase; - sc->sc_hwflags = ISSET(cf->cf_flags, COM_HW_NOIEN); + sc->sc_hwflags = 0; sc->sc_swflags = 0; + if (!strcmp(parent->dv_cfdata->cf_driver->cd_name, "isa")) { + struct isa_attach_args *ia = aux; - if (sc->sc_dev.dv_unit == comconsole) - delay(1000); + /* + * We're living on an isa. + */ + iobase = ia->ia_iobase; + bc = ia->ia_bc; + if (iobase != comconsaddr) { + if (bus_io_map(bc, iobase, COM_NPORTS, &ioh)) + panic("comattach: io mapping failed"); + } else + ioh = comconsioh; + irq = ia->ia_irq; + } else { + struct commulti_attach_args *ca = aux; + + /* + * We're living on a commulti. + */ + iobase = ca->ca_iobase; + bc = ca->ca_bc; + ioh = ca->ca_ioh; + irq = IRQUNK; + + if (ca->ca_noien) + sc->sc_hwflags |= COM_HW_NOIEN; + } + + sc->sc_bc = bc; + sc->sc_ioh = ioh; + sc->sc_iobase = iobase; + + if (iobase == comconsaddr) { + comconsattached = 1; + + /* + * Need to reset baud rate, etc. of next print so reset + * comconsinit. Also make sure console is always "hardwired". + */ + delay(1000); /* wait for output to finish */ + comconsinit = 0; + SET(sc->sc_hwflags, COM_HW_CONSOLE); + SET(sc->sc_swflags, COM_SW_SOFTCAR); + } #ifdef COM_HAYESP /* Look for a Hayes ESP board. */ - for (hayespp = hayesp_ports; *hayespp != 0; hayespp++) - if (comprobeHAYESP(*hayespp, sc)) { + for (hayespp = hayesp_ports; *hayespp != 0; hayespp++) { + bus_io_handle_t hayespioh; + +#define HAYESP_NPORTS 8 /* XXX XXX XXX ??? ??? ??? */ + if (bus_io_map(bc, *hayespp, HAYESP_NPORTS, &hayespioh)) + continue; + if (comprobeHAYESP(hayespioh, sc)) { sc->sc_hayespbase = *hayespp; + sc->sc_hayespioh = hayespioh; break; } + bus_io_unmap(bc, hayespioh, HAYESP_NPORTS); + } /* No ESP; look for other things. */ if (*hayespp == 0) { #endif /* look for a NS 16550AF UART with FIFOs */ - outb(iobase + com_fifo, + bus_io_write_1(bc, ioh, com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14); delay(100); - if (ISSET(inb(iobase + com_iir), IIR_FIFO_MASK) == IIR_FIFO_MASK) - if (ISSET(inb(iobase + com_fifo), FIFO_TRIGGER_14) == FIFO_TRIGGER_14) { + if (ISSET(bus_io_read_1(bc, ioh, com_iir), IIR_FIFO_MASK) == IIR_FIFO_MASK) + if (ISSET(bus_io_read_1(bc, ioh, com_fifo), FIFO_TRIGGER_14) == FIFO_TRIGGER_14) { SET(sc->sc_hwflags, COM_HW_FIFO); printf(": ns16550a, working fifo\n"); } else printf(": ns16550, broken fifo\n"); else printf(": ns8250 or ns16450, no fifo\n"); - outb(iobase + com_fifo, 0); + bus_io_write_1(bc, ioh, com_fifo, 0); #ifdef COM_HAYESP } #endif /* disable interrupts */ - outb(iobase + com_ier, 0); - outb(iobase + com_mcr, 0); + bus_io_write_1(bc, ioh, com_ier, 0); + bus_io_write_1(bc, ioh, com_mcr, 0); - if (ia->ia_irq != IRQUNK) - sc->sc_ih = isa_intr_establish(ia->ia_irq, IST_EDGE, IPL_TTY, + if (irq != IRQUNK) + sc->sc_ih = isa_intr_establish(irq, IST_EDGE, IPL_TTY, comintr, sc); #ifdef KGDB if (kgdb_dev == makedev(commajor, unit)) { - if (comconsole == unit) + if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) kgdb_dev = -1; /* can't debug over console port */ else { - (void) cominit(unit, kgdb_rate); + (void) cominit(bc, ioh, kgdb_rate); if (kgdb_debug_init) { /* * Print prefix of device name, @@ -340,15 +441,9 @@ comattach(parent, self, aux) } #endif - if (sc->sc_dev.dv_unit == comconsole) { - /* - * Need to reset baud rate, etc. of next print so reset - * comconsinit. Also make sure console is always "hardwired". - */ - comconsinit = 0; - SET(sc->sc_hwflags, COM_HW_CONSOLE); - SET(sc->sc_swflags, COM_SW_SOFTCAR); - } + /* XXX maybe move up some? */ + if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) + printf("%s: console\n", sc->sc_dev.dv_xname); } int @@ -359,7 +454,8 @@ comopen(dev, flag, mode, p) { int unit = COMUNIT(dev); struct com_softc *sc; - int iobase; + bus_chipset_tag_t bc; + bus_io_handle_t ioh; struct tty *tp; int s; int error = 0; @@ -405,56 +501,57 @@ comopen(dev, flag, mode, p) sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER; sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE; - iobase = sc->sc_iobase; + bc = sc->sc_bc; + ioh = sc->sc_ioh; #ifdef COM_HAYESP /* Setup the ESP board */ if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) { - int hayespbase = sc->sc_hayespbase; + bus_io_handle_t hayespioh = sc->sc_hayespioh; - outb(iobase + com_fifo, + bus_io_write_1(bc, ioh, com_fifo, FIFO_DMA_MODE|FIFO_ENABLE| FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_8); /* Set 16550 compatibility mode */ - outb(hayespbase + HAYESP_CMD1, HAYESP_SETMODE); - outb(hayespbase + HAYESP_CMD2, + bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_SETMODE); + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_MODE_FIFO|HAYESP_MODE_RTS| HAYESP_MODE_SCALE); /* Set RTS/CTS flow control */ - outb(hayespbase + HAYESP_CMD1, HAYESP_SETFLOWTYPE); - outb(hayespbase + HAYESP_CMD2, HAYESP_FLOW_RTS); - outb(hayespbase + HAYESP_CMD2, HAYESP_FLOW_CTS); + bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_SETFLOWTYPE); + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_FLOW_RTS); + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_FLOW_CTS); /* Set flow control levels */ - outb(hayespbase + HAYESP_CMD1, HAYESP_SETRXFLOW); - outb(hayespbase + HAYESP_CMD2, + bus_io_write_1(bc, hayespioh, HAYESP_CMD1, HAYESP_SETRXFLOW); + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_HIBYTE(HAYESP_RXHIWMARK)); - outb(hayespbase + HAYESP_CMD2, + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_LOBYTE(HAYESP_RXHIWMARK)); - outb(hayespbase + HAYESP_CMD2, + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_HIBYTE(HAYESP_RXLOWMARK)); - outb(hayespbase + HAYESP_CMD2, + bus_io_write_1(bc, hayespioh, HAYESP_CMD2, HAYESP_LOBYTE(HAYESP_RXLOWMARK)); } else #endif if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) /* Set the FIFO threshold based on the receive speed. */ - outb(iobase + com_fifo, + bus_io_write_1(bc, ioh, com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | (tp->t_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8)); /* flush any pending I/O */ - while (ISSET(inb(iobase + com_lsr), LSR_RXRDY)) - (void) inb(iobase + com_data); + while (ISSET(bus_io_read_1(bc, ioh, com_lsr), LSR_RXRDY)) + (void) bus_io_read_1(bc, ioh, com_data); /* you turn me on, baby */ sc->sc_mcr = MCR_DTR | MCR_RTS; if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN)) SET(sc->sc_mcr, MCR_IENABLE); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC; - outb(iobase + com_ier, sc->sc_ier); + bus_io_write_1(bc, ioh, com_ier, sc->sc_ier); - sc->sc_msr = inb(iobase + com_msr); + sc->sc_msr = bus_io_read_1(bc, ioh, com_msr); if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) || ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF)) SET(tp->t_state, TS_CARR_ON); @@ -493,7 +590,8 @@ comclose(dev, flag, mode, p) int unit = COMUNIT(dev); struct com_softc *sc = comcd.cd_devs[unit]; struct tty *tp = sc->sc_tty; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; + bus_io_handle_t ioh = sc->sc_ioh; int s; /* XXX This is for cons.c. */ @@ -503,12 +601,12 @@ comclose(dev, flag, mode, p) (*linesw[tp->t_line].l_close)(tp, flag); s = spltty(); CLR(sc->sc_lcr, LCR_SBREAK); - outb(iobase + com_lcr, sc->sc_lcr); - outb(iobase + com_ier, 0); + bus_io_write_1(bc, ioh, com_lcr, sc->sc_lcr); + bus_io_write_1(bc, ioh, com_ier, 0); if (ISSET(tp->t_cflag, HUPCL) && !ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) { /* XXX perhaps only clear DTR */ - outb(iobase + com_mcr, 0); + bus_io_write_1(bc, ioh, com_mcr, 0); } CLR(tp->t_state, TS_BUSY | TS_FLUSH); if (--comsopen == 0) @@ -516,7 +614,7 @@ comclose(dev, flag, mode, p) splx(s); ttyclose(tp); #ifdef notyet /* XXXX */ - if (unit != comconsole) { + if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { ttyfree(tp); sc->sc_tty = 0; } @@ -582,7 +680,8 @@ comioctl(dev, cmd, data, flag, p) int unit = COMUNIT(dev); struct com_softc *sc = comcd.cd_devs[unit]; struct tty *tp = sc->sc_tty; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; + bus_io_handle_t ioh = sc->sc_ioh; int error; error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); @@ -595,29 +694,29 @@ comioctl(dev, cmd, data, flag, p) switch (cmd) { case TIOCSBRK: SET(sc->sc_lcr, LCR_SBREAK); - outb(iobase + com_lcr, sc->sc_lcr); + bus_io_write_1(bc, ioh, com_lcr, sc->sc_lcr); break; case TIOCCBRK: CLR(sc->sc_lcr, LCR_SBREAK); - outb(iobase + com_lcr, sc->sc_lcr); + bus_io_write_1(bc, ioh, com_lcr, sc->sc_lcr); break; case TIOCSDTR: SET(sc->sc_mcr, sc->sc_dtr); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); break; case TIOCCDTR: CLR(sc->sc_mcr, sc->sc_dtr); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); break; case TIOCMSET: CLR(sc->sc_mcr, MCR_DTR | MCR_RTS); case TIOCMBIS: SET(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data)); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); break; case TIOCMBIC: CLR(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data)); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); break; case TIOCMGET: { u_char m; @@ -637,7 +736,7 @@ comioctl(dev, cmd, data, flag, p) SET(bits, TIOCM_DSR); if (ISSET(m, MSR_RI | MSR_TERI)) SET(bits, TIOCM_RI); - if (inb(iobase + com_ier)) + if (bus_io_read_1(bc, ioh, com_ier)) SET(bits, TIOCM_LE); *(int *)data = bits; break; @@ -692,7 +791,8 @@ comparam(tp, t) struct termios *t; { struct com_softc *sc = comcd.cd_devs[COMUNIT(tp->t_dev)]; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; + bus_io_handle_t ioh = sc->sc_ioh; int ospeed = comspeed(t->c_ospeed); u_char lcr; tcflag_t oldcflag; @@ -732,7 +832,7 @@ comparam(tp, t) if (ospeed == 0) { CLR(sc->sc_mcr, MCR_DTR); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); } /* @@ -767,34 +867,34 @@ comparam(tp, t) } } - outb(iobase + com_lcr, lcr | LCR_DLAB); - outb(iobase + com_dlbl, ospeed); - outb(iobase + com_dlbh, ospeed >> 8); - outb(iobase + com_lcr, lcr); + bus_io_write_1(bc, ioh, com_lcr, lcr | LCR_DLAB); + bus_io_write_1(bc, ioh, com_dlbl, ospeed); + bus_io_write_1(bc, ioh, com_dlbh, ospeed >> 8); + bus_io_write_1(bc, ioh, com_lcr, lcr); SET(sc->sc_mcr, MCR_DTR); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); } else - outb(iobase + com_lcr, lcr); + bus_io_write_1(bc, ioh, com_lcr, lcr); if (!ISSET(sc->sc_hwflags, COM_HW_HAYESP) && ISSET(sc->sc_hwflags, COM_HW_FIFO)) - outb(iobase + com_fifo, + bus_io_write_1(bc, ioh, com_fifo, FIFO_ENABLE | (t->c_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8)); } else - outb(iobase + com_lcr, lcr); + bus_io_write_1(bc, ioh, com_lcr, lcr); /* When not using CRTSCTS, RTS follows DTR. */ if (!ISSET(t->c_cflag, CRTSCTS)) { if (ISSET(sc->sc_mcr, MCR_DTR)) { if (!ISSET(sc->sc_mcr, MCR_RTS)) { SET(sc->sc_mcr, MCR_RTS); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); } } else { if (ISSET(sc->sc_mcr, MCR_RTS)) { CLR(sc->sc_mcr, MCR_RTS); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); } } sc->sc_dtr = MCR_DTR | MCR_RTS; @@ -816,7 +916,7 @@ comparam(tp, t) ISSET(oldcflag, MDMBUF) != ISSET(tp->t_cflag, MDMBUF) && (*linesw[tp->t_line].l_modem)(tp, 0) == 0) { CLR(sc->sc_mcr, sc->sc_dtr); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); } /* Just to be sure... */ @@ -830,7 +930,8 @@ comstart(tp) struct tty *tp; { struct com_softc *sc = comcd.cd_devs[COMUNIT(tp->t_dev)]; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; + bus_io_handle_t ioh = sc->sc_ioh; int s; s = spltty(); @@ -854,14 +955,14 @@ comstart(tp) if (!ISSET(sc->sc_ier, IER_ETXRDY)) { SET(sc->sc_ier, IER_ETXRDY); - outb(iobase + com_ier, sc->sc_ier); + bus_io_write_1(bc, ioh, com_ier, sc->sc_ier); } #ifdef COM_HAYESP if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) { u_char buffer[1024], *cp = buffer; int n = q_to_b(&tp->t_outq, cp, sizeof buffer); do - outb(iobase + com_data, *cp++); + bus_io_write_1(bc, ioh, com_data, *cp++); while (--n); } else @@ -870,17 +971,17 @@ comstart(tp) u_char buffer[16], *cp = buffer; int n = q_to_b(&tp->t_outq, cp, sizeof buffer); do { - outb(iobase + com_data, *cp++); + bus_io_write_1(bc, ioh, com_data, *cp++); } while (--n); } else - outb(iobase + com_data, getc(&tp->t_outq)); + bus_io_write_1(bc, ioh, com_data, getc(&tp->t_outq)); out: splx(s); return; stopped: if (ISSET(sc->sc_ier, IER_ETXRDY)) { CLR(sc->sc_ier, IER_ETXRDY); - outb(iobase + com_ier, sc->sc_ier); + bus_io_write_1(bc, ioh, com_ier, sc->sc_ier); } splx(s); } @@ -980,7 +1081,8 @@ compoll(arg) !ISSET(sc->sc_mcr, MCR_RTS)) { /* XXX */ SET(sc->sc_mcr, MCR_RTS); - outb(sc->sc_iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(sc->sc_bc, sc->sc_ioh, com_mcr, + sc->sc_mcr); } splx(s); @@ -1007,7 +1109,8 @@ comintr(arg) void *arg; { struct com_softc *sc = arg; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; + bus_io_handle_t ioh = sc->sc_ioh; struct tty *tp; u_char lsr, data, msr, delta; #ifdef COM_DEBUG @@ -1019,10 +1122,10 @@ comintr(arg) #ifdef COM_DEBUG n = 0; - if (ISSET(iter[n].iir = inb(iobase + com_iir), IIR_NOPEND)) + if (ISSET(iter[n].iir = bus_io_read_1(bc, ioh, com_iir), IIR_NOPEND)) return (0); #else - if (ISSET(inb(iobase + com_iir), IIR_NOPEND)) + if (ISSET(bus_io_read_1(bc, ioh, com_iir), IIR_NOPEND)) return (0); #endif @@ -1032,14 +1135,14 @@ comintr(arg) #ifdef COM_DEBUG iter[n].lsr = #endif - lsr = inb(iobase + com_lsr); + lsr = bus_io_read_1(bc, ioh, com_lsr); if (ISSET(lsr, LSR_RXRDY)) { register u_char *p = sc->sc_ibufp; comevents = 1; do { - data = inb(iobase + com_data); + data = bus_io_read_1(bc, ioh, com_data); if (ISSET(lsr, LSR_BI)) { #ifdef notdef printf("break %02x %02x %02x %02x\n", @@ -1047,7 +1150,8 @@ comintr(arg) sc->sc_dtr); #endif #ifdef DDB - if (sc->sc_dev.dv_unit == comconsole) { + if (ISSET(sc->sc_hwflags, + COM_HW_CONSOLE)) { Debugger(); goto next; } @@ -1064,8 +1168,8 @@ comintr(arg) ISSET(tp->t_cflag, CRTSCTS)) { /* XXX */ CLR(sc->sc_mcr, MCR_RTS); - outb(iobase + com_mcr, - sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, + sc->sc_mcr); } } next: @@ -1074,7 +1178,7 @@ comintr(arg) goto ohfudge; iter[n].lsr = #endif - lsr = inb(iobase + com_lsr); + lsr = bus_io_read_1(bc, ioh, com_lsr); } while (ISSET(lsr, LSR_RXRDY)); sc->sc_ibufp = p; @@ -1087,7 +1191,7 @@ comintr(arg) #ifdef COM_DEBUG iter[n].msr = #endif - msr = inb(iobase + com_msr); + msr = bus_io_read_1(bc, ioh, com_msr); if (msr != sc->sc_msr) { delta = msr ^ sc->sc_msr; @@ -1096,7 +1200,7 @@ comintr(arg) !ISSET(sc->sc_swflags, COM_SW_SOFTCAR) && (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD)) == 0) { CLR(sc->sc_mcr, sc->sc_dtr); - outb(iobase + com_mcr, sc->sc_mcr); + bus_io_write_1(bc, ioh, com_mcr, sc->sc_mcr); } if (ISSET(delta & msr, MSR_CTS) && ISSET(tp->t_cflag, CRTSCTS)) { @@ -1115,10 +1219,10 @@ comintr(arg) #ifdef COM_DEBUG if (++n >= 32) goto ohfudge; - if (ISSET(iter[n].iir = inb(iobase + com_iir), IIR_NOPEND)) + if (ISSET(iter[n].iir = bus_io_read_1(bc, ioh, com_iir), IIR_NOPEND)) return (1); #else - if (ISSET(inb(iobase + com_iir), IIR_NOPEND)) + if (ISSET(bus_io_read_1(bc, ioh, com_iir), IIR_NOPEND)) return (1); #endif } @@ -1147,8 +1251,21 @@ void comcnprobe(cp) struct consdev *cp; { + bus_chipset_tag_t bc; + bus_io_handle_t ioh; + int found; - if (!comprobe1(CONADDR)) { +#if 0 + XXX NEEDS TO BE FIXED XXX + bc = ???; +#endif + if (bus_io_map(bc, CONADDR, COM_NPORTS, &ioh)) { + cp->cn_pri = CN_DEAD; + return; + } + found = comprobe1(bc, ioh, CONADDR); + bus_io_unmap(bc, ioh, COM_NPORTS); + if (!found) { cp->cn_pri = CN_DEAD; return; } @@ -1172,26 +1289,34 @@ comcninit(cp) struct consdev *cp; { - cominit(CONUNIT, comdefaultrate); - comconsole = CONUNIT; +#if 0 + XXX NEEDS TO BE FIXED XXX + comconsbc = ???; +#endif + if (bus_io_map(comconsbc, CONADDR, COM_NPORTS, &comconsioh)) + panic("comcninit: mapping failed"); + + cominit(comconsbc, comconsioh, comdefaultrate); + comconsaddr = CONADDR; comconsinit = 0; } -cominit(unit, rate) - int unit, rate; +cominit(bc, ioh, rate) + bus_chipset_tag_t bc; + bus_io_handle_t ioh; + int rate; { int s = splhigh(); - int iobase = CONADDR; u_char stat; - outb(iobase + com_lcr, LCR_DLAB); + bus_io_write_1(bc, ioh, com_lcr, LCR_DLAB); rate = comspeed(comdefaultrate); - outb(iobase + com_dlbl, rate); - outb(iobase + com_dlbh, rate >> 8); - outb(iobase + com_lcr, LCR_8BITS); - outb(iobase + com_ier, IER_ERXRDY | IER_ETXRDY); - outb(iobase + com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_4); - stat = inb(iobase + com_iir); + bus_io_write_1(bc, ioh, com_dlbl, rate); + bus_io_write_1(bc, ioh, com_dlbh, rate >> 8); + bus_io_write_1(bc, ioh, com_lcr, LCR_8BITS); + bus_io_write_1(bc, ioh, com_ier, IER_ERXRDY | IER_ETXRDY); + bus_io_write_1(bc, ioh, com_fifo, FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_4); + stat = bus_io_read_1(bc, ioh, com_iir); splx(s); } @@ -1199,13 +1324,14 @@ comcngetc(dev) dev_t dev; { int s = splhigh(); - int iobase = CONADDR; + bus_chipset_tag_t bc = comconsbc; + bus_io_handle_t ioh = comconsioh; u_char stat, c; - while (!ISSET(stat = inb(iobase + com_lsr), LSR_RXRDY)) + while (!ISSET(stat = bus_io_read_1(bc, ioh, com_lsr), LSR_RXRDY)) ; - c = inb(iobase + com_data); - stat = inb(iobase + com_iir); + c = bus_io_read_1(bc, ioh, com_data); + stat = bus_io_read_1(bc, ioh, com_iir); splx(s); return c; } @@ -1219,7 +1345,8 @@ comcnputc(dev, c) int c; { int s = splhigh(); - int iobase = CONADDR; + bus_chipset_tag_t bc = comconsbc; + bus_io_handle_t ioh = comconsioh; u_char stat; register int timo; @@ -1227,20 +1354,20 @@ comcnputc(dev, c) if (dev != kgdb_dev) #endif if (comconsinit == 0) { - (void) cominit(COMUNIT(dev), comdefaultrate); + (void) cominit(bc, ioh, comdefaultrate); comconsinit = 1; } /* wait for any pending transmission to finish */ timo = 50000; - while (!ISSET(stat = inb(iobase + com_lsr), LSR_TXRDY) && --timo) + while (!ISSET(stat = bus_io_read_1(bc, ioh, com_lsr), LSR_TXRDY) && --timo) ; - outb(iobase + com_data, c); + bus_io_write_1(bc, ioh, com_data, c); /* wait for this transmission to complete */ timo = 1500000; - while (!ISSET(stat = inb(iobase + com_lsr), LSR_TXRDY) && --timo) + while (!ISSET(stat = bus_io_read_1(bc, ioh, com_lsr), LSR_TXRDY) && --timo) ; /* clear any interrupts generated by this transmission */ - stat = inb(iobase + com_iir); + stat = bus_io_read_1(bc, ioh, com_iir); splx(s); } diff --git a/sys/dev/isa/comvar.h b/sys/dev/isa/comvar.h index 7871165eba55..b86f7af1861f 100644 --- a/sys/dev/isa/comvar.h +++ b/sys/dev/isa/comvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: comvar.h,v 1.2 1996/03/09 23:37:14 cgd Exp $ */ +/* $NetBSD: comvar.h,v 1.3 1996/03/10 09:01:26 cgd Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. @@ -32,6 +32,16 @@ struct commulti_attach_args { int ca_slave; /* slave number */ + + bus_chipset_tag_t ca_bc; + bus_io_handle_t ca_ioh; + int ca_iobase; + int ca_noien; }; -int comprobe1 __P((int)); +int comprobe1 __P((bus_chipset_tag_t, bus_io_handle_t, int)); + +extern int comconsaddr; +extern int comconsattached; +extern bus_chipset_tag_t comconsbc; +extern bus_io_handle_t comconsioh; diff --git a/sys/dev/isa/rtfps.c b/sys/dev/isa/rtfps.c index aa8d9690289b..45e784cdc478 100644 --- a/sys/dev/isa/rtfps.c +++ b/sys/dev/isa/rtfps.c @@ -1,6 +1,7 @@ -/* $NetBSD: rtfps.c,v 1.16 1996/03/09 01:04:01 cgd Exp $ */ +/* $NetBSD: rtfps.c,v 1.17 1996/03/10 09:01:28 cgd Exp $ */ /* + * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. * Copyright (c) 1995 Charles Hannum. All rights reserved. * * This code is derived from public-domain software written by @@ -35,7 +36,7 @@ #include #include -#include +#include #include #include @@ -47,10 +48,14 @@ struct rtfps_softc { struct device sc_dev; void *sc_ih; + bus_chipset_tag_t sc_bc; int sc_iobase; int sc_irqport; + bus_io_handle_t sc_irqioh; + int sc_alive; /* mask of slave units attached */ void *sc_slaves[NSLAVES]; /* com device unit numbers */ + bus_io_handle_t sc_slaveioh[NSLAVES]; }; int rtfpsprobe(); @@ -67,40 +72,62 @@ rtfpsprobe(parent, self, aux) void *aux; { struct isa_attach_args *ia = aux; + int iobase = ia->ia_iobase; + bus_chipset_tag_t bc = ia->ia_bc; + bus_io_handle_t ioh; + int i, rv = 1; /* * Do the normal com probe for the first UART and assume - * its presence means there is a multiport board there. + * its presence, and the ability to map the other UARTS, + * means there is a multiport board there. * XXX Needs more robustness. */ - ia->ia_iosize = NSLAVES * COM_NPORTS; - return (comprobe1(ia->ia_iobase)); + + /* if the first port is in use as console, then it. */ + if (iobase == comconsaddr && !comconsattached) + goto checkmappings; + + if (bus_io_map(bc, iobase, COM_NPORTS, &ioh)) { + rv = 0; + goto out; + } + rv = comprobe1(bc, ioh, iobase); + bus_io_unmap(bc, ioh, COM_NPORTS); + if (rv == 0) + goto out; + +checkmappings: + for (i = 1; i < NSLAVES; i++) { + iobase += COM_NPORTS; + + if (iobase == comconsaddr && !comconsattached) + continue; + + if (bus_io_map(bc, iobase, COM_NPORTS, &ioh)) { + rv = 0; + goto out; + } + bus_io_unmap(bc, ioh, COM_NPORTS); + } + +out: + if (rv) + ia->ia_iosize = NSLAVES * COM_NPORTS; + return (rv); } int -rtfpssubmatch(parent, match, aux) - struct device *parent; - void *match, *aux; -{ - struct rtfps_softc *sc = (void *)parent; - struct cfdata *cf = match; - struct isa_attach_args *ia = aux; - struct commulti_attach_args *ca = ia->ia_aux; - - if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != ca->ca_slave) - return (0); - return ((*cf->cf_driver->cd_match)(parent, match, ia)); -} - -int -rtfpsprint(aux, rtfps) +rtfpsprint(aux, pnp) void *aux; - char *rtfps; + char *pnp; { - struct isa_attach_args *ia = aux; - struct commulti_attach_args *ca = ia->ia_aux; + struct commulti_attach_args *ca = aux; + if (pnp) + printf("com at %s", pnp); printf(" slave %d", ca->ca_slave); + return (UNCONF); } void @@ -111,39 +138,51 @@ rtfpsattach(parent, self, aux) struct rtfps_softc *sc = (void *)self; struct isa_attach_args *ia = aux; struct commulti_attach_args ca; - struct isa_attach_args isa; static int irqport[] = { IOBASEUNK, IOBASEUNK, IOBASEUNK, IOBASEUNK, IOBASEUNK, IOBASEUNK, IOBASEUNK, IOBASEUNK, IOBASEUNK, 0x2f2, 0x6f2, 0x6f3, IOBASEUNK, IOBASEUNK, IOBASEUNK, IOBASEUNK }; - int subunit; + int i, subunit; + sc->sc_bc = ia->ia_bc; sc->sc_iobase = ia->ia_iobase; if (ia->ia_irq >= 16 || irqport[ia->ia_irq] == IOBASEUNK) panic("rtfpsattach: invalid irq"); sc->sc_irqport = irqport[ia->ia_irq]; - outb(sc->sc_irqport, 0); + for (i = 0; i < NSLAVES; i++) + if (bus_io_map(bc, sc->sc_iobase + i * COM_NPORTS, COM_NPORTS, + &sc->sc_slaveioh[i])) + panic("rtfpsattach: couldn't map slave %d", i); + if (bus_io_map(bc, sc->sc_irqport, 1, &sc->sc_irqioh)) + panic("rtfpsattach: couldn't map irq port at 0x%x\n", + sc->sc_irqport); + + bus_io_write_1(bc, sc->sc_irqioh, 0, 0); printf("\n"); - isa.ia_aux = &ca; - for (ca.ca_slave = 0; ca.ca_slave < NSLAVES; ca.ca_slave++) { - struct cfdata *cf; - isa.ia_iobase = sc->sc_iobase + COM_NPORTS * ca.ca_slave; - isa.ia_iosize = 0x666; - isa.ia_irq = IRQUNK; - isa.ia_drq = DRQUNK; - isa.ia_msize = 0; - if ((cf = config_search(rtfpssubmatch, self, &isa)) != 0) { - subunit = cf->cf_unit; /* can change if unit == * */ - config_attach(self, cf, &isa, rtfpsprint); - sc->sc_slaves[ca.ca_slave] = - cf->cf_driver->cd_devs[subunit]; - sc->sc_alive |= 1 << ca.ca_slave; + for (i = 0; i < NSLAVES; i++) { + struct cfdata *match; + + ca.ca_slave = i; + ca.ca_bc = sc->sc_bc; + ca.ca_ioh = sc->sc_slaveioh[i]; + ca.ca_iobase = sc->sc_iobase + i * COM_NPORTS; + ca.ca_noien = 0; + + /* mimic config_found(), but with special functionality */ + if ((match = config_search(NULL, self, &ca)) != NULL) { + subunit = match->cf_unit; /* can change if unit == * */ + config_attach(self, match, &ca, rtfpsprint); + sc->sc_slaves[i] = match->cf_driver->cd_devs[subunit]; + sc->sc_alive |= 1 << i; + } else { + rtfpsprint(&ca, self->dv_xname); + printf(" not configured\n"); } } @@ -156,10 +195,10 @@ rtfpsintr(arg) void *arg; { struct rtfps_softc *sc = arg; - int iobase = sc->sc_iobase; + bus_chipset_tag_t bc = sc->sc_bc; int alive = sc->sc_alive; - outb(sc->sc_irqport, 0); + bus_io_write_1(bc, sc->sc_irqioh, 0, 0); #define TRY(n) \ if (alive & (1 << (n))) \