📄 mass_bulk.c
字号:
#define MASS_BULK_GLOBALS
#include "config.h"
INT8U Test_UnitReady(hMedLUN *medium_ptr);
//********************************************************************************
//函数名称:Creat_Medium
//输入参数:dvi_ptr,大容量设备的设备描述信息结构指针
// LUNIndex,逻辑单元索引,0为第1个逻辑单元
//输出参数:逻辑单元存在,返回逻辑单元描述符指针
// 逻辑单元不存在,返回一个容指针
//功能描述:建立(获取)大容量设备的一个媒介(逻辑单元)描述符。
//********************************************************************************
hMedLUN *Create_Medium(device_instance *dvi_ptr ,INT8U LUNIndex)
{
hMedLUN *medium_ptr;
MassStorageClass *mass_ptr;
SENSE_DATA SenseData;
INT8U i;
INT8U Statue;
mass_ptr = &MSCDevices[0];
for (i=0; i<MAX_MASS_LUN; i++) {
mass_ptr->LUN_info_ptr[i] = &MSCDeviceLUNs[i];
mass_ptr->LUN_info_ptr[i]->MSC = mass_ptr;
}
(dvi_ptr->class_instance_ptr) = mass_ptr;
mass_ptr->LUN = 0;
mass_ptr->dvi_ptr = dvi_ptr;
mass_ptr->ProtocolCode = dvi_ptr->interfacef_descriptor.bInterfaceProtocol;
mass_ptr->SubclassCode = dvi_ptr->interfacef_descriptor.bInterfaceSubClass;
if (mass_ptr->ProtocolCode != 0x50) {
return NULL;
}
/*
if (BulkOnlyGet_MassInfo(mass_ptr) == NULL) {
return NULL;
}
USB_Delay(10);
*/
Statue = Test_UnitReady(mass_ptr->LUN_info_ptr[0]);
if (Statue == COMMAND_FAILED) {
return NULL;
}
Statue = Get_RequestSense(mass_ptr->LUN_info_ptr[0], &SenseData);
if (Statue == COMMAND_FAILED) {
return NULL;
}
Statue = Get_ThisMediumCapacity(mass_ptr->LUN_info_ptr[0]);
if (Statue == COMMAND_FAILED) {
return NULL;
}
if( (mass_ptr->LUN_info_ptr[LUNIndex]->LastLogicalBlookAddress==0)
&& ( mass_ptr->LUN_info_ptr[LUNIndex]->BlockLengthInBytes==0))
{
medium_ptr = mass_ptr->LUN_info_ptr[LUNIndex];
for( i=0; i<3; i++ )
{
Statue = Get_ThisMediumCapacity(medium_ptr);
if (Statue == COMMAND_PASSED) {
return medium_ptr;
}
}
}
return NULL;
}
//********************************************************************************
//函数名称:Creat_Medium
//输入参数:hMedLUNPtr,逻辑单元描述符指针
// LUNIndex,逻辑单元索引,0为第1个逻辑单元
//输出参数:无
//功能描述:关闭逻辑单元
//********************************************************************************
void Close_Medium(hMedLUN *medium_ptr, INT8U LUNIndex)
{
if (medium_ptr == NULL) {
return ;
}
if (medium_ptr->MSC == NULL) {
return;
}
if (medium_ptr->MSC->LUN < LUNIndex) {
return;
}
medium_ptr->LastLogicalBlookAddress = 0;
medium_ptr->BlockLengthInBytes = 0;
}
//******************************************************************************************
// 函数名称:MassStorageReset
// 输入参数:DevicePtr,设备描述信息结构指针
// 输出参数:TRUE,正常完成
// FALSE,出错
// 功能描述:大容量设备复位请求。
//******************************************************************************************
INT8U Reset_MassStorage(device_instance *dvi_ptr)
{
USB_Device_Request req;
INT16U err;
INT8U none;
req.bmRequestType = 0x21;
req.bRequest = 0xff;
req.wValue = 0;
req.wIndex = 0;
req.wLength = 0;
err = Control_Transfer(&req, dvi_ptr, &none);
return (err ? FALSE:TRUE);
}
//******************************************************************************************
// 函数名称:GetMaxLUN
// 输入参数:DevicePtr,设备描述信息结构指针
// 输出参数:返回最大逻辑单元数,返回值为0表示只有1个逻辑单元存在。
// 出错返回去0xff.
// 功能描述:获取设备的逻辑单元总数请求。
//******************************************************************************************
INT8U Get_MaxLUN(device_instance *dvi_ptr)
{
INT8U MaxLUN = 0;
USB_Device_Request req;
INT16U err;
req.bmRequestType = 0xa1;
req.bRequest = 0xfe;
req.wValue = 0;
req.wIndex = 0;
req.wLength = 1;
err = Control_Transfer(&req, dvi_ptr, &MaxLUN);
if (err) {
return (0); //有些邋MassStorage设备不支持该命令
}
else {
return (MaxLUN);
}
}
//************************************************************************************
// 函数名称:BulkGetCSWStatus
// 输入参数:Bulk_tr_In_Ptr,批量输入传输描述符
// CBW_BuffPtr,命令块包缓冲区指针
// 输出参数:正常返回命令状态:0、1、2
// 出错返回0xff;
// 功能描述:获取命令状态包
//************************************************************************************
INT16U Get_CSWStatus(hMedLUN *medium_ptr)
{
COMMAND_STATUS_WRAPPER CSWB;
COMMAND_BLOCK_WRAPPER *CBW_ptr;
INT16U err;
INT8U CSWStatus;
INT32U dCSWDataResidue;
INT32U dCBW_DataXferLen;
return 0;
err =Bulk_Transfer(DirectionPID_IN, (INT8U *)&CSWB, 13, medium_ptr->MSC->dvi_ptr);
if (err) {
return err;
}
if (!
(
(CSWB.dCSW_Signature_0==0x55)
&&(CSWB.dCSW_Signature_1==0x53)
&&(CSWB.dCSW_Signature_2==0x42)
&&(CSWB.dCSW_Signature_3==0x53)
)
) {
return 0xff;
}
if (CSWB.bCSW_Status != COMMAND_PASSED) {
return 0xff;
}
dCSWDataResidue = CSWB.dCSW_DataResidue_0+
CSWB.dCSW_DataResidue_1*0x100+
CSWB.dCSW_DataResidue_2*0x10000+
CSWB.dCSW_DataResidue_3*0x1000000;
dCBW_DataXferLen = CBW_ptr->dCBW_DataXferLen_0+
CBW_ptr->dCBW_DataXferLen_1*0x100+
CBW_ptr->dCBW_DataXferLen_2*0x10000+
CBW_ptr->dCBW_DataXferLen_3*0x1000000;
if(dCSWDataResidue > dCBW_DataXferLen) {
return 0xff;
}
return 0;
}
//******************************************************************************************
//函数名称:GetThisInquiryData
//输入参数:hMedLUNPtr,逻辑单元描述符指针
// DataBuff_ptr,查询数据存放的结构指针
//输出参数:COMMAND_PASSED,命令完成
// COMMAND_FAILED,命令失败
// PHASE_ERROR,相位出错
// PERSISTENT_FAILURE,严重出错
//功能描述:查询媒介信息,如厂商信息、产品信息及产品版本号。
//******************************************************************************************
INT8U Get_ThisInquiryData(hMedLUN * medium_ptr )
{
INT8U InquiryDataBuf[36];
INQUIRY_COMMAND *inquiry_ptr;
COMMAND_BLOCK_WRAPPER *CBW_ptr;
INQUIRY_COMMAND *CBWCB_ptr;
INT16U err;
if (medium_ptr->MSC == NULL) {
return PERSISTENT_FAILURE;
}
CBW_ptr = (COMMAND_BLOCK_WRAPPER *)(medium_ptr->MSC->CBW_Buff);
CBW_ptr->dCBW_Tag++;
CBW_ptr->dCBW_DataXferLen_0 = 36;
CBW_ptr->dCBW_DataXferLen_1 = 0;
CBW_ptr->dCBW_DataXferLen_2 = 0;
CBW_ptr->dCBW_DataXferLen_3 = 0;
CBW_ptr->bCBW_Flag = CBW_IN_DATA;
CBW_ptr->bCBW_LUN = medium_ptr->LUN;
CBW_ptr->bCBW_CDBLength = 12;
CBWCB_ptr = (INQUIRY_COMMAND *)CBW_ptr->CBWCB;
memset((INT8U *)CBWCB_ptr, 0x00, 16);
CBWCB_ptr->OperationCode = UFI_INQUIRY;
CBWCB_ptr->AllocationLength = 0x24;
USB_Delay(200);
err = Bulk_Transfer(DirectionPID_OUT, (INT8U *)CBW_ptr, 31, medium_ptr->MSC->dvi_ptr);
if(err) {
goto FAILURE;
}
USB_Delay(50);
err = Bulk_Transfer(DirectionPID_IN, InquiryDataBuf, 36, medium_ptr->MSC->dvi_ptr);
if(err) {
goto FAILURE;
}
err = Get_CSWStatus(medium_ptr);
if (err) {
goto FAILURE;
}
memcpy(medium_ptr->VendorInfo, &InquiryDataBuf[8], 8);
memcpy(medium_ptr->ProductInfo, &InquiryDataBuf[16], 16);
memcpy(medium_ptr->ProductRev, &InquiryDataBuf[32], 4);
return COMMAND_PASSED;
FAILURE:
memset(medium_ptr->VendorInfo,0,8) ;
memset(medium_ptr->ProductInfo,0,16) ;
memset(medium_ptr->ProductRev,0,4) ;
return COMMAND_FAILED;
}
//*****************************************************************************
//功能描述:GetThisMediumCapacity
//输入参数:hMedLUNPtr
//输出参数:COMMAND_PASSED,命令完成
// COMMAND_FAILED,命令失败
// PHASE_ERROR,相位出错
// PERSISTENT_FAILURE,严重出错
//功能描述:获取媒介的容量,块字节数及最后块地址.
//****************************************************************************
INT8U Get_ThisMediumCapacity(hMedLUN * medium_ptr)
{
INT8U CapacityDataBuf[8];
INQUIRY_COMMAND *inquiry_ptr;
COMMAND_BLOCK_WRAPPER *CBW_ptr;
READ_CAPACITY *CBWCB_ptr;
INT16U err;
if (medium_ptr->MSC == NULL) {
return PERSISTENT_FAILURE;
}
CBW_ptr = (COMMAND_BLOCK_WRAPPER *)(medium_ptr->MSC->CBW_Buff);
CBW_ptr->dCBW_Tag++;
CBW_ptr->dCBW_DataXferLen_0 = 8;
CBW_ptr->dCBW_DataXferLen_1 = 0;
CBW_ptr->dCBW_DataXferLen_2 = 0;
CBW_ptr->dCBW_DataXferLen_3 = 0;
CBW_ptr->bCBW_Flag = CBW_IN_DATA;
CBW_ptr->bCBW_LUN = medium_ptr->LUN;
CBW_ptr->bCBW_CDBLength = 10;
CBWCB_ptr = (READ_CAPACITY *)CBW_ptr->CBWCB;
memset((INT8U *)CBWCB_ptr, 0x00, 16);
CBWCB_ptr->OperationCode = UFI_READCAPACITY;
err = Bulk_Transfer(DirectionPID_OUT, (INT8U *)CBW_ptr, 31, medium_ptr->MSC->dvi_ptr);
if(err) {
goto FAILURE;
}
USB_Delay(10);
err = Bulk_Transfer(DirectionPID_IN, CapacityDataBuf, 8, medium_ptr->MSC->dvi_ptr);
if(err) {
goto FAILURE;
}
err = Get_CSWStatus(medium_ptr);
if (err) {
goto FAILURE;
}
medium_ptr->BlockLengthInBytes // 媒介块长度(字节数)
= CapacityDataBuf[7] +
CapacityDataBuf[6]*0x100 +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -