PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
fileXio_iop.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
18//#define DEBUG
19
20#include <types.h>
21#include <stdio.h>
22#include <sysclib.h>
23#include <thbase.h>
24#include <intrman.h>
25#include <iomanX.h>
26#include <loadcore.h>
27#include <sysmem.h>
28#include <sifman.h>
29#include <sifcmd.h>
30#include <errno.h>
31#include <fileXio.h>
32
33#define MODNAME "fileXio"
34IRX_ID("IOX/File_Manager_Rpc", 1, 2);
35
36#define M_PRINTF(format, args...) \
37 printf(MODNAME ": " format, ##args)
38
39#ifdef DEBUG
40#define M_DEBUG M_PRINTF
41#else
42#define M_DEBUG(format, args...)
43#endif
44
45#define TRUE 1
46#define FALSE 0
47
48#define MIN(a, b) (((a)<(b))?(a):(b))
49#define RDOWN_64(a) ((unsigned int)(a)&~0x3F)
50
51#define DEFAULT_RWSIZE 16384
52static void *rwbuf = NULL;
53static unsigned int RWBufferSize=DEFAULT_RWSIZE;
54
55// 0x4800 bytes for DirEntry structures
56// 0x400 bytes for the filename string
57static unsigned char fileXio_rpc_buffer[0x4C00] __attribute__((__aligned__(4))); // RPC send/receive buffer
58struct t_SifRpcDataQueue qd;
59struct t_SifRpcServerData sd0;
60
61static rests_pkt rests;
62
63/* RPC exported functions */
64static int fileXio_GetDeviceList_RPC(struct fileXioDevice* ee_devices, int eecount);
65static int fileXio_CopyFile_RPC(const char *src, const char *dest, int mode);
66static int fileXio_Read_RPC(int infd, char *read_buf, int read_size, void *intr_data);
67static int fileXio_Write_RPC(int outfd, const char *write_buf, int write_size, int mis,u8 *misbuf);
68static int fileXio_GetDir_RPC(const char* pathname, struct fileXioDirEntry dirEntry[], unsigned int req_entries);
69static int fileXio_Mount_RPC(const char* mountstring, const char* mountpoint, int flag);
70static int fileXio_chstat_RPC(char *filename, void* eeptr, int mask);
71static int fileXio_getstat_RPC(char *filename, void* eeptr);
72static int fileXio_dread_RPC(int fd, void* eeptr);
73
74// Functions called by the RPC server
75static void* fileXioRpc_Stop();
76static void* fileXioRpc_GetDeviceList(unsigned int* sbuff);
77static void* fileXioRpc_Getdir(unsigned int* sbuff);
78static void* fileXioRpc_Mount(unsigned int* sbuff);
79static void* fileXioRpc_uMount(unsigned int* sbuff);
80static void* fileXioRpc_CopyFile(unsigned int* sbuff);
81static void* fileXioRpc_MkDir(unsigned int* sbuff);
82static void* fileXioRpc_RmDir(unsigned int* sbuff);
83static void* fileXioRpc_Remove(unsigned int* sbuff);
84static void* fileXioRpc_Rename(unsigned int* sbuff);
85static void* fileXioRpc_SymLink(unsigned int* sbuff);
86static void* fileXioRpc_ReadLink(unsigned int* sbuff);
87static void* fileXioRpc_ChDir(unsigned int* sbuff);
88static void* fileXioRpc_Open(unsigned int* sbuff);
89static void* fileXioRpc_Close(unsigned int* sbuff);
90static void* fileXioRpc_Read(unsigned int* sbuff);
91static void* fileXioRpc_Write(unsigned int* sbuff);
92static void* fileXioRpc_Lseek(unsigned int* sbuff);
93static void* fileXioRpc_Lseek64(unsigned int* sbuff);
94static void* fileXioRpc_ChStat(unsigned int* sbuff);
95static void* fileXioRpc_GetStat(unsigned int* sbuff);
96static void* fileXioRpc_Format(unsigned int* sbuff);
97static void* fileXioRpc_AddDrv(unsigned int* sbuff);
98static void* fileXioRpc_DelDrv(unsigned int* sbuff);
99static void* fileXioRpc_Sync(unsigned int* sbuff);
100static void* fileXioRpc_Devctl(unsigned int* sbuff);
101static void* fileXioRpc_Ioctl(unsigned int* sbuff);
102static void* fileXioRpc_Ioctl2(unsigned int* sbuff);
103static void* fileXioRpc_Dopen(unsigned int* sbuff);
104static void* fileXioRpc_Dread(unsigned int* sbuff);
105static void* fileXioRpc_Dclose(unsigned int* sbuff);
106static void* filexioRpc_SetRWBufferSize(void *sbuff);
107static void* fileXioRpc_Getdir(unsigned int* sbuff);
108static void DirEntryCopy(struct fileXioDirEntry* dirEntry, iox_dirent_t* internalDirEntry);
109
110// RPC server
111static void* fileXio_rpc_server(int fno, void *data, int size);
112static void fileXio_Thread(void* param);
113
114int _start( int argc, char *argv[])
115{
116 struct _iop_thread param;
117 int th, result;
118
119 (void)argc;
120 (void)argv;
121
122 param.attr = TH_C;
123 param.thread = (void*)fileXio_Thread;
124 param.priority = 40;
125 param.stacksize = 0x8000;
126 param.option = 0;
127
128 th = CreateThread(&param);
129
130 if (th > 0)
131 {
132 StartThread(th, NULL);
133 result=MODULE_RESIDENT_END;
134 }
135 else result=MODULE_NO_RESIDENT_END;
136
137 return result;
138}
139
140static int fileXio_GetDeviceList_RPC(struct fileXioDevice* ee_devices, int eecount)
141{
142 int device_count = 0;
143 iomanX_iop_device_t **devices = iomanX_GetDeviceList();
144 struct fileXioDevice local_devices[FILEXIO_MAX_DEVICES];
145 while (device_count < eecount && devices[device_count])
146 {
147 iomanX_iop_device_t *device = devices[device_count];
148 strncpy(local_devices[device_count].name, device->name, 128);
149 local_devices[device_count].name[15] = '\0';
150 local_devices[device_count].type = device->type;
151 local_devices[device_count].version = device->version;
152 strncpy(local_devices[device_count].desc, device->desc, 128);
153 local_devices[device_count].desc[127] = '\0';
154 ++device_count;
155 }
156 if (device_count)
157 {
158 struct t_SifDmaTransfer dmaStruct;
159 int intStatus; // interrupt status - for dis/en-abling interrupts
160
161 dmaStruct.src = local_devices;
162 dmaStruct.dest = ee_devices;
163 dmaStruct.size = sizeof(struct fileXioDevice) * device_count;
164 dmaStruct.attr = 0;
165
166 // Do the DMA transfer
167 CpuSuspendIntr(&intStatus);
168 sceSifSetDma(&dmaStruct, 1);
169 CpuResumeIntr(intStatus);
170 }
171 return device_count;
172}
173
174static int fileXio_CopyFile_RPC(const char *src, const char *dest, int mode)
175{
176 iox_stat_t stat;
177 int infd, outfd, size, remain, i;
178
179 if ((infd = iomanX_open(src, FIO_O_RDONLY, 0666)) < 0) {
180 return infd;
181 }
182 if ((outfd = iomanX_open(dest, FIO_O_RDWR|FIO_O_CREAT|FIO_O_TRUNC, 0666)) < 0) {
183 iomanX_close(infd);
184 return outfd;
185 }
186 size = iomanX_lseek(infd, 0, FIO_SEEK_END);
187 iomanX_lseek(infd, 0, FIO_SEEK_SET);
188 if (!size)
189 return 0;
190
191 remain = size % RWBufferSize;
192 for (i = 0; (unsigned int)i < (size / RWBufferSize); i++) {
193 iomanX_read(infd, rwbuf, RWBufferSize);
194 iomanX_write(outfd, rwbuf, RWBufferSize);
195 }
196 iomanX_read(infd, rwbuf, remain);
197 iomanX_write(outfd, rwbuf, remain);
198 iomanX_close(infd);
199 iomanX_close(outfd);
200
201 stat.mode = mode;
202 iomanX_chstat(dest, &stat, 1);
203
204 return size;
205}
206
207static int fileXio_Read_RPC(int infd, char *read_buf, int read_size, void *intr_data)
208{
209 int srest;
210 int erest;
211 int asize;
212 int abuffer;
213 int rlen;
214 int total;
215 int readlen;
216 int status;
217 struct t_SifDmaTransfer dmaStruct;
218 void *buffer;
219 void *aebuffer;
220 int intStatus; // interrupt status - for dis/en-abling interrupts
221 int read_buf2 = (int)read_buf;
222
223 total = 0;
224
225 if(read_size < 64)
226 {
227 srest = read_size;
228 erest = asize = abuffer = 0;
229 buffer = read_buf;
230 aebuffer = 0;
231 }else{
232 if ((read_buf2 & 0x3F) == 0)
233 srest=0;
234 else
235 srest=(int)RDOWN_64(read_buf2) - read_buf2 + 64;
236 buffer = read_buf;
237 abuffer = read_buf2 + srest;
238 aebuffer=(void *)RDOWN_64(read_buf2 + read_size);
239 asize = (int)aebuffer - (int)abuffer;
240 erest = (read_buf2 + read_size) - (int)aebuffer;
241 }
242 if (srest>0)
243 {
244 if (srest!=(rlen=iomanX_read(infd, rests.sbuffer, srest)))
245 {
246 total += srest = (rlen>0 ? rlen:0);
247 goto EXIT;
248 }
249 else
250 total += srest;
251 }
252
253 status=0;
254 while (asize>0)
255 {
256 readlen=MIN(RWBufferSize, (unsigned int)asize);
257
258 while(sceSifDmaStat(status)>=0);
259
260 rlen=iomanX_read(infd, rwbuf, readlen);
261 if (readlen!=rlen){
262 if (rlen<=0)goto EXIT;
263 dmaStruct.dest=(void *)abuffer;
264 dmaStruct.size=rlen;
265 dmaStruct.attr=0;
266 dmaStruct.src =rwbuf;
267 CpuSuspendIntr(&intStatus);
268 sceSifSetDma(&dmaStruct, 1);
269 CpuResumeIntr(intStatus);
270 total +=rlen;
271 goto EXIT;
272 }else{ //read ok
273 total += rlen;
274 asize -=rlen;
275 dmaStruct.dest=(void *)abuffer;
276 abuffer +=rlen;
277 dmaStruct.size=rlen;
278 dmaStruct.attr=0;
279 dmaStruct.src =rwbuf;
280 CpuSuspendIntr(&intStatus);
281 status=sceSifSetDma(&dmaStruct, 1);
282 CpuResumeIntr(intStatus);
283 }
284 }
285 if (erest>0)
286 {
287 rlen = iomanX_read(infd, rests.ebuffer, erest);
288 total += (rlen>0 ? rlen : 0);
289 }
290EXIT:
291 rests.ssize=srest;
292 rests.esize=erest;
293 rests.sbuf =buffer;
294 rests.ebuf =aebuffer;
295 dmaStruct.src =&rests;
296 dmaStruct.size=sizeof(rests_pkt);
297 dmaStruct.attr=0;
298 dmaStruct.dest=intr_data;
299 CpuSuspendIntr(&intStatus);
300 sceSifSetDma(&dmaStruct, 1);
301 CpuResumeIntr(intStatus);
302 return (total);
303}
304
305static int fileXio_Write_RPC(int outfd, const char *write_buf, int write_size, int mis,u8 *misbuf)
306{
308 int left;
309 int wlen;
310 int pos;
311 int total;
312
313 left = write_size;
314 total = 0;
315 if (mis > 0)
316 {
317 wlen=iomanX_write(outfd, misbuf, mis);
318 if (wlen != mis)
319 {
320 if (wlen > 0)
321 total += wlen;
322 return (total);
323 }
324 total += wlen;
325 }
326
327 left-=mis;
328 pos=(int)write_buf+mis;
329 while(left){
330 int writelen;
331 writelen = MIN(RWBufferSize, (unsigned int)left);
332 sceSifGetOtherData(&rdata, (void *)pos, rwbuf, writelen, 0);
333 wlen=iomanX_write(outfd, rwbuf, writelen);
334 if (wlen != writelen){
335 if (wlen>0)
336 total+=wlen;
337 return (total);
338 }
339 left -=writelen;
340 pos +=writelen;
341 total+=writelen;
342 }
343 return (total);
344}
345
346
347// This is the getdir for use by the EE RPC client
348// It DMA's entries to the specified buffer in EE memory
349static int fileXio_GetDir_RPC(const char* pathname, struct fileXioDirEntry dirEntry[], unsigned int req_entries)
350{
351 int matched_entries;
352 int fd;
353 iox_dirent_t dirbuf;
354 struct fileXioDirEntry localDirEntry;
355 int intStatus; // interrupt status - for dis/en-abling interrupts
356 struct t_SifDmaTransfer dmaStruct;
357
358 M_DEBUG("GetDir Request '%s'\n",pathname);
359
360 matched_entries = 0;
361
362 fd = iomanX_dopen(pathname);
363 if (fd <= 0)
364 {
365 return fd;
366 }
367 {
368 int res;
369
370 res = 1;
371 while (res > 0)
372 {
373 memset(&dirbuf, 0, sizeof(dirbuf));
374 res = iomanX_dread(fd, &dirbuf);
375 if (res > 0)
376 {
377 int dmaID;
378
379 dmaID = 0;
380
381 // check for too many entries
382 if ((unsigned int)matched_entries == req_entries)
383 {
384 iomanX_close(fd);
385 return (matched_entries);
386 }
387 // wait for any previous DMA to complete
388 // before over-writing localDirEntry
389 while(sceSifDmaStat(dmaID)>=0);
390 DirEntryCopy(&localDirEntry, &dirbuf);
391 // DMA localDirEntry to the address specified by dirEntry[matched_entries]
392 // setup the dma struct
393 dmaStruct.src = &localDirEntry;
394 dmaStruct.dest = &dirEntry[matched_entries];
395 dmaStruct.size = sizeof(struct fileXioDirEntry);
396 dmaStruct.attr = 0;
397 // Do the DMA transfer
398 CpuSuspendIntr(&intStatus);
399 dmaID = sceSifSetDma(&dmaStruct, 1);
400 CpuResumeIntr(intStatus);
401 matched_entries++;
402 } // if res
403 } // while
404
405 } // if dirs and files
406
407 // cleanup and return # of entries
408 iomanX_close(fd);
409 return (matched_entries);
410}
411
412// This is the mount for use by the EE RPC client
413static int fileXio_Mount_RPC(const char* mountstring, const char* mountpoint, int flag)
414{
415 int res=0;
416 M_DEBUG("Mount Request mountpoint:'%s' - '%s' - %d\n",mountpoint,mountstring,flag);
417 res = iomanX_mount(mountpoint, mountstring, flag, NULL, 0);
418 return(res);
419}
420
421static int fileXio_chstat_RPC(char *filename, void* eeptr, int mask)
422{
423 int res=0;
424 iox_stat_t localStat;
426
427 sceSifGetOtherData(&rdata, (void *)eeptr, &localStat, 64, 0);
428
429 res = iomanX_chstat(filename, &localStat, mask);
430 return(res);
431}
432
433static int fileXio_getstat_RPC(char *filename, void* eeptr)
434{
435 iox_stat_t localStat;
436 int res = 0;
437 struct t_SifDmaTransfer dmaStruct;
438 int intStatus; // interrupt status - for dis/en-abling interrupts
439
440 res = iomanX_getstat(filename, &localStat);
441
442 if(res >= 0)
443 {
444 // DMA localStat to the address specified by eeptr
445 // setup the dma struct
446 dmaStruct.src = &localStat;
447 dmaStruct.dest = eeptr;
448 dmaStruct.size = sizeof(iox_stat_t);
449 dmaStruct.attr = 0;
450 // Do the DMA transfer
451 CpuSuspendIntr(&intStatus);
452 sceSifSetDma(&dmaStruct, 1);
453 CpuResumeIntr(intStatus);
454 }
455
456 return(res);
457}
458
459static int fileXio_dread_RPC(int fd, void* eeptr)
460{
461 int res=0;
462 iox_dirent_t localDir;
463 struct t_SifDmaTransfer dmaStruct;
464 int intStatus; // interrupt status - for dis/en-abling interrupts
465
466 res = iomanX_dread(fd, &localDir);
467 if (res > 0)
468 {
469 // DMA localStat to the address specified by eeptr
470 // setup the dma struct
471 dmaStruct.src = &localDir;
472 dmaStruct.dest = eeptr;
473 dmaStruct.size = 64+256;
474 dmaStruct.attr = 0;
475 // Do the DMA transfer
476 CpuSuspendIntr(&intStatus);
477 sceSifSetDma(&dmaStruct, 1);
478 CpuResumeIntr(intStatus);
479 }
480
481 return(res);
482}
483
484static void* fileXioRpc_Stop(void)
485{
486 M_DEBUG("Stop Request\n");
487 return NULL;
488}
489
490// Send: Offset 0 = pointer to array of fileXioDevice structures in EE mem
491// Send: Offset 4 = requested number of entries
492// Return: Offset 0 = ret val (number of entries). Size = int
493static void* fileXioRpc_GetDeviceList(unsigned int* sbuff)
494{
495 int ret;
496 struct fxio_devlist_packet *packet=(struct fxio_devlist_packet*)sbuff;
497
498 ret=fileXio_GetDeviceList_RPC(
499 packet->deviceEntry,
500 packet->reqEntries
501 );
502 sbuff[0] = ret;
503 return sbuff;
504}
505
506// Send: Offset 0 = filename string (512 bytes)
507// Send: Offset 512 = pointer to array of DirEntry structures in EE mem
508// Send: Offset 516 = requested number of entries
509// Return: Offset 0 = ret val (number of matched entries). Size = int
510static void* fileXioRpc_Getdir(unsigned int* sbuff)
511{
512 int ret;
513 struct fxio_getdir_packet *packet=(struct fxio_getdir_packet*)sbuff;
514
515 ret=fileXio_GetDir_RPC(
516 packet->pathname,
517 packet->dirEntry,
518 packet->reqEntries
519 );
520 sbuff[0] = ret;
521 return sbuff;
522}
523
524// Send: Offset 0 = mount format string (512 bytes)
525// Send: Offset 512 = mount point (512 bytes)
526// Return: Offset 0 = return status (int)
527static void* fileXioRpc_Mount(unsigned int* sbuff)
528{
529 struct fxio_mount_packet *packet=(struct fxio_mount_packet*)sbuff;
530 int ret;
531
532 M_DEBUG("Mount Request\n");
533 ret=fileXio_Mount_RPC(
534 packet->blockdevice, // mount format string
535 packet->mountpoint, // mount point
536 packet->flags // flag (normal,readonly,robust)
537 );
538
539 sbuff[0] = ret;
540 return sbuff;
541}
542
543// Send: Offset 0 = mount format string (512 bytes)
544// Send: Offset 512 = mount point (512 bytes)
545// Return: Offset 0 = return status (int)
546static void* fileXioRpc_uMount(unsigned int* sbuff)
547{
548 int ret;
549 struct fxio_unmount_packet *packet=(struct fxio_unmount_packet*)sbuff;
550
551 M_DEBUG("uMount Request\n");
552 ret=iomanX_umount(packet->mountpoint);
553 sbuff[0] = ret;
554 return sbuff;
555}
556
557// Send: Offset 0 = source filename (512 bytes)
558// Send: Offset 512 = destination filename (512 bytes)
559// Return: Offset 0 = return status (int)
560static void* fileXioRpc_CopyFile(unsigned int* sbuff)
561{
562 int ret;
563 struct fxio_copyfile_packet *packet=(struct fxio_copyfile_packet*)sbuff;
564
565 ret=fileXio_CopyFile_RPC(
566 packet->source, // source filename
567 packet->dest, // dest filename
568 packet->mode // mode
569 );
570
571 sbuff[0] = ret;
572 return sbuff;
573}
574
575// Send: Offset 0 = filenames (512 bytes)
576// Send: Offset 512 = mode (int)
577// Return: Offset 0 = return status (int)
578static void* fileXioRpc_MkDir(unsigned int* sbuff)
579{
580 int ret;
581 struct fxio_mkdir_packet *packet=(struct fxio_mkdir_packet*)sbuff;
582
583 M_DEBUG("MkDir Request\n");
584 ret=iomanX_mkdir(packet->pathname, packet->mode);
585 sbuff[0] = ret;
586 return sbuff;
587}
588
589// Send: Offset 0 = filenames (512 bytes)
590// Return: Offset 0 = return status (int)
591static void* fileXioRpc_RmDir(unsigned int* sbuff)
592{
593 int ret;
594 struct fxio_pathsel_packet *packet=(struct fxio_pathsel_packet*)sbuff;
595
596 M_DEBUG("RmDir Request\n");
597 ret=iomanX_rmdir(packet->pathname);
598 sbuff[0] = ret;
599 return sbuff;
600}
601
602// Send: Offset 0 = filenames (512 bytes)
603// Return: Offset 0 = return status (int)
604static void* fileXioRpc_Remove(unsigned int* sbuff)
605{
606 int ret;
607 struct fxio_pathsel_packet *packet=(struct fxio_pathsel_packet*)sbuff;
608
609 M_DEBUG("Remove Request\n");
610 ret=iomanX_remove(packet->pathname);
611 sbuff[0] = ret;
612 return sbuff;
613}
614
615// Send: Offset 0 = source filename (512 bytes)
616// Send: Offset 512 = destination filename (512 bytes)
617// Return: Offset 0 = return status (int)
618static void* fileXioRpc_Rename(unsigned int* sbuff)
619{
620 int ret;
621 struct fxio_rename_packet *packet=(struct fxio_rename_packet*)sbuff;
622
623 M_DEBUG("Rename Request\n");
624 ret=iomanX_rename(packet->source, packet->dest);
625 sbuff[0] = ret;
626 return sbuff;
627}
628
629// Send: Offset 0 = source filename (512 bytes)
630// Send: Offset 512 = destination filename (512 bytes)
631// Return: Offset 0 = return status (int)
632static void* fileXioRpc_SymLink(unsigned int* sbuff)
633{
634 int ret;
635 struct fxio_rename_packet *packet=(struct fxio_rename_packet*)sbuff;
636
637 M_DEBUG("SymLink Request\n");
638 ret=iomanX_symlink(packet->source, packet->dest);
639 sbuff[0] = ret;
640 return sbuff;
641}
642
643// Send: Offset 0 = source filename (512 bytes)
644// Send: Offset 512 = buffer (512 bytes)
645// Send: Offset 1024 = buflen (int)
646// Return: Offset 0 = return status (int)
647static void* fileXioRpc_ReadLink(unsigned int* sbuff)
648{
649 int ret;
650 struct fxio_readlink_packet *packet=(struct fxio_readlink_packet*)sbuff;
651
652 M_DEBUG("ReadLink Request\n");
653 ret=iomanX_readlink(packet->source, packet->buffer, packet->buflen);
654 sbuff[0] = ret;
655 return sbuff;
656}
657
658// Send: Offset 0 = filename (512 bytes)
659// Return: Offset 0 = return status (int)
660void* fileXioRpc_ChDir(unsigned int* sbuff)
661{
662 int ret;
663 M_DEBUG("ChDir Request '%s'\n", (char*)sbuff);
664 ret=iomanX_chdir((char*)sbuff);
665 sbuff[0] = ret;
666 return sbuff;
667}
668
669// Send: Offset 0 = source filename (512 bytes)
670// Send: Offset 512 = flags (int)
671// Send: Offset 516 = modes (int)
672// Return: Offset 0 = return status (int) / fd
673static void* fileXioRpc_Open(unsigned int* sbuff)
674{
675 int ret;
676 struct fxio_open_packet *packet=(struct fxio_open_packet*)sbuff;
677
678 M_DEBUG("Open Request '%s' f:0x%x m:0x%x\n", packet->pathname, packet->flags, packet->mode);
679 ret=iomanX_open(packet->pathname, packet->flags, packet->mode);
680 sbuff[0] = ret;
681 return sbuff;
682}
683
684// Send: Offset 0 = fd (int)
685// Return: Offset 0 = return status (int)
686static void* fileXioRpc_Close(unsigned int* sbuff)
687{
688 int ret;
689 struct fxio_close_packet *packet=(struct fxio_close_packet*)sbuff;
690
691 M_DEBUG("Close Request fd:%d\n", packet->fd);
692 ret=iomanX_close(packet->fd);
693 sbuff[0] = ret;
694 return sbuff;
695}
696
697// Send: Offset 0 = fd (int)
698// Send: Offset 4 = pointer to buffer in EE mem
699// Send: Offset 8 = buffer size (int)
700// Send: Offset 12 = pointer to intr_data in EE mem
701static void* fileXioRpc_Read(unsigned int* sbuff)
702{
703 int ret;
704 struct fxio_read_packet *packet=(struct fxio_read_packet*)sbuff;
705
706 M_DEBUG("Read Request fd:%d, size:%d\n", packet->fd, packet->size);
707 ret=fileXio_Read_RPC(packet->fd, packet->buffer, packet->size, packet->intrData);
708 sbuff[0] = ret;
709 return sbuff;
710}
711
712// Send: Offset 0 = fd (int)
713// Send: Offset 4 = pointer to buffer in EE mem
714// Send: Offset 8 = buffer size (int)
715// Send: Offset 12 = misaligned buffer size (int)
716// Send: Offset 16 = misaligned buffer (16)
717static void* fileXioRpc_Write(unsigned int* sbuff)
718{
719 int ret;
720 struct fxio_write_packet *packet=(struct fxio_write_packet*)sbuff;
721
722 M_DEBUG("Write Request fd:%d, size:%d\n", packet->fd, packet->size);
723 ret=fileXio_Write_RPC(packet->fd, packet->buffer, packet->size,
724 packet->unalignedDataLen, packet->unalignedData);
725 sbuff[0] = ret;
726 return sbuff;
727}
728
729// Send: Offset 0 = fd (int)
730// Send: Offset 4 = offset (long)
731// Send: Offset 8 = whence (int)
732// Return: Offset 0 = return status (int)
733static void* fileXioRpc_Lseek(unsigned int* sbuff)
734{
735 int ret;
736 struct fxio_lseek_packet *packet=(struct fxio_lseek_packet*)sbuff;
737
738 M_DEBUG("Lseek Request fd:%d off:%d mode:%d\n", packet->fd, packet->offset, packet->whence);
739 ret=iomanX_lseek(packet->fd, (long int)packet->offset, packet->whence);
740 sbuff[0] = ret;
741 return sbuff;
742}
743
744// Send: Offset 0 = fd (int)
745// Send: Offset 4 = offset (long long)
746// Send: Offset 12 = whence (int)
747// Return: Offset 0 = return status (long long)
748static void* fileXioRpc_Lseek64(unsigned int* sbuff)
749{
750 long long ret;
751 struct fxio_lseek64_packet *packet=(struct fxio_lseek64_packet*)sbuff;
752 struct fxio_lseek64_return_pkt *ret_packet=(struct fxio_lseek64_return_pkt*)sbuff;
753
754 M_DEBUG("Lseek64 Request...\n");
755
756 long long offsetHI = packet->offset_hi;
757 offsetHI = offsetHI << 32;
758 long long offset = offsetHI | packet->offset_lo;
759 M_DEBUG("Lseek64 Request fd:%d off:%lld, mode:%d\n", packet->fd, offset, packet->whence);
760
761 ret=iomanX_lseek64(packet->fd, offset, packet->whence);
762 ret_packet->pos_lo = (u32)(ret & 0xffffffff);
763 ret_packet->pos_hi = (u32)((ret >> 32) & 0xffffffff);
764
765 return sbuff;
766}
767
768// Send: Offset 0 = filename (int)
769// Send: Offset 512 = pointer to EE mem
770// Send: Offset 516 = mask (int)
771// Return: Offset 0 = return status (int)
772static void* fileXioRpc_ChStat(unsigned int* sbuff)
773{
774 int ret=-1;
775 struct fxio_chstat_packet *packet=(struct fxio_chstat_packet*)sbuff;
776
777 M_DEBUG("ChStat Request '%s'\n", packet->pathname);
778 ret=fileXio_chstat_RPC(packet->pathname, packet->stat, packet->mask);
779 sbuff[0] = ret;
780 return sbuff;
781}
782
783// Send: Offset 0 = filename
784// Send: Offset 512 = pointer to EE mem
785// Return: Offset 0 = return status (int)
786static void* fileXioRpc_GetStat(unsigned int* sbuff)
787{
788 int ret=-1;
789 struct fxio_getstat_packet *packet=(struct fxio_getstat_packet*)sbuff;
790
791 M_DEBUG("GetStat Request '%s'\n", packet->pathname);
792 ret=fileXio_getstat_RPC(packet->pathname, packet->stat);
793 sbuff[0] = ret;
794 return sbuff;
795}
796
797// Send: Offset 0 = device
798// Send: Offset 128 = blockdevice
799// Send: Offset 640 = args
800// Send: Offset 1152 = arglen (int)
801// Return: Offset 0 = return status
802static void* fileXioRpc_Format(unsigned int* sbuff)
803{
804 int ret;
805 struct fxio_format_packet *packet=(struct fxio_format_packet*)sbuff;
806
807 M_DEBUG("Format Request dev:'%s' bd:'%s'\n", packet->device, packet->blockDevice);
808 ret=iomanX_format(packet->device, packet->blockDevice, packet->args, packet->arglen);
809 sbuff[0] = ret;
810 return sbuff;
811}
812
813//int io_AddDrv(iomanX_iop_device_t *device);
814static void* fileXioRpc_AddDrv(unsigned int* sbuff)
815{
816 int ret=-1;
817 M_DEBUG("AddDrv Request\n");
818 // BODY
819 sbuff[0] = ret;
820 return sbuff;
821}
822
823// Send: Offset 0 = fsname
824// Return: Offset 0 = return status (int)
825static void* fileXioRpc_DelDrv(unsigned int* sbuff)
826{
827 int ret=-1;
828 M_DEBUG("DelDrv Request\n");
829// ret=deldrv((char *)&sbuff[0/4]);
830 sbuff[0] = ret;
831 return sbuff;
832}
833
834// Send: Offset 0 = devname
835// Send: Offset 512 = flag (int)
836// Return: Offset 0 = return status (int)
837static void* fileXioRpc_Sync(unsigned int* sbuff)
838{
839 int ret;
840 struct fxio_sync_packet *packet=(struct fxio_sync_packet*)sbuff;
841
842 M_DEBUG("Sync Request\n");
843 ret=iomanX_sync(packet->device, packet->flags);
844 sbuff[0] = ret;
845 return sbuff;
846}
847
848//int io_devctl(const char *name, int cmd, void *arg, unsigned int arglen, void *bufp,
849// unsigned int buflen);
850static void* fileXioRpc_Devctl(unsigned int* sbuff)
851{
852 struct fxio_devctl_packet *packet = (struct fxio_devctl_packet *)sbuff;
853 struct fxio_ctl_return_pkt *ret_buf = (struct fxio_ctl_return_pkt *)rwbuf;
854 SifDmaTransfer_t dmatrans;
855 int intStatus;
856 int ret;
857
858 M_DEBUG("Devctl Request '%s' cmd:%d\n", packet->name, packet->cmd);
859
860 ret = iomanX_devctl(packet->name, packet->cmd, packet->arg, packet->arglen, ret_buf->buf, packet->buflen);
861
862 // Transfer buffer back to EE
863 if(packet->buflen != 0)
864 {
865 dmatrans.src = ret_buf;
866 dmatrans.dest = packet->intr_data;
867 dmatrans.attr = 0;
868 dmatrans.size = sizeof(struct fxio_ctl_return_pkt);
869
870 ret_buf->dest = packet->buf;
871
872 // EE is expecting data.. on error, simply use size of 0 so no data is copied.
873 if(ret >= 0)
874 ret_buf->len = packet->buflen;
875 else
876 ret_buf->len = 0;
877
878 CpuSuspendIntr(&intStatus);
879 sceSifSetDma(&dmatrans, 1);
880 CpuResumeIntr(intStatus);
881 }
882
883 sbuff[0] = ret;
884 return sbuff;
885}
886
887//int io_ioctl(int fd, int cmd, void *arg);
888static void* fileXioRpc_Ioctl(unsigned int* sbuff)
889{
890 struct fxio_ioctl_packet *packet = (struct fxio_ioctl_packet *)sbuff;
891 int ret;
892
893 M_DEBUG("Ioctl Request fd:%d cmd:%d\n", packet->fd, packet->cmd);
894
895 // BODY
896 ret=iomanX_ioctl(packet->fd, packet->cmd, packet->arg);
897 sbuff[0] = ret;
898 return sbuff;
899}
900//int io_ioctl2(int fd, int cmd, void *arg, unsigned int arglen, void *bufp,
901// unsigned int buflen);
902static void* fileXioRpc_Ioctl2(unsigned int* sbuff)
903{
904 struct fxio_ioctl2_packet *packet = (struct fxio_ioctl2_packet *)sbuff;
905 struct fxio_ctl_return_pkt *ret_buf = (struct fxio_ctl_return_pkt *)rwbuf;
906 SifDmaTransfer_t dmatrans;
907 int intStatus;
908 int ret;
909
910 M_DEBUG("ioctl2 Request fd:%d cmd:%d\n", packet->fd, packet->cmd);
911
912 ret = iomanX_ioctl2(packet->fd, packet->cmd, packet->arg, packet->arglen, ret_buf->buf, packet->buflen);
913
914 // Transfer buffer back to EE
915 if(packet->buflen != 0)
916 {
917 dmatrans.src = ret_buf;
918 dmatrans.dest = packet->intr_data;
919 dmatrans.attr = 0;
920 dmatrans.size = sizeof(struct fxio_ctl_return_pkt);
921
922 ret_buf->dest = packet->buf;
923
924 // EE is expecting data.. on error, simply use size of 0 so no data is copied.
925 if(ret >= 0)
926 ret_buf->len = packet->buflen;
927 else
928 ret_buf->len = 0;
929
930 CpuSuspendIntr(&intStatus);
931 sceSifSetDma(&dmatrans, 1);
932 CpuResumeIntr(intStatus);
933 }
934
935 sbuff[0] = ret;
936 return sbuff;
937}
938
939static void* fileXioRpc_Dopen(unsigned int* sbuff)
940{
941 int ret;
942 struct fxio_pathsel_packet *packet=(struct fxio_pathsel_packet*)sbuff;
943
944 M_DEBUG("Dopen Request '%s'\n", packet->pathname);
945 ret=iomanX_dopen(packet->pathname);
946 sbuff[0] = ret;
947 return sbuff;
948}
949
950static void* fileXioRpc_Dread(unsigned int* sbuff)
951{
952 int ret=-1;
953 struct fxio_dread_packet *packet=(struct fxio_dread_packet*)sbuff;
954
955 M_DEBUG("Dread Request fd:%d\n", packet->fd);
956 ret=fileXio_dread_RPC(packet->fd, packet->dirent);
957 sbuff[0] = ret;
958 return sbuff;
959}
960
961static void* fileXioRpc_Dclose(unsigned int* sbuff)
962{
963 int ret;
964 struct fxio_close_packet *packet=(struct fxio_close_packet*)sbuff;
965
966 M_DEBUG("Dclose Request fd:%d\n", packet->fd);
967 ret=iomanX_dclose(packet->fd);
968 sbuff[0] = ret;
969 return sbuff;
970}
971
972/*************************************************
973* The functions below are for internal use only, *
974* and are not to be exported *
975*************************************************/
976
977static void fileXio_Thread(void* param)
978{
979 int OldState;
980
981 (void)param;
982
983 M_PRINTF("fileXio: fileXio RPC Server v1.00\nCopyright (c) 2003 adresd\n");
984 M_DEBUG("fileXio: RPC Initialize\n");
985
986 sceSifInitRpc(0);
987
988 RWBufferSize=DEFAULT_RWSIZE;
989 CpuSuspendIntr(&OldState);
990 rwbuf = AllocSysMemory(ALLOC_FIRST, RWBufferSize, NULL);
991 CpuResumeIntr(OldState);
992 if (rwbuf == NULL)
993 {
994 M_DEBUG("Failed to allocate memory for RW buffer!\n");
995
996 SleepThread();
997 }
998
999 sceSifSetRpcQueue(&qd, GetThreadId());
1000 sceSifRegisterRpc(&sd0, FILEXIO_IRX, &fileXio_rpc_server, fileXio_rpc_buffer, NULL, NULL, &qd);
1001 sceSifRpcLoop(&qd);
1002}
1003
1004static void* filexioRpc_SetRWBufferSize(void *sbuff)
1005{
1006 int OldState;
1007
1008 if(rwbuf!=NULL){
1009 CpuSuspendIntr(&OldState);
1010 FreeSysMemory(rwbuf);
1011 CpuResumeIntr(OldState);
1012 }
1013
1014 RWBufferSize=((struct fxio_rwbuff*)sbuff)->size;
1015 CpuSuspendIntr(&OldState);
1016 rwbuf=AllocSysMemory(ALLOC_FIRST, RWBufferSize, NULL);
1017 CpuResumeIntr(OldState);
1018
1019 ((int*)sbuff)[0] = rwbuf!=NULL?0:-ENOMEM;
1020 return sbuff;
1021}
1022
1023static void* fileXio_rpc_server(int fno, void *data, int size)
1024{
1025 (void)size;
1026
1027 switch(fno) {
1028 case FILEXIO_DOPEN:
1029 return fileXioRpc_Dopen((unsigned*)data);
1030 case FILEXIO_DREAD:
1031 return fileXioRpc_Dread((unsigned*)data);
1032 case FILEXIO_DCLOSE:
1033 return fileXioRpc_Dclose((unsigned*)data);
1034 case FILEXIO_MOUNT:
1035 return fileXioRpc_Mount((unsigned*)data);
1036 case FILEXIO_UMOUNT:
1037 return fileXioRpc_uMount((unsigned*)data);
1038 case FILEXIO_GETDIR:
1039 return fileXioRpc_Getdir((unsigned*)data);
1040 case FILEXIO_COPYFILE:
1041 return fileXioRpc_CopyFile((unsigned*)data);
1042 case FILEXIO_STOP:
1043 return fileXioRpc_Stop();
1044 case FILEXIO_CHDIR:
1045 return fileXioRpc_ChDir((unsigned*)data);
1046 case FILEXIO_RENAME:
1047 return fileXioRpc_Rename((unsigned*)data);
1048 case FILEXIO_MKDIR:
1049 return fileXioRpc_MkDir((unsigned*)data);
1050 case FILEXIO_RMDIR:
1051 return fileXioRpc_RmDir((unsigned*)data);
1052 case FILEXIO_REMOVE:
1053 return fileXioRpc_Remove((unsigned*)data);
1054 case FILEXIO_OPEN:
1055 return fileXioRpc_Open((unsigned*)data);
1056 case FILEXIO_CLOSE:
1057 return fileXioRpc_Close((unsigned*)data);
1058 case FILEXIO_READ:
1059 return fileXioRpc_Read((unsigned*)data);
1060 case FILEXIO_WRITE:
1061 return fileXioRpc_Write((unsigned*)data);
1062 case FILEXIO_LSEEK:
1063 return fileXioRpc_Lseek((unsigned*)data);
1064 case FILEXIO_IOCTL:
1065 return fileXioRpc_Ioctl((unsigned*)data);
1066 case FILEXIO_GETSTAT:
1067 return fileXioRpc_GetStat((unsigned*)data);
1068 case FILEXIO_CHSTAT:
1069 return fileXioRpc_ChStat((unsigned*)data);
1070 case FILEXIO_FORMAT:
1071 return fileXioRpc_Format((unsigned*)data);
1072 case FILEXIO_ADDDRV:
1073 return fileXioRpc_AddDrv((unsigned*)data);
1074 case FILEXIO_DELDRV:
1075 return fileXioRpc_DelDrv((unsigned*)data);
1076 case FILEXIO_SYNC:
1077 return fileXioRpc_Sync((unsigned*)data);
1078 case FILEXIO_DEVCTL:
1079 return fileXioRpc_Devctl((unsigned*)data);
1080 case FILEXIO_SYMLINK:
1081 return fileXioRpc_SymLink((unsigned*)data);
1082 case FILEXIO_READLINK:
1083 return fileXioRpc_ReadLink((unsigned*)data);
1084 case FILEXIO_IOCTL2:
1085 return fileXioRpc_Ioctl2((unsigned*)data);
1086 case FILEXIO_LSEEK64:
1087 return fileXioRpc_Lseek64((unsigned*)data);
1088 case FILEXIO_GETDEVICELIST:
1089 return fileXioRpc_GetDeviceList((unsigned*)data);
1090 case FILEXIO_SETRWBUFFSIZE:
1091 return filexioRpc_SetRWBufferSize(data);
1092 }
1093 return NULL;
1094}
1095
1096
1097// Copy a DIR Entry from the native format to our format
1098static void DirEntryCopy(struct fileXioDirEntry* dirEntry, iox_dirent_t* internalDirEntry)
1099{
1100 dirEntry->fileSize = internalDirEntry->stat.size;
1101 dirEntry->fileProperties = internalDirEntry->stat.attr;
1102 strncpy(dirEntry->filename,internalDirEntry->name,127);
1103 dirEntry->filename[127] = '\0';
1104}
#define ENOMEM
Definition errno.h:43
Definition fileXio.h:100
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
int iomanX_format(const char *dev, const char *blockdev, void *arg, int arglen)
Definition iomanX.c:716
unsigned int version
Definition iomanX.h:85
typedef __attribute__
Definition tlbfunc.c:60
kbd_dev * devices[PS2KBD_MAXDEV]
Definition ps2kbd.c:102