- Main Page
- Modules
- Data Structures
- Files
- Related Pages

# scsi_decoder.c File Reference

`#include "config.h"`
`#include "scsi_decoder.h"`
`#include "storage_task.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)
static void | send_read_write_error_recovery_page (U8 length)
static void | sbc_header_mode_sense (Bool b_sense_10, U8 u8_data_length)
Bool | scsi_decode_command (void)
Bool | sbc_request_sense (void)
Bool | sbc_inquiry (void)
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)
Bool | sbc_prevent_allow_medium_removal (void)
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.
void | sbc_lun_status_is_cdb_field (void)
| This fonction send the UFI status FAIL because CDB field is invalid.
## Variables
U8 | g_scsi_command [16]
U8 | g_scsi_status
U32 | g_scsi_data_remaining
code U8 | g_sbc_vendor_id [8] = SBC_VENDOR_ID
code U8 | g_sbc_product_id [16] = SBC_PRODUCT_ID
code U8 | g_sbc_revision_id [4] = SBC_REVISION_ID
U8 | usb_LUN
bit | ms_data_direction
s_scsi_sense | g_scsi_sense
code struct sbc_st_std_inquiry_data | sbc_std_inquiry_data

## Detailed Description

This file is the SCSI decoder module This file contains the routines to decode and to manage the SCSI commands - Compiler: IAR EWAVR and GNU GCC for AVR

- Supported devices: AT90USB1287, AT90USB1286, AT90USB647, AT90USB646
  Author:
    Atmel Corporation: http://www.atmel.com
    Support and FAQ: http://support.atmel.no/

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 678 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().

    00679 {
    00680    Usb_write_byte(SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS);     // Page Code: Informational exceptions control page
    00681                                                                // See chapter 8.3.8 on SPC-2 specification
    00682    Usb_write_byte(SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS);   // Page Length
    00683    Usb_write_byte(0x00);                                       // ..., Test bit = 0, ...
    00684    Usb_write_byte(SBC_MRIE);                                   // MRIE = 0x05
    00685    Usb_write_byte(0x00);                                       // Interval Timer (MSB)
    00686    Usb_write_byte(0x00);
    00687    Usb_write_byte(0x00);
    00688    Usb_write_byte(0x00);                                       // Interval Timer (LSB)
    00689    Usb_write_byte(0x00);                                       // Report Count (MSB)
    00690    Usb_write_byte(0x00);
    00691    Usb_write_byte(0x00);
    00692    Usb_write_byte(0x01);                                       // Report Count (LSB)
    00693 }

Here is the caller graph for this function:

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 707 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().

    00708 {
    00709    Usb_write_byte(SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY);
    00710
    00711    Usb_write_byte(SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY);   // Page Length
    00712    Usb_write_byte(0x80);
    00713    Usb_write_byte(SBC_READ_RETRY_COUNT);
    00714    Usb_write_byte(SBC_CORRECTION_SPAN);
    00715    Usb_write_byte(SBC_HEAD_OFFSET_COUNT);
    00716    Usb_write_byte(SBC_DATA_STROBE_OFFSET);
    00717    Usb_write_byte(0x00);   // Reserved
    00718
    00719    if (length > 12)
    00720    {
    00721       Usb_write_byte(SBC_WRITE_RETRY_COUNT);
    00722       Usb_write_byte(0x00);
    00723       Usb_write_byte(SBC_RECOVERY_LIMIT_MSB);
    00724       Usb_write_byte(SBC_RECOVERY_LIMIT_LSB);
    00725    }
    00726 }

Here is the caller graph for this function:

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 630 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().

    00631 {
    00632    // Send Data length
    00633    if( b_sense_10 )
    00634    {
    00635       Usb_write_byte(0);
    00636    }
    00637    Usb_write_byte( u8_data_length );
    00638
    00639    // Send device type
    00640    Usb_write_byte(SBC_MEDIUM_TYPE);
    00641
    00642    // Write protect status
    00643    if (mem_wr_protect( usb_LUN ))
    00644    {
    00645       Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_PROTECT);  // Device is write protected
    00646    }
    00647    else
    00648    {
    00649       Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_ENABLE);   // Device is write enabled
    00650    }
    00651
    00652    if( b_sense_10 )
    00653    {  // Reserved
    00654       Usb_write_byte(0);
    00655       Usb_write_byte(0);
    00656    }
    00657
    00658    // Send Block descriptor length
    00659    if( b_sense_10 )
    00660    {
    00661       Usb_write_byte(0);
    00662    }
    00663    Usb_write_byte(SBC_BLOCK_DESCRIPTOR_LENGTH);
    00664 }

Here is the call graph for this function:

Here is the caller 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

0x1B - Optional

Definition at line 135 of file scsi_decoder.c.

Referenced by usb_mass_storage_cbw().

    00136 {
    00137    Bool status;
    00138
    00139    if (g_scsi_command[0] == SBC_CMD_WRITE_10)
    00140    {
    00141       Scsi_start_write_action();
    00142       status = sbc_write_10();
    00143       Scsi_stop_write_action();
    00144       return status;
    00145    }
    00146    if (g_scsi_command[0] == SBC_CMD_READ_10 )
    00147    {
    00148       Scsi_start_read_action();
    00149       status = sbc_read_10();
    00150       Scsi_stop_read_action();
    00151       return status;
    00152    }
    00153
    00154    switch (g_scsi_command[0])
    00155    {
    00156       case SBC_CMD_REQUEST_SENSE:               // 0x03 - Mandatory
    00157       return sbc_request_sense();
    00158       break;
    00159
    00160       case SBC_CMD_INQUIRY:                     // 0x12 - Mandatory
    00161       return sbc_inquiry();
    00162       break;
    00163
    00164       case SBC_CMD_TEST_UNIT_READY:             // 0x00 - Mandatory
    00165       return sbc_test_unit_ready();
    00166       break;
    00167
    00168       case SBC_CMD_READ_CAPACITY:               // 0x25 - Mandatory
    00169       return sbc_read_capacity();
    00170       break;
    00171
    00172       case SBC_CMD_MODE_SENSE_6:                // 0x1A - Optional
    00173       return sbc_mode_sense( FALSE );
    00174       break;
    00175
    00176       case SBC_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:// 0x1E
    00177       return sbc_prevent_allow_medium_removal();
    00178       break;
    00179
    00180       case SBC_CMD_VERIFY_10:                   // 0x2F - Optional
    00181       sbc_lun_status_is_good();
    00182       break;
    00183
    00184       case SBC_CMD_MODE_SENSE_10:               // 0x5A - Optional
    00185       return sbc_mode_sense( TRUE );
    00186       break;
    00187
    00188       case SBC_CMD_FORMAT_UNIT:                 // 0x04 - Mandatory
    00189       case SBC_CMD_MODE_SELECT_6:               // 0x15 - Optional
    00190       case SBC_CMD_START_STOP_UNIT:
    00191       case SBC_CMD_SEND_DIAGNOSTIC:             // 0x1D -
    00192       case SBC_CMD_READ_LONG:                   // 0x23 - Optional
    00193       case SBC_CMD_SYNCHRONIZE_CACHE:           // 0x35 - Optional
    00194       case SBC_CMD_WRITE_BUFFER:                // 0x3B - Optional
    00195       case SBC_CMD_RESERVE_10:                  // 0x56 - Mandatory
    00196       case SBC_CMD_RELEASE_10:                  // 0x57 - Mandatory - see chapter 7.16 - SPC 2
    00197       default:
    00198       // Command not supported
    00199       Sbc_send_failed();
    00200       Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_COMMAND_OPERATION_CODE, 0x00);
    00201       return FALSE;
    00202       break;
    00203    }
    00204    return TRUE;
    00205 }

Here is the caller 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 :

- sense key (g_scsi_sense.key)
- additional sense code (g_scsi_sense.asc)
- additional sense code qualifier (g_scsi_sense.ascq)
  Warning:
    Code:.. bytes (function code length)
  Parameters:

    | none |

  Returns:
    FALSE: result KO, TRUE: result OK

Definition at line 225 of file scsi_decoder.c.

Referenced by scsi_decode_command().

    00226 {
    00227    U8  allocation_length, i;
    00228    U8  request_sens_output[18];                             // the maximum size of request is 17
    00229
    00230    allocation_length = g_scsi_command[4];                   // Allocation length
    00231    if( allocation_length > 18 )
    00232    {
    00233       allocation_length = 18;
    00234    }
    00235    // Initialize the request sense data
    00236    request_sens_output[0] = SBC_RESPONSE_CODE_SENSE;        // 70h
    00237    request_sens_output[1] = 0x00;                           // Obsolete
    00238    request_sens_output[2] = g_scsi_sense.key;
    00239
    00240    request_sens_output[3] = 0x00;                           // For direct access media, Information field
    00241    request_sens_output[4] = 0x00;                           // give the unsigned logical block
    00242    request_sens_output[5] = 0x00;                           // address associated with the sense key
    00243    request_sens_output[6] = 0x00;
    00244
    00245    request_sens_output[7] = SBC_ADDITIONAL_SENSE_LENGTH;    // UFI device shall not adjust the Additional sense length to reflect truncation
    00246    request_sens_output[8] = SBC_COMMAND_SPECIFIC_INFORMATION_3;
    00247    request_sens_output[9] = SBC_COMMAND_SPECIFIC_INFORMATION_2;
    00248    request_sens_output[10] = SBC_COMMAND_SPECIFIC_INFORMATION_1;
    00249    request_sens_output[11] = SBC_COMMAND_SPECIFIC_INFORMATION_0;
    00250
    00251    request_sens_output[12] = g_scsi_sense.asc;
    00252    request_sens_output[13] = g_scsi_sense.ascq;
    00253
    00254    request_sens_output[14] = SBC_FIELD_REPLACEABLE_UNIT_CODE;
    00255    request_sens_output[15] = SBC_SENSE_KEY_SPECIFIC_2;
    00256    request_sens_output[16] = SBC_SENSE_KEY_SPECIFIC_1;
    00257    request_sens_output[17] = SBC_SENSE_KEY_SPECIFIC_0;
    00258
    00259    // Send the request data
    00260    for( i=0 ; i<allocation_length ; i++ )
    00261    {
    00262        Usb_write_byte( request_sens_output[i] );
    00263    }
    00264    Sbc_valid_write_usb( allocation_length );
    00265
    00266    sbc_lun_status_is_good();
    00267    return TRUE;
    00268 }

Here is the caller 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:

- vendor identification
- product identification
- peripheral qualifier
- peripheral device type
- etc

Warning:
  Code:.. bytes (function code length)

Parameters:

  | none |

Returns:
  FALSE: result KO, TRUE: result OK

Definition at line 290 of file scsi_decoder.c.

Referenced by scsi_decode_command().

    00291 {
    00292    U8 allocation_length, i;
    00293
    00294 #ifdef __GNUC__
    00295    PGM_VOID_P ptr;
    00296 #else
    00297    U8 code *ptr;
    00298 #endif
    00299
    00300    if( (0 != (g_scsi_command[1] & 0x03) )       // CMDT and EPVD bits are 0
    00301    ||  (0 !=  g_scsi_command[2]         ) )     // PAGE or OPERATION CODE fields = 0x00?
    00302    {
    00303       // (CMDT=EVPD <> 0) or (PAGE CODE <> 0x00)
    00304       // No standard inquiry asked
    00305       sbc_lun_status_is_cdb_field();
    00306       return FALSE;
    00307    }
    00308
    00309    // Manage the standard inquiry command
    00310    // Check the size of inquiry data
    00311    allocation_length = g_scsi_command[4];
    00312    if (allocation_length > SBC_MAX_INQUIRY_DATA)
    00313    {
    00314       allocation_length = SBC_MAX_INQUIRY_DATA;
    00315    }
    00316
    00317    // send first inquiry data (0 to 8)
    00318    ptr = (code U8*) &sbc_std_inquiry_data;
    00319
    00320    for ( i=0 ; ((i != 36) && (allocation_length > i)); i++)
    00321    {
    00322       if( 8 == i )
    00323       {  // send vendor id (8 to 16)
    00324            ptr = (code U8 *) &g_sbc_vendor_id;
    00325       }
    00326       if( 16 == i )
    00327       {  // send product id (16 to 32)
    00328          ptr = (code U8 *) &g_sbc_product_id;
    00329       }
    00330       if( 32 == i )
    00331       {  // send revision id (32 to 36)
    00332          ptr = (code U8 *) &g_sbc_revision_id;
    00333       }
    00334 #ifndef __GNUC__
    00335       Usb_write_byte((U8)(*ptr++));
    00336 #else    // AVRGCC does not support point to PGM space
    00337 //warning with AVRGCC assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory
    00338       Usb_write_byte(pgm_read_byte_near((unsigned int)ptr++));
    00339 #endif
    00340
    00341    }
    00342    Sbc_valid_write_usb(i);
    00343    sbc_lun_status_is_good();
    00344    return TRUE;
    00345 }

Here is the caller graph for this function:

Bool sbc_test_unit_ready | ( | void |  | ) |

Definition at line 348 of file scsi_decoder.c.

Referenced by scsi_decode_command().

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

Here is the caller graph for this function:

Bool sbc_read_capacity | ( | void |  | ) |

Definition at line 373 of file scsi_decoder.c.

Referenced by scsi_decode_command().

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

Here is the caller graph for this function:

Bool sbc_read_10 | ( | void |  | ) |

Definition at line 411 of file scsi_decoder.c.

Referenced by scsi_decode_command().

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

Here is the caller graph for this function:

Bool sbc_write_10 | ( | void |  | ) |

Definition at line 472 of file scsi_decoder.c.

Referenced by scsi_decode_command().

    00473 {
    00474    U32   mass_addr;                       // rd or wr block address
    00475    U16   mass_size;                       // rd or write nb of blocks
    00476
    00477    MSB0(mass_addr) = g_scsi_command[2];   // read address
    00478    MSB1(mass_addr) = g_scsi_command[3];
    00479    MSB2(mass_addr) = g_scsi_command[4];
    00480    MSB3(mass_addr) = g_scsi_command[5];
    00481
    00482    MSB(mass_size) = g_scsi_command[7];    // read size
    00483    LSB(mass_size) = g_scsi_command[8];
    00484
    00485    if( Is_usb_ms_data_direction_in() )
    00486    {
    00487       sbc_lun_status_is_cdb_field();
    00488       return FALSE;
    00489    }
    00490
    00491    if( 0 == g_scsi_data_remaining )
    00492    {
    00493       if( mass_size == (g_scsi_data_remaining/512) )
    00494       {
    00495          sbc_lun_status_is_good();
    00496       }else{
    00497          sbc_lun_status_is_cdb_field();
    00498       }
    00499       return TRUE;
    00500    }
    00501
    00502    if( TRUE == mem_wr_protect( usb_LUN ) )
    00503    {
    00504       sbc_lun_status_is_protected();
    00505       return FALSE;
    00506    }
    00507
    00508    switch (usb_2_memory( usb_LUN , mass_addr, g_scsi_data_remaining/512 ))
    00509    {
    00510       case CTRL_GOOD :
    00511       if( mass_size == (g_scsi_data_remaining/512) )
    00512       {
    00513          sbc_lun_status_is_good();
    00514       }else{
    00515          sbc_lun_status_is_cdb_field();
    00516       }
    00517       g_scsi_data_remaining = 0;
    00518       break;
    00519
    00520       case CTRL_NO_PRESENT :
    00521       sbc_lun_status_is_not_present();
    00522       return FALSE;
    00523       break;
    00524
    00525       case CTRL_BUSY :
    00526       sbc_lun_status_is_busy_or_change();
    00527       return FALSE;
    00528       break;
    00529
    00530       case CTRL_FAIL :
    00531       default :
    00532       sbc_lun_status_is_fail();
    00533       return FALSE;
    00534       break;
    00535    }
    00536    return TRUE;
    00537 }

Here is the caller 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 554 of file scsi_decoder.c.

Referenced by scsi_decode_command().

    00555 {
    00556    U8 allocation_length;
    00557
    00558    if( b_sense_10 )
    00559       allocation_length = g_scsi_command[8];
    00560    else
    00561       allocation_length = g_scsi_command[4];
    00562
    00563    // switch for page code
    00564    switch ( g_scsi_command[2] & SBC_MSK_PAGE_CODE )
    00565    {
    00566       case SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS:
    00567       sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS );
    00568       send_informational_exceptions_page();
    00569       Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS + 1);
    00570       break;
    00571
    00572       case SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY:
    00573       sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY );
    00574       send_read_write_error_recovery_page(allocation_length);
    00575       Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY + 1);
    00576       break;
    00577
    00578       case SBC_PAGE_CODE_ALL:
    00579       if( b_sense_10 ) {
    00580          sbc_header_mode_sense( b_sense_10 , (allocation_length < (SBC_MODE_DATA_LENGTH_CODE_ALL+2))? (allocation_length-2) : SBC_MODE_DATA_LENGTH_CODE_ALL );
    00581       }else{
    00582          sbc_header_mode_sense( b_sense_10 , (allocation_length < (SBC_MODE_DATA_LENGTH_CODE_ALL+1))? (allocation_length-1) : SBC_MODE_DATA_LENGTH_CODE_ALL );
    00583       }
    00584       if( b_sense_10 )
    00585       {
    00586          if (allocation_length == 8)
    00587          {
    00588             Sbc_valid_write_usb(8);
    00589             break;
    00590          }
    00591       }
    00592       else
    00593       {
    00594          if (allocation_length == 4)
    00595          {
    00596             Sbc_valid_write_usb(4);
    00597             break;
    00598          }
    00599       }
    00600       // send page by ascending order code
    00601       send_read_write_error_recovery_page(allocation_length);  // 12 bytes
    00602       if (allocation_length > 12)
    00603       {
    00604          send_informational_exceptions_page();                 // 12 bytes
    00605          Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_CODE_ALL + 1);
    00606       }
    00607       else
    00608       {
    00609          Sbc_valid_write_usb(allocation_length);
    00610       }
    00611       break;
    00612
    00613       default:
    00614       sbc_lun_status_is_cdb_field();
    00615       return FALSE;
    00616       break;
    00617    }
    00618    sbc_lun_status_is_good();
    00619    return TRUE;
    00620 }

Here is the caller 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 743 of file scsi_decoder.c.

Referenced by scsi_decode_command().

    00744 {
    00745    sbc_lun_status_is_good();
    00746    return TRUE;
    00747 }

Here is the caller graph for this function:

void sbc_lun_status_is_good | ( | void |  | ) |

This fonction send the UFI status GOOD.

Definition at line 752 of file scsi_decoder.c.

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().

    00753 {
    00754    Sbc_send_good();
    00755    Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
    00756 }

Here is the caller graph for this function:

void sbc_lun_status_is_not_present | ( | void |  | ) |

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

Definition at line 760 of file scsi_decoder.c.

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

    00761 {
    00762    Sbc_send_failed();
    00763    Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);
    00764 }

Here is the caller graph for this function:

void sbc_lun_status_is_busy_or_change | ( | void |  | ) |

This fonction send the UFI status busy and change.

Definition at line 768 of file scsi_decoder.c.

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

    00769 {
    00770    Sbc_send_failed();
    00771    Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );
    00772 }

Here is the caller graph for this function:

void sbc_lun_status_is_fail | ( | void |  | ) |

This fonction send the UFI status FAIL.

Definition at line 776 of file scsi_decoder.c.

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

    00777 {
    00778    Sbc_send_failed();
    00779    Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
    00780 }

Here is the caller graph for this function:

void sbc_lun_status_is_protected | ( | void |  | ) |

This fonction send the UFI status FAIL because write protection.

Definition at line 784 of file scsi_decoder.c.

Referenced by sbc_write_10().

    00785 {
    00786    Sbc_send_failed();
    00787    Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);
    00788 }

Here is the caller graph for this function:

void sbc_lun_status_is_cdb_field | ( | void |  | ) |

This fonction send the UFI status FAIL because CDB field is invalid.

Definition at line 792 of file scsi_decoder.c.

Referenced by sbc_inquiry(), sbc_mode_sense(), sbc_read_10(), and sbc_write_10().

    00793 {
    00794    Sbc_send_failed();
    00795    Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
    00796 }

Here is the caller graph for this function:

## Variable Documentation

U8 g_scsi_command[16]

Definition at line 56 of file scsi_decoder.c.

U8 g_scsi_status

Definition at line 57 of file scsi_decoder.c.

U32 g_scsi_data_remaining

Definition at line 58 of file scsi_decoder.c.

code U8 g_sbc_vendor_id[8] = SBC_VENDOR_ID

Definition at line 60 of file scsi_decoder.c.

Referenced by sbc_inquiry().

code U8 g_sbc_product_id[16] = SBC_PRODUCT_ID

Definition at line 61 of file scsi_decoder.c.

Referenced by sbc_inquiry().

code U8 g_sbc_revision_id[4] = SBC_REVISION_ID

Definition at line 62 of file scsi_decoder.c.

Referenced by sbc_inquiry().

U8 usb_LUN

Definition at line 68 of file storage_task.c.

bit ms_data_direction

Definition at line 58 of file storage_task.c.

s_scsi_sense g_scsi_sense

Definition at line 66 of file scsi_decoder.c.

code struct sbc_st_std_inquiry_data sbc_std_inquiry_data

Definition at line 69 of file scsi_decoder.c.