summaryrefslogtreecommitdiffstats
path: root/sys/dev/sio/sio.c
diff options
context:
space:
mode:
authornyan <nyan@FreeBSD.org>2000-05-12 12:37:28 +0000
committernyan <nyan@FreeBSD.org>2000-05-12 12:37:28 +0000
commit0dcfdccf0d800e75589e44ae552bb33e440dcc5a (patch)
treec98df9cccb370045297dae4b01af1efe848a839f /sys/dev/sio/sio.c
parentf3a1d3193848c020f8f34ed2f115417de5056616 (diff)
downloadFreeBSD-src-0dcfdccf0d800e75589e44ae552bb33e440dcc5a.zip
FreeBSD-src-0dcfdccf0d800e75589e44ae552bb33e440dcc5a.tar.gz
Use bus_space stuff except where it needs high performance.
Reviewed by: bde
Diffstat (limited to 'sys/dev/sio/sio.c')
-rw-r--r--sys/dev/sio/sio.c161
1 files changed, 82 insertions, 79 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c
index e6aeeb1..524828c 100644
--- a/sys/dev/sio/sio.c
+++ b/sys/dev/sio/sio.c
@@ -67,6 +67,7 @@
#include <sys/syslog.h>
#include <sys/sysctl.h>
#include <sys/bus.h>
+#include <machine/bus_pio.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <sys/timetc.h>
@@ -138,6 +139,11 @@
#define com_scr 7 /* scratch register for 16450-16550 (R/W) */
+#define sio_getreg(com, off) \
+ (bus_space_read_1((com)->bst, (com)->bsh, (off)))
+#define sio_setreg(com, off, value) \
+ (bus_space_write_1((com)->bst, (com)->bsh, (off), (value)))
+
/*
* com state bits.
* (CS_BUSY | CS_TTGO) and (CS_BUSY | CS_TTGO | CS_ODEVREADY) must be higher
@@ -236,12 +242,14 @@ struct com_s {
struct lbq obufq; /* head of queue of output buffers */
struct lbq obufs[2]; /* output buffers */
+ bus_space_tag_t bst;
+ bus_space_handle_t bsh;
+
Port_t data_port; /* i/o ports */
#ifdef COM_ESP
Port_t esp_port;
#endif
Port_t int_id_port;
- Port_t iobase;
Port_t modem_ctl_port;
Port_t line_status_port;
Port_t modem_status_port;
@@ -542,10 +550,6 @@ sio_pccard_detach(dev)
device_printf(dev, "NULL com in siounload\n");
return (0);
}
- if (com->iobase == 0) {
- device_printf(dev, "already unloaded!\n");
- return (0);
- }
com->gone = 1;
if (com->irqres) {
bus_teardown_intr(dev, com->irqres, com->cookie);
@@ -731,6 +735,7 @@ sioprobe(dev, xrid)
static bool_t already_init;
device_t xdev;
#endif
+ struct com_s *com;
bool_t failures[10];
int fn;
device_t idev;
@@ -750,6 +755,10 @@ sioprobe(dev, xrid)
if (!port)
return (ENXIO);
+ com = device_get_softc(dev);
+ com->bst = rman_get_bustag(port);
+ com->bsh = rman_get_bushandle(port);
+
#if 0
/*
* XXX this is broken - when we are first called, there are no
@@ -851,10 +860,10 @@ sioprobe(dev, xrid)
if (iobase == siocniobase)
DELAY((16 + 1) * 1000000 / (comdefaultrate / 10));
else {
- outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
- outb(iobase + com_dlbl, COMBRD(SIO_TEST_SPEED) & 0xff);
- outb(iobase + com_dlbh, (u_int) COMBRD(SIO_TEST_SPEED) >> 8);
- outb(iobase + com_cfcr, CFCR_8BITS);
+ sio_setreg(com, com_cfcr, CFCR_DLAB | CFCR_8BITS);
+ sio_setreg(com, com_dlbl, COMBRD(SIO_TEST_SPEED) & 0xff);
+ sio_setreg(com, com_dlbh, (u_int) COMBRD(SIO_TEST_SPEED) >> 8);
+ sio_setreg(com, com_cfcr, CFCR_8BITS);
DELAY((16 + 1) * 1000000 / (SIO_TEST_SPEED / 10));
}
@@ -864,8 +873,8 @@ sioprobe(dev, xrid)
* guarantee an edge trigger if an interrupt can be generated.
*/
/* EXTRA DELAY? */
- outb(iobase + com_mcr, mcr_image);
- outb(iobase + com_ier, 0);
+ sio_setreg(com, com_mcr, mcr_image);
+ sio_setreg(com, com_ier, 0);
DELAY(1000); /* XXX */
irqmap[0] = isa_irq_pending();
@@ -874,7 +883,7 @@ sioprobe(dev, xrid)
* without annoying any external device.
*/
/* EXTRA DELAY? */
- outb(iobase + com_mcr, mcr_image | MCR_LOOPBACK);
+ sio_setreg(com, com_mcr, mcr_image | MCR_LOOPBACK);
/*
* Attempt to generate an output interrupt. On 8250's, setting
@@ -884,7 +893,7 @@ sioprobe(dev, xrid)
* current setting. On 16550A's, setting IER_ETXRDY only
* generates an interrupt when IER_ETXRDY is not already set.
*/
- outb(iobase + com_ier, IER_ETXRDY);
+ sio_setreg(com, com_ier, IER_ETXRDY);
/*
* On some 16x50 incompatibles, setting IER_ETXRDY doesn't generate
@@ -892,7 +901,7 @@ sioprobe(dev, xrid)
* output. Loopback may be broken on the same incompatibles but
* it's unlikely to do more than allow the null byte out.
*/
- outb(iobase + com_data, 0);
+ sio_setreg(com, com_data, 0);
DELAY((1 + 2) * 1000000 / (SIO_TEST_SPEED / 10));
/*
@@ -903,7 +912,7 @@ sioprobe(dev, xrid)
* are disabled.
*/
/* EXTRA DELAY? */
- outb(iobase + com_mcr, mcr_image);
+ sio_setreg(com, com_mcr, mcr_image);
/*
* Some pcmcia cards have the "TXRDY bug", so we check everyone
@@ -913,14 +922,14 @@ sioprobe(dev, xrid)
/* Reading IIR register twice */
for (fn = 0; fn < 2; fn ++) {
DELAY(10000);
- failures[6] = inb(iobase + com_iir);
+ failures[6] = sio_getreg(com, com_iir);
}
/* Check IIR_TXRDY clear ? */
result = 0;
if (failures[6] & IIR_TXRDY) {
/* Nop, Double check with clearing IER */
- outb(iobase + com_ier, 0);
- if (inb(iobase + com_iir) & IIR_NOPEND) {
+ sio_setreg(com, com_ier, 0);
+ if (sio_getreg(com, com_iir) & IIR_NOPEND) {
/* Ok. we're familia this gang */
SET_FLAG(dev, COM_C_IIR_TXRDYBUG);
} else {
@@ -931,7 +940,7 @@ sioprobe(dev, xrid)
/* OK. this is well-known guys */
CLR_FLAG(dev, COM_C_IIR_TXRDYBUG);
}
- outb(iobase + com_cfcr, CFCR_8BITS);
+ sio_setreg(com, com_cfcr, CFCR_8BITS);
enable_intr();
bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
return (iobase == siocniobase ? 0 : result);
@@ -946,15 +955,15 @@ sioprobe(dev, xrid)
* o the interrupt goes away when the IIR in the UART is read.
*/
/* EXTRA DELAY? */
- failures[0] = inb(iobase + com_cfcr) - CFCR_8BITS;
- failures[1] = inb(iobase + com_ier) - IER_ETXRDY;
- failures[2] = inb(iobase + com_mcr) - mcr_image;
+ failures[0] = sio_getreg(com, com_cfcr) - CFCR_8BITS;
+ failures[1] = sio_getreg(com, com_ier) - IER_ETXRDY;
+ failures[2] = sio_getreg(com, com_mcr) - mcr_image;
DELAY(10000); /* Some internal modems need this time */
irqmap[1] = isa_irq_pending();
- failures[4] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_TXRDY;
+ failures[4] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_TXRDY;
DELAY(1000); /* XXX */
irqmap[2] = isa_irq_pending();
- failures[6] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND;
+ failures[6] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND;
/*
* Turn off all device interrupts and check that they go off properly.
@@ -965,12 +974,12 @@ sioprobe(dev, xrid)
* (On the system that this was first tested on, the input floats high
* and gives a (masked) interrupt as soon as the gate is closed.)
*/
- outb(iobase + com_ier, 0);
- outb(iobase + com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */
- failures[7] = inb(iobase + com_ier);
+ sio_setreg(com, com_ier, 0);
+ sio_setreg(com, com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */
+ failures[7] = sio_getreg(com, com_ier);
DELAY(1000); /* XXX */
irqmap[3] = isa_irq_pending();
- failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND;
+ failures[9] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND;
enable_intr();
@@ -988,7 +997,7 @@ sioprobe(dev, xrid)
result = 0;
for (fn = 0; fn < sizeof failures; ++fn)
if (failures[fn]) {
- outb(iobase + com_mcr, 0);
+ sio_setreg(com, com_mcr, 0);
result = ENXIO;
if (bootverbose) {
printf("sio%d: probe failed test(s):",
@@ -1034,7 +1043,7 @@ espattach(com, esp_port)
/*
* Bits 0,1 of dips say which COM port we are.
*/
- if (com->iobase == likely_com_ports[dips & 0x03])
+ if (rman_get_start(com->ioportres) == likely_com_ports[dips & 0x03])
printf(" : ESP");
else {
printf(" esp_port has com %d\n", dips & 0x03);
@@ -1120,6 +1129,8 @@ sioattach(dev, xrid)
bzero(com, sizeof *com);
com->unit = unit;
com->ioportres = port;
+ com->bst = rman_get_bustag(port);
+ com->bsh = rman_get_bushandle(port);
com->cfcr_image = CFCR_8BITS;
com->dtr_wait = 3 * hz;
com->loses_outints = COM_LOSESOUTINTS(flags) != 0;
@@ -1128,7 +1139,6 @@ sioattach(dev, xrid)
com->obufs[0].l_head = com->obuf1;
com->obufs[1].l_head = com->obuf2;
- com->iobase = iobase;
com->data_port = iobase + com_data;
com->int_id_port = iobase + com_iir;
com->modem_ctl_port = iobase + com_mcr;
@@ -1186,18 +1196,18 @@ sioattach(dev, xrid)
u_char scr1;
u_char scr2;
- scr = inb(iobase + com_scr);
- outb(iobase + com_scr, 0xa5);
- scr1 = inb(iobase + com_scr);
- outb(iobase + com_scr, 0x5a);
- scr2 = inb(iobase + com_scr);
- outb(iobase + com_scr, scr);
+ scr = sio_getreg(com, com_scr);
+ sio_setreg(com, com_scr, 0xa5);
+ scr1 = sio_getreg(com, com_scr);
+ sio_setreg(com, com_scr, 0x5a);
+ scr2 = sio_getreg(com, com_scr);
+ sio_setreg(com, com_scr, scr);
if (scr1 != 0xa5 || scr2 != 0x5a) {
printf(" 8250");
goto determined_type;
}
}
- outb(iobase + com_fifo, FIFO_ENABLE | FIFO_RX_HIGH);
+ sio_setreg(com, com_fifo, FIFO_ENABLE | FIFO_RX_HIGH);
DELAY(100);
com->st16650a = 0;
switch (inb(com->int_id_port) & IIR_FIFO_MASK) {
@@ -1267,7 +1277,7 @@ sioattach(dev, xrid)
outb(com->esp_port + ESP_CMD2, LOBYTE(512));
}
#endif /* COM_ESP */
- outb(iobase + com_fifo, 0);
+ sio_setreg(com, com_fifo, 0);
determined_type: ;
#ifdef COM_MULTIPORT
@@ -1341,7 +1351,6 @@ sioopen(dev, flag, mode, p)
{
struct com_s *com;
int error;
- Port_t iobase;
int mynor;
int s;
struct tty *tp;
@@ -1424,7 +1433,6 @@ open_top:
/*
* XXX we should goto open_top if comparam() slept.
*/
- iobase = com->iobase;
if (com->hasfifo) {
/*
* (Re)enable and drain fifos.
@@ -1438,9 +1446,9 @@ open_top:
* input.
*/
while (TRUE) {
- outb(iobase + com_fifo,
- FIFO_RCV_RST | FIFO_XMT_RST
- | com->fifo_image);
+ sio_setreg(com, com_fifo,
+ FIFO_RCV_RST | FIFO_XMT_RST
+ | com->fifo_image);
/*
* XXX the delays are for superstitious
* historical reasons. It must be less than
@@ -1455,7 +1463,7 @@ open_top:
DELAY(50);
if (!(inb(com->line_status_port) & LSR_RXRDY))
break;
- outb(iobase + com_fifo, 0);
+ sio_setreg(com, com_fifo, 0);
DELAY(50);
(void) inb(com->data_port);
}
@@ -1558,22 +1566,20 @@ static void
comhardclose(com)
struct com_s *com;
{
- Port_t iobase;
int s;
struct tty *tp;
int unit;
unit = com->unit;
- iobase = com->iobase;
s = spltty();
com->poll = FALSE;
com->poll_output = FALSE;
com->do_timestamp = FALSE;
com->do_dcd_timestamp = FALSE;
com->pps.ppsparam.mode = 0;
- outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
+ sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
{
- outb(iobase + com_ier, 0);
+ sio_setreg(com, com_ier, 0);
tp = com->tp;
if (tp->t_cflag & HUPCL
/*
@@ -1600,7 +1606,7 @@ comhardclose(com)
* reboots. Some BIOSes fail to detect 16550s when the
* fifos are enabled.
*/
- outb(iobase + com_fifo, 0);
+ sio_setreg(com, com_fifo, 0);
}
com->active_out = FALSE;
wakeup(&com->active_out);
@@ -2021,7 +2027,6 @@ sioioctl(dev, cmd, data, flag, p)
{
struct com_s *com;
int error;
- Port_t iobase;
int mynor;
int s;
struct tty *tp;
@@ -2034,7 +2039,6 @@ sioioctl(dev, cmd, data, flag, p)
com = com_addr(MINOR_TO_UNIT(mynor));
if (com == NULL || com->gone)
return (ENODEV);
- iobase = com->iobase;
if (mynor & CONTROL_MASK) {
struct termios *ct;
@@ -2112,10 +2116,10 @@ sioioctl(dev, cmd, data, flag, p)
}
switch (cmd) {
case TIOCSBRK:
- outb(iobase + com_cfcr, com->cfcr_image |= CFCR_SBREAK);
+ sio_setreg(com, com_cfcr, com->cfcr_image |= CFCR_SBREAK);
break;
case TIOCCBRK:
- outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
+ sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
break;
case TIOCSDTR:
(void)commctl(com, TIOCM_DTR, DMBIS);
@@ -2252,7 +2256,6 @@ comparam(tp, t)
int divisor;
u_char dlbh;
u_char dlbl;
- Port_t iobase;
int s;
int unit;
@@ -2270,7 +2273,6 @@ comparam(tp, t)
com = com_addr(unit);
if (com == NULL)
return (ENODEV);
- iobase = com->iobase;
s = spltty();
if (divisor == 0)
(void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */
@@ -2319,7 +2321,7 @@ comparam(tp, t)
if (com->esp)
com->fifo_image |= FIFO_DMA_MODE;
#endif
- outb(iobase + com_fifo, com->fifo_image);
+ sio_setreg(com, com_fifo, com->fifo_image);
}
/*
@@ -2330,7 +2332,7 @@ comparam(tp, t)
(void) siosetwater(com, t->c_ispeed);
if (divisor != 0) {
- outb(iobase + com_cfcr, cfcr | CFCR_DLAB);
+ sio_setreg(com, com_cfcr, cfcr | CFCR_DLAB);
/*
* Only set the divisor registers if they would change,
* since on some 16550 incompatibles (UMC8669F), setting
@@ -2338,23 +2340,23 @@ comparam(tp, t)
* data stops arriving.
*/
dlbl = divisor & 0xFF;
- if (inb(iobase + com_dlbl) != dlbl)
- outb(iobase + com_dlbl, dlbl);
+ if (sio_getreg(com, com_dlbl) != dlbl)
+ sio_setreg(com, com_dlbl, dlbl);
dlbh = (u_int) divisor >> 8;
- if (inb(iobase + com_dlbh) != dlbh)
- outb(iobase + com_dlbh, dlbh);
+ if (sio_getreg(com, com_dlbh) != dlbh)
+ sio_setreg(com, com_dlbh, dlbh);
}
-
- outb(iobase + com_cfcr, com->cfcr_image = cfcr);
+ sio_setreg(com, com_cfcr, com->cfcr_image = cfcr);
if (!(tp->t_state & TS_TTSTOP))
com->state |= CS_TTGO;
if (cflag & CRTS_IFLOW) {
if (com->st16650a) {
- outb(iobase + com_cfcr, 0xbf);
- outb(iobase + com_fifo, inb(iobase + com_fifo) | 0x40);
+ sio_setreg(com, com_cfcr, 0xbf);
+ sio_setreg(com, com_fifo,
+ sio_getreg(com, com_fifo) | 0x40);
}
com->state |= CS_RTS_IFLOW;
/*
@@ -2371,8 +2373,9 @@ comparam(tp, t)
*/
outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
if (com->st16650a) {
- outb(iobase + com_cfcr, 0xbf);
- outb(iobase + com_fifo, inb(iobase + com_fifo) & ~0x40);
+ sio_setreg(com, com_cfcr, 0xbf);
+ sio_setreg(com, com_fifo,
+ sio_getreg(com, com_fifo) & ~0x40);
}
}
@@ -2389,19 +2392,19 @@ comparam(tp, t)
if (!(com->last_modem_status & MSR_CTS))
com->state &= ~CS_ODEVREADY;
if (com->st16650a) {
- outb(iobase + com_cfcr, 0xbf);
- outb(iobase + com_fifo, inb(iobase + com_fifo) | 0x80);
+ sio_setreg(com, com_cfcr, 0xbf);
+ sio_setreg(com, com_fifo,
+ sio_getreg(com, com_fifo) | 0x80);
}
} else {
if (com->st16650a) {
- outb(iobase + com_cfcr, 0xbf);
- outb(iobase + com_fifo, inb(iobase + com_fifo) & ~0x80);
+ sio_setreg(com, com_cfcr, 0xbf);
+ sio_setreg(com, com_fifo,
+ sio_getreg(com, com_fifo) & ~0x80);
}
}
-
- outb(iobase + com_cfcr, com->cfcr_image);
-
+ sio_setreg(com, com_cfcr, com->cfcr_image);
/* XXX shouldn't call functions while intrs are disabled. */
disc_optim(tp, t, com);
@@ -2596,8 +2599,8 @@ comstop(tp, rw)
/* XXX avoid h/w bug. */
if (!com->esp)
#endif
- outb(com->iobase + com_fifo,
- FIFO_XMT_RST | com->fifo_image);
+ sio_setreg(com, com_fifo,
+ FIFO_XMT_RST | com->fifo_image);
com->obufs[0].l_queued = FALSE;
com->obufs[1].l_queued = FALSE;
if (com->state & CS_ODONE)
@@ -2611,8 +2614,8 @@ comstop(tp, rw)
/* XXX avoid h/w bug. */
if (!com->esp)
#endif
- outb(com->iobase + com_fifo,
- FIFO_RCV_RST | com->fifo_image);
+ sio_setreg(com, com_fifo,
+ FIFO_RCV_RST | com->fifo_image);
com_events -= (com->iptr - com->ibuf);
com->iptr = com->ibuf;
}
OpenPOWER on IntegriCloud