1 /*
2 * Copyright (c) 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 "pcie_core.h"
10 #include "device_resource_if.h"
11 #include "hdf_log.h"
12 #include "osal_mem.h"
13 #include "osal_time.h"
14 #include "pcie_dispatch.h"
15 #include "securec.h"
16
17 #define HDF_LOG_TAG pcie_core_c
18
PcieCntlrInit(struct PcieCntlr * cntlr)19 static int32_t PcieCntlrInit(struct PcieCntlr *cntlr)
20 {
21 int32_t ret;
22
23 if (cntlr == NULL) {
24 return HDF_ERR_INVALID_OBJECT;
25 }
26
27 if (cntlr->hdfDevObj == NULL) {
28 HDF_LOGE("PcieCntlrInit: no HdfDeviceObject attached!");
29 return HDF_ERR_INVALID_OBJECT;
30 }
31
32 ret = OsalMutexInit(&cntlr->mutex);
33 if (ret != HDF_SUCCESS) {
34 HDF_LOGE("PcieCntlrInit: mutex init fail!");
35 return ret;
36 }
37
38 cntlr->service.Dispatch = PcieIoDispatch;
39 cntlr->hdfDevObj->service = &(cntlr->service);
40 cntlr->device.number = (int32_t)cntlr->devInfo.busNum;
41 cntlr->device.hdfDev = cntlr->hdfDevObj;
42 return HDF_SUCCESS;
43 }
44
PcieCntlrUninit(struct PcieCntlr * cntlr)45 static void PcieCntlrUninit(struct PcieCntlr *cntlr)
46 {
47 if (cntlr != NULL) {
48 (void)OsalMutexDestroy(&cntlr->mutex);
49 }
50 }
51
PcieCntlrAdd(struct PcieCntlr * cntlr)52 int32_t PcieCntlrAdd(struct PcieCntlr *cntlr)
53 {
54 int32_t ret;
55
56 if (cntlr == NULL) {
57 return HDF_ERR_INVALID_OBJECT;
58 }
59
60 ret = PcieCntlrInit(cntlr);
61 if (ret != HDF_SUCCESS) {
62 return ret;
63 }
64
65 cntlr->device.manager = PlatformManagerGet(PLATFORM_MODULE_PCIE);
66 ret = PlatformDeviceAdd(&cntlr->device);
67 if (ret != HDF_SUCCESS) {
68 HDF_LOGE("PcieCntlrAdd: device add fail!");
69 PcieCntlrUninit(cntlr);
70 return ret;
71 }
72 return HDF_SUCCESS;
73 }
74
PcieCntlrRemove(struct PcieCntlr * cntlr)75 void PcieCntlrRemove(struct PcieCntlr *cntlr)
76 {
77 if (cntlr != NULL) {
78 PlatformDeviceDel(&cntlr->device);
79 PcieCntlrUninit(cntlr);
80 }
81 }
82
PcieCntlrParse(struct PcieCntlr * cntlr,struct HdfDeviceObject * obj)83 int32_t PcieCntlrParse(struct PcieCntlr *cntlr, struct HdfDeviceObject *obj)
84 {
85 const struct DeviceResourceNode *node = NULL;
86 struct DeviceResourceIface *drsOps = NULL;
87 int32_t ret;
88
89 if (obj == NULL || cntlr == NULL) {
90 HDF_LOGE("PcieCntlrParse: input param is NULL.");
91 return HDF_FAILURE;
92 }
93
94 node = obj->property;
95 if (node == NULL) {
96 HDF_LOGE("PcieCntlrParse: drs node is NULL.");
97 return HDF_FAILURE;
98 }
99 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
100 if (drsOps == NULL || drsOps->GetUint32 == NULL) {
101 HDF_LOGE("PcieCntlrParse: invalid drs ops fail.");
102 return HDF_FAILURE;
103 }
104
105 ret = drsOps->GetUint32(node, "busNum", &(cntlr->devInfo.busNum), 0);
106 if (ret != HDF_SUCCESS) {
107 HDF_LOGE("PcieCntlrParse: read busNum fail!");
108 return ret;
109 }
110
111 ret = drsOps->GetUint32(node, "vendorId", &(cntlr->devInfo.vendorId), 0);
112 if (ret != HDF_SUCCESS) {
113 HDF_LOGE("PcieCntlrParse: read vendorId fail!");
114 return HDF_FAILURE;
115 }
116
117 ret = drsOps->GetUint32(node, "devId", &(cntlr->devInfo.devId), 0);
118 if (ret != HDF_SUCCESS) {
119 HDF_LOGE("PcieCntlrParse: read devId fail!");
120 return HDF_FAILURE;
121 }
122 return HDF_SUCCESS;
123 }
124
PcieCntlrRead(struct PcieCntlr * cntlr,uint32_t pos,uint8_t * data,uint32_t len)125 int32_t PcieCntlrRead(struct PcieCntlr *cntlr, uint32_t pos, uint8_t *data, uint32_t len)
126 {
127 int32_t ret;
128
129 if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->read == NULL) {
130 return HDF_ERR_INVALID_OBJECT;
131 }
132 if (data == NULL || len == 0) {
133 return HDF_ERR_INVALID_PARAM;
134 }
135
136 PcieCntlrLock(cntlr);
137 ret = cntlr->ops->read(cntlr, pos, data, len);
138 PcieCntlrUnlock(cntlr);
139 return ret;
140 }
141
PcieCntlrWrite(struct PcieCntlr * cntlr,uint32_t pos,uint8_t * data,uint32_t len)142 int32_t PcieCntlrWrite(struct PcieCntlr *cntlr, uint32_t pos, uint8_t *data, uint32_t len)
143 {
144 int32_t ret;
145 if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->write == NULL) {
146 return HDF_ERR_INVALID_OBJECT;
147 }
148 if (data == NULL || len == 0) {
149 return HDF_ERR_INVALID_PARAM;
150 }
151
152 PcieCntlrLock(cntlr);
153 ret = cntlr->ops->write(cntlr, pos, data, len);
154 PcieCntlrUnlock(cntlr);
155 return ret;
156 }
157