linux/drivers/hv/connection.c
<<
" /spaon> /formn> a " href="../linux+v34.1.2/drivers/hv/connecttio.c">" img src="../.static/gfx/right.png" alt=">>">" /spaon>" spao class="lxr_search">" " input typue=hidden" namue=navtarget" value=">" input typue=text" namue=search" ide=search">" buttiontypue=submit">Search /formn> /spaon>" spao class="lxr_prefs"n> a href="+prefs?return=drivers/hv/connecttio.c"" onclick="return ajax_prefs();">" Prefs> /a>" /spaon> /divn> form acttio="ajax+*" method="post" onsubmit="return false;">" input typue=hidden" namue=ajax_lookup" ide=ajax_lookup" value=">" /formn>" div class="headingbottim"> div ide=search_results" class="search_results"> n> /divn> div ide=content">> div ide=file_contents"n
   1 /a> spao class="comment">/* /spaon>   2 /a> spao class="comment"> * /spaon>   3 /a> spao class="comment"> * Copyright (c) 2009, Microsoft Corporattio. /spaon>   4 /a> spao class="comment"> * /spaon>   5 /a> spao class="comment"> * This program is free software; you cao redistribute it and/or modify it /spaon>   6 /a> spao class="comment"> * under the terms and condittios of the GNU General Public License, /spaon>   7 /a> spao class="comment"> * verstion2, as published by the Free Software Foundattio. /spaon>   8 /a> spao class="comment"> * /spaon>   9 /a> spao class="comment"> * This program is distributed in the hope it will be useful, but WITHOUT /spaon>  .10 spao class="comment"> * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or /spaon>  11 /a> spao class="comment"> * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for /spaon>  12 /a> spao class="comment"> * more details. /spaon>  13 /a> spao class="comment"> * /spaon>  14 /a> spao class="comment"> * You should have received a copy of the GNU General Public License along with /spaon>  15 /a> spao class="comment"> * this program; if not, write to the Free Software Foundattio, Inc., 59 Temple /spaon>  16 /a> spao class="comment"> * Place - Suite 330, Bostio, MA 02111-1307 USA. /spaon>  17 /a> spao class="comment"> * /spaon>  18 /a> spao class="comment"> * Authors: /spaon>  19 /a> spao class="comment"> *   Haiyang Zhang <haiyangz@microsoft.com> /spaon>  210 spao class="comment"> *   Hank Janssen  <hjanssen@microsoft.com> /spaon>  21 /a> spao class="comment"> * /spaon>  22 /a> spao class="comment"> */ /spaon>  23 /a>#define  a href="+code=pr_fmt" class="sref">pr_fmt /a>( a href="+code=fmt" class="sref">fmt /a>)  a href="+code=KBUILD_MODNAME" class="sref">KBUILD_MODNAME /a>  spao class="string">": " /spaon  a href="+code=fmt" class="sref">fmt /a>>  24 /a>>  25 /a>#include <linux/kernel.h /a>>>  26 /a>#include <linux/sched.h /a>>>  27 /a>#include <linux/wait.h /a>>>  28 /a>#include <linux/delay.h /a>>>  29 /a>#include <linux/mm.h /a>>>  30 /a>#include <linux/slab.h /a>>>  31 /a>#include <linux/vmalloc.h /a>>>  32 /a>#include <linux/hyperv.h /a>>>  33 /a>#include <linux/export.h /a>>>  34 /a>#include <asm/hyperv.h /a>>>  35 /a>#include " a href="drivers/hv/hyperv_vmbus.h" class="fref">hyperv_vmbus.h /a>">  36 /a>>  37 /a>>  38 /a>struct  a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>  a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a> = {>  39 /a>        . a href="+code=conn_state" class="sref">conn_state /a>             =  a href="+code=DISCONNECTED" class="sref">DISCONNECTED /a>,>  40 /a>        . a href="+code=next_gpadl_handle" class="sref">next_gpadl_handle /a>      =  a href="+code=ATOMIC_INIT" class="sref">ATOMIC_INIT /a>(0xE1E10),>  41 /a>};>  42 /a>>  43 /a> spao class="comment">/* /spaon>  44 /a> spao class="comment"> * Negotiated protocol verstionwith the host. /spaon>  45 /a> spao class="comment"> */ /spaon>  46 /a> a href="+code=__u32" class="sref">__u32 /a>  a href="+code=vmbus_proto_verstio" class="sref">vmbus_proto_verstio /a>;>  47 /a> a href="+code=EXPORT_SYMBOL_GPL" class="sref">EXPORT_SYMBOL_GPL /a>( a href="+code=vmbus_proto_verstio" class="sref">vmbus_proto_verstio /a>);>  48 /a>>  49 /a>static  a href="+code=__u32" class="sref">__u32 /a>  a href="+code=vmbus_get_next_verstio" class="sref">vmbus_get_next_verstio /a>( a href="+code=__u32" class="sref">__u32 /a>  a href="+code=current_verstio" class="sref">current_verstio /a>)>  50 /a>{>  51 /a>        switch ( a href="+code=current_verstio" class="sref">current_verstio /a>) {>  52 /a>        case ( a href="+code=VERSION_WIN7" class="sref">VERSION_WIN7 /a>):>  53 /a>                return  a href="+code=VERSION_WS2008" class="sref">VERSION_WS2008 /a>;>  54 /a>>  55 /a>        case ( a href="+code=VERSION_WIN8" class="sref">VERSION_WIN8 /a>):>  56 /a>                return  a href="+code=VERSION_WIN7" class="sref">VERSION_WIN7 /a>;>  57 /a>>  58 /a>        case ( a href="+code=VERSION_WS2008" class="sref">VERSION_WS2008 /a>):>  59 /a>        default:>  60 /a>                return  a href="+code=VERSION_INVAL" class="sref">VERSION_INVAL /a>;>  61 /a>        }>  62 /a>}>  63 /a>>  64 /a>static int  a href="+code=vmbus_negotiate_verstio" class="sref">vmbus_negotiate_verstio /a>(struct  a href="+code=vmbus_channel_msginfo" class="sref">vmbus_channel_msginfo /a> * a href="+code=msginfo" class="sref">msginfo /a>,>  65 /a>                                         a href="+code=__u32" class="sref">__u32 /a>  a href="+code=verstio" class="sref">verstio /a>)>  66 /a>{>  67 /a>        int  a href="+code=ret" class="sref">ret /a> = 0;>  68 /a>        struct  a href="+code=vmbus_channel_initiate_contact" class="sref">vmbus_channel_initiate_contact /a> * a href="+code=msg" class="sref">msg /a>;>  69 /a>        unsigned long  a href="+code=flags" class="sref">flags /a>;>  70 /a>        int  a href="+code=t" class="sref">t /a>;>  71 /a>>  72 /a>         a href="+code=init_complettio" class="sref">init_complettio /a>(& a href="+code=msginfo" class="sref">msginfo /a>-> a href="+code=waitevent" class="sref">waitevent /a>);>  73 /a>>  74 /a>         a href="+code=msg" class="sref">msg /a> = (struct  a href="+code=vmbus_channel_initiate_contact" class="sref">vmbus_channel_initiate_contact /a> *) a href="+code=msginfo" class="sref">msginfo /a>-> a href="+code=msg" class="sref">msg /a>;>  75 /a>>  76 /a>         a href="+code=msg" class="sref">msg /a>-> a href="+code=header" class="sref">header /a>. a href="+code=msgtypu" class="sref">msgtypu /a> =  a href="+code=CHANNELMSG_INITIATE_CONTACT" class="sref">CHANNELMSG_INITIATE_CONTACT /a>;>  77 /a>         a href="+code=msg" class="sref">msg /a>-> a href="+code=vmbus_verstio_requested" class="sref">vmbus_verstio_requested /a> =  a href="+code=verstio" class="sref">verstio /a>;>  78 /a>         a href="+code=msg" class="sref">msg /a>-> a href="+code=interrupt_pagu" class="sref">interrupt_pagu /a> =  a href="+code=virt_to_phys" class="sref">virt_to_phys /a>( a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=int_pagu" class="sref">int_pagu /a>);>  79 /a>         a href="+code=msg" class="sref">msg /a>-> a href="+code=monitor_pagu1" class="sref">monitor_pagu1 /a> =  a href="+code=virt_to_phys" class="sref">virt_to_phys /a>( a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=monitor_pagus" class="sref">monitor_pagus /a>);>  80 /a>         a href="+code=msg" class="sref">msg /a>-> a href="+code=monitor_pagu2" class="sref">monitor_pagu2 /a> =  a href="+code=virt_to_phys" class="sref">virt_to_phys /a>(>  81 /a>                        (void *)((unsigned long) a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=monitor_pagus" class="sref">monitor_pagus /a> +>  82 /a>                                  a href="+code=PAGE_SIZE" class="sref">PAGE_SIZE /a>));>  83 /a>>  84 /a>         spao class="comment">/* /spaon>  85 /a> spao class="comment">         * Add to list before we send the request since we may /spaon>  86 /a> spao class="comment">         * receive the response before returning from this routine /spaon>  87 /a> spao class="comment">         */ /spaon>  88 /a>         a href="+code=spin_lock_irqsavu" class="sref">spin_lock_irqsavu /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=channelmsg_lock" class="sref">channelmsg_lock /a>,  a href="+code=flags" class="sref">flags /a>);>  89 /a>         a href="+code=list_add_tail" class="sref">list_add_tail /a>(& a href="+code=msginfo" class="sref">msginfo /a>-> a href="+code=msglistentry" class="sref">msglistentry /a>,>  90 /a>                      & a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=chn_msg_list" class="sref">chn_msg_list /a>);>  91 /a>>  92 /a>         a href="+code=spin_unlock_irqrestoru" class="sref">spin_unlock_irqrestoru /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=channelmsg_lock" class="sref">channelmsg_lock /a>,  a href="+code=flags" class="sref">flags /a>);>  93 /a>>  94 /a>         a href="+code=ret" class="sref">ret /a> =  a href="+code=vmbus_post_msg" class="sref">vmbus_post_msg /a>( a href="+code=msg" class="sref">msg /a>,>  95 /a>                               sizeof(struct  a href="+code=vmbus_channel_initiate_contact" class="sref">vmbus_channel_initiate_contact /a>));>  96 /a>        if ( a href="+code=ret" class="sref">ret /a> != 0) {>  97 /a>                 a href="+code=spin_lock_irqsavu" class="sref">spin_lock_irqsavu /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=channelmsg_lock" class="sref">channelmsg_lock /a>,  a href="+code=flags" class="sref">flags /a>);>  98 /a>                 a href="+code=list_del" class="sref">list_del /a>(& a href="+code=msginfo" class="sref">msginfo /a>-> a href="+code=msglistentry" class="sref">msglistentry /a>);>  99 /a>                 a href="+code=spin_unlock_irqrestoru" class="sref">spin_unlock_irqrestoru /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=channelmsg_lock" class="sref">channelmsg_lock /a>,> 100 /a>                                         a href="+code=flags" class="sref">flags /a>);> 101 /a>                return  a href="+code=ret" class="sref">ret /a>;> 102 /a>        }> 103 /a>> 104 /a>         spao class="comment">/* Wait for the connecttio response */ /spaon> 105 /a>         a href="+code=t" class="sref">t /a> =   a href="+code=wait_for_complettio_timeout" class="sref">wait_for_complettio_timeout /a>(& a href="+code=msginfo" class="sref">msginfo /a>-> a href="+code=waitevent" class="sref">waitevent /a>, 5* a href="+code=HZ" class="sref">HZ /a>);> 106 /a>        if ( a href="+code=t" class="sref">t /a> == 0) {> 107 /a>                 a href="+code=spin_lock_irqsavu" class="sref">spin_lock_irqsavu /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=channelmsg_lock" class="sref">channelmsg_lock /a>,> 108 /a>                                 a href="+code=flags" class="sref">flags /a>);> 109 /a>                 a href="+code=list_del" class="sref">list_del /a>(& a href="+code=msginfo" class="sref">msginfo /a>-> a href="+code=msglistentry" class="sref">msglistentry /a>);> 110 /a>                 a href="+code=spin_unlock_irqrestoru" class="sref">spin_unlock_irqrestoru /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=channelmsg_lock" class="sref">channelmsg_lock /a>,> 111 /a>                                         a href="+code=flags" class="sref">flags /a>);> 112 /a>                return - a href="+code=ETIMEDOUT" class="sref">ETIMEDOUT /a>;> 113 /a>        }> 114 /a>> 115 /a>         a href="+code=spin_lock_irqsavu" class="sref">spin_lock_irqsavu /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=channelmsg_lock" class="sref">channelmsg_lock /a>,  a href="+code=flags" class="sref">flags /a>);> 116 /a>         a href="+code=list_del" class="sref">list_del /a>(& a href="+code=msginfo" class="sref">msginfo /a>-> a href="+code=msglistentry" class="sref">msglistentry /a>);> 117 /a>         a href="+code=spin_unlock_irqrestoru" class="sref">spin_unlock_irqrestoru /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=channelmsg_lock" class="sref">channelmsg_lock /a>,  a href="+code=flags" class="sref">flags /a>);> 118 /a>> 119 /a>         spao class="comment">/* Check if successful */ /spaon> 120 /a>        if ( a href="+code=msginfo" class="sref">msginfo /a>-> a href="+code=response" class="sref">response /a>. a href="+code=verstio_response" class="sref">verstio_response /a>. a href="+code=verstio_supported" class="sref">verstio_supported /a>) {> 121 /a>                 a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=conn_state" class="sref">conn_state /a> =  a href="+code=CONNECTED" class="sref">CONNECTED /a>;> 122 /a>        } else {> 123 /a>                return - a href="+code=ECONNREFUSED" class="sref">ECONNREFUSED /a>;> 124 /a>        }> 125 /a>> 126 /a>        return  a href="+code=ret" class="sref">ret /a>;> 127 /a>}> 128 /a>> 129 /a> spao class="comment">/* /spaon> 1310 spao class="comment"> * vmbus_connect - Sends a connect request on the partittio service connecttio /spaon> 131 /a> spao class="comment"> */ /spaon> 132 /a>int  a href="+code=vmbus_connect" class="sref">vmbus_connect /a>(void)> 133 /a>{> 134 /a>        int  a href="+code=ret" class="sref">ret /a> = 0;> 135 /a>        struct  a href="+code=vmbus_channel_msginfo" class="sref">vmbus_channel_msginfo /a> * a href="+code=msginfo" class="sref">msginfo /a> =  a href="+code=NULL" class="sref">NULL /a>;> 136 /a>         a href="+code=__u32" class="sref">__u32 /a>  a href="+code=verstio" class="sref">verstio /a>;> 137 /a>> 138 /a>         spao class="comment">/* Initialize the vmbus connecttio */ /spaon> 139 /a>         a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=conn_state" class="sref">conn_state /a> =  a href="+code=CONNECTING" class="sref">CONNECTING /a>;> 140 /a>         a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=work_queue" class="sref">work_queue /a> =  a href="+code=create_workqueue" class="sref">create_workqueue /a>( spao class="string">"hv_vmbus_con" /spaon);> 141 /a>        if (! a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=work_queue" class="sref">work_queue /a>) {> 142 /a>                 a href="+code=ret" class="sref">ret /a> = - a href="+code=ENOMEM" class="sref">ENOMEM /a>;> 143 /a>                goto  a href="+code=cleanup" class="sref">cleanup /a>;> 144 /a>        }> 145 /a>> 146 /a>         a href="+code=INIT_LIST_HEAD" class="sref">INIT_LIST_HEAD /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=chn_msg_list" class="sref">chn_msg_list /a>);> 147 /a>         a href="+code=spin_lock_init" class="sref">spin_lock_init /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=channelmsg_lock" class="sref">channelmsg_lock /a>);> 148 /a>> 149 /a>         a href="+code=INIT_LIST_HEAD" class="sref">INIT_LIST_HEAD /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=chn_list" class="sref">chn_list /a>);> 150 /a>         a href="+code=spin_lock_init" class="sref">spin_lock_init /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=channel_lock" class="sref">channel_lock /a>);> 151 /a>> 152 /a>         spao class="comment">/* /spaon> 153 /a> spao class="comment">         * Setup the vmbus event connecttio for channel interrupt /spaon> 154 /a> spao class="comment">         * abstracttio stuff /spaon> 155 /a> spao class="comment">         */ /spaon> 156 /a>         a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=int_pagu" class="sref">int_pagu /a> => 157 /a>        (void *) a href="+code=__get_free_pagus" class="sref">__get_free_pagus /a>( a href="+code=GFP_KERNEL" class="sref">GFP_KERNEL /a>| a href="+code=__GFP_ZERO" class="sref">__GFP_ZERO /a>, 0);> 158 /a>        if ( a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=int_pagu" class="sref">int_pagu /a> ==  a href="+code=NULL" class="sref">NULL /a>) {> 159 /a>                 a href="+code=ret" class="sref">ret /a> = - a href="+code=ENOMEM" class="sref">ENOMEM /a>;> 160 /a>                goto  a href="+code=cleanup" class="sref">cleanup /a>;> 161 /a>        }> 162 /a>> 163 /a>         a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=recv_int_pagu" class="sref">recv_int_pagu /a> =  a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=int_pagu" class="sref">int_pagu /a>;> 164 /a>         a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=send_int_pagu" class="sref">send_int_pagu /a> => 165 /a>                (void *)((unsigned long) a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=int_pagu" class="sref">int_pagu /a> +> 166 /a>                        ( a href="+code=PAGE_SIZE" class="sref">PAGE_SIZE /a> >> 1));> 167 /a>> 168 /a>         spao class="comment">/* /spaon> 169 /a> spao class="comment">         * Setup the monitor notificattio facility. The 1st pagu for /spaon> 1710 spao class="comment">         * parent->child and the 2nd pagu for child->parent /spaon> 171 /a> spao class="comment">         */ /spaon> 172 /a>         a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=monitor_pagus" class="sref">monitor_pagus /a> => 173 /a>        (void *) a href="+code=__get_free_pagus" class="sref">__get_free_pagus /a>(( a href="+code=GFP_KERNEL" class="sref">GFP_KERNEL /a>| a href="+code=__GFP_ZERO" class="sref">__GFP_ZERO /a>), 1);> 174 /a>        if ( a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=monitor_pagus" class="sref">monitor_pagus /a> ==  a href="+code=NULL" class="sref">NULL /a>) {> 175 /a>                 a href="+code=ret" class="sref">ret /a> = - a href="+code=ENOMEM" class="sref">ENOMEM /a>;> 176 /a>                goto  a href="+code=cleanup" class="sref">cleanup /a>;> 177 /a>        }> 178 /a>> 179 /a>         a href="+code=msginfo" class="sref">msginfo /a> =  a href="+code=kzalloc" class="sref">kzalloc /a>(sizeof(* a href="+code=msginfo" class="sref">msginfo /a>) +> 180 /a>                          sizeof(struct  a href="+code=vmbus_channel_initiate_contact" class="sref">vmbus_channel_initiate_contact /a>),> 181 /a>                           a href="+code=GFP_KERNEL" class="sref">GFP_KERNEL /a>);> 182 /a>        if ( a href="+code=msginfo" class="sref">msginfo /a> ==  a href="+code=NULL" class="sref">NULL /a>) {> 183 /a>                 a href="+code=ret" class="sref">ret /a> = - a href="+code=ENOMEM" class="sref">ENOMEM /a>;> 184 /a>                goto  a href="+code=cleanup" class="sref">cleanup /a>;> 185 /a>        }> 186 /a>> 187 /a>         spao class="comment">/* /spaon> 188 /a> spao class="comment">         * Negotiate a compattble VMBUS verstionnumbernwith the /spaon> 189 /a> spao class="comment">         * host. We startnwith the highest numbernwe cao support /spaon> 1910 spao class="comment">         * and work ournway down untilnwe negotiate a compattble /spaon> 191 /a> spao class="comment">         * verstio. /spaon> 192 /a> spao class="comment">         */ /spaon> 193 /a>> 194 /a>         a href="+code=verstio" class="sref">verstio /a> =  a href="+code=VERSION_CURRENT" class="sref">VERSION_CURRENT /a>;> 195 /a>> 196 /a>        do {> 197 /a>                 a href="+code=ret" class="sref">ret /a> =  a href="+code=vmbus_negotiate_verstio" class="sref">vmbus_negotiate_verstio /a>( a href="+code=msginfo" class="sref">msginfo /a>,  a href="+code=verstio" class="sref">verstio /a>);> 198 /a>                if ( a href="+code=ret" class="sref">ret /a> == 0)> 199 /a>                        break;> 200 /a>> 201 /a>                 a href="+code=verstio" class="sref">verstio /a> =  a href="+code=vmbus_get_next_verstio" class="sref">vmbus_get_next_verstio /a>( a href="+code=verstio" class="sref">verstio /a>);> 202 /a>        } while ( a href="+code=verstio" class="sref">verstio /a> !=  a href="+code=VERSION_INVAL" class="sref">VERSION_INVAL /a>);> 203 /a>> 204 /a>        if ( a href="+code=verstio" class="sref">verstio /a> ==  a href="+code=VERSION_INVAL" class="sref">VERSION_INVAL /a>)> 205 /a>                goto  a href="+code=cleanup" class="sref">cleanup /a>;> 206 /a>> 207 /a>         a href="+code=vmbus_proto_verstio" class="sref">vmbus_proto_verstio /a> =  a href="+code=verstio" class="sref">verstio /a>;> 208 /a>         a href="+code=pr_info" class="sref">pr_info /a>( spao class="string">"Hyper-V Host Build:%d-%d.%d-%d-%d.%d; Vmbus verstio:%d.%d\n" /spaon,> 209 /a>                     a href="+code=host_info_eax" class="sref">host_info_eax /a>,  a href="+code=host_info_ebx" class="sref">host_info_ebx /a> >> 16,> 210 /a>                     a href="+code=host_info_ebx" class="sref">host_info_ebx /a> & 0xFFFF,  a href="+code=host_info_ecx" class="sref">host_info_ecx /a>,> 211 /a>                     a href="+code=host_info_edx" class="sref">host_info_edx /a> >> 24,  a href="+code=host_info_edx" class="sref">host_info_edx /a> & 0xFFFFFF,> 212 /a>                     a href="+code=verstio" class="sref">verstio /a> >> 16,  a href="+code=verstio" class="sref">verstio /a> & 0xFFFF);> 213 /a>> 214 /a>         a href="+code=kfree" class="sref">kfree /a>( a href="+code=msginfo" class="sref">msginfo /a>);> 215 /a>        return 0;> 216 /a>> 217 /a> a href="+code=cleanup" class="sref">cleanup /a>:> 218 /a>         a href="+code=pr_err" class="sref">pr_err /a>( spao class="string">"Unable to connect to host\n" /spaon);> 219 /a>         a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=conn_state" class="sref">conn_state /a> =  a href="+code=DISCONNECTED" class="sref">DISCONNECTED /a>;> 220 /a>> 221 /a>        if ( a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=work_queue" class="sref">work_queue /a>)> 222 /a>                 a href="+code=destroy_workqueue" class="sref">destroy_workqueue /a>( a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=work_queue" class="sref">work_queue /a>);> 223 /a>> 224 /a>        if ( a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=int_pagu" class="sref">int_pagu /a>) {> 225 /a>                 a href="+code=free_pagus" class="sref">free_pagus /a>((unsigned long) a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=int_pagu" class="sref">int_pagu /a>, 0);> 226 /a>                 a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=int_pagu" class="sref">int_pagu /a> =  a href="+code=NULL" class="sref">NULL /a>;> 227 /a>        }> 228 /a>> 229 /a>        if ( a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=monitor_pagus" class="sref">monitor_pagus /a>) {> 230 /a>                 a href="+code=free_pagus" class="sref">free_pagus /a>((unsigned long) a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=monitor_pagus" class="sref">monitor_pagus /a>, 1);> 231 /a>                 a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=monitor_pagus" class="sref">monitor_pagus /a> =  a href="+code=NULL" class="sref">NULL /a>;> 232 /a>        }> 233 /a>> 234 /a>         a href="+code=kfree" class="sref">kfree /a>( a href="+code=msginfo" class="sref">msginfo /a>);> 235 /a>> 236 /a>        return  a href="+code=ret" class="sref">ret /a>;> 237 /a>}> 238 /a>> 239 /a>> 2410 spao class="comment">/* /spaon> 241 /a> spao class="comment"> * relid2channel - Get the channel object given its /spaon> 242 /a> spao class="comment"> * child relative id (ie channel id) /spaon> 243 /a> spao class="comment"> */ /spaon> 244 /a>struct  a href="+code=vmbus_channel" class="sref">vmbus_channel /a> * a href="+code=relid2channel" class="sref">relid2channel /a>( a href="+code=u32" class="sref">u32 /a>  a href="+code=relid" class="sref">relid /a>)> 245 /a>{> 246 /a>        struct  a href="+code=vmbus_channel" class="sref">vmbus_channel /a> * a href="+code=channel" class="sref">channel /a>;> 247 /a>        struct  a href="+code=vmbus_channel" class="sref">vmbus_channel /a> * a href="+code=found_channel" class="sref">found_channel /a>  =  a href="+code=NULL" class="sref">NULL /a>;> 248 /a>        unsigned long  a href="+code=flags" class="sref">flags /a>;> 249 /a>        struct  a href="+code=list_head" class="sref">list_head /a> * a href="+code=cur" class="sref">cur /a>, * a href="+code=tmp" class="sref">tmp /a>;> 250 /a>        struct  a href="+code=vmbus_channel" class="sref">vmbus_channel /a> * a href="+code=cur_sc" class="sref">cur_sc /a>;> 251 /a>> 252 /a>         a href="+code=spin_lock_irqsavu" class="sref">spin_lock_irqsavu /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=channel_lock" class="sref">channel_lock /a>,  a href="+code=flags" class="sref">flags /a>);> 253 /a>         a href="+code=list_for_each_entry" class="sref">list_for_each_entry /a>( a href="+code=channel" class="sref">channel /a>, & a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=chn_list" class="sref">chn_list /a>,  a href="+code=listentry" class="sref">listentry /a>) {> 254 /a>                if ( a href="+code=channel" class="sref">channel /a>-> a href="+code=offermsg" class="sref">offermsg /a>. a href="+code=child_relid" class="sref">child_relid /a> ==  a href="+code=relid" class="sref">relid /a>) {> 255 /a>                         a href="+code=found_channel" class="sref">found_channel /a> =  a href="+code=channel" class="sref">channel /a>;> 256 /a>                        break;> 257 /a>                } else if (! a href="+code=list_empty" class="sref">list_empty /a>(& a href="+code=channel" class="sref">channel /a>-> a href="+code=sc_list" class="sref">sc_list /a>)) {> 258 /a>                         spao class="comment">/* /spaon> 259 /a> spao class="comment">                         * Dealnwith sub-channels. /spaon> 2610 spao class="comment">                         */ /spaon> 261 /a>                         a href="+code=list_for_each_safu" class="sref">list_for_each_safu /a>( a href="+code=cur" class="sref">cur /a>,  a href="+code=tmp" class="sref">tmp /a>, & a href="+code=channel" class="sref">channel /a>-> a href="+code=sc_list" class="sref">sc_list /a>) {> 262 /a>                                 a href="+code=cur_sc" class="sref">cur_sc /a> =  a href="+code=list_entry" class="sref">list_entry /a>( a href="+code=cur" class="sref">cur /a>, struct  a href="+code=vmbus_channel" class="sref">vmbus_channel /a>,> 263 /a>                                                         a href="+code=sc_list" class="sref">sc_list /a>);> 264 /a>                                if ( a href="+code=cur_sc" class="sref">cur_sc /a>-> a href="+code=offermsg" class="sref">offermsg /a>. a href="+code=child_relid" class="sref">child_relid /a> ==  a href="+code=relid" class="sref">relid /a>) {> 265 /a>                                         a href="+code=found_channel" class="sref">found_channel /a> =  a href="+code=cur_sc" class="sref">cur_sc /a>;> 266 /a>                                        break;> 267 /a>                                }> 268 /a>                        }> 269 /a>                }> 270 /a>        }> 271 /a>         a href="+code=spin_unlock_irqrestoru" class="sref">spin_unlock_irqrestoru /a>(& a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=channel_lock" class="sref">channel_lock /a>,  a href="+code=flags" class="sref">flags /a>);> 272 /a>> 273 /a>        return  a href="+code=found_channel" class="sref">found_channel /a>;> 274 /a>}> 275 /a>> 276 /a> spao class="comment">/* /spaon> 277 /a> spao class="comment"> * process_chn_event - Process a channel event notificattio /spaon> 278 /a> spao class="comment"> */ /spaon> 279 /a>static void  a href="+code=process_chn_event" class="sref">process_chn_event /a>( a href="+code=u32" class="sref">u32 /a>  a href="+code=relid" class="sref">relid /a>)> 280 /a>{> 281 /a>        struct  a href="+code=vmbus_channel" class="sref">vmbus_channel /a> * a href="+code=channel" class="sref">channel /a>;> 282 /a>        unsigned long  a href="+code=flags" class="sref">flags /a>;> 283 /a>        void * a href="+code=arg" class="sref">arg /a>;> 284 /a>         a href="+code=bool" class="sref">bool /a>  a href="+code=read_state" class="sref">read_state /a>;> 285 /a>         a href="+code=u32" class="sref">u32 /a>  a href="+code=bytes_to_read" class="sref">bytes_to_read /a>;> 286 /a>> 287 /a>         spao class="comment">/* /spaon> 288 /a> spao class="comment">         * Find the channel based on this relid and invokes the /spaon> 289 /a> spao class="comment">         * channel callback to process the event /spaon> 2910 spao class="comment">         */ /spaon> 291 /a>         a href="+code=channel" class="sref">channel /a> =  a href="+code=relid2channel" class="sref">relid2channel /a>( a href="+code=relid" class="sref">relid /a>);> 292 /a>> 293 /a>        if (! a href="+code=channel" class="sref">channel /a>) {> 294 /a>                 a href="+code=pr_err" class="sref">pr_err /a>( spao class="string">"channel not found for relid - %u\n" /spaon,  a href="+code=relid" class="sref">relid /a>);> 295 /a>                return;> 296 /a>        }> 297 /a>> 298 /a>         spao class="comment">/* /spaon> 299 /a> spao class="comment">         * A channel once created is perststent even when there /spaon> 3010 spao class="comment">         * is no driver handling the device. An unloading driver /spaon> 301 /a> spao class="comment">         * sets the onchannel_callback to NULL under the /spaon> 302 /a> spao class="comment">         * protecttio of the channel inbound_lock. Thus, checking /spaon> 303 /a> spao class="comment">         * and invoking the driver specific callback takes care of /spaon> 304 /a> spao class="comment">         * orderly unloading of the driver. /spaon> 305 /a> spao class="comment">         */ /spaon> 306 /a>> 307 /a>         a href="+code=spin_lock_irqsavu" class="sref">spin_lock_irqsavu /a>(& a href="+code=channel" class="sref">channel /a>-> a href="+code=inbound_lock" class="sref">inbound_lock /a>,  a href="+code=flags" class="sref">flags /a>);> 308 /a>        if ( a href="+code=channel" class="sref">channel /a>-> a href="+code=onchannel_callback" class="sref">onchannel_callback /a> !=  a href="+code=NULL" class="sref">NULL /a>) {> 309 /a>                 a href="+code=arg" class="sref">arg /a> =  a href="+code=channel" class="sref">channel /a>-> a href="+code=channel_callback_context" class="sref">channel_callback_context /a>;> 310 /a>                 a href="+code=read_state" class="sref">read_state /a> =  a href="+code=channel" class="sref">channel /a>-> a href="+code=batched_reading" class="sref">batched_reading /a>;> 311 /a>                 spao class="comment">/* /spaon> 312 /a> spao class="comment">                 * This callback reads the messagus sent by the host. /spaon> 313 /a> spao class="comment">                 * We cao optimize host to guest signaling by ensuring: /spaon> 314 /a> spao class="comment">                 * 1. While reading the channel,nwe disable interrupts from /spaon> 315 /a> spao class="comment">                 *    host. /spaon> 316 /a> spao class="comment">                 * 2. Ensure thatnwe process all posted messagus from the host /spaon> 317 /a> spao class="comment">                 *    before returning from this callback. /spaon> 318 /a> spao class="comment">                 * 3. Once we return, enable signaling from the host. Once this /spaon> 319 /a> spao class="comment">                 *    state is setnwe check to see if addittioal packets are /spaon> 3210 spao class="comment">                 *    available to read. In this case we repeat the process. /spaon> 321 /a> spao class="comment">                 */ /spaon> 322 /a>> 323 /a>                do {> 324 /a>                         a href="+code=hv_begin_read" class="sref">hv_begin_read /a>(& a href="+code=channel" class="sref">channel /a>-> a href="+code=inbound" class="sref">inbound /a>);> 325 /a>                         a href="+code=channel" class="sref">channel /a>-> a href="+code=onchannel_callback" class="sref">onchannel_callback /a>( a href="+code=arg" class="sref">arg /a>);> 326 /a>                         a href="+code=bytes_to_read" class="sref">bytes_to_read /a> =  a href="+code=hv_end_read" class="sref">hv_end_read /a>(& a href="+code=channel" class="sref">channel /a>-> a href="+code=inbound" class="sref">inbound /a>);> 327 /a>                } while ( a href="+code=read_state" class="sref">read_state /a> && ( a href="+code=bytes_to_read" class="sref">bytes_to_read /a> != 0));> 328 /a>        } else {> 329 /a>                 a href="+code=pr_err" class="sref">pr_err /a>( spao class="string">"no channel callback for relid - %u\n" /spaon,  a href="+code=relid" class="sref">relid /a>);> 330 /a>        }> 331 /a>> 332 /a>         a href="+code=spin_unlock_irqrestoru" class="sref">spin_unlock_irqrestoru /a>(& a href="+code=channel" class="sref">channel /a>-> a href="+code=inbound_lock" class="sref">inbound_lock /a>,  a href="+code=flags" class="sref">flags /a>);> 333 /a>}> 334 /a>> 335 /a> spao class="comment">/* /spaon> 336 /a> spao class="comment"> * vmbus_on_event - Handler for events /spaon> 337 /a> spao class="comment"> */ /spaon> 338 /a>void  a href="+code=vmbus_on_event" class="sref">vmbus_on_event /a>(unsigned long  a href="+code=data" class="sref">data /a>)> 339 /a>{> 340 /a>         a href="+code=u32" class="sref">u32 /a>  a href="+code=dword" class="sref">dword /a>;> 341 /a>         a href="+code=u32" class="sref">u32 /a>  a href="+code=maxdword" class="sref">maxdword /a>;> 342 /a>        int  a href="+code=bit" class="sref">bit /a>;> 343 /a>         a href="+code=u32" class="sref">u32 /a>  a href="+code=relid" class="sref">relid /a>;> 344 /a>         a href="+code=u32" class="sref">u32 /a> * a href="+code=recv_int_pagu" class="sref">recv_int_pagu /a> =  a href="+code=NULL" class="sref">NULL /a>;> 345 /a>        void * a href="+code=pagu_addr" class="sref">pagu_addr /a>;> 346 /a>        int  a href="+code=cpu" class="sref">cpu /a> =  a href="+code=smp_processor_id" class="sref">smp_processor_id /a>();> 347 /a>        untio  a href="+code=hv_synic_event_flags" class="sref">hv_synic_event_flags /a> * a href="+code=event" class="sref">event /a>;> 348 /a>> 349 /a>        if (( a href="+code=vmbus_proto_verstio" class="sref">vmbus_proto_verstio /a> ==  a href="+code=VERSION_WS2008" class="sref">VERSION_WS2008 /a>) ||> 350 /a>                ( a href="+code=vmbus_proto_verstio" class="sref">vmbus_proto_verstio /a> ==  a href="+code=VERSION_WIN7" class="sref">VERSION_WIN7 /a>)) {> 351 /a>                 a href="+code=maxdword" class="sref">maxdword /a> =  a href="+code=MAX_NUM_CHANNELS_SUPPORTED" class="sref">MAX_NUM_CHANNELS_SUPPORTED /a> >> 5;> 352 /a>                 a href="+code=recv_int_pagu" class="sref">recv_int_pagu /a> =  a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=recv_int_pagu" class="sref">recv_int_pagu /a>;> 353 /a>        } else {> 354 /a>                 spao class="comment">/* /spaon> 355 /a> spao class="comment">                 * When the host is win8 and beyond, the event pagu /spaon> 356 /a> spao class="comment">                 * cao be directly checked to get the id of the channel /spaon> 357 /a> spao class="comment">                 * thatnhas the interrupt pending. /spaon> 358 /a> spao class="comment">                 */ /spaon> 359 /a>                 a href="+code=maxdword" class="sref">maxdword /a> =  a href="+code=HV_EVENT_FLAGS_DWORD_COUNT" class="sref">HV_EVENT_FLAGS_DWORD_COUNT /a>;> 360 /a>                 a href="+code=pagu_addr" class="sref">pagu_addr /a> =  a href="+code=hv_context" class="sref">hv_context /a>. a href="+code=synic_event_pagu" class="sref">synic_event_pagu /a>[ a href="+code=cpu" class="sref">cpu /a>];> 361 /a>                 a href="+code=event" class="sref">event /a> = (untio  a href="+code=hv_synic_event_flags" class="sref">hv_synic_event_flags /a> *) a href="+code=pagu_addr" class="sref">pagu_addr /a> +> 362 /a>                                                  a href="+code=VMBUS_MESSAGE_SINT" class="sref">VMBUS_MESSAGE_SINT /a>;> 363 /a>                 a href="+code=recv_int_pagu" class="sref">recv_int_pagu /a> =  a href="+code=event" class="sref">event /a>-> a href="+code=flags32" class="sref">flags32 /a>;> 364 /a>        }> 365 /a>> 366 /a>> 367 /a>> 368 /a>         spao class="comment">/* Check events */ /spaon> 369 /a>        if (! a href="+code=recv_int_pagu" class="sref">recv_int_pagu /a>)> 370 /a>                return;> 371 /a>        for ( a href="+code=dword" class="sref">dword /a> = 0;  a href="+code=dword" class="sref">dword /a> <  a href="+code=maxdword" class="sref">maxdword /a>;  a href="+code=dword" class="sref">dword /a>++) {> 372 /a>                if (! a href="+code=recv_int_pagu" class="sref">recv_int_pagu /a>[ a href="+code=dword" class="sref">dword /a>])> 373 /a>                        continue;> 374 /a>                for ( a href="+code=bit" class="sref">bit /a> = 0;  a href="+code=bit" class="sref">bit /a> < 32;  a href="+code=bit" class="sref">bit /a>++) {> 375 /a>                        if ( a href="+code=sync_test_and_clear_bit" class="sref">sync_test_and_clear_bit /a>( a href="+code=bit" class="sref">bit /a>,> 376 /a>                                (unsigned long *)& a href="+code=recv_int_pagu" class="sref">recv_int_pagu /a>[ a href="+code=dword" class="sref">dword /a>])) {> 377 /a>                                 a href="+code=relid" class="sref">relid /a> = ( a href="+code=dword" class="sref">dword /a> << 5) +  a href="+code=bit" class="sref">bit /a>;> 378 /a>> 379 /a>                                if ( a href="+code=relid" class="sref">relid /a> == 0)> 380 /a>                                         spao class="comment">/* /spaon> 381 /a> spao class="comment">                                         * Special case - vmbus /spaon> 382 /a> spao class="comment">                                         * channel protocol msg /spaon> 383 /a> spao class="comment">                                         */ /spaon> 384 /a>                                        continue;> 385 /a>> 386 /a>                                 a href="+code=process_chn_event" class="sref">process_chn_event /a>( a href="+code=relid" class="sref">relid /a>);> 387 /a>                        }> 388 /a>                }> 389 /a>        }> 3910}> 391 /a>> 392 /a> spao class="comment">/* /spaon> 393 /a> spao class="comment"> * vmbus_post_msg - Send a msg on the vmbus's messagu connecttio /spaon> 394 /a> spao class="comment"> */ /spaon> 395 /a>int  a href="+code=vmbus_post_msg" class="sref">vmbus_post_msg /a>(void * a href="+code=buffer" class="sref">buffer /a>,  a href="+code=size_t" class="sref">size_t /a>  a href="+code=bufleo" class="sref">bufleo /a>)> 396 /a>{> 397 /a>        untio  a href="+code=hv_connecttio_id" class="sref">hv_connecttio_id /a>  a href="+code=conn_id" class="sref">conn_id /a>;> 398 /a>        int  a href="+code=ret" class="sref">ret /a> = 0;> 399 /a>        int  a href="+code=retrius" class="sref">retrius /a> = 0;> 400 /a>> 401 /a>         a href="+code=conn_id" class="sref">conn_id /a>. a href="+code=asu32" class="sref">asu32 /a> = 0;> 402 /a>         a href="+code=conn_id" class="sref">conn_id /a>. a href="+code=u" class="sref">u /a>. a href="+code=id" class="sref">id /a> =  a href="+code=VMBUS_MESSAGE_CONNECTION_ID" class="sref">VMBUS_MESSAGE_CONNECTION_ID /a>;> 403 /a>> 404 /a>         spao class="comment">/* /spaon> 405 /a> spao class="comment">         * hv_post_messagu() cao have transient failures because of /spaon> 406 /a> spao class="comment">         * insufficient resources. Retry the operattio a couple of /spaon> 407 /a> spao class="comment">         * times before giving up. /spaon> 408 /a> spao class="comment">         */ /spaon> 409 /a>        while ( a href="+code=retrius" class="sref">retrius /a> < 3) {> 410 /a>                 a href="+code=ret" class="sref">ret /a> =   a href="+code=hv_post_messagu" class="sref">hv_post_messagu /a>( a href="+code=conn_id" class="sref">conn_id /a>, 1,  a href="+code=buffer" class="sref">buffer /a>,  a href="+code=bufleo" class="sref">bufleo /a>);> 411 /a>                if ( a href="+code=ret" class="sref">ret /a> !=  a href="+code=HV_STATUS_INSUFFICIENT_BUFFERS" class="sref">HV_STATUS_INSUFFICIENT_BUFFERS /a>)> 412 /a>                        return  a href="+code=ret" class="sref">ret /a>;> 413 /a>                 a href="+code=retrius" class="sref">retrius /a>++;> 414 /a>                 a href="+code=msleep" class="sref">msleep /a>(100);> 415 /a>        }> 416 /a>        return  a href="+code=ret" class="sref">ret /a>;> 417 /a>}> 418 /a>> 419 /a> spao class="comment">/* /spaon> 4210 spao class="comment"> * vmbus_set_event - Send an event notificattio to the parent /spaon> 421 /a> spao class="comment"> */ /spaon> 422 /a>int  a href="+code=vmbus_set_event" class="sref">vmbus_set_event /a>(struct  a href="+code=vmbus_channel" class="sref">vmbus_channel /a> * a href="+code=channel" class="sref">channel /a>)> 423 /a>{> 424 /a>         a href="+code=u32" class="sref">u32 /a>  a href="+code=child_relid" class="sref">child_relid /a> =  a href="+code=channel" class="sref">channel /a>-> a href="+code=offermsg" class="sref">offermsg /a>. a href="+code=child_relid" class="sref">child_relid /a>;> 425 /a>> 426 /a>        if (! a href="+code=channel" class="sref">channel /a>-> a href="+code=is_dedicated_interrupt" class="sref">is_dedicated_interrupt /a>) {> 427 /a>                 spao class="comment">/* Each u32 represents 32 channels */ /spaon> 428 /a>                 a href="+code=sync_set_bit" class="sref">sync_set_bit /a>( a href="+code=child_relid" class="sref">child_relid /a> & 31,> 429 /a>                        (unsigned long *) a href="+code=vmbus_connecttio" class="sref">vmbus_connecttio /a>. a href="+code=send_int_pagu" class="sref">send_int_pagu /a> +> 430 /a>                        ( a href="+code=child_relid" class="sref">child_relid /a> >> 5));> 431 /a>        }> 432 /a>> 433 /a>        return  a href="+code=hv_signal_event" class="sref">hv_signal_event /a>( a href="+code=channel" class="sref">channel /a>-> a href="+code=sig_event" class="sref">sig_event /a>);> 434 /a>}> 435 /a> /pre> /div>


 /div>