Put the clearing of the socket cd interrupt and setting of it under

protection of sc->mtx.  Sometimes multiple insert/ejections could
cause further insertion/removals to not happen due to racing an ISR...
This commit is contained in:
Warner Losh 2003-08-18 03:15:44 +00:00
parent 4aef3fb1c3
commit da245931e3

View File

@ -1010,15 +1010,6 @@ cbb_event_thread(void *arg)
}
mtx_unlock(&Giant);
/*
* In our ISR, we turn off the card changed interrupt. Turn
* them back on here before we wait for them to happen. We
* turn them on/off so that we can tolerate a large latency
* between the time we signal cbb_event_thread and it gets
* a chance to run.
*/
cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD);
/*
* Wait until it has been 1s since the last time we
* get an interrupt. We handle the rest of the interrupt
@ -1026,8 +1017,15 @@ cbb_event_thread(void *arg)
* ISR, we signal sc->cv from the detach path after we've
* set the CBB_KTHREAD_DONE bit, so we can't do a simple
* 1s sleep here.
*
* In our ISR, we turn off the card changed interrupt. Turn
* them back on here before we wait for them to happen. We
* turn them on/off so that we can tolerate a large latency
* between the time we signal cbb_event_thread and it gets
* a chance to run.
*/
mtx_lock(&sc->mtx);
cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD);
cv_wait(&sc->cv, &sc->mtx);
err = 0;
while (err != EWOULDBLOCK &&
@ -1125,8 +1123,8 @@ cbb_intr(void *arg)
* excellent results.
*/
if (sockevent & CBB_SOCKET_EVENT_CD) {
cbb_clrb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD);
mtx_lock(&sc->mtx);
cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD);
sc->flags &= ~CBB_CARD_OK;
cbb_disable_func_intr(sc);
DPRINTF(("Waking up thread\n"));