PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
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
56static 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
103typedef 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
114
115static mcNameParam_t g_nameParam __attribute__((aligned(64)));
116
120static 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
128extern int _iop_reboot_count;
129
131static SifRpcClientData_t g_cdata __attribute__((aligned(64)));
132
134#define RSIZE 2048
135static union{
136 s32 result;
137 mcRpcStat_t rpcStat;
138 u8 buffer[RSIZE];
139} g_rdata __attribute__((aligned(64)));
140
141static int* g_pType = NULL;
142static int* g_pFree = NULL;
143static int* g_pFormat = NULL;
144
145static int endParameter[48] __attribute__((aligned(64)));
146static char curDir[1024] __attribute__((aligned(64)));
147static sceMcTblGetDir g_fileInfoBuff __attribute__((aligned(64))); // used by mcSetFileInfo and mcRename
148
149
151static int g_mclibInited = 0;
152
154static unsigned int g_currentCmd = 0;
155
157static int g_mcType = MC_TYPE_MC;
158
159
163static 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
195static 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
219static 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
230int 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
368int 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
410int 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
435int 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
456int 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
479int 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
505int 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
543int 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
564int 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
573int 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
599int 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
627int 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
656int 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
681int 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
703int 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
725int 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
749int 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
778int 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
810static struct libmc_PageReadAlignData libmc_ReadPageAlignData __attribute__((aligned(64)));
811
812static 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
821int 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
846int 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
898int 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
940int mcReset(void)
941{
942 g_mclibInited = 0;
943 g_cdata.server = NULL;
944 return 0;
945}
946
int mcReset(void)
Definition libmc.c:940
int mcGetEntSpace(int port, int slot, const char *path)
Definition libmc.c:725
int mcUnformat(int port, int slot)
Definition libmc.c:703
int mcSeek(int fd, int offset, int origin)
Definition libmc.c:456
static int g_mclibInited
Definition libmc.c:151
int mcRead(int fd, void *buffer, int size)
Definition libmc.c:479
MC_RPCCMD_NUMBERS
Definition libmc.c:30
int mcMkDir(int port, int slot, const char *name)
Definition libmc.c:564
static const int mcRpcCmd[2][17]
Definition libmc.c:56
int mcWritePage(int port, int slot, int page, const void *buffer)
Definition libmc.c:846
int mcEraseBlock(int port, int slot, int block, int mode)
Definition libmc.c:778
int mcOpen(int port, int slot, const char *name, int mode)
Definition libmc.c:410
int mcRename(int port, int slot, const char *oldName, const char *newName)
Definition libmc.c:749
int mcChdir(int port, int slot, const char *newDir, char *currentDir)
Definition libmc.c:573
int mcSetFileInfo(int port, int slot, const char *name, const sceMcTblGetDir *info, unsigned flags)
Definition libmc.c:627
int mcReadPage(int port, int slot, unsigned int page, void *buffer)
Definition libmc.c:821
int mcGetDir(int port, int slot, const char *name, unsigned mode, int maxent, sceMcTblGetDir *table)
Definition libmc.c:599
int mcClose(int fd)
Definition libmc.c:435
static void mcStoreDir(void *arg)
Definition libmc.c:219
int _iop_reboot_count
static void mcReadFixAlign(void *data_raw)
Definition libmc.c:195
static void mcGetInfoApdx(void *info)
Definition libmc.c:163
int mcGetInfo(int port, int slot, int *type, int *free, int *format)
Definition libmc.c:368
int mcInit(int type)
Definition libmc.c:230
int mcDelete(int port, int slot, const char *name)
Definition libmc.c:656
static int g_mcType
Definition libmc.c:157
int mcFormat(int port, int slot)
Definition libmc.c:681
int mcWrite(int fd, const void *buffer, int size)
Definition libmc.c:505
int mcChangeThreadPriority(int level)
Definition libmc.c:875
int mcSync(int mode, int *cmd, int *result)
Definition libmc.c:898
static unsigned int g_currentCmd
Definition libmc.c:154
int mcFlush(int fd)
Definition libmc.c:543
#define RSIZE
Definition libmc.c:134
#define SIF_RPC_M_NOWAIT