Ejemplo n.º 1
0
/*
 * Net VSC on device remove
 */
int
hv_nv_on_device_remove(struct hv_device *device, boolean_t destroy_channel)
{
	hn_softc_t *sc = device_get_softc(device->device);
	netvsc_dev *net_dev = sc->net_dev;;
	
	/* Stop outbound traffic ie sends and receives completions */
	net_dev->destroy = TRUE;

	hv_nv_disconnect_from_vsp(net_dev);

	/* At this point, no one should be accessing net_dev except in here */

	/* Now, we can close the channel safely */

	if (!destroy_channel) {
		device->channel->state =
		    HV_CHANNEL_CLOSING_NONDESTRUCTIVE_STATE;
	}

	free(device->channel->hv_chan_rdbuf, M_NETVSC);
	hv_vmbus_channel_close(device->channel);

	sema_destroy(&net_dev->channel_init_sema);
	free(net_dev, M_NETVSC);

	return (0);
}
Ejemplo n.º 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);
}
Ejemplo n.º 3
0
static int
hv_kvp_detach(device_t dev)
{
	struct hv_device* hv_dev;

#ifdef DEBUG
	printf("hv_kvp_detach: called\n");
#endif
	hv_dev = vmbus_get_devctx(dev);

	if (kvp_hv_dev != hv_dev) 
		printf("hv_kvp_detach: Closing an INVALID kvp device\n");
	hv_vmbus_channel_close(hv_dev->channel);
	kvp_hv_dev = NULL;
	return (0);
}
Ejemplo n.º 4
0
static int
hv_util_detach(device_t dev)
{
	struct hv_device*		hv_dev;
	struct hv_vmbus_service*	service;
	size_t				receive_buffer_offset;

	hv_dev = vmbus_get_devctx(dev);

	hv_vmbus_channel_close(hv_dev->channel);
	service = device_get_softc(dev);
	receive_buffer_offset = service - &service_table[0];

	if (service->work_queue != NULL)
	    hv_work_queue_close(service->work_queue);

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

	return (0);
}