• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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