00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00049
00050 #include "config.h"
00051 #include "storage/scsi_decoder.h"
00052 #include "conf_usb.h"
00053 #include "usb_drv.h"
00054 #include "storage/ctrl_status.h"
00055 #include "storage/ctrl_access.h"
00056
00057
00058
00059
00060
00061
00062
00063
00064 U8 g_scsi_command[16];
00065 U8 g_scsi_status;
00066 U32 g_scsi_data_remaining;
00067
00068 FLASH U8 g_sbc_vendor_id[8] = SBC_VENDOR_ID;
00069 FLASH U8 g_sbc_product_id[16] = SBC_PRODUCT_ID;
00070 FLASH U8 g_sbc_revision_id[4] = SBC_REVISION_ID;
00071
00072 extern U8 usb_LUN;
00073
00074 s_scsi_sense g_scsi_sense;
00075
00076
00077 FLASH struct sbc_st_std_inquiry_data sbc_std_inquiry_data =
00078 {
00079
00080 0x00,
00081 0,
00082
00083
00084 0,
00085 1,
00086
00087
00088
00089
00090
00091 0x00,
00092
00093
00094 2,
00095 0,
00096 0,
00097 0,
00098
00099
00100
00101
00102
00103 {
00104 0x1F,
00105 0,
00106 0
00107 },
00108
00109
00110 0,
00111 0,
00112 0,
00113 0,
00114 0,
00115 0,
00116 0,
00117 0,
00118 };
00119
00120
00121 static void send_informational_exceptions_page (void);
00122 static void send_read_write_error_recovery_page (U8);
00123 static void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length );
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
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 case SBC_CMD_MODE_SENSE_10:
00187 return sbc_mode_sense( TRUE );
00188 break;
00189
00190 case SBC_CMD_FORMAT_UNIT:
00191
00192 case SBC_CMD_MODE_SELECT_6:
00193
00194
00195
00196
00197 case SBC_CMD_START_STOP_UNIT:
00198 case SBC_CMD_SEND_DIAGNOSTIC:
00199 case SBC_CMD_READ_LONG:
00200 case SBC_CMD_SYNCHRONIZE_CACHE:
00201 case SBC_CMD_WRITE_BUFFER:
00202 case SBC_CMD_RESERVE_10:
00203 case SBC_CMD_RELEASE_10:
00204 default:
00205 {
00206 Sbc_send_failed();
00207 Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_COMMAND_OPERATION_CODE, 0x00);
00208 return FALSE;
00209 break;
00210 }
00211 }
00212 return TRUE;
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
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
00238
00239 request_sens_output[0] = SBC_RESPONSE_CODE_SENSE;
00240 request_sens_output[1] = 0x00;
00241 request_sens_output[2] = g_scsi_sense.key;
00242
00243 request_sens_output[3] = 0x00;
00244 request_sens_output[4] = 0x00;
00245 request_sens_output[5] = 0x00;
00246 request_sens_output[6] = 0x00;
00247
00248 request_sens_output[7] = SBC_ADDITIONAL_SENSE_LENGTH;
00249 request_sens_output[8] = SBC_COMMAND_SPECIFIC_INFORMATION_3;
00250 request_sens_output[9] = SBC_COMMAND_SPECIFIC_INFORMATION_2;
00251 request_sens_output[10] = SBC_COMMAND_SPECIFIC_INFORMATION_1;
00252 request_sens_output[11] = SBC_COMMAND_SPECIFIC_INFORMATION_0;
00253
00254 request_sens_output[12] = g_scsi_sense.asc;
00255 request_sens_output[13] = g_scsi_sense.ascq;
00256
00257 request_sens_output[14] = SBC_FIELD_REPLACEABLE_UNIT_CODE;
00258 request_sens_output[15] = SBC_SENSE_KEY_SPECIFIC_2;
00259 request_sens_output[16] = SBC_SENSE_KEY_SPECIFIC_1;
00260 request_sens_output[17] = SBC_SENSE_KEY_SPECIFIC_0;
00261
00262
00263 for( i=0 ; i<allocation_length ; i++ )
00264 {
00265 Usb_write_byte( request_sens_output[i] );
00266 }
00267 Sbc_valid_write_usb( allocation_length );
00268
00269 sbc_lun_status_is_good();
00270
00271 return TRUE;
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 Bool sbc_inquiry (void)
00292 {
00293 U8 allocation_length, i;
00294
00295 #ifdef AVRGCC
00296 PGM_VOID_P ptr;
00297 #else
00298 U8 FLASH *ptr;
00299 #endif
00300
00301 if( (0 == (g_scsi_command[1] & 0x03) )
00302 && (0 == g_scsi_command[2] ) )
00303 {
00304
00305
00306
00307 allocation_length = g_scsi_command[4];
00308 if (allocation_length > SBC_MAX_INQUIRY_DATA)
00309 {
00310 allocation_length = SBC_MAX_INQUIRY_DATA;
00311 }
00312
00313
00314 ptr = (FLASH U8*) &sbc_std_inquiry_data;
00315
00316 for ( i=0 ; ((i != 36) && (allocation_length > i)); i++)
00317 {
00318 if( 8 == i )
00319 {
00320 ptr = (FLASH U8 *) &g_sbc_vendor_id;
00321 }
00322 if( 16 == i )
00323 {
00324 ptr = (FLASH U8 *) &g_sbc_product_id;
00325 }
00326 if( 32 == i )
00327 {
00328 ptr = (FLASH U8 *) &g_sbc_revision_id;
00329 }
00330 #ifndef AVRGCC
00331 Usb_write_byte((U8)(*ptr++));
00332 #else // AVRGCC does not support point to PGM space
00333 #warning with avrgcc assumes devices descriptors are stored in the lower 64Kbytes of on-chip flash memory
00334 Usb_write_byte(pgm_read_byte_near((unsigned int)ptr++));
00335 #endif
00336
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 while( allocation_length > i )
00352 {
00353 if (64 == i)
00354 {
00355 Sbc_valid_write_usb(64);
00356 allocation_length -= 64;
00357 i = 0;
00358 }
00359 Usb_write_byte(0);
00360 i++;
00361 }
00362
00363 Sbc_valid_write_usb(allocation_length);
00364 sbc_lun_status_is_good();
00365 return TRUE;
00366 }
00367 else
00368 {
00369 Sbc_send_failed();
00370 Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
00371 return FALSE;
00372 }
00373 }
00374
00375
00376 Bool sbc_test_unit_ready(void)
00377 {
00378 switch ( mem_test_unit_ready(usb_LUN) )
00379 {
00380 case CTRL_GOOD :
00381 sbc_lun_status_is_good();
00382 break;
00383
00384 case CTRL_NO_PRESENT :
00385 sbc_lun_status_is_not_present();
00386 break;
00387
00388 case CTRL_BUSY :
00389 sbc_lun_status_is_busy_or_change();
00390 break;
00391
00392 case CTRL_FAIL :
00393 default :
00394 sbc_lun_status_is_fail();
00395 break;
00396 }
00397 return TRUE;
00398 }
00399
00400
00401 Bool sbc_read_capacity (void)
00402 {
00403 _MEM_TYPE_SLOW_ U32 mem_size_nb_sector;
00404
00405 switch ( mem_read_capacity( usb_LUN, &mem_size_nb_sector ) )
00406 {
00407 case CTRL_GOOD :
00408 Usb_write_byte(MSB0(mem_size_nb_sector));
00409 Usb_write_byte(MSB1(mem_size_nb_sector));
00410 Usb_write_byte(MSB2(mem_size_nb_sector));
00411 Usb_write_byte(MSB3(mem_size_nb_sector));
00412 Usb_write_byte( 0 );
00413 Usb_write_byte( 0 );
00414 Usb_write_byte( (U8)(512 >> 8) );
00415 Usb_write_byte( (U8)(512 & 0xFF));
00416
00417 Sbc_valid_write_usb(SBC_READ_CAPACITY_LENGTH);
00418 sbc_lun_status_is_good();
00419 return TRUE;
00420 break;
00421
00422 case CTRL_NO_PRESENT :
00423 sbc_lun_status_is_not_present();
00424 break;
00425
00426 case CTRL_BUSY :
00427 sbc_lun_status_is_busy_or_change();
00428 break;
00429
00430 case CTRL_FAIL :
00431 default :
00432 sbc_lun_status_is_fail();
00433 break;
00434 }
00435 return FALSE;
00436 }
00437
00438
00439 Bool sbc_read_10 (void)
00440 {
00441 U32 mass_addr;
00442 U16 mass_size;
00443
00444 MSB0(mass_addr) = g_scsi_command[2];
00445 MSB1(mass_addr) = g_scsi_command[3];
00446 MSB2(mass_addr) = g_scsi_command[4];
00447 MSB3(mass_addr) = g_scsi_command[5];
00448
00449 MSB(mass_size) = g_scsi_command[7];
00450 LSB(mass_size) = g_scsi_command[8];
00451
00452 if (mass_size != 0)
00453 {
00454 switch ( memory_2_usb( usb_LUN , mass_addr, mass_size ) )
00455 {
00456 case CTRL_GOOD :
00457 sbc_lun_status_is_good();
00458 g_scsi_data_remaining = g_scsi_data_remaining - (512 * (Uint32)mass_size);
00459 return TRUE;
00460 break;
00461
00462 case CTRL_NO_PRESENT :
00463 sbc_lun_status_is_not_present();
00464 return FALSE;
00465 break;
00466
00467 case CTRL_BUSY :
00468 sbc_lun_status_is_busy_or_change();
00469 return FALSE;
00470 break;
00471
00472 case CTRL_FAIL :
00473 default :
00474 sbc_lun_status_is_fail();
00475 return FALSE;
00476 break;
00477 }
00478 }
00479 else
00480 {
00481 sbc_lun_status_is_good();
00482 }
00483 return TRUE;
00484 }
00485
00486
00487 Bool sbc_write_10 (void)
00488 {
00489 U32 mass_addr;
00490 U16 mass_size;
00491
00492 MSB0(mass_addr) = g_scsi_command[2];
00493 MSB1(mass_addr) = g_scsi_command[3];
00494 MSB2(mass_addr) = g_scsi_command[4];
00495 MSB3(mass_addr) = g_scsi_command[5];
00496
00497 MSB(mass_size) = g_scsi_command[7];
00498 LSB(mass_size) = g_scsi_command[8];
00499
00500 if (mass_size != 0)
00501 {
00502 if( TRUE == mem_wr_protect( usb_LUN ) )
00503 {
00504 sbc_lun_status_is_protected();
00505 return FALSE;
00506 #warning For Win98 data must be read to avoid blocking
00507 }
00508 else
00509 {
00510 switch (usb_2_memory( usb_LUN , mass_addr, mass_size ))
00511 {
00512 case CTRL_GOOD :
00513 sbc_lun_status_is_good();
00514 g_scsi_data_remaining = g_scsi_data_remaining - (512 * (Uint32)mass_size);
00515 return TRUE;
00516 break;
00517
00518 case CTRL_NO_PRESENT :
00519 sbc_lun_status_is_not_present();
00520 return FALSE;
00521 break;
00522
00523 case CTRL_BUSY :
00524 sbc_lun_status_is_busy_or_change();
00525 return FALSE;
00526 break;
00527
00528 case CTRL_FAIL :
00529 default :
00530 sbc_lun_status_is_fail();
00531 return FALSE;
00532 break;
00533 }
00534 }
00535 }
00536 else
00537 {
00538 sbc_lun_status_is_good();
00539 }
00540 return TRUE;
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 Bool sbc_mode_sense( Bool b_sense_10 )
00559 {
00560 U8 allocation_length;
00561
00562 if( b_sense_10 )
00563 allocation_length = g_scsi_command[8];
00564 else
00565 allocation_length = g_scsi_command[4];
00566
00567
00568 switch ( g_scsi_command[2] & SBC_MSK_PAGE_CODE )
00569 {
00570 case SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS:
00571 sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS );
00572 send_informational_exceptions_page();
00573 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS + 1);
00574 break;
00575
00576 case SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY:
00577 sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY );
00578 send_read_write_error_recovery_page(allocation_length);
00579 Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY + 1);
00580 break;
00581
00582 case SBC_PAGE_CODE_ALL:
00583 sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_CODE_ALL );
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_send_failed();
00615 Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);
00616 return FALSE;
00617 break;
00618 }
00619 sbc_lun_status_is_good();
00620 return TRUE;
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631 void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length )
00632 {
00633
00634 if( b_sense_10 )
00635 {
00636 Usb_write_byte(0);
00637 }
00638 Usb_write_byte( u8_data_length );
00639
00640
00641 Usb_write_byte(SBC_MEDIUM_TYPE);
00642
00643
00644 if (mem_wr_protect( usb_LUN ))
00645 {
00646 Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_PROTECT);
00647 }
00648 else
00649 {
00650 Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_ENABLE);
00651 }
00652
00653 if( b_sense_10 )
00654 {
00655 Usb_write_byte(0);
00656 Usb_write_byte(0);
00657 }
00658
00659
00660 if( b_sense_10 )
00661 {
00662 Usb_write_byte(0);
00663 }
00664 Usb_write_byte(SBC_BLOCK_DESCRIPTOR_LENGTH);
00665 }
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 void send_informational_exceptions_page (void)
00678 {
00679 Usb_write_byte(SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS);
00680
00681 Usb_write_byte(SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS);
00682 Usb_write_byte(0x00);
00683 Usb_write_byte(SBC_MRIE);
00684 Usb_write_byte(0x00);
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(0x01);
00692 }
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 void send_read_write_error_recovery_page (U8 length)
00707 {
00708 Usb_write_byte(SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY);
00709
00710 Usb_write_byte(SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY);
00711 Usb_write_byte(0x80);
00712 Usb_write_byte(SBC_READ_RETRY_COUNT);
00713 Usb_write_byte(SBC_CORRECTION_SPAN);
00714 Usb_write_byte(SBC_HEAD_OFFSET_COUNT);
00715 Usb_write_byte(SBC_DATA_STROBE_OFFSET);
00716 Usb_write_byte(0x00);
00717
00718 if (length > 12)
00719 {
00720 Usb_write_byte(SBC_WRITE_RETRY_COUNT);
00721 Usb_write_byte(0x00);
00722 Usb_write_byte(SBC_RECOVERY_LIMIT_MSB);
00723 Usb_write_byte(SBC_RECOVERY_LIMIT_LSB);
00724 }
00725 }
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 Bool sbc_prevent_allow_medium_removal(void)
00741 {
00742 sbc_lun_status_is_good();
00743 return TRUE;
00744 }
00745
00746
00747
00748
00749 void sbc_lun_status_is_good(void)
00750 {
00751 Sbc_send_good();
00752 Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00753 }
00754
00755
00756
00757 void sbc_lun_status_is_not_present(void)
00758 {
00759 Sbc_send_failed();
00760 Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);
00761 }
00762
00763
00764
00765 void sbc_lun_status_is_busy_or_change(void)
00766 {
00767 Sbc_send_failed();
00768 Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );
00769 }
00770
00771
00772
00773 void sbc_lun_status_is_fail(void)
00774 {
00775 Sbc_send_failed();
00776 Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);
00777 }
00778
00779
00780
00781 void sbc_lun_status_is_protected(void)
00782 {
00783 Sbc_send_failed();
00784 Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);
00785 }
00786
00787