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 DevHostServiceClntFreeInstance(hostClnt);
325 return HDF_FAILURE;
326 }
327
328 DListInsertTail(&hostClnt->node, &devmgr->hosts);
329
330 // not start the host which only have dynamic devices
331 if (HdfSListIsEmpty(&hostClnt->unloadDevInfos)) {
332 return HDF_SUCCESS;
333 }
334
335 if (DevmgrServiceStartHostProcess(hostClnt, false, false) != HDF_SUCCESS) {
336 HDF_LOGW("failed to start device host, host id is %{public}u", hostAttr->hostId);
337 DListRemove(&hostClnt->node);
338 DevHostServiceClntFreeInstance(hostClnt);
339 return HDF_FAILURE;
340 }
341 return HDF_SUCCESS;
342 }
343
DevmgrServiceStartDeviceHosts(struct DevmgrService * inst)344 static int DevmgrServiceStartDeviceHosts(struct DevmgrService *inst)
345 {
346 int ret;
347 struct HdfSList hostList;
348 struct HdfSListIterator it;
349 struct HdfHostInfo *hostAttr = NULL;
350
351 HdfSListInit(&hostList);
352 if (!HdfAttributeManagerGetHostList(&hostList)) {
353 HDF_LOGW("%{public}s: host list is null", __func__);
354 return HDF_SUCCESS;
355 }
356 HdfSListIteratorInit(&it, &hostList);
357 while (HdfSListIteratorHasNext(&it)) {
358 hostAttr = (struct HdfHostInfo *)HdfSListIteratorNext(&it);
359 ret = DevmgrServiceStartDeviceHost(inst, hostAttr);
360 if (ret != HDF_SUCCESS) {
361 HDF_LOGW("%{public}s failed to start device host, host id is %{public}u, host name is '%{public}s'",
362 __func__, hostAttr->hostId, hostAttr->hostName);
363 }
364 }
365 HdfSListFlush(&hostList, HdfHostInfoDelete);
366 return HDF_SUCCESS;
367 }
368
DevmgrServiceListAllDevice(struct IDevmgrService * inst,struct HdfSBuf * reply)369 static int32_t DevmgrServiceListAllDevice(struct IDevmgrService *inst, struct HdfSBuf *reply)
370 {
371 struct DevmgrService *devMgrSvc = (struct DevmgrService *)inst;
372 struct DevHostServiceClnt *hostClnt = NULL;
373 struct HdfSListIterator iterator;
374 struct HdfSListNode *node = NULL;
375 const char *name = NULL;
376
377 if (devMgrSvc == NULL || reply == NULL) {
378 HDF_LOGE("%{public}s failed, parameter is null", __func__);
379 return HDF_FAILURE;
380 }
381
382 DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
383 HdfSbufWriteString(reply, hostClnt->hostName);
384 HdfSbufWriteUint32(reply, hostClnt->hostId);
385 HdfSbufWriteUint32(reply, HdfSListCount(&hostClnt->devices));
386
387 HdfSListIteratorInit(&iterator, &hostClnt->devices);
388 while (HdfSListIteratorHasNext(&iterator)) {
389 node = HdfSListIteratorNext(&iterator);
390 struct DeviceTokenClnt *tokenClnt = (struct DeviceTokenClnt *)node;
391 if (tokenClnt != NULL && tokenClnt->tokenIf != NULL) {
392 name = (tokenClnt->tokenIf->deviceName == NULL) ? "" : tokenClnt->tokenIf->deviceName;
393 HdfSbufWriteString(reply, name);
394 HdfSbufWriteUint32(reply, tokenClnt->tokenIf->devid);
395 name = (tokenClnt->tokenIf->servName == NULL) ? "" : tokenClnt->tokenIf->servName;
396 HdfSbufWriteString(reply, name);
397 } else {
398 HDF_LOGI("%{public}s host:%{public}s token null", __func__, hostClnt->hostName);
399 }
400 }
401 }
402 return HDF_SUCCESS;
403 }
404
DevmgrServiceListAllHost(struct IDevmgrService * inst,struct HdfSBuf * reply)405 static int32_t DevmgrServiceListAllHost(struct IDevmgrService *inst, struct HdfSBuf *reply)
406 {
407 struct DevmgrService *devMgrSvc = (struct DevmgrService *)inst;
408 struct DevHostServiceClnt *hostClnt = NULL;
409
410 if (devMgrSvc == NULL || reply == NULL) {
411 HDF_LOGE("%{public}s failed, parameter is null", __func__);
412 return HDF_FAILURE;
413 }
414
415 if (!HdfSbufWriteUint32(reply, DListGetCount(&devMgrSvc->hosts) + 1)) {
416 HDF_LOGE("Sbuf Write host count failed");
417 return HDF_FAILURE;
418 }
419 DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) {
420 if (!HdfSbufWriteInt32(reply, hostClnt->hostProcessId)) {
421 HDF_LOGE("%{public}s: Sbuf Write host pid failed", __func__);
422 return HDF_FAILURE;
423 }
424 }
425
426 return HDF_SUCCESS;
427 }
428
DevmgrServiceStartService(struct IDevmgrService * inst)429 int DevmgrServiceStartService(struct IDevmgrService *inst)
430 {
431 int ret;
432 struct DevmgrService *dmService = (struct DevmgrService *)inst;
433 if (dmService == NULL) {
434 HDF_LOGE("failed to start device manager service, dmService is null");
435 return HDF_FAILURE;
436 }
437
438 ret = DevmgrServiceStartDeviceHosts(dmService);
439 int startServiceRet = DevSvcManagerStartService();
440 HDF_LOGI("start svcmgr result %{public}d. Init DeviceHosts info result: %{public}d", startServiceRet, ret);
441 return ret;
442 }
443
DevmgrServicePowerStateChange(struct IDevmgrService * devmgrService,enum HdfPowerState powerState)444 int DevmgrServicePowerStateChange(struct IDevmgrService *devmgrService, enum HdfPowerState powerState)
445 {
446 struct DevHostServiceClnt *hostClient = NULL;
447 struct DevmgrService *devmgr = NULL;
448 int result = HDF_SUCCESS;
449
450 if (devmgrService == NULL) {
451 return HDF_ERR_INVALID_OBJECT;
452 }
453
454 if (!IsValidPowerState(powerState)) {
455 HDF_LOGE("%{public}s:invalid power event %{public}u", __func__, powerState);
456 return HDF_ERR_INVALID_PARAM;
457 }
458 devmgr = CONTAINER_OF(devmgrService, struct DevmgrService, super);
459
460 if (IsPowerWakeState(powerState)) {
461 HDF_LOGI("%{public}s:wake state %{public}u", __func__, powerState);
462 DLIST_FOR_EACH_ENTRY(hostClient, &devmgr->hosts, struct DevHostServiceClnt, node) {
463 if (hostClient->hostService != NULL) {
464 if (hostClient->hostService->PmNotify(hostClient->hostService, powerState) != HDF_SUCCESS) {
465 result = HDF_FAILURE;
466 }
467 }
468 }
469 } else {
470 HDF_LOGI("%{public}s:suspend state %{public}u", __func__, powerState);
471 DLIST_FOR_EACH_ENTRY_REVERSE(hostClient, &devmgr->hosts, struct DevHostServiceClnt, node) {
472 if (hostClient->hostService != NULL) {
473 if (hostClient->hostService->PmNotify(hostClient->hostService, powerState) != HDF_SUCCESS) {
474 result = HDF_FAILURE;
475 }
476 }
477 }
478 }
479
480 return result;
481 }
482
DevmgrServiceConstruct(struct DevmgrService * inst)483 bool DevmgrServiceConstruct(struct DevmgrService *inst)
484 {
485 if (inst == NULL) {
486 HDF_LOGE("%{public}s:inst is null ", __func__);
487 return false;
488 }
489 struct IDevmgrService *devMgrSvcIf = NULL;
490 if (OsalMutexInit(&inst->devMgrMutex) != HDF_SUCCESS) {
491 HDF_LOGE("%{public}s:failed to mutex init ", __func__);
492 return false;
493 }
494 devMgrSvcIf = (struct IDevmgrService *)inst;
495 if (devMgrSvcIf != NULL) {
496 devMgrSvcIf->AttachDevice = DevmgrServiceAttachDevice;
497 devMgrSvcIf->DetachDevice = DevmgrServiceDetachDevice;
498 devMgrSvcIf->LoadDevice = DevmgrServiceLoadDevice;
499 devMgrSvcIf->UnloadDevice = DevmgrServiceUnloadDevice;
500 devMgrSvcIf->AttachDeviceHost = DevmgrServiceAttachDeviceHost;
501 devMgrSvcIf->StartService = DevmgrServiceStartService;
502 devMgrSvcIf->PowerStateChange = DevmgrServicePowerStateChange;
503 devMgrSvcIf->ListAllDevice = DevmgrServiceListAllDevice;
504 devMgrSvcIf->ListAllHost = DevmgrServiceListAllHost;
505 DListHeadInit(&inst->hosts);
506 return true;
507 } else {
508 return false;
509 }
510 }
511
DevmgrServiceCreate(void)512 struct HdfObject *DevmgrServiceCreate(void)
513 {
514 static bool isDevMgrServiceInit = false;
515 static struct DevmgrService devmgrServiceInstance;
516 if (!isDevMgrServiceInit) {
517 if (!DevmgrServiceConstruct(&devmgrServiceInstance)) {
518 return NULL;
519 }
520 isDevMgrServiceInit = true;
521 }
522 return (struct HdfObject *)&devmgrServiceInstance;
523 }
524
DevmgrServiceGetInstance(void)525 struct IDevmgrService *DevmgrServiceGetInstance(void)
526 {
527 static struct IDevmgrService *instance = NULL;
528 if (instance == NULL) {
529 instance = (struct IDevmgrService *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVMGR_SERVICE);
530 }
531 return instance;
532 }
533
DevmgrServiceRelease(struct HdfObject * object)534 void DevmgrServiceRelease(struct HdfObject *object)
535 {
536 struct DevmgrService *devmgrService = (struct DevmgrService *)object;
537 struct DevHostServiceClnt *hostClnt = NULL;
538 struct DevHostServiceClnt *hostClntTmp = NULL;
539 if (devmgrService == NULL) {
540 return;
541 }
542 DLIST_FOR_EACH_ENTRY_SAFE(hostClnt, hostClntTmp, &devmgrService->hosts, struct DevHostServiceClnt, node) {
543 DListRemove(&hostClnt->node);
544 DevHostServiceClntDelete(hostClnt);
545 }
546
547 OsalMutexDestroy(&devmgrService->devMgrMutex);
548 }
549