int
vmbus_chan_send(struct vmbus_channel *chan, uint16_t type, uint16_t flags,
    void *data, int dlen, uint64_t xactid)
{
	struct vmbus_chanpkt pkt;
	int pktlen, pad_pktlen, hlen, error;
	uint64_t pad = 0;
	struct iovec iov[3];
	boolean_t send_evt;

	hlen = sizeof(pkt);
	pktlen = hlen + dlen;
	pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen);
	KASSERT(pad_pktlen <= vmbus_txbr_maxpktsz(&chan->ch_txbr),
	    ("invalid packet size %d", pad_pktlen));

	pkt.cp_hdr.cph_type = type;
	pkt.cp_hdr.cph_flags = flags;
	VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_hlen, hlen);
	VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_tlen, pad_pktlen);
	pkt.cp_hdr.cph_xactid = xactid;

	iov[0].iov_base = &pkt;
	iov[0].iov_len = hlen;
	iov[1].iov_base = data;
	iov[1].iov_len = dlen;
	iov[2].iov_base = &pad;
	iov[2].iov_len = pad_pktlen - pktlen;

	error = vmbus_txbr_write(&chan->ch_txbr, iov, 3, &send_evt);
	if (!error && send_evt)
		vmbus_chan_signal_tx(chan);
	return error;
}
Example #2
0
int
vmbus_chan_send_prplist(struct vmbus_channel *chan,
    struct vmbus_gpa_range *prp, int prp_cnt, void *data, int dlen,
    uint64_t xactid)
{
	struct vmbus_chanpkt_prplist pkt;
	int pktlen, pad_pktlen, hlen, error;
	struct iovec iov[4];
	boolean_t send_evt;
	uint64_t pad = 0;

	KASSERT(prp_cnt < VMBUS_CHAN_PRPLIST_MAX,
	    ("invalid prplist entry count %d", prp_cnt));

	hlen = __offsetof(struct vmbus_chanpkt_prplist,
	    cp_range[0].gpa_page[prp_cnt]);
	pktlen = hlen + dlen;
	pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen);

	pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA;
	pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC;
	VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_hlen, hlen);
	VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_tlen, pad_pktlen);
	pkt.cp_hdr.cph_xactid = xactid;
	pkt.cp_rsvd = 0;
	pkt.cp_range_cnt = 1;

	iov[0].iov_base = &pkt;
	iov[0].iov_len = sizeof(pkt);
	iov[1].iov_base = prp;
	iov[1].iov_len = __offsetof(struct vmbus_gpa_range, gpa_page[prp_cnt]);
	iov[2].iov_base = data;
	iov[2].iov_len = dlen;
	iov[3].iov_base = &pad;
	iov[3].iov_len = pad_pktlen - pktlen;

	error = hv_ring_buffer_write(&chan->ch_txbr, iov, 4, &send_evt);
	if (!error && send_evt)
		vmbus_chan_signal_tx(chan);
	return error;
}
Example #3
0
int
vmbus_chan_send_sglist(struct vmbus_channel *chan,
    struct vmbus_gpa sg[], int sglen, void *data, int dlen, uint64_t xactid)
{
	struct vmbus_chanpkt_sglist pkt;
	int pktlen, pad_pktlen, hlen, error;
	struct iovec iov[4];
	boolean_t send_evt;
	uint64_t pad = 0;

	KASSERT(sglen < VMBUS_CHAN_SGLIST_MAX,
	    ("invalid sglist len %d", sglen));

	hlen = __offsetof(struct vmbus_chanpkt_sglist, cp_gpa[sglen]);
	pktlen = hlen + dlen;
	pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen);

	pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA;
	pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC;
	VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_hlen, hlen);
	VMBUS_CHANPKT_SETLEN(pkt.cp_hdr.cph_tlen, pad_pktlen);
	pkt.cp_hdr.cph_xactid = xactid;
	pkt.cp_rsvd = 0;
	pkt.cp_gpa_cnt = sglen;

	iov[0].iov_base = &pkt;
	iov[0].iov_len = sizeof(pkt);
	iov[1].iov_base = sg;
	iov[1].iov_len = sizeof(struct vmbus_gpa) * sglen;
	iov[2].iov_base = data;
	iov[2].iov_len = dlen;
	iov[3].iov_base = &pad;
	iov[3].iov_len = pad_pktlen - pktlen;

	error = hv_ring_buffer_write(&chan->ch_txbr, iov, 4, &send_evt);
	if (!error && send_evt)
		vmbus_chan_signal_tx(chan);
	return error;
}