summaryrefslogtreecommitdiffstats
path: root/sys/pccard
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1995-10-21 00:55:36 +0000
committerphk <phk@FreeBSD.org>1995-10-21 00:55:36 +0000
commit6d6a401f8b20e250ab7d9a640a899fae0c5a017c (patch)
treed1751df070258ce118a4222568849a39456c07d5 /sys/pccard
parent8deb9482ef65a6a3a773ac996395624316ba29cc (diff)
downloadFreeBSD-src-6d6a401f8b20e250ab7d9a640a899fae0c5a017c.zip
FreeBSD-src-6d6a401f8b20e250ab7d9a640a899fae0c5a017c.tar.gz
A mixed bag of changes, relating to getting the state in "lsdev" right,
and pccard support to work sensibly. Better by far, but still not good.
Diffstat (limited to 'sys/pccard')
-rw-r--r--sys/pccard/pccard.c38
-rw-r--r--sys/pccard/pcic.c83
2 files changed, 86 insertions, 35 deletions
diff --git a/sys/pccard/pccard.c b/sys/pccard/pccard.c
index ae5ca49..d5dfb0c 100644
--- a/sys/pccard/pccard.c
+++ b/sys/pccard/pccard.c
@@ -46,6 +46,20 @@
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/icu.h>
+#include <sys/devconf.h>
+
+extern struct kern_devconf kdc_cpu0;
+
+struct kern_devconf kdc_pccard0 = {
+ 0, 0, 0, /* filled in by dev_attach */
+ "pccard", 0, { MDDT_BUS, 0 },
+ 0, 0, 0, BUS_EXTERNALLEN,
+ &kdc_cpu0, /* parent is the CPU */
+ 0, /* no parentdata */
+ DC_UNCONFIGURED, /* until we see it */
+ "PCCARD or PCMCIA bus",
+ DC_CLS_BUS /* class */
+};
#include "apm.h"
#if NAPM > 0
@@ -121,6 +135,8 @@ pccard_configure()
struct slot_cont *cp;
struct slot *sp;
+ dev_attach(&kdc_pccard0);
+
#include "pcic.h"
#if NPCIC > 0
pcic_probe();
@@ -267,11 +283,12 @@ struct pccard_dev *devp;
* driver is accessing the device and it is removed, then
* all bets are off...
*/
- for (devp = sp->devices; devp; devp = devp->next)
- {
- devp->drv->unload(devp);
- devp->running = 0;
+ for (devp = sp->devices; devp; devp = devp->next) {
+ if (devp->running) {
+ devp->drv->unload(devp);
+ devp->running = 0;
}
+ }
/*
* Power off the slot.
*/
@@ -338,6 +355,7 @@ int slotno;
break;
if (slotno >= MAXSLOT)
return(0);
+ kdc_pccard0.kdc_state = DC_BUSY;
MALLOC(sp, struct slot *, sizeof(*sp), M_DEVBUF, M_WAITOK);
bzero(sp, sizeof(*sp));
if (cp->extra)
@@ -407,6 +425,7 @@ printf("IRQ=%d\n",irq);
if (register_intr(irq, 0, 0, hand, maskp, unit)==0)
{
printf("IRQ=%d yes!\n",irq);
+ INTREN (1 << irq);
return(irq);
}
@@ -461,9 +480,6 @@ int err, irq = 0, s;
*/
else
{
-/* XXX ED.C
-dp->imask = &net_imask;
-*/
irq = pccard_alloc_intr(drvp->irqmask,
slot_irq_handler, (int)sp, dp->imask);
if (irq < 0)
@@ -509,7 +525,6 @@ dp->imask = &net_imask;
remove_device(devp);
else
devp->running = 1;
- INTREN (1 << irq);
return(err);
}
static void
@@ -524,12 +539,17 @@ int s;
* then unregister it if no-one else is using it.
*/
s = splhigh();
- if (dp->running)
+ if (dp->running) {
dp->drv->unload(dp);
+ dp->running = 0;
+ }
if (dp->isahd.id_irq && --sp->irqref == 0)
{
sp->cinfo->mapirq(sp, 0);
+ INTRDIS(1<<sp->irq);
unregister_intr(sp->irq, slot_irq_handler);
+ if (dp->drv->imask)
+ INTRUNMASK(*dp->drv->imask,(1<<sp->irq));
sp->irq = 0;
}
splx(s);
diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c
index 985c4bd..a5df02a 100644
--- a/sys/pccard/pcic.c
+++ b/sys/pccard/pcic.c
@@ -34,8 +34,6 @@
#include "pcic.h"
#endif
-#if NPCIC > 0
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -58,6 +56,22 @@
#include <pccard/i82365.h>
#include <pccard/card.h>
#include <pccard/slot.h>
+#include <sys/devconf.h>
+
+extern struct kern_devconf kdc_pccard0;
+
+struct kern_devconf kdc_pcic[PCIC_MAX_SLOTS] = {
+ {
+ 0, 0, 0, /* filled in by dev_attach */
+ "pcic", 0, { MDDT_BUS, 0 },
+ 0, 0, 0, BUS_EXTERNALLEN,
+ &kdc_pccard0, /* parent is the CPU */
+ 0, /* no parentdata */
+ DC_UNKNOWN,
+ "PCMCIA or PCCARD slot",
+ DC_CLS_BUS /* class */
+ }
+};
/*
* Prototypes for interrupt handler.
@@ -68,6 +82,7 @@ static int pcic_power __P((struct slot *));
static void pcic_reset __P((struct slot *));
static void pcic_disable __P((struct slot *));
static void pcic_mapirq __P((struct slot *, int));
+static void pcictimeout __P((void));
/*
* Per-slot data table.
@@ -233,11 +248,14 @@ pcic_unload()
int slot;
struct pcic_slot *cp = pcic_slots;
+ untimeout(pcictimeout);
if (pcic_irq)
{
- for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, cp++)
+ for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, cp++) {
if (cp->sp)
putb(cp, PCIC_STAT_INT, 0);
+ kdc_pcic[slot].kdc_state = DC_UNCONFIGURED;
+ }
unregister_intr(pcic_irq, pcicintr);
}
pccard_remove_controller(&cinfo);
@@ -535,9 +553,18 @@ unsigned char c;
*/
validslots++;
cp->slot = slot;
+ if (kdc_pcic[slot].kdc_state == DC_UNKNOWN) {
+ if (slot != 0)
+ kdc_pcic[slot] = kdc_pcic[0];
+ kdc_pcic[slot].kdc_unit = slot;
+ kdc_pcic[slot].kdc_state = DC_UNCONFIGURED;
+ kdc_pcic[slot].kdc_description = cinfo.name;
+ dev_attach(kdc_pcic+slot);
+ }
sp = pccard_alloc_slot(&cinfo);
if (sp == 0)
continue;
+ kdc_pcic[slot].kdc_state = DC_IDLE;
sp->cdata = cp;
cp->sp = sp;
/*
@@ -548,19 +575,9 @@ unsigned char c;
{
pcic_irq = pccard_alloc_intr(PCIC_INT_MASK_ALLOWED,
pcicintr, 0, &pcic_imask);
-#if 0
- for (try = 0; try < 16; try++)
- if (((1 << try) & PCIC_INT_MASK_ALLOWED) &&
- !pccard_alloc_intr(try, pcicintr, 0, &tty_imask))
- {
- pcic_irq = try;
- break;
- }
-#endif
if (pcic_irq < 0)
printf("pcic: failed to allocate IRQ\n");
}
- INTREN (1 << pcic_irq);
/*
* Check for a card in this slot.
*/
@@ -578,6 +595,8 @@ unsigned char c;
if (pcic_irq > 0)
putb(cp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF);
}
+ if (validslots)
+ timeout(pcictimeout,0,hz/2);
return(validslots);
}
/*
@@ -711,6 +730,18 @@ struct pcic_slot *sp = slotp->cdata;
}
/*
+ * PCIC timer, it seems that we loose interrupts sometimes
+ * so poll just in case...
+ */
+
+static void
+pcictimeout()
+{
+ timeout(pcictimeout,0,hz/2);
+ pcicintr(0);
+}
+
+/*
* PCIC Interrupt handler.
* Check each slot in turn, and read the card status change
* register. If this is non-zero, then a change has occurred
@@ -725,18 +756,18 @@ struct pcic_slot *cp = pcic_slots;
s = splhigh();
for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, cp++)
- if (cp->sp)
- if ((chg = getb(cp, PCIC_STAT_CHG)) != 0)
- if (chg & PCIC_CDTCH)
- {
- if ((getb(cp, PCIC_STATUS) & PCIC_CD) ==
- PCIC_CD)
- pccard_event(cp->sp,
- card_inserted);
- else
- pccard_event(cp->sp,
- card_removed);
- }
+ if (cp->sp && (chg = getb(cp, PCIC_STAT_CHG)) != 0)
+ if (chg & PCIC_CDTCH) {
+ if ((getb(cp, PCIC_STATUS) & PCIC_CD) ==
+ PCIC_CD) {
+ kdc_pcic[slot].kdc_state = DC_BUSY;;
+ pccard_event(cp->sp,
+ card_inserted);
+ } else {
+ pccard_event(cp->sp,
+ card_removed);
+ kdc_pcic[slot].kdc_state = DC_IDLE;;
+ }
+ }
splx(s);
}
-#endif
OpenPOWER on IntegriCloud