/* The important thing is that only one context begins cleanup. This is why error handling and cleanup become simple. We do not want to consider race condition as possible.  */
static void vhci_shutdown_connection(struct usbip_device *ud)
/* The important thing is that only one context begins cleanup. This is why error handling and cleanup become simple. We do not want to consider race condition as possible.  */
static void vhci_shutdown_connection(struct usbip_device *ud)
{
	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
	if (ud->tcp_socket) {
		usbip_udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
		kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
	}
	usbip_stop_threads(&vdev->ud);
	usbip_uinfo("stop threads\n");
	if (vdev->ud.tcp_socket != NULL) {
		sock_release(vdev->ud.tcp_socket);
		vdev->ud.tcp_socket = NULL;
	}
	usbip_uinfo("release socket\n");
	vhci_device_unlink_cleanup(vdev);
	rh_port_disconnect(vdev->rhport);
	usbip_uinfo("disconnect device\n");
}