mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-21 16:32:25 +01:00
Use a cv rather than tsleep and friends to do the sleep/wakeup
handshake between the ISR and the worker thread. Move the mutex lock so that it only protects the cv_wait. This elimiates the not sleeping with pccbb1 held messages some people were seeing. Reviewed by: jhb (at least an early version)
This commit is contained in:
parent
22afbb6bb0
commit
4fdc73e4fa
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=98156
@ -75,6 +75,8 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
@ -558,6 +560,7 @@ pccbb_attach(device_t brdev)
|
||||
uint32_t sockbase;
|
||||
|
||||
mtx_init(&sc->mtx, device_get_nameunit(brdev), "pccbb", MTX_DEF);
|
||||
cv_init(&sc->cv, "pccbb cv");
|
||||
sc->chipset = pccbb_chipset(pci_get_devid(brdev), NULL);
|
||||
sc->dev = brdev;
|
||||
sc->cbdev = NULL;
|
||||
@ -599,6 +602,7 @@ pccbb_attach(device_t brdev)
|
||||
device_printf(brdev,
|
||||
"Could not grab register memory\n");
|
||||
mtx_destroy(&sc->mtx);
|
||||
cv_destroy(&sc->cv);
|
||||
return (ENOMEM);
|
||||
}
|
||||
pci_write_config(brdev, CBBR_SOCKBASE,
|
||||
@ -608,6 +612,7 @@ pccbb_attach(device_t brdev)
|
||||
} else {
|
||||
device_printf(brdev, "Could not map register memory\n");
|
||||
mtx_destroy(&sc->mtx);
|
||||
cv_destroy(&sc->cv);
|
||||
return (ENOMEM);
|
||||
}
|
||||
}
|
||||
@ -644,6 +649,7 @@ pccbb_attach(device_t brdev)
|
||||
bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE,
|
||||
sc->base_res);
|
||||
mtx_destroy(&sc->mtx);
|
||||
cv_destroy(&sc->cv);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
@ -654,6 +660,7 @@ pccbb_attach(device_t brdev)
|
||||
bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE,
|
||||
sc->base_res);
|
||||
mtx_destroy(&sc->mtx);
|
||||
cv_destroy(&sc->cv);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
@ -715,6 +722,7 @@ pccbb_detach(device_t brdev)
|
||||
bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE,
|
||||
sc->base_res);
|
||||
mtx_destroy(&sc->mtx);
|
||||
cv_destroy(&sc->cv);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -888,7 +896,6 @@ pccbb_event_thread(void *arg)
|
||||
* if there's a card already inserted, we do the
|
||||
* right thing.
|
||||
*/
|
||||
mtx_lock(&sc->mtx);
|
||||
if (sc->flags & PCCBB_KTHREAD_DONE)
|
||||
break;
|
||||
|
||||
@ -897,19 +904,19 @@ pccbb_event_thread(void *arg)
|
||||
pccbb_insert(sc);
|
||||
else
|
||||
pccbb_removal(sc);
|
||||
mtx_unlock(&sc->mtx);
|
||||
/*
|
||||
* Wait until it has been 1s since the last time we
|
||||
* get an interrupt. We handle the rest of the interrupt
|
||||
* at the top of the loop.
|
||||
*/
|
||||
tsleep (sc, PWAIT, "pccbbev", 0);
|
||||
mtx_lock(&sc->mtx);
|
||||
cv_wait(&sc->cv, &sc->mtx);
|
||||
do {
|
||||
err = tsleep (sc, PWAIT, "pccbbev", 1 * hz);
|
||||
err = cv_timedwait(&sc->cv, &sc->mtx, 1 * hz);
|
||||
} while (err != EWOULDBLOCK &&
|
||||
(sc->flags & PCCBB_KTHREAD_DONE) == 0);
|
||||
mtx_unlock(&sc->mtx);
|
||||
}
|
||||
mtx_unlock(&sc->mtx);
|
||||
sc->flags &= ~PCCBB_KTHREAD_RUNNING;
|
||||
/*
|
||||
* XXX I think there's a race here. If we wakeup in the other
|
||||
@ -1008,7 +1015,7 @@ pccbb_intr(void *arg)
|
||||
|
||||
if (sockevent & CBB_SOCKET_EVENT_CD) {
|
||||
mtx_lock(&sc->mtx);
|
||||
wakeup(sc);
|
||||
cv_signal(&sc->cv);
|
||||
mtx_unlock(&sc->mtx);
|
||||
}
|
||||
if (sockevent & CBB_SOCKET_EVENT_CSTS) {
|
||||
|
@ -62,7 +62,8 @@ struct pccbb_softc {
|
||||
bus_space_handle_t bsh;
|
||||
u_int8_t secbus;
|
||||
u_int8_t subbus;
|
||||
struct mtx mtx;
|
||||
struct mtx mtx;
|
||||
struct cv cv;
|
||||
u_int32_t flags;
|
||||
#define PCCBB_16BIT_CARD 0x02000000
|
||||
#define PCCBB_KTHREAD_RUNNING 0x04000000
|
||||
|
Loading…
Reference in New Issue
Block a user