scsi_decoder.c

Go to the documentation of this file.
00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
00015 
00016 /* Copyright (c) 2007, Atmel Corporation All rights reserved.
00017  *
00018  * Redistribution and use in source and binary forms, with or without
00019  * modification, are permitted provided that the following conditions are met:
00020  *
00021  * 1. Redistributions of source code must retain the above copyright notice,
00022  * this list of conditions and the following disclaimer.
00023  *
00024  * 2. Redistributions in binary form must reproduce the above copyright notice,
00025  * this list of conditions and the following disclaimer in the documentation
00026  * and/or other materials provided with the distribution.
00027  *
00028  * 3. The name of ATMEL may not be used to endorse or promote products derived
00029  * from this software without specific prior written permission.
00030  *
00031  * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
00032  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00033  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY AND
00034  * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
00035  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00036  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00037  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00038  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00039  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00040  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00041  */
00042 
00043 //_____  I N C L U D E S ___________________________________________________
00044 
00045 #include "config.h"
00046 #include "scsi_decoder.h"
00047 #include "storage_task.h"
00048 #include "conf_usb.h"
00049 #include "lib_mcu/usb/usb_drv.h"
00050 #include "modules/control_access/ctrl_status.h"
00051 #include "modules/control_access/ctrl_access.h"
00052 
00053 
00054 //_____ D E F I N I T I O N S ______________________________________________
00055 
00056 U8  g_scsi_command[16];
00057 U8  g_scsi_status;
00058 U32 g_scsi_data_remaining;
00059 
00060 code    U8    g_sbc_vendor_id[8]   = SBC_VENDOR_ID;
00061 code    U8    g_sbc_product_id[16] = SBC_PRODUCT_ID;
00062 code    U8    g_sbc_revision_id[4] = SBC_REVISION_ID;
00063 
00064 extern  U8    usb_LUN;
00065 extern  bit   ms_data_direction;
00066 s_scsi_sense  g_scsi_sense;
00067 
00068 
00069 code  struct sbc_st_std_inquiry_data sbc_std_inquiry_data =
00070 {
00071    // Byte 0 : 0x00
00072    0x00,       // DeviceType: Direct-access device (SBC)
00073    0,          // PeripheralQualifier : Currently connected
00074 
00075    // Byte 1 : 0x80
00076    0,          // Reserved1
00077    1,          // RMB : Medium is removable (this bit must be at 1, else the medium isn't see on Windows)
00078 
00079    // Byte 2 : The code in the VERSION corresponds to a command set of DeviceType (here, Direct-access device - SBC)
00080    0x03,       // - 00h The device does not claim conformance to any standard.
00081                // - 03h The device complies to SPC (=SBC)
00082                // - 04h The device complies to SPC-2 (=SBC-2)
00083                // - 05h The device complies to SPC-3 (=SBC-2)
00084                // - 06h The device complies to SPC-4 (=SBC-3)
00085 
00086    // Byte 3 : 0x02
00087    2,          // Response data format
00088    0,          // NormACA
00089    0,          // Obsolete0
00090    0,          // AERC
00091 
00092    // Byte 4 : 0x1F
00093    // Byte 5 : 0x00
00094    // Byte 6 : 0x00
00095                // Reserved4[3]
00096    {
00097       0x1F,    // Additional Length (n-4)
00098       0,       // SCCS : SCC supported
00099       0
00100    },
00101 
00102    // Byte 7 : 0x00
00103    0,          // SoftReset
00104    0,          // CommandQueue
00105    0,          // Reserved5
00106    0,          // LinkedCommands
00107    0,          // Synchronous
00108    0,          // Wide16Bit
00109    0,          // Wide32Bit
00110    0,          // RelativeAddressing
00111 };
00112 
00113 
00114 static   void  send_informational_exceptions_page  (void);
00115 static   void  send_read_write_error_recovery_page (U8);
00116 static   void  sbc_header_mode_sense               ( Bool b_sense_10 , U8 u8_data_length );
00117 
00118 
00119 //_____ D E C L A R A T I O N S ____________________________________________
00120 
00121 
00135 Bool scsi_decode_command(void)
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 }
00206 
00207 
00225 Bool sbc_request_sense (void)
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 }
00269 
00270 
00290 Bool sbc_inquiry (void)
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 }
00346 
00347 
00348 Bool sbc_test_unit_ready(void)
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 }
00371 
00372 
00373 Bool sbc_read_capacity (void)
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 }
00409 
00410 
00411 Bool sbc_read_10 (void)
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 }
00470 
00471 
00472 Bool sbc_write_10 (void)
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 }
00538 
00539 
00554 Bool sbc_mode_sense( Bool b_sense_10 )
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 }
00621 
00622 
00630 void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length )
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 }
00665 
00666 
00678 void send_informational_exceptions_page (void)
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 }
00694 
00695 
00707 void send_read_write_error_recovery_page (U8 length)
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 }
00727 
00743 Bool sbc_prevent_allow_medium_removal(void)
00744 {
00745    sbc_lun_status_is_good();
00746    return TRUE;
00747 }
00748 
00749 
00752 void sbc_lun_status_is_good(void)
00753 {
00754    Sbc_send_good();
00755    Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00756 }
00757 
00760 void sbc_lun_status_is_not_present(void)
00761 {
00762    Sbc_send_failed();
00763    Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);
00764 }
00765 
00768 void sbc_lun_status_is_busy_or_change(void)
00769 {
00770    Sbc_send_failed();
00771    Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );
00772 }
00773 
00776 void sbc_lun_status_is_fail(void)
00777 {
00778    Sbc_send_failed();
00779    Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00780 }
00781 
00784 void sbc_lun_status_is_protected(void)
00785 {
00786    Sbc_send_failed();
00787    Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);
00788 }
00789 
00792 void sbc_lun_status_is_cdb_field(void)
00793 {
00794    Sbc_send_failed();
00795    Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
00796 }
00797 

Generated on Fri May 15 15:41:36 2009 for ATMEL by  doxygen 1.5.3