• 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_dispatch.h"
10 #include "hdf_log.h"
11 #include "osal_mem.h"
12 #include "pcie_core.h"
13 #include "pcie_if.h"
14 
15 #define HDF_LOG_TAG pcie_dispatch_c
16 
17 enum PcieIoCmd {
18     PCIE_CMD_READ,
19     PCIE_CMD_WRITE,
20     PCIE_CMD_BUTT,
21 };
22 
23 struct PcieDispatchFunc {
24     uint32_t cmd;
25     int32_t (*func)(struct PcieCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply);
26 };
27 
PcieCmdRead(struct PcieCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)28 static int32_t PcieCmdRead(struct PcieCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
29 {
30     uint32_t len, pos;
31     uint8_t *buf = NULL;
32     int32_t ret;
33 
34     if (!HdfSbufReadUint32(data, &len)) {
35         HDF_LOGE("PcieCmdRead: read len fail");
36         return HDF_ERR_IO;
37     }
38     if (len == 0) {
39         return HDF_ERR_INVALID_PARAM;
40     }
41     if (!HdfSbufReadUint32(data, &pos)) {
42         HDF_LOGE("PcieCmdRead: read pos fail");
43         return HDF_ERR_IO;
44     }
45 
46     buf = (uint8_t *)OsalMemCalloc(sizeof(*buf) * len);
47     if (buf == NULL) {
48         HDF_LOGE("PcieCmdRead: OsalMemCalloc error");
49         return HDF_ERR_MALLOC_FAIL;
50     }
51 
52     ret = PcieCntlrRead(cntlr, pos, buf, len);
53     if (ret != HDF_SUCCESS) {
54         HDF_LOGE("PcieCntlrRead: error, ret is %d", ret);
55         goto EXIT;
56     }
57     if (!HdfSbufWriteBuffer(reply, buf, len)) {
58         HDF_LOGE("PcieCntlrRead: sbuf write buffer failed");
59         ret = HDF_ERR_IO;
60         goto EXIT;
61     }
62     ret = HDF_SUCCESS;
63 EXIT:
64     OsalMemFree(buf);
65     return ret;
66 }
67 
PcieCmdWrite(struct PcieCntlr * cntlr,struct HdfSBuf * data,struct HdfSBuf * reply)68 static int32_t PcieCmdWrite(struct PcieCntlr *cntlr, struct HdfSBuf *data, struct HdfSBuf *reply)
69 {
70     uint32_t size, pos;
71     uint8_t *buf = NULL;
72     (void)reply;
73 
74     if (!HdfSbufReadUint32(data, &pos)) {
75         HDF_LOGE("PcieCmdWrite: read pos fail");
76         return HDF_ERR_IO;
77     }
78     if (!HdfSbufReadBuffer(data, (const void **)&buf, &size)) {
79         HDF_LOGE("PcieCmdWrite: sbuf read buffer failed");
80         return HDF_ERR_IO;
81     }
82     return PcieCntlrWrite(cntlr, pos, buf, size);
83 }
84 
PcieIoDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)85 int32_t PcieIoDispatch(struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
86 {
87     struct PcieCntlr *cntlr = NULL;
88     uint32_t i;
89     uint32_t len;
90     struct PcieDispatchFunc dispatchFunc[] = {
91         { PCIE_CMD_READ, PcieCmdRead },
92         { PCIE_CMD_WRITE, PcieCmdWrite },
93     };
94 
95     if (client == NULL || client->device == NULL) {
96         HDF_LOGE("PcieIoDispatch: client or hdf dev obj is NULL");
97         return HDF_ERR_INVALID_OBJECT;
98     }
99 
100     cntlr = (struct PcieCntlr *)client->device->service;
101     if (cntlr == NULL) {
102         HDF_LOGE("PcieIoDispatch: service is NULL");
103         return HDF_ERR_INVALID_OBJECT;
104     }
105 
106     len = sizeof(dispatchFunc) / sizeof(dispatchFunc[0]);
107     for (i = 0; i < len; i++) {
108         if (dispatchFunc[i].cmd == cmd) {
109             return dispatchFunc[i].func(cntlr, data, reply);
110         }
111     }
112 
113     HDF_LOGE("PcieIoDispatch: cmd %d is not support", cmd);
114     return HDF_ERR_NOT_SUPPORT;
115 }
116