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

📄 mvsata.c

📁 此为marvell6081芯片的驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
#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 + -