FreeBSD/sys/dev/hyperv/vmbus/hv_connection.c
/**
 * Negotiate the highest supported hypervisor version.
 */
Negotiate the highest supported hypervisor version.
Negotiate the highest supported hypervisor version .
static int
hv_vmbus_negotiate_version(struct vmbus_softc *sc,
    hv_vmbus_channel_msg_info *msg_info, uint32_t version)
{
	int					ret = 0;
	hv_vmbus_channel_initiate_contact	*msg;
	sema_init(&msg_info->wait_sema, 0, "Msg Info Sema");
	msg = (hv_vmbus_channel_initiate_contact*) msg_info->msg;
	msg->header.message_type = HV_CHANNEL_MESSAGE_INITIATED_CONTACT;
	msg->vmbus_version_requested = version;
	msg->interrupt_page = sc->vmbus_evtflags_dma.hv_paddr;
	msg->monitor_page_1 = sc->vmbus_mnf1_dma.hv_paddr;
	msg->monitor_page_2 = sc->vmbus_mnf2_dma.hv_paddr;
	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
	TAILQ_INSERT_TAIL(
		&hv_vmbus_g_connection.channel_msg_anchor,
		msg_info,
		msg_list_entry);
	mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
	ret = hv_vmbus_post_message(
		msg,
		sizeof(hv_vmbus_channel_initiate_contact));
	if (ret != 0) {
		mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
		TAILQ_REMOVE(
			&hv_vmbus_g_connection.channel_msg_anchor,
			msg_info,
			msg_list_entry);
		mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
		return (ret);
	}
	ret = sema_timedwait(&msg_info->wait_sema, 5 * hz); 
	mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
	TAILQ_REMOVE(
		&hv_vmbus_g_connection.channel_msg_anchor,
		msg_info,
		msg_list_entry);
	mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
	if (msg_info->response.version_response.version_supported) {
		hv_vmbus_g_connection.connect_state = HV_CONNECTED;
	} else {
		ret = ECONNREFUSED;
	}
	return (ret);
}
static int hv_vmbus_negotiate_version ( struct vmbus_softc * sc , hv_vmbus_channel_msg_info * msg_info , uint32_t version ) { int ret = 0 ; hv_vmbus_channel_initiate_contact * msg ; sema_init ( & msg_info -> wait_sema , 0 , " " ) ; msg = ( hv_vmbus_channel_initiate_contact * ) msg_info -> msg ; msg -> header . message_type = HV_CHANNEL_MESSAGE_INITIATED_CONTACT ; msg -> vmbus_version_requested = version ; msg -> interrupt_page = sc -> vmbus_evtflags_dma . hv_paddr ; msg -> monitor_page_1 = sc -> vmbus_mnf1_dma . hv_paddr ; msg -> monitor_page_2 = sc -> vmbus_mnf2_dma . hv_paddr ; mtx_lock ( & hv_vmbus_g_connection . channel_msg_lock ) ; TAILQ_INSERT_TAIL ( & hv_vmbus_g_connection . channel_msg_anchor , msg_info , msg_list_entry ) ; mtx_unlock ( & hv_vmbus_g_connection . channel_msg_lock ) ; ret = hv_vmbus_post_message ( msg , sizeof ( hv_vmbus_channel_initiate_contact ) ) ; if ( ret != 0 ) { mtx_lock ( & hv_vmbus_g_connection . channel_msg_lock ) ; TAILQ_REMOVE ( & hv_vmbus_g_connection . channel_msg_anchor , msg_info , msg_list_entry ) ; mtx_unlock ( & hv_vmbus_g_connection . channel_msg_lock ) ; return ( ret ) ; } ret = sema_timedwait ( & msg_info -> wait_sema , 5 * hz ) ; mtx_lock ( & hv_vmbus_g_connection . channel_msg_lock ) ; TAILQ_REMOVE ( & hv_vmbus_g_connection . channel_msg_anchor , msg_info , msg_list_entry ) ; mtx_unlock ( & hv_vmbus_g_connection . channel_msg_lock ) ; if ( msg_info -> response . version_response . version_supported ) { hv_vmbus_g_connection . connect_state = HV_CONNECTED ; } else { ret = ECONNREFUSED ; } return ( ret ) ; }
Negotiate the highest supported hypervisor version.
Negotiate the highest supported hypervisor version .
/**
	 * Add to list before we send the request since we may receive the
	 * response before returning from this routine
	 */ /**
	 * Wait for the connection response
	 */ /* KYS 5 seconds */ /**
	 * Check if successful
	 */