📄 scsi2.c
字号:
/***********************************************************************
* $Workfile: scsi2.c $
* $Revision: 1.3 $
* $Author: meterchen $
* $Date: 2003/08/25 14:03:12 $
*
* Project: TianGuang-udisk
*
* Description:
* This file implements part of SCSI2 command set
* SCSI2 command set is used in this usb mass storage device
*
* Revision History:
*
***********************************************************************
*
* Copyright (c) 2003 CHENMENG
*
* All rights reserved
*
**********************************************************************/
#include "BasicTyp.h"
/* usb device operate head file */
#include "def9603.h"
#include "macro.h"
#include "bitops.h"
/* defined in usb.c */
extern UINT8 dtapid; /* PID related status */
#define TGL0PID BIT0 /* tracks NEXT data PID for endpoint0*/
#define TGL1PID BIT1 /* tracks NEXT data PID for endpoint1*/
#define TGL2PID BIT2 /* tracks NEXT data PID for endpoint2*/
#define TGL3PID BIT3 /* tracks NEXT data PID for endpoint3*/
#include "SCSI2.h"
#include "SCSI2Cmd.h"
#include "TPBulk.h"
/* file system head file */
#include "pcdisk.h"
/* global data define */
extern INT32 BOTXfer_wResidue;
extern INT8 * BOTXfer_pData;
extern TPBLK_STRUC TPBulk_Block;
#define TPBulk_CBW TPBulk_Block.TPBulk_CommandBlock
#define CBW_wXferLen TPBulk_CBW.dCBW_DataXferLen
#define SCSI2_CDB TPBulk_CBW.cdbSCSI2
#define SCSI2_LUN TPBulk_CBW.bCBW_LUN
#define TPBulk_CSW TPBulk_Block.TPBulk_CommandStatus
#define CSW_wResidue ((INT16)TPBulk_CSW.dCSW_DataResidue)
/* state machine */
extern INT8 BOTFSMstate;
#define BOTFSM_CBWProc 0x0
#define BOTFSM_DataIn 0x1
#define BOTFSM_DataOut 0x2
#define BOTFSM_CSWProc 0x3
#define BOTFSM_CSW 0x4
#define BOTFSM_IDLE 0x5
#define BOTFSM_Stall 0x6
#define BOTFSM_DATAIN 0x7
/*
*************************************************************************
Private Data
*************************************************************************
*/
REQUEST_SENSE_DATA Req_SenseData=
{
//0x70, 0x00, 0x06, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x29,
//0x00, 0x00, 0x00, 0x00, 0x00
0x70, // INT8 ResponseCode : 7;
0, // INT8 Valid : 1;
0,// INT8 SegmentNum;
0x5,// INT8 SenseKey : 4; 5= illegal request
0, // INT8 Reserved0 : 1;
0,// INT8 WrongLenIndicator : 1;
0,// INT8 EndofMedium : 1;
0,// INT8 FileMark : 1;
0,// INT8 Info_0;
0,// INT8 Info_1;
0,// INT8 Info_2;
0,// INT8 Info_3;
0xA,// INT8 AdditionalSenseLen;
0,// INT8 CommandSpecInfo_0;
0,// INT8 CommandSpecInfo_1;
0,// INT8 CommandSpecInfo_2;
0,// INT8 CommandSpecInfo_3;
0x29,// INT8 ASC;
0,// INT8 ASCQ;
0,// INT8 FieldReplacableUnitCode;
0,// INT8 SenseKeySpec_0 : 7;
0,// INT8 SenseKeySpecValid : 1;
0,// INT8 SenseKeySpec_1;
0 // INT8 SenseKeySpec_2;
};
/* i have to use this UGLY Pad for align */
INT32 Pad=0x5555aaaa;
STD_INQUIRYDATA inquiryData =
{
0x00,// SCSI2_DEVICE,: 5;
0,//INT8 Reserved0 : 3;
0,//INT8 Reserved1 : 7;
1,//INT8 RemovableMedia : 1;
2,//INT8 Reserved2;
2,//INT8 Reserved3 : 5;
0,//INT8 NormACA : 1;
0,//INT8 Obsolete0 : 1;
0,//INT8 AERC : 1;
//INT8 Reserved4[3];
{
0x1F,0,0
},
0,//INT8 SoftReset : 1;
0,//INT8 CommandQueue : 1;
0,//INT8 Reserved5 : 1;
0,//INT8 LinkedCommands : 1;
0,//INT8 Synchronous : 1;
0,//INT8 Wide16Bit : 1;
0,//INT8 Wide32Bit : 1;
0,//INT8 RelativeAddressing : 1;
//INT8 VendorId[8];
{
'C','H','E','N',
'M','E','N','G'
},
//INT8 ProductId[16];
{
'C','F',' ','C',
'A','R','D',' ',
'R','E','A','D',
'E','R',' ',' '
},
//INT8 ProductRevisionLevel[4];
{
'0','.','0','0'
}
};
/*
*************************************************************************
* Subroutines
*************************************************************************
*/
/*
* SCSI command set interpreter
*/
BOOLEAN SCSI2_Handler( void )
{
#define cdbGeneric SCSI2_CDB.RbcCdb_Generic
BOOLEAN retStatus = FALSE;
BOTXfer_wResidue = 0;
BOTFSMstate = BOTFSM_IDLE;
switch(cdbGeneric.OperationCode)
{
/* required command */
case SCSI2_CMD_READ10:
retStatus = SCSI2_Read();
break;
case SCSI2_CMD_READCAPACITY:
retStatus = SCSI2_ReadCapacity();
break;
//case SCSI2_CMD_STARTSTOPUNIT:
// retStatus = SCSI2_OnOffUnit();
// break;
//case SCSI2_CMD_SYNCCACHE:
// retStatus = SCSI2_SyncCache();
// break;
case SCSI2_CMD_VERIFY10:
retStatus = SCSI2_Verify();
break;
case SCSI2_CMD_WRITE10:
retStatus = SCSI2_Write();
break;
case SCSI2_CMD_INQUIRY:
retStatus = SCSI2_Inquiry();
break;
//case SCSI2_CMD_MODESELECT6: //0x15
// retStatus = SCSI2_ModeSelect();
// break;
case SCSI2_CMD_MODESENSE6: //0x1A
retStatus = SCSI2_ModeSense();
break;
//case SCSI2_CMD_PRVENTALLOWMEDIUMREMOVAL:
// retStatus = SCSI2_LockMedia();
// break;
case SCSI2_CMD_TESTUNITREADY: //0x00
retStatus = SCSI2_TestUnit();
break;
case SCSI2_CMD_REQUESTSENSE: //0x03
retStatus = SCSI2_RequestSense();
break;
/* optional commands */
case SCSI2_CMD_FORMAT:
retStatus = SCSI2_Format();
break;
//case SCSI2_CMD_RESERVE6:
// retStatus = SCSI2_Reserve6();
// break;
//case SCSI2_CMD_RELEASE6:
// retStatus = SCSI2_Release6();
// break;
//case SCSI2_CMD_PERSISTANTRESERVIN:
// retStatus = SCSI2_PersisReserveIn();
// break;
//case SCSI2_CMD_PERSISTANTRESERVOUT:
// retStatus = SCSI2_PersisReserveOut();
// break;
//case SCSI2_CMD_WRITEBUFFER:
// retStatus = SCSI2_WriteBuff();
// break;
case SCSI2_CMD_READFORMATCAPCITY://0x23
retStatus = SCSI2_ReadFormatCapacity();
break;
default:
/* Invalid CBW */
TPBulksup_ErrorHandler(CASECBW,0);
//SCSI_SENSE_ILLEGAL_REQUEST=0x05
//SCSI_ADSENSE_ILLEGAL_COMMAND=0x20
//SCSI2_BuildSenseData(SCSI_SENSE_ILLEGAL_REQUEST,SCSI_ADSENSE_ILLEGAL_COMMAND,0);
TPBulk_CSWHandler();// Goto USBFSM4BOT_CSWPROC;
break;
}
return retStatus;
#undef cdbGeneric
}
BOOLEAN SCSI2_ReadFormatCapacity(void)
{
INT8 i;
INT8 BOTXfer_Data[12];
/* build readformatcapacity packet */
BOTXfer_Data[0]=0x00; BOTXfer_Data[1]=0x00;BOTXfer_Data[2]=0x00;BOTXfer_Data[3]=0x08; //capacity list header
/* current/maximum capacity descriptor */
BOTXfer_Data[4]=0x20;BOTXfer_Data[5]=0x00;BOTXfer_Data[6]=0x00; BOTXfer_Data[7]=0x00; //numbers of blocks
BOTXfer_Data[8]=0x03; //descriptor code
BOTXfer_Data[9]=0x00;BOTXfer_Data[10]=0x02;BOTXfer_Data[11]=0x00; //block length
/*
* in fact CBW_wXferLen = 0xfc
* but i only return 12Bytes
*/
BOTXfer_wResidue = 12;
BOTXfer_pData = BOTXfer_Data;
/* build CSW */
TPBulksup_ErrorHandler(CASE6, BOTXfer_wResidue);
//SCSI2_BuildSenseData(SCSI_SENSE_NO_SENSE,0,0);
BOTFSMstate = BOTFSM_DATAIN;
/* reset bulk in ep */
FLUSHTX1;
for(i=0; i<12; i++)
write_usb(TXD1,((INT8 *)BOTXfer_pData)[i]); /*send data to the tx1 FIFO */
BOTXfer_wResidue =0;
/* enable TX, choose PID, and flip the data toggle */
TXEN1_PID;
return(TRUE);
}
/*
* global data for CF card operation
*
*/
INT16 rwbuf[256*128]; //read&write sharing buffer, it can hold the maximum data issued by WINDOWS
UINT32 LBA_W32; //LBA number
UINT32 LBA_Count; //LBA quantity
BOOLEAN SCSI2_Read(void)
{
#define cdbRead SCSI2_CDB.RbcCdb_Read
INT8 i;
/* get the transfer length in cbw */
BOTXfer_wResidue = CBW_wXferLen;
/* build csw to be sent later */
TPBulksup_ErrorHandler(CASE6,BOTXfer_wResidue);
//SCSI2_BuildSenseData(SCSI_SENSE_NO_SENSE,0,0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -