• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "hdf_syscall_adapter.h"
17 #include "hdf_log.h"
18 #include "hdf_sbuf.h"
19 #include "osal_mem.h"
20 #include "devsvc_manager_clnt.h"
21 
22 #define HDF_LOG_TAG hdf_syscall_adapter
23 
HdfSyscallAdapterDispatch(struct HdfObject * service,int cmdId,struct HdfSBuf * data,struct HdfSBuf * reply)24 int HdfSyscallAdapterDispatch (struct HdfObject *service, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)
25 {
26     struct HdfIoService *ioService = (struct HdfIoService*)service;
27     struct HdfSyscallAdapter *adapter = NULL;
28 
29     if (ioService == NULL || ioService->dispatcher == NULL) {
30         return HDF_ERR_INVALID_PARAM;
31     }
32 
33     adapter = CONTAINER_OF(ioService, struct HdfSyscallAdapter, super);
34 
35     if (adapter->client.device == NULL || adapter->client.device->service == NULL ||
36         adapter->client.device->service->Dispatch == NULL) {
37             return HDF_ERR_INVALID_OBJECT;
38     }
39 
40     return adapter->client.device->service->Dispatch(&adapter->client, cmdId, data, reply);
41 }
42 
HdfSyscallAdapterInstance(struct HdfDeviceObject * deviceObject)43 static struct HdfSyscallAdapter *HdfSyscallAdapterInstance(struct HdfDeviceObject *deviceObject)
44 {
45     struct HdfSyscallAdapter *adapter = NULL;
46 
47     static struct HdfIoDispatcher kDispatcher = {
48         .Dispatch = HdfSyscallAdapterDispatch,
49     };
50 
51     adapter = CONTAINER_OF(deviceObject, struct HdfSyscallAdapter, deviceObject);
52 
53     if (adapter == NULL) {
54         return NULL;
55     }
56 
57     DListHeadInit(&adapter->listenerList);
58     if (OsalMutexInit(&adapter->mutex)) {
59         HDF_LOGE("%s: Failed to create mutex", __func__);
60         OsalMemFree(adapter);
61         return NULL;
62     }
63 
64     if (deviceObject == NULL) {
65         OsalMutexDestroy(&adapter->mutex);
66         OsalMemFree(adapter);
67         return NULL;
68     }
69 
70     adapter->client.device = deviceObject;
71 
72     if (deviceObject->service != NULL && deviceObject->service->Open != NULL) {
73         if (deviceObject->service->Open(&adapter->client) != HDF_SUCCESS) {
74             OsalMutexDestroy(&adapter->mutex);
75             OsalMemFree(adapter);
76             return NULL;
77         }
78     }
79 
80     adapter->super.dispatcher = &kDispatcher;
81     return adapter;
82 }
83 
HdfIoServiceAdapterObtain(const char * serviceName)84 struct HdfIoService *HdfIoServiceAdapterObtain(const char *serviceName)
85 {
86     struct HdfSyscallAdapter *adapter = NULL;
87     struct HdfDeviceObject *deviceObject = NULL;
88 
89     int ret;
90 
91     if (serviceName == NULL) {
92         return NULL;
93     }
94 
95     ret = HdfLoadDriverByServiceName(serviceName);
96     if (ret != HDF_SUCCESS) {
97         HDF_LOGE("%s: load %s driver failed", __func__, serviceName);
98         return NULL;
99     }
100 
101     deviceObject = DevSvcManagerClntGetDeviceObject(serviceName);
102     if (deviceObject == NULL) {
103         return NULL;
104     }
105 
106     adapter = HdfSyscallAdapterInstance(deviceObject);
107     if (adapter == NULL) {
108         return NULL;
109     }
110 
111     return &adapter->super;
112 }
113 
HdfIoServiceAdapterRecycle(struct HdfIoService * ioService)114 void HdfIoServiceAdapterRecycle(struct HdfIoService *ioService)
115 {
116     struct HdfSyscallAdapter *adapter = NULL;
117 
118     if (ioService == NULL) {
119         return;
120     }
121 
122     adapter = CONTAINER_OF(ioService, struct HdfSyscallAdapter, super);
123     if (adapter->client.device != NULL && adapter->client.device->service != NULL &&
124         adapter->client.device->service->Release != NULL) {
125         adapter->client.device->service->Release(&adapter->client);
126     }
127 
128     OsalMutexDestroy(&adapter->mutex);
129 }
130 
AddListenerToAdapterLocked(struct HdfSyscallAdapter * adapter,struct HdfDevEventlistener * listener)131 static bool AddListenerToAdapterLocked(struct HdfSyscallAdapter *adapter, struct HdfDevEventlistener *listener)
132 {
133     struct HdfDevEventlistener *it = NULL;
134     DLIST_FOR_EACH_ENTRY(it, &adapter->listenerList, struct HdfDevEventlistener, listNode) {
135         if (it == listener) {
136             HDF_LOGE("Add a listener for duplicate dev-event");
137             return false;
138         }
139     }
140     DListInsertTail(&listener->listNode, &adapter->listenerList);
141     return true;
142 }
143 
HdfDeviceRegisterEventListener(struct HdfIoService * target,struct HdfDevEventlistener * listener)144 int32_t HdfDeviceRegisterEventListener(struct HdfIoService *target, struct HdfDevEventlistener *listener)
145 {
146     if (target == NULL || listener == NULL) {
147         return HDF_ERR_INVALID_PARAM;
148     }
149 
150     if (listener->callBack == NULL && listener->onReceive == NULL) {
151         HDF_LOGE("Listener onReceive func not implemented");
152         return HDF_ERR_INVALID_OBJECT;
153     }
154 
155     struct HdfSyscallAdapter *adapter = CONTAINER_OF(target, struct HdfSyscallAdapter, super);
156 
157     OsalMutexLock(&adapter->mutex);
158     if (!AddListenerToAdapterLocked(adapter, listener)) {
159         OsalMutexUnlock(&adapter->mutex);
160         return HDF_ERR_INVALID_PARAM;
161     }
162     OsalMutexUnlock(&adapter->mutex);
163     return HDF_SUCCESS;
164 }
165 
HdfDeviceUnregisterEventListener(struct HdfIoService * target,struct HdfDevEventlistener * listener)166 int32_t HdfDeviceUnregisterEventListener(struct HdfIoService *target, struct HdfDevEventlistener *listener)
167 {
168     if (target == NULL || listener == NULL) {
169         return HDF_ERR_INVALID_PARAM;
170     }
171 
172     if (listener->listNode.next == NULL || listener->listNode.prev == NULL) {
173         HDF_LOGE("%s: broken listener, may double unregister", __func__);
174         return HDF_ERR_INVALID_OBJECT;
175     }
176 
177     struct HdfSyscallAdapter *adapter = CONTAINER_OF(target, struct HdfSyscallAdapter, super);
178     OsalMutexLock(&adapter->mutex);
179     DListRemove(&listener->listNode);
180     OsalMutexUnlock(&adapter->mutex);
181     return HDF_SUCCESS;
182 }
183 
HdfDeviceSendEvent(const struct HdfDeviceObject * deviceObject,uint32_t id,const struct HdfSBuf * data)184 int32_t HdfDeviceSendEvent(const struct HdfDeviceObject *deviceObject, uint32_t id, const struct HdfSBuf *data)
185 {
186     const struct HdfSyscallAdapter *adapter = NULL;
187 
188     if (deviceObject == NULL || data == NULL) {
189         return HDF_ERR_INVALID_PARAM;
190     }
191 
192     struct HdfDeviceObject *inputDriverObject = GetHdfDeviceObject();
193 
194     if (inputDriverObject == NULL) {
195         return HDF_ERR_NOT_SUPPORT;
196     }
197 
198     if (deviceObject == inputDriverObject) {
199         adapter = CONTAINER_OF(deviceObject, struct HdfSyscallAdapter, deviceObject);
200         struct HdfDevEventlistener *listener = NULL;
201         DLIST_FOR_EACH_ENTRY(listener, &adapter->listenerList, struct HdfDevEventlistener, listNode) {
202             OsalMutexLock(&adapter->mutex);
203             if (listener->onReceive != NULL) {
204                 (void)listener->onReceive(listener, &adapter->super, id, data);
205             } else if (listener->callBack != NULL) {
206                 (void)listener->callBack(listener->priv, id, data);
207             }
208             OsalMutexUnlock(&adapter->mutex);
209         }
210     }
211     return HDF_SUCCESS;
212 }
213