PS2SDK
PS2 Homebrew Libraries
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"
34 IRX_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
52 static void *rwbuf = NULL;
53 static unsigned int RWBufferSize=DEFAULT_RWSIZE;
54 
55 // 0x4800 bytes for DirEntry structures
56 // 0x400 bytes for the filename string
57 static unsigned char fileXio_rpc_buffer[0x4C00] __attribute__((__aligned__(4))); // RPC send/receive buffer
58 struct t_SifRpcDataQueue qd;
59 struct t_SifRpcServerData sd0;
60 
61 static rests_pkt rests;
62 
63 /* RPC exported functions */
64 static int fileXio_GetDeviceList_RPC(struct fileXioDevice* ee_devices, int eecount);
65 static int fileXio_CopyFile_RPC(const char *src, const char *dest, int mode);
66 static int fileXio_Read_RPC(int infd, char *read_buf, int read_size, void *intr_data);
67 static int fileXio_Write_RPC(int outfd, const char *write_buf, int write_size, int mis,u8 *misbuf);
68 static int fileXio_GetDir_RPC(const char* pathname, struct fileXioDirEntry dirEntry[], unsigned int req_entries);
69 static int fileXio_Mount_RPC(const char* mountstring, const char* mountpoint, int flag);
70 static int fileXio_chstat_RPC(char *filename, void* eeptr, int mask);
71 static int fileXio_getstat_RPC(char *filename, void* eeptr);
72 static int fileXio_dread_RPC(int fd, void* eeptr);
73 
74 // Functions called by the RPC server
75 static void* fileXioRpc_Stop();
76 static void* fileXioRpc_GetDeviceList(unsigned int* sbuff);
77 static void* fileXioRpc_Getdir(unsigned int* sbuff);
78 static void* fileXioRpc_Mount(unsigned int* sbuff);
79 static void* fileXioRpc_uMount(unsigned int* sbuff);
80 static void* fileXioRpc_CopyFile(unsigned int* sbuff);
81 static void* fileXioRpc_MkDir(unsigned int* sbuff);
82 static void* fileXioRpc_RmDir(unsigned int* sbuff);
83 static void* fileXioRpc_Remove(unsigned int* sbuff);
84 static void* fileXioRpc_Rename(unsigned int* sbuff);
85 static void* fileXioRpc_SymLink(unsigned int* sbuff);
86 static void* fileXioRpc_ReadLink(unsigned int* sbuff);
87 static void* fileXioRpc_ChDir(unsigned int* sbuff);
88 static void* fileXioRpc_Open(unsigned int* sbuff);
89 static void* fileXioRpc_Close(unsigned int* sbuff);
90 static void* fileXioRpc_Read(unsigned int* sbuff);
91 static void* fileXioRpc_Write(unsigned int* sbuff);
92 static void* fileXioRpc_Lseek(unsigned int* sbuff);
93 static void* fileXioRpc_Lseek64(unsigned int* sbuff);
94 static void* fileXioRpc_ChStat(unsigned int* sbuff);
95 static void* fileXioRpc_GetStat(unsigned int* sbuff);
96 static void* fileXioRpc_Format(unsigned int* sbuff);
97 static void* fileXioRpc_AddDrv(unsigned int* sbuff);
98 static void* fileXioRpc_DelDrv(unsigned int* sbuff);
99 static void* fileXioRpc_Sync(unsigned int* sbuff);
100 static void* fileXioRpc_Devctl(unsigned int* sbuff);
101 static void* fileXioRpc_Ioctl(unsigned int* sbuff);
102 static void* fileXioRpc_Ioctl2(unsigned int* sbuff);
103 static void* fileXioRpc_Dopen(unsigned int* sbuff);
104 static void* fileXioRpc_Dread(unsigned int* sbuff);
105 static void* fileXioRpc_Dclose(unsigned int* sbuff);
106 static void* filexioRpc_SetRWBufferSize(void *sbuff);
107 static void* fileXioRpc_Getdir(unsigned int* sbuff);
108 static void DirEntryCopy(struct fileXioDirEntry* dirEntry, iox_dirent_t* internalDirEntry);
109 
110 // RPC server
111 static void* fileXio_rpc_server(int fno, void *data, int size);
112 static void fileXio_Thread(void* param);
113 
114 int _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 
140 static 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 
174 static 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 
207 static 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  }
290 EXIT:
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 
305 static int fileXio_Write_RPC(int outfd, const char *write_buf, int write_size, int mis,u8 *misbuf)
306 {
307  SifRpcReceiveData_t rdata;
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
349 static 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
413 static 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 
421 static int fileXio_chstat_RPC(char *filename, void* eeptr, int mask)
422 {
423  int res=0;
424  iox_stat_t localStat;
425  SifRpcReceiveData_t rdata;
426 
427  sceSifGetOtherData(&rdata, (void *)eeptr, &localStat, 64, 0);
428 
429  res = iomanX_chstat(filename, &localStat, mask);
430  return(res);
431 }
432 
433 static 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 
459 static 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 
484 static 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
493 static 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
510 static 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)
527 static 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)
546 static 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)
560 static 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)
578 static 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)
591 static 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)
604 static 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)
618 static 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)
632 static 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)
647 static 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)
660 void* 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
673 static 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)
686 static 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
701 static 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)
717 static 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)
733 static 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)
748 static 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)
772 static 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)
786 static 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
802 static 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);
814 static 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)
825 static 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)
837 static 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);
850 static 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);
888 static 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);
902 static 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 
939 static 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 
950 static 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 
961 static 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 
977 static 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 
1004 static 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 
1023 static 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
1098 static 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 }
iomanX.h
iox_stat_t
Definition: iox_stat.h:92
fileXioDevice
Definition: fileXio.h:106
thbase.h
fxio_format_packet
Definition: fileXio.h:230
sifman.h
sysclib.h
fxio_devctl_packet
Definition: fileXio.h:250
ENOMEM
#define ENOMEM
Definition: errno.h:43
fxio_unmount_packet
Definition: fileXio.h:135
fxio_getdir_packet
Definition: fileXio.h:121
MIN
#define MIN(a, b)
Definition: audsrv_internal.h:19
t_SifRpcReceiveData
Definition: sifrpc-common.h:145
CpuSuspendIntr
int CpuSuspendIntr(int *state)
Definition: intrman.c:195
fxio_lseek64_return_pkt
Definition: fileXio.h:287
loadcore.h
fxio_rename_packet
Definition: fileXio.h:160
fxio_ioctl_packet
Definition: fileXio.h:261
fxio_lseek_packet
Definition: fileXio.h:202
fileXioDirEntry
Definition: fileXio.h:99
rests_pkt
Definition: fileXio.h:69
fxio_rwbuff
Definition: fileXio.h:292
fxio_ctl_return_pkt
Definition: fileXio.h:279
fxio_sync_packet
Definition: fileXio.h:238
fxio_dread_packet
Definition: fileXio.h:244
qd
static SifRpcDataQueue_t qd
Definition: rpc_server.c:33
fxio_read_packet
Definition: fileXio.h:185
fxio_open_packet
Definition: fileXio.h:173
_iomanX_iop_device
Definition: iomanX.h:81
stdio.h
fxio_mount_packet
Definition: fileXio.h:128
_iop_thread
Definition: thbase.h:39
fxio_getstat_packet
Definition: fileXio.h:224
t_SifDmaTransfer
Definition: sifdma.h:52
fileXio.h
devices
kbd_dev * devices[PS2KBD_MAXDEV]
Definition: ps2kbd.c:102
CpuResumeIntr
int CpuResumeIntr(int state)
Definition: intrman.c:217
iox_dirent_t
Definition: iox_stat.h:111
t_SifRpcServerData
Definition: sifrpc-common.h:98
t_SifRpcDataQueue
Definition: sifrpc-common.h:153
fxio_mkdir_packet
Definition: fileXio.h:147
fxio_close_packet
Definition: fileXio.h:180
sysmem.h
fxio_ioctl2_packet
Definition: fileXio.h:268
iomanX_format
int iomanX_format(const char *dev, const char *blockdev, void *arg, int arglen)
Definition: iomanX.c:710
__attribute__
Definition: gif_registers.h:38
fxio_lseek64_packet
Definition: fileXio.h:209
fxio_chstat_packet
Definition: fileXio.h:217
intrman.h
fxio_devlist_packet
Definition: fileXio.h:115
fxio_write_packet
Definition: fileXio.h:193
fxio_pathsel_packet
Definition: fileXio.h:154
fxio_copyfile_packet
Definition: fileXio.h:140
errno.h
sd0
static SifRpcServerData_t sd0
Definition: rpc_server.c:35
_iomanX_iop_device::version
unsigned int version
Definition: iomanX.h:85