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_if.h"
10 #ifndef __USER__
11 #include "devsvc_manager_clnt.h"
12 #include "pcie_core.h"
13 #endif
14 #include "hdf_base.h"
15 #include "hdf_log.h"
16 #ifdef __USER__
17 #include "hdf_io_service_if.h"
18 #endif
19 #include "osal_mem.h"
20 #include "securec.h"
21
22 #define HDF_LOG_TAG pcie_if_c
23
24 #define PCIE_SERVICE_NAME_LEN 32
25
26 #ifdef __USER__
27 enum PcieIoCmd {
28 PCIE_CMD_READ,
29 PCIE_CMD_WRITE,
30 PCIE_CMD_BUTT,
31 };
32
PcieGetDataFromReply(struct HdfSBuf * reply,uint8_t * data,uint32_t size)33 static int32_t PcieGetDataFromReply(struct HdfSBuf *reply, uint8_t *data, uint32_t size)
34 {
35 uint32_t rLen;
36 const void *rBuf = NULL;
37
38 if (HdfSbufReadBuffer(reply, &rBuf, &rLen) == false) {
39 HDF_LOGE("PcieGetDataFromReply: read rBuf fail!");
40 return HDF_ERR_IO;
41 }
42 if (size != rLen) {
43 HDF_LOGE("PcieGetDataFromReply: err len:%u, rLen:%u", size, rLen);
44 if (rLen > size) {
45 rLen = size;
46 }
47 }
48
49 if (memcpy_s(data, size, rBuf, rLen) != EOK) {
50 HDF_LOGE("PcieGetDataFromReply: memcpy rBuf fail!");
51 return HDF_ERR_IO;
52 }
53 return HDF_SUCCESS;
54 }
55
PcieUserRead(DevHandle handle,uint32_t pos,uint8_t * data,uint32_t len)56 static int32_t PcieUserRead(DevHandle handle, uint32_t pos, uint8_t *data, uint32_t len)
57 {
58 int32_t ret;
59 struct HdfSBuf *reply = NULL;
60 struct HdfSBuf *buf = NULL;
61 struct HdfIoService *service = (struct HdfIoService *)handle;
62
63 if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
64 HDF_LOGE("PcieUserRead: service is invalid");
65 return HDF_ERR_INVALID_PARAM;
66 }
67 if (data == NULL || len == 0) {
68 return HDF_ERR_INVALID_PARAM;
69 }
70
71 buf = HdfSbufObtainDefaultSize();
72 if (buf == NULL) {
73 HDF_LOGE("PcieUserRead: failed to obtain buf");
74 ret = HDF_ERR_MALLOC_FAIL;
75 goto EXIT;
76 }
77 if (!HdfSbufWriteUint32(buf, len)) {
78 HDF_LOGE("PcieUserRead: sbuf write uint32 failed");
79 ret = HDF_ERR_IO;
80 goto EXIT;
81 }
82 if (!HdfSbufWriteUint32(buf, pos)) {
83 HDF_LOGE("PcieUserRead: sbuf write uint32 failed");
84 ret = HDF_ERR_IO;
85 goto EXIT;
86 }
87
88 reply = HdfSbufObtainDefaultSize();
89 if (reply == NULL) {
90 HDF_LOGE("PcieUserRead: failed to obtain reply");
91 ret = HDF_ERR_MALLOC_FAIL;
92 goto EXIT;
93 }
94
95 ret = service->dispatcher->Dispatch(&service->object, PCIE_CMD_READ, buf, reply);
96 if (ret != HDF_SUCCESS) {
97 HDF_LOGE("PcieUserRead: failed to write, ret %d", ret);
98 } else {
99 ret = PcieGetDataFromReply(reply, data, len);
100 }
101
102 EXIT :
103 if (reply != NULL) {
104 HdfSbufRecycle(reply);
105 }
106 if (buf != NULL) {
107 HdfSbufRecycle(buf);
108 }
109 return ret;
110 }
111
PcieUserWrite(DevHandle handle,uint32_t pos,uint8_t * data,uint32_t len)112 static int32_t PcieUserWrite(DevHandle handle, uint32_t pos, uint8_t *data, uint32_t len)
113 {
114 int32_t ret;
115 struct HdfSBuf *buf = NULL;
116 struct HdfIoService *service = (struct HdfIoService *)handle;
117
118 if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
119 HDF_LOGE("PcieUserWrite: service is invalid");
120 return HDF_ERR_INVALID_PARAM;
121 }
122 buf = HdfSbufObtainDefaultSize();
123 if (buf == NULL) {
124 HDF_LOGE("PcieUserWrite: failed to obtain buf");
125 return HDF_ERR_MALLOC_FAIL;
126 }
127 if (!HdfSbufWriteUint32(buf, pos)) {
128 HDF_LOGE("PcieUserWrite: sbuf write uint32 failed");
129 ret = HDF_ERR_IO;
130 goto EXIT;
131 }
132 if (!HdfSbufWriteBuffer(buf, data, len)) {
133 HDF_LOGE("PcieUserWrite: sbuf write buffer failed");
134 ret = HDF_ERR_IO;
135 goto EXIT;
136 }
137
138 ret = service->dispatcher->Dispatch(&service->object, PCIE_CMD_WRITE, buf, NULL);
139 if (ret != HDF_SUCCESS) {
140 HDF_LOGE("PcieUserWrite: failed to write, ret %d", ret);
141 }
142 EXIT:
143 HdfSbufRecycle(buf);
144 return ret;
145 }
146 #endif
147
PcieCntlrObjGet(uint16_t busNum)148 static void *PcieCntlrObjGet(uint16_t busNum)
149 {
150 char *serviceName = NULL;
151 void *obj = NULL;
152
153 serviceName = (char *)OsalMemCalloc(PCIE_SERVICE_NAME_LEN + 1);
154 if (serviceName == NULL) {
155 HDF_LOGE("HDMI service name malloc fail.");
156 return NULL;
157 }
158 if (snprintf_s(serviceName, (PCIE_SERVICE_NAME_LEN + 1),
159 PCIE_SERVICE_NAME_LEN, "HDF_PLATFORM_PCIE_%hu", busNum) < 0) {
160 HDF_LOGE("get PCIE service name fail.");
161 goto EXIT;
162 }
163 #ifdef __USER__
164 obj = (void *)HdfIoServiceBind(serviceName);
165 #else
166 obj = (void *)PcieCntlrGetByBusNum(busNum);
167 #endif
168 EXIT:
169 OsalMemFree(serviceName);
170 return obj;
171 }
172
PcieOpen(uint16_t busNum)173 DevHandle PcieOpen(uint16_t busNum)
174 {
175 return (DevHandle)PcieCntlrObjGet(busNum);
176 }
177
PcieRead(DevHandle handle,uint32_t pos,uint8_t * data,uint32_t len)178 int32_t PcieRead(DevHandle handle, uint32_t pos, uint8_t *data, uint32_t len)
179 {
180 #ifdef __USER__
181 return PcieUserRead(handle, pos, data, len);
182 #else
183 return PcieCntlrRead((struct PcieCntlr *)handle, pos, data, len);
184 #endif
185 }
186
PcieWrite(DevHandle handle,uint32_t pos,uint8_t * data,uint32_t len)187 int32_t PcieWrite(DevHandle handle, uint32_t pos, uint8_t *data, uint32_t len)
188 {
189 #ifdef __USER__
190 return PcieUserWrite(handle, pos, data, len);
191 #else
192 return PcieCntlrWrite((struct PcieCntlr *)handle, pos, data, len);
193 #endif
194 }
195
PcieClose(DevHandle handle)196 void PcieClose(DevHandle handle)
197 {
198 if (handle != NULL) {
199 #ifdef __USER__
200 HdfIoServiceRecycle((struct HdfIoService *)handle);
201 #endif
202 }
203 }
204