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

📄 mass.c

📁 ARM读写U盘驱动软件包源程序
💻 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 + -