• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * emmc_adapter.c
3  *
4  * linux emmc driver implement.
5  *
6  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
7  *
8  * This software is licensed under the terms of the GNU General Public
9  * License version 2, as published by the Free Software Foundation, and
10  * may be copied, distributed, and modified under those terms.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  */
18 
19 #include <securec.h>
20 #include <linux/mmc/card.h>
21 #include <linux/mmc/host.h>
22 #include "device_resource_if.h"
23 #include "hdf_log.h"
24 #include "emmc_if.h"
25 #include "mmc_corex.h"
26 #include "mmc_emmc.h"
27 
28 #define HDF_LOG_TAG emmc_adapter_c
29 
30 struct mmc_host *GetMmcHost(int32_t slot);
31 
LinuxEmmcGetCid(struct EmmcDevice * dev,uint8_t * cid,uint32_t size)32 int32_t LinuxEmmcGetCid(struct EmmcDevice *dev, uint8_t *cid, uint32_t size)
33 {
34     struct mmc_host *mmcHost = NULL;
35     struct MmcCntlr *cntlr = NULL;
36 
37     if (dev == NULL || dev->mmc.cntlr == NULL) {
38         HDF_LOGE("LinuxEmmcGetCid: dev or cntlr is null.");
39         return HDF_ERR_INVALID_OBJECT;
40     }
41     if (cid == NULL || size < EMMC_CID_LEN) {
42         HDF_LOGE("LinuxEmmcGetCid: cid is null or size is invalid.");
43         return HDF_ERR_INVALID_PARAM;
44     }
45 
46     cntlr = dev->mmc.cntlr;
47     mmcHost = (struct mmc_host *)cntlr->priv;
48     if (mmcHost == NULL) {
49         HDF_LOGE("LinuxEmmcGetCid: mmcHost is NULL!");
50         return HDF_ERR_NOT_SUPPORT;
51     }
52     if (mmcHost->card == NULL) {
53         HDF_LOGE("LinuxEmmcGetCid: card is null.");
54         return HDF_ERR_NOT_SUPPORT;
55     }
56     if (memcpy_s(cid, sizeof(uint8_t) * size, (uint8_t *)(mmcHost->card->raw_cid),
57         sizeof(mmcHost->card->raw_cid)) != EOK) {
58         HDF_LOGE("LinuxEmmcGetCid: memcpy_s fail!");
59         return HDF_FAILURE;
60     }
61     return HDF_SUCCESS;
62 }
63 
64 static struct EmmcDeviceOps g_emmcMethod = {
65     .getCid = LinuxEmmcGetCid,
66 };
67 
LinuxEmmcDeleteCntlr(struct MmcCntlr * cntlr)68 static void LinuxEmmcDeleteCntlr(struct MmcCntlr *cntlr)
69 {
70     if (cntlr == NULL) {
71         return;
72     }
73 
74     if (cntlr->curDev != NULL) {
75         MmcDeviceRemove(cntlr->curDev);
76         OsalMemFree(cntlr->curDev);
77     }
78     MmcCntlrRemove(cntlr);
79     OsalMemFree(cntlr);
80 }
81 
LinuxEmmcCntlrParse(struct MmcCntlr * cntlr,struct HdfDeviceObject * obj)82 static int32_t LinuxEmmcCntlrParse(struct MmcCntlr *cntlr, struct HdfDeviceObject *obj)
83 {
84     const struct DeviceResourceNode *node = NULL;
85     struct DeviceResourceIface *drsOps = NULL;
86     int32_t ret;
87 
88     if (obj == NULL || cntlr == NULL) {
89         HDF_LOGE("LinuxEmmcCntlrParse: input para is NULL.");
90         return HDF_FAILURE;
91     }
92 
93     node = obj->property;
94     if (node == NULL) {
95         HDF_LOGE("LinuxEmmcCntlrParse: drs node is NULL.");
96         return HDF_FAILURE;
97     }
98     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
99     if (drsOps == NULL || drsOps->GetUint16 == NULL || drsOps->GetUint32 == NULL) {
100         HDF_LOGE("LinuxEmmcCntlrParse: invalid drs ops fail!");
101         return HDF_FAILURE;
102     }
103 
104     ret = drsOps->GetUint16(node, "hostId", &(cntlr->index), 0);
105     if (ret != HDF_SUCCESS) {
106         HDF_LOGE("LinuxEmmcCntlrParse: read hostIndex fail!");
107         return ret;
108     }
109     ret = drsOps->GetUint32(node, "devType", &(cntlr->devType), 0);
110     if (ret != HDF_SUCCESS) {
111         HDF_LOGE("LinuxEmmcCntlrParse: read devType fail!");
112         return ret;
113     }
114     return HDF_SUCCESS;
115 }
116 
LinuxEmmcBind(struct HdfDeviceObject * obj)117 static int32_t LinuxEmmcBind(struct HdfDeviceObject *obj)
118 {
119     struct MmcCntlr *cntlr = NULL;
120     int32_t ret;
121 
122     if (obj == NULL) {
123         HDF_LOGE("LinuxEmmcBind: Fail, obj is NULL.");
124         return HDF_ERR_INVALID_OBJECT;
125     }
126 
127     cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr));
128     if (cntlr == NULL) {
129         HDF_LOGE("LinuxEmmcBind: no mem for MmcCntlr.");
130         return HDF_ERR_MALLOC_FAIL;
131     }
132 
133     cntlr->ops = NULL;
134     cntlr->hdfDevObj = obj;
135     obj->service = &cntlr->service;
136     ret = LinuxEmmcCntlrParse(cntlr, obj);
137     if (ret != HDF_SUCCESS) {
138         HDF_LOGE("LinuxEmmcBind: cntlr parse fail.");
139         goto _ERR;
140     }
141     cntlr->priv = (void *)GetMmcHost((int32_t)cntlr->index);
142 
143     ret = MmcCntlrAdd(cntlr);
144     if (ret != HDF_SUCCESS) {
145         HDF_LOGE("LinuxEmmcBind: cntlr add fail.");
146         goto _ERR;
147     }
148 
149     ret = MmcCntlrAllocDev(cntlr, (enum MmcDevType)cntlr->devType);
150     if (ret != HDF_SUCCESS) {
151         HDF_LOGE("LinuxEmmcBind: alloc dev fail.");
152         goto _ERR;
153     }
154     MmcDeviceAddOps(cntlr->curDev, &g_emmcMethod);
155     HDF_LOGD("LinuxEmmcBind: Success!");
156     return HDF_SUCCESS;
157 
158 _ERR:
159     LinuxEmmcDeleteCntlr(cntlr);
160     HDF_LOGE("LinuxEmmcBind: Fail!");
161     return HDF_FAILURE;
162 }
163 
LinuxEmmcInit(struct HdfDeviceObject * obj)164 static int32_t LinuxEmmcInit(struct HdfDeviceObject *obj)
165 {
166     (void)obj;
167 
168     HDF_LOGD("LinuxEmmcInit: Success!");
169     return HDF_SUCCESS;
170 }
171 
LinuxEmmcRelease(struct HdfDeviceObject * obj)172 static void LinuxEmmcRelease(struct HdfDeviceObject *obj)
173 {
174     if (obj == NULL) {
175         return;
176     }
177     LinuxEmmcDeleteCntlr((struct MmcCntlr *)obj->service);
178 }
179 
180 struct HdfDriverEntry g_emmcDriverEntry = {
181     .moduleVersion = 1,
182     .Bind = LinuxEmmcBind,
183     .Init = LinuxEmmcInit,
184     .Release = LinuxEmmcRelease,
185     .moduleName = "HDF_PLATFORM_EMMC",
186 };
187 HDF_INIT(g_emmcDriverEntry);
188