summaryrefslogtreecommitdiffstats
path: root/sys/pccard/pcic.c
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2001-05-21 03:22:52 +0000
committerimp <imp@FreeBSD.org>2001-05-21 03:22:52 +0000
commitc647eb3dd3a3fe40270d6f28f46bb14b0e82f03f (patch)
treee32e014d12f98b72a7d509d506384d5e681a77aa /sys/pccard/pcic.c
parent9ff3821aa3027d9a1088a351417d00294fb2e394 (diff)
downloadFreeBSD-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.c67
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);
}
/*
OpenPOWER on IntegriCloud