00001 /*************************************************************************** 00002 writeback.h - 00003 writeback routines for 00004 committing data to a static disk 00005 ------------------- 00006 begin : Thu Nov 4 2005 00007 email : ngustavson@emacinc.com 00008 ***************************************************************************/ 00009 00010 #ifndef _WRITEBACK_H_ 00011 #define _WRITEBACK_H_ 00012 #include <stdio.h> 00013 #include <eeprom.h> 00014 00015 #define DIRTY 1 00016 00017 //hardware implementation specific routines 00018 #define EEPROM_WRITEBACK 00019 #ifdef EEPROM_WRITEBACK 00020 typedef eeblock blocktype; 00021 00022 static inline blocktype DISKREAD(blocktype *address, int offset) 00023 { return(address[offset]);} 00024 00025 static inline int DISKWRITE(blocktype *address,int offset,blocktype data) 00026 { return(eeprom_modify(&address[offset],data));} 00027 00028 #endif 00029 00030 typedef struct persistant_block{ 00031 int size; //number of data blocks 00032 int status; //current state 00033 blocktype *cache; //address of the cached data 00034 blocktype *disk; //address of the data on the disk 00035 struct persistant_block *previous; 00036 struct persistant_block *next; 00037 }persistant_block; 00038 00039 typedef struct persistant_block_list{ 00040 struct persistant_block *head; 00041 struct persistant_block *tail; 00042 struct persistant_block *current; 00043 int offset; 00044 int size; 00045 }persistant_block_list; 00046 00047 static inline void init_list(persistant_block_list *list){ 00048 list->head=list->tail=list->current=NULL; 00049 list->offset=list->size=0; 00050 } 00051 00052 static inline void invalidate(persistant_block *block){ 00053 block->status|=DIRTY; 00054 } 00055 00056 void __attribute__((far)) swapin(persistant_block *block); 00057 int __attribute__((far)) writeback(persistant_block_list *list); 00058 void enqueue_block(persistant_block_list *list,persistant_block *block); 00059 00060 static inline persistant_block *next_dirty(persistant_block *block){ 00061 persistant_block *start = block; 00062 00063 if(block==NULL) 00064 return NULL;//invalid block, possibly an empty list 00065 00066 do{ 00067 if(block->status&DIRTY) 00068 return block; 00069 block = block->next; 00070 }while(block!=start); 00071 00072 return NULL;//no dirty blocks found 00073 } 00074 00075 static inline int validate(persistant_block *block){ 00076 int offset; 00077 for(offset=0;offset<block->size;offset++) 00078 if(block->cache[offset]!=DISKREAD(block->disk,offset)) 00079 return 0; 00080 00081 return 1; 00082 } 00083 00084 #endif //_WRITEBACK_H_