PS2SDK
PS2 Homebrew Libraries
libmc.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 
16 #include <tamtypes.h>
17 #include <kernel.h>
18 #include <sifrpc.h>
19 #include <string.h>
20 #include "libmc.h"
21 
22 //#define MC_DEBUG
23 
24 #ifdef MC_DEBUG
25 #include <stdio.h>
26 #endif
27 
28 
31  MC_RPCCMD_INIT = 0x00,
32  MC_RPCCMD_GET_INFO,
33  MC_RPCCMD_OPEN,
34  MC_RPCCMD_CLOSE,
35  MC_RPCCMD_SEEK,
36  MC_RPCCMD_READ,
37  MC_RPCCMD_WRITE,
38  MC_RPCCMD_FLUSH,
39  MC_RPCCMD_CH_DIR,
40  MC_RPCCMD_GET_DIR,
41  MC_RPCCMD_SET_INFO,
42  MC_RPCCMD_DELETE,
43  MC_RPCCMD_FORMAT,
44  MC_RPCCMD_UNFORMAT,
45  MC_RPCCMD_GET_ENT,
46  MC_RPCCMD_CHG_PRITY,
47  MC_RPCCMD_CHECK_BLOCK,
48  MC_RPCCMD_ERASE_BLOCK = 0x0E,
49  MC_RPCCMD_READ_PAGE,
50  MC_RPCCMD_WRITE_PAGE
51 };
52 
56 static const int mcRpcCmd[2][17] =
57 {
58  // MCMAN/MCSERV values
59  {
60  0x70, // MC_RPCCMD_INIT
61  0x78, // MC_RPCCMD_GET_INFO
62  0x71, // MC_RPCCMD_OPEN
63  0x72, // MC_RPCCMD_CLOSE
64  0x75, // MC_RPCCMD_SEEK
65  0x73, // MC_RPCCMD_READ
66  0x74, // MC_RPCCMD_WRITE
67  0x7A, // MC_RPCCMD_FLUSH
68  0x7B, // MC_RPCCMD_CH_DIR
69  0x76, // MC_RPCCMD_GET_DIR
70  0x7C, // MC_RPCCMD_SET_INFO
71  0x79, // MC_RPCCMD_DELETE
72  0x77, // MC_RPCCMD_FORMAT
73  0x80, // MC_RPCCMD_UNFORMAT
74  0x7D, // MC_RPCCMD_ERASE_BLOCK (calls mcman_funcs: 39, 17, 20, 19, 30)
75  0x7E, // MC_RPCCMD_READ_PAGE
76  0x7F, // MC_RPCCMD_WRITE_PAGE (calls mcman_funcs: 20, 19)
77  },
78  // XMCMAN/XMCSERV values
79  {
80  0xFE, // MC_RPCCMD_INIT
81  0x01, // MC_RPCCMD_GET_INFO
82  0x02, // MC_RPCCMD_OPEN
83  0x03, // MC_RPCCMD_CLOSE
84  0x04, // MC_RPCCMD_SEEK
85  0x05, // MC_RPCCMD_READ
86  0x06, // MC_RPCCMD_WRITE
87  0x0A, // MC_RPCCMD_FLUSH
88  0x0C, // MC_RPCCMD_CH_DIR
89  0x0D, // MC_RPCCMD_GET_DIR
90  0x0E, // MC_RPCCMD_SET_INFO
91  0x0F, // MC_RPCCMD_DELETE
92  0x10, // MC_RPCCMD_FORMAT
93  0x11, // MC_RPCCMD_UNFORMAT
94  0x12, // MC_RPCCMD_GET_ENT
95  0x14, // MC_RPCCMD_CHG_PRITY
96  0x33, // MC_RPCCMD_CHECK_BLOCK (calls xmcman_funcs: 45)
97  }
98 };
99 
103 typedef struct { // size = 1044
104  int port; // 0
105  int slot; // 4
106  int flags; // 8
107  int maxent; // 12
108  union {
109  sceMcTblGetDir *mcT; // 16
110  char *curdir;
111  };
112  char name[1024]; // 20
113 } mcNameParam_t;
114 
115 static mcNameParam_t g_nameParam __attribute__((aligned(64)));
116 
120 static mcDescParam_t g_descParam __attribute__((aligned(64)));
121 
122 // params sent with rpc commands
123 //static McRpcNameParam g_nameParam __attribute__((aligned(64)));
124 //static McRpcDescParam g_descParam __attribute__((aligned(64)));
125 //static unsigned int mcInfoCmd[12] __attribute__((aligned(64)));
126 
128 extern int _iop_reboot_count;
129 
131 static SifRpcClientData_t g_cdata __attribute__((aligned(64)));
132 
134 #define RSIZE 2048
135 static union{
136  s32 result;
137  mcRpcStat_t rpcStat;
138  u8 buffer[RSIZE];
139 } g_rdata __attribute__((aligned(64)));
140 
141 static int* g_pType = NULL;
142 static int* g_pFree = NULL;
143 static int* g_pFormat = NULL;
144 
145 static int endParameter[48] __attribute__((aligned(64)));
146 static char curDir[1024] __attribute__((aligned(64)));
147 static sceMcTblGetDir g_fileInfoBuff __attribute__((aligned(64))); // used by mcSetFileInfo and mcRename
148 
149 
151 static int g_mclibInited = 0;
152 
154 static unsigned int g_currentCmd = 0;
155 
157 static int g_mcType = MC_TYPE_MC;
158 
159 
163 static void mcGetInfoApdx(void* info)
164 {
165  mcEndParam_t *ptr = (mcEndParam_t*)UNCACHED_SEG(info);
166  mcEndParam2_t *ptrNew = (mcEndParam2_t*)UNCACHED_SEG(info);
167 
168  // older MCSERV doesnt support retrieving whether card is formatted
169  // so if a card is present, determine whether its formatted based on the return value from MCSERV
170  if(g_mcType == MC_TYPE_MC)
171  {
172  if(g_pType != NULL)
173  *g_pType = ptr->type;
174 
175  if(g_pFree != NULL)
176  *g_pFree = ptr->free;
177 
178  if(g_pFormat != NULL)
179  *g_pFormat = (ptr->type == MC_TYPE_NONE || g_rdata.result == -2) ? 0 : 1;
180  } else {
181  if(g_pType != NULL)
182  *g_pType = ptrNew->type;
183 
184  if(g_pFree != NULL)
185  *g_pFree = ptrNew->free;
186 
187  if(g_pFormat != NULL)
188  *g_pFormat = ptrNew->formatted;
189  }
190 }
191 
195 static void mcReadFixAlign(void* data_raw)
196 {
197  mcEndParam_t *ptr = (mcEndParam_t*)UNCACHED_SEG(data_raw);
198  mcEndParam2_t *ptrNew = (mcEndParam2_t*)UNCACHED_SEG(data_raw);
199  u8 *dest;
200  int i;
201 
202  if(g_mcType == MC_TYPE_MC)
203  {
204  for(i = 0,dest = (u8*)ptr->dest1; i < ptr->size1; i++)
205  dest[i] = ptr->src1[i];
206  for(i = 0,dest = (u8*)ptr->dest2; i < ptr->size2; i++)
207  dest[i] = ptr->src2[i];
208  } else {
209  for(i = 0,dest = (u8*)ptrNew->dest1; i < ptrNew->size1; i++)
210  dest[i] = ptrNew->src1[i];
211  for(i = 0,dest = (u8*)ptrNew->dest2; i < ptrNew->size2; i++)
212  dest[i] = ptrNew->src2[i];
213  }
214 }
215 
219 static void mcStoreDir(void* arg)
220 {
221  int len;
222  char *currentDir = UNCACHED_SEG(curDir);
223  len = strlen(currentDir);
224  if(len >= 1024)
225  len = strlen(currentDir+1023);
226  memcpy(arg, currentDir, len);
227  *(currentDir+len) = 0;
228 }
229 
230 int mcInit(int type)
231 {
232  int ret=0;
233  int err=0;
234  mcRpcStat_t *rpcStat = (mcRpcStat_t*)UNCACHED_SEG(&g_rdata.rpcStat);
235  static int _rb_count = 0;
236 
237  (void)type;
238  if(_rb_count != _iop_reboot_count)
239  {
240  _rb_count = _iop_reboot_count;
241  mcReset();
242  }
243 
244  if(g_mclibInited)
245  return -1;
246 
247  sceSifInitRpc(0);
248 
249  // bind to mc rpc on iop
250  do
251  {
252  if((ret=sceSifBindRpc(&g_cdata, 0x80000400, 0)) < 0)
253  {
254  #ifdef MC_DEBUG
255  printf("libmc: bind error\n");
256  #endif
257 
258  return ret;
259  }
260  if(g_cdata.server == NULL)
261  nopdelay();
262  }
263  while (g_cdata.server == NULL);
264 
265  // for some reason calling this init sif function with 'mcserv' makes all other
266  // functions not work properly. although NOT calling it means that detecting
267  // whether or not cards are formatted doesnt seem to work :P
268 
269  // Start with calling flush with an invalid fd (so it sets the return value to
270  // sceMcResDeniedPermit, which MC_RPCCMD_INIT will not return)
271  g_descParam.fd = 0xFFFFFFFF;
272  sceSifCallRpc(&g_cdata, mcRpcCmd[MC_TYPE_XMC][MC_RPCCMD_FLUSH], 0, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL);
273  sceSifCallRpc(&g_cdata, mcRpcCmd[MC_TYPE_MC][MC_RPCCMD_FLUSH], 0, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL);
274 #ifdef MC_DEBUG
275  printf("libmc: using XMCMAN & XMCSERV\n");
276 #endif
277 
278  // Try XMCSERV RPC
279  g_mcType = MC_TYPE_XMC;
280  // call init function
281  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_INIT], 0, &g_descParam, sizeof(g_descParam), &g_rdata, 12, NULL, NULL)) < 0)
282  {
283  // init error
284 #ifdef MC_DEBUG
285  printf("libmc: initialisation error\n");
286 #endif
287  err = ret - 100;
288  }
289 
290  // If result was sceMcResDeniedPermit, RPC was unhandled
291  if (!err && rpcStat->result == sceMcResDeniedPermit)
292  {
293  err = -122;
294  }
295 
296  if (!err)
297  {
298  // check if old version of mcserv loaded
299  if (rpcStat->mcserv_version < 0x205)
300  {
301 #ifdef MC_DEBUG
302  printf("libmc: mcserv is too old (%x)\n", rpcStat->mcserv_version);
303 #endif
304  err = -120;
305  }
306 
307  // check if old version of mcman loaded
308  if (rpcStat->mcman_version < 0x206)
309  {
310 #ifdef MC_DEBUG
311  printf("libmc: mcman is too old (%x)\n", rpcStat->mcman_version);
312 #endif
313  err = -121;
314  }
315  }
316 
317  if (!err)
318  {
319  ret = rpcStat->result;
320  }
321 
322  if (err && rpcStat->result == sceMcResDeniedPermit)
323  {
324  err = 0;
325 
326  // Try MCSERV RPC
327  g_mcType = MC_TYPE_MC;
328 #ifdef MC_DEBUG
329  printf("libmc: using MCMAN & MCSERV\n");
330 #endif
331 
332  g_descParam.offset = -217;
333 
334  // call init function
335  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_INIT], 0, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) < 0)
336  {
337  // init error
338 #ifdef MC_DEBUG
339  printf("libmc: initialisation error\n");
340 #endif
341  err = ret - 100;
342  }
343 
344  // If result was sceMcResDeniedPermit, RPC was unhandled
345  if (!err && rpcStat->result == sceMcResDeniedPermit)
346  {
347  err = -122;
348  }
349 
350  if (!err)
351  {
352  ret = g_rdata.result;
353  }
354  }
355 
356  if (err)
357  {
358  g_mclibInited = 0;
359  return err;
360  }
361 
362  // successfully inited
363  g_mclibInited = 1;
364  g_currentCmd = 0;
365  return ret;
366 }
367 
368 int mcGetInfo(int port, int slot, int* type, int* free, int* format)
369 {
370  int ret;
371 
372  // check mc lib is inited
373  if(!g_mclibInited)
374  return -1;
375  // check nothing else is processing
376  if(g_currentCmd != MC_FUNC_NONE)
377  return g_currentCmd;
378 
379  // set global variables
380  if(g_mcType == MC_TYPE_MC)
381  {
382  g_descParam.port = port;
383  g_descParam.slot = slot;
384  g_descParam.size = (type) ? 1 : 0;
385  g_descParam.offset = (free) ? 1 : 0;
386  g_descParam.origin = (format) ? 1 : 0;
387  g_descParam.param = endParameter;
388  }
389  else
390  {
391  g_descParam.port = port;
392  g_descParam.slot = slot;
393  g_descParam.size = (format) ? 1 : 0;
394  g_descParam.offset = (free) ? 1 : 0;
395  g_descParam.origin = (type) ? 1 : 0;
396  g_descParam.param = endParameter;
397  }
398  g_pType = type;
399  g_pFree = free;
400  g_pFormat = format;
401  sceSifWriteBackDCache(endParameter, 192);
402 
403  // send sif command
404  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_GET_INFO], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, (SifRpcEndFunc_t)mcGetInfoApdx, endParameter)) != 0)
405  return ret;
406  g_currentCmd = MC_FUNC_GET_INFO;
407  return ret;
408 }
409 
410 int mcOpen(int port, int slot, const char *name, int mode)
411 {
412  int ret;
413 
414  // check mc lib is inited
415  if(!g_mclibInited)
416  return -1;
417  // check nothing else is processing
418  if(g_currentCmd != MC_FUNC_NONE)
419  return g_currentCmd;
420 
421  // set global variables
422  g_nameParam.port = port;
423  g_nameParam.slot = slot;
424  g_nameParam.flags = mode;
425  strncpy(g_nameParam.name, name, 1023);
426  g_nameParam.name[1023] = 0;
427 
428  // send sif command
429  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_OPEN], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, NULL, NULL)) != 0)
430  return ret;
431  g_currentCmd = MC_FUNC_OPEN;
432  return ret;
433 }
434 
435 int mcClose(int fd)
436 {
437  int ret;
438 
439  // check mc lib is inited
440  if(!g_mclibInited)
441  return -1;
442  // check nothing else is processing
443  if(g_currentCmd != MC_FUNC_NONE)
444  return g_currentCmd;
445 
446  // set global variables
447  g_descParam.fd = fd;
448 
449  // send sif command
450  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_CLOSE], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
451  return ret;
452  g_currentCmd = MC_FUNC_CLOSE;
453  return ret;
454 }
455 
456 int mcSeek(int fd, int offset, int origin)
457 {
458  int ret;
459 
460  // check mc lib is inited
461  if(!g_mclibInited)
462  return -1;
463  // check nothing else is processing
464  if(g_currentCmd != MC_FUNC_NONE)
465  return g_currentCmd;
466 
467  // set global variables
468  g_descParam.fd = fd;
469  g_descParam.offset = offset;
470  g_descParam.origin = origin;
471 
472  // send sif command
473  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_SEEK], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
474  return ret;
475  g_currentCmd = MC_FUNC_SEEK;
476  return ret;
477 }
478 
479 int mcRead(int fd, void *buffer, int size)
480 {
481  int ret;
482 
483  // check mc lib is inited
484  if(!g_mclibInited)
485  return -1;
486  // check nothing else is processing
487  if(g_currentCmd != MC_FUNC_NONE)
488  return g_currentCmd;
489 
490  // set global variables
491  g_descParam.fd = fd;
492  g_descParam.size = size;
493  g_descParam.buffer = buffer;
494  g_descParam.param = endParameter;
495  sceSifWriteBackDCache(buffer, size);
496  sceSifWriteBackDCache(endParameter, 192);
497 
498  // send sif command
499  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_READ], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, (SifRpcEndFunc_t)mcReadFixAlign, endParameter)) != 0)
500  return ret;
501  g_currentCmd = MC_FUNC_READ;
502  return ret;
503 }
504 
505 int mcWrite(int fd, const void *buffer, int size)
506 {
507  int i, ret;
508 
509  // check mc lib is inited
510  if(!g_mclibInited)
511  return -1;
512  // check nothing else is processing
513  if(g_currentCmd != MC_FUNC_NONE)
514  return g_currentCmd;
515 
516  // set global variables
517  g_descParam.fd = fd;
518  if(size < 17)
519  {
520  g_descParam.size = 0;
521  g_descParam.origin = size;
522  g_descParam.buffer = 0;
523  }
524  else
525  {
526  g_descParam.size = size - ( ((int)((const u8 *)buffer-1) & 0xFFFFFFF0) - (int)((const u8 *)buffer-16) );
527  g_descParam.origin = ( ((int)((const u8 *)buffer-1) & 0xFFFFFFF0) - (int)((const u8 *)buffer-16) );
528  g_descParam.buffer = (void*)((int)(const u8 *)buffer + ( ((int)((const u8 *)buffer-1) & 0xFFFFFFF0) - (int)((const u8 *)buffer-16) ));
529  }
530  for(i=0; i<g_descParam.origin; i++)
531  {
532  g_descParam.data[i] = *(char*)((const u8 *)buffer+i);
533  }
534  FlushCache(0);
535 
536  // send sif command
537  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_WRITE], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
538  return ret;
539  g_currentCmd = MC_FUNC_WRITE;
540  return ret;
541 }
542 
543 int mcFlush(int fd)
544 {
545  int ret;
546 
547  // check mc lib is inited
548  if(!g_mclibInited)
549  return -1;
550  // check nothing else is processing
551  if(g_currentCmd != MC_FUNC_NONE)
552  return g_currentCmd;
553 
554  // set global variables
555  g_descParam.fd = fd;
556 
557  // send sif command
558  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_FLUSH], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
559  return ret;
560  g_currentCmd = MC_FUNC_FLUSH;
561  return ret;
562 }
563 
564 int mcMkDir(int port, int slot, const char* name)
565 {
566  int ret = mcOpen(port, slot, name, 0x40);
567 
568  if(ret != 0)
569  g_currentCmd = MC_FUNC_MK_DIR;
570  return ret;
571 }
572 
573 int mcChdir(int port, int slot, const char* newDir, char* currentDir)
574 {
575  int ret;
576 
577  // check mc lib is inited
578  if(!g_mclibInited)
579  return -1;
580  // check nothing else is processing
581  if(g_currentCmd != MC_FUNC_NONE)
582  return g_currentCmd;
583 
584  // set global variables
585  g_nameParam.port = port;
586  g_nameParam.slot = slot;
587  g_nameParam.curdir = curDir;
588  strncpy(g_nameParam.name, newDir, 1023);
589  g_nameParam.name[1023] = 0;
590  sceSifWriteBackDCache(curDir, 1024);
591 
592  // send sif command
593  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_CH_DIR], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, (SifRpcEndFunc_t)mcStoreDir, currentDir)) != 0)
594  return ret;
595  g_currentCmd = MC_FUNC_CH_DIR;
596  return ret;
597 }
598 
599 int mcGetDir(int port, int slot, const char *name, unsigned mode, int maxent, sceMcTblGetDir* table)
600 {
601  int ret;
602 
603  // check mc lib is inited
604  if(!g_mclibInited)
605  return -1;
606  // check nothing else is processing
607  if(g_currentCmd != MC_FUNC_NONE)
608  return g_currentCmd;
609 
610  // set global variables
611  g_nameParam.port = port;
612  g_nameParam.slot = slot;
613  g_nameParam.flags = mode;
614  g_nameParam.maxent = maxent;
615  g_nameParam.mcT = table;
616  strncpy(g_nameParam.name, name, 1023);
617  g_nameParam.name[1023] = 0;
618  sceSifWriteBackDCache(table, maxent * sizeof(sceMcTblGetDir));
619 
620  // send sif command
621  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_GET_DIR], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, NULL, NULL)) != 0)
622  return ret;
623  g_currentCmd = MC_FUNC_GET_DIR;
624  return ret;
625 }
626 
627 int mcSetFileInfo(int port, int slot, const char* name, const sceMcTblGetDir* info, unsigned flags)
628 {
629  int ret;
630 
631  // check mc lib is inited
632  if(!g_mclibInited)
633  return -1;
634  // check nothing else is processing
635  if(g_currentCmd != MC_FUNC_NONE)
636  return g_currentCmd;
637 
638  // set global variables
639  g_nameParam.port = port;
640  g_nameParam.slot = slot;
641  g_nameParam.flags = flags; // NOTE: this was ANDed with 7 so that u cant turn off copy protect! :)
642  g_nameParam.mcT = &g_fileInfoBuff;
643  memcpy(&g_fileInfoBuff, info, sizeof(sceMcTblGetDir));
644 
645  strncpy(g_nameParam.name, name, 1023);
646  g_nameParam.name[1023] = 0;
647  FlushCache(0);
648 
649  // send sif command
650  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_SET_INFO], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, NULL, NULL)) != 0)
651  return ret;
652  g_currentCmd = MC_FUNC_SET_INFO;
653  return ret;
654 }
655 
656 int mcDelete(int port, int slot, const char *name)
657 {
658  int ret;
659 
660  // check lib is inited
661  if(!g_mclibInited)
662  return -1;
663  // check nothing else is processing
664  if(g_currentCmd != MC_FUNC_NONE)
665  return g_currentCmd;
666 
667  // set global variables
668  g_nameParam.port = port;
669  g_nameParam.slot = slot;
670  g_nameParam.flags = 0;
671  strncpy(g_nameParam.name, name, 1023);
672  g_nameParam.name[1023] = 0;
673 
674  // call delete function
675  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_DELETE], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, NULL, NULL)) != 0)
676  return ret;
677  g_currentCmd = MC_FUNC_DELETE;
678  return ret;
679 }
680 
681 int mcFormat(int port, int slot)
682 {
683  int ret;
684 
685  // check lib is inited
686  if(!g_mclibInited)
687  return -1;
688  // check nothing else is processing
689  if(g_currentCmd != MC_FUNC_NONE)
690  return g_currentCmd;
691 
692  // set global variables
693  g_descParam.port = port;
694  g_descParam.slot = slot;
695 
696  // call format function
697  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_FORMAT], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
698  return ret;
699  g_currentCmd = MC_FUNC_FORMAT;
700  return ret;
701 }
702 
703 int mcUnformat(int port, int slot)
704 {
705  int ret;
706 
707  // check lib is inited
708  if(!g_mclibInited)
709  return -1;
710  // check nothing else is processing
711  if(g_currentCmd != MC_FUNC_NONE)
712  return g_currentCmd;
713 
714  // set global variables
715  g_descParam.port = port;
716  g_descParam.slot = slot;
717 
718  // call unformat function
719  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_UNFORMAT], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
720  return ret;
721  g_currentCmd = MC_FUNC_UNFORMAT;
722  return ret;
723 }
724 
725 int mcGetEntSpace(int port, int slot, const char* path)
726 {
727  int ret;
728 
729  // check lib is inited
730  if((!g_mclibInited)||(g_mcType==MC_TYPE_MC))
731  return -1;
732  // check nothing else is processing
733  if(g_currentCmd != MC_FUNC_NONE)
734  return g_currentCmd;
735 
736  // set global variables
737  g_nameParam.port = port;
738  g_nameParam.slot = slot;
739  strncpy(g_nameParam.name, path, 1023);
740  g_nameParam.name[1023] = 0;
741 
742  // call sif function
743  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_GET_ENT], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, NULL, NULL)) != 0)
744  return ret;
745  g_currentCmd = MC_FUNC_GET_ENT;
746  return ret;
747 }
748 
749 int mcRename(int port, int slot, const char* oldName, const char* newName)
750 {
751  int ret;
752 
753  // check lib is inited
754  if((!g_mclibInited)||(g_mcType==MC_TYPE_MC)) //I don't think that the old MCSERV module supports this because the v1.00 and v1.01 OSDSYS doesn't seem to have the sceMcRename function at all and the sceMcRename function was only introduced with SCE PS2SDK v1.50. I see that it doesn't work with rom0:MCSERV either way...
755  return -1;
756  // check nothing else is processing
757  if(g_currentCmd != MC_FUNC_NONE)
758  return g_currentCmd;
759 
760  // set global variables
761  g_nameParam.port = port;
762  g_nameParam.slot = slot;
763  g_nameParam.flags = 0x10;
764  g_nameParam.mcT = &g_fileInfoBuff;
765  strncpy(g_nameParam.name, oldName, 1023);
766  g_nameParam.name[1023] = 0;
767  strncpy((char*)g_fileInfoBuff.EntryName, newName, 31);
768  g_fileInfoBuff.EntryName[31] = 0;
769  FlushCache(0);
770 
771  // call sif function
772  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_SET_INFO], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, NULL, NULL)) != 0)
773  return ret;
774  g_currentCmd = MC_FUNC_RENAME;
775  return ret;
776 }
777 
778 int mcEraseBlock(int port, int slot, int block, int mode){
779  int result;
780 
781  // check lib is inited
782  if((!g_mclibInited)||(g_mcType==MC_TYPE_XMC))
783  return -1;
784  // check nothing else is processing
785  if(g_currentCmd != MC_FUNC_NONE)
786  return g_currentCmd;
787 
788  g_descParam.port=port;
789  g_descParam.slot=slot;
790  g_descParam.offset=block;
791  g_descParam.origin=mode;
792 
793  if((result = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_ERASE_BLOCK], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL))==0){
794  g_currentCmd = MC_FUNC_ERASE_BLOCK;
795  }
796 
797  return result;
798 }
799 
801  unsigned int size1;
802  unsigned int size2;
803  void *dest1;
804  void *dest2;
805  unsigned char data1[16];
806  unsigned char data2[16];
807  unsigned char padding[16];
808 };
809 
810 static struct libmc_PageReadAlignData libmc_ReadPageAlignData __attribute__((aligned(64)));
811 
812 static void libmc_ReadAlignFunction(struct libmc_PageReadAlignData *data){
813  unsigned int misaligned;
814 
815  if((misaligned=(unsigned int)data->dest1&0xF)!=0){
816  memcpy(UNCACHED_SEG(data->dest1), UNCACHED_SEG(data->data1), 16-misaligned);
817  memcpy(UNCACHED_SEG((unsigned int)data->dest1+(16-misaligned)), UNCACHED_SEG((unsigned int)data->data1+(16-misaligned)+0x1F0), misaligned);
818  }
819 }
820 
821 int mcReadPage(int port, int slot, unsigned int page, void *buffer){
822  int result;
823 
824  // check lib is inited
825  if((!g_mclibInited)||(g_mcType==MC_TYPE_XMC))
826  return -1;
827  // check nothing else is processing
828  if(g_currentCmd != MC_FUNC_NONE)
829  return g_currentCmd;
830 
831  g_descParam.fd=page;
832  g_descParam.port=port;
833  g_descParam.slot=slot;
834  g_descParam.buffer=buffer;
835  g_descParam.param=&libmc_ReadPageAlignData;
836 
837  sceSifWriteBackDCache(buffer, 0x200);
838 
839  if((result = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_READ_PAGE], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, (void*)&libmc_ReadAlignFunction, UNCACHED_SEG(&libmc_ReadPageAlignData)))==0){
840  g_currentCmd = MC_FUNC_READ_PAGE;
841  }
842 
843  return result;
844 }
845 
846 int mcWritePage(int port, int slot, int page, const void *buffer){
847  int result, misaligned;
848 
849  // check lib is inited
850  if((!g_mclibInited)||(g_mcType==MC_TYPE_XMC))
851  return -1;
852  // check nothing else is processing
853  if(g_currentCmd != MC_FUNC_NONE)
854  return g_currentCmd;
855 
856  g_descParam.fd=page;
857  g_descParam.port=port;
858  g_descParam.slot=slot;
859  g_descParam.buffer=(void*)buffer;
860 
861  sceSifWriteBackDCache((void*)buffer, 512);
862 
863  if((misaligned=(unsigned int)buffer&0xF)!=0){
864  memcpy(g_descParam.data, buffer, 16-misaligned);
865  memcpy((void*)(g_descParam.data+(16-misaligned)), (void*)((const u8 *)buffer+(16-misaligned)+0x1F0), misaligned);
866  }
867 
868  if((result = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_WRITE_PAGE], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL))==0){
869  g_currentCmd = MC_FUNC_WRITE_PAGE;
870  }
871 
872  return result;
873 }
874 
876 {
877  int ret;
878 
879  (void)level;
880 
881  // check lib is inited
882  if((!g_mclibInited)||(g_mcType==MC_TYPE_MC))
883  return -1;
884  // check nothing else is processing
885  if(g_currentCmd != MC_FUNC_NONE)
886  return g_currentCmd;
887 
888  // set global variables
889 // *(u32*)mcCmd.name = level;
890 
891  // call sif function
892  if((ret = sceSifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_CHG_PRITY], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
893  return ret;
894  g_currentCmd = MC_FUNC_CHG_PRITY;
895  return ret;
896 }
897 
898 int mcSync(int mode, int *cmd, int *result)
899 {
900  int funcIsExecuting;
901 
902  // check if any functions are registered
903  if(g_currentCmd == MC_FUNC_NONE)
904  return -1;
905 
906  // check if function is still processing
907  funcIsExecuting = sceSifCheckStatRpc(&g_cdata);
908 
909  // if mode = 0, wait for function to finish
910  if(mode == 0)
911  {
912  while(sceSifCheckStatRpc(&g_cdata))
913  {
914  int i;
915  for(i=0; i<100000; i++)
916  ;
917  }
918  // function has finished
919  funcIsExecuting = 0;
920  }
921 
922  // get the function that just finished
923  if(cmd)
924  *cmd = g_currentCmd;
925 
926  // if function is still processing, return 0
927  if(funcIsExecuting == 1)
928  return 0;
929 
930  // function has finished, so clear last command
931  g_currentCmd = 0;
932 
933  // get result
934  if(result)
935  *result = g_rdata.result;
936 
937  return 1;
938 }
939 
940 int mcReset(void)
941 {
942  g_mclibInited = 0;
943  g_cdata.server = NULL;
944  return 0;
945 }
946 
kernel.h
mcEndParam2_t
Definition: libmc-common.h:121
SIF_RPC_M_NOWAIT
#define SIF_RPC_M_NOWAIT
Definition: sifrpc-common.h:23
mcGetDir
int mcGetDir(int port, int slot, const char *name, unsigned mode, int maxent, sceMcTblGetDir *table)
Definition: libmc.c:599
mcEndParam_t
Definition: libmc-common.h:99
mcSeek
int mcSeek(int fd, int offset, int origin)
Definition: libmc.c:456
mcRename
int mcRename(int port, int slot, const char *oldName, const char *newName)
Definition: libmc.c:749
MC_RPCCMD_NUMBERS
MC_RPCCMD_NUMBERS
Definition: libmc.c:30
s_info
Definition: xprintf.c:78
mcRpcStat_t
Definition: libmc-common.h:144
g_mclibInited
static int g_mclibInited
Definition: libmc.c:151
mcFormat
int mcFormat(int port, int slot)
Definition: libmc.c:681
mcGetEntSpace
int mcGetEntSpace(int port, int slot, const char *path)
Definition: libmc.c:725
__attribute__
static mcNameParam_t g_nameParam __attribute__((aligned(64)))
mcGetInfoApdx
static void mcGetInfoApdx(void *info)
Definition: libmc.c:163
_sceMcTblGetDir
Definition: libmc.h:138
mcReadFixAlign
static void mcReadFixAlign(void *data_raw)
Definition: libmc.c:195
mcWrite
int mcWrite(int fd, const void *buffer, int size)
Definition: libmc.c:505
mcStoreDir
static void mcStoreDir(void *arg)
Definition: libmc.c:219
mcFlush
int mcFlush(int fd)
Definition: libmc.c:543
mcReadPage
int mcReadPage(int port, int slot, unsigned int page, void *buffer)
Definition: libmc.c:821
mcRead
int mcRead(int fd, void *buffer, int size)
Definition: libmc.c:479
mcUnformat
int mcUnformat(int port, int slot)
Definition: libmc.c:703
mcEraseBlock
int mcEraseBlock(int port, int slot, int block, int mode)
Definition: libmc.c:778
mcOpen
int mcOpen(int port, int slot, const char *name, int mode)
Definition: libmc.c:410
mcDescParam_t
Definition: libmc-common.h:83
_iop_reboot_count
int _iop_reboot_count
tamtypes.h
mcInit
int mcInit(int type)
Definition: libmc.c:230
mcSync
int mcSync(int mode, int *cmd, int *result)
Definition: libmc.c:898
stdio.h
libmc_PageReadAlignData
Definition: libmc.c:800
libmc.h
mcWritePage
int mcWritePage(int port, int slot, int page, const void *buffer)
Definition: libmc.c:846
RSIZE
#define RSIZE
Definition: libmc.c:134
mcNameParam_t
Definition: libmc.c:103
mcChangeThreadPriority
int mcChangeThreadPriority(int level)
Definition: libmc.c:875
mcDelete
int mcDelete(int port, int slot, const char *name)
Definition: libmc.c:656
mcChdir
int mcChdir(int port, int slot, const char *newDir, char *currentDir)
Definition: libmc.c:573
mcGetInfo
int mcGetInfo(int port, int slot, int *type, int *free, int *format)
Definition: libmc.c:368
t_SifRpcClientData
Definition: sifrpc-common.h:134
mcReset
int mcReset(void)
Definition: libmc.c:940
g_mcType
static int g_mcType
Definition: libmc.c:157
__attribute__
Definition: gif_registers.h:38
mcSetFileInfo
int mcSetFileInfo(int port, int slot, const char *name, const sceMcTblGetDir *info, unsigned flags)
Definition: libmc.c:627
mcMkDir
int mcMkDir(int port, int slot, const char *name)
Definition: libmc.c:564
g_currentCmd
static unsigned int g_currentCmd
Definition: libmc.c:154
mcClose
int mcClose(int fd)
Definition: libmc.c:435
mcRpcCmd
static const int mcRpcCmd[2][17]
Definition: libmc.c:56