host_mem.h File Reference

#include "conf/conf_access.h"
#include "modules/control_access/ctrl_status.h"
#include "conf/conf_usb.h"

Include dependency graph for host_mem.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

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_read_format_capacity (U8 lun)
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)


Detailed Description

This file is a template for writing C software programs.

This file contains the C51 RAM called CRAM management routines which are used for Mass storage when doing ISP This file calls routines of the cram_mem.c file

Author:
Atmel Corporation: http://www.atmel.com
Support and FAQ: http://support.atmel.no/

Definition in file host_mem.h.


Function Documentation

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.

References S_dms_device::device_index, g_ms_nb_connected, i, and USB_MAX_DMS_NUMBER.

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.

References S_lun_info::b_first_unitready, S_lun_info::b_protected, CONTROL_GOOD, data_stage, S_usb_tree::device, S_dms_device::device_index, S_usb_interface::ep, FALSE, g_ms_nb_connected, g_ms_sel_dms, Get_class, Get_ep_addr, Get_nb_device, Get_nb_supported_interface, host_mem_inquiry(), host_mem_read_capacity(), host_ms_get_max_lun, Host_select_device, i, S_usb_device::interface, Is_ep_addr_in, LOG_STR_CODE, S_dms_device::lun_info, MS_CLASS, S_dms_device::nb_lun, S_dms_device::pipe_in, S_usb_endpoint::pipe_number, S_dms_device::pipe_out, TRUE, USB_MAX_DMS_NUMBER, USB_MAX_LUN_PER_DMS, and usb_tree.

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 }

Here is the call graph for this function:

void host_mem_uninstall ( void   ) 

This fonction must be call when a device is disconnected.

Definition at line 274 of file host_mem.c.

References S_usb_tree::device, S_usb_device::device_address, S_dms_device::device_index, FALSE, g_ms_nb_connected, i, TRUE, and usb_tree.

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.

Returns:
The number of LUN

Definition at line 306 of file host_mem.c.

References g_ms_nb_connected, i, Is_host_ms_configured, and S_dms_device::nb_lun.

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.

Returns:
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 334 of file host_mem.c.

References S_lun_info::b_first_unitready, S_lun_info::b_protected, S_cbw::cmd, CTRL_BUSY, CTRL_FAIL, CTRL_GOOD, CTRL_NO_PRESENT, S_cbw::dir, FALSE, g_ms_sel_dms, g_ms_sel_lun, g_readctx_b_run, host_mem_cbw_init(), host_mem_cbw_send(), host_mem_csw_read(), host_mem_mem_2_ram_stop(), host_mem_read_capacity(), host_mem_select_lun(), host_mem_wr_protect(), S_cbw::lgt, S_dms_device::lun_info, SBC_CMD_DIR_OUT, SBC_CMD_TEST_UNIT_READY, and TRUE.

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 }

Here is the call graph for this function:

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.

Returns:
*u16_nb_sector number of sector (sector = 512B)

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.

References S_cbw::cmd, CTRL_FAIL, CTRL_NO_PRESENT, S_cbw::dir, DMS_pipe_in, g_ms_sel_dms, g_ms_sel_lun, g_readctx_b_run, host_get_data(), host_mem_cbw_init(), host_mem_cbw_send(), host_mem_csw_read(), host_mem_mem_2_ram_stop(), host_mem_select_lun(), host_mem_stall_management(), S_cbw::lgt, S_cbw::lgt_lsb0, S_dms_device::lun_info, MSB0, MSB1, MSB2, MSB3, PIPE_GOOD, PIPE_STALL, SBC_CMD_DIR_IN, SBC_CMD_READ_CAPACITY, and S_lun_info::u8_block_size.

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 }

Here is the call graph for this function:

U8 host_mem_read_sector_size ( U8  lun  ) 

Returns the physical sector of the memory

Parameters:
lun,global lun selected (global!=lun of specific USB device)
Returns:
size of physical sector of disk (unit 512B)

Definition at line 441 of file host_mem.c.

References g_ms_sel_dms, g_ms_sel_lun, host_mem_select_lun(), host_mem_test_unit_ready(), S_dms_device::lun_info, and S_lun_info::u8_block_size.

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 }

Here is the call graph for this function:

Bool host_mem_wr_protect_cache ( U8  lun  ) 

Return the write protected mode (cache used) This information is in a cache to speed up command

Parameters:
lun,global lun selected (global!=lun of specific USB device)
Returns:
TRUE, the memory is protected

Definition at line 457 of file host_mem.c.

References S_lun_info::b_protected, g_ms_sel_dms, g_ms_sel_lun, host_mem_select_lun(), S_dms_device::lun_info, and TRUE.

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 }

Here is the call graph for this function:

Bool host_mem_wr_protect ( U8  lun  ) 

Return the write protected mode (no cache)

Parameters:
lun,global lun selected (global!=lun of specific USB device)
Returns:
TRUE, the memory is protected

Definition at line 472 of file host_mem.c.

References S_cbw::cmd, S_cbw::dir, DMS_pipe_in, g_ms_sel_dms, g_ms_sel_lun, g_readctx_b_run, host_get_data(), host_mem_cbw_init(), host_mem_cbw_send(), host_mem_csw_read(), host_mem_mem_2_ram_stop(), host_mem_select_lun(), host_mem_stall_management(), S_cbw::lgt, S_cbw::lgt_lsb0, PIPE_GOOD, PIPE_STALL, SBC_CMD_DIR_IN, SBC_CMD_MODE_SENSE_6, TRUE, S_cbw::u8_data, and USB_SUPPORT_MS_SECTOR_WR_MAX.

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 }

Here is the call graph for this function:

Bool host_mem_removal ( void   ) 

This fonction inform about the memory type.

Returns:
FASLE -> The memory isn't removal

Definition at line 524 of file host_mem.c.

References TRUE.

00525 {
00526    return TRUE;
00527 }

Ctrl_status host_mem_read_format_capacity ( U8  lun  ) 

Ctrl_status host_mem_inquiry ( U8  lun  ) 

Read inquiry datas

Parameters:
lun,global lun selected (global!=lun of specific USB device)
Returns:
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 597 of file host_mem.c.

References S_cbw::cmd, CTRL_FAIL, CTRL_NO_PRESENT, S_cbw::dir, DMS_pipe_in, g_readctx_b_run, host_get_data(), host_mem_cbw_init(), host_mem_cbw_send(), host_mem_csw_read(), host_mem_mem_2_ram_stop(), host_mem_select_lun(), host_mem_stall_management(), S_cbw::lgt, S_cbw::lgt_lsb0, PIPE_STALL, SBC_CMD_DIR_IN, SBC_CMD_INQUIRY, and S_cbw::u8_data.

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 }

Here is the call graph for this function:

Ctrl_status host_mem_mem_2_ram ( U8  lun,
U32  addr,
U8 ram 
)

Read sectors on lun

Parameters:
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
Returns:
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 747 of file host_mem.c.

References S_cbw::cmd, CTRL_FAIL, CTRL_GOOD, S_dms_device::device_index, S_cbw::dir, DMS_pipe_in, FALSE, g_ms_sel_dms, g_ms_sel_lun, g_readctx_b_run, g_readctx_u16_sector, g_readctx_u32_addr, g_readctx_u8_device, g_readctx_u8_lun, host_get_data(), host_mem_cbw_init(), host_mem_cbw_send(), host_mem_csw_read(), host_mem_mem_2_ram_stop(), host_mem_select_lun(), host_mem_stall_management(), HOST_MS_CBW_DATA_POS, HOST_SECTOR_SIZE, S_cbw::lgt, S_cbw::lgt_lsb0, S_cbw::lgt_lsb1, S_cbw::lgt_lsb2, S_cbw::lgt_lsb3, S_dms_device::lun_info, MSB0, MSB1, MSB2, MSB3, NULL, PIPE_GOOD, PIPE_STALL, SBC_CMD_DIR_IN, SBC_CMD_READ_10, TRUE, S_lun_info::u8_block_size, and S_cbw::u8_data.

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 }

Here is the call graph for this function:

Ctrl_status host_mem_mem_2_ram_stop ( void   ) 

This function terminates the tranfer of a physical sector from memory.

Returns:
Ctrl_status It is ready -> CTRL_GOOD Memory unplug -> CTRL_NO_PRESENT Not initialized or changed -> CTRL_BUSY An error occurred -> CTRL_FAIL

Definition at line 866 of file host_mem.c.

References CTRL_FAIL, DMS_pipe_in, FALSE, g_ms_sel_dms, g_ms_sel_lun, g_readctx_b_run, g_readctx_u16_sector, g_readctx_u8_device, g_readctx_u8_lun, host_get_data(), host_mem_csw_read(), host_mem_stall_management(), HOST_SECTOR_SIZE, Host_select_device, NULL, PIPE_GOOD, and PIPE_STALL.

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 }

Here is the call graph for this function:

Ctrl_status host_mem_ram_2_mem ( U8  lun,
U32  addr,
U8 ram 
)

Write a sectors

Parameters:
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
Returns:
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 910 of file host_mem.c.

References S_cbw::cmd, CTRL_FAIL, CTRL_GOOD, S_cbw::dir, DMS_pipe_out, g_ms_sel_dms, g_ms_sel_lun, g_readctx_b_run, host_mem_cbw_init(), host_mem_cbw_send(), host_mem_csw_read(), host_mem_mem_2_ram(), host_mem_mem_2_ram_stop(), host_mem_select_lun(), host_mem_stall_management(), HOST_MS_CBW_DATA_POS, HOST_SECTOR_SIZE, host_send_data(), S_cbw::lgt, S_cbw::lgt_lsb1, S_dms_device::lun_info, MSB0, MSB1, MSB2, MSB3, PIPE_STALL, SBC_CMD_DIR_OUT, SBC_CMD_WRITE_10, S_lun_info::u8_block_size, S_cbw::u8_data, and USB_SUPPORT_MS_SECTOR_WR_MAX.

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 }

Here is the call graph for this function:


Generated on Fri May 15 15:41:42 2009 for ATMEL by  doxygen 1.5.3