PS2SDK
PS2 Homebrew Libraries
misc.c
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.
9 #
10 # Miscellaneous routines
11 */
12 
13 #include <errno.h>
14 #include <stdio.h>
15 #include <iomanX.h>
16 #ifdef _IOP
17 #include <intrman.h>
18 #include <sysmem.h>
19 #include <sysclib.h>
20 #include <thbase.h>
21 #include <cdvdman.h>
22 #else
23 #include <string.h>
24 #include <stdlib.h>
25 #include <time.h>
26 #endif
27 #include <ctype.h>
28 #include <hdd-ioctl.h>
29 
30 #include "libpfs.h"
31 
33 // Function definitions
34 
35 void *pfsAllocMem(int size)
36 {
37 #ifdef _IOP
38  int intrStat;
39  void *mem;
40 
41  CpuSuspendIntr(&intrStat);
42  mem = AllocSysMemory(ALLOC_FIRST, size, NULL);
43  CpuResumeIntr(intrStat);
44 
45  return mem;
46 #else
47  return malloc(size);
48 #endif
49 }
50 
51 void pfsFreeMem(void *buffer)
52 {
53 #ifdef _IOP
54  int OldState;
55 
56  CpuSuspendIntr(&OldState);
57  FreeSysMemory(buffer);
58  CpuResumeIntr(OldState);
59 #else
60  free(buffer);
61 #endif
62 }
63 
64 int pfsGetTime(pfs_datetime_t *tm)
65 {
66 #ifdef _IOP
67  int i;
68  sceCdCLOCK cdtime;
69  static pfs_datetime_t timeBuf={
70  0, 7, 6, 5, 4, 3, 2000 // used if can not get time...
71  };
72 
73  for(i = 0; i < 20; i++)
74  {
75  int ret;
76 
77  ret = sceCdReadClock(&cdtime);
78 
79  if(ret!=0 && cdtime.stat==0)
80  {
81  timeBuf.sec=btoi(cdtime.second);
82  timeBuf.min=btoi(cdtime.minute);
83  timeBuf.hour=btoi(cdtime.hour);
84  timeBuf.day=btoi(cdtime.day);
85  timeBuf.month=btoi(cdtime.month & 0x7F); //The old CDVDMAN sceCdReadClock() function does not automatically file off the highest bit.
86  timeBuf.year=btoi(cdtime.year) + 2000;
87  break;
88  } else {
89  if(!(cdtime.stat & 0x80))
90  break;
91  }
92 
93  DelayThread(100000);
94  }
95  memcpy(tm, &timeBuf, sizeof(pfs_datetime_t));
96 #else
97  time_t rawtime;
98  struct tm timeinfo;
99  time(&rawtime);
100  // Convert to JST
101  rawtime += (-9 * 60 * 60);
102 #ifdef _WIN32
103  gmtime_s(&timeinfo, &rawtime);
104 #else
105  gmtime_r(&rawtime, &timeinfo);
106 #endif
107 
108  tm->sec = timeinfo.tm_sec;
109  tm->min = timeinfo.tm_min;
110  tm->hour = timeinfo.tm_hour;
111  tm->day = timeinfo.tm_mday;
112  tm->month = timeinfo.tm_mon + 1;
113  tm->year = timeinfo.tm_year + 1900;
114 #endif
115 
116  return 0;
117 }
118 
119 int pfsFsckStat(pfs_mount_t *pfsMount, pfs_super_block_t *superblock,
120  u32 stat, int mode)
121 { // mode 0=set flag, 1=remove flag, else check stat
122 
123  if(pfsMount->blockDev->transfer(pfsMount->fd, superblock, 0, PFS_SUPER_SECTOR, 1,
124  PFS_IO_MODE_READ)==0)
125  {
126  switch(mode)
127  {
128  case PFS_MODE_SET_FLAG:
129  superblock->pfsFsckStat|=stat;
130  break;
131  case PFS_MODE_REMOVE_FLAG:
132  superblock->pfsFsckStat&=~stat;
133  break;
134  default/*PFS_MODE_CHECK_FLAG*/:
135  return 0 < (superblock->pfsFsckStat & stat);
136  }
137  pfsMount->blockDev->transfer(pfsMount->fd, superblock, 0, PFS_SUPER_SECTOR, 1,
138  PFS_IO_MODE_WRITE);
139  pfsMount->blockDev->flushCache(pfsMount->fd);
140  }
141  return 0;
142 }
143 
144 void pfsPrintBitmap(const u32 *bitmap) {
145  u32 i, j;
146  char a[48+1], b[16+1];
147 
148  b[16]=0;
149  for (i=0; i < 32; i++){
150  memset(a, 0, 49);
151  for (j=0; j < 16; j++){
152  const char *c=(const char*)bitmap+j+i*16;
153 
154  sprintf(a+j*3, "%02x ", *c);
155  b[j] = ((*c>=0) && (isgraph(*c))) ?
156  *c : '.';
157  }
158  PFS_PRINTF("%s%s\n", a, b);
159  }
160 }
161 
162 u32 pfsGetScale(u32 num, u32 size)
163 {
164  u32 scale = 0;
165 
166  while((size << scale) != num)
167  scale++;
168 
169  return scale;
170 }
171 
172 u32 pfsFixIndex(u32 index)
173 {
174  if(index < PFS_INODE_MAX_BLOCKS)
175  return index;
176 
177  index -= PFS_INODE_MAX_BLOCKS;
178  return index % 123;
179 }
180 
182 // Functions to work with hdd.irx
183 
184 static int pfsHddTransfer(int fd, void *buffer, u32 sub/*0=main 1+=subs*/, u32 sector,
185  u32 size/* in sectors*/, u32 mode);
186 static u32 pfsHddGetSubCount(int fd);
187 static u32 pfsHddGetPartSize(int fd, u32 sub/*0=main 1+=subs*/);
188 static void pfsHddSetPartError(int fd);
189 static int pfsHddFlushCache(int fd);
190 
191 #ifdef PFS_SUPPORT_BHDD
192 #define NUM_SUPPORTED_DEVICES 2
193 #else
194 #define NUM_SUPPORTED_DEVICES 1
195 #endif
196 pfs_block_device_t pfsBlockDeviceCallTable[NUM_SUPPORTED_DEVICES] = {
197  {
198  "hdd",
199  &pfsHddTransfer,
200  &pfsHddGetSubCount,
201  &pfsHddGetPartSize,
202  &pfsHddSetPartError,
203  &pfsHddFlushCache,
204  },
205 #ifdef PFS_SUPPORT_BHDD
206  {
207  "bhdd",
208  &pfsHddTransfer,
209  &pfsHddGetSubCount,
210  &pfsHddGetPartSize,
211  &pfsHddSetPartError,
212  &pfsHddFlushCache,
213  },
214 #endif
215 };
216 
217 pfs_block_device_t *pfsGetBlockDeviceTable(const char *name)
218 {
219  char *end;
220  char devname[32];
221  char *tmp;
222  u32 len;
223  int i;
224 
225  while(name[0] == ' ')
226  name++;
227 
228  end = strchr(name, ':');
229  if(!end) {
230  PFS_PRINTF(PFS_DRV_NAME": Error: Unknown block device '%s'\n", name);
231  return NULL;
232  }
233 
234  len = (u8*)end - (u8*)name;
235  strncpy(devname, name, len);
236  devname[len] = '\0';
237 
238  // Loop until digit is found, then terminate string at that digit.
239  // Should then have just the device name left, minus any front spaces or trailing digits.
240  tmp = devname;
241  while(!(isdigit(tmp[0])))
242  tmp++;
243  tmp[0] = '\0';
244 
245  for(i = 0; i < NUM_SUPPORTED_DEVICES; i++)
246  if(!strcmp(pfsBlockDeviceCallTable[i].devName, devname))
247  return &pfsBlockDeviceCallTable[i];
248 
249  return NULL;
250 }
251 
252 static int pfsHddTransfer(int fd, void *buffer, u32 sub/*0=main 1+=subs*/, u32 sector,
253  u32 size/* in sectors*/, u32 mode)
254 {
256 
257  t.sub=sub;
258  t.sector=sector;
259  t.size=size;
260  t.mode=mode;
261  t.buffer=buffer;
262 
263  return iomanX_ioctl2(fd, HIOCTRANSFER, &t, 0, NULL, 0);
264 }
265 
266 static u32 pfsHddGetSubCount(int fd)
267 {
268  return iomanX_ioctl2(fd, HIOCNSUB, NULL, 0, NULL, 0);
269 }
270 
271 static u32 pfsHddGetPartSize(int fd, u32 sub/*0=main 1+=subs*/)
272 { // of a partition
273  return iomanX_ioctl2(fd, HIOCGETSIZE, &sub, 0, NULL, 0);
274 }
275 
276 static void pfsHddSetPartError(int fd)
277 {
278  iomanX_ioctl2(fd, HIOCSETPARTERROR, NULL, 0, NULL, 0);
279 }
280 
281 static int pfsHddFlushCache(int fd)
282 {
283  return iomanX_ioctl2(fd,HIOCFLUSH, NULL, 0, NULL, 0);
284 }
iomanX.h
hddIoctl2Transfer_t
Definition: hdd-ioctl.h:79
sceCdCLOCK::year
u8 year
Definition: libcdvd-common.h:205
HIOCGETSIZE
#define HIOCGETSIZE
Definition: hdd-ioctl.h:65
thbase.h
sysclib.h
sceCdCLOCK
Definition: libcdvd-common.h:188
CpuSuspendIntr
int CpuSuspendIntr(int *state)
Definition: intrman.c:195
sceCdCLOCK::hour
u8 hour
Definition: libcdvd-common.h:197
pfs_super_block_t
Definition: libpfs.h:134
sceCdCLOCK::month
u8 month
Definition: libcdvd-common.h:203
HIOCTRANSFER
#define HIOCTRANSFER
Definition: hdd-ioctl.h:63
hdd-ioctl.h
pfs_datetime_t
Definition: libpfs.h:123
cdvdman.h
pfs_block_device_t
Definition: libpfs.h:169
ctype.h
hddIoctl2Transfer_t::mode
u32 mode
Definition: hdd-ioctl.h:87
HIOCSETPARTERROR
#define HIOCSETPARTERROR
Definition: hdd-ioctl.h:67
hddIoctl2Transfer_t::sub
u32 sub
Definition: hdd-ioctl.h:82
time.h
hddIoctl2Transfer_t::size
u32 size
Definition: hdd-ioctl.h:85
stdio.h
sceCdCLOCK::stat
u8 stat
Definition: libcdvd-common.h:191
CpuResumeIntr
int CpuResumeIntr(int state)
Definition: intrman.c:217
sceCdCLOCK::day
u8 day
Definition: libcdvd-common.h:201
sysmem.h
pfs_mount_t
Definition: libpfs.h:178
sceCdReadClock
int sceCdReadClock(sceCdCLOCK *clock)
Definition: cdvdman.c:7934
intrman.h
sceCdCLOCK::minute
u8 minute
Definition: libcdvd-common.h:195
stdlib.h
sceCdCLOCK::second
u8 second
Definition: libcdvd-common.h:193
errno.h