📄 mvstoragedev.c
字号:
mvOsSemRelease( &pSataChannel->semaphore);
return MV_FALSE;
}
_setActivePMPort(pSataChannel, PMPort);
_startSoftResetDevice(pSataChannel);
mvOsSemRelease( &pSataChannel->semaphore);
return MV_TRUE;
}
/*******************************************************************************
* mvStorageIsDeviceBsyBitOff -
* check if device is BUSY bit cleared after SRST
*
* DESCRIPTION:
*
* Checks the if BSY bit in ATA status is on/off
*
* INPUT:
* pAdapter - pointer to the adapter data structure.
* channelIndex - channel number
* registerStruct - If non-zero then this function dumps ATA registers
* to this data structure before exit.
*
* OUTPUT:
* None
* RETURN:
* MV_TRUE if BSY bit is off
* MV_FALSE if BSY bit is on (or on failure)
* COMMENTS:
*
*******************************************************************************/
MV_BOOLEAN mvStorageIsDeviceBsyBitOff(MV_SATA_ADAPTER *pAdapter,
MV_U8 channelIndex,
MV_STORAGE_DEVICE_REGISTERS *registerStruct
)
{
MV_SATA_CHANNEL *pSataChannel;
MV_BUS_ADDR_T ioBaseAddr;
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);
result = _isDeviceBsyBitOff(pSataChannel);
if (registerStruct)
{
dumpAtaDeviceRegisters(pAdapter, channelIndex, MV_FALSE,
registerStruct);
}
mvOsSemRelease( &pSataChannel->semaphore);
return result;
}
/*******************************************************************************
* mvStorageDevATASetFeatures - Perform ATA SET FEATURES command.
*
* DESCRIPTION:
* Perform ATA SET FEATURES command to the ATA device connected to the
* given channel. This command is used by the host to establish parameters
* that affect the execution of certain device features (Table 44 in the
* ATA protocol document defines these features).
*
* 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).
* subCommand - Sub command for the SET FEATURES ATA command
* subCommandSpecific1 - First parameter to the sub command.
* subCommandSpecific2 - Second parameter to the sub command.
* subCommandSpecific3 - Third parameter to the sub command.
* subCommandSpecific4 - Fourth parameter to the sub command.
*
* RETURN:
* MV_TRUE on success, MV_FALSE otherwise.
* COMMENTS:
* NONE
*
*******************************************************************************/
MV_BOOLEAN mvStorageDevATASetFeatures(MV_SATA_ADAPTER *pAdapter,
MV_U8 channelIndex,
MV_U8 PMPort,
MV_U8 subCommand,
MV_U8 subCommandSpecific1,
MV_U8 subCommandSpecific2,
MV_U8 subCommandSpecific3,
MV_U8 subCommandSpecific4)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG|MV_DEBUG_NON_UDMA_COMMAND,
"ATA Set Features: %x , %x , %x , %x , %x\n", subCommand,
subCommandSpecific1, subCommandSpecific2, subCommandSpecific3,
subCommandSpecific4);
return mvStorageDevATAExecuteNonUDMACommand(pAdapter, channelIndex,
PMPort,
MV_NON_UDMA_PROTOCOL_NON_DATA,
MV_FALSE,
NULL, /* pBuffer*/
0, /* count */
subCommand, /*features*/
/* sectorCount */
subCommandSpecific1,
subCommandSpecific2, /* lbaLow */
subCommandSpecific3, /* lbaMid */
/* lbaHigh */
subCommandSpecific4,
0, /* device */
/* command */
MV_ATA_COMMAND_SET_FEATURES);
}
/*******************************************************************************
* mvStorageDevATAExecuteNonUdmaCommand - perform ATA non udma command.
*
* DESCRIPTION:
* perform ATA non UDMA command to the ATA device connected to the given
* channel
*
* 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).
* protocolType - protocol type of the command
* isEXT - true when the given command is the EXTENDED
* bufPtr - pointer to the buffer to write/read to/from
* count - number of words to transfer
* features - the value to be written to the FEATURES register
* sectorCount - the value to be written to the SECTOR COUNT register
* lbaLow - the value to be written to the LBA LOW register
* lbaMid - the value to be written to the LBA MID register
* lbaHigh - the value to be written to the LBA HIGH register
* device - the value to be written to the DEVICE register
* command - the value to be written to the COMMAND register
*
* RETURN:
* MV_TRUE on success, MV_FALSE otherwise.
* COMMENTS:
* when the command is EXTENDED, then the high 8 bits of the 16 bits values
* will be written first, so they should hold the previous value as defined in
* the ATA 6 standard
*
*******************************************************************************/
MV_BOOLEAN mvStorageDevATAExecuteNonUDMACommand(MV_SATA_ADAPTER *pAdapter,
MV_U8 channelIndex,
MV_U8 PMPort,
MV_NON_UDMA_PROTOCOL protocolType,
MV_BOOLEAN isEXT,
MV_U16_PTR bufPtr, MV_U32 count,
MV_U16 features,
MV_U16 sectorCount,
MV_U16 lbaLow, MV_U16 lbaMid,
MV_U16 lbaHigh, MV_U8 device,
MV_U8 command)
{
MV_BOOLEAN result;
if (pAdapter == NULL)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " : mvStorageDevATAExecute"
"NonUDMACommand Failed, Bad adapter data structure pointer\n");
return MV_FALSE;
}
if (pAdapter->sataChannel[channelIndex] == NULL)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: mvStorageDevATAExecu"
"teNonUDMACommand Failed, channel data structure not allocated"
"\n",
pAdapter->adapterId, channelIndex);
return MV_FALSE;
}
mvOsSemTake(&pAdapter->sataChannel[channelIndex]->semaphore);
result = executeNonUDMACommand(pAdapter, channelIndex, PMPort, protocolType,
isEXT, bufPtr, count, features, sectorCount,
lbaLow, lbaMid, lbaHigh, device, command);
mvOsSemRelease(&pAdapter->sataChannel[channelIndex]->semaphore);
return result;
}
MV_BOOLEAN executeNonUDMACommand(MV_SATA_ADAPTER *pAdapter,
MV_U8 channelIndex,
MV_U8 PMPort,
MV_NON_UDMA_PROTOCOL protocolType,
MV_BOOLEAN isEXT,
MV_U16_PTR bufPtr, MV_U32 count,
MV_U16 features,
MV_U16 sectorCount,
MV_U16 lbaLow, MV_U16 lbaMid,
MV_U16 lbaHigh, MV_U8 device,
MV_U8 command)
{
MV_SATA_CHANNEL *pSataChannel = pAdapter->sataChannel[channelIndex];
MV_BUS_ADDR_T ioBaseAddr = pAdapter->adapterIoBaseAddress;
MV_U32 eDmaRegsOffset;
MV_U32 i;
MV_U8 ATAstatus;
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG|MV_DEBUG_NON_UDMA_COMMAND, " %d %d Issue NON "
"UDMA command: protocol(%d) %p , %x , %x , %x , %x.%x.%x %x "
"command=%x\n", pAdapter->adapterId, channelIndex, protocolType,
bufPtr, count, features, sectorCount, lbaLow, lbaMid,
lbaHigh, device, command);
eDmaRegsOffset = pSataChannel->eDmaRegsOffset;
if ((PMPort) && ((pSataChannel->PMSupported == MV_FALSE) ||
(pSataChannel->deviceType != MV_SATA_DEVICE_TYPE_PM)))
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: executeNonUDMACommand"
" failed PM not supported for this channel\n",
pSataChannel->mvSataAdapter->adapterId,
pSataChannel->channelNumber);
mvOsSemRelease( &pSataChannel->semaphore);
return MV_FALSE;
}
if (command != MV_ATA_COMMAND_PM_READ_REG &&
command != MV_ATA_COMMAND_PM_WRITE_REG)
{
if (isStorageDevReadyForPIO(pSataChannel) == MV_FALSE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID,
MV_DEBUG_ERROR | MV_DEBUG_NON_UDMA_COMMAND,
" %d %d : Error in Issue NON UDMA command:"
" isStorageDevReadyForPIO failed\n",
pAdapter->adapterId, channelIndex);
return MV_FALSE;
}
}
_setActivePMPort(pSataChannel, PMPort);
if (pSataChannel->queueCommandsEnabled == MV_TRUE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, " %d %d: PIO command failed:"
"EDMA is active\n", pSataChannel->mvSataAdapter->adapterId,
pSataChannel->channelNumber);
return MV_FALSE;
}
disableStorageDevInterrupt(pSataChannel);
if (isEXT == MV_TRUE)
{
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_FEATURES_REG_OFFSET,
(features & 0xff00) >> 8);
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_SECTOR_COUNT_REG_OFFSET,
(sectorCount & 0xff00) >> 8);
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_LBA_LOW_REG_OFFSET,
(lbaLow & 0xff00) >> 8);
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_LBA_MID_REG_OFFSET,
(lbaMid & 0xff00) >> 8);
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_LBA_HIGH_REG_OFFSET,
(lbaHigh & 0xff00) >> 8);
}
else
{
if ((features & 0xff00) || (sectorCount & 0xff00) || (lbaLow & 0xff00) ||
(lbaMid & 0xff00) || (lbaHigh & 0xff00))
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR | MV_DEBUG_NON_UDMA_COMMAND,
" %d %d : Error in Issue NON UDMA command:"
" bits[15:8] of register values should be reserved"
" Features 0x%02x, SectorCount 0x%02x, LBA Low 0x%02x,"
" LBA Mid 0x%02x, LBA High 0x%02x\n",
pAdapter->adapterId, channelIndex, features,
sectorCount, lbaLow, lbaMid, lbaHigh);
enableStorageDevInterrupt(pSataChannel);
return MV_FALSE;
}
}
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_FEATURES_REG_OFFSET, features & 0xff);
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_SECTOR_COUNT_REG_OFFSET, sectorCount & 0xff);
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_LBA_LOW_REG_OFFSET, lbaLow & 0xff);
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_LBA_MID_REG_OFFSET, lbaMid & 0xff);
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_LBA_HIGH_REG_OFFSET, lbaHigh & 0xff);
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_HEAD_REG_OFFSET, device);
MV_CPU_WRITE_BUFFER_FLUSH();
MV_REG_WRITE_BYTE(ioBaseAddr, eDmaRegsOffset +
MV_ATA_DEVICE_COMMAND_REG_OFFSET, command);
if (protocolType == MV_NON_UDMA_PROTOCOL_NON_DATA)
{
/* Wait for the command to complete */
if (waitWhileStorageDevIsBusy(pAdapter, ioBaseAddr, eDmaRegsOffset, 3100, 10000) ==
MV_FALSE)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -