📄 u_atapicmd.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 + -