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