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 #include "config.h"
00044 #include <string.h>
00045 #include "conf/conf_usb.h"
00046 #include "host_mem.h"
00047 #include "conf/conf_access.h"
00048 #include "lib_mcu/usb/usb_drv.h"
00049 #include "modules/usb/host_chap9/usb_host_enum.h"
00050 #include "modules/usb/host_chap9/usb_host_task.h"
00051 #include "modules/scsi_decoder/scsi_decoder.h"
00052
00053
00054
00055 #ifndef LOG_STR_CODE
00056 #define LOG_STR_CODE(str)
00057 #else
00058 U8 code log_ms_connect[]="Mass Storage Connected";
00059 #endif
00060 #ifndef HOST_SECTOR_SIZE
00061 #define HOST_SECTOR_SIZE 512 //default sector size is 512 bytes
00062 #endif
00063
00064 #if (USB_HUB_SUPPORT==ENABLE)
00065 #ifndef USB_MAX_DMS_NUMBER
00066 #define USB_MAX_DMS_NUMBER MAX_DEVICE_IN_USB_TREE-1
00067 #endif
00068 #else
00069 #define USB_MAX_DMS_NUMBER 1
00070 #endif
00071
00072 #ifndef USB_SUPPORT_MS_SECTOR_WR_MAX
00073 #define USB_SUPPORT_MS_SECTOR_WR_MAX 1
00074 #endif
00075
00076 #define USB_MAX_LUN_PER_DMS 4
00077
00078
00079 typedef struct
00080 {
00081 U8 flag1;
00082 U8 flag2;
00083 U8 flag3;
00084 U8 flag4;
00085 U8 tag_lsb0;
00086 U8 tag_lsb1;
00087 U8 tag_lsb2;
00088 U8 tag_lsb3;
00089 U8 lgt_lsb0;
00090 U8 lgt_lsb1;
00091 U8 lgt_lsb2;
00092 U8 lgt_lsb3;
00093 U8 dir;
00094 U8 lun;
00095 U8 lgt;
00096 U8 cmd;
00097 U8 u8_data[15];
00098 } S_cbw;
00099
00100
00101 #define HOST_MS_CBW_DATA_POS 16
00102
00103
00104 typedef struct
00105 {
00106 Bool b_first_unitready;
00107 Bool b_protected;
00108 U8 u8_block_size;
00109 } S_lun_info;
00110
00111
00112 typedef struct
00113 {
00114 U8 device_index;
00115 U8 pipe_in;
00116 U8 pipe_out;
00117 U8 nb_lun;
00118 S_lun_info lun_info[USB_MAX_LUN_PER_DMS];
00119 } S_dms_device;
00120
00121
00122
00123
00124
00125 S_cbw g_ms_cbw;
00126 S_dms_device g_ms_devices[USB_MAX_DMS_NUMBER];
00127 U8 g_ms_nb_connected;
00128 U8 g_ms_sel_dms=0;
00129 U8 g_ms_sel_lun;
00130
00131 #if (USB_SUPPORT_MS_SECTOR_WR_MAX != 1)
00132 U8 g_ms_cache[(USB_SUPPORT_MS_SECTOR_WR_MAX-1)*512];
00133 #endif
00134
00135
00136
00137
00138 U8 g_readctx_b_run = FALSE;
00139 U8 g_readctx_u8_device;
00140 U8 g_readctx_u8_lun;
00141 U32 g_readctx_u32_addr;
00142 U16 g_readctx_u16_sector;
00143
00144
00145
00146 #define Is_host_ms_configured() ((g_ms_nb_connected && Is_host_not_suspended() && Is_usb_id_host()) ? TRUE : FALSE )
00147
00148
00149 #define DMS_pipe_in() (g_ms_devices[g_ms_sel_dms].pipe_in)
00150 #define DMS_pipe_out() (g_ms_devices[g_ms_sel_dms].pipe_out)
00151
00152
00153
00154 Ctrl_status host_mem_request_sense ( void );
00155
00156
00157 Bool host_mem_select_lun ( U8 lun );
00158 void host_mem_cbw_init ( void );
00159 Bool host_mem_cbw_send ( void );
00160 Ctrl_status host_mem_csw_read ( void );
00161 void host_mem_stall_management ( void );
00162
00163
00164
00165
00166
00167
00170 void host_mem_init( void )
00171 {
00172 U8 i;
00173
00174 for(i=0; i<USB_MAX_DMS_NUMBER; i++)
00175 {
00176 g_ms_devices[i].device_index=0xFF;
00177 }
00178 g_ms_nb_connected=0;
00179 }
00180
00181
00184 Bool host_mem_install( void )
00185 {
00186 U32 capacity;
00187 U8 device_num;
00188 U8 interface_num;
00189 U8 lun_offset;
00190 U8 i;
00191
00192
00193 for( device_num=0; device_num<Get_nb_device(); device_num++)
00194 {
00195 Host_select_device(device_num);
00196
00197
00198 for( interface_num=0; interface_num < Get_nb_supported_interface(); interface_num++ )
00199 {
00200 if( Get_class(interface_num)!= MS_CLASS )
00201 continue;
00202
00203 LOG_STR_CODE(log_ms_connect);
00204
00205
00206 if( g_ms_nb_connected != 0 )
00207 {
00208
00209 for( i=0; i<g_ms_nb_connected; i++ )
00210 {
00211 if( g_ms_devices[i].device_index == device_num )
00212 break;
00213 }
00214 if( i!=g_ms_nb_connected )
00215 break;
00216
00217 if( USB_MAX_DMS_NUMBER == g_ms_nb_connected )
00218 break;
00219 }
00220
00221
00222 g_ms_devices[g_ms_nb_connected].device_index = device_num;
00223
00224
00225 if(Is_ep_addr_in(Get_ep_addr(interface_num,0)))
00226 {
00227 g_ms_devices[g_ms_nb_connected].pipe_in=usb_tree.device[device_num].interface[interface_num].ep[0].pipe_number;
00228 g_ms_devices[g_ms_nb_connected].pipe_out=usb_tree.device[device_num].interface[interface_num].ep[1].pipe_number;
00229 }
00230 else
00231 {
00232 g_ms_devices[g_ms_nb_connected].pipe_in=usb_tree.device[device_num].interface[interface_num].ep[1].pipe_number;
00233 g_ms_devices[g_ms_nb_connected].pipe_out=usb_tree.device[device_num].interface[interface_num].ep[0].pipe_number;
00234 }
00235
00236
00237 if( CONTROL_GOOD != host_ms_get_max_lun() )
00238 data_stage[0] = 0;
00239 g_ms_devices[g_ms_nb_connected].nb_lun = data_stage[0]+1;
00240
00241 if( USB_MAX_LUN_PER_DMS < g_ms_devices[g_ms_nb_connected].nb_lun )
00242 g_ms_devices[g_ms_nb_connected].nb_lun = USB_MAX_LUN_PER_DMS;
00243
00244
00245 lun_offset = 0;
00246 for( i=0; i<g_ms_nb_connected; i++)
00247 {
00248 lun_offset +=g_ms_devices[i].nb_lun;
00249 }
00250
00251
00252 g_ms_sel_dms = g_ms_nb_connected;
00253 g_ms_nb_connected++;
00254
00255
00256 for( i=0; i<g_ms_devices[g_ms_sel_dms].nb_lun; i++ )
00257 {
00258
00259 g_ms_devices[g_ms_sel_dms].lun_info[i].b_first_unitready = FALSE;
00260 g_ms_devices[g_ms_sel_dms].lun_info[i].b_protected = TRUE;
00261
00262 host_mem_inquiry( lun_offset+i );
00263 host_mem_read_capacity( lun_offset+i, &capacity );
00264 }
00265 return TRUE;
00266 }
00267 }
00268 return FALSE;
00269 }
00270
00271
00274 void host_mem_uninstall( void )
00275 {
00276 U8 device_num;
00277 U8 i;
00278 Bool b_last_ms_conected = TRUE;
00279
00280 for( i=g_ms_nb_connected; i!=0; i--)
00281 {
00282 device_num = g_ms_devices[i-1].device_index;
00283 if( 0xFF == device_num )
00284 {
00285
00286
00287 g_ms_nb_connected--;
00288 continue;
00289 }
00290 if( 0 == usb_tree.device[device_num].device_address )
00291 {
00292 g_ms_devices[i-1].device_index = 0xFF;
00293 if( b_last_ms_conected )
00294 g_ms_nb_connected--;
00295 }else{
00296 b_last_ms_conected = FALSE;
00297 }
00298 }
00299 }
00300
00301
00306 U8 host_mem_get_lun( void )
00307 {
00308 U8 i;
00309 U8 host_ms_max_lun = 0;
00310
00311 if(!Is_host_ms_configured())
00312 return 0;
00313
00314 for( i=0; i<g_ms_nb_connected; i++ )
00315 {
00316 host_ms_max_lun += g_ms_devices[i].nb_lun;
00317 }
00318 return host_ms_max_lun;
00319 }
00320
00321
00322
00323
00324
00325
00334 Ctrl_status host_mem_test_unit_ready(U8 lun)
00335 {
00336 Ctrl_status status;
00337 U32 u32_nb_sector;
00338
00339 if( !host_mem_select_lun(lun) )
00340 return CTRL_NO_PRESENT;
00341 if (g_readctx_b_run)
00342 {
00343 host_mem_mem_2_ram_stop();
00344 host_mem_select_lun(lun);
00345 }
00346
00347
00348 host_mem_cbw_init();
00349
00350 g_ms_cbw.dir = SBC_CMD_DIR_OUT;
00351 g_ms_cbw.lgt = 0x06;
00352 g_ms_cbw.cmd = SBC_CMD_TEST_UNIT_READY;
00353 if( !host_mem_cbw_send() )
00354 return CTRL_FAIL;
00355
00356
00357 status = host_mem_csw_read();
00358 if( status == CTRL_GOOD )
00359 {
00360 if( FALSE == g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].b_first_unitready )
00361 {
00362
00363 status = CTRL_BUSY;
00364
00365 if( CTRL_GOOD == host_mem_read_capacity( lun , &u32_nb_sector ) )
00366 {
00367 g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].b_protected = host_mem_wr_protect( lun );
00368 g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].b_first_unitready = TRUE;
00369 }
00370 }
00371 }
00372 else
00373 {
00374 g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].b_first_unitready = FALSE;
00375 }
00376 return status;
00377 }
00378
00379
00389 Ctrl_status host_mem_read_capacity(U8 lun, U32 _MEM_TYPE_SLOW_ *u32_nb_sector )
00390 {
00391 U16 nb;
00392 U8 datas[8], status;
00393
00394 if( !host_mem_select_lun(lun) )
00395 return CTRL_NO_PRESENT;
00396 if (g_readctx_b_run)
00397 {
00398 host_mem_mem_2_ram_stop();
00399 host_mem_select_lun(lun);
00400 }
00401
00402
00403 host_mem_cbw_init();
00404 g_ms_cbw.lgt_lsb0 = 0x08;
00405 g_ms_cbw.dir = SBC_CMD_DIR_IN;
00406 g_ms_cbw.lgt = 0x0A;
00407 g_ms_cbw.cmd = SBC_CMD_READ_CAPACITY;
00408 if( !host_mem_cbw_send() )
00409 return CTRL_FAIL;
00410
00411
00412 nb=8;
00413 status = host_get_data(DMS_pipe_in(),&nb,datas);
00414 if( PIPE_GOOD != status )
00415 {
00416 if( PIPE_STALL == status )
00417 host_mem_stall_management();
00418 host_mem_csw_read();
00419 return CTRL_FAIL;
00420 }
00421
00422
00423 MSB0(*u32_nb_sector) = datas[0];
00424 MSB1(*u32_nb_sector) = datas[1];
00425 MSB2(*u32_nb_sector) = datas[2];
00426 MSB3(*u32_nb_sector) = datas[3];
00427
00428 g_ms_devices[ g_ms_sel_dms ].lun_info[ g_ms_sel_lun ].u8_block_size = datas[6]/2;
00429
00430
00431 return host_mem_csw_read();
00432 }
00433
00434
00441 U8 host_mem_read_sector_size( U8 lun )
00442 {
00443 host_mem_test_unit_ready( lun );
00444 if( !host_mem_select_lun(lun) )
00445 return 1;
00446 return g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].u8_block_size;
00447 }
00448
00449
00457 Bool host_mem_wr_protect_cache( U8 lun )
00458 {
00459 if( !host_mem_select_lun(lun) )
00460 return TRUE;
00461
00462 return g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].b_protected;
00463 }
00464
00465
00472 Bool host_mem_wr_protect( U8 lun )
00473 {
00474 U16 nb;
00475 U8 write_code[0x0C], status;
00476
00477 if( !host_mem_select_lun(lun) )
00478 return TRUE;
00479
00480 if( USB_SUPPORT_MS_SECTOR_WR_MAX < g_ms_devices[ g_ms_sel_dms ].lun_info[ g_ms_sel_lun ].u8_block_size )
00481 return TRUE;
00482
00483 if (g_readctx_b_run)
00484 {
00485 host_mem_mem_2_ram_stop();
00486 host_mem_select_lun(lun);
00487 }
00488
00489
00490 host_mem_cbw_init();
00491 g_ms_cbw.dir = SBC_CMD_DIR_IN;
00492 g_ms_cbw.lgt = 0x06;
00493 g_ms_cbw.cmd = SBC_CMD_MODE_SENSE_6;
00494 g_ms_cbw.lgt_lsb0 = 0x0C;
00495
00496 g_ms_cbw.u8_data[17-16] = 0x3F;
00497
00498 g_ms_cbw.u8_data[19-16] = 0x0C;
00499
00500 if( !host_mem_cbw_send() )
00501 return TRUE;
00502
00503
00504 nb=0x0C;
00505 status = host_get_data(DMS_pipe_in(),&nb,write_code);
00506 if( PIPE_GOOD != status )
00507 {
00508 if( PIPE_STALL == status )
00509 host_mem_stall_management();
00510 write_code[2] = 0x00;
00511 }
00512
00513
00514 host_mem_csw_read();
00515
00516 return (write_code[2] == 0x80);
00517 }
00518
00519
00524 Bool host_mem_removal(void)
00525 {
00526 return TRUE;
00527 }
00528
00529
00540
00541
00542
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
00597 Ctrl_status host_mem_inquiry( U8 lun )
00598 {
00599 U16 nb;
00600 U8 datas[31], status;
00601
00602 if( !host_mem_select_lun(lun) )
00603 return CTRL_NO_PRESENT;
00604 if (g_readctx_b_run)
00605 {
00606 host_mem_mem_2_ram_stop();
00607 host_mem_select_lun(lun);
00608 }
00609
00610 host_mem_cbw_init();
00611 g_ms_cbw.lgt_lsb0 = 0x24;
00612 g_ms_cbw.dir = SBC_CMD_DIR_IN;
00613 g_ms_cbw.lgt = 0x06;
00614 g_ms_cbw.cmd = SBC_CMD_INQUIRY;
00615
00616
00617
00618 g_ms_cbw.u8_data[19-16] = 0x24;
00619
00620 if( !host_mem_cbw_send() )
00621 return CTRL_FAIL;
00622
00623
00624
00625 nb=31;
00626 status = host_get_data(DMS_pipe_in(),&nb,datas);
00627
00628 if( PIPE_STALL == status )
00629 host_mem_stall_management();
00630
00631
00632 return host_mem_csw_read();
00633 }
00634
00635
00644 Ctrl_status host_mem_request_sense( void )
00645 {
00646 U16 nb;
00647 U8 datas[17], status;
00648 U8 sense_key, sense_key_add;
00649
00650
00651 host_mem_cbw_init();
00652 g_ms_cbw.lgt_lsb0 = 0x12;
00653 g_ms_cbw.dir = SBC_CMD_DIR_IN;
00654 g_ms_cbw.lgt = 0x06;
00655 g_ms_cbw.cmd = SBC_CMD_REQUEST_SENSE;
00656
00657
00658
00659 g_ms_cbw.u8_data[19-HOST_MS_CBW_DATA_POS] = 0x12;
00660
00661 if( !host_mem_cbw_send() )
00662 return CTRL_FAIL;
00663
00664
00665 nb=17;
00666 status = host_get_data(DMS_pipe_in(),&nb,datas);
00667 if( PIPE_GOOD != status )
00668 {
00669 if( PIPE_STALL == status )
00670 host_mem_stall_management();
00671 return CTRL_FAIL;
00672 }
00673
00674
00675
00676
00677 sense_key = (0x0F & datas[2]);
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688 sense_key_add = datas[12];
00689
00690
00691
00692
00693
00694
00695
00696 nb=13;
00697 status = host_get_data(DMS_pipe_in(),&nb,datas);
00698 if( PIPE_GOOD != status )
00699 {
00700 if( PIPE_STALL == status )
00701 host_mem_stall_management();
00702 return CTRL_FAIL;
00703 }
00704
00705
00706 switch( sense_key )
00707 {
00708 case SBC_SENSE_KEY_NOT_READY:
00709 if( SBC_ASC_MEDIUM_NOT_PRESENT == sense_key_add )
00710 return CTRL_NO_PRESENT;
00711 break;
00712
00713 case SBC_SENSE_KEY_UNIT_ATTENTION:
00714 if( SBC_ASC_NOT_READY_TO_READY_CHANGE == sense_key_add )
00715 return CTRL_BUSY;
00716 if( SBC_ASC_MEDIUM_NOT_PRESENT == sense_key_add )
00717 return CTRL_NO_PRESENT;
00718 break;
00719
00720
00721
00722
00723
00724
00725 }
00726 return CTRL_FAIL;
00727 }
00728
00729
00730
00731
00732
00733
00747 Ctrl_status host_mem_mem_2_ram( U8 lun, U32 addr, U8 *ram )
00748 {
00749 U8 status;
00750 U16 nb;
00751 U8 u8_nb_sec_ignore_at_beg, u8_sector_size;
00752 U32 u32_address;
00753
00754 if( !host_mem_select_lun(lun) )
00755 return CTRL_FAIL;
00756
00757 u8_nb_sec_ignore_at_beg = 0;
00758
00759 if( g_readctx_b_run )
00760 {
00761
00762 if( ( g_ms_devices[g_ms_sel_dms].device_index != g_readctx_u8_device)
00763 || ( g_readctx_u8_lun != g_ms_sel_lun)
00764 || ( g_readctx_u32_addr > addr)
00765 || ( (g_readctx_u32_addr+g_readctx_u16_sector) <= addr ) )
00766 {
00767 host_mem_mem_2_ram_stop();
00768 host_mem_select_lun(lun);
00769 }else{
00770 u8_nb_sec_ignore_at_beg = addr-g_readctx_u32_addr;
00771 }
00772 }
00773
00774 if( !g_readctx_b_run )
00775 {
00776 u8_sector_size = g_ms_devices[ g_ms_sel_dms ].lun_info[ g_ms_sel_lun ].u8_block_size;
00777
00778
00779 u32_address = addr / u8_sector_size;
00780
00781 u8_nb_sec_ignore_at_beg = addr % u8_sector_size;
00782
00783 g_readctx_u16_sector = u8_sector_size;
00784 g_readctx_u32_addr = addr - u8_nb_sec_ignore_at_beg;
00785
00786
00787 host_mem_cbw_init();
00788 g_ms_cbw.lgt_lsb0 = 0x00;
00789 g_ms_cbw.lgt_lsb1 = u8_sector_size * (512/256);
00790 g_ms_cbw.lgt_lsb2 = 0x00;
00791 g_ms_cbw.lgt_lsb3 = 0x00;
00792 g_ms_cbw.dir = SBC_CMD_DIR_IN;
00793 g_ms_cbw.lgt = 0x0A;
00794 g_ms_cbw.cmd = SBC_CMD_READ_10;
00795
00796 g_ms_cbw.u8_data[17-HOST_MS_CBW_DATA_POS] = MSB0(u32_address);
00797 g_ms_cbw.u8_data[18-HOST_MS_CBW_DATA_POS] = MSB1(u32_address);
00798 g_ms_cbw.u8_data[19-HOST_MS_CBW_DATA_POS] = MSB2(u32_address);
00799 g_ms_cbw.u8_data[20-HOST_MS_CBW_DATA_POS] = MSB3(u32_address);
00800
00801
00802 g_ms_cbw.u8_data[23-HOST_MS_CBW_DATA_POS] = 0x01;
00803
00804 if( !host_mem_cbw_send() )
00805 return CTRL_FAIL;
00806 }
00807
00808 if( 0 != u8_nb_sec_ignore_at_beg )
00809 {
00810
00811
00812 g_readctx_u16_sector -= u8_nb_sec_ignore_at_beg;
00813 g_readctx_u32_addr += u8_nb_sec_ignore_at_beg;
00814 while( 0 != u8_nb_sec_ignore_at_beg )
00815 {
00816
00817 nb=HOST_SECTOR_SIZE;
00818 status = host_get_data(DMS_pipe_in(),&nb,NULL);
00819 if(PIPE_GOOD != status)
00820 {
00821 if(PIPE_STALL==status)
00822 host_mem_stall_management();
00823 host_mem_csw_read();
00824 return CTRL_FAIL;
00825 }
00826 u8_nb_sec_ignore_at_beg--;
00827 }
00828 }
00829
00830
00831 g_readctx_u16_sector--;
00832 g_readctx_u32_addr++;
00833 nb=HOST_SECTOR_SIZE;
00834 status = host_get_data(DMS_pipe_in(),&nb,ram);
00835 if(PIPE_GOOD != status)
00836 {
00837 if(PIPE_STALL==status)
00838 host_mem_stall_management();
00839 host_mem_csw_read();
00840 return CTRL_FAIL;
00841 }
00842
00843 if( 0 != g_readctx_u16_sector )
00844 {
00845
00846 g_readctx_u8_device = g_ms_devices[g_ms_sel_dms].device_index;
00847 g_readctx_u8_lun = g_ms_sel_lun;
00848 g_readctx_b_run = TRUE;
00849 return CTRL_GOOD;
00850 }
00851
00852
00853 g_readctx_b_run = FALSE;
00854 return host_mem_csw_read();
00855 }
00856
00857
00866 Ctrl_status host_mem_mem_2_ram_stop( void )
00867 {
00868 U16 nb;
00869 U8 status;
00870
00871 g_readctx_b_run = FALSE;
00872
00873 g_ms_sel_lun = g_readctx_u8_lun;
00874 g_ms_sel_dms = g_readctx_u8_device;
00875 Host_select_device( g_ms_devices[g_ms_sel_dms].device_index );
00876
00877 while( 0 != g_readctx_u16_sector )
00878 {
00879
00880 nb=HOST_SECTOR_SIZE;
00881 status = host_get_data(DMS_pipe_in(),&nb,NULL);
00882 if(PIPE_GOOD != status)
00883 {
00884 if(PIPE_STALL==status)
00885 host_mem_stall_management();
00886 host_mem_csw_read();
00887 return CTRL_FAIL;
00888 }
00889 g_readctx_u16_sector--;
00890 }
00891
00892
00893 return host_mem_csw_read();
00894 }
00895
00896
00910 Ctrl_status host_mem_ram_2_mem( U8 lun, U32 addr, U8 *ram )
00911 {
00912 U8 status;
00913 U16 nb, u16_sector;
00914 U8 u8_nb_sec_ignore_at_beg, u8_sector_size;
00915 U32 u32_address;
00916 #if (USB_SUPPORT_MS_SECTOR_WR_MAX != 1)
00917 Ctrl_status read_status;
00918 U8 u8_i,u8_j;
00919 U32 u32_addr;
00920 #endif
00921
00922 if( !host_mem_select_lun(lun) )
00923 return CTRL_FAIL;
00924
00925 u8_sector_size = g_ms_devices[ g_ms_sel_dms ].lun_info[ g_ms_sel_lun ].u8_block_size;
00926
00927 if( USB_SUPPORT_MS_SECTOR_WR_MAX < u8_sector_size )
00928 return CTRL_FAIL;
00929
00930
00931
00932 u32_address = addr / u8_sector_size;
00933
00934 u8_nb_sec_ignore_at_beg = addr % u8_sector_size;
00935
00936 u16_sector = u8_sector_size;
00937
00938 #if (USB_SUPPORT_MS_SECTOR_WR_MAX != 1)
00939
00940 if( 1 != u8_sector_size )
00941 {
00942 u32_addr = addr - u8_nb_sec_ignore_at_beg;
00943 for( u8_i=0,u8_j=0 ; u8_i<u8_sector_size; u8_i++,u32_addr++ )
00944 {
00945 if( u8_i == u8_nb_sec_ignore_at_beg )
00946 continue;
00947 read_status = host_mem_mem_2_ram( lun, u32_addr, &g_ms_cache[u8_j*512] );
00948 if( CTRL_GOOD != read_status )
00949 return CTRL_GOOD;
00950 u8_j++;
00951 }
00952 }
00953 #endif
00954
00955 if (g_readctx_b_run)
00956 {
00957 host_mem_mem_2_ram_stop();
00958 host_mem_select_lun(lun);
00959 }
00960
00961
00962 host_mem_cbw_init();
00963
00964 g_ms_cbw.lgt_lsb1 = u8_sector_size * (512/256);
00965
00966
00967 g_ms_cbw.dir = SBC_CMD_DIR_OUT;
00968 g_ms_cbw.lgt = 0x0A;
00969 g_ms_cbw.cmd = SBC_CMD_WRITE_10;
00970
00971 g_ms_cbw.u8_data[17-HOST_MS_CBW_DATA_POS] = MSB0(u32_address);
00972 g_ms_cbw.u8_data[18-HOST_MS_CBW_DATA_POS] = MSB1(u32_address);
00973 g_ms_cbw.u8_data[19-HOST_MS_CBW_DATA_POS] = MSB2(u32_address);
00974 g_ms_cbw.u8_data[20-HOST_MS_CBW_DATA_POS] = MSB3(u32_address);
00975
00976
00977 g_ms_cbw.u8_data[23-HOST_MS_CBW_DATA_POS] = 0x01;
00978
00979 if( !host_mem_cbw_send() )
00980 return CTRL_FAIL;
00981
00982 #if (USB_SUPPORT_MS_SECTOR_WR_MAX != 1)
00983 if( 0 != u8_nb_sec_ignore_at_beg )
00984 {
00985
00986
00987 u16_sector -= u8_nb_sec_ignore_at_beg;
00988 for( u8_i=0; u8_i < u8_nb_sec_ignore_at_beg; u8_i++ )
00989 {
00990
00991 nb=HOST_SECTOR_SIZE;
00992 status = host_send_data(DMS_pipe_out(),nb,&g_ms_cache[u8_i*512]);
00993 if(status==PIPE_STALL)
00994 {
00995 host_mem_stall_management();
00996 host_mem_csw_read();
00997 return CTRL_FAIL;
00998 }
00999 }
01000 }
01001 #endif
01002
01003
01004 u16_sector--;
01005 nb=HOST_SECTOR_SIZE;
01006 status = host_send_data(DMS_pipe_out(),nb,ram);
01007 if(status==PIPE_STALL)
01008 {
01009 host_mem_stall_management();
01010 host_mem_csw_read();
01011 return CTRL_FAIL;
01012 }
01013
01014 #if (USB_SUPPORT_MS_SECTOR_WR_MAX != 1)
01015 while( 0 != u16_sector )
01016 {
01017
01018 nb=HOST_SECTOR_SIZE;
01019 status = host_send_data(DMS_pipe_out(),nb,&g_ms_cache[u8_nb_sec_ignore_at_beg*512]);
01020 if(status==PIPE_STALL)
01021 {
01022 host_mem_stall_management();
01023 host_mem_csw_read();
01024 return CTRL_FAIL;
01025 }
01026 u8_nb_sec_ignore_at_beg++;
01027 u16_sector--;
01028 }
01029 #endif
01030
01031
01032 return host_mem_csw_read();
01033 }
01034
01035
01036
01037
01038
01045 Bool host_mem_select_lun(U8 lun)
01046 {
01047 if( !Is_host_ms_configured() )
01048 return FALSE;
01049
01050 for( g_ms_sel_dms=0; g_ms_sel_dms < g_ms_nb_connected; g_ms_sel_dms++ )
01051 {
01052 if(lun < g_ms_devices[g_ms_sel_dms].nb_lun )
01053 {
01054 if( 0xFF == g_ms_devices[g_ms_sel_dms].device_index )
01055 return FALSE;
01056 g_ms_sel_lun = lun;
01057 Host_select_device( g_ms_devices[g_ms_sel_dms].device_index );
01058 return TRUE;
01059 }
01060 lun -= g_ms_devices[g_ms_sel_dms].nb_lun;
01061 }
01062 return FALSE;
01063 }
01064
01065
01068 void host_mem_cbw_init( void )
01069 {
01070 U8 tmp;
01071
01072 tmp = g_ms_cbw.tag_lsb0;
01073
01074 memset( &g_ms_cbw , 0, sizeof(g_ms_cbw) );
01075
01076 g_ms_cbw.flag1 = 'U';
01077 g_ms_cbw.flag2 = 'S';
01078 g_ms_cbw.flag3 = 'B';
01079 g_ms_cbw.flag4 = 'C';
01080
01081 g_ms_cbw.tag_lsb0 = tmp+1;
01082
01083 g_ms_cbw.lun = g_ms_sel_lun;
01084 }
01085
01086
01091 Bool host_mem_cbw_send( void )
01092 {
01093 return (PIPE_GOOD == host_send_data( DMS_pipe_out(), sizeof( g_ms_cbw ), (U8*) &g_ms_cbw ));
01094 }
01095
01096
01105 Ctrl_status host_mem_csw_read( void )
01106 {
01107 U16 nb;
01108 U8 status;
01109 U8 u8_datas[13];
01110 Bool b_status = TRUE;
01111 Bool b_stall = TRUE;
01112
01113 while(1)
01114 {
01115 nb = 13;
01116 status = host_get_data(DMS_pipe_in(),&nb,u8_datas);
01117 if( PIPE_GOOD == status )
01118 break;
01119 if( PIPE_STALL == status )
01120 {
01121 host_mem_stall_management();
01122 if( b_stall )
01123 {
01124 b_stall = FALSE;
01125 continue;
01126 }
01127 }
01128 return CTRL_FAIL;
01129 }
01130
01131 if( PIPE_GOOD == status )
01132 {
01133
01134
01135 if(('U' != u8_datas[0] )
01136 || ('S' != u8_datas[1] )
01137 || ('B' != u8_datas[2] )
01138 || ('S' != u8_datas[3] ) )
01139 {
01140 b_status = FALSE;
01141 }
01142
01143 if((g_ms_cbw.tag_lsb0 != u8_datas[4] )
01144 || (0 != u8_datas[5] )
01145 || (0 != u8_datas[6] )
01146 || (0 != u8_datas[7] ) )
01147 {
01148 b_status = FALSE;
01149 }
01150
01151
01152 if ( 0 != u8_datas[12] )
01153 b_status = FALSE;
01154 }
01155 else
01156 {
01157 b_status = FALSE;
01158 }
01159
01160 if( !b_status )
01161 return host_mem_request_sense();
01162
01163 return CTRL_GOOD;
01164 }
01165
01166
01169 void host_mem_stall_management( void )
01170 {
01171 U8 dummy;
01172
01173 dummy = Host_get_endpoint_number() | ~MSK_EP_DIR;
01174 host_clear_endpoint_feature(dummy);
01175 Host_select_pipe(DMS_pipe_in());
01176 Host_ack_stall();
01177 Host_reset_pipe_data_toggle();
01178 }
01179
01180