xref: /freebsd/sys/dev/hyperv/utilities/vmbus_ic.c (revision fdafd315ad0d0f28a11b9fb4476a9ab059c62b92)
19ff08654SSepherosa Ziehau /*-
29ff08654SSepherosa Ziehau  * Copyright (c) 2014,2016 Microsoft Corp.
39ff08654SSepherosa Ziehau  * All rights reserved.
49ff08654SSepherosa Ziehau  *
59ff08654SSepherosa Ziehau  * Redistribution and use in source and binary forms, with or without
69ff08654SSepherosa Ziehau  * modification, are permitted provided that the following conditions
79ff08654SSepherosa Ziehau  * are met:
89ff08654SSepherosa Ziehau  * 1. Redistributions of source code must retain the above copyright
99ff08654SSepherosa Ziehau  *    notice unmodified, this list of conditions, and the following
109ff08654SSepherosa Ziehau  *    disclaimer.
119ff08654SSepherosa Ziehau  * 2. Redistributions in binary form must reproduce the above copyright
129ff08654SSepherosa Ziehau  *    notice, this list of conditions and the following disclaimer in the
139ff08654SSepherosa Ziehau  *    documentation and/or other materials provided with the distribution.
149ff08654SSepherosa Ziehau  *
159ff08654SSepherosa Ziehau  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
169ff08654SSepherosa Ziehau  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
179ff08654SSepherosa Ziehau  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
189ff08654SSepherosa Ziehau  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
199ff08654SSepherosa Ziehau  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
209ff08654SSepherosa Ziehau  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
219ff08654SSepherosa Ziehau  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
229ff08654SSepherosa Ziehau  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
239ff08654SSepherosa Ziehau  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
249ff08654SSepherosa Ziehau  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
259ff08654SSepherosa Ziehau  */
269ff08654SSepherosa Ziehau 
279ff08654SSepherosa Ziehau #include <sys/param.h>
289ff08654SSepherosa Ziehau #include <sys/bus.h>
299ff08654SSepherosa Ziehau #include <sys/malloc.h>
309ff08654SSepherosa Ziehau #include <sys/systm.h>
319ff08654SSepherosa Ziehau #include <sys/sysctl.h>
329ff08654SSepherosa Ziehau 
339ff08654SSepherosa Ziehau #include <dev/hyperv/include/hyperv.h>
349ff08654SSepherosa Ziehau #include <dev/hyperv/include/vmbus.h>
359ff08654SSepherosa Ziehau #include <dev/hyperv/utilities/vmbus_icreg.h>
369ff08654SSepherosa Ziehau #include <dev/hyperv/utilities/vmbus_icvar.h>
379ff08654SSepherosa Ziehau 
389ff08654SSepherosa Ziehau #include "vmbus_if.h"
399ff08654SSepherosa Ziehau 
409ff08654SSepherosa Ziehau #define VMBUS_IC_BRSIZE		(4 * PAGE_SIZE)
419ff08654SSepherosa Ziehau 
429ff08654SSepherosa Ziehau #define VMBUS_IC_VERCNT		2
439ff08654SSepherosa Ziehau #define VMBUS_IC_NEGOSZ		\
449ff08654SSepherosa Ziehau 	__offsetof(struct vmbus_icmsg_negotiate, ic_ver[VMBUS_IC_VERCNT])
459ff08654SSepherosa Ziehau CTASSERT(VMBUS_IC_NEGOSZ < VMBUS_IC_BRSIZE);
469ff08654SSepherosa Ziehau 
479ff08654SSepherosa Ziehau static int	vmbus_ic_fwver_sysctl(SYSCTL_HANDLER_ARGS);
489ff08654SSepherosa Ziehau static int	vmbus_ic_msgver_sysctl(SYSCTL_HANDLER_ARGS);
499ff08654SSepherosa Ziehau 
509ff08654SSepherosa Ziehau int
vmbus_ic_negomsg(struct vmbus_ic_softc * sc,void * data,int * dlen0,uint32_t fw_ver,uint32_t msg_ver)519ff08654SSepherosa Ziehau vmbus_ic_negomsg(struct vmbus_ic_softc *sc, void *data, int *dlen0,
529ff08654SSepherosa Ziehau     uint32_t fw_ver, uint32_t msg_ver)
539ff08654SSepherosa Ziehau {
549ff08654SSepherosa Ziehau 	struct vmbus_icmsg_negotiate *nego;
559ff08654SSepherosa Ziehau 	int i, cnt, dlen = *dlen0, error;
569ff08654SSepherosa Ziehau 	uint32_t sel_fw_ver, sel_msg_ver;
579ff08654SSepherosa Ziehau 	bool has_fw_ver, has_msg_ver;
589ff08654SSepherosa Ziehau 
59*b086426bSRobert Herndon 	has_fw_ver = false;
60*b086426bSRobert Herndon 	has_msg_ver = false;
61*b086426bSRobert Herndon 
629ff08654SSepherosa Ziehau 	/*
639ff08654SSepherosa Ziehau 	 * Preliminary message verification.
649ff08654SSepherosa Ziehau 	 */
659ff08654SSepherosa Ziehau 	if (dlen < sizeof(*nego)) {
669ff08654SSepherosa Ziehau 		device_printf(sc->ic_dev, "truncated ic negotiate, len %d\n",
679ff08654SSepherosa Ziehau 		    dlen);
689ff08654SSepherosa Ziehau 		return (EINVAL);
699ff08654SSepherosa Ziehau 	}
709ff08654SSepherosa Ziehau 	nego = data;
719ff08654SSepherosa Ziehau 
729ff08654SSepherosa Ziehau 	if (nego->ic_fwver_cnt == 0) {
739ff08654SSepherosa Ziehau 		device_printf(sc->ic_dev, "ic negotiate does not contain "
749ff08654SSepherosa Ziehau 		    "framework version %u\n", nego->ic_fwver_cnt);
759ff08654SSepherosa Ziehau 		return (EINVAL);
769ff08654SSepherosa Ziehau 	}
779ff08654SSepherosa Ziehau 	if (nego->ic_msgver_cnt == 0) {
789ff08654SSepherosa Ziehau 		device_printf(sc->ic_dev, "ic negotiate does not contain "
799ff08654SSepherosa Ziehau 		    "message version %u\n", nego->ic_msgver_cnt);
809ff08654SSepherosa Ziehau 		return (EINVAL);
819ff08654SSepherosa Ziehau 	}
829ff08654SSepherosa Ziehau 
839ff08654SSepherosa Ziehau 	cnt = nego->ic_fwver_cnt + nego->ic_msgver_cnt;
849ff08654SSepherosa Ziehau 	if (dlen < __offsetof(struct vmbus_icmsg_negotiate, ic_ver[cnt])) {
859ff08654SSepherosa Ziehau 		device_printf(sc->ic_dev, "ic negotiate does not contain "
869ff08654SSepherosa Ziehau 		    "versions %d\n", dlen);
879ff08654SSepherosa Ziehau 		return (EINVAL);
889ff08654SSepherosa Ziehau 	}
899ff08654SSepherosa Ziehau 
909ff08654SSepherosa Ziehau 	error = EOPNOTSUPP;
919ff08654SSepherosa Ziehau 
929ff08654SSepherosa Ziehau 	/*
939ff08654SSepherosa Ziehau 	 * Find the best match framework version.
949ff08654SSepherosa Ziehau 	 */
959ff08654SSepherosa Ziehau 	for (i = 0; i < nego->ic_fwver_cnt; ++i) {
969ff08654SSepherosa Ziehau 		if (VMBUS_ICVER_LE(nego->ic_ver[i], fw_ver)) {
979ff08654SSepherosa Ziehau 			if (!has_fw_ver) {
989ff08654SSepherosa Ziehau 				sel_fw_ver = nego->ic_ver[i];
999ff08654SSepherosa Ziehau 				has_fw_ver = true;
1009ff08654SSepherosa Ziehau 			} else if (VMBUS_ICVER_GT(nego->ic_ver[i],
1019ff08654SSepherosa Ziehau 			    sel_fw_ver)) {
1029ff08654SSepherosa Ziehau 				sel_fw_ver = nego->ic_ver[i];
1039ff08654SSepherosa Ziehau 			}
1049ff08654SSepherosa Ziehau 		}
1059ff08654SSepherosa Ziehau 	}
1069ff08654SSepherosa Ziehau 	if (!has_fw_ver) {
1079ff08654SSepherosa Ziehau 		device_printf(sc->ic_dev, "failed to select framework "
1089ff08654SSepherosa Ziehau 		    "version\n");
1099ff08654SSepherosa Ziehau 		goto done;
1109ff08654SSepherosa Ziehau 	}
1119ff08654SSepherosa Ziehau 
1129ff08654SSepherosa Ziehau 	/*
113*b086426bSRobert Herndon 	 * Find the best match message version.
1149ff08654SSepherosa Ziehau 	 */
1159ff08654SSepherosa Ziehau 	for (i = nego->ic_fwver_cnt;
1169ff08654SSepherosa Ziehau 	    i < nego->ic_fwver_cnt + nego->ic_msgver_cnt; ++i) {
1179ff08654SSepherosa Ziehau 		if (VMBUS_ICVER_LE(nego->ic_ver[i], msg_ver)) {
1189ff08654SSepherosa Ziehau 			if (!has_msg_ver) {
1199ff08654SSepherosa Ziehau 				sel_msg_ver = nego->ic_ver[i];
1209ff08654SSepherosa Ziehau 				has_msg_ver = true;
1219ff08654SSepherosa Ziehau 			} else if (VMBUS_ICVER_GT(nego->ic_ver[i],
1229ff08654SSepherosa Ziehau 			    sel_msg_ver)) {
1239ff08654SSepherosa Ziehau 				sel_msg_ver = nego->ic_ver[i];
1249ff08654SSepherosa Ziehau 			}
1259ff08654SSepherosa Ziehau 		}
1269ff08654SSepherosa Ziehau 	}
1279ff08654SSepherosa Ziehau 	if (!has_msg_ver) {
1289ff08654SSepherosa Ziehau 		device_printf(sc->ic_dev, "failed to select message "
1299ff08654SSepherosa Ziehau 		    "version\n");
1309ff08654SSepherosa Ziehau 		goto done;
1319ff08654SSepherosa Ziehau 	}
1329ff08654SSepherosa Ziehau 
1339ff08654SSepherosa Ziehau 	error = 0;
1349ff08654SSepherosa Ziehau done:
1359ff08654SSepherosa Ziehau 	if (bootverbose || !has_fw_ver || !has_msg_ver) {
1369ff08654SSepherosa Ziehau 		if (has_fw_ver) {
1379ff08654SSepherosa Ziehau 			device_printf(sc->ic_dev, "sel framework version: "
1389ff08654SSepherosa Ziehau 			    "%u.%u\n",
1399ff08654SSepherosa Ziehau 			    VMBUS_ICVER_MAJOR(sel_fw_ver),
1409ff08654SSepherosa Ziehau 			    VMBUS_ICVER_MINOR(sel_fw_ver));
1419ff08654SSepherosa Ziehau 		}
1429ff08654SSepherosa Ziehau 		for (i = 0; i < nego->ic_fwver_cnt; i++) {
1439ff08654SSepherosa Ziehau 			device_printf(sc->ic_dev, "supp framework version: "
1449ff08654SSepherosa Ziehau 			    "%u.%u\n",
1459ff08654SSepherosa Ziehau 			    VMBUS_ICVER_MAJOR(nego->ic_ver[i]),
1469ff08654SSepherosa Ziehau 			    VMBUS_ICVER_MINOR(nego->ic_ver[i]));
1479ff08654SSepherosa Ziehau 		}
1489ff08654SSepherosa Ziehau 
1499ff08654SSepherosa Ziehau 		if (has_msg_ver) {
1509ff08654SSepherosa Ziehau 			device_printf(sc->ic_dev, "sel message version: "
1519ff08654SSepherosa Ziehau 			    "%u.%u\n",
1529ff08654SSepherosa Ziehau 			    VMBUS_ICVER_MAJOR(sel_msg_ver),
1539ff08654SSepherosa Ziehau 			    VMBUS_ICVER_MINOR(sel_msg_ver));
1549ff08654SSepherosa Ziehau 		}
1559ff08654SSepherosa Ziehau 		for (i = nego->ic_fwver_cnt;
1569ff08654SSepherosa Ziehau 		    i < nego->ic_fwver_cnt + nego->ic_msgver_cnt; i++) {
1579ff08654SSepherosa Ziehau 			device_printf(sc->ic_dev, "supp message version: "
1589ff08654SSepherosa Ziehau 			    "%u.%u\n",
1599ff08654SSepherosa Ziehau 			    VMBUS_ICVER_MAJOR(nego->ic_ver[i]),
1609ff08654SSepherosa Ziehau 			    VMBUS_ICVER_MINOR(nego->ic_ver[i]));
1619ff08654SSepherosa Ziehau 		}
1629ff08654SSepherosa Ziehau 	}
1639ff08654SSepherosa Ziehau 	if (error)
1649ff08654SSepherosa Ziehau 		return (error);
1659ff08654SSepherosa Ziehau 
1669ff08654SSepherosa Ziehau 	/* Record the selected versions. */
1679ff08654SSepherosa Ziehau 	sc->ic_fwver = sel_fw_ver;
1689ff08654SSepherosa Ziehau 	sc->ic_msgver = sel_msg_ver;
1699ff08654SSepherosa Ziehau 
1709ff08654SSepherosa Ziehau 	/* One framework version. */
1719ff08654SSepherosa Ziehau 	nego->ic_fwver_cnt = 1;
1729ff08654SSepherosa Ziehau 	nego->ic_ver[0] = sel_fw_ver;
1739ff08654SSepherosa Ziehau 
1749ff08654SSepherosa Ziehau 	/* One message version. */
1759ff08654SSepherosa Ziehau 	nego->ic_msgver_cnt = 1;
1769ff08654SSepherosa Ziehau 	nego->ic_ver[1] = sel_msg_ver;
1779ff08654SSepherosa Ziehau 
1789ff08654SSepherosa Ziehau 	/* Update data size. */
1799ff08654SSepherosa Ziehau 	nego->ic_hdr.ic_dsize = VMBUS_IC_NEGOSZ -
1809ff08654SSepherosa Ziehau 	    sizeof(struct vmbus_icmsg_hdr);
1819ff08654SSepherosa Ziehau 
1829ff08654SSepherosa Ziehau 	/* Update total size, if necessary. */
1839ff08654SSepherosa Ziehau 	if (dlen < VMBUS_IC_NEGOSZ)
1849ff08654SSepherosa Ziehau 		*dlen0 = VMBUS_IC_NEGOSZ;
1859ff08654SSepherosa Ziehau 
1869ff08654SSepherosa Ziehau 	return (0);
1879ff08654SSepherosa Ziehau }
1889ff08654SSepherosa Ziehau 
1899ff08654SSepherosa Ziehau int
vmbus_ic_probe(device_t dev,const struct vmbus_ic_desc descs[])1909ff08654SSepherosa Ziehau vmbus_ic_probe(device_t dev, const struct vmbus_ic_desc descs[])
1919ff08654SSepherosa Ziehau {
1929ff08654SSepherosa Ziehau 	device_t bus = device_get_parent(dev);
1939ff08654SSepherosa Ziehau 	const struct vmbus_ic_desc *d;
1949ff08654SSepherosa Ziehau 
1959ff08654SSepherosa Ziehau 	if (resource_disabled(device_get_name(dev), 0))
1969ff08654SSepherosa Ziehau 		return (ENXIO);
1979ff08654SSepherosa Ziehau 
1989ff08654SSepherosa Ziehau 	for (d = descs; d->ic_desc != NULL; ++d) {
1999ff08654SSepherosa Ziehau 		if (VMBUS_PROBE_GUID(bus, dev, &d->ic_guid) == 0) {
2009ff08654SSepherosa Ziehau 			device_set_desc(dev, d->ic_desc);
2019ff08654SSepherosa Ziehau 			return (BUS_PROBE_DEFAULT);
2029ff08654SSepherosa Ziehau 		}
2039ff08654SSepherosa Ziehau 	}
2049ff08654SSepherosa Ziehau 	return (ENXIO);
2059ff08654SSepherosa Ziehau }
2069ff08654SSepherosa Ziehau 
2079ff08654SSepherosa Ziehau int
vmbus_ic_attach(device_t dev,vmbus_chan_callback_t cb)2089ff08654SSepherosa Ziehau vmbus_ic_attach(device_t dev, vmbus_chan_callback_t cb)
2099ff08654SSepherosa Ziehau {
2109ff08654SSepherosa Ziehau 	struct vmbus_ic_softc *sc = device_get_softc(dev);
2119ff08654SSepherosa Ziehau 	struct vmbus_channel *chan = vmbus_get_channel(dev);
2129ff08654SSepherosa Ziehau 	struct sysctl_oid_list *child;
2139ff08654SSepherosa Ziehau 	struct sysctl_ctx_list *ctx;
2149ff08654SSepherosa Ziehau 	int error;
2159ff08654SSepherosa Ziehau 
2169ff08654SSepherosa Ziehau 	sc->ic_dev = dev;
2179ff08654SSepherosa Ziehau 	sc->ic_buflen = VMBUS_IC_BRSIZE;
2189ff08654SSepherosa Ziehau 	sc->ic_buf = malloc(VMBUS_IC_BRSIZE, M_DEVBUF, M_WAITOK | M_ZERO);
2199ff08654SSepherosa Ziehau 
2209ff08654SSepherosa Ziehau 	/*
2219ff08654SSepherosa Ziehau 	 * These services are not performance critical and do not need
2229ff08654SSepherosa Ziehau 	 * batched reading. Furthermore, some services such as KVP can
2239ff08654SSepherosa Ziehau 	 * only handle one message from the host at a time.
2249ff08654SSepherosa Ziehau 	 * Turn off batched reading for all util drivers before we open the
2259ff08654SSepherosa Ziehau 	 * channel.
2269ff08654SSepherosa Ziehau 	 */
2279ff08654SSepherosa Ziehau 	vmbus_chan_set_readbatch(chan, false);
2289ff08654SSepherosa Ziehau 
2299ff08654SSepherosa Ziehau 	error = vmbus_chan_open(chan, VMBUS_IC_BRSIZE, VMBUS_IC_BRSIZE, NULL, 0,
2309ff08654SSepherosa Ziehau 	    cb, sc);
2319ff08654SSepherosa Ziehau 	if (error) {
2329ff08654SSepherosa Ziehau 		free(sc->ic_buf, M_DEVBUF);
2339ff08654SSepherosa Ziehau 		return (error);
2349ff08654SSepherosa Ziehau 	}
2359ff08654SSepherosa Ziehau 
2369ff08654SSepherosa Ziehau 	ctx = device_get_sysctl_ctx(dev);
2379ff08654SSepherosa Ziehau 	child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
2389ff08654SSepherosa Ziehau 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fw_version",
2399ff08654SSepherosa Ziehau 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
2409ff08654SSepherosa Ziehau 	    vmbus_ic_fwver_sysctl, "A", "framework version");
2419ff08654SSepherosa Ziehau 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "msg_version",
2429ff08654SSepherosa Ziehau 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
2439ff08654SSepherosa Ziehau 	    vmbus_ic_msgver_sysctl, "A", "message version");
2449ff08654SSepherosa Ziehau 
2459ff08654SSepherosa Ziehau 	return (0);
2469ff08654SSepherosa Ziehau }
2479ff08654SSepherosa Ziehau 
2489ff08654SSepherosa Ziehau static int
vmbus_ic_fwver_sysctl(SYSCTL_HANDLER_ARGS)2499ff08654SSepherosa Ziehau vmbus_ic_fwver_sysctl(SYSCTL_HANDLER_ARGS)
2509ff08654SSepherosa Ziehau {
2519ff08654SSepherosa Ziehau 	struct vmbus_ic_softc *sc = arg1;
2529ff08654SSepherosa Ziehau 	char verstr[16];
2539ff08654SSepherosa Ziehau 
2549ff08654SSepherosa Ziehau 	snprintf(verstr, sizeof(verstr), "%u.%u",
2559ff08654SSepherosa Ziehau 	    VMBUS_ICVER_MAJOR(sc->ic_fwver), VMBUS_ICVER_MINOR(sc->ic_fwver));
2569ff08654SSepherosa Ziehau 	return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
2579ff08654SSepherosa Ziehau }
2589ff08654SSepherosa Ziehau 
2599ff08654SSepherosa Ziehau static int
vmbus_ic_msgver_sysctl(SYSCTL_HANDLER_ARGS)2609ff08654SSepherosa Ziehau vmbus_ic_msgver_sysctl(SYSCTL_HANDLER_ARGS)
2619ff08654SSepherosa Ziehau {
2629ff08654SSepherosa Ziehau 	struct vmbus_ic_softc *sc = arg1;
2639ff08654SSepherosa Ziehau 	char verstr[16];
2649ff08654SSepherosa Ziehau 
2659ff08654SSepherosa Ziehau 	snprintf(verstr, sizeof(verstr), "%u.%u",
2669ff08654SSepherosa Ziehau 	    VMBUS_ICVER_MAJOR(sc->ic_msgver), VMBUS_ICVER_MINOR(sc->ic_msgver));
2679ff08654SSepherosa Ziehau 	return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
2689ff08654SSepherosa Ziehau }
2699ff08654SSepherosa Ziehau 
2709ff08654SSepherosa Ziehau int
vmbus_ic_detach(device_t dev)2719ff08654SSepherosa Ziehau vmbus_ic_detach(device_t dev)
2729ff08654SSepherosa Ziehau {
2739ff08654SSepherosa Ziehau 	struct vmbus_ic_softc *sc = device_get_softc(dev);
2749ff08654SSepherosa Ziehau 
2759ff08654SSepherosa Ziehau 	vmbus_chan_close(vmbus_get_channel(dev));
2769ff08654SSepherosa Ziehau 	free(sc->ic_buf, M_DEVBUF);
2779ff08654SSepherosa Ziehau 
2789ff08654SSepherosa Ziehau 	return (0);
2799ff08654SSepherosa Ziehau }
2809ff08654SSepherosa Ziehau 
2819ff08654SSepherosa Ziehau int
vmbus_ic_sendresp(struct vmbus_ic_softc * sc,struct vmbus_channel * chan,void * data,int dlen,uint64_t xactid)2829ff08654SSepherosa Ziehau vmbus_ic_sendresp(struct vmbus_ic_softc *sc, struct vmbus_channel *chan,
2839ff08654SSepherosa Ziehau     void *data, int dlen, uint64_t xactid)
2849ff08654SSepherosa Ziehau {
2859ff08654SSepherosa Ziehau 	struct vmbus_icmsg_hdr *hdr;
2869ff08654SSepherosa Ziehau 	int error;
2879ff08654SSepherosa Ziehau 
2889ff08654SSepherosa Ziehau 	KASSERT(dlen >= sizeof(*hdr), ("invalid data length %d", dlen));
2899ff08654SSepherosa Ziehau 	hdr = data;
2909ff08654SSepherosa Ziehau 
2919ff08654SSepherosa Ziehau 	hdr->ic_flags = VMBUS_ICMSG_FLAG_XACT | VMBUS_ICMSG_FLAG_RESP;
2929ff08654SSepherosa Ziehau 	error = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, 0,
2939ff08654SSepherosa Ziehau 	    data, dlen, xactid);
2949ff08654SSepherosa Ziehau 	if (error)
2959ff08654SSepherosa Ziehau 		device_printf(sc->ic_dev, "resp send failed: %d\n", error);
2969ff08654SSepherosa Ziehau 	return (error);
2979ff08654SSepherosa Ziehau }
298