Example #1
0
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;
}
Example #2
0
SD_API_STATUS
CSDHCBase::Start()
{
    SD_API_STATUS status = SD_API_STATUS_INSUFFICIENT_RESOURCES;

    m_fDriverShutdown = FALSE;

    // allocate the interrupt event
    m_hevInterrupt = CreateEvent(NULL, FALSE, FALSE,NULL);

    if (NULL == m_hevInterrupt) {
        goto EXIT;
    }

    // initialize the interrupt event
    RETAILMSG(0,(_T("CSDHCBase::Start() m_dwSysIntr = %x\r\n"), m_dwSysIntr)); // jylee
    if (!InterruptInitialize (m_dwSysIntr, m_hevInterrupt, NULL, 0)) {
        goto EXIT;
    }

    m_fInterruptInitialized = TRUE;

    // create the interrupt thread for controller interrupts
    m_htIST = CreateThread(NULL, 0, ISTStub, this, 0, NULL);
    if (NULL == m_htIST) {
        goto EXIT;
    }

    for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
        PCSDHCSlotBase pSlot = GetSlot(dwSlot);
        status = pSlot->Start();

        if (!SD_API_SUCCESS(status)) {
            goto EXIT;
        }
    }

    // wake up the interrupt thread to check the slot
    ::SetInterruptEvent(m_dwSysIntr);

    status = SD_API_STATUS_SUCCESS;

EXIT:
    if (!SD_API_SUCCESS(status)) {
        // Clean up
        Stop();
    }
	RETAILMSG(0,(_T("CSDHCBase::-Start() status = %x\r\n"), status)); // jylee
    return status;
}
Example #3
0
///////////////////////////////////////////////////////////////////////////////
//  CardDllEntry - the main dll entry point
//  Input:  hInstance - the instance that is attaching
//          Reason - the reason for attaching
//          pReserved - 
//  Output: 
//  Return: TRUE
//  Notes:  this is only used to initialize the zones
///////////////////////////////////////////////////////////////////////////////
BOOL DllEntry(HINSTANCE  hInstance,
                       ULONG      Reason,
                       LPVOID     pReserved)
{
    if ( Reason == DLL_PROCESS_ATTACH ) {
        SD_DEBUG_ZONE_REGISTER(hInstance, SDH_REGISTRY_BASE_PATH);
        DisableThreadLibraryCalls( (HMODULE) hInstance );

        if( !SDInitializeCardLib() )
        {
            return FALSE;
        }
        else if( !SD_API_SUCCESS( SDHCDInitializeHCLib() ) ) 
        {
            SDDeinitializeCardLib();
            return FALSE;
        }
    }

    if ( Reason == DLL_PROCESS_DETACH ) {
        SDHCDDeinitializeHCLib();
        SDDeinitializeCardLib();
    }

    return(TRUE);
}
Example #4
0
void hifRWCompletionHandler(SD_DEVICE_HANDLE  hDevice,
					   PSD_BUS_REQUEST   pRequest,
					   PVOID             notUsed,
					   DWORD             dwParam) 
{

    PVOID    htcContext = (void *)dwParam;
	A_STATUS status = A_OK;

	if(SD_API_SUCCESS(pRequest->Status)) {
		status = A_OK;
	} else {
		status = A_ERROR;
	}

	if(htcContext != NULL) 
	{
		htcCallbacks.rwCompletionHandler(htcContext, A_OK);
	}


    SDFreeBusRequest(pRequest);
	
	NDIS_DEBUG_PRINTF(DBG_TRACE, "%s() : - Exit \r\n", __FUNCTION__);

}
Example #5
0
A_STATUS HIFInit(OSDRV_CALLBACKS *callbacks)
{
	SD_API_STATUS sdStatus;
	
    AR_DEBUG_ASSERT(callbacks != NULL);

    /* store the callback handlers */
    osdrvCallbacks = *callbacks;

    /* Register with bus driver core */
    NDIS_DEBUG_PRINTF(DBG_LEVEL_HIF, "AR6000: HIFInit registering \r\n");
    registered = 1;
#if defined(CONFIG_PM)
	// TODO about power management.
#endif /* CONFIG_PM */

    /* Register with bus driver core */
    sdFunction.pName      = "sdio_wlan";
    sdFunction.pProbe     = hifDeviceInserted;
    sdFunction.pRemove    = hifDeviceRemoved;

	
	A_MUTEX_INIT(&hif_lock);
	NdisAllocateSpinLock(&sLock);
	
    sdStatus = SDIORegisterFunction(&sdFunction);
    AR_DEBUG_ASSERT(SD_API_SUCCESS(sdStatus));	
    
    return A_OK;
}
Example #6
0
void
HIFUnMaskInterrupt(HIF_DEVICE *device)
{
    SD_API_STATUS sdStatus;

    /* Register the IRQ Handler */
	sdStatus = SDIOConnectInterrupt(device->handle, hifIRQHandler);
	AR_DEBUG_ASSERT(SD_API_SUCCESS(sdStatus));
	return;
}
Example #7
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;
}
Example #8
0
extern 
DWORD WINAPI DRG_Init(DWORD dwContext)
{
	PWCHAR*                         pRegPath = NULL;
    SDCARD_CLIENT_REGISTRATION_INFO ClientInfo;     // client into
    SD_API_STATUS                   Status;         // intermediate status
	HANDLE                          hThread;

    NDIS_DEBUG_PRINTF(DBG_TRACE, "AR6K_SDIO: +DRG_Init by DiskImage !!! \r\n");

    // get the device handle from the bus driver
    hClientHandle = SDGetDeviceHandle(dwContext, pRegPath);
    if (NULL == hClientHandle) {
		NDIS_DEBUG_PRINTF(DBG_ERR, "-DRG_Init: Failed to get client handle \r\n");
        return 0;
    }

    memset(&ClientInfo, 0, sizeof(ClientInfo));

    // set client options and register as a client device
    _tcscpy(ClientInfo.ClientName, TEXT("Atheros AR6K SDIO Wifi Card"));

    // set the callback
    ClientInfo.pSlotEventCallBack = SlotEventCallBack;

    Status = SDRegisterClient(hClientHandle, 
                              NULL, 
                              &ClientInfo);

    if (!SD_API_SUCCESS(Status)) {
        NDIS_DEBUG_PRINTF(DBG_ERR, "-DRG_Init: Failed to register client : 0x%08X \r\n", Status);
        return 0;
    }

	drvInit();

    if (!createRegKeyValues()) {
        NDIS_DEBUG_PRINTF(DBG_ERR, "-DRG_Init: Failed to create ndis registryentries \r\n");
        return 0;
    }

	// Perform NDIS register adapter on a separate thread to avoid
	// blocking the SDIO bus driver
	hThread = CreateThread(NULL, 0, 
		NdisRegisterAdapterThread, NULL, 0, NULL);
	
	CeSetThreadPriority(hThread, 200);
	CloseHandle(hThread);
	
	NDIS_DEBUG_PRINTF(DBG_TRACE, "DRG_Init : Exit\r\n");
	return 1;
}
Example #9
0
///////////////////////////////////////////////////////////////////////////////
//  IdleThread - idle thread
//  Input:  pMemCard - memory card instance
//  Output:
//  Return: thread exit code
//  Notes:
//      This thread is created if power management is enabled.
//      Normally the thread lays dormant until signalled to perform
//      the idle timeout.  When an idle timeout occurs, if the
//      timer was not cancelled, the thread deselects the memory card
//      to reduce power consumption.
///////////////////////////////////////////////////////////////////////////////
DWORD IdleThread(PSD_MEMCARD_INFO pMemCard)
{

    while(1) {

            // wait for event
        WaitForSingleObject(pMemCard->hWakeUpIdleThread, INFINITE);

        if (pMemCard->ShutDownIdleThread) {
            return 0;
        }

            // while low power polling is enabled
        while (pMemCard->EnableLowPower) {

                // wait with a timeout
            WaitForSingleObject(pMemCard->hWakeUpIdleThread, pMemCard->IdleTimeout);

            if (pMemCard->EnableLowPower) {

                DEBUGMSG(SDMEM_ZONE_POWER, (TEXT("SDMemory: Idle Timeout Wakeup after %d MS \n"),pMemCard->IdleTimeout));

                AcquireLock(pMemCard);
                    // check for cancel
                if (!pMemCard->CancelIdleTimeout){
                        // make sure we haven't already deselected the card
                    if (!pMemCard->CardDeSelected) {
                        DEBUGMSG(SDMEM_ZONE_POWER, (TEXT("SDMemory: Idle Timout, De-Selecting Card \n")));
                            // we haven't been canceled, so issue the card de-select
                        if (SD_API_SUCCESS(IssueCardSelectDeSelect(pMemCard, FALSE))) {
                            pMemCard->CardDeSelected = TRUE;
                        }
                    }
                } else {
                    DEBUGMSG(SDMEM_ZONE_POWER, (TEXT("SDMemory: Idle Timout, Cancelled! \n")));
                }

                    // clear the cancel flag
                                    // SMC_IOControl() will clear pMemCard->CancelIdleTimeout once ioctl request is end

                ReleaseLock(pMemCard);
            }
        }

        if (pMemCard->ShutDownIdleThread) {
            return 0;
        }
    }

}
Example #10
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;
}
Example #11
0
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;
}
Example #12
0
//++dralee_20060327
NDIS_STATUS
SendNullPacket(IN PMRVDRV_ADAPTER Adapter,UCHAR pwmgr )
{
    NDIS_STATUS        sdstatus;            
    SDIO_TX_PKT         downloadPkt;

    downloadPkt.Len = ADD_SDIO_PKT_HDR_LENGTH(sizeof(WCB));
    downloadPkt.Type = IF_DATA_PKT;                 

    NdisZeroMemory(&downloadPkt.Buf.TxDataBuf.Wcb, sizeof(WCB));
    downloadPkt.Buf.TxDataBuf.Wcb.PktPtr = sizeof(WCB); 
    downloadPkt.Buf.TxDataBuf.Wcb.PowerMgmt = pwmgr;  
    sdstatus = If_DownloadPkt(Adapter, &downloadPkt);
   
    if (!SD_API_SUCCESS(sdstatus))
    {                
        DBGPRINT(DBG_ERROR,(L"Send Null Pkt Fail\r\n"));  
        return NDIS_STATUS_FAILURE; 
    }
    return sdstatus;
}   
Example #13
0
///////////////////////////////////////////////////////////////////////////////
//  RequestPrologue  - pre-tasks before handling the ioctl
//  Input:  pMemCard - memory card instance
//          DeviceIoControl - device iocontrol to filter
//  Output:
//  Return: SD_API_STATUS code
//  Notes:
//          This function should be called from the Ioctl dispatch function
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS RequestPrologue(PSD_MEMCARD_INFO pMemCard, DWORD DeviceIoControl)
{
    SD_API_STATUS status = SD_API_STATUS_SUCCESS; // intermediate status

    if (pMemCard->CardEjected) {
        return SD_API_STATUS_DEVICE_REMOVED;
    }

        // check and see if we need to do power management tasks
    if (!pMemCard->EnablePowerManagement) {
        return SD_API_STATUS_SUCCESS;
    }

        // pass power Ioctls through without issuing card re-select
    if ((IOCTL_POWER_CAPABILITIES == DeviceIoControl) ||
        (IOCTL_POWER_QUERY == DeviceIoControl) ||
        (IOCTL_POWER_SET == DeviceIoControl)) {
        return SD_API_STATUS_SUCCESS;
    }

        // for all other ioctls, re-select the card
    AcquireLock(pMemCard);

        // cancel the idle timer
    pMemCard->CancelIdleTimeout= TRUE;

        // check to see if the card was deselected due to power
        // management
    if (pMemCard->CardDeSelected) {
        DEBUGMSG(SDMEM_ZONE_POWER, (TEXT("SDMemory: Re-Selecting Card \n")));
        status = IssueCardSelectDeSelect(pMemCard, TRUE);
        if (SD_API_SUCCESS(status)) {
            pMemCard->CardDeSelected = FALSE;
        }
    }

    ReleaseLock(pMemCard);

    return status;
}
Example #14
0
void 
hifRWCompletionHandler(SD_DEVICE_HANDLE  hDevice,
					   PSD_BUS_REQUEST   pRequest,
					   PVOID             notUsed,
					   DWORD             dwParam) 
{
    A_STATUS status;
    PVOID    htcContext;

    if (SD_API_SUCCESS(pRequest->Status)) {
        status = A_OK;
    } else {
        status = A_ERROR;
    }
    htcContext = (void *)dwParam;

    htcCallbacks.rwCompletionHandler(htcContext, status);
    AR_DEBUG_ASSERT(status == A_OK);

    SDFreeBusRequest(pRequest);
	return;
}
Example #15
0
///////////////////////////////////////////////////////////////////////////////
//  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;
}
Example #16
0
/* ------ Functions ------ */
void
HIFRegisterCallbacks(HTC_CALLBACKS *callbacks)
{
    SD_API_STATUS sdStatus;

    /* Store the callback and event handlers */
    htcCallbacks.deviceInsertedHandler = callbacks->deviceInsertedHandler;
    htcCallbacks.deviceRemovedHandler = callbacks->deviceRemovedHandler;
    htcCallbacks.deviceSuspendHandler = callbacks->deviceSuspendHandler;
    htcCallbacks.deviceResumeHandler = callbacks->deviceResumeHandler;
    htcCallbacks.deviceWakeupHandler = callbacks->deviceWakeupHandler;
    htcCallbacks.rwCompletionHandler = callbacks->rwCompletionHandler;
	htcCallbacks.deviceInterruptDisabler = callbacks->deviceInterruptDisabler;
    htcCallbacks.deviceInterruptEnabler = callbacks->deviceInterruptEnabler;
	htcCallbacks.dsrHandler = callbacks->dsrHandler;

    /* Register with bus driver core */
    sdFunction.pName      = "sdio_wlan";
    sdFunction.pProbe     = hifDeviceInserted;
    sdFunction.pRemove    = hifDeviceRemoved;

    sdStatus = SDIORegisterFunction(&sdFunction);
    AR_DEBUG_ASSERT(SD_API_SUCCESS(sdStatus));
}
Example #17
0
///////////////////////////////////////////////////////////////////////////////
//  SMC_Init - the init entry point for the memory driver
//  Input:  dwContext - the context for this init
//  Output:
//  Return: non-zero context
//  Notes:
///////////////////////////////////////////////////////////////////////////////
extern "C" DWORD WINAPI SMC_Init(DWORD dwContext)
{
    SD_DEVICE_HANDLE                hClientHandle;  // client handle
    PSD_MEMCARD_INFO                pDevice;        // this instance of the device
    SDCARD_CLIENT_REGISTRATION_INFO ClientInfo;     // client into
    ULONG                           BufferSize;     // size of buffer
    HKEY                            hSubKey;        // registry key
    SD_API_STATUS                   Status;         // intermediate status
    DWORD                           data;           // registry data
    DWORD                           dataLength;     // registry data length

    DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemory: +SMC_Init\r\n")));

    pDevice = (PSD_MEMCARD_INFO)SDAllocateMemoryWithTag(
                  sizeof(SD_MEMCARD_INFO),
                  SD_MEMORY_TAG);
    if (pDevice == NULL) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDMemory: Failed to allocate device info\r\n")));
        DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemory: -SMC_Init\r\n")));
        return 0;
    }

    // initialize sterile I/O request to NULL
    pDevice->pSterileIoRequest = NULL;

    InitializeCriticalSection(&pDevice->CriticalSection);
    InitializeCriticalSection(&pDevice->RemovalLock);

    // get the device handle from the bus driver
    hClientHandle = SDGetDeviceHandle(dwContext, &pDevice->pRegPath);
    // store device handle in local context
    pDevice->hDevice = hClientHandle;
    if (NULL == hClientHandle) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDMemory: Failed to get client handle\r\n")));
        CleanUpDevice(pDevice);
        DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemory: -SMC_Init\r\n")));
        return 0;
    }

    // allocate sterile I/O request
    pDevice->pSterileIoRequest = (PSG_REQ)LocalAlloc(
                                     LPTR,
                                     (sizeof(SG_REQ) + ((MAX_SG_BUF - 1) * sizeof(SG_BUF)))
                                 );
    if (NULL == pDevice->pSterileIoRequest) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDMemory: Failed to allocate sterile I/O request\r\n")));
        CleanUpDevice(pDevice);
        DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemory: -SMC_Init\r\n")));
        return 0;
    }

    // register our debug zones
    SDRegisterDebugZones(hClientHandle, pDevice->pRegPath);

    memset(&ClientInfo, 0, sizeof(ClientInfo));

    // set client options and register as a client device
    _tcscpy(ClientInfo.ClientName, TEXT("Memory Card"));

    // set the callback
    ClientInfo.pSlotEventCallBack = SlotEventCallBack;

    Status = SDRegisterClient(hClientHandle, pDevice, &ClientInfo);
    if (!SD_API_SUCCESS(Status)) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDMemory: Failed to register client : 0x%08X\r\n"),
                                     Status));
        CleanUpDevice(pDevice);
        DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemory: -SMC_Init\r\n")));
        return 0;
    }
#ifdef _FOR_MOVI_NAND_
    /**
     * Description : There is no way to distinguish between HSMMC and moviNAND.
     *               So, We assume A HSMMC card is a moviNAND. Default value is false;
     */
    pDevice->IsHSMMC = FALSE;
#endif
    // configure card and retrieve disk size/format information
    if( SDMemCardConfig( pDevice ) != ERROR_SUCCESS ) {
        CleanUpDevice(pDevice);
        DEBUGMSG( SDCARD_ZONE_ERROR, (TEXT("SDMemory: Error initializing MemCard structure and card\r\n")));
        return 0;
    }

    // aet a default block transfer size
    pDevice->BlockTransferSize = DEFAULT_BLOCK_TRANSFER_SIZE;

    // read configuration from registry

    // open the reg path
    if (RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                pDevice->pRegPath,
                0,
                KEY_ALL_ACCESS,
                &hSubKey) == ERROR_SUCCESS
       ) {
        // read "BlockTransferSize"
        dataLength = sizeof(pDevice->BlockTransferSize);
        RegQueryValueEx(
            hSubKey,
            BLOCK_TRANSFER_SIZE_KEY,
            NULL,
            NULL,
            (PUCHAR)&(pDevice->BlockTransferSize),
            &dataLength);
        if (pDevice->BlockTransferSize != DEFAULT_BLOCK_TRANSFER_SIZE) {
            DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemory: Initialize: Using block transfer size of %d blocks\r\n"),
                                        pDevice->BlockTransferSize));
        }

        // read "SingleBlockWrites"
        // default to using mulitple block writes
        pDevice->SingleBlockWrites = FALSE;
        dataLength = sizeof(DWORD);
        data = 0;
        if (RegQueryValueEx(
                    hSubKey,
                    SINGLE_BLOCK_WRITES_KEY,
                    NULL,
                    NULL,
                    (PUCHAR)&data,
                    &dataLength) == ERROR_SUCCESS
           ) {
            // key is present
            pDevice->SingleBlockWrites = TRUE;
            DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemory: Initialize: Using single block write commands only\r\n")));
        }

        // read "DisablePowerManagement"
        // on by default unless key is present
        pDevice->EnablePowerManagement = TRUE;
        dataLength = sizeof(DWORD);
        data = 0;
        if (RegQueryValueEx(
                    hSubKey,
                    DISABLE_POWER_MANAGEMENT,
                    NULL,
                    NULL,
                    (PUCHAR)&data,
                    &dataLength) == ERROR_SUCCESS
           ) {
            // key is present
            DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemory: Initialize: Disabled power management\r\n")));
            pDevice->EnablePowerManagement = FALSE;
        }

        // read "IdleTimeout"
        pDevice->IdleTimeout = DEFAULT_IDLE_TIMEOUT;
        dataLength = sizeof(pDevice->IdleTimeout);
        if (RegQueryValueEx(
                    hSubKey,
                    IDLE_TIMEOUT,
                    NULL,
                    NULL,
                    (PUCHAR)&pDevice->IdleTimeout,
                    &dataLength) == ERROR_SUCCESS
           ) {
            // key is present
            DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemory: Initialize: Using idle timeout of %u milliseconds\r\n"),
                                        pDevice->IdleTimeout));
        }

        // read "IdlePowerState"
        // default power state for idle
        // if the power state is greater than D2, we do idle checking
        pDevice->PowerStateForIdle = D2;
        dataLength = sizeof(DWORD);
        data = 0;
        if (RegQueryValueEx(
                    hSubKey,
                    IDLE_POWER_STATE,
                    NULL,
                    NULL,
                    (PUCHAR)&data,
                    &dataLength) == ERROR_SUCCESS
           ) {
            if (data <= (ULONG)D4) {
                pDevice->PowerStateForIdle = (CEDEVICE_POWER_STATE)data;
            }
        }

        DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemory: Idle Timeout: %d Idle Power State: %d\r\n"),
                                    pDevice->IdleTimeout,
                                    pDevice->PowerStateForIdle));

        RegCloseKey(hSubKey);
    }

    // allocate our buffer list; we need 2 buffers: 1 for read and 1 for write data
    BufferSize = (ULONG)(pDevice->BlockTransferSize * SD_BLOCK_SIZE);

    // create the data buffer memory list
    pDevice->hBufferList = SDCreateMemoryList(SD_MEMORY_TAG, 2, BufferSize);
    if (pDevice->hBufferList == NULL) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDMemory: Initialize: Failed to allocate buffer list\r\n")));
        CleanUpDevice(pDevice);
        return 0;
    }

    pDevice->fPreDeinitCalled = FALSE;

    InitializePowerManagement(pDevice);

    DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDMemory: -SMC_Init\r\n")));

    return (DWORD)pDevice;
}
Example #18
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;
}
Example #19
0
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;
}
Example #20
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;
}
Example #21
0
BOOL
CSDHCBase::Init(
                LPCTSTR pszActiveKey
                )
{
    BOOL fRet = FALSE;
    SD_API_STATUS status;
    HKEY    hkDevice = NULL;

    hkDevice = OpenDeviceKey(pszActiveKey);
    if (!hkDevice || !m_regDevice.Open(hkDevice, _T(""))) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: Failed to open device key\n")));
        goto EXIT;
    }

    // Get a handle to our parent bus.
    m_hBusAccess = CreateBusAccessHandle(pszActiveKey);
    if (m_hBusAccess == NULL) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: Could not get handle to parent\n")));
        goto EXIT;
    }

    m_cSlots = DetermineSlotCount();
    if (m_cSlots == 0) {
        goto EXIT;
    }

    ValidateSlotCount();
	RETAILMSG(0,(TEXT("CSDHCBase::Init  m_cSlots=%d\n"),m_cSlots)); // jylee
    m_pSlotInfos = (PSDHC_SLOT_INFO) LocalAlloc(LPTR, 
        sizeof(SDHC_SLOT_INFO) * m_cSlots);
    if (m_pSlotInfos == NULL) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to allocate slot info objects\n")));
        goto EXIT;
    }

    status = SDHCDAllocateContext(m_cSlots, &m_pHCDContext);
    if (!SD_API_SUCCESS(status)) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to allocate context : 0x%08X \n"),
            status));
        goto EXIT;
    }
    
    // Set our extension 
    m_pHCDContext->pHCSpecificContext = this;

    if (!InitializeHardware()) {
        goto EXIT;
    }
	RETAILMSG(0,(TEXT("AllocateSlotObjects\n")));
    // Allocate slot objects
    m_pSlots = AllocateSlotObjects(m_cSlots);
    if (m_pSlots == NULL) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to allocate slot objects\n")));
        goto EXIT;
    }

    // Initialize the slots
    for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
        PSDHC_SLOT_INFO pSlotInfo = &m_pSlotInfos[dwSlot];
        PCSDHCSlotBase pSlot = GetSlot(dwSlot);

		RETAILMSG(0,(TEXT("pSlot->Init\n")));
        RETAILMSG(0,(TEXT("pSlotInfo->pucRegisters : 0x%x\r\n"),pSlotInfo->pucRegisters));
        if (!pSlot->Init(dwSlot, pSlotInfo->pucRegisters, m_pHCDContext, 
            m_dwSysIntr, m_hBusAccess, m_interfaceType, m_dwBusNumber, &m_regDevice)) {
                goto EXIT;
            }
    }

    // set the host controller name
    SDHCDSetHCName(m_pHCDContext, TEXT("HSMMC"));

    // set init handler
    SDHCDSetControllerInitHandler(m_pHCDContext, CSDHCBase::SDHCInitialize);
    // set deinit handler    
    SDHCDSetControllerDeinitHandler(m_pHCDContext, CSDHCBase::SDHCDeinitialize);
    // set the Send packet handler
    SDHCDSetBusRequestHandler(m_pHCDContext, CSDHCBase::SDHCBusRequestHandler);   
    // set the cancel I/O handler
    SDHCDSetCancelIOHandler(m_pHCDContext, CSDHCBase::SDHCCancelIoHandler);   
    // set the slot option handler
    SDHCDSetSlotOptionHandler(m_pHCDContext, CSDHCBase::SDHCSlotOptionHandler);

    // These values must be set before calling SDHCDRegisterHostController()
    // because they are used during that call.
    m_dwPriority = m_regDevice.ValueDW(SDHC_PRIORITY_KEY, SDHC_CARD_CONTROLLER_PRIORITY);
	RETAILMSG(0,(TEXT("SDHCDRegisterHostController\n"))); // jylee
    // now register the host controller 
    status = SDHCDRegisterHostController(m_pHCDContext);

    if (!SD_API_SUCCESS(status)) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to register host controller: %0x08X \n"), 
            status));
        goto EXIT;
    }

    m_fRegisteredWithBusDriver = TRUE;
    fRet = TRUE;
	RETAILMSG(0,(TEXT("CSDHCBase::Init Finished.\n"))); // jylee
EXIT:
    if (hkDevice) RegCloseKey(hkDevice);

    return fRet;
}
Example #22
0
SD_API_STATUS 
CSDHCBase::SlotOptionHandler(
                             DWORD                 dwSlot, 
                             SD_SLOT_OPTION_CODE   sdOption, 
                             PVOID                 pData,
                             DWORD                 cbData
                             )
{
    SD_API_STATUS   status = SD_API_STATUS_SUCCESS;
    BOOL            fCallSlotsHandler = TRUE;

    Lock();
    Validate();
    PCSDHCSlotBase pSlot = GetSlot(dwSlot);

    DEBUGCHK(sdOption < dim(sc_rgpszOptions));
    DEBUGCHK(sc_rgpszOptions[sdOption] != NULL);
    DEBUGMSG(SDCARD_ZONE_INFO, (_T("CSDHCBase::SlotOptionHandler(%u, %s)\n"),
        dwSlot, sc_rgpszOptions[sdOption]));

    switch (sdOption) {
    case SDHCDSetSlotPower: {
        if (cbData != sizeof(DWORD)) {
            status = SD_API_STATUS_INVALID_PARAMETER;
        }
        break;
    }

    case SDHCDSetSlotInterface: {
        if (cbData != sizeof(SD_CARD_INTERFACE)) {
            status = SD_API_STATUS_INVALID_PARAMETER;
        }
        break;
    }

    case SDHCDEnableSDIOInterrupts:
    case SDHCDDisableSDIOInterrupts:
    case SDHCDAckSDIOInterrupt:
        if (pData || cbData != 0) {
            status = SD_API_STATUS_INVALID_PARAMETER;
        }
        break;

    case SDHCDGetWriteProtectStatus: {
        if (cbData != sizeof(SD_CARD_INTERFACE)) {
            status = SD_API_STATUS_INVALID_PARAMETER;
        }
        break;
    }

    case SDHCDQueryBlockCapability: {
        if (cbData != sizeof(SD_HOST_BLOCK_CAPABILITY)) {
            status = SD_API_STATUS_INVALID_PARAMETER;
        }
        break;
    }

    case SDHCDSetSlotPowerState: {
        if (cbData != sizeof(CEDEVICE_POWER_STATE)) {
            status = SD_API_STATUS_INVALID_PARAMETER;
        }

        PCEDEVICE_POWER_STATE pcps = (PCEDEVICE_POWER_STATE) pData;

        if (*pcps < m_cpsCurrent) {
            // Move controller to higher power state initially since
            // it will need to be powered for the slot to access
            // registers.
            SetControllerPowerState(*pcps);
        }

        status = pSlot->SlotOptionHandler(sdOption, pData, cbData);

        // Set the power state based on current conditions. Note that 
        // the slot may have gone to a state different from what was 
        // requested.
        CEDEVICE_POWER_STATE cps = DetermineRequiredControllerPowerState();
        SetControllerPowerState(cps);
        fCallSlotsHandler = FALSE;
        break;
    }

    case SDHCDGetSlotPowerState: {
        if (cbData != sizeof(CEDEVICE_POWER_STATE)) {
            status = SD_API_STATUS_INVALID_PARAMETER;
        }
        break;
    }

    case SDHCDWakeOnSDIOInterrupts: {
        if (cbData != sizeof(BOOL)) {
            status = SD_API_STATUS_INVALID_PARAMETER;
        }
        break;
    }

    case SDHCDGetSlotInfo: {
        if (cbData != sizeof(SDCARD_HC_SLOT_INFO)) {
            status = SD_API_STATUS_INVALID_PARAMETER;
        }
        break;
    }

    default:
        break;
    }

    if (SD_API_SUCCESS(status) && fCallSlotsHandler) {
        // Call the slots handler to do the real work.
        status = pSlot->SlotOptionHandler(sdOption, pData, cbData);
    }

    Unlock();

    return status;
}
Example #23
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;
}
Example #24
0
 SD_API_STATUS GetFirstFailedStatus() {
     if (SD_API_SUCCESS(Status) && m_pChildListNext!=NULL )
         return m_pChildListNext->GetFirstFailedStatus();
     else
         return Status;
 }
Example #25
0
// New Start function for Card detect of HSMMC ch1 on SMDK6410.
SD_API_STATUS CSDHControllerCh1::Start() {
    SD_API_STATUS status = SD_API_STATUS_INSUFFICIENT_RESOURCES;

    m_fDriverShutdown = FALSE;

    // allocate the interrupt event
    m_hevInterrupt = CreateEvent(NULL, FALSE, FALSE,NULL);

    if (NULL == m_hevInterrupt)    {
        goto EXIT;
    }

    // initialize the interrupt event
    if (!InterruptInitialize (m_dwSysIntr, m_hevInterrupt, NULL, 0)) {
        goto EXIT;
    }

    m_fInterruptInitialized = TRUE;

    // create the interrupt thread for controller interrupts
    m_htIST = CreateThread(NULL, 0, ISTStub, this, 0, NULL);
    if (NULL == m_htIST) {
        goto EXIT;
    }

    // allocate the card detect event
    m_hevCardDetectEvent = CreateEvent(NULL, FALSE, FALSE,NULL);

    if (NULL == m_hevCardDetectEvent) {
        goto EXIT;
    }

    // initialize the interrupt event
    if (!InterruptInitialize (m_dwSDDetectSysIntr, m_hevCardDetectEvent, NULL, 0)) {
        goto EXIT;
    }

    // create the card detect interrupt thread   
    m_htCardDetectThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SD_CardDetectThread, this, 0, NULL);
    if (NULL == m_htCardDetectThread)    {
        goto EXIT;
    }

    for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
        PCSDHCSlotBase pSlot = GetSlot(dwSlot);
        status = pSlot->Start();

        if (!SD_API_SUCCESS(status)) {
            goto EXIT;
        }
    }

    // wake up the interrupt thread to check the slot
    ::SetInterruptEvent(m_dwSDDetectSysIntr);   

    status = SD_API_STATUS_SUCCESS;

EXIT:
    if (!SD_API_SUCCESS(status)) {
        // Clean up
        Stop();
    }

    return status;
}
Example #26
0
BOOL CSDBusRequest::CheckForCompletion()
{
    if (m_pParentBus!=NULL) {
        return m_pParentBus->CheckForCompletion();
    }
    else if (IsComplete()) {
        // This one is completed.
        if (SD_API_SUCCESS(Status) && m_pChildListNext!=NULL) {
            Status = m_pChildListNext->GetFirstFailedStatus();
        }
#ifdef DEBUG
        SD_CARD_STATUS cardStatus;

        if (SDBUS_ZONE_REQUEST) {
            DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("--- SDBusDriver: CMD%d  CMDArg: 0x%08X TransferClass:%d ResponseType: %s Complete\n"),
                CommandCode, CommandArgument,TransferClass,  SDCardResponseTypeLookUp[CommandResponse.ResponseType & 0x7]));

            if (SD_API_SUCCESS(Status)) {
                if ( (ResponseR1 == CommandResponse.ResponseType) || (ResponseR1b == CommandResponse.ResponseType)) {
                    SDGetCardStatusFromResponse(&CommandResponse, &cardStatus);
                    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("--- SDBusDriver: R1,R1b Response, Card Status: 0x%08X,  Last State: %s \n"),
                        cardStatus,
                        SDCardStateStringLookUp[((CommandResponse.ResponseBuffer[2] >> 1) & 0x0F)]));
                }

                if (NoResponse != CommandResponse.ResponseType) {
                    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("--- SDBusDriver: Response Dump: \n")));

                    if (ResponseR2 == CommandResponse.ResponseType) {
                        SDOutputBuffer(CommandResponse.ResponseBuffer, 17);
                    } else {
                        SDOutputBuffer(CommandResponse.ResponseBuffer, 6);
                    }
                }

                if (NULL != pBlockBuffer) {   
                    if (SD_READ == TransferClass) {
                        DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("--- SDBusDriver: Read Data Transfered : NumBlocks:%d BytesPerBlock:%d  \n"),
                            NumBlocks, BlockSize));
                        if (SDBUS_ZONE_BUFFER) {
                            DEBUGMSG(SDBUS_ZONE_BUFFER, (TEXT("--- SDBusDriver: Read Data Dump: \n")));
                            SDOutputBuffer(pBlockBuffer, NumBlocks * BlockSize);
                        }
                    } else {
                        DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("--- SDBusDriver: Write Transfer Complete:  NumBlocks:%d BytesPerBlock:%d\n"),
                            NumBlocks, BlockSize));
                    }
                }
            } 
        }
#endif
        PSD_BUS_REQUEST_CALLBACK pCallbackPtr = (PSD_BUS_REQUEST_CALLBACK)InterlockedExchange( (LPLONG)&pCallback, NULL); // Make sure only call once.
        if (pCallbackPtr) {
            __try { 
                /* For Windows CE 6.0
                if (m_hCallback) {
                    IO_BUS_SD_REQUEST_CALLBACK busSdRequestCallback = {
                        pCallbackPtr,  m_sdDevice.GetDeviceHandle().hValue,m_ExternalHandle,
                        m_sdDevice.GetDeviceContext(), RequestParam };
                    CeDriverPerformCallback(
                        m_hCallback, IOCTL_BUS_SD_REQUEST_CALLBACK,&busSdRequestCallback,sizeof(busSdRequestCallback),
                        NULL,0,NULL,NULL);
                    
                }
                else */ {
                    pCallbackPtr(m_sdDevice.GetDeviceHandle().hValue,  // device handle
                        (PSD_BUS_REQUEST)m_ExternalHandle,           // the request
                        m_sdDevice.GetDeviceContext(), // device context
                        RequestParam);  // request argument
                    }
            } __except (SDProcessException(GetExceptionInformation())) {

                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("--- SDBusDriver: Exception caught in CompleteRequest when calling callback in device %s \n"),
                    m_sdDevice.GetClientName()));     
            }
        }
        
    }
Example #27
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;
}
Example #28
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;
}
Example #29
0
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;
}
Example #30
0
///////////////////////////////////////////////////////////////////////////////
//  SMC_IOControl - the I/O control entry point for the memory driver
//  Input:  Handle - the context returned from SMC_Open
//          IoctlCode - the ioctl code
//          pInBuf - the input buffer from the user
//          InBufSize - the length of the input buffer
//          pOutBuf - the output buffer from the user
//          InBufSize - the length of the output buffer
//          pBytesReturned - the size of the transfer
//  Output:
//  Return:  TRUE if ioctl was handled
//  Notes:
///////////////////////////////////////////////////////////////////////////////
extern "C" BOOL WINAPI SMC_IOControl(
    DWORD   Handle,
    DWORD   IoctlCode,
    PBYTE   pInBuf,
    DWORD   InBufSize,
    PBYTE   pOutBuf,
    DWORD   OutBufSize,
    PDWORD  pBytesReturned
)
{
    DWORD            Status = ERROR_SUCCESS;             // win32 status
    PSD_MEMCARD_INFO pHandle = (PSD_MEMCARD_INFO)Handle; // memcard info
    PSG_REQ          pSG;                                // scatter gather buffer
    SD_API_STATUS    sdStatus;                           // SD API status
    DWORD            SafeBytesReturned = 0;              // safe copy of pBytesReturned
    DWORD             dwStartTicks = 0;

    DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDMemory: +SMC_IOControl\r\n")));

    // any of these IOCTLs can access the device instance or card handle so we
    // must protect it from being freed from XXX_Deinit; Windows CE does not
    // synchronize the  callback from Deinit
    AcquireRemovalLock(pHandle);

    if (pHandle->fPreDeinitCalled) {
        Status = ERROR_INVALID_HANDLE;
        goto ErrorStatusReturn;
    }

    sdStatus = RequestPrologue(pHandle, IoctlCode);

    if (!SD_API_SUCCESS(sdStatus)) {
        ReleaseRemovalLock(pHandle);
        SetLastError(SDAPIStatusToErrorCode(sdStatus));
        return FALSE;
    }

    DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("SMC_IOControl: Recevied IOCTL %d ="), IoctlCode));
    switch(IoctlCode) {
    case IOCTL_DISK_READ:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_READ\r\n")));
        break;
    case DISK_IOCTL_READ:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("DISK_IOCTL_READ\r\n")));
        break;
    case IOCTL_DISK_WRITE:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_WRITE\r\n")));
        break;
    case DISK_IOCTL_WRITE:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("DISK_IOCTL_WRITE\r\n")));
        break;
    case IOCTL_DISK_GETINFO:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_GETINFO\r\n")));
        break;
    case DISK_IOCTL_GETINFO:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("DISK_IOCTL_GETINFO\r\n")));
        break;
    case IOCTL_DISK_SETINFO:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_SETINFO\r\n")));
        break;
    case DISK_IOCTL_INITIALIZED:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("DISK_IOCTL_INITIALIZED\r\n")));
        break;
    case IOCTL_DISK_INITIALIZED:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_INITIALIZED\r\n")));
        break;
    case IOCTL_DISK_GETNAME:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_GETNAME\r\n")));
        break;
    case DISK_IOCTL_GETNAME:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("DISK_IOCTL_GETNAME\r\n")));
        break;
    case IOCTL_DISK_GET_STORAGEID:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_GET_STORAGEID\r\n")));
        break;
    case IOCTL_DISK_FORMAT_MEDIA:
    case DISK_IOCTL_FORMAT_MEDIA:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_FORMAT_MEDIA\r\n")));
        break;
    case IOCTL_DISK_DEVICE_INFO:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_DEVICE_INFO\r\n")));
        break;
    case IOCTL_DISK_DELETE_SECTORS:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("IOCTL_DISK_DELETE_SECTORS\r\n")));
        break;
    default:
        DEBUGMSG(SDCARD_ZONE_INFO, (TEXT("**UNKNOWN**\r\n")));
        break;
    }

    // validate parameters
    switch(IoctlCode) {

    case IOCTL_DISK_READ:
    case DISK_IOCTL_READ:
    case IOCTL_DISK_WRITE:
    case DISK_IOCTL_WRITE:
        if (pInBuf == NULL || InBufSize < sizeof(SG_REQ) || InBufSize > (sizeof(SG_REQ) + ((MAX_SG_BUF - 1) * sizeof(SG_BUF)))) {
            Status = ERROR_INVALID_PARAMETER;
        }
        break;

    case DISK_IOCTL_GETINFO:
    case IOCTL_DISK_SETINFO:
        if (NULL == pInBuf || InBufSize != sizeof(DISK_INFO)) {
            Status = ERROR_INVALID_PARAMETER;
        }
        break;

    case IOCTL_DISK_DELETE_SECTORS:
        if (pInBuf == NULL || InBufSize != sizeof(DELETE_SECTOR_INFO)) {
            Status = ERROR_INVALID_PARAMETER;
        }
        break;

    case IOCTL_DISK_GETINFO:
        if (pOutBuf == NULL || OutBufSize != sizeof(DISK_INFO)) {
            Status = ERROR_INVALID_PARAMETER;
        }
        break;

    case IOCTL_DISK_GET_STORAGEID:
        // the identification data is stored after the struct, so the out
        // buffer must be at least the size of the struct.
        if (pOutBuf == NULL || OutBufSize < sizeof(STORAGE_IDENTIFICATION)) {
            Status = ERROR_INVALID_PARAMETER;
        }
        break;

    case IOCTL_DISK_FORMAT_MEDIA:
    case DISK_IOCTL_FORMAT_MEDIA:
        break;

    case IOCTL_DISK_DEVICE_INFO:
        if (NULL == pInBuf || (InBufSize != sizeof(STORAGEDEVICEINFO))) {
            Status = ERROR_INVALID_PARAMETER;
        }
        break;

    case IOCTL_POWER_CAPABILITIES:
        if (!pOutBuf || OutBufSize < sizeof(POWER_CAPABILITIES) || !pBytesReturned) {
            Status = ERROR_INVALID_PARAMETER;
        }
        break;

    case IOCTL_POWER_SET:
        if (!pOutBuf || OutBufSize < sizeof(CEDEVICE_POWER_STATE) || !pBytesReturned) {
            Status = ERROR_INVALID_PARAMETER;
        }
        break;

    default:
        Status = ERROR_INVALID_PARAMETER;
    }

    if (Status != ERROR_SUCCESS) {
        goto ErrorStatusReturn;
    }

    // execute the IOCTL
    switch(IoctlCode) {

    case IOCTL_DISK_READ:
    case DISK_IOCTL_READ:
        pSG = (PSG_REQ)pInBuf;
        if (0 == CeSafeCopyMemory((LPVOID)pHandle->pSterileIoRequest, (LPVOID)pSG, InBufSize)) {
            Status = ERROR_INVALID_PARAMETER;
            break;
        }
        Status = SDMemRead(pHandle, pHandle->pSterileIoRequest);
        __try {
            pSG->sr_status = Status;
            if (pBytesReturned && (ERROR_SUCCESS == Status)) {
                *pBytesReturned = (pHandle->pSterileIoRequest->sr_num_sec * SD_BLOCK_SIZE);
            }
        }
        __except(EXCEPTION_EXECUTE_HANDLER) {
            Status = ERROR_INVALID_PARAMETER;
        }
        break;

    case IOCTL_DISK_WRITE:
    case DISK_IOCTL_WRITE:
        pSG = (PSG_REQ)pInBuf;
        if (0 == CeSafeCopyMemory((LPVOID)pHandle->pSterileIoRequest, (LPVOID)pSG, InBufSize)) {
            Status = ERROR_INVALID_PARAMETER;
            break;
        }
        Status = SDMemWrite(pHandle, pHandle->pSterileIoRequest);
        __try {
            pSG->sr_status = Status;
            if (pBytesReturned && (ERROR_SUCCESS == Status)) {
                *pBytesReturned = (pHandle->pSterileIoRequest->sr_num_sec * SD_BLOCK_SIZE);
            }
        }
        __except(EXCEPTION_EXECUTE_HANDLER) {
            Status = ERROR_INVALID_PARAMETER;
        }
        break;

    case IOCTL_DISK_GETINFO:
    {
        DISK_INFO SafeDiskInfo = {0};
        SafeBytesReturned = sizeof(DISK_INFO);
        Status = GetDiskInfo(pHandle, &SafeDiskInfo);
        if (0 == CeSafeCopyMemory((LPVOID)pOutBuf, (LPVOID)&SafeDiskInfo, sizeof(DISK_INFO))) {
            Status = ERROR_INVALID_PARAMETER;
            break;
        }
        if (pBytesReturned) {
            if (0 == CeSafeCopyMemory((LPVOID)pBytesReturned, (LPVOID)&SafeBytesReturned, sizeof(DWORD))) {
                Status = ERROR_INVALID_PARAMETER;
                break;
            }
        }
    }
    break;

    case DISK_IOCTL_GETINFO:
    {
        DISK_INFO SafeDiskInfo = {0};
        SafeBytesReturned = sizeof(DISK_INFO);
        Status = GetDiskInfo(pHandle, &SafeDiskInfo);
        if (0 == CeSafeCopyMemory((LPVOID)pInBuf, (LPVOID)&SafeDiskInfo, sizeof(DISK_INFO))) {
            Status = ERROR_INVALID_PARAMETER;
            break;
        }
        if (pBytesReturned) {
            if (0 == CeSafeCopyMemory((LPVOID)pBytesReturned, (LPVOID)&SafeBytesReturned, sizeof(DWORD))) {
                Status = ERROR_INVALID_PARAMETER;
                break;
            }
        }
    }
    break;

    case IOCTL_DISK_SETINFO:
    {
        DISK_INFO SafeDiskInfo = {0};
        if (0 == CeSafeCopyMemory((LPVOID)&SafeDiskInfo, (LPVOID)pInBuf, sizeof(DISK_INFO))) {
            Status = ERROR_INVALID_PARAMETER;
            break;
        }
        Status = SetDiskInfo(pHandle, &SafeDiskInfo);
    }
    break;

    case IOCTL_DISK_FORMAT_MEDIA:
    case DISK_IOCTL_FORMAT_MEDIA:
        Status = ERROR_SUCCESS;
        break;

    case IOCTL_DISK_GET_STORAGEID:
    {
        __try {
            Status = GetStorageID(
                         pHandle,
                         (PSTORAGE_IDENTIFICATION)pOutBuf,
                         OutBufSize,
                         pBytesReturned);
        }
        __except(EXCEPTION_EXECUTE_HANDLER) {
            Status = ERROR_INVALID_PARAMETER;
        }
    }
    break;

    case IOCTL_DISK_DEVICE_INFO:
    {
        STORAGEDEVICEINFO SafeStorageDeviceInfo = {0};
        SafeBytesReturned = sizeof(STORAGEDEVICEINFO);
        if (!GetDeviceInfo(pHandle, &SafeStorageDeviceInfo)) {
            Status = ERROR_GEN_FAILURE;
            break;
        }
        if (0 == CeSafeCopyMemory((LPVOID)pInBuf, (LPVOID)&SafeStorageDeviceInfo, sizeof(STORAGEDEVICEINFO))) {
            Status = ERROR_INVALID_PARAMETER;
            break;
        }
        Status = ERROR_SUCCESS;
        if (pBytesReturned) {
            if (0 == CeSafeCopyMemory((LPVOID)pBytesReturned, (LPVOID)&SafeBytesReturned, sizeof(DWORD))) {
                Status = ERROR_INVALID_PARAMETER;
            }
        }
    }
    break;

    case IOCTL_DISK_DELETE_SECTORS:
    {
        DELETE_SECTOR_INFO SafeDeleteSectorInfo = {0};
        if (0 == CeSafeCopyMemory((LPVOID)&SafeDeleteSectorInfo, (LPVOID)pInBuf, sizeof(DELETE_SECTOR_INFO))) {
            Status = ERROR_INVALID_PARAMETER;
            break;
        }
        Status = SDMemErase(pHandle, &SafeDeleteSectorInfo);
    }
    break;

    case IOCTL_POWER_CAPABILITIES:
    {
        POWER_CAPABILITIES SafePowerCapabilities = {0};
        SafeBytesReturned = sizeof(POWER_CAPABILITIES);

        // support D0 + PowerStateForIdle (D2, by default)
        SafePowerCapabilities.DeviceDx = DX_MASK(D0) | DX_MASK(pHandle->PowerStateForIdle);

        SafePowerCapabilities.Power[D0] = PwrDeviceUnspecified;
        SafePowerCapabilities.Power[D1] = PwrDeviceUnspecified;
        SafePowerCapabilities.Power[D2] = PwrDeviceUnspecified;
        SafePowerCapabilities.Power[D3] = PwrDeviceUnspecified;
        SafePowerCapabilities.Power[D4] = PwrDeviceUnspecified;

        SafePowerCapabilities.Latency[D0] = 0;
        SafePowerCapabilities.Latency[D1] = 0;
        SafePowerCapabilities.Latency[D2] = 0;
        SafePowerCapabilities.Latency[D3] = 0;
        SafePowerCapabilities.Latency[D4] = 1000;

        // no device wake
        SafePowerCapabilities.WakeFromDx = 0;
        // no inrush
        SafePowerCapabilities.InrushDx = 0;

        if (0 == CeSafeCopyMemory((LPVOID)pOutBuf, (LPVOID)&SafePowerCapabilities, sizeof(POWER_CAPABILITIES))) {
            Status = ERROR_INVALID_PARAMETER;
            break;
        }
        Status = ERROR_SUCCESS;
        if (pBytesReturned) {
            if (0 == CeSafeCopyMemory((LPVOID)pBytesReturned, (LPVOID)&SafeBytesReturned, sizeof(DWORD))) {
                Status = ERROR_INVALID_PARAMETER;
            }
        }
    }
    break;

    case IOCTL_POWER_SET:
    {
        // pOutBuf is a pointer to CEDEVICE_POWER_STATE; this is the device
        // state incd .. which to put the device; if the driver does not support
        // the requested power state, then we return the adjusted power
        // state
        CEDEVICE_POWER_STATE SafeCeDevicePowerState;
        SafeBytesReturned = sizeof(CEDEVICE_POWER_STATE);
        if (0 == CeSafeCopyMemory((LPVOID)&SafeCeDevicePowerState, (LPVOID)pOutBuf, sizeof(CEDEVICE_POWER_STATE))) {
            Status = ERROR_INVALID_PARAMETER;
            break;
        }
        Status = ERROR_SUCCESS;
        HandleIoctlPowerSet(pHandle, &SafeCeDevicePowerState);
        // return the adjusted power state
        if (0 == CeSafeCopyMemory((LPVOID)pOutBuf, (LPVOID)&SafeCeDevicePowerState, sizeof(CEDEVICE_POWER_STATE))) {
            Status = ERROR_INVALID_PARAMETER;
            break;
        }
        if (pBytesReturned) {
            if (0 == CeSafeCopyMemory((LPVOID)pBytesReturned, (LPVOID)&SafeBytesReturned, sizeof(DWORD))) {
                Status = ERROR_INVALID_PARAMETER;
            }
        }
    }
    break;

    default:
        Status = ERROR_INVALID_PARAMETER;
        break;
    }

    RequestEnd(pHandle);

ErrorStatusReturn:

    ReleaseRemovalLock(pHandle);

    DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDMemory: -SMC_IOControl returning %d\n"),Status == ERROR_SUCCESS));

    if (Status != ERROR_SUCCESS) {
        SetLastError(Status);
    }

    return (ERROR_SUCCESS == Status);
}