Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/usb/usbip/src/usbip_detach.c
26288 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Copyright (C) 2011 matt mooney <[email protected]>
4
* 2005-2007 Takahiro Hirofuchi
5
*/
6
7
#include <ctype.h>
8
#include <limits.h>
9
#include <stdint.h>
10
#include <stdio.h>
11
#include <stdlib.h>
12
#include <string.h>
13
14
#include <getopt.h>
15
#include <unistd.h>
16
17
#include "vhci_driver.h"
18
#include "usbip_common.h"
19
#include "usbip_network.h"
20
#include "usbip.h"
21
22
static const char usbip_detach_usage_string[] =
23
"usbip detach <args>\n"
24
" -p, --port=<port> " USBIP_VHCI_DRV_NAME
25
" port the device is on\n";
26
27
void usbip_detach_usage(void)
28
{
29
printf("usage: %s", usbip_detach_usage_string);
30
}
31
32
static int detach_port(char *port)
33
{
34
int ret = 0;
35
uint8_t portnum;
36
char path[PATH_MAX+1];
37
int i;
38
struct usbip_imported_device *idev;
39
int found = 0;
40
41
unsigned int port_len = strlen(port);
42
43
for (unsigned int i = 0; i < port_len; i++)
44
if (!isdigit(port[i])) {
45
err("invalid port %s", port);
46
return -1;
47
}
48
49
portnum = atoi(port);
50
51
ret = usbip_vhci_driver_open();
52
if (ret < 0) {
53
err("open vhci_driver (is vhci_hcd loaded?)");
54
return -1;
55
}
56
57
/* check for invalid port */
58
for (i = 0; i < vhci_driver->nports; i++) {
59
idev = &vhci_driver->idev[i];
60
61
if (idev->port == portnum) {
62
found = 1;
63
if (idev->status != VDEV_ST_NULL)
64
break;
65
info("Port %d is already detached!\n", idev->port);
66
goto call_driver_close;
67
}
68
}
69
70
if (!found) {
71
ret = -1;
72
err("Invalid port %s > maxports %d",
73
port, vhci_driver->nports);
74
goto call_driver_close;
75
}
76
77
/* remove the port state file */
78
snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", portnum);
79
80
remove(path);
81
rmdir(VHCI_STATE_PATH);
82
83
ret = usbip_vhci_detach_device(portnum);
84
if (ret < 0) {
85
ret = -1;
86
err("Port %d detach request failed!\n", portnum);
87
goto call_driver_close;
88
}
89
info("Port %d is now detached!\n", portnum);
90
91
call_driver_close:
92
usbip_vhci_driver_close();
93
94
return ret;
95
}
96
97
int usbip_detach(int argc, char *argv[])
98
{
99
static const struct option opts[] = {
100
{ "port", required_argument, NULL, 'p' },
101
{ NULL, 0, NULL, 0 }
102
};
103
int opt;
104
int ret = -1;
105
106
for (;;) {
107
opt = getopt_long(argc, argv, "p:", opts, NULL);
108
109
if (opt == -1)
110
break;
111
112
switch (opt) {
113
case 'p':
114
ret = detach_port(optarg);
115
goto out;
116
default:
117
goto err_out;
118
}
119
}
120
121
err_out:
122
usbip_detach_usage();
123
out:
124
return ret;
125
}
126
127