aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Baldyga <r.baldyga@samsung.com>2014-02-11 05:43:03 -0500
committerFelipe Balbi <balbi@ti.com>2014-05-14 10:23:24 -0400
commitb34e08d5c7062c19a3f582d23d5f649c79ff3409 (patch)
tree4d7674db849724848d2b4a7731b518dd8c5e4bb6
parent60b6dbeffb8c253d1f80527b28611e5e236dec51 (diff)
tools: usb: aio example applications
This patch adds two example applications showing usage of Asynchronous I/O API of FunctionFS. First one (aio_simple) is simple example of bidirectional data transfer. Second one (aio_multibuff) shows multi-buffer data transfer, which may to be used in high performance applications. Both examples contains userspace applications for device and for host. It needs libaio library on the device, and libusb library on host. Signed-off-by: Robert Baldyga <r.baldyga@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c349
-rw-r--r--tools/usb/ffs-aio-example/multibuff/host_app/Makefile13
-rw-r--r--tools/usb/ffs-aio-example/multibuff/host_app/test.c146
-rw-r--r--tools/usb/ffs-aio-example/simple/device_app/aio_simple.c335
-rw-r--r--tools/usb/ffs-aio-example/simple/host_app/Makefile13
-rw-r--r--tools/usb/ffs-aio-example/simple/host_app/test.c148
6 files changed, 1004 insertions, 0 deletions
diff --git a/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c
new file mode 100644
index 000000000000..87216a0c4a8b
--- /dev/null
+++ b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c
@@ -0,0 +1,349 @@
1#define _BSD_SOURCE /* for endian.h */
2
3#include <endian.h>
4#include <errno.h>
5#include <fcntl.h>
6#include <stdarg.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <sys/ioctl.h>
11#include <sys/stat.h>
12#include <sys/types.h>
13#include <sys/poll.h>
14#include <unistd.h>
15#include <stdbool.h>
16#include <sys/eventfd.h>
17
18#include "libaio.h"
19#define IOCB_FLAG_RESFD (1 << 0)
20
21#include <linux/usb/functionfs.h>
22
23#define BUF_LEN 8192
24#define BUFS_MAX 128
25#define AIO_MAX (BUFS_MAX*2)
26
27/******************** Descriptors and Strings *******************************/
28
29static const struct {
30 struct usb_functionfs_descs_head header;
31 struct {
32 struct usb_interface_descriptor intf;
33 struct usb_endpoint_descriptor_no_audio bulk_sink;
34 struct usb_endpoint_descriptor_no_audio bulk_source;
35 } __attribute__ ((__packed__)) fs_descs, hs_descs;
36} __attribute__ ((__packed__)) descriptors = {
37 .header = {
38 .magic = htole32(FUNCTIONFS_DESCRIPTORS_MAGIC),
39 .length = htole32(sizeof(descriptors)),
40 .fs_count = 3,
41 .hs_count = 3,
42 },
43 .fs_descs = {
44 .intf = {
45 .bLength = sizeof(descriptors.fs_descs.intf),
46 .bDescriptorType = USB_DT_INTERFACE,
47 .bNumEndpoints = 2,
48 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
49 .iInterface = 1,
50 },
51 .bulk_sink = {
52 .bLength = sizeof(descriptors.fs_descs.bulk_sink),
53 .bDescriptorType = USB_DT_ENDPOINT,
54 .bEndpointAddress = 1 | USB_DIR_IN,
55 .bmAttributes = USB_ENDPOINT_XFER_BULK,
56 },
57 .bulk_source = {
58 .bLength = sizeof(descriptors.fs_descs.bulk_source),
59 .bDescriptorType = USB_DT_ENDPOINT,
60 .bEndpointAddress = 2 | USB_DIR_OUT,
61 .bmAttributes = USB_ENDPOINT_XFER_BULK,
62 },
63 },
64 .hs_descs = {
65 .intf = {
66 .bLength = sizeof(descriptors.hs_descs.intf),
67 .bDescriptorType = USB_DT_INTERFACE,
68 .bNumEndpoints = 2,
69 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
70 .iInterface = 1,
71 },
72 .bulk_sink = {
73 .bLength = sizeof(descriptors.hs_descs.bulk_sink),
74 .bDescriptorType = USB_DT_ENDPOINT,
75 .bEndpointAddress = 1 | USB_DIR_IN,
76 .bmAttributes = USB_ENDPOINT_XFER_BULK,
77 .wMaxPacketSize = htole16(512),
78 },
79 .bulk_source = {
80 .bLength = sizeof(descriptors.hs_descs.bulk_source),
81 .bDescriptorType = USB_DT_ENDPOINT,
82 .bEndpointAddress = 2 | USB_DIR_OUT,
83 .bmAttributes = USB_ENDPOINT_XFER_BULK,
84 .wMaxPacketSize = htole16(512),
85 },
86 },
87};
88
89#define STR_INTERFACE "AIO Test"
90
91static const struct {
92 struct usb_functionfs_strings_head header;
93 struct {
94 __le16 code;
95 const char str1[sizeof(STR_INTERFACE)];
96 } __attribute__ ((__packed__)) lang0;
97} __attribute__ ((__packed__)) strings = {
98 .header = {
99 .magic = htole32(FUNCTIONFS_STRINGS_MAGIC),
100 .length = htole32(sizeof(strings)),
101 .str_count = htole32(1),
102 .lang_count = htole32(1),
103 },
104 .lang0 = {
105 htole16(0x0409), /* en-us */
106 STR_INTERFACE,
107 },
108};
109
110/********************** Buffer structure *******************************/
111
112struct io_buffer {
113 struct iocb **iocb;
114 unsigned char **buf;
115 unsigned cnt;
116 unsigned len;
117 unsigned requested;
118};
119
120/******************** Endpoints handling *******************************/
121
122static void display_event(struct usb_functionfs_event *event)
123{
124 static const char *const names[] = {
125 [FUNCTIONFS_BIND] = "BIND",
126 [FUNCTIONFS_UNBIND] = "UNBIND",
127 [FUNCTIONFS_ENABLE] = "ENABLE",
128 [FUNCTIONFS_DISABLE] = "DISABLE",
129 [FUNCTIONFS_SETUP] = "SETUP",
130 [FUNCTIONFS_SUSPEND] = "SUSPEND",
131 [FUNCTIONFS_RESUME] = "RESUME",
132 };
133 switch (event->type) {
134 case FUNCTIONFS_BIND:
135 case FUNCTIONFS_UNBIND:
136 case FUNCTIONFS_ENABLE:
137 case FUNCTIONFS_DISABLE:
138 case FUNCTIONFS_SETUP:
139 case FUNCTIONFS_SUSPEND:
140 case FUNCTIONFS_RESUME:
141 printf("Event %s\n", names[event->type]);
142 }
143}
144
145static void handle_ep0(int ep0, bool *ready)
146{
147 int ret;
148 struct usb_functionfs_event event;
149
150 ret = read(ep0, &event, sizeof(event));
151 if (!ret) {
152 perror("unable to read event from ep0");
153 return;
154 }
155 display_event(&event);
156 switch (event.type) {
157 case FUNCTIONFS_SETUP:
158 if (event.u.setup.bRequestType & USB_DIR_IN)
159 write(ep0, NULL, 0);
160 else
161 read(ep0, NULL, 0);
162 break;
163
164 case FUNCT