3.2   About the FLFlash and FLSocket Structures

TrueFFS for Tornado is designed to handle a maximum of five TrueFFS block devices. Internally, TrueFFS allocates an FLFlash structure and an FLSocket structure for each of the five possible flash devices. The initialization of these structures starts with the registration of your socket component driver functions with TrueFFS.

For the most part, this registration updates the FLSocket structure referenced by the socket member of FLFlash. The initialization of the FLFlash structure is completed by running an MTD identify routine. Because this identify routine depends on functions referenced in the FLSocket structure, you must install your socket component driver before you can run an MTD identify routine.

3.2.1   FLFlash

Almost all members of the FLFlash structure are set by the MTD identify routine, which gets most of the data it needs by probing the flash hardware. The only exception is the socket member, which is set by functions internal to TrueFFS. The FLFlash structure is defined in h/tffs/flflash.h as follows:1

typedef struct tFlash FLFlash;        /* forward definition */ 
struct tFlash { 
    FlashType     type;               /* flash device type (JEDEC id) */ 
    long int      erasableBlockSize;  /* smallest erasable area */ 
    long int      chipSize;           /* chip size */ 
    int           noOfChips;          /* no. of chips in array */ 
    int           interleaving;       /* chip interleaving */ 
    unsigned      flags;              /* special options */ 
    void *        mtdVars;            /* MTD private area for socket */ 
    FLSocket *    socket;             /* FLSocket for this drive */ 
                /* MTD-supplied flash map function */ 
    void FAR0 * (*map)(FLFlash *, CardAddress, int); 
                /* MTD-supplied flash read function */ 
    FLStatus    (*read)(FLFlash *, CardAddress, void FAR1 *, int, int); 
                /* MTD-supplied flash write function */ 
    FLStatus    (*write)(FLFlash *,CardAddress,const void FAR1 *,int,int) 
                /* MTD-supplied flash erase function */ 
    FLStatus    (*erase)(FLFlash *, int, int); 
                /* callback to execute after power up */ 
    void        (*setPowerOnCallback)(FLFlash *); 
};
type
The JEDEC ID for the flash memory hardware. This member is set by the MTD's identification routine.

erasableBlockSize
The size, in bytes, of an erase block for the attached flash memory hardware. This value takes interleaving into account. Thus, when setting this value in an MTD, the code is often of the form:

vol.erasableBlockSize = aValue * vol.interleaving;

Where aValue is the erasable block size of a flash chip that is not interleaved with another.

chipSize
The size (storage capacity), in bytes, of one of the flash memory chips used to construct the flash memory array. Set by the MTD using your flFitInSocketWindow( ) global routine.

noOfChips
The number of flash memory chips used to construct the flash memory array.

interleaving
The interleaving factor of the flash memory array. This must be a power of 2 (for example, 1, 2, 4). The interleaving is defined as the address difference on the media of two consecutive bytes on a chip. For most PCMCIA cards the interleaving is 2.

flags
Bits 0-7 are reserved for the use of TrueFFS (it uses these flags to track things such as the volume mount state). Bits 8-15 are reserved for the use of the MTDs.

mtdVars
This field, if used by the MTD, is initialized by the MTD identification routine to point to a private storage area. For example, the WRS-supplied MTD for the 16-bit AMD devices uses this member to store a pointer to an area containing AMD-specific flash parameters.

socket
A pointer to the FLSocket structure for this hardware device. This structure contains data and pointers to the socket layer functions that TrueFFS needs to manage the board interface for the flash memory hardware. The functions referenced in this structure are installed when you register your socket component driver. Further, because TrueFFS uses these socket component driver functions to access the flash memory hardware, you must register your socket component driver before you try to run the MTD identify routine that initializes the bulk of this structure.

map
A pointer to the flash memory map function, the function that maps flash into an area of memory. Internally, TrueFFS initializes this member to point to a default map function appropriate for all NOR (linear) flash memory types. This default routine maps flash memory through simple socket mapping. NAND or other type Flash should replace this pointer to the default routine with a reference to a routine that uses map-through-copy emulation. For more information on this function, see 3.4.2 Writing a Map Function for an MTD.

read
A pointer to the flash memory read function. On entry to the MTD identification routine, this member has already been initialized to point to a default read function that is appropriate for all NOR (linear) flash memory types. This routine reads from flash memory by copying from a mapped window. If this is appropriate for your flash device, leave read unchanged. Otherwise, the MTD identify routine should update this member to point to a more appropriate function. For more information on this function, see 3.4.3 Writing a Read Function for an MTD.

write
A pointer to the flash memory write function. Because of the dangers associated with an inappropriate write function, the default routine for this member returns a write-protect error. The MTD identification routine must supply an appropriate function pointer for this member. For more information on this function, see 3.4.4 Writing Write and Erase Functions for an MTD.

erase
A pointer to the flash memory erase function. Because of the dangers associated with an inappropriate erase function, the default routine for this member returns a write-protect error. The MTD identification routine must supply an appropriate function pointer for this member. For more information on this function, see 3.4.4 Writing Write and Erase Functions for an MTD.

setPowerOnCallback
A pointer to the function TrueFFS should execute after the flash hardware device powers up. TrueFFS calls this routine when it tries to mount a flash device. Do not confuse this member of FLFlash with the powerOnCallback member of the FLSocket structure. For many flash memory devices, no such function is necessary. However, this member is used by the MTD defined in target/src/drv/tffs/nfdc2048.c.

3.2.2   FLSocket

As a writer of a socket component driver, your primary concern is the initialization of an FLSocket structure. This structure provides TrueFFS with pointers to the functions that you have written to handle the interface with the flash hardware. For the most part, the specifics of how you implement these functions are rather hardware specific.

When relevant, the member descriptions point out WRS-supplied BSPs that you can use as examples. However, your greatest asset in this situation is your intimate knowledge of your particular hardware. The FLSocket structure is defined in h/tffs/flsocket.h as follows:

typedef struct tSocket FLSocket;        /* forward definition */ 
  
struct tSocket { 
  unsigned      volNo;        /* volume no. of socket */ 
  unsigned      serialNo;     /* serial no. of socket on controller */ 
  FLBoolean     cardChanged;  /* need media change notification */ 
  int           VccUsers;     /* no. of current VCC users */ 
  int           VppUsers;     /* No. of current VPP users */ 
  PowerState    VccState;     /* actual VCC state */ 
  PowerState    VppState;     /* actual VPP state */ 
  FLBoolean     remapped;     /* set to TRUE if the socket window is moved */ 
  void (*powerOnCallback)(void *flash); /* notification routine for Vcc on */ 
  void *        flash;        /* flash object for callback */ 
  struct {                    /* window state */ 
    unsigned int baseAddress; /* physical base as a 4K page */ 
    unsigned int currentPage; /* our current window page mapping */ 
    void FAR0 * base;         /* pointer to window base */ 
    long int    size;         /* window size (must by power of 2) */ 
    unsigned    speed;        /* in nsec. */ 
    unsigned    busWidth;     /* 8 or 16 bits */ 
  } window; 
  FLBoolean (*cardDetected)(FLSocket vol); 
  void (*VccOn)(FLSocket vol); 
  void (*VccOff)(FLSocket vol); 
#ifdef SOCKET_12_VOLTS 
  FLStatus (*VppOn)(FLSocket vol); 
  void (*VppOff)(FLSocket vol); 
#endif  /* SOCKET_12_VOLTS */ 
  FLStatus (*initSocket)(FLSocket vol); 
  void (*setWindow)(FLSocket vol); 
  void (*setMappingContext)(FLSocket vol, unsigned page); 
  FLBoolean (*getAndClearCardChangeIndicator)(FLSocket vol); 
  FLBoolean (*writeProtected)(FLSocket vol); 
#ifdef EXIT 
  void (*freeSocket)(FLSocket vol); 
#endif 
};

*   

NOTE: TrueFFS for Tornado always defines both SOCKET_12_VOLTS and EXIT. Thus, all the members shown above are always included in the TrueFFS for Tornado version of this structure.
volNo
For internal use. Do not change the value of this member except through an MTD identification routine. This member stores the volume number (drive number) associated with this socket component driver. Each socket component is assigned a driver number based on its order of registration. Thus, the first driver to register itself is assigned a 0, the second is assigned a 1, and so on up to 4. If you are using PCMCIA slots to add flash memory cards to your system, TrueFFS for Tornado creates a unique driver for each slot. Thus, each slot has its own volNo.
serialNo
A free-use member. This member is not used by any function internal to TrueFFS and is typically set to zero. Its name implies that it was intended as a convenient place to store the serial number associated with the flash device. Thus, you are free, for the most part, to use this member as you see fit. For example, the PCIC driver supplied with some WRS BSPs use this member to store slot numbers (0 and 1).
cardChanged
The intended purpose of this member is to track whether there was a change of flash card. To detect a change of card, TrueFFS polls the card every 100 milliseconds by calling the function you specify in the cardDetected member of this structure. If that function returns FALSE, TrueFFS sets this member to TRUE. This member is also set by the function referenced in getAndClearCardChangeIndicator.
For non-removable flash media, this member should always be set to FALSE. If this member is TRUE, when TrueFFS tries to access flash, it triggers a remount for the flash device.
VccUsers
For internal use. Do not change the value of this member. Each call to flNeedVcc( ) increments this counter internally in TrueFFS. The 100 millisecond timer routine uses this counter to verify that it is safe to call the VccOff( ) routine in the socket driver.
VppUsers
For internal use. Do not change the value of this member. Each call to flNeedVpp( ) increments this counter internally in TrueFFS. The 100 millisecond timer routine uses this counter to verify that it is safe to call the VppOff( ) routine in the socket driver.
VccState
For internal use. Do not change the value of this member outside the function supplied in FLSocket.VccOn. This member reports whether Vcc is in a PowerOn, a PowerGoingOff, or a PowerOff state.
VppState
For internal use. Do not change the value of this member outside the function supplied in FLSocket.VccOn. This member reports whether Vcc is in a PowerOn, a PowerGoingOff, or a PowerOff state.
remapped
For internal use. Do not change the value of this member except from within an MTD map function. True FFS uses this member to track whether or not the window was just remapped (moved). If you write your own MTD map function, that function should set this member before returning.
powerOnCallback
Set by your xxxRegister( )function. TrueFFS calls the function referenced here after calling the function referenced in the VccOn member of this structure. If you have no need of this feature, set this member to a null pointer.
flash
For internal use. Do not change the value of this member. This member contains a pointer to the FLSocket structure associated with this socket component driver. It is needed to support removable flash media and is set dynamically by TrueFFS.
window.baseAddress
Set by your xxxRegister( )function. In this context, a window is a part of host system memory through which a part of the media memory is directly visible and addressable. The window.baseAddress member stores the memory address of this host-system memory in terms of 4K pages (that is, the base address of the window divided by 4K). The value is stored in this way in order to guarantee that the base address (when reconstructed) is page aligned.
window.currentPage
For internal use. Do not change the value of this member. Stores the currently mapped window page (in 4KB units).
window.base
Set by the function you supply in the setWindow member of this structure. TrueFFS uses this member to store the base address of the memory window on flash memory.
window.size
Set by the function you supply in the setWindow member of this structure. TrueFFS uses this member to store the size of the memory window on flash memory.
window.speed
For internal use. You should not have to change the value of this member from your socket component driver. TrueFFS uses this member to store the length of time needed to complete an interaction with the flash device. Initially, TrueFFS sets this to a default value of 250 nano seconds. However, all WRS-supplied MTDs reset it to 120 nano seconds. If you write your own MTD, be sure to reset this member value appropriately in its mapping function.
window.busWidth
For internal use. Do not change the value of this member from your socket component driver. TrueFFS uses this member to record whether the flash device is 8 or 16 bits wide. Initially, TrueFFS sets this to a default value of 16. However, some WRS-supplied MTDs reset it to 8. If you write your own MTD, be sure to reset this member value appropriately in your mapping function.
cardDetected
Initialized by your xxxRegister( ). This member points to a function that reports whether there is a flash memory card in the PCMCIA slot associated with this device. For non-removable media, this routine should always return TRUE. Internally, TrueFFS for Tornado calls this function every 100 milliseconds to check that flash media is still there. If this function returns FALSE, TrueFFS sets cardChanged to TRUE.
VccOn
Set by your xxxRegister( ). This member contains a pointer to a function that TrueFFS can call to turn on the operating voltage (Vcc, usually 5 or 3.3 Volts) for the flash memory hardware. When the media is idle, TrueFFS conserves power by turning Vcc off. Prior to making a call that accesses flash memory, TrueFFS uses this function to turn the power back on again.
When switching Vcc on, the VccOn function must not return until Vcc has stabilized at the proper operating voltage. If necessary, your VccOn function should delay execution with an idle loop or with a call to the flDelayMsec( ) routine, until the Vcc has stabilized.
Prior to accessing the flash device, TrueFFS turns on Vcc. To conserve power, TrueFFS switches Vcc off at the completion of the operation. However, when socket polling is active, a delayed Vcc-off mechanism is used, in which Vcc is turned off only after at least one interval has passed. If several flash-accessing operations are executed in rapid sequence, Vcc remains on during the sequence, and is turned off only when TrueFFS goes into a relatively idle state.
VccOff
Set by your xxxRegister( ). This member contains a pointer to a function that TrueFFS can call to turn off the operating voltage for the flash memory hardware. When the media is idle, TrueFFS conserves power by turning Vcc off. However, when socket polling is active, Vcc is turned off only after a delay. Thus, if several flags accessing operations are executed in rapid sequence, Vcc is left on during the sequence. Vcc is turned off only when TrueFFS goes into a relatively idle state.
VppOn
Set by your xxxRegister( ). TrueFFS calls this routine to apply a programming voltage (Vpp, usually 12 Volts) to the flash chip. Because not all flash chips require this voltage, the member is included only if SOCKET_12_VOLTS is defined.
When switching Vpp on, the VppOn function must not return until Vpp has stabilized at the proper voltage. If necessary, your VppOn function should delay execution with an idle loop or with a call to the flDelayMsec( ) routine, until the Vpp has stabilized.
VppOff
Set by your xxxRegister( ). TrueFFS calls this routine to turn off a programming voltage (Vpp, usually 12 Volts) to the flash chip. Because not all flash chips require this voltage, the member is included only if SOCKET_12_VOLTS is defined.
initSocket
Set by your xxxRegister( ). TrueFFS calls the function referenced here before it tries to access the socket. TrueFFS uses this function to handle any initialization that is necessary before accessing the socket, especially if that initialization was not possible at socket registration time. For example, if you did no hardware detection at socket registration time or if the flash memory medium is removable, this function should detect the flash memory medium and respond appropriately (including setting cardDetected to FALSE) if it is missing.
setWindow
Set by your xxxRegister( ). TrueFFS calls the function referenced in this member to update key members of the window structure included in this FLSocket structure. When writing a setWindow function for most hardware, you must do the following:

1.

 

Set window.baseAddress to the base address in terms of 4K pages, that is, to the base address of the window divided by 4K. This is to guarantee that the base address is page aligned.

 

2. 

 

Call flSetWindowSize( )and specify the window size in 4K units (window.baseAddress). Internally, the call to flSetWindowSize( )sets window.size and window.base for you.

 


TrueFFS assumes that it has exclusive access to the window. That is, after it sets one of these window characteristics, it does not expect your application to directly change any of them, and could crash if you do. An exception to this is the mapping register. Because TrueFFS always reestablishes this register when it accesses flash memory, your application may map the window for purposes other than TrueFFS. However, you must not do this from an interrupt routine.
On systems with multiple socket drivers (to handle multiple flash devices), make sure that the window base address is different for each socket. In addition, you must take window size into account and verify that the windows do not overlap.
setMappingContext
Set by your xxxRegister( ). This member contains a pointer to a function that TrueFFS can call to set the window mapping register. Because board-resident flash arrays usually map the entire flash into RAM, they do not need this function. The known exception to is the flash array associated with the ss5 BSP. Flash cards in the PCMCIA slot can use this function to access a mapping register that moves the effective flash address into the host's memory window (see the pc386 and pc486 BSPs).
getAndClearCardChangeIndicator
Set by your xxxRegister( ). This function reads the hardware card-change indication and clears it. It serves as a basis for detecting media-change events. If you have no such hardware capability, set this function pointer to NULL.
writeProtected
Set by your xxxRegister( ). This member contains a pointer to a function that TrueFFS can call to get the current state of the media's write-protect switch (if available).
freeSocket
Set by your xxxRegister( ). This member contains a pointer to a function that TrueFFS can call to free the resources reserved internally to the socket driver.

1:  If you are not writing an MTD, you can ignore the member descriptions provided for the FLFlash structure and skip ahead to the description of the FLSocket structure.