vmbus_ic.c revision 298446
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 298446 2016-04-22 05:01:43Z 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> 43295958Ssephe#include "hv_util.h" 44250199Sgrehan 45295958Ssephevoid 46250199Sgrehanhv_negotiate_version( 47250199Sgrehan struct hv_vmbus_icmsg_hdr* icmsghdrp, 48250199Sgrehan struct hv_vmbus_icmsg_negotiate* negop, 49250199Sgrehan uint8_t* buf) 50255414Sgrehan{ 51250199Sgrehan icmsghdrp->icmsgsize = 0x10; 52250199Sgrehan 53250199Sgrehan negop = (struct hv_vmbus_icmsg_negotiate *)&buf[ 54250199Sgrehan sizeof(struct hv_vmbus_pipe_hdr) + 55250199Sgrehan sizeof(struct hv_vmbus_icmsg_hdr)]; 56250199Sgrehan 57255414Sgrehan if (negop->icframe_vercnt >= 2 && 58250199Sgrehan negop->icversion_data[1].major == 3) { 59250199Sgrehan negop->icversion_data[0].major = 3; 60250199Sgrehan negop->icversion_data[0].minor = 0; 61250199Sgrehan negop->icversion_data[1].major = 3; 62250199Sgrehan negop->icversion_data[1].minor = 0; 63250199Sgrehan } else { 64250199Sgrehan negop->icversion_data[0].major = 1; 65250199Sgrehan negop->icversion_data[0].minor = 0; 66250199Sgrehan negop->icversion_data[1].major = 1; 67250199Sgrehan negop->icversion_data[1].minor = 0; 68250199Sgrehan } 69250199Sgrehan 70250199Sgrehan negop->icframe_vercnt = 1; 71250199Sgrehan negop->icmsg_vercnt = 1; 72250199Sgrehan} 73250199Sgrehan 74295958Ssepheint 75295958Ssephehv_util_attach(device_t dev) 76250199Sgrehan{ 77295958Ssephe struct hv_device* hv_dev; 78295958Ssephe struct hv_util_sc* softc; 79250199Sgrehan int ret; 80250199Sgrehan 81250199Sgrehan hv_dev = vmbus_get_devctx(dev); 82295958Ssephe softc = device_get_softc(dev); 83295958Ssephe softc->hv_dev = hv_dev; 84295958Ssephe softc->receive_buffer = 85255414Sgrehan malloc(4 * PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO); 86250199Sgrehan 87282212Swhu /* 88282212Swhu * These services are not performance critical and do not need 89282212Swhu * batched reading. Furthermore, some services such as KVP can 90282212Swhu * only handle one message from the host at a time. 91282212Swhu * Turn off batched reading for all util drivers before we open the 92282212Swhu * channel. 93282212Swhu */ 94282212Swhu hv_set_channel_read_state(hv_dev->channel, FALSE); 95282212Swhu 96255414Sgrehan ret = hv_vmbus_channel_open(hv_dev->channel, 4 * PAGE_SIZE, 97295958Ssephe 4 * PAGE_SIZE, NULL, 0, 98295958Ssephe 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{ 113295958Ssephe struct hv_device* hv_dev; 114295958Ssephe struct hv_util_sc* softc; 115250199Sgrehan 116250199Sgrehan hv_dev = vmbus_get_devctx(dev); 117250199Sgrehan 118250199Sgrehan hv_vmbus_channel_close(hv_dev->channel); 119295958Ssephe softc = device_get_softc(dev); 120250199Sgrehan 121295958Ssephe free(softc->receive_buffer, M_DEVBUF); 122250199Sgrehan return (0); 123250199Sgrehan} 124