scsi_decoder.c File Reference

,vThis file is the SCSI decoder module More...

#include "config.h"
#include "scsi_decoder.h"
#include "conf_usb.h"
#include "lib_mcu\usb\usb_drv.h"
#include "modules\control_access\ctrl_status.h"
#include "modules\control_access\ctrl_access.h"

Include dependency graph for scsi_decoder.c:

Go to the source code of this file.

Functions

static void send_informational_exceptions_page (void)
 This function writes informational exceptions page parameters.
static void send_read_write_error_recovery_page (U8 length)
 This function writes error recovery page.
static void sbc_header_mode_sense (Bool b_sense_10, U8 u8_data_length)
 This function send the header of the SCSI MODE SENSE command.
Bool scsi_decode_command (void)
 SCSI decoder function.
Bool sbc_request_sense (void)
 This function manages the SCSI REQUEST SENSE command (0x03).
Bool sbc_inquiry (void)
 This function manages the SCSI INQUIRY command (0x12).
Bool sbc_test_unit_ready (void)
Bool sbc_read_capacity (void)
Bool sbc_read_10 (void)
Bool sbc_write_10 (void)
Bool sbc_mode_sense (Bool b_sense_10)
 This function manages the SCSI MODE SENSE command (0x1A for sense 6 and 0x5A for sense 10).
Bool sbc_prevent_allow_medium_removal (void)
 This function manages the SCSI PREVENT ALLOW MEDIUM REMOVAL command (0x1E).
void sbc_lun_status_is_good (void)
 This fonction send the UFI status GOOD.
void sbc_lun_status_is_not_present (void)
 This fonction send the UFI status "lun not present".
void sbc_lun_status_is_busy_or_change (void)
 This fonction send the UFI status busy and change.
void sbc_lun_status_is_fail (void)
 This fonction send the UFI status FAIL.
void sbc_lun_status_is_protected (void)
 This fonction send the UFI status FAIL because write protection.

Variables

_MEM_TYPE_MEDFAST_ U8 g_scsi_command [16]
_MEM_TYPE_MEDFAST_ U8 g_scsi_status
_MEM_TYPE_MEDFAST_ U32 g_scsi_data_remaining
code U8 g_sbc_vendor_id [8] = {'A','T','M','E','L',' ',' ',' '}
code U8 g_sbc_product_id [16] = {'A','T','9','0','U','S','B','1','6','2',' ','M',' ','S',' ',' '}
code U8 g_sbc_revision_id [4] = {'0','.','0','0'}
_MEM_TYPE_MEDFAST_ U8 usb_LUN
_MEM_TYPE_MEDFAST_ s_scsi_sense g_scsi_sense
code struct sbc_st_std_inquiry_data sbc_std_inquiry_data


Detailed Description

,vThis file is the SCSI decoder module

Copyright (c) 2004 Atmel.

Please read file license.txt for copyright notice.

This file contains the routines to decode and to manage the SCSI commands

Version:
1.1 at90usb162-2enum-mouse_ms-1_0_1
Id
scsi_decoder.c,v 1.1 2006/09/04 09:37:03 rletendu Exp
Todo:
Bug:

Definition in file scsi_decoder.c.


Function Documentation

void send_informational_exceptions_page ( void   )  [static]

This function writes informational exceptions page parameters.

Warning:
Code:.. bytes (function code length)
Parameters:
none 
Returns:
FALSE: result KO, TRUE: result OK

Definition at line 655 of file scsi_decoder.c.

References SBC_MRIE, SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS, SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS, and Usb_write_byte.

Referenced by sbc_mode_sense().

00656 {
00657    Usb_write_byte(SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS);     /* Page Code: Informational exceptions control page */
00658                                                                /* See chapter 8.3.8 on SPC-2 specification */
00659    Usb_write_byte(SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS);   /* Page Length */
00660    Usb_write_byte(0x00);                                       /* ..., Test bit = 0, ... */
00661    Usb_write_byte(SBC_MRIE);                                   /* MRIE = 0x05 */
00662    Usb_write_byte(0x00);                                       /* Interval Timer (MSB) */
00663    Usb_write_byte(0x00);
00664    Usb_write_byte(0x00);
00665    Usb_write_byte(0x00);                                       /* Interval Timer (LSB) */
00666    Usb_write_byte(0x00);                                       /* Report Count (MSB) */
00667    Usb_write_byte(0x00);
00668    Usb_write_byte(0x00);
00669    Usb_write_byte(0x01);                                       /* Report Count (LSB) */
00670 }

void send_read_write_error_recovery_page ( U8  length  )  [static]

This function writes error recovery page.

Warning:
Code:.. bytes (function code length)
Parameters:
none 
Returns:
FALSE: result KO, TRUE: result OK

Definition at line 684 of file scsi_decoder.c.

References SBC_CORRECTION_SPAN, SBC_DATA_STROBE_OFFSET, SBC_HEAD_OFFSET_COUNT, SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY, SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY, SBC_READ_RETRY_COUNT, SBC_RECOVERY_LIMIT_LSB, SBC_RECOVERY_LIMIT_MSB, SBC_WRITE_RETRY_COUNT, and Usb_write_byte.

Referenced by sbc_mode_sense().

void sbc_header_mode_sense ( Bool  b_sense_10,
U8  u8_data_length 
) [static]

This function send the header of the SCSI MODE SENSE command.

Parameters:
b_sens_10 ( TRUE = sense 10, FALSE = sense 6)
u8_data_length ( data length in byte )

Definition at line 607 of file scsi_decoder.c.

References mem_wr_protect(), SBC_BLOCK_DESCRIPTOR_LENGTH, SBC_DEV_SPEC_PARAM_WR_ENABLE, SBC_DEV_SPEC_PARAM_WR_PROTECT, SBC_MEDIUM_TYPE, usb_LUN, and Usb_write_byte.

Referenced by sbc_mode_sense().

00608 {
00609    // Send Data length
00610    if( b_sense_10 )
00611    {
00612       Usb_write_byte(0);
00613    }
00614    Usb_write_byte( u8_data_length );
00615 
00616    // Send device type
00617    Usb_write_byte(SBC_MEDIUM_TYPE);
00618 
00619    // Write protect status
00620    if (mem_wr_protect( usb_LUN ))
00621    {
00622       Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_PROTECT);  // Device is write protected
00623    }
00624    else
00625    {
00626       Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_ENABLE);   // Device is write enabled
00627    }
00628 
00629    if( b_sense_10 )
00630    {  // Reserved
00631       Usb_write_byte(0);
00632       Usb_write_byte(0);
00633    }
00634 
00635    // Send Block descriptor length
00636    if( b_sense_10 )
00637    {
00638       Usb_write_byte(0);
00639    }
00640    Usb_write_byte(SBC_BLOCK_DESCRIPTOR_LENGTH);
00641 }

Here is the call graph for this function:

Bool scsi_decode_command ( void   ) 

SCSI decoder function.

This function read the SCSI command and launches the appropriate function

Warning:
Code:.. bytes (function code length)
Parameters:
nonr 
Returns:
FALSE: result KO, TRUE: result OK

Definition at line 110 of file scsi_decoder.c.

References FALSE, g_scsi_command, SBC_ASC_INVALID_COMMAND_OPERATION_CODE, Sbc_build_sense, SBC_CMD_FORMAT_UNIT, SBC_CMD_INQUIRY, SBC_CMD_MODE_SELECT_6, SBC_CMD_MODE_SENSE_10, SBC_CMD_MODE_SENSE_6, SBC_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL, SBC_CMD_READ_10, SBC_CMD_READ_CAPACITY, SBC_CMD_READ_LONG, SBC_CMD_RELEASE_10, SBC_CMD_REQUEST_SENSE, SBC_CMD_RESERVE_10, SBC_CMD_SEND_DIAGNOSTIC, SBC_CMD_START_STOP_UNIT, SBC_CMD_SYNCHRONIZE_CACHE, SBC_CMD_TEST_UNIT_READY, SBC_CMD_VERIFY_10, SBC_CMD_WRITE_10, SBC_CMD_WRITE_BUFFER, sbc_inquiry(), sbc_lun_status_is_good(), sbc_mode_sense(), sbc_prevent_allow_medium_removal(), sbc_read_10(), sbc_read_capacity(), sbc_request_sense(), Sbc_send_failed, SBC_SENSE_KEY_ILLEGAL_REQUEST, sbc_test_unit_ready(), sbc_write_10(), Scsi_start_read_action, Scsi_start_write_action, Scsi_stop_read_action, Scsi_stop_write_action, and TRUE.

Referenced by usb_mass_storage_cbw().

00111 {
00112 Bool status;
00113 
00114    if (g_scsi_command[0] == SBC_CMD_WRITE_10)
00115    {
00116       Scsi_start_write_action();
00117       status = sbc_write_10();
00118      Scsi_stop_write_action();
00119       return status;
00120    }
00121    if (g_scsi_command[0] == SBC_CMD_READ_10 )
00122    {
00123       Scsi_start_read_action();
00124       status = sbc_read_10();
00125       Scsi_stop_read_action();
00126       return status;
00127    }
00128 
00129    switch (g_scsi_command[0])                /* check other command received */
00130    {
00131       case SBC_CMD_REQUEST_SENSE:             /* 0x03 - Mandatory */
00132            return sbc_request_sense();
00133            break;
00134 
00135       case SBC_CMD_INQUIRY:                   /* 0x12 - Mandatory */
00136            return sbc_inquiry();
00137            break;
00138 
00139       case SBC_CMD_TEST_UNIT_READY:           /* 0x00 - Mandatory */
00140            return sbc_test_unit_ready();
00141            break;
00142 
00143       case SBC_CMD_READ_CAPACITY:             /* 0x25 - Mandatory */
00144            return sbc_read_capacity();
00145            break;
00146 
00147       case SBC_CMD_MODE_SENSE_6:              /* 0x1A - Optional */
00148            return sbc_mode_sense( FALSE );
00149            break;
00150 
00151       case SBC_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:/* 0x1E */
00152            return sbc_prevent_allow_medium_removal();
00153            break;
00154 
00155       case SBC_CMD_VERIFY_10:                 /* 0x2F - Optional */
00156            sbc_lun_status_is_good();
00157            break;
00158       case SBC_CMD_MODE_SENSE_10:             /* 0x5A - Optional */
00159            return sbc_mode_sense( TRUE );
00160            break;
00161 
00162       case SBC_CMD_FORMAT_UNIT:               /* 0x04 - Mandatory */
00163 
00164       case SBC_CMD_MODE_SELECT_6:             /* 0x15 - Optional */
00165 
00166 
00167 
00168 
00169       case SBC_CMD_START_STOP_UNIT:           /* 0x1B - Optional */
00170       case SBC_CMD_SEND_DIAGNOSTIC:           /* 0x1D -  */
00171       case SBC_CMD_READ_LONG:                 /* 0x23 - Optional */
00172       case SBC_CMD_SYNCHRONIZE_CACHE:         /* 0x35 - Optional */
00173       case SBC_CMD_WRITE_BUFFER:              /* 0x3B - Optional */
00174       case SBC_CMD_RESERVE_10:                /* 0x56 - Mandatory */
00175       case SBC_CMD_RELEASE_10:                /* 0x57 - Mandatory - see chapter 7.16 - SPC 2 */
00176       default:
00177            { /* Command not supported */
00178               Sbc_send_failed();
00179               Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_COMMAND_OPERATION_CODE, 0x00);
00180               return FALSE;
00181               break;
00182            }
00183    }
00184    return TRUE;
00185 }

Here is the call graph for this function:

Bool sbc_request_sense ( void   ) 

This function manages the SCSI REQUEST SENSE command (0x03).

The SCSI Sense contains the status of the last command This status is composed of 3 Bytes :

Warning:
Code:.. bytes (function code length)
Parameters:
none 
Returns:
FALSE: result KO, TRUE: result OK

Definition at line 205 of file scsi_decoder.c.

References s_scsi_sense::asc, s_scsi_sense::ascq, g_scsi_command, g_scsi_sense, s_scsi_sense::key, SBC_ADDITIONAL_SENSE_LENGTH, SBC_COMMAND_SPECIFIC_INFORMATION_0, SBC_COMMAND_SPECIFIC_INFORMATION_1, SBC_COMMAND_SPECIFIC_INFORMATION_2, SBC_COMMAND_SPECIFIC_INFORMATION_3, SBC_FIELD_REPLACEABLE_UNIT_CODE, sbc_lun_status_is_good(), SBC_RESPONSE_CODE_SENSE, SBC_SENSE_KEY_SPECIFIC_0, SBC_SENSE_KEY_SPECIFIC_1, SBC_SENSE_KEY_SPECIFIC_2, Sbc_valid_write_usb, TRUE, and Usb_write_byte.

Referenced by scsi_decode_command().

00206 {
00207   U8  allocation_length, i;
00208   U8  request_sens_output[18];   /* the maximum size of request is 17 */
00209 
00210   allocation_length = g_scsi_command[4];  /* Allocation length */
00211 
00212   /* Initialize the request sense data */
00213   request_sens_output[0] = SBC_RESPONSE_CODE_SENSE; /* 70h */
00214   request_sens_output[1] = 0x00;                    /* Obsolete */
00215   request_sens_output[2] = g_scsi_sense.key;
00216 
00217   request_sens_output[3] = 0x00;   /* For direct access media, Information field */
00218   request_sens_output[4] = 0x00;   /* give the unsigned logical block */
00219   request_sens_output[5] = 0x00;   /* address associated with the sense key */
00220   request_sens_output[6] = 0x00;
00221 
00222   request_sens_output[7] = SBC_ADDITIONAL_SENSE_LENGTH; /* !! UFI device shall not adjust the Additional sense length to reflect truncation */
00223   request_sens_output[8] = SBC_COMMAND_SPECIFIC_INFORMATION_3;
00224   request_sens_output[9] = SBC_COMMAND_SPECIFIC_INFORMATION_2;
00225   request_sens_output[10] = SBC_COMMAND_SPECIFIC_INFORMATION_1;
00226   request_sens_output[11] = SBC_COMMAND_SPECIFIC_INFORMATION_0;
00227 
00228   request_sens_output[12] = g_scsi_sense.asc;
00229   request_sens_output[13] = g_scsi_sense.ascq;
00230 
00231   request_sens_output[14] = SBC_FIELD_REPLACEABLE_UNIT_CODE;
00232   request_sens_output[15] = SBC_SENSE_KEY_SPECIFIC_2;
00233   request_sens_output[16] = SBC_SENSE_KEY_SPECIFIC_1;
00234   request_sens_output[17] = SBC_SENSE_KEY_SPECIFIC_0;
00235 
00236   /* Send the request data */
00237   for( i=0 ; i<allocation_length ; i++ )
00238   {
00239     Usb_write_byte( request_sens_output[i] );
00240   }
00241   Sbc_valid_write_usb( allocation_length );
00242 
00243   sbc_lun_status_is_good();
00244 
00245   return TRUE;
00246 }

Here is the call graph for this function:

Bool sbc_inquiry ( void   ) 

This function manages the SCSI INQUIRY command (0x12).

The SCSI Inquiry field contains information regarding parameters of the target. For example:

Warning:
Code:.. bytes (function code length)
Parameters:
none 
Returns:
FALSE: result KO, TRUE: result OK

Definition at line 267 of file scsi_decoder.c.

References FALSE, g_sbc_product_id, g_sbc_revision_id, g_sbc_vendor_id, g_scsi_command, SBC_ASC_INVALID_FIELD_IN_CDB, Sbc_build_sense, sbc_lun_status_is_good(), SBC_MAX_INQUIRY_DATA, Sbc_send_failed, SBC_SENSE_KEY_ILLEGAL_REQUEST, sbc_std_inquiry_data, Sbc_valid_write_usb, TRUE, and Usb_write_byte.

Referenced by scsi_decode_command().

00268 {
00269    U8 allocation_length, i;
00270 
00271 #ifdef AVRGCC
00272    PGM_VOID_P ptr;
00273 #else
00274    U8 code *ptr;
00275 #endif
00276 
00277    if( (0 == (g_scsi_command[1] & 0x03) )    // CMDT and EPVD bits are 0
00278    &&  (0 ==  g_scsi_command[2]         ) )  // PAGE or OPERATION CODE fields = 0x00?
00279    {
00280       //** send standard inquiry data
00281 
00282       // Check the size of inquiry data
00283       allocation_length = g_scsi_command[4];
00284       if (allocation_length > SBC_MAX_INQUIRY_DATA)
00285       {
00286          allocation_length = SBC_MAX_INQUIRY_DATA;
00287       }
00288 
00289       // send first inquiry data (0 to 8)
00290       ptr = (code U8*) &sbc_std_inquiry_data;
00291 
00292       for ( i=0 ; ((i != 36) && (allocation_length > i)); i++)
00293       {
00294          if( 8 == i )
00295          {  // send vendor id (8 to 16)
00296               ptr = (code U8 *) &g_sbc_vendor_id;
00297          }
00298          if( 16 == i )
00299          {  // send product id (16 to 32)
00300             ptr = (code U8 *) &g_sbc_product_id;
00301          }
00302          if( 32 == i )
00303          {  // send revision id (32 to 36)
00304             ptr = (code U8 *) &g_sbc_revision_id;
00305          }
00306 #ifndef AVRGCC
00307          Usb_write_byte((U8)(*ptr++));     // send tab
00308 #else    // AVRGCC does not support point to PGM space
00309 #warning with avrgcc assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory
00310          Usb_write_byte(pgm_read_byte_near((unsigned int)ptr++));
00311 #endif
00312 
00313       }
00314 
00315       //  send data (36 to SBC_MAX_INQUIRY_DATA), and can be tranmitted by Bulk
00316       //  Description of next bytes (this bytes is always egal to 0) :
00317       //  VendorSpecific    : 20 Bytes
00318       //  Next byte         : 1 byte
00319       //       - InfoUnitSupport   : 1 bit
00320       //       - QuickArbitSupport : 1 bit
00321       //       - Clocking          : 2 bits
00322       //       - Reserved6         : 4 bits
00323       //  Reserved7         : 1 byte
00324       //  VersionDescriptor : 8 bytes
00325       //  Reserved8         : 22 bytes
00326       //  ...
00327       while( allocation_length > i )
00328       {
00329          if (64 == i)
00330          {  // for each 64 bytes, send USB packet
00331             Sbc_valid_write_usb(64);
00332             allocation_length -= 64;
00333             i = 0;
00334          }
00335          Usb_write_byte(0);       // write value of last bytes of inquiry data
00336          i++;
00337       }
00338       // send last USB packet
00339       Sbc_valid_write_usb(allocation_length);
00340       sbc_lun_status_is_good();
00341       return TRUE;
00342    }
00343    else
00344    {  // (CMDT=EVPD <> 0) or (PAGE CODE <> 0x00)
00345       Sbc_send_failed();
00346       Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
00347       return FALSE;
00348    }
00349 }

Here is the call graph for this function:

Bool sbc_test_unit_ready ( void   ) 

Definition at line 352 of file scsi_decoder.c.

References CTRL_BUSY, CTRL_FAIL, CTRL_GOOD, CTRL_NO_PRESENT, mem_test_unit_ready(), sbc_lun_status_is_busy_or_change(), sbc_lun_status_is_fail(), sbc_lun_status_is_good(), sbc_lun_status_is_not_present(), TRUE, and usb_LUN.

Referenced by scsi_decode_command().

00353 {
00354    switch ( mem_test_unit_ready(usb_LUN) )
00355    {
00356    case CTRL_GOOD :
00357       sbc_lun_status_is_good();
00358       break;
00359 
00360    case CTRL_NO_PRESENT :
00361       sbc_lun_status_is_not_present();
00362       break;
00363 
00364    case CTRL_BUSY :
00365       sbc_lun_status_is_busy_or_change();
00366       break;
00367 
00368    case CTRL_FAIL :
00369    default :
00370       sbc_lun_status_is_fail();
00371       break;
00372    }
00373    return TRUE;
00374 }

Here is the call graph for this function:

Bool sbc_read_capacity ( void   ) 

Definition at line 377 of file scsi_decoder.c.

References _MEM_TYPE_SLOW_, CTRL_BUSY, CTRL_FAIL, CTRL_GOOD, CTRL_NO_PRESENT, FALSE, mem_read_capacity(), MSB0, MSB1, MSB2, MSB3, sbc_lun_status_is_busy_or_change(), sbc_lun_status_is_fail(), sbc_lun_status_is_good(), sbc_lun_status_is_not_present(), SBC_READ_CAPACITY_LENGTH, Sbc_valid_write_usb, TRUE, usb_LUN, and Usb_write_byte.

Referenced by scsi_decode_command().

00378 {
00379    _MEM_TYPE_SLOW_ U32 mem_size_nb_sector;
00380 
00381    switch ( mem_read_capacity( usb_LUN, &mem_size_nb_sector ) )
00382    {
00383    case CTRL_GOOD :
00384       Usb_write_byte(MSB0(mem_size_nb_sector));  // return nb block
00385       Usb_write_byte(MSB1(mem_size_nb_sector));
00386       Usb_write_byte(MSB2(mem_size_nb_sector));
00387       Usb_write_byte(MSB3(mem_size_nb_sector));
00388       Usb_write_byte( 0               );        // return block size (= 512B)
00389       Usb_write_byte( 0               );
00390       Usb_write_byte( (U8)(512 >> 8)  );
00391       Usb_write_byte( (U8)(512 & 0xFF));
00392 
00393       Sbc_valid_write_usb(SBC_READ_CAPACITY_LENGTH);
00394       sbc_lun_status_is_good();
00395       return TRUE;
00396       break;
00397 
00398    case CTRL_NO_PRESENT :
00399       sbc_lun_status_is_not_present();
00400       break;
00401 
00402    case CTRL_BUSY :
00403       sbc_lun_status_is_busy_or_change();
00404       break;
00405 
00406    case CTRL_FAIL :
00407    default :
00408       sbc_lun_status_is_fail();
00409       break;
00410    }
00411    return FALSE;
00412 }

Here is the call graph for this function:

Bool sbc_read_10 ( void   ) 

Definition at line 415 of file scsi_decoder.c.

References CTRL_BUSY, CTRL_FAIL, CTRL_GOOD, CTRL_NO_PRESENT, FALSE, g_scsi_command, g_scsi_data_remaining, LSB, memory_2_usb(), MSB, MSB0, MSB1, MSB2, MSB3, sbc_lun_status_is_busy_or_change(), sbc_lun_status_is_fail(), sbc_lun_status_is_good(), sbc_lun_status_is_not_present(), TRUE, and usb_LUN.

Referenced by scsi_decode_command().

00416 {
00417    U32   mass_addr;                    // rd or wr block address
00418    U16   mass_size;                    // rd or write nb of blocks
00419 
00420    MSB0(mass_addr) = g_scsi_command[2];  // read address
00421    MSB1(mass_addr) = g_scsi_command[3];
00422    MSB2(mass_addr) = g_scsi_command[4];
00423    MSB3(mass_addr) = g_scsi_command[5];
00424 
00425    MSB(mass_size) = g_scsi_command[7];  // read size
00426    LSB(mass_size) = g_scsi_command[8];
00427 
00428    if (mass_size != 0)
00429    {
00430       switch ( memory_2_usb( usb_LUN , mass_addr, mass_size ) )
00431       {
00432       case CTRL_GOOD :
00433          sbc_lun_status_is_good();
00434          g_scsi_data_remaining = g_scsi_data_remaining - (512 * (Uint32)mass_size);
00435          return TRUE;
00436          break;
00437 
00438       case CTRL_NO_PRESENT :
00439          sbc_lun_status_is_not_present();
00440          return FALSE;
00441          break;
00442 
00443       case CTRL_BUSY :
00444          sbc_lun_status_is_busy_or_change();
00445          return FALSE;
00446          break;
00447 
00448       case CTRL_FAIL :
00449       default :
00450          sbc_lun_status_is_fail();
00451          return FALSE;
00452          break;
00453       }
00454    }
00455    else
00456    {  // No data to transfer
00457       sbc_lun_status_is_good();
00458    }
00459    return TRUE;
00460 }

Here is the call graph for this function:

Bool sbc_write_10 ( void   ) 

Definition at line 463 of file scsi_decoder.c.

References CTRL_BUSY, CTRL_FAIL, CTRL_GOOD, CTRL_NO_PRESENT, FALSE, g_scsi_command, g_scsi_data_remaining, LSB, mem_wr_protect(), MSB, MSB0, MSB1, MSB2, MSB3, sbc_lun_status_is_busy_or_change(), sbc_lun_status_is_fail(), sbc_lun_status_is_good(), sbc_lun_status_is_not_present(), sbc_lun_status_is_protected(), TRUE, usb_2_memory(), and usb_LUN.

Referenced by scsi_decode_command().

00464 {
00465    U32   mass_addr;                    // rd or wr block address
00466    U16   mass_size;                    // rd or write nb of blocks
00467 
00468    MSB0(mass_addr) = g_scsi_command[2];  // read address
00469    MSB1(mass_addr) = g_scsi_command[3];
00470    MSB2(mass_addr) = g_scsi_command[4];
00471    MSB3(mass_addr) = g_scsi_command[5];
00472 
00473    MSB(mass_size) = g_scsi_command[7];  // read size
00474    LSB(mass_size) = g_scsi_command[8];
00475 
00476    if (mass_size != 0)
00477    {
00478       if( TRUE == mem_wr_protect( usb_LUN ) )
00479       {
00480          sbc_lun_status_is_protected();
00481          return FALSE;
00482 #warning For Win98 data must be read to avoid blocking
00483       }
00484       else
00485       {
00486          switch (usb_2_memory( usb_LUN , mass_addr, mass_size ))
00487          {
00488          case CTRL_GOOD :
00489             sbc_lun_status_is_good();
00490             g_scsi_data_remaining = g_scsi_data_remaining - (512 * (Uint32)mass_size);
00491             return TRUE;
00492             break;
00493 
00494          case CTRL_NO_PRESENT :
00495             sbc_lun_status_is_not_present();
00496             return FALSE;
00497             break;
00498 
00499          case CTRL_BUSY :
00500             sbc_lun_status_is_busy_or_change();
00501             return FALSE;
00502             break;
00503 
00504          case CTRL_FAIL :
00505          default :
00506             sbc_lun_status_is_fail();
00507             return FALSE;
00508             break;
00509          }
00510       }
00511    }
00512    else
00513    {  // No data to transfer
00514       sbc_lun_status_is_good();
00515    }
00516    return TRUE;
00517 }

Here is the call graph for this function:

Bool sbc_mode_sense ( Bool  b_sense_10  ) 

This function manages the SCSI MODE SENSE command (0x1A for sense 6 and 0x5A for sense 10).

The SCSI mode sense function returns parameters to an application client. It is a complementary command to the SCSI MODE SELECT command.

Warning:
Code:.. bytes (function code length)
Parameters:
b_sens_10 ( TRUE = sense 10, TRUE = sense 6)
Returns:
FALSE: result KO, TRUE: result OK

Definition at line 534 of file scsi_decoder.c.

References FALSE, g_scsi_command, SBC_ASC_INVALID_FIELD_IN_CDB, Sbc_build_sense, sbc_header_mode_sense(), sbc_lun_status_is_good(), SBC_MODE_DATA_LENGTH_CODE_ALL, SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS, SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY, SBC_MSK_PAGE_CODE, SBC_PAGE_CODE_ALL, SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS, SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY, Sbc_send_failed, SBC_SENSE_KEY_ILLEGAL_REQUEST, Sbc_valid_write_usb, send_informational_exceptions_page(), send_read_write_error_recovery_page(), and TRUE.

Referenced by scsi_decode_command().

00535 {
00536    U8 allocation_length;
00537 
00538    if( b_sense_10 )
00539       allocation_length = g_scsi_command[8];
00540    else
00541       allocation_length = g_scsi_command[4];
00542 
00543    // switch for page code
00544    switch ( g_scsi_command[2] & SBC_MSK_PAGE_CODE )
00545    {
00546       case SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS:       /* Page Code: Informational exceptions control page */
00547          sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS );
00548          send_informational_exceptions_page();
00549          Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS + 1);
00550          break;
00551 
00552       case SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY:
00553          sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY );
00554          send_read_write_error_recovery_page(allocation_length);
00555          Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY + 1);
00556          break;
00557 
00558       case SBC_PAGE_CODE_ALL:
00559          sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_CODE_ALL );
00560          if( b_sense_10 )
00561          {
00562             if (allocation_length == 8)
00563             {
00564                Sbc_valid_write_usb(8);
00565                break;
00566             }
00567          }
00568          else
00569          {
00570             if (allocation_length == 4)
00571             {
00572                Sbc_valid_write_usb(4);
00573                break;
00574             }
00575          }
00576          // send page by ascending order code
00577          send_read_write_error_recovery_page(allocation_length);  // 12 bytes
00578          if (allocation_length > 12)
00579          {
00580             send_informational_exceptions_page();                 // 12 bytes
00581             Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_CODE_ALL + 1);
00582          }
00583          else
00584          {
00585             Sbc_valid_write_usb(allocation_length);
00586          }
00587          break;
00588 
00589       default:
00590            Sbc_send_failed();
00591            Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
00592            return FALSE;
00593            break;
00594    }
00595    sbc_lun_status_is_good();
00596    return TRUE;
00597 }

Here is the call graph for this function:

Bool sbc_prevent_allow_medium_removal ( void   ) 

This function manages the SCSI PREVENT ALLOW MEDIUM REMOVAL command (0x1E).

The SCSI prevent allow medium removal command requests that the target enable or disable the removal of the medium in the logical unit.

Warning:
Code:.. bytes (function code length)
Parameters:
none 
Returns:
FALSE: result KO, TRUE: result OK

Definition at line 720 of file scsi_decoder.c.

References sbc_lun_status_is_good(), and TRUE.

Referenced by scsi_decode_command().

00721 {
00722    sbc_lun_status_is_good();
00723    return TRUE;
00724 }

Here is the call graph for this function:

void sbc_lun_status_is_good ( void   ) 

This fonction send the UFI status GOOD.

Definition at line 729 of file scsi_decoder.c.

References SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, Sbc_build_sense, Sbc_send_good, and SBC_SENSE_KEY_NO_SENSE.

Referenced by sbc_inquiry(), sbc_mode_sense(), sbc_prevent_allow_medium_removal(), sbc_read_10(), sbc_read_capacity(), sbc_request_sense(), sbc_test_unit_ready(), sbc_write_10(), and scsi_decode_command().

void sbc_lun_status_is_not_present ( void   ) 

This fonction send the UFI status "lun not present".

Definition at line 737 of file scsi_decoder.c.

References SBC_ASC_MEDIUM_NOT_PRESENT, Sbc_build_sense, Sbc_send_failed, and SBC_SENSE_KEY_NOT_READY.

Referenced by sbc_read_10(), sbc_read_capacity(), sbc_test_unit_ready(), and sbc_write_10().

void sbc_lun_status_is_busy_or_change ( void   ) 

This fonction send the UFI status busy and change.

Definition at line 745 of file scsi_decoder.c.

References SBC_ASC_NOT_READY_TO_READY_CHANGE, Sbc_build_sense, Sbc_send_failed, and SBC_SENSE_KEY_UNIT_ATTENTION.

Referenced by sbc_read_10(), sbc_read_capacity(), sbc_test_unit_ready(), and sbc_write_10().

void sbc_lun_status_is_fail ( void   ) 

This fonction send the UFI status FAIL.

Definition at line 753 of file scsi_decoder.c.

References SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, Sbc_build_sense, Sbc_send_failed, and SBC_SENSE_KEY_HARDWARE_ERROR.

Referenced by sbc_read_10(), sbc_read_capacity(), sbc_test_unit_ready(), and sbc_write_10().

void sbc_lun_status_is_protected ( void   ) 

This fonction send the UFI status FAIL because write protection.

Definition at line 761 of file scsi_decoder.c.

References SBC_ASC_WRITE_PROTECTED, Sbc_build_sense, Sbc_send_failed, and SBC_SENSE_KEY_DATA_PROTECT.

Referenced by sbc_write_10().


Variable Documentation

_MEM_TYPE_MEDFAST_ U8 g_scsi_command[16]

Definition at line 34 of file scsi_decoder.c.

Referenced by sbc_inquiry(), sbc_mode_sense(), sbc_read_10(), sbc_request_sense(), sbc_write_10(), scsi_decode_command(), and usb_mass_storage_cbw().

_MEM_TYPE_MEDFAST_ U8 g_scsi_status

Definition at line 35 of file scsi_decoder.c.

Referenced by usb_mass_storage_csw().

_MEM_TYPE_MEDFAST_ U32 g_scsi_data_remaining

Definition at line 36 of file scsi_decoder.c.

Referenced by sbc_read_10(), sbc_write_10(), usb_mass_storage_cbw(), and usb_mass_storage_csw().

code U8 g_sbc_vendor_id[8] = {'A','T','M','E','L',' ',' ',' '}

Definition at line 38 of file scsi_decoder.c.

Referenced by sbc_inquiry().

code U8 g_sbc_product_id[16] = {'A','T','9','0','U','S','B','1','6','2',' ','M',' ','S',' ',' '}

Definition at line 39 of file scsi_decoder.c.

Referenced by sbc_inquiry().

code U8 g_sbc_revision_id[4] = {'0','.','0','0'}

Definition at line 40 of file scsi_decoder.c.

Referenced by sbc_inquiry().

_MEM_TYPE_MEDFAST_ U8 usb_LUN

Definition at line 59 of file storage_task.c.

Referenced by sbc_header_mode_sense(), sbc_read_10(), sbc_read_capacity(), sbc_test_unit_ready(), sbc_write_10(), and usb_mass_storage_cbw().

_MEM_TYPE_MEDFAST_ s_scsi_sense g_scsi_sense

Definition at line 44 of file scsi_decoder.c.

Referenced by sbc_request_sense().

code struct sbc_st_std_inquiry_data sbc_std_inquiry_data

Definition at line 47 of file scsi_decoder.c.

Referenced by sbc_inquiry().


Generated on Fri Jun 15 14:07:59 2007 for Atmel by  doxygen 1.5.1-p1