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

📄 ide_func.c

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 C
📖 第 1 页 / 共 4 页
字号:

	/* Device PIO Transfer Mode Set */
	ATACmd.reg01 = 0x03;
	ATACmd.reg02 = 0x08 | DevicePara[DeviceCnt].PioMode;
	ATACmd.reg07 = SET_FEATURS;
	result = ATA_IFATACommandOutA( portNumber, masterSlave, ATA_IF_PIO_MODE2, &ATACmd );

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

	/* BSY negate wait	*/
	result = StatusWait( portNumber, masterSlave );

	/* ERROR Complete Check */
	if( ( DeviceStatus.status & 0x01 ) ){
		return STATUS_SUCCESS;
	}

	/* Set the UltraDMA transfer mode */
	if( (identifydata[106] & 0x04) ){
		DevicePara[DeviceCnt].UltraEnb = ENABLE;
		if( (identifydata[176] & 0xC0) ){
			DevicePara[DeviceCnt].UltraMode = IDE_FUNC_ULTRA_MODE6;
		}else{
			if( (identifydata[176] & 0x20) ){
				DevicePara[DeviceCnt].UltraMode = IDE_FUNC_ULTRA_MODE5;
			}else{
				if( (identifydata[176] & 0x10) ){
					DevicePara[DeviceCnt].UltraMode = IDE_FUNC_ULTRA_MODE4;
				}else{
					if( (identifydata[176] & 0x08) ){
						DevicePara[DeviceCnt].UltraMode = IDE_FUNC_ULTRA_MODE3;
					}else{
						if( (identifydata[176] & 0x04) ){
							DevicePara[DeviceCnt].UltraMode = IDE_FUNC_ULTRA_MODE2;
						}else{
							if( (identifydata[176] & 0x02) ){
								DevicePara[DeviceCnt].UltraMode = IDE_FUNC_ULTRA_MODE1;
							}else{
								DevicePara[DeviceCnt].UltraMode = IDE_FUNC_ULTRA_MODE0;
							}
						}
					}
				}
			}
		}

		/* Device UltraDMA Mode Set */
		ATACmd.reg01 = 0x03;
		ATACmd.reg02 = 0x40 | DevicePara[DeviceCnt].UltraMode;
		ATACmd.reg07 = SET_FEATURS;
		result = ATA_IFATACommandOutA( portNumber, masterSlave, ATA_IF_PIO_MODE2, &ATACmd );

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

		/* BSY negate wait	*/
		result = StatusWait( portNumber, masterSlave );

		/* ERROR Complete Check */
		if( ( DeviceStatus.status & 0x01 ) ){
			return STATUS_SUCCESS;
		}

	}else{
		DevicePara[DeviceCnt].UltraEnb = DISABLE;
	}

	/* Set MultiWordDma transfer mode */
	if( (identifydata[126] & 0x04) ){
		DevicePara[DeviceCnt].DmaMode = IDE_FUNC_MULTI_MODE2;
	}else{
		if( (identifydata[126] & 0x02) ){
			DevicePara[DeviceCnt].DmaMode = IDE_FUNC_MULTI_MODE1;
		}else{
			DevicePara[DeviceCnt].DmaMode = IDE_FUNC_MULTI_MODE0;
		}
	}

	/* UltraDma Enabel Check */
	if( DevicePara[DeviceCnt].UltraEnb == DISABLE ){
		/* Device MultiWordDma Mode Set */
		ATACmd.reg01 = 0x03;
		ATACmd.reg02 = 0x20 | DevicePara[DeviceCnt].DmaMode;
		ATACmd.reg07 = SET_FEATURS;
		result = ATA_IFATACommandOutA( portNumber, masterSlave, ATA_IF_PIO_MODE2, &ATACmd );
		if( result != STATUS_SUCCESS ){
			return result;
		}

		/* BSY negate wait	*/
		result = StatusWait( portNumber, masterSlave );

		/* ERROR Complete Check */
		if( ( DeviceStatus.status & 0x01 ) ){
			return STATUS_SUCCESS;
		}

	}

	/* DMA Transfer Mode Set */


	/* BIG Drive Mode Set */
	if( SelectDeviceNo[DeviceCnt].type == IDE_FUNC_HDD ){
		if( (identifydata[167] & 0x04) ){
			DevicePara[DeviceCnt].BigDrive = ENABLE;
			pList->bigDrive[DeviceCnt] = IDE_FUNC_HDD_BIG;
		}else{
			DevicePara[DeviceCnt].BigDrive = DISABLE;
			pList->bigDrive[DeviceCnt] = IDE_FUNC_HDD_NORMAL;
		}
	}

	/* IDENTIFY information field */
// corresponding to the Big Endian
	pList->identify[DeviceCnt].IdeTrack = ( identifydata[2] + ( identifydata[3] << 8 ));
	pList->identify[DeviceCnt].IdeCylinder = ( identifydata[6] + ( identifydata[7] << 8 ));
	pList->identify[DeviceCnt].IdeHeader = ( identifydata[12] + ( identifydata[13] << 8 ));
	for( i = 0; i < 40; i += 2 ){
		pList->identify[DeviceCnt].DevicePara[i + 0] = identifydata[54 + i + 1];
		pList->identify[DeviceCnt].DevicePara[i + 1] = identifydata[54 + i + 0];
	}
	if (DevicePara[DeviceCnt].BigDrive == ENABLE) {
		pList->identify[DeviceCnt].MaxLba =
			( identifydata[200] + ( identifydata[201] << 8 ) + ( identifydata[202] << 16 ) + ( identifydata[203] << 24 ));
	}
	else{
		pList->identify[DeviceCnt].MaxLba =
			( identifydata[120] + ( identifydata[121] << 8 ) + ( identifydata[122] << 16 ) + ( identifydata[123] << 24 ));
	}

	/* Update the device count that connected */
	DeviceCnt ++;

	return STATUS_SUCCESS;

}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: StatusWait
//
// description	: Get status
//
//
// argument		: USHORT id			   Identifier of the upper layer
//				  USHORT portNumber	   The initialized port No.
//
// return		: LONG status  		   Processing result
//
////////////////////////////////////////////////////////////////////////
*/
static LONG StatusWait( USHORT portNumber, UCHAR masterSlave )
{
	LONG result;

	while(1){
		/* STATUS READ */
		result = ATA_IFGetStatus( portNumber, masterSlave, &DeviceStatus );

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

		/* Waiting for BSY negate */
		if( !( DeviceStatus.status & 0x80 ) ){
			return STATUS_SUCCESS;
		}
	}
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDE_FuncGetDeviceParameter
//
// description	: Get the detailed information of the specified device.
//
//
//
// argument		: USHORT id				Identifier of the upper layer
//				  USHORT deviceNo		Device No. The parameter is acquired from this device.
//				  UCHAR	 *pDataptr		pointer of the parameter field
//
// return		: LONG status  			Processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDE_FuncGetDeviceParameter( USHORT id, USHORT deviceNo, UCHAR *pDataptr )
{
	LONG result;

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

/* ATA Command Clear */
	ATACmd.reg01 = 0x00;
	ATACmd.reg02 = 0x00;
	ATACmd.reg03 = 0x00;
	ATACmd.reg04 = 0x00;
	ATACmd.reg05 = 0x00;
	ATACmd.reg06 = 0x00;

/* ATA Function Port Lock */
	result = ATA_IFLockPort( SelectDeviceNo[deviceNo].portNumber );
	if( result != STATUS_SUCCESS ){
		return result;
	}

/* Device Type Check */
	if( SelectDeviceNo[deviceNo].type == IDE_FUNC_HDD ){
		/* ATA Identify Device Command Set */
		ATACmd.reg07 = IDENTIFY_DEVICE;
	}else{
		/* ATA Identify Packet Device Command Set */
		ATACmd.reg07 = IDENTIFY_PACKET_DEVICE;
	}

	/* Send ATA command */
	result = ATA_IFATACommandOutA( SelectDeviceNo[deviceNo].portNumber,
									SelectDeviceNo[deviceNo].MasterSlave,
									DevicePara[deviceNo].PioMode, &ATACmd );

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

	/* Waiting for BSY negate */
	result = StatusWait(SelectDeviceNo[deviceNo].portNumber, SelectDeviceNo[deviceNo].MasterSlave );
	if(result != STATUS_SUCCESS ){
		ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
		return result;
	}

	/* Check DQR assert */
	if( !( DeviceStatus.status & 0x08 ) ){
		ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );

		return STATUS_UNSUCCESSFUL;
	}

	/* Read IDENTIFY DEVICE DATA  */
	TranPara.transfersize = 0x200;
	TranPara.direction = ATA_IF_IDE_IN;
	TranPara.dataPointer = (ULONG)( pDataptr);
	result = ATA_IFPIODataTransfer( SelectDeviceNo[deviceNo].portNumber, SelectDeviceNo[deviceNo].MasterSlave, &TranPara );

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

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

	/* ATA Function Port Unlock */
	ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
	if(result != STATUS_SUCCESS ){
		return result;
	}

	/* ERROR Complete Check */
	if( ( DeviceStatus.status & 0x01 ) ){
		return STATUS_UNSUCCESSFUL;
	}

	/* Complete */
	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDE_FuncCommandOut
//
// description	: Send command to the spaecified device
//
//
//
// argument		: USHORT id				Identifier of the upper layer
//				  USHORT deviceNo		No. of the device that issues command
//				  UCHAR	 transferMode	Data transfer mode (PIO/DMA)
//				  IDE_FUNCCMDPARA *pCmdBlock	command block
//
// return		: LONG status  		Processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDE_FuncCommandOut( USHORT id, USHORT deviceNo, UCHAR transferMode, IDE_FUNCCMDPARA *pCmdBlock )
{
	LONG	result;

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

	/* Check if the specified Device command is on executing */
	if( CMDState[deviceNo].status == IDE_FUNC_CMD_EXEC ){
		/* Parameter error */
		return IDE_FUNC_STATUS_CMD_EXEC;
	}
	if( CMDState[deviceNo].id != id ){
		if( CMDState[deviceNo].status == IDE_FUNC_CMD_COMP ){
			/* Parameter error */
			return IDE_FUNC_STATUS_CMD_EXEC;
		}
	}

	/* ATA Function PORT Lock */
	result = ATA_IFLockPort( SelectDeviceNo[deviceNo].portNumber );

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


	/* Device Type Check */
	if( SelectDeviceNo[deviceNo].type == IDE_FUNC_HDD ){
		/* Check if the command mode is set to ATA Device  */
		if( pCmdBlock->commandMode == IDE_FUNC_ATA ){
			/* ATA Command */
			result = ATACommandSet( deviceNo, transferMode, pCmdBlock );
		}else{
			/* ATAPI Command */
			result = ATAPItoATACommandSet( deviceNo, transferMode, pCmdBlock );
		}

	}else{
		/* Check if the command mode is set to ATAPI Device  */
		if( pCmdBlock->commandMode == IDE_FUNC_ATA ){
			/* ATA Command */
			/* Parameter error */
			return STATUS_INVALID_PARAMETER;
		}
		/* ATAPI Command */
		result = ATAPICommandSet( deviceNo, transferMode, pCmdBlock );
	}

	if( result == STATUS_SUCCESS ){
		/* Set the specified device command state to ON EXECUTING */
		CMDState[deviceNo].status = IDE_FUNC_CMD_EXEC;
		CMDState[deviceNo].id = id;
	}else{

		ATA_IFUnlockPort( SelectDeviceNo[deviceNo].portNumber );
	}

	return result;

}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: ATACommandSet
//
// description	: Send the ATA command to the specified device
//
// argument		: USHORT deviceNo		No of the device that issues command
//				  UCHAR	 transferMode	data transfer mode (PIO/DMA)
//				  IDE_FUNCCMDPARA *pCmdBlock	command block
//
// return		: LONG status  			Processing result
//
////////////////////////////////////////////////////////////////////////
*/
static LONG ATACommandSet( USHORT deviceNo, UCHAR transferMode, IDE_FUNCCMDPARA *pCmdBlock )
{
	UCHAR driveSelect;

	/* Command Code Check */
	if( pCmdBlock->commandBlock[7] == HDD_BIGDRV_READ || pCmdBlock->commandBlock[7] == HDD_BIGDRV_WRITE ||
		pCmdBlock->commandBlock[7] == READ_SECTOR_BIG || pCmdBlock->commandBlock[7] == WRITE_SECTOR_BIG ||
		pCmdBlock->commandBlock[7] == FLUSH_CACHE_EXT || pCmdBlock->commandBlock[7] == READ_NATIVE_MAX_ADDRESS_EXT ||
		pCmdBlock->commandBlock[7] == READ_VERIFY_SECTOR_EXT || pCmdBlock->commandBlock[7] == SET_MAX_ADDRESS_EXT ){
		/* BIG Drive Enable Check */
		if( DevicePara[deviceNo].BigDrive == DISABLE ){
			return STATUS_INVALID_PARAMETER;
		}

		/* COMMAND Copy */
		ATACmd.reg01 = pCmdBlock->commandBlock[1];
		ATACmd.reg02 = pCmdBlock->commandBlock[2];
		ATACmd.reg03 = pCmdBlock->commandBlock[3];
		ATACmd.reg04 = pCmdBlock->commandBlock[4];
		ATACmd.reg05 = pCmdBlock->commandBlock[5];
		ATACmd.reg06 = pCmdBlock->commandBlock[6];
		ATACmd.reg07 = pCmdBlock->commandBlock[7];
		ATACmd.BigDriveReg02 = pCmdBlock->commandBlock[8];
		ATACmd.BigDriveReg03 = pCmdBlock->commandBlock[9];
		ATACmd.BigDriveReg04 = pCmdBlock->commandBlock[10];
		ATACmd.BigDriveReg05 = pCmdBlock->commandBlock[11];

		/* Sector LBA Set */
		TransferLba = (ULONG)( ( pCmdBlock->commandBlock[9] * 0x1000000) + ( pCmdBlock->commandBlock[5] * 0x10000) +
								( pCmdBlock->commandBlock[4] * 0x100) + pCmdBlock->commandBlock[3] );
		/* Master/Slave Set & BIG Drive Flag Set */
		driveSelect = SelectDeviceNo[deviceNo].MasterSlave | SEL_BIG_DRIVE;

	}else{

		/* COMMAND Copy */
		ATACmd.reg01 = pCmdBlock->commandBlock[1];
		ATACmd.reg02 = pCmdBlock->commandBlock[2];
		ATACmd.reg03 = pCmdBlock->commandBlock[3];
		ATACmd.reg04 = pCmdBlock->commandBlock[4];
		ATACmd.reg05 = pCmdBlock->commandBlock[5];
		ATACmd.reg06 = pCmdBlock->commandBlock[6];
		ATACmd.reg07 = pCmdBlock->commandBlock[7];

		/* Sector LBA Set */
		TransferLba = (ULONG)( ( pCmdBlock->commandBlock[6] * 0x1000000) + ( pCmdBlock->commandBlock[5] * 0x10000) +
								( pCmdBlock->commandBlock[4] * 0x100) + pCmdBlock->commandBlock[3] );
		/* Master/Slave Set */
		driveSelect = SelectDeviceNo[deviceNo].MasterSlave;
	}

	/* Send ATA command  */
	return( ATA_IFATACommandOutA( SelectDeviceNo[deviceNo].portNumber, driveSelect,
										 DevicePara[deviceNo].PioMode, &ATACmd ) );

}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: ATAPItoATACommandSet
//
// description	: Change the ATAPI command to the ATA command,and send to the specofied device.
//
// argument		: USHORT deviceNo		No. of the device that issues command
//				  UCHAR	 transferMode	Data transfer mode(PIO/DMA)
//				  IDE_FUNCCMDPARA *pCmdBlock	Command block
//
// return		: LONG status  		Processing result
//
////////////////////////////////////////////////////////////////////////
*/
static LONG ATAPItoATACommandSet( USHORT deviceNo, UCHAR transferMode, IDE_FUNCCMDPARA *pCmdBlock)
{
	UCHAR driveSelect;

	/* Command Code Check */
	switch( pCmdBlock->commandBlock[0] ){
		case READ10:
		case WRITE10:
			/* ATAPI Read10/Write10 Command -> ATA READ/WRITE Command */
			if( DevicePara[deviceNo].BigDrive == ENABLE ){
				/* HDD BIG Drive */
				ATACmd.reg01 = 0x00;
				ATACmd.reg02 = pCmdBlock->commandBlock[8];
				ATACmd.reg03 = pCmdBlock->commandBlock[5];
				ATACmd.reg04 = pCmdBlock->commandBlock[4];
				ATACmd.reg05 = pCmdBlock->commandBlock[3];
				ATACmd.reg06 = 0x00;
				ATACmd.BigDriveReg02 = pCmdBlock->commandBlock[7];
				ATACmd.BigDriveReg03 = pCmdBlock->commandBlock[2];
				ATACmd.BigDriveReg04 = 0x00;
				ATACmd.BigDriveReg05 = 0x00;
				ATACmd.BigDriveReg06 = 0x00;
			}else{
				/* HDD Drive */
				if( ( pCmdBlock->commandBlock[7] != 0x00)  || ( (pCmdBlock->commandBlock[2] & 0xF0) != 0x00 ) ){
					return STATUS_INVALID_PARAMETER;
				}
				ATACmd.reg01 = 0x00;
				ATACmd.reg02 = pCmdBlock->commandBlock[8];
				ATACmd.reg03 = pCmdBlock->commandBlock[5];
				ATACmd.reg04 = pCmdBlock->commandBlock[4];
				ATACmd.reg05 = pCmdBlock->commandBlock[3];
				ATACmd.reg06 = pCmdBlock->commandBlock[2];
				ATACmd.BigDriveReg02 = 0x00;
				ATACmd.BigDriveReg03 = 0x00;
				ATACmd.BigDriveReg04 = 0x00;
				ATACmd.BigDriveReg05 = 0x00;
				ATACmd.BigDriveReg06 = 0x00;
			}

			/* Sector LBA Set */
			TransferLba = (ULONG)( ( pCmdBlock->commandBlock[2] * 0x1000000) + ( pCmdBlock->commandBlock[3] * 0x10000) +
									( pCmdBlock->commandBlock[4] * 0x100) + pCmdBlock->commandBlock[5] );
			break;

		case READ12:
		case WRITE12:
			/* ATAPI Read10/Write10 Command -> ATA READ/WRITE Command */
			if( DevicePara[deviceNo].BigDrive == ENABLE ){
				/* HDD BIG Drive */
				if( pCmdBlock->commandBlock[6] != 0x00 || pCmdBlock->commandBlock[7] != 0x00 ){
					return STATUS_INVALID_PARAMETER;
				}
				ATACmd.reg01 = 0x00;
				ATACmd.reg02 = pCmdBlock->commandBlock[9];
				ATACmd.reg03 = pCmdBlock->commandBlock[5];
				ATACmd.reg04 = pCmdBlock->commandBlock[4];
				ATACmd.reg05 = pCmdBlock->commandBlock[3];
				ATACmd.reg06 = 0x00;
				ATACmd.BigDriveReg02 = pCmdBlock->commandBlock[8];
				ATACmd.BigDriveReg03 = pCmdBlock->commandBlock[2];
				ATACmd.BigDriveReg04 = 0x00;
				ATACmd.BigDriveReg05 = 0x00;
				ATACmd.BigDriveReg06 = 0x00;
			}else{
				/* HDD Drive */
				if( pCmdBlock->commandBlock[6] != 0x00 || pCmdBlock->commandBlock[7] != 0x00 ||
					pCmdBlock->commandBlock[8] != 0x00 || ( (pCmdBlock->commandBlock[2] & 0xF0) != 0x00 )){
					return STATUS_INVALID_PARAMETER;
				}
				ATACmd.reg01 = 0x00;
				ATACmd.reg02 = pCmdBlock->commandBlock[9];
				ATACmd.reg03 = pCmdBlock->commandBlock[5];
				ATACmd.reg04 = pCmdBlock->commandBlock[4];
				ATACmd.reg05 = pCmdBlock->commandBlock[3];
				ATACmd.reg06 = pCmdBlock->commandBlock[2];
				ATACmd.BigDriveReg02 = 0x00;
				ATACmd.BigDriveReg03 = 0x00;
				ATACmd.BigDriveReg04 = 0x00;
				ATACmd.BigDriveReg05 = 0x00;
				ATACmd.BigDriveReg06 = 0x00;
			}
			/* Sector LBA Set */
			TransferLba = (ULONG)( ( pCmdBlock->commandBlock[2] * 0x1000000) + ( pCmdBlock->commandBlock[3] * 0x10000) +
									( pCmdBlock->commandBlock[4] * 0x100) + pCmdBlock->commandBlock[5] );

⌨️ 快捷键说明

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