aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakahiro Hirofuchi <hirofuchi@users.sourceforge.net>2008-07-09 16:56:51 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-10-10 18:31:09 -0400
commit4d7b5c7f8ad49b7f01fb8aed83c560ac43cfbda8 (patch)
treeb9a643d4dd14f7048356b21fcb136293efff5b54
parent04679b3489e048cd5dae79e050a3afed8e4e42b6 (diff)
Staging: USB/IP: add host driver
This adds the USB IP client driver Brian Merrell cleaned up a lot of this code and submitted it for inclusion. Greg also did a lot of cleanup. Signed-off-by: Brian G. Merrell <bgmerrell@novell.com> Cc: Takahiro Hirofuchi <hirofuchi@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/usbip/Kconfig11
-rw-r--r--drivers/staging/usbip/Makefile3
-rw-r--r--drivers/staging/usbip/stub.h95
-rw-r--r--drivers/staging/usbip/stub_dev.c483
-rw-r--r--drivers/staging/usbip/stub_main.c300
-rw-r--r--drivers/staging/usbip/stub_rx.c615
-rw-r--r--drivers/staging/usbip/stub_tx.c371
7 files changed, 1878 insertions, 0 deletions
diff --git a/drivers/staging/usbip/Kconfig b/drivers/staging/usbip/Kconfig
index c4d68e1581fc..7426235ccc44 100644
--- a/drivers/staging/usbip/Kconfig
+++ b/drivers/staging/usbip/Kconfig
@@ -23,3 +23,14 @@ config USB_IP_VHCI_HCD
23 23
24 To compile this driver as a module, choose M here: the 24 To compile this driver as a module, choose M here: the
25 module will be called vhci_hcd. 25 module will be called vhci_hcd.
26
27config USB_IP_HOST
28 tristate "USB IP host driver"
29 depends on USB_IP_COMMON
30 default N
31 ---help---
32 This enables the USB IP device driver which will run on the
33 host machine.
34
35 To compile this driver as a module, choose M here: the
36 module will be called usbip.
diff --git a/drivers/staging/usbip/Makefile b/drivers/staging/usbip/Makefile
index 6ef4c3913f45..179f4211f96b 100644
--- a/drivers/staging/usbip/Makefile
+++ b/drivers/staging/usbip/Makefile
@@ -4,6 +4,9 @@ usbip_common_mod-objs := usbip_common.o usbip_event.o
4obj-$(CONFIG_USB_IP_VHCI_HCD) += vhci-hcd.o 4obj-$(CONFIG_USB_IP_VHCI_HCD) += vhci-hcd.o
5vhci-hcd-objs := vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o 5vhci-hcd-objs := vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o
6 6
7obj-$(CONFIG_USB_IP_HOST) += usbip.o
8usbip-objs := stub_dev.o stub_main.o stub_rx.o stub_tx.o
9
7ifeq ($(CONFIG_USB_DEBUG),y) 10ifeq ($(CONFIG_USB_DEBUG),y)
8 EXTRA_CFLAGS += -DDEBUG 11 EXTRA_CFLAGS += -DDEBUG
9endif 12endif
diff --git a/drivers/staging/usbip/stub.h b/drivers/staging/usbip/stub.h
new file mode 100644
index 000000000000..f541a3a83bd3
--- /dev/null
+++ b/drivers/staging/usbip/stub.h
@@ -0,0 +1,95 @@
1/*
2 * Copyright (C) 2003-2008 Takahiro Hirofuchi
3 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA.
18 */
19
20#include <linux/kernel.h>
21#include <linux/list.h>
22#include <linux/spinlock.h>
23#include <linux/slab.h>
24#include <linux/string.h>
25#include <linux/module.h>
26#include <linux/net.h>
27
28struct stub_device {
29 struct usb_interface *interface;
30 struct list_head list;
31
32 struct usbip_device ud;
33 __u32 devid;
34
35 /*
36 * stub_priv preserves private data of each urb.
37 * It is allocated as stub_priv_cache and assigned to urb->context.
38 *
39 * stub_priv is always linked to any one of 3 lists;
40 * priv_init: linked to this until the comletion of a urb.
41 * priv_tx : linked to this after the completion of a urb.
42 * priv_free: linked to this after the sending of the result.
43 *
44 * Any of these list operations should be locked by priv_lock.
45 */
46 spinlock_t priv_lock;
47 struct list_head priv_init;
48 struct list_head priv_tx;
49 struct list_head priv_free;
50
51 /* see comments for unlinking in stub_rx.c */
52 struct list_head unlink_tx;
53 struct list_head unlink_free;
54
55
56 wait_queue_head_t tx_waitq;
57};
58
59/* private data into urb->priv */
60struct stub_priv {
61 unsigned long seqnum;
62 struct list_head list;
63 struct stub_device *sdev;
64 struct urb *urb;
65
66 int unlinking;
67};
68
69struct stub_unlink {
70 unsigned long seqnum;
71 struct list_head list;
72 __u32 status;
73};
74
75
76extern struct kmem_cache *stub_priv_cache;
77
78
79/*-------------------------------------------------------------------------*/
80/* prototype declarations */
81
82/* stub_tx.c */
83void stub_complete(struct urb *);
84void stub_tx_loop(struct usbip_task *);
85
86/* stub_dev.c */
87extern struct usb_driver stub_driver;
88
89/* stub_rx.c */
90void stub_rx_loop(struct usbip_task *);
91void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32);
92
93/* stub_main.c */
94int match_busid(char *busid);
95void stub_device_cleanup_urbs(struct stub_device *sdev);
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c
new file mode 100644
index 000000000000..ee455a087eaf
--- /dev/null
+++ b/drivers/staging/usbip/stub_dev.c
@@ -0,0 +1,483 @@
1/*
2 * Copyright (C) 2003-2008 Takahiro Hirofuchi
3 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA.
18 */
19
20#include "usbip_common.h"
21#include "stub.h"
22
23
24
25static int stub_probe(struct usb_interface *interface,
26 const struct usb_device_id *id);
27static void stub_disconnect(struct usb_interface *interface);
28
29
30/*
31 * Define device IDs here if you want to explicitly limit exportable devices.
32 * In the most cases, wild card matching will be ok because driver binding can
33 * be changed dynamically by a userland program.
34 */
35static struct usb_device_id stub_table[] = {
36#if 0
37 /* just an example */
38 { USB_DEVICE(0x05ac, 0x0301) }, /* Mac 1 button mouse */
39 { USB_DEVICE(0x0430, 0x0009) }, /* Plat Home Keyboard */
40 { USB_DEVICE(0x059b, 0x0001) }, /* Iomega USB Zip 100 */
41 { USB_DEVICE(0x04b3, 0x4427) }, /* IBM USB CD-ROM */
42 { USB_DEVICE(0x05a9, 0xa511) }, /* LifeView USB cam */
43 { USB_DEVICE(0x55aa, 0x0201) }, /* Imation card reader */
44 { USB_DEVICE(0x046d, 0x0870) }, /* Qcam Express(QV-30) */
45 { USB_DEVICE(0x04bb, 0x0101) }, /* IO-DATA HD 120GB */
46 { USB_DEVICE(0x04bb, 0x0904) }, /* IO-DATA USB-ET/TX */
47 { USB_DEVICE(0x04bb, 0x0201) }, /* IO-DATA USB-ET/TX */
48 { USB_DEVICE(0x08bb, 0x2702) }, /* ONKYO USB Speaker */
49 { USB_DEVICE(0x046d, 0x08b2) }, /* Logicool Qcam 4000 Pro */
50#endif
51 /* magic for wild card */
52 { .driver_info = 1 },
53 { 0, } /* Terminating entry */
54};
55MODULE_DEVICE_TABLE(usb, stub_table);
56
57struct usb_driver stub_driver = {
58 .name = "usbip",
59 .probe = stub_probe,
60 .disconnect = stub_disconnect,
61 .id_table = stub_table,
62};
63
64
65/*-------------------------------------------------------------------------*/
66
67/* Define sysfs entries for a usbip-bound device */
68
69
70/*
71 * usbip_status shows status of usbip as long as this driver is bound to the
72 * target device.
73 */
74static ssize_t show_status(struct device *dev, struct device_attribute *attr,
75 char *buf)
76{
77 struct stub_device *sdev = dev_get_drvdata(dev);
78 int status;
79
80 if (!sdev) {
81 dev_err(dev, "sdev is null\n");
82 return -ENODEV;
83 }
84
85 spin_lock(&sdev->ud.lock);
86 status = sdev->ud.status;
87 spin_unlock(&sdev->ud.lock);
88
89 return snprintf(buf, PAGE_SIZE, "%d\n", status);
90}
91static DEVICE_ATTR(usbip_status, S_IRUGO, show_status, NULL);
92
93/*
94 * usbip_sockfd gets a socket descriptor of an established TCP connection that
95 * is used to transfer usbip requests by kernel threads. -1 is a magic number
96 * by which usbip connection is finished.
97 */
98static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr,
99 const char *buf, size_t count)
100{
101 struct stub_device *sdev = dev_get_drvdata(dev);
102 int sockfd = 0;
103 struct socket *socket;
104
105 if (!sdev) {
106 dev_err(dev, "sdev is null\n");
107 return -ENODEV;
108 }
109
110 sscanf(buf, "%d", &sockfd);
111
112 if (sockfd != -1) {
113 dev_info(dev, "stub up\n");
114
115 spin_lock(&sdev->ud.lock);
116
117 if (sdev->ud.status != SDEV_ST_AVAILABLE) {
118 dev_err(dev, "not ready\n");
119 spin_unlock(&sdev->ud.lock);
120 return -EINVAL;
121 }
122
123 socket = sockfd_to_socket(sockfd);
124 if (!socket) {
125 spin_unlock(&sdev->ud.lock);
126 return -EINVAL;
127 }
128
129#if 0
130 setnodelay(socket);
131 setkeepalive(socket);
132 setreuse(socket);
133#endif
134
135 sdev->ud.tcp_socket = socket;
136
137 spin_unlock(&sdev->ud.lock);
138
139 usbip_start_threads(&sdev->ud);
140
141 spin_lock(&sdev->ud.lock);
142 sdev->ud.status = SDEV_ST_USED;
143 spin_unlock(&sdev->ud.lock);
144
145 } else {
146 dev_info(dev, "stub down\n");
147
148 spin_lock(&sdev->ud.lock);
149 if (sdev->ud.status != SDEV_ST_USED) {
150 spin_unlock(&sdev->ud.lock);
151 return -EINVAL;
152 }
153 spin_unlock(&sdev->ud.lock);
154
155 usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN);
156 }
157
158 return count;
159}
160static DEVICE_ATTR(usbip_sockfd, S_IWUSR, NULL, store_sockfd);
161
162static int stub_add_files(struct device *dev)
163{
164 int err = 0;
165
166 err = device_create_file(dev, &dev_attr_usbip_status);
167 if (err)
168 goto err_status;
169
170 err = device_create_file(dev, &dev_attr_usbip_sockfd);
171 if (err)
172 goto err_sockfd;
173
174 err = device_create_file(dev, &dev_attr_usbip_debug);
175 if (err)
176 goto err_debug;
177
178 return 0;
179
180err_debug:
181 device_remove_file(dev, &dev_attr_usbip_sockfd);
182
183err_sockfd:
184 device_remove_file(dev, &dev_attr_usbip_status);
185
186err_status:
187 return err;
188}
189
190static void stub_remove_files(struct device *dev)
191{
192 device_remove_file(dev, &dev_attr_usbip_status);
193 device_remove_file(dev, &dev_attr_usbip_sockfd);
194 device_remove_file(dev, &dev_attr_usbip_debug);
195}
196
197
198
199/*-------------------------------------------------------------------------*/
200
201/* Event handler functions called by an event handler thread */
202
203static void stub_shutdown_connection(struct usbip_device *ud)
204{
205 struct stub_device *sdev = container_of(ud, struct stub_device, ud);
206
207 /*
208 * When removing an exported device, kernel panic sometimes occurred
209 * and then EIP was sk_wait_data of stub_rx thread. Is this because
210 * sk_wait_data returned though stub_rx thread was already finished by
211 * step 1?
212 */
213 if (ud->tcp_socket) {
214 udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
215 kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
216 }
217
218 /* 1. stop threads */
219 usbip_stop_threads(ud);
220
221 /* 2. close the socket */
222 /*
223 * tcp_socket is freed after threads are killed.
224 * So usbip_xmit do not touch NULL socket.
225 */
226 if (ud->tcp_socket) {
227 sock_release(ud->tcp_socket);
228 ud->tcp_socket = NULL;
229 }
230
231 /* 3. free used data */
232 stub_device_cleanup_urbs(sdev);
233
234 /* 4. free stub_unlink */
235 {
236 unsigned long flags;
237 struct stub_unlink *unlink, *tmp;
238
239 spin_lock_irqsave(&sdev->priv_lock, flags);
240
241 list_for_each_entry_safe(unlink, tmp, &sdev->unlink_tx, list) {
242 list_del(&unlink->list);
243 kfree(unlink);
244 }
245
246 list_for_each_entry_safe(unlink, tmp,
247 &sdev->unlink_free, list) {
248 list_del(&unlink->list);
249 kfree(unlink);
250 }
251
252 spin_unlock_irqrestore(&sdev->priv_lock, flags);
253 }
254}
255
256static void stub_device_reset(struct usbip_device *ud)
257{
258 struct stub_device *sdev = container_of(ud, struct stub_device, ud);
259 struct usb_device *udev = interface_to_usbdev(sdev->interface);
260 int ret;
261
262 udbg("device reset");
263 ret = usb_lock_device_for_reset(udev, sdev->interface);
264 if (ret < 0) {
265 dev_err(&udev->dev, "lock for reset\n");
266
267 spin_lock(&ud->lock);
268 ud->status = SDEV_ST_ERROR;
269 spin_unlock(&ud->lock);
270
271 return;
272 }
273
274 /* try to reset the device */
275 ret = usb_reset_device(udev);
276
277 usb_unlock_device(udev);
278
279 spin_lock(&ud->lock);
280 if (ret) {
281 dev_err(&udev->dev, "device reset\n");
282 ud->status = SDEV_ST_ERROR;
283
284 } else {
285 dev_info(&udev->dev, "device reset\n");
286 ud->status = SDEV_ST_AVAILABLE;
287
288 }
289 spin_unlock(&ud->lock);
290
291 return;
292}
293
294static void stub_device_unusable(struct usbip_device *ud)
295{
296 spin_lock(&ud->lock);
297 ud->status = SDEV_ST_ERROR;
298 spin_unlock(&ud->lock);
299}
300
301
302/*-------------------------------------------------------------------------*/
303
304/**
305 * stub_device_alloc - allocate a new stub_device struct
306 * @interface: usb_interface of a new device
307 *
308 * Allocates and initializes a new stub_device struct.
309 */
310static struct stub_device *stub_device_alloc(struct usb_interface *interface)
311{
312 struct stub_device *sdev;
313 int busnum = interface_to_busnum(interface);
314 int devnum = interface_to_devnum(interface);
315
316 dev_dbg(&interface->dev, "allocating stub device");
317
318 /* yes, it's a new device */
319 sdev = kzalloc(sizeof(struct stub_device), GFP_KERNEL);
320 if (!sdev) {
321 dev_err(&interface->dev, "no memory for stub_device\n");
322 return NULL;
323 }
324
325 sdev->interface = interface;
326
327 /*
328 * devid is defined with devnum when this driver is first allocated.
329 * devnum may change later if a device is reset. However, devid never
330 * changes during a usbip connection.
331 */
332 sdev->devid = (busnum << 16) | devnum;
333
334 usbip_task_init(&sdev->ud.tcp_rx, "stub_rx", stub_rx_loop);
335 usbip_task_init(&sdev->ud.tcp_tx, "stub_tx", stub_tx_loop);
336
337 sdev->ud.side = USBIP_STUB;
338 sdev->ud.status = SDEV_ST_AVAILABLE;
339 /* sdev->ud.lock = SPIN_LOCK_UNLOCKED; */
340 spin_lock_init(&sdev->ud.lock);
341 sdev->ud.tcp_socket = NULL;
342
343 INIT_LIST_HEAD(&sdev->priv_init);
344 INIT_LIST_HEAD(&sdev->priv_tx);
345 INIT_LIST_HEAD(&sdev->priv_free);
346 INIT_LIST_HEAD(&sdev->unlink_free);
347 INIT_LIST_HEAD(&sdev->unlink_tx);
348 /* sdev->priv_lock = SPIN_LOCK_UNLOCKED; */
349 spin_lock_init(&sdev->priv_lock);
350
351 init_waitqueue_head(&sdev->tx_waitq);
352
353 sdev->ud.eh_ops.shutdown = stub_shutdown_connection;
354 sdev->ud.eh_ops.reset = stub_device_reset;
355 sdev->ud.eh_ops.unusable = stub_device_unusable;
356
357 usbip_start_eh(&sdev->ud);
358
359 udbg("register new interface\n");
360 return sdev;
361}
362
363static int stub_device_free(struct stub_device *sdev)
364{
365 if (!sdev)
366 return -EINVAL;
367
368 kfree(sdev);
369 udbg("kfree udev ok\n");
370
371 return 0;
372}
373
374
375/*-------------------------------------------------------------------------*/
376
377/*
378 * If a usb device has multiple active interfaces, this driver is bound to all
379 * the active interfaces. However, usbip exports *a* usb device (i.e., not *an*
380 * active interface). Currently, a userland program must ensure that it
381 * looks at the usbip's sysfs entries of only the first active interface.
382 *
383 * TODO: use "struct usb_device_driver" to bind a usb device.
384 * However, it seems it is not fully supported in mainline kernel yet
385 * (2.6.19.2).
386 */
387static int stub_probe(struct usb_interface *interface,
388 const struct usb_device_id *id)
389{
390 struct usb_device *udev = interface_to_usbdev(interface);
391 struct stub_device *sdev = NULL;
392 char *udev_busid = interface->dev.parent->bus_id;
393 int err = 0;
394
395 dev_dbg(&interface->dev, "Enter\n");
396
397 /* check we should claim or not by busid_table */
398 if (match_busid(udev_busid)) {
399 dev_info(&interface->dev,
400 "this device %s is not in match_busid table. skip!\n",
401 udev_busid);
402
403 /*
404 * Return value should be ENODEV or ENOXIO to continue trying
405 * other matched drivers by the driver core.
406 * See driver_probe_device() in driver/base/dd.c
407 */
408 return -ENODEV;
409 }
410
411 if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) {
412 udbg("this device %s is a usb hub device. skip!\n",
413 udev_busid);
414 return -ENODEV;
415 }
416
417 if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
418 udbg("this device %s is attached on vhci_hcd. skip!\n",
419 udev_busid);
420 return -ENODEV;
421 }
422
423 /* ok. this is my device. */
424 sdev = stub_device_alloc(interface);
425 if (!sdev)
426 return -ENOMEM;
427
428 dev_info(&interface->dev, "USB/IP Stub: register a new interface "
429 "(bus %u dev %u ifn %u)\n", udev->bus->busnum, udev->devnum,
430 interface->cur_altsetting->desc.bInterfaceNumber);
431
432 /* set private data to usb_interface */
433 usb_set_intfdata(interface, sdev);
434
435 err = stub_add_files(&interface->dev);
436 if (err) {
437 dev_err(&interface->dev, "create sysfs files for %s\n",
438 udev_busid);
439 return err;
440 }
441
442 return 0;
443}
444
445
446/*
447 * called in usb_disconnect() or usb_deregister()
448 * but only if actconfig(active configuration) exists
449 */
450static void stub_disconnect(struct usb_interface *interface)
451{
452 struct stub_device *sdev = usb_get_intfdata(interface);
453
454 udbg("Enter\n");
455
456 /* get stub_device */
457 if (!sdev) {
458 err(" could not get device from inteface data");
459 /* BUG(); */
460 return;
461 }
462
463 usb_set_intfdata(interface, NULL);
464
465
466 /*
467 * NOTE:
468 * rx/tx threads are invoked for each usb_device.
469 */
470 stub_remove_files(&interface->dev);
471
472 /* 1. shutdown the current connection */
473 usbip_event_add(&sdev->ud, SDEV_EVENT_REMOVED);
474
475 /* 2. wait for the stop of the event handler */
476 usbip_stop_eh(&sdev->ud);
477
478 /* 3. free sdev */
479 stub_device_free(sdev);
480
481
482 udbg("bye\n");
483}
diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c
new file mode 100644
index 000000000000..c665d7f1ca9a
--- /dev/null
+++ b/drivers/staging/usbip/stub_main.c
@@ -0,0 +1,300 @@
1/*
2 * Copyright (C) 2003-2008 Takahiro Hirofuchi
3 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA.
18 */
19
20
21#include "usbip_common.h"
22#include "stub.h"
23
24/* Version Information */
25#define DRIVER_VERSION "1.0"
26#define DRIVER_AUTHOR "Takahiro Hirofuchi"
27#define DRIVER_DESC "Stub Driver for USB/IP"
28
29/* stub_priv is allocated from stub_priv_cache */
30struct kmem_cache *stub_priv_cache;
31
32/*-------------------------------------------------------------------------*/
33
34/* Define sysfs entries for the usbip driver */
35
36
37/*
38 * busid_tables defines matching busids that usbip can grab. A user can change
39 * dynamically what device is locally used and what device is exported to a
40 * remote host.
41 */
42#define MAX_BUSID 16
43static char busid_table[MAX_BUSID][BUS_ID_SIZE];
44static spinlock_t busid_table_lock;
45
46
47int match_busid(char *busid)
48{
49 int i;
50
51 spin_lock(&busid_table_lock);
52
53 for (i = 0; i < MAX_BUSID; i++)
54 if (busid_table[i][0])
55 if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) {
56 /* already registerd */
57 spin_unlock(&busid_table_lock);
58 return 0;
59 }
60
61 spin_unlock(&busid_table_lock);
62
63 return 1;
64}
65
66static ssize_t show_match_busid(struct device_driver *drv, char *buf)
67{
68 int i;
69 char *out = buf;
70
71 spin_lock(&busid_table_lock);
72
73 for (i = 0; i < MAX_BUSID; i++)
74 if (busid_table[i][0])
75 out += sprintf(out, "%s ", busid_table[i]);
76
77 spin_unlock(&busid_table_lock);
78
79 out += sprintf(out, "\n");
80
81 return out - buf;
82}
83
84static int add_match_busid(char *busid)
85{
86 int i;
87
88 if (!match_busid(busid))
89 return 0;
90
91 spin_lock(&busid_table_lock);
92
93 for (i = 0; i < MAX_BUSID; i++)
94 if (!busid_table[i][0]) {
95 strncpy(busid_table[i], busid, BUS_ID_SIZE);
96 spin_unlock(&busid_table_lock);
97 return 0;
98 }
99
100 spin_unlock(&busid_table_lock);
101
102 return -1;
103}
104
105static int del_match_busid(char *busid)
106{
107 int i;
108
109 spin_lock(&busid_table_lock);
110
111 for (i = 0; i < MAX_BUSID; i++)
112 if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) {
113 /* found */
114 memset(busid_table[i], 0, BUS_ID_SIZE);
115 spin_unlock(&busid_table_lock);
116 return 0;
117 }
118
119 spin_unlock(&busid_table_lock);
120
121 return -1;
122}
123
124static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
125 size_t count)
126{
127 int len;
128 char busid[BUS_ID_SIZE];
129
130 if (count < 5)
131 return -EINVAL;
132
133 /* strnlen() does not include \0 */
134 len = strnlen(buf + 4, BUS_ID_SIZE);
135
136 /* busid needs to include \0 termination */
137 if (!(len < BUS_ID_SIZE))
138 return -EINVAL;
139
140 strncpy(busid, buf + 4, BUS_ID_SIZE);
141
142
143 if (!strncmp(buf, "add ", 4)) {
144 if (add_match_busid(busid) < 0)
145 return -ENOMEM;
146 else {
147 udbg("add busid %s\n", busid);
148 return count;
149 }
150 } else if (!strncmp(buf, "del ", 4)) {
151 if (del_match_busid(busid) < 0)
152 return -ENODEV;
153 else {
154 udbg("del busid %s\n", busid);
155 return count;
156 }
157 } else
158 return -EINVAL;
159}
160
161static DRIVER_ATTR(match_busid, S_IRUSR|S_IWUSR, show_match_busid,
162 store_match_busid);
163
164
165
166/*-------------------------------------------------------------------------*/
167
168/* Cleanup functions used to free private data */
169
170static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead)
171{
172 struct stub_priv *priv, *tmp;
173
174 list_for_each_entry_safe(priv, tmp, listhead, list) {
175 list_del(&priv->list);
176 return priv;
177 }
178
179 return NULL;
180}
181
182static struct stub_priv *stub_priv_pop(struct stub_device *sdev)
183{
184 unsigned long flags;
185 struct stub_priv *priv;
186
187 spin_lock_irqsave(&sdev->priv_lock, flags);
188
189 priv = stub_priv_pop_from_listhead(&sdev->priv_init);
190 if (priv) {
191 spin_unlock_irqrestore(&sdev->priv_lock, flags);
192 return priv;
193 }
194
195 priv = stub_priv_pop_from_listhead(&sdev->priv_tx);
196 if (priv) {
197 spin_unlock_irqrestore(&sdev->priv_lock, flags);
198 return priv;
199 }
200
201 priv = stub_priv_pop_from_listhead(&sdev->priv_free);
202 if (priv) {
203 spin_unlock_irqrestore(&sdev->priv_lock, flags);
204 return priv;
205 }
206
207 spin_unlock_irqrestore(&sdev->priv_lock, flags);
208 return NULL;
209}
210
211void stub_device_cleanup_urbs(struct stub_device *sdev)
212{
213 struct stub_priv *priv;
214
215 udbg("free sdev %p\n", sdev);
216
217 while ((priv = stub_priv_pop(sdev))) {
218 struct urb *urb = priv->urb;
219
220 udbg(" free urb %p\n", urb);
221 usb_kill_urb(urb);
222
223 kmem_cache_free(stub_priv_cache, priv);
224
225 if (urb->transfer_buffer != NULL)
226 kfree(urb->transfer_buffer);
227
228 if (urb->setup_packet != NULL)
229 kfree(urb->setup_packet);
230
231 usb_free_urb(urb);
232 }
233}
234
235
236/*-------------------------------------------------------------------------*/
237
238static int __init usb_stub_init(void)
239{
240 int ret;
241
242 stub_priv_cache = kmem_cache_create("stub_priv",
243 sizeof(struct stub_priv), 0,
244 SLAB_HWCACHE_ALIGN, NULL);
245
246 if (!stub_priv_cache) {
247 printk(KERN_ERR KBUILD_MODNAME
248 ": create stub_priv_cache error\n");
249 return -ENOMEM;
250 }
251
252 ret = usb_register(&stub_driver);
253 if (ret) {
254 printk(KERN_ERR KBUILD_MODNAME ": usb_register failed %d\n",
255 ret);
256 goto error_usb_register;
257 }
258
259 printk(KERN_INFO KBUILD_MODNAME ":"
260 DRIVER_DESC ":" DRIVER_VERSION "\n");
261
262 memset(busid_table, 0, sizeof(busid_table));
263 spin_lock_init(&busid_table_lock);
264
265 ret = driver_create_file(&stub_driver.drvwrap.driver,
266 &driver_attr_match_busid);
267
268 if (ret) {
269 printk(KERN_ERR KBUILD_MODNAME ": create driver sysfs\n");
270 goto error_create_file;
271 }
272
273 return ret;
274error_create_file:
275 usb_deregister(&stub_driver);
276error_usb_register:
277 kmem_cache_destroy(stub_priv_cache);
278 return ret;
279}
280
281static void __exit usb_stub_exit(void)
282{
283 driver_remove_file(&stub_driver.drvwrap.driver,
284 &driver_attr_match_busid);
285
286 /*
287 * deregister() calls stub_disconnect() for all devices. Device
288 * specific data is cleared in stub_disconnect().
289 */
290 usb_deregister(&stub_driver);
291
292 kmem_cache_destroy(stub_priv_cache);
293}
294
295module_init(usb_stub_init);
296module_exit(usb_stub_exit);
297
298MODULE_AUTHOR(DRIVER_AUTHOR);
299MODULE_DESCRIPTION(DRIVER_DESC);
300MODULE_LICENSE("GPL");
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
new file mode 100644
index 000000000000..36ce898fced5
--- /dev/null
+++ b/drivers/staging/usbip/stub_rx.c
@@ -0,0 +1,615 @@
1/*
2 * Copyright (C) 2003-2008 Takahiro Hirofuchi
3 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA.
18 */
19
20#include "usbip_common.h"
21#include "stub.h"
22#include "../../usb/core/hcd.h"
23
24
25static int is_clear_halt_cmd(struct urb *urb)
26{
27 struct usb_ctrlrequest *req;
28
29 req = (struct usb_ctrlrequest *) urb->setup_packet;
30
31 return (req->bRequest == USB_REQ_CLEAR_FEATURE) &&
32 (req->bRequestType == USB_RECIP_ENDPOINT) &&
33 (req->wValue == USB_ENDPOINT_HALT);
34}
35
36static int is_set_interface_cmd(struct urb *urb)
37{
38 struct usb_ctrlrequest *req;
39
40 req = (struct usb_ctrlrequest *) urb->setup_packet;
41
42 return (req->bRequest == USB_REQ_SET_INTERFACE) &&
43 (req->bRequestType == USB_RECIP_INTERFACE);
44}
45
46static int is_set_configuration_cmd(struct urb *urb)
47{
48 struct usb_ctrlrequest *req;
49
50 req = (struct usb_ctrlrequest *) urb->setup_packet;
51
52 return (req->bRequest == USB_REQ_SET_CONFIGURATION) &&
53 (req->bRequestType == USB_RECIP_DEVICE);
54}
55
56static int is_reset_device_cmd(struct urb *urb)
57{
58 struct usb_ctrlrequest *req;
59 __u16 value;
60 __u16 index;
61
62 req = (struct usb_ctrlrequest *) urb->setup_packet;
63 value = le16_to_cpu(req->wValue);
64 index = le16_to_cpu(req->wIndex);
65
66 if ((req->bRequest == USB_REQ_SET_FEATURE) &&
67 (req->bRequestType == USB_RT_PORT) &&
68 (value = USB_PORT_FEAT_RESET)) {
69 dbg_stub_rx("reset_device_cmd, port %u\n", index);
70 return 1;
71 } else
72 return 0;
73}
74
75static int tweak_clear_halt_cmd(struct urb *urb)
76{
77 struct usb_ctrlrequest *req;
78 int target_endp;
79 int target_dir;
80 int target_pipe;
81 int ret;
82
83 req = (struct usb_ctrlrequest *) urb->setup_packet;
84
85 /*
86 * The stalled endpoint is specified in the wIndex value. The endpoint
87 * of the urb is the target of this clear_halt request (i.e., control
88 * endpoint).
89 */
90 target_endp = le16_to_cpu(req->wIndex) & 0x000f;
91
92 /* the stalled endpoint direction is IN or OUT?. USB_DIR_IN is 0x80. */
93 target_dir = le16_to_cpu(req->wIndex) & 0x0080;
94
95 if (target_dir)
96 target_pipe = usb_rcvctrlpipe(urb->dev, target_endp);
97 else
98 target_pipe = usb_sndctrlpipe(urb->dev, target_endp);
99
100 ret = usb_clear_halt(urb->dev, target_pipe);
101 if (ret < 0)
102 uinfo("clear_halt error: devnum %d endp %d, %d\n",
103 urb->dev->devnum, target_endp, ret);
104 else
105 uinfo("clear_halt done: devnum %d endp %d\n",
106 urb->dev->devnum, target_endp);
107
108 return ret;
109}
110
111static int tweak_set_interface_cmd(struct urb *urb)
112{
113 struct usb_ctrlrequest *req;
114 __u16 alternate;
115 __u16 interface;
116 int ret;
117
118 req = (struct usb_ctrlrequest *) urb->setup_packet;
119 alternate = le16_to_cpu(req->wValue);
120 interface = le16_to_cpu(req->wIndex);
121
122 dbg_stub_rx("set_interface: inf %u alt %u\n", interface, alternate);
123
124 ret = usb_set_interface(urb->dev, interface, alternate);
125 if (ret < 0)
126 uinfo("set_interface error: inf %u alt %u, %d\n",
127 interface, alternate, ret);
128 else
129 uinfo("set_interface done: inf %u alt %u\n",
130 interface,
131 alternate);
132
133 return ret;
134}
135
136static int tweak_set_configuration_cmd(struct urb *urb)
137{
138 struct usb_ctrlrequest *req;
139 __u16 config;
140
141 req = (struct usb_ctrlrequest *) urb->setup_packet;
142 config = le16_to_cpu(req->wValue);
143
144 /*
145 * I have never seen a multi-config device. Very rare.
146 * For most devices, this will be called to choose a default
147 * configuration only once in an initialization phase.
148 *
149 * set_configuration may change a device configuration and its device
150 * drivers will be unbound and assigned for a new device configuration.
151 * This means this usbip driver will be also unbound when called, then
152 * eventually reassigned to the device as far as driver matching
153 * condition is kept.
154 *
155 * Unfortunatelly, an existing usbip connection will be dropped
156 * due to this driver unbinding. So, skip here.
157 * A user may need to set a special configuration value before
158 * exporting the device.
159 */
160 uinfo("set_configuration (%d) to %s\n", config, urb->dev->dev.bus_id);
161 uinfo("but, skip!\n");
162
163 return 0;
164 /* return usb_driver_set_configuration(urb->dev, config); */
165}
166
167static int tweak_reset_device_cmd(struct urb *urb)
168{
169 struct usb_ctrlrequest *req;
170 __u16 value;
171 __u16 index;
172 int ret;
173
174 req = (struct usb_ctrlrequest *) urb->setup_packet;
175 value = le16_to_cpu(req->wValue);
176 index = le16_to_cpu(req->wIndex);
177
178 uinfo("reset_device (port %d) to %s\n", index, urb->dev->dev.bus_id);
179
180 /* all interfaces should be owned by usbip driver, so just reset it. */
181 ret = usb_lock_device_for_reset(urb->dev, NULL);
182 if (ret < 0) {
183 dev_err(&urb->dev->dev, "lock for reset\n");
184 return ret;
185 }
186
187 /* try to reset the device */
188 ret = usb_reset_device(urb->dev);
189 if (ret < 0)
190 dev_err(&urb->dev->dev, "device reset\n");
191
192 usb_unlock_device(urb->dev);
193
194 return ret;
195}
196
197/*
198 * clear_halt, set_interface, and set_configuration require special tricks.
199 */
200static void tweak_special_requests(struct urb *urb)
201{
202 if (!urb || !urb->setup_packet)
203 return;
204
205 if (usb_pipetype(urb->pipe) != PIPE_CONTROL)
206 return;
207
208 if (is_clear_halt_cmd(urb))
209 /* tweak clear_halt */
210 tweak_clear_halt_cmd(urb);
211
212 else if (is_set_interface_cmd(urb))
213 /* tweak set_interface */
214 tweak_set_interface_cmd(urb);
215
216 else if (is_set_configuration_cmd(urb))
217 /* tweak set_configuration */
218 tweak_set_configuration_cmd(urb);
219
220 else if (is_reset_device_cmd(urb))
221 tweak_reset_device_cmd(urb);
222 else
223 dbg_stub_rx("no need to tweak\n");
224}
225
226/*
227 * stub_recv_unlink() unlinks the URB by a call to usb_unlink_urb().
228 * By unlinking the urb asynchronously, stub_rx can continuously
229 * process coming urbs. Even if the urb is unlinked, its completion
230 * handler will be called and stub_tx will send a return pdu.
231 *
232 * See also comments about unlinking strategy in vhci_hcd.c.
233 */
234static int stub_recv_cmd_unlink(struct stub_device *sdev,
235 struct usbip_header *pdu)
236{
237 struct list_head *listhead = &sdev->priv_init;
238 struct list_head *ptr;
239 unsigned long flags;
240
241 struct stub_priv *priv;
242
243
244 spin_lock_irqsave(&sdev->priv_lock, flags);
245
246 for (ptr = listhead->next; ptr != listhead; ptr = ptr->next) {
247 priv = list_entry(ptr, struct stub_priv, list);
248 if (priv->seqnum == pdu->u.cmd_unlink.seqnum) {
249 int ret;
250
251 dev_info(&priv->urb->dev->dev, "unlink urb %p\n",
252 priv->urb);
253
254 /*
255 * This matched urb is not completed yet (i.e., be in
256 * flight in usb hcd hardware/driver). Now we are
257 * cancelling it. The unlinking flag means that we are
258 * now not going to return the normal result pdu of a
259 * submission request, but going to return a result pdu
260 * of the unlink request.
261 */
262 priv->unlinking = 1;
263
264 /*
265 * In the case that unlinking flag is on, prev->seqnum
266 * is changed from the seqnum of the cancelling urb to
267 * the seqnum of the unlink request. This will be used
268 * to make the result pdu of the unlink request.
269 */
270 priv->seqnum = pdu->base.seqnum;
271
272 spin_unlock_irqrestore(&sdev->priv_lock, flags);
273
274 /*
275 * usb_unlink_urb() is now out of spinlocking to avoid
276 * spinlock recursion since stub_complete() is
277 * sometimes called in this context but not in the
278 * interrupt context. If stub_complete() is executed
279 * before we call usb_unlink_urb(), usb_unlink_urb()
280 * will return an error value. In this case, stub_tx
281 * will return the result pdu of this unlink request
282 * though submission is completed and actual unlinking
283 * is not executed. OK?
284 */
285 /* In the above case, urb->status is not -ECONNRESET,
286 * so a driver in a client host will know the failure
287 * of the unlink request ?
288 */
289 ret = usb_unlink_urb(priv->urb);
290 if (ret != -EINPROGRESS)
291 dev_err(&priv->urb->dev->dev,
292 "failed to unlink a urb %p, ret %d\n",
293 priv->urb, ret);
294 return 0;
295 }
296 }
297
298 dbg_stub_rx("seqnum %d is not pending\n", pdu->u.cmd_unlink.seqnum);
299
300 /*
301 * The urb of the unlink target is not found in priv_init queue. It was
302 * already completed and its results is/was going to be sent by a
303 * CMD_RET pdu. In this case, usb_unlink_urb() is not needed. We only
304 * return the completeness of this unlink request to vhci_hcd.
305 */
306 stub_enqueue_ret_unlink(sdev, pdu->base.seqnum, 0);
307
308 spin_unlock_irqrestore(&sdev->priv_lock, flags);
309
310
311 return 0;
312}
313
314static int valid_request(struct stub_device *sdev, struct usbip_header *pdu)
315{
316 struct usbip_device *ud = &sdev->ud;
317
318 if (pdu->base.devid == sdev->devid) {
319 spin_lock(&ud->lock);
320 if (ud->status == SDEV_ST_USED) {
321 /* A request is valid. */
322 spin_unlock(&ud->lock);
323 return 1;
324 }
325 spin_unlock(&ud->lock);
326 }
327
328 return 0;
329}
330
331static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
332 struct usbip_header *pdu)
333{
334 struct stub_priv *priv;
335 struct usbip_device *ud = &sdev->ud;
336 unsigned long flags;
337
338 spin_lock_irqsave(&sdev->priv_lock, flags);
339
340 priv = kmem_cache_alloc(stub_priv_cache, GFP_ATOMIC);
341 if (!priv) {
342 dev_err(&sdev->interface->dev, "alloc stub_priv\n");
343 spin_unlock_irqrestore(&sdev->priv_lock, flags);
344 usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
345 return NULL;
346 }
347
348 memset(priv, 0, sizeof(struct stub_priv));
349
350 priv->seqnum = pdu->base.seqnum;
351 priv->sdev = sdev;
352
353 /*
354 * After a stub_priv is linked to a list_head,
355 * our error handler can free allocated data.
356 */
357 list_add_tail(&priv->list, &sdev->priv_init);
358
359 spin_unlock_irqrestore(&sdev->priv_lock, flags);
360
361 return priv;
362}
363
364
365static struct usb_host_endpoint *get_ep_from_epnum(struct usb_device *udev,
366 int epnum0)
367{
368 struct usb_host_config *config;
369 int i = 0, j = 0;
370 struct usb_host_endpoint *ep = NULL;
371 int epnum;
372 int found = 0;
373
374 if (epnum0 == 0)
375 return &udev->ep0;
376
377 config = udev->actconfig;
378 if (!config)
379 return NULL;
380
381 for (i = 0; i < config->desc.bNumInterfaces; i++) {
382 struct usb_host_interface *setting;
383
384 setting = config->interface[i]->cur_altsetting;
385
386 for (j = 0; j < setting->desc.bNumEndpoints; j++) {
387 ep = &setting->endpoint[j];
388 epnum = (ep->desc.bEndpointAddress & 0x7f);
389
390 if (epnum == epnum0) {
391 /* uinfo("found epnum %d\n", epnum0); */
392 found = 1;
393 break;
394 }
395 }
396 }
397
398 if (found)
399 return ep;
400 else
401 return NULL;
402}
403
404
405static int get_pipe(struct stub_device *sdev, int epnum, int dir)
406{
407 struct usb_device *udev = interface_to_usbdev(sdev->interface);
408 struct usb_host_endpoint *ep;
409 struct usb_endpoint_descriptor *epd = NULL;
410
411 ep = get_ep_from_epnum(udev, epnum);
412 if (!ep) {
413 dev_err(&sdev->interface->dev, "no such endpoint?, %d\n",
414 epnum);
415 BUG();
416 }
417
418 epd = &ep->desc;
419
420
421#if 0
422 /* epnum 0 is always control */
423 if (epnum == 0) {
424 if (dir == USBIP_DIR_OUT)
425 return usb_sndctrlpipe(udev, 0);
426 else
427 return usb_rcvctrlpipe(udev, 0);
428 }
429#endif
430
431 if (usb_endpoint_xfer_control(epd)) {
432 if (dir == USBIP_DIR_OUT)
433 return usb_sndctrlpipe(udev, epnum);
434 else
435 return usb_rcvctrlpipe(udev, epnum);
436 }
437
438 if (usb_endpoint_xfer_bulk(epd)) {
439 if (dir == USBIP_DIR_OUT)
440 return usb_sndbulkpipe(udev, epnum);
441 else
442 return usb_rcvbulkpipe(udev, epnum);
443 }
444
445 if (usb_endpoint_xfer_int(epd)) {
446 if (dir == USBIP_DIR_OUT)
447 return usb_sndintpipe(udev, epnum);
448 else
449 return usb_rcvintpipe(udev, epnum);
450 }
451
452 if (usb_endpoint_xfer_isoc(epd)) {
453 if (dir == USBIP_DIR_OUT)
454 return usb_sndisocpipe(udev, epnum);
455 else
456 return usb_rcvisocpipe(udev, epnum);
457 }
458
459 /* NOT REACHED */
460 dev_err(&sdev->interface->dev, "get pipe, epnum %d\n", epnum);
461 return 0;
462}
463
464static void stub_recv_cmd_submit(struct stub_device *sdev,
465 struct usbip_header *pdu)
466{
467 int ret;
468 struct stub_priv *priv;
469 struct usbip_device *ud = &sdev->ud;
470 struct usb_device *udev = interface_to_usbdev(sdev->interface);
471 int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction);
472
473
474 priv = stub_priv_alloc(sdev, pdu);
475 if (!priv)
476 return;
477
478 /* setup a urb */
479 if (usb_pipeisoc(pipe))
480 priv->urb = usb_alloc_urb(pdu->u.cmd_submit.number_of_packets,
481 GFP_KERNEL);
482 else
483 priv->urb = usb_alloc_urb(0, GFP_KERNEL);
484
485 if (!priv->urb) {
486 dev_err(&sdev->interface->dev, "malloc urb\n");
487 usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
488 return;
489 }
490
491 /* set priv->urb->transfer_buffer */
492 if (pdu->u.cmd_submit.transfer_buffer_length > 0) {
493 priv->urb->transfer_buffer =
494 kzalloc(pdu->u.cmd_submit.transfer_buffer_length,
495 GFP_KERNEL);
496 if (!priv->urb->transfer_buffer) {
497 dev_err(&sdev->interface->dev, "malloc x_buff\n");
498 usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
499 return;
500 }
501 }
502
503 /* set priv->urb->setup_packet */
504 priv->urb->setup_packet = kzalloc(8, GFP_KERNEL);
505 if (!priv->urb->setup_packet) {
506 dev_err(&sdev->interface->dev, "allocate setup_packet\n");
507 usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
508 return;
509 }
510 memcpy(priv->urb->setup_packet, &pdu->u.cmd_submit.setup, 8);
511
512 /* set other members from the base header of pdu */
513 priv->urb->context = (void *) priv;
514 priv->urb->dev = udev;
515 priv->urb->pipe = pipe;
516 priv->urb->complete = stub_complete;
517
518 usbip_pack_pdu(pdu, priv->urb, USBIP_CMD_SUBMIT, 0);
519
520
521 if (usbip_recv_xbuff(ud, priv->urb) < 0)
522 return;
523
524 if (usbip_recv_iso(ud, priv->urb) < 0)
525 return;
526
527 /* no need to submit an intercepted request, but harmless? */
528 tweak_special_requests(priv->urb);
529
530 /* urb is now ready to submit */
531 ret = usb_submit_urb(priv->urb, GFP_KERNEL);
532
533 if (ret == 0)
534 dbg_stub_rx("submit urb ok, seqnum %u\n", pdu->base.seqnum);
535 else {
536 dev_err(&sdev->interface->dev, "submit_urb error, %d\n", ret);
537 usbip_dump_header(pdu);
538 usbip_dump_urb(priv->urb);
539
540 /*
541 * Pessimistic.
542 * This connection will be discarded.
543 */
544 usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT);
545 }
546
547 dbg_stub_rx("Leave\n");
548 return;
549}
550
551/* recv a pdu */
552static void stub_rx_pdu(struct usbip_device *ud)
553{
554 int ret;
555 struct usbip_header pdu;
556 struct stub_device *sdev = container_of(ud, struct stub_device, ud);
557 struct device *dev = &sdev->interface->dev;
558
559 dbg_stub_rx("Enter\n");
560
561 memset(&pdu, 0, sizeof(pdu));
562
563 /* 1. receive a pdu header */
564 ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu), 0);
565 if (ret != sizeof(pdu)) {
566 dev_err(dev, "recv a header, %d\n", ret);
567 usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
568 return;
569 }
570
571 usbip_header_correct_endian(&pdu, 0);
572
573 if (dbg_flag_stub_rx)
574 usbip_dump_header(&pdu);
575
576 if (!valid_request(sdev, &pdu)) {
577 dev_err(dev, "recv invalid request\n");
578 usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
579 return;
580 }
581
582 switch (pdu.base.command) {
583 case USBIP_CMD_UNLINK:
584 stub_recv_cmd_unlink(sdev, &pdu);
585 break;
586
587 case USBIP_CMD_SUBMIT:
588 stub_recv_cmd_submit(sdev, &pdu);
589 break;
590
591 default:
592 /* NOTREACHED */
593 dev_err(dev, "unknown pdu\n");
594 usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
595 return;
596 }
597
598}
599
600void stub_rx_loop(struct usbip_task *ut)
601{
602 struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
603
604 while (1) {
605 if (signal_pending(current)) {
606 dbg_stub_rx("signal caught!\n");
607 break;
608 }
609
610 if (usbip_event_happend(ud))
611 break;
612
613 stub_rx_pdu(ud);
614 }
615}
diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c
new file mode 100644
index 000000000000..d5563cd980be
--- /dev/null
+++ b/drivers/staging/usbip/stub_tx.c
@@ -0,0 +1,371 @@
1/*
2 * Copyright (C) 2003-2008 Takahiro Hirofuchi
3 *
4 * This is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17 * USA.
18 */
19
20#include "usbip_common.h"
21#include "stub.h"
22
23
24static void stub_free_priv_and_urb(struct stub_priv *priv)
25{
26 struct urb *urb = priv->urb;
27
28 kfree(urb->setup_packet);
29 kfree(urb->transfer_buffer);
30 list_del(&priv->list);
31 kmem_cache_free(stub_priv_cache, priv);
32 usb_free_urb(urb);
33}
34
35/* be in spin_lock_irqsave(&sdev->priv_lock, flags) */
36void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum,
37 __u32 status)
38{
39 struct stub_unlink *unlink;
40
41 unlink = kzalloc(sizeof(struct stub_unlink), GFP_ATOMIC);
42 if (!unlink) {
43 dev_err(&sdev->interface->dev, "alloc stub_unlink\n");
44 usbip_event_add(&sdev->ud, VDEV_EVENT_ERROR_MALLOC);
45 return;
46 }
47
48 unlink->seqnum = seqnum;
49 unlink->status = status;
50
51 list_add_tail(&unlink->list, &sdev->unlink_tx);
52}
53
54/**
55 * stub_complete - completion handler of a usbip urb
56 * @urb: pointer to the urb completed
57 * @regs:
58 *
59 * When a urb has completed, the USB core driver calls this function mostly in
60 * the interrupt context. To return the result of a urb, the completed urb is
61 * linked to the pending list of returning.
62 *
63 */
64void stub_complete(struct urb *urb)
65{
66 struct stub_priv *priv = (struct stub_priv *) urb->context;
67 struct stub_device *sdev = priv->sdev;
68 unsigned long flags;
69
70 dbg_stub_tx("complete! status %d\n", urb->status);
71
72
73 switch (urb->status) {
74 case 0:
75 /* OK */
76 break;
77 case -ENOENT:
78 uinfo("stopped by a call of usb_kill_urb() because of"
79 "cleaning up a virtual connection\n");
80 return;
81 case -ECONNRESET:
82 uinfo("unlinked by a call of usb_unlink_urb()\n");
83 break;
84 case -EPIPE:
85 uinfo("endpoint %d is stalled\n", usb_pipeendpoint(urb->pipe));
86 break;
87 case -ESHUTDOWN:
88 uinfo("device removed?\n");
89 break;
90 default:
91 uinfo("urb completion with non-zero status %d\n", urb->status);
92 }
93
94 /* link a urb to the queue of tx. */
95 spin_lock_irqsave(&sdev->priv_lock, flags);
96
97 if (priv->unlinking) {
98 stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status);
99 stub_free_priv_and_urb(priv);
100 } else
101 list_move_tail(&priv->list, &sdev->priv_tx);
102
103
104 spin_unlock_irqrestore(&sdev->priv_lock, flags);
105
106 /* wake up tx_thread */
107 wake_up(&sdev->tx_waitq);
108}
109
110
111/*-------------------------------------------------------------------------*/
112/* fill PDU */
113
114static inline void setup_base_pdu(struct usbip_header_basic *base,
115 __u32 command, __u32 seqnum)
116{
117 base->command = command;
118 base->seqnum = seqnum;
119 base->devid = 0;
120 base->ep = 0;
121 base->direction = 0;
122}
123
124static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urb *urb)
125{
126 struct stub_priv *priv = (struct stub_priv *) urb->context;
127
128 setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, priv->seqnum);
129
130 usbip_pack_pdu(rpdu, urb, USBIP_RET_SUBMIT, 1);
131}
132
133static void setup_ret_unlink_pdu(struct usbip_header *rpdu,
134 struct stub_unlink *unlink)
135{
136 setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum);
137
138 rpdu->u.ret_unlink.status = unlink->status;
139}
140
141
142/*-------------------------------------------------------------------------*/
143/* send RET_SUBMIT */
144
145static struct stub_priv *dequeue_from_priv_tx(struct stub_device *sdev)
146{
147 unsigned long flags;
148 struct stub_priv *priv, *tmp;
149
150 spin_lock_irqsave(&sdev->priv_lock, flags);
151
152 list_for_each_entry_safe(priv, tmp, &sdev->priv_tx, list) {
153 list_move_tail(&priv->list, &sdev->priv_free);
154 spin_unlock_irqrestore(&sdev->priv_lock, flags);
155 return priv;
156 }
157
158 spin_unlock_irqrestore(&sdev->priv_lock, flags);
159
160 return NULL;
161}
162
163static int stub_send_ret_submit(struct stub_device *sdev)
164{
165 unsigned long flags;
166 struct stub_priv *priv, *tmp;
167
168 struct msghdr msg;
169 struct kvec iov[3];
170 size_t txsize;
171
172 size_t total_size = 0;
173
174 while ((priv = dequeue_from_priv_tx(sdev)) != NULL) {
175 int ret;
176 struct urb *urb = priv->urb;
177 struct usbip_header pdu_header;
178 void *iso_buffer = NULL;
179
180 txsize = 0;
181 memset(&pdu_header, 0, sizeof(pdu_header));
182 memset(&msg, 0, sizeof(msg));
183 memset(&iov, 0, sizeof(iov));
184
185 dbg_stub_tx("setup txdata urb %p\n", urb);
186
187
188 /* 1. setup usbip_header */
189 setup_ret_submit_pdu(&pdu_header, urb);
190 usbip_header_correct_endian(&pdu_header, 1);
191
192 iov[0].iov_base = &pdu_header;
193 iov[0].iov_len = sizeof(pdu_header);
194 txsize += sizeof(pdu_header);
195
196 /* 2. setup transfer buffer */
197 if (usb_pipein(urb->pipe) && urb->actual_length > 0) {
198 iov[1].iov_base = urb->transfer_buffer;
199 iov[1].iov_len = urb->actual_length;
200 txsize += urb->actual_length;
201 }
202
203 /* 3. setup iso_packet_descriptor */
204 if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
205 ssize_t len = 0;
206
207 iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
208 if (!iso_buffer) {
209 usbip_event_add(&sdev->ud,
210 SDEV_EVENT_ERROR_MALLOC);
211 return -1;
212 }
213
214 iov[2].iov_base = iso_buffer;
215 iov[2].iov_len = len;
216 txsize += len;
217 }
218
219 ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov,
220 3, txsize);
221 if (ret != txsize) {
222 dev_err(&sdev->interface->dev,
223 "sendmsg failed!, retval %d for %zd\n",
224 ret, txsize);
225 kfree(iso_buffer);
226 usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
227 return -1;
228 }
229
230 kfree(iso_buffer);
231 dbg_stub_tx("send txdata\n");
232
233 total_size += txsize;
234 }
235
236
237 spin_lock_irqsave(&sdev->priv_lock, flags);
238
239 list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) {
240 stub_free_priv_and_urb(priv);
241 }
242
243 spin_unlock_irqrestore(&sdev->priv_lock, flags);
244
245 return total_size;
246}
247
248
249/*-------------------------------------------------------------------------*/
250/* send RET_UNLINK */
251
252static struct stub_unlink *dequeue_from_unlink_tx(struct stub_device *sdev)
253{
254 unsigned long flags;
255 struct stub_unlink *unlink, *tmp;
256
257 spin_lock_irqsave(&sdev->priv_lock, flags);
258
259 list_for_each_entry_safe(unlink, tmp, &sdev->unlink_tx, list) {
260 list_move_tail(&unlink->list, &sdev->unlink_free);
261 spin_unlock_irqrestore(&sdev->priv_lock, flags);
262 return unlink;
263 }
264
265 spin_unlock_irqrestore(&sdev->priv_lock, flags);
266
267 return NULL;
268}
269
270
271static int stub_send_ret_unlink(struct stub_device *sdev)
272{
273 unsigned long flags;
274 struct stub_unlink *unlink, *tmp;
275
276 struct msghdr msg;
277 struct kvec iov[1];
278 size_t txsize;
279
280 size_t total_size = 0;
281
282 while ((unlink = dequeue_from_unlink_tx(sdev)) != NULL) {
283 int ret;
284 struct usbip_header pdu_header;
285
286 txsize = 0;
287 memset(&pdu_header, 0, sizeof(pdu_header));
288 memset(&msg, 0, sizeof(msg));
289 memset(&iov, 0, sizeof(iov));
290
291 dbg_stub_tx("setup ret unlink %lu\n", unlink->seqnum);
292
293 /* 1. setup usbip_header */
294 setup_ret_unlink_pdu(&pdu_header, unlink);
295 usbip_header_correct_endian(&pdu_header, 1);
296
297 iov[0].iov_base = &pdu_header;
298 iov[0].iov_len = sizeof(pdu_header);
299 txsize += sizeof(pdu_header);
300
301 ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov,
302 1, txsize);
303 if (ret != txsize) {
304 dev_err(&sdev->interface->dev,
305 "sendmsg failed!, retval %d for %zd\n",
306 ret, txsize);
307 usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
308 return -1;
309 }
310
311
312 dbg_stub_tx("send txdata\n");
313
314 total_size += txsize;
315 }
316
317
318 spin_lock_irqsave(&sdev->priv_lock, flags);
319
320 list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, list) {
321 list_del(&unlink->list);
322 kfree(unlink);
323 }
324
325 spin_unlock_irqrestore(&sdev->priv_lock, flags);
326
327 return total_size;
328}
329
330
331/*-------------------------------------------------------------------------*/
332
333void stub_tx_loop(struct usbip_task *ut)
334{
335 struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
336 struct stub_device *sdev = container_of(ud, struct stub_device, ud);
337
338 while (1) {
339 if (signal_pending(current)) {
340 dbg_stub_tx("signal catched\n");
341 break;
342 }
343
344 if (usbip_event_happend(ud))
345 break;
346
347 /*
348 * send_ret_submit comes earlier than send_ret_unlink. stub_rx
349 * looks at only priv_init queue. If the completion of a URB is
350 * earlier than the receive of CMD_UNLINK, priv is moved to
351 * priv_tx queue and stub_rx does not find the target priv. In
352 * this case, vhci_rx receives the result of the submit request
353 * and then receives the result of the unlink request. The
354 * result of the submit is given back to the usbcore as the
355 * completion of the unlink request. The request of the
356 * unlink is ignored. This is ok because a driver who calls
357 * usb_unlink_urb() understands the unlink was too late by
358 * getting the status of the given-backed URB which has the
359 * status of usb_submit_urb().
360 */
361 if (stub_send_ret_submit(sdev) < 0)
362 break;
363
364 if (stub_send_ret_unlink(sdev) < 0)
365 break;
366
367 wait_event_interruptible(sdev->tx_waitq,
368 (!list_empty(&sdev->priv_tx) ||
369 !list_empty(&sdev->unlink_tx)));
370 }
371}