From 673cffefc7fe0a883dbce9a6eb1a623e878b7bdd Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 10 Aug 2002 06:37:32 +0000 Subject: When we allocate our bus address via the kludge that we have in the code to do it when the bios doesn't do it for us, flag it. Then, when we dealloc, do an equal kludge to get rid of the address. This should address the can't get IRQ and panic bug in a more graceful way. # really should write a dealloc routine and just call it instead, since # this might not fix things in the kldunload case. --- sys/dev/pccbb/pccbb.c | 32 +++++++++++++++++++------------- sys/dev/pccbb/pccbbvar.h | 7 ++++--- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index d5d2b6fb775f..5cb6cd88199a 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -609,15 +609,14 @@ pccbb_attach(device_t brdev) cv_destroy(&sc->cv); return (ENOMEM); } + sc->flags |= PCCBB_KLUDGE_ALLOC; pci_write_config(brdev, CBBR_SOCKBASE, rman_get_start(sc->base_res), 4); DEVPRINTF((brdev, "PCI Memory allocated: %08lx\n", rman_get_start(sc->base_res))); } else { device_printf(brdev, "Could not map register memory\n"); - mtx_destroy(&sc->mtx); - cv_destroy(&sc->cv); - return (ENOMEM); + goto err; } } @@ -650,22 +649,14 @@ pccbb_attach(device_t brdev) RF_SHAREABLE | RF_ACTIVE); if (sc->irq_res == NULL) { printf("pccbb: Unable to map IRQ...\n"); - bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE, - sc->base_res); - mtx_destroy(&sc->mtx); - cv_destroy(&sc->cv); + goto err; return (ENOMEM); } if (bus_setup_intr(brdev, sc->irq_res, INTR_TYPE_AV, pccbb_intr, sc, &sc->intrhand)) { device_printf(brdev, "couldn't establish interrupt"); - bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res); - bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE, - sc->base_res); - mtx_destroy(&sc->mtx); - cv_destroy(&sc->cv); - return (ENOMEM); + goto err; } /* reset 16-bit pcmcia bus */ @@ -688,6 +679,21 @@ pccbb_attach(device_t brdev) } return (0); +err: + if (sc->irq_res) + bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res); + if (sc->base_res) { + if (sc->flags & PCCBB_KLUDGE_ALLOC) + bus_generic_release_resource(device_get_parent(brdev), + brdev, SYS_RES_MEMORY, CBBR_SOCKBASE, + sc->base_res); + else + bus_release_resource(brdev, SYS_RES_MEMORY, + CBBR_SOCKBASE, sc->base_res); + } + mtx_destroy(&sc->mtx); + cv_destroy(&sc->cv); + return (ENOMEM); } static int diff --git a/sys/dev/pccbb/pccbbvar.h b/sys/dev/pccbb/pccbbvar.h index a7ca49df5317..c8de2dd21f06 100644 --- a/sys/dev/pccbb/pccbbvar.h +++ b/sys/dev/pccbb/pccbbvar.h @@ -65,9 +65,10 @@ struct pccbb_softc { struct mtx mtx; struct cv cv; u_int32_t flags; -#define PCCBB_16BIT_CARD 0x02000000 -#define PCCBB_KTHREAD_RUNNING 0x04000000 -#define PCCBB_KTHREAD_DONE 0x08000000 +#define PCCBB_KLUDGE_ALLOC 0x10000000 +#define PCCBB_16BIT_CARD 0x20000000 +#define PCCBB_KTHREAD_RUNNING 0x40000000 +#define PCCBB_KTHREAD_DONE 0x80000000 int chipset; /* chipset id */ #define CB_UNKNOWN 0 /* NOT Cardbus-PCI bridge */ #define CB_TI113X 1 /* TI PCI1130/1131 */ -- cgit v1.3