--- a/sys/dev/misc/lpt/lpt.c +++ b/sys/dev/misc/lpt/lpt.c @@ -109,6 +109,7 @@ #define LPTFLAGS(s) ((s)&0xfc) struct lpt_data { + struct spinlock sc_openlk; /* serializes open/close transitions */ short sc_state; /* default case: negative prime, negative ack, handshake strobe, prime once */ @@ -365,6 +366,7 @@ uintptr_t irq; sc->sc_primed = 0; /* not primed yet */ + spin_init(&sc->sc_openlk); callout_init(&sc->sc_callout); if ((error = lpt_request_ppbus(dev, PPB_DONTWAIT))) { @@ -455,11 +457,14 @@ if (!sc) return (ENXIO); + spin_lock(&sc->sc_openlk); if (sc->sc_state) { + spin_unlock(&sc->sc_openlk); lprintf((LPT_NAME ": still open %x\n", sc->sc_state)); return(EBUSY); - } else - sc->sc_state |= LPTINIT; + } + sc->sc_state |= LPTINIT; + spin_unlock(&sc->sc_openlk); sc->sc_flags = LPTFLAGS(minor(dev)); @@ -595,8 +600,12 @@ } callout_stop(&sc->sc_callout); ppb_wctr(ppbus, LPC_NINIT); + spin_lock(&sc->sc_openlk); kfree(sc->sc_inbuf, M_LPT); + sc->sc_inbuf = NULL; kfree(sc->sc_statbuf, M_LPT); + sc->sc_statbuf = NULL; + spin_unlock(&sc->sc_openlk); end_close: /* release the bus anyway