📄 mvsata.c
字号:
#ifdef MV_SATA_IO_GRANULARITY
/*If valid IO Granularity transaction Id*/
if (pUdmaParams->iogCurrentTransId < MV_IOG_INVALID_COMMAND_ID)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG | MV_DEBUG_UDMA_COMMAND, "%d %d: "
"Edma request with IO granularity Id = 0x%x\n",
mvSataChannel->mvSataAdapter->adapterId,
mvSataChannel->channelNumber, pUdmaParams->iogCurrentTransId);
ControlFlags |= (((MV_U16)pUdmaParams->iogCurrentTransId) << 6);
}
#endif
/* in Non-queue EDMA mode */
ControlFlags |= (pCommandEntry->commandInfo.PMPort << 12);
pReqEntry->controlFlags = MV_CPU_TO_LE16(ControlFlags);
if ((mvSataChannel->queuedDMA == MV_EDMA_MODE_QUEUED) ||
(mvSataChannel->queuedDMA == MV_EDMA_MODE_NATIVE_QUEUING))
{
if (pUdmaParams->isEXT == MV_TRUE) /* Read/Write DMA QUEUED EXT */
{
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->numOfSectors & 0xFF00) >> 8,
MV_EDMA_ATA_FEATURES_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->numOfSectors) & 0xFF,
MV_EDMA_ATA_FEATURES_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pCommandEntry->commandTag << 3) & 0xF8,
MV_EDMA_ATA_SECTOR_COUNT_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress & 0xFF000000)
>> 24, MV_EDMA_ATA_LBA_LOW_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress) & 0xFF,
MV_EDMA_ATA_LBA_LOW_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,(pUdmaParams->highLBAAddress &
0xFF),
MV_EDMA_ATA_LBA_MID_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress & 0xFF00) >> 8,
MV_EDMA_ATA_LBA_MID_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->highLBAAddress & 0xFF00) >> 8,
MV_EDMA_ATA_LBA_HIGH_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress & 0xFF0000) >>
16, MV_EDMA_ATA_LBA_HIGH_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++, MV_BIT6 ,
MV_EDMA_ATA_DEVICE_ADDR,0);
if (pUdmaParams->readWrite == MV_UDMA_TYPE_READ)
{
if (mvSataChannel->queuedDMA == MV_EDMA_MODE_NATIVE_QUEUING)
{
ATACommand = MV_ATA_COMMAND_READ_FPDMA_QUEUED_EXT;
}
else
{
ATACommand = MV_ATA_COMMAND_READ_DMA_QUEUED_EXT;
}
}
else
{
if (mvSataChannel->queuedDMA == MV_EDMA_MODE_NATIVE_QUEUING)
{
ATACommand = MV_ATA_COMMAND_WRITE_FPDMA_QUEUED_EXT;
}
else
{
ATACommand = MV_ATA_COMMAND_WRITE_DMA_QUEUED_EXT;
}
}
}
else /* Read/Write DMA QUEUED */
{
WRITE_ATA_COMMAND_REG(pCommand++, (pUdmaParams->numOfSectors) &
0xFF, MV_EDMA_ATA_FEATURES_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pCommandEntry->commandTag << 3) & 0xF8,
MV_EDMA_ATA_SECTOR_COUNT_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress) & 0xFF,
MV_EDMA_ATA_LBA_LOW_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress & 0xFF00) >> 8,
MV_EDMA_ATA_LBA_MID_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress & 0xFF0000)
>> 16, MV_EDMA_ATA_LBA_HIGH_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++, MV_BIT6 |
(MV_U8)((pUdmaParams->lowLBAAddress & 0xF000000)
>> 24), MV_EDMA_ATA_DEVICE_ADDR, 0);
if (pUdmaParams->readWrite == MV_UDMA_TYPE_READ)
{
ATACommand = MV_ATA_COMMAND_READ_DMA_QUEUED;
}
else
{
ATACommand = MV_ATA_COMMAND_WRITE_DMA_QUEUED;
}
}
}
else
{
if (pUdmaParams->isEXT == MV_TRUE)
{ /* READ/WRITE DMA EXT */
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->numOfSectors & 0xFF00) >> 8,
MV_EDMA_ATA_SECTOR_COUNT_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->numOfSectors) & 0xFF,
MV_EDMA_ATA_SECTOR_COUNT_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress & 0xFF000000)
>> 24,
MV_EDMA_ATA_LBA_LOW_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress) &0xFF,
MV_EDMA_ATA_LBA_LOW_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->highLBAAddress & 0xFF),
MV_EDMA_ATA_LBA_MID_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress & 0xFF00) >> 8,
MV_EDMA_ATA_LBA_MID_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->highLBAAddress & 0xFF00) >> 8,
MV_EDMA_ATA_LBA_HIGH_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress & 0xFF0000)
>> 16,
MV_EDMA_ATA_LBA_HIGH_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++, MV_BIT6, MV_EDMA_ATA_DEVICE_ADDR,
0);
if (pUdmaParams->readWrite == MV_UDMA_TYPE_READ)
{
ATACommand = MV_ATA_COMMAND_READ_DMA_EXT;
}
else
{
ATACommand = MV_ATA_COMMAND_WRITE_DMA_EXT;
}
}
else /* READ/WRITE DMA */
{
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->numOfSectors) & 0xFF,
MV_EDMA_ATA_SECTOR_COUNT_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress) & 0xFF,
MV_EDMA_ATA_LBA_LOW_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress & 0xFF00) >> 8,
MV_EDMA_ATA_LBA_MID_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
(pUdmaParams->lowLBAAddress & 0xFF0000)
>> 16,
MV_EDMA_ATA_LBA_HIGH_ADDR, 0);
WRITE_ATA_COMMAND_REG(pCommand++,
MV_BIT6 | (MV_U8)((pUdmaParams->lowLBAAddress &
0xF000000) >> 24),
MV_EDMA_ATA_DEVICE_ADDR, 0);
if (pUdmaParams->readWrite == MV_UDMA_TYPE_READ)
{
ATACommand = MV_ATA_COMMAND_READ_DMA;
}
else
{
ATACommand = MV_ATA_COMMAND_WRITE_DMA;
}
}
}
WRITE_ATA_COMMAND_REG(pCommand++, ATACommand, MV_EDMA_ATA_COMMAND_ADDR,
MV_BIT15);
}
/*******************************************************************************
* handleEdmaFailedCommand - Handle failed EDMA command which didn't commpleted.
*
* DESCRIPTION:
* This function handles the completion of failed EDMA command when no
* response received for that command.
*
* INPUT:
* pAdapter - Pointer to the MV88SX50XX adapter data structure.
* channelIndex - The index of the channel where the response received.
* eDmaErrorCause - the value of the channel EDMA error cause register.
*
* RETURN:
* None
*
* COMMENTS:
* This function assumes that the channel semaphore is locked.
*
*******************************************************************************/
static void handleEdmaFailedCommand(MV_SATA_ADAPTER *pAdapter,
MV_U8 channelIndex, MV_U16 eDmaErrorCause)
{
MV_QUEUED_COMMAND_ENTRY *pCommandEntry;
MV_UDMA_COMMAND_PARAMS *pUdmaCommandParams;
MV_SATA_CHANNEL *pSataChannel = pAdapter->sataChannel[channelIndex];
MV_STORAGE_DEVICE_REGISTERS deviceRegs;
MV_U32 eDmaStatus;
MV_U32 commandTag;
eDmaStatus = MV_REG_READ_DWORD(pAdapter->adapterIoBaseAddress,
pSataChannel->eDmaRegsOffset +
MV_EDMA_STATUS_REG_OFFSET);
commandTag = (eDmaStatus & MV_EDMA_STATUS_TAG_MASK) >>
MV_EDMA_STATUS_TAG_OFFSET;
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, "%d %d: Handle failed command,"
"tag 0x%02x, error cause 0x%02x\n", pAdapter->adapterId,
channelIndex, commandTag, eDmaErrorCause);
pCommandEntry = &(pSataChannel->commandsQueue[commandTag]);
if (pCommandEntry->isFreeEntry == MV_TRUE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, "%d %d: Received response on a non"
"-valid tag (%x)\n", pAdapter->adapterId, channelIndex,
commandTag);
_dumpSataRegs(pAdapter,channelIndex);
dumpAtaDeviceRegisters(pAdapter, channelIndex, MV_TRUE, &deviceRegs);
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR,
" ATA Drive Registers:\n");
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR,
"%20s : %04x\n","Error", deviceRegs.errorRegister);
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR,
"%20s : %04x\n","SectorCount", deviceRegs.sectorCountRegister);
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR,
"%20s : %04x\n","LBA Low", deviceRegs.lbaLowRegister);
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR,
"%20s : %04x\n","LBA Mid", deviceRegs.lbaMidRegister);
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR,
"%20s : %04x\n","LBA High", deviceRegs.lbaHighRegister);
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR,
"%20s : %04x\n","Device", deviceRegs.deviceRegister);
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR,
"%20s : %04x\n","Status", deviceRegs.statusRegister);
return;
}
if (pSataChannel->PMSupported == MV_TRUE)
{
_setActivePMPort(pSataChannel, pCommandEntry->commandInfo.PMPort);
}
pUdmaCommandParams = &pCommandEntry->commandInfo.commandParams.udmaCommand;
dumpAtaDeviceRegisters(pAdapter, channelIndex, pUdmaCommandParams->isEXT,
&deviceRegs);
pSataChannel->EdmaQueuedCommands--;
pUdmaCommandParams->callBack(pSataChannel->mvSataAdapter, channelIndex,
MV_COMPLETION_TYPE_ERROR,
pUdmaCommandParams->commandId, eDmaErrorCause,
0, &deviceRegs);
removeCommand(pSataChannel,pCommandEntry);
}
/*******************************************************************************
* handleEdmaResponse - Handle an EDMA response queue entry.
*
* DESCRIPTION:
* This function handles the completion of EDMA command when a response
* entry is received.
*
* INPUT:
* pAdapter - Pointer to the MV88SX50XX adapter data structure.
* channelIndex - The index of the channel where the response received.
* response - Pointer to the received EDMA response block structure.
*
* RETURN:
* None
*
* COMMENTS:
* This function assumes that the channel semaphore is locked.
*
*******************************************************************************/
static void handleEdmaResponse(MV_SATA_ADAPTER *pAdapter, MV_U8 channelIndex,
MV_DMA_RESPONSE_QUEUE_ENTRY *eDmaResponse)
{
MV_QUEUED_COMMAND_ENTRY *pCommandEntry;
MV_UDMA_COMMAND_PARAMS *pUdmaCommandParams;
MV_STORAGE_DEVICE_REGISTERS deviceRegs;
MV_COMPLETION_TYPE compType = MV_COMPLETION_TYPE_NORMAL;
MV_SATA_CHANNEL *pSataChannel = pAdapter->sataChannel[channelIndex];
MV_DMA_RESPONSE_QUEUE_ENTRY response;
MV_U16 eDmaCause = 0;
response.commandTag = MV_LE16_TO_CPU(eDmaResponse->commandTag);
response.responseFlags = MV_LE16_TO_CPU(eDmaResponse->responseFlags);
response.timeStamp = MV_LE32_TO_CPU(eDmaResponse->timeStamp);
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG, "%d %d: New Response Received. ptr %p, "
"tag 0x%02x, flags 0x%x ts 0x%08x\n", pAdapter->adapterId,
channelIndex, eDmaResponse, response.commandTag,
response.responseFlags, response.timeStamp);
pCommandEntry = &(pSataChannel->commandsQueue[response.commandTag & 0x1f]);
if (response.responseFlags & 0xff) /* response with errors */
{
compType = MV_COMPLETION_TYPE_ERROR;
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, "%d %d: Response with Error. "
"outstanding commands %d, response flags 0x%x\n",
pAdapter->adapterId, channelIndex,
pSataChannel->outstandingCommands, response.responseFlags);
/*
* responseFlags will hold the low 8 bit of the EDMA error cause
* regiter. For 88SX50XX set bit 8 sence each error causes to
* eDmaSelfDisable.
*/
eDmaCause = (response.responseFlags & 0xff);
if (pAdapter->sataAdapterGeneration == MV_SATA_GEN_I)
{
eDmaCause |= MV_BIT8;
}
else
{
eDmaCause |= MV_BIT7;
}
pSataChannel->queueCommandsEnabled = MV_FALSE;
pSataChannel->EdmaActive = MV_FALSE;
if (pSataChannel->PMSupported == MV_TRUE)
{
_setActivePMPort(pSataChannel, pCommandEntry->commandInfo.PMPort);
}
}
pUdmaCommandParams = &pCommandEntry->commandInfo.commandParams.udmaCommand;
if (response.responseFlags & MV_BIT2) /*device error */
{
dumpAtaDeviceRegisters(pAdapter, channelIndex, pUdmaCommandParams->isEXT,
&deviceRegs);
}
if (pCommandEntry->isFreeEntry == MV_TRUE)
{
mvLogMsg(MV_CORE_DRIVER_LOG_ID, MV_DEBUG_ERROR, "%d %d: Received response on a non"
"-valid tag (%x)\n", pAdapter->adapterId, channelIndex,
response.commandTag);
}
else
{
pSataChannel->EdmaQueuedCommands--;
pUdmaCommandParams->callBack(pSataChannel->mvSataAdapter, channelIndex,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -