sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
fileXio_rpc.c
Go to the documentation of this file.
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
15
16#include <tamtypes.h>
17#include <kernel.h>
18#include <sifrpc.h>
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include <stdarg.h>
23#include <sys/fcntl.h>
24#include <sys/stat.h>
25#include <ps2sdkapi.h>
26#include <iopcontrol.h>
27
28#define NEWLIB_PORT_AWARE
29#include <fileXio_rpc.h>
30#include <errno.h>
31
32void _ps2sdk_fileXio_init();
33void _ps2sdk_fileXio_deinit();
34
35SifRpcClientData_t __cd0;
36
37unsigned int __sbuff[0x1300] __attribute__((aligned (64)));
38
39int __intr_data[0xC00] __attribute__((aligned(64)));
40
41int __fileXioBlockMode;
42
43int __fileXioCompletionSema;
44
45int __lock_sema_id;
46
47static inline void _fxio_intr(void)
48{
49 iSignalSema(__fileXioCompletionSema);
50}
51
52static inline int _lock(void)
53{
54 return(WaitSema(__lock_sema_id));
55}
56
57static inline int _unlock(void)
58{
59 return(SignalSema(__lock_sema_id));
60}
61
62int fileXioInit(void)
63{
64 int res;
65 ee_sema_t sp;
66
67 if (HasIopRebootedSinceLastCall())
68 fileXioExit();
69
70 if(__cd0.server)
71 {
72 return 0;
73 }
74
75 sp.init_count = 1;
76 sp.max_count = 1;
77 sp.option = 0;
78 __lock_sema_id = CreateSema(&sp);
79 if (__lock_sema_id < 0)
80 {
81 __lock_sema_id = 0;
82 return -1;
83 }
84
85 while(((res = sceSifBindRpc(&__cd0, FILEXIO_IRX, 0)) >= 0) && (__cd0.server == NULL))
86 nopdelay();
87
88 if(res < 0)
89 return res;
90
91 sp.init_count = 1;
92 sp.max_count = 1;
93 sp.option = 0;
94 __fileXioCompletionSema = CreateSema(&sp);
95 if (__fileXioCompletionSema < 0)
96 {
97 __fileXioCompletionSema = 0;
98 return -1;
99 }
100
101 __fileXioBlockMode = FXIO_WAIT;
102
103 _ps2sdk_fileXio_init();
104
105 return 0;
106}
107
108void fileXioExit(void)
109{
110 if(__cd0.server)
111 {
112 if (__lock_sema_id > 0)
113 {
114 DeleteSema(__lock_sema_id);
115 __lock_sema_id = 0;
116 }
117 if (__fileXioCompletionSema > 0)
118 {
119 DeleteSema(__fileXioCompletionSema);
120 __fileXioCompletionSema = 0;
121 }
122
123 memset(&__cd0, 0, sizeof(__cd0));
124
125 _ps2sdk_fileXio_deinit();
126 }
127}
128
129void fileXioStop(void)
130{
131 if(fileXioInit() < 0)
132 return;
133
134 sceSifCallRpc(&__cd0, FILEXIO_STOP, 0, __sbuff, 0, __sbuff, 0, 0, 0);
135
136 return;
137}
138
139int fileXioGetDeviceList(struct fileXioDevice deviceEntry[], unsigned int req_entries)
140{
141 int rv;
142 struct fxio_devlist_packet *packet=(struct fxio_devlist_packet*)__sbuff;
143
144 if(fileXioInit() < 0)
145 return -ENOPKG;
146
147 _lock();
148 WaitSema(__fileXioCompletionSema);
149
150 packet->deviceEntry = deviceEntry;
151 packet->reqEntries = req_entries;
152
153 // This will get the directory contents, and fill dirEntry via DMA
154 if((rv = sceSifCallRpc(&__cd0, FILEXIO_GETDEVICELIST, __fileXioBlockMode, __sbuff, sizeof(struct fxio_devlist_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
155 {
156 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
157 else { rv = __sbuff[0]; }
158 }
159 else
160 SignalSema(__fileXioCompletionSema);
161
162 _unlock();
163 return(rv);
164}
165
166int fileXioGetdir(const char* pathname, struct fileXioDirEntry dirEntry[], unsigned int req_entries)
167{
168 int rv;
169 struct fxio_getdir_packet *packet=(struct fxio_getdir_packet*)__sbuff;
170
171 if(fileXioInit() < 0)
172 return -ENOPKG;
173
174 _lock();
175 WaitSema(__fileXioCompletionSema);
176
177 // copy the requested pathname to the rpc buffer
178 strlcpy(packet->pathname, pathname, sizeof(packet->pathname));
179
180 sceSifWriteBackDCache(dirEntry, (sizeof(struct fileXioDirEntry) * req_entries));
181
182 packet->dirEntry = dirEntry;
183 packet->reqEntries = req_entries;
184
185 // This will get the directory contents, and fill dirEntry via DMA
186 if((rv = sceSifCallRpc(&__cd0, FILEXIO_GETDIR, __fileXioBlockMode, __sbuff, sizeof(struct fxio_getdir_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
187 {
188 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
189 else { rv = __sbuff[0]; }
190 }
191 else
192 SignalSema(__fileXioCompletionSema);
193
194 _unlock();
195 return(rv);
196}
197
198int fileXioMount(const char* mountpoint, const char* mountstring, int flag)
199{
200 int rv;
201 struct fxio_mount_packet *packet=(struct fxio_mount_packet*)__sbuff;
202
203 if(fileXioInit() < 0)
204 return -ENOPKG;
205
206 _lock();
207 WaitSema(__fileXioCompletionSema);
208
209 strlcpy(packet->blockdevice, mountstring, sizeof(packet->blockdevice));
210 strlcpy(packet->mountpoint, mountpoint, sizeof(packet->mountpoint));
211 packet->flags = flag;
212
213 if((rv = sceSifCallRpc(&__cd0, FILEXIO_MOUNT, __fileXioBlockMode, __sbuff, sizeof(struct fxio_mount_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
214 {
215 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
216 else { rv = __sbuff[0]; }
217 }
218 else
219 SignalSema(__fileXioCompletionSema);
220
221 _unlock();
222 return(rv);
223}
224
225int fileXioUmount(const char* mountpoint)
226{
227 int rv;
228 struct fxio_unmount_packet *packet=(struct fxio_unmount_packet*)__sbuff;
229
230 if(fileXioInit() < 0)
231 return -ENOPKG;
232
233 _lock();
234 WaitSema(__fileXioCompletionSema);
235
236 strlcpy(packet->mountpoint, mountpoint, sizeof(packet->mountpoint));
237
238 if((rv = sceSifCallRpc(&__cd0, FILEXIO_UMOUNT, __fileXioBlockMode, __sbuff, sizeof(struct fxio_unmount_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
239 {
240 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
241 else { rv = __sbuff[0]; }
242 }
243 else
244 SignalSema(__fileXioCompletionSema);
245
246 _unlock();
247 return(rv);
248}
249
250int fileXioCopyfile(const char* source, const char* dest, int mode)
251{
252 int rv;
253 struct fxio_copyfile_packet *packet=(struct fxio_copyfile_packet*)__sbuff;
254
255 if(fileXioInit() < 0)
256 return -ENOPKG;
257
258 _lock();
259 WaitSema(__fileXioCompletionSema);
260
261 strlcpy(packet->source, source, sizeof(packet->source));
262 strlcpy(packet->dest, dest, sizeof(packet->dest));
263 packet->mode = mode;
264
265 if((rv = sceSifCallRpc(&__cd0, FILEXIO_COPYFILE, __fileXioBlockMode, __sbuff, sizeof(struct fxio_copyfile_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
266 {
267 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
268 else { rv = __sbuff[0]; }
269 }
270 else
271 SignalSema(__fileXioCompletionSema);
272
273 _unlock();
274 return(rv);
275}
276
277int fileXioMkdir(const char* pathname, int mode)
278{
279 int rv;
280 struct fxio_mkdir_packet *packet=(struct fxio_mkdir_packet*)__sbuff;
281
282 if(fileXioInit() < 0)
283 return -ENOPKG;
284
285 _lock();
286 WaitSema(__fileXioCompletionSema);
287
288 strlcpy(packet->pathname, pathname, sizeof(packet->pathname));
289 packet->mode = mode;
290
291 if((rv = sceSifCallRpc(&__cd0, FILEXIO_MKDIR, __fileXioBlockMode, __sbuff, sizeof(struct fxio_mkdir_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
292 {
293 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
294 else { rv = __sbuff[0]; }
295 }
296 else
297 SignalSema(__fileXioCompletionSema);
298
299 _unlock();
300 return(rv);
301}
302
303int fileXioRmdir(const char* pathname)
304{
305 int rv;
306 struct fxio_pathsel_packet *packet=(struct fxio_pathsel_packet*)__sbuff;
307
308 if(fileXioInit() < 0)
309 return -ENOPKG;
310
311 _lock();
312 WaitSema(__fileXioCompletionSema);
313
314 strlcpy(packet->pathname, pathname, sizeof(packet->pathname));
315
316 if((rv = sceSifCallRpc(&__cd0, FILEXIO_RMDIR, __fileXioBlockMode, __sbuff, sizeof(struct fxio_pathsel_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
317 {
318 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
319 else { rv = __sbuff[0]; }
320 }
321 else
322 SignalSema(__fileXioCompletionSema);
323
324 _unlock();
325 return(rv);
326}
327
328int fileXioRemove(const char* pathname)
329{
330 int rv;
331 struct fxio_pathsel_packet *packet=(struct fxio_pathsel_packet*)__sbuff;
332
333 if(fileXioInit() < 0)
334 return -ENOPKG;
335
336 _lock();
337 WaitSema(__fileXioCompletionSema);
338
339 strlcpy(packet->pathname, pathname, sizeof(packet->pathname));
340
341 if((rv = sceSifCallRpc(&__cd0, FILEXIO_REMOVE, __fileXioBlockMode, __sbuff, sizeof(struct fxio_pathsel_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
342 {
343 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
344 else { rv = __sbuff[0]; }
345 }
346 else
347 SignalSema(__fileXioCompletionSema);
348
349 _unlock();
350 return(rv);
351}
352
353int fileXioRename(const char* source, const char* dest)
354{
355 int rv;
356 struct fxio_rename_packet *packet=(struct fxio_rename_packet*)__sbuff;
357
358 if(fileXioInit() < 0)
359 return -ENOPKG;
360
361 _lock();
362 WaitSema(__fileXioCompletionSema);
363
364 strlcpy(packet->source, source, sizeof(packet->source));
365 strlcpy(packet->dest, dest, sizeof(packet->dest));
366
367 if((rv = sceSifCallRpc(&__cd0, FILEXIO_RENAME, __fileXioBlockMode, __sbuff, sizeof(struct fxio_rename_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
368 {
369 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
370 else { rv = __sbuff[0]; }
371 }
372 else
373 SignalSema(__fileXioCompletionSema);
374
375 _unlock();
376 return(rv);
377}
378
379int fileXioSymlink(const char* source, const char* dest)
380{
381 int rv;
382 struct fxio_rename_packet *packet=(struct fxio_rename_packet*)__sbuff;
383
384 if(fileXioInit() < 0)
385 return -ENOPKG;
386
387 _lock();
388 WaitSema(__fileXioCompletionSema);
389
390 strlcpy(packet->source, source, sizeof(packet->source));
391 strlcpy(packet->dest, dest, sizeof(packet->dest));
392
393 if((rv = sceSifCallRpc(&__cd0, FILEXIO_SYMLINK, __fileXioBlockMode, __sbuff, sizeof(struct fxio_rename_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
394 {
395 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
396 else { rv = __sbuff[0]; }
397 }
398 else
399 SignalSema(__fileXioCompletionSema);
400
401 _unlock();
402 return(rv);
403}
404
405int fileXioReadlink(const char* source, char* buf, unsigned int buflen)
406{
407 int rv;
408 struct fxio_readlink_packet *packet=(struct fxio_readlink_packet*)__sbuff;
409
410 if(fileXioInit() < 0)
411 return -ENOPKG;
412
413 _lock();
414 WaitSema(__fileXioCompletionSema);
415
416 if( !IS_UNCACHED_SEG(buf))
417 sceSifWriteBackDCache(buf, buflen);
418
419 strlcpy(packet->source, source, sizeof(packet->source));
420 packet->buffer = buf;
421 packet->buflen = buflen;
422
423 if((rv = sceSifCallRpc(&__cd0, FILEXIO_READLINK, __fileXioBlockMode, __sbuff, sizeof(struct fxio_readlink_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
424 {
425 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
426 else { rv = __sbuff[0]; }
427 }
428 else
429 SignalSema(__fileXioCompletionSema);
430
431 _unlock();
432 return(rv);
433}
434
435int fileXioChdir(const char* pathname)
436{
437 int rv;
438 struct fxio_pathsel_packet *packet=(struct fxio_pathsel_packet*)__sbuff;
439
440 if(fileXioInit() < 0)
441 return -ENOPKG;
442
443 _lock();
444 WaitSema(__fileXioCompletionSema);
445
446 strlcpy(packet->pathname, pathname, sizeof(packet->pathname));
447
448 if((rv = sceSifCallRpc(&__cd0, FILEXIO_CHDIR, __fileXioBlockMode, __sbuff, sizeof(struct fxio_pathsel_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
449 {
450 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
451 else { rv = __sbuff[0]; }
452 }
453 else
454 SignalSema(__fileXioCompletionSema);
455
456 _unlock();
457 return(rv);
458}
459
460int fileXioOpen(const char* source, int flags, ...)
461{
462 int rv, mode;
463 struct fxio_open_packet *packet=(struct fxio_open_packet*)__sbuff;
464 va_list alist;
465
466 va_start(alist, flags);
467 mode = va_arg(alist, int); //Retrieve the mode argument, regardless of whether it is expected or not.
468 va_end(alist);
469
470 if(fileXioInit() < 0)
471 return -ENOPKG;
472
473 _lock();
474 WaitSema(__fileXioCompletionSema);
475
476 strlcpy(packet->pathname, source, sizeof(packet->pathname));
477 packet->flags = flags;
478 packet->mode = mode;
479 if((rv = sceSifCallRpc(&__cd0, FILEXIO_OPEN, __fileXioBlockMode, __sbuff, sizeof(struct fxio_open_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
480 {
481 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
482 else { rv = __sbuff[0]; }
483 }
484 else
485 SignalSema(__fileXioCompletionSema);
486
487 _unlock();
488 return(rv);
489}
490
491int fileXioClose(int fd)
492{
493 int rv;
494 struct fxio_close_packet *packet=(struct fxio_close_packet*)__sbuff;
495
496 if(fileXioInit() < 0)
497 return -ENOPKG;
498
499 _lock();
500 WaitSema(__fileXioCompletionSema);
501
502 packet->fd = fd;
503
504 if((rv = sceSifCallRpc(&__cd0, FILEXIO_CLOSE, __fileXioBlockMode, __sbuff, sizeof(struct fxio_close_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
505 {
506 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
507 else { rv = __sbuff[0]; }
508 }
509 else
510 SignalSema(__fileXioCompletionSema);
511
512 _unlock();
513 return(rv);
514}
515
516static inline void recv_intr(void *data_raw)
517{
518 rests_pkt *rests = UNCACHED_SEG(data_raw);
519
520 if(rests->ssize) memcpy(rests->sbuf, rests->sbuffer, rests->ssize);
521 if(rests->esize) memcpy(rests->ebuf, rests->ebuffer, rests->esize);
522
523 iSignalSema(__fileXioCompletionSema);
524}
525
526int fileXioRead(int fd, void *buf, int size)
527{
528 int rv;
529 struct fxio_read_packet *packet=(struct fxio_read_packet*)__sbuff;
530
531 if(fileXioInit() < 0)
532 return -ENOPKG;
533
534 _lock();
535 WaitSema(__fileXioCompletionSema);
536
537 packet->fd = fd;
538 packet->buffer = buf;
539 packet->size = size;
540 packet->intrData = __intr_data;
541
542 if (!IS_UNCACHED_SEG(buf))
543 sceSifWriteBackDCache(buf, size);
544
545 if((rv = sceSifCallRpc(&__cd0, FILEXIO_READ, __fileXioBlockMode, __sbuff, sizeof(struct fxio_read_packet), __sbuff, 4, &recv_intr, __intr_data)) >= 0)
546 {
547 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
548 else { rv = __sbuff[0]; }
549 }
550 else
551 SignalSema(__fileXioCompletionSema);
552
553 _unlock();
554 return(rv);
555}
556
557int fileXioWrite(int fd, const void *buf, int size)
558{
559 unsigned int miss;
560 int rv;
561 struct fxio_write_packet *packet=(struct fxio_write_packet*)__sbuff;
562
563 if(fileXioInit() < 0)
564 return -ENOPKG;
565
566 _lock();
567 WaitSema(__fileXioCompletionSema);
568
569 if((unsigned int)buf & 0x3F)
570 {
571 miss = 64 - ((unsigned int)buf & 0x3F);
572 if(miss > (unsigned int)size) miss = size;
573 } else {
574 miss = 0;
575 }
576
577 packet->fd = fd;
578 packet->buffer = buf;
579 packet->size = size;
580 packet->unalignedDataLen = miss;
581
582 memcpy(packet->unalignedData, buf, miss);
583
584 if(!IS_UNCACHED_SEG(buf))
585 sceSifWriteBackDCache((void*)buf, size);
586
587 if((rv = sceSifCallRpc(&__cd0, FILEXIO_WRITE, __fileXioBlockMode, __sbuff, sizeof(struct fxio_write_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
588 {
589 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
590 else { rv = __sbuff[0]; }
591 }
592 else
593 SignalSema(__fileXioCompletionSema);
594
595 _unlock();
596 return(rv);
597}
598
599int fileXioLseek(int fd, int offset, int whence)
600{
601 int rv;
602 struct fxio_lseek_packet *packet=(struct fxio_lseek_packet*)__sbuff;
603
604 if(fileXioInit() < 0)
605 return -ENOPKG;
606
607 _lock();
608 WaitSema(__fileXioCompletionSema);
609
610 packet->fd = fd;
611 packet->offset = (u32)offset;
612 packet->whence = whence;
613
614 if((rv = sceSifCallRpc(&__cd0, FILEXIO_LSEEK, __fileXioBlockMode, __sbuff, sizeof(struct fxio_lseek_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
615 {
616 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
617 else { rv = __sbuff[0]; }
618 }
619 else
620 SignalSema(__fileXioCompletionSema);
621
622 _unlock();
623 return(rv);
624}
625
626//
627// NOTE: 64-bit
628//
629s64 fileXioLseek64(int fd, s64 offset, int whence)
630{
631 s64 rv;
632 struct fxio_lseek64_packet *packet=(struct fxio_lseek64_packet*)__sbuff;
633 struct fxio_lseek64_return_pkt *ret_packet=(struct fxio_lseek64_return_pkt*)__sbuff;
634
635 if(fileXioInit() < 0)
636 return -ENOPKG;
637
638 _lock();
639 WaitSema(__fileXioCompletionSema);
640
641 packet->fd = fd;
642 packet->offset_lo = (u32)(offset & 0xffffffff);
643 packet->offset_hi = (u32)((offset >> 32) & 0xffffffff);
644 packet->whence = whence;
645
646 if((rv = sceSifCallRpc(&__cd0, FILEXIO_LSEEK64, __fileXioBlockMode, __sbuff, sizeof(struct fxio_lseek64_packet), __sbuff, 8, (void *)&_fxio_intr, NULL)) >= 0)
647 {
648 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
649 else {
650 s64 rvHI = ret_packet->pos_hi;
651 rvHI = rvHI << 32;
652 rv = rvHI | ret_packet->pos_lo;
653 }
654 }
655 else
656 SignalSema(__fileXioCompletionSema);
657
658 _unlock();
659
660 return(rv);
661}
662
663int fileXioChStat(const char *name, iox_stat_t *stat, int mask)
664{
665 int rv;
666 struct fxio_chstat_packet *packet=(struct fxio_chstat_packet*)__sbuff;
667
668 if(fileXioInit() < 0)
669 return -ENOPKG;
670
671 _lock();
672 WaitSema(__fileXioCompletionSema);
673
674 strlcpy(packet->pathname, name, sizeof(packet->pathname));
675 packet->stat = stat;
676 packet->mask = mask;
677
678 if(!IS_UNCACHED_SEG(stat))
679 sceSifWriteBackDCache(stat, sizeof(iox_stat_t));
680
681 if((rv = sceSifCallRpc(&__cd0, FILEXIO_CHSTAT, __fileXioBlockMode, __sbuff, sizeof(struct fxio_chstat_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
682 {
683 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
684 else { rv = __sbuff[0]; }
685 }
686 else
687 SignalSema(__fileXioCompletionSema);
688
689 _unlock();
690 return(rv);
691}
692
693int fileXioGetStat(const char *name, iox_stat_t *stat)
694{
695 int rv;
696 struct fxio_getstat_packet *packet=(struct fxio_getstat_packet*)__sbuff;
697
698 if(fileXioInit() < 0)
699 return -ENOPKG;
700
701 _lock();
702 WaitSema(__fileXioCompletionSema);
703
704 strlcpy(packet->pathname, name, sizeof(packet->pathname));
705 packet->stat = stat;
706
707 if(!IS_UNCACHED_SEG(stat))
708 sceSifWriteBackDCache(stat, sizeof(iox_stat_t));
709
710 if((rv = sceSifCallRpc(&__cd0, FILEXIO_GETSTAT, __fileXioBlockMode, __sbuff, sizeof(struct fxio_getstat_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
711 {
712 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
713 else { rv = __sbuff[0]; }
714 }
715 else
716 SignalSema(__fileXioCompletionSema);
717
718 _unlock();
719 return(rv);
720}
721
722int fileXioFormat(const char *dev, const char *blockdev, const void *args, int arglen)
723{
724 int rv;
725 struct fxio_format_packet *packet=(struct fxio_format_packet*)__sbuff;
726
727 if(fileXioInit() < 0)
728 return -ENOPKG;
729
730 _lock();
731 WaitSema(__fileXioCompletionSema);
732
733 strlcpy(packet->device, dev, sizeof(packet->device));
734 strlcpy(packet->blockDevice, blockdev ? blockdev : "", sizeof(packet->blockDevice));
735
736 if((unsigned int)arglen > sizeof(packet->args)) arglen = sizeof(packet->args);
737 memcpy(packet->args, args, arglen);
738 packet->arglen = arglen;
739
740 if((rv = sceSifCallRpc(&__cd0, FILEXIO_FORMAT, __fileXioBlockMode, __sbuff, sizeof(struct fxio_format_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
741 {
742 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
743 else { rv = __sbuff[0]; }
744 }
745 else
746 SignalSema(__fileXioCompletionSema);
747
748 _unlock();
749 return(rv);
750}
751
752int fileXioSync(const char *devname, int flag)
753{
754 int rv;
755 struct fxio_sync_packet *packet=(struct fxio_sync_packet*)__sbuff;
756
757 if(fileXioInit() < 0)
758 return -ENOPKG;
759
760 _lock();
761 WaitSema(__fileXioCompletionSema);
762
763 strlcpy(packet->device, devname, sizeof(packet->device));
764 packet->flags = flag;
765
766 if((rv = sceSifCallRpc(&__cd0, FILEXIO_SYNC, __fileXioBlockMode, __sbuff, sizeof(struct fxio_sync_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
767 {
768 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
769 else { rv = __sbuff[0]; }
770 }
771 else
772 SignalSema(__fileXioCompletionSema);
773
774 _unlock();
775 return(rv);
776}
777
778int fileXioDopen(const char *name)
779{
780 int rv;
781 struct fxio_pathsel_packet *packet=(struct fxio_pathsel_packet*)__sbuff;
782
783 if(fileXioInit() < 0)
784 return -ENOPKG;
785
786 _lock();
787 WaitSema(__fileXioCompletionSema);
788
789 strlcpy(packet->pathname, name, sizeof(packet->pathname));
790 if((rv = sceSifCallRpc(&__cd0, FILEXIO_DOPEN, __fileXioBlockMode, __sbuff, sizeof(struct fxio_pathsel_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
791 {
792 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
793 else { rv = __sbuff[0]; }
794 }
795 else
796 SignalSema(__fileXioCompletionSema);
797
798 _unlock();
799 return(rv);
800}
801
802int fileXioDclose(int fd)
803{
804 int rv;
805 struct fxio_close_packet *packet=(struct fxio_close_packet*)__sbuff;
806
807 if(fileXioInit() < 0)
808 return -ENOPKG;
809
810 _lock();
811 WaitSema(__fileXioCompletionSema);
812
813 packet->fd = fd;
814 if((rv = sceSifCallRpc(&__cd0, FILEXIO_DCLOSE, __fileXioBlockMode, __sbuff, sizeof(struct fxio_close_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
815 {
816 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
817 else { rv = __sbuff[0]; }
818 }
819 else
820 SignalSema(__fileXioCompletionSema);
821
822 _unlock();
823 return(rv);
824}
825
826int fileXioDread(int fd, iox_dirent_t *dirent)
827{
828 int rv;
829 struct fxio_dread_packet *packet=(struct fxio_dread_packet*)__sbuff;
830
831 if(fileXioInit() < 0)
832 return -ENOPKG;
833
834 _lock();
835 WaitSema(__fileXioCompletionSema);
836
837 packet->fd = fd;
838 packet->dirent = dirent;
839
840 if (!IS_UNCACHED_SEG(dirent))
841 sceSifWriteBackDCache(dirent, sizeof(iox_dirent_t));
842
843 if((rv = sceSifCallRpc(&__cd0, FILEXIO_DREAD, __fileXioBlockMode, __sbuff, sizeof(struct fxio_dread_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
844 {
845 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
846 else { rv = __sbuff[0]; }
847 }
848 else
849 SignalSema(__fileXioCompletionSema);
850
851 _unlock();
852 return(rv);
853}
854
855static inline void fxio_ctl_intr(void *data_raw)
856{
857 struct fxio_ctl_return_pkt *pkt = UNCACHED_SEG(data_raw);
858
859 memcpy(pkt->dest, pkt->buf, pkt->len);
860
861 iSignalSema(__fileXioCompletionSema);
862}
863
864int fileXioDevctl(const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen)
865{
866 struct fxio_devctl_packet *packet = (struct fxio_devctl_packet *)__sbuff;
867 int rv;
868
869 if(fileXioInit() < 0)
870 return -ENOPKG;
871
872 _lock();
873 WaitSema(__fileXioCompletionSema);
874
875 if(arglen > CTL_BUF_SIZE) arglen = CTL_BUF_SIZE;
876 if(buflen > CTL_BUF_SIZE) buflen = CTL_BUF_SIZE;
877 strlcpy(packet->name, name, sizeof(packet->name));
878 memcpy(packet->arg, arg, arglen);
879
880 packet->cmd = cmd;
881 packet->arglen = arglen;
882 packet->buf = buf;
883 packet->buflen = buflen;
884 packet->intr_data = __intr_data;
885
886 sceSifWriteBackDCache(buf, buflen);
887
888 if(buflen)
889 rv = sceSifCallRpc(&__cd0, FILEXIO_DEVCTL, __fileXioBlockMode, packet, sizeof(struct fxio_devctl_packet), __sbuff, 4, &fxio_ctl_intr, __intr_data);
890 else
891 rv = sceSifCallRpc(&__cd0, FILEXIO_DEVCTL, __fileXioBlockMode, packet, sizeof(struct fxio_devctl_packet), __sbuff, 4, (void *)&_fxio_intr, NULL);
892
893 if(rv >= 0)
894 {
895 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
896 else { rv = __sbuff[0]; }
897 }
898 else
899 SignalSema(__fileXioCompletionSema);
900
901 _unlock();
902 return(rv);
903}
904
905int fileXioIoctl(int fd, int cmd, void *arg){
906 struct fxio_ioctl_packet *packet = (struct fxio_ioctl_packet *)__sbuff;
907 int rv;
908
909 if(fileXioInit() < 0)
910 return -ENOPKG;
911
912 _lock();
913 WaitSema(__fileXioCompletionSema);
914
915 memcpy(packet->arg, arg, IOCTL_BUF_SIZE);
916
917 packet->fd = fd;
918 packet->cmd = cmd;
919
920 if((rv = sceSifCallRpc(&__cd0, FILEXIO_IOCTL, __fileXioBlockMode, packet, sizeof(struct fxio_ioctl_packet), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
921 {
922 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
923 else { rv = __sbuff[0]; }
924 }
925 else
926 SignalSema(__fileXioCompletionSema);
927
928 _unlock();
929 return(rv);
930}
931
932int fileXioIoctl2(int fd, int command, void *arg, unsigned int arglen, void *buf, unsigned int buflen)
933{
934 struct fxio_ioctl2_packet *packet = (struct fxio_ioctl2_packet *)__sbuff;
935 int rv;
936
937 if(fileXioInit() < 0)
938 return -ENOPKG;
939
940 _lock();
941 WaitSema(__fileXioCompletionSema);
942
943 if(arglen > CTL_BUF_SIZE) arglen = CTL_BUF_SIZE;
944 if(buflen > CTL_BUF_SIZE) buflen = CTL_BUF_SIZE;
945 memcpy(packet->arg, arg, arglen);
946
947 packet->fd = fd;
948 packet->cmd = command;
949 packet->arglen = arglen;
950 packet->buf = buf;
951 packet->buflen = buflen;
952 packet->intr_data = __intr_data;
953
954 sceSifWriteBackDCache(buf, buflen);
955
956 if(buflen)
957 rv = sceSifCallRpc(&__cd0, FILEXIO_IOCTL2, __fileXioBlockMode, packet, sizeof(struct fxio_ioctl2_packet), __sbuff, 4, &fxio_ctl_intr, __intr_data);
958 else
959 rv = sceSifCallRpc(&__cd0, FILEXIO_IOCTL2, __fileXioBlockMode, packet, sizeof(struct fxio_ioctl2_packet), __sbuff, 4, (void *)&_fxio_intr, NULL);
960
961 if(rv >= 0)
962 {
963 if(__fileXioBlockMode == FXIO_NOWAIT) { rv = 0; }
964 else { rv = __sbuff[0]; }
965 }
966 else
967 SignalSema(__fileXioCompletionSema);
968
969 _unlock();
970 return(rv);
971}
972
973int fileXioWaitAsync(int mode, int *retVal)
974{
975 if(fileXioInit() < 0)
976 return -ENOPKG;
977
978 if(__fileXioBlockMode != FXIO_NOWAIT) return 0;
979
980 switch(mode)
981 {
982 case FXIO_WAIT:
983
984 WaitSema(__fileXioCompletionSema);
985 SignalSema(__fileXioCompletionSema);
986
987 if(retVal != NULL)
988 *retVal = *(int *)UNCACHED_SEG(&__sbuff[0]);
989
990 return FXIO_COMPLETE;
991
992 case FXIO_NOWAIT:
993
994 if(PollSema(__fileXioCompletionSema) < 0)
995 return FXIO_INCOMPLETE;
996
997 SignalSema(__fileXioCompletionSema);
998
999 if(retVal != NULL)
1000 *retVal = *(int *)UNCACHED_SEG(&__sbuff[0]);
1001
1002 return FXIO_COMPLETE;
1003
1004 default:
1005 return -1;
1006 }
1007}
1008
1009void fileXioSetBlockMode(int blocking)
1010{
1011 __fileXioBlockMode = blocking;
1012}
1013
1014int fileXioSetRWBufferSize(int size){
1015 struct fxio_rwbuff *packet = (struct fxio_rwbuff *)__sbuff;
1016 int rv;
1017
1018 if(fileXioInit() < 0)
1019 return -ENOPKG;
1020
1021 _lock();
1022 WaitSema(__fileXioCompletionSema);
1023
1024 packet->size = size;
1025
1026 if((rv = sceSifCallRpc(&__cd0, FILEXIO_SETRWBUFFSIZE, 0, packet, sizeof(struct fxio_rwbuff), __sbuff, 4, (void *)&_fxio_intr, NULL)) >= 0)
1027 {
1028 rv = __sbuff[0];
1029 }
1030 else
1031 SignalSema(__fileXioCompletionSema);
1032
1033 _unlock();
1034 return(rv);
1035}
#define ENOPKG
Definition errno.h:154