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
00344 Usb_write_byte(pgm_read_byte_near((unsigned int)ptr++));
00345 #endif
00346
00347 }
00348 Sbc_valid_write_usb(i);
00349 sbc_lun_status_is_good();
00350 return TRUE;
00351 }
00352
00353
00354 Bool sbc_test_unit_ready(void)
00355 {
00356 switch ( mem_test_unit_ready(usb_LUN) )
00357 {
00358 case CTRL_GOOD :
00359 sbc_lun_status_is_good();
00360 break;
00361
00362 case CTRL_NO_PRESENT :
00363 sbc_lun_status_is_not_present();
00364 break;
00365
00366 case CTRL_BUSY :
00367 sbc_lun_status_is_busy_or_change();
00368 break;
00369
00370 case CTRL_FAIL :
00371 default :
00372 sbc_lun_status_is_fail();
00373 break;
00374 }
00375 return TRUE;
00376 }
00377
00378
00379 Bool sbc_read_capacity (void)
00380 {
00381 U32 mem_size_nb_sector;
00382
00383 switch ( mem_read_capacity( usb_LUN, &mem_size_nb_sector ) )
00384 {
00385 case CTRL_GOOD :
00386 Usb_write_byte(MSB0(mem_size_nb_sector));
00387 Usb_write_byte(MSB1(mem_size_nb_sector));
00388 Usb_write_byte(MSB2(mem_size_nb_sector));
00389 Usb_write_byte(MSB3(mem_size_nb_sector));
00390 Usb_write_byte( 0 );
00391 Usb_write_byte( 0 );
00392 Usb_write_byte( (U8)(512 >> 8) );
00393 Usb_write_byte( (U8)(512 & 0xFF));
00394
00395 Sbc_valid_write_usb(SBC_READ_CAPACITY_LENGTH);
00396 sbc_lun_status_is_good();
00397 return TRUE;
00398 break;
00399
00400 case CTRL_NO_PRESENT :
00401 sbc_lun_status_is_not_present();
00402 break;
00403
00404 case CTRL_BUSY :
00405 sbc_lun_status_is_busy_or_change();
00406 break;
00407
00408 case CTRL_FAIL :
00409 default :
00410 sbc_lun_status_is_fail();
00411 break;
00412 }
00413 return FALSE;
00414 }
00415
00416
00417 Bool sbc_read_10 (void)
00418 {
00419 U32 mass_addr;
00420 U16 mass_size;
00421
00422 MSB0(mass_addr) = g_scsi_command[2];
00423 MSB1(mass_addr) = g_scsi_command[3];
00424 MSB2(mass_addr) = g_scsi_command[4];
00425 MSB3(mass_addr) = g_scsi_command[5];
00426
00427 MSB(mass_size) = g_scsi_command[7];
00428 LSB(mass_size) = g_scsi_command[8];
00429
00430 if( Is_usb_ms_data_direction_out() )
00431 {
00432 sbc_lun_status_is_cdb_field();
00433 return FALSE;
00434 }
00435 if( 0 == g_scsi_data_remaining )
00436 {
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 return TRUE;
00444 }
00445
00446 switch ( memory_2_usb( usb_LUN , mass_addr, g_scsi_data_remaining/512 ) )
00447 {
00448 case CTRL_GOOD :
00449 if( mass_size == (g_scsi_data_remaining/512) )
00450 {
00451 sbc_lun_status_is_good();
00452 }else{
00453 sbc_lun_status_is_cdb_field();
00454 }
00455 g_scsi_data_remaining = 0;
00456 break;
00457
00458 case CTRL_NO_PRESENT :
00459 sbc_lun_status_is_not_present();
00460 return FALSE;
00461 break;
00462
00463 case CTRL_BUSY :
00464 sbc_lun_status_is_busy_or_change();
00465 return FALSE;
00466 break;
00467
00468 case CTRL_FAIL :
00469 default :
00470 sbc_lun_status_is_fail();
00471 return FALSE;
00472 break;
00473 }
00474 return TRUE;
00475 }
00476
00477
00478 Bool sbc_write_10 (void)
00479 {
00480 U32 mass_addr;
00481 U16 mass_size;
00482
00483 MSB0(mass_addr) = g_scsi_command[2];
00484 MSB1(mass_addr) = g_scsi_command[3];
00485 MSB2(mass_addr) = g_scsi_command[4];
00486 MSB3(mass_addr) = g_scsi_command[5];
00487
00488 MSB(mass_size) = g_scsi_command[7];
00489 LSB(mass_size) = g_scsi_command[8];
00490
00491 if( Is_usb_ms_data_direction_in() )
00492 {
00493 sbc_lun_status_is_cdb_field();
00494 return FALSE;
00495 }
00496
00497 if( 0 == g_scsi_data_remaining )
00498 {
00499 if( mass_size == (g_scsi_data_remaining/512) )
00500 {
00501 sbc_lun_status_is_good();
00502 }else{
00503 sbc_lun_status_is_cdb_field();
00504 }
00505 return TRUE;
00506 }
00507
00508 if( TRUE == mem_wr_protect( usb_LUN ) )
00509 {
00510 sbc_lun_status_is_protected();
00511 return FALSE;
00512 }
00513
00514 switch (usb_2_memory( usb_LUN , mass_addr, g_scsi_data_remaining/512 ))
00515 {
00516 case CTRL_GOOD :
00517 if( mass_size == (g_scsi_data_remaining/512) )
00518 {
00519 sbc_lun_status_is_good();
00520 }else{
00521 sbc_lun_status_is_cdb_field();
00522 }
00523 g_scsi_data_remaining = 0;
00524 break;
00525
00526 case CTRL_NO_PRESENT :
00527 sbc_lun_status_is_not_present();
00528 return FALSE;
00529 break;
00530
00531 case CTRL_BUSY :
00532 sbc_lun_status_is_busy_or_change();
00533 return FALSE;
00534 break;
00535
00536 case CTRL_FAIL :
00537 default :
00538 sbc_lun_status_is_fail();
00539 return FALSE;
00540 break;
00541 }
00542 return TRUE;
00543 }
00544
00545
00560 Bool sbc_mode_sense( Bool b_sense_10 )
00561 {
00562 U8 allocation_length;
00563
00564 if( b_sense_10 )
00565 allocation_length = g_scsi_command[8];
00566 else
00567 allocation_length = g_scsi_command[4];
00568
00569
00570 switch ( g_scsi_command[2] & SBC_MSK_PAGE_CODE )
00571 {
00572 case SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS:
00573 sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS );
00574 send_informational_exceptions_page();
00575 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS + 1);
00576 break;
00577
00578 case SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY:
00579 sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY );
00580 send_read_write_error_recovery_page(allocation_length);
00581 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY + 1);
00582 break;
00583
00584 case SBC_PAGE_CODE_ALL:
00585 if( b_sense_10 ) {
00586 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 );
00587 }else{
00588 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 );
00589 }
00590 if( b_sense_10 )
00591 {
00592 if (allocation_length == 8)
00593 {
00594 Sbc_valid_write_usb(8);
00595 break;
00596 }
00597 }
00598 else
00599 {
00600 if (allocation_length == 4)
00601 {
00602 Sbc_valid_write_usb(4);
00603 break;
00604 }
00605 }
00606
00607 send_read_write_error_recovery_page(allocation_length);
00608 if (allocation_length > 12)
00609 {
00610 send_informational_exceptions_page();
00611 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_CODE_ALL + 1);
00612 }
00613 else
00614 {
00615 Sbc_valid_write_usb(allocation_length);
00616 }
00617 break;
00618
00619 default:
00620 sbc_lun_status_is_cdb_field();
00621 return FALSE;
00622 break;
00623 }
00624 sbc_lun_status_is_good();
00625 return TRUE;
00626 }
00627
00628
00636 void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length )
00637 {
00638
00639 if( b_sense_10 )
00640 {
00641 Usb_write_byte(0);
00642 }
00643 Usb_write_byte( u8_data_length );
00644
00645
00646 Usb_write_byte(SBC_MEDIUM_TYPE);
00647
00648
00649 if (mem_wr_protect( usb_LUN ))
00650 {
00651 Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_PROTECT);
00652 }
00653 else
00654 {
00655 Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_ENABLE);
00656 }
00657
00658 if( b_sense_10 )
00659 {
00660 Usb_write_byte(0);
00661 Usb_write_byte(0);
00662 }
00663
00664
00665 if( b_sense_10 )
00666 {
00667 Usb_write_byte(0);
00668 }
00669 Usb_write_byte(SBC_BLOCK_DESCRIPTOR_LENGTH);
00670 }
00671
00672
00684 void send_informational_exceptions_page (void)
00685 {
00686 Usb_write_byte(SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS);
00687
00688 Usb_write_byte(SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS);
00689 Usb_write_byte(0x00);
00690 Usb_write_byte(SBC_MRIE);
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(0x00);
00698 Usb_write_byte(0x01);
00699 }
00700
00701
00713 void send_read_write_error_recovery_page (U8 length)
00714 {
00715 Usb_write_byte(SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY);
00716
00717 Usb_write_byte(SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY);
00718 Usb_write_byte(0x80);
00719 Usb_write_byte(SBC_READ_RETRY_COUNT);
00720 Usb_write_byte(SBC_CORRECTION_SPAN);
00721 Usb_write_byte(SBC_HEAD_OFFSET_COUNT);
00722 Usb_write_byte(SBC_DATA_STROBE_OFFSET);
00723 Usb_write_byte(0x00);
00724
00725 if (length > 12)
00726 {
00727 Usb_write_byte(SBC_WRITE_RETRY_COUNT);
00728 Usb_write_byte(0x00);
00729 Usb_write_byte(SBC_RECOVERY_LIMIT_MSB);
00730 Usb_write_byte(SBC_RECOVERY_LIMIT_LSB);
00731 }
00732 }
00733
00749 Bool sbc_prevent_allow_medium_removal(void)
00750 {
00751 sbc_lun_status_is_good();
00752 return TRUE;
00753 }
00754
00755
00758 void sbc_lun_status_is_good(void)
00759 {
00760 Sbc_send_good();
00761 Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00762 }
00763
00766 void sbc_lun_status_is_not_present(void)
00767 {
00768 Sbc_send_failed();
00769 Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);
00770 }
00771
00774 void sbc_lun_status_is_busy_or_change(void)
00775 {
00776 Sbc_send_failed();
00777 Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );
00778 }
00779
00782 void sbc_lun_status_is_fail(void)
00783 {
00784 Sbc_send_failed();
00785 Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00786 }
00787
00790 void sbc_lun_status_is_protected(void)
00791 {
00792 Sbc_send_failed();
00793 Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);
00794 }
00795
00798 void sbc_lun_status_is_cdb_field(void)
00799 {
00800 Sbc_send_failed();
00801 Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
00802 }
00803