Beispiel #1
0
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;
}
Beispiel #2
0
static void
ld_virtio_vq_done1(struct ld_virtio_softc *sc, struct virtio_softc *vsc,
		   struct virtqueue *vq, int slot)
{
	struct virtio_blk_req *vr = &sc->sc_reqs[slot];
	struct buf *bp = vr->vr_bp;

	vr->vr_bp = NULL;

	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, bp->b_bcount,
			(bp->b_flags & B_READ)?BUS_DMASYNC_POSTREAD
					      :BUS_DMASYNC_POSTWRITE);
	bus_dmamap_sync(vsc->sc_dmat, vr->vr_cmdsts,
			sizeof(struct virtio_blk_req_hdr), sizeof(uint8_t),
			BUS_DMASYNC_POSTREAD);

	if (vr->vr_status != VIRTIO_BLK_S_OK) {
		bp->b_error = EIO;
		bp->b_resid = bp->b_bcount;
	} else {
		bp->b_error = 0;
		bp->b_resid = 0;
	}

	virtio_dequeue_commit(vsc, vq, slot);

	lddone(&sc->sc_ld, bp);
}
Beispiel #3
0
static void
vioscsi_req_put(struct vioscsi_softc *sc, struct vioscsi_req *vr)
{
	struct virtio_softc *vsc = device_private(device_parent(sc->sc_dev));
	struct virtqueue *vq = &sc->sc_vqs[2];
	int slot = vr - sc->sc_reqs;

	DPRINTF(("%s: %p, %d\n", __func__, vr, slot));

	bus_dmamap_destroy(vsc->sc_dmat, vr->vr_control);
	bus_dmamap_destroy(vsc->sc_dmat, vr->vr_data);

	virtio_dequeue_commit(vsc, vq, slot);
}
Beispiel #4
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);
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}