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