• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 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 "hdf_device.h"
10 #include "hdf_base.h"
11 #include "hdf_device_node.h"
12 #include "hdf_device_token.h"
13 #include "hdf_log.h"
14 #include "hdf_object_manager.h"
15 #include "osal_mem.h"
16 
17 #define HDF_LOG_TAG hdf_device
18 
UpdateDeivceNodeIdIndex(struct HdfDevice * device,devid_t nodeDevid)19 static void UpdateDeivceNodeIdIndex(struct HdfDevice *device, devid_t nodeDevid)
20 {
21     if (device->devidIndex < DEVICEID(nodeDevid)) {
22         device->devidIndex = DEVICEID(nodeDevid);
23     }
24 }
25 
AcquireNodeDeivceId(struct HdfDevice * device,devid_t * devid)26 static int AcquireNodeDeivceId(struct HdfDevice *device, devid_t *devid)
27 {
28     if (device->devidIndex >= DEVICEID_MASK) {
29         return HDF_FAILURE;
30     }
31     device->devidIndex++;
32     *devid = MK_DEVID(HOSTID(device->deviceId), DEVICEID(device->deviceId), device->devidIndex);
33 
34     return HDF_SUCCESS;
35 }
36 
HdfDeviceAttach(struct IHdfDevice * devInst,struct HdfDeviceNode * devNode)37 static int HdfDeviceAttach(struct IHdfDevice *devInst, struct HdfDeviceNode *devNode)
38 {
39     int ret;
40     struct HdfDevice *device = (struct HdfDevice *)devInst;
41     struct IDeviceNode *nodeIf = (struct IDeviceNode *)devNode;
42 
43     if (device == NULL || nodeIf == NULL || nodeIf->LaunchNode == NULL) {
44         HDF_LOGE("failed to attach device, input params invalid");
45         return HDF_ERR_INVALID_PARAM;
46     }
47 
48     // for dynamic added device node, assign device id here
49     if (devNode->devId == 0 && AcquireNodeDeivceId(device, &devNode->devId) != HDF_SUCCESS) {
50         HDF_LOGE("failed to attach device, invalid device id");
51         return HDF_ERR_INVALID_PARAM;
52     }
53     devNode->token->devid = devNode->devId;
54     ret = nodeIf->LaunchNode(devNode);
55     if (ret == HDF_SUCCESS) {
56         DListInsertTail(&devNode->entry, &device->devNodes);
57         UpdateDeivceNodeIdIndex(device, devNode->devId);
58     }
59 
60     return ret;
61 }
62 
HdfDeviceDetach(struct IHdfDevice * devInst,struct HdfDeviceNode * devNode)63 int HdfDeviceDetach(struct IHdfDevice *devInst, struct HdfDeviceNode *devNode)
64 {
65     struct HdfDevice *device = NULL;
66     if (devInst == NULL || devNode == NULL) {
67         return HDF_ERR_INVALID_PARAM;
68     }
69 
70     device = CONTAINER_OF(devInst, struct HdfDevice, super);
71     if (DEVICEID(device->deviceId) != DEVICEID(devNode->devId)) {
72         HDF_LOGE("%s: device %x detach unknown devnode %x", __func__, device->deviceId, devNode->devId);
73         return HDF_DEV_ERR_NO_DEVICE;
74     }
75 
76     if (devNode->entry.next != NULL) {
77         DListRemove(&devNode->entry);
78     }
79     if (devNode->super.UnlaunchNode != NULL) {
80         devNode->super.UnlaunchNode(devNode);
81     }
82 
83     return HDF_SUCCESS;
84 }
85 
HdfDeviceGetDeviceNode(struct IHdfDevice * device,devid_t devid)86 static struct HdfDeviceNode *HdfDeviceGetDeviceNode(struct IHdfDevice *device, devid_t devid)
87 {
88     struct HdfDeviceNode *devNode = NULL;
89     struct HdfDevice *dev = CONTAINER_OF(device, struct HdfDevice, super);
90     DLIST_FOR_EACH_ENTRY(devNode, &dev->devNodes, struct HdfDeviceNode, entry) {
91         if (devNode->devId == devid) {
92             return devNode;
93         };
94     }
95     return NULL;
96 }
97 
HdfDeviceDetachWithDevid(struct IHdfDevice * device,devid_t devid)98 static int HdfDeviceDetachWithDevid(struct IHdfDevice *device, devid_t devid)
99 {
100     struct HdfDevice *dev = CONTAINER_OF(device, struct HdfDevice, super);
101     struct HdfDeviceNode *devNode = HdfDeviceGetDeviceNode(device, devid);
102     if (devNode == NULL) {
103         HDF_LOGE("detach device node %x not in device %x", devid, dev->deviceId);
104         return HDF_DEV_ERR_NO_DEVICE;
105     }
106 
107     return HdfDeviceDetach(device, devNode);
108 }
109 
HdfDeviceConstruct(struct HdfDevice * device)110 void HdfDeviceConstruct(struct HdfDevice *device)
111 {
112     device->super.Attach = HdfDeviceAttach;
113     device->super.Detach = HdfDeviceDetach;
114     device->super.DetachWithDevid = HdfDeviceDetachWithDevid;
115     device->super.GetDeviceNode = HdfDeviceGetDeviceNode;
116 
117     DListHeadInit(&device->devNodes);
118 }
119 
HdfDeviceDestruct(struct HdfDevice * device)120 void HdfDeviceDestruct(struct HdfDevice *device)
121 {
122     struct HdfDeviceNode *devNode = NULL;
123     struct HdfDeviceNode *tmp = NULL;
124     DLIST_FOR_EACH_ENTRY_SAFE(devNode, tmp, &device->devNodes, struct HdfDeviceNode, entry) {
125         HdfDeviceNodeFreeInstance(devNode);
126     }
127     DListHeadInit(&device->devNodes);
128 }
129 
HdfDeviceCreate(void)130 struct HdfObject *HdfDeviceCreate(void)
131 {
132     struct HdfDevice *device = (struct HdfDevice *)OsalMemCalloc(sizeof(struct HdfDevice));
133     if (device != NULL) {
134         HdfDeviceConstruct(device);
135     }
136     return (struct HdfObject *)device;
137 }
138 
HdfDeviceRelease(struct HdfObject * object)139 void HdfDeviceRelease(struct HdfObject *object)
140 {
141     struct HdfDevice *device = (struct HdfDevice *)object;
142     if (device != NULL) {
143         HdfDeviceDestruct(device);
144         OsalMemFree(device);
145     }
146 }
147 
HdfDeviceNewInstance(void)148 struct HdfDevice *HdfDeviceNewInstance(void)
149 {
150     return (struct HdfDevice *)HdfObjectManagerGetObject(HDF_OBJECT_ID_DEVICE);
151 }
152 
HdfDeviceFreeInstance(struct HdfDevice * device)153 void HdfDeviceFreeInstance(struct HdfDevice *device)
154 {
155     if (device != NULL) {
156         HdfObjectManagerFreeObject(&device->super.object);
157     }
158 }
159