/* Stop the adapter and free any mbufs allocated to the RX and TX buffers */ static void sln_stop(struct sln_softc *sc) { struct ifnet *ifp = &sc->arpcom.ac_if; uint32_t intr_status; int i; ASSERT_SERIALIZED(ifp->if_serializer); ifp->if_timer = 0; callout_stop(&sc->sln_state); /* disable Tx/Rx */ sc->txcfg &= ~SL_TXCFG_EN; sc->rxcfg &= ~SL_RXCFG_EN; SLN_WRITE_4(sc, SL_TX_CONFIG, sc->txcfg); SLN_WRITE_4(sc, SL_RX_CONFIG, sc->rxcfg); /* Clear interrupt */ SLN_WRITE_4(sc, SL_INT_MASK, 0); intr_status = SLN_READ_4(sc, SL_INT_STATUS); /* Free the TX list buffers */ for (i = 0; i < SL_TXD_CNT; i++) { if (sc->sln_bufdata.sln_tx_buf[i] != NULL) { m_freem(sc->sln_bufdata.sln_tx_buf[i]); sc->sln_bufdata.sln_tx_buf[i] = NULL; SLN_WRITE_4(sc, SL_TSAD0 + i * 4, 0); } } ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); }
static void lwkt_serialize_replyport(lwkt_port_t port, lwkt_msg_t msg) { KKASSERT((msg->ms_flags & (MSGF_DONE|MSGF_QUEUED)) == 0); ASSERT_SERIALIZED(port->mpu_serialize); if (msg->ms_flags & MSGF_SYNC) { /* * If a synchronous completion has been requested, just wakeup * the message without bothering to queue it to the target port. * * (both sides synchronized via serialized reply port) */ msg->ms_flags |= MSGF_DONE | MSGF_REPLY; wakeup(msg); } else { /* * If an asynchronous completion has been requested the message * must be queued to the reply port. */ _lwkt_enqueue_reply(port, msg); if (port->mp_flags & MSGPORTF_WAITING) { port->mp_flags &= ~MSGPORTF_WAITING; wakeup(port); } } }
/* * Similar to handler_call but does not block. Returns 0 on success, * and 1 on failure. */ int lwkt_serialize_handler_try(lwkt_serialize_t s, void (*func)(void *, void *), void *arg, void *frame) { /* * note: a return value of 0 indicates that the interrupt handler is * enabled. */ if (atomic_intr_handler_is_enabled(&s->interlock) == 0) { logslz(try, s); if (atomic_intr_cond_try(&s->interlock) == 0) { #ifdef INVARIANTS s->last_td = curthread; #endif logslz(tryok, s); func(arg, frame); ASSERT_SERIALIZED(s); #ifdef INVARIANTS s->last_td = (void *)-2; #endif logslz(exit_beg, s); atomic_intr_cond_exit(&s->interlock, lwkt_serialize_wakeup, s); logslz(exit_end, s); return(0); } }
void lwkt_serialize_exit(lwkt_serialize_t s) { ASSERT_SERIALIZED(s); #ifdef INVARIANTS s->last_td = (void *)-2; #endif logslz(exit_beg, s); atomic_intr_cond_exit(&s->interlock, lwkt_serialize_wakeup, s); logslz(exit_end, s); }
static void * lwkt_serialize_getport(lwkt_port_t port) { lwkt_msg_t msg; ASSERT_SERIALIZED(port->mpu_serialize); if ((msg = _lwkt_pollmsg(port)) != NULL) _lwkt_pullmsg(port, msg); return(msg); }
static int lwkt_serialize_putport(lwkt_port_t port, lwkt_msg_t msg) { KKASSERT((msg->ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0); ASSERT_SERIALIZED(port->mpu_serialize); msg->ms_target_port = port; _lwkt_pushmsg(port, msg); if (port->mp_flags & MSGPORTF_WAITING) { port->mp_flags &= ~MSGPORTF_WAITING; wakeup(port); } return (EASYNC); }
static void * lwkt_serialize_waitport(lwkt_port_t port, int flags) { lwkt_msg_t msg; int error; ASSERT_SERIALIZED(port->mpu_serialize); while ((msg = _lwkt_pollmsg(port)) == NULL) { port->mp_flags |= MSGPORTF_WAITING; error = zsleep(port, port->mpu_serialize, flags, "waitport", 0); /* see note at the top on the MSGPORTF_WAITING flag */ if (error) return(NULL); } _lwkt_pullmsg(port, msg); return(msg); }
static int lwkt_serialize_waitmsg(lwkt_msg_t msg, int flags) { lwkt_port_t port; int sentabort; int error; KASSERT((msg->ms_flags & MSGF_DROPABLE) == 0, ("can't wait dropable message")); if ((msg->ms_flags & MSGF_DONE) == 0) { port = msg->ms_reply_port; ASSERT_SERIALIZED(port->mpu_serialize); sentabort = 0; while ((msg->ms_flags & MSGF_DONE) == 0) { void *won; /* * If message was sent synchronously from the beginning * the wakeup will be on the message structure, else it * will be on the port structure. */ if (msg->ms_flags & MSGF_SYNC) { won = msg; } else { won = port; port->mp_flags |= MSGPORTF_WAITING; } /* * Only messages which support abort can be interrupted. * We must still wait for message completion regardless. */ if ((flags & PCATCH) && sentabort == 0) { error = zsleep(won, port->mpu_serialize, PCATCH, "waitmsg", 0); if (error) { sentabort = error; lwkt_serialize_exit(port->mpu_serialize); lwkt_abortmsg(msg); lwkt_serialize_enter(port->mpu_serialize); } } else { error = zsleep(won, port->mpu_serialize, 0, "waitmsg", 0); } /* see note at the top on the MSGPORTF_WAITING flag */ } /* * Turn EINTR into ERESTART if the signal indicates. */ if (sentabort && msg->ms_error == EINTR) msg->ms_error = sentabort; if (msg->ms_flags & MSGF_QUEUED) _lwkt_pullmsg(port, msg); } else { if (msg->ms_flags & MSGF_QUEUED) { port = msg->ms_reply_port; ASSERT_SERIALIZED(port->mpu_serialize); _lwkt_pullmsg(port, msg); } } return(msg->ms_error); }