diff options
Diffstat (limited to 'drivers/usb/usbip/usbip_common.c')
-rw-r--r-- | drivers/usb/usbip/usbip_common.c | 776 |
1 files changed, 776 insertions, 0 deletions
diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c new file mode 100644 index 000000000000..facaaf003f19 --- /dev/null +++ b/drivers/usb/usbip/usbip_common.c | |||
@@ -0,0 +1,776 @@ | |||
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); | ||