Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / modules / hdd / ps2hdd / cache.c
blob39cef7ee873b08ebad49cf29f441e258f40ba15b
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
10 # $Id: cache.c 911 2005-03-14 21:02:17Z oopo $
11 # APA cache manipulation routines
14 #include "hdd.h"
16 // Globals
17 apa_cache *cacheBuf;
18 int cacheSize;
20 int cacheInit(u32 size)
22 apa_header *header;
23 int i;
25 cacheSize=size; // save size ;)
26 if((header=(apa_header *)allocMem(size*sizeof(apa_header)))){
27 cacheBuf=allocMem((size+1)*sizeof(apa_cache));
28 if(cacheBuf==NULL)
29 return -ENOMEM;
31 else
32 return -ENOMEM;
33 // setup cache header...
34 memset(cacheBuf, 0, (size+1)*sizeof(apa_cache));
35 cacheBuf->next=cacheBuf;
36 cacheBuf->tail=cacheBuf;
37 for(i=1; i<size+1;i++, header++){
38 cacheBuf[i].header=header;
39 cacheBuf[i].device=-1;
40 cacheLink(cacheBuf->tail, &cacheBuf[i]);
42 return 0;
45 void cacheLink(apa_cache *clink, apa_cache *cnew)
47 cnew->tail=clink;
48 cnew->next=clink->next;
49 clink->next->tail=cnew;
50 clink->next=cnew;
53 apa_cache *cacheUnLink(apa_cache *clink)
55 clink->tail->next=clink->next;
56 clink->next->tail=clink->tail;
57 return clink;
60 int cacheTransfer(apa_cache *clink, int type)
62 int err;
63 if(type)
64 err=apaWriteHeader(clink->device, clink->header, clink->sector);
65 else// 0
66 err=apaReadHeader(clink->device, clink->header, clink->sector);
68 if(err)
70 dprintf1("ps2hdd: Error: disk err %d on device %ld, sector %ld, type %d\n",
71 err, clink->device, clink->sector, type);
72 if(type==0)// save any read error's..
73 apaSaveError(clink->device, clink->header, APA_SECTOR_SECTOR_ERROR, clink->sector);
75 clink->flags&=~CACHE_FLAG_DIRTY;
76 return err;
79 void cacheFlushDirty(apa_cache *clink)
81 if(clink->flags&CACHE_FLAG_DIRTY)
82 cacheTransfer(clink, THEADER_MODE_WRITE);
85 int cacheFlushAllDirty(u32 device)
87 u32 i;
88 // flush apal
89 for(i=1;i<cacheSize+1;i++){
90 if((cacheBuf[i].flags & CACHE_FLAG_DIRTY) && cacheBuf[i].device==device)
91 journalWrite(&cacheBuf[i]);
93 journalFlush(device);
94 // flush apa
95 for(i=1;i<cacheSize+1;i++){
96 if((cacheBuf[i].flags & CACHE_FLAG_DIRTY) && cacheBuf[i].device==device)
97 cacheTransfer(&cacheBuf[i], THEADER_MODE_WRITE);
99 return journalReset(device);
102 apa_cache *cacheGetHeader(u32 device, u32 sector, u32 mode, int *result)
104 apa_cache *clink=NULL;
105 int i;
107 *result=0;
108 for(i=1;i<cacheSize+1;i++){
109 if(cacheBuf[i].sector==sector &&
110 cacheBuf[i].device==device){
111 clink=&cacheBuf[i];
112 break;
115 if(clink!=NULL) {
116 // cached ver was found :)
117 if(clink->nused==0)
118 clink=cacheUnLink(clink);
119 clink->nused++;
120 return clink;
122 if((cacheBuf->tail==cacheBuf) &&
123 (cacheBuf->tail==cacheBuf->tail->next)){
124 dprintf1("ps2hdd: error: free buffer empty\n");
126 else
128 clink=cacheBuf->next;
129 if(clink->flags & CACHE_FLAG_DIRTY)
130 dprintf1("ps2hdd: error: dirty buffer allocated\n");
131 clink->flags=0;
132 clink->nused=1;
133 clink->device=device;
134 clink->sector=sector;
135 clink=cacheUnLink(clink);
137 if(clink==NULL)
139 *result=-ENOMEM;
140 return NULL;
142 if(!mode)
144 if((*result=cacheTransfer(clink, THEADER_MODE_READ))<0){
145 clink->nused=0;
146 clink->device=-1;
147 cacheLink(cacheBuf, clink);
148 clink=NULL;
151 return clink;
154 void cacheAdd(apa_cache *clink)
156 if(clink==NULL){
157 dprintf1("ps2hdd: Error: null buffer returned\n");
158 return;
160 if(clink->nused==0){
161 dprintf1("ps2hdd: Error: unused cache returned\n");
162 return;
164 if(clink->flags & CACHE_FLAG_DIRTY)
165 dprintf1("ps2hdd: Error: dirty buffer returned\n");
166 clink->nused--;
167 if(clink->nused==0)
168 cacheLink(cacheBuf->tail, clink);
169 return;
172 apa_cache *cacheGetFree()
174 apa_cache *cnext;
176 if((cacheBuf->tail==cacheBuf) &&
177 (cacheBuf->tail==cacheBuf->tail->next)){
178 dprintf1("ps2hdd: Error: free buffer empty\n");
179 return NULL;
181 cnext=cacheBuf->next;
182 if(cnext->flags & CACHE_FLAG_DIRTY)
183 dprintf1("ps2hdd: Error: dirty buffer allocated\n");
184 cnext->nused=1;
185 cnext->flags=0;
186 cnext->device=(u32)-1;
187 cnext->sector=-1;
188 return cacheUnLink(cnext);