vmbus_heartbeat.c revision 303824
1295958Ssephe/*- 2298446Ssephe * Copyright (c) 2014,2016 Microsoft Corp. 3295958Ssephe * All rights reserved. 4295958Ssephe * 5295958Ssephe * Redistribution and use in source and binary forms, with or without 6295958Ssephe * modification, are permitted provided that the following conditions 7295958Ssephe * are met: 8295958Ssephe * 1. Redistributions of source code must retain the above copyright 9295958Ssephe * notice unmodified, this list of conditions, and the following 10295958Ssephe * disclaimer. 11295958Ssephe * 2. Redistributions in binary form must reproduce the above copyright 12295958Ssephe * notice, this list of conditions and the following disclaimer in the 13295958Ssephe * documentation and/or other materials provided with the distribution. 14295958Ssephe * 15295958Ssephe * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16295958Ssephe * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17295958Ssephe * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18295958Ssephe * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19295958Ssephe * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20295958Ssephe * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21295958Ssephe * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22295958Ssephe * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23295958Ssephe * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24295958Ssephe * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25295958Ssephe * 26295958Ssephe * $FreeBSD: head/sys/dev/hyperv/utilities/hv_heartbeat.c 303824 2016-08-08 06:18:54Z sephe $ 27295958Ssephe */ 28295958Ssephe 29295958Ssephe#include <sys/param.h> 30295958Ssephe#include <sys/kernel.h> 31295958Ssephe#include <sys/bus.h> 32295958Ssephe#include <sys/malloc.h> 33295958Ssephe#include <sys/module.h> 34295958Ssephe#include <sys/timetc.h> 35295958Ssephe#include <sys/syscallsubr.h> 36303422Ssephe#include <sys/systm.h> 37295958Ssephe 38295958Ssephe#include <dev/hyperv/include/hyperv.h> 39302880Ssephe#include <dev/hyperv/include/vmbus.h> 40303067Ssephe#include <dev/hyperv/utilities/hv_utilreg.h> 41295958Ssephe#include "hv_util.h" 42302698Ssephe#include "vmbus_if.h" 43295958Ssephe 44295958Ssephe/* Heartbeat Service */ 45302802Ssephestatic const struct hyperv_guid service_guid = { .hv_guid = 46295958Ssephe {0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, 47295958Ssephe 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d} }; 48295958Ssephe 49295958Ssephe/** 50295958Ssephe * Process heartbeat message 51295958Ssephe */ 52295958Ssephestatic void 53303131Ssephehv_heartbeat_cb(struct vmbus_channel *channel, void *context) 54295958Ssephe{ 55295958Ssephe uint8_t* buf; 56302885Ssephe int recvlen; 57295958Ssephe uint64_t requestid; 58295958Ssephe int ret; 59295958Ssephe 60295958Ssephe struct hv_vmbus_heartbeat_msg_data* heartbeat_msg; 61295958Ssephe struct hv_vmbus_icmsg_hdr* icmsghdrp; 62295958Ssephe hv_util_sc *softc; 63295958Ssephe 64295958Ssephe softc = (hv_util_sc*)context; 65297793Spfg buf = softc->receive_buffer; 66295958Ssephe 67303823Ssephe recvlen = softc->ic_buflen; 68302885Ssephe ret = vmbus_chan_recv(channel, buf, &recvlen, &requestid); 69302885Ssephe KASSERT(ret != ENOBUFS, ("hvheartbeat recvbuf is not large enough")); 70302885Ssephe /* XXX check recvlen to make sure that it contains enough data */ 71295958Ssephe 72295958Ssephe if ((ret == 0) && recvlen > 0) { 73295958Ssephe 74295958Ssephe icmsghdrp = (struct hv_vmbus_icmsg_hdr *) 75295958Ssephe &buf[sizeof(struct hv_vmbus_pipe_hdr)]; 76295958Ssephe 77295958Ssephe if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { 78303822Ssephe hv_negotiate_version(icmsghdrp, buf); 79295958Ssephe } else { 80295958Ssephe heartbeat_msg = 81295958Ssephe (struct hv_vmbus_heartbeat_msg_data *) 82295958Ssephe &buf[sizeof(struct hv_vmbus_pipe_hdr) + 83295958Ssephe sizeof(struct hv_vmbus_icmsg_hdr)]; 84295958Ssephe 85295958Ssephe heartbeat_msg->seq_num += 1; 86295958Ssephe } 87295958Ssephe 88295958Ssephe icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | 89295958Ssephe HV_ICMSGHDRFLAG_RESPONSE; 90295958Ssephe 91302882Ssephe vmbus_chan_send(channel, VMBUS_CHANPKT_TYPE_INBAND, 0, 92302882Ssephe buf, recvlen, requestid); 93295958Ssephe } 94295958Ssephe} 95295958Ssephe 96295958Ssephestatic int 97295958Ssephehv_heartbeat_probe(device_t dev) 98295958Ssephe{ 99297220Ssephe if (resource_disabled("hvheartbeat", 0)) 100297220Ssephe return ENXIO; 101297220Ssephe 102302698Ssephe if (VMBUS_PROBE_GUID(device_get_parent(dev), dev, &service_guid) == 0) { 103295958Ssephe device_set_desc(dev, "Hyper-V Heartbeat Service"); 104295958Ssephe return BUS_PROBE_DEFAULT; 105295958Ssephe } 106295958Ssephe return ENXIO; 107295958Ssephe} 108295958Ssephe 109295958Ssephestatic int 110295958Ssephehv_heartbeat_attach(device_t dev) 111295958Ssephe{ 112303824Ssephe return hv_util_attach(dev, hv_heartbeat_cb); 113295958Ssephe} 114295958Ssephe 115295958Ssephestatic device_method_t heartbeat_methods[] = { 116295958Ssephe /* Device interface */ 117295958Ssephe DEVMETHOD(device_probe, hv_heartbeat_probe), 118295958Ssephe DEVMETHOD(device_attach, hv_heartbeat_attach), 119295958Ssephe DEVMETHOD(device_detach, hv_util_detach), 120295958Ssephe { 0, 0 } 121295958Ssephe}; 122295958Ssephe 123295958Ssephestatic driver_t heartbeat_driver = { "hvheartbeat", heartbeat_methods, sizeof(hv_util_sc)}; 124295958Ssephe 125295958Ssephestatic devclass_t heartbeat_devclass; 126295958Ssephe 127295958SsepheDRIVER_MODULE(hv_heartbeat, vmbus, heartbeat_driver, heartbeat_devclass, NULL, NULL); 128295958SsepheMODULE_VERSION(hv_heartbeat, 1); 129295958SsepheMODULE_DEPEND(hv_heartbeat, vmbus, 1, 1, 1); 130