xref: /openbmc/linux/tools/usb/usbip/src/usbip_detach.c (revision 5f8b7d4b2e9604d03ae06f1a2dd5a1f34c33e533)
11ccea77eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2588b48caSValentina Manea /*
3588b48caSValentina Manea  * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
4588b48caSValentina Manea  *               2005-2007 Takahiro Hirofuchi
5588b48caSValentina Manea  */
6588b48caSValentina Manea 
7588b48caSValentina Manea #include <ctype.h>
8588b48caSValentina Manea #include <limits.h>
9588b48caSValentina Manea #include <stdint.h>
10588b48caSValentina Manea #include <stdio.h>
11588b48caSValentina Manea #include <stdlib.h>
12588b48caSValentina Manea #include <string.h>
13588b48caSValentina Manea 
14588b48caSValentina Manea #include <getopt.h>
15588b48caSValentina Manea #include <unistd.h>
16588b48caSValentina Manea 
17588b48caSValentina Manea #include "vhci_driver.h"
18588b48caSValentina Manea #include "usbip_common.h"
19588b48caSValentina Manea #include "usbip_network.h"
20588b48caSValentina Manea #include "usbip.h"
21588b48caSValentina Manea 
22588b48caSValentina Manea static const char usbip_detach_usage_string[] =
23588b48caSValentina Manea 	"usbip detach <args>\n"
24588b48caSValentina Manea 	"    -p, --port=<port>    " USBIP_VHCI_DRV_NAME
25588b48caSValentina Manea 	" port the device is on\n";
26588b48caSValentina Manea 
usbip_detach_usage(void)27588b48caSValentina Manea void usbip_detach_usage(void)
28588b48caSValentina Manea {
29588b48caSValentina Manea 	printf("usage: %s", usbip_detach_usage_string);
30588b48caSValentina Manea }
31588b48caSValentina Manea 
detach_port(char * port)32588b48caSValentina Manea static int detach_port(char *port)
33588b48caSValentina Manea {
34d179f99aSShuah Khan (Samsung OSG) 	int ret = 0;
35588b48caSValentina Manea 	uint8_t portnum;
36588b48caSValentina Manea 	char path[PATH_MAX+1];
3740ecdeb1SShuah Khan (Samsung OSG) 	int i;
3840ecdeb1SShuah Khan (Samsung OSG) 	struct usbip_imported_device *idev;
3940ecdeb1SShuah Khan (Samsung OSG) 	int found = 0;
40588b48caSValentina Manea 
410c618145SEric Curtin 	unsigned int port_len = strlen(port);
420c618145SEric Curtin 
430c618145SEric Curtin 	for (unsigned int i = 0; i < port_len; i++)
44588b48caSValentina Manea 		if (!isdigit(port[i])) {
45588b48caSValentina Manea 			err("invalid port %s", port);
46588b48caSValentina Manea 			return -1;
47588b48caSValentina Manea 		}
48588b48caSValentina Manea 
49588b48caSValentina Manea 	portnum = atoi(port);
50588b48caSValentina Manea 
51588b48caSValentina Manea 	ret = usbip_vhci_driver_open();
52588b48caSValentina Manea 	if (ret < 0) {
530c7f35d2SGalen Guyer 		err("open vhci_driver (is vhci_hcd loaded?)");
54588b48caSValentina Manea 		return -1;
55588b48caSValentina Manea 	}
56588b48caSValentina Manea 
5740ecdeb1SShuah Khan (Samsung OSG) 	/* check for invalid port */
5840ecdeb1SShuah Khan (Samsung OSG) 	for (i = 0; i < vhci_driver->nports; i++) {
5940ecdeb1SShuah Khan (Samsung OSG) 		idev = &vhci_driver->idev[i];
6040ecdeb1SShuah Khan (Samsung OSG) 
6140ecdeb1SShuah Khan (Samsung OSG) 		if (idev->port == portnum) {
6240ecdeb1SShuah Khan (Samsung OSG) 			found = 1;
6340ecdeb1SShuah Khan (Samsung OSG) 			if (idev->status != VDEV_ST_NULL)
6440ecdeb1SShuah Khan (Samsung OSG) 				break;
6540ecdeb1SShuah Khan (Samsung OSG) 			info("Port %d is already detached!\n", idev->port);
6640ecdeb1SShuah Khan (Samsung OSG) 			goto call_driver_close;
6740ecdeb1SShuah Khan (Samsung OSG) 		}
6840ecdeb1SShuah Khan (Samsung OSG) 	}
6940ecdeb1SShuah Khan (Samsung OSG) 
7040ecdeb1SShuah Khan (Samsung OSG) 	if (!found) {
71*53e0684fSZongmin Zhou 		ret = -1;
7240ecdeb1SShuah Khan (Samsung OSG) 		err("Invalid port %s > maxports %d",
7340ecdeb1SShuah Khan (Samsung OSG) 			port, vhci_driver->nports);
7440ecdeb1SShuah Khan (Samsung OSG) 		goto call_driver_close;
7540ecdeb1SShuah Khan (Samsung OSG) 	}
7640ecdeb1SShuah Khan (Samsung OSG) 
7740ecdeb1SShuah Khan (Samsung OSG) 	/* remove the port state file */
7840ecdeb1SShuah Khan (Samsung OSG) 	snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", portnum);
7940ecdeb1SShuah Khan (Samsung OSG) 
8040ecdeb1SShuah Khan (Samsung OSG) 	remove(path);
8140ecdeb1SShuah Khan (Samsung OSG) 	rmdir(VHCI_STATE_PATH);
8240ecdeb1SShuah Khan (Samsung OSG) 
83588b48caSValentina Manea 	ret = usbip_vhci_detach_device(portnum);
84d179f99aSShuah Khan (Samsung OSG) 	if (ret < 0) {
85d179f99aSShuah Khan (Samsung OSG) 		ret = -1;
8640ecdeb1SShuah Khan (Samsung OSG) 		err("Port %d detach request failed!\n", portnum);
87d179f99aSShuah Khan (Samsung OSG) 		goto call_driver_close;
88d179f99aSShuah Khan (Samsung OSG) 	}
8940ecdeb1SShuah Khan (Samsung OSG) 	info("Port %d is now detached!\n", portnum);
90588b48caSValentina Manea 
91d179f99aSShuah Khan (Samsung OSG) call_driver_close:
92588b48caSValentina Manea 	usbip_vhci_driver_close();
93588b48caSValentina Manea 
94588b48caSValentina Manea 	return ret;
95588b48caSValentina Manea }
96588b48caSValentina Manea 
usbip_detach(int argc,char * argv[])97588b48caSValentina Manea int usbip_detach(int argc, char *argv[])
98588b48caSValentina Manea {
99588b48caSValentina Manea 	static const struct option opts[] = {
100588b48caSValentina Manea 		{ "port", required_argument, NULL, 'p' },
101588b48caSValentina Manea 		{ NULL, 0, NULL, 0 }
102588b48caSValentina Manea 	};
103588b48caSValentina Manea 	int opt;
104588b48caSValentina Manea 	int ret = -1;
105588b48caSValentina Manea 
106588b48caSValentina Manea 	for (;;) {
107588b48caSValentina Manea 		opt = getopt_long(argc, argv, "p:", opts, NULL);
108588b48caSValentina Manea 
109588b48caSValentina Manea 		if (opt == -1)
110588b48caSValentina Manea 			break;
111588b48caSValentina Manea 
112588b48caSValentina Manea 		switch (opt) {
113588b48caSValentina Manea 		case 'p':
114588b48caSValentina Manea 			ret = detach_port(optarg);
115588b48caSValentina Manea 			goto out;
116588b48caSValentina Manea 		default:
117588b48caSValentina Manea 			goto err_out;
118588b48caSValentina Manea 		}
119588b48caSValentina Manea 	}
120588b48caSValentina Manea 
121588b48caSValentina Manea err_out:
122588b48caSValentina Manea 	usbip_detach_usage();
123588b48caSValentina Manea out:
124588b48caSValentina Manea 	return ret;
125588b48caSValentina Manea }
126