• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_%u", 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