mgh: fix for default HDD DMA mode, that wasn't correctly set
[open-ps2-loader.git] / modules / ps2fs / misc.c
blob6876b22ad3a114a81b179dd74352b02fdbb09a1c
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: misc.c 1370 2007-01-17 02:28:14Z jbit $
11 # Miscellaneous routines
14 #include "pfs.h"
16 ///////////////////////////////////////////////////////////////////////////////
17 // Function defenitions
19 void *allocMem(int size)
21 int intrStat;
22 void *mem;
24 CpuSuspendIntr(&intrStat);
25 mem = AllocSysMemory(ALLOC_FIRST, size, NULL);
26 CpuResumeIntr(intrStat);
28 return mem;
31 int getPs2Time(pfs_datetime *tm)
33 cd_clock_t cdtime;
34 s32 tmp;
35 static pfs_datetime timeBuf={
36 0, 0x0D, 0x0E, 0x0A, 0x0D, 1, 2003 // used if can not get time...
39 if(CdReadClock(&cdtime)!=0 && cdtime.stat==0)
41 tmp=cdtime.second>>4;
42 timeBuf.sec=(u32)(((tmp<<2)+tmp)<<1)+(cdtime.second&0x0F);
43 tmp=cdtime.minute>>4;
44 timeBuf.min=(((tmp<<2)+tmp)<<1)+(cdtime.minute&0x0F);
45 tmp=cdtime.hour>>4;
46 timeBuf.hour=(((tmp<<2)+tmp)<<1)+(cdtime.hour&0x0F);
47 // timeBuf.hour = (timeBuf.hour + 4) % 24; // TEMP FIX (need to deal with timezones?) ... aparently not!
48 tmp=cdtime.day>>4;
49 timeBuf.day=(((tmp<<2)+tmp)<<1)+(cdtime.day&0x0F);
50 tmp=cdtime.month>>4;
51 timeBuf.month=(((tmp<<2)+tmp)<<1)+(cdtime.month&0x0F);
52 tmp=cdtime.year>>4;
53 timeBuf.year=(((tmp<<2)+tmp)<<1)+(cdtime.year&0xF)+2000;
55 memcpy(tm, &timeBuf, sizeof(pfs_datetime));
56 return 0;
59 int fsckStat(pfs_mount_t *pfsMount, pfs_super_block *superblock,
60 u32 stat, int mode)
61 { // mode 0=set flag, 1=remove flag, else check stat
63 if(pfsMount->blockDev->transfer(pfsMount->fd, superblock, 0, PFS_BLOCKSIZE, 1,
64 IOCTL2_TMODE_READ)==0)
66 switch(mode)
68 case MODE_SET_FLAG: // set flag
69 superblock->fsckStat|=stat;
70 break;
71 case MODE_REMOVE_FLAG: // remove flag
72 superblock->fsckStat&=~stat;
73 break;
74 default/*MODE_CHECK_FLAG*/:// check flag
75 return 0 < (superblock->fsckStat & stat);
77 pfsMount->blockDev->transfer(pfsMount->fd, superblock, 0, PFS_BLOCKSIZE, 1,
78 IOCTL2_TMODE_WRITE);
79 pfsMount->blockDev->flushCache(pfsMount->fd);
81 return 0;
84 void printBitmap(u32 *bitmap) {
85 u32 i, j;
86 char a[48+1], b[16+1];
88 b[16]=0;
89 for (i=0; i < 32; i++){
90 memset(a, 0, 49);
91 for (j=0; j < 16; j++){
92 char *c=(char*)bitmap+j+i*16;
94 sprintf(a+j*3, "%02x ", *c);
95 b[j] = ((*c>=0) && (look_ctype_table(*c) & 0x17)) ?
96 *c : '.';
98 printf("%s%s\n", a, b);
102 int getScale(int num, int size)
104 int scale = 0;
106 while((size << scale) != num)
107 scale++;
109 return scale;
112 u32 fixIndex(u32 index)
114 if(index < 114)
115 return index;
117 index -= 114;
118 return index % 123;
122 int checkAccess(pfs_cache_t *clink, int flags)
124 int mode;
126 // Bail if trying to write to read-only mount
127 if ((clink->pfsMount->flags & FIO_MT_RDONLY) && (flags & O_WRONLY))
128 return -EROFS;
130 if (((clink->u.inode->mode & FIO_S_IFMT) != FIO_S_IFDIR) &&
131 ((clink->u.inode->mode & 0111) == 0))
132 mode=6;
133 else
134 mode=7;
135 return ((mode & flags) & 7) == flags ? 0 : -EACCES;
138 char* splitPath(char *filename, char *path, int *result)
140 int i=0;
141 int j=0;
143 for (i=0; filename[i] == '/'; i++)
146 for (; i<1024 && filename[i] != '/'; i++){
147 if (filename[i] == 0) break;
148 if (j < 255)
149 path[j++] = filename[i];
152 if (j<256)
153 path[j]=0;
155 while (filename[i] == '/')
156 if (i<1024)
157 i++;
158 else
159 break;
160 if (i<1024)
161 return &filename[i];
163 *result=-ENAMETOOLONG;
164 return 0;
167 u16 getMaxthIndex(pfs_mount_t *pfsMount)
169 u32 max=0, maxI=0, i, v;
171 for (i=0; i < pfsMount->num_subs + 1; i++) //enumerate all subs
173 v = (pfsMount->free_zone[i] * (u64)100) /
174 (pfsMount->blockDev->getSize(pfsMount->fd, i) >> pfsMount->sector_scale);
175 if (max < v)
177 max=v;
178 maxI=i;
181 return maxI;
184 ///////////////////////////////////////////////////////////////////////////////
185 // Functions to work with hdd.irx
187 #define NUM_SUPPORTED_DEVICES 1
188 block_device deviceCallTable[NUM_SUPPORTED_DEVICES] = {
190 "hdd",
191 hddTransfer,
192 hddGetSubNumber,
193 hddGetSize,
194 hddSetPartError,
195 hddFlushCache,
199 block_device *getDeviceTable(const char *name)
201 char *end;
202 char devname[32];
203 char *tmp;
204 u32 len;
205 int i;
207 while(name[0] == ' ')
208 name++;
210 end = strchr(name, ':');
211 if(!end) {
212 printf("ps2fs: Error: Unknown block device '%s'\n", name);
213 return NULL;
216 len = (u32)end - (u32)name;
217 strncpy(devname, name, len);
218 devname[len] = '\0';
220 // Loop until digit is found, then terminate string at that digit.
221 // Should then have just the device name left, minus any front spaces or trailing digits.
222 tmp = devname;
223 while(!(look_ctype_table(tmp[0]) & 0x04))
224 tmp++;
225 tmp[0] = '\0';
227 for(i = 0; i < NUM_SUPPORTED_DEVICES; i++)
228 if(!strcmp(deviceCallTable[i].devName, devname))
229 return &deviceCallTable[i];
231 return NULL;
234 int hddTransfer(int fd, void *buffer, u32 sub/*0=main 1+=subs*/, u32 sector,
235 u32 size/* in sectors*/, u32 mode)
237 hdd_ioctl2_transfer_t t;
239 t.sub=sub;
240 t.sector=sector;
241 t.size=size;
242 t.mode=mode;
243 t.buffer=buffer;
245 return ioctl2(fd, APA_IOCTL2_TRANSFER_DATA, &t, 0, NULL, 0);
248 u32 hddGetSubNumber(int fd)
250 return ioctl2(fd, APA_IOCTL2_NUMBER_OF_SUBS, NULL, 0, NULL, 0);
253 u32 hddGetSize(int fd, u32 sub/*0=main 1+=subs*/)
254 { // of a partition
255 return ioctl2(fd, APA_IOCTL2_GETSIZE, &sub, 0, NULL, 0);
258 void hddSetPartError(int fd)
260 ioctl2(fd, APA_IOCTL2_SET_PART_ERROR, NULL, 0, NULL, 0);
263 int hddFlushCache(int fd)
265 return ioctl2(fd, APA_IOCTL2_FLUSH_CACHE, NULL, 0, NULL, 0);