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 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
10 #include "hcs_macro.h"
11 #include "hdf_config_macro.h"
12 #else
13 #include "device_resource_if.h"
14 #endif
15 #include "securec.h"
16 #include "mmc_block.h"
17 #include "mmc_dispatch.h"
18 #include "mmc_emmc.h"
19 #include "mmc_sdio.h"
20 
21 #define HDF_LOG_TAG mmc_core_c
22 
23 #define MMC_POWER_ON_DELAY_TIME 10 /* 10ms */
24 #define MMC_OCR_MAX_VOLTAGE_BIT 23
25 #define MMC_OCR_MAX_SHIFT_BITS  3
26 #define MMC_DETECET_RETRY 5
27 #define MMC_REQUEST_RETRY 3
28 #define MMC_MAX_SECTOR_NUM 2048
29 #define MMC_MAX_ERASE_SECTOR 0x100000 /* 512M */
30 #define SDIO_IRQ_TASK_STACK_SIZE 0x2000
31 
MmcCntlrDoRequest(struct MmcCntlr * cntlr,struct MmcCmd * cmd)32 int32_t MmcCntlrDoRequest(struct MmcCntlr *cntlr, struct MmcCmd *cmd)
33 {
34     if (cntlr == NULL) {
35         HDF_LOGE("MmcCntlrDoRequest: cntlr is null!");
36         return HDF_ERR_INVALID_OBJECT;
37     }
38     if (cmd == NULL) {
39         HDF_LOGE("MmcCntlrDoRequest: cmd is null!");
40         return HDF_ERR_INVALID_PARAM;
41     }
42     if (cntlr->ops == NULL || cntlr->ops->request == NULL) {
43         HDF_LOGE("MmcCntlrDoRequest: ops or request is null!");
44         return HDF_ERR_NOT_SUPPORT;
45     }
46     return cntlr->ops->request(cntlr, cmd);
47 }
48 
MmcCntlrExecRequest(struct MmcCntlr * cntlr,struct MmcCmd * cmd)49 static int32_t MmcCntlrExecRequest(struct MmcCntlr *cntlr, struct MmcCmd *cmd)
50 {
51     uint32_t i;
52     int32_t ret;
53 
54     for (i = 0; i < MMC_REQUEST_RETRY; i++) {
55         MmcCntlrLock(cntlr);
56         ret = MmcCntlrDoRequest(cntlr, cmd);
57         MmcCntlrUnlock(cntlr);
58         if (ret != HDF_SUCCESS) {
59             continue;
60         }
61         if (cmd->returnError != HDF_SUCCESS) {
62             continue;
63         }
64         if (cmd->data != NULL && cmd->data->returnError != HDF_SUCCESS) {
65             continue;
66         }
67         break;
68     }
69     return ret;
70 }
71 
MmcCntlrPlug(struct MmcCntlr * cntlr)72 static int32_t MmcCntlrPlug(struct MmcCntlr *cntlr)
73 {
74     uint32_t i;
75 
76     if (cntlr == NULL) {
77         HDF_LOGE("MmcCntlrPlug: cntlr is null!");
78         return HDF_ERR_INVALID_OBJECT;
79     }
80     if (MmcCntlrDevPlugged(cntlr) != true) {
81         HDF_LOGD("MmcCntlrPlug: dev is not plugged!");
82         return HDF_SUCCESS;
83     }
84 
85     /* dev not delete. */
86     if (cntlr->curDev != NULL) {
87         MmcCntlrLock(cntlr);
88         MmcDeleteDev(cntlr);
89         MmcCntlrUnlock(cntlr);
90     }
91 
92     if (cntlr->ops != NULL && cntlr->ops->systemInit != NULL) {
93         if (cntlr->ops->systemInit(cntlr) != HDF_SUCCESS) {
94             HDF_LOGE("MmcCntlrPlug: system init fail!");
95             return HDF_FAILURE;
96         }
97     }
98 
99     MmcCntlrLock(cntlr);
100     for (i = 0; i < MMC_DETECET_RETRY; i++) {
101         cntlr->detecting = true;
102         if (MmcDoDetect(cntlr) == HDF_SUCCESS) {
103             MmcDeviceAddOps(cntlr->curDev, NULL);
104             cntlr->detecting = false;
105             MmcCntlrUnlock(cntlr);
106             return HDF_SUCCESS;
107         }
108     }
109     cntlr->detecting = false;
110     MmcCntlrUnlock(cntlr);
111 
112     return HDF_FAILURE;
113 }
114 
MmcCntlrUnplug(struct MmcCntlr * cntlr)115 static int32_t MmcCntlrUnplug(struct MmcCntlr *cntlr)
116 {
117     if (cntlr == NULL) {
118         HDF_LOGE("MmcCntlrUnplug: cntlr is null!");
119         return HDF_ERR_INVALID_OBJECT;
120     }
121 
122     MmcCntlrLock(cntlr);
123     MmcDeleteDev(cntlr);
124     MmcCntlrUnlock(cntlr);
125     HDF_LOGD("MmcCntlrUnplug: host%d: a dev is removed!", cntlr->index);
126     return HDF_SUCCESS;
127 }
128 
MmcCntlrSdioRescanHandle(struct MmcCntlr * cntlr)129 static int32_t MmcCntlrSdioRescanHandle(struct MmcCntlr *cntlr)
130 {
131     uint8_t val;
132     int32_t error;
133 
134     if (cntlr == NULL) {
135         HDF_LOGE("MmcCntlrSdioRescanHandle: cntlr is null.");
136         return HDF_ERR_INVALID_OBJECT;
137     }
138 
139     if (cntlr->curDev != NULL && cntlr->curDev->state.bits.present > 0) {
140         if (cntlr->curDev->type == MMC_DEV_SDIO || cntlr->curDev->type == MMC_DEV_COMBO) {
141             error = SdioReadCccrIoEnable(cntlr, &val);
142             if (error != HDF_SUCCESS) {
143                 HDF_LOGD("re-detect sdio.");
144                 MmcCntlrPlug(cntlr);
145             } else {
146                 HDF_LOGD("sdio no need to rescan.");
147                 return HDF_SUCCESS;
148             }
149         } else {
150             HDF_LOGD("sd/emmc rescan does not support.");
151         }
152     } else {
153         HDF_LOGD("init detect fail, re-detect sdio.");
154         MmcCntlrPlug(cntlr);
155     }
156 
157     if (cntlr->curDev == NULL) {
158         HDF_LOGE("sdio rescan fail, please reset card!");
159         return HDF_ERR_DEVICE_BUSY;
160     }
161     return HDF_SUCCESS;
162 }
163 
MmcMsgHandleDefault(struct PlatformQueue * queue,struct PlatformMsg * msg)164 static int32_t MmcMsgHandleDefault(struct PlatformQueue *queue, struct PlatformMsg *msg)
165 {
166     int32_t ret;
167     struct MmcCntlr *cntlr = NULL;
168     struct MmcMsg *mmcMsg = NULL;
169 
170     if (queue == NULL || msg == NULL) {
171         HDF_LOGE("MmcMsgHandleDefault: msg or queue is null!");
172         return HDF_ERR_INVALID_OBJECT;
173     }
174 
175     cntlr = (struct MmcCntlr *)queue->data;
176     if (cntlr == NULL) {
177         HDF_LOGE("MmcMsgHandleDefault: cntlr is null!");
178         return HDF_ERR_INVALID_OBJECT;
179     }
180     mmcMsg = (struct MmcMsg *)msg;
181     switch (msg->code) {
182         case MMC_MSG_PLUG:
183             ret = MmcCntlrPlug(cntlr);
184             break;
185         case MMC_MSG_UNPLUG:
186             ret = MmcCntlrUnplug(cntlr);
187             break;
188         case MMC_MSG_REQUEST:
189             ret = MmcCntlrExecRequest(cntlr, mmcMsg->mmcCmd);
190             break;
191         case MMC_MSG_SDIO_RESCAN:
192             ret = MmcCntlrSdioRescanHandle(cntlr);
193             break;
194         default:
195             HDF_LOGE("MmcMsgHandleDefault: not support!");
196             ret = HDF_ERR_NOT_SUPPORT;
197             break;
198     }
199 
200     if (!mmcMsg->block) {
201         OsalMemFree(mmcMsg);
202     } else {
203         (void)OsalSemPost(&mmcMsg->sem);
204     }
205     return ret;
206 }
207 
MmcCntlrQueueCreate(struct MmcCntlr * cntlr,bool needQueue)208 static int32_t MmcCntlrQueueCreate(struct MmcCntlr *cntlr, bool needQueue)
209 {
210     int32_t ret;
211     const char *threadName = NULL;
212 
213     if (!needQueue) {
214         return HDF_SUCCESS;
215     }
216 
217     if (cntlr->devType == MMC_DEV_SDIO) {
218         threadName = "SdioWorkerThread";
219     } else if (cntlr->devType == MMC_DEV_SD) {
220         threadName = "SdWorkerThread";
221     } else if (cntlr->devType == MMC_DEV_EMMC) {
222         threadName = "EmmcWorkerThread";
223     }
224     cntlr->msgQueue = PlatformQueueCreate(MmcMsgHandleDefault, threadName, cntlr);
225     if (cntlr->msgQueue == NULL) {
226         HDF_LOGE("MmcCntlrQueueCreate: fail to create msg queue!");
227         return HDF_PLT_ERR_OS_API;
228     }
229     ret = PlatformQueueStart(cntlr->msgQueue);
230     if (ret != HDF_SUCCESS) {
231         HDF_LOGE("MmcCntlrQueueCreate: fail to start msg queue!");
232         PlatformQueueDestroy(cntlr->msgQueue);
233     }
234     return ret;
235 }
236 
MmcCntlrInit(struct MmcCntlr * cntlr,bool needQueue)237 static int32_t MmcCntlrInit(struct MmcCntlr *cntlr, bool needQueue)
238 {
239     int32_t ret;
240 
241     if (cntlr == NULL) {
242         HDF_LOGE("MmcCntlrInit: cntlr is null!");
243         return HDF_ERR_INVALID_OBJECT;
244     }
245 
246     if (cntlr->index >= MMC_CNTLR_NR_MAX) {
247         HDF_LOGE("MmcCntlrInit: invalid cntlr index:%u", cntlr->index);
248         return HDF_ERR_INVALID_PARAM;
249     }
250 
251     if (cntlr->hdfDevObj == NULL) {
252         HDF_LOGE("MmcCntlrInit: no HdfDeviceObject attached!");
253         return HDF_ERR_INVALID_OBJECT;
254     }
255 
256     ret = OsalMutexInit(&cntlr->mutex);
257     if (ret != HDF_SUCCESS) {
258         HDF_LOGE("MmcCntlrInit: mutex init fail!");
259         return ret;
260     }
261 
262     ret = MmcCntlrQueueCreate(cntlr, needQueue);
263     if (ret != HDF_SUCCESS) {
264         HDF_LOGE("MmcCntlrInit: queue create fail!");
265         return ret;
266     }
267 
268     cntlr->service.Dispatch = MmcIoDispatch;
269     cntlr->hdfDevObj->service = &(cntlr->service);
270     cntlr->device.number = cntlr->index;
271     cntlr->device.hdfDev = cntlr->hdfDevObj;
272     return HDF_SUCCESS;
273 }
274 
MmcCntlrUninit(struct MmcCntlr * cntlr)275 static void MmcCntlrUninit(struct MmcCntlr *cntlr)
276 {
277     if (cntlr != NULL) {
278         (void)OsalMutexDestroy(&cntlr->mutex);
279         PlatformQueueDestroy(cntlr->msgQueue);
280     }
281 }
282 
MmcCntlrAdd(struct MmcCntlr * cntlr,bool needQueue)283 int32_t MmcCntlrAdd(struct MmcCntlr *cntlr, bool needQueue)
284 {
285     int32_t ret;
286 
287     if (cntlr == NULL) {
288         HDF_LOGE("MmcCntlrAdd: cntlr is null!");
289         return HDF_ERR_INVALID_OBJECT;
290     }
291 
292     ret = MmcCntlrInit(cntlr, needQueue);
293     if (ret != HDF_SUCCESS) {
294         HDF_LOGE("MmcCntlrAdd: cntlr init fail, ret: %d!", ret);
295         return ret;
296     }
297 
298     cntlr->device.manager = PlatformManagerGet(PLATFORM_MODULE_MMC);
299     ret = PlatformDeviceAdd(&cntlr->device);
300     if (ret != HDF_SUCCESS) {
301         HDF_LOGE("MmcCntlrAdd: device add fail, ret: %d!", ret);
302         MmcCntlrUninit(cntlr);
303         return ret;
304     }
305     return HDF_SUCCESS;
306 }
307 
MmcCntlrRemove(struct MmcCntlr * cntlr)308 void MmcCntlrRemove(struct MmcCntlr *cntlr)
309 {
310     if (cntlr != NULL) {
311         MmcCntlrUninit(cntlr);
312         PlatformDeviceDel(&cntlr->device);
313     }
314 }
315 
MmcCntlrSetDevice(struct MmcCntlr * cntlr,struct MmcDevice * mmc)316 void MmcCntlrSetDevice(struct MmcCntlr *cntlr, struct MmcDevice *mmc)
317 {
318     if (cntlr == NULL || mmc == NULL) {
319         HDF_LOGE("MmcCntlrSetDevice: cntlr or mmc is null!");
320         return;
321     }
322     cntlr->curDev = mmc;
323 }
324 
MmcCntlrGetDevice(struct MmcCntlr * cntlr)325 struct MmcDevice *MmcCntlrGetDevice(struct MmcCntlr *cntlr)
326 {
327     struct MmcDevice *mmc = NULL;
328 
329     if (cntlr != NULL) {
330         mmc = cntlr->curDev;
331     }
332     return MmcDeviceGet(mmc);
333 }
334 
MmcCntlrPostMsg(struct MmcCntlr * cntlr,struct MmcMsg * mmcMsg)335 static int32_t MmcCntlrPostMsg(struct MmcCntlr *cntlr, struct MmcMsg *mmcMsg)
336 {
337     int32_t ret;
338 
339     if (cntlr == NULL) {
340         HDF_LOGE("MmcCntlrPostMsg: cntlr is null!");
341         return HDF_ERR_INVALID_OBJECT;
342     }
343     if (mmcMsg == NULL) {
344         HDF_LOGE("MmcCntlrPostMsg: mmcMsg is null!");
345         return HDF_ERR_INVALID_PARAM;
346     }
347 
348     if (mmcMsg->block) {
349         (void)OsalSemInit(&mmcMsg->sem, 0);
350     }
351     (void)PlatformQueueAddMsg(cntlr->msgQueue, &mmcMsg->msg);
352     if (!mmcMsg->block) {
353         return HDF_SUCCESS;
354     }
355 
356     ret = OsalSemWait(&mmcMsg->sem, HDF_WAIT_FOREVER);
357     (void)OsalSemDestroy(&mmcMsg->sem);
358     OsalMemFree(mmcMsg);
359     if (ret != HDF_SUCCESS) {
360         HDF_LOGE("MmcCntlrPostMsg: wait msg fail, ret: %d!", ret);
361     }
362     return ret;
363 }
364 
MmcCntlrSetClock(struct MmcCntlr * cntlr,uint32_t clock)365 void MmcCntlrSetClock(struct MmcCntlr *cntlr, uint32_t clock)
366 {
367     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->setClock == NULL) {
368         HDF_LOGE("MmcCntlrSetClock: cntlr or ops or setClock is null!");
369         return;
370     }
371     cntlr->curDev->workPara.clock = clock;
372     cntlr->ops->setClock(cntlr, clock);
373 }
374 
MmcCntlrSetBusWidth(struct MmcCntlr * cntlr,enum MmcBusWidth width)375 void MmcCntlrSetBusWidth(struct MmcCntlr *cntlr, enum MmcBusWidth width)
376 {
377     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->setBusWidth == NULL) {
378         HDF_LOGE("MmcCntlrSetBusWidth: cntlr or ops or setBusWidth is null!");
379         return;
380     }
381     cntlr->curDev->workPara.width = width;
382     cntlr->ops->setBusWidth(cntlr, width);
383 }
384 
MmcCntlrSetBusTiming(struct MmcCntlr * cntlr,enum MmcBusTiming timing)385 void MmcCntlrSetBusTiming(struct MmcCntlr *cntlr, enum MmcBusTiming timing)
386 {
387     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->setBusTiming == NULL) {
388         HDF_LOGE("MmcCntlrSetBusTiming: cntlr or ops or setBusTiming is null!");
389         return;
390     }
391     cntlr->curDev->workPara.timing = timing;
392     cntlr->ops->setBusTiming(cntlr, timing);
393 }
394 
MmcCntlrSetEnhanceStrobe(struct MmcCntlr * cntlr,bool enable)395 void MmcCntlrSetEnhanceStrobe(struct MmcCntlr *cntlr, bool enable)
396 {
397     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->setEnhanceStrobe == NULL) {
398         HDF_LOGE("MmcCntlrSetEnhanceStrobe: cntlr or ops or setEnhanceStrobe is null!");
399         return;
400     }
401     cntlr->ops->setEnhanceStrobe(cntlr, enable);
402 }
403 
MmcCntlrSwitchVoltage(struct MmcCntlr * cntlr,enum MmcVolt voltage)404 int32_t MmcCntlrSwitchVoltage(struct MmcCntlr *cntlr, enum MmcVolt voltage)
405 {
406     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->switchVoltage == NULL) {
407         HDF_LOGE("MmcCntlrSwitchVoltage: cntlr or ops or switchVoltage is null!");
408         return HDF_ERR_INVALID_PARAM;
409     }
410     return cntlr->ops->switchVoltage(cntlr, voltage);
411 }
412 
MmcCntlrDevReadOnly(struct MmcCntlr * cntlr)413 bool MmcCntlrDevReadOnly(struct MmcCntlr *cntlr)
414 {
415     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->devReadOnly == NULL) {
416         HDF_LOGE("MmcCntlrDevReadOnly: cntlr or ops or devReadOnly is null!");
417         return false;
418     }
419     return cntlr->ops->devReadOnly(cntlr);
420 }
421 
MmcCntlrDevPlugged(struct MmcCntlr * cntlr)422 bool MmcCntlrDevPlugged(struct MmcCntlr *cntlr)
423 {
424     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->devPlugged == NULL) {
425         HDF_LOGE("MmcCntlrDevPlugged: cntlr or ops or devPlugged is null!");
426         return false;
427     }
428 
429     if (cntlr->caps.bits.nonremovable > 0) {
430         return true;
431     }
432     return cntlr->ops->devPlugged(cntlr);
433 }
434 
MmcCntlrDevBusy(struct MmcCntlr * cntlr)435 bool MmcCntlrDevBusy(struct MmcCntlr *cntlr)
436 {
437     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->devBusy == NULL) {
438         HDF_LOGE("MmcCntlrDevBusy: cntlr or ops or devBusy is null!");
439         return true;
440     }
441 
442     return cntlr->ops->devBusy(cntlr);
443 }
444 
MmcCntlrTune(struct MmcCntlr * cntlr,uint32_t cmdCode)445 int32_t MmcCntlrTune(struct MmcCntlr *cntlr, uint32_t cmdCode)
446 {
447     if (cntlr == NULL || cntlr->ops == NULL || cntlr->ops->tune == NULL) {
448         HDF_LOGE("MmcCntlrTune: cntlr or ops or tune is null!");
449         return HDF_ERR_INVALID_PARAM;
450     }
451     return cntlr->ops->tune(cntlr, cmdCode);
452 }
453 
MmcCntlrSelectWorkVoltage(struct MmcCntlr * cntlr,union MmcOcr * ocr)454 void MmcCntlrSelectWorkVoltage(struct MmcCntlr *cntlr, union MmcOcr *ocr)
455 {
456     uint32_t tmpOcr;
457     uint32_t i;
458 
459     /* ignore reveserd. */
460     if ((ocr->ocrData & 0x7F) > 0) {
461         ocr->ocrData &= (~0x7F);
462     }
463     /* use low voltage shuould both host and dev support. */
464     if (cntlr->ocrDef.bits.vdd1v65To1v95 == 0) {
465         ocr->bits.vdd1v65To1v95 = 0;
466     }
467 
468     /*
469      * Based on the voltage range supported by the host and the voltage range read from the OCR register,
470      * obtain the voltage range supported by both the host and the OCR register,
471      * and then select the minimum voltage value.
472      */
473     tmpOcr = ((ocr->ocrData) & (cntlr->ocrDef.ocrData));
474     for (i = 0; i <= MMC_OCR_MAX_VOLTAGE_BIT; i++) {
475         if ((tmpOcr & (1 << i)) > 0) {
476             break;
477         }
478     }
479 
480     if (i > 0 && i <= MMC_OCR_MAX_VOLTAGE_BIT) {
481         tmpOcr &= (MMC_OCR_MAX_SHIFT_BITS << i);
482         cntlr->vddBit = i;
483     } else {
484         tmpOcr = 0;
485     }
486     cntlr->curDev->reg.ocr.ocrData = tmpOcr;
487 }
488 
MmcCntlrPowerUp(struct MmcCntlr * cntlr)489 void MmcCntlrPowerUp(struct MmcCntlr *cntlr)
490 {
491     if (cntlr == NULL || cntlr->ops == NULL) {
492         HDF_LOGE("MmcCntlrPowerUp: cntlr or ops is null!");
493         return;
494     }
495 
496     if (cntlr->ops->setEnhanceStrobe != NULL) {
497         cntlr->ops->setEnhanceStrobe(cntlr, false);
498     }
499     /* disable clock. */
500     if (cntlr->ops->setClock != NULL) {
501         cntlr->ops->setClock(cntlr, 0);
502     }
503     /* power up. */
504     if (cntlr->ops->setPowerMode != NULL) {
505         cntlr->ops->setPowerMode(cntlr, MMC_POWER_MODE_POWER_UP);
506     }
507     if (cntlr->ops->setBusWidth != NULL) {
508         cntlr->ops->setBusWidth(cntlr, BUS_WIDTH1);
509     }
510     if (cntlr->ops->setBusTiming != NULL) {
511         cntlr->ops->setBusTiming(cntlr, BUS_TIMING_MMC_DS);
512     }
513     MmcMDelay(MMC_POWER_ON_DELAY_TIME);
514 
515     /* enable clock. */
516     if (cntlr->ops->setClock != NULL) {
517         cntlr->ops->setClock(cntlr, cntlr->freqDef);
518     }
519     /* power on. */
520     if (cntlr->ops->setPowerMode != NULL) {
521         cntlr->ops->setPowerMode(cntlr, MMC_POWER_MODE_POWER_ON);
522     }
523     MmcMDelay(MMC_POWER_ON_DELAY_TIME);
524 
525     if (cntlr->ops->hardwareReset != NULL && cntlr->caps.bits.hardwareReset > 0) {
526         cntlr->ops->hardwareReset(cntlr);
527     }
528     /* init voltage 3.3v. */
529     if (cntlr->ops->switchVoltage != NULL) {
530         cntlr->ops->switchVoltage(cntlr, cntlr->voltDef);
531     }
532 }
533 
MmcCntlrPowerOff(struct MmcCntlr * cntlr)534 void MmcCntlrPowerOff(struct MmcCntlr *cntlr)
535 {
536     if (cntlr == NULL || cntlr->ops == NULL) {
537         HDF_LOGE("MmcCntlrPowerOff: cntlr or ops is null!");
538         return;
539     }
540 
541     /* disable clock. */
542     if (cntlr->ops->setClock != NULL) {
543         cntlr->ops->setClock(cntlr, 0);
544     }
545     /* power up. */
546     if (cntlr->ops->setPowerMode != NULL) {
547         cntlr->ops->setPowerMode(cntlr, MMC_POWER_MODE_POWER_OFF);
548     }
549     if (cntlr->ops->setBusWidth != NULL) {
550         cntlr->ops->setBusWidth(cntlr, BUS_WIDTH1);
551     }
552 }
553 
MmcCntlrAllocDev(struct MmcCntlr * cntlr,enum MmcDevType devType)554 int32_t MmcCntlrAllocDev(struct MmcCntlr *cntlr, enum MmcDevType devType)
555 {
556     uint32_t len = 0;
557     struct MmcDevice *mmc = NULL;
558 
559     if (cntlr == NULL) {
560         HDF_LOGE("MmcCntlrAllocDev: cntlr is null!");
561         return HDF_ERR_INVALID_PARAM;
562     }
563 
564     if (devType == MMC_DEV_SDIO || devType == MMC_DEV_COMBO) {
565         len = (uint32_t)sizeof(struct SdioDevice);
566     } else if (devType == MMC_DEV_SD) {
567         len = (uint32_t)sizeof(struct SdDevice);
568     } else if (devType == MMC_DEV_EMMC) {
569         len = (uint32_t)sizeof(struct EmmcDevice);
570     }
571 
572     if (len == 0) {
573         HDF_LOGE("MmcCntlrAllocDev: len is 0, type = %d!", (uint32_t)devType);
574         return HDF_ERR_INVALID_PARAM;
575     }
576 
577     mmc = (struct MmcDevice *)OsalMemCalloc(len);
578     if (mmc == NULL) {
579         HDF_LOGE("MmcCntlrAllocDev: OsalMemCalloc fail!");
580         return HDF_ERR_MALLOC_FAIL;
581     }
582     mmc->type = devType;
583     mmc->cntlr = cntlr;
584     MmcCntlrSetDevice(cntlr, mmc);
585     return 0;
586 }
587 
MmcCntlrFreeDev(struct MmcCntlr * cntlr)588 void MmcCntlrFreeDev(struct MmcCntlr *cntlr)
589 {
590     if (cntlr == NULL || cntlr->curDev == NULL) {
591         HDF_LOGE("MmcCntlrFreeDev: cntlr or curDev is null!");
592         return;
593     }
594 
595     OsalMemFree(cntlr->curDev);
596     cntlr->curDev = NULL;
597 }
598 
MmcCntlrSupportUhs(struct MmcCntlr * cntlr)599 bool MmcCntlrSupportUhs(struct MmcCntlr *cntlr)
600 {
601     if (cntlr == NULL) {
602         HDF_LOGE("MmcCntlrSupportUhs: cntlr is null!");
603         return false;
604     }
605 
606     if (cntlr->caps.bits.uhsSdr12 > 0 ||
607         cntlr->caps.bits.uhsSdr25 > 0 ||
608         cntlr->caps.bits.uhsSdr50 > 0 ||
609         cntlr->caps.bits.uhsSdr104 > 0 ||
610         cntlr->caps.bits.uhsDdr50 > 0) {
611         return true;
612     }
613     return false;
614 }
615 
MmcCntlrSupportHighSpeed400EnhancedStrobe(struct MmcCntlr * cntlr)616 bool MmcCntlrSupportHighSpeed400EnhancedStrobe(struct MmcCntlr *cntlr)
617 {
618     if (cntlr == NULL) {
619         HDF_LOGE("MmcCntlrSupportHighSpeed400EnhancedStrobe: cntlr is null!");
620         return false;
621     }
622 
623     if (cntlr->caps2.bits.hs400EnhancedStrobe > 0 &&
624         cntlr->caps.bits.cap8Bit > 0 &&
625         cntlr->caps2.bits.hs400Support1v2 > 0 &&
626         cntlr->caps2.bits.hs400Support1v8 > 0) {
627         return true;
628     }
629     return false;
630 }
631 
MmcCntlrSupportHighSpeed400(struct MmcCntlr * cntlr)632 bool MmcCntlrSupportHighSpeed400(struct MmcCntlr *cntlr)
633 {
634     if (cntlr == NULL) {
635         HDF_LOGE("MmcCntlrSupportHighSpeed400: cntlr is null!");
636         return false;
637     }
638 
639     if (cntlr->caps.bits.cap8Bit > 0 &&
640         cntlr->caps2.bits.hs400Support1v2 > 0 &&
641         cntlr->caps2.bits.hs400Support1v8 > 0) {
642         return true;
643     }
644     return false;
645 }
646 
MmcCntlrSupportHighSpeed200(struct MmcCntlr * cntlr)647 bool MmcCntlrSupportHighSpeed200(struct MmcCntlr *cntlr)
648 {
649     if (cntlr == NULL) {
650         HDF_LOGE("MmcCntlrSupportHighSpeed200: cntlr is null!");
651         return false;
652     }
653 
654     if (cntlr->caps2.bits.hs200Sdr1v8 > 0 ||
655         cntlr->caps2.bits.hs200Sdr1v2 > 0) {
656         return true;
657     }
658     return false;
659 }
660 
MmcCntlrSdSupportCmd23(struct MmcCntlr * cntlr)661 bool MmcCntlrSdSupportCmd23(struct MmcCntlr *cntlr)
662 {
663     struct SdDevice *dev = NULL;
664 
665     if (cntlr == NULL || cntlr->curDev == NULL) {
666         HDF_LOGE("MmcCntlrSdSupportCmd23: cntlr or curDev is null!");
667         return false;
668     }
669     if (cntlr->curDev->type != MMC_DEV_SD && cntlr->curDev->type != MMC_DEV_COMBO) {
670         return false;
671     }
672 
673     dev = (struct SdDevice *)cntlr->curDev;
674     if ((dev->reg.scr.cmdSupport & SD_SCR_SET_BLOCK_COUNT_SUPPORT) > 0) {
675         return true;
676     }
677     return false;
678 }
679 
MmcCntlrEmmcSupportCmd23(struct MmcCntlr * cntlr)680 bool MmcCntlrEmmcSupportCmd23(struct MmcCntlr *cntlr)
681 {
682     struct EmmcDevice *dev = NULL;
683 
684     if (cntlr == NULL || cntlr->curDev == NULL) {
685         HDF_LOGE("MmcCntlrEmmcSupportCmd23: cntlr or curDev is null!");
686         return false;
687     }
688     if (cntlr->curDev->type != MMC_DEV_EMMC) {
689         return false;
690     }
691 
692     dev = (struct EmmcDevice *)cntlr->curDev;
693     if ((dev->mmc.reg.csd.ccc & MMC_CSD_CCC_BLOCK_READ) > 0 ||
694         (dev->mmc.reg.csd.ccc & MMC_CSD_CCC_BLOCK_WRITE) > 0) {
695         return true;
696     }
697     return false;
698 }
699 
MmcCntlrAddMsgToQueue(struct MmcCntlr * cntlr,struct MmcCmd * cmd,int32_t code,bool block)700 int32_t MmcCntlrAddMsgToQueue(struct MmcCntlr *cntlr, struct MmcCmd *cmd,
701     int32_t code, bool block)
702 {
703     struct MmcMsg *msg = NULL;
704 
705     if (cntlr == NULL) {
706         HDF_LOGE("MmcCntlrAddMsgToQueue: cntlr is null!");
707         return HDF_ERR_INVALID_OBJECT;
708     }
709 
710     msg = (struct MmcMsg *)OsalMemCalloc(sizeof(struct MmcMsg));
711     if (msg == NULL) {
712         HDF_LOGE("MmcCntlrAddMsgToQueue: OsalMemCalloc fail!n");
713         return HDF_ERR_MALLOC_FAIL;
714     }
715     msg->msg.code = code;
716     msg->msg.data = (void *)cntlr;
717     msg->block = block;
718     msg->mmcCmd = cmd;
719     return MmcCntlrPostMsg(cntlr, msg);
720 }
721 
MmcCntlrAddRequestMsgToQueue(struct MmcCntlr * cntlr,struct MmcCmd * cmd)722 int32_t MmcCntlrAddRequestMsgToQueue(struct MmcCntlr *cntlr, struct MmcCmd *cmd)
723 {
724     if (cntlr == NULL) {
725         HDF_LOGE("MmcCntlrAddRequestMsgToQueue: cntlr is null!");
726         return HDF_ERR_INVALID_OBJECT;
727     }
728     if (cntlr->ops == NULL || cntlr->ops->devPlugged == NULL) {
729         HDF_LOGE("MmcCntlrAddRequestMsgToQueue: ops or devPlugged is null!");
730         return HDF_PLT_ERR_NO_DEV;
731     }
732     if (cntlr->ops->devPlugged(cntlr) == false) {
733         HDF_LOGE("MmcCntlrAddRequestMsgToQueue: host%d dev is unplug!", cntlr->index);
734         return HDF_PLT_ERR_NO_DEV;
735     }
736 
737     return MmcCntlrAddMsgToQueue(cntlr, cmd, MMC_MSG_REQUEST, true);
738 }
739 
MmcCntlrAddDetectMsgToQueue(struct MmcCntlr * cntlr)740 int32_t MmcCntlrAddDetectMsgToQueue(struct MmcCntlr *cntlr)
741 {
742     if (cntlr == NULL) {
743         HDF_LOGE("MmcCntlrAddDetectMsgToQueue: cntlr is null!");
744         return HDF_ERR_INVALID_OBJECT;
745     }
746     if (cntlr->ops == NULL || cntlr->ops->devPlugged == NULL) {
747         HDF_LOGE("MmcCntlrAddDetectMsgToQueue: ops or devPlugged is null!");
748         return HDF_PLT_ERR_NO_DEV;
749     }
750 
751     if (cntlr->ops->devPlugged(cntlr) == false) {
752         HDF_LOGD("MmcCntlrAddDetectMsgToQueue: host%d dev is not plugged!", cntlr->index);
753         return HDF_PLT_ERR_NO_DEV;
754     }
755     cntlr->devPlugged = true;
756     return MmcCntlrAddMsgToQueue(cntlr, NULL, MMC_MSG_PLUG, false);
757 }
758 
MmcCntlrAddPlugMsgToQueue(struct MmcCntlr * cntlr)759 int32_t MmcCntlrAddPlugMsgToQueue(struct MmcCntlr *cntlr)
760 {
761     bool curStatus = false;
762     int32_t code;
763 
764     if (cntlr == NULL) {
765         HDF_LOGE("MmcCntlrAddPlugMsgToQueue: cntlr is null!");
766         return HDF_ERR_INVALID_OBJECT;
767     }
768     if (cntlr->ops == NULL || cntlr->ops->devPlugged == NULL) {
769         HDF_LOGE("MmcCntlrAddPlugMsgToQueue: ops or devPlugged is null!");
770         return HDF_PLT_ERR_NO_DEV;
771     }
772 
773     curStatus = cntlr->ops->devPlugged(cntlr);
774     if (curStatus == cntlr->devPlugged) {
775         HDF_LOGD("MmcCntlrAddPlugMsgToQueue: dev plug srtatus not change.");
776         return HDF_SUCCESS;
777     }
778 
779     if (curStatus == true) {
780         cntlr->devPlugged = true;
781         code = MMC_MSG_PLUG;
782         HDF_LOGD("host%d: a dev is plugged!", cntlr->index);
783     } else {
784         cntlr->devPlugged = false;
785         code = MMC_MSG_UNPLUG;
786         HDF_LOGD("host%d: a dev is unplugged!", cntlr->index);
787     }
788     return MmcCntlrAddMsgToQueue(cntlr, NULL, code, false);
789 }
790 
MmcCntlrAddSdioRescanMsgToQueue(struct MmcCntlr * cntlr)791 int32_t MmcCntlrAddSdioRescanMsgToQueue(struct MmcCntlr *cntlr)
792 {
793     if (cntlr == NULL) {
794         HDF_LOGE("MmcCntlrAddSdioRescanMsgToQueue: cntlr is null!");
795         return HDF_ERR_INVALID_OBJECT;
796     }
797     if (cntlr->devType != MMC_DEV_SDIO) {
798         HDF_LOGD("MmcCntlrAddSdioRescanMsgToQueue: not sdio card, do not handle rescan!");
799         return HDF_FAILURE;
800     }
801 
802     return MmcCntlrAddMsgToQueue(cntlr, NULL, MMC_MSG_SDIO_RESCAN, true);
803 }
804 
SdioHandlePendingIrq(struct MmcCntlr * cntlr,struct SdioDevice * dev)805 static void SdioHandlePendingIrq(struct MmcCntlr *cntlr, struct SdioDevice *dev)
806 {
807     uint8_t val;
808     int32_t ret;
809     uint32_t i;
810     struct SdioFunction *func = dev->curFunction;
811 
812     if (func == NULL) {
813         HDF_LOGE("MmcCntlrHandleSdioPendingIrq: cur func is null!");
814         return;
815     }
816     if (dev->irqPending == true && func->irqHandler != NULL) {
817         func->irqHandler(func);
818         return;
819     }
820 
821     ret = SdioReadCccrIntPending(cntlr, &val);
822     if (ret != HDF_SUCCESS) {
823         HDF_LOGE("MmcCntlrHandleSdioPendingIrq: read cccr int pending fail! ret = %d.", ret);
824         return;
825     }
826 
827     for (i = 0; i < SDIO_MAX_FUNCTION_NUMBER; i++) {
828         if ((val & (1 << (i + 1))) == 0) {
829             continue;
830         }
831         func = dev->sdioFunc[i];
832         if (func == NULL) {
833             HDF_LOGD("MmcCntlrHandleSdioPendingIrq: function%d not exist.", i + 1);
834             continue;
835         }
836         if (func->irqHandler == NULL) {
837             HDF_LOGD("MmcCntlrHandleSdioPendingIrq: function%d irq handler not exist.", i + 1);
838             continue;
839         }
840         func->irqHandler(func);
841     }
842 }
843 
SdioIrqThreadWorker(void * data)844 static int32_t SdioIrqThreadWorker(void *data)
845 {
846     int32_t ret;
847     struct SdioDevice *dev = (struct SdioDevice *)data;
848     struct MmcCntlr *cntlr = NULL;
849 
850     if (dev == NULL) {
851         HDF_LOGE("SdioIrqThreadWorker: data is null!");
852         return HDF_FAILURE;
853     }
854 
855     cntlr = dev->sd.mmc.cntlr;
856     if (cntlr == NULL) {
857         HDF_LOGE("SdioIrqThreadWorker: cntlr is null!");
858         return HDF_ERR_INVALID_OBJECT;
859     }
860 
861     while (true) {
862         /* wait envent */
863         ret = OsalSemWait(&dev->sem, HDF_WAIT_FOREVER);
864         if (ret != HDF_SUCCESS) {
865             continue;
866         }
867         SdioHandlePendingIrq(cntlr, dev);
868         dev->irqPending = false;
869         if (cntlr->caps.bits.sdioIrq > 0 && cntlr->ops != NULL && cntlr->ops->setSdioIrq != NULL) {
870             (void)cntlr->ops->setSdioIrq(cntlr, true);
871         }
872     }
873 
874     return HDF_SUCCESS;
875 }
876 
MmcCntlrCreatSdioIrqThread(struct MmcCntlr * cntlr)877 int32_t MmcCntlrCreatSdioIrqThread(struct MmcCntlr *cntlr)
878 {
879     int32_t ret;
880     struct OsalThreadParam config = {0};
881     struct SdioDevice *dev = NULL;
882 
883     if (cntlr == NULL || cntlr->curDev == NULL) {
884         HDF_LOGE("MmcCntlrCreatSdioIrqThread: cntlr or curDev is null!");
885         return HDF_ERR_INVALID_OBJECT;
886     }
887 
888     dev = (struct SdioDevice *)cntlr->curDev;
889     ret = OsalSemInit(&dev->sem, 0);
890     if (ret != HDF_SUCCESS) {
891         HDF_LOGE("MmcCntlrCreatSdioIrqThread: sem init fail, ret: %d!", ret);
892         return ret;
893     }
894 
895     ret = OsalThreadCreate(&dev->thread, (OsalThreadEntry)SdioIrqThreadWorker, dev);
896     if (ret != HDF_SUCCESS) {
897         HDF_LOGE("MmcCntlrCreatSdioIrqThread: thread create fail, ret: %d!", ret);
898         (void)OsalSemDestroy(&dev->sem);
899         return ret;
900     }
901 
902     if (memset_s(&config, sizeof(config), 0, sizeof(config)) != EOK) {
903         HDF_LOGE("MmcCntlrCreatSdioIrqThread: memset_s fail!");
904         OsalThreadDestroy(&dev->thread);
905         (void)OsalSemDestroy(&dev->sem);
906         return HDF_ERR_IO;
907     }
908     config.name = "SdioIrqTask";
909     config.priority = OSAL_THREAD_PRI_HIGHEST;
910     config.stackSize = SDIO_IRQ_TASK_STACK_SIZE;
911     ret = OsalThreadStart(&dev->thread, &config);
912     if (ret != HDF_SUCCESS) {
913         HDF_LOGE("MmcCntlrCreatSdioIrqThread: thread start fail.");
914         OsalThreadDestroy(&dev->thread);
915         (void)OsalSemDestroy(&dev->sem);
916         return ret;
917     }
918     dev->threadRunning = true;
919     if (cntlr->caps.bits.sdioIrq > 0 && cntlr->ops != NULL && cntlr->ops->setSdioIrq != NULL) {
920         (void)cntlr->ops->setSdioIrq(cntlr, true);
921     }
922     return HDF_SUCCESS;
923 }
924 
MmcCntlrDestroySdioIrqThread(struct MmcCntlr * cntlr)925 void MmcCntlrDestroySdioIrqThread(struct MmcCntlr *cntlr)
926 {
927     struct SdioDevice *dev = NULL;
928 
929     if (cntlr == NULL || cntlr->curDev == NULL) {
930         HDF_LOGE("MmcCntlrDestroySdioIrqThread: cntlr or curDev is null!");
931         return;
932     }
933 
934     dev = (struct SdioDevice *)cntlr->curDev;
935     (void)OsalThreadDestroy(&dev->thread);
936     (void)OsalSemDestroy(&dev->sem);
937     dev->threadRunning = true;
938 }
939 
MmcCntlrNotifySdioIrqThread(struct MmcCntlr * cntlr)940 void MmcCntlrNotifySdioIrqThread(struct MmcCntlr *cntlr)
941 {
942     struct SdioDevice *dev = NULL;
943 
944     if (cntlr == NULL || cntlr->curDev == NULL) {
945         HDF_LOGD("MmcCntlrNotifySdioIrqThread: cntlr or curDev is null!");
946         return;
947     }
948     if (cntlr->curDev->type != MMC_DEV_SDIO && cntlr->curDev->type != MMC_DEV_COMBO) {
949         return;
950     }
951     dev = (struct SdioDevice *)cntlr->curDev;
952     if (dev->threadRunning == true) {
953         dev->irqPending = true;
954         /* notify the worker thread */
955         (void)OsalSemPost(&dev->sem);
956     }
957 }
958 
959 #ifdef LOSCFG_DRIVERS_HDF_CONFIG_MACRO
960 #define MMC_PARSE_DEVICE_INFO(node, cntlr) \
961     do { \
962         cntlr->index = HCS_PROP(node, hostId); \
963         cntlr->devType = HCS_PROP(node, devType); \
964     } while (0)
965 
966 #define MMC_PARSE_CNTLR_FREQ_INFO(node, cntlr) \
967     do { \
968         cntlr->freqMin = HCS_PROP(node, freqMin); \
969         cntlr->freqMax = HCS_PROP(node, freqMax); \
970         cntlr->freqDef = HCS_PROP(node, freqDef); \
971     } while (0)
972 
973 #define MMC_PARSE_CNTLR_CAPS_INFO(node, cntlr) \
974     do { \
975         cntlr->voltDef = HCS_PROP(node, voltDef); \
976         cntlr->ocrDef.ocrData = HCS_PROP(node, ocrDef); \
977         cntlr->caps.capsData = HCS_PROP(node, caps); \
978         cntlr->caps2.caps2Data = HCS_PROP(node, caps2); \
979         cntlr->maxBlkNum = HCS_PROP(node, maxBlkNum); \
980         cntlr->maxBlkSize = HCS_PROP(node, maxBlkSize); \
981         cntlr->maxReqSize = cntlr->maxBlkNum * cntlr->maxBlkSize; \
982     } while (0)
983 
984 #define MMC_FIND_CONFIG(node, name, cntlr) \
985     do { \
986         if (strcmp(HCS_PROP(node, match_attr), name) == 0) { \
987             MMC_PARSE_DEVICE_INFO(node, cntlr); \
988             MMC_PARSE_CNTLR_FREQ_INFO(node, cntlr); \
989             MMC_PARSE_CNTLR_CAPS_INFO(node, cntlr); \
990             break; \
991         } \
992     } while (0)
993 
994 #define PLATFORM_CONFIG HCS_NODE(HCS_ROOT, platform)
995 #define MMC_CNTLR_PARSE_CONFIG HCS_NODE(HCS_NODE(HCS_ROOT, platform), mmc_config)
996 
MmcCntlrParse(struct MmcCntlr * cntlr,struct HdfDeviceObject * obj)997 int32_t MmcCntlrParse(struct MmcCntlr *cntlr, struct HdfDeviceObject *obj)
998 {
999     if (cntlr == NULL || obj == NULL) {
1000         HDF_LOGE("MmcCntlrParse: input param is null!");
1001         return HDF_FAILURE;
1002     }
1003 
1004     /* parse hcs config. */
1005 #if HCS_NODE_HAS_PROP(PLATFORM_CONFIG, mmc_config)
1006     HCS_FOREACH_CHILD_VARGS(MMC_CNTLR_PARSE_CONFIG, MMC_FIND_CONFIG, obj->deviceMatchAttr, cntlr);
1007 #endif
1008 
1009     return HDF_SUCCESS;
1010 }
1011 #else
MmcCntlrParseCapability(const struct DeviceResourceNode * node,struct DeviceResourceIface * drsOps,struct MmcCntlr * cntlr)1012 static void MmcCntlrParseCapability(const struct DeviceResourceNode *node,
1013     struct DeviceResourceIface *drsOps, struct MmcCntlr *cntlr)
1014 {
1015     int32_t ret;
1016 
1017     ret = drsOps->GetUint16(node, "voltDef", &(cntlr->voltDef), 0);
1018     if (ret != HDF_SUCCESS) {
1019         cntlr->voltDef = 0;
1020     }
1021     ret = drsOps->GetUint32(node, "freqMin", &(cntlr->freqMin), 0);
1022     if (ret != HDF_SUCCESS) {
1023         cntlr->freqMin = 0;
1024     }
1025     ret = drsOps->GetUint32(node, "freqMax", &(cntlr->freqMax), 0);
1026     if (ret != HDF_SUCCESS) {
1027         cntlr->freqMax = 0;
1028     }
1029     ret = drsOps->GetUint32(node, "freqDef", &(cntlr->freqDef), 0);
1030     if (ret != HDF_SUCCESS) {
1031         cntlr->freqDef = 0;
1032     }
1033     ret = drsOps->GetUint32(node, "ocrDef", &(cntlr->ocrDef.ocrData), 0);
1034     if (ret != HDF_SUCCESS) {
1035         cntlr->ocrDef.ocrData = 0;
1036     }
1037 
1038     ret = drsOps->GetUint32(node, "caps", &(cntlr->caps.capsData), 0);
1039     if (ret != HDF_SUCCESS) {
1040         cntlr->caps.capsData = 0;
1041     }
1042     ret = drsOps->GetUint32(node, "caps2", &(cntlr->caps2.caps2Data), 0);
1043     if (ret != HDF_SUCCESS) {
1044         cntlr->caps2.caps2Data = 0;
1045     }
1046 
1047     ret = drsOps->GetUint32(node, "maxBlkNum", &(cntlr->maxBlkNum), 0);
1048     if (ret != HDF_SUCCESS) {
1049         cntlr->maxBlkNum = 0;
1050     }
1051     ret = drsOps->GetUint32(node, "maxBlkSize", &(cntlr->maxBlkSize), 0);
1052     if (ret != HDF_SUCCESS) {
1053         cntlr->maxBlkSize = 0;
1054     }
1055     cntlr->maxReqSize = cntlr->maxBlkNum * cntlr->maxBlkSize;
1056 }
1057 
MmcCntlrParse(struct MmcCntlr * cntlr,struct HdfDeviceObject * obj)1058 int32_t MmcCntlrParse(struct MmcCntlr *cntlr, struct HdfDeviceObject *obj)
1059 {
1060     const struct DeviceResourceNode *node = NULL;
1061     struct DeviceResourceIface *drsOps = NULL;
1062     int32_t ret;
1063 
1064     if (obj == NULL || cntlr == NULL) {
1065         HDF_LOGE("MmcCntlrParse: input param is null!");
1066         return HDF_FAILURE;
1067     }
1068 
1069     node = obj->property;
1070     if (node == NULL) {
1071         HDF_LOGE("MmcCntlrParse: drs node is null!");
1072         return HDF_FAILURE;
1073     }
1074     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
1075     if (drsOps == NULL || drsOps->GetUint16 == NULL || drsOps->GetUint32 == NULL) {
1076         HDF_LOGE("MmcCntlrParse: invalid drs ops fail!");
1077         return HDF_FAILURE;
1078     }
1079 
1080     ret = drsOps->GetUint16(node, "hostId", &(cntlr->index), 0);
1081     if (ret != HDF_SUCCESS) {
1082         HDF_LOGE("MmcCntlrParse: read hostId fail, ret: %d", ret);
1083         return ret;
1084     }
1085     HDF_LOGD("MmcCntlrParse: hostId = %d", cntlr->index);
1086 
1087     ret = drsOps->GetUint32(node, "devType", &(cntlr->devType), 0);
1088     if (ret != HDF_SUCCESS) {
1089         HDF_LOGE("MmcCntlrParse: read devType fail, ret: %d", ret);
1090         return ret;
1091     }
1092     HDF_LOGD("MmcCntlrParse: devType = %d", cntlr->devType);
1093 
1094     MmcCntlrParseCapability(node, drsOps, cntlr);
1095     return HDF_SUCCESS;
1096 }
1097 #endif
1098 
MmcDeviceAdd(struct MmcDevice * mmc)1099 int32_t MmcDeviceAdd(struct MmcDevice *mmc)
1100 {
1101     int32_t ret;
1102 
1103     if (mmc == NULL || mmc->cntlr == NULL) {
1104         HDF_LOGE("MmcDeviceAdd: mmc or cntlr is null!");
1105         return HDF_ERR_INVALID_OBJECT;
1106     }
1107     if (mmc->type >= MMC_DEV_INVALID) {
1108         return HDF_PLT_ERR_DEV_TYPE;
1109     }
1110     if (mmc->secSize == 0) {
1111         mmc->secSize = MMC_SEC_SIZE;
1112     } else {
1113         HDF_LOGE("MmcDeviceAdd: invalid sector size:%u", mmc->secSize);
1114         return HDF_ERR_INVALID_PARAM;
1115     }
1116     if (mmc->type != MMC_DEV_SDIO && mmc->capacity == 0) {
1117         HDF_LOGE("MmcDeviceAdd: invalid capacity:%u", mmc->capacity);
1118         return HDF_ERR_INVALID_PARAM;
1119     }
1120     if (mmc->type != MMC_DEV_SDIO && mmc->eraseSize == 0) {
1121         HDF_LOGE("MmcDeviceAdd: invalid erase size:%u", mmc->eraseSize);
1122         return HDF_ERR_INVALID_PARAM;
1123     }
1124     mmc->device.number = mmc->cntlr->device.number + MMC_CNTLR_NR_MAX;
1125 
1126     if (MmcCntlrGet(mmc->cntlr) == NULL) {
1127         HDF_LOGE("MmcDeviceAdd: mmc cntlr get fail!");
1128         return HDF_PLT_ERR_DEV_GET;
1129     }
1130 
1131     mmc->device.manager = PlatformManagerGet(PLATFORM_MODULE_MMC);
1132     ret = PlatformDeviceAdd(&mmc->device);
1133     if (ret != HDF_SUCCESS) {
1134         HDF_LOGE("MmcDeviceAdd: mmc device add fail, ret: %d!", ret);
1135         MmcCntlrPut(mmc->cntlr);
1136         return ret;
1137     }
1138 
1139     if (mmc->type == MMC_DEV_EMMC || mmc->type == MMC_DEV_SD || mmc->type == MMC_DEV_COMBO) {
1140         ret = MmcBlockInit(mmc);
1141         if (ret != HDF_SUCCESS) {
1142         HDF_LOGE("MmcDeviceAdd: mmc block init fail, ret: %d!", ret);
1143             MmcCntlrPut(mmc->cntlr);
1144             PlatformDeviceDel(&mmc->device);
1145             return ret;
1146         }
1147     }
1148     return HDF_SUCCESS;
1149 }
1150 
MmcDeviceRemove(struct MmcDevice * mmc)1151 void MmcDeviceRemove(struct MmcDevice *mmc)
1152 {
1153     if (mmc == NULL) {
1154         HDF_LOGE("MmcDeviceRemove: mmc is null!");
1155         return;
1156     }
1157     if (mmc->type == MMC_DEV_EMMC || mmc->type == MMC_DEV_SD || mmc->type == MMC_DEV_COMBO) {
1158         MmcBlockUninit(mmc);
1159     }
1160     PlatformDeviceDel(&mmc->device);
1161     MmcCntlrPut(mmc->cntlr);
1162 }
1163 
MmcDeviceGet(struct MmcDevice * mmc)1164 struct MmcDevice *MmcDeviceGet(struct MmcDevice *mmc)
1165 {
1166     if (mmc == NULL) {
1167         HDF_LOGE("MmcDeviceGet: mmc is null!");
1168         return NULL;
1169     }
1170 
1171     if (PlatformDeviceGet(&mmc->device) != HDF_SUCCESS) {
1172         HDF_LOGE("MmcDeviceGet: get device ref fail!");
1173         return NULL;
1174     }
1175     return mmc;
1176 }
1177 
MmcDevicePut(struct MmcDevice * mmc)1178 void MmcDevicePut(struct MmcDevice *mmc)
1179 {
1180     if (mmc == NULL) {
1181         HDF_LOGE("MmcDevicePut: mmc is null!");
1182         return;
1183     }
1184     PlatformDevicePut(&mmc->device);
1185 }
1186 
MmcDeviceAddOps(struct MmcDevice * mmc,void * ops)1187 void MmcDeviceAddOps(struct MmcDevice *mmc, void *ops)
1188 {
1189     if (mmc->type >= MMC_DEV_INVALID) {
1190         HDF_LOGE("MmcDeviceAddOps: dev type error!");
1191         return;
1192     }
1193 
1194     if (mmc->type == MMC_DEV_SDIO || mmc->type == MMC_DEV_COMBO) {
1195         SdioDeviceAddOps((struct SdioDevice *)mmc, ops);
1196         return;
1197     }
1198 
1199     if (mmc->type == MMC_DEV_EMMC) {
1200         EmmcDeviceAddOps((struct EmmcDevice *)mmc, (struct EmmcDeviceOps *)ops);
1201     }
1202 }
1203 
MmcDeviceFillRwInfo(struct MmcRwData * info,uint8_t * buf,bool writeFlag,size_t startSec,size_t nSec)1204 static void MmcDeviceFillRwInfo(struct MmcRwData *info, uint8_t *buf,
1205     bool writeFlag, size_t startSec, size_t nSec)
1206 {
1207     info->buf = buf;
1208     info->writeFlag = writeFlag;
1209     info->startSector = startSec;
1210     info->sectors = nSec;
1211 }
1212 
MmcDeviceRead(struct MmcDevice * mmc,uint8_t * buf,size_t startSec,size_t nSec)1213 ssize_t MmcDeviceRead(struct MmcDevice *mmc, uint8_t *buf, size_t startSec, size_t nSec)
1214 {
1215     struct MmcCmd cmd = {0};
1216     struct MmcData data = {0};
1217     struct MmcRwData info = {0};
1218     size_t curSec = nSec;
1219     size_t curStartSec = startSec;
1220     size_t readSec;
1221     ssize_t ret;
1222 
1223     if (mmc == NULL) {
1224         HDF_LOGE("MmcDeviceRead: mmc is null!");
1225         return HDF_ERR_INVALID_OBJECT;
1226     }
1227     if (buf == NULL) {
1228         HDF_LOGE("MmcDeviceRead: buf is null!");
1229         return HDF_ERR_INVALID_PARAM;
1230     }
1231 
1232     do {
1233         if (curSec >= MMC_MAX_SECTOR_NUM) {
1234             readSec = MMC_MAX_SECTOR_NUM;
1235         } else {
1236             readSec = curSec;
1237         }
1238         MmcDeviceFillRwInfo(&info, buf, false, curStartSec, readSec);
1239         if (mmc->cntlr->detecting == true) {
1240             /* In SD device detecting, VFS will read/write SD. */
1241             ret = MmcSendReadWriteBlocks(mmc->cntlr, &info);
1242         } else {
1243             cmd.data = &data;
1244             MmcSetupReadWriteBlocksCmd(mmc, &cmd, &info);
1245             ret = MmcCntlrAddRequestMsgToQueue(mmc->cntlr, &cmd);
1246         }
1247         if (ret != HDF_SUCCESS) {
1248             HDF_LOGE("MmcDeviceRead: fail!");
1249             return ret;
1250         }
1251         curSec -= readSec;
1252         curStartSec += readSec;
1253         buf += (readSec * BYTES_PER_BLOCK);
1254     } while (curSec > 0);
1255 
1256     return nSec;
1257 }
1258 
MmcDeviceWrite(struct MmcDevice * mmc,uint8_t * buf,size_t startSec,size_t nSec)1259 ssize_t MmcDeviceWrite(struct MmcDevice *mmc, uint8_t *buf, size_t startSec, size_t nSec)
1260 {
1261     struct MmcCmd cmd = {0};
1262     struct MmcData data = {0};
1263     struct MmcRwData info = {0};
1264     size_t curSec = nSec;
1265     size_t curStartSec = startSec;
1266     size_t writeSec;
1267     ssize_t ret;
1268 
1269     if (mmc == NULL) {
1270         HDF_LOGE("MmcDeviceWrite: mmc is null!");
1271         return HDF_ERR_INVALID_OBJECT;
1272     }
1273     if (buf == NULL) {
1274         HDF_LOGE("MmcDeviceWrite: buf is null!");
1275         return HDF_ERR_INVALID_PARAM;
1276     }
1277 
1278     do {
1279         if (curSec >= MMC_MAX_SECTOR_NUM) {
1280             writeSec = MMC_MAX_SECTOR_NUM;
1281         } else {
1282             writeSec = curSec;
1283         }
1284         MmcDeviceFillRwInfo(&info, buf, true, curStartSec, writeSec);
1285         if (mmc->cntlr->detecting == true) {
1286             /* In SD device detecting, VFS will read/write SD. */
1287             ret = MmcSendReadWriteBlocks(mmc->cntlr, &info);
1288         } else {
1289             cmd.data = &data;
1290             MmcSetupReadWriteBlocksCmd(mmc, &cmd, &info);
1291             ret = MmcCntlrAddRequestMsgToQueue(mmc->cntlr, &cmd);
1292         }
1293         if (ret != HDF_SUCCESS) {
1294             HDF_LOGE("MmcDeviceWrite: fail!");
1295             return ret;
1296         }
1297         curSec -= writeSec;
1298         curStartSec += writeSec;
1299         buf += (writeSec * BYTES_PER_BLOCK);
1300     } while (curSec > 0);
1301 
1302     return nSec;
1303 }
1304 
MmcDeviceErase(struct MmcDevice * mmc,size_t startSec,size_t nSec)1305 ssize_t MmcDeviceErase(struct MmcDevice *mmc, size_t startSec, size_t nSec)
1306 {
1307     size_t curSec = nSec;
1308     size_t curStartSec = startSec;
1309     size_t eraseSec;
1310     ssize_t ret;
1311 
1312     if (mmc == NULL) {
1313         HDF_LOGE("MmcDeviceErase: mmc is null!");
1314         return HDF_ERR_INVALID_OBJECT;
1315     }
1316 
1317     do {
1318         if (curSec > MMC_MAX_ERASE_SECTOR) {
1319             eraseSec = MMC_MAX_ERASE_SECTOR;
1320         } else {
1321             eraseSec = curSec;
1322         }
1323         ret = MmcSendErase(mmc->cntlr, curStartSec, eraseSec);
1324         if (ret != HDF_SUCCESS) {
1325             HDF_LOGE("MmcDeviceErase: fail!");
1326             return ret;
1327         }
1328         curSec -= eraseSec;
1329         curStartSec += eraseSec;
1330     } while (curSec > 0);
1331 
1332     return HDF_SUCCESS;
1333 }
1334