📄 cf_ifc.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 + -