void HIFShutDownDevice(HIF_DEVICE *device) { SD_API_STATUS sdStatus; //SDCONFIG_BUS_MODE_DATA busSettings; UCHAR buffer; if (device == NULL) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "Invalid Handle passed\n"); return; } /* Remove the allocated current if any */ /* * There is no equivalent for this one in WINCE status = SDLIB_IssueConfig(device->handle, SDCONFIG_FUNC_FREE_SLOT_CURRENT, NULL, 0); DBG_ASSERT(SDIO_SUCCESS(status)); */ /* Disable the card */ SDIODisconnectInterrupt(device->handle); sdStatus = SDSetCardFeature(device->handle, SD_IO_FUNCTION_DISABLE, NULL, 0); AR_DEBUG_ASSERT(SD_API_SUCCESS(sdStatus)); /* Perform a soft I/O reset */ sdStatus = SDReadWriteRegistersDirect(device->handle, SD_IO_WRITE, 0, SD_IO_REG_IO_ABORT, 1, &buffer, 0); AR_DEBUG_ASSERT(SD_API_SUCCESS(sdStatus)); /* * WAR - Codetelligence driver does not seem to shutdown correctly in 1 * bit mode. By default it configures the HC in the 4 bit. Its later in * our driver that we switch to 1 bit mode. If we try to shutdown, the * driver hangs so we revert to 4 bit mode, to be transparent to the * underlying bus driver. */ /* * Not sure whether this is required for WINCE hence commenting */ /* if (sdio1bitmode) { ZERO_OBJECT(busSettings); busSettings.BusModeFlags = device->handle->pHcd->CardProperties.BusMode; SDCONFIG_SET_BUS_WIDTH(busSettings.BusModeFlags, SDCONFIG_BUS_WIDTH_4_BIT); // Issue config request to change the bus width to 4 bit status = SDLIB_IssueConfig(device->handle, SDCONFIG_BUS_MODE_CTRL, &busSettings, sizeof(SDCONFIG_BUS_MODE_DATA)); DBG_ASSERT(SDIO_SUCCESS(status)); } */ /* Unregister with bus driver core */ sdStatus = SDIOUnregisterFunction(&sdFunction); AR_DEBUG_ASSERT(SD_API_SUCCESS(sdStatus)); return; }
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; }
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; }
static A_STATUS PowerChangeNotify(HIF_DEVICE *device, HIF_DEVICE_POWER_CHANGE_TYPE PowerChange) { A_STATUS status = A_OK; SD_API_STATUS sdStatus = SD_API_STATUS_SUCCESS; NDIS_DEBUG_PRINTF(1, "%s() : Enter (%d) + \r\n",__FUNCTION__,PowerChange); switch (PowerChange) { case HIF_DEVICE_POWER_UP: if (InterlockedExchange(&device->PowerStateOff, POWER_ON) != POWER_OFF) { /* shouldn't be calling this if we are not powered off */ A_ASSERT(FALSE); break; } if (device->SlotPowerRemoved) { /* power was removed from a previous power down attempt */ device->SlotPowerRemoved = FALSE; /* try powering up */ PowerUpDownSlot(device, TRUE); } /* Reinit SDIO since HIF_DEVICE_POWER_DOWN or HIF_DEVICE_POWER_OFF * would have reset the SDIO interface */ status = ReinitSDIO(device); #ifdef HIF_SDIO_BYPASS if (A_SUCCESS(status)) { /* re-activate */ g_BypassModeActive = ActivateSDIOStackBypassMode(); } #endif break; case HIF_DEVICE_POWER_DOWN: case HIF_DEVICE_POWER_CUT: /* set powered off flag, but check previous value */ if (InterlockedExchange(&device->PowerStateOff, POWER_OFF) != POWER_ON) { /* shouldn't be calling this if we are powered off already */ A_ASSERT(FALSE); break; } #ifdef HIF_SDIO_BYPASS g_BypassModeActive = FALSE; /* de-activeate bypass mode */ DeactivateSDIOStackBypassMode(); #endif /* disable I/O function and reset SDIO controller to minimize power */ sdStatus = SDSetCardFeature(device->handle, SD_IO_FUNCTION_DISABLE, NULL, 0); A_ASSERT(SD_API_SUCCESS(sdStatus)); { A_UINT8 buffer; /* Perform a I/O reset, this causes the SDIO interface * to be in the un-enumerated state */ buffer = 1 << 3; sdStatus = SDReadWriteRegistersDirect(device->handle, SD_IO_WRITE, 0, SD_IO_REG_IO_ABORT, 0, &buffer, 1); A_ASSERT(SD_API_SUCCESS(sdStatus)); } if (PowerChange == HIF_DEVICE_POWER_CUT) { /* caller wants the device to be completely off */ device->SlotPowerRemoved = PowerUpDownSlot (device, FALSE); } break; default: A_ASSERT(FALSE); return A_ERROR; } return status; }