Home | History | Annotate | Download | only in DwMmcHcDxe
      1 /** @file
      2   This file provides some helper functions which are specific for SD card device.
      3 
      4   Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "DwMmcHcDxe.h"
     16 
     17 /**
     18   Send command GO_IDLE_STATE to the device to make it go to Idle State.
     19 
     20   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
     21 
     22   @param[in] PassThru       A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
     23   @param[in] Slot           The slot number of the SD card to send the command to.
     24 
     25   @retval EFI_SUCCESS       The SD device is reset correctly.
     26   @retval Others            The device reset fails.
     27 
     28 **/
     29 EFI_STATUS
     30 SdCardReset (
     31   IN EFI_SD_MMC_PASS_THRU_PROTOCOL      *PassThru,
     32   IN UINT8                              Slot
     33   )
     34 {
     35   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
     36   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
     37   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
     38   EFI_STATUS                            Status;
     39 
     40   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
     41   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
     42   ZeroMem (&Packet, sizeof (Packet));
     43 
     44   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
     45   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
     46   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
     47 
     48   SdMmcCmdBlk.CommandIndex = SD_GO_IDLE_STATE;
     49   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeBc;
     50 
     51   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
     52 
     53   return Status;
     54 }
     55 
     56 /**
     57   Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface
     58   condition.
     59 
     60   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
     61 
     62   @param[in] PassThru       A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
     63   @param[in] Slot           The slot number of the SD card to send the command to.
     64   @param[in] SupplyVoltage  The supplied voltage by the host.
     65   @param[in] CheckPattern   The check pattern to be sent to the device.
     66 
     67   @retval EFI_SUCCESS       The operation is done correctly.
     68   @retval Others            The operation fails.
     69 
     70 **/
     71 EFI_STATUS
     72 SdCardVoltageCheck (
     73   IN EFI_SD_MMC_PASS_THRU_PROTOCOL      *PassThru,
     74   IN UINT8                              Slot,
     75   IN UINT8                              SupplyVoltage,
     76   IN UINT8                              CheckPattern
     77   )
     78 {
     79   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
     80   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
     81   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
     82   EFI_STATUS                            Status;
     83 
     84   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
     85   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
     86   ZeroMem (&Packet, sizeof (Packet));
     87 
     88   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
     89   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
     90   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
     91 
     92   SdMmcCmdBlk.CommandIndex = SD_SEND_IF_COND;
     93   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeBcr;
     94   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR7;
     95   SdMmcCmdBlk.CommandArgument = (SupplyVoltage << 8) | CheckPattern;
     96 
     97   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
     98 
     99   if (!EFI_ERROR (Status)) {
    100     if (SdMmcStatusBlk.Resp0 != SdMmcCmdBlk.CommandArgument) {
    101       return EFI_DEVICE_ERROR;
    102     }
    103   }
    104 
    105   return Status;
    106 }
    107 
    108 /**
    109   Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device.
    110 
    111   Refer to SDIO Simplified Spec 3 Section 3.2 for details.
    112 
    113   @param[in] PassThru       A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    114   @param[in] Slot           The slot number of the SD card to send the command to.
    115   @param[in] VoltageWindow  The supply voltage window.
    116   @param[in] S18R           The boolean to show if it should switch to 1.8v.
    117 
    118   @retval EFI_SUCCESS       The operation is done correctly.
    119   @retval Others            The operation fails.
    120 
    121 **/
    122 EFI_STATUS
    123 SdioSendOpCond (
    124   IN EFI_SD_MMC_PASS_THRU_PROTOCOL      *PassThru,
    125   IN UINT8                              Slot,
    126   IN UINT32                             VoltageWindow,
    127   IN BOOLEAN                            S18R
    128   )
    129 {
    130   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
    131   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
    132   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
    133   EFI_STATUS                            Status;
    134   UINT32                                Switch;
    135 
    136   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
    137   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
    138   ZeroMem (&Packet, sizeof (Packet));
    139 
    140   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
    141   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
    142   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
    143 
    144   SdMmcCmdBlk.CommandIndex = SDIO_SEND_OP_COND;
    145   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeBcr;
    146   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR4;
    147 
    148   Switch = S18R ? BIT24 : 0;
    149 
    150   SdMmcCmdBlk.CommandArgument = (VoltageWindow & 0xFFFFFF) | Switch;
    151 
    152   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    153 
    154   return Status;
    155 }
    156 
    157 /**
    158   Send command SD_SEND_OP_COND to the device to see whether it is SDIO device.
    159 
    160   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
    161 
    162   @param[in]  PassThru       A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    163   @param[in]  Slot           The slot number of the SD card to send the command to.
    164   @param[in]  Rca            The relative device address of addressed device.
    165   @param[in]  VoltageWindow  The supply voltage window.
    166   @param[in]  S18R           The boolean to show if it should switch to 1.8v.
    167   @param[in]  Xpc            The boolean to show if it should provide 0.36w power control.
    168   @param[in]  Hcs            The boolean to show if it support host capacity info.
    169   @param[out] Ocr            The buffer to store returned OCR register value.
    170 
    171   @retval EFI_SUCCESS        The operation is done correctly.
    172   @retval Others             The operation fails.
    173 
    174 **/
    175 EFI_STATUS
    176 SdCardSendOpCond (
    177   IN     EFI_SD_MMC_PASS_THRU_PROTOCOL  *PassThru,
    178   IN     UINT8                          Slot,
    179   IN     UINT16                         Rca,
    180   IN     UINT32                         VoltageWindow,
    181   IN     BOOLEAN                        S18R,
    182   IN     BOOLEAN                        Xpc,
    183   IN     BOOLEAN                        Hcs,
    184      OUT UINT32                         *Ocr
    185   )
    186 {
    187   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
    188   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
    189   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
    190   EFI_STATUS                            Status;
    191   UINT32                                Switch;
    192   UINT32                                MaxPower;
    193   UINT32                                HostCapacity;
    194 
    195   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
    196   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
    197   ZeroMem (&Packet, sizeof (Packet));
    198 
    199   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
    200   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
    201   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
    202 
    203   SdMmcCmdBlk.CommandIndex = SD_APP_CMD;
    204   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeAc;
    205   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
    206   SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
    207 
    208   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    209   if (EFI_ERROR (Status)) {
    210     return Status;
    211   }
    212 
    213   SdMmcCmdBlk.CommandIndex = SD_SEND_OP_COND;
    214   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeBcr;
    215   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR3;
    216 
    217   Switch       = S18R ? BIT24 : 0;
    218   MaxPower     = Xpc ? BIT28 : 0;
    219   HostCapacity = Hcs ? BIT30 : 0;
    220 
    221   SdMmcCmdBlk.CommandArgument = (VoltageWindow & 0xFFFFFF) | Switch | MaxPower | HostCapacity;
    222 
    223   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    224   if (!EFI_ERROR (Status)) {
    225     //
    226     // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
    227     //
    228     *Ocr = SdMmcStatusBlk.Resp0;
    229   }
    230 
    231   return Status;
    232 }
    233 
    234 /**
    235   Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the
    236   data of their CID registers.
    237 
    238   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
    239 
    240   @param[in] PassThru       A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    241   @param[in] Slot           The slot number of the SD card to send the command to.
    242 
    243   @retval EFI_SUCCESS       The operation is done correctly.
    244   @retval Others            The operation fails.
    245 
    246 **/
    247 EFI_STATUS
    248 SdCardAllSendCid (
    249   IN EFI_SD_MMC_PASS_THRU_PROTOCOL      *PassThru,
    250   IN UINT8                              Slot
    251   )
    252 {
    253   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
    254   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
    255   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
    256   EFI_STATUS                            Status;
    257 
    258   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
    259   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
    260   ZeroMem (&Packet, sizeof (Packet));
    261 
    262   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
    263   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
    264   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
    265 
    266   SdMmcCmdBlk.CommandIndex = SD_ALL_SEND_CID;
    267   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeBcr;
    268   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2;
    269 
    270   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    271 
    272   return Status;
    273 }
    274 
    275 /**
    276   Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device
    277   Address (RCA).
    278 
    279   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
    280 
    281   @param[in]  PassThru      A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    282   @param[in]  Slot          The slot number of the SD card to send the command to.
    283   @param[out] Rca           The relative device address to assign.
    284 
    285   @retval EFI_SUCCESS       The operation is done correctly.
    286   @retval Others            The operation fails.
    287 
    288 **/
    289 EFI_STATUS
    290 SdCardSetRca (
    291   IN     EFI_SD_MMC_PASS_THRU_PROTOCOL  *PassThru,
    292   IN     UINT8                          Slot,
    293      OUT UINT16                         *Rca
    294   )
    295 {
    296   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
    297   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
    298   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
    299   EFI_STATUS                            Status;
    300 
    301   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
    302   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
    303   ZeroMem (&Packet, sizeof (Packet));
    304 
    305   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
    306   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
    307   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
    308 
    309   SdMmcCmdBlk.CommandIndex = SD_SET_RELATIVE_ADDR;
    310   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeBcr;
    311   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR6;
    312 
    313   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    314   if (!EFI_ERROR (Status)) {
    315     *Rca = (UINT16)(SdMmcStatusBlk.Resp0 >> 16);
    316   }
    317 
    318   return Status;
    319 }
    320 
    321 /**
    322   Send command SEND_CSD to the SD device to get the data of the CSD register.
    323 
    324   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
    325 
    326   @param[in]  PassThru      A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    327   @param[in]  Slot          The slot number of the SD card to send the command to.
    328   @param[in]  Rca           The relative device address of selected device.
    329   @param[out] Csd           The buffer to store the content of the CSD register.
    330                             Note the caller should ignore the lowest byte of this
    331                             buffer as the content of this byte is meaningless even
    332                             if the operation succeeds.
    333 
    334   @retval EFI_SUCCESS       The operation is done correctly.
    335   @retval Others            The operation fails.
    336 
    337 **/
    338 EFI_STATUS
    339 SdCardGetCsd (
    340   IN     EFI_SD_MMC_PASS_THRU_PROTOCOL  *PassThru,
    341   IN     UINT8                          Slot,
    342   IN     UINT16                         Rca,
    343      OUT SD_CSD                         *Csd
    344   )
    345 {
    346   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
    347   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
    348   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
    349   EFI_STATUS                            Status;
    350 
    351   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
    352   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
    353   ZeroMem (&Packet, sizeof (Packet));
    354 
    355   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
    356   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
    357   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
    358 
    359   SdMmcCmdBlk.CommandIndex = SD_SEND_CSD;
    360   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeAc;
    361   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2;
    362   SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
    363 
    364   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    365   if (!EFI_ERROR (Status)) {
    366     //
    367     // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
    368     //
    369     CopyMem (((UINT8*)Csd) + 1, &SdMmcStatusBlk.Resp0, sizeof (SD_CSD) - 1);
    370   }
    371 
    372   return Status;
    373 }
    374 
    375 /**
    376   Send command SEND_CSD to the SD device to get the data of the CSD register.
    377 
    378   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
    379 
    380   @param[in]  PassThru      A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    381   @param[in]  Slot          The slot number of the SD card to send the command to.
    382   @param[in]  Rca           The relative device address of selected device.
    383   @param[out] Scr           The buffer to store the content of the SCR register.
    384 
    385   @retval EFI_SUCCESS       The operation is done correctly.
    386   @retval Others            The operation fails.
    387 
    388 **/
    389 EFI_STATUS
    390 SdCardGetScr (
    391   IN     EFI_SD_MMC_PASS_THRU_PROTOCOL  *PassThru,
    392   IN     UINT8                          Slot,
    393   IN     UINT16                         Rca,
    394      OUT SD_SCR                         *Scr
    395   )
    396 {
    397   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
    398   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
    399   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
    400   EFI_STATUS                            Status;
    401 
    402   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
    403   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
    404   ZeroMem (&Packet, sizeof (Packet));
    405 
    406   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
    407   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
    408   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
    409 
    410   SdMmcCmdBlk.CommandIndex = SD_APP_CMD;
    411   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeAc;
    412   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
    413   SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
    414 
    415   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    416   if (EFI_ERROR (Status)) {
    417     return Status;
    418   }
    419 
    420   SdMmcCmdBlk.CommandIndex = SD_SEND_SCR;
    421   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeAdtc;
    422   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
    423 
    424   Packet.InDataBuffer     = Scr;
    425   Packet.InTransferLength = sizeof (SD_SCR);
    426 
    427   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    428 
    429   return Status;
    430 }
    431 
    432 /**
    433   Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
    434 
    435   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
    436 
    437   @param[in]  PassThru      A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    438   @param[in]  Slot          The slot number of the SD card to send the command to.
    439   @param[in]  Rca           The relative device address of selected device.
    440 
    441   @retval EFI_SUCCESS       The operation is done correctly.
    442   @retval Others            The operation fails.
    443 
    444 **/
    445 EFI_STATUS
    446 SdCardSelect (
    447   IN EFI_SD_MMC_PASS_THRU_PROTOCOL      *PassThru,
    448   IN UINT8                              Slot,
    449   IN UINT16                             Rca
    450   )
    451 {
    452   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
    453   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
    454   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
    455   EFI_STATUS                            Status;
    456 
    457   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
    458   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
    459   ZeroMem (&Packet, sizeof (Packet));
    460 
    461   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
    462   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
    463   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
    464 
    465   SdMmcCmdBlk.CommandIndex = SD_SELECT_DESELECT_CARD;
    466   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeAc;
    467   if (Rca != 0) {
    468     SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1b;
    469   }
    470   SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
    471 
    472   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    473 
    474   return Status;
    475 }
    476 
    477 /**
    478   Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
    479 
    480   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
    481 
    482   @param[in]  PassThru      A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    483   @param[in]  Slot          The slot number of the SD card to send the command to.
    484 
    485   @retval EFI_SUCCESS       The operation is done correctly.
    486   @retval Others            The operation fails.
    487 
    488 **/
    489 EFI_STATUS
    490 SdCardVoltageSwitch (
    491   IN EFI_SD_MMC_PASS_THRU_PROTOCOL      *PassThru,
    492   IN UINT8                              Slot
    493   )
    494 {
    495   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
    496   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
    497   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
    498   EFI_STATUS                            Status;
    499 
    500   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
    501   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
    502   ZeroMem (&Packet, sizeof (Packet));
    503 
    504   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
    505   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
    506   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
    507 
    508   SdMmcCmdBlk.CommandIndex = SD_VOLTAGE_SWITCH;
    509   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeAc;
    510   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
    511   SdMmcCmdBlk.CommandArgument = 0;
    512 
    513   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    514 
    515   return Status;
    516 }
    517 
    518 /**
    519   Send command SET_BUS_WIDTH to the SD device to set the bus width.
    520 
    521   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
    522 
    523   @param[in] PassThru       A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    524   @param[in] Slot           The slot number of the SD card to send the command to.
    525   @param[in] Rca            The relative device address of addressed device.
    526   @param[in] BusWidth       The bus width to be set, it could be 1 or 4.
    527 
    528   @retval EFI_SUCCESS       The operation is done correctly.
    529   @retval Others            The operation fails.
    530 
    531 **/
    532 EFI_STATUS
    533 SdCardSetBusWidth (
    534   IN EFI_SD_MMC_PASS_THRU_PROTOCOL      *PassThru,
    535   IN UINT8                              Slot,
    536   IN UINT16                             Rca,
    537   IN UINT8                              BusWidth
    538   )
    539 {
    540   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
    541   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
    542   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
    543   EFI_STATUS                            Status;
    544   UINT8                                 Value;
    545 
    546   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
    547   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
    548   ZeroMem (&Packet, sizeof (Packet));
    549 
    550   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
    551   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
    552   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
    553 
    554   SdMmcCmdBlk.CommandIndex = SD_APP_CMD;
    555   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeAc;
    556   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
    557   SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
    558 
    559   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    560   if (EFI_ERROR (Status)) {
    561     return Status;
    562   }
    563 
    564   SdMmcCmdBlk.CommandIndex = SD_SET_BUS_WIDTH;
    565   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeAc;
    566   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
    567 
    568   if (BusWidth == 1) {
    569     Value = 0;
    570   } else if (BusWidth == 4) {
    571     Value = 2;
    572   } else {
    573     return EFI_INVALID_PARAMETER;
    574   }
    575 
    576   SdMmcCmdBlk.CommandArgument = Value & 0x3;
    577 
    578   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    579   return Status;
    580 }
    581 
    582 /**
    583   Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
    584 
    585   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
    586 
    587   @param[in]  PassThru      A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    588   @param[in]  Slot          The slot number of the SD card to send the command to.
    589   @param[in]  AccessMode    The value for access mode group.
    590   @param[in]  CommandSystem The value for command set group.
    591   @param[in]  DriveStrength The value for drive length group.
    592   @param[in]  PowerLimit    The value for power limit group.
    593   @param[in]  Mode          Switch or check function.
    594   @param[out] SwitchResp    The return switch function status.
    595 
    596   @retval EFI_SUCCESS       The operation is done correctly.
    597   @retval Others            The operation fails.
    598 
    599 **/
    600 EFI_STATUS
    601 SdCardSwitch (
    602   IN     EFI_SD_MMC_PASS_THRU_PROTOCOL  *PassThru,
    603   IN     UINT8                          Slot,
    604   IN     UINT8                          AccessMode,
    605   IN     UINT8                          CommandSystem,
    606   IN     UINT8                          DriveStrength,
    607   IN     UINT8                          PowerLimit,
    608   IN     BOOLEAN                        Mode,
    609      OUT UINT8                          *SwitchResp
    610   )
    611 {
    612   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
    613   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
    614   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
    615   EFI_STATUS                            Status;
    616   UINT32                                ModeValue;
    617 
    618   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
    619   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
    620   ZeroMem (&Packet, sizeof (Packet));
    621 
    622   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
    623   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
    624   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
    625 
    626   SdMmcCmdBlk.CommandIndex = SD_SWITCH_FUNC;
    627   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeAdtc;
    628   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
    629 
    630   ModeValue = Mode ? BIT31 : 0;
    631   SdMmcCmdBlk.CommandArgument = (AccessMode & 0xF) | ((PowerLimit & 0xF) << 4) | \
    632                                 ((DriveStrength & 0xF) << 8) | ((DriveStrength & 0xF) << 12) | \
    633                                 ModeValue;
    634 
    635   Packet.InDataBuffer     = SwitchResp;
    636   Packet.InTransferLength = 64;
    637 
    638   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    639 
    640   return Status;
    641 }
    642 
    643 /**
    644   Send command SEND_STATUS to the addressed SD device to get its status register.
    645 
    646   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
    647 
    648   @param[in]  PassThru      A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    649   @param[in]  Slot          The slot number of the SD card to send the command to.
    650   @param[in]  Rca           The relative device address of addressed device.
    651   @param[out] DevStatus     The returned device status.
    652 
    653   @retval EFI_SUCCESS       The operation is done correctly.
    654   @retval Others            The operation fails.
    655 
    656 **/
    657 EFI_STATUS
    658 SdCardSendStatus (
    659   IN     EFI_SD_MMC_PASS_THRU_PROTOCOL  *PassThru,
    660   IN     UINT8                          Slot,
    661   IN     UINT16                         Rca,
    662      OUT UINT32                         *DevStatus
    663   )
    664 {
    665   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
    666   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
    667   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
    668   EFI_STATUS                            Status;
    669 
    670   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
    671   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
    672   ZeroMem (&Packet, sizeof (Packet));
    673 
    674   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
    675   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
    676   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
    677 
    678   SdMmcCmdBlk.CommandIndex = SD_SEND_STATUS;
    679   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeAc;
    680   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
    681   SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
    682 
    683   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    684   if (!EFI_ERROR (Status)) {
    685     *DevStatus = SdMmcStatusBlk.Resp0;
    686   }
    687 
    688   return Status;
    689 }
    690 
    691 /**
    692   Send command SEND_TUNING_BLOCK to the SD device for HS200 optimal sampling point
    693   detection.
    694 
    695   It may be sent up to 40 times until the host finishes the tuning procedure.
    696 
    697   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
    698 
    699   @param[in] PassThru       A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    700   @param[in] Slot           The slot number of the SD card to send the command to.
    701 
    702   @retval EFI_SUCCESS       The operation is done correctly.
    703   @retval Others            The operation fails.
    704 
    705 **/
    706 EFI_STATUS
    707 SdCardSendTuningBlk (
    708   IN EFI_SD_MMC_PASS_THRU_PROTOCOL      *PassThru,
    709   IN UINT8                              Slot
    710   )
    711 {
    712   EFI_SD_MMC_COMMAND_BLOCK              SdMmcCmdBlk;
    713   EFI_SD_MMC_STATUS_BLOCK               SdMmcStatusBlk;
    714   EFI_SD_MMC_PASS_THRU_COMMAND_PACKET   Packet;
    715   EFI_STATUS                            Status;
    716   UINT8                                 TuningBlock[64];
    717 
    718   ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
    719   ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
    720   ZeroMem (&Packet, sizeof (Packet));
    721 
    722   Packet.SdMmcCmdBlk    = &SdMmcCmdBlk;
    723   Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
    724   Packet.Timeout        = DW_MMC_HC_GENERIC_TIMEOUT;
    725 
    726   SdMmcCmdBlk.CommandIndex = SD_SEND_TUNING_BLOCK;
    727   SdMmcCmdBlk.CommandType  = SdMmcCommandTypeAdtc;
    728   SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
    729   SdMmcCmdBlk.CommandArgument = 0;
    730 
    731   Packet.InDataBuffer     = TuningBlock;
    732   Packet.InTransferLength = sizeof (TuningBlock);
    733 
    734   Status = DwMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
    735 
    736   return Status;
    737 }
    738 
    739 /**
    740   Switch the bus width to specified width.
    741 
    742   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
    743   SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
    744 
    745   @param[in] PciIo          A pointer to the EFI_PCI_IO_PROTOCOL instance.
    746   @param[in] PassThru       A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    747   @param[in] Slot           The slot number of the SD card to send the command to.
    748   @param[in] Rca            The relative device address to be assigned.
    749   @param[in] BusWidth       The bus width to be set, it could be 4 or 8.
    750 
    751   @retval EFI_SUCCESS       The operation is done correctly.
    752   @retval Others            The operation fails.
    753 
    754 **/
    755 EFI_STATUS
    756 SdCardSwitchBusWidth (
    757   IN EFI_PCI_IO_PROTOCOL                *PciIo,
    758   IN EFI_SD_MMC_PASS_THRU_PROTOCOL      *PassThru,
    759   IN UINT8                              Slot,
    760   IN UINT16                             Rca,
    761   IN BOOLEAN                            IsDdr,
    762   IN UINT8                              BusWidth
    763   )
    764 {
    765   EFI_STATUS          Status;
    766   UINT32              DevStatus;
    767 
    768   Status = SdCardSetBusWidth (PassThru, Slot, Rca, BusWidth);
    769   if (EFI_ERROR (Status)) {
    770     DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth, Status));
    771     return Status;
    772   }
    773 
    774   Status = SdCardSendStatus (PassThru, Slot, Rca, &DevStatus);
    775   if (EFI_ERROR (Status)) {
    776     DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: Send status fails with %r\n", Status));
    777     return Status;
    778   }
    779   //
    780   // Check the switch operation is really successful or not.
    781   //
    782   if ((DevStatus >> 16) != 0) {
    783     DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus));
    784     return EFI_DEVICE_ERROR;
    785   }
    786 
    787   Status = DwMmcHcSetBusWidth (PciIo, Slot, IsDdr, BusWidth);
    788 
    789   return Status;
    790 }
    791 
    792 /**
    793   Switch the high speed timing according to request.
    794 
    795   Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
    796   SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
    797 
    798   @param[in] PciIo          A pointer to the EFI_PCI_IO_PROTOCOL instance.
    799   @param[in] PassThru       A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
    800   @param[in] Slot           The slot number of the SD card to send the command to.
    801   @param[in] Rca            The relative device address to be assigned.
    802   @param[in] S18A           The boolean to show if it's a UHS-I SD card.
    803   @param[in] BusWidths      The bus width of the SD card.
    804 
    805   @retval EFI_SUCCESS       The operation is done correctly.
    806   @retval Others            The operation fails.
    807 
    808 **/
    809 EFI_STATUS
    810 SdCardSetBusMode (
    811   IN EFI_PCI_IO_PROTOCOL                *PciIo,
    812   IN EFI_SD_MMC_PASS_THRU_PROTOCOL      *PassThru,
    813   IN UINT8                              Slot,
    814   IN UINT16                             Rca,
    815   IN BOOLEAN                            S18A,
    816   IN UINT32                             BusWidths
    817   )
    818 {
    819   EFI_STATUS                   Status;
    820   DW_MMC_HC_SLOT_CAP           *Capability;
    821   UINT32                       ClockFreq;
    822   UINT8                        AccessMode;
    823   UINT8                        SwitchResp[64];
    824   DW_MMC_HC_PRIVATE_DATA       *Private;
    825   BOOLEAN                      IsDdr;
    826 
    827   Private = DW_MMC_HC_PRIVATE_FROM_THIS (PassThru);
    828 
    829   Capability = &Private->Capability[Slot];
    830 
    831   if ((Capability->BusWidth == 1) || (Capability->BusWidth == 4)) {
    832     BusWidths &= Capability[Slot].BusWidth;
    833   } else {
    834     DEBUG ((DEBUG_ERROR, "SdCardSetBusMode: BusWidths (%d) in capability are wrong\n", Capability->BusWidth));
    835     return EFI_INVALID_PARAMETER;
    836   }
    837 
    838   if (BusWidths == 0) {
    839     DEBUG ((DEBUG_ERROR, "SdCardSetBusMode: Get wrong BusWidths:%d\n", BusWidths));
    840     return EFI_INVALID_PARAMETER;
    841   }
    842 
    843   if (Private->Capability[Slot].Ddr50) {
    844     IsDdr = TRUE;
    845   } else {
    846     IsDdr = FALSE;
    847   }
    848 
    849   Status = SdCardSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusWidths);
    850   if (EFI_ERROR (Status)) {
    851     DEBUG ((DEBUG_ERROR, "SdCardSetBusMode: Executing SdCardSwitchBusWidth fails with %r\n", Status));
    852     return Status;
    853   }
    854 
    855   //
    856   // Get the supported bus speed from SWITCH cmd return data group #1.
    857   //
    858   Status = SdCardSwitch (PassThru, Slot, 0xF, 0xF, 0xF, 0xF, FALSE, SwitchResp);
    859   if (EFI_ERROR (Status)) {
    860     return Status;
    861   }
    862   //
    863   // Calculate supported bus speed/bus width/clock frequency by host and device capability.
    864   //
    865   ClockFreq = 0;
    866   if (S18A && (Capability->Sdr104 != 0) && ((SwitchResp[13] & BIT3) != 0)) {
    867     ClockFreq = 208;
    868     AccessMode = 3;
    869   } else if (S18A && (Capability->Sdr50 != 0) && ((SwitchResp[13] & BIT2) != 0)) {
    870     ClockFreq = 100;
    871     AccessMode = 2;
    872   } else if (S18A && (Capability->Ddr50 != 0) && ((SwitchResp[13] & BIT4) != 0)) {
    873     ClockFreq = 50;
    874     AccessMode = 4;
    875   } else if ((SwitchResp[13] & BIT1) != 0) {
    876     ClockFreq = 50;
    877     AccessMode = 1;
    878   } else {
    879     ClockFreq = 25;
    880     AccessMode = 0;
    881   }
    882 
    883   Status = SdCardSwitch (PassThru, Slot, AccessMode, 0xF, 0xF, 0xF, TRUE, SwitchResp);
    884   if (EFI_ERROR (Status)) {
    885     return Status;
    886   }
    887 
    888   if ((SwitchResp[16] & 0xF) != AccessMode) {
    889     DEBUG ((DEBUG_ERROR, "SdCardSetBusMode: Switch to AccessMode %d ClockFreq %d fails! The Switch response is 0x%1x\n", AccessMode, ClockFreq, SwitchResp[16] & 0xF));
    890     return EFI_DEVICE_ERROR;
    891   }
    892 
    893   DEBUG ((DEBUG_INFO, "SdCardSetBusMode: Switch to AccessMode %d ClockFreq %d \n", AccessMode, ClockFreq));
    894 
    895   Status = DwMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, *Capability);
    896   if (EFI_ERROR (Status)) {
    897     return Status;
    898   }
    899 
    900   return Status;
    901 }
    902 
    903 /**
    904   Execute SD device identification procedure.
    905 
    906   Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
    907 
    908   @param[in] Private        A pointer to the DW_MMC_HC_PRIVATE_DATA instance.
    909   @param[in] Slot           The slot number of the SD card to send the command to.
    910 
    911   @retval EFI_SUCCESS       There is a SD card.
    912   @retval Others            There is not a SD card.
    913 
    914 **/
    915 EFI_STATUS
    916 SdCardIdentification (
    917   IN DW_MMC_HC_PRIVATE_DATA             *Private,
    918   IN UINT8                              Slot
    919   )
    920 {
    921   EFI_STATUS                     Status;
    922   EFI_PCI_IO_PROTOCOL            *PciIo;
    923   EFI_SD_MMC_PASS_THRU_PROTOCOL  *PassThru;
    924   UINT32                         Ocr;
    925   UINT16                         Rca;
    926   BOOLEAN                        Xpc;
    927   BOOLEAN                        S18r;
    928   UINT64                         MaxCurrent;
    929   SD_SCR                         Scr;
    930   SD_CSD                         Csd;
    931 
    932   PciIo    = Private->PciIo;
    933   PassThru = &Private->PassThru;
    934   //
    935   // 1. Send Cmd0 to the device
    936   //
    937   Status = SdCardReset (PassThru, Slot);
    938   if (EFI_ERROR (Status)) {
    939     DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status));
    940     return Status;
    941   }
    942   MicroSecondDelay (10000);
    943   //
    944   // 2. Send Cmd8 to the device
    945   //
    946   Status = SdCardVoltageCheck (PassThru, Slot, 0x1, 0xFF);
    947   if (EFI_ERROR (Status)) {
    948     DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status));
    949     return Status;
    950   }
    951   //
    952   // 3. Send Acmd41 with voltage window 0 to the device
    953   //
    954   Status = SdCardSendOpCond (PassThru, Slot, 0, 0, FALSE, FALSE, FALSE, &Ocr);
    955   if (EFI_ERROR (Status)) {
    956     DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status));
    957     return EFI_DEVICE_ERROR;
    958   }
    959 
    960   if (Private->Capability[Slot].Voltage33 != 0) {
    961     //
    962     // Support 3.3V
    963     //
    964     MaxCurrent = ((UINT32)Private->MaxCurrent[Slot] & 0xFF) * 4;
    965     S18r = FALSE;
    966   } else if (Private->Capability[Slot].Voltage30 != 0) {
    967     //
    968     // Support 3.0V
    969     //
    970     MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 8) & 0xFF) * 4;
    971     S18r = FALSE;
    972   } else if (Private->Capability[Slot].Voltage18 != 0) {
    973     //
    974     // Support 1.8V
    975     //
    976     MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 16) & 0xFF) * 4;
    977     S18r = TRUE;
    978   } else {
    979     ASSERT (FALSE);
    980     return EFI_DEVICE_ERROR;
    981   }
    982 
    983   if (MaxCurrent >= 150) {
    984     Xpc = TRUE;
    985   } else {
    986     Xpc = FALSE;
    987   }
    988 
    989   //
    990   // 4. Repeatly send Acmd41 with supply voltage window to the device.
    991   //    Note here we only support the cards complied with SD physical
    992   //    layer simplified spec version 2.0 and version 3.0 and above.
    993   //
    994   do {
    995     Status = SdCardSendOpCond (PassThru, Slot, 0, Ocr, S18r, Xpc, TRUE, &Ocr);
    996     if (EFI_ERROR (Status)) {
    997       DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status, Ocr, S18r, Xpc));
    998       return EFI_DEVICE_ERROR;
    999     }
   1000   } while ((Ocr & BIT31) == 0);
   1001 
   1002   Status = SdCardAllSendCid (PassThru, Slot);
   1003   if (EFI_ERROR (Status)) {
   1004     DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status));
   1005     return Status;
   1006   }
   1007 
   1008   Status = SdCardSetRca (PassThru, Slot, &Rca);
   1009   if (EFI_ERROR (Status)) {
   1010     DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status));
   1011     return Status;
   1012   }
   1013 
   1014   Status = SdCardGetCsd (PassThru, Slot, Rca, &Csd);
   1015   if (EFI_ERROR (Status)) {
   1016     DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardGetCsd fails with %r\n", Status));
   1017     return Status;
   1018   }
   1019 
   1020   Status = SdCardSelect (PassThru, Slot, Rca);
   1021   if (EFI_ERROR (Status)) {
   1022     DEBUG ((DEBUG_ERROR, "SdCardIdentification: Selecting card fails with %r\n", Status));
   1023     return Status;
   1024   }
   1025 
   1026   Status = SdCardGetScr (PassThru, Slot, Rca, &Scr);
   1027   if (EFI_ERROR (Status)) {
   1028     DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardGetScr fails with %r\n", Status));
   1029     return Status;
   1030   }
   1031 
   1032   //
   1033   // Enter Data Tranfer Mode.
   1034   //
   1035   DEBUG ((DEBUG_INFO, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot));
   1036   Private->Slot[Slot].CardType = SdCardType;
   1037 
   1038   Status = SdCardSetBusMode (PciIo, PassThru, Slot, Rca, S18r, Scr.SdBusWidths);
   1039   if (EFI_ERROR (Status)) {
   1040     return Status;
   1041   }
   1042 
   1043   Private->Slot[Slot].Initialized = TRUE;
   1044 
   1045   return Status;
   1046 }
   1047