• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------------
2  * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
3  * Description: LiteOS USB Driver Composite Devices
4  * Author: Yannik Li
5  * Create: 2021-02-21
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 #include "usb_handle.h"
37 #include "f_common.h"
38 
39 #ifdef __cplusplus
40 #if __cplusplus
41 //extern "C" {
42 #endif /* __cplusplus */
43 #endif /* __cplusplus */
44 
45 static LINUX_LIST_HEAD(g_hanle_list);
46 static DEFINE_SPINLOCK(g_hanle_lock);
47 static unsigned int devmap = 0;
48 
alloc_fd_for_handle(void)49 static int alloc_fd_for_handle(void)
50 {
51   int bitsize = 0x8 * sizeof (devmap);
52   bool found = false;
53   int i;
54 
55   for (i = 1; i < bitsize; i++)
56     {
57       if ((devmap & (1 << i)) == 0)
58         {
59           devmap |= (1 << i);
60           found = true;
61           break;
62         }
63     }
64   return found ? i : -1;
65 }
66 
free_fd_for_handle(int fd)67 static int free_fd_for_handle(int fd)
68 {
69   if (fd <= 0 || fd > 31)
70     {
71       return -1;
72     }
73   devmap &= (~(1 << fd));
74 
75   return 0;
76 }
77 
handle_find_by_name(const char * devName)78 static struct usb_handle *handle_find_by_name(const char *devName)
79 {
80   struct usb_handle *handle = NULL;
81   bool found = false;
82   uint32_t flags;
83 
84   if (!devName)
85     {
86       return NULL;
87     }
88 
89   spin_lock_irqsave(&g_hanle_lock, flags);
90   list_for_each_entry(handle, &g_hanle_list, entry)
91     {
92       if (strcmp(handle->name, devName) == 0)
93         {
94           found = true;
95           break;
96         }
97     }
98   spin_unlock_irqrestore(&g_hanle_lock, flags);
99 
100   return found ? handle : NULL;
101 }
102 
handle_find_by_fd(int fd)103 static struct usb_handle *handle_find_by_fd(int fd)
104 {
105   struct usb_handle *handle = NULL;
106   bool found = false;
107   uint32_t flags;
108 
109   if (fd <= 0)
110     {
111       return NULL;
112     }
113 
114   spin_lock_irqsave(&g_hanle_lock, flags);
115   list_for_each_entry(handle, &g_hanle_list, entry)
116     {
117       if (handle->fd == fd)
118         {
119           found = true;
120           break;
121         }
122     }
123   spin_unlock_irqrestore(&g_hanle_lock, flags);
124 
125   return found ? handle : NULL;
126 }
127 
register_handle(char * devName,struct UsbHandleOps * ops,void * priv,struct usb_obj * obj)128 int register_handle(char *devName, struct UsbHandleOps *ops, void *priv, struct usb_obj *obj)
129 {
130   struct usb_handle *handle = NULL;
131   uint32_t flags;
132 
133   if (devName == NULL || ops == NULL) {
134     return -1;
135   }
136   handle = handle_find_by_name(devName);
137   if (handle)
138     {
139       return -1;
140     }
141   handle = (struct usb_handle *)usbm_malloc(obj, sizeof(*handle));
142   if (!handle)
143     {
144       return -1;
145     }
146   handle->name = devName;
147   handle->fd = -1;
148   handle->ops = ops;
149   handle->obj = obj;
150   handle->priv = priv;
151   spin_lock_irqsave(&g_hanle_lock, flags);
152   list_add_tail(&handle->entry, &g_hanle_list);
153   spin_unlock_irqrestore(&g_hanle_lock, flags);
154 
155   return 0;
156 }
157 
unregister_handle(const char * devName)158 int unregister_handle(const char *devName)
159 {
160   uint32_t flags;
161   struct usb_handle *handle = NULL;
162 
163   handle = handle_find_by_name(devName);
164   if (handle == NULL)
165     {
166       return -1;
167     }
168   spin_lock_irqsave(&g_hanle_lock, flags);
169   list_del_init(&handle->entry);
170   spin_unlock_irqrestore(&g_hanle_lock, flags);
171   usbm_free(handle->obj, handle->name);
172   usbm_free(handle->obj, handle);
173 
174   return 0;
175 }
176 
handle_open(const char * name)177 int handle_open(const char *name)
178 {
179   int fd;
180   struct usb_handle *handle = NULL;
181   if (name == NULL)
182     {
183       return -1;
184     }
185   handle = handle_find_by_name(name);
186   if (handle == NULL)
187     {
188       return -1;
189     }
190   if (handle->fd > 0)
191     {
192       return -1;
193     }
194   fd = alloc_fd_for_handle();
195   if (fd <= 0)
196     {
197       return -1;
198     }
199   handle->fd = fd;
200   if (handle->ops && handle->ops->open)
201     {
202       handle->ops->open(handle);
203     }
204   return fd;
205 }
206 
handle_close(int fd)207 int handle_close(int fd)
208 {
209   int ret = -1;
210   struct usb_handle *handle = NULL;
211 
212   handle = handle_find_by_fd(fd);
213   if (handle == NULL)
214     {
215       dprintf("%s, can not found hand, fd = %d\n", __func__, fd);
216       return -1;
217     }
218   if (handle->ops && handle->ops->close)
219     {
220       ret = handle->ops->close(handle);
221       if (ret)
222         {
223           return ret;
224         }
225     }
226   handle->fd = -1;
227   free_fd_for_handle(fd);
228 
229   return ret;
230 }
231 
handle_read(int fd,void * buffer,size_t len)232 int handle_read(int fd, void *buffer, size_t len)
233 {
234   int ret = -1;
235   struct usb_handle *handle = NULL;
236 
237   handle = handle_find_by_fd(fd);
238   if (handle == NULL)
239     {
240       dprintf("%s, can not found hand, fd = %d\n", __func__, fd);
241       return -1;
242     }
243   if (handle->ops && handle->ops->read)
244     {
245       ret = handle->ops->read(handle, buffer, len);
246     }
247 
248   return ret;
249 }
250 
handle_write(int fd,void * buffer,size_t len)251 int handle_write(int fd, void *buffer, size_t len)
252 {
253   int ret = -1;
254   struct usb_handle *handle = NULL;
255 
256   handle = handle_find_by_fd(fd);
257   if (handle == NULL)
258     {
259       dprintf("%s, can not found hand, fd = %d\n", __func__, fd);
260       return -1;
261     }
262   if (handle->ops && handle->ops->write)
263     {
264       ret = handle->ops->write(handle, buffer, len);
265     }
266 
267   return ret;
268 }
269 
handle_ioctl(int fd,int cmd,void * arg)270 int handle_ioctl(int fd, int cmd, void *arg)
271 {
272   int ret = -1;
273   struct usb_handle *handle = NULL;
274 
275   handle = handle_find_by_fd(fd);
276   if (handle == NULL)
277     {
278       dprintf("%s, can not found hand, fd = %d\n", __func__, fd);
279       return -1;
280     }
281   if (handle->ops && handle->ops->ioctl)
282     {
283       ret = handle->ops->ioctl(handle, cmd, arg);
284     }
285 
286   return ret;
287 }
288 
handle_mmap(int fd,uint32_t size)289 void *handle_mmap(int fd, uint32_t size)
290 {
291   void *mem = NULL;
292   struct usb_handle *handle = NULL;
293 
294   handle = handle_find_by_fd(fd);
295   if (handle == NULL)
296     {
297       dprintf("%s, can not found hand, fd = %d\n", __func__, fd);
298       return NULL;
299     }
300   if (handle->ops && handle->ops->mmap)
301     {
302       mem = handle->ops->mmap(handle, size);
303     }
304 
305   return mem;
306 }
307 
handle_poll(int fd,int timeout)308 int handle_poll(int fd, int timeout)
309 {
310   int ret = -1;
311   struct usb_handle *handle = NULL;
312 
313   handle = handle_find_by_fd(fd);
314   if (handle == NULL)
315     {
316       dprintf("%s, can not found hand, fd = %d\n", __func__, fd);
317       return -1;
318     }
319   if (handle->ops && handle->ops->poll)
320     {
321       ret = handle->ops->poll(handle, timeout);
322     }
323 
324   return ret;
325 }
326 
327 #ifdef __cplusplus
328 #if __cplusplus
329 //}
330 #endif /* __cplusplus */
331 #endif /* __cplusplus */
332