📄 mass.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: MASS.c
** Last modified Date: 2005-04-22
** Last Version: V1.0
** Description:
**
**------------------------------------------------------------------------------------------------------
** Created By: Lishan Zhou
** Created date: 2005-04-22
** Version: V1.0
** Description:
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:2005-05-04
** Version:
** Description:
**
********************************************************************************************************/
#include "HostStack.h"
MassStorageClass *create_mass_class_instance( device_instance *dvi_ptr );
void dispose_mass_class_instance( device_instance *dvi_ptr );
unsigned char MassStorageReset(device_instance * DevicePtr);
unsigned char GetMaxLUN(device_instance * DevicePtr);
unsigned char GetThisInquiryData(hMedLUN * hMedLUNPtr);
unsigned char GetThisMediumCapacity(hMedLUN * hMedLUNPtr);
unsigned char GetRequestSense(hMedLUN * hMedLUNPtr, SENSE_DATA *SenseDataPtr);
hMedLUN *GetMassBulkOnlyInfo(MassStorageClass *mass_i_ptr);
hMedLUN *GetMassCBIOnlyInfo(MassStorageClass *mass_i_ptr);
unsigned short mass_init_commands( device_instance *dvi_ptr )
{ MassStorageClass *mass_i_ptr;
mass_i_ptr= create_mass_class_instance( dvi_ptr );
if ( NULL == mass_i_ptr )
return (1);
dvi_ptr->class_instance_ptr = mass_i_ptr;
return ( 0 );
}
MassStorageClass MSCDevices[MAX_MASS_DEVICES_DEFINE];
void ini_mass_device_mem(void)
{
uint16 i;
for( i=0; i<MAX_MASS_DEVICES_DEFINE ;i++)
MSCDevices[i].dvi_ptr = NULL;
}
MassStorageClass *malloc_mass_device_mem(void)
{
uint16 i;
for( i=0; i<MAX_MASS_DEVICES_DEFINE ;i++)
if(MSCDevices[i].dvi_ptr==NULL)
{
MSCDevices[i].dvi_ptr = (device_instance *)(-1);
return &MSCDevices[i];
}
return NULL;
}
void free_mass_device_mem(MassStorageClass * MSC_ptr)
{
uint16 i;
for( i=0; i<MAX_MASS_DEVICES_DEFINE ;i++)
if( &MSCDevices[i] == MSC_ptr )
MSC_ptr->dvi_ptr = NULL;
}
hMedLUN MSCDeviceLNUs[MAX_MASS_DEVICES_LUN_DEFINE];
void ini_mass_device_LUN_mem(void)
{
uint16 i;
for( i=0; i<MAX_MASS_DEVICES_LUN_DEFINE ;i++)
MSCDeviceLNUs[i].MSC = NULL;
}
hMedLUN *malloc_mass_device_LUN_mem(void)
{
uint16 i;
for( i=0; i<MAX_MASS_DEVICES_LUN_DEFINE ;i++)
if(MSCDeviceLNUs[i].MSC==NULL)
{
MSCDeviceLNUs[i].MSC = (MassStorageClass *)(-1);
return &MSCDeviceLNUs[i];
}
return NULL;
}
void free_mass_device_LNU_mem(hMedLUN * MSCLUN_ptr)
{
uint16 i;
for( i=0; i<MAX_MASS_DEVICES_LUN_DEFINE ;i++)
if( &MSCDeviceLNUs[i] == MSCLUN_ptr)
MSCLUN_ptr->MSC = NULL;
}
MassStorageClass *create_mass_class_instance( device_instance *dvi_ptr )
{
MassStorageClass *mass_i_ptr;
endpoint_info *epi_ptr;
transfer_instance *tr_instance_ptr;
if ( NULL == (mass_i_ptr = malloc_mass_device_mem()) )
return NULL ;
mass_i_ptr->LUN = 0 ;
mass_i_ptr->dvi_ptr = dvi_ptr;
mass_i_ptr->setup_epi_ptr = dvi_ptr->epi_ptr[0];
mass_i_ptr->ProtocolCode = Get_bInterfaceProtocol(dvi_ptr);
mass_i_ptr->SubclassCode = Get_bInterfaceSubClass(dvi_ptr);
mass_i_ptr->tr_bulk_in_ptr = NULL ;
mass_i_ptr->tr_bulk_out_ptr = NULL ;
mass_i_ptr->tr_int_in_ptr = NULL ;
mass_i_ptr->CBW_BuffPtr = NULL ;
epi_ptr = find_endport_type(dvi_ptr, Ep_TransferType_Bulk, Ep_Direction_IN_ENDPOINT, 1);
if( epi_ptr == NULL )
return NULL ;
if(NO_OPEN_ATL_TRANSFER==(tr_instance_ptr=atl_open_transfer_instance( epi_ptr )))
return NULL ;
mass_i_ptr->tr_bulk_in_ptr = tr_instance_ptr;
epi_ptr = find_endport_type(dvi_ptr, Ep_TransferType_Bulk, Ep_Direction_OUT_ENDPOINT, 1);
if( epi_ptr == NULL )
return NULL ;
if(NO_OPEN_ATL_TRANSFER==(tr_instance_ptr=atl_open_transfer_instance( epi_ptr )))
return NULL ;
mass_i_ptr->tr_bulk_out_ptr = tr_instance_ptr;
if(mass_i_ptr->ProtocolCode == 0x50)
{
if(GetMassBulkOnlyInfo(mass_i_ptr) == NULL)
return NULL;
}
else
{
if(GetMassCBIOnlyInfo(mass_i_ptr) == NULL)
return NULL;
}
return ( mass_i_ptr );
}
hMedLUN *GetMassBulkOnlyInfo(MassStorageClass *mass_i_ptr)
{
unsigned char MediumIndex;
hMedLUN *medium_infor_ptr;
mass_i_ptr->CBW_BuffPtr = malloc( sizeof( unsigned char )* 31 );
if(mass_i_ptr->CBW_BuffPtr ==NULL)
return NULL ;
mass_i_ptr->CBW_BuffPtr[0] = 0x55;
mass_i_ptr->CBW_BuffPtr[1] = 0x53;
mass_i_ptr->CBW_BuffPtr[2] = 0x42;
mass_i_ptr->CBW_BuffPtr[3] = 0x43;
mass_i_ptr->LUN = GetMaxLUN(mass_i_ptr->dvi_ptr);
if(mass_i_ptr->LUN>MAX_MASS_LUN-1)
mass_i_ptr->LUN = MAX_MASS_LUN-1;
for(MediumIndex = 0;mass_i_ptr->LUN +1>MediumIndex;MediumIndex++)
{
if ( NULL == (medium_infor_ptr= malloc_mass_device_LUN_mem()) )
break ;
mass_i_ptr->LUN_infor_ptr[MediumIndex] = medium_infor_ptr;
medium_infor_ptr->LUN = MediumIndex;
medium_infor_ptr->MSC = mass_i_ptr ;
medium_infor_ptr->BlockLengthInBytes = 0;
medium_infor_ptr->LastLogicalBlookAddress=0;
if( GetThisInquiryData( medium_infor_ptr ) )
return NULL ;
}
return medium_infor_ptr;
}
hMedLUN *GetMassCBIOnlyInfo(MassStorageClass *mass_i_ptr)
{
hMedLUN *medium_infor_ptr;
endpoint_info *epi_ptr;
transfer_instance *tr_instance_ptr;
if( NULL == (epi_ptr = find_endport_type(mass_i_ptr->dvi_ptr, Ep_TransferType_Interrupt, Ep_Direction_IN_ENDPOINT, 1)))
return NULL ;
if(NO_OPEN_ATL_TRANSFER==(tr_instance_ptr=atl_open_transfer_instance( epi_ptr )))
return NULL ;
mass_i_ptr->tr_int_in_ptr = tr_instance_ptr;
if ( NULL == (medium_infor_ptr = malloc_mass_device_LUN_mem()) )
return NULL ;
mass_i_ptr->LUN_infor_ptr[0] = medium_infor_ptr;
medium_infor_ptr->LUN = 0;
medium_infor_ptr->MSC = mass_i_ptr ;
medium_infor_ptr->BlockLengthInBytes = 0;
medium_infor_ptr->LastLogicalBlookAddress=0;
if(GetThisInquiryData(medium_infor_ptr) )
return NULL ;
return medium_infor_ptr;
}
void dispose_mass_class_instance( device_instance *dvi_ptr )
{
MassStorageClass *mass_i_ptr;
unsigned short i;
mass_i_ptr = (MassStorageClass *)mass_instance_ptr( dvi_ptr );
if(mass_i_ptr==NULL)
return;
if(mass_i_ptr->tr_bulk_in_ptr)
atl_close_transfer_instance(mass_i_ptr->tr_bulk_in_ptr);
if(mass_i_ptr->tr_bulk_out_ptr)
atl_close_transfer_instance(mass_i_ptr->tr_bulk_out_ptr);
if(mass_i_ptr->tr_int_in_ptr)
atl_close_transfer_instance(mass_i_ptr->tr_int_in_ptr);
if(mass_i_ptr->CBW_BuffPtr)
free(mass_i_ptr->CBW_BuffPtr);
for(i=0;i <= mass_i_ptr->LUN+1; i++)
if(mass_i_ptr->LUN_infor_ptr[i])
{
free_mass_device_LNU_mem(mass_i_ptr->LUN_infor_ptr[i]);
mass_i_ptr->LUN_infor_ptr[i] = NULL;
}
if( dvi_ptr->class_instance_ptr )
free_mass_device_mem(dvi_ptr->class_instance_ptr);
dvi_ptr->class_instance_ptr = NULL;
}
unsigned short mass_dispose_process( device_instance *dvi_ptr )
{
dispose_mass_class_instance(dvi_ptr);
return ( 0 );
}
hMedLUN * Creat_Medium(device_instance *dvi_ptr ,unsigned char LUNIndex)
{
hMedLUN * hMedLUNPtr=0;
MassStorageClass *MSC_ptr;
unsigned char i,Statue;
SENSE_DATA SenseData;
MSC_ptr = mass_instance_ptr(dvi_ptr);
if(MSC_ptr ==NULL)
return NULL;
if(MSC_ptr->LUN < LUNIndex)
return NULL;
if( (MSC_ptr->LUN_infor_ptr[LUNIndex]->LastLogicalBlookAddress==0)
&& ( MSC_ptr->LUN_infor_ptr[LUNIndex]->BlockLengthInBytes==0))
{
hMedLUNPtr = MSC_ptr->LUN_infor_ptr[LUNIndex];
for( i=0; i<3; i++ )
{
Statue = GetThisMediumCapacity(hMedLUNPtr);
if(Statue)
{
if(Statue== COMMAND_FAILED)
{ if(GetRequestSense(hMedLUNPtr, &SenseData))
return NULL;
else
{
if((SenseData.ASC==0x34)&&(SenseData.ASCQ==0x00))
{
}
if((SenseData.ASC==0x28)&&(SenseData.ASCQ==0x00))
{
}
}
}
else
return NULL;
}
else
return hMedLUNPtr;
}
}
return NULL;
}
void Close_Medium(hMedLUN *hMedLUNPtr,unsigned char LUNIndex)
{
if(hMedLUNPtr==NULL)
return;
if(hMedLUNPtr->MSC ==NULL)
return ;
if(hMedLUNPtr->MSC->LUN < LUNIndex)
return ;
hMedLUNPtr->MSC->LUN_infor_ptr[LUNIndex]->LastLogicalBlookAddress =0;
hMedLUNPtr->MSC->LUN_infor_ptr[LUNIndex]->BlockLengthInBytes=0;
}
uint8 CommandBlockHandle(TR_With_RBC *tr_with_rbc_ptr)
{
uint8 Statue;
if( 0x50 == tr_with_rbc_ptr->MSC->ProtocolCode)
{
Statue = BulkOnlyComHandle( tr_with_rbc_ptr);
}
else
{
Statue = CBIOnlyComHandle( tr_with_rbc_ptr);
}
return Statue;
}
unsigned char GetThisInquiryData(hMedLUN * hMedLUNPtr )
{
TR_With_RBC tr_with_rbc;
unsigned char InquiryDataBuf[36];
unsigned char Status;
if(hMedLUNPtr->MSC==NULL)
return PERSISTENT_FAILURE;
MCom_INQUIRY(hMedLUNPtr->MSC->RBC_BuffPtr);
tr_with_rbc.MSC = hMedLUNPtr->MSC;
tr_with_rbc.LUN = hMedLUNPtr->LUN;
tr_with_rbc.CBLength = (hMedLUNPtr->MSC->ProtocolCode==0x50)? 6:12;
tr_with_rbc.DataTransferLength = 36;
tr_with_rbc.Data_BuffPtr = InquiryDataBuf;
tr_with_rbc.RBC_BuffPtr = hMedLUNPtr->MSC->RBC_BuffPtr;
tr_with_rbc.TrDirection = IN_DATA;
Status = CommandBlockHandle( &tr_with_rbc );
if( Status == COMMAND_PASSED)
{
memcpy(hMedLUNPtr->VendorInfo, &InquiryDataBuf[8], 8);
memcpy(hMedLUNPtr->ProductInfo, &InquiryDataBuf[16], 16);
memcpy(hMedLUNPtr->ProductRev, &InquiryDataBuf[32], 4);
}
else
{ memset(hMedLUNPtr->VendorInfo,0,8) ;
memset(hMedLUNPtr->ProductInfo,0,8) ;
memset(hMedLUNPtr->ProductRev,0,8) ;
}
return Status;
}
unsigned char GetThisMediumCapacity(hMedLUN * hMedLUNPtr )
{
TR_With_RBC tr_with_rbc;
unsigned char CapacityDataBuf[8];
unsigned char Status;
if(hMedLUNPtr->MSC==NULL)
return PERSISTENT_FAILURE;
MCom_ReadCapacity(hMedLUNPtr->MSC->RBC_BuffPtr);
tr_with_rbc.MSC = hMedLUNPtr->MSC;
tr_with_rbc.LUN = hMedLUNPtr->LUN;
tr_with_rbc.CBLength = (hMedLUNPtr->MSC->ProtocolCode==0x50)? 10:12;
tr_with_rbc.DataTransferLength = 0x08;
tr_with_rbc.Data_BuffPtr = CapacityDataBuf;
tr_with_rbc.RBC_BuffPtr = hMedLUNPtr->MSC->RBC_BuffPtr;
tr_with_rbc.TrDirection = IN_DATA;
Status = CommandBlockHandle( &tr_with_rbc );
if( Status == COMMAND_PASSED)
{
hMedLUNPtr->BlockLengthInBytes
= CapacityDataBuf[7] +
CapacityDataBuf[6]*0x100 +
CapacityDataBuf[5]*0x10000+
CapacityDataBuf[4]*0x1000000;
hMedLUNPtr->LastLogicalBlookAddress
= CapacityDataBuf[3] +
CapacityDataBuf[2]*0x100 +
CapacityDataBuf[1]*0x10000+
CapacityDataBuf[0]*0x1000000;
}
else
{
hMedLUNPtr->BlockLengthInBytes = 0;
hMedLUNPtr->LastLogicalBlookAddress =0;
}
return Status;
}
unsigned char GetRequestSense(hMedLUN * hMedLUNPtr, SENSE_DATA *SenseDataPtr)
{
TR_With_RBC tr_with_rbc;
unsigned char SenseDataBuf[18];
unsigned char Status;
if(hMedLUNPtr->MSC==NULL)
return PERSISTENT_FAILURE;
MCom_RequestSense(hMedLUNPtr->MSC->RBC_BuffPtr);
tr_with_rbc.MSC = hMedLUNPtr->MSC;
tr_with_rbc.LUN = hMedLUNPtr->LUN;
tr_with_rbc.CBLength = (hMedLUNPtr->MSC->ProtocolCode==0x50)? 0x0c:12;
tr_with_rbc.DataTransferLength = 0x12;
tr_with_rbc.Data_BuffPtr = SenseDataBuf;
tr_with_rbc.RBC_BuffPtr = hMedLUNPtr->MSC->RBC_BuffPtr;
tr_with_rbc.TrDirection = IN_DATA;
Status = CommandBlockHandle( &tr_with_rbc );
if( Status == COMMAND_PASSED)
{
SenseDataPtr->SenseKey = SenseDataBuf[2]&0x0f;
SenseDataPtr->ASC = SenseDataBuf[12];
SenseDataPtr->ASCQ = SenseDataBuf[13];
}
return Status;
}
unsigned short ReadBlockData(hMedLUN *MediumPtr,
unsigned char *BufferPtr,
unsigned int LBA,
unsigned short TrBLength)
{
TR_With_RBC tr_with_rbc;
unsigned char Status;
SENSE_DATA SenseData;
if(MediumPtr->MSC==NULL)
return 0;
if( (MediumPtr->BlockLengthInBytes==0x00)||
(MediumPtr->LastLogicalBlookAddress == 0x00) )
return (0);
MCom_Read10(MediumPtr->MSC->RBC_BuffPtr, LBA, TrBLength);
tr_with_rbc.MSC = MediumPtr->MSC;
tr_with_rbc.LUN = MediumPtr->LUN;
tr_with_rbc.CBLength = (MediumPtr->MSC->ProtocolCode==0x50)? 0x0A:12;
tr_with_rbc.DataTransferLength = TrBLength * MediumPtr->BlockLengthInBytes;
tr_with_rbc.Data_BuffPtr = BufferPtr;
tr_with_rbc.RBC_BuffPtr = MediumPtr->MSC->RBC_BuffPtr;
tr_with_rbc.TrDirection = IN_DATA;
Status = CommandBlockHandle( &tr_with_rbc );
if( Status == COMMAND_PASSED)
{
return tr_with_rbc.DataTransferLength;
}
else
{
if(GetRequestSense(MediumPtr, &SenseData))
return NULL;
else
{
if((SenseData.ASC==0x3a)&&(SenseData.ASCQ==0x00))
{
MediumPtr->BlockLengthInBytes = NULL;
MediumPtr->LastLogicalBlookAddress = NULL;
}
}
}
return (0);
}
unsigned short WriteBlockData(hMedLUN *MediumPtr,
unsigned char *BufferPtr,
unsigned int LBA,
unsigned short TrBLength)
{
TR_With_RBC tr_with_rbc;
unsigned char Status;
SENSE_DATA SenseData;
if(MediumPtr->MSC==NULL)
return (0);
if( (MediumPtr->BlockLengthInBytes==0x00)||
(MediumPtr->LastLogicalBlookAddress == 0x00) )
return (0);
MCom_Write10(MediumPtr->MSC->RBC_BuffPtr, LBA, TrBLength);
tr_with_rbc.MSC = MediumPtr->MSC;
tr_with_rbc.LUN = MediumPtr->LUN;
tr_with_rbc.CBLength = (MediumPtr->MSC->ProtocolCode==0x50)? 0x0A:12;
tr_with_rbc.DataTransferLength = TrBLength * MediumPtr->BlockLengthInBytes;
tr_with_rbc.Data_BuffPtr = BufferPtr;
tr_with_rbc.RBC_BuffPtr = MediumPtr->MSC->RBC_BuffPtr;
tr_with_rbc.TrDirection = OUT_DATA;
Status = CommandBlockHandle( &tr_with_rbc );
if( Status == COMMAND_PASSED)
{
return tr_with_rbc.DataTransferLength;
}
else
{
if(GetRequestSense(MediumPtr, &SenseData))
return NULL;
else
{
if((SenseData.ASC==0x3a)&&(SenseData.ASCQ==0x00))
{
MediumPtr->BlockLengthInBytes = NULL;
MediumPtr->LastLogicalBlookAddress = NULL;
}
}
}
return (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -