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 mcRpcStat_t *rpcStat = (mcRpcStat_t*)UNCACHED_SEG(&g_rdata.rpcStat);
234 static int _rb_count = 0;
235
236 if(_rb_count != _iop_reboot_count)
237 {
238 _rb_count = _iop_reboot_count;
239 mcReset();
240 }
241
242 if(g_mclibInited)
243 return -1;
244
245 SifInitRpc(0);
246
247 // set which modules to use
248 g_mcType = type;
249
250 // bind to mc rpc on iop
251 do
252 {
253 if((ret=SifBindRpc(&g_cdata, 0x80000400, 0)) < 0)
254 {
255 #ifdef MC_DEBUG
256 printf("libmc: bind error\n");
257 #endif
258
259 return ret;
260 }
261 if(g_cdata.server == NULL)
262 nopdelay();
263 }
264 while (g_cdata.server == NULL);
265
266 // for some reason calling this init sif function with 'mcserv' makes all other
267 // functions not work properly. although NOT calling it means that detecting
268 // whether or not cards are formatted doesnt seem to work :P
269 if(g_mcType == MC_TYPE_MC)
270 {
271#ifdef MC_DEBUG
272 printf("libmc: using MCMAN & MCSERV\n");
273
274#endif
275 g_descParam.offset = -217;
276
277 // call init function
278 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_INIT], 0, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL))>=0)
279 {
280 ret = g_rdata.result;
281 }
282 else{
283 // init error
284#ifdef MC_DEBUG
285 printf("libmc: initialisation error\n");
286#endif
287 g_mclibInited = 0;
288 return g_rdata.result - 100;
289 }
290 }
291 else if(g_mcType == MC_TYPE_XMC)
292 {
293#ifdef MC_DEBUG
294 printf("libmc: using XMCMAN & XMCSERV\n");
295#endif
296
297 // call init function
298 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_INIT], 0, &g_descParam, sizeof(g_descParam), &g_rdata, 12, NULL, NULL)) < 0)
299 {
300 // init error
301#ifdef MC_DEBUG
302 printf("libmc: initialisation error\n");
303#endif
304 g_mclibInited = 0;
305 return ret - 100;
306 }
307
308 // check if old version of mcserv loaded
309 if(rpcStat->mcserv_version < 0x205)
310 {
311#ifdef MC_DEBUG
312 printf("libmc: mcserv is too old (%x)\n", rpcStat->mcserv_version);
313#endif
314 g_mclibInited = 0;
315 return -120;
316 }
317
318 // check if old version of mcman loaded
319 if(rpcStat->mcman_version < 0x206)
320 {
321#ifdef MC_DEBUG
322 printf("libmc: mcman is too old (%x)\n", rpcStat->mcman_version);
323#endif
324 g_mclibInited = 0;
325 return -121;
326 }
327 ret = rpcStat->result;
328 }
329
330 // successfully inited
331 g_mclibInited = 1;
332 g_currentCmd = 0;
333 return ret;
334}
335
336int mcGetInfo(int port, int slot, int* type, int* free, int* format)
337{
338 int ret;
339
340 // check mc lib is inited
341 if(!g_mclibInited)
342 return -1;
343 // check nothing else is processing
344 if(g_currentCmd != MC_FUNC_NONE)
345 return g_currentCmd;
346
347 // set global variables
348 if(g_mcType == MC_TYPE_MC)
349 {
350 g_descParam.port = port;
351 g_descParam.slot = slot;
352 g_descParam.size = (type) ? 1 : 0;
353 g_descParam.offset = (free) ? 1 : 0;
354 g_descParam.origin = (format) ? 1 : 0;
355 g_descParam.param = endParameter;
356 }
357 else
358 {
359 g_descParam.port = port;
360 g_descParam.slot = slot;
361 g_descParam.size = (format) ? 1 : 0;
362 g_descParam.offset = (free) ? 1 : 0;
363 g_descParam.origin = (type) ? 1 : 0;
364 g_descParam.param = endParameter;
365 }
366 g_pType = type;
367 g_pFree = free;
368 g_pFormat = format;
369 SifWriteBackDCache(endParameter, 192);
370
371 // send sif command
372 if((ret = SifCallRpc(&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)
373 return ret;
374 g_currentCmd = MC_FUNC_GET_INFO;
375 return ret;
376}
377
378int mcOpen(int port, int slot, const char *name, int mode)
379{
380 int ret;
381
382 // check mc lib is inited
383 if(!g_mclibInited)
384 return -1;
385 // check nothing else is processing
386 if(g_currentCmd != MC_FUNC_NONE)
387 return g_currentCmd;
388
389 // set global variables
390 g_nameParam.port = port;
391 g_nameParam.slot = slot;
392 g_nameParam.flags = mode;
393 strncpy(g_nameParam.name, name, 1023);
394 g_nameParam.name[1023] = 0;
395
396 // send sif command
397 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_OPEN], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, NULL, NULL)) != 0)
398 return ret;
399 g_currentCmd = MC_FUNC_OPEN;
400 return ret;
401}
402
403int mcClose(int fd)
404{
405 int ret;
406
407 // check mc lib is inited
408 if(!g_mclibInited)
409 return -1;
410 // check nothing else is processing
411 if(g_currentCmd != MC_FUNC_NONE)
412 return g_currentCmd;
413
414 // set global variables
415 g_descParam.fd = fd;
416
417 // send sif command
418 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_CLOSE], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
419 return ret;
420 g_currentCmd = MC_FUNC_CLOSE;
421 return ret;
422}
423
424int mcSeek(int fd, int offset, int origin)
425{
426 int ret;
427
428 // check mc lib is inited
429 if(!g_mclibInited)
430 return -1;
431 // check nothing else is processing
432 if(g_currentCmd != MC_FUNC_NONE)
433 return g_currentCmd;
434
435 // set global variables
436 g_descParam.fd = fd;
437 g_descParam.offset = offset;
438 g_descParam.origin = origin;
439
440 // send sif command
441 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_SEEK], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
442 return ret;
443 g_currentCmd = MC_FUNC_SEEK;
444 return ret;
445}
446
447int mcRead(int fd, void *buffer, int size)
448{
449 int ret;
450
451 // check mc lib is inited
452 if(!g_mclibInited)
453 return -1;
454 // check nothing else is processing
455 if(g_currentCmd != MC_FUNC_NONE)
456 return g_currentCmd;
457
458 // set global variables
459 g_descParam.fd = fd;
460 g_descParam.size = size;
461 g_descParam.buffer = buffer;
462 g_descParam.param = endParameter;
463 SifWriteBackDCache(buffer, size);
464 SifWriteBackDCache(endParameter, 192);
465
466 // send sif command
467 if((ret = SifCallRpc(&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)
468 return ret;
469 g_currentCmd = MC_FUNC_READ;
470 return ret;
471}
472
473int mcWrite(int fd, const void *buffer, int size)
474{
475 int i, ret;
476
477 // check mc lib is inited
478 if(!g_mclibInited)
479 return -1;
480 // check nothing else is processing
481 if(g_currentCmd != MC_FUNC_NONE)
482 return g_currentCmd;
483
484 // set global variables
485 g_descParam.fd = fd;
486 if(size < 17)
487 {
488 g_descParam.size = 0;
489 g_descParam.origin = size;
490 g_descParam.buffer = 0;
491 }
492 else
493 {
494 g_descParam.size = size - ( ((int)((const u8 *)buffer-1) & 0xFFFFFFF0) - (int)((const u8 *)buffer-16) );
495 g_descParam.origin = ( ((int)((const u8 *)buffer-1) & 0xFFFFFFF0) - (int)((const u8 *)buffer-16) );
496 g_descParam.buffer = (void*)((int)(const u8 *)buffer + ( ((int)((const u8 *)buffer-1) & 0xFFFFFFF0) - (int)((const u8 *)buffer-16) ));
497 }
498 for(i=0; i<g_descParam.origin; i++)
499 {
500 g_descParam.data[i] = *(char*)((const u8 *)buffer+i);
501 }
502 FlushCache(0);
503
504 // send sif command
505 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_WRITE], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
506 return ret;
507 g_currentCmd = MC_FUNC_WRITE;
508 return ret;
509}
510
511int mcFlush(int fd)
512{
513 int ret;
514
515 // check mc lib is inited
516 if(!g_mclibInited)
517 return -1;
518 // check nothing else is processing
519 if(g_currentCmd != MC_FUNC_NONE)
520 return g_currentCmd;
521
522 // set global variables
523 g_descParam.fd = fd;
524
525 // send sif command
526 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_FLUSH], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
527 return ret;
528 g_currentCmd = MC_FUNC_FLUSH;
529 return ret;
530}
531
532int mcMkDir(int port, int slot, const char* name)
533{
534 int ret = mcOpen(port, slot, name, 0x40);
535
536 if(ret != 0)
537 g_currentCmd = MC_FUNC_MK_DIR;
538 return ret;
539}
540
541int mcChdir(int port, int slot, const char* newDir, char* currentDir)
542{
543 int ret;
544
545 // check mc lib is inited
546 if(!g_mclibInited)
547 return -1;
548 // check nothing else is processing
549 if(g_currentCmd != MC_FUNC_NONE)
550 return g_currentCmd;
551
552 // set global variables
553 g_nameParam.port = port;
554 g_nameParam.slot = slot;
555 g_nameParam.curdir = curDir;
556 strncpy(g_nameParam.name, newDir, 1023);
557 g_nameParam.name[1023] = 0;
558 SifWriteBackDCache(curDir, 1024);
559
560 // send sif command
561 if((ret = SifCallRpc(&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)
562 return ret;
563 g_currentCmd = MC_FUNC_CH_DIR;
564 return ret;
565}
566
567int mcGetDir(int port, int slot, const char *name, unsigned mode, int maxent, sceMcTblGetDir* table)
568{
569 int ret;
570
571 // check mc lib is inited
572 if(!g_mclibInited)
573 return -1;
574 // check nothing else is processing
575 if(g_currentCmd != MC_FUNC_NONE)
576 return g_currentCmd;
577
578 // set global variables
579 g_nameParam.port = port;
580 g_nameParam.slot = slot;
581 g_nameParam.flags = mode;
582 g_nameParam.maxent = maxent;
583 g_nameParam.mcT = table;
584 strncpy(g_nameParam.name, name, 1023);
585 g_nameParam.name[1023] = 0;
586 SifWriteBackDCache(table, maxent * sizeof(sceMcTblGetDir));
587
588 // send sif command
589 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_GET_DIR], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, NULL, NULL)) != 0)
590 return ret;
591 g_currentCmd = MC_FUNC_GET_DIR;
592 return ret;
593}
594
595int mcSetFileInfo(int port, int slot, const char* name, const sceMcTblGetDir* info, unsigned flags)
596{
597 int ret;
598
599 // check mc lib is inited
600 if(!g_mclibInited)
601 return -1;
602 // check nothing else is processing
603 if(g_currentCmd != MC_FUNC_NONE)
604 return g_currentCmd;
605
606 // set global variables
607 g_nameParam.port = port;
608 g_nameParam.slot = slot;
609 g_nameParam.flags = flags; // NOTE: this was ANDed with 7 so that u cant turn off copy protect! :)
610 g_nameParam.mcT = &g_fileInfoBuff;
611 memcpy(&g_fileInfoBuff, info, sizeof(sceMcTblGetDir));
612
613 strncpy(g_nameParam.name, name, 1023);
614 g_nameParam.name[1023] = 0;
615 FlushCache(0);
616
617 // send sif command
618 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_SET_INFO], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, NULL, NULL)) != 0)
619 return ret;
620 g_currentCmd = MC_FUNC_SET_INFO;
621 return ret;
622}
623
624int mcDelete(int port, int slot, const char *name)
625{
626 int ret;
627
628 // check lib is inited
629 if(!g_mclibInited)
630 return -1;
631 // check nothing else is processing
632 if(g_currentCmd != MC_FUNC_NONE)
633 return g_currentCmd;
634
635 // set global variables
636 g_nameParam.port = port;
637 g_nameParam.slot = slot;
638 g_nameParam.flags = 0;
639 strncpy(g_nameParam.name, name, 1023);
640 g_nameParam.name[1023] = 0;
641
642 // call delete function
643 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_DELETE], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, NULL, NULL)) != 0)
644 return ret;
645 g_currentCmd = MC_FUNC_DELETE;
646 return ret;
647}
648
649int mcFormat(int port, int slot)
650{
651 int ret;
652
653 // check lib is inited
654 if(!g_mclibInited)
655 return -1;
656 // check nothing else is processing
657 if(g_currentCmd != MC_FUNC_NONE)
658 return g_currentCmd;
659
660 // set global variables
661 g_descParam.port = port;
662 g_descParam.slot = slot;
663
664 // call format function
665 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_FORMAT], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
666 return ret;
667 g_currentCmd = MC_FUNC_FORMAT;
668 return ret;
669}
670
671int mcUnformat(int port, int slot)
672{
673 int ret;
674
675 // check lib is inited
676 if(!g_mclibInited)
677 return -1;
678 // check nothing else is processing
679 if(g_currentCmd != MC_FUNC_NONE)
680 return g_currentCmd;
681
682 // set global variables
683 g_descParam.port = port;
684 g_descParam.slot = slot;
685
686 // call unformat function
687 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_UNFORMAT], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
688 return ret;
689 g_currentCmd = MC_FUNC_UNFORMAT;
690 return ret;
691}
692
693int mcGetEntSpace(int port, int slot, const char* path)
694{
695 int ret;
696
697 // check lib is inited
698 if((!g_mclibInited)||(g_mcType==MC_TYPE_MC))
699 return -1;
700 // check nothing else is processing
701 if(g_currentCmd != MC_FUNC_NONE)
702 return g_currentCmd;
703
704 // set global variables
705 g_nameParam.port = port;
706 g_nameParam.slot = slot;
707 strncpy(g_nameParam.name, path, 1023);
708 g_nameParam.name[1023] = 0;
709
710 // call sif function
711 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_GET_ENT], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, NULL, NULL)) != 0)
712 return ret;
713 g_currentCmd = MC_FUNC_GET_ENT;
714 return ret;
715}
716
717int mcRename(int port, int slot, const char* oldName, const char* newName)
718{
719 int ret;
720
721 // check lib is inited
722 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...
723 return -1;
724 // check nothing else is processing
725 if(g_currentCmd != MC_FUNC_NONE)
726 return g_currentCmd;
727
728 // set global variables
729 g_nameParam.port = port;
730 g_nameParam.slot = slot;
731 g_nameParam.flags = 0x10;
732 g_nameParam.mcT = &g_fileInfoBuff;
733 strncpy(g_nameParam.name, oldName, 1023);
734 g_nameParam.name[1023] = 0;
735 strncpy((char*)g_fileInfoBuff.EntryName, newName, 31);
736 g_fileInfoBuff.EntryName[31] = 0;
737 FlushCache(0);
738
739 // call sif function
740 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_SET_INFO], SIF_RPC_M_NOWAIT, &g_nameParam, sizeof(g_nameParam), &g_rdata, 4, NULL, NULL)) != 0)
741 return ret;
742 g_currentCmd = MC_FUNC_RENAME;
743 return ret;
744}
745
746int mcEraseBlock(int port, int slot, int block, int mode){
747 int result;
748
749 // check lib is inited
750 if((!g_mclibInited)||(g_mcType==MC_TYPE_XMC))
751 return -1;
752 // check nothing else is processing
753 if(g_currentCmd != MC_FUNC_NONE)
754 return g_currentCmd;
755
756 g_descParam.port=port;
757 g_descParam.slot=slot;
758 g_descParam.offset=block;
759 g_descParam.origin=mode;
760
761 if((result = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_ERASE_BLOCK], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL))==0){
762 g_currentCmd = MC_FUNC_ERASE_BLOCK;
763 }
764
765 return result;
766}
767
769 unsigned int size1;
770 unsigned int size2;
771 void *dest1;
772 void *dest2;
773 unsigned char data1[16];
774 unsigned char data2[16];
775 unsigned char padding[16];
776};
777
778static struct libmc_PageReadAlignData libmc_ReadPageAlignData __attribute__((aligned(64)));
779
780static void libmc_ReadAlignFunction(struct libmc_PageReadAlignData *data){
781 unsigned int misaligned;
782
783 if((misaligned=(unsigned int)data->dest1&0xF)!=0){
784 memcpy(UNCACHED_SEG(data->dest1), UNCACHED_SEG(data->data1), 16-misaligned);
785 memcpy(UNCACHED_SEG((unsigned int)data->dest1+(16-misaligned)), UNCACHED_SEG((unsigned int)data->data1+(16-misaligned)+0x1F0), misaligned);
786 }
787}
788
789int mcReadPage(int port, int slot, unsigned int page, void *buffer){
790 int result;
791
792 // check lib is inited
793 if((!g_mclibInited)||(g_mcType==MC_TYPE_XMC))
794 return -1;
795 // check nothing else is processing
796 if(g_currentCmd != MC_FUNC_NONE)
797 return g_currentCmd;
798
799 g_descParam.fd=page;
800 g_descParam.port=port;
801 g_descParam.slot=slot;
802 g_descParam.buffer=buffer;
803 g_descParam.param=&libmc_ReadPageAlignData;
804
805 SifWriteBackDCache(buffer, 0x200);
806
807 if((result = SifCallRpc(&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){
808 g_currentCmd = MC_FUNC_READ_PAGE;
809 }
810
811 return result;
812}
813
814int mcWritePage(int port, int slot, int page, const void *buffer){
815 int result, misaligned;
816
817 // check lib is inited
818 if((!g_mclibInited)||(g_mcType==MC_TYPE_XMC))
819 return -1;
820 // check nothing else is processing
821 if(g_currentCmd != MC_FUNC_NONE)
822 return g_currentCmd;
823
824 g_descParam.fd=page;
825 g_descParam.port=port;
826 g_descParam.slot=slot;
827 g_descParam.buffer=(void*)buffer;
828
829 SifWriteBackDCache((void*)buffer, 512);
830
831 if((misaligned=(unsigned int)buffer&0xF)!=0){
832 memcpy(g_descParam.data, buffer, 16-misaligned);
833 memcpy((void*)(g_descParam.data+(16-misaligned)), (void*)((const u8 *)buffer+(16-misaligned)+0x1F0), misaligned);
834 }
835
836 if((result = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_WRITE_PAGE], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL))==0){
837 g_currentCmd = MC_FUNC_WRITE_PAGE;
838 }
839
840 return result;
841}
842
844{
845 int ret;
846
847 (void)level;
848
849 // check lib is inited
850 if((!g_mclibInited)||(g_mcType==MC_TYPE_MC))
851 return -1;
852 // check nothing else is processing
853 if(g_currentCmd != MC_FUNC_NONE)
854 return g_currentCmd;
855
856 // set global variables
857// *(u32*)mcCmd.name = level;
858
859 // call sif function
860 if((ret = SifCallRpc(&g_cdata, mcRpcCmd[g_mcType][MC_RPCCMD_CHG_PRITY], SIF_RPC_M_NOWAIT, &g_descParam, sizeof(g_descParam), &g_rdata, 4, NULL, NULL)) != 0)
861 return ret;
862 g_currentCmd = MC_FUNC_CHG_PRITY;
863 return ret;
864}
865
866int mcSync(int mode, int *cmd, int *result)
867{
868 int funcIsExecuting;
869
870 // check if any functions are registered
871 if(g_currentCmd == MC_FUNC_NONE)
872 return -1;
873
874 // check if function is still processing
875 funcIsExecuting = SifCheckStatRpc(&g_cdata);
876
877 // if mode = 0, wait for function to finish
878 if(mode == 0)
879 {
880 while(SifCheckStatRpc(&g_cdata))
881 {
882 int i;
883 for(i=0; i<100000; i++)
884 ;
885 }
886 // function has finished
887 funcIsExecuting = 0;
888 }
889
890 // get the function that just finished
891 if(cmd)
892 *cmd = g_currentCmd;
893
894 // if function is still processing, return 0
895 if(funcIsExecuting == 1)
896 return 0;
897
898 // function has finished, so clear last command
899 g_currentCmd = 0;
900
901 // get result
902 if(result)
903 *result = g_rdata.result;
904
905 return 1;
906}
907
908int mcReset(void)
909{
910 g_mclibInited = 0;
911 g_cdata.server = NULL;
912 return 0;
913}
914
#define SIF_RPC_M_NOWAIT
Definition sifrpc.h:24
int mcReset(void)
Definition libmc.c:908
int mcGetEntSpace(int port, int slot, const char *path)
Definition libmc.c:693
int mcUnformat(int port, int slot)
Definition libmc.c:671
int mcSeek(int fd, int offset, int origin)
Definition libmc.c:424
static int g_mclibInited
Definition libmc.c:151
int mcRead(int fd, void *buffer, int size)
Definition libmc.c:447
MC_RPCCMD_NUMBERS
Definition libmc.c:30
int mcMkDir(int port, int slot, const char *name)
Definition libmc.c:532
static const int mcRpcCmd[2][17]
Definition libmc.c:56
int mcWritePage(int port, int slot, int page, const void *buffer)
Definition libmc.c:814
int mcEraseBlock(int port, int slot, int block, int mode)
Definition libmc.c:746
int mcOpen(int port, int slot, const char *name, int mode)
Definition libmc.c:378
int mcRename(int port, int slot, const char *oldName, const char *newName)
Definition libmc.c:717
int mcChdir(int port, int slot, const char *newDir, char *currentDir)
Definition libmc.c:541
int mcSetFileInfo(int port, int slot, const char *name, const sceMcTblGetDir *info, unsigned flags)
Definition libmc.c:595
int mcReadPage(int port, int slot, unsigned int page, void *buffer)
Definition libmc.c:789
int mcGetDir(int port, int slot, const char *name, unsigned mode, int maxent, sceMcTblGetDir *table)
Definition libmc.c:567
int mcClose(int fd)
Definition libmc.c:403
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:336
int mcInit(int type)
Definition libmc.c:230
int mcDelete(int port, int slot, const char *name)
Definition libmc.c:624
static int g_mcType
Definition libmc.c:157
int mcFormat(int port, int slot)
Definition libmc.c:649
int mcWrite(int fd, const void *buffer, int size)
Definition libmc.c:473
int mcChangeThreadPriority(int level)
Definition libmc.c:843
int mcSync(int mode, int *cmd, int *result)
Definition libmc.c:866
static unsigned int g_currentCmd
Definition libmc.c:154
int mcFlush(int fd)
Definition libmc.c:511
#define RSIZE
Definition libmc.c:134