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

- File List
- Globals

# scsi_decoder.c

Go to the documentation of this file.

    00001
    00018 //_____  I N C L U D E S ___________________________________________________
    00019
    00020 #include "config.h"
    00021 #include "scsi_decoder.h"
    00022 #include "conf_usb.h"
    00023 #include "lib_mcu\usb\usb_drv.h"                    // FIXME
    00024 #include "modules\control_access\ctrl_status.h"
    00025 #include "modules\control_access\ctrl_access.h"
    00026
    00027
    00028 //_____ M A C R O S ________________________________________________________
    00029
    00030
    00031 //_____ D E F I N I T I O N S ______________________________________________
    00032
    00033
    00034 _MEM_TYPE_MEDFAST_ U8  g_scsi_command[16];
    00035 _MEM_TYPE_MEDFAST_ U8  g_scsi_status;
    00036 _MEM_TYPE_MEDFAST_ U32 g_scsi_data_remaining;
    00037
    00038 code    U8    g_sbc_vendor_id[8]   = SBC_VENDOR_ID;
    00039 code    U8    g_sbc_product_id[16] = SBC_PRODUCT_ID;
    00040 code    U8    g_sbc_revision_id[4] = SBC_REVISION_ID;
    00041
    00042 extern  _MEM_TYPE_MEDFAST_  U8  usb_LUN;
    00043
    00044 _MEM_TYPE_MEDFAST_ s_scsi_sense  g_scsi_sense;
    00045
    00046
    00047 code  struct sbc_st_std_inquiry_data sbc_std_inquiry_data =
    00048 {
    00049    /* Byte 0 : 0x00 */
    00050    0x00,        /* DeviceType: Direct-access device */
    00051    0,           /* PeripheralQualifier : Currently connected */
    00052
    00053    /* Byte 1 : 0x80 */
    00054    0,           /* Reserved1 */
    00055    1,           /* RMB : Medium is removable (this bit must be at 1, else the medium isn't see on Windows) */
    00056
    00057  //  /* Byte 2 : 0x02 */
    00058  //  0x02,        /* Version: Device compliant to ANSI X3.131:1994 */
    00059
    00060    /* Byte 2 : 0x00 */
    00061    0x00,        /* Version: Device not compliant to any standard */
    00062
    00063    /* Byte 3 : 0x02 */
    00064    2,           /* Response data format */
    00065    0,           /* NormACA */
    00066    0,           /* Obsolete0 */
    00067    0,           /* AERC */
    00068
    00069    /* Byte 4 : 0x1F */
    00070    /* Byte 5 : 0x00 */
    00071    /* Byte 6 : 0x00 */
    00072                 /* Reserved4[3] */
    00073    {
    00074       0x1F,     /* Additional Length (n-4) */
    00075       0,        /* SCCS : SCC supported */
    00076       0
    00077    },
    00078
    00079    /* Byte 7 : 0x00 */
    00080    0,          /* SoftReset */
    00081    0,          /* CommandQueue */
    00082    0,          /* Reserved5 */
    00083    0,          /* LinkedCommands */
    00084    0,          /* Synchronous */
    00085    0,          /* Wide16Bit */
    00086    0,          /* Wide32Bit */
    00087    0,          /* RelativeAddressing */
    00088 };
    00089
    00090
    00091 static  void  send_informational_exceptions_page (void);
    00092 static  void  send_read_write_error_recovery_page (U8);
    00093 static  void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length );
    00094
    00095
    00096 //_____ D E C L A R A T I O N S ____________________________________________
    00110 Bool scsi_decode_command(void)
    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 }
    00186
    00187
    00205 Bool sbc_request_sense (void)
    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 }
    00247
    00267 Bool sbc_inquiry (void)
    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 }
    00350
    00351
    00352 Bool sbc_test_unit_ready(void)
    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 }
    00375
    00376
    00377 Bool sbc_read_capacity (void)
    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 }
    00413
    00414
    00415 Bool sbc_read_10 (void)
    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 }
    00461
    00462
    00463 Bool sbc_write_10 (void)
    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 }
    00518
    00519
    00534 Bool sbc_mode_sense( Bool b_sense_10 )
    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 }
    00598
    00599
    00607 void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length )
    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 }
    00642
    00643
    00655 void send_informational_exceptions_page (void)
    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 }
    00671
    00672
    00684 void send_read_write_error_recovery_page (U8 length)
    00685 {
    00686    Usb_write_byte(SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY);
    00687
    00688    Usb_write_byte(SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY);   /* Page Length */
    00689    Usb_write_byte(0x80);
    00690    Usb_write_byte(SBC_READ_RETRY_COUNT);
    00691    Usb_write_byte(SBC_CORRECTION_SPAN);
    00692    Usb_write_byte(SBC_HEAD_OFFSET_COUNT);
    00693    Usb_write_byte(SBC_DATA_STROBE_OFFSET);
    00694    Usb_write_byte(0x00);   /* Reserved */
    00695
    00696    if (length > 12)
    00697    {
    00698       Usb_write_byte(SBC_WRITE_RETRY_COUNT);
    00699       Usb_write_byte(0x00);
    00700       Usb_write_byte(SBC_RECOVERY_LIMIT_MSB);
    00701       Usb_write_byte(SBC_RECOVERY_LIMIT_LSB);
    00702    }
    00703 }
    00704
    00720 Bool sbc_prevent_allow_medium_removal(void)
    00721 {
    00722    sbc_lun_status_is_good();
    00723    return TRUE;
    00724 }
    00725
    00726
    00729 void sbc_lun_status_is_good(void)
    00730 {
    00731    Sbc_send_good();
    00732    Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
    00733 }
    00734
    00737 void sbc_lun_status_is_not_present(void)
    00738 {
    00739    Sbc_send_failed();
    00740    Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);
    00741 }
    00742
    00745 void sbc_lun_status_is_busy_or_change(void)
    00746 {
    00747    Sbc_send_failed();
    00748    Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );
    00749 }
    00750
    00753 void sbc_lun_status_is_fail(void)
    00754 {
    00755    Sbc_send_failed();
    00756    Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
    00757 }
    00758
    00761 void sbc_lun_status_is_protected(void)
    00762 {
    00763    Sbc_send_failed();
    00764    Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);
    00765 }