Exemplo n.º 1
0
///////////////////////////////////////////////////////////////////////////////
//  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;
}
Exemplo n.º 2
0
///////////////////////////////////////////////////////////////////////////////
//  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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
///////////////////////////////////////////////////////////////////////////////
//  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;
}
Exemplo n.º 5
0
///////////////////////////////////////////////////////////////////////////////
//  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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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;
}