The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/hyperv/utilities/vmbus_shutdown.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2014,2016 Microsoft Corp.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice unmodified, this list of conditions, and the following
   10  *    disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include <sys/param.h>
   31 #include <sys/bus.h>
   32 #include <sys/kernel.h>
   33 #include <sys/module.h>
   34 #include <sys/reboot.h>
   35 #include <sys/systm.h>
   36 
   37 #include <dev/hyperv/include/hyperv.h>
   38 #include <dev/hyperv/include/vmbus.h>
   39 #include <dev/hyperv/utilities/vmbus_icreg.h>
   40 #include <dev/hyperv/utilities/vmbus_icvar.h>
   41 
   42 #define VMBUS_SHUTDOWN_FWVER_MAJOR      3
   43 #define VMBUS_SHUTDOWN_FWVER            \
   44         VMBUS_IC_VERSION(VMBUS_SHUTDOWN_FWVER_MAJOR, 0)
   45 
   46 #define VMBUS_SHUTDOWN_MSGVER_MAJOR     3
   47 #define VMBUS_SHUTDOWN_MSGVER           \
   48         VMBUS_IC_VERSION(VMBUS_SHUTDOWN_MSGVER_MAJOR, 0)
   49 
   50 static int                      vmbus_shutdown_probe(device_t);
   51 static int                      vmbus_shutdown_attach(device_t);
   52 
   53 static const struct vmbus_ic_desc vmbus_shutdown_descs[] = {
   54         {
   55                 .ic_guid = { .hv_guid = {
   56                     0x31, 0x60, 0x0b, 0x0e, 0x13, 0x52, 0x34, 0x49,
   57                     0x81, 0x8b, 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb } },
   58                 .ic_desc = "Hyper-V Shutdown"
   59         },
   60         VMBUS_IC_DESC_END
   61 };
   62 
   63 static device_method_t vmbus_shutdown_methods[] = {
   64         /* Device interface */
   65         DEVMETHOD(device_probe,         vmbus_shutdown_probe),
   66         DEVMETHOD(device_attach,        vmbus_shutdown_attach),
   67         DEVMETHOD(device_detach,        vmbus_ic_detach),
   68         DEVMETHOD_END
   69 };
   70 
   71 static driver_t vmbus_shutdown_driver = {
   72         "hvshutdown",
   73         vmbus_shutdown_methods,
   74         sizeof(struct vmbus_ic_softc)
   75 };
   76 
   77 DRIVER_MODULE(hv_shutdown, vmbus, vmbus_shutdown_driver, NULL, NULL);
   78 MODULE_VERSION(hv_shutdown, 1);
   79 MODULE_DEPEND(hv_shutdown, vmbus, 1, 1, 1);
   80 
   81 static void
   82 vmbus_shutdown_cb(struct vmbus_channel *chan, void *xsc)
   83 {
   84         struct vmbus_ic_softc *sc = xsc;
   85         struct vmbus_icmsg_hdr *hdr;
   86         struct vmbus_icmsg_shutdown *msg;
   87         int dlen, error, do_shutdown = 0;
   88         uint64_t xactid;
   89         void *data;
   90 
   91         /*
   92          * Receive request.
   93          */
   94         data = sc->ic_buf;
   95         dlen = sc->ic_buflen;
   96         error = vmbus_chan_recv(chan, data, &dlen, &xactid);
   97         KASSERT(error != ENOBUFS, ("icbuf is not large enough"));
   98         if (error)
   99                 return;
  100 
  101         if (dlen < sizeof(*hdr)) {
  102                 device_printf(sc->ic_dev, "invalid data len %d\n", dlen);
  103                 return;
  104         }
  105         hdr = data;
  106 
  107         /*
  108          * Update request, which will be echoed back as response.
  109          */
  110         switch (hdr->ic_type) {
  111         case VMBUS_ICMSG_TYPE_NEGOTIATE:
  112                 error = vmbus_ic_negomsg(sc, data, &dlen,
  113                     VMBUS_SHUTDOWN_FWVER, VMBUS_SHUTDOWN_MSGVER);
  114                 if (error)
  115                         return;
  116                 break;
  117 
  118         case VMBUS_ICMSG_TYPE_SHUTDOWN:
  119                 if (dlen < VMBUS_ICMSG_SHUTDOWN_SIZE_MIN) {
  120                         device_printf(sc->ic_dev, "invalid shutdown len %d\n",
  121                             dlen);
  122                         return;
  123                 }
  124                 msg = data;
  125 
  126                 /* XXX ic_flags definition? */
  127                 if (msg->ic_haltflags == 0 || msg->ic_haltflags == 1) {
  128                         device_printf(sc->ic_dev, "shutdown requested\n");
  129                         hdr->ic_status = VMBUS_ICMSG_STATUS_OK;
  130                         do_shutdown = 1;
  131                 } else {
  132                         device_printf(sc->ic_dev, "unknown shutdown flags "
  133                             "0x%08x\n", msg->ic_haltflags);
  134                         hdr->ic_status = VMBUS_ICMSG_STATUS_FAIL;
  135                 }
  136                 break;
  137 
  138         default:
  139                 device_printf(sc->ic_dev, "got 0x%08x icmsg\n", hdr->ic_type);
  140                 break;
  141         }
  142 
  143         /*
  144          * Send response by echoing the request back.
  145          */
  146         vmbus_ic_sendresp(sc, chan, data, dlen, xactid);
  147 
  148         if (do_shutdown)
  149                 shutdown_nice(RB_POWEROFF);
  150 }
  151 
  152 static int
  153 vmbus_shutdown_probe(device_t dev)
  154 {
  155 
  156         return (vmbus_ic_probe(dev, vmbus_shutdown_descs));
  157 }
  158 
  159 static int
  160 vmbus_shutdown_attach(device_t dev)
  161 {
  162 
  163         return (vmbus_ic_attach(dev, vmbus_shutdown_cb));
  164 }

Cache object: 4c06ce5ba389f7dcfc68b761618380c0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.