diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/include/tools/endian.h | 56 | ||||
-rw-r--r-- | tools/usb/ffs-test.c | 126 | ||||
-rw-r--r-- | tools/usb/usbip/libsrc/usbip_common.h | 2 |
3 files changed, 173 insertions, 11 deletions
diff --git a/tools/include/tools/endian.h b/tools/include/tools/endian.h new file mode 100644 index 000000000000..8001194008da --- /dev/null +++ b/tools/include/tools/endian.h | |||
@@ -0,0 +1,56 @@ | |||
1 | #ifndef _TOOLS_ENDIAN_H | ||
2 | #define _TOOLS_ENDIAN_H | ||
3 | |||
4 | #include <byteswap.h> | ||
5 | |||
6 | #if __BYTE_ORDER == __LITTLE_ENDIAN | ||
7 | |||
8 | #ifndef htole16 | ||
9 | #define htole16(x) (x) | ||
10 | #endif | ||
11 | #ifndef htole32 | ||
12 | #define htole32(x) (x) | ||
13 | #endif | ||
14 | #ifndef htole64 | ||
15 | #define htole64(x) (x) | ||
16 | #endif | ||
17 | |||
18 | #ifndef le16toh | ||
19 | #define le16toh(x) (x) | ||
20 | #endif | ||
21 | |||
22 | #ifndef le32toh | ||
23 | #define le32toh(x) (x) | ||
24 | #endif | ||
25 | |||
26 | #ifndef le64toh | ||
27 | #define le64toh(x) (x) | ||
28 | #endif | ||
29 | |||
30 | #else /* __BYTE_ORDER */ | ||
31 | |||
32 | #ifndef htole16 | ||
33 | #define htole16(x) __bswap_16(x) | ||
34 | #endif | ||
35 | #ifndef htole32 | ||
36 | #define htole32(x) __bswap_32(x) | ||
37 | #endif | ||
38 | #ifndef htole64 | ||
39 | #define htole64(x) __bswap_64(x) | ||
40 | #endif | ||
41 | |||
42 | #ifndef le16toh | ||
43 | #define le16toh(x) __bswap_16(x) | ||
44 | #endif | ||
45 | |||
46 | #ifndef le32toh | ||
47 | #define le32toh(x) __bswap_32(x) | ||
48 | #endif | ||
49 | |||
50 | #ifndef le64toh | ||
51 | #define le64toh(x) __bswap_64(x) | ||
52 | #endif | ||
53 | |||
54 | #endif | ||
55 | |||
56 | #endif /* _TOOLS_ENDIAN_H */ | ||
diff --git a/tools/usb/ffs-test.c b/tools/usb/ffs-test.c index a87e99f37c52..88d5e71be044 100644 --- a/tools/usb/ffs-test.c +++ b/tools/usb/ffs-test.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * ffs-test.c.c -- user mode filesystem api for usb composite function | 2 | * ffs-test.c -- user mode filesystem api for usb composite function |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Samsung Electronics | 4 | * Copyright (C) 2010 Samsung Electronics |
5 | * Author: Michal Nazarewicz <mina86@mina86.com> | 5 | * Author: Michal Nazarewicz <mina86@mina86.com> |
@@ -29,6 +29,7 @@ | |||
29 | #include <fcntl.h> | 29 | #include <fcntl.h> |
30 | #include <pthread.h> | 30 | #include <pthread.h> |
31 | #include <stdarg.h> | 31 | #include <stdarg.h> |
32 | #include <stdbool.h> | ||
32 | #include <stdio.h> | 33 | #include <stdio.h> |
33 | #include <stdlib.h> | 34 | #include <stdlib.h> |
34 | #include <string.h> | 35 | #include <string.h> |
@@ -106,7 +107,9 @@ static void _msg(unsigned level, const char *fmt, ...) | |||
106 | /******************** Descriptors and Strings *******************************/ | 107 | /******************** Descriptors and Strings *******************************/ |
107 | 108 | ||
108 | static const struct { | 109 | static const struct { |
109 | struct usb_functionfs_descs_head header; | 110 | struct usb_functionfs_descs_head_v2 header; |
111 | __le32 fs_count; | ||
112 | __le32 hs_count; | ||
110 | struct { | 113 | struct { |
111 | struct usb_interface_descriptor intf; | 114 | struct usb_interface_descriptor intf; |
112 | struct usb_endpoint_descriptor_no_audio sink; | 115 | struct usb_endpoint_descriptor_no_audio sink; |
@@ -114,11 +117,12 @@ static const struct { | |||
114 | } __attribute__((packed)) fs_descs, hs_descs; | 117 | } __attribute__((packed)) fs_descs, hs_descs; |
115 | } __attribute__((packed)) descriptors = { | 118 | } __attribute__((packed)) descriptors = { |
116 | .header = { | 119 | .header = { |
117 | .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC), | 120 | .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2), |
121 | .flags = cpu_to_le32(FUNCTIONFS_HAS_FS_DESC | | ||
122 | FUNCTIONFS_HAS_HS_DESC), | ||
118 | .length = cpu_to_le32(sizeof descriptors), | 123 | .length = cpu_to_le32(sizeof descriptors), |
119 | .fs_count = cpu_to_le32(3), | ||
120 | .hs_count = cpu_to_le32(3), | ||
121 | }, | 124 | }, |
125 | .fs_count = cpu_to_le32(3), | ||
122 | .fs_descs = { | 126 | .fs_descs = { |
123 | .intf = { | 127 | .intf = { |
124 | .bLength = sizeof descriptors.fs_descs.intf, | 128 | .bLength = sizeof descriptors.fs_descs.intf, |
@@ -142,6 +146,7 @@ static const struct { | |||
142 | /* .wMaxPacketSize = autoconfiguration (kernel) */ | 146 | /* .wMaxPacketSize = autoconfiguration (kernel) */ |
143 | }, | 147 | }, |
144 | }, | 148 | }, |
149 | .hs_count = cpu_to_le32(3), | ||
145 | .hs_descs = { | 150 | .hs_descs = { |
146 | .intf = { | 151 | .intf = { |
147 | .bLength = sizeof descriptors.fs_descs.intf, | 152 | .bLength = sizeof descriptors.fs_descs.intf, |
@@ -168,6 +173,89 @@ static const struct { | |||
168 | }, | 173 | }, |
169 | }; | 174 | }; |
170 | 175 | ||
176 | static size_t descs_to_legacy(void **legacy, const void *descriptors_v2) | ||
177 | { | ||
178 | const unsigned char *descs_end, *descs_start; | ||
179 | __u32 length, fs_count = 0, hs_count = 0, count; | ||
180 | |||
181 | /* Read v2 header */ | ||
182 | { | ||
183 | const struct { | ||
184 | const struct usb_functionfs_descs_head_v2 header; | ||
185 | const __le32 counts[]; | ||
186 | } __attribute__((packed)) *const in = descriptors_v2; | ||
187 | const __le32 *counts = in->counts; | ||
188 | __u32 flags; | ||
189 | |||
190 | if (le32_to_cpu(in->header.magic) != | ||
191 | FUNCTIONFS_DESCRIPTORS_MAGIC_V2) | ||
192 | return 0; | ||
193 | length = le32_to_cpu(in->header.length); | ||
194 | if (length <= sizeof in->header) | ||
195 | return 0; | ||
196 | length -= sizeof in->header; | ||
197 | flags = le32_to_cpu(in->header.flags); | ||
198 | if (flags & ~(FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC | | ||
199 | FUNCTIONFS_HAS_SS_DESC)) | ||
200 | return 0; | ||
201 | |||
202 | #define GET_NEXT_COUNT_IF_FLAG(ret, flg) do { \ | ||
203 | if (!(flags & (flg))) \ | ||
204 | break; \ | ||
205 | if (length < 4) \ | ||
206 | return 0; \ | ||
207 | ret = le32_to_cpu(*counts); \ | ||
208 | length -= 4; \ | ||
209 | ++counts; \ | ||
210 | } while (0) | ||
211 | |||
212 | GET_NEXT_COUNT_IF_FLAG(fs_count, FUNCTIONFS_HAS_FS_DESC); | ||
213 | GET_NEXT_COUNT_IF_FLAG(hs_count, FUNCTIONFS_HAS_HS_DESC); | ||
214 | GET_NEXT_COUNT_IF_FLAG(count, FUNCTIONFS_HAS_SS_DESC); | ||
215 | |||
216 | count = fs_count + hs_count; | ||
217 | if (!count) | ||
218 | return 0; | ||
219 | descs_start = (const void *)counts; | ||
220 | |||
221 | #undef GET_NEXT_COUNT_IF_FLAG | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * Find the end of FS and HS USB descriptors. SS descriptors | ||
226 | * are ignored since legacy format does not support them. | ||
227 | */ | ||
228 | descs_end = descs_start; | ||
229 | do { | ||
230 | if (length < *descs_end) | ||
231 | return 0; | ||
232 | length -= *descs_end; | ||
233 | descs_end += *descs_end; | ||
234 | } while (--count); | ||
235 | |||
236 | /* Allocate legacy descriptors and copy the data. */ | ||
237 | { | ||
238 | #pragma GCC diagnostic push | ||
239 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | ||
240 | struct { | ||
241 | struct usb_functionfs_descs_head header; | ||
242 | __u8 descriptors[]; | ||
243 | } __attribute__((packed)) *out; | ||
244 | #pragma GCC diagnostic pop | ||
245 | |||
246 | length = sizeof out->header + (descs_end - descs_start); | ||
247 | out = malloc(length); | ||
248 | out->header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC); | ||
249 | out->header.length = cpu_to_le32(length); | ||
250 | out->header.fs_count = cpu_to_le32(fs_count); | ||
251 | out->header.hs_count = cpu_to_le32(hs_count); | ||
252 | memcpy(out->descriptors, descs_start, descs_end - descs_start); | ||
253 | *legacy = out; | ||
254 | } | ||
255 | |||
256 | return length; | ||
257 | } | ||
258 | |||
171 | 259 | ||
172 | #define STR_INTERFACE_ "Source/Sink" | 260 | #define STR_INTERFACE_ "Source/Sink" |
173 | 261 | ||
@@ -487,12 +575,29 @@ ep0_consume(struct thread *ignore, const void *buf, size_t nbytes) | |||
487 | return nbytes; | 575 | return nbytes; |
488 | } | 576 | } |
489 | 577 | ||
490 | static void ep0_init(struct thread *t) | 578 | static void ep0_init(struct thread *t, bool legacy_descriptors) |
491 | { | 579 | { |
580 | void *legacy; | ||
492 | ssize_t ret; | 581 | ssize_t ret; |
582 | size_t len; | ||
583 | |||
584 | if (legacy_descriptors) { | ||
585 | info("%s: writing descriptors\n", t->filename); | ||
586 | goto legacy; | ||
587 | } | ||
493 | 588 | ||
494 | info("%s: writing descriptors\n", t->filename); | 589 | info("%s: writing descriptors (in v2 format)\n", t->filename); |
495 | ret = write(t->fd, &descriptors, sizeof descriptors); | 590 | ret = write(t->fd, &descriptors, sizeof descriptors); |
591 | |||
592 | if (ret < 0 && errno == EINVAL) { | ||
593 | warn("%s: new format rejected, trying legacy\n", t->filename); | ||
594 | legacy: | ||
595 | len = descs_to_legacy(&legacy, &descriptors); | ||
596 | if (len) { | ||
597 | ret = write(t->fd, legacy, len); | ||
598 | free(legacy); | ||
599 | } | ||
600 | } | ||
496 | die_on(ret < 0, "%s: write: descriptors", t->filename); | 601 | die_on(ret < 0, "%s: write: descriptors", t->filename); |
497 | 602 | ||
498 | info("%s: writing strings\n", t->filename); | 603 | info("%s: writing strings\n", t->filename); |
@@ -503,14 +608,15 @@ static void ep0_init(struct thread *t) | |||
503 | 608 | ||
504 | /******************** Main **************************************************/ | 609 | /******************** Main **************************************************/ |
505 | 610 | ||
506 | int main(void) | 611 | int main(int argc, char **argv) |
507 | { | 612 | { |
613 | bool legacy_descriptors; | ||
508 | unsigned i; | 614 | unsigned i; |
509 | 615 | ||
510 | /* XXX TODO: Argument parsing missing */ | 616 | legacy_descriptors = argc > 2 && !strcmp(argv[1], "-l"); |
511 | 617 | ||
512 | init_thread(threads); | 618 | init_thread(threads); |
513 | ep0_init(threads); | 619 | ep0_init(threads, legacy_descriptors); |
514 | 620 | ||
515 | for (i = 1; i < sizeof threads / sizeof *threads; ++i) | 621 | for (i = 1; i < sizeof threads / sizeof *threads; ++i) |
516 | init_thread(threads + i); | 622 | init_thread(threads + i); |
diff --git a/tools/usb/usbip/libsrc/usbip_common.h b/tools/usb/usbip/libsrc/usbip_common.h index 5a0e95edf4df..15fe792e1e96 100644 --- a/tools/usb/usbip/libsrc/usbip_common.h +++ b/tools/usb/usbip/libsrc/usbip_common.h | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <syslog.h> | 15 | #include <syslog.h> |
16 | #include <unistd.h> | 16 | #include <unistd.h> |
17 | #include <linux/usb/ch9.h> | 17 | #include <linux/usb/ch9.h> |
18 | #include "../../uapi/usbip.h" | 18 | #include <linux/usbip.h> |
19 | 19 | ||
20 | #ifndef USBIDS_FILE | 20 | #ifndef USBIDS_FILE |
21 | #define USBIDS_FILE "/usr/share/hwdata/usb.ids" | 21 | #define USBIDS_FILE "/usr/share/hwdata/usb.ids" |