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