mirror of
https://github.com/openharmony/drivers_adapter.git
synced 2026-07-01 03:23:20 -04:00
feat: support dynamic load khdf driver module
Signed-off-by: yuanbo <yuanbo@huawei.com>
This commit is contained in:
+14
-2
@@ -4,12 +4,24 @@ PointerAlignment: Right
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
AlignTrailingComments: true
|
||||
AlignConsecutiveMacros: Consecutive
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
IndentCaseLabels: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParens: ControlStatementsExceptControlMacros
|
||||
SpacesInCStyleCastParentheses: false
|
||||
AlignEscapedNewlines: Left
|
||||
NamespaceIndentation: None
|
||||
FixNamespaceComments: true
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
BreakConstructorInitializers: AfterColon
|
||||
AlignArrayOfStructures: Left
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortLambdasOnASingleLine: Empty
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
SpaceInEmptyBlock: false
|
||||
LambdaBodyIndentation: Signature
|
||||
BreakBeforeTernaryOperators: false
|
||||
Cpp11BracedListStyle: true
|
||||
SpaceAroundPointerQualifiers: Both
|
||||
|
||||
ForEachMacros:
|
||||
- 'DLIST_FOR_EACH_ENTRY'
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
*/
|
||||
|
||||
#include "devhost_service_full.h"
|
||||
#include "devmgr_service_clnt.h"
|
||||
#include "dev_attribute_serialize.h"
|
||||
#include "hdf_device_node.h"
|
||||
#include "power_state_token.h"
|
||||
#include "devmgr_service_clnt.h"
|
||||
#include "hdf_base.h"
|
||||
#include "hdf_device_info.h"
|
||||
#include "hdf_device_node.h"
|
||||
#include "hdf_log.h"
|
||||
#include "osal_message.h"
|
||||
#include "power_state_token.h"
|
||||
|
||||
#define HDF_LOG_TAG devhost_service_full
|
||||
|
||||
@@ -57,8 +57,7 @@ static int32_t DevHostServiceFullDispatchMessage(struct HdfMessageTask *task, st
|
||||
return status;
|
||||
}
|
||||
|
||||
static int DevHostServiceFullOpsDevice(
|
||||
struct IDevHostService *devHostService, uintptr_t parm, int cmdCode)
|
||||
static int DevHostServiceFullOpsDevice(struct IDevHostService *devHostService, uintptr_t parm, int cmdCode)
|
||||
{
|
||||
if (devHostService == NULL) {
|
||||
HDF_LOGE("input is null");
|
||||
@@ -77,8 +76,7 @@ static int DevHostServiceFullOpsDevice(
|
||||
return task->SendMessage(task, message, true);
|
||||
}
|
||||
|
||||
static int DevHostServiceFullAddDevice(
|
||||
struct IDevHostService *devHostService, const struct HdfDeviceInfo *attribute)
|
||||
static int DevHostServiceFullAddDevice(struct IDevHostService *devHostService, const struct HdfDeviceInfo *attribute)
|
||||
{
|
||||
return DevHostServiceFullOpsDevice(devHostService, (uintptr_t)attribute, DEVHOST_MESSAGE_ADD_DEVICE);
|
||||
}
|
||||
@@ -137,8 +135,8 @@ static uint32_t SysEventToPowerState(uint32_t sysEvent)
|
||||
}
|
||||
}
|
||||
|
||||
static int OnSysEventReceived(struct HdfSysEventNotifyNode *self, uint64_t eventClass,
|
||||
uint32_t event, const char* content)
|
||||
static int OnSysEventReceived(
|
||||
struct HdfSysEventNotifyNode *self, uint64_t eventClass, uint32_t event, const char *content)
|
||||
{
|
||||
(void)(content);
|
||||
if (self == NULL) {
|
||||
@@ -152,7 +150,7 @@ static int OnSysEventReceived(struct HdfSysEventNotifyNode *self, uint64_t event
|
||||
|
||||
static int DevHostServiceFullStartService(struct IDevHostService *service)
|
||||
{
|
||||
struct DevHostService *hostService = (struct DevHostService*)service;
|
||||
struct DevHostService *hostService = (struct DevHostService *)service;
|
||||
if (hostService == NULL) {
|
||||
HDF_LOGE("Start device service failed, hostService is null");
|
||||
return HDF_FAILURE;
|
||||
@@ -176,7 +174,7 @@ static int DevHostServiceFullStartService(struct IDevHostService *service)
|
||||
|
||||
int DevHostServiceFullPmNotify(struct IDevHostService *service, uint32_t state)
|
||||
{
|
||||
struct DevHostService *hostService = (struct DevHostService*)service;
|
||||
struct DevHostService *hostService = (struct DevHostService *)service;
|
||||
int result = HDF_SUCCESS;
|
||||
|
||||
if (hostService == NULL || !IsValidPowerState(state)) {
|
||||
|
||||
@@ -13,7 +13,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "devmgr_service_stub.h"
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <securec.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "devhost_service_proxy.h"
|
||||
#include "device_token_proxy.h"
|
||||
#include "devmgr_query_device.h"
|
||||
@@ -21,11 +27,13 @@
|
||||
#include "hdf_log.h"
|
||||
#include "hdf_sbuf.h"
|
||||
#include "osal_mem.h"
|
||||
#include "osal_sysevent.h"
|
||||
|
||||
#include "devmgr_service_stub.h"
|
||||
|
||||
#define HDF_LOG_TAG devmgr_service_stub
|
||||
|
||||
static int32_t DevmgrServiceStubDispatchAttachDevice(
|
||||
struct IDevmgrService *devmgrSvc, struct HdfSBuf *data)
|
||||
static int32_t DevmgrServiceStubDispatchAttachDevice(struct IDevmgrService *devmgrSvc, struct HdfSBuf *data)
|
||||
{
|
||||
uint32_t deviceId;
|
||||
if (!HdfSbufReadUint32(data, &deviceId)) {
|
||||
@@ -74,8 +82,7 @@ static int32_t DevmgrServiceStubDispatchUnloadDevice(struct IDevmgrService *devm
|
||||
return devmgrSvc->UnloadDevice(devmgrSvc, serviceName);
|
||||
}
|
||||
|
||||
int32_t DevmgrServiceStubDispatch(
|
||||
struct HdfRemoteService* stub, int code, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
int32_t DevmgrServiceStubDispatch(struct HdfRemoteService *stub, int code, struct HdfSBuf *data, struct HdfSBuf *reply)
|
||||
{
|
||||
int32_t ret = HDF_FAILURE;
|
||||
struct DevmgrServiceStub *serviceStub = (struct DevmgrServiceStub *)stub;
|
||||
@@ -120,16 +127,102 @@ int32_t DevmgrServiceStubDispatch(
|
||||
break;
|
||||
}
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGE("%{public}s devmgr service stub dispach failed, cmd id is %{public}d, ret = %{public}d",
|
||||
__func__, code, ret);
|
||||
HDF_LOGE("%{public}s devmgr service stub dispach failed, cmd id is %{public}d, ret = %{public}d", __func__,
|
||||
code, ret);
|
||||
HdfSbufWriteInt32(reply, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void RemoveModule(const char *module)
|
||||
{
|
||||
uint32_t flags = O_NONBLOCK | O_EXCL;
|
||||
if (syscall(__NR_delete_module, module, flags) != 0) {
|
||||
HDF_LOGE("failed to remove module %{public}s", module);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t InstallModule(const char *module)
|
||||
{
|
||||
HDF_LOGI("try to install module %{public}s", module);
|
||||
|
||||
int fd = open(module, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
HDF_LOGE("module %{public}s is invalid", module);
|
||||
return HDF_ERR_BAD_FD;
|
||||
}
|
||||
int32_t ret = syscall(SYS_finit_module, fd, "", 0);
|
||||
if (ret != 0) {
|
||||
HDF_LOGE("failed to install module %{public}s", module);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t MakeModulePath(char *buffer, const char *moduleName)
|
||||
{
|
||||
char temp[PATH_MAX] = {0};
|
||||
if (sprintf_s(temp, PATH_MAX, "%s/%s.ko", HDF_MODULE_DIR, moduleName) <= 0) {
|
||||
HDF_LOGI("driver module path sprintf failed: %{public}s", moduleName);
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
HDF_LOGI("driver module file: %{public}s", temp);
|
||||
|
||||
char *path = realpath(temp, buffer);
|
||||
if (path == NULL || strncmp(path, HDF_MODULE_DIR, strlen(HDF_MODULE_DIR)) != 0) {
|
||||
HDF_LOGI("driver module file is invalud: %{public}s", temp);
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return HDF_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t ModuleSysEventHandle(
|
||||
struct HdfSysEventNotifyNode *self, uint64_t eventClass, uint32_t event, const char *content)
|
||||
{
|
||||
if (self == NULL || (eventClass & HDF_SYSEVENT_CLASS_MODULE) == 0 || content == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
HDF_LOGI("handle driver module: %{public}s", content);
|
||||
char modulePath[PATH_MAX] = {0};
|
||||
int32_t ret = MakeModulePath(modulePath, content);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
switch (event) {
|
||||
case KEVENT_MODULE_INSTALL:
|
||||
ret = InstallModule(modulePath);
|
||||
break;
|
||||
case KEVENT_MODULE_REMOVE:
|
||||
RemoveModule(modulePath);
|
||||
break;
|
||||
default:
|
||||
ret = HDF_ERR_NOT_SUPPORT;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t DriverModuleLoadHelperInit(void)
|
||||
{
|
||||
static struct HdfSysEventNotifyNode sysEventNotify = {
|
||||
.callback = ModuleSysEventHandle,
|
||||
};
|
||||
|
||||
int32_t ret = HdfSysEventNotifyRegister(&sysEventNotify, HDF_SYSEVENT_CLASS_MODULE);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
HDF_LOGW("ModuleLoadHelper:failed to register module event listener");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct HdfRemoteDispatcher g_devmgrDispatcher = {
|
||||
.Dispatch = DevmgrServiceStubDispatch
|
||||
.Dispatch = DevmgrServiceStubDispatch,
|
||||
};
|
||||
|
||||
int DevmgrServiceStubStartService(struct IDevmgrService *inst)
|
||||
@@ -169,6 +262,8 @@ int DevmgrServiceStubStartService(struct IDevmgrService *inst)
|
||||
}
|
||||
fullService->remote = remoteService;
|
||||
|
||||
DriverModuleLoadHelperInit();
|
||||
|
||||
return DevmgrServiceStartService((struct IDevmgrService *)&fullService->super);
|
||||
}
|
||||
|
||||
@@ -208,4 +303,3 @@ void DevmgrServiceStubRelease(struct HdfObject *object)
|
||||
OsalMemFree(instance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,8 +96,8 @@ static int OnKEventReceived(
|
||||
struct HdfSysEvent *receivedEvent = NULL;
|
||||
uint32_t receivedEventLen = 0;
|
||||
|
||||
if (!HdfSbufReadBuffer(data, (const void **)&receivedEvent, &receivedEventLen)
|
||||
|| receivedEventLen != sizeof(struct HdfSysEvent)) {
|
||||
if (!HdfSbufReadBuffer(data, (const void **)&receivedEvent, &receivedEventLen) ||
|
||||
receivedEventLen != sizeof(struct HdfSysEvent)) {
|
||||
HDF_LOGE("failed to read kevent object");
|
||||
return HDF_FAILURE;
|
||||
}
|
||||
@@ -107,8 +107,7 @@ static int OnKEventReceived(
|
||||
OsalMutexLock(¬ifier->mutex);
|
||||
|
||||
struct HdfSysEventNotifyNode *notifyNode = NULL;
|
||||
DLIST_FOR_EACH_ENTRY(notifyNode, ¬ifier->notifyNodeList, struct HdfSysEventNotifyNode, listNode)
|
||||
{
|
||||
DLIST_FOR_EACH_ENTRY(notifyNode, ¬ifier->notifyNodeList, struct HdfSysEventNotifyNode, listNode) {
|
||||
if (receivedEvent->eventClass & notifyNode->classFilter) {
|
||||
(void)notifyNode->callback(
|
||||
notifyNode, receivedEvent->eventClass, receivedEvent->eventid, receivedEvent->content);
|
||||
@@ -157,7 +156,7 @@ static void DeInitKeventIoServiceListenerLocked(struct HdfSysEventNotifier *noti
|
||||
notifier->keventIoService = NULL;
|
||||
}
|
||||
|
||||
int HdfSysEventNotifyRegister(struct HdfSysEventNotifyNode *notifierNode, uint64_t classSet)
|
||||
int32_t HdfSysEventNotifyRegister(struct HdfSysEventNotifyNode *notifierNode, uint64_t classSet)
|
||||
{
|
||||
if (notifierNode == NULL) {
|
||||
return HDF_ERR_INVALID_PARAM;
|
||||
@@ -172,7 +171,7 @@ int HdfSysEventNotifyRegister(struct HdfSysEventNotifyNode *notifierNode, uint64
|
||||
OsalMutexLock(¬ifier->mutex);
|
||||
DListInsertTail(¬ifierNode->listNode, ¬ifier->notifyNodeList);
|
||||
notifierNode->classFilter = classSet;
|
||||
int ret = InitKeventIoServiceListenerLocked(notifier);
|
||||
int32_t ret = InitKeventIoServiceListenerLocked(notifier);
|
||||
if (ret != HDF_SUCCESS) {
|
||||
DListRemove(¬ifierNode->listNode);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ group("hdf_test_uhdf") {
|
||||
deps = [
|
||||
"unittest/config:hdf_adapter_uhdf_test_config",
|
||||
"unittest/manager:hdf_adapter_uhdf_test_ioservice",
|
||||
"unittest/manager:hdf_adapter_uhdf_test_manager",
|
||||
"unittest/manager:hdf_adapter_uhdf_test_pm",
|
||||
"unittest/manager:hdf_adapter_uhdf_test_sbuf",
|
||||
"unittest/osal:hdf_adapter_uhdf_test_osal",
|
||||
|
||||
Reference in New Issue
Block a user