int viornd_vq_done(struct virtqueue *vq) { struct virtio_softc *vsc = vq->vq_owner; struct viornd_softc *sc = (struct viornd_softc *)vsc->sc_child; int slot, len, i; if (virtio_dequeue(vsc, vq, &slot, &len) != 0) return 0; bus_dmamap_sync(vsc->sc_dmat, sc->sc_dmamap, 0, VIORND_BUFSIZE, BUS_DMASYNC_POSTREAD); if (len > VIORND_BUFSIZE) { printf("%s: inconsistent descriptor length %d > %d\n", sc->sc_dev.dv_xname, len, VIORND_BUFSIZE); goto out; } #if VIORND_DEBUG printf("%s: got %d bytes of entropy\n", __func__, len); #endif for (i = 0; (i + 1) * sizeof(int) <= len; i++) add_true_randomness(sc->sc_buf[i]); if (sc->sc_interval) timeout_add_sec(&sc->sc_tick, sc->sc_interval); out: virtio_dequeue_commit(vq, slot); return 1; }
static int virtioblk_callback(struct virtio_queue *vq) { struct virtioblk_request *req; unsigned int len; while ((req = virtio_dequeue(vq, &len)) != NULL) { req->size = len; mark_thread_ready(req->thread, 1, 2); } return 0; }
static int virtiocon_output_callback(struct virtio_queue *vq) { struct thread *thread; unsigned int len; kprintf("[VCO]"); while ((thread = virtio_dequeue(vq, &len)) != NULL) { mark_thread_ready(thread, 1, 2); } return 0; }
static int virtiocon_input_callback(struct virtio_queue *vq) { char *buf; unsigned int len; int i; //kprintf("[VCI]"); while ((buf = virtio_dequeue(vq, &len)) != NULL) { //kprintf("[vcinp%d:", len); //for (i = 0; i < len; ++i) kprintf("%c", buf[i]); //kprintf("]"); } return 0; }
int viomb_vq_dequeue(struct virtqueue *vq) { struct virtio_softc *vsc = vq->vq_owner; struct viomb_softc *sc = (struct viomb_softc *)vsc->sc_child; int r, slot; r = virtio_dequeue(vsc, vq, &slot, NULL); if (r != 0) { printf("%s: dequeue failed, errno %d\n", DEVNAME(sc), r); return(r); } virtio_dequeue_commit(vq, slot); return(0); }
static int ld_virtio_vq_done(struct virtqueue *vq) { struct virtio_softc *vsc = vq->vq_owner; struct ld_virtio_softc *sc = device_private(vsc->sc_child); int r = 0; int slot; again: if (virtio_dequeue(vsc, vq, &slot, NULL)) return r; r = 1; ld_virtio_vq_done1(sc, vsc, vq, slot); goto again; }
int viocon_tx_drain(struct viocon_port *vp, struct virtqueue *vq) { struct virtio_softc *vsc = vq->vq_owner; int ndone = 0, len, slot; splassert(IPL_TTY); while (virtio_dequeue(vsc, vq, &slot, &len) == 0) { bus_dmamap_sync(vsc->sc_dmat, vp->vp_dmamap, vp->vp_tx_buf - vp->vp_rx_buf + slot * BUFSIZE, BUFSIZE, BUS_DMASYNC_POSTREAD); virtio_dequeue_commit(vq, slot); ndone++; } return ndone; }
void viocon_rx_soft(void *arg) { struct viocon_port *vp = arg; struct virtqueue *vq = vp->vp_rx; struct virtio_softc *vsc = vq->vq_owner; struct tty *tp = vp->vp_tty; int slot, len, i; u_char *p; while (!vp->vp_iflow && virtio_dequeue(vsc, vq, &slot, &len) == 0) { bus_dmamap_sync(vsc->sc_dmat, vp->vp_dmamap, slot * BUFSIZE, BUFSIZE, BUS_DMASYNC_POSTREAD); p = vp->vp_rx_buf + slot * BUFSIZE; for (i = 0; i < len; i++) (*linesw[tp->t_line].l_rint)(*p++, tp); virtio_dequeue_commit(vq, slot); } viocon_rx_fill(vp); return; }
int viornd_vq_done(struct virtqueue *vq) { struct virtio_softc *vsc = vq->vq_owner; struct viornd_softc *sc = device_private(vsc->sc_child); int slot, len; mutex_enter(&sc->sc_mutex); if (virtio_dequeue(vsc, vq, &slot, &len) != 0) { mutex_exit(&sc->sc_mutex); return 0; } sc->sc_active = false; bus_dmamap_sync(vsc->sc_dmat, sc->sc_dmamap, 0, VIORND_BUFSIZE, BUS_DMASYNC_POSTREAD); if (len > VIORND_BUFSIZE) { aprint_error_dev(sc->sc_dev, "inconsistent descriptor length %d > %d\n", len, VIORND_BUFSIZE); goto out; } #if VIORND_DEBUG aprint_normal("%s: got %d bytes of entropy\n", __func__, len); #endif rnd_add_data(&sc->sc_rndsource, sc->sc_buf, VIORND_BUFSIZE, VIORND_BUFSIZE * NBBY); out: virtio_dequeue_commit(vsc, vq, slot); mutex_exit(&sc->sc_mutex); return 1; }
static int vioscsi_vq_done(struct virtqueue *vq) { struct virtio_softc *vsc = vq->vq_owner; struct vioscsi_softc *sc = device_private(vsc->sc_child); int ret = 0; DPRINTF(("%s: enter\n", __func__)); for (;;) { int r, slot; r = virtio_dequeue(vsc, vq, &slot, NULL); if (r != 0) break; DPRINTF(("%s: slot=%d\n", __func__, slot)); vioscsi_req_done(sc, vsc, &sc->sc_reqs[slot]); ret = 1; } DPRINTF(("%s: exit %d\n", __func__, ret)); return ret; }
static int ld_virtio_dump(struct ld_softc *ld, void *data, int blkno, int blkcnt) { struct ld_virtio_softc *sc = device_private(ld->sc_dv); struct virtio_softc *vsc = sc->sc_virtio; struct virtqueue *vq = &sc->sc_vq; struct virtio_blk_req *vr; int slot, r; if (sc->sc_readonly) return EIO; r = virtio_enqueue_prep(vsc, vq, &slot); if (r != 0) { if (r == EAGAIN) { /* no free slot; dequeue first */ delay(100); ld_virtio_vq_done(vq); r = virtio_enqueue_prep(vsc, vq, &slot); if (r != 0) return r; } return r; } vr = &sc->sc_reqs[slot]; r = bus_dmamap_load(vsc->sc_dmat, vr->vr_payload, data, blkcnt*ld->sc_secsize, NULL, BUS_DMA_WRITE|BUS_DMA_NOWAIT); if (r != 0) return r; r = virtio_enqueue_reserve(vsc, vq, slot, vr->vr_payload->dm_nsegs + VIRTIO_BLK_MIN_SEGMENTS); if (r != 0) { bus_dmamap_unload(vsc->sc_dmat, vr->vr_payload); return r; } vr->vr_bp = (void*)0xdeadbeef; vr->vr_hdr.type = VIRTIO_BLK_T_OUT; vr->vr_hdr.ioprio = 0; vr->vr_hdr.sector = (daddr_t) blkno * ld->sc_secsize / 512; bus_dmamap_sync(vsc->sc_dmat, vr->vr_cmdsts, 0, sizeof(struct virtio_blk_req_hdr), BUS_DMASYNC_PREWRITE); bus_dmamap_sync(vsc->sc_dmat, vr->vr_payload, 0, blkcnt*ld->sc_secsize, BUS_DMASYNC_PREWRITE); bus_dmamap_sync(vsc->sc_dmat, vr->vr_cmdsts, offsetof(struct virtio_blk_req, vr_status), sizeof(uint8_t), BUS_DMASYNC_PREREAD); virtio_enqueue_p(vsc, vq, slot, vr->vr_cmdsts, 0, sizeof(struct virtio_blk_req_hdr), true); virtio_enqueue(vsc, vq, slot, vr->vr_payload, true); virtio_enqueue_p(vsc, vq, slot, vr->vr_cmdsts, offsetof(struct virtio_blk_req, vr_status), sizeof(uint8_t), false); virtio_enqueue_commit(vsc, vq, slot, true); for ( ; ; ) { int dslot; r = virtio_dequeue(vsc, vq, &dslot, NULL); if (r != 0) continue; if (dslot != slot) { ld_virtio_vq_done1(sc, vsc, vq, dslot); continue; } else break; } bus_dmamap_sync(vsc->sc_dmat, vr->vr_cmdsts, 0, sizeof(struct virtio_blk_req_hdr), BUS_DMASYNC_POSTWRITE); bus_dmamap_sync(vsc->sc_dmat, vr->vr_payload, 0, blkcnt*ld->sc_secsize, BUS_DMASYNC_POSTWRITE); bus_dmamap_sync(vsc->sc_dmat, vr->vr_cmdsts, offsetof(struct virtio_blk_req, vr_status), sizeof(uint8_t), BUS_DMASYNC_POSTREAD); if (vr->vr_status == VIRTIO_BLK_S_OK) r = 0; else r = EIO; virtio_dequeue_commit(vsc, vq, slot); return r; }