/*static char *SCCSID = "@(#)cachdata.c 6.6 91/12/02";*/

#define SCCSID "@(#)cachdata.c  6.6 91/12/02"
/********************************************************/
/*                                                      */
/*       IBM/Microsoft Confidential                     */
/*                                                      */
/*       Copyright (c) IBM Corporation 1987, 1989       */
/*       Copyright (c) Microsoft Corporation 1987, 1989 */
/*                                                      */
/*       All Rights Reserved                            */
/********************************************************/

#define FNO_NUM FNO_CACHDATA_C
#define INCL_TYPES                      // for basedef.h typedefs
#include <osconst.h>
#include <ostypes.h>
#include <basemac.h>
#include <basedef.h>
#include <fnofs.h>
#include <osmac.h>
#include <mi.h>
#include <sft.h>
#include <pgexport.h>
#include <tkexport.h>
#include <cache.h>

PBUFHDR BufHashTable [HASHCNT] = {NULL};      /* hash table */

BUFHDR BufLRUHead;                      // Head of LRU chain
BUFHDR BufFreeList;
int GFB_Sem = 0;
BUFHDR BufDirtyHead;
ulong_t FileDirtyMsk = DMASK_INIT;

int fLWDaemon;
int fAsyncReadRunning = FALSE;
int AsyncReadSem;
ulong_t AsyncReadHeadSel = 0;
ulong_t AsyncReadHeadOff = 0;
ulong_t AsyncReadTailSel = 0;
ulong_t AsyncReadTailOff = 0;
ulong_t msLastIO;
ulong_t cBufs = 0;
ulong_t cbufLWLock = 0;         /* count of buffers locked by lazy write thread */
ulong_t LWBufWanted = 0;
int fGFBActive = 0;
ulong_t pGFBWaitChain = 0;
ulong_t S2_RW_RQPKT_SIZE;
ulong_t DiskThresh;
ulong_t FLWReqListSel = 0;

ulong_t cachebuffer1 = 0;          /* address of 1st FAT cache buffer */
ulong_t cachebuffer2 = 0;          /* address of 1st FAT cache header buffer */
ulong_t cachebuffer3 = 0;          /* address of 2nd FAT cache buffer */
ulong_t cachebuffer4 = 0;          /* address of 2st FAT cache header buffer */

LWPARMS LWData = {       /* Lazy write parameters                */
    1000L,      /* msIdle       ms of no disk I/O to declare idle  */
    5000L,      /* msDataAge    max number of ms dirty data in cache */
     500L,      /* msIdleBuf    ms since last buffer dirty before idle flush */
   65536L,      /* cbWriteCache threshold below which all writes are cached */
   65535L,      /* cbufDirtyMax max # dirty before AddLw wakes up lazy write */
       0L       /* cbuf         total number of buffers */
};
BUFA_LOOKUP aBufa = {
        {0,0}, {0,1}, {1,1}, {0,2},
        {2,1}, {0,3}, {1,2}, {0,3},
        {3,1}, {0,4}, {1,3}, {0,4},
        {2,2}, {0,4}, {1,3}, {0,4}
            };
ulong_t semLW = 0;            /* semaphore for lazy daemon block      */
ulong_t semLR = 0;            /* semaphore for lazy read block      */
ulong_t semLRWait = 0;        /* semaphore for lazy read block      */
ulong_t cbufLWLock;            /* count of buffers locked by lazy write thread */
ulong_t pLinLRBuf;             /* Linear address of Lazy Read buffer */
ulong_t pPhysLRBuf;            /* physical address of Lazy Read buffer */
ulong_t msLastDiskWrite = 0;
/*
 *** Count of dirty buffers
 */

ulong_t cbufDirty = 0;       /* this is decremented in DCBREM when we remove
                              * a buffer out of the dirty chain */
/*
 *** Dirty Ordinal table--lookup table to set dirty bits after a write
 *
 */

BYTE abDirtOrd[] = {
           1, 3, 7, 0xf,
           0, 2, 6, 0xe,
           0, 0, 4, 0xc,
           0, 0, 0, 8
           };

/*
 ***    Dirty bits if entire block changed starting at sector 'i'
 */
BYTE abDirtBits[] = {
        0x0f, 0x0e, 0x0c, 0x08
                    };
/*
 ***    Clearing mask for buf.CacheDirDirtMask value if we don't finish block
 */
BYTE abDirtBits2[] = {
        0xff, 0xf1, 0xf3, 0xf7
                     };
BYTE ByteBitMasks[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

ulong_t FreeBufs = 0;

KSEMMTX HotFixKsem;
KSEMMTX FLWKsem;
int fHotFixing;
