mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
- defined constant ISA_HOLE_START (would be nice to include machine/pmap.h,
but it has too much baggage). - create a new routine 'unregister_device_interrupt', which is now used instead of having two routines with the same code snippet. - Minor cleanups and commenting. [ No functional changes, just moving things around ]
This commit is contained in:
parent
1f1d79b8fe
commit
f47a5dccbf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=30679
@ -48,7 +48,7 @@
|
||||
#include <i386/isa/icu.h>
|
||||
|
||||
#include "apm.h"
|
||||
#if NAPM > 0
|
||||
#if NAPM > 0
|
||||
#include <machine/apm_bios.h>
|
||||
#endif /* NAPM > 0 */
|
||||
|
||||
@ -59,6 +59,12 @@
|
||||
#include <machine/clock.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
/*
|
||||
* XXX ISA_HOLE_START is defined in <machine/pmap.h>, but it
|
||||
* carries too much baggage
|
||||
*/
|
||||
#define ISA_HOLE_START 0xA0000
|
||||
|
||||
SYSCTL_NODE(_machdep, OID_AUTO, pccard, CTLFLAG_RW, 0, "pccard");
|
||||
|
||||
static int pcic_resume_reset =
|
||||
@ -87,6 +93,7 @@ SYSCTL_INT(_machdep_pccard, OID_AUTO, apm_pccard_resume, CTLFLAG_RW,
|
||||
|
||||
static int allocate_driver(struct slot *, struct drv_desc *);
|
||||
static void inserted(void *);
|
||||
static void unregister_device_interrupt(struct pccard_dev *devp);
|
||||
static void disable_slot(struct slot *);
|
||||
static int invalid_io_memory(unsigned long, int);
|
||||
static struct pccard_drv *find_driver(char *);
|
||||
@ -288,6 +295,36 @@ power_off_slot(void *arg)
|
||||
sp->ctrl->disable(sp);
|
||||
}
|
||||
|
||||
/*
|
||||
* unregister_device_interrupt - Disable the interrupt generation to
|
||||
* the device driver which is handling it, so we can remove it.
|
||||
*/
|
||||
static void
|
||||
unregister_device_interrupt(struct pccard_dev *devp)
|
||||
{
|
||||
struct slot *sp = devp->sp;
|
||||
int s;
|
||||
|
||||
s = splhigh();
|
||||
if (devp->running) {
|
||||
devp->drv->unload(devp);
|
||||
devp->running = 0;
|
||||
if (devp->isahd.id_irq && --sp->irqref <= 0) {
|
||||
printf("Return IRQ=%d\n",sp->irq);
|
||||
sp->ctrl->mapirq(sp, 0);
|
||||
INTRDIS(1<<sp->irq);
|
||||
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), (1<<sp->irq));
|
||||
sp->irq = 0;
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* disable_slot - Disables the slot by removing
|
||||
* the power and unmapping the I/O
|
||||
@ -299,40 +336,23 @@ disable_slot(struct slot *sp)
|
||||
struct pccard_dev *devp;
|
||||
/*
|
||||
* Unload all the drivers on this slot. Note we can't
|
||||
* call remove_device from here, because this may be called
|
||||
* from the event routine, which is called from the slot
|
||||
* controller's ISR, and this could remove the device
|
||||
* structure out in the middle of some driver activity.
|
||||
* remove the device structures themselves, because this
|
||||
* may be called from the event routine, which is called
|
||||
* from the slot controller's ISR, and removing the structures
|
||||
* shouldn't happen during the middle of some driver activity.
|
||||
*
|
||||
* Note that a race condition is possible here; if a
|
||||
* driver is accessing the device and it is removed, then
|
||||
* all bets are off...
|
||||
*/
|
||||
for (devp = sp->devices; devp; devp = devp->next) {
|
||||
if (devp->running) {
|
||||
int s = splhigh();
|
||||
devp->drv->unload(devp);
|
||||
devp->running = 0;
|
||||
if (devp->isahd.id_irq && --sp->irqref == 0) {
|
||||
printf("Return IRQ=%d\n",sp->irq);
|
||||
sp->ctrl->mapirq(sp, 0);
|
||||
INTRDIS(1<<sp->irq);
|
||||
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), (1<<sp->irq));
|
||||
sp->irq = 0;
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
}
|
||||
/* Power off the slot 1/2 second after remove of the card */
|
||||
for (devp = sp->devices; devp; devp = devp->next)
|
||||
unregister_device_interrupt(devp);
|
||||
|
||||
/* Power off the slot 1/2 second after removal of the card */
|
||||
sp->poff_ch = timeout(power_off_slot, (caddr_t)sp, hz / 2);
|
||||
sp->pwr_off_pending = 1;
|
||||
|
||||
/* De-activate all contexts. */
|
||||
/* De-activate all contexts. */
|
||||
for (i = 0; i < sp->ctrl->maxmem; i++)
|
||||
if (sp->mem[i].flags & MDF_ACTIVE) {
|
||||
sp->mem[i].flags = 0;
|
||||
@ -346,7 +366,7 @@ disable_slot(struct slot *sp)
|
||||
}
|
||||
|
||||
/*
|
||||
* APM hooks for suspending and resuming.
|
||||
* APM hooks for suspending and resuming.
|
||||
*/
|
||||
#if NAPM > 0
|
||||
static int
|
||||
@ -463,7 +483,7 @@ pccard_alloc_slot(struct slot_ctrl *cp)
|
||||
ap->ah_order = APM_MID_ORDER;
|
||||
apm_hook_establish(APM_HOOK_RESUME, ap);
|
||||
}
|
||||
#endif /* NAPM > 0 */
|
||||
#endif /* NAPM > 0 */
|
||||
return(sp);
|
||||
}
|
||||
|
||||
@ -572,7 +592,7 @@ allocate_driver(struct slot *sp, struct drv_desc *drvp)
|
||||
*/
|
||||
if (drvp->mem)
|
||||
devp->isahd.id_maddr =
|
||||
(caddr_t)(drvp->mem + atdevbase - 0xA0000);
|
||||
(caddr_t)(drvp->mem + atdevbase - ISA_HOLE_START);
|
||||
else
|
||||
devp->isahd.id_maddr = 0;
|
||||
devp->next = sp->devices;
|
||||
@ -604,24 +624,7 @@ remove_device(struct pccard_dev *devp)
|
||||
* If an interrupt is enabled on this slot,
|
||||
* then unregister it if no-one else is using it.
|
||||
*/
|
||||
s = splhigh();
|
||||
if (devp->running) {
|
||||
devp->drv->unload(devp);
|
||||
devp->running = 0;
|
||||
}
|
||||
if (devp->isahd.id_irq && --sp->irqref == 0) {
|
||||
printf("Return IRQ=%d\n",sp->irq);
|
||||
sp->ctrl->mapirq(sp, 0);
|
||||
INTRDIS(1<<sp->irq);
|
||||
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);
|
||||
unregister_device_interrupt(devp);
|
||||
/*
|
||||
* Remove from device list on this slot.
|
||||
*/
|
||||
@ -654,11 +657,15 @@ inserted(void *arg)
|
||||
*/
|
||||
sp->pwr.vcc = 50;
|
||||
sp->pwr.vpp = 0;
|
||||
/*
|
||||
* Disable any pending timeouts for this slot, and explicitly
|
||||
* power it off right now. Then, re-enable the power using
|
||||
* the (possibly new) power settings.
|
||||
*/
|
||||
untimeout(power_off_slot, (caddr_t)sp, sp->poff_ch);
|
||||
if (sp->pwr_off_pending)
|
||||
sp->ctrl->disable(sp);
|
||||
sp->pwr_off_pending = 0;
|
||||
power_off_slot(sp);
|
||||
sp->ctrl->power(sp);
|
||||
|
||||
printf("Card inserted, slot %d\n", sp->slot);
|
||||
/*
|
||||
* Now start resetting the card.
|
||||
@ -684,8 +691,6 @@ static void enable_beep(void *dummy)
|
||||
void
|
||||
pccard_event(struct slot *sp, enum card_event event)
|
||||
{
|
||||
int s;
|
||||
|
||||
if (sp->insert_seq) {
|
||||
sp->insert_seq = 0;
|
||||
untimeout(inserted, (void *)sp, sp->insert_ch);
|
||||
@ -697,7 +702,7 @@ pccard_event(struct slot *sp, enum card_event event)
|
||||
* data structures are not unlinked.
|
||||
*/
|
||||
if (sp->state == filled) {
|
||||
s = splhigh();
|
||||
int s = splhigh();
|
||||
disable_slot(sp);
|
||||
sp->state = empty;
|
||||
splx(s);
|
||||
@ -736,6 +741,10 @@ slot_irq_handler(int sp)
|
||||
for (dp = ((struct slot *)sp)->devices; dp; dp = dp->next)
|
||||
if (dp->isahd.id_irq && dp->running && dp->drv->handler(dp))
|
||||
return;
|
||||
/*
|
||||
* XXX - Should 'debounce' these for drivers that have recently
|
||||
* been removed.
|
||||
*/
|
||||
printf("Slot %d, unfielded interrupt (%d)\n",
|
||||
((struct slot *)sp)->slot, ((struct slot *)sp)->irq);
|
||||
}
|
||||
@ -986,7 +995,7 @@ crdioctl(dev_t dev, int cmd, caddr_t data, int fflag, struct proc *p)
|
||||
*/
|
||||
pccard_mem = *(unsigned long *)data;
|
||||
pccard_kmem = (unsigned char *)(pccard_mem
|
||||
+ atdevbase - 0xA0000);
|
||||
+ atdevbase - ISA_HOLE_START);
|
||||
break;
|
||||
/*
|
||||
* Set power values
|
||||
@ -1006,7 +1015,7 @@ crdioctl(dev_t dev, int cmd, caddr_t data, int fflag, struct proc *p)
|
||||
else
|
||||
sysbeep(PCCARD_BEEP_PITCH2, PCCARD_BEEP_DURATION2);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -1079,7 +1088,7 @@ crd_drvinit(void *unused)
|
||||
dev = makedev(CDEV_MAJOR, 0);
|
||||
cdevsw_add(&dev,&crd_cdevsw, NULL);
|
||||
crd_devsw_installed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SYSINIT(crddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,crd_drvinit,NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user