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

📄 storage.c

📁 使用ISP1362芯片的USB_OTG参考设计源代码比较新的版本
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
**  WASABI-Hot! version 1.2c   
**
**
**      -- copyright (c) 2001-2004 by Philips Japan, Ltd. -- All rights reserved --
**
**
**      ** This code has been made to check/learn                          ** 
**      **                             the ISP1362/ISP1363 functionalities **
**      ** Release 06-Aug-2004                                             **
**
**      OKANO, Akifumi
**      
**		Application Laboratory, Mobile and Connectivity
**      Semiconductors Div, Philips Japan Ltd.
**      akifumi.okano@philips.com
**      +81-3-3740-4668
*/


/****************************************************************************/
/*	includes																*/
/****************************************************************************/

#include		<alloc.h>

#include		"_hc_core/atl_mix.h"
#include		"_hc_core/chap9.h"
#include		"_hc_core/dev_ep.h"
#include		"_hc_core/transfer.h"

#include		"_hc_cls/cls_hndl.h"

#include		"class_dr/storage/storage.h"
#include		"class_dr/storage/fs.h"

#include		"ui.h"
#include		"general.h"


/****************************************************************************/
/*	constants																*/
/****************************************************************************/

//#define		NO_DRIVE						0
#define		IDLE							1
#define		WAIT_FOR_CARD					2
#define		MOUNT_PROCEED					3
#define		MOUNTED							4
#define		UNMOUNT_PROCEED					5
#define		WAIT_STABILIZED					7
#define		WAIT_FOR_CARD_START				8

#define		STORAGE_CARD_WAIT_POLLING_INTERVAL			1000
#define		STORAGE_MOUNT_MONITOR_POLLING_INTERVAL		1000


/****************************************************************************/
/*	global vars																*/
/****************************************************************************/

device_instance 	*g_storage_device_ptr		= NULL;
unsigned long		g_payload_size;

unsigned long		g_cc_logger[ 16 ]	= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

/****************************************************************************/
/*	function prototypes														*/
/****************************************************************************/


static void					strg_maintenance_routine_entry( void );
static void					strg_maintenance_routine( device_instance *dvi_ptr );
static unsigned char		check_the_card_exist( void );

static unsigned char		strg_command( unsigned char command_index, unsigned char *buffer_ptr, unsigned long logical_block_address, unsigned short allocation_length );
static unsigned char		bulk_only_transfer( st_command_block_wrapper *cbw_ptr, unsigned char *buffer_ptr, unsigned short allocation_length, unsigned char direction );
static void					un_stall( unsigned char direction );
static void					reset_recovery( void );
static unsigned char		ctrl_tr(  unsigned char *buffer_ptr, device_instance *dvi_ptr, unsigned short req, unsigned short length );

static unsigned char		strg_bulk_transfer( device_instance *dvi_ptr, unsigned char *buffer_ptr, unsigned short length, unsigned char direction );
static unsigned char		strg_bulk_transfer_once( device_instance *dvi_ptr, unsigned char *buffer_ptr, unsigned short length, unsigned char direction );
static transfer_instance	*start_strg_bulk_transfer( device_instance *dvi_ptr );
static void					end_strg_bulk_transfer( endpoint_info_ptr eip );

static unsigned char		strg_bulk_transfer_pp_once( device_instance *dvi_ptr, unsigned char *buffer_ptr, unsigned short length, unsigned char direction );
static						transfer_instance *start_strg_bulk_transfer_pp( device_instance *dvi_ptr, unsigned char buffer_switch );
static void					end_strg_bulk_transfer_pp( endpoint_info_ptr eip );


static void					storage_data_dump( char *s, unsigned char *b, unsigned short n );

void						strg_status_monitor( unsigned char dummy_for_compatibility );


/****************************************************************************/
/*	function definitions													*/
/****************************************************************************/

/*
==============================================================================
==============================================================================
====	Public functions for storage drive
====		Functions for APPLICATION side
==============================================================================
==============================================================================
*/


device_instance *storage_device_ready( void )
{
	return ( g_storage_device_ptr );
}


volume_param *storage_volume_ready( void )
{
	if ( storage_device_ready() )
		return ( (((storage_instance *)(g_storage_device_ptr->class_instance_ptr))->volume_instance)[ 0 ] );
	else
		return ( NULL );
}


unsigned char storage_device_address( void )
{
	if ( NULL == g_storage_device_ptr )
		return ( 0xFF );
	
	return ( g_storage_device_ptr->address );
}


unsigned char storage_mount( void )
{
	device_instance		*dvi_ptr;
	storage_instance	*si_ptr;

	if ( NULL == (dvi_ptr	= g_storage_device_ptr) )
		return ( error );
		
	si_ptr		= (storage_instance *)(dvi_ptr->class_instance_ptr);

	if (si_ptr->state == WAIT_FOR_CARD)
		return ( no_error );
	if (si_ptr->state != IDLE)
		return ( error );

	si_ptr->state	= WAIT_FOR_CARD;

	return ( no_error );
}


unsigned char storage_unmount( void )
{
	unsigned char	err;
	
	err		= storage_remount( True );
	
	return ( err );
}


unsigned char storage_remount( unsigned char remount )
{
	device_instance		*dvi_ptr;
	storage_instance	*si_ptr;
	
	if ( NULL == (dvi_ptr	= g_storage_device_ptr) )
		return ( error );
		
	si_ptr		= (storage_instance *)(dvi_ptr->class_instance_ptr);

	if (si_ptr->state != MOUNTED)
		return ( error );

	si_ptr->state	= UNMOUNT_PROCEED;
	si_ptr->remount	= remount;
	
	return ( no_error );
}


unsigned short storage_read_sector( unsigned char *buffer_ptr, unsigned long logical_block_address, unsigned short num_of_sector )
{
	if ( strg_command( ST_READ, buffer_ptr, logical_block_address, num_of_sector ) )
		return ( 0 );
	else
		return ( num_of_sector );
}


unsigned short storage_write_sector( unsigned char *buffer_ptr, unsigned long logical_block_address, unsigned short num_of_sector )
{
	if ( strg_command( ST_WRITE, buffer_ptr, logical_block_address, num_of_sector ) )
		return ( 0 );
	else
		return ( num_of_sector );
}


extern volume_param	g_volume_parameter;

void storage_info( void )
{
	volume_param	*vpp;
	vpp		= &g_volume_parameter;
	
	mprintf( LIGHTGRAY, CONTINUE, "\r\n  Volume parameters (file system = %s)\r\n",	(vpp->file_system) ? "FAT12" : "FAT16" );

	mprintf( LIGHTGRAY, CONTINUE, "    bytes/sector      = %8u bytes",		vpp->bytes_per_sector );
		mprintf( LIGHTGRAY, CONTINUE, "    reserved sectors        = %8u\r\n",		vpp->reserved_sectors );
	mprintf( LIGHTGRAY, CONTINUE, "    sector/cluster    = %8u sectors",		vpp->sector_per_cluster );
		mprintf( LIGHTGRAY, CONTINUE, "  number of FATs          = %8u\r\n",		vpp->number_of_FATs );
	mprintf( LIGHTGRAY, CONTINUE, "    bytes/cluster     = %8u bytes",	vpp->bytes_per_cluster );
		mprintf( LIGHTGRAY, CONTINUE, "    root directory entries  = %8u\r\n",	vpp->root_directory_entries );
	mprintf( LIGHTGRAY, CONTINUE, "    total sectors     = %8lu sectors",		vpp->total_sectors );
		mprintf( LIGHTGRAY, CONTINUE, "  number of FAT sectors   = %8u\r\n",		vpp->number_of_FAT_sectors );


	mprintf( LIGHTGRAY, CONTINUE, "    start_sector_FAT1                = 0x%04X\r\n", vpp->start_sector_FAT1 );
	mprintf( LIGHTGRAY, CONTINUE, "    start_sector_FAT2                = 0x%04X\r\n", vpp->start_sector_FAT2 );
	mprintf( LIGHTGRAY, CONTINUE, "    start_sector_root_directory      = 0x%04X\r\n", vpp->start_sector_root_directory );
	mprintf( LIGHTGRAY, CONTINUE, "    start_sector_claster_region      = 0x%04X\r\n", vpp->start_sector_claster_region );
}


#include		<stdio.h>
#define			DUMP_INFO_DATA_SIZE		512

void storage_dump_info( unsigned long start_sec, unsigned long length )
{
	FILE			*fp;
	unsigned long	i;
	unsigned short	j;
	volume_param	*vpp;
	
	mprintf( LIGHTGRAY, CONTINUE, "\r\nvolume dump..." );
	
	if ( NULL == (fp	= fopen( "storage.txt", "w" )) )
	{
		mprintf( LIGHTGRAY, CONTINUE, "file open error\r\n" );
		return;
	}
	
	vpp		= &g_volume_parameter;

	fprintf( fp, "bytes_per_sector        = 0x%04X\n",		vpp->bytes_per_sector );
	fprintf( fp, "sector_per_cluster      = 0x%02X\n",		vpp->sector_per_cluster );
	fprintf( fp, "reserved_sectors        = 0x%02X\n",		vpp->reserved_sectors );
	fprintf( fp, "number_of_FATs          = 0x%02X\n",		vpp->number_of_FATs );
	fprintf( fp, "root_directory_entries  = 0x%04X (%d entries)\n",	    vpp->root_directory_entries, vpp->root_directory_entries );
	fprintf( fp, "number_of_FAT_sectors   = 0x%04X\n",		vpp->number_of_FAT_sectors );

	
	fprintf( fp, "start_sector_FAT1                = 0x%04X\n", vpp->start_sector_FAT1 );
	fprintf( fp, "start_sector_FAT2                = 0x%04X\n", vpp->start_sector_FAT2 );
	fprintf( fp, "start_sector_root_directory      = 0x%04X\n", vpp->start_sector_root_directory );
	fprintf( fp, "start_sector_claster_region      = 0x%04X\n\n\n", vpp->start_sector_claster_region );
				
	for ( i = start_sec; i < start_sec + length; i++ )
	{
		unsigned char	data[ DUMP_INFO_DATA_SIZE ];
		strg_command( ST_READ, data, i, 1 );
		
		{
			
			fprintf(fp, "dump:lba=%lu (0x%04lX)", i, i );

			for ( j = 0; j < DUMP_INFO_DATA_SIZE; j++ )
			{
				if ( !(j % 16) )
					fprintf( fp, "\n%04d(0x%04X) : ", j, j );
			
				fprintf( fp, " %02X", *(data + j) );
			}

			fprintf( fp, "\n" );
		}
	}
	
	fclose( fp );
	
	mprintf( LIGHTGRAY, CONTINUE, "done\r\n" );
}




/*
==============================================================================
==============================================================================
====	Public functions for storage drive
====		Functions for HOST CONTROLLER side
==============================================================================
==============================================================================
*/


/*********															*********/
/*																			*/
/*	Device class handling functions											*/
/*																			*/
/*		This functions is called from functions in cls_hndl.c as callback	*/
/*		functions. 															*/
/*		All these functions are needed to be installed by 					*/
/*		"clshndl_initialization_method_install()"	in "cls_hndl.c".			*/
/*																			*/
/*		These functions will be called at storage device attach/detach		*/
/*		events. 															*/
/*																			*/
/*********															*********/


unsigned short storage_init_commands( device_instance *dvi_ptr )
{
	storage_instance		*si_ptr;
	endpoint_info_ptr		eip;
	unsigned char			buffer;
	unsigned short			err;
	unsigned char			i;
	
	if ( devep_regist_config_descriptors( dvi_ptr, 1, 0 ) )
	{
		mprintf( RED, CONTINUE, "error : storage_init_commands\r\n" );
		return ( error );	//	to dispose device
	}
	

	if ( g_storage_device_ptr )
	{
		mprintf( RED, CONTINUE, "error : No multiple storage device supprt\r\n" );
		return ( error );	//	to dispose device
	}
	
	//	Check descriptor
	
	if ( 0x06 != (dvi_ptr->interfacef_descriptor).bInterfaceSubClass )
	{
		mprintf( RED, CONTINUE, "error : This is not compatible to SCSI command set. bInterfaceSubClass=0x%02X\r\n", (dvi_ptr->interfacef_descriptor).bInterfaceSubClass );
		return ( error );	//	to dispose device
	}
	
	if ( 0x50 != (dvi_ptr->interfacef_descriptor).bInterfaceProtocol )
	{
		mprintf( RED, CONTINUE, "error : This does not support bulk-only transport. bInterfaceProtocol=0x%02X\r\n", (dvi_ptr->interfacef_descriptor).bInterfaceSubClass );
		return ( error );	//	to dispose device
	}
	
	/*
	**	Make a storage instance for storage device
	*/

	if ( NULL == (si_ptr		= (storage_instance *)malloc( sizeof( storage_instance ) )) )
		mprintf( LIGHTRED, CONTINUE, "error @ storage_init_commands : making storage class instance.\r\n" );
		
	dvi_ptr->class_instance_ptr		= si_ptr;



	/*********
	 Is this RESET command needed?
	 *********/	
	ctrl_tr( &buffer, dvi_ptr, storage_cls_sp_request_BulkOnlyMassStorageReset, 0 );
	
	err		= ctrl_tr( &buffer, dvi_ptr, storage_cls_sp_request_GetMaxLUN, 1 );

	if ( (err & 0x00FF) == 0x4 )
		si_ptr->max_LUN		= 0;
	else
		si_ptr->max_LUN		= buffer;
	
	si_ptr->target_LUN	= 0;

	//	Find first 2 (IN and OUT) endpoints for main communication
	
	for ( i = 0; i < MAX_ENDPOINT_NUM; i++ )
	{
		if ( NULL == ( eip		= (dvi_ptr->epi_ptr)[ EpOUT ][ i ] ) )
			continue;
	
		if ( eip->transfer_type == Ep_TransferType_Bulk )
		{
			si_ptr->endpoint_OUT	= eip;
			si_ptr->ep_out			= i;
			break;
		}
	}
	
	for ( i = 0; i < MAX_ENDPOINT_NUM; i++ )
	{
		if ( NULL == ( eip		= (dvi_ptr->epi_ptr)[ EpIN  ][ i ] ) )
			continue;
	
		if ( eip->transfer_type == Ep_TransferType_Bulk )
		{
			si_ptr->endpoint_IN		= eip;
			si_ptr->ep_in			= i | 0x80;
			break;
		}
	}
	
	si_ptr->volume_instance[ 0 ]	= NULL;
	si_ptr->state					= IDLE;
	si_ptr->remount					= True;
	
	g_payload_size					= atlmix_atl_payload_size();

	g_storage_device_ptr			= dvi_ptr;

	gene_install_asynchronous_periodic_process( 8, strg_maintenance_routine_entry );

	storage_mount();
	
	si_ptr->previous_state	= 0xFF;
	ui_install_status_monitor_custom_routine( STORAGE_STATUS_MONITOR_LINE, strg_status_monitor );

//	mprintf( LIGHTGRAY, CONTINUE, "  storage class : class driver started, Bulk-only transfer/SCSI protocol\r\n" );

	return ( no_error );
}


unsigned short storage_dispose_process( device_instance *dvi_ptr )
{
	storage_instance		*si_ptr;

	ui_install_status_monitor_custom_routine( STORAGE_STATUS_MONITOR_LINE, NULL );
	gene_install_asynchronous_periodic_process( 8, NULL );

	si_ptr		= (storage_instance *)(dvi_ptr->class_instance_ptr);
	
	if ( si_ptr->volume_instance[ 0 ] != NULL )
	{
		mprintf( RED, CONTINUE, "error : volume removed before volume-close\r\n" );
		fs_volume_close( si_ptr->volume_instance[ 0 ] );
		
		si_ptr->volume_instance[ 0 ]	= NULL;
	}
	
	free( si_ptr );
	dvi_ptr->class_instance_ptr		= NULL;
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -