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

📄 ide_func.c

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* Get ATA Status */
	result = ATA_IFGetStatus( SelectDeviceNo[deviceNo].portNumber, SelectDeviceNo[deviceNo].MasterSlave, &status );
	if(result != STATUS_SUCCESS ){
		return result;
	}

	/* STATUS Check */
	if( (status.status & 0x01) ){
		/* ERROR COMPLETE */
		return IDE_FUNC_STATUS_ERROR;
	}
	if( (status.status & 0x80) ){
		/* DEVICE BSY */
		return IDE_FUNC_STATUS_BSY;
	}
	if( !(status.status & 0x08) ){
		/* DRQ negate */
		return IDE_FUNC_STATUS_NOT_READY;
	}

	if(	SelectDeviceNo[deviceNo].type == IDE_FUNC_HDD ){
		/* Hard disk */
		ataFuncTranPara.direction = pTranPara->direction;
		ataFuncTranPara.dataPointer = pTranPara->dataPointer;
		ataFuncTranPara.transfersize = pTranPara->dataSize;
	}
	else{
		/* Not hard disk */
		/* Check the transfer direction */
		if( (status.IntReasen & 0x02) ){
			if( pTranPara->direction != ATA_IF_IDE_IN ){
				/* Parameter error */
				return STATUS_INVALID_PARAMETER;
			}
		}else{
			if( pTranPara->direction != ATA_IF_IDE_OUT ){
				/* Parameter error */
				return STATUS_INVALID_PARAMETER;
			}
		}
		ataFuncTranPara.direction = pTranPara->direction;
		ataFuncTranPara.dataPointer = pTranPara->dataPointer;
		ataFuncTranPara.transfersize = status.transfersize;
	}

	/* Start PIO data transmission */
	result = ATA_IFPIODataTransfer( SelectDeviceNo[deviceNo].portNumber, SelectDeviceNo[deviceNo].MasterSlave, &ataFuncTranPara );
	if( result == STATUS_SUCCESS ){
		/* Set the number of data actually transfered(number of bytes) */
		pTranPara->transferSize = (ULONG)( status.transfersize );
	}

	return result;

}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDE_FuncGetStatus
//
// description	: Get the status information of the specified device
//
// argument		: USHORT id				Identifier of the upper layer
//				  USHORT deviceNo		No. of the device that executing DMA transfer
//				  UCHAR	 *pStatus		Memory for saving the status
//				  UCHAR	 *pSenseData	Memory for saving resuest sense data
//
// return		: LONG status  		Processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDE_FuncGetStatus( USHORT id, USHORT deviceNo, ULONG *pStatus,ULONG *pTrasferSize, UCHAR *pSenseData )
{
	LONG	result;
	ATA_IFSTATUS	status;


	/* Device No. Check */
	if( deviceNo >= DeviceCnt ){
		/* Parameter error */
		return STATUS_INVALID_PARAMETER;
	}

	/* DMA STATE Check */
	if( DMAState[deviceNo].status == IDE_FUNC_DMA_EXEC ){
		/* IDE DMA in operating */
		return IDE_FUNC_STATUS_DMA_EXEC;
	}

	/* Check the Command Executing ID */
	if( CMDState[deviceNo].id != id ){
		if( CMDState[deviceNo].status != IDE_FUNC_CMD_STOP ){
			/* Parameter error */
			return IDE_FUNC_STATUS_CMD_EXEC;
		}else{
			*pStatus = IDE_FUNC_CMD_STOP;
			return STATUS_SUCCESS;
		}
	}

	/* Check the Command STATE	*/
	if( CMDState[deviceNo].status != IDE_FUNC_CMD_EXEC ){
		/* Check Command STOP or COMPLETE */
		if( CMDState[deviceNo].status == IDE_FUNC_CMD_STOP ){
			/* Set to Command Stop status */
			*pStatus = IDE_FUNC_CMD_STOP;
			return STATUS_SUCCESS;
		}else{
			/* Command State STOP Set */
			CMDState[deviceNo].status = IDE_FUNC_CMD_STOP;
			/* Set Command Complete status */
			*pStatus = IDE_FUNC_CMD_COMP;
			return STATUS_SUCCESS;
		}
	}

	/* Get ATA Status */
	result = ATA_IFGetStatus( SelectDeviceNo[deviceNo].portNumber, SelectDeviceNo[deviceNo].MasterSlave, &status );
	*pTrasferSize = status.transfersize;

	if( result != STATUS_SUCCESS ){
		return result;
	}

	if( ( status.busStatus & IDE_FUNC_DMAREQ ) ){
		*pStatus = IDE_FUNC_TRAN_READY;
		return STATUS_SUCCESS;
	}

	/* STATUS Check */
	if( ( status.status & 0x01 ) ){
		/* ERROR Complete */
		CMDState[deviceNo].status = IDE_FUNC_CMD_STOP;
		/* Device Type Check */
		if( SelectDeviceNo[deviceNo].type == IDE_FUNC_HDD ){
			/* ERROR CODE Set */
			*pStatus = ATAErrorStatusSet( status.error );
			ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
			return STATUS_SUCCESS;
		}else{
			/* Device Error Set */
			*pStatus = IDE_FUNC_DEVICE_ERR;
			/* Get Requset Sense Data */
			ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
			return( ATAPIRequestSense( deviceNo, pSenseData ) );
		}

	}

	if( ( status.status & 0x80 ) ){
		/* STATUS BSY */
		*pStatus = IDE_FUNC_BSY;
		ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
		return STATUS_SUCCESS;
	}

	if( ( status.status & 0x08 ) ){
		if(	SelectDeviceNo[deviceNo].type == IDE_FUNC_HDD ){
										/* ATA device					*/
			*pStatus = IDE_FUNC_TRAN_READY;
		}
		else{
										/* Other than ATA device		*/
			if( (status.IntReasen & 0x02) ){
				/* Assert DRQ */
				*pStatus = IDE_FUNC_PIOIN_READY;
			}else{
				*pStatus = IDE_FUNC_PIOOUT_READY;
			}
		}
		return STATUS_SUCCESS;
	}

	/* Command Complete */
	if( DMAState[deviceNo].status != IDE_FUNC_DMA_EXEC ){
		DMAState[deviceNo].status = IDE_FUNC_DMA_STOP;
		IDEDMA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
	}

	/* Command Complete */
	ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
	CMDState[deviceNo].status = IDE_FUNC_CMD_STOP;
	*pStatus = IDE_FUNC_CMD_COMP;

	return STATUS_SUCCESS;

}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: ATAErrorStatusSet
//
// description	: Get HDD error code
//
// argument		: UCHAR	 ERROR			the contents of ATA ERROR Register
//
// return		: LONG status  		Processing result
//
////////////////////////////////////////////////////////////////////////
*/
static LONG ATAErrorStatusSet( UCHAR error )
{

	if( (error & 0x80) ){
		return IDE_FUNC_CRC_ERR;
	}

	if( (error & 0x40) ){
		return IDE_FUNC_WP_ERR;
	}

	if( (error & 0x20) ){
		return IDE_FUNC_MC_ERR;
	}

	if( (error & 0x10) ){
		return IDE_FUNC_IDNF_ERR;
	}

	if( (error & 0x08) ){
		return IDE_FUNC_MCR_ERR;
	}

	if( (error & 0x02) ){
		return IDE_FUNC_NM_ERR;
	}

	if( (error & 0x04) ){
		return IDE_FUNC_ABORT_ERR;
	}

	return IDE_FUNC_ABORT_ERR;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: ATAPIRequestSense
//
// description	: Get ATAPI request sense data
//
// argument		: USHORT deviceNo			No. of the device from which to get the request sense data
//				  UCHAR	 *pSenseDara		Memory field of the request sense data
//
// return		: LONG status  				Processing result
//
////////////////////////////////////////////////////////////////////////
*/
static LONG ATAPIRequestSense( USHORT deviceNo, UCHAR *pSenseData )
{
	LONG	result;
	UCHAR	i;
	ATA_IFTRANPARA	ataFuncTranPara;
	ATA_IFSTATUS	status;

	/* ATAPI Command Block Set */
	for( i=0; i<0x0c; i++ ){
		ATAPICmd[i] = 0x00;
	}
	ATAPICmd[0] = 0x03;
	ATAPICmd[4] = 0x20;

	/* Send ATAPI Command */
	result = ATA_IFAtapiCommandOutA( SelectDeviceNo[deviceNo].portNumber,
										SelectDeviceNo[deviceNo].MasterSlave,
										ATA_IF_PIO, DevicePara[deviceNo].PioMode, ATAPICmd );
	if( result != STATUS_SUCCESS ){
		return result;
	}

	/* 	Waiting DRQ assert*/
	while(1){
		/* Get ATA STATUS */
		ATA_IFGetStatus( SelectDeviceNo[deviceNo].portNumber, SelectDeviceNo[deviceNo].MasterSlave, &status );
		if( (status.status & 0x08) ){
			break;
		}
	}

	/* ATA PIO data transfer */
	ataFuncTranPara.direction = ATA_IF_IDE_IN;
	ataFuncTranPara.dataPointer = (ULONG)( pSenseData );
	ataFuncTranPara.transfersize = status.transfersize;
	result = ATA_IFPIODataTransfer( SelectDeviceNo[deviceNo].portNumber, SelectDeviceNo[deviceNo].MasterSlave, &ataFuncTranPara );
	if( result != STATUS_SUCCESS ){
		return result;
	}

	/* Waiting for BSY negate  */
	while(1){
		/* Get ATA STATUS */
		ATA_IFGetStatus( SelectDeviceNo[deviceNo].portNumber, SelectDeviceNo[deviceNo].MasterSlave, &status );
		if( !(status.status & 0x80) ){
			break;
		}
	}

	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDE_FuncNotifyDmaComp
//
// description	: Process IDEDMA CALLBACK
//
//
// argument		: ULONG portNumber		The port No. When DMA completed
//				  ULONG lReserve1		Reserved
//				  ULONG VOID *pReserve	Reserved
//
// return		: none
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDE_FuncNotifyDmaComp(ULONG portNumber, ULONG lReserve1, VOID *pReserve )
{
	USHORT i;

	/* CALL BACK Pointer Check */
	for( i=0; i<DeviceCnt; i++ ){
		if( SelectDeviceNo[i].portNumber == portNumber ){
			if( DMAState[i].status == IDE_FUNC_DMA_EXEC ){
				/* DMA STATE COMPLETE Set */
				DMAState[i].status =IDE_FUNC_DMA_COMP;
				break;
			}
		}
	}

	return STATUS_SUCCESS;

}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDE_FuncNotifyIntrq
//
// description	: Process ATA INTRQ CALL BACK
//
// argument		: ULONG portNumber		The port No. When INTRQ completed
//				  ULONG lReserve1		Reserved
//				  ULONG VOID *pReserve	Reserved
//
// return		: none
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDE_FuncNotifyIntrq( ULONG portNumber, ULONG lReserve1, VOID *pReserve )
{

	USHORT i;

	/* CALL BACK Pointer Check */
	for( i=0; i<DeviceCnt; i++ ){
		if( SelectDeviceNo[i].portNumber == portNumber ){
			if( CMDState[i].status == IDE_FUNC_CMD_EXEC ){
				/* CALL BACK */
				break;
			}
		}
	}

	return STATUS_SUCCESS;


}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDE_FuncXferRateSet
//
// description	: Set the data transfer mode of the specified device
//
// argument		: USHORT id						Identifier
//				  USHORT deviceNo				The No. of the device that deletes callback
//
// return		: none
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDE_FuncXferRateSet( USHORT id, USHORT deviceNo )
{
LONG	result;

	result = ATA_IFLockPort( SelectDeviceNo[deviceNo].portNumber );
	if( result != STATUS_SUCCESS ){
		return result;
	}

	/* Device PIO Transfer Mode Set */
	ATACmd.reg01 = 0x03;
	ATACmd.reg02 = 0x08 | DevicePara[deviceNo].PioMode;
	ATACmd.reg07 = SET_FEATURS;

	result = ATA_IFATACommandOutA( SelectDeviceNo[deviceNo].portNumber,
									SelectDeviceNo[deviceNo].MasterSlave,
									ATA_IF_PIO_MODE2, &ATACmd );
	if( result != STATUS_SUCCESS ){
		ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
		return result;
	}

	/* BSY negate wait	*/
	result = StatusWait( SelectDeviceNo[deviceNo].portNumber, SelectDeviceNo[deviceNo].MasterSlave );

	/* ERROR Complete Check */
	if( ( DeviceStatus.status & 0x01 ) ){
		ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
		return STATUS_SUCCESS;
	}

	if(	DevicePara[deviceNo].UltraEnb == ENABLE){
		/* Device UltraDMA Mode Set */
		ATACmd.reg01 = 0x03;
		ATACmd.reg02 = 0x40 | DevicePara[deviceNo].UltraMode;
		ATACmd.reg07 = SET_FEATURS;
		result = ATA_IFATACommandOutA( SelectDeviceNo[deviceNo].portNumber,
										SelectDeviceNo[deviceNo].MasterSlave,
										ATA_IF_PIO_MODE2, &ATACmd );
		if( result != STATUS_SUCCESS ){
			ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
			return result;
		}

		/* BSY negate wait	*/
		result = StatusWait( SelectDeviceNo[deviceNo].portNumber, SelectDeviceNo[deviceNo].MasterSlave );

		/* ERROR Complete Check */
		if( ( DeviceStatus.status & 0x01 ) ){
			ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
			return STATUS_SUCCESS;
		}
	}else{
		/* Device MultiWordDma Mode Set */
		ATACmd.reg01 = 0x03;
		ATACmd.reg02 = 0x20 | DevicePara[deviceNo].DmaMode;
		ATACmd.reg07 = SET_FEATURS;
		result = ATA_IFATACommandOutA( SelectDeviceNo[deviceNo].portNumber,
										SelectDeviceNo[deviceNo].MasterSlave,
										ATA_IF_PIO_MODE2, &ATACmd );
		if( result != STATUS_SUCCESS ){
			ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
			return result;
		}

		/* BSY negate wait	*/
		result = StatusWait( SelectDeviceNo[deviceNo].portNumber, SelectDeviceNo[deviceNo].MasterSlave );

		/* ERROR Complete Check */
		if( ( DeviceStatus.status & 0x01 ) ){
			ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
			return STATUS_SUCCESS;
		}
	}

	ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDE_FuncXferRateChange
//
// description	: Modify the transfer mode of the specified device
//
// argument		:
//
// return		:
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDE_FuncXferRateChange( USHORT deviceNo, IDE_FUNCXFERPARA *pXferPara )
{

	DevicePara[deviceNo].PioMode = pXferPara->PIOMode;
	DevicePara[deviceNo].UltraMode = pXferPara->ultraDMAMode;
	DevicePara[deviceNo].DmaMode = pXferPara->multiDMAMode;

	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDE_FuncGetInterrupt
//
// description	: Get the interrupt factor
//
// argument		:
//
// return		:
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDE_FuncGetInterrupt( UCHAR mainIntEnb, UCHAR *pStatus )
{

	ATA_IFGetInterrupt( mainIntEnb, &IntStat);

	if( IntStat.ide_int_stat & 0x80 ){
		*pStatus |= IDE_FUNC_INT_REGCMP;
	}
	if( IntStat.ide_int_stat & 0x40 ){
		*pStatus |= IDE_FUNC_INT_REGERR;
	}
	if( IntStat.ide_int_stat & 0x20 ){
		*pStatus |= IDE_FUNC_INT_SEQWRREGCMP;
	}
	if( IntStat.ide_int_stat & 0x10 ){
		*pStatus |= IDE_FUNC_INT_CMPINTRQ;
	}

	if( IntStat.ide_int_stat & 0x04 ){
		*pStatus |= IDE_FUNC_INT_IDECMP;
	}
	if( IntStat.ide_int_stat & 0x02 ){
		*pStatus |= IDE_FUNC_INT_DETECTINTRQ;
	}
	if( IntStat.ide_int_stat & 0x01 ){
		*pStatus |= IDE_FUNC_INT_DETECTTERM;
	}
	return STATUS_SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -