aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2001-05-21 03:22:52 +0000
committerWarner Losh <imp@FreeBSD.org>2001-05-21 03:22:52 +0000
commite67316366dcf62101d427c526d67a8392168ea4d (patch)
treeba2e1aee66018fb6b20ea3541419c080f2b8ebba
parentda76f18bc623402d3746e20d9952b4681c3ebaed (diff)
Notes
-rw-r--r--sys/pccard/pcic.c67
-rw-r--r--sys/pccard/pcic_isa.c4
-rw-r--r--sys/pccard/pcicvar.h12
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];
};