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