📄 storage.c
字号:
/*
** 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 + -