Free resources on attach failure.

This commit is contained in:
enami 2000-02-04 09:31:07 +00:00
parent 82235a8673
commit 730f15bb19
2 changed files with 58 additions and 11 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: aic_pcmcia.c,v 1.15 2000/02/04 01:27:12 cgd Exp $ */
/* $NetBSD: aic_pcmcia.c,v 1.16 2000/02/04 09:31:07 enami Exp $ */
/*
* Copyright (c) 1997 Marc Horowitz. All rights reserved.
@ -134,7 +134,7 @@ aic_pcmcia_attach(parent, self, aux)
if (cfe == 0) {
printf(": can't alloc i/o space\n");
return;
goto no_config_entry;
}
sc->sc_iot = psc->sc_pcioh.iot;
@ -144,19 +144,19 @@ aic_pcmcia_attach(parent, self, aux)
pcmcia_function_init(pf, cfe);
if (pcmcia_function_enable(pf)) {
printf(": function enable failed\n");
return;
goto enable_failed;
}
/* Map in the io space */
if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, 0, psc->sc_pcioh.size,
&psc->sc_pcioh, &psc->sc_io_window)) {
printf(": can't map i/o space\n");
return;
goto iomap_failed;
}
if (!aic_find(sc->sc_iot, sc->sc_ioh)) {
printf(": unable to detect chip!\n");
return;
goto no_aic_found;
}
pp = pcmcia_product_lookup(pa, aic_pcmcia_products,
@ -174,6 +174,22 @@ aic_pcmcia_attach(parent, self, aux)
psc->sc_flags |= AIC_PCMCIA_ATTACH;
aicattach(sc);
psc->sc_flags &= ~AIC_PCMCIA_ATTACH;
return;
no_aic_found:
/* Unmap our i/o window. */
pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
iomap_failed:
/* Disable the device. */
pcmcia_function_disable(psc->sc_pf);
enable_failed:
/* Unmap our i/o space. */
pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
no_config_entry:
psc->sc_io_window = -1;
}
int
@ -184,6 +200,10 @@ aic_pcmcia_detach(self, flags)
struct aic_pcmcia_softc *sc = (struct aic_pcmcia_softc *)self;
int error;
if (sc->sc_io_window == -1)
/* Nothing to detach. */
return (0);
if ((error = aic_detach(self, flags)) != 0)
return (error);

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdc_pcmcia.c,v 1.28 2000/02/01 06:48:15 enami Exp $ */
/* $NetBSD: wdc_pcmcia.c,v 1.29 2000/02/04 09:31:07 enami Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -292,14 +292,14 @@ wdc_pcmcia_attach(parent, self, aux)
if (cfe == NULL) {
printf(": can't handle card info\n");
return;
goto no_config_entry;
}
/* Enable the card. */
pcmcia_function_init(pa->pf, cfe);
if (pcmcia_function_enable(pa->pf)) {
printf(": function enable failed\n");
return;
goto enable_failed;
}
wpp = wdc_pcmcia_lookup(pa);
@ -311,7 +311,7 @@ wdc_pcmcia_attach(parent, self, aux)
if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, 0,
sc->sc_pioh.size, &sc->sc_pioh, &sc->sc_iowindow)) {
printf(": can't map first I/O space\n");
return;
goto iomap_failed;
}
if (cfe->num_iospace <= 1)
@ -319,7 +319,7 @@ wdc_pcmcia_attach(parent, self, aux)
else if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_AUTO, 0,
sc->sc_auxpioh.size, &sc->sc_auxpioh, &sc->sc_auxiowindow)) {
printf(": can't map second I/O space\n");
return;
goto iomapaux_failed;
}
if ((wpp != NULL) && (wpp->wpp_name != NULL))
@ -345,7 +345,7 @@ wdc_pcmcia_attach(parent, self, aux)
if (sc->wdc_channel.ch_queue == NULL) {
printf("%s: can't allocate memory for command queue\n",
sc->sc_wdcdev.sc_dev.dv_xname);
return;
goto ch_queue_alloc_failed;
}
if (quirks & WDC_PCMCIA_NO_EXTRA_RESETS)
sc->sc_wdcdev.cap |= WDC_CAPABILITY_NO_EXTRA_RESETS;
@ -356,6 +356,29 @@ wdc_pcmcia_attach(parent, self, aux)
sc->sc_flags |= WDC_PCMCIA_ATTACH;
wdcattach(&sc->wdc_channel);
sc->sc_flags &= ~WDC_PCMCIA_ATTACH;
return;
ch_queue_alloc_failed:
/* Unmap our aux i/o window. */
if (sc->sc_auxiowindow != -1)
pcmcia_io_unmap(sc->sc_pf, sc->sc_auxiowindow);
iomapaux_failed:
/* Unmap our i/o window. */
pcmcia_io_unmap(sc->sc_pf, sc->sc_iowindow);
iomap_failed:
/* Disable the function */
pcmcia_function_disable(sc->sc_pf);
enable_failed:
/* Unmap our i/o space. */
pcmcia_io_free(sc->sc_pf, &sc->sc_pioh);
if (cfe->num_iospace == 2)
pcmcia_io_free(sc->sc_pf, &sc->sc_auxpioh);
no_config_entry:
sc->sc_iowindow = -1;
}
int
@ -366,6 +389,10 @@ wdc_pcmcia_detach(self, flags)
struct wdc_pcmcia_softc *sc = (struct wdc_pcmcia_softc *)self;
int error;
if (sc->sc_iowindow == -1)
/* Nothing to detach */
return (0);
if ((error = wdcdetach(self, flags)) != 0)
return (error);