summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>2001-06-25 23:00:56 +0000
committerConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>2001-06-25 23:00:56 +0000
commit7c69cf6866bd05c89faae322d335b26ec28db076 (patch)
treef9ea8cc8a23c8a947e6bff1c1d76ba764d5d2587 /sys/dev
parent5fce785dd1876e924d9de0353c6f473d0d70039b (diff)
Enable interrupts during PCIIDE detect
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/pciide.c141
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);
}
}