FreeBSD/sys/dev/hyperv/vmbus/hv_connection.c
/**
 * Send a connect request on the partition service connection
 */
Send a connect request on the partition service connection
Send a connect request on the partition service connection
int
hv_vmbus_connect(struct vmbus_softc *sc)
{
	int					ret = 0;
	uint32_t				version;
	hv_vmbus_channel_msg_info*		msg_info = NULL;
	if (hv_vmbus_g_connection.connect_state != HV_DISCONNECTED) {
		return (-1);
	}
	hv_vmbus_g_connection.connect_state = HV_CONNECTING;
	TAILQ_INIT(&hv_vmbus_g_connection.channel_msg_anchor);
	mtx_init(&hv_vmbus_g_connection.channel_msg_lock, "vmbus channel msg",
		NULL, MTX_DEF);
	TAILQ_INIT(&hv_vmbus_g_connection.channel_anchor);
	mtx_init(&hv_vmbus_g_connection.channel_lock, "vmbus channel",
		NULL, MTX_DEF);
	msg_info = (hv_vmbus_channel_msg_info*)
		malloc(sizeof(hv_vmbus_channel_msg_info) +
			sizeof(hv_vmbus_channel_initiate_contact),
			M_DEVBUF, M_WAITOK | M_ZERO);
	hv_vmbus_g_connection.channels = malloc(sizeof(hv_vmbus_channel*) *
	    VMBUS_CHAN_MAX, M_DEVBUF, M_WAITOK | M_ZERO);
	version = HV_VMBUS_VERSION_CURRENT;
	do {
		ret = hv_vmbus_negotiate_version(sc, msg_info, version);
		if (ret == EWOULDBLOCK) {
			goto cleanup;
		}
		if (hv_vmbus_g_connection.connect_state == HV_CONNECTED)
			break;
		version = hv_vmbus_get_next_version(version);
	} while (version != HV_VMBUS_VERSION_INVALID);
	hv_vmbus_protocal_version = version;
	if (bootverbose)
		printf("VMBUS: Protocol Version: %d.%d\n",
		    version >> 16, version & 0xFFFF);
	sema_destroy(&msg_info->wait_sema);
	free(msg_info, M_DEVBUF);
	return (0);
	cleanup:
	hv_vmbus_g_connection.connect_state = HV_DISCONNECTED;
	mtx_destroy(&hv_vmbus_g_connection.channel_lock);
	mtx_destroy(&hv_vmbus_g_connection.channel_msg_lock);
	if (msg_info) {
		sema_destroy(&msg_info->wait_sema);
		free(msg_info, M_DEVBUF);
	}
	free(hv_vmbus_g_connection.channels, M_DEVBUF);
	return (ret);
}
int hv_vmbus_connect ( struct vmbus_softc * sc ) { int ret = 0 ; uint32_t version ; hv_vmbus_channel_msg_info * msg_info = NULL ; if ( hv_vmbus_g_connection . connect_state != HV_DISCONNECTED ) { return ( -1 ) ; } hv_vmbus_g_connection . connect_state = HV_CONNECTING ; TAILQ_INIT ( & hv_vmbus_g_connection . channel_msg_anchor ) ; mtx_init ( & hv_vmbus_g_connection . channel_msg_lock , " " , NULL , MTX_DEF ) ; TAILQ_INIT ( & hv_vmbus_g_connection . channel_anchor ) ; mtx_init ( & hv_vmbus_g_connection . channel_lock , " " , NULL , MTX_DEF ) ; msg_info = ( hv_vmbus_channel_msg_info * ) malloc ( sizeof ( hv_vmbus_channel_msg_info ) + sizeof ( hv_vmbus_channel_initiate_contact ) , M_DEVBUF , M_WAITOK | M_ZERO ) ; hv_vmbus_g_connection . channels = malloc ( sizeof ( hv_vmbus_channel * ) * VMBUS_CHAN_MAX , M_DEVBUF , M_WAITOK | M_ZERO ) ; version = HV_VMBUS_VERSION_CURRENT ; do { ret = hv_vmbus_negotiate_version ( sc , msg_info , version ) ; if ( ret == EWOULDBLOCK ) { goto cleanup ; } if ( hv_vmbus_g_connection . connect_state == HV_CONNECTED ) break ; version = hv_vmbus_get_next_version ( version ) ; } while ( version != HV_VMBUS_VERSION_INVALID ) ; hv_vmbus_protocal_version = version ; if ( bootverbose ) printf ( " \n " , version >> 16 , version & 0xFFFF ) ; sema_destroy ( & msg_info -> wait_sema ) ; free ( msg_info , M_DEVBUF ) ; return ( 0 ) ; cleanup : hv_vmbus_g_connection . connect_state = HV_DISCONNECTED ; mtx_destroy ( & hv_vmbus_g_connection . channel_lock ) ; mtx_destroy ( & hv_vmbus_g_connection . channel_msg_lock ) ; if ( msg_info ) { sema_destroy ( & msg_info -> wait_sema ) ; free ( msg_info , M_DEVBUF ) ; } free ( hv_vmbus_g_connection . channels , M_DEVBUF ) ; return ( ret ) ; }
Send a connect request on the partition service connection
Send a connect request on the partition service connection
/**
	 * Make sure we are not connecting or connected
	 */ /**
	 * Initialize the vmbus connection
	 */ /*
	 * Find the highest vmbus version number we can support.
	 */ /*
			 * We timed out.
			 */ /*
	 * Cleanup after failure!
	 */