?? 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 + -