diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2001-11-04 18:31:43 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2001-11-04 18:31:43 +0000 |
commit | b5644c6f24e4adeba4d609e44ebfccdb7efec6b5 (patch) | |
tree | 764ed373f8c709de9e28ca86f79d283337d34475 /sys | |
parent | 7b9588abccf7736f3392b0341320ea8c96f7aeeb (diff) |
7751 has two registers in config space (0x40 - RETRY_TIMEOUT and 0x41,
TRDY_TIMEOUT). These registers must be initialized to zero to disable
these timers or 7751 will get PCI aborts on its descriptor rings on
certain chipsets. These timers were removed because they were unneeded
in the 7951. I'm not sure how I missed this in the datasheet, but there
it is plain as day on page 24. Thanks go to Hifn for pointing this out.
Upshot: PCI abort problem on 7751 appears to be solved.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/hifn7751.c | 21 | ||||
-rw-r--r-- | sys/dev/pci/hifn7751reg.h | 10 | ||||
-rw-r--r-- | sys/dev/pci/hifn7751var.h | 4 |
3 files changed, 29 insertions, 6 deletions
diff --git a/sys/dev/pci/hifn7751.c b/sys/dev/pci/hifn7751.c index 30ca41f298c..7b34a367722 100644 --- a/sys/dev/pci/hifn7751.c +++ b/sys/dev/pci/hifn7751.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hifn7751.c,v 1.103 2001/09/06 03:31:34 jason Exp $ */ +/* $OpenBSD: hifn7751.c,v 1.104 2001/11/04 18:31:42 jason Exp $ */ /* * Invertex AEON / Hifn 7751 driver @@ -154,6 +154,9 @@ hifn_attach(parent, self, aux) int rseg; caddr_t kva; + sc->sc_pci_pc = pa->pa_pc; + sc->sc_pci_tag = pa->pa_tag; + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_HIFN && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_HIFN_7951) sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC; @@ -185,6 +188,10 @@ hifn_attach(parent, self, aux) goto fail_io0; } + cmd = pci_conf_read(sc->sc_pci_pc, sc->sc_pci_tag, HIFN_RETRY_TIMEOUT); + cmd &= 0xffff0000; + pci_conf_write(sc->sc_pci_pc, sc->sc_pci_tag, HIFN_RETRY_TIMEOUT, cmd); + sc->sc_dmat = pa->pa_dmat; if (bus_dmamap_create(sc->sc_dmat, sizeof(*sc->sc_dma), 1, sizeof(*sc->sc_dma), 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) { @@ -438,6 +445,8 @@ hifn_reset_board(sc, full) struct hifn_softc *sc; int full; { + u_int32_t reg; + /* * Set polling in the DMA configuration register to zero. 0x7 avoids * resetting the board and zeros out the other fields. @@ -468,6 +477,10 @@ hifn_reset_board(sc, full) HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE); hifn_puc_wait(sc); + + reg = pci_conf_read(sc->sc_pci_pc, sc->sc_pci_tag, HIFN_RETRY_TIMEOUT); + reg &= 0xffff0000; + pci_conf_write(sc->sc_pci_pc, sc->sc_pci_tag, HIFN_RETRY_TIMEOUT, reg); } u_int32_t @@ -956,8 +969,13 @@ hifn_init_dma(sc) struct hifn_softc *sc; { struct hifn_dma *dma = sc->sc_dma; + u_int32_t reg; int i; + reg = pci_conf_read(sc->sc_pci_pc, sc->sc_pci_tag, HIFN_RETRY_TIMEOUT); + reg &= 0xffff0000; + pci_conf_write(sc->sc_pci_pc, sc->sc_pci_tag, HIFN_RETRY_TIMEOUT, reg); + /* initialize static pointer values */ for (i = 0; i < HIFN_D_CMD_RSIZE; i++) dma->cmdr[i].p = sc->sc_dmamap->dm_segs[0].ds_addr + @@ -1539,6 +1557,7 @@ hifn_intr(arg) restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT | HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT); if (restart) { + printf("%s: abort, resetting.\n"); hifnstats.hst_abort++; hifn_abort(sc); return (1); diff --git a/sys/dev/pci/hifn7751reg.h b/sys/dev/pci/hifn7751reg.h index a84a30000d2..a21d5dd33fe 100644 --- a/sys/dev/pci/hifn7751reg.h +++ b/sys/dev/pci/hifn7751reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hifn7751reg.h,v 1.30 2001/08/27 18:54:56 jason Exp $ */ +/* $OpenBSD: hifn7751reg.h,v 1.31 2001/11/04 18:31:42 jason Exp $ */ /* * Invertex AEON / Hifn 7751 driver @@ -35,7 +35,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __HIFN_H__ -#define __HIFN_H__ +#define __HIFN_H__ #include <machine/endian.h> @@ -43,8 +43,10 @@ * Some PCI configuration space offset defines. The names were made * identical to the names used by the Linux kernel. */ -#define HIFN_BAR0 (PCI_MAPREG_START + 0) /* PUC register map */ -#define HIFN_BAR1 (PCI_MAPREG_START + 4) /* DMA register map */ +#define HIFN_BAR0 (PCI_MAPREG_START + 0) /* PUC register map */ +#define HIFN_BAR1 (PCI_MAPREG_START + 4) /* DMA register map */ +#define HIFN_RETRY_TIMEOUT 0x40 +#define HIFN_TRDY_TIMEOUT 0x41 /* * The values below should multiple of 4 -- and be large enough to handle diff --git a/sys/dev/pci/hifn7751var.h b/sys/dev/pci/hifn7751var.h index 235136d5d4c..5daeae657f0 100644 --- a/sys/dev/pci/hifn7751var.h +++ b/sys/dev/pci/hifn7751var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hifn7751var.h,v 1.37 2001/08/28 21:40:54 jason Exp $ */ +/* $OpenBSD: hifn7751var.h,v 1.38 2001/11/04 18:31:42 jason Exp $ */ /* * Invertex AEON / Hifn 7751 driver @@ -153,6 +153,8 @@ struct hifn_softc { int sc_rnghz; int sc_c_busy, sc_s_busy, sc_d_busy, sc_r_busy, sc_active; struct hifn_session sc_sessions[2048]; + pci_chipset_tag_t sc_pci_pc; + pcitag_t sc_pci_tag; }; #define WRITE_REG_0(sc,reg,val) \ |