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

📄 mvialcommon.c

📁 此为marvell 6081芯片驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************************
*       (c), Copyright 2001, Marvell International Ltd.                        *
* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL SEMICONDUCTOR, INC.   *
* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT  *
* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE        *
* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL.     *
* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED,       *
* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE.   *
********************************************************************************
* mvIALCommon.c
*
* DESCRIPTION:
*    C implementation for IAL's common functions.
*
* DEPENDENCIES:
*    mvIALCommon.h.
*
*******************************************************************************/

/* includes */
#include "mvOs.h"
#include "mvScsiAtaLayer.h"
#include "mvIALCommon.h"
#include "mvIALCommonUtils.h"
#include "mvStorageDev.h"


/* defines */
#undef DISABLE_PM_SCC
#undef ALLOW_NCQ
/* typedefs */

/*Static functions*/
static MV_BOOLEAN mvGetEDMAAllowedModes(MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
										MV_SAL_ADAPTER_EXTENSION *pScsiAdapterExt,
										MV_U8 channelIndex,
										MV_BOOLEAN *TCQ,
										MV_BOOLEAN *NCQ,
										MV_U8   *queueDepth,
										MV_U8   *numOfDrives);

static void mvFlushSCSICommandQueue(MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
									MV_U8 channelIndex);

static void mvAddToSCSICommandQueue(MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
									MV_U8 channelIndex,
									MV_SATA_SCSI_CMD_BLOCK *Scb);

static MV_BOOLEAN mvAdapterStateMachine(
									   MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
									   MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt);

static MV_BOOLEAN mvChannelStateMachine(
									   MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
									   MV_U8 channelIndex,
									   MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt);

static void mvSetChannelState(MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
							  MV_U8 channelIndex,
							  MV_CHANNEL_STATE state);


/*PM related*/
static MV_BOOLEAN mvPMCommandCompletionCB(MV_SATA_ADAPTER *pSataAdapter,
										  MV_U8 channelIndex,
										  MV_COMPLETION_TYPE comp_type,
										  MV_VOID_PTR commandId,
										  MV_U16 responseFlags,
										  MV_U32 timeStamp,
										  MV_STORAGE_DEVICE_REGISTERS *registerStruct);


static MV_BOOLEAN mvQueuePMAccessRegisterCommand(
												MV_IAL_COMMON_ADAPTER_EXTENSION* ialExt,
												MV_U8 channelIndex,
												MV_U8 PMPort,
												MV_U8 PMReg,
												MV_U32 Value,
												MV_BOOLEAN isRead);




static MV_BOOLEAN mvPMEstablishSataComm(
									   MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
									   MV_U8 channelIndex);

static MV_BOOLEAN mvPMCheckForConnectedDevices(
											  MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
											  MV_U8 channelIndex,
											  MV_BOOLEAN* bIsChannelReady);


static MV_BOOLEAN mvInitPMDevice(MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
								 MV_U8 channelIndex,
								 MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt,
								 MV_BOOLEAN* bIsChannelReady,
								 MV_BOOLEAN* isDeviceReconnected,
								 MV_BOOLEAN* bPMErrorDetected);

static MV_BOOLEAN mvPMEnableCommStatusChangeBits(MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
												 MV_U8 channelIndex,
												 MV_BOOLEAN enable);

static MV_BOOLEAN mvPMEnableAsyncNotify(
									   MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
									   MV_U8 channelIndex);


static void mvCheckPMForError(MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
							  MV_U8 channelIndex);

/*End PM related*/

static MV_BOOLEAN mvStartChannelInit(MV_SATA_ADAPTER *pSataAdapter,
									 MV_U8 channelIndex,
									 MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt,
									 MV_BOOLEAN *isChannelReady);

static MV_BOOLEAN mvChannelSRSTFinished(MV_SATA_ADAPTER *pSataAdapter,
										MV_SATA_CHANNEL *pSataChannel,
										MV_U8 channelIndex,
										MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt,
										MV_BOOLEAN* bIsChannelReady,
										MV_BOOLEAN* bFatalError);

static MV_BOOLEAN mvConfigChannelQueuingMode(
											MV_IAL_COMMON_ADAPTER_EXTENSION* ialExt,
											MV_U8 channelIndex,
											MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt);

static MV_BOOLEAN mvConfigChannelDMA(
									MV_IAL_COMMON_ADAPTER_EXTENSION* ialExt,
									MV_U8 channelIndex,
									MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt);

static void mvSetChannelTimer(MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
							  MV_U8 channelIndex,
							  MV_U32 timeout);
static void mvDecrementChannelTimer(MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
									MV_U8 channelIndex);
static MV_BOOLEAN mvIsChannelTimerExpired(
										 MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
										 MV_U8 channelIndex);


/*Channel state machine*/


static MV_BOOLEAN mvChannelNotConnectedStateHandler(
												   MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
												   MV_U8 channelIndex,
												   MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt);


static MV_BOOLEAN mvChannelConnectedStateHandler(
												MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
												MV_U8 channelIndex,
												MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt);

MV_BOOLEAN mvChannelInSrstStateHandler(
									  MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
									  MV_U8 channelIndex,
									  MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt);

static MV_BOOLEAN mvChannelPMStaggeredSpinUpStateHandler(
														MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
														MV_U8 channelIndex,
														MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt);

static MV_BOOLEAN mvChannelPMSrstDeviceStateHandler(
												   MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
												   MV_U8 channelIndex,
												   MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt);

static MV_BOOLEAN mvChannelReadyStateHandler(
											MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
											MV_U8 channelIndex);

static MV_BOOLEAN mvChannelPMHotPlugStateHandler(
												MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
												MV_U8 channelIndex,
												MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt);


#ifdef DISABLE_PM_SCC
MV_BOOLEAN mvPMDisableSSC(MV_SATA_ADAPTER *pSataAdapter, MV_U8 channelIndex);
#endif

#ifdef ALLOW_NCQ
MV_BOOLEAN mvPMEnableLocking(MV_SATA_ADAPTER *pSataAdapter, MV_U8 channelIndex);
#endif



/*Public functions*/

/*******************************************************************************
* mvAdapterStartInitialization - start adapter initialization
*
* DESCRIPTION:
*  Starts adapter initialization after driver load.
*  State - machine related data structure is initialized for adapter
*  and its channels. Begin staggered spin-up.
*  Adapter state is changed to ADAPTER_READY.
* INPUT:
*    pAdapter    - pointer to the adapter data structure.
*    scsiAdapterExt  - SCSI to ATA layer adapter extension data structure
* OUTPUT:
*    None.
*
* RETURN:
*    MV_TRUE on success
*    MV_FALSE on error
*
*******************************************************************************/

MV_BOOLEAN mvAdapterStartInitialization(MV_SATA_ADAPTER *pSataAdapter,
										MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
										MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt)
{
	MV_U8 channelIndex;
	ialExt->pSataAdapter = pSataAdapter;
	ialExt->adapterState = ADAPTER_INITIALIZING;
	for (channelIndex = 0; channelIndex < MV_SATA_CHANNELS_NUM; channelIndex++)
	{
		ialExt->channelState[channelIndex] = CHANNEL_NOT_CONNECTED;
		ialExt->IALChannelExt[channelIndex].SRSTTimerThreshold = 0;
		ialExt->IALChannelExt[channelIndex].SRSTTimerValue = 0;
		ialExt->IALChannelExt[channelIndex].IALChannelPendingCmdQueue = NULL;
		ialExt->IALChannelExt[channelIndex].completionError = MV_FALSE;
		ialExt->IALChannelExt[channelIndex].pmRegAccessInProgress = MV_FALSE;
		ialExt->IALChannelExt[channelIndex].devInSRST =
		MV_SATA_PM_CONTROL_PORT + 1;
		ialExt->IALChannelExt[channelIndex].PMdevsToInit = 0;
		ialExt->IALChannelExt[channelIndex].PMnumberOfPorts = 0;
		ialExt->IALChannelExt[channelIndex].pmAccessType = 0;
		ialExt->IALChannelExt[channelIndex].pmReg = 0;
		ialExt->IALChannelExt[channelIndex].pmAsyncNotifyEnabled = MV_FALSE;
	}
	return mvAdapterStateMachine(ialExt, scsiAdapterExt);
}


/*******************************************************************************
* mvRestartChannel - restart specific channel
*
* DESCRIPTION:
*  The function is used in channel hot-plug to restart the channel
*  initialization sequence. The channel stated is changed to
*  CHANNEL_CONNECTED and any pending command in software queue are flushed
* INPUT:
*    pAdapter    - pointer to the adapter data structure.
*    channelIndex  - channel number
*    scsiAdapterExt  - SCSI to ATA layer adapter extension data structure
*    bBusReset       - MV_TRUE if the faunction is called because of bus reset,
*                       MV_FALSE otherwise
* OUTPUT:
*    None.
*
* RETURN:
*    MV_TRUE on success
*    MV_FALSE on error
*
*******************************************************************************/

void mvRestartChannel(MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
					  MV_U8 channelIndex,
					  MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt,
					  MV_BOOLEAN bBusReset)
{
	MV_SATA_ADAPTER *pSataAdapter = ialExt->pSataAdapter;
	MV_BOOLEAN bBusChangeNotify = MV_FALSE;
	mvSataScsiSetDriveReady(scsiAdapterExt,
							channelIndex, 0xFF, MV_FALSE);
	if (pSataAdapter->sataChannel[channelIndex] != NULL)
	{
		if (mvStorageDevGetDeviceType(pSataAdapter,channelIndex)
			 == MV_SATA_DEVICE_TYPE_PM)
		{
			bBusChangeNotify = MV_TRUE;
		}
		mvSataDisableChannelDma(pSataAdapter, channelIndex);
		mvSataFlushDmaQueue (pSataAdapter, channelIndex,
							 MV_FLUSH_TYPE_CALLBACK);
	}
	mvFlushSCSICommandQueue(ialExt, channelIndex);
	ialExt->IALChannelExt[channelIndex].SRSTTimerThreshold = 0;
	ialExt->IALChannelExt[channelIndex].SRSTTimerValue = 0;
	if (pSataAdapter->sataChannel[channelIndex] != NULL)
	{
		mvSataRemoveChannel(pSataAdapter,channelIndex);
		IALReleaseChannel(pSataAdapter, channelIndex);
		pSataAdapter->sataChannel[channelIndex] = NULL;
	}
	ialExt->channelState[channelIndex] = CHANNEL_CONNECTED;
	if (bBusReset == MV_TRUE)
	{
		if (bBusChangeNotify == MV_TRUE)
		{
			/*Notify about bus change*/
			IALBusChangeNotify(pSataAdapter, channelIndex);
		}
	}
	else
	{
		/*Notify about bus change*/
		IALBusChangeNotify(pSataAdapter, channelIndex);
	}
}



/*******************************************************************************
* mvPMHotPlugDetected - restart specific channel
*
* DESCRIPTION:
*  The function is used in PM hot-plug to wait for empty EDMA command queue
*  and then restart the channel initialization sequence.
*  The channel stated is changed to CHANNEL_PM_HOT_PLUG if there are any
*  pending command in EDMA queue
* INPUT:
*    pAdapter    - pointer to the adapter data structure.
*    channelIndex  - channel number

* OUTPUT:
*    None.
*
* RETURN:
*    None
*
*******************************************************************************/

void mvPMHotPlugDetected(MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
						 MV_U8 channelIndex,
						 MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt)
{
	if (ialExt->channelState[channelIndex] == CHANNEL_NOT_CONNECTED ||
		ialExt->channelState[channelIndex] == CHANNEL_CONNECTED ||
		ialExt->channelState[channelIndex] == CHANNEL_IN_SRST)
	{
		return;
	}
	mvSataDisableChannelDma(ialExt->pSataAdapter, channelIndex);
	mvSataFlushDmaQueue (ialExt->pSataAdapter,
						 channelIndex, MV_FLUSH_TYPE_CALLBACK);
	mvSataChannelHardReset(ialExt->pSataAdapter, channelIndex);
	mvRestartChannel(ialExt, channelIndex, scsiAdapterExt, MV_FALSE);
}

/*******************************************************************************
* mvStopChannel - stop channel
*
* DESCRIPTION:
*  The function is used when the channel is unplugged.
*  The channel stated is changed to CHANNEL_NOT_CONNECTED
*  until further connection.
* INPUT:
*    pAdapter    - pointer to the adapter data structure.
*    channelIndex  - channel number
* OUTPUT:
*    None.
*
* RETURN:
*    None
*******************************************************************************/
void mvStopChannel(MV_IAL_COMMON_ADAPTER_EXTENSION *ialExt,
				   MV_U8 channelIndex,
				   MV_SAL_ADAPTER_EXTENSION *scsiAdapterExt)
{
	MV_SATA_ADAPTER *pSataAdapter = ialExt->pSataAdapter;
	mvSataScsiSetDriveReady(scsiAdapterExt, channelIndex, 0xFF, MV_FALSE);
	mvSetChannelState(ialExt, channelIndex, CHANNEL_NOT_CONNECTED);
	if (pSataAdapter->sataChannel[channelIndex] != NULL)
	{
		mvSataDisableChannelDma(ialExt->pSataAdapter, channelIndex);
		mvSataFlushDmaQueue (ialExt->pSataAdapter, channelIndex,
							 MV_FLUSH_TYPE_CALLBACK);
	}
	mvFlushSCSICommandQueue(ialExt, channelIndex);
	if (pSataAdapter->sataChannel[channelIndex] != NULL)
	{
		mvSataRemoveChannel(pSataAdapter,channelIndex);
		IALReleaseChannel(pSataAdapter, channelIndex);
	}
	pSataAdapter->sataChannel[channelIndex] = NULL;
	/*Notify about bus change*/
	IALBusChangeNotify(pSataAdapter, channelIndex);
}


/*******************************************************************************
* mvExecuteScsiCommand - execute SCSI command
*
* DESCRIPTION:
*  IAL common layer wrapper of mvSataExecuteScsiCommand function.
*  If either the adapter state is either other than ADAPTER_READY
*  or the channel is connected but channel state is not CHANNEL_READY,
*  the current SCSI command is queued in channel's SCSI commands
*  software queue until channel initialization sequence completed.
*  If channel is found in CHANNEL ready state the SCSI command is passed to
*  SCSI ATA translation layer.
* INPUT:
*    pScb    - SCSI command block structure.
*
* OUTPUT:
*    None.
*
* RETURN:
*    Return MV_SCSI_COMMAND_STATUS_COMPLETED if the command has been added

⌨️ 快捷键说明

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