1 /* ----------------------------------------------------------------------------
2 * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved.
3 * Description: LiteOS USB Driver HID Protocol HeadFile
4 * Author: Yannik Li
5 * Create: 2021-02-04
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
14 * to endorse or promote products derived from this software without specific prior written
15 * permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * --------------------------------------------------------------------------- */
28 /* ----------------------------------------------------------------------------
29 * Notice of Export Control Law
30 * ===============================================
31 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might
32 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located.
33 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such
34 * applicable export control laws and regulations.
35 * --------------------------------------------------------------------------- */
36
37 #ifndef _F_GENERIC_GADGET_H
38 #define _F_GENERIC_GADGET_H
39
40 #include "usb_obj.h"
41 #include "gadget/usbdev.h"
42 #include "gadget/composite.h"
43
44
45 #ifdef __cplusplus
46 #if __cplusplus
47 //extern "C" {
48 #endif /* __cplusplus */
49 #endif /* __cplusplus */
50
51 /* Define usb generic function gadget path. */
52
53 #define USB_GENERIC_DEV "/dev/generic"
54
55 #define GENERIC_IOC_MAGIC 'g'
56 #define GENERIC_CMD_FREE_MEM _IO(GENERIC_IOC_MAGIC, 1)
57 #define GENERIC_CMD_CANCEL_REQUEST _IO(GENERIC_IOC_MAGIC, 2)
58 #define GENERIC_CMD_GET_PIPE_INFO _IO(GENERIC_IOC_MAGIC, 3)
59 #define GENERIC_CMD_GET_EP0_EVENT _IO(GENERIC_IOC_MAGIC, 4)
60 #define GENERIC_CMD_ENDPOINT_IO _IO(GENERIC_IOC_MAGIC, 5)
61 #define GENERIC_CMD_GET_REQ_STATUS _IO(GENERIC_IOC_MAGIC, 6)
62
63 #define USB_GENERIC_EVENTS_NUM 4
64 #define USB_GENERIC_COMPLETE_EVENT (1 << 0)
65 #define USB_GENERIC_EP0_EVENT (1 << 0)
66
67 struct event_fifo
68 {
69 uint32_t in;
70 uint32_t out;
71 uint8_t data[USB_GENERIC_EVENTS_NUM];
72 };
73
74 enum generic_state
75 {
76 /*
77 * Waiting for descriptors and strings.
78 */
79 GENERIC_READ_DESCRIPTORS,
80 GENERIC_READ_STRINGS,
81
82 /*
83 * We've got descriptors and strings.
84 */
85 GENERIC_ACTIVE,
86
87 /*
88 * Function is deactived, all epfiles, except ep0, are deleted
89 * so there is no way to perform any operations on them.
90 */
91 GENERIC_DEACTIVATED,
92
93 /*
94 * All endpoints have been closed.
95 */
96 GENERIC_CLOSING
97 };
98
99 enum generic_setup_state
100 {
101 /* There is no setup request pending. */
102 GENERIC_NO_SETUP,
103 /*
104 * There was a setup request event there, the request
105 * will be handled on the next read/write on ep0.
106 */
107 GENERIC_SETUP_PENDING,
108 /*
109 * The existing event was canceled.
110 */
111 GENERIC_SETUP_CANCELLED
112 };
113
114 struct generic_memory
115 {
116 size_t size;
117 size_t buf;
118 char storage[];
119 };
120
121 struct IoData {
122 uint32_t aio; /* 0 for sync ,1 for async */
123 uint32_t read; /* 0 for write ,1 for read */
124 uint32_t len; /* the len of this io request */
125 uint32_t timeout; /* sync timeout */
126 uint32_t buf; /* the address of map buf */
127 };
128
129 struct generic_ep
130 {
131 struct usbdev_ep_s *ep;
132 struct usbdev_req_s *req;
133 EVENT_CB_S event;
134
135 /* [0]: full speed, [1]: high speed, [2]: super speed */
136 usb_endpoint_descriptor_t *descs[3];
137 uint8_t num;
138 int status;
139 void *priv;
140 };
141
142 struct usb_memory
143 {
144 struct usb_obj obj;
145 unsigned long mem;
146 unsigned long vm_start;
147 uint32_t size;
148 atomic_t usage;
149 };
150
151 struct generic_strings {
152 uint16_t language;
153 struct usbd_string *strings;
154 };
155
156 struct generic_dev_s
157 {
158 struct usb_obj obj;
159 struct usbdev_s *usbdev;
160 struct generic_driver_s *drvr;
161 const char *name;
162 int minor;
163 int minor_offset;
164 pthread_mutex_t mutex;
165 struct usbdev_devinfo_s *devinfo;
166 struct list_head ep0_comp_list;
167 struct list_head ep0_req_list;
168 bool inuse;
169 bool desc_ready;
170 bool eps_enbale;
171
172 /* the number of files are opened (EP0 and others) */
173 atomic_t opened;
174
175 /* EP0 state */
176 enum generic_state state;
177 enum generic_setup_state setup_state;
178 struct usb_device_request setup;
179 uint16_t ep0_can_stall;
180 struct event_fifo efifo;
181 EVENT_CB_S ep0_event;
182 spinlock_t event_lock;
183 struct usb_obj memory_obj;
184 struct usbdev_req_s *ctrlreq;
185 EVENT_CB_S ctrlreq_event;
186 uint32_t event_mask;
187 EVENT_CB_S ep_event_all;
188 uint32_t cur_buff;
189
190 /* Flags */
191 unsigned long flags;
192 const void *raw_descs_data;
193 const void *raw_descs;
194 uint32_t raw_descs_length;
195 uint32_t fs_descs_count;
196 uint32_t hs_descs_count;
197 uint32_t ss_descs_count;
198 uint32_t fs_descs_len;
199 uint32_t hs_descs_len;
200 uint32_t ss_descs_len;
201 uint32_t descs_flags;
202 uint32_t strings_count;
203 uint32_t lang_count;
204 const void *raw_strings;
205 struct generic_strings *dev_strings;
206
207 #define GENERIC_MAX_EPS_COUNT 31
208 uint8_t eps_addrmap[GENERIC_MAX_EPS_COUNT];
209 usb_endpoint_descriptor_t *eps_descs[GENERIC_MAX_EPS_COUNT][3];
210 uint8_t speed;
211 spinlock_t eps_lock;
212 spinlock_t ep0_lock;
213 struct generic_ep *eps;
214 uint8_t eps_revmap[16];
215 uint32_t alt_setting;
216 uint16_t interfaces_count;
217 uint16_t eps_count;
218 struct usb_obj epfiles_obj;
219 };
220
221 struct generic_driver_s
222 {
223 struct usbdevclass_driver_s drvr;
224 struct generic_dev_s *dev;
225 };
226
227 struct generic_softc
228 {
229 struct generic_dev_s dev;
230 struct generic_driver_s drvr;
231 };
232
event_fifo_reset(struct event_fifo * efifo)233 static inline void event_fifo_reset(struct event_fifo *efifo)
234 {
235 efifo->in = efifo->out = 0;
236 }
237
event_fifo_len(struct event_fifo * efifo)238 static inline bool event_fifo_len(struct event_fifo *efifo)
239 {
240 return efifo->in - efifo->out;
241 }
242
event_fifo_is_empty(struct event_fifo * efifo)243 static inline bool event_fifo_is_empty(struct event_fifo *efifo)
244 {
245 return efifo->in == efifo->out;
246 }
247
event_fifo_is_full(struct event_fifo * efifo)248 static inline bool event_fifo_is_full(struct event_fifo *efifo)
249 {
250 uint32_t mask = USB_GENERIC_EVENTS_NUM - 1;
251 return event_fifo_len(efifo) > (mask);
252 }
253
event_fifo_put(struct event_fifo * efifo,uint8_t event)254 static inline int event_fifo_put(struct event_fifo *efifo, uint8_t event)
255 {
256 int ret = !event_fifo_is_full(efifo);
257 if (ret)
258 {
259 uint32_t mask = USB_GENERIC_EVENTS_NUM - 1;
260 efifo->data[efifo->in & mask] = event;
261 efifo->in++;
262 }
263
264 return ret;
265 }
266
event_fifo_get(struct event_fifo * efifo,uint8_t * event)267 static inline int event_fifo_get(struct event_fifo *efifo, uint8_t *event)
268 {
269 int ret = !event_fifo_is_empty(efifo);
270 if (ret)
271 {
272 uint32_t mask = USB_GENERIC_EVENTS_NUM - 1;
273 *event = efifo->data[efifo->out & mask];
274 efifo->out++;
275 }
276
277 return ret;
278 }
279
280 extern int usbdev_generic_alloc_instance(const char *name);
281 extern int usbdev_generic_free_instance(const char *name);
282 extern void usbdev_generic_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor);
283 extern void generic_dev_closed(struct generic_dev_s *dev);
284 extern void generic_dev_opened(struct generic_dev_s *dev);
285
286 #ifdef __cplusplus
287 #if __cplusplus
288 //}
289 #endif /* __cplusplus */
290 #endif /* __cplusplus */
291
292 #endif /* _F_GENERIC_GADGET_H */
293