• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "devmgr_service.h"
10 #include "devhost_service_clnt.h"
11 #include "device_token_clnt.h"
12 #include "devsvc_manager.h"
13 #include "hdf_attribute_manager.h"
14 #include "hdf_base.h"
15 #include "hdf_driver_installer.h"
16 #include "hdf_host_info.h"
17 #include "hdf_core_log.h"
18 #include "hdf_object_manager.h"
19 #include "osal_time.h"
20 
21 #define HDF_LOG_TAG devmgr_service
22 #define INVALID_PID (-1)
23 
DevmgrServiceDynamicDevInfoFound(const char * svcName,struct DevHostServiceClnt ** targetHostClnt,struct HdfDeviceInfo ** targetDeviceInfo)24 static bool DevmgrServiceDynamicDevInfoFound(
25     const char *svcName, struct DevHostServiceClnt **targetHostClnt, struct HdfDeviceInfo **targetDeviceInfo)
26 {
27     struct HdfSListIterator itDeviceInfo;
28     struct HdfDeviceInfo *deviceInfo = NULL;
29     struct DevHostServiceClnt *hostClnt = NULL;
30     struct DevmgrService *devMgrSvc = (struct DevmgrService *)DevmgrServiceGetInstance();
31     if (devMgrSvc == NULL) {
32         return false;
33     }
34     if (targetHostClnt == NULL || targetDeviceInfo == NULL) {
35         HDF_LOGE("invalid params");
36         return false;
37     }
38 
39     DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
40         HdfSListIteratorInit(&itDeviceInfo, &hostClnt->dynamicDevInfos);
41         while (HdfSListIteratorHasNext(&itDeviceInfo)) {
42             deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
43             if (strcmp(deviceInfo->svcName, svcName) == 0) {
44                 *targetDeviceInfo = deviceInfo;
45                 *targetHostClnt = hostClnt;
46                 return true;
47             }
48         }
49     }
50 
51     return false;
52 }
53 
54 #define WAIT_HOST_SLEEP_TIME    2 // ms
55 #define WAIT_HOST_SLEEP_CNT     1000
DevmgrServiceStartHostProcess(struct DevHostServiceClnt * hostClnt,bool sync,bool dynamic)56 static int DevmgrServiceStartHostProcess(struct DevHostServiceClnt *hostClnt, bool sync, bool dynamic)
57 {
58     int waitCount = WAIT_HOST_SLEEP_CNT;
59     struct IDriverInstaller *installer = DriverInstallerGetInstance();
60     if (installer == NULL || installer->StartDeviceHost == NULL) {
61         HDF_LOGE("invalid installer");
62         return HDF_FAILURE;
63     }
64 
65     hostClnt->hostPid = installer->StartDeviceHost(hostClnt->hostId, hostClnt->hostName, dynamic);
66     if (hostClnt->hostPid == HDF_FAILURE) {
67         HDF_LOGW("failed to start device host(%{public}s, %{public}u)", hostClnt->hostName, hostClnt->hostId);
68         return HDF_FAILURE;
69     }
70     hostClnt->stopFlag = false;
71     if (!sync) {
72         return HDF_SUCCESS;
73     }
74 
75     while (hostClnt->hostService == NULL && waitCount > 0) {
76         OsalMSleep(WAIT_HOST_SLEEP_TIME);
77         waitCount--;
78     }
79 
80     if (waitCount <= 0) {
81         HDF_LOGE("wait host(%{public}s, %{public}d) attach timeout", hostClnt->hostName, hostClnt->hostId);
82         if (installer->StopDeviceHost != NULL) {
83             installer->StopDeviceHost(hostClnt->hostId, hostClnt->hostName);
84         }
85         hostClnt->hostPid = -1;
86         return HDF_ERR_TIMEOUT;
87     }
88 
89     return HDF_SUCCESS;
90 }
91 
DevmgrServiceLoadDevice(struct IDevmgrService * devMgrSvc,const char * serviceName)92 static int DevmgrServiceLoadDevice(struct IDevmgrService *devMgrSvc, const char *serviceName)
93 {
94     struct HdfDeviceInfo *deviceInfo = NULL;
95     struct DevHostServiceClnt *hostClnt = NULL;
96     bool dynamic = true;
97     int ret;
98     (void)devMgrSvc;
99 
100     if (serviceName == NULL) {
101         return HDF_ERR_INVALID_PARAM;
102     }
103 
104     if (!DevmgrServiceDynamicDevInfoFound(serviceName, &hostClnt, &deviceInfo)) {
105         HDF_LOGE("device %{public}s not in configed device list", serviceName);
106         return HDF_DEV_ERR_NO_DEVICE;
107     }
108 
109     if (deviceInfo->preload != DEVICE_PRELOAD_DISABLE) {
110         HDF_LOGE("device %{public}s not an dynamic load device", serviceName);
111         return HDF_DEV_ERR_NORANGE;
112     }
113 
114     dynamic = HdfSListIsEmpty(&hostClnt->unloadDevInfos) && !HdfSListIsEmpty(&hostClnt->dynamicDevInfos);
115     OsalMutexLock(&hostClnt->hostLock);
116     if (hostClnt->hostPid < 0) {
117         OsalMutexUnlock(&hostClnt->hostLock);
118         if (DevmgrServiceStartHostProcess(hostClnt, true, dynamic) != HDF_SUCCESS) {
119             HDF_LOGW("failed to start device host(%{public}s, %{public}u)", hostClnt->hostName, hostClnt->hostId);
120             return HDF_FAILURE;
121         }
122         OsalMutexLock(&hostClnt->hostLock);
123     }
124 
125     if (hostClnt->hostService == NULL || hostClnt->hostService->AddDevice == NULL) {
126         OsalMutexUnlock(&hostClnt->hostLock);
127         HDF_LOGE("%{public}s load %{public}s failed, hostService is null", __func__, serviceName);
128         return HDF_FAILURE;
129     }
130     ret = hostClnt->hostService->AddDevice(hostClnt->hostService, deviceInfo);
131     OsalMutexUnlock(&hostClnt->hostLock);
132     if (ret == HDF_SUCCESS) {
133         deviceInfo->status = HDF_SERVICE_USABLE;
134     }
135     return ret;
136 }
137 
DevmgrServiceStopHost(struct DevHostServiceClnt * hostClnt)138 static int DevmgrServiceStopHost(struct DevHostServiceClnt *hostClnt)
139 {
140     struct IDriverInstaller *installer = DriverInstallerGetInstance();
141     if (installer == NULL || installer->StopDeviceHost == NULL) {
142         HDF_LOGE("invalid installer");
143         return HDF_FAILURE;
144     }
145     installer->StopDeviceHost(hostClnt->hostId, hostClnt->hostName);
146     hostClnt->stopFlag = true;
147     return HDF_SUCCESS;
148 }
149 
DevmgrServiceUnloadDevice(struct IDevmgrService * devMgrSvc,const char * serviceName)150 static int DevmgrServiceUnloadDevice(struct IDevmgrService *devMgrSvc, const char *serviceName)
151 {
152     struct HdfDeviceInfo *deviceInfo = NULL;
153     struct DevHostServiceClnt *hostClnt = NULL;
154     int ret;
155     (void)devMgrSvc;
156 
157     if (serviceName == NULL) {
158         return HDF_ERR_INVALID_PARAM;
159     }
160 
161     if (!DevmgrServiceDynamicDevInfoFound(serviceName, &hostClnt, &deviceInfo) ||
162         deviceInfo->preload != DEVICE_PRELOAD_DISABLE) {
163         HDF_LOGE("device %{public}s not in configed dynamic device list", serviceName);
164         return HDF_DEV_ERR_NO_DEVICE;
165     }
166     OsalMutexLock(&hostClnt->hostLock);
167     if (hostClnt->hostService == NULL || hostClnt->hostService->DelDevice == NULL) {
168         OsalMutexUnlock(&hostClnt->hostLock);
169         HDF_LOGE("%{public}s unload %{public}s failed, hostService is null", __func__, serviceName);
170         return HDF_FAILURE;
171     }
172     ret = hostClnt->hostService->DelDevice(hostClnt->hostService, deviceInfo->deviceId);
173     if (ret != HDF_SUCCESS) {
174         OsalMutexUnlock(&hostClnt->hostLock);
175         HDF_LOGI("%{public}s:unload service %{public}s delDevice failed", __func__, serviceName);
176         return ret;
177     }
178     deviceInfo->status = HDF_SERVICE_UNUSABLE;
179     if (!HdfSListIsEmpty(&hostClnt->devices)) {
180         OsalMutexUnlock(&hostClnt->hostLock);
181         HDF_LOGD("%{public}s host %{public}s devices is not empty", __func__, hostClnt->hostName);
182         return HDF_SUCCESS;
183     }
184     if (!HdfSListIsEmpty(&hostClnt->unloadDevInfos)) {
185         OsalMutexUnlock(&hostClnt->hostLock);
186         HDF_LOGD("%{public}s the hdf_devmgr need not to stop automatically started host %{public}s", __func__,
187             hostClnt->hostName);
188         return HDF_SUCCESS;
189     }
190     hostClnt->hostPid = INVALID_PID;
191     hostClnt->hostService = NULL; // old hostService will be recycled in CleanupDiedHostResources
192     HdfSListFlush(&hostClnt->devices, DeviceTokenClntDelete);
193     OsalMutexUnlock(&hostClnt->hostLock);
194     ret = DevmgrServiceStopHost(hostClnt);
195 
196     return ret;
197 }
198 
DevmgrServiceLoadLeftDriver(struct DevmgrService * devMgrSvc)199 int32_t DevmgrServiceLoadLeftDriver(struct DevmgrService *devMgrSvc)
200 {
201     int32_t ret;
202     struct HdfSListIterator itDeviceInfo;
203     struct HdfDeviceInfo *deviceInfo = NULL;
204     struct DevHostServiceClnt *hostClnt = NULL;
205     if (devMgrSvc == NULL) {
206         return HDF_FAILURE;
207     }
208 
209     DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
210         HdfSListIteratorInit(&itDeviceInfo, &hostClnt->unloadDevInfos);
211         while (HdfSListIteratorHasNext(&itDeviceInfo)) {
212             deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo);
213             if (deviceInfo->preload == DEVICE_PRELOAD_ENABLE_STEP2) {
214                 ret = hostClnt->hostService->AddDevice(hostClnt->hostService, deviceInfo);
215                 if (ret != HDF_SUCCESS) {
216                     HDF_LOGE("%{public}s:failed to load driver %{public}s", __func__, deviceInfo->moduleName);
217                     continue;
218                 }
219                 deviceInfo->status = HDF_SERVICE_USABLE;
220                 HdfSListIteratorRemove(&itDeviceInfo);
221             }
222         }
223     }
224     return HDF_SUCCESS;
225 }
226 
DevmgrServiceFindDeviceHost(struct IDevmgrService * inst,uint16_t hostId)227 static struct DevHostServiceClnt *DevmgrServiceFindDeviceHost(struct IDevmgrService *inst, uint16_t hostId)
228 {
229     struct DevHostServiceClnt *hostClnt = NULL;
230     struct DevmgrService *dmService = (struct DevmgrService *)inst;
231     if (dmService == NULL) {
232         HDF_LOGE("failed to find device host, dmService is null");
233         return NULL;
234     }
235 
236     DLIST_FOR_EACH_ENTRY(hostClnt, &dmService->hosts, struct DevHostServiceClnt, node) {
237         if (hostClnt->hostId == hostId) {
238             return hostClnt;
239         }
240     }
241     HDF_LOGE("cannot find host %{public}u", hostId);
242     return NULL;
243 }
244 
DevmgrServiceAttachDevice(struct IDevmgrService * inst,struct IHdfDeviceToken * token)245 static int DevmgrServiceAttachDevice(struct IDevmgrService *inst, struct IHdfDeviceToken *token)
246 {
247     struct DevHostServiceClnt *hostClnt = NULL;
248     struct DeviceTokenClnt *tokenClnt = NULL;
249 
250     if (token == NULL) {
251         return HDF_FAILURE;
252     }
253     hostClnt = DevmgrServiceFindDeviceHost(inst, HOSTID(token->devid));
254     if (hostClnt == NULL) {
255         HDF_LOGE("failed to attach device, hostClnt is null");
256         return HDF_FAILURE;
257     }
258     tokenClnt = DeviceTokenClntNewInstance(token);
259     if (tokenClnt == NULL) {
260         HDF_LOGE("failed to attach device, tokenClnt is null");
261         return HDF_FAILURE;
262     }
263 
264     HdfSListAdd(&hostClnt->devices, &tokenClnt->node);
265     return HDF_SUCCESS;
266 }
267 
HdfSListHostSearchDeviceTokenComparer(struct HdfSListNode * tokenNode,uint32_t devid)268 static bool HdfSListHostSearchDeviceTokenComparer(struct HdfSListNode *tokenNode, uint32_t devid)
269 {
270     struct DeviceTokenClnt *tokenClnt = CONTAINER_OF(tokenNode, struct DeviceTokenClnt, node);
271     return tokenClnt->tokenIf->devid == devid;
272 }
273 
DevmgrServiceDetachDevice(struct IDevmgrService * inst,devid_t devid)274 static int DevmgrServiceDetachDevice(struct IDevmgrService *inst, devid_t devid)
275 {
276     struct DevHostServiceClnt *hostClnt = NULL;
277     struct DeviceTokenClnt *tokenClnt = NULL;
278     struct HdfSListNode *tokenClntNode = NULL;
279 
280     hostClnt = DevmgrServiceFindDeviceHost(inst, HOSTID(devid));
281     if (hostClnt == NULL) {
282         HDF_LOGE("failed to attach device, hostClnt is null");
283         return HDF_FAILURE;
284     }
285     tokenClntNode = HdfSListSearch(&hostClnt->devices, devid, HdfSListHostSearchDeviceTokenComparer);
286     if (tokenClntNode == NULL) {
287         HDF_LOGE("devmgr detach devic not found");
288         return HDF_DEV_ERR_NO_DEVICE;
289     }
290     tokenClnt = CONTAINER_OF(tokenClntNode, struct DeviceTokenClnt, node);
291     HdfSListRemove(&hostClnt->devices, &tokenClnt->node);
292     return HDF_SUCCESS;
293 }
294 
DevmgrServiceAttachDeviceHost(struct IDevmgrService * inst,uint16_t hostId,struct IDevHostService * hostService)295 static int DevmgrServiceAttachDeviceHost(
296     struct IDevmgrService *inst, uint16_t hostId, struct IDevHostService *hostService)
297 {
298     struct DevHostServiceClnt *hostClnt = DevmgrServiceFindDeviceHost(inst, hostId);
299     if (hostClnt == NULL) {
300         HDF_LOGE("failed to attach device host, hostClnt is null");
301         return HDF_FAILURE;
302     }
303     if (hostService == NULL) {
304         HDF_LOGE("failed to attach device host, hostService is null");
305         return HDF_FAILURE;
306     }
307 
308     (void)OsalMutexLock(&hostClnt->hostLock);
309     hostClnt->hostService = hostService;
310     (void)OsalMutexUnlock(&hostClnt->hostLock);
311     return DevHostServiceClntInstallDriver(hostClnt);
312 }
313 
DevmgrServiceStartDeviceHost(struct DevmgrService * devmgr,struct HdfHostInfo * hostAttr)314 static int DevmgrServiceStartDeviceHost(struct DevmgrService *devmgr, struct HdfHostInfo *hostAttr)
315 {
316     struct DevHostServiceClnt *hostClnt = DevHostServiceClntNewInstance(hostAttr->hostId, hostAttr->hostName);
317     if (hostClnt == NULL) {
318         HDF_LOGW("failed to create new device host client");
319         return HDF_FAILURE;
320     }
321 
322     if (HdfAttributeManagerGetDeviceList(hostClnt) != HDF_SUCCESS) {
323         HDF_LOGW("failed to get device list for host %{public}s", hostClnt->hostName);
324         return HDF_FAILURE;
325     }
326 
327     DListInsertTail(&hostClnt->node, &devmgr->hosts);
328 
329     // not start the host which only have dynamic devices
330     if (HdfSListIsEmpty(&hostClnt->unloadDevInfos)) {
331         return HDF_SUCCESS;
332     }
333 
334     if (DevmgrServiceStartHostProcess(hostClnt, false, false) != HDF_SUCCESS) {
335         HDF_LOGW("failed to start device host, host id is %{public}u", hostAttr->hostId);
336         DListRemove(&hostClnt->node);
337         DevHostServiceClntFreeInstance(hostClnt);
338         return HDF_FAILURE;
339     }
340     return HDF_SUCCESS;
341 }
342 
DevmgrServiceStartDeviceHosts(struct DevmgrService * inst)343 static int DevmgrServiceStartDeviceHosts(struct DevmgrService *inst)
344 {
345     int ret;
346     struct HdfSList hostList;
347     struct HdfSListIterator it;
348     struct HdfHostInfo *hostAttr = NULL;
349 
350     HdfSListInit(&hostList);
351     if (!HdfAttributeManagerGetHostList(&hostList)) {
352         HDF_LOGW("%{public}s: host list is null", __func__);
353         return HDF_SUCCESS;
354     }
355     HdfSListIteratorInit(&it, &hostList);
356     while (HdfSListIteratorHasNext(&it)) {
357         hostAttr = (struct HdfHostInfo *)HdfSListIteratorNext(&it);
358         ret = DevmgrServiceStartDeviceHost(inst, hostAttr);
359         if (ret != HDF_SUCCESS) {
360             HDF_LOGW("%{public}s failed to start device host, host id is %{public}u, host name is '%{public}s'",
361                 __func__, hostAttr->hostId, hostAttr->hostName);
362         }
363     }
364     HdfSListFlush(&hostList, HdfHostInfoDelete);
365     return HDF_SUCCESS;
366 }
367 
DevmgrServiceListAllDevice(struct IDevmgrService * inst,struct HdfSBuf * reply)368 static int32_t DevmgrServiceListAllDevice(struct IDevmgrService *inst, struct HdfSBuf *reply)
369 {
370     struct DevmgrService *devMgrSvc = (struct DevmgrService *)inst;
371     struct DevHostServiceClnt *hostClnt = NULL;
372     struct HdfSListIterator iterator;
373     struct HdfSListNode *node = NULL;
374     const char *name = NULL;
375 
376     if (devMgrSvc == NULL || reply == NULL) {
377         HDF_LOGE("%{public}s failed, parameter is null", __func__);
378         return HDF_FAILURE;
379     }
380 
381     DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
382         HdfSbufWriteString(reply, hostClnt->hostName);
383         HdfSbufWriteUint32(reply, hostClnt->hostId);
384         HdfSbufWriteUint32(reply, HdfSListCount(&hostClnt->devices));
385 
386         HdfSListIteratorInit(&iterator, &hostClnt->devices);
387         while (HdfSListIteratorHasNext(&iterator)) {
388             node = HdfSListIteratorNext(&iterator);
389             struct DeviceTokenClnt *tokenClnt = (struct DeviceTokenClnt *)node;
390             if (tokenClnt != NULL && tokenClnt->tokenIf != NULL) {
391                 name = (tokenClnt->tokenIf->deviceName == NULL) ? "" : tokenClnt->tokenIf->deviceName;
392                 HdfSbufWriteString(reply, name);
393                 HdfSbufWriteUint32(reply, tokenClnt->tokenIf->devid);
394                 name = (tokenClnt->tokenIf->servName == NULL) ? "" : tokenClnt->tokenIf->servName;
395                 HdfSbufWriteString(reply, name);
396             } else {
397                 HDF_LOGI("%{public}s host:%{public}s token null", __func__, hostClnt->hostName);
398             }
399         }
400     }
401     return HDF_SUCCESS;
402 }
403 
DevmgrServiceListAllHost(struct IDevmgrService * inst,struct HdfSBuf * reply)404 static int32_t DevmgrServiceListAllHost(struct IDevmgrService *inst, struct HdfSBuf *reply)
405 {
406     struct DevmgrService *devMgrSvc = (struct DevmgrService *)inst;
407     struct DevHostServiceClnt *hostClnt = NULL;
408 
409     if (devMgrSvc == NULL || reply == NULL) {
410         HDF_LOGE("%{public}s failed, parameter is null", __func__);
411         return HDF_FAILURE;
412     }
413 
414     if (!HdfSbufWriteUint32(reply, DListGetCount(&devMgrSvc->hosts) + 1)) {
415         HDF_LOGE("Sbuf Write host count failed");
416         return HDF_FAILURE;
417     }
418     DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
419         if (!HdfSbufWriteInt32(reply, hostClnt->hostProcessId)) {
420             HDF_LOGE("%{public}s: Sbuf Write host pid failed", __func__);
421             return HDF_FAILURE;
422         }
423     }
424 
425     return HDF_SUCCESS;
426 }
427 
DevmgrServiceStartService(struct IDevmgrService * inst)428 int DevmgrServiceStartService(struct IDevmgrService *inst)
429 {
430     int ret;
431     struct DevmgrService *dmService = (struct DevmgrService *)inst;
432     if (dmService == NULL) {
433         HDF_LOGE("failed to start device manager service, dmService is null");
434         return HDF_FAILURE;
435     }
436 
437     ret = DevmgrServiceStartDeviceHosts(dmService);
438     int startServiceRet = DevSvcManagerStartService();
439     HDF_LOGI("start svcmgr result %{public}d. Init DeviceHosts info result: %{public}d", startServiceRet, ret);
440     return ret;
441 }
442 
DevmgrServicePowerStateChange(struct IDevmgrService * devmgrService,enum HdfPowerState powerState)443 int DevmgrServicePowerStateChange(struct IDevmgrService *devmgrService, enum HdfPowerState powerState)
444 {
445     struct DevHostServiceClnt *hostClient = NULL;
446     struct DevmgrService *devmgr = NULL;
447     int result = HDF_SUCCESS;
448 
449     if (devmgrService == NULL) {
450         return HDF_ERR_INVALID_OBJECT;
451     }
452 
453     if (!IsValidPowerState(powerState)) {
454         HDF_LOGE("%{public}s:invalid power event %{public}u", __func__, powerState);
455         return HDF_ERR_INVALID_PARAM;
456     }
457     devmgr = CONTAINER_OF(devmgrService, struct DevmgrService, super);
458 
459     if (IsPowerWakeState(powerState)) {
460         HDF_LOGI("%{public}s:wake state %{public}u", __func__, powerState);
461         DLIST_FOR_EACH_ENTRY(hostClient, &devmgr->hosts, struct DevHostServiceClnt, node) {
462             if (hostClient->hostService != NULL) {
463                 if (hostClient->hostService->PmNotify(hostClient->hostService, powerState) != HDF_SUCCESS) {
464                     result = HDF_FAILURE;
465                 }
466             }
467         }
468     } else {
469         HDF_LOGI("%{public}s:suspend state %{public}u", __func__, powerState);
470         DLIST_FOR_EACH_ENTRY_REVERSE(hostClient, &devmgr->hosts, struct DevHostServiceClnt, node) {
471             if (hostClient->hostService != NULL) {
472                 if (hostClient->hostService->PmNotify(hostClient->hostService, powerState) != HDF_SUCCESS) {
473                     result = HDF_FAILURE;
474                 }
475             }
476         }
477     }
478 
479     return result;
480 }
481 
DevmgrServiceConstruct(struct DevmgrService * inst)482 bool DevmgrServiceConstruct(struct DevmgrService *inst)
483 {
484     if (inst == NULL) {
485         HDF_LOGE("%{public}s:inst is null ", __func__);
486         return false;
487     }
488     struct IDevmgrService *devMgrSvcIf = NULL;
489     if (OsalMutexInit(&inst->devMgrMutex) != HDF_SUCCESS) {
490         HDF_LOGE("%{public}s:failed to mutex init ", __func__);
491         return false;
492     }
493     devMgrSvcIf = (struct IDevmgrService *)inst;
494     if (devMgrSvcIf != NULL) {
495         devMgrSvcIf->AttachDevice = DevmgrServiceAttachDevice;
496         devMgrSvcIf->DetachDevice = DevmgrServiceDetachDevice;
497         devMgrSvcIf->LoadDevice = DevmgrServiceLoadDevice;
498         devMgrSvcIf->UnloadDevice = DevmgrServiceUnloadDevice;
499         devMgrSvcIf->AttachDeviceHost = DevmgrServiceAttachDeviceHost;
500         devMgrSvcIf->StartService = DevmgrServiceStartService;
501         devMgrSvcIf->PowerStateChange = DevmgrServicePowerStateChange;
502         devMgrSvcIf->ListAllDevice = DevmgrServiceListAllDevice;
503         devMgrSvcIf->ListAllHost = DevmgrServiceListAllHost;
504         DListHeadInit(&inst->hosts);
505         return true;
506     } else {
507         return false;
508     }
509 }
510 
DevmgrServiceCreate(void)511 struct HdfObject *DevmgrServiceCreate(void)
512 {
513     static bool isDevMgrServiceInit = false;
514     static struct DevmgrService devmgrServiceInstance;
515     if (!isDevMgrServiceInit) {
516         if (!DevmgrServiceConstruct(&devmgrServiceInstance)) {
517             return NULL;
518         }
519         isDevMgrServiceInit = true;
520     }
521     return (struct HdfObject *)&devmgrServiceInstance;
522 }
523 
DevmgrServiceGetInstance(void)524 struct IDevmgrService *DevmgrServiceGetInstance(void)
525 {
526     static struct IDevmgrService *instance = NULL;
527     if (instance == NULL) {
528         instance = (struct IDevmgrService *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVMGR_SERVICE);
529     }
530     return instance;
531 }
532 
DevmgrServiceRelease(struct HdfObject * object)533 void DevmgrServiceRelease(struct HdfObject *object)
534 {
535     struct DevmgrService *devmgrService = (struct DevmgrService *)object;
536     struct DevHostServiceClnt *hostClnt = NULL;
537     struct DevHostServiceClnt *hostClntTmp = NULL;
538     if (devmgrService == NULL) {
539         return;
540     }
541     DLIST_FOR_EACH_ENTRY_SAFE(hostClnt, hostClntTmp, &devmgrService->hosts, struct DevHostServiceClnt, node) {
542         DListRemove(&hostClnt->node);
543         DevHostServiceClntDelete(hostClnt);
544     }
545 
546     OsalMutexDestroy(&devmgrService->devMgrMutex);
547 }
548