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

📄 scsicmd.c

📁 SdCard_V2.1TinyFatFs.rar是单片机实现SD卡功能的FAT文件系统
💻 C
📖 第 1 页 / 共 2 页
字号:
    ScsiPrepareDiskInfo();
    BulkSetDmaIn((UINT16)UsbDmaTotalLength);
    BulkState = BULK_DMA_IN_COMPLETED;   
  }  
  else
  {
    BulkInStall();
    BulkState = STALL_IN_COMPLETED; 
  }  
}  

//----------------------------------------------------------------------------
// ScsiCmdRquestSense
//----------------------------------------------------------------------------	
void ScsiCmdRquestSense()
{
  bit ClearSenseWord = true;
  
  if (UsbDmaTotalLength > REQUEST_SENSE_DATA_LEN)
    UsbDmaTotalLength = REQUEST_SENSE_DATA_LEN;

  if ((ScsiLun > LastDevice) || (!(0x80 & BlockWrapper->Flags)))
  {
    //We put unsupport sense word on SenseKey,AddSenseCode,AddSenseCodeQ[MAX_DEVICE_NUM].
    //It needn't to clear beause ScsiLun start from 0 to MAX_DEVICE_NUM - 1.        
    ScsiLun = MAX_DEVICE_NUM;  
    ClearSenseWord = false;
  }
    
  //Force to be Command Passed  ????
  CmdStatus = COMMAND_PASSED;
    BulkFreeBuffer();
  // Init Data of RequestSense.
  SetBulkInFull();
    memset((BYTE xdata *)(FIFO_ADDRESS_IN), 0, REQUEST_SENSE_DATA_LEN);
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 0) = 0x70;
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 7) = 0x0A;
    *(BYTE xdata *)(FIFO_ADDRESS_IN + SENSE_KEY_INDEX)      = (0xf & SenseKey);
    *(BYTE xdata *)(FIFO_ADDRESS_IN + ADD_SENSE_CODE_INDEX) = AddSenseCode;
    *(BYTE xdata *)(FIFO_ADDRESS_IN + ADD_SENSE_CODEQ_INDEX)= AddSenseCodeQ;
  if (ClearSenseWord)
  {
    SenseKey      = NO_SENSE;
    AddSenseCode  = 0x00;
    AddSenseCodeQ = 0x00; 
  }  
  
  
  if (CmdStatus != PHASE_ERROR)
  {
     BulkSetDmaIn((UINT16)UsbDmaTotalLength);
     BulkState = BULK_DMA_IN_COMPLETED;   
  }  
  else
  {
    BulkInStall();
    BulkState = STALL_IN_COMPLETED; 
  }  
}  

//----------------------------------------------------------------------------
// ScsiCmdModeSense6
//----------------------------------------------------------------------------	
void ScsiCmdModeSense6()
{
  BYTE PageCode = (*(BYTE xdata *)(FIFO_ADDRESS_OUT + CBWCB_OFFSET + 2) & 0x3f);
    
  if ( !(0x80 & BlockWrapper->Flags) )
    ScsiInvalidFieldError(ScsiLun); 

  BulkFreeBuffer();  //Out端点接收使能
      
  if (CmdStatus == COMMAND_PASSED)
  {
  	SetBulkInFull();
    ScsiPrepareModePage(PageCode, (UINT16)UsbDmaTotalLength);
    BulkSetDmaIn((UINT16)UsbDmaTotalLength);
    BulkState = BULK_DMA_IN_COMPLETED;   
  }
  else  
  {
    BulkInStall();
    BulkState = STALL_IN_COMPLETED; 
  }
}  

//----------------------------------------------------------------------------
// ScsiCmdModeSense10
//----------------------------------------------------------------------------
void ScsiCmdModeSense10()
{
    BulkFreeBuffer();
    SetBulkInFull();
  // Always return the fixed data.	
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 0)     = 0x00;
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 1)     = 0x06;
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 2)     = 0x00;
    if (ScsiWriteProtect[ScsiLun])
    {
        *(BYTE xdata *)(FIFO_ADDRESS_IN + 3) = 0x80;
    }
    else
    {
        *(BYTE xdata *)(FIFO_ADDRESS_IN + 3) = 0x00;
    }
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 4)     = 0x00;
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 5)     = 0x00;
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 6)     = 0x00;
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 7)     = 0x00;
  
  
  BulkSetDmaIn(8);
  BulkState = BULK_DMA_IN_COMPLETED;	
}	
//----------------------------------------------------------------------------
// ScsiCmdReadBuf---2007.08.16
//----------------------------------------------------------------------------
void ScsiCmdReadBuf(void)
{
    BulkFreeBuffer();

    SetBulkInFull();
	memset((BYTE xdata *)DMA_FIFOB0, 0, 8);

    BulkSetDmaIn(8);
    BulkState   = BULK_DMA_IN_COMPLETED;
}

//----------------------------------------------------------------------------
// ScsiCmdStartStopUnit
//----------------------------------------------------------------------------	
void ScsiCmdStartStopUnit()
{
  if (ConvertEndian32(BlockWrapper->DataXsferLen) != 0) 
    ScsiInvalidFieldError(ScsiLun);
  // Host request device to unload this LUN.  
  if (*(BYTE xdata *)(FIFO_ADDRESS_OUT + CBWCB_OFFSET + 4) == 0x02)
    ScsiLoadStatus[ScsiLun] &= ~SCSI_LOAD_STATUS_MASK; 

  if (*(BYTE xdata *)(FIFO_ADDRESS_OUT + CBWCB_OFFSET + 0x04)) // detect start or stop device.
    StorageStart(); // add by C.H. Liang
  else
    StorageEject(); // add by C.H. Liang
  
  BulkFreeBuffer();  //

  CmdStatus = 0x00;
  BulkPrepareCSW(CmdStatus);
}  

//----------------------------------------------------------------------------
// ScsiCmdPreventRemoval
//----------------------------------------------------------------------------	
void ScsiCmdPreventRemoval()
{
  if (ConvertEndian32(BlockWrapper->DataXsferLen) != 0) 
    ScsiInvalidFieldError(ScsiLun); 
  // We don't support link SCSI commands.  
  if (*(BYTE xdata *)(FIFO_ADDRESS_OUT + CBWCB_OFFSET + 5) & SCSI_CTRL_LINK_BIT)      
  {
    SET_ILLEGAL_REQUEST(ScsiLun);
    CmdStatus = COMMAND_FAILED;  	
  }	
  
  BulkFreeBuffer();  //Out端点接收使能
  
  if (CmdStatus == COMMAND_PASSED)
    BulkPrepareCSW(CmdStatus);
  else  
  {
    BulkInStall();
    BulkState = STALL_IN_COMPLETED;   
  }  
}  

//----------------------------------------------------------------------------
// ScsiCmdReadCapacity10
//----------------------------------------------------------------------------
void ScsiCmdReadCapacity10()
{
  if (UsbDmaTotalLength > CAPACITY10_DATA_LEN)
    UsbDmaTotalLength = CAPACITY10_DATA_LEN;
    
  if (!(0x80 & BlockWrapper->Flags))
    ScsiInvalidFieldError(ScsiLun); 
  
  BulkFreeBuffer();  //Out端点接收使能
    
  if (CmdStatus == COMMAND_PASSED)
  {
        SetBulkInFull();
    ScsiGetLunCapacity();
    BulkSetDmaIn((UINT16)UsbDmaTotalLength);
    BulkState = BULK_DMA_IN_COMPLETED; 
  }  
  else
  {  
    BulkInStall();		  			//将IN STALL位置1
    BulkState = STALL_IN_COMPLETED; //转到STALL_IN_COMPLETED状态处理
  }     
}  

//----------------------------------------------------------------------------
// ScsiCmdRead10
//----------------------------------------------------------------------------
void ScsiCmdRead10()
{
    STATUS Status;

    SectorStart = *(UINT32 xdata *)(FIFO_ADDRESS_OUT + CBWCB_OFFSET + 2);
    SectorCount = *(UINT16 xdata *)(FIFO_ADDRESS_OUT + CBWCB_OFFSET + 7);

    if(!(BlockWrapper->Flags & 0x80))
    {
        SetSenseErrCmdField();
    } 
    
    BulkFreeBuffer();//Out端点接收使能  

    if(CmdStatus == COMMAND_PASSED)
    {	
        Status = ReadSector();	//derek

		if(Status != STATUS_SUCCESS)
        {
            CmdStatus = COMMAND_FAILED;
            SetSenseDataRd(Status);
        }
    }

    if(CmdStatus == COMMAND_PASSED)
    {
        BulkState = BULK_DMA_IN_COMPLETED;
		BulkSetDmaIn(BYTES_PER_SECTOR);

    }
    else
    {
        BulkInStall();
        BulkState = STALL_IN_COMPLETED;
    }
}  

//----------------------------------------------------------------------------
// ScsiCmdWrite10
//----------------------------------------------------------------------------
void ScsiCmdWrite10()
{

    SectorStart = *(UINT32 xdata *)(FIFO_ADDRESS_OUT + CBWCB_OFFSET + 2);
    SectorCount = *(UINT16 xdata *)(FIFO_ADDRESS_OUT + CBWCB_OFFSET + 7);

    if(0x80 & BlockWrapper->Flags)
    {
        SetSenseErrCmdField();
    }

    BulkFreeBuffer();//Out端点接收使能  

    if(CmdStatus == COMMAND_PASSED)
    {
        FirstWrite = true;
        BulkState = BULK_DMA_OUT_COMPLETED;

    }
	if(CmdStatus != COMMAND_PASSED)       
    {
        BulkInStall();
        BulkState = STALL_IN_COMPLETED; 
    }
}  

//----------------------------------------------------------------------------
// ScsiCmdVerify10
//----------------------------------------------------------------------------
void ScsiCmdVerify10()
{
      
  if (ConvertEndian32(BlockWrapper->DataXsferLen) != 0) 
      ScsiInvalidFieldError(ScsiLun); 
      
  BulkFreeBuffer();  //Out端点接收使能
      
  if (CmdStatus == COMMAND_PASSED)
    BulkPrepareCSW(CmdStatus);  
  else        
  {
    BulkInStall();
    BulkState = STALL_IN_COMPLETED; 
  }     
}  

//----------------------------------------------------------------------------
// ScsiCmdModeSelect6
//----------------------------------------------------------------------------
void ScsiCmdModeSelect6()
{
  if (0x80 & BlockWrapper->Flags)
  {
    ScsiInvalidFieldError(ScsiLun); 
  }
  // We don't support this command. 
  CmdStatus = COMMAND_FAILED; 
  
  BulkFreeBuffer();  //Out端点接收使能
  
  if (CmdStatus != PHASE_ERROR)
  {
    SET_ILLEGAL_REQUEST(ScsiLun);    	
    // Wait Data Received Ready.
    BulkWaitOutDataReady();  // Wait Data Received Ready.
    BulkPrepareCSW(CmdStatus);
  }	
  else        
  {
    BulkInStall();
    BulkState = STALL_IN_COMPLETED; 
  }     	
}	

//----------------------------------------------------------------------------
// OpCode = 0x23.
//----------------------------------------------------------------------------
void ScsiCmdOpCode23H()
{
  BulkFreeBuffer();    	
    
	SetBulkInFull(); 	
    memset((BYTE xdata *)(FIFO_ADDRESS_IN), 0, 12);
  // Emulate PenDrive behavior to run BIOS Boot.
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 3)     = 0x08;
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 5)     = 0x01;
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 6)     = 0xF4;
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 8)     = 0x02;
    *(BYTE xdata *)(FIFO_ADDRESS_IN + 10)    = 0x02;

  BulkSetDmaIn(12);  
  BulkState = BULK_DMA_IN_COMPLETED;
 
}  

/***************************************************************************
  SCSI COMMAND END
***************************************************************************/

//----------------------------------------------------------------------------
// Do some initializations before a new SCSI command executed.
//----------------------------------------------------------------------------
void ScsiCmdNewStart()
{ 
  // Update the memory address of BlockWrapper.
  BlockWrapper = (CMD_BLOCK_WRAPPER xdata *)(FIFO_ADDRESS_OUT);     
 
  // UsbDmaTotalLength is used on other Scsicmd other than reading and writing.
  UsbDmaTotalLength = ConvertEndian32(BlockWrapper->DataXsferLen); 
  SectorStart = 0;				  //reset SectorStart & SectorCount
  SectorCount   = 0;
  CmdStatus = COMMAND_PASSED; 
  ScsiLun = BlockWrapper->CbwcbLun;
  WrapperTag = BlockWrapper->Tag;
}

//----------------------------------------------------------------------------
// Init SCSI used parameters.
//----------------------------------------------------------------------------
void ScsiInit()
{
  BYTE i;

    SenseKey      = NO_SENSE;
    AddSenseCode  = 0x00;
    AddSenseCodeQ = 0x00;

  for (i = 0; i < MAX_DEVICE_NUM ; i++)  
  {
    ScsiWriteProtect[i] = false;
    ScsiWriteProtectChange[i] = false;
  }  
}	

//----------------------------------------------------------------------------
// Check SCSI Command
//----------------------------------------------------------------------------
void ScsiCheckCmd()
{
    BYTE OpCode;
    ScsiCmdNewStart();        
    OpCode = *(BYTE xdata *)(FIFO_ADDRESS_OUT + CBWCB_OFFSET);
												 //
    ScsiLunValidCheck();

    if(CmdStatus == PHASE_ERROR)
    {
        SetSenseDataRd(STATUS_NO_MEDIA);
        BulkInStall();
        BulkState = STALL_IN_COMPLETED; 
        return;
    }

    if(BlockWrapper->Sign != CBW_SIGNATURE)
    {
        SetSenseErrCmdField();
        CmdStatus = PHASE_ERROR;
        BulkInStall();
        BulkState = STALL_IN_COMPLETED; 
        return;
    }

    switch (OpCode)
    {
        case TEST_UNIT_READY_OPCODE: ScsiCmdTestUnitReady(); return;
        case REQUEST_SENSE_OPCODE  : ScsiCmdRquestSense();   return;
        case MODE_SELECT6_OPCODE   : ScsiCmdModeSelect6();   return;
        case MODE_SENSE6_OPCODE    : ScsiCmdModeSense6();    return;
        case INQUIRY_OPCODE        : ScsiCmdInquiry();       return;
        case START_STOP_UNIT_OPCODE: ScsiCmdStartStopUnit(); return;
        case PREVENT_REMOVAL_OPCODE: ScsiCmdPreventRemoval();return;
        case READ_CAPACITY10_OPCODE: ScsiCmdReadCapacity10();return;
        case READ10_OPCODE         : ScsiCmdRead10();        return;
        case WRITE10_OPCODE        : ScsiCmdWrite10();       return;
        case VERIFY10_OPCODE       : ScsiCmdVerify10();      return;
        case _23_OPCODE            : ScsiCmdOpCode23H();     return;
        case MODE_SENSE10_OPCODE   : ScsiCmdModeSense10();   return;
		case READ_BUFFER		   : ScsiCmdReadBuf();			 return; //2007.08.16
        default:
            CmdStatus = PHASE_ERROR;
            SetSenseErrOpCode();
            BulkInStall();
            BulkState = STALL_IN_COMPLETED; 
    }
}	 
 

⌨️ 快捷键说明

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