/////////////////////////////////////////////////////////////////////////////// // SDMemCalcDataAccessClocks - Calculate the data access clocks // Input: pMemCard - the memcard // Output: pReadAccessClocks - Pointer to ULONG for read access clocks // pWriteAccessClocks - Pointer to ULONG for write access clocks // Return: TRUE or FALSE to indicate function success/failure // Notes: Calculate data access times for memory devices. This calculation // is to fine tune the data delay time /////////////////////////////////////////////////////////////////////////////// BOOL SDMemCalcDataAccessClocks(PSD_MEMCARD_INFO pMemCard, PULONG pReadAccessClocks, PULONG pWriteAccessClocks) { SD_CARD_INTERFACE cardInterface; // current card interface SD_API_STATUS status; // intermediate status DOUBLE clockPeriodNs; // clock period in nano seconds ULONG asyncClocks; // clocks required for the async portion // fetch the card clock rate status = SDCardInfoQuery(pMemCard->hDevice, SD_INFO_CARD_INTERFACE, &cardInterface, sizeof(cardInterface)); if(!SD_API_SUCCESS(status)) { DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDMemCalcDataAccessClocks: Can't get card interface info\r\n"))); return FALSE; } if(0 == cardInterface.ClockRate) { DEBUGCHK(FALSE); return FALSE; } // if the clock rate is greater than 1 Ghz, this won't work if(cardInterface.ClockRate > 1000000000) { DEBUGCHK(FALSE); return FALSE; } // calculate the clock period in nano seconds, clock rate is in Hz clockPeriodNs = 1000000000 / cardInterface.ClockRate; // calculate the async portion now that we know the clock rate // make asyncClock an integer asyncClocks = (ULONG)(pMemCard->CSDRegister.DataAccessTime.TAAC / clockPeriodNs); // add the async and synchronous portions together for the read access *pReadAccessClocks = asyncClocks + pMemCard->CSDRegister.DataAccessTime.NSAC; // for the write access the clocks area multiple of the read clocks *pWriteAccessClocks = (*pReadAccessClocks) * pMemCard->CSDRegister.WriteSpeedFactor; DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemCalcDataAccessClocks: Tpd:%f ns, Asynch: %f ns, AsyncClocks:%d , SyncClocks: %d, ReadTotal: %d, Write Factor: %d WriteTotal: %d \n"), clockPeriodNs, pMemCard->CSDRegister.DataAccessTime.TAAC, asyncClocks, pMemCard->CSDRegister.DataAccessTime.NSAC, *pReadAccessClocks, pMemCard->CSDRegister.WriteSpeedFactor, *pWriteAccessClocks)); return TRUE; }
/////////////////////////////////////////////////////////////////////////////// // SDGetCardStatus - Get the current card status // Input: pMemCard - SD memory card structure // // Output: pCardStatus - card status // Return: win32 status code // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SDGetCardStatus(PSD_MEMCARD_INFO pMemCard , SD_CARD_STATUS *pCardStatus) { SD_API_STATUS status; // api status status = SDCardInfoQuery(pMemCard->hDevice, SD_INFO_CARD_STATUS, pCardStatus, sizeof(SD_CARD_STATUS)); if (!SD_API_SUCCESS(status)){ return SDAPIStatusToErrorCode(status); } return ERROR_SUCCESS; }
BOOL hifDeviceInserted(SD_DEVICE_HANDLE *handle) { HIF_DEVICE *device; SD_API_STATUS sdStatus; SDIO_CARD_INFO sdioInfo; SD_HOST_BLOCK_CAPABILITY blockCap; SD_CARD_RCA cardRCA; A_UCHAR rgucTuple[SD_CISTPLE_MAX_BODY_SIZE]; PSD_CISTPL_FUNCE_FUNCTION pFunce = (PSD_CISTPL_FUNCE_FUNCTION) rgucTuple; A_UINT32 ulLength = 0; A_UCHAR ucRegVal; A_BOOL blockMode; SD_CARD_INTERFACE ci; SD_IO_FUNCTION_ENABLE_INFO fData; DWORD bData; //SDCONFIG_FUNC_SLOT_CURRENT_DATA slotCurrent; #ifdef CEPC HANDLE hThread; #endif //CEPC device = addHifDevice(handle); HIF_DEBUG_PRINTF(ATH_LOG_TRC, "hifDeviceInserted: Enter\n"); /* Enable SDIO [dragon] function */ fData.Interval = DEFAULT_SDIO_FUNCTION_RETRY_TIMEOUT; fData.ReadyRetryCount = DEFAULT_SDIO_FUNCTION_RETRIES; sdStatus = SDSetCardFeature (handle, SD_IO_FUNCTION_ENABLE, &fData, sizeof(fData)); if (!SD_API_SUCCESS(sdStatus)) { return FALSE; } /* * Issue commands to get the manufacturer ID and stuff and compare it * against the rev Id derived from the ID registered during the * initialization process. Report the device only in the case there * is a match. */ sdStatus = SDCardInfoQuery(handle, SD_INFO_SDIO, &sdioInfo, sizeof(sdioInfo)); if (!SD_API_SUCCESS(sdStatus)) { return FALSE; } funcNo = sdioInfo.FunctionNumber; sdStatus = SDCardInfoQuery(handle, SD_INFO_REGISTER_RCA, &cardRCA, sizeof(cardRCA)); HIF_DEBUG_PRINTF(ATH_LOG_INF, "Card RCA is 0x%x\n", cardRCA); /* Configure the SDIO Bus Width */ memset(&ci, 0, sizeof(ci)); if (sdio1bitmode) { ci.InterfaceMode = SD_INTERFACE_SD_MMC_1BIT; } else { ci.InterfaceMode = SD_INTERFACE_SD_4BIT; } if (sdiobusspeedlow) { ci.ClockRate = SDIO_CLOCK_FREQUENCY_REDUCED; } else { ci.ClockRate = SDIO_CLOCK_FREQUENCY_DEFAULT; } sdStatus = SDSetCardFeature(handle, SD_SET_CARD_INTERFACE, &ci, sizeof(ci)); if (!SD_API_SUCCESS(sdStatus)) { return FALSE; } /* Check if the target supports block mode */ sdStatus = SDReadWriteRegistersDirect(handle, SD_IO_READ, 0, 0x08, FALSE, &ucRegVal, 1); if (!SD_API_SUCCESS(sdStatus)) { return FALSE; } blockMode = (ucRegVal & 0x2) >> 1; // SMB is bit 1 if (!blockMode) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "Function does not support block mode\n"); return FALSE; } else { HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Function supports block mode\n"); blockCap.ReadBlocks = blockCap.WriteBlocks = 8; blockCap.ReadBlockSize = blockCap.WriteBlockSize = HIF_MBOX_BLOCK_SIZE; sdStatus = SDCardInfoQuery(handle, SD_INFO_HOST_BLOCK_CAPABILITY, &blockCap, sizeof(blockCap)); if (blockCap.ReadBlockSize < blockCap.WriteBlockSize) { maxBlockSize = blockCap.ReadBlockSize; } else { maxBlockSize = blockCap.WriteBlockSize; } if (blockCap.ReadBlocks < blockCap.WriteBlocks) { maxBlocks = blockCap.ReadBlocks; } else { maxBlocks = blockCap.WriteBlocks; } sdStatus = SDGetTuple(handle, SD_CISTPL_FUNCE, NULL, &ulLength, FALSE); if ((!SD_API_SUCCESS(sdStatus)) || (ulLength > sizeof(rgucTuple)) ) { return FALSE; } sdStatus = SDGetTuple(handle, SD_CISTPL_FUNCE, rgucTuple, &ulLength, FALSE); if ((!SD_API_SUCCESS(sdStatus)) || (pFunce->bType != SD_CISTPL_FUNCE_FUNCTION_TYPE) ) { return FALSE; } if (maxBlockSize > pFunce->wMaxBlkSize) { maxBlockSize = pFunce->wMaxBlkSize; } bData = (DWORD)maxBlockSize; sdStatus = SDSetCardFeature(handle, SD_IO_FUNCTION_SET_BLOCK_SIZE, &bData, sizeof(bData)); } HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Bytes Per Block: %d bytes, Block Count:%d \n", maxBlockSize, maxBlocks); /* Allocate the slot current */ /* Kowsalya : commenting as there is no equivalent for this in WINCE */ /* status = SDLIB_GetDefaultOpCurrent(handle, &slotCurrent.SlotCurrent); if (SDIO_SUCCESS(status)) { HIF_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Allocating Slot current: %d mA\n", slotCurrent.SlotCurrent)); status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_ALLOC_SLOT_CURRENT, &slotCurrent, sizeof(slotCurrent)); if (!SDIO_SUCCESS(status)) { HIF_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Failed to allocate slot current %d\n", status)); return FALSE; } } */ /* Inform HTC */ if ((htcCallbacks.deviceInsertedHandler(device)) != A_OK) { HIF_DEBUG_PRINTF(ATH_LOG_TRC, "Device rejected\n"); return FALSE; } #ifdef CEPC NdisInitializeEvent(&hifIRQEvent); hThread = CreateThread(NULL, 0, hifIRQThread, (LPVOID)handle, 0, NULL); CeSetThreadPriority(hThread, 200); CloseHandle(hThread); #endif //CEPC return TRUE; }
/////////////////////////////////////////////////////////////////////////////// // SDMemCardConfig - Initialise the memcard structure and card itself // Input: pMemCard - SD memory card structure // Output: // Return: win32 status code // Notes: /////////////////////////////////////////////////////////////////////////////// DWORD SDMemCardConfig( PSD_MEMCARD_INFO pMemCard ) { DWORD status = ERROR_SUCCESS; // intermediate win32 status DWORD dwSDHC; // high capacity value SD_API_STATUS apiStatus; // intermediate SD API status SD_CARD_INTERFACE cardInterface; // card interface SD_DATA_TRANSFER_CLOCKS dataTransferClocks; // data transfer clocks // retrieve CID Register contents apiStatus = SDCardInfoQuery( pMemCard->hDevice, SD_INFO_REGISTER_CID, &(pMemCard->CIDRegister), sizeof(SD_PARSED_REGISTER_CID) ); if(!SD_API_SUCCESS(apiStatus)) { DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDMemCardConfig: Can't read CID Register\r\n"))); return ERROR_GEN_FAILURE; } // Retrieve CSD Register contents apiStatus = SDCardInfoQuery( pMemCard->hDevice, SD_INFO_REGISTER_CSD, &(pMemCard->CSDRegister), sizeof(SD_PARSED_REGISTER_CSD) ); if(!SD_API_SUCCESS(apiStatus)) { DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDMemCardConfig: Can't read CSD Register\r\n"))); return ERROR_GEN_FAILURE; } // retreive the card's RCA apiStatus = SDCardInfoQuery(pMemCard->hDevice, SD_INFO_REGISTER_RCA, &(pMemCard->RCA), sizeof(pMemCard->RCA)); if(!SD_API_SUCCESS(apiStatus)) { DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDMemCardConfig: Can't read RCA \r\n"))); return ERROR_GEN_FAILURE; } // get write protect state apiStatus = SDCardInfoQuery( pMemCard->hDevice, SD_INFO_CARD_INTERFACE, &cardInterface, sizeof(cardInterface)); if(!SD_API_SUCCESS(apiStatus)) { DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDMemCardConfig: Can't read Card Interface\r\n"))); return ERROR_GEN_FAILURE; } // Get write protect state from Card Interface structure pMemCard->WriteProtected = cardInterface.WriteProtected; if( pMemCard->WriteProtected ) { DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemCardConfig: Card is write protected\r\n"))); } // get capacity information apiStatus = SDCardInfoQuery( pMemCard->hDevice, SD_INFO_HIGH_CAPACITY_SUPPORT, &dwSDHC, sizeof(dwSDHC)); if(!SD_API_SUCCESS(apiStatus)) { pMemCard->HighCapacity = FALSE; } else { pMemCard->HighCapacity = dwSDHC != 0; } if( pMemCard->HighCapacity ) { DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemCardConfig: Card is high capacity (2.0+)\r\n"))); } // If the card doesn't support block reads, then fail if (!(pMemCard->CSDRegister.CardCommandClasses & SD_CSD_CCC_BLOCK_READ)) { DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDMemCardConfig: Card does not support block read\r\n"))); return ERROR_BAD_DEVICE; } // If the card doesn't support block writes, then mark the card as // write protected if (!(pMemCard->CSDRegister.CardCommandClasses & SD_CSD_CCC_BLOCK_WRITE)) { DEBUGMSG(SDCARD_ZONE_INIT || SDCARD_ZONE_WARN, (TEXT("SDMemCardConfig: Card does not support block write; mark as WP\r\n"))); pMemCard->WriteProtected = TRUE; } // Calculate read and write data access clocks to fine tune access times if( !SDMemCalcDataAccessClocks( pMemCard, &dataTransferClocks.ReadClocks, &dataTransferClocks.WriteClocks) ) { DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDMemCardConfig: Unable to calculate data access clocks\r\n"))); return ERROR_GEN_FAILURE; } // Call API to set the read and write data access clocks apiStatus = SDSetCardFeature( pMemCard->hDevice, SD_SET_DATA_TRANSFER_CLOCKS, &dataTransferClocks, sizeof(dataTransferClocks)); if(!SD_API_SUCCESS(apiStatus)) { DEBUGMSG(SDCARD_ZONE_ERROR,(TEXT("SDMemCardConfig: Can't set data access clocks\r\n"))); return ERROR_GEN_FAILURE; } // FATFS only supports 512 bytes per sector so set that pMemCard->DiskInfo.di_bytes_per_sect = SD_BLOCK_SIZE; // indicate that we aren't using Cylinder/Head/Sector addressing, // and that reads and writes are synchronous. pMemCard->DiskInfo.di_flags = DISK_INFO_FLAG_CHS_UNCERTAIN | DISK_INFO_FLAG_PAGEABLE; // since we aren't using C/H/S addressing we can set the counts of these // items to zero pMemCard->DiskInfo.di_cylinders = 0; pMemCard->DiskInfo.di_heads = 0; pMemCard->DiskInfo.di_sectors = 0; // Work out whether we have a Master Boot Record switch( pMemCard->CSDRegister.FileSystem ) { case SD_FS_FAT_PARTITION_TABLE: // yes, we have a MBR pMemCard->DiskInfo.di_flags |= DISK_INFO_FLAG_MBR; break; case SD_FS_FAT_NO_PARTITION_TABLE: // no, we don't have a MBR break; default: // ee don't do "Other" file systems DEBUGMSG( SDCARD_ZONE_ERROR, (TEXT("SDMemCardConfig: Card indicates unsupported file system (non FAT)\r\n"))); return ERROR_GEN_FAILURE; } // calculate total number of sectors on the card // // NOTE:The bus is only using BLOCK units instead of BYTE units if // the device type is SD (not MMC) and if the CSDVersion is SD_CSD_VERSION_CODE_2_0. // Since we don't have access to the device type, we are checking to see if it is // a high definition card. This should work for most cases. // if( pMemCard->CSDRegister.CSDVersion == SD_CSD_VERSION_CODE_2_0 && pMemCard->HighCapacity ) { pMemCard->DiskInfo.di_total_sectors = pMemCard->CSDRegister.DeviceSize; #ifdef _MMC_SPEC_42_ // Date : 07.05.14 // Developer : HS.JANG // Description : If MMC card is on SPEC42 } else if (pMemCard->CSDRegister.SpecVersion >= HSMMC_CSD_SPEC_VERSION_CODE_SUPPORTED ) { #ifdef _FOR_MOVI_NAND_ // Date : 07.05.28 // Developer : HS.JANG // Description : There is no way to distinguish between HSMMC // and moviNAND. So, We assume that All HSMMC // card is the moviNAND pMemCard->IsHSMMC = TRUE; #endif if( (signed)(pMemCard->CSDRegister.SectorCount) > 0) { RETAILMSG(1,(TEXT("[HSMMC] This MMC card is on SPEC42.\n"))); pMemCard->DiskInfo.di_total_sectors = pMemCard->CSDRegister.SectorCount; pMemCard->HighCapacity = TRUE; } else { pMemCard->DiskInfo.di_total_sectors = pMemCard->CSDRegister.DeviceSize/SD_BLOCK_SIZE; } #endif } else { pMemCard->DiskInfo.di_total_sectors = pMemCard->CSDRegister.DeviceSize/SD_BLOCK_SIZE; } // FATFS and the SD Memory file spec only supports 512 byte sectors. An SD Memory // card will ALWAYS allow us to read and write in 512 byte blocks - but it might // be configured for a larger size initially. We set the size to 512 bytes here if needed. if( pMemCard->CSDRegister.MaxReadBlockLength != SD_BLOCK_SIZE ) { // Set block length to 512 bytes status = SDMemSetBlockLen( pMemCard, SD_BLOCK_SIZE ); } 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; }
BOOL hifDeviceInserted(SD_DEVICE_HANDLE *handle) { HIF_DEVICE *device; #if 0 SD_API_STATUS sdStatus; SDIO_CARD_INFO sdioInfo; SD_HOST_BLOCK_CAPABILITY blockCap; SD_CARD_RCA cardRCA; A_UCHAR rgucTuple[SD_CISTPLE_MAX_BODY_SIZE]; PSD_CISTPL_FUNCE_FUNCTION pFunce = (PSD_CISTPL_FUNCE_FUNCTION) rgucTuple; A_UINT32 ulLength = 0; A_UCHAR ucRegVal; A_BOOL blockMode; SD_CARD_INTERFACE ci; SD_IO_FUNCTION_ENABLE_INFO fData; DWORD bData; //SDCONFIG_FUNC_SLOT_CURRENT_DATA slotCurrent; //HANDLE hIrqThread; #endif HANDLE hThread; device = addHifDevice(handle); NDIS_DEBUG_PRINTF(1, "hifDeviceInserted: Enter\r\n"); #if 0 /* Enable SDIO [dragon] function */ fData.Interval = DEFAULT_SDIO_FUNCTION_RETRY_TIMEOUT; fData.ReadyRetryCount = DEFAULT_SDIO_FUNCTION_RETRIES; sdStatus = SDSetCardFeature (handle, SD_IO_FUNCTION_ENABLE, &fData, sizeof(fData)); if (!SD_API_SUCCESS(sdStatus)) { return FALSE; } /* * Issue commands to get the manufacturer ID and stuff and compare it * against the rev Id derived from the ID registered during the * initialization process. Report the device only in the case there * is a match. */ sdStatus = SDCardInfoQuery(handle, SD_INFO_SDIO, &sdioInfo, sizeof(sdioInfo)); if (!SD_API_SUCCESS(sdStatus)) { return FALSE; } funcNo = sdioInfo.FunctionNumber; sdStatus = SDCardInfoQuery(handle, SD_INFO_REGISTER_RCA, &cardRCA, sizeof(cardRCA)); NDIS_DEBUG_PRINTF(1, " Card RCA is 0x%x \r\n", cardRCA); /* Configure the SDIO Bus Width */ memset(&ci, 0, sizeof(ci)); if (sdio1bitmode) { ci.InterfaceMode = SD_INTERFACE_SD_MMC_1BIT; } else { ci.InterfaceMode = SD_INTERFACE_SD_4BIT; } if (sdiobusspeedlow) { ci.ClockRate = SDIO_CLOCK_FREQUENCY_REDUCED; } else { ci.ClockRate = SDIO_CLOCK_FREQUENCY_DEFAULT; } sdStatus = SDSetCardFeature(handle, SD_SET_CARD_INTERFACE, &ci, sizeof(ci)); if (!SD_API_SUCCESS(sdStatus)) { return FALSE; } /* Check if the target supports block mode */ sdStatus = SDReadWriteRegistersDirect(handle, SD_IO_READ, 0, 0x08, FALSE, &ucRegVal, 1); if (!SD_API_SUCCESS(sdStatus)) { return FALSE; } blockMode = (ucRegVal & 0x2) >> 1; // SMB is bit 1 if (!blockMode) { NDIS_DEBUG_PRINTF(DBG_ERR, "[HIF] Function does not support block mode \r\n"); return FALSE; } else { NDIS_DEBUG_PRINTF(DBG_LEVEL_HIF, "[HIF] Function supports block mode \r\n"); blockCap.ReadBlocks = blockCap.WriteBlocks = 8; blockCap.ReadBlockSize = blockCap.WriteBlockSize = HIF_MBOX_BLOCK_SIZE; sdStatus = SDCardInfoQuery(handle, SD_INFO_HOST_BLOCK_CAPABILITY, &blockCap, sizeof(blockCap)); if (blockCap.ReadBlockSize < blockCap.WriteBlockSize) { maxBlockSize = blockCap.ReadBlockSize; } else { maxBlockSize = blockCap.WriteBlockSize; } if (blockCap.ReadBlocks < blockCap.WriteBlocks) { maxBlocks = blockCap.ReadBlocks; } else { maxBlocks = blockCap.WriteBlocks; } sdStatus = SDGetTuple(handle, SD_CISTPL_FUNCE, NULL, &ulLength, FALSE); if ((!SD_API_SUCCESS(sdStatus)) || (ulLength > sizeof(rgucTuple)) ) { return FALSE; } sdStatus = SDGetTuple(handle, SD_CISTPL_FUNCE, rgucTuple, &ulLength, FALSE); if ((!SD_API_SUCCESS(sdStatus)) || (pFunce->bType != SD_CISTPL_FUNCE_FUNCTION_TYPE) ) { return FALSE; } if (maxBlockSize > pFunce->wMaxBlkSize) { maxBlockSize = pFunce->wMaxBlkSize; } bData = (DWORD)maxBlockSize; sdStatus = SDSetCardFeature(handle, SD_IO_FUNCTION_SET_BLOCK_SIZE, &bData, sizeof(bData)); } NDIS_DEBUG_PRINTF(DBG_LEVEL_HIF, "Bytes Per Block: %d bytes, Block Count:%d \r\n", maxBlockSize, maxBlocks); /* Allocate the slot current */ /* Kowsalya : commenting as there is no equivalent for this in WINCE */ /* status = SDLIB_GetDefaultOpCurrent(handle, &slotCurrent.SlotCurrent); if (SDIO_SUCCESS(status)) { HIF_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("Allocating Slot current: %d mA\n", slotCurrent.SlotCurrent)); status = SDLIB_IssueConfig(handle, SDCONFIG_FUNC_ALLOC_SLOT_CURRENT, &slotCurrent, sizeof(slotCurrent)); if (!SDIO_SUCCESS(status)) { HIF_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Failed to allocate slot current %d\n", status)); return FALSE; } } */ /* Initialize the bus requests to be used later */ A_MEMZERO(device->busRequest, sizeof(device->busRequest)); for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) { NdisInitializeEvent(&device->busRequest[count].sem_req); hifFreeBusRequest(device, &device->busRequest[count]); } #else SetupSlotPowerControl(device); if (!SetupSDIOInterface(device)) { return FALSE; } #endif InitializeCriticalSection(&gCriticalSection); //ÃʱâÈ device->async_shutdown = 0; hThread = CreateThread(NULL, 0, async_task, (void *)device, 0, NULL); CeSetThreadPriority(hThread, 200); CloseHandle(hThread); NdisInitializeEvent(&device->sem_async); #if USE_IRQ_THREAD hThread = CreateThread(NULL, 0, hifIRQThread, (void *)device, 0, NULL); CeSetThreadPriority(hThread, 200); CloseHandle(hThread); NdisInitializeEvent(&hifIRQEvent); #endif /* start up inform DRV layer */ if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != A_OK) { NDIS_DEBUG_PRINTF(DBG_ERR, "[HIF] AR6000: Device rejected \r\n"); } NDIS_DEBUG_PRINTF(DBG_LEVEL_HIF, " %s() -Exit \r\n",__FUNCTION__); return TRUE; }
static BOOL SetupSDIOInterface(HIF_DEVICE *device) { SD_API_STATUS sdStatus; SDIO_CARD_INFO sdioInfo; SD_HOST_BLOCK_CAPABILITY blockCap; SD_CARD_RCA cardRCA; A_UCHAR rgucTuple[SD_CISTPLE_MAX_BODY_SIZE]; PSD_CISTPL_FUNCE_FUNCTION pFunce = (PSD_CISTPL_FUNCE_FUNCTION) rgucTuple; A_UINT32 ulLength = 0; A_UCHAR ucRegVal; A_BOOL blockMode; SD_CARD_INTERFACE ci; SD_IO_FUNCTION_ENABLE_INFO fData; DWORD bData; BOOL doInterfaceChange = FALSE; SD_DEVICE_HANDLE handle; int count; handle = device->handle; NDIS_DEBUG_PRINTF(1, "%s() : Enter + \r\n",__FUNCTION__); /* Enable SDIO [dragon] function */ fData.Interval = DEFAULT_SDIO_FUNCTION_RETRY_TIMEOUT; fData.ReadyRetryCount = DEFAULT_SDIO_FUNCTION_RETRIES; sdStatus = SDSetCardFeature (handle, SD_IO_FUNCTION_ENABLE, &fData, sizeof(fData)); if (!SD_API_SUCCESS(sdStatus)) { NDIS_DEBUG_PRINTF(DBG_ERR, "SDSetCardFeature (0x%x)\n", sdStatus); return FALSE; } /* * Issue commands to get the manufacturer ID and stuff and compare it * against the rev Id derived from the ID registered during the * initialization process. Report the device only in the case there * is a match. */ sdStatus = SDCardInfoQuery(handle, SD_INFO_SDIO, &sdioInfo, sizeof(sdioInfo)); if (!SD_API_SUCCESS(sdStatus)) { NDIS_DEBUG_PRINTF(DBG_ERR, "SDCardInfoQuery (0x%x) \r\n", sdStatus); return FALSE; } funcNo = sdioInfo.FunctionNumber; sdStatus = SDCardInfoQuery(handle, SD_INFO_REGISTER_RCA, &cardRCA, sizeof(cardRCA)); NDIS_DEBUG_PRINTF(1, "Card RCA is 0x%x \r\n", cardRCA); /* Configure the SDIO Bus Width */ memset(&ci, 0, sizeof(ci)); /* get current interface settings */ sdStatus = SDCardInfoQuery(handle, SD_INFO_CARD_INTERFACE, &ci, sizeof(ci)); if (!SD_API_SUCCESS(sdStatus)) { NDIS_DEBUG_PRINTF(DBG_ERR, "%s() : ERR, SDCardInfoQuery Fail !!\r\n",__FUNCTION__); return FALSE; } //DebugBreak(); #ifdef HIF_SDIO_1BIT /* force to 1 bit mode */ sdio1bitmode = 1; #endif if (sdio1bitmode && (ci.InterfaceMode != SD_INTERFACE_SD_MMC_1BIT)) { /* force to 1 bit mode */ ci.InterfaceMode = SD_INTERFACE_SD_MMC_1BIT; doInterfaceChange = TRUE; } /* check for forced low speed operation */ if (sdiobusspeedlow) { /* only set the lower of our current rate and our desired reduced rate, * otherwise we run at a clock rate that the bus driver setup for us */ ci.ClockRate = min(ci.ClockRate, SDIO_CLOCK_FREQUENCY_REDUCED); doInterfaceChange = TRUE; } if (doInterfaceChange) { sdStatus = SDSetCardFeature(handle, SD_SET_CARD_INTERFACE, &ci, sizeof(ci)); if (!SD_API_SUCCESS(sdStatus)) { NDIS_DEBUG_PRINTF(DBG_ERR, "%s() : SDSetCardFeature Fail !!\r\n",__FUNCTION__); return FALSE; } } NDIS_DEBUG_PRINTF(DBG_TRACE, ("** SDIO Interface : %s : %d (%s)\r\n", doInterfaceChange ? "Overridden to" : "Set by busdriver", ci.ClockRate, (ci.InterfaceMode == SD_INTERFACE_SD_MMC_1BIT) ? "1-bit" : "4-bit")); /* save card interface mode to restore later */ A_MEMCPY(&device->CardInterface, &ci, sizeof(ci)); /* Check if the target supports block mode */ sdStatus = SDReadWriteRegistersDirect(handle, SD_IO_READ, 0, 0x08, FALSE, &ucRegVal, 1); if (!SD_API_SUCCESS(sdStatus)) { NDIS_DEBUG_PRINTF(DBG_ERR, "%s() : SDReadWriteRegistersDirect Fail !!\r\n",__FUNCTION__); return FALSE; } blockMode = (ucRegVal & 0x2) >> 1; // SMB is bit 1 if (!blockMode) { NDIS_DEBUG_PRINTF(DBG_ERR, ("Function does not support block mode\n")); return FALSE; } else { NDIS_DEBUG_PRINTF(DBG_TRACE, ("Function supports block mode \r\n")); blockCap.ReadBlocks = blockCap.WriteBlocks = 8; blockCap.ReadBlockSize = blockCap.WriteBlockSize = HIF_MBOX_BLOCK_SIZE; sdStatus = SDCardInfoQuery(handle, SD_INFO_HOST_BLOCK_CAPABILITY, &blockCap, sizeof(blockCap)); if (blockCap.ReadBlockSize < blockCap.WriteBlockSize) { maxBlockSize = blockCap.ReadBlockSize; } else { maxBlockSize = blockCap.WriteBlockSize; } if (blockCap.ReadBlocks < blockCap.WriteBlocks) { maxBlocks = blockCap.ReadBlocks; } else { maxBlocks = blockCap.WriteBlocks; } sdStatus = SDGetTuple(handle, SD_CISTPL_FUNCE, NULL, &ulLength, FALSE); if ((!SD_API_SUCCESS(sdStatus)) || (ulLength > sizeof(rgucTuple)) ) { return FALSE; } sdStatus = SDGetTuple(handle, SD_CISTPL_FUNCE, rgucTuple, &ulLength, FALSE); if ((!SD_API_SUCCESS(sdStatus)) || (pFunce->bType != SD_CISTPL_FUNCE_FUNCTION_TYPE) ) { return FALSE; } if (maxBlockSize > pFunce->wMaxBlkSize) { maxBlockSize = pFunce->wMaxBlkSize; } bData = (DWORD)maxBlockSize; sdStatus = SDSetCardFeature(handle, SD_IO_FUNCTION_SET_BLOCK_SIZE, &bData, sizeof(bData)); } NDIS_DEBUG_PRINTF(DBG_TRACE, "Bytes Per Block: %d bytes, Block Count:%d \r\n", maxBlockSize, maxBlocks); /* Initialize the bus requests to be used later */ A_MEMZERO(device->busRequest, sizeof(device->busRequest)); for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) { NdisInitializeEvent(&device->busRequest[count].sem_req); hifFreeBusRequest(device, &device->busRequest[count]); } return TRUE; }