Hello, > > Implementation of new disconnect operation. This is linked as a part of > > usbip command. With this patch, usbip command has following > operations. > > > > bind > > unbind > > list (local/remote) > > attach > > detach > > port > > connect ... previous patch > > disconnect ... this patch > > > > In device side node, this sends an un-export request, receives an > > un-export response and unbind corresponding device internally. The > > definition of the request and response are defined in original code: > > tools/usb/usbip/usbip_network.h but was not used. It's corresponding > to > > NEW-4 in following diagram. > > > > To find disconnecting device, requesting host and requested > > bus-id-in-requester identifies the target. So it cannot to disconnect a > > device from other host than a host which connected the device. > > Please see review comments on patch 3/10 - all of those apply for this > patch. OK. I will follow the comments. > > EXISTING) - invites devices from application(vhci)-side > > +------+ > +------------------+ > > device--+ STUB | | application/VHCI | > > +------+ > +------------------+ > > (server) (client) > > 1) # usbipd ... start daemon > > = = = > > 2) # usbip list --local > > 3) # usbip bind > > <--- list bound devices --- 4) # usbip list --remote > > <--- import a device ------ 5) # usbip attach > > = = = > > X disconnected 6) # usbip detach > > 7) usbip unbind > > > > NEW) - dedicates devices from device(stub)-side > > +------+ > +------------------+ > > device--+ STUB | | application/VHCI | > > +------+ > +------------------+ > > (client) (server) > > 1) # usbipa ... start > daemon > > = = = > > 2) # usbip list --local > > 3) # usbip connect --- export a device ------> > > = = = > > 4) # usbip disconnect --- un-export a device ---> > > > > Bind and unbind are done in connect and disconnect internally. > > > > Signed-off-by: Nobuo Iwata <nobuo.iwata@xxxxxxxxxxxxxxx> > > --- > > tools/usb/usbip/src/Makefile.am | 2 +- > > tools/usb/usbip/src/usbip.c | 6 + > > tools/usb/usbip/src/usbip.h | 2 + > > tools/usb/usbip/src/usbip_disconnect.c | 200 > +++++++++++++++++++++++++ > > 4 files changed, 209 insertions(+), 1 deletion(-) > > > > diff --git a/tools/usb/usbip/src/Makefile.am > b/tools/usb/usbip/src/Makefile.am > > index 0947476..42760c3 100644 > > --- a/tools/usb/usbip/src/Makefile.am > > +++ b/tools/usb/usbip/src/Makefile.am > > @@ -7,6 +7,6 @@ sbin_PROGRAMS := usbip usbipd > > usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ > > usbip_attach.c usbip_detach.c usbip_list.c \ > > usbip_bind.c usbip_unbind.c usbip_port.c \ > > - usbip_connect.c > > + usbip_connect.c usbip_disconnect.c > > > > usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c > > diff --git a/tools/usb/usbip/src/usbip.c > b/tools/usb/usbip/src/usbip.c > > index ad2a259..ead88a2 100644 > > --- a/tools/usb/usbip/src/usbip.c > > +++ b/tools/usb/usbip/src/usbip.c > > @@ -83,6 +83,12 @@ static const struct command cmds[] = { > > .usage = usbip_connect_usage > > }, > > { > > + .name = "disconnect", > > + .fn = usbip_disconnect, > > + .help = "Disconnect a USB device from a remote > computer", > > + .usage = usbip_disconnect_usage > > + }, > > + { > > .name = "list", > > .fn = usbip_list, > > .help = "List exportable or local USB devices", > > diff --git a/tools/usb/usbip/src/usbip.h > b/tools/usb/usbip/src/usbip.h > > index 3c22c27..b6537ef 100644 > > --- a/tools/usb/usbip/src/usbip.h > > +++ b/tools/usb/usbip/src/usbip.h > > @@ -32,6 +32,7 @@ int usbip_bind(int argc, char *argv[]); > > int usbip_unbind(int argc, char *argv[]); > > int usbip_port_show(int argc, char *argv[]); > > int usbip_connect(int argc, char *argv[]); > > +int usbip_disconnect(int argc, char *argv[]); > > > > void usbip_attach_usage(void); > > void usbip_detach_usage(void); > > @@ -39,6 +40,7 @@ void usbip_list_usage(void); > > void usbip_bind_usage(void); > > void usbip_unbind_usage(void); > > void usbip_connect_usage(void); > > +void usbip_disconnect_usage(void); > > > > int usbip_bind_device(char *busid); > > int usbip_unbind_device(char *busid); > > diff --git a/tools/usb/usbip/src/usbip_disconnect.c > b/tools/usb/usbip/src/usbip_disconnect.c > > new file mode 100644 > > index 0000000..4ee7feb > > --- /dev/null > > +++ b/tools/usb/usbip/src/usbip_disconnect.c > > @@ -0,0 +1,200 @@ > > +/* > > + * Copyright (C) 2011 matt mooney <mfm@xxxxxxxxxxxxx> > > + * 2005-2007 Takahiro Hirofuchi > > + * Copyright (C) 2015-2016 Nobuo Iwata > <nobuo.iwata@xxxxxxxxxxxxxxx> > > + * > > + * This program is free software: you can redistribute it and/or modify > > + * it under the terms of the GNU General Public License as published > by > > + * the Free Software Foundation, either version 2 of the License, or > > + * (at your option) any later version. > > + * > > + * This program is distributed in the hope that it will be useful, > > + * but WITHOUT ANY WARRANTY; without even the implied warranty > of > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. > See the > > + * GNU General Public License for more details. > > + * > > + * You should have received a copy of the GNU General Public License > > + * along with this program. If not, see > <http://www.gnu.org/licenses/>. > > + */ > > + > > +#include <sys/stat.h> > > + > > +#include <limits.h> > > +#include <stdint.h> > > +#include <stdio.h> > > +#include <string.h> > > + > > +#include <getopt.h> > > +#include <unistd.h> > > + > > +#include "usbip_host_driver.h" > > +#include "usbip_host_common.h" > > +#include "usbip_device_driver.h" > > +#include "usbip_common.h" > > +#include "usbip_network.h" > > +#include "usbip.h" > > + > > +static struct usbip_host_driver *driver = &host_driver; > > + > > +static const char usbip_disconnect_usage_string[] = > > + "usbip disconnect <args>\n" > > + " -r, --remote=<host> Address of a remote computer\n" > > + " -b, --busid=<busid> Bus ID of a device to be > disconnected\n" > > + " -d, --device Run with an alternate driver, e.g. > vUDC\n"; > > + > > +void usbip_disconnect_usage(void) > > +{ > > + printf("usage: %s", usbip_disconnect_usage_string); > > +} > > + > > +static int send_unexport_device(int sockfd, struct usbip_usb_device > *udev) > > +{ > > + int rc; > > + struct op_unexport_request request; > > + uint16_t code = OP_REP_UNEXPORT; > > + > > + /* send a request */ > > + rc = usbip_net_send_op_common(sockfd, OP_REQ_UNEXPORT, > 0); > > + if (rc < 0) { > > + err("send op_common"); > > + return -1; > > + } > > + > > + memset(&request, 0, sizeof(request)); > > + memcpy(&request.udev, udev, sizeof(request.udev)); > > + > > + PACK_OP_UNEXPORT_REQUEST(0, &request); > > + > > + rc = usbip_net_send(sockfd, (void *) &request, sizeof(request)); > > + if (rc < 0) { > > + err("send op_export_request"); > > + return -1; > > + } > > + > > + /* receive a reply */ > > + rc = usbip_net_recv_op_common(sockfd, &code); > > + if (rc < 0) { > > + err("recv op_common"); > > + return -1; > > + } > > + > > + return 0; > > +} > > + > > +static int unexport_device(char *busid, int sockfd) > > +{ > > + int rc; > > + struct usbip_exported_device *edev; > > + > > + rc = usbip_driver_open(driver); > > + if (rc < 0) { > > + err("open driver"); > > + goto err_out; > > + } > > + > > + rc = usbip_refresh_device_list(driver); > > + if (rc < 0) { > > + err("could not refresh device list"); > > + goto err_driver_close; > > + } > > + > > + edev = usbip_get_device(driver, busid); > > + if (edev == NULL) { > > + err("find device"); > > + goto err_driver_close; > > + } > > + > > + rc = send_unexport_device(sockfd, &edev->udev); > > + if (rc < 0) { > > + err("send unexport"); > > + goto err_driver_close; > > + } > > + > > + usbip_driver_close(driver); > > + > > + return 0; > > + > > +err_driver_close: > > + usbip_driver_close(driver); > > +err_out: > > + return -1; > > +} > > + > > +static int disconnect_device(char *host, char *busid, int unbind) > > +{ > > + int sockfd; > > + int rc; > > + > > + sockfd = usbip_net_tcp_connect(host, usbip_port_string); > > + if (sockfd < 0) { > > + err("tcp connect"); > > + return -1; > > + } > > + > > + rc = unexport_device(busid, sockfd); > > + if (rc < 0) { > > + err("unexport"); > > + close(sockfd); > > + return -1; > > + } > > + > > + close(sockfd); > > + > > + if (unbind) { > > + rc = usbip_unbind_device(busid); > > + if (rc) { > > + err("unbind"); > > + return -1; > > + } > > + } > > + > > + return 0; > > +} > > + > > +int usbip_disconnect(int argc, char *argv[]) > > +{ > > + static const struct option opts[] = { > > + { "remote", required_argument, NULL, 'r' }, > > + { "busid", required_argument, NULL, 'b' }, > > + { "device", no_argument, NULL, 'd' }, > > + { NULL, 0, NULL, 0 } > > + }; > > + char *host = NULL; > > + char *busid = NULL; > > + int opt; > > + int unbind = 1; > > + int ret = -1; > > + > > + for (;;) { > > + opt = getopt_long(argc, argv, "r:b:d", opts, NULL); > > + > > + if (opt == -1) > > + break; > > + > > + switch (opt) { > > + case 'r': > > + host = optarg; > > + break; > > + case 'b': > > + busid = optarg; > > + break; > > + case 'd': > > + driver = &device_driver; > > + unbind = 0; > > + break; > > + default: > > + goto err_out; > > + } > > + } > > + > > + if (!host || !busid) > > + goto err_out; > > + > > + ret = disconnect_device(host, busid, unbind); > > + goto out; > > + > > +err_out: > > + usbip_disconnect_usage(); > > +out: > > + return ret; > > +} > > Best Regards, Nobuo Iwata // -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html