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