• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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 "pcie_dispatch.h"
14 #include "securec.h"
15 
16 #define HDF_LOG_TAG pcie_core_c
17 
PcieCntlrInit(struct PcieCntlr * cntlr)18 static int32_t PcieCntlrInit(struct PcieCntlr *cntlr)
19 {
20     int32_t ret;
21 
22     if (cntlr == NULL || cntlr->hdfDevObj == NULL) {
23         HDF_LOGE("PcieCntlrInit: cntlr or hdfDevObj is null!");
24         return HDF_ERR_INVALID_OBJECT;
25     }
26 
27     ret = OsalSpinInit(&cntlr->spin);
28     if (ret != HDF_SUCCESS) {
29         HDF_LOGE("PcieCntlrInit: spin init fail!");
30         return ret;
31     }
32 
33     cntlr->service.Dispatch = PcieIoDispatch;
34     cntlr->hdfDevObj->service = &(cntlr->service);
35     cntlr->device.number = (int32_t)cntlr->devInfo.busNum;
36     cntlr->device.hdfDev = cntlr->hdfDevObj;
37     return HDF_SUCCESS;
38 }
39 
PcieCntlrUninit(struct PcieCntlr * cntlr)40 static inline void PcieCntlrUninit(struct PcieCntlr *cntlr)
41 {
42     if (cntlr != NULL) {
43         (void)OsalSpinDestroy(&cntlr->spin);
44     }
45 }
46 
PcieCntlrAdd(struct PcieCntlr * cntlr)47 int32_t PcieCntlrAdd(struct PcieCntlr *cntlr)
48 {
49     int32_t ret;
50 
51     if (cntlr == NULL) {
52         HDF_LOGE("PcieCntlrAdd: invalid param!");
53         return HDF_ERR_INVALID_OBJECT;
54     }
55 
56     ret = PcieCntlrInit(cntlr);
57     if (ret != HDF_SUCCESS) {
58         HDF_LOGE("PcieCntlrAdd: pcie cntlr init fail!");
59         return ret;
60     }
61 
62     cntlr->device.manager = PlatformManagerGet(PLATFORM_MODULE_PCIE);
63     ret = PlatformDeviceAdd(&cntlr->device);
64     if (ret != HDF_SUCCESS) {
65         HDF_LOGE("PcieCntlrAdd: device add fail!");
66         PcieCntlrUninit(cntlr);
67         return ret;
68     }
69     return HDF_SUCCESS;
70 }
71 
PcieCntlrRemove(struct PcieCntlr * cntlr)72 void PcieCntlrRemove(struct PcieCntlr *cntlr)
73 {
74     if (cntlr != NULL) {
75         PlatformDeviceDel(&cntlr->device);
76         PcieCntlrUninit(cntlr);
77     }
78 }
79 
PcieCntlrParse(struct PcieCntlr * cntlr,struct HdfDeviceObject * obj)80 int32_t PcieCntlrParse(struct PcieCntlr *cntlr, struct HdfDeviceObject *obj)
81 {
82     const struct DeviceResourceNode *node = NULL;
83     struct DeviceResourceIface *drsOps = NULL;
84     int32_t ret;
85 
86     if (obj == NULL || cntlr == NULL) {
87         HDF_LOGE("PcieCntlrParse: input param is null!");
88         return HDF_FAILURE;
89     }
90 
91     node = obj->property;
92     if (node == NULL) {
93         HDF_LOGE("PcieCntlrParse: drs node is null!");
94         return HDF_FAILURE;
95     }
96     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
97     if (drsOps == NULL || drsOps->GetUint32 == NULL) {
98         HDF_LOGE("PcieCntlrParse: invalid drs ops fail.");
99         return HDF_FAILURE;
100     }
101 
102     ret = drsOps->GetUint16(node, "busNum", &(cntlr->devInfo.busNum), 0);
103     if (ret != HDF_SUCCESS) {
104         HDF_LOGE("PcieCntlrParse: read busNum fail!");
105         return ret;
106     }
107 
108     ret = drsOps->GetUint32(node, "vendorId", &(cntlr->devInfo.vendorId), 0);
109     if (ret != HDF_SUCCESS) {
110         HDF_LOGE("PcieCntlrParse: read vendorId fail!");
111         return HDF_FAILURE;
112     }
113 
114     ret = drsOps->GetUint32(node, "devId", &(cntlr->devInfo.devId), 0);
115     if (ret != HDF_SUCCESS) {
116         HDF_LOGE("PcieCntlrParse: read devId fail!");
117         return HDF_FAILURE;
118     }
119     return HDF_SUCCESS;
120 }
121 
PcieCntlrRead(struct PcieCntlr * cntlr,uint32_t mode,uint32_t pos,uint8_t * data,uint32_t len)122 int32_t PcieCntlrRead(struct PcieCntlr *cntlr, uint32_t mode, uint32_t pos, uint8_t *data, uint32_t len)
123 {
124     int32_t ret;
125 
126     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->read == NULL) {
127         HDF_LOGE("PcieCntlrRead: invalid cntlr");
128         return HDF_ERR_INVALID_OBJECT;
129     }
130     if (data == NULL || len == 0 || mode > PCIE_IO) {
131         HDF_LOGE("PcieCntlrRead: invalid param");
132         return HDF_ERR_INVALID_PARAM;
133     }
134 
135     PcieCntlrLock(cntlr);
136     ret = cntlr->ops->read(cntlr, mode, pos, data, len);
137     PcieCntlrUnlock(cntlr);
138     return ret;
139 }
140 
PcieCntlrWrite(struct PcieCntlr * cntlr,uint32_t mode,uint32_t pos,uint8_t * data,uint32_t len)141 int32_t PcieCntlrWrite(struct PcieCntlr *cntlr, uint32_t mode, uint32_t pos, uint8_t *data, uint32_t len)
142 {
143     int32_t ret;
144     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->write == NULL) {
145         HDF_LOGE("PcieCntlrWrite: invalid cntlr");
146         return HDF_ERR_INVALID_OBJECT;
147     }
148     if (data == NULL || len == 0 || mode > PCIE_IO) {
149         HDF_LOGE("PcieCntlrWrite: invalid cb");
150         return HDF_ERR_INVALID_PARAM;
151     }
152 
153     PcieCntlrLock(cntlr);
154     ret = cntlr->ops->write(cntlr, mode, pos, data, len);
155     PcieCntlrUnlock(cntlr);
156     return ret;
157 }
158 
PcieCntlrDmaMap(struct PcieCntlr * cntlr,PcieCallbackFunc cb,uintptr_t addr,uint32_t len,uint8_t dir)159 int32_t PcieCntlrDmaMap(struct PcieCntlr *cntlr, PcieCallbackFunc cb, uintptr_t addr, uint32_t len, uint8_t dir)
160 {
161     int32_t ret;
162 
163     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->write == NULL) {
164         HDF_LOGE("PcieCntlrDmaMap: invalid param");
165         return HDF_ERR_INVALID_OBJECT;
166     }
167     if (addr == 0 || cb == NULL || len == 0) {
168         HDF_LOGE("PcieCntlrDmaMap: invalid param");
169         return HDF_ERR_INVALID_PARAM;
170     }
171 
172     PcieCntlrLock(cntlr);
173     if (cntlr->dmaCb != NULL) {
174         HDF_LOGE("PcieCntlrDmaMap: irq has been registered");
175         PcieCntlrUnlock(cntlr);
176         return HDF_FAILURE;
177     }
178     cntlr->dmaCb = cb;
179     ret = cntlr->ops->dmaMap(cntlr, addr, len, dir);
180     PcieCntlrUnlock(cntlr);
181     return ret;
182 }
183 
PcieCntlrDmaUnmap(struct PcieCntlr * cntlr,uintptr_t addr,uint32_t len,uint8_t dir)184 void PcieCntlrDmaUnmap(struct PcieCntlr *cntlr, uintptr_t addr, uint32_t len, uint8_t dir)
185 {
186     if (cntlr == NULL) {
187         HDF_LOGE("PcieCntlrDmaUnmap: invalid param");
188         return;
189     }
190     PcieCntlrLock(cntlr);
191     cntlr->ops->dmaUnmap(cntlr, addr, len, dir);
192     cntlr->dmaCb = NULL;
193     PcieCntlrUnlock(cntlr);
194 }
195 
PcieCntlrRegisterIrq(struct PcieCntlr * cntlr,PcieCallbackFunc cb)196 int32_t PcieCntlrRegisterIrq(struct PcieCntlr *cntlr, PcieCallbackFunc cb)
197 {
198     if (cntlr == NULL || cntlr->ops == NULL || cb == NULL) {
199         HDF_LOGE("PcieCntlrRegisterIrq: invalid param");
200         return HDF_ERR_INVALID_OBJECT;
201     }
202 
203     PcieCntlrLock(cntlr);
204     if (cntlr->cb != NULL) {
205         HDF_LOGE("PcieCntlrRegisterIrq: irq has been registered");
206         PcieCntlrUnlock(cntlr);
207         return HDF_FAILURE;
208     }
209     cntlr->cb = cb;
210     if (cntlr->ops->registerIrq != NULL) {
211         cntlr->ops->registerIrq(cntlr);
212     }
213     PcieCntlrUnlock(cntlr);
214     return HDF_SUCCESS;
215 }
216 
PcieCntlrUnregisterIrq(struct PcieCntlr * cntlr)217 void PcieCntlrUnregisterIrq(struct PcieCntlr *cntlr)
218 {
219     if (cntlr == NULL || cntlr->ops == NULL) {
220         HDF_LOGE("PcieCntlrUnregisterIrq: invalid param");
221         return;
222     }
223     PcieCntlrLock(cntlr);
224     if (cntlr->ops->unregisterIrq != NULL) {
225         cntlr->ops->unregisterIrq(cntlr);
226     }
227 
228     cntlr->cb = NULL;
229     PcieCntlrUnlock(cntlr);
230 }
231 
PcieCntlrCallback(struct PcieCntlr * cntlr)232 int32_t PcieCntlrCallback(struct PcieCntlr *cntlr)
233 {
234     if (cntlr == NULL) {
235         HDF_LOGE("PcieCntlrCallback: cntlr is null!");
236         return HDF_ERR_INVALID_OBJECT;
237     }
238     if (cntlr->cb != NULL) {
239         return cntlr->cb((DevHandle)cntlr);
240     }
241     return HDF_SUCCESS;
242 }
243 
PcieCntlrDmaCallback(struct PcieCntlr * cntlr)244 int32_t PcieCntlrDmaCallback(struct PcieCntlr *cntlr)
245 {
246     if (cntlr == NULL) {
247         HDF_LOGE("PcieCntlrDmaCallback: cntlr is null!");
248         return HDF_ERR_INVALID_OBJECT;
249     }
250     if (cntlr->dmaCb != NULL) {
251         return cntlr->dmaCb((DevHandle)cntlr);
252     }
253     return HDF_SUCCESS;
254 }
255