Author: sephe
Date: Fri Nov 11 03:43:06 2016
New Revision: 308499
URL: https://svnweb.freebsd.org/changeset/base/308499

Log:
  MFC 307845
  
      hyperv/ic: Rework framework/message version negotiation.
  
      Submitted by:   Hongjiang Zhang <honzhan microsoft com>
      Modified by:    sephe
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D8280

Modified:
  stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c
  stable/10/sys/dev/hyperv/utilities/hv_kvp.c
  stable/10/sys/dev/hyperv/utilities/hv_kvp.h
  stable/10/sys/dev/hyperv/utilities/hv_shutdown.c
  stable/10/sys/dev/hyperv/utilities/hv_timesync.c
  stable/10/sys/dev/hyperv/utilities/hv_util.c
  stable/10/sys/dev/hyperv/utilities/hv_util.h
  stable/10/sys/dev/hyperv/utilities/hv_utilreg.h
  stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c   Fri Nov 11 03:41:36 
2016        (r308498)
+++ stable/10/sys/dev/hyperv/utilities/hv_heartbeat.c   Fri Nov 11 03:43:06 
2016        (r308499)
@@ -40,6 +40,14 @@ __FBSDID("$FreeBSD$");
 
 #include "vmbus_if.h"
 
+#define VMBUS_HEARTBEAT_FWVER_MAJOR    3
+#define VMBUS_HEARTBEAT_FWVER          \
+       VMBUS_IC_VERSION(VMBUS_HEARTBEAT_FWVER_MAJOR, 0)
+
+#define VMBUS_HEARTBEAT_MSGVER_MAJOR   3
+#define VMBUS_HEARTBEAT_MSGVER         \
+       VMBUS_IC_VERSION(VMBUS_HEARTBEAT_MSGVER_MAJOR, 0)
+
 static const struct vmbus_ic_desc vmbus_heartbeat_descs[] = {
        {
                .ic_guid = { .hv_guid = {
@@ -80,7 +88,8 @@ vmbus_heartbeat_cb(struct vmbus_channel 
         */
        switch (hdr->ic_type) {
        case VMBUS_ICMSG_TYPE_NEGOTIATE:
-               error = vmbus_ic_negomsg(sc, data, &dlen);
+               error = vmbus_ic_negomsg(sc, data, &dlen,
+                   VMBUS_HEARTBEAT_FWVER, VMBUS_HEARTBEAT_MSGVER);
                if (error)
                        return;
                break;

Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.c
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/hv_kvp.c Fri Nov 11 03:41:36 2016        
(r308498)
+++ stable/10/sys/dev/hyperv/utilities/hv_kvp.c Fri Nov 11 03:43:06 2016        
(r308499)
@@ -61,7 +61,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/mutex.h>
 
 #include <dev/hyperv/include/hyperv.h>
+#include <dev/hyperv/include/vmbus.h>
 #include <dev/hyperv/utilities/hv_utilreg.h>
+#include <dev/hyperv/utilities/vmbus_icreg.h>
 
 #include "hv_util.h"
 #include "unicode.h"
@@ -74,6 +76,12 @@ __FBSDID("$FreeBSD$");
 #define KVP_ERROR      1
 #define kvp_hdr                hdr.kvp_hdr
 
+#define KVP_FWVER_MAJOR                3
+#define KVP_FWVER              VMBUS_IC_VERSION(KVP_FWVER_MAJOR, 0)
+
+#define KVP_MSGVER_MAJOR       4
+#define KVP_MSGVER             VMBUS_IC_VERSION(KVP_MSGVER_MAJOR, 0)
+
 /* hv_kvp debug control */
 static int hv_kvp_log = 0;
 
@@ -208,52 +216,10 @@ hv_kvp_transaction_init(hv_kvp_sc *sc, u
        sc->host_msg_id = request_id;
        sc->rcv_buf = rcv_buf;
        sc->host_kvp_msg = (struct hv_kvp_msg *)&rcv_buf[
-               sizeof(struct hv_vmbus_pipe_hdr) +
-               sizeof(struct hv_vmbus_icmsg_hdr)];
+           sizeof(struct hv_vmbus_pipe_hdr) +
+           sizeof(struct hv_vmbus_icmsg_hdr)];
 }
 
-
-/*
- * hv_kvp - version neogtiation function
- */
-static void
-hv_kvp_negotiate_version(struct hv_vmbus_icmsg_hdr *icmsghdrp, uint8_t *buf)
-{
-       struct hv_vmbus_icmsg_negotiate *negop;
-       int icframe_vercnt;
-       int icmsg_vercnt;
-
-       icmsghdrp->icmsgsize = 0x10;
-
-       negop = (struct hv_vmbus_icmsg_negotiate *)&buf[
-               sizeof(struct hv_vmbus_pipe_hdr) +
-               sizeof(struct hv_vmbus_icmsg_hdr)];
-       icframe_vercnt = negop->icframe_vercnt;
-       icmsg_vercnt = negop->icmsg_vercnt;
-
-       /*
-        * Select the framework version number we will support
-        */
-       if ((icframe_vercnt >= 2) && (negop->icversion_data[1].major == 3)) {
-               icframe_vercnt = 3;
-               if (icmsg_vercnt > 2)
-                       icmsg_vercnt = 4;
-               else
-                       icmsg_vercnt = 3;
-       } else {
-               icframe_vercnt = 1;
-               icmsg_vercnt = 1;
-       }
-
-       negop->icframe_vercnt = 1;
-       negop->icmsg_vercnt = 1;
-       negop->icversion_data[0].major = icframe_vercnt;
-       negop->icversion_data[0].minor = 0;
-       negop->icversion_data[1].major = icmsg_vercnt;
-       negop->icversion_data[1].minor = 0;
-}
-
-
 /*
  * Convert ip related info in umsg from utf8 to utf16 and store in hmsg
  */
@@ -578,7 +544,8 @@ hv_kvp_respond_host(hv_kvp_sc *sc, int e
                error = HV_KVP_E_FAIL;
 
        hv_icmsg_hdrp->status = error;
-       hv_icmsg_hdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | 
HV_ICMSGHDRFLAG_RESPONSE;
+       hv_icmsg_hdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION |
+           HV_ICMSGHDRFLAG_RESPONSE;
 
        error = vmbus_chan_send(vmbus_get_channel(sc->dev),
            VMBUS_CHANPKT_TYPE_INBAND, 0, sc->rcv_buf, sc->host_msg_len,
@@ -622,8 +589,8 @@ hv_kvp_process_request(void *context, in
        uint32_t recvlen = 0;
        uint64_t requestid;
        struct hv_vmbus_icmsg_hdr *icmsghdrp;
-       int ret = 0;
-       hv_kvp_sc               *sc;
+       int ret = 0, error;
+       hv_kvp_sc *sc;
 
        hv_kvp_log_info("%s: entering hv_kvp_process_request\n", __func__);
 
@@ -637,14 +604,15 @@ hv_kvp_process_request(void *context, in
        /* XXX check recvlen to make sure that it contains enough data */
 
        while ((ret == 0) && (recvlen > 0)) {
-
                icmsghdrp = (struct hv_vmbus_icmsg_hdr *)
-                       &kvp_buf[sizeof(struct hv_vmbus_pipe_hdr)];
+                   &kvp_buf[sizeof(struct hv_vmbus_pipe_hdr)];
 
                hv_kvp_transaction_init(sc, recvlen, requestid, kvp_buf);
                if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) {
-                       hv_kvp_negotiate_version(icmsghdrp, kvp_buf);
-                       hv_kvp_respond_host(sc, ret);
+                       error = vmbus_ic_negomsg(&sc->util_sc,
+                           kvp_buf, &recvlen, KVP_FWVER, KVP_MSGVER);
+                       /* XXX handle vmbus_ic_negomsg failure. */
+                       hv_kvp_respond_host(sc, error);
 
                        /*
                         * It is ok to not acquire the mutex before setting

Modified: stable/10/sys/dev/hyperv/utilities/hv_kvp.h
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/hv_kvp.h Fri Nov 11 03:41:36 2016        
(r308498)
+++ stable/10/sys/dev/hyperv/utilities/hv_kvp.h Fri Nov 11 03:43:06 2016        
(r308499)
@@ -28,7 +28,6 @@
 
 #ifndef _KVP_H
 #define _KVP_H
-
 /*
  * An implementation of HyperV key value pair (KVP) functionality for FreeBSD
  *
@@ -178,9 +177,9 @@ struct hv_kvp_ipaddr_value {
 }__attribute__((packed));
 
 struct hv_kvp_hdr {
-       uint8_t  operation;
-       uint8_t  pool;
-       uint16_t pad;
+       uint8_t                 operation;
+       uint8_t                 pool;
+       uint16_t                pad;
 } __attribute__((packed));
 
 struct hv_kvp_exchg_msg_value {

Modified: stable/10/sys/dev/hyperv/utilities/hv_shutdown.c
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/hv_shutdown.c    Fri Nov 11 03:41:36 
2016        (r308498)
+++ stable/10/sys/dev/hyperv/utilities/hv_shutdown.c    Fri Nov 11 03:43:06 
2016        (r308499)
@@ -41,6 +41,14 @@ __FBSDID("$FreeBSD$");
 
 #include "vmbus_if.h"
 
+#define VMBUS_SHUTDOWN_FWVER_MAJOR     3
+#define VMBUS_SHUTDOWN_FWVER           \
+       VMBUS_IC_VERSION(VMBUS_SHUTDOWN_FWVER_MAJOR, 0)
+
+#define VMBUS_SHUTDOWN_MSGVER_MAJOR    3
+#define VMBUS_SHUTDOWN_MSGVER          \
+       VMBUS_IC_VERSION(VMBUS_SHUTDOWN_MSGVER_MAJOR, 0)
+
 static const struct vmbus_ic_desc vmbus_shutdown_descs[] = {
        {
                .ic_guid = { .hv_guid = {
@@ -82,7 +90,8 @@ vmbus_shutdown_cb(struct vmbus_channel *
         */
        switch (hdr->ic_type) {
        case VMBUS_ICMSG_TYPE_NEGOTIATE:
-               error = vmbus_ic_negomsg(sc, data, &dlen);
+               error = vmbus_ic_negomsg(sc, data, &dlen,
+                   VMBUS_SHUTDOWN_FWVER, VMBUS_SHUTDOWN_MSGVER);
                if (error)
                        return;
                break;

Modified: stable/10/sys/dev/hyperv/utilities/hv_timesync.c
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/hv_timesync.c    Fri Nov 11 03:41:36 
2016        (r308498)
+++ stable/10/sys/dev/hyperv/utilities/hv_timesync.c    Fri Nov 11 03:43:06 
2016        (r308499)
@@ -42,6 +42,14 @@ __FBSDID("$FreeBSD$");
 
 #include "vmbus_if.h"
 
+#define VMBUS_TIMESYNC_FWVER_MAJOR     3
+#define VMBUS_TIMESYNC_FWVER           \
+       VMBUS_IC_VERSION(VMBUS_TIMESYNC_FWVER_MAJOR, 0)
+
+#define VMBUS_TIMESYNC_MSGVER_MAJOR    3
+#define VMBUS_TIMESYNC_MSGVER          \
+       VMBUS_IC_VERSION(VMBUS_TIMESYNC_MSGVER_MAJOR, 0)
+
 static const struct vmbus_ic_desc vmbus_timesync_descs[] = {
        {
                .ic_guid = { .hv_guid = {
@@ -162,7 +170,8 @@ vmbus_timesync_cb(struct vmbus_channel *
         */
        switch (hdr->ic_type) {
        case VMBUS_ICMSG_TYPE_NEGOTIATE:
-               error = vmbus_ic_negomsg(sc, data, &dlen);
+               error = vmbus_ic_negomsg(sc, data, &dlen,
+                   VMBUS_TIMESYNC_FWVER, VMBUS_TIMESYNC_MSGVER);
                if (error)
                        return;
                break;

Modified: stable/10/sys/dev/hyperv/utilities/hv_util.c
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/hv_util.c        Fri Nov 11 03:41:36 
2016        (r308498)
+++ stable/10/sys/dev/hyperv/utilities/hv_util.c        Fri Nov 11 03:43:06 
2016        (r308499)
@@ -37,6 +37,7 @@
 #include <sys/module.h>
 #include <sys/reboot.h>
 #include <sys/systm.h>
+#include <sys/sysctl.h>
 #include <sys/timetc.h>
 
 #include <dev/hyperv/include/hyperv.h>
@@ -53,52 +54,145 @@
        __offsetof(struct vmbus_icmsg_negotiate, ic_ver[VMBUS_IC_VERCNT])
 CTASSERT(VMBUS_IC_NEGOSZ < VMBUS_IC_BRSIZE);
 
+static int     vmbus_ic_fwver_sysctl(SYSCTL_HANDLER_ARGS);
+static int     vmbus_ic_msgver_sysctl(SYSCTL_HANDLER_ARGS);
+
 int
-vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int *dlen0)
+vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int *dlen0,
+    uint32_t fw_ver, uint32_t msg_ver)
 {
        struct vmbus_icmsg_negotiate *nego;
-       int cnt, major, dlen = *dlen0;
+       int i, cnt, dlen = *dlen0, error;
+       uint32_t sel_fw_ver, sel_msg_ver;
+       bool has_fw_ver, has_msg_ver;
 
        /*
-        * Preliminary message size verification
+        * Preliminary message verification.
         */
        if (dlen < sizeof(*nego)) {
                device_printf(sc->ic_dev, "truncated ic negotiate, len %d\n",
                    dlen);
-               return EINVAL;
+               return (EINVAL);
        }
        nego = data;
 
+       if (nego->ic_fwver_cnt == 0) {
+               device_printf(sc->ic_dev, "ic negotiate does not contain "
+                   "framework version %u\n", nego->ic_fwver_cnt);
+               return (EINVAL);
+       }
+       if (nego->ic_msgver_cnt == 0) {
+               device_printf(sc->ic_dev, "ic negotiate does not contain "
+                   "message version %u\n", nego->ic_msgver_cnt);
+               return (EINVAL);
+       }
+
        cnt = nego->ic_fwver_cnt + nego->ic_msgver_cnt;
        if (dlen < __offsetof(struct vmbus_icmsg_negotiate, ic_ver[cnt])) {
                device_printf(sc->ic_dev, "ic negotiate does not contain "
                    "versions %d\n", dlen);
-               return EINVAL;
+               return (EINVAL);
+       }
+
+       error = EOPNOTSUPP;
+
+       /*
+        * Find the best match framework version.
+        */
+       has_fw_ver = false;
+       for (i = 0; i < nego->ic_fwver_cnt; ++i) {
+               if (VMBUS_ICVER_LE(nego->ic_ver[i], fw_ver)) {
+                       if (!has_fw_ver) {
+                               sel_fw_ver = nego->ic_ver[i];
+                               has_fw_ver = true;
+                       } else if (VMBUS_ICVER_GT(nego->ic_ver[i],
+                           sel_fw_ver)) {
+                               sel_fw_ver = nego->ic_ver[i];
+                       }
+               }
+       }
+       if (!has_fw_ver) {
+               device_printf(sc->ic_dev, "failed to select framework "
+                   "version\n");
+               goto done;
+       }
+
+       /*
+        * Fine the best match message version.
+        */
+       has_msg_ver = false;
+       for (i = nego->ic_fwver_cnt;
+           i < nego->ic_fwver_cnt + nego->ic_msgver_cnt; ++i) {
+               if (VMBUS_ICVER_LE(nego->ic_ver[i], msg_ver)) {
+                       if (!has_msg_ver) {
+                               sel_msg_ver = nego->ic_ver[i];
+                               has_msg_ver = true;
+                       } else if (VMBUS_ICVER_GT(nego->ic_ver[i],
+                           sel_msg_ver)) {
+                               sel_msg_ver = nego->ic_ver[i];
+                       }
+               }
+       }
+       if (!has_msg_ver) {
+               device_printf(sc->ic_dev, "failed to select message "
+                   "version\n");
+               goto done;
        }
 
-       /* Select major version; XXX looks wrong. */
-       if (nego->ic_fwver_cnt >= 2 && VMBUS_ICVER_MAJOR(nego->ic_ver[1]) == 3)
-               major = 3;
-       else
-               major = 1;
+       error = 0;
+done:
+       if (bootverbose || !has_fw_ver || !has_msg_ver) {
+               if (has_fw_ver) {
+                       device_printf(sc->ic_dev, "sel framework version: "
+                           "%u.%u\n",
+                           VMBUS_ICVER_MAJOR(sel_fw_ver),
+                           VMBUS_ICVER_MINOR(sel_fw_ver));
+               }
+               for (i = 0; i < nego->ic_fwver_cnt; i++) {
+                       device_printf(sc->ic_dev, "supp framework version: "
+                           "%u.%u\n",
+                           VMBUS_ICVER_MAJOR(nego->ic_ver[i]),
+                           VMBUS_ICVER_MINOR(nego->ic_ver[i]));
+               }
+
+               if (has_msg_ver) {
+                       device_printf(sc->ic_dev, "sel message version: "
+                           "%u.%u\n",
+                           VMBUS_ICVER_MAJOR(sel_msg_ver),
+                           VMBUS_ICVER_MINOR(sel_msg_ver));
+               }
+               for (i = nego->ic_fwver_cnt;
+                   i < nego->ic_fwver_cnt + nego->ic_msgver_cnt; i++) {
+                       device_printf(sc->ic_dev, "supp message version: "
+                           "%u.%u\n",
+                           VMBUS_ICVER_MAJOR(nego->ic_ver[i]),
+                           VMBUS_ICVER_MINOR(nego->ic_ver[i]));
+               }
+       }
+       if (error)
+               return (error);
+
+       /* Record the selected versions. */
+       sc->ic_fwver = sel_fw_ver;
+       sc->ic_msgver = sel_msg_ver;
 
-       /* One framework version */
+       /* One framework version. */
        nego->ic_fwver_cnt = 1;
-       nego->ic_ver[0] = VMBUS_IC_VERSION(major, 0);
+       nego->ic_ver[0] = sel_fw_ver;
 
-       /* One message version */
+       /* One message version. */
        nego->ic_msgver_cnt = 1;
-       nego->ic_ver[1] = VMBUS_IC_VERSION(major, 0);
+       nego->ic_ver[1] = sel_msg_ver;
 
-       /* Update data size */
+       /* Update data size. */
        nego->ic_hdr.ic_dsize = VMBUS_IC_NEGOSZ -
            sizeof(struct vmbus_icmsg_hdr);
 
-       /* Update total size, if necessary */
+       /* Update total size, if necessary. */
        if (dlen < VMBUS_IC_NEGOSZ)
                *dlen0 = VMBUS_IC_NEGOSZ;
 
-       return 0;
+       return (0);
 }
 
 int
@@ -124,6 +218,8 @@ hv_util_attach(device_t dev, vmbus_chan_
 {
        struct hv_util_sc *sc = device_get_softc(dev);
        struct vmbus_channel *chan = vmbus_get_channel(dev);
+       struct sysctl_oid_list *child;
+       struct sysctl_ctx_list *ctx;
        int error;
 
        sc->ic_dev = dev;
@@ -146,9 +242,41 @@ hv_util_attach(device_t dev, vmbus_chan_
                free(sc->receive_buffer, M_DEVBUF);
                return (error);
        }
+
+       ctx = device_get_sysctl_ctx(dev);
+       child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
+       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fw_version",
+           CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+           vmbus_ic_fwver_sysctl, "A", "framework version");
+       SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "msg_version",
+           CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+           vmbus_ic_msgver_sysctl, "A", "message version");
+
        return (0);
 }
 
+static int
+vmbus_ic_fwver_sysctl(SYSCTL_HANDLER_ARGS)
+{
+       struct hv_util_sc *sc = arg1;
+       char verstr[16];
+
+       snprintf(verstr, sizeof(verstr), "%u.%u",
+           VMBUS_ICVER_MAJOR(sc->ic_fwver), VMBUS_ICVER_MINOR(sc->ic_fwver));
+       return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
+}
+
+static int
+vmbus_ic_msgver_sysctl(SYSCTL_HANDLER_ARGS)
+{
+       struct hv_util_sc *sc = arg1;
+       char verstr[16];
+
+       snprintf(verstr, sizeof(verstr), "%u.%u",
+           VMBUS_ICVER_MAJOR(sc->ic_msgver), VMBUS_ICVER_MINOR(sc->ic_msgver));
+       return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
+}
+
 int
 hv_util_detach(device_t dev)
 {

Modified: stable/10/sys/dev/hyperv/utilities/hv_util.h
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/hv_util.h        Fri Nov 11 03:41:36 
2016        (r308498)
+++ stable/10/sys/dev/hyperv/utilities/hv_util.h        Fri Nov 11 03:43:06 
2016        (r308499)
@@ -42,6 +42,8 @@ typedef struct hv_util_sc {
        device_t                ic_dev;
        uint8_t                 *receive_buffer;
        int                     ic_buflen;
+       uint32_t                ic_fwver;       /* framework version */
+       uint32_t                ic_msgver;      /* message version */
 } hv_util_sc;
 
 struct vmbus_ic_desc {
@@ -54,6 +56,7 @@ struct vmbus_ic_desc {
 int            hv_util_attach(device_t dev, vmbus_chan_callback_t cb);
 int            hv_util_detach(device_t dev);
 int            vmbus_ic_probe(device_t dev, const struct vmbus_ic_desc 
descs[]);
-int            vmbus_ic_negomsg(struct hv_util_sc *, void *data, int *dlen);
+int            vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int *dlen,
+                   uint32_t fw_ver, uint32_t msg_ver);
 
 #endif

Modified: stable/10/sys/dev/hyperv/utilities/hv_utilreg.h
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/hv_utilreg.h     Fri Nov 11 03:41:36 
2016        (r308498)
+++ stable/10/sys/dev/hyperv/utilities/hv_utilreg.h     Fri Nov 11 03:43:06 
2016        (r308499)
@@ -76,16 +76,4 @@ typedef struct hv_vmbus_icmsg_negotiate 
        hv_vmbus_ic_version     icversion_data[1]; /* any size array */
 } __packed hv_vmbus_icmsg_negotiate;
 
-typedef struct hv_vmbus_shutdown_msg_data {
-       uint32_t                reason_code;
-       uint32_t                timeout_seconds;
-       uint32_t                flags;
-       uint8_t                 display_message[2048];
-} __packed hv_vmbus_shutdown_msg_data;
-
-typedef struct hv_vmbus_heartbeat_msg_data {
-       uint64_t                seq_num;
-       uint32_t                reserved[8];
-} __packed hv_vmbus_heartbeat_msg_data;
-
 #endif /* !_HV_UTILREG_H_ */

Modified: stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h
==============================================================================
--- stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h    Fri Nov 11 03:41:36 
2016        (r308498)
+++ stable/10/sys/dev/hyperv/utilities/vmbus_icreg.h    Fri Nov 11 03:43:06 
2016        (r308499)
@@ -42,6 +42,12 @@
 #define VMBUS_IC_VERSION(major, minor) ((major) | (((uint32_t)(minor)) << 16))
 #define VMBUS_ICVER_MAJOR(ver)         ((ver) & 0xffff)
 #define VMBUS_ICVER_MINOR(ver)         (((ver) & 0xffff0000) >> 16)
+#define VMBUS_ICVER_SWAP(ver)          \
+       ((VMBUS_ICVER_MAJOR((ver)) << 16) | VMBUS_ICVER_MINOR((ver)))
+#define VMBUS_ICVER_LE(v1, v2)         \
+       (VMBUS_ICVER_SWAP((v1)) <= VMBUS_ICVER_SWAP((v2)))
+#define VMBUS_ICVER_GT(v1, v2)         \
+       (VMBUS_ICVER_SWAP((v1)) > VMBUS_ICVER_SWAP((v2)))
 
 struct vmbus_pipe_hdr {
        uint32_t                ph_flags;
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to