vmbus_heartbeat.c revision 295958
1295958Ssephe/*- 2295958Ssephe * Copyright (c) 2014 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 295958 2016-02-24 05:01:18Z 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> 36295958Ssephe 37295958Ssephe#include <dev/hyperv/include/hyperv.h> 38295958Ssephe#include "hv_util.h" 39295958Ssephe 40295958Ssephe/* Heartbeat Service */ 41295958Ssephestatic hv_guid service_guid = { .data = 42295958Ssephe {0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, 43295958Ssephe 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d} }; 44295958Ssephe 45295958Ssephe/** 46295958Ssephe * Process heartbeat message 47295958Ssephe */ 48295958Ssephestatic void 49295958Ssephehv_heartbeat_cb(void *context) 50295958Ssephe{ 51295958Ssephe uint8_t* buf; 52295958Ssephe hv_vmbus_channel* channel; 53295958Ssephe uint32_t recvlen; 54295958Ssephe uint64_t requestid; 55295958Ssephe int ret; 56295958Ssephe 57295958Ssephe struct hv_vmbus_heartbeat_msg_data* heartbeat_msg; 58295958Ssephe struct hv_vmbus_icmsg_hdr* icmsghdrp; 59295958Ssephe hv_util_sc *softc; 60295958Ssephe 61295958Ssephe softc = (hv_util_sc*)context; 62295958Ssephe buf = softc->receive_buffer;; 63295958Ssephe channel = softc->hv_dev->channel; 64295958Ssephe 65295958Ssephe ret = hv_vmbus_channel_recv_packet(channel, buf, PAGE_SIZE, &recvlen, 66295958Ssephe &requestid); 67295958Ssephe 68295958Ssephe if ((ret == 0) && recvlen > 0) { 69295958Ssephe 70295958Ssephe icmsghdrp = (struct hv_vmbus_icmsg_hdr *) 71295958Ssephe &buf[sizeof(struct hv_vmbus_pipe_hdr)]; 72295958Ssephe 73295958Ssephe if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { 74295958Ssephe hv_negotiate_version(icmsghdrp, NULL, buf); 75295958Ssephe 76295958Ssephe } else { 77295958Ssephe heartbeat_msg = 78295958Ssephe (struct hv_vmbus_heartbeat_msg_data *) 79295958Ssephe &buf[sizeof(struct hv_vmbus_pipe_hdr) + 80295958Ssephe sizeof(struct hv_vmbus_icmsg_hdr)]; 81295958Ssephe 82295958Ssephe heartbeat_msg->seq_num += 1; 83295958Ssephe } 84295958Ssephe 85295958Ssephe icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | 86295958Ssephe HV_ICMSGHDRFLAG_RESPONSE; 87295958Ssephe 88295958Ssephe hv_vmbus_channel_send_packet(channel, buf, recvlen, requestid, 89295958Ssephe HV_VMBUS_PACKET_TYPE_DATA_IN_BAND, 0); 90295958Ssephe } 91295958Ssephe} 92295958Ssephe 93295958Ssephestatic int 94295958Ssephehv_heartbeat_probe(device_t dev) 95295958Ssephe{ 96295958Ssephe const char *p = vmbus_get_type(dev); 97295958Ssephe if (!memcmp(p, &service_guid, sizeof(hv_guid))) { 98295958Ssephe device_set_desc(dev, "Hyper-V Heartbeat Service"); 99295958Ssephe return BUS_PROBE_DEFAULT; 100295958Ssephe } 101295958Ssephe 102295958Ssephe return ENXIO; 103295958Ssephe} 104295958Ssephe 105295958Ssephestatic int 106295958Ssephehv_heartbeat_attach(device_t dev) 107295958Ssephe{ 108295958Ssephe hv_util_sc *softc = (hv_util_sc*)device_get_softc(dev); 109295958Ssephe 110295958Ssephe softc->callback = hv_heartbeat_cb; 111295958Ssephe 112295958Ssephe return hv_util_attach(dev); 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