aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/include/tools/endian.h56
-rw-r--r--tools/usb/ffs-test.c126
-rw-r--r--tools/usb/usbip/libsrc/usbip_common.h2
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
108static const struct { 109static 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
176static 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
490static void ep0_init(struct thread *t) 578static 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);
594legacy:
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
506int main(void) 611int 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"