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); }
/* * 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; } } }
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); } }