Deleted Added
full compact
26c26
< * $FreeBSD: head/usr.sbin/bhyve/pci_virtio_block.c 248477 2013-03-18 22:38:30Z neel $
---
> * $FreeBSD: head/usr.sbin/bhyve/pci_virtio_block.c 249813 2013-04-23 16:40:39Z neel $
30c30
< __FBSDID("$FreeBSD: head/usr.sbin/bhyve/pci_virtio_block.c 248477 2013-03-18 22:38:30Z neel $");
---
> __FBSDID("$FreeBSD: head/usr.sbin/bhyve/pci_virtio_block.c 249813 2013-04-23 16:40:39Z neel $");
189a190,196
> sc->vbsc_isr = 0;
> sc->msix_table_idx_req = VIRTIO_MSI_NO_VECTOR;
> sc->msix_table_idx_cfg = VIRTIO_MSI_NO_VECTOR;
> sc->vbsc_features = 0;
> sc->vbsc_pfn = 0;
> sc->vbsc_lastq = 0;
> memset(&sc->vbsc_q, 0, sizeof(struct vring_hqueue));
206d212
< int nsegs;
208c214
< int writeop, type;
---
> int indirect, writeop, type;
218,225c224
< /*
< * Verify that the descriptor is indirect, and obtain
< * the pointer to the indirect descriptor.
< * There has to be space for at least 3 descriptors
< * in the indirect descriptor array: the block header,
< * 1 or more data descriptors, and a status byte.
< */
< assert(vd->vd_flags & VRING_DESC_F_INDIRECT);
---
> indirect = ((vd->vd_flags & VRING_DESC_F_INDIRECT) != 0);
227,229c226,229
< nsegs = vd->vd_len / sizeof(struct virtio_desc);
< assert(nsegs >= 3);
< assert(nsegs < VTBLK_MAXSEGS + 2);
---
> if (indirect) {
> vid = paddr_guest2host(vtblk_ctx(sc), vd->vd_addr, vd->vd_len);
> vd = &vid[0];
> }
231,233d230
< vid = paddr_guest2host(vtblk_ctx(sc), vd->vd_addr, vd->vd_len);
< assert((vid->vd_flags & VRING_DESC_F_INDIRECT) == 0);
<
237c234
< vbh = paddr_guest2host(vtblk_ctx(sc), vid[0].vd_addr,
---
> vbh = paddr_guest2host(vtblk_ctx(sc), vd->vd_addr,
239,241c236,238
< assert(vid[0].vd_len == sizeof(struct virtio_blk_hdr));
< assert(vid[0].vd_flags & VRING_DESC_F_NEXT);
< assert((vid[0].vd_flags & VRING_DESC_F_WRITE) == 0);
---
> assert(vd->vd_len == sizeof(struct virtio_blk_hdr));
> assert(vd->vd_flags & VRING_DESC_F_NEXT);
> assert((vd->vd_flags & VRING_DESC_F_WRITE) == 0);
256,260c253,258
< for (i = 1, iolen = 0; i < nsegs - 1; i++) {
< iov[i-1].iov_base = paddr_guest2host(vtblk_ctx(sc),
< vid[i].vd_addr, vid[i].vd_len);
< iov[i-1].iov_len = vid[i].vd_len;
< iolen += vid[i].vd_len;
---
> i = iolen = 0;
> while (1) {
> if (indirect)
> vd = &vid[i + 1]; /* skip first indirect desc */
> else
> vd = &hq->hq_dtable[vd->vd_next];
262,263c260,261
< assert(vid[i].vd_flags & VRING_DESC_F_NEXT);
< assert((vid[i].vd_flags & VRING_DESC_F_INDIRECT) == 0);
---
> if ((vd->vd_flags & VRING_DESC_F_NEXT) == 0)
> break;
264a263,265
> if (i == VTBLK_MAXSEGS)
> break;
>
271c272
< assert(((vid[i].vd_flags & VRING_DESC_F_WRITE) == 0) ==
---
> assert(((vd->vd_flags & VRING_DESC_F_WRITE) == 0) ==
272a274,280
>
> iov[i].iov_base = paddr_guest2host(vtblk_ctx(sc),
> vd->vd_addr,
> vd->vd_len);
> iov[i].iov_len = vd->vd_len;
> iolen += vd->vd_len;
> i++;
276,279c284,287
< status = paddr_guest2host(vtblk_ctx(sc), vid[nsegs - 1].vd_addr, 1);
< assert(vid[nsegs - 1].vd_len == 1);
< assert((vid[nsegs - 1].vd_flags & VRING_DESC_F_NEXT) == 0);
< assert(vid[nsegs - 1].vd_flags & VRING_DESC_F_WRITE);
---
> status = paddr_guest2host(vtblk_ctx(sc), vd->vd_addr, 1);
> assert(vd->vd_len == 1);
> assert((vd->vd_flags & VRING_DESC_F_NEXT) == 0);
> assert(vd->vd_flags & VRING_DESC_F_WRITE);
282c290
< writeop ? "write" : "read", iolen, nsegs - 2, offset));
---
> writeop ? "write" : "read", iolen, i, offset));
284,288c292,295
< if (writeop){
< err = pwritev(sc->vbsc_fd, iov, nsegs - 2, offset);
< } else {
< err = preadv(sc->vbsc_fd, iov, nsegs - 2, offset);
< }
---
> if (writeop)
> err = pwritev(sc->vbsc_fd, iov, i, offset);
> else
> err = preadv(sc->vbsc_fd, iov, i, offset);
293c300
< * Return the single indirect descriptor back to the host
---
> * Return the single descriptor back to the host
300d306
< }
302,308d307
< static void
< pci_vtblk_qnotify(struct pci_vtblk_softc *sc)
< {
< struct vring_hqueue *hq = &sc->vbsc_q;
< int i;
< int ndescs;
<
310,324d308
< * Calculate number of ring entries to process
< */
< ndescs = hq_num_avail(hq);
<
< if (ndescs == 0)
< return;
<
< /*
< * Run through all the entries, placing them into iovecs and
< * sending when an end-of-packet is found
< */
< for (i = 0; i < ndescs; i++)
< pci_vtblk_proc(sc, hq);
<
< /*
335d318
<
338a322,336
> pci_vtblk_qnotify(struct pci_vtblk_softc *sc)
> {
> struct vring_hqueue *hq = &sc->vbsc_q;
> int ndescs;
>
> while ((ndescs = hq_num_avail(hq)) != 0) {
> /*
> * Run through all the entries, placing them into iovecs and
> * sending when an end-of-packet is found
> */
> pci_vtblk_proc(sc, hq);
> }
> }
>
> static void