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