📄 mvstoragedev.c
字号:
channelIndex);
return MV_FALSE;
}
ioBaseAddr =pSataChannel->mvSataAdapter->adapterIoBaseAddress;
mvOsSemTake(&pSataChannel->semaphore);
eDmaRegsOffset = pSataChannel->eDmaRegsOffset;
if (pSataChannel->queueCommandsEnabled == MV_TRUE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: mvStorageDevATAIdle"
"Immediate command failed: EDMA is active\n",
pSataChannel->mvSataAdapter->adapterId,
pSataChannel->channelNumber);
mvOsSemRelease( &pSataChannel->semaphore);
return MV_FALSE;
}
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_NON_UDMA_COMMAND | MV_DEBUG_ERROR, "Issue IDLE IMMEDIATE COMMAND\n");
disableStorageDevInterrupt(pSataChannel);
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset + MV_ATA_DEVICE_COMMAND_REG_OFFSET,
MV_ATA_COMMAND_IDLE_IMMEDIATE);
if (waitWhileStorageDevIsBusy(pAdapter,
ioBaseAddr, eDmaRegsOffset, 10000, 100) == MV_FALSE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: Idle Immediate failed\n",
pSataChannel->mvSataAdapter->adapterId, pSataChannel->channelNumber);
enableStorageDevInterrupt(pSataChannel);
mvOsSemRelease( &pSataChannel->semaphore);
return MV_FALSE;
}
enableStorageDevInterrupt(pSataChannel);
mvOsSemRelease( &pSataChannel->semaphore);
return MV_TRUE;
}
/*******************************************************************************
* mvStorageDevATAIdentifyDevice - Perform an ATA IDENTIFY device command.
*
* DESCRIPTION:
* This function issues an IDENTIFY command to the connected device, and
* stores all the information in the identifyDevice buffer of the channel.
*
* INPUT:
* pAdapter - Pointer to the device data structure.
* channelIndex - The index of the channel where the storage device
* connected to.
* PMPort - index of the required destination port multipliers
* device Port (0 if no PM available).
* identifyDeviceResult - a buffer that is allocated by IAL that will hold
* the IDENTIFY DEIVICE command result.
*
* RETURN:
* MV_TRUE on success, MV_FALSE on failure.
*
* COMMENTS:
* None.
*
*******************************************************************************/
MV_BOOLEAN mvStorageDevATAIdentifyDevice(MV_SATA_ADAPTER *pAdapter,
MV_U8 channelIndex,
MV_U8 PMPort,
MV_U16_PTR identifyDeviceResult
)
{
MV_BOOLEAN result;
/* Get the pointer to the relevant channel. */
MV_SATA_CHANNEL *pSataChannel;
if (pAdapter == NULL)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " : mvStorageDevATAIdentif"
"yDevice failed, Bad adapter data structure pointer\n");
return MV_FALSE;
}
pSataChannel = pAdapter->sataChannel[channelIndex];
if (pSataChannel == NULL)
{ /* If the pointer do not exists, retrun false */
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: channel data "
"structure is not allocated\n", pAdapter->adapterId,
channelIndex);
return MV_FALSE;
}
if (identifyDeviceResult == NULL)
{ /* If the pointer do not exists, retrun false */
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: identify data buffer"
" is not allocated\n", pAdapter->adapterId, channelIndex);
return MV_FALSE;
}
result = mvStorageDevATAExecuteNonUDMACommand(pAdapter, channelIndex,
PMPort,
MV_NON_UDMA_PROTOCOL_PIO_DATA_IN,
MV_FALSE,
/* pBuffer */
identifyDeviceResult,
256, /* count */
0, /* features */
0, /* sectorCount */
0, /* lbaLow */
0, /* lbaMid */
0, /* lbaHigh */
0, /* device */
/* The command */
MV_ATA_COMMAND_IDENTIFY);
if (result == MV_FALSE)
{
return MV_FALSE;
}
if (identifyDeviceResult[IDEN_ATA_VERSION] & (MV_BIT7 | MV_BIT6 | MV_BIT5))
{
/* if ATA 5/6/7 then check CRC of Identify command result */
MV_U8 crc = 0;
MV_U16 count;
MV_U8_PTR pointer = (MV_U8_PTR)identifyDeviceResult;
/* If no 0xa5 signature valid, then don't check CRC */
if (pointer[510] != 0xa5)
{
return MV_TRUE;
}
for (count = 0 ; count < 512 ; count ++)
{
crc += pointer[count];
}
if (crc != 0)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: IDENTIFY DEVICE "
"ATA Command failed due to wrong CRC checksum (%02x)\n",
pAdapter->adapterId, channelIndex,crc);
return MV_FALSE;
}
}
return MV_TRUE;
}
/*******************************************************************************
* mvStorageDevATASoftResetDevice - Issue SATA SOFTWARE reset to device.
*
* DESCRIPTION:
* Perform SOFTWARE RESET to the connected storage device by setting the
* SRST bit of the ATA device COMMAND
*
* INPUT:
* pAdapter - Pointer to the device data structure.
* channelIndex - Index of the required channel.
* PMPort - index of the required destination port multipliers
* device port (0 if no PM available).
* registerStruct - Pointer to ATA registers data structure
*
* RETURN:
* MV_TRUE on success, MV_FALSE otherwise.
*
* COMMENTS:
* NONE
*
*******************************************************************************/
MV_BOOLEAN mvStorageDevATASoftResetDevice(MV_SATA_ADAPTER *pAdapter,
MV_U8 channelIndex,
MV_U8 PMPort,
MV_STORAGE_DEVICE_REGISTERS *registerStruct
)
{
MV_SATA_CHANNEL *pSataChannel;
MV_BUS_ADDR_T ioBaseAddr;
MV_U32 eDmaRegsOffset;
MV_BOOLEAN result;
if (pAdapter == NULL)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " : mvStorageDevATASoftRes"
"etDevice Failed, Bad adapter data structure pointer\n");
return MV_FALSE;
}
pSataChannel = pAdapter->sataChannel[channelIndex];
ioBaseAddr = pAdapter->adapterIoBaseAddress;
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);
eDmaRegsOffset = pSataChannel->eDmaRegsOffset;
if (pSataChannel->queueCommandsEnabled == MV_TRUE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: mvStorageDevATASoft"
"ResetDevice command failed: EDMA is active\n",
pSataChannel->mvSataAdapter->adapterId,
pSataChannel->channelNumber);
mvOsSemRelease( &pSataChannel->semaphore);
return MV_FALSE;
}
_setActivePMPort(pSataChannel, PMPort);
result = _doSoftReset(pSataChannel);
if (registerStruct)
{
dumpAtaDeviceRegisters(pAdapter, channelIndex, MV_FALSE,
registerStruct);
}
mvOsSemRelease( &pSataChannel->semaphore);
return result;
}
void _startSoftResetDevice(MV_SATA_CHANNEL *pSataChannel)
{
MV_BUS_ADDR_T ioBaseAddr =
pSataChannel->mvSataAdapter->adapterIoBaseAddress;
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_NON_UDMA_COMMAND | MV_DEBUG, "Issue SRST COMMAND\n");
/* Write to the Device Control register, bits 1,2: */
/* - bit 1 (nIEN): is the enable bit for the device assertion of INTRQ */
/* to the host. When the nIEN bit is set to one, or the device is not */
/* selected, the device shall release the INTRQ signal. */
/* - bit 2 (SRST): is the host software reset bit. */
MV_REG_WRITE_BYTE(ioBaseAddr, pSataChannel->eDmaRegsOffset +
MV_ATA_DEVICE_CONTROL_REG_OFFSET, MV_BIT2|MV_BIT1);
MV_REG_READ_BYTE(ioBaseAddr, pSataChannel->eDmaRegsOffset +
MV_ATA_DEVICE_CONTROL_REG_OFFSET);
mvMicroSecondsDelay(pSataChannel->mvSataAdapter, 10);
/* enableStorageDevInterrupt will clear the SRST bit*/
enableStorageDevInterrupt(pSataChannel);
}
MV_BOOLEAN _isDeviceBsyBitOff(MV_SATA_CHANNEL *pSataChannel)
{
MV_BUS_ADDR_T ioBaseAddr =
pSataChannel->mvSataAdapter->adapterIoBaseAddress;
MV_U8 ATAstatus;
MV_U32 eDmaRegsOffset = pSataChannel->eDmaRegsOffset;
ATAstatus = MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_STATUS_REG_OFFSET);
if ((ATAstatus & MV_ATA_BUSY_STATUS) == 0)
{
return MV_TRUE;
}
else
{
#ifdef MV_LOGGER
if (pSataChannel->mvSataAdapter->sataAdapterGeneration
== MV_SATA_GEN_II)
{
MV_U32 ifStatus = MV_REG_READ_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_SATA_II_IF_STATUS_REG_OFFSET);
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG,
"[%d %d] SATA interface status register = 0x%X\n",
pSataChannel->mvSataAdapter->adapterId,
pSataChannel->channelNumber,
ifStatus);
}
#endif
return MV_FALSE;
}
}
/*******************************************************************************
* mvStorageDevATAStartSoftResetDevice -
* begins device software reset
*
* DESCRIPTION:
*
* Submits SRST for channel connected device and exit. The IAL must call the
* mvStorageIsDeviceBsyBitOff later on to check whether the device is
* ready
*
* INPUT:
* pAdapter - pointer to the adapter data structure.
* channelIndex - channel number
* PMPort - port multiplier port
*
* OUTPUT:
* None
* RETURN:
* MV_TRUE on success,
* MV_FALSE otherwise.
* COMMENTS:
*
*******************************************************************************/
MV_BOOLEAN mvStorageDevATAStartSoftResetDevice(MV_SATA_ADAPTER *pAdapter,
MV_U8 channelIndex,
MV_U8 PMPort
)
{
MV_SATA_CHANNEL *pSataChannel;
MV_BUS_ADDR_T ioBaseAddr;
if (pAdapter == NULL)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " : mvStorageDevATASoftRes"
"etDevice Failed, Bad adapter data structure pointer\n");
return MV_FALSE;
}
pSataChannel = pAdapter->sataChannel[channelIndex];
ioBaseAddr = pAdapter->adapterIoBaseAddress;
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->queueCommandsEnabled == MV_TRUE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: mvStorageDevATASoft"
"ResetDevice command failed: EDMA is active\n",
pSataChannel->mvSataAdapter->adapterId,
pSataChannel->channelNumber);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -