vmbus_ic.c revision 303069
1250199Sgrehan/*- 2298446Ssephe * Copyright (c) 2014,2016 Microsoft Corp. 3250199Sgrehan * All rights reserved. 4250199Sgrehan * 5250199Sgrehan * Redistribution and use in source and binary forms, with or without 6250199Sgrehan * modification, are permitted provided that the following conditions 7250199Sgrehan * are met: 8250199Sgrehan * 1. Redistributions of source code must retain the above copyright 9250199Sgrehan * notice unmodified, this list of conditions, and the following 10250199Sgrehan * disclaimer. 11250199Sgrehan * 2. Redistributions in binary form must reproduce the above copyright 12250199Sgrehan * notice, this list of conditions and the following disclaimer in the 13250199Sgrehan * documentation and/or other materials provided with the distribution. 14250199Sgrehan * 15250199Sgrehan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16250199Sgrehan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17250199Sgrehan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18250199Sgrehan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19250199Sgrehan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20250199Sgrehan * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21250199Sgrehan * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22250199Sgrehan * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23250199Sgrehan * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24250199Sgrehan * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25271493Sdelphij * 26271493Sdelphij * $FreeBSD: head/sys/dev/hyperv/utilities/hv_util.c 303069 2016-07-20 05:34:28Z sephe $ 27250199Sgrehan */ 28250199Sgrehan 29271493Sdelphij/* 30250199Sgrehan * A common driver for all hyper-V util services. 31250199Sgrehan */ 32250199Sgrehan 33250199Sgrehan#include <sys/param.h> 34250199Sgrehan#include <sys/kernel.h> 35250199Sgrehan#include <sys/bus.h> 36250199Sgrehan#include <sys/malloc.h> 37250199Sgrehan#include <sys/module.h> 38250199Sgrehan#include <sys/reboot.h> 39250199Sgrehan#include <sys/timetc.h> 40255414Sgrehan#include <sys/syscallsubr.h> 41250199Sgrehan 42250199Sgrehan#include <dev/hyperv/include/hyperv.h> 43303021Ssephe#include <dev/hyperv/include/vmbus.h> 44303067Ssephe#include <dev/hyperv/utilities/hv_utilreg.h> 45295958Ssephe#include "hv_util.h" 46250199Sgrehan 47295958Ssephevoid 48250199Sgrehanhv_negotiate_version( 49250199Sgrehan struct hv_vmbus_icmsg_hdr* icmsghdrp, 50250199Sgrehan struct hv_vmbus_icmsg_negotiate* negop, 51250199Sgrehan uint8_t* buf) 52255414Sgrehan{ 53250199Sgrehan icmsghdrp->icmsgsize = 0x10; 54250199Sgrehan 55250199Sgrehan negop = (struct hv_vmbus_icmsg_negotiate *)&buf[ 56250199Sgrehan sizeof(struct hv_vmbus_pipe_hdr) + 57250199Sgrehan sizeof(struct hv_vmbus_icmsg_hdr)]; 58250199Sgrehan 59255414Sgrehan if (negop->icframe_vercnt >= 2 && 60250199Sgrehan negop->icversion_data[1].major == 3) { 61250199Sgrehan negop->icversion_data[0].major = 3; 62250199Sgrehan negop->icversion_data[0].minor = 0; 63250199Sgrehan negop->icversion_data[1].major = 3; 64250199Sgrehan negop->icversion_data[1].minor = 0; 65250199Sgrehan } else { 66250199Sgrehan negop->icversion_data[0].major = 1; 67250199Sgrehan negop->icversion_data[0].minor = 0; 68250199Sgrehan negop->icversion_data[1].major = 1; 69250199Sgrehan negop->icversion_data[1].minor = 0; 70250199Sgrehan } 71250199Sgrehan 72250199Sgrehan negop->icframe_vercnt = 1; 73250199Sgrehan negop->icmsg_vercnt = 1; 74250199Sgrehan} 75250199Sgrehan 76295958Ssepheint 77295958Ssephehv_util_attach(device_t dev) 78250199Sgrehan{ 79295958Ssephe struct hv_util_sc* softc; 80303069Ssephe struct hv_vmbus_channel *chan; 81250199Sgrehan int ret; 82250199Sgrehan 83295958Ssephe softc = device_get_softc(dev); 84295958Ssephe softc->receive_buffer = 85255414Sgrehan malloc(4 * PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO); 86303069Ssephe chan = vmbus_get_channel(dev); 87250199Sgrehan 88282212Swhu /* 89282212Swhu * These services are not performance critical and do not need 90282212Swhu * batched reading. Furthermore, some services such as KVP can 91282212Swhu * only handle one message from the host at a time. 92282212Swhu * Turn off batched reading for all util drivers before we open the 93282212Swhu * channel. 94282212Swhu */ 95303069Ssephe vmbus_chan_set_readbatch(chan, false); 96282212Swhu 97303069Ssephe ret = vmbus_chan_open(chan, 4 * PAGE_SIZE, 4 * PAGE_SIZE, NULL, 0, 98303069Ssephe softc->callback, softc); 99250199Sgrehan 100250199Sgrehan if (ret) 101295958Ssephe goto error0; 102250199Sgrehan 103250199Sgrehan return (0); 104250199Sgrehan 105295958Ssepheerror0: 106295958Ssephe free(softc->receive_buffer, M_DEVBUF); 107250199Sgrehan return (ret); 108250199Sgrehan} 109250199Sgrehan 110295958Ssepheint 111250199Sgrehanhv_util_detach(device_t dev) 112250199Sgrehan{ 113302702Ssephe struct hv_util_sc *sc = device_get_softc(dev); 114250199Sgrehan 115303069Ssephe vmbus_chan_close(vmbus_get_channel(dev)); 116302702Ssephe free(sc->receive_buffer, M_DEVBUF); 117250199Sgrehan 118250199Sgrehan return (0); 119250199Sgrehan} 120