• 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 "obj_ref.h"
37 #include "usb_obj.h"
38 #include "f_common.h"
39 #include <linux/spinlock.h>
40 
41 #ifdef __cplusplus
42 #if __cplusplus
43 //extern "C" {
44 #endif /* __cplusplus */
45 #endif /* __cplusplus */
46 
usbobj_init(struct usb_obj * obj,const char * name,void (* release)(struct usb_obj * obj))47 int usbobj_init(struct usb_obj *obj, const char *name,
48                 void (*release)(struct usb_obj *obj))
49 {
50   if (!obj)
51   {
52     return -1;
53   }
54 
55   obj->name = name;
56   obj->parent = NULL;
57   objref_init(&obj->ref, 1);
58   INIT_LIST_HEAD(&obj->entry);
59   INIT_LIST_HEAD(&obj->children);
60   INIT_LIST_HEAD(&obj->objres_head);
61   spin_lock_init(&obj->objres_lock);
62   spin_lock_init(&obj->lock);
63   obj->release = release;
64 
65   return 0;
66 }
67 
usbobj_add(struct usb_obj * obj,struct usb_obj * parent)68 int usbobj_add(struct usb_obj *obj, struct usb_obj *parent)
69 {
70   uint32_t flags;
71 
72   if (!obj || !parent)
73     {
74       return -1;
75     }
76 
77   usbobj_get(parent);
78   spin_lock_irqsave(&parent->lock, flags);
79   list_add_tail(&obj->entry, &parent->children);
80   obj->parent = parent;
81   spin_unlock_irqrestore(&parent->lock, flags);
82 
83   return 0;
84 }
85 
usbobj_remove(struct usb_obj * obj)86 int usbobj_remove(struct usb_obj *obj)
87 {
88   struct usb_obj *parent;
89   uint32_t flags;
90 
91   if (!obj || !obj->parent)
92     {
93       return -1;
94     }
95 
96   parent = obj->parent;
97   spin_lock_irqsave(&parent->lock, flags);
98   list_del_init(&obj->entry);
99   spin_unlock_irqrestore(&parent->lock, flags);
100   obj->parent = NULL;
101 
102   return 0;
103 }
104 
usbobj_find(struct usb_obj * obj,usbobj_match_t match,void * match_data)105 struct usb_obj *usbobj_find(struct usb_obj *obj, usbobj_match_t match, void *match_data)
106 {
107   struct usb_obj *child;
108   bool found = false;
109   uint32_t flags;
110 
111   if (!obj)
112     {
113       return NULL;
114     }
115 
116   spin_lock_irqsave(&obj->lock, flags);
117   list_for_each_entry(child, &obj->children, entry)
118     {
119       if (match(child, match_data))
120         {
121           found = true;
122           break;
123         }
124     }
125   spin_unlock_irqrestore(&obj->lock, flags);
126 
127   return found ? child : NULL;
128 }
129 
usbobj_get(struct usb_obj * obj)130 void usbobj_get(struct usb_obj *obj)
131 {
132   if (obj)
133     {
134       objref_get(&obj->ref);
135     }
136 }
137 
usbobj_release_child(struct usb_obj * obj,void * data)138 static void usbobj_release_child(struct usb_obj *obj, void *data)
139 {
140   (void)data;
141   usbobj_put(obj);
142 }
143 
usbobj_release(struct obj_ref * ref)144 static void usbobj_release(struct obj_ref *ref)
145 {
146   struct usb_obj *obj = container_of(ref, struct usb_obj, ref);
147   struct usb_obj *parent = obj->parent;
148   uint32_t flags;
149 
150   if (parent)
151     {
152       spin_lock_irqsave(&parent->lock, flags);
153       list_del_init(&obj->entry);
154       spin_unlock_irqrestore(&parent->lock, flags);
155     }
156 
157   usbobj_for_each_child(obj, NULL, NULL, usbobj_release_child, NULL);
158 
159   objres_release_all(obj);
160   if (obj->release)
161     {
162       obj->release(obj);
163     }
164 
165   if (parent)
166     {
167       usbobj_put(parent);
168     }
169 }
170 
usbobj_put(struct usb_obj * obj)171 void usbobj_put(struct usb_obj *obj)
172 {
173   if (obj)
174     {
175       (void)objref_put(&obj->ref, usbobj_release);
176     }
177 }
178 
usbobj_for_each_child(struct usb_obj * obj,usbobj_match_t match,void * match_data,void (* fn)(struct usb_obj *,void *),void * data)179 void usbobj_for_each_child(struct usb_obj *obj,
180                            usbobj_match_t match, void *match_data,
181                            void (*fn)(struct usb_obj *, void *),
182                            void *data)
183 {
184   struct usb_obj *child, *tmp;
185   uint32_t flags;
186 
187   if (!obj || !fn)
188     {
189       return;
190     }
191 
192   spin_lock_irqsave(&obj->lock, flags);
193   list_for_each_entry_safe(child, tmp, &obj->children, entry)
194     {
195       if (match && !match(child, match_data))
196         {
197           continue;
198         }
199       fn(child, data);
200     }
201   spin_unlock_irqrestore(&obj->lock, flags);
202 }
203 
204 #ifdef __cplusplus
205 #if __cplusplus
206 //}
207 #endif /* __cplusplus */
208 #endif /* __cplusplus */
209