aboutsummaryrefslogtreecommitdiffstats
path: root/tools/usb
diff options
context:
space:
mode:
authorKrzysztof Opasiak <k.opasiak@samsung.com>2016-03-08 15:49:04 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-04-26 18:19:50 -0400
commit3391ba0e2792411dc3372b76a4662971d6eaa405 (patch)
treefbdcc3eaa65fbd29882b06f0300fef4afc91fb71 /tools/usb
parentea6873a45a22f35c8ab0f9c025df6a6c6dd532f3 (diff)
usbip: tools: Extract generic code to be shared with vudc backend
Extract the code from current stub driver backend and a common interface for both stub driver and vudc. This allows to share most of the usbipd code for both of them. Based on code created in cooperation with Open Operating Systems Student Society at University of Warsaw (O2S3@UW) consisting of: Igor Kotrasinski <ikotrasinsk@gmail.com> Karol Kosik <karo9@interia.eu> Ewelina Kosmider <3w3lfin@gmail.com> Dawid Lazarczyk <lazarczyk.dawid@gmail.com> Piotr Szulc <ps347277@students.mimuw.edu.pl> Tutor and project owner: Krzysztof Opasiak <k.opasiak@samsung.com> Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'tools/usb')
-rw-r--r--tools/usb/usbip/libsrc/Makefile.am3
-rw-r--r--tools/usb/usbip/libsrc/usbip_host_common.c273
-rw-r--r--tools/usb/usbip/libsrc/usbip_host_common.h104
-rw-r--r--tools/usb/usbip/libsrc/usbip_host_driver.c269
-rw-r--r--tools/usb/usbip/libsrc/usbip_host_driver.h27
-rw-r--r--tools/usb/usbip/src/usbipd.c30
6 files changed, 428 insertions, 278 deletions
diff --git a/tools/usb/usbip/libsrc/Makefile.am b/tools/usb/usbip/libsrc/Makefile.am
index 7c8f8a4d54e4..eb62f99cc0ee 100644
--- a/tools/usb/usbip/libsrc/Makefile.am
+++ b/tools/usb/usbip/libsrc/Makefile.am
@@ -4,5 +4,6 @@ libusbip_la_LDFLAGS = -version-info @LIBUSBIP_VERSION@
4 4
5lib_LTLIBRARIES := libusbip.la 5lib_LTLIBRARIES := libusbip.la
6libusbip_la_SOURCES := names.c names.h usbip_host_driver.c usbip_host_driver.h \ 6libusbip_la_SOURCES := names.c names.h usbip_host_driver.c usbip_host_driver.h \
7 usbip_common.c usbip_common.h vhci_driver.c vhci_driver.h \ 7 usbip_common.c usbip_common.h usbip_host_common.h \
8 usbip_host_common.c vhci_driver.c vhci_driver.h \
8 sysfs_utils.c sysfs_utils.h 9 sysfs_utils.c sysfs_utils.h
diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c
new file mode 100644
index 000000000000..9d415228883d
--- /dev/null
+++ b/tools/usb/usbip/libsrc/usbip_host_common.c
@@ -0,0 +1,273 @@
1/*
2 * Copyright (C) 2015-2016 Samsung Electronics
3 * Igor Kotrasinski <i.kotrasinsk@samsung.com>
4 * Krzysztof Opasiak <k.opasiak@samsung.com>
5 *
6 * Refactored from usbip_host_driver.c, which is:
7 * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
8 * 2005-2007 Takahiro Hirofuchi
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
27
28#include <errno.h>
29#include <unistd.h>
30
31#include <libudev.h>
32
33#include "usbip_common.h"
34#include "usbip_host_common.h"
35#include "list.h"
36#include "sysfs_utils.h"
37
38struct udev *udev_context;
39
40static int32_t read_attr_usbip_status(struct usbip_usb_device *udev)
41{
42 char status_attr_path[SYSFS_PATH_MAX];
43 int fd;
44 int length;
45 char status;
46 int value = 0;
47
48 snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status",
49 udev->path);
50
51 fd = open(status_attr_path, O_RDONLY);
52 if (fd < 0) {
53 err("error opening attribute %s", status_attr_path);
54 return -1;
55 }
56
57 length = read(fd, &status, 1);
58 if (length < 0) {
59 err("error reading attribute %s", status_attr_path);
60 close(fd);
61 return -1;
62 }
63
64 value = atoi(&status);
65
66 return value;
67}
68
69static
70struct usbip_exported_device *usbip_exported_device_new(
71 struct usbip_host_driver *hdriver, const char *sdevpath)
72{
73 struct usbip_exported_device *edev = NULL;
74 struct usbip_exported_device *edev_old;
75 size_t size;
76 int i;
77
78 edev = calloc(1, sizeof(struct usbip_exported_device));
79
80 edev->sudev =
81 udev_device_new_from_syspath(udev_context, sdevpath);
82 if (!edev->sudev) {
83 err("udev_device_new_from_syspath: %s", sdevpath);
84 goto err;
85 }
86
87 if (hdriver->ops.read_device(edev->sudev, &edev->udev) < 0)
88 goto err;
89
90 edev->status = read_attr_usbip_status(&edev->udev);
91 if (edev->status < 0)
92 goto err;
93
94 /* reallocate buffer to include usb interface data */
95 size = sizeof(struct usbip_exported_device) +
96 edev->udev.bNumInterfaces * sizeof(struct usbip_usb_interface);
97
98 edev_old = edev;
99 edev = realloc(edev, size);
100 if (!edev) {
101 edev = edev_old;
102 dbg("realloc failed");
103 goto err;
104 }
105
106 for (i = 0; i < edev->udev.bNumInterfaces; i++) {
107 /* vudc does not support reading interfaces */
108 if (!hdriver->ops.read_interface)
109 break;
110 hdriver->ops.read_interface(&edev->udev, i, &edev->uinf[i]);
111 }
112
113 return edev;
114err:
115 if (edev->sudev)
116 udev_device_unref(edev->sudev);
117 if (edev)
118 free(edev);
119
120 return NULL;
121}
122
123static int refresh_exported_devices(struct usbip_host_driver *hdriver)
124{
125 struct usbip_exported_device *edev;
126 struct udev_enumerate *enumerate;
127 struct udev_list_entry *devices, *dev_list_entry;
128 struct udev_device *dev;
129 const char *path;
130
131 enumerate = udev_enumerate_new(udev_context);
132 udev_enumerate_add_match_subsystem(enumerate, hdriver->udev_subsystem);
133 udev_enumerate_scan_devices(enumerate);
134
135 devices = udev_enumerate_get_list_entry(enumerate);
136
137 udev_list_entry_foreach(dev_list_entry, devices) {
138 path = udev_list_entry_get_name(dev_list_entry);
139 dev = udev_device_new_from_syspath(udev_context,
140 path);
141 if (dev == NULL)
142 continue;
143
144 /* Check whether device uses usbip driver. */
145 if (hdriver->ops.is_my_device(dev)) {
146 edev = usbip_exported_device_new(hdriver, path);
147 if (!edev) {
148 dbg("usbip_exported_device_new failed");
149 continue;
150 }
151
152 list_add(&edev->node, &hdriver->edev_list);
153 hdriver->ndevs++;
154 }
155 }
156
157 return 0;
158}
159
160static void usbip_exported_device_destroy(struct list_head *devs)
161{
162 struct list_head *i, *tmp;
163 struct usbip_exported_device *edev;
164
165 list_for_each_safe(i, tmp, devs) {
166 edev = list_entry(i, struct usbip_exported_device, node);
167 list_del(i);
168 free(edev);
169 }
170}
171
172int usbip_generic_driver_open(struct usbip_host_driver *hdriver)
173{
174 int rc;
175
176 udev_context = udev_new();
177 if (!udev_context) {
178 err("udev_new failed");
179 return -1;
180 }
181
182 rc = refresh_exported_devices(hdriver);
183 if (rc < 0)
184 goto err;
185 return 0;
186err:
187 udev_unref(udev_context);
188 return -1;
189}
190
191void usbip_generic_driver_close(struct usbip_host_driver *hdriver)
192{
193 if (!hdriver)
194 return;
195
196 usbip_exported_device_destroy(&hdriver->edev_list);
197
198 udev_unref(udev_context);
199}
200
201int usbip_generic_refresh_device_list(struct usbip_host_driver *hdriver)
202{
203 int rc;
204
205 usbip_exported_device_destroy(&hdriver->edev_list);
206
207 hdriver->ndevs = 0;
208 INIT_LIST_HEAD(&hdriver->edev_list);
209
210 rc = refresh_exported_devices(hdriver);
211 if (rc < 0)
212 return -1;
213
214 return 0;
215}
216
217int usbip_export_device(struct usbip_exported_device *edev, int sockfd)
218{
219 char attr_name[] = "usbip_sockfd";
220 char sockfd_attr_path[SYSFS_PATH_MAX];
221 char sockfd_buff[30];
222 int ret;
223
224 if (edev->status != SDEV_ST_AVAILABLE) {
225 dbg("device not available: %s", edev->udev.busid);
226 switch (edev->status) {
227 case SDEV_ST_ERROR:
228 dbg("status SDEV_ST_ERROR");
229 break;
230 case SDEV_ST_USED:
231 dbg("status SDEV_ST_USED");
232 break;
233 default:
234 dbg("status unknown: 0x%x", edev->status);
235 }
236 return -1;
237 }
238
239 /* only the first interface is true */
240 snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s",
241 edev->udev.path, attr_name);
242
243 snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd);
244
245 ret = write_sysfs_attribute(sockfd_attr_path, sockfd_buff,
246 strlen(sockfd_buff));
247 if (ret < 0) {
248 err("write_sysfs_attribute failed: sockfd %s to %s",
249 sockfd_buff, sockfd_attr_path);
250 return ret;
251 }
252
253 info("connect: %s", edev->udev.busid);
254
255 return ret;
256}
257
258struct usbip_exported_device *usbip_generic_get_device(
259 struct usbip_host_driver *hdriver, int num)
260{
261 struct list_head *i;
262 struct usbip_exported_device *edev;
263 int cnt = 0;
264
265 list_for_each(i, &hdriver->edev_list) {
266 edev = list_entry(i, struct usbip_exported_device, node);
267 if (num == cnt)
268 return edev;
269 cnt++;
270 }
271
272 return NULL;
273}
diff --git a/tools/usb/usbip/libsrc/usbip_host_common.h b/tools/usb/usbip/libsrc/usbip_host_common.h
new file mode 100644
index 000000000000..a64b8033fe64
--- /dev/null
+++ b/tools/usb/usbip/libsrc/usbip_host_common.h
@@ -0,0 +1,104 @@
1/*
2 * Copyright (C) 2015-2016 Samsung Electronics
3 * Igor Kotrasinski <i.kotrasinsk@samsung.com>
4 * Krzysztof Opasiak <k.opasiak@samsung.com>
5 *
6 * Refactored from usbip_host_driver.c, which is:
7 * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
8 * 2005-2007 Takahiro Hirofuchi
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24#ifndef __USBIP_HOST_COMMON_H
25#define __USBIP_HOST_COMMON_H
26
27#include <stdint.h>
28#include <libudev.h>
29#include <errno.h>
30#include "list.h"
31#include "usbip_common.h"
32#include "sysfs_utils.h"
33
34struct usbip_host_driver;
35
36struct usbip_host_driver_ops {
37 int (*open)(struct usbip_host_driver *hdriver);
38 void (*close)(struct usbip_host_driver *hdriver);
39 int (*refresh_device_list)(struct usbip_host_driver *hdriver);
40 struct usbip_exported_device * (*get_device)(
41 struct usbip_host_driver *hdriver, int num);
42
43 int (*read_device)(struct udev_device *sdev,
44 struct usbip_usb_device *dev);
45 int (*read_interface)(struct usbip_usb_device *udev, int i,
46 struct usbip_usb_interface *uinf);
47 int (*is_my_device)(struct udev_device *udev);
48};
49
50struct usbip_host_driver {
51 int ndevs;
52 /* list of exported device */
53 struct list_head edev_list;
54 const char *udev_subsystem;
55 struct usbip_host_driver_ops ops;
56};
57
58struct usbip_exported_device {
59 struct udev_device *sudev;
60 int32_t status;
61 struct usbip_usb_device udev;
62 struct list_head node;
63 struct usbip_usb_interface uinf[];
64};
65
66/* External API to access the driver */
67static inline int usbip_driver_open(struct usbip_host_driver *hdriver)
68{
69 if (!hdriver->ops.open)
70 return -EOPNOTSUPP;
71 return hdriver->ops.open(hdriver);
72}
73
74static inline void usbip_driver_close(struct usbip_host_driver *hdriver)
75{
76 if (!hdriver->ops.close)
77 return;
78 hdriver->ops.close(hdriver);
79}
80
81static inline int usbip_refresh_device_list(struct usbip_host_driver *hdriver)
82{
83 if (!hdriver->ops.refresh_device_list)
84 return -EOPNOTSUPP;
85 return hdriver->ops.refresh_device_list(hdriver);
86}
87
88static inline struct usbip_exported_device *
89usbip_get_device(struct usbip_host_driver *hdriver, int num)
90{
91 if (!hdriver->ops.get_device)
92 return NULL;
93 return hdriver->ops.get_device(hdriver, num);
94}
95
96/* Helper functions for implementing driver backend */
97int usbip_generic_driver_open(struct usbip_host_driver *hdriver);
98void usbip_generic_driver_close(struct usbip_host_driver *hdriver);
99int usbip_generic_refresh_device_list(struct usbip_host_driver *hdriver);
100int usbip_export_device(struct usbip_exported_device *edev, int sockfd);
101struct usbip_exported_device *usbip_generic_get_device(
102 struct usbip_host_driver *hdriver, int num);
103
104#endif /* __USBIP_HOST_COMMON_H */
diff --git a/tools/usb/usbip/libsrc/usbip_host_driver.c b/tools/usb/usbip/libsrc/usbip_host_driver.c
index bef08d5c44e8..4de6edc54d35 100644
--- a/tools/usb/usbip/libsrc/usbip_host_driver.c
+++ b/tools/usb/usbip/libsrc/usbip_host_driver.c
@@ -1,6 +1,9 @@
1/* 1/*
2 * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> 2 * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
3 * 2005-2007 Takahiro Hirofuchi 3 * 2005-2007 Takahiro Hirofuchi
4 * Copyright (C) 2015-2016 Samsung Electronics
5 * Igor Kotrasinski <i.kotrasinsk@samsung.com>
6 * Krzysztof Opasiak <k.opasiak@samsung.com>
4 * 7 *
5 * This program is free software: you can redistribute it and/or modify 8 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -16,265 +19,47 @@
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 20 */
18 21
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <fcntl.h>
22
23#include <errno.h>
24#include <unistd.h> 22#include <unistd.h>
25
26#include <libudev.h> 23#include <libudev.h>
27 24
28#include "usbip_common.h" 25#include "usbip_host_common.h"
29#include "usbip_host_driver.h" 26#include "usbip_host_driver.h"
30#include "list.h"
31#include "sysfs_utils.h"
32 27
33#undef PROGNAME 28#undef PROGNAME
34#define PROGNAME "libusbip" 29#define PROGNAME "libusbip"
35 30
36struct usbip_host_driver *host_driver; 31static int is_my_device(struct udev_device *dev)
37struct udev *udev_context;
38
39static int32_t read_attr_usbip_status(struct usbip_usb_device *udev)
40{
41 char status_attr_path[SYSFS_PATH_MAX];
42 int fd;
43 int length;
44 char status;
45 int value = 0;
46
47 snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status",
48 udev->path);
49
50 fd = open(status_attr_path, O_RDONLY);
51 if (fd < 0) {
52 err("error opening attribute %s", status_attr_path);
53 return -1;
54 }
55
56 length = read(fd, &status, 1);
57 if (length < 0) {
58 err("error reading attribute %s", status_attr_path);
59 close(fd);
60 return -1;
61 }
62
63 value = atoi(&status);
64
65 return value;
66}
67
68static
69struct usbip_exported_device *usbip_exported_device_new(const char *sdevpath)
70{
71 struct usbip_exported_device *edev = NULL;
72 struct usbip_exported_device *edev_old;
73 size_t size;
74 int i;
75
76 edev = calloc(1, sizeof(struct usbip_exported_device));
77
78 edev->sudev = udev_device_new_from_syspath(udev_context, sdevpath);
79 if (!edev->sudev) {
80 err("udev_device_new_from_syspath: %s", sdevpath);
81 goto err;
82 }
83
84 read_usb_device(edev->sudev, &edev->udev);
85
86 edev->status = read_attr_usbip_status(&edev->udev);
87 if (edev->status < 0)
88 goto err;
89
90 /* reallocate buffer to include usb interface data */
91 size = sizeof(struct usbip_exported_device) +
92 edev->udev.bNumInterfaces * sizeof(struct usbip_usb_interface);
93
94 edev_old = edev;
95 edev = realloc(edev, size);
96 if (!edev) {
97 edev = edev_old;
98 dbg("realloc failed");
99 goto err;
100 }
101
102 for (i = 0; i < edev->udev.bNumInterfaces; i++)
103 read_usb_interface(&edev->udev, i, &edev->uinf[i]);
104
105 return edev;
106err:
107 if (edev->sudev)
108 udev_device_unref(edev->sudev);
109 if (edev)
110 free(edev);
111
112 return NULL;
113}
114
115static int refresh_exported_devices(void)
116{ 32{
117 struct usbip_exported_device *edev;
118 struct udev_enumerate *enumerate;
119 struct udev_list_entry *devices, *dev_list_entry;
120 struct udev_device *dev;
121 const char *path;
122 const char *driver; 33 const char *driver;
123 34
124 enumerate = udev_enumerate_new(udev_context); 35 driver = udev_device_get_driver(dev);
125 udev_enumerate_add_match_subsystem(enumerate, "usb"); 36 return driver != NULL && !strcmp(driver, USBIP_HOST_DRV_NAME);
126 udev_enumerate_scan_devices(enumerate);
127
128 devices = udev_enumerate_get_list_entry(enumerate);
129
130 udev_list_entry_foreach(dev_list_entry, devices) {
131 path = udev_list_entry_get_name(dev_list_entry);
132 dev = udev_device_new_from_syspath(udev_context, path);
133 if (dev == NULL)
134 continue;
135
136 /* Check whether device uses usbip-host driver. */
137 driver = udev_device_get_driver(dev);
138 if (driver != NULL && !strcmp(driver, USBIP_HOST_DRV_NAME)) {
139 edev = usbip_exported_device_new(path);
140 if (!edev) {
141 dbg("usbip_exported_device_new failed");
142 continue;
143 }
144
145 list_add(&edev->node, &host_driver->edev_list);
146 host_driver->ndevs++;
147 }
148 }
149
150 return 0;
151}
152
153static void usbip_exported_device_destroy(void)
154{
155 struct list_head *i, *tmp;
156 struct usbip_exported_device *edev;
157
158 list_for_each_safe(i, tmp, &host_driver->edev_list) {
159 edev = list_entry(i, struct usbip_exported_device, node);
160 list_del(i);
161 free(edev);
162 }
163} 37}
164 38
165int usbip_host_driver_open(void) 39static int usbip_host_driver_open(struct usbip_host_driver *hdriver)
166{ 40{
167 int rc;
168
169 udev_context = udev_new();
170 if (!udev_context) {
171 err("udev_new failed");
172 return -1;
173 }
174
175 host_driver = calloc(1, sizeof(*host_driver));
176
177 host_driver->ndevs = 0;
178 INIT_LIST_HEAD(&host_driver->edev_list);
179
180 rc = refresh_exported_devices();
181 if (rc < 0)
182 goto err_free_host_driver;
183
184 return 0;
185
186err_free_host_driver:
187 free(host_driver);
188 host_driver = NULL;
189
190 udev_unref(udev_context);
191
192 return -1;
193}
194
195void usbip_host_driver_close(void)
196{
197 if (!host_driver)
198 return;
199
200 usbip_exported_device_destroy();
201
202 free(host_driver);
203 host_driver = NULL;
204
205 udev_unref(udev_context);
206}
207
208int usbip_host_refresh_device_list(void)
209{
210 int rc;
211
212 usbip_exported_device_destroy();
213
214 host_driver->ndevs = 0;
215 INIT_LIST_HEAD(&host_driver->edev_list);
216
217 rc = refresh_exported_devices();
218 if (rc < 0)
219 return -1;
220
221 return 0;
222}
223
224int usbip_host_export_device(struct usbip_exported_device *edev, int sockfd)
225{
226 char attr_name[] = "usbip_sockfd";
227 char sockfd_attr_path[SYSFS_PATH_MAX];
228 char sockfd_buff[30];
229 int ret; 41 int ret;
230 42
231 if (edev->status != SDEV_ST_AVAILABLE) { 43 hdriver->ndevs = 0;
232 dbg("device not available: %s", edev->udev.busid); 44 INIT_LIST_HEAD(&hdriver->edev_list);
233 switch (edev->status) {
234 case SDEV_ST_ERROR:
235 dbg("status SDEV_ST_ERROR");
236 break;
237 case SDEV_ST_USED:
238 dbg("status SDEV_ST_USED");
239 break;
240 default:
241 dbg("status unknown: 0x%x", edev->status);
242 }
243 return -1;
244 }
245
246 /* only the first interface is true */
247 snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s",
248 edev->udev.path, attr_name);
249
250 snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd);
251
252 ret = write_sysfs_attribute(sockfd_attr_path, sockfd_buff,
253 strlen(sockfd_buff));
254 if (ret < 0) {
255 err("write_sysfs_attribute failed: sockfd %s to %s",
256 sockfd_buff, sockfd_attr_path);
257 return ret;
258 }
259
260 info("connect: %s", edev->udev.busid);
261 45
46 ret = usbip_generic_driver_open(hdriver);
47 if (ret)
48 err("please load " USBIP_CORE_MOD_NAME ".ko and "
49 USBIP_HOST_DRV_NAME ".ko!");
262 return ret; 50 return ret;
263} 51}
264 52
265struct usbip_exported_device *usbip_host_get_device(int num) 53struct usbip_host_driver host_driver = {
266{ 54 .edev_list = LIST_HEAD_INIT(host_driver.edev_list),
267 struct list_head *i; 55 .udev_subsystem = "usb",
268 struct usbip_exported_device *edev; 56 .ops = {
269 int cnt = 0; 57 .open = usbip_host_driver_open,
270 58 .close = usbip_generic_driver_close,
271 list_for_each(i, &host_driver->edev_list) { 59 .refresh_device_list = usbip_generic_refresh_device_list,
272 edev = list_entry(i, struct usbip_exported_device, node); 60 .get_device = usbip_generic_get_device,
273 if (num == cnt) 61 .read_device = read_usb_device,
274 return edev; 62 .read_interface = read_usb_interface,
275 else 63 .is_my_device = is_my_device,
276 cnt++; 64 },
277 } 65};
278
279 return NULL;
280}
diff --git a/tools/usb/usbip/libsrc/usbip_host_driver.h b/tools/usb/usbip/libsrc/usbip_host_driver.h
index 2a31f855c616..77f07e72a7fe 100644
--- a/tools/usb/usbip/libsrc/usbip_host_driver.h
+++ b/tools/usb/usbip/libsrc/usbip_host_driver.h
@@ -1,6 +1,9 @@
1/* 1/*
2 * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> 2 * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
3 * 2005-2007 Takahiro Hirofuchi 3 * 2005-2007 Takahiro Hirofuchi
4 * Copyright (C) 2015-2016 Samsung Electronics
5 * Igor Kotrasinski <i.kotrasinsk@samsung.com>
6 * Krzysztof Opasiak <k.opasiak@samsung.com>
4 * 7 *
5 * This program is free software: you can redistribute it and/or modify 8 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -22,28 +25,8 @@
22#include <stdint.h> 25#include <stdint.h>
23#include "usbip_common.h" 26#include "usbip_common.h"
24#include "list.h" 27#include "list.h"
28#include "usbip_host_common.h"
25 29
26struct usbip_host_driver { 30extern struct usbip_host_driver host_driver;
27 int ndevs;
28 /* list of exported device */
29 struct list_head edev_list;
30};
31
32struct usbip_exported_device {
33 struct udev_device *sudev;
34 int32_t status;
35 struct usbip_usb_device udev;
36 struct list_head node;
37 struct usbip_usb_interface uinf[];
38};
39
40extern struct usbip_host_driver *host_driver;
41
42int usbip_host_driver_open(void);
43void usbip_host_driver_close(void);
44
45int usbip_host_refresh_device_list(void);
46int usbip_host_export_device(struct usbip_exported_device *edev, int sockfd);
47struct usbip_exported_device *usbip_host_get_device(int num);
48 31
49#endif /* __USBIP_HOST_DRIVER_H */ 32#endif /* __USBIP_HOST_DRIVER_H */
diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c
index 2a7cd2b8d966..8a2ec4dab4bd 100644
--- a/tools/usb/usbip/src/usbipd.c
+++ b/tools/usb/usbip/src/usbipd.c
@@ -1,6 +1,9 @@
1/* 1/*
2 * Copyright (C) 2011 matt mooney <mfm@muteddisk.com> 2 * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
3 * 2005-2007 Takahiro Hirofuchi 3 * 2005-2007 Takahiro Hirofuchi
4 * Copyright (C) 2015-2016 Samsung Electronics
5 * Igor Kotrasinski <i.kotrasinsk@samsung.com>
6 * Krzysztof Opasiak <k.opasiak@samsung.com>
4 * 7 *
5 * This program is free software: you can redistribute it and/or modify 8 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -41,6 +44,7 @@
41#include <poll.h> 44#include <poll.h>
42 45
43#include "usbip_host_driver.h" 46#include "usbip_host_driver.h"
47#include "usbip_host_common.h"
44#include "usbip_common.h" 48#include "usbip_common.h"
45#include "usbip_network.h" 49#include "usbip_network.h"
46#include "list.h" 50#include "list.h"
@@ -83,6 +87,8 @@ static const char usbipd_help_string[] =
83 " -v, --version\n" 87 " -v, --version\n"
84 " Show version.\n"; 88 " Show version.\n";
85 89
90static struct usbip_host_driver *driver;
91
86static void usbipd_help(void) 92static void usbipd_help(void)
87{ 93{
88 printf("%s\n", usbipd_help_string); 94 printf("%s\n", usbipd_help_string);
@@ -107,7 +113,7 @@ static int recv_request_import(int sockfd)
107 } 113 }
108 PACK_OP_IMPORT_REQUEST(0, &req); 114 PACK_OP_IMPORT_REQUEST(0, &req);
109 115
110 list_for_each(i, &host_driver->edev_list) { 116 list_for_each(i, &driver->edev_list) {
111 edev = list_entry(i, struct usbip_exported_device, node); 117 edev = list_entry(i, struct usbip_exported_device, node);
112 if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) { 118 if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) {
113 info("found requested device: %s", req.busid); 119 info("found requested device: %s", req.busid);
@@ -121,7 +127,7 @@ static int recv_request_import(int sockfd)
121 usbip_net_set_nodelay(sockfd); 127 usbip_net_set_nodelay(sockfd);
122 128
123 /* export device needs a TCP/IP socket descriptor */ 129 /* export device needs a TCP/IP socket descriptor */
124 rc = usbip_host_export_device(edev, sockfd); 130 rc = usbip_export_device(edev, sockfd);
125 if (rc < 0) 131 if (rc < 0)
126 error = 1; 132 error = 1;
127 } else { 133 } else {
@@ -166,7 +172,7 @@ static int send_reply_devlist(int connfd)
166 172
167 reply.ndev = 0; 173 reply.ndev = 0;
168 /* number of exported devices */ 174 /* number of exported devices */
169 list_for_each(j, &host_driver->edev_list) { 175 list_for_each(j, &driver->edev_list) {
170 reply.ndev += 1; 176 reply.ndev += 1;
171 } 177 }
172 info("exportable devices: %d", reply.ndev); 178 info("exportable devices: %d", reply.ndev);
@@ -184,7 +190,7 @@ static int send_reply_devlist(int connfd)
184 return -1; 190 return -1;
185 } 191 }
186 192
187 list_for_each(j, &host_driver->edev_list) { 193 list_for_each(j, &driver->edev_list) {
188 edev = list_entry(j, struct usbip_exported_device, node); 194 edev = list_entry(j, struct usbip_exported_device, node);
189 dump_usb_device(&edev->udev); 195 dump_usb_device(&edev->udev);
190 memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev)); 196 memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
@@ -246,7 +252,7 @@ static int recv_pdu(int connfd)
246 return -1; 252 return -1;
247 } 253 }
248 254
249 ret = usbip_host_refresh_device_list(); 255 ret = usbip_refresh_device_list(driver);
250 if (ret < 0) { 256 if (ret < 0) {
251 dbg("could not refresh device list: %d", ret); 257 dbg("could not refresh device list: %d", ret);
252 return -1; 258 return -1;
@@ -491,16 +497,13 @@ static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
491 struct timespec timeout; 497 struct timespec timeout;
492 sigset_t sigmask; 498 sigset_t sigmask;
493 499
494 if (usbip_host_driver_open()) { 500 if (usbip_driver_open(driver))
495 err("please load " USBIP_CORE_MOD_NAME ".ko and "
496 USBIP_HOST_DRV_NAME ".ko!");
497 return -1; 501 return -1;
498 }
499 502
500 if (daemonize) { 503 if (daemonize) {
501 if (daemon(0, 0) < 0) { 504 if (daemon(0, 0) < 0) {
502 err("daemonizing failed: %s", strerror(errno)); 505 err("daemonizing failed: %s", strerror(errno));
503 usbip_host_driver_close(); 506 usbip_driver_close(driver);
504 return -1; 507 return -1;
505 } 508 }
506 umask(0); 509 umask(0);
@@ -525,7 +528,7 @@ static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
525 528
526 ai_head = do_getaddrinfo(NULL, family); 529 ai_head = do_getaddrinfo(NULL, family);
527 if (!ai_head) { 530 if (!ai_head) {
528 usbip_host_driver_close(); 531 usbip_driver_close(driver);
529 return -1; 532 return -1;
530 } 533 }
531 nsockfd = listen_all_addrinfo(ai_head, sockfdlist, 534 nsockfd = listen_all_addrinfo(ai_head, sockfdlist,
@@ -533,7 +536,7 @@ static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
533 freeaddrinfo(ai_head); 536 freeaddrinfo(ai_head);
534 if (nsockfd <= 0) { 537 if (nsockfd <= 0) {
535 err("failed to open a listening socket"); 538 err("failed to open a listening socket");
536 usbip_host_driver_close(); 539 usbip_driver_close(driver);
537 return -1; 540 return -1;
538 } 541 }
539 542
@@ -574,7 +577,7 @@ static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
574 577
575 info("shutting down " PROGNAME); 578 info("shutting down " PROGNAME);
576 free(fds); 579 free(fds);
577 usbip_host_driver_close(); 580 usbip_driver_close(driver);
578 581
579 return 0; 582 return 0;
580} 583}
@@ -613,6 +616,7 @@ int main(int argc, char *argv[])
613 err("not running as root?"); 616 err("not running as root?");
614 617
615 cmd = cmd_standalone_mode; 618 cmd = cmd_standalone_mode;
619 driver = &host_driver;
616 for (;;) { 620 for (;;) {
617 opt = getopt_long(argc, argv, "46DdP::t:hv", longopts, NULL); 621 opt = getopt_long(argc, argv, "46DdP::t:hv", longopts, NULL);
618 622