int F200001(TRUSERID *handle, int iRequest, ST_PACK *rPack, int *pRetCode, char *szMsg) { int ret = 0; CAccTrans& ats = CAccTrans::GetInst(); TRANS& trans = ats.trans; trans.termid = rPack->lwithdraw_flag; trans.cardno = rPack->lvol0; ats.SetCardCntAndCardBal(rPack->lvol5, rPack->lvol6, rPack->lvol7); // trans.transcode= rPack->lcert_code; ret = CheckCardStatus(); if(ret) { return ret; } T_t_cardtrans cardtrans; memset(&cardtrans, 0, sizeof(cardtrans)); ret = CardTransProcess(cardtrans); if(ret) { return ret; } ret = DoResponse(cardtrans, handle, pRetCode, szMsg); if(ret) { return ret; } return 0; }
/** Send command by using Host IO protocol @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance. @param CommandIndex The command index to set the command index field of command register. @param Argument Command argument to set the argument field of command register. @param DataType TRANSFER_TYPE, indicates no data, data in or data out. @param Buffer Contains the data read from / write to the device. @param BufferSize The size of the buffer. @param ResponseType RESPONSE_TYPE. @param TimeOut Time out value in 1 ms unit. @param ResponseData Depending on the ResponseType, such as CSD or card status. @retval EFI_SUCCESS @retval EFI_INVALID_PARAMETER @retval EFI_UNSUPPORTED @retval EFI_DEVICE_ERROR **/ EFI_STATUS SendCommand ( IN CARD_DATA *CardData, IN UINT16 CommandIndex, IN UINT32 Argument, IN TRANSFER_TYPE DataType, IN UINT8 *Buffer, OPTIONAL IN UINT32 BufferSize, IN RESPONSE_TYPE ResponseType, IN UINT32 TimeOut, OUT UINT32 *ResponseData ) { EFI_STATUS Status; EFI_SD_HOST_IO_PROTOCOL *SDHostIo; SDHostIo = CardData->SDHostIo; if (CardData->CardType != MMCCard && CardData->CardType != MMCCardHighCap) { CommandIndex |= AUTO_CMD12_ENABLE; } Status = SDHostIo->SendCommand ( SDHostIo, CommandIndex, Argument, DataType, Buffer, BufferSize, ResponseType, TimeOut, ResponseData ); if (!EFI_ERROR (Status)) { if (ResponseType == ResponseR1 || ResponseType == ResponseR1b) { ASSERT(ResponseData != NULL); Status = CheckCardStatus (*ResponseData); } } else { SDHostIo->ResetSDHost (SDHostIo, Reset_DAT_CMD); } return Status; }
/** Send command by using Host IO protocol @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance. @param CommandIndex The command index to set the command index field of command register. @param Argument Command argument to set the argument field of command register. @param DataType TRANSFER_TYPE, indicates no data, data in or data out. @param Buffer Contains the data read from / write to the device. @param BufferSize The size of the buffer. @param ResponseType RESPONSE_TYPE. @param TimeOut Time out value in 1 ms unit. @param ResponseData Depending on the ResponseType, such as CSD or card status. @retval EFI_SUCCESS @retval EFI_INVALID_PARAMETER @retval EFI_UNSUPPORTED @retval EFI_DEVICE_ERROR **/ EFI_STATUS SendCommand ( IN EFI_SD_HOST_IO_PROTOCOL *This, IN UINT16 CommandIndex, IN UINT32 Argument, IN TRANSFER_TYPE DataType, IN UINT8 *Buffer, OPTIONAL IN UINT32 BufferSize, IN RESPONSE_TYPE ResponseType, IN UINT32 TimeOut, OUT UINT32 *ResponseData ) { EFI_STATUS Status; Status = This->SendCommand ( This, CommandIndex, Argument, DataType, Buffer, BufferSize, ResponseType, TimeOut, ResponseData ); if (!EFI_ERROR (Status)) { if (ResponseType == ResponseR1 || ResponseType == ResponseR1b) { ASSERT(ResponseData != NULL); Status = CheckCardStatus (*ResponseData); } } else { This->ResetSDHost (This, Reset_DAT_CMD); } return Status; }
/** Send the card APP_CMD command with the following command indicated by CommandIndex @param CardData Pointer to CARD_DATA. @param CommandIndex The command index to set the command index field of command register. @param Argument Command argument to set the argument field of command register. @param DataType TRANSFER_TYPE, indicates no data, data in or data out. @param Buffer Contains the data read from / write to the device. @param BufferSize The size of the buffer. @param ResponseType RESPONSE_TYPE. @param TimeOut Time out value in 1 ms unit. @param ResponseData Depending on the ResponseType, such as CSD or card status. @retval EFI_SUCCESS @retval EFI_INVALID_PARAMETER @retval EFI_UNSUPPORTED @retval EFI_DEVICE_ERROR **/ EFI_STATUS SendAppCommand ( IN CARD_DATA *CardData, IN UINT16 CommandIndex, IN UINT32 Argument, IN TRANSFER_TYPE DataType, IN UINT8 *Buffer, OPTIONAL IN UINT32 BufferSize, IN RESPONSE_TYPE ResponseType, IN UINT32 TimeOut, OUT UINT32 *ResponseData ) { EFI_STATUS Status; EFI_SD_HOST_IO_PROTOCOL *SDHostIo; UINT8 Index; SDHostIo = CardData->SDHostIo; Status = EFI_SUCCESS; for (Index = 0; Index < 2; Index++) { Status = SDHostIo->SendCommand ( SDHostIo, APP_CMD, (CardData->Address << 16), NoData, NULL, 0, ResponseR1, TIMEOUT_COMMAND, (UINT32*)&(CardData->CardStatus) ); if (!EFI_ERROR (Status)) { Status = CheckCardStatus (*(UINT32*)&(CardData->CardStatus)); if (CardData->CardStatus.SAPP_CMD != 1) { Status = EFI_DEVICE_ERROR; } if (!EFI_ERROR (Status)) { break; } } else { SDHostIo->ResetSDHost (SDHostIo, Reset_Auto); } } if (EFI_ERROR (Status)) { return Status; } if (CardData->CardType != MMCCard && CardData->CardType != MMCCardHighCap) { CommandIndex |= AUTO_CMD12_ENABLE; } Status = SDHostIo->SendCommand ( SDHostIo, CommandIndex, Argument, DataType, Buffer, BufferSize, ResponseType, TimeOut, ResponseData ); if (!EFI_ERROR (Status)) { if (ResponseType == ResponseR1 || ResponseType == ResponseR1b) { ASSERT(ResponseData != NULL); Status = CheckCardStatus (*ResponseData); } } else { SDHostIo->ResetSDHost (SDHostIo, Reset_Auto); } return Status; }
/** MMC/SD card init function @param CardData Pointer to CARD_DATA. @return EFI_SUCCESS @return others **/ EFI_STATUS MMCSDCardInit ( IN CARD_DATA *CardData ) { EFI_STATUS Status; EFI_SD_HOST_IO_PROTOCOL *SDHostIo; SWITCH_ARGUMENT SwitchArgument; UINT32 Data; UINT32 Argument; UINT32 nIndex; UINT8 PowerValue; BOOLEAN EnableDDRMode; ASSERT(CardData != NULL); SDHostIo = CardData->SDHostIo; EnableDDRMode = FALSE; CardData->CardType = UnknownCard; Status = GetCardType (CardData); if (EFI_ERROR (Status)) { goto Exit; } DEBUG((DEBUG_INFO, "CardData->CardType 0x%x\n", CardData->CardType)); ASSERT (CardData->CardType != UnknownCard); // //MMC, SD card need host auto stop command support // SDHostIo->EnableAutoStopCmd (SDHostIo, TRUE); if (CardData->CardType == MMCCard) { Status = MMCCardVoltageSelection (CardData); if (EFI_ERROR(Status)) { goto Exit; } } // // Get CID Register // Status = SendCommand ( CardData, ALL_SEND_CID, 0, NoData, NULL, 0, ResponseR2, TIMEOUT_COMMAND, (UINT32*)&(CardData->CIDRegister) ); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "ALL_SEND_CID Fail Status = 0x%x\n", Status)); goto Exit; } else { // Dump out the Card ID data DEBUG((EFI_D_INFO, "Product Name: ")); for ( nIndex=0; nIndex<6; nIndex++ ) { DEBUG((EFI_D_INFO, "%c", CardData->CIDRegister.PNM[nIndex])); } DEBUG((EFI_D_INFO, "\nApplication ID : %d\n", CardData->CIDRegister.OID)); DEBUG((EFI_D_INFO, "Manufacturer ID: %d\n", CardData->CIDRegister.MID)); DEBUG((EFI_D_INFO, "Revision ID : %d\n", CardData->CIDRegister.PRV)); DEBUG((EFI_D_INFO, "Serial Number : %d\n", CardData->CIDRegister.PSN)); } // //SET_RELATIVE_ADDR // if (CardData->CardType == MMCCard || CardData->CardType == MMCCardHighCap) { // //Hard code the RCA address // CardData->Address = 1; // // Set RCA Register // Status = SendCommand ( CardData, SET_RELATIVE_ADDR, (CardData->Address << 16), NoData, NULL, 0, ResponseR1, TIMEOUT_COMMAND, (UINT32*)&(CardData->CardStatus) ); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status)); goto Exit; } } else { Data = 0; Status = SendCommand ( CardData, SET_RELATIVE_ADDR, 0, NoData, NULL, 0, ResponseR6, TIMEOUT_COMMAND, &Data ); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status)); goto Exit; } CardData->Address = (UINT16)(Data >> 16); *(UINT32*)&CardData->CardStatus = Data & 0x1FFF; CardData->CardStatus.ERROR = (Data >> 13) & 0x1; CardData->CardStatus.ILLEGAL_COMMAND = (Data >> 14) & 0x1; CardData->CardStatus.COM_CRC_ERROR = (Data >> 15) & 0x1; Status = CheckCardStatus (*(UINT32*)&CardData->CardStatus); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status)); goto Exit; } } // // Get CSD Register // Status = SendCommand ( CardData, SEND_CSD, (CardData->Address << 16), NoData, NULL, 0, ResponseR2, TIMEOUT_COMMAND, (UINT32*)&(CardData->CSDRegister) ); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "SEND_CSD Fail Status = 0x%x\n", Status)); goto Exit; } DEBUG((EFI_D_INFO, "CardData->CSDRegister.SPEC_VERS = 0x%x\n", CardData->CSDRegister.SPEC_VERS)); DEBUG((EFI_D_INFO, "CardData->CSDRegister.CSD_STRUCTURE = 0x%x\n", CardData->CSDRegister.CSD_STRUCTURE)); Status = CaculateCardParameter (CardData); if (EFI_ERROR (Status)) { goto Exit; } // // It is platform and hardware specific, need hadrware engineer input // if (CardData->CSDRegister.DSR_IMP == 1) { // // Default is 0x404 // Status = SendCommand ( CardData, SET_DSR, (DEFAULT_DSR_VALUE << 16), NoData, NULL, 0, ResponseNo, TIMEOUT_COMMAND, NULL ); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "SET_DSR Fail Status = 0x%x\n", Status)); // // Assume can operate even fail // } } // //Change clock frequency from 400KHz to max supported when not in high speed mode // Status = SDHostIo->SetClockFrequency (SDHostIo, CardData->MaxFrequency); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "MMCSDCardInit:Fail to SetClockFrequency \n")); goto Exit; } // //Put the card into tran state // Status = SendCommand ( CardData, SELECT_DESELECT_CARD, (CardData->Address << 16), NoData, NULL, 0, ResponseR1, TIMEOUT_COMMAND, (UINT32*)&(CardData->CardStatus) ); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "SELECT_DESELECT_CARD Fail Status = 0x%x\n", Status)); goto Exit; } // // No spec requirment, can be adjusted // gBS->Stall (5 * 1000); // // No need to do so // // Status = SendCommand ( CardData, SEND_STATUS, (CardData->Address << 16), NoData, NULL, 0, ResponseR1, TIMEOUT_COMMAND, (UINT32*)&(CardData->CardStatus) ); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "SELECT_DESELECT_CARD SEND_STATUS Fail Status = 0x%x\n", Status)); goto Exit; } // //if the SPEC_VERS indicates a version 4.0 or higher //The card is a high speed card and support Switch //and Send_ext_csd command //otherwise it is an old card // if (CardData->CardType == MMCCard || CardData->CardType == MMCCardHighCap) { // //Only V4.0 and above supports more than 1 bits and high speed // if (CardData->CSDRegister.SPEC_VERS >= 4) { // //Get ExtCSDRegister // Status = SendCommand ( CardData, SEND_EXT_CSD, 0x0, InData, CardData->AlignedBuffer, sizeof (EXT_CSD), ResponseR1, TIMEOUT_DATA, (UINT32*)&(CardData->CardStatus) ); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "SEND_EXT_CSD Fail Status = 0x%x\n", Status)); goto Exit; } CopyMem (&(CardData->ExtCSDRegister), CardData->AlignedBuffer, sizeof (EXT_CSD)); // // Recaculate the block number for >2G MMC card // Data = (CardData->ExtCSDRegister.SEC_COUNT[0]) | (CardData->ExtCSDRegister.SEC_COUNT[1] << 8) | (CardData->ExtCSDRegister.SEC_COUNT[2] << 16) | (CardData->ExtCSDRegister.SEC_COUNT[3] << 24); if (Data != 0) { CardData->BlockNumber = Data; } DEBUG((DEBUG_INFO, "CardData->BlockNumber %d\n", Data)); DEBUG((EFI_D_ERROR, "CardData->ExtCSDRegister.CARD_TYPE -> %d\n", (UINTN)CardData->ExtCSDRegister.CARD_TYPE)); if ((CardData->ExtCSDRegister.CARD_TYPE & BIT2)|| (CardData->ExtCSDRegister.CARD_TYPE & BIT3)) { //DEBUG((DEBUG_INFO, "To enable DDR mode\n")); //EnableDDRMode = TRUE; } // // Check current chipset capability and the plugged-in card // whether supports HighSpeed // if (SDHostIo->HostCapability.HighSpeedSupport) { // //Change card timing to high speed interface timing // ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT)); SwitchArgument.CmdSet = 0; SwitchArgument.Value = 1; SwitchArgument.Index = (UINT32)((UINTN) (&(CardData->ExtCSDRegister.HS_TIMING)) - (UINTN)(&(CardData->ExtCSDRegister))); SwitchArgument.Access = WriteByte_Mode; Status = SendCommand ( CardData, SWITCH, *(UINT32*)&SwitchArgument, NoData, NULL, 0, ResponseR1b, TIMEOUT_COMMAND, (UINT32*)&(CardData->CardStatus) ); if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "MMCSDCardInit:SWITCH frequency Fail Status = 0x%x\n", Status)); } gBS->Stall (5 * 1000); if (!EFI_ERROR (Status)) { Status = SendCommand ( CardData, SEND_STATUS, (CardData->Address << 16), NoData, NULL, 0, ResponseR1, TIMEOUT_COMMAND, (UINT32*)&(CardData->CardStatus) ); if (!EFI_ERROR (Status)) { if (EnableDDRMode) { DEBUG((EFI_D_ERROR, "Enable ddr mode on host controller\n")); SDHostIo->SetDDRMode (SDHostIo, TRUE); } else { DEBUG((EFI_D_ERROR, "Enable high speed mode on host controller\n")); SDHostIo->SetHighSpeedMode (SDHostIo, TRUE); } // // Change host clock to support high speed and enable chispet to // support speed // if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) { Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_MMC_PP_HIGH); } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) { Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_MMC_PP); } else { Status = EFI_UNSUPPORTED; } if (EFI_ERROR (Status)) { DEBUG((EFI_D_ERROR, "MMCSDCardInit:Fail to SetClockFrequency \n")); goto Exit; } // // It seems no need to stall after changing bus freqeuncy. // It is said that the freqeuncy can be changed at any time. Just appends 8 clocks after command. // But SetClock alreay has delay. // } } } // // Prefer wide bus width for performance // // // Set to BusWidth bits mode, only version 4.0 or above support more than 1 bits // if (SDHostIo->HostCapability.BusWidth8 == TRUE) { Status = MMCCardSetBusWidth (CardData, 8, EnableDDRMode); if (EFI_ERROR (Status)) { // // CE-ATA may support 8 bits and 4 bits, but has no software method for detection // Status = MMCCardSetBusWidth (CardData, 4, EnableDDRMode); if (EFI_ERROR (Status)) { goto Exit; } } } else if (SDHostIo->HostCapability.BusWidth4 == TRUE) { Status = MMCCardSetBusWidth (CardData, 4, EnableDDRMode); if (EFI_ERROR (Status)) { goto Exit; } } PowerValue = 0; if (CardData->CurrentBusWidth == 8) { if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) { PowerValue = CardData->ExtCSDRegister.PWR_CL_52_360; PowerValue = PowerValue >> 4; } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) { PowerValue = CardData->ExtCSDRegister.PWR_CL_26_360; PowerValue = PowerValue >> 4; }