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 AND FITNESS FOR A PARTICULAR PURPOSE 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
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 :
00080    //  0x02,   // Version: Device compliant to ANSI X3.131:1994
00081    0x00,       // Version: Device not compliant to any standard
00082 
00083    // Byte 3 : 0x02
00084    2,          // Response data format
00085    0,          // NormACA
00086    0,          // Obsolete0
00087    0,          // AERC
00088 
00089    // Byte 4 : 0x1F
00090    // Byte 5 : 0x00
00091    // Byte 6 : 0x00
00092                // Reserved4[3]
00093    {
00094       0x1F,    // Additional Length (n-4)
00095       0,       // SCCS : SCC supported
00096       0
00097    },
00098 
00099    // Byte 7 : 0x00
00100    0,          // SoftReset
00101    0,          // CommandQueue
00102    0,          // Reserved5
00103    0,          // LinkedCommands
00104    0,          // Synchronous
00105    0,          // Wide16Bit
00106    0,          // Wide32Bit
00107    0,          // RelativeAddressing
00108 };
00109 
00110 
00111 static   void  send_informational_exceptions_page  (void);
00112 static   void  send_read_write_error_recovery_page (U8);
00113 static   void  sbc_header_mode_sense               ( Bool b_sense_10 , U8 u8_data_length );
00114 
00115 
00116 //_____ D E C L A R A T I O N S ____________________________________________
00117 
00118 
00132 Bool scsi_decode_command(void)
00133 {
00134    Bool status;
00135 
00136    if (g_scsi_command[0] == SBC_CMD_WRITE_10)
00137    {
00138       Scsi_start_write_action();
00139       status = sbc_write_10();
00140       Scsi_stop_write_action();
00141       return status;
00142    }
00143    if (g_scsi_command[0] == SBC_CMD_READ_10 )
00144    {
00145       Scsi_start_read_action();
00146       status = sbc_read_10();
00147       Scsi_stop_read_action();
00148       return status;
00149    }
00150 
00151    switch (g_scsi_command[0])
00152    {
00153       case SBC_CMD_REQUEST_SENSE:               // 0x03 - Mandatory
00154       return sbc_request_sense();
00155       break;
00156 
00157       case SBC_CMD_INQUIRY:                     // 0x12 - Mandatory
00158       return sbc_inquiry();
00159       break;
00160 
00161       case SBC_CMD_TEST_UNIT_READY:             // 0x00 - Mandatory
00162       return sbc_test_unit_ready();
00163       break;
00164 
00165       case SBC_CMD_READ_CAPACITY:               // 0x25 - Mandatory
00166       return sbc_read_capacity();
00167       break;
00168 
00169       case SBC_CMD_MODE_SENSE_6:                // 0x1A - Optional
00170       return sbc_mode_sense( FALSE );
00171       break;
00172 
00173       case SBC_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:// 0x1E
00174       return sbc_prevent_allow_medium_removal();
00175       break;
00176 
00177       case SBC_CMD_VERIFY_10:                   // 0x2F - Optional
00178       sbc_lun_status_is_good();
00179       break;
00180 
00181       case SBC_CMD_MODE_SENSE_10:               // 0x5A - Optional
00182       return sbc_mode_sense( TRUE );
00183       break;
00184 
00185       case SBC_CMD_FORMAT_UNIT:                 // 0x04 - Mandatory
00186       case SBC_CMD_MODE_SELECT_6:               // 0x15 - Optional
00187       case SBC_CMD_START_STOP_UNIT:             
00188       case SBC_CMD_SEND_DIAGNOSTIC:             // 0x1D - 
00189       case SBC_CMD_READ_LONG:                   // 0x23 - Optional
00190       case SBC_CMD_SYNCHRONIZE_CACHE:           // 0x35 - Optional
00191       case SBC_CMD_WRITE_BUFFER:                // 0x3B - Optional
00192       case SBC_CMD_RESERVE_10:                  // 0x56 - Mandatory
00193       case SBC_CMD_RELEASE_10:                  // 0x57 - Mandatory - see chapter 7.16 - SPC 2
00194       default:
00195       // Command not supported
00196       Sbc_send_failed();
00197       Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_COMMAND_OPERATION_CODE, 0x00);
00198       return FALSE;
00199       break;
00200    }
00201    return TRUE;
00202 }
00203 
00204 
00222 Bool sbc_request_sense (void)
00223 {
00224    U8  allocation_length, i;
00225    U8  request_sens_output[18];                             // the maximum size of request is 17
00226 
00227    allocation_length = g_scsi_command[4];                   // Allocation length
00228    if( allocation_length > 18 )
00229    {
00230       allocation_length = 18;
00231    }
00232    // Initialize the request sense data
00233    request_sens_output[0] = SBC_RESPONSE_CODE_SENSE;        // 70h
00234    request_sens_output[1] = 0x00;                           // Obsolete
00235    request_sens_output[2] = g_scsi_sense.key;
00236 
00237    request_sens_output[3] = 0x00;                           // For direct access media, Information field
00238    request_sens_output[4] = 0x00;                           // give the unsigned logical block
00239    request_sens_output[5] = 0x00;                           // address associated with the sense key
00240    request_sens_output[6] = 0x00;
00241 
00242    request_sens_output[7] = SBC_ADDITIONAL_SENSE_LENGTH;    // UFI device shall not adjust the Additional sense length to reflect truncation
00243    request_sens_output[8] = SBC_COMMAND_SPECIFIC_INFORMATION_3;
00244    request_sens_output[9] = SBC_COMMAND_SPECIFIC_INFORMATION_2;
00245    request_sens_output[10] = SBC_COMMAND_SPECIFIC_INFORMATION_1;
00246    request_sens_output[11] = SBC_COMMAND_SPECIFIC_INFORMATION_0;
00247 
00248    request_sens_output[12] = g_scsi_sense.asc;
00249    request_sens_output[13] = g_scsi_sense.ascq;
00250 
00251    request_sens_output[14] = SBC_FIELD_REPLACEABLE_UNIT_CODE;
00252    request_sens_output[15] = SBC_SENSE_KEY_SPECIFIC_2;
00253    request_sens_output[16] = SBC_SENSE_KEY_SPECIFIC_1;
00254    request_sens_output[17] = SBC_SENSE_KEY_SPECIFIC_0;
00255 
00256    // Send the request data
00257    for( i=0 ; i<allocation_length ; i++ )
00258    {
00259        Usb_write_byte( request_sens_output[i] );
00260    }
00261    Sbc_valid_write_usb( allocation_length );
00262 
00263    sbc_lun_status_is_good();
00264    return TRUE;
00265 }
00266 
00267 
00287 Bool sbc_inquiry (void)
00288 {
00289    U8 allocation_length, i;
00290 
00291 #ifdef __GNUC__
00292    PGM_VOID_P ptr;
00293 #else
00294    U8 code *ptr;
00295 #endif
00296 
00297    if( (0 != (g_scsi_command[1] & 0x03) )       // CMDT and EPVD bits are 0
00298    ||  (0 !=  g_scsi_command[2]         ) )     // PAGE or OPERATION CODE fields = 0x00?
00299    {  
00300       // (CMDT=EVPD <> 0) or (PAGE CODE <> 0x00)
00301       sbc_lun_status_is_cdb_field();
00302       return FALSE;
00303    }
00304 
00305    // Check the size of inquiry data
00306    allocation_length = g_scsi_command[4];
00307    if (allocation_length > SBC_MAX_INQUIRY_DATA)
00308    {
00309       allocation_length = SBC_MAX_INQUIRY_DATA;
00310    }
00311 
00312    // send first inquiry data (0 to 8)
00313    ptr = (code U8*) &sbc_std_inquiry_data;
00314 
00315    for ( i=0 ; ((i != 36) && (allocation_length > i)); i++)
00316    {
00317       if( 8 == i )
00318       {  // send vendor id (8 to 16)
00319            ptr = (code U8 *) &g_sbc_vendor_id;
00320       }
00321       if( 16 == i )
00322       {  // send product id (16 to 32)
00323          ptr = (code U8 *) &g_sbc_product_id;
00324       }
00325       if( 32 == i )
00326       {  // send revision id (32 to 36)
00327          ptr = (code U8 *) &g_sbc_revision_id;
00328       }
00329 #ifndef __GNUC__
00330       Usb_write_byte((U8)(*ptr++));
00331 #else    // AVRGCC does not support point to PGM space
00332 //warning with AVRGCC assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory
00333       Usb_write_byte(pgm_read_byte_near((unsigned int)ptr++));
00334 #endif
00335 
00336    }
00337    Sbc_valid_write_usb(i);
00338    sbc_lun_status_is_good();
00339    return TRUE;      
00340 }
00341 
00342 
00343 Bool sbc_test_unit_ready(void)
00344 {
00345    switch ( mem_test_unit_ready(usb_LUN) )
00346    {
00347       case CTRL_GOOD :
00348       sbc_lun_status_is_good();
00349       break;
00350 
00351       case CTRL_NO_PRESENT :
00352       sbc_lun_status_is_not_present();
00353       break;
00354 
00355       case CTRL_BUSY :
00356       sbc_lun_status_is_busy_or_change();
00357       break;
00358 
00359       case CTRL_FAIL :
00360       default :
00361       sbc_lun_status_is_fail();
00362       break;
00363    }
00364    return TRUE;
00365 }
00366 
00367 
00368 Bool sbc_read_capacity (void)
00369 {
00370    U32 mem_size_nb_sector;
00371 
00372    switch ( mem_read_capacity( usb_LUN, &mem_size_nb_sector ) )
00373    {
00374       case CTRL_GOOD :
00375       Usb_write_byte(MSB0(mem_size_nb_sector));    // return nb block
00376       Usb_write_byte(MSB1(mem_size_nb_sector));
00377       Usb_write_byte(MSB2(mem_size_nb_sector));
00378       Usb_write_byte(MSB3(mem_size_nb_sector));
00379       Usb_write_byte( 0               );           // return block size (= 512B)
00380       Usb_write_byte( 0               );
00381       Usb_write_byte( (U8)(512 >> 8)  );
00382       Usb_write_byte( (U8)(512 & 0xFF));
00383 
00384       Sbc_valid_write_usb(SBC_READ_CAPACITY_LENGTH);
00385       sbc_lun_status_is_good();
00386       break;
00387 
00388       case CTRL_NO_PRESENT :
00389       sbc_lun_status_is_not_present();
00390       break;
00391 
00392       case CTRL_BUSY :
00393       sbc_lun_status_is_busy_or_change();
00394       break;
00395 
00396       case CTRL_FAIL :
00397       default :
00398       sbc_lun_status_is_fail();
00399       break;
00400    }
00401    return TRUE;
00402 }
00403 
00404 
00405 Bool sbc_read_10 (void)
00406 {
00407    U32   mass_addr;                       // rd or wr block address
00408    U16   mass_size;                       // rd or write nb of blocks
00409 
00410    MSB0(mass_addr) = g_scsi_command[2];   // read address
00411    MSB1(mass_addr) = g_scsi_command[3];
00412    MSB2(mass_addr) = g_scsi_command[4];
00413    MSB3(mass_addr) = g_scsi_command[5];
00414 
00415    MSB(mass_size) = g_scsi_command[7];    // read size
00416    LSB(mass_size) = g_scsi_command[8];
00417    
00418    if( Is_usb_ms_data_direction_out() )
00419    {
00420       sbc_lun_status_is_cdb_field();
00421       return FALSE;
00422    }
00423    if( 0 == g_scsi_data_remaining )
00424    {
00425       if( mass_size == (g_scsi_data_remaining/512) )
00426       {
00427          sbc_lun_status_is_good();
00428       }else{
00429          sbc_lun_status_is_cdb_field();
00430       }
00431       return TRUE;
00432    }
00433 
00434    switch ( memory_2_usb( usb_LUN , mass_addr,  g_scsi_data_remaining/512 ) )
00435    {
00436       case CTRL_GOOD :
00437       if( mass_size == (g_scsi_data_remaining/512) )
00438       {
00439          sbc_lun_status_is_good();
00440       }else{
00441          sbc_lun_status_is_cdb_field();
00442       }
00443       g_scsi_data_remaining = 0;
00444       break;
00445 
00446       case CTRL_NO_PRESENT :
00447       sbc_lun_status_is_not_present();
00448       return FALSE;
00449       break;
00450 
00451       case CTRL_BUSY :
00452       sbc_lun_status_is_busy_or_change();
00453       return FALSE;
00454       break;
00455 
00456       case CTRL_FAIL :
00457       default :
00458       sbc_lun_status_is_fail();
00459       return FALSE;
00460       break;
00461    }
00462    return TRUE;
00463 }
00464 
00465 
00466 Bool sbc_write_10 (void)
00467 {
00468    U32   mass_addr;                       // rd or wr block address
00469    U16   mass_size;                       // rd or write nb of blocks
00470 
00471    MSB0(mass_addr) = g_scsi_command[2];   // read address
00472    MSB1(mass_addr) = g_scsi_command[3];
00473    MSB2(mass_addr) = g_scsi_command[4];
00474    MSB3(mass_addr) = g_scsi_command[5];
00475 
00476    MSB(mass_size) = g_scsi_command[7];    // read size
00477    LSB(mass_size) = g_scsi_command[8];
00478    
00479    if( 0 == g_scsi_data_remaining )
00480    {
00481       if( mass_size == (g_scsi_data_remaining/512) )
00482       {
00483          sbc_lun_status_is_good();
00484       }else{
00485          sbc_lun_status_is_cdb_field();
00486       }
00487       return TRUE;
00488    }
00489    
00490    if( TRUE == mem_wr_protect( usb_LUN ) )
00491    {
00493       sbc_lun_status_is_protected();
00494       return TRUE;
00495    }
00496 
00497    switch (usb_2_memory( usb_LUN , mass_addr, g_scsi_data_remaining/512 ))
00498    {
00499       case CTRL_GOOD :
00500       if( mass_size == (g_scsi_data_remaining/512) )
00501       {
00502          sbc_lun_status_is_good();
00503       }else{
00504          sbc_lun_status_is_cdb_field();
00505       }
00506       g_scsi_data_remaining = 0;
00507       break;
00508 
00509       case CTRL_NO_PRESENT :
00510       sbc_lun_status_is_not_present();
00511       return FALSE;
00512       break;
00513 
00514       case CTRL_BUSY :
00515       sbc_lun_status_is_busy_or_change();
00516       return FALSE;
00517       break;
00518 
00519       case CTRL_FAIL :
00520       default :
00521       sbc_lun_status_is_fail();
00522       return FALSE;
00523       break;
00524    }
00525    return TRUE;
00526 }
00527 
00528 
00543 Bool sbc_mode_sense( Bool b_sense_10 )
00544 {
00545    U8 allocation_length;
00546 
00547    if( b_sense_10 )
00548       allocation_length = g_scsi_command[8];
00549    else
00550       allocation_length = g_scsi_command[4];
00551 
00552    // switch for page code
00553    switch ( g_scsi_command[2] & SBC_MSK_PAGE_CODE )
00554    {
00555       case SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS:
00556       sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS );
00557       send_informational_exceptions_page();
00558       Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS + 1);
00559       break;
00560 
00561       case SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY:
00562       sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY );
00563       send_read_write_error_recovery_page(allocation_length);
00564       Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY + 1);
00565       break;
00566 
00567       case SBC_PAGE_CODE_ALL:
00568       sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_CODE_ALL );
00569       if( b_sense_10 )
00570       {
00571          if (allocation_length == 8)
00572          {
00573             Sbc_valid_write_usb(8);
00574             break;
00575          }
00576       }
00577       else
00578       {
00579          if (allocation_length == 4)
00580          {
00581             Sbc_valid_write_usb(4);
00582             break;
00583          }
00584       }
00585       // send page by ascending order code
00586       send_read_write_error_recovery_page(allocation_length);  // 12 bytes
00587       if (allocation_length > 12)
00588       {
00589          send_informational_exceptions_page();                 // 12 bytes
00590          Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_CODE_ALL + 1);
00591       }
00592       else
00593       {
00594          Sbc_valid_write_usb(allocation_length);
00595       }
00596       break;
00597 
00598       default:
00599       sbc_lun_status_is_cdb_field();
00600       return TRUE;
00601       break;
00602    }
00603    sbc_lun_status_is_good();
00604    return TRUE;
00605 }
00606 
00607 
00615 void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length )
00616 {
00617    // Send Data length
00618    if( b_sense_10 )
00619    {
00620       Usb_write_byte(0);
00621    }
00622    Usb_write_byte( u8_data_length );
00623 
00624    // Send device type
00625    Usb_write_byte(SBC_MEDIUM_TYPE);
00626 
00627    // Write protect status
00628    if (mem_wr_protect( usb_LUN ))
00629    {
00630       Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_PROTECT);  // Device is write protected
00631    }
00632    else
00633    {
00634       Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_ENABLE);   // Device is write enabled
00635    }
00636 
00637    if( b_sense_10 )
00638    {  // Reserved
00639       Usb_write_byte(0);
00640       Usb_write_byte(0);
00641    }
00642 
00643    // Send Block descriptor length
00644    if( b_sense_10 )
00645    {
00646       Usb_write_byte(0);
00647    }
00648    Usb_write_byte(SBC_BLOCK_DESCRIPTOR_LENGTH);
00649 }
00650 
00651 
00663 void send_informational_exceptions_page (void)
00664 {
00665    Usb_write_byte(SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS);     // Page Code: Informational exceptions control page
00666                                                                // See chapter 8.3.8 on SPC-2 specification
00667    Usb_write_byte(SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS);   // Page Length
00668    Usb_write_byte(0x00);                                       // ..., Test bit = 0, ...
00669    Usb_write_byte(SBC_MRIE);                                   // MRIE = 0x05
00670    Usb_write_byte(0x00);                                       // Interval Timer (MSB)
00671    Usb_write_byte(0x00);
00672    Usb_write_byte(0x00);
00673    Usb_write_byte(0x00);                                       // Interval Timer (LSB)
00674    Usb_write_byte(0x00);                                       // Report Count (MSB)
00675    Usb_write_byte(0x00);
00676    Usb_write_byte(0x00);
00677    Usb_write_byte(0x01);                                       // Report Count (LSB)
00678 }
00679 
00680 
00692 void send_read_write_error_recovery_page (U8 length)
00693 {
00694    Usb_write_byte(SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY);
00695 
00696    Usb_write_byte(SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY);   // Page Length
00697    Usb_write_byte(0x80);
00698    Usb_write_byte(SBC_READ_RETRY_COUNT);
00699    Usb_write_byte(SBC_CORRECTION_SPAN);
00700    Usb_write_byte(SBC_HEAD_OFFSET_COUNT);
00701    Usb_write_byte(SBC_DATA_STROBE_OFFSET);
00702    Usb_write_byte(0x00);   // Reserved
00703 
00704    if (length > 12)
00705    {
00706       Usb_write_byte(SBC_WRITE_RETRY_COUNT);
00707       Usb_write_byte(0x00);
00708       Usb_write_byte(SBC_RECOVERY_LIMIT_MSB);
00709       Usb_write_byte(SBC_RECOVERY_LIMIT_LSB);
00710    }
00711 }
00712 
00728 Bool sbc_prevent_allow_medium_removal(void)
00729 {
00730    sbc_lun_status_is_good();
00731    return TRUE;
00732 }
00733 
00734 
00737 void sbc_lun_status_is_good(void)
00738 {
00739    Sbc_send_good();
00740    Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00741 }
00742 
00745 void sbc_lun_status_is_not_present(void)
00746 {
00747    Sbc_send_failed();
00748    Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);
00749 }
00750 
00753 void sbc_lun_status_is_busy_or_change(void)
00754 {
00755    Sbc_send_failed();
00756    Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );
00757 }
00758 
00761 void sbc_lun_status_is_fail(void)
00762 {
00763    Sbc_send_failed();
00764    Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00765 }
00766 
00769 void sbc_lun_status_is_protected(void)
00770 {
00771    Sbc_send_failed();
00772    Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);
00773 }
00774 
00777 void sbc_lun_status_is_cdb_field(void)
00778 {
00779    Sbc_send_failed();
00780    Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
00781 }
00782 

Generated on Fri Oct 31 15:08:58 2008 for ATMEL by  doxygen 1.5.3