Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader/simon.git] / modules / vmc / mcman / mcdev.c
blob0bab2ca4ba79091e52378bde7392653576c1e4a9
1 /*
2 Copyright 2009-2010, jimmikaelkael
3 Licenced under Academic Free License version 3.0
4 Review Open PS2 Loader README & LICENSE files for further details.
5 */
7 #include "mcman.h"
9 // mc driver vars
10 static int mcman_mc_port = 0;
11 static int mcman_mc_slot = 0;
12 static int mcman_io_sema = 0;
14 // mc driver ops functions prototypes
15 int mc_init(iop_device_t *iop_dev);
16 int mc_deinit(iop_device_t *dev);
17 int mc_open(iop_file_t *f, char *filename, int mode, int flags);
18 int mc_close(iop_file_t *f);
19 int mc_lseek(iop_file_t *f, int pos, int where);
20 int mc_read(iop_file_t *f, void *buf, int size);
21 int mc_write(iop_file_t *f, void *buf, int size);
22 int mc_format(iop_file_t *f, char *a1, char *a2, void *a3, int a4);
23 int mc_remove(iop_file_t *f, char *filename);
24 int mc_mkdir(iop_file_t *f, char *dirname);
25 int mc_rmdir(iop_file_t *f, char *dirname);
26 int mc_dopen(iop_file_t *f, char *dirname);
27 int mc_dclose(iop_file_t *f);
28 int mc_dread(iop_file_t *f, fio_dirent_t *dirent);
29 int mc_getstat(iop_file_t *f, char *filename, fio_stat_t *stat);
30 int mc_chstat(iop_file_t *f, char *filename, fio_stat_t *stat, u32 statmask);
31 int mc_ioctl(iop_file_t *f, int a1, void* a2);
33 // driver ops func tab
34 void *mcman_mcops[17] = {
35 (void*)mc_init,
36 (void*)mc_deinit,
37 (void*)mc_format,
38 (void*)mc_open,
39 (void*)mc_close,
40 (void*)mc_read,
41 (void*)mc_write,
42 (void*)mc_lseek,
43 (void*)mc_ioctl,
44 (void*)mc_remove,
45 (void*)mc_mkdir,
46 (void*)mc_rmdir,
47 (void*)mc_dopen,
48 (void*)mc_dclose,
49 (void*)mc_dread,
50 (void*)mc_getstat,
51 (void*)mc_chstat
54 // driver descriptor
55 static iop_device_t mcman_mcdev = {
56 "mc",
57 IOP_DT_FS,
59 "Memory Card",
60 (struct _iop_device_ops *)&mcman_mcops
63 //--------------------------------------------------------------
64 int mc_init(iop_device_t *dev)
66 return 0;
69 //--------------------------------------------------------------
70 int mcman_ioerrcode(int errcode)
72 register int r = errcode;
74 if (r < 0) {
75 switch (r + 8) {
76 case 0:
77 r = -EIO;
78 break;
79 case 1:
80 r = -EMFILE;
81 break;
82 case 2:
83 r = -EEXIST;
84 break;
85 case 3:
86 r = -EACCES;
87 break;
88 case 4:
89 r = -ENOENT;
90 break;
91 case 5:
92 r = -ENOSPC;
93 break;
94 case 6:
95 r = -EFORMAT;
96 break;
97 default:
98 r = -ENXIO;
99 break;
102 return r;
105 //--------------------------------------------------------------
106 int mcman_modloadcb(char *filename, int *unit, u8 *arg3)
108 register char *path = filename;
109 register int upos;
111 if (*path == 0x20) {
112 path++;
113 while (*path == 0x20)
114 path++;
117 if (((u8)path[0] | 0x20) != mcman_mcdev.name[0])
118 return 0;
119 if (((u8)path[1] | 0x20) != mcman_mcdev.name[1])
120 return 0;
122 if ((u32)strlen(path) < 2) return 2;
124 upos = mcman_chrpos(path, ':');
126 if (upos < 0)
127 upos = strlen(path);
129 if (unit) {
130 upos --;
131 if (((u8)path[upos] - 0x30) < 10)
132 *unit = (u8)path[upos] - 0x30;
133 else *unit = 0;
136 upos--;
137 *unit += 2;
139 if (arg3) {
140 register int m, v;
142 *arg3 = 0;
143 for (m = 1; ((u8)path[upos --] - 0x30) < 10; m = v << 1) {
144 v = m << 2;
145 *arg3 += m * (path[upos] - 0x30);
146 v += m;
150 return 1;
153 //--------------------------------------------------------------
154 void mcman_unit2card(u32 unit)
156 mcman_mc_port = unit & 1;
157 mcman_mc_slot = (unit >> 1) & (MCMAN_MAXSLOT - 1);
159 // original mcman/xmcman code below is silly and I doubt it
160 // can support more than 2 units anyway...
162 register u32 mask = 0xF0000000;
164 while (!(unit & mask)) {
165 mask >>= 4;
166 if (mask < 0x10)
167 break;
170 mcman_mc_port = unit & 0xf;
171 mcman_mc_slot = 0;
173 if (mask < 0xf) {
174 while (mask) {
175 mcman_mc_slot = ((u32)(unit & mask)) / ((u32)(mask & (mask >> 0x3))) \
176 + (((mcman_mc_slot << 2) + mcman_mc_slot) << 1);
177 mask >>= 4;
183 //--------------------------------------------------------------
184 int mcman_initdev(void)
186 iop_sema_t smp;
188 SetCheckKelfPathCallback(mcman_modloadcb);
190 DelDrv(mcman_mcdev.name);
191 if (AddDrv(&mcman_mcdev)) {
192 McCloseAll();
193 return 1;
196 smp.attr = 1;
197 smp.initial = 1;
198 smp.max = 1;
199 smp.option = 0;
200 mcman_io_sema = CreateSema(&smp);
202 return 0;
205 //--------------------------------------------------------------
206 int mc_deinit(iop_device_t *dev)
208 DeleteSema(mcman_io_sema);
209 McCloseAll();
211 return 0;
214 //--------------------------------------------------------------
215 int mc_open(iop_file_t *f, char *filename, int mode, int flags)
217 register int r;
219 WaitSema(mcman_io_sema);
220 mcman_unit2card(f->unit);
222 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
223 if (r >= -1) {
224 r = McOpen(mcman_mc_port, mcman_mc_slot, filename, mode);
225 if (r >= 0)
226 f->privdata = (void*)r;
228 SignalSema(mcman_io_sema);
230 return mcman_ioerrcode(r);
233 //--------------------------------------------------------------
234 int mc_close(iop_file_t *f)
236 register int r;
238 WaitSema(mcman_io_sema);
239 r = McClose((int)f->privdata);
240 SignalSema(mcman_io_sema);
242 return mcman_ioerrcode(r);
245 //--------------------------------------------------------------
246 int mc_lseek(iop_file_t *f, int pos, int where)
248 register int r;
250 WaitSema(mcman_io_sema);
251 r = McSeek((int)f->privdata, pos, where);
252 SignalSema(mcman_io_sema);
254 return mcman_ioerrcode(r);
257 //--------------------------------------------------------------
258 int mc_read(iop_file_t *f, void *buf, int size)
260 register int r;
262 WaitSema(mcman_io_sema);
263 r = McRead((int)f->privdata, buf, size);
264 SignalSema(mcman_io_sema);
266 return mcman_ioerrcode(r);
269 //--------------------------------------------------------------
270 int mc_write(iop_file_t *f, void *buf, int size)
272 register int r;
274 WaitSema(mcman_io_sema);
275 r = McWrite((int)f->privdata, buf, size);
276 SignalSema(mcman_io_sema);
278 return mcman_ioerrcode(r);
281 //--------------------------------------------------------------
282 int mc_format(iop_file_t *f, char *a1, char *a2, void *a3, int a4)
284 register int r;
286 WaitSema(mcman_io_sema);
287 mcman_unit2card(f->unit);
289 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
290 if (r >= -2) {
291 r = McFormat(mcman_mc_port, mcman_mc_slot);
293 SignalSema(mcman_io_sema);
295 return mcman_ioerrcode(r);
298 //--------------------------------------------------------------
299 int mc_remove(iop_file_t *f, char *filename)
301 register int r;
303 WaitSema(mcman_io_sema);
304 mcman_unit2card(f->unit);
306 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
307 if (r >= -1) {
308 r = McDelete(mcman_mc_port, mcman_mc_slot, filename, 0);
310 SignalSema(mcman_io_sema);
312 return mcman_ioerrcode(r);
315 //--------------------------------------------------------------
316 int mc_mkdir(iop_file_t *f, char *dirname)
318 register int r;
320 WaitSema(mcman_io_sema);
321 mcman_unit2card(f->unit);
323 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
324 if (r >= -1) {
325 r = McOpen(mcman_mc_port, mcman_mc_slot, dirname, 0x40);
327 SignalSema(mcman_io_sema);
329 return mcman_ioerrcode(r);
332 //--------------------------------------------------------------
333 int mc_rmdir(iop_file_t *f, char *dirname)
335 register int r;
337 WaitSema(mcman_io_sema);
338 mcman_unit2card(f->unit);
340 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
341 if (r >= -1) {
342 r = McDelete(mcman_mc_port, mcman_mc_slot, dirname, 0);
344 SignalSema(mcman_io_sema);
346 return mcman_ioerrcode(r);
349 //--------------------------------------------------------------
350 int mc_dopen(iop_file_t *f, char *dirname)
352 register int r;
354 WaitSema(mcman_io_sema);
355 mcman_unit2card(f->unit);
357 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
358 if (r >= -1) {
359 r = McOpen(mcman_mc_port, mcman_mc_slot, dirname, 0);
360 if (r >= 0)
361 f->privdata = (void*)r;
364 SignalSema(mcman_io_sema);
366 return mcman_ioerrcode(r);
369 //--------------------------------------------------------------
370 int mc_dclose(iop_file_t *f)
372 register int r;
374 WaitSema(mcman_io_sema);
375 r = McClose((int)f->privdata);
376 SignalSema(mcman_io_sema);
378 return mcman_ioerrcode(r);
381 //--------------------------------------------------------------
382 int mc_dread(iop_file_t *f, fio_dirent_t *dirent)
384 register int r;
386 WaitSema(mcman_io_sema);
387 r = mcman_dread((int)f->privdata, dirent);
388 SignalSema(mcman_io_sema);
390 return mcman_ioerrcode(r);
393 //--------------------------------------------------------------
394 int mc_getstat(iop_file_t *f, char *filename, fio_stat_t *stat)
396 register int r;
398 WaitSema(mcman_io_sema);
399 mcman_unit2card(f->unit);
401 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
402 if (r >= -1) {
403 r = mcman_getstat(mcman_mc_port, mcman_mc_slot, filename, stat);
406 SignalSema(mcman_io_sema);
408 return mcman_ioerrcode(r);
411 //--------------------------------------------------------------
412 int mc_chstat(iop_file_t *f, char *filename, fio_stat_t *stat, u32 statmask)
414 register int r, flags;
415 sceMcTblGetDir mctbl;
417 WaitSema(mcman_io_sema);
418 mcman_unit2card(f->unit);
420 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
421 if (r >= -1) {
422 if (statmask & SCE_CST_ATTR) {
423 flags = 0x008;
424 mctbl.Reserve2 = stat->attr;
426 else flags = 0x000;
428 if (statmask & SCE_CST_MODE) {
429 flags |= 0x200;
430 if (stat->mode & SCE_STM_R) mctbl.AttrFile |= sceMcFileAttrReadable;
431 else mctbl.AttrFile &= (unsigned short)~sceMcFileAttrReadable;
433 if (stat->mode & SCE_STM_W) mctbl.AttrFile |= sceMcFileAttrWriteable;
434 else mctbl.AttrFile &= (unsigned short)~sceMcFileAttrWriteable;
436 if (stat->mode & SCE_STM_X) mctbl.AttrFile |= sceMcFileAttrExecutable;
437 else mctbl.AttrFile &= (unsigned short)~sceMcFileAttrExecutable;
439 if (stat->mode & SCE_STM_C) mctbl.AttrFile |= sceMcFileAttrDupProhibit;
440 else mctbl.AttrFile &= (unsigned short)~sceMcFileAttrDupProhibit;
442 if (stat->mode & sceMcFileAttrPS1) mctbl.AttrFile |= sceMcFileAttrPS1;
443 else mctbl.AttrFile &= (unsigned short)~sceMcFileAttrPS1;
445 if (stat->mode & sceMcFileAttrPDAExec) mctbl.AttrFile |= sceMcFileAttrPDAExec;
446 else mctbl.AttrFile &= (unsigned short)~sceMcFileAttrPDAExec;
449 if (statmask & SCE_CST_CT) {
450 flags |= 0x001;
451 mctbl._Create = *((sceMcStDateTime*)&stat->ctime[0]);
454 if (statmask & SCE_CST_MT) {
455 flags |= 0x002;
456 mctbl._Modify = *((sceMcStDateTime*)&stat->mtime[0]);
459 r = McSetFileInfo(mcman_mc_port, mcman_mc_slot, filename, &mctbl, flags);
461 SignalSema(mcman_io_sema);
463 return mcman_ioerrcode(r);
466 //--------------------------------------------------------------
467 int mc_ioctl(iop_file_t *f, int a1, void* a2)
469 WaitSema(mcman_io_sema);
470 return 0;
473 //--------------------------------------------------------------