diff options
author | imp <imp@FreeBSD.org> | 2001-05-21 03:22:52 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2001-05-21 03:22:52 +0000 |
commit | c647eb3dd3a3fe40270d6f28f46bb14b0e82f03f (patch) | |
tree | e32e014d12f98b72a7d509d506384d5e681a77aa /sys/pccard/pcic.c | |
parent | 9ff3821aa3027d9a1088a351417d00294fb2e394 (diff) | |
download | FreeBSD-src-c647eb3dd3a3fe40270d6f28f46bb14b0e82f03f.zip FreeBSD-src-c647eb3dd3a3fe40270d6f28f46bb14b0e82f03f.tar.gz |
Next step towards pcic_pci: the ability to allocate mapped memory in attach.
o Introduce flags word to the softc. This will be used to control various
aspects of the driver. Right now there are two bits defined, PCIC_IO_MAPPED
and PCIC_MEM_MAPPED. One for ISA cards that are I/O mapped, the other is
for PCI cards that are memory mapped. Only the ISA side is implemented
with this commit.
o Introduce a pcic_dealloc which will cleanly dealloc resources used. Right
now it is only supported when called from probe/attach.
o Keep track of resources allocated in the pcic_softc.
o move pcictimeout_ch to the softc so we can support multiple devices
in polling mode.
o In ISA probe, set PCIC_IO_MAPPED.
o Introduce and compute the slot mask. This will be used later when
we expand the number of slots on ISA from 2 to 4. In such a case, we
appear to have to use polling mode otherwise we get two different cards
trying to drive the same interrupt line. I don't have hardware to
test this configuration, so I'll stop here.
Diffstat (limited to 'sys/pccard/pcic.c')
-rw-r--r-- | sys/pccard/pcic.c | 67 |
1 files changed, 56 insertions, 11 deletions
diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c index e3264dd..d6719d2 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); } /* |