예제 #1
0
/* 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);
}
예제 #2
0
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);
        }
    }
}
예제 #3
0
/*
 * 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);
	}
    }
예제 #4
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);
}
예제 #5
0
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);
}
예제 #6
0
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);
}
예제 #7
0
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);
}
예제 #8
0
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);
}