www.pudn.com > efs.rar > fs_pm_super.h


/**********************************************************************
 * fs_pm_super.h
 *
 * Super-block management for Embedded File System.
 * Copyright (C) 2002, 2003, 2004, 2005, 2006 Qualcomm, Inc.
 *
 * This file describes the interface to the code the manages the EFS
 * superblock.
 */

/*===========================================================================

                        EDIT HISTORY FOR MODULE

  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.

  $Header: //depot/asic/MSMSHARED/services/efs/MSM_EFS.01.02/fs_pm_super.h#15 $ $DateTime: 2006/08/31 17:09:53 $ $Author: davidb $

when          who     what, where, why
--------      ---     ------------------------------------------------------
2006-08-31    dlb     New minor version for DB GID fix.
2006-08-23    sh      Adjust the NAND LOG region size with page size.
2006-08-17    dlb     New minor version for LOG CRC improvements.
2006-05-12    sh      Swap the NOR/NAND version bits back again
2006-04-18    dlb     Add forward-updates of superblock.
2006-03-03    sh      Force NAND and NOR Superblock versions to be different
2006-03-02    sh      Bump the ver number because Soft Limit is removed
2006-01-27    sh      Renamed some Q&R defines to be more explanatory
2006-01-17    dlb     Support multiple NOR write styles.
2006-01-11    nrs     Fixed Copyright header
2005-12-14    sh      Expand Log Region from 8 to 32 blocks.
2005-11-09    nrs     Quota and Reservation cleanup
2005-10-18    nrs     Fixes for quotas and reservations
2005-07-20    nrs     Support for quotas and reservations
2005-04-20    dlb     Support 2k pages.
2005-01-04    dlb     Update copyright line.
2004-12-30    dlb     Utilize new factory image code.
2004-10-15    dlb     Update copyright header.
2004-10-07    dlb     Whitespace cleanup.
2004-04-26    drh     Update both NAND and NOR super version for release
2003-11-16     gr     Updated NAND super version so that 6300 3xxx builds
                      and 5xxx builds can be distinguished.
2003-06-17    jkl     Updated NOR and NAND SUPER VERSION.
2003-06-12    adm     Add support for factory start.
2003-04-24    bgc     Updated NOR_VERSION from 3 to 5 due to the old ptables
                      that lack the validity check are now invalid.
2002-08-08    drh     Created by dlb.  Added history header.

===========================================================================*/


#ifndef __FS_NOR_SUPER_H__
#define __FS_NOR_SUPER_H__

#include "customer.h"
#include "fs_device.h"
#include "fs_sys_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/* The data associated with the superblock.  All fields of this structure
 * are internal. */
struct fs_super_data;
typedef struct fs_super_data *fs_super_t;

/* Initialize the superblock code.  Searches the device for an existing
 * superblock, and loads it.  If it is not found, then it will erase as
 * necessary and write a simple superblock out. */
void
fs_super_init (
    fs_super_t  super,
    fs_device_t dev,
    int *fresh_start);

/* Write out an updated superblock to the given segment. */
void
fs_super_update (
    fs_super_t  super,
    page_id page);

/* Ensure that the page size is properly configured. */
#ifndef EFS_PAGE_SIZE
  #error EFS_PAGE_SIZE must be defined
#endif

/**********************************************************************
 *   _   _  ___ _____ _____
 *  | \ | |/ _ \_   _| ____|_
 *  |  \| | | | || | |  _| (_)
 *  | |\  | |_| || | | |___ _
 *  |_| \_|\___/ |_| |_____(_)
 *
 * Although this information is in a publically accessible structure (since
 * it is needed), please do not make changes to this data aside from
 * calling the above functions.
 */

/* First is the actual superblock itself.  This is the data written to the
 * device.  The in-memory copy will always be modified as changes are made,
 * even though the changes will not be written as timely.  It is important
 * that this structure be exactly the size of the smallest page size we
 * support (512 bytes). */

/* There are two version fields for alternative types of implementations.
 * These values _MUST_ be distinct, but it is possible to change only one
 * of them. */

/* Since the version codes now contain a bit indicating type, have some
 * macros to check these bits. */

/* This was the first version number that used the lowest bit to indicate
 * NOR/NAND. */
#define FS_SUPER_LOWEST_ENCODED_VERSION  0x0024

/* Macros to construct and deconstruct version numbers. */
#define FS_SUPER_NANDIFY_VERSION(x)   ((x << 1) | 1)
#define FS_SUPER_NORIFY_VERSION(x)    ((x << 1) | 0)
#define FS_SUPER_VERSION_IS_NAND(x)   (((x) & 1) == 1)
#define FS_SUPER_VERSION_IS_NOR(x)    (((x) & 1) == 0)
#define FS_SUPER_VERSIONOF(x)         ((x) >> 1)

/* Given a superblock pointer, these query macros are useful for deciding
 * which particular algorithms to use. */
#define FS_ISNOR(super)  FS_SUPER_VERSION_IS_NOR((super)->data.version)
#define FS_ISNAND(super) FS_SUPER_VERSION_IS_NAND((super)->data.version)

/* Older superblock versions.  These are named after the feature change
 * that caused the bump.  Non-forward-compatible changes should indicate
 * this change with a larger version bump (such as to the next multiple of
 * 0x100). */
#define FS_SUPER_VERSION_QANDR     0x0012
#define FS_SUPER_VERSION_LONGNAME  0x0013
#define FS_SUPER_VERSION_LOGCRC    0x0014
#define FS_SUPER_VERSION_DBGID     0x0015

#define FS_SUPER_VERSION       FS_SUPER_VERSION_DBGID
#define FS_SUPER_VERSION_NOR   FS_SUPER_NORIFY_VERSION (FS_SUPER_VERSION)
#define FS_SUPER_VERSION_NAND  FS_SUPER_NANDIFY_VERSION (FS_SUPER_VERSION)

/* There are two magic numbers in the superblock itself.  These are to
 * reduce the likelyhood of deciding alternative data is a superblock.
 * In little endian, this is viewed in ASCII as "EFSSuper". */
#define FS_SUPER_MAGIC1    0x53534645
#define FS_SUPER_MAGIC2    0x72657075

/* Version 1 supports the superblock in this many diverse locations. */
#define SUPER_SEGMENTS  4

/* Maximum number of regions supported by this version of the superblock. */
#define FS_MAXIMUM_REGIONS      4

/* The number of superblock contained page table entries.  This is chosen
 * to make the superblock fit inside a single page. */
#if EFS_PAGE_SIZE == 512
  #define SUPERBLOCK_PAGE_ENTRIES   34
#elif EFS_PAGE_SIZE == 2048
  #define SUPERBLOCK_PAGE_ENTRIES   226
#endif


/* Definitions of which page table is which. */
#define FS_PTABLE       0
#define FS_RTABLE       1

/**********************************************************************/
/* Constants defining the region boundaries in NAND flash. */

/* Number of blocks used by the log region in NAND.  These are always at
 * the very end of flash.   Too few, and the wear in this region becomes
 * too concentrated and expires these blocks before others.
 * Too many, and it wastes space that could be used for data.
 * 512KB is a reasonable size.   A target may wish to override the value
 * by defining EFS_NAND_LOG_REGION_BLOCKS. */
#ifdef EFS_NAND_LOG_REGION_BLOCKS
  #define FS_NAND_LOG_REGION_BLOCKS (EFS_NAND_LOG_REGION_BLOCKS)
#elif EFS_PAGE_SIZE ==  512
  #define FS_NAND_LOG_REGION_BLOCKS 32
#elif EFS_PAGE_SIZE == 2048
  #define FS_NAND_LOG_REGION_BLOCKS  8
#endif

/* Number of regions in the NAND flash. */
#define FS_NAND_REGION_COUNT            4

struct nor_info {
  fs_device_write_style_t   style;
};

struct nand_info {
  uint16        nodes_per_page;
  uint16        page_depth;             /* Depth of page table, including
                                           nodes within the superblock. */
  uint16        super_nodes;            /* Page nodes within the
                                           superblock. */
  uint16        num_regions;            /* How many regions are in this FS. */
  uint32        regions[FS_MAXIMUM_REGIONS];
                                        /* Offset of the start of each
                                         * region.  Region 0 is assumed to
                                         * start at 0, regions[0] indicates
                                         * the start of region 1, and so
                                         * on. */
  uint32        logr_badmap;            /* Map of bad blocks in the log
                                           region. */
  uint32        pad;
  uint32        tables[2][SUPERBLOCK_PAGE_ENTRIES];
};

struct superblock_data {
  uint32        page_header;
  uint16        version;
  uint16        age;
  uint32        magic1;
  uint32        magic2;
  uint32        block_size;             /* Number of pages per block. */
  uint32        page_size;              /* Page size in bytes. */
  uint32        block_count;            /* Total number of blocks in
                                           filesystem. */
  uint32        log_head;
  uint32        alloc_next[FS_MAXIMUM_REGIONS];
  uint32        gc_next[FS_MAXIMUM_REGIONS];

  /* data stored in the superblock on behalf of an upper layer of code */
  uint32        upper_data[FS_UPPER_DATA_COUNT];
  union {
    struct nand_info nand;
    struct nor_info nor;
  } u;
  uint32        _padding[3];    /* Superblock must be 512 bytes */
  uint32        crc32;
};
typedef struct superblock_data *superblock_data_t;

/* This is the data structure holding the superblock information.  This
 * also holds a cache of various other computed information. */

struct fs_super_data {
  struct superblock_data   data;

  /* Device this superblock resides in. */
  fs_device_t dev;

  /* Number of bits to shift a block into a page number.  This is the log
   * base 2 of the block size.  The block mask has the low bits cleared to
   * mask out and only get the block part of a page.*/
  int block_shift;
  uint32 block_mask;

  /* A count of the total number of pages.  Again, just to save math. */
  uint32 total_pages;

  /* Locations where each superblock will be written.  These are block
   * numbers, and the superblock should be written as the first page of
   * that block.  These values can change if blocks wear out. */
  uint32 segment_offsets[SUPER_SEGMENTS];

  /* Tracking for updates.  During the update, the superblock will remain
   * at the older version.  Once it is finished, the next superblock update
   * will switch to the correct version. */
  uint32 desired_version;
};

/* Needed for factory code. */
/* Create an initial superblock.  Assumes that no other superblocks were
 * found (otherwise the new one wouldn't be always be the oldest. */
void fs_super_create_superblock (fs_super_t super);

/* Needed for wipeefs and for factory startup code.  Invalidates any
 * existing superblocks. */
void fs_pm_super_invalidate_superblocks (void);

#ifdef __cplusplus
}
#endif

#endif /* __FS_NOR_SUPER_H__ */