📄 ftllite.c
字号:
/* * $Log: V:/ftllite.c_v $ * * Rev 1.36 01 Mar 1998 12:59:36 amirban * Add parameter to mapSector * * Rev 1.35 23 Feb 1998 17:08:32 Yair * Added casts * * Rev 1.34 19 Feb 1998 19:05:46 amirban * Shortened FORMAT_PATTERN, and changed repl. page handling * * Rev 1.33 23 Nov 1997 17:19:36 Yair * Get rid of warnings (With Danny) * * Rev 1.32 11 Nov 1997 15:26:46 ANDRY * () in complex expressions to get rid of compiler warnings * * Rev 1.31 06 Oct 1997 18:37:24 ANDRY * no COBUX * * Rev 1.30 05 Oct 1997 15:31:40 ANDRY * for COBUX: checkForWriteInPlace() always skips even number of bytes` * * Rev 1.29 28 Sep 1997 18:22:08 danig * Free socket buffer in flsocket.c * * Rev 1.28 23 Sep 1997 18:09:44 danig * Initialize buffer.sectorNo in initTables * * Rev 1.27 10 Sep 1997 16:17:16 danig * Got rid of generic names * * Rev 1.26 31 Aug 1997 14:28:30 danig * Registration routine return status * * Rev 1.25 28 Aug 1997 19:01:28 danig * buffer per socket * * Rev 1.24 28 Jul 1997 14:52:30 danig * volForCallback * * Rev 1.23 24 Jul 1997 18:02:44 amirban * FAR to FAR0 * * Rev 1.22 21 Jul 1997 19:18:36 danig * Compile with SINGLE_BUFFER * * Rev 1.21 20 Jul 1997 17:17:12 amirban * Get rid of warnings * * Rev 1.20 07 Jul 1997 15:22:00 amirban * Ver 2.0 * * Rev 1.19 03 Jun 1997 17:08:10 amirban * setBusy change * * Rev 1.18 18 May 1997 17:56:04 amirban * Add flash read/write flag parameter * * Rev 1.17 01 May 1997 12:15:52 amirban * Initialize vol.garbageCollectStatus * * Rev 1.16 02 Apr 1997 16:56:06 amirban * More Big-Endian: Virtual map * * Rev 1.15 18 Mar 1997 15:04:06 danig * More Big-Endian corrections for BAM * * Rev 1.14 10 Mar 1997 18:52:38 amirban * Big-Endian corrections for BAM * * Rev 1.13 21 Oct 1996 18:03:18 amirban * Defragment i/f change * * Rev 1.12 09 Oct 1996 11:55:30 amirban * Assign Big-Endian unit numbers * * Rev 1.11 08 Oct 1996 12:17:46 amirban * Use remapped * * Rev 1.10 03 Oct 1996 11:56:42 amirban * New Big-Endian * * Rev 1.9 09 Sep 1996 11:39:12 amirban * Background and mapSector bugs * * Rev 1.8 29 Aug 1996 14:19:04 amirban * Fix boot-image bug, warnings * * Rev 1.7 15 Aug 1996 14:04:38 amirban * * Rev 1.6 12 Aug 1996 15:49:54 amirban * Advanced background transfer, and defined setBusy * * Rev 1.5 31 Jul 1996 14:30:28 amirban * Background stuff * * Rev 1.3 08 Jul 1996 17:21:16 amirban * Better page scan in mount unit * * Rev 1.2 16 Jun 1996 14:03:42 amirban * Added badFormat return code for mount * * Rev 1.1 09 Jun 1996 18:16:02 amirban * Corrected definition of LogicalAddress * * Rev 1.0 20 Mar 1996 13:33:06 amirban * Initial revision. *//************************************************************************//* *//* FAT-FTL Lite Software Development Kit *//* Copyright (C) M-Systems Ltd. 1995-1996 *//* *//************************************************************************/#include "backgrnd.h"#include "flflash.h"#include "flbuffer.h"#include "fltl.h"/* Implementation constants and type definitions */#define SECTOR_OFFSET_MASK (SECTOR_SIZE - 1)typedef long int LogicalAddress; /* Byte address of media in logical unit no. order. */typedef long int VirtualAddress; /* Byte address of media as specified by Virtual Map. */typedef SectorNo LogicalSectorNo; /* A logical sector no. is given by dividing its logical address by the sector size */typedef SectorNo VirtualSectorNo; /* A virtual sector no. is such that the first page is no. 0, the 2nd is 1 etc. The virtual sector no. is given by dividing its virtual address by the sector size and adding the number of pages (result always positive). */typedef unsigned short UnitNo;#define ADDRESSES_PER_SECTOR (SECTOR_SIZE / sizeof(LogicalAddress))#define UNASSIGNED_ADDRESS 0xffffffffl#define DELETED_ADDRESS 0#define DELETED_SECTOR 0#define PAGE_SIZE_BITS (SECTOR_SIZE_BITS + (SECTOR_SIZE_BITS - 2))#define PAGE_SIZE (1L << PAGE_SIZE_BITS)/* Unit descriptor record */#define UNASSIGNED_UNIT_NO 0xffff#define MARKED_FOR_ERASE 0x7ffftypedef struct { short noOfFreeSectors; short noOfGarbageSectors;} Unit;typedef Unit *UnitPtr;/* Structure of data on a unit */#define FREE_SECTOR 0xffffffffl#define GARBAGE_SECTOR 0#define ALLOCATED_SECTOR 0xfffffffel#define FORMAT_SECTOR 0x30#define DATA_SECTOR 0x40#define REPLACEMENT_PAGE 0x60#define BAD_SECTOR 0x70static char FORMAT_PATTERN[15] = {0x13, 3, 'C', 'I', 'S', 0x46, 57, 0, 'F', 'T', 'L', '1', '0', '0', 0};typedef struct { char formatPattern[15]; unsigned char noOfTransferUnits; /* no. of transfer units */ LEulong wearLevelingInfo; LEushort logicalUnitNo; unsigned char log2SectorSize; unsigned char log2UnitSize; LEushort firstPhysicalEUN; /* units reserved for boot image */ LEushort noOfUnits; /* no. of formatted units */ LEulong virtualMediumSize; /* virtual size of volume */ LEulong directAddressingMemory; /* directly addressable memory */ LEushort noOfPages; /* no. of virtual pages */ unsigned char flags; unsigned char eccCode; LEulong serialNumber; LEulong altEUHoffset; LEulong BAMoffset; char reserved[12]; char embeddedCIS[4]; /* Actual length may be larger. By default, this contains FF's */} UnitHeader;/* flags assignments */#define HIDDEN_AREA_FLAG 1#define REVERSE_POLARITY_FLASH 2#define DOUBLE_BAI 4#define dummyUnit ((const UnitHeader *) 0) /* for offset calculations */#define logicalUnitNoOffset ((char *) &dummyUnit->logicalUnitNo - \ (char *) dummyUnit)#ifndef MALLOC_TFFS#define HEAP_SIZE \ ((0x100000l / PAGE_SIZE) * \ sizeof(LogicalSectorNo) + \ (0x100000l / ASSUMED_FTL_UNIT_SIZE) * \ (sizeof(Unit) + sizeof(UnitPtr))) * \ MAX_VOLUME_MBYTES + \ (ASSUMED_VM_LIMIT / SECTOR_SIZE) * \ sizeof(LogicalSectorNo)#endif#define cannotWriteOver(newContents, oldContents) \ ((newContents) & ~(oldContents))struct tTLrec { FLBoolean badFormat; /* true if FTL format is bad */ VirtualSectorNo totalFreeSectors; /* Free sectors on volume */ SectorNo virtualSectors; /* size of virtual volume */ unsigned int unitSizeBits; /* log2 of unit size */ unsigned int erasableBlockSizeBits; /* log2 of erasable block size */ UnitNo noOfUnits; UnitNo noOfTransferUnits; UnitNo firstPhysicalEUN; int noOfPages; VirtualSectorNo directAddressingSectors;/* no. of directly addressable sectors */ VirtualAddress directAddressingMemory; /* end of directly addressable memory */ CardAddress unitOffsetMask; /* = 1 << unitSizeBits - 1 */ CardAddress bamOffset; unsigned int sectorsPerUnit; unsigned int unitHeaderSectors; /* sectors used by unit header */ Unit * physicalUnits; /* unit table by physical no. */ Unit ** logicalUnits; /* unit table by logical no. */ Unit * transferUnit; /* The active transfer unit */ LogicalSectorNo * pageTable; /* page translation table */ /* directly addressable sectors */ LogicalSectorNo replacementPageAddress; VirtualSectorNo replacementPageNo; SectorNo mappedSectorNo; const void FAR0 * mappedSector; CardAddress mappedSectorAddress; unsigned long currWearLevelingInfo;#ifdef BACKGROUND Unit * unitEraseInProgress; /* Unit currently being formatted */ FLStatus garbageCollectStatus; /* Status of garbage collection */ /* When unit transfer is in the background, and is currently in progress, all write operations done on the 'from' unit moust be mirrored on the transfer unit. If so, 'mirrorOffset' will be non-zero and will be the offset of the alternate address from the original. 'mirrorFrom' and 'mirrorTo' will be the limits of the original addresses to mirror. */ long int mirrorOffset; CardAddress mirrorFrom, mirrorTo;#endif#ifndef SINGLE_BUFFER FLBuffer * volBuffer; /* Define a sector buffer */#endif FLFlash flash;#ifndef MALLOC_TFFS char heap[HEAP_SIZE];#endif};typedef TLrec Flare;static Flare vols[DRIVES];#ifdef SINGLE_BUFFERextern FLBuffer buffer;#else#define buffer (*vol.volBuffer)/* Virtual map cache (shares memory with buffer) */#define mapCache ((LEulong *) buffer.data)#endif/* Unit header buffer (shares memory with buffer) */#define uh ((UnitHeader *) buffer.data)/* Transfer sector buffer (shares memory with buffer) */#define sectorCopy ((LEulong *) buffer.data)#define FREE_UNIT -0x400 /* Indicates a transfer unit *//*----------------------------------------------------------------------*//* p h y s i c a l B a s e *//* *//* Returns the physical address of a unit. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* unit : unit pointer *//* *//* Returns: *//* physical address of unit *//*----------------------------------------------------------------------*/static CardAddress physicalBase(Flare vol, const Unit *unit){ return (CardAddress) (unit - vol.physicalUnits) << vol.unitSizeBits;}/*----------------------------------------------------------------------*//* l o g i c a l 2 P h y s i c a l *//* *//* Returns the physical address of a logical sector no. *//* *//* Parameters: *//* vol : Pointer identifying drive *//* address : logical sector no. *//* *//* Returns: *//* CardAddress : physical address of sector *//*----------------------------------------------------------------------*/static CardAddress logical2Physical(Flare vol, LogicalSectorNo address){ return physicalBase(&vol,vol.logicalUnits[address >> (vol.unitSizeBits - SECTOR_SIZE_BITS)]) | (((CardAddress) address << SECTOR_SIZE_BITS) & vol.unitOffsetMask);}/*----------------------------------------------------------------------*//* m a p L o g i c a l *//* *//* Maps a logical sector and returns pointer to physical Flash location.*//* *//* Parameters: *//* vol : Pointer identifying drive *//* address : logical sector no. *//* *//* Returns: *//* Pointer to sector on Flash *//*----------------------------------------------------------------------*/static void FAR0 *mapLogical(Flare vol, LogicalSectorNo address){ return vol.flash.map(&vol.flash,logical2Physical(&vol,address),SECTOR_SIZE);}/*----------------------------------------------------------------------*//* a l l o c E n t r y O f f s e t *//* *//* Returns unit offset of given BAM entry *//* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -