📄 mvstoragedev.c
字号:
}
/*******************************************************************************
* mvPMDevReadReg - Reads port multiplier's internal register
*
*
* DESCRIPTION:
* Performs PIO non-data command for reading port multiplier's internal
* register.
*
* INPUT:
* pAdapter - Pointer to the device data structure.
* channelIndex - Index of the required channel
* PMPort - This should be port 0xf
* PMReg - The required register to be read
* pValue - A pointer to 32bit data container that holds
* the result.
* registerStruct - A pointer to ATA register data structure. This
* holds the ATA registers dump after command
* is executed.
*
* RETURN:
* MV_TRUE on success, MV_FALSE otherwise.
* COMMENTS:
* NONE
*
*******************************************************************************/
MV_BOOLEAN mvPMDevReadReg(MV_SATA_ADAPTER *pAdapter, MV_U8 channelIndex,
MV_U8 PMPort, MV_U8 PMReg, MV_U32 *pValue,
MV_STORAGE_DEVICE_REGISTERS *registerStruct)
{
MV_SATA_CHANNEL *pSataChannel;
MV_BOOLEAN result;
if (pAdapter == NULL)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " : mvStorageDevPMReadReg"
" Failed, Bad adapter data structure pointer\n");
return MV_FALSE;
}
pSataChannel = pAdapter->sataChannel[channelIndex];
if (pSataChannel == NULL)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: channel data structu"
"re is not allocated\n", pAdapter->adapterId, channelIndex);
return MV_FALSE;
}
mvOsSemTake(&pSataChannel->semaphore);
if (pSataChannel->PMSupported == MV_FALSE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: mvStorageDevPMReadReg"
" failed PM not supported for this channel\n",
pAdapter->adapterId, channelIndex);
mvOsSemRelease( &pSataChannel->semaphore);
return MV_FALSE;
}
if (pSataChannel->queueCommandsEnabled == MV_TRUE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: mvStorageDevPMReadReg"
" command failed: EDMA is active\n",
pAdapter->adapterId, channelIndex);
mvOsSemRelease( &pSataChannel->semaphore);
return MV_FALSE;
}
result = _PMAccessReg(pAdapter, channelIndex, PMPort, PMReg, pValue,
registerStruct, MV_TRUE);
mvOsSemRelease( &pSataChannel->semaphore);
return result;
}
/*******************************************************************************
* mvPMDevWriteReg - Writes to port multiplier's internal register
*
*
* DESCRIPTION:
* Performs PIO non-data command for writing to port multiplier's internal
* register.
*
* INPUT:
* pAdapter - Pointer to the device data structure.
* channelIndex - Index of the required channel
* PMPort - This should be port 0xf
* PMReg - The required register to be read
* value - Holds 32bit of the value to be written
* registerStruct - A pointer to ATA register data structure. This
* holds the ATA registers dump after command
* is executed.
*
* RETURN:
* MV_TRUE on success, MV_FALSE otherwise.
* COMMENTS:
* NONE
*
*******************************************************************************/
MV_BOOLEAN mvPMDevWriteReg(MV_SATA_ADAPTER *pAdapter, MV_U8 channelIndex,
MV_U8 PMPort, MV_U8 PMReg, MV_U32 value,
MV_STORAGE_DEVICE_REGISTERS *registerStruct)
{
MV_SATA_CHANNEL *pSataChannel;
MV_BOOLEAN result;
if (pAdapter == NULL)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " : mvStorageDevPMWriteReg"
" Failed, Bad adapter data structure pointer\n");
return MV_FALSE;
}
pSataChannel = pAdapter->sataChannel[channelIndex];
if (pSataChannel == NULL)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: channel data structu"
"re is not allocated\n", pAdapter->adapterId, channelIndex);
return MV_FALSE;
}
mvOsSemTake(&pSataChannel->semaphore);
if (pSataChannel->PMSupported == MV_FALSE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: mvStorageDevPMWriteReg"
" failed PM not supported for this channel\n",
pAdapter->adapterId, channelIndex);
mvOsSemRelease( &pSataChannel->semaphore);
return MV_FALSE;
}
if (pSataChannel->queueCommandsEnabled == MV_TRUE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: mvStorageDevPMWriteReg"
" command failed: EDMA is active\n",
pAdapter->adapterId, channelIndex);
mvOsSemRelease( &pSataChannel->semaphore);
return MV_FALSE;
}
result = _PMAccessReg(pAdapter, channelIndex, PMPort, PMReg, &value,
registerStruct, MV_FALSE);
mvOsSemRelease( &pSataChannel->semaphore);
return result;
}
static MV_BOOLEAN _checkPMPortSStatus(MV_SATA_ADAPTER* pAdapter,
MV_U8 channelIndex,
MV_U8 PMPort,
MV_BOOLEAN *error)
{
MV_BOOLEAN result;
MV_U32 SStatus;
result = mvPMDevReadReg(pAdapter, channelIndex, PMPort,
MV_SATA_PSCR_SSTATUS_REG_NUM, &SStatus, NULL);
if (result == MV_FALSE)
{
*error = MV_TRUE;
return result;
}
*error = MV_FALSE;
SStatus &= (MV_BIT0 | MV_BIT1);
if ((SStatus == (MV_BIT0 | MV_BIT1)) || (SStatus == 0))
{
return MV_TRUE;
}
else
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, "[%d %d]"
"PM staggered spin-up - "
"SATA communication not established.\n",
pAdapter->adapterId, channelIndex);
return MV_FALSE;
}
}
/*******************************************************************************
* mvPMDevEnableStaggeredSpinUp -
*
*
* DESCRIPTION:
* Enables commnucation on a port multiplier's device SATA channel
*
* INPUT:
* pAdapter - Pointer to the device data structure.
* channelIndex - Index of the required channel
* PMPort - Required device SATA channel on port multiplier
*
* RETURN:
* MV_TRUE on success, MV_FALSE otherwise.
* COMMENTS:
* NONE
*
*******************************************************************************/
MV_BOOLEAN mvPMDevEnableStaggeredSpinUp(MV_SATA_ADAPTER *pAdapter,
MV_U8 channelIndex, MV_U8 PMPort)
{
MV_BOOLEAN result;
result = mvPMDevWriteReg(pAdapter, channelIndex, PMPort,
MV_SATA_PSCR_SCONTROL_REG_NUM, 0x311, NULL);
if (result == MV_FALSE)
{
return result;
}
mvMicroSecondsDelay(pAdapter, MV_SATA_COMM_INIT_DELAY);
result = mvPMDevWriteReg(pAdapter, channelIndex, PMPort,
MV_SATA_PSCR_SCONTROL_REG_NUM, 0x310, NULL);
return result;
}
/*******************************************************************************
* mvPMDevEnableStaggeredSpinUpAll -
*
*
* DESCRIPTION:
* Enables commnucation on all port multiplier's device SATA channels
*
* INPUT:
* pAdapter - Pointer to the device data structure.
* channelIndex - Index of the required channel
* PMNumOfPorts - Number of device SATA channel the port multiplier
* has.
* bitmask - A pointer to 16bit data container that holds
* a bitmask of '1' when the relevant port multiplier's
* device port staggered spinup operation is success.
*
* RETURN:
* MV_TRUE on success, MV_FALSE otherwise.
* COMMENTS:
* NONE
*
*******************************************************************************/
MV_BOOLEAN mvPMDevEnableStaggeredSpinUpAll(MV_SATA_ADAPTER *pSataAdapter,
MV_U8 channelIndex,
MV_U8 PMNumOfPorts,
MV_U16 *bitmask)
{
MV_U8 PMPort;
MV_U8 retryCount;
MV_U8 tmpBitmask = 1;
if (bitmask == NULL)
{
return MV_FALSE;
}
/*Do not issue staggered spinup for port 0 - already done because of
legacy port mode*/
*bitmask = 1;
for (PMPort = 1; PMPort < PMNumOfPorts; PMPort++)
{
if (mvPMDevEnableStaggeredSpinUp(pSataAdapter,
channelIndex,
PMPort) == MV_TRUE)
{
tmpBitmask |= (1 << PMPort);
}
else
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR,
"Error [%d %d %d]: "
"PM enable staggered spin-up failed.\n",
pSataAdapter->adapterId, channelIndex, PMPort);
return MV_FALSE;
}
}
mvMicroSecondsDelay(pSataAdapter, MV_SATA_COMM_INIT_WAIT_DELAY);
for (retryCount = 0; retryCount < 200; retryCount++)
{
for (PMPort = 0; PMPort < PMNumOfPorts; PMPort++)
{
MV_BOOLEAN error;
if ((*bitmask) & (1 << PMPort))
{
continue;
}
if (_checkPMPortSStatus(pSataAdapter,
channelIndex, PMPort, &error) == MV_FALSE)
{
if (error == MV_TRUE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR,
"[%d %d %d]: "
"Fatal error - cannot read PM port SStatus.\n",
pSataAdapter->adapterId, channelIndex, PMPort);
break;
}
mvMicroSecondsDelay(pSataAdapter, 1000);
}
else
{
if (bitmask != NULL)
{
*bitmask |= (1 << PMPort);
}
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG,
"[%d %d %d] PM SATA PHY ready after %d msec\n",
pSataAdapter->adapterId, channelIndex,
PMPort, retryCount);
}
}
if (tmpBitmask == *bitmask)
{
break;
}
}
if (tmpBitmask != *bitmask)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -