]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.c
EmbeddedPkg/MmcDxe: Add 'This' pointer attribute to protocol function
[mirror_edk2.git] / ArmPlatformPkg / Drivers / PL180MciDxe / PL180Mci.c
CommitLineData
633724f4 1/** @file\r
2 This file implement the MMC Host Protocol for the ARM PrimeCell PL180.\r
3\r
4 Copyright (c) 2011, ARM Limited. All rights reserved.\r
5 \r
6 This program and the accompanying materials \r
7 are licensed and made available under the terms and conditions of the BSD License \r
8 which accompanies this distribution. The full text of the license may be found at \r
9 http://opensource.org/licenses/bsd-license.php \r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
13\r
14**/\r
15\r
16#include "PL180Mci.h"\r
17\r
18#include <Library/DevicePathLib.h>\r
19#include <Library/BaseMemoryLib.h>\r
20\r
21EFI_MMC_HOST_PROTOCOL *gpMmcHost;\r
22\r
23// Untested ...\r
24//#define USE_STREAM\r
25\r
26#define MMCI0_BLOCKLEN 512\r
27#define MMCI0_POW2_BLOCKLEN 9\r
28#define MMCI0_TIMEOUT 1000\r
29\r
30BOOLEAN\r
31MciIsPowerOn (\r
32 VOID\r
33 )\r
34{\r
35 return ((MmioRead32(MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON);\r
36}\r
37\r
38EFI_STATUS\r
39MciInitialize (\r
40 VOID\r
41 )\r
42{\r
43 MCI_TRACE("MciInitialize()");\r
44 return EFI_SUCCESS;\r
45}\r
46\r
47BOOLEAN\r
48MciIsCardPresent (\r
16d88c2d 49 IN EFI_MMC_HOST_PROTOCOL *This\r
633724f4 50 )\r
51{\r
52 return (MmioRead32(FixedPcdGet32(PcdPL180SysMciRegAddress)) & 1);\r
53}\r
54\r
55BOOLEAN\r
56MciIsReadOnly (\r
16d88c2d 57 IN EFI_MMC_HOST_PROTOCOL *This\r
633724f4 58 )\r
59{\r
60 return (MmioRead32(FixedPcdGet32(PcdPL180SysMciRegAddress)) & 2);\r
61}\r
62\r
63#if 0\r
64//Note: This function has been commented out because it is not used yet.\r
65// This function could be used to remove the hardcoded BlockLen used\r
66// in MciPrepareDataPath\r
67\r
68// Convert block size to 2^n\r
69STATIC\r
70UINT32\r
71GetPow2BlockLen (\r
72 IN UINT32 BlockLen\r
73 )\r
74{\r
75 UINTN Loop;\r
76 UINTN Pow2BlockLen;\r
77\r
78 Loop = 0x8000;\r
79 Pow2BlockLen = 15;\r
80 do {\r
81 Loop = (Loop >> 1) & 0xFFFF;\r
82 Pow2BlockLen--;\r
83 } while (Pow2BlockLen && (!(Loop & BlockLen)));\r
84\r
85 return Pow2BlockLen;\r
86}\r
87#endif\r
88\r
89VOID\r
90MciPrepareDataPath (\r
91 IN UINTN TransferDirection\r
92 )\r
93{\r
94 // Set Data Length & Data Timer\r
16d88c2d 95 MmioWrite32 (MCI_DATA_TIMER_REG,0xFFFFFFF);\r
96 MmioWrite32 (MCI_DATA_LENGTH_REG,MMCI0_BLOCKLEN);\r
633724f4 97\r
98#ifndef USE_STREAM\r
99 //Note: we are using a hardcoded BlockLen (=512). If we decide to use a variable size, we could\r
100 // compute the pow2 of BlockLen with the above function GetPow2BlockLen()\r
16d88c2d 101 MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_DMA_ENABLE | TransferDirection | (MMCI0_POW2_BLOCKLEN << 4));\r
633724f4 102#else\r
16d88c2d 103 MmioWrite32 (MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_DMA_ENABLE | TransferDirection | MCI_DATACTL_STREAM_TRANS);\r
633724f4 104#endif\r
105}\r
106\r
107EFI_STATUS\r
108MciSendCommand (\r
16d88c2d 109 IN EFI_MMC_HOST_PROTOCOL *This,\r
110 IN MMC_CMD MmcCmd,\r
111 IN UINT32 Argument\r
633724f4 112 )\r
113{\r
114 UINT32 Status;\r
115 UINT32 Cmd;\r
116 UINTN RetVal;\r
117 UINTN CmdCtrlReg;\r
118\r
119 RetVal = EFI_SUCCESS;\r
120\r
121 if ((MmcCmd == MMC_CMD17) || (MmcCmd == MMC_CMD11)) {\r
122 MciPrepareDataPath(MCI_DATACTL_CARD_TO_CONT);\r
123 } else if ((MmcCmd == MMC_CMD24) || (MmcCmd == MMC_CMD20)) {\r
124 MciPrepareDataPath(MCI_DATACTL_CONT_TO_CARD);\r
125 }\r
126\r
127 // Create Command for PL180\r
128 Cmd = (MMC_GET_INDX(MmcCmd) & INDX_MASK) | MCI_CPSM_ENABLED;\r
129 if (MmcCmd & MMC_CMD_WAIT_RESPONSE) {\r
130 Cmd |= MCI_CPSM_WAIT_RESPONSE;\r
131 }\r
132\r
133 if (MmcCmd & MMC_CMD_LONG_RESPONSE) {\r
134 Cmd |= MCI_CPSM_LONG_RESPONSE;\r
135 }\r
136\r
137 // Clear Status register static flags\r
138 MmioWrite32(MCI_CLEAR_STATUS_REG,0x7FF);\r
139\r
140 //Write to command argument register\r
141 MmioWrite32(MCI_ARGUMENT_REG,Argument);\r
142\r
143 //Write to command register\r
144 MmioWrite32(MCI_COMMAND_REG,Cmd);\r
145\r
146 if (Cmd & MCI_CPSM_WAIT_RESPONSE) {\r
147 Status = MmioRead32(MCI_STATUS_REG);\r
148 while (!(Status & (MCI_STATUS_CMD_RESPEND | MCI_STATUS_CMD_CMDCRCFAIL | MCI_STATUS_CMD_CMDTIMEOUT | MCI_STATUS_CMD_START_BIT_ERROR))) {\r
149 Status = MmioRead32(MCI_STATUS_REG);\r
150 }\r
151\r
152 if ((Status & MCI_STATUS_CMD_START_BIT_ERROR)) {\r
153 DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) Start bit Error! Response:0x%X Status:0x%x\n",(Cmd & 0x3F),MmioRead32(MCI_RESPONSE0_REG),Status));\r
154 RetVal = EFI_NO_RESPONSE;\r
155 goto Exit;\r
156 } else if ((Status & MCI_STATUS_CMD_CMDTIMEOUT)) {\r
157 //DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT! Response:0x%X Status:0x%x\n",(Cmd & 0x3F),MmioRead32(MCI_RESPONSE0_REG),Status));\r
158 RetVal = EFI_TIMEOUT;\r
159 goto Exit;\r
160 } else if ((!(MmcCmd & MMC_CMD_NO_CRC_RESPONSE)) && (Status & MCI_STATUS_CMD_CMDCRCFAIL)) {\r
161 // The CMD1 and response type R3 do not contain CRC. We should ignore the CRC failed Status.\r
162 RetVal = EFI_CRC_ERROR;\r
163 goto Exit;\r
164 } else {\r
165 RetVal = EFI_SUCCESS;\r
166 goto Exit;\r
167 }\r
168 } else {\r
169 Status = MmioRead32(MCI_STATUS_REG);\r
170 while (!(Status & (MCI_STATUS_CMD_SENT | MCI_STATUS_CMD_CMDCRCFAIL | MCI_STATUS_CMD_CMDTIMEOUT| MCI_STATUS_CMD_START_BIT_ERROR))) {\r
171 Status = MmioRead32(MCI_STATUS_REG);\r
172 }\r
173\r
174 if ((Status & MCI_STATUS_CMD_START_BIT_ERROR)) {\r
175 DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) Start bit Error! Response:0x%X Status:0x%x\n",(Cmd & 0x3F),MmioRead32(MCI_RESPONSE0_REG),Status));\r
176 RetVal = EFI_NO_RESPONSE;\r
177 goto Exit;\r
178 } else if ((Status & MCI_STATUS_CMD_CMDTIMEOUT)) {\r
179 //DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT! Response:0x%X Status:0x%x\n",(Cmd & 0x3F),MmioRead32(MCI_RESPONSE0_REG),Status));\r
180 RetVal = EFI_TIMEOUT;\r
181 goto Exit;\r
182 } else\r
183 if ((!(MmcCmd & MMC_CMD_NO_CRC_RESPONSE)) && (Status & MCI_STATUS_CMD_CMDCRCFAIL)) {\r
184 // The CMD1 does not contain CRC. We should ignore the CRC failed Status.\r
185 RetVal = EFI_CRC_ERROR;\r
186 goto Exit;\r
187 } else {\r
188 RetVal = EFI_SUCCESS;\r
189 goto Exit;\r
190 }\r
191 }\r
192\r
193Exit:\r
16d88c2d 194 // Disable Command Path\r
633724f4 195 CmdCtrlReg = MmioRead32(MCI_COMMAND_REG);\r
196 MmioWrite32(MCI_COMMAND_REG, (CmdCtrlReg & ~MCI_CPSM_ENABLED));\r
197 return RetVal;\r
198}\r
199\r
200EFI_STATUS\r
201MciReceiveResponse (\r
16d88c2d 202 IN EFI_MMC_HOST_PROTOCOL *This,\r
203 IN MMC_RESPONSE_TYPE Type,\r
204 IN UINT32* Buffer\r
633724f4 205 )\r
206{\r
207 if (Buffer == NULL) {\r
208 return EFI_INVALID_PARAMETER;\r
209 }\r
210\r
211 if ((Type == MMC_RESPONSE_TYPE_R1) || (Type == MMC_RESPONSE_TYPE_R1b) ||\r
212 (Type == MMC_RESPONSE_TYPE_R3) || (Type == MMC_RESPONSE_TYPE_R6) ||\r
213 (Type == MMC_RESPONSE_TYPE_R7))\r
214 {\r
bb0f9e9b 215 Buffer[0] = MmioRead32(MCI_RESPONSE3_REG);\r
633724f4 216 } else if (Type == MMC_RESPONSE_TYPE_R2) {\r
217 Buffer[0] = MmioRead32(MCI_RESPONSE0_REG);\r
218 Buffer[1] = MmioRead32(MCI_RESPONSE1_REG);\r
219 Buffer[2] = MmioRead32(MCI_RESPONSE2_REG);\r
220 Buffer[3] = MmioRead32(MCI_RESPONSE3_REG);\r
221 }\r
222\r
223 return EFI_SUCCESS;\r
224}\r
225\r
226EFI_STATUS\r
227MciReadBlockData (\r
16d88c2d 228 IN EFI_MMC_HOST_PROTOCOL *This,\r
229 IN EFI_LBA Lba,\r
230 IN UINTN Length,\r
231 IN UINT32* Buffer\r
633724f4 232 )\r
233{\r
234 UINTN Loop;\r
235 UINTN Finish;\r
236 UINTN Status;\r
237 EFI_STATUS RetVal;\r
238 UINTN DataCtrlReg;\r
239\r
240 RetVal = EFI_SUCCESS;\r
241\r
242 // Read data from the RX FIFO\r
243 Loop = 0;\r
244 Finish = MMCI0_BLOCKLEN / 4;\r
245 do {\r
246 // Read the Status flags\r
247 Status = MmioRead32(MCI_STATUS_REG);\r
248\r
249 // Do eight reads if possible else a single read\r
250 if (Status & MCI_STATUS_CMD_RXFIFOHALFFULL) {\r
251 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
252 Loop++;\r
253 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
254 Loop++;\r
255 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
256 Loop++;\r
257 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
258 Loop++;\r
259 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
260 Loop++;\r
261 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
262 Loop++;\r
263 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
264 Loop++;\r
265 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
266 Loop++;\r
267 } else if (Status & MCI_STATUS_CMD_RXDATAAVAILBL) {\r
268 Buffer[Loop] = MmioRead32(MCI_FIFO_REG);\r
269 Loop++;\r
270 } else {\r
271 //Check for error conditions and timeouts\r
272 if(Status & MCI_STATUS_CMD_DATATIMEOUT) {\r
273 DEBUG ((EFI_D_ERROR, "MciReadBlockData(): TIMEOUT! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status));\r
274 RetVal = EFI_TIMEOUT;\r
275 break;\r
276 } else if(Status & MCI_STATUS_CMD_DATACRCFAIL) {\r
277 DEBUG ((EFI_D_ERROR, "MciReadBlockData(): CRC Error! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status));\r
278 RetVal = EFI_CRC_ERROR;\r
279 break;\r
280 } else if(Status & MCI_STATUS_CMD_START_BIT_ERROR) {\r
281 DEBUG ((EFI_D_ERROR, "MciReadBlockData(): Start-bit Error! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status));\r
282 RetVal = EFI_NO_RESPONSE;\r
283 break;\r
284 }\r
285 }\r
286 //clear RX over run flag\r
287 if(Status & MCI_STATUS_CMD_RXOVERRUN) {\r
288 MmioWrite32(MCI_CLEAR_STATUS_REG, MCI_STATUS_CMD_RXOVERRUN);\r
289 }\r
290 } while ((Loop < Finish));\r
291\r
292 //Clear Status flags\r
293 MmioWrite32(MCI_CLEAR_STATUS_REG, 0x7FF);\r
294\r
295 //Disable Data path\r
296 DataCtrlReg = MmioRead32(MCI_DATA_CTL_REG);\r
297 MmioWrite32(MCI_DATA_CTL_REG, (DataCtrlReg & 0xFE));\r
298\r
299 return RetVal;\r
300}\r
301\r
302EFI_STATUS\r
303MciWriteBlockData (\r
16d88c2d 304 IN EFI_MMC_HOST_PROTOCOL *This,\r
305 IN EFI_LBA Lba,\r
306 IN UINTN Length,\r
307 IN UINT32* Buffer\r
633724f4 308 )\r
309{\r
310 UINTN Loop;\r
311 UINTN Finish;\r
312 UINTN Timer;\r
313 UINTN Status;\r
314 EFI_STATUS RetVal;\r
315 UINTN DataCtrlReg;\r
316\r
317 RetVal = EFI_SUCCESS;\r
318\r
319 // Write the data to the TX FIFO\r
320 Loop = 0;\r
321 Finish = MMCI0_BLOCKLEN / 4;\r
322 Timer = MMCI0_TIMEOUT * 100;\r
323 do {\r
324 // Read the Status flags\r
325 Status = MmioRead32(MCI_STATUS_REG);\r
326\r
327 // Do eight writes if possible else a single write\r
328 if (Status & MCI_STATUS_CMD_TXFIFOHALFEMPTY) {\r
329 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
330 Loop++;\r
331 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
332 Loop++;\r
333 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
334 Loop++;\r
335 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
336 Loop++;\r
337 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
338 Loop++;\r
339 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
340 Loop++;\r
341 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
342 Loop++;\r
343 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
344 Loop++;\r
345 } else if ((Status & MCI_STATUS_CMD_TXFIFOEMPTY)) {\r
346 MmioWrite32(MCI_FIFO_REG, Buffer[Loop]);\r
347 Loop++;\r
348 } else {\r
349 //Check for error conditions and timeouts\r
350 if(Status & MCI_STATUS_CMD_DATATIMEOUT) {\r
351 DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): TIMEOUT! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status));\r
352 RetVal = EFI_TIMEOUT;\r
353 goto Exit;\r
354 } else if(Status & MCI_STATUS_CMD_DATACRCFAIL) {\r
355 DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): CRC Error! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status));\r
356 RetVal = EFI_CRC_ERROR;\r
357 goto Exit;\r
358 } else if(Status & MCI_STATUS_CMD_TX_UNDERRUN) {\r
359 DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): TX buffer Underrun! Response:0x%X Status:0x%x, Number of bytes written 0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status, Loop));\r
360 RetVal = EFI_BUFFER_TOO_SMALL;\r
361 ASSERT(0);\r
362 goto Exit;\r
363 }\r
364 }\r
365 } while (Loop < Finish);\r
366\r
367 // Wait for FIFO to drain\r
368 Timer = MMCI0_TIMEOUT * 60;\r
369 Status = MmioRead32(MCI_STATUS_REG);\r
370#ifndef USE_STREAM\r
371 // Single block\r
372 while (((Status & MCI_STATUS_CMD_TXDONE) != MCI_STATUS_CMD_TXDONE) && Timer) {\r
373#else\r
374 // Stream\r
375 while (((Status & MCI_STATUS_CMD_DATAEND) != MCI_STATUS_CMD_DATAEND) && Timer) {\r
376#endif\r
377 NanoSecondDelay(10);\r
378 Status = MmioRead32(MCI_STATUS_REG);\r
379 Timer--;\r
380 }\r
381\r
382 if(Timer == 0) {\r
383 DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): Data End timeout Number of bytes written 0x%x\n",Loop));\r
384 ASSERT(Timer > 0);\r
385 return EFI_TIMEOUT;\r
386 }\r
387\r
388 //Clear Status flags\r
389 MmioWrite32(MCI_CLEAR_STATUS_REG, 0x7FF);\r
390 if (Timer == 0) {\r
391 RetVal = EFI_TIMEOUT;\r
392 }\r
393\r
394Exit:\r
395 //Disable Data path\r
396 DataCtrlReg = MmioRead32(MCI_DATA_CTL_REG);\r
397 MmioWrite32(MCI_DATA_CTL_REG, (DataCtrlReg & 0xFE));\r
398 return RetVal;\r
399}\r
400\r
401EFI_STATUS\r
402MciNotifyState (\r
16d88c2d 403 IN EFI_MMC_HOST_PROTOCOL *This,\r
404 IN MMC_STATE State\r
633724f4 405 )\r
406{\r
407 UINT32 Data32;\r
408\r
409 switch(State) {\r
410 case MmcInvalidState:\r
411 ASSERT(0);\r
412 break;\r
413 case MmcHwInitializationState:\r
414 // If device already turn on then restart it\r
415 Data32 = MmioRead32(MCI_POWER_CONTROL_REG);\r
416 if ((Data32 & 0x2) == MCI_POWER_UP) {\r
417 MCI_TRACE("MciNotifyState(MmcHwInitializationState): TurnOff MCI");\r
418\r
419 // Turn off\r
420 MmioWrite32(MCI_CLOCK_CONTROL_REG, 0);\r
421 MmioWrite32(MCI_POWER_CONTROL_REG, 0);\r
422 MicroSecondDelay(100);\r
423 }\r
424\r
425 MCI_TRACE("MciNotifyState(MmcHwInitializationState): TurnOn MCI");\r
426 // Setup clock\r
427 // - 0x1D = 29 => should be the clock divider to be less than 400kHz at MCLK = 24Mhz\r
428 MmioWrite32(MCI_CLOCK_CONTROL_REG,0x1D | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);\r
429 //MmioWrite32(MCI_CLOCK_CONTROL_REG,0x1D | MCI_CLOCK_ENABLE);\r
430\r
431 // Set the voltage\r
432 MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_OPENDRAIN | (15<<2));\r
433 MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_UP);\r
434 MicroSecondDelay(10);\r
435 MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_ON);\r
436 MicroSecondDelay(100);\r
437\r
438 // Set Data Length & Data Timer\r
439 MmioWrite32(MCI_DATA_TIMER_REG,0xFFFFF);\r
440 MmioWrite32(MCI_DATA_LENGTH_REG,8);\r
441\r
442 ASSERT((MmioRead32(MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON);\r
443 break;\r
444 case MmcIdleState:\r
445 MCI_TRACE("MciNotifyState(MmcIdleState)");\r
446 break;\r
447 case MmcReadyState:\r
448 MCI_TRACE("MciNotifyState(MmcReadyState)");\r
449 break;\r
450 case MmcIdentificationState:\r
451 MCI_TRACE("MciNotifyState(MmcIdentificationState)");\r
452 break;\r
453 case MmcStandByState:{\r
454 volatile UINT32 PwrCtrlReg;\r
455 MCI_TRACE("MciNotifyState(MmcStandByState)");\r
456\r
457 // Enable MCICMD push-pull drive\r
458 PwrCtrlReg = MmioRead32(MCI_POWER_CONTROL_REG);\r
459 //Disable Open Drain output\r
460 PwrCtrlReg &=~(MCI_POWER_OPENDRAIN);\r
461 MmioWrite32(MCI_POWER_CONTROL_REG,PwrCtrlReg);\r
462\r
463 // Set MMCI0 clock to 4MHz (24MHz may be possible with cache enabled)\r
464 //\r
465 // Note: Increasing clock speed causes TX FIFO under-run errors.\r
466 // So careful when optimising this driver for higher performance.\r
467 //\r
468 MmioWrite32(MCI_CLOCK_CONTROL_REG,0x02 | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE);\r
469 // Set MMCI0 clock to 24MHz (by bypassing the divider)\r
470 //MmioWrite32(MCI_CLOCK_CONTROL_REG,MCI_CLOCK_BYPASS | MCI_CLOCK_ENABLE);\r
471 break;\r
472 }\r
473 case MmcTransferState:\r
474 //MCI_TRACE("MciNotifyState(MmcTransferState)");\r
475 break;\r
476 case MmcSendingDataState:\r
477 MCI_TRACE("MciNotifyState(MmcSendingDataState)");\r
478 break;\r
479 case MmcReceiveDataState:\r
480 MCI_TRACE("MciNotifyState(MmcReceiveDataState)");\r
481 break;\r
482 case MmcProgrammingState:\r
483 MCI_TRACE("MciNotifyState(MmcProgrammingState)");\r
484 break;\r
485 case MmcDisconnectState:\r
486 MCI_TRACE("MciNotifyState(MmcDisconnectState)");\r
487 break;\r
488 default:\r
489 ASSERT(0);\r
490 }\r
491 return EFI_SUCCESS;\r
492}\r
493\r
494EFI_GUID mPL180MciDevicePathGuid = EFI_CALLER_ID_GUID;\r
495\r
496EFI_STATUS\r
497MciBuildDevicePath (\r
16d88c2d 498 IN EFI_MMC_HOST_PROTOCOL *This,\r
499 IN EFI_DEVICE_PATH_PROTOCOL **DevicePath\r
633724f4 500 )\r
501{\r
502 EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;\r
503\r
504 NewDevicePathNode = CreateDeviceNode(HARDWARE_DEVICE_PATH,HW_VENDOR_DP,sizeof(VENDOR_DEVICE_PATH));\r
505 CopyGuid(&((VENDOR_DEVICE_PATH*)NewDevicePathNode)->Guid,&mPL180MciDevicePathGuid);\r
506\r
507 *DevicePath = NewDevicePathNode;\r
508 return EFI_SUCCESS;\r
509}\r
510\r
511EFI_MMC_HOST_PROTOCOL gMciHost = {\r
16d88c2d 512 MMC_HOST_PROTOCOL_REVISION,\r
633724f4 513 MciIsCardPresent,\r
514 MciIsReadOnly,\r
515 MciBuildDevicePath,\r
516 MciNotifyState,\r
517 MciSendCommand,\r
518 MciReceiveResponse,\r
519 MciReadBlockData,\r
520 MciWriteBlockData\r
521};\r
522\r
523EFI_STATUS\r
524PL180MciDxeInitialize (\r
525 IN EFI_HANDLE ImageHandle,\r
526 IN EFI_SYSTEM_TABLE *SystemTable\r
527 )\r
528{\r
529 EFI_STATUS Status;\r
530 EFI_HANDLE Handle = NULL;\r
531\r
532 MCI_TRACE("PL180MciDxeInitialize()");\r
533\r
534 //Publish Component Name, BlockIO protocol interfaces\r
535 Status = gBS->InstallMultipleProtocolInterfaces (\r
536 &Handle, \r
537 &gEfiMmcHostProtocolGuid, &gMciHost,\r
538 NULL\r
539 );\r
540 ASSERT_EFI_ERROR (Status);\r
541\r
542 return EFI_SUCCESS;\r
543}\r