diff --git a/sys/pccard/pcic_pci.c b/sys/pccard/pcic_pci.c index 7627cc21114..9c4c891a4d2 100644 --- a/sys/pccard/pcic_pci.c +++ b/sys/pccard/pcic_pci.c @@ -677,13 +677,26 @@ pcic_pci_shutdown(device_t dev) sp = &sc->slots[0]; /* - * Turn off the power to the slot before we do anything - * with it. + * Turn off the power to the slot in an attempt to + * keep the system from hanging on reboot. We also turn off + * card interrupts in an attempt to control interrupt storms. + * on some (all?) this has the effect of also turning off + * card status change interrupts. A side effect of writing 0 + * to INT_GEN is that the card is placed into "reset" mode + * where nothing happens until it is taken out of "reset" + * mode. */ sp->putb(sp, PCIC_INT_GEN, 0); sp->putb(sp, PCIC_POWER, 0); - /* Ack any pending interrupts */ + /* + * Writing to INT_GEN can cause an interrupt, so we blindly + * ack all possible interrupts here. Reading the stat change + * shouldn't be necessary, but some TI chipsets need it in the + * normal course of operations, so we do it here too. We can't + * lose any interrupts after this point, so go ahead and ack + * everything. The bits in INT_GEN clear upon reading them. + */ bus_space_write_4(sp->bst, sp->bsh, 0, 0xffffffff); sp->getb(sp, PCIC_STAT_CHG); } @@ -765,8 +778,6 @@ pcic_pci_attach(device_t dev) sc->csc_route = pcic_intr_path; sc->func_route = pcic_intr_path; - pcic_pci_shutdown(dev); - if (itm && itm->init) itm->init(dev); else