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

📄 u_atapicmd.c

📁 EPSON USB DEVICE MASS-STORAGE CLASS driver, BULK ONLY on Ram disk
💻 C
字号:
/****************************************************************************
 * File name   : atapicmd.c
 * Module name : ATAPI Command Check module
 * Author	   : Hiromichi Kondo
 *---------------------------------------------------------------------------
 * $Id: atapicmd.c,v 1.3 2003/05/13 11:00:30 9551619 Exp $
 ****************************************************************************/
#include "u_ram_data.h"
#include "u_rom_data.h"
#include "u_value.h"
#include "u_macro.h"

#include "usbmedia.h"

/*--- Function Prototype ---------------------------------------------------*/
int IsCommonErrorFound(int dir);

void SetSenseKey(int);

int TestUnitReady(void);
int RequestSense(void);
int Inquiry(void);
int ReadCapacity(void);
int ReadFormatCapacity(void);
int ModeSelect(void);
int ModeSelectPara(void);
void MSelFindPage(BYTE page);
int IsMSelRcvParaInvalid(void);
int ModeSense(void);
int Prevent(void);
int CmdError(void);
int Read10(void);
int Seek(void);
int StartStopUnit(void);
int Verify(void);
int Write10(void);


/*****************************************************************************
 *     CBWCBIATAPI
 *****************************************************************************/
int IsCommonErrorFound(int dir)
{
	int ret = RC_ERROR;

	if( bulk_req_tran_cnt != bulk_total_tran_cnt )
	{
		cmd_status = PHASE_ERROR;
		return ret;
	}

	if( bulk_req_tran_cnt != 0x00 && tran_flag.Direction != dir )
	{
		cmd_status = PHASE_ERROR;
		return ret;
	}
	
	if( cmd_block[0] != 0x03 && cmd_block[0] != 0x12 )
	{

		if( atten_flag.PowerOnReset )
		{
			atten_flag.PowerOnReset = 0;
			SetSenseKey(0x062900);
			return ret;
		}
	}

	if ((cmd_block[1] & 0xE0) == 0x00)
		ret = RC_NO_ERROR;
	else
		SetSenseKey(0x052500);
	
	return ret;
}

/*****************************************************************************
 *     SenseKey()
 *****************************************************************************/
void SetSenseKey(int key)
{
	sense_data[0] = (unsigned char)(key >>16);
	sense_data[1] = (unsigned char)(key >> 8);
	sense_data[2] = (unsigned char)key;
	cmd_status = (key == 0 ? COMMAND_SUCCESS : COMMAND_FAILED);
}

/*****************************************************************************
 *  Test Unit Ready
 *****************************************************************************/
int TestUnitReady(void)
{
	int ret = RC_NG;

	bulk_total_tran_cnt = 0;
	if (IsCommonErrorFound(DIR_NONE) == RC_NO_ERROR)
	{
		SetSenseKey(0x0);
		ret = RC_OK;
	}
	return ret;
}

/*****************************************************************************
 *  Request Sense
 *****************************************************************************/
int RequestSense(void)
{
	int i;
	int ret = RC_NG;

	bulk_total_tran_cnt = MKDWORD(0x00,0x00,0x00,cmd_block[4]);

	if (IsCommonErrorFound(DIR_IN) == RC_NO_ERROR)
	{
		bulk_tran_start_addr = wk_data;

		for (i = 0;i < 18;i++)
			wk_data[i] = 0x00;
		
		wk_data[ 0] = 0x70;
		wk_data[ 7] = 0x0A;
		wk_data[ 2] = sense_data[0];
		wk_data[12] = sense_data[1];
		wk_data[13] = sense_data[2];
			
		if (bulk_total_tran_cnt > 18)
			bulk_total_tran_cnt = 18;
			
		SetSenseKey(0x0);
		ret = RC_OK;
	}
	return ret;
}

/*****************************************************************************
 *     Inquiry
 *****************************************************************************/
int Inquiry(void)
{
	int ret = RC_NG;
	
	bulk_total_tran_cnt = MKDWORD(0x00,0x00,0x00,cmd_block[4]);

	if (IsCommonErrorFound(DIR_IN) == RC_NO_ERROR)
	{
		bulk_tran_start_addr = (BYTE *)&inquiry_data[0];
			
		if (bulk_total_tran_cnt > 36)
			bulk_total_tran_cnt = 36;

		SetSenseKey(0x0);
		ret = RC_OK;
	}
	return ret;
}

/*****************************************************************************
 *     ReadCapacity
 *****************************************************************************/
int ReadCapacity(void)
{
	int ret = RC_NG;
	DWORD total_sec_cnt;

	bulk_total_tran_cnt = 0x08;

	if (IsCommonErrorFound(DIR_IN) == RC_NO_ERROR) {
		/*  */
		bulk_tran_start_addr = wk_data;

		wk_data[0]	= DWORD2BYTE_HH(last_lba);
		wk_data[1]	= DWORD2BYTE_HL(last_lba);
		wk_data[2]	= DWORD2BYTE_LH(last_lba);
		wk_data[3]	= DWORD2BYTE_LL(last_lba);

		wk_data[4] = DWORD2BYTE_HH(block_size);
		wk_data[5] = DWORD2BYTE_HL(block_size);
		wk_data[6] = DWORD2BYTE_LH(block_size);
		wk_data[7] = DWORD2BYTE_LL(block_size);
				
		SetSenseKey(0x0);
		ret = RC_OK;
	}
	return ret;
}

/*****************************************************************************
 *     ReadFormatCapacity
 *****************************************************************************/
int ReadFormatCapacity(void)
{
	int ret = RC_NG;
	int total_sec_cnt;
	
	bulk_total_tran_cnt = MKDWORD(0x00,0x00,cmd_block[7],cmd_block[8]);

	if (IsCommonErrorFound(DIR_IN) == RC_NO_ERROR)
	{
		bulk_tran_start_addr = wk_data;

		wk_data[0] = 0x00;
		wk_data[1] = 0x00;
		wk_data[2] = 0x00;
		wk_data[3] = 0x10;
				
		total_sec_cnt = last_lba + 1;

		wk_data[4]	= DWORD2BYTE_HH(total_sec_cnt);
		wk_data[5]	= DWORD2BYTE_HL(total_sec_cnt);
		wk_data[6]	= DWORD2BYTE_LH(total_sec_cnt);
		wk_data[7]	= DWORD2BYTE_LL(total_sec_cnt);

		wk_data[8]	= 0x03;	/*  */

		wk_data[9] = DWORD2BYTE_HL(block_size);
		wk_data[10] = DWORD2BYTE_LH(block_size);
		wk_data[11] = DWORD2BYTE_LL(block_size);

		wk_data[12] = DWORD2BYTE_HH(total_sec_cnt);
		wk_data[13] = DWORD2BYTE_HL(total_sec_cnt);
		wk_data[14] = DWORD2BYTE_LH(total_sec_cnt);
		wk_data[15] = DWORD2BYTE_LL(total_sec_cnt);

		/* Reserved  */
		wk_data[16] = 0x00;

		wk_data[17] = DWORD2BYTE_HL(block_size);
		wk_data[18] = DWORD2BYTE_LH(block_size);
		wk_data[19] = DWORD2BYTE_LL(block_size);

		if (bulk_total_tran_cnt > 20)
			bulk_total_tran_cnt = 20;

		SetSenseKey(0x0);
		ret = RC_OK;
	}
	return ret;
}

/*****************************************************************************
 * Mode Select
 *****************************************************************************/
int ModeSelect(void)
{
	int ret = RC_NG;
	
	bulk_total_tran_cnt = MKDWORD(0x00,0x00,cmd_block[7],cmd_block[8]);
	
	/* CBWCBIATAPI */
	if (IsCommonErrorFound(DIR_OUT) == RC_NO_ERROR) {

		if ((cmd_block[1] & 0x01) == 0x01) {	/* SP */
			/*  */
			SetSenseKey(0x052400);
		} else {
			bulk_tran_start_addr = wk_data;
			ret = RC_OK;
		}
	}
	return ret;
}

/*****************************************************************************
 *     Mode Select
 *****************************************************************************/
int ModeSelParaCheck(void)
{
	int ret = RC_OK;		/*  */
	
	wk_cnt = bulk_total_tran_cnt;
	
	if (wk_cnt < 8) {
		/*  */
		SetSenseKey(0x051A00);	/* Parameter List Length Error */
		ret = RC_NG;
	} else {
		/*  */
		wk_cnt -= 8;
		wk_ptr = wk_data + 8;
		while (wk_cnt > 0) {
			/*  */
			MSelFindPage(wk_ptr[0]);
			if (mode_data_cnt == 0) {
				/*  */
				SetSenseKey(0x052600);
				ret = RC_NG;
				break;
			} else if (wk_cnt < mode_data_cnt) {
				/*  */
				SetSenseKey(0x051A00);	/* Parameter List Length Error */
				ret = RC_NG;
				break;
			} else {
				/* Changeable */
				if (IsMSelRcvParaInvalid() == RC_NG) {
					/*  */
					SetSenseKey(0x052600);
					ret = RC_NG;
					break;
				}
			}
			/*  */
			wk_cnt	-= mode_data_cnt;
			wk_ptr += mode_data_cnt;
		}
	}
	
	if (ret == RC_OK)
		SetSenseKey(0x0);

	return ret;
}

/*****************************************************************************
 *     Mode Select
 *****************************************************************************/
void MSelFindPage(BYTE page)
{
	int i;
	
	mode_data_addr = (BYTE *)&mode_data[0];		/* Mode Page */
	mode_data_cnt = 0;				/*  */
	
	for (i = 0;i < MODE_PAGE_CNT;i++) {	/*  */
		if (mode_data_addr[0] == page) {

			mode_data_cnt = mode_data_addr[1] + 2;
			
			/* Changeable */
			mode_chg_addr = mode_data_addr + MODE_PAGES_LEN;
			break;
		}
		mode_data_addr += mode_data_addr[1] + 2;
	}
}

/*****************************************************************************
 *     Mode Select
 *****************************************************************************/
int IsMSelRcvParaInvalid(void)
{
	unsigned char chg;
	int i,ret = RC_NG;		/*  */
	
	chg = wk_ptr[0] ^ mode_data_addr[0];
	if ( chg == 0x00 )
	{	/* Page Code  */
		chg = wk_ptr[1] ^ mode_data_addr[1];
		if (chg == 0x00)
		{   /* Page Length */ 
			for (i = 2;i < mode_data_cnt;i++)
			{
				chg = wk_ptr[i] ^ mode_data_addr[i];
				if ((chg != 0x00) && ((chg & ~mode_chg_addr[i]) != 0x00))
						break;
			}
			if (i == mode_data_cnt)
				ret = RC_OK;
		}
	}
	
	return ret;
}

/*****************************************************************************
 *     Mode Sense
 *****************************************************************************/
int ModeSense(void)
{
	unsigned char page;
	int i,ret = RC_NG;
	
	bulk_total_tran_cnt = MKDWORD(0x00,0x00,cmd_block[7],cmd_block[8]);

	if (IsCommonErrorFound(DIR_IN) == RC_NO_ERROR)
	{
		if ((cmd_block[2] & 0xC0) == 0xC0)
			SetSenseKey(0x053900);
		else
		{
			page = cmd_block[2] & 0x3F;
			MSelFindPage(page);

			if (page != 0x3F && mode_data_cnt == 0)
				SetSenseKey(0x052400);
			else
			{
				if (page == 0x3F)
				{
					mode_data_cnt  = MODE_PAGES_LEN;
					mode_data_addr = (BYTE *)&mode_data[0];
					mode_chg_addr  = (BYTE *)(&mode_data[0] + MODE_PAGES_LEN);
				}

				bulk_tran_start_addr = wk_data;
						
				for (i = 0;i < 8;i++)
					wk_data[i] = 0x00;

				wk_data[1] = mode_data_cnt + 6;
						
				if ((cmd_block[2] & 0xC0) != 0x40)
				{	/* Default,Current Value */
					for (i = 0;i < mode_data_cnt;i++)
						wk_data[i + 8] = mode_data_addr[i];
				} 
				else 
				{	/* Changeable Value */
					for (i = 0;i < mode_data_cnt;i++)
						wk_data[i + 8] = mode_chg_addr[i];
				}
						
				if (bulk_total_tran_cnt > mode_data_cnt + 8)
					bulk_total_tran_cnt = mode_data_cnt + 8;
						
				SetSenseKey(0x0);
				ret = RC_OK;
			}
		}
	}
	
	return ret;
}

/*****************************************************************************
 * PREVENT
 *****************************************************************************/
int Prevent(void)
{
	int ret = RC_NG;

	bulk_total_tran_cnt = 0;
	
	if (IsCommonErrorFound(DIR_NONE) == RC_NO_ERROR)
		SetSenseKey(0x052400);

	return ret;
}

/*****************************************************************************
 * CmdError
 *****************************************************************************/
int CmdError(void)
{
	int ret = RC_NG;

	bulk_total_tran_cnt = 0x00;
	if ( atten_flag.PowerOnReset )
	{
		atten_flag.PowerOnReset = 0;

		SetSenseKey(0x062900);
		return ret;
	}
	else
		SetSenseKey(0x052000);

	return ret;
}

/*****************************************************************************
 * Read 10
 *****************************************************************************/
int Read10(void)
{
	int sec_cnt;
	int ret = RC_NG;

	sec_cnt = MKWORD(cmd_block[7], cmd_block[8]);
	bulk_total_tran_cnt = sec_cnt * block_size;
	
	if (IsCommonErrorFound(DIR_IN) == RC_NO_ERROR)
	{
		ata_lba = MKDWORD(cmd_block[2],cmd_block[3],cmd_block[4],cmd_block[5]);

		if (last_lba < ata_lba + sec_cnt - 1 )
			SetSenseKey(0x052100);		/* LOGICAL BLOCK ADDRESS OUT OF RANGE */
		else
		{
			SetSenseKey(0x0);
			ret = RC_OK;

			if( bulk_total_tran_cnt != 0 )
			{
				tran_flag.DMA = 1;		/* DMA */
//				bulk_tran_start_addr = usb_wk_buf;
				
				if ( media_ReadSec(ata_lba, sec_cnt, &usb_wk_buf[0]) !=0 )
					panic(40);
			}
		}
	}
	return ret;
}

/*****************************************************************************
 *  Write 10
 *****************************************************************************/
int Write10(void)
{
	int sec_cnt;
	int ret = RC_NG;

	sec_cnt = MKWORD(cmd_block[7], cmd_block[8]);
	bulk_total_tran_cnt = sec_cnt * block_size;
	
	if (IsCommonErrorFound(DIR_OUT) == RC_NO_ERROR)
	{
		ata_lba = MKDWORD(cmd_block[2],cmd_block[3],cmd_block[4],cmd_block[5]);

		if (last_lba < ata_lba + sec_cnt -1)
		{
			SetSenseKey(0x052100);	/* LOGICAL BLOCK ADDRESS OUT OF RANGE */
		}
		else
		{
			SetSenseKey(0x0);
			ret = RC_OK;

			if( bulk_total_tran_cnt != 0 )
			{
//				bulk_tran_start_addr = usb_wk_buf;
				tran_flag.DMA = 1;				/* DMA */
			}
		}
	}
	return ret;
}

/*****************************************************************************
 * Seek
 *****************************************************************************/
int Seek(void)
{
	int ret = RC_NG;

	bulk_total_tran_cnt = 0;
	if (IsCommonErrorFound(DIR_NONE) == RC_NO_ERROR)
	{
		ata_lba = MKDWORD(cmd_block[2],cmd_block[3],cmd_block[4],cmd_block[5]);

		if( last_lba < ata_lba )
		{
			SetSenseKey(0x052100);
		}
		else
		{
			SetSenseKey(0x0);
			ret = RC_OK;
		}
	}
	return ret;
}

/*****************************************************************************
 * StartStopUnit
 *****************************************************************************/
int StartStopUnit(void)
{
	int ret = RC_NG;
	
	bulk_total_tran_cnt = 0;
	if (IsCommonErrorFound(DIR_NONE) == RC_NO_ERROR)
	{
		if ((cmd_block[4] & 0x02) == 0x02)
		{
			SetSenseKey(0x052400);
		}
		else
		{
			SetSenseKey(0x0);
			ret = RC_OK;
		}
	}
	return ret;
}

/*****************************************************************************
 * Verify
 *****************************************************************************/
int Verify(void)
{
	int ret = RC_NG;
	int sec_cnt;

	bulk_total_tran_cnt = 0;
	if (IsCommonErrorFound(DIR_NONE) == RC_NO_ERROR)
	{
		ata_lba = MKDWORD(cmd_block[2],cmd_block[3],cmd_block[4],cmd_block[5]);
		sec_cnt = MKWORD(cmd_block[7], cmd_block[8]);

		if( last_lba < ata_lba + sec_cnt - 1 )
		{
			SetSenseKey(0x052100);
		} 
		else if ((cmd_block[1] & 0x02) == 0x02)
		{
			/* ByteChk() */
			SetSenseKey(0x052400);
		}
		else
		{
			SetSenseKey(0x0);
			ret = RC_OK;
		}
	}
	
	return ret;
}

⌨️ 快捷键说明

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