diff options
author | Valentina Manea <valentina.manea.m@gmail.com> | 2014-08-20 00:31:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-08-25 13:40:06 -0400 |
commit | 96c2737716d586a218bc795fcb79d2e2b6003081 (patch) | |
tree | d2cad517eece7a5ee6255e028f3263c2e0b1e23c /drivers/staging | |
parent | 588b48caf65c4a92af567948ec0025065e749ddf (diff) |
usbip: move usbip kernel code out of staging
At this point, USB/IP kernel code is fully functional
and can be moved out of staging.
Signed-off-by: Valentina Manea <valentina.manea.m@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/Kconfig | 2 | ||||
-rw-r--r-- | drivers/staging/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/usbip/Kconfig | 41 | ||||
-rw-r--r-- | drivers/staging/usbip/Makefile | 10 | ||||
-rw-r--r-- | drivers/staging/usbip/README | 7 | ||||
-rw-r--r-- | drivers/staging/usbip/stub.h | 113 | ||||
-rw-r--r-- | drivers/staging/usbip/stub_dev.c | 525 | ||||
-rw-r--r-- | drivers/staging/usbip/stub_main.c | 335 | ||||
-rw-r--r-- | drivers/staging/usbip/stub_rx.c | 594 | ||||
-rw-r--r-- | drivers/staging/usbip/stub_tx.c | 398 | ||||
-rw-r--r-- | drivers/staging/usbip/uapi/usbip.h | 26 | ||||
-rw-r--r-- | drivers/staging/usbip/usbip_common.c | 776 | ||||
-rw-r--r-- | drivers/staging/usbip/usbip_common.h | 335 | ||||
-rw-r--r-- | drivers/staging/usbip/usbip_event.c | 128 | ||||
-rw-r--r-- | drivers/staging/usbip/usbip_protocol.txt | 358 | ||||
-rw-r--r-- | drivers/staging/usbip/vhci.h | 129 | ||||
-rw-r--r-- | drivers/staging/usbip/vhci_hcd.c | 1171 | ||||
-rw-r--r-- | drivers/staging/usbip/vhci_rx.c | 268 | ||||
-rw-r--r-- | drivers/staging/usbip/vhci_sysfs.c | 252 | ||||
-rw-r--r-- | drivers/staging/usbip/vhci_tx.c | 224 |
20 files changed, 0 insertions, 5693 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 2c486ea6236b..35b494f5667f 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -28,8 +28,6 @@ source "drivers/staging/et131x/Kconfig" | |||
28 | 28 | ||
29 | source "drivers/staging/slicoss/Kconfig" | 29 | source "drivers/staging/slicoss/Kconfig" |
30 | 30 | ||
31 | source "drivers/staging/usbip/Kconfig" | ||
32 | |||
33 | source "drivers/staging/wlan-ng/Kconfig" | 31 | source "drivers/staging/wlan-ng/Kconfig" |
34 | 32 | ||
35 | source "drivers/staging/comedi/Kconfig" | 33 | source "drivers/staging/comedi/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 1e1a3a10faf7..e66a5dbd9b02 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -6,7 +6,6 @@ obj-$(CONFIG_STAGING) += staging.o | |||
6 | obj-y += media/ | 6 | obj-y += media/ |
7 | obj-$(CONFIG_ET131X) += et131x/ | 7 | obj-$(CONFIG_ET131X) += et131x/ |
8 | obj-$(CONFIG_SLICOSS) += slicoss/ | 8 | obj-$(CONFIG_SLICOSS) += slicoss/ |
9 | obj-$(CONFIG_USBIP_CORE) += usbip/ | ||
10 | obj-$(CONFIG_PRISM2_USB) += wlan-ng/ | 9 | obj-$(CONFIG_PRISM2_USB) += wlan-ng/ |
11 | obj-$(CONFIG_COMEDI) += comedi/ | 10 | obj-$(CONFIG_COMEDI) += comedi/ |
12 | obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ | 11 | obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ |
diff --git a/drivers/staging/usbip/Kconfig b/drivers/staging/usbip/Kconfig deleted file mode 100644 index bd99e9e47e50..000000000000 --- a/drivers/staging/usbip/Kconfig +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | config USBIP_CORE | ||
2 | tristate "USB/IP support" | ||
3 | depends on USB && NET | ||
4 | ---help--- | ||
5 | This enables pushing USB packets over IP to allow remote | ||
6 | machines direct access to USB devices. It provides the | ||
7 | USB/IP core that is required by both drivers. | ||
8 | |||
9 | For more details, and to get the userspace utility | ||
10 | programs, please see <http://usbip.sourceforge.net/>. | ||
11 | |||
12 | To compile this as a module, choose M here: the module will | ||
13 | be called usbip-core. | ||
14 | |||
15 | If unsure, say N. | ||
16 | |||
17 | config USBIP_VHCI_HCD | ||
18 | tristate "VHCI hcd" | ||
19 | depends on USBIP_CORE | ||
20 | ---help--- | ||
21 | This enables the USB/IP virtual host controller driver, | ||
22 | which is run on the remote machine. | ||
23 | |||
24 | To compile this driver as a module, choose M here: the | ||
25 | module will be called vhci-hcd. | ||
26 | |||
27 | config USBIP_HOST | ||
28 | tristate "Host driver" | ||
29 | depends on USBIP_CORE | ||
30 | ---help--- | ||
31 | This enables the USB/IP host driver, which is run on the | ||
32 | machine that is sharing the USB devices. | ||
33 | |||
34 | To compile this driver as a module, choose M here: the | ||
35 | module will be called usbip-host. | ||
36 | |||
37 | config USBIP_DEBUG | ||
38 | bool "Debug messages for USB/IP" | ||
39 | depends on USBIP_CORE | ||
40 | ---help--- | ||
41 | This enables the debug messages from the USB/IP drivers. | ||
diff --git a/drivers/staging/usbip/Makefile b/drivers/staging/usbip/Makefile deleted file mode 100644 index 9ecd61545be1..000000000000 --- a/drivers/staging/usbip/Makefile +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | ccflags-$(CONFIG_USBIP_DEBUG) := -DDEBUG | ||
2 | |||
3 | obj-$(CONFIG_USBIP_CORE) += usbip-core.o | ||
4 | usbip-core-y := usbip_common.o usbip_event.o | ||
5 | |||
6 | obj-$(CONFIG_USBIP_VHCI_HCD) += vhci-hcd.o | ||
7 | vhci-hcd-y := vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o | ||
8 | |||
9 | obj-$(CONFIG_USBIP_HOST) += usbip-host.o | ||
10 | usbip-host-y := stub_dev.o stub_main.o stub_rx.o stub_tx.o | ||
diff --git a/drivers/staging/usbip/README b/drivers/staging/usbip/README deleted file mode 100644 index 41a2cf2e77a6..000000000000 --- a/drivers/staging/usbip/README +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | TODO: | ||
2 | - more discussion about the protocol | ||
3 | - testing | ||
4 | - review of the userspace interface | ||
5 | - document the protocol | ||
6 | |||
7 | Please send patches for this code to Greg Kroah-Hartman <greg@kroah.com> | ||
diff --git a/drivers/staging/usbip/stub.h b/drivers/staging/usbip/stub.h deleted file mode 100644 index 266e2b0ce9a8..000000000000 --- a/drivers/staging/usbip/stub.h +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
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 | #ifndef __USBIP_STUB_H | ||
21 | #define __USBIP_STUB_H | ||
22 | |||
23 | #include <linux/list.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/spinlock.h> | ||
26 | #include <linux/types.h> | ||
27 | #include <linux/usb.h> | ||
28 | #include <linux/wait.h> | ||
29 | |||
30 | #define STUB_BUSID_OTHER 0 | ||
31 | #define STUB_BUSID_REMOV 1 | ||
32 | #define STUB_BUSID_ADDED 2 | ||
33 | #define STUB_BUSID_ALLOC 3 | ||
34 | |||
35 | struct stub_device { | ||
36 | struct usb_interface *interface; | ||
37 | struct usb_device *udev; | ||
38 | |||
39 | struct usbip_device ud; | ||
40 | __u32 devid; | ||
41 | |||
42 | /* | ||
43 | * stub_priv preserves private data of each urb. | ||
44 | * It is allocated as stub_priv_cache and assigned to urb->context. | ||
45 | * | ||
46 | * stub_priv is always linked to any one of 3 lists; | ||
47 | * priv_init: linked to this until the comletion of a urb. | ||
48 | * priv_tx : linked to this after the completion of a urb. | ||
49 | * priv_free: linked to this after the sending of the result. | ||
50 | * | ||
51 | * Any of these list operations should be locked by priv_lock. | ||
52 | */ | ||
53 | spinlock_t priv_lock; | ||
54 | struct list_head priv_init; | ||
55 | struct list_head priv_tx; | ||
56 | struct list_head priv_free; | ||
57 | |||
58 | /* see comments for unlinking in stub_rx.c */ | ||
59 | struct list_head unlink_tx; | ||
60 | struct list_head unlink_free; | ||
61 | |||
62 | wait_queue_head_t tx_waitq; | ||
63 | }; | ||
64 | |||
65 | /* private data into urb->priv */ | ||
66 | struct stub_priv { | ||
67 | unsigned long seqnum; | ||
68 | struct list_head list; | ||
69 | struct stub_device *sdev; | ||
70 | struct urb *urb; | ||
71 | |||
72 | int unlinking; | ||
73 | }; | ||
74 | |||
75 | struct stub_unlink { | ||
76 | unsigned long seqnum; | ||
77 | struct list_head list; | ||
78 | __u32 status; | ||
79 | }; | ||
80 | |||
81 | /* same as SYSFS_BUS_ID_SIZE */ | ||
82 | #define BUSID_SIZE 32 | ||
83 | |||
84 | struct bus_id_priv { | ||
85 | char name[BUSID_SIZE]; | ||
86 | char status; | ||
87 | int interf_count; | ||
88 | struct stub_device *sdev; | ||
89 | struct usb_device *udev; | ||
90 | char shutdown_busid; | ||
91 | }; | ||
92 | |||
93 | /* stub_priv is allocated from stub_priv_cache */ | ||
94 | extern struct kmem_cache *stub_priv_cache; | ||
95 | |||
96 | /* stub_dev.c */ | ||
97 | extern struct usb_device_driver stub_driver; | ||
98 | |||
99 | /* stub_main.c */ | ||
100 | struct bus_id_priv *get_busid_priv(const char *busid); | ||
101 | int del_match_busid(char *busid); | ||
102 | void stub_device_cleanup_urbs(struct stub_device *sdev); | ||
103 | |||
104 | /* stub_rx.c */ | ||
105 | int stub_rx_loop(void *data); | ||
106 | |||
107 | /* stub_tx.c */ | ||
108 | void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum, | ||
109 | __u32 status); | ||
110 | void stub_complete(struct urb *urb); | ||
111 | int stub_tx_loop(void *data); | ||
112 | |||
113 | #endif /* __USBIP_STUB_H */ | ||
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c deleted file mode 100644 index 51d0c7188738..000000000000 --- a/drivers/staging/usbip/stub_dev.c +++ /dev/null | |||
@@ -1,525 +0,0 @@ | |||
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/device.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/kthread.h> | ||
23 | #include <linux/module.h> | ||
24 | |||
25 | #include "usbip_common.h" | ||
26 | #include "stub.h" | ||
27 | |||
28 | /* | ||
29 | * Define device IDs here if you want to explicitly limit exportable devices. | ||
30 | * In most cases, wildcard matching will be okay because driver binding can be | ||
31 | * changed dynamically by a userland program. | ||
32 | */ | ||
33 | static struct usb_device_id stub_table[] = { | ||
34 | #if 0 | ||
35 | /* just an example */ | ||
36 | { USB_DEVICE(0x05ac, 0x0301) }, /* Mac 1 button mouse */ | ||
37 | { USB_DEVICE(0x0430, 0x0009) }, /* Plat Home Keyboard */ | ||
38 | { USB_DEVICE(0x059b, 0x0001) }, /* Iomega USB Zip 100 */ | ||
39 | { USB_DEVICE(0x04b3, 0x4427) }, /* IBM USB CD-ROM */ | ||
40 | { USB_DEVICE(0x05a9, 0xa511) }, /* LifeView USB cam */ | ||
41 | { USB_DEVICE(0x55aa, 0x0201) }, /* Imation card reader */ | ||
42 | { USB_DEVICE(0x046d, 0x0870) }, /* Qcam Express(QV-30) */ | ||
43 | { USB_DEVICE(0x04bb, 0x0101) }, /* IO-DATA HD 120GB */ | ||
44 | { USB_DEVICE(0x04bb, 0x0904) }, /* IO-DATA USB-ET/TX */ | ||
45 | { USB_DEVICE(0x04bb, 0x0201) }, /* IO-DATA USB-ET/TX */ | ||
46 | { USB_DEVICE(0x08bb, 0x2702) }, /* ONKYO USB Speaker */ | ||
47 | { USB_DEVICE(0x046d, 0x08b2) }, /* Logicool Qcam 4000 Pro */ | ||
48 | #endif | ||
49 | /* magic for wild card */ | ||
50 | { .driver_info = 1 }, | ||
51 | { 0, } /* Terminating entry */ | ||
52 | }; | ||
53 | MODULE_DEVICE_TABLE(usb, stub_table); | ||
54 | |||
55 | /* | ||
56 | * usbip_status shows the status of usbip-host as long as this driver is bound | ||
57 | * to the target device. | ||
58 | */ | ||
59 | static ssize_t usbip_status_show(struct device *dev, | ||
60 | struct device_attribute *attr, char *buf) | ||
61 | { | ||
62 | struct stub_device *sdev = dev_get_drvdata(dev); | ||
63 | int status; | ||
64 | |||
65 | if (!sdev) { | ||
66 | dev_err(dev, "sdev is null\n"); | ||
67 | return -ENODEV; | ||
68 | } | ||
69 | |||
70 | spin_lock_irq(&sdev->ud.lock); | ||
71 | status = sdev->ud.status; | ||
72 | spin_unlock_irq(&sdev->ud.lock); | ||
73 | |||
74 | return snprintf(buf, PAGE_SIZE, "%d\n", status); | ||
75 | } | ||
76 | static DEVICE_ATTR_RO(usbip_status); | ||
77 | |||
78 | /* | ||
79 | * usbip_sockfd gets a socket descriptor of an established TCP connection that | ||
80 | * is used to transfer usbip requests by kernel threads. -1 is a magic number | ||
81 | * by which usbip connection is finished. | ||
82 | */ | ||
83 | static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr, | ||
84 | const char *buf, size_t count) | ||
85 | { | ||
86 | struct stub_device *sdev = dev_get_drvdata(dev); | ||
87 | int sockfd = 0; | ||
88 | struct socket *socket; | ||
89 | int rv; | ||
90 | |||
91 | if (!sdev) { | ||
92 | dev_err(dev, "sdev is null\n"); | ||
93 | return -ENODEV; | ||
94 | } | ||
95 | |||
96 | rv = sscanf(buf, "%d", &sockfd); | ||
97 | if (rv != 1) | ||
98 | return -EINVAL; | ||
99 | |||
100 | if (sockfd != -1) { | ||
101 | int err; | ||
102 | |||
103 | dev_info(dev, "stub up\n"); | ||
104 | |||
105 | spin_lock_irq(&sdev->ud.lock); | ||
106 | |||
107 | if (sdev->ud.status != SDEV_ST_AVAILABLE) { | ||
108 | dev_err(dev, "not ready\n"); | ||
109 | goto err; | ||
110 | } | ||
111 | |||
112 | socket = sockfd_lookup(sockfd, &err); | ||
113 | if (!socket) | ||
114 | goto err; | ||
115 | |||
116 | sdev->ud.tcp_socket = socket; | ||
117 | |||
118 | spin_unlock_irq(&sdev->ud.lock); | ||
119 | |||
120 | sdev->ud.tcp_rx = kthread_get_run(stub_rx_loop, &sdev->ud, | ||
121 | "stub_rx"); | ||
122 | sdev->ud.tcp_tx = kthread_get_run(stub_tx_loop, &sdev->ud, | ||
123 | "stub_tx"); | ||
124 | |||
125 | spin_lock_irq(&sdev->ud.lock); | ||
126 | sdev->ud.status = SDEV_ST_USED; | ||
127 | spin_unlock_irq(&sdev->ud.lock); | ||
128 | |||
129 | } else { | ||
130 | dev_info(dev, "stub down\n"); | ||
131 | |||
132 | spin_lock_irq(&sdev->ud.lock); | ||
133 | if (sdev->ud.status != SDEV_ST_USED) | ||
134 | goto err; | ||
135 | |||
136 | spin_unlock_irq(&sdev->ud.lock); | ||
137 | |||
138 | usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN); | ||
139 | } | ||
140 | |||
141 | return count; | ||
142 | |||
143 | err: | ||
144 | spin_unlock_irq(&sdev->ud.lock); | ||
145 | return -EINVAL; | ||
146 | } | ||
147 | static DEVICE_ATTR(usbip_sockfd, S_IWUSR, NULL, store_sockfd); | ||
148 | |||
149 | static int stub_add_files(struct device *dev) | ||
150 | { | ||
151 | int err = 0; | ||
152 | |||
153 | err = device_create_file(dev, &dev_attr_usbip_status); | ||
154 | if (err) | ||
155 | goto err_status; | ||
156 | |||
157 | err = device_create_file(dev, &dev_attr_usbip_sockfd); | ||
158 | if (err) | ||
159 | goto err_sockfd; | ||
160 | |||
161 | err = device_create_file(dev, &dev_attr_usbip_debug); | ||
162 | if (err) | ||
163 | goto err_debug; | ||
164 | |||
165 | return 0; | ||
166 | |||
167 | err_debug: | ||
168 | device_remove_file(dev, &dev_attr_usbip_sockfd); | ||
169 | err_sockfd: | ||
170 | device_remove_file(dev, &dev_attr_usbip_status); | ||
171 | err_status: | ||
172 | return err; | ||
173 | } | ||
174 | |||
175 | static void stub_remove_files(struct device *dev) | ||
176 | { | ||
177 | device_remove_file(dev, &dev_attr_usbip_status); | ||
178 | device_remove_file(dev, &dev_attr_usbip_sockfd); | ||
179 | device_remove_file(dev, &dev_attr_usbip_debug); | ||
180 | } | ||
181 | |||
182 | static void stub_shutdown_connection(struct usbip_device *ud) | ||
183 | { | ||
184 | struct stub_device *sdev = container_of(ud, struct stub_device, ud); | ||
185 | |||
186 | /* | ||
187 | * When removing an exported device, kernel panic sometimes occurred | ||
188 | * and then EIP was sk_wait_data of stub_rx thread. Is this because | ||
189 | * sk_wait_data returned though stub_rx thread was already finished by | ||
190 | * step 1? | ||
191 | */ | ||
192 | if (ud->tcp_socket) { | ||
193 | dev_dbg(&sdev->udev->dev, "shutdown tcp_socket %p\n", | ||
194 | ud->tcp_socket); | ||
195 | kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); | ||
196 | } | ||
197 | |||
198 | /* 1. stop threads */ | ||
199 | if (ud->tcp_rx) { | ||
200 | kthread_stop_put(ud->tcp_rx); | ||
201 | ud->tcp_rx = NULL; | ||
202 | } | ||
203 | if (ud->tcp_tx) { | ||
204 | kthread_stop_put(ud->tcp_tx); | ||
205 | ud->tcp_tx = NULL; | ||
206 | } | ||
207 | |||
208 | /* | ||
209 | * 2. close the socket | ||
210 | * | ||
211 | * tcp_socket is freed after threads are killed so that usbip_xmit does | ||
212 | * not touch NULL socket. | ||
213 | */ | ||
214 | if (ud->tcp_socket) { | ||
215 | sockfd_put(ud->tcp_socket); | ||
216 | ud->tcp_socket = NULL; | ||
217 | } | ||
218 | |||
219 | /* 3. free used data */ | ||
220 | stub_device_cleanup_urbs(sdev); | ||
221 | |||
222 | /* 4. free stub_unlink */ | ||
223 | { | ||
224 | unsigned long flags; | ||
225 | struct stub_unlink *unlink, *tmp; | ||
226 | |||
227 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
228 | list_for_each_entry_safe(unlink, tmp, &sdev->unlink_tx, list) { | ||
229 | list_del(&unlink->list); | ||
230 | kfree(unlink); | ||
231 | } | ||
232 | list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, | ||
233 | list) { | ||
234 | list_del(&unlink->list); | ||
235 | kfree(unlink); | ||
236 | } | ||
237 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
238 | } | ||
239 | } | ||
240 | |||
241 | static void stub_device_reset(struct usbip_device *ud) | ||
242 | { | ||
243 | struct stub_device *sdev = container_of(ud, struct stub_device, ud); | ||
244 | struct usb_device *udev = sdev->udev; | ||
245 | int ret; | ||
246 | |||
247 | dev_dbg(&udev->dev, "device reset"); | ||
248 | |||
249 | ret = usb_lock_device_for_reset(udev, sdev->interface); | ||
250 | if (ret < 0) { | ||
251 | dev_err(&udev->dev, "lock for reset\n"); | ||
252 | spin_lock_irq(&ud->lock); | ||
253 | ud->status = SDEV_ST_ERROR; | ||
254 | spin_unlock_irq(&ud->lock); | ||
255 | return; | ||
256 | } | ||
257 | |||
258 | /* try to reset the device */ | ||
259 | ret = usb_reset_device(udev); | ||
260 | usb_unlock_device(udev); | ||
261 | |||
262 | spin_lock_irq(&ud->lock); | ||
263 | if (ret) { | ||
264 | dev_err(&udev->dev, "device reset\n"); | ||
265 | ud->status = SDEV_ST_ERROR; | ||
266 | } else { | ||
267 | dev_info(&udev->dev, "device reset\n"); | ||
268 | ud->status = SDEV_ST_AVAILABLE; | ||
269 | } | ||
270 | spin_unlock_irq(&ud->lock); | ||
271 | } | ||
272 | |||
273 | static void stub_device_unusable(struct usbip_device *ud) | ||
274 | { | ||
275 | spin_lock_irq(&ud->lock); | ||
276 | ud->status = SDEV_ST_ERROR; | ||
277 | spin_unlock_irq(&ud->lock); | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * stub_device_alloc - allocate a new stub_device struct | ||
282 | * @interface: usb_interface of a new device | ||
283 | * | ||
284 | * Allocates and initializes a new stub_device struct. | ||
285 | */ | ||
286 | static struct stub_device *stub_device_alloc(struct usb_device *udev) | ||
287 | { | ||
288 | struct stub_device *sdev; | ||
289 | int busnum = udev->bus->busnum; | ||
290 | int devnum = udev->devnum; | ||
291 | |||
292 | dev_dbg(&udev->dev, "allocating stub device"); | ||
293 | |||
294 | /* yes, it's a new device */ | ||
295 | sdev = kzalloc(sizeof(struct stub_device), GFP_KERNEL); | ||
296 | if (!sdev) | ||
297 | return NULL; | ||
298 | |||
299 | sdev->udev = usb_get_dev(udev); | ||
300 | |||
301 | /* | ||
302 | * devid is defined with devnum when this driver is first allocated. | ||
303 | * devnum may change later if a device is reset. However, devid never | ||
304 | * changes during a usbip connection. | ||
305 | */ | ||
306 | sdev->devid = (busnum << 16) | devnum; | ||
307 | sdev->ud.side = USBIP_STUB; | ||
308 | sdev->ud.status = SDEV_ST_AVAILABLE; | ||
309 | spin_lock_init(&sdev->ud.lock); | ||
310 | sdev->ud.tcp_socket = NULL; | ||
311 | |||
312 | INIT_LIST_HEAD(&sdev->priv_init); | ||
313 | INIT_LIST_HEAD(&sdev->priv_tx); | ||
314 | INIT_LIST_HEAD(&sdev->priv_free); | ||
315 | INIT_LIST_HEAD(&sdev->unlink_free); | ||
316 | INIT_LIST_HEAD(&sdev->unlink_tx); | ||
317 | spin_lock_init(&sdev->priv_lock); | ||
318 | |||
319 | init_waitqueue_head(&sdev->tx_waitq); | ||
320 | |||
321 | sdev->ud.eh_ops.shutdown = stub_shutdown_connection; | ||
322 | sdev->ud.eh_ops.reset = stub_device_reset; | ||
323 | sdev->ud.eh_ops.unusable = stub_device_unusable; | ||
324 | |||
325 | usbip_start_eh(&sdev->ud); | ||
326 | |||
327 | dev_dbg(&udev->dev, "register new device\n"); | ||
328 | |||
329 | return sdev; | ||
330 | } | ||
331 | |||
332 | static void stub_device_free(struct stub_device *sdev) | ||
333 | { | ||
334 | kfree(sdev); | ||
335 | } | ||
336 | |||
337 | static int stub_probe(struct usb_device *udev) | ||
338 | { | ||
339 | struct stub_device *sdev = NULL; | ||
340 | const char *udev_busid = dev_name(&udev->dev); | ||
341 | int err = 0; | ||
342 | struct bus_id_priv *busid_priv; | ||
343 | int rc; | ||
344 | |||
345 | dev_dbg(&udev->dev, "Enter\n"); | ||
346 | |||
347 | /* check we should claim or not by busid_table */ | ||
348 | busid_priv = get_busid_priv(udev_busid); | ||
349 | if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) || | ||
350 | (busid_priv->status == STUB_BUSID_OTHER)) { | ||
351 | dev_info(&udev->dev, | ||
352 | "%s is not in match_busid table... skip!\n", | ||
353 | udev_busid); | ||
354 | |||
355 | /* | ||
356 | * Return value should be ENODEV or ENOXIO to continue trying | ||
357 | * other matched drivers by the driver core. | ||
358 | * See driver_probe_device() in driver/base/dd.c | ||
359 | */ | ||
360 | return -ENODEV; | ||
361 | } | ||
362 | |||
363 | if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) { | ||
364 | dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n", | ||
365 | udev_busid); | ||
366 | return -ENODEV; | ||
367 | } | ||
368 | |||
369 | if (!strcmp(udev->bus->bus_name, "vhci_hcd")) { | ||
370 | dev_dbg(&udev->dev, | ||
371 | "%s is attached on vhci_hcd... skip!\n", | ||
372 | udev_busid); | ||
373 | |||
374 | return -ENODEV; | ||
375 | } | ||
376 | |||
377 | /* ok, this is my device */ | ||
378 | sdev = stub_device_alloc(udev); | ||
379 | if (!sdev) | ||
380 | return -ENOMEM; | ||
381 | |||
382 | dev_info(&udev->dev, | ||
383 | "usbip-host: register new device (bus %u dev %u)\n", | ||
384 | udev->bus->busnum, udev->devnum); | ||
385 | |||
386 | busid_priv->shutdown_busid = 0; | ||
387 | |||
388 | /* set private data to usb_device */ | ||
389 | dev_set_drvdata(&udev->dev, sdev); | ||
390 | busid_priv->sdev = sdev; | ||
391 | busid_priv->udev = udev; | ||
392 | |||
393 | /* | ||
394 | * Claim this hub port. | ||
395 | * It doesn't matter what value we pass as owner | ||
396 | * (struct dev_state) as long as it is unique. | ||
397 | */ | ||
398 | rc = usb_hub_claim_port(udev->parent, udev->portnum, | ||
399 | (struct usb_dev_state *) udev); | ||
400 | if (rc) { | ||
401 | dev_dbg(&udev->dev, "unable to claim port\n"); | ||
402 | return rc; | ||
403 | } | ||
404 | |||
405 | err = stub_add_files(&udev->dev); | ||
406 | if (err) { | ||
407 | dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid); | ||
408 | dev_set_drvdata(&udev->dev, NULL); | ||
409 | usb_put_dev(udev); | ||
410 | kthread_stop_put(sdev->ud.eh); | ||
411 | |||
412 | busid_priv->sdev = NULL; | ||
413 | stub_device_free(sdev); | ||
414 | return err; | ||
415 | } | ||
416 | busid_priv->status = STUB_BUSID_ALLOC; | ||
417 | |||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | static void shutdown_busid(struct bus_id_priv *busid_priv) | ||
422 | { | ||
423 | if (busid_priv->sdev && !busid_priv->shutdown_busid) { | ||
424 | busid_priv->shutdown_busid = 1; | ||
425 | usbip_event_add(&busid_priv->sdev->ud, SDEV_EVENT_REMOVED); | ||
426 | |||
427 | /* wait for the stop of the event handler */ | ||
428 | usbip_stop_eh(&busid_priv->sdev->ud); | ||
429 | } | ||
430 | } | ||
431 | |||
432 | /* | ||
433 | * called in usb_disconnect() or usb_deregister() | ||
434 | * but only if actconfig(active configuration) exists | ||
435 | */ | ||
436 | static void stub_disconnect(struct usb_device *udev) | ||
437 | { | ||
438 | struct stub_device *sdev; | ||
439 | const char *udev_busid = dev_name(&udev->dev); | ||
440 | struct bus_id_priv *busid_priv; | ||
441 | int rc; | ||
442 | |||
443 | dev_dbg(&udev->dev, "Enter\n"); | ||
444 | |||
445 | busid_priv = get_busid_priv(udev_busid); | ||
446 | if (!busid_priv) { | ||
447 | BUG(); | ||
448 | return; | ||
449 | } | ||
450 | |||
451 | sdev = dev_get_drvdata(&udev->dev); | ||
452 | |||
453 | /* get stub_device */ | ||
454 | if (!sdev) { | ||
455 | dev_err(&udev->dev, "could not get device"); | ||
456 | return; | ||
457 | } | ||
458 | |||
459 | dev_set_drvdata(&udev->dev, NULL); | ||
460 | |||
461 | /* | ||
462 | * NOTE: rx/tx threads are invoked for each usb_device. | ||
463 | */ | ||
464 | stub_remove_files(&udev->dev); | ||
465 | |||
466 | /* release port */ | ||
467 | rc = usb_hub_release_port(udev->parent, udev->portnum, | ||
468 | (struct usb_dev_state *) udev); | ||
469 | if (rc) { | ||
470 | dev_dbg(&udev->dev, "unable to release port\n"); | ||
471 | return; | ||
472 | } | ||
473 | |||
474 | /* If usb reset is called from event handler */ | ||
475 | if (busid_priv->sdev->ud.eh == current) | ||
476 | return; | ||
477 | |||
478 | /* shutdown the current connection */ | ||
479 | shutdown_busid(busid_priv); | ||
480 | |||
481 | usb_put_dev(sdev->udev); | ||
482 | |||
483 | /* free sdev */ | ||
484 | busid_priv->sdev = NULL; | ||
485 | stub_device_free(sdev); | ||
486 | |||
487 | if (busid_priv->status == STUB_BUSID_ALLOC) { | ||
488 | busid_priv->status = STUB_BUSID_ADDED; | ||
489 | } else { | ||
490 | busid_priv->status = STUB_BUSID_OTHER; | ||
491 | del_match_busid((char *)udev_busid); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | #ifdef CONFIG_PM | ||
496 | |||
497 | /* These functions need usb_port_suspend and usb_port_resume, | ||
498 | * which reside in drivers/usb/core/usb.h. Skip for now. */ | ||
499 | |||
500 | static int stub_suspend(struct usb_device *udev, pm_message_t message) | ||
501 | { | ||
502 | dev_dbg(&udev->dev, "stub_suspend\n"); | ||
503 | |||
504 | return 0; | ||
505 | } | ||
506 | |||
507 | static int stub_resume(struct usb_device *udev, pm_message_t message) | ||
508 | { | ||
509 | dev_dbg(&udev->dev, "stub_resume\n"); | ||
510 | |||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | #endif /* CONFIG_PM */ | ||
515 | |||
516 | struct usb_device_driver stub_driver = { | ||
517 | .name = "usbip-host", | ||
518 | .probe = stub_probe, | ||
519 | .disconnect = stub_disconnect, | ||
520 | #ifdef CONFIG_PM | ||
521 | .suspend = stub_suspend, | ||
522 | .resume = stub_resume, | ||
523 | #endif | ||
524 | .supports_autosuspend = 0, | ||
525 | }; | ||
diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c deleted file mode 100644 index 44ab43fc4fcc..000000000000 --- a/drivers/staging/usbip/stub_main.c +++ /dev/null | |||
@@ -1,335 +0,0 @@ | |||
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/string.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/device.h> | ||
23 | |||
24 | #include "usbip_common.h" | ||
25 | #include "stub.h" | ||
26 | |||
27 | #define DRIVER_AUTHOR "Takahiro Hirofuchi" | ||
28 | #define DRIVER_DESC "USB/IP Host Driver" | ||
29 | |||
30 | struct kmem_cache *stub_priv_cache; | ||
31 | /* | ||
32 | * busid_tables defines matching busids that usbip can grab. A user can change | ||
33 | * dynamically what device is locally used and what device is exported to a | ||
34 | * remote host. | ||
35 | */ | ||
36 | #define MAX_BUSID 16 | ||
37 | static struct bus_id_priv busid_table[MAX_BUSID]; | ||
38 | static spinlock_t busid_table_lock; | ||
39 | |||
40 | static void init_busid_table(void) | ||
41 | { | ||
42 | /* | ||
43 | * This also sets the bus_table[i].status to | ||
44 | * STUB_BUSID_OTHER, which is 0. | ||
45 | */ | ||
46 | memset(busid_table, 0, sizeof(busid_table)); | ||
47 | |||
48 | spin_lock_init(&busid_table_lock); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Find the index of the busid by name. | ||
53 | * Must be called with busid_table_lock held. | ||
54 | */ | ||
55 | static int get_busid_idx(const char *busid) | ||
56 | { | ||
57 | int i; | ||
58 | int idx = -1; | ||
59 | |||
60 | for (i = 0; i < MAX_BUSID; i++) | ||
61 | if (busid_table[i].name[0]) | ||
62 | if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) { | ||
63 | idx = i; | ||
64 | break; | ||
65 | } | ||
66 | return idx; | ||
67 | } | ||
68 | |||
69 | struct bus_id_priv *get_busid_priv(const char *busid) | ||
70 | { | ||
71 | int idx; | ||
72 | struct bus_id_priv *bid = NULL; | ||
73 | |||
74 | spin_lock(&busid_table_lock); | ||
75 | idx = get_busid_idx(busid); | ||
76 | if (idx >= 0) | ||
77 | bid = &(busid_table[idx]); | ||
78 | spin_unlock(&busid_table_lock); | ||
79 | |||
80 | return bid; | ||
81 | } | ||
82 | |||
83 | static int add_match_busid(char *busid) | ||
84 | { | ||
85 | int i; | ||
86 | int ret = -1; | ||
87 | |||
88 | spin_lock(&busid_table_lock); | ||
89 | /* already registered? */ | ||
90 | if (get_busid_idx(busid) >= 0) { | ||
91 | ret = 0; | ||
92 | goto out; | ||
93 | } | ||
94 | |||
95 | for (i = 0; i < MAX_BUSID; i++) | ||
96 | if (!busid_table[i].name[0]) { | ||
97 | strlcpy(busid_table[i].name, busid, BUSID_SIZE); | ||
98 | if ((busid_table[i].status != STUB_BUSID_ALLOC) && | ||
99 | (busid_table[i].status != STUB_BUSID_REMOV)) | ||
100 | busid_table[i].status = STUB_BUSID_ADDED; | ||
101 | ret = 0; | ||
102 | break; | ||
103 | } | ||
104 | |||
105 | out: | ||
106 | spin_unlock(&busid_table_lock); | ||
107 | |||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | int del_match_busid(char *busid) | ||
112 | { | ||
113 | int idx; | ||
114 | int ret = -1; | ||
115 | |||
116 | spin_lock(&busid_table_lock); | ||
117 | idx = get_busid_idx(busid); | ||
118 | if (idx < 0) | ||
119 | goto out; | ||
120 | |||
121 | /* found */ | ||
122 | ret = 0; | ||
123 | |||
124 | if (busid_table[idx].status == STUB_BUSID_OTHER) | ||
125 | memset(busid_table[idx].name, 0, BUSID_SIZE); | ||
126 | |||
127 | if ((busid_table[idx].status != STUB_BUSID_OTHER) && | ||
128 | (busid_table[idx].status != STUB_BUSID_ADDED)) | ||
129 | busid_table[idx].status = STUB_BUSID_REMOV; | ||
130 | |||
131 | out: | ||
132 | spin_unlock(&busid_table_lock); | ||
133 | |||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | static ssize_t show_match_busid(struct device_driver *drv, char *buf) | ||
138 | { | ||
139 | int i; | ||
140 | char *out = buf; | ||
141 | |||
142 | spin_lock(&busid_table_lock); | ||
143 | for (i = 0; i < MAX_BUSID; i++) | ||
144 | if (busid_table[i].name[0]) | ||
145 | out += sprintf(out, "%s ", busid_table[i].name); | ||
146 | spin_unlock(&busid_table_lock); | ||
147 | out += sprintf(out, "\n"); | ||
148 | |||
149 | return out - buf; | ||
150 | } | ||
151 | |||
152 | static ssize_t store_match_busid(struct device_driver *dev, const char *buf, | ||
153 | size_t count) | ||
154 | { | ||
155 | int len; | ||
156 | char busid[BUSID_SIZE]; | ||
157 | |||
158 | if (count < 5) | ||
159 | return -EINVAL; | ||
160 | |||
161 | /* busid needs to include \0 termination */ | ||
162 | len = strlcpy(busid, buf + 4, BUSID_SIZE); | ||
163 | if (sizeof(busid) <= len) | ||
164 | return -EINVAL; | ||
165 | |||
166 | if (!strncmp(buf, "add ", 4)) { | ||
167 | if (add_match_busid(busid) < 0) | ||
168 | return -ENOMEM; | ||
169 | |||
170 | pr_debug("add busid %s\n", busid); | ||
171 | return count; | ||
172 | } | ||
173 | |||
174 | if (!strncmp(buf, "del ", 4)) { | ||
175 | if (del_match_busid(busid) < 0) | ||
176 | return -ENODEV; | ||
177 | |||
178 | pr_debug("del busid %s\n", busid); | ||
179 | return count; | ||
180 | } | ||
181 | |||
182 | return -EINVAL; | ||
183 | } | ||
184 | static DRIVER_ATTR(match_busid, S_IRUSR | S_IWUSR, show_match_busid, | ||
185 | store_match_busid); | ||
186 | |||
187 | static ssize_t rebind_store(struct device_driver *dev, const char *buf, | ||
188 | size_t count) | ||
189 | { | ||
190 | int ret; | ||
191 | int len; | ||
192 | struct bus_id_priv *bid; | ||
193 | |||
194 | /* buf length should be less that BUSID_SIZE */ | ||
195 | len = strnlen(buf, BUSID_SIZE); | ||
196 | |||
197 | if (!(len < BUSID_SIZE)) | ||
198 | return -EINVAL; | ||
199 | |||
200 | bid = get_busid_priv(buf); | ||
201 | if (!bid) | ||
202 | return -ENODEV; | ||
203 | |||
204 | ret = device_attach(&bid->udev->dev); | ||
205 | if (ret < 0) { | ||
206 | dev_err(&bid->udev->dev, "rebind failed\n"); | ||
207 | return ret; | ||
208 | } | ||
209 | |||
210 | return count; | ||
211 | } | ||
212 | |||
213 | static DRIVER_ATTR_WO(rebind); | ||
214 | |||
215 | static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead) | ||
216 | { | ||
217 | struct stub_priv *priv, *tmp; | ||
218 | |||
219 | list_for_each_entry_safe(priv, tmp, listhead, list) { | ||
220 | list_del(&priv->list); | ||
221 | return priv; | ||
222 | } | ||
223 | |||
224 | return NULL; | ||
225 | } | ||
226 | |||
227 | static struct stub_priv *stub_priv_pop(struct stub_device *sdev) | ||
228 | { | ||
229 | unsigned long flags; | ||
230 | struct stub_priv *priv; | ||
231 | |||
232 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
233 | |||
234 | priv = stub_priv_pop_from_listhead(&sdev->priv_init); | ||
235 | if (priv) | ||
236 | goto done; | ||
237 | |||
238 | priv = stub_priv_pop_from_listhead(&sdev->priv_tx); | ||
239 | if (priv) | ||
240 | goto done; | ||
241 | |||
242 | priv = stub_priv_pop_from_listhead(&sdev->priv_free); | ||
243 | |||
244 | done: | ||
245 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
246 | |||
247 | return priv; | ||
248 | } | ||
249 | |||
250 | void stub_device_cleanup_urbs(struct stub_device *sdev) | ||
251 | { | ||
252 | struct stub_priv *priv; | ||
253 | struct urb *urb; | ||
254 | |||
255 | dev_dbg(&sdev->udev->dev, "free sdev %p\n", sdev); | ||
256 | |||
257 | while ((priv = stub_priv_pop(sdev))) { | ||
258 | urb = priv->urb; | ||
259 | dev_dbg(&sdev->udev->dev, "free urb %p\n", urb); | ||
260 | usb_kill_urb(urb); | ||
261 | |||
262 | kmem_cache_free(stub_priv_cache, priv); | ||
263 | |||
264 | kfree(urb->transfer_buffer); | ||
265 | kfree(urb->setup_packet); | ||
266 | usb_free_urb(urb); | ||
267 | } | ||
268 | } | ||
269 | |||
270 | static int __init usbip_host_init(void) | ||
271 | { | ||
272 | int ret; | ||
273 | |||
274 | init_busid_table(); | ||
275 | |||
276 | stub_priv_cache = KMEM_CACHE(stub_priv, SLAB_HWCACHE_ALIGN); | ||
277 | if (!stub_priv_cache) { | ||
278 | pr_err("kmem_cache_create failed\n"); | ||
279 | return -ENOMEM; | ||
280 | } | ||
281 | |||
282 | ret = usb_register_device_driver(&stub_driver, THIS_MODULE); | ||
283 | if (ret) { | ||
284 | pr_err("usb_register failed %d\n", ret); | ||
285 | goto err_usb_register; | ||
286 | } | ||
287 | |||
288 | ret = driver_create_file(&stub_driver.drvwrap.driver, | ||
289 | &driver_attr_match_busid); | ||
290 | if (ret) { | ||
291 | pr_err("driver_create_file failed\n"); | ||
292 | goto err_create_file; | ||
293 | } | ||
294 | |||
295 | ret = driver_create_file(&stub_driver.drvwrap.driver, | ||
296 | &driver_attr_rebind); | ||
297 | if (ret) { | ||
298 | pr_err("driver_create_file failed\n"); | ||
299 | goto err_create_file; | ||
300 | } | ||
301 | |||
302 | pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); | ||
303 | return ret; | ||
304 | |||
305 | err_create_file: | ||
306 | usb_deregister_device_driver(&stub_driver); | ||
307 | err_usb_register: | ||
308 | kmem_cache_destroy(stub_priv_cache); | ||
309 | return ret; | ||
310 | } | ||
311 | |||
312 | static void __exit usbip_host_exit(void) | ||
313 | { | ||
314 | driver_remove_file(&stub_driver.drvwrap.driver, | ||
315 | &driver_attr_match_busid); | ||
316 | |||
317 | driver_remove_file(&stub_driver.drvwrap.driver, | ||
318 | &driver_attr_rebind); | ||
319 | |||
320 | /* | ||
321 | * deregister() calls stub_disconnect() for all devices. Device | ||
322 | * specific data is cleared in stub_disconnect(). | ||
323 | */ | ||
324 | usb_deregister_device_driver(&stub_driver); | ||
325 | |||
326 | kmem_cache_destroy(stub_priv_cache); | ||
327 | } | ||
328 | |||
329 | module_init(usbip_host_init); | ||
330 | module_exit(usbip_host_exit); | ||
331 | |||
332 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
333 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
334 | MODULE_LICENSE("GPL"); | ||
335 | MODULE_VERSION(USBIP_VERSION); | ||
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c deleted file mode 100644 index 00e475c51a12..000000000000 --- a/drivers/staging/usbip/stub_rx.c +++ /dev/null | |||
@@ -1,594 +0,0 @@ | |||
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 <asm/byteorder.h> | ||
21 | #include <linux/kthread.h> | ||
22 | #include <linux/usb.h> | ||
23 | #include <linux/usb/hcd.h> | ||
24 | |||
25 | #include "usbip_common.h" | ||
26 | #include "stub.h" | ||
27 | |||
28 | static int is_clear_halt_cmd(struct urb *urb) | ||
29 | { | ||
30 | struct usb_ctrlrequest *req; | ||
31 | |||
32 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
33 | |||
34 | return (req->bRequest == USB_REQ_CLEAR_FEATURE) && | ||
35 | (req->bRequestType == USB_RECIP_ENDPOINT) && | ||
36 | (req->wValue == USB_ENDPOINT_HALT); | ||
37 | } | ||
38 | |||
39 | static int is_set_interface_cmd(struct urb *urb) | ||
40 | { | ||
41 | struct usb_ctrlrequest *req; | ||
42 | |||
43 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
44 | |||
45 | return (req->bRequest == USB_REQ_SET_INTERFACE) && | ||
46 | (req->bRequestType == USB_RECIP_INTERFACE); | ||
47 | } | ||
48 | |||
49 | static int is_set_configuration_cmd(struct urb *urb) | ||
50 | { | ||
51 | struct usb_ctrlrequest *req; | ||
52 | |||
53 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
54 | |||
55 | return (req->bRequest == USB_REQ_SET_CONFIGURATION) && | ||
56 | (req->bRequestType == USB_RECIP_DEVICE); | ||
57 | } | ||
58 | |||
59 | static int is_reset_device_cmd(struct urb *urb) | ||
60 | { | ||
61 | struct usb_ctrlrequest *req; | ||
62 | __u16 value; | ||
63 | __u16 index; | ||
64 | |||
65 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
66 | value = le16_to_cpu(req->wValue); | ||
67 | index = le16_to_cpu(req->wIndex); | ||
68 | |||
69 | if ((req->bRequest == USB_REQ_SET_FEATURE) && | ||
70 | (req->bRequestType == USB_RT_PORT) && | ||
71 | (value == USB_PORT_FEAT_RESET)) { | ||
72 | usbip_dbg_stub_rx("reset_device_cmd, port %u\n", index); | ||
73 | return 1; | ||
74 | } else | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static int tweak_clear_halt_cmd(struct urb *urb) | ||
79 | { | ||
80 | struct usb_ctrlrequest *req; | ||
81 | int target_endp; | ||
82 | int target_dir; | ||
83 | int target_pipe; | ||
84 | int ret; | ||
85 | |||
86 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
87 | |||
88 | /* | ||
89 | * The stalled endpoint is specified in the wIndex value. The endpoint | ||
90 | * of the urb is the target of this clear_halt request (i.e., control | ||
91 | * endpoint). | ||
92 | */ | ||
93 | target_endp = le16_to_cpu(req->wIndex) & 0x000f; | ||
94 | |||
95 | /* the stalled endpoint direction is IN or OUT?. USB_DIR_IN is 0x80. */ | ||
96 | target_dir = le16_to_cpu(req->wIndex) & 0x0080; | ||
97 | |||
98 | if (target_dir) | ||
99 | target_pipe = usb_rcvctrlpipe(urb->dev, target_endp); | ||
100 | else | ||
101 | target_pipe = usb_sndctrlpipe(urb->dev, target_endp); | ||
102 | |||
103 | ret = usb_clear_halt(urb->dev, target_pipe); | ||
104 | if (ret < 0) | ||
105 | dev_err(&urb->dev->dev, | ||
106 | "usb_clear_halt error: devnum %d endp %d ret %d\n", | ||
107 | urb->dev->devnum, target_endp, ret); | ||
108 | else | ||
109 | dev_info(&urb->dev->dev, | ||
110 | "usb_clear_halt done: devnum %d endp %d\n", | ||
111 | urb->dev->devnum, target_endp); | ||
112 | |||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | static int tweak_set_interface_cmd(struct urb *urb) | ||
117 | { | ||
118 | struct usb_ctrlrequest *req; | ||
119 | __u16 alternate; | ||
120 | __u16 interface; | ||
121 | int ret; | ||
122 | |||
123 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
124 | alternate = le16_to_cpu(req->wValue); | ||
125 | interface = le16_to_cpu(req->wIndex); | ||
126 | |||
127 | usbip_dbg_stub_rx("set_interface: inf %u alt %u\n", | ||
128 | interface, alternate); | ||
129 | |||
130 | ret = usb_set_interface(urb->dev, interface, alternate); | ||
131 | if (ret < 0) | ||
132 | dev_err(&urb->dev->dev, | ||
133 | "usb_set_interface error: inf %u alt %u ret %d\n", | ||
134 | interface, alternate, ret); | ||
135 | else | ||
136 | dev_info(&urb->dev->dev, | ||
137 | "usb_set_interface done: inf %u alt %u\n", | ||
138 | interface, alternate); | ||
139 | |||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | static int tweak_set_configuration_cmd(struct urb *urb) | ||
144 | { | ||
145 | struct stub_priv *priv = (struct stub_priv *) urb->context; | ||
146 | struct stub_device *sdev = priv->sdev; | ||
147 | struct usb_ctrlrequest *req; | ||
148 | __u16 config; | ||
149 | int err; | ||
150 | |||
151 | req = (struct usb_ctrlrequest *) urb->setup_packet; | ||
152 | config = le16_to_cpu(req->wValue); | ||
153 | |||
154 | err = usb_set_configuration(sdev->udev, config); | ||
155 | if (err && err != -ENODEV) | ||
156 | dev_err(&sdev->udev->dev, "can't set config #%d, error %d\n", | ||
157 | config, err); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static int tweak_reset_device_cmd(struct urb *urb) | ||
162 | { | ||
163 | struct stub_priv *priv = (struct stub_priv *) urb->context; | ||
164 | struct stub_device *sdev = priv->sdev; | ||
165 | |||
166 | dev_info(&urb->dev->dev, "usb_queue_reset_device\n"); | ||
167 | |||
168 | /* | ||
169 | * With the implementation of pre_reset and post_reset the driver no | ||
170 | * longer unbinds. This allows the use of synchronous reset. | ||
171 | */ | ||
172 | |||
173 | if (usb_lock_device_for_reset(sdev->udev, sdev->interface) < 0) { | ||
174 | dev_err(&urb->dev->dev, "could not obtain lock to reset device\n"); | ||
175 | return 0; | ||
176 | } | ||
177 | usb_reset_device(sdev->udev); | ||
178 | usb_unlock_device(sdev->udev); | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | /* | ||
184 | * clear_halt, set_interface, and set_configuration require special tricks. | ||
185 | */ | ||
186 | static void tweak_special_requests(struct urb *urb) | ||
187 | { | ||
188 | if (!urb || !urb->setup_packet) | ||
189 | return; | ||
190 | |||
191 | if (usb_pipetype(urb->pipe) != PIPE_CONTROL) | ||
192 | return; | ||
193 | |||
194 | if (is_clear_halt_cmd(urb)) | ||
195 | /* tweak clear_halt */ | ||
196 | tweak_clear_halt_cmd(urb); | ||
197 | |||
198 | else if (is_set_interface_cmd(urb)) | ||
199 | /* tweak set_interface */ | ||
200 | tweak_set_interface_cmd(urb); | ||
201 | |||
202 | else if (is_set_configuration_cmd(urb)) | ||
203 | /* tweak set_configuration */ | ||
204 | tweak_set_configuration_cmd(urb); | ||
205 | |||
206 | else if (is_reset_device_cmd(urb)) | ||
207 | tweak_reset_device_cmd(urb); | ||
208 | else | ||
209 | usbip_dbg_stub_rx("no need to tweak\n"); | ||
210 | } | ||
211 | |||
212 | /* | ||
213 | * stub_recv_unlink() unlinks the URB by a call to usb_unlink_urb(). | ||
214 | * By unlinking the urb asynchronously, stub_rx can continuously | ||
215 | * process coming urbs. Even if the urb is unlinked, its completion | ||
216 | * handler will be called and stub_tx will send a return pdu. | ||
217 | * | ||
218 | * See also comments about unlinking strategy in vhci_hcd.c. | ||
219 | */ | ||
220 | static int stub_recv_cmd_unlink(struct stub_device *sdev, | ||
221 | struct usbip_header *pdu) | ||
222 | { | ||
223 | int ret; | ||
224 | unsigned long flags; | ||
225 | struct stub_priv *priv; | ||
226 | |||
227 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
228 | |||
229 | list_for_each_entry(priv, &sdev->priv_init, list) { | ||
230 | if (priv->seqnum != pdu->u.cmd_unlink.seqnum) | ||
231 | continue; | ||
232 | |||
233 | dev_info(&priv->urb->dev->dev, "unlink urb %p\n", | ||
234 | priv->urb); | ||
235 | |||
236 | /* | ||
237 | * This matched urb is not completed yet (i.e., be in | ||
238 | * flight in usb hcd hardware/driver). Now we are | ||
239 | * cancelling it. The unlinking flag means that we are | ||
240 | * now not going to return the normal result pdu of a | ||
241 | * submission request, but going to return a result pdu | ||
242 | * of the unlink request. | ||
243 | */ | ||
244 | priv->unlinking = 1; | ||
245 | |||
246 | /* | ||
247 | * In the case that unlinking flag is on, prev->seqnum | ||
248 | * is changed from the seqnum of the cancelling urb to | ||
249 | * the seqnum of the unlink request. This will be used | ||
250 | * to make the result pdu of the unlink request. | ||
251 | */ | ||
252 | priv->seqnum = pdu->base.seqnum; | ||
253 | |||
254 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
255 | |||
256 | /* | ||
257 | * usb_unlink_urb() is now out of spinlocking to avoid | ||
258 | * spinlock recursion since stub_complete() is | ||
259 | * sometimes called in this context but not in the | ||
260 | * interrupt context. If stub_complete() is executed | ||
261 | * before we call usb_unlink_urb(), usb_unlink_urb() | ||
262 | * will return an error value. In this case, stub_tx | ||
263 | * will return the result pdu of this unlink request | ||
264 | * though submission is completed and actual unlinking | ||
265 | * is not executed. OK? | ||
266 | */ | ||
267 | /* In the above case, urb->status is not -ECONNRESET, | ||
268 | * so a driver in a client host will know the failure | ||
269 | * of the unlink request ? | ||
270 | */ | ||
271 | ret = usb_unlink_urb(priv->urb); | ||
272 | if (ret != -EINPROGRESS) | ||
273 | dev_err(&priv->urb->dev->dev, | ||
274 | "failed to unlink a urb %p, ret %d\n", | ||
275 | priv->urb, ret); | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | usbip_dbg_stub_rx("seqnum %d is not pending\n", | ||
281 | pdu->u.cmd_unlink.seqnum); | ||
282 | |||
283 | /* | ||
284 | * The urb of the unlink target is not found in priv_init queue. It was | ||
285 | * already completed and its results is/was going to be sent by a | ||
286 | * CMD_RET pdu. In this case, usb_unlink_urb() is not needed. We only | ||
287 | * return the completeness of this unlink request to vhci_hcd. | ||
288 | */ | ||
289 | stub_enqueue_ret_unlink(sdev, pdu->base.seqnum, 0); | ||
290 | |||
291 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
292 | |||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static int valid_request(struct stub_device *sdev, struct usbip_header *pdu) | ||
297 | { | ||
298 | struct usbip_device *ud = &sdev->ud; | ||
299 | int valid = 0; | ||
300 | |||
301 | if (pdu->base.devid == sdev->devid) { | ||
302 | spin_lock_irq(&ud->lock); | ||
303 | if (ud->status == SDEV_ST_USED) { | ||
304 | /* A request is valid. */ | ||
305 | valid = 1; | ||
306 | } | ||
307 | spin_unlock_irq(&ud->lock); | ||
308 | } | ||
309 | |||
310 | return valid; | ||
311 | } | ||
312 | |||
313 | static struct stub_priv *stub_priv_alloc(struct stub_device *sdev, | ||
314 | struct usbip_header *pdu) | ||
315 | { | ||
316 | struct stub_priv *priv; | ||
317 | struct usbip_device *ud = &sdev->ud; | ||
318 | unsigned long flags; | ||
319 | |||
320 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
321 | |||
322 | priv = kmem_cache_zalloc(stub_priv_cache, GFP_ATOMIC); | ||
323 | if (!priv) { | ||
324 | dev_err(&sdev->interface->dev, "alloc stub_priv\n"); | ||
325 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
326 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); | ||
327 | return NULL; | ||
328 | } | ||
329 | |||
330 | priv->seqnum = pdu->base.seqnum; | ||
331 | priv->sdev = sdev; | ||
332 | |||
333 | /* | ||
334 | * After a stub_priv is linked to a list_head, | ||
335 | * our error handler can free allocated data. | ||
336 | */ | ||
337 | list_add_tail(&priv->list, &sdev->priv_init); | ||
338 | |||
339 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
340 | |||
341 | return priv; | ||
342 | } | ||
343 | |||
344 | static int get_pipe(struct stub_device *sdev, int epnum, int dir) | ||
345 | { | ||
346 | struct usb_device *udev = sdev->udev; | ||
347 | struct usb_host_endpoint *ep; | ||
348 | struct usb_endpoint_descriptor *epd = NULL; | ||
349 | |||
350 | if (dir == USBIP_DIR_IN) | ||
351 | ep = udev->ep_in[epnum & 0x7f]; | ||
352 | else | ||
353 | ep = udev->ep_out[epnum & 0x7f]; | ||
354 | if (!ep) { | ||
355 | dev_err(&sdev->interface->dev, "no such endpoint?, %d\n", | ||
356 | epnum); | ||
357 | BUG(); | ||
358 | } | ||
359 | |||
360 | epd = &ep->desc; | ||
361 | if (usb_endpoint_xfer_control(epd)) { | ||
362 | if (dir == USBIP_DIR_OUT) | ||
363 | return usb_sndctrlpipe(udev, epnum); | ||
364 | else | ||
365 | return usb_rcvctrlpipe(udev, epnum); | ||
366 | } | ||
367 | |||
368 | if (usb_endpoint_xfer_bulk(epd)) { | ||
369 | if (dir == USBIP_DIR_OUT) | ||
370 | return usb_sndbulkpipe(udev, epnum); | ||
371 | else | ||
372 | return usb_rcvbulkpipe(udev, epnum); | ||
373 | } | ||
374 | |||
375 | if (usb_endpoint_xfer_int(epd)) { | ||
376 | if (dir == USBIP_DIR_OUT) | ||
377 | return usb_sndintpipe(udev, epnum); | ||
378 | else | ||
379 | return usb_rcvintpipe(udev, epnum); | ||
380 | } | ||
381 | |||
382 | if (usb_endpoint_xfer_isoc(epd)) { | ||
383 | if (dir == USBIP_DIR_OUT) | ||
384 | return usb_sndisocpipe(udev, epnum); | ||
385 | else | ||
386 | return usb_rcvisocpipe(udev, epnum); | ||
387 | } | ||
388 | |||
389 | /* NOT REACHED */ | ||
390 | dev_err(&sdev->interface->dev, "get pipe, epnum %d\n", epnum); | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static void masking_bogus_flags(struct urb *urb) | ||
395 | { | ||
396 | int xfertype; | ||
397 | struct usb_device *dev; | ||
398 | struct usb_host_endpoint *ep; | ||
399 | int is_out; | ||
400 | unsigned int allowed; | ||
401 | |||
402 | if (!urb || urb->hcpriv || !urb->complete) | ||
403 | return; | ||
404 | dev = urb->dev; | ||
405 | if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED)) | ||
406 | return; | ||
407 | |||
408 | ep = (usb_pipein(urb->pipe) ? dev->ep_in : dev->ep_out) | ||
409 | [usb_pipeendpoint(urb->pipe)]; | ||
410 | if (!ep) | ||
411 | return; | ||
412 | |||
413 | xfertype = usb_endpoint_type(&ep->desc); | ||
414 | if (xfertype == USB_ENDPOINT_XFER_CONTROL) { | ||
415 | struct usb_ctrlrequest *setup = | ||
416 | (struct usb_ctrlrequest *) urb->setup_packet; | ||
417 | |||
418 | if (!setup) | ||
419 | return; | ||
420 | is_out = !(setup->bRequestType & USB_DIR_IN) || | ||
421 | !setup->wLength; | ||
422 | } else { | ||
423 | is_out = usb_endpoint_dir_out(&ep->desc); | ||
424 | } | ||
425 | |||
426 | /* enforce simple/standard policy */ | ||
427 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | | ||
428 | URB_DIR_MASK | URB_FREE_BUFFER); | ||
429 | switch (xfertype) { | ||
430 | case USB_ENDPOINT_XFER_BULK: | ||
431 | if (is_out) | ||
432 | allowed |= URB_ZERO_PACKET; | ||
433 | /* FALLTHROUGH */ | ||
434 | case USB_ENDPOINT_XFER_CONTROL: | ||
435 | allowed |= URB_NO_FSBR; /* only affects UHCI */ | ||
436 | /* FALLTHROUGH */ | ||
437 | default: /* all non-iso endpoints */ | ||
438 | if (!is_out) | ||
439 | allowed |= URB_SHORT_NOT_OK; | ||
440 | break; | ||
441 | case USB_ENDPOINT_XFER_ISOC: | ||
442 | allowed |= URB_ISO_ASAP; | ||
443 | break; | ||
444 | } | ||
445 | urb->transfer_flags &= allowed; | ||
446 | } | ||
447 | |||
448 | static void stub_recv_cmd_submit(struct stub_device *sdev, | ||
449 | struct usbip_header *pdu) | ||
450 | { | ||
451 | int ret; | ||
452 | struct stub_priv *priv; | ||
453 | struct usbip_device *ud = &sdev->ud; | ||
454 | struct usb_device *udev = sdev->udev; | ||
455 | int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction); | ||
456 | |||
457 | priv = stub_priv_alloc(sdev, pdu); | ||
458 | if (!priv) | ||
459 | return; | ||
460 | |||
461 | /* setup a urb */ | ||
462 | if (usb_pipeisoc(pipe)) | ||
463 | priv->urb = usb_alloc_urb(pdu->u.cmd_submit.number_of_packets, | ||
464 | GFP_KERNEL); | ||
465 | else | ||
466 | priv->urb = usb_alloc_urb(0, GFP_KERNEL); | ||
467 | |||
468 | if (!priv->urb) { | ||
469 | dev_err(&sdev->interface->dev, "malloc urb\n"); | ||
470 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); | ||
471 | return; | ||
472 | } | ||
473 | |||
474 | /* allocate urb transfer buffer, if needed */ | ||
475 | if (pdu->u.cmd_submit.transfer_buffer_length > 0) { | ||
476 | priv->urb->transfer_buffer = | ||
477 | kzalloc(pdu->u.cmd_submit.transfer_buffer_length, | ||
478 | GFP_KERNEL); | ||
479 | if (!priv->urb->transfer_buffer) { | ||
480 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); | ||
481 | return; | ||
482 | } | ||
483 | } | ||
484 | |||
485 | /* copy urb setup packet */ | ||
486 | priv->urb->setup_packet = kmemdup(&pdu->u.cmd_submit.setup, 8, | ||
487 | GFP_KERNEL); | ||
488 | if (!priv->urb->setup_packet) { | ||
489 | dev_err(&sdev->interface->dev, "allocate setup_packet\n"); | ||
490 | usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC); | ||
491 | return; | ||
492 | } | ||
493 | |||
494 | /* set other members from the base header of pdu */ | ||
495 | priv->urb->context = (void *) priv; | ||
496 | priv->urb->dev = udev; | ||
497 | priv->urb->pipe = pipe; | ||
498 | priv->urb->complete = stub_complete; | ||
499 | |||
500 | usbip_pack_pdu(pdu, priv->urb, USBIP_CMD_SUBMIT, 0); | ||
501 | |||
502 | |||
503 | if (usbip_recv_xbuff(ud, priv->urb) < 0) | ||
504 | return; | ||
505 | |||
506 | if (usbip_recv_iso(ud, priv->urb) < 0) | ||
507 | return; | ||
508 | |||
509 | /* no need to submit an intercepted request, but harmless? */ | ||
510 | tweak_special_requests(priv->urb); | ||
511 | |||
512 | masking_bogus_flags(priv->urb); | ||
513 | /* urb is now ready to submit */ | ||
514 | ret = usb_submit_urb(priv->urb, GFP_KERNEL); | ||
515 | |||
516 | if (ret == 0) | ||
517 | usbip_dbg_stub_rx("submit urb ok, seqnum %u\n", | ||
518 | pdu->base.seqnum); | ||
519 | else { | ||
520 | dev_err(&sdev->interface->dev, "submit_urb error, %d\n", ret); | ||
521 | usbip_dump_header(pdu); | ||
522 | usbip_dump_urb(priv->urb); | ||
523 | |||
524 | /* | ||
525 | * Pessimistic. | ||
526 | * This connection will be discarded. | ||
527 | */ | ||
528 | usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT); | ||
529 | } | ||
530 | |||
531 | usbip_dbg_stub_rx("Leave\n"); | ||
532 | } | ||
533 | |||
534 | /* recv a pdu */ | ||
535 | static void stub_rx_pdu(struct usbip_device *ud) | ||
536 | { | ||
537 | int ret; | ||
538 | struct usbip_header pdu; | ||
539 | struct stub_device *sdev = container_of(ud, struct stub_device, ud); | ||
540 | struct device *dev = &sdev->udev->dev; | ||
541 | |||
542 | usbip_dbg_stub_rx("Enter\n"); | ||
543 | |||
544 | memset(&pdu, 0, sizeof(pdu)); | ||
545 | |||
546 | /* receive a pdu header */ | ||
547 | ret = usbip_recv(ud->tcp_socket, &pdu, sizeof(pdu)); | ||
548 | if (ret != sizeof(pdu)) { | ||
549 | dev_err(dev, "recv a header, %d\n", ret); | ||
550 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); | ||
551 | return; | ||
552 | } | ||
553 | |||
554 | usbip_header_correct_endian(&pdu, 0); | ||
555 | |||
556 | if (usbip_dbg_flag_stub_rx) | ||
557 | usbip_dump_header(&pdu); | ||
558 | |||
559 | if (!valid_request(sdev, &pdu)) { | ||
560 | dev_err(dev, "recv invalid request\n"); | ||
561 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); | ||
562 | return; | ||
563 | } | ||
564 | |||
565 | switch (pdu.base.command) { | ||
566 | case USBIP_CMD_UNLINK: | ||
567 | stub_recv_cmd_unlink(sdev, &pdu); | ||
568 | break; | ||
569 | |||
570 | case USBIP_CMD_SUBMIT: | ||
571 | stub_recv_cmd_submit(sdev, &pdu); | ||
572 | break; | ||
573 | |||
574 | default: | ||
575 | /* NOTREACHED */ | ||
576 | dev_err(dev, "unknown pdu\n"); | ||
577 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); | ||
578 | break; | ||
579 | } | ||
580 | } | ||
581 | |||
582 | int stub_rx_loop(void *data) | ||
583 | { | ||
584 | struct usbip_device *ud = data; | ||
585 | |||
586 | while (!kthread_should_stop()) { | ||
587 | if (usbip_event_happened(ud)) | ||
588 | break; | ||
589 | |||
590 | stub_rx_pdu(ud); | ||
591 | } | ||
592 | |||
593 | return 0; | ||
594 | } | ||
diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c deleted file mode 100644 index dbcabc9dbe0d..000000000000 --- a/drivers/staging/usbip/stub_tx.c +++ /dev/null | |||
@@ -1,398 +0,0 @@ | |||
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/kthread.h> | ||
21 | #include <linux/socket.h> | ||
22 | |||
23 | #include "usbip_common.h" | ||
24 | #include "stub.h" | ||
25 | |||
26 | static void stub_free_priv_and_urb(struct stub_priv *priv) | ||
27 | { | ||
28 | struct urb *urb = priv->urb; | ||
29 | |||
30 | kfree(urb->setup_packet); | ||
31 | kfree(urb->transfer_buffer); | ||
32 | list_del(&priv->list); | ||
33 | kmem_cache_free(stub_priv_cache, priv); | ||
34 | usb_free_urb(urb); | ||
35 | } | ||
36 | |||
37 | /* be in spin_lock_irqsave(&sdev->priv_lock, flags) */ | ||
38 | void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum, | ||
39 | __u32 status) | ||
40 | { | ||
41 | struct stub_unlink *unlink; | ||
42 | |||
43 | unlink = kzalloc(sizeof(struct stub_unlink), GFP_ATOMIC); | ||
44 | if (!unlink) { | ||
45 | usbip_event_add(&sdev->ud, VDEV_EVENT_ERROR_MALLOC); | ||
46 | return; | ||
47 | } | ||
48 | |||
49 | unlink->seqnum = seqnum; | ||
50 | unlink->status = status; | ||
51 | |||
52 | list_add_tail(&unlink->list, &sdev->unlink_tx); | ||
53 | } | ||
54 | |||
55 | /** | ||
56 | * stub_complete - completion handler of a usbip urb | ||
57 | * @urb: pointer to the urb completed | ||
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 | */ | ||
64 | void 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 | usbip_dbg_stub_tx("complete! status %d\n", urb->status); | ||
71 | |||
72 | switch (urb->status) { | ||
73 | case 0: | ||
74 | /* OK */ | ||
75 | break; | ||
76 | case -ENOENT: | ||
77 | dev_info(&urb->dev->dev, | ||
78 | "stopped by a call to usb_kill_urb() because of cleaning up a virtual connection\n"); | ||
79 | return; | ||
80 | case -ECONNRESET: | ||
81 | dev_info(&urb->dev->dev, | ||
82 | "unlinked by a call to usb_unlink_urb()\n"); | ||
83 | break; | ||
84 | case -EPIPE: | ||
85 | dev_info(&urb->dev->dev, "endpoint %d is stalled\n", | ||
86 | usb_pipeendpoint(urb->pipe)); | ||
87 | break; | ||
88 | case -ESHUTDOWN: | ||
89 | dev_info(&urb->dev->dev, "device removed?\n"); | ||
90 | break; | ||
91 | default: | ||
92 | dev_info(&urb->dev->dev, | ||
93 | "urb completion with non-zero status %d\n", | ||
94 | urb->status); | ||
95 | break; | ||
96 | } | ||
97 | |||
98 | /* link a urb to the queue of tx. */ | ||
99 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
100 | if (priv->unlinking) { | ||
101 | stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status); | ||
102 | stub_free_priv_and_urb(priv); | ||
103 | } else { | ||
104 | list_move_tail(&priv->list, &sdev->priv_tx); | ||
105 | } | ||
106 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
107 | |||
108 | /* wake up tx_thread */ | ||
109 | wake_up(&sdev->tx_waitq); | ||
110 | } | ||
111 | |||
112 | static inline void setup_base_pdu(struct usbip_header_basic *base, | ||
113 | __u32 command, __u32 seqnum) | ||
114 | { | ||
115 | base->command = command; | ||
116 | base->seqnum = seqnum; | ||
117 | base->devid = 0; | ||
118 | base->ep = 0; | ||
119 | base->direction = 0; | ||
120 | } | ||
121 | |||
122 | static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urb *urb) | ||
123 | { | ||
124 | struct stub_priv *priv = (struct stub_priv *) urb->context; | ||
125 | |||
126 | setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, priv->seqnum); | ||
127 | usbip_pack_pdu(rpdu, urb, USBIP_RET_SUBMIT, 1); | ||
128 | } | ||
129 | |||
130 | static void setup_ret_unlink_pdu(struct usbip_header *rpdu, | ||
131 | struct stub_unlink *unlink) | ||
132 | { | ||
133 | setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum); | ||
134 | rpdu->u.ret_unlink.status = unlink->status; | ||
135 | } | ||
136 | |||
137 | static struct stub_priv *dequeue_from_priv_tx(struct stub_device *sdev) | ||
138 | { | ||
139 | unsigned long flags; | ||
140 | struct stub_priv *priv, *tmp; | ||
141 | |||
142 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
143 | |||
144 | list_for_each_entry_safe(priv, tmp, &sdev->priv_tx, list) { | ||
145 | list_move_tail(&priv->list, &sdev->priv_free); | ||
146 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
147 | return priv; | ||
148 | } | ||
149 | |||
150 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
151 | |||
152 | return NULL; | ||
153 | } | ||
154 | |||
155 | static int stub_send_ret_submit(struct stub_device *sdev) | ||
156 | { | ||
157 | unsigned long flags; | ||
158 | struct stub_priv *priv, *tmp; | ||
159 | |||
160 | struct msghdr msg; | ||
161 | size_t txsize; | ||
162 | |||
163 | size_t total_size = 0; | ||
164 | |||
165 | while ((priv = dequeue_from_priv_tx(sdev)) != NULL) { | ||
166 | int ret; | ||
167 | struct urb *urb = priv->urb; | ||
168 | struct usbip_header pdu_header; | ||
169 | struct usbip_iso_packet_descriptor *iso_buffer = NULL; | ||
170 | struct kvec *iov = NULL; | ||
171 | int iovnum = 0; | ||
172 | |||
173 | txsize = 0; | ||
174 | memset(&pdu_header, 0, sizeof(pdu_header)); | ||
175 | memset(&msg, 0, sizeof(msg)); | ||
176 | |||
177 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) | ||
178 | iovnum = 2 + urb->number_of_packets; | ||
179 | else | ||
180 | iovnum = 2; | ||
181 | |||
182 | iov = kcalloc(iovnum, sizeof(struct kvec), GFP_KERNEL); | ||
183 | |||
184 | if (!iov) { | ||
185 | usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_MALLOC); | ||
186 | return -1; | ||
187 | } | ||
188 | |||
189 | iovnum = 0; | ||
190 | |||
191 | /* 1. setup usbip_header */ | ||
192 | setup_ret_submit_pdu(&pdu_header, urb); | ||
193 | usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n", | ||
194 | pdu_header.base.seqnum, urb); | ||
195 | usbip_header_correct_endian(&pdu_header, 1); | ||
196 | |||
197 | iov[iovnum].iov_base = &pdu_header; | ||
198 | iov[iovnum].iov_len = sizeof(pdu_header); | ||
199 | iovnum++; | ||
200 | txsize += sizeof(pdu_header); | ||
201 | |||
202 | /* 2. setup transfer buffer */ | ||
203 | if (usb_pipein(urb->pipe) && | ||
204 | usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS && | ||
205 | urb->actual_length > 0) { | ||
206 | iov[iovnum].iov_base = urb->transfer_buffer; | ||
207 | iov[iovnum].iov_len = urb->actual_length; | ||
208 | iovnum++; | ||
209 | txsize += urb->actual_length; | ||
210 | } else if (usb_pipein(urb->pipe) && | ||
211 | usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | ||
212 | /* | ||
213 | * For isochronous packets: actual length is the sum of | ||
214 | * the actual length of the individual, packets, but as | ||
215 | * the packet offsets are not changed there will be | ||
216 | * padding between the packets. To optimally use the | ||
217 | * bandwidth the padding is not transmitted. | ||
218 | */ | ||
219 | |||
220 | int i; | ||
221 | |||
222 | for (i = 0; i < urb->number_of_packets; i++) { | ||
223 | iov[iovnum].iov_base = urb->transfer_buffer + | ||
224 | urb->iso_frame_desc[i].offset; | ||
225 | iov[iovnum].iov_len = | ||
226 | urb->iso_frame_desc[i].actual_length; | ||
227 | iovnum++; | ||
228 | txsize += urb->iso_frame_desc[i].actual_length; | ||
229 | } | ||
230 | |||
231 | if (txsize != sizeof(pdu_header) + urb->actual_length) { | ||
232 | dev_err(&sdev->interface->dev, | ||
233 | "actual length of urb %d does not match iso packet sizes %zu\n", | ||
234 | urb->actual_length, | ||
235 | txsize-sizeof(pdu_header)); | ||
236 | kfree(iov); | ||
237 | usbip_event_add(&sdev->ud, | ||
238 | SDEV_EVENT_ERROR_TCP); | ||
239 | return -1; | ||
240 | } | ||
241 | } | ||
242 | |||
243 | /* 3. setup iso_packet_descriptor */ | ||
244 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | ||
245 | ssize_t len = 0; | ||
246 | |||
247 | iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len); | ||
248 | if (!iso_buffer) { | ||
249 | usbip_event_add(&sdev->ud, | ||
250 | SDEV_EVENT_ERROR_MALLOC); | ||
251 | kfree(iov); | ||
252 | return -1; | ||
253 | } | ||
254 | |||
255 | iov[iovnum].iov_base = iso_buffer; | ||
256 | iov[iovnum].iov_len = len; | ||
257 | txsize += len; | ||
258 | iovnum++; | ||
259 | } | ||
260 | |||
261 | ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, | ||
262 | iov, iovnum, txsize); | ||
263 | if (ret != txsize) { | ||
264 | dev_err(&sdev->interface->dev, | ||
265 | "sendmsg failed!, retval %d for %zd\n", | ||
266 | ret, txsize); | ||
267 | kfree(iov); | ||
268 | kfree(iso_buffer); | ||
269 | usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP); | ||
270 | return -1; | ||
271 | } | ||
272 | |||
273 | kfree(iov); | ||
274 | kfree(iso_buffer); | ||
275 | |||
276 | total_size += txsize; | ||
277 | } | ||
278 | |||
279 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
280 | list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) { | ||
281 | stub_free_priv_and_urb(priv); | ||
282 | } | ||
283 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
284 | |||
285 | return total_size; | ||
286 | } | ||
287 | |||
288 | static struct stub_unlink *dequeue_from_unlink_tx(struct stub_device *sdev) | ||
289 | { | ||
290 | unsigned long flags; | ||
291 | struct stub_unlink *unlink, *tmp; | ||
292 | |||
293 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
294 | |||
295 | list_for_each_entry_safe(unlink, tmp, &sdev->unlink_tx, list) { | ||
296 | list_move_tail(&unlink->list, &sdev->unlink_free); | ||
297 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
298 | return unlink; | ||
299 | } | ||
300 | |||
301 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
302 | |||
303 | return NULL; | ||
304 | } | ||
305 | |||
306 | static int stub_send_ret_unlink(struct stub_device *sdev) | ||
307 | { | ||
308 | unsigned long flags; | ||
309 | struct stub_unlink *unlink, *tmp; | ||
310 | |||
311 | struct msghdr msg; | ||
312 | struct kvec iov[1]; | ||
313 | size_t txsize; | ||
314 | |||
315 | size_t total_size = 0; | ||
316 | |||
317 | while ((unlink = dequeue_from_unlink_tx(sdev)) != NULL) { | ||
318 | int ret; | ||
319 | struct usbip_header pdu_header; | ||
320 | |||
321 | txsize = 0; | ||
322 | memset(&pdu_header, 0, sizeof(pdu_header)); | ||
323 | memset(&msg, 0, sizeof(msg)); | ||
324 | memset(&iov, 0, sizeof(iov)); | ||
325 | |||
326 | usbip_dbg_stub_tx("setup ret unlink %lu\n", unlink->seqnum); | ||
327 | |||
328 | /* 1. setup usbip_header */ | ||
329 | setup_ret_unlink_pdu(&pdu_header, unlink); | ||
330 | usbip_header_correct_endian(&pdu_header, 1); | ||
331 | |||
332 | iov[0].iov_base = &pdu_header; | ||
333 | iov[0].iov_len = sizeof(pdu_header); | ||
334 | txsize += sizeof(pdu_header); | ||
335 | |||
336 | ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, | ||
337 | 1, txsize); | ||
338 | if (ret != txsize) { | ||
339 | dev_err(&sdev->interface->dev, | ||
340 | "sendmsg failed!, retval %d for %zd\n", | ||
341 | ret, txsize); | ||
342 | usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP); | ||
343 | return -1; | ||
344 | } | ||
345 | |||
346 | usbip_dbg_stub_tx("send txdata\n"); | ||
347 | total_size += txsize; | ||
348 | } | ||
349 | |||
350 | spin_lock_irqsave(&sdev->priv_lock, flags); | ||
351 | |||
352 | list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, list) { | ||
353 | list_del(&unlink->list); | ||
354 | kfree(unlink); | ||
355 | } | ||
356 | |||
357 | spin_unlock_irqrestore(&sdev->priv_lock, flags); | ||
358 | |||
359 | return total_size; | ||
360 | } | ||
361 | |||
362 | int stub_tx_loop(void *data) | ||
363 | { | ||
364 | struct usbip_device *ud = data; | ||
365 | struct stub_device *sdev = container_of(ud, struct stub_device, ud); | ||
366 | |||
367 | while (!kthread_should_stop()) { | ||
368 | if (usbip_event_happened(ud)) | ||
369 | break; | ||
370 | |||
371 | /* | ||
372 | * send_ret_submit comes earlier than send_ret_unlink. stub_rx | ||
373 | * looks at only priv_init queue. If the completion of a URB is | ||
374 | * earlier than the receive of CMD_UNLINK, priv is moved to | ||
375 | * priv_tx queue and stub_rx does not find the target priv. In | ||
376 | * this case, vhci_rx receives the result of the submit request | ||
377 | * and then receives the result of the unlink request. The | ||
378 | * result of the submit is given back to the usbcore as the | ||
379 | * completion of the unlink request. The request of the | ||
380 | * unlink is ignored. This is ok because a driver who calls | ||
381 | * usb_unlink_urb() understands the unlink was too late by | ||
382 | * getting the status of the given-backed URB which has the | ||
383 | * status of usb_submit_urb(). | ||
384 | */ | ||
385 | if (stub_send_ret_submit(sdev) < 0) | ||
386 | break; | ||
387 | |||
388 | if (stub_send_ret_unlink(sdev) < 0) | ||
389 | break; | ||
390 | |||
391 | wait_event_interruptible(sdev->tx_waitq, | ||
392 | (!list_empty(&sdev->priv_tx) || | ||
393 | !list_empty(&sdev->unlink_tx) || | ||
394 | kthread_should_stop())); | ||
395 | } | ||
396 | |||
397 | return 0; | ||
398 | } | ||
diff --git a/drivers/staging/usbip/uapi/usbip.h b/drivers/staging/usbip/uapi/usbip.h deleted file mode 100644 index fa5db30ede36..000000000000 --- a/drivers/staging/usbip/uapi/usbip.h +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | /* | ||
2 | * usbip.h | ||
3 | * | ||
4 | * USBIP uapi defines and function prototypes etc. | ||
5 | */ | ||
6 | |||
7 | #ifndef _UAPI_LINUX_USBIP_H | ||
8 | #define _UAPI_LINUX_USBIP_H | ||
9 | |||
10 | /* usbip device status - exported in usbip device sysfs status */ | ||
11 | enum usbip_device_status { | ||
12 | /* sdev is available. */ | ||
13 | SDEV_ST_AVAILABLE = 0x01, | ||
14 | /* sdev is now used. */ | ||
15 | SDEV_ST_USED, | ||
16 | /* sdev is unusable because of a fatal error. */ | ||
17 | SDEV_ST_ERROR, | ||
18 | |||
19 | /* vdev does not connect a remote device. */ | ||
20 | VDEV_ST_NULL, | ||
21 | /* vdev is used, but the USB address is not assigned yet */ | ||
22 | VDEV_ST_NOTASSIGNED, | ||
23 | VDEV_ST_USED, | ||
24 | VDEV_ST_ERROR | ||
25 | }; | ||
26 | #endif /* _UAPI_LINUX_USBIP_H */ | ||
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c deleted file mode 100644 index facaaf003f19..000000000000 --- a/drivers/staging/usbip/usbip_common.c +++ /dev/null | |||
@@ -1,776 +0,0 @@ | |||
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 <asm/byteorder.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/fs.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/stat.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/moduleparam.h> | ||
28 | #include <net/sock.h> | ||
29 | |||
30 | #include "usbip_common.h" | ||
31 | |||
32 | #define DRIVER_AUTHOR "Takahiro Hirofuchi <hirofuchi@users.sourceforge.net>" | ||
33 | #define DRIVER_DESC "USB/IP Core" | ||
34 | |||
35 | #ifdef CONFIG_USBIP_DEBUG | ||
36 | unsigned long usbip_debug_flag = 0xffffffff; | ||
37 | #else | ||
38 | unsigned long usbip_debug_flag; | ||
39 | #endif | ||
40 | EXPORT_SYMBOL_GPL(usbip_debug_flag); | ||
41 | module_param(usbip_debug_flag, ulong, S_IRUGO|S_IWUSR); | ||
42 | MODULE_PARM_DESC(usbip_debug_flag, "debug flags (defined in usbip_common.h)"); | ||
43 | |||
44 | /* FIXME */ | ||
45 | struct device_attribute dev_attr_usbip_debug; | ||
46 | EXPORT_SYMBOL_GPL(dev_attr_usbip_debug); | ||
47 | |||
48 | static ssize_t usbip_debug_show(struct device *dev, | ||
49 | struct device_attribute *attr, char *buf) | ||
50 | { | ||
51 | return sprintf(buf, "%lx\n", usbip_debug_flag); | ||
52 | } | ||
53 | |||
54 | static ssize_t usbip_debug_store(struct device *dev, | ||
55 | struct device_attribute *attr, const char *buf, | ||
56 | size_t count) | ||
57 | { | ||
58 | if (sscanf(buf, "%lx", &usbip_debug_flag) != 1) | ||
59 | return -EINVAL; | ||
60 | return count; | ||
61 | } | ||
62 | DEVICE_ATTR_RW(usbip_debug); | ||
63 | |||
64 | static void usbip_dump_buffer(char *buff, int bufflen) | ||
65 | { | ||
66 | print_hex_dump(KERN_DEBUG, "usbip-core", DUMP_PREFIX_OFFSET, 16, 4, | ||
67 | buff, bufflen, false); | ||
68 | } | ||
69 | |||
70 | static void usbip_dump_pipe(unsigned int p) | ||
71 | { | ||
72 | unsigned char type = usb_pipetype(p); | ||
73 | unsigned char ep = usb_pipeendpoint(p); | ||
74 | unsigned char dev = usb_pipedevice(p); | ||
75 | unsigned char dir = usb_pipein(p); | ||
76 | |||
77 | pr_debug("dev(%d) ep(%d) [%s] ", dev, ep, dir ? "IN" : "OUT"); | ||
78 | |||
79 | switch (type) { | ||
80 | case PIPE_ISOCHRONOUS: | ||
81 | pr_debug("ISO\n"); | ||
82 | break; | ||
83 | case PIPE_INTERRUPT: | ||
84 | pr_debug("INT\n"); | ||
85 | break; | ||
86 | case PIPE_CONTROL: | ||
87 | pr_debug("CTRL\n"); | ||
88 | break; | ||
89 | case PIPE_BULK: | ||
90 | pr_debug("BULK\n"); | ||
91 | break; | ||
92 | default: | ||
93 | pr_debug("ERR\n"); | ||
94 | break; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | static void usbip_dump_usb_device(struct usb_device *udev) | ||
99 | { | ||
100 | struct device *dev = &udev->dev; | ||
101 | int i; | ||
102 | |||
103 | dev_dbg(dev, " devnum(%d) devpath(%s) usb speed(%s)", | ||
104 | udev->devnum, udev->devpath, usb_speed_string(udev->speed)); | ||
105 | |||
106 | pr_debug("tt %p, ttport %d\n", udev->tt, udev->ttport); | ||
107 | |||
108 | dev_dbg(dev, " "); | ||
109 | for (i = 0; i < 16; i++) | ||
110 | pr_debug(" %2u", i); | ||
111 | pr_debug("\n"); | ||
112 | |||
113 | dev_dbg(dev, " toggle0(IN) :"); | ||
114 | for (i = 0; i < 16; i++) | ||
115 | pr_debug(" %2u", (udev->toggle[0] & (1 << i)) ? 1 : 0); | ||
116 | pr_debug("\n"); | ||
117 | |||
118 | dev_dbg(dev, " toggle1(OUT):"); | ||
119 | for (i = 0; i < 16; i++) | ||
120 | pr_debug(" %2u", (udev->toggle[1] & (1 << i)) ? 1 : 0); | ||
121 | pr_debug("\n"); | ||
122 | |||
123 | dev_dbg(dev, " epmaxp_in :"); | ||
124 | for (i = 0; i < 16; i++) { | ||
125 | if (udev->ep_in[i]) | ||
126 | pr_debug(" %2u", | ||
127 | le16_to_cpu(udev->ep_in[i]->desc.wMaxPacketSize)); | ||
128 | } | ||
129 | pr_debug("\n"); | ||
130 | |||
131 | dev_dbg(dev, " epmaxp_out :"); | ||
132 | for (i = 0; i < 16; i++) { | ||
133 | if (udev->ep_out[i]) | ||
134 | pr_debug(" %2u", | ||
135 | le16_to_cpu(udev->ep_out[i]->desc.wMaxPacketSize)); | ||
136 | } | ||
137 | pr_debug("\n"); | ||
138 | |||
139 | dev_dbg(dev, "parent %p, bus %p\n", udev->parent, udev->bus); | ||
140 | |||
141 | dev_dbg(dev, | ||
142 | "descriptor %p, config %p, actconfig %p, rawdescriptors %p\n", | ||
143 | &udev->descriptor, udev->config, | ||
144 | udev->actconfig, udev->rawdescriptors); | ||
145 | |||
146 | dev_dbg(dev, "have_langid %d, string_langid %d\n", | ||
147 | udev->have_langid, udev->string_langid); | ||
148 | |||
149 | dev_dbg(dev, "maxchild %d\n", udev->maxchild); | ||
150 | } | ||
151 | |||
152 | static void usbip_dump_request_type(__u8 rt) | ||
153 | { | ||
154 | switch (rt & USB_RECIP_MASK) { | ||
155 | case USB_RECIP_DEVICE: | ||
156 | pr_debug("DEVICE"); | ||
157 | break; | ||
158 | case USB_RECIP_INTERFACE: | ||
159 | pr_debug("INTERF"); | ||
160 | break; | ||
161 | case USB_RECIP_ENDPOINT: | ||
162 | pr_debug("ENDPOI"); | ||
163 | break; | ||
164 | case USB_RECIP_OTHER: | ||
165 | pr_debug("OTHER "); | ||
166 | break; | ||
167 | default: | ||
168 | pr_debug("------"); | ||
169 | break; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd) | ||
174 | { | ||
175 | if (!cmd) { | ||
176 | pr_debug(" : null pointer\n"); | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | pr_debug(" "); | ||
181 | pr_debug("bRequestType(%02X) bRequest(%02X) wValue(%04X) wIndex(%04X) wLength(%04X) ", | ||
182 | cmd->bRequestType, cmd->bRequest, | ||
183 | cmd->wValue, cmd->wIndex, cmd->wLength); | ||
184 | pr_debug("\n "); | ||
185 | |||
186 | if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) { | ||
187 | pr_debug("STANDARD "); | ||
188 | switch (cmd->bRequest) { | ||
189 | case USB_REQ_GET_STATUS: | ||
190 | pr_debug("GET_STATUS\n"); | ||
191 | break; | ||
192 | case USB_REQ_CLEAR_FEATURE: | ||
193 | pr_debug("CLEAR_FEAT\n"); | ||
194 | break; | ||
195 | case USB_REQ_SET_FEATURE: | ||
196 | pr_debug("SET_FEAT\n"); | ||
197 | break; | ||
198 | case USB_REQ_SET_ADDRESS: | ||
199 | pr_debug("SET_ADDRRS\n"); | ||
200 | break; | ||
201 | case USB_REQ_GET_DESCRIPTOR: | ||
202 | pr_debug("GET_DESCRI\n"); | ||
203 | break; | ||
204 | case USB_REQ_SET_DESCRIPTOR: | ||
205 | pr_debug("SET_DESCRI\n"); | ||
206 | break; | ||
207 | case USB_REQ_GET_CONFIGURATION: | ||
208 | pr_debug("GET_CONFIG\n"); | ||
209 | break; | ||
210 | case USB_REQ_SET_CONFIGURATION: | ||
211 | pr_debug("SET_CONFIG\n"); | ||
212 | break; | ||
213 | case USB_REQ_GET_INTERFACE: | ||
214 | pr_debug("GET_INTERF\n"); | ||
215 | break; | ||
216 | case USB_REQ_SET_INTERFACE: | ||
217 | pr_debug("SET_INTERF\n"); | ||
218 | break; | ||
219 | case USB_REQ_SYNCH_FRAME: | ||
220 | pr_debug("SYNC_FRAME\n"); | ||
221 | break; | ||
222 | default: | ||
223 | pr_debug("REQ(%02X)\n", cmd->bRequest); | ||
224 | break; | ||
225 | } | ||
226 | usbip_dump_request_type(cmd->bRequestType); | ||
227 | } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) { | ||
228 | pr_debug("CLASS\n"); | ||
229 | } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) { | ||
230 | pr_debug("VENDOR\n"); | ||
231 | } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED) { | ||
232 | pr_debug("RESERVED\n"); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | void usbip_dump_urb(struct urb *urb) | ||
237 | { | ||
238 | struct device *dev; | ||
239 | |||
240 | if (!urb) { | ||
241 | pr_debug("urb: null pointer!!\n"); | ||
242 | return; | ||
243 | } | ||
244 | |||
245 | if (!urb->dev) { | ||
246 | pr_debug("urb->dev: null pointer!!\n"); | ||
247 | return; | ||
248 | } | ||
249 | |||
250 | dev = &urb->dev->dev; | ||
251 | |||
252 | dev_dbg(dev, " urb :%p\n", urb); | ||
253 | dev_dbg(dev, " dev :%p\n", urb->dev); | ||
254 | |||
255 | usbip_dump_usb_device(urb->dev); | ||
256 | |||
257 | dev_dbg(dev, " pipe :%08x ", urb->pipe); | ||
258 | |||
259 | usbip_dump_pipe(urb->pipe); | ||
260 | |||
261 | dev_dbg(dev, " status :%d\n", urb->status); | ||
262 | dev_dbg(dev, " transfer_flags :%08X\n", urb->transfer_flags); | ||
263 | dev_dbg(dev, " transfer_buffer :%p\n", urb->transfer_buffer); | ||
264 | dev_dbg(dev, " transfer_buffer_length:%d\n", | ||
265 | urb->transfer_buffer_length); | ||
266 | dev_dbg(dev, " actual_length :%d\n", urb->actual_length); | ||
267 | dev_dbg(dev, " setup_packet :%p\n", urb->setup_packet); | ||
268 | |||
269 | if (urb->setup_packet && usb_pipetype(urb->pipe) == PIPE_CONTROL) | ||
270 | usbip_dump_usb_ctrlrequest( | ||
271 | (struct usb_ctrlrequest *)urb->setup_packet); | ||
272 | |||
273 | dev_dbg(dev, " start_frame :%d\n", urb->start_frame); | ||
274 | dev_dbg(dev, " number_of_packets :%d\n", urb->number_of_packets); | ||
275 | dev_dbg(dev, " interval :%d\n", urb->interval); | ||
276 | dev_dbg(dev, " error_count :%d\n", urb->error_count); | ||
277 | dev_dbg(dev, " context :%p\n", urb->context); | ||
278 | dev_dbg(dev, " complete :%p\n", urb->complete); | ||
279 | } | ||
280 | EXPORT_SYMBOL_GPL(usbip_dump_urb); | ||
281 | |||
282 | void usbip_dump_header(struct usbip_header *pdu) | ||
283 | { | ||
284 | pr_debug("BASE: cmd %u seq %u devid %u dir %u ep %u\n", | ||
285 | pdu->base.command, | ||
286 | pdu->base.seqnum, | ||
287 | pdu->base.devid, | ||
288 | pdu->base.direction, | ||
289 | pdu->base.ep); | ||
290 | |||
291 | switch (pdu->base.command) { | ||
292 | case USBIP_CMD_SUBMIT: | ||
293 | pr_debug("USBIP_CMD_SUBMIT: x_flags %u x_len %u sf %u #p %d iv %d\n", | ||
294 | pdu->u.cmd_submit.transfer_flags, | ||
295 | pdu->u.cmd_submit.transfer_buffer_length, | ||
296 | pdu->u.cmd_submit.start_frame, | ||
297 | pdu->u.cmd_submit.number_of_packets, | ||
298 | pdu->u.cmd_submit.interval); | ||
299 | break; | ||
300 | case USBIP_CMD_UNLINK: | ||
301 | pr_debug("USBIP_CMD_UNLINK: seq %u\n", | ||
302 | pdu->u.cmd_unlink.seqnum); | ||
303 | break; | ||
304 | case USBIP_RET_SUBMIT: | ||
305 | pr_debug("USBIP_RET_SUBMIT: st %d al %u sf %d #p %d ec %d\n", | ||
306 | pdu->u.ret_submit.status, | ||
307 | pdu->u.ret_submit.actual_length, | ||
308 | pdu->u.ret_submit.start_frame, | ||
309 | pdu->u.ret_submit.number_of_packets, | ||
310 | pdu->u.ret_submit.error_count); | ||
311 | break; | ||
312 | case USBIP_RET_UNLINK: | ||
313 | pr_debug("USBIP_RET_UNLINK: status %d\n", | ||
314 | pdu->u.ret_unlink.status); | ||
315 | break; | ||
316 | default: | ||
317 | /* NOT REACHED */ | ||
318 | pr_err("unknown command\n"); | ||
319 | break; | ||
320 | } | ||
321 | } | ||
322 | EXPORT_SYMBOL_GPL(usbip_dump_header); | ||
323 | |||
324 | /* Receive data over TCP/IP. */ | ||
325 | int usbip_recv(struct socket *sock, void *buf, int size) | ||
326 | { | ||
327 | int result; | ||
328 | struct msghdr msg; | ||
329 | struct kvec iov; | ||
330 | int total = 0; | ||
331 | |||
332 | /* for blocks of if (usbip_dbg_flag_xmit) */ | ||
333 | char *bp = buf; | ||
334 | int osize = size; | ||
335 | |||
336 | usbip_dbg_xmit("enter\n"); | ||
337 | |||
338 | if (!sock || !buf || !size) { | ||
339 | pr_err("invalid arg, sock %p buff %p size %d\n", sock, buf, | ||
340 | size); | ||
341 | return -EINVAL; | ||
342 | } | ||
343 | |||
344 | do { | ||
345 | sock->sk->sk_allocation = GFP_NOIO; | ||
346 | iov.iov_base = buf; | ||
347 | iov.iov_len = size; | ||
348 | msg.msg_name = NULL; | ||
349 | msg.msg_namelen = 0; | ||
350 | msg.msg_control = NULL; | ||
351 | msg.msg_controllen = 0; | ||
352 | msg.msg_flags = MSG_NOSIGNAL; | ||
353 | |||
354 | result = kernel_recvmsg(sock, &msg, &iov, 1, size, MSG_WAITALL); | ||
355 | if (result <= 0) { | ||
356 | pr_debug("receive sock %p buf %p size %u ret %d total %d\n", | ||
357 | sock, buf, size, result, total); | ||
358 | goto err; | ||
359 | } | ||
360 | |||
361 | size -= result; | ||
362 | buf += result; | ||
363 | total += result; | ||
364 | } while (size > 0); | ||
365 | |||
366 | if (usbip_dbg_flag_xmit) { | ||
367 | if (!in_interrupt()) | ||
368 | pr_debug("%-10s:", current->comm); | ||
369 | else | ||
370 | pr_debug("interrupt :"); | ||
371 | |||
372 | pr_debug("receiving....\n"); | ||
373 | usbip_dump_buffer(bp, osize); | ||
374 | pr_debug("received, osize %d ret %d size %d total %d\n", | ||
375 | osize, result, size, total); | ||
376 | } | ||
377 | |||
378 | return total; | ||
379 | |||
380 | err: | ||
381 | return result; | ||
382 | } | ||
383 | EXPORT_SYMBOL_GPL(usbip_recv); | ||
384 | |||
385 | /* there may be more cases to tweak the flags. */ | ||
386 | static unsigned int tweak_transfer_flags(unsigned int flags) | ||
387 | { | ||
388 | flags &= ~URB_NO_TRANSFER_DMA_MAP; | ||
389 | return flags; | ||
390 | } | ||
391 | |||
392 | static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb, | ||
393 | int pack) | ||
394 | { | ||
395 | struct usbip_header_cmd_submit *spdu = &pdu->u.cmd_submit; | ||
396 | |||
397 | /* | ||
398 | * Some members are not still implemented in usbip. I hope this issue | ||
399 | * will be discussed when usbip is ported to other operating systems. | ||
400 | */ | ||
401 | if (pack) { | ||
402 | spdu->transfer_flags = | ||
403 | tweak_transfer_flags(urb->transfer_flags); | ||
404 | spdu->transfer_buffer_length = urb->transfer_buffer_length; | ||
405 | spdu->start_frame = urb->start_frame; | ||
406 | spdu->number_of_packets = urb->number_of_packets; | ||
407 | spdu->interval = urb->interval; | ||
408 | } else { | ||
409 | urb->transfer_flags = spdu->transfer_flags; | ||
410 | urb->transfer_buffer_length = spdu->transfer_buffer_length; | ||
411 | urb->start_frame = spdu->start_frame; | ||
412 | urb->number_of_packets = spdu->number_of_packets; | ||
413 | urb->interval = spdu->interval; | ||
414 | } | ||
415 | } | ||
416 | |||
417 | static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb, | ||
418 | int pack) | ||
419 | { | ||
420 | struct usbip_header_ret_submit *rpdu = &pdu->u.ret_submit; | ||
421 | |||
422 | if (pack) { | ||
423 | rpdu->status = urb->status; | ||
424 | rpdu->actual_length = urb->actual_length; | ||
425 | rpdu->start_frame = urb->start_frame; | ||
426 | rpdu->number_of_packets = urb->number_of_packets; | ||
427 | rpdu->error_count = urb->error_count; | ||
428 | } else { | ||
429 | urb->status = rpdu->status; | ||
430 | urb->actual_length = rpdu->actual_length; | ||
431 | urb->start_frame = rpdu->start_frame; | ||
432 | urb->number_of_packets = rpdu->number_of_packets; | ||
433 | urb->error_count = rpdu->error_count; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, | ||
438 | int pack) | ||
439 | { | ||
440 | switch (cmd) { | ||
441 | case USBIP_CMD_SUBMIT: | ||
442 | usbip_pack_cmd_submit(pdu, urb, pack); | ||
443 | break; | ||
444 | case USBIP_RET_SUBMIT: | ||
445 | usbip_pack_ret_submit(pdu, urb, pack); | ||
446 | break; | ||
447 | default: | ||
448 | /* NOT REACHED */ | ||
449 | pr_err("unknown command\n"); | ||
450 | break; | ||
451 | } | ||
452 | } | ||
453 | EXPORT_SYMBOL_GPL(usbip_pack_pdu); | ||
454 | |||
455 | static void correct_endian_basic(struct usbip_header_basic *base, int send) | ||
456 | { | ||
457 | if (send) { | ||
458 | base->command = cpu_to_be32(base->command); | ||
459 | base->seqnum = cpu_to_be32(base->seqnum); | ||
460 | base->devid = cpu_to_be32(base->devid); | ||
461 | base->direction = cpu_to_be32(base->direction); | ||
462 | base->ep = cpu_to_be32(base->ep); | ||
463 | } else { | ||
464 | base->command = be32_to_cpu(base->command); | ||
465 | base->seqnum = be32_to_cpu(base->seqnum); | ||
466 | base->devid = be32_to_cpu(base->devid); | ||
467 | base->direction = be32_to_cpu(base->direction); | ||
468 | base->ep = be32_to_cpu(base->ep); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | static void correct_endian_cmd_submit(struct usbip_header_cmd_submit *pdu, | ||
473 | int send) | ||
474 | { | ||
475 | if (send) { | ||
476 | pdu->transfer_flags = cpu_to_be32(pdu->transfer_flags); | ||
477 | |||
478 | cpu_to_be32s(&pdu->transfer_buffer_length); | ||
479 | cpu_to_be32s(&pdu->start_frame); | ||
480 | cpu_to_be32s(&pdu->number_of_packets); | ||
481 | cpu_to_be32s(&pdu->interval); | ||
482 | } else { | ||
483 | pdu->transfer_flags = be32_to_cpu(pdu->transfer_flags); | ||
484 | |||
485 | be32_to_cpus(&pdu->transfer_buffer_length); | ||
486 | be32_to_cpus(&pdu->start_frame); | ||
487 | be32_to_cpus(&pdu->number_of_packets); | ||
488 | be32_to_cpus(&pdu->interval); | ||
489 | } | ||
490 | } | ||
491 | |||
492 | static void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu, | ||
493 | int send) | ||
494 | { | ||
495 | if (send) { | ||
496 | cpu_to_be32s(&pdu->status); | ||
497 | cpu_to_be32s(&pdu->actual_length); | ||
498 | cpu_to_be32s(&pdu->start_frame); | ||
499 | cpu_to_be32s(&pdu->number_of_packets); | ||
500 | cpu_to_be32s(&pdu->error_count); | ||
501 | } else { | ||
502 | be32_to_cpus(&pdu->status); | ||
503 | be32_to_cpus(&pdu->actual_length); | ||
504 | be32_to_cpus(&pdu->start_frame); | ||
505 | be32_to_cpus(&pdu->number_of_packets); | ||
506 | be32_to_cpus(&pdu->error_count); | ||
507 | } | ||
508 | } | ||
509 | |||
510 | static void correct_endian_cmd_unlink(struct usbip_header_cmd_unlink *pdu, | ||
511 | int send) | ||
512 | { | ||
513 | if (send) | ||
514 | pdu->seqnum = cpu_to_be32(pdu->seqnum); | ||
515 | else | ||
516 | pdu->seqnum = be32_to_cpu(pdu->seqnum); | ||
517 | } | ||
518 | |||
519 | static void correct_endian_ret_unlink(struct usbip_header_ret_unlink *pdu, | ||
520 | int send) | ||
521 | { | ||
522 | if (send) | ||
523 | cpu_to_be32s(&pdu->status); | ||
524 | else | ||
525 | be32_to_cpus(&pdu->status); | ||
526 | } | ||
527 | |||
528 | void usbip_header_correct_endian(struct usbip_header *pdu, int send) | ||
529 | { | ||
530 | __u32 cmd = 0; | ||
531 | |||
532 | if (send) | ||
533 | cmd = pdu->base.command; | ||
534 | |||
535 | correct_endian_basic(&pdu->base, send); | ||
536 | |||
537 | if (!send) | ||
538 | cmd = pdu->base.command; | ||
539 | |||
540 | switch (cmd) { | ||
541 | case USBIP_CMD_SUBMIT: | ||
542 | correct_endian_cmd_submit(&pdu->u.cmd_submit, send); | ||
543 | break; | ||
544 | case USBIP_RET_SUBMIT: | ||
545 | correct_endian_ret_submit(&pdu->u.ret_submit, send); | ||
546 | break; | ||
547 | case USBIP_CMD_UNLINK: | ||
548 | correct_endian_cmd_unlink(&pdu->u.cmd_unlink, send); | ||
549 | break; | ||
550 | case USBIP_RET_UNLINK: | ||
551 | correct_endian_ret_unlink(&pdu->u.ret_unlink, send); | ||
552 | break; | ||
553 | default: | ||
554 | /* NOT REACHED */ | ||
555 | pr_err("unknown command\n"); | ||
556 | break; | ||
557 | } | ||
558 | } | ||
559 | EXPORT_SYMBOL_GPL(usbip_header_correct_endian); | ||
560 | |||
561 | static void usbip_iso_packet_correct_endian( | ||
562 | struct usbip_iso_packet_descriptor *iso, int send) | ||
563 | { | ||
564 | /* does not need all members. but copy all simply. */ | ||
565 | if (send) { | ||
566 | iso->offset = cpu_to_be32(iso->offset); | ||
567 | iso->length = cpu_to_be32(iso->length); | ||
568 | iso->status = cpu_to_be32(iso->status); | ||
569 | iso->actual_length = cpu_to_be32(iso->actual_length); | ||
570 | } else { | ||
571 | iso->offset = be32_to_cpu(iso->offset); | ||
572 | iso->length = be32_to_cpu(iso->length); | ||
573 | iso->status = be32_to_cpu(iso->status); | ||
574 | iso->actual_length = be32_to_cpu(iso->actual_length); | ||
575 | } | ||
576 | } | ||
577 | |||
578 | static void usbip_pack_iso(struct usbip_iso_packet_descriptor *iso, | ||
579 | struct usb_iso_packet_descriptor *uiso, int pack) | ||
580 | { | ||
581 | if (pack) { | ||
582 | iso->offset = uiso->offset; | ||
583 | iso->length = uiso->length; | ||
584 | iso->status = uiso->status; | ||
585 | iso->actual_length = uiso->actual_length; | ||
586 | } else { | ||
587 | uiso->offset = iso->offset; | ||
588 | uiso->length = iso->length; | ||
589 | uiso->status = iso->status; | ||
590 | uiso->actual_length = iso->actual_length; | ||
591 | } | ||
592 | } | ||
593 | |||
594 | /* must free buffer */ | ||
595 | struct usbip_iso_packet_descriptor* | ||
596 | usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen) | ||
597 | { | ||
598 | struct usbip_iso_packet_descriptor *iso; | ||
599 | int np = urb->number_of_packets; | ||
600 | ssize_t size = np * sizeof(*iso); | ||
601 | int i; | ||
602 | |||
603 | iso = kzalloc(size, GFP_KERNEL); | ||
604 | if (!iso) | ||
605 | return NULL; | ||
606 | |||
607 | for (i = 0; i < np; i++) { | ||
608 | usbip_pack_iso(&iso[i], &urb->iso_frame_desc[i], 1); | ||
609 | usbip_iso_packet_correct_endian(&iso[i], 1); | ||
610 | } | ||
611 | |||
612 | *bufflen = size; | ||
613 | |||
614 | return iso; | ||
615 | } | ||
616 | EXPORT_SYMBOL_GPL(usbip_alloc_iso_desc_pdu); | ||
617 | |||
618 | /* some members of urb must be substituted before. */ | ||
619 | int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) | ||
620 | { | ||
621 | void *buff; | ||
622 | struct usbip_iso_packet_descriptor *iso; | ||
623 | int np = urb->number_of_packets; | ||
624 | int size = np * sizeof(*iso); | ||
625 | int i; | ||
626 | int ret; | ||
627 | int total_length = 0; | ||
628 | |||
629 | if (!usb_pipeisoc(urb->pipe)) | ||
630 | return 0; | ||
631 | |||
632 | /* my Bluetooth dongle gets ISO URBs which are np = 0 */ | ||
633 | if (np == 0) | ||
634 | return 0; | ||
635 | |||
636 | buff = kzalloc(size, GFP_KERNEL); | ||
637 | if (!buff) | ||
638 | return -ENOMEM; | ||
639 | |||
640 | ret = usbip_recv(ud->tcp_socket, buff, size); | ||
641 | if (ret != size) { | ||
642 | dev_err(&urb->dev->dev, "recv iso_frame_descriptor, %d\n", | ||
643 | ret); | ||
644 | kfree(buff); | ||
645 | |||
646 | if (ud->side == USBIP_STUB) | ||
647 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); | ||
648 | else | ||
649 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
650 | |||
651 | return -EPIPE; | ||
652 | } | ||
653 | |||
654 | iso = (struct usbip_iso_packet_descriptor *) buff; | ||
655 | for (i = 0; i < np; i++) { | ||
656 | usbip_iso_packet_correct_endian(&iso[i], 0); | ||
657 | usbip_pack_iso(&iso[i], &urb->iso_frame_desc[i], 0); | ||
658 | total_length += urb->iso_frame_desc[i].actual_length; | ||
659 | } | ||
660 | |||
661 | kfree(buff); | ||
662 | |||
663 | if (total_length != urb->actual_length) { | ||
664 | dev_err(&urb->dev->dev, | ||
665 | "total length of iso packets %d not equal to actual length of buffer %d\n", | ||
666 | total_length, urb->actual_length); | ||
667 | |||
668 | if (ud->side == USBIP_STUB) | ||
669 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); | ||
670 | else | ||
671 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
672 | |||
673 | return -EPIPE; | ||
674 | } | ||
675 | |||
676 | return ret; | ||
677 | } | ||
678 | EXPORT_SYMBOL_GPL(usbip_recv_iso); | ||
679 | |||
680 | /* | ||
681 | * This functions restores the padding which was removed for optimizing | ||
682 | * the bandwidth during transfer over tcp/ip | ||
683 | * | ||
684 | * buffer and iso packets need to be stored and be in propeper endian in urb | ||
685 | * before calling this function | ||
686 | */ | ||
687 | void usbip_pad_iso(struct usbip_device *ud, struct urb *urb) | ||
688 | { | ||
689 | int np = urb->number_of_packets; | ||
690 | int i; | ||
691 | int actualoffset = urb->actual_length; | ||
692 | |||
693 | if (!usb_pipeisoc(urb->pipe)) | ||
694 | return; | ||
695 | |||
696 | /* if no packets or length of data is 0, then nothing to unpack */ | ||
697 | if (np == 0 || urb->actual_length == 0) | ||
698 | return; | ||
699 | |||
700 | /* | ||
701 | * if actual_length is transfer_buffer_length then no padding is | ||
702 | * present. | ||
703 | */ | ||
704 | if (urb->actual_length == urb->transfer_buffer_length) | ||
705 | return; | ||
706 | |||
707 | /* | ||
708 | * loop over all packets from last to first (to prevent overwritting | ||
709 | * memory when padding) and move them into the proper place | ||
710 | */ | ||
711 | for (i = np-1; i > 0; i--) { | ||
712 | actualoffset -= urb->iso_frame_desc[i].actual_length; | ||
713 | memmove(urb->transfer_buffer + urb->iso_frame_desc[i].offset, | ||
714 | urb->transfer_buffer + actualoffset, | ||
715 | urb->iso_frame_desc[i].actual_length); | ||
716 | } | ||
717 | } | ||
718 | EXPORT_SYMBOL_GPL(usbip_pad_iso); | ||
719 | |||
720 | /* some members of urb must be substituted before. */ | ||
721 | int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb) | ||
722 | { | ||
723 | int ret; | ||
724 | int size; | ||
725 | |||
726 | if (ud->side == USBIP_STUB) { | ||
727 | /* the direction of urb must be OUT. */ | ||
728 | if (usb_pipein(urb->pipe)) | ||
729 | return 0; | ||
730 | |||
731 | size = urb->transfer_buffer_length; | ||
732 | } else { | ||
733 | /* the direction of urb must be IN. */ | ||
734 | if (usb_pipeout(urb->pipe)) | ||
735 | return 0; | ||
736 | |||
737 | size = urb->actual_length; | ||
738 | } | ||
739 | |||
740 | /* no need to recv xbuff */ | ||
741 | if (!(size > 0)) | ||
742 | return 0; | ||
743 | |||
744 | ret = usbip_recv(ud->tcp_socket, urb->transfer_buffer, size); | ||
745 | if (ret != size) { | ||
746 | dev_err(&urb->dev->dev, "recv xbuf, %d\n", ret); | ||
747 | if (ud->side == USBIP_STUB) { | ||
748 | usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); | ||
749 | } else { | ||
750 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
751 | return -EPIPE; | ||
752 | } | ||
753 | } | ||
754 | |||
755 | return ret; | ||
756 | } | ||
757 | EXPORT_SYMBOL_GPL(usbip_recv_xbuff); | ||
758 | |||
759 | static int __init usbip_core_init(void) | ||
760 | { | ||
761 | pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); | ||
762 | return 0; | ||
763 | } | ||
764 | |||
765 | static void __exit usbip_core_exit(void) | ||
766 | { | ||
767 | return; | ||
768 | } | ||
769 | |||
770 | module_init(usbip_core_init); | ||
771 | module_exit(usbip_core_exit); | ||
772 | |||
773 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
774 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
775 | MODULE_LICENSE("GPL"); | ||
776 | MODULE_VERSION(USBIP_VERSION); | ||
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h deleted file mode 100644 index 4da3866a037d..000000000000 --- a/drivers/staging/usbip/usbip_common.h +++ /dev/null | |||
@@ -1,335 +0,0 @@ | |||
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 | #ifndef __USBIP_COMMON_H | ||
21 | #define __USBIP_COMMON_H | ||
22 | |||
23 | #include <linux/compiler.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/net.h> | ||
27 | #include <linux/printk.h> | ||
28 | #include <linux/spinlock.h> | ||
29 | #include <linux/types.h> | ||
30 | #include <linux/usb.h> | ||
31 | #include <linux/wait.h> | ||
32 | #include "uapi/usbip.h" | ||
33 | |||
34 | #define USBIP_VERSION "1.0.0" | ||
35 | |||
36 | #undef pr_fmt | ||
37 | |||
38 | #ifdef DEBUG | ||
39 | #define pr_fmt(fmt) KBUILD_MODNAME ": %s:%d: " fmt, __func__, __LINE__ | ||
40 | #else | ||
41 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
42 | #endif | ||
43 | |||
44 | enum { | ||
45 | usbip_debug_xmit = (1 << 0), | ||
46 | usbip_debug_sysfs = (1 << 1), | ||
47 | usbip_debug_urb = (1 << 2), | ||
48 | usbip_debug_eh = (1 << 3), | ||
49 | |||
50 | usbip_debug_stub_cmp = (1 << 8), | ||
51 | usbip_debug_stub_dev = (1 << 9), | ||
52 | usbip_debug_stub_rx = (1 << 10), | ||
53 | usbip_debug_stub_tx = (1 << 11), | ||
54 | |||
55 | usbip_debug_vhci_rh = (1 << 8), | ||
56 | usbip_debug_vhci_hc = (1 << 9), | ||
57 | usbip_debug_vhci_rx = (1 << 10), | ||
58 | usbip_debug_vhci_tx = (1 << 11), | ||
59 | usbip_debug_vhci_sysfs = (1 << 12) | ||
60 | }; | ||
61 | |||
62 | #define usbip_dbg_flag_xmit (usbip_debug_flag & usbip_debug_xmit) | ||
63 | #define usbip_dbg_flag_vhci_rh (usbip_debug_flag & usbip_debug_vhci_rh) | ||
64 | #define usbip_dbg_flag_vhci_hc (usbip_debug_flag & usbip_debug_vhci_hc) | ||
65 | #define usbip_dbg_flag_vhci_rx (usbip_debug_flag & usbip_debug_vhci_rx) | ||
66 | #define usbip_dbg_flag_vhci_tx (usbip_debug_flag & usbip_debug_vhci_tx) | ||
67 | #define usbip_dbg_flag_stub_rx (usbip_debug_flag & usbip_debug_stub_rx) | ||
68 | #define usbip_dbg_flag_stub_tx (usbip_debug_flag & usbip_debug_stub_tx) | ||
69 | #define usbip_dbg_flag_vhci_sysfs (usbip_debug_flag & usbip_debug_vhci_sysfs) | ||
70 | |||
71 | extern unsigned long usbip_debug_flag; | ||
72 | extern struct device_attribute dev_attr_usbip_debug; | ||
73 | |||
74 | #define usbip_dbg_with_flag(flag, fmt, args...) \ | ||
75 | do { \ | ||
76 | if (flag & usbip_debug_flag) \ | ||
77 | pr_debug(fmt, ##args); \ | ||
78 | } while (0) | ||
79 | |||
80 | #define usbip_dbg_sysfs(fmt, args...) \ | ||
81 | usbip_dbg_with_flag(usbip_debug_sysfs, fmt , ##args) | ||
82 | #define usbip_dbg_xmit(fmt, args...) \ | ||
83 | usbip_dbg_with_flag(usbip_debug_xmit, fmt , ##args) | ||
84 | #define usbip_dbg_urb(fmt, args...) \ | ||
85 | usbip_dbg_with_flag(usbip_debug_urb, fmt , ##args) | ||
86 | #define usbip_dbg_eh(fmt, args...) \ | ||
87 | usbip_dbg_with_flag(usbip_debug_eh, fmt , ##args) | ||
88 | |||
89 | #define usbip_dbg_vhci_rh(fmt, args...) \ | ||
90 | usbip_dbg_with_flag(usbip_debug_vhci_rh, fmt , ##args) | ||
91 | #define usbip_dbg_vhci_hc(fmt, args...) \ | ||
92 | usbip_dbg_with_flag(usbip_debug_vhci_hc, fmt , ##args) | ||
93 | #define usbip_dbg_vhci_rx(fmt, args...) \ | ||
94 | usbip_dbg_with_flag(usbip_debug_vhci_rx, fmt , ##args) | ||
95 | #define usbip_dbg_vhci_tx(fmt, args...) \ | ||
96 | usbip_dbg_with_flag(usbip_debug_vhci_tx, fmt , ##args) | ||
97 | #define usbip_dbg_vhci_sysfs(fmt, args...) \ | ||
98 | usbip_dbg_with_flag(usbip_debug_vhci_sysfs, fmt , ##args) | ||
99 | |||
100 | #define usbip_dbg_stub_cmp(fmt, args...) \ | ||
101 | usbip_dbg_with_flag(usbip_debug_stub_cmp, fmt , ##args) | ||
102 | #define usbip_dbg_stub_rx(fmt, args...) \ | ||
103 | usbip_dbg_with_flag(usbip_debug_stub_rx, fmt , ##args) | ||
104 | #define usbip_dbg_stub_tx(fmt, args...) \ | ||
105 | usbip_dbg_with_flag(usbip_debug_stub_tx, fmt , ##args) | ||
106 | |||
107 | /* | ||
108 | * USB/IP request headers | ||
109 | * | ||
110 | * Each request is transferred across the network to its counterpart, which | ||
111 | * facilitates the normal USB communication. The values contained in the headers | ||
112 | * are basically the same as in a URB. Currently, four request types are | ||
113 | * defined: | ||
114 | * | ||
115 | * - USBIP_CMD_SUBMIT: a USB request block, corresponds to usb_submit_urb() | ||
116 | * (client to server) | ||
117 | * | ||
118 | * - USBIP_RET_SUBMIT: the result of USBIP_CMD_SUBMIT | ||
119 | * (server to client) | ||
120 | * | ||
121 | * - USBIP_CMD_UNLINK: an unlink request of a pending USBIP_CMD_SUBMIT, | ||
122 | * corresponds to usb_unlink_urb() | ||
123 | * (client to server) | ||
124 | * | ||
125 | * - USBIP_RET_UNLINK: the result of USBIP_CMD_UNLINK | ||
126 | * (server to client) | ||
127 | * | ||
128 | */ | ||
129 | #define USBIP_CMD_SUBMIT 0x0001 | ||
130 | #define USBIP_CMD_UNLINK 0x0002 | ||
131 | #define USBIP_RET_SUBMIT 0x0003 | ||
132 | #define USBIP_RET_UNLINK 0x0004 | ||
133 | |||
134 | #define USBIP_DIR_OUT 0x00 | ||
135 | #define USBIP_DIR_IN 0x01 | ||
136 | |||
137 | /** | ||
138 | * struct usbip_header_basic - data pertinent to every request | ||
139 | * @command: the usbip request type | ||
140 | * @seqnum: sequential number that identifies requests; incremented per | ||
141 | * connection | ||
142 | * @devid: specifies a remote USB device uniquely instead of busnum and devnum; | ||
143 | * in the stub driver, this value is ((busnum << 16) | devnum) | ||
144 | * @direction: direction of the transfer | ||
145 | * @ep: endpoint number | ||
146 | */ | ||
147 | struct usbip_header_basic { | ||
148 | __u32 command; | ||
149 | __u32 seqnum; | ||
150 | __u32 devid; | ||
151 | __u32 direction; | ||
152 | __u32 ep; | ||
153 | } __packed; | ||
154 | |||
155 | /** | ||
156 | * struct usbip_header_cmd_submit - USBIP_CMD_SUBMIT packet header | ||
157 | * @transfer_flags: URB flags | ||
158 | * @transfer_buffer_length: the data size for (in) or (out) transfer | ||
159 | * @start_frame: initial frame for isochronous or interrupt transfers | ||
160 | * @number_of_packets: number of isochronous packets | ||
161 | * @interval: maximum time for the request on the server-side host controller | ||
162 | * @setup: setup data for a control request | ||
163 | */ | ||
164 | struct usbip_header_cmd_submit { | ||
165 | __u32 transfer_flags; | ||
166 | __s32 transfer_buffer_length; | ||
167 | |||
168 | /* it is difficult for usbip to sync frames (reserved only?) */ | ||
169 | __s32 start_frame; | ||
170 | __s32 number_of_packets; | ||
171 | __s32 interval; | ||
172 | |||
173 | unsigned char setup[8]; | ||
174 | } __packed; | ||
175 | |||
176 | /** | ||
177 | * struct usbip_header_ret_submit - USBIP_RET_SUBMIT packet header | ||
178 | * @status: return status of a non-iso request | ||
179 | * @actual_length: number of bytes transferred | ||
180 | * @start_frame: initial frame for isochronous or interrupt transfers | ||
181 | * @number_of_packets: number of isochronous packets | ||
182 | * @error_count: number of errors for isochronous transfers | ||
183 | */ | ||
184 | struct usbip_header_ret_submit { | ||
185 | __s32 status; | ||
186 | __s32 actual_length; | ||
187 | __s32 start_frame; | ||
188 | __s32 number_of_packets; | ||
189 | __s32 error_count; | ||
190 | } __packed; | ||
191 | |||
192 | /** | ||
193 | * struct usbip_header_cmd_unlink - USBIP_CMD_UNLINK packet header | ||
194 | * @seqnum: the URB seqnum to unlink | ||
195 | */ | ||
196 | struct usbip_header_cmd_unlink { | ||
197 | __u32 seqnum; | ||
198 | } __packed; | ||
199 | |||
200 | /** | ||
201 | * struct usbip_header_ret_unlink - USBIP_RET_UNLINK packet header | ||
202 | * @status: return status of the request | ||
203 | */ | ||
204 | struct usbip_header_ret_unlink { | ||
205 | __s32 status; | ||
206 | } __packed; | ||
207 | |||
208 | /** | ||
209 | * struct usbip_header - common header for all usbip packets | ||
210 | * @base: the basic header | ||
211 | * @u: packet type dependent header | ||
212 | */ | ||
213 | struct usbip_header { | ||
214 | struct usbip_header_basic base; | ||
215 | |||
216 | union { | ||
217 | struct usbip_header_cmd_submit cmd_submit; | ||
218 | struct usbip_header_ret_submit ret_submit; | ||
219 | struct usbip_header_cmd_unlink cmd_unlink; | ||
220 | struct usbip_header_ret_unlink ret_unlink; | ||
221 | } u; | ||
222 | } __packed; | ||
223 | |||
224 | /* | ||
225 | * This is the same as usb_iso_packet_descriptor but packed for pdu. | ||
226 | */ | ||
227 | struct usbip_iso_packet_descriptor { | ||
228 | __u32 offset; | ||
229 | __u32 length; /* expected length */ | ||
230 | __u32 actual_length; | ||
231 | __u32 status; | ||
232 | } __packed; | ||
233 | |||
234 | enum usbip_side { | ||
235 | USBIP_VHCI, | ||
236 | USBIP_STUB, | ||
237 | }; | ||
238 | |||
239 | /* event handler */ | ||
240 | #define USBIP_EH_SHUTDOWN (1 << 0) | ||
241 | #define USBIP_EH_BYE (1 << 1) | ||
242 | #define USBIP_EH_RESET (1 << 2) | ||
243 | #define USBIP_EH_UNUSABLE (1 << 3) | ||
244 | |||
245 | #define SDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE) | ||
246 | #define SDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) | ||
247 | #define SDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) | ||
248 | #define SDEV_EVENT_ERROR_SUBMIT (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) | ||
249 | #define SDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) | ||
250 | |||
251 | #define VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_BYE) | ||
252 | #define VDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) | ||
253 | #define VDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET) | ||
254 | #define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE) | ||
255 | |||
256 | /* a common structure for stub_device and vhci_device */ | ||
257 | struct usbip_device { | ||
258 | enum usbip_side side; | ||
259 | enum usbip_device_status status; | ||
260 | |||
261 | /* lock for status */ | ||
262 | spinlock_t lock; | ||
263 | |||
264 | struct socket *tcp_socket; | ||
265 | |||
266 | struct task_struct *tcp_rx; | ||
267 | struct task_struct *tcp_tx; | ||
268 | |||
269 | unsigned long event; | ||
270 | struct task_struct *eh; | ||
271 | wait_queue_head_t eh_waitq; | ||
272 | |||
273 | struct eh_ops { | ||
274 | void (*shutdown)(struct usbip_device *); | ||
275 | void (*reset)(struct usbip_device *); | ||
276 | void (*unusable)(struct usbip_device *); | ||
277 | } eh_ops; | ||
278 | }; | ||
279 | |||
280 | #define kthread_get_run(threadfn, data, namefmt, ...) \ | ||
281 | ({ \ | ||
282 | struct task_struct *__k \ | ||
283 | = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \ | ||
284 | if (!IS_ERR(__k)) { \ | ||
285 | get_task_struct(__k); \ | ||
286 | wake_up_process(__k); \ | ||
287 | } \ | ||
288 | __k; \ | ||
289 | }) | ||
290 | |||
291 | #define kthread_stop_put(k) \ | ||
292 | do { \ | ||
293 | kthread_stop(k); \ | ||
294 | put_task_struct(k); \ | ||
295 | } while (0) | ||
296 | |||
297 | /* usbip_common.c */ | ||
298 | void usbip_dump_urb(struct urb *purb); | ||
299 | void usbip_dump_header(struct usbip_header *pdu); | ||
300 | |||
301 | int usbip_recv(struct socket *sock, void *buf, int size); | ||
302 | |||
303 | void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd, | ||
304 | int pack); | ||
305 | void usbip_header_correct_endian(struct usbip_header *pdu, int send); | ||
306 | |||
307 | struct usbip_iso_packet_descriptor* | ||
308 | usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen); | ||
309 | |||
310 | /* some members of urb must be substituted before. */ | ||
311 | int usbip_recv_iso(struct usbip_device *ud, struct urb *urb); | ||
312 | void usbip_pad_iso(struct usbip_device *ud, struct urb *urb); | ||
313 | int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb); | ||
314 | |||
315 | /* usbip_event.c */ | ||
316 | int usbip_start_eh(struct usbip_device *ud); | ||
317 | void usbip_stop_eh(struct usbip_device *ud); | ||
318 | void usbip_event_add(struct usbip_device *ud, unsigned long event); | ||
319 | int usbip_event_happened(struct usbip_device *ud); | ||
320 | |||
321 | static inline int interface_to_busnum(struct usb_interface *interface) | ||
322 | { | ||
323 | struct usb_device *udev = interface_to_usbdev(interface); | ||
324 | |||
325 | return udev->bus->busnum; | ||
326 | } | ||
327 | |||
328 | static inline int interface_to_devnum(struct usb_interface *interface) | ||
329 | { | ||
330 | struct usb_device *udev = interface_to_usbdev(interface); | ||
331 | |||
332 | return udev->devnum; | ||
333 | } | ||
334 | |||
335 | #endif /* __USBIP_COMMON_H */ | ||
diff --git a/drivers/staging/usbip/usbip_event.c b/drivers/staging/usbip/usbip_event.c deleted file mode 100644 index 64933b993d7a..000000000000 --- a/drivers/staging/usbip/usbip_event.c +++ /dev/null | |||
@@ -1,128 +0,0 @@ | |||
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/kthread.h> | ||
21 | #include <linux/export.h> | ||
22 | |||
23 | #include "usbip_common.h" | ||
24 | |||
25 | static int event_handler(struct usbip_device *ud) | ||
26 | { | ||
27 | usbip_dbg_eh("enter\n"); | ||
28 | |||
29 | /* | ||
30 | * Events are handled by only this thread. | ||
31 | */ | ||
32 | while (usbip_event_happened(ud)) { | ||
33 | usbip_dbg_eh("pending event %lx\n", ud->event); | ||
34 | |||
35 | /* | ||
36 | * NOTE: shutdown must come first. | ||
37 | * Shutdown the device. | ||
38 | */ | ||
39 | if (ud->event & USBIP_EH_SHUTDOWN) { | ||
40 | ud->eh_ops.shutdown(ud); | ||
41 | ud->event &= ~USBIP_EH_SHUTDOWN; | ||
42 | } | ||
43 | |||
44 | /* Reset the device. */ | ||
45 | if (ud->event & USBIP_EH_RESET) { | ||
46 | ud->eh_ops.reset(ud); | ||
47 | ud->event &= ~USBIP_EH_RESET; | ||
48 | } | ||
49 | |||
50 | /* Mark the device as unusable. */ | ||
51 | if (ud->event & USBIP_EH_UNUSABLE) { | ||
52 | ud->eh_ops.unusable(ud); | ||
53 | ud->event &= ~USBIP_EH_UNUSABLE; | ||
54 | } | ||
55 | |||
56 | /* Stop the error handler. */ | ||
57 | if (ud->event & USBIP_EH_BYE) | ||
58 | return -1; | ||
59 | } | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static int event_handler_loop(void *data) | ||
65 | { | ||
66 | struct usbip_device *ud = data; | ||
67 | |||
68 | while (!kthread_should_stop()) { | ||
69 | wait_event_interruptible(ud->eh_waitq, | ||
70 | usbip_event_happened(ud) || | ||
71 | kthread_should_stop()); | ||
72 | usbip_dbg_eh("wakeup\n"); | ||
73 | |||
74 | if (event_handler(ud) < 0) | ||
75 | break; | ||
76 | } | ||
77 | |||
78 | return 0; | ||
79 | } | ||
80 | |||
81 | int usbip_start_eh(struct usbip_device *ud) | ||
82 | { | ||
83 | init_waitqueue_head(&ud->eh_waitq); | ||
84 | ud->event = 0; | ||
85 | |||
86 | ud->eh = kthread_run(event_handler_loop, ud, "usbip_eh"); | ||
87 | if (IS_ERR(ud->eh)) { | ||
88 | pr_warn("Unable to start control thread\n"); | ||
89 | return PTR_ERR(ud->eh); | ||
90 | } | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | EXPORT_SYMBOL_GPL(usbip_start_eh); | ||
95 | |||
96 | void usbip_stop_eh(struct usbip_device *ud) | ||
97 | { | ||
98 | if (ud->eh == current) | ||
99 | return; /* do not wait for myself */ | ||
100 | |||
101 | kthread_stop(ud->eh); | ||
102 | usbip_dbg_eh("usbip_eh has finished\n"); | ||
103 | } | ||
104 | EXPORT_SYMBOL_GPL(usbip_stop_eh); | ||
105 | |||
106 | void usbip_event_add(struct usbip_device *ud, unsigned long event) | ||
107 | { | ||
108 | unsigned long flags; | ||
109 | |||
110 | spin_lock_irqsave(&ud->lock, flags); | ||
111 | ud->event |= event; | ||
112 | wake_up(&ud->eh_waitq); | ||
113 | spin_unlock_irqrestore(&ud->lock, flags); | ||
114 | } | ||
115 | EXPORT_SYMBOL_GPL(usbip_event_add); | ||
116 | |||
117 | int usbip_event_happened(struct usbip_device *ud) | ||
118 | { | ||
119 | int happened = 0; | ||
120 | |||
121 | spin_lock(&ud->lock); | ||
122 | if (ud->event != 0) | ||
123 | happened = 1; | ||
124 | spin_unlock(&ud->lock); | ||
125 | |||
126 | return happened; | ||
127 | } | ||
128 | EXPORT_SYMBOL_GPL(usbip_event_happened); | ||
diff --git a/drivers/staging/usbip/usbip_protocol.txt b/drivers/staging/usbip/usbip_protocol.txt deleted file mode 100644 index 16b6fe27284c..000000000000 --- a/drivers/staging/usbip/usbip_protocol.txt +++ /dev/null | |||
@@ -1,358 +0,0 @@ | |||
1 | PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! | ||
2 | 28 Jun 2011 | ||
3 | |||
4 | The USB/IP protocol follows a server/client architecture. The server exports the | ||
5 | USB devices and the clients imports them. The device driver for the exported | ||
6 | USB device runs on the client machine. | ||
7 | |||
8 | The client may ask for the list of the exported USB devices. To get the list the | ||
9 | client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST | ||
10 | packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent | ||
11 | in one or more pieces at the low level transport layer). The server sends back | ||
12 | the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the | ||
13 | TCP/IP connection is closed. | ||
14 | |||
15 | virtual host controller usb host | ||
16 | "client" "server" | ||
17 | (imports USB devices) (exports USB devices) | ||
18 | | | | ||
19 | | OP_REQ_DEVLIST | | ||
20 | | ----------------------------------------------> | | ||
21 | | | | ||
22 | | OP_REP_DEVLIST | | ||
23 | | <---------------------------------------------- | | ||
24 | | | | ||
25 | |||
26 | Once the client knows the list of exported USB devices it may decide to use one | ||
27 | of them. First the client opens a TCP/IP connection towards the server and | ||
28 | sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the | ||
29 | import was successful the TCP/IP connection remains open and will be used | ||
30 | to transfer the URB traffic between the client and the server. The client may | ||
31 | send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and | ||
32 | USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the | ||
33 | server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. | ||
34 | |||
35 | virtual host controller usb host | ||
36 | "client" "server" | ||
37 | (imports USB devices) (exports USB devices) | ||
38 | | | | ||
39 | | OP_REQ_IMPORT | | ||
40 | | ----------------------------------------------> | | ||
41 | | | | ||
42 | | OP_REP_IMPORT | | ||
43 | | <---------------------------------------------- | | ||
44 | | | | ||
45 | | | | ||
46 | | USBIP_CMD_SUBMIT(seqnum = n) | | ||
47 | | ----------------------------------------------> | | ||
48 | | | | ||
49 | | USBIP_RET_SUBMIT(seqnum = n) | | ||
50 | | <---------------------------------------------- | | ||
51 | | . | | ||
52 | | : | | ||
53 | | | | ||
54 | | USBIP_CMD_SUBMIT(seqnum = m) | | ||
55 | | ----------------------------------------------> | | ||
56 | | | | ||
57 | | USBIP_CMD_SUBMIT(seqnum = m+1) | | ||
58 | | ----------------------------------------------> | | ||
59 | | | | ||
60 | | USBIP_CMD_SUBMIT(seqnum = m+2) | | ||
61 | | ----------------------------------------------> | | ||
62 | | | | ||
63 | | USBIP_RET_SUBMIT(seqnum = m) | | ||
64 | | <---------------------------------------------- | | ||
65 | | | | ||
66 | | USBIP_CMD_SUBMIT(seqnum = m+3) | | ||
67 | | ----------------------------------------------> | | ||
68 | | | | ||
69 | | USBIP_RET_SUBMIT(seqnum = m+1) | | ||
70 | | <---------------------------------------------- | | ||
71 | | | | ||
72 | | USBIP_CMD_SUBMIT(seqnum = m+4) | | ||
73 | | ----------------------------------------------> | | ||
74 | | | | ||
75 | | USBIP_RET_SUBMIT(seqnum = m+2) | | ||
76 | | <---------------------------------------------- | | ||
77 | | . | | ||
78 | | : | | ||
79 | | | | ||
80 | | USBIP_CMD_UNLINK | | ||
81 | | ----------------------------------------------> | | ||
82 | | | | ||
83 | | USBIP_RET_UNLINK | | ||
84 | | <---------------------------------------------- | | ||
85 | | | | ||
86 | |||
87 | The fields are in network (big endian) byte order meaning that the most significant | ||
88 | byte (MSB) is stored at the lowest address. | ||
89 | |||
90 | |||
91 | OP_REQ_DEVLIST: Retrieve the list of exported USB devices. | ||
92 | |||
93 | Offset | Length | Value | Description | ||
94 | -----------+--------+------------+--------------------------------------------------- | ||
95 | 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 | ||
96 | -----------+--------+------------+--------------------------------------------------- | ||
97 | 2 | 2 | 0x8005 | Command code: Retrieve the list of exported USB | ||
98 | | | | devices. | ||
99 | -----------+--------+------------+--------------------------------------------------- | ||
100 | 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 | ||
101 | |||
102 | OP_REP_DEVLIST: Reply with the list of exported USB devices. | ||
103 | |||
104 | Offset | Length | Value | Description | ||
105 | -----------+--------+------------+--------------------------------------------------- | ||
106 | 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0. | ||
107 | -----------+--------+------------+--------------------------------------------------- | ||
108 | 2 | 2 | 0x0005 | Reply code: The list of exported USB devices. | ||
109 | -----------+--------+------------+--------------------------------------------------- | ||
110 | 4 | 4 | 0x00000000 | Status: 0 for OK | ||
111 | -----------+--------+------------+--------------------------------------------------- | ||
112 | 8 | 4 | n | Number of exported devices: 0 means no exported | ||
113 | | | | devices. | ||
114 | -----------+--------+------------+--------------------------------------------------- | ||
115 | 0x0C | | | From now on the exported n devices are described, | ||
116 | | | | if any. If no devices are exported the message | ||
117 | | | | ends with the previous "number of exported | ||
118 | | | | devices" field. | ||
119 | -----------+--------+------------+--------------------------------------------------- | ||
120 | | 256 | | path: Path of the device on the host exporting the | ||
121 | | | | USB device, string closed with zero byte, e.g. | ||
122 | | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" | ||
123 | | | | The unused bytes shall be filled with zero | ||
124 | | | | bytes. | ||
125 | -----------+--------+------------+--------------------------------------------------- | ||
126 | 0x10C | 32 | | busid: Bus ID of the exported device, string | ||
127 | | | | closed with zero byte, e.g. "3-2". The unused | ||
128 | | | | bytes shall be filled with zero bytes. | ||
129 | -----------+--------+------------+--------------------------------------------------- | ||
130 | 0x12C | 4 | | busnum | ||
131 | -----------+--------+------------+--------------------------------------------------- | ||
132 | 0x130 | 4 | | devnum | ||
133 | -----------+--------+------------+--------------------------------------------------- | ||
134 | 0x134 | 4 | | speed | ||
135 | -----------+--------+------------+--------------------------------------------------- | ||
136 | 0x138 | 2 | | idVendor | ||
137 | -----------+--------+------------+--------------------------------------------------- | ||
138 | 0x13A | 2 | | idProduct | ||
139 | -----------+--------+------------+--------------------------------------------------- | ||
140 | 0x13C | 2 | | bcdDevice | ||
141 | -----------+--------+------------+--------------------------------------------------- | ||
142 | 0x13E | 1 | | bDeviceClass | ||
143 | -----------+--------+------------+--------------------------------------------------- | ||
144 | 0x13F | 1 | | bDeviceSubClass | ||
145 | -----------+--------+------------+--------------------------------------------------- | ||
146 | 0x140 | 1 | | bDeviceProtocol | ||
147 | -----------+--------+------------+--------------------------------------------------- | ||
148 | 0x141 | 1 | | bConfigurationValue | ||
149 | -----------+--------+------------+--------------------------------------------------- | ||
150 | 0x142 | 1 | | bNumConfigurations | ||
151 | -----------+--------+------------+--------------------------------------------------- | ||
152 | 0x143 | 1 | | bNumInterfaces | ||
153 | -----------+--------+------------+--------------------------------------------------- | ||
154 | 0x144 | | m_0 | From now on each interface is described, all | ||
155 | | | | together bNumInterfaces times, with the | ||
156 | | | | the following 4 fields: | ||
157 | -----------+--------+------------+--------------------------------------------------- | ||
158 | | 1 | | bInterfaceClass | ||
159 | -----------+--------+------------+--------------------------------------------------- | ||
160 | 0x145 | 1 | | bInterfaceSubClass | ||
161 | -----------+--------+------------+--------------------------------------------------- | ||
162 | 0x146 | 1 | | bInterfaceProtocol | ||
163 | -----------+--------+------------+--------------------------------------------------- | ||
164 | 0x147 | 1 | | padding byte for alignment, shall be set to zero | ||
165 | -----------+--------+------------+--------------------------------------------------- | ||
166 | 0xC + | | | The second exported USB device starts at i=1 | ||
167 | i*0x138 + | | | with the busid field. | ||
168 | m_(i-1)*4 | | | | ||
169 | |||
170 | OP_REQ_IMPORT: Request to import (attach) a remote USB device. | ||
171 | |||
172 | Offset | Length | Value | Description | ||
173 | -----------+--------+------------+--------------------------------------------------- | ||
174 | 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 | ||
175 | -----------+--------+------------+--------------------------------------------------- | ||
176 | 2 | 2 | 0x8003 | Command code: import a remote USB device. | ||
177 | -----------+--------+------------+--------------------------------------------------- | ||
178 | 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 | ||
179 | -----------+--------+------------+--------------------------------------------------- | ||
180 | 8 | 32 | | busid: the busid of the exported device on the | ||
181 | | | | remote host. The possible values are taken | ||
182 | | | | from the message field OP_REP_DEVLIST.busid. | ||
183 | | | | A string closed with zero, the unused bytes | ||
184 | | | | shall be filled with zeros. | ||
185 | -----------+--------+------------+--------------------------------------------------- | ||
186 | |||
187 | OP_REP_IMPORT: Reply to import (attach) a remote USB device. | ||
188 | |||
189 | Offset | Length | Value | Description | ||
190 | -----------+--------+------------+--------------------------------------------------- | ||
191 | 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 | ||
192 | -----------+--------+------------+--------------------------------------------------- | ||
193 | 2 | 2 | 0x0003 | Reply code: Reply to import. | ||
194 | -----------+--------+------------+--------------------------------------------------- | ||
195 | 4 | 4 | 0x00000000 | Status: 0 for OK | ||
196 | | | | 1 for error | ||
197 | -----------+--------+------------+--------------------------------------------------- | ||
198 | 8 | | | From now on comes the details of the imported | ||
199 | | | | device, if the previous status field was OK (0), | ||
200 | | | | otherwise the reply ends with the status field. | ||
201 | -----------+--------+------------+--------------------------------------------------- | ||
202 | | 256 | | path: Path of the device on the host exporting the | ||
203 | | | | USB device, string closed with zero byte, e.g. | ||
204 | | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" | ||
205 | | | | The unused bytes shall be filled with zero | ||
206 | | | | bytes. | ||
207 | -----------+--------+------------+--------------------------------------------------- | ||
208 | 0x108 | 32 | | busid: Bus ID of the exported device, string | ||
209 | | | | closed with zero byte, e.g. "3-2". The unused | ||
210 | | | | bytes shall be filled with zero bytes. | ||
211 | -----------+--------+------------+--------------------------------------------------- | ||
212 | 0x128 | 4 | | busnum | ||
213 | -----------+--------+------------+--------------------------------------------------- | ||
214 | 0x12C | 4 | | devnum | ||
215 | -----------+--------+------------+--------------------------------------------------- | ||
216 | 0x130 | 4 | | speed | ||
217 | -----------+--------+------------+--------------------------------------------------- | ||
218 | 0x134 | 2 | | idVendor | ||
219 | -----------+--------+------------+--------------------------------------------------- | ||
220 | 0x136 | 2 | | idProduct | ||
221 | -----------+--------+------------+--------------------------------------------------- | ||
222 | 0x138 | 2 | | bcdDevice | ||
223 | -----------+--------+------------+--------------------------------------------------- | ||
224 | 0x139 | 1 | | bDeviceClass | ||
225 | -----------+--------+------------+--------------------------------------------------- | ||
226 | 0x13A | 1 | | bDeviceSubClass | ||
227 | -----------+--------+------------+--------------------------------------------------- | ||
228 | 0x13B | 1 | | bDeviceProtocol | ||
229 | -----------+--------+------------+--------------------------------------------------- | ||
230 | 0x13C | 1 | | bConfigurationValue | ||
231 | -----------+--------+------------+--------------------------------------------------- | ||
232 | 0x13D | 1 | | bNumConfigurations | ||
233 | -----------+--------+------------+--------------------------------------------------- | ||
234 | 0x13E | 1 | | bNumInterfaces | ||
235 | |||
236 | USBIP_CMD_SUBMIT: Submit an URB | ||
237 | |||
238 | Offset | Length | Value | Description | ||
239 | -----------+--------+------------+--------------------------------------------------- | ||
240 | 0 | 4 | 0x00000001 | command: Submit an URB | ||
241 | -----------+--------+------------+--------------------------------------------------- | ||
242 | 4 | 4 | | seqnum: the sequence number of the URB to submit | ||
243 | -----------+--------+------------+--------------------------------------------------- | ||
244 | 8 | 4 | | devid | ||
245 | -----------+--------+------------+--------------------------------------------------- | ||
246 | 0xC | 4 | | direction: 0: USBIP_DIR_OUT | ||
247 | | | | 1: USBIP_DIR_IN | ||
248 | -----------+--------+------------+--------------------------------------------------- | ||
249 | 0x10 | 4 | | ep: endpoint number, possible values are: 0...15 | ||
250 | -----------+--------+------------+--------------------------------------------------- | ||
251 | 0x14 | 4 | | transfer_flags: possible values depend on the | ||
252 | | | | URB transfer type, see below | ||
253 | -----------+--------+------------+--------------------------------------------------- | ||
254 | 0x18 | 4 | | transfer_buffer_length | ||
255 | -----------+--------+------------+--------------------------------------------------- | ||
256 | 0x1C | 4 | | start_frame: specify the selected frame to | ||
257 | | | | transmit an ISO frame, ignored if URB_ISO_ASAP | ||
258 | | | | is specified at transfer_flags | ||
259 | -----------+--------+------------+--------------------------------------------------- | ||
260 | 0x20 | 4 | | number_of_packets: number of ISO packets | ||
261 | -----------+--------+------------+--------------------------------------------------- | ||
262 | 0x24 | 4 | | interval: maximum time for the request on the | ||
263 | | | | server-side host controller | ||
264 | -----------+--------+------------+--------------------------------------------------- | ||
265 | 0x28 | 8 | | setup: data bytes for USB setup, filled with | ||
266 | | | | zeros if not used | ||
267 | -----------+--------+------------+--------------------------------------------------- | ||
268 | 0x30 | | | URB data. For ISO transfers the padding between | ||
269 | | | | each ISO packets is not transmitted. | ||
270 | |||
271 | |||
272 | Allowed transfer_flags | value | control | interrupt | bulk | isochronous | ||
273 | -------------------------+------------+---------+-----------+----------+------------- | ||
274 | URB_SHORT_NOT_OK | 0x00000001 | only in | only in | only in | no | ||
275 | URB_ISO_ASAP | 0x00000002 | no | no | no | yes | ||
276 | URB_NO_TRANSFER_DMA_MAP | 0x00000004 | yes | yes | yes | yes | ||
277 | URB_NO_FSBR | 0x00000020 | yes | no | no | no | ||
278 | URB_ZERO_PACKET | 0x00000040 | no | no | only out | no | ||
279 | URB_NO_INTERRUPT | 0x00000080 | yes | yes | yes | yes | ||
280 | URB_FREE_BUFFER | 0x00000100 | yes | yes | yes | yes | ||
281 | URB_DIR_MASK | 0x00000200 | yes | yes | yes | yes | ||
282 | |||
283 | |||
284 | USBIP_RET_SUBMIT: Reply for submitting an URB | ||
285 | |||
286 | Offset | Length | Value | Description | ||
287 | -----------+--------+------------+--------------------------------------------------- | ||
288 | 0 | 4 | 0x00000003 | command | ||
289 | -----------+--------+------------+--------------------------------------------------- | ||
290 | 4 | 4 | | seqnum: URB sequence number | ||
291 | -----------+--------+------------+--------------------------------------------------- | ||
292 | 8 | 4 | | devid | ||
293 | -----------+--------+------------+--------------------------------------------------- | ||
294 | 0xC | 4 | | direction: 0: USBIP_DIR_OUT | ||
295 | | | | 1: USBIP_DIR_IN | ||
296 | -----------+--------+------------+--------------------------------------------------- | ||
297 | 0x10 | 4 | | ep: endpoint number | ||
298 | -----------+--------+------------+--------------------------------------------------- | ||
299 | 0x14 | 4 | | status: zero for successful URB transaction, | ||
300 | | | | otherwise some kind of error happened. | ||
301 | -----------+--------+------------+--------------------------------------------------- | ||
302 | 0x18 | 4 | n | actual_length: number of URB data bytes | ||
303 | -----------+--------+------------+--------------------------------------------------- | ||
304 | 0x1C | 4 | | start_frame: for an ISO frame the actually | ||
305 | | | | selected frame for transmit. | ||
306 | -----------+--------+------------+--------------------------------------------------- | ||
307 | 0x20 | 4 | | number_of_packets | ||
308 | -----------+--------+------------+--------------------------------------------------- | ||
309 | 0x24 | 4 | | error_count | ||
310 | -----------+--------+------------+--------------------------------------------------- | ||
311 | 0x28 | 8 | | setup: data bytes for USB setup, filled with | ||
312 | | | | zeros if not used | ||
313 | -----------+--------+------------+--------------------------------------------------- | ||
314 | 0x30 | n | | URB data bytes. For ISO transfers the padding | ||
315 | | | | between each ISO packets is not transmitted. | ||
316 | |||
317 | USBIP_CMD_UNLINK: Unlink an URB | ||
318 | |||
319 | Offset | Length | Value | Description | ||
320 | -----------+--------+------------+--------------------------------------------------- | ||
321 | 0 | 4 | 0x00000002 | command: URB unlink command | ||
322 | -----------+--------+------------+--------------------------------------------------- | ||
323 | 4 | 4 | | seqnum: URB sequence number to unlink: FIXME: is this so? | ||
324 | -----------+--------+------------+--------------------------------------------------- | ||
325 | 8 | 4 | | devid | ||
326 | -----------+--------+------------+--------------------------------------------------- | ||
327 | 0xC | 4 | | direction: 0: USBIP_DIR_OUT | ||
328 | | | | 1: USBIP_DIR_IN | ||
329 | -----------+--------+------------+--------------------------------------------------- | ||
330 | 0x10 | 4 | | ep: endpoint number: zero | ||
331 | -----------+--------+------------+--------------------------------------------------- | ||
332 | 0x14 | 4 | | seqnum: the URB sequence number given previously | ||
333 | | | | at USBIP_CMD_SUBMIT.seqnum field | ||
334 | -----------+--------+------------+--------------------------------------------------- | ||
335 | 0x30 | n | | URB data bytes. For ISO transfers the padding | ||
336 | | | | between each ISO packets is not transmitted. | ||
337 | |||
338 | USBIP_RET_UNLINK: Reply for URB unlink | ||
339 | |||
340 | Offset | Length | Value | Description | ||
341 | -----------+--------+------------+--------------------------------------------------- | ||
342 | 0 | 4 | 0x00000004 | command: reply for the URB unlink command | ||
343 | -----------+--------+------------+--------------------------------------------------- | ||
344 | 4 | 4 | | seqnum: the unlinked URB sequence number | ||
345 | -----------+--------+------------+--------------------------------------------------- | ||
346 | 8 | 4 | | devid | ||
347 | -----------+--------+------------+--------------------------------------------------- | ||
348 | 0xC | 4 | | direction: 0: USBIP_DIR_OUT | ||
349 | | | | 1: USBIP_DIR_IN | ||
350 | -----------+--------+------------+--------------------------------------------------- | ||
351 | 0x10 | 4 | | ep: endpoint number | ||
352 | -----------+--------+------------+--------------------------------------------------- | ||
353 | 0x14 | 4 | | status: This is the value contained in the | ||
354 | | | | urb->status in the URB completition handler. | ||
355 | | | | FIXME: a better explanation needed. | ||
356 | -----------+--------+------------+--------------------------------------------------- | ||
357 | 0x30 | n | | URB data bytes. For ISO transfers the padding | ||
358 | | | | between each ISO packets is not transmitted. | ||
diff --git a/drivers/staging/usbip/vhci.h b/drivers/staging/usbip/vhci.h deleted file mode 100644 index a863a98a91ce..000000000000 --- a/drivers/staging/usbip/vhci.h +++ /dev/null | |||
@@ -1,129 +0,0 @@ | |||
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 | */ | ||
10 | |||
11 | #ifndef __USBIP_VHCI_H | ||
12 | #define __USBIP_VHCI_H | ||
13 | |||
14 | #include <linux/device.h> | ||
15 | #include <linux/list.h> | ||
16 | #include <linux/spinlock.h> | ||
17 | #include <linux/sysfs.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/usb.h> | ||
20 | #include <linux/usb/hcd.h> | ||
21 | #include <linux/wait.h> | ||
22 | |||
23 | struct vhci_device { | ||
24 | struct usb_device *udev; | ||
25 | |||
26 | /* | ||
27 | * devid specifies a remote usb device uniquely instead | ||
28 | * of combination of busnum and devnum. | ||
29 | */ | ||
30 | __u32 devid; | ||
31 | |||
32 | /* speed of a remote device */ | ||
33 | enum usb_device_speed speed; | ||
34 | |||
35 | /* vhci root-hub port to which this device is attached */ | ||
36 | __u32 rhport; | ||
37 | |||
38 | struct usbip_device ud; | ||
39 | |||
40 | /* lock for the below link lists */ | ||
41 | spinlock_t priv_lock; | ||
42 | |||
43 | /* vhci_priv is linked to one of them. */ | ||
44 | struct list_head priv_tx; | ||
45 | struct list_head priv_rx; | ||
46 | |||
47 | /* vhci_unlink is linked to one of them */ | ||
48 | struct list_head unlink_tx; | ||
49 | struct list_head unlink_rx; | ||
50 | |||
51 | /* vhci_tx thread sleeps for this queue */ | ||
52 | wait_queue_head_t waitq_tx; | ||
53 | }; | ||
54 | |||
55 | /* urb->hcpriv, use container_of() */ | ||
56 | struct vhci_priv { | ||
57 | unsigned long seqnum; | ||
58 | struct list_head list; | ||
59 | |||
60 | struct vhci_device *vdev; | ||
61 | struct urb *urb; | ||
62 | }; | ||
63 | |||
64 | struct vhci_unlink { | ||
65 | /* seqnum of this request */ | ||
66 | unsigned long seqnum; | ||
67 | |||
68 | struct list_head list; | ||
69 | |||
70 | /* seqnum of the unlink target */ | ||
71 | unsigned long unlink_seqnum; | ||
72 | }; | ||
73 | |||
74 | /* Number of supported ports. Value has an upperbound of USB_MAXCHILDREN */ | ||
75 | #define VHCI_NPORTS 8 | ||
76 | |||
77 | /* for usb_bus.hcpriv */ | ||
78 | struct vhci_hcd { | ||
79 | spinlock_t lock; | ||
80 | |||
81 | u32 port_status[VHCI_NPORTS]; | ||
82 | |||
83 | unsigned resuming:1; | ||
84 | unsigned long re_timeout; | ||
85 | |||
86 | atomic_t seqnum; | ||
87 | |||
88 | /* | ||
89 | * NOTE: | ||
90 | * wIndex shows the port number and begins from 1. | ||
91 | * But, the index of this array begins from 0. | ||
92 | */ | ||
93 | struct vhci_device vdev[VHCI_NPORTS]; | ||
94 | }; | ||
95 | |||
96 | extern struct vhci_hcd *the_controller; | ||
97 | extern const struct attribute_group dev_attr_group; | ||
98 | |||
99 | /* vhci_hcd.c */ | ||
100 | void rh_port_connect(int rhport, enum usb_device_speed speed); | ||
101 | |||
102 | /* vhci_rx.c */ | ||
103 | struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum); | ||
104 | int vhci_rx_loop(void *data); | ||
105 | |||
106 | /* vhci_tx.c */ | ||
107 | int vhci_tx_loop(void *data); | ||
108 | |||
109 | static inline struct vhci_device *port_to_vdev(__u32 port) | ||
110 | { | ||
111 | return &the_controller->vdev[port]; | ||
112 | } | ||
113 | |||
114 | static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd) | ||
115 | { | ||
116 | return (struct vhci_hcd *) (hcd->hcd_priv); | ||
117 | } | ||
118 | |||
119 | static inline struct usb_hcd *vhci_to_hcd(struct vhci_hcd *vhci) | ||
120 | { | ||
121 | return container_of((void *) vhci, struct usb_hcd, hcd_priv); | ||
122 | } | ||
123 | |||
124 | static inline struct device *vhci_dev(struct vhci_hcd *vhci) | ||
125 | { | ||
126 | return vhci_to_hcd(vhci)->self.controller; | ||
127 | } | ||
128 | |||
129 | #endif /* __USBIP_VHCI_H */ | ||
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c deleted file mode 100644 index c02374b6049c..000000000000 --- a/drivers/staging/usbip/vhci_hcd.c +++ /dev/null | |||
@@ -1,1171 +0,0 @@ | |||
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/init.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/kthread.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/slab.h> | ||
27 | |||
28 | #include "usbip_common.h" | ||
29 | #include "vhci.h" | ||
30 | |||
31 | #define DRIVER_AUTHOR "Takahiro Hirofuchi" | ||
32 | #define DRIVER_DESC "USB/IP 'Virtual' Host Controller (VHCI) Driver" | ||
33 | |||
34 | /* | ||
35 | * TODO | ||
36 | * - update root hub emulation | ||
37 | * - move the emulation code to userland ? | ||
38 | * porting to other operating systems | ||
39 | * minimize kernel code | ||
40 | * - add suspend/resume code | ||
41 | * - clean up everything | ||
42 | */ | ||
43 | |||
44 | /* See usb gadget dummy hcd */ | ||
45 | |||
46 | static int vhci_hub_status(struct usb_hcd *hcd, char *buff); | ||
47 | static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | ||
48 | u16 wIndex, char *buff, u16 wLength); | ||
49 | static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | ||
50 | gfp_t mem_flags); | ||
51 | static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status); | ||
52 | static int vhci_start(struct usb_hcd *vhci_hcd); | ||
53 | static void vhci_stop(struct usb_hcd *hcd); | ||
54 | static int vhci_get_frame_number(struct usb_hcd *hcd); | ||
55 | |||
56 | static const char driver_name[] = "vhci_hcd"; | ||
57 | static const char driver_desc[] = "USB/IP Virtual Host Controller"; | ||
58 | |||
59 | struct vhci_hcd *the_controller; | ||
60 | |||
61 | static const char * const bit_desc[] = { | ||
62 | "CONNECTION", /*0*/ | ||
63 | "ENABLE", /*1*/ | ||
64 | "SUSPEND", /*2*/ | ||
65 | "OVER_CURRENT", /*3*/ | ||
66 | "RESET", /*4*/ | ||
67 | "R5", /*5*/ | ||
68 | "R6", /*6*/ | ||
69 | "R7", /*7*/ | ||
70 | "POWER", /*8*/ | ||
71 | "LOWSPEED", /*9*/ | ||
72 | "HIGHSPEED", /*10*/ | ||
73 | "PORT_TEST", /*11*/ | ||
74 | "INDICATOR", /*12*/ | ||
75 | "R13", /*13*/ | ||
76 | "R14", /*14*/ | ||
77 | "R15", /*15*/ | ||
78 | "C_CONNECTION", /*16*/ | ||
79 | "C_ENABLE", /*17*/ | ||
80 | "C_SUSPEND", /*18*/ | ||
81 | "C_OVER_CURRENT", /*19*/ | ||
82 | "C_RESET", /*20*/ | ||
83 | "R21", /*21*/ | ||
84 | "R22", /*22*/ | ||
85 | "R23", /*23*/ | ||
86 | "R24", /*24*/ | ||
87 | "R25", /*25*/ | ||
88 | "R26", /*26*/ | ||
89 | "R27", /*27*/ | ||
90 | "R28", /*28*/ | ||
91 | "R29", /*29*/ | ||
92 | "R30", /*30*/ | ||
93 | "R31", /*31*/ | ||
94 | }; | ||
95 | |||
96 | static void dump_port_status_diff(u32 prev_status, u32 new_status) | ||
97 | { | ||
98 | int i = 0; | ||
99 | u32 bit = 1; | ||
100 | |||
101 | pr_debug("status prev -> new: %08x -> %08x\n", prev_status, new_status); | ||
102 | while (bit) { | ||
103 | u32 prev = prev_status & bit; | ||
104 | u32 new = new_status & bit; | ||
105 | char change; | ||
106 | |||
107 | if (!prev && new) | ||
108 | change = '+'; | ||
109 | else if (prev && !new) | ||
110 | change = '-'; | ||
111 | else | ||
112 | change = ' '; | ||
113 | |||
114 | if (prev || new) | ||
115 | pr_debug(" %c%s\n", change, bit_desc[i]); | ||
116 | bit <<= 1; | ||
117 | i++; | ||
118 | } | ||
119 | pr_debug("\n"); | ||
120 | } | ||
121 | |||
122 | void rh_port_connect(int rhport, enum usb_device_speed speed) | ||
123 | { | ||
124 | usbip_dbg_vhci_rh("rh_port_connect %d\n", rhport); | ||
125 | |||
126 | spin_lock(&the_controller->lock); | ||
127 | |||
128 | the_controller->port_status[rhport] |= USB_PORT_STAT_CONNECTION | ||
129 | | (1 << USB_PORT_FEAT_C_CONNECTION); | ||
130 | |||
131 | switch (speed) { | ||
132 | case USB_SPEED_HIGH: | ||
133 | the_controller->port_status[rhport] |= USB_PORT_STAT_HIGH_SPEED; | ||
134 | break; | ||
135 | case USB_SPEED_LOW: | ||
136 | the_controller->port_status[rhport] |= USB_PORT_STAT_LOW_SPEED; | ||
137 | break; | ||
138 | default: | ||
139 | break; | ||
140 | } | ||
141 | |||
142 | spin_unlock(&the_controller->lock); | ||
143 | |||
144 | usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); | ||
145 | } | ||
146 | |||
147 | static void rh_port_disconnect(int rhport) | ||
148 | { | ||
149 | usbip_dbg_vhci_rh("rh_port_disconnect %d\n", rhport); | ||
150 | |||
151 | spin_lock(&the_controller->lock); | ||
152 | |||
153 | the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION; | ||
154 | the_controller->port_status[rhport] |= | ||
155 | (1 << USB_PORT_FEAT_C_CONNECTION); | ||
156 | |||
157 | spin_unlock(&the_controller->lock); | ||
158 | usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); | ||
159 | } | ||
160 | |||
161 | #define PORT_C_MASK \ | ||
162 | ((USB_PORT_STAT_C_CONNECTION \ | ||
163 | | USB_PORT_STAT_C_ENABLE \ | ||
164 | | USB_PORT_STAT_C_SUSPEND \ | ||
165 | | USB_PORT_STAT_C_OVERCURRENT \ | ||
166 | | USB_PORT_STAT_C_RESET) << 16) | ||
167 | |||
168 | /* | ||
169 | * Returns 0 if the status hasn't changed, or the number of bytes in buf. | ||
170 | * Ports are 0-indexed from the HCD point of view, | ||
171 | * and 1-indexed from the USB core pointer of view. | ||
172 | * | ||
173 | * @buf: a bitmap to show which port status has been changed. | ||
174 | * bit 0: reserved | ||
175 | * bit 1: the status of port 0 has been changed. | ||
176 | * bit 2: the status of port 1 has been changed. | ||
177 | * ... | ||
178 | */ | ||
179 | static int vhci_hub_status(struct usb_hcd *hcd, char *buf) | ||
180 | { | ||
181 | struct vhci_hcd *vhci; | ||
182 | int retval; | ||
183 | int rhport; | ||
184 | int changed = 0; | ||
185 | |||
186 | retval = DIV_ROUND_UP(VHCI_NPORTS + 1, 8); | ||
187 | memset(buf, 0, retval); | ||
188 | |||
189 | vhci = hcd_to_vhci(hcd); | ||
190 | |||
191 | spin_lock(&vhci->lock); | ||
192 | if (!HCD_HW_ACCESSIBLE(hcd)) { | ||
193 | usbip_dbg_vhci_rh("hw accessible flag not on?\n"); | ||
194 | goto done; | ||
195 | } | ||
196 | |||
197 | /* check pseudo status register for each port */ | ||
198 | for (rhport = 0; rhport < VHCI_NPORTS; rhport++) { | ||
199 | if ((vhci->port_status[rhport] & PORT_C_MASK)) { | ||
200 | /* The status of a port has been changed, */ | ||
201 | usbip_dbg_vhci_rh("port %d status changed\n", rhport); | ||
202 | |||
203 | buf[(rhport + 1) / 8] |= 1 << (rhport + 1) % 8; | ||
204 | changed = 1; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | if ((hcd->state == HC_STATE_SUSPENDED) && (changed == 1)) | ||
209 | usb_hcd_resume_root_hub(hcd); | ||
210 | |||
211 | done: | ||
212 | spin_unlock(&vhci->lock); | ||
213 | return changed ? retval : 0; | ||
214 | } | ||
215 | |||
216 | static inline void hub_descriptor(struct usb_hub_descriptor *desc) | ||
217 | { | ||
218 | memset(desc, 0, sizeof(*desc)); | ||
219 | desc->bDescriptorType = 0x29; | ||
220 | desc->bDescLength = 9; | ||
221 | desc->wHubCharacteristics = (__constant_cpu_to_le16(0x0001)); | ||
222 | desc->bNbrPorts = VHCI_NPORTS; | ||
223 | desc->u.hs.DeviceRemovable[0] = 0xff; | ||
224 | desc->u.hs.DeviceRemovable[1] = 0xff; | ||
225 | } | ||
226 | |||
227 | static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | ||
228 | u16 wIndex, char *buf, u16 wLength) | ||
229 | { | ||
230 | struct vhci_hcd *dum; | ||
231 | int retval = 0; | ||
232 | int rhport; | ||
233 | |||
234 | u32 prev_port_status[VHCI_NPORTS]; | ||
235 | |||
236 | if (!HCD_HW_ACCESSIBLE(hcd)) | ||
237 | return -ETIMEDOUT; | ||
238 | |||
239 | /* | ||
240 | * NOTE: | ||
241 | * wIndex shows the port number and begins from 1. | ||
242 | */ | ||
243 | usbip_dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue, | ||
244 | wIndex); | ||
245 | if (wIndex > VHCI_NPORTS) | ||
246 | pr_err("invalid port number %d\n", wIndex); | ||
247 | rhport = ((__u8)(wIndex & 0x00ff)) - 1; | ||
248 | |||
249 | dum = hcd_to_vhci(hcd); | ||
250 | |||
251 | spin_lock(&dum->lock); | ||
252 | |||
253 | /* store old status and compare now and old later */ | ||
254 | if (usbip_dbg_flag_vhci_rh) { | ||
255 | memcpy(prev_port_status, dum->port_status, | ||
256 | sizeof(prev_port_status)); | ||
257 | } | ||
258 | |||
259 | switch (typeReq) { | ||
260 | case ClearHubFeature: | ||
261 | usbip_dbg_vhci_rh(" ClearHubFeature\n"); | ||
262 | break; | ||
263 | case ClearPortFeature: | ||
264 | switch (wValue) { | ||
265 | case USB_PORT_FEAT_SUSPEND: | ||
266 | if (dum->port_status[rhport] & USB_PORT_STAT_SUSPEND) { | ||
267 | /* 20msec signaling */ | ||
268 | dum->resuming = 1; | ||
269 | dum->re_timeout = | ||
270 | jiffies + msecs_to_jiffies(20); | ||
271 | } | ||
272 | break; | ||
273 | case USB_PORT_FEAT_POWER: | ||
274 | usbip_dbg_vhci_rh( | ||
275 | " ClearPortFeature: USB_PORT_FEAT_POWER\n"); | ||
276 | dum->port_status[rhport] = 0; | ||
277 | dum->resuming = 0; | ||
278 | break; | ||
279 | case USB_PORT_FEAT_C_RESET: | ||
280 | usbip_dbg_vhci_rh( | ||
281 | " ClearPortFeature: USB_PORT_FEAT_C_RESET\n"); | ||
282 | switch (dum->vdev[rhport].speed) { | ||
283 | case USB_SPEED_HIGH: | ||
284 | dum->port_status[rhport] |= | ||
285 | USB_PORT_STAT_HIGH_SPEED; | ||
286 | break; | ||
287 | case USB_SPEED_LOW: | ||
288 | dum->port_status[rhport] |= | ||
289 | USB_PORT_STAT_LOW_SPEED; | ||
290 | break; | ||
291 | default: | ||
292 | break; | ||
293 | } | ||
294 | default: | ||
295 | usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n", | ||
296 | wValue); | ||
297 | dum->port_status[rhport] &= ~(1 << wValue); | ||
298 | break; | ||
299 | } | ||
300 | break; | ||
301 | case GetHubDescriptor: | ||
302 | usbip_dbg_vhci_rh(" GetHubDescriptor\n"); | ||
303 | hub_descriptor((struct usb_hub_descriptor *) buf); | ||
304 | break; | ||
305 | case GetHubStatus: | ||
306 | usbip_dbg_vhci_rh(" GetHubStatus\n"); | ||
307 | *(__le32 *) buf = cpu_to_le32(0); | ||
308 | break; | ||
309 | case GetPortStatus: | ||
310 | usbip_dbg_vhci_rh(" GetPortStatus port %x\n", wIndex); | ||
311 | if (wIndex > VHCI_NPORTS || wIndex < 1) { | ||
312 | pr_err("invalid port number %d\n", wIndex); | ||
313 | retval = -EPIPE; | ||
314 | } | ||
315 | |||
316 | /* we do not care about resume. */ | ||
317 | |||
318 | /* whoever resets or resumes must GetPortStatus to | ||
319 | * complete it!! | ||
320 | */ | ||
321 | if (dum->resuming && time_after(jiffies, dum->re_timeout)) { | ||
322 | dum->port_status[rhport] |= | ||
323 | (1 << USB_PORT_FEAT_C_SUSPEND); | ||
324 | dum->port_status[rhport] &= | ||
325 | ~(1 << USB_PORT_FEAT_SUSPEND); | ||
326 | dum->resuming = 0; | ||
327 | dum->re_timeout = 0; | ||
328 | } | ||
329 | |||
330 | if ((dum->port_status[rhport] & (1 << USB_PORT_FEAT_RESET)) != | ||
331 | 0 && time_after(jiffies, dum->re_timeout)) { | ||
332 | dum->port_status[rhport] |= | ||
333 | (1 << USB_PORT_FEAT_C_RESET); | ||
334 | dum->port_status[rhport] &= | ||
335 | ~(1 << USB_PORT_FEAT_RESET); | ||
336 | dum->re_timeout = 0; | ||
337 | |||
338 | if (dum->vdev[rhport].ud.status == | ||
339 | VDEV_ST_NOTASSIGNED) { | ||
340 | usbip_dbg_vhci_rh( | ||
341 | " enable rhport %d (status %u)\n", | ||
342 | rhport, | ||
343 | dum->vdev[rhport].ud.status); | ||
344 | dum->port_status[rhport] |= | ||
345 | USB_PORT_STAT_ENABLE; | ||
346 | } | ||
347 | } | ||
348 | ((__le16 *) buf)[0] = cpu_to_le16(dum->port_status[rhport]); | ||
349 | ((__le16 *) buf)[1] = | ||
350 | cpu_to_le16(dum->port_status[rhport] >> 16); | ||
351 | |||
352 | usbip_dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0], | ||
353 | ((u16 *)buf)[1]); | ||
354 | break; | ||
355 | case SetHubFeature: | ||
356 | usbip_dbg_vhci_rh(" SetHubFeature\n"); | ||
357 | retval = -EPIPE; | ||
358 | break; | ||
359 | case SetPortFeature: | ||
360 | switch (wValue) { | ||
361 | case USB_PORT_FEAT_SUSPEND: | ||
362 | usbip_dbg_vhci_rh( | ||
363 | " SetPortFeature: USB_PORT_FEAT_SUSPEND\n"); | ||
364 | break; | ||
365 | case USB_PORT_FEAT_RESET: | ||
366 | usbip_dbg_vhci_rh( | ||
367 | " SetPortFeature: USB_PORT_FEAT_RESET\n"); | ||
368 | /* if it's already running, disconnect first */ | ||
369 | if (dum->port_status[rhport] & USB_PORT_STAT_ENABLE) { | ||
370 | dum->port_status[rhport] &= | ||
371 | ~(USB_PORT_STAT_ENABLE | | ||
372 | USB_PORT_STAT_LOW_SPEED | | ||
373 | USB_PORT_STAT_HIGH_SPEED); | ||
374 | /* FIXME test that code path! */ | ||
375 | } | ||
376 | /* 50msec reset signaling */ | ||
377 | dum->re_timeout = jiffies + msecs_to_jiffies(50); | ||
378 | |||
379 | /* FALLTHROUGH */ | ||
380 | default: | ||
381 | usbip_dbg_vhci_rh(" SetPortFeature: default %d\n", | ||
382 | wValue); | ||
383 | dum->port_status[rhport] |= (1 << wValue); | ||
384 | break; | ||
385 | } | ||
386 | break; | ||
387 | |||
388 | default: | ||
389 | pr_err("default: no such request\n"); | ||
390 | |||
391 | /* "protocol stall" on error */ | ||
392 | retval = -EPIPE; | ||
393 | } | ||
394 | |||
395 | if (usbip_dbg_flag_vhci_rh) { | ||
396 | pr_debug("port %d\n", rhport); | ||
397 | /* Only dump valid port status */ | ||
398 | if (rhport >= 0) { | ||
399 | dump_port_status_diff(prev_port_status[rhport], | ||
400 | dum->port_status[rhport]); | ||
401 | } | ||
402 | } | ||
403 | usbip_dbg_vhci_rh(" bye\n"); | ||
404 | |||
405 | spin_unlock(&dum->lock); | ||
406 | |||
407 | return retval; | ||
408 | } | ||
409 | |||
410 | static struct vhci_device *get_vdev(struct usb_device *udev) | ||
411 | { | ||
412 | int i; | ||
413 | |||
414 | if (!udev) | ||
415 | return NULL; | ||
416 | |||
417 | for (i = 0; i < VHCI_NPORTS; i++) | ||
418 | if (the_controller->vdev[i].udev == udev) | ||
419 | return port_to_vdev(i); | ||
420 | |||
421 | return NULL; | ||
422 | } | ||
423 | |||
424 | static void vhci_tx_urb(struct urb *urb) | ||
425 | { | ||
426 | struct vhci_device *vdev = get_vdev(urb->dev); | ||
427 | struct vhci_priv *priv; | ||
428 | |||
429 | if (!vdev) { | ||
430 | pr_err("could not get virtual device"); | ||
431 | return; | ||
432 | } | ||
433 | |||
434 | priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC); | ||
435 | if (!priv) { | ||
436 | usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); | ||
437 | return; | ||
438 | } | ||
439 | |||
440 | spin_lock(&vdev->priv_lock); | ||
441 | |||
442 | priv->seqnum = atomic_inc_return(&the_controller->seqnum); | ||
443 | if (priv->seqnum == 0xffff) | ||
444 | dev_info(&urb->dev->dev, "seqnum max\n"); | ||
445 | |||
446 | priv->vdev = vdev; | ||
447 | priv->urb = urb; | ||
448 | |||
449 | urb->hcpriv = (void *) priv; | ||
450 | |||
451 | list_add_tail(&priv->list, &vdev->priv_tx); | ||
452 | |||
453 | wake_up(&vdev->waitq_tx); | ||
454 | spin_unlock(&vdev->priv_lock); | ||
455 | } | ||
456 | |||
457 | static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | ||
458 | gfp_t mem_flags) | ||
459 | { | ||
460 | struct device *dev = &urb->dev->dev; | ||
461 | int ret = 0; | ||
462 | struct vhci_device *vdev; | ||
463 | |||
464 | usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", | ||
465 | hcd, urb, mem_flags); | ||
466 | |||
467 | /* patch to usb_sg_init() is in 2.5.60 */ | ||
468 | BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length); | ||
469 | |||
470 | spin_lock(&the_controller->lock); | ||
471 | |||
472 | if (urb->status != -EINPROGRESS) { | ||
473 | dev_err(dev, "URB already unlinked!, status %d\n", urb->status); | ||
474 | spin_unlock(&the_controller->lock); | ||
475 | return urb->status; | ||
476 | } | ||
477 | |||
478 | vdev = port_to_vdev(urb->dev->portnum-1); | ||
479 | |||
480 | /* refuse enqueue for dead connection */ | ||
481 | spin_lock(&vdev->ud.lock); | ||
482 | if (vdev->ud.status == VDEV_ST_NULL || | ||
483 | vdev->ud.status == VDEV_ST_ERROR) { | ||
484 | dev_err(dev, "enqueue for inactive port %d\n", vdev->rhport); | ||
485 | spin_unlock(&vdev->ud.lock); | ||
486 | spin_unlock(&the_controller->lock); | ||
487 | return -ENODEV; | ||
488 | } | ||
489 | spin_unlock(&vdev->ud.lock); | ||
490 | |||
491 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | ||
492 | if (ret) | ||
493 | goto no_need_unlink; | ||
494 | |||
495 | /* | ||
496 | * The enumeration process is as follows; | ||
497 | * | ||
498 | * 1. Get_Descriptor request to DevAddrs(0) EndPoint(0) | ||
499 | * to get max packet length of default pipe | ||
500 | * | ||
501 | * 2. Set_Address request to DevAddr(0) EndPoint(0) | ||
502 | * | ||
503 | */ | ||
504 | if (usb_pipedevice(urb->pipe) == 0) { | ||
505 | __u8 type = usb_pipetype(urb->pipe); | ||
506 | struct usb_ctrlrequest *ctrlreq = | ||
507 | (struct usb_ctrlrequest *) urb->setup_packet; | ||
508 | |||
509 | if (type != PIPE_CONTROL || !ctrlreq) { | ||
510 | dev_err(dev, "invalid request to devnum 0\n"); | ||
511 | ret = -EINVAL; | ||
512 | goto no_need_xmit; | ||
513 | } | ||
514 | |||
515 | switch (ctrlreq->bRequest) { | ||
516 | case USB_REQ_SET_ADDRESS: | ||
517 | /* set_address may come when a device is reset */ | ||
518 | dev_info(dev, "SetAddress Request (%d) to port %d\n", | ||
519 | ctrlreq->wValue, vdev->rhport); | ||
520 | |||
521 | if (vdev->udev) | ||
522 | usb_put_dev(vdev->udev); | ||
523 | vdev->udev = usb_get_dev(urb->dev); | ||
524 | |||
525 | spin_lock(&vdev->ud.lock); | ||
526 | vdev->ud.status = VDEV_ST_USED; | ||
527 | spin_unlock(&vdev->ud.lock); | ||
528 | |||
529 | if (urb->status == -EINPROGRESS) { | ||
530 | /* This request is successfully completed. */ | ||
531 | /* If not -EINPROGRESS, possibly unlinked. */ | ||
532 | urb->status = 0; | ||
533 | } | ||
534 | |||
535 | goto no_need_xmit; | ||
536 | |||
537 | case USB_REQ_GET_DESCRIPTOR: | ||
538 | if (ctrlreq->wValue == cpu_to_le16(USB_DT_DEVICE << 8)) | ||
539 | usbip_dbg_vhci_hc( | ||
540 | "Not yet?:Get_Descriptor to device 0 (get max pipe size)\n"); | ||
541 | |||
542 | if (vdev->udev) | ||
543 | usb_put_dev(vdev->udev); | ||
544 | vdev->udev = usb_get_dev(urb->dev); | ||
545 | goto out; | ||
546 | |||
547 | default: | ||
548 | /* NOT REACHED */ | ||
549 | dev_err(dev, | ||
550 | "invalid request to devnum 0 bRequest %u, wValue %u\n", | ||
551 | ctrlreq->bRequest, | ||
552 | ctrlreq->wValue); | ||
553 | ret = -EINVAL; | ||
554 | goto no_need_xmit; | ||
555 | } | ||
556 | |||
557 | } | ||
558 | |||
559 | out: | ||
560 | vhci_tx_urb(urb); | ||
561 | spin_unlock(&the_controller->lock); | ||
562 | |||
563 | return 0; | ||
564 | |||
565 | no_need_xmit: | ||
566 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
567 | no_need_unlink: | ||
568 | spin_unlock(&the_controller->lock); | ||
569 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); | ||
570 | return ret; | ||
571 | } | ||
572 | |||
573 | /* | ||
574 | * vhci_rx gives back the urb after receiving the reply of the urb. If an | ||
575 | * unlink pdu is sent or not, vhci_rx receives a normal return pdu and gives | ||
576 | * back its urb. For the driver unlinking the urb, the content of the urb is | ||
577 | * not important, but the calling to its completion handler is important; the | ||
578 | * completion of unlinking is notified by the completion handler. | ||
579 | * | ||
580 | * | ||
581 | * CLIENT SIDE | ||
582 | * | ||
583 | * - When vhci_hcd receives RET_SUBMIT, | ||
584 | * | ||
585 | * - case 1a). the urb of the pdu is not unlinking. | ||
586 | * - normal case | ||
587 | * => just give back the urb | ||
588 | * | ||
589 | * - case 1b). the urb of the pdu is unlinking. | ||
590 | * - usbip.ko will return a reply of the unlinking request. | ||
591 | * => give back the urb now and go to case 2b). | ||
592 | * | ||
593 | * - When vhci_hcd receives RET_UNLINK, | ||
594 | * | ||
595 | * - case 2a). a submit request is still pending in vhci_hcd. | ||
596 | * - urb was really pending in usbip.ko and urb_unlink_urb() was | ||
597 | * completed there. | ||
598 | * => free a pending submit request | ||
599 | * => notify unlink completeness by giving back the urb | ||
600 | * | ||
601 | * - case 2b). a submit request is *not* pending in vhci_hcd. | ||
602 | * - urb was already given back to the core driver. | ||
603 | * => do not give back the urb | ||
604 | * | ||
605 | * | ||
606 | * SERVER SIDE | ||
607 | * | ||
608 | * - When usbip receives CMD_UNLINK, | ||
609 | * | ||
610 | * - case 3a). the urb of the unlink request is now in submission. | ||
611 | * => do usb_unlink_urb(). | ||
612 | * => after the unlink is completed, send RET_UNLINK. | ||
613 | * | ||
614 | * - case 3b). the urb of the unlink request is not in submission. | ||
615 | * - may be already completed or never be received | ||
616 | * => send RET_UNLINK | ||
617 | * | ||
618 | */ | ||
619 | static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | ||
620 | { | ||
621 | struct vhci_priv *priv; | ||
622 | struct vhci_device *vdev; | ||
623 | |||
624 | pr_info("dequeue a urb %p\n", urb); | ||
625 | |||
626 | spin_lock(&the_controller->lock); | ||
627 | |||
628 | priv = urb->hcpriv; | ||
629 | if (!priv) { | ||
630 | /* URB was never linked! or will be soon given back by | ||
631 | * vhci_rx. */ | ||
632 | spin_unlock(&the_controller->lock); | ||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | { | ||
637 | int ret = 0; | ||
638 | |||
639 | ret = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
640 | if (ret) { | ||
641 | spin_unlock(&the_controller->lock); | ||
642 | return ret; | ||
643 | } | ||
644 | } | ||
645 | |||
646 | /* send unlink request here? */ | ||
647 | vdev = priv->vdev; | ||
648 | |||
649 | if (!vdev->ud.tcp_socket) { | ||
650 | /* tcp connection is closed */ | ||
651 | spin_lock(&vdev->priv_lock); | ||
652 | |||
653 | pr_info("device %p seems to be disconnected\n", vdev); | ||
654 | list_del(&priv->list); | ||
655 | kfree(priv); | ||
656 | urb->hcpriv = NULL; | ||
657 | |||
658 | spin_unlock(&vdev->priv_lock); | ||
659 | |||
660 | /* | ||
661 | * If tcp connection is alive, we have sent CMD_UNLINK. | ||
662 | * vhci_rx will receive RET_UNLINK and give back the URB. | ||
663 | * Otherwise, we give back it here. | ||
664 | */ | ||
665 | pr_info("gives back urb %p\n", urb); | ||
666 | |||
667 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
668 | |||
669 | spin_unlock(&the_controller->lock); | ||
670 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, | ||
671 | urb->status); | ||
672 | spin_lock(&the_controller->lock); | ||
673 | |||
674 | } else { | ||
675 | /* tcp connection is alive */ | ||
676 | struct vhci_unlink *unlink; | ||
677 | |||
678 | spin_lock(&vdev->priv_lock); | ||
679 | |||
680 | /* setup CMD_UNLINK pdu */ | ||
681 | unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC); | ||
682 | if (!unlink) { | ||
683 | spin_unlock(&vdev->priv_lock); | ||
684 | spin_unlock(&the_controller->lock); | ||
685 | usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); | ||
686 | return -ENOMEM; | ||
687 | } | ||
688 | |||
689 | unlink->seqnum = atomic_inc_return(&the_controller->seqnum); | ||
690 | if (unlink->seqnum == 0xffff) | ||
691 | pr_info("seqnum max\n"); | ||
692 | |||
693 | unlink->unlink_seqnum = priv->seqnum; | ||
694 | |||
695 | pr_info("device %p seems to be still connected\n", vdev); | ||
696 | |||
697 | /* send cmd_unlink and try to cancel the pending URB in the | ||
698 | * peer */ | ||
699 | list_add_tail(&unlink->list, &vdev->unlink_tx); | ||
700 | wake_up(&vdev->waitq_tx); | ||
701 | |||
702 | spin_unlock(&vdev->priv_lock); | ||
703 | } | ||
704 | |||
705 | spin_unlock(&the_controller->lock); | ||
706 | |||
707 | usbip_dbg_vhci_hc("leave\n"); | ||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | static void vhci_device_unlink_cleanup(struct vhci_device *vdev) | ||
712 | { | ||
713 | struct vhci_unlink *unlink, *tmp; | ||
714 | |||
715 | spin_lock(&the_controller->lock); | ||
716 | spin_lock(&vdev->priv_lock); | ||
717 | |||
718 | list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { | ||
719 | pr_info("unlink cleanup tx %lu\n", unlink->unlink_seqnum); | ||
720 | list_del(&unlink->list); | ||
721 | kfree(unlink); | ||
722 | } | ||
723 | |||
724 | while (!list_empty(&vdev->unlink_rx)) { | ||
725 | struct urb *urb; | ||
726 | |||
727 | unlink = list_first_entry(&vdev->unlink_rx, struct vhci_unlink, | ||
728 | list); | ||
729 | |||
730 | /* give back URB of unanswered unlink request */ | ||
731 | pr_info("unlink cleanup rx %lu\n", unlink->unlink_seqnum); | ||
732 | |||
733 | urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum); | ||
734 | if (!urb) { | ||
735 | pr_info("the urb (seqnum %lu) was already given back\n", | ||
736 | unlink->unlink_seqnum); | ||
737 | list_del(&unlink->list); | ||
738 | kfree(unlink); | ||
739 | continue; | ||
740 | } | ||
741 | |||
742 | urb->status = -ENODEV; | ||
743 | |||
744 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); | ||
745 | |||
746 | list_del(&unlink->list); | ||
747 | |||
748 | spin_unlock(&vdev->priv_lock); | ||
749 | spin_unlock(&the_controller->lock); | ||
750 | |||
751 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, | ||
752 | urb->status); | ||
753 | |||
754 | spin_lock(&the_controller->lock); | ||
755 | spin_lock(&vdev->priv_lock); | ||
756 | |||
757 | kfree(unlink); | ||
758 | } | ||
759 | |||
760 | spin_unlock(&vdev->priv_lock); | ||
761 | spin_unlock(&the_controller->lock); | ||
762 | } | ||
763 | |||
764 | /* | ||
765 | * The important thing is that only one context begins cleanup. | ||
766 | * This is why error handling and cleanup become simple. | ||
767 | * We do not want to consider race condition as possible. | ||
768 | */ | ||
769 | static void vhci_shutdown_connection(struct usbip_device *ud) | ||
770 | { | ||
771 | struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); | ||
772 | |||
773 | /* need this? see stub_dev.c */ | ||
774 | if (ud->tcp_socket) { | ||
775 | pr_debug("shutdown tcp_socket %p\n", ud->tcp_socket); | ||
776 | kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR); | ||
777 | } | ||
778 | |||
779 | /* kill threads related to this sdev */ | ||
780 | if (vdev->ud.tcp_rx) { | ||
781 | kthread_stop_put(vdev->ud.tcp_rx); | ||
782 | vdev->ud.tcp_rx = NULL; | ||
783 | } | ||
784 | if (vdev->ud.tcp_tx) { | ||
785 | kthread_stop_put(vdev->ud.tcp_tx); | ||
786 | vdev->ud.tcp_tx = NULL; | ||
787 | } | ||
788 | pr_info("stop threads\n"); | ||
789 | |||
790 | /* active connection is closed */ | ||
791 | if (vdev->ud.tcp_socket) { | ||
792 | sockfd_put(vdev->ud.tcp_socket); | ||
793 | vdev->ud.tcp_socket = NULL; | ||
794 | } | ||
795 | pr_info("release socket\n"); | ||
796 | |||
797 | vhci_device_unlink_cleanup(vdev); | ||
798 | |||
799 | /* | ||
800 | * rh_port_disconnect() is a trigger of ... | ||
801 | * usb_disable_device(): | ||
802 | * disable all the endpoints for a USB device. | ||
803 | * usb_disable_endpoint(): | ||
804 | * disable endpoints. pending urbs are unlinked(dequeued). | ||
805 | * | ||
806 | * NOTE: After calling rh_port_disconnect(), the USB device drivers of a | ||
807 | * detached device should release used urbs in a cleanup function (i.e. | ||
808 | * xxx_disconnect()). Therefore, vhci_hcd does not need to release | ||
809 | * pushed urbs and their private data in this function. | ||
810 | * | ||
811 | * NOTE: vhci_dequeue() must be considered carefully. When shutting down | ||
812 | * a connection, vhci_shutdown_connection() expects vhci_dequeue() | ||
813 | * gives back pushed urbs and frees their private data by request of | ||
814 | * the cleanup function of a USB driver. When unlinking a urb with an | ||
815 | * active connection, vhci_dequeue() does not give back the urb which | ||
816 | * is actually given back by vhci_rx after receiving its return pdu. | ||
817 | * | ||
818 | */ | ||
819 | rh_port_disconnect(vdev->rhport); | ||
820 | |||
821 | pr_info("disconnect device\n"); | ||
822 | } | ||
823 | |||
824 | |||
825 | static void vhci_device_reset(struct usbip_device *ud) | ||
826 | { | ||
827 | struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); | ||
828 | |||
829 | spin_lock(&ud->lock); | ||
830 | |||
831 | vdev->speed = 0; | ||
832 | vdev->devid = 0; | ||
833 | |||
834 | if (vdev->udev) | ||
835 | usb_put_dev(vdev->udev); | ||
836 | vdev->udev = NULL; | ||
837 | |||
838 | if (ud->tcp_socket) { | ||
839 | sockfd_put(ud->tcp_socket); | ||
840 | ud->tcp_socket = NULL; | ||
841 | } | ||
842 | ud->status = VDEV_ST_NULL; | ||
843 | |||
844 | spin_unlock(&ud->lock); | ||
845 | } | ||
846 | |||
847 | static void vhci_device_unusable(struct usbip_device *ud) | ||
848 | { | ||
849 | spin_lock(&ud->lock); | ||
850 | ud->status = VDEV_ST_ERROR; | ||
851 | spin_unlock(&ud->lock); | ||
852 | } | ||
853 | |||
854 | static void vhci_device_init(struct vhci_device *vdev) | ||
855 | { | ||
856 | memset(vdev, 0, sizeof(*vdev)); | ||
857 | |||
858 | vdev->ud.side = USBIP_VHCI; | ||
859 | vdev->ud.status = VDEV_ST_NULL; | ||
860 | spin_lock_init(&vdev->ud.lock); | ||
861 | |||
862 | INIT_LIST_HEAD(&vdev->priv_rx); | ||
863 | INIT_LIST_HEAD(&vdev->priv_tx); | ||
864 | INIT_LIST_HEAD(&vdev->unlink_tx); | ||
865 | INIT_LIST_HEAD(&vdev->unlink_rx); | ||
866 | spin_lock_init(&vdev->priv_lock); | ||
867 | |||
868 | init_waitqueue_head(&vdev->waitq_tx); | ||
869 | |||
870 | vdev->ud.eh_ops.shutdown = vhci_shutdown_connection; | ||
871 | vdev->ud.eh_ops.reset = vhci_device_reset; | ||
872 | vdev->ud.eh_ops.unusable = vhci_device_unusable; | ||
873 | |||
874 | usbip_start_eh(&vdev->ud); | ||
875 | } | ||
876 | |||
877 | static int vhci_start(struct usb_hcd *hcd) | ||
878 | { | ||
879 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); | ||
880 | int rhport; | ||
881 | int err = 0; | ||
882 | |||
883 | usbip_dbg_vhci_hc("enter vhci_start\n"); | ||
884 | |||
885 | /* initialize private data of usb_hcd */ | ||
886 | |||
887 | for (rhport = 0; rhport < VHCI_NPORTS; rhport++) { | ||
888 | struct vhci_device *vdev = &vhci->vdev[rhport]; | ||
889 | |||
890 | vhci_device_init(vdev); | ||
891 | vdev->rhport = rhport; | ||
892 | } | ||
893 | |||
894 | atomic_set(&vhci->seqnum, 0); | ||
895 | spin_lock_init(&vhci->lock); | ||
896 | |||
897 | hcd->power_budget = 0; /* no limit */ | ||
898 | hcd->uses_new_polling = 1; | ||
899 | |||
900 | /* vhci_hcd is now ready to be controlled through sysfs */ | ||
901 | err = sysfs_create_group(&vhci_dev(vhci)->kobj, &dev_attr_group); | ||
902 | if (err) { | ||
903 | pr_err("create sysfs files\n"); | ||
904 | return err; | ||
905 | } | ||
906 | |||
907 | return 0; | ||
908 | } | ||
909 | |||
910 | static void vhci_stop(struct usb_hcd *hcd) | ||
911 | { | ||
912 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); | ||
913 | int rhport = 0; | ||
914 | |||
915 | usbip_dbg_vhci_hc("stop VHCI controller\n"); | ||
916 | |||
917 | /* 1. remove the userland interface of vhci_hcd */ | ||
918 | sysfs_remove_group(&vhci_dev(vhci)->kobj, &dev_attr_group); | ||
919 | |||
920 | /* 2. shutdown all the ports of vhci_hcd */ | ||
921 | for (rhport = 0; rhport < VHCI_NPORTS; rhport++) { | ||
922 | struct vhci_device *vdev = &vhci->vdev[rhport]; | ||
923 | |||
924 | usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED); | ||
925 | usbip_stop_eh(&vdev->ud); | ||
926 | } | ||
927 | } | ||
928 | |||
929 | static int vhci_get_frame_number(struct usb_hcd *hcd) | ||
930 | { | ||
931 | pr_err("Not yet implemented\n"); | ||
932 | return 0; | ||
933 | } | ||
934 | |||
935 | #ifdef CONFIG_PM | ||
936 | |||
937 | /* FIXME: suspend/resume */ | ||
938 | static int vhci_bus_suspend(struct usb_hcd *hcd) | ||
939 | { | ||
940 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); | ||
941 | |||
942 | dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); | ||
943 | |||
944 | spin_lock(&vhci->lock); | ||
945 | hcd->state = HC_STATE_SUSPENDED; | ||
946 | spin_unlock(&vhci->lock); | ||
947 | |||
948 | return 0; | ||
949 | } | ||
950 | |||
951 | static int vhci_bus_resume(struct usb_hcd *hcd) | ||
952 | { | ||
953 | struct vhci_hcd *vhci = hcd_to_vhci(hcd); | ||
954 | int rc = 0; | ||
955 | |||
956 | dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); | ||
957 | |||
958 | spin_lock(&vhci->lock); | ||
959 | if (!HCD_HW_ACCESSIBLE(hcd)) | ||
960 | rc = -ESHUTDOWN; | ||
961 | else | ||
962 | hcd->state = HC_STATE_RUNNING; | ||
963 | spin_unlock(&vhci->lock); | ||
964 | |||
965 | return rc; | ||
966 | } | ||
967 | |||
968 | #else | ||
969 | |||
970 | #define vhci_bus_suspend NULL | ||
971 | #define vhci_bus_resume NULL | ||
972 | #endif | ||
973 | |||
974 | static struct hc_driver vhci_hc_driver = { | ||
975 | .description = driver_name, | ||
976 | .product_desc = driver_desc, | ||
977 | .hcd_priv_size = sizeof(struct vhci_hcd), | ||
978 | |||
979 | .flags = HCD_USB2, | ||
980 | |||
981 | .start = vhci_start, | ||
982 | .stop = vhci_stop, | ||
983 | |||
984 | .urb_enqueue = vhci_urb_enqueue, | ||
985 | .urb_dequeue = vhci_urb_dequeue, | ||
986 | |||
987 | .get_frame_number = vhci_get_frame_number, | ||
988 | |||
989 | .hub_status_data = vhci_hub_status, | ||
990 | .hub_control = vhci_hub_control, | ||
991 | .bus_suspend = vhci_bus_suspend, | ||
992 | .bus_resume = vhci_bus_resume, | ||
993 | }; | ||
994 | |||
995 | static int vhci_hcd_probe(struct platform_device *pdev) | ||
996 | { | ||
997 | struct usb_hcd *hcd; | ||
998 | int ret; | ||
999 | |||
1000 | usbip_dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id); | ||
1001 | |||
1002 | /* | ||
1003 | * Allocate and initialize hcd. | ||
1004 | * Our private data is also allocated automatically. | ||
1005 | */ | ||
1006 | hcd = usb_create_hcd(&vhci_hc_driver, &pdev->dev, dev_name(&pdev->dev)); | ||
1007 | if (!hcd) { | ||
1008 | pr_err("create hcd failed\n"); | ||
1009 | return -ENOMEM; | ||
1010 | } | ||
1011 | hcd->has_tt = 1; | ||
1012 | |||
1013 | /* this is private data for vhci_hcd */ | ||
1014 | the_controller = hcd_to_vhci(hcd); | ||
1015 | |||
1016 | /* | ||
1017 | * Finish generic HCD structure initialization and register. | ||
1018 | * Call the driver's reset() and start() routines. | ||
1019 | */ | ||
1020 | ret = usb_add_hcd(hcd, 0, 0); | ||
1021 | if (ret != 0) { | ||
1022 | pr_err("usb_add_hcd failed %d\n", ret); | ||
1023 | usb_put_hcd(hcd); | ||
1024 | the_controller = NULL; | ||
1025 | return ret; | ||
1026 | } | ||
1027 | |||
1028 | usbip_dbg_vhci_hc("bye\n"); | ||
1029 | return 0; | ||
1030 | } | ||
1031 | |||
1032 | static int vhci_hcd_remove(struct platform_device *pdev) | ||
1033 | { | ||
1034 | struct usb_hcd *hcd; | ||
1035 | |||
1036 | hcd = platform_get_drvdata(pdev); | ||
1037 | if (!hcd) | ||
1038 | return 0; | ||
1039 | |||
1040 | /* | ||
1041 | * Disconnects the root hub, | ||
1042 | * then reverses the effects of usb_add_hcd(), | ||
1043 | * invoking the HCD's stop() methods. | ||
1044 | */ | ||
1045 | usb_remove_hcd(hcd); | ||
1046 | usb_put_hcd(hcd); | ||
1047 | the_controller = NULL; | ||
1048 | |||
1049 | return 0; | ||
1050 | } | ||
1051 | |||
1052 | #ifdef CONFIG_PM | ||
1053 | |||
1054 | /* what should happen for USB/IP under suspend/resume? */ | ||
1055 | static int vhci_hcd_suspend(struct platform_device *pdev, pm_message_t state) | ||
1056 | { | ||
1057 | struct usb_hcd *hcd; | ||
1058 | int rhport = 0; | ||
1059 | int connected = 0; | ||
1060 | int ret = 0; | ||
1061 | |||
1062 | hcd = platform_get_drvdata(pdev); | ||
1063 | |||
1064 | spin_lock(&the_controller->lock); | ||
1065 | |||
1066 | for (rhport = 0; rhport < VHCI_NPORTS; rhport++) | ||
1067 | if (the_controller->port_status[rhport] & | ||
1068 | USB_PORT_STAT_CONNECTION) | ||
1069 | connected += 1; | ||
1070 | |||
1071 | spin_unlock(&the_controller->lock); | ||
1072 | |||
1073 | if (connected > 0) { | ||
1074 | dev_info(&pdev->dev, | ||
1075 | "We have %d active connection%s. Do not suspend.\n", | ||
1076 | connected, (connected == 1 ? "" : "s")); | ||
1077 | ret = -EBUSY; | ||
1078 | } else { | ||
1079 | dev_info(&pdev->dev, "suspend vhci_hcd"); | ||
1080 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
1081 | } | ||
1082 | |||
1083 | return ret; | ||
1084 | } | ||
1085 | |||
1086 | static int vhci_hcd_resume(struct platform_device *pdev) | ||
1087 | { | ||
1088 | struct usb_hcd *hcd; | ||
1089 | |||
1090 | dev_dbg(&pdev->dev, "%s\n", __func__); | ||
1091 | |||
1092 | hcd = platform_get_drvdata(pdev); | ||
1093 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
1094 | usb_hcd_poll_rh_status(hcd); | ||
1095 | |||
1096 | return 0; | ||
1097 | } | ||
1098 | |||
1099 | #else | ||
1100 | |||
1101 | #define vhci_hcd_suspend NULL | ||
1102 | #define vhci_hcd_resume NULL | ||
1103 | |||
1104 | #endif | ||
1105 | |||
1106 | static struct platform_driver vhci_driver = { | ||
1107 | .probe = vhci_hcd_probe, | ||
1108 | .remove = vhci_hcd_remove, | ||
1109 | .suspend = vhci_hcd_suspend, | ||
1110 | .resume = vhci_hcd_resume, | ||
1111 | .driver = { | ||
1112 | .name = driver_name, | ||
1113 | .owner = THIS_MODULE, | ||
1114 | }, | ||
1115 | }; | ||
1116 | |||
1117 | /* | ||
1118 | * The VHCI 'device' is 'virtual'; not a real plug&play hardware. | ||
1119 | * We need to add this virtual device as a platform device arbitrarily: | ||
1120 | * 1. platform_device_register() | ||
1121 | */ | ||
1122 | static void the_pdev_release(struct device *dev) | ||
1123 | { | ||
1124 | } | ||
1125 | |||
1126 | static struct platform_device the_pdev = { | ||
1127 | /* should be the same name as driver_name */ | ||
1128 | .name = driver_name, | ||
1129 | .id = -1, | ||
1130 | .dev = { | ||
1131 | .release = the_pdev_release, | ||
1132 | }, | ||
1133 | }; | ||
1134 | |||
1135 | static int __init vhci_hcd_init(void) | ||
1136 | { | ||
1137 | int ret; | ||
1138 | |||
1139 | if (usb_disabled()) | ||
1140 | return -ENODEV; | ||
1141 | |||
1142 | ret = platform_driver_register(&vhci_driver); | ||
1143 | if (ret) | ||
1144 | goto err_driver_register; | ||
1145 | |||
1146 | ret = platform_device_register(&the_pdev); | ||
1147 | if (ret) | ||
1148 | goto err_platform_device_register; | ||
1149 | |||
1150 | pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); | ||
1151 | return ret; | ||
1152 | |||
1153 | err_platform_device_register: | ||
1154 | platform_driver_unregister(&vhci_driver); | ||
1155 | err_driver_register: | ||
1156 | return ret; | ||
1157 | } | ||
1158 | |||
1159 | static void __exit vhci_hcd_exit(void) | ||
1160 | { | ||
1161 | platform_device_unregister(&the_pdev); | ||
1162 | platform_driver_unregister(&vhci_driver); | ||
1163 | } | ||
1164 | |||
1165 | module_init(vhci_hcd_init); | ||
1166 | module_exit(vhci_hcd_exit); | ||
1167 | |||
1168 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
1169 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
1170 | MODULE_LICENSE("GPL"); | ||
1171 | MODULE_VERSION(USBIP_VERSION); | ||
diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c deleted file mode 100644 index 00e4a54308e4..000000000000 --- a/drivers/staging/usbip/vhci_rx.c +++ /dev/null | |||
@@ -1,268 +0,0 @@ | |||
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/kthread.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | #include "usbip_common.h" | ||
24 | #include "vhci.h" | ||
25 | |||
26 | /* get URB from transmitted urb queue. caller must hold vdev->priv_lock */ | ||
27 | struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum) | ||
28 | { | ||
29 | struct vhci_priv *priv, *tmp; | ||
30 | struct urb *urb = NULL; | ||
31 | int status; | ||
32 | |||
33 | list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) { | ||
34 | if (priv->seqnum != seqnum) | ||
35 | continue; | ||
36 | |||
37 | urb = priv->urb; | ||
38 | status = urb->status; | ||
39 | |||
40 | usbip_dbg_vhci_rx("find urb %p vurb %p seqnum %u\n", | ||
41 | urb, priv, seqnum); | ||
42 | |||
43 | switch (status) { | ||
44 | case -ENOENT: | ||
45 | /* fall through */ | ||
46 | case -ECONNRESET: | ||
47 | dev_info(&urb->dev->dev, | ||
48 | "urb %p was unlinked %ssynchronuously.\n", urb, | ||
49 | status == -ENOENT ? "" : "a"); | ||
50 | break; | ||
51 | case -EINPROGRESS: | ||
52 | /* no info output */ | ||
53 | break; | ||
54 | default: | ||
55 | dev_info(&urb->dev->dev, | ||
56 | "urb %p may be in a error, status %d\n", urb, | ||
57 | status); | ||
58 | } | ||
59 | |||
60 | list_del(&priv->list); | ||
61 | kfree(priv); | ||
62 | urb->hcpriv = NULL; | ||
63 | |||
64 | break; | ||
65 | } | ||
66 | |||
67 | return urb; | ||
68 | } | ||
69 | |||
70 | static void vhci_recv_ret_submit(struct vhci_device *vdev, | ||
71 | struct usbip_header *pdu) | ||
72 | { | ||
73 | struct usbip_device *ud = &vdev->ud; | ||
74 | struct urb *urb; | ||
75 | |||
76 | spin_lock(&vdev->priv_lock); | ||
77 | urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum); | ||
78 | spin_unlock(&vdev->priv_lock); | ||
79 | |||
80 | if (!urb) { | ||
81 | pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum); | ||
82 | pr_info("max seqnum %d\n", | ||
83 | atomic_read(&the_controller->seqnum)); | ||
84 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
85 | return; | ||
86 | } | ||
87 | |||
88 | /* unpack the pdu to a urb */ | ||
89 | usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0); | ||
90 | |||
91 | /* recv transfer buffer */ | ||
92 | if (usbip_recv_xbuff(ud, urb) < 0) | ||
93 | return; | ||
94 | |||
95 | /* recv iso_packet_descriptor */ | ||
96 | if (usbip_recv_iso(ud, urb) < 0) | ||
97 | return; | ||
98 | |||
99 | /* restore the padding in iso packets */ | ||
100 | usbip_pad_iso(ud, urb); | ||
101 | |||
102 | if (usbip_dbg_flag_vhci_rx) | ||
103 | usbip_dump_urb(urb); | ||
104 | |||
105 | usbip_dbg_vhci_rx("now giveback urb %p\n", urb); | ||
106 | |||
107 | spin_lock(&the_controller->lock); | ||
108 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); | ||
109 | spin_unlock(&the_controller->lock); | ||
110 | |||
111 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); | ||
112 | |||
113 | usbip_dbg_vhci_rx("Leave\n"); | ||
114 | } | ||
115 | |||
116 | static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev, | ||
117 | struct usbip_header *pdu) | ||
118 | { | ||
119 | struct vhci_unlink *unlink, *tmp; | ||
120 | |||
121 | spin_lock(&vdev->priv_lock); | ||
122 | |||
123 | list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) { | ||
124 | pr_info("unlink->seqnum %lu\n", unlink->seqnum); | ||
125 | if (unlink->seqnum == pdu->base.seqnum) { | ||
126 | usbip_dbg_vhci_rx("found pending unlink, %lu\n", | ||
127 | unlink->seqnum); | ||
128 | list_del(&unlink->list); | ||
129 | |||
130 | spin_unlock(&vdev->priv_lock); | ||
131 | return unlink; | ||
132 | } | ||
133 | } | ||
134 | |||
135 | spin_unlock(&vdev->priv_lock); | ||
136 | |||
137 | return NULL; | ||
138 | } | ||
139 | |||
140 | static void vhci_recv_ret_unlink(struct vhci_device *vdev, | ||
141 | struct usbip_header *pdu) | ||
142 | { | ||
143 | struct vhci_unlink *unlink; | ||
144 | struct urb *urb; | ||
145 | |||
146 | usbip_dump_header(pdu); | ||
147 | |||
148 | unlink = dequeue_pending_unlink(vdev, pdu); | ||
149 | if (!unlink) { | ||
150 | pr_info("cannot find the pending unlink %u\n", | ||
151 | pdu->base.seqnum); | ||
152 | return; | ||
153 | } | ||
154 | |||
155 | spin_lock(&vdev->priv_lock); | ||
156 | urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum); | ||
157 | spin_unlock(&vdev->priv_lock); | ||
158 | |||
159 | if (!urb) { | ||
160 | /* | ||
161 | * I get the result of a unlink request. But, it seems that I | ||
162 | * already received the result of its submit result and gave | ||
163 | * back the URB. | ||
164 | */ | ||
165 | pr_info("the urb (seqnum %d) was already given back\n", | ||
166 | pdu->base.seqnum); | ||
167 | } else { | ||
168 | usbip_dbg_vhci_rx("now giveback urb %p\n", urb); | ||
169 | |||
170 | /* If unlink is successful, status is -ECONNRESET */ | ||
171 | urb->status = pdu->u.ret_unlink.status; | ||
172 | pr_info("urb->status %d\n", urb->status); | ||
173 | |||
174 | spin_lock(&the_controller->lock); | ||
175 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); | ||
176 | spin_unlock(&the_controller->lock); | ||
177 | |||
178 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, | ||
179 | urb->status); | ||
180 | } | ||
181 | |||
182 | kfree(unlink); | ||
183 | } | ||
184 | |||
185 | static int vhci_priv_tx_empty(struct vhci_device *vdev) | ||
186 | { | ||
187 | int empty = 0; | ||
188 | |||
189 | spin_lock(&vdev->priv_lock); | ||
190 | empty = list_empty(&vdev->priv_rx); | ||
191 | spin_unlock(&vdev->priv_lock); | ||
192 | |||
193 | return empty; | ||
194 | } | ||
195 | |||
196 | /* recv a pdu */ | ||
197 | static void vhci_rx_pdu(struct usbip_device *ud) | ||
198 | { | ||
199 | int ret; | ||
200 | struct usbip_header pdu; | ||
201 | struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); | ||
202 | |||
203 | usbip_dbg_vhci_rx("Enter\n"); | ||
204 | |||
205 | memset(&pdu, 0, sizeof(pdu)); | ||
206 | |||
207 | /* receive a pdu header */ | ||
208 | ret = usbip_recv(ud->tcp_socket, &pdu, sizeof(pdu)); | ||
209 | if (ret < 0) { | ||
210 | if (ret == -ECONNRESET) | ||
211 | pr_info("connection reset by peer\n"); | ||
212 | else if (ret == -EAGAIN) { | ||
213 | /* ignore if connection was idle */ | ||
214 | if (vhci_priv_tx_empty(vdev)) | ||
215 | return; | ||
216 | pr_info("connection timed out with pending urbs\n"); | ||
217 | } else if (ret != -ERESTARTSYS) | ||
218 | pr_info("xmit failed %d\n", ret); | ||
219 | |||
220 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
221 | return; | ||
222 | } | ||
223 | if (ret == 0) { | ||
224 | pr_info("connection closed"); | ||
225 | usbip_event_add(ud, VDEV_EVENT_DOWN); | ||
226 | return; | ||
227 | } | ||
228 | if (ret != sizeof(pdu)) { | ||
229 | pr_err("received pdu size is %d, should be %d\n", ret, | ||
230 | (unsigned int)sizeof(pdu)); | ||
231 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | usbip_header_correct_endian(&pdu, 0); | ||
236 | |||
237 | if (usbip_dbg_flag_vhci_rx) | ||
238 | usbip_dump_header(&pdu); | ||
239 | |||
240 | switch (pdu.base.command) { | ||
241 | case USBIP_RET_SUBMIT: | ||
242 | vhci_recv_ret_submit(vdev, &pdu); | ||
243 | break; | ||
244 | case USBIP_RET_UNLINK: | ||
245 | vhci_recv_ret_unlink(vdev, &pdu); | ||
246 | break; | ||
247 | default: | ||
248 | /* NOT REACHED */ | ||
249 | pr_err("unknown pdu %u\n", pdu.base.command); | ||
250 | usbip_dump_header(&pdu); | ||
251 | usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); | ||
252 | break; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | int vhci_rx_loop(void *data) | ||
257 | { | ||
258 | struct usbip_device *ud = data; | ||
259 | |||
260 | while (!kthread_should_stop()) { | ||
261 | if (usbip_event_happened(ud)) | ||
262 | break; | ||
263 | |||
264 | vhci_rx_pdu(ud); | ||
265 | } | ||
266 | |||
267 | return 0; | ||
268 | } | ||
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c deleted file mode 100644 index 211f43f67ea2..000000000000 --- a/drivers/staging/usbip/vhci_sysfs.c +++ /dev/null | |||
@@ -1,252 +0,0 @@ | |||
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/kthread.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/net.h> | ||
23 | |||
24 | #include "usbip_common.h" | ||
25 | #include "vhci.h" | ||
26 | |||
27 | /* TODO: refine locking ?*/ | ||
28 | |||
29 | /* Sysfs entry to show port status */ | ||
30 | static ssize_t status_show(struct device *dev, struct device_attribute *attr, | ||
31 | char *out) | ||
32 | { | ||
33 | char *s = out; | ||
34 | int i = 0; | ||
35 | |||
36 | BUG_ON(!the_controller || !out); | ||
37 | |||
38 | spin_lock(&the_controller->lock); | ||
39 | |||
40 | /* | ||
41 | * output example: | ||
42 | * prt sta spd dev socket local_busid | ||
43 | * 000 004 000 000 c5a7bb80 1-2.3 | ||
44 | * 001 004 000 000 d8cee980 2-3.4 | ||
45 | * | ||
46 | * IP address can be retrieved from a socket pointer address by looking | ||
47 | * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a | ||
48 | * port number and its peer IP address. | ||
49 | */ | ||
50 | out += sprintf(out, | ||
51 | "prt sta spd bus dev socket local_busid\n"); | ||
52 | |||
53 | for (i = 0; i < VHCI_NPORTS; i++) { | ||
54 | struct vhci_device *vdev = port_to_vdev(i); | ||
55 | |||
56 | spin_lock(&vdev->ud.lock); | ||
57 | out += sprintf(out, "%03u %03u ", i, vdev->ud.status); | ||
58 | |||
59 | if (vdev->ud.status == VDEV_ST_USED) { | ||
60 | out += sprintf(out, "%03u %08x ", | ||
61 | vdev->speed, vdev->devid); | ||
62 | out += sprintf(out, "%16p ", vdev->ud.tcp_socket); | ||
63 | out += sprintf(out, "%s", dev_name(&vdev->udev->dev)); | ||
64 | |||
65 | } else { | ||
66 | out += sprintf(out, "000 000 000 0000000000000000 0-0"); | ||
67 | } | ||
68 | |||
69 | out += sprintf(out, "\n"); | ||
70 | spin_unlock(&vdev->ud.lock); | ||
71 | } | ||
72 | |||
73 | spin_unlock(&the_controller->lock); | ||
74 | |||
75 | return out - s; | ||
76 | } | ||
77 | static DEVICE_ATTR_RO(status); | ||
78 | |||
79 | /* Sysfs entry to shutdown a virtual connection */ | ||
80 | static int vhci_port_disconnect(__u32 rhport) | ||
81 | { | ||
82 | struct vhci_device *vdev; | ||
83 | |||
84 | usbip_dbg_vhci_sysfs("enter\n"); | ||
85 | |||
86 | /* lock */ | ||
87 | spin_lock(&the_controller->lock); | ||
88 | |||
89 | vdev = port_to_vdev(rhport); | ||
90 | |||
91 | spin_lock(&vdev->ud.lock); | ||
92 | if (vdev->ud.status == VDEV_ST_NULL) { | ||
93 | pr_err("not connected %d\n", vdev->ud.status); | ||
94 | |||
95 | /* unlock */ | ||
96 | spin_unlock(&vdev->ud.lock); | ||
97 | spin_unlock(&the_controller->lock); | ||
98 | |||
99 | return -EINVAL; | ||
100 | } | ||
101 | |||
102 | /* unlock */ | ||
103 | spin_unlock(&vdev->ud.lock); | ||
104 | spin_unlock(&the_controller->lock); | ||
105 | |||
106 | usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN); | ||
107 | |||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static ssize_t store_detach(struct device *dev, struct device_attribute *attr, | ||
112 | const char *buf, size_t count) | ||
113 | { | ||
114 | int err; | ||
115 | __u32 rhport = 0; | ||
116 | |||
117 | if (sscanf(buf, "%u", &rhport) != 1) | ||
118 | return -EINVAL; | ||
119 | |||
120 | /* check rhport */ | ||
121 | if (rhport >= VHCI_NPORTS) { | ||
122 | dev_err(dev, "invalid port %u\n", rhport); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | |||
126 | err = vhci_port_disconnect(rhport); | ||
127 | if (err < 0) | ||
128 | return -EINVAL; | ||
129 | |||
130 | usbip_dbg_vhci_sysfs("Leave\n"); | ||
131 | |||
132 | return count; | ||
133 | } | ||
134 | static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach); | ||
135 | |||
136 | /* Sysfs entry to establish a virtual connection */ | ||
137 | static int valid_args(__u32 rhport, enum usb_device_speed speed) | ||
138 | { | ||
139 | /* check rhport */ | ||
140 | if (rhport >= VHCI_NPORTS) { | ||
141 | pr_err("port %u\n", rhport); | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | |||
145 | /* check speed */ | ||
146 | switch (speed) { | ||
147 | case USB_SPEED_LOW: | ||
148 | case USB_SPEED_FULL: | ||
149 | case USB_SPEED_HIGH: | ||
150 | case USB_SPEED_WIRELESS: | ||
151 | break; | ||
152 | default: | ||
153 | pr_err("Failed attach request for unsupported USB speed: %s\n", | ||
154 | usb_speed_string(speed)); | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * To start a new USB/IP attachment, a userland program needs to setup a TCP | ||
163 | * connection and then write its socket descriptor with remote device | ||
164 | * information into this sysfs file. | ||
165 | * | ||
166 | * A remote device is virtually attached to the root-hub port of @rhport with | ||
167 | * @speed. @devid is embedded into a request to specify the remote device in a | ||
168 | * server host. | ||
169 | * | ||
170 | * write() returns 0 on success, else negative errno. | ||
171 | */ | ||
172 | static ssize_t store_attach(struct device *dev, struct device_attribute *attr, | ||
173 | const char *buf, size_t count) | ||
174 | { | ||
175 | struct vhci_device *vdev; | ||
176 | struct socket *socket; | ||
177 | int sockfd = 0; | ||
178 | __u32 rhport = 0, devid = 0, speed = 0; | ||
179 | int err; | ||
180 | |||
181 | /* | ||
182 | * @rhport: port number of vhci_hcd | ||
183 | * @sockfd: socket descriptor of an established TCP connection | ||
184 | * @devid: unique device identifier in a remote host | ||
185 | * @speed: usb device speed in a remote host | ||
186 | */ | ||
187 | if (sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed) != 4) | ||
188 | return -EINVAL; | ||
189 | |||
190 | usbip_dbg_vhci_sysfs("rhport(%u) sockfd(%u) devid(%u) speed(%u)\n", | ||
191 | rhport, sockfd, devid, speed); | ||
192 | |||
193 | /* check received parameters */ | ||
194 | if (valid_args(rhport, speed) < 0) | ||
195 | return -EINVAL; | ||
196 | |||
197 | /* Extract socket from fd. */ | ||
198 | socket = sockfd_lookup(sockfd, &err); | ||
199 | if (!socket) | ||
200 | return -EINVAL; | ||
201 | |||
202 | /* now need lock until setting vdev status as used */ | ||
203 | |||
204 | /* begin a lock */ | ||
205 | spin_lock(&the_controller->lock); | ||
206 | vdev = port_to_vdev(rhport); | ||
207 | spin_lock(&vdev->ud.lock); | ||
208 | |||
209 | if (vdev->ud.status != VDEV_ST_NULL) { | ||
210 | /* end of the lock */ | ||
211 | spin_unlock(&vdev->ud.lock); | ||
212 | spin_unlock(&the_controller->lock); | ||
213 | |||
214 | sockfd_put(socket); | ||
215 | |||
216 | dev_err(dev, "port %d already used\n", rhport); | ||
217 | return -EINVAL; | ||
218 | } | ||
219 | |||
220 | dev_info(dev, | ||
221 | "rhport(%u) sockfd(%d) devid(%u) speed(%u) speed_str(%s)\n", | ||
222 | rhport, sockfd, devid, speed, usb_speed_string(speed)); | ||
223 | |||
224 | vdev->devid = devid; | ||
225 | vdev->speed = speed; | ||
226 | vdev->ud.tcp_socket = socket; | ||
227 | vdev->ud.status = VDEV_ST_NOTASSIGNED; | ||
228 | |||
229 | spin_unlock(&vdev->ud.lock); | ||
230 | spin_unlock(&the_controller->lock); | ||
231 | /* end the lock */ | ||
232 | |||
233 | vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); | ||
234 | vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); | ||
235 | |||
236 | rh_port_connect(rhport, speed); | ||
237 | |||
238 | return count; | ||
239 | } | ||
240 | static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach); | ||
241 | |||
242 | static struct attribute *dev_attrs[] = { | ||
243 | &dev_attr_status.attr, | ||
244 | &dev_attr_detach.attr, | ||
245 | &dev_attr_attach.attr, | ||
246 | &dev_attr_usbip_debug.attr, | ||
247 | NULL, | ||
248 | }; | ||
249 | |||
250 | const struct attribute_group dev_attr_group = { | ||
251 | .attrs = dev_attrs, | ||
252 | }; | ||
diff --git a/drivers/staging/usbip/vhci_tx.c b/drivers/staging/usbip/vhci_tx.c deleted file mode 100644 index 409fd99f3257..000000000000 --- a/drivers/staging/usbip/vhci_tx.c +++ /dev/null | |||
@@ -1,224 +0,0 @@ | |||
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/kthread.h> | ||
21 | #include <linux/slab.h> | ||
22 | |||
23 | #include "usbip_common.h" | ||
24 | #include "vhci.h" | ||
25 | |||
26 | static void setup_cmd_submit_pdu(struct usbip_header *pdup, struct urb *urb) | ||
27 | { | ||
28 | struct vhci_priv *priv = ((struct vhci_priv *)urb->hcpriv); | ||
29 | struct vhci_device *vdev = priv->vdev; | ||
30 | |||
31 | usbip_dbg_vhci_tx("URB, local devnum %u, remote devid %u\n", | ||
32 | usb_pipedevice(urb->pipe), vdev->devid); | ||
33 | |||
34 | pdup->base.command = USBIP_CMD_SUBMIT; | ||
35 | pdup->base.seqnum = priv->seqnum; | ||
36 | pdup->base.devid = vdev->devid; | ||
37 | pdup->base.direction = usb_pipein(urb->pipe) ? | ||
38 | USBIP_DIR_IN : USBIP_DIR_OUT; | ||
39 | pdup->base.ep = usb_pipeendpoint(urb->pipe); | ||
40 | |||
41 | usbip_pack_pdu(pdup, urb, USBIP_CMD_SUBMIT, 1); | ||
42 | |||
43 | if (urb->setup_packet) | ||
44 | memcpy(pdup->u.cmd_submit.setup, urb->setup_packet, 8); | ||
45 | } | ||
46 | |||
47 | static struct vhci_priv *dequeue_from_priv_tx(struct vhci_device *vdev) | ||
48 | { | ||
49 | struct vhci_priv *priv, *tmp; | ||
50 | |||
51 | spin_lock(&vdev->priv_lock); | ||
52 | |||
53 | list_for_each_entry_safe(priv, tmp, &vdev->priv_tx, list) { | ||
54 | list_move_tail(&priv->list, &vdev->priv_rx); | ||
55 | spin_unlock(&vdev->priv_lock); | ||
56 | return priv; | ||
57 | } | ||
58 | |||
59 | spin_unlock(&vdev->priv_lock); | ||
60 | |||
61 | return NULL; | ||
62 | } | ||
63 | |||
64 | static int vhci_send_cmd_submit(struct vhci_device *vdev) | ||
65 | { | ||
66 | struct vhci_priv *priv = NULL; | ||
67 | |||
68 | struct msghdr msg; | ||
69 | struct kvec iov[3]; | ||
70 | size_t txsize; | ||
71 | |||
72 | size_t total_size = 0; | ||
73 | |||
74 | while ((priv = dequeue_from_priv_tx(vdev)) != NULL) { | ||
75 | int ret; | ||
76 | struct urb *urb = priv->urb; | ||
77 | struct usbip_header pdu_header; | ||
78 | struct usbip_iso_packet_descriptor *iso_buffer = NULL; | ||
79 | |||
80 | txsize = 0; | ||
81 | memset(&pdu_header, 0, sizeof(pdu_header)); | ||
82 | memset(&msg, 0, sizeof(msg)); | ||
83 | memset(&iov, 0, sizeof(iov)); | ||
84 | |||
85 | usbip_dbg_vhci_tx("setup txdata urb %p\n", urb); | ||
86 | |||
87 | /* 1. setup usbip_header */ | ||
88 | setup_cmd_submit_pdu(&pdu_header, urb); | ||
89 | usbip_header_correct_endian(&pdu_header, 1); | ||
90 | |||
91 | iov[0].iov_base = &pdu_header; | ||
92 | iov[0].iov_len = sizeof(pdu_header); | ||
93 | txsize += sizeof(pdu_header); | ||
94 | |||
95 | /* 2. setup transfer buffer */ | ||
96 | if (!usb_pipein(urb->pipe) && urb->transfer_buffer_length > 0) { | ||
97 | iov[1].iov_base = urb->transfer_buffer; | ||
98 | iov[1].iov_len = urb->transfer_buffer_length; | ||
99 | txsize += urb->transfer_buffer_length; | ||
100 | } | ||
101 | |||
102 | /* 3. setup iso_packet_descriptor */ | ||
103 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | ||
104 | ssize_t len = 0; | ||
105 | |||
106 | iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len); | ||
107 | if (!iso_buffer) { | ||
108 | usbip_event_add(&vdev->ud, | ||
109 | SDEV_EVENT_ERROR_MALLOC); | ||
110 | return -1; | ||
111 | } | ||
112 | |||
113 | iov[2].iov_base = iso_buffer; | ||
114 | iov[2].iov_len = len; | ||
115 | txsize += len; | ||
116 | } | ||
117 | |||
118 | ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 3, txsize); | ||
119 | if (ret != txsize) { | ||
120 | pr_err("sendmsg failed!, ret=%d for %zd\n", ret, | ||
121 | txsize); | ||
122 | kfree(iso_buffer); | ||
123 | usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP); | ||
124 | return -1; | ||
125 | } | ||
126 | |||
127 | kfree(iso_buffer); | ||
128 | usbip_dbg_vhci_tx("send txdata\n"); | ||
129 | |||
130 | total_size += txsize; | ||
131 | } | ||
132 | |||
133 | return total_size; | ||
134 | } | ||
135 | |||
136 | static struct vhci_unlink *dequeue_from_unlink_tx(struct vhci_device *vdev) | ||
137 | { | ||
138 | struct vhci_unlink *unlink, *tmp; | ||
139 | |||
140 | spin_lock(&vdev->priv_lock); | ||
141 | |||
142 | list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { | ||
143 | list_move_tail(&unlink->list, &vdev->unlink_rx); | ||
144 | spin_unlock(&vdev->priv_lock); | ||
145 | return unlink; | ||
146 | } | ||
147 | |||
148 | spin_unlock(&vdev->priv_lock); | ||
149 | |||
150 | return NULL; | ||
151 | } | ||
152 | |||
153 | static int vhci_send_cmd_unlink(struct vhci_device *vdev) | ||
154 | { | ||
155 | struct vhci_unlink *unlink = NULL; | ||
156 | |||
157 | struct msghdr msg; | ||
158 | struct kvec iov[3]; | ||
159 | size_t txsize; | ||
160 | |||
161 | size_t total_size = 0; | ||
162 | |||
163 | while ((unlink = dequeue_from_unlink_tx(vdev)) != NULL) { | ||
164 | int ret; | ||
165 | struct usbip_header pdu_header; | ||
166 | |||
167 | txsize = 0; | ||
168 | memset(&pdu_header, 0, sizeof(pdu_header)); | ||
169 | memset(&msg, 0, sizeof(msg)); | ||
170 | memset(&iov, 0, sizeof(iov)); | ||
171 | |||
172 | usbip_dbg_vhci_tx("setup cmd unlink, %lu\n", unlink->seqnum); | ||
173 | |||
174 | /* 1. setup usbip_header */ | ||
175 | pdu_header.base.command = USBIP_CMD_UNLINK; | ||
176 | pdu_header.base.seqnum = unlink->seqnum; | ||
177 | pdu_header.base.devid = vdev->devid; | ||
178 | pdu_header.base.ep = 0; | ||
179 | pdu_header.u.cmd_unlink.seqnum = unlink->unlink_seqnum; | ||
180 | |||
181 | usbip_header_correct_endian(&pdu_header, 1); | ||
182 | |||
183 | iov[0].iov_base = &pdu_header; | ||
184 | iov[0].iov_len = sizeof(pdu_header); | ||
185 | txsize += sizeof(pdu_header); | ||
186 | |||
187 | ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 1, txsize); | ||
188 | if (ret != txsize) { | ||
189 | pr_err("sendmsg failed!, ret=%d for %zd\n", ret, | ||
190 | txsize); | ||
191 | usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP); | ||
192 | return -1; | ||
193 | } | ||
194 | |||
195 | usbip_dbg_vhci_tx("send txdata\n"); | ||
196 | |||
197 | total_size += txsize; | ||
198 | } | ||
199 | |||
200 | return total_size; | ||
201 | } | ||
202 | |||
203 | int vhci_tx_loop(void *data) | ||
204 | { | ||
205 | struct usbip_device *ud = data; | ||
206 | struct vhci_device *vdev = container_of(ud, struct vhci_device, ud); | ||
207 | |||
208 | while (!kthread_should_stop()) { | ||
209 | if (vhci_send_cmd_submit(vdev) < 0) | ||
210 | break; | ||
211 | |||
212 | if (vhci_send_cmd_unlink(vdev) < 0) | ||
213 | break; | ||
214 | |||
215 | wait_event_interruptible(vdev->waitq_tx, | ||
216 | (!list_empty(&vdev->priv_tx) || | ||
217 | !list_empty(&vdev->unlink_tx) || | ||
218 | kthread_should_stop())); | ||
219 | |||
220 | usbip_dbg_vhci_tx("pending urbs ?, now wake up\n"); | ||
221 | } | ||
222 | |||
223 | return 0; | ||
224 | } | ||