📄 massstorage.c
字号:
///////////////////////////////////////////////////////////////////////////////
//
// File name: MassStorage.C
// Version: 1.0
// Date: 2003/7/13
// Description: MSCD=>Mass Storage Class Driver
//
//
// Author:
// Email:
// Phone: (03) 578-7888
// Company: Faraday Tech. Corp.
///////////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "chipset.h"
#include "flib.h"
#include "Lib_Host20.h"
#include "Host20_AP.H"
#include "scsi.h"
#include "MassStorage.H"
#include "command.h"
#include "filectrl.h"
//#include "serial.h"
UINT32 gwTag=0x88888888;
//===============================================================================================
//===============================================================================================
//===============================================================================================
//============================= Group-1: Mass Storage Class Implement ===========================
//===============================================================================================
//===============================================================================================
//===============================================================================================
//***************************************************************************************
// Function Name: Host20_MSCD_ClearFeature
// Description:
// Input:
// Output:
// Status:S
//***************************************************************************************
UINT8 Host20_MSCD_ClearFeature(UINT8 bEdNum)
{
UINT8 bTemp;
UINT8 HOST20_CLEAR_FEATURE[8] = {0x02,0x01,0x00,0x00,0x81,0x00,0x00,0x00}; //Get MAX LUN
HOST20_CLEAR_FEATURE[4]=bEdNum;
if (flib_Host20_Issue_Control_ByMode ((bEdNum&0x1F),&HOST20_CLEAR_FEATURE,0x00 //bEdNum,UINT8* pbCmd,hwDataSize
,&bTemp,1)>0)//UINT8* pbData,UINT8 bModeSelect
{
printf(">>> Host20_MSCD_ClearFeature Fail ...\n");
return (0);
}
return (1);
}
//***************************************************************************************
// Function Name:Host20_MSCD_issue_CBW
// Description:
// Input:
// Output:
// Status:P-OK
//***************************************************************************************
UINT8 Host20_MSCD_issue_CBW(struct us_data *psMassStorage)
{
Host20_BufferPointerArray_Structure aTemp;
//<1>.Prepare the CBW data
sOTGH_PT_BLK->sCBW.u32Signature = OTGH_PT_CBW_SIGNATE;
sOTGH_PT_BLK->sCBW.u32DataTransferLength=psMassStorage->srb->request_bufflen;
sOTGH_PT_BLK->sCBW.u32Tag=gwTag;
switch (psMassStorage->srb->sc_data_direction) {
case SCSI_DATA_WRITE:
sOTGH_PT_BLK->sCBW.u8Flags=0x00;
break;
case SCSI_DATA_READ:
sOTGH_PT_BLK->sCBW.u8Flags=0x80; //john 0x01
break;
case SCSI_DATA_UNKNOWN:
case SCSI_DATA_NONE:
printf(">>> Unknow 'psMassStorage->srb->sc_data_direction'... \n");
while(1);
break;
}
sOTGH_PT_BLK->sCBW.u8LUN=0;//Only support 1 LUN
sOTGH_PT_BLK->sCBW.u8CBLength=psMassStorage->srb->cmd_len;//Command Length
memcpy(&(sOTGH_PT_BLK->sCBW.u8CB[0]),&(psMassStorage->srb->cmnd[0]),16);
//<2>.Issue the Bulk-Out command
aTemp.BufferPointerArray[0]=(UINT32)(&(sOTGH_PT_BLK->sCBW.u32Signature));
aTemp.BufferPointerArray[1]=0;
aTemp.BufferPointerArray[2]=0;
aTemp.BufferPointerArray[3]=0;
aTemp.BufferPointerArray[4]=0;
return(flib_Host20_Issue_Bulk (sOTGH_PT_BLK->bOutQHDArrayNum,31,(&aTemp.BufferPointerArray[0]),0,OTGH_Dir_Out));
}
//***************************************************************************************
// Function Name:Host20_MSCD_issue_CSW
// Description:
// Input:
// Output:
// Status:P-OK
//***************************************************************************************
UINT8 Host20_MSCD_issue_CSW(struct us_data *psMassStorage)
{
UINT32 wCBWTag,wCSWTag,bTemp;
Host20_BufferPointerArray_Structure aTemp;
//<1>.Issue the Bulk-IN Command
aTemp.BufferPointerArray[0]=(UINT32)(&(sOTGH_PT_BLK->sCSW.u32Signature));
aTemp.BufferPointerArray[1]=0;
aTemp.BufferPointerArray[2]=0;
aTemp.BufferPointerArray[3]=0;
aTemp.BufferPointerArray[4]=0;
bTemp=flib_Host20_Issue_Bulk (sOTGH_PT_BLK->bInQHDArrayNum,13,&(aTemp.BufferPointerArray[0]),0,OTGH_Dir_IN);
if (bTemp!=0) { //john if (bTemp==HOST20_FAIL) {
return(HOST20_MSCD_CSW_Status_STALL);
}
//<2>.Check the data-Tag
wCBWTag=(UINT32)(sOTGH_PT_BLK->sCBW.u32Tag);
wCSWTag=(UINT32)(sOTGH_PT_BLK->sCSW.u32Tag);
if (wCBWTag!=wCSWTag)
{printf(">>> Error: Received CSW->Tag fail (Expected data:0x%x / Received Data:0x%x)\n",(UINT32)(wCBWTag),(UINT32)(wCSWTag));
return(HOST20_MSCD_CSW_Status_NOT_VALID);
}
//<3>.Check the data-Signature
if ((sOTGH_PT_BLK->sCSW.u32Signature)!=OTGH_PT_CSW_SIGNATE)
{printf(">>> Error: Received CSW->Signature fail (Expected data:%d / Received Data:%d)\n",OTGH_PT_CSW_SIGNATE,(UINT32)(sOTGH_PT_BLK->sCSW.u32Tag));
return(HOST20_MSCD_CSW_Status_NOT_VALID);
}
//<4>.Checking Status OTGH_PT_CSW_PASS
if ((sOTGH_PT_BLK->sCSW.u8Status)!=HOST20_MSCD_CSW_Status_PASS)
{printf(">>> Error: Received CSW->Status fail 'HOST20_MSCD_CSW_Status_FAIL'\n");
return(sOTGH_PT_BLK->sCSW.u8Status);
}
return(HOST20_MSCD_CSW_Status_PASS);
}
//***************************************************************************************
// Function Name: Host20_MSCD_issue_Data
// Description:
// Input:
// Output:
// Status:P-OK
//***************************************************************************************
UINT8 Host20_MSCD_issue_Data(struct us_data *psMassStorage)
{
UINT8 *pbDataPage[5];
UINT32 wTotalLengthRemain,w4kRemain,wOffset,i;
//<1>.To fill the data buffer
wTotalLengthRemain=psMassStorage->srb->request_bufflen;
pbDataPage[0]=((UINT32)(psMassStorage->srb->request_buffer))&0xfffff000;
wOffset=((UINT32)(psMassStorage->srb->request_buffer))&0x0fff;
w4kRemain=4096-wOffset;
i=1;
while (wTotalLengthRemain>w4kRemain)
{
if (wTotalLengthRemain>w4kRemain)
{
if (i<5)
pbDataPage[i]=pbDataPage[i-1]+4096;
else
{printf("??? Buffer OverRun...\n");
while(1);
}
}
wTotalLengthRemain=wTotalLengthRemain-w4kRemain;
w4kRemain=4096;
i++;
} //while (wTotalLengthRemain>w4kRemain)
//<2>.Issue Transfer
switch (psMassStorage->srb->sc_data_direction)
{
case SCSI_DATA_WRITE://Out
//<1>.Issue the Loop1-OutData
return(flib_Host20_Issue_Bulk (sOTGH_PT_BLK->bOutQHDArrayNum,psMassStorage->srb->request_bufflen
,&(pbDataPage[0]),wOffset,OTGH_Dir_Out));
break;
case SCSI_DATA_READ://In
//<2>.Issue the Loop2-InData & Compare
return(flib_Host20_Issue_Bulk (sOTGH_PT_BLK->bInQHDArrayNum, psMassStorage->srb->request_bufflen
,&(pbDataPage[0]),wOffset,OTGH_Dir_IN));
break;
case SCSI_DATA_UNKNOWN:
case SCSI_DATA_NONE:
printf(">>> Unknow 'psMassStorage->srb->sc_data_direction'... \n");
while(1);
break;
}
return(0);
}
//***************************************************************************************
// Function Name: Host20_MSCD_usb_stor_control_thread
// Description:
// <1>.Issue CBW
// <2>.Issue Data Stage
// <3>.Issue CSW
// <4>.Fill the result & return
// Input:
// Output:
// Status:S
//***************************************************************************************
void Host20_MSCD_usb_stor_control_thread(struct us_data *psMassStorage)
{
UINT8 bValue;
//<1>.CBW issue
if (Host20_MSCD_issue_CBW(psMassStorage)>0)
{printf("??? 'Host20_MSCD_issue_CBW' Fail...\n");
while(1);
}
//<2>.Data issue
if (Mass_stor_us->srb->request_bufflen>0)
if (Host20_MSCD_issue_Data(psMassStorage)>0)
{printf("??? 'Host20_MSCD_issue_Data' Fail...\n");
while(1);
}
//<3>.CSW issue
bValue=Host20_MSCD_issue_CSW(psMassStorage);
if(bValue>0)
{printf("??? 'Host20_MSCD_issue_CSW' Fail...\n");
//For Stall=>try again
if (bValue==HOST20_MSCD_CSW_Status_STALL)
{printf(">>> Device Stall the Command, CSW issue again.\n");
//<3.1>.Clear Feature
Host20_MSCD_ClearFeature(0x81);
//<3.2>.Read CSW again
bValue=Host20_MSCD_issue_CSW(psMassStorage);
}
//For Reset Recovery
//if (bValue>0)
// {
// if ()
// printf(">>> Issue the Reset Recovery Procedure...\n");
// /////???? => Will implement the Reset Recovery Procedure
// while(1);
// }
}
Mass_stor_us->srb->result = SAM_STAT_GOOD;
gwTag++;
}
//***************************************************************************************
// Function Name: Host20_MSCD_GetMaxLUN
// Description:
// Input:
// Output:
// Status:S
//***************************************************************************************
UINT8 Host20_MSCD_GetMaxLUN(void)
{
UINT8 bMaxLun;
UINT8 HOST20_MSCD_GET_MAX_LUN[8] = {0xA1,0xFE,0x00,0x00,0x00,0x00,0x01,0x00}; //Get MAX LUN
//Setup=0xA1,0xFE,0x00,0x00,0x00,0x00,0x01,0x00
//In =1 bytes
//Ack
if (flib_Host20_Issue_Control_ByMode (1,&HOST20_MSCD_GET_MAX_LUN,0x01 //bEdNum,UINT8* pbCmd,hwDataSize
,&bMaxLun,0)>0)//UINT8* pbData,UINT8 bModeSelect
{
printf(">>> Host20_MSCD_GetMaxLUN Fail ...\n");
return (0);
}
return (bMaxLun);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -