diff options
| author | Warner Losh <imp@FreeBSD.org> | 2001-05-21 03:22:52 +0000 |
|---|---|---|
| committer | Warner Losh <imp@FreeBSD.org> | 2001-05-21 03:22:52 +0000 |
| commit | e67316366dcf62101d427c526d67a8392168ea4d (patch) | |
| tree | ba2e1aee66018fb6b20ea3541419c080f2b8ebba | |
| parent | da76f18bc623402d3746e20d9952b4681c3ebaed (diff) | |
Notes
| -rw-r--r-- | sys/pccard/pcic.c | 67 | ||||
| -rw-r--r-- | sys/pccard/pcic_isa.c | 4 | ||||
| -rw-r--r-- | sys/pccard/pcicvar.h | 12 |
3 files changed, 72 insertions, 11 deletions
diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c index e3264ddc935e..d6719d249145 100644 --- a/sys/pccard/pcic.c +++ b/sys/pccard/pcic.c @@ -59,8 +59,6 @@ static timeout_t pcic_reset; static void pcic_resume(struct slot *); static void pcic_disable(struct slot *); static timeout_t pcictimeout; -static struct callout_handle pcictimeout_ch - = CALLOUT_HANDLE_INITIALIZER(&pcictimeout_ch); static int pcic_memory(struct slot *, int); static int pcic_io(struct slot *, int); @@ -108,6 +106,29 @@ putw(struct pcic_slot *sp, int reg, unsigned short word) } /* + * Free up resources allocated so far. + */ +static void +pcic_dealloc(device_t dev) +{ + struct pcic_softc *sc; + + sc = (struct pcic_softc *) device_get_softc(dev); + if (sc->iores) + bus_release_resource(dev, SYS_RES_IOPORT, sc->iorid, + sc->iores); + if (sc->memres) + bus_release_resource(dev, SYS_RES_MEMORY, sc->memrid, + sc->memres); + untimeout(pcictimeout, sc, sc->timeout_ch); + if (sc->ih) + bus_teardown_intr(dev, sc->irqres, sc->ih); + if (sc->irqres) + bus_release_resource(dev, SYS_RES_IRQ, sc->irqrid, sc->irqres); + +} + +/* * entry point from main code to map/unmap memory context. */ static int @@ -242,7 +263,6 @@ pcic_attach(device_t dev) int error; int irq; int i; - void *ih; device_t kid; struct resource *r; int rid; @@ -252,6 +272,7 @@ pcic_attach(device_t dev) int stat; sc = (struct pcic_softc *) device_get_softc(dev); + callout_handle_init(&sc->timeout_ch); sp = &sc->slots[0]; for (i = 0; i < PCIC_CARD_SLOTS; i++, sp++) { if (!sp->slt) @@ -268,14 +289,34 @@ pcic_attach(device_t dev) device_printf(dev, "Can't get pccard info slot %d", i); return (ENXIO); } + sc->slotmask |= (1 << i); slt->cdata = sp; sp->slt = slt; } - rid = 0; - r = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE); - if (!r) - return (ENXIO); + if (sc->flags & PCIC_IO_MAPPED) { + rid = 0; + r = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, + RF_ACTIVE); + if (!r) { + pcic_dealloc(dev); + return (ENXIO); + } + sc->iorid = rid; + sc->iores = r; + } + + if (sc->flags & PCIC_MEM_MAPPED) { + rid = 0; + r = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, + RF_ACTIVE); + if (!r) { + pcic_dealloc(dev); + return (ENXIO); + } + sc->memrid = rid; + sc->memres = r; + } irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0); if (irq == 0) { @@ -297,11 +338,13 @@ pcic_attach(device_t dev) r = 0; irq = 0; } + sc->irqrid = rid; + sc->irqres = r; if (r) { error = bus_setup_intr(dev, r, INTR_TYPE_MISC, - pcicintr, (void *) sc, &ih); + pcicintr, (void *) sc, &sc->ih); if (error) { - bus_release_resource(dev, SYS_RES_IRQ, rid, r); + pcic_dealloc(dev); return (error); } irq = rman_get_start(r); @@ -310,7 +353,7 @@ pcic_attach(device_t dev) irq = 0; } if (irq == 0) { - pcictimeout_ch = timeout(pcictimeout, (void *) sc, hz/2); + sc->timeout_ch = timeout(pcictimeout, (void *) sc, hz/2); device_printf(dev, "Polling mode\n"); } @@ -557,12 +600,14 @@ pcicintr(void *arg) static void pcictimeout(void *chan) { + struct pcic_softc *sc = (struct pcic_softc *) chan; + if (pcicintr1(chan) != 0) { printf("pcic%d: Static bug detected, ignoring hardware.\n", ((struct pcic_softc *)chan)->unit); return; } - pcictimeout_ch = timeout(pcictimeout, chan, hz/2); + sc->timeout_ch = timeout(pcictimeout, chan, hz/2); } /* diff --git a/sys/pccard/pcic_isa.c b/sys/pccard/pcic_isa.c index 130e67085102..ae79a038e9e6 100644 --- a/sys/pccard/pcic_isa.c +++ b/sys/pccard/pcic_isa.c @@ -282,6 +282,10 @@ pcic_isa_probe(device_t dev) static int pcic_isa_attach(device_t dev) { + struct pcic_softc *sc; + + sc = device_get_softc(dev); + sc->flags |= PCIC_IO_MAPPED; return (pcic_attach(dev)); } diff --git a/sys/pccard/pcicvar.h b/sys/pccard/pcicvar.h index bc0dd34851d9..2f46014c742e 100644 --- a/sys/pccard/pcicvar.h +++ b/sys/pccard/pcicvar.h @@ -41,7 +41,19 @@ struct pcic_slot { struct pcic_softc { + u_int32_t slotmask; /* Mask of valid slots */ + u_int32_t flags; /* Interesting flags */ +#define PCIC_IO_MAPPED 0x00000001 +#define PCIC_MEM_MAPPED 0x00000002 + int iorid; /* Rid of I/O region */ + struct resource *iores; /* resource for I/O region */ + int memrid; + struct resource *memres; + int irqrid; + struct resource *irqres; + void *ih; int unit; + struct callout_handle timeout_ch; struct pcic_slot slots[PCIC_MAX_SLOTS]; }; |
