#include "config.h"#include <string.h>#include "conf/conf_usb.h"#include "host_mem.h"#include "conf/conf_access.h"#include "lib_mcu/usb/usb_drv.h"#include "modules/usb/host_chap9/usb_host_enum.h"#include "modules/usb/host_chap9/usb_host_task.h"#include "modules/scsi_decoder/scsi_decoder.h"
Go to the source code of this file.
Data Structures | |
| struct | S_cbw |
| struct | S_lun_info |
| struct | S_dms_device |
Defines | |
| #define | LOG_STR_CODE(str) |
| #define | HOST_SECTOR_SIZE 512 |
| #define | USB_MAX_DMS_NUMBER MAX_DEVICE_IN_USB_TREE-1 |
| #define | USB_SUPPORT_MS_SECTOR_WR_MAX 1 |
| #define | USB_MAX_LUN_PER_DMS 4 |
| #define | HOST_MS_CBW_DATA_POS 16 |
| #define | Is_host_ms_configured() ((g_ms_nb_connected && Is_host_not_suspended() && Is_usb_id_host()) ? TRUE : FALSE ) |
| #define | DMS_pipe_in() (g_ms_devices[g_ms_sel_dms].pipe_in) |
| #define | DMS_pipe_out() (g_ms_devices[g_ms_sel_dms].pipe_out) |
Functions | |
| Ctrl_status | host_mem_request_sense (void) |
| Bool | host_mem_select_lun (U8 lun) |
| Select the USB device corresponding at the LUN. | |
| void | host_mem_cbw_init (void) |
| Bool | host_mem_cbw_send (void) |
| Ctrl_status | host_mem_csw_read (void) |
| void | host_mem_stall_management (void) |
| This function writes data from the usb memory. | |
| void | host_mem_init (void) |
| This fonction must be call only once at the program startup to initialize the USB driver MS. | |
| Bool | host_mem_install (void) |
| This fonction must be call when a device is connected. | |
| void | host_mem_uninstall (void) |
| This fonction must be call when a device is disconnected. | |
| U8 | host_mem_get_lun (void) |
| This fonction returns the number of LUN of the devices mass storage connected to the host. | |
| Ctrl_status | host_mem_test_unit_ready (U8 lun) |
| This fonction test the state of memory, and start the initialisation of the memory. | |
| Ctrl_status | host_mem_read_capacity (U8 lun, U32 _MEM_TYPE_SLOW_ *u32_nb_sector) |
| This fonction returns the address of the last valid sector. | |
| U8 | host_mem_read_sector_size (U8 lun) |
| Bool | host_mem_wr_protect_cache (U8 lun) |
| Bool | host_mem_wr_protect (U8 lun) |
| Bool | host_mem_removal (void) |
| This fonction inform about the memory type. | |
| Ctrl_status | host_mem_inquiry (U8 lun) |
| Ctrl_status | host_mem_mem_2_ram (U8 lun, U32 addr, U8 *ram) |
| Ctrl_status | host_mem_mem_2_ram_stop (void) |
| This function terminates the tranfer of a physical sector from memory. | |
| Ctrl_status | host_mem_ram_2_mem (U8 lun, U32 addr, U8 *ram) |
Variables | |
| S_cbw | g_ms_cbw |
| S_dms_device | g_ms_devices [MAX_DEVICE_IN_USB_TREE-1] |
| U8 | g_ms_nb_connected |
| U8 | g_ms_sel_dms = 0 |
| U8 | g_ms_sel_lun |
| U8 | g_readctx_b_run = FALSE |
| U8 | g_readctx_u8_device |
| U8 | g_readctx_u8_lun |
| U32 | g_readctx_u32_addr |
| U16 | g_readctx_u16_sector |
Definition in file host_mem.c.
| #define LOG_STR_CODE | ( | str | ) |
Definition at line 56 of file host_mem.c.
| #define HOST_SECTOR_SIZE 512 |
Definition at line 61 of file host_mem.c.
Referenced by host_mem_mem_2_ram(), host_mem_mem_2_ram_stop(), and host_mem_ram_2_mem().
| #define USB_MAX_DMS_NUMBER MAX_DEVICE_IN_USB_TREE-1 |
| #define USB_SUPPORT_MS_SECTOR_WR_MAX 1 |
Definition at line 73 of file host_mem.c.
| #define USB_MAX_LUN_PER_DMS 4 |
| #define HOST_MS_CBW_DATA_POS 16 |
Definition at line 101 of file host_mem.c.
Referenced by host_mem_mem_2_ram(), host_mem_ram_2_mem(), and host_mem_request_sense().
| #define Is_host_ms_configured | ( | ) | ((g_ms_nb_connected && Is_host_not_suspended() && Is_usb_id_host()) ? TRUE : FALSE ) |
Definition at line 146 of file host_mem.c.
Referenced by host_mem_get_lun(), and host_mem_select_lun().
| #define DMS_pipe_in | ( | ) | (g_ms_devices[g_ms_sel_dms].pipe_in) |
Definition at line 149 of file host_mem.c.
Referenced by host_mem_csw_read(), host_mem_inquiry(), host_mem_mem_2_ram(), host_mem_mem_2_ram_stop(), host_mem_read_capacity(), host_mem_request_sense(), host_mem_stall_management(), and host_mem_wr_protect().
| #define DMS_pipe_out | ( | ) | (g_ms_devices[g_ms_sel_dms].pipe_out) |
Definition at line 150 of file host_mem.c.
Referenced by host_mem_cbw_send(), and host_mem_ram_2_mem().
| Ctrl_status host_mem_request_sense | ( | void | ) |
Read the error informations about last command FAIL
Definition at line 644 of file host_mem.c.
References S_cbw::cmd, CTRL_BUSY, CTRL_FAIL, CTRL_NO_PRESENT, S_cbw::dir, DMS_pipe_in, host_get_data(), host_mem_cbw_init(), host_mem_cbw_send(), host_mem_stall_management(), HOST_MS_CBW_DATA_POS, S_cbw::lgt, S_cbw::lgt_lsb0, PIPE_GOOD, PIPE_STALL, SBC_ASC_MEDIUM_NOT_PRESENT, SBC_ASC_NOT_READY_TO_READY_CHANGE, SBC_CMD_DIR_IN, SBC_CMD_REQUEST_SENSE, SBC_SENSE_KEY_NOT_READY, SBC_SENSE_KEY_UNIT_ATTENTION, and S_cbw::u8_data.
Referenced by host_mem_csw_read().
00645 { 00646 U16 nb; 00647 U8 datas[17], status; 00648 U8 sense_key, sense_key_add; 00649 00650 // Send CBW 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 //g_ms_cbw.u8_data[16-HOST_MS_CBW_DATA_POS] = 0x00; // 16 - CBWCB1 - reserved 00657 //g_ms_cbw.u8_data[17-HOST_MS_CBW_DATA_POS] = 0x00; // 17 - CBWCB2 - reserved 00658 //g_ms_cbw.u8_data[18-HOST_MS_CBW_DATA_POS] = 0x00; // 18 - CBWCB3 - reserved 00659 g_ms_cbw.u8_data[19-HOST_MS_CBW_DATA_POS] = 0x12; // 19 - CBWCB4 - Allocation Length 00660 //g_ms_cbw.u8_data[20-HOST_MS_CBW_DATA_POS] = 0x00; // 20 - CBWCW5 - Control 00661 if( !host_mem_cbw_send() ) 00662 return CTRL_FAIL; 00663 00664 // Receiv Sense Code 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 // 0 - Response Code 00675 // 1 - obsolete 00676 // 2 - Sense Key 00677 sense_key = (0x0F & datas[2]); 00678 // 3 - MSB3(Information) 00679 // 4 - MSB2(Information) 00680 // 5 - MSB1(Information) 00681 // 6 - MSB0(Information) 00682 // 7 - Additional Sense Length 00683 // 8 - MSB3(Command Specific Information) 00684 // 9 - MSB2(Command Specific Information) 00685 // 10 - MSB1(Command Specific Information) 00686 // 11 - MSB0(Command Specific Information) 00687 // 12 - Additional Sense Code 00688 sense_key_add = datas[12]; 00689 // 13 - Additional Sense Code Qualifier 00690 // 14 - Field Replaceable Unit Code 00691 // 15 - MSB2(Sense Key Specific) 00692 // 16 - MSB1(Sense Key Specific) 00693 // 17 - MSB0(Sense Key Specific) 00694 00695 // Receiv CSW, but ignore status 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 // Translate Sense Code to device status 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 case SBC_SENSE_KEY_NO_SENSE: 00721 case SBC_SENSE_KEY_HARDWARE_ERROR: 00722 case SBC_SENSE_KEY_DATA_PROTECT: 00723 break; 00724 */ 00725 } 00726 return CTRL_FAIL; // By default FAIL 00727 }
Select the USB device corresponding at the LUN.
| lun | LUN number to select |
Definition at line 1045 of file host_mem.c.
References FALSE, g_ms_nb_connected, g_ms_sel_dms, g_ms_sel_lun, Host_select_device, Is_host_ms_configured, S_dms_device::nb_lun, and TRUE.
Referenced by host_mem_inquiry(), host_mem_mem_2_ram(), host_mem_ram_2_mem(), host_mem_read_capacity(), host_mem_read_sector_size(), host_mem_test_unit_ready(), host_mem_wr_protect(), and host_mem_wr_protect_cache().
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; // Device disconnected 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 }
| void host_mem_cbw_init | ( | void | ) |
Initialize at 0 the data of cbw command
Definition at line 1068 of file host_mem.c.
References S_cbw::flag1, S_cbw::flag2, S_cbw::flag3, S_cbw::flag4, g_ms_sel_lun, S_cbw::lun, and S_cbw::tag_lsb0.
Referenced by host_mem_inquiry(), host_mem_mem_2_ram(), host_mem_ram_2_mem(), host_mem_read_capacity(), host_mem_request_sense(), host_mem_test_unit_ready(), and host_mem_wr_protect().
01069 { 01070 U8 tmp; 01071 01072 tmp = g_ms_cbw.tag_lsb0; 01073 // Clear all structure 01074 memset( &g_ms_cbw , 0, sizeof(g_ms_cbw) ); 01075 // Write Flag 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 // Increment tag 01081 g_ms_cbw.tag_lsb0 = tmp+1; 01082 // Update LUN 01083 g_ms_cbw.lun = g_ms_sel_lun; 01084 }
| Bool host_mem_cbw_send | ( | void | ) |
Send the CBW command
Definition at line 1091 of file host_mem.c.
References DMS_pipe_out, host_send_data(), and PIPE_GOOD.
Referenced by host_mem_inquiry(), host_mem_mem_2_ram(), host_mem_ram_2_mem(), host_mem_read_capacity(), host_mem_request_sense(), host_mem_test_unit_ready(), and host_mem_wr_protect().
01092 { 01093 return (PIPE_GOOD == host_send_data( DMS_pipe_out(), sizeof( g_ms_cbw ), (U8*) &g_ms_cbw )); 01094 }
| Ctrl_status host_mem_csw_read | ( | void | ) |
Wait and read CSW status
Definition at line 1105 of file host_mem.c.
References CTRL_FAIL, CTRL_GOOD, DMS_pipe_in, FALSE, host_get_data(), host_mem_request_sense(), host_mem_stall_management(), PIPE_GOOD, PIPE_STALL, S_cbw::tag_lsb0, and TRUE.
Referenced by host_mem_inquiry(), host_mem_mem_2_ram(), host_mem_mem_2_ram_stop(), host_mem_ram_2_mem(), host_mem_read_capacity(), host_mem_test_unit_ready(), and host_mem_wr_protect().
01106 { 01107 U16 nb; 01108 U8 status; 01109 U8 u8_datas[13]; 01110 Bool b_status = TRUE; // By default no error 01111 Bool b_stall = TRUE; // Accept one stall on CSW 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; // Error STALL but retry 01126 } 01127 } 01128 return CTRL_FAIL; 01129 } 01130 01131 if( PIPE_GOOD == status ) 01132 { 01133 // CSW receiv then check CSW 01134 // Check "USBS" string (0 to 3) 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; // Flag error 01141 } 01142 // Check CBW Tag (4 to 7) 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; // Tag error 01149 } 01150 // CSW Data Residue (8 to 11) 01151 // Check CSW status (12) 01152 if ( 0 != u8_datas[12] ) 01153 b_status = FALSE; // Status FAIL 01154 } 01155 else 01156 { 01157 b_status = FALSE; // Error PIPE IN, then status FAIL 01158 } 01159 01160 if( !b_status ) 01161 return host_mem_request_sense(); 01162 01163 return CTRL_GOOD; 01164 }
| void host_mem_stall_management | ( | void | ) |
This function writes data from the usb memory.
Definition at line 1169 of file host_mem.c.
References DMS_pipe_in, Host_ack_stall, host_clear_endpoint_feature, Host_get_endpoint_number, Host_reset_pipe_data_toggle, Host_select_pipe, and MSK_EP_DIR.
Referenced by host_mem_csw_read(), host_mem_inquiry(), host_mem_mem_2_ram(), host_mem_mem_2_ram_stop(), host_mem_ram_2_mem(), host_mem_read_capacity(), host_mem_request_sense(), and host_mem_wr_protect().
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 }
| void host_mem_init | ( | void | ) |
This fonction must be call only once at the program startup to initialize the USB driver MS.
Definition at line 170 of file host_mem.c.
Referenced by host_ms_task_init().
00171 { 00172 U8 i; 00173 // Reset Device MS struct 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 }
| Bool host_mem_install | ( | void | ) |
This fonction must be call when a device is connected.
Definition at line 184 of file host_mem.c.
Referenced by host_ms_task().
00185 { 00186 U32 capacity; 00187 U8 device_num; 00188 U8 interface_num; 00189 U8 lun_offset; 00190 U8 i; 00191 00192 // Check all devices connected 00193 for( device_num=0; device_num<Get_nb_device(); device_num++) 00194 { 00195 Host_select_device(device_num); 00196 00197 // Check all interfaces of device 00198 for( interface_num=0; interface_num < Get_nb_supported_interface(); interface_num++ ) 00199 { 00200 if( Get_class(interface_num)!= MS_CLASS ) 00201 continue; // It is not a MS interface 00202 00203 LOG_STR_CODE(log_ms_connect); 00204 00205 // If it is not the first MS device 00206 if( g_ms_nb_connected != 0 ) 00207 { 00208 // Check if already installed 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; // Device already installed 00216 // Check struct space free 00217 if( USB_MAX_DMS_NUMBER == g_ms_nb_connected ) 00218 break; // Too many MS device connected 00219 } 00220 00221 //** Start install 00222 g_ms_devices[g_ms_nb_connected].device_index = device_num; 00223 00224 // Get correct physical pipes associated to IN/OUT Mass Storage Endpoints 00225 if(Is_ep_addr_in(Get_ep_addr(interface_num,0))) 00226 { //Yes associate it to the MassStorage IN pipe 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 { //No, invert... 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 // Get last LUN number on the device mass storage connected 00237 if( CONTROL_GOOD != host_ms_get_max_lun() ) 00238 data_stage[0] = 0; // If STALL request then last LUN number = 0 00239 g_ms_devices[g_ms_nb_connected].nb_lun = data_stage[0]+1; // Save number of LUN = last LUN number + 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; // Limitation on the number of LUN 00243 00244 // Compute LUN offset of this new device 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 // Add the new MS device in MS strut 00252 g_ms_sel_dms = g_ms_nb_connected; 00253 g_ms_nb_connected++; 00254 00255 // Initialize all LUN from the new MS device 00256 for( i=0; i<g_ms_devices[g_ms_sel_dms].nb_lun; i++ ) 00257 { 00258 // Init struct of LUN 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 // Init MS corresponding at LUN 00262 host_mem_inquiry( lun_offset+i ); 00263 host_mem_read_capacity( lun_offset+i, &capacity ); 00264 } 00265 return TRUE; // Install interface/device done 00266 } 00267 } 00268 return FALSE; // No MSC install 00269 }
| void host_mem_uninstall | ( | void | ) |
This fonction must be call when a device is disconnected.
Definition at line 274 of file host_mem.c.
Referenced by host_ms_task().
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 // Device already remove but struct no updated 00286 // it may be possible in case of many MS on USB HUB 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 }
| U8 host_mem_get_lun | ( | void | ) |
This fonction returns the number of LUN of the devices mass storage connected to the host.
Definition at line 306 of file host_mem.c.
Referenced by host_ms_task().
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 }
| Ctrl_status host_mem_test_unit_ready | ( | U8 | lun | ) |
This fonction test the state of memory, and start the initialisation of the memory.
Definition at line 334 of file host_mem.c.
Referenced by host_mem_read_sector_size().
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 // Send CBW 00348 host_mem_cbw_init(); 00349 // g_ms_cbw.lgt_lsb0 = 0; 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 // Read CSW status 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 // Signal the new diskl 00363 status = CTRL_BUSY; 00364 // U-Disk valid then update info LUN 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 }
| Ctrl_status host_mem_read_capacity | ( | U8 | lun, | |
| U32 _MEM_TYPE_SLOW_ * | u32_nb_sector | |||
| ) |
This fonction returns the address of the last valid sector.
Ctrl_status It is ready -> CTRL_GOOD Memory unplug -> CTRL_NO_PRESENT Not initialize or change -> CTRL_BUSY A error occur -> CTRL_FAIL
Definition at line 389 of file host_mem.c.
Referenced by host_mem_install(), and host_mem_test_unit_ready().
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 // Send CBW 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 // Receiv the capacity data 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 // Get last sector address 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 // Get block size (unit 512B) 00428 g_ms_devices[ g_ms_sel_dms ].lun_info[ g_ms_sel_lun ].u8_block_size = datas[6]/2; // Block size MSB 00429 00430 // Read CSW status 00431 return host_mem_csw_read(); 00432 }
Returns the physical sector of the memory
| lun,global | lun selected (global!=lun of specific USB device) |
Definition at line 441 of file host_mem.c.
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 }
Return the write protected mode (cache used) This information is in a cache to speed up command
| lun,global | lun selected (global!=lun of specific USB device) |
Definition at line 457 of file host_mem.c.
00458 { 00459 if( !host_mem_select_lun(lun) ) 00460 return TRUE; // no present 00461 00462 return g_ms_devices[g_ms_sel_dms].lun_info[g_ms_sel_lun].b_protected; 00463 }
Return the write protected mode (no cache)
| lun,global | lun selected (global!=lun of specific USB device) |
Definition at line 472 of file host_mem.c.
Referenced by host_mem_test_unit_ready().
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; // No supported this lun in write mode, because sector size != 512B 00482 00483 if (g_readctx_b_run) 00484 { 00485 host_mem_mem_2_ram_stop(); 00486 host_mem_select_lun(lun); 00487 } 00488 00489 // Send CBW 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 //g_ms_cbw.u8_data[16-16] = 0x00; // 16 - CBWCB1 - Option 00496 g_ms_cbw.u8_data[17-16] = 0x3F; // 17 - CBWCB2 - Page Code 3F = return all mode pages 00497 //g_ms_cbw.u8_data[18-16] = 0x00; // 18 - CBWCB3 - reserved 00498 g_ms_cbw.u8_data[19-16] = 0x0C; // 19 - CBWCB4 - Allocation Length 00499 //g_ms_cbw.u8_data[20-16] = 0x00; // 20 - CBWCB5 - Control 00500 if( !host_mem_cbw_send() ) 00501 return TRUE; 00502 00503 // Receiv 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; // error then no write protected by defaut 00511 } 00512 00513 // Read CSW status 00514 host_mem_csw_read(); // ignore error on CSW (in case of specific Udisk) 00515 00516 return (write_code[2] == 0x80); 00517 }
| Bool host_mem_removal | ( | void | ) |
This fonction inform about the memory type.
Definition at line 524 of file host_mem.c.
00525 { 00526 return TRUE; 00527 }
| Ctrl_status host_mem_inquiry | ( | U8 | lun | ) |
Read inquiry datas
| lun,global | lun selected (global!=lun of specific USB device) |
Definition at line 597 of file host_mem.c.
Referenced by host_mem_install().
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 //g_ms_cbw.u8_data[16-16] = 0x00; // 16 - CBWCB1 - Option 00616 //g_ms_cbw.u8_data[17-16] = 0x00; // 17 - CBWCB2 - Page or operation code 00617 //g_ms_cbw.u8_data[18-16] = 0x00; // 18 - CBWCB3 - reserved 00618 g_ms_cbw.u8_data[19-16] = 0x24; // 19 - CBWCB4 - Allocation Length 00619 //g_ms_cbw.u8_data[20-16] = 0x00; // 20 - CBWCB5 - Control 00620 if( !host_mem_cbw_send() ) 00621 return CTRL_FAIL; 00622 00623 // Receiv Inquiry data 00624 // Transfer data ... 00625 nb=31; 00626 status = host_get_data(DMS_pipe_in(),&nb,datas); 00627 // Ignore inquiry data 00628 if( PIPE_STALL == status ) 00629 host_mem_stall_management(); 00630 00631 // Read CSW status 00632 return host_mem_csw_read(); 00633 }
| Ctrl_status host_mem_mem_2_ram | ( | U8 | lun, | |
| U32 | addr, | |||
| U8 * | ram | |||
| ) |
Read sectors on lun
| lun,global | lun selected (global!=lun of specific USB device) | |
| addr | Sector address to start read (unit 512B) | |
| *ram | buffer 512B to store the sector readed |
Definition at line 747 of file host_mem.c.
Referenced by host_mem_ram_2_mem().
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; // no present 00756 00757 u8_nb_sec_ignore_at_beg = 0; 00758 00759 if( g_readctx_b_run ) 00760 { 00761 // Check if the sector requested is the following of previous read command 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 // Compute the address in physical sector units 00779 u32_address = addr / u8_sector_size; 00780 // Compute the number of sector to ignore from the beginning of the physical sector 00781 u8_nb_sec_ignore_at_beg = addr % u8_sector_size; 00782 // Update context 00783 g_readctx_u16_sector = u8_sector_size; 00784 g_readctx_u32_addr = addr - u8_nb_sec_ignore_at_beg; 00785 00786 // Send CBW 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 //g_ms_cbw.u8_data[16-HOST_MS_CBW_DATA_POS] = 0x00; // 16 - CBWCB1 - Option 00796 g_ms_cbw.u8_data[17-HOST_MS_CBW_DATA_POS] = MSB0(u32_address); // 17 - CBWCB2 - MSB3(Logical Block Address) 00797 g_ms_cbw.u8_data[18-HOST_MS_CBW_DATA_POS] = MSB1(u32_address); // 18 - CBWCB3 - MSB2(Logical Block Address) 00798 g_ms_cbw.u8_data[19-HOST_MS_CBW_DATA_POS] = MSB2(u32_address); // 19 - CBWCB4 - MSB1(Logical Block Address) 00799 g_ms_cbw.u8_data[20-HOST_MS_CBW_DATA_POS] = MSB3(u32_address); // 20 - CBWCB5 - MSB0(Logical Block Address) 00800 //g_ms_cbw.u8_data[21-HOST_MS_CBW_DATA_POS] = 0x00; // 21 - CBWCB6 - reserved 00801 //g_ms_cbw.u8_data[22-HOST_MS_CBW_DATA_POS] = 0x00; // 22 - CBWCB7 - MSB1(Transfer Length) 00802 g_ms_cbw.u8_data[23-HOST_MS_CBW_DATA_POS] = 0x01; // 23 - CBWCB8 - MSB0(Transfer Length) 00803 //g_ms_cbw.u8_data[24-HOST_MS_CBW_DATA_POS] = 0x00; // 24 - CBWCB9 - Control 00804 if( !host_mem_cbw_send() ) 00805 return CTRL_FAIL; 00806 } 00807 00808 if( 0 != u8_nb_sec_ignore_at_beg ) 00809 { 00810 // Ignore eventualy first sector of command (in case of device with sector >512B) 00811 // Update sector remaining 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 // Read one sector 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 // Transfer data ... 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 // Update context 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 // Read CSW status 00853 g_readctx_b_run = FALSE; 00854 return host_mem_csw_read(); 00855 }
| Ctrl_status host_mem_mem_2_ram_stop | ( | void | ) |
This function terminates the tranfer of a physical sector from memory.
Definition at line 866 of file host_mem.c.
Referenced by host_mem_inquiry(), host_mem_mem_2_ram(), host_mem_ram_2_mem(), host_mem_read_capacity(), host_mem_test_unit_ready(), and host_mem_wr_protect().
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 // Read one sector 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 // Read CSW status 00893 return host_mem_csw_read(); 00894 }
| Ctrl_status host_mem_ram_2_mem | ( | U8 | lun, | |
| U32 | addr, | |||
| U8 * | ram | |||
| ) |
Write a sectors
| lun,global | lun selected (global!=lun of specific USB device) | |
| addr | Sector address to start write (unit 512B) | |
| *ram | buffer 512B with the data to store in the sector writed |
Definition at line 910 of file host_mem.c.
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; // no present 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; // No supported this lun in write mode, because sector size != 512B 00929 00930 00931 // Compute the address in physical sector units 00932 u32_address = addr / u8_sector_size; 00933 // Compute the number of sector to ignore from the beginning of the physical sector 00934 u8_nb_sec_ignore_at_beg = addr % u8_sector_size; 00935 // Update context 00936 u16_sector = u8_sector_size; 00937 00938 #if (USB_SUPPORT_MS_SECTOR_WR_MAX != 1) 00939 // If the sector size > 512B then read sector and store it in a buffer 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 // Send CBW 00962 host_mem_cbw_init(); 00963 //g_ms_cbw.lgt_lsb0 = 0x00; 00964 g_ms_cbw.lgt_lsb1 = u8_sector_size * (512/256); 00965 //g_ms_cbw.lgt_lsb2 = 0x00; 00966 //g_ms_cbw.lgt_lsb3 = 0x00; 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 //g_ms_cbw.u8_data[16-HOST_MS_CBW_DATA_POS] = 0x00; // 16 - CBWCB1 - Option 00971 g_ms_cbw.u8_data[17-HOST_MS_CBW_DATA_POS] = MSB0(u32_address); // 17 - CBWCB2 - MSB3(Logical Block Address) 00972 g_ms_cbw.u8_data[18-HOST_MS_CBW_DATA_POS] = MSB1(u32_address); // 18 - CBWCB3 - MSB2(Logical Block Address) 00973 g_ms_cbw.u8_data[19-HOST_MS_CBW_DATA_POS] = MSB2(u32_address); // 19 - CBWCB4 - MSB1(Logical Block Address) 00974 g_ms_cbw.u8_data[20-HOST_MS_CBW_DATA_POS] = MSB3(u32_address); // 20 - CBWCB5 - MSB0(Logical Block Address) 00975 //g_ms_cbw.u8_data[21-HOST_MS_CBW_DATA_POS] = 0x00; // 21 - CBWCB6 - reserved 00976 //g_ms_cbw.u8_data[22-HOST_MS_CBW_DATA_POS] = 0x00; // 22 - CBWCB7 - MSB1(Transfer Length) 00977 g_ms_cbw.u8_data[23-HOST_MS_CBW_DATA_POS] = 0x01; // 23 - CBWCB8 - MSB0(Transfer Length) 00978 //g_ms_cbw.u8_data[24-HOST_MS_CBW_DATA_POS] = 0x00; // 24 - CBWCB9 - Control 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 // Ignore eventualy first sector of command (in case of device with sector >512B) 00986 // Update sector remaining 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 // Transfer data ... 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 // Transfer data ... 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 // Transfer data ... 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 // Read CSW status 01032 return host_mem_csw_read(); 01033 }
Definition at line 125 of file host_mem.c.
| S_dms_device g_ms_devices[MAX_DEVICE_IN_USB_TREE-1] |
Definition at line 126 of file host_mem.c.
Definition at line 127 of file host_mem.c.
Referenced by host_mem_get_lun(), host_mem_init(), host_mem_install(), host_mem_select_lun(), and host_mem_uninstall().
| U8 g_ms_sel_dms = 0 |
Definition at line 128 of file host_mem.c.
Referenced by host_mem_install(), host_mem_mem_2_ram(), host_mem_mem_2_ram_stop(), host_mem_ram_2_mem(), host_mem_read_capacity(), host_mem_read_sector_size(), host_mem_select_lun(), host_mem_test_unit_ready(), host_mem_wr_protect(), and host_mem_wr_protect_cache().
Definition at line 129 of file host_mem.c.
Referenced by host_mem_cbw_init(), host_mem_mem_2_ram(), host_mem_mem_2_ram_stop(), host_mem_ram_2_mem(), host_mem_read_capacity(), host_mem_read_sector_size(), host_mem_select_lun(), host_mem_test_unit_ready(), host_mem_wr_protect(), and host_mem_wr_protect_cache().
| U8 g_readctx_b_run = FALSE |
Definition at line 138 of file host_mem.c.
Referenced by host_mem_inquiry(), host_mem_mem_2_ram(), host_mem_mem_2_ram_stop(), host_mem_ram_2_mem(), host_mem_read_capacity(), host_mem_test_unit_ready(), and host_mem_wr_protect().
Definition at line 139 of file host_mem.c.
Referenced by host_mem_mem_2_ram(), and host_mem_mem_2_ram_stop().
Definition at line 140 of file host_mem.c.
Referenced by host_mem_mem_2_ram(), and host_mem_mem_2_ram_stop().
Definition at line 142 of file host_mem.c.
Referenced by host_mem_mem_2_ram(), and host_mem_mem_2_ram_stop().
1.5.3