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 #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
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
00072 0x00,
00073 0,
00074
00075
00076 0,
00077 1,
00078
00079
00080 0x03,
00081
00082
00083
00084
00085
00086
00087 2,
00088 0,
00089 0,
00090 0,
00091
00092
00093
00094
00095
00096 {
00097 0x1F,
00098 0,
00099 0
00100 },
00101
00102
00103 0,
00104 0,
00105 0,
00106 0,
00107 0,
00108 0,
00109 0,
00110 0,
00111 };
00112
00113
00114 static void send_informational_exceptions_page (void);
00115 static void send_read_write_error_recovery_page (U8);
00116 static void sbc_header_mode_sense ( Bool b_sense_10 , U8 u8_data_length );
00117
00118
00119
00120
00121
00135 Bool scsi_decode_command(void)
00136 {
00137 Bool status;
00138
00139 if (g_scsi_command[0] == SBC_CMD_WRITE_10)
00140 {
00141 Scsi_start_write_action();
00142 status = sbc_write_10();
00143 Scsi_stop_write_action();
00144 return status;
00145 }
00146 if (g_scsi_command[0] == SBC_CMD_READ_10 )
00147 {
00148 Scsi_start_read_action();
00149 status = sbc_read_10();
00150 Scsi_stop_read_action();
00151 return status;
00152 }
00153
00154 switch (g_scsi_command[0])
00155 {
00156 case SBC_CMD_REQUEST_SENSE:
00157 return sbc_request_sense();
00158 break;
00159
00160 case SBC_CMD_INQUIRY:
00161 return sbc_inquiry();
00162 break;
00163
00164 case SBC_CMD_TEST_UNIT_READY:
00165 return sbc_test_unit_ready();
00166 break;
00167
00168 case SBC_CMD_READ_CAPACITY:
00169 return sbc_read_capacity();
00170 break;
00171
00172 case SBC_CMD_MODE_SENSE_6:
00173 return sbc_mode_sense( FALSE );
00174 break;
00175
00176 case SBC_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
00177 return sbc_prevent_allow_medium_removal();
00178 break;
00179
00180 case SBC_CMD_VERIFY_10:
00181 sbc_lun_status_is_good();
00182 break;
00183
00184 case SBC_CMD_MODE_SENSE_10:
00185 return sbc_mode_sense( TRUE );
00186 break;
00187
00188 case SBC_CMD_FORMAT_UNIT:
00189 case SBC_CMD_MODE_SELECT_6:
00190 case SBC_CMD_START_STOP_UNIT:
00191 case SBC_CMD_SEND_DIAGNOSTIC:
00192 case SBC_CMD_READ_LONG:
00193 case SBC_CMD_SYNCHRONIZE_CACHE:
00194 case SBC_CMD_WRITE_BUFFER:
00195 case SBC_CMD_RESERVE_10:
00196 case SBC_CMD_RELEASE_10:
00197 default:
00198
00199 Sbc_send_failed();
00200 Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_COMMAND_OPERATION_CODE, 0x00);
00201 return FALSE;
00202 break;
00203 }
00204 return TRUE;
00205 }
00206
00207
00225 Bool sbc_request_sense (void)
00226 {
00227 U8 allocation_length, i;
00228 U8 request_sens_output[18];
00229
00230 allocation_length = g_scsi_command[4];
00231 if( allocation_length > 18 )
00232 {
00233 allocation_length = 18;
00234 }
00235
00236 request_sens_output[0] = SBC_RESPONSE_CODE_SENSE;
00237 request_sens_output[1] = 0x00;
00238 request_sens_output[2] = g_scsi_sense.key;
00239
00240 request_sens_output[3] = 0x00;
00241 request_sens_output[4] = 0x00;
00242 request_sens_output[5] = 0x00;
00243 request_sens_output[6] = 0x00;
00244
00245 request_sens_output[7] = SBC_ADDITIONAL_SENSE_LENGTH;
00246 request_sens_output[8] = SBC_COMMAND_SPECIFIC_INFORMATION_3;
00247 request_sens_output[9] = SBC_COMMAND_SPECIFIC_INFORMATION_2;
00248 request_sens_output[10] = SBC_COMMAND_SPECIFIC_INFORMATION_1;
00249 request_sens_output[11] = SBC_COMMAND_SPECIFIC_INFORMATION_0;
00250
00251 request_sens_output[12] = g_scsi_sense.asc;
00252 request_sens_output[13] = g_scsi_sense.ascq;
00253
00254 request_sens_output[14] = SBC_FIELD_REPLACEABLE_UNIT_CODE;
00255 request_sens_output[15] = SBC_SENSE_KEY_SPECIFIC_2;
00256 request_sens_output[16] = SBC_SENSE_KEY_SPECIFIC_1;
00257 request_sens_output[17] = SBC_SENSE_KEY_SPECIFIC_0;
00258
00259
00260 for( i=0 ; i<allocation_length ; i++ )
00261 {
00262 Usb_write_byte( request_sens_output[i] );
00263 }
00264 Sbc_valid_write_usb( allocation_length );
00265
00266 sbc_lun_status_is_good();
00267 return TRUE;
00268 }
00269
00270
00290 Bool sbc_inquiry (void)
00291 {
00292 U8 allocation_length, i;
00293
00294 #ifdef __GNUC__
00295 PGM_VOID_P ptr;
00296 #else
00297 U8 code *ptr;
00298 #endif
00299
00300 if( (0 != (g_scsi_command[1] & 0x03) )
00301 || (0 != g_scsi_command[2] ) )
00302 {
00303
00304
00305 sbc_lun_status_is_cdb_field();
00306 return FALSE;
00307 }
00308
00309
00310
00311 allocation_length = g_scsi_command[4];
00312 if (allocation_length > SBC_MAX_INQUIRY_DATA)
00313 {
00314 allocation_length = SBC_MAX_INQUIRY_DATA;
00315 }
00316
00317
00318 ptr = (code U8*) &sbc_std_inquiry_data;
00319
00320 for ( i=0 ; ((i != 36) && (allocation_length > i)); i++)
00321 {
00322 if( 8 == i )
00323 {
00324 ptr = (code U8 *) &g_sbc_vendor_id;
00325 }
00326 if( 16 == i )
00327 {
00328 ptr = (code U8 *) &g_sbc_product_id;
00329 }
00330 if( 32 == i )
00331 {
00332 ptr = (code U8 *) &g_sbc_revision_id;
00333 }
00334 #ifndef __GNUC__
00335 Usb_write_byte((U8)(*ptr++));
00336 #else // AVRGCC does not support point to PGM space
00337
00338 Usb_write_byte(pgm_read_byte_near((unsigned int)ptr++));
00339 #endif
00340
00341 }
00342 Sbc_valid_write_usb(i);
00343 sbc_lun_status_is_good();
00344 return TRUE;
00345 }
00346
00347
00348 Bool sbc_test_unit_ready(void)
00349 {
00350 switch ( mem_test_unit_ready(usb_LUN) )
00351 {
00352 case CTRL_GOOD :
00353 sbc_lun_status_is_good();
00354 break;
00355
00356 case CTRL_NO_PRESENT :
00357 sbc_lun_status_is_not_present();
00358 break;
00359
00360 case CTRL_BUSY :
00361 sbc_lun_status_is_busy_or_change();
00362 break;
00363
00364 case CTRL_FAIL :
00365 default :
00366 sbc_lun_status_is_fail();
00367 break;
00368 }
00369 return TRUE;
00370 }
00371
00372
00373 Bool sbc_read_capacity (void)
00374 {
00375 U32 mem_size_nb_sector;
00376
00377 switch ( mem_read_capacity( usb_LUN, &mem_size_nb_sector ) )
00378 {
00379 case CTRL_GOOD :
00380 Usb_write_byte(MSB0(mem_size_nb_sector));
00381 Usb_write_byte(MSB1(mem_size_nb_sector));
00382 Usb_write_byte(MSB2(mem_size_nb_sector));
00383 Usb_write_byte(MSB3(mem_size_nb_sector));
00384 Usb_write_byte( 0 );
00385 Usb_write_byte( 0 );
00386 Usb_write_byte( (U8)(512 >> 8) );
00387 Usb_write_byte( (U8)(512 & 0xFF));
00388
00389 Sbc_valid_write_usb(SBC_READ_CAPACITY_LENGTH);
00390 sbc_lun_status_is_good();
00391 return TRUE;
00392 break;
00393
00394 case CTRL_NO_PRESENT :
00395 sbc_lun_status_is_not_present();
00396 break;
00397
00398 case CTRL_BUSY :
00399 sbc_lun_status_is_busy_or_change();
00400 break;
00401
00402 case CTRL_FAIL :
00403 default :
00404 sbc_lun_status_is_fail();
00405 break;
00406 }
00407 return FALSE;
00408 }
00409
00410
00411 Bool sbc_read_10 (void)
00412 {
00413 U32 mass_addr;
00414 U16 mass_size;
00415
00416 MSB0(mass_addr) = g_scsi_command[2];
00417 MSB1(mass_addr) = g_scsi_command[3];
00418 MSB2(mass_addr) = g_scsi_command[4];
00419 MSB3(mass_addr) = g_scsi_command[5];
00420
00421 MSB(mass_size) = g_scsi_command[7];
00422 LSB(mass_size) = g_scsi_command[8];
00423
00424 if( Is_usb_ms_data_direction_out() )
00425 {
00426 sbc_lun_status_is_cdb_field();
00427 return FALSE;
00428 }
00429 if( 0 == g_scsi_data_remaining )
00430 {
00431 if( mass_size == (g_scsi_data_remaining/512) )
00432 {
00433 sbc_lun_status_is_good();
00434 }else{
00435 sbc_lun_status_is_cdb_field();
00436 }
00437 return TRUE;
00438 }
00439
00440 switch ( memory_2_usb( usb_LUN , mass_addr, g_scsi_data_remaining/512 ) )
00441 {
00442 case CTRL_GOOD :
00443 if( mass_size == (g_scsi_data_remaining/512) )
00444 {
00445 sbc_lun_status_is_good();
00446 }else{
00447 sbc_lun_status_is_cdb_field();
00448 }
00449 g_scsi_data_remaining = 0;
00450 break;
00451
00452 case CTRL_NO_PRESENT :
00453 sbc_lun_status_is_not_present();
00454 return FALSE;
00455 break;
00456
00457 case CTRL_BUSY :
00458 sbc_lun_status_is_busy_or_change();
00459 return FALSE;
00460 break;
00461
00462 case CTRL_FAIL :
00463 default :
00464 sbc_lun_status_is_fail();
00465 return FALSE;
00466 break;
00467 }
00468 return TRUE;
00469 }
00470
00471
00472 Bool sbc_write_10 (void)
00473 {
00474 U32 mass_addr;
00475 U16 mass_size;
00476
00477 MSB0(mass_addr) = g_scsi_command[2];
00478 MSB1(mass_addr) = g_scsi_command[3];
00479 MSB2(mass_addr) = g_scsi_command[4];
00480 MSB3(mass_addr) = g_scsi_command[5];
00481
00482 MSB(mass_size) = g_scsi_command[7];
00483 LSB(mass_size) = g_scsi_command[8];
00484
00485 if( Is_usb_ms_data_direction_in() )
00486 {
00487 sbc_lun_status_is_cdb_field();
00488 return FALSE;
00489 }
00490
00491 if( 0 == g_scsi_data_remaining )
00492 {
00493 if( mass_size == (g_scsi_data_remaining/512) )
00494 {
00495 sbc_lun_status_is_good();
00496 }else{
00497 sbc_lun_status_is_cdb_field();
00498 }
00499 return TRUE;
00500 }
00501
00502 if( TRUE == mem_wr_protect( usb_LUN ) )
00503 {
00504 sbc_lun_status_is_protected();
00505 return FALSE;
00506 }
00507
00508 switch (usb_2_memory( usb_LUN , mass_addr, g_scsi_data_remaining/512 ))
00509 {
00510 case CTRL_GOOD :
00511 if( mass_size == (g_scsi_data_remaining/512) )
00512 {
00513 sbc_lun_status_is_good();
00514 }else{
00515 sbc_lun_status_is_cdb_field();
00516 }
00517 g_scsi_data_remaining = 0;
00518 break;
00519
00520 case CTRL_NO_PRESENT :
00521 sbc_lun_status_is_not_present();
00522 return FALSE;
00523 break;
00524
00525 case CTRL_BUSY :
00526 sbc_lun_status_is_busy_or_change();
00527 return FALSE;
00528 break;
00529
00530 case CTRL_FAIL :
00531 default :
00532 sbc_lun_status_is_fail();
00533 return FALSE;
00534 break;
00535 }
00536 return TRUE;
00537 }
00538
00539
00554 Bool sbc_mode_sense( Bool b_sense_10 )
00555 {
00556 U8 allocation_length;
00557
00558 if( b_sense_10 )
00559 allocation_length = g_scsi_command[8];
00560 else
00561 allocation_length = g_scsi_command[4];
00562
00563
00564 switch ( g_scsi_command[2] & SBC_MSK_PAGE_CODE )
00565 {
00566 case SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS:
00567 sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS );
00568 send_informational_exceptions_page();
00569 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS + 1);
00570 break;
00571
00572 case SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY:
00573 sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY );
00574 send_read_write_error_recovery_page(allocation_length);
00575 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY + 1);
00576 break;
00577
00578 case SBC_PAGE_CODE_ALL:
00579 if( b_sense_10 ) {
00580 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 );
00581 }else{
00582 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 );
00583 }
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_lun_status_is_cdb_field();
00615 return FALSE;
00616 break;
00617 }
00618 sbc_lun_status_is_good();
00619 return TRUE;
00620 }
00621
00622
00630 void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length )
00631 {
00632
00633 if( b_sense_10 )
00634 {
00635 Usb_write_byte(0);
00636 }
00637 Usb_write_byte( u8_data_length );
00638
00639
00640 Usb_write_byte(SBC_MEDIUM_TYPE);
00641
00642
00643 if (mem_wr_protect( usb_LUN ))
00644 {
00645 Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_PROTECT);
00646 }
00647 else
00648 {
00649 Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_ENABLE);
00650 }
00651
00652 if( b_sense_10 )
00653 {
00654 Usb_write_byte(0);
00655 Usb_write_byte(0);
00656 }
00657
00658
00659 if( b_sense_10 )
00660 {
00661 Usb_write_byte(0);
00662 }
00663 Usb_write_byte(SBC_BLOCK_DESCRIPTOR_LENGTH);
00664 }
00665
00666
00678 void send_informational_exceptions_page (void)
00679 {
00680 Usb_write_byte(SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS);
00681
00682 Usb_write_byte(SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS);
00683 Usb_write_byte(0x00);
00684 Usb_write_byte(SBC_MRIE);
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(0x00);
00692 Usb_write_byte(0x01);
00693 }
00694
00695
00707 void send_read_write_error_recovery_page (U8 length)
00708 {
00709 Usb_write_byte(SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY);
00710
00711 Usb_write_byte(SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY);
00712 Usb_write_byte(0x80);
00713 Usb_write_byte(SBC_READ_RETRY_COUNT);
00714 Usb_write_byte(SBC_CORRECTION_SPAN);
00715 Usb_write_byte(SBC_HEAD_OFFSET_COUNT);
00716 Usb_write_byte(SBC_DATA_STROBE_OFFSET);
00717 Usb_write_byte(0x00);
00718
00719 if (length > 12)
00720 {
00721 Usb_write_byte(SBC_WRITE_RETRY_COUNT);
00722 Usb_write_byte(0x00);
00723 Usb_write_byte(SBC_RECOVERY_LIMIT_MSB);
00724 Usb_write_byte(SBC_RECOVERY_LIMIT_LSB);
00725 }
00726 }
00727
00743 Bool sbc_prevent_allow_medium_removal(void)
00744 {
00745 sbc_lun_status_is_good();
00746 return TRUE;
00747 }
00748
00749
00752 void sbc_lun_status_is_good(void)
00753 {
00754 Sbc_send_good();
00755 Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00756 }
00757
00760 void sbc_lun_status_is_not_present(void)
00761 {
00762 Sbc_send_failed();
00763 Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);
00764 }
00765
00768 void sbc_lun_status_is_busy_or_change(void)
00769 {
00770 Sbc_send_failed();
00771 Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );
00772 }
00773
00776 void sbc_lun_status_is_fail(void)
00777 {
00778 Sbc_send_failed();
00779 Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00780 }
00781
00784 void sbc_lun_status_is_protected(void)
00785 {
00786 Sbc_send_failed();
00787 Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);
00788 }
00789
00792 void sbc_lun_status_is_cdb_field(void)
00793 {
00794 Sbc_send_failed();
00795 Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
00796 }
00797