/* * Start output on interface. Get another datagram * to send from the interface queue and map it to * the interface before starting output. * * Must be called at spl 5 */ void dmcstart(struct ifnet *ifp) { struct dmc_softc *sc = ifp->if_softc; struct mbuf *m; struct dmcbufs *rp; int n; /* * Dequeue up to NXMT requests and map them to the UNIBUS. * If no more requests, or no dmc buffers available, just return. */ n = 0; for (rp = &sc->sc_xbufs[0]; rp < &sc->sc_xbufs[NXMT]; rp++ ) { /* find an available buffer */ if ((rp->flags & DBUF_DMCS) == 0) { IFQ_DEQUEUE(&sc->sc_if.if_snd, m); if (m == 0) return; /* mark it dmcs */ rp->flags |= (DBUF_DMCS); /* * Have request mapped to UNIBUS for transmission * and start the output. */ rp->cc = if_ubaput(&sc->sc_ifuba, &sc->sc_ifw[n], m); rp->cc &= DMC_CCOUNT; if (++sc->sc_oused == 1) sc->sc_if.if_timer = dmc_timeout; dmcload(sc, DMC_WRITE, rp->ubinfo, rp->cc | ((rp->ubinfo>>2)&DMC_XMEM)); } n++; }
/* * Setup output on interface. * Get another datagram to send off of the interface queue, * and map it to the interface before starting the output. * Must be called from ipl >= our interrupt level. */ void destart(struct ifnet *ifp) { struct de_softc *sc = ifp->if_softc; struct de_cdata *dc; struct de_ring *rp; struct mbuf *m; int nxmit, len; /* * the following test is necessary, since * the code is not reentrant and we have * multiple transmission buffers. */ if (sc->sc_if.if_flags & IFF_OACTIVE) return; dc = sc->sc_dedata; for (nxmit = sc->sc_nxmit; nxmit < NXMT; nxmit++) { IFQ_DEQUEUE(&ifp->if_snd, m); if (m == 0) break; rp = &dc->dc_xrent[sc->sc_xfree]; if (rp->r_flags & XFLG_OWN) panic("deuna xmit in progress"); #if NBPFILTER > 0 if (ifp->if_bpf) bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); #endif len = if_ubaput(&sc->sc_ifuba, &sc->sc_ifw[sc->sc_xfree], m); rp->r_slen = len; rp->r_tdrerr = 0; rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN; sc->sc_xfree++; if (sc->sc_xfree == NXMT) sc->sc_xfree = 0; } if (sc->sc_nxmit != nxmit) { sc->sc_nxmit = nxmit; if (ifp->if_flags & IFF_RUNNING) DE_WLOW(PCSR0_INTE|CMD_PDMD); } }