summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2002-09-14 15:00:04 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2002-09-14 15:00:04 +0000
commitba7f64753be9b6947a6f7ced6881ff8514567111 (patch)
treef36e6570326246d8aeaa73d422ed1d03aeed0691
parente162a1d92ccb99d4d9189430745c97caa313f496 (diff)
Various fixes and cleanups in the cy driver.
Finally my "Cyclades Cyclom-8Y" works correctly. Cleanups: - no more stupid arrays, we have softc structs, use them. - no more global poll timeout that walks an array, timeouts are now cheap, one poll per softc. - sc_dev.dv_xname is the correct thing to print in diagnostic printfs. - don't have bus-specific code in the generic attach for @#%$! sake, it took 20 seconds to fix (I suspect that the workaround took much more time to write). - spltty, not splhigh. - use pci_mapreg_map, not pci_{io,mem}_find + bus_space_map. - use defines, not magic constants in a few places. - KNF in a few places (much more work needed). Now the interesting parts: - when handling the interrupt, don't just ignore it when the tty is not open. Read and discard the data. If we don't read it, the card will interrupt again and again and again and ... (inspired by NetBSD). - actually enable interrupts on PLX9050 - From FreeBSD: "Work around a PLX9050 bug that causes system lockup in certain systems" deraadt@ ok
-rw-r--r--sys/dev/ic/cy.c392
-rw-r--r--sys/dev/ic/cyreg.h9
-rw-r--r--sys/dev/isa/cy_isa.c30
-rw-r--r--sys/dev/pci/cy_pci.c136
4 files changed, 267 insertions, 300 deletions
diff --git a/sys/dev/ic/cy.c b/sys/dev/ic/cy.c
index 7adce063d89..9810023bb6b 100644
--- a/sys/dev/ic/cy.c
+++ b/sys/dev/ic/cy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cy.c,v 1.18 2002/09/09 00:05:21 art Exp $ */
+/* $OpenBSD: cy.c,v 1.19 2002/09/14 15:00:02 art Exp $ */
/*
* cy.c
@@ -57,8 +57,6 @@
#include <dev/ic/cyreg.h>
-void cy_attach(struct device *, struct device *, void *);
-int cy_probe_common(int, bus_space_tag_t, bus_space_handle_t, int);
int cy_intr(void *);
int cyparam(struct tty *, struct termios *);
void cystart(struct tty *);
@@ -72,25 +70,17 @@ struct cfdriver cy_cd = {
NULL, "cy", DV_TTY
};
-static int cy_nr_cd1400s[NCY];
-static int cy_bus_types[NCY];
-static bus_space_handle_t cy_card_memh[NCY];
-static int cy_open = 0;
-static int cy_events = 0;
-
-struct timeout cy_poll_to;
-
/*
* Common probe routine
+ *
+ * returns the number of chips found.
*/
int
-cy_probe_common(card, memt, memh, bustype)
- int card, bustype;
- bus_space_tag_t memt;
- bus_space_handle_t memh;
+cy_probe_common(bus_space_tag_t memt, bus_space_handle_t memh, int bustype)
{
int cy_chip, chip_offs;
u_char firmware_ver;
+ int nchips;
/* Cyclom card hardware reset */
bus_space_write_1(memt, memh, CY16_RESET<<bustype, 0);
@@ -101,7 +91,7 @@ cy_probe_common(card, memt, memh, bustype)
printf("cy: card reset done\n");
#endif
- cy_nr_cd1400s[card] = 0;
+ nchips = 0;
for (cy_chip = 0, chip_offs = 0;
cy_chip < CY_MAX_CD1400s;
@@ -114,8 +104,8 @@ cy_probe_common(card, memt, memh, bustype)
chip_offs -= (CY32_ADDR_FIX << bustype);
#ifdef CY_DEBUG
- printf("cy%d probe chip %d offset 0x%lx ... ",
- card, cy_chip, chip_offs);
+ printf("cy: probe chip %d offset 0x%lx ... ",
+ cy_chip, chip_offs);
#endif
/* wait until the chip is ready for command */
@@ -164,10 +154,10 @@ cy_probe_common(card, memt, memh, bustype)
break;
/* firmware version OK, CD1400 found */
- cy_nr_cd1400s[card]++;
+ nchips++;
}
- if (cy_nr_cd1400s[card] == 0) {
+ if (nchips == 0) {
#ifdef CY_DEBUG
printf("no CD1400s found\n");
#endif
@@ -175,45 +165,25 @@ cy_probe_common(card, memt, memh, bustype)
}
#ifdef CY_DEBUG
- printf("found %d CD1400s\n", cy_nr_cd1400s[card]);
+ printf("found %d CD1400s\n", nchips);
#endif
- cy_card_memh[card] = memh;
- cy_bus_types[card] = bustype;
-
- return (1);
+ return (nchips);
}
void
-cy_attach(parent, self, aux)
+cy_attach(parent, self)
struct device *parent, *self;
- void *aux;
{
int card, port, cy_chip, num_chips, cdu, chip_offs, cy_clock;
struct cy_softc *sc = (void *)self;
card = sc->sc_dev.dv_unit;
- num_chips = cy_nr_cd1400s[card];
+ num_chips = sc->sc_nr_cd1400s;
if (num_chips == 0)
return;
- sc->sc_bustype = cy_bus_types[card];
- sc->sc_memh = cy_card_memh[card];
- switch (sc->sc_bustype) {
-#if NCY_ISA > 0
- case CY_BUSTYPE_ISA:
- sc->sc_memt = ((struct isa_attach_args *)(aux))->ia_memt;
- break;
-#endif
-#if NCY_PCI > 0
- case CY_BUSTYPE_PCI:
- sc->sc_memt = ((struct pci_attach_args *)aux)->pa_memt;
- break;
-#endif
- }
-
- if (!timeout_initialized(&cy_poll_to))
- timeout_set(&cy_poll_to, cy_poll, NULL);
+ timeout_set(&sc->sc_poll_to, cy_poll, sc);
bzero(sc->sc_ports, sizeof(sc->sc_ports));
sc->sc_nports = num_chips * CD1400_NO_OF_CHANNELS;
@@ -262,24 +232,6 @@ cy_attach(parent, self, aux)
/* ensure an edge for the next interrupt */
bus_space_write_1(sc->sc_memt, sc->sc_memh,
CY_CLEAR_INTR<<sc->sc_bustype, 0);
-
- switch (sc->sc_bustype) {
-#if NCY_ISA > 0
- case CY_BUSTYPE_ISA:
- {
- struct isa_attach_args *ia = aux;
-
- sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq,
- IST_EDGE, IPL_TTY, cy_intr, sc, sc->sc_dev.dv_xname);
-
- if (sc->sc_ih == NULL)
- panic("cy: couldn't establish interrupt");
- }
- break;
-#endif /* NCY_ISA > 0 */
- case CY_BUSTYPE_PCI:
- break;
- }
}
/*
@@ -306,24 +258,24 @@ cyopen(dev, flag, mode, p)
struct tty *tp;
int s, error;
-#ifdef CY_DEBUG
- printf("cy%d open port %d flag 0x%x mode 0x%x\n",
- card, port, flag, mode);
-#endif
-
if (card >= cy_cd.cd_ndevs ||
(sc = cy_cd.cd_devs[card]) == NULL) {
return (ENXIO);
}
+#ifdef CY_DEBUG
+ printf("%s open port %d flag 0x%x mode 0x%x\n", sc->sc_dev.dv_xname,
+ port, flag, mode);
+#endif
+
cy = &sc->sc_ports[port];
s = spltty();
if (cy->cy_tty == NULL) {
if ((cy->cy_tty = ttymalloc()) == NULL) {
splx(s);
- printf("cy%d port %d open: can't allocate tty\n",
- card, port);
+ printf("%s port %d open: can't allocate tty\n",
+ sc->sc_dev.dv_xname, port);
return (ENOMEM);
}
}
@@ -359,8 +311,8 @@ cyopen(dev, flag, mode, p)
if (cy->cy_ibuf == NULL) {
cy->cy_ibuf = malloc(IBUF_SIZE, M_DEVBUF, M_NOWAIT);
if (cy->cy_ibuf == NULL) {
- printf("cy%d: (port %d) can't allocate input buffer\n",
- card, port);
+ printf("%s: (port %d) can't allocate input buffer\n",
+ sc->sc_dev.dv_xname, port);
splx(s);
return (ENOMEM);
}
@@ -380,11 +332,8 @@ cyopen(dev, flag, mode, p)
cy->cy_channel_control = 0;
- /* hmm... need spltty() here? */
- if (cy_open == 0) {
- cy_open = 1;
- timeout_add(&cy_poll_to, 1);
- }
+ if (!timeout_pending(&sc->sc_poll_to))
+ timeout_add(&sc->sc_poll_to, 1);
/* this sets parameters and raises DTR */
cyparam(tp, &tp->t_termios);
@@ -450,8 +399,8 @@ cyclose(dev, flag, mode, p)
int s;
#ifdef CY_DEBUG
- printf("cy%d close port %d, flag 0x%x, mode 0x%x\n",
- card, port, flag, mode);
+ printf("%s close port %d, flag 0x%x, mode 0x%x\n", sc->sc_dev.dv_xname,
+ port, flag, mode);
#endif
(*linesw[tp->t_line].l_close)(tp, flag);
@@ -492,8 +441,8 @@ cyread(dev, uio, flag)
struct tty *tp = cy->cy_tty;
#ifdef CY_DEBUG
- printf("cy%d read port %d uio 0x%x flag 0x%x\n",
- card, port, uio, flag);
+ printf("%s read port %d uio 0x%x flag 0x%x\n", sc->sc_dev.dv_xname,
+ port, uio, flag);
#endif
return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
@@ -515,8 +464,8 @@ cywrite(dev, uio, flag)
struct tty *tp = cy->cy_tty;
#ifdef CY_DEBUG
- printf("cy%d write port %d uio 0x%x flag 0x%x\n",
- card, port, uio, flag);
+ printf("%s write port %d uio 0x%x flag 0x%x\n", sc->sc_dev.dv_xname,
+ port, uio, flag);
#endif
return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
@@ -535,11 +484,6 @@ cytty(dev)
struct cy_port *cy = &sc->sc_ports[port];
struct tty *tp = cy->cy_tty;
-#ifdef CY_DEBUG
- printf("cy%d tty port %d tp 0x%x\n",
- card, port, tp);
-#endif
-
return (tp);
}
@@ -562,8 +506,8 @@ cyioctl(dev, cmd, data, flag, p)
int error;
#ifdef CY_DEBUG
- printf("cy%d port %d ioctl cmd 0x%x data 0x%x flag 0x%x\n",
- card, port, cmd, data, flag);
+ printf("%s port %d ioctl cmd 0x%x data 0x%x flag 0x%x\n",
+ sc->sc_dev.dv_xname, port, cmd, data, flag);
#endif
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
@@ -647,7 +591,7 @@ cystart(tp)
int s;
#ifdef CY_DEBUG
- printf("cy%d port %d start, tty 0x%x\n", card, port, tp);
+ printf("%s port %d start, tty 0x%x\n", sc->sc_dev.dv_xname, port, tp);
#endif
s = spltty();
@@ -692,8 +636,8 @@ cystop(tp, flag)
int s;
#ifdef CY_DEBUG
- printf("cy%d port %d stop tty 0x%x flag 0x%x\n",
- card, port, tp, flag);
+ printf("%s port %d stop tty 0x%x flag 0x%x\n", sc->sc_dev.dv_xname,
+ port, tp, flag);
#endif
s = spltty();
@@ -729,8 +673,8 @@ cyparam(tp, t)
int s, opt;
#ifdef CY_DEBUG
- printf("cy%d port %d param tty 0x%x termios 0x%x\n",
- card, port, tp, t);
+ printf("%s port %d param tty 0x%x termios 0x%x\n", sc->sc_dev.dv_xname,
+ port, tp, t);
printf("ispeed %d ospeed %d\n", t->c_ispeed, t->c_ospeed);
#endif
@@ -967,11 +911,10 @@ cy_modem_control(cy, bits, howto)
* This routine is common for multiple cards
*/
void
-cy_poll(arg)
- void *arg;
+cy_poll(void *arg)
{
int card, port;
- struct cy_softc *sc;
+ struct cy_softc *sc = arg;
struct cy_port *cy;
struct tty *tp;
static int counter = 0;
@@ -981,160 +924,155 @@ cy_poll(arg)
int s;
- s = splhigh();
+ s = spltty();
- if (cy_events == 0 && ++counter < 200) {
+ if (sc->sc_events == 0 && ++counter < 200) {
splx(s);
goto out;
}
- cy_events = 0;
+ sc->sc_events = 0;
splx(s);
- for (card = 0; card < cy_cd.cd_ndevs; card++) {
- sc = cy_cd.cd_devs[card];
- if (sc == NULL)
- continue;
-
#ifdef CY_DEBUG1
- sc->sc_poll_count1++;
- did_something = 0;
+ sc->sc_poll_count1++;
+ did_something = 0;
#endif
- for (port = 0; port < sc->sc_nports; port++) {
- cy = &sc->sc_ports[port];
- if ((tp = cy->cy_tty) == NULL || cy->cy_ibuf == NULL ||
- !ISSET(tp->t_state, TS_ISOPEN | TS_WOPEN))
- continue;
+ for (port = 0; port < sc->sc_nports; port++) {
+ cy = &sc->sc_ports[port];
+ if ((tp = cy->cy_tty) == NULL || cy->cy_ibuf == NULL ||
+ !ISSET(tp->t_state, TS_ISOPEN | TS_WOPEN))
+ continue;
- /*
- * handle received data
- */
- while (cy->cy_ibuf_rd_ptr != cy->cy_ibuf_wr_ptr) {
- u_char line_stat;
- int chr;
+ /*
+ * handle received data
+ */
+ while (cy->cy_ibuf_rd_ptr != cy->cy_ibuf_wr_ptr) {
+ u_char line_stat;
+ int chr;
- line_stat = cy->cy_ibuf_rd_ptr[0];
- chr = cy->cy_ibuf_rd_ptr[1];
+ line_stat = cy->cy_ibuf_rd_ptr[0];
+ chr = cy->cy_ibuf_rd_ptr[1];
- if (line_stat &
- (CD1400_RDSR_BREAK|CD1400_RDSR_FE))
- chr |= TTY_FE;
- if (line_stat & CD1400_RDSR_PE)
- chr |= TTY_PE;
+ if (line_stat &
+ (CD1400_RDSR_BREAK|CD1400_RDSR_FE))
+ chr |= TTY_FE;
+ if (line_stat & CD1400_RDSR_PE)
+ chr |= TTY_PE;
- /*
- * on an overrun error the data is treated as
- * good just as it should be.
- */
+ /*
+ * on an overrun error the data is treated as
+ * good just as it should be.
+ */
#ifdef CY_DEBUG
- printf("cy%d port %d ttyinput 0x%x\n",
- card, port, chr);
+ printf("%s port %d ttyinput 0x%x\n",
+ sc->sc_dev.dv_xname, port, chr);
#endif
- (*linesw[tp->t_line].l_rint)(chr, tp);
+ (*linesw[tp->t_line].l_rint)(chr, tp);
- s = splhigh(); /* really necessary? */
- if ((cy->cy_ibuf_rd_ptr += 2) ==
- cy->cy_ibuf_end)
- cy->cy_ibuf_rd_ptr = cy->cy_ibuf;
- splx(s);
+ s = spltty(); /* really necessary? */
+ if ((cy->cy_ibuf_rd_ptr += 2) ==
+ cy->cy_ibuf_end)
+ cy->cy_ibuf_rd_ptr = cy->cy_ibuf;
+ splx(s);
#ifdef CY_DEBUG1
- did_something = 1;
+ did_something = 1;
#endif
- }
+ }
#ifndef CY_HW_RTS
- /* If we don't have any received data in ibuf and
- * CRTSCTS is on and RTS is turned off, it is time
- * to turn RTS back on
- */
- if (ISSET(tp->t_cflag, CRTSCTS)) {
- /* we can't use cy_modem_control() here as it
- doesn't change RTS if RTSCTS is on */
- cd_write_reg(cy, CD1400_CAR,
- port & CD1400_CAR_CHAN);
+ /*
+ * If we don't have any received data in ibuf and
+ * CRTSCTS is on and RTS is turned off, it is time
+ * to turn RTS back on
+ */
+ if (ISSET(tp->t_cflag, CRTSCTS)) {
+ /* we can't use cy_modem_control() here as it
+ doesn't change RTS if RTSCTS is on */
+ cd_write_reg(cy, CD1400_CAR,
+ port & CD1400_CAR_CHAN);
- if ((cd_read_reg(cy,
- CD1400_MSVR1) & CD1400_MSVR1_RTS) == 0) {
- cd_write_reg(cy, CD1400_MSVR1,
- CD1400_MSVR1_RTS);
+ if ((cd_read_reg(cy,
+ CD1400_MSVR1) & CD1400_MSVR1_RTS) == 0) {
+ cd_write_reg(cy, CD1400_MSVR1,
+ CD1400_MSVR1_RTS);
#ifdef CY_DEBUG1
- did_something = 1;
+ did_something = 1;
#endif
- }
}
+ }
#endif /* CY_HW_RTS */
- /*
- * handle carrier changes
- */
- s = splhigh();
- if (ISSET(cy->cy_flags, CYF_CARRIER_CHANGED)) {
- int carrier;
+ /*
+ * handle carrier changes
+ */
+ s = spltty();
+ if (ISSET(cy->cy_flags, CYF_CARRIER_CHANGED)) {
+ int carrier;
- CLR(cy->cy_flags, CYF_CARRIER_CHANGED);
- splx(s);
+ CLR(cy->cy_flags, CYF_CARRIER_CHANGED);
+ splx(s);
- carrier = ((cy->cy_carrier_stat &
- CD1400_MSVR2_CD) != 0);
+ carrier = ((cy->cy_carrier_stat &
+ CD1400_MSVR2_CD) != 0);
#ifdef CY_DEBUG
- printf("cy_poll: carrier change "
- "(card %d, port %d, carrier %d)\n",
- card, port, carrier);
+ printf("cy_poll: carrier change "
+ "(card %d, port %d, carrier %d)\n",
+ card, port, carrier);
#endif
- if (CY_DIALIN(tp->t_dev) &&
- !(*linesw[tp->t_line].l_modem)(tp, carrier))
- cy_modem_control(cy, TIOCM_DTR, DMBIC);
+ if (CY_DIALIN(tp->t_dev) &&
+ !(*linesw[tp->t_line].l_modem)(tp, carrier))
+ cy_modem_control(cy, TIOCM_DTR, DMBIC);
#ifdef CY_DEBUG1
- did_something = 1;
+ did_something = 1;
#endif
- } else {
- splx(s);
- }
+ } else {
+ splx(s);
+ }
- s = splhigh();
- if (ISSET(cy->cy_flags, CYF_START)) {
- CLR(cy->cy_flags, CYF_START);
- splx(s);
+ s = spltty();
+ if (ISSET(cy->cy_flags, CYF_START)) {
+ CLR(cy->cy_flags, CYF_START);
+ splx(s);
- (*linesw[tp->t_line].l_start)(tp);
+ (*linesw[tp->t_line].l_start)(tp);
#ifdef CY_DEBUG1
- did_something = 1;
+ did_something = 1;
#endif
- } else {
- splx(s);
- }
+ } else {
+ splx(s);
+ }
- /* could move this to even upper level... */
- if (cy->cy_fifo_overruns) {
- cy->cy_fifo_overruns = 0;
- /* doesn't report overrun count,
- but shouldn't really matter */
- log(LOG_WARNING, "cy%d port %d fifo overrun\n",
- card, port);
- }
- if (cy->cy_ibuf_overruns) {
- cy->cy_ibuf_overruns = 0;
- log(LOG_WARNING, "cy%d port %d ibuf overrun\n",
- card, port);
- }
- } /* for(port...) */
+ /* could move this to even upper level... */
+ if (cy->cy_fifo_overruns) {
+ cy->cy_fifo_overruns = 0;
+ /* doesn't report overrun count,
+ but shouldn't really matter */
+ log(LOG_WARNING, "cy%d port %d fifo overrun\n",
+ card, port);
+ }
+ if (cy->cy_ibuf_overruns) {
+ cy->cy_ibuf_overruns = 0;
+ log(LOG_WARNING, "cy%d port %d ibuf overrun\n",
+ card, port);
+ }
+ } /* for(port...) */
#ifdef CY_DEBUG1
- if (did_something && counter >= 200)
- sc->sc_poll_count2++;
+ if (did_something && counter >= 200)
+ sc->sc_poll_count2++;
#endif
- } /* for(card...) */
counter = 0;
out:
- timeout_add(&cy_poll_to, 1);
+ timeout_add(&sc->sc_poll_to, 1);
}
/*
@@ -1146,15 +1084,14 @@ cy_intr(arg)
{
struct cy_softc *sc = arg;
struct cy_port *cy;
- int card = sc->sc_dev.dv_unit;
int cy_chip, stat;
- int int_serviced = 0;
+ int int_serviced = -1;
/*
* Check interrupt status of each CD1400 chip on this card
* (multiple cards cannot share the same interrupt)
*/
- for (cy_chip = 0; cy_chip < cy_nr_cd1400s[card]; cy_chip++) {
+ for (cy_chip = 0; cy_chip < sc->sc_nr_cd1400s; cy_chip++) {
stat = cd_read_reg_sc(sc, cy_chip, CD1400_SVRR);
if (stat == 0)
@@ -1177,20 +1114,21 @@ cy_intr(arg)
cy->cy_rx_int_count++;
#endif
- if (cy->cy_tty == NULL ||
- !ISSET(cy->cy_tty->t_state, TS_ISOPEN))
- goto end_rx_serv;
-
buf_p = cy->cy_ibuf_wr_ptr;
if (ISSET(serv_type, CD1400_RIVR_EXCEPTION)) {
line_stat = cd_read_reg(cy, CD1400_RDSR);
recv_data = cd_read_reg(cy, CD1400_RDSR);
+ if (cy->cy_tty == NULL ||
+ !ISSET(cy->cy_tty->t_state, TS_ISOPEN))
+ goto end_rx_serv;
+
#ifdef CY_DEBUG
- printf("cy%d port %d recv exception, "
+ printf("%s port %d recv exception, "
"line_stat 0x%x, char 0x%x\n",
- card, cy->cy_port_num, line_stat, recv_data);
+ sc->sc_dev.dv_xname, cy->cy_port_num,
+ line_stat, recv_data);
#endif
if (ISSET(line_stat, CD1400_RDSR_OE))
cy->cy_fifo_overruns++;
@@ -1206,12 +1144,22 @@ cy_intr(arg)
buf_p -= 2;
cy->cy_ibuf_overruns++;
}
- cy_events = 1;
+ sc->sc_events = 1;
} else { /* no exception, received data OK */
n_chars = cd_read_reg(cy, CD1400_RDCR);
+
+ /* If no tty or not open, discard data */
+ if (cy->cy_tty == NULL ||
+ !ISSET(cy->cy_tty->t_state, TS_ISOPEN)) {
+ while (n_chars--)
+ cd_read_reg(cy, CD1400_RDSR);
+ goto end_rx_serv;
+ }
+
#ifdef CY_DEBUG
- printf("cy%d port %d receive ok %d chars\n",
- card, cy->cy_port_num, n_chars);
+ printf("%s port %d receive ok %d chars\n",
+ sc->sc_dev.dv_xname, cy->cy_port_num,
+ n_chars);
#endif
while (n_chars--) {
*buf_p++ = 0; /* status: OK */
@@ -1227,7 +1175,7 @@ cy_intr(arg)
break;
}
}
- cy_events = 1;
+ sc->sc_events = 1;
}
cy->cy_ibuf_wr_ptr = buf_p;
@@ -1271,13 +1219,13 @@ cy_intr(arg)
modem_stat = cd_read_reg(cy, CD1400_MSVR2);
#ifdef CY_DEBUG
- printf("cy%d port %d modem line change, new stat 0x%x\n",
- card, cy->cy_port_num, modem_stat);
+ printf("%s port %d modem line change, new stat 0x%x\n",
+ sc->sc_dev.dv_xname, cy->cy_port_num, modem_stat);
#endif
if (ISSET((cy->cy_carrier_stat ^ modem_stat),
CD1400_MSVR2_CD)) {
SET(cy->cy_flags, CYF_CARRIER_CHANGED);
- cy_events = 1;
+ sc->sc_events = 1;
}
cy->cy_carrier_stat = modem_stat;
@@ -1304,8 +1252,8 @@ cy_intr(arg)
cy->cy_tx_int_count++;
#endif
#ifdef CY_DEBUG
- printf("cy%d port %d tx service\n",
- card, cy->cy_port_num);
+ printf("%s port %d tx service\n", sc->sc_dev.dv_xname,
+ cy->cy_port_num);
#endif
/* stop transmitting if no tty or CYF_STOP set */
@@ -1376,7 +1324,7 @@ txdone:
if (tp->t_outq.c_cc <= tp->t_lowat) {
SET(cy->cy_flags, CYF_START);
- cy_events = 1;
+ sc->sc_events = 1;
}
/* terminate service context */
@@ -1400,7 +1348,7 @@ cy_enable_transmitter(cy)
struct cy_port *cy;
{
int s;
- s = splhigh();
+ s = spltty();
cd_write_reg(cy, CD1400_CAR, cy->cy_port_num & CD1400_CAR_CHAN);
cd_write_reg(cy, CD1400_SRER, cd_read_reg(cy, CD1400_SRER)
| CD1400_SRER_TXRDY);
diff --git a/sys/dev/ic/cyreg.h b/sys/dev/ic/cyreg.h
index b2babd7a768..9a4263604c5 100644
--- a/sys/dev/ic/cyreg.h
+++ b/sys/dev/ic/cyreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cyreg.h,v 1.7 2002/03/14 01:26:54 millert Exp $ */
+/* $OpenBSD: cyreg.h,v 1.8 2002/09/14 15:00:02 art Exp $ */
/* $FreeBSD: cyreg.h,v 1.1 1995/07/05 12:15:51 bde Exp $ */
/*-
@@ -166,6 +166,8 @@ struct cy_port {
/* software state for one card */
struct cy_softc {
struct device sc_dev;
+ struct timeout sc_poll_to;
+ int sc_events;
void *sc_ih;
bus_space_tag_t sc_memt;
bus_space_handle_t sc_memh;
@@ -173,14 +175,15 @@ struct cy_softc {
int sc_nports; /* number of ports on this card */
int sc_cd1400_offs[CY_MAX_CD1400s];
struct cy_port sc_ports[CY_MAX_PORTS];
+ int sc_nr_cd1400s;
#ifdef CY_DEBUG1
int sc_poll_count1;
int sc_poll_count2;
#endif
};
-int cy_probe_common(int, bus_space_tag_t, bus_space_handle_t, int);
-void cy_attach(struct device *, struct device *, void *);
+int cy_probe_common(bus_space_tag_t, bus_space_handle_t, int);
+void cy_attach(struct device *, struct device *);
int cy_intr(void *);
#endif /* _DEV_IC_CYREG_H_ */
diff --git a/sys/dev/isa/cy_isa.c b/sys/dev/isa/cy_isa.c
index e151e8f2a88..ecb71f3c38c 100644
--- a/sys/dev/isa/cy_isa.c
+++ b/sys/dev/isa/cy_isa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cy_isa.c,v 1.7 2002/03/14 01:26:56 millert Exp $ */
+/* $OpenBSD: cy_isa.c,v 1.8 2002/09/14 15:00:03 art Exp $ */
/*
* cy_isa.c
@@ -37,6 +37,7 @@ cy_isa_probe(parent, match, aux)
struct isa_attach_args *ia = aux;
bus_space_tag_t memt;
bus_space_handle_t memh;
+ int ret;
if (ia->ia_irq == IRQUNK) {
printf("cy%d error: interrupt not defined\n", card);
@@ -47,10 +48,10 @@ cy_isa_probe(parent, match, aux)
if (bus_space_map(memt, ia->ia_maddr, 0x2000, 0, &memh) != 0)
return (0);
- if (cy_probe_common(card, memt, memh, CY_BUSTYPE_ISA) == 0) {
- bus_space_unmap(memt, memh, 0x2000);
+ ret = cy_probe_common(memt, memh, CY_BUSTYPE_ISA);
+ bus_space_unmap(memt, memh, 0x2000);
+ if (ret == 0)
return (0);
- }
ia->ia_iosize = 0;
ia->ia_msize = 0x2000;
@@ -62,5 +63,24 @@ cy_isa_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
- cy_attach(parent, self, aux);
+ struct cy_softc *sc = (struct cy_softc *)self;
+ struct isa_attach_args *ia = aux;
+
+ sc->sc_bustype = CY_BUSTYPE_ISA;
+ sc->sc_memt = ia->ia_memt;
+
+ if (bus_space_map(ia->ia_memt, ia->ia_maddr, 0x2000, 0,
+ &sc->sc_memh) != 0)
+ return;
+
+ sc->sc_nr_cd1400s = cy_probe_common(sc->sc_memt, sc->sc_memh,
+ CY_BUSTYPE_ISA);
+
+ cy_attach(parent, self);
+
+ sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq,
+ IST_EDGE, IPL_TTY, cy_intr, sc, sc->sc_dev.dv_xname);
+
+ if (sc->sc_ih == NULL)
+ panic("cy: couldn't establish interrupt");
}
diff --git a/sys/dev/pci/cy_pci.c b/sys/dev/pci/cy_pci.c
index e1ebbe84975..6e0fcf21ea9 100644
--- a/sys/dev/pci/cy_pci.c
+++ b/sys/dev/pci/cy_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cy_pci.c,v 1.9 2002/03/14 01:26:58 millert Exp $ */
+/* $OpenBSD: cy_pci.c,v 1.10 2002/09/14 15:00:03 art Exp $ */
/*
* cy_pci.c
@@ -25,10 +25,23 @@
int cy_pci_match(struct device *, void *, void *);
void cy_pci_attach(struct device *, struct device *, void *);
+struct cy_pci_softc {
+ struct cy_softc sc_cy; /* real softc */
+
+ bus_space_tag_t sc_iot; /* PLX i/o tag */
+ bus_space_handle_t sc_ioh; /* PLX i/o handle */
+};
+
struct cfattach cy_pci_ca = {
- sizeof(struct cy_softc), cy_pci_match, cy_pci_attach
+ sizeof(struct cy_pci_softc), cy_pci_match, cy_pci_attach
};
+#define CY_PLX_9050_ICS_IENABLE 0x040
+#define CY_PLX_9050_ICS_LOCAL_IENABLE 0x001
+#define CY_PLX_9050_ICS_LOCAL_IPOLARITY 0x002
+#define CY_PLX_9060_ICS_IENABLE 0x100
+#define CY_PLX_9060_ICS_LOCAL_IENABLE 0x800
+
int
cy_pci_match(parent, match, aux)
struct device *parent;
@@ -63,93 +76,76 @@ cy_pci_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
+ struct cy_pci_softc *psc = (struct cy_pci_softc *)self;
struct cy_softc *sc = (struct cy_softc *)self;
struct pci_attach_args *pa = aux;
pci_intr_handle_t ih;
- bus_space_tag_t memt;
- bus_space_handle_t memh;
- bus_addr_t memaddr;
- bus_size_t memsize;
- bus_space_tag_t iot;
- bus_space_handle_t ioh;
- bus_addr_t iobase;
- bus_size_t iosize;
+ pcireg_t memtype;
int plx_ver;
- int cacheable;
-
- memt = pa->pa_memt;
- iot = pa->pa_iot;
- if (pci_mem_find(pa->pa_pc, pa->pa_tag, 0x18,
- &memaddr, &memsize, &cacheable) != 0) {
- printf("%s: can't find PCI card memory",
- sc->sc_dev.dv_xname);
- return;
- }
+ sc->sc_bustype = CY_BUSTYPE_PCI;
- /* map the memory (non-cacheable) */
- if (bus_space_map(memt, memaddr, memsize, 0, &memh) != 0) {
- printf("%s: couldn't map PCI memory region\n",
- sc->sc_dev.dv_xname);
- return;
- }
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_CYCLADES_CYCLOMY_1:
+ case PCI_PRODUCT_CYCLADES_CYCLOM4Y_1:
+ case PCI_PRODUCT_CYCLADES_CYCLOM8Y_1:
+ memtype = PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT_1M;
+ break;
+ case PCI_PRODUCT_CYCLADES_CYCLOMY_2:
+ case PCI_PRODUCT_CYCLADES_CYCLOM4Y_2:
+ case PCI_PRODUCT_CYCLADES_CYCLOM8Y_2:
+ memtype = PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT;
+ break;
+ }
- /* the PCI Cyclom IO space is only used for enabling interrupts */
- if (pci_io_find(pa->pa_pc, pa->pa_tag, 0x14, &iobase, &iosize) != 0) {
- bus_space_unmap(memt, memh, memsize);
- printf("%s: couldn't find PCI io region\n",
+ if (pci_mapreg_map(pa, 0x14, PCI_MAPREG_TYPE_IO, 0,
+ &psc->sc_iot, &psc->sc_ioh, NULL, NULL, 0) != 0) {
+ printf("%s: unable to map PLX registers\n",
sc->sc_dev.dv_xname);
- return;
- }
+ return;
+ }
- if (bus_space_map(iot, iobase, iosize, 0, &ioh) != 0) {
- bus_space_unmap(memt, memh, memsize);
- printf("%s: couldn't map PCI io region\n",
+ if (pci_mapreg_map(pa, 0x18, memtype, 0, &sc->sc_memt,
+ &sc->sc_memh, NULL, NULL, 0) != 0) {
+ printf("%s: couldn't map device registers\n",
sc->sc_dev.dv_xname);
return;
}
-#ifdef CY_DEBUG
- printf("%s: pci mapped mem 0x%lx (size %d), io 0x%x (size %d)\n",
- sc->sc_dev.dv_xname, memaddr, memsize, iobase, iosize);
-#endif
-
- if (cy_probe_common(sc->sc_dev.dv_unit, memt, memh,
- CY_BUSTYPE_PCI) == 0) {
- bus_space_unmap(memt, memh, memsize);
- bus_space_unmap(iot, ioh, iosize);
- printf("%s: PCI Cyclom card with no CD1400s!?\n",
+ if ((sc->sc_nr_cd1400s = cy_probe_common(sc->sc_memt, sc->sc_memh,
+ CY_BUSTYPE_PCI)) == 0) {
+ printf("%s: PCI Cyclom card with no CD1400s\n",
sc->sc_dev.dv_xname);
- return;
- }
+ return;
+ }
- cy_attach(parent, self, aux);
-
- /* Get PLX version */
- memt = pa->pa_memt;
- iot = pa->pa_iot;
- plx_ver = bus_space_read_1(memt, memh, CY_PLX_VER) & 0x0f;
-
- /* Enable PCI card interrupts */
- switch (plx_ver) {
- case CY_PLX_9050:
- bus_space_write_2(iot, ioh, CY_PCI_INTENA_9050,
- bus_space_read_2(iot, ioh, CY_PCI_INTENA_9050) | 0x40);
- break;
- case CY_PLX_9060:
- case CY_PLX_9080:
- default:
- bus_space_write_2(iot, ioh, CY_PCI_INTENA,
- bus_space_read_2(iot, ioh, CY_PCI_INTENA) | 0x900);
- }
-
- /* Enable PCI card interrupts */
if (pci_intr_map(pa, &ih) != 0)
panic("%s: couldn't map PCI interrupt", sc->sc_dev.dv_xname);
sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_TTY, cy_intr,
sc, sc->sc_dev.dv_xname);
+ if (sc->sc_ih == NULL)
+ panic("%s: couldn't establish interrupt", sc->sc_dev.dv_xname);
+
+ cy_attach(parent, self);
- if (sc->sc_ih == NULL)
- panic("%s: couldn't establish interrupt", sc->sc_dev.dv_xname);
+ /* Get PLX version */
+ plx_ver = bus_space_read_1(sc->sc_memt, sc->sc_memh, CY_PLX_VER) & 0x0f;
+
+ /* Enable PCI card interrupts */
+ switch (plx_ver) {
+ case CY_PLX_9050:
+ bus_space_write_2(psc->sc_iot, psc->sc_ioh, CY_PCI_INTENA_9050,
+ CY_PLX_9050_ICS_IENABLE | CY_PLX_9050_ICS_LOCAL_IENABLE |
+ CY_PLX_9050_ICS_LOCAL_IPOLARITY);
+ break;
+
+ case CY_PLX_9060:
+ case CY_PLX_9080:
+ default:
+ bus_space_write_2(psc->sc_iot, psc->sc_ioh, CY_PCI_INTENA,
+ bus_space_read_2(psc->sc_iot, psc->sc_ioh,
+ CY_PCI_INTENA) | CY_PLX_9060_ICS_IENABLE |
+ CY_PLX_9060_ICS_LOCAL_IENABLE);
+ }
}