1 /*
2  * Copyright (c) 2020-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 #ifndef __USER__
10 #include "mmc_emmc.h"
11 #endif
12 #include "emmc_if.h"
13 #ifdef __USER__
14 #include "hdf_io_service_if.h"
15 #endif
16 #include "hdf_log.h"
17 #include "securec.h"
18 
19 #define HDF_LOG_TAG emmc_if_c
20 
21 #ifdef __USER__
EmmcGetCidReadReplyData(struct HdfSBuf * reply,uint8_t * cid,uint32_t size)22 static int32_t EmmcGetCidReadReplyData(struct HdfSBuf *reply, uint8_t *cid, uint32_t size)
23 {
24     uint32_t rLen;
25     const void *rBuf = NULL;
26 
27     if (HdfSbufReadBuffer(reply, &rBuf, &rLen) == false) {
28         HDF_LOGE("EmmcGetCidReadReplyData: read rBuf fail!");
29         return HDF_ERR_IO;
30     }
31     if (size != rLen) {
32         HDF_LOGE("EmmcGetCidReadReplyData: err len:%u, rLen:%u", size, rLen);
33         if (rLen > size) {
34             rLen = size;
35         }
36     }
37 
38     if (memcpy_s(cid, size, rBuf, rLen) != EOK) {
39         HDF_LOGE("EmmcGetCidReadReplyData: memcpy rBuf fail!");
40         return HDF_ERR_IO;
41     }
42     return HDF_SUCCESS;
43 }
44 
EmmcServiceGetCid(struct HdfIoService * service,uint8_t * cid,uint32_t size)45 int32_t EmmcServiceGetCid(struct HdfIoService *service, uint8_t *cid, uint32_t size)
46 {
47     int32_t ret;
48     struct HdfSBuf *reply = NULL;
49 
50     reply = HdfSbufObtainDefaultSize();
51     if (reply == NULL) {
52         HDF_LOGE("EmmcServiceGetCid: fail to obtain reply!");
53         ret = HDF_ERR_MALLOC_FAIL;
54         goto __EXIT;
55     }
56 
57     if (service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
58         HDF_LOGE("EmmcServiceGetCid: dispatcher or Dispatch is null!");
59         ret = HDF_ERR_NOT_SUPPORT;
60         goto __EXIT;
61     }
62 
63     ret = service->dispatcher->Dispatch(&service->object, EMMC_CMD_GET_CID, NULL, reply);
64     if (ret != HDF_SUCCESS) {
65         HDF_LOGE("EmmcServiceGetCid: fail to send service call, ret: %d!", ret);
66         goto __EXIT;
67     }
68 
69     ret = EmmcGetCidReadReplyData(reply, cid, size);
70     if (ret != HDF_SUCCESS) {
71         goto __EXIT;
72     }
73     HDF_LOGD("EmmcServiceGetCid: success");
74 
75 __EXIT:
76     if (reply != NULL) {
77         HdfSbufRecycle(reply);
78     }
79     return ret;
80 }
81 
82 #else
EmmcDeviceGetFromHandle(DevHandle handle,struct EmmcDevice ** emmc)83 static int32_t EmmcDeviceGetFromHandle(DevHandle handle, struct EmmcDevice **emmc)
84 {
85     struct MmcDevice *mmc = NULL;
86 
87     if (handle == NULL) {
88         HDF_LOGE("EmmcDeviceGetFromHandle: handle is null!");
89         return HDF_ERR_INVALID_OBJECT;
90     }
91 
92     if (emmc == NULL) {
93         HDF_LOGE("EmmcDeviceGetFromHandle: emmc is null!");
94         return HDF_ERR_INVALID_PARAM;
95     }
96 
97     mmc = MmcCntlrGetDevice((struct MmcCntlr *)handle);
98     if (mmc == NULL) {
99         HDF_LOGE("EmmcDeviceGetFromHandle: mmc is null!");
100         return HDF_PLT_ERR_NO_DEV;
101     }
102     if (mmc->type != MMC_DEV_EMMC) {
103         MmcDevicePut(mmc);
104         return HDF_PLT_ERR_DEV_TYPE;
105     }
106 
107     *emmc = (struct EmmcDevice *)mmc;
108     return HDF_SUCCESS;
109 }
110 
111 #endif
112 
EmmcGetCid(DevHandle handle,uint8_t * cid,uint32_t size)113 int32_t EmmcGetCid(DevHandle handle, uint8_t *cid, uint32_t size)
114 {
115 #ifndef __USER__
116     struct EmmcDevice *emmc = NULL;
117     int32_t ret;
118 #endif
119     if (handle == NULL) {
120         HDF_LOGE("EmmcGetCid: handle is null!");
121         return HDF_ERR_INVALID_OBJECT;
122     }
123 
124     if (cid == NULL || size < EMMC_CID_LEN) {
125         HDF_LOGE("EmmcGetCid: error parms!");
126         return HDF_ERR_INVALID_PARAM;
127     }
128 #ifdef __USER__
129     return EmmcServiceGetCid((struct HdfIoService *)handle, cid, size);
130 #else
131     if (EmmcDeviceGetFromHandle(handle, &emmc) != HDF_SUCCESS) {
132         return HDF_ERR_INVALID_OBJECT;
133     }
134     ret = EmmcDeviceGetCid(emmc, cid, size);
135     MmcDevicePut((struct MmcDevice *)emmc);
136     return ret;
137 #endif
138 }
139 
EmmcGetHuid(uint8_t * cid,uint32_t size)140 void EmmcGetHuid(uint8_t *cid, uint32_t size)
141 {
142     DevHandle handle = NULL;
143 
144     if (cid == NULL || size == 0) {
145         HDF_LOGE("EmmcGetUdid: error parms!");
146         return;
147     }
148     if (memset_s(cid, sizeof(uint8_t) * size, 0, sizeof(uint8_t) * size) != EOK) {
149         HDF_LOGE("EmmcGetUdid: memset_s fail!");
150         return;
151     }
152     handle = EmmcOpen(0);
153     if (handle == NULL) {
154         HDF_LOGD("EmmcGetUdid: open fail, use default value!");
155         return;
156     }
157     if (EmmcGetCid(handle, cid, size) != HDF_SUCCESS) {
158         HDF_LOGD("EmmcGetUdid: get fail, use default value!");
159     }
160     EmmcClose(handle);
161 }
162