00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 #include "config.h"
00051 #include "storage/scsi_decoder.h"
00052 #include "conf_usb.h"
00053 #include "usb_drv.h"                   
00054 #include "storage/ctrl_status.h"
00055 #include "storage/ctrl_access.h"
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 U8  g_scsi_command[16];
00065 U8  g_scsi_status;
00066 U32 g_scsi_data_remaining;
00067 
00068 FLASH U8    g_sbc_vendor_id[8]   = SBC_VENDOR_ID;
00069 FLASH U8    g_sbc_product_id[16] = SBC_PRODUCT_ID;
00070 FLASH U8    g_sbc_revision_id[4] = SBC_REVISION_ID;
00071 
00072 extern  U8  usb_LUN;
00073 
00074  s_scsi_sense  g_scsi_sense;
00075 
00076 
00077 FLASH struct sbc_st_std_inquiry_data sbc_std_inquiry_data =
00078 {
00079    
00080    0x00,        
00081    0,           
00082 
00083    
00084    0,           
00085    1,           
00086 
00087  
00088  
00089 
00090    
00091    0x00,        
00092 
00093    
00094    2,           
00095    0,           
00096    0,           
00097    0,           
00098 
00099    
00100    
00101    
00102                 
00103    {
00104       0x1F,     
00105       0,        
00106       0
00107    },
00108 
00109    
00110    0,          
00111    0,          
00112    0,          
00113    0,          
00114    0,          
00115    0,          
00116    0,          
00117    0,          
00118 };
00119 
00120 
00121 static  void  send_informational_exceptions_page (void);
00122 static  void  send_read_write_error_recovery_page (U8);
00123 static  void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length );
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 
00138 Bool scsi_decode_command(void)
00139 {
00140 Bool status;
00141 
00142    if (g_scsi_command[0] == SBC_CMD_WRITE_10)
00143    {
00144       Scsi_start_write_action();
00145       status = sbc_write_10();
00146           Scsi_stop_write_action();
00147       return status;
00148    }
00149    if (g_scsi_command[0] == SBC_CMD_READ_10 )
00150    {
00151       Scsi_start_read_action();
00152       status = sbc_read_10();
00153       Scsi_stop_read_action();
00154       return status;
00155    }
00156 
00157    switch (g_scsi_command[0])                
00158    {
00159       case SBC_CMD_REQUEST_SENSE:             
00160            return sbc_request_sense();
00161            break;
00162 
00163       case SBC_CMD_INQUIRY:                   
00164            return sbc_inquiry();
00165            break;
00166 
00167       case SBC_CMD_TEST_UNIT_READY:           
00168            return sbc_test_unit_ready();
00169            break;
00170 
00171       case SBC_CMD_READ_CAPACITY:             
00172            return sbc_read_capacity();
00173            break;
00174 
00175       case SBC_CMD_MODE_SENSE_6:              
00176            return sbc_mode_sense( FALSE );
00177            break;
00178 
00179       case SBC_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
00180            return sbc_prevent_allow_medium_removal();
00181            break;
00182 
00183       case SBC_CMD_VERIFY_10:                 
00184            sbc_lun_status_is_good();
00185            break;
00186       case SBC_CMD_MODE_SENSE_10:             
00187            return sbc_mode_sense( TRUE );
00188            break;
00189 
00190       case SBC_CMD_FORMAT_UNIT:               
00191 
00192       case SBC_CMD_MODE_SELECT_6:             
00193 
00194 
00195 
00196 
00197       case SBC_CMD_START_STOP_UNIT:           
00198       case SBC_CMD_SEND_DIAGNOSTIC:           
00199       case SBC_CMD_READ_LONG:                 
00200       case SBC_CMD_SYNCHRONIZE_CACHE:         
00201       case SBC_CMD_WRITE_BUFFER:              
00202       case SBC_CMD_RESERVE_10:                
00203       case SBC_CMD_RELEASE_10:                
00204       default:
00205            { 
00206               Sbc_send_failed();
00207               Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_COMMAND_OPERATION_CODE, 0x00);
00208               return FALSE;
00209               break;
00210            }
00211    }
00212    return TRUE;
00213 }
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 Bool sbc_request_sense (void)
00232 {
00233   U8  allocation_length, i;
00234   U8  request_sens_output[18];   
00235 
00236   allocation_length = g_scsi_command[4];  
00237 
00238   
00239   request_sens_output[0] = SBC_RESPONSE_CODE_SENSE; 
00240   request_sens_output[1] = 0x00;                    
00241   request_sens_output[2] = g_scsi_sense.key;
00242 
00243   request_sens_output[3] = 0x00;   
00244   request_sens_output[4] = 0x00;   
00245   request_sens_output[5] = 0x00;   
00246   request_sens_output[6] = 0x00;
00247 
00248   request_sens_output[7] = SBC_ADDITIONAL_SENSE_LENGTH; 
00249   request_sens_output[8] = SBC_COMMAND_SPECIFIC_INFORMATION_3;
00250   request_sens_output[9] = SBC_COMMAND_SPECIFIC_INFORMATION_2;
00251   request_sens_output[10] = SBC_COMMAND_SPECIFIC_INFORMATION_1;
00252   request_sens_output[11] = SBC_COMMAND_SPECIFIC_INFORMATION_0;
00253 
00254   request_sens_output[12] = g_scsi_sense.asc;
00255   request_sens_output[13] = g_scsi_sense.ascq;
00256 
00257   request_sens_output[14] = SBC_FIELD_REPLACEABLE_UNIT_CODE;
00258   request_sens_output[15] = SBC_SENSE_KEY_SPECIFIC_2;
00259   request_sens_output[16] = SBC_SENSE_KEY_SPECIFIC_1;
00260   request_sens_output[17] = SBC_SENSE_KEY_SPECIFIC_0;
00261 
00262   
00263   for( i=0 ; i<allocation_length ; i++ )
00264   {
00265     Usb_write_byte( request_sens_output[i] );
00266   }
00267   Sbc_valid_write_usb( allocation_length );
00268 
00269   sbc_lun_status_is_good();
00270 
00271   return TRUE;
00272 }
00273 
00274 
00275 
00276 
00277 
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 Bool sbc_inquiry (void)
00292 {
00293    U8 allocation_length, i;
00294 
00295 #ifdef AVRGCC
00296    PGM_VOID_P ptr;
00297 #else
00298    U8 FLASH *ptr;
00299 #endif
00300 
00301    if( (0 == (g_scsi_command[1] & 0x03) )    
00302    &&  (0 ==  g_scsi_command[2]         ) )  
00303    {
00304       
00305 
00306       
00307       allocation_length = g_scsi_command[4];
00308       if (allocation_length > SBC_MAX_INQUIRY_DATA)
00309       {
00310          allocation_length = SBC_MAX_INQUIRY_DATA;
00311       }
00312 
00313       
00314       ptr = (FLASH U8*) &sbc_std_inquiry_data;
00315 
00316       for ( i=0 ; ((i != 36) && (allocation_length > i)); i++)
00317       {
00318          if( 8 == i )
00319          {  
00320               ptr = (FLASH U8 *) &g_sbc_vendor_id;
00321          }
00322          if( 16 == i )
00323          {  
00324             ptr = (FLASH U8 *) &g_sbc_product_id;
00325          }
00326          if( 32 == i )
00327          {  
00328             ptr = (FLASH U8 *) &g_sbc_revision_id;
00329          }
00330 #ifndef AVRGCC
00331          Usb_write_byte((U8)(*ptr++));     
00332 #else    // AVRGCC does not support point to PGM space
00333 #warning with avrgcc assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory
00334          Usb_write_byte(pgm_read_byte_near((unsigned int)ptr++));
00335 #endif
00336 
00337       }
00338 
00339       
00340       
00341       
00342       
00343       
00344       
00345       
00346       
00347       
00348       
00349       
00350       
00351       while( allocation_length > i )
00352       {
00353          if (64 == i)
00354          {  
00355             Sbc_valid_write_usb(64);
00356             allocation_length -= 64;
00357             i = 0;
00358          }
00359          Usb_write_byte(0);       
00360          i++;
00361       }
00362       
00363       Sbc_valid_write_usb(allocation_length);
00364       sbc_lun_status_is_good();
00365       return TRUE;
00366    }
00367    else
00368    {  
00369       Sbc_send_failed();
00370       Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
00371       return FALSE;
00372    }
00373 }
00374 
00375 
00376 Bool sbc_test_unit_ready(void)
00377 {
00378    switch ( mem_test_unit_ready(usb_LUN) )
00379    {
00380    case CTRL_GOOD :
00381       sbc_lun_status_is_good();
00382       break;
00383 
00384    case CTRL_NO_PRESENT :
00385       sbc_lun_status_is_not_present();
00386       break;
00387 
00388    case CTRL_BUSY :
00389       sbc_lun_status_is_busy_or_change();
00390       break;
00391 
00392    case CTRL_FAIL :
00393    default :
00394       sbc_lun_status_is_fail();
00395       break;
00396    }
00397    return TRUE;
00398 }
00399 
00400 
00401 Bool sbc_read_capacity (void)
00402 {
00403    _MEM_TYPE_SLOW_ U32 mem_size_nb_sector;
00404 
00405    switch ( mem_read_capacity( usb_LUN, &mem_size_nb_sector ) )
00406    {
00407    case CTRL_GOOD :
00408       Usb_write_byte(MSB0(mem_size_nb_sector));  
00409       Usb_write_byte(MSB1(mem_size_nb_sector));
00410       Usb_write_byte(MSB2(mem_size_nb_sector));
00411       Usb_write_byte(MSB3(mem_size_nb_sector));
00412       Usb_write_byte( 0               );        
00413       Usb_write_byte( 0               );
00414       Usb_write_byte( (U8)(512 >> 8)  );
00415       Usb_write_byte( (U8)(512 & 0xFF));
00416 
00417       Sbc_valid_write_usb(SBC_READ_CAPACITY_LENGTH);
00418       sbc_lun_status_is_good();
00419       return TRUE;
00420       break;
00421 
00422    case CTRL_NO_PRESENT :
00423       sbc_lun_status_is_not_present();
00424       break;
00425 
00426    case CTRL_BUSY :
00427       sbc_lun_status_is_busy_or_change();
00428       break;
00429 
00430    case CTRL_FAIL :
00431    default :
00432       sbc_lun_status_is_fail();
00433       break;
00434    }
00435    return FALSE;
00436 }
00437 
00438 
00439 Bool sbc_read_10 (void)
00440 {
00441    U32   mass_addr;                    
00442    U16   mass_size;                    
00443 
00444    MSB0(mass_addr) = g_scsi_command[2];  
00445    MSB1(mass_addr) = g_scsi_command[3];
00446    MSB2(mass_addr) = g_scsi_command[4];
00447    MSB3(mass_addr) = g_scsi_command[5];
00448 
00449    MSB(mass_size) = g_scsi_command[7];  
00450    LSB(mass_size) = g_scsi_command[8];
00451 
00452    if (mass_size != 0)
00453    {
00454       switch ( memory_2_usb( usb_LUN , mass_addr, mass_size ) )
00455       {
00456       case CTRL_GOOD :
00457          sbc_lun_status_is_good();
00458          g_scsi_data_remaining = g_scsi_data_remaining - (512 * (Uint32)mass_size);
00459          return TRUE;
00460          break;
00461 
00462       case CTRL_NO_PRESENT :
00463          sbc_lun_status_is_not_present();
00464          return FALSE;
00465          break;
00466 
00467       case CTRL_BUSY :
00468          sbc_lun_status_is_busy_or_change();
00469          return FALSE;
00470          break;
00471 
00472       case CTRL_FAIL :
00473       default :
00474          sbc_lun_status_is_fail();
00475          return FALSE;
00476          break;
00477       }
00478    }
00479    else
00480    {  
00481       sbc_lun_status_is_good();
00482    }
00483    return TRUE;
00484 }
00485 
00486 
00487 Bool sbc_write_10 (void)
00488 {
00489    U32   mass_addr;                    
00490    U16   mass_size;                    
00491 
00492    MSB0(mass_addr) = g_scsi_command[2];  
00493    MSB1(mass_addr) = g_scsi_command[3];
00494    MSB2(mass_addr) = g_scsi_command[4];
00495    MSB3(mass_addr) = g_scsi_command[5];
00496 
00497    MSB(mass_size) = g_scsi_command[7];  
00498    LSB(mass_size) = g_scsi_command[8];
00499 
00500    if (mass_size != 0)
00501    {
00502       if( TRUE == mem_wr_protect( usb_LUN ) )
00503       {
00504          sbc_lun_status_is_protected();
00505          return FALSE;
00506 #warning For Win98 data must be read to avoid blocking
00507       }
00508       else
00509       {
00510          switch (usb_2_memory( usb_LUN , mass_addr, mass_size ))
00511          {
00512          case CTRL_GOOD :
00513             sbc_lun_status_is_good();
00514             g_scsi_data_remaining = g_scsi_data_remaining - (512 * (Uint32)mass_size);
00515             return TRUE;
00516             break;
00517 
00518          case CTRL_NO_PRESENT :
00519             sbc_lun_status_is_not_present();
00520             return FALSE;
00521             break;
00522 
00523          case CTRL_BUSY :
00524             sbc_lun_status_is_busy_or_change();
00525             return FALSE;
00526             break;
00527 
00528          case CTRL_FAIL :
00529          default :
00530             sbc_lun_status_is_fail();
00531             return FALSE;
00532             break;
00533          }
00534       }
00535    }
00536    else
00537    {  
00538       sbc_lun_status_is_good();
00539    }
00540    return TRUE;
00541 }
00542 
00543 
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557 
00558 Bool sbc_mode_sense( Bool b_sense_10 )
00559 {
00560    U8 allocation_length;
00561 
00562    if( b_sense_10 )
00563       allocation_length = g_scsi_command[8];
00564    else
00565       allocation_length = g_scsi_command[4];
00566 
00567    
00568    switch ( g_scsi_command[2] & SBC_MSK_PAGE_CODE )
00569    {
00570       case SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS:       
00571          sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS );
00572          send_informational_exceptions_page();
00573          Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS + 1);
00574          break;
00575 
00576       case SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY:
00577          sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY );
00578          send_read_write_error_recovery_page(allocation_length);
00579          Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY + 1);
00580          break;
00581 
00582       case SBC_PAGE_CODE_ALL:
00583          sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_CODE_ALL );
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          
00601          send_read_write_error_recovery_page(allocation_length);  
00602          if (allocation_length > 12)
00603          {
00604             send_informational_exceptions_page();                 
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_send_failed();
00615            Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
00616            return FALSE;
00617            break;
00618    }
00619    sbc_lun_status_is_good();
00620    return TRUE;
00621 }
00622 
00623 
00624 
00625 
00626 
00627 
00628 
00629 
00630 
00631 void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length )
00632 {
00633    
00634    if( b_sense_10 )
00635    {
00636       Usb_write_byte(0);
00637    }
00638    Usb_write_byte( u8_data_length );
00639 
00640    
00641    Usb_write_byte(SBC_MEDIUM_TYPE);
00642 
00643    
00644    if (mem_wr_protect( usb_LUN ))
00645    {
00646       Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_PROTECT);  
00647    }
00648    else
00649    {
00650       Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_ENABLE);   
00651    }
00652 
00653    if( b_sense_10 )
00654    {  
00655       Usb_write_byte(0);
00656       Usb_write_byte(0);
00657    }
00658 
00659    
00660    if( b_sense_10 )
00661    {
00662       Usb_write_byte(0);
00663    }
00664    Usb_write_byte(SBC_BLOCK_DESCRIPTOR_LENGTH);
00665 }
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673 
00674 
00675 
00676 
00677 void send_informational_exceptions_page (void)
00678 {
00679    Usb_write_byte(SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS);     
00680                                                                
00681    Usb_write_byte(SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS);   
00682    Usb_write_byte(0x00);                                       
00683    Usb_write_byte(SBC_MRIE);                                   
00684    Usb_write_byte(0x00);                                       
00685    Usb_write_byte(0x00);
00686    Usb_write_byte(0x00);
00687    Usb_write_byte(0x00);                                       
00688    Usb_write_byte(0x00);                                       
00689    Usb_write_byte(0x00);
00690    Usb_write_byte(0x00);
00691    Usb_write_byte(0x01);                                       
00692 }
00693 
00694 
00695 
00696 
00697 
00698 
00699 
00700 
00701 
00702 
00703 
00704 
00705 
00706 void send_read_write_error_recovery_page (U8 length)
00707 {
00708    Usb_write_byte(SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY);
00709 
00710    Usb_write_byte(SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY);   
00711    Usb_write_byte(0x80);
00712    Usb_write_byte(SBC_READ_RETRY_COUNT);
00713    Usb_write_byte(SBC_CORRECTION_SPAN);
00714    Usb_write_byte(SBC_HEAD_OFFSET_COUNT);
00715    Usb_write_byte(SBC_DATA_STROBE_OFFSET);
00716    Usb_write_byte(0x00);   
00717 
00718    if (length > 12)
00719    {
00720       Usb_write_byte(SBC_WRITE_RETRY_COUNT);
00721       Usb_write_byte(0x00);
00722       Usb_write_byte(SBC_RECOVERY_LIMIT_MSB);
00723       Usb_write_byte(SBC_RECOVERY_LIMIT_LSB);
00724    }
00725 }
00726 
00727 
00728 
00729 
00730 
00731 
00732 
00733 
00734 
00735 
00736 
00737 
00738 
00739 
00740 Bool sbc_prevent_allow_medium_removal(void)
00741 {
00742    sbc_lun_status_is_good();
00743    return TRUE;
00744 }
00745 
00746 
00747 
00748 
00749 void sbc_lun_status_is_good(void)
00750 {
00751    Sbc_send_good();
00752    Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00753 }
00754 
00755 
00756 
00757 void sbc_lun_status_is_not_present(void)
00758 {
00759    Sbc_send_failed();
00760    Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);
00761 }
00762 
00763 
00764 
00765 void sbc_lun_status_is_busy_or_change(void)
00766 {
00767    Sbc_send_failed();
00768    Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );
00769 }
00770 
00771 
00772 
00773 void sbc_lun_status_is_fail(void)
00774 {
00775    Sbc_send_failed();
00776    Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00777 }
00778 
00779 
00780 
00781 void sbc_lun_status_is_protected(void)
00782 {
00783    Sbc_send_failed();
00784    Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);
00785 }
00786 
00787