summaryrefslogtreecommitdiffstats
path: root/tools/usb/usbip
diff options
context:
space:
mode:
Diffstat (limited to 'tools/usb/usbip')
-rw-r--r--tools/usb/usbip/libsrc/usbip_common.c23
-rw-r--r--tools/usb/usbip/libsrc/usbip_common.h11
-rw-r--r--tools/usb/usbip/libsrc/usbip_host_common.c5
-rw-r--r--tools/usb/usbip/src/usbip_attach.c10
-rw-r--r--tools/usb/usbip/src/usbip_list.c6
-rw-r--r--tools/usb/usbip/src/usbip_network.c10
-rw-r--r--tools/usb/usbip/src/usbip_network.h6
-rw-r--r--tools/usb/usbip/src/usbipd.c34
8 files changed, 80 insertions, 25 deletions
diff --git a/tools/usb/usbip/libsrc/usbip_common.c b/tools/usb/usbip/libsrc/usbip_common.c
index 001bb8e8f668..bb424638d75b 100644
--- a/tools/usb/usbip/libsrc/usbip_common.c
+++ b/tools/usb/usbip/libsrc/usbip_common.c
@@ -66,6 +66,29 @@ const char *usbip_speed_string(int num)
return "Unknown Speed";
}
+struct op_common_status_string {
+ int num;
+ char *desc;
+};
+
+static struct op_common_status_string op_common_status_strings[] = {
+ { ST_OK, "Request Completed Successfully" },
+ { ST_NA, "Request Failed" },
+ { ST_DEV_BUSY, "Device busy (exported)" },
+ { ST_DEV_ERR, "Device in error state" },
+ { ST_NODEV, "Device not found" },
+ { ST_ERROR, "Unexpected response" },
+ { 0, NULL}
+};
+
+const char *usbip_op_common_status_string(int status)
+{
+ for (int i = 0; op_common_status_strings[i].desc != NULL; i++)
+ if (op_common_status_strings[i].num == status)
+ return op_common_status_strings[i].desc;
+
+ return "Unknown Op Common Status";
+}
#define DBG_UDEV_INTEGER(name)\
dbg("%-20s = %x", to_string(name), (int) udev->name)
diff --git a/tools/usb/usbip/libsrc/usbip_common.h b/tools/usb/usbip/libsrc/usbip_common.h
index e45ec9d2fdbc..73a367a7fa10 100644
--- a/tools/usb/usbip/libsrc/usbip_common.h
+++ b/tools/usb/usbip/libsrc/usbip_common.h
@@ -43,6 +43,16 @@
#define SYSFS_PATH_MAX 256
#define SYSFS_BUS_ID_SIZE 32
+/* Defines for op_code status in server/client op_common PDUs */
+#define ST_OK 0x00
+#define ST_NA 0x01
+ /* Device requested for import is not available */
+#define ST_DEV_BUSY 0x02
+ /* Device requested for import is in error state */
+#define ST_DEV_ERR 0x03
+#define ST_NODEV 0x04
+#define ST_ERROR 0x05
+
extern int usbip_use_syslog;
extern int usbip_use_stderr;
extern int usbip_use_debug ;
@@ -130,6 +140,7 @@ int read_usb_interface(struct usbip_usb_device *udev, int i,
const char *usbip_speed_string(int num);
const char *usbip_status_string(int32_t status);
+const char *usbip_op_common_status_string(int status);
int usbip_names_init(char *);
void usbip_names_free(void);
diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c
index 6ff7b601f854..dc93fadbee96 100644
--- a/tools/usb/usbip/libsrc/usbip_host_common.c
+++ b/tools/usb/usbip/libsrc/usbip_host_common.c
@@ -234,14 +234,17 @@ int usbip_export_device(struct usbip_exported_device *edev, int sockfd)
switch (edev->status) {
case SDEV_ST_ERROR:
dbg("status SDEV_ST_ERROR");
+ ret = ST_DEV_ERR;
break;
case SDEV_ST_USED:
dbg("status SDEV_ST_USED");
+ ret = ST_DEV_BUSY;
break;
default:
dbg("status unknown: 0x%x", edev->status);
+ ret = -1;
}
- return -1;
+ return ret;
}
/* only the first interface is true */
diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c
index 7f07b2d50f59..ba88728483ff 100644
--- a/tools/usb/usbip/src/usbip_attach.c
+++ b/tools/usb/usbip/src/usbip_attach.c
@@ -135,6 +135,7 @@ static int query_import_device(int sockfd, char *busid)
struct op_import_request request;
struct op_import_reply reply;
uint16_t code = OP_REP_IMPORT;
+ int status;
memset(&request, 0, sizeof(request));
memset(&reply, 0, sizeof(reply));
@@ -157,9 +158,10 @@ static int query_import_device(int sockfd, char *busid)
}
/* receive a reply */
- rc = usbip_net_recv_op_common(sockfd, &code);
+ rc = usbip_net_recv_op_common(sockfd, &code, &status);
if (rc < 0) {
- err("recv op_common");
+ err("Attach Request for %s failed - %s\n",
+ busid, usbip_op_common_status_string(status));
return -1;
}
@@ -194,10 +196,8 @@ static int attach_device(char *host, char *busid)
}
rhport = query_import_device(sockfd, busid);
- if (rhport < 0) {
- err("query");
+ if (rhport < 0)
return -1;
- }
close(sockfd);
diff --git a/tools/usb/usbip/src/usbip_list.c b/tools/usb/usbip/src/usbip_list.c
index d65a9f444174..8d4ccf4b9480 100644
--- a/tools/usb/usbip/src/usbip_list.c
+++ b/tools/usb/usbip/src/usbip_list.c
@@ -62,6 +62,7 @@ static int get_exported_devices(char *host, int sockfd)
struct usbip_usb_interface uintf;
unsigned int i;
int rc, j;
+ int status;
rc = usbip_net_send_op_common(sockfd, OP_REQ_DEVLIST, 0);
if (rc < 0) {
@@ -69,9 +70,10 @@ static int get_exported_devices(char *host, int sockfd)
return -1;
}
- rc = usbip_net_recv_op_common(sockfd, &code);
+ rc = usbip_net_recv_op_common(sockfd, &code, &status);
if (rc < 0) {
- dbg("usbip_net_recv_op_common failed");
+ err("Exported Device List Request failed - %s\n",
+ usbip_op_common_status_string(status));
return -1;
}
diff --git a/tools/usb/usbip/src/usbip_network.c b/tools/usb/usbip/src/usbip_network.c
index b4c37e76a6e0..8ffcd47d9638 100644
--- a/tools/usb/usbip/src/usbip_network.c
+++ b/tools/usb/usbip/src/usbip_network.c
@@ -163,7 +163,7 @@ int usbip_net_send_op_common(int sockfd, uint32_t code, uint32_t status)
return 0;
}
-int usbip_net_recv_op_common(int sockfd, uint16_t *code)
+int usbip_net_recv_op_common(int sockfd, uint16_t *code, int *status)
{
struct op_common op_common;
int rc;
@@ -179,8 +179,8 @@ int usbip_net_recv_op_common(int sockfd, uint16_t *code)
PACK_OP_COMMON(0, &op_common);
if (op_common.version != USBIP_VERSION) {
- dbg("version mismatch: %d %d", op_common.version,
- USBIP_VERSION);
+ err("USBIP Kernel and tool version mismatch: %d %d:",
+ op_common.version, USBIP_VERSION);
goto err;
}
@@ -191,10 +191,14 @@ int usbip_net_recv_op_common(int sockfd, uint16_t *code)
if (op_common.code != *code) {
dbg("unexpected pdu %#0x for %#0x", op_common.code,
*code);
+ /* return error status */
+ *status = ST_ERROR;
goto err;
}
}
+ *status = op_common.status;
+
if (op_common.status != ST_OK) {
dbg("request failed at peer: %d", op_common.status);
goto err;
diff --git a/tools/usb/usbip/src/usbip_network.h b/tools/usb/usbip/src/usbip_network.h
index 7032687621d3..555215eae43e 100644
--- a/tools/usb/usbip/src/usbip_network.h
+++ b/tools/usb/usbip/src/usbip_network.h
@@ -27,9 +27,7 @@ struct op_common {
#define OP_REPLY (0x00 << 8)
uint16_t code;
- /* add more error code */
-#define ST_OK 0x00
-#define ST_NA 0x01
+ /* status codes defined in usbip_common.h */
uint32_t status; /* op_code status (for reply) */
} __attribute__((packed));
@@ -176,7 +174,7 @@ void usbip_net_pack_usb_interface(int pack, struct usbip_usb_interface *uinf);
ssize_t usbip_net_recv(int sockfd, void *buff, size_t bufflen);
ssize_t usbip_net_send(int sockfd, void *buff, size_t bufflen);
int usbip_net_send_op_common(int sockfd, uint32_t code, uint32_t status);
-int usbip_net_recv_op_common(int sockfd, uint16_t *code);
+int usbip_net_recv_op_common(int sockfd, uint16_t *code, int *status);
int usbip_net_set_reuseaddr(int sockfd);
int usbip_net_set_nodelay(int sockfd);
int usbip_net_set_keepalive(int sockfd);
diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c
index c6dad2a13c80..32864c52942d 100644
--- a/tools/usb/usbip/src/usbipd.c
+++ b/tools/usb/usbip/src/usbipd.c
@@ -107,7 +107,7 @@ static int recv_request_import(int sockfd)
struct usbip_usb_device pdu_udev;
struct list_head *i;
int found = 0;
- int error = 0;
+ int status = ST_OK;
int rc;
memset(&req, 0, sizeof(req));
@@ -133,22 +133,21 @@ static int recv_request_import(int sockfd)
usbip_net_set_nodelay(sockfd);
/* export device needs a TCP/IP socket descriptor */
- rc = usbip_export_device(edev, sockfd);
- if (rc < 0)
- error = 1;
+ status = usbip_export_device(edev, sockfd);
+ if (status < 0)
+ status = ST_NA;
} else {
info("requested device not found: %s", req.busid);
- error = 1;
+ status = ST_NODEV;
}
- rc = usbip_net_send_op_common(sockfd, OP_REP_IMPORT,
- (!error ? ST_OK : ST_NA));
+ rc = usbip_net_send_op_common(sockfd, OP_REP_IMPORT, status);
if (rc < 0) {
dbg("usbip_net_send_op_common failed: %#0x", OP_REP_IMPORT);
return -1;
}
- if (error) {
+ if (status) {
dbg("import request busid %s: failed", req.busid);
return -1;
}
@@ -176,10 +175,21 @@ static int send_reply_devlist(int connfd)
struct list_head *j;
int rc, i;
+ /*
+ * Exclude devices that are already exported to a client from
+ * the exportable device list to avoid:
+ * - import requests for devices that are exported only to
+ * fail the request.
+ * - revealing devices that are imported by a client to
+ * another client.
+ */
+
reply.ndev = 0;
/* number of exported devices */
list_for_each(j, &driver->edev_list) {
- reply.ndev += 1;
+ edev = list_entry(j, struct usbip_exported_device, node);
+ if (edev->status != SDEV_ST_USED)
+ reply.ndev += 1;
}
info("exportable devices: %d", reply.ndev);
@@ -198,6 +208,9 @@ static int send_reply_devlist(int connfd)
list_for_each(j, &driver->edev_list) {
edev = list_entry(j, struct usbip_exported_device, node);
+ if (edev->status == SDEV_ST_USED)
+ continue;
+
dump_usb_device(&edev->udev);
memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
usbip_net_pack_usb_device(1, &pdu_udev);
@@ -251,8 +264,9 @@ static int recv_pdu(int connfd)
{
uint16_t code = OP_UNSPEC;
int ret;
+ int status;
- ret = usbip_net_recv_op_common(connfd, &code);
+ ret = usbip_net_recv_op_common(connfd, &code, &status);
if (ret < 0) {
dbg("could not receive opcode: %#0x", code);
return -1;
OpenPOWER on IntegriCloud