diff options
author | nate <nate@FreeBSD.org> | 1997-01-11 18:23:20 +0000 |
---|---|---|
committer | nate <nate@FreeBSD.org> | 1997-01-11 18:23:20 +0000 |
commit | 74e2dbdd0962c9c9675a75887cb3494992d8d81e (patch) | |
tree | f7c60d90f7e55971345c032d841959b4d84a160d /sys | |
parent | 8a825f6d66e058aef45a59f2e60978de7197881d (diff) | |
download | FreeBSD-src-74e2dbdd0962c9c9675a75887cb3494992d8d81e.zip FreeBSD-src-74e2dbdd0962c9c9675a75887cb3494992d8d81e.tar.gz |
Update the PCIC controller's imask with individual slot IRQ's.
Assuming that the intr_mask[] was updated by changing the maskptrs (the
existing update_intr_masks() function will not work) this code was
written so the PCIC controller insertion/removal events will not
interrupt the card IRQ handler events.
Some possible scenarios:
+ Card is removed during IRQ handler:
- PCIC card handler is allowed to interrupt
- card removal event is called, removing the driver and data structures
* card interrupt handler continues w/out driver, data structures, and hardware
OR (the code just committed)
* card IRQ handler has no hardware to read/write to, but has code and
data to run on (XXX- Assume it completes and doesn't spin forever)
- PCIC card handler unloads the card driver
The current situation at least leaves the card interrupt handlers the
drivers and data structures to work with although the hardware can't be
guaranteed.
Reviewed by: bde
Diffstat (limited to 'sys')
-rw-r--r-- | sys/pccard/driver.h | 4 | ||||
-rw-r--r-- | sys/pccard/pccard.c | 16 | ||||
-rw-r--r-- | sys/pccard/pcic.c | 1 | ||||
-rw-r--r-- | sys/pccard/slot.h | 3 |
4 files changed, 18 insertions, 6 deletions
diff --git a/sys/pccard/driver.h b/sys/pccard/driver.h index fab35ec..7b70b14 100644 --- a/sys/pccard/driver.h +++ b/sys/pccard/driver.h @@ -12,8 +12,8 @@ struct pccard_drv; void pccard_add_driver __P((struct pccard_drv *)); #ifdef _I386_ISA_ISA_DEVICE_H_ /* XXX actually if inthand2_t is declared */ -int pccard_alloc_intr __P((int imask, inthand2_t *hand, int unit, - int *maskp)); +int pccard_alloc_intr __P((u_int imask, inthand2_t *hand, int unit, + u_int *maskp, u_int *pcic_imask)); #endif void pccard_configure __P((void)); void pccard_remove_driver __P((struct pccard_drv *dp)); diff --git a/sys/pccard/pccard.c b/sys/pccard/pccard.c index 623413e..75846ad 100644 --- a/sys/pccard/pccard.c +++ b/sys/pccard/pccard.c @@ -305,8 +305,11 @@ disable_slot(struct slot *sp) unregister_intr(sp->irq, slot_irq_handler); if (devp->drv->imask) INTRUNMASK(*devp->drv->imask,(1<<sp->irq)); + /* Remove from the PCIC controller imask */ + if (sp->ctrl->imask) + INTRUNMASK(*(sp->ctrl->imask), (i<<sp->irq)); sp->irq = 0; - } + } splx(s); } } @@ -439,7 +442,8 @@ pccard_alloc_slot(struct slot_ctrl *cp) * allowed are passed as a mask. */ int -pccard_alloc_intr(int imask, inthand2_t *hand, int unit, int *maskp) +pccard_alloc_intr(u_int imask, inthand2_t *hand, int unit, + u_int *maskp, u_int *pcic_imask) { int irq; unsigned int mask; @@ -451,6 +455,8 @@ pccard_alloc_intr(int imask, inthand2_t *hand, int unit, int *maskp) if (maskp) INTRMASK (*maskp, mask); if (register_intr(irq, 0, 0, hand, maskp, unit)==0) { + /* add this to the PCIC controller's mask */ + INTRMASK(*pcic_imask, (1 << irq)); INTREN (mask); return(irq); } @@ -506,7 +512,8 @@ allocate_driver(struct slot *sp, struct drv_desc *drvp) * device relies on a different interrupt mask. */ irq = pccard_alloc_intr(drvp->irqmask, - slot_irq_handler, (int)sp, dp->imask); + slot_irq_handler, (int)sp, + dp->imask, sp->ctrl->imask); if (irq < 0) return(EINVAL); sp->irq = irq; @@ -578,6 +585,9 @@ remove_device(struct pccard_dev *devp) unregister_intr(sp->irq, slot_irq_handler); if (devp->drv->imask) INTRUNMASK(*devp->drv->imask,(1<<sp->irq)); + /* Remove from PCIC controller imask */ + if (sp->ctrl->imask) + INTRUNMASK(*(sp->ctrl->imask),(1<<sp->irq)); sp->irq = 0; } splx(s); diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c index 5a834c2..e06a034 100644 --- a/sys/pccard/pcic.c +++ b/sys/pccard/pcic.c @@ -567,6 +567,7 @@ pcic_probe(void) cinfo.maxmem = PCIC_MEM_WIN; cinfo.maxio = PCIC_IO_WIN; cinfo.irqs = free_irqs; + cinfo.pcic_imask = &pcic_imask; #ifdef LKM bzero(pcic_slots, sizeof(pcic_slots)); diff --git a/sys/pccard/slot.h b/sys/pccard/slot.h index e0f5fa3..c58147c 100644 --- a/sys/pccard/slot.h +++ b/sys/pccard/slot.h @@ -58,11 +58,12 @@ struct slot_ctrl { int maxmem; /* Number of allowed memory windows */ int maxio; /* Number of allowed I/O windows */ int irqs; /* IRQ's that are allowed */ + u_int *imask; /* IRQ mask for the PCIC controller */ char *name; /* controller name */ + /* * The rest is maintained by the mainline PC-CARD code. */ - struct slot_ctrl *next; /* Allows linked list of controllers */ int slots; /* Slots available */ }; |