PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
mcdev.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright (c) 2009 jimmikaelkael
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include <mcman.h>
12#include "mcman-internal.h"
13
14// mc driver vars
15static int mcman_mc_port = 0;
16static int mcman_mc_slot = 0;
17static int mcman_io_sema = 0;
18
19// mc driver ops functions prototypes
20int mc_init(MC_IO_DEV_T *iop_dev);
21int mc_deinit(MC_IO_DEV_T *dev);
22#if MCMAN_ENABLE_EXTENDED_DEV_OPS
23int mc_open(MC_IO_FIL_T *f, const char *filename, int flags, int mode);
24#else
25int mc_open(MC_IO_FIL_T *f, const char *filename, int flags);
26#endif
27int mc_close(MC_IO_FIL_T *f);
28int mc_lseek(MC_IO_FIL_T *f, int pos, int where);
29int mc_read(MC_IO_FIL_T *f, void *buf, int size);
30int mc_write(MC_IO_FIL_T *f, void *buf, int size);
31#if MCMAN_ENABLE_EXTENDED_DEV_OPS
32int mc_format(MC_IO_FIL_T *f, const char *dev, const char *blockdev, void *arg, int arglen);
33#else
34int mc_format(MC_IO_FIL_T *f);
35#endif
36int mc_remove(MC_IO_FIL_T *f, const char *filename);
37#if MCMAN_ENABLE_EXTENDED_DEV_OPS
38int mc_mkdir(MC_IO_FIL_T *f, const char *dirname, int mode);
39#else
40int mc_mkdir(MC_IO_FIL_T *f, const char *dirname);
41#endif
42int mc_rmdir(MC_IO_FIL_T *f, const char *dirname);
43int mc_dopen(MC_IO_FIL_T *f, const char *dirname);
44int mc_dclose(MC_IO_FIL_T *f);
45int mc_dread(MC_IO_FIL_T *f, MC_IO_DRE_T *dirent);
46int mc_getstat(MC_IO_FIL_T *f, const char *filename, MC_IO_STA_T *stat);
47int mc_chstat(MC_IO_FIL_T *f, const char *filename, MC_IO_STA_T *stat, unsigned int statmask);
48int mc_ioctl(MC_IO_FIL_T *f, int cmd, void* param);
49
50#if MCMAN_ENABLE_EXTENDED_DEV_OPS
51int mc_rename(MC_IO_FIL_T *f, const char *old, const char *new);
52int mc_chdir(MC_IO_FIL_T *f, const char *name);
53int mc_sync(MC_IO_FIL_T *f, const char *dev, int flag);
54int mc_mount(MC_IO_FIL_T *f, const char *fsname, const char *devname, int flag, void *arg, int arglen);
55int mc_umount(MC_IO_FIL_T *f, const char *fsname);
56s64 mc_lseek64(MC_IO_FIL_T *f, s64 pos, int where);
57int mc_devctl(MC_IO_FIL_T *f, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
58int mc_symlink(MC_IO_FIL_T *f, const char *old, const char *new);
59int mc_readlink(MC_IO_FIL_T *f, const char *path, char *buf, unsigned int buflen);
60int mc_ioctl2(MC_IO_FIL_T *f, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
61#endif
62
63// driver ops func tab
64static MC_IO_OPS_T mcman_mcops = {
65 &mc_init,
66 &mc_deinit,
67 &mc_format,
68 &mc_open,
69 &mc_close,
70 &mc_read,
71 &mc_write,
72 &mc_lseek,
73 &mc_ioctl,
74 &mc_remove,
75 &mc_mkdir,
76 &mc_rmdir,
77 &mc_dopen,
78 &mc_dclose,
79 &mc_dread,
80 &mc_getstat,
81 &mc_chstat,
82#if MCMAN_ENABLE_EXTENDED_DEV_OPS
83 &mc_rename,
84 &mc_chdir,
85 &mc_sync,
86 &mc_mount,
87 &mc_umount,
88 &mc_lseek64,
89 &mc_devctl,
90 &mc_symlink,
91 &mc_readlink,
92 &mc_ioctl2,
93#endif
94};
95
96// driver descriptor
97static MC_IO_DEV_T mcman_mcdev = {
98#if !defined(BUILDING_XFROMMAN) && !defined(BUILDING_VMCMAN)
99 "mc",
100#elif defined(BUILDING_VMCMAN)
101 "vmc",
102#elif defined(BUILDING_XFROMMAN)
103 "xfrom",
104#endif
105 IOP_DT_FS
106#if MCMAN_ENABLE_EXTENDED_DEV_OPS
108#endif
109 ,
110 1,
111#if !defined(BUILDING_XFROMMAN) && !defined(BUILDING_VMCMAN)
112 "Memory Card",
113#elif defined(BUILDING_VMCMAN)
114 "Virtual Memory Card",
115#elif defined(BUILDING_XFROMMAN)
116 "External flash rom",
117#endif
118 &mcman_mcops,
119};
120
121//--------------------------------------------------------------
122int mc_init(MC_IO_DEV_T *dev)
123{
124 (void)dev;
125
126 return 0;
127}
128
129//--------------------------------------------------------------
130int mcman_ioerrcode(int errcode)
131{
132 register int r = errcode;
133
134 if (r < 0) {
135 switch (r + 8) {
136 case 0:
137 r = -EIO;
138 break;
139 case 1:
140 r = -EMFILE;
141 break;
142 case 2:
143 r = -EEXIST;
144 break;
145 case 3:
146 r = -EACCES;
147 break;
148 case 4:
149 r = -ENOENT;
150 break;
151 case 5:
152 r = -ENOSPC;
153 break;
154 case 6:
155 r = -EFORMAT;
156 break;
157 default:
158 r = -ENXIO;
159 break;
160 }
161 }
162 return r;
163}
164
165//--------------------------------------------------------------
166int mcman_modloadcb(const char *filename, int *port, int *slot)
167{
168 register const char *path = filename;
169 register int upos;
170
171 if (*path == 0x20) {
172 path++;
173 while (*path == 0x20)
174 path++;
175 }
176
177 if (((u8)path[0] | 0x20) != mcman_mcdev.name[0])
178 return 0;
179 if (((u8)path[1] | 0x20) != mcman_mcdev.name[1])
180 return 0;
181
182 if ((u32)strlen(path) < 2) return 2;
183
184 upos = mcman_chrpos(path, ':');
185
186 if (upos < 0)
187 upos = strlen(path);
188
189 if (port) {
190 upos --;
191 if (((u8)path[upos] - 0x30) < 10)
192 *port = (u8)path[upos] - 0x30;
193 else *port = 0;
194 }
195
196 upos--;
197 if (port) {
198 *port += 2;
199 }
200
201 if (slot) {
202 register int m, v;
203
204 *slot = 0;
205 for (m = 1; ((u8)path[upos --] - 0x30) < 10; m = v << 1) {
206 v = m << 2;
207 *slot += m * (path[upos] - 0x30);
208 v += m;
209 }
210 }
211
212 return 1;
213}
214
215//--------------------------------------------------------------
216void mcman_unit2card(u32 unit)
217{
218#if !defined(BUILDING_XFROMMAN) && !defined(BUILDING_VMCMAN)
219 mcman_mc_port = unit & 1;
220 mcman_mc_slot = (unit >> 1) & (MCMAN_MAXSLOT - 1);
221#elif defined(BUILDING_VMCMAN)
222 mcman_mc_port = 0;
223 mcman_mc_slot = unit & (MCMAN_MAXSLOT - 1);
224#elif defined(BUILDING_XFROMMAN)
225 (void)unit;
226 mcman_mc_port = 0;
227 mcman_mc_slot = 0;
228#endif
229
230 // original mcman/xmcman code below is silly and I doubt it
231 // can support more than 2 units anyway...
232 /*
233 register u32 mask = 0xF0000000;
234
235 while (!(unit & mask)) {
236 mask >>= 4;
237 if (mask < 0x10)
238 break;
239 }
240
241 mcman_mc_port = unit & 0xf;
242 mcman_mc_slot = 0;
243
244 if (mask < 0xf) {
245 while (mask) {
246 mcman_mc_slot = ((u32)(unit & mask)) / ((u32)(mask & (mask >> 0x3))) \
247 + (((mcman_mc_slot << 2) + mcman_mc_slot) << 1);
248 mask >>= 4;
249 }
250 }
251 */
252}
253
254//--------------------------------------------------------------
255int mcman_initdev(void)
256{
257 iop_sema_t smp;
258
259#if !defined(BUILDING_XFROMMAN) && !defined(BUILDING_VMCMAN)
260 SetCheckKelfPathCallback(mcman_modloadcb);
261#endif
262
263#if MCMAN_ENABLE_EXTENDED_DEV_OPS
264 iomanX_DelDrv(mcman_mcdev.name);
265 if (iomanX_AddDrv(&mcman_mcdev)) {
266 McCloseAll();
267 return 1;
268 }
269#else
270 DelDrv(mcman_mcdev.name);
271 if (AddDrv(&mcman_mcdev)) {
272 McCloseAll();
273 return 1;
274 }
275#endif
276
277 smp.attr = 1;
278 smp.initial = 1;
279 smp.max = 1;
280 smp.option = 0;
281 mcman_io_sema = CreateSema(&smp);
282
283 return 0;
284}
285
286//--------------------------------------------------------------
287void mcman_deinitdev(void)
288{
289 WaitSema(mcman_io_sema);
290#if MCMAN_ENABLE_EXTENDED_DEV_OPS
291 iomanX_DelDrv(mcman_mcdev.name);
292#else
293 DelDrv(mcman_mcdev.name);
294#endif
295}
296
297//--------------------------------------------------------------
298int mc_deinit(MC_IO_DEV_T *dev)
299{
300 (void)dev;
301
302 McCloseAll();
303 DeleteSema(mcman_io_sema);
304
305 return 0;
306}
307
308//--------------------------------------------------------------
309#if MCMAN_ENABLE_EXTENDED_DEV_OPS
310int mc_open(MC_IO_FIL_T *f, const char *filename, int flags, int mode)
311#else
312int mc_open(MC_IO_FIL_T *f, const char *filename, int flags)
313#endif
314{
315 register int r;
316
317 WaitSema(mcman_io_sema);
318 mcman_unit2card(f->unit);
319
320 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
321 if (r >= -1) {
322 r = McOpen(mcman_mc_port, mcman_mc_slot, filename, flags);
323 if (r >= 0)
324 f->privdata = (void*)(uiptr)(int)r;
325 }
326 SignalSema(mcman_io_sema);
327
328 return mcman_ioerrcode(r);
329}
330
331//--------------------------------------------------------------
332int mc_close(MC_IO_FIL_T *f)
333{
334 register int r;
335
336 WaitSema(mcman_io_sema);
337 r = McClose((int)(uiptr)f->privdata);
338 SignalSema(mcman_io_sema);
339
340 return mcman_ioerrcode(r);
341}
342
343//--------------------------------------------------------------
344int mc_lseek(MC_IO_FIL_T *f, int pos, int where)
345{
346 register int r;
347
348 WaitSema(mcman_io_sema);
349 r = McSeek((int)(uiptr)f->privdata, pos, where);
350 SignalSema(mcman_io_sema);
351
352 return mcman_ioerrcode(r);
353}
354
355//--------------------------------------------------------------
356int mc_read(MC_IO_FIL_T *f, void *buf, int size)
357{
358 register int r;
359
360 WaitSema(mcman_io_sema);
361 r = McRead((int)(uiptr)f->privdata, buf, size);
362 SignalSema(mcman_io_sema);
363
364 return mcman_ioerrcode(r);
365}
366
367//--------------------------------------------------------------
368int mc_write(MC_IO_FIL_T *f, void *buf, int size)
369{
370 register int r;
371
372 WaitSema(mcman_io_sema);
373 r = McWrite((int)(uiptr)f->privdata, buf, size);
374 SignalSema(mcman_io_sema);
375
376 return mcman_ioerrcode(r);
377}
378
379//--------------------------------------------------------------
380#if MCMAN_ENABLE_EXTENDED_DEV_OPS
381int mc_format(MC_IO_FIL_T *f, const char *dev, const char *blockdev, void *arg, int arglen)
382#else
383int mc_format(MC_IO_FIL_T *f)
384#endif
385{
386 register int r;
387
388#if MCMAN_ENABLE_EXTENDED_DEV_OPS
389 (void)dev;
390 (void)blockdev;
391 (void)arg;
392 (void)arglen;
393#endif
394
395 WaitSema(mcman_io_sema);
396 mcman_unit2card(f->unit);
397
398 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
399 if (r >= -2) {
400 r = McFormat(mcman_mc_port, mcman_mc_slot);
401 }
402 SignalSema(mcman_io_sema);
403
404 return mcman_ioerrcode(r);
405}
406
407//--------------------------------------------------------------
408int mc_remove(MC_IO_FIL_T *f, const char *filename)
409{
410 register int r;
411
412 WaitSema(mcman_io_sema);
413 mcman_unit2card(f->unit);
414
415 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
416 if (r >= -1) {
417 r = McDelete(mcman_mc_port, mcman_mc_slot, filename, 0);
418 }
419 SignalSema(mcman_io_sema);
420
421 return mcman_ioerrcode(r);
422}
423
424//--------------------------------------------------------------
425#if MCMAN_ENABLE_EXTENDED_DEV_OPS
426int mc_mkdir(MC_IO_FIL_T *f, const char *dirname, int mode)
427#else
428int mc_mkdir(MC_IO_FIL_T *f, const char *dirname)
429#endif
430{
431 register int r;
432
433#if MCMAN_ENABLE_EXTENDED_DEV_OPS
434 (void)mode;
435#endif
436
437 WaitSema(mcman_io_sema);
438 mcman_unit2card(f->unit);
439
440 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
441 if (r >= -1) {
442 r = McOpen(mcman_mc_port, mcman_mc_slot, dirname, 0x40);
443 }
444 SignalSema(mcman_io_sema);
445
446 return mcman_ioerrcode(r);
447}
448
449//--------------------------------------------------------------
450int mc_rmdir(MC_IO_FIL_T *f, const char *dirname)
451{
452 register int r;
453
454 WaitSema(mcman_io_sema);
455 mcman_unit2card(f->unit);
456
457 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
458 if (r >= -1) {
459 r = McDelete(mcman_mc_port, mcman_mc_slot, dirname, 0);
460 }
461 SignalSema(mcman_io_sema);
462
463 return mcman_ioerrcode(r);
464}
465
466//--------------------------------------------------------------
467int mc_dopen(MC_IO_FIL_T *f, const char *dirname)
468{
469 register int r;
470
471 WaitSema(mcman_io_sema);
472 mcman_unit2card(f->unit);
473
474 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
475 if (r >= -1) {
476 r = McOpen(mcman_mc_port, mcman_mc_slot, dirname, 0);
477 if (r >= 0)
478 f->privdata = (void*)(uiptr)(int)r;
479 }
480
481 SignalSema(mcman_io_sema);
482
483 return mcman_ioerrcode(r);
484}
485
486//--------------------------------------------------------------
487int mc_dclose(MC_IO_FIL_T *f)
488{
489 register int r;
490
491 WaitSema(mcman_io_sema);
492 r = McClose((int)(uiptr)f->privdata);
493 SignalSema(mcman_io_sema);
494
495 return mcman_ioerrcode(r);
496}
497
498//--------------------------------------------------------------
499int mc_dread(MC_IO_FIL_T *f, MC_IO_DRE_T *dirent)
500{
501 register int r;
502
503 WaitSema(mcman_io_sema);
504 r = mcman_dread((int)(uiptr)f->privdata, dirent);
505 SignalSema(mcman_io_sema);
506
507 return mcman_ioerrcode(r);
508}
509
510//--------------------------------------------------------------
511int mc_getstat(MC_IO_FIL_T *f, const char *filename, MC_IO_STA_T *stat)
512{
513 register int r;
514
515 WaitSema(mcman_io_sema);
516 mcman_unit2card(f->unit);
517
518 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
519 if (r >= -1) {
520 r = mcman_getstat(mcman_mc_port, mcman_mc_slot, filename, stat);
521 }
522
523 SignalSema(mcman_io_sema);
524
525 return mcman_ioerrcode(r);
526}
527
528//--------------------------------------------------------------
529int mc_chstat(MC_IO_FIL_T *f, const char *filename, MC_IO_STA_T *stat, unsigned int statmask)
530{
531 register int r;
532 sceMcTblGetDir mctbl;
533
534 WaitSema(mcman_io_sema);
535 mcman_unit2card(f->unit);
536
537 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
538 if (r >= -1) {
539 register int flags;
540
541 flags = 0x000;
542
543 if (statmask & MC_IO_CST_ATTR) {
544 flags |= 0x008;
545 mctbl.Reserve2 = stat->attr;
546 }
547
548 if (statmask & MC_IO_CST_MODE) {
549 flags |= 0x200;
550 mctbl.AttrFile = 0;
551 if (stat->mode & MC_IO_S_RD) mctbl.AttrFile |= sceMcFileAttrReadable;
552 if (stat->mode & MC_IO_S_WR) mctbl.AttrFile |= sceMcFileAttrWriteable;
553 if (stat->mode & MC_IO_S_EX) mctbl.AttrFile |= sceMcFileAttrExecutable;
554#if !MCMAN_ENABLE_EXTENDED_DEV_OPS
555 if (stat->mode & SCE_STM_C) mctbl.AttrFile |= sceMcFileAttrDupProhibit;
556 if (stat->mode & sceMcFileAttrPS1) mctbl.AttrFile |= sceMcFileAttrPS1;
557 if (stat->mode & sceMcFileAttrPDAExec) mctbl.AttrFile |= sceMcFileAttrPDAExec;
558#endif
559 }
560
561 if (statmask & MC_IO_CST_CT) {
562 flags |= 0x001;
563 memcpy(&mctbl._Create, stat->ctime, sizeof(sceMcStDateTime));
564 }
565
566 if (statmask & MC_IO_CST_MT) {
567 flags |= 0x002;
568 memcpy(&mctbl._Modify, stat->mtime, sizeof(sceMcStDateTime));
569 }
570
571 r = McSetFileInfo(mcman_mc_port, mcman_mc_slot, filename, &mctbl, flags);
572 }
573 SignalSema(mcman_io_sema);
574
575 return mcman_ioerrcode(r);
576}
577
578//--------------------------------------------------------------
579int mc_ioctl(MC_IO_FIL_T *f, int cmd, void* param)
580{
581 (void)f;
582 (void)cmd;
583 (void)param;
584
585 WaitSema(mcman_io_sema);
586 SignalSema(mcman_io_sema);
587 return 0;
588}
589
590#if MCMAN_ENABLE_EXTENDED_DEV_OPS
591//--------------------------------------------------------------
592int mc_rename(MC_IO_FIL_T *f, const char *old, const char *new)
593{
594 (void)f;
595 (void)old;
596 (void)new;
597
598 register int r;
599 sceMcTblGetDir mctbl;
600
601 WaitSema(mcman_io_sema);
602 mcman_unit2card(f->unit);
603
604 r = McDetectCard2(mcman_mc_port, mcman_mc_slot);
605 if (r >= -1) {
606 int l;
607
608 l = strlen(new);
609 if (l < 32) {
610 memcpy((void *)mctbl.EntryName, new, l);
611 mctbl.EntryName[l] = 0;
612 r = McSetFileInfo(mcman_mc_port, mcman_mc_slot, old, &mctbl, sceMcFileAttrFile);
613 r = mcman_ioerrcode(r);
614 }
615 else {
616 r = -ENAMETOOLONG;
617 }
618 }
619 else {
620 r = mcman_ioerrcode(r);
621 }
622 SignalSema(mcman_io_sema);
623
624 return r;
625}
626
627//--------------------------------------------------------------
628int mc_chdir(MC_IO_FIL_T *f, const char *name)
629{
630 (void)f;
631 (void)name;
632
633 WaitSema(mcman_io_sema);
634 SignalSema(mcman_io_sema);
635 return 0;
636}
637
638//--------------------------------------------------------------
639int mc_sync(MC_IO_FIL_T *f, const char *dev, int flag)
640{
641 (void)f;
642 (void)dev;
643 (void)flag;
644
645 WaitSema(mcman_io_sema);
646 SignalSema(mcman_io_sema);
647 return 0;
648}
649
650//--------------------------------------------------------------
651int mc_mount(MC_IO_FIL_T *f, const char *fsname, const char *devname, int flag, void *arg, int arglen)
652{
653 int r;
654
655 (void)fsname;
656 (void)flag;
657 (void)arg;
658 (void)arglen;
659
660 WaitSema(mcman_io_sema);
661 mcman_unit2card(f->unit);
662#if defined(BUILDING_VMCMAN)
663 r = mcman_iomanx_backing_mount(mcman_mc_port, mcman_mc_slot, devname);
664#else
665 r = 0;
666#endif
667 SignalSema(mcman_io_sema);
668 return r;
669}
670
671//--------------------------------------------------------------
672int mc_umount(MC_IO_FIL_T *f, const char *fsname)
673{
674 int r;
675
676 (void)fsname;
677
678 WaitSema(mcman_io_sema);
679 mcman_unit2card(f->unit);
680#if defined(BUILDING_VMCMAN)
681 r = mcman_iomanx_backing_umount(mcman_mc_port, mcman_mc_slot);
682#else
683 r = 0;
684#endif
685 SignalSema(mcman_io_sema);
686 return r;
687}
688
689//--------------------------------------------------------------
690s64 mc_lseek64(MC_IO_FIL_T *f, s64 pos, int where)
691{
692 return mc_lseek(f, pos, where);
693}
694
695//--------------------------------------------------------------
696int mc_devctl(MC_IO_FIL_T *f, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen)
697{
698 (void)f;
699 (void)name;
700 (void)cmd;
701 (void)arg;
702 (void)arglen;
703 (void)buf;
704 (void)buflen;
705
706 WaitSema(mcman_io_sema);
707 SignalSema(mcman_io_sema);
708 return 0;
709}
710
711//--------------------------------------------------------------
712int mc_symlink(MC_IO_FIL_T *f, const char *old, const char *new)
713{
714 (void)f;
715 (void)old;
716 (void)new;
717
718 WaitSema(mcman_io_sema);
719 SignalSema(mcman_io_sema);
720 return 0;
721}
722
723//--------------------------------------------------------------
724int mc_readlink(MC_IO_FIL_T *f, const char *path, char *buf, unsigned int buflen)
725{
726 (void)f;
727 (void)path;
728 (void)buf;
729 (void)buflen;
730
731 WaitSema(mcman_io_sema);
732 SignalSema(mcman_io_sema);
733 return 0;
734}
735
736//--------------------------------------------------------------
737int mc_ioctl2(MC_IO_FIL_T *f, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen)
738{
739 (void)f;
740 (void)cmd;
741 (void)arg;
742 (void)arglen;
743 (void)buf;
744 (void)buflen;
745
746 WaitSema(mcman_io_sema);
747 SignalSema(mcman_io_sema);
748 return 0;
749}
750#endif
#define ENOENT
Definition errno.h:23
#define ENOSPC
Definition errno.h:75
#define EEXIST
Definition errno.h:53
#define ENXIO
Definition errno.h:31
#define ENAMETOOLONG
Definition errno.h:191
#define EMFILE
Definition errno.h:67
#define EIO
Definition errno.h:29
#define EFORMAT
Definition errno.h:115
#define EACCES
Definition errno.h:45
#define IOP_DT_FSEXT
Definition iomanX.h:66