diff options
author | Alexander Yurchenko <grange@cvs.openbsd.org> | 2003-01-16 16:15:47 +0000 |
---|---|---|
committer | Alexander Yurchenko <grange@cvs.openbsd.org> | 2003-01-16 16:15:47 +0000 |
commit | 6ae3cc5ccd257a40febf421ff47fbaed38959722 (patch) | |
tree | 334479f18d559d7feacc1042c0bceb70e10b576a /sys/dev/pci/pciide.c | |
parent | 6fe02e0318d86538fef2f4d327100971d05b203c (diff) |
- add two inline functions for accessing chip configuration space
through the index and data registers
- proper registers and bits names
- more debug in cable detection
- back the code for checking interrupt asserting in case of shared IRQ,
it seems to solve the problem with repeatable ``bugus intr'' messages
in PDC20376 (one more step to get it working); based on tests by
j@pureftpd.org
Some input and ok from costa@
Diffstat (limited to 'sys/dev/pci/pciide.c')
-rw-r--r-- | sys/dev/pci/pciide.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c index e0a95eb842a..eb0847b9403 100644 --- a/sys/dev/pci/pciide.c +++ b/sys/dev/pci/pciide.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pciide.c,v 1.107 2003/01/16 12:31:01 grange Exp $ */ +/* $OpenBSD: pciide.c,v 1.108 2003/01/16 16:15:46 grange Exp $ */ /* $NetBSD: pciide.c,v 1.127 2001/08/03 01:31:08 tsutsui Exp $ */ /* @@ -4023,6 +4023,32 @@ hpt_pci_intr(arg) (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20276 || \ (sc)->sc_pp->ide_product == PCI_PRODUCT_PROMISE_PDC20277) +static __inline u_int8_t +pdc268_config_read(struct channel_softc *chp, int index) +{ + struct pciide_channel *cp = (struct pciide_channel *)chp; + struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; + int channel = chp->channel; + + bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, + PDC268_INDEX(channel), index); + return (bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, + PDC268_DATA(channel))); +} + +static __inline void +pdc268_config_write(struct channel_softc *chp, int index, u_int8_t value) +{ + struct pciide_channel *cp = (struct pciide_channel *)chp; + struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; + int channel = chp->channel; + + bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, + PDC268_INDEX(channel), index); + bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, + PDC268_DATA(channel), value); +} + void pdc202xx_chip_map(sc, pa) struct pciide_softc *sc; @@ -4303,11 +4329,10 @@ pdc20268_setup_channel(chp) u_int32_t idedma_ctl; struct pciide_channel *cp = (struct pciide_channel*)chp; struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; + int channel = chp->channel; /* check 80 pins cable */ - bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, PDC268_REG0, 0x0b); - cable = bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, - PDC268_REG1) & 0x04; + cable = pdc268_config_read(chp, 0x0b) & PDC268_CABLE; /* setup DMA if needed */ pciide_channel_dma_setup(cp); @@ -4323,8 +4348,13 @@ pdc20268_setup_channel(chp) /* use Ultra/DMA */ drvp->drive_flags &= ~DRIVE_DMA; idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); - if (cable && drvp->UDMA_mode > 2) + if (cable && drvp->UDMA_mode > 2) { + WDCDEBUG_PRINT(("%s(%s:%d:%d): 80-pin " + "cable not detected\n", drvp->drive_name, + sc->sc_wdcdev.sc_dev.dv_xname, + channel, drive), DEBUG_PROBE); drvp->UDMA_mode = 2; + } } else if (drvp->drive_flags & DRIVE_DMA) { idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); } @@ -4333,7 +4363,7 @@ pdc20268_setup_channel(chp) if (idedma_ctl != 0) { /* Add software bits in status register */ bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, - IDEDMA_CTL(chp->channel), idedma_ctl); + IDEDMA_CTL(channel), idedma_ctl); } pciide_print_modes(cp); } @@ -4385,6 +4415,17 @@ pdc20265_pci_intr(arg) /* If a compat channel skip. */ if (cp->compat) continue; + + /* + * In case of shared IRQ check that the interrupt + * was actually generated by this channel. + */ + if (PDC_IS_268(sc)) { + if ((pdc268_config_read(wdc_cp, + 0x0b) & PDC268_INTR) == 0) + continue; + } + /* * The Ultra/100 seems to assert PDC2xx_SCR_INT * spuriously, * however it asserts INT in IDEDMA_CTL even for non-DMA ops. |