00001
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 #include "config.h"
00049 #include "scsi_decoder.h"
00050 #include "storage_task.h"
00051 #include "conf_usb.h"
00052 #include "lib_mcu/usb/usb_drv.h"
00053 #include "modules/control_access/ctrl_status.h"
00054 #include "modules/control_access/ctrl_access.h"
00055
00056
00057
00058
00059 U8 g_scsi_command[16];
00060 U8 g_scsi_status;
00061 U32 g_scsi_data_remaining;
00062
00063 code U8 g_sbc_vendor_id[8] = SBC_VENDOR_ID;
00064 code U8 g_sbc_product_id[16] = SBC_PRODUCT_ID;
00065 code U8 g_sbc_revision_id[4] = SBC_REVISION_ID;
00066
00067 extern U8 usb_LUN;
00068 extern bit ms_data_direction;
00069 s_scsi_sense g_scsi_sense;
00070
00071
00072 code struct sbc_st_std_inquiry_data sbc_std_inquiry_data =
00073 {
00074
00075 0x00,
00076 0,
00077
00078
00079 0,
00080 1,
00081
00082
00083 0x03,
00084
00085
00086
00087
00088
00089
00090 2,
00091 0,
00092 0,
00093 0,
00094
00095
00096
00097
00098
00099 {
00100 0x1F,
00101 0,
00102 0
00103 },
00104
00105
00106 0,
00107 0,
00108 0,
00109 0,
00110 0,
00111 0,
00112 0,
00113 0,
00114 };
00115
00116
00117 static void send_informational_exceptions_page (void);
00118 static void send_read_write_error_recovery_page (U8);
00119 static void sbc_header_mode_sense ( Bool b_sense_10 , U8 u8_data_length );
00120
00121
00122
00123
00124
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
00187 case SBC_CMD_MODE_SENSE_10:
00188 return sbc_mode_sense( TRUE );
00189 break;
00190
00191 case SBC_CMD_START_STOP_UNIT:
00192 sbc_lun_status_is_good();
00193 break;
00194
00195 case SBC_CMD_FORMAT_UNIT:
00196 case SBC_CMD_MODE_SELECT_6:
00197 case SBC_CMD_SEND_DIAGNOSTIC:
00198 case SBC_CMD_READ_LONG:
00199 case SBC_CMD_SYNCHRONIZE_CACHE:
00200 case SBC_CMD_WRITE_BUFFER:
00201 case SBC_CMD_RESERVE_10:
00202 case SBC_CMD_RELEASE_10:
00203 default:
00204
00205 Sbc_send_failed();
00206 Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_COMMAND_OPERATION_CODE, 0x00);
00207 return FALSE;
00208 break;
00209 }
00210 return TRUE;
00211 }
00212
00213
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 if( allocation_length > 18 )
00238 {
00239 allocation_length = 18;
00240 }
00241
00242 request_sens_output[0] = SBC_RESPONSE_CODE_SENSE;
00243 request_sens_output[1] = 0x00;
00244 request_sens_output[2] = g_scsi_sense.key;
00245
00246 request_sens_output[3] = 0x00;
00247 request_sens_output[4] = 0x00;
00248 request_sens_output[5] = 0x00;
00249 request_sens_output[6] = 0x00;
00250
00251 request_sens_output[7] = SBC_ADDITIONAL_SENSE_LENGTH;
00252 request_sens_output[8] = SBC_COMMAND_SPECIFIC_INFORMATION_3;
00253 request_sens_output[9] = SBC_COMMAND_SPECIFIC_INFORMATION_2;
00254 request_sens_output[10] = SBC_COMMAND_SPECIFIC_INFORMATION_1;
00255 request_sens_output[11] = SBC_COMMAND_SPECIFIC_INFORMATION_0;
00256
00257 request_sens_output[12] = g_scsi_sense.asc;
00258 request_sens_output[13] = g_scsi_sense.ascq;
00259
00260 request_sens_output[14] = SBC_FIELD_REPLACEABLE_UNIT_CODE;
00261 request_sens_output[15] = SBC_SENSE_KEY_SPECIFIC_2;
00262 request_sens_output[16] = SBC_SENSE_KEY_SPECIFIC_1;
00263 request_sens_output[17] = SBC_SENSE_KEY_SPECIFIC_0;
00264
00265
00266 for( i=0 ; i<allocation_length ; i++ )
00267 {
00268 Usb_write_byte( request_sens_output[i] );
00269 }
00270 Sbc_valid_write_usb( allocation_length );
00271
00272 sbc_lun_status_is_good();
00273 return TRUE;
00274 }
00275
00276
00296 Bool sbc_inquiry (void)
00297 {
00298 U8 allocation_length, i;
00299
00300 #ifdef __GNUC__
00301 PGM_VOID_P ptr;
00302 #else
00303 U8 code *ptr;
00304 #endif
00305
00306 if( (0 != (g_scsi_command[1] & 0x03) )
00307 || (0 != g_scsi_command[2] ) )
00308 {
00309
00310
00311 sbc_lun_status_is_cdb_field();
00312 return FALSE;
00313 }
00314
00315
00316
00317 allocation_length = g_scsi_command[4];
00318 if (allocation_length > SBC_MAX_INQUIRY_DATA)
00319 {
00320 allocation_length = SBC_MAX_INQUIRY_DATA;
00321 }
00322
00323
00324 ptr = (code U8*) &sbc_std_inquiry_data;
00325
00326 for ( i=0 ; ((i != 36) && (allocation_length > i)); i++)
00327 {
00328 if( 8 == i )
00329 {
00330 ptr = (code U8 *) &g_sbc_vendor_id;
00331 }
00332 if( 16 == i )
00333 {
00334 ptr = (code U8 *) &g_sbc_product_id;
00335 }
00336 if( 32 == i )
00337 {
00338 ptr = (code U8 *) &g_sbc_revision_id;
00339 }
00340 #ifndef __GNUC__
00341 Usb_write_byte((U8)(*ptr++));
00342 #else // AVRGCC does not support point to PGM space
00343 Usb_write_byte(pgm_read_byte_near((unsigned int)ptr++));
00344 #endif
00345
00346 }
00347 Sbc_valid_write_usb(i);
00348 sbc_lun_status_is_good();
00349 return TRUE;
00350 }
00351
00352
00353 Bool sbc_test_unit_ready(void)
00354 {
00355 switch ( mem_test_unit_ready(usb_LUN) )
00356 {
00357 case CTRL_GOOD :
00358 sbc_lun_status_is_good();
00359 break;
00360
00361 case CTRL_NO_PRESENT :
00362 sbc_lun_status_is_not_present();
00363 break;
00364
00365 case CTRL_BUSY :
00366 sbc_lun_status_is_busy_or_change();
00367 break;
00368
00369 case CTRL_FAIL :
00370 default :
00371 sbc_lun_status_is_fail();
00372 break;
00373 }
00374 return TRUE;
00375 }
00376
00377
00378 Bool sbc_read_capacity (void)
00379 {
00380 U32 mem_size_nb_sector;
00381
00382 switch ( mem_read_capacity( usb_LUN, &mem_size_nb_sector ) )
00383 {
00384 case CTRL_GOOD :
00385 Usb_write_byte(MSB0(mem_size_nb_sector));
00386 Usb_write_byte(MSB1(mem_size_nb_sector));
00387 Usb_write_byte(MSB2(mem_size_nb_sector));
00388 Usb_write_byte(MSB3(mem_size_nb_sector));
00389 Usb_write_byte( 0 );
00390 Usb_write_byte( 0 );
00391 Usb_write_byte( (U8)(512 >> 8) );
00392 Usb_write_byte( (U8)(512 & 0xFF));
00393
00394 Sbc_valid_write_usb(SBC_READ_CAPACITY_LENGTH);
00395 sbc_lun_status_is_good();
00396 return TRUE;
00397 break;
00398
00399 case CTRL_NO_PRESENT :
00400 sbc_lun_status_is_not_present();
00401 break;
00402
00403 case CTRL_BUSY :
00404 sbc_lun_status_is_busy_or_change();
00405 break;
00406
00407 case CTRL_FAIL :
00408 default :
00409 sbc_lun_status_is_fail();
00410 break;
00411 }
00412 return FALSE;
00413 }
00414
00415
00416 Bool sbc_read_10 (void)
00417 {
00418 U32 mass_addr;
00419 U16 mass_size;
00420
00421 MSB0(mass_addr) = g_scsi_command[2];
00422 MSB1(mass_addr) = g_scsi_command[3];
00423 MSB2(mass_addr) = g_scsi_command[4];
00424 MSB3(mass_addr) = g_scsi_command[5];
00425
00426 MSB(mass_size) = g_scsi_command[7];
00427 LSB(mass_size) = g_scsi_command[8];
00428
00429 if( Is_usb_ms_data_direction_out() )
00430 {
00431 sbc_lun_status_is_cdb_field();
00432 return FALSE;
00433 }
00434 if( 0 == g_scsi_data_remaining )
00435 {
00436 if( mass_size == (g_scsi_data_remaining/512) )
00437 {
00438 sbc_lun_status_is_good();
00439 }else{
00440 sbc_lun_status_is_cdb_field();
00441 }
00442 return TRUE;
00443 }
00444
00445 switch ( memory_2_usb( usb_LUN , mass_addr, g_scsi_data_remaining/512 ) )
00446 {
00447 case CTRL_GOOD :
00448 if( mass_size == (g_scsi_data_remaining/512) )
00449 {
00450 sbc_lun_status_is_good();
00451 }else{
00452 sbc_lun_status_is_cdb_field();
00453 }
00454 g_scsi_data_remaining = 0;
00455 break;
00456
00457 case CTRL_NO_PRESENT :
00458 sbc_lun_status_is_not_present();
00459 return FALSE;
00460 break;
00461
00462 case CTRL_BUSY :
00463 sbc_lun_status_is_busy_or_change();
00464 return FALSE;
00465 break;
00466
00467 case CTRL_FAIL :
00468 default :
00469 sbc_lun_status_is_fail();
00470 return FALSE;
00471 break;
00472 }
00473 return TRUE;
00474 }
00475
00476
00477 Bool sbc_write_10 (void)
00478 {
00479 U32 mass_addr;
00480 U16 mass_size;
00481
00482 MSB0(mass_addr) = g_scsi_command[2];
00483 MSB1(mass_addr) = g_scsi_command[3];
00484 MSB2(mass_addr) = g_scsi_command[4];
00485 MSB3(mass_addr) = g_scsi_command[5];
00486
00487 MSB(mass_size) = g_scsi_command[7];
00488 LSB(mass_size) = g_scsi_command[8];
00489
00490 if( Is_usb_ms_data_direction_in() )
00491 {
00492 sbc_lun_status_is_cdb_field();
00493 return FALSE;
00494 }
00495
00496 if( 0 == g_scsi_data_remaining )
00497 {
00498 if( mass_size == (g_scsi_data_remaining/512) )
00499 {
00500 sbc_lun_status_is_good();
00501 }else{
00502 sbc_lun_status_is_cdb_field();
00503 }
00504 return TRUE;
00505 }
00506
00507 if( TRUE == mem_wr_protect( usb_LUN ) )
00508 {
00509 sbc_lun_status_is_protected();
00510 return FALSE;
00511 }
00512
00513 switch (usb_2_memory( usb_LUN , mass_addr, g_scsi_data_remaining/512 ))
00514 {
00515 case CTRL_GOOD :
00516 if( mass_size == (g_scsi_data_remaining/512) )
00517 {
00518 sbc_lun_status_is_good();
00519 }else{
00520 sbc_lun_status_is_cdb_field();
00521 }
00522 g_scsi_data_remaining = 0;
00523 break;
00524
00525 case CTRL_NO_PRESENT :
00526 sbc_lun_status_is_not_present();
00527 return FALSE;
00528 break;
00529
00530 case CTRL_BUSY :
00531 sbc_lun_status_is_busy_or_change();
00532 return FALSE;
00533 break;
00534
00535 case CTRL_FAIL :
00536 default :
00537 sbc_lun_status_is_fail();
00538 return FALSE;
00539 break;
00540 }
00541 return TRUE;
00542 }
00543
00544
00559 Bool sbc_mode_sense( Bool b_sense_10 )
00560 {
00561 U8 allocation_length;
00562
00563 if( b_sense_10 )
00564 allocation_length = g_scsi_command[8];
00565 else
00566 allocation_length = g_scsi_command[4];
00567
00568
00569 switch ( g_scsi_command[2] & SBC_MSK_PAGE_CODE )
00570 {
00571 case SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS:
00572 sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS );
00573 send_informational_exceptions_page();
00574 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS + 1);
00575 break;
00576
00577 case SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY:
00578 sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY );
00579 send_read_write_error_recovery_page(allocation_length);
00580 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY + 1);
00581 break;
00582
00583 case SBC_PAGE_CODE_ALL:
00584 if( b_sense_10 ) {
00585 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 );
00586 }else{
00587 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 );
00588 }
00589 if( b_sense_10 )
00590 {
00591 if (allocation_length == 8)
00592 {
00593 Sbc_valid_write_usb(8);
00594 break;
00595 }
00596 }
00597 else
00598 {
00599 if (allocation_length == 4)
00600 {
00601 Sbc_valid_write_usb(4);
00602 break;
00603 }
00604 }
00605
00606 send_read_write_error_recovery_page(allocation_length);
00607 if (allocation_length > 12)
00608 {
00609 send_informational_exceptions_page();
00610 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_CODE_ALL + 1);
00611 }
00612 else
00613 {
00614 Sbc_valid_write_usb(allocation_length);
00615 }
00616 break;
00617
00618 default:
00619 sbc_lun_status_is_cdb_field();
00620 return FALSE;
00621 break;
00622 }
00623 sbc_lun_status_is_good();
00624 return TRUE;
00625 }
00626
00627
00635 void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length )
00636 {
00637
00638 if( b_sense_10 )
00639 {
00640 Usb_write_byte(0);
00641 }
00642 Usb_write_byte( u8_data_length );
00643
00644
00645 Usb_write_byte(SBC_MEDIUM_TYPE);
00646
00647
00648 if (mem_wr_protect( usb_LUN ))
00649 {
00650 Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_PROTECT);
00651 }
00652 else
00653 {
00654 Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_ENABLE);
00655 }
00656
00657 if( b_sense_10 )
00658 {
00659 Usb_write_byte(0);
00660 Usb_write_byte(0);
00661 }
00662
00663
00664 if( b_sense_10 )
00665 {
00666 Usb_write_byte(0);
00667 }
00668 Usb_write_byte(SBC_BLOCK_DESCRIPTOR_LENGTH);
00669 }
00670
00671
00683 void send_informational_exceptions_page (void)
00684 {
00685 Usb_write_byte(SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS);
00686
00687 Usb_write_byte(SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS);
00688 Usb_write_byte(0x00);
00689 Usb_write_byte(SBC_MRIE);
00690 Usb_write_byte(0x00);
00691 Usb_write_byte(0x00);
00692 Usb_write_byte(0x00);
00693 Usb_write_byte(0x00);
00694 Usb_write_byte(0x00);
00695 Usb_write_byte(0x00);
00696 Usb_write_byte(0x00);
00697 Usb_write_byte(0x01);
00698 }
00699
00700
00712 void send_read_write_error_recovery_page (U8 length)
00713 {
00714 Usb_write_byte(SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY);
00715
00716 Usb_write_byte(SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY);
00717 Usb_write_byte(0x80);
00718 Usb_write_byte(SBC_READ_RETRY_COUNT);
00719 Usb_write_byte(SBC_CORRECTION_SPAN);
00720 Usb_write_byte(SBC_HEAD_OFFSET_COUNT);
00721 Usb_write_byte(SBC_DATA_STROBE_OFFSET);
00722 Usb_write_byte(0x00);
00723
00724 if (length > 12)
00725 {
00726 Usb_write_byte(SBC_WRITE_RETRY_COUNT);
00727 Usb_write_byte(0x00);
00728 Usb_write_byte(SBC_RECOVERY_LIMIT_MSB);
00729 Usb_write_byte(SBC_RECOVERY_LIMIT_LSB);
00730 }
00731 }
00732
00748 Bool sbc_prevent_allow_medium_removal(void)
00749 {
00750 sbc_lun_status_is_good();
00751 return TRUE;
00752 }
00753
00754
00757 void sbc_lun_status_is_good(void)
00758 {
00759 Sbc_send_good();
00760 Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00761 }
00762
00765 void sbc_lun_status_is_not_present(void)
00766 {
00767 Sbc_send_failed();
00768 Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);
00769 }
00770
00773 void sbc_lun_status_is_busy_or_change(void)
00774 {
00775 Sbc_send_failed();
00776 Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );
00777 }
00778
00781 void sbc_lun_status_is_fail(void)
00782 {
00783 Sbc_send_failed();
00784 Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00785 }
00786
00789 void sbc_lun_status_is_protected(void)
00790 {
00791 Sbc_send_failed();
00792 Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);
00793 }
00794
00797 void sbc_lun_status_is_cdb_field(void)
00798 {
00799 Sbc_send_failed();
00800 Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
00801 }
00802