00001
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 #include "config.h"
00047 #include <string.h>
00048 #include "conf/conf_usb.h"
00049 #include "host_mem.h"
00050 #include "conf/conf_access.h"
00051 #include "lib_mcu/usb/usb_drv.h"
00052 #include "modules/usb/host_chap9/usb_host_enum.h"
00053 #include "modules/usb/host_chap9/usb_host_task.h"
00054 #include "modules/scsi_decoder/scsi_decoder.h"
00055
00056
00057
00058 #ifndef LOG_STR_CODE
00059 #define LOG_STR_CODE(str)
00060 #else
00061 U8 code log_ms_connect[]="Mass Storage Connected";
00062 #endif
00063 #ifndef HOST_SECTOR_SIZE
00064 #define HOST_SECTOR_SIZE 512 //default sector size is 512 bytes
00065 #endif
00066
00067 #if (USB_HUB_SUPPORT==ENABLE)
00068 #ifndef USB_MAX_DMS_NUMBER
00069 #define USB_MAX_DMS_NUMBER MAX_DEVICE_IN_USB_TREE-1
00070 #endif
00071 #else
00072 #define USB_MAX_DMS_NUMBER 1
00073 #endif
00074
00075 #ifndef USB_SUPPORT_MS_SECTOR_WR_MAX
00076 #define USB_SUPPORT_MS_SECTOR_WR_MAX 1
00077 #endif
00078
00079 #define USB_MAX_LUN_PER_DMS 4
00080
00081
00082 typedef struct
00083 {
00084 U8 flag1;
00085 U8 flag2;
00086 U8 flag3;
00087 U8 flag4;
00088 U8 tag_lsb0;
00089 U8 tag_lsb1;
00090 U8 tag_lsb2;
00091 U8 tag_lsb3;
00092 U8 lgt_lsb0;
00093 U8 lgt_lsb1;
00094 U8 lgt_lsb2;
00095 U8 lgt_lsb3;
00096 U8 dir;
00097 U8 lun;
00098 U8 lgt;
00099 U8 cmd;
00100 U8 u8_data[15];
00101 } S_cbw;
00102
00103
00104 #define HOST_MS_CBW_DATA_POS 16
00105
00106
00107 typedef struct
00108 {
00109 Bool b_first_unitready;
00110 Bool b_protected;
00111 U8 u8_block_size;
00112 } S_lun_info;
00113
00114
00115 typedef struct
00116 {
00117 U8 device_index;
00118 U8 pipe_in;
00119 U8 pipe_out;
00120 U8 nb_lun;
00121 S_lun_info lun_info[USB_MAX_LUN_PER_DMS];
00122 } S_dms_device;
00123
00124
00125
00126
00127
00128 S_cbw g_ms_cbw;
00129 S_dms_device g_ms_devices[USB_MAX_DMS_NUMBER];
00130 U8 g_ms_nb_connected;
00131 U8 g_ms_sel_dms=0;
00132 U8 g_ms_sel_lun;
00133
00134 #if (USB_SUPPORT_MS_SECTOR_WR_MAX != 1)
00135 U8 g_ms_cache[(USB_SUPPORT_MS_SECTOR_WR_MAX-1)*512];
00136 #endif
00137
00138
00139
00140
00141 U8 g_readctx_b_run = FALSE;
00142 U8 g_readctx_u8_device;
00143 U8 g_readctx_u8_lun;
00144 U32 g_readctx_u32_addr;
00145 U16 g_readctx_u16_sector;
00146
00147
00148
00149 #define Is_host_ms_configured() ((g_ms_nb_connected && Is_host_not_suspended() && Is_usb_id_host()) ? TRUE : FALSE )
00150
00151
00152 #define DMS_pipe_in() (g_ms_devices[g_ms_sel_dms].pipe_in)
00153 #define DMS_pipe_out() (g_ms_devices[g_ms_sel_dms].pipe_out)
00154
00155
00156
00157 Ctrl_status host_mem_request_sense ( void );
00158
00159
00160 Bool host_mem_select_lun ( U8 lun );
00161 void host_mem_cbw_init ( void );
00162 Bool host_mem_cbw_send ( void );
00163 Ctrl_status host_mem_csw_read ( void );
00164 void host_mem_stall_management ( void );
00165
00166
00167
00168
00169
00170
00173 void host_mem_init( void )
00174 {
00175 U8 i;
00176
00177 for(i=0; i<USB_MAX_DMS_NUMBER; i++)
00178 {
00179 g_ms_devices[i].device_index=0xFF;
00180 }
00181 g_ms_nb_connected=0;
00182 }
00183
00184
00187 Bool host_mem_install( void )
00188 {
00189 U32 capacity;
00190 U8 device_num;
00191 U8 interface_num;
00192 U8 lun_offset;
00193 U8 i;
00194
00195
00196 for( device_num=0; device_num<Get_nb_device(); device_num++)
00197 {
00198 Host_select_device(device_num);
00199
00200
00201 for( interface_num=0; interface_num < Get_nb_supported_interface(); interface_num++ )
00202 {
00203 if( Get_class(interface_num)!= MS_CLASS )
00204 continue;
00205
00206 LOG_STR_CODE(log_ms_connect);
00207
00208
00209 if( g_ms_nb_connected != 0 )
00210 {
00211
00212 for( i=0; i<g_ms_nb_connected; i++ )
00213 {
00214 if( g_ms_devices[i].device_index == device_num )
00215 break;
00216 }
00217 if( i!=g_ms_nb_connected )
00218 break;
00219
00220 if( USB_MAX_DMS_NUMBER == g_ms_nb_connected )
00221 break;
00222 }
00223
00224
00225 g_ms_devices[g_ms_nb_connected].device_index = device_num;
00226
00227
00228 if(Is_ep_addr_in(Get_ep_addr(interface_num,0)))
00229 {
00230 g_ms_devices[g_ms_nb_connected].pipe_in=usb_tree.device[device_num].interface[interface_num].ep[0].pipe_number;
00231 g_ms_devices[g_ms_nb_connected].pipe_out=usb_tree.device[device_num].interface[interface_num].ep[1].pipe_number;
00232 }
00233 else
00234 {
00235 g_ms_devices[g_ms_nb_connected].pipe_in=usb_tree.device[device_num].interface[interface_num].ep[1].pipe_number;
00236 g_ms_devices[g_ms_nb_connected].pipe_out=usb_tree.device[device_num].interface[interface_num].ep[0].pipe_number;
00237 }
00238
00239
00240 if( CONTROL_GOOD != host_ms_get_max_lun() )
00241 data_stage[0] = 0;
00242 g_ms_devices[g_ms_nb_connected].nb_lun = data_stage[0]+1;
00243
00244 if( USB_MAX_LUN_PER_DMS < g_ms_devices[g_ms_nb_connected].nb_lun )
00245 g_ms_devices[g_ms_nb_connected].nb_lun = USB_MAX_LUN_PER_DMS;
00246
00247
00248 lun_offset = 0;
00249 for( i=0; i<g_ms_nb_connected; i++)
00250 {
00251 lun_offset +=g_ms_devices[i].nb_lun;
00252 }
00253
00254
00255 g_ms_sel_dms = g_ms_nb_connected;
00256 g_ms_nb_connected++;
00257
00258
00259 for( i=0; i<g_ms_devices[g_ms_sel_dms].nb_lun; i++ )
00260 {
00261
00262 g_ms_devices[g_ms_sel_dms].lun_info[i].b_first_unitready = FALSE;
00263 g_ms_devices[g_ms_sel_dms].lun_info[i].b_protected = TRUE;
00264
00265 host_mem_inquiry( lun_offset+i );
00266 host_mem_read_capacity( lun_offset+i, &capacity );
00267 }
00268 return TRUE;
00269 }
00270 }
00271 return FALSE;
00272 }
00273
00274
00277 void host_mem_uninstall( void )
00278 {
00279 U8 device_num;
00280 U8 i;
00281 Bool b_last_ms_conected = TRUE;
00282
00283 for( i=g_ms_nb_connected; i!=0; i--)
00284 {
00285 device_num = g_ms_devices[i-1].device_index;
00286 if( 0xFF == device_num )
00287 {
00288
00289
00290 g_ms_nb_connected--;
00291 continue;
00292 }
00293 if( 0 == usb_tree.device[device_num].device_address )
00294 {
00295 g_ms_devices[i-1].device_index = 0xFF;
00296 if( b_last_ms_conected )
00297 g_ms_nb_connected--;
00298 }else{
00299 b_last_ms_conected = FALSE;
00300 }
00301 }
00302 }
00303
00304
00309 U8 host_mem_get_lun( void )
00310 {
00311 U8 i;
00312 U8 host_ms_max_lun = 0;
00313
00314 if(!Is_host_ms_configured())
00315 return 0;
00316
00317 for( i=0; i<g_ms_nb_connected; i++ )
00318 {
00319 host_ms_max_lun += g_ms_devices[i].nb_lun;
00320 }
00321 return host_ms_max_lun;
00322 }
00323
00324
00325
00326
00327
00328
00337 Ctrl_status host_mem_test_unit_ready(U8 lun)
00338 {
00339 Ctrl_status status;
00340 U32 u32_nb_sector;
00341
00342 if( !host_mem_select_lun(lun) )
00343 return CTRL_NO_PRESENT;
00344 if (g_readctx_b_run)
00345 {
00346 host_mem_mem_2_ram_stop();
00347 host_mem_select_lun(lun);
00348 }
00349
00350
00351 host_mem_cbw_init();
00352
00353 g_ms_cbw.dir = SBC_CMD_DIR_OUT;
00354 g_ms_cbw.lgt = 0x06;
00355 g_ms_cbw.cmd = SBC_CMD_TEST_UNIT_READY;
00356 if( !host_mem_cbw_send() )
00357 return CTRL_FAIL;
00358
00359
00360 status = host_mem_csw_read();
00361 if( status == CTRL_GOOD )
00362 {
00363 if( FALSE == g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].b_first_unitready )
00364 {
00365
00366 status = CTRL_BUSY;
00367
00368 if( CTRL_GOOD == host_mem_read_capacity( lun , &u32_nb_sector ) )
00369 {
00370 g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].b_protected = host_mem_wr_protect( lun );
00371 g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].b_first_unitready = TRUE;
00372 }
00373 }
00374 }
00375 else
00376 {
00377 g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].b_first_unitready = FALSE;
00378 }
00379 return status;
00380 }
00381
00382
00392 Ctrl_status host_mem_read_capacity(U8 lun, U32 _MEM_TYPE_SLOW_ *u32_nb_sector )
00393 {
00394 U16 nb;
00395 U8 datas[8], status;
00396
00397 if( !host_mem_select_lun(lun) )
00398 return CTRL_NO_PRESENT;
00399 if (g_readctx_b_run)
00400 {
00401 host_mem_mem_2_ram_stop();
00402 host_mem_select_lun(lun);
00403 }
00404
00405
00406 host_mem_cbw_init();
00407 g_ms_cbw.lgt_lsb0 = 0x08;
00408 g_ms_cbw.dir = SBC_CMD_DIR_IN;
00409 g_ms_cbw.lgt = 0x0A;
00410 g_ms_cbw.cmd = SBC_CMD_READ_CAPACITY;
00411 if( !host_mem_cbw_send() )
00412 return CTRL_FAIL;
00413
00414
00415 nb=8;
00416 status = host_get_data(DMS_pipe_in(),&nb,datas);
00417 if( PIPE_GOOD != status )
00418 {
00419 if( PIPE_STALL == status )
00420 host_mem_stall_management();
00421 host_mem_csw_read();
00422 return CTRL_FAIL;
00423 }
00424
00425
00426 MSB0(*u32_nb_sector) = datas[0];
00427 MSB1(*u32_nb_sector) = datas[1];
00428 MSB2(*u32_nb_sector) = datas[2];
00429 MSB3(*u32_nb_sector) = datas[3];
00430
00431 g_ms_devices[ g_ms_sel_dms ].lun_info[ g_ms_sel_lun ].u8_block_size = datas[6]/2;
00432
00433
00434 return host_mem_csw_read();
00435 }
00436
00437
00444 U8 host_mem_read_sector_size( U8 lun )
00445 {
00446 host_mem_test_unit_ready( lun );
00447 if( !host_mem_select_lun(lun) )
00448 return 1;
00449 return g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].u8_block_size;
00450 }
00451
00452
00460 Bool host_mem_wr_protect_cache( U8 lun )
00461 {
00462 if( !host_mem_select_lun(lun) )
00463 return TRUE;
00464
00465 return g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].b_protected;
00466 }
00467
00468
00475 Bool host_mem_wr_protect( U8 lun )
00476 {
00477 U16 nb;
00478 U8 write_code[0x0C], status;
00479
00480 if( !host_mem_select_lun(lun) )
00481 return TRUE;
00482
00483 if( USB_SUPPORT_MS_SECTOR_WR_MAX < g_ms_devices[ g_ms_sel_dms ].lun_info[ g_ms_sel_lun ].u8_block_size )
00484 return TRUE;
00485
00486 if (g_readctx_b_run)
00487 {
00488 host_mem_mem_2_ram_stop();
00489 host_mem_select_lun(lun);
00490 }
00491
00492
00493 host_mem_cbw_init();
00494 g_ms_cbw.dir = SBC_CMD_DIR_IN;
00495 g_ms_cbw.lgt = 0x06;
00496 g_ms_cbw.cmd = SBC_CMD_MODE_SENSE_6;
00497 g_ms_cbw.lgt_lsb0 = 0x0C;
00498
00499 g_ms_cbw.u8_data[17-16] = 0x3F;
00500
00501 g_ms_cbw.u8_data[19-16] = 0x0C;
00502
00503 if( !host_mem_cbw_send() )
00504 return TRUE;
00505
00506
00507 nb=0x0C;
00508 status = host_get_data(DMS_pipe_in(),&nb,write_code);
00509 if( PIPE_GOOD != status )
00510 {
00511 if( PIPE_STALL == status )
00512 host_mem_stall_management();
00513 write_code[2] = 0x00;
00514 }
00515
00516
00517 host_mem_csw_read();
00518
00519 return (write_code[2] == 0x80);
00520 }
00521
00522
00527 Bool host_mem_removal(void)
00528 {
00529 return TRUE;
00530 }
00531
00532
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00600 Ctrl_status host_mem_inquiry( U8 lun )
00601 {
00602 U16 nb;
00603 U8 datas[31], status;
00604
00605 if( !host_mem_select_lun(lun) )
00606 return CTRL_NO_PRESENT;
00607 if (g_readctx_b_run)
00608 {
00609 host_mem_mem_2_ram_stop();
00610 host_mem_select_lun(lun);
00611 }
00612
00613 host_mem_cbw_init();
00614 g_ms_cbw.lgt_lsb0 = 0x24;
00615 g_ms_cbw.dir = SBC_CMD_DIR_IN;
00616 g_ms_cbw.lgt = 0x06;
00617 g_ms_cbw.cmd = SBC_CMD_INQUIRY;
00618
00619
00620
00621 g_ms_cbw.u8_data[19-16] = 0x24;
00622
00623 if( !host_mem_cbw_send() )
00624 return CTRL_FAIL;
00625
00626
00627
00628 nb=31;
00629 status = host_get_data(DMS_pipe_in(),&nb,datas);
00630
00631 if( PIPE_STALL == status )
00632 host_mem_stall_management();
00633
00634
00635 return host_mem_csw_read();
00636 }
00637
00638
00647 Ctrl_status host_mem_request_sense( void )
00648 {
00649 U16 nb;
00650 U8 datas[17], status;
00651 U8 sense_key, sense_key_add;
00652
00653
00654 host_mem_cbw_init();
00655 g_ms_cbw.lgt_lsb0 = 0x12;
00656 g_ms_cbw.dir = SBC_CMD_DIR_IN;
00657 g_ms_cbw.lgt = 0x06;
00658 g_ms_cbw.cmd = SBC_CMD_REQUEST_SENSE;
00659
00660
00661
00662 g_ms_cbw.u8_data[19-HOST_MS_CBW_DATA_POS] = 0x12;
00663
00664 if( !host_mem_cbw_send() )
00665 return CTRL_FAIL;
00666
00667
00668 nb=17;
00669 status = host_get_data(DMS_pipe_in(),&nb,datas);
00670 if( PIPE_GOOD != status )
00671 {
00672 if( PIPE_STALL == status )
00673 host_mem_stall_management();
00674 return CTRL_FAIL;
00675 }
00676
00677
00678
00679
00680 sense_key = (0x0F & datas[2]);
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 sense_key_add = datas[12];
00692
00693
00694
00695
00696
00697
00698
00699 nb=13;
00700 status = host_get_data(DMS_pipe_in(),&nb,datas);
00701 if( PIPE_GOOD != status )
00702 {
00703 if( PIPE_STALL == status )
00704 host_mem_stall_management();
00705 return CTRL_FAIL;
00706 }
00707
00708
00709 switch( sense_key )
00710 {
00711 case SBC_SENSE_KEY_NOT_READY:
00712 if( SBC_ASC_MEDIUM_NOT_PRESENT == sense_key_add )
00713 return CTRL_NO_PRESENT;
00714 break;
00715
00716 case SBC_SENSE_KEY_UNIT_ATTENTION:
00717 if( SBC_ASC_NOT_READY_TO_READY_CHANGE == sense_key_add )
00718 return CTRL_BUSY;
00719 if( SBC_ASC_MEDIUM_NOT_PRESENT == sense_key_add )
00720 return CTRL_NO_PRESENT;
00721 break;
00722
00723
00724
00725
00726
00727
00728 }
00729 return CTRL_FAIL;
00730 }
00731
00732
00733
00734
00735
00736
00750 Ctrl_status host_mem_mem_2_ram( U8 lun, U32 addr, U8 *ram )
00751 {
00752 U8 status;
00753 U16 nb;
00754 U8 u8_nb_sec_ignore_at_beg, u8_sector_size;
00755 U32 u32_address;
00756
00757 if( !host_mem_select_lun(lun) )
00758 return CTRL_FAIL;
00759
00760 u8_nb_sec_ignore_at_beg = 0;
00761
00762 if( g_readctx_b_run )
00763 {
00764
00765 if( ( g_ms_devices[g_ms_sel_dms].device_index != g_readctx_u8_device)
00766 || ( g_readctx_u8_lun != g_ms_sel_lun)
00767 || ( g_readctx_u32_addr > addr)
00768 || ( (g_readctx_u32_addr+g_readctx_u16_sector) <= addr ) )
00769 {
00770 host_mem_mem_2_ram_stop();
00771 host_mem_select_lun(lun);
00772 }else{
00773 u8_nb_sec_ignore_at_beg = addr-g_readctx_u32_addr;
00774 }
00775 }
00776
00777 if( !g_readctx_b_run )
00778 {
00779 u8_sector_size = g_ms_devices[ g_ms_sel_dms ].lun_info[ g_ms_sel_lun ].u8_block_size;
00780
00781
00782 u32_address = addr / u8_sector_size;
00783
00784 u8_nb_sec_ignore_at_beg = addr % u8_sector_size;
00785
00786 g_readctx_u16_sector = u8_sector_size;
00787 g_readctx_u32_addr = addr - u8_nb_sec_ignore_at_beg;
00788
00789
00790 host_mem_cbw_init();
00791 g_ms_cbw.lgt_lsb0 = 0x00;
00792 g_ms_cbw.lgt_lsb1 = u8_sector_size * (512/256);
00793 g_ms_cbw.lgt_lsb2 = 0x00;
00794 g_ms_cbw.lgt_lsb3 = 0x00;
00795 g_ms_cbw.dir = SBC_CMD_DIR_IN;
00796 g_ms_cbw.lgt = 0x0A;
00797 g_ms_cbw.cmd = SBC_CMD_READ_10;
00798
00799 g_ms_cbw.u8_data[17-HOST_MS_CBW_DATA_POS] = MSB0(u32_address);
00800 g_ms_cbw.u8_data[18-HOST_MS_CBW_DATA_POS] = MSB1(u32_address);
00801 g_ms_cbw.u8_data[19-HOST_MS_CBW_DATA_POS] = MSB2(u32_address);
00802 g_ms_cbw.u8_data[20-HOST_MS_CBW_DATA_POS] = MSB3(u32_address);
00803
00804
00805 g_ms_cbw.u8_data[23-HOST_MS_CBW_DATA_POS] = 0x01;
00806
00807 if( !host_mem_cbw_send() )
00808 return CTRL_FAIL;
00809 }
00810
00811 if( 0 != u8_nb_sec_ignore_at_beg )
00812 {
00813
00814
00815 g_readctx_u16_sector -= u8_nb_sec_ignore_at_beg;
00816 g_readctx_u32_addr += u8_nb_sec_ignore_at_beg;
00817 while( 0 != u8_nb_sec_ignore_at_beg )
00818 {
00819
00820 nb=HOST_SECTOR_SIZE;
00821 status = host_get_data(DMS_pipe_in(),&nb,NULL);
00822 if(PIPE_GOOD != status)
00823 {
00824 if(PIPE_STALL==status)
00825 host_mem_stall_management();
00826 host_mem_csw_read();
00827 return CTRL_FAIL;
00828 }
00829 u8_nb_sec_ignore_at_beg--;
00830 }
00831 }
00832
00833
00834 g_readctx_u16_sector--;
00835 g_readctx_u32_addr++;
00836 nb=HOST_SECTOR_SIZE;
00837 status = host_get_data(DMS_pipe_in(),&nb,ram);
00838 if(PIPE_GOOD != status)
00839 {
00840 if(PIPE_STALL==status)
00841 host_mem_stall_management();
00842 host_mem_csw_read();
00843 return CTRL_FAIL;
00844 }
00845
00846 if( 0 != g_readctx_u16_sector )
00847 {
00848
00849 g_readctx_u8_device = g_ms_devices[g_ms_sel_dms].device_index;
00850 g_readctx_u8_lun = g_ms_sel_lun;
00851 g_readctx_b_run = TRUE;
00852 return CTRL_GOOD;
00853 }
00854
00855
00856 g_readctx_b_run = FALSE;
00857 return host_mem_csw_read();
00858 }
00859
00860
00869 Ctrl_status host_mem_mem_2_ram_stop( void )
00870 {
00871 U16 nb;
00872 U8 status;
00873
00874 g_readctx_b_run = FALSE;
00875
00876 g_ms_sel_lun = g_readctx_u8_lun;
00877 g_ms_sel_dms = g_readctx_u8_device;
00878 Host_select_device( g_ms_devices[g_ms_sel_dms].device_index );
00879
00880 while( 0 != g_readctx_u16_sector )
00881 {
00882
00883 nb=HOST_SECTOR_SIZE;
00884 status = host_get_data(DMS_pipe_in(),&nb,NULL);
00885 if(PIPE_GOOD != status)
00886 {
00887 if(PIPE_STALL==status)
00888 host_mem_stall_management();
00889 host_mem_csw_read();
00890 return CTRL_FAIL;
00891 }
00892 g_readctx_u16_sector--;
00893 }
00894
00895
00896 return host_mem_csw_read();
00897 }
00898
00912 Ctrl_status host_mem_ram_2_mem( U8 lun, U32 addr, U8 *ram )
00913 {
00914 U8 status;
00915 U16 nb, u16_sector;
00916 U8 u8_nb_sec_ignore_at_beg, u8_sector_size;
00917 U32 u32_address;
00918 #if (USB_SUPPORT_MS_SECTOR_WR_MAX != 1)
00919 Ctrl_status read_status;
00920 U8 u8_i,u8_j;
00921 U32 u32_addr;
00922 #endif
00923
00924 if( !host_mem_select_lun(lun) )
00925 return CTRL_FAIL;
00926
00927 u8_sector_size = g_ms_devices[ g_ms_sel_dms ].lun_info[ g_ms_sel_lun ].u8_block_size;
00928
00929 if( USB_SUPPORT_MS_SECTOR_WR_MAX < u8_sector_size )
00930 return CTRL_FAIL;
00931
00932
00933
00934 u32_address = addr / u8_sector_size;
00935
00936 u8_nb_sec_ignore_at_beg = addr % u8_sector_size;
00937
00938 u16_sector = u8_sector_size;
00939
00940 #if (USB_SUPPORT_MS_SECTOR_WR_MAX != 1)
00941
00942 if( 1 != u8_sector_size )
00943 {
00944 u32_addr = addr - u8_nb_sec_ignore_at_beg;
00945 for( u8_i=0,u8_j=0 ; u8_i<u8_sector_size; u8_i++,u32_addr++ )
00946 {
00947 if( u8_i == u8_nb_sec_ignore_at_beg )
00948 continue;
00949 read_status = host_mem_mem_2_ram( lun, u32_addr, &g_ms_cache[u8_j*512] );
00950 if( CTRL_GOOD != read_status )
00951 return CTRL_GOOD;
00952 u8_j++;
00953 }
00954 }
00955 #endif
00956
00957 if (g_readctx_b_run)
00958 {
00959 host_mem_mem_2_ram_stop();
00960 host_mem_select_lun(lun);
00961 }
00962
00963
00964 host_mem_cbw_init();
00965
00966 g_ms_cbw.lgt_lsb1 = u8_sector_size * (512/256);
00967
00968
00969 g_ms_cbw.dir = SBC_CMD_DIR_OUT;
00970 g_ms_cbw.lgt = 0x0A;
00971 g_ms_cbw.cmd = SBC_CMD_WRITE_10;
00972
00973 g_ms_cbw.u8_data[17-HOST_MS_CBW_DATA_POS] = MSB0(u32_address);
00974 g_ms_cbw.u8_data[18-HOST_MS_CBW_DATA_POS] = MSB1(u32_address);
00975 g_ms_cbw.u8_data[19-HOST_MS_CBW_DATA_POS] = MSB2(u32_address);
00976 g_ms_cbw.u8_data[20-HOST_MS_CBW_DATA_POS] = MSB3(u32_address);
00977
00978
00979 g_ms_cbw.u8_data[23-HOST_MS_CBW_DATA_POS] = 0x01;
00980
00981 if( !host_mem_cbw_send() )
00982 return CTRL_FAIL;
00983
00984 #if (USB_SUPPORT_MS_SECTOR_WR_MAX != 1)
00985 if( 0 != u8_nb_sec_ignore_at_beg )
00986 {
00987
00988
00989 u16_sector -= u8_nb_sec_ignore_at_beg;
00990 for( u8_i=0; u8_i < u8_nb_sec_ignore_at_beg; u8_i++ )
00991 {
00992
00993 nb=HOST_SECTOR_SIZE;
00994 status = host_send_data(DMS_pipe_out(),nb,&g_ms_cache[u8_i*512]);
00995 if(status==PIPE_STALL)
00996 {
00997 host_mem_stall_management();
00998 host_mem_csw_read();
00999 return CTRL_FAIL;
01000 }
01001 }
01002 }
01003 #endif
01004
01005
01006 u16_sector--;
01007 nb=HOST_SECTOR_SIZE;
01008 status = host_send_data(DMS_pipe_out(),nb,ram);
01009 if(status==PIPE_STALL)
01010 {
01011 host_mem_stall_management();
01012 host_mem_csw_read();
01013 return CTRL_FAIL;
01014 }
01015
01016 #if (USB_SUPPORT_MS_SECTOR_WR_MAX != 1)
01017 while( 0 != u16_sector )
01018 {
01019
01020 nb=HOST_SECTOR_SIZE;
01021 status = host_send_data(DMS_pipe_out(),nb,&g_ms_cache[u8_nb_sec_ignore_at_beg*512]);
01022 if(status==PIPE_STALL)
01023 {
01024 host_mem_stall_management();
01025 host_mem_csw_read();
01026 return CTRL_FAIL;
01027 }
01028 u8_nb_sec_ignore_at_beg++;
01029 u16_sector--;
01030 }
01031 #endif
01032
01033
01034 return host_mem_csw_read();
01035 }
01036
01037
01051 Ctrl_status host_mem_mem_2_ram_ext( U8 lun, U32 addr, U8 *ram , U8 u8_nb_sector)
01052 {
01053 Ctrl_status status;
01054 U8 u8_status;
01055 U8 u8_sector_size;
01056 U16 nb;
01057 U32 dCBWDataTransferLength;
01058
01059 if( !host_mem_select_lun(lun) )
01060 return CTRL_FAIL;
01061
01062 u8_sector_size = g_ms_devices[ g_ms_sel_dms ].lun_info[ g_ms_sel_lun ].u8_block_size;
01063
01064 if( 1 < u8_sector_size )
01065 {
01066
01067 while( u8_nb_sector != 0 ) {
01068 status = host_mem_mem_2_ram(lun, addr, ram);
01069 if (status != CTRL_GOOD) return status;
01070 u8_nb_sector--;
01071 addr++;
01072 ram = (U8*)ram + HOST_SECTOR_SIZE;
01073 }
01074 return CTRL_GOOD;
01075 }
01076
01077 if (g_readctx_b_run)
01078 {
01079 host_mem_mem_2_ram_stop();
01080 host_mem_select_lun(lun);
01081 }
01082
01083 dCBWDataTransferLength = (U32)u8_nb_sector * 512;
01084
01085
01086 host_mem_cbw_init();
01087 g_ms_cbw.lgt_lsb0 = LSB0(dCBWDataTransferLength);
01088 g_ms_cbw.lgt_lsb1 = LSB1(dCBWDataTransferLength);
01089 g_ms_cbw.lgt_lsb2 = LSB2(dCBWDataTransferLength);
01090 g_ms_cbw.lgt_lsb3 = LSB3(dCBWDataTransferLength);
01091 g_ms_cbw.dir = SBC_CMD_DIR_IN;
01092 g_ms_cbw.lgt = 0x0A;
01093 g_ms_cbw.cmd = SBC_CMD_READ_10;
01094
01095 g_ms_cbw.u8_data[17-HOST_MS_CBW_DATA_POS] = MSB0(addr);
01096 g_ms_cbw.u8_data[18-HOST_MS_CBW_DATA_POS] = MSB1(addr);
01097 g_ms_cbw.u8_data[19-HOST_MS_CBW_DATA_POS] = MSB2(addr);
01098 g_ms_cbw.u8_data[20-HOST_MS_CBW_DATA_POS] = MSB3(addr);
01099
01100
01101 g_ms_cbw.u8_data[23-HOST_MS_CBW_DATA_POS] = u8_nb_sector;
01102
01103 if( !host_mem_cbw_send() )
01104 return CTRL_FAIL;
01105
01106
01107 nb=HOST_SECTOR_SIZE;
01108 while( u8_nb_sector!= 0 )
01109 {
01110 u8_status = host_get_data(DMS_pipe_in(),&nb,ram);
01111 if(PIPE_GOOD != u8_status)
01112 {
01113 if(PIPE_STALL==u8_status)
01114 host_mem_stall_management();
01115 host_mem_csw_read();
01116 return CTRL_FAIL;
01117 }
01118 u8_nb_sector--;
01119 ram = (U8*)ram + HOST_SECTOR_SIZE;
01120 }
01121
01122
01123 g_readctx_b_run = FALSE;
01124 return host_mem_csw_read();
01125 }
01126
01127
01142 Ctrl_status host_mem_ram_2_mem_ext( U8 lun, U32 addr, U8 *ram , U8 u8_nb_sector)
01143 {
01144 U8 status;
01145 U16 nb;
01146 U8 u8_sector_size;
01147 U32 dCBWDataTransferLength;
01148
01149 if( !host_mem_select_lun(lun) )
01150 return CTRL_FAIL;
01151
01152 u8_sector_size = g_ms_devices[ g_ms_sel_dms ].lun_info[ g_ms_sel_lun ].u8_block_size;
01153
01154 if( 1 < u8_sector_size )
01155 return CTRL_FAIL;
01156
01157
01158 if (g_readctx_b_run)
01159 {
01160 host_mem_mem_2_ram_stop();
01161 host_mem_select_lun(lun);
01162 }
01163
01164 dCBWDataTransferLength = (U32)u8_nb_sector * 512;
01165
01166
01167 host_mem_cbw_init();
01168 g_ms_cbw.lgt_lsb0 = LSB0(dCBWDataTransferLength);
01169 g_ms_cbw.lgt_lsb1 = LSB1(dCBWDataTransferLength);
01170 g_ms_cbw.lgt_lsb2 = LSB2(dCBWDataTransferLength);
01171 g_ms_cbw.lgt_lsb3 = LSB3(dCBWDataTransferLength);
01172 g_ms_cbw.dir = SBC_CMD_DIR_OUT;
01173 g_ms_cbw.lgt = 0x0A;
01174 g_ms_cbw.cmd = SBC_CMD_WRITE_10;
01175
01176 g_ms_cbw.u8_data[17-HOST_MS_CBW_DATA_POS] = MSB0(addr);
01177 g_ms_cbw.u8_data[18-HOST_MS_CBW_DATA_POS] = MSB1(addr);
01178 g_ms_cbw.u8_data[19-HOST_MS_CBW_DATA_POS] = MSB2(addr);
01179 g_ms_cbw.u8_data[20-HOST_MS_CBW_DATA_POS] = MSB3(addr);
01180
01181
01182 g_ms_cbw.u8_data[23-HOST_MS_CBW_DATA_POS] = u8_nb_sector;
01183
01184 if( !host_mem_cbw_send() )
01185 return CTRL_FAIL;
01186
01187
01188 nb=HOST_SECTOR_SIZE;
01189 while( u8_nb_sector!= 0 )
01190 {
01191 status = host_send_data(DMS_pipe_out(),nb,ram);
01192 if(status==PIPE_STALL)
01193 {
01194 host_mem_stall_management();
01195 host_mem_csw_read();
01196 return CTRL_FAIL;
01197 }
01198 u8_nb_sector--;
01199 ram = (U8*)ram + HOST_SECTOR_SIZE;
01200 }
01201
01202
01203 return host_mem_csw_read();
01204 }
01205
01206
01207
01208
01209
01216 Bool host_mem_select_lun(U8 lun)
01217 {
01218 if( !Is_host_ms_configured() )
01219 return FALSE;
01220
01221 for( g_ms_sel_dms=0; g_ms_sel_dms < g_ms_nb_connected; g_ms_sel_dms++ )
01222 {
01223 if(lun < g_ms_devices[g_ms_sel_dms].nb_lun )
01224 {
01225 if( 0xFF == g_ms_devices[g_ms_sel_dms].device_index )
01226 return FALSE;
01227 g_ms_sel_lun = lun;
01228 Host_select_device( g_ms_devices[g_ms_sel_dms].device_index );
01229 return TRUE;
01230 }
01231 lun -= g_ms_devices[g_ms_sel_dms].nb_lun;
01232 }
01233 return FALSE;
01234 }
01235
01236
01239 void host_mem_cbw_init( void )
01240 {
01241 U8 tmp;
01242
01243 tmp = g_ms_cbw.tag_lsb0;
01244
01245 memset( &g_ms_cbw , 0, sizeof(g_ms_cbw) );
01246
01247 g_ms_cbw.flag1 = 'U';
01248 g_ms_cbw.flag2 = 'S';
01249 g_ms_cbw.flag3 = 'B';
01250 g_ms_cbw.flag4 = 'C';
01251
01252 g_ms_cbw.tag_lsb0 = tmp+1;
01253
01254 g_ms_cbw.lun = g_ms_sel_lun;
01255 }
01256
01257
01262 Bool host_mem_cbw_send( void )
01263 {
01264 return (PIPE_GOOD == host_send_data( DMS_pipe_out(), sizeof( g_ms_cbw ), (U8*) &g_ms_cbw ));
01265 }
01266
01267
01276 Ctrl_status host_mem_csw_read( void )
01277 {
01278 U16 nb;
01279 U8 status;
01280 U8 u8_datas[13];
01281 Bool b_status = TRUE;
01282 Bool b_stall = TRUE;
01283
01284 while(1)
01285 {
01286 nb = 13;
01287 status = host_get_data(DMS_pipe_in(),&nb,u8_datas);
01288 if( PIPE_GOOD == status )
01289 break;
01290 if( PIPE_STALL == status )
01291 {
01292 host_mem_stall_management();
01293 if( b_stall )
01294 {
01295 b_stall = FALSE;
01296 continue;
01297 }
01298 }
01299 return CTRL_FAIL;
01300 }
01301
01302 if( PIPE_GOOD == status )
01303 {
01304
01305
01306 if(('U' != u8_datas[0] )
01307 || ('S' != u8_datas[1] )
01308 || ('B' != u8_datas[2] )
01309 || ('S' != u8_datas[3] ) )
01310 {
01311 b_status = FALSE;
01312 }
01313
01314 if((g_ms_cbw.tag_lsb0 != u8_datas[4] )
01315 || (0 != u8_datas[5] )
01316 || (0 != u8_datas[6] )
01317 || (0 != u8_datas[7] ) )
01318 {
01319 b_status = FALSE;
01320 }
01321
01322
01323 if ( 0 != u8_datas[12] )
01324 b_status = FALSE;
01325 }
01326 else
01327 {
01328 b_status = FALSE;
01329 }
01330
01331 if( !b_status )
01332 return host_mem_request_sense();
01333
01334 return CTRL_GOOD;
01335 }
01336
01337
01340 void host_mem_stall_management( void )
01341 {
01342 U8 dummy;
01343
01344 dummy = Host_get_endpoint_number() | ~MSK_EP_DIR;
01345 host_clear_endpoint_feature(dummy);
01346 Host_select_pipe(DMS_pipe_in());
01347 Host_ack_stall();
01348 Host_reset_pipe_data_toggle();
01349 }
01350
01351