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 }

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