From 25e4076f9721a51fefdbf00ec0048b9a85ba892b Mon Sep 17 00:00:00 2001 From: yuanbo Date: Tue, 16 Nov 2021 10:48:45 +0800 Subject: [PATCH] support union device id Signed-off-by: yuanbo --- core/adapter/vnode/src/hdf_vnode_adapter.c | 2 +- core/common/src/hdf_attribute.c | 9 +- core/common/src/hdf_device_node_ext.c | 88 +++++----- core/common/src/load_driver_entry.c | 69 -------- core/host/include/devhost_service.h | 2 +- core/host/include/devmgr_service_clnt.h | 3 +- core/host/include/hdf_device.h | 35 +++- core/host/include/hdf_device_node.h | 35 ++-- core/host/include/hdf_driver_loader.h | 7 +- core/host/include/hdf_observer_record.h | 6 +- core/host/include/hdf_service_subscriber.h | 5 +- core/host/src/devhost_service.c | 83 +++++----- core/host/src/devmgr_service_clnt.c | 20 ++- core/host/src/devsvc_manager_clnt.c | 1 - core/host/src/hdf_device.c | 72 ++++++-- core/host/src/hdf_device_node.c | 184 ++++++++++++++------- core/host/src/hdf_device_object.c | 24 +-- core/host/src/hdf_driver_loader.c | 93 ++++------- core/host/src/hdf_observer_record.c | 9 +- core/host/src/hdf_service_observer.c | 14 +- core/host/src/hdf_service_subscriber.c | 5 +- core/manager/src/devmgr_service.c | 54 ++++-- core/manager/src/driver_manager.c | 122 ++++++++++++++ core/shared/include/devhost_service_if.h | 3 +- core/shared/include/device_token_if.h | 2 + core/shared/include/devmgr_service_if.h | 3 +- core/shared/include/hdf_driver.h | 30 ++++ test/unittest/manager/sample_driver_test.c | 34 ++-- utils/include/hdf_cstring.h | 1 + utils/src/hdf_cstring.c | 24 +++ 30 files changed, 658 insertions(+), 381 deletions(-) delete mode 100644 core/common/src/load_driver_entry.c create mode 100644 core/manager/src/driver_manager.c create mode 100644 core/shared/include/hdf_driver.h diff --git a/core/adapter/vnode/src/hdf_vnode_adapter.c b/core/adapter/vnode/src/hdf_vnode_adapter.c index 340054fb..b3c7de64 100644 --- a/core/adapter/vnode/src/hdf_vnode_adapter.c +++ b/core/adapter/vnode/src/hdf_vnode_adapter.c @@ -643,7 +643,7 @@ int32_t HdfDeviceSendEvent(const struct HdfDeviceObject *deviceObject, uint32_t } deviceNode = CONTAINER_OF(deviceObject, struct HdfDeviceNode, deviceObject); - if (deviceNode->deviceInfo->policy != SERVICE_POLICY_CAPACITY) { + if (deviceNode->policy != SERVICE_POLICY_CAPACITY) { return HDF_ERR_NOT_SUPPORT; } diff --git a/core/common/src/hdf_attribute.c b/core/common/src/hdf_attribute.c index b6af3fe7..ac3849bd 100644 --- a/core/common/src/hdf_attribute.c +++ b/core/common/src/hdf_attribute.c @@ -247,6 +247,8 @@ static bool GetDeviceNodeInfo(const struct DeviceResourceNode *deviceNode, struc struct HdfSList *HdfAttributeManagerGetDeviceList(uint16_t hostId, const char *hostName) { uint16_t deviceIdx = 0; + uint8_t deviceNnodeIdx = 0; + struct HdfDeviceInfo *deviceNodeInfo = NULL; const struct DeviceResourceNode *hostNode = GetHostNode(hostName); struct HdfSList *deviceList = NULL; const struct DeviceResourceNode *device = NULL; @@ -261,7 +263,8 @@ struct HdfSList *HdfAttributeManagerGetDeviceList(uint16_t hostId, const char *h while (device != NULL) { const struct DeviceResourceNode *deviceNode = device->child; while (deviceNode != NULL) { - struct HdfDeviceInfo *deviceNodeInfo = HdfDeviceInfoNewInstance(); + deviceNnodeIdx = 0; + deviceNodeInfo = HdfDeviceInfoNewInstance(); if (deviceNodeInfo == NULL) { HdfSListFlush(deviceList, HdfDeviceInfoDelete); OsalMemFree(deviceList); @@ -282,10 +285,12 @@ struct HdfSList *HdfAttributeManagerGetDeviceList(uint16_t hostId, const char *h deviceNode = deviceNode->sibling; continue; } - deviceNodeInfo->deviceId = deviceIdx++; + deviceNodeInfo->deviceId = MK_DEVID(hostId, deviceIdx, deviceNnodeIdx); + deviceNnodeIdx++; deviceNode = deviceNode->sibling; } device = device->sibling; + deviceIdx++; } if (HdfSListCount(deviceList) == 0) { OsalMemFree(deviceList); diff --git a/core/common/src/hdf_device_node_ext.c b/core/common/src/hdf_device_node_ext.c index c0eab0d7..13fb2c6d 100644 --- a/core/common/src/hdf_device_node_ext.c +++ b/core/common/src/hdf_device_node_ext.c @@ -20,7 +20,6 @@ static int DeviceNodeExtDispatch(struct HdfObject *stub, int code, struct HdfSBuf *data, struct HdfSBuf *reply) { struct IDeviceIoService *deviceMethod = NULL; - const struct HdfDeviceInfo *deviceInfo = NULL; struct HdfDeviceNode *devNode = NULL; uint64_t ioClientPtr = 0; @@ -39,12 +38,8 @@ static int DeviceNodeExtDispatch(struct HdfObject *stub, int code, struct HdfSBu HDF_LOGE("device ext dispatch: device service interface is null"); return HDF_FAILURE; } - deviceInfo = devNode->deviceInfo; - if (deviceInfo == NULL) { - HDF_LOGE("device ext dispatch: device deviceInfo is null"); - return HDF_FAILURE; - } - if (deviceInfo->policy == SERVICE_POLICY_CAPACITY) { + + if (devNode->policy == SERVICE_POLICY_CAPACITY) { if (deviceMethod->Dispatch == NULL) { HDF_LOGE("device ext dispatch: remote service dispatch method is null"); return HDF_FAILURE; @@ -54,57 +49,80 @@ static int DeviceNodeExtDispatch(struct HdfObject *stub, int code, struct HdfSBu return HDF_FAILURE; } -static int DeviceNodeExtPublishService(struct HdfDeviceNode *inst, const char *serviceName) +static int DeviceNodeExtPublishService(struct HdfDeviceNode *devNode) { - const struct HdfDeviceInfo *deviceInfo = NULL; struct HdfDeviceObject *deviceObject = NULL; - struct DeviceNodeExt *devNodeExt = (struct DeviceNodeExt *)inst; + struct DeviceNodeExt *devNodeExt = (struct DeviceNodeExt *)devNode; int ret; + static struct HdfIoDispatcher dispatcher = { .Dispatch = DeviceNodeExtDispatch }; + if (devNodeExt == NULL) { return HDF_FAILURE; } - ret = HdfDeviceNodePublishPublicService(inst, serviceName); - if (ret != HDF_SUCCESS) { - HDF_LOGE("failed to publish device service, ret is %d", ret); - return HDF_FAILURE; - } - deviceInfo = inst->deviceInfo; deviceObject = &devNodeExt->super.deviceObject; - if ((deviceObject->service == NULL) || (deviceInfo == NULL)) { - HDF_LOGE("Device service interface or deviceInfo is null"); + if (deviceObject->service == NULL) { + HDF_LOGE("device service interface is null"); return HDF_FAILURE; } - if (deviceInfo->policy == SERVICE_POLICY_CAPACITY) { - devNodeExt->ioService = HdfIoServicePublish(serviceName, deviceInfo->permission); + if (devNode->policy == SERVICE_POLICY_CAPACITY) { + devNodeExt->ioService = HdfIoServicePublish(devNode->servName, devNode->permission); if (devNodeExt->ioService != NULL) { - static struct HdfIoDispatcher dispatcher = { - .Dispatch = DeviceNodeExtDispatch - }; - devNodeExt->ioService->target = (struct HdfObject*)(&inst->deviceObject); + devNodeExt->ioService->target = (struct HdfObject *)(deviceObject); devNodeExt->ioService->dispatcher = &dispatcher; } else { - HDF_LOGE("Device remote service bind failed"); - HdfDeviceNodeReclaimService(serviceName); - return HDF_FAILURE; + HDF_LOGE("device remote service publish failed"); + return HDF_DEV_ERR_NO_DEVICE_SERVICE; } } + + // base(device node) publish inner service + ret = HdfDeviceNodePublishPublicService(devNode); + if (ret != HDF_SUCCESS) { + HDF_LOGE("failed to publish device service, ret is %d", ret); + HdfIoServiceRemove(devNodeExt->ioService); + devNodeExt->ioService = NULL; + return ret; + } + return HDF_SUCCESS; } +int DeviceNodeExtRemoveService(struct HdfDeviceNode *devNode) +{ + struct DeviceNodeExt *devNodeExt = CONTAINER_OF(devNode, struct DeviceNodeExt, super); + if (devNode == NULL) { + return HDF_ERR_INVALID_PARAM; + } + + if (devNode->policy == SERVICE_POLICY_CAPACITY) { + HdfIoServiceRemove(devNodeExt->ioService); + devNodeExt->ioService = NULL; + } + + // remove inner service published by base + return HdfDeviceNodeRemoveService(devNode); +} + static void DeviceNodeExtConstruct(struct DeviceNodeExt *inst) { struct IDeviceNode *nodeIf = (struct IDeviceNode *)inst; if (nodeIf != NULL) { HdfDeviceNodeConstruct(&inst->super); nodeIf->PublishService = DeviceNodeExtPublishService; + nodeIf->RemoveService = DeviceNodeExtRemoveService; } } +static void DeviceNodeExtDestruct(struct DeviceNodeExt *devnode) +{ + DeviceNodeExtRemoveService(&devnode->super); + HdfDeviceNodeDestruct(&devnode->super); +} + struct HdfObject *DeviceNodeExtCreate() { - struct DeviceNodeExt *instance = - (struct DeviceNodeExt *)OsalMemCalloc(sizeof(struct DeviceNodeExt)); + struct DeviceNodeExt *instance = (struct DeviceNodeExt *)OsalMemCalloc(sizeof(struct DeviceNodeExt)); if (instance != NULL) { DeviceNodeExtConstruct(instance); instance->ioService = NULL; @@ -114,13 +132,9 @@ struct HdfObject *DeviceNodeExtCreate() void DeviceNodeExtRelease(struct HdfObject *object) { - struct DeviceNodeExt *instance = (struct DeviceNodeExt *)object; - if (instance != NULL) { - if (instance->ioService != NULL) { - HdfIoServiceRemove(instance->ioService); - } - HdfDeviceNodeDestruct(&instance->super); - OsalMemFree(instance); + struct DeviceNodeExt *devnode = (struct DeviceNodeExt *)object; + if (devnode != NULL) { + DeviceNodeExtDestruct(devnode); + OsalMemFree(devnode); } } - diff --git a/core/common/src/load_driver_entry.c b/core/common/src/load_driver_entry.c deleted file mode 100644 index 165a7840..00000000 --- a/core/common/src/load_driver_entry.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. - * - * HDF is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * See the LICENSE file in the root of this repository for complete details. - */ - -#include "hdf_driver_loader.h" -#include "hdf_log.h" -#include "osal_mem.h" - -static struct HdfDriverEntry *HdfDriverEntryConstruct(int32_t *driverCount) -{ - int i; - struct HdfDriverEntry *driverEntry = NULL; - size_t *addrBegin = NULL; - *driverCount = (int32_t)(((uint8_t *)(HDF_DRIVER_END()) - (uint8_t *)(HDF_DRIVER_BEGIN())) / sizeof(size_t)); - if (*driverCount <= 0) { - HDF_LOGE("%s: failed to hdf get device counts", __func__); - return NULL; - } - driverEntry = OsalMemCalloc(*driverCount * sizeof(struct HdfDriverEntry)); - if (driverEntry == NULL) { - HDF_LOGE("%s: failed to alloc driver entry mem", __func__); - *driverCount = 0; - return NULL; - } - addrBegin = (size_t *)(HDF_DRIVER_BEGIN()); - for (i = 0; i < *driverCount; i++) { - driverEntry[i] = *(struct HdfDriverEntry *)(*addrBegin); - addrBegin++; - } - return driverEntry; -} - -struct HdfDriverEntry *HdfDriverLoaderGetDriverEntry(const struct HdfDeviceInfo *deviceInfo) -{ - int i; - static struct HdfDriverEntry *driverEntry = NULL; - static int32_t driverCount = 0; - if ((deviceInfo == NULL) || (deviceInfo->moduleName == NULL) || (deviceInfo->svcName == NULL)) { - HDF_LOGE("%s: failed to get device entry, input deviceInfo is NULL", __func__); - return NULL; - } - if (driverEntry == NULL) { - driverEntry = HdfDriverEntryConstruct(&driverCount); - if (driverEntry == NULL) { - HDF_LOGE("%s: failed to construct driver entry", __func__); - return NULL; - } - } - for (i = 0; i < driverCount; i++) { - if (driverEntry == NULL) { - HDF_LOGE("%s: driver entry is null", __func__); - return NULL; - } - if (driverEntry[i].moduleName == NULL) { - HDF_LOGE("%s: driver entry module name is null", __func__); - continue; - } - if (strcmp(deviceInfo->moduleName, driverEntry[i].moduleName) == 0) { - return &driverEntry[i]; - } - } - HDF_LOGE("failed to get device entry %s", deviceInfo->svcName); - return NULL; -} - diff --git a/core/host/include/devhost_service.h b/core/host/include/devhost_service.h index eb7347ee..8ddba0ce 100644 --- a/core/host/include/devhost_service.h +++ b/core/host/include/devhost_service.h @@ -27,7 +27,7 @@ struct DevHostService { void DevHostServiceConstruct(struct DevHostService *service); void DevHostServiceDestruct(struct DevHostService *service); int DevHostServiceAddDevice(struct IDevHostService *inst, const struct HdfDeviceInfo *deviceInfo); -int DevHostServiceDelDevice(struct IDevHostService *inst, const struct HdfDeviceInfo *deviceInfo); +int DevHostServiceDelDevice(struct IDevHostService *inst, devid_t devId); struct IDevHostService *DevHostServiceNewInstance(uint16_t hostId, const char *hostName); void DevHostServiceFreeInstance(struct IDevHostService *service); struct HdfObject *DevHostServiceCreate(void); diff --git a/core/host/include/devmgr_service_clnt.h b/core/host/include/devmgr_service_clnt.h index 87216668..d5aecee8 100644 --- a/core/host/include/devmgr_service_clnt.h +++ b/core/host/include/devmgr_service_clnt.h @@ -19,7 +19,8 @@ struct DevmgrServiceClnt { struct DevmgrServiceClnt *DevmgrServiceClntGetInstance(void); void DevmgrServiceClntFreeInstance(struct DevmgrServiceClnt *inst); -int DevmgrServiceClntAttachDevice(const struct HdfDeviceInfo *deviceInfo, struct IHdfDeviceToken *deviceToken); +int DevmgrServiceClntAttachDevice(struct IHdfDeviceToken *deviceToken); +int DevmgrServiceClntDetachDevice(devid_t devid); int DevmgrServiceClntAttachDeviceHost(uint16_t hostId, struct IDevHostService *hostService); #endif /* DEVMGR_SERVICE_CLIENT_H */ diff --git a/core/host/include/hdf_device.h b/core/host/include/hdf_device.h index 25e2a065..7048dff5 100644 --- a/core/host/include/hdf_device.h +++ b/core/host/include/hdf_device.h @@ -9,20 +9,40 @@ #ifndef HDF_DEVICE_H #define HDF_DEVICE_H -#include "devhost_service.h" -#include "device_token_if.h" #include "hdf_device_desc.h" -#include "hdf_object.h" -#include "hdf_service_observer.h" #include "hdf_dlist.h" -#include "osal_mutex.h" +#include "hdf_object.h" + +/* + * -----------------+----------------+----------------+----------------+ + * | BYTE | BYTE | BYTE | BYTE | + * +---------------------------------+---------------------------------+ + * | host id | device id | device node id | + * -----------------+---------------------------------+----------------+ + */ +typedef uint32_t devid_t; + +#define HOSTID_BITS 8 +#define DEVICEID_BITS 16 +#define DEVNODEID_BITS 8 +#define DEVNODEID_MASK ((1 << DEVNODEID_BITS) - 1) +#define DEVICEID_MASK ((1 << DEVICEID_BITS) - 1) + +#define HOSTID(devid) (devid >> (DEVICEID_BITS + DEVNODEID_BITS)) +#define DEVICEID(devid) ((devid >> DEVNODEID_BITS) & DEVICEID_MASK) +#define DEVNODEID(devid) (devid & DEVNODEID_MASK) + +#define MK_DEVID(hostId, deviceId, devnodeId) \ + (hostId << (DEVICEID_BITS + DEVNODEID_BITS) | deviceId << DEVNODEID_BITS | devnodeId) struct HdfDeviceNode; struct IHdfDevice { struct HdfObject object; - int (*Attach)(struct IHdfDevice *, struct HdfDeviceNode *); - void (*Detach)(struct IHdfDevice *, struct HdfDeviceNode *); + int (*Attach)(struct IHdfDevice *device, struct HdfDeviceNode *deviceNode); + int (*Detach)(struct IHdfDevice *device, struct HdfDeviceNode *deviceNode); + struct HdfDeviceNode *(*GetDeviceNode)(struct IHdfDevice *device, devid_t devid); + int (*DetachWithDevid)(struct IHdfDevice *device, devid_t devid); }; struct HdfDevice { @@ -38,6 +58,5 @@ struct HdfObject *HdfDeviceCreate(void); void HdfDeviceRelease(struct HdfObject *object); struct HdfDevice *HdfDeviceNewInstance(void); void HdfDeviceFreeInstance(struct HdfDevice *device); -void HdfDeviceDelete(struct HdfSListNode *deviceEntry); #endif /* HDF_DEVICE_H */ diff --git a/core/host/include/hdf_device_node.h b/core/host/include/hdf_device_node.h index 475158ea..1c203854 100644 --- a/core/host/include/hdf_device_node.h +++ b/core/host/include/hdf_device_node.h @@ -13,6 +13,7 @@ #include "hdf_device_info.h" #include "hdf_device_desc.h" #include "hdf_dlist.h" +#include "hdf_driver.h" #include "hdf_pm.h" struct HdfDeviceNode; @@ -20,8 +21,10 @@ struct DevHostService; struct IDeviceNode { struct HdfObject object; - int (*PublishService)(struct HdfDeviceNode *, const char *); - int (*LaunchNode)(struct HdfDeviceNode *, struct IHdfDevice *); + int (*PublishService)(struct HdfDeviceNode *devNode); + int (*RemoveService)(struct HdfDeviceNode *devNode); + int (*LaunchNode)(struct HdfDeviceNode *devNode); + int (*ReleaseNode)(struct HdfDeviceNode *devNode); }; struct HdfDeviceNode { @@ -31,20 +34,32 @@ struct HdfDeviceNode { struct DevHostService *hostService; struct HdfDeviceObject deviceObject; struct IHdfDeviceToken *token; - struct HdfDriverEntry *driverEntry; - const struct HdfDeviceInfo *deviceInfo; + struct HdfDriver *driver; + const struct HdfDevice *device; + char *servName; + devid_t devId; + uint16_t policy; + uint16_t permission; + uint8_t devStatus; + bool servStatus; +}; + +enum DevNodeStaus { + DEVNODE_NONE = 0, + DEVNODE_INITED, + DEVNODE_LAUNCHED, }; int HdfDeviceNodeAddPowerStateListener( struct HdfDeviceNode *devNode, const struct IPowerEventListener *listener); void HdfDeviceNodeRemovePowerStateListener( struct HdfDeviceNode *devNode, const struct IPowerEventListener *listener); -void HdfDeviceNodeConstruct(struct HdfDeviceNode *service); -void HdfDeviceNodeDestruct(struct HdfDeviceNode *service); -struct HdfDeviceNode *HdfDeviceNodeNewInstance(void); -void HdfDeviceNodeFreeInstance(struct HdfDeviceNode *service); +void HdfDeviceNodeConstruct(struct HdfDeviceNode *devNode); +void HdfDeviceNodeDestruct(struct HdfDeviceNode *devNode); +struct HdfDeviceNode *HdfDeviceNodeNewInstance(const struct HdfDeviceInfo *deviceInfo, struct HdfDriver *driver); +void HdfDeviceNodeFreeInstance(struct HdfDeviceNode *devNode); void HdfDeviceNodeDelete(struct HdfDeviceNode *devNode); -int HdfDeviceNodePublishPublicService(struct HdfDeviceNode *service, const char *svcName); -void HdfDeviceNodeReclaimService(const char *svcName); +int HdfDeviceNodePublishPublicService(struct HdfDeviceNode *devNode); +int HdfDeviceNodeRemoveService(struct HdfDeviceNode *devNode); #endif /* HDF_DEVICE_NODE_H */ diff --git a/core/host/include/hdf_driver_loader.h b/core/host/include/hdf_driver_loader.h index 56048807..e22d29c2 100644 --- a/core/host/include/hdf_driver_loader.h +++ b/core/host/include/hdf_driver_loader.h @@ -15,9 +15,8 @@ struct IDriverLoader { struct HdfObject object; - struct HdfDriverEntry *(*GetDriverEntry)(const struct HdfDeviceInfo *deviceInfo); - struct HdfDeviceNode *(*LoadNode)(struct IDriverLoader *, const struct HdfDeviceInfo *deviceInfo); - void (*UnLoadNode)(struct IDriverLoader *, const struct HdfDeviceInfo *deviceInfo); + struct HdfDriver *(*GetDriver)(const char *driverName); + void (*ReclaimDriver)(struct HdfDriver *driver); }; struct HdfDriverLoader { @@ -28,7 +27,7 @@ struct HdfObject *HdfDriverLoaderCreate(void); void HdfDriverLoaderConstruct(struct HdfDriverLoader *inst); void HdfDriverLoaderRelease(struct HdfObject *object); struct IDriverLoader *HdfDriverLoaderGetInstance(void); -struct HdfDriverEntry *HdfDriverLoaderGetDriverEntry(const struct HdfDeviceInfo *deviceInfo); +struct HdfDriver *HdfDriverLoaderGetDriver(const char *moduleName); struct HdfDeviceNode *HdfDriverLoaderLoadNode( struct IDriverLoader *loader, const struct HdfDeviceInfo *deviceInfo); void HdfDriverLoaderUnLoadNode(struct IDriverLoader *loader, const struct HdfDeviceInfo *deviceInfo); diff --git a/core/host/include/hdf_observer_record.h b/core/host/include/hdf_observer_record.h index a8bcbd93..7e63ab82 100644 --- a/core/host/include/hdf_observer_record.h +++ b/core/host/include/hdf_observer_record.h @@ -9,6 +9,7 @@ #ifndef HDF_OBSERVER_RECORD_H #define HDF_OBSERVER_RECORD_H +#include "hdf_device.h" #include "hdf_object.h" #include "hdf_slist.h" #include "osal_mutex.h" @@ -17,18 +18,17 @@ struct HdfServiceObserverRecord { struct HdfSListNode entry; uint32_t serviceKey; uint16_t policy; - uint32_t matchId; + devid_t devId; struct OsalMutex obsRecMutex; struct HdfSList subscribers; struct HdfObject *publisher; }; -uint32_t HdfMakeHardwareId(uint16_t hostId, uint16_t deviceId); struct HdfServiceObserverRecord *HdfServiceObserverRecordObtain(uint32_t serviceKey); void HdfServiceObserverRecordRecycle(struct HdfServiceObserverRecord *record); bool HdfServiceObserverRecordCompare(struct HdfSListNode *listEntry, uint32_t serviceKey); void HdfServiceObserverRecordNotifySubscribers( - struct HdfServiceObserverRecord *record, uint32_t matchId, uint16_t policy); + struct HdfServiceObserverRecord *record, devid_t devid, uint16_t policy); void HdfServiceObserverRecordDelete(struct HdfSListNode *listEntry); #endif /* HDF_OBSERVER_RECORD_H */ diff --git a/core/host/include/hdf_service_subscriber.h b/core/host/include/hdf_service_subscriber.h index 2d2528b0..29ba7477 100644 --- a/core/host/include/hdf_service_subscriber.h +++ b/core/host/include/hdf_service_subscriber.h @@ -9,13 +9,14 @@ #ifndef HDF_SERVICE_SUBSCRIBER_H #define HDF_SERVICE_SUBSCRIBER_H +#include "hdf_device.h" #include "hdf_device_desc.h" #include "hdf_slist.h" struct HdfServiceSubscriber { struct HdfSListNode entry; uint32_t state; - uint32_t matchId; + uint32_t devId; struct SubscriberCallback callback; }; @@ -24,7 +25,7 @@ enum { HDF_SUBSCRIBER_STATE_READY }; -struct HdfServiceSubscriber *HdfServiceSubscriberObtain(struct SubscriberCallback callback, uint32_t matchId); +struct HdfServiceSubscriber *HdfServiceSubscriberObtain(struct SubscriberCallback callback, devid_t devid); void HdfServiceSubscriberRecycle(struct HdfServiceSubscriber *subscriber); void HdfServiceSubscriberDelete(struct HdfSListNode *listEntry); diff --git a/core/host/src/devhost_service.c b/core/host/src/devhost_service.c index 984f6e6c..a964cec5 100644 --- a/core/host/src/devhost_service.c +++ b/core/host/src/devhost_service.c @@ -11,6 +11,7 @@ #include "devsvc_manager_clnt.h" #include "hdf_base.h" #include "hdf_driver_loader.h" +#include "hdf_driver.h" #include "hdf_log.h" #include "hdf_object_manager.h" #include "osal_mem.h" @@ -34,16 +35,15 @@ static struct HdfDevice *DevHostServiceFindDevice(struct DevHostService *hostSer return NULL; } -static void DevHostServiceFreeDevice(struct DevHostService *hostService, uint16_t deviceId) +static void DevHostServiceFreeDevice(struct DevHostService *hostService, struct HdfDevice *device) { - struct HdfDevice *device = DevHostServiceFindDevice(hostService, deviceId); if (device != NULL) { DListRemove(&device->node); HdfDeviceFreeInstance(device); } } -static struct HdfDevice *DevHostServiceGetDevice(struct DevHostService *inst, uint16_t deviceId) +static struct HdfDevice *DevHostServiceQueryOrAddDevice(struct DevHostService *inst, uint16_t deviceId) { struct HdfDevice *device = DevHostServiceFindDevice(inst, deviceId); if (device == NULL) { @@ -64,79 +64,88 @@ int DevHostServiceAddDevice(struct IDevHostService *inst, const struct HdfDevice int ret = HDF_FAILURE; struct HdfDevice *device = NULL; struct HdfDeviceNode *devNode = NULL; + struct HdfDriver *driver = NULL; struct DevHostService *hostService = CONTAINER_OF(inst, struct DevHostService, super); struct IDriverLoader *driverLoader = HdfDriverLoaderGetInstance(); - if (inst == NULL || deviceInfo == NULL || driverLoader == NULL || driverLoader->LoadNode == NULL) { + if (inst == NULL || deviceInfo == NULL || driverLoader == NULL || driverLoader->GetDriver == NULL) { HDF_LOGE("failed to add device, input param is null"); return ret; } - device = DevHostServiceGetDevice(hostService, deviceInfo->deviceId); + device = DevHostServiceQueryOrAddDevice(hostService, DEVICEID(deviceInfo->deviceId)); if (device == NULL || device->super.Attach == NULL) { ret = HDF_DEV_ERR_NO_DEVICE; goto error; } - devNode = driverLoader->LoadNode(driverLoader, deviceInfo); - if (devNode == NULL) { - ret = HDF_DEV_ERR_NO_DEVICE_SERVICE; + driver = driverLoader->GetDriver(deviceInfo->moduleName); + if (driver == NULL) { + ret = HDF_DEV_ERR_NODATA; goto error; } + + devNode = HdfDeviceNodeNewInstance(deviceInfo, driver); + if (devNode == NULL) { + driverLoader->ReclaimDriver(driver); + ret = HDF_DEV_ERR_NO_MEMORY; + goto error; + } + devNode->hostService = hostService; + devNode->device = device; + devNode->driver = driver; ret = device->super.Attach(&device->super, devNode); if (ret != HDF_SUCCESS) { + HdfDeviceNodeFreeInstance(devNode); goto error; } return HDF_SUCCESS; error: - DevHostServiceFreeDevice(hostService, device->deviceId); + driverLoader->ReclaimDriver(driver); + DevHostServiceFreeDevice(hostService, device); return ret; } -static struct HdfDeviceNode *DevHostServiceSeparateDeviceNode(struct DListHead *deviceNodes, - const struct HdfDeviceInfo *deviceInfo) -{ - struct HdfDeviceNode *deviceNode = NULL; - DLIST_FOR_EACH_ENTRY(deviceNode, deviceNodes, struct HdfDeviceNode, entry) { - if (strcmp(deviceNode->deviceInfo->svcName, deviceInfo->svcName) == 0 && - strcmp(deviceNode->deviceInfo->moduleName, deviceInfo->moduleName) == 0) { - DListRemove(&deviceNode->entry); - return deviceNode; - } - } - return NULL; -} - -int DevHostServiceDelDevice(struct IDevHostService *inst, const struct HdfDeviceInfo *deviceInfo) +int DevHostServiceDelDevice(struct IDevHostService *inst, devid_t devId) { struct HdfDevice *device = NULL; struct DevHostService *hostService = (struct DevHostService *)inst; - struct IDriverLoader *driverLoader = HdfDriverLoaderGetInstance(); struct HdfDeviceNode *devNode = NULL; + struct HdfDriver *driver = NULL; + struct IDriverLoader *driverLoader = HdfDriverLoaderGetInstance(); - if ((deviceInfo == NULL) || (driverLoader == NULL) || (driverLoader->UnLoadNode == NULL)) { + if (driverLoader == NULL || driverLoader->ReclaimDriver == NULL) { HDF_LOGE("failed to del device, input param is null"); return HDF_FAILURE; } - device = DevHostServiceFindDevice(hostService, deviceInfo->deviceId); + device = DevHostServiceFindDevice(hostService, DEVICEID(devId)); if (device == NULL) { HDF_LOGW("failed to del device, device is not exist"); return HDF_SUCCESS; } - driverLoader->UnLoadNode(driverLoader, deviceInfo); - devNode = DevHostServiceSeparateDeviceNode(&device->devNodes, deviceInfo); - if (device->super.Detach != NULL) { - device->super.Detach(&device->super, devNode); - } else { - HdfDeviceNodeFreeInstance(devNode); + devNode = device->super.GetDeviceNode(&device->super, devId); + if (devNode == NULL) { + return HDF_DEV_ERR_NO_DEVICE; } - DevSvcManagerClntRemoveService(deviceInfo->svcName); + driver = devNode->driver; + + // device detach will release device node, do not use devNode after this + if (device->super.Detach != NULL) { + if (device->super.Detach(&device->super, devNode) != HDF_SUCCESS) { + HDF_LOGE("failed to del device %x", devId); + return HDF_FAILURE; + } + } + + // remove driver instance or close driver library + driverLoader->ReclaimDriver(driver); + if (DListIsEmpty(&device->devNodes)) { - DevHostServiceFreeDevice(hostService, device->deviceId); + DevHostServiceFreeDevice(hostService, device); } return HDF_SUCCESS; } @@ -163,7 +172,7 @@ static int ApplyDevicesPowerState(struct HdfDevice *device, uint32_t state) if (deviceNode->powerToken != NULL) { ret = PowerStateChange(deviceNode->powerToken, state); if (ret != HDF_SUCCESS) { - HDF_LOGE("device %s failed to resume(%d)", deviceNode->driverEntry->moduleName, state); + HDF_LOGE("device %s failed to resume(%d)", deviceNode->driver->entry->moduleName, state); } } } @@ -172,7 +181,7 @@ static int ApplyDevicesPowerState(struct HdfDevice *device, uint32_t state) if (deviceNode->powerToken != NULL) { ret = PowerStateChange(deviceNode->powerToken, state); if (ret != HDF_SUCCESS) { - HDF_LOGE("device %s failed to suspend(%d)", deviceNode->driverEntry->moduleName, state); + HDF_LOGE("device %s failed to suspend(%d)", deviceNode->driver->entry->moduleName, state); } } } diff --git a/core/host/src/devmgr_service_clnt.c b/core/host/src/devmgr_service_clnt.c index 378ec5f5..e690010e 100644 --- a/core/host/src/devmgr_service_clnt.c +++ b/core/host/src/devmgr_service_clnt.c @@ -31,7 +31,7 @@ int DevmgrServiceClntAttachDeviceHost(uint16_t hostId, struct IDevHostService *h return devMgrSvcIf->AttachDeviceHost(devMgrSvcIf, hostId, hostService); } -int DevmgrServiceClntAttachDevice(const struct HdfDeviceInfo *deviceInfo, struct IHdfDeviceToken *deviceToken) +int DevmgrServiceClntAttachDevice(struct IHdfDeviceToken *deviceToken) { struct IDevmgrService *devMgrSvcIf = NULL; struct DevmgrServiceClnt *inst = DevmgrServiceClntGetInstance(); @@ -45,7 +45,22 @@ int DevmgrServiceClntAttachDevice(const struct HdfDeviceInfo *deviceInfo, struct HDF_LOGE("devmgr client failed to attach device, dmsOps->AttachDevice is nul"); return HDF_FAILURE; } - return devMgrSvcIf->AttachDevice(devMgrSvcIf, deviceInfo, deviceToken); + return devMgrSvcIf->AttachDevice(devMgrSvcIf, deviceToken); +} +int DevmgrServiceClntDetachDevice(devid_t devid) +{ + struct IDevmgrService *devMgrSvcIf = NULL; + struct DevmgrServiceClnt *inst = DevmgrServiceClntGetInstance(); + if (inst == NULL || inst->devMgrSvcIf == NULL) { + HDF_LOGE("devmgr client failed to deatch device, inst is null"); + return HDF_FAILURE; + } + + devMgrSvcIf = inst->devMgrSvcIf; + if (devMgrSvcIf->DetachDevice == NULL) { + return HDF_FAILURE; + } + return devMgrSvcIf->DetachDevice(devMgrSvcIf, devid); } struct DevmgrServiceClnt *DevmgrServiceClntGetInstance() @@ -64,4 +79,3 @@ void DevmgrServiceClntFreeInstance(struct DevmgrServiceClnt *inst) inst->devMgrSvcIf = NULL; } } - diff --git a/core/host/src/devsvc_manager_clnt.c b/core/host/src/devsvc_manager_clnt.c index 3cce4a59..04569e5b 100644 --- a/core/host/src/devsvc_manager_clnt.c +++ b/core/host/src/devsvc_manager_clnt.c @@ -136,7 +136,6 @@ void DevSvcManagerClntRemoveService(const char *svcName) serviceManager = devSvcMgrClnt->devSvcMgrIf; if (serviceManager == NULL || serviceManager->RemoveService == NULL) { - HDF_LOGE("failed to remove service, method not implement"); return; } serviceManager->RemoveService(serviceManager, svcName); diff --git a/core/host/src/hdf_device.c b/core/host/src/hdf_device.c index 451faf99..ce30c37c 100644 --- a/core/host/src/hdf_device.c +++ b/core/host/src/hdf_device.c @@ -20,28 +20,80 @@ static int HdfDeviceAttach(struct IHdfDevice *devInst, struct HdfDeviceNode *devNode) { + int ret; struct HdfDevice *device = (struct HdfDevice *)devInst; struct IDeviceNode *nodeIf = (struct IDeviceNode *)devNode; if (device == NULL || nodeIf == NULL || nodeIf->LaunchNode == NULL) { HDF_LOGE("failed to attach device, input params invalid"); return HDF_ERR_INVALID_PARAM; } - DListInsertTail(&devNode->entry, &device->devNodes); - return nodeIf->LaunchNode(devNode, devInst); + + ret = nodeIf->LaunchNode(devNode); + if (ret == HDF_SUCCESS) { + DListInsertTail(&devNode->entry, &device->devNodes); + } + + return ret; +} + +static int HdfDeviceDetach(struct IHdfDevice *devInst, struct HdfDeviceNode *devNode) +{ + struct HdfDevice *device = NULL; + if (devInst == NULL || devNode == NULL) { + return HDF_ERR_INVALID_PARAM; + } + + device = CONTAINER_OF(devInst, struct HdfDevice, super); + if (device->deviceId != DEVICEID(devNode->devId)) { + HDF_LOGE("%s: device %x detach unknown devnode %x", __func__, device->deviceId, devNode->devId); + return HDF_DEV_ERR_NO_DEVICE; + } + DListRemove(&devNode->entry); + HdfDeviceNodeFreeInstance(devNode); + + return HDF_SUCCESS; +} + +static struct HdfDeviceNode *HdfDeviceGetDeviceNode(struct IHdfDevice *device, devid_t devid) +{ + struct HdfDeviceNode *devNode = NULL; + struct HdfDevice *dev = CONTAINER_OF(device, struct HdfDevice, super); + DLIST_FOR_EACH_ENTRY(devNode, &dev->devNodes, struct HdfDeviceNode, entry) { + if (devNode->devId == devid) { + return devNode; + }; + } + return NULL; +} + +static int HdfDeviceDetachWithDevid(struct IHdfDevice *device, devid_t devid) +{ + struct HdfDevice *dev = CONTAINER_OF(device, struct HdfDevice, super); + struct HdfDeviceNode *devNode = HdfDeviceGetDeviceNode(device, devid); + if (devNode == NULL) { + HDF_LOGE("detach device node %x not in device %x", devid, dev->deviceId); + return HDF_DEV_ERR_NO_DEVICE; + } + + return HdfDeviceDetach(device, devNode); } void HdfDeviceConstruct(struct HdfDevice *device) { device->super.Attach = HdfDeviceAttach; + device->super.Detach = HdfDeviceDetach; + device->super.DetachWithDevid = HdfDeviceDetachWithDevid; + device->super.GetDeviceNode = HdfDeviceGetDeviceNode; + DListHeadInit(&device->devNodes); } void HdfDeviceDestruct(struct HdfDevice *device) { struct HdfDeviceNode *devNode = NULL; - struct HdfDeviceNode *devNodeTmp = NULL; - DLIST_FOR_EACH_ENTRY_SAFE(devNode, devNodeTmp, &device->devNodes, struct HdfDeviceNode, entry) { - HdfDeviceNodeDelete(devNode); + struct HdfDeviceNode *tmp = NULL; + DLIST_FOR_EACH_ENTRY_SAFE(devNode, tmp, &device->devNodes, struct HdfDeviceNode, entry) { + HdfDeviceNodeFreeInstance(devNode); } DListHeadInit(&device->devNodes); } @@ -76,13 +128,3 @@ void HdfDeviceFreeInstance(struct HdfDevice *device) HdfObjectManagerFreeObject(&device->super.object); } } - -void HdfDeviceDelete(struct HdfSListNode *listEntry) -{ - if (listEntry != NULL) { - struct HdfDevice *device = (struct HdfDevice *)HDF_SLIST_CONTAINER_OF( - struct HdfSListNode, listEntry, struct HdfDevice, node); - HdfDeviceFreeInstance(device); - } -} - diff --git a/core/host/src/hdf_device_node.c b/core/host/src/hdf_device_node.c index f08c2539..93c33556 100644 --- a/core/host/src/hdf_device_node.c +++ b/core/host/src/hdf_device_node.c @@ -10,7 +10,10 @@ #include "devhost_service.h" #include "devmgr_service_clnt.h" #include "devsvc_manager_clnt.h" +#include "hcs_tree_if.h" +#include "hdf_attribute_manager.h" #include "hdf_base.h" +#include "hdf_cstring.h" #include "hdf_device_object.h" #include "hdf_device_token.h" #include "hdf_log.h" @@ -21,83 +24,82 @@ #define HDF_LOG_TAG device_node -static int HdfDeviceNodePublishLocalService( - struct HdfDeviceNode *devNode, const struct HdfDeviceInfo *deviceInfo) +static int HdfDeviceNodePublishLocalService(struct HdfDeviceNode *devNode) { - uint32_t matchId; - struct DevHostService *hostService = NULL; - if ((devNode == NULL) || (deviceInfo == NULL)) { + if (devNode == NULL) { HDF_LOGE("failed to publish local service, device is null"); return HDF_FAILURE; } - hostService = devNode->hostService; - if (hostService == NULL) { + if (devNode->hostService == NULL) { HDF_LOGE("failed to publish local service, host service is null"); return HDF_FAILURE; } - matchId = HdfMakeHardwareId(deviceInfo->hostId, deviceInfo->deviceId); - return HdfServiceObserverPublishService(&hostService->observer, deviceInfo->svcName, - matchId, deviceInfo->policy, (struct HdfObject *)devNode->deviceObject.service); + return HdfServiceObserverPublishService(&(devNode->hostService->observer), devNode->servName, + devNode->devId, devNode->policy, (struct HdfObject *)devNode->deviceObject.service); } -static int HdfDeviceNodePublishService( - struct HdfDeviceNode *devNode, const struct HdfDeviceInfo *deviceInfo, struct IHdfDevice *device) +static int HdfDeviceNodePublishService(struct HdfDeviceNode *devNode) { int status = HDF_SUCCESS; struct IDeviceNode *nodeIf = NULL; - (void)device; - if ((deviceInfo->policy == SERVICE_POLICY_NONE) || - ((deviceInfo->svcName != NULL) && (strlen(deviceInfo->svcName) == 0))) { - HDF_LOGI("policy is %d", SERVICE_POLICY_NONE); + if (devNode->policy == SERVICE_POLICY_NONE || + (devNode->servName != NULL && strlen(devNode->servName) == 0)) { return status; } nodeIf = &devNode->super; - if ((deviceInfo->policy == SERVICE_POLICY_PUBLIC) || - (deviceInfo->policy == SERVICE_POLICY_CAPACITY)) { + if (devNode->policy == SERVICE_POLICY_PUBLIC || devNode->policy == SERVICE_POLICY_CAPACITY) { if (nodeIf->PublishService != NULL) { - status = nodeIf->PublishService(devNode, deviceInfo->svcName); + status = nodeIf->PublishService(devNode); } } if (status == HDF_SUCCESS) { - status = HdfDeviceNodePublishLocalService(devNode, deviceInfo); + status = HdfDeviceNodePublishLocalService(devNode); } return status; } -int HdfDeviceLaunchNode(struct HdfDeviceNode *devNode, struct IHdfDevice *devInst) +int HdfDeviceLaunchNode(struct HdfDeviceNode *devNode) { - struct HdfDevice *device = (struct HdfDevice *)devInst; - struct HdfDriverEntry *driverEntry = NULL; - const struct HdfDeviceInfo *deviceInfo = NULL; - struct IHdfDeviceToken *deviceToken = NULL; + const struct HdfDriverEntry *driverEntry = NULL; int ret; - if (device == NULL || devNode == NULL) { + if (devNode == NULL) { HDF_LOGE("failed to launch service, device or service is null"); return HDF_ERR_INVALID_PARAM; } - driverEntry = devNode->driverEntry; - deviceInfo = devNode->deviceInfo; - if (deviceInfo == NULL) { - HDF_LOGE("failed to launch service, deviceInfo is null"); - return HDF_ERR_INVALID_PARAM; - } - - if ((driverEntry == NULL) || (driverEntry->Init == NULL)) { + HDF_LOGI("launch devnode %s", devNode->servName); + driverEntry = devNode->driver->entry; + if (driverEntry == NULL || driverEntry->Init == NULL) { HDF_LOGE("failed to launch service, deviceEntry invalid"); return HDF_ERR_INVALID_PARAM; } + + devNode->devStatus = DEVNODE_LAUNCHED; + if (devNode->policy == SERVICE_POLICY_PUBLIC || devNode->policy == SERVICE_POLICY_CAPACITY) { + if (driverEntry->Bind == NULL) { + HDF_LOGE("driver %s bind method is null, ignore device service publish", driverEntry->moduleName); + devNode->devStatus = DEVNODE_NONE; + return HDF_ERR_INVALID_OBJECT; + } + ret = driverEntry->Bind(&devNode->deviceObject); + if (ret != HDF_SUCCESS) { + HDF_LOGE("bind driver %s failed", driverEntry->moduleName); + return HDF_DEV_ERR_DEV_INIT_FAIL; + } + } + ret = driverEntry->Init(&devNode->deviceObject); if (ret != HDF_SUCCESS) { return HDF_DEV_ERR_DEV_INIT_FAIL; } - ret = HdfDeviceNodePublishService(devNode, deviceInfo, devInst); + + ret = HdfDeviceNodePublishService(devNode); if (ret != HDF_SUCCESS) { return HDF_DEV_ERR_PUBLISH_FAIL; } - deviceToken = devNode->token; - ret = DevmgrServiceClntAttachDevice(deviceInfo, deviceToken); + + ret = DevmgrServiceClntAttachDevice(devNode->token); if (ret != HDF_SUCCESS) { return HDF_DEV_ERR_ATTACHDEV_FAIL; } @@ -127,19 +129,29 @@ void HdfDeviceNodeRemovePowerStateListener( devNode->powerToken = NULL; } - -int HdfDeviceNodePublishPublicService(struct HdfDeviceNode *devNode, const char *svcName) +int HdfDeviceNodePublishPublicService(struct HdfDeviceNode *devNode) { - if ((devNode == NULL) || (devNode->deviceObject.service == NULL)) { + int ret; + if (devNode == NULL || devNode->deviceObject.service == NULL) { HDF_LOGE("failed to publish public service: devNode is NULL"); return HDF_FAILURE; } - return DevSvcManagerClntAddService(svcName, &devNode->deviceObject); + ret = DevSvcManagerClntAddService(devNode->servName, &devNode->deviceObject); + if (ret == HDF_SUCCESS) { + devNode->servStatus = true; + } + + return ret; } -void HdfDeviceNodeReclaimService(const char *svcName) +int HdfDeviceNodeRemoveService(struct HdfDeviceNode *devNode) { - DevSvcManagerClntRemoveService(svcName); + if (devNode != NULL && devNode->servStatus) { + DevSvcManagerClntRemoveService(devNode->servName); + devNode->servStatus = false; + } + + return HDF_SUCCESS; } void HdfDeviceNodeConstruct(struct HdfDeviceNode *devNode) @@ -150,6 +162,28 @@ void HdfDeviceNodeConstruct(struct HdfDeviceNode *devNode) devNode->token = HdfDeviceTokenNewInstance(); nodeIf->LaunchNode = HdfDeviceLaunchNode; nodeIf->PublishService = HdfDeviceNodePublishPublicService; + nodeIf->RemoveService = HdfDeviceNodeRemoveService; + } +} + +void HdfDeviceReleaseNode(struct HdfDeviceNode *devNode) +{ + const struct HdfDriverEntry *driverEntry = NULL; + if (devNode == NULL) { + return; + } + + if (devNode->driver != NULL) { + driverEntry = devNode->driver->entry; + } + + if (driverEntry != NULL && driverEntry->Release != NULL) { + driverEntry->Release(&devNode->deviceObject); + } + + if (devNode->servStatus) { + HdfDeviceNodeRemoveService(devNode); + DevmgrServiceClntDetachDevice(devNode->devId); } } @@ -158,31 +192,55 @@ void HdfDeviceNodeDestruct(struct HdfDeviceNode *devNode) if (devNode == NULL) { return; } - HdfDeviceTokenFreeInstance(devNode->token); - devNode->token = NULL; - PowerStateTokenFreeInstance(devNode->powerToken); - devNode->powerToken = NULL; + HDF_LOGI("release devnode %s", devNode->servName); + switch (devNode->devStatus) { + case DEVNODE_LAUNCHED: + HdfDeviceReleaseNode(devNode); + HdfDeviceTokenFreeInstance(devNode->token); + devNode->token = NULL; + case DEVNODE_INITED: // fall-through + PowerStateTokenFreeInstance(devNode->powerToken); + devNode->powerToken = NULL; + OsalMemFree(devNode->servName); + devNode->servName = NULL; + break; + case DEVNODE_NONE: + break; + default: + break; + } } -struct HdfDeviceNode *HdfDeviceNodeNewInstance() +struct HdfDeviceNode *HdfDeviceNodeNewInstance(const struct HdfDeviceInfo *deviceInfo, struct HdfDriver *driver) { - return (struct HdfDeviceNode *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVICE_SERVICE); + struct HdfDeviceNode *devNode = NULL; + if (deviceInfo == NULL) { + return NULL; + } + devNode = (struct HdfDeviceNode *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVICE_SERVICE); + if (devNode == NULL) { + return NULL; + } + + devNode->driver = driver; + devNode->devId = deviceInfo->deviceId; + devNode->permission = deviceInfo->permission; + devNode->policy = deviceInfo->policy; + devNode->token->devid = deviceInfo->deviceId; + devNode->servName = HdfStringCopy(deviceInfo->svcName); + if (devNode->servName == NULL) { + return NULL; + } + devNode->deviceObject.property = HcsGetNodeByMatchAttr(HdfGetRootNode(), deviceInfo->deviceMatchAttr); + devNode->deviceObject.priv = (void *)(deviceInfo->private); + if (devNode->deviceObject.property == NULL) { + HDF_LOGD("node %s property empty, match attr: %s", deviceInfo->moduleName, deviceInfo->deviceMatchAttr); + } + devNode->devStatus = DEVNODE_INITED; + return devNode; } void HdfDeviceNodeFreeInstance(struct HdfDeviceNode *devNode) { - HdfObjectManagerFreeObject((struct HdfObject *) devNode); + HdfObjectManagerFreeObject((struct HdfObject *)devNode); } - -void HdfDeviceNodeDelete(struct HdfDeviceNode *devNode) -{ - if (devNode == NULL) { - return; - } - - if (devNode->driverEntry->Release != NULL) { - devNode->driverEntry->Release(&devNode->deviceObject); - } - HdfDeviceNodeFreeInstance(devNode); -} - diff --git a/core/host/src/hdf_device_object.c b/core/host/src/hdf_device_object.c index 6ab71003..8e44d6d3 100644 --- a/core/host/src/hdf_device_object.c +++ b/core/host/src/hdf_device_object.c @@ -9,6 +9,7 @@ #include "hdf_device_object.h" #include "hdf_base.h" #include "hdf_device_node.h" +#include "devhost_service.h" #include "hdf_log.h" #include "hdf_observer_record.h" #include "hdf_service_observer.h" @@ -19,12 +20,10 @@ int32_t HdfDeviceSubscribeService( struct HdfDeviceObject *deviceObject, const char *serviceName, struct SubscriberCallback callback) { - uint32_t matchId; struct DevHostService *hostService = NULL; - const struct HdfDeviceInfo *deviceInfo = NULL; struct HdfDeviceNode *devNode = NULL; if (deviceObject == NULL || serviceName == NULL) { - HDF_LOGE("failed to subscribe service, deviceObject/serviceName is null"); + HDF_LOGE("failed to subscribe service, serviceName is null"); return HDF_FAILURE; } devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF( @@ -34,31 +33,20 @@ int32_t HdfDeviceSubscribeService( HDF_LOGE("failed to subscribe service, hostService is null"); return HDF_FAILURE; } - deviceInfo = devNode->deviceInfo; - if (deviceInfo == NULL) { - HDF_LOGE("failed to subscribe service, deviceInfo is null"); - return HDF_FAILURE; - } - matchId = HdfMakeHardwareId(deviceInfo->hostId, deviceInfo->deviceId); - return HdfServiceObserverSubscribeService(&hostService->observer, serviceName, matchId, callback); + + return HdfServiceObserverSubscribeService(&hostService->observer, serviceName, devNode->devId, callback); } const char *HdfDeviceGetServiceName(const struct HdfDeviceObject *deviceObject) { struct HdfDeviceNode *devNode = NULL; - const struct HdfDeviceInfo *deviceInfo = NULL; if (deviceObject == NULL) { HDF_LOGE("failed to get service name, deviceObject is invalid"); return NULL; } devNode = (struct HdfDeviceNode *)HDF_SLIST_CONTAINER_OF( struct HdfDeviceObject, deviceObject, struct HdfDeviceNode, deviceObject); - deviceInfo = devNode->deviceInfo; - if (deviceInfo == NULL) { - HDF_LOGE("failed to get service name, deviceInfo is null"); - return NULL; - } - return deviceInfo->svcName; + return devNode->servName; } int HdfPmRegisterPowerListener(struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener) @@ -134,7 +122,7 @@ void HdfPmSetMode(struct HdfDeviceObject *deviceObject, uint32_t mode) bool HdfDeviceSetClass(struct HdfDeviceObject *deviceObject, DeviceClass deviceClass) { if ((deviceObject == NULL) || (deviceClass >= DEVICE_CLASS_MAX) || - (deviceClass < DEVICE_CLASS_DEFAULT)) { + (deviceClass >= DEVICE_CLASS_MAX)) { return false; } deviceObject->deviceClass = deviceClass; diff --git a/core/host/src/hdf_driver_loader.c b/core/host/src/hdf_driver_loader.c index 98cfbee6..14e4d204 100755 --- a/core/host/src/hdf_driver_loader.c +++ b/core/host/src/hdf_driver_loader.c @@ -17,82 +17,52 @@ #define HDF_LOG_TAG driver_loader -struct HdfDeviceNode *HdfDriverLoaderLoadNode( - struct IDriverLoader *loader, const struct HdfDeviceInfo *deviceInfo) +int32_t HdfDriverEntryConstruct() { + int i; struct HdfDriverEntry *driverEntry = NULL; - struct HdfDeviceNode *devNode = NULL; - if ((loader == NULL) || (loader->GetDriverEntry == NULL)) { - HDF_LOGE("failed to load node, loader is invalid"); - return NULL; + size_t *addrBegin = NULL; + int32_t count = 0; + + count = (int32_t)(((uint8_t *)(HDF_DRIVER_END()) - (uint8_t *)(HDF_DRIVER_BEGIN())) / sizeof(size_t)); + if (count <= 0) { + HDF_LOGE("%s: no hdf driver exist", __func__); + return HDF_FAILURE; } - driverEntry = loader->GetDriverEntry(deviceInfo); - if (driverEntry == NULL) { - HDF_LOGE("failed to load node, deviceEntry is null"); - return NULL; - } - - devNode = HdfDeviceNodeNewInstance(); - if (devNode == NULL) { - HDF_LOGE("failed to load node, device node is null"); - return NULL; - } - - devNode->driverEntry = driverEntry; - devNode->deviceInfo = deviceInfo; - devNode->deviceObject.property = HcsGetNodeByMatchAttr(HdfGetRootNode(), deviceInfo->deviceMatchAttr); - devNode->deviceObject.priv = (void *)(deviceInfo->private); - if (devNode->deviceObject.property == NULL) { - HDF_LOGW("failed to load node, property is null, match attr is: %s", deviceInfo->deviceMatchAttr); - } - - if ((deviceInfo->policy == SERVICE_POLICY_PUBLIC) || (deviceInfo->policy == SERVICE_POLICY_CAPACITY)) { - if (driverEntry->Bind == NULL) { - HDF_LOGE("driver bind method is null"); - HdfDeviceNodeFreeInstance(devNode); - return NULL; - } - if (driverEntry->Bind(&devNode->deviceObject) != 0) { - HDF_LOGE("bind driver failed"); - HdfDeviceNodeFreeInstance(devNode); - return NULL; + addrBegin = (size_t *)(HDF_DRIVER_BEGIN()); + for (i = 0; i < count; i++) { + driverEntry = (struct HdfDriverEntry *)(*addrBegin); + if (HdfRegisterDriverEntry(driverEntry) != HDF_SUCCESS) { + HDF_LOGE("failed to register driver %s, skip and try another", driverEntry ? driverEntry->moduleName : ""); + continue; } + addrBegin++; } - return devNode; + return HDF_SUCCESS; } -void HdfDriverLoaderUnLoadNode(struct IDriverLoader *loader, const struct HdfDeviceInfo *deviceInfo) +struct HdfDriver *HdfDriverLoaderGetDriver(const char *moduleName) { - struct HdfDriverEntry *driverEntry = NULL; - struct HdfDeviceObject *deviceObject = NULL; - if ((loader == NULL) || (loader->GetDriverEntry == NULL)) { - HDF_LOGE("failed to unload service, loader invalid"); - return; + if (moduleName == NULL) { + HDF_LOGE("%s: failed to get device entry, moduleName is NULL", __func__); + return NULL; } - driverEntry = loader->GetDriverEntry(deviceInfo); - if (driverEntry == NULL) { - HDF_LOGE("failed to unload service, driverEntry is null"); - return; - } - if (driverEntry->Release == NULL) { - HDF_LOGI("device release func is null"); - return; - } - deviceObject = DevSvcManagerClntGetDeviceObject(deviceInfo->svcName); - if (deviceObject != NULL) { - driverEntry->Release(deviceObject); - } + return HdfDriverManagerGetDriver(moduleName); +} + +void HdfDriverLoaderReclaimDriver(struct HdfDriver *driver) +{ + // kernel driver do not need release + (void)driver; } void HdfDriverLoaderConstruct(struct HdfDriverLoader *inst) { if (inst != NULL) { - struct IDriverLoader *driverLoaderIf = (struct IDriverLoader *)inst; - driverLoaderIf->LoadNode = HdfDriverLoaderLoadNode; - driverLoaderIf->UnLoadNode = HdfDriverLoaderUnLoadNode; - driverLoaderIf->GetDriverEntry = HdfDriverLoaderGetDriverEntry; + inst->super.GetDriver = HdfDriverLoaderGetDriver; + inst->super.ReclaimDriver = HdfDriverLoaderReclaimDriver; } } @@ -101,6 +71,9 @@ struct HdfObject *HdfDriverLoaderCreate() static bool isDriverLoaderInit = false; static struct HdfDriverLoader driverLoader; if (!isDriverLoaderInit) { + if (HdfDriverEntryConstruct() != HDF_SUCCESS) { + return NULL; + } HdfDriverLoaderConstruct(&driverLoader); isDriverLoaderInit = true; } diff --git a/core/host/src/hdf_observer_record.c b/core/host/src/hdf_observer_record.c index 574afecd..e30e7b53 100644 --- a/core/host/src/hdf_observer_record.c +++ b/core/host/src/hdf_observer_record.c @@ -14,11 +14,6 @@ #define HDF_LOG_TAG observer_record #define HALF_INT_LEN 16 -uint32_t HdfMakeHardwareId(uint16_t hostId, uint16_t deviceId) -{ - return ((uint32_t)hostId << HALF_INT_LEN) | deviceId; -} - struct HdfServiceObserverRecord *HdfServiceObserverRecordObtain(uint32_t serviceKey) { struct HdfServiceObserverRecord *observerRecord = @@ -59,7 +54,7 @@ bool HdfServiceObserverRecordCompare(struct HdfSListNode *listEntry, uint32_t se } void HdfServiceObserverRecordNotifySubscribers( - struct HdfServiceObserverRecord *record, uint32_t matchId, uint16_t policy) + struct HdfServiceObserverRecord *record, uint32_t devId, uint16_t policy) { struct HdfSListIterator it; if (record == NULL) { @@ -72,7 +67,7 @@ void HdfServiceObserverRecordNotifySubscribers( while (HdfSListIteratorHasNext(&it)) { struct HdfServiceSubscriber *subscriber = (struct HdfServiceSubscriber *)HdfSListIteratorNext(&it); - if ((matchId == subscriber->matchId) || (policy != SERVICE_POLICY_PRIVATE)) { + if (devId == subscriber->devId || policy != SERVICE_POLICY_PRIVATE) { subscriber->state = HDF_SUBSCRIBER_STATE_READY; if (subscriber->callback.OnServiceConnected != NULL) { subscriber->callback.OnServiceConnected(subscriber->callback.deviceObject, record->publisher); diff --git a/core/host/src/hdf_service_observer.c b/core/host/src/hdf_service_observer.c index 29aa1555..ed79a964 100644 --- a/core/host/src/hdf_service_observer.c +++ b/core/host/src/hdf_service_observer.c @@ -36,7 +36,7 @@ void HdfServiceObserverDestruct(struct HdfServiceObserver *observer) } int HdfServiceObserverSubscribeService(struct HdfServiceObserver *observer, - const char *svcName, uint32_t matchId, struct SubscriberCallback callback) + const char *svcName, devid_t devid, struct SubscriberCallback callback) { struct HdfServiceObserverRecord *serviceRecord = NULL; struct HdfServiceSubscriber *subscriber = NULL; @@ -53,7 +53,7 @@ int HdfServiceObserverSubscribeService(struct HdfServiceObserver *observer, HDF_LOGE("failed to subscribe service, serviceRecord is null"); return HDF_FAILURE; } - subscriber = HdfServiceSubscriberObtain(callback, matchId); + subscriber = HdfServiceSubscriberObtain(callback, devid); if (subscriber == NULL) { HDF_LOGE("failed to subscribe service, subscriber is null"); HdfServiceObserverRecordRecycle(serviceRecord); @@ -63,7 +63,7 @@ int HdfServiceObserverSubscribeService(struct HdfServiceObserver *observer, HdfSListAdd(&observer->services, &serviceRecord->entry); OsalMutexUnlock(&observer->observerMutex); } else { - subscriber = HdfServiceSubscriberObtain(callback, matchId); + subscriber = HdfServiceSubscriberObtain(callback, devid); if (subscriber == NULL) { HDF_LOGE("failed to subscribe service, subscriber obtain null"); return HDF_FAILURE; @@ -72,7 +72,7 @@ int HdfServiceObserverSubscribeService(struct HdfServiceObserver *observer, if ((serviceRecord->publisher != NULL) && (subscriber->callback.OnServiceConnected != NULL) && ((serviceRecord->policy != SERVICE_POLICY_PRIVATE) || - (serviceRecord->matchId == matchId))) { + (serviceRecord->devId == devid))) { subscriber->state = HDF_SUBSCRIBER_STATE_READY; subscriber->callback.OnServiceConnected(subscriber->callback.deviceObject, serviceRecord->publisher); } @@ -83,7 +83,7 @@ int HdfServiceObserverSubscribeService(struct HdfServiceObserver *observer, } int HdfServiceObserverPublishService(struct HdfServiceObserver *observer, - const char *svcName, uint32_t matchId, uint16_t policy, struct HdfObject *service) + const char *svcName, uint32_t devId, uint16_t policy, struct HdfObject *service) { struct HdfServiceObserverRecord *serviceRecord = NULL; uint32_t serviceKey = HdfStringMakeHashKey(svcName, 0); @@ -100,14 +100,14 @@ int HdfServiceObserverPublishService(struct HdfServiceObserver *observer, return HDF_FAILURE; } serviceRecord->publisher = service; - serviceRecord->matchId = matchId; + serviceRecord->devId = devId; serviceRecord->policy = policy; OsalMutexLock(&observer->observerMutex); HdfSListAdd(&observer->services, &serviceRecord->entry); OsalMutexUnlock(&observer->observerMutex); } else { serviceRecord->publisher = service; - HdfServiceObserverRecordNotifySubscribers(serviceRecord, matchId, policy); + HdfServiceObserverRecordNotifySubscribers(serviceRecord, devId, policy); } return HDF_SUCCESS; } diff --git a/core/host/src/hdf_service_subscriber.c b/core/host/src/hdf_service_subscriber.c index efcec2f4..6aa3ffd2 100644 --- a/core/host/src/hdf_service_subscriber.c +++ b/core/host/src/hdf_service_subscriber.c @@ -7,15 +7,16 @@ */ #include "hdf_service_subscriber.h" +#include "hdf_device.h" #include "osal_mem.h" -struct HdfServiceSubscriber *HdfServiceSubscriberObtain(struct SubscriberCallback callback, uint32_t matchId) +struct HdfServiceSubscriber *HdfServiceSubscriberObtain(struct SubscriberCallback callback, devid_t devid) { struct HdfServiceSubscriber *serviceSubscriber = (struct HdfServiceSubscriber *)OsalMemCalloc(sizeof(struct HdfServiceSubscriber)); if (serviceSubscriber != NULL) { serviceSubscriber->state = HDF_SUBSCRIBER_STATE_PENDING; - serviceSubscriber->matchId = matchId; + serviceSubscriber->devId = devid; serviceSubscriber->callback = callback; } return serviceSubscriber; diff --git a/core/manager/src/devmgr_service.c b/core/manager/src/devmgr_service.c index e11da3ed..741cbf3a 100644 --- a/core/manager/src/devmgr_service.c +++ b/core/manager/src/devmgr_service.c @@ -33,7 +33,7 @@ static int DevmgrServiceActiveDevice(struct DevHostServiceClnt *hostClnt, } return ret; } else if (!isLoad && (deviceInfo->preload != DEVICE_PRELOAD_DISABLE)) { - devHostSvcIf->DelDevice(devHostSvcIf, deviceInfo); + devHostSvcIf->DelDevice(devHostSvcIf, deviceInfo->deviceId); deviceInfo->preload = DEVICE_PRELOAD_DISABLE; return HDF_SUCCESS; } else { @@ -117,7 +117,7 @@ static struct DevHostServiceClnt *DevmgrServiceFindDeviceHost(struct IDevmgrServ return NULL; } -static void DevmgrServiceUpdateStatus(struct DevHostServiceClnt *hostClnt, uint16_t deviceId, uint16_t status) +static void DevmgrServiceUpdateStatus(struct DevHostServiceClnt *hostClnt, devid_t devId, uint16_t status) { struct HdfSListIterator it; struct HdfDeviceInfo *deviceInfo = NULL; @@ -125,27 +125,23 @@ static void DevmgrServiceUpdateStatus(struct DevHostServiceClnt *hostClnt, uint1 HdfSListIteratorInit(&it, hostClnt->deviceInfos); while (HdfSListIteratorHasNext(&it)) { deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&it); - if (deviceInfo->deviceId == deviceId) { + if (deviceInfo->deviceId == devId) { deviceInfo->status = status; HDF_LOGD("%s host:%s %u device:%s %u status:%u", __func__, hostClnt->hostName, - hostClnt->hostId, deviceInfo->svcName, deviceId, deviceInfo->status); + hostClnt->hostId, deviceInfo->svcName, devId, deviceInfo->status); return; } } - HDF_LOGE("%s: not find device %u in host %u", __func__, deviceId, hostClnt->hostId); + HDF_LOGE("%s: not find device %u in host %u", __func__, devId, hostClnt->hostId); return; } -static int DevmgrServiceAttachDevice( - struct IDevmgrService *inst, const struct HdfDeviceInfo *deviceInfo, struct IHdfDeviceToken *token) +static int DevmgrServiceAttachDevice(struct IDevmgrService *inst, struct IHdfDeviceToken *token) { struct DevHostServiceClnt *hostClnt = NULL; struct DeviceTokenClnt *tokenClnt = NULL; - if (deviceInfo == NULL) { - HDF_LOGE("failed to attach device, deviceInfo is null"); - return HDF_FAILURE; - } - hostClnt = DevmgrServiceFindDeviceHost(inst, deviceInfo->hostId); + + hostClnt = DevmgrServiceFindDeviceHost(inst, HOSTID(token->devid)); if (hostClnt == NULL) { HDF_LOGE("failed to attach device, hostClnt is null"); return HDF_FAILURE; @@ -156,12 +152,39 @@ static int DevmgrServiceAttachDevice( return HDF_FAILURE; } - tokenClnt->deviceInfo = deviceInfo; - DevmgrServiceUpdateStatus(hostClnt, deviceInfo->deviceId, HDF_SERVICE_USABLE); + DevmgrServiceUpdateStatus(hostClnt, token->devid, HDF_SERVICE_USABLE); HdfSListAdd(&hostClnt->devices, &tokenClnt->node); return HDF_SUCCESS; } +static bool HdfSListHostSearchDeviceTokenComparer(struct HdfSListNode *tokenNode, uint32_t devid) +{ + struct DeviceTokenClnt *tokenClnt = CONTAINER_OF(tokenNode, struct DeviceTokenClnt, node); + return tokenClnt->tokenIf->devid == devid; +} + +static int DevmgrServiceDetachDevice(struct IDevmgrService *inst, devid_t devid) +{ + struct DevHostServiceClnt *hostClnt = NULL; + struct DeviceTokenClnt *tokenClnt = NULL; + struct HdfSListNode *tokenClntNode = NULL; + + hostClnt = DevmgrServiceFindDeviceHost(inst, HOSTID(devid)); + if (hostClnt == NULL) { + HDF_LOGE("failed to attach device, hostClnt is null"); + return HDF_FAILURE; + } + tokenClntNode = HdfSListSearch(&hostClnt->devices, devid, HdfSListHostSearchDeviceTokenComparer); + if (tokenClntNode == NULL) { + HDF_LOGE("devmgr detach device %x not found", devid); + return HDF_DEV_ERR_NO_DEVICE; + } + tokenClnt = CONTAINER_OF(tokenClntNode, struct DeviceTokenClnt, node); + DevmgrServiceUpdateStatus(hostClnt, devid, HDF_SERVICE_UNUSABLE); + HdfSListRemove(&hostClnt->devices, &tokenClnt->node); + return HDF_SUCCESS; +} + static int DevmgrServiceAttachDeviceHost( struct IDevmgrService *inst, uint16_t hostId, struct IDevHostService *hostService) { @@ -281,6 +304,7 @@ bool DevmgrServiceConstruct(struct DevmgrService *inst) devMgrSvcIf = (struct IDevmgrService *)inst; if (devMgrSvcIf != NULL) { devMgrSvcIf->AttachDevice = DevmgrServiceAttachDevice; + devMgrSvcIf->DetachDevice = DevmgrServiceDetachDevice; devMgrSvcIf->AttachDeviceHost = DevmgrServiceAttachDeviceHost; devMgrSvcIf->StartService = DevmgrServiceStartService; devMgrSvcIf->PowerStateChange = DevmgrServicePowerStateChange; @@ -323,7 +347,7 @@ void DevmgrServiceRelease(struct HdfObject *object) } DLIST_FOR_EACH_ENTRY_SAFE(hostClnt, hostClntTmp, &devmgrService->hosts, struct DevHostServiceClnt, node) { DListRemove(&hostClnt->node); - DevHostServiceClntDelete(hostClnt); + DevHostServiceClntDelete(hostClnt); } OsalMutexDestroy(&devmgrService->devMgrMutex); diff --git a/core/manager/src/driver_manager.c b/core/manager/src/driver_manager.c new file mode 100644 index 00000000..54809559 --- /dev/null +++ b/core/manager/src/driver_manager.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include "hdf_dlist.h" +#include "hdf_driver.h" +#include "hdf_log.h" +#include "osal_mem.h" + +static struct DListHead *HdfDriverHead() +{ + static struct DListHead driverHead = { 0 }; + if (driverHead.next == NULL) { + DListHeadInit(&driverHead); + } + + return &driverHead; +} + +int32_t HdfRegisterDriverEntry(const struct HdfDriverEntry *entry) +{ + struct HdfDriver *newDriver = NULL; + + if (entry == NULL || entry->moduleName == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + + newDriver = OsalMemCalloc(sizeof(struct HdfDriver)); + if (newDriver == NULL) { + return HDF_DEV_ERR_NO_MEMORY; + } + + newDriver->entry = entry; + + DListInsertTail(&newDriver->node, HdfDriverHead()); + + return HDF_SUCCESS; +} + +int32_t HdfUnregisterDriverEntry(const struct HdfDriverEntry *entry) +{ + struct DListHead *driverHead = NULL; + struct HdfDriver *driver = NULL; + struct HdfDriver *tmp = NULL; + + if (entry == NULL || entry->moduleName == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + + driverHead = HdfDriverHead(); + DLIST_FOR_EACH_ENTRY_SAFE(driver, tmp, driverHead, struct HdfDriver, node) + { + if (driver->entry == entry) { + DListRemove(&driver->node); + OsalMemFree(driver); + break; + } + } + + return HDF_SUCCESS; +} + +int32_t HdfRegisterDriver(struct HdfDriver *driver) +{ + if (driver == NULL || driver->entry == NULL || driver->entry->moduleName == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + + DListInsertTail(&driver->node, HdfDriverHead()); + return HDF_SUCCESS; +} + +int32_t HdfUnregisterDriver(struct HdfDriver *driver) +{ + struct DListHead *driverHead = NULL; + struct HdfDriver *it = NULL; + struct HdfDriver *tmp = NULL; + + if (driver == NULL) { + return HDF_ERR_INVALID_PARAM; + } + + driverHead = HdfDriverHead(); + DLIST_FOR_EACH_ENTRY_SAFE(it, tmp, driverHead, struct HdfDriver, node) + { + if (it == driver) { + DListRemove(&it->node); + break; + } + } + + return HDF_SUCCESS; +} + +struct HdfDriver *HdfDriverManagerGetDriver(const char *driverName) +{ + struct DListHead *driverHead = NULL; + struct HdfDriver *driver = NULL; + + if (driverName == NULL) { + return NULL; + } + + driverHead = HdfDriverHead(); + DLIST_FOR_EACH_ENTRY(driver, driverHead, struct HdfDriver, node) { + if (driver->entry != NULL && driver->entry->moduleName != NULL && + !strcmp(driver->entry->moduleName, driverName)) { + return driver; + } + } + HDF_LOGE("%s:driver %s not found", __func__, driverName); + return NULL; +} + +struct DListHead *HdfDriverManagerGetDriverList() +{ + return HdfDriverHead(); +} diff --git a/core/shared/include/devhost_service_if.h b/core/shared/include/devhost_service_if.h index a1c22691..2a4513e9 100644 --- a/core/shared/include/devhost_service_if.h +++ b/core/shared/include/devhost_service_if.h @@ -9,13 +9,14 @@ #ifndef DEVHOST_SERVICE_IF_H #define DEVHOST_SERVICE_IF_H +#include "hdf_device.h" #include "hdf_device_info.h" #include "hdf_object.h" struct IDevHostService { struct HdfObject object; int (*AddDevice)(struct IDevHostService *hostService, const struct HdfDeviceInfo *devInfo); - int (*DelDevice)(struct IDevHostService *hostService, const struct HdfDeviceInfo *devInfo); + int (*DelDevice)(struct IDevHostService *hostService, devid_t devId); int (*StartService)(struct IDevHostService *hostService); int (*PmNotify)(struct IDevHostService *service, uint32_t powerState); }; diff --git a/core/shared/include/device_token_if.h b/core/shared/include/device_token_if.h index c086152c..586f66e9 100644 --- a/core/shared/include/device_token_if.h +++ b/core/shared/include/device_token_if.h @@ -10,9 +10,11 @@ #define DEVICE_TOKEN_IF_H #include "hdf_object.h" +#include "hdf_device.h" struct IHdfDeviceToken { struct HdfObject object; + devid_t devid; }; #endif /* DEVICE_TOKEN_IF_H */ diff --git a/core/shared/include/devmgr_service_if.h b/core/shared/include/devmgr_service_if.h index 55df8e42..08ad1395 100644 --- a/core/shared/include/devmgr_service_if.h +++ b/core/shared/include/devmgr_service_if.h @@ -19,7 +19,8 @@ struct IDevmgrService { struct HdfObject base; struct HdfDeviceObject object; int (*AttachDeviceHost)(struct IDevmgrService *, uint16_t, struct IDevHostService *); - int (*AttachDevice)(struct IDevmgrService *, const struct HdfDeviceInfo *, struct IHdfDeviceToken *); + int (*AttachDevice)(struct IDevmgrService *, struct IHdfDeviceToken *); + int (*DetachDevice)(struct IDevmgrService *, devid_t); int (*StartService)(struct IDevmgrService *); int (*PowerStateChange)(struct IDevmgrService *, enum HdfPowerState pEvent); }; diff --git a/core/shared/include/hdf_driver.h b/core/shared/include/hdf_driver.h new file mode 100644 index 00000000..1190e995 --- /dev/null +++ b/core/shared/include/hdf_driver.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#ifndef HDF_DRIVER_H +#define HDF_DRIVER_H + +#include "hdf_device_desc.h" +#include "hdf_dlist.h" + +struct HdfDriver { + const struct HdfDriverEntry *entry; + uint16_t type; + uint16_t bus; + struct DListHead node; + void *priv; +}; + +int32_t HdfRegisterDriverEntry(const struct HdfDriverEntry *entry); +int32_t HdfUnregisterDriverEntry(const struct HdfDriverEntry *entry); +int32_t HdfRegisterDriver(struct HdfDriver *driver); +int32_t HdfUnregisterDriver(struct HdfDriver *driver); +struct HdfDriver *HdfDriverManagerGetDriver(const char *driverName); +struct DListHead *HdfDriverManagerGetDriverList(void); + +#endif // HDF_DRIVER_H \ No newline at end of file diff --git a/test/unittest/manager/sample_driver_test.c b/test/unittest/manager/sample_driver_test.c index 60978766..9ea1434b 100644 --- a/test/unittest/manager/sample_driver_test.c +++ b/test/unittest/manager/sample_driver_test.c @@ -26,20 +26,23 @@ void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) int32_t SampleDriverRegisterDevice(struct HdfSBuf *data) { + const char *moduleName = NULL; + const char *serviceName = NULL; + struct HdfDeviceObject *devObj = NULL; if (data == NULL) { return HDF_FAILURE; } - const char *moduleName = HdfSbufReadString(data); + moduleName = HdfSbufReadString(data); if (moduleName == NULL) { return HDF_FAILURE; } - const char *serviceName = HdfSbufReadString(data); + serviceName = HdfSbufReadString(data); if (serviceName == NULL) { return HDF_FAILURE; } - struct HdfDeviceObject *devObj = HdfRegisterDevice(moduleName, serviceName, NULL); + devObj = HdfRegisterDevice(moduleName, serviceName, NULL); if (devObj == NULL) { return HDF_FAILURE; } @@ -48,15 +51,17 @@ int32_t SampleDriverRegisterDevice(struct HdfSBuf *data) int32_t SampleDriverUnregisterDevice(struct HdfSBuf *data) { + const char *moduleName = NULL; + const char *serviceName = NULL; if (data == NULL) { return HDF_FAILURE; } - const char *moduleName = HdfSbufReadString(data); + moduleName = HdfSbufReadString(data); if (moduleName == NULL) { return HDF_FAILURE; } - const char *serviceName = HdfSbufReadString(data); + serviceName = HdfSbufReadString(data); if (serviceName == NULL) { return HDF_FAILURE; } @@ -71,11 +76,12 @@ int32_t SampleDriverSendEvent(struct HdfDeviceIoClient *client, int id, struct H int32_t SampleDriverPowerStateInject(uint32_t powerState) { + int ret; struct IDevmgrService *devmgrService = DevmgrServiceGetInstance(); if (devmgrService == NULL || devmgrService->PowerStateChange == NULL) { return HDF_ERR_INVALID_OBJECT; } - int ret = devmgrService->PowerStateChange(devmgrService, powerState); + ret = devmgrService->PowerStateChange(devmgrService, powerState); HDF_LOGI("%s: inject power state(%d) done, ret = %d", __func__, powerState, ret); return ret; @@ -83,11 +89,11 @@ int32_t SampleDriverPowerStateInject(uint32_t powerState) int32_t SampleDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) { + uint32_t powerState = 0; int32_t ret = HDF_SUCCESS; if (reply == NULL || client == NULL) { return HDF_FAILURE; } - uint32_t powerState = 0; switch (cmdId) { case SAMPLE_DRIVER_REGISTER_DEVICE: { ret = SampleDriverRegisterDevice(data); @@ -118,15 +124,16 @@ int32_t SampleDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) { - HDF_LOGD("%s::enter", __func__); - if (deviceObject == NULL) { - return HDF_FAILURE; - } static struct IDeviceIoService testService = { .Dispatch = SampleDriverDispatch, .Open = NULL, .Release = NULL, }; + HDF_LOGD("%s::enter", __func__); + if (deviceObject == NULL) { + return HDF_FAILURE; + } + deviceObject->service = &testService; return HDF_SUCCESS; } @@ -162,6 +169,8 @@ struct SampleDriverPmListener { int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) { + static struct SampleDriverPmListener pmListener = {0}; + int ret; HDF_LOGI("%s::enter!", __func__); if (deviceObject == NULL) { HDF_LOGE("%s::ptr is null!", __func__); @@ -169,13 +178,12 @@ int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) } HDF_LOGD("%s:Init success", __func__); - static struct SampleDriverPmListener pmListener = {0}; pmListener.powerListener.DozeResume = HdfSampleDozeResume; pmListener.powerListener.DozeSuspend = HdfSampleDozeSuspend; pmListener.powerListener.Resume = HdfSampleResume; pmListener.powerListener.Suspend = HdfSampleSuspend; - int ret = HdfPmRegisterPowerListener(deviceObject, &pmListener.powerListener); + ret = HdfPmRegisterPowerListener(deviceObject, &pmListener.powerListener); HDF_LOGI("%s:register power listener, ret = %d", __func__, ret); return HDF_SUCCESS; diff --git a/utils/include/hdf_cstring.h b/utils/include/hdf_cstring.h index 8e261c5f..a2374f30 100644 --- a/utils/include/hdf_cstring.h +++ b/utils/include/hdf_cstring.h @@ -23,6 +23,7 @@ struct HdfCString { uint32_t HdfStringMakeHashKey(const char *key, uint32_t mask); struct HdfCString *HdfCStringObtain(const char *str); void HdfCStringRecycle(struct HdfCString *inst); +char *HdfStringCopy(const char *src); #ifdef __cplusplus } diff --git a/utils/src/hdf_cstring.c b/utils/src/hdf_cstring.c index cdba3fdf..a5d503fd 100644 --- a/utils/src/hdf_cstring.c +++ b/utils/src/hdf_cstring.c @@ -54,3 +54,27 @@ void HdfCStringRecycle(struct HdfCString *inst) OsalMemFree(inst); } } + +char *HdfStringCopy(const char *src) +{ + char *newStr = NULL; + size_t srcSize; + size_t dstSize; + + if (src == NULL) { + return NULL; + } + srcSize = strlen(src); + dstSize = srcSize + 1; + newStr = OsalMemAlloc(dstSize); + if (newStr == NULL) { + return NULL; + } + + if (strncpy_s(newStr, dstSize, src, srcSize) != EOK) { + OsalMemFree(newStr); + newStr = NULL; + } + + return newStr; +}