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
00081 0x00,
00082
00083
00084 2,
00085 0,
00086 0,
00087 0,
00088
00089
00090
00091
00092
00093 {
00094 0x1F,
00095 0,
00096 0
00097 },
00098
00099
00100 0,
00101 0,
00102 0,
00103 0,
00104 0,
00105 0,
00106 0,
00107 0,
00108 };
00109
00110
00111 static void send_informational_exceptions_page (void);
00112 static void send_read_write_error_recovery_page (U8);
00113 static void sbc_header_mode_sense ( Bool b_sense_10 , U8 u8_data_length );
00114
00115
00116
00117
00118
00132 Bool scsi_decode_command(void)
00133 {
00134 Bool status;
00135
00136 if (g_scsi_command[0] == SBC_CMD_WRITE_10)
00137 {
00138 Scsi_start_write_action();
00139 status = sbc_write_10();
00140 Scsi_stop_write_action();
00141 return status;
00142 }
00143 if (g_scsi_command[0] == SBC_CMD_READ_10 )
00144 {
00145 Scsi_start_read_action();
00146 status = sbc_read_10();
00147 Scsi_stop_read_action();
00148 return status;
00149 }
00150
00151 switch (g_scsi_command[0])
00152 {
00153 case SBC_CMD_REQUEST_SENSE:
00154 return sbc_request_sense();
00155 break;
00156
00157 case SBC_CMD_INQUIRY:
00158 return sbc_inquiry();
00159 break;
00160
00161 case SBC_CMD_TEST_UNIT_READY:
00162 return sbc_test_unit_ready();
00163 break;
00164
00165 case SBC_CMD_READ_CAPACITY:
00166 return sbc_read_capacity();
00167 break;
00168
00169 case SBC_CMD_MODE_SENSE_6:
00170 return sbc_mode_sense( FALSE );
00171 break;
00172
00173 case SBC_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
00174 return sbc_prevent_allow_medium_removal();
00175 break;
00176
00177 case SBC_CMD_VERIFY_10:
00178 sbc_lun_status_is_good();
00179 break;
00180
00181 case SBC_CMD_MODE_SENSE_10:
00182 return sbc_mode_sense( TRUE );
00183 break;
00184
00185 case SBC_CMD_FORMAT_UNIT:
00186 case SBC_CMD_MODE_SELECT_6:
00187 case SBC_CMD_START_STOP_UNIT:
00188 case SBC_CMD_SEND_DIAGNOSTIC:
00189 case SBC_CMD_READ_LONG:
00190 case SBC_CMD_SYNCHRONIZE_CACHE:
00191 case SBC_CMD_WRITE_BUFFER:
00192 case SBC_CMD_RESERVE_10:
00193 case SBC_CMD_RELEASE_10:
00194 default:
00195
00196 Sbc_send_failed();
00197 Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_COMMAND_OPERATION_CODE, 0x00);
00198 return FALSE;
00199 break;
00200 }
00201 return TRUE;
00202 }
00203
00204
00222 Bool sbc_request_sense (void)
00223 {
00224 U8 allocation_length, i;
00225 U8 request_sens_output[18];
00226
00227 allocation_length = g_scsi_command[4];
00228 if( allocation_length > 18 )
00229 {
00230 allocation_length = 18;
00231 }
00232
00233 request_sens_output[0] = SBC_RESPONSE_CODE_SENSE;
00234 request_sens_output[1] = 0x00;
00235 request_sens_output[2] = g_scsi_sense.key;
00236
00237 request_sens_output[3] = 0x00;
00238 request_sens_output[4] = 0x00;
00239 request_sens_output[5] = 0x00;
00240 request_sens_output[6] = 0x00;
00241
00242 request_sens_output[7] = SBC_ADDITIONAL_SENSE_LENGTH;
00243 request_sens_output[8] = SBC_COMMAND_SPECIFIC_INFORMATION_3;
00244 request_sens_output[9] = SBC_COMMAND_SPECIFIC_INFORMATION_2;
00245 request_sens_output[10] = SBC_COMMAND_SPECIFIC_INFORMATION_1;
00246 request_sens_output[11] = SBC_COMMAND_SPECIFIC_INFORMATION_0;
00247
00248 request_sens_output[12] = g_scsi_sense.asc;
00249 request_sens_output[13] = g_scsi_sense.ascq;
00250
00251 request_sens_output[14] = SBC_FIELD_REPLACEABLE_UNIT_CODE;
00252 request_sens_output[15] = SBC_SENSE_KEY_SPECIFIC_2;
00253 request_sens_output[16] = SBC_SENSE_KEY_SPECIFIC_1;
00254 request_sens_output[17] = SBC_SENSE_KEY_SPECIFIC_0;
00255
00256
00257 for( i=0 ; i<allocation_length ; i++ )
00258 {
00259 Usb_write_byte( request_sens_output[i] );
00260 }
00261 Sbc_valid_write_usb( allocation_length );
00262
00263 sbc_lun_status_is_good();
00264 return TRUE;
00265 }
00266
00267
00287 Bool sbc_inquiry (void)
00288 {
00289 U8 allocation_length, i;
00290
00291 #ifdef __GNUC__
00292 PGM_VOID_P ptr;
00293 #else
00294 U8 code *ptr;
00295 #endif
00296
00297 if( (0 != (g_scsi_command[1] & 0x03) )
00298 || (0 != g_scsi_command[2] ) )
00299 {
00300
00301 sbc_lun_status_is_cdb_field();
00302 return FALSE;
00303 }
00304
00305
00306 allocation_length = g_scsi_command[4];
00307 if (allocation_length > SBC_MAX_INQUIRY_DATA)
00308 {
00309 allocation_length = SBC_MAX_INQUIRY_DATA;
00310 }
00311
00312
00313 ptr = (code U8*) &sbc_std_inquiry_data;
00314
00315 for ( i=0 ; ((i != 36) && (allocation_length > i)); i++)
00316 {
00317 if( 8 == i )
00318 {
00319 ptr = (code U8 *) &g_sbc_vendor_id;
00320 }
00321 if( 16 == i )
00322 {
00323 ptr = (code U8 *) &g_sbc_product_id;
00324 }
00325 if( 32 == i )
00326 {
00327 ptr = (code U8 *) &g_sbc_revision_id;
00328 }
00329 #ifndef __GNUC__
00330 Usb_write_byte((U8)(*ptr++));
00331 #else // AVRGCC does not support point to PGM space
00332
00333 Usb_write_byte(pgm_read_byte_near((unsigned int)ptr++));
00334 #endif
00335
00336 }
00337 Sbc_valid_write_usb(i);
00338 sbc_lun_status_is_good();
00339 return TRUE;
00340 }
00341
00342
00343 Bool sbc_test_unit_ready(void)
00344 {
00345 switch ( mem_test_unit_ready(usb_LUN) )
00346 {
00347 case CTRL_GOOD :
00348 sbc_lun_status_is_good();
00349 break;
00350
00351 case CTRL_NO_PRESENT :
00352 sbc_lun_status_is_not_present();
00353 break;
00354
00355 case CTRL_BUSY :
00356 sbc_lun_status_is_busy_or_change();
00357 break;
00358
00359 case CTRL_FAIL :
00360 default :
00361 sbc_lun_status_is_fail();
00362 break;
00363 }
00364 return TRUE;
00365 }
00366
00367
00368 Bool sbc_read_capacity (void)
00369 {
00370 U32 mem_size_nb_sector;
00371
00372 switch ( mem_read_capacity( usb_LUN, &mem_size_nb_sector ) )
00373 {
00374 case CTRL_GOOD :
00375 Usb_write_byte(MSB0(mem_size_nb_sector));
00376 Usb_write_byte(MSB1(mem_size_nb_sector));
00377 Usb_write_byte(MSB2(mem_size_nb_sector));
00378 Usb_write_byte(MSB3(mem_size_nb_sector));
00379 Usb_write_byte( 0 );
00380 Usb_write_byte( 0 );
00381 Usb_write_byte( (U8)(512 >> 8) );
00382 Usb_write_byte( (U8)(512 & 0xFF));
00383
00384 Sbc_valid_write_usb(SBC_READ_CAPACITY_LENGTH);
00385 sbc_lun_status_is_good();
00386 break;
00387
00388 case CTRL_NO_PRESENT :
00389 sbc_lun_status_is_not_present();
00390 break;
00391
00392 case CTRL_BUSY :
00393 sbc_lun_status_is_busy_or_change();
00394 break;
00395
00396 case CTRL_FAIL :
00397 default :
00398 sbc_lun_status_is_fail();
00399 break;
00400 }
00401 return TRUE;
00402 }
00403
00404
00405 Bool sbc_read_10 (void)
00406 {
00407 U32 mass_addr;
00408 U16 mass_size;
00409
00410 MSB0(mass_addr) = g_scsi_command[2];
00411 MSB1(mass_addr) = g_scsi_command[3];
00412 MSB2(mass_addr) = g_scsi_command[4];
00413 MSB3(mass_addr) = g_scsi_command[5];
00414
00415 MSB(mass_size) = g_scsi_command[7];
00416 LSB(mass_size) = g_scsi_command[8];
00417
00418 if( Is_usb_ms_data_direction_out() )
00419 {
00420 sbc_lun_status_is_cdb_field();
00421 return FALSE;
00422 }
00423 if( 0 == g_scsi_data_remaining )
00424 {
00425 if( mass_size == (g_scsi_data_remaining/512) )
00426 {
00427 sbc_lun_status_is_good();
00428 }else{
00429 sbc_lun_status_is_cdb_field();
00430 }
00431 return TRUE;
00432 }
00433
00434 switch ( memory_2_usb( usb_LUN , mass_addr, g_scsi_data_remaining/512 ) )
00435 {
00436 case CTRL_GOOD :
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 g_scsi_data_remaining = 0;
00444 break;
00445
00446 case CTRL_NO_PRESENT :
00447 sbc_lun_status_is_not_present();
00448 return FALSE;
00449 break;
00450
00451 case CTRL_BUSY :
00452 sbc_lun_status_is_busy_or_change();
00453 return FALSE;
00454 break;
00455
00456 case CTRL_FAIL :
00457 default :
00458 sbc_lun_status_is_fail();
00459 return FALSE;
00460 break;
00461 }
00462 return TRUE;
00463 }
00464
00465
00466 Bool sbc_write_10 (void)
00467 {
00468 U32 mass_addr;
00469 U16 mass_size;
00470
00471 MSB0(mass_addr) = g_scsi_command[2];
00472 MSB1(mass_addr) = g_scsi_command[3];
00473 MSB2(mass_addr) = g_scsi_command[4];
00474 MSB3(mass_addr) = g_scsi_command[5];
00475
00476 MSB(mass_size) = g_scsi_command[7];
00477 LSB(mass_size) = g_scsi_command[8];
00478
00479 if( 0 == g_scsi_data_remaining )
00480 {
00481 if( mass_size == (g_scsi_data_remaining/512) )
00482 {
00483 sbc_lun_status_is_good();
00484 }else{
00485 sbc_lun_status_is_cdb_field();
00486 }
00487 return TRUE;
00488 }
00489
00490 if( TRUE == mem_wr_protect( usb_LUN ) )
00491 {
00493 sbc_lun_status_is_protected();
00494 return TRUE;
00495 }
00496
00497 switch (usb_2_memory( usb_LUN , mass_addr, g_scsi_data_remaining/512 ))
00498 {
00499 case CTRL_GOOD :
00500 if( mass_size == (g_scsi_data_remaining/512) )
00501 {
00502 sbc_lun_status_is_good();
00503 }else{
00504 sbc_lun_status_is_cdb_field();
00505 }
00506 g_scsi_data_remaining = 0;
00507 break;
00508
00509 case CTRL_NO_PRESENT :
00510 sbc_lun_status_is_not_present();
00511 return FALSE;
00512 break;
00513
00514 case CTRL_BUSY :
00515 sbc_lun_status_is_busy_or_change();
00516 return FALSE;
00517 break;
00518
00519 case CTRL_FAIL :
00520 default :
00521 sbc_lun_status_is_fail();
00522 return FALSE;
00523 break;
00524 }
00525 return TRUE;
00526 }
00527
00528
00543 Bool sbc_mode_sense( Bool b_sense_10 )
00544 {
00545 U8 allocation_length;
00546
00547 if( b_sense_10 )
00548 allocation_length = g_scsi_command[8];
00549 else
00550 allocation_length = g_scsi_command[4];
00551
00552
00553 switch ( g_scsi_command[2] & SBC_MSK_PAGE_CODE )
00554 {
00555 case SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS:
00556 sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS );
00557 send_informational_exceptions_page();
00558 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS + 1);
00559 break;
00560
00561 case SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY:
00562 sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY );
00563 send_read_write_error_recovery_page(allocation_length);
00564 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY + 1);
00565 break;
00566
00567 case SBC_PAGE_CODE_ALL:
00568 sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_CODE_ALL );
00569 if( b_sense_10 )
00570 {
00571 if (allocation_length == 8)
00572 {
00573 Sbc_valid_write_usb(8);
00574 break;
00575 }
00576 }
00577 else
00578 {
00579 if (allocation_length == 4)
00580 {
00581 Sbc_valid_write_usb(4);
00582 break;
00583 }
00584 }
00585
00586 send_read_write_error_recovery_page(allocation_length);
00587 if (allocation_length > 12)
00588 {
00589 send_informational_exceptions_page();
00590 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_CODE_ALL + 1);
00591 }
00592 else
00593 {
00594 Sbc_valid_write_usb(allocation_length);
00595 }
00596 break;
00597
00598 default:
00599 sbc_lun_status_is_cdb_field();
00600 return TRUE;
00601 break;
00602 }
00603 sbc_lun_status_is_good();
00604 return TRUE;
00605 }
00606
00607
00615 void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length )
00616 {
00617
00618 if( b_sense_10 )
00619 {
00620 Usb_write_byte(0);
00621 }
00622 Usb_write_byte( u8_data_length );
00623
00624
00625 Usb_write_byte(SBC_MEDIUM_TYPE);
00626
00627
00628 if (mem_wr_protect( usb_LUN ))
00629 {
00630 Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_PROTECT);
00631 }
00632 else
00633 {
00634 Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_ENABLE);
00635 }
00636
00637 if( b_sense_10 )
00638 {
00639 Usb_write_byte(0);
00640 Usb_write_byte(0);
00641 }
00642
00643
00644 if( b_sense_10 )
00645 {
00646 Usb_write_byte(0);
00647 }
00648 Usb_write_byte(SBC_BLOCK_DESCRIPTOR_LENGTH);
00649 }
00650
00651
00663 void send_informational_exceptions_page (void)
00664 {
00665 Usb_write_byte(SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS);
00666
00667 Usb_write_byte(SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS);
00668 Usb_write_byte(0x00);
00669 Usb_write_byte(SBC_MRIE);
00670 Usb_write_byte(0x00);
00671 Usb_write_byte(0x00);
00672 Usb_write_byte(0x00);
00673 Usb_write_byte(0x00);
00674 Usb_write_byte(0x00);
00675 Usb_write_byte(0x00);
00676 Usb_write_byte(0x00);
00677 Usb_write_byte(0x01);
00678 }
00679
00680
00692 void send_read_write_error_recovery_page (U8 length)
00693 {
00694 Usb_write_byte(SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY);
00695
00696 Usb_write_byte(SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY);
00697 Usb_write_byte(0x80);
00698 Usb_write_byte(SBC_READ_RETRY_COUNT);
00699 Usb_write_byte(SBC_CORRECTION_SPAN);
00700 Usb_write_byte(SBC_HEAD_OFFSET_COUNT);
00701 Usb_write_byte(SBC_DATA_STROBE_OFFSET);
00702 Usb_write_byte(0x00);
00703
00704 if (length > 12)
00705 {
00706 Usb_write_byte(SBC_WRITE_RETRY_COUNT);
00707 Usb_write_byte(0x00);
00708 Usb_write_byte(SBC_RECOVERY_LIMIT_MSB);
00709 Usb_write_byte(SBC_RECOVERY_LIMIT_LSB);
00710 }
00711 }
00712
00728 Bool sbc_prevent_allow_medium_removal(void)
00729 {
00730 sbc_lun_status_is_good();
00731 return TRUE;
00732 }
00733
00734
00737 void sbc_lun_status_is_good(void)
00738 {
00739 Sbc_send_good();
00740 Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00741 }
00742
00745 void sbc_lun_status_is_not_present(void)
00746 {
00747 Sbc_send_failed();
00748 Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);
00749 }
00750
00753 void sbc_lun_status_is_busy_or_change(void)
00754 {
00755 Sbc_send_failed();
00756 Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );
00757 }
00758
00761 void sbc_lun_status_is_fail(void)
00762 {
00763 Sbc_send_failed();
00764 Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00765 }
00766
00769 void sbc_lun_status_is_protected(void)
00770 {
00771 Sbc_send_failed();
00772 Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);
00773 }
00774
00777 void sbc_lun_status_is_cdb_field(void)
00778 {
00779 Sbc_send_failed();
00780 Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
00781 }
00782