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

📄 ide_func.c

📁 epson usb2.0 控制芯片 S1R72V05 固件程序。
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * description : ATA/ATAPI Interface
 * Maker	   : Hideyuki Nekoshima
 * Copyright   : (C)2003,SEIKO EPSON Corp. All Rights Reserved.
 */

#include "SPRDEF.h"
#include "SPRSTS.h"

#include "IDE_Func.h"

/* ATA/ATAPI IF function list */
/*
*/
static LONG GetDeviceParameter( USHORT portNumber, UCHAR masterSlave, IDE_FUNCDEVICELIST* );
static LONG StatusWait( USHORT portNumber, UCHAR masterSlave );
static LONG ATACommandSet( USHORT deviceNo, UCHAR transferMode, IDE_FUNCCMDPARA *pCmdBlock);
static LONG ATAPItoATACommandSet( USHORT deviceNo, UCHAR transferMode, IDE_FUNCCMDPARA *pCmdBlock);
static LONG ATAPICommandSet( USHORT deviceNo, UCHAR transferMode, IDE_FUNCCMDPARA *pCmdBlock );
static LONG ATAErrorStatusSet( UCHAR error );
static LONG ATAPIRequestSense( USHORT deviceNo, UCHAR *pSenseData );


#define FREE_ID					0x00						/* Free the ID */
#define ALLOC_ID				0x01						/* Allocate ID */

#define FIRST_OPEN				0x01						/* IDE Function Module Firat Open Check */
#define NO_DEVICE				0xFF						/* DEVICE Type Initialize */

#define ENABLE					0x00						/* Enable */
#define DISABLE					0x01						/* Disable */

#define IDENTIFY_DEVICE			0xEC						/* ATA Identify Device Command */
#define IDENTIFY_PACKET_DEVICE	0xA1						/* ATA Identify Packet Device Command */
#define SET_FEATURS				0xEF						/* ATA Set Featues Command */
#define HDD_READ				0xC8						/* READ DMA Command */
#define HDD_WRITE				0xCA						/* WRITE DMA Command */
#define HDD_BIGDRV_READ			0x25						/* BIG Drive Read DMA Command*/
#define HDD_BIGDRV_WRITE		0x35						/* BIG Drive Write DMA Command */

#define READ6					0x08						/* ATAPI Read6 Command */
#define WRITE6					0x0A						/* ATAPI Write6 Command */
#define READ10					0x28						/* ATAPI Read10 Command */
#define WRITE10					0x2A						/* ATAPI Write10 Command */
#define READ12					0xA8						/* ATAPI Read12 Command */
#define WRITE12					0xAA						/* ATAPI Write12 Command */
#define VERIFY10				0x2F						/* ATAPI Verify10 Command */
#define SEEK					0x2B						/* ATAPI SEEK Command */
#define START_STOP				0x1B						/* ATAPI START/STOP UNIT Command */


#define READ_SECTOR				0x20						/* ATA Read Sector Command */
#define WRITE_SECTOR			0x30						/* ATA Write Sector Command */
#define READ_DMA				0xC8						/* ATA Read DMA Command	 */
#define WRITE_DMA				0xCA						/* ATA Write DMA Command	 */
#define READ_VERIFY				0x40						/* ATA Read Verify Command	 */
#define READ_SECTOR_BIG			0x24						/* ATA Read Sector Command */
#define WRITE_SECTOR_BIG		0x34						/* ATA Write Sector Command */
#define SEEK_ATA				0x70						/* ATA Seek Command */
#define IDLE					0xE3						/* ATA Idle Command */
#define IDLE_IMMEDIATE			0xE1						/* ATA Idle Immedate Command */
#define STANDBY					0xE2						/* ATA Standby Command */
#define STANDBY_IMMEDIATE		0xE0						/* ATA Standby Immediate Command */
#define FLUSH_CACHE_EXT			0xEA						/* ATA FLUSH CACHE EXT Command */
#define READ_NATIVE_MAX_ADDRESS_EXT		0x27				/* ATA READ NATIVE MAX ADDRESS EXT Command */
#define READ_VERIFY_SECTOR_EXT			0x42				/* ATA READ VERIFY SECTOR(S) EXT Command */
#define SET_MAX_ADDRESS_EXT				0x37				/* ATA SET MAX ADDRESS EXT Command */

#define SEL_BIG_DRIVE			0x01						/* HDD Big Drive Enable */

#define IDE_FUNC_DMAREQ			0x80
#define IDE_FUNC_IORDY			0x10

#define DMA_TRAN				0x01						/* H/W DMA transfer */
#define SOFT_TRAN				0x02						/* Software data transfer */


typedef struct selectdevice{
	USHORT	portNumber;										/* Device connection port number  */
	UCHAR	MasterSlave;									/* Device master/slave */
	UCHAR	type;											/* Device Type (HDD, CD, MO, etc..) */
}SELECT_DEVICE;
static SELECT_DEVICE	SelectDeviceNo[MAX_DEVICE];			/* device managment table */

static ATA_IFSTATUS		DeviceStatus;						/* ATA Status */
static ATA_IFATACMD		ATACmd;								/* ATA Command */
static ATA_IFTRANPARA 	TranPara;							/* ATA Data Transfer Parameter */
static	ATA_IFINTERRUPT	IntStat;		/* ATA Interrupt Status 			*/
static UCHAR	ATAPICmd[12];								/* ATAPI Command Block */

typedef struct devicepara{
	UCHAR PioMode;											/* PIO Transfer Mode */
	UCHAR DmaMode;											/* MultiWordDma Transfer Mode */
	UCHAR UltraEnb;											/* UltraDma Enable/Disable */
	UCHAR UltraMode;										/* UltraDma Transfer Mode */
	UCHAR BigDrive;											/* Big Drive Enale/Disable */
}DEVICE_PARA;
static DEVICE_PARA	DevicePara[MAX_DEVICE];					/* Device Parameter management */

typedef struct cmdstatus{
	USHORT id;												/* Upper layer ID */
	USHORT status;											/* Command Status (STOP, COMP, EXEC) */
}IDE_FUNC_CMDSTS;
static IDE_FUNC_CMDSTS CMDState[MAX_DEVICE];				/* ATA/ATAPI Command management  */

typedef struct dmastatus{
	USHORT id;												/* Upper layer ID */
	USHORT status;											/* DMA Transfer Status (STOP, COMP, EXEC)*/
}IDE_FUNC_DMASTS;
static IDE_FUNC_DMASTS DMAState[MAX_DEVICE];				/* DMA transfer management */

typedef struct compflag{
	UCHAR dmaComp		:1;									/* IDE DMA Complete */
	UCHAR intrq			:1;									/* ATA Intrq */
	UCHAR reserve		:6;
}IDE_FUNC_COMPFLAG;
// Delete because not used.
//static volatile IDE_FUNC_COMPFLAG CompleteFlag;

static UCHAR DeviceCnt;										/* The number of connected devices */
static ULONG TransferLba;									/* Read/Write transfer start sector adress(Encryption use) */

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDE_FuncReset
//
// description	: Initialize the IDE Function Module.
//
//				: Initialize the local varibles of IDE Function Module,
//				  and initialzie the lower layer.
//
// argument		: none
//
// return		: LONG status 		Processing result
////////////////////////////////////////////////////////////////////////
*/
LONG IDE_FuncReset( void )
{
	UCHAR	i;

	/* Clear internal work data */
	DeviceCnt = 0;
	/* PORT Execution Flag Clear */
	for(i=0; i<MAX_DEVICE; i++){
		CMDState[i].status = IDE_FUNC_CMD_STOP;
		DMAState[i].status = IDE_FUNC_DMA_STOP;
	}

	/* Reset lower layer */
	ATA_IFReset();
	IDEDMA_IFReset();

	/* Complete */
	return STATUS_SUCCESS;

}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDE_FuncOpen
//
// description	: Open IDE Function Module.
//
//				  Open IDE Function Module,it enters the usable status.
//				  If Open is not executed, will not do the API processing in Module
//
// argument		: non
//
// return		: LONG status  			Processing result
//
// flag			: UCHAR OpenFlag PASS	It Indicates if Interface Module is usable.
////////////////////////////////////////////////////////////////////////
*/
LONG IDE_FuncOpen( void )
{
	LONG	result;
	UCHAR	i;

/* OPEN the lower layer */
	result = ATA_IFOpen();
	if( result != STATUS_SUCCESS ){
		return result;
	}

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

	DeviceCnt = 0;
	for(i=0; i<MAX_DEVICE; i++){
		CMDState[i].status = IDE_FUNC_CMD_STOP;
		DMAState[i].status = IDE_FUNC_DMA_STOP;
	}

	/* Complete */
	return STATUS_SUCCESS;
}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDE_FuncDeviceReset
//
// description	: Initialzie the specified device.
//
//
// argument		: USHORT id				the identifier of the upper layer
//				  USHORT deviceNo		Initialized device No
//
// return		: LONG status  			Processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDE_FuncDeviceReset( USHORT id, USHORT deviceNo )
{
	LONG	result;


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

/* DMA PORT Reset */
	result = IDEDMA_IFInitPort( SelectDeviceNo[deviceNo].portNumber );
	if( result != STATUS_SUCCESS ){
		return result;
	}

/* ATA/ATAPI Device Reset */
	/* PORT Lock */
	result = ATA_IFLockPort( SelectDeviceNo[deviceNo].portNumber );
	if(( result != STATUS_SUCCESS )&&( result != STATUS_LOCKED_PORT )){
		return result;
	}
	/* Device Reset */
	result = ATA_IFSelResetDevice( SelectDeviceNo[deviceNo].portNumber, SelectDeviceNo[deviceNo].MasterSlave );

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

/* Clear the internal prameter. */
	CMDState[deviceNo].status = IDE_FUNC_CMD_STOP;
	DMAState[deviceNo].status = IDE_FUNC_DMA_STOP;

	return STATUS_SUCCESS;
}


/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDE_FuncGetDeviceList
//
// description	: Get the device list that connected to the port
//
//
// argument		: USHORT id					 Identifier of the upper layer.
//				  IDE_FUNCDEVICELIST *pList	 Device list
//
// return		: LONG status				 Processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDE_FuncGetDeviceList( USHORT id, IDE_FUNCDEVICELIST *pList )
{

	LONG	result;
	USHORT portCount;
	USHORT i;
	UCHAR  masterEnb;
	UCHAR  slaveEnb;

	if( DeviceCnt == 0x00 ){


		for(portCount=0; portCount < ATA_IF_MAX_PORT; portCount++){

			/* ATA Function PORT LOCK */
			result = ATA_IFLockPort( portCount );

			if(result != STATUS_SUCCESS){
				DeviceCnt = 0x00;
				pList->deviceCount = 0x00;
				return result;
			}

/* Check the initial value of the Status & Register */
			/* BSY negate wait	*/
			result = StatusWait( portCount, ATA_IF_MASTER );
			if( result != STATUS_SUCCESS ){
				return result;
			}
			/* ATA Task Register Check */
			if( DeviceStatus.IntReasen == 0x01 || DeviceStatus.status == 0x50 ){
				masterEnb = ENABLE;
			}else{
				masterEnb = DISABLE;
			}

			result = StatusWait( portCount, ATA_IF_SLAVE );
			if( result != STATUS_SUCCESS ){
				return result;
			}
			/* ATA Task Register Check */

			if( DeviceStatus.status == 0x50 ){
				slaveEnb = ENABLE;
			}else{
				if( DeviceStatus.IntReasen == 0x01 && DeviceStatus.transfersize != 0x00 ){
					slaveEnb = ENABLE;
				}else{
					slaveEnb = DISABLE;
				}
			}

			/* Get Master Device Parameter */
			if( masterEnb == ENABLE ){
				result = GetDeviceParameter( portCount, ATA_IF_MASTER, pList );
				if(result != STATUS_SUCCESS){
					ATA_IFUnlockPort( portCount );

					DeviceCnt = 0x00;
					pList->deviceCount = 0x00;
					return result;
				}
			}

			/* Get Slave Device Parameter  */
			if( slaveEnb == ENABLE ){
				result = GetDeviceParameter( portCount, ATA_IF_SLAVE, pList );
				if(result != STATUS_SUCCESS){
					ATA_IFUnlockPort( portCount );
					DeviceCnt = 0x00;
					pList->deviceCount = 0x00;
					return result;
				}
			}

			/* ATA Function PORT Unlock */
			result = ATA_IFUnlockPort( portCount );
		}

	}

	/* Device List Data Set */
	pList->deviceCount = DeviceCnt;
	if( DeviceCnt != 0x00 ){
		for( i=0; i<DeviceCnt; i++){
			pList->deviceType[i] = SelectDeviceNo[i].type;
		}
	}

	return STATUS_SUCCESS;

}

/*
////////////////////////////////////////////////////////////////////////
// Function_Name: GetDeviceParameter
//
// description	: Get the parameter of the device
//
//
// argument		: USHORT portNumber		The port thet device is connected
//				  UCHAR	 masterSlabe	ATA Master/Slave selection
//
// return		: LONG status  		Processing result
//
////////////////////////////////////////////////////////////////////////
*/
static LONG GetDeviceParameter( USHORT portNumber, UCHAR masterSlave, IDE_FUNCDEVICELIST *pList )
{
	LONG	result;
	USHORT	i;
	UCHAR	ataAtapi;
	UCHAR	identifydata[0x200];
	UCHAR	inquirydata[4];

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

/* Send IDE IDENTIFY DEVICE Command  */
	ATACmd.reg07 = ataAtapi = IDENTIFY_DEVICE;
	result = ATA_IFATACommandOutA( portNumber, masterSlave, ATA_IF_PIO_MODE2, &ATACmd );

	/* BSY negate wait	*/
	result = StatusWait( portNumber, masterSlave );
	if( result != STATUS_SUCCESS ){
		return result;
	}

	/* ERROR Complete Check */
	if( ( DeviceStatus.status & 0x01 ) ){

		/* Send ATAPI IDENTIFY PACKET DEVICE Command */
		ATACmd.reg07 = ataAtapi = IDENTIFY_PACKET_DEVICE;
		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;
		}

	}

	/* Check DRQ assert */

	if( !( DeviceStatus.status & 0x08 ) ){
		return STATUS_SUCCESS;
	}

	/* Read IDENTIFY DEVICE DATA */
	TranPara.transfersize = 0x200;
	TranPara.direction = ATA_IF_IDE_IN;
	TranPara.dataPointer = (ULONG)( identifydata );

	result = ATA_IFPIODataTransfer( portNumber, masterSlave, &TranPara );

#ifdef FPGA_DEBUG_C
identifydata[106]=0x0;
identifydata[126]=0x04;	/* MultiWord DMA Mode 2 */
identifydata[176]=0x04;	/* Ultra DMA Mode 2 */
#endif

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

	/* BSY negate wait	*/
	result = StatusWait( portNumber, masterSlave );
	if(result != STATUS_SUCCESS ){
		return STATUS_SUCCESS;
	}

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

	/* ATA/ATAPI Device Check */
	if( ataAtapi == IDENTIFY_PACKET_DEVICE ){

		/* Send ATAPI DEVICE Inquiry Command */
		for(i=0; i<0x0c; i++){
			ATAPICmd[i] = 0;
		}
		ATAPICmd[0] = 0x12;
		ATAPICmd[4] = 0x04;

		result = ATA_IFAtapiCommandOutA( portNumber, masterSlave, ATA_IF_PIO, ATA_IF_PIO_MODE2, ATAPICmd );

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

		/* BSY negate wait	*/
		result = StatusWait( portNumber, masterSlave );
		if(result != STATUS_SUCCESS ){
			return STATUS_SUCCESS;
		}

		/* Clear DRQ assert */
		if( !( DeviceStatus.status & 0x08 ) ){
			return STATUS_SUCCESS;
		}

		/* Read Inquiry Data */
		TranPara.transfersize = 0x04;
		TranPara.direction = ATA_IF_IDE_IN;
		TranPara.dataPointer = (ULONG)( inquirydata );

		result = ATA_IFPIODataTransfer( portNumber, masterSlave, &TranPara );

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

		/* BSY negate wait	*/
		result = StatusWait(  portNumber,  masterSlave );
		if(result != STATUS_SUCCESS ){
			return STATUS_SUCCESS;
		}

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

		/* Device Type Set */
		SelectDeviceNo[DeviceCnt].type = inquirydata[0];

	}else{

		/* Device Type Set */
		SelectDeviceNo[DeviceCnt].type = IDE_FUNC_HDD;
	}

	/* Set port No. the device is connected & Master/Slave driver */
	SelectDeviceNo[DeviceCnt].portNumber = portNumber;
	SelectDeviceNo[DeviceCnt].MasterSlave = masterSlave;

	/* set the PIO transfer mode */
	if( (identifydata[128] & 0x02) ){
		DevicePara[DeviceCnt].PioMode = ATA_IF_PIO_MODE4;
	}
	else{
		if( (identifydata[128] & 0x01) ){
			DevicePara[DeviceCnt].PioMode = ATA_IF_PIO_MODE3;
		}else{
			DevicePara[DeviceCnt].PioMode = ATA_IF_PIO_MODE0;
		}
	}

⌨️ 快捷键说明

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