diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2008-06-14 02:28:15 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2008-06-14 02:28:15 +0000 |
commit | 39bf0ad16e634ef2ae9f5a8137e199639e1afd14 (patch) | |
tree | 9987d8aecb32c983a530845c6570337c05467ef2 /sys/dev/pci/if_ath_pci.c | |
parent | bb2c2a417d86aa1eeade1222d6db1a3a8a54f340 (diff) |
Allow ath(4) to detach cleanly when attaching via PCI. Also
complete/cleanup the attachment cleanup code.
ok reyk@ jsg@
Diffstat (limited to 'sys/dev/pci/if_ath_pci.c')
-rw-r--r-- | sys/dev/pci/if_ath_pci.c | 63 |
1 files changed, 37 insertions, 26 deletions
diff --git a/sys/dev/pci/if_ath_pci.c b/sys/dev/pci/if_ath_pci.c index ae083c3aa68..7c9a50976ad 100644 --- a/sys/dev/pci/if_ath_pci.c +++ b/sys/dev/pci/if_ath_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ath_pci.c,v 1.15 2007/06/06 21:41:31 reyk Exp $ */ +/* $OpenBSD: if_ath_pci.c,v 1.16 2008/06/14 02:28:14 jsing Exp $ */ /* $NetBSD: if_ath_pci.c,v 1.7 2004/06/30 05:58:17 mycroft Exp $ */ /*- @@ -82,7 +82,8 @@ struct ath_pci_softc { pci_chipset_tag_t sc_pc; pcitag_t sc_pcitag; - void *sc_ih; /* interrupt handler */ + void *sc_ih; /* Interrupt handler. */ + void *sc_sdhook; /* Shutdown hook. */ }; /* Base Address Register */ @@ -125,11 +126,8 @@ ath_pci_attach(struct device *parent, struct device *self, void *aux) struct pci_attach_args *pa = aux; pci_chipset_tag_t pc = pa->pa_pc; pcitag_t pt = pa->pa_tag; - bus_space_tag_t iot; - bus_space_handle_t ioh; pci_intr_handle_t ih; pcireg_t mem_type; - void *hook; const char *intrstr = NULL; psc->sc_pc = pc; @@ -142,17 +140,15 @@ ath_pci_attach(struct device *parent, struct device *self, void *aux) if (mem_type != PCI_MAPREG_TYPE_MEM && mem_type != PCI_MAPREG_MEM_TYPE_64BIT) { printf(": bad PCI register type %d\n", (int)mem_type); - goto bad; + goto fail; } if (mem_type == PCI_MAPREG_MEM_TYPE_64BIT) sc->sc_64bit = 1; - if (pci_mapreg_map(pa, ATH_BAR0, mem_type, 0, &iot, &ioh, - NULL, NULL, 0)) { + if (pci_mapreg_map(pa, ATH_BAR0, mem_type, 0, &sc->sc_st, &sc->sc_sh, + NULL, &sc->sc_ss, 0)) { printf(": cannot map register space\n"); - goto bad; + goto fail; } - sc->sc_st = iot; - sc->sc_sh = ioh; sc->sc_invalid = 1; @@ -160,37 +156,37 @@ ath_pci_attach(struct device *parent, struct device *self, void *aux) * Arrange interrupt line. */ if (pci_intr_map(pa, &ih)) { - printf(": couldn't map interrupt\n"); - goto bad1; + printf(": couldn't map interrupt!\n"); + goto unmap; } intrstr = pci_intr_string(pc, ih); psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, ath_intr, sc, sc->sc_dev.dv_xname); if (psc->sc_ih == NULL) { - printf(": couldn't map interrupt\n"); - goto bad2; + printf(": couldn't map interrupt!\n"); + goto unmap; } printf(": %s\n", intrstr); sc->sc_dmat = pa->pa_dmat; - hook = shutdownhook_establish(ath_pci_shutdown, psc); - if (hook == NULL) { - printf(": couldn't make shutdown hook\n"); - goto bad3; + psc->sc_sdhook = shutdownhook_establish(ath_pci_shutdown, psc); + if (psc->sc_sdhook == NULL) { + printf(": couldn't establish shutdown hook!\n"); + goto deintr; } if (ath_attach(PCI_PRODUCT(pa->pa_id), sc) == 0) return; - shutdownhook_disestablish(hook); - -bad3: pci_intr_disestablish(pc, psc->sc_ih); -bad2: /* XXX */ -bad1: /* XXX */ -bad: + shutdownhook_disestablish(psc->sc_sdhook); +deintr: + pci_intr_disestablish(pc, psc->sc_ih); +unmap: + bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_ss); +fail: return; } @@ -198,9 +194,24 @@ int ath_pci_detach(struct device *self, int flags) { struct ath_pci_softc *psc = (struct ath_pci_softc *)self; + struct ath_softc *sc = &psc->sc_sc; ath_detach(&psc->sc_sc, flags); - pci_intr_disestablish(psc->sc_pc, psc->sc_ih); + + if (psc->sc_ih != NULL) { + pci_intr_disestablish(psc->sc_pc, psc->sc_ih); + psc->sc_ih = NULL; + } + + if (psc->sc_sdhook != NULL) { + shutdownhook_disestablish(psc->sc_sdhook); + psc->sc_sdhook = NULL; + } + + if (sc->sc_sh != 0) { + bus_space_unmap(sc->sc_st, sc->sc_sh, sc->sc_ss); + sc->sc_sh = 0; + } return (0); } |