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