summaryrefslogtreecommitdiff
path: root/sys/dev/pci/pciide.c
diff options
context:
space:
mode:
authorAlexander Yurchenko <grange@cvs.openbsd.org>2003-01-16 16:15:47 +0000
committerAlexander Yurchenko <grange@cvs.openbsd.org>2003-01-16 16:15:47 +0000
commit6ae3cc5ccd257a40febf421ff47fbaed38959722 (patch)
tree334479f18d559d7feacc1042c0bceb70e10b576a /sys/dev/pci/pciide.c
parent6fe02e0318d86538fef2f4d327100971d05b203c (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.c53
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.