From 1f3992c083c6ff3c1e7b5776412b4570277d7539 Mon Sep 17 00:00:00 2001 From: mikeb Date: Wed, 14 Jun 2017 09:47:37 +0000 Subject: [PATCH] Add another type of a scatter-gather list operation used by StorVSC Obtained from FreeBSD. --- sys/dev/pv/hyperv.c | 44 ++++++++++++++++++++++++++++++++++++++++++ sys/dev/pv/hypervvar.h | 2 ++ 2 files changed, 46 insertions(+) diff --git a/sys/dev/pv/hyperv.c b/sys/dev/pv/hyperv.c index 2d0a38fabc7..f9840e87113 100644 --- a/sys/dev/pv/hyperv.c +++ b/sys/dev/pv/hyperv.c @@ -1402,6 +1402,50 @@ hv_channel_send_sgl(struct hv_channel *ch, struct vmbus_gpa *sgl, return (rv); } +int +hv_channel_send_prpl(struct hv_channel *ch, struct vmbus_gpa_range *prpl, + uint32_t nprp, void *data, uint32_t datalen, uint64_t rid) +{ + struct hv_softc *sc = ch->ch_sc; + struct vmbus_chanpkt_prplist cp; + struct iovec iov[4]; + uint32_t buflen, pktlen, pktlen_aligned; + uint64_t zeropad = 0; + int rv, needsig = 0; + + buflen = sizeof(struct vmbus_gpa_range) * (nprp + 1); + pktlen = sizeof(cp) + datalen + buflen; + pktlen_aligned = roundup(pktlen, sizeof(uint64_t)); + + cp.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA; + cp.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC; + VMBUS_CHANPKT_SETLEN(cp.cp_hdr.cph_hlen, sizeof(cp) + buflen); + VMBUS_CHANPKT_SETLEN(cp.cp_hdr.cph_tlen, pktlen_aligned); + cp.cp_hdr.cph_tid = rid; + cp.cp_range_cnt = 1; + cp.cp_rsvd = 0; + + iov[0].iov_base = &cp; + iov[0].iov_len = sizeof(cp); + + iov[1].iov_base = prpl; + iov[1].iov_len = buflen; + + iov[2].iov_base = data; + iov[2].iov_len = datalen; + + iov[3].iov_base = &zeropad; + iov[3].iov_len = pktlen_aligned - pktlen; + + mtx_enter(&ch->ch_wrd.rd_lock); + rv = hv_ring_write(&ch->ch_wrd, iov, 4, &needsig); + mtx_leave(&ch->ch_wrd.rd_lock); + if (rv == 0 && needsig) + hv_channel_setevent(sc, ch); + + return (rv); +} + int hv_ring_peek(struct hv_ring_data *rrd, void *data, uint32_t datalen) { diff --git a/sys/dev/pv/hypervvar.h b/sys/dev/pv/hypervvar.h index 425431bb406..3305a4459d6 100644 --- a/sys/dev/pv/hypervvar.h +++ b/sys/dev/pv/hypervvar.h @@ -212,6 +212,8 @@ int hv_channel_send(struct hv_channel *, void *, uint32_t, uint64_t, int, uint32_t); int hv_channel_send_sgl(struct hv_channel *, struct vmbus_gpa *, uint32_t, void *, uint32_t, uint64_t); +int hv_channel_send_prpl(struct hv_channel *, struct vmbus_gpa_range *, + uint32_t, void *, uint32_t, uint64_t); int hv_channel_recv(struct hv_channel *, void *, uint32_t, uint32_t *, uint64_t *, int); -- 2.20.1