예제 #1
0
파일: viornd.c 프로젝트: ajinkya93/OpenBSD
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;
}
예제 #2
0
파일: virtioblk.c 프로젝트: HarryR/sanos
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;
}
예제 #3
0
파일: virtiocon.c 프로젝트: HarryR/sanos
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;
}
예제 #4
0
파일: virtiocon.c 프로젝트: HarryR/sanos
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;
}
예제 #5
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);
}
예제 #6
0
파일: ld_virtio.c 프로젝트: ryo/netbsd-src
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;
}
예제 #7
0
파일: viocon.c 프로젝트: ajinkya93/OpenBSD
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;
}
예제 #8
0
파일: viocon.c 프로젝트: ajinkya93/OpenBSD
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;
}
예제 #9
0
파일: viornd.c 프로젝트: ryo/netbsd-src
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;
}
예제 #10
0
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;
}
예제 #11
0
파일: ld_virtio.c 프로젝트: ryo/netbsd-src
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;
}