static A_BOOL IssueSDCommand(SD_DEVICE_HANDLE hDevice, A_UINT8 Cmd, A_UINT32 Argument, SD_RESPONSE_TYPE ResponseType, SD_COMMAND_RESPONSE *pResponse) { SD_API_STATUS sdStatus; sdStatus = SDSynchronousBusRequest(hDevice, Cmd, Argument, SD_COMMAND, ResponseType, pResponse, 0, 0, NULL, 0); return SD_API_SUCCESS(sdStatus) ? TRUE : FALSE; }
/////////////////////////////////////////////////////////////////////////////// // SDMemDoBusRequest - Perform a bus request, returns Windows Status // Input: pMemCard - SD memory card structure // Command - SD command to send over bus // Argument - 32 bit argument specific to the command // TransferClass - Command only, or associated with read/write data // ResponseType - Response Type for the command // NumBlocks - Number of data blocks in pBlockArray, can be zero // if transfer class is not read or write // BlockSize - Size of data blocks in pBlockArray. All blocks // must be same size. // pBuffer - Pointer to buffer containing BlockSize*NumBlocks bytes // Flags // Output: // Return: standard win32 status code // Notes: This function performs an SD Bus Request and converts the SD status // of that transaction into a standard windows status code. /////////////////////////////////////////////////////////////////////////////// DWORD SDMemDoBusRequest( PSD_MEMCARD_INFO pMemcard, UCHAR Command, DWORD Argument, SD_TRANSFER_CLASS TransferClass, SD_RESPONSE_TYPE ResponseType, ULONG NumBlocks, ULONG BlockSize, PUCHAR pBuffer, DWORD Flags) { SD_API_STATUS RequestStatus; // intermediate status DEBUGMSG( SDMEM_ZONE_BUS_REQS, (TEXT("SDMemDoBusRequest: CMD%d Arg 0x%08X TransferClass %d NumBlocks %d BlockSize %d\r\n"), Command,Argument,TransferClass,NumBlocks,BlockSize)); // initiate the bus transaction RequestStatus = SDSynchronousBusRequest( pMemcard->hDevice, Command, Argument, TransferClass, ResponseType, NULL, NumBlocks, BlockSize, pBuffer, Flags); // get the status and convert if necessary if (!SD_API_SUCCESS(RequestStatus)) { DEBUGMSG( SDCARD_ZONE_ERROR, (TEXT("SDMemDoBusRequest Failed: CMD%d returned API status 0x%X\r\n"), Command,RequestStatus)); return SDAPIStatusToErrorCode(RequestStatus); } // everything was OK, return success return ERROR_SUCCESS; }
A_STATUS HIFReadWrite(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length, HIF_REQUEST *request, void *context) { A_UINT8 rw; A_UINT8 mode; A_UINT8 opcode; A_UINT32 blockLen, blockCount, count; PSD_BUS_REQUEST busRequest; A_STATUS status = A_OK; SD_TRANSFER_CLASS transferClass; DWORD dwArg; A_UCHAR command; SD_API_STATUS sdStatus; SD_COMMAND_RESPONSE response; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "HIFReadWrite:Enter\n"); HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Address 0x%x\n", address); if (request->dmode == HIF_BLOCK_BASIS && request->type != HIF_EXTENDED_IO) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "Block mode not allowed for this type of command\n"); return A_ERROR; } if (request->dmode == HIF_BLOCK_BASIS) { mode = SD_IO_BLOCK_MODE; blockLen = HIF_MBOX_BLOCK_SIZE; blockCount = length / HIF_MBOX_BLOCK_SIZE; count = blockCount; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Block mode (BlockLen: %d, BlockCount: %d)\n", blockLen, blockCount); } else if (request->dmode == HIF_BYTE_BASIS) { mode = SD_IO_BYTE_MODE; blockLen = length; blockCount = 1; count = blockLen; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Byte mode (BlockLen: %d, BlockCount: %d)\n", blockLen, blockCount); } else { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "Invalid data mode: %d\n", request->dmode); return A_ERROR; } if (request->amode == HIF_FIXED_ADDRESS) { opcode = SD_IO_FIXED_ADDRESS; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Fixed "); } else if (request->amode == HIF_INCREMENTAL_ADDRESS) { opcode = SD_IO_INCREMENT_ADDRESS; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Incremental "); } else { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "Invalid address mode: %d\n", request->amode); return A_ERROR; } if (request->direction == HIF_WRITE) { transferClass = SD_WRITE; rw = SD_IO_OP_WRITE; if ((address >= HIF_MBOX_START_ADDR(0)) && (address <= HIF_MBOX_END_ADDR(3))) { /* Mailbox write. Adjust the address so that the last byte falls on the EOM address */ address = address + HIF_MBOX_WIDTH - length; } HIF_DEBUG_PRINTF(ATH_LOG_TRC, "[Write]"); } else { transferClass = SD_READ; rw = SD_IO_OP_READ; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "[Read ]"); } if (request->type == HIF_EXTENDED_IO) { dwArg = BUILD_IO_RW_EXTENDED_ARG(rw, mode, funcNo, address, opcode, count); command = SD_IO_RW_EXTENDED; } else if (request->type == HIF_BASIC_IO) { dwArg = BUILD_IO_RW_DIRECT_ARG(rw, SD_IO_RW_NORMAL, funcNo, address, 0); command = SD_IO_RW_NORMAL; } else { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "Invalid command type: %d\n", request->type); return A_ERROR; } if (request->emode == HIF_SYNCHRONOUS) { HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Synchronous\n"); sdStatus = SDSynchronousBusRequest(device->handle, command, dwArg, transferClass, ResponseR5, &response, blockCount, blockLen, buffer, 0); if (!SD_API_SUCCESS(sdStatus)) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "SDBusRequest failed 0x%x\n", sdStatus); status = A_ERROR; } } else { HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Asynchronous\n"); sdStatus = SDBusRequest(device->handle, command, dwArg, transferClass, ResponseR5, blockCount, blockLen, buffer, hifRWCompletionHandler, (DWORD) context, &busRequest, 0); if (!SD_API_SUCCESS(sdStatus)) { status = A_ERROR; } } return status; }
/////////////////////////////////////////////////////////////////////////////// // IssueCardSelectDeSelect - issue card select // Input: pMemCard - memory card instance // Select - select the card // Output: // Return: SD_API_STATUS code // Notes: /////////////////////////////////////////////////////////////////////////////// SD_API_STATUS IssueCardSelectDeSelect(PSD_MEMCARD_INFO pMemCard, BOOL Select) { USHORT relativeAddress; // relative address SD_RESPONSE_TYPE responseType; // expected response SD_API_STATUS status; // intermediate status int retryCount; // retryCount; SD_CARD_STATUS cardStatus; // card status if (Select) { // using the cards original address selects the card again relativeAddress = pMemCard->RCA; DEBUG_CHECK((relativeAddress != 0), (TEXT("IssueCardSelectDeSelect - Relative address is zero! \n"))); // the selected card should return a response responseType = ResponseR1b; } else { // address of zero deselects the card relativeAddress = 0; // according to the spec no response will be returned responseType = NoResponse; } retryCount = DEFAULT_DESELECT_RETRY_COUNT; while (retryCount) { status = SDSynchronousBusRequest(pMemCard->hDevice, SD_CMD_SELECT_DESELECT_CARD, ((DWORD)relativeAddress) << 16, SD_COMMAND, responseType, NULL, 0, 0, NULL, 0); if (!SD_API_SUCCESS(status)) { break; } if (!Select) { // if we deselected, get the card status and check for // standby state status = SDCardInfoQuery(pMemCard->hDevice, SD_INFO_CARD_STATUS, &cardStatus, sizeof(SD_CARD_STATUS)); if (!SD_API_SUCCESS(status)){ break; } if (SD_STATUS_CURRENT_STATE(cardStatus) == SD_STATUS_CURRENT_STATE_STDBY) { DEBUGMSG(SDMEM_ZONE_POWER, (TEXT("SDMemory: Card now in Standby \n"))); break; } else { DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDMemory: Card not in standby! Card Status: 0x%08X \n") , cardStatus)); // set unusuccessful for retry status = SD_API_STATUS_UNSUCCESSFUL; } retryCount--; } else { DEBUGMSG(SDMEM_ZONE_POWER, (TEXT("SDMemory: Card now in Transfer state \n"))); break; } } return status; }
static A_STATUS __HIFReadWrite(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length, A_UINT32 request, void *context) { A_UINT8 rw; A_UINT8 mode; A_UINT8 opcode; A_UINT32 blockLen, blockCount, count; PSD_BUS_REQUEST busRequest=NULL; A_STATUS status = A_OK; SD_TRANSFER_CLASS transferClass; DWORD dwArg; A_UCHAR command; SD_API_STATUS sdStatus; SD_COMMAND_RESPONSE response; NDIS_DEBUG_PRINTF(0, "%s() : Enter \r\n",__FUNCTION__); if(context != NULL) NDIS_DEBUG_PRINTF(0, "%s() : context = 0x%08x \r\n", __FUNCTION__,context); if ((request & HIF_BLOCK_BASIS) && (!(request & HIF_EXTENDED_IO))) { NDIS_DEBUG_PRINTF(DBG_ERR, "Block mode not allowed for this type of command\r\n"); return A_ERROR; } if (request & HIF_BLOCK_BASIS) { mode = SD_IO_BLOCK_MODE; blockLen = HIF_MBOX_BLOCK_SIZE; blockCount = length / HIF_MBOX_BLOCK_SIZE; count = blockCount; } else if (request & HIF_BYTE_BASIS) { mode = SD_IO_BYTE_MODE; blockLen = length; blockCount = 1; count = blockLen; } else { NDIS_DEBUG_PRINTF(DBG_ERR, "Invalid data mode: %08x\r\n", request); return A_ERROR; } if (request & HIF_FIXED_ADDRESS) { opcode = SD_IO_FIXED_ADDRESS; NDIS_DEBUG_PRINTF(DBG_TRACE, "Fixed "); } else if (request & HIF_INCREMENTAL_ADDRESS) { opcode = SD_IO_INCREMENT_ADDRESS; NDIS_DEBUG_PRINTF(0, "Incremental "); } else { NDIS_DEBUG_PRINTF(DBG_ERR, "Invalid address mode: %08x\r\n", request); return A_ERROR; } if (request & HIF_WRITE) { transferClass = SD_WRITE; rw = SD_IO_OP_WRITE; if ((address >= HIF_MBOX_START_ADDR(0)) && (address <= HIF_MBOX_END_ADDR(3))) { /* Mailbox write. Adjust the address so that the last byte falls on the EOM address */ address = address + HIF_MBOX_WIDTH - length; } NDIS_DEBUG_PRINTF(0, "[Write]"); } else { transferClass = SD_READ; rw = SD_IO_OP_READ; NDIS_DEBUG_PRINTF(0, "[Read ] \r\n"); } if (request & HIF_EXTENDED_IO) { dwArg = BUILD_IO_RW_EXTENDED_ARG(rw, mode, funcNo, address, opcode, count); command = SD_IO_RW_EXTENDED; } else if (request & HIF_BASIC_IO) { dwArg = BUILD_IO_RW_DIRECT_ARG(rw, SD_IO_RW_NORMAL, funcNo, address, 0); command = SD_IO_RW_NORMAL; } else { NDIS_DEBUG_PRINTF(DBG_ERR, "Invalid command type: %08x\r\n", request); return A_ERROR; } if((request & HIF_READ) && (dwArg > 0x14000000)) { NDIS_DEBUG_PRINTF(DBG_TRACE, "Synchronous, command = %d, dwArg = 0x%08x, funcNo=%d \r\n", command, dwArg,funcNo); NDIS_DEBUG_PRINTF(0, "blockCount=%d,blockLen=%d \r\n", blockCount, blockLen); } sdStatus = SDSynchronousBusRequest(device->handle, command, dwArg, transferClass, ResponseR5, &response, blockCount, blockLen, buffer, 0); if (!SD_API_SUCCESS(sdStatus)) { NDIS_DEBUG_PRINTF(DBG_ERR, "SDBusRequest failed 0x%x, device->handle = 0x%x, buffer = 0x%x\r\n", sdStatus, device->handle, buffer); NDIS_DEBUG_PRINTF(DBG_ERR, "1[%d]2[%d]3[%d]4[%d]5[%d]6[%d] \r\n",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5]); status = A_ERROR; } if(status != A_OK) NDIS_DEBUG_PRINTF(DBG_ERR, "%s() : Status = %d - Exit \r\n",__FUNCTION__, status); return status; }