static void fwe_output_callback(struct fw_xfer *xfer) { struct fwe_softc *fwe; struct ifnet *ifp; int s; fwe = (struct fwe_softc *)xfer->sc; ifp = fwe->eth_softc.ifp; /* XXX error check */ FWEDEBUG(ifp, "resp = %d\n", xfer->resp); if (xfer->resp != 0) ifp->if_oerrors ++; m_freem(xfer->mbuf); fw_xfer_unload(xfer); s = splimp(); FWE_LOCK(fwe); STAILQ_INSERT_TAIL(&fwe->xferlist, xfer, link); FWE_UNLOCK(fwe); splx(s); /* for queue full */ if (ifp->if_snd.ifq_head != NULL) fwe_start(ifp); }
static int fw_read_async(struct fw_drv1 *d, struct uio *uio, int ioflag) { int err = 0, s; struct fw_xfer *xfer; struct fw_bind *fwb; struct fw_pkt *fp; struct tcode_info *tinfo; FW_GLOCK(d->fc); while ((xfer = STAILQ_FIRST(&d->rq)) == NULL && err == 0) err = msleep(&d->rq, FW_GMTX(d->fc), FWPRI, "fwra", 0); if (err != 0) { FW_GUNLOCK(d->fc); return (err); } s = splfw(); STAILQ_REMOVE_HEAD(&d->rq, link); FW_GUNLOCK(xfer->fc); splx(s); fp = &xfer->recv.hdr; #if 0 /* for GASP ?? */ if (fc->irx_post != NULL) fc->irx_post(fc, fp->mode.ld); #endif tinfo = &xfer->fc->tcode[fp->mode.hdr.tcode]; err = uiomove(fp, tinfo->hdr_len, uio); if (err) goto out; err = uiomove(xfer->recv.payload, xfer->recv.pay_len, uio); out: /* recycle this xfer */ fwb = (struct fw_bind *)xfer->sc; fw_xfer_unload(xfer); xfer->recv.pay_len = PAGE_SIZE; FW_GLOCK(xfer->fc); STAILQ_INSERT_TAIL(&fwb->xferlist, xfer, link); FW_GUNLOCK(xfer->fc); return (err); }