static int
hv_kvp_attach(device_t dev)
{
	int	ret = KVP_SUCCESS;
#ifdef DEBUG
	printf("hv_kvp_attach: called\n");
#endif

	kvp_hv_dev = vmbus_get_devctx(dev);
	device_printf(dev, "Hyper-V Service attaching: %s\n", 
		"Hyper-V KVP Service\n");

#if 0
	ret = hv_vmbus_channel_open(hv_dev->channel, 
			2 * PAGE_SIZE, 2 * PAGE_SIZE, 
			NULL, 0, hv_kvp_callback, hv_dev->channel);

	if (ret) printf("hv_kvp_attach: hv_vmbus_channel_open failed\n");
#endif
	kvp_msg_state.kvp_rcv_timer = timeout(kvp_user_rcv_timer, NULL, 10);
	if (kvp_msg_state.kvp_rcv_timer.callout == NULL) {
		printf("hv_kvp_attach: timer creation failed\n");
		ret = -1; 
	}
	return (ret);
}
Beispiel #2
0
/*
 * Net VSC on device add
 * 
 * Callback when the device belonging to this driver is added
 */
netvsc_dev *
hv_nv_on_device_add(struct hv_device *device, void *additional_info)
{
	struct hv_vmbus_channel *chan = device->channel;
	netvsc_dev *net_dev;
	int ret = 0;

	net_dev = hv_nv_alloc_net_device(device);
	if (net_dev == NULL)
		return NULL;

	/* Initialize the NetVSC channel extension */

	sema_init(&net_dev->channel_init_sema, 0, "netdev_sema");

	chan->hv_chan_rdbuf = malloc(NETVSC_PACKET_SIZE, M_NETVSC, M_WAITOK);

	/*
	 * Open the channel
	 */
	ret = hv_vmbus_channel_open(chan,
	    NETVSC_DEVICE_RING_BUFFER_SIZE, NETVSC_DEVICE_RING_BUFFER_SIZE,
	    NULL, 0, hv_nv_on_channel_callback, chan);
	if (ret != 0) {
		free(chan->hv_chan_rdbuf, M_NETVSC);
		goto cleanup;
	}

	/*
	 * Connect with the NetVsp
	 */
	ret = hv_nv_connect_to_vsp(device);
	if (ret != 0)
		goto close;

	return (net_dev);

close:
	/* Now, we can close the channel safely */
	free(chan->hv_chan_rdbuf, M_NETVSC);
	hv_vmbus_channel_close(chan);

cleanup:
	/*
	 * Free the packet buffers on the netvsc device packet queue.
	 * Release other resources.
	 */
	if (net_dev) {
		sema_destroy(&net_dev->channel_init_sema);
		free(net_dev, M_NETVSC);
	}

	return (NULL);
}
/* 
 * Initiate a connection and receive REGISTER message from the user daemon
 */
void
hv_kvp_conn_register(void *p)
{
	int error=KVP_SUCCESS;
	if (conn_ready == FALSE) {
		/* wait until the user daemon is ready */
		if (kvp_connect_user() != KVP_SUCCESS) {
#ifdef DEBUG
			printf("kvp_conn: Connect to user daemon failed\n");
#endif
			return;
		}
		else {
#ifdef DEBUG
			printf("kvp_conn: Connect to user daemon successful\n");
#endif
			conn_ready = TRUE;
		}
	}

	/* First message from the user should be a KVP_OP_REGISTER msg */
	if (register_done == FALSE) {
		error = kvp_rcv_user(); /* receive a message from user */
		if (hv_user_kvp_msg.kvp_hdr.operation == KVP_OP_REGISTER) {
#ifdef DEBUG
			printf("kvp_conn:Rcvd KVP_OP_REGISTER msg from user\n");
#endif
			/* Cancel timer and establish connection to the host */
			if (kvp_msg_state.kvp_rcv_timer.callout) {
                        	untimeout(kvp_user_rcv_timer, NULL, 
					kvp_msg_state.kvp_rcv_timer);
				 kvp_msg_state.kvp_rcv_timer.callout = NULL;
			}
			error = hv_vmbus_channel_open(kvp_hv_dev->channel, 
					4 * PAGE_SIZE, 4 * PAGE_SIZE, 
				NULL, 0, hv_kvp_callback, kvp_hv_dev->channel);
			if (error) 
				printf("hv_kvp_conn: vmbus_chan_open failed\n");

			register_done = TRUE;
			kvp_msg_state.kvp_ready = TRUE;

		}
	}
}
Beispiel #4
0
static int
hv_util_attach(device_t dev)
{
	struct hv_device*		hv_dev;
	struct hv_vmbus_service*	service;
	int				ret;
	size_t				receive_buffer_offset;

	hv_dev = vmbus_get_devctx(dev);
	service = device_get_softc(dev);
	receive_buffer_offset = service - &service_table[0];
	device_printf(dev, "Hyper-V Service attaching: %s\n", service->name);
	receive_buffer[receive_buffer_offset] =
		malloc(4 * PAGE_SIZE, M_DEVBUF, M_WAITOK | M_ZERO);

	if (service->init != NULL) {
	    ret = service->init(service);
	    if (ret) {
		ret = ENODEV;
		goto error0;
	    }
	}

	ret = hv_vmbus_channel_open(hv_dev->channel, 4 * PAGE_SIZE,
		    4 * PAGE_SIZE, NULL, 0,
		    service->callback, hv_dev->channel);

	if (ret)
	    goto error0;

	return (0);

	error0:

	    free(receive_buffer[receive_buffer_offset], M_DEVBUF);
	    receive_buffer[receive_buffer_offset] = NULL;

	return (ret);
}
/* Timer to establish connection with the user daemon */
static void
kvp_user_rcv_timer(void *arg)
{
	int error=KVP_SUCCESS;
        printf("kvp_user_rcv_timer: timer triggered\n");
	//printf("kvp:guid:%s\n",kvp_hv_dev->class_id);
	
	/* If daemon is already ready, just connect to the host and return */
	if (hv_kvp_ready()) {
		kvp_msg_state.kvp_rcv_timer.callout = NULL;
		error = hv_vmbus_channel_open(kvp_hv_dev->channel, 
					4 * PAGE_SIZE, 4 * PAGE_SIZE, 
				NULL, 0, hv_kvp_callback, kvp_hv_dev->channel);
		if (error) 
			printf("kvp_user_rcv_timer: vmbus_chan_open failed\n");
	}
	else {
		hv_queue_work_item(kvp_work_queue, hv_kvp_conn_register, NULL);
		kvp_msg_state.kvp_rcv_timer = 
			timeout(kvp_user_rcv_timer, NULL, 10);
	}
}