⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cf_ifc.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/** @file CF_IFC.c
 *  @  Compact flash interface module.
 *     All functions in this file should be in the defined interface.
 *     utility functions not in the actual interface should go 
 *
 *  Copyright (c) Marvell Semiconductor, Inc. 
 */
 
#include "precomp.h"
//************************************************************************************
//* Function: 		cf_CreateIface
//*	Description:	Allocates memory for compact flash interface.
//* Returns			Status code returned and pointer to interface returned through iface.
//* Date:			04/03/2003
//************************************************************************************
IX_STATUS cf_CreateIface( PVOID *iface, ULONG ioVirtRegBaseAddress )
{
	PCF_OBJECT pCf;
	NTSTATUS Status;

	DBGPRINT(DBG_HWIF,("+cf_CreateIface: ioVirtRegBaseAddress = %x\n", ioVirtRegBaseAddress ));

	Status = MRVDRV_ALLOC_MEM(&pCf, sizeof (CF_OBJECT));
	if( Status != NDIS_STATUS_SUCCESS )
		return IX_STATUS_FAILURE;

	// PJG: init all to zero.
	MRVDRV_ZERO_MEM(pCf, sizeof(CF_OBJECT));

	pCf -> ulSignatureTop = CF_Signature;				 // set our structure signatures.
	pCf -> ulSignatureBottom = CF_Signature;			 // this will let us know if anyone overwrites our object.
	pCf -> ulMrvDrvVirtualIoBase = ioVirtRegBaseAddress; // virtual base address for CF

	*iface = (PVOID)pCf;
	cf_InitInterface( (PCF_OBJECT)*iface);				 // Initialize the HW interface.
	return IX_STATUS_SUCCESS;
}

//*************************************************************************************
//* Function: 		cf_DestroyIface
//*	Description:	Tears down the compact flash interface and frees accociated memory..
//* Returns			IX_STATUS_SUCCESS if everything went ok, IX_STATUS_FAILURE if anything is
//*						not as expected.
//* Date:			04/03/2003
//************************************************************************************
IX_STATUS cf_DestroyIface( PVOID *iface )
{
	PCF_OBJECT pCf = NULL;
	if ( !*iface ) 
	{
		/// ASSERT(0);
		DBGPRINT(DBG_ERROR,("Attempt to free interface with NULL POINTER\n"));
		return IX_STATUS_FAILURE;
	}
	pCf = (PCF_OBJECT)*iface;
	ASSERT( pCf -> ulSignatureTop == CF_Signature );
	ASSERT( pCf -> ulSignatureBottom == CF_Signature );
	
	MRVDRV_FREE_MEM( *iface, sizeof(CF_OBJECT));
	*iface = NULL;
	return IX_STATUS_SUCCESS;
}

//************************************************************************************
//* Function: 		cf_SendCmd
//*	Description:	Downloads a command sequence to the device.
//* Returns			IX_STATUS_SUCCESS if cmd download when ok, IX_STATUS_DEVICE_BUSY
//*						if device is busy.
//* Date:			04/02/2003
//************************************************************************************
IX_STATUS cf_SendCmd 
	( 
		PVOID iface, 							// pointer to our interface object.
		USHORT *cmdBuf, 						// the command buffer to transmit.
		USHORT cmdSizeBytes 					// number of bytes in command buffer.
	)
{
	PCF_OBJECT pCf = (PCF_OBJECT)iface;
	USHORT leftOverByte = cmdSizeBytes % sizeof(USHORT);	// see if we divide evenly.
	USHORT cmdSizeWords = cmdSizeBytes/sizeof(USHORT);	//  get the whole number of words.
	int ii;
	
	//-------------------------------------------------------------------------------
	// Debug assertions from specifciation.
	//-------------------------------------------------------------------------------
	ASSERT( pCf != NULL );
	ASSERT( pCf -> ulSignatureTop == CF_Signature );
	ASSERT( pCf -> ulSignatureBottom == CF_Signature );
	ASSERT( pCf -> ulMrvDrvVirtualIoBase != 0 );
	ASSERT( cmdSizeBytes != 0 );
	ASSERT( cmdBuf != NULL );
	
	//-------------------------------------------------------------------------------
	// First check if device is ready. If not then wait... upper layer must block on
	//		and wait for device on Device Busy status.
	//-------------------------------------------------------------------------------
	if ( cf_IsCmdReady( pCf ) != IX_STATUS_SUCCESS )
	{
		//AllenDBGPRINT(DBG_WARNING,("cf_SendCmd ERROR: Device is not ready for commands"));
		//DEBUGMSG(1, (TEXT("cf_SendCmd ERROR: Device is not ready for commands\r\n")));
		//RETAILMSG(1, (TEXT("cf_SendCmd ERROR: Device is not ready for commands\r\n")));

		return IX_STATUS_DEVICE_BUSY;
	}
	
	//-------------------------------------------------------------------------------
       //      Set command length
	//-------------------------------------------------------------------------------
    	NdisRawWritePortUshort(
  		 	pCf -> ulMrvDrvVirtualIoBase + CFMACREG_HCR_IO_CMD_WRITE_LEN,
	         	cmdSizeBytes );

	//-------------------------------------------------------------------------------
       //      Download command words.
	//-------------------------------------------------------------------------------
    	for( ii = 0; ii < (int)cmdSizeWords; ii++ )
    	{
        	NdisRawWritePortUshort(
  		    		pCf -> ulMrvDrvVirtualIoBase + CFMACREG_HCR_IO_CMD_WRITE_PORT,
            			*cmdBuf);
        	cmdBuf++;
    	}
    
	//-------------------------------------------------------------------------------
    	//      If cmd was not even number of bytes write the leftover byte to the device.
    	//-------------------------------------------------------------------------------
    	if ( leftOverByte )
    	{
    		NdisRawWritePortUchar(
    				pCf -> ulMrvDrvVirtualIoBase + CFMACREG_HCR_IO_CMD_WRITE_PORT,
        			(UCHAR)*((UCHAR *)cmdBuf));

    	}
	cf_UshortRegSetBits(pCf, CFMACREG_HCR_HOST_STATUS,    CFMACREG_HCR_HS_FlushDataFifo );

	//-------------------------------------------------------------------------------
	// Set the bit in host status to indicate host cmd download is complete.
	//-------------------------------------------------------------------------------
	cf_UshortRegSetBits(pCf, CFMACREG_HCR_HOST_STATUS,    CFMACREG_HCR_HS_CmdDnLdOvr );
        
	//-------------------------------------------------------------------------------
	// Set the interrupt cause bit to allow fw to get a cmd download complete interrupt.
	//-------------------------------------------------------------------------------
    	NdisRawWritePortUshort(
  				pCf -> ulMrvDrvVirtualIoBase  + CFMACREG_HCR_CARD_INT_CAUSE,
        			CFMACREG_HCR_CIC_CmdDnLdOvr);

    	return IX_STATUS_SUCCESS;
}


//************************************************************************************
//* Function: 		cf_IsFirmwareLoaded
//*	Description:	Determines if firmware is already loaded in the device.
//*                 Firmware is loaded and running if scratch port is 0x5a.
//*                 If scratch port is 0xc3, then card is ready to accept firmware
//*                 Any other value, we are hosed!
//* Returns			return true if value is 0x5a, firmware is loaded
//*                 return false for any other value, code will try to reload firmware
//*                 Assert if value is not one of the two.
//* Date:			04/02/2003
//************************************************************************************
IX_STATUS cf_IsFirmwareLoaded ( PVOID iface )
{
	UCHAR ucTemp;
	USHORT  usTemp;
	 
	PCF_OBJECT pCf = (PCF_OBJECT)iface;

/*
#ifdef IPAQ_ODD_UCHAR_ACCESS_FIX
   
	NdisRawReadPortUchar(
	    		pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT - 1 , 
		    	&usTemp);

        ucTemp = (UCHAR)(usTemp >> 8);
    
#else 

    	NdisRawReadPortUchar(
	    		pCf -> ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT, 
		    	&ucTemp);
#endif 

    DBGPRINT(DBG_FWDL,("cf_IsFirmwareLoaded: CFMACREG_CCR_SCRATCH_PORT = %x\n", ucTemp));
*/
    
	NdisRawReadPortUshort(
	    		pCf -> ulMrvDrvVirtualIoBase + 0x0000003E, // CFMACREG_CCR_SCRATCH_PORT - 1
		    	&usTemp);

       DBGPRINT(DBG_FWDL ,("cf_IsFirmwareLoaded - 1: CFMACREG_CCR_SCRATCH_PORT = %x\n", usTemp));	

       ucTemp = (UCHAR)(usTemp >> 8);

	DBGPRINT(DBG_FWDL ,("cf_IsFirmwareLoaded - 2: CFMACREG_CCR_SCRATCH_PORT = %x\n", ucTemp));		

	
	if ( ucTemp == CF_SCRATCH_FIRMWARE_READY )
	    return IX_STATUS_SUCCESS;
       else if ( ucTemp == CF_SCRATCH_BOOT_WAITING )
	    return IX_STATUS_BOOT_READY;
	else if ( ucTemp == 0x00 )
		return IX_STATUS_HOST_BOOT_READY;
	else
	    return IX_STATUS_FAILURE;
}


/******************************************************************************
 *
 * Name: cf_ReadCommandResponse()
 *
 *
 * Description: 
 *    This routine reads command responses from the card
 *
 *  Arguments:
 *      PMRVDRV_ADAPTER - Pointer to adapter object.
 *    
 *  Return Value:
 * 
 *  Notes:                
 *
 *****************************************************************************/

VOID
cf_ReadCommandResponse
(
     IN     PMRVDRV_ADAPTER  Adapter,
     IN OUT  PUCHAR          packetBuf
)
{
        USHORT packetSizeBytes = 0;
    
	int ii;
	PUSHORT packetPtr = (PUSHORT)packetBuf;		    // Word pointer to our packet.
	USHORT packetSizeWords = 0;		                //  get the whole number of words.
	USHORT leftOverByte = 0;			            // see if we divide evenly.

	ASSERT(packetBuf);
    
    	NdisRawReadPortUshort(
		        Adapter->ulMrvDrvVirtualIoBase + CFMACREG_CCR_IO_CMD_READ_LEN,
		        &packetSizeBytes);
		        
    	DBGPRINT(DBG_HWIF | DBG_ERROR,("RSPONSE length of %d bytes\n",packetSizeBytes));
    	// make sure buffer is a big as we need
    	if ( packetSizeBytes > MRVDRV_SIZE_OF_CMD_BUFFER )
    	{
       	DBGPRINT(DBG_ERROR,("ERROR: More bytes ready than size of buffer!\n"));
        	return;
    	}
    
    	if ( !packetSizeBytes )
    	{
       	DBGPRINT(DBG_ERROR,("Error: Nothing to read!\n"));
        	return;
    	}
		        
	packetSizeWords = packetSizeBytes / sizeof(USHORT);		//  get the whole number of words.
	leftOverByte = packetSizeBytes % sizeof(USHORT);			// see if we divide evenly.
	
	//-------------------------------------------------------------------------------
   	//      Download packet from the device.
	//-------------------------------------------------------------------------------
   	for( ii = 0; ii < (int)packetSizeWords; ii++ )
    	{
   		NdisRawReadPortUshort(
  				Adapter -> ulMrvDrvVirtualIoBase + CFMACREG_HCR_IO_CMD_READ_PORT,
   	        		packetPtr);
       			packetPtr++;
    	}
    	
	//-------------------------------------------------------------------------------
   	//      If cmd was not even number of bytes write the leftover byte to the device.
    	//-------------------------------------------------------------------------------
   	if ( leftOverByte )
    	{
   		NdisRawReadPortUchar(
   				Adapter -> ulMrvDrvVirtualIoBase + CFMACREG_HCR_IO_CMD_READ_PORT,
	        		((UCHAR *)packetPtr));
   	}

    	DBGPRINT(DBG_CMDRESP,("cf_ReadCommandResponse: Transfered %d bytes\n",packetSizeBytes));
 
    	return;
}


/******************************************************************************
 *
 * Name: cf_UseAndLockCfDownloadPath(), cf_ReleaseCfDownloadPath()
 *
 *
 * Description: 
 *    		The two fuctions used for exclude the Command and Tx translation 
 *    		to CF interface 
 
 *  Arguments:
 *      	PMRVDRV_ADAPTER - Pointer to adapter object.
 *    
 *  Return Value:
 * 
 *  Notes:                
 *
 *****************************************************************************/

BOOLEAN 
cf_UseAndLockCfDownloadPath( IN PMRVDRV_ADAPTER  Adapter)
{
	DBGPRINT(DBG_TXDATA ,("++ cf_UseAndLockCfDownloadPath()\n"));
	NdisAcquireSpinLock(&Adapter->lCFInterfaceLock);
    	if ( Adapter->bCFInterfaceIsBusy == TRUE )
    	{
        	NdisReleaseSpinLock(&Adapter->lCFInterfaceLock);
        	DBGPRINT(DBG_TXDATA, ("SendPacket: return RESOURCES because interface is busy!\n"));
		DBGPRINT(DBG_TXDATA ,("-- cf_UseAndLockCfDownloadPath()\n"));
        	return FALSE;
    	}
    	Adapter->bCFInterfaceIsBusy = TRUE;

    	NdisReleaseSpinLock(&Adapter->lCFInterfaceLock);
	DBGPRINT(DBG_TXDATA ,("-- cf_UseAndLockCfDownloadPath()\n"));
	
	return TRUE;
}

VOID 
cf_ReleaseCfDownloadPath( IN PMRVDRV_ADAPTER  Adapter)
{
	DBGPRINT(DBG_TXDATA ,("++ cf_ReleaseCfDownloadPath()\n"));
    	NdisAcquireSpinLock(&Adapter->lCFInterfaceLock);
    	Adapter->bCFInterfaceIsBusy = FALSE;
    	NdisReleaseSpinLock(&Adapter->lCFInterfaceLock);
	DBGPRINT(DBG_TXDATA ,("-- cf_ReleaseCfDownloadPath()\n"));
}

VOID
cf_WriteDeepSleepExit( PMRVDRV_ADAPTER Adapter, PVOID iface)
{
	USHORT  usVal;
	int i;
	PCF_OBJECT pCf = (PCF_OBJECT)iface;

	EnableInterrupt(Adapter);

	for (i=0;i<30;i++)
	{
		NdisRawReadPortUshort(
            			pCf->ulMrvDrvVirtualIoBase + CFMACREG_CCR_SCRATCH_PORT-1,
            			&usVal);
	}
       DBGPRINT(DBG_ALLEN, ("CheckForHang Read back 0x%x\n", usVal));
	
	DBGPRINT(DBG_ALLEN ,("-- cf_WriteDeepSleepExit()\n"));
	
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -