diff options
author | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 2001-06-25 23:00:56 +0000 |
---|---|---|
committer | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 2001-06-25 23:00:56 +0000 |
commit | 7c69cf6866bd05c89faae322d335b26ec28db076 (patch) | |
tree | f9ea8cc8a23c8a947e6bff1c1d76ba764d5d2587 /sys/dev/pci/pciide.c | |
parent | 5fce785dd1876e924d9de0353c6f473d0d70039b (diff) |
Enable interrupts during PCIIDE detect
Diffstat (limited to 'sys/dev/pci/pciide.c')
-rw-r--r-- | sys/dev/pci/pciide.c | 141 |
1 files changed, 107 insertions, 34 deletions
diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c index 82965b3cf87..2cc6978f628 100644 --- a/sys/dev/pci/pciide.c +++ b/sys/dev/pci/pciide.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pciide.c,v 1.53 2001/06/12 15:40:32 niklas Exp $ */ +/* $OpenBSD: pciide.c,v 1.54 2001/06/25 23:00:55 csapuntz Exp $ */ /* $NetBSD: pciide.c,v 1.110 2001/03/20 17:56:46 bouyer Exp $ */ /* @@ -471,6 +471,8 @@ void pciide_mapchan __P((struct pci_attach_args *, int pciide_chan_candisable __P((struct pciide_channel *)); void pciide_map_compat_intr __P(( struct pci_attach_args *, struct pciide_channel *, int, int)); +void pciide_unmap_compat_intr __P(( struct pci_attach_args *, + struct pciide_channel *, int, int)); int pciide_print __P((void *, const char *pnp)); int pciide_compat_intr __P((void *)); int pciide_pci_intr __P((void *)); @@ -1138,6 +1140,7 @@ pciide_chansetup(sc, channel, interface) sc->sc_wdcdev.sc_dev.dv_xname, cp->name); return 0; } + cp->hw_ok = 1; return 1; } @@ -1197,11 +1200,10 @@ pciide_map_compat_intr(pa, cp, compatchan, interface) struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; struct channel_softc *wdc_cp = &cp->wdc_channel; - if (cp->hw_ok == 0) - return; if ((interface & PCIIDE_INTERFACE_PCI(wdc_cp->channel)) != 0) return; + cp->compat = 1; cp->ih = pciide_machdep_compat_intr_establish(&sc->sc_wdcdev.sc_dev, pa, compatchan, pciide_compat_intr, cp); if (cp->ih == NULL) { @@ -1211,6 +1213,25 @@ pciide_map_compat_intr(pa, cp, compatchan, interface) } } +/* + * generic code to map the compat intr if hw_ok=1 and it is a compat channel. + * Set hw_ok=0 on failure + */ +void +pciide_unmap_compat_intr(pa, cp, compatchan, interface) + struct pci_attach_args *pa; + struct pciide_channel *cp; + int compatchan, interface; +{ + struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; + struct channel_softc *wdc_cp = &cp->wdc_channel; + + if ((interface & PCIIDE_INTERFACE_PCI(wdc_cp->channel)) != 0) + return; + + pciide_machdep_compat_intr_disestablish(&sc->sc_wdcdev.sc_dev, cp->ih); +} + void pciide_print_channels(nchannels, interface) int nchannels; @@ -1298,6 +1319,9 @@ default_chip_map(sc, pa) * Check to see if something appears to be there. */ failreason = NULL; + pciide_map_compat_intr(pa, cp, channel, interface); + if (cp->hw_ok == 0) + continue; if (!wdcprobe(&cp->wdc_channel)) { failreason = "not responding; disabled or no drives?"; goto next; @@ -1323,12 +1347,11 @@ next: sc->sc_wdcdev.sc_dev.dv_xname, cp->name, failreason); cp->hw_ok = 0; + pciide_unmap_compat_intr(pa, cp, channel, interface); bus_space_unmap(cp->wdc_channel.cmd_iot, cp->wdc_channel.cmd_ioh, cmdsize); bus_space_unmap(cp->wdc_channel.ctl_iot, cp->wdc_channel.ctl_ioh, ctlsize); - } else { - pciide_map_compat_intr(pa, cp, channel, interface); } if (cp->hw_ok) { cp->wdc_channel.data32iot = cp->wdc_channel.cmd_iot; @@ -1466,19 +1489,24 @@ piix_chip_map(sc, pa) continue; } /* PIIX are compat-only pciide devices */ - pciide_mapchan(pa, cp, 0, &cmdsize, &ctlsize, pciide_pci_intr); + pciide_map_compat_intr(pa, cp, channel, 0); if (cp->hw_ok == 0) continue; + pciide_mapchan(pa, cp, 0, &cmdsize, &ctlsize, pciide_pci_intr); + if (cp->hw_ok == 0) + goto next; if (pciide_chan_candisable(cp)) { idetim = PIIX_IDETIM_CLEAR(idetim, PIIX_IDETIM_IDE, channel); pci_conf_write(sc->sc_pc, sc->sc_tag, PIIX_IDETIM, idetim); } - pciide_map_compat_intr(pa, cp, channel, 0); if (cp->hw_ok == 0) - continue; + goto next; sc->sc_wdcdev.set_modes(&cp->wdc_channel); +next: + if (cp->hw_ok == 0) + pciide_unmap_compat_intr(pa, cp, channel, 0); } WDCDEBUG_PRINT(("piix_setup_chip: idetim=0x%x", @@ -1872,14 +1900,20 @@ amd756_chip_map(sc, pa) sc->sc_wdcdev.sc_dev.dv_xname, cp->name); continue; } + pciide_map_compat_intr(pa, cp, channel, interface); + if (cp->hw_ok == 0) + continue; + pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, pciide_pci_intr); - if (pciide_chan_candisable(cp)) + if (pciide_chan_candisable(cp)) { chanenable &= ~AMD756_CHAN_EN(channel); - pciide_map_compat_intr(pa, cp, channel, interface); - if (cp->hw_ok == 0) + } + if (cp->hw_ok == 0) { + pciide_unmap_compat_intr(pa, cp, channel, interface); continue; + } amd756_setup_channel(&cp->wdc_channel); } @@ -2065,20 +2099,27 @@ apollo_chip_map(sc, pa) sc->sc_wdcdev.sc_dev.dv_xname, cp->name); continue; } - pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, - pciide_pci_intr); + pciide_map_compat_intr(pa, cp, channel, interface); if (cp->hw_ok == 0) continue; + + pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, + pciide_pci_intr); + if (cp->hw_ok == 0) { + goto next; + } if (pciide_chan_candisable(cp)) { ideconf &= ~APO_IDECONF_EN(channel); pci_conf_write(sc->sc_pc, sc->sc_tag, APO_IDECONF, ideconf); } - pciide_map_compat_intr(pa, cp, channel, interface); if (cp->hw_ok == 0) - continue; + goto next; apollo_setup_channel(&sc->pciide_channels[channel].wdc_channel); +next: + if (cp->hw_ok == 0) + pciide_unmap_compat_intr(pa, cp, channel, interface); } WDCDEBUG_PRINT(("apollo_chip_map: APO_DATATIM=0x%x, APO_UDMA=0x%x\n", pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM), @@ -2239,18 +2280,22 @@ cmd_channel_map(pa, sc, channel) sc->sc_wdcdev.sc_dev.dv_xname, cp->name); return; } - - pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, cmd_pci_intr); + pciide_map_compat_intr(pa, cp, channel, interface); if (cp->hw_ok == 0) return; + pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, cmd_pci_intr); + if (cp->hw_ok == 0) { + pciide_unmap_compat_intr(pa, cp, channel, interface); + return; + } if (channel == 1) { if (pciide_chan_candisable(cp)) { ctrl &= ~CMD_CTRL_2PORT; pciide_pci_write(pa->pa_pc, pa->pa_tag, CMD_CTRL, ctrl); + pciide_unmap_compat_intr(pa, cp, channel, interface); } } - pciide_map_compat_intr(pa, cp, channel, interface); } int @@ -2609,14 +2654,20 @@ cy693_chip_map(sc, pa) cp->wdc_channel.data32iot = cp->wdc_channel.cmd_iot; cp->wdc_channel.data32ioh = cp->wdc_channel.cmd_ioh; + pciide_map_compat_intr(pa, cp, sc->sc_cy_compatchan, interface); + if (cp->hw_ok == 0) + return; wdcattach(&cp->wdc_channel); if (pciide_chan_candisable(cp)) { pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, 0); } - pciide_map_compat_intr(pa, cp, sc->sc_cy_compatchan, interface); - if (cp->hw_ok == 0) + if (cp->hw_ok == 0) { + pciide_unmap_compat_intr(pa, cp, sc->sc_cy_compatchan, + interface); return; + } + WDCDEBUG_PRINT(("cy693_chip_map: old timings reg 0x%x\n", pci_conf_read(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL)),DEBUG_PROBE); cy693_setup_channel(&cp->wdc_channel); @@ -2736,10 +2787,15 @@ sis_chip_map(sc, pa) sc->sc_wdcdev.sc_dev.dv_xname, cp->name); continue; } + pciide_map_compat_intr(pa, cp, channel, interface); + if (cp->hw_ok == 0) + continue; pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, pciide_pci_intr); - if (cp->hw_ok == 0) + if (cp->hw_ok == 0) { + pciide_unmap_compat_intr(pa, cp, channel, interface); continue; + } if (pciide_chan_candisable(cp)) { if (channel == 0) sis_ctr0 &= ~SIS_CTRL0_CHAN0_EN; @@ -2748,9 +2804,10 @@ sis_chip_map(sc, pa) pciide_pci_write(sc->sc_pc, sc->sc_tag, SIS_CTRL0, sis_ctr0); } - pciide_map_compat_intr(pa, cp, channel, interface); - if (cp->hw_ok == 0) + if (cp->hw_ok == 0) { + pciide_unmap_compat_intr(pa, cp, channel, interface); continue; + } sis_setup_channel(&cp->wdc_channel); } } @@ -2890,17 +2947,25 @@ acer_chip_map(sc, pa) printf("%s: %s ignored (disabled)\n", sc->sc_wdcdev.sc_dev.dv_xname, cp->name); continue; - } + } + pciide_map_compat_intr(pa, cp, channel, interface); + if (cp->hw_ok == 0) + continue; pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, acer_pci_intr); - if (cp->hw_ok == 0) + if (cp->hw_ok == 0) { + pciide_unmap_compat_intr(pa, cp, channel, interface); continue; + } if (pciide_chan_candisable(cp)) { cr &= ~(PCIIDE_CHAN_EN(channel) << PCI_INTERFACE_SHIFT); pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG, cr); } - pciide_map_compat_intr(pa, cp, channel, interface); + if (cp->hw_ok == 0) { + pciide_unmap_compat_intr(pa, cp, channel, interface); + continue; + } acer_setup_channel(&cp->wdc_channel); } } @@ -3339,18 +3404,24 @@ pdc202xx_chip_map(sc, pa) sc->sc_wdcdev.sc_dev.dv_xname, cp->name); continue; } + pciide_map_compat_intr(pa, cp, channel, interface); + if (cp->hw_ok == 0) + continue; if (PDC_IS_265(sc)) pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, pdc20265_pci_intr); else pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, pdc202xx_pci_intr); - if (cp->hw_ok == 0) - continue; - if (pciide_chan_candisable(cp)) + if (cp->hw_ok == 0) { + pciide_unmap_compat_intr(pa, cp, channel, interface); + continue; + } + if (pciide_chan_candisable(cp)) { st &= ~(PDC_IS_262(sc) ? PDC262_STATE_EN(channel):PDC246_STATE_EN(channel)); - pciide_map_compat_intr(pa, cp, channel, interface); + pciide_unmap_compat_intr(pa, cp, channel, interface); + } pdc202xx_setup_channel(&cp->wdc_channel); } WDCDEBUG_PRINT(("pdc202xx_setup_chip: new controller state 0x%x\n", st), @@ -3644,13 +3715,15 @@ opti_chip_map(sc, pa) sc->sc_wdcdev.sc_dev.dv_xname, cp->name); continue; } - pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, - pciide_pci_intr); - if (cp->hw_ok == 0) - continue; pciide_map_compat_intr(pa, cp, channel, interface); if (cp->hw_ok == 0) continue; + pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, + pciide_pci_intr); + if (cp->hw_ok == 0) { + pciide_unmap_compat_intr(pa, cp, channel, interface); + continue; + } opti_setup_channel(&cp->wdc_channel); } } |