convert these to use new <machine/bus.h> 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.)
This commit is contained in:
parent
ab5476b242
commit
85286bff2f
407
sys/dev/ic/com.c
407
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 <sys/device.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/isa/comreg.h>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/pio.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/isa/comreg.h>
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/pio.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/isa/comreg.h>
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 <sys/device.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/isa/comreg.h>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/pio.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#include <dev/isa/comreg.h>
|
||||
|
@ -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))) \
|
||||
|
|
Loading…
Reference in New Issue